diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index 7b6df1e1b..9fb7db09a 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -543,6 +543,10 @@ namespace MWScript { boost::shared_ptr action = (ptr.getClass().activate(ptr, actor)); action->execute (actor); + if (action->getTarget() != MWWorld::Ptr() && action->getTarget() != ptr) + { + updatePtr(ptr, action->getTarget()); + } } float InterpreterContext::getSecondsPassed() const @@ -657,6 +661,9 @@ namespace MWScript void InterpreterContext::updatePtr(const MWWorld::Ptr& base, const MWWorld::Ptr& updated) { if (!mReference.isEmpty() && base == mReference) + { mReference = updated; + mLocals = &mReference.getRefData().getLocals(); + } } } diff --git a/apps/openmw/mwworld/action.cpp b/apps/openmw/mwworld/action.cpp index c29377ecb..5663ba38f 100644 --- a/apps/openmw/mwworld/action.cpp +++ b/apps/openmw/mwworld/action.cpp @@ -12,6 +12,11 @@ const MWWorld::Ptr& MWWorld::Action::getTarget() const return mTarget; } +void MWWorld::Action::setTarget(const MWWorld::Ptr& target) +{ + mTarget = target; +} + MWWorld::Action::Action (bool keepSound, const Ptr& target) : mKeepSound (keepSound), mSoundOffset(0), mTarget (target) {} diff --git a/apps/openmw/mwworld/action.hpp b/apps/openmw/mwworld/action.hpp index 38907cf44..6b4dff6aa 100644 --- a/apps/openmw/mwworld/action.hpp +++ b/apps/openmw/mwworld/action.hpp @@ -23,10 +23,12 @@ namespace MWWorld protected: - const Ptr& getTarget() const; + void setTarget(const Ptr&); public: + const Ptr& getTarget() const; + Action (bool keepSound = false, const Ptr& target = Ptr()); ///< \param keepSound Keep playing the sound even if the object the sound is played on is removed. diff --git a/apps/openmw/mwworld/actiontake.cpp b/apps/openmw/mwworld/actiontake.cpp index 320e45653..e7aab6da2 100644 --- a/apps/openmw/mwworld/actiontake.cpp +++ b/apps/openmw/mwworld/actiontake.cpp @@ -23,7 +23,7 @@ namespace MWWorld { MWBase::Environment::get().getMechanicsManager()->itemTaken( actor, getTarget(), MWWorld::Ptr(), getTarget().getRefData().getCount()); - actor.getClass().getContainerStore (actor).add (getTarget(), getTarget().getRefData().getCount(), actor); + MWWorld::Ptr newitem = *actor.getClass().getContainerStore (actor).add (getTarget(), getTarget().getRefData().getCount(), actor); // Added by tes3mp mwmp::WorldEvent *event = mwmp::Main::get().getNetworking()->createWorldEvent(); @@ -41,5 +41,6 @@ namespace MWWorld mwmp::Main::get().getLocalPlayer()->sendInventory(); MWBase::Environment::get().getWorld()->deleteObject (getTarget()); + setTarget(newitem); } } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 52b45d2d5..4fadcc70d 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1503,8 +1503,6 @@ namespace MWWorld float diff = duration * osg::DegreesToRadians(90.f); float targetRot = std::min(std::max(minRot, oldRot + diff * (it->second == 1 ? 1 : -1)), maxRot); rotateObject(it->first, objPos.rot[0], objPos.rot[1], targetRot); - // the rotation order we want to use - mWorldScene->updateObjectRotation(it->first, false); bool reached = (targetRot == maxRot && it->second) || targetRot == minRot; @@ -1528,6 +1526,9 @@ namespace MWWorld } } + // the rotation order we want to use + mWorldScene->updateObjectRotation(it->first, false); + if (reached) { // Mark as non-moving diff --git a/components/myguiplatform/myguirendermanager.cpp b/components/myguiplatform/myguirendermanager.cpp index 9d1f7100f..5ab7ab736 100644 --- a/components/myguiplatform/myguirendermanager.cpp +++ b/components/myguiplatform/myguirendermanager.cpp @@ -210,7 +210,7 @@ public: osg::ref_ptr mVertexBuffer; // need to hold on to this too as the mVertexBuffer does not hold a ref to its own array - osg::ref_ptr mArray; + osg::ref_ptr mArray; // optional osg::ref_ptr mStateSet; @@ -244,21 +244,25 @@ private: class OSGVertexBuffer : public MyGUI::IVertexBuffer { - osg::ref_ptr mBuffer; - osg::ref_ptr mVertexArray; + osg::ref_ptr mBuffer[2]; + osg::ref_ptr mVertexArray[2]; size_t mNeedVertexCount; - bool mQueuedForDrawing; + unsigned int mCurrentBuffer; + bool mUsed; // has the mCurrentBuffer been submitted to the rendering thread void destroy(); - void create(); + osg::UByteArray* create(); public: OSGVertexBuffer(); - virtual ~OSGVertexBuffer(); + virtual ~OSGVertexBuffer() {} - void markAsQueuedForDrawing(); + void markUsed(); + + osg::Array* getVertexArray(); + osg::VertexBufferObject* getVertexBuffer(); virtual void setVertexCount(size_t count); virtual size_t getVertexCount(); @@ -266,26 +270,18 @@ public: virtual MyGUI::Vertex *lock(); virtual void unlock(); -/*internal:*/ - - osg::VertexBufferObject *getBuffer() const { return mBuffer.get(); } - osg::UByteArray *getArray() const { return mVertexArray.get(); } }; OSGVertexBuffer::OSGVertexBuffer() : mNeedVertexCount(0) - , mQueuedForDrawing(false) + , mCurrentBuffer(0) + , mUsed(false) { } -OSGVertexBuffer::~OSGVertexBuffer() +void OSGVertexBuffer::markUsed() { - destroy(); -} - -void OSGVertexBuffer::markAsQueuedForDrawing() -{ - mQueuedForDrawing = true; + mUsed = true; } void OSGVertexBuffer::setVertexCount(size_t count) @@ -303,48 +299,51 @@ size_t OSGVertexBuffer::getVertexCount() MyGUI::Vertex *OSGVertexBuffer::lock() { - if (mQueuedForDrawing || !mVertexArray) + if (mUsed) { - // Force recreating the buffer, to make sure we are not modifying a buffer currently - // queued for rendering in the last frame's draw thread. - // a more efficient solution might be double buffering - destroy(); - create(); - mQueuedForDrawing = false; + mCurrentBuffer = (mCurrentBuffer+1)%2; + mUsed = false; } - else + osg::UByteArray* array = mVertexArray[mCurrentBuffer]; + if (!array) { - mVertexArray->resize(mNeedVertexCount * sizeof(MyGUI::Vertex)); + array = create(); + } + else if (array->size() != mNeedVertexCount * sizeof(MyGUI::Vertex)) + { + array->resize(mNeedVertexCount * sizeof(MyGUI::Vertex)); } - MYGUI_PLATFORM_ASSERT(mBuffer.valid(), "Vertex buffer is not created"); - - return (MyGUI::Vertex*)&(*mVertexArray)[0]; + return (MyGUI::Vertex*)&(*array)[0]; } void OSGVertexBuffer::unlock() { - mVertexArray->dirty(); - mBuffer->dirty(); + mVertexArray[mCurrentBuffer]->dirty(); + mBuffer[mCurrentBuffer]->dirty(); } -void OSGVertexBuffer::destroy() +osg::UByteArray* OSGVertexBuffer::create() { - mBuffer = nullptr; - mVertexArray = nullptr; -} + mVertexArray[mCurrentBuffer] = new osg::UByteArray(mNeedVertexCount*sizeof(MyGUI::Vertex)); -void OSGVertexBuffer::create() -{ - MYGUI_PLATFORM_ASSERT(!mBuffer.valid(), "Vertex buffer already exist"); - - mVertexArray = new osg::UByteArray(mNeedVertexCount*sizeof(MyGUI::Vertex)); - - mBuffer = new osg::VertexBufferObject; - mBuffer->setDataVariance(osg::Object::DYNAMIC); - mBuffer->setUsage(GL_DYNAMIC_DRAW); + mBuffer[mCurrentBuffer] = new osg::VertexBufferObject; + mBuffer[mCurrentBuffer]->setDataVariance(osg::Object::DYNAMIC); + mBuffer[mCurrentBuffer]->setUsage(GL_DYNAMIC_DRAW); // NB mBuffer does not own the array - mBuffer->setArray(0, mVertexArray.get()); + mBuffer[mCurrentBuffer]->setArray(0, mVertexArray[mCurrentBuffer].get()); + + return mVertexArray[mCurrentBuffer]; +} + +osg::Array* OSGVertexBuffer::getVertexArray() +{ + return mVertexArray[mCurrentBuffer]; +} + +osg::VertexBufferObject* OSGVertexBuffer::getVertexBuffer() +{ + return mBuffer[mCurrentBuffer]; } // --------------------------------------------------------------------------- @@ -438,9 +437,9 @@ void RenderManager::doRender(MyGUI::IVertexBuffer *buffer, MyGUI::ITexture *text { Drawable::Batch batch; batch.mVertexCount = count; - batch.mVertexBuffer = static_cast(buffer)->getBuffer(); - static_cast(buffer)->markAsQueuedForDrawing(); - batch.mArray = static_cast(buffer)->getArray(); + batch.mVertexBuffer = static_cast(buffer)->getVertexBuffer(); + batch.mArray = static_cast(buffer)->getVertexArray(); + static_cast(buffer)->markUsed(); if (texture) { batch.mTexture = static_cast(texture)->getTexture();