Updated OPTIONS method for user function

This commit is contained in:
Michael Mainguy 2023-10-31 12:49:36 -05:00
parent bb93e502c9
commit d7d8b414e5
12 changed files with 221 additions and 36 deletions

12
package-lock.json generated
View File

@ -19,11 +19,13 @@
"@cloudflare/workers-types": "^4.20230821.0",
"@netlify/functions": "^1.6.0",
"@typed-mxgraph/typed-mxgraph": "^1.0.8",
"@types/file-saver": "^2.0.6",
"@types/node": "^18.14.0",
"dexie": "^3.2.4",
"dexie-observable": "^4.0.1-beta.13",
"earcut": "^2.2.4",
"events": "^3.3.0",
"file-saver": "^2.0.5",
"hls.js": "^1.1.4",
"loglevel": "^1.8.1",
"mxgraph": "^4.2.2",
@ -974,6 +976,11 @@
"resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.39.6.tgz",
"integrity": "sha512-H90aoynNhhkQP6DRweEjJp5vfUVdIj7tdPLsu7pq89vODD/lcugKfZOsfgwpvM6XUewEp2N5dCg1Uf3Qe55Dcg=="
},
"node_modules/@types/file-saver": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.6.tgz",
"integrity": "sha512-Mw671DVqoMHbjw0w4v2iiOro01dlT/WhWp5uwecBa0Wg8c+bcZOjgF1ndBnlaxhtvFCgTRBtsGivSVhrK/vnag=="
},
"node_modules/@types/http-cache-semantics": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz",
@ -2117,6 +2124,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/file-saver": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
"integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
},
"node_modules/fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",

View File

@ -31,6 +31,8 @@
"dexie": "^3.2.4",
"dexie-observable": "^4.0.1-beta.13",
"earcut": "^2.2.4",
"file-saver": "^2.0.5",
"@types/file-saver": "^2.0.6",
"hls.js": "^1.1.4",
"loglevel": "^1.8.1",
"mxgraph": "^4.2.2",

View File

