Character Movement

Frenzy123

19-12-2008 15:41:05

sorry to do this guys but another question about movement. I have a charcter in a 3d world that i need to move in the x and z directions and i need to rotate around the y axis and which ever way my character is facing he moves in that direction. So the usual sort of fps or 3rd person. I have looked at other threads but i cant seem to find one which includes moving in the direction you are facing, i understand the theory but cannot seem to reproduce it. As i understand to move in the direction your facing you just multiply your orientation with your movement force but it doesnt seem to work. Here is my code.

//MovementForce is the force applied by my input and the same for Torque
Vector3 MovementForce1 = MovementForce;
Vector3 Torque1 = Torque;
MovementForce1 *= getMass();
bod->setOmega(Torque1);

Quaternion Orientation;
bod->getPositionOrientation(Vector3(0,0,0),Orientation);
Vector3 force = Orientation * (MovementForce1 - bod->getVelocity()/GlobalVariableClass::get()->PhysicsWorld->getTimeStep());

bod->addForce(force);

now with the code as it is my character slides everywhere but other than this it seems to be ok(although i do not want to slide). If i move the mass multiplier to a more appropriate place i.e. just before the force is set , if i rotate my character and then move i fly undesirably across the world.


Any help would be appreciated. Thankyou in advance

majc

30-12-2008 21:22:36

This is my movement class i hope it helps:

#include "cOgreNewtFrameListener.h"


cOgreNewtFrameListener::cOgreNewtFrameListener(cEntityCollisionHandler *entityCollision, cPlayer *player, cBulletGraphics* bulletGraph, cBullet *bullet,cGUI *renderer, cEntityCollisionHandler *npc, cPlayerGraphics *playerGraphs, bool bufferedKeys , bool bufferedMouse, bool bufferedJoy ):cBasicFrameListener(true,true,false)
{
using namespace OIS;

mEntityCollision = entityCollision;
mPlayer = player;
mBulletGraph = bulletGraph;
mRenderer = renderer;
mNPCcollision = npc;
mPlayerGraph = playerGraphs;
sensitivityX = 0.05;
sensitivityY = 0.05;
mBullet = bullet;
FPSmode = true;
mKeyboard->setEventCallback(this);
mMouse->setEventCallback(this);
mMouse->setBuffered(false);
displayCameraDetails = true;
mRaySceneQuery = cGraphicalInterface::getInstance()->getSceneManager()->createRayQuery(Ray());
mRenderer->createCrosshair();
mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");
mCurrentObject = 0;
counter = 0;
}

CEGUI::MouseButton cOgreNewtFrameListener::convertOISMouseButtonToCegui(int buttonID)
{
switch (buttonID)
{
case 0: return CEGUI::LeftButton;
case 1: return CEGUI::RightButton;
case 2: return CEGUI::MiddleButton;
case 3: return CEGUI::X1Button;
default: return CEGUI::LeftButton;
}
}

bool cOgreNewtFrameListener::mouseMoved( const OIS::MouseEvent &arg )
{
CEGUI::System::getSingleton().injectMouseMove( arg.state.X.rel, arg.state.Y.rel );
return true;
}

bool cOgreNewtFrameListener::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
CEGUI::System::getSingleton().injectMouseButtonDown(convertOISMouseButtonToCegui(id));
return true;
}

bool cOgreNewtFrameListener::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
CEGUI::System::getSingleton().injectMouseButtonUp(convertOISMouseButtonToCegui(id));
return true;
}


