1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-04-13 19:06:44 +00:00

poor camera with some fixes

This commit is contained in:
greye 2012-08-14 02:36:18 +04:00
parent db94018865
commit fe1a9ac3c5
6 changed files with 129 additions and 120 deletions

View file

@ -24,5 +24,5 @@ void MouseLookEvent::event(Type type, int index, const void *p)
float y = arg->state.Y.rel * sensY; float y = arg->state.Y.rel * sensY;
MWBase::World *world = MWBase::Environment::get().getWorld(); MWBase::World *world = MWBase::Environment::get().getWorld();
world->rotateObject(world->getPlayer().getPlayer(), -y, 0.f, x, true); world->rotateObject(world->getPlayer().getPlayer(), -y, 0.f, -x, true);
} }

View file

@ -290,7 +290,7 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
} }
Vector3 playerdirection = -mCameraRotNode->convertWorldToLocalOrientation(orientation).zAxis(); Vector3 playerdirection = mCameraRotNode->convertWorldToLocalOrientation(orientation).zAxis();
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);

View file

@ -16,12 +16,16 @@ namespace MWRender
: mCamera(camera), : mCamera(camera),
mPlayerNode(node), mPlayerNode(node),
mCameraNode(mPlayerNode->createChildSceneNode()), mCameraNode(mPlayerNode->createChildSceneNode()),
mVanityNode(mPlayerNode->createChildSceneNode()),
mFirstPersonView(true), mFirstPersonView(true),
mVanityMode(false), mVanityMode(false),
mPreviewMode(false) mPreviewMode(false),
mHeight(40.f)
{ {
Ogre::SceneNode *pitchNode = mCameraNode->createChildSceneNode(); mCameraNode->attachObject(mCamera);
pitchNode->attachObject(mCamera); mCameraNode->setPosition(0.f, 0.f, mHeight);
mPreviewCam.yaw = 0.f;
} }
bool Player::rotate(const Ogre::Vector3 &rot, bool adjust) bool Player::rotate(const Ogre::Vector3 &rot, bool adjust)
@ -32,7 +36,7 @@ namespace MWRender
mTimeIdle = 0.f; mTimeIdle = 0.f;
if (mVanityMode) { if (mVanityMode) {
toggleVanityMode(); toggleVanityMode(false);
} }
return !mVanityMode && !mPreviewMode; return !mVanityMode && !mPreviewMode;
@ -44,26 +48,21 @@ namespace MWRender
Ogre::SceneNode *yawNode = pitchNode->getParentSceneNode(); Ogre::SceneNode *yawNode = pitchNode->getParentSceneNode();
if (adjust) { if (adjust) {
float f = setYaw(getYaw() + rot.z);
limitPitchAngle(89.5f, Ogre::Radian(rot.x).valueDegrees()); setPitch(getPitch() + rot.x);
if (f != 0.0) {
pitchNode->pitch(Ogre::Degree(f));
}
yawNode->yaw(Ogre::Radian(-rot.z));
} else { } else {
Ogre::Radian radx(rot.x); setYaw(rot.z);
if (radx.valueDegrees() > 89.5f) { setPitch(rot.x);
radx = Ogre::Degree(89.5f);
} else if (radx.valueDegrees() < -89.5f) {
radx = Ogre::Degree(-89.5f);
} }
Ogre::Quaternion xr(radx, Ogre::Vector3::UNIT_X); Ogre::Quaternion xr(
Ogre::Quaternion yr(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Y); Ogre::Radian(getPitch() + Ogre::Math::HALF_PI),
Ogre::Vector3::UNIT_X
);
Ogre::Quaternion zr(Ogre::Radian(getYaw()), Ogre::Vector3::UNIT_Z);
pitchNode->setOrientation(xr); pitchNode->setOrientation(xr);
yawNode->setOrientation(yr); yawNode->setOrientation(zr);
}
updateListener(); updateListener();
} }
@ -77,27 +76,6 @@ namespace MWRender
ptr.getRefData().setBaseNode(mPlayerNode); ptr.getRefData().setBaseNode(mPlayerNode);
} }
float Player::limitPitchAngle(float limitAbs, float shift)
{
Ogre::Quaternion orient =
mCamera->getParentSceneNode()->getOrientation();
float pitchAngle =
(2 * Ogre::Degree(Ogre::Math::ASin(orient.x)).valueDegrees());
if (pitchAngle + shift < limitAbs && pitchAngle + shift > -limitAbs) {
return shift;
}
if (pitchAngle > 0) {
float f = limitAbs - pitchAngle - shift;
return (f > 0.f) ? f : 0.f;
} else if (pitchAngle < 0) {
float f = -limitAbs - pitchAngle - shift;
return (f < 0.f) ? f : 0.f;
}
return 0.f;
}
void Player::updateListener() void Player::updateListener()
{ {
Ogre::Vector3 pos = mCamera->getRealPosition(); Ogre::Vector3 pos = mCamera->getRealPosition();
@ -116,7 +94,7 @@ namespace MWRender
++mUpdates; ++mUpdates;
mTimeIdle += duration; mTimeIdle += duration;
if (mTimeIdle > 30.f) { if (mTimeIdle > 30.f) {
toggleVanityMode(); toggleVanityMode(true);
} }
} }
if (mFirstPersonView && !mVanityMode) { if (mFirstPersonView && !mVanityMode) {
@ -139,54 +117,83 @@ namespace MWRender
} }
} }
void Player::toggleVanityMode() void Player::toggleVanityMode(bool enable, bool force)
{ {
mVanityMode = !mVanityMode; if (mVanityMode == enable) {
return;
}
mVanityMode = 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 (mVanityMode) {
mYaw = getYawAngle();
mPitch = getPitchAngle();
mOffset = mCamera->getPosition().z;
rot.x = Ogre::Degree(-30.f).valueRadians(); rot.x = Ogre::Degree(-30.f).valueRadians();
mMainCam.offset = mCamera->getPosition().z;
mPlayerNode->removeChild(mCameraNode);
mVanityNode->addChild(mCameraNode);
} else { } else {
rot.x = Ogre::Degree(mPitch).valueRadians(); rot.x = getPitch();
rot.z = Ogre::Degree(mYaw).valueRadians(); offset = mMainCam.offset;
offset = mOffset;
mVanityNode->removeChild(mCameraNode);
mPlayerNode->addChild(mCameraNode);
} }
rot.z = getYaw();
mCamera->setPosition(0.f, 0.f, offset); mCamera->setPosition(0.f, 0.f, offset);
rotateCamera(rot, false); rotateCamera(rot, false);
} }
void Player::togglePreviewMode() void Player::togglePreviewMode(bool enable)
{ {
/// \todo move camera /// \todo move camera
mPreviewMode = !mPreviewMode; if (mPreviewMode == enable) {
return;
}
mPreviewMode = enable;
} }
float Player::getPitchAngle() float Player::getYaw()
{ {
Ogre::Quaternion orient if (mVanityMode || mPreviewMode) {
= mCamera->getParentSceneNode()->getOrientation(); return mPreviewCam.yaw;
}
float angle = return mMainCam.yaw;
(2 * Ogre::Degree(Ogre::Math::ASin(orient.x)).valueDegrees());
return angle;
} }
float Player::getYawAngle() void Player::setYaw(float angle)
{ {
Ogre::Quaternion orient if (angle > Ogre::Math::PI) {
= mCameraNode->getOrientation(); angle -= Ogre::Math::TWO_PI;
} else if (angle < -Ogre::Math::PI) {
float angle = angle += Ogre::Math::TWO_PI;
(2 * Ogre::Degree(Ogre::Math::ASin(orient.y)).valueDegrees()); }
if (orient.w < 0) { if (mVanityMode || mPreviewMode) {
angle = -angle; mPreviewCam.yaw = angle;
} else {
mMainCam.yaw = angle;
}
}
float Player::getPitch()
{
if (mVanityMode || 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;
}
if (mVanityMode || mPreviewMode) {
mPreviewCam.pitch = angle;
} else {
mMainCam.pitch = angle;
} }
return -angle;
} }
} }

