my code is:
Code: Select all
#include "OGRE\ExampleApplication.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 MyFrame: public FrameListener, public OIS::KeyListener
{
private:
Camera* mCamera;
OIS::InputManager* _man;
OIS::Keyboard* _key;
OIS::Mouse* _mouse;
SceneNode* mBodyNode;
SceneNode* mCameraPivot;
SceneNode* mCameraGoal;
SceneNode* mCameraNode;
Real mPivotPitch;
Vector3 mKeyDirection; // player's local intended direction based on WASD keys
Vector3 mGoalDirection; // actual intended direction in world-space
public:
MyFrame(RenderWindow* win, Camera* cam)
{
size_t windowHnd = 0;
std::stringstream windowHndStr;
win->getCustomAttribute("WINDOW", &windowHnd);
windowHndStr << windowHnd;
OIS::ParamList pl;
pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
_man = OIS::InputManager::createInputSystem(pl);
_key = static_cast<OIS::Keyboard*>(_man->createInputObject(OIS::OISKeyboard, false));
_mouse = static_cast<OIS::Mouse*>(_man->createInputObject(OIS::OISMouse, false));
_key->setEventCallback(this);
setupCamera(cam);
}
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;
}
bool keyPressed( const OIS::KeyEvent& evt )
{
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;
return true;
}
bool keyReleased( const OIS::KeyEvent& evt )
{
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;
return true;
}
bool processUnbufferedInput(const Ogre::FrameEvent& evt)
{
static bool mMouseDown = false; // If a mouse button is depressed
static Ogre::Real mToggle = 0.0; // The time left until next toggle
static Ogre::Real mRotate = 0.13; // The rotate constant
static Ogre::Real mMove = 250; // The movement constant
//_mouse->capture();
if (mKeyDirection != Vector3::ZERO)
{
// 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) * evt.timeSinceLastFrame * 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, evt.timeSinceLastFrame * RUN_SPEED, //*mAnims[mBaseAnimID]->getWeight(),
Node::TS_LOCAL);
}
return true;
}
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() + 10;
mCameraNode->translate(goalOffset * deltaTime * 9.0f);
// always look at the pivot
mCameraNode->lookAt(mCameraPivot->_getDerivedPosition(), Node::TS_WORLD);
}
bool frameRenderingQueued(const Ogre::FrameEvent& evt)
{
_key->capture();
if(!processUnbufferedInput(evt)) return false;
updateCamera(evt.timeSinceLastFrame);
return true;
}
void setupContent(SceneManager* mSceneMgr)
{
Entity* ent = mSceneMgr->createEntity("Ent", "mario.mesh");
mBodyNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("nodo1");
mBodyNode->attachObject(ent);
mBodyNode->translate(0,0,0);
mBodyNode->setScale(0.1f,0.1f,0.1f);
MeshManager::getSingleton().createPlane("floor", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
Plane(Vector3::UNIT_Y, 0), 1000, 1000, 10, 10, true, 1, 10, 10, Vector3::UNIT_Z);
// create a floor entity, give it a material, and place it at the origin
Entity* floor = mSceneMgr->createEntity("Floor", "floor");
floor->setMaterialName("Examples/Rockwall");
floor->setCastShadows(false);
mSceneMgr->getRootSceneNode()->attachObject(floor);
mKeyDirection = Vector3::ZERO;
}
};
class MyGame: public ExampleApplication
{
private:
MyFrame* characterController;
protected:
void createScene()
{
characterController = new MyFrame(mWindow, mCamera);
characterController->setupContent(mSceneMgr);
}
void createCamera()
{
mCamera = mSceneMgr->createCamera("MyCamera1");
//mCamera->setPosition(Vector3(0,0,0));
//mCamera->lookAt(Vector3(0,0,0));
mCamera->setNearClipDistance(5);
}
void createFrameListener()
{
FrameListener* listener = characterController;
mRoot->addFrameListener(listener);
//ExampleApplication::createFrameListener();
}
};
