Updated Logging, added change color to update db.

This commit is contained in:
Michael Mainguy 2023-07-27 06:32:34 -05:00
parent d55b82833d
commit af2227b746
15 changed files with 166 additions and 187 deletions

View File

@ -3,12 +3,11 @@ import "@babylonjs/inspector";
import {
ArcRotateCamera,
DualShockButton,
DualShockPad,
Engine,
HavokPlugin,
HemisphericLight,
MeshBuilder, OculusTouchController,
MeshBuilder,
PBRMetallicRoughnessMaterial,
PhotoDome,
PhysicsAggregate,
@ -25,6 +24,7 @@ import {Rigplatform} from "./controllers/rigplatform";
import {DiagramManager} from "./diagram/diagramManager";
import {Toolbox} from "./toolbox/toolbox";
import {DualshockEventMapper} from "./util/DualshockEventMapper";
import log from "loglevel";
export class App {
@ -36,13 +36,15 @@ export class App {
public static gamepad: Gamepad;
constructor() {
log.setLevel('debug');
const canvas = document.createElement("canvas");
canvas.style.width = "100%";
canvas.style.height = "100%";
canvas.id = "gameCanvas";
document.body.appendChild(canvas);
log.debug('App', 'gameCanvas created');
this.initialize(canvas).then(() => {
console.log('Scene Initialized');
log.debug('App', 'Scene Initialized');
});
}
@ -99,7 +101,7 @@ export class App {
App.xr.baseExperience.camera.position = new Vector3(0, 1.6, 0);
window.addEventListener(('pa-button-state-change'), (event: any) => {
if (event.detail) {
console.log(event.detail);
log.debug('App', event.detail);
}
});
@ -111,6 +113,7 @@ export class App {
const toolbox = new Toolbox(scene, App.xr.baseExperience);
App.scene.gamepadManager.onGamepadConnectedObservable.add((gamepad) => {
try {
const dualshock = (gamepad as DualShockPad);
dualshock.onButtonDownObservable.add((button: any) => {
@ -168,9 +171,12 @@ export class App {
}
}));
});
} catch (err) {
log.warn('App', err);
}
});
//camera.parent = App.rig.rigMesh;
window.addEventListener("keydown", (ev) => {
// Shift+Ctrl+Alt+I
if (ev.shiftKey && ev.ctrlKey && ev.altKey && ev.keyCode === 73) {
@ -181,11 +187,13 @@ export class App {
}
}
});
log.info('App', 'keydown event listener added, use Ctrl+Shift+Alt+I to toggle debug layer');
engine.runRenderLoop(() => {
scene.render();
});
log.info('App', 'Render loop started');
}
createGround() {
@ -204,7 +212,7 @@ export class App {
return ground;
}
}
const app = new App();

View File

@ -11,7 +11,8 @@ import {
import {MeshConverter} from "../diagram/meshConverter";
import {DiagramManager} from "../diagram/diagramManager";
import {DiagramEvent, DiagramEventType} from "../diagram/diagramEntity";
import log from 'loglevel';
import log from "loglevel";
export class Base {
static stickVector = Vector3.Zero();
@ -95,11 +96,11 @@ export class Base {
mesh = this.xr.pointerSelection.getMeshUnderPointer(this.controller.uniqueId);
}
if (!this.grabbedMesh) {
console.log("no grabbed mesh");
log.debug("controllers", "no grabbed mesh");
return;
}
if (mesh?.id != this?.grabbedMesh?.id) {
console.log("not the same mesh");
log.debug("controllers", "not the same mesh");
}
mesh = this.grabbedMesh;
if (!mesh?.metadata?.template) {

View File

@ -1,4 +1,3 @@
import {AbstractMesh, Observable, TransformNode} from "@babylonjs/core";
export enum ControllerMovementMode {

View File

@ -1,6 +1,7 @@
import {Scene, Vector3, WebXRDefaultExperience, WebXRInputSource} from "@babylonjs/core";
import {Base} from "./base";
import {Controllers} from "./controllers";
import log from "loglevel";
export class Left extends Base {
@ -16,6 +17,7 @@ export class Left extends Base {
if (init.components['xr-standard-thumbstick']) {
init.components['xr-standard-thumbstick']
.onAxisValueChangedObservable.add((value) => {
log.trace('Left', `thumbstick moved ${value.x}, ${value.y}`);
if (!Controllers.movable) {
this.moveRig(value);
} else {
@ -24,6 +26,7 @@ export class Left extends Base {
});
init.components['xr-standard-thumbstick'].onButtonStateChangedObservable.add((value) => {
if (value.pressed) {
log.trace('Left', 'thumbstick changed');
Controllers.controllerObserver.notifyObservers({type: 'decreaseVelocity', value: value.value});
}
});

View File

@ -8,6 +8,7 @@ import {
WebXRInputSource
} from "@babylonjs/core";
import {ControllerMovementMode, Controllers} from "./controllers";
import log from "loglevel";
export class Right extends Base {
public static instance: Right;
@ -60,6 +61,7 @@ export class Right extends Base {
private initThumbstick(thumbstick: WebXRControllerComponent) {
if (thumbstick) {
thumbstick.onAxisValueChangedObservable.add((value) => {
log.trace('Right', `thumbstick moved ${value.x}, ${value.y}`);
if (!Controllers.movable) {
this.moveRig(value);
} else {
@ -72,6 +74,7 @@ export class Right extends Base {
});
thumbstick.onButtonStateChangedObservable.add((value) => {
if (value.pressed) {
log.trace('Right', `thumbstick changed ${value.value}`);
Controllers.controllerObserver.notifyObservers({type: 'increaseVelocity', value: value.value});
}
});

View File

@ -18,6 +18,8 @@ import {Right} from "./right";
import {Left} from "./left";
import {Bmenu} from "../menus/bmenu";
import {Controllers} from "./controllers";
import log from "loglevel";
export class Rigplatform {
@ -39,30 +41,15 @@ export class Rigplatform {
this.scene = scene;
Rigplatform.xr = xr;
Rigplatform.instance = this;
this.bMenu = new Bmenu(scene, xr.baseExperience);
this.camera = scene.activeCamera;
this.rigMesh = MeshBuilder.CreateBox("platform", {width: 2, height: .02, depth: 2}, scene);
//new Hud(this.rigMesh, scene);
const transform = new TransformNode("transform", scene);
transform.parent=this.rigMesh;
transform.position = new Vector3(0, 1.6, -5);
const pointer = MeshBuilder.CreateSphere("pointer", {diameter: .1}, scene);
pointer.parent = transform;
pointer.position = this.velocity;
for (const cam of scene.cameras) {
cam.parent = this.rigMesh;
//cam.position = new Vector3(0, 1.6, 0);
}
const myMaterial = new StandardMaterial("myMaterial", scene);
myMaterial.diffuseColor = Color3.Blue();
this.rigMesh.material = myMaterial;
const rigMaterial = new StandardMaterial("rigMaterial", scene);
rigMaterial.diffuseColor = Color3.Blue();
this.rigMesh.material = rigMaterial;
this.rigMesh.setAbsolutePosition(new Vector3(0, .1, -3));
this.rigMesh.visibility = 1;
const rigAggregate =
@ -73,39 +60,30 @@ export class Rigplatform {
scene);
rigAggregate.body.setMotionType(PhysicsMotionType.DYNAMIC);
rigAggregate.body.setGravityFactor(.001);
this.#fixRotation();
this.fixRotation();
this.body = rigAggregate.body;
this.#setupKeyboard();
this.#initializeControllers();
this.initializeControllers();
scene.onActiveCameraChanged.add((s) => {
this.camera = s.activeCamera;
this.camera.parent = this.rigMesh;
});
this.registerVelocityObserver();
}
public forwardback(val: number) {
this.velocity.z = (val * this.velocityArray[this.velocityIndex])*-1;
private registerVelocityObserver() {
this.scene.onBeforeRenderObservable.add(() => {
const vel = this.velocity.applyRotationQuaternion(this.camera.absoluteRotation);
this.body.setLinearVelocity(vel);
});
}
public forwardback(val: number) {
this.velocity.z = (val * this.velocityArray[this.velocityIndex])*-1;
}
public leftright(val: number) {
this.velocity.x = (val * this.velocityArray[this.velocityIndex]);
const vel = this.velocity.applyRotationQuaternion(this.camera.absoluteRotation);
this.body.setLinearVelocity(vel);
}
public stop() {
}
public updown(val: number) {
this.velocity.y = (val * this.velocityArray[this.velocityIndex])*-1;
const vel = this.velocity.applyRotationQuaternion(this.camera.absoluteRotation);
this.body.setLinearVelocity(vel);
}
public turn(val: number) {
const snap = true;
if (snap) {
@ -114,11 +92,9 @@ export class Rigplatform {
this.turning = true;
this.yRotation += Angle.FromDegrees(Math.sign(val) * 22.5).radians();
}
} else {
if (Math.abs(val) < .1) {
this.turning = false;
}
}
} else {
@ -130,7 +106,7 @@ export class Rigplatform {
}
}
#initializeControllers() {
private initializeControllers() {
Rigplatform.xr.input.onControllerAddedObservable.add((source) => {
let controller;
switch (source.inputSource.handedness) {
@ -165,7 +141,7 @@ export class Rigplatform {
this.updown(event.value);
break;
case "stop":
this.stop();
log.warn("Rigplatform", "stop is no longer implemented");
break;
case "menu":
this.bMenu.toggle();
@ -183,20 +159,8 @@ export class Rigplatform {
controller.setRig(this);
}
});
}
//create a method to set the camera to the rig
#setupKeyboard() {
///simplify this with a map
}
#fixRotation() {
private fixRotation() {
this.scene.registerBeforeRender(() => {
const q = this.rigMesh.rotationQuaternion;
this.body.setAngularVelocity(Vector3.Zero());
@ -205,8 +169,6 @@ export class Rigplatform {
e.y += this.yRotation;
q.copyFrom(Quaternion.FromEulerAngles(0, e.y, 0));
}
});
}
}

View File

@ -1,4 +1,4 @@
import {Vector3} from "@babylonjs/core";
import {Color3, Vector3} from "@babylonjs/core";
import {BmenuState} from "../menus/MenuState";
export enum DiagramEventType {
ADD,
@ -7,6 +7,7 @@ export enum DiagramEventType {
DROP,
DROPPED,
CLEAR,
CHANGECOLOR
}
@ -14,6 +15,8 @@ export type DiagramEvent = {
type: DiagramEventType;
menustate?: BmenuState;
entity?: DiagramEntity;
oldColor?: Color3;
newColor?: Color3;
}
export type DiagramEntity = {

View File

@ -1,15 +1,10 @@
import {
AbstractMesh,
InputBlock, Material, NodeMaterial,
Observable,
Scene,
WebXRExperienceHelper
} from "@babylonjs/core";
import {AbstractMesh, Color3, Material, Observable, Scene, WebXRExperienceHelper} from "@babylonjs/core";
import {DiagramEntity, DiagramEvent, DiagramEventType} from "./diagramEntity";
import {IPersistenceManager} from "./persistenceManager";
import {IndexdbPersistenceManager} from "./indexdbPersistenceManager";
import {MeshConverter} from "./meshConverter";
import log from "loglevel";
export class DiagramManager {
@ -21,35 +16,38 @@ export class DiagramManager {
static currentMesh: AbstractMesh;
private materialMap: Map<string, Material> = new Map<string, Material>();
constructor(scene: Scene, xr: WebXRExperienceHelper) {
this.scene = scene;
this.xr = xr;
this.persistenceManager.updateObserver.add(this.#onRemoteEvent, -1, true, this);
this.persistenceManager.updateObserver.add(this.onRemoteEvent, -1, true, this);
log.debug('DiagramManager', "remove event observer added");
this.persistenceManager.initialize();
if (!DiagramManager.onDiagramEventObservable) {
log.debug('DiagramManager', "onDiagramEventObservable missing, recreated");
DiagramManager.onDiagramEventObservable = new Observable();
}
if (DiagramManager.onDiagramEventObservable.hasObservers()) {
log.warn('DiagramManager', "onDiagramEventObservable already has Observers, this shouldn't happen");
} else {
DiagramManager.onDiagramEventObservable.add(this.#onDiagramEvent, -1, true, this);
DiagramManager.onDiagramEventObservable.add(this.onDiagramEvent, -1, true, this);
log.debug('DiagramManager', "onDiagramEventObservable Observer added");
}
log.debug('DiagramManager', "DiagramManager constructed");
}
#onRemoteEvent(event: DiagramEntity) {
private onRemoteEvent(event: DiagramEntity) {
//const mesh = Toolbox.instance.newMesh(ToolType[Object.entries(ToolType).find(e => e[1] == event.template)[0]], event.id);
log.debug('DiagramManager', event);
const mesh = MeshConverter.fromDiagramEntity(event, this.scene);
if (event.parent) {
mesh.parent = this.scene.getMeshById(event.parent);
}
}
private buildNodeMaterial() {
const nodeMaterial = new NodeMaterial("nodeMaterial", this.scene, { emitComments: true });
const positionInput = new InputBlock("position");
positionInput.setAsAttribute("position");
}
#onDiagramEvent(event: DiagramEvent) {
private onDiagramEvent(event: DiagramEvent) {
const entity = event.entity;
let mesh;
if (entity) {
@ -68,6 +66,9 @@ export class DiagramManager {
case DiagramEventType.MODIFY:
this.persistenceManager.modify(mesh);
break;
case DiagramEventType.CHANGECOLOR:
this.persistenceManager.changeColor(event.oldColor, event.newColor);
break;
case DiagramEventType.REMOVE:
if (mesh) {
this.persistenceManager.remove(mesh);

View File

@ -3,6 +3,7 @@ import {AbstractMesh, Observable, Vector3} from "@babylonjs/core";
import {DiagramEntity} from "./diagramEntity";
import Dexie from "dexie";
import {MeshConverter} from "./meshConverter";
import log from "loglevel";
export class IndexdbPersistenceManager implements IPersistenceManager {
public updateObserver: Observable<DiagramEntity> = new Observable<DiagramEntity>();
@ -10,10 +11,11 @@ export class IndexdbPersistenceManager implements IPersistenceManager {
constructor(name: string) {
this.db = new Dexie(name);
this.db.version(1).stores({entities: "id,position,rotation,last_seen,template,text,scale,color"});
log.debug('IndexdbPersistenceManager', "IndexdbPersistenceManager constructed");
}
public add(mesh: AbstractMesh) {
if (!mesh) {
console.log("Adding null mesh");
log.warn('IndexdbPersistenceManager', "Adding null mesh");
return;
}
const entity = <any>MeshConverter.toDiagramEntity(mesh);
@ -45,22 +47,13 @@ export class IndexdbPersistenceManager implements IPersistenceManager {
e.position = this.xyztovec(e.position);
e.rotation = this.xyztovec(e.rotation);
e.scale = this.xyztovec(e.scale);
console.log(e);
log.debug('IndexdbPersistenceManager', 'adding', e);
this.updateObserver.notifyObservers(e);
});
log.warn('IndexdbPersistenceManager', "initialize finished");
}
private dummyEntity(): DiagramEntity {
const entity: DiagramEntity = <DiagramEntity>{};
entity.id = "test";
entity.position = new Vector3(0,2,-5);
entity.rotation = Vector3.Zero();
entity.last_seen = new Date();
entity.scale = new Vector3(.1,.1,.1);
entity.color = "#ff0000";
entity.text = "test";
entity.parent = null;
entity.template = "#text-template";
return entity;
public changeColor(oldColor, newColor) {
log.debug('IndexdbPersistenceManager', `changeColor ${oldColor.toHexString()} to ${newColor.toHexString()}`);
this.db['entities'].where('color').equals(oldColor.toHexString()).modify({color: newColor.toHexString()});
}
}

View File

@ -2,6 +2,7 @@ import {DiagramEntity} from "./diagramEntity";
import {AbstractMesh, Color3, InstancedMesh, Mesh, Scene, StandardMaterial} from "@babylonjs/core";
import {v4 as uuidv4} from 'uuid';
import {Toolbox} from "../toolbox/toolbox";
import log from "loglevel";
export class MeshConverter {
@ -29,21 +30,21 @@ export class MeshConverter {
}
let mesh = scene.getMeshById(entity.id);
if (mesh) {
console.log('mesh already exists');
log.debug('mesh already exists');
} else {
mesh = scene.getMeshById("tool-" + entity.template + "-" + entity.color);
if (mesh) {
if (mesh.isAnInstance) {
console.log('error: mesh is an instance');
log.debug('error: mesh is an instance');
} else {
mesh = new InstancedMesh(entity.id, (mesh as Mesh));
}
} else {
console.log('no mesh found for ' + entity.template + "-" + entity.color);
log.debug('no mesh found for ' + entity.template + "-" + entity.color);
Toolbox.instance.updateToolbox(entity.color);
mesh = scene.getMeshById("tool-" + entity.template + "-" + entity.color);
if (!mesh) {
console.log('no mesh found for ' + entity.template + "-" + entity.color);
log.debug('no mesh found for ' + entity.template + "-" + entity.color);
} else {
mesh = new InstancedMesh(entity.id, (mesh as Mesh));
}

View File

@ -1,4 +1,4 @@
import {AbstractMesh, Observable} from "@babylonjs/core";
import {AbstractMesh, Color3, Observable} from "@babylonjs/core";
import {DiagramEntity} from "./diagramEntity";
export interface IPersistenceManager {
@ -6,6 +6,7 @@ export interface IPersistenceManager {
remove(mesh: AbstractMesh);
modify(mesh: AbstractMesh);
initialize();
changeColor(oldColor: Color3, newColor: Color3)
updateObserver: Observable<DiagramEntity>;
}

View File

@ -20,6 +20,7 @@ import {DiagramManager} from "../diagram/diagramManager";
import {BmenuState} from "./MenuState";
import {DiagramEvent, DiagramEventType} from "../diagram/diagramEntity";
import {MeshConverter} from "../diagram/meshConverter";
import log from "loglevel";
export class Bmenu {
private state: BmenuState = BmenuState.NONE;
@ -48,7 +49,7 @@ export class Bmenu {
pointerInfo.pickInfo?.pickedMesh?.parent?.parent?.id != "toolbox") {
switch (this.state) {
case BmenuState.REMOVING:
console.log("removing " + pointerInfo.pickInfo.pickedMesh.id);
log.debug("removing " + pointerInfo.pickInfo.pickedMesh.id);
const event: DiagramEvent = {
type: DiagramEventType.REMOVE,
entity:
@ -71,7 +72,7 @@ export class Bmenu {
entity: MeshConverter.toDiagramEntity(mesh),
}
)
console.log(mesh.scaling);
log.debug(mesh.scaling);
});
}
@ -80,7 +81,7 @@ export class Bmenu {
break;
case BmenuState.LABELING:
const mesh = pointerInfo.pickInfo.pickedMesh;
console.log("labeling " + mesh.id);
log.debug("labeling " + mesh.id);
/* const myPlane = MeshBuilder.CreatePlane("myPlane", {width: 1, height: .125}, this.scene);
//myPlane.parent=mesh;
const pos = mesh.absolutePosition;
@ -106,10 +107,10 @@ export class Bmenu {
textInput.value = "";
textInput.focus();
textInput.addEventListener('input', (event)=> {
console.log(event);
log.debug(event);
});
textInput.addEventListener('keydown', (event)=> {
console.log(event);
log.debug(event);
if (event.key == "Enter") {
textInput.blur();
textInput.remove();
@ -178,7 +179,7 @@ export class Bmenu {
this.state = BmenuState.LABELING;
break;
default:
console.log("Unknown button");
log.error("Unknown button");
return;
}
this.manager.dispose();

View File

@ -10,6 +10,8 @@ import {
import {CameraHelper} from "../util/cameraHelper";
import {AdvancedDynamicTexture, Button3D, ColorPicker, GUI3DManager, StackPanel3D, TextBlock} from "@babylonjs/gui";
import {DiagramManager} from "../diagram/diagramManager";
import {DiagramEventType} from "../diagram/diagramEntity";
export enum ToolType {
BOX ="#box-template",
@ -117,14 +119,19 @@ export class Toolbox {
colorPicker.scaleX = 5;
colorPicker.value = color;
colorPicker.onValueChangedObservable.add((value) => {
const oldColor = material.diffuseColor.clone();
material.diffuseColor = value;
material.id = "material-" + value.toHexString();
material.name = "material-" + value.toHexString();
mesh.id = "toolbox-color-" + value.toHexString();
mesh.name = "toolbox-color-" + value.toHexString();
console.log(mesh.getChildren( (node) => {
return (node?.parent?.id!="toolbox") &&
(node?.parent?.parent?.id != "toolbox")}));
DiagramManager.onDiagramEventObservable.notifyObservers(
{
type: DiagramEventType.CHANGECOLOR,
oldColor: oldColor,
newColor: value
}
);
});
advancedTexture2.addControl(colorPicker);

View File

@ -1,4 +1,5 @@
import {DualShockButton} from "@babylonjs/core";
import log from "loglevel";
type ButtonEvent = {
objectName?: string,
pressed: boolean,
@ -17,69 +18,69 @@ export class DualshockEventMapper {
};
switch (buttonid) {
case DualShockButton.Circle:
console.log('circle');
log.debug('DualshockEventMapper','circle');
break;
case DualShockButton.Cross:
console.log('cross');
log.debug('DualshockEventMapper','cross');
buttonEvent.objectName = "right-controller";
buttonEvent.buttonIndex = 3;
break;
case DualShockButton.Triangle:
console.log('triangle');
log.debug('DualshockEventMapper','triangle');
break;
case DualShockButton.Square:
console.log('square');
log.debug('DualshockEventMapper','square');
buttonEvent.objectName = "right-controller";
buttonEvent.buttonIndex = 4;
break;
case DualShockButton.L1:
console.log('L1');
log.debug('DualshockEventMapper','L1');
buttonEvent.objectName = "left-controller";
buttonEvent.buttonIndex = 2;
break;
case DualShockButton.R1:
console.log('R1');
log.debug('DualshockEventMapper','R1');
buttonEvent.objectName = "right-controller";
buttonEvent.buttonIndex = 2;
break;
case 6:
console.log('L2');
log.debug('DualshockEventMapper','L2');
buttonEvent.objectName = "left-controller";
buttonEvent.buttonIndex = 1;
break;
case 7:
console.log('R2');
log.debug('DualshockEventMapper','R2');
buttonEvent.objectName = "right-controller";
buttonEvent.buttonIndex = 1;
break;
case 12:
console.log('D-Pad Up');
log.debug('DualshockEventMapper','D-Pad Up');
break;
case 13:
console.log('D-Pad Down');
log.debug('DualshockEventMapper','D-Pad Down');
buttonEvent.objectName = "left-controller";
buttonEvent.buttonIndex = 3;
break;
case 14:
console.log('D-Pad Left');
log.debug('DualshockEventMapper','D-Pad Left');
buttonEvent.objectName = "left-controller";
buttonEvent.buttonIndex = 4;
break;
case 15:
console.log('D-Pad Right');
log.debug('DualshockEventMapper','D-Pad Right');
break;
case 10:
console.log('L3');
log.debug('DualshockEventMapper','L3');
buttonEvent.objectName = "left-controller";
buttonEvent.buttonIndex = 0;
break;
case 11:
console.log('R3');
log.debug('DualshockEventMapper','R3');
buttonEvent.objectName = "right-controller";
buttonEvent.buttonIndex = 0;
break;
default:
console.log(buttonid);
log.debug('DualshockEventMapper',buttonid);
}
return buttonEvent;

View File

@ -1,5 +0,0 @@
export class Logger {
static debug(value) {
console.log(value)
}
}