mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 19:56:38 +00:00 
			
		
		
		
	With this PR we optimise a function that is called quite often when loading new cells. We remove avoidable dynamic_casts. We remove an unused pair.second element. We convert a map to an unordered_map because its ordering is irrelevant in this case. We avoid adding the root Skeleton node to the bones' node path.
		
			
				
	
	
		
			90 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			90 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #ifndef OPENMW_COMPONENTS_NIFOSG_SKELETON_H
 | |
| #define OPENMW_COMPONENTS_NIFOSG_SKELETON_H
 | |
| 
 | |
| #include <osg/Group>
 | |
| 
 | |
| #include <memory>
 | |
| #include <unordered_map>
 | |
| 
 | |
| namespace SceneUtil
 | |
| {
 | |
| 
 | |
|     /// @brief Defines a Bone hierarchy, used for updating of skeleton-space bone matrices.
 | |
|     /// @note To prevent unnecessary updates, only bones that are used for skinning will be added to this hierarchy.
 | |
|     class Bone
 | |
|     {
 | |
|     public:
 | |
|         Bone();
 | |
|         ~Bone();
 | |
| 
 | |
|         osg::Matrixf mMatrixInSkeletonSpace;
 | |
| 
 | |
|         osg::MatrixTransform* mNode;
 | |
| 
 | |
|         std::vector<Bone*> mChildren;
 | |
| 
 | |
|         /// Update the skeleton-space matrix of this bone and all its children.
 | |
|         void update(const osg::Matrixf* parentMatrixInSkeletonSpace);
 | |
| 
 | |
|     private:
 | |
|         Bone(const Bone&);
 | |
|         void operator=(const Bone&);
 | |
|     };
 | |
| 
 | |
|     /// @brief Handles the bone matrices for any number of child RigGeometries.
 | |
|     /// @par Bones should be created as osg::MatrixTransform children of the skeleton.
 | |
|     /// To be a referenced by a RigGeometry, a bone needs to have a unique name.
 | |
|     class Skeleton : public osg::Group
 | |
|     {
 | |
|     public:
 | |
|         Skeleton();
 | |
|         Skeleton(const Skeleton& copy, const osg::CopyOp& copyop);
 | |
| 
 | |
|         META_Node(SceneUtil, Skeleton)
 | |
| 
 | |
|         /// Retrieve a bone by name.
 | |
|         Bone* getBone(const std::string& name);
 | |
| 
 | |
|         /// Request an update of bone matrices. May be a no-op if already updated in this frame.
 | |
|         void updateBoneMatrices(unsigned int traversalNumber);
 | |
| 
 | |
|         enum ActiveType
 | |
|         {
 | |
|             Inactive=0,
 | |
|             SemiActive, /// Like Active, but don't bother with Update (including new bounding box) if we're off-screen
 | |
|             Active
 | |
|         };
 | |
| 
 | |
|         /// Set the skinning active flag. Inactive skeletons will not have their child rigs updated.
 | |
|         /// You should set this flag to false if you know that bones are not currently moving.
 | |
|         void setActive(ActiveType active);
 | |
| 
 | |
|         bool getActive() const;
 | |
| 
 | |
|         void traverse(osg::NodeVisitor& nv) override;
 | |
| 
 | |
|         void markDirty();
 | |
| 
 | |
|         void childInserted(unsigned int) override;
 | |
|         void childRemoved(unsigned int, unsigned int) override;
 | |
| 
 | |
|     private:
 | |
|         // The root bone is not a "real" bone, it has no corresponding node in the scene graph.
 | |
|         // As far as the scene graph goes we support multiple root bones.
 | |
|         std::unique_ptr<Bone> mRootBone;
 | |
| 
 | |
|         typedef std::unordered_map<std::string, std::vector<osg::MatrixTransform*> > BoneCache;
 | |
|         BoneCache mBoneCache;
 | |
|         bool mBoneCacheInit;
 | |
| 
 | |
|         bool mNeedToUpdateBoneMatrices;
 | |
| 
 | |
|         ActiveType mActive;
 | |
| 
 | |
|         unsigned int mLastFrameNumber;
 | |
|         unsigned int mLastCullFrameNumber;
 | |
|     };
 | |
| 
 | |
| }
 | |
| 
 | |
| #endif
 |