root/OpenSceneGraph/trunk/include/osgAnimation/Target @ 10599

Revision 10599, 3.8 kB (checked in by cedricpinson, 5 years ago)

From Michael Platings, In Target, the default constructor is explicitly called on _target. This is necessary for FloatTarget? and DoubleTarget? so that _target is initialised to 0, otherwise you get a junk value. In MorphGeometry?.cpp, UpdateMorph::link now links channels of the same index to the same target. Previously a new FloatTarget? was created for each channel, so multiple animations didn't work.

RevLine 
[9093]1/*  -*-c++-*-
[10344]2 *  Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net>
[9093]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
16#ifndef OSGANIMATION_TARGET_H
17#define OSGANIMATION_TARGET_H
18
19#include <vector>
20#include <osg/Quat>
21#include <osg/Vec3>
22#include <osg/Vec2>
23#include <osg/Vec4>
24#include <osg/Referenced>
[9094]25#include <osgAnimation/Export>
[9093]26
27namespace osgAnimation
28{
29
30    class Channel;
31
[9094]32    class OSGANIMATION_EXPORT Target : public osg::Referenced
[9093]33    {
34    public:
35           
36        Target();
[10561]37        virtual ~Target() {}
[10556]38        void reset() { _weight = 0; _priorityWeight = 0; }
39        int getCount() const { return referenceCount(); }
[9093]40        float getWeight() const { return _weight; }
41    protected:
42        float _weight;
[10556]43        float _priorityWeight;
44        int _lastPriority;
[9093]45    };
46
47
48    template <class T>
49    class TemplateTarget : public Target
50    {
51    public:
52           
[10599]53        TemplateTarget() : _target() {}
[9093]54        TemplateTarget(const T& v) { setValue(v); }
[10576]55        TemplateTarget(const TemplateTarget& v) { setValue(v.getValue()); }
[9093]56
[10556]57        inline void lerp(float t, const T& a, const T& b);
58
59        /**
60         *  The priority is used to detect a change of priority
61         *  It's important to update animation target in priority
62         *  order. eg:
63         *  all animation with priority 1
64         *  all animation with priority 0
65         *  all animation with priority -1
66         *  ...
67         */
68        void update(float weight, const T& val, int priority)
[9119]69        {
[10556]70            if (_weight || _priorityWeight)
71            {
72                if (_lastPriority != priority)
73                {
74                    // change in priority
75                    // add to weight with the same previous priority cumulated weight
76                    _weight += _priorityWeight * (1.0 - _weight);
77                    _priorityWeight = 0;
78                    _lastPriority = priority;
79                }
80
81                _priorityWeight += weight;
82                float t = (1.0 - _weight) * weight / _priorityWeight;
83                lerp(t, _target, val);
84            }
[9093]85            else
[9119]86            {
[10556]87                _priorityWeight = weight;
88                _lastPriority = priority;
89                _target = val;
[9119]90            }
[9093]91        }
[10556]92        const T& getValue() const { return _target; }
[9093]93
[10556]94        void setValue(const T& value) { _target = value; }
[9093]95
96    protected:
97
98        T _target;
99    };
100
[10556]101    template <class T>
102    inline void TemplateTarget<T>::lerp(float t, const T& a, const T& b)
103    {
104        _target = a * (1.0f - t) + b * t;
105    }
106
[9093]107    template <>
[10556]108    inline void TemplateTarget<osg::Quat>::lerp(float t, const osg::Quat& a, const osg::Quat& b)
[9093]109    {
[10576]110        if (a.asVec4() * b.asVec4() < 0.0)
111        {
112            _target = a * (1.0f - t) + b * -t;
113        }
114        else
115        {
116            _target = a * (1.0f - t) + b * t;
117        }
118
[10556]119        osg::Quat::value_type len2 = _target.length2();
120        if ( len2 != 1.0 && len2 != 0.0)
121            _target *= 1.0/sqrt(len2);
122    }
[10576]123
[9093]124    typedef TemplateTarget<osg::Quat> QuatTarget;
125    typedef TemplateTarget<osg::Vec3> Vec3Target;
126    typedef TemplateTarget<osg::Vec4> Vec4Target;
127    typedef TemplateTarget<osg::Vec2> Vec2Target;
128    typedef TemplateTarget<float> FloatTarget;
129    typedef TemplateTarget<double> DoubleTarget;
130 
131}
132
133#endif
Note: See TracBrowser for help on using the browser.