Browse Source

Fixing the scaling issue

rickfromwork 4 năm trước cách đây
mục cha
commit
1fd4214737
1 tập tin đã thay đổi với 58 bổ sung31 xóa
  1. 58 31
      gui/src/3D/controls/touchButton3D.ts

+ 58 - 31
gui/src/3D/controls/touchButton3D.ts

@@ -1,7 +1,7 @@
 // Assumptions: absolute position of button mesh is inside the mesh
 
 import { DeepImmutableObject, Nullable } from "babylonjs/types";
-import { Vector3 } from "babylonjs/Maths/math.vector";
+import { Vector3, Quaternion} from "babylonjs/Maths/math.vector";
 import { Mesh } from "babylonjs/Meshes/mesh";
 import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
 import { TransformNode } from "babylonjs/Meshes/transformNode";
@@ -80,7 +80,8 @@ export class TouchButton3D extends Button3D {
     private _collisionMesh: Mesh;
     private _collidableFrontDirection: Vector3;
     private _lastTouchPoint: Vector3;
-    private _buttonForwardRay: Ray;
+    private _tempButtonForwardRay: Ray;
+    private _lastKnownCollidableScale: Vector3;
 
     private _collidableInitialized = false;
 
@@ -103,7 +104,7 @@ export class TouchButton3D extends Button3D {
     constructor(name?: string, collisionMesh?: Mesh) {
         super(name);
 
-        this._buttonForwardRay = new Ray(Vector3.Zero(), Vector3.Zero());
+        this._tempButtonForwardRay = new Ray(Vector3.Zero(), Vector3.Zero());
 
         if (collisionMesh) {
             this.collisionMesh = collisionMesh;
@@ -116,10 +117,23 @@ export class TouchButton3D extends Button3D {
      * Sets the front-facing direction of the button
      * @param frontDir the forward direction of the button
      */
-    public set collidableFrontDirection(frontDir: Vector3) {
-        this._collidableFrontDirection = frontDir.normalize();
+    public set collidableFrontDirection(frontWorldDir: Vector3) {
+        this._collidableFrontDirection = frontWorldDir.normalize();
 
-        this._updateDistances();
+        // Zero out the scale to force it to be proplerly updated in _updateDistanceOffsets
+        this._lastKnownCollidableScale = Vector3.Zero();
+
+        this._updateDistanceOffsets();
+    }
+
+    private _getWorldMatrixData(mesh: Mesh) {
+        let translation = Vector3.Zero();
+        let rotation = Quaternion.Identity();
+        let scale = Vector3.Zero();
+
+        mesh.getWorldMatrix().decompose(scale, rotation, translation);
+
+        return {translation: translation, rotation: rotation, scale: scale};
     }
 
     /**
@@ -131,6 +145,11 @@ export class TouchButton3D extends Button3D {
             this._collisionMesh.dispose();
         }
 
+        // parent the mesh to sync transforms
+        if (!collisionMesh.parent && this.mesh) {
+            collisionMesh.setParent(this.mesh);
+        }
+
         this._collisionMesh = collisionMesh;
         this._collisionMesh.metadata = this;
 
@@ -220,33 +239,39 @@ export class TouchButton3D extends Button3D {
      *    _collisionMesh
      *    _collidableFrontDirection
      */
-    private _updateDistances() {
-        const collisionMeshPos = this._collisionMesh.getAbsolutePosition();
-
-        this._buttonForwardRay.origin = collisionMeshPos;
-        this._buttonForwardRay.direction = this._collidableFrontDirection;
-
-        const frontPickingInfo = this._buttonForwardRay.intersectsMesh(this._collisionMesh as DeepImmutableObject<AbstractMesh>);
-        this._buttonForwardRay.direction = this._buttonForwardRay.direction.negate();
-        const backPickingInfo = this._buttonForwardRay.intersectsMesh(this._collisionMesh as DeepImmutableObject<AbstractMesh>);
-
-        this._frontOffset = 0;
-        this._backOffset = 0;
-
-        if (frontPickingInfo.hit && backPickingInfo.hit) {
-            this._frontOffset = this._getDistanceOffPlane(frontPickingInfo.pickedPoint!,
-                                                              this._collidableFrontDirection,
-                                                              collisionMeshPos);
-            this._backOffset = this._getDistanceOffPlane(backPickingInfo.pickedPoint!,
-                                                             this._collidableFrontDirection,
-                                                             collisionMeshPos);
-        }
+    private _updateDistanceOffsets() {
+        let worldMatrixData = this._getWorldMatrixData(this._collisionMesh);
+        
+        if (!worldMatrixData.scale.equalsWithEpsilon(this._lastKnownCollidableScale)) {
+            const collisionMeshPos = this._collisionMesh.getAbsolutePosition();
+
+            this._tempButtonForwardRay.origin = collisionMeshPos;
+            this._tempButtonForwardRay.direction = this._collidableFrontDirection;
+
+            const frontPickingInfo = this._tempButtonForwardRay.intersectsMesh(this._collisionMesh as DeepImmutableObject<AbstractMesh>);
+            this._tempButtonForwardRay.direction = this._tempButtonForwardRay.direction.negate();
+            const backPickingInfo = this._tempButtonForwardRay.intersectsMesh(this._collisionMesh as DeepImmutableObject<AbstractMesh>);
+
+            this._frontOffset = 0;
+            this._backOffset = 0;
+
+            if (frontPickingInfo.hit && backPickingInfo.hit) {
+                this._frontOffset = this._getDistanceOffPlane(frontPickingInfo.pickedPoint!,
+                                                                  this._collidableFrontDirection,
+                                                                  collisionMeshPos);
+                this._backOffset = this._getDistanceOffPlane(backPickingInfo.pickedPoint!,
+                                                                 this._collidableFrontDirection,
+                                                                 collisionMeshPos);
+            }
 
-        // For now, set the hover height equal to the thickness of the button
-        const buttonThickness = this._frontOffset - this._backOffset;
+            // For now, set the hover height equal to the thickness of the button
+            const buttonThickness = this._frontOffset - this._backOffset;
 
-        this._hoverOffset = this._frontOffset + (buttonThickness * 1.25);
-        this._pushThroughBackOffset = this._backOffset - (buttonThickness * 1.5);
+            this._hoverOffset = this._frontOffset + (buttonThickness * 1.25);
+            this._pushThroughBackOffset = this._backOffset - (buttonThickness * 1.5);
+
+            this._lastKnownCollidableScale = this._getWorldMatrixData(this._collisionMesh).scale;
+        }
     }
 
     // Returns the distance in front of the center of the button
@@ -323,6 +348,8 @@ export class TouchButton3D extends Button3D {
     /** @hidden */
     public _collisionCheckForStateChange(mesh: Mesh) {
         if (this._collidableInitialized) {
+            this._updateDistanceOffsets();
+
             const collidablePosition = mesh.getAbsolutePosition();
             const inRange = this._isPrimedForInteraction(collidablePosition);