From 9b95a78e5dc7440b0fefb1f6e768f72d1d25fdf7 Mon Sep 17 00:00:00 2001 From: Cedric Pinson Date: Wed, 9 Sep 2009 09:52:54 +0000 Subject: [PATCH] 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::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. --- include/osgAnimation/AnimationManagerBase | 1 - include/osgAnimation/Channel | 27 +++++++++++++- include/osgAnimation/CubicBezier | 9 ++++- include/osgAnimation/Target | 37 ++++++------------- src/osgAnimation/AnimationManagerBase.cpp | 5 --- src/osgAnimation/BasicAnimationManager.cpp | 3 -- src/osgAnimation/CMakeLists.txt | 1 - src/osgAnimation/TimelineAnimationManager.cpp | 3 +- 8 files changed, 45 insertions(+), 41 deletions(-) diff --git a/include/osgAnimation/AnimationManagerBase b/include/osgAnimation/AnimationManagerBase index 4393848b5..c19bfb272 100644 --- a/include/osgAnimation/AnimationManagerBase +++ b/include/osgAnimation/AnimationManagerBase @@ -46,7 +46,6 @@ namespace osgAnimation /// Operation that must be done each frame void clearTargets(); - void normalizeTargets(); LinkVisitor* getOrCreateLinkVisitor(); void setLinkVisitor(LinkVisitor*); diff --git a/include/osgAnimation/Channel b/include/osgAnimation/Channel index 61c955685..ea04e6b86 100644 --- a/include/osgAnimation/Channel +++ b/include/osgAnimation/Channel @@ -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 KeyframeContainerType; Channel* clone() const { return new TemplateChannel(*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(); } diff --git a/include/osgAnimation/CubicBezier b/include/osgAnimation/CubicBezier index 718fc2110..70f270dbd 100644 --- a/include/osgAnimation/CubicBezier +++ b/include/osgAnimation/CubicBezier @@ -1,5 +1,5 @@ /* -*-c++-*- - * Copyright (C) 2008 Cedric Pinson + * Copyright (C) 2008 Cedric Pinson * * 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() {} diff --git a/include/osgAnimation/Target b/include/osgAnimation/Target index e811a5606..8b5400a0d 100644 --- a/include/osgAnimation/Target +++ b/include/osgAnimation/Target @@ -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 - inline void TemplateTarget::normalize() - { - _weight += _priorityWeight * (1.0f - _weight); - if (_weight < 0.9999f ) - if (_weight > 0.0001f) - _target /= _weight; // rescale by default - } - template inline void TemplateTarget::lerp(float t, const T& a, const T& b) { @@ -118,24 +107,20 @@ namespace osgAnimation template <> inline void TemplateTarget::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::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 QuatTarget; typedef TemplateTarget Vec3Target; typedef TemplateTarget Vec4Target; diff --git a/src/osgAnimation/AnimationManagerBase.cpp b/src/osgAnimation/AnimationManagerBase.cpp index 2fa40a75c..2e3d2f67a 100644 --- a/src/osgAnimation/AnimationManagerBase.cpp +++ b/src/osgAnimation/AnimationManagerBase.cpp @@ -30,11 +30,6 @@ void AnimationManagerBase::clearTargets() for (TargetSet::iterator it = _targets.begin(); it != _targets.end(); it++) (*it).get()->reset(); } -void AnimationManagerBase::normalizeTargets() -{ - for (TargetSet::iterator it = _targets.begin(); it != _targets.end(); it++) - (*it).get()->normalize(); -} void AnimationManagerBase::operator()(osg::Node* node, osg::NodeVisitor* nv) { diff --git a/src/osgAnimation/BasicAnimationManager.cpp b/src/osgAnimation/BasicAnimationManager.cpp index 5648531f4..93c718978 100644 --- a/src/osgAnimation/BasicAnimationManager.cpp +++ b/src/osgAnimation/BasicAnimationManager.cpp @@ -113,9 +113,6 @@ void BasicAnimationManager::update (double time) toremove.pop_back(); } } - - for (TargetSet::iterator it = _targets.begin(); it != _targets.end(); it++) - (*it).get()->normalize(); } diff --git a/src/osgAnimation/CMakeLists.txt b/src/osgAnimation/CMakeLists.txt index 04a17889c..9aff2a5e5 100644 --- a/src/osgAnimation/CMakeLists.txt +++ b/src/osgAnimation/CMakeLists.txt @@ -53,7 +53,6 @@ ADD_LIBRARY(${LIB_NAME} ActionVisitor.cpp Animation.cpp AnimationManagerBase.cpp - AnimationManager.cpp BasicAnimationManager.cpp Bone.cpp BoneMapVisitor.cpp diff --git a/src/osgAnimation/TimelineAnimationManager.cpp b/src/osgAnimation/TimelineAnimationManager.cpp index 3fcc827e8..65bb71cd9 100644 --- a/src/osgAnimation/TimelineAnimationManager.cpp +++ b/src/osgAnimation/TimelineAnimationManager.cpp @@ -1,5 +1,5 @@ /* -*-c++-*- - * Copyright (C) 2008 Cedric Pinson + * Copyright (C) 2008 Cedric Pinson * * 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,5 +36,4 @@ void TimelineAnimationManager::update(double time) { clearTargets(); _timeline->update(time); - normalizeTargets(); }