Merge remote-tracking branch 'kcat/animations'

actorid
Marc Zinnschlag 12 years ago
commit 61e476118d

@ -14,7 +14,7 @@ set(GAME_HEADER
source_group(game FILES ${GAME} ${GAME_HEADER}) source_group(game FILES ${GAME} ${GAME_HEADER})
add_openmw_dir (mwrender add_openmw_dir (mwrender
renderingmanager debugging sky player animation npcanimation creatureanimation activatoranimation renderingmanager debugging sky camera animation npcanimation creatureanimation activatoranimation
actors objects renderinginterface localmap occlusionquery terrain terrainmaterial water shadows actors objects renderinginterface localmap occlusionquery terrain terrainmaterial water shadows
compositors characterpreview externalrendering globalmap videoplayer ripplesimulation refraction compositors characterpreview externalrendering globalmap videoplayer ripplesimulation refraction
) )

@ -317,7 +317,7 @@ namespace MWBase
virtual void togglePOV() = 0; virtual void togglePOV() = 0;
virtual void togglePreviewMode(bool enable) = 0; virtual void togglePreviewMode(bool enable) = 0;
virtual bool toggleVanityMode(bool enable, bool force) = 0; virtual bool toggleVanityMode(bool enable) = 0;
virtual void allowVanityMode(bool allow) = 0; virtual void allowVanityMode(bool allow) = 0;
virtual void togglePlayerLooking(bool enable) = 0; virtual void togglePlayerLooking(bool enable) = 0;
virtual void changeVanityModeScale(float factor) = 0; virtual void changeVanityModeScale(float factor) = 0;

@ -720,19 +720,17 @@ namespace MWInput
void InputManager::resetIdleTime() void InputManager::resetIdleTime()
{ {
if (mTimeIdle < 0) { if (mTimeIdle < 0)
MWBase::Environment::get().getWorld()->toggleVanityMode(false, false); MWBase::Environment::get().getWorld()->toggleVanityMode(false);
}
mTimeIdle = 0.f; mTimeIdle = 0.f;
} }
void InputManager::updateIdleTime(float dt) void InputManager::updateIdleTime(float dt)
{ {
if (mTimeIdle >= 0.f) { if (mTimeIdle >= 0.f)
mTimeIdle += dt; mTimeIdle += dt;
}
if (mTimeIdle > 30.f) { if (mTimeIdle > 30.f) {
MWBase::Environment::get().getWorld()->toggleVanityMode(true, false); MWBase::Environment::get().getWorld()->toggleVanityMode(true);
mTimeIdle = -1.f; mTimeIdle = -1.f;
} }
} }

@ -1,7 +1,8 @@
#include "player.hpp" #include "camera.hpp"
#include <OgreSceneNode.h> #include <OgreSceneNode.h>
#include <OgreCamera.h> #include <OgreCamera.h>
#include <OgreSceneManager.h>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
@ -14,10 +15,9 @@
namespace MWRender namespace MWRender
{ {
Player::Player (Ogre::Camera *camera, Ogre::SceneNode* node) Camera::Camera (Ogre::Camera *camera)
: mCamera(camera), : mCamera(camera),
mPlayerNode(node), mCameraNode(NULL),
mCameraNode(mPlayerNode->createChildSceneNode()),
mFirstPersonView(true), mFirstPersonView(true),
mPreviewMode(false), mPreviewMode(false),
mFreeLook(true), mFreeLook(true),
@ -28,51 +28,16 @@ namespace MWRender
{ {
mVanity.enabled = false; mVanity.enabled = false;
mVanity.allowed = true; mVanity.allowed = true;
mVanity.forced = false;
mCameraNode->attachObject(mCamera);
mCameraNode->setPosition(0.f, 0.f, mHeight);
mPreviewCam.yaw = 0.f; mPreviewCam.yaw = 0.f;
mPreviewCam.offset = 400.f; mPreviewCam.offset = 400.f;
} }
Player::~Player() Camera::~Camera()
{
delete mAnimation;
}
bool Player::rotate(const Ogre::Vector3 &rot, bool adjust)
{ {
if (mVanity.enabled) {
toggleVanityMode(false);
}
Ogre::Vector3 trueRot = rot;
/// \note rotate player on forced vanity
if (mVanity.forced) {
if (mFreeLook) {
float diff = (adjust) ? rot.z : mMainCam.yaw - rot.z;
mVanity.enabled = false;
rotateCamera(rot, adjust);
mVanity.enabled = true;
compensateYaw(diff);
}
trueRot.z = 0.f;
}
if (mFreeLook || mVanity.enabled || mPreviewMode) {
rotateCamera(trueRot, adjust);
}
/// \note if vanity mode is forced by TVM then rotate player
return (!mVanity.enabled && !mPreviewMode) || mVanity.forced;
} }
void Player::rotateCamera(const Ogre::Vector3 &rot, bool adjust) void Camera::rotateCamera(const Ogre::Vector3 &rot, bool adjust)
{ {
if (adjust) { if (adjust) {
setYaw(getYaw() + rot.z); setYaw(getYaw() + rot.z);
@ -81,33 +46,37 @@ namespace MWRender
setYaw(rot.z); setYaw(rot.z);
setPitch(rot.x); setPitch(rot.x);
} }
Ogre::Quaternion xr(
Ogre::Radian(getPitch() + Ogre::Math::HALF_PI), Ogre::Quaternion xr(Ogre::Radian(getPitch() + Ogre::Math::HALF_PI), Ogre::Vector3::UNIT_X);
Ogre::Vector3::UNIT_X
);
Ogre::Quaternion zr(
Ogre::Radian(getYaw()),
Ogre::Vector3::NEGATIVE_UNIT_Z
);
if (!mVanity.enabled && !mPreviewMode) { if (!mVanity.enabled && !mPreviewMode) {
mPlayerNode->setOrientation(zr);
mCameraNode->setOrientation(xr); mCameraNode->setOrientation(xr);
} else { } else {
Ogre::Quaternion zr(Ogre::Radian(getYaw()), Ogre::Vector3::NEGATIVE_UNIT_Z);
mCameraNode->setOrientation(zr * xr); mCameraNode->setOrientation(zr * xr);
} }
} }
std::string Player::getHandle() const const std::string &Camera::getHandle() const
{ {
return mPlayerNode->getName(); return mTrackingPtr.getRefData().getHandle();
} }
void Player::attachTo(const MWWorld::Ptr &ptr) void Camera::attachTo(const MWWorld::Ptr &ptr)
{ {
ptr.getRefData().setBaseNode(mPlayerNode); mTrackingPtr = ptr;
Ogre::SceneNode *node = mTrackingPtr.getRefData().getBaseNode()->createChildSceneNode(Ogre::Vector3(0.0f, 0.0f, mHeight));
if(mCameraNode)
{
node->setOrientation(mCameraNode->getOrientation());
node->setPosition(mCameraNode->getPosition());
node->setScale(mCameraNode->getScale());
mCameraNode->getCreator()->destroySceneNode(mCameraNode);
}
mCameraNode = node;
mCameraNode->attachObject(mCamera);
} }
void Player::updateListener() void Camera::updateListener()
{ {
Ogre::Vector3 pos = mCamera->getRealPosition(); Ogre::Vector3 pos = mCamera->getRealPosition();
Ogre::Vector3 dir = mCamera->getRealDirection(); Ogre::Vector3 dir = mCamera->getRealDirection();
@ -116,29 +85,27 @@ namespace MWRender
MWBase::Environment::get().getSoundManager()->setListenerPosDir(pos, dir, up); MWBase::Environment::get().getSoundManager()->setListenerPosDir(pos, dir, up);
} }
void Player::update(float duration) void Camera::update(float duration)
{ {
updateListener(); updateListener();
// only show the crosshair in game mode and in first person mode. // only show the crosshair in game mode and in first person mode.
MWBase::Environment::get().getWindowManager ()->showCrosshair MWBase::WindowManager *wm = MWBase::Environment::get().getWindowManager();
(!MWBase::Environment::get().getWindowManager ()->isGuiMode () && (mFirstPersonView && !mVanity.enabled && !mPreviewMode)); wm->showCrosshair(!wm->isGuiMode() && (mFirstPersonView && !mVanity.enabled && !mPreviewMode));
if (mFirstPersonView && !mVanity.enabled) { if(mVanity.enabled)
return; {
}
if (mVanity.enabled) {
Ogre::Vector3 rot(0.f, 0.f, 0.f); Ogre::Vector3 rot(0.f, 0.f, 0.f);
rot.z = Ogre::Degree(3.f * duration).valueRadians(); rot.z = Ogre::Degree(3.f * duration).valueRadians();
rotateCamera(rot, true); rotateCamera(rot, true);
} }
} }
void Player::toggleViewMode() void Camera::toggleViewMode()
{ {
mFirstPersonView = !mFirstPersonView; mFirstPersonView = !mFirstPersonView;
mAnimation->setViewMode((mVanity.enabled || mPreviewMode || !mFirstPersonView) ? mAnimation->setViewMode(isFirstPerson() ? NpcAnimation::VM_FirstPerson :
NpcAnimation::VM_Normal : NpcAnimation::VM_FirstPerson); NpcAnimation::VM_Normal);
if (mFirstPersonView) { if (mFirstPersonView) {
mCamera->setPosition(0.f, 0.f, 0.f); mCamera->setPosition(0.f, 0.f, 0.f);
setLowHeight(false); setLowHeight(false);
@ -148,28 +115,24 @@ namespace MWRender
} }
} }
void Player::allowVanityMode(bool allow) void Camera::allowVanityMode(bool allow)
{ {
if (!allow && mVanity.enabled && !mVanity.forced) { if (!allow && mVanity.enabled)
toggleVanityMode(false); toggleVanityMode(false);
}
mVanity.allowed = allow; mVanity.allowed = allow;
} }
bool Player::toggleVanityMode(bool enable, bool force) bool Camera::toggleVanityMode(bool enable)
{ {
if ((mVanity.forced && !force) || if(!mVanity.allowed && enable)
(!mVanity.allowed && (force || enable)))
{
return false; return false;
} else if (mVanity.enabled == enable) {
if(mVanity.enabled == enable)
return true; return true;
}
mVanity.enabled = enable; mVanity.enabled = enable;
mVanity.forced = force && enable;
mAnimation->setViewMode((mVanity.enabled || mPreviewMode || !mFirstPersonView) ? mAnimation->setViewMode(isFirstPerson() ? NpcAnimation::VM_FirstPerson :
NpcAnimation::VM_Normal : NpcAnimation::VM_FirstPerson); NpcAnimation::VM_Normal);
float offset = mPreviewCam.offset; float offset = mPreviewCam.offset;
Ogre::Vector3 rot(0.f, 0.f, 0.f); Ogre::Vector3 rot(0.f, 0.f, 0.f);
@ -185,20 +148,22 @@ namespace MWRender
setLowHeight(!mFirstPersonView); setLowHeight(!mFirstPersonView);
} }
rot.z = getYaw(); rot.z = getYaw();
mCamera->setPosition(0.f, 0.f, offset); mCamera->setPosition(0.f, 0.f, offset);
rotateCamera(rot, false); rotateCamera(rot, false);
return true; return true;
} }
void Player::togglePreviewMode(bool enable) void Camera::togglePreviewMode(bool enable)
{ {
if (mPreviewMode == enable) { if(mPreviewMode == enable)
return; return;
}
mPreviewMode = enable; mPreviewMode = enable;
mAnimation->setViewMode((mVanity.enabled || mPreviewMode || !mFirstPersonView) ? mAnimation->setViewMode(isFirstPerson() ? NpcAnimation::VM_FirstPerson :
NpcAnimation::VM_Normal : NpcAnimation::VM_FirstPerson); NpcAnimation::VM_Normal);
float offset = mCamera->getPosition().z; float offset = mCamera->getPosition().z;
if (mPreviewMode) { if (mPreviewMode) {
mMainCam.offset = offset; mMainCam.offset = offset;
@ -211,19 +176,19 @@ namespace MWRender
setLowHeight(!mFirstPersonView); setLowHeight(!mFirstPersonView);
} }
mCamera->setPosition(0.f, 0.f, offset); mCamera->setPosition(0.f, 0.f, offset);
rotateCamera(Ogre::Vector3(getPitch(), 0.f, getYaw()), false); rotateCamera(Ogre::Vector3(getPitch(), 0.f, getYaw()), false);
} }
float Player::getYaw() float Camera::getYaw()
{ {
if (mVanity.enabled || mPreviewMode) { if(mVanity.enabled || mPreviewMode)
return mPreviewCam.yaw; return mPreviewCam.yaw;
}
return mMainCam.yaw; return mMainCam.yaw;
} }
void Player::setYaw(float angle) void Camera::setYaw(float angle)
{ {
if (angle > Ogre::Math::PI) { if (angle > Ogre::Math::PI) {
angle -= Ogre::Math::TWO_PI; angle -= Ogre::Math::TWO_PI;
@ -237,7 +202,7 @@ namespace MWRender
} }
} }
float Player::getPitch() float Camera::getPitch()
{ {
if (mVanity.enabled || mPreviewMode) { if (mVanity.enabled || mPreviewMode) {
return mPreviewCam.pitch; return mPreviewCam.pitch;
@ -245,18 +210,18 @@ namespace MWRender
return mMainCam.pitch; return mMainCam.pitch;
} }
void Player::setPitch(float angle) void Camera::setPitch(float angle)
{ {
const float epsilon = 0.000001; const float epsilon = 0.000001f;
float limit = Ogre::Math::HALF_PI - epsilon; float limit = Ogre::Math::HALF_PI - epsilon;
if (mVanity.forced || mPreviewMode) { if(mPreviewMode)
limit /= 2; limit /= 2;
}
if (angle > limit) { if(angle > limit)
angle = limit; angle = limit;
} else if (angle < -limit) { else if(angle < -limit)
angle = -limit; angle = -limit;
}
if (mVanity.enabled || mPreviewMode) { if (mVanity.enabled || mPreviewMode) {
mPreviewCam.pitch = angle; mPreviewCam.pitch = angle;
} else { } else {
@ -264,11 +229,11 @@ namespace MWRender
} }
} }
void Player::setCameraDistance(float dist, bool adjust, bool override) void Camera::setCameraDistance(float dist, bool adjust, bool override)
{ {
if (mFirstPersonView && !mPreviewMode && !mVanity.enabled) { if(mFirstPersonView && !mPreviewMode && !mVanity.enabled)
return; return;
}
Ogre::Vector3 v(0.f, 0.f, dist); Ogre::Vector3 v(0.f, 0.f, dist);
if (adjust) { if (adjust) {
v += mCamera->getPosition(); v += mCamera->getPosition();
@ -293,7 +258,7 @@ namespace MWRender
} }
} }
void Player::setCameraDistance() void Camera::setCameraDistance()
{ {
if (mDistanceAdjusted) { if (mDistanceAdjusted) {
if (mVanity.enabled || mPreviewMode) { if (mVanity.enabled || mPreviewMode) {
@ -305,65 +270,54 @@ namespace MWRender
mDistanceAdjusted = false; mDistanceAdjusted = false;
} }
void Player::setAnimation(NpcAnimation *anim) void Camera::setAnimation(NpcAnimation *anim)
{ {
anim->setViewMode((mVanity.enabled || mPreviewMode || !mFirstPersonView) ? // If we're switching to a new NpcAnimation, ensure the old one is
NpcAnimation::VM_Normal : NpcAnimation::VM_FirstPerson); // using a normal view mode
if(mAnimation && mAnimation != anim)
delete mAnimation; mAnimation->setViewMode(NpcAnimation::VM_Normal);
mAnimation = anim; mAnimation = anim;
mAnimation->setViewMode(isFirstPerson() ? NpcAnimation::VM_FirstPerson :
NpcAnimation::VM_Normal);
} }
void Player::setHeight(float height) void Camera::setHeight(float height)
{ {
mHeight = height; mHeight = height;
mCameraNode->setPosition(0.f, 0.f, mHeight); mCameraNode->setPosition(0.f, 0.f, mHeight);
} }
float Player::getHeight() float Camera::getHeight()
{ {
return mHeight * mPlayerNode->getScale().z; return mHeight * mTrackingPtr.getRefData().getBaseNode()->getScale().z;
} }
bool Player::getPosition(Ogre::Vector3 &player, Ogre::Vector3 &camera) bool Camera::getPosition(Ogre::Vector3 &player, Ogre::Vector3 &camera)
{ {
mCamera->getParentSceneNode ()->needUpdate(true); mCamera->getParentSceneNode ()->needUpdate(true);
camera = mCamera->getRealPosition(); camera = mCamera->getRealPosition();
player = mPlayerNode->getPosition(); player = mTrackingPtr.getRefData().getBaseNode()->getPosition();
return mFirstPersonView && !mVanity.enabled && !mPreviewMode; return mFirstPersonView && !mVanity.enabled && !mPreviewMode;
} }
Ogre::Vector3 Player::getPosition() Ogre::Vector3 Camera::getPosition()
{ {
return mPlayerNode->getPosition(); return mTrackingPtr.getRefData().getBaseNode()->getPosition();
} }
void Player::getSightAngles(float &pitch, float &yaw) void Camera::getSightAngles(float &pitch, float &yaw)
{ {
pitch = mMainCam.pitch; pitch = mMainCam.pitch;
yaw = mMainCam.yaw; yaw = mMainCam.yaw;
} }
void Player::compensateYaw(float diff) void Camera::togglePlayerLooking(bool enable)
{
mPreviewCam.yaw -= diff;
Ogre::Quaternion zr(
Ogre::Radian(mPreviewCam.yaw),
Ogre::Vector3::NEGATIVE_UNIT_Z
);
Ogre::Quaternion xr(
Ogre::Radian(mPreviewCam.pitch),
Ogre::Vector3::UNIT_X);
mCameraNode->setOrientation(zr * xr);
}
void Player::togglePlayerLooking(bool enable)
{ {
mFreeLook = enable; mFreeLook = enable;
} }
void Player::setLowHeight(bool low) void Camera::setLowHeight(bool low)
{ {
if (low) { if (low) {
mCameraNode->setPosition(0.f, 0.f, mHeight * 0.85); mCameraNode->setPosition(0.f, 0.f, mHeight * 0.85);
@ -372,7 +326,7 @@ namespace MWRender
} }
} }
bool Player::isVanityOrPreviewModeEnabled() bool Camera::isVanityOrPreviewModeEnabled()
{ {
return mPreviewMode || mVanity.enabled; return mPreviewMode || mVanity.enabled;
} }

@ -1,8 +1,10 @@
#ifndef GAME_MWRENDER_PLAYER_H #ifndef GAME_MWRENDER_CAMERA_H
#define GAME_MWRENDER_PLAYER_H #define GAME_MWRENDER_CAMERA_H
#include <string> #include <string>
#include "../mwworld/ptr.hpp"
namespace Ogre namespace Ogre
{ {
class Vector3; class Vector3;
@ -10,24 +12,20 @@ namespace Ogre
class SceneNode; class SceneNode;
} }
namespace MWWorld
{
class Ptr;
}
namespace MWRender namespace MWRender
{ {
class NpcAnimation; class NpcAnimation;
/// \brief Player character rendering and camera control
class Player /// \brief Camera control
class Camera
{ {
struct CamData { struct CamData {
float pitch, yaw, offset; float pitch, yaw, offset;
}; };
Ogre::Camera *mCamera; MWWorld::Ptr mTrackingPtr;
Ogre::SceneNode *mPlayerNode; Ogre::Camera *mCamera;
Ogre::SceneNode *mCameraNode; Ogre::SceneNode *mCameraNode;
NpcAnimation *mAnimation; NpcAnimation *mAnimation;
@ -37,7 +35,7 @@ namespace MWRender
bool mFreeLook; bool mFreeLook;
struct { struct {
bool enabled, allowed, forced; bool enabled, allowed;
} mVanity; } mVanity;
float mHeight, mCameraDistance; float mHeight, mCameraDistance;
@ -51,15 +49,11 @@ namespace MWRender
void setLowHeight(bool low = true); void setLowHeight(bool low = true);
public: public:
Camera(Ogre::Camera *camera);
~Camera();
Player (Ogre::Camera *camera, Ogre::SceneNode* mNode); /// Set where the camera is looking at. Uses Morrowind (euler) angles
~Player();
/// Set where the player is looking at. Uses Morrowind (euler) angles
/// \param rot Rotation angles in radians /// \param rot Rotation angles in radians
/// \return true if player object needs to bo rotated physically
bool rotate(const Ogre::Vector3 &rot, bool adjust);
void rotateCamera(const Ogre::Vector3 &rot, bool adjust); void rotateCamera(const Ogre::Vector3 &rot, bool adjust);
float getYaw(); float getYaw();
@ -68,22 +62,21 @@ namespace MWRender
float getPitch(); float getPitch();
void setPitch(float angle); void setPitch(float angle);
void compensateYaw(float diff); const std::string &getHandle() const;
std::string getHandle() const;
/// Attach camera to object /// Attach camera to object
/// \note there is no protection from attaching the same camera to
/// several different objects
void attachTo(const MWWorld::Ptr &); void attachTo(const MWWorld::Ptr &);
void toggleViewMode(); void toggleViewMode();
bool toggleVanityMode(bool enable, bool force = false); bool toggleVanityMode(bool enable);
void allowVanityMode(bool allow); void allowVanityMode(bool allow);
void togglePreviewMode(bool enable); void togglePreviewMode(bool enable);
bool isFirstPerson() const
{ return !(mVanity.enabled || mPreviewMode || !mFirstPersonView); }
void update(float duration); void update(float duration);
/// Set camera distance for current mode. Don't work on 1st person view. /// Set camera distance for current mode. Don't work on 1st person view.
@ -96,8 +89,6 @@ namespace MWRender
void setCameraDistance(); void setCameraDistance();
void setAnimation(NpcAnimation *anim); void setAnimation(NpcAnimation *anim);
NpcAnimation *getAnimation() const
{ return mAnimation; }
void setHeight(float height); void setHeight(float height);
float getHeight(); float getHeight();

@ -12,6 +12,7 @@
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwworld/player.hpp" #include "../mwworld/player.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/inventorystore.hpp"
#include "renderconst.hpp" #include "renderconst.hpp"
#include "npcanimation.hpp" #include "npcanimation.hpp"
@ -134,6 +135,46 @@ namespace MWRender
void InventoryPreview::update(int sizeX, int sizeY) void InventoryPreview::update(int sizeX, int sizeY)
{ {
MWWorld::InventoryStore &inv = MWWorld::Class::get(mCharacter).getInventoryStore(mCharacter);
MWWorld::ContainerStoreIterator iter = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
std::string groupname;
if(iter == inv.end())
groupname = "inventoryhandtohand";
else
{
const std::string &type = iter->getTypeName();
if(type == typeid(ESM::Lockpick).name() || type == typeid(ESM::Probe).name())
groupname = "inventoryweapononehand";
else if(type == typeid(ESM::Weapon).name())
{
MWWorld::LiveCellRef<ESM::Weapon> *ref = iter->get<ESM::Weapon>();
int type = ref->mBase->mData.mType;
if(type == ESM::Weapon::ShortBladeOneHand ||
type == ESM::Weapon::LongBladeOneHand ||
type == ESM::Weapon::BluntOneHand ||
type == ESM::Weapon::AxeOneHand)
groupname = "inventoryweapononehand";
else if(type == ESM::Weapon::LongBladeTwoHand ||
type == ESM::Weapon::BluntTwoClose ||
type == ESM::Weapon::AxeTwoHand)
groupname = "inventoryweapontwohand";
else if(type == ESM::Weapon::BluntTwoWide ||
type == ESM::Weapon::SpearTwoWide)
groupname = "inventoryweapontwowide";
else
groupname = "inventoryhandtohand";
}
else
groupname = "inventoryhandtohand";
}
if(groupname != mCurrentAnimGroup)
{
mCurrentAnimGroup = groupname;
mAnimation->play(mCurrentAnimGroup, "start", "stop", 0.0f, 0);
}
mAnimation->forceUpdate(); mAnimation->forceUpdate();
mAnimation->runAnimation(0.0f); mAnimation->runAnimation(0.0f);
@ -155,7 +196,10 @@ namespace MWRender
if (!mSelectionBuffer) if (!mSelectionBuffer)
mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, 0); mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, 0);
mAnimation->play("inventoryhandtohand", "start", "stop", 0.0f, 0); mAnimation->showWeapons(true);
mCurrentAnimGroup = "inventoryhandtohand";
mAnimation->play(mCurrentAnimGroup, "start", "stop", 0.0f, 0);
} }
// -------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------

@ -53,6 +53,7 @@ namespace MWRender
MWWorld::Ptr mCharacter; MWWorld::Ptr mCharacter;
MWRender::NpcAnimation* mAnimation; MWRender::NpcAnimation* mAnimation;
std::string mCurrentAnimGroup;
std::string mName; std::string mName;

@ -20,7 +20,6 @@
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "player.hpp"
#include "renderconst.hpp" #include "renderconst.hpp"
using namespace Ogre; using namespace Ogre;

@ -39,8 +39,6 @@ namespace MWWorld
namespace MWRender namespace MWRender
{ {
class Player;
class Debugging class Debugging
{ {
OEngine::Physic::PhysicEngine* mEngine; OEngine::Physic::PhysicEngine* mEngine;

@ -178,7 +178,8 @@ void NpcAnimation::updateParts(bool forceupdate)
{ &NpcAnimation::mGloveR, MWWorld::InventoryStore::Slot_RightGauntlet, 0 }, { &NpcAnimation::mGloveR, MWWorld::InventoryStore::Slot_RightGauntlet, 0 },
{ &NpcAnimation::mShirt, MWWorld::InventoryStore::Slot_Shirt, 0 }, { &NpcAnimation::mShirt, MWWorld::InventoryStore::Slot_Shirt, 0 },
{ &NpcAnimation::mPants, MWWorld::InventoryStore::Slot_Pants, 0 }, { &NpcAnimation::mPants, MWWorld::InventoryStore::Slot_Pants, 0 },
{ &NpcAnimation::mShield, MWWorld::InventoryStore::Slot_CarriedLeft, 0 } { &NpcAnimation::mShield, MWWorld::InventoryStore::Slot_CarriedLeft, 0 },
{ &NpcAnimation::mWeapon, MWWorld::InventoryStore::Slot_CarriedRight, 0 }
}; };
static const size_t slotlistsize = sizeof(slotlist)/sizeof(slotlist[0]); static const size_t slotlistsize = sizeof(slotlist)/sizeof(slotlist[0]);
@ -239,7 +240,7 @@ void NpcAnimation::updateParts(bool forceupdate)
ESM::PRT_RForearm, ESM::PRT_LForearm, ESM::PRT_RPauldron, ESM::PRT_LPauldron ESM::PRT_RForearm, ESM::PRT_LForearm, ESM::PRT_RPauldron, ESM::PRT_LPauldron
}; };
size_t parts_size = sizeof(parts)/sizeof(parts[0]); size_t parts_size = sizeof(parts)/sizeof(parts[0]);
for(int p = 0;p < static_cast<int> (parts_size);++p) for(size_t p = 0;p < parts_size;++p)
reserveIndividualPart(parts[p], slotlist[i].mSlot, prio); reserveIndividualPart(parts[p], slotlist[i].mSlot, prio);
} }
else if(slotlist[i].mSlot == MWWorld::InventoryStore::Slot_Skirt) else if(slotlist[i].mSlot == MWWorld::InventoryStore::Slot_Skirt)
@ -260,29 +261,7 @@ void NpcAnimation::updateParts(bool forceupdate)
if(mViewMode == VM_HeadOnly) if(mViewMode == VM_HeadOnly)
return; return;
std::map<int, int> bodypartMap; showWeapons(mShowWeapons);
bodypartMap[ESM::PRT_Neck] = ESM::BodyPart::MP_Neck;
bodypartMap[ESM::PRT_Cuirass] = ESM::BodyPart::MP_Chest;
bodypartMap[ESM::PRT_Groin] = ESM::BodyPart::MP_Groin;
bodypartMap[ESM::PRT_RHand] = ESM::BodyPart::MP_Hand;
bodypartMap[ESM::PRT_LHand] = ESM::BodyPart::MP_Hand;
bodypartMap[ESM::PRT_RWrist] = ESM::BodyPart::MP_Wrist;
bodypartMap[ESM::PRT_LWrist] = ESM::BodyPart::MP_Wrist;
bodypartMap[ESM::PRT_RForearm] = ESM::BodyPart::MP_Forearm;
bodypartMap[ESM::PRT_LForearm] = ESM::BodyPart::MP_Forearm;
bodypartMap[ESM::PRT_RUpperarm] = ESM::BodyPart::MP_Upperarm;
bodypartMap[ESM::PRT_LUpperarm] = ESM::BodyPart::MP_Upperarm;
bodypartMap[ESM::PRT_RFoot] = ESM::BodyPart::MP_Foot;
bodypartMap[ESM::PRT_LFoot] = ESM::BodyPart::MP_Foot;
bodypartMap[ESM::PRT_RAnkle] = ESM::BodyPart::MP_Ankle;
bodypartMap[ESM::PRT_LAnkle] = ESM::BodyPart::MP_Ankle;
bodypartMap[ESM::PRT_RKnee] = ESM::BodyPart::MP_Knee;
bodypartMap[ESM::PRT_LKnee] = ESM::BodyPart::MP_Knee;
bodypartMap[ESM::PRT_RLeg] = ESM::BodyPart::MP_Upperleg;
bodypartMap[ESM::PRT_LLeg] = ESM::BodyPart::MP_Upperleg;
bodypartMap[ESM::PRT_Tail] = ESM::BodyPart::MP_Tail;
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
const int Flag_Female = 0x01; const int Flag_Female = 0x01;
const int Flag_FirstPerson = 0x02; const int Flag_FirstPerson = 0x02;
@ -299,21 +278,43 @@ void NpcAnimation::updateParts(bool forceupdate)
std::pair<std::string, int> thisCombination = std::make_pair(race, flags); std::pair<std::string, int> thisCombination = std::make_pair(race, flags);
if (sRaceMapping.find(thisCombination) == sRaceMapping.end()) if (sRaceMapping.find(thisCombination) == sRaceMapping.end())
{ {
sRaceMapping[thisCombination].resize(ESM::PRT_Count); static std::map<int, int> bodypartMap;
for (int i=0; i<ESM::PRT_Count; ++i) if(bodypartMap.size() == 0)
sRaceMapping[thisCombination][i] = NULL; {
bodypartMap[ESM::PRT_Neck] = ESM::BodyPart::MP_Neck;
bodypartMap[ESM::PRT_Cuirass] = ESM::BodyPart::MP_Chest;
bodypartMap[ESM::PRT_Groin] = ESM::BodyPart::MP_Groin;
bodypartMap[ESM::PRT_RHand] = ESM::BodyPart::MP_Hand;
bodypartMap[ESM::PRT_LHand] = ESM::BodyPart::MP_Hand;
bodypartMap[ESM::PRT_RWrist] = ESM::BodyPart::MP_Wrist;
bodypartMap[ESM::PRT_LWrist] = ESM::BodyPart::MP_Wrist;
bodypartMap[ESM::PRT_RForearm] = ESM::BodyPart::MP_Forearm;
bodypartMap[ESM::PRT_LForearm] = ESM::BodyPart::MP_Forearm;
bodypartMap[ESM::PRT_RUpperarm] = ESM::BodyPart::MP_Upperarm;
bodypartMap[ESM::PRT_LUpperarm] = ESM::BodyPart::MP_Upperarm;
bodypartMap[ESM::PRT_RFoot] = ESM::BodyPart::MP_Foot;
bodypartMap[ESM::PRT_LFoot] = ESM::BodyPart::MP_Foot;
bodypartMap[ESM::PRT_RAnkle] = ESM::BodyPart::MP_Ankle;
bodypartMap[ESM::PRT_LAnkle] = ESM::BodyPart::MP_Ankle;
bodypartMap[ESM::PRT_RKnee] = ESM::BodyPart::MP_Knee;
bodypartMap[ESM::PRT_LKnee] = ESM::BodyPart::MP_Knee;
bodypartMap[ESM::PRT_RLeg] = ESM::BodyPart::MP_Upperleg;
bodypartMap[ESM::PRT_LLeg] = ESM::BodyPart::MP_Upperleg;
bodypartMap[ESM::PRT_Tail] = ESM::BodyPart::MP_Tail;
}
const MWWorld::Store<ESM::BodyPart> &partStore = store.get<ESM::BodyPart>(); sRaceMapping[thisCombination].resize(ESM::PRT_Count, NULL);
for (MWWorld::Store<ESM::BodyPart>::iterator it = partStore.begin(); it != partStore.end(); ++it) const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
const MWWorld::Store<ESM::BodyPart> &partStore = store.get<ESM::BodyPart>();
for(MWWorld::Store<ESM::BodyPart>::iterator it = partStore.begin(); it != partStore.end(); ++it)
{ {
const ESM::BodyPart& bodypart = *it; const ESM::BodyPart& bodypart = *it;
if (bodypart.mData.mFlags & ESM::BodyPart::BPF_NotPlayable) if (bodypart.mData.mFlags & ESM::BodyPart::BPF_NotPlayable)
continue; continue;
if (bodypart.mData.mType != ESM::BodyPart::MT_Skin) if (bodypart.mData.mType != ESM::BodyPart::MT_Skin)
{
continue; continue;
}
if (!mNpc->isMale() != (bodypart.mData.mFlags & ESM::BodyPart::BPF_Female)) if (!mNpc->isMale() != (bodypart.mData.mFlags & ESM::BodyPart::BPF_Female))
continue; continue;
if (!Misc::StringUtils::ciEqual(bodypart.mRace, mNpc->mRace)) if (!Misc::StringUtils::ciEqual(bodypart.mRace, mNpc->mRace))
@ -480,7 +481,7 @@ void NpcAnimation::showWeapons(bool showWeapon)
if(mWeapon != inv.end()) // special case for weapons if(mWeapon != inv.end()) // special case for weapons
{ {
std::string mesh = MWWorld::Class::get(*mWeapon).getModel(*mWeapon); std::string mesh = MWWorld::Class::get(*mWeapon).getModel(*mWeapon);
addOrReplaceIndividualPart(ESM::PRT_Weapon,-1,1,mesh); addOrReplaceIndividualPart(ESM::PRT_Weapon, MWWorld::InventoryStore::Slot_CarriedRight, 1, mesh);
} }
} }
else else

@ -49,12 +49,14 @@ using namespace Ogre;
namespace MWRender { namespace MWRender {
RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, RenderingManager::RenderingManager(OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir,
const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine,MWWorld::Fallback* fallback) const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine,
MWWorld::Fallback* fallback)
: mRendering(_rend) : mRendering(_rend)
, mFallback(fallback) , mFallback(fallback)
, mObjects(mRendering,mFallback) , mObjects(mRendering, mFallback)
, mActors(mRendering, this) , mActors(mRendering, this)
, mPlayerAnimation(NULL)
, mAmbientMode(0) , mAmbientMode(0)
, mSunEnabled(0) , mSunEnabled(0)
, mPhysicsEngine(engine) , mPhysicsEngine(engine)
@ -148,14 +150,13 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
applyCompositors(); applyCompositors();
SceneNode *rt = mRendering.getScene()->getRootSceneNode(); mRootNode = mRendering.getScene()->getRootSceneNode();
mRootNode = rt; mRootNode->createChildSceneNode("player");
mObjects.setRootNode(mRootNode); mObjects.setRootNode(mRootNode);
mActors.setRootNode(mRootNode); mActors.setRootNode(mRootNode);
Ogre::SceneNode *playerNode = mRootNode->createChildSceneNode ("player"); mCamera = new MWRender::Camera(mRendering.getCamera());
mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode);
mShadows = new Shadows(&mRendering); mShadows = new Shadows(&mRendering);
@ -183,7 +184,8 @@ RenderingManager::~RenderingManager ()
mRendering.getWindow()->removeListener(this); mRendering.getWindow()->removeListener(this);
mRendering.removeWindowEventListener(this); mRendering.removeWindowEventListener(this);
delete mPlayer; delete mPlayerAnimation;
delete mCamera;
delete mSkyManager; delete mSkyManager;
delete mDebugging; delete mDebugging;
delete mShadows; delete mShadows;
@ -264,37 +266,20 @@ void RenderingManager::scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3
ptr.getRefData().getBaseNode()->setScale(scale); ptr.getRefData().getBaseNode()->setScale(scale);
} }
bool RenderingManager::rotateObject(const MWWorld::Ptr &ptr, Ogre::Vector3 &rot, bool adjust) void RenderingManager::rotateObject(const MWWorld::Ptr &ptr)
{ {
bool isActive = ptr.getRefData().getBaseNode() != 0; Ogre::Vector3 rot(ptr.getRefData().getPosition().rot);
bool isPlayer = isActive && ptr.getRefData().getHandle() == "player";
bool force = true;
if (isPlayer) if(ptr.getRefData().getHandle() == mCamera->getHandle() &&
force = mPlayer->rotate(rot, adjust); !mCamera->isVanityOrPreviewModeEnabled())
mCamera->rotateCamera(rot, false);
MWWorld::Class::get(ptr).adjustRotation(ptr, rot.x, rot.y, rot.z); Ogre::Quaternion newo = Ogre::Quaternion(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Z);
if (!isPlayer && isActive) if(!MWWorld::Class::get(ptr).isActor())
{ newo = Ogre::Quaternion(Ogre::Radian(-rot.x), Ogre::Vector3::UNIT_X) *
if(adjust) Ogre::Quaternion(Ogre::Radian(-rot.y), Ogre::Vector3::UNIT_Y) * newo;
{
const float *objRot = ptr.getRefData().getPosition().rot;
rot.x += objRot[0];
rot.y += objRot[1];
rot.z += objRot[2];
}
Ogre::Quaternion newo = Ogre::Quaternion(Ogre::Radian(-rot.x), Ogre::Vector3::UNIT_X) * ptr.getRefData().getBaseNode()->setOrientation(newo);
Ogre::Quaternion(Ogre::Radian(-rot.y), Ogre::Vector3::UNIT_Y) *
Ogre::Quaternion(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Z);
ptr.getRefData().getBaseNode()->setOrientation(newo);
}
else if(isPlayer)
{
rot.x = -mPlayer->getPitch();
rot.z = mPlayer->getYaw();
}
return force;
} }
void void
@ -317,7 +302,7 @@ void RenderingManager::update (float duration, bool paused)
{ {
MWBase::World *world = MWBase::Environment::get().getWorld(); MWBase::World *world = MWBase::Environment::get().getWorld();
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWWorld::Ptr player = world->getPlayer().getPlayer();
int blind = MWWorld::Class::get(player).getCreatureStats(player).getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::Blind)).mMagnitude; int blind = MWWorld::Class::get(player).getCreatureStats(player).getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::Blind)).mMagnitude;
mRendering.getFader()->setFactor(1.f-(blind / 100.f)); mRendering.getFader()->setFactor(1.f-(blind / 100.f));
@ -330,16 +315,16 @@ void RenderingManager::update (float duration, bool paused)
Ogre::Vector3 playerPos(_playerPos[0], _playerPos[1], _playerPos[2]); Ogre::Vector3 playerPos(_playerPos[0], _playerPos[1], _playerPos[2]);
Ogre::Vector3 orig, dest; Ogre::Vector3 orig, dest;
mPlayer->setCameraDistance(); mCamera->setCameraDistance();
if (!mPlayer->getPosition(orig, dest)) { if(!mCamera->getPosition(orig, dest))
orig.z += mPlayer->getHeight() * mRootNode->getScale().z; {
orig.z += mCamera->getHeight() * mRootNode->getScale().z;
btVector3 btOrig(orig.x, orig.y, orig.z); btVector3 btOrig(orig.x, orig.y, orig.z);
btVector3 btDest(dest.x, dest.y, dest.z); btVector3 btDest(dest.x, dest.y, dest.z);
std::pair<std::string, float> test = std::pair<std::string,float> test = mPhysicsEngine->rayTest(btOrig, btDest);
mPhysicsEngine->rayTest(btOrig, btDest);
if (!test.first.empty()) { if (!test.first.empty()) {
mPlayer->setCameraDistance(test.second * orig.distance(dest), false, false); mCamera->setCameraDistance(test.second * orig.distance(dest), false, false);
} }
} }
@ -353,14 +338,12 @@ void RenderingManager::update (float duration, bool paused)
Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition(); Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition();
applyFog(world->isUnderwater (world->getPlayer().getPlayer().getCell(), cam)); applyFog(world->isUnderwater(player.getCell(), cam));
if(paused) if(paused)
{
return; return;
}
mPlayer->update(duration); mCamera->update(duration);
mActors.update (duration); mActors.update (duration);
mObjects.update (duration); mObjects.update (duration);
@ -371,18 +354,11 @@ void RenderingManager::update (float duration, bool paused)
mSkyManager->setGlare(mOcclusionQuery->getSunVisibility()); mSkyManager->setGlare(mOcclusionQuery->getSunVisibility());
Ogre::SceneNode *node = data.getBaseNode(); Ogre::SceneNode *node = data.getBaseNode();
//Ogre::Quaternion orient = Ogre::Quaternion orient = node->_getDerivedOrientation();
//node->convertLocalToWorldOrientation(node->_getDerivedOrientation());
Ogre::Quaternion orient =
node->_getDerivedOrientation();
mLocalMap->updatePlayer(playerPos, orient); mLocalMap->updatePlayer(playerPos, orient);
mWater->updateUnderwater( mWater->updateUnderwater(world->isUnderwater(player.getCell(), cam));
world->isUnderwater(
world->getPlayer().getPlayer().getCell(),
cam)
);
mWater->update(duration, playerPos); mWater->update(duration, playerPos);
} }
@ -876,39 +852,49 @@ void RenderingManager::getTriangleBatchCount(unsigned int &triangles, unsigned i
} }
} }
void RenderingManager::attachCameraTo(const MWWorld::Ptr &ptr) void RenderingManager::setupPlayer(const MWWorld::Ptr &ptr)
{ {
mPlayer->attachTo(ptr); ptr.getRefData().setBaseNode(mRendering.getScene()->getSceneNode("player"));
mCamera->attachTo(ptr);
} }
void RenderingManager::renderPlayer(const MWWorld::Ptr &ptr) void RenderingManager::renderPlayer(const MWWorld::Ptr &ptr)
{ {
MWRender::NpcAnimation *anim = if(!mPlayerAnimation)
new MWRender::NpcAnimation( {
ptr, ptr.getRefData ().getBaseNode (), mPlayerAnimation = new NpcAnimation(ptr, ptr.getRefData().getBaseNode(),
MWWorld::Class::get(ptr).getInventoryStore(ptr), RV_Actors MWWorld::Class::get(ptr).getInventoryStore(ptr),
); RV_Actors);
mPlayer->setAnimation(anim); }
mWater->removeEmitter (ptr); else
mWater->addEmitter (ptr); {
// Reconstruct the NpcAnimation in-place
mPlayerAnimation->~NpcAnimation();
new(mPlayerAnimation) NpcAnimation(ptr, ptr.getRefData().getBaseNode(),
MWWorld::Class::get(ptr).getInventoryStore(ptr),
RV_Actors);
}
mCamera->setAnimation(mPlayerAnimation);
mWater->removeEmitter(ptr);
mWater->addEmitter(ptr);
// apply race height // apply race height
MWBase::Environment::get().getWorld()->scaleObject(ptr, 1.f); MWBase::Environment::get().getWorld()->scaleObject(ptr, 1.f);
} }
void RenderingManager::getPlayerData(Ogre::Vector3 &eyepos, float &pitch, float &yaw) void RenderingManager::getCameraData(Ogre::Vector3 &eyepos, float &pitch, float &yaw)
{ {
eyepos = mPlayer->getPosition(); eyepos = mCamera->getPosition();
eyepos.z += mPlayer->getHeight(); eyepos.z += mCamera->getHeight();
mPlayer->getSightAngles(pitch, yaw); mCamera->getSightAngles(pitch, yaw);
} }
bool RenderingManager::vanityRotateCamera(float* rot) bool RenderingManager::vanityRotateCamera(const float *rot)
{ {
if(!mPlayer->isVanityOrPreviewModeEnabled()) if(!mCamera->isVanityOrPreviewModeEnabled())
return false; return false;
Ogre::Vector3 vRot(rot); Ogre::Vector3 vRot(rot);
mPlayer->rotateCamera(vRot, true); mCamera->rotateCamera(vRot, true);
return true; return true;
} }
@ -931,7 +917,7 @@ Animation* RenderingManager::getAnimation(const MWWorld::Ptr &ptr)
{ {
Animation *anim = mActors.getAnimation(ptr); Animation *anim = mActors.getAnimation(ptr);
if(!anim && ptr.getRefData().getHandle() == "player") if(!anim && ptr.getRefData().getHandle() == "player")
anim = mPlayer->getAnimation(); anim = mPlayerAnimation;
return anim; return anim;
} }

