Panda3D

lerp.cxx

00001 // Filename: lerp.cxx
00002 // Created by:  frang (30May00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 
00016 #include "lerp.h"
00017 
00018 #include "clockObject.h"
00019 #include "throw_event.h"
00020 
00021 TypeHandle Lerp::_type_handle;
00022 TypeHandle AutonomousLerp::_type_handle;
00023 
00024 static INLINE float scale_t(float t, float start, float end) {
00025   float ret = t;
00026   if (ret < start)
00027     ret = start;
00028   if (ret > end)
00029     ret = end;
00030   // Avoid a possible divide-by-zero
00031   if (end == 0.0f)
00032       return 0.0f;
00033   return ret / end;
00034 }
00035 
00036 Lerp::Lerp(LerpFunctor* func, float endt, LerpBlendType* blend)
00037   : _blend(blend), _func(func), _startt(0.), _endt(endt),
00038     _delta(1.), _t(0.) {}
00039 
00040 Lerp::Lerp(LerpFunctor* func, float startt, float endt,
00041            LerpBlendType* blend) : _blend(blend), _func(func),
00042                                    _startt(startt),
00043                                    _endt(endt),
00044                                    _delta(1.),
00045                                    _t(startt) {}
00046 
00047 Lerp::Lerp(const Lerp& c) : _blend(c._blend), _func(c._func), _event(c._event),
00048                             _startt(c._startt), _endt(c._endt),
00049                             _delta(c._delta), _t(c._t) {}
00050 
00051 Lerp::~Lerp() {}
00052 
00053 Lerp& Lerp::operator=(const Lerp& c) {
00054   _blend = c._blend;
00055   _func = c._func;
00056   _event = c._event;
00057   _startt = c._startt;
00058   _endt = c._endt;
00059   _delta = c._delta;
00060   _t = c._t;
00061   return *this;
00062 }
00063 
00064 void Lerp::step() {
00065   _t += _delta;
00066   if (is_done()) {
00067     (*_func)(1.0);
00068     if (!_event.empty()) {
00069       throw_event(_event);
00070     }
00071   } else {
00072     float t = scale_t(_t, _startt, _endt);
00073     t = (_blend==(LerpBlendType*)0L)?t:(*_blend)(t);
00074     (*_func)(t);
00075   }
00076 }
00077 
00078 void Lerp::set_step_size(float delta) {
00079   _delta = delta;
00080 }
00081 
00082 float Lerp::get_step_size() const {
00083   return _delta;
00084 }
00085 
00086 void Lerp::set_t(float t) {
00087   _t = t;
00088   float x = scale_t(_t, _startt, _endt);
00089   x = (_blend==(LerpBlendType*)0L)?x:(*_blend)(x);
00090   (*_func)(x);
00091 }
00092 
00093 float Lerp::get_t() const {
00094   return _t;
00095 }
00096 
00097 bool Lerp::is_done() const {
00098   return (_t >= _endt);
00099 }
00100 
00101 LerpFunctor* Lerp::get_functor() const {
00102   return _func;
00103 }
00104 
00105 void Lerp::set_end_event(const std::string& event) {
00106   _event = event;
00107 }
00108 
00109 std::string Lerp::get_end_event() const {
00110   return _event;
00111 }
00112 
00113 AutonomousLerp::AutonomousLerp(LerpFunctor* func, float endt,
00114                                LerpBlendType* blend, EventHandler* handler)
00115   : _blend(blend), _func(func), _handler(handler),
00116     _startt(0.), _endt(endt), _t(0.) {}
00117 
00118 AutonomousLerp::AutonomousLerp(LerpFunctor* func, float startt, float endt,
00119                                LerpBlendType* blend, EventHandler* handler)
00120   : _blend(blend), _func(func), _handler(handler),
00121     _startt(startt), _endt(endt), _t(startt) {}
00122 
00123 AutonomousLerp::AutonomousLerp(const AutonomousLerp& c) : _blend(c._blend),
00124                                                           _func(c._func),
00125                                                           _handler(c._handler),
00126                                                           _event(c._event),
00127                                                           _startt(c._startt),
00128                                                           _endt(c._endt),
00129                                                           _t(c._t) {}
00130 
00131 AutonomousLerp::~AutonomousLerp() {}
00132 
00133 AutonomousLerp& AutonomousLerp::operator=(const AutonomousLerp& c) {
00134   _blend = c._blend;
00135   _func = c._func;
00136   _handler = c._handler;
00137   _event = c._event;
00138   _startt = c._startt;
00139   _endt = c._endt;
00140   _t = c._t;
00141   return *this;
00142 }
00143 
00144 void AutonomousLerp::start() {
00145   _t = _startt;
00146   _handler->add_hook("NewFrame", handle_event, this);
00147 }
00148 
00149 void AutonomousLerp::stop() {
00150   _handler->remove_hook("NewFrame", handle_event, this);
00151 }
00152 
00153 void AutonomousLerp::resume() {
00154   _handler->add_hook("NewFrame", handle_event, this);
00155 }
00156 
00157 bool AutonomousLerp::is_done() const {
00158   return (_t >= _endt);
00159 }
00160 
00161 LerpFunctor* AutonomousLerp::get_functor() const {
00162   return _func;
00163 }
00164 
00165 void AutonomousLerp::set_t(float t) {
00166   _t = t;
00167   float x = scale_t(_t, _startt, _endt);
00168   x = (_blend==(LerpBlendType*)0L)?x:(*_blend)(x);
00169   (*_func)(x);
00170 }
00171 
00172 float AutonomousLerp::get_t() const {
00173   return _t;
00174 }
00175 
00176 void AutonomousLerp::set_end_event(const std::string& event) {
00177   _event = event;
00178 }
00179 
00180 std::string AutonomousLerp::get_end_event() const {
00181   return _event;
00182 }
00183 
00184 void AutonomousLerp::step() {
00185   // Probably broken because it does not set the final value when t
00186   // exceeds end_t. see fixed Lerp::step() above
00187   if (is_done()) {
00188     stop();
00189     return;
00190   }
00191   float delta = ClockObject::get_global_clock()->get_dt();
00192   _t += delta;
00193   float t = scale_t(_t, _startt, _endt);
00194   t = (_blend==(LerpBlendType*)0L)?t:(*_blend)(t);
00195   (*_func)(t);
00196   if (is_done() && !_event.empty())
00197     throw_event(_event);
00198 }
00199 
00200 void AutonomousLerp::handle_event(const Event *, void* data) {
00201   AutonomousLerp* l = (AutonomousLerp*)data;
00202   l->step();
00203 }
 All Classes Functions Variables Enumerations