1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-02-13 20:09:40 +00:00

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 add_openmw_dir (mwinput
inputmanager inputmanager
mouselookevent
) )
add_openmw_dir (mwgui add_openmw_dir (mwgui

View file

@ -186,7 +186,7 @@ namespace MWBase
virtual void scaleObject (const MWWorld::Ptr& ptr, float scale) = 0; 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) virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false)
const = 0; const = 0;

View file

@ -6,7 +6,6 @@
#include <openengine/gui/events.hpp> #include <openengine/gui/events.hpp>
#include <openengine/ogre/exitlistener.hpp> #include <openengine/ogre/exitlistener.hpp>
#include <openengine/ogre/mouselook.hpp>
#include <openengine/ogre/renderer.hpp> #include <openengine/ogre/renderer.hpp>
#include "../mwgui/window_manager.hpp" #include "../mwgui/window_manager.hpp"
@ -16,12 +15,12 @@
#include <libs/platform/strings.h> #include <libs/platform/strings.h>
#include "mouselookevent.hpp"
#include "../engine.hpp" #include "../engine.hpp"
#include "../mwworld/player.hpp" #include "../mwworld/player.hpp"
#include "../mwrender/player.hpp"
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <OgreRoot.h> #include <OgreRoot.h>
@ -82,7 +81,7 @@ namespace MWInput
OEngine::Render::ExitListener exit; OEngine::Render::ExitListener exit;
Mangle::Input::OISDriver input; Mangle::Input::OISDriver input;
OEngine::Input::Poller poller; OEngine::Input::Poller poller;
OEngine::Render::MouseLookEventPtr mouse; MouseLookEventPtr mouse;
OEngine::GUI::EventInjectorPtr guiEvents; OEngine::GUI::EventInjectorPtr guiEvents;
MWWorld::Player &player; MWWorld::Player &player;
MWGui::WindowManager &windows; MWGui::WindowManager &windows;
@ -279,8 +278,7 @@ private:
// Add the exit listener // Add the exit listener
ogre.getRoot()->addFrameListener(&exit); ogre.getRoot()->addFrameListener(&exit);
// Set up the mouse handler and tell it about the player camera mouse = MouseLookEventPtr(new MouseLookEvent());
mouse = MouseLookEventPtr(new MouseLookEvent(player.getRenderer()->getCamera()));
// This event handler pumps events into MyGUI // This event handler pumps events into MyGUI
guiEvents = EventInjectorPtr(new EventInjector(windows.getGui())); guiEvents = EventInjectorPtr(new EventInjector(windows.getGui()));
@ -419,7 +417,7 @@ private:
if(guiMode) if(guiMode)
{ {
// Disable mouse look // Disable mouse look
mouse->setCamera(NULL); mouse->disable();
// Enable GUI events // Enable GUI events
guiEvents->enabled = true; guiEvents->enabled = true;
@ -428,7 +426,7 @@ private:
{ {
// Start mouse-looking again. TODO: This should also allow // Start mouse-looking again. TODO: This should also allow
// for other ways to disable mouselook, like paralyzation. // for other ways to disable mouselook, like paralyzation.
mouse->setCamera(player.getRenderer()->getCamera()); mouse->enable();
// Disable GUI events // Disable GUI events
guiEvents->enabled = false; 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,15 +1,21 @@
#include "player.hpp" #include "player.hpp"
#include <OgreSceneNode.h> #include <OgreSceneNode.h>
#include <OgreCamera.h>
#include "../mwworld/ptr.hpp"
#include "../mwworld/refdata.hpp"
namespace MWRender namespace MWRender
{ {
Player::Player (Ogre::Camera *camera, Ogre::SceneNode* node) 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::SceneNode *sceneNode = mNode;
Ogre::Node* yawNode = sceneNode->getChildIterator().getNext(); Ogre::Node* yawNode = sceneNode->getChildIterator().getNext();
@ -18,17 +24,35 @@ namespace MWRender
// we are only interested in X and Y rotation // we are only interested in X and Y rotation
// Rotate around X axis // Rotate around X axis
Ogre::Quaternion xr(Ogre::Radian(x), Ogre::Vector3::UNIT_X); Ogre::Quaternion xr(Ogre::Radian(rot.x), Ogre::Vector3::UNIT_X);
// Rotate around Y axis // Rotate around Y axis
Ogre::Quaternion yr(Ogre::Radian(-z), Ogre::Vector3::UNIT_Y); Ogre::Quaternion yr(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Y);
pitchNode->setOrientation(xr); pitchNode->setOrientation(xr);
yawNode->setOrientation(yr); yawNode->setOrientation(yr);
return !mVanityModeEnabled;
} }
std::string Player::getHandle() const std::string Player::getHandle() const
{ {
return mNode->getName(); 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> #include <string>
namespace Ogre namespace Ogre
{ {
class Vector3;
class Camera; class Camera;
class SceneNode; class SceneNode;
} }
namespace MWWorld
{
class Ptr;
}
namespace MWRender namespace MWRender
{ {
/// \brief Player character rendering and camera control /// \brief Player character rendering and camera control
@ -17,17 +24,28 @@ namespace MWRender
Ogre::Camera *mCamera; Ogre::Camera *mCamera;
Ogre::SceneNode* mNode; Ogre::SceneNode* mNode;
bool mFirstPersonView;
bool mVanityModeEnabled;
public: public:
Player (Ogre::Camera *camera, Ogre::SceneNode* mNode); Player (Ogre::Camera *camera, Ogre::SceneNode* mNode);
Ogre::Camera *getCamera() { return mCamera; }
/// Set where the player is looking at. Uses Morrowind (euler) angles /// Set where the player is looking at. Uses Morrowind (euler) angles
void setRot(float x, float y, float z); bool setRotation(const Ogre::Vector3 &rot);
bool adjustRotation(const Ogre::Vector3 &rot);
std::string getHandle() const; std::string getHandle() const;
Ogre::SceneNode* getNode() {return mNode;}
void attachTo(const MWWorld::Ptr &);
void toggleViewMode() {
mFirstPersonView = !mFirstPersonView;
}
void toggleVanityMode() {
mVanityModeEnabled = !mVanityModeEnabled;
}
}; };
} }

View file

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

View file

@ -183,10 +183,6 @@ MWRender::Actors& RenderingManager::getActors(){
return mActors; return mActors;
} }
MWRender::Player& RenderingManager::getPlayer(){
return (*mPlayer);
}
OEngine::Render::Fader* RenderingManager::getFader() OEngine::Render::Fader* RenderingManager::getFader()
{ {
return mRendering.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::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){ 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 } // 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); RenderingManager(OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine);
virtual ~RenderingManager(); virtual ~RenderingManager();
void attachCameraTo(const MWWorld::Ptr &ptr);
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
SkyManager* getSkyManager(); SkyManager* getSkyManager();
Compositors* getCompositors(); Compositors* getCompositors();
@ -89,7 +85,7 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
void moveObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& position); void moveObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& position);
void scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& scale); 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 setWaterHeight(const float height);
void toggleWater(); void toggleWater();

View file

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

View file

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

View file

@ -14,11 +14,6 @@ namespace MWBase
class World; class World;
} }
namespace MWRender
{
class Player;
}
namespace MWWorld namespace MWWorld
{ {
class CellStore; class CellStore;
@ -28,7 +23,6 @@ namespace MWWorld
{ {
LiveCellRef<ESM::NPC> mPlayer; LiveCellRef<ESM::NPC> mPlayer;
MWWorld::CellStore *mCellStore; MWWorld::CellStore *mCellStore;
MWRender::Player *mRenderer;
std::string mName; std::string mName;
bool mMale; bool mMale;
std::string mRace; std::string mRace;
@ -38,13 +32,10 @@ namespace MWWorld
int mForwardBackward; int mForwardBackward;
public: public:
Player(MWRender::Player *renderer, const ESM::NPC *player, const MWBase::World& world); Player(const ESM::NPC *player, const MWBase::World& world);
~Player(); ~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) void setCell (MWWorld::CellStore *cellStore)
{ {
mCellStore = cellStore; mCellStore = cellStore;
@ -56,8 +47,6 @@ namespace MWWorld
return ptr; return ptr;
} }
MWRender::Player *getRenderer() { return mRenderer; }
void setName (const std::string& name) void setName (const std::string& name)
{ {
mName = name; mName = name;

View file

@ -149,7 +149,7 @@ namespace MWWorld
if (adjustPlayerPos) { if (adjustPlayerPos) {
world->moveObject(player, pos.pos[0], pos.pos[1], pos.pos[2]); 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); world->getPlayer().setCell(cell);

View file

@ -189,8 +189,9 @@ namespace MWWorld
mEsm.open (masterPath.string()); mEsm.open (masterPath.string());
mStore.load (mEsm); mStore.load (mEsm);
MWRender::Player* play = &(mRendering->getPlayer()); mPlayer = new MWWorld::Player (mStore.npcs.find ("player"), *this);
mPlayer = new MWWorld::Player (play, mStore.npcs.find ("player"), *this); mRendering->attachCameraTo(mPlayer->getPlayer());
mPhysics->addActor (mPlayer->getPlayer().getRefData().getHandle(), "", Ogre::Vector3 (0, 0, 0)); mPhysics->addActor (mPlayer->getPlayer().getRefData().getHandle(), "", Ogre::Vector3 (0, 0, 0));
// global variables // global variables
@ -598,19 +599,20 @@ namespace MWWorld
mPhysics->scaleObject( ptr.getRefData().getHandle(), scale ); 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(); mPhysics->rotateObject(
ptr.getRefData().getPosition().rot[1] = Ogre::Degree(y).valueRadians(); ptr.getRefData().getHandle(),
ptr.getRefData().getPosition().rot[2] = Ogre::Degree(z).valueRadians(); ptr.getRefData().getBaseNode()->getOrientation()
);
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());
} }
void World::indexToPosition (int cellX, int cellY, float &x, float &y, bool centre) const 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 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) virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false)
const; const;