mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 23:53:52 +00:00
Merge remote-tracking branch 'kcat/animations'
This commit is contained in:
commit
61e476118d
23 changed files with 365 additions and 378 deletions
|
@ -14,7 +14,7 @@ set(GAME_HEADER
|
|||
source_group(game FILES ${GAME} ${GAME_HEADER})
|
||||
|
||||
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
|
||||
compositors characterpreview externalrendering globalmap videoplayer ripplesimulation refraction
|
||||
)
|
||||
|
|
|
@ -317,7 +317,7 @@ namespace MWBase
|
|||
|
||||
virtual void togglePOV() = 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 togglePlayerLooking(bool enable) = 0;
|
||||
virtual void changeVanityModeScale(float factor) = 0;
|
||||
|
|
|
@ -720,19 +720,17 @@ namespace MWInput
|
|||
|
||||
void InputManager::resetIdleTime()
|
||||
{
|
||||
if (mTimeIdle < 0) {
|
||||
MWBase::Environment::get().getWorld()->toggleVanityMode(false, false);
|
||||
}
|
||||
if (mTimeIdle < 0)
|
||||
MWBase::Environment::get().getWorld()->toggleVanityMode(false);
|
||||
mTimeIdle = 0.f;
|
||||
}
|
||||
|
||||
void InputManager::updateIdleTime(float dt)
|
||||
{
|
||||
if (mTimeIdle >= 0.f) {
|
||||
if (mTimeIdle >= 0.f)
|
||||
mTimeIdle += dt;
|
||||
}
|
||||
if (mTimeIdle > 30.f) {
|
||||
MWBase::Environment::get().getWorld()->toggleVanityMode(true, false);
|
||||
MWBase::Environment::get().getWorld()->toggleVanityMode(true);
|
||||
mTimeIdle = -1.f;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#include "player.hpp"
|
||||
#include "camera.hpp"
|
||||
|
||||
#include <OgreSceneNode.h>
|
||||
#include <OgreCamera.h>
|
||||
#include <OgreSceneManager.h>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
|
@ -14,10 +15,9 @@
|
|||
|
||||
namespace MWRender
|
||||
{
|
||||
Player::Player (Ogre::Camera *camera, Ogre::SceneNode* node)
|
||||
Camera::Camera (Ogre::Camera *camera)
|
||||
: mCamera(camera),
|
||||
mPlayerNode(node),
|
||||
mCameraNode(mPlayerNode->createChildSceneNode()),
|
||||
mCameraNode(NULL),
|
||||
mFirstPersonView(true),
|
||||
mPreviewMode(false),
|
||||
mFreeLook(true),
|
||||
|
@ -28,51 +28,16 @@ namespace MWRender
|
|||
{
|
||||
mVanity.enabled = false;
|
||||
mVanity.allowed = true;
|
||||
mVanity.forced = false;
|
||||
|
||||
mCameraNode->attachObject(mCamera);
|
||||
mCameraNode->setPosition(0.f, 0.f, mHeight);
|
||||
|
||||
mPreviewCam.yaw = 0.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) {
|
||||
setYaw(getYaw() + rot.z);
|
||||
|
@ -81,33 +46,37 @@ namespace MWRender
|
|||
setYaw(rot.z);
|
||||
setPitch(rot.x);
|
||||
}
|
||||
Ogre::Quaternion xr(
|
||||
Ogre::Radian(getPitch() + Ogre::Math::HALF_PI),
|
||||
Ogre::Vector3::UNIT_X
|
||||
);
|
||||
Ogre::Quaternion zr(
|
||||
Ogre::Radian(getYaw()),
|
||||
Ogre::Vector3::NEGATIVE_UNIT_Z
|
||||
);
|
||||
|
||||
Ogre::Quaternion xr(Ogre::Radian(getPitch() + Ogre::Math::HALF_PI), Ogre::Vector3::UNIT_X);
|
||||
if (!mVanity.enabled && !mPreviewMode) {
|
||||
mPlayerNode->setOrientation(zr);
|
||||
mCameraNode->setOrientation(xr);
|
||||
} else {
|
||||
Ogre::Quaternion zr(Ogre::Radian(getYaw()), Ogre::Vector3::NEGATIVE_UNIT_Z);
|
||||
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 dir = mCamera->getRealDirection();
|
||||
|
@ -116,29 +85,27 @@ namespace MWRender
|
|||
MWBase::Environment::get().getSoundManager()->setListenerPosDir(pos, dir, up);
|
||||
}
|
||||
|
||||
void Player::update(float duration)
|
||||
void Camera::update(float duration)
|
||||
{
|
||||
updateListener();
|
||||
|
||||
// only show the crosshair in game mode and in first person mode.
|
||||
MWBase::Environment::get().getWindowManager ()->showCrosshair
|
||||
(!MWBase::Environment::get().getWindowManager ()->isGuiMode () && (mFirstPersonView && !mVanity.enabled && !mPreviewMode));
|
||||
MWBase::WindowManager *wm = MWBase::Environment::get().getWindowManager();
|
||||
wm->showCrosshair(!wm->isGuiMode() && (mFirstPersonView && !mVanity.enabled && !mPreviewMode));
|
||||
|
||||
if (mFirstPersonView && !mVanity.enabled) {
|
||||
return;
|
||||
}
|
||||
if (mVanity.enabled) {
|
||||
if(mVanity.enabled)
|
||||
{
|
||||
Ogre::Vector3 rot(0.f, 0.f, 0.f);
|
||||
rot.z = Ogre::Degree(3.f * duration).valueRadians();
|
||||
rotateCamera(rot, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::toggleViewMode()
|
||||
void Camera::toggleViewMode()
|
||||
{
|
||||
mFirstPersonView = !mFirstPersonView;
|
||||
mAnimation->setViewMode((mVanity.enabled || mPreviewMode || !mFirstPersonView) ?
|
||||
NpcAnimation::VM_Normal : NpcAnimation::VM_FirstPerson);
|
||||
mAnimation->setViewMode(isFirstPerson() ? NpcAnimation::VM_FirstPerson :
|
||||
NpcAnimation::VM_Normal);
|
||||
if (mFirstPersonView) {
|
||||
mCamera->setPosition(0.f, 0.f, 0.f);
|
||||
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);
|
||||
}
|
||||
mVanity.allowed = allow;
|
||||
}
|
||||
|
||||
bool Player::toggleVanityMode(bool enable, bool force)
|
||||
bool Camera::toggleVanityMode(bool enable)
|
||||
{
|
||||
if ((mVanity.forced && !force) ||
|
||||
(!mVanity.allowed && (force || enable)))
|
||||
{
|
||||
if(!mVanity.allowed && enable)
|
||||
return false;
|
||||
} else if (mVanity.enabled == enable) {
|
||||
return true;
|
||||
}
|
||||
mVanity.enabled = enable;
|
||||
mVanity.forced = force && enable;
|
||||
|
||||
mAnimation->setViewMode((mVanity.enabled || mPreviewMode || !mFirstPersonView) ?
|
||||
NpcAnimation::VM_Normal : NpcAnimation::VM_FirstPerson);
|
||||
if(mVanity.enabled == enable)
|
||||
return true;
|
||||
mVanity.enabled = enable;
|
||||
|
||||
mAnimation->setViewMode(isFirstPerson() ? NpcAnimation::VM_FirstPerson :
|
||||
NpcAnimation::VM_Normal);
|
||||
|
||||
float offset = mPreviewCam.offset;
|
||||
Ogre::Vector3 rot(0.f, 0.f, 0.f);
|
||||
|
@ -185,20 +148,22 @@ namespace MWRender
|
|||
setLowHeight(!mFirstPersonView);
|
||||
}
|
||||
rot.z = getYaw();
|
||||
|
||||
mCamera->setPosition(0.f, 0.f, offset);
|
||||
rotateCamera(rot, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Player::togglePreviewMode(bool enable)
|
||||
void Camera::togglePreviewMode(bool enable)
|
||||
{
|
||||
if (mPreviewMode == enable) {
|
||||
if(mPreviewMode == enable)
|
||||
return;
|
||||
}
|
||||
|
||||
mPreviewMode = enable;
|
||||
mAnimation->setViewMode((mVanity.enabled || mPreviewMode || !mFirstPersonView) ?
|
||||
NpcAnimation::VM_Normal : NpcAnimation::VM_FirstPerson);
|
||||
mAnimation->setViewMode(isFirstPerson() ? NpcAnimation::VM_FirstPerson :
|
||||
NpcAnimation::VM_Normal);
|
||||
|
||||
float offset = mCamera->getPosition().z;
|
||||
if (mPreviewMode) {
|
||||
mMainCam.offset = offset;
|
||||
|
@ -211,19 +176,19 @@ namespace MWRender
|
|||
|
||||
setLowHeight(!mFirstPersonView);
|
||||
}
|
||||
|
||||
mCamera->setPosition(0.f, 0.f, offset);
|
||||
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 mMainCam.yaw;
|
||||
}
|
||||
|
||||
void Player::setYaw(float angle)
|
||||
void Camera::setYaw(float angle)
|
||||
{
|
||||
if (angle > Ogre::Math::PI) {
|
||||
angle -= Ogre::Math::TWO_PI;
|
||||
|
@ -237,7 +202,7 @@ namespace MWRender
|
|||
}
|
||||
}
|
||||
|
||||
float Player::getPitch()
|
||||
float Camera::getPitch()
|
||||
{
|
||||
if (mVanity.enabled || mPreviewMode) {
|
||||
return mPreviewCam.pitch;
|
||||
|
@ -245,18 +210,18 @@ namespace MWRender
|
|||
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;
|
||||
if (mVanity.forced || mPreviewMode) {
|
||||
limit /= 2;
|
||||
}
|
||||
if (angle > limit) {
|
||||
if(mPreviewMode)
|
||||
limit /= 2;
|
||||
|
||||
if(angle > limit)
|
||||
angle = limit;
|
||||
} else if (angle < -limit) {
|
||||
else if(angle < -limit)
|
||||
angle = -limit;
|
||||
}
|
||||
|
||||
if (mVanity.enabled || mPreviewMode) {
|
||||
mPreviewCam.pitch = angle;
|
||||
} 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;
|
||||
}
|
||||
|
||||
Ogre::Vector3 v(0.f, 0.f, dist);
|
||||
if (adjust) {
|
||||
v += mCamera->getPosition();
|
||||
|
@ -293,7 +258,7 @@ namespace MWRender
|
|||
}
|
||||
}
|
||||
|
||||
void Player::setCameraDistance()
|
||||
void Camera::setCameraDistance()
|
||||
{
|
||||
if (mDistanceAdjusted) {
|
||||
if (mVanity.enabled || mPreviewMode) {
|
||||
|
@ -305,65 +270,54 @@ namespace MWRender
|
|||
mDistanceAdjusted = false;
|
||||
}
|
||||
|
||||
void Player::setAnimation(NpcAnimation *anim)
|
||||
void Camera::setAnimation(NpcAnimation *anim)
|
||||
{
|
||||
anim->setViewMode((mVanity.enabled || mPreviewMode || !mFirstPersonView) ?
|
||||
NpcAnimation::VM_Normal : NpcAnimation::VM_FirstPerson);
|
||||
|
||||
delete mAnimation;
|
||||
// If we're switching to a new NpcAnimation, ensure the old one is
|
||||
// using a normal view mode
|
||||
if(mAnimation && mAnimation != anim)
|
||||
mAnimation->setViewMode(NpcAnimation::VM_Normal);
|
||||
mAnimation = anim;
|
||||
mAnimation->setViewMode(isFirstPerson() ? NpcAnimation::VM_FirstPerson :
|
||||
NpcAnimation::VM_Normal);
|
||||
}
|
||||
|
||||
void Player::setHeight(float height)
|
||||
void Camera::setHeight(float height)
|
||||
{
|
||||
mHeight = height;
|
||||
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);
|
||||
camera = mCamera->getRealPosition();
|
||||
player = mPlayerNode->getPosition();
|
||||
player = mTrackingPtr.getRefData().getBaseNode()->getPosition();
|
||||
|
||||
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;
|
||||
yaw = mMainCam.yaw;
|
||||
}
|
||||
|
||||
void Player::compensateYaw(float diff)
|
||||
{
|
||||
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)
|
||||
void Camera::togglePlayerLooking(bool enable)
|
||||
{
|
||||
mFreeLook = enable;
|
||||
}
|
||||
|
||||
void Player::setLowHeight(bool low)
|
||||
void Camera::setLowHeight(bool low)
|
||||
{
|
||||
if (low) {
|
||||
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;
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
#ifndef GAME_MWRENDER_PLAYER_H
|
||||
#define GAME_MWRENDER_PLAYER_H
|
||||
#ifndef GAME_MWRENDER_CAMERA_H
|
||||
#define GAME_MWRENDER_CAMERA_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class Vector3;
|
||||
|
@ -10,24 +12,20 @@ namespace Ogre
|
|||
class SceneNode;
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
class Ptr;
|
||||
}
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
class NpcAnimation;
|
||||
/// \brief Player character rendering and camera control
|
||||
class Player
|
||||
|
||||
/// \brief Camera control
|
||||
class Camera
|
||||
{
|
||||
struct CamData {
|
||||
float pitch, yaw, offset;
|
||||
};
|
||||
|
||||
Ogre::Camera *mCamera;
|
||||
MWWorld::Ptr mTrackingPtr;
|
||||
|
||||
Ogre::SceneNode *mPlayerNode;
|
||||
Ogre::Camera *mCamera;
|
||||
Ogre::SceneNode *mCameraNode;
|
||||
|
||||
NpcAnimation *mAnimation;
|
||||
|
@ -37,7 +35,7 @@ namespace MWRender
|
|||
bool mFreeLook;
|
||||
|
||||
struct {
|
||||
bool enabled, allowed, forced;
|
||||
bool enabled, allowed;
|
||||
} mVanity;
|
||||
|
||||
float mHeight, mCameraDistance;
|
||||
|
@ -51,15 +49,11 @@ namespace MWRender
|
|||
void setLowHeight(bool low = true);
|
||||
|
||||
public:
|
||||
Camera(Ogre::Camera *camera);
|
||||
~Camera();
|
||||
|
||||
Player (Ogre::Camera *camera, Ogre::SceneNode* mNode);
|
||||
~Player();
|
||||
|
||||
/// Set where the player is looking at. Uses Morrowind (euler) angles
|
||||
/// Set where the camera is looking at. Uses Morrowind (euler) angles
|
||||
/// \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);
|
||||
|
||||
float getYaw();
|
||||
|
@ -68,22 +62,21 @@ namespace MWRender
|
|||
float getPitch();
|
||||
void setPitch(float angle);
|
||||
|
||||
void compensateYaw(float diff);
|
||||
|
||||
std::string getHandle() const;
|
||||
const std::string &getHandle() const;
|
||||
|
||||
/// Attach camera to object
|
||||
/// \note there is no protection from attaching the same camera to
|
||||
/// several different objects
|
||||
void attachTo(const MWWorld::Ptr &);
|
||||
|
||||
void toggleViewMode();
|
||||
|
||||
bool toggleVanityMode(bool enable, bool force = false);
|
||||
bool toggleVanityMode(bool enable);
|
||||
void allowVanityMode(bool allow);
|
||||
|
||||
void togglePreviewMode(bool enable);
|
||||
|
||||
bool isFirstPerson() const
|
||||
{ return !(mVanity.enabled || mPreviewMode || !mFirstPersonView); }
|
||||
|
||||
void update(float duration);
|
||||
|
||||
/// Set camera distance for current mode. Don't work on 1st person view.
|
||||
|
@ -96,8 +89,6 @@ namespace MWRender
|
|||
void setCameraDistance();
|
||||
|
||||
void setAnimation(NpcAnimation *anim);
|
||||
NpcAnimation *getAnimation() const
|
||||
{ return mAnimation; }
|
||||
|
||||
void setHeight(float height);
|
||||
float getHeight();
|
|
@ -12,6 +12,7 @@
|
|||
#include "../mwbase/world.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
|
||||
#include "renderconst.hpp"
|
||||
#include "npcanimation.hpp"
|
||||
|
@ -134,6 +135,46 @@ namespace MWRender
|
|||
|
||||
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->runAnimation(0.0f);
|
||||
|
||||
|
@ -155,7 +196,10 @@ namespace MWRender
|
|||
if (!mSelectionBuffer)
|
||||
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;
|
||||
|
||||
MWRender::NpcAnimation* mAnimation;
|
||||
std::string mCurrentAnimGroup;
|
||||
|
||||
std::string mName;
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
#include "player.hpp"
|
||||
#include "renderconst.hpp"
|
||||
|
||||
using namespace Ogre;
|
||||
|
|
|
@ -39,8 +39,6 @@ namespace MWWorld
|
|||
|
||||
namespace MWRender
|
||||
{
|
||||
class Player;
|
||||
|
||||
class Debugging
|
||||
{
|
||||
OEngine::Physic::PhysicEngine* mEngine;
|
||||
|
|
|
@ -178,7 +178,8 @@ void NpcAnimation::updateParts(bool forceupdate)
|
|||
{ &NpcAnimation::mGloveR, MWWorld::InventoryStore::Slot_RightGauntlet, 0 },
|
||||
{ &NpcAnimation::mShirt, MWWorld::InventoryStore::Slot_Shirt, 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]);
|
||||
|
||||
|
@ -239,7 +240,7 @@ void NpcAnimation::updateParts(bool forceupdate)
|
|||
ESM::PRT_RForearm, ESM::PRT_LForearm, ESM::PRT_RPauldron, ESM::PRT_LPauldron
|
||||
};
|
||||
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);
|
||||
}
|
||||
else if(slotlist[i].mSlot == MWWorld::InventoryStore::Slot_Skirt)
|
||||
|
@ -260,29 +261,7 @@ void NpcAnimation::updateParts(bool forceupdate)
|
|||
if(mViewMode == VM_HeadOnly)
|
||||
return;
|
||||
|
||||
std::map<int, int> bodypartMap;
|
||||
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();
|
||||
showWeapons(mShowWeapons);
|
||||
|
||||
const int Flag_Female = 0x01;
|
||||
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);
|
||||
if (sRaceMapping.find(thisCombination) == sRaceMapping.end())
|
||||
{
|
||||
sRaceMapping[thisCombination].resize(ESM::PRT_Count);
|
||||
for (int i=0; i<ESM::PRT_Count; ++i)
|
||||
sRaceMapping[thisCombination][i] = NULL;
|
||||
static std::map<int, int> bodypartMap;
|
||||
if(bodypartMap.size() == 0)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
sRaceMapping[thisCombination].resize(ESM::PRT_Count, NULL);
|
||||
|
||||
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)
|
||||
for(MWWorld::Store<ESM::BodyPart>::iterator it = partStore.begin(); it != partStore.end(); ++it)
|
||||
{
|
||||
const ESM::BodyPart& bodypart = *it;
|
||||
if (bodypart.mData.mFlags & ESM::BodyPart::BPF_NotPlayable)
|
||||
continue;
|
||||
if (bodypart.mData.mType != ESM::BodyPart::MT_Skin)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!mNpc->isMale() != (bodypart.mData.mFlags & ESM::BodyPart::BPF_Female))
|
||||
continue;
|
||||
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
|
||||
{
|
||||
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
|
||||
|
|
|
@ -49,12 +49,14 @@ using namespace Ogre;
|
|||
|
||||
namespace MWRender {
|
||||
|
||||
RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir,
|
||||
const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine,MWWorld::Fallback* fallback)
|
||||
RenderingManager::RenderingManager(OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir,
|
||||
const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine,
|
||||
MWWorld::Fallback* fallback)
|
||||
: mRendering(_rend)
|
||||
, mFallback(fallback)
|
||||
, mObjects(mRendering,mFallback)
|
||||
, mObjects(mRendering, mFallback)
|
||||
, mActors(mRendering, this)
|
||||
, mPlayerAnimation(NULL)
|
||||
, mAmbientMode(0)
|
||||
, mSunEnabled(0)
|
||||
, mPhysicsEngine(engine)
|
||||
|
@ -148,14 +150,13 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
|
|||
|
||||
applyCompositors();
|
||||
|
||||
SceneNode *rt = mRendering.getScene()->getRootSceneNode();
|
||||
mRootNode = rt;
|
||||
mRootNode = mRendering.getScene()->getRootSceneNode();
|
||||
mRootNode->createChildSceneNode("player");
|
||||
|
||||
mObjects.setRootNode(mRootNode);
|
||||
mActors.setRootNode(mRootNode);
|
||||
|
||||
Ogre::SceneNode *playerNode = mRootNode->createChildSceneNode ("player");
|
||||
mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode);
|
||||
mCamera = new MWRender::Camera(mRendering.getCamera());
|
||||
|
||||
mShadows = new Shadows(&mRendering);
|
||||
|
||||
|
@ -183,7 +184,8 @@ RenderingManager::~RenderingManager ()
|
|||
mRendering.getWindow()->removeListener(this);
|
||||
mRendering.removeWindowEventListener(this);
|
||||
|
||||
delete mPlayer;
|
||||
delete mPlayerAnimation;
|
||||
delete mCamera;
|
||||
delete mSkyManager;
|
||||
delete mDebugging;
|
||||
delete mShadows;
|
||||
|
@ -264,37 +266,20 @@ void RenderingManager::scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3
|
|||
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;
|
||||
bool isPlayer = isActive && ptr.getRefData().getHandle() == "player";
|
||||
bool force = true;
|
||||
Ogre::Vector3 rot(ptr.getRefData().getPosition().rot);
|
||||
|
||||
if (isPlayer)
|
||||
force = mPlayer->rotate(rot, adjust);
|
||||
if(ptr.getRefData().getHandle() == mCamera->getHandle() &&
|
||||
!mCamera->isVanityOrPreviewModeEnabled())
|
||||
mCamera->rotateCamera(rot, false);
|
||||
|
||||
MWWorld::Class::get(ptr).adjustRotation(ptr, rot.x, rot.y, rot.z);
|
||||
if (!isPlayer && isActive)
|
||||
{
|
||||
if(adjust)
|
||||
{
|
||||
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.z), Ogre::Vector3::UNIT_Z);
|
||||
if(!MWWorld::Class::get(ptr).isActor())
|
||||
newo = Ogre::Quaternion(Ogre::Radian(-rot.x), Ogre::Vector3::UNIT_X) *
|
||||
Ogre::Quaternion(Ogre::Radian(-rot.y), Ogre::Vector3::UNIT_Y) * newo;
|
||||
|
||||
Ogre::Quaternion newo = Ogre::Quaternion(Ogre::Radian(-rot.x), Ogre::Vector3::UNIT_X) *
|
||||
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;
|
||||
ptr.getRefData().getBaseNode()->setOrientation(newo);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -317,7 +302,7 @@ void RenderingManager::update (float duration, bool paused)
|
|||
{
|
||||
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;
|
||||
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 orig, dest;
|
||||
mPlayer->setCameraDistance();
|
||||
if (!mPlayer->getPosition(orig, dest)) {
|
||||
orig.z += mPlayer->getHeight() * mRootNode->getScale().z;
|
||||
mCamera->setCameraDistance();
|
||||
if(!mCamera->getPosition(orig, dest))
|
||||
{
|
||||
orig.z += mCamera->getHeight() * mRootNode->getScale().z;
|
||||
|
||||
btVector3 btOrig(orig.x, orig.y, orig.z);
|
||||
btVector3 btDest(dest.x, dest.y, dest.z);
|
||||
std::pair<std::string, float> test =
|
||||
mPhysicsEngine->rayTest(btOrig, btDest);
|
||||
std::pair<std::string,float> test = mPhysicsEngine->rayTest(btOrig, btDest);
|
||||
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();
|
||||
|
||||
applyFog(world->isUnderwater (world->getPlayer().getPlayer().getCell(), cam));
|
||||
applyFog(world->isUnderwater(player.getCell(), cam));
|
||||
|
||||
if(paused)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mPlayer->update(duration);
|
||||
mCamera->update(duration);
|
||||
|
||||
mActors.update (duration);
|
||||
mObjects.update (duration);
|
||||
|
@ -371,18 +354,11 @@ void RenderingManager::update (float duration, bool paused)
|
|||
mSkyManager->setGlare(mOcclusionQuery->getSunVisibility());
|
||||
|
||||
Ogre::SceneNode *node = data.getBaseNode();
|
||||
//Ogre::Quaternion orient =
|
||||
//node->convertLocalToWorldOrientation(node->_getDerivedOrientation());
|
||||
Ogre::Quaternion orient =
|
||||
node->_getDerivedOrientation();
|
||||
Ogre::Quaternion orient = node->_getDerivedOrientation();
|
||||
|
||||
mLocalMap->updatePlayer(playerPos, orient);
|
||||
|
||||
mWater->updateUnderwater(
|
||||
world->isUnderwater(
|
||||
world->getPlayer().getPlayer().getCell(),
|
||||
cam)
|
||||
);
|
||||
mWater->updateUnderwater(world->isUnderwater(player.getCell(), cam));
|
||||
|
||||
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)
|
||||
{
|
||||
MWRender::NpcAnimation *anim =
|
||||
new MWRender::NpcAnimation(
|
||||
ptr, ptr.getRefData ().getBaseNode (),
|
||||
MWWorld::Class::get(ptr).getInventoryStore(ptr), RV_Actors
|
||||
);
|
||||
mPlayer->setAnimation(anim);
|
||||
mWater->removeEmitter (ptr);
|
||||
mWater->addEmitter (ptr);
|
||||
if(!mPlayerAnimation)
|
||||
{
|
||||
mPlayerAnimation = new NpcAnimation(ptr, ptr.getRefData().getBaseNode(),
|
||||
MWWorld::Class::get(ptr).getInventoryStore(ptr),
|
||||
RV_Actors);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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
|
||||
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.z += mPlayer->getHeight();
|
||||
mPlayer->getSightAngles(pitch, yaw);
|
||||
eyepos = mCamera->getPosition();
|
||||
eyepos.z += mCamera->getHeight();
|
||||
mCamera->getSightAngles(pitch, yaw);
|
||||
}
|
||||
|
||||
bool RenderingManager::vanityRotateCamera(float* rot)
|
||||
bool RenderingManager::vanityRotateCamera(const float *rot)
|
||||
{
|
||||
if(!mPlayer->isVanityOrPreviewModeEnabled())
|
||||
if(!mCamera->isVanityOrPreviewModeEnabled())
|
||||
return false;
|
||||
|
||||
Ogre::Vector3 vRot(rot);
|
||||
mPlayer->rotateCamera(vRot, true);
|
||||
mCamera->rotateCamera(vRot, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -931,7 +917,7 @@ Animation* RenderingManager::getAnimation(const MWWorld::Ptr &ptr)
|
|||
{
|
||||
Animation *anim = mActors.getAnimation(ptr);
|
||||
if(!anim && ptr.getRefData().getHandle() == "player")
|
||||
anim = mPlayer->getAnimation();
|
||||
anim = mPlayerAnimation;
|
||||
return anim;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
#include "objects.hpp"
|
||||
#include "actors.hpp"
|
||||
#include "player.hpp"
|
||||
#include "camera.hpp"
|
||||
#include "occlusionquery.hpp"
|
||||
|
||||
namespace Ogre
|
||||
|
@ -50,49 +50,44 @@ namespace MWRender
|
|||
class VideoPlayer;
|
||||
class Animation;
|
||||
|
||||
class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener, public Ogre::RenderTargetListener {
|
||||
|
||||
private:
|
||||
|
||||
|
||||
class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener, public Ogre::RenderTargetListener
|
||||
{
|
||||
private:
|
||||
virtual MWRender::Objects& getObjects();
|
||||
virtual MWRender::Actors& getActors();
|
||||
|
||||
public:
|
||||
public:
|
||||
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();
|
||||
|
||||
void togglePOV() {
|
||||
mPlayer->toggleViewMode();
|
||||
void togglePOV()
|
||||
{ mCamera->toggleViewMode(); }
|
||||
|
||||
void togglePreviewMode(bool enable)
|
||||
{ mCamera->togglePreviewMode(enable); }
|
||||
|
||||
bool toggleVanityMode(bool enable)
|
||||
{ return mCamera->toggleVanityMode(enable); }
|
||||
|
||||
void allowVanityMode(bool allow)
|
||||
{ mCamera->allowVanityMode(allow); }
|
||||
|
||||
void togglePlayerLooking(bool enable)
|
||||
{ mCamera->togglePlayerLooking(enable); }
|
||||
|
||||
void changeVanityModeScale(float factor)
|
||||
{
|
||||
if(mCamera->isVanityOrPreviewModeEnabled())
|
||||
mCamera->setCameraDistance(-factor/120.f*10, true, true);
|
||||
}
|
||||
|
||||
void togglePreviewMode(bool enable) {
|
||||
mPlayer->togglePreviewMode(enable);
|
||||
}
|
||||
bool vanityRotateCamera(const float *rot);
|
||||
|
||||
bool toggleVanityMode(bool enable, bool force) {
|
||||
return mPlayer->toggleVanityMode(enable, force);
|
||||
}
|
||||
void getCameraData(Ogre::Vector3 &eyepos, float &pitch, float &yaw);
|
||||
|
||||
void allowVanityMode(bool allow) {
|
||||
mPlayer->allowVanityMode(allow);
|
||||
}
|
||||
|
||||
void togglePlayerLooking(bool enable) {
|
||||
mPlayer->togglePlayerLooking(enable);
|
||||
}
|
||||
|
||||
void changeVanityModeScale(float factor) {
|
||||
if (mPlayer->isVanityOrPreviewModeEnabled())
|
||||
mPlayer->setCameraDistance(-factor/120.f*10, true, true);
|
||||
}
|
||||
|
||||
bool vanityRotateCamera(float* rot);
|
||||
|
||||
void getPlayerData(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);
|
||||
|
||||
SkyManager* getSkyManager();
|
||||
|
@ -121,11 +116,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
|
|||
void moveObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& position);
|
||||
void scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& scale);
|
||||
|
||||
/// Rotates object accordingly to its type
|
||||
/// \param rot euler angles in radians
|
||||
/// \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);
|
||||
/// Updates an object's rotation
|
||||
void rotateObject (const MWWorld::Ptr& ptr);
|
||||
|
||||
void setWaterHeight(const float height);
|
||||
void toggleWater();
|
||||
|
@ -207,12 +199,11 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
|
|||
void stopVideo();
|
||||
void frameStarted(float dt);
|
||||
|
||||
protected:
|
||||
virtual void windowResized(Ogre::RenderWindow* rw);
|
||||
protected:
|
||||
virtual void windowResized(Ogre::RenderWindow* rw);
|
||||
virtual void windowClosed(Ogre::RenderWindow* rw);
|
||||
|
||||
private:
|
||||
|
||||
private:
|
||||
sh::Factory* mFactory;
|
||||
|
||||
void setAmbientMode();
|
||||
|
@ -241,6 +232,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
|
|||
MWRender::Objects mObjects;
|
||||
MWRender::Actors mActors;
|
||||
|
||||
MWRender::NpcAnimation *mPlayerAnimation;
|
||||
|
||||
// 0 normal, 1 more bright, 2 max
|
||||
int mAmbientMode;
|
||||
|
||||
|
@ -255,7 +248,7 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
|
|||
|
||||
OEngine::Physic::PhysicEngine* mPhysicsEngine;
|
||||
|
||||
MWRender::Player *mPlayer;
|
||||
MWRender::Camera *mCamera;
|
||||
|
||||
MWRender::Debugging *mDebugging;
|
||||
|
||||
|
|
|
@ -205,7 +205,7 @@ unsigned int Moon::getPhaseInt() const
|
|||
return 0;
|
||||
}
|
||||
|
||||
SkyManager::SkyManager (SceneNode* root, Camera* pCamera)
|
||||
SkyManager::SkyManager(Ogre::SceneNode *root, Ogre::Camera *pCamera)
|
||||
: mHour(0.0f)
|
||||
, mDay(0)
|
||||
, mMonth(0)
|
||||
|
|
|
@ -282,10 +282,8 @@ namespace MWScript
|
|||
MWBase::World *world =
|
||||
MWBase::Environment::get().getWorld();
|
||||
|
||||
if (world->toggleVanityMode(sActivate, true)) {
|
||||
context.report(
|
||||
(sActivate) ? "Vanity Mode -> On" : "Vanity Mode -> Off"
|
||||
);
|
||||
if (world->toggleVanityMode(sActivate)) {
|
||||
context.report(sActivate ? "Vanity Mode -> On" : "Vanity Mode -> Off");
|
||||
sActivate = !sActivate;
|
||||
} else {
|
||||
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?
|
||||
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[0]), Ogre::Vector3::UNIT_X)) *
|
||||
Ogre::Quaternion(Ogre::Radian( refpos.rot[0]), Ogre::Vector3::UNIT_X)) *
|
||||
movement;
|
||||
}
|
||||
|
||||
|
@ -160,7 +160,7 @@ namespace MWWorld
|
|||
{
|
||||
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[0]), Ogre::Vector3::UNIT_X)) *
|
||||
Ogre::Quaternion(Ogre::Radian( refpos.rot[0]), Ogre::Vector3::UNIT_X)) *
|
||||
movement / time;
|
||||
}
|
||||
else
|
||||
|
@ -260,14 +260,13 @@ namespace MWWorld
|
|||
std::pair<float, std::string> PhysicsSystem::getFacedHandle (MWWorld::World& world, float queryDistance)
|
||||
{
|
||||
btVector3 dir(0, 1, 0);
|
||||
dir = dir.rotate(btVector3(1, 0, 0), mPlayerData.pitch);
|
||||
dir = dir.rotate(btVector3(0, 0, 1), mPlayerData.yaw);
|
||||
dir = dir.rotate(btVector3(1, 0, 0), mCameraData.pitch);
|
||||
dir = dir.rotate(btVector3(0, 0, 1), mCameraData.yaw);
|
||||
dir.setX(-dir.x());
|
||||
|
||||
btVector3 origin(
|
||||
mPlayerData.eyepos.x,
|
||||
mPlayerData.eyepos.y,
|
||||
mPlayerData.eyepos.z);
|
||||
btVector3 origin(mCameraData.eyepos.x,
|
||||
mCameraData.eyepos.y,
|
||||
mCameraData.eyepos.z);
|
||||
origin += dir * 5;
|
||||
|
||||
btVector3 dest = origin + dir * queryDistance;
|
||||
|
@ -280,14 +279,13 @@ namespace MWWorld
|
|||
std::vector < std::pair <float, std::string> > PhysicsSystem::getFacedHandles (float queryDistance)
|
||||
{
|
||||
btVector3 dir(0, 1, 0);
|
||||
dir = dir.rotate(btVector3(1, 0, 0), mPlayerData.pitch);
|
||||
dir = dir.rotate(btVector3(0, 0, 1), mPlayerData.yaw);
|
||||
dir = dir.rotate(btVector3(1, 0, 0), mCameraData.pitch);
|
||||
dir = dir.rotate(btVector3(0, 0, 1), mCameraData.yaw);
|
||||
dir.setX(-dir.x());
|
||||
|
||||
btVector3 origin(
|
||||
mPlayerData.eyepos.x,
|
||||
mPlayerData.eyepos.y,
|
||||
mPlayerData.eyepos.z);
|
||||
btVector3 origin(mCameraData.eyepos.x,
|
||||
mCameraData.eyepos.y,
|
||||
mCameraData.eyepos.z);
|
||||
origin += dir * 5;
|
||||
|
||||
btVector3 dest = origin + dir * queryDistance;
|
||||
|
@ -552,10 +550,10 @@ namespace MWWorld
|
|||
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;
|
||||
mPlayerData.pitch = pitch;
|
||||
mPlayerData.yaw = yaw;
|
||||
mCameraData.eyepos = eyepos;
|
||||
mCameraData.pitch = pitch;
|
||||
mCameraData.yaw = yaw;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,13 +77,13 @@ namespace MWWorld
|
|||
|
||||
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:
|
||||
struct {
|
||||
Ogre::Vector3 eyepos;
|
||||
float pitch, yaw;
|
||||
} mPlayerData;
|
||||
} mCameraData;
|
||||
|
||||
OEngine::Render::OgreRenderer &mRender;
|
||||
OEngine::Physic::PhysicEngine* mEngine;
|
||||
|
|
|
@ -81,10 +81,13 @@ namespace MWWorld
|
|||
{}
|
||||
}
|
||||
|
||||
std::string RefData::getHandle()
|
||||
const std::string &RefData::getHandle()
|
||||
{
|
||||
if (!mBaseNode)
|
||||
return "";
|
||||
if(!mBaseNode)
|
||||
{
|
||||
static const std::string empty;
|
||||
return empty;
|
||||
}
|
||||
|
||||
return mBaseNode->getName();
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ namespace MWWorld
|
|||
RefData& operator= (const RefData& refData);
|
||||
|
||||
/// Return OGRE handle (may be empty).
|
||||
std::string getHandle();
|
||||
const std::string &getHandle();
|
||||
|
||||
/// Return OGRE base node (can be a null pointer).
|
||||
Ogre::SceneNode* getBaseNode();
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include "../mwmechanics/movement.hpp"
|
||||
|
||||
#include "../mwrender/sky.hpp"
|
||||
#include "../mwrender/player.hpp"
|
||||
|
||||
#include "../mwclass/door.hpp"
|
||||
|
||||
|
@ -813,33 +812,50 @@ namespace MWWorld
|
|||
|
||||
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[1] = rot.y;
|
||||
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;
|
||||
|
||||
while(objRot[0]>=fullRotateRad)
|
||||
objRot[0] -= fullRotateRad;
|
||||
while(objRot[1]>=fullRotateRad)
|
||||
objRot[1] -= fullRotateRad;
|
||||
while(objRot[2]>=fullRotateRad)
|
||||
objRot[2] -= fullRotateRad;
|
||||
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)
|
||||
objRot[0] += fullRotateRad;
|
||||
while(objRot[1]<=-fullRotateRad)
|
||||
objRot[1] += fullRotateRad;
|
||||
while(objRot[2]<=-fullRotateRad)
|
||||
objRot[2] += fullRotateRad;
|
||||
while(objRot[1] < -pi) objRot[1] += two_pi;
|
||||
while(objRot[1] > pi) objRot[1] -= two_pi;
|
||||
|
||||
if (ptr.getRefData().getBaseNode() != 0) {
|
||||
mPhysics->rotateObject(ptr);
|
||||
}
|
||||
while(objRot[2] < -pi) objRot[2] += two_pi;
|
||||
while(objRot[2] > pi) objRot[2] -= two_pi;
|
||||
|
||||
if(ptr.getRefData().getBaseNode() != 0)
|
||||
{
|
||||
mRendering->rotateObject(ptr);
|
||||
mPhysics->rotateObject(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1136,8 +1152,8 @@ namespace MWWorld
|
|||
|
||||
float pitch, yaw;
|
||||
Ogre::Vector3 eyepos;
|
||||
mRendering->getPlayerData(eyepos, pitch, yaw);
|
||||
mPhysics->updatePlayerData(eyepos, pitch, yaw);
|
||||
mRendering->getCameraData(eyepos, pitch, yaw);
|
||||
mPhysics->updateCameraData(eyepos, pitch, yaw);
|
||||
|
||||
performUpdateSceneQueries ();
|
||||
|
||||
|
@ -1483,13 +1499,15 @@ namespace MWWorld
|
|||
|
||||
void World::setupPlayer()
|
||||
{
|
||||
const ESM::NPC* player = mStore.get<ESM::NPC>().find ("player");
|
||||
mPlayer = new MWWorld::Player (player, *this);
|
||||
mRendering->attachCameraTo(mPlayer->getPlayer());
|
||||
const ESM::NPC *player = mStore.get<ESM::NPC>().find("player");
|
||||
mPlayer = new MWWorld::Player(player, *this);
|
||||
|
||||
Ptr ptr = mPlayer->getPlayer();
|
||||
mRendering->setupPlayer(ptr);
|
||||
if (mNewGame)
|
||||
{
|
||||
MWWorld::Class::get(mPlayer->getPlayer()).getContainerStore(mPlayer->getPlayer()).fill(player->mInventory, "", mStore);
|
||||
MWWorld::Class::get(mPlayer->getPlayer()).getInventoryStore(mPlayer->getPlayer()).autoEquip (mPlayer->getPlayer());
|
||||
MWWorld::Class::get(ptr).getContainerStore(ptr).fill(player->mInventory, "", mStore);
|
||||
MWWorld::Class::get(ptr).getInventoryStore(ptr).autoEquip(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -355,8 +355,8 @@ namespace MWWorld
|
|||
mRendering->togglePreviewMode(enable);
|
||||
}
|
||||
|
||||
virtual bool toggleVanityMode(bool enable, bool force) {
|
||||
return mRendering->toggleVanityMode(enable, force);
|
||||
virtual bool toggleVanityMode(bool enable) {
|
||||
return mRendering->toggleVanityMode(enable);
|
||||
}
|
||||
|
||||
virtual void allowVanityMode(bool allow) {
|
||||
|
|
|
@ -207,7 +207,7 @@ struct RecordFactoryEntry {
|
|||
static const RecordFactoryEntry recordFactories [] = {
|
||||
|
||||
{ "NiNode", &construct <NiNode >, RC_NiNode },
|
||||
{ "AvoidNode", &construct <NiNode >, RC_NiNode },
|
||||
{ "AvoidNode", &construct <NiNode >, RC_AvoidNode },
|
||||
{ "NiBSParticleNode", &construct <NiNode >, RC_NiBSParticleNode },
|
||||
{ "NiBSAnimationNode", &construct <NiNode >, RC_NiBSAnimationNode },
|
||||
{ "NiBillboardNode", &construct <NiNode >, RC_NiNode },
|
||||
|
|
|
@ -36,6 +36,7 @@ enum RecordType
|
|||
{
|
||||
RC_MISSING = 0,
|
||||
RC_NiNode,
|
||||
RC_AvoidNode,
|
||||
RC_NiTriShape,
|
||||
RC_NiRotatingParticles,
|
||||
RC_NiAutoNormalParticles,
|
||||
|
|
|
@ -185,6 +185,10 @@ void ManualBulletShapeLoader::handleNode(btTriangleMesh* mesh, const Nif::Node *
|
|||
else
|
||||
isCollisionNode = isCollisionNode && (node->recType != Nif::RC_RootCollisionNode);
|
||||
|
||||
// Don't collide with AvoidNode shapes
|
||||
if(node->recType == Nif::RC_AvoidNode)
|
||||
flags |= 0x800;
|
||||
|
||||
// Marker objects
|
||||
/// \todo don't do this in the editor
|
||||
std::string nodename = node->name;
|
||||
|
|
Loading…
Reference in a new issue