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)
|
||||
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
|
||||
|
@ -62,6 +71,12 @@ struct Transformation
|
|||
return transform;
|
||||
}
|
||||
|
||||
bool isIdentity() const
|
||||
{
|
||||
return pos == osg::Vec3f(0,0,0)
|
||||
&& rotation.isIdentity() && scale == 1.f;
|
||||
}
|
||||
|
||||
static const Transformation& getIdentity()
|
||||
{
|
||||
static const Transformation identity = {
|
||||
|
|
|
@ -376,6 +376,32 @@ namespace NifOsg
|
|||
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,
|
||||
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)
|
||||
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())
|
||||
handleNodeControllers(nifNode, transformNode, animflags);
|
||||
|
||||
// Optimization pass
|
||||
optimize(nifNode, transformNode, skipMeshes);
|
||||
|
||||
const Nif::NiNode *ninode = dynamic_cast<const Nif::NiNode*>(nifNode);
|
||||
if(ninode)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue