Move exit XR button to toolbox class
Refactored exit XR button creation from rigplatform to toolbox for better organization and UI cohesion. - Add setXR() methods to DiagramManager, DiagramMenuManager, and Toolbox to pass WebXRDefaultExperience after initialization - Create setupXRButton() in Toolbox class that creates button when entering XR - Position button at bottom-right of toolbox (x: 0.5, y: -0.35, z: 0) - Use Y-axis rotation (Math.PI) for correct orientation within toolbox coordinate system - Scale button to 0.2 for appropriate size - Remove button creation code from rigplatform Exit button now moves with toolbox and is logically grouped with other UI elements. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
d59c7b6e6e
commit
100c5e612c
@ -8,7 +8,6 @@ import {DefaultScene} from "../defaultScene";
|
|||||||
import {ControllerEvent} from "./types/controllerEvent";
|
import {ControllerEvent} from "./types/controllerEvent";
|
||||||
import {ControllerEventType} from "./types/controllerEventType";
|
import {ControllerEventType} from "./types/controllerEventType";
|
||||||
import {controllerObservable} from "./controllers";
|
import {controllerObservable} from "./controllers";
|
||||||
import {Button} from "../objects/Button";
|
|
||||||
|
|
||||||
const RIGHT = "right";
|
const RIGHT = "right";
|
||||||
const LEFT = "left";
|
const LEFT = "left";
|
||||||
@ -45,25 +44,7 @@ export class Rigplatform {
|
|||||||
|
|
||||||
this._xr = xr;
|
this._xr = xr;
|
||||||
this.rigMesh = buildRig(xr);
|
this.rigMesh = buildRig(xr);
|
||||||
this._xr.baseExperience.onStateChangedObservable.add((state) => {
|
// Exit XR button is now created in toolbox class
|
||||||
if (state == 2) {
|
|
||||||
const button = Button.CreateButton("exitXr", "exitXr", this._scene, {});
|
|
||||||
button.transform.position.z = 1;
|
|
||||||
button.transform.rotation.y = Math.PI;
|
|
||||||
button.transform.position.y = 1.2;
|
|
||||||
button.transform.scaling = new Vector3(.1, .1, .1);
|
|
||||||
button.transform.parent = this.rigMesh;
|
|
||||||
button.onPointerObservable.add((evt) => {
|
|
||||||
console.log(evt);
|
|
||||||
console.log(evt.sourceEvent.type);
|
|
||||||
if (evt.sourceEvent.type == 'pointerdown') {
|
|
||||||
xr.baseExperience.exitXRAsync();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
this._fixRotation();
|
this._fixRotation();
|
||||||
this._initializeControllers();
|
this._initializeControllers();
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import {AbstractActionManager, AbstractMesh, ActionManager, Observable, Scene} from "@babylonjs/core";
|
import {AbstractActionManager, AbstractMesh, ActionManager, Observable, Scene, WebXRDefaultExperience} from "@babylonjs/core";
|
||||||
import {DiagramEntity, DiagramEntityType, DiagramEvent, DiagramEventType} from "./types/diagramEntity";
|
import {DiagramEntity, DiagramEntityType, DiagramEvent, DiagramEventType} from "./types/diagramEntity";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
|
|
||||||
@ -29,6 +29,14 @@ export class DiagramManager {
|
|||||||
private _moving: number = 10;
|
private _moving: number = 10;
|
||||||
private _i: number = 0;
|
private _i: number = 0;
|
||||||
|
|
||||||
|
public get diagramMenuManager(): DiagramMenuManager {
|
||||||
|
return this._diagramMenuManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setXR(xr: WebXRDefaultExperience): void {
|
||||||
|
this._diagramMenuManager.setXR(xr);
|
||||||
|
}
|
||||||
|
|
||||||
constructor(readyObservable: Observable<boolean>) {
|
constructor(readyObservable: Observable<boolean>) {
|
||||||
this._me = getMe();
|
this._me = getMe();
|
||||||
this._scene = DefaultScene.Scene;
|
this._scene = DefaultScene.Scene;
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import {DiagramEntityType, DiagramEvent, DiagramEventType} from "./types/diagramEntity";
|
import {DiagramEntityType, DiagramEvent, DiagramEventType} from "./types/diagramEntity";
|
||||||
import {AbstractMesh, ActionEvent, Observable, Scene, Vector3, WebXRInputSource} from "@babylonjs/core";
|
import {AbstractMesh, ActionEvent, Observable, Scene, Vector3, WebXRDefaultExperience, WebXRInputSource} from "@babylonjs/core";
|
||||||
import {InputTextView} from "../information/inputTextView";
|
import {InputTextView} from "../information/inputTextView";
|
||||||
import {DefaultScene} from "../defaultScene";
|
import {DefaultScene} from "../defaultScene";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
@ -127,4 +127,8 @@ export class DiagramMenuManager {
|
|||||||
private notifyAll(event: DiagramEvent) {
|
private notifyAll(event: DiagramEvent) {
|
||||||
this._notifier.notifyObservers(event, DiagramEventObserverMask.ALL);
|
this._notifier.notifyObservers(event, DiagramEventObserverMask.ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public setXR(xr: WebXRDefaultExperience): void {
|
||||||
|
this.toolbox.setXR(xr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,8 +1,9 @@
|
|||||||
import {AbstractMesh, Color3, InstancedMesh, Node, Observable, Scene, TransformNode, Vector3} from "@babylonjs/core";
|
import {AbstractMesh, Color3, InstancedMesh, Node, Observable, Scene, TransformNode, Vector3, WebXRDefaultExperience} from "@babylonjs/core";
|
||||||
import {buildColor} from "./functions/buildColor";
|
import {buildColor} from "./functions/buildColor";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
import {Handle} from "../objects/handle";
|
import {Handle} from "../objects/handle";
|
||||||
import {DefaultScene} from "../defaultScene";
|
import {DefaultScene} from "../defaultScene";
|
||||||
|
import {Button} from "../objects/Button";
|
||||||
|
|
||||||
const colors: string[] = [
|
const colors: string[] = [
|
||||||
"#222222", "#8b4513", "#006400", "#778899",
|
"#222222", "#8b4513", "#006400", "#778899",
|
||||||
@ -18,6 +19,7 @@ export class Toolbox {
|
|||||||
private readonly _logger = log.getLogger('Toolbox');
|
private readonly _logger = log.getLogger('Toolbox');
|
||||||
private readonly _handle: Handle;
|
private readonly _handle: Handle;
|
||||||
private readonly _scene: Scene;
|
private readonly _scene: Scene;
|
||||||
|
private _xr?: WebXRDefaultExperience;
|
||||||
|
|
||||||
constructor(readyObservable: Observable<boolean>) {
|
constructor(readyObservable: Observable<boolean>) {
|
||||||
this._scene = DefaultScene.Scene;
|
this._scene = DefaultScene.Scene;
|
||||||
@ -31,6 +33,11 @@ export class Toolbox {
|
|||||||
});
|
});
|
||||||
Toolbox._instance = this;
|
Toolbox._instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public setXR(xr: WebXRDefaultExperience): void {
|
||||||
|
this._xr = xr;
|
||||||
|
this.setupXRButton();
|
||||||
|
}
|
||||||
private index = 0;
|
private index = 0;
|
||||||
private colorPicker: TransformNode;
|
private colorPicker: TransformNode;
|
||||||
private changing = false;
|
private changing = false;
|
||||||
@ -128,5 +135,33 @@ export class Toolbox {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private setupXRButton() {
|
||||||
|
if (!this._xr) {
|
||||||
|
this._logger.warn('XR not available, exit XR button will not be created');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._xr.baseExperience.onStateChangedObservable.add((state) => {
|
||||||
|
if (state == 2) { // WebXRState.IN_XR
|
||||||
|
const button = Button.CreateButton("exitXr", "exitXr", this._scene, {});
|
||||||
|
|
||||||
|
// Position button at bottom-right of toolbox, matching handle size and orientation
|
||||||
|
button.transform.position.x = 0.5; // Right side
|
||||||
|
button.transform.position.y = -0.35; // Below color grid
|
||||||
|
button.transform.position.z = 0; // Coplanar with toolbox
|
||||||
|
button.transform.rotation.y = Math.PI; // Flip 180° on local x-axis to face correctly
|
||||||
|
button.transform.scaling = new Vector3(.2, .2, .2); // Match handle height
|
||||||
|
button.transform.parent = this._toolboxBaseNode;
|
||||||
|
|
||||||
|
button.onPointerObservable.add((evt) => {
|
||||||
|
this._logger.debug(evt);
|
||||||
|
if (evt.sourceEvent.type == 'pointerdown') {
|
||||||
|
this._xr.baseExperience.exitXRAsync();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -79,6 +79,9 @@ export async function groundMeshObserver(ground: AbstractMesh,
|
|||||||
rig.turnSnap = parseFloat(config.snapTurnSnap);
|
rig.turnSnap = parseFloat(config.snapTurnSnap);
|
||||||
const webController = new WebController(ground.getScene(), rig, diagramManager);
|
const webController = new WebController(ground.getScene(), rig, diagramManager);
|
||||||
|
|
||||||
|
// Set XR on diagram manager so toolbox can create exit button
|
||||||
|
diagramManager.setXR(xr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function positionComponentsRelativeToCamera(scene: Scene, diagramManager: DiagramManager) {
|
function positionComponentsRelativeToCamera(scene: Scene, diagramManager: DiagramManager) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user