aframe-lerp-component.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /******/ (function(modules) { // webpackBootstrap
  2. /******/ // The module cache
  3. /******/ var installedModules = {};
  4. /******/ // The require function
  5. /******/ function __webpack_require__(moduleId) {
  6. /******/ // Check if module is in cache
  7. /******/ if(installedModules[moduleId])
  8. /******/ return installedModules[moduleId].exports;
  9. /******/ // Create a new module (and put it into the cache)
  10. /******/ var module = installedModules[moduleId] = {
  11. /******/ exports: {},
  12. /******/ id: moduleId,
  13. /******/ loaded: false
  14. /******/ };
  15. /******/ // Execute the module function
  16. /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  17. /******/ // Flag the module as loaded
  18. /******/ module.loaded = true;
  19. /******/ // Return the exports of the module
  20. /******/ return module.exports;
  21. /******/ }
  22. /******/ // expose the modules object (__webpack_modules__)
  23. /******/ __webpack_require__.m = modules;
  24. /******/ // expose the module cache
  25. /******/ __webpack_require__.c = installedModules;
  26. /******/ // __webpack_public_path__
  27. /******/ __webpack_require__.p = "";
  28. /******/ // Load entry module and return exports
  29. /******/ return __webpack_require__(0);
  30. /******/ })
  31. /************************************************************************/
  32. /******/ ([
  33. /* 0 */
  34. /***/ (function(module, exports, __webpack_require__) {
  35. /* global AFRAME THREE */
  36. if (typeof AFRAME === 'undefined') {
  37. throw new Error('Component attempted to register before AFRAME was available.');
  38. }
  39. var degToRad = THREE.Math.degToRad;
  40. var almostEqual = __webpack_require__(1);
  41. /**
  42. * Linear Interpolation component for A-Frame.
  43. */
  44. AFRAME.registerComponent('lerp', {
  45. schema: {
  46. properties: { default: ['position', 'rotation', 'scale']},
  47. },
  48. /**
  49. * Called once when component is attached. Generally for initial setup.
  50. */
  51. init: function () {
  52. var el = this.el;
  53. this.lastPosition = el.getAttribute('position');
  54. this.lastRotation = el.getAttribute('rotation');
  55. this.lastScale = el.getAttribute('scale');
  56. this.lerpingPosition = false;
  57. this.lerpingRotation = false;
  58. this.lerpingScale = false;
  59. this.timeOfLastUpdate = 0;
  60. },
  61. /**
  62. * Called on each scene tick.
  63. */
  64. tick: function (time, deltaTime) {
  65. var progress;
  66. var now = this.now();
  67. var obj3d = this.el.object3D;
  68. this.checkForComponentChanged();
  69. // Lerp position
  70. if (this.lerpingPosition) {
  71. progress = (now - this.startLerpTimePosition) / this.duration;
  72. obj3d.position.lerpVectors(this.startPosition, this.targetPosition, progress);
  73. // console.log("new position", obj3d.position);
  74. if (progress >= 1) {
  75. this.lerpingPosition = false;
  76. }
  77. }
  78. // Slerp rotation
  79. if (this.lerpingRotation) {
  80. progress = (now - this.startLerpTimeRotation) / this.duration;
  81. THREE.Quaternion.slerp(this.startRotation, this.targetRotation, obj3d.quaternion, progress);
  82. if (progress >= 1) {
  83. this.lerpingRotation = false;
  84. }
  85. }
  86. // Lerp scale
  87. if (this.lerpingScale) {
  88. progress = (now - this.startLerpTimeScale) / this.duration;
  89. obj3d.scale.lerpVectors(this.startScale, this.targetScale, progress);
  90. if (progress >= 1) {
  91. this.lerpingScale = false;
  92. }
  93. }
  94. },
  95. checkForComponentChanged: function() {
  96. var el = this.el;
  97. var hasChanged = false;
  98. var newPosition = el.getAttribute('position');
  99. if (this.isLerpable('position') && !this.almostEqualVec3(this.lastPosition, newPosition)) {
  100. this.toPosition(this.lastPosition, newPosition);
  101. this.lastPosition = newPosition;
  102. hasChanged = true;
  103. }
  104. var newRotation = el.getAttribute('rotation');
  105. if (this.isLerpable('rotation') && !this.almostEqualVec3(this.lastRotation, newRotation)) {
  106. this.toRotation(this.lastRotation, newRotation);
  107. this.lastRotation = newRotation;
  108. hasChanged = true;
  109. }
  110. var newScale = el.getAttribute('scale');
  111. if (this.isLerpable('scale') && !this.almostEqualVec3(this.lastScale, newScale)) {
  112. this.toScale(this.lastScale, newScale);
  113. this.lastScale = newScale;
  114. hasChanged = true;
  115. }
  116. if (hasChanged) {
  117. this.updateDuration();
  118. }
  119. },
  120. isLerpable: function(name) {
  121. return this.data.properties.indexOf(name) != -1
  122. },
  123. updateDuration: function() {
  124. var now = this.now();
  125. this.duration = now - this.timeOfLastUpdate;
  126. this.timeOfLastUpdate = now;
  127. },
  128. /**
  129. * Start lerp to position (vec3)
  130. */
  131. toPosition: function (from, to) {
  132. this.lerpingPosition = true;
  133. this.startLerpTimePosition = this.now();
  134. this.startPosition = new THREE.Vector3(from.x, from.y, from.z);
  135. this.targetPosition = new THREE.Vector3(to.x, to.y, to.z);
  136. },
  137. /**
  138. * Start lerp to euler rotation (vec3,'YXZ')
  139. */
  140. toRotation: function (from, to) {
  141. this.lerpingRotation = true;
  142. this.startLerpTimeRotation = this.now();
  143. this.startRotation = new THREE.Quaternion();
  144. this.startRotation.setFromEuler(
  145. new THREE.Euler(degToRad(from.x), degToRad(from.y), degToRad(from.z), 'YXZ'));
  146. this.targetRotation = new THREE.Quaternion();
  147. this.targetRotation.setFromEuler(
  148. new THREE.Euler(degToRad(to.x), degToRad(to.y), degToRad(to.z), 'YXZ'));
  149. },
  150. /**
  151. * Start lerp to scale (vec3)
  152. */
  153. toScale: function (from, to) {
  154. this.lerpingScale = true;
  155. this.startLerpTimeScale = this.now();
  156. this.startScale = new THREE.Vector3(from.x, from.y, from.z);
  157. this.targetScale = new THREE.Vector3(to.x, to.y, to.z);
  158. },
  159. almostEqualVec3: function(a, b) {
  160. return almostEqual(a.x, b.x) && almostEqual(a.y, b.y) && almostEqual(a.z, b.z);
  161. },
  162. /**
  163. * Returns the current time in milliseconds (ms)
  164. */
  165. now: function() {
  166. return Date.now();
  167. }
  168. });
  169. /***/ }),
  170. /* 1 */
  171. /***/ (function(module, exports) {
  172. "use strict"
  173. var abs = Math.abs
  174. , min = Math.min
  175. function almostEqual(a, b, absoluteError, relativeError) {
  176. var d = abs(a - b)
  177. if (absoluteError == null) absoluteError = almostEqual.DBL_EPSILON;
  178. if (relativeError == null) relativeError = absoluteError;
  179. if(d <= absoluteError) {
  180. return true
  181. }
  182. if(d <= relativeError * min(abs(a), abs(b))) {
  183. return true
  184. }
  185. return a === b
  186. }
  187. almostEqual.FLT_EPSILON = 1.19209290e-7
  188. almostEqual.DBL_EPSILON = 2.2204460492503131e-16
  189. module.exports = almostEqual
  190. /***/ })
  191. /******/ ]);