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 }
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); }
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; }
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 }