350 likes | 468 Views
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. <Scene> <Mesh name="pickup" xFileName="media\pickup.x" />
E N D
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 • <Scene> • <Mesh name="pickup" xFileName="media\\pickup.x" /> • <PhysicsMaterial name="wheel" friction="false" /> • <PhysicsModel name="pickup"> • <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" /> • </PhysicsModel> • <Mesh name="ground" xFileName="media\\ground.x" /> • <PhysicsModel name="ground" dynamism="static" > • <NxPlaneShape normal.y="1" offset="3.5"/> • </PhysicsModel> • <group> • <PhysicsEntity name="ground" • shadedMesh="ground" physicsModel="ground" /> • <PhysicsEntity name="pickup" shadedMesh="pickup" physicsModel="pickup" position.y="30" /> • <PhysicsEntity name="nmi" shadedMesh="pickup" physicsModel="pickup" position.x="6" position.y="50" position.z="6" /> • </group> • <Camera owner="pickup" eye.x="-16" eye.y="8" eye.z="0"/> • </Scene>
Directory.h – új konténerek • typedef std::map<const std::wstring, NxMaterial*> PhysicsMaterialDirectory; • class PhysicsModel; • typedef std::map<const std::wstring, PhysicsModel*> 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: PhysicsEntitybase 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) < 0.001 ) • 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