physx学习笔记
1.tutorial01 盒子 Physx的基本设置
//.h
NiPhysXManager* m_pkPhysManager;
//.cpp //初始化 m_pkPhysManager = NiPhysXManager::GetPhysXManager(); if (!m_pkPhysManager->Initialize()) { char acMsg[1024]; NiSprintf(acMsg, 1024, "Unable to initialize PhysX SDK version %d.\n" "This may mean you don't have PhysX installed.\n" "Have you installed PhysX System Software and Core?\n", NX_SDK_VERSION_NUMBER); NiMessageBox(acMsg, "PhysX Initialization Failed"); return false; } m_pkPhysManager->m_pkPhysXSDK->setParameter(NX_SKIN_WIDTH, 0.01f); m_pkPhysManager->m_pkPhysXSDK->setParameter(NX_BOUNCE_THRESHOLD, -0.5f); m_pkPhysManager->m_pkPhysXSDK->setParameter(NX_VISUALIZATION_SCALE, 0.0f); m_pkPhysManager->m_pkPhysXSDK->setParameter(NX_VISUALIZE_BODY_AXES, 0.2f); m_pkPhysManager->m_pkPhysXSDK->setParameter(NX_VISUALIZE_COLLISION_SHAPES,1.0f);
//销毁 //在所有Physx对象被销毁之后调用 m_pkPhysManager->ShutDown();
2.tutorial02 盒子和球 载入了Physx对象
// //.h // NiPhysXScenePtr m_spPhysScene; // //.cpp //
//初始化和创建场景 m_spPhysScene = NiNew NiPhysXScene(); NxSceneDesc kSceneDesc; kSceneDesc.gravity.set(0.0f, 0.0f, -9.8f); NxScene* pkScene = m_pkPhysManager->m_pkPhysXSDK->createScene(kSceneDesc); // Attach the physics scene to the wrapper m_spPhysScene->SetPhysXScene(pkScene); // Look for the PhysX content. NiPhysXPropPtr spBallProp = 0; for (unsigned int ui = 1; ui < kStream.GetObjectCount(); ui++) { if (NiIsKindOf(NiPhysXProp, kStream.GetObjectAt(ui))) { // We have found the PhysX content in the NIF. spBallProp = (NiPhysXProp*)kStream.GetObjectAt(ui); } } // We can optimize the updating of transformations when actors // are sleeping. This is only appropriate if there is no moving // object in the scene graph below the actor-controlled object. // In this case there is nothing moving below the ball in the scene // graph. ((NiPhysXRigidBodyDest*)spBallProp->GetDestinationAt(0))-> SetOptimizeSleep(true); //使球的物理属性生效 m_spPhysScene->AddProp(spBallProp); // The ball is a destination object - the Gamebryo scene graph ball // receives pose information from the PhysX actor. We need to enable // the updating of destinations to start the transfer of information. // Each object needs to be enabled and the whole scene. By default the // object update is enabled, but the scene update is not. m_spPhysScene->SetUpdateDest(true);
//UpdateFrame() // A call to Simulate starts the simulation. // We pass it the target time. m_spPhysScene->Simulate(m_fAccumTime); // We want the results immediately, so we call FetchResults with // the same time we just asked for, and the second argument as true // to block on the results. m_spPhysScene->FetchResults(m_fAccumTime, true); // Now the actors have been moved, but we need to update the // Gamebryo objects. UpdateDestinations does that. Note it is called // on the NiPhysXScene that owns the objects being updated. m_spPhysScene->UpdateDestinations(m_fAccumTime); // FInally we update the scene graph. m_spScene->Update(m_fAccumTime);
//恢复场景为初始状态 void BallInBox::ResetBall() { // To restore the scene to its initial conditions, we use the data // stored in the snapshot that was originally loaded from the NIF file. // By default, that is snapshot 0. m_spPhysScene->RestoreSnapshotState(0); }
3.tutorial03 带杠杆动画的盒子和球 在Physx场景中加入了一个动画控制的对象
//初始化 // The ball is a destination object - the Gamebryo scene graph ball // receives pose information from the PhysX actor. We need to enable // the updating of destinations to start the transfer of information. // This scene now contains the paddle, which is a source of pose // information for PhysX. We need to enable updates of sources in the // scene. // Each object needs to be enabled and the whole scene. By default the // object update is enabled, but the scene update is not. m_spPhysScene->SetUpdateDest(true); m_spPhysScene->SetUpdateSrc(true);
4.tutorial04 物理模拟与渲染并行
//开启异步模拟 m_spPhysScene->SetAsynchronousSimulation(true); //在初始化的最后开始第一次模拟 m_spPhysScene->Simulate(0.001f);
更新
更新时先传入上一帧的时间来等待物理模拟线程完成工作,必须在任何Physx sdk调用前做,因为当模拟的时候任何
SDK调用都是不安全的
// Simulation has been going on between frames. Now we get the // results. We still block because we need the answers. We have to do // this before we do anything that might touch the PhysX SDK, because // it is unsafe to try any SDK operations while simulating. m_spPhysScene->FetchResults(fLastSimTime, true); m_spPhysScene->UpdateDestinations(fLastSimTime); NiApplication::UpdateFrame(); // Calls process input // Update the camera. This uses global time. //if (m_kTurret.Read()) // m_spTrnNode->Update(m_fAccumTime); // We update the scene graph. m_spScene->Update(m_fAccumTime); // Now we start the next step, giving a time that will actually be // in te past by the time we get the results. m_spPhysScene->UpdateSources(m_fAccumTime); m_spPhysScene->Simulate(m_fAccumTime); fLastSimTime = m_fAccumTime;