CannonShape.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import * as RE from 'rogue-engine';
  2. import * as CANNON from 'cannon-es';
  3. import * as THREE from 'three';
  4. import CannonBody from '../CannonBody.re';
  5. export default class CannonShape extends RE.Component {
  6. shape: CANNON.Shape;
  7. body: CANNON.Body | undefined;
  8. bodyComponent: CannonBody | undefined;
  9. localPos: THREE.Vector3 = new THREE.Vector3();
  10. worldPos = new THREE.Vector3();
  11. localRot = new THREE.Quaternion();
  12. worldQuaternion = new THREE.Quaternion();
  13. private matrixA = new THREE.Matrix4();
  14. private matrixB = new THREE.Matrix4();
  15. private matrixC = new THREE.Matrix4();
  16. awake() {
  17. this.createShape();
  18. }
  19. start() {
  20. if (!this.shape) return;
  21. this.bodyComponent = this.getBodyComponent(this.object3d);
  22. if (!this.bodyComponent) return;
  23. this.body = this.bodyComponent.body;
  24. const bodyIsShape = this.object3d === this.bodyComponent.object3d;
  25. this.object3d.getWorldPosition(this.worldPos);
  26. this.localPos.copy(this.worldPos);
  27. this.bodyComponent.object3d.updateWorldMatrix(true, true);
  28. this.bodyComponent.object3d.worldToLocal(this.localPos);
  29. let position = new CANNON.Vec3(
  30. this.localPos.x,
  31. this.localPos.y,
  32. this.localPos.z,
  33. );
  34. this.object3d.updateWorldMatrix(true, true);
  35. this.object3d.getWorldQuaternion(this.worldQuaternion);
  36. this.matrixA.makeRotationFromQuaternion(this.worldQuaternion);
  37. this.object3d.updateWorldMatrix(true, true);
  38. this.matrixB.copy(this.bodyComponent.object3d.matrixWorld).invert();
  39. this.matrixC.extractRotation(this.matrixB);
  40. this.matrixA.premultiply(this.matrixC);
  41. this.localRot.setFromRotationMatrix(this.matrixA);
  42. let rotation = new CANNON.Quaternion(
  43. this.localRot.x,
  44. this.localRot.y,
  45. this.localRot.z,
  46. this.localRot.w,
  47. );
  48. if (bodyIsShape) {
  49. this.body.addShape(this.shape);
  50. } else {
  51. this.body.addShape(this.shape, position, rotation);
  52. }
  53. }
  54. private getBodyComponent(object3d: THREE.Object3D): CannonBody | undefined {
  55. const bodyComponent = RE.getComponent(CannonBody, object3d);
  56. if (bodyComponent) {
  57. return bodyComponent;
  58. }
  59. if (!object3d.parent) return;
  60. return this.getBodyComponent(object3d.parent as THREE.Object3D);
  61. }
  62. protected createShape(): void {};
  63. }