Added Initial Config Menu.
This commit is contained in:
parent
06b2989f3a
commit
9d5cb0ab95
@ -23,7 +23,7 @@ import HavokPhysics from "@babylonjs/havok";
|
|||||||
import {Rigplatform} from "./controllers/rigplatform";
|
import {Rigplatform} from "./controllers/rigplatform";
|
||||||
import {DiagramManager} from "./diagram/diagramManager";
|
import {DiagramManager} from "./diagram/diagramManager";
|
||||||
import {Toolbox} from "./toolbox/toolbox";
|
import {Toolbox} from "./toolbox/toolbox";
|
||||||
import {DualshockEventMapper} from "./util/DualshockEventMapper";
|
import {DualshockEventMapper} from "./util/dualshockEventMapper";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -24,6 +24,7 @@ export class Base {
|
|||||||
protected previousRotation: Vector3 = null;
|
protected previousRotation: Vector3 = null;
|
||||||
protected previousScaling: Vector3 = null;
|
protected previousScaling: Vector3 = null;
|
||||||
protected previousPosition: Vector3 = null;
|
protected previousPosition: Vector3 = null;
|
||||||
|
|
||||||
protected readonly xr: WebXRDefaultExperience;
|
protected readonly xr: WebXRDefaultExperience;
|
||||||
|
|
||||||
constructor(controller: WebXRInputSource, scene: Scene, xr: WebXRDefaultExperience) {
|
constructor(controller: WebXRInputSource, scene: Scene, xr: WebXRDefaultExperience) {
|
||||||
@ -42,18 +43,30 @@ export class Base {
|
|||||||
this.initGrip(init.components['xr-standard-squeeze']);
|
this.initGrip(init.components['xr-standard-squeeze']);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public disable() {
|
||||||
|
this.controller.motionController.rootMesh.setEnabled(false);
|
||||||
|
this.controller.pointer.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public enable() {
|
||||||
|
this.controller.motionController.rootMesh.setEnabled(true);
|
||||||
|
this.controller.pointer.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
private createCopy(mesh: AbstractMesh) {
|
private createCopy(mesh: AbstractMesh) {
|
||||||
if (!mesh.isAnInstance) {
|
if (!mesh.isAnInstance) {
|
||||||
return new InstancedMesh("new", (mesh as Mesh));
|
return new InstancedMesh("new", (mesh as Mesh));
|
||||||
} else {
|
} else {
|
||||||
return new InstancedMesh("new", (mesh as InstancedMesh).sourceMesh);
|
return new InstancedMesh("new", (mesh as InstancedMesh).sourceMesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private initGrip(grip: WebXRControllerComponent) {
|
private initGrip(grip: WebXRControllerComponent) {
|
||||||
grip.onButtonStateChangedObservable.add(() => {
|
grip.onButtonStateChangedObservable.add(() => {
|
||||||
if (grip.changes.pressed) {
|
if (grip.changes.pressed) {
|
||||||
if (grip.pressed){
|
if (grip.pressed) {
|
||||||
let mesh = this.scene.meshUnderPointer;
|
let mesh = this.scene.meshUnderPointer;
|
||||||
if (this.xr.pointerSelection.getMeshUnderPointer) {
|
if (this.xr.pointerSelection.getMeshUnderPointer) {
|
||||||
mesh = this.xr.pointerSelection.getMeshUnderPointer(this.controller.uniqueId);
|
mesh = this.xr.pointerSelection.getMeshUnderPointer(this.controller.uniqueId);
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
import {AbstractMesh, Observable, TransformNode} from "@babylonjs/core";
|
import {AbstractMesh, Observable, TransformNode} from "@babylonjs/core";
|
||||||
|
|
||||||
|
export type ControllerEventType = {
|
||||||
|
type: string
|
||||||
|
}
|
||||||
export class Controllers {
|
export class Controllers {
|
||||||
public static movable: TransformNode | AbstractMesh;
|
public static movable: TransformNode | AbstractMesh;
|
||||||
public static controllerObserver = new Observable();
|
public static controllerObserver: Observable<ControllerEventType> = new Observable();
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,17 +1,18 @@
|
|||||||
import {Scene, Vector3, WebXRDefaultExperience, WebXRInputSource} from "@babylonjs/core";
|
import {Scene, Vector3, WebXRControllerComponent, WebXRDefaultExperience, WebXRInputSource} from "@babylonjs/core";
|
||||||
import {Base} from "./base";
|
import {Base} from "./base";
|
||||||
import {Controllers} from "./controllers";
|
import {Controllers} from "./controllers";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
|
import {ConfigMenu} from "../menus/configMenu";
|
||||||
|
|
||||||
|
|
||||||
export class Left extends Base {
|
export class Left extends Base {
|
||||||
public static instance: Left;
|
public static instance: Left;
|
||||||
|
public configMenu: ConfigMenu;
|
||||||
constructor(controller:
|
constructor(controller:
|
||||||
WebXRInputSource, scene: Scene, xr: WebXRDefaultExperience) {
|
WebXRInputSource, scene: Scene, xr: WebXRDefaultExperience) {
|
||||||
|
|
||||||
super(controller, scene, xr);
|
super(controller, scene, xr);
|
||||||
|
this.configMenu = new ConfigMenu(this.scene, xr.baseExperience);
|
||||||
Left.instance = this;
|
Left.instance = this;
|
||||||
this.controller.onMotionControllerInitObservable.add((init) => {
|
this.controller.onMotionControllerInitObservable.add((init) => {
|
||||||
if (init.components['xr-standard-thumbstick']) {
|
if (init.components['xr-standard-thumbstick']) {
|
||||||
@ -24,6 +25,8 @@ export class Left extends Base {
|
|||||||
this.moveMovable(value);
|
this.moveMovable(value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.initXButton(init.components['x-button']);
|
||||||
|
this.initYButton(init.components['y-button']);
|
||||||
init.components['xr-standard-thumbstick'].onButtonStateChangedObservable.add((value) => {
|
init.components['xr-standard-thumbstick'].onButtonStateChangedObservable.add((value) => {
|
||||||
if (value.pressed) {
|
if (value.pressed) {
|
||||||
log.trace('Left', 'thumbstick changed');
|
log.trace('Left', 'thumbstick changed');
|
||||||
@ -35,6 +38,26 @@ export class Left extends Base {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private initXButton(xbutton: WebXRControllerComponent) {
|
||||||
|
if (xbutton) {
|
||||||
|
xbutton.onButtonStateChangedObservable.add((button) => {
|
||||||
|
if (button.pressed) {
|
||||||
|
Controllers.controllerObserver.notifyObservers({type: 'x-button', value: button.value});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private initYButton(ybutton: WebXRControllerComponent) {
|
||||||
|
if (ybutton) {
|
||||||
|
ybutton.onButtonStateChangedObservable.add((button) => {
|
||||||
|
if (button.pressed) {
|
||||||
|
Controllers.controllerObserver.notifyObservers({type: 'y-button', value: button.value});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private moveMovable(value: { x: number, y: number }) {
|
private moveMovable(value: { x: number, y: number }) {
|
||||||
if (Math.abs(value.x) > .1) {
|
if (Math.abs(value.x) > .1) {
|
||||||
Controllers.movable.position.x += .005 * Math.sign(value.x);
|
Controllers.movable.position.x += .005 * Math.sign(value.x);
|
||||||
|
|||||||
@ -1,11 +1,5 @@
|
|||||||
import {Base} from "./base";
|
import {Base} from "./base";
|
||||||
import {
|
import {Scene, Vector3, WebXRControllerComponent, WebXRDefaultExperience, WebXRInputSource} from "@babylonjs/core";
|
||||||
Scene,
|
|
||||||
Vector3,
|
|
||||||
WebXRControllerComponent,
|
|
||||||
WebXRDefaultExperience,
|
|
||||||
WebXRInputSource
|
|
||||||
} from "@babylonjs/core";
|
|
||||||
import {Controllers} from "./controllers";
|
import {Controllers} from "./controllers";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
|
|
||||||
@ -22,8 +16,6 @@ export class Right extends Base {
|
|||||||
this.initAButton(init.components['a-button']);
|
this.initAButton(init.components['a-button']);
|
||||||
this.initThumbstick(init.components['xr-standard-thumbstick']);
|
this.initThumbstick(init.components['xr-standard-thumbstick']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private initBButton(bbutton: WebXRControllerComponent) {
|
private initBButton(bbutton: WebXRControllerComponent) {
|
||||||
|
|||||||
@ -16,16 +16,15 @@ import {
|
|||||||
} from "@babylonjs/core";
|
} from "@babylonjs/core";
|
||||||
import {Right} from "./right";
|
import {Right} from "./right";
|
||||||
import {Left} from "./left";
|
import {Left} from "./left";
|
||||||
import {Bmenu} from "../menus/bmenu";
|
import {EditMenu} from "../menus/editMenu";
|
||||||
import {Controllers} from "./controllers";
|
import {Controllers} from "./controllers";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export class Rigplatform {
|
export class Rigplatform {
|
||||||
private velocityIndex = 2;
|
private velocityIndex = 2;
|
||||||
private readonly velocityArray = [0.01, 0.1, 1, 2, 5];
|
private readonly velocityArray = [0.01, 0.1, 1, 2, 5];
|
||||||
public bMenu: Bmenu;
|
public bMenu: EditMenu;
|
||||||
private readonly scene: Scene;
|
private readonly scene: Scene;
|
||||||
public static instance: Rigplatform;
|
public static instance: Rigplatform;
|
||||||
private static xr: WebXRDefaultExperience;
|
private static xr: WebXRDefaultExperience;
|
||||||
@ -41,8 +40,9 @@ export class Rigplatform {
|
|||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
Rigplatform.xr = xr;
|
Rigplatform.xr = xr;
|
||||||
Rigplatform.instance = this;
|
Rigplatform.instance = this;
|
||||||
this.bMenu = new Bmenu(scene, xr.baseExperience);
|
this.bMenu = new EditMenu(scene, xr.baseExperience);
|
||||||
this.camera = scene.activeCamera;
|
this.camera = scene.activeCamera;
|
||||||
|
|
||||||
this.rigMesh = MeshBuilder.CreateBox("platform", {width: 2, height: .02, depth: 2}, scene);
|
this.rigMesh = MeshBuilder.CreateBox("platform", {width: 2, height: .02, depth: 2}, scene);
|
||||||
for (const cam of scene.cameras) {
|
for (const cam of scene.cameras) {
|
||||||
cam.parent = this.rigMesh;
|
cam.parent = this.rigMesh;
|
||||||
|
|||||||
@ -1,11 +0,0 @@
|
|||||||
export class Amenu {
|
|
||||||
private visible = false;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public toggle() {
|
|
||||||
this.visible = !this.visible;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
68
src/menus/configMenu.ts
Normal file
68
src/menus/configMenu.ts
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import {AdvancedDynamicTexture, RadioGroup, SelectionPanel} from "@babylonjs/gui";
|
||||||
|
import {AbstractMesh, Angle, MeshBuilder, Scene, WebXRExperienceHelper} from "@babylonjs/core";
|
||||||
|
import {CameraHelper} from "../util/cameraHelper";
|
||||||
|
import log from "loglevel";
|
||||||
|
import {AppConfig} from "../util/appConfig";
|
||||||
|
import {Controllers} from "../controllers/controllers";
|
||||||
|
|
||||||
|
export class ConfigMenu {
|
||||||
|
private readonly scene: Scene;
|
||||||
|
private readonly xr: WebXRExperienceHelper;
|
||||||
|
private configPlane: AbstractMesh = null;
|
||||||
|
|
||||||
|
constructor(scene: Scene, xr: WebXRExperienceHelper) {
|
||||||
|
this.scene = scene;
|
||||||
|
this.xr = xr;
|
||||||
|
Controllers.controllerObserver.add((event) => {
|
||||||
|
if (event.type == 'x-button') {
|
||||||
|
this.toggle();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public toggle() {
|
||||||
|
if (this.configPlane) {
|
||||||
|
this.configPlane.dispose();
|
||||||
|
this.configPlane = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.configPlane = MeshBuilder
|
||||||
|
.CreatePlane("gridSizePlane",
|
||||||
|
{
|
||||||
|
width: .25,
|
||||||
|
height: .5
|
||||||
|
}, this.scene);
|
||||||
|
const configTexture = AdvancedDynamicTexture.CreateForMesh(this.configPlane, 256, 512);
|
||||||
|
configTexture.background = "white";
|
||||||
|
const selectionPanel = new SelectionPanel("selectionPanel");
|
||||||
|
selectionPanel.fontSize = "24px";
|
||||||
|
selectionPanel.height = "100%";
|
||||||
|
configTexture.addControl(selectionPanel)
|
||||||
|
const radio1 = new RadioGroup("Rotation Snap");
|
||||||
|
radio1.addRadio("Off", this.rotateVal);
|
||||||
|
radio1.addRadio("22.5 degrees", this.rotateVal);
|
||||||
|
radio1.addRadio("45 degrees", this.rotateVal);
|
||||||
|
radio1.addRadio("90 degrees", this.rotateVal);
|
||||||
|
selectionPanel.addGroup(radio1);
|
||||||
|
const radio2 = new RadioGroup("Grid Snap");
|
||||||
|
radio2.addRadio("Off", this.gridVal);
|
||||||
|
radio2.addRadio("1 cm", this.gridVal);
|
||||||
|
radio2.addRadio("10 cm", this.gridVal);
|
||||||
|
radio2.addRadio("25 cm", this.gridVal);
|
||||||
|
selectionPanel.addGroup(radio1);
|
||||||
|
selectionPanel.addGroup(radio2);
|
||||||
|
this.configPlane.position = CameraHelper.getFrontPosition(2, this.scene);
|
||||||
|
this.configPlane.rotation.y = Angle.FromDegrees(180).radians();
|
||||||
|
}
|
||||||
|
|
||||||
|
private rotateVal(value) {
|
||||||
|
AppConfig.config.rotateSnap = AppConfig.config.rotateSnapArray[value];
|
||||||
|
log.debug("configMenu", "rotate Snap", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private gridVal(value) {
|
||||||
|
AppConfig.config.gridSnap = AppConfig.config.gridSnapArray[value];
|
||||||
|
log.debug("configMenu", "grid Snap", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -14,8 +14,10 @@ import {DiagramEvent, DiagramEventType} from "../diagram/diagramEntity";
|
|||||||
import {MeshConverter} from "../diagram/meshConverter";
|
import {MeshConverter} from "../diagram/meshConverter";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
import {InputTextView} from "../information/inputTextView";
|
import {InputTextView} from "../information/inputTextView";
|
||||||
|
import {Right} from "../controllers/right";
|
||||||
|
import {Left} from "../controllers/left";
|
||||||
|
|
||||||
export class Bmenu {
|
export class EditMenu {
|
||||||
private state: BmenuState = BmenuState.NONE;
|
private state: BmenuState = BmenuState.NONE;
|
||||||
private manager: GUI3DManager;
|
private manager: GUI3DManager;
|
||||||
private readonly scene: Scene;
|
private readonly scene: Scene;
|
||||||
@ -102,6 +104,10 @@ export class Bmenu {
|
|||||||
} else {
|
} else {
|
||||||
textInput.value = "";
|
textInput.value = "";
|
||||||
}
|
}
|
||||||
|
if (this.xr.sessionManager.inXRSession) {
|
||||||
|
Right.instance.disable();
|
||||||
|
Left.instance.disable();
|
||||||
|
}
|
||||||
textInput.focus();
|
textInput.focus();
|
||||||
|
|
||||||
if (navigator.userAgent.indexOf('Macintosh') > -1) {
|
if (navigator.userAgent.indexOf('Macintosh') > -1) {
|
||||||
@ -128,6 +134,8 @@ export class Bmenu {
|
|||||||
MeshConverter.updateTextNode(mesh, textInput.value);
|
MeshConverter.updateTextNode(mesh, textInput.value);
|
||||||
this.persist(mesh, textInput.value);
|
this.persist(mesh, textInput.value);
|
||||||
this.cleanup();
|
this.cleanup();
|
||||||
|
Right.instance.enable();
|
||||||
|
Left.instance.enable();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.textInput = textInput;
|
this.textInput = textInput;
|
||||||
@ -1,9 +1,13 @@
|
|||||||
import {
|
import {
|
||||||
AbstractMesh, Angle,
|
AbstractMesh,
|
||||||
Color3, InstancedMesh, Mesh,
|
Angle,
|
||||||
|
Color3,
|
||||||
|
InstancedMesh,
|
||||||
|
Mesh,
|
||||||
MeshBuilder,
|
MeshBuilder,
|
||||||
Scene,
|
Scene,
|
||||||
StandardMaterial, TransformNode,
|
StandardMaterial,
|
||||||
|
TransformNode,
|
||||||
Vector3,
|
Vector3,
|
||||||
WebXRExperienceHelper
|
WebXRExperienceHelper
|
||||||
} from "@babylonjs/core";
|
} from "@babylonjs/core";
|
||||||
@ -80,8 +84,6 @@ export class Toolbox {
|
|||||||
this.addPanel.position = new Vector3(0, 0, .5);
|
this.addPanel.position = new Vector3(0, 0, .5);
|
||||||
addButton.onPointerClickObservable.add(() => {
|
addButton.onPointerClickObservable.add(() => {
|
||||||
this.buildColor(Color3.Random());
|
this.buildColor(Color3.Random());
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -106,14 +108,16 @@ export class Toolbox {
|
|||||||
newItem.position = new Vector3(this.calculatePosition(++i), .1, 0);
|
newItem.position = new Vector3(this.calculatePosition(++i), .1, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const myPlane = MeshBuilder
|
const colorPickerPlane = MeshBuilder
|
||||||
.CreatePlane("myPlane",
|
.CreatePlane("myPlane",
|
||||||
{width: Toolbox.WIDGET_SIZE,
|
{
|
||||||
height: Toolbox.WIDGET_SIZE}, this.scene);
|
width: Toolbox.WIDGET_SIZE,
|
||||||
myPlane.parent=mesh;
|
height: Toolbox.WIDGET_SIZE
|
||||||
myPlane.position= new Vector3(this.calculatePosition(++i), .1, 0);
|
}, this.scene);
|
||||||
|
colorPickerPlane.parent = mesh;
|
||||||
|
colorPickerPlane.position = new Vector3(this.calculatePosition(++i), .1, 0);
|
||||||
|
|
||||||
const advancedTexture2 = AdvancedDynamicTexture.CreateForMesh(myPlane, 1024, 1024);
|
const colorPickerTexture = AdvancedDynamicTexture.CreateForMesh(colorPickerPlane, 1024, 1024);
|
||||||
const colorPicker = new ColorPicker("color-picker");
|
const colorPicker = new ColorPicker("color-picker");
|
||||||
colorPicker.scaleY = 5;
|
colorPicker.scaleY = 5;
|
||||||
colorPicker.scaleX = 5;
|
colorPicker.scaleX = 5;
|
||||||
@ -134,7 +138,7 @@ export class Toolbox {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
advancedTexture2.addControl(colorPicker);
|
colorPickerTexture.addControl(colorPicker);
|
||||||
this.addPanel.position.z += .25;
|
this.addPanel.position.z += .25;
|
||||||
this.node.position.z -= .125;
|
this.node.position.z -= .125;
|
||||||
}
|
}
|
||||||
|
|||||||
19
src/util/appConfig.ts
Normal file
19
src/util/appConfig.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
export class AppConfig {
|
||||||
|
public gridSnap = 0;
|
||||||
|
public rotateSnap = 0;
|
||||||
|
public gridSnapArray =
|
||||||
|
[0, 0.1, 0.5, 1];
|
||||||
|
public rotateSnapArray =
|
||||||
|
[0, 22.5, 45, 90]
|
||||||
|
|
||||||
|
private static _config: AppConfig;
|
||||||
|
|
||||||
|
public static get config() {
|
||||||
|
if (!AppConfig._config) {
|
||||||
|
AppConfig._config = new AppConfig();
|
||||||
|
}
|
||||||
|
return AppConfig._config;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
import {DualShockButton} from "@babylonjs/core";
|
import {DualShockButton} from "@babylonjs/core";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
|
|
||||||
type ButtonEvent = {
|
type ButtonEvent = {
|
||||||
objectName?: string,
|
objectName?: string,
|
||||||
pressed: boolean,
|
pressed: boolean,
|
||||||
@ -57,17 +58,18 @@ export class DualshockEventMapper {
|
|||||||
log.debug('DualshockEventMapper','D-Pad Up');
|
log.debug('DualshockEventMapper','D-Pad Up');
|
||||||
break;
|
break;
|
||||||
case 13:
|
case 13:
|
||||||
log.debug('DualshockEventMapper','D-Pad Down');
|
log.debug('DualshockEventMapper', 'D-Pad Down');
|
||||||
buttonEvent.objectName = "left-controller";
|
buttonEvent.objectName = "left-controller";
|
||||||
buttonEvent.buttonIndex = 3;
|
buttonEvent.buttonIndex = 3;
|
||||||
break;
|
break;
|
||||||
case 14:
|
case 14:
|
||||||
log.debug('DualshockEventMapper','D-Pad Left');
|
log.debug('DualshockEventMapper', 'D-Pad Left');
|
||||||
|
log.debug('DualshockEventMapper', 'D-Pad Left');
|
||||||
buttonEvent.objectName = "left-controller";
|
buttonEvent.objectName = "left-controller";
|
||||||
buttonEvent.buttonIndex = 4;
|
buttonEvent.buttonIndex = 4;
|
||||||
break;
|
break;
|
||||||
case 15:
|
case 15:
|
||||||
log.debug('DualshockEventMapper','D-Pad Right');
|
log.debug('DualshockEventMapper', 'D-Pad Right');
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
log.debug('DualshockEventMapper','L3');
|
log.debug('DualshockEventMapper','L3');
|
||||||
@ -1,10 +0,0 @@
|
|||||||
import {PlanePanel} from "@babylonjs/gui";
|
|
||||||
|
|
||||||
export class MyMenu extends PlanePanel {
|
|
||||||
public arrangeChildren: boolean = true;
|
|
||||||
protected _arrangeChildren() {
|
|
||||||
if (this.arrangeChildren) {
|
|
||||||
super._arrangeChildren();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user