View file

@ -20,29 +20,36 @@ namespace MWRender
/// \brief Player character rendering and camera control /// \brief Player character rendering and camera control
class Player class Player
{ {
struct CamData {
float pitch, yaw, offset;
};
Ogre::Camera *mCamera; Ogre::Camera *mCamera;
Ogre::SceneNode *mPlayerNode; Ogre::SceneNode *mPlayerNode;
Ogre::SceneNode *mCameraNode; Ogre::SceneNode *mCameraNode;
Ogre::SceneNode *mVanityNode;
bool mFirstPersonView; bool mFirstPersonView;
bool mVanityMode; bool mVanityMode;
bool mPreviewMode; bool mPreviewMode;
float mPitch, mYaw, mOffset; float mHeight;
CamData mMainCam, mPreviewCam;
float mTimeIdle; float mTimeIdle;
int mUpdates; int mUpdates;
float limitPitchAngle(float limitAbs, float shift = 0.f);
/// Updates sound manager listener data /// Updates sound manager listener data
void updateListener(); void updateListener();
void rotateCamera(const Ogre::Vector3 &rot, bool adjust); void rotateCamera(const Ogre::Vector3 &rot, bool adjust);
float getYawAngle(); float getYaw();
float getPitchAngle(); void setYaw(float angle);
float getPitch();
void setPitch(float angle);
public: public:
@ -62,9 +69,9 @@ namespace MWRender
void toggleViewMode(); void toggleViewMode();
void toggleVanityMode(); void toggleVanityMode(bool enable, bool force = false);
void togglePreviewMode(); void togglePreviewMode(bool enable);
void update(float duration); void update(float duration);
}; };

