ShatterEffect(NewtonWorld* const world, NewtonMesh* const mesh, int interiorMaterial)
		:dList<ShatterAtom>(), m_world (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;
		dMatrix matrix(GetIdentityMatrix()); 
		NewtonMeshCalculateOOBB(mesh, &matrix[0][0], &size.m_x, &size.m_y, &size.m_z);

		// pepper the inside of the BBox box of the mesh with random points
		int count = 0;
		dVector points[NUMBER_OF_ITERNAL_PARTS + 1];
		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 ++;
			}
		} 

		// create a texture matrix, for applying the material's UV to all internal faces
		dMatrix textureMatrix (GetIdentityMatrix());
		textureMatrix[0][0] = 1.0f / size.m_x;
		textureMatrix[1][1] = 1.0f / size.m_y;

		// now we call create we decompose the mesh into several convex pieces 
		NewtonMesh* const debriMeshPieces = NewtonMeshVoronoiDecomposition (mesh, count, sizeof (dVector), &points[0].m_x, interiorMaterial, &textureMatrix[0][0]);


		// Get the volume of the original mesh
		NewtonCollision* const collision = NewtonCreateConvexHullFromMesh (m_world, mesh, 0.0f, 0);
		dFloat volume = NewtonConvexCollisionCalculateVolume (collision);
		NewtonReleaseCollision(m_world, collision);

		// 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) {
			nextDebri = NewtonMeshCreateNextLayer (debriMeshPieces, debri); 

			NewtonCollision* const collision = NewtonCreateConvexHullFromMesh (m_world, debri, 0.0f, 0);
			if (collision) {
				ShatterAtom& 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);
	}
Esempio n. 2
0
NewtonBody* Body::create(NewtonCollision* collision, float mass, int freezeState, const Vec4f& damping)
{
	Vec4f minBox, maxBox;
	Vec4f origin, inertia;

	m_body = NewtonCreateBody(newton::world, collision, this->m_matrix[0]);

	NewtonBodySetUserData(m_body, this);
	NewtonBodySetMatrix(m_body, this->m_matrix[0]);
	NewtonConvexCollisionCalculateInertialMatrix(collision, &inertia[0], &origin[0]);

	if (mass < 0.0f)
		mass = NewtonConvexCollisionCalculateVolume(collision) * 0.5f;

	if (mass != 0.0f)
		NewtonBodySetMassMatrix(m_body, mass, mass * inertia.x, mass * inertia.y, mass * inertia.z);

	NewtonBodySetCentreOfMass(m_body, &origin[0]);

	NewtonBodySetForceAndTorqueCallback(m_body, Body::__applyForceAndTorqueCallback);
	NewtonBodySetTransformCallback(m_body, Body::__setTransformCallback);
	NewtonBodySetDestructorCallback(m_body, Body::__destroyBodyCallback);

	NewtonBodySetFreezeState(m_body, freezeState);
	NewtonBodySetLinearDamping(m_body, damping.w);
	NewtonBodySetAngularDamping(m_body, &damping[0]);

	return m_body;
}
	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);
	}
