标签: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