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);
}
	void RayCastCompoundsAllSubShapes(const dVector& origin, const dVector& end)
	{
		m_param = 1.0f;
		m_body = NULL;
		NewtonWorld* const world = GetWorld();
		NewtonWorldRayCast(world, &origin[0], &end[0], PickCompound, this, NULL, 0);
		if (m_body) {
			// we found a compound, find all sub shape on teh path of the ray
			dMatrix matrix;
			NewtonBodyGetMatrix(m_body, &matrix[0][0]);
			dVector localP0(matrix.UntransformVector(origin));
			dVector localP1(matrix.UntransformVector(end));

			NewtonCollision* const compoundCollision = NewtonBodyGetCollision(m_body);
			dAssert(NewtonCollisionGetType(compoundCollision) == SERIALIZE_ID_COMPOUND);
			for (void* node = NewtonCompoundCollisionGetFirstNode(compoundCollision); node; node = NewtonCompoundCollisionGetNextNode(compoundCollision, node)) {
				dVector normal;
				dLong attribute;
				NewtonCollision* const subShape = NewtonCompoundCollisionGetCollisionFromNode(compoundCollision, node);
				dFloat xxx = NewtonCollisionRayCast(subShape, &localP0[0], &localP1[0], &normal[0], &attribute);
				if (xxx < 1.0f) {
					dTrace (("sub shape hit\n"))
				}
			}
		}
	}
static void OnReconstructMainMeshCallBack (NewtonBody* const body, NewtonFracturedCompoundMeshPart* const mainMesh, const NewtonCollision* const fracturedCompoundCollision)
{
	DemoEntity* const entity = (DemoEntity*)NewtonBodyGetUserData(body);
	DemoMesh* const visualMesh = (DemoMesh*)entity->GetMesh();
	dAssert (visualMesh->IsType(DemoMesh::GetRttiType()));
	
	dAssert (NewtonCollisionGetType(fracturedCompoundCollision) == SERIALIZE_ID_FRACTURED_COMPOUND);

	DemoEntityManager* const scene = (DemoEntityManager*)NewtonWorldGetUserData(NewtonBodyGetWorld(body));
	dAssert (scene);

	visualMesh->RemoveAll();
	for (void* segment = NewtonFracturedCompoundMeshPartGetFirstSegment(mainMesh); segment; segment = NewtonFracturedCompoundMeshPartGetNextSegment (segment)) {
		DemoSubMesh* const subMesh = visualMesh->AddSubMesh();

		int material = NewtonFracturedCompoundMeshPartGetMaterial (segment); 
		int indexCount = NewtonFracturedCompoundMeshPartGetIndexCount (segment); 

		subMesh->m_textureHandle = AddTextureRef ((GLuint)material);
		subMesh->m_shader = scene->GetShaderCache().m_diffuseEffect;

		subMesh->AllocIndexData (indexCount);
		subMesh->m_indexCount = NewtonFracturedCompoundMeshPartGetIndexStream (fracturedCompoundCollision, mainMesh, segment, (int*)subMesh->m_indexes); 
	}

	visualMesh->OptimizeForRender();
}
	static dFloat PickCompound(const NewtonBody* const body, const NewtonCollision* const shapeHit, const dFloat* const hitContact, const dFloat* const hitNormal, dLong collisionID, void* const userData, dFloat intersectParam)
	{
		NewtonCollision* const collision = NewtonBodyGetCollision(body);
		if (NewtonCollisionGetType(collision) == SERIALIZE_ID_COMPOUND) {
			dShowAllSubShapes* const me = (dShowAllSubShapes*)userData;
			if (intersectParam < me->m_param) {
				me->m_param = intersectParam;
				me->m_body = body;
				return intersectParam;
			}
		}
		return 1.2f;
	}
