Panda3D
|
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 }