mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 20:26:43 +00:00 
			
		
		
		
	Improved local rotations
This commit is contained in:
		
							parent
							
								
									53fb17da10
								
							
						
					
					
						commit
						7cd4dd0c91
					
				
					 5 changed files with 44 additions and 35 deletions
				
			
		|  | @ -230,7 +230,7 @@ namespace MWBase | |||
| 
 | ||||
|             virtual void rotateObject(const MWWorld::Ptr& ptr,float x,float y,float z, bool adjust = false) = 0; | ||||
| 
 | ||||
|             virtual void localRotateObject (const MWWorld::Ptr& ptr, float rotation, Ogre::Vector3 axis) = 0; | ||||
|             virtual void localRotateObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0; | ||||
| 
 | ||||
|             virtual void safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos) = 0; | ||||
|             ///< place an object in a "safe" location (ie not in the void, etc).
 | ||||
|  |  | |||
|  | @ -84,29 +84,30 @@ namespace MWScript | |||
|                     Interpreter::Type_Float angle = runtime[0].mFloat; | ||||
|                     runtime.pop(); | ||||
| 
 | ||||
|                     float ax = Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees(); | ||||
|                     float ay = Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees(); | ||||
|                     float az = Ogre::Radian(ptr.getRefData().getPosition().rot[2]).valueDegrees(); | ||||
|                     float ax = Ogre::Radian(ptr.getRefData().getLocalRotation().rot[0]).valueDegrees(); | ||||
|                     float ay = Ogre::Radian(ptr.getRefData().getLocalRotation().rot[1]).valueDegrees(); | ||||
|                     float az = Ogre::Radian(ptr.getRefData().getLocalRotation().rot[2]).valueDegrees(); | ||||
| 
 | ||||
|                     float *objRot = ptr.getRefData().getPosition().rot; | ||||
| 
 | ||||
|                     float lx = Ogre::Radian(objRot[0]).valueDegrees(); | ||||
|                     float ly = Ogre::Radian(objRot[1]).valueDegrees(); | ||||
|                     float lz = Ogre::Radian(objRot[2]).valueDegrees(); | ||||
| 
 | ||||
|                     if (axis == "x") | ||||
|                     { | ||||
|                         MWBase::Environment::get().getWorld()->rotateObject(ptr,angle,ay,az); | ||||
|                         MWBase::Environment::get().getWorld()->localRotateObject(ptr,angle-lx,ay,az); | ||||
|                     } | ||||
|                     else if (axis == "y") | ||||
|                     { | ||||
|                         MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,angle,az); | ||||
|                         MWBase::Environment::get().getWorld()->localRotateObject(ptr,ax,angle-ly,az); | ||||
|                     } | ||||
|                     else if (axis == "z") | ||||
|                     { | ||||
|                         MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,angle); | ||||
|                         MWBase::Environment::get().getWorld()->localRotateObject(ptr,ax,ay,angle-lz); | ||||
|                     } | ||||
|                     else | ||||
|                         throw std::runtime_error ("invalid ration axis: " + axis); | ||||
| 
 | ||||
|                     //Local rotations clear
 | ||||
|                     ptr.getRefData().getLocalRotation().rot[0]=0; | ||||
|                     ptr.getRefData().getLocalRotation().rot[1]=0; | ||||
|                     ptr.getRefData().getLocalRotation().rot[2]=0; | ||||
|                 } | ||||
|         }; | ||||
| 
 | ||||
|  | @ -153,15 +154,15 @@ namespace MWScript | |||
| 
 | ||||
