mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-24 22:43:47 +00:00
Merge branch 'NiFltAnimationNode' into 'master'
Add NiFltAnimationNode support Closes #6684 See merge request OpenMW/openmw!1732
This commit is contained in:
commit
1ac7eaa6b0
@ -164,6 +164,7 @@ Programmers
|
||||
Nialsy
|
||||
Nick Crawford (nighthawk469)
|
||||
Nikolay Kasyanov (corristo)
|
||||
Noah Gooder
|
||||
nobrakal
|
||||
Nolan Poe (nopoe)
|
||||
Nurivan Gomez (Nuri-G)
|
||||
@ -228,14 +229,14 @@ Programmers
|
||||
viadanna
|
||||
Vincent Heuken
|
||||
Vladimir Panteleev (CyberShadow)
|
||||
vocollapse
|
||||
Wang Ryu (bzzt)
|
||||
Will Herrmann (Thunderforge)
|
||||
vocollapse
|
||||
Wolfgang Lieff
|
||||
xyzz
|
||||
Yohaulticetl
|
||||
Yuri Krupenin
|
||||
zelurker
|
||||
Noah Gooder
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
@ -138,11 +138,12 @@
|
||||
Feature #6288: Preserve the "blocked" record flag for referenceable objects.
|
||||
Feature #6380: Commas are treated as whitespace in vanilla
|
||||
Feature #6419: Topics shouldn't be greyed out if they can produce another topic reference
|
||||
Feature #6443: NiStencilProperty is not fully supported
|
||||
Feature #6443: Support NiStencilProperty
|
||||
Feature #6534: Shader-based object texture blending
|
||||
Feature #6541: Gloss-mapping
|
||||
Feature #6592: Missing support for NiTriShape particle emitters
|
||||
Feature #6600: Support NiSortAdjustNode
|
||||
Feature #6684: Support NiFltAnimationNode
|
||||
Task #6201: Remove the "Note: No relevant classes found. No output generated" warnings
|
||||
Task #6264: Remove the old classes in animation.cpp
|
||||
Task #6553: Simplify interpreter instruction registration
|
||||
|
@ -2,9 +2,9 @@
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include <osg/Version>
|
||||
#include <osg/LOD>
|
||||
#include <osg/Switch>
|
||||
#include <osg/Sequence>
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osg/Material>
|
||||
#include <osgUtil/IncrementalCompileOperation>
|
||||
@ -65,7 +65,7 @@ namespace MWRender
|
||||
case ESM::REC_CONT:
|
||||
return store.get<ESM::Container>().searchStatic(id)->mModel;
|
||||
default:
|
||||
return std::string();
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,6 +152,13 @@ namespace MWRender
|
||||
n->setDataVariance(osg::Object::STATIC);
|
||||
return n;
|
||||
}
|
||||
if (const osg::Sequence* sq = dynamic_cast<const osg::Sequence*>(node))
|
||||
{
|
||||
osg::Group* n = new osg::Group;
|
||||
n->addChild(operator()(sq->getChild(sq->getValue() != -1 ? sq->getValue() : 0)));
|
||||
n->setDataVariance(osg::Object::STATIC);
|
||||
return n;
|
||||
}
|
||||
|
||||
mNodePath.push_back(node);
|
||||
|
||||
@ -301,6 +308,11 @@ namespace MWRender
|
||||
traverse(*lod->getChild(i));
|
||||
return;
|
||||
}
|
||||
if (osg::Sequence* sq = dynamic_cast<osg::Sequence*>(&node))
|
||||
{
|
||||
traverse(*sq->getChild(sq->getValue() != -1 ? sq->getValue() : 0));
|
||||
return;
|
||||
}
|
||||
|
||||
traverse(node);
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ static std::map<std::string, CreateRecord> makeFactory()
|
||||
{"NiNode" , &construct <NiNode , RC_NiNode >},
|
||||
{"NiSwitchNode" , &construct <NiSwitchNode , RC_NiSwitchNode >},
|
||||
{"NiLODNode" , &construct <NiLODNode , RC_NiLODNode >},
|
||||
{"NiFltAnimationNode" , &construct <NiFltAnimationNode , RC_NiFltAnimationNode >},
|
||||
{"AvoidNode" , &construct <NiNode , RC_AvoidNode >},
|
||||
{"NiCollisionSwitch" , &construct <NiNode , RC_NiCollisionSwitch >},
|
||||
{"NiBSParticleNode" , &construct <NiNode , RC_NiBSParticleNode >},
|
||||
|
@ -431,6 +431,22 @@ struct NiLODNode : public NiSwitchNode
|
||||
}
|
||||
};
|
||||
|
||||
struct NiFltAnimationNode : public NiSwitchNode
|
||||
{
|
||||
float mDuration;
|
||||
enum Flags
|
||||
{
|
||||
Flag_Swing = 0x40
|
||||
};
|
||||
|
||||
|
||||
void read(NIFStream *nif) override
|
||||
{
|
||||
NiSwitchNode::read(nif);
|
||||
mDuration = nif->getFloat();
|
||||
}
|
||||
};
|
||||
|
||||
// Abstract
|
||||
struct NiAccumulator : Record
|
||||
{
|
||||
|
@ -38,6 +38,7 @@ enum RecordType
|
||||
RC_NiNode,
|
||||
RC_NiSwitchNode,
|
||||
RC_NiLODNode,
|
||||
RC_NiFltAnimationNode,
|
||||
RC_NiBillboardNode,
|
||||
RC_AvoidNode,
|
||||
RC_NiCollisionSwitch,
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <osg/Array>
|
||||
#include <osg/LOD>
|
||||
#include <osg/Switch>
|
||||
#include <osg/Sequence>
|
||||
#include <osg/TexGen>
|
||||
#include <osg/ValueObject>
|
||||
|
||||
@ -416,6 +417,33 @@ namespace NifOsg
|
||||
return switchNode;
|
||||
}
|
||||
|
||||
static osg::ref_ptr<osg::Sequence> prepareSequenceNode(const Nif::Node* nifNode)
|
||||
{
|
||||
const Nif::NiFltAnimationNode* niFltAnimationNode = static_cast<const Nif::NiFltAnimationNode*>(nifNode);
|
||||
osg::ref_ptr<osg::Sequence> sequenceNode (new osg::Sequence);
|
||||
sequenceNode->setName(niFltAnimationNode->name);
|
||||
if (niFltAnimationNode->children.length()!=0)
|
||||
{
|
||||
if (niFltAnimationNode->flags & Nif::NiFltAnimationNode::Flag_Swing)
|
||||
sequenceNode->setDefaultTime(niFltAnimationNode->mDuration/(niFltAnimationNode->children.length()*2));
|
||||
else
|
||||
sequenceNode->setDefaultTime(niFltAnimationNode->mDuration/niFltAnimationNode->children.length());
|
||||
}
|
||||
return sequenceNode;
|
||||
}
|
||||
|
||||
static void activateSequenceNode(osg::Group* osgNode, const Nif::Node* nifNode)
|
||||
{
|
||||
const Nif::NiFltAnimationNode* niFltAnimationNode = static_cast<const Nif::NiFltAnimationNode*>(nifNode);
|
||||
osg::Sequence* sequenceNode = static_cast<osg::Sequence*>(osgNode);
|
||||
if (niFltAnimationNode->flags & Nif::NiFltAnimationNode::Flag_Swing)
|
||||
sequenceNode->setInterval(osg::Sequence::SWING, 0,-1);
|
||||
else
|
||||
sequenceNode->setInterval(osg::Sequence::LOOP, 0,-1);
|
||||
sequenceNode->setDuration(1.0f, -1);
|
||||
sequenceNode->setMode(osg::Sequence::START);
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Image> handleSourceTexture(const Nif::NiSourceTexture* st, Resource::ImageManager* imageManager)
|
||||
{
|
||||
if (!st)
|
||||
@ -707,6 +735,12 @@ namespace NifOsg
|
||||
node->addChild(lodNode);
|
||||
currentNode = lodNode;
|
||||
}
|
||||
else if (nifNode->recType == Nif::RC_NiFltAnimationNode)
|
||||
{
|
||||
osg::ref_ptr<osg::Sequence> sequenceNode = prepareSequenceNode(nifNode);
|
||||
node->addChild(sequenceNode);
|
||||
currentNode = sequenceNode;
|
||||
}
|
||||
|
||||
const Nif::NiNode *ninode = dynamic_cast<const Nif::NiNode*>(nifNode);
|
||||
if(ninode)
|
||||
@ -727,6 +761,9 @@ namespace NifOsg
|
||||
}
|
||||
}
|
||||
|
||||
if (nifNode->recType == Nif::RC_NiFltAnimationNode)
|
||||
activateSequenceNode(currentNode,nifNode);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osg/PositionAttitudeTransform>
|
||||
#include <osg/LOD>
|
||||
#include <osg/Sequence>
|
||||
#include <osg/Billboard>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/Notify>
|
||||
@ -845,7 +846,7 @@ void Optimizer::RemoveEmptyNodesVisitor::removeEmptyNodes()
|
||||
++pitr)
|
||||
{
|
||||
osg::Group* parent = *pitr;
|
||||
if (!parent->asSwitch() && !dynamic_cast<osg::LOD*>(parent))
|
||||
if (!parent->asSwitch() && !dynamic_cast<osg::LOD*>(parent) && !dynamic_cast<osg::Sequence*>(parent))
|
||||
{
|
||||
parent->removeChild(nodeToRemove.get());
|
||||
if (parent->getNumChildren()==0 && isOperationPermissibleForObject(parent)) newEmptyGroups.insert(parent);
|
||||
@ -887,6 +888,13 @@ void Optimizer::RemoveRedundantNodesVisitor::apply(osg::Switch& switchNode)
|
||||
traverse(*switchNode.getChild(i));
|
||||
}
|
||||
|
||||
void Optimizer::RemoveRedundantNodesVisitor::apply(osg::Sequence& sequenceNode)
|
||||
{
|
||||
// We should keep all sequence child nodes since they reflect different sequence states.
|
||||
for (unsigned int i=0; i<sequenceNode.getNumChildren(); ++i)
|
||||
traverse(*sequenceNode.getChild(i));
|
||||
}
|
||||
|
||||
void Optimizer::RemoveRedundantNodesVisitor::apply(osg::Group& group)
|
||||
{
|
||||
if (typeid(group)==typeid(osg::Group) &&
|
||||
@ -1951,6 +1959,12 @@ void Optimizer::MergeGroupsVisitor::apply(osg::Switch &switchNode)
|
||||
traverse(switchNode);
|
||||
}
|
||||
|
||||
void Optimizer::MergeGroupsVisitor::apply(osg::Sequence &sequenceNode)
|
||||
{
|
||||
// We should keep all sequence child nodes since they reflect different sequence states.
|
||||
traverse(sequenceNode);
|
||||
}
|
||||
|
||||
void Optimizer::MergeGroupsVisitor::apply(osg::Group &group)
|
||||
{
|
||||
if (group.getNumChildren() <= 1)
|
||||
|
@ -362,6 +362,7 @@ class Optimizer
|
||||
void apply(osg::Transform& transform) override;
|
||||
void apply(osg::LOD& lod) override;
|
||||
void apply(osg::Switch& switchNode) override;
|
||||
void apply(osg::Sequence& sequenceNode) override;
|
||||
void apply(osg::Geometry&) override { }
|
||||
|
||||
bool isOperationPermissible(osg::Node& node);
|
||||
@ -385,6 +386,7 @@ class Optimizer
|
||||
void apply(osg::Group& group) override;
|
||||
void apply(osg::LOD& lod) override;
|
||||
void apply(osg::Switch& switchNode) override;
|
||||
void apply(osg::Sequence& sequenceNode) override;
|
||||
};
|
||||
|
||||
class MergeGeometryVisitor : public BaseOptimizerVisitor
|
||||
|
Loading…
x
Reference in New Issue
Block a user