@ -17,7 +17,7 @@
#include "objects.hpp" #include "objects.hpp"
#include "actors.hpp" #include "actors.hpp"
#include "player.hpp" #include "camera.hpp"
#include "occlusionquery.hpp" #include "occlusionquery.hpp"
namespace Ogre namespace Ogre
@ -50,49 +50,44 @@ namespace MWRender
class VideoPlayer; class VideoPlayer;
class Animation; class Animation;
class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener, public Ogre::RenderTargetListener { class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener, public Ogre::RenderTargetListener
{
private: private:
virtual MWRender::Objects& getObjects(); virtual MWRender::Objects& getObjects();
virtual MWRender::Actors& getActors(); virtual MWRender::Actors& getActors();
public: public:
RenderingManager(OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, RenderingManager(OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir,
const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine,MWWorld::Fallback* fallback); const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine,
MWWorld::Fallback* fallback);
virtual ~RenderingManager(); virtual ~RenderingManager();
void togglePOV() { void togglePOV()
mPlayer->toggleViewMode(); { mCamera->toggleViewMode(); }
}
void togglePreviewMode(bool enable) { void togglePreviewMode(bool enable)
mPlayer->togglePreviewMode(enable); { mCamera->togglePreviewMode(enable); }
}
bool toggleVanityMode(bool enable, bool force) { bool toggleVanityMode(bool enable)
return mPlayer->toggleVanityMode(enable, force); { return mCamera->toggleVanityMode(enable); }
}
void allowVanityMode(bool allow) { void allowVanityMode(bool allow)
mPlayer->allowVanityMode(allow); { mCamera->allowVanityMode(allow); }
}
void togglePlayerLooking(bool enable) { void togglePlayerLooking(bool enable)
mPlayer->togglePlayerLooking(enable); { mCamera->togglePlayerLooking(enable); }
}
void changeVanityModeScale(float factor) { void changeVanityModeScale(float factor)
if (mPlayer->isVanityOrPreviewModeEnabled()) {
mPlayer->setCameraDistance(-factor/120.f*10, true, true); if(mCamera->isVanityOrPreviewModeEnabled())
mCamera->setCameraDistance(-factor/120.f*10, true, true);
} }
bool vanityRotateCamera(float* rot); bool vanityRotateCamera(const float *rot);
void getPlayerData(Ogre::Vector3 &eyepos, float &pitch, float &yaw); void getCameraData(Ogre::Vector3 &eyepos, float &pitch, float &yaw);
void attachCameraTo(const MWWorld::Ptr &ptr); void setupPlayer(const MWWorld::Ptr &ptr);
void renderPlayer(const MWWorld::Ptr &ptr); void renderPlayer(const MWWorld::Ptr &ptr);
SkyManager* getSkyManager(); SkyManager* getSkyManager();
@ -121,11 +116,8 @@ 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);
/// Rotates object accordingly to its type /// Updates an object's rotation
/// \param rot euler angles in radians void rotateObject (const MWWorld::Ptr& ptr);
/// \param adjust indicates should rotation be set or adjusted
/// \return true if object needs to be rotated physically
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();
@ -207,12 +199,11 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
void stopVideo(); void stopVideo();
void frameStarted(float dt); void frameStarted(float dt);
protected: protected:
virtual void windowResized(Ogre::RenderWindow* rw); virtual void windowResized(Ogre::RenderWindow* rw);
virtual void windowClosed(Ogre::RenderWindow* rw); virtual void windowClosed(Ogre::RenderWindow* rw);
private: private:
sh::Factory* mFactory; sh::Factory* mFactory;
void setAmbientMode(); void setAmbientMode();
@ -241,6 +232,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
MWRender::Objects mObjects; MWRender::Objects mObjects;
MWRender::Actors mActors; MWRender::Actors mActors;
MWRender::NpcAnimation *mPlayerAnimation;
// 0 normal, 1 more bright, 2 max // 0 normal, 1 more bright, 2 max
int mAmbientMode; int mAmbientMode;
@ -255,7 +248,7 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
OEngine::Physic::PhysicEngine* mPhysicsEngine; OEngine::Physic::PhysicEngine* mPhysicsEngine;
MWRender::Player *mPlayer; MWRender::Camera *mCamera;
MWRender::Debugging *mDebugging; MWRender::Debugging *mDebugging;

@ -205,7 +205,7 @@ unsigned int Moon::getPhaseInt() const
return 0; return 0;
} }
SkyManager::SkyManager (SceneNode* root, Camera* pCamera) SkyManager::SkyManager(Ogre::SceneNode *root, Ogre::Camera *pCamera)
: mHour(0.0f) : mHour(0.0f)
, mDay(0) , mDay(0)
, mMonth(0) , mMonth(0)