void cOgreNewtFrameListener::input(const FrameEvent& evt)
{
Ogre::Vector3 trans, strafe, vec, pos;
Quaternion orientation = Ogre::Quaternion::IDENTITY;

pos = cPhysicsInterface::getInstance()->getPosition(mEntityCollision->getBody());
orientation = cPhysicsInterface::getInstance()->getOrientation(mEntityCollision->getBody());

vec = Ogre::Vector3(0.0,0.0,-2);
trans = orientation * vec;

vec = Ogre::Vector3(2,0.0,0.0);
strafe = orientation * vec;

mKeyboard->capture();
mMouse->capture();

if(mKeyboard->isKeyDown(KC_M))
{
if (timer <= 0.0)
{
FPSmode = !FPSmode;
if (!FPSmode)
{
mMouse->setBuffered(true);
mRenderer->createDefaultMouseArrow();
}
else
{
mMouse->setBuffered(false);
mRenderer->createCrosshair();
}
timer = 0.2;
}
}

timer -= evt.timeSinceLastFrame;

ms = mMouse->getMouseState();
mRotX = Degree(-ms.X.rel * sensitivityX);
mRotY = Degree(-ms.Y.rel * sensitivityY);
camRotationX = -ms.X.rel * sensitivityX;
camRotationY = -ms.Y.rel * sensitivityY;

mEntityCollision->getBody()->setOmega(Ogre::Vector3(0,camRotationX,0));
mPlayerGraph->getCamView()->pitch(mRotY);
Ogre::Real pitchAngle = (2 * Ogre::Degree(Ogre::Math::ACos(mPlayerGraph->getCamView()->getOrientation().w)).valueDegrees());

if (pitchAngle > 90.0f)
{
mPlayerGraph->getCamView()->pitch(Degree(-camRotationY) );
}
else
{
mPlayerGraph->getCamView()->pitch(mRotY);
}

if (!FPSmode)
{
CEGUI::System::getSingleton().injectMouseMove(ms.X.rel, ms.Y.rel);
}

if( ms.buttonDown( MB_Left ) && (mPlayer->getIsAlive()) )
{
if (timer2 <= 0.0)
{
if(FPSmode)
{
Ray ray = mBulletGraph->fireCameraRay(0.5,0.5);
mBullet->fireRay(evt.timeSinceLastFrame, 1,5000, 10, ray.getOrigin(), ray.getDirection(), true);
timer2 = 0.5;
}
else
{
CEGUI::Point mousePos = CEGUI::MouseCursor::getSingleton().getPosition();
Ray ray = mBulletGraph->fireCameraRay(mousePos.d_x/float(ms.width), mousePos.d_y/float(ms.height));
CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::LeftButton);
mBullet->fireRay(evt.timeSinceLastFrame, 1,5000, 10, ray.getOrigin(), ray.getDirection(), false);
timer2 = 0.5;
}
}
}
timer2 -= evt.timeSinceLastFrame;

if( ms.buttonDown( MB_Right ) && (mPlayer->getIsAlive()))
{
}

Real height = mEntityCollision->getHeightFromGround(mEntityCollision->getBody());

if(mPlayer->getIsRunning() == false) //Restores stamina
{
mPlayer->setStamina(mPlayer->getStamina()+ evt.timeSinceLastFrame);
if(mPlayer->getStamina() >= mPlayer->getStaminaLimit())
{
mPlayer->setStamina(mPlayer->getStaminaLimit());
}
}

if((mPlayer->getIsJumping() == true)&&((height >14)&&(height <16)))
{
mPlayer->setRunVel(Ogre::Vector3(0,0,0));
mEntityCollision->getBody()->setVelocity( (trans * 16.0 * mPlayer->getRunVel()));//add velocity to the body
}

if((mKeyboard->isKeyDown(KC_A) || mKeyboard->isKeyDown(KC_LEFT)) && (mPlayer->getIsJumping() == false) && (mPlayer->getIsAlive()))
{
if(mPlayer->getIsRunning() == false)
{
mPlayer->setRunVel(Ogre::Vector3(1,1,1));
}
mEntityCollision->getBody()->unFreeze();
mEntityCollision->getBody()->setVelocity( (strafe * -1 * 70.0 * mPlayer->getRunVel()) );
}

if((mKeyboard->isKeyDown(KC_D) || mKeyboard->isKeyDown(KC_RIGHT)) && (mPlayer->getIsJumping() == false) && (mPlayer->getIsAlive()))// Move camera RIGHT
{
if(mPlayer->getIsRunning() == false)
{
mPlayer->setRunVel(Ogre::Vector3(1,1,1));
}
mEntityCollision->getBody()->unFreeze();
mEntityCollision->getBody()->setVelocity( (strafe * 70.0 * mPlayer->getRunVel()) );
}

