PhysX integráció Szécsi László
Letöltés diák: bagira.iit.bme.hu/~szecsi/GraphGame //l11-physx.ppt modell: bagira.iit.bme.hu/~szecsi/GraphGame //pickup.zip
XML – új XML file <NxBoxShape position.y="9" dimension.x="32" dimension.y="4" dimension.z="10" /> <NxBoxShape position.y="12" dimension.x="6" dimension.y="4" dimension.z="10" /> <PhysicsEntity name="ground" shadedMesh="ground" physicsModel="ground" />
Directory.h – új konténerek typedef std::map PhysicsMaterialDirectory; class PhysicsModel; typedef std::map PhysicsModelDirectory;
EngineCore – új tagváltozók NxPhysicsSDK*nxPhysicsSDK; NxScene*nxScene; PhysicsMaterialDirectory physicsMaterialDirectory; PhysicsModelDirectory physicsModelDirectory;
EngineCore – új metódusok void loadPhysicsMaterials(XMLNode& xMainNode); void loadPhysicsModels(XMLNode& xMainNode); // folyt.
Shapek betöltéséhez modellbe void loadShapeDesc(XMLNode& shapeNode, NxShapeDesc* shapeDesc, D3DXVECTOR3 originalAxis = D3DXVECTOR3(0, 1, 0)); void loadNxBoxShapes(XMLNode& physicsModelNode, PhysicsModel* physicsModel); void loadNxCapsuleShapes(XMLNode& physicsModelNode, PhysicsModel* physicsModel); void loadNxSphereShapes(XMLNode& physicsModelNode, PhysicsModel* physicsModel); void loadNxPlaneShapes(XMLNode& physicsModelNode, PhysicsModel* physicsModel);
Entitás betöltő metódus void loadPhysicsEntities( XMLNode& groupNode, NodeGroup* group); // class PhysicsEntity; elődekl. kell
EngineCore-t hagyjuk félbe Majd később implementáljuk a metódusokat Előbb csináljuk meg az új osztályokat
Új class: PhysicsModel ( NxActorDesc wrapper ) class PhysicsEntity; class PhysicsModel { NxActorDesc nxActorDesc; public: void addShape( NxShapeDesc* shapeDesc); PhysicsModel(bool dynamic); ~PhysicsModel(); NxActorDesc& getNxActorDesc(); };
PhysicsModel::PhysicsModel PhysicsModel::PhysicsModel( bool dynamic) { NxBodyDesc* nxBodyDesc = NULL; if(dynamic) nxBodyDesc = new NxBodyDesc(); nxActorDesc.body = nxBodyDesc; nxActorDesc.density = 1; }
PhysicsModel.cpp PhysicsModel::~PhysicsModel() { delete nxActorDesc.body; } NxActorDesc& PhysicsModel::getNxActorDesc() { return nxActorDesc; }
PhysicsModel::addShape void PhysicsModel::addShape( NxShapeDesc* shapeDesc){ nxActorDesc.shapes.pushBack( shapeDesc); }
Új class: PhysicsEntity base class: Entity class PhysicsEntity : public Entity { NxActor* nxActor; public: NxActor* getNxActor(); PhysicsEntity(ShadedMesh* shadedMesh, PhysicsModel* physicsModel, NxScene* nxScene, const NxVec3& position); void render(const RenderContext& context); void setPosition( const D3DXVECTOR3& position); };
PhysicsEntity.cpp #include "PhysicsModel.h" #include "ShadedMesh.h" #include "Camera.h" PhysicsEntity::PhysicsEntity( ShadedMesh* shadedMesh, PhysicsModel* physicsModel, NxScene* nxScene, const NxVec3& position) :Entity(shadedMesh) { NxActorDesc& nxActorDesc = physicsModel->getNxActorDesc(); nxActorDesc.globalPose.t = position; nxActor = nxScene->createActor(nxActorDesc); }
PhysicsEntity.cpp NxActor* PhysicsEntity::getNxActor() { return nxActor; }
PhysicsEntity.cpp void PhysicsEntity::render(const RenderContext& context) { NxMat34 pose = nxActor->getGlobalPose(); D3DXMATRIX modelMatrix; D3DXMatrixIdentity(&modelMatrix); pose.getColumnMajor44((NxF32*)&modelMatrix); D3DXMATRIX modelMatrixInverse; D3DXMatrixInverse(&modelMatrixInverse, NULL, &modelMatrix); context.effect->SetMatrix("modelMatrix", &modelMatrix); context.effect->SetMatrix("modelMatrixInverse", &modelMatrixInverse); D3DXMATRIX modelViewProjMatrix = modelMatrix * context.camera->getViewMatrix() * context.camera->getProjMatrix(); context.effect->SetMatrix("modelViewProjMatrix", &modelViewProjMatrix); D3DXMATRIX modelViewMatrix = modelMatrix * context.camera->getViewMatrix(); context.effect->SetMatrix("modelViewMatrix", &modelViewMatrix); shadedMesh->render(context); }
Vissza az EngineCore-hoz Implementáljuk a betöltőket meg a többit EngineCore.cpp: #include "PhysicsModel.h" #include "PhysicsEntity.h"
createManagedResources kieg. nxPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION) ; nxPhysicsSDK->setParameter(NX_SKIN_WIDTH, 0.01); NxSceneDesc nxSceneDesc; nxSceneDesc.simType = NX_SIMULATION_SW; nxSceneDesc.gravity = NxVec3(0,-9.8,0); nxScene = nxPhysicsSDK- >createScene(nxSceneDesc);
createManagedResources folyt. NxMaterial* defaultMaterial = nxScene->getMaterialFromIndex(0); defaultMaterial->setRestitution(0.5); defaultMaterial-> setStaticFriction(0.5); defaultMaterial-> setDynamicFriction(0.5); loadLevel();
releaseManagedResources kieg. nxPhysicsSDK->releaseScene(*nxScene); nxPhysicsSDK->release();
createDefaultResources kieg. nxScene->simulate(0.0001); nxScene->flushStream(); return S_OK;
releaseDefaultResources kieg. while (!nxScene-> fetchResults( NX_RIGID_BODY_FINISHED, false)) // üres ciklus ;
animate void EngineCore::animate(double dt, double t) { currentCamera->second->animate(dt); while (!nxScene-> fetchResults(NX_RIGID_BODY_FINISHED, false)); sceneRoot->control( ControlContext(status, dt, sceneRoot)); sceneRoot->animate(dt); nxScene->simulate(dt); nxScene->flushStream(); }
loadLevel kieg. XMLNode xMainNode=XMLNode::openFileHelper(L" media\\levelPhysX.xml", L"Scene"); //… loadPhysicsMaterials(xMainNode); loadPhysicsModels(xMainNode); // még a loadGroup előtt
loadGroup kieg. loadPhysicsEntities(groupNode, group);
void EngineCore::loadPhysicsMaterials(XMLNode& xMainNode){ int iPhysicsMaterial = 0; XMLNode physicsMaterialNode; while( !(physicsMaterialNode = xMainNode.getChildNode(L"PhysicsMaterial", iPhysicsMaterial)).isEmpty() ) { const wchar_t* physicsMaterialName = physicsMaterialNode|L"name"; NxMaterialDesc nxMaterialDesc; if(physicsMaterialNode.readBool(L"friction", true)) nxMaterialDesc.flags &= ~NX_MF_DISABLE_FRICTION; else nxMaterialDesc.flags |= NX_MF_DISABLE_FRICTION; physicsMaterialDirectory[physicsMaterialName] = nxScene->createMaterial(nxMaterialDesc); iPhysicsMaterial++; } √
void EngineCore::loadPhysicsModels(XMLNode& xMainNode) { int iPhysicsModel = 0; XMLNode physicsModelNode; while( !(physicsModelNode = xMainNode.getChildNode(L"PhysicsModel", iPhysicsModel)).isEmpty() ) { const wchar_t* physicsModelName = physicsModelNode|L"name"; PhysicsModel* physicsModel; const wchar_t* dynamismString = physicsModelNode|L"dynamism"; if(dynamismString && wcscmp(dynamismString, L"static") == 0) { physicsModel = new PhysicsModel(false); loadNxPlaneShapes(physicsModelNode, physicsModel); } else physicsModel = new PhysicsModel(true); loadNxBoxShapes(physicsModelNode, physicsModel); loadNxCapsuleShapes(physicsModelNode, physicsModel); loadNxSphereShapes(physicsModelNode, physicsModel); physicsModelDirectory[physicsModelName] = physicsModel; iPhysicsModel++; }
// segédfüggvény, mindegyik shapehez kell void EngineCore::loadShapeDesc(XMLNode& shapeNode, NxShapeDesc* shapeDesc, D3DXVECTOR3 originalAxis) { shapeDesc->localPose.t = shapeNode.readNxVec3(L"position"); D3DXVECTOR3 axis = shapeNode.readVector(L"axis"); if(D3DXVec3Length(&axis) < ) axis = originalAxis; D3DXVECTOR3 turnAxis; D3DXVec3Cross(&turnAxis, &axis, &originalAxis); D3DXVec3Normalize(&axis, &axis); D3DXMATRIX turnMatrix; D3DXMatrixRotationAxis(&turnMatrix, &turnAxis, acos(D3DXVec3Dot(&axis, &originalAxis))); shapeDesc-> localPose.M.setColumnMajorStride4((NxF32*)&turnMatrix); }
void EngineCore::loadNxBoxShapes(XMLNode& physicsModelNode, PhysicsModel* physicsModel) { int iShape = 0; XMLNode shapeNode; while( !(shapeNode = physicsModelNode.getChildNode(L"NxBoxShape", iShape)).isEmpty() ) { NxBoxShapeDesc* nxBoxShapeDesc = new NxBoxShapeDesc(); loadShapeDesc(shapeNode, nxBoxShapeDesc); nxBoxShapeDesc->dimensions = shapeNode.readNxVec3(L"dimension", NxVec3(10, 10, 10)); physicsModel->addShape(nxBoxShapeDesc); iShape++; }
void EngineCore::loadNxCapsuleShapes(XMLNode& physicsModelNode, PhysicsModel* physicsModel) { int iShape = 0; XMLNode shapeNode; while( !(shapeNode = physicsModelNode.getChildNode(L"NxCapsuleShape", iShape)).isEmpty() ) { NxCapsuleShapeDesc* nxCapsuleShapeDesc = new NxCapsuleShapeDesc(); loadShapeDesc(shapeNode, nxCapsuleShapeDesc); nxCapsuleShapeDesc->radius = shapeNode.readDouble(L"radius", 5.0); nxCapsuleShapeDesc->height = shapeNode.readDouble(L"height", 10.0); physicsModel->addShape(nxCapsuleShapeDesc); iShape++; }
void EngineCore::loadNxSphereShapes(XMLNode& physicsModelNode, PhysicsModel* physicsModel) { int iShape = 0; XMLNode shapeNode; while( !(shapeNode = physicsModelNode.getChildNode(L"NxSphereShape", iShape)).isEmpty() ) { NxSphereShapeDesc* nxSphereShapeDesc = new NxSphereShapeDesc(); loadShapeDesc(shapeNode, nxSphereShapeDesc); nxSphereShapeDesc->radius = shapeNode.readDouble(L"radius", 1.0); physicsModel->addShape(nxSphereShapeDesc); iShape++; }
void EngineCore::loadNxPlaneShapes(XMLNode& physicsModelNode, PhysicsModel* physicsModel) { int iShape = 0; XMLNode shapeNode; while( !(shapeNode = physicsModelNode.getChildNode(L"NxPlaneShape", iShape)).isEmpty() ) { NxPlaneShapeDesc* nxPlaneShapeDesc = new NxPlaneShapeDesc(); loadShapeDesc(shapeNode, nxPlaneShapeDesc); nxPlaneShapeDesc->d = shapeNode.readDouble(L"offset"); nxPlaneShapeDesc->normal = shapeNode.readNxVec3(L"normal", NxVec3(0, 1, 0)); physicsModel->addShape(nxPlaneShapeDesc); iShape++; }
void EngineCore::loadPhysicsEntities( XMLNode& groupNode, NodeGroup* group) { int iPhysicsEntity = 0; XMLNode physicsEntityNode; while( !(physicsEntityNode = groupNode.getChildNode(L"PhysicsEntity", iPhysicsEntity)).isEmpty() ) { const wchar_t* shadedMeshName = physicsEntityNode|L"shadedMesh"; ShadedMeshDirectory::iterator iShadedMesh = shadedMeshDirectory.find(shadedMeshName); const wchar_t* physicsModelName = physicsEntityNode|L"physicsModel"; PhysicsModelDirectory::iterator iPhysicsModel = physicsModelDirectory.find(physicsModelName); if(iShadedMesh != shadedMeshDirectory.end() && iPhysicsModel != physicsModelDirectory.end()){ NxVec3 position = physicsEntityNode.readNxVec3(L"position"); PhysicsEntity* physicsEntity = new PhysicsEntity(iShadedMesh->second, iPhysicsModel->second, nxScene, position); group->add(physicsEntity); const wchar_t* entityName = physicsEntityNode|L"name"; if(entityName) entityDirectory[entityName] = physicsEntity; } iPhysicsEntity++; }
Próba Leesik a földre XML-be: Legyen még egy ugyanilyen entitás, valahol fölötte és kicsit odébb Ráesik és leborul