1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-21 12:23:51 +00:00

Avoid special-casing player rotation

This commit is contained in:
Chris Robinson 2013-04-28 01:14:58 -07:00
parent ab52e68c05
commit ce7bc20fa1
6 changed files with 52 additions and 86 deletions

View file

@ -40,17 +40,6 @@ namespace MWRender
{ {
delete mAnimation; 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) void Player::rotateCamera(const Ogre::Vector3 &rot, bool adjust)
{ {
@ -63,16 +52,15 @@ namespace MWRender
} }
Ogre::Quaternion xr(Ogre::Radian(getPitch() + Ogre::Math::HALF_PI), Ogre::Vector3::UNIT_X); 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) { if (!mVanity.enabled && !mPreviewMode) {
mPlayerNode->setOrientation(zr);
mCameraNode->setOrientation(xr); mCameraNode->setOrientation(xr);
} else { } else {
Ogre::Quaternion zr(Ogre::Radian(getYaw()), Ogre::Vector3::NEGATIVE_UNIT_Z);
mCameraNode->setOrientation(zr * xr); mCameraNode->setOrientation(zr * xr);
} }
} }
std::string Player::getHandle() const const std::string &Player::getHandle() const
{ {
return mPlayerNode->getName(); return mPlayerNode->getName();
} }
@ -318,19 +306,6 @@ namespace MWRender
yaw = mMainCam.yaw; 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) void Player::togglePlayerLooking(bool enable)
{ {
mFreeLook = enable; mFreeLook = enable;

View file

@ -57,9 +57,6 @@ namespace MWRender
/// Set where the player is looking at. Uses Morrowind (euler) angles /// Set where the player is looking at. Uses Morrowind (euler) angles
/// \param rot Rotation angles in radians /// \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); void rotateCamera(const Ogre::Vector3 &rot, bool adjust);
float getYaw(); float getYaw();
@ -68,9 +65,7 @@ namespace MWRender
float getPitch(); float getPitch();
void setPitch(float angle); void setPitch(float angle);
void compensateYaw(float diff); const std::string &getHandle() const;
std::string getHandle() const;
/// Attach camera to object /// Attach camera to object
/// \note there is no protection from attaching the same camera to /// \note there is no protection from attaching the same camera to

View file

@ -264,37 +264,19 @@ void RenderingManager::scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3
ptr.getRefData().getBaseNode()->setScale(scale); 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; Ogre::Vector3 rot(ptr.getRefData().getPosition().rot);
bool isPlayer = isActive && ptr.getRefData().getHandle() == "player";
bool force = true;
if (isPlayer) if(ptr.getRefData().getHandle() == mPlayer->getHandle())
force = mPlayer->rotate(rot, adjust); mPlayer->rotateCamera(rot, false);
MWWorld::Class::get(ptr).adjustRotation(ptr, rot.x, rot.y, rot.z); Ogre::Quaternion newo = Ogre::Quaternion(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Z);
if (!isPlayer && isActive) if(!MWWorld::Class::get(ptr).isActor())
{ newo = Ogre::Quaternion(Ogre::Radian(-rot.x), Ogre::Vector3::UNIT_X) *
if(adjust) Ogre::Quaternion(Ogre::Radian(-rot.y), Ogre::Vector3::UNIT_Y) * newo;
{
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.x), Ogre::Vector3::UNIT_X) * ptr.getRefData().getBaseNode()->setOrientation(newo);
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 void

View file

@ -121,11 +121,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
void moveObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& position); void moveObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& position);
void scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& scale); void scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& scale);
/// Rotates object accordingly to its type /// Updates an object's rotation
/// \param rot euler angles in radians void rotateObject (const MWWorld::Ptr& ptr);
/// \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);
void setWaterHeight(const float height); void setWaterHeight(const float height);
void toggleWater(); void toggleWater();

View file

@ -145,7 +145,7 @@ namespace MWWorld
// FIXME: This works, but it's inconcsistent with how the rotations are applied elsewhere. Why? // 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)* 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[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; movement;
} }
@ -161,7 +161,7 @@ namespace MWWorld
{ {
velocity = (Ogre::Quaternion(Ogre::Radian( -refpos.rot[2]), Ogre::Vector3::UNIT_Z)* 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[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; movement / time;
} }
else else

View file

@ -810,33 +810,50 @@ namespace MWWorld
void World::rotateObjectImp (const Ptr& ptr, Ogre::Vector3 rot, bool adjust) void World::rotateObjectImp (const Ptr& ptr, Ogre::Vector3 rot, bool adjust)
{ {
if (mRendering->rotateObject(ptr, rot, adjust)) 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
{ {
// rotate physically iff renderer confirm so
float *objRot = ptr.getRefData().getPosition().rot;
objRot[0] = rot.x; objRot[0] = rot.x;
objRot[1] = rot.y; objRot[1] = rot.y;
objRot[2] = rot.z; objRot[2] = rot.z;
}
float fullRotateRad=Ogre::Degree(360).valueRadians(); 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;
while(objRot[0]>=fullRotateRad) if(objRot[0] < -half_pi) objRot[0] = -half_pi;
objRot[0] -= fullRotateRad; else if(objRot[0] > half_pi) objRot[0] = half_pi;
while(objRot[1]>=fullRotateRad) }
objRot[1] -= fullRotateRad; else
while(objRot[2]>=fullRotateRad) {
objRot[2] -= fullRotateRad; while(objRot[0] < -pi) objRot[0] += two_pi;
while(objRot[0] > pi) objRot[0] -= two_pi;
}
while(objRot[0]<=-fullRotateRad) while(objRot[1] < -pi) objRot[1] += two_pi;
objRot[0] += fullRotateRad; while(objRot[1] > pi) objRot[1] -= two_pi;
while(objRot[1]<=-fullRotateRad)
objRot[1] += fullRotateRad;
while(objRot[2]<=-fullRotateRad)
objRot[2] += fullRotateRad;
if (ptr.getRefData().getBaseNode() != 0) { while(objRot[2] < -pi) objRot[2] += two_pi;
mPhysics->rotateObject(ptr); while(objRot[2] > pi) objRot[2] -= two_pi;
}
if(ptr.getRefData().getBaseNode() != 0)
{
mRendering->rotateObject(ptr);
mPhysics->rotateObject(ptr);
} }
} }