1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-20 02:53:51 +00:00

preview mode, advanced vanity support

This commit is contained in:
greye 2012-08-14 14:37:48 +04:00
parent fe1a9ac3c5
commit 6f87c0c36d
7 changed files with 169 additions and 48 deletions

View file

@ -250,6 +250,9 @@ namespace MWBase
virtual bool isUnderwater(const ESM::Cell &cell, const Ogre::Vector3 &pos) = 0; virtual bool isUnderwater(const ESM::Cell &cell, const Ogre::Vector3 &pos) = 0;
virtual void togglePOV() = 0; virtual void togglePOV() = 0;
virtual void togglePreviewMode(bool enable) = 0;
virtual bool toggleVanityMode(bool enable, bool force) = 0;
virtual void allowVanityMode(bool allow) = 0;
}; };
} }

View file

@ -406,19 +406,22 @@ private:
else else
player.setUpDown (0); player.setUpDown (0);
if (poller.isDown(A_TogglePOV)) { if (mControlSwitch["playerviewswitch"]) {
if (mPreviewPOVDelay <= 0.5 && if (poller.isDown(A_TogglePOV)) {
(mPreviewPOVDelay += duration) > 0.5) if (mPreviewPOVDelay <= 0.5 &&
{ (mPreviewPOVDelay += duration) > 0.5)
// enable preview mode {
MWBase::Environment::get().getWorld()->togglePreviewMode(true);
}
} else {
if (mPreviewPOVDelay > 0.5) {
//disable preview mode
MWBase::Environment::get().getWorld()->togglePreviewMode(false);
} else if (mPreviewPOVDelay > 0.f) {
togglePOV();
}
mPreviewPOVDelay = 0.f;
} }
} else {
if (mPreviewPOVDelay > 0.5) {
//disable preview mode
} else if (mPreviewPOVDelay > 0.f) {
togglePOV();
}
mPreviewPOVDelay = 0.f;
} }
} }
} }

View file

