1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-06-25 04:41:33 +00:00

Refactor NiMaterialColorController

This commit is contained in:
Alexei Kotov 2023-09-13 23:30:13 +03:00
parent a224bea6d4
commit 208bfa9e21
5 changed files with 26 additions and 27 deletions

View file

@ -224,15 +224,12 @@ namespace Nif
void NiMaterialColorController::read(NIFStream* nif) void NiMaterialColorController::read(NIFStream* nif)
{ {
NiPoint3InterpController::read(nif); NiPoint3InterpController::read(nif);
// Two bits that correspond to the controlled material color.
// 00: Ambient
// 01: Diffuse
// 10: Specular
// 11: Emissive
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0)) if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
mTargetColor = nif->getUShort() & 3; mTargetColor = static_cast<TargetColor>(nif->get<uint16_t>() & 3);
else else
mTargetColor = (flags >> 4) & 3; mTargetColor = static_cast<TargetColor>((flags >> 4) & 3);
if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 103)) if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 103))
mData.read(nif); mData.read(nif);
} }
@ -240,6 +237,7 @@ namespace Nif
void NiMaterialColorController::post(Reader& nif) void NiMaterialColorController::post(Reader& nif)
{ {
NiPoint3InterpController::post(nif); NiPoint3InterpController::post(nif);
mData.post(nif); mData.post(nif);
} }

View file

