ogre SdkCameraMan code to mogre source

andyhebear1

04-02-2013 06:52:07

mogre SdkCameraMan.cs c# code:
use it very simple

class OgreBites {
enum CameraStyle : byte { // enumerator values for different styles of camera movement
/// <summary>
/// 自由
/// </summary>
CS_FREELOOK,
/// <summary>
/// 轨迹
/// </summary>
CS_ORBIT,
/// <summary>
/// 手动
/// </summary>
CS_MANUAL
}
//Utility class for controlling the camera in samples.
//write by: rains
//blog : http://hi.baidu.com/rainssoft
//web : http://www.masswig.com
//mail : andyhebear#gmail.com , andyhebear#hotmail.com
class SdkCameraMan {
public SdkCameraMan(Camera cam) {
//
mCamera = null;
mTarget = null;
mOrbiting = (false);
mZooming = (false);
mTopSpeed = (150);
mVelocity = (Vector3.ZERO);
mGoingForward = (false);
mGoingBack = (false);
mGoingLeft = (false);
mGoingRight = (false);
mGoingUp = (false);
mGoingDown = (false);
mFastMove = (false);

setCamera(cam);
setStyle(CS_FREELOOK);
}
~SdkCameraMan() { }
CameraStyle CS_FREELOOK = CameraStyle.CS_FREELOOK;
CameraStyle CS_MANUAL = CameraStyle.CS_MANUAL;
CameraStyle CS_ORBIT = CameraStyle.CS_ORBIT;
//
Camera mCamera;
CameraStyle mStyle;
SceneNode mTarget;
bool mOrbiting;
bool mZooming;
float mTopSpeed;
Vector3 mVelocity;
bool mGoingForward;
bool mGoingBack;
bool mGoingLeft;
bool mGoingRight;
bool mGoingUp;
bool mGoingDown;
bool mFastMove;
/*-----------------------------------------------------------------------------
| Swaps the camera on our camera man for another camera.
-----------------------------------------------------------------------------*/
public virtual void setCamera(Camera cam) {
mCamera = cam;
}

public virtual Camera getCamera() {
return mCamera;
}

/*-----------------------------------------------------------------------------
| Sets the target we will revolve around. Only applies for orbit style.
-----------------------------------------------------------------------------*/
public virtual void setTarget(SceneNode target) {
if (target != mTarget) {
mTarget = target;
if (target != null) {
setYawPitchDist(new Degree(0), new Degree(15), 150);
mCamera.SetAutoTracking(true, mTarget);
}
else {
mCamera.SetAutoTracking(false);
}
}
}

public virtual SceneNode getTarget() {
return mTarget;
}

/*-----------------------------------------------------------------------------
| Sets the spatial offset from the target. Only applies for orbit style.
-----------------------------------------------------------------------------*/
public virtual void setYawPitchDist(Radian yaw, Radian pitch, float dist) {
Vector3 tpos = mTarget._getDerivedPosition();
mCamera.SetPosition(tpos.x, tpos.y, tpos.z);
mCamera.Orientation = (mTarget._getDerivedOrientation());
mCamera.Yaw(yaw);
mCamera.Pitch(-pitch);
mCamera.MoveRelative(new Vector3(0, 0, dist));
}
/*-----------------------------------------------------------------------------
| Sets the camera's top speed. Only applies for free-look style.
-----------------------------------------------------------------------------*/
public virtual void setTopSpeed(float topSpeed) {
mTopSpeed = topSpeed;
}

public virtual float getTopSpeed() {
return mTopSpeed;
}

/*-----------------------------------------------------------------------------
| Sets the movement style of our camera man.
-----------------------------------------------------------------------------*/
public virtual void setStyle(CameraStyle style) {
if (mStyle != CS_ORBIT && style == CS_ORBIT) {
setTarget(mTarget != null ? mTarget : mCamera.SceneManager.RootSceneNode);
mCamera.SetFixedYawAxis(true);
manualStop();
setYawPitchDist(new Degree(0), new 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;
}
public virtual CameraStyle getStyle() {
return mStyle;
}

/*-----------------------------------------------------------------------------
| Manually stops the camera when in free-look mode.
-----------------------------------------------------------------------------*/
public virtual void manualStop() {
if (mStyle == CS_FREELOOK) {
mGoingForward = false;
mGoingBack = false;
mGoingLeft = false;
mGoingRight = false;
mGoingUp = false;
mGoingDown = false;
mVelocity = Vector3.ZERO;
}
}

public virtual bool frameRenderingQueued(Mogre.FrameEvent evt) {
if (mStyle == CS_FREELOOK) {
// build our acceleration vector based on keyboard input composite
Vector3 accel = Vector3.ZERO;
if (mGoingForward) accel += mCamera.Direction;
if (mGoingBack) accel -= mCamera.Direction;
if (mGoingRight) accel += mCamera.Right;
if (mGoingLeft) accel -= mCamera.Right;
if (mGoingUp) accel += mCamera.Up;
if (mGoingDown) accel -= mCamera.Up;

// if accelerating, try to reach top speed in a certain time
float topSpeed = mFastMove ? mTopSpeed * 20 : mTopSpeed;
if (accel.SquaredLength != 0) {
accel.Normalise();
accel = accel.NormalisedCopy;
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();
float tooSmall = float.Epsilon;//0.005f;
// keep camera velocity below top speed and above epsilon
if (mVelocity.SquaredLength > topSpeed * topSpeed) {
mVelocity.Normalise();
mVelocity = mVelocity.NormalisedCopy;
mVelocity *= topSpeed;
}
else if (mVelocity.SquaredLength < tooSmall * tooSmall)
mVelocity = Vector3.ZERO;

if (mVelocity != Vector3.ZERO) mCamera.Move(mVelocity * evt.timeSinceLastFrame);
}

return true;
}

/*-----------------------------------------------------------------------------
| Processes key presses for free-look style movement.
-----------------------------------------------------------------------------*/
public virtual void injectKeyDown(MOIS.KeyEvent evt) {
if (mStyle == CS_FREELOOK) {
if (evt.key == MOIS.KeyCode.KC_W || evt.key == MOIS.KeyCode.KC_UP) mGoingForward = true;
else if (evt.key == MOIS.KeyCode.KC_S || evt.key == MOIS.KeyCode.KC_DOWN) mGoingBack = true;
else if (evt.key == MOIS.KeyCode.KC_A || evt.key == MOIS.KeyCode.KC_LEFT) mGoingLeft = true;
else if (evt.key == MOIS.KeyCode.KC_D || evt.key == MOIS.KeyCode.KC_RIGHT) mGoingRight = true;
else if (evt.key == MOIS.KeyCode.KC_PGUP) mGoingUp = true;
else if (evt.key == MOIS.KeyCode.KC_PGDOWN) mGoingDown = true;
else if (evt.key == MOIS.KeyCode.KC_LSHIFT) mFastMove = true;
}
}

/*-----------------------------------------------------------------------------
| Processes key releases for free-look style movement.
-----------------------------------------------------------------------------*/
public virtual void injectKeyUp(MOIS.KeyEvent evt) {
if (mStyle == CS_FREELOOK) {
if (evt.key == MOIS.KeyCode.KC_W || evt.key == MOIS.KeyCode.KC_UP) mGoingForward = false;
else if (evt.key == MOIS.KeyCode.KC_S || evt.key == MOIS.KeyCode.KC_DOWN) mGoingBack = false;
else if (evt.key == MOIS.KeyCode.KC_A || evt.key == MOIS.KeyCode.KC_LEFT) mGoingLeft = false;
else if (evt.key == MOIS.KeyCode.KC_D || evt.key == MOIS.KeyCode.KC_RIGHT) mGoingRight = false;
else if (evt.key == MOIS.KeyCode.KC_PGUP) mGoingUp = false;
else if (evt.key == MOIS.KeyCode.KC_PGDOWN) mGoingDown = false;
else if (evt.key == MOIS.KeyCode.KC_LSHIFT) mFastMove = false;
}
}

/*-----------------------------------------------------------------------------
| Processes mouse movement differently for each style.
-----------------------------------------------------------------------------*/
#if OGRE_PLATFORM_IPHONE
public virtual void injectMouseMove(MOIS.MultiTouchEvent evt)
#else
public virtual void injectMouseMove(MOIS.MouseEvent evt)
#endif
{
if (mStyle == CS_ORBIT) {
float dist = (mCamera.Position - mTarget._getDerivedPosition()).Length;

if (mOrbiting) { // yaw around the target, and pitch locally
Vector3 tpos = mTarget._getDerivedPosition();
mCamera.SetPosition(tpos.x, tpos.y, tpos.z);

mCamera.Yaw(new Degree(-evt.state.X.rel * 0.25f));
mCamera.Pitch(new Degree(-evt.state.Y.rel * 0.25f));

mCamera.MoveRelative(new 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(new 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(new Vector3(0, 0, -evt.state.Z.rel * 0.0008f * dist));
}
}
else if (mStyle == CS_FREELOOK) {
mCamera.Yaw(new Degree(-evt.state.X.rel * 0.15f));
mCamera.Pitch(new Degree(-evt.state.Y.rel * 0.15f));
}
}

/*-----------------------------------------------------------------------------
| Processes mouse presses. Only applies for orbit style.
| Left button is for orbiting, and right button is for zooming.
-----------------------------------------------------------------------------*/
#if OGRE_PLATFORM_IPHONE
public virtual void injectMouseDown(const OIS::MultiTouchEvent& evt)
{
if (mStyle == CS_ORBIT)
{
mOrbiting = true;
}
}
#else
public virtual void injectMouseDown(MOIS.MouseEvent evt, MOIS.MouseButtonID id) {
if (mStyle == CS_ORBIT) {
if (id == MOIS.MouseButtonID.MB_Left) mOrbiting = true;
else if (id == MOIS.MouseButtonID.MB_Right) mZooming = true;
}
}
#endif

/*-----------------------------------------------------------------------------
| Processes mouse releases. Only applies for orbit style.
| Left button is for orbiting, and right button is for zooming.
-----------------------------------------------------------------------------*/
#if OGRE_PLATFORM_IPHONE
public virtual void injectMouseUp(const OIS::MultiTouchEvent& evt)
{
if (mStyle == CS_ORBIT)
{
mOrbiting = false;
}
}
#else
public virtual void injectMouseUp(MOIS.MouseEvent evt, MOIS.MouseButtonID id) {
if (mStyle == CS_ORBIT) {
if (id == MOIS.MouseButtonID.MB_Left) mOrbiting = false;
else if (id == MOIS.MouseButtonID.MB_Right) mZooming = false;
}
}
#endif

}

}

link: ogre SampleBrowser demo
SdkCameraMan.h
c++ code:


namespace OgreBites
{
enum CameraStyle // enumerator values for different styles of camera movement
{
CS_FREELOOK,
CS_ORBIT,
CS_MANUAL
};

/*=============================================================================
| Utility class for controlling the camera in samples.
=============================================================================*/
class SdkCameraMan
{
public:
SdkCameraMan(Ogre::Camera* cam)
: mCamera(0)
, 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);
}

virtual ~SdkCameraMan() {}

/*-----------------------------------------------------------------------------
| Swaps the camera on our camera man for another camera.
-----------------------------------------------------------------------------*/
virtual void setCamera(Ogre::Camera* cam)
{
mCamera = cam;
}

virtual Ogre::Camera* getCamera()
{
return mCamera;
}

/*-----------------------------------------------------------------------------
| Sets the target we will revolve around. Only applies for orbit style.
-----------------------------------------------------------------------------*/
virtual void 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);
}

}


}

virtual Ogre::SceneNode* getTarget()
{
return mTarget;
}

/*-----------------------------------------------------------------------------
| Sets the spatial offset from the target. Only applies for orbit style.
-----------------------------------------------------------------------------*/
virtual void 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));
}

