1
0
Fork 1
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:
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 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
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;
}
}
}

View file

@ -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;
}
}
}
}

View file

@ -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);
};
}

View file

@ -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();

View file

@ -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();

View file

@ -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);
}
};
}