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);
}
Beispiel #2
0
	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);
	}
	dInfinitePlane (NewtonWorld* const world, const dVector& plane)
		:m_minBox (-0.1f, -2000.0f, -2000.0f, 0.0f)
		,m_maxBox ( 0.1f,  2000.0f,  2000.0f, 0.0f)

	{
		// get the transformation matrix that takes the plane to the world local space
		m_rotation = dGrammSchmidt(plane);

		// build a unit grid in local space (this will be the shadow at projection of the collision aabb)
		m_unitSphape[0] = dVector (0.0f,  1.0f,  1.0f);
		m_unitSphape[1] = dVector (0.0f, -1.0f,  1.0f);
		m_unitSphape[2] = dVector (0.0f, -1.0f, -1.0f);
		m_unitSphape[3] = dVector (0.0f,  1.0f, -1.0f);

		// save the plane in local space
		m_plane = m_rotation.UntransformPlane (plane);

#ifdef PASS_A_QUAD
		// passing a single quad	
		for (int i = 0; i < MAX_THREAD_FACES; i ++) {
			m_faceIndices[i][0] = 4;
			// face attribute
			m_indexArray[i][4] = 0;
			// face normal
			m_indexArray[i][4 + 1] = 4;
			// face area (the plane is clipped around the box, the face size is always optimal)
			m_indexArray[i][4 + 2 + 4] = 0;

			for (int j = 0; j < 4; j ++) {
				// face vertex index
				m_indexArray[i][j] = j;
				// face adjacent index (infinite plane does not have shared edge with other faces)
				m_indexArray[i][j + 4 + 2] = 4;
			}
		}
#else
		// passing two triangle	
		for (int i = 0; i < MAX_THREAD_FACES; i ++) {
			// first triangle
			{
				// index count
				m_faceIndices[i][0] = 3;
				
				// face indices
				m_indexArray[i][0] = 0;
				m_indexArray[i][1] = 1;
				m_indexArray[i][2] = 2;

				// face attribute
				m_indexArray[i][3] = 0;

				// face normal
				m_indexArray[i][4] = 4;

				// face adjacent index (infinite plane does not have shared edge with other faces)
				m_indexArray[i][5] = 4;
				m_indexArray[i][6] = 4;
				m_indexArray[i][7] = 4;

				// face area (the plane is clipped around the box, the face size is always optimal)
				m_indexArray[i][8] = 0;
			}

			// second triangle
			{
				// index count
				m_faceIndices[i][1] = 3;
				
				// face indices
				m_indexArray[i][0 + 9] = 0;
				m_indexArray[i][1 + 9] = 2;
				m_indexArray[i][2 + 9] = 3;

				// face attribute
				m_indexArray[i][3 + 9] = 0;

				// face normal
				m_indexArray[i][4 + 9] = 4;

				// face adjacent index (infinite plane does not have shared edge with other faces)
				m_indexArray[i][5 + 9] = 4;
				m_indexArray[i][6 + 9] = 4;
				m_indexArray[i][7 + 9] = 4;

				// face area (the plane is clipped around the box, the face size is always optimal)
				m_indexArray[i][8 + 9] = 0;
			}
		}
#endif

		// create a Newton user collision 
		m_collision = NewtonCreateUserMeshCollision (world, &m_minBox[0], &m_maxBox[0], this, 
													 PlaneCollisionCollideCallback, PlaneMeshCollisionRayHitCallback, 
													 PlaneCollisionDestroyCallback, PlaneCollisionGetCollisionInfo, 
													 PlaneCollisionAABBOverlapTest, PlaneCollisionGetFacesInAABB, 
													 UserCollisionSerializationCallback, 0);

		// set a debug display call back
		NewtonStaticCollisionSetDebugCallback (m_collision, ShowMeshCollidingFaces);

		// set the collisoin offset Matrix;
		NewtonCollisionSetMatrix(m_collision, &m_rotation[0][0]);
		
	}