if(mKeyboard->isKeyDown(KC_UP) || mKeyboard->isKeyDown(KC_W) && (mPlayer->getIsJumping() == false) && (mPlayer->getIsAlive()))
{
if(mPlayer->getIsRunning() == false)
{
mPlayer->setRunVel(Ogre::Vector3(1,1,1));
}
mEntityCollision->getBody()->setVelocity( (trans * 70.0 * mPlayer->getRunVel()));//add velocity to the body
}

if(mKeyboard->isKeyDown(KC_DOWN) || mKeyboard->isKeyDown(KC_S) && (mPlayer->getIsJumping() == false) && (mPlayer->getIsAlive()))// Move camera backward
{
if(mPlayer->getIsRunning() == false)
{
mPlayer->setRunVel(Ogre::Vector3(1,1,1));
}
mEntityCollision->getBody()->unFreeze();
mEntityCollision->getBody()->setVelocity( (trans * -1 * 70.0 * mPlayer->getRunVel()) );
}

if ((mKeyboard->isKeyDown(KC_LSHIFT)) && (mPlayer->getIsJumping() == false) && (mPlayer->getIsAlive()))// jump key
{
mEntityCollision->getBody()->setVelocity(mEntityCollision->getBody()->getVelocity() * Ogre::Vector3(1,0,1) + Ogre::Vector3(0,20,0) * mPlayer->getJmpVel());

}
if(height > 15)//if height bigger than 15 player its jumping
{
mPlayer->setIsJumping(true);
}
if(height <= 15)//if height lower than 15 player it isnt jumping
{
mPlayer->setIsJumping(false);
}

if ((mKeyboard->isKeyDown(KC_SPACE))&& (mPlayer->getIsJumping() == false) && (mPlayer->getStamina() > 1) && (mPlayer->getIsAlive()))//raise player velocity
{
mPlayer->setStamina(mPlayer->getStamina() - evt.timeSinceLastFrame);
mPlayer->setIsRunning(true);
if(mPlayer->getStamina() > 1)
{
mPlayer->setRunVel(Ogre::Vector3(2.5,2.5,2.5));
}
else
{
mPlayer->setRunVel(Ogre::Vector3(1,1,1));
}
}

if(mKeyboard->isKeyDown(KC_PGUP) && (mPlayer->getIsAlive()))
mTranslateVector.y = mMoveScale; // Move camera up

if(mKeyboard->isKeyDown(KC_PGDOWN) && (mPlayer->getIsAlive()))
mTranslateVector.y = -mMoveScale; // Move camera down

if( mKeyboard->isKeyDown(KC_F) && mTimeUntilNextToggle <= 0 )
{
mStatsOn = !mStatsOn;
//showDebugOverlay(mStatsOn);
mTimeUntilNextToggle = 1;
}

if( mKeyboard->isKeyDown(KC_T) && mTimeUntilNextToggle <= 0 )
{
switch(mFiltering)
{
case TFO_BILINEAR:
mFiltering = TFO_TRILINEAR;
mAniso = 1;
break;
case TFO_TRILINEAR:
mFiltering = TFO_ANISOTROPIC;
mAniso = 8;
break;
case TFO_ANISOTROPIC:
mFiltering = TFO_BILINEAR;
mAniso = 1;
break;
default: break;
}
MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering);
MaterialManager::getSingleton().setDefaultAnisotropy(mAniso);

// showDebugOverlay(mStatsOn);
mTimeUntilNextToggle = 1;
}

if(mKeyboard->isKeyDown(KC_SYSRQ) && mTimeUntilNextToggle <= 0)
{
std::ostringstream ss;
ss << "screenshot_" << ++mNumScreenShots << ".png";
cGraphicalInterface::getInstance()->getWindow()->writeContentsToFile(ss.str());
mTimeUntilNextToggle = 0.5;
mDebugText = "Saved: " + ss.str();
}

