diff --git a/apps/openmw/mwgui/itemwidget.cpp b/apps/openmw/mwgui/itemwidget.cpp index fe7cb79de..a31eb9c76 100644 --- a/apps/openmw/mwgui/itemwidget.cpp +++ b/apps/openmw/mwgui/itemwidget.cpp @@ -67,20 +67,30 @@ namespace MWGui void ItemWidget::setIcon(const std::string &icon) { - if (mItemShadow) - mItemShadow->setImageTexture(icon); - if (mItem) - mItem->setImageTexture(icon); + if (mCurrentIcon != icon) + { + mCurrentIcon = icon; + + if (mItemShadow) + mItemShadow->setImageTexture(icon); + if (mItem) + mItem->setImageTexture(icon); + } } void ItemWidget::setFrame(const std::string &frame, const MyGUI::IntCoord &coord) { if (mFrame) { - mFrame->setImageTexture(frame); mFrame->setImageTile(MyGUI::IntSize(coord.width, coord.height)); // Why is this needed? MyGUI bug? mFrame->setImageCoord(coord); } + + if (mCurrentFrame != frame) + { + mCurrentFrame = frame; + mFrame->setImageTexture(frame); + } } void ItemWidget::setIcon(const MWWorld::Ptr &ptr) @@ -105,6 +115,8 @@ namespace MWGui mItemShadow->setImageTexture(""); mItem->setImageTexture(""); mText->setCaption(""); + mCurrentIcon.clear(); + mCurrentFrame.clear(); return; } diff --git a/apps/openmw/mwgui/itemwidget.hpp b/apps/openmw/mwgui/itemwidget.hpp index ce9f58f50..dd1717d11 100644 --- a/apps/openmw/mwgui/itemwidget.hpp +++ b/apps/openmw/mwgui/itemwidget.hpp @@ -47,6 +47,9 @@ namespace MWGui MyGUI::ImageBox* mItemShadow; MyGUI::ImageBox* mFrame; MyGUI::TextBox* mText; + + std::string mCurrentIcon; + std::string mCurrentFrame; }; } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index e337ad039..3aa7a27e6 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -401,7 +401,6 @@ namespace MWMechanics { updateDrowning(ptr, duration); calculateNpcStatModifiers(ptr, duration); - updateEquippedLight(ptr, duration); } void Actors::adjustMagicEffects (const MWWorld::Ptr& creature) @@ -738,11 +737,19 @@ namespace MWMechanics } } - UpdateSummonedCreatures updateSummonedCreatures(ptr); - creatureStats.getActiveSpells().visitEffectSources(updateSummonedCreatures); - if (ptr.getClass().hasInventoryStore(ptr)) - ptr.getClass().getInventoryStore(ptr).visitEffectSources(updateSummonedCreatures); - updateSummonedCreatures.process(); + bool hasSummonEffect = false; + for (MagicEffects::Collection::const_iterator it = effects.begin(); it != effects.end(); ++it) + if (it->first.mId >= ESM::MagicEffect::SummonScamp && it->first.mId <= ESM::MagicEffect::SummonStormAtronach) + hasSummonEffect = true; + + if (!creatureStats.getSummonedCreatureMap().empty() || !creatureStats.getSummonedCreatureGraveyard().empty() || hasSummonEffect) + { + UpdateSummonedCreatures updateSummonedCreatures(ptr); + creatureStats.getActiveSpells().visitEffectSources(updateSummonedCreatures); + if (ptr.getClass().hasInventoryStore(ptr)) + ptr.getClass().getInventoryStore(ptr).visitEffectSources(updateSummonedCreatures); + updateSummonedCreatures.process(); + } } void Actors::calculateNpcStatModifiers (const MWWorld::Ptr& ptr, float duration) @@ -1027,10 +1034,13 @@ namespace MWMechanics { static float timerUpdateAITargets = 0; static float timerUpdateHeadTrack = 0; + static float timerUpdateEquippedLight = 0; + const float updateEquippedLightInterval = 1.0f; // target lists get updated once every 1.0 sec if (timerUpdateAITargets >= 1.0f) timerUpdateAITargets = 0; if (timerUpdateHeadTrack >= 0.3f) timerUpdateHeadTrack = 0; + if (timerUpdateEquippedLight >= updateEquippedLightInterval) timerUpdateEquippedLight = 0; MWWorld::Ptr player = getPlayer(); @@ -1116,7 +1126,12 @@ namespace MWMechanics } if(iter->first.getTypeName() == typeid(ESM::NPC).name()) + { updateNpc(iter->first, duration); + + if (timerUpdateEquippedLight == 0) + updateEquippedLight(iter->first, updateEquippedLightInterval); + } } } diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 5f7910ab5..d35ddb8be 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1882,10 +1882,14 @@ void CharacterController::update(float duration) { if(mHitState != CharState_KnockDown && mHitState != CharState_KnockOut) { - world->rotateObject(mPtr, rot.x(), rot.y(), rot.z(), true); + if (rot != osg::Vec3f()) + world->rotateObject(mPtr, rot.x(), rot.y(), rot.z(), true); } else //avoid z-rotating for knockdown - world->rotateObject(mPtr, rot.x(), rot.y(), 0.0f, true); + { + if (rot.x() != 0 && rot.y() != 0) + world->rotateObject(mPtr, rot.x(), rot.y(), 0.0f, true); + } if (!mMovementAnimationControlled) world->queueMovement(mPtr, vec); diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index d0806b511..cdbeffa19 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -575,6 +575,8 @@ namespace MWRender mAccumCtrl = NULL; mAnimSources.clear(); + + mAnimVelocities.clear(); } bool Animation::hasAnimation(const std::string &anim) const @@ -952,6 +954,10 @@ namespace MWRender if (!mAccumRoot) return 0.0f; + std::map::const_iterator found = mAnimVelocities.find(groupname); + if (found != mAnimVelocities.end()) + return found->second; + // Look in reverse; last-inserted source has priority. AnimSourceList::const_reverse_iterator animsrc(mAnimSources.rbegin()); for(;animsrc != mAnimSources.rend();++animsrc) @@ -999,6 +1005,8 @@ namespace MWRender } } + mAnimVelocities.insert(std::make_pair(groupname, velocity)); + return velocity; } diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 584eca614..f765a7a40 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -274,6 +274,8 @@ protected: float mAlpha; + mutable std::map mAnimVelocities; + osg::ref_ptr mLightListCallback; const NodeMap& getNodeMap() const; diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 3c05e313e..4d1c5a59f 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -32,6 +32,26 @@ namespace { + void setNodeRotation(const MWWorld::Ptr& ptr, MWRender::RenderingManager& rendering, bool inverseRotationOrder) + { + if (!ptr.getRefData().getBaseNode()) + return; + + osg::Quat worldRotQuat(ptr.getRefData().getPosition().rot[2], osg::Vec3(0,0,-1)); + if (!ptr.getClass().isActor()) + { + 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); + } + void addObject(const MWWorld::Ptr& ptr, MWPhysics::PhysicsSystem& physics, MWRender::RenderingManager& rendering) { @@ -40,6 +60,8 @@ namespace if (id == "prisonmarker" || id == "divinemarker" || id == "templemarker" || id == "northmarker") model = ""; // marker objects that have a hardcoded function in the game logic, should be hidden from the player ptr.getClass().insertObjectRendering(ptr, model, rendering); + setNodeRotation(ptr, rendering, false); + ptr.getClass().insertObject (ptr, model, physics); if (ptr.getClass().isActor()) @@ -49,23 +71,8 @@ namespace 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()) - { - 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); - } + setNodeRotation(ptr, rendering, inverseRotationOrder); + physics.updateRotation(ptr); } void updateObjectScale(const MWWorld::Ptr& ptr, MWPhysics::PhysicsSystem& physics, @@ -133,7 +140,6 @@ namespace try { addObject(ptr, mPhysics, mRendering); - updateObjectRotation(ptr, mPhysics, mRendering, false); } catch (const std::exception& e) { @@ -629,7 +635,6 @@ namespace MWWorld try { addObject(ptr, *mPhysics, mRendering); - updateObjectRotation(ptr, false); MWBase::Environment::get().getWorld()->scaleObject(ptr, ptr.getCellRef().getScale()); } catch (std::exception& e) diff --git a/files/mygui/openmw_hud_energybar.skin.xml b/files/mygui/openmw_hud_energybar.skin.xml index 640133d66..2b41b5ea9 100644 --- a/files/mygui/openmw_hud_energybar.skin.xml +++ b/files/mygui/openmw_hud_energybar.skin.xml @@ -61,14 +61,14 @@ - + - + @@ -76,7 +76,7 @@ - + @@ -84,7 +84,7 @@ - + @@ -92,7 +92,7 @@ - + @@ -100,7 +100,7 @@ - + diff --git a/files/mygui/openmw_list.skin.xml b/files/mygui/openmw_list.skin.xml index c1e8114e9..9f5b2e94d 100644 --- a/files/mygui/openmw_list.skin.xml +++ b/files/mygui/openmw_list.skin.xml @@ -9,6 +9,7 @@ + @@ -50,6 +51,7 @@ + diff --git a/files/mygui/openmw_progress.skin.xml b/files/mygui/openmw_progress.skin.xml index 71bbfe9f0..95f5b378c 100644 --- a/files/mygui/openmw_progress.skin.xml +++ b/files/mygui/openmw_progress.skin.xml @@ -54,7 +54,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -70,7 +70,7 @@ - + @@ -78,18 +78,19 @@ - + - + + - +