Added camera movement (arrows/WASD). No mouse look yet.

actorid
Nicolay Korslund 15 years ago
parent af7c87e8dc
commit 6b6f5b95ec

@ -28,7 +28,7 @@ set(OGRE ogre/renderer.cpp)
set(OGRE_HEADER ogre/renderer.hpp)
set(INPUT input/oismanager.cpp)
set(INPUT_HEADER input/oismanager.hpp input/listener.hpp input/func_binder.hpp input/dispatch_map.hpp input/dispatcher.hpp)
set(INPUT_HEADER input/oismanager.hpp input/listener.hpp input/func_binder.hpp input/dispatch_map.hpp input/dispatcher.hpp input/poller.hpp)
set(GAME game/main.cpp game/engine.cpp)
set(GAME_HEADER game/mwinput/inputmanager.hpp game/engine.hpp)
@ -38,7 +38,7 @@ set(ESM_STORE_HEADER esm_store/cell_store.hpp esm_store/reclists.hpp esm_store/s
set(GAMEREND game/mwrender/mwscene.cpp game/mwrender/cell.cpp game/mwrender/interior.cpp)
set(GAMEREND_HEADER game/mwrender/cell.hpp game/mwrender/mwscene.hpp
game/mwrender/interior.hpp)
game/mwrender/interior.hpp game/mwrender/playerpos.hpp)
set(ESM_HEADER esm/defs.hpp esm/loadcell.hpp esm/loadfact.hpp esm/loadltex.hpp
esm/loadskil.hpp

@ -11,6 +11,7 @@
#include "mwrender/interior.hpp"
#include "mwinput/inputmanager.hpp"
#include "mwrender/playerpos.hpp"
OMW::Engine::Engine() {}
@ -118,9 +119,12 @@ void OMW::Engine::go()
std::cout << "\nSetting up cell rendering\n";
// Sets up camera, scene manager etc
// Sets up camera, scene manager, and viewport.
MWRender::MWScene scene(mOgre);
// Used to control the player camera and position
MWRender::PlayerPos player(scene.getCamera());
// This connects the cell data with the rendering scene.
MWRender::InteriorCellRender rend(cell, scene);
@ -130,7 +134,7 @@ void OMW::Engine::go()
std::cout << "Setting up input system\n";
// Sets up the input system
MWInput::MWInputManager input(mOgre);
MWInput::MWInputManager input(mOgre, player);
std::cout << "\nStart! Press Q/ESC or close window to exit.\n";

@ -1,9 +1,11 @@
#ifndef _INPUT_MWINPUTMANAGER_H
#define _INPUT_MWINPUTMANAGER_H
#ifndef _MWINPUT_MWINPUTMANAGER_H
#define _MWINPUT_MWINPUTMANAGER_H
#include "input/listener.hpp"
#include "input/dispatcher.hpp"
#include "input/poller.hpp"
#include "boost/bind.hpp"
#include "game/mwrender/playerpos.hpp"
namespace MWInput
{
@ -11,21 +13,35 @@ namespace MWInput
{
A_Quit, // Exit the program
A_MoveLeft, // Move player left / right
A_MoveRight,
A_MoveUp, // Move up / down
A_MoveDown,
A_MoveForward, // Forward / Backward
A_MoveBackward,
A_LAST // Marker for the last item
};
// Class that handles all input and key bindings for OpenMW
class MWInputManager
class MWInputManager : public Ogre::FrameListener
{
// Note: the order here is important. The OISManager must be
// initialized before poller and listener.
Input::Dispatcher disp;
Input::OISManager input;
Input::Poller poller;
Input::InputListener listener;
MWRender::PlayerPos &player;
public:
MWInputManager(Render::OgreRenderer &ogre)
MWInputManager(Render::OgreRenderer &ogre,
MWRender::PlayerPos &_player)
: disp(A_LAST),
input(ogre),
listener(ogre, input, disp)
poller(input),
listener(ogre, input, disp),
player(_player)
{
using namespace Input;
using namespace OIS;
@ -35,9 +51,56 @@ namespace MWInput
boost::bind(&InputListener::exitNow, &listener),
"Quit program");
// Add ourselves as a frame listener, to catch movement keys
ogre.getRoot()->addFrameListener(this);
// Key bindings
disp.bind(KC_Q, A_Quit);
disp.bind(KC_ESCAPE, A_Quit);
// Key bindings for polled keys
// Arrow keys
poller.bind(A_MoveLeft, KC_LEFT);
poller.bind(A_MoveRight, KC_RIGHT);
poller.bind(A_MoveForward, KC_UP);
poller.bind(A_MoveBackward, KC_DOWN);
// WASD keys
poller.bind(A_MoveLeft, KC_A);
poller.bind(A_MoveRight, KC_D);
poller.bind(A_MoveForward, KC_W);
poller.bind(A_MoveBackward, KC_D);
// Use shift and ctrl for up and down
poller.bind(A_MoveUp, KC_LSHIFT);
poller.bind(A_MoveDown, KC_LCONTROL);
}
// Used to check for movement keys
bool frameStarted(const Ogre::FrameEvent &evt)
{
float speed = 300 * evt.timeSinceLastFrame;
float moveX = 0, moveY = 0, moveZ = 0;
using namespace std;
if(poller.isDown(A_MoveLeft)) moveX -= speed;
if(poller.isDown(A_MoveRight)) moveX += speed;
if(poller.isDown(A_MoveForward)) moveZ -= speed;
if(poller.isDown(A_MoveBackward)) moveZ += speed;
// TODO: These should be enabled for floating modes (like
// swimming and levitation) and disabled for everything else.
if(poller.isDown(A_MoveUp)) moveY += speed;
if(poller.isDown(A_MoveDown)) moveY -= speed;
if(moveX == 0 && moveY == 0 && moveZ == 0)
return true;
player.moveRel(moveX, moveY, moveZ);
return true;
}
};
}

