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:
parent
db94018865
commit
fe1a9ac3c5
6 changed files with 129 additions and 120 deletions
apps/openmw
mwinput
mwrender
mwworld
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue