Curve.cpp 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352
  1. // Purposely not including Base.h here, or any other gameplay dependencies
  2. // so this class can be reused between gameplay and gameplay-encoder.
  3. #include "Curve.h"
  4. #include "Quaternion.h"
  5. #include <cassert>
  6. #include <cmath>
  7. #include <memory>
  8. using std::memcpy;
  9. using std::fabs;
  10. using std::sqrt;
  11. using std::cos;
  12. using std::sin;
  13. using std::exp;
  14. using std::strcmp;
  15. #ifndef NULL
  16. #define NULL 0
  17. #endif
  18. #ifndef MATH_PI
  19. #define MATH_PI 3.14159265358979323846f
  20. #endif
  21. #ifndef MATH_PIOVER2
  22. #define MATH_PIOVER2 1.57079632679489661923f
  23. #endif
  24. #ifndef MATH_PIX2
  25. #define MATH_PIX2 6.28318530717958647693f
  26. #endif
  27. // Object deletion macro
  28. #ifndef SAFE_DELETE
  29. #define SAFE_DELETE(x) \
  30. if (x) \
  31. { \
  32. delete x; \
  33. x = NULL; \
  34. }
  35. #endif
  36. // Array deletion macro
  37. #ifndef SAFE_DELETE_ARRAY
  38. #define SAFE_DELETE_ARRAY(x) \
  39. if (x) \
  40. { \
  41. delete[] x; \
  42. x = NULL; \
  43. }
  44. #endif
  45. namespace gameplay
  46. {
  47. Curve* Curve::create(unsigned int pointCount, unsigned int componentCount)
  48. {
  49. return new Curve(pointCount, componentCount);
  50. }
  51. Curve::Curve(unsigned int pointCount, unsigned int componentCount)
  52. : _pointCount(pointCount), _componentCount(componentCount), _componentSize(sizeof(float)*componentCount), _quaternionOffset(NULL), _points(NULL)
  53. {
  54. _points = new Point[_pointCount];
  55. for (unsigned int i = 0; i < _pointCount; i++)
  56. {
  57. _points[i].time = 0.0f;
  58. _points[i].value = new float[_componentCount];
  59. _points[i].inValue = new float[_componentCount];
  60. _points[i].outValue = new float[_componentCount];
  61. _points[i].type = LINEAR;
  62. }
  63. _points[_pointCount - 1].time = 1.0f;
  64. }
  65. Curve::~Curve()
  66. {
  67. SAFE_DELETE_ARRAY(_points);
  68. SAFE_DELETE_ARRAY(_quaternionOffset);
  69. }
  70. Curve::Point::Point()
  71. : time(0.0f), value(NULL), inValue(NULL), outValue(NULL)
  72. {
  73. }
  74. Curve::Point::~Point()
  75. {
  76. SAFE_DELETE_ARRAY(value);
  77. SAFE_DELETE_ARRAY(inValue);
  78. SAFE_DELETE_ARRAY(outValue);
  79. }
  80. unsigned int Curve::getPointCount() const
  81. {
  82. return _pointCount;
  83. }
  84. unsigned int Curve::getComponentCount() const
  85. {
  86. return _componentCount;
  87. }
  88. float Curve::getStartTime() const
  89. {
  90. return _points[0].time;
  91. }
  92. float Curve::getEndTime() const
  93. {
  94. return _points[_pointCount-1].time;
  95. }
  96. void Curve::setPoint(unsigned int index, float time, float* value, InterpolationType type)
  97. {
  98. setPoint(index, time, value, type, NULL, NULL);
  99. }
  100. void Curve::setPoint(unsigned int index, float time, float* value, InterpolationType type, float* inValue, float* outValue)
  101. {
  102. assert(index < _pointCount && time >= 0.0f && time <= 1.0f && !(index == 0 && time != 0.0f) && !(_pointCount != 1 && index == _pointCount - 1 && time != 1.0f));
  103. _points[index].time = time;
  104. _points[index].type = type;
  105. if (value)
  106. memcpy(_points[index].value, value, _componentSize);
  107. if (inValue)
  108. memcpy(_points[index].inValue, inValue, _componentSize);
  109. if (outValue)
  110. memcpy(_points[index].outValue, outValue, _componentSize);
  111. }
  112. void Curve::setTangent(unsigned int index, InterpolationType type, float* inValue, float* outValue)
  113. {
  114. assert(index < _pointCount);
  115. _points[index].type = type;
  116. if (inValue)
  117. memcpy(_points[index].inValue, inValue, _componentSize);
  118. if (outValue)
  119. memcpy(_points[index].outValue, outValue, _componentSize);
  120. }
  121. void Curve::evaluate(float time, float* dst) const
  122. {
  123. assert(dst && time >= 0 && time <= 1.0f);
  124. // Check if the point count is 1.
  125. // Check if we are at or beyond the bounds of the curve.
  126. if (_pointCount == 1 || time <= _points[0].time)
  127. {
  128. memcpy(dst, _points[0].value, _componentSize);
  129. return;
  130. }
  131. else if (time >= _points[_pointCount - 1].time)
  132. {
  133. memcpy(dst, _points[_pointCount - 1].value, _componentSize);
  134. return;
  135. }
  136. // Locate the points we are interpolating between using a binary search.
  137. unsigned int index = determineIndex(time);
  138. Point* from = _points + index;
  139. Point* to = _points + (index + 1);
  140. // Calculate the fractional time between the two points.
  141. float scale = (to->time - from->time);
  142. float t = (time - from->time) / scale;
  143. // Calculate the value of the curve discretely if appropriate.
  144. switch (from->type)
  145. {
  146. case BEZIER:
  147. {
  148. interpolateBezier(t, from, to, dst);
  149. return;
  150. }
  151. case BSPLINE:
  152. {
  153. Point* c0;
  154. Point* c1;
  155. if (index == 0)
  156. {
  157. c0 = from;
  158. }
  159. else
  160. {
  161. c0 = (_points + index - 1);
  162. }
  163. if (index == _pointCount - 2)
  164. {
  165. c1 = to;
  166. }
  167. else
  168. {
  169. c1 = (_points + index + 2);
  170. }
  171. interpolateBSpline(t, c0, from, to, c1, dst);
  172. return;
  173. }
  174. case FLAT:
  175. {
  176. interpolateHermiteFlat(t, from, to, dst);
  177. return;
  178. }
  179. case HERMITE:
  180. {
  181. interpolateHermite(t, from, to, dst);
  182. return;
  183. }
  184. case LINEAR:
  185. {
  186. // Can just break here because linear formula follows switch
  187. break;
  188. }
  189. case SMOOTH:
  190. {
  191. interpolateHermiteSmooth(t, index, from, to, dst);
  192. return;
  193. }
  194. case STEP:
  195. {
  196. memcpy(dst, from->value, _componentSize);
  197. return;
  198. }
  199. case QUADRATIC_IN:
  200. {
  201. t *= t;
  202. break;
  203. }
  204. case QUADRATIC_OUT:
  205. {
  206. t *= -(t - 2.0f);
  207. break;
  208. }
  209. case QUADRATIC_IN_OUT:
  210. {
  211. float tx2 = t * 2.0f;
  212. if (tx2 < 1.0f)
  213. t = 0.5f * (tx2 * tx2);
  214. else
  215. {
  216. float temp = tx2 - 1.0f;
  217. t = 0.5f * (-( temp * (temp - 2.0f)) + 1.0f);
  218. }
  219. break;
  220. }
  221. case QUADRATIC_OUT_IN:
  222. {
  223. if (t < 0.5f)
  224. {
  225. t = 2.0f * t * (1.0f - t);
  226. }
  227. else
  228. {
  229. t = 1.0f + 2.0f * t * (t - 1.0f);
  230. }
  231. break;
  232. }
  233. case CUBIC_IN:
  234. {
  235. t *= t * t;
  236. break;
  237. }
  238. case CUBIC_OUT:
  239. {
  240. t--;
  241. t = t * t * t + 1;
  242. break;
  243. }
  244. case CUBIC_IN_OUT:
  245. {
  246. if ((t *= 2.0f) < 1.0f)
  247. {
  248. t = t * t * t * 0.5f;
  249. }
  250. else
  251. {
  252. t -= 2.0f;
  253. t = (t * t * t + 2.0f) * 0.5f;
  254. }
  255. break;
  256. }
  257. case CUBIC_OUT_IN:
  258. {
  259. t = (2.0f * t - 1.0f);
  260. t = (t * t * t + 1) * 0.5f;
  261. break;
  262. }
  263. case QUARTIC_IN:
  264. {
  265. t *= t * t * t;
  266. break;
  267. }
  268. case QUARTIC_OUT:
  269. {
  270. t--;
  271. t = -(t * t * t * t) + 1.0f;
  272. break;
  273. }
  274. case QUARTIC_IN_OUT:
  275. {
  276. t *= 2.0f;
  277. if (t < 1.0f)
  278. {
  279. t = 0.5f * t * t * t * t;
  280. }
  281. else
  282. {
  283. t -= 2.0f;
  284. t = -0.5f * (t * t * t * t - 2.0f);
  285. }
  286. break;
  287. }
  288. case QUARTIC_OUT_IN:
  289. {
  290. t = 2.0f * t - 1.0f;
  291. if (t < 0.0f)
  292. {
  293. t = 0.5f * (-(t * t) * t * t + 1.0f);
  294. }
  295. else
  296. {
  297. t = 0.5f * (t * t * t * t + 1.0f);
  298. }
  299. break;
  300. }
  301. case QUINTIC_IN:
  302. {
  303. t *= t * t * t * t;
  304. break;
  305. }
  306. case QUINTIC_OUT:
  307. {
  308. t--;
  309. t = t * t * t * t * t + 1.0f;
  310. break;
  311. }
  312. case QUINTIC_IN_OUT:
  313. {
  314. t *= 2.0f;
  315. if (t < 1.0f)
  316. {
  317. t = 0.5f * t * t * t * t * t;
  318. }
  319. else
  320. {
  321. t -= 2.0f;
  322. t = 0.5f * (t * t * t * t * t + 2.0f);
  323. }
  324. break;
  325. }
  326. case QUINTIC_OUT_IN:
  327. {
  328. t = 2.0f * t - 1.0f;
  329. t = 0.5f * (t * t * t * t * t + 1.0f);
  330. break;
  331. }
  332. case SINE_IN:
  333. {
  334. t = -(cos(t * MATH_PIOVER2) - 1.0f);
  335. break;
  336. }
  337. case SINE_OUT:
  338. {
  339. t = sin(t * MATH_PIOVER2);
  340. break;
  341. }
  342. case SINE_IN_OUT:
  343. {
  344. t = -0.5f * (cos(MATH_PI * t) - 1.0f);
  345. break;
  346. }
  347. case SINE_OUT_IN:
  348. {
  349. if (t < 0.5f)
  350. {
  351. t = 0.5f * sin(MATH_PI * t);
  352. }
  353. else
  354. {
  355. t = -0.5f * cos(MATH_PIOVER2 * (2.0f * t - 1.0f)) + 1.0f;
  356. }
  357. break;
  358. }
  359. case EXPONENTIAL_IN:
  360. {
  361. if (t != 0.0f)
  362. {
  363. t = exp(10.0f * (t - 1.0f));
  364. }
  365. break;
  366. }
  367. case EXPONENTIAL_OUT:
  368. {
  369. if (t != 1.0f)
  370. {
  371. t = -exp(-10.0f * t) + 1.0f;
  372. }
  373. break;
  374. }
  375. case EXPONENTIAL_IN_OUT:
  376. {
  377. if (t != 0.0f && t != 1.0f)
  378. {
  379. if (t < 0.5f)
  380. {
  381. t = 0.5f * exp(10.0f * (2.0f * t - 1.0f));
  382. }
  383. else
  384. {
  385. t = -0.5f * exp(10.0f * (-2.0f * t + 1.0f)) + 1.0f;
  386. }
  387. }
  388. break;
  389. }
  390. case EXPONENTIAL_OUT_IN:
  391. {
  392. if (t != 0.0f && t != 1.0f)
  393. {
  394. if (t < 0.5f)
  395. {
  396. t = -0.5f * exp(-20.0f * t) + 0.5f;
  397. }
  398. else
  399. {
  400. t = 0.5f * exp(20.0f * (t - 1.0f)) + 0.5f;
  401. }
  402. }
  403. break;
  404. }
  405. case CIRCULAR_IN:
  406. {
  407. t = -(sqrt(1.0f - t * t) - 1.0f);
  408. break;
  409. }
  410. case CIRCULAR_OUT:
  411. {
  412. t--;
  413. t = sqrt(1.0f - t * t);
  414. break;
  415. }
  416. case CIRCULAR_IN_OUT:
  417. {
  418. t *= 2.0f;
  419. if (t < 1.0f)
  420. {
  421. t = 0.5f * (-sqrt((1.0f - t * t)) + 1.0f);
  422. }
  423. else
  424. {
  425. t -= 2.0f;
  426. t = 0.5f * (sqrt((1.0f - t * t)) + 1.0f);
  427. }
  428. break;
  429. }
  430. case CIRCULAR_OUT_IN:
  431. {
  432. t = 2.0f * t - 1.0f;
  433. if (t < 0.0f)
  434. {
  435. t = 0.5f * sqrt(1.0f - t * t);
  436. }
  437. else
  438. {
  439. t = 0.5f * (2.0f - sqrt(1.0f - t * t));
  440. }
  441. break;
  442. }
  443. case ELASTIC_IN:
  444. {
  445. if (t != 0.0f && t != 1.0f)
  446. {
  447. t = t - 1.0f;
  448. t = -1.0f * ( exp(10.0f * t) * sin( (t - 0.075f) * MATH_PIX2 / 0.3f ) );
  449. }
  450. break;
  451. }
  452. case ELASTIC_OUT:
  453. {
  454. if (t != 0.0f && t != 1.0f)
  455. {
  456. t = exp(-10.0f * t) * sin((t - 0.075f) * MATH_PIX2 / 0.3f) + 1.0f;
  457. }
  458. break;
  459. }
  460. case ELASTIC_IN_OUT:
  461. {
  462. if (t != 0.0f && t != 1.0f)
  463. {
  464. t = 2.0f * t - 1.0f;
  465. if (t < 0.0f)
  466. {
  467. t = -0.5f * (exp((10 * t)) * sin(((t - 0.1125f) * MATH_PIX2 / 0.45f)));
  468. }
  469. else
  470. {
  471. t = 0.5f * exp((-10 * t)) * sin(((t - 0.1125f) * MATH_PIX2 / 0.45f)) + 1.0f;
  472. }
  473. }
  474. break;
  475. }
  476. case ELASTIC_OUT_IN:
  477. {
  478. if (t != 0.0f && t != 1.0f)
  479. {
  480. t *= 2.0f;
  481. if (t < 1.0f)
  482. {
  483. t = 0.5f * (exp((-10 * t)) * sin(((t - 0.1125f) * (MATH_PIX2) / 0.45f))) + 0.5f;
  484. }
  485. else
  486. {
  487. t = 0.5f * (exp((10 *(t - 2))) * sin(((t - 0.1125f) * (MATH_PIX2) / 0.45f))) + 0.5f;
  488. }
  489. }
  490. break;
  491. }
  492. case OVERSHOOT_IN:
  493. {
  494. t = t * t * (2.70158f * t - 1.70158f);
  495. break;
  496. }
  497. case OVERSHOOT_OUT:
  498. {
  499. t--;
  500. t = t * t * (2.70158f * t + 1.70158f) + 1;
  501. break;
  502. }
  503. case OVERSHOOT_IN_OUT:
  504. {
  505. t *= 2.0f;
  506. if (t < 1.0f)
  507. {
  508. t = 0.5f * t * t * (3.5949095f * t - 2.5949095f);
  509. }
  510. else
  511. {
  512. t -= 2.0f;
  513. t = 0.5f * (t * t * (3.5949095f * t + 2.5949095f) + 2.0f);
  514. }
  515. break;
  516. }
  517. case OVERSHOOT_OUT_IN:
  518. {
  519. t = 2.0f * t - 1.0f;
  520. if (t < 0.0f)
  521. {
  522. t = 0.5f * (t * t * (3.5949095f * t + 2.5949095f) + 1.0f);
  523. }
  524. else
  525. {
  526. t = 0.5f * (t * t * (3.5949095f * t - 2.5949095f) + 1.0f);
  527. }
  528. break;
  529. }
  530. case BOUNCE_IN:
  531. {
  532. t = 1.0f - t;
  533. if (t < 0.36363636363636365f)
  534. {
  535. t = 7.5625f * t * t;
  536. }
  537. else if (t < 0.7272727272727273f)
  538. {
  539. t -= 0.5454545454545454f;
  540. t = 7.5625f * t * t + 0.75f;
  541. }
  542. else if (t < 0.9090909090909091f)
  543. {
  544. t -= 0.8181818181818182f;
  545. t = 7.5625f * t * t + 0.9375f;
  546. }
  547. else
  548. {
  549. t -= 0.9545454545454546f;
  550. t = 7.5625f * t * t + 0.984375f;
  551. }
  552. t = 1.0f - t;
  553. break;
  554. }
  555. case BOUNCE_OUT:
  556. {
  557. if (t < 0.36363636363636365f)
  558. {
  559. t = 7.5625f * t * t;
  560. }
  561. else if (t < 0.7272727272727273f)
  562. {
  563. t -= 0.5454545454545454f;
  564. t = 7.5625f * t * t + 0.75f;
  565. }
  566. else if (t < 0.9090909090909091f)
  567. {
  568. t -= 0.8181818181818182f;
  569. t = 7.5625f * t * t + 0.9375f;
  570. }
  571. else
  572. {
  573. t -= 0.9545454545454546f;
  574. t = 7.5625f * t * t + 0.984375f;
  575. }
  576. break;
  577. }
  578. case BOUNCE_IN_OUT:
  579. {
  580. if (t < 0.5f)
  581. {
  582. t = 1.0f - t * 2.0f;
  583. if (t < 0.36363636363636365f)
  584. {
  585. t = 7.5625f * t * t;
  586. }
  587. else if (t < 0.7272727272727273f)
  588. {
  589. t -= 0.5454545454545454f;
  590. t = 7.5625f * t * t + 0.75f;
  591. }
  592. else if (t < 0.9090909090909091f)
  593. {
  594. t -= 0.8181818181818182f;
  595. t = 7.5625f * t * t + 0.9375f;
  596. }
  597. else
  598. {
  599. t -= 0.9545454545454546f;
  600. t = 7.5625f * t * t + 0.984375f;
  601. }
  602. t = (1.0f - t) * 0.5f;
  603. }
  604. else
  605. {
  606. t = t * 2.0f - 1.0f;
  607. if (t < 0.36363636363636365f)
  608. {
  609. t = 7.5625f * t * t;
  610. }
  611. else if (t < 0.7272727272727273f)
  612. {
  613. t -= 0.5454545454545454f;
  614. t = 7.5625f * t * t + 0.75f;
  615. }
  616. else if (t < 0.9090909090909091f)
  617. {
  618. t -= 0.8181818181818182f;
  619. t = 7.5625f * t * t + 0.9375f;
  620. }
  621. else
  622. {
  623. t -= 0.9545454545454546f;
  624. t = 7.5625f * t * t + 0.984375f;
  625. }
  626. t = 0.5f * t + 0.5f;
  627. }
  628. break;
  629. }
  630. case BOUNCE_OUT_IN:
  631. {
  632. if (t < 0.1818181818f)
  633. {
  634. t = 15.125f * t * t;
  635. }
  636. else if (t < 0.3636363636f)
  637. {
  638. t = 1.5f + (-8.250000001f + 15.125f * t) * t;
  639. }
  640. else if (t < 0.4545454546f)
  641. {
  642. t = 3.0f + (-12.375f + 15.125f * t) * t;
  643. }
  644. else if (t < 0.5f)
  645. {
  646. t = 3.9375f + (-14.4375f + 15.125f * t) * t;
  647. }
  648. else if (t <= 0.5454545455f)
  649. {
  650. t = -3.625000004f + (15.81250001f - 15.125f * t) * t;
  651. }
  652. else if (t <= 0.6363636365f)
  653. {
  654. t = -4.75f + (17.875f - 15.125f * t) * t;
  655. }
  656. else if (t <= 0.8181818180f)
  657. {
  658. t = -7.374999995f + (21.99999999f - 15.125f * t) * t;
  659. }
  660. else
  661. {
  662. t = -14.125f + (30.25f - 15.125f * t) * t;
  663. }
  664. break;
  665. }
  666. }
  667. interpolateLinear(t, from, to, dst);
  668. }
  669. float Curve::lerp(float t, float from, float to)
  670. {
  671. return lerpInl(t, from, to);
  672. }
  673. void Curve::setQuaternionOffset(unsigned int offset)
  674. {
  675. assert(offset <= (_componentCount - 4));
  676. if (!_quaternionOffset)
  677. _quaternionOffset = new unsigned int[1];
  678. *_quaternionOffset = offset;
  679. }
  680. void Curve::interpolateBezier(float s, Point* from, Point* to, float* dst) const
  681. {
  682. float s_2 = s * s;
  683. float eq0 = 1 - s;
  684. float eq0_2 = eq0 * eq0;
  685. float eq1 = eq0_2 * eq0;
  686. float eq2 = 3 * s * eq0_2;
  687. float eq3 = 3 * s_2 * eq0;
  688. float eq4 = s_2 * s;
  689. float* fromValue = from->value;
  690. float* toValue = to->value;
  691. float* outValue = from->outValue;
  692. float* inValue = to->inValue;
  693. if (!_quaternionOffset)
  694. {
  695. for (unsigned int i = 0; i < _componentCount; i++)
  696. {
  697. if (fromValue[i] == toValue[i])
  698. dst[i] = fromValue[i];
  699. else
  700. dst[i] = bezier(eq1, eq2, eq3, eq4, fromValue[i], outValue[i], toValue[i], inValue[i]);
  701. }
  702. }
  703. else
  704. {
  705. // Interpolate any values up to the quaternion offset as scalars.
  706. unsigned int quaternionOffset = *_quaternionOffset;
  707. unsigned int i = 0;
  708. for (i = 0; i < quaternionOffset; i++)
  709. {
  710. if (fromValue[i] == toValue[i])
  711. dst[i] = fromValue[i];
  712. else
  713. dst[i] = bezier(eq1, eq2, eq3, eq4, fromValue[i], outValue[i], toValue[i], inValue[i]);
  714. }
  715. // Handle quaternion component.
  716. float interpTime = bezier(eq1, eq2, eq3, eq4, from->time, outValue[i], to->time, inValue[i]);
  717. interpolateQuaternion(interpTime, (fromValue + i), (toValue + i), (dst + i));
  718. // Handle remaining components (if any) as scalars
  719. for (i += 4; i < _componentCount; i++)
  720. {
  721. if (fromValue[i] == toValue[i])
  722. dst[i] = fromValue[i];
  723. else
  724. dst[i] = bezier(eq1, eq2, eq3, eq4, fromValue[i], outValue[i], toValue[i], inValue[i]);
  725. }
  726. }
  727. }
  728. void Curve::interpolateBSpline(float s, Point* c0, Point* c1, Point* c2, Point* c3, float* dst) const
  729. {
  730. float s_2 = s * s;
  731. float s_3 = s_2 * s;
  732. float eq0 = (-s_3 + 3 * s_2 - 3 * s + 1) / 6.0f;
  733. float eq1 = (3 * s_3 - 6 * s_2 + 4) / 6.0f;
  734. float eq2 = (-3 * s_3 + 3 * s_2 + 3 * s + 1) / 6.0f;
  735. float eq3 = s_3 / 6.0f;
  736. float* c0Value = c0->value;
  737. float* c1Value = c1->value;
  738. float* c2Value = c2->value;
  739. float* c3Value = c3->value;
  740. if (!_quaternionOffset)
  741. {
  742. for (unsigned int i = 0; i < _componentCount; i++)
  743. {
  744. if (c1Value[i] == c2Value[i])
  745. dst[i] = c1Value[i];
  746. else
  747. dst[i] = bspline(eq0, eq1, eq2, eq3, c0Value[i], c1Value[i], c2Value[i], c3Value[i]);
  748. }
  749. }
  750. else
  751. {
  752. // Interpolate any values up to the quaternion offset as scalars.
  753. unsigned int quaternionOffset = *_quaternionOffset;
  754. unsigned int i = 0;
  755. for (i = 0; i < quaternionOffset; i++)
  756. {
  757. if (c1Value[i] == c2Value[i])
  758. dst[i] = c1Value[i];
  759. else
  760. dst[i] = bspline(eq0, eq1, eq2, eq3, c0Value[i], c1Value[i], c2Value[i], c3Value[i]);
  761. }
  762. // Handle quaternion component.
  763. float interpTime;
  764. if (c0->time == c1->time)
  765. interpTime = bspline(eq0, eq1, eq2, eq3, -c0->time, c1->time, c2->time, c3->time);
  766. else if (c2->time == c3->time)
  767. interpTime = bspline(eq0, eq1, eq2, eq3, c0->time, c1->time, c2->time, -c3->time);
  768. else
  769. interpTime = bspline(eq0, eq1, eq2, eq3, c0->time, c1->time, c2->time, c3->time);
  770. interpolateQuaternion(s, (c1Value + i) , (c2Value + i), (dst + i));
  771. // Handle remaining components (if any) as scalars
  772. for (i += 4; i < _componentCount; i++)
  773. {
  774. if (c1Value[i] == c2Value[i])
  775. dst[i] = c1Value[i];
  776. else
  777. dst[i] = bspline(eq0, eq1, eq2, eq3, c0Value[i], c1Value[i], c2Value[i], c3Value[i]);
  778. }
  779. }
  780. }
  781. void Curve::interpolateHermite(float s, Point* from, Point* to, float* dst) const
  782. {
  783. // Calculate the hermite basis functions.
  784. float s_2 = s * s; // t^2
  785. float s_3 = s_2 * s; // t^3
  786. float h00 = 2 * s_3 - 3 * s_2 + 1; // basis function 0
  787. float h01 = -2 * s_3 + 3 * s_2; // basis function 1
  788. float h10 = s_3 - 2 * s_2 + s; // basis function 2
  789. float h11 = s_3 - s_2; // basis function 3
  790. float* fromValue = from->value;
  791. float* toValue = to->value;
  792. float* outValue = from->outValue;
  793. float* inValue = to->inValue;
  794. if (!_quaternionOffset)
  795. {
  796. for (unsigned int i = 0; i < _componentCount; i++)
  797. {
  798. if (fromValue[i] == toValue[i])
  799. dst[i] = fromValue[i];
  800. else
  801. dst[i] = hermite(h00, h01, h10, h11, fromValue[i], outValue[i], toValue[i], inValue[i]);
  802. }
  803. }
  804. else
  805. {
  806. // Interpolate any values up to the quaternion offset as scalars.
  807. unsigned int quaternionOffset = *_quaternionOffset;
  808. unsigned int i = 0;
  809. for (i = 0; i < quaternionOffset; i++)
  810. {
  811. if (fromValue[i] == toValue[i])
  812. dst[i] = fromValue[i];
  813. else
  814. dst[i] = hermite(h00, h01, h10, h11, fromValue[i], outValue[i], toValue[i], inValue[i]);
  815. }
  816. // Handle quaternion component.
  817. float interpTime = hermite(h00, h01, h10, h11, from->time, outValue[i], to->time, inValue[i]);
  818. interpolateQuaternion(interpTime, (fromValue + i), (toValue + i), (dst + i));
  819. // Handle remaining components (if any) as scalars
  820. for (i += 4; i < _componentCount; i++)
  821. {
  822. if (fromValue[i] == toValue[i])
  823. dst[i] = fromValue[i];
  824. else
  825. dst[i] = hermite(h00, h01, h10, h11, fromValue[i], outValue[i], toValue[i], inValue[i]);
  826. }
  827. }
  828. }
  829. void Curve::interpolateHermiteFlat(float s, Point* from, Point* to, float* dst) const
  830. {
  831. // Calculate the hermite basis functions.
  832. float s_2 = s * s; // t^2
  833. float s_3 = s_2 * s; // t^3
  834. float h00 = 2 * s_3 - 3 * s_2 + 1; // basis function 0
  835. float h01 = -2 * s_3 + 3 * s_2; // basis function 1
  836. float* fromValue = from->value;
  837. float* toValue = to->value;
  838. if (!_quaternionOffset)
  839. {
  840. for (unsigned int i = 0; i < _componentCount; i++)
  841. {
  842. if (fromValue[i] == toValue[i])
  843. dst[i] = fromValue[i];
  844. else
  845. dst[i] = hermiteFlat(h00, h01, fromValue[i], toValue[i]);
  846. }
  847. }
  848. else
  849. {
  850. // Interpolate any values up to the quaternion offset as scalars.
  851. unsigned int quaternionOffset = *_quaternionOffset;
  852. unsigned int i = 0;
  853. for (i = 0; i < quaternionOffset; i++)
  854. {
  855. if (fromValue[i] == toValue[i])
  856. dst[i] = fromValue[i];
  857. else
  858. dst[i] = hermiteFlat(h00, h01, fromValue[i], toValue[i]);
  859. }
  860. // Handle quaternion component.
  861. float interpTime = hermiteFlat(h00, h01, from->time, to->time);
  862. interpolateQuaternion(interpTime, (fromValue + i), (toValue + i), (dst + i));
  863. // Handle remaining components (if any) as scalars
  864. for (i += 4; i < _componentCount; i++)
  865. {
  866. if (fromValue[i] == toValue[i])
  867. dst[i] = fromValue[i];
  868. else
  869. dst[i] = hermiteFlat(h00, h01, fromValue[i], toValue[i]);
  870. }
  871. }
  872. }
  873. void Curve::interpolateHermiteSmooth(float s, unsigned int index, Point* from, Point* to, float* dst) const
  874. {
  875. // Calculate the hermite basis functions.
  876. float s_2 = s * s; // t^2
  877. float s_3 = s_2 * s; // t^3
  878. float h00 = 2 * s_3 - 3 * s_2 + 1; // basis function 0
  879. float h01 = -2 * s_3 + 3 * s_2; // basis function 1
  880. float h10 = s_3 - 2 * s_2 + s; // basis function 2
  881. float h11 = s_3 - s_2; // basis function 3
  882. float inValue;
  883. float outValue;
  884. float* fromValue = from->value;
  885. float* toValue = to->value;
  886. if (!_quaternionOffset)
  887. {
  888. for (unsigned int i = 0; i < _componentCount; i++)
  889. {
  890. if (fromValue[i] == toValue[i])
  891. {
  892. dst[i] = fromValue[i];
  893. }
  894. else
  895. {
  896. if (index == 0)
  897. {
  898. outValue = toValue[i] - fromValue[i];
  899. }
  900. else
  901. {
  902. outValue = (toValue[i] - (from - 1)->value[i]) * ((from->time - (from - 1)->time) / (to->time - (from - 1)->time));
  903. }
  904. if (index == _pointCount - 2)
  905. {
  906. inValue = toValue[i] - fromValue[i];
  907. }
  908. else
  909. {
  910. inValue = ((to + 1)->value[i] - fromValue[i]) * ((to->time - from->time) / ((to + 1)->time - from->time));
  911. }
  912. dst[i] = hermiteSmooth(h00, h01, h10, h11, fromValue[i], outValue, toValue[i], inValue);
  913. }
  914. }
  915. }
  916. else
  917. {
  918. // Interpolate any values up to the quaternion offset as scalars.
  919. unsigned int quaternionOffset = *_quaternionOffset;
  920. unsigned int i = 0;
  921. for (i = 0; i < quaternionOffset; i++)
  922. {
  923. if (fromValue[i] == toValue[i])
  924. {
  925. dst[i] = fromValue[i];
  926. }
  927. else
  928. {
  929. if (index == 0)
  930. {
  931. outValue = toValue[i] - fromValue[i];
  932. }
  933. else
  934. {
  935. outValue = (toValue[i] - (from - 1)->value[i]) * ((from->time - (from - 1)->time) / (to->time - (from - 1)->time));
  936. }
  937. if (index == _pointCount - 2)
  938. {
  939. inValue = toValue[i] - fromValue[i];
  940. }
  941. else
  942. {
  943. inValue = ((to + 1)->value[i] - fromValue[i]) * ((to->time - from->time) / ((to + 1)->time - from->time));
  944. }
  945. dst[i] = hermiteSmooth(h00, h01, h10, h11, fromValue[i], outValue, toValue[i], inValue);
  946. }
  947. }
  948. // Handle quaternion component.
  949. if (index == 0)
  950. {
  951. outValue = to->time - from->time;
  952. }
  953. else
  954. {
  955. outValue = (to->time - (from - 1)->time) * ((from->time - (from - 1)->time) / (to->time - (from - 1)->time));
  956. }
  957. if (index == _pointCount - 2)
  958. {
  959. inValue = to->time - from->time;
  960. }
  961. else
  962. {
  963. inValue = ((to + 1)->time - from->time) * ((to->time - from->time) / ((to + 1)->time - from->time));
  964. }
  965. float interpTime = hermiteSmooth(h00, h01, h10, h11, from->time, outValue, to->time, inValue);
  966. interpolateQuaternion(interpTime, (fromValue + i), (toValue + i), (dst + i));
  967. // Handle remaining components (if any) as scalars
  968. for (i += 4; i < _componentCount; i++)
  969. {
  970. if (fromValue[i] == toValue[i])
  971. {
  972. dst[i] = fromValue[i];
  973. }
  974. else
  975. {
  976. // Interpolate as scalar.
  977. if (index == 0)
  978. {
  979. outValue = toValue[i] - fromValue[i];
  980. }
  981. else
  982. {
  983. outValue = (toValue[i] - (from - 1)->value[i]) * ((from->time - (from - 1)->time) / (to->time - (from - 1)->time));
  984. }
  985. if (index == _pointCount - 2)
  986. {
  987. inValue = toValue[i] - fromValue[i];
  988. }
  989. else
  990. {
  991. inValue = ((to + 1)->value[i] - fromValue[i]) * ((to->time - from->time) / ((to + 1)->time - from->time));
  992. }
  993. dst[i] = hermiteSmooth(h00, h01, h10, h11, fromValue[i], outValue, toValue[i], inValue);
  994. }
  995. }
  996. }
  997. }
  998. void Curve::interpolateLinear(float s, Point* from, Point* to, float* dst) const
  999. {
  1000. float* fromValue = from->value;
  1001. float* toValue = to->value;
  1002. if (!_quaternionOffset)
  1003. {
  1004. for (unsigned int i = 0; i < _componentCount; i++)
  1005. {
  1006. if (fromValue[i] == toValue[i])
  1007. dst[i] = fromValue[i];
  1008. else
  1009. dst[i] = lerpInl(s, fromValue[i], toValue[i]);
  1010. }
  1011. }
  1012. else
  1013. {
  1014. // Interpolate any values up to the quaternion offset as scalars.
  1015. unsigned int quaternionOffset = *_quaternionOffset;
  1016. unsigned int i = 0;
  1017. for (i = 0; i < quaternionOffset; i++)
  1018. {
  1019. if (fromValue[i] == toValue[i])
  1020. dst[i] = fromValue[i];
  1021. else
  1022. dst[i] = lerpInl(s, fromValue[i], toValue[i]);
  1023. }
  1024. // Handle quaternion component.
  1025. interpolateQuaternion(s, (fromValue + i), (toValue + i), (dst + i));
  1026. // handle any remaining components as scalars
  1027. for (i += 4; i < _componentCount; i++)
  1028. {
  1029. if (fromValue[i] == toValue[i])
  1030. dst[i] = fromValue[i];
  1031. else
  1032. dst[i] = lerpInl(s, fromValue[i], toValue[i]);
  1033. }
  1034. }
  1035. }
  1036. void Curve::interpolateQuaternion(float s, float* from, float* to, float* dst) const
  1037. {
  1038. // Evaluate.
  1039. if (s >= 0)
  1040. {
  1041. Quaternion::slerp(from[0], from[1], from[2], from[3], to[0], to[1], to[2], to[3], s, dst, dst + 1, dst + 2, dst + 3);
  1042. }
  1043. else
  1044. Quaternion::slerp(to[0], to[1], to[2], to[3], from[0], from[1], from[2], from[3], s, dst, dst + 1, dst + 2, dst + 3);
  1045. //((Quaternion*) dst)->normalize();
  1046. }
  1047. int Curve::determineIndex(float time) const
  1048. {
  1049. unsigned int min = 0;
  1050. unsigned int max = _pointCount - 1;
  1051. unsigned int mid = 0;
  1052. // Do a binary search to determine the index.
  1053. do
  1054. {
  1055. mid = (min + max) >> 1;
  1056. if (time >= _points[mid].time && time <= _points[mid + 1].time)
  1057. return mid;
  1058. else if (time < _points[mid].time)
  1059. max = mid - 1;
  1060. else
  1061. min = mid + 1;
  1062. } while (min <= max);
  1063. // We should never hit this!
  1064. return -1;
  1065. }
  1066. int Curve::getInterpolationType(const char* curveId)
  1067. {
  1068. if (strcmp(curveId, "BEZIER") == 0)
  1069. {
  1070. return Curve::BEZIER;
  1071. }
  1072. else if (strcmp(curveId, "BSPLINE") == 0)
  1073. {
  1074. return Curve::BSPLINE;
  1075. }
  1076. else if (strcmp(curveId, "FLAT") == 0)
  1077. {
  1078. return Curve::FLAT;
  1079. }
  1080. else if (strcmp(curveId, "HERMITE") == 0)
  1081. {
  1082. return Curve::HERMITE;
  1083. }
  1084. else if (strcmp(curveId, "LINEAR") == 0)
  1085. {
  1086. return Curve::LINEAR;
  1087. }
  1088. else if (strcmp(curveId, "SMOOTH") == 0)
  1089. {
  1090. return Curve::SMOOTH;
  1091. }
  1092. else if (strcmp(curveId, "STEP") == 0)
  1093. {
  1094. return Curve::STEP;
  1095. }
  1096. else if (strcmp(curveId, "QUADRATIC_IN") == 0)
  1097. {
  1098. return Curve::QUADRATIC_IN;
  1099. }
  1100. else if (strcmp(curveId, "QUADRATIC_OUT") == 0)
  1101. {
  1102. return Curve::QUADRATIC_OUT;
  1103. }
  1104. else if (strcmp(curveId, "QUADRATIC_IN_OUT") == 0)
  1105. {
  1106. return Curve::QUADRATIC_IN_OUT;
  1107. }
  1108. else if (strcmp(curveId, "QUADRATIC_OUT_IN") == 0)
  1109. {
  1110. return Curve::QUADRATIC_OUT_IN;
  1111. }
  1112. else if (strcmp(curveId, "CUBIC_IN") == 0)
  1113. {
  1114. return Curve::CUBIC_IN;
  1115. }
  1116. else if (strcmp(curveId, "CUBIC_OUT") == 0)
  1117. {
  1118. return Curve::CUBIC_OUT;
  1119. }
  1120. else if (strcmp(curveId, "CUBIC_IN_OUT") == 0)
  1121. {
  1122. return Curve::CUBIC_IN_OUT;
  1123. }
  1124. else if (strcmp(curveId, "CUBIC_OUT_IN") == 0)
  1125. {
  1126. return Curve::CUBIC_OUT_IN;
  1127. }
  1128. else if (strcmp(curveId, "QUARTIC_IN") == 0)
  1129. {
  1130. return Curve::QUARTIC_IN;
  1131. }
  1132. else if (strcmp(curveId, "QUARTIC_OUT") == 0)
  1133. {
  1134. return Curve::QUARTIC_OUT;
  1135. }
  1136. else if (strcmp(curveId, "QUARTIC_IN_OUT") == 0)
  1137. {
  1138. return Curve::QUARTIC_IN_OUT;
  1139. }
  1140. else if (strcmp(curveId, "QUARTIC_OUT_IN") == 0)
  1141. {
  1142. return Curve::QUARTIC_OUT_IN;
  1143. }
  1144. else if (strcmp(curveId, "QUINTIC_IN") == 0)
  1145. {
  1146. return Curve::QUINTIC_IN;
  1147. }
  1148. else if (strcmp(curveId, "QUINTIC_OUT") == 0)
  1149. {
  1150. return Curve::QUINTIC_OUT;
  1151. }
  1152. else if (strcmp(curveId, "QUINTIC_IN_OUT") == 0)
  1153. {
  1154. return Curve::QUINTIC_IN_OUT;
  1155. }
  1156. else if (strcmp(curveId, "QUINTIC_OUT_IN") == 0)
  1157. {
  1158. return Curve::QUINTIC_OUT_IN;
  1159. }
  1160. else if (strcmp(curveId, "SINE_IN") == 0)
  1161. {
  1162. return Curve::SINE_IN;
  1163. }
  1164. else if (strcmp(curveId, "SINE_OUT") == 0)
  1165. {
  1166. return Curve::SINE_OUT;
  1167. }
  1168. else if (strcmp(curveId, "SINE_IN_OUT") == 0)
  1169. {
  1170. return Curve::SINE_IN_OUT;
  1171. }
  1172. else if (strcmp(curveId, "SINE_OUT_IN") == 0)
  1173. {
  1174. return Curve::SINE_OUT_IN;
  1175. }
  1176. else if (strcmp(curveId, "EXPONENTIAL_IN") == 0)
  1177. {
  1178. return Curve::EXPONENTIAL_IN;
  1179. }
  1180. else if (strcmp(curveId, "EXPONENTIAL_OUT") == 0)
  1181. {
  1182. return Curve::EXPONENTIAL_OUT;
  1183. }
  1184. else if (strcmp(curveId, "EXPONENTIAL_IN_OUT") == 0)
  1185. {
  1186. return Curve::EXPONENTIAL_IN_OUT;
  1187. }
  1188. else if (strcmp(curveId, "EXPONENTIAL_OUT_IN") == 0)
  1189. {
  1190. return Curve::EXPONENTIAL_OUT_IN;
  1191. }
  1192. else if (strcmp(curveId, "CIRCULAR_IN") == 0)
  1193. {
  1194. return Curve::CIRCULAR_IN;
  1195. }
  1196. else if (strcmp(curveId, "CIRCULAR_OUT") == 0)
  1197. {
  1198. return Curve::CIRCULAR_OUT;
  1199. }
  1200. else if (strcmp(curveId, "CIRCULAR_IN_OUT") == 0)
  1201. {
  1202. return Curve::CIRCULAR_IN_OUT;
  1203. }
  1204. else if (strcmp(curveId, "CIRCULAR_OUT_IN") == 0)
  1205. {
  1206. return Curve::CIRCULAR_OUT_IN;
  1207. }
  1208. else if (strcmp(curveId, "ELASTIC_IN") == 0)
  1209. {
  1210. return Curve::ELASTIC_IN;
  1211. }
  1212. else if (strcmp(curveId, "ELASTIC_OUT") == 0)
  1213. {
  1214. return Curve::ELASTIC_OUT;
  1215. }
  1216. else if (strcmp(curveId, "ELASTIC_IN_OUT") == 0)
  1217. {
  1218. return Curve::ELASTIC_IN_OUT;
  1219. }
  1220. else if (strcmp(curveId, "ELASTIC_OUT_IN") == 0)
  1221. {
  1222. return Curve::ELASTIC_OUT_IN;
  1223. }
  1224. else if (strcmp(curveId, "OVERSHOOT_IN") == 0)
  1225. {
  1226. return Curve::OVERSHOOT_IN;
  1227. }
  1228. else if (strcmp(curveId, "OVERSHOOT_OUT") == 0)
  1229. {
  1230. return Curve::OVERSHOOT_OUT;
  1231. }
  1232. else if (strcmp(curveId, "OVERSHOOT_IN_OUT") == 0)
  1233. {
  1234. return Curve::OVERSHOOT_IN_OUT;
  1235. }
  1236. else if (strcmp(curveId, "OVERSHOOT_OUT_IN") == 0)
  1237. {
  1238. return Curve::OVERSHOOT_OUT_IN;
  1239. }
  1240. else if (strcmp(curveId, "BOUNCE_IN") == 0)
  1241. {
  1242. return Curve::BOUNCE_IN;
  1243. }
  1244. else if (strcmp(curveId, "BOUNCE_OUT") == 0)
  1245. {
  1246. return Curve::BOUNCE_OUT;
  1247. }
  1248. else if (strcmp(curveId, "BOUNCE_IN_OUT") == 0)
  1249. {
  1250. return Curve::BOUNCE_IN_OUT;
  1251. }
  1252. else if (strcmp(curveId, "BOUNCE_OUT_IN") == 0)
  1253. {
  1254. return Curve::BOUNCE_OUT_IN;
  1255. }
  1256. return -1;
  1257. }
  1258. }