forked from mirror/openmw-tes3mp
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})
|
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)
|
void Camera::rotateCamera(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)
|
|
||||||
{
|
{
|
||||||
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) ||
|
|
||||||
(!mVanity.allowed && (force || enable)))
|
|
||||||
{
|
{
|
||||||
|
if(!mVanity.allowed && enable)
|
||||||
return false;
|
return false;
|
||||||
} else if (mVanity.enabled == enable) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
mVanity.enabled = enable;
|
|
||||||
mVanity.forced = force && enable;
|
|
||||||
|
|
||||||
mAnimation->setViewMode((mVanity.enabled || mPreviewMode || !mFirstPersonView) ?
|
if(mVanity.enabled == enable)
|
||||||
NpcAnimation::VM_Normal : NpcAnimation::VM_FirstPerson);
|
return true;
|
||||||
|
mVanity.enabled = enable;
|
||||||
|
|
||||||
|
mAnimation->setViewMode(isFirstPerson() ? 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,7 +261,26 @@ void NpcAnimation::updateParts(bool forceupdate)
|
||||||
if(mViewMode == VM_HeadOnly)
|
if(mViewMode == VM_HeadOnly)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::map<int, int> bodypartMap;
|
showWeapons(mShowWeapons);
|
||||||
|
|
||||||
|
const int Flag_Female = 0x01;
|
||||||
|
const int Flag_FirstPerson = 0x02;
|
||||||
|
|
||||||
|
int flags = 0;
|
||||||
|
if (!mNpc->isMale())
|
||||||
|
flags |= Flag_Female;
|
||||||
|
if (mViewMode == VM_FirstPerson)
|
||||||
|
flags |= Flag_FirstPerson;
|
||||||
|
|
||||||
|
// Remember body parts so we only have to search through the store once for each race/gender/viewmode combination
|
||||||
|
static std::map< std::pair<std::string, int> , std::vector<const ESM::BodyPart*> > sRaceMapping;
|
||||||
|
std::string race = Misc::StringUtils::lowerCase(mNpc->mRace);
|
||||||
|
std::pair<std::string, int> thisCombination = std::make_pair(race, flags);
|
||||||
|
if (sRaceMapping.find(thisCombination) == sRaceMapping.end())
|
||||||
|
{
|
||||||
|
static std::map<int, int> bodypartMap;
|
||||||
|
if(bodypartMap.size() == 0)
|
||||||
|
{
|
||||||
bodypartMap[ESM::PRT_Neck] = ESM::BodyPart::MP_Neck;
|
bodypartMap[ESM::PRT_Neck] = ESM::BodyPart::MP_Neck;
|
||||||
bodypartMap[ESM::PRT_Cuirass] = ESM::BodyPart::MP_Chest;
|
bodypartMap[ESM::PRT_Cuirass] = ESM::BodyPart::MP_Chest;
|
||||||
bodypartMap[ESM::PRT_Groin] = ESM::BodyPart::MP_Groin;
|
bodypartMap[ESM::PRT_Groin] = ESM::BodyPart::MP_Groin;
|
||||||
|
@ -281,39 +301,20 @@ void NpcAnimation::updateParts(bool forceupdate)
|
||||||
bodypartMap[ESM::PRT_RLeg] = ESM::BodyPart::MP_Upperleg;
|
bodypartMap[ESM::PRT_RLeg] = ESM::BodyPart::MP_Upperleg;
|
||||||
bodypartMap[ESM::PRT_LLeg] = ESM::BodyPart::MP_Upperleg;
|
bodypartMap[ESM::PRT_LLeg] = ESM::BodyPart::MP_Upperleg;
|
||||||
bodypartMap[ESM::PRT_Tail] = ESM::BodyPart::MP_Tail;
|
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::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
|
||||||
|
|
||||||
const int Flag_Female = 0x01;
|
|
||||||
const int Flag_FirstPerson = 0x02;
|
|
||||||
|
|
||||||
int flags = 0;
|
|
||||||
if (!mNpc->isMale())
|
|
||||||
flags |= Flag_Female;
|
|
||||||
if (mViewMode == VM_FirstPerson)
|
|
||||||
flags |= Flag_FirstPerson;
|
|
||||||
|
|
||||||
// Remember body parts so we only have to search through the store once for each race/gender/viewmode combination
|
|
||||||
static std::map< std::pair<std::string, int> , std::vector<const ESM::BodyPart*> > sRaceMapping;
|
|
||||||
std::string race = Misc::StringUtils::lowerCase(mNpc->mRace);
|
|
||||||
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;
|
|
||||||
|
|
||||||
const MWWorld::Store<ESM::BodyPart> &partStore = store.get<ESM::BodyPart>();
|
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;
|
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) *
|
|
||||||
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);
|
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)
|
||||||
|
{ 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) {
|
bool vanityRotateCamera(const float *rot);
|
||||||
mPlayer->togglePreviewMode(enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool toggleVanityMode(bool enable, bool force) {
|
void getCameraData(Ogre::Vector3 &eyepos, float &pitch, float &yaw);
|
||||||
return mPlayer->toggleVanityMode(enable, force);
|
|
||||||
}
|
|
||||||
|
|
||||||
void allowVanityMode(bool allow) {
|
void setupPlayer(const MWWorld::Ptr &ptr);
|
||||||
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 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;
|
||||||
// rotate physically iff renderer confirm so
|
|
||||||
float *objRot = ptr.getRefData().getPosition().rot;
|
float *objRot = ptr.getRefData().getPosition().rot;
|
||||||
|
if(adjust)
|
||||||
|
{
|
||||||
|
objRot[0] += rot.x;
|
||||||
|
objRot[1] += rot.y;
|
||||||
|
objRot[2] += rot.z;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
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();
|
|
||||||
|
|
||||||
while(objRot[0]>=fullRotateRad)
|
|
||||||
objRot[0] -= fullRotateRad;
|
|
||||||
while(objRot[1]>=fullRotateRad)
|
|
||||||
objRot[1] -= fullRotateRad;
|
|
||||||
while(objRot[2]>=fullRotateRad)
|
|
||||||
objRot[2] -= fullRotateRad;
|
|
||||||
|
|
||||||
while(objRot[0]<=-fullRotateRad)
|
|
||||||
objRot[0] += fullRotateRad;
|
|
||||||
while(objRot[1]<=-fullRotateRad)
|
|
||||||
objRot[1] += fullRotateRad;
|
|
||||||
while(objRot[2]<=-fullRotateRad)
|
|
||||||
objRot[2] += fullRotateRad;
|
|
||||||
|
|
||||||
if (ptr.getRefData().getBaseNode() != 0) {
|
|
||||||
mPhysics->rotateObject(ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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[1] < -pi) objRot[1] += two_pi;
|
||||||
|
while(objRot[1] > pi) objRot[1] -= two_pi;
|
||||||
|
|
||||||
|
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;
|
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…
Reference in a new issue