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 dPluginCamera::SetPerspectiveMatrix(dSceneRender* const render, int width, int height)
{
	// set the perspective matrix
	render->SetPerspectiveProjection(width, height, m_fov * 180.0f / 3.1416f, m_frontPlane, m_backPlane);

	// calculate the same gluLookAt matrix
	dMatrix modelViewMatrix(dGetIdentityMatrix());
	modelViewMatrix[2] = m_matrix.m_front.Scale (-1.0f);
	modelViewMatrix[0] = m_matrix.m_up.CrossProduct(modelViewMatrix[2]);
	modelViewMatrix[1] = modelViewMatrix[2].CrossProduct(modelViewMatrix[0]);
	modelViewMatrix[3] = m_matrix.m_posit;
	modelViewMatrix = modelViewMatrix.Inverse();

	// apply scale, zoom and pan 
	dMatrix zoomMatrix(dGetIdentityMatrix());
	zoomMatrix[0][0] = D_PERSPECTIVE_PIXEL_TO_METERS_SCALE * m_zoom;
	zoomMatrix[1][1] = D_PERSPECTIVE_PIXEL_TO_METERS_SCALE * m_zoom;
	zoomMatrix[2][2] = D_PERSPECTIVE_PIXEL_TO_METERS_SCALE * m_zoom;

	dMatrix panMatrix (dGetIdentityMatrix());
	// use a pan sensitivity 0f 0.25f
	dFloat panSensitivity = D_PANNING_SENSITIVITY;
	panMatrix.m_posit = dVector(m_panX * panSensitivity, m_panY * panSensitivity, 0.0f, 1.0f);

	dMatrix matrix (zoomMatrix * modelViewMatrix * panMatrix);
	render->SetModelViewMatrix(matrix);
}
void SixAxisManipulators(DemoEntityManager* const scene)
{
	// load the sky box
	scene->CreateSkyBox();
	CreateLevelMesh(scene, "flatPlane.ngd", true);
	dSixAxisManager* const robotManager = new dSixAxisManager(scene);

	dMatrix origin(dYawMatrix(0.0f * dDegreeToRad));
	dMatrix origin1(dYawMatrix(180.0f * dDegreeToRad));
	origin.m_posit.m_z = -1.0f;
	origin1.m_posit.m_z = 1.0f;

	int count = 10;
count = 1;
origin = dGetIdentityMatrix();
origin.m_posit.m_x = 2.0f;
	for (int i = 0; i < count; i++) {
		robotManager->MakeKukaRobot(scene, origin);
		//robotManager->MakeKukaRobot (scene, origin1);
		origin.m_posit.m_x += 1.0f;
		origin1.m_posit.m_x += 1.0f;
	}

	//	origin.m_posit = dVector (-3.0f, 0.5f, 0.0f, 1.0f);
	origin.m_posit = dVector(-2.0f, 0.5f, 0.0f, 1.0f);
	scene->SetCameraMatrix(dGetIdentityMatrix(), origin.m_posit);
}
	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);
	}
