hsVectorStream* plPhysXCooking::CookHull(int nVerts, hsPoint3* verts, bool inflate) { NxConvexMeshDesc convexDesc; convexDesc.numVertices = nVerts; convexDesc.pointStrideBytes = sizeof(hsPoint3); convexDesc.points = verts; convexDesc.flags = NX_CF_COMPUTE_CONVEX; if(inflate) { convexDesc.flags|= NX_CF_INFLATE_CONVEX ; } hsVectorStream* ram = new hsVectorStream; plPXStream buf(ram); bool status = NxCookConvexMesh(convexDesc, buf); hsAssert(status, "Convex mesh failed to cook"); if (status) { ram->Rewind(); return ram; } else { delete ram; return nil; } }
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; }
//------------------------------------------------------------------------------------------------- bool sdPhysXCookUtility::CookConvexMesh(const NxConvexMeshDesc& kDesc, NxStream& kStream) { #ifdef COOKING_INTERFACE return ms_pkCooking->NxCookConvexMesh(kDesc, kStream); #else return NxCookConvexMesh(kDesc, kStream); #endif }
bool CookConvexMesh(const NxConvexMeshDesc& desc, NxStream& stream) { #ifdef COOKING_INTERFACE hasCookingLibrary(); if ( !gCooking ) return false; return gCooking->NxCookConvexMesh(desc,stream); #else return NxCookConvexMesh(desc,stream); #endif }
// 增加一辆车 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 plGenericPhysical::IWritePXPhysical(hsStream* S, plResManager* mgr) { S->writeFloat(fMass); S->writeFloat(fFriction); S->writeFloat(fRestitution); S->writeByte(fBounds); S->writeByte(plPXSimDefs::toGroup(fMemberGroup, fCollideGroup)); S->writeInt(plPXSimDefs::setReportsOn(fReportGroup)); S->writeShort(fLOSDBs); mgr->writeKey(S, fObjectKey); mgr->writeKey(S, fSceneNode); mgr->writeKey(S, fSubWorld); mgr->writeKey(S, fSoundGroup); fPos.write(S); fRot.write(S); fProps.write(S); if (fBounds == plSimDefs::kSphereBounds) { S->writeFloat(fRadius); fOffset.write(S); } else if (fBounds == plSimDefs::kBoxBounds) { fDimensions.write(S); fOffset.write(S); } else if (fBounds == plSimDefs::kHullBounds) { #ifdef HAVE_PX_SDK if (!sPhysxWasInit) { NxInitCooking(); sPhysxWasInit = true; } NxConvexMeshDesc convexDesc; convexDesc.numVertices = fVerts.size(); convexDesc.pointStrideBytes = sizeof(hsVector3); convexDesc.points = &fVerts[0]; convexDesc.flags = NX_CF_COMPUTE_CONVEX; plPXStream buf(S); if (!NxCookConvexMesh(convexDesc, buf)) throw hsBadParamException(__FILE__, __LINE__, "Incorrect data for PhysX Hull Bake"); #else throw hsNotImplementedException(__FILE__, __LINE__, "PhysX HullBounds"); #endif } else { // Proxy or Explicit #ifdef HAVE_PX_SDK if (!sPhysxWasInit) { NxInitCooking(); sPhysxWasInit = true; } NxTriangleMeshDesc triDesc; triDesc.numVertices = fVerts.size(); triDesc.pointStrideBytes = sizeof(hsVector3); triDesc.points = &fVerts[0]; triDesc.numTriangles = fIndices.size() / 3; triDesc.triangleStrideBytes = sizeof(unsigned int) * 3; triDesc.triangles = &fIndices[0]; triDesc.flags = 0; // 32-bit appears to be the default for index size plPXStream buf(S); if (!NxCookTriangleMesh(triDesc, buf)) throw hsBadParamException(__FILE__, __LINE__, "Incorrect data for a PhysX Trimesh Bake"); #else throw hsNotImplementedException(__FILE__, __LINE__, "PhysX TriangleMesh"); #endif } }
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; }