void RigidBodyData::Load(ILoad* const iload) { ULONG nwrit; int revision; dVector veloc; dVector omega; dMatrix matrix; RigidBodyWorldDesc& me = *(RigidBodyWorldDesc*) RigidBodyWorldDesc::GetDescriptor(); iload->Read((const char*)&revision, sizeof (revision), &nwrit); iload->Read((const char*)&m_oldControlerID, sizeof (m_oldControlerID), &nwrit); iload->Read((const char*)&m_collisionShape, sizeof (m_collisionShape), &nwrit); iload->Read((const char*)&m_hideGizmos, sizeof (m_hideGizmos), &nwrit); iload->Read((const char*)&m_mass, sizeof (m_mass), &nwrit); iload->Read((const char*)&m_inertia, sizeof (m_inertia), &nwrit); iload->Read((const char*)&m_origin, sizeof (m_origin), &nwrit); iload->Read((const char*)&matrix, sizeof (matrix), &nwrit); iload->Read((const char*)&veloc, sizeof (veloc), &nwrit); iload->Read((const char*)&omega, sizeof (omega), &nwrit); NewtonCollision* const collision = NewtonCreateCollisionFromSerialization (me.m_newton, LoadCollision, iload); CreateBody(collision, veloc, omega); NewtonBodySetMatrix(m_body, &matrix[0][0]); NewtonDestroyCollision(collision); }
//CollisionPtr CollisionSerializer::importCollision(Ogre::DataStreamPtr& stream, OgreNewt::World* world) CollisionPtr CollisionSerializer::importCollision(Ogre::DataStream& stream, OgreNewt::World* world) { CollisionPtr dest; NewtonCollision* col = NewtonCreateCollisionFromSerialization(world->getNewtonWorld(), &CollisionSerializer::_newtonDeserializeCallback, &stream); // the type doesn't really matter... but lets do it correctly switch( Collision::getCollisionPrimitiveType(col) ) { case BoxPrimitiveType: dest = CollisionPtr(new CollisionPrimitives::Box(world)); break; case ConePrimitiveType: dest = CollisionPtr(new CollisionPrimitives::Cone(world)); break; case EllipsoidPrimitiveType: dest = CollisionPtr(new CollisionPrimitives::Ellipsoid(world)); break; case CapsulePrimitiveType: dest = CollisionPtr(new CollisionPrimitives::Capsule(world)); break; case CylinderPrimitiveType: dest = CollisionPtr(new CollisionPrimitives::Cylinder(world)); break; case CompoundCollisionPrimitiveType: dest = CollisionPtr(new CollisionPrimitives::CompoundCollision(world)); break; case ConvexHullPrimitiveType: dest = CollisionPtr(new CollisionPrimitives::ConvexHull(world)); break; case ConvexHullModifierPrimitiveType: dest = CollisionPtr(new ConvexModifierCollision(world)); break; case ChamferCylinderPrimitiveType: dest = CollisionPtr(new CollisionPrimitives::ChamferCylinder(world)); break; case TreeCollisionPrimitiveType: dest = CollisionPtr(new CollisionPrimitives::TreeCollision(world)); break; case NullPrimitiveType: dest = CollisionPtr(new CollisionPrimitives::Null(world)); break; case HeighFieldPrimitiveType: case ScenePrimitiveType: default: dest = CollisionPtr(new Collision(world)); } dest->m_col = col; return dest; }
void CollisionDetection::addStaticTreeCollisionMesh( Entity *entity, string name) { bool meshCreated = false; NewtonCollision *treeCollision; std::stringstream out; out << name; string fileString = ConstManager::getString("cmesh_file_path"); fileString += out.str(); fileString.append(".cmesh"); cout << fileString<<endl; char *fileName = (char*) fileString.c_str(); if( !gernerateMeshes ) { FILE* meshFile; meshFile = fopen(fileName,"r"); if (meshFile!=NULL) { treeCollision = NewtonCreateCollisionFromSerialization (newtonWorld, myDeserializeCollisionCallbackFunction, meshFile); fclose (meshFile); meshCreated = true; } else { cout << "Colision detection could not read file.\nAttempting to create mesh from scratch" << endl; } } if( !meshCreated ) { treeCollision = NewtonCreateTreeCollision (newtonWorld, 0); NewtonTreeCollisionBeginBuild(treeCollision); size_t vertex_count; size_t index_count; Ogre::Vector3 *vertices; unsigned long *indices; GetMeshInformation( entity->getMesh(), vertex_count, vertices, index_count, indices, entity->getParentNode()->getPosition(), entity->getParentNode()->getOrientation(), entity->getParentNode()->_getDerivedScale()); /* Ogre::Vector3(), Ogre::Quaternion::IDENTITY, Ogre::Vector3(1,1,1)); */ dFloat vArray[9]; int i0, i1, i2; for (int i = 0; i < static_cast<int>(index_count); i += 3) { i0 = indices[i]; i1 = indices[i+1]; i2 = indices[i+2]; vArray[0] = vertices[i0].x; vArray[1] = vertices[i0].y; vArray[2] = vertices[i0].z; vArray[3] = vertices[i1].x; vArray[4] = vertices[i1].y; vArray[5] = vertices[i1].z; vArray[6] = vertices[i2].x; vArray[7] = vertices[i2].y; vArray[8] = vertices[i2].z; NewtonTreeCollisionAddFace(treeCollision, 3, vArray, sizeof(dFloat)*3, i); } NewtonTreeCollisionEndBuild(treeCollision, 1); FILE* meshFile; meshFile = fopen(fileName,"w"); if (meshFile!=NULL) { NewtonCollisionSerialize(newtonWorld, treeCollision, mySerializeCollisionCallbackFunction, meshFile); fclose (meshFile); } else { cout << "Colision detection could not write cmesh file." << endl; } } NewtonBody* rigidTree = NewtonCreateBody (newtonWorld, treeCollision); NewtonReleaseCollision (newtonWorld, treeCollision); NewtonBodySetMatrix (rigidTree, &idmatrix[0]); dFloat boxP0[3]; dFloat boxP1[3]; //possibly need this if we rely on newton //NewtonCollisionCalculateAABB (treeCollision, &idmatrix[0], &boxP0[0], &boxP1[0]); collisionsMap.insert(pair<Entity*,NewtonCollision*>(entity,treeCollision)); bodysMap.insert(pair<Entity*,NewtonBody*>(entity,rigidTree)); }
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; }
static void AddStructuredFractured (DemoEntityManager* const scene, const dVector& origin, int materialID, const char* const assetName) { // create the shape and visual mesh as a common data to be re used NewtonWorld* const world = scene->GetNewton(); #if 0 // load the mesh asset DemoEntity entity(GetIdentityMatrix(), NULL); entity.LoadNGD_mesh (assetName, world); DemoMesh____* const mesh = entity.GetMesh(); dAssert (mesh); // convert the mesh to a newtonMesh NewtonMesh* const solidMesh = mesh->CreateNewtonMesh (world, entity.GetMeshMatrix() * entity.GetCurrentMatrix()); #else int externalMaterial = LoadTexture("wood_0.tga"); NewtonCollision* const collision = CreateConvexCollision (world, dGetIdentityMatrix(), dVector (3.0f, 3.0f, 3.0f, 0.0), _BOX_PRIMITIVE, 0); NewtonMesh* const solidMesh = NewtonMeshCreateFromCollision(collision); NewtonDestroyCollision(collision); //NewtonMeshTriangulate(solidMesh); NewtonMeshApplyBoxMapping (solidMesh, externalMaterial, externalMaterial, externalMaterial); #endif // create a random point cloud dVector points[MAX_POINT_CLOUD_SIZE]; int pointCount = MakeRandomPoisonPointCloud (solidMesh, points); // int pointCount = MakeRandomGuassianPointCloud (solidMesh, points, MAX_POINT_CLOUD_SIZE); // create and interiors material for texturing the fractured pieces //int internalMaterial = LoadTexture("KAMEN-stup.tga"); int internalMaterial = LoadTexture("concreteBrick.tga"); // crate a texture matrix for uv mapping of fractured pieces dMatrix textureMatrix (dGetIdentityMatrix()); textureMatrix[0][0] = 1.0f / 2.0f; textureMatrix[1][1] = 1.0f / 2.0f; /// create the fractured collision and mesh int debreePhysMaterial = NewtonMaterialGetDefaultGroupID(world); NewtonCollision* structuredFracturedCollision = NewtonCreateFracturedCompoundCollision (world, solidMesh, 0, debreePhysMaterial, pointCount, &points[0][0], sizeof (dVector), internalMaterial, &textureMatrix[0][0], OnReconstructMainMeshCallBack, OnEmitFracturedCompound, OnEmitFracturedChunk); // uncomment this to test serialization #if 0 FILE* file = fopen ("serialize.bin", "wb"); NewtonCollisionSerialize (world, structuredFracturedCollision, DemoEntityManager::SerializeFile, file); NewtonDestroyCollision (structuredFracturedCollision); fclose (file); file = fopen ("serialize.bin", "rb"); structuredFracturedCollision = NewtonCreateCollisionFromSerialization (world, DemoEntityManager::DeserializeFile, file); NewtonFracturedCompoundSetCallbacks (structuredFracturedCollision, OnReconstructMainMeshCallBack, OnEmitFracturedCompound, OnEmitFracturedChunk); fclose (file); #endif #if 0 // test the interface dTree<void*, void*> detachableNodes; NewtonCompoundCollisionBeginAddRemove(structuredFracturedCollision); // remove all chunk that can be detached for the first layer for (void* node = NewtonCompoundCollisionGetFirstNode(structuredFracturedCollision); node; node = NewtonCompoundCollisionGetNextNode(structuredFracturedCollision, node)) { if (NewtonFracturedCompoundIsNodeFreeToDetach (structuredFracturedCollision, node)) { detachableNodes.Insert(node, node); } // remove any node that can be deched fro the secund layer, this codul; be reusive void* neighbors[32]; int count = NewtonFracturedCompoundNeighborNodeList (structuredFracturedCollision, node, neighbors, sizeof (neighbors) / sizeof (neighbors[0])); for (int i = 0; i < count; i ++ ) { if (NewtonFracturedCompoundIsNodeFreeToDetach (structuredFracturedCollision, neighbors[i])) { detachableNodes.Insert(node, node); } } } // now delete the actual nodes dTree<void*, void*>::Iterator iter (detachableNodes) ; for (iter.Begin(); iter; iter ++) { void* const node = iter.GetNode()->GetInfo(); NewtonCompoundCollisionRemoveSubCollision (structuredFracturedCollision, node); } NewtonCompoundCollisionEndAddRemove(structuredFracturedCollision); #endif #if 1 dVector plane (0.0f, 1.0f, 0.0f, 0.0f); NewtonCollision* const crack = NewtonFracturedCompoundPlaneClip (structuredFracturedCollision, &plane[0]); if (crack) { NewtonDestroyCollision (structuredFracturedCollision); } #endif dVector com(0.0f); dVector inertia(0.0f); NewtonConvexCollisionCalculateInertialMatrix (structuredFracturedCollision, &inertia[0], &com[0]); //dFloat mass = 10.0f; //int materialId = 0; //create the rigid body dMatrix matrix (dGetIdentityMatrix()); matrix.m_posit = origin; matrix.m_posit.m_y = 20.0; matrix.m_posit.m_w = 1.0f; NewtonBody* const rigidBody = NewtonCreateDynamicBody (world, structuredFracturedCollision, &matrix[0][0]); // set the mass and center of mass dFloat density = 1.0f; dFloat mass = density * NewtonConvexCollisionCalculateVolume (structuredFracturedCollision); NewtonBodySetMassProperties (rigidBody, mass, structuredFracturedCollision); // set the transform call back function NewtonBodySetTransformCallback (rigidBody, DemoEntity::TransformCallback); // set the force and torque call back function NewtonBodySetForceAndTorqueCallback (rigidBody, PhysicsApplyGravityForce); // create the entity and visual mesh and attach to the body as user data CreateVisualEntity (scene, rigidBody); // assign the wood id // NewtonBodySetMaterialGroupID (rigidBody, materialId); // set a destructor for this rigid body // NewtonBodySetDestructorCallback (rigidBody, PhysicsBodyDestructor); // release the interior texture // ReleaseTexture (internalMaterial); // delete the solid mesh since it no longed needed NewtonMeshDestroy (solidMesh); // destroy the fracture collision NewtonDestroyCollision (structuredFracturedCollision); }