@ -0,0 +1,56 @@
#ifndef _MWRENDER_PLAYERPOS_H
#define _MWRENDER_PLAYERPOS_H
#include "OgreCamera.h"
namespace MWRender
{
// This class keeps track of the player position. It takes care of
// camera movement, sound listener updates, and collision handling
// (to be done).
class PlayerPos
{
float x, y, z;
Ogre::Camera *camera;
public:
PlayerPos(Ogre::Camera *cam) :
camera(cam), x(0), y(0), z(0) {}
// Set the player position. Uses Morrowind coordinates.
void setPos(float _x, float _y, float _z)
{
x = _x;
y = _y;
z = _z;
// TODO: Update sound listener
}
// Move the player relative to her own position and
// orientation. After the call, the new position is returned.
void moveRel(float &relX, float &relY, float &relZ)
{
using namespace Ogre;
// Move camera relative to its own direction
camera->moveRelative(Vector3(relX,0,relZ));
// Up/down movement is always done relative the world axis.
camera->move(Vector3(0,relY,0));
// Get new camera position, converting back to MW coords.
Vector3 pos = camera->getPosition();
relX = pos[0];
relY = -pos[2];
relZ = pos[1];
// TODO: Collision detection must be used to find the REAL new
// position.
// Set the position
setPos(relX, relY, relZ);
}
};
}
#endif

@ -24,6 +24,9 @@ namespace Input
mMouse = input.mouse;
mKeyboard = input.keyboard;
assert(mKeyboard);
assert(mWindow);
// Add ourself to the managers
rend.getRoot() -> addFrameListener(this);
mKeyboard -> setEventCallback(this);

@ -0,0 +1,51 @@
#ifndef _INPUT_POLLER_H
#define _INPUT_POLLER_H
#include "dispatch_map.hpp"
#include "oismanager.hpp"
namespace Input {
/** The poller is used to check (poll) for keys rather than waiting
for events. TODO: Might make this OIS-independent later. */
struct Poller
{
DispatchMap map;
OIS::Keyboard *keyboard;
Poller(Input::OISManager &ois)
{
keyboard = ois.keyboard;
assert(keyboard);
}
/** Bind or unbind a given action with a key. The action is the first
parameter, the key is the second.
*/
void bind(int in, int out) { map.bind(in, out); }
void unbind(int in, int out) { map.unbind(in, out); }
bool isBound(int in) const { return map.isBound(in); }
/// Check whether a given action button is currently pressed.
typedef DispatchMap::OutList _O;
bool isDown(int index) const
{
assert(keyboard);
// No bindings, no action
if(!isBound(index))
return false;
// Get all the keys bound to this action, and check them.
const _O &list = map.getList(index);
_O::const_iterator it;
for(it = list.begin(); it != list.end(); it++)
// If there's any match, we're good to go.
if(keyboard->isKeyDown((OIS::KeyCode)*it)) return true;
return false;
}
};
}
#endif

@ -130,11 +130,6 @@ InputListener mInput;
// Functions called from D during event handling
extern "C" int32_t ois_isPressed(int32_t keysym)
{
return mKeyboard->isKeyDown((OIS::KeyCode)keysym);
}
// Dump screen contents to file
extern "C" void ogre_screenshot(char* filename)
{
@ -160,15 +155,6 @@ extern "C" void ogre_rotateCamera(float x, float y)
mCamera->setOrientation(nopitch);
}
// Get current camera position
extern "C" void ogre_getCameraPos(float *x, float *y, float *z)
{
Vector3 pos = mCamera->getPosition();
*x = pos[0];
*y = -pos[2];
*z = pos[1];
}
// Get current camera orientation, in the form of 'front' and 'up'
// vectors.
extern "C" void ogre_getCameraOrientation(float *fx, float *fy, float *fz,
@ -212,12 +198,3 @@ extern "C" void ogre_setCameraRotation(float r1, float r2, float r3)
// Rotates first around z, then y, then x
mCamera->setOrientation(xr*yr*zr);
}
// Move camera relative to its own axis set.
extern "C" void ogre_moveCameraRel(float x, float y, float z)
{
mCamera->moveRelative(Vector3(x,0,z));
// up/down movement is always done relative the world axis
mCamera->move(Vector3(0,y,0));
}

Loading…
Cancel
Save