mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-03 23:26:40 +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
				
			
		| 
						 | 
					@ -41,17 +41,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)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (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 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) *
 | 
					 | 
				
			||||||
                                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);
 | 
					    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;
 | 
				
			||||||
            // rotate physically iff renderer confirm so
 | 
					
 | 
				
			||||||
        float *objRot = ptr.getRefData().getPosition().rot;
 | 
					        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[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();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            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