void OnEndUpdate (dFloat timestepInSecunds)
	{
		DemoCamera* const camera = m_scene->GetCamera();

		dMatrix camMatrix(camera->GetNextMatrix());
		dMatrix playerMatrix (m_player->GetNextMatrix());

		dVector frontDir (camMatrix[0]);

		CustomPlayerController* const controller = m_player->m_controller; 
		dFloat height = controller->GetHigh();
		dVector upDir (controller->GetUpDir());

		dVector camOrigin(0.0f); 
		
		if (m_player->m_inputs.m_cameraMode) {
			// set third person view camera
			camOrigin = playerMatrix.TransformVector (upDir.Scale(height));
			camOrigin -= frontDir.Scale (PLAYER_THIRD_PERSON_VIEW_DIST);
		} else {
			// set first person view camera
			camMatrix = camMatrix * playerMatrix;
			camOrigin = playerMatrix.TransformVector (upDir.Scale(height));
		}

		camera->SetNextMatrix (*m_scene, camMatrix, camOrigin);

		// update the shot button
		if (m_shootState) {
			SpawnRandomProp (camera->GetNextMatrix());
		}
	}
// 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);
}
    // /////////////////////////////////////////////////////////////////
    //
    // /////////////////////////////////////////////////////////////////
    bool EnvironmentSceneNode::VPreRender()
    {
        bool result = false;

        result = SceneNode::VPreRender();

        if(result && !g_appPtr->GetTextureManagerPtr()->Bind(m_texHandle, GL_TEXTURE_CUBE_MAP, GL_TEXTURE0)) {
            GF_LOG_TRACE_ERR("EnvironmentSceneNode::VPreRender()", "Failed to activate the CubeMap texture");
            result = false;
        }

        if(result) {
            glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);

            // Get the camera matrix and clear the cameras position (we want to be able to rotate the environment box but not move it!).
            Matrix4 camMatrix(m_sgmPtr->GetCamera()->VGet()->GetToWorld());
            camMatrix[Matrix4::M30] = 0.0f;
            camMatrix[Matrix4::M31] = 0.0f;
            camMatrix[Matrix4::M32] = 0.0f;
            camMatrix[Matrix4::M33] = 1.0f;
            m_sgmPtr->GetStackManager()->GetModelViewMatrixStack()->LoadMatrix(camMatrix);
        }

        return (result);
    }
