2 * Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net>
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.
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.
16#ifndef OSGANIMATION_TARGET
17#define OSGANIMATION_TARGET 1
24#include <osg/Referenced>
25#include <osgAnimation/Export>
32 class OSGANIMATION_EXPORT Target : public osg::Referenced
38 void reset() { _weight = 0; _priorityWeight = 0; }
39 int getCount() const { return referenceCount(); }
40 float getWeight() const { return _weight; }
43 float _priorityWeight;
49 class TemplateTarget : public Target
53 TemplateTarget() : _target() {}
54 TemplateTarget(const T& v) { setValue(v); }
55 TemplateTarget(const TemplateTarget& v) { setValue(v.getValue()); }
57 inline void lerp(float t, const T& a, const T& b);
60 * The priority is used to detect a change of priority
61 * It's important to update animation target in priority
63 * all animation with priority 1
64 * all animation with priority 0
65 * all animation with priority -1
68 void update(float weight, const T& val, int priority)
70 if (_weight || _priorityWeight)
72 if (_lastPriority != priority)
75 // add to weight with the same previous priority cumulated weight
76 _weight += _priorityWeight * (1.0 - _weight);
78 _lastPriority = priority;
81 _priorityWeight += weight;
82 float t = (1.0 - _weight) * weight / _priorityWeight;
83 lerp(t, _target, val);
87 _priorityWeight = weight;
88 _lastPriority = priority;
92 const T& getValue() const { return _target; }
94 void setValue(const T& value) { _target = value; }
102 inline void TemplateTarget<T>::lerp(float t, const T& a, const T& b)
104 _target = a * (1.0f - t) + b * t;
108 inline void TemplateTarget<osg::Quat>::lerp(float t, const osg::Quat& a, const osg::Quat& b)
110 if (a.asVec4() * b.asVec4() < 0.0)
112 _target = a * (1.0f - t) + b * -t;
116 _target = a * (1.0f - t) + b * t;
119 osg::Quat::value_type len2 = _target.length2();
120 if ( len2 != 1.0 && len2 != 0.0)
121 _target *= 1.0/sqrt(len2);
124 typedef TemplateTarget<osg::Matrixf> MatrixTarget;
125 typedef TemplateTarget<osg::Quat> QuatTarget;
126 typedef TemplateTarget<osg::Vec3> Vec3Target;
127 typedef TemplateTarget<osg::Vec4> Vec4Target;
128 typedef TemplateTarget<osg::Vec2> Vec2Target;
129 typedef TemplateTarget<float> FloatTarget;
130 typedef TemplateTarget<double> DoubleTarget;