mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 20:53:50 +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 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
|
||||
player.setUpDown (0);
|
||||
|
||||
if (poller.isDown(A_TogglePOV)) {
|
||||
if (mPreviewPOVDelay <= 0.5 &&
|
||||
(mPreviewPOVDelay += duration) > 0.5)
|
||||
{
|
||||
// enable preview mode
|
||||
if (mControlSwitch["playerviewswitch"]) {
|
||||
if (poller.isDown(A_TogglePOV)) {
|
||||
if (mPreviewPOVDelay <= 0.5 &&
|
||||
(mPreviewPOVDelay += duration) > 0.5)
|
||||
{
|
||||
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()),
|
||||
mVanityNode(mPlayerNode->createChildSceneNode()),
|
||||
mFirstPersonView(true),
|
||||
mVanityMode(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->setPosition(0.f, 0.f, mHeight);
|
||||
|
||||
mPreviewCam.yaw = 0.f;
|
||||
mPreviewCam.offset = 600.f;
|
||||
}
|
||||
|
||||
bool Player::rotate(const Ogre::Vector3 &rot, bool adjust)
|
||||
{
|
||||
rotateCamera(rot, adjust);
|
||||
|
||||
mUpdates = 0;
|
||||
mTimeIdle = 0.f;
|
||||
|
||||
if (mVanityMode) {
|
||||
if (mVanity.enabled) {
|
||||
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)
|
||||
|
@ -90,19 +111,19 @@ namespace MWRender
|
|||
|
||||
void Player::update(float duration)
|
||||
{
|
||||
if (!mVanityMode) {
|
||||
if (!mVanity.enabled) {
|
||||
++mUpdates;
|
||||
mTimeIdle += duration;
|
||||
if (mTimeIdle > 30.f) {
|
||||
toggleVanityMode(true);
|
||||
}
|
||||
}
|
||||
if (mFirstPersonView && !mVanityMode) {
|
||||
if (mFirstPersonView && !mVanity.enabled) {
|
||||
return;
|
||||
}
|
||||
if (mVanityMode) {
|
||||
if (mVanity.enabled) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -113,49 +134,75 @@ namespace MWRender
|
|||
if (mFirstPersonView) {
|
||||
mCamera->setPosition(0.f, 0.f, 0.f);
|
||||
} 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) {
|
||||
return;
|
||||
if (!allow && mVanity.enabled && !mVanity.forced) {
|
||||
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;
|
||||
Ogre::Vector3 rot(0.f, 0.f, 0.f);
|
||||
if (mVanityMode) {
|
||||
if (mVanity.enabled) {
|
||||
rot.x = Ogre::Degree(-30.f).valueRadians();
|
||||
mMainCam.offset = mCamera->getPosition().z;
|
||||
|
||||
mPlayerNode->removeChild(mCameraNode);
|
||||
mVanityNode->addChild(mCameraNode);
|
||||
moveCameraNode(mVanityNode);
|
||||
} else {
|
||||
rot.x = getPitch();
|
||||
offset = mMainCam.offset;
|
||||
|
||||
mVanityNode->removeChild(mCameraNode);
|
||||
mPlayerNode->addChild(mCameraNode);
|
||||
moveCameraNode(mPlayerNode);
|
||||
}
|
||||
rot.z = getYaw();
|
||||
mCamera->setPosition(0.f, 0.f, offset);
|
||||
rotateCamera(rot, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Player::togglePreviewMode(bool enable)
|
||||
{
|
||||
/// \todo move camera
|
||||
if (mPreviewMode == enable) {
|
||||
return;
|
||||
}
|
||||
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()
|
||||
{
|
||||
if (mVanityMode || mPreviewMode) {
|
||||
if (mVanity.enabled || mPreviewMode) {
|
||||
return mPreviewCam.yaw;
|
||||
}
|
||||
return mMainCam.yaw;
|
||||
|
@ -168,7 +215,7 @@ namespace MWRender
|
|||
} else if (angle < -Ogre::Math::PI) {
|
||||
angle += Ogre::Math::TWO_PI;
|
||||
}
|
||||
if (mVanityMode || mPreviewMode) {
|
||||
if (mVanity.enabled || mPreviewMode) {
|
||||
mPreviewCam.yaw = angle;
|
||||
} else {
|
||||
mMainCam.yaw = angle;
|
||||
|
@ -177,23 +224,59 @@ namespace MWRender
|
|||
|
||||
float Player::getPitch()
|
||||
{
|
||||
if (mVanityMode || mPreviewMode) {
|
||||
if (mVanity.enabled || mPreviewMode) {
|
||||
return mPreviewCam.pitch;
|
||||
}
|
||||
return mMainCam.pitch;
|
||||
}
|
||||
|
||||
void Player::setPitch(float angle)
|
||||
{
|
||||
if (angle > Ogre::Math::HALF_PI) {
|
||||
angle = Ogre::Math::HALF_PI - 0.01;
|
||||
} else if (angle < -Ogre::Math::HALF_PI) {
|
||||
angle = -Ogre::Math::HALF_PI + 0.01;
|
||||
{
|
||||
float limit = Ogre::Math::HALF_PI;
|
||||
if (mVanity.forced || mPreviewMode) {
|
||||
limit /= 2;
|
||||
}
|
||||
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;
|
||||
} else {
|
||||
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;
|
||||
|
||||
bool mFirstPersonView;
|
||||
bool mVanityMode;
|
||||
bool mPreviewMode;
|
||||
|
||||
float mHeight;
|
||||
struct {
|
||||
bool enabled, allowed, forced;
|
||||
} mVanity;
|
||||
|
||||
float mHeight, mCameraDistance;
|
||||
CamData mMainCam, mPreviewCam;
|
||||
|
||||
float mTimeIdle;
|
||||
|
@ -51,6 +54,8 @@ namespace MWRender
|
|||
float getPitch();
|
||||
void setPitch(float angle);
|
||||
|
||||
void moveCameraNode(Ogre::SceneNode *node);
|
||||
|
||||
public:
|
||||
|
||||
Player (Ogre::Camera *camera, Ogre::SceneNode* mNode);
|
||||
|
@ -69,11 +74,14 @@ namespace MWRender
|
|||
|
||||
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 update(float duration);
|
||||
|
||||
void setCameraDistance(float dist, bool adjust = false);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -318,13 +318,13 @@ void RenderingManager::update (float duration){
|
|||
float *fpos = data.getPosition().pos;
|
||||
|
||||
/// \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::Quaternion orient =
|
||||
node->convertLocalToWorldOrientation(node->_getDerivedOrientation());
|
||||
|
||||
mLocalMap->updatePlayer(mRendering.getCamera()->getRealPosition(), orient);
|
||||
mLocalMap->updatePlayer(pos, orient);
|
||||
|
||||
if (mWater) {
|
||||
Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition();
|
||||
|
|
|
@ -60,6 +60,18 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
|
|||
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);
|
||||
|
||||
SkyManager* getSkyManager();
|
||||
|
|
|
@ -280,6 +280,18 @@ namespace MWWorld
|
|||
virtual void 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