123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- /* -*-c++-*-
- * Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net>
- *
- * This library is open source and may be redistributed and/or modified under
- * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
- * (at your option) any later version. The full license is in LICENSE file
- * included with this distribution, and on the openscenegraph.org website.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * OpenSceneGraph Public License for more details.
- */
- #ifndef OSGANIMATION_TARGET
- #define OSGANIMATION_TARGET 1
- #include <vector>
- #include <osg/Quat>
- #include <osg/Vec3>
- #include <osg/Vec2>
- #include <osg/Vec4>
- #include <osg/Referenced>
- #include <osgAnimation/Export>
- namespace osgAnimation
- {
- class Channel;
- class OSGANIMATION_EXPORT Target : public osg::Referenced
- {
- public:
- Target();
- virtual ~Target() {}
- void reset() { _weight = 0; _priorityWeight = 0; }
- int getCount() const { return referenceCount(); }
- float getWeight() const { return _weight; }
- protected:
- float _weight;
- float _priorityWeight;
- int _lastPriority;
- };
- template <class T>
- class TemplateTarget : public Target
- {
- public:
- TemplateTarget() : _target() {}
- TemplateTarget(const T& v) { setValue(v); }
- TemplateTarget(const TemplateTarget& v) { setValue(v.getValue()); }
- inline void lerp(float t, const T& a, const T& b);
- /**
- * The priority is used to detect a change of priority
- * It's important to update animation target in priority
- * order. eg:
- * all animation with priority 1
- * all animation with priority 0
- * all animation with priority -1
- * ...
- */
- void update(float weight, const T& val, int priority)
- {
- if (_weight || _priorityWeight)
- {
- if (_lastPriority != priority)
- {
- // change in priority
- // add to weight with the same previous priority cumulated weight
- _weight += _priorityWeight * (1.0 - _weight);
- _priorityWeight = 0;
- _lastPriority = priority;
- }
- _priorityWeight += weight;
- float t = (1.0 - _weight) * weight / _priorityWeight;
- lerp(t, _target, val);
- }
- else
- {
- _priorityWeight = weight;
- _lastPriority = priority;
- _target = val;
- }
- }
- const T& getValue() const { return _target; }
- void setValue(const T& value) { _target = value; }
- protected:
- T _target;
- };
- template <class T>
- inline void TemplateTarget<T>::lerp(float t, const T& a, const T& b)
- {
- _target = a * (1.0f - t) + b * t;
- }
- template <>
- inline void TemplateTarget<osg::Quat>::lerp(float t, const osg::Quat& a, const osg::Quat& b)
- {
- if (a.asVec4() * b.asVec4() < 0.0)
- {
- _target = a * (1.0f - t) + b * -t;
- }
- else
- {
- _target = a * (1.0f - t) + b * t;
- }
- osg::Quat::value_type len2 = _target.length2();
- if ( len2 != 1.0 && len2 != 0.0)
- _target *= 1.0/sqrt(len2);
- }
- typedef TemplateTarget<osg::Matrixf> MatrixTarget;
- typedef TemplateTarget<osg::Quat> QuatTarget;
- typedef TemplateTarget<osg::Vec3> Vec3Target;
- typedef TemplateTarget<osg::Vec4> Vec4Target;
- typedef TemplateTarget<osg::Vec2> Vec2Target;
- typedef TemplateTarget<float> FloatTarget;
- typedef TemplateTarget<double> DoubleTarget;
- }
- #endif
|