meshExploder.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import { Vector3 } from "../Maths/math.vector.js";
  2. /**
  3. * Class used to explode meshes (ie. to have a center and move them away from that center to better see the overall organization)
  4. */
  5. export class MeshExploder {
  6. /**
  7. * Explodes meshes from a center mesh.
  8. * @param meshes The meshes to explode.
  9. * @param centerMesh The mesh to be center of explosion.
  10. */
  11. constructor(meshes, centerMesh) {
  12. this._meshesOrigins = [];
  13. this._toCenterVectors = [];
  14. this._scaledDirection = new Vector3(1, 1, 1);
  15. this._newPosition = Vector3.Zero();
  16. this._centerPosition = Vector3.Zero();
  17. this._meshes = meshes.slice();
  18. if (centerMesh) {
  19. this._centerMesh = centerMesh;
  20. }
  21. else {
  22. this._setCenterMesh();
  23. }
  24. this._centerMesh.computeWorldMatrix(true);
  25. const centerMeshIndex = this._meshes.indexOf(this._centerMesh);
  26. if (centerMeshIndex >= 0) {
  27. this._meshes.splice(centerMeshIndex, 1);
  28. }
  29. this._centerPosition = this._centerMesh.getAbsolutePosition().clone();
  30. for (let index = 0; index < this._meshes.length; index++) {
  31. if (this._meshes[index]) {
  32. const mesh = this._meshes[index];
  33. this._meshesOrigins[index] = mesh.getAbsolutePosition().clone();
  34. this._toCenterVectors[index] = Vector3.Zero();
  35. if (mesh.hasBoundingInfo && this._centerMesh.hasBoundingInfo) {
  36. mesh.computeWorldMatrix(true);
  37. mesh.getBoundingInfo().boundingBox.centerWorld.subtractToRef(this._centerMesh.getBoundingInfo().boundingBox.centerWorld, this._toCenterVectors[index]);
  38. }
  39. }
  40. }
  41. }
  42. _setCenterMesh() {
  43. let averageCenter = Vector3.Zero();
  44. const totalCenters = Vector3.Zero();
  45. let shortestToCenter = Number.MAX_VALUE;
  46. for (let index = 0; index < this._meshes.length; index++) {
  47. if (this._meshes[index]) {
  48. const mesh = this._meshes[index];
  49. const boundingInfo = mesh.getBoundingInfo();
  50. if (boundingInfo) {
  51. totalCenters.addInPlace(boundingInfo.boundingBox.centerWorld);
  52. }
  53. }
  54. }
  55. averageCenter = totalCenters.scale(1 / this._meshes.length);
  56. for (let index = 0; index < this._meshes.length; index++) {
  57. if (this._meshes[index]) {
  58. const mesh = this._meshes[index];
  59. const boundingInfo = mesh.getBoundingInfo();
  60. if (boundingInfo) {
  61. const distanceToCenter = boundingInfo.boundingBox.centerWorld.subtract(averageCenter).lengthSquared();
  62. if (distanceToCenter < shortestToCenter) {
  63. this._centerMesh = mesh;
  64. shortestToCenter = distanceToCenter;
  65. }
  66. }
  67. }
  68. }
  69. }
  70. /**
  71. * Get class name
  72. * @returns "MeshExploder"
  73. */
  74. getClassName() {
  75. return "MeshExploder";
  76. }
  77. /**
  78. * "Exploded meshes"
  79. * @returns Array of meshes with the centerMesh at index 0.
  80. */
  81. getMeshes() {
  82. const meshArray = this._meshes.slice();
  83. meshArray.unshift(this._centerMesh);
  84. return meshArray;
  85. }
  86. /**
  87. * Explodes meshes giving a specific direction
  88. * @param direction Number to multiply distance of each mesh's origin from center. Use a negative number to implode, or zero to reset.
  89. */
  90. explode(direction = 1.0) {
  91. for (let index = 0; index < this._meshes.length; index++) {
  92. if (this._meshes[index] && this._meshesOrigins[index] && this._toCenterVectors[index]) {
  93. this._toCenterVectors[index].scaleToRef(direction, this._scaledDirection);
  94. this._meshesOrigins[index].addToRef(this._scaledDirection, this._newPosition);
  95. this._meshes[index].setAbsolutePosition(this._newPosition);
  96. }
  97. }
  98. this._centerMesh.setAbsolutePosition(this._centerPosition);
  99. }
  100. }
  101. //# sourceMappingURL=meshExploder.js.map