View file

@ -135,7 +135,6 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
Ogre::SceneNode *playerNode = mMwRoot->createChildSceneNode ("player"); Ogre::SceneNode *playerNode = mMwRoot->createChildSceneNode ("player");
playerNode->pitch(Degree(90));
mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode); mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode);
mShadows = new Shadows(&mRendering); mShadows = new Shadows(&mRendering);
@ -309,17 +308,23 @@ void RenderingManager::update (float duration){
mRendering.update(duration); mRendering.update(duration);
float *fpos = MWWorld::RefData &data =
MWBase::Environment::get() MWBase::Environment::get()
.getWorld() .getWorld()
->getPlayer() ->getPlayer()
.getPlayer() .getPlayer()
.getRefData() .getRefData();
.getPosition()
.pos;
Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]);
mLocalMap->updatePlayer(pos, mRendering.getCamera()->getRealOrientation() ); float *fpos = data.getPosition().pos;
/// \note only for LocalMap::updatePlayer()
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);
if (mWater) { if (mWater) {
Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition(); Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition();

View file

@ -11,7 +11,7 @@
#include <components/nifbullet/bullet_nif_loader.hpp> #include <components/nifbullet/bullet_nif_loader.hpp>
#include "../mwbase/world.hpp" // FIXME //#include "../mwbase/world.hpp" // FIXME
#include "ptr.hpp" #include "ptr.hpp"
#include "class.hpp" #include "class.hpp"
@ -183,35 +183,25 @@ namespace MWWorld
iter!=actors.end(); ++iter) iter!=actors.end(); ++iter)
{ {
//dirty stuff to get the camera orientation. Must be changed! //dirty stuff to get the camera orientation. Must be changed!
Ogre::Quaternion orient =
mRender.getScene()->getSceneNode(iter->first)->getOrientation();
Ogre::SceneNode *sceneNode = mRender.getScene()->getSceneNode (iter->first); float yaw = orient.getRoll().valueDegrees();
Ogre::Vector3 dir; float pitch = 0.f;
Ogre::Node* yawNode = sceneNode->getChildIterator().getNext();
Ogre::Node* pitchNode = yawNode->getChildIterator().getNext();
Ogre::Quaternion yawQuat = yawNode->getOrientation();
Ogre::Quaternion pitchQuat = pitchNode->getOrientation();
if (iter->first == "player") {
/// \fixme should not rely on player camera, real pitch needed
Ogre::SceneNode *node = mRender.getCamera()->getParentSceneNode();
pitch = node->getOrientation().getPitch().valueDegrees();
playerphysics->ps.viewangles.x = pitch - 90;
playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees(); playerphysics->ps.viewangles.y = -yaw + 90;
playerphysics->ps.viewangles.y = yawQuat.getYaw().valueDegrees() *-1 + 90;
Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
pm_ref.rightmove = -iter->second.x; pm_ref.rightmove = -iter->second.x;
pm_ref.forwardmove = -iter->second.y; pm_ref.forwardmove = -iter->second.y;
pm_ref.upmove = iter->second.z; pm_ref.upmove = iter->second.z;
} }
}
mEngine->stepSimulation(dt); mEngine->stepSimulation(dt);
} }