forked from mirror/openmw-tes3mp
Avoid special-casing player rotation
This commit is contained in:
parent
ab52e68c05
commit
ce7bc20fa1
6 changed files with 52 additions and 86 deletions
|
@ -41,17 +41,6 @@ namespace MWRender
|
|||
delete mAnimation;
|
||||
}
|
||||
|
||||
bool Player::rotate(const Ogre::Vector3 &rot, bool adjust)
|
||||
{
|
||||
if (mVanity.enabled)
|
||||
toggleVanityMode(false);
|
||||
|
||||
if (mFreeLook || mVanity.enabled || mPreviewMode)
|
||||
rotateCamera(rot, adjust);
|
||||
|
||||
return (!mVanity.enabled && !mPreviewMode);
|
||||
}
|
||||
|
||||
void Player::rotateCamera(const Ogre::Vector3 &rot, bool adjust)
|
||||
{
|
||||
if (adjust) {
|
||||
|
@ -63,16 +52,15 @@ namespace MWRender
|
|||
}
|
||||
|
||||
Ogre::Quaternion xr(Ogre::Radian(getPitch() + Ogre::Math::HALF_PI), Ogre::Vector3::UNIT_X);
|
||||
Ogre::Quaternion zr(Ogre::Radian(getYaw()), Ogre::Vector3::NEGATIVE_UNIT_Z);
|
||||
if (!mVanity.enabled && !mPreviewMode) {
|
||||
mPlayerNode->setOrientation(zr);
|
||||
mCameraNode->setOrientation(xr);
|
||||
} else {
|
||||
Ogre::Quaternion zr(Ogre::Radian(getYaw()), Ogre::Vector3::NEGATIVE_UNIT_Z);
|
||||
mCameraNode->setOrientation(zr * xr);
|
||||
}
|
||||
}
|
||||
|
||||
std::string Player::getHandle() const
|
||||
const std::string &Player::getHandle() const
|
||||
{
|
||||
return mPlayerNode->getName();
|
||||
}
|
||||
|
@ -318,19 +306,6 @@ namespace MWRender
|
|||
yaw = mMainCam.yaw;
|
||||
}
|
||||
|
||||
void Player::compensateYaw(float diff)
|
||||
{
|
||||
mPreviewCam.yaw -= diff;
|
||||
Ogre::Quaternion zr(
|
||||
Ogre::Radian(mPreviewCam.yaw),
|
||||
Ogre::Vector3::NEGATIVE_UNIT_Z
|
||||
);
|
||||
Ogre::Quaternion xr(
|
||||
Ogre::Radian(mPreviewCam.pitch),
|
||||
Ogre::Vector3::UNIT_X);
|
||||
mCameraNode->setOrientation(zr * xr);
|
||||
}
|
||||
|
||||
void Player::togglePlayerLooking(bool enable)
|
||||
{
|
||||
mFreeLook = enable;
|
||||
|
|
|
@ -57,9 +57,6 @@ namespace MWRender
|
|||
|
||||
/// Set where the player is looking at. Uses Morrowind (euler) angles
|
||||
/// \param rot Rotation angles in radians
|
||||
/// \return true if player object needs to bo rotated physically
|
||||
bool rotate(const Ogre::Vector3 &rot, bool adjust);
|
||||
|
||||
void rotateCamera(const Ogre::Vector3 &rot, bool adjust);
|
||||
|
||||
float getYaw();
|
||||
|
@ -68,9 +65,7 @@ namespace MWRender
|
|||
float getPitch();
|
||||
void setPitch(float angle);
|
||||
|
||||
void compensateYaw(float diff);
|
||||
|
||||
std::string getHandle() const;
|
||||
const std::string &getHandle() const;
|
||||
|
||||
/// Attach camera to object
|
||||
/// \note there is no protection from attaching the same camera to
|
||||
|
|
|
@ -264,37 +264,19 @@ void RenderingManager::scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3
|
|||
ptr.getRefData().getBaseNode()->setScale(scale);
|
||||
}
|
||||
|
||||
bool RenderingManager::rotateObject(const MWWorld::Ptr &ptr, Ogre::Vector3 &rot, bool adjust)
|
||||
void RenderingManager::rotateObject(const MWWorld::Ptr &ptr)
|
||||
{
|
||||
bool isActive = ptr.getRefData().getBaseNode() != 0;
|
||||
bool isPlayer = isActive && ptr.getRefData().getHandle() == "player";
|
||||
bool force = true;
|
||||
Ogre::Vector3 rot(ptr.getRefData().getPosition().rot);
|
||||
|
||||
if (isPlayer)
|
||||
force = mPlayer->rotate(rot, adjust);
|
||||
if(ptr.getRefData().getHandle() == mPlayer->getHandle())
|
||||
mPlayer->rotateCamera(rot, false);
|
||||
|
||||
MWWorld::Class::get(ptr).adjustRotation(ptr, rot.x, rot.y, rot.z);
|
||||
if (!isPlayer && isActive)
|
||||
{
|
||||
if(adjust)
|
||||
{
|
||||
const float *objRot = ptr.getRefData().getPosition().rot;
|
||||
rot.x += objRot[0];
|
||||
rot.y += objRot[1];
|
||||
rot.z += objRot[2];
|
||||
}
|
||||
Ogre::Quaternion newo = Ogre::Quaternion(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Z);
|
||||
if(!MWWorld::Class::get(ptr).isActor())
|
||||
newo = Ogre::Quaternion(Ogre::Radian(-rot.x), Ogre::Vector3::UNIT_X) *
|
||||
Ogre::Quaternion(Ogre::Radian(-rot.y), Ogre::Vector3::UNIT_Y) * newo;
|
||||
|
||||
Ogre::Quaternion newo = Ogre::Quaternion(Ogre::Radian(-rot.x), Ogre::Vector3::UNIT_X) *
|
||||
Ogre::Quaternion(Ogre::Radian(-rot.y), Ogre::Vector3::UNIT_Y) *
|
||||
Ogre::Quaternion(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Z);
|
||||
ptr.getRefData().getBaseNode()->setOrientation(newo);
|
||||
}
|
||||
else if(isPlayer)
|
||||
{
|
||||
rot.x = -mPlayer->getPitch();
|
||||
rot.z = mPlayer->getYaw();
|
||||
}
|
||||
return force;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -121,11 +121,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
|
|||
void moveObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& position);
|
||||
void scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& scale);
|
||||
|
||||
/// Rotates object accordingly to its type
|
||||
/// \param rot euler angles in radians
|
||||
/// \param adjust indicates should rotation be set or adjusted
|
||||
/// \return true if object needs to be rotated physically
|
||||
bool rotateObject (const MWWorld::Ptr& ptr, Ogre::Vector3 &rot, bool adjust = false);
|
||||
/// Updates an object's rotation
|
||||
void rotateObject (const MWWorld::Ptr& ptr);
|
||||
|
||||
void setWaterHeight(const float height);
|
||||
void toggleWater();
|
||||
|
|
|
@ -145,7 +145,7 @@ namespace MWWorld
|
|||
// FIXME: This works, but it's inconcsistent with how the rotations are applied elsewhere. Why?
|
||||
return position + (Ogre::Quaternion(Ogre::Radian( -refpos.rot[2]), Ogre::Vector3::UNIT_Z)*
|
||||
Ogre::Quaternion(Ogre::Radian( -refpos.rot[1]), Ogre::Vector3::UNIT_Y)*
|
||||
Ogre::Quaternion(Ogre::Radian( -refpos.rot[0]), Ogre::Vector3::UNIT_X)) *
|
||||
Ogre::Quaternion(Ogre::Radian( refpos.rot[0]), Ogre::Vector3::UNIT_X)) *
|
||||
movement;
|
||||
}
|
||||
|
||||
|
@ -161,7 +161,7 @@ namespace MWWorld
|
|||
{
|
||||
velocity = (Ogre::Quaternion(Ogre::Radian( -refpos.rot[2]), Ogre::Vector3::UNIT_Z)*
|
||||
Ogre::Quaternion(Ogre::Radian( -refpos.rot[1]), Ogre::Vector3::UNIT_Y)*
|
||||
Ogre::Quaternion(Ogre::Radian( -refpos.rot[0]), Ogre::Vector3::UNIT_X)) *
|
||||
Ogre::Quaternion(Ogre::Radian( refpos.rot[0]), Ogre::Vector3::UNIT_X)) *
|
||||
movement / time;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -810,33 +810,50 @@ namespace MWWorld
|
|||
|
||||
void World::rotateObjectImp (const Ptr& ptr, Ogre::Vector3 rot, bool adjust)
|
||||
{
|
||||
if (mRendering->rotateObject(ptr, rot, adjust))
|
||||
{
|
||||
// rotate physically iff renderer confirm so
|
||||
const float two_pi = Ogre::Math::TWO_PI;
|
||||
const float pi = Ogre::Math::PI;
|
||||
|
||||
float *objRot = ptr.getRefData().getPosition().rot;
|
||||
if(adjust)
|
||||
{
|
||||
objRot[0] += rot.x;
|
||||
objRot[1] += rot.y;
|
||||
objRot[2] += rot.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
objRot[0] = rot.x;
|
||||
objRot[1] = rot.y;
|
||||
objRot[2] = rot.z;
|
||||
|
||||
float fullRotateRad=Ogre::Degree(360).valueRadians();
|
||||
|
||||
while(objRot[0]>=fullRotateRad)
|
||||
objRot[0] -= fullRotateRad;
|
||||
while(objRot[1]>=fullRotateRad)
|
||||
objRot[1] -= fullRotateRad;
|
||||
while(objRot[2]>=fullRotateRad)
|
||||
objRot[2] -= fullRotateRad;
|
||||
|
||||
while(objRot[0]<=-fullRotateRad)
|
||||
objRot[0] += fullRotateRad;
|
||||
while(objRot[1]<=-fullRotateRad)
|
||||
objRot[1] += fullRotateRad;
|
||||
while(objRot[2]<=-fullRotateRad)
|
||||
objRot[2] += fullRotateRad;
|
||||
|
||||
if (ptr.getRefData().getBaseNode() != 0) {
|
||||
mPhysics->rotateObject(ptr);
|
||||
}
|
||||
|
||||
if(Class::get(ptr).isActor())
|
||||
{
|
||||
/* HACK? Actors shouldn't really be rotating around X (or Y), but
|
||||
* currently it's done so for rotating the camera, which needs
|
||||
* clamping.
|
||||
*/
|
||||
const float half_pi = Ogre::Math::HALF_PI;
|
||||
|
||||
if(objRot[0] < -half_pi) objRot[0] = -half_pi;
|
||||
else if(objRot[0] > half_pi) objRot[0] = half_pi;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(objRot[0] < -pi) objRot[0] += two_pi;
|
||||
while(objRot[0] > pi) objRot[0] -= two_pi;
|
||||
}
|
||||
|
||||
while(objRot[1] < -pi) objRot[1] += two_pi;
|
||||
while(objRot[1] > pi) objRot[1] -= two_pi;
|
||||
|
||||
while(objRot[2] < -pi) objRot[2] += two_pi;
|
||||
while(objRot[2] > pi) objRot[2] -= two_pi;
|
||||
|
||||
if(ptr.getRefData().getBaseNode() != 0)
|
||||
{
|
||||
mRendering->rotateObject(ptr);
|
||||
mPhysics->rotateObject(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue