void BuildRegularTetrahedra (DemoEntityManager* const scene, int materialID) { dFloat mass = 5.0f; NewtonWorld* const world = scene->GetNewton(); dVector tetra[] = { dVector(-1.0f, 0.0f, -0.71f, 0.0f), dVector(1.0f, 0.0f, -0.71f, 0.0f), dVector(0.0f, -1.0f, 0.71f, 0.0f), dVector(0.0f, 1.0f, 0.71f, 0.0f) }; NewtonMesh* const tetrahedra = NewtonMeshCreate(scene->GetNewton()); NewtonMeshBeginBuild(tetrahedra); AddTetra (tetrahedra, 0, 1, 2, 3, tetra, 0); NewtonMeshEndBuild(tetrahedra); dMatrix aligmentUV(dGetIdentityMatrix()); int material = LoadTexture("smilli.tga"); NewtonMeshApplyBoxMapping (tetrahedra, material, material, material, &aligmentUV[0][0]); NewtonMeshCalculateVertexNormals (tetrahedra, 60.0f * dDegreeToRad); // make a deformable collision mesh NewtonCollision* const deformableCollision = NewtonCreateDeformableSolid(world, tetrahedra, materialID); //create a rigid body with a deformable mesh m_body = CreateRigidBody (scene, mass, deformableCollision); // create the soft body mesh DemoMesh* const mesh = new TetrahedraSoftMesh(scene, tetrahedra, m_body); SetMesh(mesh, dGetIdentityMatrix()); // do not forget to destroy this objects, else you get bad memory leaks. mesh->Release (); NewtonMeshDestroy (tetrahedra); NewtonDestroyCollision(deformableCollision); }
void LoadTetrahedraCube(DemoEntityManager* const scene, int materialID) { dFloat mass = 5.0f; NewtonWorld* const world = scene->GetNewton(); char name[2048]; dGetWorkingFileName ("box.tet", name); NewtonMesh* const tetraCube = NewtonMeshLoadTetrahedraMesh(scene->GetNewton(), name); dMatrix aligmentUV(dGetIdentityMatrix()); int material = LoadTexture("smilli.tga"); NewtonMeshApplyBoxMapping(tetraCube, material, material, material, &aligmentUV[0][0]); NewtonMeshCalculateVertexNormals(tetraCube, 60.0f * dDegreeToRad); // make a deformable collision mesh NewtonCollision* const deformableCollision = NewtonCreateDeformableSolid(world, tetraCube, materialID); //create a rigid body with a deformable mesh m_body = CreateRigidBody(scene, mass, deformableCollision); // create the soft body mesh //m_mesh = new TetrahedraSoftMesh(tetraCube, m_body); DemoMesh* const mesh = new TetrahedraSoftMesh(scene, tetraCube, m_body); SetMesh(mesh, dGetIdentityMatrix()); // do not forget to destroy this objects, else you get bad memory leaks. mesh->Release (); NewtonDestroyCollision(deformableCollision); NewtonMeshDestroy(tetraCube); }
NewtonMesh* CreateQuadClothPatch(DemoEntityManager* const scene, int size_x, int size_z) { size_x += 1; size_z += 1; dAssert(size_x <= 129); dAssert(size_z <= 129); dFloat dimension = 0.125f; dBigVector* const points = new dBigVector[size_x * size_z]; int* const faceIndexCount = new int[(size_x - 1) * (size_z - 1)]; int* const faceVertexIndex = new int[4 * (size_x - 1) * (size_z - 1)]; dFloat y = 0.0f; int vertexCount = 0; for (int i = 0; i < size_z; i++) { dFloat z = (i - size_z / 2) * dimension; for (int j = 0; j < size_x; j++) { dFloat x = (j - size_x / 2) * dimension; points[vertexCount] = dVector(x, y, z, 0.0f); vertexCount++; } } int faceCount = 0; for (int i = 0; i < size_z - 1; i++) { for (int j = 0; j < size_x - 1; j++) { faceIndexCount[faceCount] = 4; faceVertexIndex[faceCount * 4 + 0] = (i + 0) * size_x + j + 0; faceVertexIndex[faceCount * 4 + 1] = (i + 0) * size_x + j + 1; faceVertexIndex[faceCount * 4 + 2] = (i + 1) * size_x + j + 1; faceVertexIndex[faceCount * 4 + 3] = (i + 1) * size_x + j + 0; faceCount++; } } dMatrix aligmentUV(dGetIdentityMatrix()); NewtonMeshVertexFormat vertexFormat; NewtonMeshClearVertexFormat(&vertexFormat); vertexFormat.m_faceCount = faceCount; vertexFormat.m_faceIndexCount = faceIndexCount; vertexFormat.m_vertex.m_data = &points[0][0]; vertexFormat.m_vertex.m_indexList = faceVertexIndex; vertexFormat.m_vertex.m_strideInBytes = sizeof(dBigVector); NewtonMesh* const clothPatch = NewtonMeshCreate(scene->GetNewton()); NewtonMeshBuildFromVertexListIndexList(clothPatch, &vertexFormat); int material = LoadTexture("persianRug.tga"); NewtonMeshApplyBoxMapping(clothPatch, material, material, material, &aligmentUV[0][0]); delete[] points; delete[] faceIndexCount; delete[] faceVertexIndex; return clothPatch; }
static void AddFracturedPrimitive(DemoEntityManager* const scene, dFloat mass, const dVector& origin, const dVector& size, int xCount, int zCount, dFloat spacing, PrimitiveType type, int materialID, const dMatrix& shapeOffsetMatrix) { // create the shape and visual mesh as a common data to be re used NewtonWorld* const world = scene->GetNewton(); NewtonCollision* const collision = CreateConvexCollision(world, shapeOffsetMatrix, size, type, materialID); // create a newton mesh from the collision primitive NewtonMesh* const mesh = NewtonMeshCreateFromCollision(collision); // apply a material map int externalMaterial = LoadTexture("reljef.tga"); //int internalMaterial = LoadTexture("KAMEN-stup.tga"); int internalMaterial = LoadTexture("concreteBrick.tga"); dMatrix aligmentUV(dGetIdentityMatrix()); NewtonMeshApplyBoxMapping(mesh, externalMaterial, externalMaterial, externalMaterial, &aligmentUV[0][0]); // create a newton mesh from the collision primitive VoronoidEffect fracture(world, mesh, internalMaterial); DemoMesh* const visualMesh = new DemoMesh(mesh); dFloat startElevation = 100.0f; dMatrix matrix(dGetIdentityMatrix()); for (int i = 0; i < xCount; i++) { dFloat x = origin.m_x + (i - xCount / 2) * spacing; for (int j = 0; j < zCount; j++) { dFloat z = origin.m_z + (j - zCount / 2) * spacing; matrix.m_posit.m_x = x; matrix.m_posit.m_z = z; dVector floor(FindFloor(world, dVector(matrix.m_posit.m_x, startElevation, matrix.m_posit.m_z, 0.0f), 2.0f * startElevation)); matrix.m_posit.m_y = floor.m_y + 1.0f; SimpleFracturedEffectEntity::AddFracturedEntity(scene, visualMesh, collision, fracture, matrix.m_posit); } } // do not forget to release the assets NewtonMeshDestroy(mesh); visualMesh->Release(); NewtonDestroyCollision(collision); }
static void AddShatterPrimitive (DemoEntityManager* const scene, dFloat mass, const dVector& origin, const dVector& size, int xCount, int zCount, dFloat spacing, PrimitiveType type, int materialID) { dMatrix matrix (GetIdentityMatrix()); // create the shape and visual mesh as a common data to be re used NewtonWorld* const world = scene->GetNewton(); NewtonCollision* const collision = CreateConvexCollision (world, GetIdentityMatrix(), size, type, materialID); // create a newton mesh from the collision primitive NewtonMesh* const mesh = NewtonMeshCreateFromCollision(collision); // apply a material map int externalMaterial = LoadTexture("reljef.tga"); int internalMaterial = LoadTexture("KAMEN-stup.tga"); NewtonMeshApplyBoxMapping(mesh, externalMaterial, externalMaterial, externalMaterial); // create a newton mesh from the collision primitive ShatterEffect shatter (world, mesh, internalMaterial); DemoMesh* const visualMesh = new DemoMesh(mesh); for (int i = 0; i < xCount; i ++) { dFloat x = origin.m_x + (i - xCount / 2) * spacing; for (int j = 0; j < zCount; j ++) { dFloat z = origin.m_z + (j - zCount / 2) * spacing; matrix.m_posit.m_x = x; matrix.m_posit.m_z = z; matrix.m_posit.m_y = FindFloor (world, x, z) + 4.0f; AddShatterEntity (scene, visualMesh, collision, shatter, matrix.m_posit); } } // do not forget to release the assets NewtonMeshDestroy (mesh); visualMesh->Release(); NewtonReleaseCollision(world, collision); }
static void CreateSimpleVoronoiShatter (DemoEntityManager* const scene) { // create a collision primitive // dVector size (2.0f, 2.0f, 2.0f); // dVector size = dVector (10.0f, 0.5f, 10.0f, 0.0f); dVector size = dVector (5.0f, 5.0f, 5.0f, 0.0f); NewtonWorld* const world = scene->GetNewton(); // NewtonCollision* const collision = CreateConvexCollision (world, GetIdentityMatrix(), size, _BOX_PRIMITIVE, 0); NewtonCollision* const collision = CreateConvexCollision (world, GetIdentityMatrix(), size, _CAPSULE_PRIMITIVE, 0); // NewtonCollision* const collision = CreateConvexCollision (world, GetIdentityMatrix(), size, _SPHERE_PRIMITIVE, 0); // NewtonCollision* const collision = CreateConvexCollision (world, GetIdentityMatrix(), size, _REGULAR_CONVEX_HULL_PRIMITIVE, 0); // NewtonCollision* const collision = CreateConvexCollision (world, GetIdentityMatrix(), size, _RANDOM_CONVEX_HULL_PRIMITIVE, 0); // create a newton mesh from the collision primitive NewtonMesh* const mesh = NewtonMeshCreateFromCollision(collision); // apply a simple Box Mapping int tex0 = LoadTexture("reljef.tga"); NewtonMeshApplyBoxMapping(mesh, tex0, tex0, tex0); // pepper the bing box of the mesh with random points dVector points[NUMBER_OF_ITERNAL_PARTS + 100]; int count = 0; while (count < NUMBER_OF_ITERNAL_PARTS) { dFloat x = RandomVariable(size.m_x); dFloat y = RandomVariable(size.m_y); dFloat z = RandomVariable(size.m_z); if ((x <= size.m_x) && (x >= -size.m_x) && (y <= size.m_y) && (y >= -size.m_y) && (z <= size.m_z) && (z >= -size.m_z)){ points[count] = dVector (x, y, z); count ++; } } count = 4; // Create the array of convex pieces from the mesh int interior = LoadTexture("KAMEN-stup.tga"); // int interior = LoadTexture("camo.tga"); dMatrix textureMatrix (GetIdentityMatrix()); textureMatrix[0][0] = 1.0f / size.m_x; textureMatrix[1][1] = 1.0f / size.m_y; NewtonMesh* const convexParts = NewtonMeshVoronoiDecomposition (mesh, count, sizeof (dVector), &points[0].m_x, interior, &textureMatrix[0][0]); // NewtonMesh* const convexParts = NewtonMeshConvexDecomposition (mesh, 1000000); #if 1 dScene xxxx(world); dScene::dTreeNode* const modelNode = xxxx.CreateSceneNode(xxxx.GetRootNode()); dScene::dTreeNode* const meshNode = xxxx.CreateMeshNode(modelNode); dMeshNodeInfo* const modelMesh = (dMeshNodeInfo*)xxxx.GetInfoFromNode(meshNode); modelMesh->ReplaceMesh (convexParts); xxxx.Serialize("../../../media/xxx.ngd"); #endif DemoEntity* const entity = new DemoEntity(NULL); entity->SetMatrix(*scene, dQuaternion(), dVector (0, 10, 0, 0)); entity->InterpolateMatrix (*scene, 1.0f); scene->Append (entity); DemoMesh* const mesh1 = new DemoMesh(convexParts); entity->SetMesh(mesh1); mesh1->Release(); /* DemoEntity* const entity2 = new DemoEntity(NULL); entity2->SetMatrix(*scene, dQuaternion(), dVector (0, 10, 0, 0)); entity2->InterpolateMatrix (*scene, 1.0f); scene->Append (entity2); DemoMesh* const mesh2 = new DemoMesh(mesh); entity2->SetMesh(mesh2); mesh2->Release(); */ // make sure the assets are released before leaving the function if (convexParts) { NewtonMeshDestroy (convexParts); } NewtonMeshDestroy (mesh); NewtonReleaseCollision(world, collision); }
static void AddStructuredFractured (DemoEntityManager* const scene, const dVector& origin, int materialID, const char* const assetName) { // create the shape and visual mesh as a common data to be re used NewtonWorld* const world = scene->GetNewton(); #if 0 // load the mesh asset DemoEntity entity(GetIdentityMatrix(), NULL); entity.LoadNGD_mesh (assetName, world); DemoMesh____* const mesh = entity.GetMesh(); dAssert (mesh); // convert the mesh to a newtonMesh NewtonMesh* const solidMesh = mesh->CreateNewtonMesh (world, entity.GetMeshMatrix() * entity.GetCurrentMatrix()); #else int externalMaterial = LoadTexture("wood_0.tga"); NewtonCollision* const collision = CreateConvexCollision (world, dGetIdentityMatrix(), dVector (3.0f, 3.0f, 3.0f, 0.0), _BOX_PRIMITIVE, 0); NewtonMesh* const solidMesh = NewtonMeshCreateFromCollision(collision); NewtonDestroyCollision(collision); //NewtonMeshTriangulate(solidMesh); NewtonMeshApplyBoxMapping (solidMesh, externalMaterial, externalMaterial, externalMaterial); #endif // create a random point cloud dVector points[MAX_POINT_CLOUD_SIZE]; int pointCount = MakeRandomPoisonPointCloud (solidMesh, points); // int pointCount = MakeRandomGuassianPointCloud (solidMesh, points, MAX_POINT_CLOUD_SIZE); // create and interiors material for texturing the fractured pieces //int internalMaterial = LoadTexture("KAMEN-stup.tga"); int internalMaterial = LoadTexture("concreteBrick.tga"); // crate a texture matrix for uv mapping of fractured pieces dMatrix textureMatrix (dGetIdentityMatrix()); textureMatrix[0][0] = 1.0f / 2.0f; textureMatrix[1][1] = 1.0f / 2.0f; /// create the fractured collision and mesh int debreePhysMaterial = NewtonMaterialGetDefaultGroupID(world); NewtonCollision* structuredFracturedCollision = NewtonCreateFracturedCompoundCollision (world, solidMesh, 0, debreePhysMaterial, pointCount, &points[0][0], sizeof (dVector), internalMaterial, &textureMatrix[0][0], OnReconstructMainMeshCallBack, OnEmitFracturedCompound, OnEmitFracturedChunk); // uncomment this to test serialization #if 0 FILE* file = fopen ("serialize.bin", "wb"); NewtonCollisionSerialize (world, structuredFracturedCollision, DemoEntityManager::SerializeFile, file); NewtonDestroyCollision (structuredFracturedCollision); fclose (file); file = fopen ("serialize.bin", "rb"); structuredFracturedCollision = NewtonCreateCollisionFromSerialization (world, DemoEntityManager::DeserializeFile, file); NewtonFracturedCompoundSetCallbacks (structuredFracturedCollision, OnReconstructMainMeshCallBack, OnEmitFracturedCompound, OnEmitFracturedChunk); fclose (file); #endif #if 0 // test the interface dTree<void*, void*> detachableNodes; NewtonCompoundCollisionBeginAddRemove(structuredFracturedCollision); // remove all chunk that can be detached for the first layer for (void* node = NewtonCompoundCollisionGetFirstNode(structuredFracturedCollision); node; node = NewtonCompoundCollisionGetNextNode(structuredFracturedCollision, node)) { if (NewtonFracturedCompoundIsNodeFreeToDetach (structuredFracturedCollision, node)) { detachableNodes.Insert(node, node); } // remove any node that can be deched fro the secund layer, this codul; be reusive void* neighbors[32]; int count = NewtonFracturedCompoundNeighborNodeList (structuredFracturedCollision, node, neighbors, sizeof (neighbors) / sizeof (neighbors[0])); for (int i = 0; i < count; i ++ ) { if (NewtonFracturedCompoundIsNodeFreeToDetach (structuredFracturedCollision, neighbors[i])) { detachableNodes.Insert(node, node); } } } // now delete the actual nodes dTree<void*, void*>::Iterator iter (detachableNodes) ; for (iter.Begin(); iter; iter ++) { void* const node = iter.GetNode()->GetInfo(); NewtonCompoundCollisionRemoveSubCollision (structuredFracturedCollision, node); } NewtonCompoundCollisionEndAddRemove(structuredFracturedCollision); #endif #if 1 dVector plane (0.0f, 1.0f, 0.0f, 0.0f); NewtonCollision* const crack = NewtonFracturedCompoundPlaneClip (structuredFracturedCollision, &plane[0]); if (crack) { NewtonDestroyCollision (structuredFracturedCollision); } #endif dVector com(0.0f); dVector inertia(0.0f); NewtonConvexCollisionCalculateInertialMatrix (structuredFracturedCollision, &inertia[0], &com[0]); //dFloat mass = 10.0f; //int materialId = 0; //create the rigid body dMatrix matrix (dGetIdentityMatrix()); matrix.m_posit = origin; matrix.m_posit.m_y = 20.0; matrix.m_posit.m_w = 1.0f; NewtonBody* const rigidBody = NewtonCreateDynamicBody (world, structuredFracturedCollision, &matrix[0][0]); // set the mass and center of mass dFloat density = 1.0f; dFloat mass = density * NewtonConvexCollisionCalculateVolume (structuredFracturedCollision); NewtonBodySetMassProperties (rigidBody, mass, structuredFracturedCollision); // set the transform call back function NewtonBodySetTransformCallback (rigidBody, DemoEntity::TransformCallback); // set the force and torque call back function NewtonBodySetForceAndTorqueCallback (rigidBody, PhysicsApplyGravityForce); // create the entity and visual mesh and attach to the body as user data CreateVisualEntity (scene, rigidBody); // assign the wood id // NewtonBodySetMaterialGroupID (rigidBody, materialId); // set a destructor for this rigid body // NewtonBodySetDestructorCallback (rigidBody, PhysicsBodyDestructor); // release the interior texture // ReleaseTexture (internalMaterial); // delete the solid mesh since it no longed needed NewtonMeshDestroy (solidMesh); // destroy the fracture collision NewtonDestroyCollision (structuredFracturedCollision); }
DemoMesh::DemoMesh(const char* const name, const NewtonCollision* const collision, const char* const texture0, const char* const texture1, const char* const texture2, dFloat opacity, const dMatrix& uvMatrix) :DemoMeshInterface() ,dList<DemoSubMesh>() ,m_uv(NULL) ,m_vertex(NULL) ,m_normal(NULL) ,m_optimizedOpaqueDiplayList(0) ,m_optimizedTransparentDiplayList(0) { // create a helper mesh from the collision collision NewtonMesh* const mesh = NewtonMeshCreateFromCollision(collision); // apply the vertex normals NewtonMeshCalculateVertexNormals(mesh, 30.0f * dDegreeToRad); dMatrix aligmentUV(uvMatrix); // NewtonCollisionGetMatrix(collision, &aligmentUV[0][0]); aligmentUV = aligmentUV.Inverse(); // apply uv projections NewtonCollisionInfoRecord info; NewtonCollisionGetInfo (collision, &info); switch (info.m_collisionType) { case SERIALIZE_ID_SPHERE: { NewtonMeshApplySphericalMapping(mesh, LoadTexture (texture0), &aligmentUV[0][0]); break; } case SERIALIZE_ID_CONE: case SERIALIZE_ID_CAPSULE: case SERIALIZE_ID_CYLINDER: case SERIALIZE_ID_CHAMFERCYLINDER: { //NewtonMeshApplySphericalMapping(mesh, LoadTexture(texture0)); NewtonMeshApplyCylindricalMapping(mesh, LoadTexture(texture0), LoadTexture(texture1), &aligmentUV[0][0]); break; } default: { int tex0 = LoadTexture(texture0); int tex1 = LoadTexture(texture1); int tex2 = LoadTexture(texture2); NewtonMeshApplyBoxMapping(mesh, tex0, tex1, tex2, &aligmentUV[0][0]); break; } } // extract vertex data from the newton mesh int vertexCount = NewtonMeshGetPointCount (mesh); AllocVertexData(vertexCount); NewtonMeshGetVertexChannel(mesh, 3 * sizeof (dFloat), (dFloat*)m_vertex); NewtonMeshGetNormalChannel(mesh, 3 * sizeof (dFloat), (dFloat*)m_normal); NewtonMeshGetUV0Channel(mesh, 2 * sizeof (dFloat), (dFloat*)m_uv); // extract the materials index array for mesh void* const geometryHandle = NewtonMeshBeginHandle (mesh); for (int handle = NewtonMeshFirstMaterial (mesh, geometryHandle); handle != -1; handle = NewtonMeshNextMaterial (mesh, geometryHandle, handle)) { int material = NewtonMeshMaterialGetMaterial (mesh, geometryHandle, handle); int indexCount = NewtonMeshMaterialGetIndexCount (mesh, geometryHandle, handle); DemoSubMesh* const segment = AddSubMesh(); segment->m_textureHandle = (GLuint)material; segment->SetOpacity(opacity); segment->AllocIndexData (indexCount); NewtonMeshMaterialGetIndexStream (mesh, geometryHandle, handle, (int*)segment->m_indexes); } NewtonMeshEndHandle (mesh, geometryHandle); // destroy helper mesh NewtonMeshDestroy(mesh); // optimize this mesh for hardware buffers if possible OptimizeForRender (); }
static void CreateConvexAproximation (const char* const name, DemoEntityManager* const scene, const dVector& origin, int instaceCount, const char* const texture) { char fileName[2048]; dGetWorkingFileName (name, fileName); NewtonWorld* const world = scene->GetNewton(); dScene compoundTestMesh (world); compoundTestMesh.Deserialize(fileName); // freeze the scale and pivot on the model compoundTestMesh.FreezeScale(); // compoundTestMesh.FreezeGeometryPivot (); dMeshNodeInfo* meshInfo = NULL; dMatrix scale (dGetIdentityMatrix()); for (dScene::dTreeNode* node = compoundTestMesh.GetFirstNode (); node; node = compoundTestMesh.GetNextNode (node)) { dNodeInfo* info = compoundTestMesh.GetInfoFromNode(node); if (info->GetTypeId() == dMeshNodeInfo::GetRttiType()) { for (void* link = compoundTestMesh.GetFirstParentLink(node); link; link = compoundTestMesh.GetNextParentLink (node, link)) { dScene::dTreeNode* const node = compoundTestMesh.GetNodeFromLink(link); dNodeInfo* const info = compoundTestMesh.GetInfoFromNode(node); if (info->GetTypeId() == dSceneNodeInfo::GetRttiType()) { scale = ((dSceneNodeInfo*)info)->GetGeometryTransform(); break; } } meshInfo = (dMeshNodeInfo*) info; break; } } NewtonMeshApplyTransform(meshInfo->GetMesh(), &scale[0][0]); dAssert (meshInfo); dAssert (meshInfo->GetMesh()); #if 1 NewtonMesh* const mesh = meshInfo->GetMesh(); #else dGetWorkingFileName ("mesh.off", fileName); NewtonMesh* const mesh = NewtonMeshLoadOFF(world, fileName); // dMatrix scale (GetIdentityMatrix()); // //dFloat scaleMag = 0.05f; // dFloat scaleMag = 1.0f; // scale[0][0] = scaleMag; // scale[1][1] = scaleMag; // scale[2][2] = scaleMag; // NewtonMesApplyTransform (mesh, &scale[0][0]); #endif //NewtonMesh* const newtonMesh = NewtonMeshSimplify(mesh, 500, ReportProgress); // create a convex approximation form the original mesh, 32 convex max and no more than 100 vertex convex hulls // NewtonMesh* const convexApproximation = NewtonMeshApproximateConvexDecomposition (mesh, 0.01f, 0.2f, 32, 100, ReportProgress, scene); NewtonMesh* const convexApproximation = NewtonMeshApproximateConvexDecomposition (mesh, 0.01f, 0.2f, 256, 100, ReportProgress, scene); // NewtonMesh* const convexApproximation = NewtonMeshApproximateConvexDecomposition (mesh, 0.00001f, 0.0f, 256, 100, ReportProgress, scene); // create a compound collision by creation a convex hull of each segment of the source mesh NewtonCollision* const compound = NewtonCreateCompoundCollisionFromMesh (world, convexApproximation, 0.001f, 0, 0); // test collision mode // NewtonCollisionSetCollisonMode(compound, 0); // make a visual Mesh int tex = LoadTexture(texture); dMatrix aligmentUV(dGetIdentityMatrix()); NewtonMeshApplyBoxMapping(mesh, tex, tex, tex, &aligmentUV[0][0]); DemoMesh* const visualMesh = new DemoMesh (mesh); dMatrix matrix (dGetIdentityMatrix()); matrix.m_posit = origin; for (int ix = 0; ix < instaceCount; ix ++) { for (int iz = 0; iz < instaceCount; iz ++) { dFloat y = origin.m_y; dFloat x = origin.m_x + (ix - instaceCount/2) * 10.0f; dFloat z = origin.m_z + (iz - instaceCount/2) * 10.0f; matrix.m_posit = FindFloor (world, dVector (x, y + 10.0f, z, 0.0f), 20.0f); ; matrix.m_posit.m_y += 2.0f; CreateSimpleSolid (scene, visualMesh, 10.0f, matrix, compound, 0); } } visualMesh->Release(); NewtonDestroyCollision(compound); NewtonMeshDestroy (convexApproximation); }