File: skeleton.hpp

package info (click to toggle)
openmw 0.49.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 33,992 kB
  • sloc: cpp: 372,479; xml: 2,149; sh: 1,403; python: 797; makefile: 26
file content (85 lines) | stat: -rw-r--r-- 2,645 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#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();

        osg::Matrixf mMatrixInSkeletonSpace;

        osg::MatrixTransform* mNode;

        std::vector<std::unique_ptr<Bone>> mChildren;

        /// Update the skeleton-space matrix of this bone and all its children.
        void update(const osg::Matrixf* parentMatrixInSkeletonSpace);
    };

    /// @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