diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index e1fb57b77f..a00ae9c3c4 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -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). diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index f2179897dc..617d496ffd 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -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); } }; diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index b11b59ac62..df35a6f5b1 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -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); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index aa9107c6ec..2f488a2304 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -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); } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index b0eb656798..a51bdc2e69 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -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.