@ -282,10 +282,8 @@ namespace MWScript
MWBase::World *world = MWBase::World *world =
MWBase::Environment::get().getWorld(); MWBase::Environment::get().getWorld();
if (world->toggleVanityMode(sActivate, true)) { if (world->toggleVanityMode(sActivate)) {
context.report( context.report(sActivate ? "Vanity Mode -> On" : "Vanity Mode -> Off");
(sActivate) ? "Vanity Mode -> On" : "Vanity Mode -> Off"
);
sActivate = !sActivate; sActivate = !sActivate;
} else { } else {
context.report("Vanity Mode -> No"); context.report("Vanity Mode -> No");

@ -144,7 +144,7 @@ namespace MWWorld
// FIXME: This works, but it's inconcsistent with how the rotations are applied elsewhere. Why? // FIXME: This works, but it's inconcsistent with how the rotations are applied elsewhere. Why?
return position + (Ogre::Quaternion(Ogre::Radian( -refpos.rot[2]), Ogre::Vector3::UNIT_Z)* return position + (Ogre::Quaternion(Ogre::Radian( -refpos.rot[2]), Ogre::Vector3::UNIT_Z)*
Ogre::Quaternion(Ogre::Radian( -refpos.rot[1]), Ogre::Vector3::UNIT_Y)* Ogre::Quaternion(Ogre::Radian( -refpos.rot[1]), Ogre::Vector3::UNIT_Y)*
Ogre::Quaternion(Ogre::Radian( -refpos.rot[0]), Ogre::Vector3::UNIT_X)) * Ogre::Quaternion(Ogre::Radian( refpos.rot[0]), Ogre::Vector3::UNIT_X)) *
movement; movement;
} }
@ -160,7 +160,7 @@ namespace MWWorld
{ {
velocity = (Ogre::Quaternion(Ogre::Radian( -refpos.rot[2]), Ogre::Vector3::UNIT_Z)* velocity = (Ogre::Quaternion(Ogre::Radian( -refpos.rot[2]), Ogre::Vector3::UNIT_Z)*
Ogre::Quaternion(Ogre::Radian( -refpos.rot[1]), Ogre::Vector3::UNIT_Y)* Ogre::Quaternion(Ogre::Radian( -refpos.rot[1]), Ogre::Vector3::UNIT_Y)*
Ogre::Quaternion(Ogre::Radian( -refpos.rot[0]), Ogre::Vector3::UNIT_X)) * Ogre::Quaternion(Ogre::Radian( refpos.rot[0]), Ogre::Vector3::UNIT_X)) *
movement / time; movement / time;
} }
else else
@ -260,14 +260,13 @@ namespace MWWorld
std::pair<float, std::string> PhysicsSystem::getFacedHandle (MWWorld::World& world, float queryDistance) std::pair<float, std::string> PhysicsSystem::getFacedHandle (MWWorld::World& world, float queryDistance)
{ {
btVector3 dir(0, 1, 0); btVector3 dir(0, 1, 0);
dir = dir.rotate(btVector3(1, 0, 0), mPlayerData.pitch); dir = dir.rotate(btVector3(1, 0, 0), mCameraData.pitch);
dir = dir.rotate(btVector3(0, 0, 1), mPlayerData.yaw); dir = dir.rotate(btVector3(0, 0, 1), mCameraData.yaw);
dir.setX(-dir.x()); dir.setX(-dir.x());
btVector3 origin( btVector3 origin(mCameraData.eyepos.x,
mPlayerData.eyepos.x, mCameraData.eyepos.y,
mPlayerData.eyepos.y, mCameraData.eyepos.z);
mPlayerData.eyepos.z);
origin += dir * 5; origin += dir * 5;
btVector3 dest = origin + dir * queryDistance; btVector3 dest = origin + dir * queryDistance;
@ -280,14 +279,13 @@ namespace MWWorld
std::vector < std::pair <float, std::string> > PhysicsSystem::getFacedHandles (float queryDistance) std::vector < std::pair <float, std::string> > PhysicsSystem::getFacedHandles (float queryDistance)
{ {
btVector3 dir(0, 1, 0); btVector3 dir(0, 1, 0);
dir = dir.rotate(btVector3(1, 0, 0), mPlayerData.pitch); dir = dir.rotate(btVector3(1, 0, 0), mCameraData.pitch);
dir = dir.rotate(btVector3(0, 0, 1), mPlayerData.yaw); dir = dir.rotate(btVector3(0, 0, 1), mCameraData.yaw);
dir.setX(-dir.x()); dir.setX(-dir.x());
btVector3 origin( btVector3 origin(mCameraData.eyepos.x,
mPlayerData.eyepos.x, mCameraData.eyepos.y,
mPlayerData.eyepos.y, mCameraData.eyepos.z);
mPlayerData.eyepos.z);
origin += dir * 5; origin += dir * 5;
btVector3 dest = origin + dir * queryDistance; btVector3 dest = origin + dir * queryDistance;
@ -552,10 +550,10 @@ namespace MWWorld
return true; return true;
} }
void PhysicsSystem::updatePlayerData(Ogre::Vector3 &eyepos, float pitch, float yaw) void PhysicsSystem::updateCameraData(const Ogre::Vector3 &eyepos, float pitch, float yaw)
{ {
mPlayerData.eyepos = eyepos; mCameraData.eyepos = eyepos;
mPlayerData.pitch = pitch; mCameraData.pitch = pitch;
mPlayerData.yaw = yaw; mCameraData.yaw = yaw;
} }
} }