/*-----------------------------------------------------------------------------
| Sets the camera's top speed. Only applies for free-look style.
-----------------------------------------------------------------------------*/
virtual void setTopSpeed(Ogre::Real topSpeed)
{
mTopSpeed = topSpeed;
}

virtual Ogre::Real getTopSpeed()
{
return mTopSpeed;
}

/*-----------------------------------------------------------------------------
| Sets the movement style of our camera man.
-----------------------------------------------------------------------------*/
virtual void 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;

}

virtual CameraStyle getStyle()
{
return mStyle;
}

/*-----------------------------------------------------------------------------
| Manually stops the camera when in free-look mode.
-----------------------------------------------------------------------------*/
virtual void manualStop()
{
if (mStyle == CS_FREELOOK)
{
mGoingForward = false;
mGoingBack = false;
mGoingLeft = false;
mGoingRight = false;
mGoingUp = false;
mGoingDown = false;
mVelocity = Ogre::Vector3::ZERO;
}
}

virtual bool 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;
}

/*-----------------------------------------------------------------------------
| Processes key presses for free-look style movement.
-----------------------------------------------------------------------------*/
virtual void injectKeyDown(const OIS::KeyEvent& evt)
{
if (mStyle == CS_FREELOOK)
{
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;
}
}

/*-----------------------------------------------------------------------------
| Processes key releases for free-look style movement.
-----------------------------------------------------------------------------*/
virtual void injectKeyUp(const OIS::KeyEvent& evt)
{
if (mStyle == CS_FREELOOK)
{
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;
}
}

