From 83f61d16366b2c93699c2dbbc0d14ec22b9c3d56 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Thu, 12 Sep 2019 22:15:41 +0300 Subject: [PATCH] Support target color in NiMaterialColorController (bug #5159) --- CHANGELOG.md | 3 ++- components/nifosg/controller.cpp | 38 ++++++++++++++++++++++++++++---- components/nifosg/controller.hpp | 16 ++++++++++---- components/nifosg/nifloader.cpp | 8 ++++++- 4 files changed, 55 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4adb32534..dbd44a9cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -138,8 +138,9 @@ Bug #5134: Doors rotation by "Lock" console command is inconsistent Bug #5137: Textures with Clamp Mode set to Clamp instead of Wrap are too dark outside the boundaries Bug #5149: Failing lock pick attempts isn't always a crime - Bug #5188: Objects without a name don't fallback to their ID + Bug #5159: NiMaterialColorController can only control the diffuse color Bug #5161: Creature companions can't be activated when they are knocked down + Bug #5188: Objects without a name don't fallback to their ID Feature #1774: Handle AvoidNode Feature #2229: Improve pathfinding AI Feature #3025: Analogue gamepad movement controls diff --git a/components/nifosg/controller.cpp b/components/nifosg/controller.cpp index 4029e9b15..1842e0017 100644 --- a/components/nifosg/controller.cpp +++ b/components/nifosg/controller.cpp @@ -385,8 +385,9 @@ void AlphaController::apply(osg::StateSet *stateset, osg::NodeVisitor *nv) } } -MaterialColorController::MaterialColorController(const Nif::NiPosData *data) +MaterialColorController::MaterialColorController(const Nif::NiPosData *data, TargetColor color) : mData(data->mKeyList, osg::Vec3f(1,1,1)) + , mTargetColor(color) { } @@ -397,6 +398,7 @@ MaterialColorController::MaterialColorController() MaterialColorController::MaterialColorController(const MaterialColorController ©, const osg::CopyOp ©op) : StateSetUpdater(copy, copyop), Controller(copy) , mData(copy.mData) + , mTargetColor(copy.mTargetColor) { } @@ -413,9 +415,37 @@ void MaterialColorController::apply(osg::StateSet *stateset, osg::NodeVisitor *n { osg::Vec3f value = mData.interpKey(getInputValue(nv)); osg::Material* mat = static_cast(stateset->getAttribute(osg::StateAttribute::MATERIAL)); - osg::Vec4f diffuse = mat->getDiffuse(osg::Material::FRONT_AND_BACK); - diffuse.set(value.x(), value.y(), value.z(), diffuse.a()); - mat->setDiffuse(osg::Material::FRONT_AND_BACK, diffuse); + switch (mTargetColor) + { + case Diffuse: + { + osg::Vec4f diffuse = mat->getDiffuse(osg::Material::FRONT_AND_BACK); + diffuse.set(value.x(), value.y(), value.z(), diffuse.a()); + mat->setDiffuse(osg::Material::FRONT_AND_BACK, diffuse); + break; + } + case Specular: + { + osg::Vec4f specular = mat->getSpecular(osg::Material::FRONT_AND_BACK); + specular.set(value.x(), value.y(), value.z(), specular.a()); + mat->setSpecular(osg::Material::FRONT_AND_BACK, specular); + break; + } + case Emissive: + { + osg::Vec4f emissive = mat->getEmission(osg::Material::FRONT_AND_BACK); + emissive.set(value.x(), value.y(), value.z(), emissive.a()); + mat->setEmission(osg::Material::FRONT_AND_BACK, emissive); + break; + } + case Ambient: + default: + { + osg::Vec4f ambient = mat->getAmbient(osg::Material::FRONT_AND_BACK); + ambient.set(value.x(), value.y(), value.z(), ambient.a()); + mat->setAmbient(osg::Material::FRONT_AND_BACK, ambient); + } + } } } diff --git a/components/nifosg/controller.hpp b/components/nifosg/controller.hpp index 36217f31a..d5fb56f0e 100644 --- a/components/nifosg/controller.hpp +++ b/components/nifosg/controller.hpp @@ -281,11 +281,15 @@ namespace NifOsg class MaterialColorController : public SceneUtil::StateSetUpdater, public SceneUtil::Controller { - private: - Vec3Interpolator mData; - public: - MaterialColorController(const Nif::NiPosData *data); + enum TargetColor + { + Ambient = 0, + Diffuse = 1, + Specular = 2, + Emissive = 3 + }; + MaterialColorController(const Nif::NiPosData *data, TargetColor color); MaterialColorController(); MaterialColorController(const MaterialColorController& copy, const osg::CopyOp& copyop); @@ -294,6 +298,10 @@ namespace NifOsg virtual void setDefaults(osg::StateSet* stateset); virtual void apply(osg::StateSet* stateset, osg::NodeVisitor* nv); + + private: + Vec3Interpolator mData; + TargetColor mTargetColor; }; class FlipController : public SceneUtil::StateSetUpdater, public SceneUtil::Controller diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 7699271d3..58e336b5d 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -750,7 +750,13 @@ namespace NifOsg else if (ctrl->recType == Nif::RC_NiMaterialColorController) { const Nif::NiMaterialColorController* matctrl = static_cast(ctrl.getPtr()); - osg::ref_ptr osgctrl(new MaterialColorController(matctrl->data.getPtr())); + // Two bits that correspond to the controlled material color. + // 00: Ambient + // 01: Diffuse + // 10: Specular + // 11: Emissive + MaterialColorController::TargetColor targetColor = static_cast((matctrl->flags >> 4) & 3); + osg::ref_ptr osgctrl(new MaterialColorController(matctrl->data.getPtr(), targetColor)); setupController(matctrl, osgctrl, animflags); composite->addController(osgctrl); }