@ -77,13 +77,13 @@ namespace MWWorld
bool getObjectAABB(const MWWorld::Ptr &ptr, Ogre::Vector3 &min, Ogre::Vector3 &max); bool getObjectAABB(const MWWorld::Ptr &ptr, Ogre::Vector3 &min, Ogre::Vector3 &max);
void updatePlayerData(Ogre::Vector3 &eyepos, float pitch, float yaw); void updateCameraData(const Ogre::Vector3 &eyepos, float pitch, float yaw);
private: private:
struct { struct {
Ogre::Vector3 eyepos; Ogre::Vector3 eyepos;
float pitch, yaw; float pitch, yaw;
} mPlayerData; } mCameraData;
OEngine::Render::OgreRenderer &mRender; OEngine::Render::OgreRenderer &mRender;
OEngine::Physic::PhysicEngine* mEngine; OEngine::Physic::PhysicEngine* mEngine;

@ -81,10 +81,13 @@ namespace MWWorld
{} {}
} }
std::string RefData::getHandle() const std::string &RefData::getHandle()
{ {
if (!mBaseNode) if(!mBaseNode)
return ""; {
static const std::string empty;
return empty;
}
return mBaseNode->getName(); return mBaseNode->getName();
} }

@ -60,7 +60,7 @@ namespace MWWorld
RefData& operator= (const RefData& refData); RefData& operator= (const RefData& refData);
/// Return OGRE handle (may be empty). /// Return OGRE handle (may be empty).
std::string getHandle(); const std::string &getHandle();
/// Return OGRE base node (can be a null pointer). /// Return OGRE base node (can be a null pointer).
Ogre::SceneNode* getBaseNode(); Ogre::SceneNode* getBaseNode();

