Procházet zdrojové kódy

Merge pull request #6647 from ravenops/feature/position-based-billboards

add positional mode to billboards
David Catuhe před 6 roky
rodič
revize
d8c895fa13

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

@@ -61,6 +61,7 @@
 ### Meshes
 - Added new CreateTiledPlane and CreateTiledBox ([JohnK](https://github.com/BabylonJSGuide/))
 - Added absolute scaling and rotation getters ([haroldma](https://github.com/haroldma))
+- Added `BILLBOARDMODE_USE_POSITION` flag to billboards allowing use of camera positioning instead of orientation for mesh rotation ([delaneyj](https://github.com/delaneyj))
 
 ### Physics
 - Update Ammo.js library to support global collision contact callbacks ([MackeyK24](https://github.com/MackeyK24/))

+ 5 - 0
src/Meshes/abstractMesh.ts

@@ -162,6 +162,11 @@ export class AbstractMesh extends TransformNode implements IDisposable, ICullabl
         return TransformNode.BILLBOARDMODE_ALL;
     }
 
+    /** Billboard on using position instead of orientation */
+    public static get BILLBOARDMODE_USE_POSITION(): number {
+        return TransformNode.BILLBOARDMODE_USE_POSITION;
+    }
+
     // Internal data
     /** @hidden */
     public _internalAbstractMeshDataInfo = new _InternalAbstractMeshDataInfo();

+ 51 - 28
src/Meshes/transformNode.ts

@@ -36,6 +36,10 @@ export class TransformNode extends Node {
      * Object will rotate to face the camera
      */
     public static BILLBOARDMODE_ALL = 7;
+    /**
+     * Object will rotate to face the camera's position instead of orientation
+     */
+    public static BILLBOARDMODE_USE_POSITION = 128;
 
     private _forward = new Vector3(0, 0, 1);
     private _forwardInverted = new Vector3(0, 0, -1);
@@ -942,6 +946,27 @@ export class TransformNode extends Node {
             return this._worldMatrix;
         }
 
+        let camera = (<Camera>this.getScene().activeCamera);
+        const useBillboardPath = this._billboardMode !== TransformNode.BILLBOARDMODE_NONE && !this.preserveParentRotationForBillboard;
+        const useBillboardPosition = this._billboardMode & TransformNode.BILLBOARDMODE_USE_POSITION;
+
+        // Billboarding based on camera position
+        if (useBillboardPath && camera && useBillboardPosition) {
+            this.lookAt(camera.position);
+
+            if ((this.billboardMode & TransformNode.BILLBOARDMODE_X) !== TransformNode.BILLBOARDMODE_X) {
+                this.rotation.x = 0;
+            }
+
+            if ((this.billboardMode & TransformNode.BILLBOARDMODE_Y) !== TransformNode.BILLBOARDMODE_Y) {
+                this.rotation.y = 0;
+            }
+
+            if ((this.billboardMode & TransformNode.BILLBOARDMODE_Z) !== TransformNode.BILLBOARDMODE_Z) {
+                this.rotation.z = 0;
+            }
+        }
+
         this._updateCache();
         let cache = this._cache;
         cache.pivotMatrixUpdated = false;
@@ -952,8 +977,6 @@ export class TransformNode extends Node {
         this._childUpdateId++;
         this._isDirty = false;
         let parent = this._getEffectiveParent();
-        const useBillboardPath = this._billboardMode !== TransformNode.BILLBOARDMODE_NONE && !this.preserveParentRotationForBillboard;
-        let camera = (<Camera>this.getScene().activeCamera);
 
         // Scaling
         let scaling: Vector3 = cache.scaling;
@@ -1048,40 +1071,40 @@ export class TransformNode extends Node {
             this._worldMatrix.copyFrom(this._localMatrix);
         }
 
-        // Billboarding (testing PG:http://www.babylonjs-playground.com/#UJEIL#13)
-        if (useBillboardPath && camera) {
+        // Billboarding based on camera orientation (testing PG:http://www.babylonjs-playground.com/#UJEIL#13)
+        if (useBillboardPath && camera && this.billboardMode && !useBillboardPosition) {
             let storedTranslation = TmpVectors.Vector3[0];
-            this._worldMatrix.getTranslationToRef(storedTranslation); // Save translation
+                this._worldMatrix.getTranslationToRef(storedTranslation); // Save translation
 
-            // Cancel camera rotation
-            TmpVectors.Matrix[1].copyFrom(camera.getViewMatrix());
-            TmpVectors.Matrix[1].setTranslationFromFloats(0, 0, 0);
-            TmpVectors.Matrix[1].invertToRef(TmpVectors.Matrix[0]);
+                // Cancel camera rotation
+                TmpVectors.Matrix[1].copyFrom(camera.getViewMatrix());
+                TmpVectors.Matrix[1].setTranslationFromFloats(0, 0, 0);
+                TmpVectors.Matrix[1].invertToRef(TmpVectors.Matrix[0]);
 
-            if ((this.billboardMode & TransformNode.BILLBOARDMODE_ALL) !== TransformNode.BILLBOARDMODE_ALL) {
-                TmpVectors.Matrix[0].decompose(undefined, TmpVectors.Quaternion[0], undefined);
-                let eulerAngles = TmpVectors.Vector3[1];
-                TmpVectors.Quaternion[0].toEulerAnglesToRef(eulerAngles);
+                if ((this.billboardMode & TransformNode.BILLBOARDMODE_ALL) !== TransformNode.BILLBOARDMODE_ALL) {
+                    TmpVectors.Matrix[0].decompose(undefined, TmpVectors.Quaternion[0], undefined);
+                    let eulerAngles = TmpVectors.Vector3[1];
+                    TmpVectors.Quaternion[0].toEulerAnglesToRef(eulerAngles);
 
-                if ((this.billboardMode & TransformNode.BILLBOARDMODE_X) !== TransformNode.BILLBOARDMODE_X) {
-                    eulerAngles.x = 0;
-                }
+                    if ((this.billboardMode & TransformNode.BILLBOARDMODE_X) !== TransformNode.BILLBOARDMODE_X) {
+                        eulerAngles.x = 0;
+                    }
 
-                if ((this.billboardMode & TransformNode.BILLBOARDMODE_Y) !== TransformNode.BILLBOARDMODE_Y) {
-                    eulerAngles.y = 0;
-                }
+                    if ((this.billboardMode & TransformNode.BILLBOARDMODE_Y) !== TransformNode.BILLBOARDMODE_Y) {
+                        eulerAngles.y = 0;
+                    }
 
-                if ((this.billboardMode & TransformNode.BILLBOARDMODE_Z) !== TransformNode.BILLBOARDMODE_Z) {
-                    eulerAngles.z = 0;
-                }
+                    if ((this.billboardMode & TransformNode.BILLBOARDMODE_Z) !== TransformNode.BILLBOARDMODE_Z) {
+                        eulerAngles.z = 0;
+                    }
 
-                Matrix.RotationYawPitchRollToRef(eulerAngles.y, eulerAngles.x, eulerAngles.z, TmpVectors.Matrix[0]);
-            }
-            this._worldMatrix.setTranslationFromFloats(0, 0, 0);
-            this._worldMatrix.multiplyToRef(TmpVectors.Matrix[0], this._worldMatrix);
+                    Matrix.RotationYawPitchRollToRef(eulerAngles.y, eulerAngles.x, eulerAngles.z, TmpVectors.Matrix[0]);
+                }
+                this._worldMatrix.setTranslationFromFloats(0, 0, 0);
+                this._worldMatrix.multiplyToRef(TmpVectors.Matrix[0], this._worldMatrix);
 
-            // Restore translation
-            this._worldMatrix.setTranslation(TmpVectors.Vector3[0]);
+                // Restore translation
+                this._worldMatrix.setTranslation(TmpVectors.Vector3[0]);
         }
 
         // Normal matrix