From 08f06c6c2d6f89eeea5c85a6dc82ec92e5fcc802 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 1 Mar 2016 16:57:11 +0100 Subject: [PATCH 01/10] Fix a crash that could occur with actors that define 'bip01 spine1' but do not define 'bip01 spine2' (Fixes #3223). --- apps/openmw/mwrender/weaponanimation.cpp | 25 +++++++++++++++--------- apps/openmw/mwrender/weaponanimation.hpp | 3 +++ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwrender/weaponanimation.cpp b/apps/openmw/mwrender/weaponanimation.cpp index 2627d3fc6..d5fb70d16 100644 --- a/apps/openmw/mwrender/weaponanimation.cpp +++ b/apps/openmw/mwrender/weaponanimation.cpp @@ -182,23 +182,30 @@ void WeaponAnimation::deleteControllers() void WeaponAnimation::configureControllers(float characterPitchRadians) { - if (!mSpineControllers[0]) - return; - if (mPitchFactor == 0.f || characterPitchRadians == 0.f) { - for (int i=0; i<2; ++i) - mSpineControllers[i]->setEnabled(false); + setControllerEnabled(false); return; } float pitch = characterPitchRadians * mPitchFactor; osg::Quat rotate (pitch/2, osg::Vec3f(-1,0,0)); + setControllerRotate(rotate); + setControllerEnabled(true); +} + +void WeaponAnimation::setControllerRotate(const osg::Quat& rotate) +{ for (int i=0; i<2; ++i) - { - mSpineControllers[i]->setRotate(rotate); - mSpineControllers[i]->setEnabled(true); - } + if (mSpineControllers[i]) + mSpineControllers[i]->setRotate(rotate); +} + +void WeaponAnimation::setControllerEnabled(bool enabled) +{ + for (int i=0; i<2; ++i) + if (mSpineControllers[i]) + mSpineControllers[i]->setEnabled(enabled); } } diff --git a/apps/openmw/mwrender/weaponanimation.hpp b/apps/openmw/mwrender/weaponanimation.hpp index 3bf0fb721..d50729c62 100644 --- a/apps/openmw/mwrender/weaponanimation.hpp +++ b/apps/openmw/mwrender/weaponanimation.hpp @@ -52,6 +52,9 @@ namespace MWRender osg::ref_ptr mSpineControllers[2]; + void setControllerRotate(const osg::Quat& rotate); + void setControllerEnabled(bool enabled); + virtual osg::Group* getArrowBone() = 0; virtual osg::Node* getWeaponNode() = 0; virtual Resource::ResourceSystem* getResourceSystem() = 0; From 64636bd85a7c7172f106dd4c0f11e79290aba75c Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 1 Mar 2016 17:05:02 +0100 Subject: [PATCH 02/10] Improve error reporting --- components/nifosg/nifloader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index ab6bfcff3..1300d592f 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -470,7 +470,7 @@ namespace NifOsg const Nif::NiTextureEffect* textureEffect = static_cast(nifNode); if (textureEffect->textureType != Nif::NiTextureEffect::Environment_Map) { - std::cerr << "Unhandled NiTextureEffect type " << textureEffect->textureType << std::endl; + std::cerr << "Unhandled NiTextureEffect type " << textureEffect->textureType << " in " << mFilename << std::endl; return; } @@ -487,7 +487,7 @@ namespace NifOsg texGen->setMode(osg::TexGen::SPHERE_MAP); break; default: - std::cerr << "Unhandled NiTextureEffect coordGenType " << textureEffect->coordGenType << std::endl; + std::cerr << "Unhandled NiTextureEffect coordGenType " << textureEffect->coordGenType << " in " << mFilename << std::endl; return; } From 30d06bfe0e9140796df9f205fd5f161e9b53865a Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 1 Mar 2016 17:27:54 +0100 Subject: [PATCH 03/10] Add comment --- components/nifosg/nifloader.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 1300d592f..b7eb9d8a7 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -1377,6 +1377,8 @@ namespace NifOsg break; case Nif::NiTexturingProperty::GlossTexture: { + // Not used by the vanilla engine. MCP (Morrowind Code Patch) adds an option to use Gloss maps: + // "- Gloss map fix. Morrowind removed gloss map entries from model files after loading them. This stops Morrowind from removing them." std::cerr << "NiTexturingProperty::GlossTexture in " << mFilename << " not currently used." << std::endl; continue; } From 414c19f717e9e75d46cbd59d7130254c8dd10cd4 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 1 Mar 2016 18:40:18 +0100 Subject: [PATCH 04/10] Fix detailMapUV bug --- files/shaders/objects_vertex.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/shaders/objects_vertex.glsl b/files/shaders/objects_vertex.glsl index b1004aad3..297941172 100644 --- a/files/shaders/objects_vertex.glsl +++ b/files/shaders/objects_vertex.glsl @@ -68,7 +68,7 @@ void main(void) #endif #if @detailMap - detailMapUV = (gl_TextureMatrix[@detailMap] * gl_MultiTexCoord@detailMap).xy; + detailMapUV = (gl_TextureMatrix[@detailMapUV] * gl_MultiTexCoord@detailMapUV).xy; #endif #if @emissiveMap From 6e7c6fdd7ee7672ee20d3d8374eecf17c5cf412a Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 1 Mar 2016 18:41:36 +0100 Subject: [PATCH 05/10] Implement NiTexturingProperty::DecalTexture --- components/nifosg/nifloader.cpp | 24 +++++++++++++++++++----- components/shader/shadervisitor.cpp | 4 ++-- files/shaders/objects_fragment.glsl | 10 ++++++++++ files/shaders/objects_vertex.glsl | 8 ++++++++ 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index b7eb9d8a7..8ffb8d5de 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -1374,6 +1374,7 @@ namespace NifOsg case Nif::NiTexturingProperty::DarkTexture: case Nif::NiTexturingProperty::BumpTexture: case Nif::NiTexturingProperty::DetailTexture: + case Nif::NiTexturingProperty::DecalTexture: break; case Nif::NiTexturingProperty::GlossTexture: { @@ -1382,11 +1383,6 @@ namespace NifOsg std::cerr << "NiTexturingProperty::GlossTexture in " << mFilename << " not currently used." << std::endl; continue; } - case Nif::NiTexturingProperty::DecalTexture: - { - std::cerr << "NiTexturingProperty::DecalTexture in " << mFilename << " not currently used." << std::endl; - continue; - } default: { std::cerr << "Warning: unhandled texture stage " << i << " in " << mFilename << std::endl; @@ -1454,6 +1450,21 @@ namespace NifOsg // Set this texture to Off by default since we can't render it with the fixed-function pipeline stateset->setTextureMode(texUnit, GL_TEXTURE_2D, osg::StateAttribute::OFF); } + else if (i == Nif::NiTexturingProperty::DecalTexture) + { + osg::TexEnvCombine* texEnv = new osg::TexEnvCombine; + texEnv->setCombine_RGB(GL_INTERPOLATE); + texEnv->setSource0_RGB(GL_TEXTURE); + texEnv->setOperand0_RGB(GL_SRC_COLOR); + texEnv->setSource1_RGB(GL_PREVIOUS_ARB); + texEnv->setOperand1_RGB(GL_SRC_COLOR); + texEnv->setSource2_RGB(GL_TEXTURE); + texEnv->setOperand2_RGB(GL_SRC_ALPHA); + texEnv->setCombine_Alpha(GL_REPLACE); + texEnv->setSource0_Alpha(GL_PREVIOUS); + texEnv->setOperand0_Alpha(GL_SRC_ALPHA); + stateset->setTextureAttributeAndModes(texUnit, texEnv, osg::StateAttribute::ON); + } switch (i) { @@ -1472,6 +1483,9 @@ namespace NifOsg case Nif::NiTexturingProperty::DetailTexture: texture2d->setName("detailMap"); break; + case Nif::NiTexturingProperty::DecalTexture: + texture2d->setName("decalMap"); + break; default: break; } diff --git a/components/shader/shadervisitor.cpp b/components/shader/shadervisitor.cpp index b06ceafde..92bdac7b7 100644 --- a/components/shader/shadervisitor.cpp +++ b/components/shader/shadervisitor.cpp @@ -88,11 +88,11 @@ namespace Shader return newStateSet.get(); } - const char* defaultTextures[] = { "diffuseMap", "normalMap", "emissiveMap", "darkMap", "detailMap", "envMap", "specularMap" }; + const char* defaultTextures[] = { "diffuseMap", "normalMap", "emissiveMap", "darkMap", "detailMap", "envMap", "specularMap", "decalMap" }; bool isTextureNameRecognized(const std::string& name) { for (unsigned int i=0; i Date: Wed, 2 Mar 2016 13:20:23 +0100 Subject: [PATCH 06/10] Infinite loop fix --- apps/openmw/mwrender/animation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 7f7183b9e..5cf502476 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -1363,6 +1363,7 @@ namespace MWRender foundKeyframeCtrl = true; break; } + cb = cb->getNestedCallback(); } if (foundKeyframeCtrl) From 563807ee5335c823d24fdc898ed439706bfa5b31 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 2 Mar 2016 13:33:31 +0100 Subject: [PATCH 07/10] Share the StateSet used to invert front face --- components/sceneutil/attach.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/components/sceneutil/attach.cpp b/components/sceneutil/attach.cpp index 38330901d..8ac0aa992 100644 --- a/components/sceneutil/attach.cpp +++ b/components/sceneutil/attach.cpp @@ -102,9 +102,15 @@ namespace SceneUtil // Need to invert culling because of the negative scale // Note: for absolute correctness we would need to check the current front face for every mesh then invert it // However MW isn't doing this either, so don't. Assuming all meshes are using backface culling is more efficient. - osg::FrontFace* frontFace = new osg::FrontFace; - frontFace->setMode(osg::FrontFace::CLOCKWISE); - trans->getOrCreateStateSet()->setAttributeAndModes(frontFace, osg::StateAttribute::ON); + static osg::ref_ptr frontFaceStateSet; + if (!frontFaceStateSet) + { + frontFaceStateSet = new osg::StateSet; + osg::FrontFace* frontFace = new osg::FrontFace; + frontFace->setMode(osg::FrontFace::CLOCKWISE); + frontFaceStateSet->setAttributeAndModes(frontFace, osg::StateAttribute::ON); + } + trans->setStateSet(frontFaceStateSet); } if (trans) From 3d6323f13a20ae5cba65814d859137ec8dd94005 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 2 Mar 2016 17:02:30 +0100 Subject: [PATCH 08/10] Force-enable hasWater() for exterior cells (Fixes #3222) --- apps/openmw/mwworld/worldimp.cpp | 2 +- components/esm/loadcell.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 2ab027cd6..0dbadca17 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2039,7 +2039,7 @@ namespace MWWorld bool World::isUnderwater(const MWWorld::CellStore* cell, const osg::Vec3f &pos) const { - if (!(cell->getCell()->mData.mFlags & ESM::Cell::HasWater)) { + if (!(cell->getCell()->hasWater())) { return false; } return pos.z() < cell->getWaterLevel(); diff --git a/components/esm/loadcell.hpp b/components/esm/loadcell.hpp index f92e0b5b7..cab8cf65e 100644 --- a/components/esm/loadcell.hpp +++ b/components/esm/loadcell.hpp @@ -141,7 +141,7 @@ struct Cell bool hasWater() const { - return (mData.mFlags&HasWater) != 0; + return ((mData.mFlags&HasWater) != 0) || isExterior(); } // Restore the given reader to the stored position. Will try to open From dd2fbfc0a2e5d09cd8e54d47ba1124f1a9bfbf9d Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 2 Mar 2016 21:57:25 +0100 Subject: [PATCH 09/10] Fix windows build --- components/nifosg/nifloader.cpp | 40 ++++++++++++++++----------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 8ffb8d5de..705dbe83a 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -1433,16 +1433,16 @@ namespace NifOsg { osg::TexEnvCombine* texEnv = new osg::TexEnvCombine; texEnv->setScale_RGB(2.f); - texEnv->setCombine_Alpha(GL_MODULATE); - texEnv->setOperand0_Alpha(GL_SRC_ALPHA); - texEnv->setOperand1_Alpha(GL_SRC_ALPHA); - texEnv->setSource0_Alpha(GL_PREVIOUS_ARB); - texEnv->setSource1_Alpha(GL_TEXTURE); - texEnv->setCombine_RGB(GL_MODULATE); - texEnv->setOperand0_RGB(GL_SRC_COLOR); - texEnv->setOperand1_RGB(GL_SRC_COLOR); - texEnv->setSource0_RGB(GL_PREVIOUS_ARB); - texEnv->setSource1_RGB(GL_TEXTURE); + texEnv->setCombine_Alpha(osg::TexEnvCombine::MODULATE); + texEnv->setOperand0_Alpha(osg::TexEnvCombine::SRC_ALPHA); + texEnv->setOperand1_Alpha(osg::TexEnvCombine::SRC_ALPHA); + texEnv->setSource0_Alpha(osg::TexEnvCombine::PREVIOUS); + texEnv->setSource1_Alpha(osg::TexEnvCombine::TEXTURE); + texEnv->setCombine_RGB(osg::TexEnvCombine::MODULATE); + texEnv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR); + texEnv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR); + texEnv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS); + texEnv->setSource1_RGB(osg::TexEnvCombine::TEXTURE); stateset->setTextureAttributeAndModes(texUnit, texEnv, osg::StateAttribute::ON); } else if (i == Nif::NiTexturingProperty::BumpTexture) @@ -1453,16 +1453,16 @@ namespace NifOsg else if (i == Nif::NiTexturingProperty::DecalTexture) { osg::TexEnvCombine* texEnv = new osg::TexEnvCombine; - texEnv->setCombine_RGB(GL_INTERPOLATE); - texEnv->setSource0_RGB(GL_TEXTURE); - texEnv->setOperand0_RGB(GL_SRC_COLOR); - texEnv->setSource1_RGB(GL_PREVIOUS_ARB); - texEnv->setOperand1_RGB(GL_SRC_COLOR); - texEnv->setSource2_RGB(GL_TEXTURE); - texEnv->setOperand2_RGB(GL_SRC_ALPHA); - texEnv->setCombine_Alpha(GL_REPLACE); - texEnv->setSource0_Alpha(GL_PREVIOUS); - texEnv->setOperand0_Alpha(GL_SRC_ALPHA); + texEnv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); + texEnv->setSource0_RGB(osg::TexEnvCombine::TEXTURE); + texEnv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR); + texEnv->setSource1_RGB(osg::TexEnvCombine::PREVIOUS); + texEnv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR); + texEnv->setSource2_RGB(osg::TexEnvCombine::TEXTURE); + texEnv->setOperand2_RGB(osg::TexEnvCombine::SRC_ALPHA); + texEnv->setCombine_Alpha(osg::TexEnvCombine::REPLACE); + texEnv->setSource0_Alpha(osg::TexEnvCombine::PREVIOUS); + texEnv->setOperand0_Alpha(osg::TexEnvCombine::SRC_ALPHA); stateset->setTextureAttributeAndModes(texUnit, texEnv, osg::StateAttribute::ON); } From 2eaf96e3bfe7fd9052c8c0896bcf3f40cbcd2ce4 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 2 Mar 2016 21:58:11 +0100 Subject: [PATCH 10/10] Make ResourceManager destructor virtual --- components/resource/resourcemanager.cpp | 4 ++++ components/resource/resourcemanager.hpp | 1 + 2 files changed, 5 insertions(+) diff --git a/components/resource/resourcemanager.cpp b/components/resource/resourcemanager.cpp index 0a9784e6b..d19d9cf80 100644 --- a/components/resource/resourcemanager.cpp +++ b/components/resource/resourcemanager.cpp @@ -13,6 +13,10 @@ namespace Resource } + ResourceManager::~ResourceManager() + { + } + void ResourceManager::updateCache(double referenceTime) { mCache->updateTimeStampOfObjectsInCacheWithExternalReferences(referenceTime); diff --git a/components/resource/resourcemanager.hpp b/components/resource/resourcemanager.hpp index 34fce0145..b69256834 100644 --- a/components/resource/resourcemanager.hpp +++ b/components/resource/resourcemanager.hpp @@ -18,6 +18,7 @@ namespace Resource { public: ResourceManager(const VFS::Manager* vfs); + virtual ~ResourceManager(); /// Clear cache entries that have not been referenced for longer than expiryDelay. virtual void updateCache(double referenceTime);