@ -18,7 +18,6 @@
#include "../mwmechanics/movement.hpp" #include "../mwmechanics/movement.hpp"
#include "../mwrender/sky.hpp" #include "../mwrender/sky.hpp"
#include "../mwrender/player.hpp"
#include "../mwclass/door.hpp" #include "../mwclass/door.hpp"
@ -813,33 +812,50 @@ namespace MWWorld
void World::rotateObjectImp (const Ptr& ptr, Ogre::Vector3 rot, bool adjust) void World::rotateObjectImp (const Ptr& ptr, Ogre::Vector3 rot, bool adjust)
{ {
if (mRendering->rotateObject(ptr, rot, adjust)) const float two_pi = Ogre::Math::TWO_PI;
const float pi = Ogre::Math::PI;
float *objRot = ptr.getRefData().getPosition().rot;
if(adjust)
{
objRot[0] += rot.x;
objRot[1] += rot.y;
objRot[2] += rot.z;
}
else
{ {
// rotate physically iff renderer confirm so
float *objRot = ptr.getRefData().getPosition().rot;
objRot[0] = rot.x; objRot[0] = rot.x;
objRot[1] = rot.y; objRot[1] = rot.y;
objRot[2] = rot.z; objRot[2] = rot.z;
}
float fullRotateRad=Ogre::Degree(360).valueRadians(); if(Class::get(ptr).isActor())
{
/* HACK? Actors shouldn't really be rotating around X (or Y), but
* currently it's done so for rotating the camera, which needs
* clamping.
*/
const float half_pi = Ogre::Math::HALF_PI;
if(objRot[0] < -half_pi) objRot[0] = -half_pi;
else if(objRot[0] > half_pi) objRot[0] = half_pi;
}
else
{
while(objRot[0] < -pi) objRot[0] += two_pi;
while(objRot[0] > pi) objRot[0] -= two_pi;
}
while(objRot[0]>=fullRotateRad) while(objRot[1] < -pi) objRot[1] += two_pi;
objRot[0] -= fullRotateRad; while(objRot[1] > pi) objRot[1] -= two_pi;
while(objRot[1]>=fullRotateRad)
objRot[1] -= fullRotateRad; while(objRot[2] < -pi) objRot[2] += two_pi;
while(objRot[2]>=fullRotateRad) while(objRot[2] > pi) objRot[2] -= two_pi;
objRot[2] -= fullRotateRad;
if(ptr.getRefData().getBaseNode() != 0)
while(objRot[0]<=-fullRotateRad) {
objRot[0] += fullRotateRad; mRendering->rotateObject(ptr);
while(objRot[1]<=-fullRotateRad) mPhysics->rotateObject(ptr);
objRot[1] += fullRotateRad;
while(objRot[2]<=-fullRotateRad)
objRot[2] += fullRotateRad;
if (ptr.getRefData().getBaseNode() != 0) {
mPhysics->rotateObject(ptr);
}
} }
} }
@ -1136,8 +1152,8 @@ namespace MWWorld
float pitch, yaw; float pitch, yaw;
Ogre::Vector3 eyepos; Ogre::Vector3 eyepos;
mRendering->getPlayerData(eyepos, pitch, yaw); mRendering->getCameraData(eyepos, pitch, yaw);
mPhysics->updatePlayerData(eyepos, pitch, yaw); mPhysics->updateCameraData(eyepos, pitch, yaw);
performUpdateSceneQueries (); performUpdateSceneQueries ();
@ -1483,13 +1499,15 @@ namespace MWWorld
void World::setupPlayer() void World::setupPlayer()
{ {
const ESM::NPC* player = mStore.get<ESM::NPC>().find ("player"); const ESM::NPC *player = mStore.get<ESM::NPC>().find("player");
mPlayer = new MWWorld::Player (player, *this); mPlayer = new MWWorld::Player(player, *this);
mRendering->attachCameraTo(mPlayer->getPlayer());
Ptr ptr = mPlayer->getPlayer();
mRendering->setupPlayer(ptr);
if (mNewGame) if (mNewGame)
{ {
MWWorld::Class::get(mPlayer->getPlayer()).getContainerStore(mPlayer->getPlayer()).fill(player->mInventory, "", mStore); MWWorld::Class::get(ptr).getContainerStore(ptr).fill(player->mInventory, "", mStore);
MWWorld::Class::get(mPlayer->getPlayer()).getInventoryStore(mPlayer->getPlayer()).autoEquip (mPlayer->getPlayer()); MWWorld::Class::get(ptr).getInventoryStore(ptr).autoEquip(ptr);
} }
} }

