static void LoadFloor(DemoEntityManager* const scene, NewtonCollision* const sceneCollision)
{
	NewtonWorld* const world = scene->GetNewton();

	// add a flat plane
	dMatrix matrix (dGetIdentityMatrix());
	DemoEntityManager::dListNode* const floorNode = LoadScene(scene, "flatPlane.ngd", matrix);

	DemoEntity* const entity = floorNode->GetInfo();
	DemoMesh* const mesh = (DemoMesh*)entity->GetMesh();
	dAssert (mesh->IsType(DemoMesh::GetRttiType()));

	NewtonCollision* const tree = NewtonCreateTreeCollision(world, 0);
	NewtonTreeCollisionBeginBuild(tree);

	dFloat* const vertex = mesh->m_vertex;
	for (DemoMesh::dListNode* node = mesh->GetFirst(); node; node = node->GetNext()){
		DemoSubMesh* const subMesh = &node->GetInfo();
		unsigned int* const indices = subMesh->m_indexes;
		int trianglesCount = subMesh->m_indexCount;
		for (int i = 0; i < trianglesCount; i += 3) {

			dVector face[3];
			int index = indices[i + 0] * 3;
			face[0] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]);

			index = indices[i + 1] * 3;
			face[1] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]);

			index = indices[i + 2] * 3;
			face[2] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]);

			int matID = 0;
			//matID = matID == 2 ? 1 : 2 ;
			NewtonTreeCollisionAddFace(tree, 3, &face[0].m_x, sizeof (dVector), matID);
		}
	}
	NewtonTreeCollisionEndBuild (tree, 1);

	// add the collision tree to the collision scene
	void* const proxy = NewtonSceneCollisionAddSubCollision (sceneCollision, tree);

	// destroy the original tree collision
	NewtonDestroyCollision (tree);


	// set the parameter on the added collision share
	matrix = entity->GetCurrentMatrix();
	NewtonCollision* const collisionTree = NewtonSceneCollisionGetCollisionFromNode (sceneCollision, proxy);

	NewtonSceneCollisionSetSubCollisionMatrix (sceneCollision, proxy, &matrix[0][0]);	
	NewtonCollisionSetUserData(collisionTree, entity);

	// set the application level callback, for debug display
	#ifdef USE_STATIC_MESHES_DEBUG_COLLISION
	NewtonStaticCollisionSetDebugCallback (collisionTree, ShowMeshCollidingFaces);
	#endif
}
예제 #2
0
		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);
		}
예제 #3
0
NewtonCollision* CreateCollisionTree (NewtonWorld* world, DemoEntity* const entity, int materialID, bool optimize)
{
	// measure the time to build a collision tree
	unsigned64 timer0 = dGetTimeInMicrosenconds();

	// create the collision tree geometry
	NewtonCollision* collision = NewtonCreateTreeCollision(world, materialID);

	// set the application level callback
#ifdef USE_STATIC_MESHES_DEBUG_COLLISION
	NewtonStaticCollisionSetDebugCallback (collision, ShowMeshCollidingFaces);
#endif

	// prepare to create collision geometry
	NewtonTreeCollisionBeginBuild(collision);

	// iterate the entire geometry an build the collision
	for (DemoEntity* model = entity->GetFirst(); model; model = model->GetNext()) {

		dMatrix matrix (model->GetMeshMatrix() * model->CalculateGlobalMatrix(entity));
		DemoMesh* const mesh = (DemoMesh*)model->GetMesh();
		dAssert (mesh->IsType(DemoMesh::GetRttiType()));

		dFloat* const vertex = mesh->m_vertex;
		for (DemoMesh::dListNode* nodes = mesh->GetFirst(); nodes; nodes = nodes->GetNext()) {
			DemoSubMesh& segment = nodes->GetInfo();
			int matID = segment.m_textureHandle;
			for (int i = 0; i < segment.m_indexCount; i += 3) {
				int index;	
				dVector face[3];

				index = segment.m_indexes[i + 0] * 3;
				face[0] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]);

				index = segment.m_indexes[i + 1] * 3;
				face[1] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]);

				index = segment.m_indexes[i + 2] * 3;
				face[2] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]);

				matrix.TransformTriplex (&face[0].m_x, sizeof (dVector), &face[0].m_x, sizeof (dVector), 3);

				// use material ids as physics materials 
				NewtonTreeCollisionAddFace(collision, 3, &face[0].m_x, sizeof (dVector), matID);
			}
		}
	}
	NewtonTreeCollisionEndBuild(collision, optimize ? 1 : 0);


	// test Serialization