Esempio n. 4
0
void LoadLumberYardMesh(DemoEntityManager* const scene, const dVector& location, int shapeid)
{
	DemoEntity* const entity = DemoEntity::LoadNGD_mesh ("lumber.ngd", scene->GetNewton(), scene->GetShaderCache());

	dTree<NewtonCollision*, DemoMesh*> filter;
	NewtonWorld* const world = scene->GetNewton();

	dFloat density = 15.0f;

	int defaultMaterialID = NewtonMaterialGetDefaultGroupID(scene->GetNewton());
	for (DemoEntity* child = entity->GetFirst(); child; child = child->GetNext()) {
		DemoMesh* const mesh = (DemoMesh*)child->GetMesh();
		if (mesh) {
			dAssert(mesh->IsType(DemoMesh::GetRttiType()));
			dTree<NewtonCollision*, DemoMesh*>::dTreeNode* node = filter.Find(mesh);
			if (!node) {
				// make a collision shape only for and instance
				dFloat* const array = mesh->m_vertex;
				dVector minBox(1.0e10f, 1.0e10f, 1.0e10f, 1.0f);
				dVector maxBox(-1.0e10f, -1.0e10f, -1.0e10f, 1.0f);

				for (int i = 0; i < mesh->m_vertexCount; i++) {
					dVector p(array[i * 3 + 0], array[i * 3 + 1], array[i * 3 + 2], 1.0f);
					minBox.m_x = dMin(p.m_x, minBox.m_x);
					minBox.m_y = dMin(p.m_y, minBox.m_y);
					minBox.m_z = dMin(p.m_z, minBox.m_z);

					maxBox.m_x = dMax(p.m_x, maxBox.m_x);
					maxBox.m_y = dMax(p.m_y, maxBox.m_y);
					maxBox.m_z = dMax(p.m_z, maxBox.m_z);
				}

				dVector size(maxBox - minBox);
				dMatrix offset(dGetIdentityMatrix());
				offset.m_posit = (maxBox + minBox).Scale(0.5f);
				NewtonCollision* const shape = NewtonCreateBox(world, size.m_x, size.m_y, size.m_z, shapeid, &offset[0][0]);
				node = filter.Insert(shape, mesh);
			}

			// create a body and add to the world
			NewtonCollision* const shape = node->GetInfo();
			dMatrix matrix(child->GetMeshMatrix() * child->CalculateGlobalMatrix());
			matrix.m_posit += location;
			dFloat mass = density * NewtonConvexCollisionCalculateVolume(shape);
			CreateSimpleSolid(scene, mesh, mass, matrix, shape, defaultMaterialID);
		}
	}

	// destroy all shapes
	while (filter.GetRoot()) {
		NewtonCollision* const shape = filter.GetRoot()->GetInfo();
		NewtonDestroyCollision(shape);
		filter.Remove(filter.GetRoot());
	}
	delete entity;
}
	float Collider3D::ComputeVolume() const
	{
		float volume;

		// Check for existing collision handles, and create a temporary one if none is available
		if (m_handles.empty())
		{
			PhysWorld3D world;

			NewtonCollision* collision = CreateHandle(&world);
			{
				volume = NewtonConvexCollisionCalculateVolume(collision);
			}
			NewtonDestroyCollision(collision);
		}
		else
			volume = NewtonConvexCollisionCalculateVolume(m_handles.begin()->second);

		return volume;
	}
Esempio n. 6
0
	float Collider3D::ComputeVolume() const
	{
		float volume;

		// Si nous n'avons aucune instance, nous en créons une temporaire
		if (m_handles.empty())
		{
			PhysWorld3D world;

			NewtonCollision* collision = CreateHandle(&world);
			{
				volume = NewtonConvexCollisionCalculateVolume(collision);
			}
			NewtonDestroyCollision(collision);
		}
		else // Sinon on utilise une instance au hasard (elles sont toutes identiques de toute façon)
			volume = NewtonConvexCollisionCalculateVolume(m_handles.begin()->second);

		return volume;
	}
	void SetModelMass( dFloat mass, dAnimationJointRoot* const rootNode) const
	{
		dFloat volume = 0.0f;
		for (dAnimationJoint* joint = GetFirstJoint(rootNode); joint; joint = GetNextJoint(joint)) {
			volume += NewtonConvexCollisionCalculateVolume(NewtonBodyGetCollision(joint->GetBody()));
		}
		dFloat density = mass / volume;

		for (dAnimationJoint* joint = GetFirstJoint(rootNode); joint; joint = GetNextJoint(joint)) {
			dFloat Ixx;
			dFloat Iyy;
			dFloat Izz;
			NewtonBody* const body = joint->GetBody();
			NewtonBodyGetMass(body, &mass, &Ixx, &Iyy, &Izz);
			dFloat scale = density * NewtonConvexCollisionCalculateVolume(NewtonBodyGetCollision(body));
			mass *= scale;
			Ixx *= scale;
			Iyy *= scale;
			Izz *= scale;
			NewtonBodySetMassMatrix(body, mass, Ixx, Iyy, Izz);
		}
	}
