aframe-interpolation.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  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. deltaRot: { default: 0.1 }
  13. },
  14. init: function () {
  15. this.driver = vwf.views["vwf/view/aframeComponent"];
  16. },
  17. update: function (oldData) {
  18. if (!this.interpolation) {
  19. this.deltaPos = parseFloat(this.data.deltaPos);
  20. this.deltaRot = THREE.Math.degToRad(parseFloat(this.data.deltaRot));
  21. this.enabled = JSON.parse(this.data.enabled);
  22. if (this.enabled) {
  23. }
  24. }
  25. },
  26. /**
  27. * Called when a component is removed (e.g., via removeAttribute).
  28. * Generally undoes all modifications to the entity.
  29. */
  30. remove: function () { },
  31. /**
  32. * Called on each scene tick.
  33. */
  34. tick: function (t, dt) {
  35. var now = performance.now();
  36. var timepassed = now - this.lastTime;
  37. //console.log(timepassed);
  38. if (!this.node) {
  39. let interNode = Object.entries(this.driver.state.nodes).find(el =>
  40. el[1].parentID == this.el.id && el[1].extendsID == "http://vwf.example.com/aframe/interpolation-component.vwf"
  41. );
  42. this.node = this.driver.nodes[interNode[0]];
  43. this.nodeState = interNode[1];
  44. }
  45. if (this.enabled && this.node && this.node.interpolate) {
  46. this.setInterpolatedTransforms(timepassed);
  47. // this.restoreTransforms();
  48. }
  49. this.lastTime = now;
  50. },
  51. tock: function(t, dt){
  52. if (this.node) {
  53. if (this.enabled && this.node.interpolate) {
  54. this.restoreTransforms();
  55. }
  56. }
  57. },
  58. vecCmpThreeJS: function (a, b, delta) {
  59. let distance = a.distanceTo(b);
  60. //let distance = goog.vec.Vec3.distance(a,b);
  61. if (distance > delta) {
  62. return false;
  63. }
  64. return true;
  65. },
  66. vecCmp: function (a, b, delta) {
  67. // let distance = a.distanceTo(b);
  68. let distance = goog.vec.Vec3.distance(a,b);
  69. if (distance > delta) {
  70. return false;
  71. }
  72. return true;
  73. },
  74. restoreTransforms: function () {
  75. var now = this.node.interpolate.position.selfTick;
  76. if (now && this.node.needPositionRestore) {
  77. let pos = goog.vec.Vec3.clone(now);
  78. this.el.object3D.position.set(pos[0], pos[1], pos[2]);
  79. this.node.needPositionRestore = false;
  80. }
  81. var rNow = this.node.interpolate.rotation.selfTick;
  82. if(rNow && this.node.needRotationRestore) {
  83. let r = new THREE.Euler();
  84. let rot = r.copy(rNow);
  85. this.el.object3D.rotation.set(rot.x, rot.y, rot.z)
  86. this.node.needRotationRestore = false;
  87. }
  88. // let r = new THREE.Vector3();
  89. // let rot = r.copy(this.node.interpolate.position.selfTick);
  90. // if (rot && this.node.needTransformRestore) {
  91. // this.el.object3D.position.set(rot.x, rot.y, rot.z)
  92. // this.node.needTransformRestore = false;
  93. // }
  94. // let r = new THREE.Euler();
  95. // let rot = r.copy(this.node.interpolate.rotation.selfTick);
  96. // if (rot && this.node.needTransformRestore) {
  97. // this.el.object3D.rotation.set(rot.x, rot.y, rot.z)
  98. // this.node.needTransformRestore = false;
  99. // }
  100. },
  101. setInterpolatedTransforms: function (deltaTime) {
  102. var step = (this.node.tickTime) / (this.node.realTickDif);
  103. step = Math.min(step, 1);
  104. //step = Math.min(1, .2 * (deltaTime / 16.6)) //Math.min(step, 1);
  105. deltaTime = Math.min(deltaTime, this.node.realTickDif)
  106. this.node.tickTime += deltaTime || 0;
  107. this.interpolatePosition(step);
  108. this.interpolateRotation(step);
  109. // if (this.node.tickTime == 0){
  110. // this.restoreTransforms();
  111. // }
  112. },
  113. radians: function (degrees) {
  114. // return degrees * Math.PI / 180.0;
  115. return THREE.Math.degToRad(degrees)
  116. },
  117. interpolateRotation: function (step) {
  118. let last = this.node.interpolate.rotation.lastTick;
  119. let now = this.node.interpolate.rotation.selfTick;
  120. if (last && now) {
  121. let comp = this.vecCmpThreeJS(last.toVector3(), now.toVector3(), this.deltaRot);
  122. if (!comp) {
  123. // console.log('Last:', last, ' Now: ', now);
  124. let lastV = (new THREE.Quaternion()).setFromEuler(new THREE.Euler(
  125. (last.x),
  126. (last.y),
  127. (last.z), last.order//'YXZ'
  128. ));
  129. let nowV = (new THREE.Quaternion()).setFromEuler(new THREE.Euler(
  130. (now.x),
  131. (now.y),
  132. (now.z), last.order//'YXZ'
  133. ));
  134. let q = new THREE.Quaternion();
  135. let e = new THREE.Euler();
  136. THREE.Quaternion.slerp(lastV, nowV, q, step || 0);
  137. let interp = e.setFromQuaternion(q, last.order); //'YXZ');
  138. //this.el.object3D.rotation.set(interp.x, interp.y, interp.z);
  139. this.setRotation(interp);
  140. this.node.needRotationRestore = true;
  141. }
  142. }
  143. },
  144. interpolatePosition: function (step) {
  145. var last = this.node.interpolate.position.lastTick; //this.node.lastTickTransform;
  146. var now = this.node.interpolate.position.selfTick; //Transform;
  147. if (last && now) {
  148. let comp = this.vecCmp(last, now, this.deltaPos);
  149. if (!comp) {
  150. var interp = goog.vec.Vec3.lerp(
  151. last, now,
  152. step || 0,
  153. goog.vec.Vec3.create()
  154. );
  155. // console.log(this.node.id);
  156. //console.log(step + ' : ' + interp);
  157. // var lastV = (new THREE.Vector3()).copy(last);
  158. // var nowV = (new THREE.Vector3()).copy(now);
  159. // var interp = lastV.lerp(nowV, step || 0);
  160. //this.el.setAttribute('position',interp);
  161. //this.el.object3D.position.set(interp.x, interp.y, interp.z);
  162. this.setPosition(interp);
  163. this.node.needPositionRestore = true;
  164. }
  165. }
  166. },
  167. setPosition: function (interp) {
  168. let vec = goog.vec.Vec3.clone(interp);
  169. this.el.object3D.position.set(vec[0], vec[1], vec[2]);
  170. },
  171. setRotation: function (interp) {
  172. let vec = (new THREE.Euler()).copy(interp);
  173. this.el.object3D.rotation.set(vec.x, vec.y, vec.z);
  174. },
  175. pause: function () { },
  176. play: function () { }
  177. });