void DebugRenderWorldCollision (const NewtonWorld* const world, DEBUG_DRAW_MODE mode)
{
	glDisable(GL_TEXTURE_2D);
	if (mode == m_lines) {
		glDisable (GL_LIGHTING);
		glBegin(GL_LINES);
	} else {
		glBegin(GL_TRIANGLES);
	}
	for (NewtonBody* body = NewtonWorldGetFirstBody(world); body; body = NewtonWorldGetNextBody(world, body)) {
		NewtonCollision* const collision = NewtonBodyGetCollision(body);
		int collisionType = NewtonCollisionGetType (collision);
		switch (collisionType) 
		{
			//SERIALIZE_ID_SPHERE:
			//SERIALIZE_ID_CAPSULE:
			//SERIALIZE_ID_CHAMFERCYLINDER:
			//SERIALIZE_ID_TAPEREDCAPSULE:
			//SERIALIZE_ID_CYLINDER:
			//SERIALIZE_ID_TAPEREDCYLINDER:
			//SERIALIZE_ID_BOX:
			//SERIALIZE_ID_CONE:
			//SERIALIZE_ID_CONVEXHULL:
			//SERIALIZE_ID_NULL:
			//SERIALIZE_ID_COMPOUND:
			//SERIALIZE_ID_CLOTH_PATCH:
			//SERIALIZE_ID_DEFORMABLE_SOLID:
//			case SERIALIZE_ID_TREE:
//			case SERIALIZE_ID_SCENE:
//			case SERIALIZE_ID_USERMESH:
			case SERIALIZE_ID_HEIGHTFIELD:
//			case SERIALIZE_ID_COMPOUND_BREAKABLE:
				break;
			default: 
				DebugShowBodyCollision (body, mode);
		}
	}
	glEnd();

	glDisable (GL_LIGHTING);
	glBegin(GL_LINES);
	glColor3f(1.0f, 1.0f, 0.0f);
	for (int i = 0; i < g_debugDisplayCount; i += 2) {
		glVertex3f (g_debugDisplayCallback[i].m_x, g_debugDisplayCallback[i].m_y, g_debugDisplayCallback[i].m_z);
		glVertex3f (g_debugDisplayCallback[i+1].m_x, g_debugDisplayCallback[i+1].m_y, g_debugDisplayCallback[i+1].m_z);
	}
	glEnd();
}
		void Render(DemoEntityManager* const scene)
		{
			NewtonCollision* const deformableCollision = NewtonBodyGetCollision(m_body);
			dAssert((NewtonCollisionGetType(deformableCollision) == SERIALIZE_ID_CLOTH_PATCH) || (NewtonCollisionGetType(deformableCollision) == SERIALIZE_ID_DEFORMABLE_SOLID));

			const dFloat* const particles = NewtonDeformableMeshGetParticleArray(deformableCollision);
			int stride = NewtonDeformableMeshGetParticleStrideInBytes(deformableCollision) / sizeof (dFloat);

			// calculate vertex skinning
			for (int i = 0; i < m_vertexCount; i++) {
				int index = m_indexMap[i] * stride;
				m_vertex[i * 3 + 0] = particles[index + 0];
				m_vertex[i * 3 + 1] = particles[index + 1];
				m_vertex[i * 3 + 2] = particles[index + 2];
			}

			DemoMesh::Render(scene);
		}
void DemoEntityManager::BodyDeserialization (NewtonBody* const body, void* const bodyUserData, NewtonDeserializeCallback deserializecallback, void* const serializeHandle)
{
	int size;
	char bodyIndentification[256];
	
	deserializecallback (serializeHandle, &size, sizeof (size));
	deserializecallback (serializeHandle, bodyIndentification, size);

	// get the world and the scene form the world user data
	NewtonWorld* const world = NewtonBodyGetWorld(body);
	DemoEntityManager* const scene = (DemoEntityManager*)NewtonWorldGetUserData(world);

	// here we attach a visual object to the entity, 
	dMatrix matrix;
	NewtonBodyGetMatrix(body, &matrix[0][0]);
	DemoEntity* const entity = new DemoEntity(matrix, NULL);
	scene->Append (entity);

	NewtonBodySetUserData (body, entity);
	NewtonBodySetTransformCallback(body, DemoEntity::TransformCallback);
	NewtonBodySetForceAndTorqueCallback(body, PhysicsApplyGravityForce);
	NewtonCollision* const collision = NewtonBodyGetCollision(body);

	#ifdef USE_STATIC_MESHES_DEBUG_COLLISION
		if (NewtonCollisionGetType(collision) == SERIALIZE_ID_TREE) {
			NewtonStaticCollisionSetDebugCallback (collision, ShowMeshCollidingFaces);
		}
	#endif

	//for visual mesh we will collision mesh and convert it to a visual mesh using NewtonMesh 
	dTree <DemoMeshInterface*, const void*>* const cache = (dTree <DemoMeshInterface*, const void*>*)bodyUserData;
	dTree <DemoMeshInterface*, const void*>::dTreeNode* node = cache->Find(NewtonCollisionDataPointer (collision));
	if (!node) {
		DemoMeshInterface* mesh = new DemoMesh(bodyIndentification, collision, NULL, NULL, NULL);
		node = cache->Insert(mesh, NewtonCollisionDataPointer (collision));
	} else {
		node->GetInfo()->AddRef();
	}
	
	DemoMeshInterface* const mesh = node->GetInfo();
	entity->SetMesh(mesh, dGetIdentityMatrix());
	mesh->Release();
}
static void OnEmitFracturedCompound (NewtonBody* const fracturedCompound)
{
	NewtonWorld* const world = NewtonBodyGetWorld(fracturedCompound);
	DemoEntityManager* const scene = (DemoEntityManager*)NewtonWorldGetUserData(world);

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

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

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

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

	NewtonBodySetUserData (fracturedCompound, visualChunkEntity);

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

	// get the fractured compound mesh from the body
	NewtonCollision* const fracturedCompoundCollision = NewtonBodyGetCollision(fracturedCompound);
	dAssert (NewtonCollisionGetType(fracturedCompoundCollision) == SERIALIZE_ID_FRACTURED_COMPOUND);

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

	// add the mesh indices
	OnReconstructMainMeshCallBack (fracturedCompound, mainMesh, fracturedCompoundCollision);
}
		void Render(DemoEntityManager* const scene)
		{
			NewtonCollision* const deformableCollision = NewtonBodyGetCollision(m_body);
			dAssert((NewtonCollisionGetType(deformableCollision) == SERIALIZE_ID_CLOTH_PATCH) || (NewtonCollisionGetType(deformableCollision) == SERIALIZE_ID_DEFORMABLE_SOLID));

			const dFloat* const particles = NewtonDeformableMeshGetParticleArray(deformableCollision);
			int stride = NewtonDeformableMeshGetParticleStrideInBytes(deformableCollision) / sizeof (dFloat);

			// calculate vertex skinning
			for (int i = 0; i < m_vertexCount; i++) {
				int index = m_indexMap[i] * stride;
				m_vertex[i * 3 + 0] = particles[index + 0];
				m_vertex[i * 3 + 1] = particles[index + 1];
				m_vertex[i * 3 + 2] = particles[index + 2];

				// clear the normal for next loop
				m_normal[i * 3 + 0] = 0.0f;
				m_normal[i * 3 + 1] = 0.0f;
				m_normal[i * 3 + 2] = 0.0f;
			}

			// calculate vertex normals 
			int normalStride = 3;
			for (DemoMesh::dListNode* segmentNode = GetFirst(); segmentNode; segmentNode = segmentNode->GetNext()) {
				const DemoSubMesh& subSegment = segmentNode->GetInfo();
				for (int i = 0; i < subSegment.m_indexCount; i += 3) {
					int i0 = subSegment.m_indexes[i + 0] * normalStride;
					int i1 = subSegment.m_indexes[i + 1] * normalStride;
					int i2 = subSegment.m_indexes[i + 2] * normalStride;
					dVector p0(m_vertex[i0], m_vertex[i0 + 1], m_vertex[i0 + 2], 0.0f);
					dVector p1(m_vertex[i1], m_vertex[i1 + 1], m_vertex[i1 + 2], 0.0f);
					dVector p2(m_vertex[i2], m_vertex[i2 + 1], m_vertex[i2 + 2], 0.0f);
					dVector p10(p1 - p0);
					dVector p20(p2 - p0);
					dVector normal(p10.CrossProduct(p20));
					normal = normal.Scale(1.0f / dSqrt(normal.DotProduct3(normal)));

					m_normal[i0 + 0] += normal.m_x;
					m_normal[i0 + 1] += normal.m_y;
					m_normal[i0 + 2] += normal.m_z;

					m_normal[i1 + 0] += normal.m_x;
					m_normal[i1 + 1] += normal.m_y;
					m_normal[i1 + 2] += normal.m_z;

					m_normal[i2 + 0] += normal.m_x;
					m_normal[i2 + 1] += normal.m_y;
					m_normal[i2 + 2] += normal.m_z;
				}
			}

			// normalize all the normals
			for (int i = 0; i < m_vertexCount; i++) {
				dVector n(m_normal[i * 3 + 0], m_normal[i * 3 + 1], m_normal[i * 3 + 2], 0.0f);
				n = n.Scale(1.0f / dSqrt(n.DotProduct3(n)));
				m_normal[i * 3 + 0] = n.m_x;
				m_normal[i * 3 + 1] = n.m_y;
				m_normal[i * 3 + 2] = n.m_z;
			}

			glDisable(GL_CULL_FACE);
			DemoMesh::Render(scene);
			glEnable(GL_CULL_FACE);
		}