void BasicCar (DemoEntityManager* const scene)
{
	// load the sky box
	scene->CreateSkyBox();

	CreateLevelMesh (scene, "flatPlane.ngd", 1);
//	CreateHeightFieldTerrain (scene, 10, 8.0f, 5.0f, 0.2f, 200.0f, -50.0f);


	dMatrix location (dGetIdentityMatrix());
	location.m_posit = dVector (0.0f, 10.0f, 0.0f, 1.0f);

	location.m_posit = FindFloor (scene->GetNewton(), location.m_posit, 100.0f);
	location.m_posit.m_y += 2.0f;

	NewtonWorld* const world = scene->GetNewton();

	// create a vehicle controller manager
	BasicCarControllerManager* const manager = new BasicCarControllerManager (world);
	
	// load 
	basicCarParameters.m_differentialType = BasciCarParameters::m_RWD;
	BasicCarEntity* const heavyVehicle = new BasicCarEntity (scene, manager, location, basicCarParameters);
	heavyVehicle->BuidlBasicCar (basicCarParameters);

	// set this vehicle as the player
	manager->SetAsPlayer(heavyVehicle);

	dMatrix camMatrix (manager->m_player->GetNextMatrix());
	scene->SetCameraMouseLock (true);
	scene->SetCameraMatrix(camMatrix, camMatrix.m_posit);

//
	//	dVector location (origin);
	//	location.m_x += 20.0f;
	//	location.m_z += 20.0f;
//	location.m_posit.m_z += 4.0f;

	int count = 1;
	dMatrix shapeOffsetMatrix (dGetIdentityMatrix());
	int defaultMaterialID = NewtonMaterialGetDefaultGroupID (scene->GetNewton());

	dVector size (3.0f, 0.125f, 3.0f, 0.0f);
	//AddPrimitiveArray(scene, 100.0f, location.m_posit, size, count, count, 5.0f, _BOX_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);

	size = dVector(1.0f, 0.5f, 1.0f, 0.0f);
	//	AddPrimitiveArray(scene, 10.0f, location.m_posit, size, count, count, 5.0f, _SPHERE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	//	AddPrimitiveArray(scene, 10.0f, location.m_posit, size, count, count, 5.0f, _BOX_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	//	AddPrimitiveArray(scene, 10.0f, location.m_posit, size, count, count, 5.0f, _CAPSULE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
		AddPrimitiveArray(scene, 10.0f, location.m_posit, size, count, count, 5.0f, _CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	//	AddPrimitiveArray(scene, 10.0f, location.m_posit, size, count, count, 5.0f, _TAPERED_CAPSULE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	//	AddPrimitiveArray(scene, 10.0f, location.m_posit, size, count, count, 5.0f, _TAPERED_CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	//	AddPrimitiveArray(scene, 10.0f, location.m_posit, size, count, count, 5.0f, _CHAMFER_CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	//	AddPrimitiveArray(scene, 10.0f, location.m_posit, size, count, count, 5.0f, _CONE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	//	AddPrimitiveArray(scene, 10.0f, location.m_posit, size, count, count, 5.0f, _REGULAR_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	//	AddPrimitiveArray(scene, 10.0f, location.m_posit, size, count, count, 5.0f, _RANDOM_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);

	//	NewtonSerializeToFile (scene->GetNewton(), "C:/Users/Julio/Desktop/newton-dynamics/applications/media/xxxxx.bin");
}
// create physics scene
void ClosestDistance (DemoEntityManager* const scene)
{
	scene->CreateSkyBox();

	// customize the scene after loading
	// set a user friction variable in the body for variable friction demos
	// later this will be done using LUA script
	NewtonWorld* const world = scene->GetNewton();
	dMatrix offsetMatrix (dGetIdentityMatrix());

	CreateLevelMesh (scene, "flatPlane.ngd", 1);
	//	CreateLevelMesh (scene, "playground.ngd", 0);

	int materialID = NewtonMaterialGetDefaultGroupID (world);

	// disable collision
//	NewtonMaterialSetDefaultCollidable (world, materialID, materialID, 0);

//	PrimitiveType castinShapeType = _SPHERE_PRIMITIVE;
//	PrimitiveType castinShapeType = _BOX_PRIMITIVE;
//	PrimitiveType castinShapeType = _CAPSULE_PRIMITIVE;
//	PrimitiveType castinShapeType = _CYLINDER_PRIMITIVE;
//	PrimitiveType castinShapeType = _CONE_PRIMITIVE;
//	PrimitiveType castinShapeType = _TAPERED_CAPSULE_PRIMITIVE;
//	PrimitiveType castinShapeType = _TAPERED_CYLINDER_PRIMITIVE;
//	PrimitiveType castinShapeType = _CHAMFER_CYLINDER_PRIMITIVE;
//	PrimitiveType castinShapeType = _RANDOM_CONVEX_HULL_PRIMITIVE;
//	PrimitiveType castinShapeType = _REGULAR_CONVEX_HULL_PRIMITIVE;
	PrimitiveType castinShapeType = _COMPOUND_CONVEX_CRUZ_PRIMITIVE;


//	ClosestDistanceEntityManager* const parallelManager = new ClosestDistanceEntityManager (scene);

	dClosestDistanceManager* const castManager = new dClosestDistanceManager (scene);

	int count = 5;
//	castManager->AddPrimitives (count, dVector (  0, 0, 0), _SPHERE_PRIMITIVE, materialID, castinShapeType);
//	castManager->AddPrimitives (count, dVector (  2, 0, 2), _BOX_PRIMITIVE, materialID, castinShapeType);
//	castManager->AddPrimitives (count, dVector (  4, 0, 4), _CAPSULE_PRIMITIVE, materialID, castinShapeType);
//	castManager->AddPrimitives (count, dVector (  8, 0, 8), _CYLINDER_PRIMITIVE, materialID, castinShapeType);
//	castManager->AddPrimitives (count, dVector ( 10, 0, 10), _CHAMFER_CYLINDER_PRIMITIVE, materialID, castinShapeType);
//	castManager->AddPrimitives (count, dVector (- 4, 0, -4), _CONE_PRIMITIVE, materialID, castinShapeType);
//	castManager->AddPrimitives (count, dVector (- 6, 0, -6), _TAPERED_CAPSULE_PRIMITIVE, materialID, castinShapeType);
//	castManager->AddPrimitives (count, dVector (- 8, 0, -8), _TAPERED_CYLINDER_PRIMITIVE, materialID, castinShapeType);
//	castManager->AddPrimitives (count, dVector (-10, 0, -10), _REGULAR_CONVEX_HULL_PRIMITIVE, materialID, castinShapeType);
	castManager->AddPrimitives (count, dVector (-12, 0, -12), _COMPOUND_CONVEX_CRUZ_PRIMITIVE, materialID, castinShapeType);
	
	

	// place camera into position
	//dMatrix camMatrix (dYawMatrix(90.0f * 3.1416f /180.0f));
	dMatrix camMatrix (dGetIdentityMatrix());
	dQuaternion rot (camMatrix);
	dVector origin (-30.0f, 10.0f, 0.0f, 0.0f);
	scene->SetCameraMatrix(rot, origin);
}
static void BuildJenga (DemoEntityManager* const scene, dFloat mass, const dVector& origin, const dVector& size, int count)
{
	// build a standard block stack of 20 * 3 boxes for a total of 60
	NewtonWorld* const world = scene->GetNewton();

	dVector blockBoxSize (0.8f, 0.5f, 0.8f * 3.0f);
	blockBoxSize = blockBoxSize.Scale (1.0f);

	// create the stack
	dMatrix baseMatrix (dGetIdentityMatrix());

	// for the elevation of the floor at the stack position
	baseMatrix.m_posit.m_x = origin.m_x;
	baseMatrix.m_posit.m_z = origin.m_z;

	dFloat startElevation = 100.0f;
	dVector floor (FindFloor (world, dVector (baseMatrix.m_posit.m_x, startElevation, baseMatrix.m_posit.m_z, 0.0f), 2.0f * startElevation));
	baseMatrix.m_posit.m_y = floor.m_y + blockBoxSize.m_y / 2.0f;

	// set realistic mass and inertia matrix for each block
	mass = 5.0f;

	// create a 90 degree rotation matrix
	dMatrix rotMatrix (dYawMatrix (3.141592f * 0.5f));

	// create a material to control collision with this objects
	int defaultMaterialID;
	defaultMaterialID = NewtonMaterialGetDefaultGroupID (world);

	// separate a bit the block alone the horizontal direction
	dFloat gap = 0.01f;

	// create the shape and visual mesh as a common data to be re used
	NewtonCollision* const collision = CreateConvexCollision (world, dGetIdentityMatrix(), blockBoxSize, _BOX_PRIMITIVE, defaultMaterialID);
	DemoMesh* const geometry = new DemoMesh("box", collision, "wood_0.tga", "wood_0.tga", "wood_0.tga");

	for (int i = 0; i < count; i ++) { 
		dMatrix matrix(baseMatrix);
		matrix.m_posit -= matrix.m_front.Scale (blockBoxSize.m_x - gap); 

		for (int j = 0; j < 3; j ++) { 
			CreateSimpleSolid (scene, geometry, mass, matrix, collision, defaultMaterialID);
			matrix.m_posit += matrix.m_front.Scale (blockBoxSize.m_x + gap);  
		}

		baseMatrix = rotMatrix * baseMatrix;
		baseMatrix.m_posit += matrix.m_up.Scale (blockBoxSize.m_y * 0.99f);
	}

	// do not forget to release the assets	
	geometry->Release(); 
	NewtonDestroyCollision (collision);
}
	PuckEntity (DemoEntityManager* const scene, int materialID)
		:DemoEntity (dGetIdentityMatrix(), NULL)
		,m_launched(false)
	{
		scene->Append(this);

		NewtonWorld* const world = scene->GetNewton();

		dVector puckSize(WEIGHT_DIAMETER, WEIGHT_HEIGHT, 0.0f, 0.0f);

		// create the shape and visual mesh as a common data to be re used
		NewtonCollision* const collision = CreateConvexCollision (world, dGetIdentityMatrix(), puckSize, _CYLINDER_PRIMITIVE, materialID);

		// correction: make the puck an upright cylinder, this makes everything simpler  
		dMatrix collisionAligmentMatrix (dRollMatrix(3.141592f/2.0f));
		NewtonCollisionSetMatrix(collision, &collisionAligmentMatrix[0][0]);

		DemoMesh* const geometry = new DemoMesh("cylinder_1", collision, "smilli.tga", "smilli.tga", "smilli.tga");

		//dMatrix matrix = dRollMatrix(3.141592f/2.0f);
		dMatrix matrix (dGetIdentityMatrix());
		matrix.m_posit.m_x = -TABLE_LENGTH*0.5f+WEIGHT_DIAMETER;
		matrix.m_posit.m_z = -11.8f;
//matrix.m_posit.m_z += 4.0f;
		matrix.m_posit.m_y = 5.0f;

		m_puckBody = CreateSimpleSolid (scene, geometry, WEIGHT_MASS, matrix, collision, materialID);

		// Set moment of inertia
		// correction: this is deprecated, NewtonBodySetMassProperties produce the exact result
		//dVector I;
		//dFloat Mass = WEIGHT_MASS;
		//dFloat Radius = WEIGHT_RADIUS;
		//dFloat Height = WEIGHT_HEIGHT;
		//I.m_x = I.m_z = Mass*(3.0f*Radius*Radius+Height*Height)/12.0f;
		//I.m_y = Mass*Radius*Radius/2.0f;
		//NewtonBodySetMassMatrix(gPuckBody,Mass, I.m_x, I.m_y, I.m_z);	
		NewtonBodySetMassProperties(m_puckBody, WEIGHT_MASS, NewtonBodyGetCollision(m_puckBody));


		NewtonBodySetMaterialGroupID(m_puckBody, materialID);

		// remember to make continuous collision work with auto sleep mode, right now this is no working
		NewtonBodySetContinuousCollisionMode(m_puckBody, 1);
		NewtonBodySetAutoSleep(m_puckBody, 1);

		// Set callbacks
		NewtonBodySetForceAndTorqueCallback(m_puckBody, NewtonRigidBodySetForceCB);

		// do not forget to release the assets
		geometry->Release(); 
		NewtonDestroyCollision (collision);
	}
static void LoadPlayGroundScene(DemoEntityManager* const scene, TriggerManager* const triggerManager)
{
	NewtonWorld* const world = scene->GetNewton();
	//	CreateLevelMesh (scene, "flatPlane.ngd", true);
	//	return;

	// make the body with a dummy null collision, so that we can use for attaching world objects
	dMatrix matrix (dGetIdentityMatrix());
	NewtonCollision* const dommyCollision = NewtonCreateNull(world);
	NewtonBody* const playGroundBody = NewtonCreateDynamicBody (world, dommyCollision, &matrix[0][0]);
	NewtonDestroyCollision (dommyCollision);	


	// use a multi shape static scene collision
	NewtonCollision* const sceneCollision = NewtonCreateSceneCollision (world, 0);

	// start adding shapes to this scene collisions 
	NewtonSceneCollisionBeginAddRemove (sceneCollision);

	// populate the scene collision
	{
		// load a flat floor
		LoadFloor(scene, sceneCollision);

		// load a slide platform
		dMatrix slideMatrix(dGetIdentityMatrix());
		slideMatrix.m_posit.m_x += 80.0f;
		slideMatrix.m_posit.m_z = -20.0f;
		//LoadSlide(scene, triggerManager, sceneCollision, "slide.ngd", slideMatrix, playGroundBody);
		LoadFerryBridge(scene, triggerManager, sceneCollision, "platformBridge.ngd", slideMatrix, playGroundBody);

		// load another hanging bridge
		dMatrix bridgeMatrix(dGetIdentityMatrix());
		bridgeMatrix.m_posit.m_x += 40.0f;
		LoadHangingBridge(scene, triggerManager, sceneCollision, "hangingBridge.ngd", bridgeMatrix, playGroundBody);

		// load another ferry bridge
		bridgeMatrix.m_posit.m_z += 20.0f;
		LoadFerryBridge(scene, triggerManager, sceneCollision, "platformBridge.ngd", bridgeMatrix, playGroundBody);
	}
	// finalize adding shapes to this scene collisions 
	NewtonSceneCollisionEndAddRemove (sceneCollision);

	// attach this collision to the playground Body
	NewtonBodySetCollision(playGroundBody, sceneCollision);


	// set the reference to the visual
	//NewtonBodySetUserData(level, visualMesh);

	// do not forget to release the collision
	NewtonDestroyCollision (sceneCollision);
}
static void BuildPyramid (DemoEntityManager* const scene, dFloat mass, const dVector& origin, const dVector& size, int count, PrimitiveType type, const dMatrix& shapeMatrix = dGetIdentityMatrix())
{
	dMatrix matrix (dGetIdentityMatrix());
	matrix.m_posit = origin;
	matrix.m_posit.m_w = 1.0f;

	// create the shape and visual mesh as a common data to be re used
	NewtonWorld* const world = scene->GetNewton();

	int defaultMaterialID;
	defaultMaterialID = NewtonMaterialGetDefaultGroupID (world);

	//dMatrix shapeMatrix (dRollMatrix(3.141692f * 0.5f));
	NewtonCollision* const collision = CreateConvexCollision (world, shapeMatrix, size, type, defaultMaterialID);

	DemoMesh* const geometry = new DemoMesh("cylinder_1", collision, "wood_4.tga", "wood_4.tga", "wood_1.tga");
	//DemoMesh____* const geometry = new DemoMesh____("cylinder_1", collision, "smilli.tga", "smilli.tga", "smilli.tga");

	//	matrix = dRollMatrix(3.141592f/2.0f);
	dFloat startElevation = 100.0f;
	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 + size.m_y / 2.0f; 

	// get the dimension from shape itself
	dVector minP;
	dVector maxP;
	CalculateAABB (collision, dGetIdentityMatrix(), minP, maxP);

	//dFloat stepz = size.m_z + 0.01f;
	dFloat stepz = maxP.m_z - minP.m_z + 0.01f;
	dFloat stepy = maxP.m_y - minP.m_y;

	float y0 = matrix.m_posit.m_y + stepy / 2.0f;
	float z0 = matrix.m_posit.m_z - stepz * count / 2;

	matrix.m_posit.m_y = y0;
	for (int j = 0; j < count; j ++) {
		matrix.m_posit.m_z = z0;
		for (int i = 0; i < (count - j) ; i ++) {
			CreateSimpleSolid (scene, geometry, mass, matrix, collision, defaultMaterialID);
			matrix.m_posit.m_z += stepz;
		}
		z0 += stepz * 0.5f;
		matrix.m_posit.m_y += stepy;
	}

	// do not forget to release the assets	
	geometry->Release(); 
	NewtonDestroyCollision (collision);
}
	SimpleSoftBodyEntity(DemoEntityManager* const scene, const dVector& location)
		:DemoEntity(dGetIdentityMatrix(), NULL)
		,m_body(NULL)
	{
		dMatrix matrix (dGetIdentityMatrix());

		matrix.m_posit.m_x = location.m_x;
		matrix.m_posit.m_y = location.m_y;
		matrix.m_posit.m_z = location.m_z;
		ResetMatrix(*scene, matrix);

		// add an new entity to the world
		scene->Append(this);
	}
		ClosestDistanceEntity (DemoEntityManager* const scene, dMatrix& matrix, int materialID, PrimitiveType castingShapeType)
			:DemoEntity (matrix, NULL)
			,m_contactsCount(0)
		{
			NewtonWorld* const world = scene->GetNewton();

			dVector size(1.0f, 1.0f, 1.0f, 0.0f);
			m_castingShape = CreateConvexCollision (world, dGetIdentityMatrix(), size, castingShapeType, 0);

			DemoMesh* const geometry = new DemoMesh("convexShape", m_castingShape, "smilli.tga", "smilli.tga", "smilli.tga");
			SetMesh(geometry, dGetIdentityMatrix());
			geometry->Release();

			scene->Append(this);
		}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
dCustomJoint::dCustomJoint ()
	:dCustomAlloc()
	,m_localMatrix0(dGetIdentityMatrix())
	,m_localMatrix1(dGetIdentityMatrix())
	,m_userData(NULL)
	,m_body0(NULL)
	,m_body1(NULL)
	,m_joint(NULL)
	,m_world(NULL)
	,m_userDestructor(NULL)
	,m_stiffness(1.0f)
	,m_maxDof(0)
	,m_autoDestroy(0)
{
}
static NewtonBody* CreatePlaneCollision (DemoEntityManager* const scene, const dVector& planeEquation)
{
	NewtonCollision* const planeCollision = CreateInfinitePlane (scene->GetNewton(), planeEquation);

	// create the the rigid body for
	dMatrix matrix (dGetIdentityMatrix());
	NewtonBody* const body = NewtonCreateDynamicBody(scene->GetNewton(), planeCollision, &matrix[0][0]);

	// create a visual mesh
	DemoMesh* const mesh = CreateVisualPlaneMesh (planeEquation, scene);
	DemoEntity* const entity = new DemoEntity(matrix, NULL);

	NewtonCollisionGetMatrix(planeCollision, &matrix[0][0]);

	scene->Append (entity);
	entity->SetMesh(mesh, matrix);
	mesh->Release();

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

	// destroy the collision shape
	NewtonDestroyCollision (planeCollision);
	return body;
}
	void CreatCasterBody(dFloat location_x, dFloat location_z, PrimitiveType shapeType, int materialID)
	{
		NewtonWorld* const world = ((CustomControllerManager<dClosestDistanceRecord>*)GetManager())->GetWorld();
		DemoEntityManager* const scene = (DemoEntityManager*)NewtonWorldGetUserData(world);

		//dMatrix matrix (GetIdentityMatrix());
		dMatrix matrix (dRollMatrix(3.141592f/2.0f));

		matrix.m_posit.m_x = location_x;
		matrix.m_posit.m_y = 2.0f;
		matrix.m_posit.m_z = location_z;

		// create the shape and visual mesh as a common data to be re used
		dVector size(0.5f, 0.5f, 0.75f, 0.0f);
		NewtonCollision* const collision = CreateConvexCollision (world, dGetIdentityMatrix(), size, shapeType, materialID);

		//	DemoMesh____* const geometry = new DemoMesh____("cylinder_1", collision, "wood_0.tga", "wood_0.tga", "wood_1.tga");
		DemoMesh* const geometry = new DemoMesh("convexShape", collision, "smilli.tga", "smilli.tga", "smilli.tga");
		m_body = CreateSimpleSolid (scene, geometry, 1.0f, matrix, collision, materialID);

		// disable gravity and apply a force that only spin the body 
		//NewtonBodySetForceAndTorqueCallback(m_myBody, PhysicsSpinBody);
		//NewtonBodySetAutoSleep (m_myBody, 0);

		geometry->Release(); 
		NewtonDestroyCollision (collision);
	}
void dCustomTransformController::PostUpdate(dCustomTransformManager* const manager, dFloat timestep) const
{
	if (m_calculateLocalTransform) {

		dMatrix parentMatrixPool[128];
		const dSkeletonBone* stackPool[128];

		int stack = 1;
		stackPool[0] = this;
		parentMatrixPool[0] = dGetIdentityMatrix();

		while (stack) {
			dMatrix matrix;
			stack--;

			dMatrix parentMatrix(parentMatrixPool[stack]);
			const dSkeletonBone* const bone = stackPool[stack];

			NewtonBodyGetMatrix(bone->GetBody(), &matrix[0][0]);
			manager->OnUpdateTransform(bone, matrix * parentMatrix * bone->GetBindMatrix());

			parentMatrix = matrix.Inverse();
			for (dList<dSkeletonBone>::dListNode* ptrNode = bone->GetFirst(); ptrNode; ptrNode = ptrNode->GetNext()) {
				parentMatrixPool[stack] = parentMatrix;
				stackPool[stack] = &ptrNode->GetInfo();
				stack++;
			}
		}
	}
}
void DynamicRagdoll(DemoEntityManager* const scene)
{
	// load the sky box
	scene->CreateSkyBox();

	CreateLevelMesh(scene, "flatPlane.ngd", true);


	dDynamicRagdollManager* const manager = new dDynamicRagdollManager(scene);
	NewtonWorld* const world = scene->GetNewton();
	int defaultMaterialID = NewtonMaterialGetDefaultGroupID(world);
	NewtonMaterialSetDefaultFriction(world, defaultMaterialID, defaultMaterialID, 1.0f, 1.0f);
	NewtonMaterialSetDefaultElasticity(world, defaultMaterialID, defaultMaterialID, 0.0f);

	dMatrix origin (dYawMatrix(0.0f * dDegreeToRad));
	origin.m_posit.m_y = 2.0f;
	manager->CreateRagdollExperiment_0(origin);
/*
//	int count = 10;
//	count = 1;
//origin = dGetIdentityMatrix();
	origin.m_posit.m_x = 2.0f;
//	origin.m_posit.m_y = 2.1f;
	origin.m_posit.m_y = 3.0f;
	for (int i = 0; i < count; i++) {
		manager->CreateRagDoll(scene, origin);
		//manager->CreateRagDoll (scene, origin1);
		origin.m_posit.m_x += 1.0f;
	}
*/
	origin.m_posit.m_x = -3.0f;
	origin.m_posit.m_y = 1.0f;
	origin.m_posit.m_z = 0.0f;
	scene->SetCameraMatrix(dGetIdentityMatrix(), origin.m_posit);
}
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);
}
Exemple #19
0
static dNewtonDynamicBody* CreateBackgroundBody(dNewton* const world)
{
	// make a flat quad 
	dFloat points[4][3] = 
	{
		{-100.0f, 0.0f,  100.0f}, 
		{ 100.0f, 0.0f,  100.0f}, 
		{ 100.0f, 0.0f, -100.0f}, 
		{-100.0f, 0.0f, -100.0f}, 
	};

	// create a collision tree instance with collision mask 1 
	dNewtonCollisionMesh collision (world, 1);

	// start building the collision mesh
	collision.BeginFace();

	// add the face one at a time
	collision.AddFace (4, &points[0][0], 3 * sizeof (dFloat), 0);

	// finish building the collision
	collision.EndFace();

	// create a body with a collision and locate at the identity matrix position 
	return new MyDynamicBody (world, 0, &collision, NULL, dGetIdentityMatrix());
}
void dVehicleChassis::Finalize()
{
	dVector minP;
	dVector maxP;
	m_vehicle->CalculateNodeAABB(dGetIdentityMatrix(), minP, maxP);

	const dList<dVehicleNode*>& children = m_vehicle->GetChildren();
	for (dList<dVehicleNode*>::dListNode* tireNode = children.GetFirst(); tireNode; tireNode = tireNode->GetNext()) {
		dVehicleVirtualTire* const tire = (dVehicleVirtualTire*)tireNode->GetInfo()->GetAsTire();
		if (tire) {
			dVector tireMinP;
			dVector tireMaxP;

			dMatrix tireMatrix(tire->GetHardpointMatrix(0.0f));
			tire->CalculateNodeAABB(tireMatrix, tireMinP, tireMaxP);

			minP = minP.Min (tireMinP);
			maxP = maxP.Max (tireMaxP);
		}
	}

	m_obbOrigin = (maxP + minP).Scale (0.5f);
	m_obbSize = (maxP - minP).Scale (0.5f) + dVector (0.1f, 0.1f, 0.1f, 0.0f);

	m_vehicle->RigidBodyToStates();
	m_solver.Finalize(this);
}
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;
}
void HeightFieldCollision (DemoEntityManager* const scene)
{
	// load the sky box
	scene->CreateSkyBox();

	CreateHeightFieldTerrain(scene, HEIGHTFIELD_DEFAULT_SIZE, HEIGHTFIELD_DEFAULT_CELLSIZE, 1.5f, 0.2f, 200.0f, -50.0f);


	dMatrix locationTransform (dGetIdentityMatrix());
	locationTransform.m_posit = FindFloor (scene->GetNewton(), dVector(126, 50, 50), 100.0f);
	locationTransform.m_posit.m_y += 2.0f;

	scene->SetCameraMatrix(dQuaternion(locationTransform), locationTransform.m_posit + dVector(0, 5, 0));

	const int defaultMaterialID = NewtonMaterialGetDefaultGroupID (scene->GetNewton());
	const dVector location (locationTransform.m_posit + dVector(20, 20, 0));
	const dVector size (0.5f, 0.5f, 0.75f, 0.0f);
	const int count = 5;
	const dMatrix shapeOffsetMatrix (dGetIdentityMatrix());

	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _SPHERE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _BOX_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _CAPSULE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _CONE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
//	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _TAPERED_CAPSULE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
//	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _TAPERED_CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _CHAMFER_CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _REGULAR_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _COMPOUND_CONVEX_CRUZ_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _RANDOM_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
}
void CustomPlayerController::SetPlayerOrigin (dFloat originHigh)
{
	dAssert (0);
	NewtonCollision* const playerShape = NewtonBodyGetCollision(m_body);
	NewtonCompoundCollisionBeginAddRemove(playerShape);	

		dMatrix supportShapeMatrix (dGetIdentityMatrix());
		supportShapeMatrix[0] = m_upVector;
		supportShapeMatrix[1] = m_frontVector;
		supportShapeMatrix[2] = supportShapeMatrix[0] * supportShapeMatrix[1];
		supportShapeMatrix.m_posit = supportShapeMatrix[0].Scale(m_height * 0.5f - originHigh);
		supportShapeMatrix.m_posit.m_w = 1.0f;
		NewtonCollisionSetMatrix (m_supportShape, &supportShapeMatrix[0][0]);

		dMatrix collisionShapeMatrix (supportShapeMatrix);
		dFloat cylinderHeight = m_height - m_stairStep;
		dAssert (cylinderHeight > 0.0f);
		collisionShapeMatrix.m_posit = collisionShapeMatrix[0].Scale(cylinderHeight * 0.5f + m_stairStep - originHigh);
		collisionShapeMatrix.m_posit.m_w = 1.0f;
		NewtonCollisionSetMatrix (m_upperBodyShape, &collisionShapeMatrix[0][0]);

	NewtonCompoundCollisionEndAddRemove (playerShape);	

	dFloat Ixx;
	dFloat Iyy;
	dFloat Izz;
	dFloat mass;
	NewtonBodyGetMassMatrix(m_body, &mass, &Ixx, &Iyy, &Izz);
	NewtonBodySetMassProperties(m_body, mass, playerShape);
}
CustomLimitBallAndSocket::CustomLimitBallAndSocket(const dMatrix& pinAndPivotFrame, NewtonBody* const child, NewtonBody* const parent)
	:CustomBallAndSocket(pinAndPivotFrame, child, parent)
	,m_rotationOffset(dGetIdentityMatrix())
{
	SetConeAngle (0.0f);
	SetTwistAngle (0.0f, 0.0f);
}
	void SpawnRandomProp(const dMatrix& location) const
	{
		NewtonWorld* const world = GetWorld();
		DemoEntityManager* const scene = (DemoEntityManager*) NewtonWorldGetUserData(world);
		//scene->SetCurrent();

		static PrimitiveType proSelection[] = {_SPHERE_PRIMITIVE, _BOX_PRIMITIVE, _CAPSULE_PRIMITIVE, _CYLINDER_PRIMITIVE, _CONE_PRIMITIVE, 
											   _CHAMFER_CYLINDER_PRIMITIVE, _RANDOM_CONVEX_HULL_PRIMITIVE, _REGULAR_CONVEX_HULL_PRIMITIVE};

		PrimitiveType type = PrimitiveType (dRand() % (sizeof (proSelection) / sizeof (proSelection[0])));

		dVector size (0.35f, 0.25f, 0.25f, 0.0f);
		NewtonCollision* const collision = CreateConvexCollision (world, dGetIdentityMatrix(), size, type, 0);
		DemoMesh* const geometry = new DemoMesh("prop", collision, "smilli.tga", "smilli.tga", "smilli.tga");

		dMatrix matrix (location);
		matrix.m_posit.m_y += 0.5f;

		NewtonBody* const prop = CreateSimpleSolid (scene, geometry, 30.0f, matrix, collision, 0);
		NewtonDestroyCollision(collision);
		geometry->Release();

		dFloat initialSpeed = 20.0f; 
		dVector veloc (matrix.m_front.Scale (initialSpeed));
		NewtonBodySetVelocity(prop, &veloc[0]);
		NewtonBodySetLinearDamping(prop, 0);
	}
