Browse Source

Merge pull request #5427 from barroij/instanceLineMesh

add InstancedLinesMesh
David Catuhe 6 years ago
parent
commit
5a1fcf515d

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

@@ -74,7 +74,7 @@
 - Fixed a bug with `mesh.alwaysSelectAsActiveMesh` preventing layerMask to be taken in account ([Deltakosh](https://github.com/deltakosh))
 - Fixed a bug with pointer up being fire twice ([Deltakosh](https://github.com/deltakosh))
 - Fixed a bug with particle systems being update once per camera instead of once per frame ([Deltakosh](https://github.com/deltakosh))
-- Handle properly the `LinesMesh` `intersectionThreshold` by using its value directly when the intersection against a `Ray` is checked, instead of extending the `BoundingInfo` accordingly ([barroij](https://github.com/barroij))
+- Handle properly the `LinesMesh` `intersectionThreshold` by using its value directly when the intersection against a `Ray` is checked, instead of extending the `BoundingInfo` accordingly + Addded an `InstancesLinesMesh` class used to create instance of `LinesMesh` so that each instance can have its own `intersectionThreshold` value ([barroij](https://github.com/barroij))
 - Fixed the `LineEdgesRenderer` used for edge rendering of `LinesMesh` handle properly LinesMesh made of disconnected lines + Make it work for instance of `LinesMesh` ([barroij](https://github.com/barroij))
 - Fixed `Matrix.toNormalMatrix`function ([barroij](https://github.com/barroij))
 - Add missing effect layer to asset container ([TrevorDev](https://github.com/TrevorDev))

+ 1 - 1
src/Math/babylon.math.ts

@@ -2272,7 +2272,7 @@ module BABYLON {
          * @param result defines the Vector3 where to store the result
          */
         public static TransformCoordinatesToRef(vector: Vector3, transformation: Readonly<Matrix>, result: Vector3): void {
-            return Vector3.TransformCoordinatesFromFloatsToRef(vector.x, vector.y, vector.z, transformation, result);
+            Vector3.TransformCoordinatesFromFloatsToRef(vector.x, vector.y, vector.z, transformation, result);
         }
 
         /**

+ 7 - 5
src/Mesh/babylon.abstractMesh.ts

@@ -1361,9 +1361,9 @@ module BABYLON {
          */
         public intersects(ray: Ray, fastCheck?: boolean): PickingInfo {
             var pickingInfo = new PickingInfo();
-            const intersectionTreshold = this.getClassName() === "LinesMesh" ? (<LinesMesh>(this as any)).intersectionThreshold : 0;
+            const intersectionThreshold = this.getClassName() === "InstancedLinesMesh" || this.getClassName() === "LinesMesh" ? (this as any).intersectionThreshold : 0;
             const boundingInfo = this._boundingInfo;
-            if (!this.subMeshes || !boundingInfo || !ray.intersectsSphere(boundingInfo.boundingSphere, intersectionTreshold) || !ray.intersectsBox(boundingInfo.boundingBox, intersectionTreshold)) {
+            if (!this.subMeshes || !boundingInfo || !ray.intersectsSphere(boundingInfo.boundingSphere, intersectionThreshold) || !ray.intersectsBox(boundingInfo.boundingBox, intersectionThreshold)) {
                 return pickingInfo;
             }
 
@@ -1400,8 +1400,10 @@ module BABYLON {
             if (intersectInfo) {
                 // Get picked point
                 const world = this.getWorldMatrix();
-                const worldOrigin = Vector3.TransformCoordinates(ray.origin, world);
-                const direction = ray.direction.scaleToRef(intersectInfo.distance, Tmp.Vector3[0]);
+                const worldOrigin = Tmp.Vector3[0];
+                const direction = Tmp.Vector3[1];
+                Vector3.TransformCoordinatesToRef(ray.origin, world, worldOrigin);
+                ray.direction.scaleToRef(intersectInfo.distance, direction);
                 const worldDirection = Vector3.TransformNormal(direction, world);
                 const pickedPoint = worldDirection.addInPlace(worldOrigin);
 
@@ -1509,7 +1511,7 @@ module BABYLON {
             });
 
             // SubMeshes
-            if (this.getClassName() !== "InstancedMesh") {
+            if (this.getClassName() !== "InstancedMesh" || this.getClassName() !== "InstancedLinesMesh") {
                 this.releaseSubMeshes();
             }
 

+ 36 - 17
src/Mesh/babylon.linesMesh.ts

@@ -17,24 +17,9 @@ module BABYLON {
          * The intersection Threshold is the margin applied when intersection a segment of the LinesMesh with a Ray.
          * This margin is expressed in world space coordinates, so its value may vary.
          * Default value is 0.1
-         * @returns the intersection Threshold value.
          */
-        public get intersectionThreshold(): number {
-            return this._intersectionThreshold;
-        }
-
-        /**
-         * The intersection Threshold is the margin applied when intersection a segment of the LinesMesh with a Ray.
-         * This margin is expressed in world space coordinates, so its value may vary.
-         */
-        public set intersectionThreshold(value: number) {
-            if (this._intersectionThreshold === value) {
-                return;
-            }
-            this._intersectionThreshold = value;
-        }
+        public intersectionThreshold: number;
 
-        private _intersectionThreshold: number;
         private _colorShader: ShaderMaterial;
 
         /**
@@ -73,7 +58,7 @@ module BABYLON {
                 this.useVertexAlpha = source.useVertexAlpha;
             }
 
-            this._intersectionThreshold = 0.1;
+            this.intersectionThreshold = 0.1;
 
             var defines: string[] = [];
             var options = {
@@ -169,5 +154,39 @@ module BABYLON {
         public clone(name: string, newParent?: Node, doNotCloneChildren?: boolean): LinesMesh {
             return new LinesMesh(name, this.getScene(), newParent, this, doNotCloneChildren);
         }
+
+        /**
+         * Creates a new InstancedLinesMesh object from the mesh model.
+         * @see http://doc.babylonjs.com/how_to/how_to_use_instances
+         * @param name defines the name of the new instance
+         * @returns a new InstancedLinesMesh
+         */
+        public createInstance(name: string): InstancedLinesMesh {
+            return new InstancedLinesMesh(name, this);
+        }
+    }
+
+    /**
+     * Creates an instance based on a source LinesMesh
+     */
+    export class InstancedLinesMesh extends InstancedMesh {
+        /**
+         * The intersection Threshold is the margin applied when intersection a segment of the LinesMesh with a Ray.
+         * This margin is expressed in world space coordinates, so its value may vary.
+         * Initilized with the intersectionThreshold value of the source LinesMesh
+         */
+        public intersectionThreshold: number;
+
+        constructor(name: string, source: LinesMesh) {
+            super(name, source);
+            this.intersectionThreshold = source.intersectionThreshold;
+        }
+
+        /**
+         * Returns the string "InstancedLinesMesh".
+         */
+        public getClassName(): string {
+            return "InstancedLinesMesh";
+        }
     }
 }

+ 0 - 1
src/Mesh/babylon.mesh.ts

@@ -2308,7 +2308,6 @@ module BABYLON {
 
         /**
          * Creates a new InstancedMesh object from the mesh model.
-         * Warning : this method is not supported for Line mesh and LineSystem
          * @see http://doc.babylonjs.com/how_to/how_to_use_instances
          * @param name defines the name of the new instance
          * @returns a new InstancedMesh

+ 2 - 4
src/Mesh/babylon.subMesh.ts

@@ -344,10 +344,8 @@ module BABYLON {
 
             // LineMesh first as it's also a Mesh...
             if (LinesMesh) {
-                const mesh = this._mesh instanceof InstancedMesh ? (<InstancedMesh>this._mesh).sourceMesh : this._mesh;
-                if (mesh instanceof LinesMesh) {
-                    const linesMesh = <LinesMesh>mesh;
-                    return this._intersectLines(ray, positions, indices, linesMesh.intersectionThreshold, fastCheck);
+                if (this._mesh.getClassName() === "InstancedLinesMesh" || this._mesh.getClassName() === "LinesMesh") {
+                    return this._intersectLines(ray, positions, indices, (this._mesh as any).intersectionThreshold, fastCheck);
                 }
             }
 

+ 5 - 10
src/Rendering/babylon.edgesRenderer.ts

@@ -62,25 +62,20 @@ module BABYLON {
         return this;
     };
 
-    export interface InstancedMesh {
+    export interface InstancedLinesMesh {
         /**
          * Enables the edge rendering mode on the mesh.
          * This mode makes the mesh edges visible
          * @param epsilon defines the maximal distance between two angles to detect a face
          * @param checkVerticesInsteadOfIndices indicates that we should check vertex list directly instead of faces
-         * @returns the currentInstancedMesh
+         * @returns the current InstancedLinesMesh
          * @see https://www.babylonjs-playground.com/#19O9TU#0
          */
-        enableEdgesRendering(epsilon?: number, checkVerticesInsteadOfIndices?: boolean): InstancedMesh;
+        enableEdgesRendering(epsilon?: number, checkVerticesInsteadOfIndices?: boolean): InstancedLinesMesh;
     }
 
-    InstancedMesh.prototype.enableEdgesRendering = function(epsilon = 0.95, checkVerticesInsteadOfIndices = false): InstancedMesh {
-        if (this.sourceMesh.getClassName() === 'LinesMesh') {
-            LinesMesh.prototype.enableEdgesRendering.apply(this, arguments);
-        }
-        else {
-            AbstractMesh.prototype.enableEdgesRendering.apply(this, arguments);
-        }
+    InstancedLinesMesh.prototype.enableEdgesRendering = function(epsilon = 0.95, checkVerticesInsteadOfIndices = false): InstancedLinesMesh {
+        LinesMesh.prototype.enableEdgesRendering.apply(this, arguments);
         return this;
     };
 

+ 1 - 1
src/babylon.scene.ts

@@ -2231,7 +2231,7 @@ module BABYLON {
                     return false;
                 }
 
-                let hardwareInstancedRendering = mesh.getClassName() === "InstancedMesh" || engine.getCaps().instancedArrays && (<Mesh>mesh).instances.length > 0;
+                let hardwareInstancedRendering = mesh.getClassName() === "InstancedMesh" || mesh.getClassName() === "InstancedLinesMesh" || engine.getCaps().instancedArrays && (<Mesh>mesh).instances.length > 0;
                 // Is Ready For Mesh
                 for (let step of this._isReadyForMeshStage) {
                     if (!step.action(mesh, hardwareInstancedRendering)) {