PlaformEntityEntity (DemoEntityManager* const scene, DemoEntity* const source, NewtonBody* const triggerPort0, NewtonBody* const triggerPort1)
		:DemoEntity (source->GetNextMatrix(), NULL)
	{
		scene->Append(this);

		DemoMesh* const mesh = (DemoMesh*)source->GetMesh();
		dAssert (mesh->IsType(DemoMesh::GetRttiType()));

		SetMesh(mesh, source->GetMeshMatrix());

		const dFloat mass = 100.0f;
		dMatrix matrix (source->GetNextMatrix()) ;
		NewtonWorld* const world = scene->GetNewton();

		// note: because the mesh matrix can have scale, for simplicity just apply the local mesh matrix to the vertex cloud
		dVector pool[128];
		const dMatrix& meshMatrix = GetMeshMatrix();
		meshMatrix.TransformTriplex(&pool[0].m_x, sizeof (dVector), mesh->m_vertex, 3 * sizeof (dFloat), mesh->m_vertexCount);
		NewtonCollision* const collision = NewtonCreateConvexHull(world, mesh->m_vertexCount, &pool[0].m_x, sizeof (dVector), 0, 0, NULL);

		NewtonBody* body = CreateSimpleBody (world, this, 100, matrix, collision, 0);
		NewtonDestroyCollision(collision);


		// attach a kinematic joint controller joint to move this body 
		dVector pivot;
		NewtonBodyGetCentreOfMass (body, &pivot[0]);
		pivot = matrix.TransformVector(pivot);
		m_driver = new FerryDriver (body, pivot, triggerPort0, triggerPort1);
		m_driver->SetMaxLinearFriction (50.0f * dAbs (mass * DEMO_GRAVITY)); 
		m_driver->SetMaxAngularFriction(50.0f * dAbs (mass * DEMO_GRAVITY)); 
	}
NewtonBody* CreateSimpleSolid (DemoEntityManager* const scene, DemoMesh* const mesh, dFloat mass, const dMatrix& matrix, NewtonCollision* const collision, int materialId)
{
	dAssert (mesh);
	dAssert (collision);

	// add an new entity to the world
	DemoEntity* const entity = new DemoEntity(matrix, NULL);
	scene->Append (entity);
	entity->SetMesh(mesh, dGetIdentityMatrix());
	return CreateSimpleBody (scene->GetNewton(), entity, mass, matrix, collision, materialId);
}
    StupidComplexOfConvexShapes (DemoEntityManager* const scene, int count)
        :DemoEntity (dGetIdentityMatrix(), NULL)
        ,m_rayP0(0.0f, 0.0f, 0.0f, 0.0f)
        ,m_rayP1(0.0f, 0.0f, 0.0f, 0.0f)
    {
        scene->Append(this);

        count = 40;
        //count = 1;
        const dFloat size = 0.5f;

        DemoMesh* gemetries[32];
        NewtonCollision* collisionArray[32];
        NewtonWorld* const world = scene->GetNewton();
        int materialID = NewtonMaterialGetDefaultGroupID(world);

        // create a pool of predefined convex mesh
        //		PrimitiveType selection[] = {_SPHERE_PRIMITIVE,	_BOX_PRIMITIVE,	_CAPSULE_PRIMITIVE, _CYLINDER_PRIMITIVE, _CONE_PRIMITIVE, _TAPERED_CAPSULE_PRIMITIVE, _TAPERED_CYLINDER_PRIMITIVE, _CHAMFER_CYLINDER_PRIMITIVE, _RANDOM_CONVEX_HULL_PRIMITIVE, _REGULAR_CONVEX_HULL_PRIMITIVE};
        PrimitiveType selection[] = {_SPHERE_PRIMITIVE};
        for (int i = 0; i < int (sizeof (collisionArray) / sizeof (collisionArray[0])); i ++) {
            int index = dRand() % (sizeof (selection) / sizeof (selection[0]));
            dVector shapeSize (size + RandomVariable (size / 2.0f), size + RandomVariable (size / 2.0f), size + RandomVariable (size / 2.0f), 0.0f);
            shapeSize = dVector(size, size, size, 0.0f);
            collisionArray[i] = CreateConvexCollision (world, dGetIdentityMatrix(), shapeSize, selection[index], materialID);
            gemetries[i] = new DemoMesh("geometry", collisionArray[i], "wood_4.tga", "wood_4.tga", "wood_1.tga");
        }

        // make a large complex of plane by adding lost of these shapes at a random location and oriention;
        NewtonCollision* const compound = NewtonCreateCompoundCollision (world, materialID);
        NewtonCompoundCollisionBeginAddRemove(compound);

        for (int i = 0 ; i < count; i ++) {
            for (int j = 0 ; j < count; j ++) {
                float pitch = RandomVariable (1.0f) * 2.0f * 3.1416f;
                float yaw = RandomVariable (1.0f) * 2.0f * 3.1416f;
                float roll = RandomVariable (1.0f) * 2.0f * 3.1416f;

                float x = size * (j - count / 2) + RandomVariable (size * 0.5f);
                float y = RandomVariable (size * 2.0f);
                float z = size * (i - count / 2) + RandomVariable (size * 0.5f);

                dMatrix matrix (dPitchMatrix (pitch) * dYawMatrix (yaw) * dRollMatrix (roll));
                matrix.m_posit = dVector (x, y, z, 1.0f);

                int index = dRand() % (sizeof (selection) / sizeof (selection[0]));
                DemoEntity* const entity = new DemoEntity(matrix, this);

                entity->SetMesh(gemetries[index], dGetIdentityMatrix());

                NewtonCollisionSetMatrix (collisionArray[index], &matrix[0][0]);
                NewtonCompoundCollisionAddSubCollision (compound, collisionArray[index]);
            }
        }
        NewtonCompoundCollisionEndAddRemove(compound);

        CreateSimpleBody (world, NULL, 0.0f, dGetIdentityMatrix(), compound, 0);

        // destroy all collision shapes after they are used
        NewtonDestroyCollision(compound);
        for (int i = 0; i < int (sizeof (collisionArray) / sizeof (collisionArray[0])); i ++) {
            gemetries[i]->Release();
            NewtonDestroyCollision(collisionArray[i]);
        }

        // now make and array of collision shapes for convex casting by mouse point click an drag
        CreateCastingShapes(scene, size * 2.0f);
    }
