380 likes | 525 Views
Fizika. PhysX. Kezdeti teendők. Letöltés: OgrePhysXBase.zip Kicsomagol Futtat: OgrePhysX.sln Include és library útvonalak beállítása Working directory beállítása Fordít Futtat. # include " Ogre.h " # define OIS_DYNAMIC_LIB # include <OIS/ OIS.h > using namespace Ogre ;
E N D
Fizika PhysX
Kezdeti teendők • Letöltés: OgrePhysXBase.zip • Kicsomagol • Futtat: OgrePhysX.sln • Include és library útvonalak beállítása • Working directory beállítása • Fordít • Futtat
#include "Ogre.h" #define OIS_DYNAMIC_LIB #include <OIS/OIS.h> usingnamespaceOgre; Root* ogreRoot; SceneManager* sceneManager; Camera* camera; RenderWindow* renderWindow; OIS::InputManager* OISInputManager; SceneNode* box1Node; SceneNode* box2Node; SceneNode* box3Node;
createGround(); SceneNode* rootNode = sceneManager->getRootSceneNode(); box1Node = rootNode->createChildSceneNode(); Entity* box1 = sceneManager->createEntity("box1", "doboz.mesh"); box1Node->attachObject(box1); box1Node->setScale(10,10,10); box1Node->setPosition(0,10,0); box2Node = rootNode->createChildSceneNode(); Entity* box2 = sceneManager->createEntity("box2", "doboz.mesh"); box2Node->attachObject(box2); box2Node->setScale(15,15,15); box2Node->setPosition(5,30,0); box3Node = rootNode->createChildSceneNode(); Entity* box3 = sceneManager->createEntity("box3", "doboz.mesh"); box3Node->attachObject(box3); box3Node->setScale(5,5,5); box3Node->setPosition(-2,50,5); sceneManager->setSkyBox(true, "Sky", 10, true);
classPhysicsHandler; PhysicsHandler* physicsHandler; classPhysicsHandler: publicFrameListener { public: PhysicsHandler () { } ~PhysicsHandler () { } boolframeStarted(constFrameEvent&evt) { returntrue; } }; classControlDeviceHandler : publicFrameListener voidsetupListeners() { ogreRoot->addFrameListener(newControlDeviceHandler()); physicsHandler = newPhysicsHandler(); ogreRoot->addFrameListener(physicsHandler); }
classPhysicsHandler : publicFrameListener { protected: boolinited; NxPhysicsSDK* mPhysicsSDK; NxScene* mPhysicsScene; public: PhysicsHandler() { inited = false; mPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION); if (!mPhysicsSDK) return; mPhysicsSDK->getFoundationSDK().getRemoteDebugger()->connect("localhost", 5425); mPhysicsSDK->setParameter(NX_SKIN_WIDTH, 0.01); NxSceneDescsceneDesc; sceneDesc.simType = NX_SIMULATION_HW; sceneDesc.gravity = NxVec3(0,-90.8f,0); sceneDesc.groundPlane = true; mPhysicsScene = mPhysicsSDK->createScene(sceneDesc); if(!mPhysicsScene) { sceneDesc.simType = NX_SIMULATION_SW; mPhysicsScene = mPhysicsSDK->createScene(sceneDesc); if(!mPhysicsScene) return; } // Createthedefaultmaterial NxMaterial* defaultMaterial = mPhysicsScene->getMaterialFromIndex(0); defaultMaterial->setRestitution(0.5); defaultMaterial->setStaticFriction(0.5); defaultMaterial->setDynamicFriction(0.5); inited = true; }
PhysX-hez mi kell indulásképpen? #include "NxPhysics.h " • Includepath beállítása: ..\PhysX\SDKs\Physics\include ..\PhysX\SDKs\Foundation ..\PhysX\SDKs\PhysXLoader\include • Librarypath beállítása: ..\PhysX\SDKs\lib\Win32 • Library megadása : PhysXLoader.lib • PhysXLoader.dll másolása bin-be Próba… fordul-e?
Szimuláció boolframeStarted(constFrameEvent&evt) { if(!inited) returntrue; mPhysicsScene->simulate(evt.timeSinceLastFrame); mPhysicsScene->flushStream(); while (!mPhysicsScene->fetchResults(NX_RIGID_BODY_FINISHED, false)); returntrue; }
Visual Debugger Sík Futtat : RemoteDebugger.exe Futtat: OgrePhysX
classPhysXBoxObject { protected: SceneNode* ogreNode; NxActorDescactorDesc; NxBoxShapeDescboxDesc; NxActor* actor; NxBodyDescbodyDesc; public: PhysXBoxObject(SceneNode* ogreNode, NxScene* physXScene) { this->ogreNode = ogreNode; boxDesc.dimensions.set(ogreNode->getScale().x, ogreNode->getScale().y, ogreNode->getScale().z); actorDesc.shapes.pushBack(&boxDesc); actorDesc.body = &bodyDesc; actorDesc.density = 10; actorDesc.globalPose.t = NxVec3(ogreNode->getPosition().x, ogreNode->getPosition().y, ogreNode->getPosition().z); actor = physXScene->createActor(actorDesc); } };
classPhysicsHandler : publicFrameListener { protected: boolinited; NxPhysicsSDK* mPhysicsSDK; NxScene* mPhysicsScene; PhysXBoxObject* boxes[3]; public: PhysicsHandler() { … defaultMaterial->setDynamicFriction(0.5); boxes[0] = newPhysXBoxObject(box1Node, mPhysicsScene); boxes[1] = newPhysXBoxObject(box2Node, mPhysicsScene); boxes[2] = newPhysXBoxObject(box3Node, mPhysicsScene); inited = true; }
classPhysXBoxObject { public: void update() { ogreNode->setOrientation(actor->getGlobalOrientationQuat().w, actor->getGlobalOrientationQuat().x, actor->getGlobalOrientationQuat().y, actor->getGlobalOrientationQuat().z); ogreNode->setPosition(actor->getGlobalPosition().x, actor->getGlobalPosition().y, actor->getGlobalPosition().z); }
Próba classPhysicsHandler : publicFrameListener { … boolframeStarted(constFrameEvent&evt) { if(!inited) returntrue; mPhysicsScene->simulate(evt.timeSinceLastFrame); mPhysicsScene->flushStream(); while (!mPhysicsScene->fetchResults(NX_RIGID_BODY_FINISHED, false)); boxes[0]->update(); boxes[1]->update(); boxes[2]->update(); returntrue; }
Próba PhysXBoxObject(SceneNode* ogreNode, NxScene* physXScene) { this->ogreNode = ogreNode; boxDesc.dimensions.set(ogreNode->getScale().x * 0.5f, ogreNode->getScale().y * 0.5f, ogreNode->getScale().z * 0.5f);
classPhysXBallObject { protected: SceneNode* ogreNode; NxActorDescactorDesc; NxSphereShapeDescsphereDesc; NxActor* actor; NxBodyDescbodyDesc; public: PhysXBallObject(SceneNode* ogreNode, NxScene* physXScene) { this->ogreNode = ogreNode; sphereDesc.radius = 3; actorDesc.shapes.pushBack(&sphereDesc); actorDesc.body = &bodyDesc; actorDesc.density = 10; actorDesc.globalPose.t = NxVec3(camera->getPosition().x, camera->getPosition().y, camera->getPosition().z); actor = physXScene->createActor(actorDesc); actor->addForce(NxVec3(camera->getDirection().x * 10000, camera->getDirection().y * 10000, camera->getDirection().z * 10000), NX_ACCELERATION); } void update() { ogreNode->setOrientation(actor->getGlobalOrientationQuat().w, actor->getGlobalOrientationQuat().x, actor->getGlobalOrientationQuat().y, actor->getGlobalOrientationQuat().z); ogreNode->setPosition(actor->getGlobalPosition().x, actor->getGlobalPosition().y, actor->getGlobalPosition().z); } };
classPhysicsHandler : publicFrameListener { protected: … std::vector<PhysXBallObject*> balls; public: voidaddBall(SceneNode* ogreNode) { balls.push_back(newPhysXBallObject(ogreNode, mPhysicsScene)); } boolframeStarted(constFrameEvent&evt) { … boxes[0]->update(); boxes[1]->update(); boxes[2]->update(); std::vector<PhysXBallObject*>::iterator it = balls.begin(); std::vector<PhysXBallObject*>::iteratoritend = balls.end(); while(it != itend) { (*it)->update(); it++; } returntrue; }
Elődeklaráció voidaddBall(); classPhysicsHandler; PhysicsHandler* physicsHandler; … voidaddBall() { static int id = 0; SceneNode* ballNode = sceneManager->getRootSceneNode()->createChildSceneNode(); Entity *ballEnt = sceneManager->createEntity("ball"+StringConverter::toString(id),"strippedBall.mesh"); ballNode->attachObject(ballEnt); ballNode->setScale(3,3,3); physicsHandler->addBall(ballNode); id++; } voidcreateGround()
classControlDeviceHandler : publicFrameListener { … boolframeStarted(constFrameEvent&evt) { if( mKeyboard->isKeyDown(OIS::KC_SPACE) && mTimeUntilNextToggle < 0) { addBall(); mTimeUntilNextToggle = 0.5f; } …
Statikus Actor PhysXBoxObject(SceneNode* ogreNode, NxScene* physXScene) { this->ogreNode = ogreNode; boxDesc.dimensions.set(ogreNode->getScale().x * 0.5f, ogreNode->getScale().y * 0.5f, ogreNode->getScale().z * 0.5f); actorDesc.shapes.pushBack(&boxDesc); actorDesc.body = 0;//&bodyDesc; … Ekkor az update függvényre sincs szükség!!
Animáció //globális változó SceneNode* hammerNode; … classAnimController : publicFrameListener { public: boolframeStarted(constFrameEvent&evt) { hammerNode->rotate(Vector3::UNIT_Y, Radian(evt.timeSinceLastFrame * 2.0f)); returntrue; } }; voidsetupListeners() { ogreRoot->addFrameListener(newAnimController()); … }
voidsetupScene() { … hammerNode = rootNode->createChildSceneNode(); SceneNode* tempNode = hammerNode->createChildSceneNode(); Entity* hammer = sceneManager->createEntity("hammer", "TrollMace.mesh"); tempNode->attachObject(hammer); tempNode->rotate(Vector3::UNIT_X,Radian(Degree(90))); hammerNode->setScale(30,30,30); hammerNode->setPosition(0,5,30); … }
classPhysXHammerObject { protected: SceneNode* ogreNode; NxActorDescactorDesc; NxBoxShapeDescheadBoxDesc; NxBoxShapeDeschandleBoxDesc; NxActor* actor; NxBodyDescbodyDesc; public: PhysXHammerObject(SceneNode* ogreNode, NxScene* physXScene) { this->ogreNode = ogreNode; headBoxDesc.dimensions.set(ogreNode->getScale().x * 0.25f, ogreNode->getScale().y * 0.25 * 0.5f, ogreNode->getScale().z * 0.25 * 0.5f); headBoxDesc.localPose.t.set(0,ogreNode->getScale().y * 0.865f,0); actorDesc.shapes.pushBack(&headBoxDesc); handleBoxDesc.dimensions.set(ogreNode->getScale().x * 0.5f * 0.1f, ogreNode->getScale().y * 0.5f, ogreNode->getScale().z * 0.5f * 0.1f); handleBoxDesc.localPose.t.set(0,ogreNode->getScale().y * 0.5,0); actorDesc.shapes.pushBack(&handleBoxDesc); actorDesc.body = &bodyDesc; actorDesc.density = 10; actorDesc.globalPose.t= NxVec3(ogreNode->getPosition().x, ogreNode->getPosition().y, ogreNode->getPosition().z); actor = physXScene->createActor(actorDesc); actor->raiseBodyFlag(NX_BF_KINEMATIC); //KINEMATIKUS ACTOR } …
void update() { Matrix4 transform; SceneNode* tempNode = ((SceneNode*) ogreNode->getChild(0)); Vector3 pos = tempNode->_getDerivedPosition(); Quaternionorient = tempNode->_getDerivedOrientation(); actor->moveGlobalPosition(NxVec3(pos.x,pos.y,pos.z)); actor->moveGlobalOrientation(NxQuat(NxVec3(orient.x,orient.y,orient.z),orient.w)); } }; classPhysicsHandler : publicFrameListener { protected: PhysXHammerObject* hammer; … PhysicsHandler() { … hammer = newPhysXHammerObject(hammerNode, mPhysicsScene); } boolframeStarted(constFrameEvent&evt) { … hammer->update(); }
Önálló (otthoni) feladat Kamera köré egy kinematikus Actor-t. Lehessen böködni a dobozokat.
class Explosive { public: Explosive(SceneManager* sceneManager, NxScene* physXScene) { static int id = 0; float a = Math::RangeRandom(0, 360); float d = Math::RangeRandom(50, 120); float x = Math::Cos(a) * d; float z = Math::Sin(a) * d; SceneNode* node = sceneManager->getRootSceneNode()->createChildSceneNode(); Entity* entity = sceneManager->createEntity("explosive"+StringConverter::toString(id), "explosive.mesh"); node->attachObject(entity); node->setScale(10,10,10); node->setPosition(x,0,z); id++; } };
voidsetupExplosives() { for(int i = 0; i <8; i ++) newExplosive(sceneManager, physicsHandler->getScene()); } … int _tmain(intargc, _TCHAR* argv[]) { … setupScene(); setupListeners(); setupExplosives(); … } classPhysicsHandler : publicFrameListener { … public: NxScene* getScene() { returnmPhysicsScene; } …
Explosive(SceneManager* sceneManager, NxScene* physXScene) { … node->setPosition(x,0,z); NxActorDescactorDesc; NxBoxShapeDescboxDesc; boxDesc.dimensions.set(2.5,5,2.5); boxDesc.shapeFlags |= NX_TRIGGER_ENABLE; actorDesc.shapes.pushBack(&boxDesc); actorDesc.globalPose.t.set(x,5,z); NxActor* actor = physXScene->createActor(actorDesc); physXScene->setUserTriggerReport(this); id++; }
Trigger report classExplosive { … voidonTrigger(NxShape&triggerShape, NxShape&otherShape, NxTriggerFlag status) { float f = 300; otherShape.getActor().addForce(NxVec3(Math::RangeRandom(-f, f), Math::RangeRandom(0, 5 * f), Math::RangeRandom(-f, f)) ,NX_ACCELERATION); } };