NewtonCollision* CreateConvexCollision (NewtonWorld* world, const dMatrix& srcMatrix, const dVector& originalSize, PrimitiveType type, int materialID__)
{
	dVector size (originalSize);

	NewtonCollision* collision = NULL;
	switch (type) 
	{
		case _NULL_PRIMITIVE:
		{
			collision = NewtonCreateNull (world); 
			break;
		}

		case _SPHERE_PRIMITIVE:
		{
			// create the collision 
			collision = NewtonCreateSphere (world, size.m_x * 0.5f, 0, NULL); 
			break;
		}

		case _BOX_PRIMITIVE:
		{
			// create the collision 
			collision = NewtonCreateBox (world, size.m_x, size.m_y, size.m_z, 0, NULL); 
			break;
		}


		case _CONE_PRIMITIVE:
		{
			dFloat r = size.m_x * 0.5f;
			dFloat h = size.m_y;

			// create the collision 
			collision = NewtonCreateCone (world, r, h, 0, NULL); 
			break;
		}

		case _CYLINDER_PRIMITIVE:
		{
			// create the collision 
			collision = NewtonCreateCylinder (world, size.m_x * 0.5f, size.m_y, 0, NULL); 
			break;
		}


		case _CAPSULE_PRIMITIVE:
		{
			// create the collision 
			collision = NewtonCreateCapsule (world, size.m_x * 0.5f, size.m_y, 0, NULL); 
			break;
		}

		case _TAPERED_CAPSULE_PRIMITIVE:
		{
			// create the collision 
			collision = NewtonCreateTaperedCapsule (world, size.m_x * 0.5f, size.m_z * 0.5f, size.m_y, 0, NULL); 
			break;
		}


		case _CHAMFER_CYLINDER_PRIMITIVE:
		{
			// create the collision 
			collision = NewtonCreateChamferCylinder (world, size.m_x * 0.5f, size.m_y, 0, NULL); 
			break;
		}

		case _TAPERED_CYLINDER_PRIMITIVE:
		{
			// create the collision 
			collision = NewtonCreateTaperedCylinder (world, size.m_x * 0.5f, size.m_z * 0.5f, size.m_y, 0, NULL); 
			break;
		}


		case _RANDOM_CONVEX_HULL_PRIMITIVE:
		{
			// Create a clouds of random point around the origin
			#define SAMPLE_COUNT 200
			dVector cloud [SAMPLE_COUNT];

			// make sure that at least the top and bottom are present
			cloud [0] = dVector ( size.m_x * 0.5f, 0.0f, 0.0f, 0.0f);
			cloud [1] = dVector (-size.m_x * 0.5f, 0.0f, 0.0f, 0.0f);
			cloud [2] = dVector ( 0.0f,  size.m_y * 0.5f, 0.0f, 0.0f); 
			cloud [3] = dVector ( 0.0f, -size.m_y * 0.5f, 0.0f, 0.0f);
			cloud [4] = dVector (0.0f, 0.0f,  size.m_z * 0.5f, 0.0f); 
			cloud [5] = dVector (0.0f, 0.0f, -size.m_z * 0.5f, 0.0f); 

			int count = 6;
			// populate the cloud with pseudo Gaussian random points
			for (int i = 6; i < SAMPLE_COUNT; i ++) {
				cloud [i].m_x = RandomVariable(size.m_x);
				cloud [i].m_y = RandomVariable(size.m_y);
				cloud [i].m_z = RandomVariable(size.m_z);
				count ++;
			}
			collision = NewtonCreateConvexHull (world, count, &cloud[0].m_x, sizeof (dVector), 0.01f, 0, NULL); 
			break;
		}

		case _REGULAR_CONVEX_HULL_PRIMITIVE:
		{
			// Create a clouds of random point around the origin
			#define STEPS_HULL 6
			//#define STEPS_HULL 3

			dVector cloud [STEPS_HULL * 4 + 256];
			int count = 0;
			dFloat radius = size.m_y;
			dFloat height = size.m_x * 0.999f;
			dFloat x = - height * 0.5f;
			dMatrix rotation (dPitchMatrix(2.0f * 3.141592f / STEPS_HULL));
			for (int i = 0; i < 4; i ++) {
				dFloat pad = ((i == 1) || (i == 2)) * 0.25f * radius;
				dVector p (x, 0.0f, radius + pad);
				x += 0.3333f * height;
				dMatrix acc (dGetIdentityMatrix());
				for (int j = 0; j < STEPS_HULL; j ++) {
					cloud[count] = acc.RotateVector(p);
					acc = acc * rotation;
					count ++;
				}
			}

			collision = NewtonCreateConvexHull (world, count, &cloud[0].m_x, sizeof (dVector), 0.02f, 0, NULL); 
			break;
		}

		case _COMPOUND_CONVEX_CRUZ_PRIMITIVE:
		{
			//dMatrix matrix (GetIdentityMatrix());
			dMatrix matrix (dPitchMatrix(15.0f * 3.1416f / 180.0f) * dYawMatrix(15.0f * 3.1416f / 180.0f) * dRollMatrix(15.0f * 3.1416f / 180.0f));
//			NewtonCollision* const collisionA = NewtonCreateBox (world, size.m_x, size.m_x * 0.25f, size.m_x * 0.25f, 0, &matrix[0][0]); 
//			NewtonCollision* const collisionB = NewtonCreateBox (world, size.m_x * 0.25f, size.m_x, size.m_x * 0.25f, 0, &matrix[0][0]); 
//			NewtonCollision* const collisionC = NewtonCreateBox (world, size.m_x * 0.25f, size.m_x * 0.25f, size.m_x, 0, &matrix[0][0]); 

matrix.m_posit = dVector (size.m_x * 0.5f, 0.0f, 0.0f, 1.0f);
NewtonCollision* const collisionA = NewtonCreateBox (world, size.m_x, size.m_x * 0.25f, size.m_x * 0.25f, 0, &matrix[0][0]); 
matrix.m_posit = dVector (0.0f, size.m_x * 0.5f, 0.0f, 1.0f);
NewtonCollision* const collisionB = NewtonCreateBox (world, size.m_x * 0.25f, size.m_x, size.m_x * 0.25f, 0, &matrix[0][0]); 
matrix.m_posit = dVector (0.0f, 0.0f, size.m_x * 0.5f, 1.0f);
NewtonCollision* const collisionC = NewtonCreateBox (world, size.m_x * 0.25f, size.m_x * 0.25f, size.m_x, 0, &matrix[0][0]); 


			collision = NewtonCreateCompoundCollision (world, 0);

			NewtonCompoundCollisionBeginAddRemove(collision);

			NewtonCompoundCollisionAddSubCollision (collision, collisionA);
			NewtonCompoundCollisionAddSubCollision (collision, collisionB);
			NewtonCompoundCollisionAddSubCollision (collision, collisionC);

			NewtonCompoundCollisionEndAddRemove(collision);	

			NewtonDestroyCollision(collisionA);
			NewtonDestroyCollision(collisionB);
			NewtonDestroyCollision(collisionC);
			break;
		}

		default: dAssert (0);
	}


	dMatrix matrix (srcMatrix);
	matrix.m_front = matrix.m_front.Scale (1.0f / dSqrt (matrix.m_front % matrix.m_front));
	matrix.m_right = matrix.m_front * matrix.m_up;
	matrix.m_right = matrix.m_right.Scale (1.0f / dSqrt (matrix.m_right % matrix.m_right));
	matrix.m_up = matrix.m_right * matrix.m_front;
	NewtonCollisionSetMatrix(collision, &matrix[0][0]);

	return collision;
}
    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);
    }
void dNewtonCollision::SetMatrix(const dMatrix matrix)
{
	NewtonCollisionSetMatrix(m_shape, &matrix[0][0]);
}