From Michael Platings, I have removed Target::normalize() as calling it was incorrect - the interpolation is already done in such a way that the Target's value is always normalized.
Finally, I have fixed TemplateTarget<osg::Quat>::lerp() as it was giving incorrect results when interpolating between some small rotations. From Cedric Pinson, i renamed the method in channel to be more general. Adjusted the CubicBezier key constructor to use a single value as input.
This commit is contained in:
@@ -46,7 +46,6 @@ namespace osgAnimation
|
||||
|
||||
/// Operation that must be done each frame
|
||||
void clearTargets();
|
||||
void normalizeTargets();
|
||||
|
||||
LinkVisitor* getOrCreateLinkVisitor();
|
||||
void setLinkVisitor(LinkVisitor*);
|
||||
|
||||
@@ -54,6 +54,11 @@ namespace osgAnimation
|
||||
virtual Sampler* getSampler() = 0;
|
||||
virtual const Sampler* getSampler() const = 0;
|
||||
|
||||
// create a keyframe container from current target value
|
||||
// with one key only, can be used for debug or to create
|
||||
// easily a default channel from an existing one
|
||||
virtual bool createKeyframeContainerFromTargetValue() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
std::string _targetName;
|
||||
@@ -71,9 +76,9 @@ namespace osgAnimation
|
||||
typedef TemplateKeyframeContainer<typename SamplerType::KeyframeType> KeyframeContainerType;
|
||||
Channel* clone() const { return new TemplateChannel<SamplerType>(*this); }
|
||||
|
||||
TemplateChannel (const TemplateChannel& channel) :
|
||||
TemplateChannel (const TemplateChannel& channel) :
|
||||
Channel(channel),
|
||||
_target(new TargetType),
|
||||
_target(new TargetType(*channel.getTargetTyped())),
|
||||
_sampler(channel._sampler.get())
|
||||
{
|
||||
}
|
||||
@@ -87,6 +92,23 @@ namespace osgAnimation
|
||||
_sampler = s;
|
||||
}
|
||||
|
||||
virtual bool createKeyframeContainerFromTargetValue()
|
||||
{
|
||||
if (!_target.valid()) // no target it does not make sense to do it
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// create a key from current target value
|
||||
typename KeyframeContainerType::KeyType key(0, _target->getValue());
|
||||
// recreate the keyframe container
|
||||
getOrCreateSampler()->setKeyframeContainer(0);
|
||||
getOrCreateSampler()->getOrCreateKeyframeContainer();
|
||||
// add the key
|
||||
_sampler->getKeyframeContainerTyped()->push_back(key);
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual ~TemplateChannel() {}
|
||||
virtual void update(float time, float weight, int priority)
|
||||
{
|
||||
@@ -120,6 +142,7 @@ namespace osgAnimation
|
||||
void setSampler(SamplerType* sampler) { _sampler = sampler; }
|
||||
|
||||
TargetType* getTargetTyped() { return _target.get(); }
|
||||
const TargetType* getTargetTyped() const { return _target.get(); }
|
||||
void setTarget(TargetType* target) { _target = target; }
|
||||
|
||||
virtual float getStartTime() const { return _sampler->getStartTime(); }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2008 Cedric Pinson <mornifle@plopbyte.net>
|
||||
* 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
|
||||
@@ -36,6 +36,13 @@ namespace osgAnimation
|
||||
mPoint[1] = v1;
|
||||
mPoint[2] = v2;
|
||||
}
|
||||
// Constructor with value only
|
||||
TemplateCubicBezier(const T& v0)
|
||||
{
|
||||
mPoint[0] = v0;
|
||||
mPoint[1] = v0;
|
||||
mPoint[2] = v0;
|
||||
}
|
||||
|
||||
TemplateCubicBezier() {}
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ namespace osgAnimation
|
||||
|
||||
Target();
|
||||
virtual ~Target() {}
|
||||
virtual void normalize() = 0;
|
||||
void reset() { _weight = 0; _priorityWeight = 0; }
|
||||
int getCount() const { return referenceCount(); }
|
||||
float getWeight() const { return _weight; }
|
||||
@@ -53,6 +52,7 @@ namespace osgAnimation
|
||||
|
||||
TemplateTarget() {}
|
||||
TemplateTarget(const T& v) { setValue(v); }
|
||||
TemplateTarget(const TemplateTarget& v) { setValue(v.getValue()); }
|
||||
|
||||
inline void lerp(float t, const T& a, const T& b);
|
||||
|
||||
@@ -91,8 +91,6 @@ namespace osgAnimation
|
||||
}
|
||||
const T& getValue() const { return _target; }
|
||||
|
||||
inline void normalize();
|
||||
|
||||
void setValue(const T& value) { _target = value; }
|
||||
|
||||
protected:
|
||||
@@ -100,15 +98,6 @@ namespace osgAnimation
|
||||
T _target;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline void TemplateTarget<T>::normalize()
|
||||
{
|
||||
_weight += _priorityWeight * (1.0f - _weight);
|
||||
if (_weight < 0.9999f )
|
||||
if (_weight > 0.0001f)
|
||||
_target /= _weight; // rescale by default
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void TemplateTarget<T>::lerp(float t, const T& a, const T& b)
|
||||
{
|
||||
@@ -118,24 +107,20 @@ namespace osgAnimation
|
||||
template <>
|
||||
inline void TemplateTarget<osg::Quat>::lerp(float t, const osg::Quat& a, const osg::Quat& b)
|
||||
{
|
||||
_target = a * (1.0f - t) + b * t;
|
||||
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);
|
||||
}
|
||||
template <>
|
||||
inline void TemplateTarget<osg::Quat>::normalize()
|
||||
{
|
||||
_weight += _priorityWeight * (1.0f - _weight);
|
||||
if (_weight < 0.9999f )
|
||||
if (_weight > 0.0001f)
|
||||
{
|
||||
osg::Quat::value_type len2 = _target.length2(); // normalize
|
||||
if ( len2 != 1.0 && len2 != 0.0)
|
||||
_target *= 1.0/sqrt(len2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
typedef TemplateTarget<osg::Quat> QuatTarget;
|
||||
typedef TemplateTarget<osg::Vec3> Vec3Target;
|
||||
typedef TemplateTarget<osg::Vec4> Vec4Target;
|
||||
|
||||
Reference in New Issue
Block a user