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:
parent
ab52e68c05
commit
ce7bc20fa1
6 changed files with 52 additions and 86 deletions
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue