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:
parent
fe1a9ac3c5
commit
6f87c0c36d
7 changed files with 169 additions and 48 deletions
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue