mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-04-18 14:42:27 +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
|
Nialsy
|
||||||
Nick Crawford (nighthawk469)
|
Nick Crawford (nighthawk469)
|
||||||
Nikolay Kasyanov (corristo)
|
Nikolay Kasyanov (corristo)
|
||||||
|
Noah Gooder
|
||||||
nobrakal
|
nobrakal
|
||||||
Nolan Poe (nopoe)
|
Nolan Poe (nopoe)
|
||||||
Nurivan Gomez (Nuri-G)
|
Nurivan Gomez (Nuri-G)
|
||||||
@ -228,14 +229,14 @@ Programmers
|
|||||||
viadanna
|
viadanna
|
||||||
Vincent Heuken
|
Vincent Heuken
|
||||||
Vladimir Panteleev (CyberShadow)
|
Vladimir Panteleev (CyberShadow)
|
||||||
|
vocollapse
|
||||||
Wang Ryu (bzzt)
|
Wang Ryu (bzzt)
|
||||||
Will Herrmann (Thunderforge)
|
Will Herrmann (Thunderforge)
|
||||||
vocollapse
|
Wolfgang Lieff
|
||||||
xyzz
|
xyzz
|
||||||
Yohaulticetl
|
Yohaulticetl
|
||||||
Yuri Krupenin
|
Yuri Krupenin
|
||||||
zelurker
|
zelurker
|
||||||
Noah Gooder
|
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
-------------
|
-------------
|
||||||
|
@ -138,11 +138,12 @@
|
|||||||
Feature #6288: Preserve the "blocked" record flag for referenceable objects.
|
Feature #6288: Preserve the "blocked" record flag for referenceable objects.
|
||||||
Feature #6380: Commas are treated as whitespace in vanilla
|
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 #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 #6534: Shader-based object texture blending
|
||||||
Feature #6541: Gloss-mapping
|
Feature #6541: Gloss-mapping
|
||||||
Feature #6592: Missing support for NiTriShape particle emitters
|
Feature #6592: Missing support for NiTriShape particle emitters
|
||||||
Feature #6600: Support NiSortAdjustNode
|
Feature #6600: Support NiSortAdjustNode
|
||||||
|
Feature #6684: Support NiFltAnimationNode
|
||||||
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
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include <osg/Version>
|
|
||||||
#include <osg/LOD>
|
#include <osg/LOD>
|
||||||
#include <osg/Switch>
|
#include <osg/Switch>
|
||||||
|
#include <osg/Sequence>
|
||||||
#include <osg/MatrixTransform>
|
#include <osg/MatrixTransform>
|
||||||
#include <osg/Material>
|
#include <osg/Material>
|
||||||
#include <osgUtil/IncrementalCompileOperation>
|
#include <osgUtil/IncrementalCompileOperation>
|
||||||
@ -65,7 +65,7 @@ namespace MWRender
|
|||||||
case ESM::REC_CONT:
|
case ESM::REC_CONT:
|
||||||
return store.get<ESM::Container>().searchStatic(id)->mModel;
|
return store.get<ESM::Container>().searchStatic(id)->mModel;
|
||||||
default:
|
default:
|
||||||
return std::string();
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,6 +152,13 @@ namespace MWRender
|
|||||||
n->setDataVariance(osg::Object::STATIC);
|
n->setDataVariance(osg::Object::STATIC);
|
||||||
return n;
|
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);
|
mNodePath.push_back(node);
|
||||||
|
|
||||||
@ -301,6 +308,11 @@ namespace MWRender
|
|||||||
traverse(*lod->getChild(i));
|
traverse(*lod->getChild(i));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (osg::Sequence* sq = dynamic_cast<osg::Sequence*>(&node))
|
||||||
|
{
|
||||||
|
traverse(*sq->getChild(sq->getValue() != -1 ? sq->getValue() : 0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
traverse(node);
|
traverse(node);
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ static std::map<std::string, CreateRecord> makeFactory()
|
|||||||
{"NiNode" , &construct <NiNode , RC_NiNode >},
|
{"NiNode" , &construct <NiNode , RC_NiNode >},
|
||||||
{"NiSwitchNode" , &construct <NiSwitchNode , RC_NiSwitchNode >},
|
{"NiSwitchNode" , &construct <NiSwitchNode , RC_NiSwitchNode >},
|
||||||
{"NiLODNode" , &construct <NiLODNode , RC_NiLODNode >},
|
{"NiLODNode" , &construct <NiLODNode , RC_NiLODNode >},
|
||||||
|
{"NiFltAnimationNode" , &construct <NiFltAnimationNode , RC_NiFltAnimationNode >},
|
||||||
{"AvoidNode" , &construct <NiNode , RC_AvoidNode >},
|
{"AvoidNode" , &construct <NiNode , RC_AvoidNode >},
|
||||||
{"NiCollisionSwitch" , &construct <NiNode , RC_NiCollisionSwitch >},
|
{"NiCollisionSwitch" , &construct <NiNode , RC_NiCollisionSwitch >},
|
||||||
{"NiBSParticleNode" , &construct <NiNode , RC_NiBSParticleNode >},
|
{"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
|
// Abstract
|
||||||
struct NiAccumulator : Record
|
struct NiAccumulator : Record
|
||||||
{
|
{
|
||||||
|
@ -38,6 +38,7 @@ enum RecordType
|
|||||||
RC_NiNode,
|
RC_NiNode,
|
||||||
RC_NiSwitchNode,
|
RC_NiSwitchNode,
|
||||||
RC_NiLODNode,
|
RC_NiLODNode,
|
||||||
|
RC_NiFltAnimationNode,
|
||||||
RC_NiBillboardNode,
|
RC_NiBillboardNode,
|
||||||
RC_AvoidNode,
|
RC_AvoidNode,
|
||||||
RC_NiCollisionSwitch,
|
RC_NiCollisionSwitch,
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <osg/Array>
|
#include <osg/Array>
|
||||||
#include <osg/LOD>
|
#include <osg/LOD>
|
||||||
#include <osg/Switch>
|
#include <osg/Switch>
|
||||||
|
#include <osg/Sequence>
|
||||||
#include <osg/TexGen>
|
#include <osg/TexGen>
|
||||||
#include <osg/ValueObject>
|
#include <osg/ValueObject>
|
||||||
|
|
||||||
@ -416,6 +417,33 @@ namespace NifOsg
|
|||||||
return switchNode;
|
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)
|
osg::ref_ptr<osg::Image> handleSourceTexture(const Nif::NiSourceTexture* st, Resource::ImageManager* imageManager)
|
||||||
{
|
{
|
||||||
if (!st)
|
if (!st)
|
||||||
@ -707,6 +735,12 @@ namespace NifOsg
|
|||||||
node->addChild(lodNode);
|
node->addChild(lodNode);
|
||||||
currentNode = 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);
|
const Nif::NiNode *ninode = dynamic_cast<const Nif::NiNode*>(nifNode);
|
||||||
if(ninode)
|
if(ninode)
|
||||||
@ -727,6 +761,9 @@ namespace NifOsg
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nifNode->recType == Nif::RC_NiFltAnimationNode)
|
||||||
|
activateSequenceNode(currentNode,nifNode);
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <osg/MatrixTransform>
|
#include <osg/MatrixTransform>
|
||||||
#include <osg/PositionAttitudeTransform>
|
#include <osg/PositionAttitudeTransform>
|
||||||
#include <osg/LOD>
|
#include <osg/LOD>
|
||||||
|
#include <osg/Sequence>
|
||||||
#include <osg/Billboard>
|
#include <osg/Billboard>
|
||||||
#include <osg/Geometry>
|
#include <osg/Geometry>
|
||||||
#include <osg/Notify>
|
#include <osg/Notify>
|
||||||
@ -845,7 +846,7 @@ void Optimizer::RemoveEmptyNodesVisitor::removeEmptyNodes()
|
|||||||
++pitr)
|
++pitr)
|
||||||
{
|
{
|
||||||
osg::Group* parent = *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());
|
parent->removeChild(nodeToRemove.get());
|
||||||
if (parent->getNumChildren()==0 && isOperationPermissibleForObject(parent)) newEmptyGroups.insert(parent);
|
if (parent->getNumChildren()==0 && isOperationPermissibleForObject(parent)) newEmptyGroups.insert(parent);
|
||||||
@ -887,6 +888,13 @@ void Optimizer::RemoveRedundantNodesVisitor::apply(osg::Switch& switchNode)
|
|||||||
traverse(*switchNode.getChild(i));
|
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)
|
void Optimizer::RemoveRedundantNodesVisitor::apply(osg::Group& group)
|
||||||
{
|
{
|
||||||
if (typeid(group)==typeid(osg::Group) &&
|
if (typeid(group)==typeid(osg::Group) &&
|
||||||
@ -1951,6 +1959,12 @@ void Optimizer::MergeGroupsVisitor::apply(osg::Switch &switchNode)
|
|||||||
traverse(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)
|
void Optimizer::MergeGroupsVisitor::apply(osg::Group &group)
|
||||||
{
|
{
|
||||||
if (group.getNumChildren() <= 1)
|
if (group.getNumChildren() <= 1)
|
||||||
|
@ -362,6 +362,7 @@ class Optimizer
|
|||||||
void apply(osg::Transform& transform) override;
|
void apply(osg::Transform& transform) override;
|
||||||
void apply(osg::LOD& lod) override;
|
void apply(osg::LOD& lod) override;
|
||||||
void apply(osg::Switch& switchNode) override;
|
void apply(osg::Switch& switchNode) override;
|
||||||
|
void apply(osg::Sequence& sequenceNode) override;
|
||||||
void apply(osg::Geometry&) override { }
|
void apply(osg::Geometry&) override { }
|
||||||
|
|
||||||
bool isOperationPermissible(osg::Node& node);
|
bool isOperationPermissible(osg::Node& node);
|
||||||
@ -385,6 +386,7 @@ class Optimizer
|
|||||||
void apply(osg::Group& group) override;
|
void apply(osg::Group& group) override;
|
||||||
void apply(osg::LOD& lod) override;
|
void apply(osg::LOD& lod) override;
|
||||||
void apply(osg::Switch& switchNode) override;
|
void apply(osg::Switch& switchNode) override;
|
||||||
|
void apply(osg::Sequence& sequenceNode) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MergeGeometryVisitor : public BaseOptimizerVisitor
|
class MergeGeometryVisitor : public BaseOptimizerVisitor
|
||||||
|
Loading…
x
Reference in New Issue
Block a user