Explorar o código

Merge branch 'master' of https://github.com/BabylonJS/Babylon.js

David Catuhe %!s(int64=6) %!d(string=hai) anos
pai
achega
02a8b05da9
Modificáronse 3 ficheiros con 110 adicións e 0 borrados
  1. 1 0
      dist/preview release/what's new.md
  2. 1 0
      src/Misc/index.ts
  3. 108 0
      src/Misc/meshExploder.ts

+ 1 - 0
dist/preview release/what's new.md

@@ -119,6 +119,7 @@
 - Added OnAfterEnteringVRObservable to webVRHelper ([TrevorDev](https://github.com/TrevorDev))
 - Added Support for Side By Side and Top/Bottom VR videos in the [video dome](https://doc.babylonjs.com/how_to/360videodome#video-types) ([Sebavan](https://github.com/Sebavan))
 - onActiveCameraChanged shouldn't be fired when rendering rig cameras ([TrevorDev](https://github.com/TrevorDev))
+- Added `MeshExploder` class ([danjpar](https://github.com/danjpar))
 
 ### OBJ Loader
 - Add color vertex support (not part of standard) ([brianzinn](https://github.com/brianzinn))

+ 1 - 0
src/Misc/index.ts

@@ -4,6 +4,7 @@ export * from "./dds";
 export * from "./decorators";
 export * from "./deferred";
 export * from "./environmentTextureTools";
+export * from "./meshExploder";
 export * from "./filesInput";
 export * from "./HighDynamicRange/index";
 export * from "./khronosTextureContainer";

+ 108 - 0
src/Misc/meshExploder.ts

@@ -0,0 +1,108 @@
+import { Mesh } from "../Meshes/mesh";
+import { Vector3 } from "../Maths/math";
+
+/**
+ * Class used to explode meshes.
+ */
+export class MeshExploder {
+    private _centerMesh: Mesh;
+    private _meshes: Array<Mesh>;
+    private _meshesOrigins: Array<Vector3> = [];
+    private _toCenterVectors: Array<Vector3> = [];
+    private _scaledDirection = new Vector3(0.0, 0.0, 0.0);
+    private _newPosition = new Vector3(0.0, 0.0, 0.0);
+    private _centerPosition = new Vector3(0.0, 0.0, 0.0);
+
+    /**
+     * Explodes meshes from a center mesh.
+     * @param meshes The meshes to explode.
+     * @param centerMesh The mesh to be center of explosion.
+     */
+    constructor(meshes: Array<Mesh>, centerMesh?: Mesh) {
+
+        this._meshes = meshes.slice();
+
+        if (centerMesh) {
+            this._centerMesh = centerMesh;
+        } else {
+            this._setCenterMesh();
+        }
+        if (this._meshes.indexOf(this._centerMesh) >= 0) {
+            this._meshes.splice(this._meshes.indexOf(this._centerMesh), 1);
+        }
+        this._centerPosition = this._centerMesh.getAbsolutePosition().clone();
+        for (var index = 0; index < this._meshes.length; index++) {
+            if (this._meshes[index]) {
+                var mesh = this._meshes[index];
+                this._meshesOrigins[index] = mesh.getAbsolutePosition().clone();
+                this._toCenterVectors[index] = new Vector3(0.0, 0.0, 0.0);
+                if (mesh._boundingInfo && this._centerMesh._boundingInfo) {
+                    mesh._boundingInfo.boundingBox.centerWorld.subtractToRef(this._centerMesh._boundingInfo.boundingBox.centerWorld, this._toCenterVectors[index]);
+                }
+            }
+        }
+    }
+
+    private _setCenterMesh(): void {
+        var averageCenter = new Vector3(0.0, 0.0, 0.0);
+        var totalCenters = new Vector3(0.0, 0.0, 0.0);
+        var shortestToCenter = Number.MAX_VALUE;
+        for (var index = 0; index < this._meshes.length; index++) {
+            if (this._meshes[index]) {
+                var mesh = this._meshes[index];
+                if (mesh._boundingInfo) {
+                    totalCenters.addInPlace(mesh._boundingInfo.boundingBox.centerWorld);
+                }
+            }
+        }
+        averageCenter = totalCenters.scale(1 / this._meshes.length);
+        for (var index = 0; index < this._meshes.length; index++) {
+            if (this._meshes[index]) {
+                var mesh = this._meshes[index];
+                if (mesh._boundingInfo) {
+                    var distanceToCenter = mesh._boundingInfo.boundingBox.centerWorld.subtract(averageCenter).length();
+                    if (distanceToCenter < shortestToCenter) {
+                        this._centerMesh = mesh;
+                        shortestToCenter = distanceToCenter;
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * "MeshExploder"
+     * @returns "MeshExploder"
+     */
+    public getClassName(): string {
+        return "MeshExploder";
+    }
+
+    /**
+     * "Exploded meshes"
+     * @returns Array of meshes with the centerMesh at index 0.
+     */
+    public getMeshes(): Array<Mesh> {
+        var meshArray: Array<Mesh>;
+        meshArray = this._meshes.slice();
+        meshArray.unshift(this._centerMesh);
+        return meshArray;
+    }
+
+    /**
+     * Explodes mesh a given number of times.
+     * @param direction Number to multiply distance of each mesh's origin from center. Use a negative number to implode, or zero to reset.
+     */
+    public explode(direction: number = 1.0): void {
+        for (var index = 0; index < this._meshes.length; index++) {
+            if (this._meshes[index] && this._meshesOrigins[index] && this._toCenterVectors[index]) {
+                this._toCenterVectors[index].scaleToRef(direction, this._scaledDirection);
+                this._meshesOrigins[index].addToRef(this._scaledDirection, this._newPosition);
+                this._meshes[index].setAbsolutePosition(this._newPosition);
+                this._meshes[index].computeWorldMatrix(true);
+            }
+        }
+        this._centerMesh.setAbsolutePosition(this._centerPosition);
+        this._centerMesh.computeWorldMatrix(true);
+    }
+}