aframe-interpolation.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /*
  2. The MIT License (MIT)
  3. Copyright (c) 2014-2018 Nikolai Suslov and the Krestianstvo.org project contributors. (https://github.com/NikolaySuslov/livecodingspace/blob/master/LICENSE.md)
  4. */
  5. if (typeof AFRAME === 'undefined') {
  6. throw new Error('Component attempted to register before AFRAME was available.');
  7. }
  8. AFRAME.registerComponent('interpolation', {
  9. schema: {
  10. enabled: { default: true },
  11. deltaPos: { default: 0.001 },
  12. deltaScale: { default: 0.001 },
  13. deltaRot: { default: 0.1 }
  14. },
  15. init: function () {
  16. this.driver = vwf.views["vwf/view/aframeComponent"];
  17. //this.el.sceneEl.components['scene-utils'].interpolationComponents[this.el.id] = this;
  18. },
  19. update: function (oldData) {
  20. if (!this.interpolation) {
  21. this.deltaPos = parseFloat(this.data.deltaPos);
  22. this.deltaScale = parseFloat(this.data.deltaScale);
  23. this.deltaRot = THREE.Math.degToRad(parseFloat(this.data.deltaRot));
  24. this.enabled = JSON.parse(this.data.enabled);
  25. if (this.enabled) {
  26. }
  27. }
  28. },
  29. /**
  30. * Called when a component is removed (e.g., via removeAttribute).
  31. * Generally undoes all modifications to the entity.
  32. */
  33. remove: function () {
  34. //delete this.el.sceneEl.components['scene-utils'].interpolationComponents[this.el.id]
  35. },
  36. /**
  37. * Called on each scene tick.
  38. */
  39. // interpolationTick
  40. tick: function (t, dt) {
  41. var now = performance.now();
  42. var timepassed = now - this.lastTime;
  43. //console.log(timepassed);
  44. if (!this.node) {
  45. let interNode = Object.entries(this.driver.state.nodes).find(el =>
  46. el[1].parentID == this.el.id && el[1].extendsID == "proxy/aframe/interpolation-component.vwf"
  47. );
  48. this.node = this.driver.nodes[interNode[0]];
  49. this.nodeState = interNode[1];
  50. }
  51. if (this.enabled && this.node && this.node.interpolate && this.driver.interpolateView) {
  52. this.setInterpolatedTransforms(timepassed);
  53. // this.restoreTransforms();
  54. }
  55. this.lastTime = now;
  56. },
  57. //interpolationTock
  58. tock: function (t, dt) {
  59. if (this.node) {
  60. if (this.enabled && this.node.interpolate && this.driver.interpolateView) {
  61. this.restoreTransforms();
  62. }
  63. }
  64. },
  65. vecCmpThreeJS: function (a, b, delta) {
  66. let distance = a.distanceTo(b);
  67. //let distance = goog.vec.Vec3.distance(a,b);
  68. if (distance > delta) {
  69. return false;
  70. }
  71. return true;
  72. },
  73. vecCmp: function (a, b, delta) {
  74. // let distance = a.distanceTo(b);
  75. let distance = goog.vec.Vec3.distance(a, b);
  76. if (distance > delta) {
  77. return false;
  78. }
  79. return true;
  80. },
  81. restoreTransforms: function () {
  82. this.restorePositionTransforms();
  83. this.restoreRotationTransforms();
  84. this.restoreScaleTransforms();
  85. },
  86. restorePositionTransforms: function () {
  87. var now = this.node.interpolate.position.selfTick;
  88. if (now && this.node.needPositionRestore) {
  89. let pos = goog.vec.Vec3.clone(now);
  90. this.el.object3D.position.set(pos[0], pos[1], pos[2]);
  91. this.node.needPositionRestore = false;
  92. }
  93. },
  94. restoreRotationTransforms: function () {
  95. var now = this.node.interpolate.rotation.selfTick;
  96. if (now && this.node.needRotationRestore) {
  97. let r = new THREE.Euler();
  98. let rot = r.copy(now);
  99. this.el.object3D.rotation.set(rot.x, rot.y, rot.z)
  100. this.node.needRotationRestore = false;
  101. }
  102. },
  103. restoreScaleTransforms: function () {
  104. var now = this.node.interpolate.scale.selfTick;
  105. if (now && this.node.needScaleRestore) {
  106. let pos = goog.vec.Vec3.clone(now);
  107. this.el.object3D.scale.set(pos[0], pos[1], pos[2]);
  108. this.node.needScaleRestore = false;
  109. }
  110. },
  111. setInterpolatedTransforms: function (deltaTime) {
  112. var step = (this.node.tickTime) / (this.node.realTickDif);
  113. step = Math.min(step, 1);
  114. //step = Math.min(1, .2 * (deltaTime / 16.6)) //Math.min(step, 1);
  115. deltaTime = Math.min(deltaTime, this.node.realTickDif)
  116. this.node.tickTime += deltaTime || 0;
  117. this.interpolatePosition(step);
  118. this.interpolateRotation(step);
  119. this.interpolateScale(step);
  120. // if (this.node.tickTime == 0){
  121. // this.restoreTransforms();
  122. // }
  123. },
  124. radians: function (degrees) {
  125. // return degrees * Math.PI / 180.0;
  126. return THREE.Math.degToRad(degrees)
  127. },
  128. interpolateRotation: function (step) {
  129. let last = this.node.interpolate.rotation.lastTick;
  130. let now = this.node.interpolate.rotation.selfTick;
  131. if (last && now) {
  132. let comp = this.vecCmpThreeJS(last.toVector3(), now.toVector3(), this.deltaRot);
  133. if (!comp) {
  134. // console.log('Last:', last, ' Now: ', now);
  135. let lastV = (new THREE.Quaternion()).setFromEuler(new THREE.Euler(
  136. (last.x),
  137. (last.y),
  138. (last.z), last.order//'YXZ'
  139. ));
  140. let nowV = (new THREE.Quaternion()).setFromEuler(new THREE.Euler(
  141. (now.x),
  142. (now.y),
  143. (now.z), last.order//'YXZ'
  144. ));
  145. let q = new THREE.Quaternion();
  146. let e = new THREE.Euler();
  147. THREE.Quaternion.slerp(lastV, nowV, q, step || 0);
  148. let interp = e.setFromQuaternion(q, last.order); //'YXZ');
  149. //this.el.object3D.rotation.set(interp.x, interp.y, interp.z);
  150. this.setRotation(interp);
  151. this.node.needRotationRestore = true;
  152. }
  153. }
  154. },
  155. interpolatePosition: function (step) {
  156. var last = this.node.interpolate.position.lastTick; //this.node.lastTickTransform;
  157. var now = this.node.interpolate.position.selfTick; //Transform;
  158. if (last && now) {
  159. let comp = this.vecCmp(last, now, this.deltaPos);
  160. if (!comp) {
  161. var interp = goog.vec.Vec3.lerp(
  162. last, now,
  163. step || 0,
  164. goog.vec.Vec3.create()
  165. );
  166. this.setPosition(interp);
  167. this.node.needPositionRestore = true;
  168. }
  169. }
  170. },
  171. interpolateScale: function (step) {
  172. var last = this.node.interpolate.scale.lastTick; //this.node.lastTickTransform;
  173. var now = this.node.interpolate.scale.selfTick; //Transform;
  174. if (last && now) {
  175. let comp = this.vecCmp(last, now, this.deltaScale);
  176. if (!comp) {
  177. var interp = goog.vec.Vec3.lerp(
  178. last, now,
  179. step || 0,
  180. goog.vec.Vec3.create()
  181. );
  182. this.setScale(interp);
  183. this.node.needScaleRestore = true;
  184. }
  185. }
  186. },
  187. setPosition: function (interp) {
  188. let vec = goog.vec.Vec3.clone(interp);
  189. this.el.object3D.position.set(vec[0], vec[1], vec[2]);
  190. },
  191. setRotation: function (interp) {
  192. let vec = (new THREE.Euler()).copy(interp);
  193. this.el.object3D.rotation.set(vec.x, vec.y, vec.z);
  194. },
  195. setScale: function (interp) {
  196. let vec = goog.vec.Vec3.clone(interp);
  197. this.el.object3D.scale.set(vec[0], vec[1], vec[2]);
  198. },
  199. pause: function () { },
  200. play: function () { }
  201. });