// // EPhysXPhysEngine::BuildConvexMesh // NxConvexMesh *ESciVis::BuildConvexMesh( const IPxTriMesh input_mesh ) { //IPxTriMesh mesh = input_mesh->Clone(); //mesh->SetFormat( GE_MESH_POSITION ); //mesh->MergeVertices(); //This command causes convex cook crash NxConvexMeshDesc convex_mesh_desc; NxArray<NxVec3> verts; for (uint i=0; i<input_mesh->GetVertexNum(); i++) { EVertex v; v = input_mesh->GetVertex(i); verts.push_back( NxVec3(v.position.x, v.position.y, v.position.z) ); } convex_mesh_desc.numVertices = input_mesh->GetVertexNum(); convex_mesh_desc.pointStrideBytes = sizeof(NxVec3); convex_mesh_desc.points = &verts[0]; convex_mesh_desc.flags = NX_CF_COMPUTE_CONVEX; ASSERT( convex_mesh_desc.isValid() ); MemoryWriteBuffer buf; bool r = nx_cook->NxCookConvexMesh(convex_mesh_desc, buf); if (!r) { RUNTIME_ERROR("mesh contains to many vertices"); } return nx->createConvexMesh(MemoryReadBuffer(buf.data)); }
Menge::GeometryInterface * NovodexPhysicSystem::cookConcave( const float * _verts, int _vertexSize, const int * _indecies, int _indexSize ) { NxTriangleMeshDesc triMeshDesc; triMeshDesc.numVertices = _vertexSize; triMeshDesc.pointStrideBytes = 3 * sizeof(float); triMeshDesc.points = _verts; triMeshDesc.numTriangles = _indexSize; triMeshDesc.triangles = _indecies; triMeshDesc.triangleStrideBytes = 3 * sizeof(int); triMeshDesc.flags = 0; NxTriangleMeshShapeDesc * nxTriShape = new NxTriangleMeshShapeDesc(); NxInitCooking(); MemoryWriteBuffer buf; //bool status = NxCookTriangleMesh(triMeshDesc, UserStream("c:\\cooked.bin", false)); bool status = NxCookTriangleMesh(triMeshDesc, buf); assert(status); nxTriShape->meshData = m_physicsSDK->createTriangleMesh(MemoryReadBuffer(buf.data)); nxTriShape->group = GROUP_COLLIDABLE_NON_PUSHABLE; NovodexGeometry * novodexGeometry = new NovodexGeometry(nxTriShape); return novodexGeometry; }
Menge::GeometryInterface * NovodexPhysicSystem::cookConvex( const float * _verts, int _vertexSize, const int * _indecies, int _indexSize ) { NxConvexMeshDesc m_convexMesh; m_convexMesh.numVertices = _vertexSize; m_convexMesh.pointStrideBytes = 3 * sizeof(float); m_convexMesh.points = _verts; m_convexMesh.numTriangles = _indexSize; m_convexMesh.triangles = _indecies; m_convexMesh.triangleStrideBytes = 3 * sizeof(int); m_convexMesh.flags = 0; NxConvexShapeDesc * nxConvexShape = new NxConvexShapeDesc(); NxInitCooking(); MemoryWriteBuffer buf; bool status = NxCookConvexMesh(m_convexMesh, buf); assert(status); nxConvexShape->meshData = m_physicsSDK->createConvexMesh(MemoryReadBuffer(buf.data)); nxConvexShape->group = GROUP_COLLIDABLE_PUSHABLE; NovodexGeometry * novodexGeometry = new NovodexGeometry(nxConvexShape); return novodexGeometry; }
PxConvexMesh* CreateConvexMesh(const PxVec3* verts, const PxU32 numVerts) { PxPhysics& physics = *g_pPhysicsWorld->PhysXSDK; PxCooking& cooking = *g_pPhysicsWorld->Cooking; // Create descriptor for convex mesh PxConvexMeshDesc convexDesc; convexDesc.points.count = numVerts; convexDesc.points.stride = sizeof(PxVec3); convexDesc.points.data = verts; convexDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX | PxConvexFlag::eINFLATE_CONVEX; PxConvexMesh* convexMesh = NULL; MemoryWriteBuffer buf; if(cooking.cookConvexMesh(convexDesc, buf)) { convexMesh = physics.createConvexMesh(MemoryReadBuffer(buf.data)); } return convexMesh; }
// 增加一辆车 NxVehicle* NxAllVehicle::addVehicle(const NxVec3& pos, VehicleInfo vinfo, std::string name, NxScene* nxScene, NxPhysicsSDK* nxPhysics) { NxVehicleDesc vehicleDesc; NxBoxShapeDesc boxShapes[2]; NxConvexShapeDesc carShape[2]; NxArray<NxVec3> points; NxArray<NxVec3> points2; NxReal halfWidth = vinfo.width / 2;//1.1529f; NxReal halfLength = vinfo.length / 2;//2.5278f; NxReal halfHeight = vinfo.height / 2; //0.6027; points.pushBack().set(halfLength,-halfHeight * 0.1f, 0); points.pushBack().set(halfLength * 0.7f, 0, 0); points.pushBack().set(0.2f * halfLength, halfHeight * 0.2f, 0); points.pushBack().set(-halfLength, halfHeight * 0.2f, 0); points.pushBack().set(0.1*halfLength, halfHeight * 0.2f, halfWidth * 0.9f); points.pushBack().set(0.1*halfLength, halfHeight * 0.2f,-halfWidth * 0.9f); points.pushBack().set(-0.8*halfLength, halfHeight * 0.2f, halfWidth * 0.9f); points.pushBack().set(-0.8*halfLength, halfHeight * 0.2f,-halfWidth * 0.9f); points.pushBack().set(halfLength * 0.9f,-halfHeight * 0.25f, halfWidth * 0.8f); points.pushBack().set(halfLength * 0.9f,-halfHeight * 0.25f,-halfWidth * 0.8f); points.pushBack().set(0,-halfHeight * 0.2f, halfWidth); points.pushBack().set(0,-halfHeight * 0.2f,-halfWidth); points.pushBack().set(-halfLength * 0.9f,-halfHeight * 0.2f, halfWidth * 0.9f); points.pushBack().set(-halfLength * 0.9f,-halfHeight * 0.2f,-halfWidth * 0.9f); points.pushBack().set(halfLength * 0.8f, -halfHeight, halfWidth * 0.79f); points.pushBack().set(halfLength * 0.8f, -halfHeight,-halfWidth * 0.79f); points.pushBack().set(-halfLength * 0.8f, -halfHeight, halfWidth * 0.79f); points.pushBack().set(-halfLength * 0.8f, -halfHeight,-halfWidth * 0.79f); for(NxU32 i = 2; i < 8; i++) { points2.pushBack(points[i]); } points2.pushBack().set(-0.5*halfLength, halfHeight*0.8f, halfWidth*0.7f); points2.pushBack().set(-0.5*halfLength, halfHeight*0.8f,-halfWidth*0.7f); points2.pushBack().set(-0.7*halfLength, halfHeight*0.7f, halfWidth*0.7f); points2.pushBack().set(-0.7*halfLength, halfHeight*0.7f,-halfWidth*0.7f); static NxConvexMeshDesc convexMesh; convexMesh.numVertices = points.size(); convexMesh.points = &(points[0].x); convexMesh.pointStrideBytes = sizeof(NxVec3); convexMesh.flags |= NX_CF_COMPUTE_CONVEX|NX_CF_USE_LEGACY_COOKER; MemoryWriteBuffer buf; bool status = NxCookConvexMesh(convexMesh, buf); if(status) { carShape[0].meshData = nxPhysics->createConvexMesh(MemoryReadBuffer(buf.data)); vehicleDesc.carShapes.pushBack(&carShape[0]); } static NxConvexMeshDesc convexMesh2; convexMesh2.numVertices = points2.size(); convexMesh2.points = (&points2[0].x); convexMesh2.pointStrideBytes = sizeof(NxVec3); convexMesh2.flags = NX_CF_COMPUTE_CONVEX|NX_CF_USE_LEGACY_COOKER; MemoryWriteBuffer buf2; status = NxCookConvexMesh(convexMesh2, buf2); if(status) { carShape[1].meshData = nxPhysics->createConvexMesh(MemoryReadBuffer(buf2.data)); vehicleDesc.carShapes.pushBack(&carShape[1]); } vehicleDesc.position = pos; vehicleDesc.mass = vinfo.mass;//1200;//monsterTruck ? 12000 : vehicleDesc.digitalSteeringDelta = vinfo.steerablity;//0.04f; vehicleDesc.steeringMaxAngle = vinfo.maxSteeringAngle; //30.f; vehicleDesc.motorForce = vinfo.maxAcceleraion * vinfo.mass;//3500.f;//monsterTruck?180.f: NxVehicleMotorDesc motorDesc; NxVehicleGearDesc gearDesc; NxReal wheelRadius = 0.4f; vehicleDesc.maxVelocity = vinfo.maxVelocity; //80.f;//(monsterTruck)?40.f:80.f; motorDesc.setToCorvette(); vehicleDesc.motorDesc = &motorDesc; gearDesc.setToCorvette(); vehicleDesc.gearDesc = &gearDesc; vehicleDesc.differentialRatio = 3.42f; wheelRadius = 0.3622f; vehicleDesc.centerOfMass.set(0,-0.7f,0); NxWheelDesc wheelDesc[4]; for(NxU32 i=0;i<4;i++) { wheelDesc[i].wheelApproximation = 10; //wheelDesc[i].wheelFlags |= NX_WF_BUILD_LOWER_HALF; wheelDesc[i].wheelRadius = wheelRadius;//(monsterTruck)?wheelRadius*3.f:wheelRadius; wheelDesc[i].wheelWidth = 0.1923f;//(monsterTruck)?0.3f:0.1923f; wheelDesc[i].wheelSuspension = 0.2f;//(monsterTruck)?0.6f:0.2f; wheelDesc[i].springRestitution = 7000;//monsterTruck?(crovette?5000:4000):7000; wheelDesc[i].springDamping = 800; wheelDesc[i].springBias = 0.0f; // 设为1.0后居然会出错!!!!!!!! //wheelDesc[i].maxHandBraking = 1.f; //monsterTruck?0.5f:1.f; wheelDesc[i].inverseWheelMass = 4.0f / vinfo.maxAcceleraion; // 换算成动力 wheelDesc[i].frictionToFront = 1.f; wheelDesc[i].frictionToSide = 2.f; vehicleDesc.carWheels.pushBack(&wheelDesc[i]); } NxReal heightPos = -0.3622f; //(monsterTruck)?1.f: wheelDesc[0].position.set( 1.02f, heightPos, 1.26); wheelDesc[1].position.set( 1.12f, heightPos,-1.54); wheelDesc[2].position.set(-1.02f, heightPos, 1.26); wheelDesc[3].position.set(-1.12f, heightPos,-1.54); NxU32 flags = NX_WF_BUILD_LOWER_HALF; wheelDesc[0].wheelFlags |= ((vinfo.driven==FrontDriven)?NX_WF_ACCELERATED:0) | NX_WF_STEERABLE_INPUT | flags; wheelDesc[1].wheelFlags |= ((vinfo.driven==FrontDriven)?NX_WF_ACCELERATED:0) | NX_WF_STEERABLE_INPUT | flags; wheelDesc[2].wheelFlags |= ((vinfo.driven==BackDriven)?NX_WF_ACCELERATED:0) | NX_WF_AFFECTED_BY_HANDBRAKE | flags; wheelDesc[3].wheelFlags |= ((vinfo.driven==BackDriven)?NX_WF_ACCELERATED:0) | NX_WF_AFFECTED_BY_HANDBRAKE | flags; vehicleDesc.steeringSteerPoint.set(1.8, 0, 0); vehicleDesc.steeringTurnPoint.set(-1.5, 0, 0); NxVehicle* vehicle = NxVehicle::createVehicle(nxScene, &vehicleDesc, name); NxQuat q; // 少转过90度,可能会有问题 q.fromAngleAxis(90.0f, NxVec3(0.0f, 1.0f, 0.0f)); vehicle->getActor()->setGlobalOrientationQuat(q); vehicle->mVInfo = vinfo; vehicle->setOilAmount(vinfo.oilAmount); // 加到队列中 mAllVehicle.pushBack(vehicle); mIsLive.pushBack(0); // miUserVehicle = mAllVehicle.size() - 1; return vehicle; }
void PhysCreateStaticRigidBodyMesh ( int iObject ) { sObject* pObject = dbGetObject ( iObject ); if ( !pObject ) return; int iCount = 0; for ( int iMesh = 0; iMesh < pObject->iMeshCount; iMesh++ ) { NxVec3* pVertices = new NxVec3 [ pObject->ppMeshList [ iMesh ]->dwVertexCount ]; int iVertexCount = pObject->ppMeshList [ iMesh ]->dwVertexCount; int* iTriangles = new int [ pObject->ppMeshList [ iMesh ]->dwIndexCount ]; int iTriangleCount = pObject->ppMeshList [ iMesh ]->dwIndexCount; sOffsetMap offsetMap; GetFVFOffsetMap ( pObject->ppMeshList [ iMesh ], &offsetMap ); for ( int i = 0; i < iVertexCount; i++ ) { pVertices [ i ].x = *( ( float* ) pObject->ppMeshList [ iMesh ]->pVertexData + offsetMap.dwX + ( offsetMap.dwSize * i ) ); pVertices [ i ].y = *( ( float* ) pObject->ppMeshList [ iMesh ]->pVertexData + offsetMap.dwY + ( offsetMap.dwSize * i ) ); pVertices [ i ].z = *( ( float* ) pObject->ppMeshList [ iMesh ]->pVertexData + offsetMap.dwZ + ( offsetMap.dwSize * i ) ); } for ( i = 0; i < iTriangleCount; i++ ) iTriangles [ i ] = pObject->ppMeshList [ iMesh ]->pIndices [ i ]; NxTriangleMeshDesc levelDesc; levelDesc.numVertices = iVertexCount; levelDesc.numTriangles = iTriangleCount / 3; levelDesc.pointStrideBytes = sizeof ( NxVec3 ); levelDesc.triangleStrideBytes = 3 * sizeof ( int ); levelDesc.points = pVertices; levelDesc.triangles = iTriangles; levelDesc.flags = NX_CF_COMPUTE_CONVEX; NxTriangleMeshShapeDesc levelShapeDesc; NxInitCooking ( ); MemoryWriteBuffer buf; bool status = NxCookTriangleMesh ( levelDesc, buf ); if ( status ) { levelShapeDesc.meshData = gPhysicsSDK->createTriangleMesh ( MemoryReadBuffer ( buf.data ) ); NxActor* actor = NULL; NxActorDesc actorDesc; actorDesc.shapes.pushBack ( &levelShapeDesc ); actor = gScene->createActor ( actorDesc ); sPhysObject* pPhys = new sPhysObject; pPhys->iID = iObject; actor->userData = ( void* )pPhys; SetActorCollisionGroup ( actor, GROUP_COLLIDABLE_NON_PUSHABLE ); } } }
NxActor* CreatePyramid(const NxVec3& pos, const NxVec3& boxDim, const NxReal density) { // Add a single-shape actor to the scene NxActorDesc actorDesc; NxBodyDesc bodyDesc; // Pyramid NxVec3 verts[8] = { NxVec3(boxDim.x,-boxDim.y,-boxDim.z), NxVec3(-boxDim.x,-boxDim.y,-boxDim.z), NxVec3(-boxDim.x,-boxDim.y,boxDim.z), NxVec3(boxDim.x,-boxDim.y,boxDim.z), NxVec3(boxDim.x*0.5,boxDim.y,-boxDim.z*0.5), NxVec3(-boxDim.x*0.5,boxDim.y,-boxDim.z*0.5), NxVec3(-boxDim.x*0.5,boxDim.y,boxDim.z*0.5), NxVec3(boxDim.x*0.5,boxDim.y,boxDim.z*0.5) }; // Create descriptor for convex mesh NxConvexMeshDesc convexDesc; convexDesc.numVertices = 8; convexDesc.pointStrideBytes = sizeof(NxVec3); convexDesc.points = verts; convexDesc.flags = NX_CF_COMPUTE_CONVEX | NX_CF_USE_LEGACY_COOKER; // The actor has one shape, a convex mesh NxConvexShapeDesc convexShapeDesc; convexShapeDesc.localPose.t = NxVec3(0,boxDim.y,0); NxInitCooking(); if (0) { // Cooking from file #ifndef LINUX bool status = NxCookConvexMesh(convexDesc, UserStream("c:\\tmp.bin", false)); convexShapeDesc.meshData = gPhysicsSDK->createConvexMesh(UserStream("c:\\tmp.bin", true)); #else printf("Linux does not behave well with UserStreams, use Memorybuffers instead\n"); #endif } else { // Cooking from memory MemoryWriteBuffer buf; bool status = NxCookConvexMesh(convexDesc, buf); convexShapeDesc.meshData = gPhysicsSDK->createConvexMesh(MemoryReadBuffer(buf.data)); } if (convexShapeDesc.meshData) { NxActorDesc actorDesc; actorDesc.shapes.pushBack(&convexShapeDesc); if (density) { actorDesc.body = &bodyDesc; actorDesc.density = density; } else { actorDesc.body = NULL; } actorDesc.globalPose.t = pos; NxActor* actor = gScene->createActor(actorDesc); return actor; // gPhysicsSDK->releaseConvexMesh(*convexShapeDesc.meshData); } return NULL; }
NxActor* CreateConvex(const NxVec3 &pos, int flag) { NxActorDesc actorDesc; NxBodyDesc bodyDesc; NxVec3 boxDim(1,0.8,1.5); // Pyramid NxVec3 verts[8] = { NxVec3(boxDim.x, -boxDim.y, -boxDim.z), NxVec3(-boxDim.x, -boxDim.y, -boxDim.z), NxVec3(-boxDim.x, -boxDim.y, boxDim.z), NxVec3(boxDim.x, -boxDim.y, boxDim.z), NxVec3(boxDim.x*0.5, boxDim.y, -boxDim.z*0.5), NxVec3(-boxDim.x*0.5, boxDim.y, -boxDim.z*0.5), NxVec3(-boxDim.x*0.5, boxDim.y, boxDim.z*0.5), NxVec3(boxDim.x*0.5, boxDim.y, boxDim.z*0.5) }; // Create descriptor for convex mesh if (!convexDesc) { convexDesc = new NxConvexMeshDesc(); assert(convexDesc); } convexDesc->numVertices = 8; convexDesc->pointStrideBytes = sizeof(NxVec3); convexDesc->points = verts; convexDesc->flags = NX_CF_COMPUTE_CONVEX; NxConvexShapeDesc convexShapeDesc; convexShapeDesc.localPose.t = NxVec3(0, 2.0f, boxDim.z * 0.4); convexShapeDesc.userData = convexDesc; NxInitCooking(); // Cooking from memory MemoryWriteBuffer buf; bool status = NxCookConvexMesh(*convexDesc, buf); // // Please note about the created Convex Mesh, user needs to release it when no one uses it to save memory. It can be detected // by API "meshData->getReferenceCount() == 0". And, the release API is "gPhysicsSDK->releaseConvexMesh(*convexShapeDesc.meshData);" // NxConvexMesh *pMesh = gPhysicsSDK->createConvexMesh(MemoryReadBuffer(buf.data)); assert(pMesh); convexShapeDesc.meshData = pMesh; NxCloseCooking(); if (pMesh) { // Save mesh in userData for drawing. pMesh->saveToDesc(*convexDesc); // NxActorDesc actorDesc; assert(convexShapeDesc.isValid()); actorDesc.shapes.pushBack(&convexShapeDesc); if (0 == flag) { //Dynamic actor bodyDesc.flags |= NX_BF_DISABLE_GRAVITY; actorDesc.body = &bodyDesc; actorDesc.density = 1.0f; } else if (1 == flag) { //Static actor actorDesc.body = NULL; actorDesc.density = 1.0f; } else if (2 == flag) { // Kinematic actor bodyDesc.flags |= NX_BF_KINEMATIC; actorDesc.body = &bodyDesc; actorDesc.density = 1.0f; } actorDesc.globalPose.t = pos; //NxVec3(6.5f, 0.0f, 0.0f); assert(actorDesc.isValid()); NxActor* actor = gScene->createActor(actorDesc); assert(actor); return actor; } return NULL; }