浏览代码

Merge pull request #8844 from CedricGuillemet/fixGizmoInstancedMesh

[gizmo] fix camera LH/RH coord + fix instanced meshes update
David Catuhe 5 年之前
父节点
当前提交
985622f526
共有 3 个文件被更改,包括 34 次插入14 次删除
  1. 3 2
      src/Gizmos/axisDragGizmo.ts
  2. 5 1
      src/Gizmos/cameraGizmo.ts
  3. 26 11
      src/Gizmos/gizmo.ts

+ 3 - 2
src/Gizmos/axisDragGizmo.ts

@@ -118,7 +118,8 @@ export class AxisDragGizmo extends Gizmo {
                     if ((this.attachedNode as any).position) { // Required for nodes like lights
                         (this.attachedNode as any).position.addInPlaceFromFloats(localDelta.x, localDelta.y, localDelta.z);
                     }
-                    this.attachedNode.getWorldMatrix().addTranslationFromFloats(localDelta.x, localDelta.y, localDelta.z);
+                    // use _worldMatrix to not force a matrix update when calling GetWorldMatrix especialy with Cameras
+                    this.attachedNode._worldMatrix.addTranslationFromFloats(localDelta.x, localDelta.y, localDelta.z);
                     this.attachedNode.updateCache();
                 } else {
                     currentSnapDragDistance += event.dragDistance;
@@ -127,7 +128,7 @@ export class AxisDragGizmo extends Gizmo {
                         currentSnapDragDistance = currentSnapDragDistance % this.snapDistance;
                         localDelta.normalizeToRef(tmpVector);
                         tmpVector.scaleInPlace(this.snapDistance * dragSteps);
-                        this.attachedNode.getWorldMatrix().addTranslationFromFloats(tmpVector.x, tmpVector.y, tmpVector.z);
+                        this.attachedNode._worldMatrix.addTranslationFromFloats(tmpVector.x, tmpVector.y, tmpVector.z);
                         this.attachedNode.updateCache();
                         tmpSnapEvent.snapDistance = this.snapDistance * dragSteps;
                         this.onSnapObservable.notifyObservers(tmpSnapEvent);

+ 5 - 1
src/Gizmos/cameraGizmo.ts

@@ -110,6 +110,11 @@ export class CameraGizmo extends Gizmo {
         this._cameraLinesMesh.scaling.x = 1 / this._rootMesh.scaling.x;
         this._cameraLinesMesh.scaling.y = 1 / this._rootMesh.scaling.y;
         this._cameraLinesMesh.scaling.z = 1 / this._rootMesh.scaling.z;
+
+        // take care of coordinate system in camera scene to properly display the mesh with the good Y axis orientation in this scene
+        this._cameraMesh.parent = null;
+        this._cameraMesh.rotation.y = Math.PI * 0.5 * (this._camera.getScene().useRightHandedSystem ? 1 : -1);
+        this._cameraMesh.parent = this._rootMesh;
     }
 
     // Static helper methods
@@ -158,7 +163,6 @@ export class CameraGizmo extends Gizmo {
         cyl3.rotation.z = Math.PI * 0.5;
 
         root.scaling.scaleInPlace(CameraGizmo._Scale);
-        root.rotation.y = -Math.PI * 0.5;
         mesh.position.x = -0.9;
 
         return root;

+ 26 - 11
src/Gizmos/gizmo.ts

@@ -112,6 +112,9 @@ export class Gizmo implements IDisposable {
     private _tempQuaternion = new Quaternion(0, 0, 0, 1);
     private _tempVector = new Vector3();
     private _tempVector2 = new Vector3();
+    private _tempMatrix1 = new Matrix();
+    private _tempMatrix2 = new Matrix();
+    private _rightHandtoLeftHandMatrix = Matrix.RotationY(Math.PI);
 
     /**
      * Creates a gizmo
@@ -187,16 +190,27 @@ export class Gizmo implements IDisposable {
 
         if  ((<Camera>this._attachedNode)._isCamera) {
             var camera = this._attachedNode as Camera;
+            var worldMatrix;
+            var worldMatrixUC;
             if (camera.parent) {
-                var parentInv = new Matrix();
-                var localMat = new Matrix();
-                camera.parent.getWorldMatrix().invertToRef(parentInv);
-                this._attachedNode.getWorldMatrix().multiplyToRef(parentInv, localMat);
-                localMat.decompose(this._tempVector2, this._tempQuaternion, this._tempVector);
+                var parentInv = this._tempMatrix2;
+                camera.parent._worldMatrix.invertToRef(parentInv);
+                this._attachedNode._worldMatrix.multiplyToRef(parentInv, this._tempMatrix1);
+                worldMatrix = this._tempMatrix1;
             } else {
-                this._attachedNode.getWorldMatrix().decompose(this._tempVector2, this._tempQuaternion, this._tempVector);
+                worldMatrix = this._attachedNode._worldMatrix;
             }
 
+            if (camera.getScene().useRightHandedSystem) {
+                // avoid desync with RH matrix computation. Otherwise, rotation of PI around Y axis happens each frame resulting in axis flipped because worldMatrix is computed as inverse of viewMatrix.
+                this._rightHandtoLeftHandMatrix.multiplyToRef(worldMatrix, this._tempMatrix2);
+                worldMatrixUC = this._tempMatrix2;
+            } else {
+                worldMatrixUC = worldMatrix;
+            }
+
+            worldMatrixUC.decompose(this._tempVector2, this._tempQuaternion, this._tempVector);
+
             var inheritsTargetCamera = this._attachedNode.getClassName() === "FreeCamera"
             || this._attachedNode.getClassName() === "FlyCamera"
             || this._attachedNode.getClassName() === "ArcFollowCamera"
@@ -207,17 +221,18 @@ export class Gizmo implements IDisposable {
             if (inheritsTargetCamera) {
                 var targetCamera = this._attachedNode as TargetCamera;
                 targetCamera.rotation = this._tempQuaternion.toEulerAngles();
+
                 if (targetCamera.rotationQuaternion) {
                     targetCamera.rotationQuaternion.copyFrom(this._tempQuaternion);
                 }
             }
 
             camera.position.copyFrom(this._tempVector);
-        } else if ((<Mesh>this._attachedNode)._isMesh || this._attachedNode.getClassName() === "AbstractMesh" || this._attachedNode.getClassName() === "TransformNode") {
+        } else if ((<Mesh>this._attachedNode)._isMesh || this._attachedNode.getClassName() === "AbstractMesh" || this._attachedNode.getClassName() === "TransformNode" || this._attachedNode.getClassName() === "InstancedMesh") {
             var transform = this._attachedNode as TransformNode;
             if (transform.parent) {
-                var parentInv = new Matrix();
-                var localMat = new Matrix();
+                var parentInv = this._tempMatrix1;
+                var localMat = this._tempMatrix2;
                 transform.parent.getWorldMatrix().invertToRef(parentInv);
                 this._attachedNode._worldMatrix.multiplyToRef(parentInv, localMat);
                 localMat.decompose(transform.scaling, this._tempQuaternion, transform.position);
@@ -234,8 +249,8 @@ export class Gizmo implements IDisposable {
             const parent = bone.getParent();
 
             if (parent) {
-                var invParent = new Matrix();
-                var boneLocalMatrix = new Matrix();
+                var invParent = this._tempMatrix1;
+                var boneLocalMatrix = this._tempMatrix2;
                 parent.getWorldMatrix().invertToRef(invParent);
                 bone.getWorldMatrix().multiplyToRef(invParent, boneLocalMatrix);
                 var lmat = bone.getLocalMatrix();