static int MakeRandomGuassianPointCloud (NewtonMesh* const mesh, dVector* const points, int count)
{
	dVector size(0.0f);
	dMatrix matrix(dGetIdentityMatrix()); 
	NewtonMeshCalculateOOBB(mesh, &matrix[0][0], &size.m_x, &size.m_y, &size.m_z);

	dVector minBox (matrix.m_posit - matrix[0].Scale (size.m_x) - matrix[1].Scale (size.m_y) - matrix[2].Scale (size.m_z));
	dVector maxBox (matrix.m_posit + matrix[0].Scale (size.m_x) + matrix[1].Scale (size.m_y) + matrix[2].Scale (size.m_z));

	size = (maxBox - minBox).Scale (0.5f);
	dVector origin = (maxBox + minBox).Scale (0.5f);

	dFloat biasExp = 10.0f;
	dFloat r = dSqrt (size.DotProduct3(size));
	r = powf(r, 1.0f/biasExp);
	for (int i = 0; i < count; i++) {
		dVector& p = points[i];
		bool test;
		do {
			p = dVector (2.0f * RandomVariable(r), 2.0f * RandomVariable(r), 2.0f * RandomVariable(r), 0.0f);
			dFloat len = dSqrt (p.DotProduct3(p));
			dFloat scale = powf(len, biasExp) / len;
			p = p.Scale (scale) + origin;
			test = (p.m_x > minBox.m_x) && (p.m_x < maxBox.m_x) && (p.m_y > minBox.m_y) && (p.m_y < maxBox.m_y) && (p.m_z > minBox.m_z) && (p.m_z < maxBox.m_z);
		} while (!test);
	}

	return count;
}
	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);
	}
	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);
	}
static int MakeRandomPoisonPointCloud(NewtonMesh* const mesh, dVector* const points)
{
	dVector size(0.0f);
	dMatrix matrix(dGetIdentityMatrix()); 
	NewtonMeshCalculateOOBB(mesh, &matrix[0][0], &size.m_x, &size.m_y, &size.m_z);

	dVector minBox (matrix.m_posit - matrix[0].Scale (size.m_x) - matrix[1].Scale (size.m_y) - matrix[2].Scale (size.m_z));
	dVector maxBox (matrix.m_posit + matrix[0].Scale (size.m_x) + matrix[1].Scale (size.m_y) + matrix[2].Scale (size.m_z));

	size = maxBox - minBox;
	int xCount = int (size.m_x / POINT_DENSITY_PER_METERS) + 1;
	int yCount = int (size.m_y / POINT_DENSITY_PER_METERS) + 1;
	int zCount = int (size.m_z / POINT_DENSITY_PER_METERS) + 1;

	int count = 0;
	dFloat z0 = minBox.m_z;
	for (int iz = 0; (iz < zCount) && (count < MAX_POINT_CLOUD_SIZE); iz ++) {
		dFloat y0 = minBox.m_y;
		for (int iy = 0; (iy < yCount) && (count < MAX_POINT_CLOUD_SIZE); iy ++) {
			dFloat x0 = minBox.m_x;
			for (int ix = 0; (ix < xCount) && (count < MAX_POINT_CLOUD_SIZE); ix ++) {

				dFloat x = x0;
				dFloat y = y0;
				dFloat z = z0;
				x += RandomVariable(POISON_VARIANCE);
				y += RandomVariable(POISON_VARIANCE);
				z += RandomVariable(POISON_VARIANCE);
				points[count] = dVector (x, y, z);
				count ++;
				x0 += POINT_DENSITY_PER_METERS;
			}
			y0 += POINT_DENSITY_PER_METERS;
		}
		z0 += POINT_DENSITY_PER_METERS;
	}

	return count;
}
	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);
	}