#if 0
	FILE* file = fopen ("serialize.bin", "wb");
	NewtonCollisionSerialize (world, collision, DemoEntityManager::SerializeFile, file);
	fclose (file);
	NewtonDestroyCollision (collision);

	file = fopen ("serialize.bin", "rb");
	collision = NewtonCreateCollisionFromSerialization (world, DemoEntityManager::DeserializeFile, file);
	fclose (file);
#endif	



	// measure the time to build a collision tree
	timer0 = (dGetTimeInMicrosenconds() - timer0) / 1000;

	return collision;
}
예제 #4
0
	void AddCollisionTreeMesh (DemoEntityManager* const scene)
	{
		// open the level data
		char fullPathName[2048];
		GetWorkingFileName ("playground.ngd", fullPathName);

		scene->LoadScene (fullPathName);

		// find the visual mesh and make a collision tree
		NewtonWorld* const world = scene->GetNewton();
		DemoEntity* const entity = scene->GetLast()->GetInfo();
		DemoMesh* const mesh = (DemoMesh*)entity->GetMesh();
		dAssert (mesh->IsType(DemoMesh::GetRttiType()));

		NewtonCollision* const tree = NewtonCreateTreeCollision(world, 0);
		NewtonTreeCollisionBeginBuild(tree);

		dFloat* const vertex = mesh->m_vertex;
		for (DemoMesh::dListNode* node = mesh->GetFirst(); node; node = node->GetNext()){
			DemoSubMesh* const subMesh = &node->GetInfo();
			unsigned int* const indices = subMesh->m_indexes;
			int trianglesCount = subMesh->m_indexCount;
			for (int i = 0; i < trianglesCount; i += 3) {

				dVector face[3];
				int index = indices[i + 0] * 3;
				face[0] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]);

				index = indices[i + 1] * 3;
				face[1] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]);

				index = indices[i + 2] * 3;
				face[2] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]);

				int matID = 0;
				//matID = matID == 2 ? 1 : 2 ;
				NewtonTreeCollisionAddFace(tree, 3, &face[0].m_x, sizeof (dVector), matID);
			}
		}
		NewtonTreeCollisionEndBuild (tree, 0);

		// add the collision tree to the collision scene
		void* const proxy = NewtonSceneCollisionAddSubCollision (m_sceneCollision, tree);

		// destroy the original tree collision
		NewtonDestroyCollision (tree);

		// set the parameter on the added collision share
		dMatrix matrix (entity->GetCurrentMatrix());
		NewtonCollision* const collisionTree = NewtonSceneCollisionGetCollisionFromNode (m_sceneCollision, proxy);

		NewtonSceneCollisionSetSubCollisionMatrix (m_sceneCollision, proxy, &matrix[0][0]);	
		NewtonCollisionSetUserData(collisionTree, mesh);

		// set the application level callback
#ifdef USE_STATIC_MESHES_DEBUG_COLLISION
		NewtonStaticCollisionSetDebugCallback (collisionTree, ShowMeshCollidingFaces);
#endif

		mesh->AddRef();

		scene->RemoveEntity (entity);

	#ifdef USE_TEST_ALL_FACE_USER_RAYCAST_CALLBACK
		// set a ray cast callback for all face ray cast 
		NewtonTreeCollisionSetUserRayCastCallback (collisionTree, AllRayHitCallback);
		dVector p0 (0,  100, 0, 0);
		dVector p1 (0, -100, 0, 0);
		dVector normal(0.0f);
		dLong id;
		dFloat parameter;
		parameter = NewtonCollisionRayCast (collisionTree, &p0[0], &p1[0], &normal[0], &id);
	#endif
	}