rotateObject() added, input system rewritten

This commit is contained in:
greye 2012-08-09 00:15:52 +04:00
parent 1db7978361
commit ec9cf4d3c6
16 changed files with 217 additions and 86 deletions

View file

@ -21,6 +21,7 @@ add_openmw_dir (mwrender
add_openmw_dir (mwinput
inputmanager
mouselookevent
)
add_openmw_dir (mwgui

View file

@ -186,7 +186,7 @@ namespace MWBase
virtual void scaleObject (const MWWorld::Ptr& ptr, float scale) = 0;
virtual void rotateObject(const MWWorld::Ptr& ptr,float x,float y,float z) = 0;
virtual void rotateObject(const MWWorld::Ptr& ptr,float x,float y,float z, bool adjust = false) = 0;
virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false)
const = 0;

View file

@ -6,7 +6,6 @@
#include <openengine/gui/events.hpp>
#include <openengine/ogre/exitlistener.hpp>
#include <openengine/ogre/mouselook.hpp>
#include <openengine/ogre/renderer.hpp>
#include "../mwgui/window_manager.hpp"
@ -16,12 +15,12 @@
#include <libs/platform/strings.h>
#include "mouselookevent.hpp"
#include "../engine.hpp"
#include "../mwworld/player.hpp"
#include "../mwrender/player.hpp"
#include <boost/bind.hpp>
#include <boost/filesystem.hpp>
#include <OgreRoot.h>
@ -82,7 +81,7 @@ namespace MWInput
OEngine::Render::ExitListener exit;
Mangle::Input::OISDriver input;
OEngine::Input::Poller poller;
OEngine::Render::MouseLookEventPtr mouse;
MouseLookEventPtr mouse;
OEngine::GUI::EventInjectorPtr guiEvents;
MWWorld::Player &player;
MWGui::WindowManager &windows;
@ -279,8 +278,7 @@ private:
// Add the exit listener
ogre.getRoot()->addFrameListener(&exit);
// Set up the mouse handler and tell it about the player camera
mouse = MouseLookEventPtr(new MouseLookEvent(player.getRenderer()->getCamera()));
mouse = MouseLookEventPtr(new MouseLookEvent());
// This event handler pumps events into MyGUI
guiEvents = EventInjectorPtr(new EventInjector(windows.getGui()));
@ -419,7 +417,7 @@ private:
if(guiMode)
{
// Disable mouse look
mouse->setCamera(NULL);
mouse->disable();
// Enable GUI events
guiEvents->enabled = true;
@ -428,7 +426,7 @@ private:
{
// Start mouse-looking again. TODO: This should also allow
// for other ways to disable mouselook, like paralyzation.
mouse->setCamera(player.getRenderer()->getCamera());
mouse->enable();
// Disable GUI events
guiEvents->enabled = false;

View file

@ -0,0 +1,28 @@
#include "mouselookevent.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/player.hpp"
#include <OIS/OIS.h>
#include <OgreCamera.h>
#include <OgreSceneNode.h>
using namespace OIS;
using namespace MWInput;
void MouseLookEvent::event(Type type, int index, const void *p)
{
if (type != EV_MouseMove || mDisabled) {
return;
}
MouseEvent *arg = (MouseEvent*)(p);
float x = arg->state.X.rel * sensX;
float y = arg->state.Y.rel * sensY;
MWBase::World *world = MWBase::Environment::get().getWorld();
world->rotateObject(world->getPlayer().getPlayer(), -y, 0.f, -x, true);
}

View file

@ -0,0 +1,57 @@
#ifndef _MWINPUT_MOUSELOOKEVENT_H
#define _MWINPUT_MOUSELOOKEVENT_H
/*
A mouse-look class for Ogre. Accepts input events from Mangle::Input
and translates them.
You can adjust the mouse sensibility and switch to a different
camera. The mouselook class also has an optional wrap protection
that keeps the camera from flipping upside down.
You can disable the mouse looker at any time by calling
setCamera(NULL), and reenable it by setting the camera back.
NOTE: The current implementation will ONLY work for native OIS
events.
*/
#include <mangle/input/event.hpp>
namespace MWInput
{
class MouseLookEvent : public Mangle::Input::Event
{
float sensX, sensY; // Mouse sensibility
bool flipProt; // Flip protection
bool mDisabled;
public:
MouseLookEvent(float sX = 0.2, float sY = 0.2, bool prot=true)
: sensX(sX), sensY(sY), flipProt(prot)
{}
void setSens(float sX, float sY) {
sensX = sX;
sensY = sY;
}
void setProt(bool p) {
flipProt = p;
}
void disable() {
mDisabled = true;
}
void enable() {
mDisabled = false;
}
void event(Type type, int index, const void *p);
};
typedef boost::shared_ptr<MouseLookEvent> MouseLookEventPtr;
}
#endif

View file

@ -1,34 +1,58 @@
#include "player.hpp"
#include <OgreSceneNode.h>
#include <OgreCamera.h>
#include "../mwworld/ptr.hpp"
#include "../mwworld/refdata.hpp"
namespace MWRender
{
Player::Player (Ogre::Camera *camera, Ogre::SceneNode* node)
: mCamera (camera), mNode (node)
: mCamera (camera),
mNode (node),
mFirstPersonView(true),
mVanityModeEnabled(false)
{}
void Player::setRot(float x, float y, float z)
bool Player::setRotation(const Ogre::Vector3 &rot)
{
Ogre::SceneNode *sceneNode = mNode;
Ogre::Node* yawNode = sceneNode->getChildIterator().getNext();
Ogre::Node* pitchNode = yawNode->getChildIterator().getNext();
Ogre::SceneNode *sceneNode = mNode;
Ogre::Node* yawNode = sceneNode->getChildIterator().getNext();
Ogre::Node* pitchNode = yawNode->getChildIterator().getNext();
// we are only interested in X and Y rotation
// we are only interested in X and Y rotation
// Rotate around X axis
Ogre::Quaternion xr(Ogre::Radian(x), Ogre::Vector3::UNIT_X);
// Rotate around X axis
Ogre::Quaternion xr(Ogre::Radian(rot.x), Ogre::Vector3::UNIT_X);
// Rotate around Y axis
Ogre::Quaternion yr(Ogre::Radian(-z), Ogre::Vector3::UNIT_Y);
// Rotate around Y axis
Ogre::Quaternion yr(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Y);
pitchNode->setOrientation(xr);
yawNode->setOrientation(yr);
pitchNode->setOrientation(xr);
yawNode->setOrientation(yr);
return !mVanityModeEnabled;
}
std::string Player::getHandle() const
{
return mNode->getName();
}
void Player::attachTo(const MWWorld::Ptr &ptr)
{
ptr.getRefData().setBaseNode(mNode);
}
bool Player::adjustRotation(const Ogre::Vector3 &rot)
{
Ogre::SceneNode *pitchNode = mCamera->getParentSceneNode();
Ogre::SceneNode *yawNode = pitchNode->getParentSceneNode();
pitchNode->pitch(Ogre::Degree(rot.x));
yawNode->yaw(Ogre::Degree(rot.z));
return !mVanityModeEnabled;
}
}

View file

@ -3,12 +3,19 @@
#include <string>
namespace Ogre
{
{
class Vector3;
class Camera;
class SceneNode;
}
namespace MWWorld
{
class Ptr;
}
namespace MWRender
{
/// \brief Player character rendering and camera control
@ -17,17 +24,28 @@ namespace MWRender
Ogre::Camera *mCamera;
Ogre::SceneNode* mNode;
public:
bool mFirstPersonView;
bool mVanityModeEnabled;
Player (Ogre::Camera *camera, Ogre::SceneNode* mNode);
public:
Ogre::Camera *getCamera() { return mCamera; }
Player (Ogre::Camera *camera, Ogre::SceneNode* mNode);
/// Set where the player is looking at. Uses Morrowind (euler) angles
void setRot(float x, float y, float z);
/// Set where the player is looking at. Uses Morrowind (euler) angles
bool setRotation(const Ogre::Vector3 &rot);
bool adjustRotation(const Ogre::Vector3 &rot);
std::string getHandle() const;
Ogre::SceneNode* getNode() {return mNode;}
std::string getHandle() const;
void attachTo(const MWWorld::Ptr &);
void toggleViewMode() {
mFirstPersonView = !mFirstPersonView;
}
void toggleVanityMode() {
mVanityModeEnabled = !mVanityModeEnabled;
}
};
}

View file

@ -1,16 +1,17 @@
#ifndef _GAME_RENDERING_INTERFACE_H
#define _GAME_RENDERING_INTERFACE_H
namespace MWRender{
class Objects;
class Actors;
class Player;
namespace MWRender
{
class Objects;
class Actors;
class RenderingInterface{
class RenderingInterface
{
public:
virtual MWRender::Objects& getObjects() = 0;
virtual MWRender::Player& getPlayer() = 0;
virtual MWRender::Actors& getActors() = 0;
virtual ~RenderingInterface(){};
};
}
#endif
#endif

View file

@ -183,10 +183,6 @@ MWRender::Actors& RenderingManager::getActors(){
return mActors;
}
MWRender::Player& RenderingManager::getPlayer(){
return (*mPlayer);
}
OEngine::Render::Fader* RenderingManager::getFader()
{
return mRendering.getFader();
@ -251,9 +247,31 @@ void RenderingManager::moveObject (const MWWorld::Ptr& ptr, const Ogre::Vector3&
void RenderingManager::scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& scale){
}
void RenderingManager::rotateObject (const MWWorld::Ptr& ptr, const::Ogre::Quaternion& orientation){
bool
RenderingManager::rotateObject(
const MWWorld::Ptr &ptr,
Ogre::Vector3 &rot,
bool adjust)
{
if (ptr.getRefData().getHandle() == "player") {
if (adjust) {
return mPlayer->adjustRotation(rot);
} else {
return mPlayer->setRotation(rot);
}
}
MWWorld::Class::get(ptr).adjustRotation(ptr, rot.x, rot.y, rot.z);
Ogre::Quaternion xr(Ogre::Degree(rot.x), Ogre::Vector3::UNIT_X);
Ogre::Quaternion yr(Ogre::Degree(-rot.z), Ogre::Vector3::UNIT_Y);
Ogre::Quaternion zr(Ogre::Degree(rot.y), Ogre::Vector3::UNIT_Z);
ptr.getRefData().getBaseNode()->setOrientation(xr * yr * zr);
return true;
}
void RenderingManager::moveObjectToCell (const MWWorld::Ptr& ptr, const Ogre::Vector3& position, MWWorld::Ptr::CellStore *store){
}
@ -770,4 +788,9 @@ void RenderingManager::getTriangleBatchCount(unsigned int &triangles, unsigned i
}
}
void RenderingManager::attachCameraTo(const MWWorld::Ptr &ptr)
{
mPlayer->attachTo(ptr);
}
} // namespace

View file

@ -56,11 +56,7 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
RenderingManager(OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine);
virtual ~RenderingManager();
virtual MWRender::Player& getPlayer(); /// \todo move this to private again as soon as
/// MWWorld::Player has been rewritten to not need access
/// to internal details of the rendering system anymore
void attachCameraTo(const MWWorld::Ptr &ptr);
SkyManager* getSkyManager();
Compositors* getCompositors();
@ -89,7 +85,7 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
void moveObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& position);
void scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& scale);
void rotateObject (const MWWorld::Ptr& ptr, const::Ogre::Quaternion& orientation);
bool rotateObject (const MWWorld::Ptr& ptr, Ogre::Vector3 &rot, bool adjust = false);
void setWaterHeight(const float height);
void toggleWater();

View file

@ -492,11 +492,13 @@ namespace MWSound
startRandomTitle();
const ESM::Cell *cell = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->cell;
Ogre::Camera *cam = MWBase::Environment::get().getWorld()->getPlayer().getRenderer()->getCamera();
// Ogre::Camera *cam = MWBase::Environment::get().getWorld()->getPlayer().getRenderer()->getCamera();
Ogre::Vector3 nPos, nDir, nUp;
/*
nPos = cam->getRealPosition();
nDir = cam->getRealDirection();
nUp = cam->getRealUp();
*/
Environment env = Env_Normal;
if((cell->data.flags&cell->HasWater) && nPos.y < cell->water)

View file

@ -6,8 +6,6 @@
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwrender/player.hpp"
#include "../mwmechanics/movement.hpp"
#include "../mwmechanics/npcstats.hpp"
@ -15,8 +13,8 @@
namespace MWWorld
{
Player::Player (MWRender::Player *renderer, const ESM::NPC *player, const MWBase::World& world) :
mCellStore (0), mRenderer (renderer), mClass (0),
Player::Player (const ESM::NPC *player, const MWBase::World& world) :
mCellStore (0), mClass (0),
mAutoMove (false), mForwardBackward (0)
{
mPlayer.base = player;
@ -28,7 +26,6 @@ namespace MWWorld
float* playerPos = mPlayer.mData.getPosition().pos;
playerPos[0] = playerPos[1] = playerPos[2] = 0;
mPlayer.mData.setBaseNode(renderer->getNode());
/// \todo Do not make a copy of classes defined in esm/p records.
mClass = new ESM::Class (*world.getStore().classes.find (player->cls));
}
@ -38,11 +35,6 @@ namespace MWWorld
delete mClass;
}
void Player::setRot(float x, float y, float z)
{
mRenderer->setRot(x, y, z);
}
void Player::setClass (const ESM::Class& class_)
{
ESM::Class *new_class = new ESM::Class (class_);

View file

@ -14,11 +14,6 @@ namespace MWBase
class World;
}
namespace MWRender
{
class Player;
}
namespace MWWorld
{
class CellStore;
@ -28,7 +23,6 @@ namespace MWWorld
{
LiveCellRef<ESM::NPC> mPlayer;
MWWorld::CellStore *mCellStore;
MWRender::Player *mRenderer;
std::string mName;
bool mMale;
std::string mRace;
@ -38,13 +32,10 @@ namespace MWWorld
int mForwardBackward;
public:
Player(MWRender::Player *renderer, const ESM::NPC *player, const MWBase::World& world);
Player(const ESM::NPC *player, const MWBase::World& world);
~Player();
/// Set where the player is looking at. Uses Morrowind (euler) angles
void setRot(float x, float y, float z);
void setCell (MWWorld::CellStore *cellStore)
{
mCellStore = cellStore;
@ -56,8 +47,6 @@ namespace MWWorld
return ptr;
}
MWRender::Player *getRenderer() { return mRenderer; }
void setName (const std::string& name)
{
mName = name;

View file

@ -149,7 +149,7 @@ namespace MWWorld
if (adjustPlayerPos) {
world->moveObject(player, pos.pos[0], pos.pos[1], pos.pos[2]);
MWBase::Environment::get().getWorld()->getPlayer().setRot (pos.rot[0], pos.rot[1], pos.rot[2]);
world->rotateObject(player, pos.rot[0], pos.rot[1], pos.rot[2]);
}
world->getPlayer().setCell(cell);

View file

@ -189,8 +189,9 @@ namespace MWWorld
mEsm.open (masterPath.string());
mStore.load (mEsm);
MWRender::Player* play = &(mRendering->getPlayer());
mPlayer = new MWWorld::Player (play, mStore.npcs.find ("player"), *this);
mPlayer = new MWWorld::Player (mStore.npcs.find ("player"), *this);
mRendering->attachCameraTo(mPlayer->getPlayer());
mPhysics->addActor (mPlayer->getPlayer().getRefData().getHandle(), "", Ogre::Vector3 (0, 0, 0));
// global variables
@ -598,19 +599,20 @@ namespace MWWorld
mPhysics->scaleObject( ptr.getRefData().getHandle(), scale );
}
void World::rotateObject (const Ptr& ptr,float x,float y,float z)
void World::rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust)
{
MWWorld::Class::get(ptr).adjustRotation(ptr,x,y,z);
Ogre::Vector3 rot(x, y, z);
if (mRendering->rotateObject(ptr, rot, adjust)) {
float *objRot = ptr.getRefData().getPosition().rot;
objRot[0] = Ogre::Degree(rot.x).valueRadians();
objRot[1] = Ogre::Degree(rot.y).valueRadians();
objRot[2] = Ogre::Degree(rot.z).valueRadians();
ptr.getRefData().getPosition().rot[0] = Ogre::Degree(x).valueRadians();
ptr.getRefData().getPosition().rot[1] = Ogre::Degree(y).valueRadians();
ptr.getRefData().getPosition().rot[2] = Ogre::Degree(z).valueRadians();
Ogre::Quaternion rotx(Ogre::Degree(-x),Ogre::Vector3::UNIT_X);
Ogre::Quaternion roty(Ogre::Degree(-y),Ogre::Vector3::UNIT_Y);
Ogre::Quaternion rotz(Ogre::Degree(-z),Ogre::Vector3::UNIT_Z);
ptr.getRefData().getBaseNode()->setOrientation(rotx*roty*rotz);
mPhysics->rotateObject(ptr.getRefData().getHandle(),ptr.getRefData().getBaseNode()->getOrientation());
mPhysics->rotateObject(
ptr.getRefData().getHandle(),
ptr.getRefData().getBaseNode()->getOrientation()
);
}
}
void World::indexToPosition (int cellX, int cellY, float &x, float &y, bool centre) const

View file

@ -209,7 +209,7 @@ namespace MWWorld
virtual void scaleObject (const Ptr& ptr, float scale);
virtual void rotateObject (const Ptr& ptr,float x,float y,float z);
virtual void rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust = false);
virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false)
const;