diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 919eeb18f..1ba17a967 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -42,15 +42,22 @@ namespace rendering.addWaterRippleEmitter(ptr); } - void updateObjectLocalRotation (const MWWorld::Ptr& ptr, MWPhysics::PhysicsSystem& physics, - MWRender::RenderingManager& rendering) + void updateObjectRotation (const MWWorld::Ptr& ptr, MWPhysics::PhysicsSystem& physics, + MWRender::RenderingManager& rendering, bool inverseRotationOrder) { if (ptr.getRefData().getBaseNode() != NULL) { osg::Quat worldRotQuat(ptr.getRefData().getPosition().rot[2], osg::Vec3(0,0,-1)); if (!ptr.getClass().isActor()) - worldRotQuat = worldRotQuat * osg::Quat(ptr.getRefData().getPosition().rot[1], osg::Vec3(0,-1,0)) * - osg::Quat(ptr.getRefData().getPosition().rot[0], osg::Vec3(-1,0,0)); + { + float xr = ptr.getRefData().getPosition().rot[0]; + float yr = ptr.getRefData().getPosition().rot[1]; + if (!inverseRotationOrder) + worldRotQuat = worldRotQuat * osg::Quat(yr, osg::Vec3(0,-1,0)) * + osg::Quat(xr, osg::Vec3(-1,0,0)); + else + worldRotQuat = osg::Quat(xr, osg::Vec3(-1,0,0)) * osg::Quat(yr, osg::Vec3(0,-1,0)) * worldRotQuat; + } rendering.rotateObject(ptr, worldRotQuat); physics.updateRotation(ptr); @@ -106,7 +113,7 @@ namespace try { addObject(ptr, mPhysics, mRendering); - updateObjectLocalRotation(ptr, mPhysics, mRendering); + updateObjectRotation(ptr, mPhysics, mRendering, false); updateObjectScale(ptr, mPhysics, mRendering); ptr.getClass().adjustPosition (ptr, false); } @@ -127,9 +134,9 @@ namespace namespace MWWorld { - void Scene::updateObjectLocalRotation (const Ptr& ptr) + void Scene::updateObjectRotation (const Ptr& ptr, bool inverseRotationOrder) { - ::updateObjectLocalRotation(ptr, *mPhysics, mRendering); + ::updateObjectRotation(ptr, *mPhysics, mRendering, inverseRotationOrder); } void Scene::updateObjectScale(const Ptr &ptr) @@ -548,7 +555,7 @@ namespace MWWorld try { addObject(ptr, *mPhysics, mRendering); - MWBase::Environment::get().getWorld()->rotateObject(ptr, 0, 0, 0, true); + updateObjectRotation(ptr, false); MWBase::Environment::get().getWorld()->scaleObject(ptr, ptr.getCellRef().getScale()); } catch (std::exception& e) diff --git a/apps/openmw/mwworld/scene.hpp b/apps/openmw/mwworld/scene.hpp index ca6ed83b9..439c8d72c 100644 --- a/apps/openmw/mwworld/scene.hpp +++ b/apps/openmw/mwworld/scene.hpp @@ -107,7 +107,7 @@ namespace MWWorld void removeObjectFromScene (const Ptr& ptr); ///< Remove an object from the scene, but not from the world model. - void updateObjectLocalRotation (const Ptr& ptr); + void updateObjectRotation (const Ptr& ptr, bool inverseRotationOrder); void updateObjectScale(const Ptr& ptr); bool isCellActive(const CellStore &cell); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 03f2c1ab8..b800db4a2 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1255,7 +1255,7 @@ namespace MWWorld ptr.getRefData().setPosition(pos); if(ptr.getRefData().getBaseNode() != 0) - mWorldScene->updateObjectLocalRotation(ptr); + mWorldScene->updateObjectRotation(ptr, true); } void World::adjustPosition(const Ptr &ptr, bool force) diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 9ff3e7d1f..9f4928120 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -350,6 +350,8 @@ namespace MWWorld virtual void scaleObject (const Ptr& ptr, float scale); /// World rotates object, uses radians + /// @note Rotations via this method use a different rotation order than the initial rotations in the CS. This + /// could be considered a bug, but is needed for MW compatibility. /// \param adjust indicates rotation should be set or adjusted virtual void rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust = false);