@ -157,8 +157,16 @@ namespace Nif
struct NiMaterialColorController : public NiPoint3InterpController struct NiMaterialColorController : public NiPoint3InterpController
{ {
enum class TargetColor
{
Ambient = 0,
Diffuse = 1,
Specular = 2,
Emissive = 3,
};
NiPosDataPtr mData; NiPosDataPtr mData;
unsigned int mTargetColor; TargetColor mTargetColor;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(Reader& nif) override; void post(Reader& nif) override;

View file

@ -444,7 +444,7 @@ namespace NifOsg
MaterialColorController::MaterialColorController( MaterialColorController::MaterialColorController(
const Nif::NiMaterialColorController* ctrl, const osg::Material* baseMaterial) const Nif::NiMaterialColorController* ctrl, const osg::Material* baseMaterial)
: mTargetColor(static_cast<MaterialColorController::TargetColor>(ctrl->mTargetColor)) : mTargetColor(ctrl->mTargetColor)
, mBaseMaterial(baseMaterial) , mBaseMaterial(baseMaterial)
{ {
if (!ctrl->mInterpolator.empty()) if (!ctrl->mInterpolator.empty())
@ -477,30 +477,31 @@ namespace NifOsg
{ {
osg::Vec3f value = mData.interpKey(getInputValue(nv)); osg::Vec3f value = mData.interpKey(getInputValue(nv));
osg::Material* mat = static_cast<osg::Material*>(stateset->getAttribute(osg::StateAttribute::MATERIAL)); osg::Material* mat = static_cast<osg::Material*>(stateset->getAttribute(osg::StateAttribute::MATERIAL));
using TargetColor = Nif::NiMaterialColorController::TargetColor;
switch (mTargetColor) switch (mTargetColor)
{ {
case Diffuse: case TargetColor::Diffuse:
{ {
osg::Vec4f diffuse = mat->getDiffuse(osg::Material::FRONT_AND_BACK); osg::Vec4f diffuse = mat->getDiffuse(osg::Material::FRONT_AND_BACK);
diffuse.set(value.x(), value.y(), value.z(), diffuse.a()); diffuse.set(value.x(), value.y(), value.z(), diffuse.a());
mat->setDiffuse(osg::Material::FRONT_AND_BACK, diffuse); mat->setDiffuse(osg::Material::FRONT_AND_BACK, diffuse);
break; break;
} }
case Specular: case TargetColor::Specular:
{ {
osg::Vec4f specular = mat->getSpecular(osg::Material::FRONT_AND_BACK); osg::Vec4f specular = mat->getSpecular(osg::Material::FRONT_AND_BACK);
specular.set(value.x(), value.y(), value.z(), specular.a()); specular.set(value.x(), value.y(), value.z(), specular.a());
mat->setSpecular(osg::Material::FRONT_AND_BACK, specular); mat->setSpecular(osg::Material::FRONT_AND_BACK, specular);
break; break;
} }
case Emissive: case TargetColor::Emissive:
{ {
osg::Vec4f emissive = mat->getEmission(osg::Material::FRONT_AND_BACK); osg::Vec4f emissive = mat->getEmission(osg::Material::FRONT_AND_BACK);
emissive.set(value.x(), value.y(), value.z(), emissive.a()); emissive.set(value.x(), value.y(), value.z(), emissive.a());
mat->setEmission(osg::Material::FRONT_AND_BACK, emissive); mat->setEmission(osg::Material::FRONT_AND_BACK, emissive);
break; break;
} }
case Ambient: case TargetColor::Ambient:
default: default:
{ {
osg::Vec4f ambient = mat->getAmbient(osg::Material::FRONT_AND_BACK); osg::Vec4f ambient = mat->getAmbient(osg::Material::FRONT_AND_BACK);

View file

@ -336,13 +336,6 @@ namespace NifOsg
class MaterialColorController : public SceneUtil::StateSetUpdater, public SceneUtil::Controller class MaterialColorController : public SceneUtil::StateSetUpdater, public SceneUtil::Controller
{ {
public: public:
enum TargetColor
{
Ambient = 0,
Diffuse = 1,
Specular = 2,
Emissive = 3
};
MaterialColorController(const Nif::NiMaterialColorController* ctrl, const osg::Material* baseMaterial); MaterialColorController(const Nif::NiMaterialColorController* ctrl, const osg::Material* baseMaterial);
MaterialColorController(); MaterialColorController();
MaterialColorController(const MaterialColorController& copy, const osg::CopyOp& copyop); MaterialColorController(const MaterialColorController& copy, const osg::CopyOp& copyop);
@ -355,7 +348,7 @@ namespace NifOsg
private: private:
Vec3Interpolator mData; Vec3Interpolator mData;
TargetColor mTargetColor = Ambient; Nif::NiMaterialColorController::TargetColor mTargetColor;
osg::ref_ptr<const osg::Material> mBaseMaterial; osg::ref_ptr<const osg::Material> mBaseMaterial;
}; };

View file

@ -988,18 +988,17 @@ namespace NifOsg
{ {
const Nif::NiMaterialColorController* matctrl const Nif::NiMaterialColorController* matctrl
= static_cast<const Nif::NiMaterialColorController*>(ctrl.getPtr()); = static_cast<const Nif::NiMaterialColorController*>(ctrl.getPtr());
if (matctrl->mData.empty() && matctrl->mInterpolator.empty()) Nif::NiInterpolatorPtr interp = matctrl->mInterpolator;
if (matctrl->mData.empty() && interp.empty())
continue; continue;
auto targetColor = static_cast<MaterialColorController::TargetColor>(matctrl->mTargetColor);
if (mVersion <= Nif::NIFFile::VER_MW if (mVersion <= Nif::NIFFile::VER_MW
&& targetColor == MaterialColorController::TargetColor::Specular) && matctrl->mTargetColor == Nif::NiMaterialColorController::TargetColor::Specular)
continue; continue;
if (!matctrl->mInterpolator.empty() if (!interp.empty() && interp->recType != Nif::RC_NiPoint3Interpolator)
&& matctrl->mInterpolator->recType != Nif::RC_NiPoint3Interpolator)
{ {
Log(Debug::Error) Log(Debug::Error)
<< "Unsupported interpolator type for NiMaterialColorController " << matctrl->recIndex << "Unsupported interpolator type for NiMaterialColorController " << matctrl->recIndex
<< " in " << mFilename << ": " << matctrl->mInterpolator->recName; << " in " << mFilename << ": " << interp->recName;
continue; continue;
} }
osg::ref_ptr<MaterialColorController> osgctrl = new MaterialColorController(matctrl, baseMaterial); osg::ref_ptr<MaterialColorController> osgctrl = new MaterialColorController(matctrl, baseMaterial);