From 106ef4c9369e303aaf79654c597961e1516f3522 Mon Sep 17 00:00:00 2001 From: Glorf Date: Wed, 10 Apr 2013 22:53:03 +0200 Subject: [PATCH 01/12] Rotate script --- apps/openmw/mwscript/docs/vmformat.txt | 4 +- .../mwscript/transformationextensions.cpp | 41 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 7e9827062b..7810c2874b 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -318,5 +318,7 @@ op 0x20001fb: DropSoulGem, explicit reference op 0x20001fc: OnDeath op 0x20001fd: IsWerewolf op 0x20001fe: IsWerewolf, explicit reference +op 0x20001ff: Rotate +op 0x2000200: Rotate, explicit reference -opcodes 0x20001ff-0x3ffffff unused +opcodes 0x2000201-0x3ffffff unused diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index 49688efb5d..6c4fb0f4bd 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -542,6 +542,42 @@ namespace MWScript } }; + template + class OpRotate : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + + std::string axis = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + Interpreter::Type_Float rotation = (runtime[0].mFloat/80); //It works this way, don't ask me why + 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(); + + //Axis in morrowind are inverted + if (axis == "y") + { + MWBase::Environment::get().getWorld()->rotateObject(ptr,ax+rotation,ay,az); + } + else if (axis == "x") + { + MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay+rotation,az); + } + else if (axis == "z") + { + MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,az+rotation); + } + else + throw std::runtime_error ("invalid rotation axis: " + axis); + } + }; + const int opcodeSetScale = 0x2000164; const int opcodeSetScaleExplicit = 0x2000165; const int opcodeSetAngle = 0x2000166; @@ -568,6 +604,8 @@ namespace MWScript const int opcodePlaceAtMeExplicit = 0x200019e; const int opcodeModScale = 0x20001e3; const int opcodeModScaleExplicit = 0x20001e4; + const int opcodeRotate = 0x20001ff; + const int opcodeRotateExplicit = 0x2000200; void registerExtensions (Compiler::Extensions& extensions) { @@ -585,6 +623,7 @@ namespace MWScript extensions.registerInstruction("placeatpc","clfl",opcodePlaceAtPc); extensions.registerInstruction("placeatme","clfl",opcodePlaceAtMe,opcodePlaceAtMeExplicit); extensions.registerInstruction("modscale","f",opcodeModScale,opcodeModScaleExplicit); + extensions.registerInstruction("rotate","cf",opcodeRotate,opcodeRotateExplicit); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -614,6 +653,8 @@ namespace MWScript interpreter.installSegment5(opcodePlaceAtMeExplicit,new OpPlaceAtMe); interpreter.installSegment5(opcodeModScale,new OpModScale); interpreter.installSegment5(opcodeModScaleExplicit,new OpModScale); + interpreter.installSegment5(opcodeRotate,new OpRotate); + interpreter.installSegment5(opcodeRotateExplicit,new OpRotate); } } } From 4e0233cf06384472ef49f47de87fcccc1068066c Mon Sep 17 00:00:00 2001 From: Glorf Date: Sun, 14 Apr 2013 21:42:37 +0200 Subject: [PATCH 02/12] Base local rotations implementation --- .../mwscript/transformationextensions.cpp | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index 6c4fb0f4bd..922353974d 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -553,26 +553,30 @@ namespace MWScript std::string axis = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - Interpreter::Type_Float rotation = (runtime[0].mFloat/80); //It works this way, don't ask me why + Interpreter::Type_Float rotation = (runtime[0].mFloat/80); //It works this way, don't ask me why (probably framerate) 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 *objRot = ptr.getRefData().getPosition().rot; - //Axis in morrowind are inverted - if (axis == "y") + if (axis == "x") { - MWBase::Environment::get().getWorld()->rotateObject(ptr,ax+rotation,ay,az); + objRot[0]+=Ogre::Degree(rotation).valueRadians(); + + ptr.getRefData().getBaseNode()->rotate(Ogre::Quaternion(Ogre::Radian(Ogre::Degree(-rotation).valueRadians()), Ogre::Vector3::UNIT_X));; } - else if (axis == "x") + else if (axis == "y") { - MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay+rotation,az); + objRot[1]+=Ogre::Degree(rotation).valueRadians(); + + ptr.getRefData().getBaseNode()->rotate(Ogre::Quaternion(Ogre::Radian(Ogre::Degree(-rotation).valueRadians()), Ogre::Vector3::UNIT_Y)); } else if (axis == "z") { - MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,az+rotation); + objRot[2]+=Ogre::Degree(rotation).valueRadians(); + + ptr.getRefData().getBaseNode()->rotate(Ogre::Quaternion(Ogre::Radian(Ogre::Degree(-rotation).valueRadians()), Ogre::Vector3::UNIT_Z)); } + else throw std::runtime_error ("invalid rotation axis: " + axis); } From 972481f63f7ef724364b6cf9672aac50fc558788 Mon Sep 17 00:00:00 2001 From: Glorf Date: Mon, 15 Apr 2013 16:45:53 +0200 Subject: [PATCH 03/12] Working rotate, rotateworld --- apps/openmw/mwbase/windowmanager.hpp | 2 + apps/openmw/mwbase/world.hpp | 2 + apps/openmw/mwgui/windowmanagerimp.cpp | 5 ++ apps/openmw/mwgui/windowmanagerimp.hpp | 2 + apps/openmw/mwscript/docs/vmformat.txt | 4 +- .../mwscript/transformationextensions.cpp | 56 +++++++++++++++++-- apps/openmw/mwworld/worldimp.cpp | 6 ++ apps/openmw/mwworld/worldimp.hpp | 2 + 8 files changed, 73 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 976d7d84c1..b34117df29 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -251,6 +251,8 @@ namespace MWBase virtual void changePointer (const std::string& name) = 0; virtual const Translation::Storage& getTranslationDataStorage() const = 0; + + virtual int getFPS() const = 0; }; } diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 39e985890a..94a30d759b 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -230,6 +230,8 @@ 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 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/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index f994683a66..b3a080bf25 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -1200,3 +1200,8 @@ void WindowManager::frameStarted (float dt) { mInventoryWindow->doRenderUpdate (); } + +int WindowManager::getFPS() const +{ + return mFPS; +} diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 3c9fc586a3..3a7296b5ba 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -248,6 +248,8 @@ namespace MWGui void onSoulgemDialogButtonPressed (int button); + virtual int getFPS() const; + private: OEngine::GUI::MyGUIManager *mGuiManager; OEngine::Render::OgreRenderer *mRendering; diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 7810c2874b..b7ee2d31c6 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -320,5 +320,7 @@ op 0x20001fd: IsWerewolf op 0x20001fe: IsWerewolf, explicit reference op 0x20001ff: Rotate op 0x2000200: Rotate, explicit reference +op 0x2000201: RotateWorld +op 0x2000202: RotateWorld, explicit reference -opcodes 0x2000201-0x3ffffff unused +opcodes 0x2000203-0x3ffffff unused diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index 922353974d..41bacf1106 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -13,6 +13,7 @@ #include #include "../mwbase/environment.hpp" +#include "../mwbase/windowmanager.hpp" #include "../mwworld/class.hpp" #include "../mwworld/player.hpp" @@ -549,11 +550,11 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWWorld::Ptr ptr = R()(runtime); + const MWWorld::Ptr& ptr = R()(runtime); std::string axis = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - Interpreter::Type_Float rotation = (runtime[0].mFloat/80); //It works this way, don't ask me why (probably framerate) + Interpreter::Type_Float rotation = (runtime[0].mFloat/MWBase::Environment::get().getWindowManager()->getFPS()); runtime.pop(); float *objRot = ptr.getRefData().getPosition().rot; @@ -562,19 +563,22 @@ namespace MWScript { objRot[0]+=Ogre::Degree(rotation).valueRadians(); - ptr.getRefData().getBaseNode()->rotate(Ogre::Quaternion(Ogre::Radian(Ogre::Degree(-rotation).valueRadians()), Ogre::Vector3::UNIT_X));; + if (ptr.getRefData().getBaseNode() != 0) + MWBase::Environment::get().getWorld()->localRotateObject(ptr, rotation, Ogre::Vector3::UNIT_X); } else if (axis == "y") { objRot[1]+=Ogre::Degree(rotation).valueRadians(); - ptr.getRefData().getBaseNode()->rotate(Ogre::Quaternion(Ogre::Radian(Ogre::Degree(-rotation).valueRadians()), Ogre::Vector3::UNIT_Y)); + if (ptr.getRefData().getBaseNode() != 0) + MWBase::Environment::get().getWorld()->localRotateObject(ptr, rotation, Ogre::Vector3::UNIT_Y); } else if (axis == "z") { objRot[2]+=Ogre::Degree(rotation).valueRadians(); - ptr.getRefData().getBaseNode()->rotate(Ogre::Quaternion(Ogre::Radian(Ogre::Degree(-rotation).valueRadians()), Ogre::Vector3::UNIT_Z)); + if (ptr.getRefData().getBaseNode() != 0) + MWBase::Environment::get().getWorld()->localRotateObject(ptr, rotation, Ogre::Vector3::UNIT_Z); } else @@ -582,6 +586,43 @@ namespace MWScript } }; + template + class OpRotateWorld : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + + std::string axis = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + Interpreter::Type_Float rotation = (runtime[0].mFloat/MWBase::Environment::get().getWindowManager()->getFPS()); + runtime.pop(); + + float *objRot = ptr.getRefData().getPosition().rot; + + float ax = Ogre::Radian(objRot[0]).valueDegrees(); + float ay = Ogre::Radian(objRot[1]).valueDegrees(); + float az = Ogre::Radian(objRot[2]).valueDegrees(); + + if (axis == "x") + { + MWBase::Environment::get().getWorld()->rotateObject(ptr,ax+rotation,ay,az); + } + else if (axis == "y") + { + MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay+rotation,az); + } + else if (axis == "z") + { + MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,az+rotation); + } + else + throw std::runtime_error ("invalid rotation axis: " + axis); + } + }; + const int opcodeSetScale = 0x2000164; const int opcodeSetScaleExplicit = 0x2000165; const int opcodeSetAngle = 0x2000166; @@ -610,6 +651,8 @@ namespace MWScript const int opcodeModScaleExplicit = 0x20001e4; const int opcodeRotate = 0x20001ff; const int opcodeRotateExplicit = 0x2000200; + const int opcodeRotateWorld = 0x2000201; + const int opcodeRotateWorldExplicit = 0x2000202; void registerExtensions (Compiler::Extensions& extensions) { @@ -628,6 +671,7 @@ namespace MWScript extensions.registerInstruction("placeatme","clfl",opcodePlaceAtMe,opcodePlaceAtMeExplicit); extensions.registerInstruction("modscale","f",opcodeModScale,opcodeModScaleExplicit); extensions.registerInstruction("rotate","cf",opcodeRotate,opcodeRotateExplicit); + extensions.registerInstruction("rotateworld","cf",opcodeRotateWorld,opcodeRotateWorldExplicit); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -659,6 +703,8 @@ namespace MWScript interpreter.installSegment5(opcodeModScaleExplicit,new OpModScale); interpreter.installSegment5(opcodeRotate,new OpRotate); interpreter.installSegment5(opcodeRotateExplicit,new OpRotate); + interpreter.installSegment5(opcodeRotateWorld,new OpRotateWorld); + interpreter.installSegment5(opcodeRotateWorldExplicit,new OpRotateWorld); } } } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 11ccd8f2fc..c5ebbb306f 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -826,6 +826,12 @@ namespace MWWorld } } + void World::localRotateObject (const Ptr& ptr, float rotation, Ogre::Vector3 axis) + { + ptr.getRefData().getBaseNode()->rotate(Ogre::Quaternion(Ogre::Radian(Ogre::Degree(-rotation).valueRadians()), axis)); + mPhysics->rotateObject(ptr); + } + void World::adjustPosition(const Ptr &ptr) { Ogre::Vector3 pos (ptr.getRefData().getPosition().pos[0], ptr.getRefData().getPosition().pos[1], ptr.getRefData().getPosition().pos[2]); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 7b12babee9..59a359b6b7 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -254,6 +254,8 @@ 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 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. From 763308868d501bc7bd7102d6a442855f8c155f1b Mon Sep 17 00:00:00 2001 From: Glorf Date: Mon, 15 Apr 2013 17:45:18 +0200 Subject: [PATCH 04/12] Fixed rotation speed --- apps/openmw/mwbase/windowmanager.hpp | 2 -- apps/openmw/mwgui/windowmanagerimp.cpp | 5 ----- apps/openmw/mwgui/windowmanagerimp.hpp | 2 -- apps/openmw/mwscript/transformationextensions.cpp | 5 ++--- 4 files changed, 2 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index b34117df29..976d7d84c1 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -251,8 +251,6 @@ namespace MWBase virtual void changePointer (const std::string& name) = 0; virtual const Translation::Storage& getTranslationDataStorage() const = 0; - - virtual int getFPS() const = 0; }; } diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index b3a080bf25..f994683a66 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -1200,8 +1200,3 @@ void WindowManager::frameStarted (float dt) { mInventoryWindow->doRenderUpdate (); } - -int WindowManager::getFPS() const -{ - return mFPS; -} diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 3a7296b5ba..3c9fc586a3 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -248,8 +248,6 @@ namespace MWGui void onSoulgemDialogButtonPressed (int button); - virtual int getFPS() const; - private: OEngine::GUI::MyGUIManager *mGuiManager; OEngine::Render::OgreRenderer *mRendering; diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index 41bacf1106..8ac5a7802a 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -13,7 +13,6 @@ #include #include "../mwbase/environment.hpp" -#include "../mwbase/windowmanager.hpp" #include "../mwworld/class.hpp" #include "../mwworld/player.hpp" @@ -554,7 +553,7 @@ namespace MWScript std::string axis = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - Interpreter::Type_Float rotation = (runtime[0].mFloat/MWBase::Environment::get().getWindowManager()->getFPS()); + Interpreter::Type_Float rotation = (runtime[0].mFloat*MWBase::Environment::get().getFrameDuration()); runtime.pop(); float *objRot = ptr.getRefData().getPosition().rot; @@ -597,7 +596,7 @@ namespace MWScript std::string axis = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - Interpreter::Type_Float rotation = (runtime[0].mFloat/MWBase::Environment::get().getWindowManager()->getFPS()); + Interpreter::Type_Float rotation = (runtime[0].mFloat*MWBase::Environment::get().getFrameDuration()); runtime.pop(); float *objRot = ptr.getRefData().getPosition().rot; From 1e92ffc3147229b9d1b08e972b4372f7b8ca9f49 Mon Sep 17 00:00:00 2001 From: Glorf Date: Tue, 16 Apr 2013 21:17:19 +0200 Subject: [PATCH 05/12] Added rotation layer --- .../mwscript/transformationextensions.cpp | 27 +++++++++---------- apps/openmw/mwworld/refdata.cpp | 12 ++++++++- apps/openmw/mwworld/refdata.hpp | 10 +++++++ apps/openmw/mwworld/scene.cpp | 7 +++++ apps/openmw/mwworld/worldimp.cpp | 6 +++-- 5 files changed, 44 insertions(+), 18 deletions(-) diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index 8ac5a7802a..e2d701268b 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -102,6 +102,11 @@ namespace MWScript } 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; } }; @@ -148,15 +153,15 @@ namespace MWScript if (axis=="x") { - runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees()); + runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[0]+ptr.getRefData().getLocalRotation().rot[0]).valueDegrees()); } else if (axis=="y") { - runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees()); + runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[1]+ptr.getRefData().getLocalRotation().rot[1]).valueDegrees()); } else if (axis=="z") { - runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[2]).valueDegrees()); + runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[2]+ptr.getRefData().getLocalRotation().rot[2]).valueDegrees()); } else throw std::runtime_error ("invalid ration axis: " + axis); @@ -556,27 +561,19 @@ namespace MWScript Interpreter::Type_Float rotation = (runtime[0].mFloat*MWBase::Environment::get().getFrameDuration()); runtime.pop(); - float *objRot = ptr.getRefData().getPosition().rot; - if (axis == "x") { - objRot[0]+=Ogre::Degree(rotation).valueRadians(); - - if (ptr.getRefData().getBaseNode() != 0) - MWBase::Environment::get().getWorld()->localRotateObject(ptr, rotation, Ogre::Vector3::UNIT_X); + ptr.getRefData().getLocalRotation().rot[0]+=rotation; + MWBase::Environment::get().getWorld()->localRotateObject(ptr, rotation, Ogre::Vector3::UNIT_X); } else if (axis == "y") { - objRot[1]+=Ogre::Degree(rotation).valueRadians(); - - if (ptr.getRefData().getBaseNode() != 0) + ptr.getRefData().getLocalRotation().rot[1]+=rotation; MWBase::Environment::get().getWorld()->localRotateObject(ptr, rotation, Ogre::Vector3::UNIT_Y); } else if (axis == "z") { - objRot[2]+=Ogre::Degree(rotation).valueRadians(); - - if (ptr.getRefData().getBaseNode() != 0) + ptr.getRefData().getLocalRotation().rot[2]+=rotation; MWBase::Environment::get().getWorld()->localRotateObject(ptr, rotation, Ogre::Vector3::UNIT_Z); } diff --git a/apps/openmw/mwworld/refdata.cpp b/apps/openmw/mwworld/refdata.cpp index 4be2878104..db565c4513 100644 --- a/apps/openmw/mwworld/refdata.cpp +++ b/apps/openmw/mwworld/refdata.cpp @@ -19,6 +19,7 @@ namespace MWWorld mEnabled = refData.mEnabled; mCount = refData.mCount; mPosition = refData.mPosition; + mLocalRotation = refData.mLocalRotation; mCustomData = refData.mCustomData ? refData.mCustomData->clone() : 0; } @@ -34,7 +35,11 @@ namespace MWWorld RefData::RefData (const ESM::CellRef& cellRef) : mBaseNode(0), mHasLocals (false), mEnabled (true), mCount (1), mPosition (cellRef.mPos), mCustomData (0) - {} + { + mLocalRotation.rot[0]=0; + mLocalRotation.rot[1]=0; + mLocalRotation.rot[2]=0; + } RefData::RefData (const RefData& refData) : mBaseNode(0), mCustomData (0) @@ -141,6 +146,11 @@ namespace MWWorld return mPosition; } + LocalRotation& RefData::getLocalRotation() + { + return mLocalRotation; + } + void RefData::setCustomData (CustomData *data) { delete mCustomData; diff --git a/apps/openmw/mwworld/refdata.hpp b/apps/openmw/mwworld/refdata.hpp index 3a6e0fc9fd..c3aa647ec2 100644 --- a/apps/openmw/mwworld/refdata.hpp +++ b/apps/openmw/mwworld/refdata.hpp @@ -5,6 +5,8 @@ #include "../mwscript/locals.hpp" +#include + namespace Ogre { class SceneNode; @@ -18,6 +20,10 @@ namespace ESM namespace MWWorld { + struct LocalRotation{ + float rot[3]; + }; + class CustomData; class RefData @@ -34,6 +40,8 @@ namespace MWWorld ESM::Position mPosition; + LocalRotation mLocalRotation; + CustomData *mCustomData; void copy (const RefData& refData); @@ -78,6 +86,8 @@ namespace MWWorld ESM::Position& getPosition(); + LocalRotation& getLocalRotation(); + void setCustomData (CustomData *data); ///< Set custom data (potentially replacing old custom data). The ownership of \æ data is /// transferred to this. diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 439f761311..b11b59ac62 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -50,6 +50,13 @@ 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); + 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 52d0d953a0..69bcad619d 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -826,8 +826,10 @@ namespace MWWorld void World::localRotateObject (const Ptr& ptr, float rotation, Ogre::Vector3 axis) { - ptr.getRefData().getBaseNode()->rotate(Ogre::Quaternion(Ogre::Radian(Ogre::Degree(-rotation).valueRadians()), axis)); - mPhysics->rotateObject(ptr); + if (ptr.getRefData().getBaseNode() != 0) { + ptr.getRefData().getBaseNode()->rotate(Ogre::Quaternion(Ogre::Radian(Ogre::Degree(-rotation).valueRadians()), axis)); + mPhysics->rotateObject(ptr); + } } void World::adjustPosition(const Ptr &ptr) From 1fd59d0ce0c63e893f6203a723579d25dc3ec7c9 Mon Sep 17 00:00:00 2001 From: Glorf Date: Tue, 16 Apr 2013 21:21:54 +0200 Subject: [PATCH 06/12] Removed useless include --- apps/openmw/mwworld/refdata.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/openmw/mwworld/refdata.hpp b/apps/openmw/mwworld/refdata.hpp index c3aa647ec2..77ceb3721a 100644 --- a/apps/openmw/mwworld/refdata.hpp +++ b/apps/openmw/mwworld/refdata.hpp @@ -5,8 +5,6 @@ #include "../mwscript/locals.hpp" -#include - namespace Ogre { class SceneNode; From e3a9f73eb6008159b3ba1fa1fa15451050360407 Mon Sep 17 00:00:00 2001 From: Glorf Date: Tue, 16 Apr 2013 21:40:34 +0200 Subject: [PATCH 07/12] Improved getangle script behaviour --- apps/openmw/mwscript/transformationextensions.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index e2d701268b..beb6c3d8c1 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -153,15 +153,15 @@ namespace MWScript if (axis=="x") { - runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[0]+ptr.getRefData().getLocalRotation().rot[0]).valueDegrees()); + runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees()+ptr.getRefData().getLocalRotation().rot[0]); } else if (axis=="y") { - runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[1]+ptr.getRefData().getLocalRotation().rot[1]).valueDegrees()); + runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees()+ptr.getRefData().getLocalRotation().rot[1]); } else if (axis=="z") { - runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[2]+ptr.getRefData().getLocalRotation().rot[2]).valueDegrees()); + runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[2]).valueDegrees()+ptr.getRefData().getLocalRotation().rot[2]); } else throw std::runtime_error ("invalid ration axis: " + axis); From 53fb17da10436022178562d5d573659f769e0102 Mon Sep 17 00:00:00 2001 From: Glorf Date: Wed, 24 Apr 2013 21:42:04 +0200 Subject: [PATCH 08/12] Rotation system fixes --- apps/openmw/mwscript/transformationextensions.cpp | 9 +++------ apps/openmw/mwworld/worldimp.cpp | 8 ++++++++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index beb6c3d8c1..f2179897dc 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -153,15 +153,15 @@ namespace MWScript if (axis=="x") { - runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees()+ptr.getRefData().getLocalRotation().rot[0]); + runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[0]).valueDegrees()+ptr.getRefData().getLocalRotation().rot[0]); } else if (axis=="y") { - runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees()+ptr.getRefData().getLocalRotation().rot[1]); + runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[1]).valueDegrees()+ptr.getRefData().getLocalRotation().rot[1]); } else if (axis=="z") { - runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[2]).valueDegrees()+ptr.getRefData().getLocalRotation().rot[2]); + runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[2]).valueDegrees()+ptr.getRefData().getLocalRotation().rot[2]); } else throw std::runtime_error ("invalid ration axis: " + axis); @@ -563,17 +563,14 @@ namespace MWScript if (axis == "x") { - ptr.getRefData().getLocalRotation().rot[0]+=rotation; MWBase::Environment::get().getWorld()->localRotateObject(ptr, rotation, Ogre::Vector3::UNIT_X); } else if (axis == "y") { - ptr.getRefData().getLocalRotation().rot[1]+=rotation; MWBase::Environment::get().getWorld()->localRotateObject(ptr, rotation, Ogre::Vector3::UNIT_Y); } else if (axis == "z") { - ptr.getRefData().getLocalRotation().rot[2]+=rotation; MWBase::Environment::get().getWorld()->localRotateObject(ptr, rotation, Ogre::Vector3::UNIT_Z); } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 69bcad619d..aa9107c6ec 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -827,6 +827,14 @@ namespace MWWorld void World::localRotateObject (const Ptr& ptr, float rotation, Ogre::Vector3 axis) { 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().getBaseNode()->rotate(Ogre::Quaternion(Ogre::Radian(Ogre::Degree(-rotation).valueRadians()), axis)); mPhysics->rotateObject(ptr); } From 7cd4dd0c910b014d4d3b35e35ea71bf07021c2f6 Mon Sep 17 00:00:00 2001 From: Glorf Date: Thu, 25 Apr 2013 19:14:10 +0200 Subject: [PATCH 09/12] Improved local rotations --- apps/openmw/mwbase/world.hpp | 2 +- .../mwscript/transformationextensions.cpp | 42 ++++++++++--------- apps/openmw/mwworld/scene.cpp | 10 ++--- apps/openmw/mwworld/worldimp.cpp | 23 ++++++---- apps/openmw/mwworld/worldimp.hpp | 2 +- 5 files changed, 44 insertions(+), 35 deletions(-) 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. From 240217ae421c1455b08459533e471482600195b9 Mon Sep 17 00:00:00 2001 From: Glorf Date: Thu, 25 Apr 2013 20:52:38 +0200 Subject: [PATCH 10/12] Fixed rotations more than 360 degrees --- apps/openmw/mwworld/worldimp.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 2f488a2304..d3190e0b5e 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -818,6 +818,22 @@ namespace MWWorld objRot[1] = rot.y; 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); } @@ -832,6 +848,22 @@ namespace MWWorld ptr.getRefData().getLocalRotation().rot[1]=Ogre::Degree(y).valueRadians(); ptr.getRefData().getLocalRotation().rot[2]=Ogre::Degree(z).valueRadians(); + float fullRotateRad=Ogre::Degree(360).valueRadians(); + + while(ptr.getRefData().getLocalRotation().rot[0]>=fullRotateRad) + ptr.getRefData().getLocalRotation().rot[0]-=fullRotateRad; + while(ptr.getRefData().getLocalRotation().rot[1]>=fullRotateRad) + ptr.getRefData().getLocalRotation().rot[1]-=fullRotateRad; + while(ptr.getRefData().getLocalRotation().rot[2]>=fullRotateRad) + ptr.getRefData().getLocalRotation().rot[2]-=fullRotateRad; + + while(ptr.getRefData().getLocalRotation().rot[0]<=-fullRotateRad) + ptr.getRefData().getLocalRotation().rot[0]+=fullRotateRad; + while(ptr.getRefData().getLocalRotation().rot[1]<=-fullRotateRad) + ptr.getRefData().getLocalRotation().rot[1]+=fullRotateRad; + while(ptr.getRefData().getLocalRotation().rot[2]<=-fullRotateRad) + ptr.getRefData().getLocalRotation().rot[2]+=fullRotateRad; + float *worldRot = ptr.getRefData().getPosition().rot; Ogre::Quaternion worldRotQuat(Ogre::Quaternion(Ogre::Radian(-worldRot[0]), Ogre::Vector3::UNIT_X)* From a373f539886e1d1752f9b354f465badbd2289da9 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 26 Apr 2013 02:02:51 +0200 Subject: [PATCH 11/12] Added SetAtStart --- apps/openmw/mwscript/docs/vmformat.txt | 4 +++- .../mwscript/transformationextensions.cpp | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index b7ee2d31c6..e201d13f74 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -322,5 +322,7 @@ op 0x20001ff: Rotate op 0x2000200: Rotate, explicit reference op 0x2000201: RotateWorld op 0x2000202: RotateWorld, explicit reference +op 0x2000203: SetAtStart +op 0x2000204: SetAtStart, explicit -opcodes 0x2000203-0x3ffffff unused +opcodes 0x2000205-0x3ffffff unused diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index 617d496ffd..cb06faea79 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -620,6 +620,24 @@ namespace MWScript } }; + template + class OpSetAtStart : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + ptr.getRefData().getLocalRotation().rot[0] = 0; + ptr.getRefData().getLocalRotation().rot[1] = 0; + ptr.getRefData().getLocalRotation().rot[2] = 0; + MWBase::Environment::get().getWorld()->rotateObject(ptr, 0,0,0,true); + MWBase::Environment::get().getWorld()->moveObject(ptr, ptr.getCellRef().mPos.pos[0], + ptr.getCellRef().mPos.pos[1], ptr.getCellRef().mPos.pos[2]); + + } + }; + const int opcodeSetScale = 0x2000164; const int opcodeSetScaleExplicit = 0x2000165; const int opcodeSetAngle = 0x2000166; @@ -650,6 +668,8 @@ namespace MWScript const int opcodeRotateExplicit = 0x2000200; const int opcodeRotateWorld = 0x2000201; const int opcodeRotateWorldExplicit = 0x2000202; + const int opcodeSetAtStart = 0x2000203; + const int opcodeSetAtStartExplicit = 0x2000204; void registerExtensions (Compiler::Extensions& extensions) { @@ -669,6 +689,7 @@ namespace MWScript extensions.registerInstruction("modscale","f",opcodeModScale,opcodeModScaleExplicit); extensions.registerInstruction("rotate","cf",opcodeRotate,opcodeRotateExplicit); extensions.registerInstruction("rotateworld","cf",opcodeRotateWorld,opcodeRotateWorldExplicit); + extensions.registerInstruction("setatstart","",opcodeSetAtStart,opcodeSetAtStartExplicit); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -702,6 +723,8 @@ namespace MWScript interpreter.installSegment5(opcodeRotateExplicit,new OpRotate); interpreter.installSegment5(opcodeRotateWorld,new OpRotateWorld); interpreter.installSegment5(opcodeRotateWorldExplicit,new OpRotateWorld); + interpreter.installSegment5(opcodeSetAtStart,new OpSetAtStart); + interpreter.installSegment5(opcodeSetAtStartExplicit,new OpSetAtStart); } } } From 7821610ec60df01710d5762d8b3708634e88204a Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 26 Apr 2013 02:08:53 +0200 Subject: [PATCH 12/12] Make OnDeath work with explicit reference --- apps/openmw/mwscript/docs/vmformat.txt | 3 ++- apps/openmw/mwscript/statsextensions.cpp | 14 ++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index e201d13f74..3abd14c782 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -324,5 +324,6 @@ op 0x2000201: RotateWorld op 0x2000202: RotateWorld, explicit reference op 0x2000203: SetAtStart op 0x2000204: SetAtStart, explicit +op 0x2000205: OnDeath, explicit -opcodes 0x2000205-0x3ffffff unused +opcodes 0x2000206-0x3ffffff unused diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 1d321fbbb7..04e89edc66 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -1025,16 +1025,14 @@ namespace MWScript } }; + template class OpOnDeath : public Interpreter::Opcode0 { public: virtual void execute (Interpreter::Runtime& runtime) { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - - MWWorld::Ptr ptr = context.getReference(); + MWWorld::Ptr ptr = R()(runtime); Interpreter::Type_Integer value = MWWorld::Class::get (ptr).getCreatureStats (ptr).hasDied(); @@ -1146,9 +1144,8 @@ namespace MWScript const int opcodeRaiseRankExplicit = 0x20001e9; const int opcodeLowerRank = 0x20001ea; const int opcodeLowerRankExplicit = 0x20001eb; - const int opcodeOnDeath = 0x20001fc; - + const int opcodeOnDeathExplicit = 0x2000205; const int opcodeIsWerewolf = 0x20001fd; const int opcodeIsWerewolfExplicit = 0x20001fe; @@ -1266,7 +1263,7 @@ namespace MWScript extensions.registerInstruction ("raiserank", "", opcodeRaiseRank, opcodeRaiseRankExplicit); extensions.registerInstruction ("lowerrank", "", opcodeLowerRank, opcodeLowerRankExplicit); - extensions.registerFunction ("ondeath", 'l', "", opcodeOnDeath); + extensions.registerFunction ("ondeath", 'l', "", opcodeOnDeath, opcodeOnDeathExplicit); extensions.registerFunction ("iswerewolf", 'l', "", opcodeIsWerewolf, opcodeIsWerewolfExplicit); } @@ -1384,7 +1381,8 @@ namespace MWScript interpreter.installSegment5 (opcodeLowerRank, new OpLowerRank); interpreter.installSegment5 (opcodeLowerRankExplicit, new OpLowerRank); - interpreter.installSegment5 (opcodeOnDeath, new OpOnDeath); + interpreter.installSegment5 (opcodeOnDeath, new OpOnDeath); + interpreter.installSegment5 (opcodeOnDeathExplicit, new OpOnDeath); interpreter.installSegment5 (opcodeIsWerewolf, new OpIsWerewolf); interpreter.installSegment5 (opcodeIsWerewolfExplicit, new OpIsWerewolf);