CannonTrimesh.re.ts 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import * as RE from 'rogue-engine';
  2. import * as THREE from 'three';
  3. import * as CANNON from 'cannon-es';
  4. import CannonShape from './CannonShape';
  5. export default class CannonTrimesh extends CannonShape {
  6. shape: CANNON.Trimesh;
  7. @RE.props.vector3() sizeOffset: THREE.Vector3 = new THREE.Vector3(1, 1, 1);
  8. private _collisionResponse = true;
  9. @RE.props.checkbox()
  10. get collisionResponse() {
  11. return this._collisionResponse;
  12. };
  13. set collisionResponse(value: boolean) {
  14. this._collisionResponse = value;
  15. if (!this.shape) return;
  16. this.shape.collisionResponse = value;
  17. };
  18. worldScale = new THREE.Vector3();
  19. worldPos = new THREE.Vector3();
  20. tmpVec0 = new CANNON.Vec3();
  21. tmpVec1 = new CANNON.Vec3();
  22. tmpVec2 = new CANNON.Vec3();
  23. tmpQuat0 = new CANNON.Vec3();
  24. createShape() {
  25. if (!(this.object3d instanceof THREE.Mesh)) return;
  26. this.object3d.updateWorldMatrix(true, true);
  27. this.object3d.getWorldScale(this.worldScale);
  28. this.object3d.getWorldPosition(this.worldPos);
  29. this.object3d.getWorldQuaternion(this.worldQuaternion);
  30. const mesh = this.object3d;
  31. let geometry = (mesh.geometry as THREE.BufferGeometry);
  32. geometry.computeBoundingSphere();
  33. geometry.normalizeNormals();
  34. if (geometry.index !== null) {
  35. const nonIndexedGeo = geometry.toNonIndexed();
  36. geometry.copy(nonIndexedGeo);
  37. }
  38. const vertices = this.getVertices(geometry);
  39. if (!vertices.length) return;
  40. const indices = Object.keys(vertices).map(Number);
  41. this.shape = new CANNON.Trimesh(vertices as unknown as number[], indices);
  42. this.shape.collisionResponse = this._collisionResponse;
  43. }
  44. getVertices (geometry: THREE.BufferGeometry) {
  45. const position = geometry.attributes.position;
  46. const vertices = new Float32Array(position.count * 3);
  47. for (let i = 0; i < position.count; i++) {
  48. vertices[i * 3] = position.getX(i) * this.worldScale.x;
  49. vertices[i * 3 + 1] = position.getY(i) * this.worldScale.y;
  50. vertices[i * 3 + 2] = position.getZ(i) * this.worldScale.z;
  51. }
  52. return vertices;
  53. }
  54. }
  55. RE.registerComponent(CannonTrimesh);