forked from teamnwah/openmw-tes3coop
		
	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