CannonSpring.re.ts 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import * as RE from 'rogue-engine';
  2. import * as THREE from 'three';
  3. import * as CANNON from 'cannon-es';
  4. import CannonBody from '../CannonBody.re';
  5. import * as RogueCannon from '../../Lib/RogueCannon';
  6. export default class CannonSpring extends RE.Component {
  7. spring: CANNON.Spring;
  8. targetBody: CANNON.Body;
  9. @RE.Prop("Object3D") target: THREE.Object3D;
  10. @RE.Prop("Vector3") anchorA: THREE.Vector3 = new THREE.Vector3();
  11. @RE.Prop("Vector3") anchorB: THREE.Vector3 = new THREE.Vector3();
  12. @RE.Prop("Number") restLength: number = 0;
  13. @RE.Prop("Number") stiffness: number = 50;
  14. @RE.Prop("Number") damping: number = 1;
  15. start() {
  16. this.createSpring();
  17. }
  18. private getCannonBodyComponent(object3d: THREE.Object3D): CannonBody {
  19. const cannonBody = RE.getComponent(CannonBody, object3d);
  20. if (!cannonBody) {
  21. throw "CannonSpring targets must have a Cannon Body Component"
  22. }
  23. return cannonBody;
  24. }
  25. applyForce = () => {
  26. this.spring.applyForce();
  27. }
  28. private createSpring() {
  29. if (!this.target) throw "CannonSpring requires a target";
  30. const bodyA = this.getCannonBodyComponent(this.object3d).body;
  31. const bodyB = this.getCannonBodyComponent(this.target).body;
  32. this.spring = new CANNON.Spring(bodyA, bodyB, {
  33. localAnchorA: new CANNON.Vec3(this.anchorA.x, this.anchorA.y, this.anchorA.z),
  34. localAnchorB: new CANNON.Vec3(this.anchorB.x, this.anchorB.y, this.anchorB.z),
  35. restLength: this.restLength,
  36. stiffness: this.stiffness,
  37. damping: this.damping,
  38. });
  39. RogueCannon.getWorld().addEventListener('postStep', this.applyForce)
  40. }
  41. onBeforeRemoved() {
  42. RogueCannon.getWorld().removeEventListener('postStep', this.applyForce);
  43. }
  44. }
  45. RE.registerComponent(CannonSpring);