static void LoadHangingBridge (DemoEntityManager* const scene, TriggerManager* const triggerManager, NewtonCollision* const sceneCollision, const char* const name, const dMatrix& location, NewtonBody* const playGroundBody)
{
	NewtonWorld* const world = scene->GetNewton();
	DemoEntityManager::dListNode* const bridgeNodes = scene->GetLast();
	LoadScene(scene, name, location);

	// add bridge foundations
	for (DemoEntityManager::dListNode* node = bridgeNodes->GetNext(); node; node = node->GetNext()) {
		DemoEntity* const entity = node->GetInfo();
		if (entity->GetName().Find("ramp") != -1) {	
			DemoMesh* const mesh = (DemoMesh*)entity->GetMesh();
			dAssert (mesh->IsType(DemoMesh::GetRttiType()));

			NewtonCollision* const collision = NewtonCreateConvexHull(world, mesh->m_vertexCount, mesh->m_vertex, 3 * sizeof (dFloat), 0, 0, NULL);
			void* const proxy = NewtonSceneCollisionAddSubCollision (sceneCollision, collision);
			NewtonDestroyCollision (collision);

			// get the location of this tire relative to the car chassis
			dMatrix matrix (entity->GetNextMatrix());

			NewtonCollision* const bridgeCollision = NewtonSceneCollisionGetCollisionFromNode (sceneCollision, proxy);
			NewtonSceneCollisionSetSubCollisionMatrix (sceneCollision, proxy, &matrix[0][0]);	
			NewtonCollisionSetUserData(bridgeCollision, entity);
		}
	}


	// add all the planks that form the bridge
	dTree<NewtonBody*, dString> planks;
	dFloat plankMass = 30.0f;
	for (DemoEntityManager::dListNode* node = bridgeNodes->GetNext(); node; node = node->GetNext()) {
		DemoEntity* const entity = node->GetInfo();
		if (entity->GetName().Find("plank") != -1) {	
			DemoMesh* const mesh = (DemoMesh*)entity->GetMesh();
			dAssert (mesh->IsType(DemoMesh::GetRttiType()));

			// note: because the mesh matrix can have scale, for simplicity just apply the local mesh matrix to the vertex cloud
			dVector pool[128];
			const dMatrix& meshMatrix = entity->GetMeshMatrix();
			meshMatrix.TransformTriplex(&pool[0].m_x, sizeof (dVector), mesh->m_vertex, 3 * sizeof (dFloat), mesh->m_vertexCount);

			NewtonCollision* const collision = NewtonCreateConvexHull(world, mesh->m_vertexCount, &pool[0].m_x, sizeof (dVector), 0, 0, NULL);
			NewtonBody* const body = CreateSimpleBody (world, entity, plankMass, entity->GetNextMatrix(), collision, 0);
			NewtonDestroyCollision (collision);
			planks.Insert(body, entity->GetName());
		}
	}

	// connect each plant with a hinge
	// calculate the with of a plank
	dFloat plankwidth = 0.0f;
	dVector planksideDir (1.0f, 0.0f, 0.0f, 0.0f);
	{
		NewtonBody* const body0 = planks.Find("plank01")->GetInfo();
		NewtonBody* const body1 = planks.Find("plank02")->GetInfo();

		dMatrix matrix0;
		dMatrix matrix1;
		NewtonBodyGetMatrix(body0, &matrix0[0][0]);
		NewtonBodyGetMatrix(body1, &matrix1[0][0]);

		planksideDir = matrix1.m_posit - matrix0.m_posit;
		planksideDir = planksideDir.Scale (1.0f / dSqrt (planksideDir % planksideDir));

		dVector dir (matrix0.UnrotateVector(planksideDir));
		NewtonCollision* const shape = NewtonBodyGetCollision(body0);

		dVector p0;
		dVector p1;
		NewtonCollisionSupportVertex(shape, &dir[0], &p0[0]);
		dVector dir1 (dir.Scale (-1.0f));
		NewtonCollisionSupportVertex(shape, &dir1[0], &p1[0]);
		plankwidth = dAbs (0.5f * ((p1 - p0) % dir));
	}


	dTree<NewtonBody*, dString>::Iterator iter (planks);
	iter.Begin();

	dMatrix matrix0;
	NewtonBody* body0 = iter.GetNode()->GetInfo();
	NewtonBodyGetMatrix(body0, &matrix0[0][0]);

	for (iter ++; iter; iter ++) {
		NewtonBody* const body1 = iter.GetNode()->GetInfo();
		
		dMatrix matrix1;
		NewtonBodyGetMatrix(body1, &matrix1[0][0]);

		// calculate the hinge parameter form the matrix location of each plank
		dMatrix pinMatrix0 (dGetIdentityMatrix());
		pinMatrix0[0] = pinMatrix0[1] * planksideDir;
		pinMatrix0[0] = pinMatrix0[0].Scale (1.0f / dSqrt (pinMatrix0[0] % pinMatrix0[0]));
		pinMatrix0[2] = pinMatrix0[0] * pinMatrix0[1];
		pinMatrix0[0][3] = 0.0f;
		pinMatrix0[1][3] = 0.0f;
		pinMatrix0[2][3] = 0.0f;

		// calculate the pivot
		pinMatrix0[3] = matrix0.m_posit + pinMatrix0[2].Scale (plankwidth);
		pinMatrix0[3][3] = 1.0f;

		dMatrix pinMatrix1 (pinMatrix0);
		pinMatrix1[3] = matrix1.m_posit - pinMatrix1[2].Scale (plankwidth);
		pinMatrix1[3][3] = 1.0f;

		// connect these two plank by a hinge, there a wiggle space between eh hinge that give therefore use the alternate hinge constructor
		new CustomHinge (pinMatrix0, pinMatrix1, body0, body1);

		body0 = body1;
		matrix0 = matrix1;
	}

	// connect the last and first plank to the bridge base
	{
		iter.Begin();
		body0 = iter.GetNode()->GetInfo();
		NewtonBodyGetMatrix(body0, &matrix0[0][0]);

		dMatrix pinMatrix0 (dGetIdentityMatrix());
		pinMatrix0[0] = pinMatrix0[1] * planksideDir;
		pinMatrix0[0] = pinMatrix0[0].Scale (1.0f / dSqrt (pinMatrix0[0] % pinMatrix0[0]));
		pinMatrix0[2] = pinMatrix0[0] * pinMatrix0[1];
		pinMatrix0[0][3] = 0.0f;
		pinMatrix0[1][3] = 0.0f;
		pinMatrix0[2][3] = 0.0f;
		pinMatrix0[3] = matrix0.m_posit - pinMatrix0[2].Scale (plankwidth);

		new CustomHinge (pinMatrix0, body0, playGroundBody);
	}

	{
		iter.End();
		body0 = iter.GetNode()->GetInfo();
		NewtonBodyGetMatrix(body0, &matrix0[0][0]);

		dMatrix pinMatrix0 (dGetIdentityMatrix());
		pinMatrix0[0] = pinMatrix0[1] * planksideDir;
		pinMatrix0[0] = pinMatrix0[0].Scale (1.0f / dSqrt (pinMatrix0[0] % pinMatrix0[0]));
		pinMatrix0[2] = pinMatrix0[0] * pinMatrix0[1];
		pinMatrix0[0][3] = 0.0f;
		pinMatrix0[1][3] = 0.0f;
		pinMatrix0[2][3] = 0.0f;
		pinMatrix0[3] = matrix0.m_posit + pinMatrix0[2].Scale (plankwidth);

		new CustomHinge (pinMatrix0, body0, playGroundBody);
	}
}