void LoadLumberYardMesh(DemoEntityManager* const scene, const dVector& location, int shapeid) { DemoEntity* const entity = DemoEntity::LoadNGD_mesh ("lumber.ngd", scene->GetNewton(), scene->GetShaderCache()); dTree<NewtonCollision*, DemoMesh*> filter; NewtonWorld* const world = scene->GetNewton(); dFloat density = 15.0f; int defaultMaterialID = NewtonMaterialGetDefaultGroupID(scene->GetNewton()); for (DemoEntity* child = entity->GetFirst(); child; child = child->GetNext()) { DemoMesh* const mesh = (DemoMesh*)child->GetMesh(); if (mesh) { dAssert(mesh->IsType(DemoMesh::GetRttiType())); dTree<NewtonCollision*, DemoMesh*>::dTreeNode* node = filter.Find(mesh); if (!node) { // make a collision shape only for and instance dFloat* const array = mesh->m_vertex; dVector minBox(1.0e10f, 1.0e10f, 1.0e10f, 1.0f); dVector maxBox(-1.0e10f, -1.0e10f, -1.0e10f, 1.0f); for (int i = 0; i < mesh->m_vertexCount; i++) { dVector p(array[i * 3 + 0], array[i * 3 + 1], array[i * 3 + 2], 1.0f); minBox.m_x = dMin(p.m_x, minBox.m_x); minBox.m_y = dMin(p.m_y, minBox.m_y); minBox.m_z = dMin(p.m_z, minBox.m_z); maxBox.m_x = dMax(p.m_x, maxBox.m_x); maxBox.m_y = dMax(p.m_y, maxBox.m_y); maxBox.m_z = dMax(p.m_z, maxBox.m_z); } dVector size(maxBox - minBox); dMatrix offset(dGetIdentityMatrix()); offset.m_posit = (maxBox + minBox).Scale(0.5f); NewtonCollision* const shape = NewtonCreateBox(world, size.m_x, size.m_y, size.m_z, shapeid, &offset[0][0]); node = filter.Insert(shape, mesh); } // create a body and add to the world NewtonCollision* const shape = node->GetInfo(); dMatrix matrix(child->GetMeshMatrix() * child->CalculateGlobalMatrix()); matrix.m_posit += location; dFloat mass = density * NewtonConvexCollisionCalculateVolume(shape); CreateSimpleSolid(scene, mesh, mass, matrix, shape, defaultMaterialID); } } // destroy all shapes while (filter.GetRoot()) { NewtonCollision* const shape = filter.GetRoot()->GetInfo(); NewtonDestroyCollision(shape); filter.Remove(filter.GetRoot()); } delete entity; }
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; }