瀏覽代碼

Tweaking Control3D to work better with multiple pointers

rickfromwork 4 年之前
父節點
當前提交
87bc6d7360
共有 2 個文件被更改,包括 23 次插入14 次删除
  1. 20 12
      gui/src/3D/controls/control3D.ts
  2. 3 2
      gui/src/3D/controls/touchButton3D.ts

+ 20 - 12
gui/src/3D/controls/control3D.ts

@@ -20,7 +20,7 @@ export class Control3D implements IDisposable, IBehaviorAware<Control3D> {
     private _node: Nullable<TransformNode>;
     private _node: Nullable<TransformNode>;
     private _downCount = 0;
     private _downCount = 0;
     private _enterCount = -1;
     private _enterCount = -1;
-    private _downPointerIds: { [id: number]: boolean } = {};
+    private _downPointerIds: { [id: number]: number } = {}; // Store number of pointer downs per ID, from near and far interactions
     private _isVisible = true;
     private _isVisible = true;
 
 
     /** Gets or sets the control position  in world space */
     /** Gets or sets the control position  in world space */
@@ -306,16 +306,16 @@ export class Control3D implements IDisposable, IBehaviorAware<Control3D> {
 
 
     /** @hidden */
     /** @hidden */
     public _onPointerEnter(target: Control3D): boolean {
     public _onPointerEnter(target: Control3D): boolean {
-        if (this._enterCount > 0) {
-            return false;
-        }
-
         if (this._enterCount === -1) { // -1 is for touch input, we are now sure we are with a mouse or pencil
         if (this._enterCount === -1) { // -1 is for touch input, we are now sure we are with a mouse or pencil
             this._enterCount = 0;
             this._enterCount = 0;
         }
         }
 
 
         this._enterCount++;
         this._enterCount++;
 
 
+        if (this._enterCount > 1) {
+            return false;
+        }
+
         this.onPointerEnterObservable.notifyObservers(this, -1, target, this);
         this.onPointerEnterObservable.notifyObservers(this, -1, target, this);
 
 
         if (this.pointerEnterAnimation) {
         if (this.pointerEnterAnimation) {
@@ -327,6 +327,12 @@ export class Control3D implements IDisposable, IBehaviorAware<Control3D> {
 
 
     /** @hidden */
     /** @hidden */
     public _onPointerOut(target: Control3D): void {
     public _onPointerOut(target: Control3D): void {
+        this._enterCount--;
+
+        if (this._enterCount > 0) {
+            return;
+        }
+
         this._enterCount = 0;
         this._enterCount = 0;
 
 
         this.onPointerOutObservable.notifyObservers(this, -1, target, this);
         this.onPointerOutObservable.notifyObservers(this, -1, target, this);
@@ -338,14 +344,12 @@ export class Control3D implements IDisposable, IBehaviorAware<Control3D> {
 
 
     /** @hidden */
     /** @hidden */
     public _onPointerDown(target: Control3D, coordinates: Vector3, pointerId: number, buttonIndex: number): boolean {
     public _onPointerDown(target: Control3D, coordinates: Vector3, pointerId: number, buttonIndex: number): boolean {
-        if (this._downCount !== 0) {
-            this._downCount++;
-            return false;
-        }
-
         this._downCount++;
         this._downCount++;
+        this._downPointerIds[pointerId] = this._downPointerIds[pointerId] + 1 || 1;
 
 
-        this._downPointerIds[pointerId] = true;
+        if (this._downCount !== 1) {
+            return false;
+        }
 
 
         this.onPointerDownObservable.notifyObservers(new Vector3WithInfo(coordinates, buttonIndex), -1, target, this);
         this.onPointerDownObservable.notifyObservers(new Vector3WithInfo(coordinates, buttonIndex), -1, target, this);
 
 
@@ -359,7 +363,11 @@ export class Control3D implements IDisposable, IBehaviorAware<Control3D> {
     /** @hidden */
     /** @hidden */
     public _onPointerUp(target: Control3D, coordinates: Vector3, pointerId: number, buttonIndex: number, notifyClick: boolean): void {
     public _onPointerUp(target: Control3D, coordinates: Vector3, pointerId: number, buttonIndex: number, notifyClick: boolean): void {
         this._downCount--;
         this._downCount--;
-        delete this._downPointerIds[pointerId];
+        this._downPointerIds[pointerId]--;
+
+        if (this._downPointerIds[pointerId] <= 0) {
+            delete this._downPointerIds[pointerId];
+        }
 
 
         if (this._downCount < 0) {
         if (this._downCount < 0) {
             // Handle if forcePointerUp was called prior to this
             // Handle if forcePointerUp was called prior to this

+ 3 - 2
gui/src/3D/controls/touchButton3D.ts

@@ -355,6 +355,7 @@ export class TouchButton3D extends Button3D {
 
 
             const uniqueId = mesh.uniqueId;
             const uniqueId = mesh.uniqueId;
 
 
+            let activeInteraction = this._activeInteractions.get(uniqueId);
             if (inRange) {
             if (inRange) {
                 const pointOnButton = this._getPointOnButton(collidablePosition);
                 const pointOnButton = this._getPointOnButton(collidablePosition);
                 const heightFromCenter = this._getHeightFromButtonCenter(collidablePosition);
                 const heightFromCenter = this._getHeightFromButtonCenter(collidablePosition);
@@ -371,7 +372,7 @@ export class TouchButton3D extends Button3D {
                 };
                 };
 
 
                 // Update button state and fire events
                 // Update button state and fire events
-                switch (this._activeInteractions.get(uniqueId) || ButtonState.None) {
+                switch (activeInteraction || ButtonState.None) {
                     case ButtonState.None:
                     case ButtonState.None:
                         if (isGreater(this._frontOffset) &&
                         if (isGreater(this._frontOffset) &&
                             isLower(this._hoverOffset)) {
                             isLower(this._hoverOffset)) {
@@ -401,7 +402,7 @@ export class TouchButton3D extends Button3D {
 
 
                 this._previousHeight.set(uniqueId, heightFromCenter);
                 this._previousHeight.set(uniqueId, heightFromCenter);
             }
             }
-            else {
+            else if ((activeInteraction != undefined) && (activeInteraction != ButtonState.None)) {
                 this._updateButtonState(uniqueId, ButtonState.None, this._lastTouchPoint);
                 this._updateButtonState(uniqueId, ButtonState.None, this._lastTouchPoint);
                 this._previousHeight.delete(uniqueId);
                 this._previousHeight.delete(uniqueId);
             }
             }