physx integr áció
DESCRIPTION
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. - PowerPoint PPT PresentationTRANSCRIPT
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.cppvoid 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
;
animatevoid 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);
} elsephysicsModel = new PhysicsModel(true);
loadNxBoxShapes(physicsModelNode, physicsModel);loadNxCapsuleShapes(physicsModelNode, physicsModel);loadNxSphereShapes(physicsModelNode, physicsModel);
physicsModelDirectory[physicsModelName] = physicsModel;iPhysicsModel++;
}}
// segédfüggvény, mindegyik shapehez kellvoid 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