@ -18,28 +18,49 @@ namespace MWRender
mCameraNode(mPlayerNode->createChildSceneNode()), mCameraNode(mPlayerNode->createChildSceneNode()),
mVanityNode(mPlayerNode->createChildSceneNode()), mVanityNode(mPlayerNode->createChildSceneNode()),
mFirstPersonView(true), mFirstPersonView(true),
mVanityMode(false),
mPreviewMode(false), mPreviewMode(false),
mHeight(40.f) mHeight(40.f),
mCameraDistance(400.f)
{ {
mVanity.enabled = false;
mVanity.allowed = true;
mVanity.forced = false;
mCameraNode->attachObject(mCamera); mCameraNode->attachObject(mCamera);
mCameraNode->setPosition(0.f, 0.f, mHeight); mCameraNode->setPosition(0.f, 0.f, mHeight);
mPreviewCam.yaw = 0.f; mPreviewCam.yaw = 0.f;
mPreviewCam.offset = 600.f;
} }
bool Player::rotate(const Ogre::Vector3 &rot, bool adjust) bool Player::rotate(const Ogre::Vector3 &rot, bool adjust)
{ {
rotateCamera(rot, adjust);
mUpdates = 0; mUpdates = 0;
mTimeIdle = 0.f; mTimeIdle = 0.f;
if (mVanityMode) { if (mVanity.enabled) {
toggleVanityMode(false); toggleVanityMode(false);
} }
return !mVanityMode && !mPreviewMode; Ogre::Vector3 trueRot = rot;
/// \note rotate player on forced vanity
if (mVanity.forced) {
moveCameraNode(mPlayerNode);
mVanity.enabled = false;
rotateCamera(rot, adjust);
moveCameraNode(mVanityNode);
mVanity.enabled = true;
trueRot.z = 0.f;
}
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 Player::rotateCamera(const Ogre::Vector3 &rot, bool adjust)
@ -90,19 +111,19 @@ namespace MWRender
void Player::update(float duration) void Player::update(float duration)
{ {
if (!mVanityMode) { if (!mVanity.enabled) {
++mUpdates; ++mUpdates;
mTimeIdle += duration; mTimeIdle += duration;
if (mTimeIdle > 30.f) { if (mTimeIdle > 30.f) {
toggleVanityMode(true); toggleVanityMode(true);
} }
} }
if (mFirstPersonView && !mVanityMode) { if (mFirstPersonView && !mVanity.enabled) {
return; return;
} }
if (mVanityMode) { 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);
} }
} }
@ -113,49 +134,75 @@ namespace MWRender
if (mFirstPersonView) { if (mFirstPersonView) {
mCamera->setPosition(0.f, 0.f, 0.f); mCamera->setPosition(0.f, 0.f, 0.f);
} else { } else {
mCamera->setPosition(0.f, 0.f, 400.f); mCamera->setPosition(0.f, 0.f, mCameraDistance);
} }
} }
void Player::toggleVanityMode(bool enable, bool force) void Player::allowVanityMode(bool allow)
{ {
if (mVanityMode == enable) { if (!allow && mVanity.enabled && !mVanity.forced) {
return; toggleVanityMode(false);
} }
mVanityMode = enable; mVanity.allowed = allow;
}
bool Player::toggleVanityMode(bool enable, bool force)
{
if ((mVanity.forced && !force) ||
(!mVanity.allowed && (force || enable)))
{
return false;
} else if (mVanity.enabled == enable) {
return true;
}
mVanity.enabled = enable;
mVanity.forced = force && enable;
float offset = 300.f; float offset = 300.f;
Ogre::Vector3 rot(0.f, 0.f, 0.f); Ogre::Vector3 rot(0.f, 0.f, 0.f);
if (mVanityMode) { if (mVanity.enabled) {
rot.x = Ogre::Degree(-30.f).valueRadians(); rot.x = Ogre::Degree(-30.f).valueRadians();
mMainCam.offset = mCamera->getPosition().z; mMainCam.offset = mCamera->getPosition().z;
mPlayerNode->removeChild(mCameraNode); moveCameraNode(mVanityNode);
mVanityNode->addChild(mCameraNode);
} else { } else {
rot.x = getPitch(); rot.x = getPitch();
offset = mMainCam.offset; offset = mMainCam.offset;
mVanityNode->removeChild(mCameraNode); moveCameraNode(mPlayerNode);
mPlayerNode->addChild(mCameraNode);
} }
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;
} }
void Player::togglePreviewMode(bool enable) void Player::togglePreviewMode(bool enable)
{ {
/// \todo move camera
if (mPreviewMode == enable) { if (mPreviewMode == enable) {
return; return;
} }
mPreviewMode = enable; mPreviewMode = enable;
float offset = mCamera->getPosition().z;
if (mPreviewMode) {
mMainCam.offset = offset;
offset = mPreviewCam.offset;
moveCameraNode(mVanityNode);
} else {
mPreviewCam.offset = offset;
offset = mMainCam.offset;
moveCameraNode(mPlayerNode);
}
mCamera->setPosition(0.f, 0.f, mPreviewCam.offset);
rotateCamera(Ogre::Vector3(getPitch(), 0.f, getYaw()), false);
} }
float Player::getYaw() float Player::getYaw()
{ {
if (mVanityMode || mPreviewMode) { if (mVanity.enabled || mPreviewMode) {
return mPreviewCam.yaw; return mPreviewCam.yaw;
} }
return mMainCam.yaw; return mMainCam.yaw;
@ -168,7 +215,7 @@ namespace MWRender
} else if (angle < -Ogre::Math::PI) { } else if (angle < -Ogre::Math::PI) {
angle += Ogre::Math::TWO_PI; angle += Ogre::Math::TWO_PI;
} }
if (mVanityMode || mPreviewMode) { if (mVanity.enabled || mPreviewMode) {
mPreviewCam.yaw = angle; mPreviewCam.yaw = angle;
} else { } else {
mMainCam.yaw = angle; mMainCam.yaw = angle;
@ -177,23 +224,59 @@ namespace MWRender
float Player::getPitch() float Player::getPitch()
{ {
if (mVanityMode || mPreviewMode) { if (mVanity.enabled || mPreviewMode) {
return mPreviewCam.pitch; return mPreviewCam.pitch;
} }
return mMainCam.pitch; return mMainCam.pitch;
} }
void Player::setPitch(float angle) void Player::setPitch(float angle)
{ {
if (angle > Ogre::Math::HALF_PI) { float limit = Ogre::Math::HALF_PI;
angle = Ogre::Math::HALF_PI - 0.01; if (mVanity.forced || mPreviewMode) {
} else if (angle < -Ogre::Math::HALF_PI) { limit /= 2;
angle = -Ogre::Math::HALF_PI + 0.01;
} }
if (mVanityMode || mPreviewMode) { if (angle > limit) {
angle = limit - 0.01;
} else if (angle < -limit) {
angle = -limit + 0.01;
}
if (mVanity.enabled || mPreviewMode) {
mPreviewCam.pitch = angle; mPreviewCam.pitch = angle;
} else { } else {
mMainCam.pitch = angle; mMainCam.pitch = angle;
} }
} }
void Player::moveCameraNode(Ogre::SceneNode *node)
{
mCameraNode->getParentSceneNode()->removeChild(mCameraNode);
node->addChild(mCameraNode);
}
void Player::setCameraDistance(float dist, bool adjust)
{
/// \note non-Morrowind feature: allow to change camera distance
/// int 3d-person mode
/// \todo review and simplify condition if possible
if (mPreviewMode ||
mVanity.forced ||
(!mVanity.enabled && !mFirstPersonView))
{
Ogre::Vector3 v(0.f, 0.f, dist);
if (adjust) {
v += mCamera->getPosition();
}
if (v.z > 800.f) {
v.z = 800.f;
} else if (v.z < 100.f) {
v.z = 100.f;
}
mCamera->setPosition(v);
if (!mVanity.enabled && !mFirstPersonView) {
mCameraDistance = v.z;
}
}
}
} }

View file

@ -31,10 +31,13 @@ namespace MWRender
Ogre::SceneNode *mVanityNode; Ogre::SceneNode *mVanityNode;
bool mFirstPersonView; bool mFirstPersonView;
bool mVanityMode;
bool mPreviewMode; bool mPreviewMode;
float mHeight; struct {
bool enabled, allowed, forced;
} mVanity;
float mHeight, mCameraDistance;
CamData mMainCam, mPreviewCam; CamData mMainCam, mPreviewCam;
float mTimeIdle; float mTimeIdle;
@ -51,6 +54,8 @@ namespace MWRender
float getPitch(); float getPitch();
void setPitch(float angle); void setPitch(float angle);
void moveCameraNode(Ogre::SceneNode *node);
public: public:
Player (Ogre::Camera *camera, Ogre::SceneNode* mNode); Player (Ogre::Camera *camera, Ogre::SceneNode* mNode);
@ -69,11 +74,14 @@ namespace MWRender
void toggleViewMode(); void toggleViewMode();
void toggleVanityMode(bool enable, bool force = false); bool toggleVanityMode(bool enable, bool force = false);
void allowVanityMode(bool allow);
void togglePreviewMode(bool enable); void togglePreviewMode(bool enable);
void update(float duration); void update(float duration);
void setCameraDistance(float dist, bool adjust = false);
}; };
} }

View file

@ -318,13 +318,13 @@ void RenderingManager::update (float duration){
float *fpos = data.getPosition().pos; float *fpos = data.getPosition().pos;
/// \note only for LocalMap::updatePlayer() /// \note only for LocalMap::updatePlayer()
Ogre::Vector3 pos(fpos[0], -fpos[2], fpos[1]); Ogre::Vector3 pos(fpos[0], -fpos[2], -fpos[1]);
Ogre::SceneNode *node = data.getBaseNode(); Ogre::SceneNode *node = data.getBaseNode();
Ogre::Quaternion orient = Ogre::Quaternion orient =
node->convertLocalToWorldOrientation(node->_getDerivedOrientation()); node->convertLocalToWorldOrientation(node->_getDerivedOrientation());
mLocalMap->updatePlayer(mRendering.getCamera()->getRealPosition(), orient); mLocalMap->updatePlayer(pos, orient);
if (mWater) { if (mWater) {
Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition(); Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition();

View file

@ -60,6 +60,18 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
mPlayer->toggleViewMode(); mPlayer->toggleViewMode();
} }
void togglePreviewMode(bool enable) {
mPlayer->togglePreviewMode(enable);
}
virtual bool toggleVanityMode(bool enable, bool force) {
return mPlayer->toggleVanityMode(enable, force);
}
virtual void allowVanityMode(bool allow) {
mPlayer->allowVanityMode(allow);
}
void attachCameraTo(const MWWorld::Ptr &ptr); void attachCameraTo(const MWWorld::Ptr &ptr);
SkyManager* getSkyManager(); SkyManager* getSkyManager();

View file

@ -280,6 +280,18 @@ namespace MWWorld
virtual void togglePOV() { virtual void togglePOV() {
mRendering->togglePOV(); mRendering->togglePOV();
} }
virtual void togglePreviewMode(bool enable) {
mRendering->togglePreviewMode(enable);
}
virtual bool toggleVanityMode(bool enable, bool force) {
return mRendering->toggleVanityMode(enable, force);
}
virtual void allowVanityMode(bool allow) {
mRendering->allowVanityMode(allow);
}
}; };
} }