@ -23,6 +23,7 @@ import {DiagramExporter} from "./util/diagramExporter";
import {Spinner} from "./util/spinner";
import {WebController} from "./controllers/webController";
import {PouchdbPersistenceManager} from "./integration/pouchdbPersistenceManager";
import {addSceneInspector} from "./util/functions/sceneInspctor";
export class App {
@ -78,6 +79,7 @@ export class App {
const diagramManager = new DiagramManager(scene, controllers, toolbox, config);
const db = new PouchdbPersistenceManager("diagram");
//diagramManager.setPersistenceManager(db);
db.configObserver.add((newConfig) => {
config.onConfigChangedObservable.notifyObservers(newConfig, 1);
@ -253,31 +255,13 @@ export class App {
});
*/
window.addEventListener("keydown", (ev) => {
if (ev.key == "z") {
//voiceManager.startRecording();
}
if (ev.key == "x") {
//voiceManager.stopRecording();
}
if (ev.shiftKey && ev.ctrlKey && ev.altKey && ev.keyCode === 73) {
import("@babylonjs/core/Debug/debugLayer").then(() => {
import("@babylonjs/inspector").then(() => {
if (scene.debugLayer.isVisible()) {
scene.debugLayer.hide();
} else {
scene.debugLayer.show();
}
});
});
}
});
addSceneInspector(scene);
const exportLink = document.querySelector('#downloadLink');
if (exportLink) {
exportLink.addEventListener('click', (ev) => {
ev.preventDefault();
const exporter = new DiagramExporter(scene);
exporter.export();
exporter.exportgltf();
});
}

View File

@ -1,9 +1,18 @@
import {Scene, Vector3, WebXRControllerComponent, WebXRDefaultExperience, WebXRInputSource} from "@babylonjs/core";
import {
Scene,
TransformNode,
Vector2,
Vector3,
WebXRControllerComponent,
WebXRDefaultExperience,
WebXRInputSource
} from "@babylonjs/core";
import {Base} from "./base";
import {ControllerEventType, Controllers} from "./controllers";
import log from "loglevel";
import {ConfigMenu} from "../menus/configMenu";
import {DiagramManager} from "../diagram/diagramManager";
import {Button} from "../objects/button";
export class Left extends Base {
@ -25,8 +34,22 @@ export class Left extends Base {
this.moveMovable(value);
}
});
if (init.components['x-button']) {
const transform = new TransformNode('x-button', scene);
transform.parent = controller.grip;
transform.rotation.x = Math.PI / 2;
transform.scaling = new Vector3(.2, .2, .2);
const xbutton = new Button(transform, 'X', 'toggle toolbox menu', new Vector2(-.5, -.1));
const ybutton = new Button(transform, 'Y', 'toggle settings menu', new Vector2(-.4, .1));
}
this.initXButton(init.components['x-button']);
this.initYButton(init.components['y-button']);
const buttonhome = new TransformNode('buttons', scene)
//const xbutton = new Button(buttonhome, 'X', 'open edit menu', new Vector2(0,0));
//const ybutton = new Button(buttonhome, 'Y', 'open edit menu', new Vector2(.4,0));
this.initTrigger(init.components['xr-standard-trigger']);
init.components['xr-standard-thumbstick'].onButtonStateChangedObservable.add((value) => {
if (value.pressed) {
@ -58,6 +81,7 @@ export class Left extends Base {
private initXButton(xbutton: WebXRControllerComponent) {
if (xbutton) {
xbutton.onButtonStateChangedObservable.add((button) => {
if (button.pressed) {
this.controllers.controllerObserver.notifyObservers({

View File

@ -1,9 +1,18 @@
import {Base} from "./base";
import {Scene, Vector3, WebXRControllerComponent, WebXRDefaultExperience, WebXRInputSource} from "@babylonjs/core";
import {
Scene,
TransformNode,
Vector2,
Vector3,
WebXRControllerComponent,
WebXRDefaultExperience,
WebXRInputSource
} from "@babylonjs/core";
import {ControllerEventType, Controllers} from "./controllers";
import log from "loglevel";
import {DiagramManager} from "../diagram/diagramManager";
import {DiagramListingMenu} from "../menus/diagramListingMenu";
import {Button} from "../objects/button";
export class Right extends Base {
private listingMenu: DiagramListingMenu;
@ -36,6 +45,15 @@ export class Right extends Base {
this.listingMenu = new DiagramListingMenu(this.scene, xr, this.controllers);
this.controller.onMotionControllerInitObservable.add((init) => {
this.initTrigger(init.components['xr-standard-trigger']);
if (init.components['a-button']) {
const transform = new TransformNode('a-button', scene);
transform.parent = controller.grip;
transform.rotation.x = Math.PI / 2;
transform.scaling = new Vector3(.2, .2, .2);
const abutton = new Button(transform, 'A', 'toggle edit menu', new Vector2(.5, -.1));
const bbutton = new Button(transform, 'B', 'toggle diagram selector', new Vector2(.4, .1));
}
this.initBButton(init.components['b-button']);
this.initAButton(init.components['a-button']);
this.initThumbstick(init.components['xr-standard-thumbstick']);

View File

@ -21,7 +21,6 @@ export class PouchdbPersistenceManager implements IPersistenceManager {
console.log(name);
this.config = new PouchDB("config");
this.diagramListings = new PouchDB("diagramListings");
}
private _currentDiagramId: string;
@ -38,7 +37,6 @@ export class PouchdbPersistenceManager implements IPersistenceManager {
this.diagramListings.put({_id: value, name: "New Diagram"});
}
this.db = new PouchDB(value);
this.db.sync(this.remote, {live: true});
}
@ -108,11 +106,11 @@ export class PouchdbPersistenceManager implements IPersistenceManager {
}
public async getNewRelicData(): Promise<any[]> {
return [];
}
public async setNewRelicData(data: any[]): Promise<any> {
return data;
}
public async setConfig(config: any, initial: boolean = false): Promise<any> {
@ -175,7 +173,6 @@ export class PouchdbPersistenceManager implements IPersistenceManager {
}
}
syncDoc = function (info) {
console.log(info);
if (info.direction == 'pull') {

80
src/menus/cameraMenu.ts Normal file
View File

@ -0,0 +1,80 @@
import {Color3, DynamicTexture, Mesh, MeshBuilder, Scene, StandardMaterial, Vector3} from "@babylonjs/core";
export class CameraMenu {
private scene: Scene;
private xr;
private controllers;
constructor(scene, xr, controllers) {
this.scene = scene;
this.xr = xr;
this.controllers = controllers;
this.buildMenu(1, new Vector3(0, 1, 0));
//this.buildMenu(4, new Vector3(0,2,0));
//this.buildMenu(5, new Vector3(1,2,0));
//this.buildMenu(6, new Vector3(1,1,0));
}
private buildMenu(camnum: number, position: Vector3) {
const camerasphere = MeshBuilder.CreateSphere("camerasphere", {
diameter: 10,
slice: .5,
sideOrientation: Mesh.DOUBLESIDE
}, this.scene);
//const camerasphere = MeshBuilder.CreatePlane("camerasphere", {width: 1.6, height: .6, sideOrientation: Mesh.DOUBLESIDE }, this.scene);
camerasphere.position = position;
const material = new StandardMaterial("cameramaterial", this.scene);
material.emissiveColor = new Color3(1, 1, 1);
//camerasphere.rotation.z = Math.PI;
/*const texture = new VideoTexture("video",
'https://local.immersiveidea.com/',
this.scene);
*/
//const texture = new DynamicTexture("dynamic texture", {width: 512, height: 256}, this.scene, false);
const texture = new DynamicTexture('texture', {width: 1600, height: 1600}, this.scene);
//const img = document.createElement('img');
//document.body.append(img);
//img.width=2592;
//img.height=1944;
material.diffuseTexture = texture;
const img = new Image();
img.src = 'https://cameras.immersiveidea.com/mjpg/video.mjpg?camera=' + camnum + '&timestamp=1698497537140';
const ctx = texture.getContext();
img.onload = () => {
ctx.drawImage(img, 250, 0, 2112, 1940, 0, 0, 1600, 1600);
texture.update();
window.setInterval((texture, img, ctx) => {
//const start = new Date();
ctx.drawImage(img, 250, 0, 2112, 1940, 0, 0, 1600, 1600);
texture.update();
//console.log(new Date() - start);
}, 60, texture, img, ctx);
}
//https://cameras.immersiveidea.com/mjpg/video.mjpg?camera=1&timestamp=1698497537140');
//texture.getContext().drawImage(img, 0,0);
texture.onLoadObservable.add(() => {
console.log('texture loaded');
});
this.scene.onAfterRenderObservable.add(() => {
// texture._rebuild();
}, 1, true, this);
camerasphere.material = material;
/*texture.video.play().then(() => {
console.log('video playing');
}).catch((err) => {
console.log(err);
console.log("here");
});
*/
console.log('video loaded');
//Material.diffuseColor = new Color3(0, 0, 0);
//https://cameras.immersiveidea.com/mjpg/video.mjpg?camera=1&resolution=2592x1944&compression=30&mirror=0&rotation=0&textsize=medium&textposition=top&textbackgroundcolor=black&textcolor=white&text=0&clock=0&date=0&overlayimage=0&fps=0&videokeyframeinterval=13&videobitrate=0&maxframesize=0&timestamp=1698491710423
}
}

View File

@ -27,6 +27,7 @@ import {Controllers} from "../controllers/controllers";
import {setMenuPosition} from "../util/functions/setMenuPosition";
import {DiagramExporter} from "../util/diagramExporter";
import {SoccerMenu} from "../soccer/soccerMenu";
import {CameraMenu} from "./cameraMenu";
export class EditMenu extends AbstractMenu {
private state: EditMenuState = EditMenuState.NONE;
@ -37,6 +38,7 @@ export class EditMenu extends AbstractMenu {
private readonly diagramManager: DiagramManager;
private connection: DiagramConnection = null;
private panel: PlanePanel;
private cameraMenu: CameraMenu = null;
private sounds: DiaSounds;
private get isVisible(): boolean {
@ -237,13 +239,13 @@ export class EditMenu extends AbstractMenu {
panel.columns = 4;
this.manager.addControl(panel);
panel.addControl(this.makeButton("Cameras", "camera"));
panel.addControl(this.makeButton("Modify", "modify"));
panel.addControl(this.makeButton("Remove", "remove"));
panel.addControl(this.makeButton("Add Label", "label"));
panel.addControl(this.makeButton("Copy", "copy"));
panel.addControl(this.makeButton("Connect", "connect"));
panel.addControl(this.makeButton("Export", "export"));
panel.addControl(this.makeButton("Export GLTF", "exportgltf"));
panel.addControl(this.makeButton("Recolor", "recolor"));
panel.addControl(this.makeButton("New Relic", "newrelic"));
panel.addControl(this.makeButton("Soccer", "soccer"));
@ -303,12 +305,16 @@ export class EditMenu extends AbstractMenu {
case "newrelic":
this.showNewRelic();
break;
case "export":
this.download();
case "exportgltf":
this.downloadgltf();
break;
case "soccer":
this.createSoccerField();
break;
case "camera":
if (!this.cameraMenu) {
this.cameraMenu = new CameraMenu(this.scene, null, null);
}
default:
this.logger.error("Unknown button");
return;
@ -324,8 +330,8 @@ export class EditMenu extends AbstractMenu {
}
}
private download() {
private downloadgltf() {
const exporter = new DiagramExporter(this.scene);
exporter.export();
exporter.exportgltf();
}
}

View File

@ -30,6 +30,4 @@ export class IntegrationMenu extends AbstractMenu {
grid.addControl(labelText2, 1, 0);
setMenuPosition(this.plane, this.scene);
}
}

43
src/objects/button.ts Normal file
View File

@ -0,0 +1,43 @@
import {DynamicTexture, MeshBuilder, StandardMaterial, TransformNode, Vector2, Vector3} from "@babylonjs/core";
export class Button {
private parent: TransformNode;
constructor(parent: TransformNode, label: string, description: string, position: Vector2) {
this.parent = parent;
this.buildButton(label, description, position);
}
private buildButton(label: string, description: string, position: Vector2) {
const button = MeshBuilder.CreateSphere(label, {diameter: .1}, this.parent.getScene());
const descriptionPlane = MeshBuilder.CreatePlane(label, {width: .3, height: .1}, this.parent.getScene());
button.parent = this.parent;
button.position.y = position.y;
button.position.x = position.x;
descriptionPlane.parent = this.parent;
descriptionPlane.position.y = position.y - .1;
descriptionPlane.position.x = position.x;
const descTexture = new DynamicTexture('texture_desc_' + label, {
width: 768,
height: 256
}, this.parent.getScene());
const descMaterial = new StandardMaterial('button_desc_' + label)
descriptionPlane.material = descMaterial;
descMaterial.diffuseTexture = descTexture;
descTexture.drawText(description, null, null, 'bold 64px Arial',
'#000000', '#ffffff', true);
const texture = new DynamicTexture('texture_' + label, {width: 256, height: 256}, this.parent.getScene());
const material = new StandardMaterial('button_' + label)
button.material = material;
material.diffuseTexture = texture;
texture.drawText(label, null, null, 'bold 128px Arial',
'#000000', '#ffffff', true);
button.scaling = new Vector3(.1, 1, 1);
button.rotation.y = Math.PI / 2;
button.rotation.z = Math.PI;
}
}

View File

@ -7,7 +7,7 @@ export class DiagramExporter {
this.scene = scene;
}
public export() {
public exportgltf() {
import("@babylonjs/serializers").then((serializers) => {
serializers.GLTF2Export.GLBAsync(this.scene, 'diagram.glb', {
shouldExportNode: function (node) {

View File

@ -0,0 +1,21 @@
export function addSceneInspector(scene) {
window.addEventListener("keydown", (ev) => {
if (ev.key == "z") {
//voiceManager.startRecording();
}
if (ev.key == "x") {
//voiceManager.stopRecording();
}
if (ev.shiftKey && ev.ctrlKey && ev.altKey && ev.keyCode === 73) {
import("@babylonjs/core/Debug/debugLayer").then(() => {
import("@babylonjs/inspector").then(() => {
if (scene.debugLayer.isVisible()) {
scene.debugLayer.hide();
} else {
scene.debugLayer.show();
}
});
});
}
});
}