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:
Cedric Pinson
2009-09-09 09:52:54 +00:00
parent a851b0b412
commit 9b95a78e5d
8 changed files with 45 additions and 41 deletions

View File

@@ -46,7 +46,6 @@ namespace osgAnimation
/// Operation that must be done each frame
void clearTargets();
void normalizeTargets();
LinkVisitor* getOrCreateLinkVisitor();
void setLinkVisitor(LinkVisitor*);

View File

@@ -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(); }

View File

@@ -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() {}

View File

@@ -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;