|                     if (axis=="x") | ||||
|                     { | ||||
|                         runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[0]).valueDegrees()+ptr.getRefData().getLocalRotation().rot[0]); | ||||
|                         runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[0]).valueDegrees()+Ogre::Radian(ptr.getRefData().getLocalRotation().rot[0]).valueDegrees()); | ||||
|                     } | ||||
|                     else if (axis=="y") | ||||
|                     { | ||||
|                         runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[1]).valueDegrees()+ptr.getRefData().getLocalRotation().rot[1]); | ||||
|                         runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[1]).valueDegrees()+Ogre::Radian(ptr.getRefData().getLocalRotation().rot[1]).valueDegrees()); | ||||
|                     } | ||||
|                     else if (axis=="z") | ||||
|                     { | ||||
|                         runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[2]).valueDegrees()+ptr.getRefData().getLocalRotation().rot[2]); | ||||
|                         runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[2]).valueDegrees()+Ogre::Radian(ptr.getRefData().getLocalRotation().rot[2]).valueDegrees()); | ||||
|                     } | ||||
|                     else | ||||
|                         throw std::runtime_error ("invalid ration axis: " + axis); | ||||
|  | @ -561,21 +562,24 @@ namespace MWScript | |||
|                     Interpreter::Type_Float rotation = (runtime[0].mFloat*MWBase::Environment::get().getFrameDuration()); | ||||
|                     runtime.pop(); | ||||
| 
 | ||||
|                     float ax = Ogre::Radian(ptr.getRefData().getLocalRotation().rot[0]).valueDegrees(); | ||||
|                     float ay = Ogre::Radian(ptr.getRefData().getLocalRotation().rot[1]).valueDegrees(); | ||||
|                     float az = Ogre::Radian(ptr.getRefData().getLocalRotation().rot[2]).valueDegrees(); | ||||
| 
 | ||||
|                     if (axis == "x") | ||||
|                     { | ||||
|                         MWBase::Environment::get().getWorld()->localRotateObject(ptr, rotation, Ogre::Vector3::UNIT_X); | ||||
|                         MWBase::Environment::get().getWorld()->localRotateObject(ptr,ax+rotation,ay,az); | ||||
|                     } | ||||
|                     else if (axis == "y") | ||||
|                     { | ||||
|                         MWBase::Environment::get().getWorld()->localRotateObject(ptr, rotation, Ogre::Vector3::UNIT_Y); | ||||
|                         MWBase::Environment::get().getWorld()->localRotateObject(ptr,ax,ay+rotation,az); | ||||
|                     } | ||||
|                     else if (axis == "z") | ||||
|                     { | ||||
|                         MWBase::Environment::get().getWorld()->localRotateObject(ptr, rotation, Ogre::Vector3::UNIT_Z); | ||||
|                         MWBase::Environment::get().getWorld()->localRotateObject(ptr,ax,ay,az+rotation); | ||||
|                     } | ||||
| 
 | ||||