@ -355,8 +355,8 @@ namespace MWWorld
mRendering->togglePreviewMode(enable); mRendering->togglePreviewMode(enable);
} }
virtual bool toggleVanityMode(bool enable, bool force) { virtual bool toggleVanityMode(bool enable) {
return mRendering->toggleVanityMode(enable, force); return mRendering->toggleVanityMode(enable);
} }
virtual void allowVanityMode(bool allow) { virtual void allowVanityMode(bool allow) {

@ -207,7 +207,7 @@ struct RecordFactoryEntry {
static const RecordFactoryEntry recordFactories [] = { static const RecordFactoryEntry recordFactories [] = {
{ "NiNode", &construct <NiNode >, RC_NiNode }, { "NiNode", &construct <NiNode >, RC_NiNode },
{ "AvoidNode", &construct <NiNode >, RC_NiNode }, { "AvoidNode", &construct <NiNode >, RC_AvoidNode },
{ "NiBSParticleNode", &construct <NiNode >, RC_NiBSParticleNode }, { "NiBSParticleNode", &construct <NiNode >, RC_NiBSParticleNode },
{ "NiBSAnimationNode", &construct <NiNode >, RC_NiBSAnimationNode }, { "NiBSAnimationNode", &construct <NiNode >, RC_NiBSAnimationNode },
{ "NiBillboardNode", &construct <NiNode >, RC_NiNode }, { "NiBillboardNode", &construct <NiNode >, RC_NiNode },

@ -36,6 +36,7 @@ enum RecordType
{ {
RC_MISSING = 0, RC_MISSING = 0,
RC_NiNode, RC_NiNode,
RC_AvoidNode,
RC_NiTriShape, RC_NiTriShape,
RC_NiRotatingParticles, RC_NiRotatingParticles,
RC_NiAutoNormalParticles, RC_NiAutoNormalParticles,

@ -185,6 +185,10 @@ void ManualBulletShapeLoader::handleNode(btTriangleMesh* mesh, const Nif::Node *
else else
isCollisionNode = isCollisionNode && (node->recType != Nif::RC_RootCollisionNode); isCollisionNode = isCollisionNode && (node->recType != Nif::RC_RootCollisionNode);
// Don't collide with AvoidNode shapes
if(node->recType == Nif::RC_AvoidNode)
flags |= 0x800;
// Marker objects // Marker objects
/// \todo don't do this in the editor /// \todo don't do this in the editor
std::string nodename = node->name; std::string nodename = node->name;

Loading…
Cancel
Save