forked from mirror/openmw-tes3mp
poor camera with some fixes
This commit is contained in:
parent
db94018865
commit
fe1a9ac3c5
6 changed files with 129 additions and 120 deletions
|
@ -24,5 +24,5 @@ void MouseLookEvent::event(Type type, int index, const void *p)
|
|||
float y = arg->state.Y.rel * sensY;
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -16,12 +16,16 @@ namespace MWRender
|
|||
: mCamera(camera),
|
||||
mPlayerNode(node),
|
||||
mCameraNode(mPlayerNode->createChildSceneNode()),
|
||||
mVanityNode(mPlayerNode->createChildSceneNode()),
|
||||
mFirstPersonView(true),
|
||||
mVanityMode(false),
|
||||
mPreviewMode(false)
|
||||
mPreviewMode(false),
|
||||
mHeight(40.f)
|
||||
{
|
||||
Ogre::SceneNode *pitchNode = mCameraNode->createChildSceneNode();
|
||||
pitchNode->attachObject(mCamera);
|
||||
mCameraNode->attachObject(mCamera);
|
||||
mCameraNode->setPosition(0.f, 0.f, mHeight);
|
||||
|
||||
mPreviewCam.yaw = 0.f;
|
||||
}
|
||||
|
||||
bool Player::rotate(const Ogre::Vector3 &rot, bool adjust)
|
||||
|
@ -32,7 +36,7 @@ namespace MWRender
|
|||
mTimeIdle = 0.f;
|
||||
|
||||
if (mVanityMode) {
|
||||
toggleVanityMode();
|
||||
toggleVanityMode(false);
|
||||
}
|
||||
|
||||
return !mVanityMode && !mPreviewMode;
|
||||
|
@ -44,26 +48,21 @@ namespace MWRender
|
|||
Ogre::SceneNode *yawNode = pitchNode->getParentSceneNode();
|
||||
|
||||
if (adjust) {
|
||||
float f =
|
||||
limitPitchAngle(89.5f, Ogre::Radian(rot.x).valueDegrees());
|
||||
|
||||
if (f != 0.0) {
|
||||
pitchNode->pitch(Ogre::Degree(f));
|
||||
}
|
||||
yawNode->yaw(Ogre::Radian(-rot.z));
|
||||
setYaw(getYaw() + rot.z);
|
||||
setPitch(getPitch() + rot.x);
|
||||
} else {
|
||||
Ogre::Radian radx(rot.x);
|
||||
if (radx.valueDegrees() > 89.5f) {
|
||||
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 yr(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Y);
|
||||
|
||||
pitchNode->setOrientation(xr);
|
||||
yawNode->setOrientation(yr);
|
||||
setYaw(rot.z);
|
||||
setPitch(rot.x);
|
||||
}
|
||||
Ogre::Quaternion xr(
|
||||
Ogre::Radian(getPitch() + Ogre::Math::HALF_PI),
|
||||
Ogre::Vector3::UNIT_X
|
||||
);
|
||||
Ogre::Quaternion zr(Ogre::Radian(getYaw()), Ogre::Vector3::UNIT_Z);
|
||||
|
||||
pitchNode->setOrientation(xr);
|
||||
yawNode->setOrientation(zr);
|
||||
|
||||
updateListener();
|
||||
}
|
||||
|
||||
|
@ -77,27 +76,6 @@ namespace MWRender
|
|||
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()
|
||||
{
|
||||
Ogre::Vector3 pos = mCamera->getRealPosition();
|
||||
|
@ -116,7 +94,7 @@ namespace MWRender
|
|||
++mUpdates;
|
||||
mTimeIdle += duration;
|
||||
if (mTimeIdle > 30.f) {
|
||||
toggleVanityMode();
|
||||
toggleVanityMode(true);
|
||||
}
|
||||
}
|
||||
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;
|
||||
Ogre::Vector3 rot(0.f, 0.f, 0.f);
|
||||
if (mVanityMode) {
|
||||
mYaw = getYawAngle();
|
||||
mPitch = getPitchAngle();
|
||||
mOffset = mCamera->getPosition().z;
|
||||
|
||||
rot.x = Ogre::Degree(-30.f).valueRadians();
|
||||
mMainCam.offset = mCamera->getPosition().z;
|
||||
|
||||
mPlayerNode->removeChild(mCameraNode);
|
||||
mVanityNode->addChild(mCameraNode);
|
||||
} else {
|
||||
rot.x = Ogre::Degree(mPitch).valueRadians();
|
||||
rot.z = Ogre::Degree(mYaw).valueRadians();
|
||||
offset = mOffset;
|
||||
rot.x = getPitch();
|
||||
offset = mMainCam.offset;
|
||||
|
||||
mVanityNode->removeChild(mCameraNode);
|
||||
mPlayerNode->addChild(mCameraNode);
|
||||
}
|
||||
rot.z = getYaw();
|
||||
mCamera->setPosition(0.f, 0.f, offset);
|
||||
rotateCamera(rot, false);
|
||||
}
|
||||
|
||||
void Player::togglePreviewMode()
|
||||
void Player::togglePreviewMode(bool enable)
|
||||
{
|
||||
/// \todo move camera
|
||||
mPreviewMode = !mPreviewMode;
|
||||
}
|
||||
|
||||
float Player::getPitchAngle()
|
||||
{
|
||||
Ogre::Quaternion orient
|
||||
= mCamera->getParentSceneNode()->getOrientation();
|
||||
|
||||
float angle =
|
||||
(2 * Ogre::Degree(Ogre::Math::ASin(orient.x)).valueDegrees());
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
float Player::getYawAngle()
|
||||
{
|
||||
Ogre::Quaternion orient
|
||||
= mCameraNode->getOrientation();
|
||||
|
||||
float angle =
|
||||
(2 * Ogre::Degree(Ogre::Math::ASin(orient.y)).valueDegrees());
|
||||
if (orient.w < 0) {
|
||||
angle = -angle;
|
||||
if (mPreviewMode == enable) {
|
||||
return;
|
||||
}
|
||||
mPreviewMode = enable;
|
||||
}
|
||||
|
||||
float Player::getYaw()
|
||||
{
|
||||
if (mVanityMode || mPreviewMode) {
|
||||
return mPreviewCam.yaw;
|
||||
}
|
||||
return mMainCam.yaw;
|
||||
}
|
||||
|
||||
void Player::setYaw(float angle)
|
||||
{
|
||||
if (angle > Ogre::Math::PI) {
|
||||
angle -= Ogre::Math::TWO_PI;
|
||||
} else if (angle < -Ogre::Math::PI) {
|
||||
angle += Ogre::Math::TWO_PI;
|
||||
}
|
||||
if (mVanityMode || mPreviewMode) {
|
||||
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
|
||||
class Player
|
||||
{
|
||||
struct CamData {
|
||||
float pitch, yaw, offset;
|
||||
};
|
||||
|
||||
Ogre::Camera *mCamera;
|
||||
|
||||
Ogre::SceneNode *mPlayerNode;
|
||||
Ogre::SceneNode *mCameraNode;
|
||||
Ogre::SceneNode *mVanityNode;
|
||||
|
||||
bool mFirstPersonView;
|
||||
bool mVanityMode;
|
||||
bool mPreviewMode;
|
||||
|
||||
float mPitch, mYaw, mOffset;
|
||||
float mHeight;
|
||||
CamData mMainCam, mPreviewCam;
|
||||
|
||||
float mTimeIdle;
|
||||
int mUpdates;
|
||||
|
||||
float limitPitchAngle(float limitAbs, float shift = 0.f);
|
||||
|
||||
/// Updates sound manager listener data
|
||||
void updateListener();
|
||||
|
||||
void rotateCamera(const Ogre::Vector3 &rot, bool adjust);
|
||||
|
||||
float getYawAngle();
|
||||
float getPitchAngle();
|
||||
float getYaw();
|
||||
void setYaw(float angle);
|
||||
|
||||
float getPitch();
|
||||
void setPitch(float angle);
|
||||
|
||||
public:
|
||||
|
||||
|
@ -62,9 +69,9 @@ namespace MWRender
|
|||
|
||||
void toggleViewMode();
|
||||
|
||||
void toggleVanityMode();
|
||||
void toggleVanityMode(bool enable, bool force = false);
|
||||
|
||||
void togglePreviewMode();
|
||||
void togglePreviewMode(bool enable);
|
||||
|
||||
void update(float duration);
|
||||
};
|
||||
|
|
|
@ -135,7 +135,6 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
|
|||
|
||||
|
||||
Ogre::SceneNode *playerNode = mMwRoot->createChildSceneNode ("player");
|
||||
playerNode->pitch(Degree(90));
|
||||
mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode);
|
||||
|
||||
mShadows = new Shadows(&mRendering);
|
||||
|
@ -309,17 +308,23 @@ void RenderingManager::update (float duration){
|
|||
|
||||
mRendering.update(duration);
|
||||
|
||||
float *fpos =
|
||||
MWWorld::RefData &data =
|
||||
MWBase::Environment::get()
|
||||
.getWorld()
|
||||
->getPlayer()
|
||||
.getPlayer()
|
||||
.getRefData()
|
||||
.getPosition()
|
||||
.pos;
|
||||
Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]);
|
||||
.getRefData();
|
||||
|
||||
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) {
|
||||
Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition();
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#include <components/nifbullet/bullet_nif_loader.hpp>
|
||||
|
||||
#include "../mwbase/world.hpp" // FIXME
|
||||
//#include "../mwbase/world.hpp" // FIXME
|
||||
|
||||
#include "ptr.hpp"
|
||||
#include "class.hpp"
|
||||
|
@ -172,7 +172,7 @@ namespace MWWorld
|
|||
OEngine::Physic::PhysicActor* act = it->second;
|
||||
act->setWalkDirection(btVector3(0,0,0));
|
||||
}
|
||||
playerMove::playercmd& pm_ref = playerphysics->cmd;
|
||||
playerMove::playercmd& pm_ref = playerphysics->cmd;
|
||||
|
||||
pm_ref.rightmove = 0;
|
||||
pm_ref.forwardmove = 0;
|
||||
|
@ -183,35 +183,25 @@ namespace MWWorld
|
|||
iter!=actors.end(); ++iter)
|
||||
{
|
||||
//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);
|
||||
Ogre::Vector3 dir;
|
||||
Ogre::Node* yawNode = sceneNode->getChildIterator().getNext();
|
||||
Ogre::Node* pitchNode = yawNode->getChildIterator().getNext();
|
||||
Ogre::Quaternion yawQuat = yawNode->getOrientation();
|
||||
Ogre::Quaternion pitchQuat = pitchNode->getOrientation();
|
||||
|
||||
|
||||
|
||||
playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees();
|
||||
|
||||
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.forwardmove = -iter->second.y;
|
||||
pm_ref.upmove = iter->second.z;
|
||||
float yaw = orient.getRoll().valueDegrees();
|
||||
float pitch = 0.f;
|
||||
|
||||
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.y = -yaw + 90;
|
||||
|
||||
pm_ref.rightmove = -iter->second.x;
|
||||
pm_ref.forwardmove = -iter->second.y;
|
||||
pm_ref.upmove = iter->second.z;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
mEngine->stepSimulation(dt);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue