root/OpenSceneGraph/trunk/include/osgAnimation/RigGeometry @ 10693

Revision 10693, 4.4 kB (checked in by cedricpinson, 4 years ago)

From Cedric Pinson, The following commit include:
* Refactore of RigGeometry? to support hardware skinning
* Refactore of Timeline to split Action in differents files
* Add example how to use hardware skinning

Line 
1/*  -*-c++-*-
2 *  Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net>
3 *
4 * This library is open source and may be redistributed and/or modified under 
5 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
6 * (at your option) any later version.  The full license is in LICENSE file
7 * included with this distribution, and on the openscenegraph.org website.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * OpenSceneGraph Public License for more details.
13*/
14
15#ifndef OSGANIMATION_RIGGEOMETRY_H
16#define OSGANIMATION_RIGGEOMETRY_H
17
18#include <osgAnimation/Export>
19#include <osgAnimation/Skeleton>
20#include <osgAnimation/RigTransform>
21#include <osg/Geometry>
22
23namespace osgAnimation
24{
25
26    class OSGANIMATION_EXPORT RigGeometry : public osg::Geometry
27    {
28    public:
29
30        RigGeometry();
31        RigGeometry(const osg::Geometry& b);
32        RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
33
34        META_Object(osgAnimation, RigGeometry);
35
36        void setInfluenceMap(VertexInfluenceMap* vertexInfluenceMap) { _vertexInfluenceMap = vertexInfluenceMap; }
37        const VertexInfluenceMap* getInfluenceMap() const { return _vertexInfluenceMap.get();}
38        VertexInfluenceMap* getInfluenceMap() { return _vertexInfluenceMap.get();}
39 
40        const Skeleton* getSkeleton() const;
41        Skeleton* getSkeleton();
42        // will be used by the update callback to init correctly the rig mesh
43        void setSkeleton(Skeleton*);
44       
45        void setNeedToComputeMatrix(bool state) { _needToComputeMatrix = state;}
46        bool getNeedToComputeMatrix() const { return _needToComputeMatrix;}
47       
48
49        // this build the internal database about vertex influence and bones
50        void buildVertexInfluenceSet();
51        const VertexInfluenceSet& getVertexInfluenceSet() const;
52
53        void computeMatrixFromRootSkeleton();
54
55
56        // set implementation of rig method
57        void setRigTransformImplementation(RigTransform*);
58        RigTransform* getRigTransformImplementation();
59
60        virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
61        void update();
62
63        const osg::Matrix& getMatrixFromSkeletonToGeometry() const;
64        const osg::Matrix& getInvMatrixFromSkeletonToGeometry() const;
65
66    protected:
67
68        osg::ref_ptr<RigTransform> _rigTransformImplementation;
69
70        VertexInfluenceSet _vertexInfluenceSet;
71        osg::ref_ptr<VertexInfluenceMap> _vertexInfluenceMap;
72
73        osg::Matrix _matrixFromSkeletonToGeometry;
74        osg::Matrix _invMatrixFromSkeletonToGeometry;
75        osg::observer_ptr<Skeleton> _root;
76        bool _needToComputeMatrix;
77 
78        struct FindNearestParentSkeleton : public osg::NodeVisitor
79        {
80            osg::ref_ptr<Skeleton> _root;
81            FindNearestParentSkeleton() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_PARENTS) {}
82            void apply(osg::Transform& node)
83            {
84                if (_root.valid())
85                    return;
86                _root = dynamic_cast<osgAnimation::Skeleton*>(&node);
87                traverse(node);
88            }
89        };
90
91
92        struct UpdateVertex : public osg::Drawable::UpdateCallback
93        {
94            virtual void update(osg::NodeVisitor*, osg::Drawable* drw)
95            {
96                RigGeometry* geom = dynamic_cast<RigGeometry*>(drw);
97                if (!geom)
98                    return;
99                if (!geom->getSkeleton() && !geom->getParents().empty())
100                {
101                    FindNearestParentSkeleton finder;
102                    if (geom->getParents().size() > 1)
103                        osg::notify(osg::WARN) << "A RigGeometry should not have multi parent ( " << geom->getName() << " )" << std::endl;
104                    geom->getParents()[0]->accept(finder);
105
106                    if (!finder._root.valid())
107                        return;
108                    geom->buildVertexInfluenceSet();
109                    geom->setSkeleton(finder._root.get());
110                }
111
112                if (!geom->getSkeleton())
113                    return;
114
115                if (geom->getNeedToComputeMatrix())
116                    geom->computeMatrixFromRootSkeleton();
117
118                geom->update();
119            }
120        };
121   };
122
123}
124
125#endif
Note: See TracBrowser for help on using the browser.