Removed some unused code. Optimized export bundle. Started building diagram selector menu.

This commit is contained in:
Michael Mainguy 2023-11-10 13:19:28 -06:00
parent 237b127686
commit 72bdbf3ffa
24 changed files with 215 additions and 201 deletions

View File

@ -19,6 +19,7 @@ import {reparent} from "./functions/reparent";
import {snapGridVal} from "../util/functions/snapGridVal"; import {snapGridVal} from "../util/functions/snapGridVal";
import {snapRotateVal} from "../util/functions/snapRotateVal"; import {snapRotateVal} from "../util/functions/snapRotateVal";
import {grabAndClone} from "./functions/grab"; import {grabAndClone} from "./functions/grab";
import {isDiagramEntity} from "../diagram/functions/isDiagramEntity";
export class Base { export class Base {
static stickVector = Vector3.Zero(); static stickVector = Vector3.Zero();
@ -113,8 +114,8 @@ export class Base {
return; return;
} }
let player = false; let player = false;
const template = mesh?.metadata?.template;
if (!template) { if (!isDiagramEntity(mesh)) {
if (mesh?.metadata?.handle == true) { if (mesh?.metadata?.handle == true) {
mesh && mesh.setParent(this.controller.motionController.rootMesh); mesh && mesh.setParent(this.controller.motionController.rootMesh);
this.grabbedMesh = mesh; this.grabbedMesh = mesh;
@ -131,7 +132,8 @@ export class Base {
} }
} else { } else {
if (template == '#connection-template') {
if (mesh?.metadata?.template == '#connection-template') {
return; return;
} }
} }
@ -165,7 +167,7 @@ export class Base {
} }
private toolboxHandleWasGrabbed(mesh: AbstractMesh): boolean { private toolboxHandleWasGrabbed(mesh: AbstractMesh): boolean {
if (!mesh?.metadata?.template if (isDiagramEntity(mesh)
&& mesh?.metadata?.handle == true) { && mesh?.metadata?.handle == true) {
this.grabbedMesh = null; this.grabbedMesh = null;
this.previousParentId = null; this.previousParentId = null;
@ -196,7 +198,7 @@ export class Base {
this.previousRotation = null; this.previousRotation = null;
this.previousPosition = null; this.previousPosition = null;
this.grabbedMesh = null; this.grabbedMesh = null;
if (mesh?.metadata?.template && (mesh?.metadata?.template.indexOf('#') == -1)) { if (isDiagramEntity(mesh) && (mesh?.metadata?.template.indexOf('#') == -1)) {
return; return;
} }
const entity = toDiagramEntity(mesh); const entity = toDiagramEntity(mesh);

View File

@ -1,16 +1,15 @@
import { import {
Color3,
Mesh, Mesh,
MeshBuilder, MeshBuilder,
PhysicsAggregate, PhysicsAggregate,
PhysicsMotionType, PhysicsMotionType,
PhysicsShapeType, PhysicsShapeType,
Scene, Scene,
StandardMaterial,
TransformNode, TransformNode,
Vector3 Vector3
} from "@babylonjs/core"; } from "@babylonjs/core";
import {AppConfig} from "../../util/appConfig"; import {AppConfig} from "../../util/appConfig";
import {buildStandardMaterial} from "../../materials/functions/buildStandardMaterial";
export function buildRig(scene: Scene, appConfig: AppConfig): Mesh { export function buildRig(scene: Scene, appConfig: AppConfig): Mesh {
const rigMesh = MeshBuilder.CreateCylinder("platform", {diameter: .5, height: 1.6}, scene); const rigMesh = MeshBuilder.CreateCylinder("platform", {diameter: .5, height: 1.6}, scene);
@ -24,10 +23,7 @@ export function buildRig(scene: Scene, appConfig: AppConfig): Mesh {
scene.onActiveCameraChanged.add((s) => { scene.onActiveCameraChanged.add((s) => {
s.activeCamera.parent = cameratransform; s.activeCamera.parent = cameratransform;
}); });
rigMesh.material = buildStandardMaterial("rigMaterial", scene, "#2222ff");
const rigMaterial = new StandardMaterial("rigMaterial", scene);
rigMaterial.diffuseColor = Color3.Blue();
rigMesh.material = rigMaterial;
rigMesh.setAbsolutePosition(new Vector3(0, .01, -3)); rigMesh.setAbsolutePosition(new Vector3(0, .01, -3));
rigMesh.visibility = 0; rigMesh.visibility = 0;
const rigAggregate = const rigAggregate =

View File

@ -42,7 +42,7 @@ export class Right extends Base {
controllers: Controllers, controllers: Controllers,
) { ) {
super(controller, scene, xr, controllers, diagramManager); super(controller, scene, xr, controllers, diagramManager);
this.listingMenu = new DiagramListingMenu(this.scene, xr, this.controllers); this.listingMenu = new DiagramListingMenu(this.scene, xr, this.controllers, diagramManager);
this.controller.onMotionControllerInitObservable.add((init) => { this.controller.onMotionControllerInitObservable.add((init) => {
this.initTrigger(init.components['xr-standard-trigger']); this.initTrigger(init.components['xr-standard-trigger']);
if (init.components['a-button']) { if (init.components['a-button']) {

View File

@ -30,7 +30,10 @@ export class Rigplatform {
private readonly controllers: Controllers; private readonly controllers: Controllers;
private registered = false; private registered = false;
constructor(scene: Scene, xr: WebXRDefaultExperience, diagramManager: DiagramManager, controllers: Controllers) { constructor(scene: Scene, xr: WebXRDefaultExperience,
diagramManager: DiagramManager,
controllers: Controllers,
) {
this.scene = scene; this.scene = scene;
this.diagramManager = diagramManager; this.diagramManager = diagramManager;
this.controllers = controllers; this.controllers = controllers;

View File

@ -5,9 +5,12 @@ import {DiagramManager} from "../diagram/diagramManager";
import {GridMaterial} from "@babylonjs/materials"; import {GridMaterial} from "@babylonjs/materials";
import {setMenuPosition} from "../util/functions/setMenuPosition"; import {setMenuPosition} from "../util/functions/setMenuPosition";
import {wheelHandler} from "./functions/wheelHandler"; import {wheelHandler} from "./functions/wheelHandler";
import log, {Logger} from "loglevel";
import {isDiagramEntity} from "../diagram/functions/isDiagramEntity";
export class WebController { export class WebController {
private readonly scene: Scene; private readonly scene: Scene;
private readonly logger: Logger = log.getLogger('WebController');
private speed: number = 1; private speed: number = 1;
private readonly referencePlane: AbstractMesh; private readonly referencePlane: AbstractMesh;
private pickedMesh: AbstractMesh; private pickedMesh: AbstractMesh;
@ -35,7 +38,7 @@ export class WebController {
this.scene.onKeyboardObservable.add((kbInfo) => { this.scene.onKeyboardObservable.add((kbInfo) => {
console.log(kbInfo); this.logger.debug(kbInfo);
if (kbInfo.type == 1) { if (kbInfo.type == 1) {
switch (kbInfo.event.key) { switch (kbInfo.event.key) {
case "ArrowUp": case "ArrowUp":
@ -66,7 +69,7 @@ export class WebController {
} }
break; break;
default: default:
console.log(kbInfo.event); this.logger.debug(kbInfo.event);
} }
} else { } else {
@ -138,7 +141,7 @@ export class WebController {
this.rig.turn(evt.movementX); this.rig.turn(evt.movementX);
} }
const meshPickInfo = scene.pick(this.scene.pointerX, this.scene.pointerY, (mesh) => { const meshPickInfo = scene.pick(this.scene.pointerX, this.scene.pointerY, (mesh) => {
return mesh.metadata?.template != undefined; return isDiagramEntity(mesh);
}); });
const planePickInfo = scene.pick(this.scene.pointerX, this.scene.pointerY, (mesh) => { const planePickInfo = scene.pick(this.scene.pointerX, this.scene.pointerY, (mesh) => {
return mesh.id == this.referencePlane.id; return mesh.id == this.referencePlane.id;
@ -178,9 +181,4 @@ export class WebController {
} }
this._mesh = mesh; this._mesh = mesh;
} }
private handlePointer(info, state) {
console.log(info);
console.log(state);
}
} }

View File

@ -1,15 +1,7 @@
import { import {AbstractMesh, MeshBuilder, PointerInfo, Scene, TransformNode, Vector3} from "@babylonjs/core";
AbstractMesh,
Color3,
MeshBuilder,
PointerInfo,
Scene,
StandardMaterial,
TransformNode,
Vector3
} from "@babylonjs/core";
import {v4 as uuidv4} from 'uuid'; import {v4 as uuidv4} from 'uuid';
import log, {Logger} from "loglevel"; import log, {Logger} from "loglevel";
import {buildStandardMaterial} from "../materials/functions/buildStandardMaterial";
export class DiagramConnection { export class DiagramConnection {
@ -112,10 +104,8 @@ export class DiagramConnection {
private buildConnection() { private buildConnection() {
this.logger.debug(`buildConnection from ${this._from} to ${this._to}`); this.logger.debug(`buildConnection from ${this._from} to ${this._to}`);
this._mesh = MeshBuilder.CreateCylinder(this.id + "_cylinder", {diameter: .02, height: 1}, this.scene); this._mesh = MeshBuilder.CreateCylinder(this.id + "_connection", {diameter: .02, height: 1}, this.scene);
const material = new StandardMaterial(this.id + "_material", this.scene); this._mesh.material = buildStandardMaterial(this.id + "_material", this.scene, "#000000");
material.diffuseColor = new Color3(0, 0, 0);
this._mesh.material = material;
this.transformNode = new TransformNode(this.id + "_transform", this.scene); this.transformNode = new TransformNode(this.id + "_transform", this.scene);
this._mesh.setParent(this.transformNode); this._mesh.setParent(this.transformNode);
this.recalculate(); this.recalculate();

View File

@ -13,10 +13,13 @@ import {applyScaling} from "./functions/applyScaling";
import {toDiagramEntity} from "./functions/toDiagramEntity"; import {toDiagramEntity} from "./functions/toDiagramEntity";
import {v4 as uuidv4} from 'uuid'; import {v4 as uuidv4} from 'uuid';
import {buildEntityActionManager} from "./functions/buildEntityActionManager"; import {buildEntityActionManager} from "./functions/buildEntityActionManager";
import {isDiagramEntity} from "./functions/isDiagramEntity";
import {DiagramListingEvent} from "./types/diagramListing";
export class DiagramManager { export class DiagramManager {
public readonly onDiagramEventObservable: Observable<DiagramEvent> = new Observable(); public readonly onDiagramEventObservable: Observable<DiagramEvent> = new Observable();
public readonly onDiagramEventListingObservable: Observable<DiagramListingEvent> = new Observable();
private readonly logger = log.getLogger('DiagramManager'); private readonly logger = log.getLogger('DiagramManager');
private readonly toolbox: Toolbox; private readonly toolbox: Toolbox;
private readonly scene: Scene; private readonly scene: Scene;
@ -49,7 +52,7 @@ export class DiagramManager {
this.logger.debug("DiagramManager constructed"); this.logger.debug("DiagramManager constructed");
scene.onMeshRemovedObservable.add((mesh) => { scene.onMeshRemovedObservable.add((mesh) => {
if (mesh?.metadata?.template) { if (isDiagramEntity(mesh)) {
if (mesh.metadata.template != '#connection-template') { if (mesh.metadata.template != '#connection-template') {
scene.meshes.forEach((m) => { scene.meshes.forEach((m) => {
if (m?.metadata?.to == mesh.id || m?.metadata?.from == mesh.id) { if (m?.metadata?.to == mesh.id || m?.metadata?.from == mesh.id) {

View File

@ -1,8 +1,10 @@
import {ActionManager, ExecuteCodeAction, PlaySoundAction, Scene} from "@babylonjs/core"; import {ActionManager, ExecuteCodeAction, PlaySoundAction, Scene} from "@babylonjs/core";
import {ControllerEventType, Controllers} from "../../controllers/controllers"; import {ControllerEventType, Controllers} from "../../controllers/controllers";
import {DiaSounds} from "../../util/diaSounds"; import {DiaSounds} from "../../util/diaSounds";
import log from "loglevel";
export function buildEntityActionManager(scene: Scene, sounds: DiaSounds, controllers: Controllers) { export function buildEntityActionManager(scene: Scene, sounds: DiaSounds, controllers: Controllers) {
const logger = log.getLogger('buildEntityActionManager');
const actionManager = new ActionManager(scene); const actionManager = new ActionManager(scene);
actionManager.registerAction( actionManager.registerAction(
new PlaySoundAction(ActionManager.OnPointerOverTrigger, sounds.tick)); new PlaySoundAction(ActionManager.OnPointerOverTrigger, sounds.tick));
@ -12,7 +14,7 @@ export function buildEntityActionManager(scene: Scene, sounds: DiaSounds, contro
type: ControllerEventType.PULSE, type: ControllerEventType.PULSE,
gripId: evt?.additionalData?.pickResult?.gripTransform?.id gripId: evt?.additionalData?.pickResult?.gripTransform?.id
}) })
this.logger.debug(evt); logger.debug(evt);
}) })
); );
return actionManager; return actionManager;

View File

@ -7,6 +7,7 @@ import {Toolbox} from "../../toolbox/toolbox";
import {DiaSounds} from "../../util/diaSounds"; import {DiaSounds} from "../../util/diaSounds";
import {fromDiagramEntity} from "./fromDiagramEntity"; import {fromDiagramEntity} from "./fromDiagramEntity";
import {isDiagramEntity} from "./isDiagramEntity";
export function diagramEventHandler(event: DiagramEvent, export function diagramEventHandler(event: DiagramEvent,
@ -37,12 +38,19 @@ export function diagramEventHandler(event: DiagramEvent,
} }
switch (event.type) { switch (event.type) {
case DiagramEventType.RESET:
this.scene.getAllMeshes().forEach((m) => {
if (m?.metadata?.template && !m?.metadata?.tool) {
m.dispose();
}
});
break;
case DiagramEventType.CLEAR: case DiagramEventType.CLEAR:
break; break;
case DiagramEventType.DROPPED: case DiagramEventType.DROPPED:
break; break;
case DiagramEventType.DROP: case DiagramEventType.DROP:
if (mesh?.metadata?.template && (mesh.metadata.template.indexOf('#') > -1)) { if (isDiagramEntity(mesh) && (mesh.metadata.template.indexOf('#') > -1)) {
TextLabel.updateTextNode(mesh, entity.text); TextLabel.updateTextNode(mesh, entity.text);
} }
break; break;
@ -71,7 +79,6 @@ export function diagramEventHandler(event: DiagramEvent,
} else { } else {
mesh.dispose(); mesh.dispose();
} }
sounds.exit.play(); sounds.exit.play();
} }
break; break;

View File

@ -1,6 +1,7 @@
import {DiaSounds} from "../../util/diaSounds"; import {DiaSounds} from "../../util/diaSounds";
import {AbstractMesh, PhysicsAggregate, PhysicsBody, PhysicsMotionType, PhysicsShapeType, Scene} from "@babylonjs/core"; import {AbstractMesh, PhysicsAggregate, PhysicsBody, PhysicsMotionType, PhysicsShapeType, Scene} from "@babylonjs/core";
import log from "loglevel"; import log from "loglevel";
import {isDiagramEntity} from "./isDiagramEntity";
const logger = log.getLogger('DiagramShapePhysics'); const logger = log.getLogger('DiagramShapePhysics');
const MASS_FACTOR = 10; const MASS_FACTOR = 10;
@ -9,7 +10,7 @@ export function applyPhysics(sounds: DiaSounds,
mesh: AbstractMesh, mesh: AbstractMesh,
scene: Scene, scene: Scene,
motionType?: PhysicsMotionType) { motionType?: PhysicsMotionType) {
if (!mesh?.metadata?.template) { if (!isDiagramEntity(mesh)) {
logger.error("applyPhysics: mesh.metadata.template is null", mesh); logger.error("applyPhysics: mesh.metadata.template is null", mesh);
return; return;
} }

View File

@ -1,9 +1,10 @@
import {DiagramEntity} from "../types/diagramEntity"; import {DiagramEntity} from "../types/diagramEntity";
import {AbstractMesh, Color3, InstancedMesh, Mesh, Quaternion, Scene, StandardMaterial, Vector3} from "@babylonjs/core"; import {AbstractMesh, InstancedMesh, Mesh, Quaternion, Scene, Vector3} from "@babylonjs/core";
import {DiagramConnection} from "../diagramConnection"; import {DiagramConnection} from "../diagramConnection";
import {TextLabel} from "../../objects/textLabel"; import {TextLabel} from "../../objects/textLabel";
import log from "loglevel"; import log from "loglevel";
import {v4 as uuidv4} from 'uuid'; import {v4 as uuidv4} from 'uuid';
import {buildStandardMaterial} from "../../materials/functions/buildStandardMaterial";
const logger = log.getLogger('fromDiagramEntity'); const logger = log.getLogger('fromDiagramEntity');
@ -54,9 +55,8 @@ export function fromDiagramEntity(entity: DiagramEntity, scene: Scene): Abstract
newMesh.scaling = xyztovec(entity.scale); newMesh.scaling = xyztovec(entity.scale);
} }
if (!newMesh.material) { if (!newMesh.material) {
const material = new StandardMaterial("material-" + entity.id, scene); this.logger.warn("new material created, this shouldn't happen");
material.diffuseColor = Color3.FromHexString(entity.color); newMesh.material = buildStandardMaterial("material-" + entity.id, scene, entity.color);
newMesh.material = material;
} }
if (entity.text) { if (entity.text) {
newMesh.metadata.text = entity.text; newMesh.metadata.text = entity.text;

View File

@ -0,0 +1,9 @@
import {AbstractMesh} from "@babylonjs/core";
export function isDiagramEntity(mesh: AbstractMesh): boolean {
if (mesh?.metadata?.template != undefined) {
return true;
} else {
return false;
}
}

View File

@ -1,6 +1,7 @@
import {PresentationStep} from "./presentationStep"; import {PresentationStep} from "./presentationStep";
import log, {Logger} from "loglevel"; import log, {Logger} from "loglevel";
import {Scene} from "@babylonjs/core"; import {Scene} from "@babylonjs/core";
import {isDiagramEntity} from "./functions/isDiagramEntity";
export class PresentationManager { export class PresentationManager {
_currentStep: PresentationStep = null; _currentStep: PresentationStep = null;
@ -24,7 +25,7 @@ export class PresentationManager {
this._steps[this._steps.length - 1].next = step; this._steps[this._steps.length - 1].next = step;
} else { } else {
this.scene.getActiveMeshes().forEach((mesh) => { this.scene.getActiveMeshes().forEach((mesh) => {
if (mesh.metadata?.template) { if (isDiagramEntity(mesh)) {
step.entities.push({ step.entities.push({
entity: mesh, entity: mesh,
endPosition: mesh.position.clone(), endPosition: mesh.position.clone(),

View File

@ -9,7 +9,8 @@ export enum DiagramEventType {
DROPPED, DROPPED,
CLEAR, CLEAR,
CHANGECOLOR, CHANGECOLOR,
SYNC SYNC,
RESET
} }
export enum DiagramEventMask { export enum DiagramEventMask {

View File

@ -2,15 +2,15 @@ export enum DiagramListingEventType {
GET, GET,
ADD, ADD,
REMOVE, REMOVE,
MODIFY MODIFY,
GETALL,
} }
export type DiagramListingEvent = { export type DiagramListingEvent = {
type: DiagramListingEventType; type: DiagramListingEventType;
listing: DiagramListing; listing?: DiagramListing;
} }
export type DiagramListing = { export type DiagramListing = {
type: DiagramListingEvent;
id: string; id: string;
name: string; name: string;
description?: string; description?: string;

View File

@ -6,11 +6,11 @@ import {v4 as uuidv4} from 'uuid';
import axios from "axios"; import axios from "axios";
import {DiagramManager} from "../diagram/diagramManager"; import {DiagramManager} from "../diagram/diagramManager";
import log, {Logger} from "loglevel"; import log, {Logger} from "loglevel";
import {DiagramListing, DiagramListingEvent} from "../diagram/types/diagramListing"; import {DiagramListing, DiagramListingEventType} from "../diagram/types/diagramListing";
export class PouchdbPersistenceManager { export class PouchdbPersistenceManager {
configObserver: Observable<AppConfigType> = new Observable<AppConfigType>(); configObserver: Observable<AppConfigType> = new Observable<AppConfigType>();
diagramListingObserver: Observable<DiagramListingEvent> = new Observable<DiagramListingEvent>();
updateObserver: Observable<DiagramEntity> = new Observable<DiagramEntity>(); updateObserver: Observable<DiagramEntity> = new Observable<DiagramEntity>();
removeObserver: Observable<DiagramEntity> = new Observable<DiagramEntity>(); removeObserver: Observable<DiagramEntity> = new Observable<DiagramEntity>();
//implement IPersistenceManager interface with pouchdb apis //implement IPersistenceManager interface with pouchdb apis
@ -25,6 +25,18 @@ export class PouchdbPersistenceManager {
} }
public setDiagramManager(diagramManager: DiagramManager) { public setDiagramManager(diagramManager: DiagramManager) {
diagramManager.onDiagramEventListingObservable.add((evt) => {
if (evt.type == DiagramListingEventType.GETALL) {
this.diagramListings.allDocs({include_docs: true}).then((all) => {
for (const entity of all.rows) {
diagramManager.onDiagramEventListingObservable.notifyObservers({
type: DiagramListingEventType.ADD,
listing: {id: entity.doc._id, name: entity.doc.name}
}, -1, false, this);
}
});
}
}, -1, false, this);
diagramManager.onDiagramEventObservable.add((evt) => { diagramManager.onDiagramEventObservable.add((evt) => {
switch (evt.type) { switch (evt.type) {
case DiagramEventType.CHANGECOLOR: case DiagramEventType.CHANGECOLOR:

View File

@ -5,9 +5,9 @@ export function buildStandardMaterial(name: string, scene: Scene, color: string)
if (existingMaterial) { if (existingMaterial) {
return (existingMaterial as StandardMaterial); return (existingMaterial as StandardMaterial);
} }
const handleMaterial = new StandardMaterial(name, scene); const newMaterial = new StandardMaterial(name, scene);
handleMaterial.id = name; newMaterial.id = name;
handleMaterial.diffuseColor = Color3.FromHexString(color); newMaterial.diffuseColor = Color3.FromHexString(color);
handleMaterial.alpha = 1; newMaterial.alpha = 1;
return handleMaterial; return newMaterial;
} }

View File

@ -1,9 +1,11 @@
import {Color3, DynamicTexture, Mesh, MeshBuilder, Scene, StandardMaterial, Vector3} from "@babylonjs/core"; import {Color3, DynamicTexture, Mesh, MeshBuilder, Scene, StandardMaterial, Vector3} from "@babylonjs/core";
import log, {Logger} from "loglevel";
export class CameraMenu { export class CameraMenu {
private readonly scene: Scene; private readonly scene: Scene;
private xr; private xr;
private controllers; private controllers;
private readonly logger: Logger = log.getLogger('CameraMenu');
constructor(scene, xr, controllers) { constructor(scene, xr, controllers) {
this.scene = scene; this.scene = scene;
@ -22,23 +24,11 @@ export class CameraMenu {
slice: .5, slice: .5,
sideOrientation: Mesh.DOUBLESIDE sideOrientation: Mesh.DOUBLESIDE
}, this.scene); }, this.scene);
//const camerasphere = MeshBuilder.CreatePlane("camerasphere", {width: 1.6, height: .6, sideOrientation: Mesh.DOUBLESIDE }, this.scene);
camerasphere.position = position; camerasphere.position = position;
const material = new StandardMaterial("cameramaterial", this.scene); const material = new StandardMaterial("cameramaterial", this.scene);
material.emissiveColor = new Color3(1, 1, 1); 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 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; material.diffuseTexture = texture;
const img = new Image(); const img = new Image();
img.src = 'https://cameras.immersiveidea.com/mjpg/video.mjpg?camera=' + camnum + '&timestamp=1698497537140'; img.src = 'https://cameras.immersiveidea.com/mjpg/video.mjpg?camera=' + camnum + '&timestamp=1698497537140';
@ -47,34 +37,15 @@ export class CameraMenu {
ctx.drawImage(img, 250, 0, 2112, 1940, 0, 0, 1600, 1600); ctx.drawImage(img, 250, 0, 2112, 1940, 0, 0, 1600, 1600);
texture.update(); texture.update();
window.setInterval((texture, img, ctx) => { window.setInterval((texture, img, ctx) => {
//const start = new Date();
ctx.drawImage(img, 250, 0, 2112, 1940, 0, 0, 1600, 1600); ctx.drawImage(img, 250, 0, 2112, 1940, 0, 0, 1600, 1600);
texture.update(); texture.update();
//console.log(new Date() - start);
}, 60, texture, img, ctx); }, 60, texture, img, ctx);
} }
//https://cameras.immersiveidea.com/mjpg/video.mjpg?camera=1&timestamp=1698497537140');
//texture.getContext().drawImage(img, 0,0);
texture.onLoadObservable.add(() => { texture.onLoadObservable.add(() => {
console.log('texture loaded'); this.logger.debug('texture loaded');
}); });
this.scene.onAfterRenderObservable.add(() => {
// texture._rebuild();
}, 1, true, this);
camerasphere.material = material; camerasphere.material = material;
/*texture.video.play().then(() => { this.logger.info('camera built');
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

@ -3,14 +3,24 @@ import {AbstractMenu} from "./abstractMenu";
import {ControllerEventType, Controllers} from "../controllers/controllers"; import {ControllerEventType, Controllers} from "../controllers/controllers";
import {AdvancedDynamicTexture, Button, Control, ScrollViewer, StackPanel, TextBlock} from "@babylonjs/gui"; import {AdvancedDynamicTexture, Button, Control, ScrollViewer, StackPanel, TextBlock} from "@babylonjs/gui";
import {setMenuPosition} from "../util/functions/setMenuPosition"; import {setMenuPosition} from "../util/functions/setMenuPosition";
import {DiagramManager} from "../diagram/diagramManager";
import {DiagramListingEvent, DiagramListingEventType} from "../diagram/types/diagramListing";
export class DiagramListingMenu extends AbstractMenu { export class DiagramListingMenu extends AbstractMenu {
private mesh: AbstractMesh; private mesh: AbstractMesh;
constructor(scene: Scene, xr: WebXRDefaultExperience, controllers: Controllers) { private panel: StackPanel;
private readonly diagramManager: DiagramManager;
constructor(scene: Scene, xr: WebXRDefaultExperience, controllers: Controllers, diagramManager: DiagramManager) {
super(scene, xr, controllers); super(scene, xr, controllers);
this.diagramManager = diagramManager;
this.buildMenu(); this.buildMenu();
this.controllers.controllerObserver.add((event) => { this.controllers.controllerObserver.add((event) => {
if (event.type == ControllerEventType.B_BUTTON) { if (event.type == ControllerEventType.B_BUTTON) {
this.toggle(); this.toggle();
} }
}); });
@ -19,9 +29,15 @@ export class DiagramListingMenu extends AbstractMenu {
public toggle() { public toggle() {
setMenuPosition(this.handle.mesh, this.scene, new Vector3(0, .4, 0)); setMenuPosition(this.handle.mesh, this.scene, new Vector3(0, .4, 0));
this.mesh.isVisible = !this.mesh.isVisible; this.mesh.isVisible = !this.mesh.isVisible;
this.populateData();
(this.mesh.parent as AbstractMesh).isVisible = this.mesh.isVisible; (this.mesh.parent as AbstractMesh).isVisible = this.mesh.isVisible;
} }
public populateData() {
this.panel.clearControls();
this.diagramManager.onDiagramEventListingObservable.notifyObservers({type: DiagramListingEventType.GETALL}, -1);
}
private buildMenu() { private buildMenu() {
const configPlane = MeshBuilder const configPlane = MeshBuilder
.CreatePlane("gridSizePlane", .CreatePlane("gridSizePlane",
@ -35,37 +51,44 @@ export class DiagramListingMenu extends AbstractMenu {
configTexture.background = "white"; configTexture.background = "white";
const scrollViewer = new ScrollViewer('diagramListingScroll'); const scrollViewer = new ScrollViewer('diagramListingScroll');
configTexture.addControl(scrollViewer); configTexture.addControl(scrollViewer);
const stackpanel = new StackPanel('diagramListingStack'); this.panel = new StackPanel('diagramListingStack');
scrollViewer.addControl(stackpanel); scrollViewer.addControl(this.panel);
for (let i = 0; i < 100; i++) {
const row = new StackPanel('diagramListingRow ' + i);
row.isVertical = false;
row.height = "68px";
row.width = 1;
stackpanel.addControl(row);
const selectButton = Button.CreateSimpleButton('diagramListingText ' + i, 'Select');
selectButton.height = "64px";
selectButton.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
selectButton.width = "220px";
selectButton.color = "white";
selectButton.fontSize = "48px";
selectButton.background = "#333333";
selectButton.onPointerClickObservable.add(() => {
});
const textBlock = new TextBlock('diagramListingText ' + i, 'Diagram ' + i);
textBlock.width = "1000px";
textBlock.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
textBlock.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
textBlock.fontSize = "48px";
row.addControl(selectButton);
row.addControl(textBlock);
}
this.createHandle(configPlane); this.createHandle(configPlane);
configPlane.position.y = .5; configPlane.position.y = .5;
setMenuPosition(this.handle.mesh, this.scene, new Vector3(0, .4, 0)); setMenuPosition(this.handle.mesh, this.scene, new Vector3(0, .4, 0));
this.mesh.isVisible = false; this.mesh.isVisible = false;
(this.mesh.parent as AbstractMesh).isVisible = false; (this.mesh.parent as AbstractMesh).isVisible = false;
this.diagramManager.onDiagramEventListingObservable.add((event: DiagramListingEvent) => {
if (event.type == DiagramListingEventType.ADD) {
this.addRow(event.listing.id, event.listing.name);
}
}, -1, false, this);
}
private addRow(id: string, name: string) {
const row = new StackPanel('diagramListingRow ' + id);
row.isVertical = false;
row.height = "68px";
row.width = 1;
this.panel.addControl(row);
const selectButton = Button.CreateSimpleButton('diagramListingText ' + id, id);
selectButton.height = "64px";
selectButton.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
selectButton.width = "220px";
selectButton.color = "white";
selectButton.fontSize = "48px";
selectButton.background = "#333333";
selectButton.onPointerClickObservable.add(() => {
console.log(id);
}, -1, false, this);
const textBlock = new TextBlock('diagramListingText ' + name, 'Diagram ' + name);
textBlock.width = "1000px";
textBlock.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
textBlock.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
textBlock.fontSize = "48px";
row.addControl(selectButton);
row.addControl(textBlock);
} }
} }

View File

@ -28,6 +28,7 @@ import {setMenuPosition} from "../util/functions/setMenuPosition";
import {SoccerMenu} from "../soccer/soccerMenu"; import {SoccerMenu} from "../soccer/soccerMenu";
import {CameraMenu} from "./cameraMenu"; import {CameraMenu} from "./cameraMenu";
import {exportGltf} from "../util/functions/exportGltf"; import {exportGltf} from "../util/functions/exportGltf";
import {isDiagramEntity} from "../diagram/functions/isDiagramEntity";
export class EditMenu extends AbstractMenu { export class EditMenu extends AbstractMenu {
private state: EditMenuState = EditMenuState.NONE; private state: EditMenuState = EditMenuState.NONE;
@ -160,23 +161,63 @@ export class EditMenu extends AbstractMenu {
this.diagramManager.onDiagramEventObservable.notifyObservers(event, -1); this.diagramManager.onDiagramEventObservable.notifyObservers(event, -1);
} }
private modifyMesh(mesh: AbstractMesh) { constructor(scene: Scene, xr: WebXRDefaultExperience, diagramManager: DiagramManager, controllers: Controllers) {
if (mesh.metadata?.template && super(scene, xr, controllers);
mesh.parent?.parent?.id != "toolbox") { this.sounds = new DiaSounds(scene);
if (this.gizmoManager.gizmos.boundingBoxGizmo.attachedMesh?.id == mesh.id) { this.diagramManager = diagramManager;
this.gizmoManager.gizmos.boundingBoxGizmo.attachedMesh = null; this.gizmoManager = new GizmoManager(scene);
} else { this.gizmoManager.boundingBoxGizmoEnabled = true;
this.gizmoManager.attachToMesh(mesh); this.gizmoManager.gizmos.boundingBoxGizmo.scaleBoxSize = .020;
this.gizmoManager.gizmos.boundingBoxGizmo.onScaleBoxDragObservable.add(() => { this.gizmoManager.gizmos.boundingBoxGizmo.rotationSphereSize = .020;
this.diagramManager.onDiagramEventObservable.notifyObservers({ this.gizmoManager.gizmos.boundingBoxGizmo.scaleDragSpeed = 2;
type: DiagramEventType.MODIFY, this.gizmoManager.clearGizmoOnEmptyPointerEvent = true;
entity: toDiagramEntity(mesh), this.gizmoManager.usePointerToAttachGizmos = false;
}, -1 this.manager = new GUI3DManager(this.scene);
) const panel = new PlanePanel();
this.logger.debug(mesh.scaling);
}); 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 GLTF", "exportgltf"));
panel.addControl(this.makeButton("Recolor", "recolor"));
panel.addControl(this.makeButton("New Relic", "newrelic"));
panel.addControl(this.makeButton("Soccer", "soccer"));
//panel.addControl(this.makeButton("Add Ring Cameras", "addRingCameras"));
this.manager.controlScaling = .1;
this.scene.onPointerObservable.add((pointerInfo) => {
switch (pointerInfo.type) {
case PointerEventTypes.POINTERPICK:
const pickedMesh = pointerInfo.pickInfo?.pickedMesh;
if (isDiagramEntity(pickedMesh) &&
pickedMesh?.parent?.parent?.id != "toolbox") {
this.diagramEntityPicked(pointerInfo).then(() => {
this.logger.debug("handled");
}).catch((e) => {
this.logger.error(e);
});
break;
} else {
const tool = pickedMesh?.metadata?.tool;
if (tool) {
this.logger.debug("tool type", tool);
this.paintColor = (pickedMesh.material as StandardMaterial).diffuseColor.toHexString();
this.logger.debug((pickedMesh.material as StandardMaterial).diffuseColor.toHexString());
this.logger.debug(pickedMesh.id);
}
}
} }
} });
this.panel = panel;
this.createHandle(this.manager.rootContainer.children[0].node);
this.manager.rootContainer.children[0].node.position.y = .2;
this.isVisible = false;
} }
private copyMesh(mesh: AbstractMesh) { private copyMesh(mesh: AbstractMesh) {
@ -223,63 +264,23 @@ export class EditMenu extends AbstractMenu {
} }
constructor(scene: Scene, xr: WebXRDefaultExperience, diagramManager: DiagramManager, controllers: Controllers) { private modifyMesh(mesh: AbstractMesh) {
super(scene, xr, controllers); if (isDiagramEntity(mesh) &&
this.sounds = new DiaSounds(scene); mesh.parent?.parent?.id != "toolbox") {
this.diagramManager = diagramManager; if (this.gizmoManager.gizmos.boundingBoxGizmo.attachedMesh?.id == mesh.id) {
this.gizmoManager = new GizmoManager(scene); this.gizmoManager.gizmos.boundingBoxGizmo.attachedMesh = null;
this.gizmoManager.boundingBoxGizmoEnabled = true; } else {
this.gizmoManager.gizmos.boundingBoxGizmo.scaleBoxSize = .020; this.gizmoManager.attachToMesh(mesh);
this.gizmoManager.gizmos.boundingBoxGizmo.rotationSphereSize = .020; this.gizmoManager.gizmos.boundingBoxGizmo.onScaleBoxDragObservable.add(() => {
this.gizmoManager.gizmos.boundingBoxGizmo.scaleDragSpeed = 2; this.diagramManager.onDiagramEventObservable.notifyObservers({
this.gizmoManager.clearGizmoOnEmptyPointerEvent = true; type: DiagramEventType.MODIFY,
this.gizmoManager.usePointerToAttachGizmos = false; entity: toDiagramEntity(mesh),
this.manager = new GUI3DManager(this.scene); }, -1
const panel = new PlanePanel(); )
this.logger.debug(mesh.scaling);
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 GLTF", "exportgltf"));
panel.addControl(this.makeButton("Recolor", "recolor"));
panel.addControl(this.makeButton("New Relic", "newrelic"));
panel.addControl(this.makeButton("Soccer", "soccer"));
//panel.addControl(this.makeButton("Add Ring Cameras", "addRingCameras"));
this.manager.controlScaling = .1;
this.scene.onPointerObservable.add((pointerInfo) => {
switch (pointerInfo.type) {
case PointerEventTypes.POINTERPICK:
const pickedMesh = pointerInfo.pickInfo?.pickedMesh;
if (pickedMesh.metadata?.template &&
pickedMesh?.parent?.parent?.id != "toolbox") {
this.diagramEntityPicked(pointerInfo).then(() => {
this.logger.debug("handled");
}).catch((e) => {
this.logger.error(e);
});
break;
} else {
const tool = pickedMesh?.metadata?.tool;
if (tool) {
this.logger.debug("tool type", tool);
this.paintColor = (pickedMesh.material as StandardMaterial).diffuseColor.toHexString();
this.logger.debug((pickedMesh.material as StandardMaterial).diffuseColor.toHexString());
this.logger.debug(pickedMesh.id);
}
}
} }
}); }
this.panel = panel;
this.createHandle(this.manager.rootContainer.children[0].node);
this.manager.rootContainer.children[0].node.position.y = .2;
this.isVisible = false;
} }
private handleClick(_info, state) { private handleClick(_info, state) {

View File

@ -19,9 +19,9 @@ export function buildTool(tool: ToolType, parent: AbstractMesh) {
WIDGET_SIZE, WIDGET_SIZE,
WIDGET_SIZE); WIDGET_SIZE);
newItem.parent = parent; newItem.parent = parent;
newItem.metadata = {template: tool}; newItem.metadata = {template: tool, tool: true};
const instance = new InstancedMesh("instance-" + id, newItem); const instance = new InstancedMesh("instance-" + id, newItem);
instance.metadata = {template: tool}; instance.metadata = {template: tool, tool: true};
instance.parent = parent; instance.parent = parent;
newItem.setEnabled(false); newItem.setEnabled(false);
newItem.onEnabledStateChangedObservable.add(() => { newItem.onEnabledStateChangedObservable.add(() => {

View File

@ -15,6 +15,7 @@ import {Button3D, GUI3DManager, TextBlock} from "@babylonjs/gui";
import {DiaSounds} from "../util/diaSounds"; import {DiaSounds} from "../util/diaSounds";
import {AppConfig} from "../util/appConfig"; import {AppConfig} from "../util/appConfig";
import Hls from "hls.js"; import Hls from "hls.js";
import log, {Logger} from "loglevel";
export class Introduction { export class Introduction {
@ -27,6 +28,7 @@ export class Introduction {
private advance: Button3D; private advance: Button3D;
private sounds: DiaSounds; private sounds: DiaSounds;
private config: AppConfig; private config: AppConfig;
private logger: Logger = log.getLogger('Introduction');
private videoElement: HTMLVideoElement; private videoElement: HTMLVideoElement;
@ -90,7 +92,7 @@ export class Introduction {
hls.attachMedia(vid); hls.attachMedia(vid);
hls.on(Hls.Events.MANIFEST_PARSED, function () { hls.on(Hls.Events.MANIFEST_PARSED, function () {
vid.play().then(() => { vid.play().then(() => {
console.log("Video Playing"); this.logger.debug("Video Playing");
}); });
}); });
} else if (vid.canPlayType('application/vnd.apple.mpegurl')) { } else if (vid.canPlayType('application/vnd.apple.mpegurl')) {

View File

@ -3,6 +3,7 @@ import HavokPhysics from "@babylonjs/havok";
import {AppConfig} from "./appConfig"; import {AppConfig} from "./appConfig";
import {snapGridVal} from "./functions/snapGridVal"; import {snapGridVal} from "./functions/snapGridVal";
import {snapRotateVal} from "./functions/snapRotateVal"; import {snapRotateVal} from "./functions/snapRotateVal";
import {isDiagramEntity} from "../diagram/functions/isDiagramEntity";
export class CustomPhysics { export class CustomPhysics {
private readonly scene: Scene; private readonly scene: Scene;
@ -21,7 +22,7 @@ export class CustomPhysics {
scene.collisionsEnabled = true; scene.collisionsEnabled = true;
scene.onAfterPhysicsObservable.add(() => { scene.onAfterPhysicsObservable.add(() => {
scene.meshes.forEach((mesh) => { scene.meshes.forEach((mesh) => {
if (mesh?.metadata?.template && mesh.physicsBody) { if (isDiagramEntity(mesh) && mesh.physicsBody) {
const body = mesh.physicsBody; const body = mesh.physicsBody;
const linearVelocity = new Vector3(); const linearVelocity = new Vector3();
body.getLinearVelocityToRef(linearVelocity); body.getLinearVelocityToRef(linearVelocity);

View File

@ -54,14 +54,7 @@ export class Spinner {
rotate.setKeys(keys); rotate.setKeys(keys);
spinner.animations.push(rotate); spinner.animations.push(rotate);
this.scene.beginAnimation(spinner, 0, 30, true); this.scene.beginAnimation(spinner, 0, 30, true);
//material.indexOfRefraction = Math.PI/4;
//material.indexOfRefraction = 1;
/*material.reflectionFresnelParameters = new FresnelParameters();
material.reflectionFresnelParameters.leftColor = Color3.Black();
material.reflectionFresnelParameters.rightColor = Color3.White();
material.reflectionFresnelParameters.power = 1;
*/
material.alpha = .9; material.alpha = .9;
spinner.material = material; spinner.material = material;
let particleSystem; let particleSystem;
@ -92,7 +85,5 @@ export class Spinner {
this.spinner = spinner; this.spinner = spinner;
this.spinner.setEnabled(false); this.spinner.setEnabled(false);
this.particleSystem = particleSystem; this.particleSystem = particleSystem;
} }
} }