mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-03 17:09:40 +00:00
nisortadjust support
This commit is contained in:
parent
8cfb3e1053
commit
712107de2d
4 changed files with 89 additions and 11 deletions
|
@ -132,6 +132,7 @@
|
||||||
Feature #6443: NiStencilProperty is not fully supported
|
Feature #6443: NiStencilProperty is not fully supported
|
||||||
Feature #6534: Shader-based object texture blending
|
Feature #6534: Shader-based object texture blending
|
||||||
Feature #6592: Missing support for NiTriShape particle emitters
|
Feature #6592: Missing support for NiTriShape particle emitters
|
||||||
|
Feature #6600: Support NiSortAdjustNode
|
||||||
Task #6201: Remove the "Note: No relevant classes found. No output generated" warnings
|
Task #6201: Remove the "Note: No relevant classes found. No output generated" warnings
|
||||||
Task #6264: Remove the old classes in animation.cpp
|
Task #6264: Remove the old classes in animation.cpp
|
||||||
Task #6553: Simplify interpreter instruction registration
|
Task #6553: Simplify interpreter instruction registration
|
||||||
|
|
|
@ -153,7 +153,7 @@ static std::map<std::string,RecordFactoryEntry> makeFactory()
|
||||||
factory["bhkRigidBody"] = {&construct <bhkRigidBody> , RC_bhkRigidBody };
|
factory["bhkRigidBody"] = {&construct <bhkRigidBody> , RC_bhkRigidBody };
|
||||||
factory["bhkRigidBodyT"] = {&construct <bhkRigidBody> , RC_bhkRigidBodyT };
|
factory["bhkRigidBodyT"] = {&construct <bhkRigidBody> , RC_bhkRigidBodyT };
|
||||||
factory["BSLightingShaderProperty"] = {&construct <BSLightingShaderProperty> , RC_BSLightingShaderProperty };
|
factory["BSLightingShaderProperty"] = {&construct <BSLightingShaderProperty> , RC_BSLightingShaderProperty };
|
||||||
factory["NiSortAdjustNode"] = {&construct <NiSortAdjustNode> , RC_NiNode };
|
factory["NiSortAdjustNode"] = {&construct <NiSortAdjustNode> , RC_NiSortAdjustNode };
|
||||||
factory["NiClusterAccumulator"] = {&construct <NiClusterAccumulator> , RC_NiClusterAccumulator };
|
factory["NiClusterAccumulator"] = {&construct <NiClusterAccumulator> , RC_NiClusterAccumulator };
|
||||||
factory["NiAlphaAccumulator"] = {&construct <NiAlphaAccumulator> , RC_NiAlphaAccumulator };
|
factory["NiAlphaAccumulator"] = {&construct <NiAlphaAccumulator> , RC_NiAlphaAccumulator };
|
||||||
return factory;
|
return factory;
|
||||||
|
|
|
@ -142,7 +142,8 @@ enum RecordType
|
||||||
RC_bhkRigidBodyT,
|
RC_bhkRigidBodyT,
|
||||||
RC_BSLightingShaderProperty,
|
RC_BSLightingShaderProperty,
|
||||||
RC_NiClusterAccumulator,
|
RC_NiClusterAccumulator,
|
||||||
RC_NiAlphaAccumulator
|
RC_NiAlphaAccumulator,
|
||||||
|
RC_NiSortAdjustNode
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Base class for all records
|
/// Base class for all records
|
||||||
|
|
|
@ -219,6 +219,9 @@ namespace NifOsg
|
||||||
bool mHasHerbalismLabel = false;
|
bool mHasHerbalismLabel = false;
|
||||||
bool mHasStencilProperty = false;
|
bool mHasStencilProperty = false;
|
||||||
|
|
||||||
|
const Nif::NiSortAdjustNode* mPushedSorter = nullptr;
|
||||||
|
const Nif::NiSortAdjustNode* mLastAppliedNoInheritSorter = nullptr;
|
||||||
|
|
||||||
// This is used to queue emitters that weren't attached to their node yet.
|
// This is used to queue emitters that weren't attached to their node yet.
|
||||||
std::vector<std::pair<size_t, osg::ref_ptr<Emitter>>> mEmitterQueue;
|
std::vector<std::pair<size_t, osg::ref_ptr<Emitter>>> mEmitterQueue;
|
||||||
|
|
||||||
|
@ -309,10 +312,6 @@ namespace NifOsg
|
||||||
if (mHasHerbalismLabel)
|
if (mHasHerbalismLabel)
|
||||||
created->getOrCreateUserDataContainer()->addDescription(Constants::HerbalismLabel);
|
created->getOrCreateUserDataContainer()->addDescription(Constants::HerbalismLabel);
|
||||||
|
|
||||||
// When dealing with stencil buffer, draw order is especially sensitive. Make sure such objects are drawn with traversal order.
|
|
||||||
if (mHasStencilProperty)
|
|
||||||
created->getOrCreateStateSet()->setRenderBinDetails(2, "TraversalOrderBin");
|
|
||||||
|
|
||||||
// Attach particle emitters to their nodes which should all be loaded by now.
|
// Attach particle emitters to their nodes which should all be loaded by now.
|
||||||
handleQueuedParticleEmitters(created, nif);
|
handleQueuedParticleEmitters(created, nif);
|
||||||
|
|
||||||
|
@ -597,6 +596,22 @@ namespace NifOsg
|
||||||
if (nifNode->recType == Nif::RC_NiBSAnimationNode || nifNode->recType == Nif::RC_NiBSParticleNode)
|
if (nifNode->recType == Nif::RC_NiBSAnimationNode || nifNode->recType == Nif::RC_NiBSParticleNode)
|
||||||
animflags = nifNode->flags;
|
animflags = nifNode->flags;
|
||||||
|
|
||||||
|
if (nifNode->recType == Nif::RC_NiSortAdjustNode)
|
||||||
|
{
|
||||||
|
auto sortNode = static_cast<const Nif::NiSortAdjustNode*>(nifNode);
|
||||||
|
|
||||||
|
if (sortNode->mSubSorter.empty())
|
||||||
|
{
|
||||||
|
Log(Debug::Warning) << "Empty accumulator found in '" << nifNode->recName << "' node " << nifNode->recIndex;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mPushedSorter && !mPushedSorter->mSubSorter.empty() && mPushedSorter->mMode != Nif::NiSortAdjustNode::SortingMode_Inherit)
|
||||||
|
mLastAppliedNoInheritSorter = mPushedSorter;
|
||||||
|
mPushedSorter = sortNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Hide collision shapes, but don't skip the subgraph
|
// Hide collision shapes, but don't skip the subgraph
|
||||||
// We still need to animate the hidden bones so the physics system can access them
|
// We still need to animate the hidden bones so the physics system can access them
|
||||||
if (nifNode->recType == Nif::RC_RootCollisionNode)
|
if (nifNode->recType == Nif::RC_RootCollisionNode)
|
||||||
|
@ -2008,6 +2023,13 @@ namespace NifOsg
|
||||||
mat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,1));
|
mat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,1));
|
||||||
|
|
||||||
bool hasMatCtrl = false;
|
bool hasMatCtrl = false;
|
||||||
|
bool hasSortAlpha = false;
|
||||||
|
osg::StateSet* blendFuncStateSet = nullptr;
|
||||||
|
|
||||||
|
auto setBin_Transparent = [] (osg::StateSet* ss) { ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); };
|
||||||
|
auto setBin_BackToFront = [] (osg::StateSet* ss) { ss->setRenderBinDetails(0, "SORT_BACK_TO_FRONT"); };
|
||||||
|
auto setBin_Traversal = [] (osg::StateSet* ss) { ss->setRenderBinDetails(2, "TraversalOrderBin"); };
|
||||||
|
auto setBin_Inherit = [] (osg::StateSet* ss) { ss->setRenderBinToInherit(); };
|
||||||
|
|
||||||
int lightmode = 1;
|
int lightmode = 1;
|
||||||
float emissiveMult = 1.f;
|
float emissiveMult = 1.f;
|
||||||
|
@ -2085,17 +2107,23 @@ namespace NifOsg
|
||||||
bool noSort = (alphaprop->flags>>13)&1;
|
bool noSort = (alphaprop->flags>>13)&1;
|
||||||
if (!noSort)
|
if (!noSort)
|
||||||
{
|
{
|
||||||
node->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
hasSortAlpha = true;
|
||||||
node->getOrCreateStateSet()->setNestRenderBins(false);
|
if (!mPushedSorter)
|
||||||
|
setBin_Transparent(node->getStateSet());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
node->getOrCreateStateSet()->setRenderBinToInherit();
|
{
|
||||||
|
if (!mPushedSorter)
|
||||||
|
setBin_Inherit(node->getStateSet());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (osg::StateSet* stateset = node->getStateSet())
|
else if (osg::StateSet* stateset = node->getStateSet())
|
||||||
{
|
{
|
||||||
stateset->removeAttribute(osg::StateAttribute::BLENDFUNC);
|
stateset->removeAttribute(osg::StateAttribute::BLENDFUNC);
|
||||||
stateset->removeMode(GL_BLEND);
|
stateset->removeMode(GL_BLEND);
|
||||||
stateset->setRenderBinToInherit();
|
blendFuncStateSet = stateset;
|
||||||
|
if (!mPushedSorter)
|
||||||
|
blendFuncStateSet->setRenderBinToInherit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if((alphaprop->flags>>9)&1)
|
if((alphaprop->flags>>9)&1)
|
||||||
|
@ -2158,7 +2186,10 @@ namespace NifOsg
|
||||||
mat->setColorMode(osg::Material::OFF);
|
mat->setColorMode(osg::Material::OFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasMatCtrl && mat->getColorMode() == osg::Material::OFF
|
if (!mPushedSorter && !hasSortAlpha && mHasStencilProperty)
|
||||||
|
setBin_Traversal(node->getOrCreateStateSet());
|
||||||
|
|
||||||
|
if (!mPushedSorter && !hasMatCtrl && mat->getColorMode() == osg::Material::OFF
|
||||||
&& mat->getEmission(osg::Material::FRONT_AND_BACK) == osg::Vec4f(0,0,0,1)
|
&& mat->getEmission(osg::Material::FRONT_AND_BACK) == osg::Vec4f(0,0,0,1)
|
||||||
&& mat->getDiffuse(osg::Material::FRONT_AND_BACK) == osg::Vec4f(1,1,1,1)
|
&& mat->getDiffuse(osg::Material::FRONT_AND_BACK) == osg::Vec4f(1,1,1,1)
|
||||||
&& mat->getAmbient(osg::Material::FRONT_AND_BACK) == osg::Vec4f(1,1,1,1)
|
&& mat->getAmbient(osg::Material::FRONT_AND_BACK) == osg::Vec4f(1,1,1,1)
|
||||||
|
@ -2177,6 +2208,51 @@ namespace NifOsg
|
||||||
stateset->addUniform(new osg::Uniform("emissiveMult", emissiveMult));
|
stateset->addUniform(new osg::Uniform("emissiveMult", emissiveMult));
|
||||||
if (specStrength != 1.f)
|
if (specStrength != 1.f)
|
||||||
stateset->addUniform(new osg::Uniform("specStrength", specStrength));
|
stateset->addUniform(new osg::Uniform("specStrength", specStrength));
|
||||||
|
|
||||||
|
if (!mPushedSorter)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto assignBin = [&] (int mode, int type) {
|
||||||
|
if (mode == Nif::NiSortAdjustNode::SortingMode_Off)
|
||||||
|
{
|
||||||
|
setBin_Traversal(stateset);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == Nif::RC_NiAlphaAccumulator)
|
||||||
|
{
|
||||||
|
if (hasSortAlpha)
|
||||||
|
setBin_BackToFront(stateset);
|
||||||
|
else
|
||||||
|
setBin_Traversal(stateset);
|
||||||
|
}
|
||||||
|
else if (type == Nif::RC_NiClusterAccumulator)
|
||||||
|
setBin_BackToFront(stateset);
|
||||||
|
else
|
||||||
|
Log(Debug::Error) << "Unrecognized NiAccumulator in " << mFilename;
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (mPushedSorter->mMode)
|
||||||
|
{
|
||||||
|
case Nif::NiSortAdjustNode::SortingMode_Inherit:
|
||||||
|
{
|
||||||
|
if (mLastAppliedNoInheritSorter)
|
||||||
|
assignBin(mLastAppliedNoInheritSorter->mMode, mLastAppliedNoInheritSorter->mSubSorter->recType);
|
||||||
|
else
|
||||||
|
assignBin(mPushedSorter->mMode, Nif::RC_NiAlphaAccumulator);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Nif::NiSortAdjustNode::SortingMode_Off:
|
||||||
|
{
|
||||||
|
setBin_Traversal(stateset);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Nif::NiSortAdjustNode::SortingMode_Subsort:
|
||||||
|
{
|
||||||
|
assignBin(mPushedSorter->mMode, mPushedSorter->mSubSorter->recType);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue