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) 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; 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 diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index ab6bfcff3..705dbe83a 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; } @@ -1374,17 +1374,15 @@ namespace NifOsg case Nif::NiTexturingProperty::DarkTexture: case Nif::NiTexturingProperty::BumpTexture: case Nif::NiTexturingProperty::DetailTexture: + case Nif::NiTexturingProperty::DecalTexture: 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; } - 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; @@ -1435,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) @@ -1452,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(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); + } switch (i) { @@ -1470,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/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); 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) 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