static void OnEmitFracturedChunk (NewtonBody* const chunkBody, NewtonFracturedCompoundMeshPart* const fractureChunkMesh, const NewtonCollision* const fracturedCompoundCollision)
{
	NewtonWorld* const world = NewtonBodyGetWorld(chunkBody);
	DemoEntityManager* const scene = (DemoEntityManager*)NewtonWorldGetUserData(world);

	// set the force an torque call back
	NewtonBodySetForceAndTorqueCallback (chunkBody, PhysicsApplyGravityForce);

	// set the transform callback 
	NewtonBodySetTransformCallback (chunkBody, DemoEntity::TransformCallback);

	// create the visual entity and mesh, and set the use data
	dMatrix matrix;
	NewtonBodyGetMatrix (chunkBody, &matrix[0][0]);

	DemoEntity* const visualChunkEntity = new DemoEntity(matrix, NULL);
	scene->Append(visualChunkEntity);

	NewtonBodySetUserData (chunkBody, visualChunkEntity);

	// create the mesh geometry and attach it to the entity
	DemoMesh* const visualChunkMesh = new DemoMesh ("fracturedChuckMesh");
	visualChunkEntity->SetMesh (visualChunkMesh, dGetIdentityMatrix());
	visualChunkMesh->Release();

	// add the vertex data
	AddMeshVertexwData (visualChunkMesh, fractureChunkMesh, fracturedCompoundCollision);

	// add the mesh indices
	OnReconstructMainMeshCallBack (chunkBody, fractureChunkMesh, fracturedCompoundCollision);
}
// create physics scene
void ConvexCast (DemoEntityManager* const scene)
{
    scene->CreateSkyBox();

    //char fileName[2048];
    //NewtonWorld* const world = scene->GetNewton();
    //GetWorkingFileName ("low_rez_rim.OFF", fileName);
    //NewtonMesh* const mesh = NewtonMeshLoadOFF(world, fileName);
    //NewtonCollision* coll = NewtonCreateConvexHullFromMesh (world, mesh, 0.0f, 0);
    //NewtonDestroyCollision(coll);


    // customize the scene after loading
    // set a user friction variable in the body for variable friction demos
    // later this will be done using LUA script
    //NewtonWorld* const world = scene->GetNewton();
//	dMatrix offsetMatrix (dGetIdentityMatrix());

    //	CreateLevelMesh (scene, "flatPlane.ngd", 0);
    //	CreateLevelMesh (scene, "playground.ngd", 0);

    StupidComplexOfConvexShapes* const stupidLevel = new StupidComplexOfConvexShapes (scene, 100);
    new dConvexCastManager (scene, stupidLevel);

    // add a single compound Box test
    AddSingleCompound(scene);
    AddStaticMesh(scene);
    AddUserDefineStaticMesh(scene);

    // place camera into position
    dMatrix camMatrix (dGetIdentityMatrix());
    dQuaternion rot (camMatrix);
    dVector origin (-30.0f, 10.0f, 0.0f, 0.0f);
    scene->SetCameraMatrix(rot, origin);
}
void AddPrimitiveArray (DemoEntityManager* const scene, dFloat mass, const dVector& origin, const dVector& size, int xCount, int zCount, dFloat spacing, PrimitiveType type, int materialID, const dMatrix& shapeOffsetMatrix, dFloat startElevation)
{
	// 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);

	// test collision mode
	//NewtonCollisionSetCollisonMode(collision, 0);

	DemoMesh* const geometry = new DemoMesh("primitive", collision, "smilli.tga", "smilli.tga", "smilli.tga");

	//dFloat startElevation = 1000.0f;
	//dFloat startElevation = 20.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 + size.m_y * 0.5f;
			CreateSimpleSolid (scene, geometry, mass, matrix, collision, materialID);
		}
	}
	// do not forget to release the assets	
	geometry->Release(); 
	NewtonDestroyCollision (collision);
}
void StructuredConvexFracturing (DemoEntityManager* const scene)
{
	// load the skybox
	scene->CreateSkyBox();

	// load the scene from a ngd file format
	//CreateLevelMesh (scene, "ruinsFloor.ngd", true);
	CreateLevelMesh (scene, "flatPlane.ngd", true);
	//CreateLevelMesh (scene, "sponza.ngd", true);
	//CreateLevelMesh (scene, "sponza.ngd", true);
	AddPrimitiveArray (scene, 0.0f, dVector (0.0f, 0.0f, 0.0f, 0.0f), dVector (100.0f, 1.0f, 100.0f, 0.0f), 1, 1, 0, _BOX_PRIMITIVE, 0, dGetIdentityMatrix());



	AddStructuredFractured (scene, dVector (0.0f, 0.0f, 0.0f, 0.0f), 0, "colum.ngd");


	// create a shattered mesh array
	//CreateSimpleVoronoiFracture (scene);

	//int defaultMaterialID = NewtonMaterialGetDefaultGroupID (scene->GetNewton());
	dVector location (0.0f, 0.0f, 0.0f, 0.0f);
	dVector size (0.75f, 0.75f, 0.75f, 0.0f);
	dMatrix shapeOffsetMatrix (dGetIdentityMatrix());

	// place camera into position
	dQuaternion rot (dVector (0.0f, 1.0f, 0.0f, 0.0f), -30.0f * 3.141592f / 180.0f); 
	dVector origin (-45.0f, 20.0f, -15.0f, 0.0f);
	scene->SetCameraMatrix(rot, origin);
}
static void CreateVisualEntity (DemoEntityManager* const scene, NewtonBody* const body)
{
	dMatrix matrix;
	NewtonBodyGetMatrix(body, &matrix[0][0]);

	DemoEntity* const visualEntity = new DemoEntity(matrix, NULL);
	scene->Append(visualEntity);

	// set the entiry as the user data;
	NewtonBodySetUserData (body, visualEntity);

	// create the mesh geometry and attach it to the entity
	DemoMesh* const visualMesh = new DemoMesh ("fraturedMainMesh");
	visualEntity->SetMesh (visualMesh, dGetIdentityMatrix());
	visualMesh->Release();

	// create the mesh and set the vertex array, but not the sub meshes
	NewtonCollision* const fracturedCompoundCollision = NewtonBodyGetCollision(body);
	dAssert (NewtonCollisionGetType(fracturedCompoundCollision) == SERIALIZE_ID_FRACTURED_COMPOUND);

	// add the vertex data
	NewtonFracturedCompoundMeshPart* const mainMesh = NewtonFracturedCompoundGetMainMesh (fracturedCompoundCollision);
	AddMeshVertexwData (visualMesh, mainMesh, fracturedCompoundCollision);

	// now add the sub mesh by calling the call back
	OnReconstructMainMeshCallBack (body, mainMesh, fracturedCompoundCollision);
}