|                     else | ||||
|                         throw std::runtime_error ("invalid rotation axis: " + axis); | ||||
|                         throw std::runtime_error ("invalid ration axis: " + axis); | ||||
|                 } | ||||
|         }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -49,13 +49,11 @@ namespace | |||
|                     { | ||||
|                         rendering.addObject(ptr); | ||||
|                         class_.insertObject(ptr, physics); | ||||
|                         MWBase::Environment::get().getWorld()->rotateObject(ptr, 0, 0, 0, true); | ||||
| 
 | ||||
|                         //To keep local-rotations
 | ||||
|                         const float *local = ptr.getRefData().getLocalRotation().rot; | ||||
|                         MWBase::Environment::get().getWorld()->localRotateObject(ptr, local[0], Ogre::Vector3::UNIT_X); | ||||
|                         MWBase::Environment::get().getWorld()->localRotateObject(ptr, local[1], Ogre::Vector3::UNIT_Y); | ||||
|                         MWBase::Environment::get().getWorld()->localRotateObject(ptr, local[2], Ogre::Vector3::UNIT_Z); | ||||
|                         float ax = Ogre::Radian(ptr.getRefData().getLocalRotation().rot[0]).valueDegrees(); | ||||
|                         float ay = Ogre::Radian(ptr.getRefData().getLocalRotation().rot[1]).valueDegrees(); | ||||
|                         float az = Ogre::Radian(ptr.getRefData().getLocalRotation().rot[2]).valueDegrees(); | ||||
|                         MWBase::Environment::get().getWorld()->localRotateObject(ptr, ax, ay, az); | ||||
| 
 | ||||
|                         MWBase::Environment::get().getWorld()->scaleObject(ptr, ptr.getCellRef().mScale); | ||||
|                         class_.adjustPosition(ptr); | ||||
|  |  | |||
|  | @ -824,18 +824,25 @@ namespace MWWorld | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void World::localRotateObject (const Ptr& ptr, float rotation, Ogre::Vector3 axis) | ||||
|     void World::localRotateObject (const Ptr& ptr, float x, float y, float z) | ||||
|     { | ||||
|         if (ptr.getRefData().getBaseNode() != 0) { | ||||
| 
 | ||||
|             if(axis==Ogre::Vector3::UNIT_X) | ||||
|                 ptr.getRefData().getLocalRotation().rot[0]+=rotation; | ||||
|             else if(axis==Ogre::Vector3::UNIT_Y) | ||||
|                 ptr.getRefData().getLocalRotation().rot[1]+=rotation; | ||||
|             else if(axis==Ogre::Vector3::UNIT_Z) | ||||
|                 ptr.getRefData().getLocalRotation().rot[2]+=rotation; | ||||
|             ptr.getRefData().getLocalRotation().rot[0]=Ogre::Degree(x).valueRadians(); | ||||
|             ptr.getRefData().getLocalRotation().rot[1]=Ogre::Degree(y).valueRadians(); | ||||
|             ptr.getRefData().getLocalRotation().rot[2]=Ogre::Degree(z).valueRadians(); | ||||
| 
 | ||||
|             ptr.getRefData().getBaseNode()->rotate(Ogre::Quaternion(Ogre::Radian(Ogre::Degree(-rotation).valueRadians()), axis)); | ||||
|             float *worldRot = ptr.getRefData().getPosition().rot; | ||||
| 
 | ||||
|             Ogre::Quaternion worldRotQuat(Ogre::Quaternion(Ogre::Radian(-worldRot[0]), Ogre::Vector3::UNIT_X)* | ||||
|             Ogre::Quaternion(Ogre::Radian(-worldRot[1]), Ogre::Vector3::UNIT_Y)* | ||||
|             Ogre::Quaternion(Ogre::Radian(-worldRot[2]), Ogre::Vector3::UNIT_Z)); | ||||
| 
 | ||||
|             Ogre::Quaternion rot(Ogre::Quaternion(Ogre::Radian(Ogre::Degree(-x).valueRadians()), Ogre::Vector3::UNIT_X)* | ||||
|             Ogre::Quaternion(Ogre::Radian(Ogre::Degree(-y).valueRadians()), Ogre::Vector3::UNIT_Y)* | ||||
|             Ogre::Quaternion(Ogre::Radian(Ogre::Degree(-z).valueRadians()), Ogre::Vector3::UNIT_Z)); | ||||
| 
 | ||||
|             ptr.getRefData().getBaseNode()->setOrientation(worldRotQuat*rot); | ||||
|             mPhysics->rotateObject(ptr); | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -254,7 +254,7 @@ namespace MWWorld | |||
|             /// \param adjust indicates rotation should be set or adjusted
 | ||||
|             virtual void rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust = false); | ||||
| 
 | ||||
|             virtual void localRotateObject (const Ptr& ptr, float rotation, Ogre::Vector3 axis); | ||||
|             virtual void localRotateObject (const Ptr& ptr, float x, float y, float z); | ||||
| 
 | ||||
|             virtual void safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos); | ||||
|             ///< place an object in a "safe" location (ie not in the void, etc). Makes a copy of the Ptr.
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue