470 likes | 617 Views
Ogre Karakter. Csontváz animáció Third person camera PhysX character controller. Kezdeti teendők. OgreCharacterBase.zip letöltése Kicsomagolás Include és library könyvtárak módosítása Working directory : $(SolutionDir)/bin Fordítás Futtatás. Futtatás. Ogre skeleton file.
E N D
Ogre Karakter Csontváz animáció Third person camera PhysX character controller
Kezdeti teendők • OgreCharacterBase.zip letöltése • Kicsomagolás • Include és library könyvtárak módosítása • Working directory : $(SolutionDir)/bin • Fordítás • Futtatás
Ogre skeleton file • Nézzük meg a media/soldier.skeleton.xml fájlt, ami a media/soldier.skeleton szöveges (xml) változata. • Mit tartalmaz: • Izület (bone) nevek és a hozzájuk tartozó transzformáció (eltolás és kvaternió) • Izület hierarchia (kinek ki a szülő izülete) • Animációs adatok: • Minden animációra (névvel ellátottak): • Minden animációban résztvevő csontra (név szerint): • Kulcskeret adatok: időpillanat, aktuális transzformáció • Fontos, hogy nem minden csont adatait, és nem minden frame-ben tárolunk, hanem csak akkor, ha változnak!
Új osztály: PlayerCharacter OgreCharacter.cpp: #include "playerCharacter.h " … PhysicsHandler* physxHandler; PlayerCharacter* playerCharacter; … classmainFrameListener { … boolframeStarted(constFrameEvent&evt) { … if(!physxHandler->update(t, dt)) returnfalse; playerCharacter->update(t, dt); returntrue; } }; voidinit() { … newLevel(sceneManager, physxHandler->getScene()); playerCharacter = new PlayerCharacter(sceneManager, physxHandler->getScene()); … }
PlayerCharacter.h #pragmaonce #include "Ogre.h" #include "NxPhysics.h" classPlayerCharacter { public: PlayerCharacter(Ogre::SceneManager* sm, NxScene* nxs); ~PlayerCharacter(void); void update(float t, floatdt); Ogre::Vector3 getDirection(){returnnode->getOrientation() * Ogre::Vector3::UNIT_Z;} Ogre::Vector3 getPosition(){return node->getPosition();} protected: Ogre::Entity* entity; Ogre::SceneNode* node; Ogre::AnimationState* animations[2]; };
PlayerCharacter.cpp #include "stdafx.h" #include "PlayerCharacter.h„ PlayerCharacter::PlayerCharacter(Ogre::SceneManager* sm, NxScene* nxs) { } PlayerCharacter::~PlayerCharacter(void) { } void PlayerCharacter::update(float t, float dt) { }
Konstruktor PlayerCharacter::PlayerCharacter(Ogre::SceneManager* sm, NxScene* nxs) { entity = sm->createEntity("player", "soldier.mesh"); node = sm->getRootSceneNode()->createChildSceneNode(); node->attachObject(entity); entity->getSkeleton()-> setBlendMode(Ogre::SkeletonAnimationBlendMode::ANIMBLEND_CUMULATIVE); animations[0] = entity->getAnimationState("leg_stand"); animations[1] = entity->getAnimationState("up_stand"); animations[0]->setEnabled(true); animations[1]->setEnabled(true); animations[0]->setWeight(1); animations[1]->setWeight(1); animations[0]->setLoop(true); animations[1]->setLoop(true); } leg_stand up_stand leg_run up_run
update void PlayerCharacter::update(float t, float dt) { animations[0]->addTime(dt); animations[1]->addTime(dt); }
Új osztály: ThirdPersonCamera OgreCharacter.cpp: #include " ThirdPersonCamera.h " … ThirdPersonCamera* TPCamera; … classmainFrameListener { … boolframeStarted(constFrameEvent&evt) { … playerCharacter->update(t, dt); TPCamera->update(t, dt); returntrue; } }; voidinit() { … playerCharacter = new PlayerCharacter(sceneManager, physxHandler->getScene()); TPCamera = newThirdPersonCamera(); TPCamera->setCamera(camera); TPCamera->setCharacter(playerCharacter); … }
ThirdPersonCamera.h #pragmaonce #include "Ogre.h" #include "PlayerCharacter.h" classThirdPersonCamera { public: ThirdPersonCamera(); ~ThirdPersonCamera(void); voidsetCharacter(PlayerCharacter* c) { character = c; reset();} voidsetCamera(Ogre::Camera* camera) { this->camera = camera; reset();} void update(float t, floatdt); protected: Ogre::Camera* camera; PlayerCharacter* character; voidreset(); Ogre::Radian angle1; Ogre::Radian angle2; Ogre::Quaternionrot; floatcamHeight; floatcamDist; floattargetHeight; floatmotionBlend; };
ThirdPersonCamera.cpp #include "StdAfx.h" #include "ThirdPersonCamera.h" using namespace Ogre; ThirdPersonCamera::ThirdPersonCamera(void) { camera = 0; character = 0; angle1 = 0; angle2 = 0; rot = Quaternion::IDENTITY; camHeight = 1.0f; camDist = 25; targetHeight = 10; motionBlend = 2.0f; } ThirdPersonCamera::~ThirdPersonCamera(void) { }
ThirdPersonCamera.cpp void ThirdPersonCamera::reset() { if(camera == 0 || character == 0) return; Vector3 dir = character->getDirection(); dir.y = 0; dir.normalise(); dir.y = -camHeight; camera->setPosition(character->getPosition() - dir * camDist); camera->lookAt(character->getPosition() + Vector3(0,targetHeight,0)); } void ThirdPersonCamera::update(float t, float dt) { reset(); }
PlayerCharacter osztálybakét új publikus függvény: void PlayerCharacter::move(float amount) { node->translate(amount * Ogre::Vector3::UNIT_Z, Ogre::Node::TS_LOCAL); } void PlayerCharacter::turn(float amount) { node->rotate(Ogre::Vector3::UNIT_Y, Ogre::Radian(amount)); }
Új osztály: PlayerController #pragmaonce #include "PlayerCharacter.h" #define OIS_DYNAMIC_LIB #include <OIS/OIS.h> classPlayerController { public: PlayerController(PlayerCharacter* c); ~PlayerController(void); void update(float t, float dt, OIS::Keyboard* keyboard, OIS::Mouse* mouse); floatmTimeUntilNextToggle; protected: PlayerCharacter* character; };
#include "StdAfx.h" #include "PlayerController.h" PlayerController::PlayerController(PlayerCharacter* c) { character = c; } PlayerController::~PlayerController(void) { } voidPlayerController::update(float t, floatdt, OIS::Keyboard* keyboard, OIS::Mouse* mouse) { if (mTimeUntilNextToggle >= 0) mTimeUntilNextToggle -= dt; const OIS::MouseState &ms = mouse->getMouseState(); if( keyboard->isKeyDown(OIS::KC_UP)) character->move(20 * dt); if( keyboard->isKeyDown(OIS::KC_DOWN)) character->move(20 * -dt); if( keyboard->isKeyDown(OIS::KC_RIGHT)) character->turn(-dt); if( keyboard->isKeyDown(OIS::KC_LEFT)) character->turn(dt); }
InputHandler.h … #include "PlayerController.h„ … classInputHandler : publicOgre::FrameListener { … floatmTimeUntilNextToggle; std::list<PlayerController*> controllers; … bool update(float t, float dt) { … std::list<PlayerController*>::iterator it = controllers.begin(); std::list<PlayerController*>::iteratoritend = controllers.end(); while(it != itend) { (*it)->update(t, dt, mKeyboard, mMouse); it++; } returntrue; } voidaddPlayerController(PlayerController* c) { controllers.push_back(c); } }
OgreCharacter.cpp #include "PlayerController.h" … ThirdPersonCamera* TPCamera; PlayerController* playerController; … voidinit() { … playerController = newPlayerController(playerCharacter); inputHandler->addPlayerController(playerController); ogreRoot->addFrameListener(newmainFrameListener()); }
PlayerCharacter.h protected: enumPlayerAction { PA_BASE, PA_NONE, PA_WEAPON_HOLD, PA_SHOOT }; enumPlayerPose { PP_BASE, PP_STAND, PP_RUN }; PlayerActionaction; PlayerActionlastAction; PlayerPosepose; PlayerPoselastPose; boolinAction();
PlayerCharacter.cpp PlayerCharacter:: PlayerCharacter(…) { … lastAction = action = PA_NONE; lastPose = pose = PP_STAND; } boolPlayerCharacter::inAction() { return !animations[1]->getLoop() && !animations[1]->hasEnded(); }
voidPlayerCharacter::move(floatamount) { if(inAction()) return; node->translate(amount * Vector3::UNIT_Z, Node::TS_LOCAL); action = PA_NONE; pose = PP_RUN; } voidPlayerCharacter::turn(floatamount) { if(inAction()) return; node->rotate(Vector3::UNIT_Y, Radian(amount)); }
void PlayerCharacter::update(float t, float dt) { if(action != lastAction || pose != lastPose) { if(!animations[0]->getLoop() && animations[0]->hasEnded()) pose =PP_STAND; if(!animations[1]->getLoop() && animations[1]->hasEnded()) action = PA_NONE; animations[0]->setEnabled(false); animations[1]->setEnabled(false); animations[0] = 0; animations[1] = 0; if(action == PA_NONE) { if(pose == PP_STAND) animations[1] = entity->getAnimationState("up_stand"); if(pose == PP_RUN) animations[1] = entity->getAnimationState("up_run"); animations[1]->setLoop(true); } elseif(action == PA_WEAPON_HOLD) { animations[1] = entity->getAnimationState("up_weapon_hold"); animations[1]->setLoop(true); } …//következő dia
elseif(action == PA_SHOOT) { animations[1] = entity->getAnimationState("up_shoot"); animations[1]->setLoop(false); animations[1]->setTimePosition(0); } if(pose == PP_STAND) { animations[0] = entity->getAnimationState("leg_stand"); animations[0]->setLoop(true); } elseif(pose == PP_RUN) { animations[0] = entity->getAnimationState("leg_run"); animations[0]->setLoop(true); } if(animations[0]) animations[0]->setEnabled(true); if(animations[1]) animations[1]->setEnabled(true); lastAction = action; lastPose = pose; }
Update vége animations[0]->addTime(dt); animations[1]->addTime(dt); if(!inAction()) action = PA_NONE; pose = PP_STAND; }
Lövésúj publikus függvény void PlayerCharacter::shoot() { if(inAction()) return; action = PA_SHOOT; }
voidPlayerController::update(float t, floatdt, OIS::Keyboard* keyboard, OIS::Mouse* mouse) { … if( ms.buttonDown(OIS::MB_Left)) character->shoot(); }
Fegyvert a kézbe!! classPlayerCharacter { … protected: boolhasWeapon; }; PlayerCharacter::PlayerCharacter(Ogre::SceneManager* sm, NxScene* nxs) { … hasWeapon = true; }
void PlayerCharacter::update(float t, float dt) { … if(!inAction()) { if(hasWeapon) action = PA_WEAPON_HOLD; else action = PA_NONE; } pose = PP_STAND; } voidPlayerCharacter::move(floatamount) { if(inAction()) return; node->translate(amount * Vector3::UNIT_Z, Node::TS_LOCAL); if(hasWeapon) action = PA_WEAPON_HOLD; else action = PA_NONE; pose = PP_RUN; }
De hol a fegyver? classPlayerCharacter { … protected: Ogre::SceneNode* weaponNode; }; PlayerCharacter::PlayerCharacter(Ogre::SceneManager* sm, NxScene* nxs) { … hasWeapon = true; Ogre::Entity* weapon = sm->createEntity("weapon", "rifle.mesh"); weaponNode = node->createChildSceneNode(); Ogre::SceneNode* tempNode = weaponNode->createChildSceneNode(); tempNode->rotate(Ogre::Vector3::UNIT_X, Ogre::Radian(Ogre::Degree(90))); tempNode->attachObject(weapon); }
void PlayerCharacter::update(float t, float dt) { … if(hasWeapon) { weaponNode->setVisible(true); Ogre::Bone* rightHand = entity->getSkeleton()->getBone("hand_r"); weaponNode->setPosition(rightHand->_getDerivedPosition()); weaponNode->setOrientation(rightHand->_getDerivedOrientation()); } else weaponNode->setVisible(false); }
Finomabb kamera mozgás voidThirdPersonCamera::update(float t, floatdt) { Vector3 currentPos = camera->getPosition(); Vector3 dir = character->getDirection(); dir.y = 0; dir.normalise(); dir.y = -camHeight; Vector3 newPos = character->getPosition() - dir * camDist; camera->setPosition(motionBlend * dt * newPos + (1.0f - motionBlend * dt) * currentPos); camera->lookAt(character->getPosition() + Vector3(0,targetHeight,0)); }
Fizika • Új include könyvtár: …\PhysX\SDKs\NxCharacter\include • Új link library NxCharacter.lib • Másoljuk: …\PhysX\Bin\win32\NxCharacter.dll –t bin-be
PlayerCharacter.h … #include "NxCapsuleController.h" classPlayerCharacter { … public: … staticvoidupdateAllCharacters(); … protected.: … NxCapsuleController* mController; };
PlayerCharacter.cpp #include "ControllerManager.h" static ControllerManager gCM; void PlayerCharacter::updateAllCharacters() { gCM.updateControllers(); }
PlayerCharacter::PlayerCharacter() NxCapsuleControllerDesc desc; desc.setToDefault(); desc.radius = 2.0f; desc.height = 5.0f; desc.upDirection = NX_Y; desc.slopeLimit = 0.707; desc.stepOffset = 0.5; desc.skinWidth = 0.1; desc.callback = NULL; desc.position.set(0,5,0); mController = (NxCapsuleController*)gCM.createController(nxs, desc); mController->setCollision(true);
PlayerCharacter::move() { //node->translate(amount * Vector3::UNIT_Z, Node::TS_LOCAL); NxU32 collisionFlags; Ogre::Vector3 m = amount * getDirection(); mController->move(NxVec3(m.x,m.y,m.z), 1, 0.001, collisionFlags); node->setPosition(mController->getPosition().x, mController->getPosition().y - 5, mController->getPosition().z); … }
OgreCharacter.cpp classmainFrameListener { … boolframeStarted(constFrameEvent&evt) { … if(!physxHandler->update(t, dt)) returnfalse; playerCharacter->update(t, dt); TPCamera->update(t, dt); PlayerCharacter::updateAllCharacters(); returntrue; } };