Esempio n. 8
0
/*
=============
CMod_PhysicsAddEntity
=============
*/
void CMod_PhysicsAddEntity(sharedEntity_t * gEnt) {
	NewtonCollision* collision = NULL;
	NewtonBody* body = NULL;

	std::map<int, bspCmodel>::iterator it = bspModels.find (gEnt->s.modelindex);
	if ( it == bspModels.end() ) {
		return;
	}
	
	vec3_t inertia, com;
	dMatrix matrix (GetIdentityMatrix());
	bspCmodel* bmodel = &it->second;
	
	collision = NewtonCreateConvexHull (g_world, bmodel->vertices.size(), &bmodel->vertices[0].m_x, sizeof (dVector), 0.0f, &matrix[0][0]);
	body = NewtonCreateBody (g_world, collision);
	NewtonConvexCollisionCalculateVolume (collision);
	NewtonReleaseCollision (g_world, collision);
	
	bmodel->rigidBody = body;

	NewtonBodySetMaterialGroupID (body, defaultMaterialGroup);
	NewtonBodySetUserData (body, (void*)gEnt);
	NewtonBodySetDestructorCallback (body, PhysicsEntityDie);
	NewtonBodySetContinuousCollisionMode (body, 0);
	NewtonBodySetForceAndTorqueCallback (body, PhysicsEntityThink);
	NewtonBodySetTransformCallback (body, PhysicsEntitySetTransform);
	
	NewtonConvexCollisionCalculateInertialMatrix (collision, &inertia[0], &com[0]);
	NewtonBodySetCentreOfMass (body, &com[0]);
	
	VectorScale (inertia, 10.0f, inertia); // The inertia needs to be scaled by the mass.
	
	NewtonBodySetMassMatrix (body, 10.f, inertia[0], inertia[1], inertia[2]);
	
	matrix.m_posit.m_x = gEnt->s.origin[0] * UNITS_PER_METRE;
	matrix.m_posit.m_y = gEnt->s.origin[1] * UNITS_PER_METRE;
	matrix.m_posit.m_z = gEnt->s.origin[2] * UNITS_PER_METRE;
	NewtonBodySetMatrix (body, &matrix[0][0]);
	
	gEnt->s.pos.trType = TR_INTERPOLATE;
	VectorCopy (gEnt->s.origin, gEnt->s.pos.trBase);
	VectorCopy (gEnt->s.origin, gEnt->r.currentOrigin);
	
	gEnt->s.apos.trType = TR_INTERPOLATE;
	VectorCopy (gEnt->s.angles, gEnt->s.apos.trBase);
	VectorCopy (gEnt->s.angles, gEnt->r.currentAngles);
}
void dNewtonBody::CalculateBuoyancyForces(const void* plane, void* force, void* torque, float bodyDensity)
{
	dFloat Ixx;
	dFloat Iyy;
	dFloat Izz;
	dFloat mass;

	NewtonBodyGetMass(m_body, &mass, &Ixx, &Iyy, &Izz);

	if (mass > 0.0f) {
		dMatrix matrix;
		dVector cog(0.0f);
		dVector accelPerUnitMass(0.0f);
		dVector torquePerUnitMass(0.0f);
		const dVector gravity(0.0f, -9.8f, 0.0f, 0.0f);

		NewtonBodyGetMatrix(m_body, &matrix[0][0]);
		NewtonBodyGetCentreOfMass(m_body, &cog[0]);
		cog = matrix.TransformVector(cog);
		NewtonCollision* const collision = NewtonBodyGetCollision(m_body);

		dFloat shapeVolume = NewtonConvexCollisionCalculateVolume(collision);
		dFloat fluidDensity = 1.0f / (bodyDensity * shapeVolume);
		dFloat viscosity = 0.995f;

		NewtonConvexCollisionCalculateBuoyancyAcceleration(collision, &matrix[0][0], &cog[0], &gravity[0], (float*)plane, fluidDensity, viscosity, &accelPerUnitMass[0], &torquePerUnitMass[0]);

		dVector finalForce(accelPerUnitMass.Scale(mass));
		dVector finalTorque(torquePerUnitMass.Scale(mass));

		dVector omega(0.0f);
		NewtonBodyGetOmega(m_body, &omega[0]);
		omega = omega.Scale(viscosity);
		NewtonBodySetOmega(m_body, &omega[0]);

		((float*)force)[0] = finalForce.m_x ;
		((float*)force)[1] = finalForce.m_y ;
		((float*)force)[2] = finalForce.m_z ;
		((float*)torque)[0] = finalTorque.m_x;
		((float*)torque)[1] = finalTorque.m_y;
		((float*)torque)[2] = finalTorque.m_z;
	}
}
		void OnInside(NewtonBody* const visitor)
		{
			dFloat Ixx;
			dFloat Iyy;
			dFloat Izz;
			dFloat mass;
			
			NewtonBodyGetMass(visitor, &mass, &Ixx, &Iyy, &Izz);
			if (mass > 0.0f) {
				dMatrix matrix;
				dVector cog(0.0f);
				dVector accelPerUnitMass(0.0f);
				dVector torquePerUnitMass(0.0f);
				const dVector gravity (0.0f, DEMO_GRAVITY, 0.0f, 0.0f);

				NewtonBodyGetMatrix (visitor, &matrix[0][0]);
				NewtonBodyGetCentreOfMass(visitor, &cog[0]);
				cog = matrix.TransformVector (cog);
				NewtonCollision* const collision = NewtonBodyGetCollision(visitor);

				
				dFloat shapeVolume = NewtonConvexCollisionCalculateVolume (collision);
				dFloat fluidDentity = 1.0f / (m_waterToSolidVolumeRatio * shapeVolume);
				dFloat viscosity = 0.995f;

				NewtonConvexCollisionCalculateBuoyancyAcceleration (collision, &matrix[0][0], &cog[0], &gravity[0], &m_plane[0], fluidDentity, viscosity, &accelPerUnitMass[0], &torquePerUnitMass[0]);

				dVector force (accelPerUnitMass.Scale (mass));
				dVector torque (torquePerUnitMass.Scale (mass));

				dVector omega(0.0f); 
				NewtonBodyGetOmega(visitor, &omega[0]);
				omega = omega.Scale (viscosity);
				NewtonBodySetOmega(visitor, &omega[0]);

				NewtonBodyAddForce (visitor, &force[0]);
				NewtonBodyAddTorque (visitor, &torque[0]);
			}
		}
Esempio n. 11
0
float NzBaseGeom::ComputeVolume() const
{
	return NewtonConvexCollisionCalculateVolume(m_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);
}
static void CreateDebriPiece (const NewtonBody* sourceBody, NewtonMesh* mesh, dFloat volume)
{
	dFloat Ixx;
	dFloat Iyy;
	dFloat Izz;
	dFloat mass;
	dFloat shapeVolume;
	NewtonWorld* world;
	NewtonBody* rigidBody;
	NewtonCollision* collision;
	OGLMesh* meshInstance;
	SceneManager* system;
	RenderPrimitive* primitive;
	dVector inertia;
	dVector origin;
	dVector veloc;
	dVector omega;
	dMatrix matrix;

	world = NewtonBodyGetWorld (sourceBody);

	NewtonBodyGetMatrix (sourceBody, &matrix[0][0]);

	NewtonBodyGetMassMatrix (sourceBody, &mass, &Ixx, &Iyy, &Izz);

	// make a visual object
	meshInstance = new OGLMesh();

	meshInstance->BuildFromMesh (mesh);

	// create a visual geometry
	primitive = new RenderPrimitive (matrix, meshInstance);
	meshInstance->Release();

	// save the graphics system
	system = (SceneManager*) NewtonWorldGetUserData(world);
	system->AddModel (primitive);

	collision = NewtonCreateConvexHullFromMesh (world, mesh, 0.1f, DEBRI_ID);

	// calculate the moment of inertia and the relative center of mass of the solid
	shapeVolume = NewtonConvexCollisionCalculateVolume (collision);
	NewtonConvexCollisionCalculateInertialMatrix (collision, &inertia[0], &origin[0]);	

	mass = mass * shapeVolume / volume;
	Ixx = mass * inertia[0];
	Iyy = mass * inertia[1];
	Izz = mass * inertia[2];

	//create the rigid body
	rigidBody = NewtonCreateBody (world, collision);

	// set the correct center of gravity for this body
	NewtonBodySetCentreOfMass (rigidBody, &origin[0]);

	// set the mass matrix
	NewtonBodySetMassMatrix (rigidBody, mass, Ixx, Iyy, Izz);

	// save the pointer to the graphic object with the body.
	NewtonBodySetUserData (rigidBody, primitive);

	// assign the wood id
//	NewtonBodySetMaterialGroupID (rigidBody, NewtonBodyGetMaterialGroupID(source));

	// set continue collision mode
	NewtonBodySetContinuousCollisionMode (rigidBody, 1);

	// set a destructor for this rigid body
	NewtonBodySetDestructorCallback (rigidBody, PhysicsBodyDestructor);

	// set the transform call back function
	NewtonBodySetTransformCallback (rigidBody, PhysicsSetTransform);

	// set the force and torque call back function
	NewtonBodySetForceAndTorqueCallback (rigidBody, PhysicsApplyGravityForce);

	// set the matrix for both the rigid body and the graphic body
	NewtonBodySetMatrix (rigidBody, &matrix[0][0]);
	PhysicsSetTransform (rigidBody, &matrix[0][0], 0);

	NewtonBodyGetVelocity(sourceBody, &veloc[0]);
	NewtonBodyGetOmega(sourceBody, &omega[0]);
	veloc += omega * matrix.RotateVector(origin);

// for now so that I can see the body
veloc = dVector (0, 0, 0, 0);
//	omega = dVector (0, 0, 0, 0);

	NewtonBodySetVelocity(rigidBody, &veloc[0]);
	NewtonBodySetOmega(rigidBody, &omega[0]);

	NewtonReleaseCollision(world, collision);

}
static void DestroyThisBodyCallback (const NewtonBody* body, const NewtonJoint* contactJoint)
{
	NewtonWorld* world;
	NewtonMesh* topMesh;
	NewtonMesh* bottomMesh;
	NewtonMesh* effectMesh;
	RenderPrimitive* srcPrimitive;
	dMatrix matrix;
	dFloat maxForce;
	dVector point;
	dVector dir0;
	dVector dir1;


	// Get the world;
	world = NewtonBodyGetWorld (body);

	// find a the strongest force 
	maxForce = 0.0f;
	for (void* contact = NewtonContactJointGetFirstContact (contactJoint); contact; contact = NewtonContactJointGetNextContact (contactJoint, contact)) {
		dVector force;
		NewtonMaterial* material;

		material = NewtonContactGetMaterial (contact);
		NewtonMaterialGetContactForce (material, &force.m_x);
		if (force.m_x > maxForce) {
			dVector normal;
			NewtonMaterialGetContactPositionAndNormal(material, &point[0], &normal[0]);
			NewtonMaterialGetContactTangentDirections (material, &dir0[0], &dir0[0]);
		}
	}

	// get the visual primitive
	srcPrimitive = (RenderPrimitive*) NewtonBodyGetUserData (body);

	// get the effect mesh that is use to create the debris pieces
	effectMesh = srcPrimitive->m_specialEffect;


	// calculate the cut plane plane
	NewtonBodyGetMatrix (body, &matrix[0][0]);

	dMatrix clipMatrix (dgGrammSchmidt(dir0) * 
						dYawMatrix(30.0f * 3.1416f/180.0f * RandomVariable(1.0f)) * 
						dRollMatrix(30.0f * 3.1416f/180.0f * RandomVariable(1.0f)));

	clipMatrix.m_posit = point;
	clipMatrix.m_posit.m_w = 1.0f;
	clipMatrix = clipMatrix * matrix.Inverse();

	// break the mesh into two pieces
	NewtonMeshClip (effectMesh, meshClipper, &clipMatrix[0][0], &topMesh, &bottomMesh);
	if (topMesh && bottomMesh) {
		dFloat volume;
		NewtonMesh* meshPartA = NULL;
		NewtonMesh* meshPartB = NULL;

		volume = NewtonConvexCollisionCalculateVolume (NewtonBodyGetCollision(body));

		// the clipper was able to make a cut now we can create new debris piece for replacement
		dMatrix clipMatrix1 (dgGrammSchmidt(dir1) * 
							 dYawMatrix(30.0f * 3.1416f/180.0f * RandomVariable(1.0f)) * 
							 dRollMatrix(30.0f * 3.1416f/180.0f * RandomVariable(1.0f)));
		NewtonMeshClip (bottomMesh, meshClipper, &clipMatrix1[0][0], &meshPartA, &meshPartB);
		if (meshPartA && meshPartB) {
			// creat another split (you can make as many depend of the FPS)
			CreateDebriPiece (body, meshPartA, volume);
			CreateDebriPiece (body, meshPartB, volume);

			NewtonMeshDestroy(meshPartA);
			NewtonMeshDestroy(meshPartB);
		} else {
			CreateDebriPiece (body, bottomMesh, volume);
		}
		NewtonMeshDestroy(bottomMesh);


		dMatrix clipMatrix2 (dgGrammSchmidt(dir1) * 
							 dYawMatrix(30.0f * 3.1416f/180.0f * RandomVariable(1.0f)) * 
			                 dRollMatrix(30.0f * 3.1416f/180.0f * RandomVariable(1.0f)));
		NewtonMeshClip (topMesh, meshClipper, &clipMatrix2[0][0], &meshPartA, &meshPartB);
		if (meshPartA && meshPartB) {
			// creat another split (you can make as many depend of the FPS)
			CreateDebriPiece (body, meshPartA, volume);
			CreateDebriPiece (body, meshPartB, volume);

			NewtonMeshDestroy(meshPartA);
			NewtonMeshDestroy(meshPartB);
		} else {
			CreateDebriPiece (body, topMesh, volume);
		}
		NewtonMeshDestroy(topMesh);


		// remove the old visual from graphics world
		SceneManager* system = (SceneManager*) NewtonWorldGetUserData(world);
		delete srcPrimitive;
		system->Remove(srcPrimitive);

		// finally destroy this body;
		NewtonDestroyBody(world, body);
	}
}
	VoronoidEffect(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);

		dVector points[NUMBER_OF_INTERNAL_PARTS + 8];

		int count = 0;
		// pepper the inside of the BBox box of the mesh with random points
		while (count < NUMBER_OF_INTERNAL_PARTS) {
			dFloat x = dGaussianRandom (size.m_x);
			dFloat y = dGaussianRandom (size.m_y);
			dFloat z = dGaussianRandom (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++;
			}
		}

		// add the bounding box as a safeguard area
		points[count + 0] = dVector(size.m_x, size.m_y, size.m_z, 0.0f);
		points[count + 1] = dVector(size.m_x, size.m_y, -size.m_z, 0.0f);
		points[count + 2] = dVector(size.m_x, -size.m_y, size.m_z, 0.0f);
		points[count + 3] = dVector(size.m_x, -size.m_y, -size.m_z, 0.0f);
		points[count + 4] = dVector(-size.m_x, size.m_y, size.m_z, 0.0f);
		points[count + 5] = dVector(-size.m_x, size.m_y, -size.m_z, 0.0f);
		points[count + 6] = dVector(-size.m_x, -size.m_y, size.m_z, 0.0f);
		points[count + 7] = dVector(-size.m_x, -size.m_y, -size.m_z, 0.0f);
		count += 8;


		// 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 = NewtonMeshCreateVoronoiConvexDecomposition(m_world, count, &points[0].m_x, sizeof (dVector), interiorMaterial, &textureMatrix[0][0]);
		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 voronoi convexes against the mesh 
			NewtonMesh* const fracturePiece = NewtonMeshConvexMeshIntersection(mesh, debri);
			if (fracturePiece) {
				// make a convex hull collision shape
				NewtonCollision* const collision = NewtonCreateConvexHullFromMesh(m_world, fracturePiece, 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(fracturePiece);
					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(fracturePiece);
			}

			NewtonMeshDestroy(debri);
		}

		NewtonMeshDestroy(debriMeshPieces);
	}