diff --git a/public/assets/screenshot1.png b/public/assets/screenshot1.png new file mode 100644 index 0000000..d5269df Binary files /dev/null and b/public/assets/screenshot1.png differ diff --git a/public/assets/screenthot3.png b/public/assets/screenthot3.png new file mode 100644 index 0000000..4c76d21 Binary files /dev/null and b/public/assets/screenthot3.png differ diff --git a/public/manifest.webmanifest b/public/manifest.webmanifest index d966cfd..b1bbc05 100644 --- a/public/manifest.webmanifest +++ b/public/manifest.webmanifest @@ -6,7 +6,7 @@ "short_name": "Deep Diagram", "theme_color": "#000000", "background_color": "#000000", - "description": "Immersive diagraming tool to dig into deeper meaning behind your ideas", + "description": "An immersive mind mapping and diagramming tool that lets you create, share, and visualize data on the Oculus Quest and desktop browsers.", "icons": [ { "src": "/Android.png", @@ -28,22 +28,22 @@ ], "screenshots": [ { - "src": "/assets/com.oculus.browser-20230121-110512.jpg", + "src": "/assets/screenshot1.png", "sizes": "1024x1024", - "type": "image/jpeg", - "label": "Example 1" + "type": "image/png", + "label": "Example of a few boxes on the web" }, { - "src": "/assets/com.oculus.browser-20230121-110746.jpg", + "src": "/assets/screenshot2.png", "sizes": "1024x1024", - "type": "image/jpeg", - "label": "Example 2" + "type": "image/png", + "label": "Example of menus on the web" }, { - "src": "/assets/com.oculus.browser-20230121-111323.jpg", + "src": "/assets/screenshots3.png", "sizes": "1024x1024", - "type": "image/jpeg", - "label": "Complex Architecture Diagram" + "type": "image/jpg", + "label": "Example showing the web app on the Oculus Quest" } ] } \ No newline at end of file diff --git a/src/controllers/webController.ts b/src/controllers/webController.ts index 1932fe4..5326e32 100644 --- a/src/controllers/webController.ts +++ b/src/controllers/webController.ts @@ -21,13 +21,17 @@ export class WebController { private readonly controllers: Controllers; private upDownWheel: boolean = false; private fowardBackWheel: boolean = false; + private canvas: HTMLCanvasElement; - constructor(scene: Scene, rig: Rigplatform, diagramManager: DiagramManager, controllers: Controllers) { + constructor(scene: Scene, + rig: Rigplatform, + diagramManager: DiagramManager, + controllers: Controllers) { this.scene = scene; this.rig = rig; this.diagramManager = diagramManager; this.controllers = controllers; - + this.canvas = document.querySelector('#gameCanvas'); this.referencePlane = MeshBuilder.CreatePlane('referencePlane', {size: 10}, this.scene); this.referencePlane.setEnabled(false); this.referencePlane.visibility = 0.5; @@ -40,9 +44,9 @@ export class WebController { this.scene.onKeyboardObservable.add((kbInfo) => { this.logger.debug(kbInfo); - const canvas = document.querySelector('#gameCanvas'); - if (canvas && kbInfo.event.target != canvas) { + + if (this.canvas && kbInfo.event.target != this.canvas) { return; } if (kbInfo.type == KeyboardEventTypes.KEYUP) { @@ -100,7 +104,6 @@ export class WebController { if (kbInfo.type == 1) { //this.referencePlane.setEnabled(true); } else { - this.referencePlane.setEnabled(false); if (this.pickedMesh) { this.pickedMesh.showBoundingBox = false; @@ -113,10 +116,18 @@ export class WebController { this.scene.onPointerUp = () => { this.mouseDown = false; this.rig.turn(0); + if (this.pickedMesh) { + this.referencePlane.setEnabled(false); + this.pickedMesh.showBoundingBox = false; + this.pickedMesh = null; + } }; window.addEventListener('wheel', (evt) => { + if (this.canvas && evt.target != this.canvas) { + return; + } switch (evt.buttons) { case 0: if (this.fowardBackWheel == false) { diff --git a/src/menus/editMenu.ts b/src/menus/editMenu.ts index 8b3dd80..8fab356 100644 --- a/src/menus/editMenu.ts +++ b/src/menus/editMenu.ts @@ -181,7 +181,7 @@ 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("Modify", "modify")); panel.addControl(this.makeButton("Remove", "remove")); panel.addControl(this.makeButton("Label", "label")); panel.addControl(this.makeButton("Copy", "copy")); diff --git a/src/menus/scaleMenu.ts b/src/menus/scaleMenu.ts index c4e78a0..0b06d7e 100644 --- a/src/menus/scaleMenu.ts +++ b/src/menus/scaleMenu.ts @@ -20,7 +20,7 @@ export class ScaleMenu extends AbstractMenu { constructor(scene: Scene, xr: WebXRDefaultExperience, controllers: Controllers) { super(scene, xr, controllers); - this.sounds = new DiaSounds(scene); + this.transformNode = new TransformNode("scaleMenu", scene); this.xTransformNode = new TransformNode("xTransformNode", scene); this.xTransformNode.parent = this.transformNode; diff --git a/src/toolbox/simpleToolbox.ts b/src/toolbox/simpleToolbox.ts new file mode 100644 index 0000000..4945904 --- /dev/null +++ b/src/toolbox/simpleToolbox.ts @@ -0,0 +1,20 @@ +import {Color3, Scene, StandardMaterial, TransformNode} from "@babylonjs/core"; +import {enumKeys} from "../util/functions/enumKeys"; +import {ToolType} from "./types/toolType"; +import {buildMesh} from "./functions/buildMesh"; + +export class SimpleToolbox { + private scene: Scene; + private transformNode: TransformNode; + + constructor(scene: Scene) { + this.scene = scene; + this.transformNode = new TransformNode("SimpleToolbox", this.scene); + } + + private buildBaseShapes(color: Color3) { + for (const tool of enumKeys(ToolType)) { + const mesh = buildMesh(ToolType[tool], id = toolId(tool, (parent.material as StandardMaterial).diffuseColor), this.transformNode); + } + } +} \ No newline at end of file diff --git a/src/util/functions/groundMeshObserver.ts b/src/util/functions/groundMeshObserver.ts index 0a5dce0..7d4819d 100644 --- a/src/util/functions/groundMeshObserver.ts +++ b/src/util/functions/groundMeshObserver.ts @@ -9,6 +9,7 @@ export async function groundMeshObserver(ground, scene, diagramManager, controll const xr = await WebXRDefaultExperience.CreateAsync(scene, { floorMeshes: [ground], disableTeleportation: true, + disableDefaultUI: true, outputCanvasOptions: { canvasOptions: { framebufferScaleFactor: 1 @@ -19,10 +20,23 @@ export async function groundMeshObserver(ground, scene, diagramManager, controll enablePointerSelectionOnAllControllers: true } + }); xr.baseExperience.onInitialXRPoseSetObservable.add((camera) => { //camera.position = new Vector3(0, -1.6, 0); }); + const enterButton = (document.querySelector('#enterXR') as HTMLAnchorElement); + if (enterButton) { + const vrSupported = await xr.baseExperience.sessionManager.isSessionSupportedAsync('immersive-vr'); + if (vrSupported) { + enterButton.style.display = "block"; + enterButton.addEventListener('click', (evt) => { + evt.preventDefault(); + xr.baseExperience.enterXRAsync('immersive-vr', 'local-floor'); + }); + } + + } if (spinner) { spinner.hide(); diff --git a/src/vrApp.ts b/src/vrApp.ts index c0f1edb..3d3d895 100644 --- a/src/vrApp.ts +++ b/src/vrApp.ts @@ -14,7 +14,6 @@ import {groundMeshObserver} from "./util/functions/groundMeshObserver"; import {MainMenu} from "./menus/mainMenu"; import {buildQuestLink} from "./util/functions/buildQuestLink"; import {exportGltf} from "./util/functions/exportGltf"; -import {Tutorial} from "./tutorial/tutorial"; export class VrApp { private scene: Scene; @@ -42,7 +41,6 @@ export class VrApp { const spinner = new Spinner(scene); spinner.show(); const config = new AppConfig(); - const tutorial = new Tutorial(scene, config); const controllers = new Controllers(); const toolbox = new Toolbox(scene, controllers); const diagramManager = new DiagramManager(scene, controllers, toolbox, config);