From c5d3e6c9935f2d0f9ec863475f316e8ea00f096d Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 22 Feb 2016 14:31:02 +0100 Subject: [PATCH 1/9] Disable preloading of levelled lists --- apps/openmw/mwclass/creaturelevlist.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwclass/creaturelevlist.cpp b/apps/openmw/mwclass/creaturelevlist.cpp index e2f29ea72..0223fb634 100644 --- a/apps/openmw/mwclass/creaturelevlist.cpp +++ b/apps/openmw/mwclass/creaturelevlist.cpp @@ -56,8 +56,9 @@ namespace MWClass void CreatureLevList::getModelsToPreload(const MWWorld::Ptr &ptr, std::vector &models) const { + // disable for now, too many false positives + /* const MWWorld::LiveCellRef *ref = ptr.get(); - for (std::vector::const_iterator it = ref->mBase->mList.begin(); it != ref->mBase->mList.end(); ++it) { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); @@ -68,6 +69,7 @@ namespace MWClass MWWorld::ManualRef ref(store, it->mId); ref.getPtr().getClass().getModelsToPreload(ref.getPtr(), models); } + */ } void CreatureLevList::insertObjectRendering(const MWWorld::Ptr &ptr, const std::string& model, MWRender::RenderingInterface &renderingInterface) const From 1667c807be651dbeb1be3055b4a5143f5e2db2c5 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 22 Feb 2016 15:21:06 +0100 Subject: [PATCH 2/9] Warn about particle emitters that have multiple parent node paths --- components/nifosg/particle.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/nifosg/particle.cpp b/components/nifosg/particle.cpp index 500339722..205b0fd54 100644 --- a/components/nifosg/particle.cpp +++ b/components/nifosg/particle.cpp @@ -267,6 +267,8 @@ void Emitter::emitParticles(double dt) const osg::Matrix psToWorld = worldMats[0]; worldToPs = osg::Matrix::inverse(psToWorld); } + if (worldMats.size() > 1) + std::cerr << "Found multiple parent node paths in particle emitter, this is not correctly supported " << std::endl; const osg::Matrix& ltw = getLocalToWorldMatrix(); osg::Matrix emitterToPs = ltw * worldToPs; From a6621626aa934207b4475ff4066387b42fbdef7b Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 22 Feb 2016 15:22:37 +0100 Subject: [PATCH 3/9] Don't use multiple parent node paths in CSVRender::Object --- apps/opencs/view/render/object.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index 33939625d..c220321d5 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -160,7 +160,6 @@ CSVRender::Object::Object (CSMWorld::Data& data, osg::Group* parentNode, mBaseNode->addCullCallback(new SceneUtil::LightListCallback); mOutline = new osgFX::Scribe; - mOutline->addChild(mBaseNode); mBaseNode->setUserData(new ObjectTag(this)); @@ -194,10 +193,14 @@ void CSVRender::Object::setSelected(bool selected) { mSelected = selected; + mOutline->removeChild(mBaseNode); mParentNode->removeChild(mOutline); mParentNode->removeChild(mBaseNode); if (selected) + { + mOutline->addChild(mBaseNode); mParentNode->addChild(mOutline); + } else mParentNode->addChild(mBaseNode); } From 055d35a2b09f5bcc6082b306fc5254779ae491fc Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 22 Feb 2016 18:10:25 +0100 Subject: [PATCH 4/9] Revert "Warn about particle emitters that have multiple parent node paths" Not working correctly because osg won't ignore camera nodes. This reverts commit 1667c807be651dbeb1be3055b4a5143f5e2db2c5. --- components/nifosg/particle.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/components/nifosg/particle.cpp b/components/nifosg/particle.cpp index 205b0fd54..500339722 100644 --- a/components/nifosg/particle.cpp +++ b/components/nifosg/particle.cpp @@ -267,8 +267,6 @@ void Emitter::emitParticles(double dt) const osg::Matrix psToWorld = worldMats[0]; worldToPs = osg::Matrix::inverse(psToWorld); } - if (worldMats.size() > 1) - std::cerr << "Found multiple parent node paths in particle emitter, this is not correctly supported " << std::endl; const osg::Matrix& ltw = getLocalToWorldMatrix(); osg::Matrix emitterToPs = ltw * worldToPs; From 8bd16e4d5ab92035974b629349c6d8f3f5bbe977 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 22 Feb 2016 18:58:19 +0100 Subject: [PATCH 5/9] Don't compute the world matrix multiple times --- apps/openmw/mwmechanics/character.cpp | 12 ++++++------ apps/openmw/mwrender/camera.cpp | 6 +++--- apps/openmw/mwrender/characterpreview.cpp | 6 +++--- apps/openmw/mwrender/rotatecontroller.cpp | 6 +++--- apps/openmw/mwrender/weaponanimation.cpp | 12 ++++++------ apps/openmw/mwworld/worldimp.cpp | 6 +++--- components/nifosg/particle.cpp | 6 +++--- components/resource/scenemanager.cpp | 6 +++--- 8 files changed, 30 insertions(+), 30 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 67707d028..2f024838d 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -2140,10 +2140,10 @@ void CharacterController::updateHeadTracking(float duration) if (!mHeadTrackTarget.isEmpty()) { - osg::MatrixList mats = head->getWorldMatrices(); - if (mats.empty()) + osg::NodePathList nodepaths = head->getParentalNodePaths(); + if (nodepaths.empty()) return; - osg::Matrixf mat = mats[0]; + osg::Matrixf mat = osg::computeLocalToWorld(nodepaths[0]); osg::Vec3f headPos = mat.getTrans(); osg::Vec3f direction; @@ -2154,9 +2154,9 @@ void CharacterController::updateHeadTracking(float duration) node = anim->getNode("Bip01 Head"); if (node != NULL) { - osg::MatrixList mats = node->getWorldMatrices(); - if (mats.size()) - direction = mats[0].getTrans() - headPos; + osg::NodePathList nodepaths = node->getParentalNodePaths(); + if (nodepaths.size()) + direction = osg::computeLocalToWorld(nodepaths[0]).getTrans() - headPos; } else // no head node to look at, fall back to look at center of collision box diff --git a/apps/openmw/mwrender/camera.cpp b/apps/openmw/mwrender/camera.cpp index 88934414f..5a3f2bea3 100644 --- a/apps/openmw/mwrender/camera.cpp +++ b/apps/openmw/mwrender/camera.cpp @@ -88,10 +88,10 @@ namespace MWRender const osg::Node* trackNode = mTrackingNode; if (!trackNode) return osg::Vec3d(); - osg::MatrixList mats = trackNode->getWorldMatrices(); - if (!mats.size()) + osg::NodePathList nodepaths = trackNode->getParentalNodePaths(); + if (nodepaths.empty()) return osg::Vec3d(); - const osg::Matrix& worldMat = mats[0]; + osg::Matrix worldMat = osg::computeLocalToWorld(nodepaths[0]); osg::Vec3d position = worldMat.getTrans(); if (!isFirstPerson()) diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index b9f20f4ea..201124447 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -365,10 +365,10 @@ namespace MWRender traverse(node, nv); // Now update camera utilizing the updated head position - osg::MatrixList mats = mNodeToFollow->getWorldMatrices(); - if (!mats.size()) + osg::NodePathList nodepaths = mNodeToFollow->getParentalNodePaths(); + if (!nodepaths.size()) return; - osg::Matrix worldMat = mats[0]; + osg::Matrix worldMat = osg::computeLocalToWorld(nodepaths[0]); osg::Vec3 headOffset = worldMat.getTrans(); cam->setViewMatrixAsLookAt(headOffset + mPosOffset, headOffset + mLookAtOffset, osg::Vec3(0,0,1)); diff --git a/apps/openmw/mwrender/rotatecontroller.cpp b/apps/openmw/mwrender/rotatecontroller.cpp index 11f5b943d..534cc7490 100644 --- a/apps/openmw/mwrender/rotatecontroller.cpp +++ b/apps/openmw/mwrender/rotatecontroller.cpp @@ -44,11 +44,11 @@ void RotateController::operator()(osg::Node *node, osg::NodeVisitor *nv) osg::Quat RotateController::getWorldOrientation(osg::Node *node) { // this could be optimized later, we just need the world orientation, not the full matrix - osg::MatrixList worldMats = node->getWorldMatrices(mRelativeTo); + osg::NodePathList nodepaths = node->getParentalNodePaths(mRelativeTo); osg::Quat worldOrient; - if (!worldMats.empty()) + if (!nodepaths.empty()) { - osg::Matrixf worldMat = worldMats[0]; + osg::Matrixf worldMat = osg::computeLocalToWorld(nodepaths[0]); worldOrient = worldMat.getRotate(); } return worldOrient; diff --git a/apps/openmw/mwrender/weaponanimation.cpp b/apps/openmw/mwrender/weaponanimation.cpp index 8fd294ccd..2627d3fc6 100644 --- a/apps/openmw/mwrender/weaponanimation.cpp +++ b/apps/openmw/mwrender/weaponanimation.cpp @@ -114,10 +114,10 @@ void WeaponAnimation::releaseArrow(MWWorld::Ptr actor, float attackStrength) osg::Node* weaponNode = getWeaponNode(); if (!weaponNode) return; - osg::MatrixList mats = weaponNode->getWorldMatrices(); - if (mats.empty()) + osg::NodePathList nodepaths = weaponNode->getParentalNodePaths(); + if (nodepaths.empty()) return; - osg::Vec3f launchPos = mats[0].getTrans(); + osg::Vec3f launchPos = osg::computeLocalToWorld(nodepaths[0]).getTrans(); float fThrownWeaponMinSpeed = gmst.find("fThrownWeaponMinSpeed")->getFloat(); float fThrownWeaponMaxSpeed = gmst.find("fThrownWeaponMaxSpeed")->getFloat(); @@ -140,10 +140,10 @@ void WeaponAnimation::releaseArrow(MWWorld::Ptr actor, float attackStrength) return; osg::ref_ptr ammoNode = mAmmunition->getNode(); - osg::MatrixList mats = ammoNode->getWorldMatrices(); - if (mats.empty()) + osg::NodePathList nodepaths = ammoNode->getParentalNodePaths(); + if (nodepaths.empty()) return; - osg::Vec3f launchPos = mats[0].getTrans(); + osg::Vec3f launchPos = osg::computeLocalToWorld(nodepaths[0]).getTrans(); float fProjectileMinSpeed = gmst.find("fProjectileMinSpeed")->getFloat(); float fProjectileMaxSpeed = gmst.find("fProjectileMaxSpeed")->getFloat(); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 98517f543..f3d80ee67 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1051,9 +1051,9 @@ namespace MWWorld if(!node) node = anim->getNode("Bip01 Head"); if(node) { - osg::MatrixList mats = node->getWorldMatrices(); - if(!mats.empty()) - return mats[0]; + osg::NodePathList nodepaths = node->getParentalNodePaths(); + if(!nodepaths.empty()) + return osg::computeLocalToWorld(nodepaths[0]); } } return osg::Matrixf::translate(actor.getRefData().getPosition().asVec3()); diff --git a/components/nifosg/particle.cpp b/components/nifosg/particle.cpp index 500339722..be2e708fb 100644 --- a/components/nifosg/particle.cpp +++ b/components/nifosg/particle.cpp @@ -261,10 +261,10 @@ void Emitter::emitParticles(double dt) osg::Matrix worldToPs; // maybe this could be optimized by halting at the lowest common ancestor of the particle and emitter nodes - osg::MatrixList worldMats = getParticleSystem()->getWorldMatrices(); - if (!worldMats.empty()) + osg::NodePathList partsysNodePaths = getParticleSystem()->getParentalNodePaths(); + if (partsysNodePaths.size()) { - const osg::Matrix psToWorld = worldMats[0]; + osg::Matrix psToWorld = osg::computeLocalToWorld(partsysNodePaths[0]); worldToPs = osg::Matrix::inverse(psToWorld); } diff --git a/components/resource/scenemanager.cpp b/components/resource/scenemanager.cpp index 9965e7767..113406ef6 100644 --- a/components/resource/scenemanager.cpp +++ b/components/resource/scenemanager.cpp @@ -69,10 +69,10 @@ namespace void transformInitialParticles(osgParticle::ParticleSystem* partsys, osg::Node* node) { - osg::MatrixList mats = node->getWorldMatrices(); - if (mats.empty()) + osg::NodePathList nodepaths = node->getParentalNodePaths(); + if (nodepaths.empty()) return; - osg::Matrixf worldMat = mats[0]; + osg::Matrixf worldMat = osg::computeLocalToWorld(nodepaths[0]); worldMat.orthoNormalize(worldMat); // scale is already applied on the particle node for (int i=0; inumParticles(); ++i) { From 90a99991d1eaca47b192e01fc4eb5cef7ae249f1 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 22 Feb 2016 19:06:12 +0100 Subject: [PATCH 6/9] Use empty() instead of !size() --- apps/openmw/mwdialogue/keywordsearch.hpp | 2 +- apps/openmw/mwgui/console.cpp | 2 +- apps/openmw/mwgui/containeritemmodel.cpp | 2 +- apps/openmw/mwmechanics/aiwander.cpp | 2 +- apps/openmw/mwmechanics/character.cpp | 2 +- apps/openmw/mwrender/characterpreview.cpp | 2 +- apps/openmw/mwrender/globalmap.cpp | 2 +- apps/openmw/mwrender/localmap.cpp | 2 +- apps/openmw/mwrender/water.cpp | 2 +- apps/openmw/mwsound/soundmanagerimp.cpp | 2 +- components/esm/loadtes3.cpp | 4 ++-- components/nifosg/nifloader.cpp | 8 ++++---- components/nifosg/particle.cpp | 2 +- components/sceneutil/lightmanager.cpp | 2 +- components/sceneutil/workqueue.cpp | 2 +- components/shader/shadervisitor.cpp | 2 +- 16 files changed, 20 insertions(+), 20 deletions(-) diff --git a/apps/openmw/mwdialogue/keywordsearch.hpp b/apps/openmw/mwdialogue/keywordsearch.hpp index 3532dc22b..f296f223f 100644 --- a/apps/openmw/mwdialogue/keywordsearch.hpp +++ b/apps/openmw/mwdialogue/keywordsearch.hpp @@ -158,7 +158,7 @@ public: } // resolve overlapping keywords - while (matches.size()) + while (!matches.empty()) { int longestKeywordSize = 0; typename std::vector::iterator longestKeyword = matches.begin(); diff --git a/apps/openmw/mwgui/console.cpp b/apps/openmw/mwgui/console.cpp index 1777d86ad..aeff7dc39 100644 --- a/apps/openmw/mwgui/console.cpp +++ b/apps/openmw/mwgui/console.cpp @@ -240,7 +240,7 @@ namespace MWGui mCommandLine->setCaption(newCaption); // List candidates if repeatedly pressing tab - if (oldCaption == newCaption && matches.size()) + if (oldCaption == newCaption && !matches.empty()) { int i = 0; printOK(""); diff --git a/apps/openmw/mwgui/containeritemmodel.cpp b/apps/openmw/mwgui/containeritemmodel.cpp index b2befc3ba..1e4749695 100644 --- a/apps/openmw/mwgui/containeritemmodel.cpp +++ b/apps/openmw/mwgui/containeritemmodel.cpp @@ -37,7 +37,7 @@ ContainerItemModel::ContainerItemModel(const std::vector& itemSour : mItemSources(itemSources) , mWorldItems(worldItems) { - assert (mItemSources.size()); + assert (!mItemSources.empty()); } ContainerItemModel::ContainerItemModel (const MWWorld::Ptr& source) diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 8231e572e..27c7f6a93 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -255,7 +255,7 @@ namespace MWMechanics // Construct a new path if there isn't one if(!storage.mPathFinder.isPathConstructed()) { - if (mAllowedNodes.size()) + if (!mAllowedNodes.empty()) { setPathToAnAllowedNode(actor, storage, pos); } diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 2f024838d..0035ebb1a 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -2155,7 +2155,7 @@ void CharacterController::updateHeadTracking(float duration) if (node != NULL) { osg::NodePathList nodepaths = node->getParentalNodePaths(); - if (nodepaths.size()) + if (!nodepaths.empty()) direction = osg::computeLocalToWorld(nodepaths[0]).getTrans() - headPos; } else diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index 201124447..c858b57b7 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -366,7 +366,7 @@ namespace MWRender // Now update camera utilizing the updated head position osg::NodePathList nodepaths = mNodeToFollow->getParentalNodePaths(); - if (!nodepaths.size()) + if (nodepaths.empty()) return; osg::Matrix worldMat = osg::computeLocalToWorld(nodepaths[0]); osg::Vec3 headOffset = worldMat.getTrans(); diff --git a/apps/openmw/mwrender/globalmap.cpp b/apps/openmw/mwrender/globalmap.cpp index 9e8a545f8..b3b6cc3b0 100644 --- a/apps/openmw/mwrender/globalmap.cpp +++ b/apps/openmw/mwrender/globalmap.cpp @@ -402,7 +402,7 @@ namespace MWRender || bounds.mMinY > bounds.mMaxY) throw std::runtime_error("invalid map bounds"); - if (!map.mImageData.size()) + if (map.mImageData.empty()) return; Files::IMemStream istream(&map.mImageData[0], map.mImageData.size()); diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index be477735f..8340ab78a 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -632,7 +632,7 @@ void LocalMap::MapSegment::initFogOfWar() void LocalMap::MapSegment::loadFogOfWar(const ESM::FogTexture &esm) { const std::vector& data = esm.mImageData; - if (!data.size()) + if (data.empty()) { initFogOfWar(); return; diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index a410527de..0a379e50a 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -566,7 +566,7 @@ void Water::createSimpleWaterStateSet(osg::Node* node, float alpha) textures.push_back(tex); } - if (!textures.size()) + if (textures.empty()) return; float fps = mFallback->getFallbackFloat("Water_SurfaceFPS"); diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index e8ceaa40f..ae8601594 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -366,7 +366,7 @@ namespace MWSound else filelist = mMusicFiles[mCurrentPlaylist]; - if(!filelist.size()) + if(filelist.empty()) return; int i = Misc::Rng::rollDice(filelist.size()); diff --git a/components/esm/loadtes3.cpp b/components/esm/loadtes3.cpp index df35a2579..60d411fc6 100644 --- a/components/esm/loadtes3.cpp +++ b/components/esm/loadtes3.cpp @@ -53,14 +53,14 @@ void ESM::Header::load (ESMReader &esm) { esm.getSubHeader(); mSCRD.resize(esm.getSubSize()); - if (mSCRD.size()) + if (!mSCRD.empty()) esm.getExact(&mSCRD[0], mSCRD.size()); } if (esm.isNextSub("SCRS")) { esm.getSubHeader(); mSCRS.resize(esm.getSubSize()); - if (mSCRS.size()) + if (!mSCRS.empty()) esm.getExact(&mSCRS[0], mSCRS.size()); } } diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 0b49419ff..975d6d6e0 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -962,7 +962,7 @@ namespace NifOsg if (uvSet >= (int)data->uvlist.size()) { std::cerr << "Warning: out of bounds UV set " << uvSet << " on TriShape \"" << triShape->name << "\" in " << mFilename << std::endl; - if (data->uvlist.size()) + if (!data->uvlist.empty()) geometry->setTexCoordArray(textureStage, data->uvlist[0]); continue; } @@ -1040,7 +1040,7 @@ namespace NifOsg triShapeToGeometry(triShape, morphGeom, parentNode, composite, boundTextures, animflags); const std::vector& morphs = morpher->data.getPtr()->mMorphs; - if (!morphs.size()) + if (morphs.empty()) return morphGeom; // Note we are not interested in morph 0, which just contains the original vertices for (unsigned int i = 1; i < morphs.size(); ++i) @@ -1228,7 +1228,7 @@ namespace NifOsg return NULL; } - if (!pixelData->mipmaps.size()) + if (pixelData->mipmaps.empty()) return NULL; unsigned char* data = new unsigned char[pixelData->data.size()]; @@ -1274,7 +1274,7 @@ namespace NifOsg void handleTextureProperty(const Nif::NiTexturingProperty* texprop, osg::StateSet* stateset, SceneUtil::CompositeStateSetUpdater* composite, Resource::ImageManager* imageManager, std::vector& boundTextures, int animflags) { - if (boundTextures.size()) + if (!boundTextures.empty()) { // overriding a parent NiTexturingProperty, so remove what was previously bound for (unsigned int i=0; igetParentalNodePaths(); - if (partsysNodePaths.size()) + if (!partsysNodePaths.empty()) { osg::Matrix psToWorld = osg::computeLocalToWorld(partsysNodePaths[0]); worldToPs = osg::Matrix::inverse(psToWorld); diff --git a/components/sceneutil/lightmanager.cpp b/components/sceneutil/lightmanager.cpp index 3950d0aea..da29647c2 100644 --- a/components/sceneutil/lightmanager.cpp +++ b/components/sceneutil/lightmanager.cpp @@ -351,7 +351,7 @@ namespace SceneUtil mLightList.push_back(&l); } } - if (mLightList.size()) + if (!mLightList.empty()) { unsigned int maxLights = static_cast (8 - mLightManager->getStartLight()); diff --git a/components/sceneutil/workqueue.cpp b/components/sceneutil/workqueue.cpp index bb1d1f1f7..bbd9f4840 100644 --- a/components/sceneutil/workqueue.cpp +++ b/components/sceneutil/workqueue.cpp @@ -87,7 +87,7 @@ osg::ref_ptr WorkQueue::removeWorkItem() { mCondition.wait(&mMutex); } - if (mQueue.size()) + if (!mQueue.empty()) { osg::ref_ptr item = mQueue.front(); mQueue.pop(); diff --git a/components/shader/shadervisitor.cpp b/components/shader/shadervisitor.cpp index 46d4edf44..c88200759 100644 --- a/components/shader/shadervisitor.cpp +++ b/components/shader/shadervisitor.cpp @@ -103,7 +103,7 @@ namespace Shader if (mAllowedToModifyStateSets) writableStateSet = node.getStateSet(); const osg::StateSet::TextureAttributeList& texAttributes = stateset->getTextureAttributeList(); - if (texAttributes.size()) + if (!texAttributes.empty()) { const osg::Texture* diffuseMap = NULL; const osg::Texture* normalMap = NULL; From 5cdee454ef0d2ab6f39778a94b8f9f5121430f4b Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 22 Feb 2016 19:13:56 +0100 Subject: [PATCH 7/9] Fix degree/radians mixup (Fixes #3213) --- apps/openmw/mwscript/transformationextensions.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index 64c126de1..95e2deee9 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -318,8 +318,8 @@ namespace MWScript ptr = MWBase::Environment::get().getWorld()->moveObject(ptr,store,x,y,z); dynamic_cast(runtime.getContext()).updatePtr(base,ptr); - float ax = osg::RadiansToDegrees(ptr.getRefData().getPosition().rot[0]); - float ay = osg::RadiansToDegrees(ptr.getRefData().getPosition().rot[1]); + float ax = ptr.getRefData().getPosition().rot[0]; + float ay = ptr.getRefData().getPosition().rot[1]; // Note that you must specify ZRot in minutes (1 degree = 60 minutes; north = 0, east = 5400, south = 10800, west = 16200) // except for when you position the player, then degrees must be used. // See "Morrowind Scripting for Dummies (9th Edition)" pages 50 and 54 for reference. @@ -374,14 +374,14 @@ namespace MWScript } dynamic_cast(runtime.getContext()).updatePtr(base,ptr); - float ax = osg::RadiansToDegrees(ptr.getRefData().getPosition().rot[0]); - float ay = osg::RadiansToDegrees(ptr.getRefData().getPosition().rot[1]); + float ax = ptr.getRefData().getPosition().rot[0]; + float ay = ptr.getRefData().getPosition().rot[1]; // Note that you must specify ZRot in minutes (1 degree = 60 minutes; north = 0, east = 5400, south = 10800, west = 16200) // except for when you position the player, then degrees must be used. // See "Morrowind Scripting for Dummies (9th Edition)" pages 50 and 54 for reference. if(ptr != MWMechanics::getPlayer()) zRot = zRot/60.0f; - MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,zRot); + MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,osg::DegreesToRadians(zRot)); ptr.getClass().adjustPosition(ptr, false); } }; From d05603c7fe0bf59b976b463cdca5fae05d17dc8c Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 22 Feb 2016 19:37:19 +0100 Subject: [PATCH 8/9] Directly apply On Target 'When Strikes' enchantments instead of launching a projectile (Fixes #3212) --- apps/openmw/mwclass/creature.cpp | 13 +------- apps/openmw/mwclass/npc.cpp | 13 +------- apps/openmw/mwmechanics/combat.cpp | 38 ++++++++++++------------ apps/openmw/mwmechanics/combat.hpp | 2 ++ apps/openmw/mwmechanics/spellcasting.cpp | 25 +++++++++------- apps/openmw/mwmechanics/spellcasting.hpp | 3 +- 6 files changed, 40 insertions(+), 54 deletions(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 0f021b5a2..4a7af1099 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -306,18 +306,7 @@ namespace MWClass } // Apply "On hit" enchanted weapons - std::string enchantmentName = !weapon.isEmpty() ? weapon.getClass().getEnchantment(weapon) : ""; - if (!enchantmentName.empty()) - { - const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get().find( - enchantmentName); - if (enchantment->mData.mType == ESM::Enchantment::WhenStrikes) - { - MWMechanics::CastSpell cast(ptr, victim); - cast.mHitPosition = hitPosition; - cast.cast(weapon); - } - } + MWMechanics::applyOnStrikeEnchantment(ptr, victim, weapon, hitPosition); } else if (isBipedal(ptr)) { diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 474985f7b..4c825f63f 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -637,18 +637,7 @@ namespace MWClass damage *= store.find("fCombatKODamageMult")->getFloat(); // Apply "On hit" enchanted weapons - std::string enchantmentName = !weapon.isEmpty() ? weapon.getClass().getEnchantment(weapon) : ""; - if (!enchantmentName.empty()) - { - const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get().find( - enchantmentName); - if (enchantment->mData.mType == ESM::Enchantment::WhenStrikes) - { - MWMechanics::CastSpell cast(ptr, victim); - cast.mHitPosition = hitPosition; - cast.cast(weapon); - } - } + MWMechanics::applyOnStrikeEnchantment(ptr, victim, weapon, hitPosition); MWMechanics::applyElementalShields(ptr, victim); diff --git a/apps/openmw/mwmechanics/combat.cpp b/apps/openmw/mwmechanics/combat.cpp index a01dc7079..8d9d4cb3a 100644 --- a/apps/openmw/mwmechanics/combat.cpp +++ b/apps/openmw/mwmechanics/combat.cpp @@ -29,28 +29,28 @@ float signedAngleRadians (const osg::Vec3f& v1, const osg::Vec3f& v2, const osg: return std::atan2((normal * (v1 ^ v2)), (v1 * v2)); } -bool applyEnchantment (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, const MWWorld::Ptr& object, const osg::Vec3f& hitPosition) +} + +namespace MWMechanics { - std::string enchantmentName = !object.isEmpty() ? object.getClass().getEnchantment(object) : ""; - if (!enchantmentName.empty()) + + bool applyOnStrikeEnchantment (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, const MWWorld::Ptr& object, const osg::Vec3f& hitPosition) { - const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get().find( - enchantmentName); - if (enchantment->mData.mType == ESM::Enchantment::WhenStrikes) + std::string enchantmentName = !object.isEmpty() ? object.getClass().getEnchantment(object) : ""; + if (!enchantmentName.empty()) { - MWMechanics::CastSpell cast(attacker, victim); - cast.mHitPosition = hitPosition; - cast.cast(object); - return true; + const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get().find( + enchantmentName); + if (enchantment->mData.mType == ESM::Enchantment::WhenStrikes) + { + MWMechanics::CastSpell cast(attacker, victim); + cast.mHitPosition = hitPosition; + cast.cast(object, false); + return true; + } } + return false; } - return false; -} - -} - -namespace MWMechanics -{ bool blockMeleeAttack(const MWWorld::Ptr &attacker, const MWWorld::Ptr &blocker, const MWWorld::Ptr &weapon, float damage, float attackStrength) { @@ -215,9 +215,9 @@ namespace MWMechanics damage *= gmst.find("fCombatKODamageMult")->getFloat(); // Apply "On hit" effect of the weapon - bool appliedEnchantment = applyEnchantment(attacker, victim, weapon, hitPosition); + bool appliedEnchantment = applyOnStrikeEnchantment(attacker, victim, weapon, hitPosition); if (weapon != projectile) - appliedEnchantment = applyEnchantment(attacker, victim, projectile, hitPosition); + appliedEnchantment = applyOnStrikeEnchantment(attacker, victim, projectile, hitPosition); if (damage > 0) MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition); diff --git a/apps/openmw/mwmechanics/combat.hpp b/apps/openmw/mwmechanics/combat.hpp index ca78d7956..7d0b3b78f 100644 --- a/apps/openmw/mwmechanics/combat.hpp +++ b/apps/openmw/mwmechanics/combat.hpp @@ -6,6 +6,8 @@ namespace MWMechanics { +bool applyOnStrikeEnchantment(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, const MWWorld::Ptr& object, const osg::Vec3f& hitPosition); + /// @return can we block the attack? bool blockMeleeAttack (const MWWorld::Ptr& attacker, const MWWorld::Ptr& blocker, const MWWorld::Ptr& weapon, float damage, float attackStrength); diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 736d2a616..8882d14a8 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -687,7 +687,7 @@ namespace MWMechanics throw std::runtime_error("ID type cannot be casted"); } - bool CastSpell::cast(const MWWorld::Ptr &item) + bool CastSpell::cast(const MWWorld::Ptr &item, bool launchProjectile) { std::string enchantmentName = item.getClass().getEnchantment(item); if (enchantmentName.empty()) @@ -754,15 +754,20 @@ namespace MWMechanics inflict(mTarget, mCaster, enchantment->mEffects, ESM::RT_Touch); } - std::string projectileModel; - std::string sound; - float speed = 0; - getProjectileInfo(enchantment->mEffects, projectileModel, sound, speed); - if (!projectileModel.empty()) - MWBase::Environment::get().getWorld()->launchMagicBolt(projectileModel, sound, mId, speed, - false, enchantment->mEffects, mCaster, mSourceName, - // Not needed, enchantments can only be cast by actors - osg::Vec3f(1,0,0)); + if (launchProjectile) + { + std::string projectileModel; + std::string sound; + float speed = 0; + getProjectileInfo(enchantment->mEffects, projectileModel, sound, speed); + if (!projectileModel.empty()) + MWBase::Environment::get().getWorld()->launchMagicBolt(projectileModel, sound, mId, speed, + false, enchantment->mEffects, mCaster, mSourceName, + // Not needed, enchantments can only be cast by actors + osg::Vec3f(1,0,0)); + } + else if (!mTarget.isEmpty()) + inflict(mTarget, mCaster, enchantment->mEffects, ESM::RT_Target); return true; } diff --git a/apps/openmw/mwmechanics/spellcasting.hpp b/apps/openmw/mwmechanics/spellcasting.hpp index 5b48bd4a8..5bc618058 100644 --- a/apps/openmw/mwmechanics/spellcasting.hpp +++ b/apps/openmw/mwmechanics/spellcasting.hpp @@ -81,7 +81,8 @@ namespace MWMechanics bool cast (const ESM::Spell* spell); /// @note mCaster must be an actor - bool cast (const MWWorld::Ptr& item); + /// @param launchProjectile If set to false, "on target" effects are directly applied instead of being launched as projectile originating from the caster. + bool cast (const MWWorld::Ptr& item, bool launchProjectile=true); /// @note mCaster must be an NPC bool cast (const ESM::Ingredient* ingredient); From 062410bd8c83fe4b2cd927c2c6d6f5031a175c8e Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 23 Feb 2016 10:56:18 +0100 Subject: [PATCH 9/9] Don't incorrectly remove TexEnv state --- components/shader/shadervisitor.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/components/shader/shadervisitor.cpp b/components/shader/shadervisitor.cpp index c88200759..b06ceafde 100644 --- a/components/shader/shadervisitor.cpp +++ b/components/shader/shadervisitor.cpp @@ -142,13 +142,6 @@ namespace Shader std::cerr << "ShaderVisitor encountered unknown texture " << texture << std::endl; } } - // remove state that has no effect when rendering with shaders - if (stateset->getTextureAttribute(unit, osg::StateAttribute::TEXENV)) - { - if (!writableStateSet) - writableStateSet = getWritableStateSet(node); - writableStateSet->removeTextureAttribute(unit, osg::StateAttribute::TEXENV); - } } if (mAutoUseNormalMaps && diffuseMap != NULL && normalMap == NULL)