long NewtonDemos::onLoad(FXObject* sender, FXSelector id, void* eventPtr)
{
	BEGIN_MENU_OPTION();

	const FXchar patterns[]="Newton Dynamics Files (*.ngd)";
	FXFileDialog open(this,"Load Newton Dynamics scene");
	open.setPatternList(patterns);
	open.setDirectory ("../../../media");
	if(open.execute()){

		m_scene->Cleanup();

		// load the scene from a ngd file format
		m_scene->makeCurrent();
		m_scene->LoadScene (open.getFilename().text());
		m_scene->makeNonCurrent();

		// add a sky box to the scene, make the first object
		m_scene->Addtop (new SkyBox());

		// place camera into position
		dMatrix camMatrix (GetIdentityMatrix());
		//		camMatrix.m_posit = dVector (-40.0f, 10.0f, 0.0f, 0.0f);
		camMatrix = dYawMatrix(-0.0f * 3.1416f / 180.0f);
		camMatrix.m_posit = dVector (-5.0f, 1.0f, -0.0f, 0.0f);
		m_scene->SetCameraMatrix(camMatrix, camMatrix.m_posit);

		RestoreSettings ();
	}


	m_scene->ResetTimer();
	END_MENU_OPTION();
	return 1;
}
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");
}
static void SimpleMeshLevel (DemoEntityManager* const scene, bool optimization)
{
	// load the skybox
	scene->CreateSkyBox();

//float xxx[] = {2.3257, -3.6253, -2.7155, 2.7075, -3.6253, -2.7155, 2.7075, -3.6253, -2.3337, 2.3257, -3.6253, -2.3337};
//NewtonCollision* aaa = NewtonCreateConvexHull(scene->GetNewton(), sizeof (xxx) /(3 * sizeof (float)), xxx, 3 * sizeof (float), 0, 0, 0);


	// load the scene from a ngd file format
//	CreateLevelMesh (scene, "flatPlane.ngd", optimization);
	CreateLevelMesh (scene, "sponza.ngd", optimization);
//	CreateLevelMesh (scene, "cattle.ngd", fileName);
//	CreateLevelMesh (scene, "playground.ngd", optimization);
	
	// place camera into position
//	dQuaternion rot;
//	dVector posit (0.0f, 1.0f, 0.0f, 0.0f);
//	scene->SetCameraMatrix(rot, posit);

	dMatrix camMatrix (dRollMatrix(-20.0f * 3.1416f /180.0f) * dYawMatrix(-45.0f * 3.1416f /180.0f));
	dQuaternion rot (camMatrix);
	dVector origin (-30.0f, 40.0f, -15.0f, 0.0f);
	scene->SetCameraMatrix(rot, origin);

	NewtonWorld* const world = scene->GetNewton();
	int defaultMaterialID = NewtonMaterialGetDefaultGroupID (world);
	dVector location (0.0f, 0.0f, 0.0f, 0.0f);
	dVector size (0.5f, 0.5f, 1.0f, 0.0f);

//	int count = 1;
	int count = 6;
	dMatrix shapeOffsetMatrix (dGetIdentityMatrix());
	for (int i = 0; i < 3; i ++) {
		AddPrimitiveArray(scene, 10.0f, location, size, count, count, 3.0f, _SPHERE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
		AddPrimitiveArray(scene, 10.0f, location, size, count, count, 3.0f, _BOX_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
		AddPrimitiveArray(scene, 10.0f, location, size, count, count, 3.0f, _CAPSULE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
		AddPrimitiveArray(scene, 10.0f, location, size, count, count, 3.0f, _CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
		AddPrimitiveArray(scene, 10.0f, location, size, count, count, 3.0f, _TAPERED_CAPSULE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
		AddPrimitiveArray(scene, 10.0f, location, size, count, count, 3.0f, _TAPERED_CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
		AddPrimitiveArray(scene, 10.0f, location, size, count, count, 3.0f, _CHAMFER_CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
		AddPrimitiveArray(scene, 10.0f, location, size, count, count, 3.0f, _CONE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
		AddPrimitiveArray(scene, 10.0f, location, size, count, count, 3.0f, _REGULAR_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
		AddPrimitiveArray(scene, 10.0f, location, size, count, count, 3.0f, _RANDOM_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
		AddPrimitiveArray(scene, 10.0f, location, size, count, count, 3.0f, _COMPOUND_CONVEX_CRUZ_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	}



count = 8;
for (int i = 0; i < 50; i ++){
//AddPrimitiveArray(scene, 10.0f, location, size, count, count, 1.7f, _REGULAR_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
//AddPrimitiveArray(scene, 10.0f, location, size, count, count, 1.0f, _SPHERE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
}

}
// 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 SimpleMeshLevel (DemoEntityManager* const scene, bool optimization)
{
	// suspend simulation before making changes to the physics world
	scene->StopsExecution ();

	// load the skybox
	scene->Append(new SkyBox());


	// load the scene from and alchemedia file format
//	CreateLevelMesh (scene, "flatPlane.ngd", optimization);
	CreateLevelMesh (scene, "sponza.ngd", optimization);
//	CreateLevelMesh (scene, "cattle.ngd", fileName);
//	CreateLevelMesh (scene, "playground.ngd", fileName);
	
	// place camera into position
//	dQuaternion rot;
//	dVector posit (0.0f, 1.0f, 0.0f, 0.0f);
//	scene->SetCameraMatrix(rot, posit);

	dMatrix camMatrix (dRollMatrix(-20.0f * 3.1416f /180.0f) * dYawMatrix(-45.0f * 3.1416f /180.0f));
	dQuaternion rot (camMatrix);
//dQuaternion rot;
	dVector origin (-30.0f, 40.0f, -15.0f, 0.0f);
//	dVector origin (-10.0f, 1.0f, 0.0f, 0.0f);
	scene->SetCameraMatrix(rot, origin);

	NewtonWorld* const world = scene->GetNewton();
	int defaultMaterialID = NewtonMaterialGetDefaultGroupID (world);
	dVector location (0.0f, 0.0f, 0.0f, 0.0f);
	dVector size (0.5f, 0.5f, 0.5f, 0.0f);
	int count = 8;
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 1.7f, _SPHERE_PRIMITIVE, defaultMaterialID);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 1.7f, _BOX_PRIMITIVE, defaultMaterialID);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 1.7f, _CAPSULE_PRIMITIVE, defaultMaterialID);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 1.7f, _CYLINDER_PRIMITIVE, defaultMaterialID);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 1.7f, _CHAMFER_CYLINDER_PRIMITIVE, defaultMaterialID);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 1.7f, _BOX_PRIMITIVE, defaultMaterialID);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 1.7f, _CONE_PRIMITIVE, defaultMaterialID);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 1.7f, _CAPSULE_PRIMITIVE, defaultMaterialID);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 1.7f, _REGULAR_CONVEX_HULL_PRIMITIVE, defaultMaterialID);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 1.7f, _RANDOM_CONVEX_HULL_PRIMITIVE, defaultMaterialID);

//for (int i = 0; i < 20; i ++)
//AddPrimitiveArray(scene, 10.0f, location, size, count, count, 1.7f, _SPHERE_PRIMITIVE, defaultMaterialID);

	// resume the simulation
	scene->ContinueExecution();
}
void CompoundCollision (DemoEntityManager* const scene)
{
	// load the skybox
	scene->CreateSkyBox();

	// load the scene from a ngd file format
//	CreateLevelMesh (scene, "flatPlane.ngd", true);
//	CreateLevelMesh (scene, "playground.ngd", true);
	//	CreateLevelMesh (scene, "sponza.ngd", true);
	CreateHeightFieldTerrain(scene, HEIGHTFIELD_DEFAULT_SIZE, HEIGHTFIELD_DEFAULT_CELLSIZE,
							 1.5f, 0.2f, 200.0f, -50.0f);

	int defaultMaterialID = NewtonMaterialGetDefaultGroupID (scene->GetNewton());

	// set a material callback to get the colliding shape
	NewtonMaterialSetCollisionCallback (scene->GetNewton(), defaultMaterialID, defaultMaterialID, NULL, OnGettingTheCollisionSubShapeFromMaterialCallback);
	NewtonMaterialSetCompoundCollisionCallback(scene->GetNewton(), defaultMaterialID, defaultMaterialID, OnSubShapeAABBOverlapTest);

	dMatrix camMatrix (dRollMatrix(-20.0f * 3.1416f /180.0f) * dYawMatrix(-45.0f * 3.1416f /180.0f));
	dQuaternion rot (camMatrix);
	dVector origin (100.0f, 0.0f, 100.0f, 0.0f);
	dFloat hight = 1000.0f;
	origin = FindFloor (scene->GetNewton(), dVector (origin.m_x, hight, origin .m_z, 0.0f), hight * 2);
	origin.m_y += 10.0f;

	dVector location (origin);
	location.m_x += 40.0f;
	location.m_z += 40.0f;

	// this crash temporarily (I need to make the compound use shape Instance)
	MakeFunnyCompound (scene, location);

	int count = 5;
	dVector size (0.5f, 0.5f, 0.75f, 0.0f);
	dMatrix shapeOffsetMatrix (dGetIdentityMatrix());
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _BOX_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);


	// place camera into position
//	dQuaternion rot;
//	dVector origin (-40.0f, 10.0f, 0.0f, 0.0f);
	scene->SetCameraMatrix(rot, origin);
	//ExportScene (scene->GetNewton(), "../../../media/test1.ngd");

}
dMatrix GetModelViewMatrix ()
{
	int i;
	int j;

	GLdouble modelview[16]; 
	glGetDoublev(GL_MODELVIEW_MATRIX, modelview); 
	dMatrix camMatrix (dGetIdentityMatrix());
	for (i = 0; i < 4; i ++) {
		for (j = 0; j < 4; j ++) {
			camMatrix[i][j] = dFloat (modelview[i * 4 + j]);
		}
	}
	return camMatrix;
}
	void SetCamera()
	{
		if (m_player) {
			DemoEntityManager* const scene = (DemoEntityManager*)NewtonWorldGetUserData(GetWorld());
			DemoCamera* const camera = scene->GetCamera();
			dMatrix camMatrix(camera->GetNextMatrix());

			DemoEntity* player = (DemoEntity*)NewtonBodyGetUserData(m_player->GetBody());
			dMatrix playerMatrix(player->GetNextMatrix());

			dFloat height = 2.0f;
			dVector frontDir(camMatrix[0]);
			dVector upDir(0.0f, 1.0f, 0.0f, 0.0f);
			dVector camOrigin = playerMatrix.TransformVector(upDir.Scale(height));
			camOrigin -= frontDir.Scale(PLAYER_THIRD_PERSON_VIEW_DIST);

			camera->SetNextMatrix(*scene, camMatrix, camOrigin);
		}
	}
