forked from mirror/openmw-tes3mp
Remove redundant Transform nodes for TriShapes/ParticleSystems with an identity transform
This commit is contained in:
parent
ab597f672e
commit
ad46ff7a98
2 changed files with 47 additions and 0 deletions
|
@ -42,6 +42,15 @@ struct Matrix3
|
||||||
for (int j=0;j<3;++j)
|
for (int j=0;j<3;++j)
|
||||||
mValues[i][j] = (i==j) ? 1.f : 0.f;
|
mValues[i][j] = (i==j) ? 1.f : 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isIdentity() const
|
||||||
|
{
|
||||||
|
for (int i=0;i<3;++i)
|
||||||
|
for (int j=0;j<3;++j)
|
||||||
|
if ((i==j) != (mValues[i][j] == 1))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Transformation
|
struct Transformation
|
||||||
|
@ -62,6 +71,12 @@ struct Transformation
|
||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isIdentity() const
|
||||||
|
{
|
||||||
|
return pos == osg::Vec3f(0,0,0)
|
||||||
|
&& rotation.isIdentity() && scale == 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
static const Transformation& getIdentity()
|
static const Transformation& getIdentity()
|
||||||
{
|
{
|
||||||
static const Transformation identity = {
|
static const Transformation identity = {
|
||||||
|
|
|
@ -376,6 +376,32 @@ namespace NifOsg
|
||||||
toSetup->setFunction(boost::shared_ptr<ControllerFunction>(new ControllerFunction(ctrl)));
|
toSetup->setFunction(boost::shared_ptr<ControllerFunction>(new ControllerFunction(ctrl)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void optimize (const Nif::Node* nifNode, osg::Group* node, bool skipMeshes)
|
||||||
|
{
|
||||||
|
// For nodes with an identity transform, remove the redundant Transform node
|
||||||
|
if (node->getDataVariance() == osg::Object::STATIC
|
||||||
|
// For TriShapes, we can only collapse the node, but not completely remove it,
|
||||||
|
// if the link to animated collision shapes is supposed to stay intact.
|
||||||
|
&& (nifNode->recType != Nif::RC_NiTriShape || !skipMeshes))
|
||||||
|
{
|
||||||
|
if (node->getNumParents() && nifNode->trafo.isIdentity())
|
||||||
|
{
|
||||||
|
osg::Group* parent = node->getParent(0);
|
||||||
|
osg::Node* child = node->getChild(0);
|
||||||
|
child->setUpdateCallback(node->getUpdateCallback());
|
||||||
|
child->setStateSet(node->getStateSet());
|
||||||
|
child->setName(node->getName());
|
||||||
|
// make sure to copy the UserDataContainer with the record index, so that connections to an animated collision shape don't break
|
||||||
|
child->setUserDataContainer(node->getUserDataContainer());
|
||||||
|
parent->addChild(child);
|
||||||
|
node->removeChild(child);
|
||||||
|
parent->removeChild(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// For NiTriShapes *with* a valid transform, perhaps we could apply the transform to the vertices.
|
||||||
|
// Need to make sure that won't break transparency sorting. Check what the original engine is doing?
|
||||||
|
}
|
||||||
|
|
||||||
osg::ref_ptr<osg::Node> handleNode(const Nif::Node* nifNode, osg::Group* parentNode, Resource::TextureManager* textureManager,
|
osg::ref_ptr<osg::Node> handleNode(const Nif::Node* nifNode, osg::Group* parentNode, Resource::TextureManager* textureManager,
|
||||||
std::map<int, int> boundTextures, int animflags, int particleflags, bool skipMeshes, TextKeyMap* textKeys, osg::Node* rootNode=NULL)
|
std::map<int, int> boundTextures, int animflags, int particleflags, bool skipMeshes, TextKeyMap* textKeys, osg::Node* rootNode=NULL)
|
||||||
{
|
{
|
||||||
|
@ -490,9 +516,15 @@ namespace NifOsg
|
||||||
if (composite->getNumControllers() > 0)
|
if (composite->getNumControllers() > 0)
|
||||||
transformNode->addUpdateCallback(composite);
|
transformNode->addUpdateCallback(composite);
|
||||||
|
|
||||||
|
|
||||||
|
// Note: NiTriShapes are not allowed to have KeyframeControllers (the vanilla engine just crashes when there is one).
|
||||||
|
// We can take advantage of this constraint for optimizations later.
|
||||||
if (!nifNode->controller.empty())
|
if (!nifNode->controller.empty())
|
||||||
handleNodeControllers(nifNode, transformNode, animflags);
|
handleNodeControllers(nifNode, transformNode, animflags);
|
||||||
|
|
||||||
|
// Optimization pass
|
||||||
|
optimize(nifNode, transformNode, skipMeshes);
|
||||||
|
|
||||||
const Nif::NiNode *ninode = dynamic_cast<const Nif::NiNode*>(nifNode);
|
const Nif::NiNode *ninode = dynamic_cast<const Nif::NiNode*>(nifNode);
|
||||||
if(ninode)
|
if(ninode)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue