标签:android style blog http os io ar for 2014
/*************************************************** ©2014 Pf_D. All rights reserved. ***************************************************/ #pragma once #include "OGRE\Ogre.h" #include "OIS\OIS.h" using namespace Ogre; #define NUM_ANIMS 13 // number of animations the character has #define CHAR_HEIGHT 5 // height of character‘s center of mass(质心) above ground #define CAM_HEIGHT 2 // height of camera above character‘s center of mass #define RUN_SPEED 17 // character running speed in units per second #define TURN_SPEED 500.0f // character turning in degrees per second #define ANIM_FADE_SPEED 7.5f // animation crossfade speed in % of full weight per second #define JUMP_ACCEL 30.0f // character jump acceleration in upward units per squared second #define GRAVITY 90.0f // gravity in downward units per squared second class SinbadCharacterController { private: // all the animations our character has, and a null ID // some of these affect separate body parts and will be blended together enum AnimID { ANIM_IDLE_BASE, ANIM_IDLE_TOP, ANIM_RUN_BASE, ANIM_RUN_TOP, ANIM_HANDS_CLOSED, ANIM_HANDS_RELAXED, ANIM_DRAW_SWORDS, ANIM_SLICE_VERTICAL, ANIM_SLICE_HORIZONTAL, ANIM_DANCE, ANIM_JUMP_START, ANIM_JUMP_LOOP, ANIM_JUMP_END, ANIM_NONE }; public: SinbadCharacterController(Camera* cam) { setupBody(cam->getSceneManager()); setupCamera(cam); setupAnimations(); } void addTime(Real deltaTime) { updateBody(deltaTime); updateAnimations(deltaTime); updateCamera(deltaTime); } void injectKeyDown(const OIS::KeyEvent& evt) { if (evt.key == OIS::KC_Q && (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP)) { // take swords out (or put them back, since it‘s the same animation but reversed) setTopAnimation(ANIM_DRAW_SWORDS, true); mTimer = 0; } else if (evt.key == OIS::KC_E && !mSwordsDrawn) { if (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP) { // start dancing setBaseAnimation(ANIM_DANCE, true); setTopAnimation(ANIM_NONE); // disable hand animation because the dance controls hands mAnims[ANIM_HANDS_RELAXED]->setEnabled(false); } else if (mBaseAnimID == ANIM_DANCE) { // stop dancing setBaseAnimation(ANIM_IDLE_BASE); setTopAnimation(ANIM_IDLE_TOP); // re-enable hand animation mAnims[ANIM_HANDS_RELAXED]->setEnabled(true); } } // keep track of the player‘s intended direction else if (evt.key == OIS::KC_W) mKeyDirection.z = -1; else if (evt.key == OIS::KC_A) mKeyDirection.x = -1; else if (evt.key == OIS::KC_S) mKeyDirection.z = 1; else if (evt.key == OIS::KC_D) mKeyDirection.x = 1; else if (evt.key == OIS::KC_SPACE && (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP)) { // jump if on ground setBaseAnimation(ANIM_JUMP_START, true); setTopAnimation(ANIM_NONE); mTimer = 0; } if (!mKeyDirection.isZeroLength() && mBaseAnimID == ANIM_IDLE_BASE) { // start running if not already moving and the player wants to move setBaseAnimation(ANIM_RUN_BASE, true); if (mTopAnimID == ANIM_IDLE_TOP) setTopAnimation(ANIM_RUN_TOP, true); } } void injectKeyUp(const OIS::KeyEvent& evt) { // keep track of the player‘s intended direction if (evt.key == OIS::KC_W && mKeyDirection.z == -1) mKeyDirection.z = 0; else if (evt.key == OIS::KC_A && mKeyDirection.x == -1) mKeyDirection.x = 0; else if (evt.key == OIS::KC_S && mKeyDirection.z == 1) mKeyDirection.z = 0; else if (evt.key == OIS::KC_D && mKeyDirection.x == 1) mKeyDirection.x = 0; if (mKeyDirection.isZeroLength() && mBaseAnimID == ANIM_RUN_BASE) { // stop running if already moving and the player doesn‘t want to move setBaseAnimation(ANIM_IDLE_BASE); if (mTopAnimID == ANIM_RUN_TOP) setTopAnimation(ANIM_IDLE_TOP); } } #if (OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS) || (OGRE_PLATFORM == OGRE_PLATFORM_ANDROID) void injectMouseMove(const OIS::MultiTouchEvent& evt) { // update camera goal based on mouse movement updateCameraGoal(-0.05f * evt.state.X.rel, -0.05f * evt.state.Y.rel, -0.0005f * evt.state.Z.rel); } void injectMouseDown(const OIS::MultiTouchEvent& evt) { if (mSwordsDrawn && (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP)) { // if swords are out, and character‘s not doing something weird, then SLICE! setTopAnimation(ANIM_SLICE_VERTICAL, true); mTimer = 0; } } #else void injectMouseMove(const OIS::MouseEvent& evt) { // update camera goal based on mouse movement updateCameraGoal(-0.05f * evt.state.X.rel, -0.05f * evt.state.Y.rel, -0.0005f * evt.state.Z.rel); } void injectMouseDown(const OIS::MouseEvent& evt, OIS::MouseButtonID id) { if (mSwordsDrawn && (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP)) { // if swords are out, and character‘s not doing something weird, then SLICE! if (id == OIS::MB_Left) setTopAnimation(ANIM_SLICE_VERTICAL, true); else if (id == OIS::MB_Right) setTopAnimation(ANIM_SLICE_HORIZONTAL, true); mTimer = 0; } } #endif private: void setupBody(SceneManager* sceneMgr) { // create main model // 让角色踩在平面上 mBodyNode = sceneMgr->getRootSceneNode()->createChildSceneNode(Vector3::UNIT_Y * CHAR_HEIGHT); mBodyEnt = sceneMgr->createEntity("SinbadBody", "Sinbad.mesh"); mBodyNode->attachObject(mBodyEnt); // create swords and attach to sheath LogManager::getSingleton().logMessage("Creating swords"); mSword1 = sceneMgr->createEntity("SinbadSword1", "Sword.mesh"); mSword2 = sceneMgr->createEntity("SinbadSword2", "Sword.mesh"); mBodyEnt->attachObjectToBone("Sheath.L", mSword1); mBodyEnt->attachObjectToBone("Sheath.R", mSword2); LogManager::getSingleton().logMessage("Creating the chains"); // create a couple of ribbon trails for the swords, just for fun NameValuePairList params; params["numberOfChains"] = "2"; params["maxElements"] = "80"; mSwordTrail = (RibbonTrail*)sceneMgr->createMovableObject("RibbonTrail", ¶ms); mSwordTrail->setMaterialName("Examples/LightRibbonTrail"); mSwordTrail->setTrailLength(20); mSwordTrail->setVisible(false); sceneMgr->getRootSceneNode()->attachObject(mSwordTrail); for (int i = 0; i < 2; i++) { mSwordTrail->setInitialColour(i, 1, 0.8, 0); mSwordTrail->setColourChange(i, 0.75, 1.25, 1.25, 1.25); mSwordTrail->setWidthChange(i, 1); mSwordTrail->setInitialWidth(i, 0.5); } mKeyDirection = Vector3::ZERO; mVerticalVelocity = 0; } void setupAnimations() { // this is very important due to the nature of the exported animations mBodyEnt->getSkeleton()->setBlendMode(ANIMBLEND_CUMULATIVE); String animNames[] = {"IdleBase", "IdleTop", "RunBase", "RunTop", "HandsClosed", "HandsRelaxed", "DrawSwords", "SliceVertical", "SliceHorizontal", "Dance", "JumpStart", "JumpLoop", "JumpEnd"}; // populate our animation list for (int i = 0; i < NUM_ANIMS; i++) { mAnims[i] = mBodyEnt->getAnimationState(animNames[i]); mAnims[i]->setLoop(true); mFadingIn[i] = false; mFadingOut[i] = false; } // start off in the idle state (top and bottom together) setBaseAnimation(ANIM_IDLE_BASE); setTopAnimation(ANIM_IDLE_TOP); // relax the hands since we‘re not holding anything mAnims[ANIM_HANDS_RELAXED]->setEnabled(true); mSwordsDrawn = false; } void setupCamera(Camera* cam) { // create a pivot at roughly the character‘s shoulder mCameraPivot = cam->getSceneManager()->getRootSceneNode()->createChildSceneNode(); // this is where the camera should be soon, and it spins around the pivot mCameraGoal = mCameraPivot->createChildSceneNode(Vector3(0, 0, 15)); // this is where the camera actually is mCameraNode = cam->getSceneManager()->getRootSceneNode()->createChildSceneNode(); mCameraNode->setPosition(mCameraPivot->getPosition() + mCameraGoal->getPosition()); mCameraPivot->setFixedYawAxis(true); mCameraGoal->setFixedYawAxis(true); mCameraNode->setFixedYawAxis(true); // our model is quite small, so reduce the clipping planes cam->setNearClipDistance(0.1); cam->setFarClipDistance(100); mCameraNode->attachObject(cam); mPivotPitch = 0; } void updateBody(Real deltaTime) { mGoalDirection = Vector3::ZERO; // we will calculate this if (mKeyDirection != Vector3::ZERO && mBaseAnimID != ANIM_DANCE) { // calculate actually goal direction in world based on player‘s key directions mGoalDirection += mKeyDirection.z * mCameraNode->getOrientation().zAxis(); mGoalDirection += mKeyDirection.x * mCameraNode->getOrientation().xAxis(); mGoalDirection.y = 0; mGoalDirection.normalise(); Quaternion toGoal = mBodyNode->getOrientation().zAxis().getRotationTo(mGoalDirection); // calculate how much the character has to turn to face goal direction Real yawToGoal = toGoal.getYaw().valueDegrees(); // this is how much the character CAN turn this frame Real yawAtSpeed = yawToGoal / Math::Abs(yawToGoal) * deltaTime * TURN_SPEED; // reduce "turnability" if we‘re in midair if (mBaseAnimID == ANIM_JUMP_LOOP) yawAtSpeed *= 0.2f; // turn as much as we can, but not more than we need to if (yawToGoal < 0) yawToGoal = std::min<Real>(0, std::max<Real>(yawToGoal, yawAtSpeed)); //yawToGoal = Math::Clamp<Real>(yawToGoal, yawAtSpeed, 0); else if (yawToGoal > 0) yawToGoal = std::max<Real>(0, std::min<Real>(yawToGoal, yawAtSpeed)); //yawToGoal = Math::Clamp<Real>(yawToGoal, 0, yawAtSpeed); mBodyNode->yaw(Degree(yawToGoal)); // move in current body direction (not the goal direction) mBodyNode->translate(0, 0, deltaTime * RUN_SPEED * mAnims[mBaseAnimID]->getWeight(), Node::TS_LOCAL); } if (mBaseAnimID == ANIM_JUMP_LOOP) { // if we‘re jumping, add a vertical offset too, and apply gravity mBodyNode->translate(0, mVerticalVelocity * deltaTime, 0, Node::TS_LOCAL); mVerticalVelocity -= GRAVITY * deltaTime; Vector3 pos = mBodyNode->getPosition(); if (pos.y <= CHAR_HEIGHT) { // if we‘ve hit the ground, change to landing state pos.y = CHAR_HEIGHT; mBodyNode->setPosition(pos); setBaseAnimation(ANIM_JUMP_END, true); mTimer = 0; } } } void updateAnimations(Real deltaTime) { Real baseAnimSpeed = 1; Real topAnimSpeed = 1; mTimer += deltaTime; if (mTopAnimID == ANIM_DRAW_SWORDS) { // flip the draw swords animation if we need to put it back topAnimSpeed = mSwordsDrawn ? -1 : 1; // half-way through the animation is when the hand grasps the handles... if (mTimer >= mAnims[mTopAnimID]->getLength() / 2 && mTimer - deltaTime < mAnims[mTopAnimID]->getLength() / 2) { // so transfer the swords from the sheaths to the hands mBodyEnt->detachAllObjectsFromBone(); mBodyEnt->attachObjectToBone(mSwordsDrawn ? "Sheath.L" : "Handle.L", mSword1); mBodyEnt->attachObjectToBone(mSwordsDrawn ? "Sheath.R" : "Handle.R", mSword2); // change the hand state to grab or let go mAnims[ANIM_HANDS_CLOSED]->setEnabled(!mSwordsDrawn); mAnims[ANIM_HANDS_RELAXED]->setEnabled(mSwordsDrawn); // toggle sword trails if (mSwordsDrawn) { mSwordTrail->setVisible(false); mSwordTrail->removeNode(mSword1->getParentNode()); mSwordTrail->removeNode(mSword2->getParentNode()); } else { mSwordTrail->setVisible(true); mSwordTrail->addNode(mSword1->getParentNode()); mSwordTrail->addNode(mSword2->getParentNode()); } } if (mTimer >= mAnims[mTopAnimID]->getLength()) { // animation is finished, so return to what we were doing before if (mBaseAnimID == ANIM_IDLE_BASE) setTopAnimation(ANIM_IDLE_TOP); else { setTopAnimation(ANIM_RUN_TOP); mAnims[ANIM_RUN_TOP]->setTimePosition(mAnims[ANIM_RUN_BASE]->getTimePosition()); } mSwordsDrawn = !mSwordsDrawn; } } else if (mTopAnimID == ANIM_SLICE_VERTICAL || mTopAnimID == ANIM_SLICE_HORIZONTAL) { if (mTimer >= mAnims[mTopAnimID]->getLength()) { // animation is finished, so return to what we were doing before if (mBaseAnimID == ANIM_IDLE_BASE) setTopAnimation(ANIM_IDLE_TOP); else { setTopAnimation(ANIM_RUN_TOP); mAnims[ANIM_RUN_TOP]->setTimePosition(mAnims[ANIM_RUN_BASE]->getTimePosition()); } } // don‘t sway hips from side to side when slicing. that‘s just embarrassing. if (mBaseAnimID == ANIM_IDLE_BASE) baseAnimSpeed = 0; } else if (mBaseAnimID == ANIM_JUMP_START) { if (mTimer >= mAnims[mBaseAnimID]->getLength()) { // takeoff animation finished, so time to leave the ground! setBaseAnimation(ANIM_JUMP_LOOP, true); // apply a jump acceleration to the character mVerticalVelocity = JUMP_ACCEL; } } else if (mBaseAnimID == ANIM_JUMP_END) { if (mTimer >= mAnims[mBaseAnimID]->getLength()) { // safely landed, so go back to running or idling if (mKeyDirection == Vector3::ZERO) { setBaseAnimation(ANIM_IDLE_BASE); setTopAnimation(ANIM_IDLE_TOP); } else { setBaseAnimation(ANIM_RUN_BASE, true); setTopAnimation(ANIM_RUN_TOP, true); } } } // increment the current base and top animation times if (mBaseAnimID != ANIM_NONE) mAnims[mBaseAnimID]->addTime(deltaTime * baseAnimSpeed); if (mTopAnimID != ANIM_NONE) mAnims[mTopAnimID]->addTime(deltaTime * topAnimSpeed); // apply smooth transitioning between our animations fadeAnimations(deltaTime); } void fadeAnimations(Real deltaTime) { for (int i = 0; i < NUM_ANIMS; i++) { if (mFadingIn[i]) { // slowly fade this animation in until it has full weight Real newWeight = mAnims[i]->getWeight() + deltaTime * ANIM_FADE_SPEED; mAnims[i]->setWeight(Math::Clamp<Real>(newWeight, 0, 1)); if (newWeight >= 1) mFadingIn[i] = false; } else if (mFadingOut[i]) { // slowly fade this animation out until it has no weight, and then disable it Real newWeight = mAnims[i]->getWeight() - deltaTime * ANIM_FADE_SPEED; mAnims[i]->setWeight(Math::Clamp<Real>(newWeight, 0, 1)); if (newWeight <= 0) { mAnims[i]->setEnabled(false); mFadingOut[i] = false; } } } } void updateCamera(Real deltaTime) { // place the camera pivot roughly at the character‘s shoulder mCameraPivot->setPosition(mBodyNode->getPosition() + Vector3::UNIT_Y * CAM_HEIGHT); // move the camera smoothly to the goal Vector3 goalOffset = mCameraGoal->_getDerivedPosition() - mCameraNode->getPosition(); mCameraNode->translate(goalOffset * deltaTime * 9.0f); // always look at the pivot mCameraNode->lookAt(mCameraPivot->_getDerivedPosition(), Node::TS_WORLD); } void updateCameraGoal(Real deltaYaw, Real deltaPitch, Real deltaZoom) { mCameraPivot->yaw(Degree(deltaYaw), Node::TS_WORLD); // bound the pitch if (!(mPivotPitch + deltaPitch > 25 && deltaPitch > 0) && !(mPivotPitch + deltaPitch < -60 && deltaPitch < 0)) { mCameraPivot->pitch(Degree(deltaPitch), Node::TS_LOCAL); mPivotPitch += deltaPitch; } Real dist = mCameraGoal->_getDerivedPosition().distance(mCameraPivot->_getDerivedPosition()); Real distChange = deltaZoom * dist; // bound the zoom if (!(dist + distChange < 8 && distChange < 0) && !(dist + distChange > 25 && distChange > 0)) { mCameraGoal->translate(0, 0, distChange, Node::TS_LOCAL); } } void setBaseAnimation(AnimID id, bool reset = false) { if (mBaseAnimID >= 0 && mBaseAnimID < NUM_ANIMS) { // if we have an old animation, fade it out mFadingIn[mBaseAnimID] = false; mFadingOut[mBaseAnimID] = true; } mBaseAnimID = id; if (id != ANIM_NONE) { // if we have a new animation, enable it and fade it in mAnims[id]->setEnabled(true); mAnims[id]->setWeight(0); mFadingOut[id] = false; mFadingIn[id] = true; if (reset) mAnims[id]->setTimePosition(0); } } void setTopAnimation(AnimID id, bool reset = false) { if (mTopAnimID >= 0 && mTopAnimID < NUM_ANIMS) { // if we have an old animation, fade it out mFadingIn[mTopAnimID] = false; mFadingOut[mTopAnimID] = true; } mTopAnimID = id; if (id != ANIM_NONE) { // if we have a new animation, enable it and fade it in mAnims[id]->setEnabled(true); mAnims[id]->setWeight(0); mFadingOut[id] = false; mFadingIn[id] = true; if (reset) mAnims[id]->setTimePosition(0); } } SceneNode* mBodyNode; SceneNode* mCameraPivot; SceneNode* mCameraGoal; SceneNode* mCameraNode; Real mPivotPitch; Entity* mBodyEnt; Entity* mSword1; Entity* mSword2; RibbonTrail* mSwordTrail; AnimationState* mAnims[NUM_ANIMS]; // master animation list AnimID mBaseAnimID; // current base (full- or lower-body) animation AnimID mTopAnimID; // current top (upper-body) animation bool mFadingIn[NUM_ANIMS]; // which animations are fading in bool mFadingOut[NUM_ANIMS]; // which animations are fading out bool mSwordsDrawn; Vector3 mKeyDirection; // player‘s local intended direction based on WASD keys Vector3 mGoalDirection; // actual intended direction in world-space Real mVerticalVelocity; // for jumping Real mTimer; // general timer to see how long animations have been playing };
/*************************************************** ©2014 Pf_D. All rights reserved. ***************************************************/ #pragma once #include "OGRE\Ogre.h" #include "OIS\OIS.h" enum CameraStyle { CS_FREELOOK, CS_ORBIT, CS_MANUAL }; class cCameraManager { private: Ogre::Camera *mCamera; CameraStyle mStyle; Ogre::SceneNode *mTarget; bool mOrbiting; bool mZooming; Ogre::Real mTopSpeed; Ogre::Vector3 mVelocity; bool mGoingForward; bool mGoingBack; bool mGoingLeft; bool mGoingRight; bool mGoingUp; bool mGoingDown; bool mFastMove; public: cCameraManager(Ogre::Camera *cam); void setCamera(Ogre::Camera *cam); Ogre::Camera *getCamera(); void manualStop(); void setStyle(CameraStyle style); CameraStyle getStyle(); void setYawPitchDist(Ogre::Radian yaw, Ogre::Radian pitch, Ogre::Real dist); void setTarget(Ogre::SceneNode *target); Ogre::SceneNode *getTarget(); void setTopSpeed(Ogre::Real topSpeed); Ogre::Real getTopSpeed(); bool frameRenderingQueued(const Ogre::FrameEvent& evt); // Processes key press for free-look style movement. void injectKeyDown(const OIS::KeyEvent &evt); void injectKeyUp(const OIS::KeyEvent &evt); // Processes mouse movement differently for each style. void injectMouseMove(const OIS::MouseEvent &evt); // Processes mouse presses. Only applies for orbit style. // Left button is for orbiting, and right button is for zooming. void injectMouseDown(const OIS::MouseEvent &evt, OIS::MouseButtonID id); void injectMouseUp(const OIS::MouseEvent &evt, OIS::MouseButtonID id); };
/*************************************************** ©2014 Pf_D. All rights reserved. ***************************************************/ #include "Graphics.h" cCameraManager::cCameraManager(Ogre::Camera *cam) :mCamera(0), mStyle(CameraStyle::CS_FREELOOK), mTarget(0), mOrbiting(false), mZooming(false), mTopSpeed(150), mVelocity(Ogre::Vector3::ZERO), mGoingForward(false), mGoingBack(false), mGoingLeft(false), mGoingRight(false), mGoingUp(false), mGoingDown(false), mFastMove(false) { setCamera(cam); setStyle(CS_FREELOOK); } void cCameraManager::setCamera(Ogre::Camera *cam) { mCamera = cam; } Ogre::Camera *cCameraManager::getCamera() { return mCamera; } void cCameraManager::setYawPitchDist(Ogre::Radian yaw, Ogre::Radian pitch, Ogre::Real dist) { mCamera->setPosition(mTarget->_getDerivedPosition()); mCamera->setOrientation(mTarget->_getDerivedOrientation()); mCamera->yaw(yaw); mCamera->pitch(pitch); mCamera->moveRelative(Ogre::Vector3(0, 0, dist)); } void cCameraManager::setTarget(Ogre::SceneNode *target) { if(target != mTarget) { mTarget = target; if(target) { setYawPitchDist(Ogre::Degree(0), Ogre::Degree(15), 150); mCamera->setAutoTracking(true, mTarget); } else mCamera->setAutoTracking(false); } } Ogre::SceneNode *cCameraManager::getTarget() { return mTarget; } void cCameraManager::manualStop() { if(mStyle == CS_FREELOOK) { mVelocity = Ogre::Vector3::ZERO; mGoingForward = false; mGoingBack = false; mGoingLeft = false; mGoingRight = false; mGoingUp = false; mGoingDown = false; } } void cCameraManager::setStyle(CameraStyle style) { if(mStyle != CS_ORBIT && style == CS_ORBIT) { setTarget(mTarget ? mTarget : mCamera->getSceneManager()->getRootSceneNode()); mCamera->setFixedYawAxis(true); manualStop(); setYawPitchDist(Ogre::Degree(0), Ogre::Degree(15), 150); } else if(mStyle != CS_FREELOOK && style == CS_FREELOOK) { mCamera->setAutoTracking(false); mCamera->setFixedYawAxis(true); } else if(mStyle != CS_MANUAL && style == CS_MANUAL) { mCamera->setAutoTracking(false); manualStop(); } mStyle = style; } CameraStyle cCameraManager::getStyle() { return mStyle; } void cCameraManager::setTopSpeed(Ogre::Real topSpeed) { mTopSpeed = topSpeed; } Ogre::Real cCameraManager::getTopSpeed() { return mTopSpeed; } bool cCameraManager::frameRenderingQueued(const Ogre::FrameEvent& evt) { if (mStyle == CS_FREELOOK) { // build our acceleration vector based on keyboard input composite Ogre::Vector3 accel = Ogre::Vector3::ZERO; if (mGoingForward) accel += mCamera->getDirection(); if (mGoingBack) accel -= mCamera->getDirection(); if (mGoingRight) accel += mCamera->getRight(); if (mGoingLeft) accel -= mCamera->getRight(); if (mGoingUp) accel += mCamera->getUp(); if (mGoingDown) accel -= mCamera->getUp(); // if accelerating, try to reach top speed in a certain time Ogre::Real topSpeed = mFastMove ? mTopSpeed * 20 : mTopSpeed; if (accel.squaredLength() != 0) { accel.normalise(); mVelocity += accel * topSpeed * evt.timeSinceLastFrame * 10; } // if not accelerating, try to stop in a certain time else mVelocity -= mVelocity * evt.timeSinceLastFrame * 10; Ogre::Real tooSmall = std::numeric_limits<Ogre::Real>::epsilon(); // keep camera velocity below top speed and above epsilon if (mVelocity.squaredLength() > topSpeed * topSpeed) { mVelocity.normalise(); mVelocity *= topSpeed; } else if (mVelocity.squaredLength() < tooSmall * tooSmall) mVelocity = Ogre::Vector3::ZERO; if (mVelocity != Ogre::Vector3::ZERO) mCamera->move(mVelocity * evt.timeSinceLastFrame); } return true; } void cCameraManager::injectKeyDown(const OIS::KeyEvent &evt) { if(mStyle != CS_FREELOOK) return; if (evt.key == OIS::KC_W || evt.key == OIS::KC_UP) mGoingForward = true; else if (evt.key == OIS::KC_S || evt.key == OIS::KC_DOWN) mGoingBack = true; else if (evt.key == OIS::KC_A || evt.key == OIS::KC_LEFT) mGoingLeft = true; else if (evt.key == OIS::KC_D || evt.key == OIS::KC_RIGHT) mGoingRight = true; else if (evt.key == OIS::KC_PGUP) mGoingUp = true; else if (evt.key == OIS::KC_PGDOWN) mGoingDown = true; else if (evt.key == OIS::KC_LSHIFT) mFastMove = true; } void cCameraManager::injectKeyUp(const OIS::KeyEvent &evt) { if(mStyle != CS_FREELOOK) return; if (evt.key == OIS::KC_W || evt.key == OIS::KC_UP) mGoingForward = false; else if (evt.key == OIS::KC_S || evt.key == OIS::KC_DOWN) mGoingBack = false; else if (evt.key == OIS::KC_A || evt.key == OIS::KC_LEFT) mGoingLeft = false; else if (evt.key == OIS::KC_D || evt.key == OIS::KC_RIGHT) mGoingRight = false; else if (evt.key == OIS::KC_PGUP) mGoingUp = false; else if (evt.key == OIS::KC_PGDOWN) mGoingDown = false; else if (evt.key == OIS::KC_LSHIFT) mFastMove = false; } void cCameraManager::injectMouseMove(const OIS::MouseEvent &evt) { if (mStyle == CS_ORBIT) { Ogre::Real dist = (mCamera->getPosition() - mTarget->_getDerivedPosition()).length(); if (mOrbiting) // yaw around the target, and pitch locally { mCamera->setPosition(mTarget->_getDerivedPosition()); mCamera->yaw(Ogre::Degree(-evt.state.X.rel * 0.25f)); mCamera->pitch(Ogre::Degree(-evt.state.Y.rel * 0.25f)); mCamera->moveRelative(Ogre::Vector3(0, 0, dist)); // don‘t let the camera go over the top or around the bottom of the target } else if (mZooming) // move the camera toward or away from the target { // the further the camera is, the faster it moves mCamera->moveRelative(Ogre::Vector3(0, 0, evt.state.Y.rel * 0.004f * dist)); } else if (evt.state.Z.rel != 0) // move the camera toward or away from the target { // the further the camera is, the faster it moves mCamera->moveRelative(Ogre::Vector3(0, 0, -evt.state.Z.rel * 0.0008f * dist)); } } else if (mStyle == CS_FREELOOK) { mCamera->yaw(Ogre::Degree(-evt.state.X.rel * 0.15f)); mCamera->pitch(Ogre::Degree(-evt.state.Y.rel * 0.15f)); } } void cCameraManager::injectMouseDown(const OIS::MouseEvent &evt, OIS::MouseButtonID id) { if (mStyle == CS_ORBIT) { if (id == OIS::MB_Left) mOrbiting = true; else if (id == OIS::MB_Right) mZooming = true; } } void cCameraManager::injectMouseUp(const OIS::MouseEvent &evt, OIS::MouseButtonID id) { if (mStyle == CS_ORBIT) { if (id == OIS::MB_Left) mOrbiting = false; else if (id == OIS::MB_Right) mZooming = false; } }
/*************************************************** ©2014 Pf_D. All rights reserved. ***************************************************/ #pragma once #include "Graphics.h" #include "OGRE\Ogre.h" #include "OIS\OIS.h" #include "MyGUI.h" #include "MyGUI_OgrePlatform.h" class cApplication : public Ogre::FrameListener, public OIS::KeyListener, public OIS::MouseListener { protected: MyGUI::Gui *mGUI; MyGUI::OgrePlatform *mPlatform; Ogre::Root *mRoot; Ogre::RenderWindow *mWindow; Ogre::SceneManager *mSceneMgr; Ogre::Camera *mCamera; Ogre::Viewport *mVp; cCameraManager *mCameraMgr; OIS::InputManager *mInputMgr; OIS::Keyboard *mKeyboard; OIS::Mouse *mMouse; bool mDragLook; public: cApplication() :mDragLook(false) { } virtual bool frameStarted(const Ogre::FrameEvent &evt); virtual bool frameRenderingQueued(const Ogre::FrameEvent &evt); virtual bool frameEnded(const Ogre::FrameEvent &evt); virtual bool keyPressed(const OIS::KeyEvent &arg); virtual bool keyReleased(const OIS::KeyEvent &arg); virtual bool mouseMoved(const OIS::MouseEvent &arg); virtual bool mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id); virtual bool mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id); virtual void setupResources(); virtual void createInput(); virtual void chooseSceneMgr(); virtual void setupView(); virtual void loadResources(); virtual void createScene() {} bool setup(); void go(); void setDragLook(bool enabled); };
/*************************************************** ©2014 Pf_D. All rights reserved. ***************************************************/ #include "System.h" bool cApplication::frameStarted(const Ogre::FrameEvent &evt) { mKeyboard->capture(); mMouse->capture(); return true; } bool cApplication::frameRenderingQueued(const Ogre::FrameEvent &evt) { mCameraMgr->frameRenderingQueued(evt); return true; } bool cApplication::frameEnded(const Ogre::FrameEvent &evt) { return true; } bool cApplication::keyPressed(const OIS::KeyEvent &arg) { if(arg.key == OIS::KC_ESCAPE) exit(0); MyGUI::InputManager::getInstance().injectKeyPress( MyGUI::KeyCode::Enum(arg.key), arg.text); mCameraMgr->injectKeyDown(arg); // ... return true; } bool cApplication::keyReleased(const OIS::KeyEvent &arg) { MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(arg.key)); mCameraMgr->injectKeyUp(arg); // ... return true; } bool cApplication::mouseMoved( const OIS::MouseEvent &arg ) { bool ret = MyGUI::InputManager::getInstance().injectMouseMove( arg.state.X.abs, arg.state.Y.abs, arg.state.Z.abs); if(!ret) mCameraMgr->injectMouseMove(arg); // ... return true; } bool cApplication::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id ) { bool ret = MyGUI::InputManager::getInstance().injectMousePress( arg.state.X.abs, arg.state.Y.abs, MyGUI::MouseButton::Enum(id)); if(!ret) mCameraMgr->injectMouseDown(arg, id); if(mDragLook && id == OIS::MB_Left) { mCameraMgr->setStyle(CS_FREELOOK); MyGUI::Gui::getInstance().hidePointer(); } // ... return true; } bool cApplication::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id ) { bool ret = MyGUI::InputManager::getInstance().injectMouseRelease( arg.state.X.abs, arg.state.Y.abs, MyGUI::MouseButton::Enum(id)); if(!ret) mCameraMgr->injectMouseUp(arg, id); if(mDragLook && id == OIS::MB_Left) { mCameraMgr->setStyle(CS_MANUAL); MyGUI::Gui::getInstance().showPointer(); } // ... return true; } void cApplication::setupResources() { Ogre::ConfigFile cf; #if OGRE_DEBUG_MODE cf.load("resources_d.cfg"); #else cf.load("resources.cfg"); #endif Ogre::ConfigFile::SectionIterator secIter = cf.getSectionIterator(); Ogre::String secName, typeName, archName; while(secIter.hasMoreElements()) { secName = secIter.peekNextKey(); Ogre::ConfigFile::SettingsMultiMap *settings = secIter.getNext(); Ogre::ConfigFile::SettingsMultiMap::iterator i; for(i=settings->begin(); i!=settings->end(); i++) { typeName = i->first; archName = i->second; Ogre::ResourceGroupManager::getSingleton().addResourceLocation( archName, typeName, secName); } } } void cApplication::createInput() { OIS::ParamList parameters; unsigned int windowHandle = 0; std::ostringstream windowHandleString; mWindow->getCustomAttribute("WINDOW", &windowHandle); windowHandleString << windowHandle; parameters.insert(std::make_pair("WINDOW", windowHandleString.str())); parameters.insert(std::make_pair("w32_mouse", std::string("DISCL_FOREGROUND"))); parameters.insert(std::make_pair("w32_mouse", std::string("DISCL_NONEXCLUSIVE"))); mInputMgr = OIS::InputManager::createInputSystem(parameters); mKeyboard = static_cast<OIS::Keyboard*>(mInputMgr->createInputObject(OIS::OISKeyboard, true)); mKeyboard->setEventCallback(this); mMouse = static_cast<OIS::Mouse*>(mInputMgr->createInputObject(OIS::OISMouse, true)); const OIS::MouseState &mouseState = mMouse->getMouseState(); mouseState.width = mWindow->getWidth(); mouseState.height = mWindow->getHeight(); mMouse->setEventCallback(this); } void cApplication::chooseSceneMgr() { mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC); } void cApplication::setupView() { // Create camera mCamera = mSceneMgr->createCamera("Camera"); //mCamera->setPosition(Ogre::Vector3(0, 0, 50)); //mCamera->lookAt(Ogre::Vector3(0, 0, -300)); mCamera->setNearClipDistance(5); mCameraMgr = new cCameraManager(mCamera); // Create viewports mVp = mWindow->addViewport(mCamera); mVp->setBackgroundColour(Ogre::ColourValue(0, 0, 0)); mCamera->setAspectRatio(Ogre::Real(mVp->getActualWidth())/Ogre::Real(mVp->getActualHeight())); } void cApplication::loadResources() { Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); } bool cApplication::setup() { #ifndef OGRE_STATIC_LIB #if OGRE_DEBUG_MODE mRoot = OGRE_NEW Ogre::Root("plugins_d.cfg"); #else mRoot = OGRE_NEW Ogre::Root("plugins.cfg"); #endif #endif setupResources(); if(!mRoot->showConfigDialog()) return false; mWindow = mRoot->initialise(true); createInput(); ShowCursor(false); chooseSceneMgr(); setupView(); loadResources(); createScene(); mRoot->addFrameListener(this); return true; } void cApplication::go() { if(!setup()) return; mRoot->startRendering(); } void cApplication::setDragLook(bool enabled) { if(enabled) { mCameraMgr->setStyle(CS_MANUAL); mDragLook = true; } else { mCameraMgr->setStyle(CS_FREELOOK); mDragLook = false; } }
/*************************************************** ©2014 Pf_D. All rights reserved. ***************************************************/ #include "System.h" #include "SinbadCharacterController.h" class cMyApplication : public cApplication { private: SinbadCharacterController* mChara; public: bool frameRenderingQueued(const Ogre::FrameEvent &evt) { mChara->addTime(evt.timeSinceLastFrame); return cApplication::frameRenderingQueued(evt); } bool keyPressed(const OIS::KeyEvent &arg) { mChara->injectKeyDown(arg); return cApplication::keyPressed(arg); } bool keyReleased(const OIS::KeyEvent &arg) { mChara->injectKeyUp(arg); return cApplication::keyReleased(arg); } bool mouseMoved(const OIS::MouseEvent &arg) { mChara->injectMouseMove(arg); return cApplication::mouseMoved(arg); } bool mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id) { mChara->injectMouseDown(arg, id); return cApplication::mousePressed(arg, id); } void createScene() { // MyGUI mPlatform = new MyGUI::OgrePlatform(); mPlatform->initialise(mWindow, mSceneMgr); mGUI = new MyGUI::Gui(); mGUI->initialise(); MyGUI::Gui::getInstance().hidePointer(); // set background and some fog mVp->setBackgroundColour(Ogre::ColourValue(1.0f, 1.0f, 0.8f)); mSceneMgr->setFog(Ogre::FOG_LINEAR, Ogre::ColourValue(1.0f, 1.0f, 0.8f), 0, 15, 100); // set shadow properties mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_TEXTURE_MODULATIVE); mSceneMgr->setShadowColour(Ogre::ColourValue(0.5, 0.5, 0.5)); mSceneMgr->setShadowTextureSize(1024); mSceneMgr->setShadowTextureCount(1); // disable default camera control so the character can do its own mCameraMgr->setStyle(CS_MANUAL); // use a small amount of ambient lighting mSceneMgr->setAmbientLight(Ogre::ColourValue(0.3, 0.3, 0.3)); // add a bright light above the scene Ogre::Light* light = mSceneMgr->createLight(); light->setType(Ogre::Light::LT_POINT); light->setPosition(-10, 40, 20); light->setSpecularColour(Ogre::ColourValue::White); // create a floor mesh resource Ogre::MeshManager::getSingleton().createPlane("floor", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::Plane(Ogre::Vector3::UNIT_Y, 0), 100, 100, 10, 10, true, 1, 10, 10, Ogre::Vector3::UNIT_Z); // create a floor entity, give it a material, and place it at the origin Ogre::Entity* floor = mSceneMgr->createEntity("Floor", "floor"); floor->setMaterialName("Examples/Rockwall"); floor->setCastShadows(false); mSceneMgr->getRootSceneNode()->attachObject(floor); mChara = new SinbadCharacterController(mCamera); } }; int main() { cMyApplication App; App.go(); return 0; }
标签:android style blog http os io ar for 2014
原文地址:http://www.cnblogs.com/mynamepfd/p/3949769.html