// create physics scene
void PrimitiveCollision (DemoEntityManager* const scene)
{
	// load the skybox
	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());

	int materialID = NewtonMaterialGetDefaultGroupID (world);

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

	AddSinglePrimitive (scene, -10.0f, _SPHERE_PRIMITIVE, materialID);
	AddSinglePrimitive (scene,  -8.0f, _BOX_PRIMITIVE, materialID);
	AddSinglePrimitive (scene,  -6.0f, _CAPSULE_PRIMITIVE, materialID);
	AddSinglePrimitive (scene,  -4.0f, _CYLINDER_PRIMITIVE, materialID);
	AddSinglePrimitive (scene,  -2.0f, _CONE_PRIMITIVE, materialID);
	AddSinglePrimitive (scene,   4.0f, _CHAMFER_CYLINDER_PRIMITIVE, materialID);
	AddSinglePrimitive (scene,   6.0f, _RANDOM_CONVEX_HULL_PRIMITIVE, materialID);
	AddSinglePrimitive (scene,   8.0f, _REGULAR_CONVEX_HULL_PRIMITIVE, materialID);


	// here we will change the standard gravity force callback and apply null and add a 
	for (NewtonBody* body = NewtonWorldGetFirstBody(world); body; body = NewtonWorldGetNextBody(world, body)) {
		DemoEntity* const entity = (DemoEntity*) NewtonBodyGetUserData(body);
		entity->SetUserData (new ShowCollisionCollide(body));
		NewtonBodySetForceAndTorqueCallback(body, PhysicsSpinBody);
		NewtonBodySetAutoSleep (body, 0);
	}

	// place camera into position
	//dMatrix camMatrix (dYawMatrix(90.0f * dDegreeToRad));
	dMatrix camMatrix (dGetIdentityMatrix());
	dQuaternion rot (camMatrix);
	dVector origin (-15.0f, 0.0f, 0.0f, 0.0f);
	scene->SetCameraMatrix(rot, origin);

}
static void SimpleMeshLevel (DemoEntityManager* const scene, bool optimization)
{
	// load the skybox
	scene->CreateSkyBox();

	// load the scene from a ngd file format
//	CreateLevelMesh (scene, "flatPlane.ngd", optimization);
	CreateLevelMesh (scene, "sponza.ngd", optimization);
//	CreateLevelMesh (scene, "cattle.ngd", fileName);
//	CreateLevelMesh (scene, "playground.ngd", optimization);

	dMatrix camMatrix (dRollMatrix(-20.0f * 3.1416f /180.0f) * dYawMatrix(-45.0f * 3.1416f /180.0f));
	dQuaternion rot (camMatrix);
	dVector origin (-30.0f, 40.0f, -15.0f, 0.0f);
	scene->SetCameraMatrix(rot, origin);

	NewtonWorld* const world = scene->GetNewton();
	int defaultMaterialID = NewtonMaterialGetDefaultGroupID (world);
	dVector location (0.0f, 0.0f, 0.0f, 0.0f);
	dVector size (0.25f, 0.25f, 0.5f, 0.0f);

	int count = 6;
	dMatrix shapeOffsetMatrix (dGetIdentityMatrix());
	for (int i = 0; i < 3; i ++) {
		AddPrimitiveArray(scene, 10.0f, location, size, count, count, 3.0f, _SPHERE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
		AddPrimitiveArray(scene, 10.0f, location, size, count, count, 3.0f, _BOX_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
		AddPrimitiveArray(scene, 10.0f, location, size, count, count, 3.0f, _CAPSULE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
		AddPrimitiveArray(scene, 10.0f, location, size, count, count, 3.0f, _CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
		AddPrimitiveArray(scene, 10.0f, location, size, count, count, 3.0f, _CHAMFER_CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
		AddPrimitiveArray(scene, 10.0f, location, size, count, count, 3.0f, _CONE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
		AddPrimitiveArray(scene, 10.0f, location, size, count, count, 3.0f, _REGULAR_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
		AddPrimitiveArray(scene, 10.0f, location, size, count, count, 3.0f, _RANDOM_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
		AddPrimitiveArray(scene, 10.0f, location, size, count, count, 3.0f, _COMPOUND_CONVEX_CRUZ_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	}


count = 8;
for (int i = 0; i < 50; i ++){
//AddPrimitiveArray(scene, 10.0f, location, size, count, count, 1.7f, _REGULAR_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
//AddPrimitiveArray(scene, 10.0f, location, size, count, count, 1.0f, _SPHERE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
}

}
	void ApplyInputs(dCustomPlayerController* const controller)
	{
		if (controller == m_player) {
			DemoEntityManager* const scene = (DemoEntityManager*)NewtonWorldGetUserData(GetWorld());
			dFloat forwarSpeed = (int(scene->GetKeyState('W')) - int(scene->GetKeyState('S'))) * PLAYER_WALK_SPEED;
			dFloat strafeSpeed = (int(scene->GetKeyState('D')) - int(scene->GetKeyState('A'))) * PLAYER_WALK_SPEED;

			if (forwarSpeed && strafeSpeed) {
				dFloat invMag = PLAYER_WALK_SPEED / dSqrt(forwarSpeed * forwarSpeed + strafeSpeed * strafeSpeed);
				forwarSpeed *= invMag;
				strafeSpeed *= invMag;
			}

			DemoCamera* const camera = scene->GetCamera();
			dMatrix camMatrix(camera->GetNextMatrix());

			controller->SetForwardSpeed(forwarSpeed);
			controller->SetLateralSpeed(strafeSpeed);
			controller->SetHeadingAngle(camera->GetYawAngle());
		}
	}
void StandardJoints (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
    dMatrix offsetMatrix (dGetIdentityMatrix());

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

    dVector location (0.0f, 0.0f, 0.0f, 0.0f);
    dVector size (1.5f, 2.0f, 2.0f, 0.0f);

//	AddPoweredRagDoll (scene, dVector (-20.0f, 0.0f, -15.0f));
	AddDistance (scene, dVector (-20.0f, 0.0f, -25.0f));
	AddLimitedBallAndSocket (scene, dVector (-20.0f, 0.0f, -20.0f));
//	AddPoweredRagDoll (scene, dVector (-20.0f, 0.0f, -15.0f));
	AddBallAndSockectWithFriction (scene, dVector (-20.0f, 0.0f, -10.0f));
	Add6DOF (scene, dVector (-20.0f, 0.0f, -5.0f));
	AddHinge (scene, dVector (-20.0f, 0.0f, 0.0f));

	AddSlider (scene, dVector (-20.0f, 0.0f, 5.0f));
	AddCylindrical (scene, dVector (-20.0f, 0.0f, 10.0f));
	AddUniversal (scene, dVector (-20.0f, 0.0f, 15.0f));
	//just to show up add some relational joints example 
	AddGear (scene, dVector (-20.0f, 0.0f, 20.0f));
	AddPulley (scene, dVector (-20.0f, 0.0f, 25.0f));
	AddGearAndRack (scene, dVector (-20.0f, 0.0f, 30.0f));
	AddSlidingContact (scene, dVector (-20.0f, 0.0f, 35.0f));

//	AddPathFollow (scene, dVector (20.0f, 0.0f, 0.0f));


    // place camera into position
    dMatrix camMatrix (dGetIdentityMatrix());
    dQuaternion rot (camMatrix);
    dVector origin (-40.0f, 5.0f, 0.0f, 0.0f);
    scene->SetCameraMatrix(rot, origin);
}
	void UpdateCamera (dFloat timestep)
	{
		if (m_player) {
			DemoEntityManager* const scene = (DemoEntityManager*) NewtonWorldGetUserData(GetWorld());
			DemoCamera* const camera = scene->GetCamera();
			dMatrix camMatrix (camera->GetNextMatrix ());
			dMatrix playerMatrix (m_player->GetNextMatrix());

			dVector frontDir (camMatrix[0]);
			dVector camOrigin; 
			if (m_externalView) {
				camOrigin = playerMatrix.m_posit + dVector(0.0f, VEHICLE_THIRD_PERSON_VIEW_HIGHT, 0.0f, 0.0f);
				camOrigin -= frontDir.Scale (VEHICLE_THIRD_PERSON_VIEW_DIST);
			} else {
				dAssert (0);
				//            camMatrix = camMatrix * playerMatrix;
				//            camOrigin = playerMatrix.TransformVector(dVector(-0.8f, ARTICULATED_VEHICLE_CAMERA_EYEPOINT, 0.0f, 0.0f));
			}

			camera->SetNextMatrix (*scene, camMatrix, camOrigin);
		}
	}
void NonUniformScaledCollision(DemoEntityManager* const scene)
{
	// load the skybox
	scene->CreateSkyBox();

	// load the scene from a ngd file format
	CreateLevelMesh(scene, "flatPlane.ngd", 1);
	//	CreateLevelMesh (scene, "sponza.ngd", 1);
	//	CreateLevelMesh (scene, "cattle.ngd", fileName);
	//	CreateLevelMesh (scene, "playground.ngd", 1);

	dMatrix camMatrix(dRollMatrix(-20.0f * 3.1416f / 180.0f) * dYawMatrix(-45.0f * 3.1416f / 180.0f));
	dQuaternion rot(camMatrix);
	//	dVector origin (-30.0f, 40.0f, -15.0f, 0.0f);
	dVector origin(-10.0f, 5.0f, -15.0f, 0.0f);
	scene->SetCameraMatrix(rot, origin);

	NewtonWorld* const world = scene->GetNewton();
	int defaultMaterialID = NewtonMaterialGetDefaultGroupID(world);
	dVector location(0.0f, 0.0f, 0.0f, 0.0f);
	dVector size0(0.5f, 0.5f, 1.0f, 0.0f);
	dVector size1(0.5f, 0.5f, 0.5f, 0.0f);

	int count = 5;
	dMatrix shapeOffsetMatrix(dRollMatrix(3.141592f / 2.0f));
	shapeOffsetMatrix.m_posit.m_y = 0.0f;

	AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 4.0f, _SPHERE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 4.0f, _BOX_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 4.0f, _CAPSULE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddNonUniformScaledPrimitives(scene, 10.0f, location, size1, count, count, 4.0f, _CAPSULE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddNonUniformScaledPrimitives(scene, 10.0f, location, size1, count, count, 4.0f, _CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 4.0f, _CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 4.0f, _CHAMFER_CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 4.0f, _CONE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 4.0f, _REGULAR_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 4.0f, _RANDOM_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 4.0f, _COMPOUND_CONVEX_CRUZ_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
}
void UserPlaneCollision (DemoEntityManager* const scene)
{
	// load the sky box
	scene->CreateSkyBox();

	//	create a user define infinite plane collision, and use it as a floor
	CreatePlaneCollision (scene, dVector (0.0f, 1.0f, 0.0f, 0.0f));


	dMatrix camMatrix (dRollMatrix(-20.0f * dDegreeToRad) * dYawMatrix(-45.0f * dDegreeToRad));
	dQuaternion rot (camMatrix);
	dVector origin (0.0f, 0.0f, 0.0f, 0.0f);
//	dFloat hight = 1000.0f;
//	origin = FindFloor (scene->GetNewton(), dVector (origin.m_x, hight, origin .m_z, 0.0f), hight * 2);
	origin.m_y += 10.0f;

	scene->SetCameraMatrix(rot, origin);

	int defaultMaterialID = NewtonMaterialGetDefaultGroupID (scene->GetNewton());
	dVector location (origin);
	location.m_x += 20.0f;
	location.m_z += 20.0f;
//	dVector size (0.5f, 0.5f, 0.75f, 0.0f);
	dVector size (1.0f, 1.0f, 1.0f, 0.0f);

	int count = 1;
	dMatrix shapeOffsetMatrix (dGetIdentityMatrix());
	AddUniformScaledPrimitives(scene, 10.0f, location, size, count, count, 4.0f, _BOX_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
//	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, _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, _RANDOM_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
//	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _COMPOUND_CONVEX_CRUZ_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
}
void UserHeightFieldCollision (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 camMatrix (dRollMatrix(-20.0f * dDegreeToRad) * dYawMatrix(-45.0f * dDegreeToRad));
	dQuaternion rot (camMatrix);
	dVector origin (250.0f, 0.0f, 250.0f, 0.0f);
	dFloat height = 1000.0f;
	origin = FindFloor (scene->GetNewton(), dVector (origin.m_x, height, origin .m_z, 0.0f), height * 2);
	origin.m_y += 10.0f;

	scene->SetCameraMatrix(rot, origin);

	int defaultMaterialID = NewtonMaterialGetDefaultGroupID (scene->GetNewton());
	dVector location (origin);
	location.m_x += 20.0f;
	location.m_z += 20.0f;
	dVector size (0.5f, 0.5f, 0.75f, 0.0f);

	int count = 5;
//	int count = 1;
	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, _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, _RANDOM_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _COMPOUND_CONVEX_CRUZ_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
}
void Restitution (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());

	int defaultMaterialID = NewtonMaterialGetDefaultGroupID (world);
	NewtonMaterialSetCollisionCallback (world, defaultMaterialID, defaultMaterialID, NULL, UserContactRestitution); 


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

	dVector location (0.0f, 0.0f, 0.0f, 0.0f);
	dVector size (0.5f, 0.5f, 1.0f, 0.0f);

	// create some spheres 
	dVector sphSize (1.0f, 1.0f, 1.0f, 0.0f);
	NewtonCollision* const sphereCollision = CreateConvexCollision (world, offsetMatrix, sphSize, _SPHERE_PRIMITIVE, 0);
	DemoMesh* const sphereMesh = new DemoMesh("sphere", sphereCollision, "smilli.tga", "smilli.tga", "smilli.tga");

	// create some boxes too
	dVector boxSize (1.0f, 0.5f, 2.0f, 0.0f);
	NewtonCollision* const boxCollision = CreateConvexCollision (world, offsetMatrix, boxSize, _BOX_PRIMITIVE, 0);
	DemoMesh* const boxMesh = new DemoMesh("box", boxCollision, "smilli.tga", "smilli.tga", "smilli.tga");


	int zCount = 10;
	dFloat spacing = 4.0f;
	dMatrix matrix (dGetIdentityMatrix());
	dVector origin (matrix.m_posit);
	origin.m_x -= 0.0f;

	// create a simple scene
	for (int i = 0; i < zCount; i ++) {
		dFloat z;
		dFloat x;
		dFloat mass;
		dVector size (1.0f, 0.5f, 2.0f, 0.0f);

		x = origin.m_x;
		z = origin.m_z + (i - zCount / 2) * spacing;

		mass = 1.0f;
		matrix.m_posit = FindFloor (world, dVector (x, 100.0f, z), 200.0f);
		matrix.m_posit.m_w = 1.0f;
		
		float restitution;
		NewtonBody* body;
		NewtonCollision* collision;
		

		matrix.m_posit.m_y += 4.0f;
		body = CreateSimpleSolid (scene, sphereMesh, mass, matrix, sphereCollision, defaultMaterialID);
		NewtonBodySetLinearDamping (body, 0.0f);
		collision = NewtonBodyGetCollision(body);
		restitution = i * 0.1f + 0.083f;
		NewtonCollisionSetUserData (collision, *((void**)&restitution));

		matrix.m_posit.m_y += 4.0f;
		//body = CreateSimpleSolid (scene, sphereMesh, mass, matrix, sphereCollision, defaultMaterialID, shapeOffsetMatrix);
		body = CreateSimpleSolid (scene, boxMesh, mass, matrix, boxCollision, defaultMaterialID);
		NewtonBodySetLinearDamping (body, 0.0f);
		collision = NewtonBodyGetCollision(body);
		restitution = i * 0.1f + 0.083f;
		NewtonCollisionSetUserData (collision, *((void**)&restitution));

		matrix.m_posit.m_y += 4.0f;
		body = CreateSimpleSolid (scene, sphereMesh, mass, matrix, sphereCollision, defaultMaterialID);
		NewtonBodySetLinearDamping (body, 0.0f);
		collision = NewtonBodyGetCollision(body);
		restitution = i * 0.1f + 0.083f;
		NewtonCollisionSetUserData (collision, *((void**)&restitution));

		matrix.m_posit.m_y += 4.0f;
		dVector boxSize (1.0f, 0.5f, 2.0f, 0.0f);
		body = CreateSimpleSolid (scene, boxMesh, mass, matrix, boxCollision, defaultMaterialID);
		NewtonBodySetLinearDamping (body, 0.0f);
		collision = NewtonBodyGetCollision(body);
		restitution = i * 0.1f + 0.083f;
		NewtonCollisionSetUserData (collision, *((void**)&restitution));
	}

	boxMesh->Release();
	sphereMesh->Release();
	NewtonDestroyCollision(boxCollision);
	NewtonDestroyCollision(sphereCollision);


	dMatrix camMatrix (dGetIdentityMatrix());
	dQuaternion rot (camMatrix);
	origin = dVector (-25.0f, 5.0f, 0.0f, 0.0f);
	scene->SetCameraMatrix(rot, origin);

}
// create physics scene
void PuckSlide (DemoEntityManager* const scene)
{
	scene->CreateSkyBox();

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

	int	materialGroupIDs[SB_NUM_MATERIALS];

	// Create groups
	for (int i = 0; i < SB_NUM_MATERIALS; i++)
	{
		materialGroupIDs[i] = NewtonMaterialCreateGroupID(world);
	}
	
	// Setup the material data
	NewtonMaterialSetDefaultSoftness(world, materialGroupIDs[SBMaterial_WEIGHT], materialGroupIDs[SBMaterial_SURFACE], 0.15f);
	NewtonMaterialSetDefaultElasticity(world, materialGroupIDs[SBMaterial_WEIGHT], materialGroupIDs[SBMaterial_SURFACE], 0.30f);
	NewtonMaterialSetDefaultFriction(world, materialGroupIDs[SBMaterial_WEIGHT], materialGroupIDs[SBMaterial_SURFACE], 0.05f, 0.04f);


	// setup callbacks for collisions between two material groups
	NewtonMaterialSetCollisionCallback(world,materialGroupIDs[SBMaterial_WEIGHT],materialGroupIDs[SBMaterial_SURFACE],NULL,PhysicsNewton_CollisionPuckSurfaceCB);

	///////
	// Add table
	{
		dVector tableSize(TABLE_LENGTH, TABLE_HEIGHT, TABLE_WIDTH, 0.0f);

		// create the shape and visual mesh as a common data to be re used
		NewtonCollision* const collision = CreateConvexCollision (world, dGetIdentityMatrix(), tableSize, _BOX_PRIMITIVE, materialGroupIDs[SBMaterial_SURFACE]);

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

		dMatrix matrix = dGetIdentityMatrix();
		matrix.m_posit.m_x = 0.0f;
		matrix.m_posit.m_z = 0.0f;
		matrix.m_posit.m_y = 0.0f;
		NewtonBody* const tableBody = CreateSimpleSolid (scene, geometry, 0.0, matrix, collision, materialGroupIDs[SBMaterial_SURFACE]);

		// this is deprecated, use NewtonBodySetMassProperties
		//NewtonBodySetMassMatrix(tableBody, 0.0f, 1.0f, 1.0f, 1.0f);
		NewtonBodySetMassProperties(tableBody, 0.0f, NewtonBodyGetCollision(tableBody));

		NewtonBodySetMaterialGroupID(tableBody, materialGroupIDs[SBMaterial_SURFACE]);

		// it is not wise to se static body to continuous collision mode
		//NewtonBodySetContinuousCollisionMode(tableBody, 1);

		// do not forget to release the assets	
		geometry->Release(); 

		// the collision need to be destroy, the body is using an instance no a reference
		NewtonDestroyCollision (collision);
	}
	///////

	// Add puck
	{
		new PuckEntity (scene, materialGroupIDs[SBMaterial_WEIGHT]);
	}

	// place camera into position
	dMatrix camMatrix (dPitchMatrix(20.0f * 3.1416f /180.0f));
	dQuaternion rot (camMatrix);
	dVector origin (CAMERA_Z, CAMERA_Y, CAMERA_X, 0.0f);
	scene->SetCameraMatrix(rot, origin);
}
void ScaledMeshCollision (DemoEntityManager* const scene)
{
	// load the skybox
	scene->CreateSkyBox();

	// load the scene from a ngd file format
	CreateLevelMesh (scene, "flatPlane.ngd", 1);
	//CreateLevelMesh (scene, "flatPlaneDoubleFace.ngd", 1);
	//CreateLevelMesh (scene, "sponza.ngd", 0);
	//CreateLevelMesh (scene, "cattle.ngd", fileName);
	//CreateLevelMesh (scene, "playground.ngd", 0);

	//dMatrix camMatrix (dRollMatrix(-20.0f * 3.1416f /180.0f) * dYawMatrix(-45.0f * 3.1416f /180.0f));
	dMatrix camMatrix (dGetIdentityMatrix());
	dQuaternion rot (camMatrix);
	dVector origin (-15.0f, 5.0f, 0.0f, 0.0f);
	//origin = origin.Scale (0.25f);
	scene->SetCameraMatrix(rot, origin);


	NewtonWorld* const world = scene->GetNewton();
	int defaultMaterialID = NewtonMaterialGetDefaultGroupID (world);
	dVector location (0.0f, 0.0f, 0.0f, 0.0f);

	dMatrix matrix (dGetIdentityMatrix());
	matrix.m_posit = location;
	matrix.m_posit.m_x = 0.0f;
	matrix.m_posit.m_y = 0.0f;
	matrix.m_posit.m_z = 0.0f;
	matrix.m_posit.m_w = 1.0f;

	DemoEntity teaPot (dGetIdentityMatrix(), NULL);
	teaPot.LoadNGD_mesh("teapot.ngd", world);
	//teaPot.LoadNGD_mesh("box.ngd", world);

	NewtonCollision* const staticCollision = CreateCollisionTree (world, &teaPot, 0, true);
	CreateScaleStaticMesh (&teaPot, staticCollision, scene, matrix, dVector (1.0f, 1.0f, 1.0f, 0.0f));
//	CreateScaleStaticMesh (&teaPot, staticCollision, scene, matrix, dVector (0.5f, 0.5f, 2.0f, 0.0f));

	matrix.m_posit.m_z = -5.0f;
	CreateScaleStaticMesh (&teaPot, staticCollision, scene, matrix, dVector (0.5f, 0.5f, 2.0f, 0.0f));

	matrix.m_posit.m_z = 5.0f;
	CreateScaleStaticMesh (&teaPot, staticCollision, scene, matrix, dVector (3.0f, 3.0f, 1.5f, 0.0f));

	matrix.m_posit.m_z = 0.0f;
	matrix.m_posit.m_x = -5.0f;
	CreateScaleStaticMesh (&teaPot, staticCollision, scene, matrix, dVector (0.5f, 0.5f, 0.5f, 0.0f));

	matrix.m_posit.m_x = 5.0f;
	CreateScaleStaticMesh (&teaPot, staticCollision, scene, matrix, dVector (2.0f, 2.0f, 2.0f, 0.0f));

	// do not forget to destroy the collision mesh helper
	NewtonDestroyCollision(staticCollision);

	dVector size0 (1.0f, 1.0f, 1.0f, 0.0f);
	dVector size1 (0.5f, 1.0f, 1.0f, 0.0f);
	dMatrix shapeOffsetMatrix (dRollMatrix(3.141592f/2.0f));

	int count = 3;
	AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 5.0f, _SPHERE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 5.0f, _BOX_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 5.0f, _CAPSULE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddNonUniformScaledPrimitives(scene, 10.0f, location, size1, count, count, 5.0f, _CAPSULE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddNonUniformScaledPrimitives(scene, 10.0f, location, size1, count, count, 5.0f, _CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 5.0f, _CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 5.0f, _CHAMFER_CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 5.0f, _CONE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 5.0f, _REGULAR_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 5.0f, _RANDOM_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);

	origin.m_x -= 4.0f;
	origin.m_y += 1.0f;
	scene->SetCameraMatrix(rot, origin);	
}
void PrecessingTops (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
	dMatrix offsetMatrix (dGetIdentityMatrix());

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

	dVector location (0.0f, 0.0f, 0.0f, 0.0f);
	dVector size (3.0f, 2.0f, 0.0f, 0.0f);

	// create an array of cones 
	const int count = 10;

	// all shapes use the x axis as the  axis of symmetry, to make an upright cone we apply a 90 degree rotation local matrix
	dMatrix shapeOffsetMatrix (dRollMatrix(-3.141592f/2.0f));
	AddPrimitiveArray(scene, 50.0f, location, size, count, count, 5.0f, _CONE_PRIMITIVE, 0, shapeOffsetMatrix);

	// till the cont 30 degrees, and apply a local high angular velocity
	dMatrix matrix (dRollMatrix (-25.0f * 3.141592f / 180.0f));
	dVector omega (0.0f, 50.0f, 0.0f);
	omega = matrix.RotateVector (omega);
	dVector damp (0.0f, 0.0f, 0.0f, 0.0f);

	int topscount = 0;
	NewtonBody* array[count * count];
	NewtonWorld* const world = scene->GetNewton();
	for (NewtonBody* body = NewtonWorldGetFirstBody(world); body; body = NewtonWorldGetNextBody(world, body)) {
		NewtonCollision* const collision = NewtonBodyGetCollision(body);
		dVector com;
		if (NewtonCollisionGetType (collision) == SERIALIZE_ID_CONE) {
			array[topscount] = body;
			topscount ++;
		}
	}

	for (int i = 0; i < topscount ; i ++) {
		dMatrix bodyMatrix;
		NewtonBody* const body = array[i];
		NewtonBodyGetMatrix(body, &bodyMatrix[0][0]);
		matrix.m_posit = bodyMatrix.m_posit;
		matrix.m_posit.m_y += 1.0f; 
		NewtonBodySetMatrix(body, &matrix[0][0]);

		dFloat Ixx;
		dFloat Iyy;
		dFloat Izz;
		dFloat mass;
		NewtonBodyGetMassMatrix(body, &mass, &Ixx, &Iyy, &Izz);
		NewtonBodySetMassMatrix(body, mass, Ixx, Iyy * 8.0f, Izz);
		NewtonBodySetOmega (body, &omega[0]);

		NewtonBodySetAutoSleep (body, 0);
		NewtonBodySetLinearDamping(body, 0.0f);
		NewtonBodySetAngularDamping (body, &damp[0]);

	}

	// place camera into position
	dMatrix camMatrix (dGetIdentityMatrix());
	dQuaternion rot (camMatrix);
	dVector origin (-40.0f, 5.0f, 0.0f, 0.0f);
	scene->SetCameraMatrix(rot, origin);
}
void SceneCollision (DemoEntityManager* const scene)
{
	NewtonWorld* world = scene->GetNewton();

	// add the Sky
	scene->CreateSkyBox();

	// create a body and with a scene collision
	NewtonCollision* const sceneCollision = NewtonCreateSceneCollision (scene->GetNewton(), 0);

	// create a visual scene empty mesh
	ComplexScene* const visualMesh = new ComplexScene(sceneCollision);
	scene->Append (visualMesh);


	// add some shapes
	visualMesh->AddPrimitives(scene);

	// this is optional, finish the scene construction, optimize the collision scene
	dMatrix matrix (dGetIdentityMatrix());


	// create the level body and add it to the world
	NewtonBody* const level = NewtonCreateDynamicBody (world, sceneCollision, &matrix[0][0]);

	// replace the collision with the newly created one the  
	visualMesh->m_sceneCollision = NewtonBodyGetCollision(level);

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

	// do not forget to release the collision
	NewtonDestroyCollision (sceneCollision);


	// add few objects
	int defaultMaterialID = NewtonMaterialGetDefaultGroupID (world);
	NewtonMaterialSetCollisionCallback (world, defaultMaterialID, defaultMaterialID, OnBodyAABBOverlap, OnContactCollision); 
	NewtonMaterialSetCompoundCollisionCallback(world, defaultMaterialID, defaultMaterialID, OnSubShapeAABBOverlapTest);



	dVector location (0.0f, 0.0f, 0.0f, 0.0f);
	dVector size (0.5f, 0.5f, 0.5f, 0.0f);
	dMatrix shapeOffsetMatrix (dGetIdentityMatrix());

	int count = 5;
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 1.7f, _SPHERE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 1.7f, _BOX_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 1.7f, _CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 1.7f, _CHAMFER_CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 1.7f, _CONE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 1.7f, _CAPSULE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 1.7f, _RANDOM_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 1.7f, _COMPOUND_CONVEX_CRUZ_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
	

	dMatrix camMatrix (dRollMatrix(-20.0f * 3.1416f /180.0f) * dYawMatrix(-45.0f * 3.1416f /180.0f));
	dQuaternion rot (camMatrix);
	dVector origin (-15.0f, 5.0f, 0.0f, 0.0f);
	scene->SetCameraMatrix(rot, origin);

}
void PDFDocumentTools::CalculateCameraPropertiesFromInventorCamera(
    Vector3 inventorCameraPosition, Vector4 inventorCameraOrientation, float inventorCameraFocalDistance, float inventorCameraHeight, // inputs
    Vector3& camCenterOfOrbit, Vector3& camCenterToCamera, float& camRadiusOfOrbit, float& camRollAngle, float& camFOVAngle
    )
{
  SbVec3f cameraRotationAxis(inventorCameraOrientation[0], inventorCameraOrientation[1], inventorCameraOrientation[2]);
  SbRotation cameraOrientation(cameraRotationAxis, inventorCameraOrientation[3]);

  SbMatrix cameraRotationMatrix;
  cameraOrientation.getValue(cameraRotationMatrix);

  //Vector3 kosXAxis(1,0,0);
  //Vector3 kosYAxis(0,1,0);
  Vector3 kosZAxis(0,0,1);
  Vector3 camXAxis(cameraRotationMatrix[0][0], cameraRotationMatrix[0][1], cameraRotationMatrix[0][2]);
  Vector3 camYAxis(cameraRotationMatrix[1][0], cameraRotationMatrix[1][1], cameraRotationMatrix[1][2]);
  Vector3 camZAxis(cameraRotationMatrix[2][0], cameraRotationMatrix[2][1], cameraRotationMatrix[2][2]);
  Vector3 camYAxisInverted = camYAxis * -1;
  Vector3 centerToCamera = camZAxis * inventorCameraFocalDistance;
  Vector3 centerOfOrbit = inventorCameraPosition - centerToCamera;
  centerToCamera.normalize(); // Must be AFTER calculation of centerOfOrbit!

  Vector4 mx(cameraRotationMatrix[0][0], cameraRotationMatrix[0][1], cameraRotationMatrix[0][2], cameraRotationMatrix[0][3]);
  Vector4 my(cameraRotationMatrix[1][0], cameraRotationMatrix[1][1], cameraRotationMatrix[1][2], cameraRotationMatrix[1][3]);
  Vector4 mz(cameraRotationMatrix[2][0], cameraRotationMatrix[2][1], cameraRotationMatrix[2][2], cameraRotationMatrix[2][3]);
  Vector4 mr(cameraRotationMatrix[3][0], cameraRotationMatrix[3][1], cameraRotationMatrix[3][2], cameraRotationMatrix[3][3]);
  Matrix4 camMatrix(mx, my, mz, mr);

  Vector3 projectionAxis1 = camZAxis.cross(kosZAxis); 
  Vector3 projectionAxis2 = projectionAxis1.cross(camZAxis);

  projectionAxis2.normalize();

  // Calc roll angle
  double rollAangleRadians = acos(camYAxisInverted.dot(projectionAxis2));
  double rollAngleDegrees = (rollAangleRadians / M_PI * 180.0) + 180.0;

  double angleRadBetweenProjectionAxisAndCamXAxis = acos(camXAxis.dot(projectionAxis2));
  if (angleRadBetweenProjectionAxisAndCamXAxis <  (M_PI/2.0))
  {
    rollAngleDegrees = 360.0 - rollAngleDegrees;
  }

  // Calc FOV angle
  double fieldOfViewAngle = 45.0;
  if (inventorCameraHeight != 0)
  {
    fieldOfViewAngle = 180.0/(M_PI/inventorCameraHeight);
  }
  if (fieldOfViewAngle > 180.0)  // Can happen if Orthographic camera mode is selected in inventor
  {
    fieldOfViewAngle = 45.0;
  }

  // Return result values
  camCenterOfOrbit  = centerOfOrbit;
  camCenterToCamera = centerToCamera;
  camRadiusOfOrbit  = inventorCameraFocalDistance;
  camRollAngle      = rollAngleDegrees;
  camFOVAngle       = fieldOfViewAngle;
}
void AlchimedesBuoyancy(DemoEntityManager* const scene)
{
	// load the sky box
	scene->CreateSkyBox();


	// load the mesh 
	CreateLevelMesh (scene, "swimmingPool.ngd", true);


	// add a trigger Manager to the world
	MyTriggerManager* const triggerManager = new MyTriggerManager(scene->GetNewton());

	dMatrix triggerLocation (dGetIdentityMatrix());
	triggerLocation.m_posit.m_x =  17.0f;
	triggerLocation.m_posit.m_y = -3.5f;

	NewtonCollision* const poolBox = NewtonCreateBox (scene->GetNewton(), 30.0f, 6.0f, 20.0f, 0, NULL);  
	triggerManager->CreateBuoyancyTrigger (triggerLocation, poolBox);
	NewtonDestroyCollision (poolBox);

	// 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
	dMatrix offsetMatrix (dGetIdentityMatrix());

	// place camera into position
	dMatrix camMatrix (dGetIdentityMatrix());
	dQuaternion rot (camMatrix);
	dVector origin (-20.0f, 10.0f, 0.0f, 0.0f);
	scene->SetCameraMatrix(rot, origin);


	int defaultMaterialID = NewtonMaterialGetDefaultGroupID (scene->GetNewton());

/*
	//test buoyancy on scaled collisions
	dVector plane (0.0f, 1.0f, 0.0f, 0.0f);
	dMatrix L1 (dPitchMatrix(30.0f * 3.141692f / 180.0f) * dYawMatrix(0.0f * 3.141692f / 180.0f) * dRollMatrix(0.0f * 3.141692f / 180.0f));
	NewtonCollision* xxx0 = NewtonCreateCompoundCollision(scene->GetNewton(), 0);
	NewtonCompoundCollisionBeginAddRemove(xxx0);
	NewtonCollision* xxxx0 = NewtonCreateBox(scene->GetNewton(), 1.0f, 2.0f, 1.0f, 0, &L1[0][0]);
	NewtonCompoundCollisionAddSubCollision(xxx0, xxxx0);
	NewtonCompoundCollisionEndAddRemove(xxx0);

	NewtonCollision* xxx1 = NewtonCreateCompoundCollision(scene->GetNewton(), 0);
	NewtonCollision* xxxx1 = NewtonCreateBox(scene->GetNewton(), 1.0f, 1.0f, 1.0f, 0, &L1[0][0]);
	NewtonCompoundCollisionAddSubCollision(xxx1, xxxx1);
	NewtonCompoundCollisionEndAddRemove(xxx1);
	NewtonCollisionSetScale(xxx1, 1.0f, 2.0f, 1.0f);

	//dMatrix m (dPitchMatrix(45.0f * 3.141692f / 180.0f) * dYawMatrix(40.0f * 3.141692f / 180.0f) * dRollMatrix(70.0f * 3.141692f / 180.0f));
	dMatrix m (dPitchMatrix(0.0f * 3.141692f / 180.0f) * dYawMatrix(0.0f * 3.141692f / 180.0f) * dRollMatrix(0.0f * 3.141692f / 180.0f));

	dVector gravity (0.0f, 0.0f, -9.8f, 0.0f);
	dVector cog0 (0.0f, 0.0f, 0.0f, 0.0f);
	dVector accelPerUnitMass0;
	dVector torquePerUnitMass0;
	NewtonConvexCollisionCalculateBuoyancyAcceleration (xxx0, &m[0][0], &cog0[0], &gravity[0], &plane[0], 1.0f, 0.1f, &accelPerUnitMass0[0], &torquePerUnitMass0[0]);

	dVector cog1 (0.0f, 0.0f, 0.0f, 0.0f);
	dVector accelPerUnitMass1;
	dVector torquePerUnitMass1;
	NewtonConvexCollisionCalculateBuoyancyAcceleration (xxx1, &m[0][0], &cog1[0], &gravity[0], &plane[0], 1.0f, 0.1f, &accelPerUnitMass1[0], &torquePerUnitMass1[0]);
*/

	int count = 5;
	dVector size (1.0f, 0.25f, 0.5f);
	dVector location (10.0f, 0.0f, 0.0f, 0.0f);
	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, _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);

/*
for (NewtonBody* bodyPtr = NewtonWorldGetFirstBody(scene->GetNewton()); bodyPtr; bodyPtr = NewtonWorldGetNextBody(scene->GetNewton(), bodyPtr)) {
	NewtonCollision* collision = NewtonBodyGetCollision(bodyPtr);
	if (NewtonCollisionGetType(collision) == SERIALIZE_ID_COMPOUND) {
		NewtonCollisionSetScale (collision, 0.5f, 0.5f, 0.5f);
	}
}
*/

//	AddPrimitiveArray(scene, 10.0f, location, size, count, count, 5.0f, _RANDOM_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix);
}