/*-----------------------------------------------------------------------------
| Processes mouse movement differently for each style.
-----------------------------------------------------------------------------*/
#if OGRE_PLATFORM == OGRE_PLATFORM_IPHONE
virtual void injectMouseMove(const OIS::MultiTouchEvent& evt)
#else
virtual void injectMouseMove(const OIS::MouseEvent& evt)
#endif
{
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));
}
}

/*-----------------------------------------------------------------------------
| Processes mouse presses. Only applies for orbit style.
| Left button is for orbiting, and right button is for zooming.
-----------------------------------------------------------------------------*/
#if OGRE_PLATFORM == OGRE_PLATFORM_IPHONE
virtual void injectMouseDown(const OIS::MultiTouchEvent& evt)
{
if (mStyle == CS_ORBIT)
{
mOrbiting = true;
}
}
#else
virtual void 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;
}
}
#endif

/*-----------------------------------------------------------------------------
| Processes mouse releases. Only applies for orbit style.
| Left button is for orbiting, and right button is for zooming.
-----------------------------------------------------------------------------*/
#if OGRE_PLATFORM == OGRE_PLATFORM_IPHONE
virtual void injectMouseUp(const OIS::MultiTouchEvent& evt)
{
if (mStyle == CS_ORBIT)
{
mOrbiting = false;
}
}
#else
virtual void 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;
}
}
#endif

protected:

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;
};
}