mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-29 04:20:29 +00:00
Merge branch 'movement' of git://github.com/zinnschlag/openmw.git into collisions
This commit is contained in:
commit
1dc452ec91
@ -145,6 +145,7 @@ set(GAMEWORLD_HEADER
|
||||
mwworld/containerutil.hpp
|
||||
mwworld/player.hpp
|
||||
mwworld/doingphysics.hpp
|
||||
mwworld/cellfunctors.hpp
|
||||
)
|
||||
source_group(apps\\openmw\\mwworld FILES ${GAMEWORLD} ${GAMEWORLD_HEADER})
|
||||
|
||||
@ -206,6 +207,7 @@ set(GAMEMECHANICS_HEADER
|
||||
mwmechanics/stat.hpp
|
||||
mwmechanics/creaturestats.hpp
|
||||
mwmechanics/magiceffects.hpp
|
||||
mwmechanics/movement.hpp
|
||||
)
|
||||
source_group(apps\\openmw\\mwmechanics FILES ${GAMEMECHANICS} ${GAMEMECHANICS_HEADER})
|
||||
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
#include <OgreVector3.h>
|
||||
|
||||
#include "components/esm/records.hpp"
|
||||
#include <components/esm_store/cell_store.hpp>
|
||||
#include <components/misc/fileops.hpp>
|
||||
@ -158,7 +160,8 @@ bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt)
|
||||
mEnvironment.mWorld->markCellAsUnchanged();
|
||||
|
||||
// update actors
|
||||
mEnvironment.mMechanicsManager->update();
|
||||
std::vector<std::pair<std::string, Ogre::Vector3> > movement;
|
||||
mEnvironment.mMechanicsManager->update (movement);
|
||||
|
||||
if (focusFrameCounter++ == focusUpdateFrame)
|
||||
{
|
||||
@ -179,6 +182,8 @@ bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt)
|
||||
|
||||
focusFrameCounter = 0;
|
||||
}
|
||||
|
||||
mEnvironment.mWorld->doPhysics (movement, mEnvironment.mFrameDuration);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@ -388,7 +393,7 @@ void OMW::Engine::go()
|
||||
else
|
||||
{
|
||||
pos.pos[0] = pos.pos[1] = 0;
|
||||
mEnvironment.mWorld->changeCell (mCellName, pos);
|
||||
mEnvironment.mWorld->changeToInteriorCell (mCellName, pos);
|
||||
}
|
||||
|
||||
// Sets up the input system
|
||||
|
@ -23,6 +23,7 @@ namespace MWClass
|
||||
{
|
||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||
cellRender.insertMesh ("meshes\\" + model);
|
||||
cellRender.insertObjectPhysics();
|
||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ namespace MWClass
|
||||
{
|
||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||
cellRender.insertMesh ("meshes\\" + model);
|
||||
cellRender.insertObjectPhysics();
|
||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ namespace MWClass
|
||||
{
|
||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||
cellRender.insertMesh ("meshes\\" + model);
|
||||
cellRender.insertObjectPhysics();
|
||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ namespace MWClass
|
||||
{
|
||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||
cellRender.insertMesh ("meshes\\" + model);
|
||||
cellRender.insertObjectPhysics();
|
||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ namespace MWClass
|
||||
{
|
||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||
cellRender.insertMesh ("meshes\\" + model);
|
||||
cellRender.insertObjectPhysics();
|
||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ namespace MWClass
|
||||
{
|
||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||
cellRender.insertMesh ("meshes\\" + model);
|
||||
cellRender.insertObjectPhysics();
|
||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ namespace MWClass
|
||||
{
|
||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||
cellRender.insertMesh ("meshes\\" + model);
|
||||
cellRender.insertActorPhysics();
|
||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ namespace MWClass
|
||||
{
|
||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||
cellRender.insertMesh ("meshes\\" + model);
|
||||
cellRender.insertObjectPhysics();
|
||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ namespace MWClass
|
||||
{
|
||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||
cellRender.insertMesh ("meshes\\" + model);
|
||||
cellRender.insertObjectPhysics();
|
||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ namespace MWClass
|
||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||
|
||||
cellRender.insertMesh ("meshes\\" + model);
|
||||
cellRender.insertObjectPhysics();
|
||||
|
||||
// Extract the color and convert to floating point
|
||||
const int color = ref->base->data.color;
|
||||
|
@ -26,6 +26,7 @@ namespace MWClass
|
||||
{
|
||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||
cellRender.insertMesh ("meshes\\" + model);
|
||||
cellRender.insertObjectPhysics();
|
||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ namespace MWClass
|
||||
{
|
||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||
cellRender.insertMesh ("meshes\\" + model);
|
||||
cellRender.insertObjectPhysics();
|
||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||
}
|
||||
}
|
||||
|
@ -256,8 +256,9 @@ namespace MWClass
|
||||
cellRender.insertMesh (headModel, Ogre::Vector3( 0, 0, 5), axis, Ogre::Radian(0), npcName + "head", neckandup, neckNumbers);
|
||||
neckandup[neckNumbers++] = npcName + "head";
|
||||
cellRender.insertMesh (hairModel, Ogre::Vector3( 0, -1, 0), axis, Ogre::Radian(0), npcName + "hair", neckandup, neckNumbers);
|
||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||
|
||||
cellRender.insertActorPhysics();
|
||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||
}
|
||||
|
||||
void Npc::enable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const
|
||||
@ -392,7 +393,8 @@ namespace MWClass
|
||||
{
|
||||
case Run:
|
||||
|
||||
throw std::runtime_error ("run stance not manually setable for NPCs");
|
||||
stats.mRun = set;
|
||||
break;
|
||||
|
||||
case Sneak:
|
||||
|
||||
@ -414,7 +416,10 @@ namespace MWClass
|
||||
{
|
||||
case Run:
|
||||
|
||||
return ignoreForce ? false : stats.mForceRun;
|
||||
if (!ignoreForce && stats.mForceRun)
|
||||
return true;
|
||||
|
||||
return stats.mRun;
|
||||
|
||||
case Sneak:
|
||||
|
||||
@ -436,6 +441,35 @@ namespace MWClass
|
||||
return getStance (ptr, Run) ? 600 : 300; // TODO calculate these values from stats
|
||||
}
|
||||
|
||||
MWMechanics::Movement& Npc::getMovementSettings (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
if (!ptr.getRefData().getMovement().get())
|
||||
{
|
||||
boost::shared_ptr<MWMechanics::Movement> movement (
|
||||
new MWMechanics::Movement);
|
||||
|
||||
ptr.getRefData().getMovement() = movement;
|
||||
}
|
||||
|
||||
return *ptr.getRefData().getMovement();
|
||||
}
|
||||
|
||||
Ogre::Vector3 Npc::getMovementVector (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
Ogre::Vector3 vector (0, 0, 0);
|
||||
|
||||
if (ptr.getRefData().getMovement().get())
|
||||
{
|
||||
vector.x = - ptr.getRefData().getMovement()->mLeftRight * 200;
|
||||
vector.z = - ptr.getRefData().getMovement()->mForwardBackward * 200;
|
||||
|
||||
if (getStance (ptr, Run, false))
|
||||
vector *= 2;
|
||||
}
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
void Npc::registerSelf()
|
||||
{
|
||||
boost::shared_ptr<Class> instance (new Npc);
|
||||
|
@ -56,6 +56,13 @@ namespace MWClass
|
||||
virtual float getSpeed (const MWWorld::Ptr& ptr) const;
|
||||
///< Return movement speed.
|
||||
|
||||
virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const;
|
||||
///< Return desired movement.
|
||||
|
||||
virtual Ogre::Vector3 getMovementVector (const MWWorld::Ptr& ptr) const;
|
||||
///< Return desired movement vector (determined based on movement settings,
|
||||
/// stance and stats).
|
||||
|
||||
static void registerSelf();
|
||||
};
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ namespace MWClass
|
||||
{
|
||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||
cellRender.insertMesh ("meshes\\" + model);
|
||||
cellRender.insertObjectPhysics();
|
||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ namespace MWClass
|
||||
{
|
||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||
cellRender.insertMesh ("meshes\\" + model);
|
||||
cellRender.insertObjectPhysics();
|
||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ namespace MWClass
|
||||
{
|
||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||
cellRender.insertMesh ("meshes\\" + model);
|
||||
cellRender.insertObjectPhysics();
|
||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ namespace MWClass
|
||||
{
|
||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||
cellRender.insertMesh ("meshes\\" + model);
|
||||
cellRender.insertObjectPhysics();
|
||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ namespace MWClass
|
||||
{
|
||||
MWRender::Rendering rendering (cellRender, ref->ref);
|
||||
cellRender.insertMesh ("meshes\\" + model);
|
||||
cellRender.insertObjectPhysics();
|
||||
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
|
||||
}
|
||||
}
|
||||
|
@ -41,27 +41,25 @@ namespace MWInput
|
||||
|
||||
A_MoveLeft, // Move player left / right
|
||||
A_MoveRight,
|
||||
A_MoveUp, // Move up / down
|
||||
A_MoveDown,
|
||||
A_MoveForward, // Forward / Backward
|
||||
A_MoveBackward,
|
||||
|
||||
A_Activate,
|
||||
|
||||
A_Use, //Use weapon, spell, etc.
|
||||
A_Use, //Use weapon, spell, etc.
|
||||
A_Jump,
|
||||
A_AutoMove, //Toggle Auto-move forward
|
||||
A_Rest, //Rest
|
||||
A_Journal, //Journal
|
||||
A_Weapon, //Draw/Sheath weapon
|
||||
A_Spell, //Ready/Unready Casting
|
||||
A_AlwaysRun, //Toggle Always Run
|
||||
A_AutoMove, //Toggle Auto-move forward
|
||||
A_Rest, //Rest
|
||||
A_Journal, //Journal
|
||||
A_Weapon, //Draw/Sheath weapon
|
||||
A_Spell, //Ready/Unready Casting
|
||||
A_AlwaysRun, //Toggle Always Run
|
||||
A_CycleSpellLeft, //cycling through spells
|
||||
A_CycleSpellRight,
|
||||
A_CycleWeaponLeft,//Cycling through weapons
|
||||
A_CycleWeaponRight,
|
||||
A_ToggleSneak, //Toggles Sneak, add Push-Sneak later
|
||||
A_ToggleWalk, //Toggle Walking/Running
|
||||
A_ToggleSneak, //Toggles Sneak, add Push-Sneak later
|
||||
A_ToggleWalk, //Toggle Walking/Running
|
||||
|
||||
A_QuickSave,
|
||||
A_QuickLoad,
|
||||
@ -143,24 +141,19 @@ namespace MWInput
|
||||
|
||||
void toggleAutoMove()
|
||||
{
|
||||
if (player.getAutoMove() == false)
|
||||
{
|
||||
player.setAutoMove(true);
|
||||
} else {
|
||||
player.setAutoMove(false);
|
||||
}
|
||||
player.setAutoMove (!player.getAutoMove());
|
||||
}
|
||||
|
||||
void toggleWalking()
|
||||
{
|
||||
player.setisWalking(true);
|
||||
player.toggleRunning();
|
||||
}
|
||||
|
||||
// Exit program now button (which is disabled in GUI mode)
|
||||
void exitNow()
|
||||
{
|
||||
if(!windows.isGuiMode())
|
||||
exit.exitNow();
|
||||
if(!windows.isGuiMode())
|
||||
exit.exitNow();
|
||||
}
|
||||
|
||||
public:
|
||||
@ -262,73 +255,54 @@ namespace MWInput
|
||||
poller.bind(A_MoveRight, KC_D);
|
||||
poller.bind(A_MoveForward, KC_W);
|
||||
poller.bind(A_MoveBackward, KC_S);
|
||||
|
||||
// Use shift and ctrl for up and down
|
||||
poller.bind(A_MoveUp, KC_LSHIFT);
|
||||
poller.bind(A_MoveDown, KC_LCONTROL);
|
||||
}
|
||||
|
||||
//NOTE: Used to check for movement keys
|
||||
bool frameStarted(const Ogre::FrameEvent &evt)
|
||||
{
|
||||
// Tell OIS to handle all input events
|
||||
input.capture();
|
||||
// Tell OIS to handle all input events
|
||||
input.capture();
|
||||
|
||||
// Update windows/gui as a result of input events
|
||||
// For instance this could mean opening a new window/dialog,
|
||||
// by doing this after the input events are handled we
|
||||
// ensure that window/gui changes appear quickly while
|
||||
// avoiding that window/gui changes does not happen in
|
||||
// event callbacks (which may crash)
|
||||
windows.update();
|
||||
// Update windows/gui as a result of input events
|
||||
// For instance this could mean opening a new window/dialog,
|
||||
// by doing this after the input events are handled we
|
||||
// ensure that window/gui changes appear quickly while
|
||||
// avoiding that window/gui changes does not happen in
|
||||
// event callbacks (which may crash)
|
||||
windows.update();
|
||||
|
||||
// Disable movement in Gui mode
|
||||
if(windows.isGuiMode()) return true;
|
||||
// Disable movement in Gui mode
|
||||
if (windows.isGuiMode()) return true;
|
||||
|
||||
float speed = 300 * evt.timeSinceLastFrame; //placeholder player speed?
|
||||
//float TESTwalkSpeed = 100 * evt.timeSinceLastFrame; //How about another?
|
||||
// Configure player movement according to keyboard input. Actual movement will
|
||||
// be done in the physics system.
|
||||
if (poller.isDown(A_MoveLeft))
|
||||
{
|
||||
player.setAutoMove (false);
|
||||
player.setLeftRight (1);
|
||||
}
|
||||
else if (poller.isDown(A_MoveRight))
|
||||
{
|
||||
player.setAutoMove (false);
|
||||
player.setLeftRight (-1);
|
||||
}
|
||||
else
|
||||
player.setLeftRight (0);
|
||||
|
||||
float moveX = 0, moveY = 0, moveZ = 0;
|
||||
if (poller.isDown(A_MoveForward))
|
||||
{
|
||||
player.setAutoMove (false);
|
||||
player.setForwardBackward (1);
|
||||
}
|
||||
else if (poller.isDown(A_MoveBackward))
|
||||
{
|
||||
player.setAutoMove (false);
|
||||
player.setForwardBackward (-1);
|
||||
}
|
||||
else
|
||||
player.setForwardBackward (0);
|
||||
|
||||
//execute Automove - condition checked in function
|
||||
player.executeAutoMove((float)evt.timeSinceLastFrame); //or since last frame?
|
||||
|
||||
//Poll and execute movement keys - will disable automove if pressed.
|
||||
if(poller.isDown(A_MoveLeft))
|
||||
{
|
||||
player.setAutoMove(false);
|
||||
moveX -= speed;
|
||||
}
|
||||
|
||||
if(poller.isDown(A_MoveRight))
|
||||
{
|
||||
player.setAutoMove(false);
|
||||
moveX += speed;
|
||||
}
|
||||
|
||||
if(poller.isDown(A_MoveForward))
|
||||
{
|
||||
player.setAutoMove(false);
|
||||
moveZ -= speed;
|
||||
}
|
||||
|
||||
if(poller.isDown(A_MoveBackward))
|
||||
{
|
||||
player.setAutoMove(false);
|
||||
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)
|
||||
player.moveRel(moveX, moveY, moveZ);
|
||||
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Switch between gui modes. Besides controlling the Gui windows
|
||||
|
@ -234,11 +234,17 @@ namespace MWMechanics
|
||||
|
||||
void MechanicsManager::removeActor (const MWWorld::Ptr& ptr)
|
||||
{
|
||||
if (ptr==mWatched)
|
||||
mWatched = MWWorld::Ptr();
|
||||
|
||||
mActors.erase (ptr);
|
||||
}
|
||||
|
||||
void MechanicsManager::dropActors (const MWWorld::Ptr::CellStore *cellStore)
|
||||
{
|
||||
if (!mWatched.isEmpty() && mWatched.getCell()==cellStore)
|
||||
mWatched = MWWorld::Ptr();
|
||||
|
||||
std::set<MWWorld::Ptr>::iterator iter = mActors.begin();
|
||||
|
||||
while (iter!=mActors.end())
|
||||
@ -255,7 +261,7 @@ namespace MWMechanics
|
||||
mWatched = ptr;
|
||||
}
|
||||
|
||||
void MechanicsManager::update()
|
||||
void MechanicsManager::update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement)
|
||||
{
|
||||
if (!mWatched.isEmpty())
|
||||
{
|
||||
@ -350,6 +356,15 @@ namespace MWMechanics
|
||||
|
||||
mEnvironment.mWindowManager->configureSkills (majorSkills, minorSkills);
|
||||
}
|
||||
|
||||
for (std::set<MWWorld::Ptr>::iterator iter (mActors.begin()); iter!=mActors.end();
|
||||
++iter)
|
||||
{
|
||||
Ogre::Vector3 vector = MWWorld::Class::get (*iter).getMovementVector (*iter);
|
||||
|
||||
if (vector!=Ogre::Vector3::ZERO)
|
||||
movement.push_back (std::make_pair (iter->getRefData().getHandle(), vector));
|
||||
}
|
||||
}
|
||||
|
||||
void MechanicsManager::setPlayerName (const std::string& name)
|
||||
|
@ -2,12 +2,19 @@
|
||||
#define GAME_MWMECHANICS_MECHANICSMANAGER_H
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
#include "creaturestats.hpp"
|
||||
#include "npcstats.hpp"
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class Vector3;
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
class Environment;
|
||||
@ -53,8 +60,8 @@ namespace MWMechanics
|
||||
///< On each update look for changes in a previously registered actor and update the
|
||||
/// GUI accordingly.
|
||||
|
||||
void update();
|
||||
///< Update actor stats
|
||||
void update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement);
|
||||
///< Update actor stats and store desired velocity vectors in \a movement
|
||||
|
||||
void setPlayerName (const std::string& name);
|
||||
///< Set player name.
|
||||
|
16
apps/openmw/mwmechanics/movement.hpp
Normal file
16
apps/openmw/mwmechanics/movement.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef GAME_MWMECHANICS_MOVEMENT_H
|
||||
#define GAME_MWMECHANICS_MOVEMENT_H
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
/// Desired movement for an actor
|
||||
struct Movement
|
||||
{
|
||||
signed char mLeftRight; // 1: wants to move left, -1: wants to move right
|
||||
signed char mForwardBackward; // 1:wants to move forward, -1: wants to move backward
|
||||
|
||||
Movement() : mLeftRight (0), mForwardBackward (0) {}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -21,10 +21,12 @@ namespace MWMechanics
|
||||
|
||||
bool mForceRun;
|
||||
bool mForceSneak;
|
||||
bool mRun;
|
||||
bool mSneak;
|
||||
bool mCombat;
|
||||
|
||||
NpcStats() : mForceRun (false), mForceSneak (false), mSneak (false), mCombat (false) {}
|
||||
NpcStats() : mForceRun (false), mForceSneak (false), mRun (false), mSneak (false),
|
||||
mCombat (false) {}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,9 @@ namespace MWRender
|
||||
|
||||
virtual void scaleMesh(Ogre::Vector3 axis, std::string sceneNodeName[], int elements) = 0;
|
||||
|
||||
virtual void insertObjectPhysics() = 0;
|
||||
|
||||
virtual void insertActorPhysics() = 0;
|
||||
|
||||
/// insert a light related to the most recent insertBegin call.
|
||||
virtual void insertLight(float r, float g, float b, float radius) = 0;
|
||||
|
@ -58,6 +58,8 @@ void ExteriorCellRender::insertBegin (ESM::CellRef &ref)
|
||||
|
||||
// Rotates first around z, then y, then x
|
||||
mInsert->setOrientation(xr*yr*zr);
|
||||
|
||||
mInsertMesh.clear();
|
||||
}
|
||||
|
||||
|
||||
@ -81,18 +83,18 @@ void ExteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec,
|
||||
if(sceneParent[i] != "" && parent->getChild(sceneParent[i]))
|
||||
parent = dynamic_cast<Ogre::SceneNode*> (parent->getChild(sceneParent[i]));
|
||||
}
|
||||
|
||||
|
||||
mNpcPart = parent->createChildSceneNode(sceneNodeName);
|
||||
NIFLoader::load(mesh);
|
||||
MovableObject *ent = mScene.getMgr()->createEntity(mesh);
|
||||
|
||||
|
||||
mNpcPart->translate(vec);
|
||||
mNpcPart->rotate(axis, angle);
|
||||
// mNpcPart->translate(vec);
|
||||
//mNpcPart->rotate(axis, angle);
|
||||
mNpcPart->attachObject(ent);
|
||||
//mNpcPart->
|
||||
|
||||
|
||||
}
|
||||
*/
|
||||
void ExteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements)
|
||||
@ -108,7 +110,7 @@ void ExteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec,
|
||||
if(sceneParent[i] != "" && parent->getChild(sceneParent[i]))
|
||||
parent = dynamic_cast<Ogre::SceneNode*> (parent->getChild(sceneParent[i]));
|
||||
}
|
||||
|
||||
|
||||
mNpcPart = parent->createChildSceneNode(sceneNodeName);
|
||||
MeshPtr good2 = NIFLoader::load(mesh);
|
||||
|
||||
@ -120,7 +122,7 @@ void ExteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec,
|
||||
mNpcPart->rotate(axis, angle);
|
||||
}
|
||||
else{
|
||||
|
||||
|
||||
mNpcPart->rotate(axis, angle);
|
||||
mNpcPart->translate(vec);
|
||||
}
|
||||
@ -202,6 +204,22 @@ void ExteriorCellRender::insertMesh(const std::string &mesh)
|
||||
NIFLoader::load(mesh);
|
||||
MovableObject *ent = mScene.getMgr()->createEntity(mesh);
|
||||
mInsert->attachObject(ent);
|
||||
|
||||
if (mInsertMesh.empty())
|
||||
mInsertMesh = mesh;
|
||||
}
|
||||
|
||||
void ExteriorCellRender::insertObjectPhysics()
|
||||
{
|
||||
if (!mInsertMesh.empty())
|
||||
mScene.addObject (mInsert->getName(), mInsertMesh, mInsert->getOrientation(),
|
||||
mInsert->getScale().x, mInsert->getPosition());
|
||||
}
|
||||
|
||||
void ExteriorCellRender::insertActorPhysics()
|
||||
{
|
||||
if (!mInsertMesh.empty())
|
||||
mScene.addActor (mInsert->getName(), mInsertMesh, mInsert->getPosition());
|
||||
}
|
||||
|
||||
// insert a light related to the most recent insertBegin call.
|
||||
|
@ -54,6 +54,7 @@ namespace MWRender
|
||||
Ogre::SceneNode *mBase;
|
||||
|
||||
Ogre::SceneNode *mInsert;
|
||||
std::string mInsertMesh;
|
||||
Ogre::SceneNode *mNpcPart;
|
||||
|
||||
// 0 normal, 1 more bright, 2 max
|
||||
@ -67,11 +68,15 @@ namespace MWRender
|
||||
/// insert a mesh related to the most recent insertBegin call.
|
||||
virtual void insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements);
|
||||
virtual void insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements, bool translateFirst);
|
||||
|
||||
|
||||
virtual void insertMesh(const std::string &mesh);
|
||||
virtual void rotateMesh(Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName[], int elements);
|
||||
virtual void scaleMesh(Ogre::Vector3 axis, std::string sceneNodeName[], int elements);
|
||||
|
||||
virtual void insertObjectPhysics();
|
||||
|
||||
virtual void insertActorPhysics();
|
||||
|
||||
/// insert a light related to the most recent insertBegin call.
|
||||
virtual void insertLight(float r, float g, float b, float radius);
|
||||
|
||||
@ -85,7 +90,7 @@ namespace MWRender
|
||||
void configureFog();
|
||||
|
||||
void setAmbientMode();
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
@ -60,6 +60,8 @@ void InteriorCellRender::insertBegin (ESM::CellRef &ref)
|
||||
|
||||
// Rotates first around z, then y, then x
|
||||
insert->setOrientation(xr*yr*zr);
|
||||
|
||||
mInsertMesh.clear();
|
||||
}
|
||||
|
||||
// insert a mesh related to the most recent insertBegin call.
|
||||
@ -100,7 +102,7 @@ void InteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec,
|
||||
if(sceneParent[i] != "" && parent->getChild(sceneParent[i]))
|
||||
parent = dynamic_cast<Ogre::SceneNode*> (parent->getChild(sceneParent[i]));
|
||||
}
|
||||
|
||||
|
||||
npcPart = parent->createChildSceneNode(sceneNodeName);
|
||||
//npcPart->showBoundingBox(true);
|
||||
|
||||
@ -108,7 +110,7 @@ void InteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec,
|
||||
|
||||
MovableObject *ent = scene.getMgr()->createEntity(mesh);
|
||||
//ent->extr
|
||||
|
||||
|
||||
// MovableObject *ent2 = scene.getMgr()->createEntity(bounds
|
||||
// );
|
||||
//ent->
|
||||
@ -119,7 +121,7 @@ void InteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec,
|
||||
npcPart->rotate(axis, angle);
|
||||
}
|
||||
else{
|
||||
|
||||
|
||||
npcPart->rotate(axis, angle);
|
||||
npcPart->translate(vec);
|
||||
}
|
||||
@ -185,6 +187,22 @@ void InteriorCellRender::insertMesh(const std::string &mesh)
|
||||
NIFLoader::load(mesh);
|
||||
MovableObject *ent = scene.getMgr()->createEntity(mesh);
|
||||
insert->attachObject(ent);
|
||||
|
||||
if (mInsertMesh.empty())
|
||||
mInsertMesh = mesh;
|
||||
}
|
||||
|
||||
void InteriorCellRender::insertObjectPhysics()
|
||||
{
|
||||
if (!mInsertMesh.empty())
|
||||
scene.addObject (insert->getName(), mInsertMesh, insert->getOrientation(),
|
||||
insert->getScale().x, insert->getPosition());
|
||||
}
|
||||
|
||||
void InteriorCellRender::insertActorPhysics()
|
||||
{
|
||||
if (!mInsertMesh.empty())
|
||||
scene.addActor (insert->getName(), mInsertMesh, insert->getPosition());
|
||||
}
|
||||
|
||||
// insert a light related to the most recent insertBegin call.
|
||||
|
@ -54,6 +54,7 @@ namespace MWRender
|
||||
Ogre::SceneNode *base;
|
||||
|
||||
Ogre::SceneNode *insert;
|
||||
std::string mInsertMesh;
|
||||
Ogre::SceneNode *npcPart;
|
||||
|
||||
// 0 normal, 1 more bright, 2 max
|
||||
@ -69,6 +70,11 @@ namespace MWRender
|
||||
virtual void insertMesh(const std::string &mesh);
|
||||
virtual void insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements);
|
||||
virtual void insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements, bool translateFirst);
|
||||
|
||||
virtual void insertObjectPhysics();
|
||||
|
||||
virtual void insertActorPhysics();
|
||||
|
||||
/// insert a light related to the most recent insertBegin call.
|
||||
virtual void insertLight(float r, float g, float b, float radius);
|
||||
|
||||
|
@ -42,7 +42,10 @@ MWScene::MWScene(OEngine::Render::OgreRenderer &_rend)
|
||||
//used to obtain ingame information of ogre objects (which are faced or selected)
|
||||
mRaySceneQuery = rend.getScene()->createRayQuery(Ray());
|
||||
|
||||
mPlayer = new MWRender::Player (getCamera());
|
||||
Ogre::SceneNode *playerNode = mwRoot->createChildSceneNode();
|
||||
playerNode->attachObject (getCamera());
|
||||
|
||||
mPlayer = new MWRender::Player (getCamera(), playerNode->getName());
|
||||
}
|
||||
|
||||
MWScene::~MWScene()
|
||||
@ -99,16 +102,24 @@ std::pair<std::string, float> MWScene::getFacedHandle (MWWorld::World& world)
|
||||
return std::pair<std::string, float>(handle, distance);
|
||||
}
|
||||
|
||||
void MWScene::doPhysics (float duration, MWWorld::World& world)
|
||||
void MWScene::doPhysics (float duration, MWWorld::World& world,
|
||||
const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
|
||||
{
|
||||
// stop changes to world from being reported back to the physics system
|
||||
MWWorld::DoingPhysics scopeGuard;
|
||||
|
||||
}
|
||||
// move object directly for now -> TODO replace with physics
|
||||
for (std::vector<std::pair<std::string, Ogre::Vector3> >::const_iterator iter (actors.begin());
|
||||
iter!=actors.end(); ++iter)
|
||||
{
|
||||
MWWorld::Ptr ptr = world.getPtrViaHandle (iter->first);
|
||||
|
||||
void MWScene::setMovement (const std::vector<std::string, Ogre::Vector3>& actors)
|
||||
{
|
||||
Ogre::SceneNode *sceneNode = rend.getScene()->getSceneNode (iter->first);
|
||||
|
||||
Ogre::Vector3 newPos = sceneNode->getPosition() + sceneNode->getOrientation() * iter->second;
|
||||
|
||||
world.moveObject (ptr, newPos.x, newPos.y, newPos.z);
|
||||
}
|
||||
}
|
||||
|
||||
void MWScene::addObject (const std::string& handle, const std::string& mesh,
|
||||
@ -128,8 +139,9 @@ void MWScene::removeObject (const std::string& handle)
|
||||
|
||||
}
|
||||
|
||||
void MWScene::moveObject (const std::string& handle, const Ogre::Vector3& position)
|
||||
void MWScene::moveObject (const std::string& handle, const Ogre::Vector3& position, bool updatePhysics)
|
||||
{
|
||||
rend.getScene()->getSceneNode (handle)->setPosition (position);
|
||||
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <openengine/ogre/renderer.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
@ -60,11 +61,8 @@ namespace MWRender
|
||||
std::pair<std::string, float> getFacedHandle (MWWorld::World& world);
|
||||
|
||||
/// Run physics simulation and modify \a world accordingly.
|
||||
void doPhysics (float duration, MWWorld::World& world);
|
||||
|
||||
/// Inform phyiscs system about desired velocity vectors for actors
|
||||
/// (in Morrowind coordinates).
|
||||
void setMovement (const std::vector<std::string, Ogre::Vector3>& actors);
|
||||
void doPhysics (float duration, MWWorld::World& world,
|
||||
const std::vector<std::pair<std::string, Ogre::Vector3> >& actors);
|
||||
|
||||
/// Add object to physics system.
|
||||
void addObject (const std::string& handle, const std::string& mesh,
|
||||
@ -78,7 +76,7 @@ namespace MWRender
|
||||
void removeObject (const std::string& handle);
|
||||
|
||||
/// Move object.
|
||||
void moveObject (const std::string& handle, const Ogre::Vector3& position);
|
||||
void moveObject (const std::string& handle, const Ogre::Vector3& position, bool updatePhysics);
|
||||
|
||||
/// Change object's orientation.
|
||||
void rotateObject (const std::string& handle, const Ogre::Quaternion& rotation);
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
Player::Player (Ogre::Camera *camera) : mCamera (camera)
|
||||
Player::Player (Ogre::Camera *camera, const std::string& handle)
|
||||
: mCamera (camera), mHandle (handle)
|
||||
{}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef GAME_MWRENDER_PLAYER_H
|
||||
#define GAME_MWRENDER_PLAYER_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class Camera;
|
||||
@ -12,12 +14,15 @@ namespace MWRender
|
||||
class Player
|
||||
{
|
||||
Ogre::Camera *mCamera;
|
||||
std::string mHandle;
|
||||
|
||||
public:
|
||||
|
||||
Player (Ogre::Camera *camera);
|
||||
Player (Ogre::Camera *camera, const std::string& handle);
|
||||
|
||||
Ogre::Camera *getCamera() { return mCamera; }
|
||||
|
||||
std::string getHandle() const { return mHandle; }
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ namespace MWScript
|
||||
else
|
||||
{
|
||||
pos.pos[0] = pos.pos[1] = 0;
|
||||
context.getWorld().changeCell (cell, pos);
|
||||
context.getWorld().changeToInteriorCell (cell, pos);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -16,6 +16,6 @@ namespace MWWorld
|
||||
if (mCellName.empty())
|
||||
environment.mWorld->changeToExteriorCell (mPosition);
|
||||
else
|
||||
environment.mWorld->changeCell (mCellName, mPosition);
|
||||
environment.mWorld->changeToInteriorCell (mCellName, mPosition);
|
||||
}
|
||||
}
|
||||
|
31
apps/openmw/mwworld/cellfunctors.hpp
Normal file
31
apps/openmw/mwworld/cellfunctors.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef GAME_MWWORLD_CELLFUNCTORS_H
|
||||
#define GAME_MWWORLD_CELLFUNCTORS_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "refdata.hpp"
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
class CellRef;
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
/// List all (Ogre-)handles.
|
||||
struct ListHandles
|
||||
{
|
||||
std::vector<std::string> mHandles;
|
||||
|
||||
bool operator() (ESM::CellRef& ref, RefData& data)
|
||||
{
|
||||
std::string handle = data.getHandle();
|
||||
if (!handle.empty())
|
||||
mHandles.push_back (handle);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -3,6 +3,8 @@
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <OgreVector3.h>
|
||||
|
||||
#include "ptr.hpp"
|
||||
#include "nullaction.hpp"
|
||||
|
||||
@ -112,6 +114,16 @@ namespace MWWorld
|
||||
return 0;
|
||||
}
|
||||
|
||||
MWMechanics::Movement& Class::getMovementSettings (const Ptr& ptr) const
|
||||
{
|
||||
throw std::runtime_error ("movement settings not supported by class");
|
||||
}
|
||||
|
||||
Ogre::Vector3 Class::getMovementVector (const Ptr& ptr) const
|
||||
{
|
||||
return Ogre::Vector3 (0, 0, 0);
|
||||
}
|
||||
|
||||
const Class& Class::get (const std::string& key)
|
||||
{
|
||||
std::map<std::string, boost::shared_ptr<Class> >::const_iterator iter = sClasses.find (key);
|
||||
|
@ -10,6 +10,11 @@
|
||||
#include "containerstore.hpp"
|
||||
#include "refdata.hpp"
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class Vector3;
|
||||
}
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
class CellRenderImp;
|
||||
@ -19,6 +24,7 @@ namespace MWMechanics
|
||||
{
|
||||
struct CreatureStats;
|
||||
struct NpcStats;
|
||||
struct Movement;
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
@ -126,6 +132,13 @@ namespace MWWorld
|
||||
virtual float getSpeed (const Ptr& ptr) const;
|
||||
///< Return movement speed.
|
||||
|
||||
virtual MWMechanics::Movement& getMovementSettings (const Ptr& ptr) const;
|
||||
///< Return desired movement.
|
||||
|
||||
virtual Ogre::Vector3 getMovementVector (const Ptr& ptr) const;
|
||||
///< Return desired movement vector (determined based on movement settings,
|
||||
/// stance and stats).
|
||||
|
||||
static const Class& get (const std::string& key);
|
||||
///< If there is no class for this \a key, an exception is thrown.
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
namespace MWWorld
|
||||
{
|
||||
int DoingPhysics::sCounter = 0;
|
||||
int DoingPhysics::sSuppress = 0;
|
||||
|
||||
DoingPhysics::DoingPhysics()
|
||||
{
|
||||
@ -17,6 +18,16 @@ namespace MWWorld
|
||||
|
||||
bool DoingPhysics::isDoingPhysics()
|
||||
{
|
||||
return sCounter>0;
|
||||
return sCounter>0 || sSuppress>0;
|
||||
}
|
||||
|
||||
SuppressDoingPhysics::SuppressDoingPhysics()
|
||||
{
|
||||
++DoingPhysics::sSuppress;
|
||||
}
|
||||
|
||||
SuppressDoingPhysics::~SuppressDoingPhysics()
|
||||
{
|
||||
--DoingPhysics::sSuppress;
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,13 @@
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
///< Scope guard for blocking physics updates during physics simulation.
|
||||
class SuppressDoingPhysics;
|
||||
|
||||
/// Scope guard for blocking physics updates during physics simulation.
|
||||
class DoingPhysics
|
||||
{
|
||||
static int sCounter;
|
||||
static int sSuppress;
|
||||
|
||||
private:
|
||||
|
||||
@ -20,6 +23,23 @@ namespace MWWorld
|
||||
~DoingPhysics();
|
||||
|
||||
static bool isDoingPhysics();
|
||||
|
||||
friend class SuppressDoingPhysics;
|
||||
};
|
||||
|
||||
/// Scope guard for temporarily lifting the block issues by DoingPhysics
|
||||
class SuppressDoingPhysics
|
||||
{
|
||||
private:
|
||||
|
||||
SuppressDoingPhysics (const SuppressDoingPhysics&);
|
||||
SuppressDoingPhysics& operator= (const SuppressDoingPhysics&);
|
||||
|
||||
public:
|
||||
|
||||
SuppressDoingPhysics();
|
||||
|
||||
~SuppressDoingPhysics();
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -4,20 +4,21 @@
|
||||
#include "../mwrender/player.hpp"
|
||||
|
||||
#include "world.hpp"
|
||||
#include "class.hpp"
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
Player::Player (MWRender::Player *renderer, const ESM::NPC *player, MWWorld::World& world) :
|
||||
mCellStore (0), mRenderer (renderer), mWorld (world), mClass (0), mCollisionMode (true)
|
||||
mCellStore (0), mRenderer (renderer), mWorld (world), mClass (0), mCollisionMode (true),
|
||||
mAutoMove (false), mForwardBackward (0)
|
||||
{
|
||||
mPlayer.base = player;
|
||||
mName = player->name;
|
||||
mMale = !(player->flags & ESM::NPC::Female);
|
||||
mRace = player->race;
|
||||
mPlayer.ref.pos.pos[0] = mPlayer.ref.pos.pos[1] = mPlayer.ref.pos.pos[2] = 0;
|
||||
mPlayer.mData.setHandle (renderer->getHandle());
|
||||
mClass = new ESM::Class (*world.getStore().classes.find (player->cls));
|
||||
mAutoMove = false;
|
||||
misWalking = false;
|
||||
}
|
||||
|
||||
Player::~Player()
|
||||
@ -64,4 +65,45 @@ namespace MWWorld
|
||||
mClass = new_class;
|
||||
}
|
||||
|
||||
void Player::setAutoMove (bool enable)
|
||||
{
|
||||
MWWorld::Ptr ptr = getPlayer();
|
||||
|
||||
mAutoMove = enable;
|
||||
|
||||
int value = mForwardBackward;
|
||||
|
||||
if (mAutoMove)
|
||||
value = 1;
|
||||
|
||||
MWWorld::Class::get (ptr).getMovementSettings (ptr).mForwardBackward = value;
|
||||
}
|
||||
|
||||
void Player::setLeftRight (int value)
|
||||
{
|
||||
MWWorld::Ptr ptr = getPlayer();
|
||||
|
||||
MWWorld::Class::get (ptr).getMovementSettings (ptr).mLeftRight = value;
|
||||
}
|
||||
|
||||
void Player::setForwardBackward (int value)
|
||||
{
|
||||
MWWorld::Ptr ptr = getPlayer();
|
||||
|
||||
mForwardBackward = value;
|
||||
|
||||
if (mAutoMove)
|
||||
value = 1;
|
||||
|
||||
MWWorld::Class::get (ptr).getMovementSettings (ptr).mForwardBackward = value;
|
||||
}
|
||||
|
||||
void Player::toggleRunning()
|
||||
{
|
||||
MWWorld::Ptr ptr = getPlayer();
|
||||
|
||||
bool running = MWWorld::Class::get (ptr).getStance (ptr, MWWorld::Class::Run, true);
|
||||
|
||||
MWWorld::Class::get (ptr).setStance (ptr, MWWorld::Class::Run, !running);
|
||||
}
|
||||
}
|
||||
|
@ -30,9 +30,8 @@ namespace MWWorld
|
||||
std::string mBirthsign;
|
||||
ESM::Class *mClass;
|
||||
bool mCollisionMode;
|
||||
|
||||
bool mAutoMove;
|
||||
bool misWalking;//Testing...
|
||||
int mForwardBackward;
|
||||
|
||||
public:
|
||||
|
||||
@ -117,33 +116,13 @@ namespace MWWorld
|
||||
return mAutoMove;
|
||||
}
|
||||
|
||||
void setAutoMove(bool setMe)
|
||||
{
|
||||
mAutoMove = setMe;
|
||||
}
|
||||
void setAutoMove (bool enable);
|
||||
|
||||
//NOTE: we don't have speed being calculated yet, so for now this function only requires a frame duration.
|
||||
/// <param name="duration">float value representing time since last call</param>
|
||||
void executeAutoMove(float duration)
|
||||
{
|
||||
float X_Val = 0.0f;
|
||||
float Y_Val = 0.0f;
|
||||
float Z_Val = 300.0f * duration * -1.0f;
|
||||
if (mAutoMove == true)
|
||||
{
|
||||
moveRel(X_Val, Y_Val, Z_Val);
|
||||
}
|
||||
}
|
||||
void setLeftRight (int value);
|
||||
|
||||
bool getisWalking()
|
||||
{
|
||||
return misWalking;
|
||||
}
|
||||
void setForwardBackward (int value);
|
||||
|
||||
void setisWalking(bool setMe)
|
||||
{
|
||||
misWalking = setMe;
|
||||
}
|
||||
void toggleRunning();
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
#include "../mwmechanics/movement.hpp"
|
||||
|
||||
#include "containerstore.hpp"
|
||||
|
||||
@ -36,6 +37,7 @@ namespace MWWorld
|
||||
// are never copied outside of container operations.
|
||||
boost::shared_ptr<MWMechanics::CreatureStats> mCreatureStats;
|
||||
boost::shared_ptr<MWMechanics::NpcStats> mNpcStats;
|
||||
boost::shared_ptr<MWMechanics::Movement> mMovement;
|
||||
|
||||
boost::shared_ptr<ContainerStore<RefData> > mContainerStore;
|
||||
|
||||
@ -102,6 +104,11 @@ namespace MWWorld
|
||||
return mNpcStats;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWMechanics::Movement>& getMovement()
|
||||
{
|
||||
return mMovement;
|
||||
}
|
||||
|
||||
boost::shared_ptr<ContainerStore<RefData> >& getContainerStore()
|
||||
{
|
||||
return mContainerStore;
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "refdata.hpp"
|
||||
#include "globals.hpp"
|
||||
#include "doingphysics.hpp"
|
||||
#include "cellfunctors.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -271,6 +272,15 @@ namespace MWWorld
|
||||
|
||||
void World::unloadCell (CellRenderCollection::iterator iter)
|
||||
{
|
||||
ListHandles functor;
|
||||
iter->first->forEach (functor);
|
||||
|
||||
{ // silence annoying g++ warning
|
||||
for (std::vector<std::string>::const_iterator iter (functor.mHandles.begin());
|
||||
iter!=functor.mHandles.end(); ++iter)
|
||||
mScene.removeObject (*iter);
|
||||
}
|
||||
|
||||
removeScripts (iter->first);
|
||||
mEnvironment.mMechanicsManager->dropActors (iter->first);
|
||||
iter->second->destroy();
|
||||
@ -295,9 +305,12 @@ namespace MWWorld
|
||||
}
|
||||
}
|
||||
|
||||
void World::playerCellChange (Ptr::CellStore *cell, const ESM::Position& position)
|
||||
void World::playerCellChange (Ptr::CellStore *cell, const ESM::Position& position,
|
||||
bool adjustPlayerPos)
|
||||
{
|
||||
mPlayer->setPos (position.pos[0], position.pos[1], position.pos[2], true);
|
||||
if (adjustPlayerPos)
|
||||
mPlayer->setPos (position.pos[0], position.pos[1], position.pos[2], true);
|
||||
|
||||
mPlayer->setCell (cell);
|
||||
// TODO orientation
|
||||
|
||||
@ -316,8 +329,87 @@ namespace MWWorld
|
||||
}
|
||||
}
|
||||
|
||||
void World::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos)
|
||||
{
|
||||
SuppressDoingPhysics scopeGuard;
|
||||
|
||||
// remove active
|
||||
mEnvironment.mMechanicsManager->removeActor (mPlayer->getPlayer());
|
||||
|
||||
CellRenderCollection::iterator active = mActiveCells.begin();
|
||||
|
||||
while (active!=mActiveCells.end())
|
||||
{
|
||||
if (!(active->first->cell->data.flags & ESM::Cell::Interior))
|
||||
{
|
||||
if (std::abs (X-active->first->cell->data.gridX)<=1 &&
|
||||
std::abs (Y-active->first->cell->data.gridY)<=1)
|
||||
{
|
||||
// keep cells within the new 3x3 grid
|
||||
++active;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
unloadCell (active++);
|
||||
}
|
||||
|
||||
// Load cells
|
||||
for (int x=X-1; x<=X+1; ++x)
|
||||
for (int y=Y-1; y<=Y+1; ++y)
|
||||
{
|
||||
CellRenderCollection::iterator iter = mActiveCells.begin();
|
||||
|
||||
while (iter!=mActiveCells.end())
|
||||
{
|
||||
assert (!(iter->first->cell->data.flags & ESM::Cell::Interior));
|
||||
|
||||
if (x==iter->first->cell->data.gridX &&
|
||||
y==iter->first->cell->data.gridY)
|
||||
break;
|
||||
|
||||
++iter;
|
||||
}
|
||||
|
||||
if (iter==mActiveCells.end())
|
||||
{
|
||||
mExteriors[std::make_pair (x, y)].loadExt (x, y, mStore, mEsm);
|
||||
Ptr::CellStore *cell = &mExteriors[std::make_pair (x, y)];
|
||||
|
||||
loadCell (cell, new MWRender::ExteriorCellRender (*cell, mEnvironment, mScene));
|
||||
}
|
||||
}
|
||||
|
||||
// find current cell
|
||||
CellRenderCollection::iterator iter = mActiveCells.begin();
|
||||
|
||||
while (iter!=mActiveCells.end())
|
||||
{
|
||||
assert (!(iter->first->cell->data.flags & ESM::Cell::Interior));
|
||||
|
||||
if (X==iter->first->cell->data.gridX &&
|
||||
Y==iter->first->cell->data.gridY)
|
||||
break;
|
||||
|
||||
++iter;
|
||||
}
|
||||
|
||||
assert (iter!=mActiveCells.end());
|
||||
|
||||
mCurrentCell = iter->first;
|
||||
|
||||
// adjust player
|
||||
playerCellChange (&mExteriors[std::make_pair (X, Y)], position, adjustPlayerPos);
|
||||
|
||||
// Sky system
|
||||
adjustSky();
|
||||
|
||||
mCellChanged = true;
|
||||
}
|
||||
|
||||
World::World (OEngine::Render::OgreRenderer& renderer, const boost::filesystem::path& dataDir,
|
||||
const std::string& master, const boost::filesystem::path& resDir, bool newGame, Environment& environment)
|
||||
const std::string& master, const boost::filesystem::path& resDir,
|
||||
bool newGame, Environment& environment)
|
||||
: mSkyManager (0), mScene (renderer), mPlayer (0), mCurrentCell (0), mGlobalVariables (0),
|
||||
mSky (false), mCellChanged (false), mEnvironment (environment)
|
||||
{
|
||||
@ -331,6 +423,7 @@ namespace MWWorld
|
||||
mStore.load (mEsm);
|
||||
|
||||
mPlayer = new MWWorld::Player (mScene.getPlayer(), mStore.npcs.find ("player"), *this);
|
||||
mScene.addActor (mPlayer->getPlayer().getRefData().getHandle(), "", Ogre::Vector3 (0, 0, 0));
|
||||
|
||||
// global variables
|
||||
mGlobalVariables = new Globals (mStore);
|
||||
@ -418,7 +511,8 @@ namespace MWWorld
|
||||
|
||||
Ptr World::getPtrViaHandle (const std::string& handle)
|
||||
{
|
||||
// TODO player
|
||||
if (mPlayer->getPlayer().getRefData().getHandle()==handle)
|
||||
return mPlayer->getPlayer();
|
||||
|
||||
for (CellRenderCollection::iterator iter (mActiveCells.begin());
|
||||
iter!=mActiveCells.end(); ++iter)
|
||||
@ -587,8 +681,10 @@ namespace MWWorld
|
||||
return mGlobalVariables->getInt ("timescale");
|
||||
}
|
||||
|
||||
void World::changeCell (const std::string& cellName, const ESM::Position& position)
|
||||
void World::changeToInteriorCell (const std::string& cellName, const ESM::Position& position)
|
||||
{
|
||||
SuppressDoingPhysics scopeGuard;
|
||||
|
||||
// remove active
|
||||
CellRenderCollection::iterator active = mActiveCells.begin();
|
||||
|
||||
@ -614,89 +710,14 @@ namespace MWWorld
|
||||
//currentRegion->name = "";
|
||||
}
|
||||
|
||||
void World::changeCell (int X, int Y, const ESM::Position& position)
|
||||
{
|
||||
// remove active
|
||||
CellRenderCollection::iterator active = mActiveCells.begin();
|
||||
|
||||
while (active!=mActiveCells.end())
|
||||
{
|
||||
if (!(active->first->cell->data.flags & ESM::Cell::Interior))
|
||||
{
|
||||
if (std::abs (X-active->first->cell->data.gridX)<=1 &&
|
||||
std::abs (Y-active->first->cell->data.gridY)<=1)
|
||||
{
|
||||
// keep cells within the new 3x3 grid
|
||||
++active;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
unloadCell (active++);
|
||||
}
|
||||
|
||||
// Load cells
|
||||
for (int x=X-1; x<=X+1; ++x)
|
||||
for (int y=Y-1; y<=Y+1; ++y)
|
||||
{
|
||||
CellRenderCollection::iterator iter = mActiveCells.begin();
|
||||
|
||||
while (iter!=mActiveCells.end())
|
||||
{
|
||||
assert (!(iter->first->cell->data.flags & ESM::Cell::Interior));
|
||||
|
||||
if (x==iter->first->cell->data.gridX &&
|
||||
y==iter->first->cell->data.gridY)
|
||||
break;
|
||||
|
||||
++iter;
|
||||
}
|
||||
|
||||
if (iter==mActiveCells.end())
|
||||
{
|
||||
mExteriors[std::make_pair (x, y)].loadExt (x, y, mStore, mEsm);
|
||||
Ptr::CellStore *cell = &mExteriors[std::make_pair (x, y)];
|
||||
|
||||
loadCell (cell, new MWRender::ExteriorCellRender (*cell, mEnvironment, mScene));
|
||||
}
|
||||
}
|
||||
|
||||
// find current cell
|
||||
CellRenderCollection::iterator iter = mActiveCells.begin();
|
||||
|
||||
while (iter!=mActiveCells.end())
|
||||
{
|
||||
assert (!(iter->first->cell->data.flags & ESM::Cell::Interior));
|
||||
|
||||
if (X==iter->first->cell->data.gridX &&
|
||||
Y==iter->first->cell->data.gridY)
|
||||
break;
|
||||
|
||||
++iter;
|
||||
}
|
||||
|
||||
assert (iter!=mActiveCells.end());
|
||||
|
||||
mCurrentCell = iter->first;
|
||||
|
||||
// adjust player
|
||||
playerCellChange (&mExteriors[std::make_pair (X, Y)], position);
|
||||
|
||||
// Sky system
|
||||
adjustSky();
|
||||
|
||||
mCellChanged = true;
|
||||
}
|
||||
|
||||
|
||||
void World::changeToExteriorCell (const ESM::Position& position)
|
||||
void World::changeToExteriorCell (const ESM::Position& position)
|
||||
{
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
positionToIndex (position.pos[0], position.pos[1], x, y);
|
||||
|
||||
changeCell (x, y, position);
|
||||
changeCell (x, y, position, true);
|
||||
}
|
||||
|
||||
const ESM::Cell *World::getExterior (const std::string& cellName) const
|
||||
@ -722,6 +743,7 @@ namespace MWWorld
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void World::markCellAsUnchanged()
|
||||
{
|
||||
mCellChanged = false;
|
||||
@ -781,15 +803,16 @@ namespace MWWorld
|
||||
|
||||
if (mCurrentCell->cell->data.gridX!=cellX || mCurrentCell->cell->data.gridY!=cellY)
|
||||
{
|
||||
changeCell (cellX, cellY, mPlayer->getPlayer().getCellRef().pos);
|
||||
|
||||
if (!DoingPhysics::isDoingPhysics())
|
||||
mScene.moveObject (ptr.getRefData().getHandle(), Ogre::Vector3 (x, y, z));
|
||||
changeCell (cellX, cellY, mPlayer->getPlayer().getCellRef().pos, false);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mScene.moveObject (ptr.getRefData().getHandle(), Ogre::Vector3 (x, y, z),
|
||||
!DoingPhysics::isDoingPhysics());
|
||||
|
||||
// TODO cell change for non-player ref
|
||||
}
|
||||
|
||||
@ -821,4 +844,10 @@ namespace MWWorld
|
||||
if (y<0)
|
||||
--cellY;
|
||||
}
|
||||
|
||||
void World::doPhysics (const std::vector<std::pair<std::string, Ogre::Vector3> >& actors,
|
||||
float duration)
|
||||
{
|
||||
mScene.doPhysics (duration, *this, actors);
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,11 @@
|
||||
#include "ptr.hpp"
|
||||
#include "globals.hpp"
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class Vector3;
|
||||
}
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
struct Position;
|
||||
@ -83,14 +88,19 @@ namespace MWWorld
|
||||
|
||||
void loadCell (Ptr::CellStore *cell, MWRender::CellRender *render);
|
||||
|
||||
void playerCellChange (Ptr::CellStore *cell, const ESM::Position& position);
|
||||
void playerCellChange (Ptr::CellStore *cell, const ESM::Position& position,
|
||||
bool adjustPlayerPos = true);
|
||||
|
||||
void adjustSky();
|
||||
|
||||
void changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos);
|
||||
///< Move from exterior to interior or from interior cell to a different
|
||||
/// interior cell.
|
||||
public:
|
||||
|
||||
World (OEngine::Render::OgreRenderer& renderer, const boost::filesystem::path& dataDir,
|
||||
const std::string& master, const boost::filesystem::path& resDir, bool newGame, Environment& environment);
|
||||
const std::string& master, const boost::filesystem::path& resDir, bool newGame,
|
||||
Environment& environment);
|
||||
|
||||
~World();
|
||||
|
||||
@ -138,12 +148,11 @@ namespace MWWorld
|
||||
|
||||
float getTimeScaleFactor() const;
|
||||
|
||||
void changeCell (const std::string& cellName, const ESM::Position& position);
|
||||
///< works only for interior cells currently.
|
||||
|
||||
void changeCell (int X, int Y, const ESM::Position& position);
|
||||
void changeToInteriorCell (const std::string& cellName, const ESM::Position& position);
|
||||
///< Move to interior cell.
|
||||
|
||||
void changeToExteriorCell (const ESM::Position& position);
|
||||
///< Move to exterior cell.
|
||||
|
||||
const ESM::Cell *getExterior (const std::string& cellName) const;
|
||||
///< Return a cell matching the given name or a 0-pointer, if there is no such cell.
|
||||
@ -162,6 +171,10 @@ namespace MWWorld
|
||||
|
||||
void positionToIndex (float x, float y, int &cellX, int &cellY) const;
|
||||
///< Convert position to cell numbers
|
||||
|
||||
void doPhysics (const std::vector<std::pair<std::string, Ogre::Vector3> >& actors,
|
||||
float duration);
|
||||
///< Run physics simulation and modify \a world accordingly.
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,48 @@ namespace ESMS
|
||||
loadRefs(store, esm);
|
||||
}
|
||||
|
||||
/// Call functor (ref) for each reference. functor must return a bool. Returning
|
||||
/// false will abort the iteration.
|
||||
/// \return Iteration completed?
|
||||
template<class Functor>
|
||||
bool forEach (Functor& functor)
|
||||
{
|
||||
return
|
||||
forEachImp (functor, activators) &&
|
||||
forEachImp (functor, potions) &&
|
||||
forEachImp (functor, appas) &&
|
||||
forEachImp (functor, armors) &&
|
||||
forEachImp (functor, books) &&
|
||||
forEachImp (functor, clothes) &&
|
||||
forEachImp (functor, containers) &&
|
||||
forEachImp (functor, creatures) &&
|
||||
forEachImp (functor, doors) &&
|
||||
forEachImp (functor, ingreds) &&
|
||||
forEachImp (functor, creatureLists) &&
|
||||
forEachImp (functor, itemLists) &&
|
||||
forEachImp (functor, lights) &&
|
||||
forEachImp (functor, lockpicks) &&
|
||||
forEachImp (functor, miscItems) &&
|
||||
forEachImp (functor, npcs) &&
|
||||
forEachImp (functor, probes) &&
|
||||
forEachImp (functor, repairs) &&
|
||||
forEachImp (functor, statics) &&
|
||||
forEachImp (functor, weapons);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template<class Functor, class List>
|
||||
bool forEachImp (Functor& functor, List& list)
|
||||
{
|
||||
for (typename List::List::iterator iter (list.list.begin()); iter!=list.list.end();
|
||||
++iter)
|
||||
if (!functor (iter->ref, iter->mData))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void loadRefs(const ESMStore &store, ESMReader &esm)
|
||||
{
|
||||
assert (cell);
|
||||
|
Loading…
x
Reference in New Issue
Block a user