Refactor fly/walk mode.

This commit is contained in:
Michael Mainguy 2024-01-15 11:03:07 -06:00
parent a1adbf5bd9
commit cdc47f8ac9
11 changed files with 4617 additions and 55 deletions

View File

@ -7,7 +7,7 @@
"node": ">=18.0.0" "node": ">=18.0.0"
}, },
"scripts": { "scripts": {
"dev": "vite", "dev": "cp ./node_modules/@babylonjs/havok/lib/esm/HavokPhysics.wasm ./node_modules/.vite/deps && vite",
"build": "vite build", "build": "vite build",
"preview": "vite preview", "preview": "vite preview",
"serve": "node server.js", "serve": "node server.js",

4312
public/arch_demo.xml Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

View File

@ -9,10 +9,10 @@ import {
TransformNode, TransformNode,
Vector3 Vector3
} from "@babylonjs/core"; } from "@babylonjs/core";
import {AppConfig} from "../../util/appConfig";
import {buildStandardMaterial} from "../../materials/functions/buildStandardMaterial"; import {buildStandardMaterial} from "../../materials/functions/buildStandardMaterial";
export function buildRig(scene: Scene, appConfig: AppConfig): Mesh { export function buildRig(scene: Scene): Mesh {
const rigMesh = MeshBuilder.CreateCylinder("platform", {diameter: .5, height: 1.6}, scene); const rigMesh = MeshBuilder.CreateCylinder("platform", {diameter: .5, height: 1.6}, scene);
const cameratransform = new TransformNode("cameraTransform", scene); const cameratransform = new TransformNode("cameraTransform", scene);
@ -57,14 +57,6 @@ export function buildRig(scene: Scene, appConfig: AppConfig): Mesh {
rightFoot.position.z= 2; rightFoot.position.z= 2;
*/ */
rigAggregate.body.setMotionType(PhysicsMotionType.DYNAMIC); rigAggregate.body.setMotionType(PhysicsMotionType.DYNAMIC);
if (appConfig.current.flyMode) {
rigAggregate.body.setGravityFactor(.02);
} else {
rigAggregate.body.setGravityFactor(1);
}
return rigMesh; return rigMesh;
} }

View File

@ -10,19 +10,14 @@ import {
import {Base} from "./base"; import {Base} from "./base";
import {ControllerEventType, Controllers} from "./controllers"; import {ControllerEventType, Controllers} from "./controllers";
import log from "loglevel"; import log from "loglevel";
import {ConfigMenu} from "../menus/configMenu";
import {DiagramManager} from "../diagram/diagramManager"; import {DiagramManager} from "../diagram/diagramManager";
import {RoundButton} from "../objects/roundButton"; import {RoundButton} from "../objects/roundButton";
export class Left extends Base { export class Left extends Base {
public configMenu: ConfigMenu;
constructor(controller: constructor(controller:
WebXRInputSource, scene: Scene, xr: WebXRDefaultExperience, diagramManager: DiagramManager, controllers: Controllers) { WebXRInputSource, scene: Scene, xr: WebXRDefaultExperience, diagramManager: DiagramManager, controllers: Controllers) {
super(controller, scene, xr, controllers, diagramManager); super(controller, scene, xr, controllers, diagramManager);
this.configMenu = new ConfigMenu(this.scene, xr, this.controllers, this.diagramManager.config);
this.controller.onMotionControllerInitObservable.add((init) => { this.controller.onMotionControllerInitObservable.add((init) => {
if (init.components['xr-standard-thumbstick']) { if (init.components['xr-standard-thumbstick']) {
init.components['xr-standard-thumbstick'] init.components['xr-standard-thumbstick']
@ -41,7 +36,6 @@ export class Left extends Base {
transform.scaling = new Vector3(.2, .2, .2); transform.scaling = new Vector3(.2, .2, .2);
const xbutton = new RoundButton(transform, 'X', 'toggle toolbox menu', new Vector2(-.5, -.1)); const xbutton = new RoundButton(transform, 'X', 'toggle toolbox menu', new Vector2(-.5, -.1));
const ybutton = new RoundButton(transform, 'Y', 'toggle settings menu', new Vector2(-.4, .1)); const ybutton = new RoundButton(transform, 'Y', 'toggle settings menu', new Vector2(-.4, .1));
} }
this.initXButton(init.components['x-button']); this.initXButton(init.components['x-button']);
this.initYButton(init.components['y-button']); this.initYButton(init.components['y-button']);

View File

@ -20,15 +20,8 @@ export class Rigplatform {
private leftController: Left; private leftController: Left;
private readonly xr: WebXRDefaultExperience; private readonly xr: WebXRDefaultExperience;
private yRotation: number = 0; private yRotation: number = 0;
public turnSnap: number = 0;
public rigMesh: Mesh; public rigMesh: Mesh;
public flyMode: boolean = true;
private turning: boolean = false;
private velocity: Vector3 = Vector3.Zero();
private turnVelocity: number = 0;
private logger = log.getLogger('Rigplatform');
private readonly diagramManager: DiagramManager;
private readonly controllers: Controllers;
private registered = false;
constructor(scene: Scene, xr: WebXRDefaultExperience, constructor(scene: Scene, xr: WebXRDefaultExperience,
diagramManager: DiagramManager, diagramManager: DiagramManager,
@ -38,13 +31,33 @@ export class Rigplatform {
this.diagramManager = diagramManager; this.diagramManager = diagramManager;
this.controllers = controllers; this.controllers = controllers;
this.xr = xr; this.xr = xr;
this.bMenu = new EditMenu(scene, xr, this.diagramManager, controllers); this.rigMesh = buildRig(scene);
this.rigMesh = buildRig(scene, this.diagramManager.config);
this.fixRotation(); this.fixRotation();
this.initializeControllers(); this.initializeControllers();
this.registerVelocityObserver(); this.registerVelocityObserver();
} }
private turning: boolean = false;
private velocity: Vector3 = Vector3.Zero();
private turnVelocity: number = 0;
private logger = log.getLogger('Rigplatform');
private readonly diagramManager: DiagramManager;
private readonly controllers: Controllers;
private registered = false;
private _flyMode: boolean = true;
public set flyMode(value: boolean) {
this._flyMode = value;
if (this._flyMode) {
this.rigMesh.physicsBody.setGravityFactor(.01);
console.log('flymode');
} else {
this.rigMesh.physicsBody.setGravityFactor(1);
console.log('walkmode');
}
}
public forwardback(val: number) { public forwardback(val: number) {
this.velocity.z = (val * this.velocityArray[this.velocityIndex])*-1; this.velocity.z = (val * this.velocityArray[this.velocityIndex])*-1;
} }
@ -54,8 +67,10 @@ export class Rigplatform {
public updown(val: number) { public updown(val: number) {
this.velocity.y = (val * this.velocityArray[this.velocityIndex])*-1; this.velocity.y = (val * this.velocityArray[this.velocityIndex])*-1;
} }
public turn(val: number) { public turn(val: number) {
const snap = this.diagramManager.config.current?.turnSnap; const snap = this.turnSnap;
if (snap && snap > 0) { if (snap && snap > 0) {
if (!this.turning) { if (!this.turning) {
if (Math.abs(val) > .1) { if (Math.abs(val) > .1) {
@ -79,7 +94,7 @@ export class Rigplatform {
private registerVelocityObserver() { private registerVelocityObserver() {
this.scene.onBeforeRenderObservable.add(() => { this.scene.onBeforeRenderObservable.add(() => {
const vel = this.velocity.applyRotationQuaternion(this.scene.activeCamera.absoluteRotation); const vel = this.velocity.applyRotationQuaternion(this.scene.activeCamera.absoluteRotation);
if (!this.diagramManager.config.current.flyMode) { if (!this._flyMode) {
vel.y = 0; vel.y = 0;
} }
if (vel.length() > 0) { if (vel.length() > 0) {
@ -118,14 +133,10 @@ export class Rigplatform {
this.leftright(event.value); this.leftright(event.value);
break; break;
case ControllerEventType.UP_DOWN: case ControllerEventType.UP_DOWN:
if (this.diagramManager.config.current.flyMode) { if (this._flyMode) {
this.updown(event.value); this.updown(event.value);
} }
break; break;
case ControllerEventType.MENU:
this.bMenu.toggle();
break;
case ControllerEventType.MOTION: case ControllerEventType.MOTION:
this.logger.debug(JSON.stringify(event)); this.logger.debug(JSON.stringify(event));
@ -160,7 +171,7 @@ export class Rigplatform {
} }
private fixRotation() { private fixRotation() {
this.scene.onAfterPhysicsObservable.add(() => { this.scene.onAfterPhysicsObservable.add(() => {
const turnSnap = this.diagramManager.config.current?.turnSnap; const turnSnap = this.turnSnap;
if (turnSnap && turnSnap > 0) { if (turnSnap && turnSnap > 0) {
const q = this.rigMesh.rotationQuaternion; const q = this.rigMesh.rotationQuaternion;
this.rigMesh.physicsBody.setAngularVelocity(Vector3.Zero()); this.rigMesh.physicsBody.setAngularVelocity(Vector3.Zero());

View File

@ -8,8 +8,6 @@ import {setMenuPosition} from "../util/functions/setMenuPosition";
export class ConfigMenu extends AbstractMenu { export class ConfigMenu extends AbstractMenu {
private sounds: DiaSounds; private sounds: DiaSounds;
private yObserver;
private config: AppConfig; private config: AppConfig;
private gridSnaps: Array<{ label: string, value: number }> = [ private gridSnaps: Array<{ label: string, value: number }> = [
{label: "Off", value: 0}, {label: "Off", value: 0},
@ -31,18 +29,17 @@ export class ConfigMenu extends AbstractMenu {
super(scene, xr, controllers); super(scene, xr, controllers);
this.config = config; this.config = config;
this.sounds = new DiaSounds(scene); this.sounds = new DiaSounds(scene);
if (!this.yObserver) {
this.controllers.controllerObserver.add((event) => { this.controllers.controllerObserver.add((event) => {
if (event.type == ControllerEventType.Y_BUTTON) { if (event.type == ControllerEventType.Y_BUTTON) {
this.toggle(); this.toggle();
} }
}); });
}
} }
public toggle() { public toggle() {
if (this.handle) { if (this.handle) {
this.handle.mesh.dispose(false, true); this.handle.mesh.dispose(false, true);

View File

@ -1,21 +1,21 @@
import {Color3, MeshBuilder, Observable, PBRMaterial, Scene, TransformNode, Vector3} from "@babylonjs/core"; import {Color3, MeshBuilder, Observable, Scene, StandardMaterial, TransformNode, Vector3} from "@babylonjs/core";
import {enumKeys} from "../../util/functions/enumKeys"; import {enumKeys} from "../../util/functions/enumKeys";
import {ToolType} from "../types/toolType"; import {ToolType} from "../types/toolType";
import {buildTool} from "./buildTool"; import {buildTool} from "./buildTool";
import {AdvancedDynamicTexture, ColorPicker} from "@babylonjs/gui"; import {AdvancedDynamicTexture, ColorPicker} from "@babylonjs/gui";
import {MarbleProceduralTexture} from "@babylonjs/procedural-textures";
export function buildColor(color: Color3, scene: Scene, parent: TransformNode, index: number, export function buildColor(color: Color3, scene: Scene, parent: TransformNode, index: number,
colorChangeObservable: Observable<{ oldColor: string, newColor: string }>) { colorChangeObservable: Observable<{ oldColor: string, newColor: string }>) {
const width = 1; const width = 1;
const depth = .2; const depth = .2;
const material = new PBRMaterial("material-" + color.toHexString(), scene); //const material = new PBRMaterial("material-" + color.toHexString(), scene);
const material = new StandardMaterial("material-" + color.toHexString(), scene);
material.diffuseColor = color;
//const material = new StandardMaterial("material-" + color.toHexString(), scene); //const material = new StandardMaterial("material-" + color.toHexString(), scene);
material.albedoColor = color; //material.albedoColor = color;
material.metallic = 1; //material.metallic = 1;
material.bumpTexture = new MarbleProceduralTexture("marble", 1024, scene); //material.bumpTexture = new MarbleProceduralTexture("marble", 1024, scene);
material.bumpTexture.level = 5; //material.bumpTexture.level = 5;
const mesh = MeshBuilder.CreateBox("toolbox-color-" + color.toHexString(), { const mesh = MeshBuilder.CreateBox("toolbox-color-" + color.toHexString(), {
width: width, width: width,
height: .01, height: .01,
@ -48,9 +48,9 @@ export function buildColor(color: Color3, scene: Scene, parent: TransformNode, i
colorPicker.scaleX = 5; colorPicker.scaleX = 5;
colorPicker.value = color; colorPicker.value = color;
colorPicker.onValueChangedObservable.add((value) => { colorPicker.onValueChangedObservable.add((value) => {
const oldColor = material.albedoColor.clone(); const oldColor = material.diffuseColor.clone();
const newColor = value.clone(); const newColor = value.clone();
material.albedoColor = newColor; material.diffuseColor = newColor;
const newColorHex = newColor.toHexString(); const newColorHex = newColor.toHexString();
material.id = "material-" + newColorHex; material.id = "material-" + newColorHex;
material.name = "material-" + newColorHex; material.name = "material-" + newColorHex;

View File

@ -1,6 +1,9 @@
import {WebXRDefaultExperience, WebXRState} from "@babylonjs/core"; import {WebXRDefaultExperience, WebXRState} from "@babylonjs/core";
import log from "loglevel"; import log from "loglevel";
import {WebController} from "../../controllers/webController"; import {WebController} from "../../controllers/webController";
import {EditMenu} from "../../menus/editMenu";
import {ControllerEventType} from "../../controllers/controllers";
import {ConfigMenu} from "../../menus/configMenu";
export async function groundMeshObserver(ground, scene, diagramManager, controllers, spinner) { export async function groundMeshObserver(ground, scene, diagramManager, controllers, spinner) {
const xr = await WebXRDefaultExperience.CreateAsync(scene, { const xr = await WebXRDefaultExperience.CreateAsync(scene, {
@ -41,6 +44,22 @@ export async function groundMeshObserver(ground, scene, diagramManager, controll
}); });
import('../../controllers/rigplatform').then((rigmodule) => { import('../../controllers/rigplatform').then((rigmodule) => {
const rig = new rigmodule.Rigplatform(scene, xr, diagramManager, controllers); const rig = new rigmodule.Rigplatform(scene, xr, diagramManager, controllers);
const currentConfig = diagramManager.config.current;
rig.flyMode = currentConfig.flyMode;
rig.turnSnap = currentConfig.turnSnap;
diagramManager.config.onConfigChangedObservable.add((config) => {
rig.flyMode = config.flyMode;
rig.turnSnap = config.turnSnap;
});
const menu = new EditMenu(scene, xr, diagramManager, controllers);
controllers.controllerObserver.add((event) => {
if (event.type == ControllerEventType.MENU) {
menu.toggle();
}
});
const config = new ConfigMenu(scene, xr, controllers, diagramManager.config);
const webController = new WebController(scene, rig, diagramManager, controllers); const webController = new WebController(scene, rig, diagramManager, controllers);
}); });
} }