DelaunayEffect(NewtonWorld* const world, NewtonMesh* const mesh, int interiorMaterial) :FractureEffect(world) { // first we populate the bounding Box area with few random point to get some interior subdivisions. // the subdivision are local to the point placement, by placing these points visual ally with a 3d tool // and have precise control of how the debris are created. // the number of pieces is equal to the number of point inside the Mesh plus the number of point on the mesh dVector size(0.0f); dMatrix matrix(dGetIdentityMatrix()); NewtonMeshCalculateOOBB(mesh, &matrix[0][0], &size.m_x, &size.m_y, &size.m_z); // create a texture matrix, for applying the material's UV to all internal faces dMatrix textureMatrix(dGetIdentityMatrix()); textureMatrix[0][0] = 1.0f / size.m_x; textureMatrix[1][1] = 1.0f / size.m_y; // Get the volume of the original mesh NewtonCollision* const collision1 = NewtonCreateConvexHullFromMesh(m_world, mesh, 0.0f, 0); dFloat volume = NewtonConvexCollisionCalculateVolume(collision1); NewtonDestroyCollision(collision1); // now we call create we decompose the mesh into several convex pieces NewtonMesh* const debriMeshPieces = NewtonMeshCreateTetrahedraIsoSurface(mesh); dAssert(debriMeshPieces); // now we iterate over each pieces and for each one we create a visual entity and a rigid body NewtonMesh* nextDebri; for (NewtonMesh* debri = NewtonMeshCreateFirstLayer(debriMeshPieces); debri; debri = nextDebri) { // get next segment piece nextDebri = NewtonMeshCreateNextLayer(debriMeshPieces, debri); //clip the Delaunay convexes against the mesh, make a convex hull collision shape NewtonCollision* const collision = NewtonCreateConvexHullFromMesh(m_world, debri, 0.0f, 0); if (collision) { // we have a piece which has a convex collision representation, add that to the list FractureAtom& atom = Append()->GetInfo(); atom.m_mesh = new DemoMesh(debri); atom.m_collision = collision; NewtonConvexCollisionCalculateInertialMatrix(atom.m_collision, &atom.m_momentOfInirtia[0], &atom.m_centerOfMass[0]); dFloat debriVolume = NewtonConvexCollisionCalculateVolume(atom.m_collision); atom.m_massFraction = debriVolume / volume; } NewtonMeshDestroy(debri); } NewtonMeshDestroy(debriMeshPieces); }
void CreateTetrahedraPrimitive(DemoEntityManager* const scene, int materialID) { dFloat mass = 5.0f; dVector size (1.0f); NewtonWorld* const world = scene->GetNewton(); NewtonCollision* const primitiveShape = CreateConvexCollision (world, dGetIdentityMatrix(), size, _SPHERE_PRIMITIVE, materialID); //NewtonCollision* const primitiveShape = CreateConvexCollision (world, dGetIdentityMatrix(), size, _BOX_PRIMITIVE, materialID); NewtonMesh* const skinMesh = NewtonMeshCreateFromCollision(primitiveShape); dMatrix aligmentUV(dGetIdentityMatrix()); int material = LoadTexture("smilli.tga"); NewtonMeshApplySphericalMapping(skinMesh, material, &aligmentUV[0][0]); // now now make an tetrahedra iso surface approximation of this mesh NewtonMesh* const tetraIsoSurface = NewtonMeshCreateTetrahedraIsoSurface(skinMesh); // calculate the linear blend weight for the tetrahedra mesh NewtonCreateTetrahedraLinearBlendSkinWeightsChannel (tetraIsoSurface, skinMesh); NewtonDestroyCollision(primitiveShape); // make a deformable collision mesh NewtonCollision* const deformableCollision = NewtonCreateDeformableSolid(world, tetraIsoSurface, 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(tetraIsoSurface, m_body); DemoMesh* const mesh = new LinearBlendMeshTetra(scene, skinMesh, m_body); SetMesh(mesh, dGetIdentityMatrix()); // do not forget to destroy this objects, else you get bad memory leaks. mesh->Release (); NewtonMeshDestroy(skinMesh); NewtonDestroyCollision(deformableCollision); NewtonMeshDestroy(tetraIsoSurface); }