Browse Source

Merge pull request #5547 from bghgary/axes-viewer

Update axes viewer
sebavan 6 years ago
parent
commit
0fe6a009ae

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

@@ -71,6 +71,7 @@
 - Added support for overriding the mesh used for the world matrix for a mesh with a skeleton ([bghgary](https://github.com/bghgary))
 - Added support for linking a bone to a transform node ([bghgary](https://github.com/bghgary))
 - Factored out `setDirection` function from `lookAt` for transform node ([bghgary](https://github.com/bghgary))
+- Add support for setting renderingGroupId and creating instances to `AxesViewer` ([bghgary](https://github.com/bghgary))
 
 ### glTF Loader
 
@@ -154,3 +155,4 @@
   - _Note: The root node is still a `Mesh` object and is still the first in the returned list of meshes_
   - `TransformNode` objects are excluded from the returned list of meshes when importing mesh
   - `TransformNode` objects do not raise `onMeshLoaded` events
+- `xAxisMesh`, `yAxisMesh`, and `zAxisMesh` of `AxesViewer` was renamed to `xAxis`, `yAxis`, and `zAxis` respectively and now return a `TransformNode` to represent the parent node of the cylinder and line of the arrow ([bghgary](https://github.com/bghgary))

+ 3 - 3
inspector/src/components/actionTabs/tabs/propertyGrids/meshes/axesViewerComponent.tsx

@@ -40,9 +40,9 @@ export class AxesViewerComponent extends React.Component<IAxisViewerComponentPro
         const y = new BABYLON.Vector3(0, 1, 0);
         const z = new BABYLON.Vector3(0, 0, 1);
 
-        viewer.xAxisMesh!.reservedDataStore = { hidden: true };
-        viewer.yAxisMesh!.reservedDataStore = { hidden: true };
-        viewer.zAxisMesh!.reservedDataStore = { hidden: true };
+        viewer.xAxis.reservedDataStore = { hidden: true };
+        viewer.yAxis.reservedDataStore = { hidden: true };
+        viewer.zAxis.reservedDataStore = { hidden: true };
 
         node.reservedDataStore.onBeforeRenderObserver = scene.onBeforeRenderObservable.add(() => {
             let matrix = node.getWorldMatrix();

+ 97 - 76
src/Debug/babylon.axesViewer.ts

@@ -7,79 +7,89 @@ module BABYLON.Debug {
      * The Axes viewer will show 3 axes in a specific point in space
      */
     export class AxesViewer {
-        private _xmesh: Nullable<AbstractMesh>;
-        private _ymesh: Nullable<AbstractMesh>;
-        private _zmesh: Nullable<AbstractMesh>;
-        private _tmpVector = new BABYLON.Vector3();
+        private _xAxis: TransformNode;
+        private _yAxis: TransformNode;
+        private _zAxis: TransformNode;
+        private _tmpVector = new Vector3();
         private _scaleLinesFactor = 4;
+        private _instanced = false;
+
         /**
          * Gets the hosting scene
          */
-        public scene: Nullable<Scene>;
+        public scene: Scene;
+
         /**
          * Gets or sets a number used to scale line length
          */
         public scaleLines = 1;
 
-        /** Gets the mesh used to render x-axis */
-        public get xAxisMesh(): Nullable<AbstractMesh> {
-            return this._xmesh;
-        }
-
-        /** Gets the mesh used to render x-axis */
-        public get yAxisMesh(): Nullable<AbstractMesh> {
-            return this._ymesh;
+        /** Gets the node hierarchy used to render x-axis */
+        public get xAxis(): TransformNode {
+            return this._xAxis;
         }
 
-        /** Gets the mesh used to render x-axis */
-        public get zAxisMesh(): Nullable<AbstractMesh> {
-            return this._zmesh;
+        /** Gets the node hierarchy used to render y-axis */
+        public get yAxis(): TransformNode {
+            return this._yAxis;
         }
 
-        private static _recursiveChangeRenderingGroupId(mesh: AbstractMesh, id: number) {
-            mesh.renderingGroupId = id;
-            mesh.getChildMeshes().forEach((m) => {
-                AxesViewer._recursiveChangeRenderingGroupId(m, id);
-            });
+        /** Gets the node hierarchy used to render z-axis */
+        public get zAxis(): TransformNode {
+            return this._zAxis;
         }
 
         /**
          * Creates a new AxesViewer
          * @param scene defines the hosting scene
          * @param scaleLines defines a number used to scale line length (1 by default)
+         * @param renderingGroupId defines a number used to set the renderingGroupId of the meshes (2 by default)
+         * @param xAxis defines the node hierarchy used to render the x-axis
+         * @param yAxis defines the node hierarchy used to render the y-axis
+         * @param zAxis defines the node hierarchy used to render the z-axis
          */
-        constructor(scene: Scene, scaleLines = 1) {
+        constructor(scene: Scene, scaleLines = 1, renderingGroupId: Nullable<number> = 2, xAxis?: TransformNode, yAxis?: TransformNode, zAxis?: TransformNode) {
             this.scaleLines = scaleLines;
 
-            var greenColoredMaterial = new BABYLON.StandardMaterial("", scene);
-            greenColoredMaterial.disableLighting = true;
-            greenColoredMaterial.emissiveColor = BABYLON.Color3.Green().scale(0.5);
-
-            var redColoredMaterial = new BABYLON.StandardMaterial("", scene);
-            redColoredMaterial.disableLighting = true;
-            redColoredMaterial.emissiveColor = BABYLON.Color3.Red().scale(0.5);
-
-            var blueColoredMaterial = new BABYLON.StandardMaterial("", scene);
-            blueColoredMaterial.disableLighting = true;
-            blueColoredMaterial.emissiveColor = BABYLON.Color3.Blue().scale(0.5);
+            if (!xAxis) {
+                var redColoredMaterial = new StandardMaterial("", scene);
+                redColoredMaterial.disableLighting = true;
+                redColoredMaterial.emissiveColor = Color3.Red().scale(0.5);
+                xAxis = AxisDragGizmo._CreateArrow(scene, redColoredMaterial);
+            }
 
-            this._xmesh = BABYLON.AxisDragGizmo._CreateArrow(scene, redColoredMaterial);
-            this._ymesh = BABYLON.AxisDragGizmo._CreateArrow(scene, greenColoredMaterial);
-            this._zmesh = BABYLON.AxisDragGizmo._CreateArrow(scene, blueColoredMaterial);
+            if (!yAxis) {
+                var greenColoredMaterial = new StandardMaterial("", scene);
+                greenColoredMaterial.disableLighting = true;
+                greenColoredMaterial.emissiveColor = Color3.Green().scale(0.5);
+                yAxis = AxisDragGizmo._CreateArrow(scene, greenColoredMaterial);
+            }
 
-            this._xmesh.rotationQuaternion = new BABYLON.Quaternion();
-            this._xmesh.scaling.setAll(this.scaleLines * this._scaleLinesFactor);
-            this._ymesh.rotationQuaternion = new BABYLON.Quaternion();
-            this._ymesh.scaling.setAll(this.scaleLines * this._scaleLinesFactor);
-            this._zmesh.rotationQuaternion = new BABYLON.Quaternion();
-            this._zmesh.scaling.setAll(this.scaleLines * this._scaleLinesFactor);
+            if (!zAxis) {
+                var blueColoredMaterial = new StandardMaterial("", scene);
+                blueColoredMaterial.disableLighting = true;
+                blueColoredMaterial.emissiveColor = Color3.Blue().scale(0.5);
+                zAxis = AxisDragGizmo._CreateArrow(scene, blueColoredMaterial);
+            }
 
-            AxesViewer._recursiveChangeRenderingGroupId(this._xmesh, 2);
-            AxesViewer._recursiveChangeRenderingGroupId(this._ymesh, 2);
-            AxesViewer._recursiveChangeRenderingGroupId(this._zmesh, 2);
+            this._xAxis = xAxis;
+            this._xAxis.rotationQuaternion = new Quaternion();
+            this._xAxis.scaling.setAll(this.scaleLines * this._scaleLinesFactor);
+            this._yAxis = yAxis;
+            this._yAxis.rotationQuaternion = new Quaternion();
+            this._yAxis.scaling.setAll(this.scaleLines * this._scaleLinesFactor);
+            this._zAxis = zAxis;
+            this._zAxis.rotationQuaternion = new Quaternion();
+            this._zAxis.scaling.setAll(this.scaleLines * this._scaleLinesFactor);
+
+            if (renderingGroupId != null) {
+                AxesViewer._SetRenderingGroupId(this._xAxis, renderingGroupId);
+                AxesViewer._SetRenderingGroupId(this._yAxis, renderingGroupId);
+                AxesViewer._SetRenderingGroupId(this._zAxis, renderingGroupId);
+            }
 
             this.scene = scene;
-            this.update(new BABYLON.Vector3(), Vector3.Right(), Vector3.Up(), Vector3.Forward());
+            this.update(new Vector3(), Vector3.Right(), Vector3.Up(), Vector3.Forward());
         }
 
         /**
@@ -90,48 +100,59 @@ module BABYLON.Debug {
          * @param zaxis defines the z axis of the viewer
          */
         public update(position: Vector3, xaxis: Vector3, yaxis: Vector3, zaxis: Vector3): void {
-            if (this._xmesh) {
-                this._xmesh.position.copyFrom(position);
-                xaxis.scaleToRef(-1, this._tmpVector);
-                this._xmesh.setDirection(this._tmpVector);
-                this._xmesh.scaling.setAll(this.scaleLines * this._scaleLinesFactor);
-            }
-            if (this._ymesh) {
-                this._ymesh.position.copyFrom(position);
-                yaxis.scaleToRef(-1, this._tmpVector);
-                this._ymesh.setDirection(this._tmpVector);
-                this._ymesh.scaling.setAll(this.scaleLines * this._scaleLinesFactor);
-            }
-            if (this._zmesh) {
-                this._zmesh.position.copyFrom(position);
-                zaxis.scaleToRef(-1, this._tmpVector);
-                this._zmesh.setDirection(this._tmpVector);
-                this._zmesh.scaling.setAll(this.scaleLines * this._scaleLinesFactor);
-            }
+            this._xAxis.position.copyFrom(position);
+            xaxis.scaleToRef(-1, this._tmpVector);
+            this._xAxis.setDirection(this._tmpVector);
+            this._xAxis.scaling.setAll(this.scaleLines * this._scaleLinesFactor);
+
+            this._yAxis.position.copyFrom(position);
+            yaxis.scaleToRef(-1, this._tmpVector);
+            this._yAxis.setDirection(this._tmpVector);
+            this._yAxis.scaling.setAll(this.scaleLines * this._scaleLinesFactor);
+
+            this._zAxis.position.copyFrom(position);
+            zaxis.scaleToRef(-1, this._tmpVector);
+            this._zAxis.setDirection(this._tmpVector);
+            this._zAxis.scaling.setAll(this.scaleLines * this._scaleLinesFactor);
+        }
 
+        /**
+         * Creates an instance of this axes viewer.
+         * @returns a new axes viewer with instanced meshes
+         */
+        public createInstance(): AxesViewer {
+            const xAxis = AxisDragGizmo._CreateArrowInstance(this.scene, this._xAxis);
+            const yAxis = AxisDragGizmo._CreateArrowInstance(this.scene, this._yAxis);
+            const zAxis = AxisDragGizmo._CreateArrowInstance(this.scene, this._zAxis);
+            const axesViewer = new AxesViewer(this.scene, this.scaleLines, null, xAxis, yAxis, zAxis);
+            axesViewer._instanced = true;
+            return axesViewer;
         }
 
         /** Releases resources */
         public dispose() {
-
-            if (this._xmesh) {
-                this._xmesh.dispose();
+            if (this._xAxis) {
+                this._xAxis.dispose(false, !this._instanced);
+                delete this._xAxis;
             }
 
-            if (this._ymesh) {
-                this._ymesh.dispose();
+            if (this._yAxis) {
+                this._yAxis.dispose(false, !this._instanced);
+                delete this._yAxis;
             }
 
-            if (this._zmesh) {
-                this._zmesh.dispose();
+            if (this._zAxis) {
+                this._zAxis.dispose(false, !this._instanced);
+                delete this._zAxis;
             }
 
-            this._xmesh = null;
-            this._ymesh = null;
-            this._zmesh = null;
-
-            this.scene = null;
+            delete this.scene;
         }
 
+        private static _SetRenderingGroupId(node: TransformNode, id: number) {
+            node.getChildMeshes().forEach((mesh) => {
+                mesh.renderingGroupId = id;
+            });
+        }
     }
 }

+ 30 - 21
src/Gizmos/babylon.axisDragGizmo.ts

@@ -16,28 +16,38 @@ module BABYLON {
          * Event that fires each time the gizmo snaps to a new location.
          * * snapDistance is the the change in distance
          */
-        public onSnapObservable = new Observable<{snapDistance: number}>();
+        public onSnapObservable = new Observable<{ snapDistance: number }>();
 
         /** @hidden */
-        public static _CreateArrow(scene: Scene, material: StandardMaterial) {
-            var arrow = new BABYLON.AbstractMesh("", scene);
-            var arrowMesh = BABYLON.MeshBuilder.CreateCylinder("yPosMesh", {diameterTop: 0, height: 1.5, diameterBottom: 0.75, tessellation: 96}, scene);
-            var arrowTail = BABYLON.MeshBuilder.CreateLines("yPosMesh", {points: [new Vector3(0, 0, 0), new Vector3(0, 1.1, 0)]}, scene);
-            arrowTail.color = material.emissiveColor;
-            arrow.addChild(arrowMesh);
-            arrow.addChild(arrowTail);
+        public static _CreateArrow(scene: Scene, material: StandardMaterial): TransformNode {
+            var arrow = new BABYLON.TransformNode("arrow", scene);
+            var cylinder = BABYLON.MeshBuilder.CreateCylinder("cylinder", { diameterTop: 0, height: 1.5, diameterBottom: 0.75, tessellation: 96 }, scene);
+            var line = BABYLON.MeshBuilder.CreateLines("line", { points: [new Vector3(0, 0, 0), new Vector3(0, 1.1, 0)] }, scene);
+            line.color = material.emissiveColor;
+            cylinder.parent = arrow;
+            line.parent = arrow;
 
             // Position arrow pointing in its drag axis
-            arrowMesh.scaling.scaleInPlace(0.05);
-            arrowMesh.material = material;
-            arrowMesh.rotation.x = Math.PI / 2;
-            arrowMesh.position.z += 0.3;
-            arrowTail.scaling.scaleInPlace(0.26);
-            arrowTail.rotation.x = Math.PI / 2;
-            arrowTail.material = material;
+            cylinder.scaling.scaleInPlace(0.05);
+            cylinder.material = material;
+            cylinder.rotation.x = Math.PI / 2;
+            cylinder.position.z += 0.3;
+            line.scaling.scaleInPlace(0.26);
+            line.rotation.x = Math.PI / 2;
+            line.material = material;
             return arrow;
         }
 
+        /** @hidden */
+        public static _CreateArrowInstance(scene: Scene, arrow: TransformNode): TransformNode {
+            const instance = new BABYLON.TransformNode("arrow", scene);
+            for (const mesh of arrow.getChildMeshes()) {
+                const childInstance = (mesh as Mesh).createInstance(mesh.name);
+                childInstance.parent = instance;
+            }
+            return instance;
+        }
+
         /**
          * Creates an AxisDragGizmo
          * @param gizmoLayer The utility layer the gizmo will be added to
@@ -61,14 +71,13 @@ module BABYLON {
 
             arrow.lookAt(this._rootMesh.position.subtract(dragAxis));
             arrow.scaling.scaleInPlace(1 / 3);
-
-            this._rootMesh.addChild(arrow);
+            arrow.parent = this._rootMesh;
 
             var currentSnapDragDistance = 0;
             var tmpVector = new Vector3();
-            var tmpSnapEvent = {snapDistance: 0};
+            var tmpSnapEvent = { snapDistance: 0 };
             // Add drag behavior to handle events when the gizmo is dragged
-            this.dragBehavior = new PointerDragBehavior({dragAxis: dragAxis});
+            this.dragBehavior = new PointerDragBehavior({ dragAxis: dragAxis });
             this.dragBehavior.moveAttached = false;
             this._rootMesh.addBehavior(this.dragBehavior);
 
@@ -81,13 +90,13 @@ module BABYLON {
                         this.attachedMesh.parent.computeWorldMatrix().invertToRef(tmpMatrix);
                         tmpMatrix.setTranslationFromFloats(0, 0, 0);
                         Vector3.TransformCoordinatesToRef(event.delta, tmpMatrix, localDelta);
-                    }else {
+                    } else {
                         localDelta.copyFrom(event.delta);
                     }
                     // Snapping logic
                     if (this.snapDistance == 0) {
                         this.attachedMesh.position.addInPlace(localDelta);
-                    }else {
+                    } else {
                         currentSnapDragDistance += event.dragDistance;
                         if (Math.abs(currentSnapDragDistance) > this.snapDistance) {
                             var dragSteps = Math.floor(Math.abs(currentSnapDragDistance) / this.snapDistance);