Curve.cpp 37 KB

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