Exemple #10
0
void CustomVehicleController::Init (NewtonCollision* const chassisShape, const dMatrix& vehicleFrame, dFloat mass, const dVector& gravityVector)
{
	m_finalized = false;
	m_externalContactStatesCount = 0;
	m_sleepCounter = VEHICLE_SLEEP_COUNTER;
	m_freeContactList = m_externalContactStatesPoll.GetFirst();
	CustomVehicleControllerManager* const manager = (CustomVehicleControllerManager*) GetManager(); 
	NewtonWorld* const world = manager->GetWorld(); 

	// create a compound collision 	
	NewtonCollision* const vehShape = NewtonCreateCompoundCollision(world, 0);
	NewtonCompoundCollisionBeginAddRemove(vehShape);

	// if the shape is a compound collision ass all the pieces one at a time
	int shapeType = NewtonCollisionGetType (chassisShape);
	if (shapeType == SERIALIZE_ID_COMPOUND) {
		for (void* node = NewtonCompoundCollisionGetFirstNode(chassisShape); node; node = NewtonCompoundCollisionGetNextNode (chassisShape, node)) { 
			NewtonCollision* const subCollision = NewtonCompoundCollisionGetCollisionFromNode(chassisShape, node);
			NewtonCompoundCollisionAddSubCollision (vehShape, subCollision);
		}
	} else {
		dAssert ((shapeType == SERIALIZE_ID_CONVEXHULL) || (shapeType == SERIALIZE_ID_BOX));
		NewtonCompoundCollisionAddSubCollision (vehShape, chassisShape);
	}
	NewtonCompoundCollisionEndAddRemove (vehShape);	

	// create the rigid body for this vehicle
	dMatrix locationMatrix (dGetIdentityMatrix());
	m_body = NewtonCreateDynamicBody(world, vehShape, &locationMatrix[0][0]);

	// set vehicle mass, inertia and center of mass
	NewtonBodySetMassProperties (m_body, mass, vehShape);

	// set linear and angular drag to zero
	dVector drag(0.0f, 0.0f, 0.0f, 0.0f);
	NewtonBodySetLinearDamping(m_body, 0);
	NewtonBodySetAngularDamping(m_body, &drag[0]);

	// destroy the collision help shape
	NewtonDestroyCollision (vehShape);

	// initialize vehicle internal components
	NewtonBodyGetCentreOfMass (m_body, &m_chassisState.m_com[0]);
	m_chassisState.m_comOffset = dVector (0.0f, 0.0f, 0.0f, 0.0f);

	m_chassisState.m_gravity = gravityVector;
	m_chassisState.m_gravityMag = dSqrt (gravityVector % gravityVector);
	m_chassisState.Init(this, vehicleFrame);

//	m_stateList.Append(&m_staticWorld);
	m_stateList.Append(&m_chassisState);

	// create the normalized size tire shape
	m_tireCastShape = NewtonCreateChamferCylinder(world, 0.5f, 1.0f, 0, NULL);

	// initialize all components to empty
	m_engine = NULL;
	m_brakes = NULL;
	m_steering = NULL;
	m_handBrakes = NULL;

	SetDryRollingFrictionTorque (100.0f/4.0f);
	SetAerodynamicsDownforceCoefficient (0.5f * dSqrt (gravityVector % gravityVector), 60.0f * 0.447f);
}
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);
}