PageRenderTime 21ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 1ms

/indra/llmath/llinterp.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 426 lines | 304 code | 69 blank | 53 comment | 9 complexity | 42d0bad19c4eae5cf33457d6896fd00b MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llinterp.h
  3. *
  4. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  5. * Second Life Viewer Source Code
  6. * Copyright (C) 2010, Linden Research, Inc.
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation;
  11. * version 2.1 of the License only.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. *
  22. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  23. * $/LicenseInfo$
  24. */
  25. #ifndef LL_LLINTERP_H
  26. #define LL_LLINTERP_H
  27. #if defined(LL_WINDOWS)
  28. // macro definitions for common math constants (e.g. M_PI) are declared under the _USE_MATH_DEFINES
  29. // on Windows system.
  30. // So, let's define _USE_MATH_DEFINES before including math.h
  31. #define _USE_MATH_DEFINES
  32. #endif
  33. #include "math.h"
  34. // Class from which different types of interpolators can be derived
  35. class LLInterpVal
  36. {
  37. public:
  38. virtual ~LLInterpVal() {}
  39. virtual void interp(LLInterpVal &target, const F32 frac); // Linear interpolation for each type
  40. };
  41. template <typename Type>
  42. class LLInterp
  43. {
  44. public:
  45. LLInterp();
  46. virtual ~LLInterp() {}
  47. virtual void start();
  48. void update(const F32 time);
  49. const Type &getCurVal() const;
  50. void setStartVal(const Type &start_val);
  51. const Type &getStartVal() const;
  52. void setEndVal(const Type &target_val);
  53. const Type &getEndVal() const;
  54. void setStartTime(const F32 time);
  55. F32 getStartTime() const;
  56. void setEndTime(const F32 time);
  57. F32 getEndTime() const;
  58. BOOL isActive() const;
  59. BOOL isDone() const;
  60. protected:
  61. F32 mStartTime;
  62. F32 mEndTime;
  63. F32 mDuration;
  64. BOOL mActive;
  65. BOOL mDone;
  66. Type mStartVal;
  67. Type mEndVal;
  68. F32 mCurTime;
  69. Type mCurVal;
  70. };
  71. template <typename Type>
  72. class LLInterpLinear : public LLInterp<Type>
  73. {
  74. public:
  75. /*virtual*/ void start();
  76. void update(const F32 time);
  77. F32 getCurFrac() const;
  78. protected:
  79. F32 mCurFrac;
  80. };
  81. template <typename Type>
  82. class LLInterpExp : public LLInterpLinear<Type>
  83. {
  84. public:
  85. void update(const F32 time);
  86. protected:
  87. };
  88. template <typename Type>
  89. class LLInterpAttractor : public LLInterp<Type>
  90. {
  91. public:
  92. LLInterpAttractor();
  93. /*virtual*/ void start();
  94. void setStartVel(const Type &vel);
  95. void setForce(const F32 force);
  96. void update(const F32 time);
  97. protected:
  98. F32 mForce;
  99. Type mStartVel;
  100. Type mVelocity;
  101. };
  102. template <typename Type>
  103. class LLInterpFunc : public LLInterp<Type>
  104. {
  105. public:
  106. LLInterpFunc();
  107. void update(const F32 time);
  108. void setFunc(Type (*)(const F32, void *data), void *data);
  109. protected:
  110. Type (*mFunc)(const F32 time, void *data);
  111. void *mData;
  112. };
  113. ///////////////////////////////////
  114. //
  115. // Implementation
  116. //
  117. //
  118. /////////////////////////////////
  119. //
  120. // LLInterp base class implementation
  121. //
  122. template <typename Type>
  123. LLInterp<Type>::LLInterp()
  124. : mStartVal(Type()), mEndVal(Type()), mCurVal(Type())
  125. {
  126. mStartTime = 0.f;
  127. mEndTime = 1.f;
  128. mDuration = 1.f;
  129. mCurTime = 0.f;
  130. mDone = FALSE;
  131. mActive = FALSE;
  132. }
  133. template <class Type>
  134. void LLInterp<Type>::setStartVal(const Type &start_val)
  135. {
  136. mStartVal = start_val;
  137. }
  138. template <class Type>
  139. void LLInterp<Type>::start()
  140. {
  141. mCurVal = mStartVal;
  142. mCurTime = mStartTime;
  143. mDone = FALSE;
  144. mActive = FALSE;
  145. }
  146. template <class Type>
  147. const Type &LLInterp<Type>::getStartVal() const
  148. {
  149. return mStartVal;
  150. }
  151. template <class Type>
  152. void LLInterp<Type>::setEndVal(const Type &end_val)
  153. {
  154. mEndVal = end_val;
  155. }
  156. template <class Type>
  157. const Type &LLInterp<Type>::getEndVal() const
  158. {
  159. return mEndVal;
  160. }
  161. template <class Type>
  162. const Type &LLInterp<Type>::getCurVal() const
  163. {
  164. return mCurVal;
  165. }
  166. template <class Type>
  167. void LLInterp<Type>::setStartTime(const F32 start_time)
  168. {
  169. mStartTime = start_time;
  170. mDuration = mEndTime - mStartTime;
  171. }
  172. template <class Type>
  173. F32 LLInterp<Type>::getStartTime() const
  174. {
  175. return mStartTime;
  176. }
  177. template <class Type>
  178. void LLInterp<Type>::setEndTime(const F32 end_time)
  179. {
  180. mEndTime = end_time;
  181. mDuration = mEndTime - mStartTime;
  182. }
  183. template <class Type>
  184. F32 LLInterp<Type>::getEndTime() const
  185. {
  186. return mEndTime;
  187. }
  188. template <class Type>
  189. BOOL LLInterp<Type>::isDone() const
  190. {
  191. return mDone;
  192. }
  193. template <class Type>
  194. BOOL LLInterp<Type>::isActive() const
  195. {
  196. return mActive;
  197. }
  198. //////////////////////////////
  199. //
  200. // LLInterpLinear derived class implementation.
  201. //
  202. template <typename Type>
  203. void LLInterpLinear<Type>::start()
  204. {
  205. LLInterp<Type>::start();
  206. mCurFrac = 0.f;
  207. }
  208. template <typename Type>
  209. void LLInterpLinear<Type>::update(const F32 time)
  210. {
  211. F32 target_frac = (time - this->mStartTime) / this->mDuration;
  212. F32 dfrac = target_frac - this->mCurFrac;
  213. if (target_frac >= 0.f)
  214. {
  215. this->mActive = TRUE;
  216. }
  217. if (target_frac > 1.f)
  218. {
  219. this->mCurVal = this->mEndVal;
  220. this->mCurFrac = 1.f;
  221. this->mCurTime = time;
  222. this->mDone = TRUE;
  223. return;
  224. }
  225. target_frac = llmin(1.f, target_frac);
  226. target_frac = llmax(0.f, target_frac);
  227. if (dfrac >= 0.f)
  228. {
  229. F32 total_frac = 1.f - this->mCurFrac;
  230. F32 inc_frac = dfrac / total_frac;
  231. this->mCurVal = inc_frac * this->mEndVal + (1.f - inc_frac) * this->mCurVal;
  232. this->mCurTime = time;
  233. }
  234. else
  235. {
  236. F32 total_frac = this->mCurFrac - 1.f;
  237. F32 inc_frac = dfrac / total_frac;
  238. this->mCurVal = inc_frac * this->mStartVal + (1.f - inc_frac) * this->mCurVal;
  239. this->mCurTime = time;
  240. }
  241. mCurFrac = target_frac;
  242. }
  243. template <class Type>
  244. F32 LLInterpLinear<Type>::getCurFrac() const
  245. {
  246. return mCurFrac;
  247. }
  248. //////////////////////////////
  249. //
  250. // LLInterpAttractor derived class implementation.
  251. //
  252. template <class Type>
  253. LLInterpAttractor<Type>::LLInterpAttractor() : LLInterp<Type>()
  254. {
  255. mForce = 0.1f;
  256. mVelocity *= 0.f;
  257. mStartVel *= 0.f;
  258. }
  259. template <class Type>
  260. void LLInterpAttractor<Type>::start()
  261. {
  262. LLInterp<Type>::start();
  263. mVelocity = mStartVel;
  264. }
  265. template <class Type>
  266. void LLInterpAttractor<Type>::setStartVel(const Type &vel)
  267. {
  268. mStartVel = vel;
  269. }
  270. template <class Type>
  271. void LLInterpAttractor<Type>::setForce(const F32 force)
  272. {
  273. mForce = force;
  274. }
  275. template <class Type>
  276. void LLInterpAttractor<Type>::update(const F32 time)
  277. {
  278. if (time > this->mStartTime)
  279. {
  280. this->mActive = TRUE;
  281. }
  282. else
  283. {
  284. return;
  285. }
  286. if (time > this->mEndTime)
  287. {
  288. this->mDone = TRUE;
  289. return;
  290. }
  291. F32 dt = time - this->mCurTime;
  292. Type dist_val = this->mEndVal - this->mCurVal;
  293. Type dv = 0.5*dt*dt*this->mForce*dist_val;
  294. this->mVelocity += dv;
  295. this->mCurVal += this->mVelocity * dt;
  296. this->mCurTime = time;
  297. }
  298. //////////////////////////////
  299. //
  300. // LLInterpFucn derived class implementation.
  301. //
  302. template <class Type>
  303. LLInterpFunc<Type>::LLInterpFunc() : LLInterp<Type>()
  304. {
  305. mFunc = NULL;
  306. mData = NULL;
  307. }
  308. template <class Type>
  309. void LLInterpFunc<Type>::setFunc(Type (*func)(const F32, void *data), void *data)
  310. {
  311. mFunc = func;
  312. mData = data;
  313. }
  314. template <class Type>
  315. void LLInterpFunc<Type>::update(const F32 time)
  316. {
  317. if (time > this->mStartTime)
  318. {
  319. this->mActive = TRUE;
  320. }
  321. else
  322. {
  323. return;
  324. }
  325. if (time > this->mEndTime)
  326. {
  327. this->mDone = TRUE;
  328. return;
  329. }
  330. this->mCurVal = (*mFunc)(time - this->mStartTime, mData);
  331. this->mCurTime = time;
  332. }
  333. //////////////////////////////
  334. //
  335. // LLInterpExp derived class implementation.
  336. //
  337. template <class Type>
  338. void LLInterpExp<Type>::update(const F32 time)
  339. {
  340. F32 target_frac = (time - this->mStartTime) / this->mDuration;
  341. if (target_frac >= 0.f)
  342. {
  343. this->mActive = TRUE;
  344. }
  345. if (target_frac > 1.f)
  346. {
  347. this->mCurVal = this->mEndVal;
  348. this->mCurFrac = 1.f;
  349. this->mCurTime = time;
  350. this->mDone = TRUE;
  351. return;
  352. }
  353. this->mCurFrac = 1.f - (F32)(exp(-2.f*target_frac));
  354. this->mCurVal = this->mStartVal + this->mCurFrac * (this->mEndVal - this->mStartVal);
  355. this->mCurTime = time;
  356. }
  357. #endif // LL_LLINTERP_H