From 24863f620b1ea705d76972c87b4f60668d659935 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 30 May 2018 14:43:07 +0400 Subject: [PATCH] RotateWorld: rotate around world axis (bug #4426) --- apps/openmw/mwbase/world.hpp | 2 ++ .../mwscript/transformationextensions.cpp | 25 +++++++++---------- apps/openmw/mwworld/worldimp.cpp | 9 +++++++ apps/openmw/mwworld/worldimp.hpp | 2 ++ 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 47502fd71..fb1450aa6 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -564,6 +564,8 @@ namespace MWBase virtual bool isPlayerInJail() const = 0; + virtual void rotateWorldObject (const MWWorld::Ptr& ptr, osg::Quat rotate) = 0; + /// Return terrain height at \a worldPos position. virtual float getTerrainHeightAt(const osg::Vec3f& worldPos) const = 0; diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index 5e617fb1a..611199f72 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -579,26 +579,25 @@ namespace MWScript Interpreter::Type_Float rotation = osg::DegreesToRadians(runtime[0].mFloat*MWBase::Environment::get().getFrameDuration()); runtime.pop(); - const float *objRot = ptr.getRefData().getPosition().rot; + if (!ptr.getRefData().getBaseNode()) + return; - float ax = objRot[0]; - float ay = objRot[1]; - float az = objRot[2]; + // We can rotate actors only around Z axis + if (ptr.getClass().isActor() && (axis == "x" || axis == "y")) + return; + osg::Quat rot; if (axis == "x") - { - MWBase::Environment::get().getWorld()->rotateObject(ptr,ax+rotation,ay,az); - } + rot = osg::Quat(rotation, -osg::X_AXIS); else if (axis == "y") - { - MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay+rotation,az); - } + rot = osg::Quat(rotation, -osg::Y_AXIS); else if (axis == "z") - { - MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,az+rotation); - } + rot = osg::Quat(rotation, -osg::Z_AXIS); else throw std::runtime_error ("invalid rotation axis: " + axis); + + osg::Quat attitude = ptr.getRefData().getBaseNode()->getAttitude(); + MWBase::Environment::get().getWorld()->rotateWorldObject(ptr, attitude * rot); } }; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 6cf1ead87..55e2e5dbc 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1342,6 +1342,15 @@ namespace MWWorld rotateObjectImp(ptr, osg::Vec3f(x, y, z), adjust); } + void World::rotateWorldObject (const Ptr& ptr, osg::Quat rotate) + { + if(ptr.getRefData().getBaseNode() != 0) + { + mRendering->rotateObject(ptr, rotate); + mPhysics->updateRotation(ptr); + } + } + MWWorld::Ptr World::placeObject(const MWWorld::ConstPtr& ptr, MWWorld::CellStore* cell, ESM::Position pos) { return copyObjectToCell(ptr,cell,pos,ptr.getRefData().getCount(),false); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 0d168c912..1d22b96bc 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -214,6 +214,8 @@ namespace MWWorld void setWaterHeight(const float height) override; + void rotateWorldObject (const MWWorld::Ptr& ptr, osg::Quat rotate) override; + bool toggleWater() override; bool toggleWorld() override;