VelocityNode.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import { Vector3 } from '../../../../build/three.module.js';
  2. import { Vector3Node } from '../inputs/Vector3Node.js';
  3. function VelocityNode( target, params ) {
  4. Vector3Node.call( this );
  5. this.params = {};
  6. this.velocity = new Vector3();
  7. this.setTarget( target );
  8. this.setParams( params );
  9. }
  10. VelocityNode.prototype = Object.create( Vector3Node.prototype );
  11. VelocityNode.prototype.constructor = VelocityNode;
  12. VelocityNode.prototype.nodeType = 'Velocity';
  13. VelocityNode.prototype.getReadonly = function ( /*builder*/ ) {
  14. return false;
  15. };
  16. VelocityNode.prototype.setParams = function ( params ) {
  17. switch ( this.params.type ) {
  18. case 'elastic':
  19. delete this.moment;
  20. delete this.speed;
  21. delete this.springVelocity;
  22. delete this.lastVelocity;
  23. break;
  24. }
  25. this.params = params || {};
  26. switch ( this.params.type ) {
  27. case 'elastic':
  28. this.moment = new Vector3();
  29. this.speed = new Vector3();
  30. this.springVelocity = new Vector3();
  31. this.lastVelocity = new Vector3();
  32. break;
  33. }
  34. };
  35. VelocityNode.prototype.setTarget = function ( target ) {
  36. if ( this.target ) {
  37. delete this.position;
  38. delete this.oldPosition;
  39. }
  40. this.target = target;
  41. if ( target ) {
  42. this.position = target.getWorldPosition( this.position || new Vector3() );
  43. this.oldPosition = this.position.clone();
  44. }
  45. };
  46. VelocityNode.prototype.updateFrameVelocity = function ( /*frame*/ ) {
  47. if ( this.target ) {
  48. this.position = this.target.getWorldPosition( this.position || new Vector3() );
  49. this.velocity.subVectors( this.position, this.oldPosition );
  50. this.oldPosition.copy( this.position );
  51. }
  52. };
  53. VelocityNode.prototype.updateFrame = function ( frame ) {
  54. this.updateFrameVelocity( frame );
  55. switch ( this.params.type ) {
  56. case 'elastic':
  57. // convert to real scale: 0 at 1 values
  58. var deltaFps = frame.delta * ( this.params.fps || 60 );
  59. var spring = Math.pow( this.params.spring, deltaFps ),
  60. damping = Math.pow( this.params.damping, deltaFps );
  61. // fix relative frame-rate
  62. this.velocity.multiplyScalar( Math.exp( - this.params.damping * deltaFps ) );
  63. // elastic
  64. this.velocity.add( this.springVelocity );
  65. this.velocity.add( this.speed.multiplyScalar( damping ).multiplyScalar( 1 - spring ) );
  66. // speed
  67. this.speed.subVectors( this.velocity, this.lastVelocity );
  68. // spring velocity
  69. this.springVelocity.add( this.speed );
  70. this.springVelocity.multiplyScalar( spring );
  71. // moment
  72. this.moment.add( this.springVelocity );
  73. // damping
  74. this.moment.multiplyScalar( damping );
  75. this.lastVelocity.copy( this.velocity );
  76. this.value.copy( this.moment );
  77. break;
  78. default:
  79. this.value.copy( this.velocity );
  80. }
  81. };
  82. VelocityNode.prototype.copy = function ( source ) {
  83. Vector3Node.prototype.copy.call( this, source );
  84. if ( source.target ) this.setTarget( source.target );
  85. this.setParams( source.params );
  86. return this;
  87. };
  88. VelocityNode.prototype.toJSON = function ( meta ) {
  89. var data = Vector3Node.prototype.toJSON.call( this, meta );
  90. if ( this.target ) data.target = this.target.uuid;
  91. // clone params
  92. data.params = JSON.parse( JSON.stringify( this.params ) );
  93. return data;
  94. };
  95. export { VelocityNode };