物理引擎
可参考:physxsetup.pdf
// 这是PhysX API的一个Hello World程序,不带渲染 #include <algorithm> #include <PxPhysicsAPI.h> constexpr auto PVD_HOST = "localhost"; using namespace physx; // 用于管理和分配内存,这里使用的是一份默认的实现 // 实现这个类以定制某些功能 static PxDefaultAllocator gAllocator; // 错误处理类,这里使用的也是默认实现 static PxDefaultErrorCallback gErrorCallback; static PxFoundation* gFoundation = NULL; static PxPhysics* gPhysics = NULL; // 这是个啥 static PxDefaultCpuDispatcher* gDispatcher = NULL; // 场景和材质 static PxScene* gScene = NULL; static PxMaterial* gMaterial = NULL; // [?]用于调试 static PxPvd* gPvd = NULL; static PxReal stackZ = 10.0f; // 向场景中添加Actor static PxRigidDynamic* createDynamic(const PxTransform& t, const PxGeometry& geometry, const PxVec3& velocity = PxVec3(0)) { PxRigidDynamic* dynamic = PxCreateDynamic(*gPhysics, t, geometry, *gMaterial, 10.0f); dynamic->setAngularDamping(0.5f); dynamic->setLinearVelocity(velocity); gScene->addActor(*dynamic); return dynamic; } // 向场景中添加Actor static void createStack(const PxTransform& t, PxU32 size, PxReal halfExtent) { PxShape* shape = gPhysics->createShape(PxBoxGeometry(halfExtent, halfExtent, halfExtent), *gMaterial); for (PxU32 i = 0; i < size; i++) { for (PxU32 j = 0; j < size - i; j++) { PxTransform localTm(PxVec3(PxReal(j * 2) - PxReal(size - i), PxReal(i * 2 + 1), 0) * halfExtent); PxRigidDynamic* body = gPhysics->createRigidDynamic(t.transform(localTm)); body->attachShape(*shape); PxRigidBodyExt::updateMassAndInertia(*body, 10.0f); gScene->addActor(*body); } } shape->release(); } inline void initPhysics(bool interactive) { // 创建Foundation gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback); gPvd = PxCreatePvd(*gFoundation); PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10); gPvd->connect(*transport, PxPvdInstrumentationFlag::eALL); // 创建Physics gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(), true, gPvd); // 创建场景 PxSceneDesc sceneDesc(gPhysics->getTolerancesScale()); sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f); gDispatcher = PxDefaultCpuDispatcherCreate(2); sceneDesc.cpuDispatcher = gDispatcher; sceneDesc.filterShader = PxDefaultSimulationFilterShader; gScene = gPhysics->createScene(sceneDesc); PxPvdSceneClient* pvdClient = gScene->getScenePvdClient(); if (pvdClient) { pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true); pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true); pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true); } // 创建材质 gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f); // 向场景中添加Actor PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0, 1, 0, 0), *gMaterial); gScene->addActor(*groundPlane); for (PxU32 i = 0; i < 5; i++) createStack(PxTransform(PxVec3(0, 0, stackZ -= 10.0f)), 10, 2.0f); if (!interactive) createDynamic(PxTransform(PxVec3(0, 40, 100)), PxSphereGeometry(10), PxVec3(0, -50, -100)); } // 步进 void stepPhysics(bool /*interactive*/) { gScene->simulate(1.0f / 60.0f); gScene->fetchResults(true); } // 清理工作 void cleanupPhysics(bool /*interactive*/) { PX_RELEASE(gScene); PX_RELEASE(gDispatcher); PX_RELEASE(gPhysics); if (gPvd) { PxPvdTransport* transport = gPvd->getTransport(); gPvd->release(); gPvd = NULL; PX_RELEASE(transport); } PX_RELEASE(gFoundation); printf("SnippetHelloWorld done.\n"); } int main() { static const PxU32 frameCount = 100; // 初始化物理引擎 initPhysics(false); // 执行仿真 for (PxU32 i = 0; i < frameCount; i++) stepPhysics(false); // 清理物理引擎 cleanupPhysics(false); return 0; }