if(mKeyboard->isKeyDown(KC_R) && mTimeUntilNextToggle <=0)
{
mSceneDetailIndex = (mSceneDetailIndex+1)%3 ;
switch(mSceneDetailIndex)
{
case 0 : cGraphicalInterface::getInstance()->getCamera()->setPolygonMode(PM_SOLID); break;
case 1 : cGraphicalInterface::getInstance()->getCamera()->setPolygonMode(PM_WIREFRAME); break;
case 2 : cGraphicalInterface::getInstance()->getCamera()->setPolygonMode(PM_POINTS); break;
}
mTimeUntilNextToggle = 0.5;
}


/*if(mKeyboard->isKeyDown(KC_P) && mTimeUntilNextToggle <= 0)
{
displayCameraDetails = !displayCameraDetails;
mTimeUntilNextToggle = 0.5;
if (!displayCameraDetails)
mDebugText = "";
}
if(displayCameraDetails)*/
//mDebugOverlay->show();
//mDebugText = "O: asdkhfalskjdfhlasdhfljkashdfljkahdjkfa ";
}



bool cOgreNewtFrameListener::keyClicked(const OIS::KeyEvent &e)
{
return true;
}

bool cOgreNewtFrameListener::keyPressed(const OIS::KeyEvent &e)
{
return true;
}

bool cOgreNewtFrameListener::keyReleased(const OIS::KeyEvent &e)
{
if(mPlayer->getIsJumping() == false)
{
switch(e.key)
{
case KC_UP:
case KC_W:
//mPlayer->setRunVel(Ogre::Vector3(0,0,0));
mEntityCollision->getBody()->setVelocity(mPlayer->getRunVel());
break;

case KC_DOWN:
case KC_S:
//mPlayer->setRunVel(Ogre::Vector3(0,0,0));
mEntityCollision->getBody()->setVelocity(mPlayer->getRunVel());
break;

case KC_LEFT:
case KC_A:
//mPlayer->setRunVel(Ogre::Vector3(0,0,0));
mEntityCollision->getBody()->setVelocity(mPlayer->getRunVel());
break;

case KC_RIGHT:
case KC_D:
//mPlayer->setRunVel(Ogre::Vector3(0,0,0));
mEntityCollision->getBody()->setVelocity(mPlayer->getRunVel());
break;

case KC_SPACE:
mPlayer->setRunVel(Ogre::Vector3(0,0,0));
mEntityCollision->getBody()->setVelocity(mPlayer->getRunVel());
mPlayer->setIsRunning(false);
return true;
break;
}
}
else
{
switch(e.key)
{
case KC_SPACE:
mPlayer->setRunVel(Ogre::Vector3(0,0,0));
mPlayer->setIsRunning(false);
return true;
break;
}
}
return true;
}


bool cOgreNewtFrameListener::frameStarted(const FrameEvent& evt)
{
if(cGraphicalInterface::getInstance()->getWindow()->isClosed())
return false;
input(evt);
mEntityCollision->getBody()->getPositionOrientation(position,orientation);
Ogre::Vector3 positions[] = {Ogre::Vector3(327,17.9905,-1113.91), Ogre::Vector3(-1442,17.9905,-1061), Ogre::Vector3(-99,17.9905,58)};
Ogre::Vector3 wanderMin(-4000,0,-4000);
Ogre::Vector3 wanderMax(4000,0,4000);
mNPCcollision->AIBehavior(mNPCcollision->getBody(),wanderMin,wanderMax,3,positions, position, evt);
return true;
}

bool cOgreNewtFrameListener::frameEnded(const FrameEvent& evt)
{
if( mKeyboard->isKeyDown( KC_ESCAPE) )
{
return false;
}
//updateStats();
return true;
}

cOgreNewtFrameListener::~cOgreNewtFrameListener()
{
//Remove ourself as a Window listener
WindowEventUtilities::removeWindowEventListener(cGraphicalInterface::getInstance()->getWindow(), this);
windowClosed(cGraphicalInterface::getInstance()->getWindow());
}