static void CreateScaleStaticMesh (DemoEntity* const entity, NewtonCollision* const collision, DemoEntityManager* const scene, const dMatrix& location, const dVector& scale) { // now make a scale version of the same model // first Get The mesh and make a scale copy DemoMesh* const mesh = (DemoMesh*)entity->GetMesh(); dAssert (mesh->IsType(DemoMesh::GetRttiType())); // since the render does no handle scale, we will made a duplicated mesh with the scale baked in DemoMesh* const scaledMesh = new DemoMesh (*mesh); // now scale the vertex list for (int i = 0 ; i < mesh->m_vertexCount; i ++) { scaledMesh->m_vertex[i * 3 + 0] *= scale.m_x; scaledMesh->m_vertex[i * 3 + 1] *= scale.m_y; scaledMesh->m_vertex[i * 3 + 2] *= scale.m_z; } // re-optimize for render scaledMesh->OptimizeForRender(); DemoEntity* const scaledEntity = new DemoEntity(location, NULL); scene->Append (scaledEntity); scaledEntity->SetMesh(scaledMesh, dGetIdentityMatrix()); scaledMesh->Release(); // now make a body with a scaled collision mesh // note: the collision do not have to be destroyed because we did no create a new collision we are simple using an existing one NewtonBody* const scaledBody = NewtonCreateDynamicBody(scene->GetNewton(), collision, &location[0][0]); NewtonBodySetUserData(scaledBody, scaledEntity); // apply the scale to the new body collision; // // note: scaling a collision mesh does not updates the broadPhase, this function is a until that do update broad phase NewtonBodySetCollisionScale (scaledBody, scale.m_x, scale.m_y, scale.m_z); }
static void AddNonUniformScaledPrimitives(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[0][0], size, type, materialID); NewtonCollision* const collision = CreateConvexCollision(world, dGetIdentityMatrix(), size, type, materialID); dFloat startElevation = 1000.0f; dMatrix matrix(dGetIdentityMatrix()); //matrix = dPitchMatrix(-45.0f * 3.141592f/180.0f); for (int i = 0; i < xCount; i++) { dFloat x = origin.m_x + (i - xCount / 2) * spacing; for (int j = 0; j < zCount; j++) { dFloat scalex = 1.0f + 1.5f * (dFloat(dRand()) / dFloat(dRAND_MAX) - 0.5f); dFloat scaley = 1.0f + 1.5f * (dFloat(dRand()) / dFloat(dRAND_MAX) - 0.5f); dFloat scalez = 1.0f + 1.5f * (dFloat(dRand()) / dFloat(dRAND_MAX) - 0.5f); 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 + 8.0f; // create a solid //NewtonBody* const body = CreateSimpleSolid (scene, geometry, mass, matrix, collision, materialID); NewtonBody* const body = CreateSimpleSolid(scene, NULL, mass, matrix, collision, materialID); DemoEntity* entity = (DemoEntity*)NewtonBodyGetUserData(body); NewtonCollisionSetScale(collision, scalex, scaley, scalez); DemoMesh* const geometry = new DemoMesh("cylinder_1", collision, "smilli.tga", "smilli.tga", "smilli.tga"); entity->SetMesh(geometry, dGetIdentityMatrix()); NewtonBodySetCollisionScale(body, scalex, scaley, scalez); dVector omega(0.0f); NewtonBodySetOmega(body, &omega[0]); // release the mesh geometry->Release(); } } // do not forget to delete the collision NewtonDestroyCollision(collision); }