/* -*-c++-*- * 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 * (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. * * Authors: * Cedric Pinson * Michael Platings */ #ifndef OSGANIMATION_CHANNEL #define OSGANIMATION_CHANNEL 1 #include #include #include #include #include namespace osgAnimation { class OSGANIMATION_EXPORT Channel : public osg::Object { public: Channel(); Channel(const Channel& channel); virtual ~Channel(); virtual Channel* clone() const = 0; virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; } virtual const char* libraryName() const { return "osgAnimation"; } virtual const char* className() const { return "Channel"; } virtual void update(double time, float weight, int priority) = 0; virtual void reset() = 0; virtual Target* getTarget() = 0; virtual bool setTarget(Target*) = 0; const std::string& getName() const; void setName(const std::string& name); virtual double getStartTime() const = 0; virtual double getEndTime() const = 0; const std::string& getTargetName() const; void setTargetName(const std::string& name); 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; std::string _name; }; template class TemplateChannel : public Channel { public: typedef typename SamplerType::UsingType UsingType; typedef TemplateTarget TargetType; typedef TemplateKeyframeContainer KeyframeContainerType; Object* cloneType() const { return new TemplateChannel(); } Object* clone(const osg::CopyOp&) const { return new TemplateChannel(*this); } Channel* clone() const { return new TemplateChannel(*this); } TemplateChannel (const TemplateChannel& channel) : Channel(channel) { if (channel.getTargetTyped()) _target = new TargetType(*channel.getTargetTyped()); if (channel.getSamplerTyped()) _sampler = new SamplerType(*channel.getSamplerTyped()); } TemplateChannel (SamplerType* s = 0,TargetType* target = 0) { if (target) _target = target; else _target = new TargetType; _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(double time, float weight, int priority) { // skip if weight == 0 if (weight < 1e-4) return; typename SamplerType::UsingType value; _sampler->getValueAt(time, value); _target->update(weight, value, priority); } virtual void reset() { _target->reset(); } virtual Target* getTarget() { return _target.get();} virtual bool setTarget(Target* target) { _target = dynamic_cast(target); return _target.get() == target; } SamplerType* getOrCreateSampler() { if (!_sampler.valid()) _sampler = new SamplerType; return _sampler.get(); } Sampler* getSampler() { return _sampler.get(); } const Sampler* getSampler() const { return _sampler.get(); } SamplerType* getSamplerTyped() { return _sampler.get();} const SamplerType* getSamplerTyped() const { return _sampler.get();} 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 double getStartTime() const { return _sampler->getStartTime(); } virtual double getEndTime() const { return _sampler->getEndTime(); } protected: osg::ref_ptr _target; osg::ref_ptr _sampler; }; typedef std::vector > ChannelList; typedef TemplateChannel DoubleStepChannel; typedef TemplateChannel FloatStepChannel; typedef TemplateChannel Vec2StepChannel; typedef TemplateChannel Vec3StepChannel; typedef TemplateChannel Vec4StepChannel; typedef TemplateChannel QuatStepChannel; typedef TemplateChannel DoubleLinearChannel; typedef TemplateChannel FloatLinearChannel; typedef TemplateChannel Vec2LinearChannel; typedef TemplateChannel Vec3LinearChannel; typedef TemplateChannel Vec4LinearChannel; typedef TemplateChannel QuatSphericalLinearChannel; typedef TemplateChannel MatrixLinearChannel; typedef TemplateChannel FloatCubicBezierChannel; typedef TemplateChannel DoubleCubicBezierChannel; typedef TemplateChannel Vec2CubicBezierChannel; typedef TemplateChannel Vec3CubicBezierChannel; typedef TemplateChannel Vec4CubicBezierChannel; } #endif