diff --git a/index.html b/index.html index 466f05d..ff69121 100644 --- a/index.html +++ b/index.html @@ -1,139 +1,266 @@ - - - Deep Diagram - - - - - - - - - - + div#create { + left: 50%; + top: 60%; + transform: translate(-50%, -50%); + z-index: 12; + width: 320px; + height: 240px; + border: 3px inset #FFD700; + display: none; + } + + div.overlay div a.cancel { + font-size: small; + font-weight: lighter; + font-style: italic; + background-color: #222211; + color: #EEC755; + } + + div.overlay div a.cancel:hover { + background-color: #EEC700; + color: #000000; + } + + #download { + display: none; + } + + #main.mini { + left: 100px; + top: 200px; + width: 160px; + } + + #main.mini img, #tutorial img { + width: 160px; + height: 60px; + } + + #main.mini div a, #tutorial div a { + width: 80px; + } + + #tutorial h1 { + font-size: x-large; + font-weight: bolder; + text-align: center; + color: #F9F9E9; + } + + #tutorial { + z-index: 15; + left: 100px; + top: 560px; + width: 160px; + height: 210px; + } + + + #closekey, #closekey a:active, #closekey a:visited, #closekey a:link { + position: relative; + color: #ffffff; + } + + #loadingGrid { + z-index: -1; + width: 100%; + height: 100%; + } + + + + + + + + + +
+

Help

+
Desktop
+
Quest
+
-
Download Model
+
+ +
Start
+
Download Model
+
+
+
+
+
Create
+
Cancel
+
+
+
X
+ + + +
+ @@ -141,42 +268,27 @@
-
- -
-
- - - -
- + \ No newline at end of file diff --git a/package.json b/package.json index 5a13ab7..5508e26 100644 --- a/package.json +++ b/package.json @@ -28,8 +28,6 @@ "events": "^3.3.0", "@typed-mxgraph/typed-mxgraph": "^1.0.8", "@types/node": "^18.14.0", - "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", @@ -37,15 +35,11 @@ "loglevel": "^1.8.1", "mxgraph": "^4.2.2", "niceware": "^4.0.0", - "p2p-data-channel": "^1.10.7", "pouchdb": "^8.0.1", "pouchdb-find": "^7.2.2", "query-string": "^8.1.0", - "recordrtc": "^5.6.2", - "ring-client-api": "11.7.7", "round": "^2.0.1", - "uuid": "^9.0.0", - "material-components-web": "^11.0.0" + "uuid": "^9.0.0" }, "devDependencies": { "typescript": "^4.9.5", diff --git a/public/Big Dripper_1.wav b/public/Big Dripper_1.wav deleted file mode 100644 index 3c15ee2..0000000 Binary files a/public/Big Dripper_1.wav and /dev/null differ diff --git a/public/ak-alfa.glb b/public/ak-alfa.glb deleted file mode 100644 index 39754c5..0000000 Binary files a/public/ak-alfa.glb and /dev/null differ diff --git a/public/android-icon-192x192.png b/public/android-icon-192x192.png new file mode 100644 index 0000000..c1cf121 Binary files /dev/null and b/public/android-icon-192x192.png differ diff --git a/public/arch_demo.xml b/public/arch_demo.xml deleted file mode 100644 index cdc0cf1..0000000 --- a/public/arch_demo.xml +++ /dev/null @@ -1,4312 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/assets/Android.png b/public/assets/Android.png new file mode 100644 index 0000000..d0c53e2 Binary files /dev/null and b/public/assets/Android.png differ diff --git a/public/assets/ddd.svg b/public/assets/ddd.svg new file mode 100644 index 0000000..a82b82a --- /dev/null +++ b/public/assets/ddd.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/assets/favicon-16x16.png b/public/assets/favicon-16x16.png index 67b42c7..7b8f083 100644 Binary files a/public/assets/favicon-16x16.png and b/public/assets/favicon-16x16.png differ diff --git a/public/assets/favicon-32x32.png b/public/assets/favicon-32x32.png index 829e0c4..6c11f6c 100644 Binary files a/public/assets/favicon-32x32.png and b/public/assets/favicon-32x32.png differ diff --git a/public/assets/favicon-96x96.png b/public/assets/favicon-96x96.png index 0f83304..bcdfc10 100644 Binary files a/public/assets/favicon-96x96.png and b/public/assets/favicon-96x96.png differ diff --git a/public/assets/grid.png b/public/assets/grid.png new file mode 100644 index 0000000..398e201 Binary files /dev/null and b/public/assets/grid.png differ diff --git a/public/assets/grid2.png b/public/assets/grid2.png new file mode 100644 index 0000000..70b8c89 Binary files /dev/null and b/public/assets/grid2.png differ diff --git a/public/assets/grid3.jpg b/public/assets/grid3.jpg new file mode 100644 index 0000000..4a7bfdf Binary files /dev/null and b/public/assets/grid3.jpg differ diff --git a/public/assets/iPhone.png b/public/assets/iPhone.png new file mode 100644 index 0000000..d02b862 Binary files /dev/null and b/public/assets/iPhone.png differ diff --git a/public/assets/textures/keyboard.jpg b/public/assets/textures/keyboard.jpg new file mode 100644 index 0000000..835c419 Binary files /dev/null and b/public/assets/textures/keyboard.jpg differ diff --git a/public/assets/textures/keyboardhelp.jpg b/public/assets/textures/keyboardhelp.jpg new file mode 100644 index 0000000..7c16776 Binary files /dev/null and b/public/assets/textures/keyboardhelp.jpg differ diff --git a/public/assets/textures/keyboardhelp2.jpg b/public/assets/textures/keyboardhelp2.jpg new file mode 100644 index 0000000..e7c5cbf Binary files /dev/null and b/public/assets/textures/keyboardhelp2.jpg differ diff --git a/public/assets/textures/mouse.jpg b/public/assets/textures/mouse.jpg new file mode 100644 index 0000000..e8049a7 Binary files /dev/null and b/public/assets/textures/mouse.jpg differ diff --git a/public/assets/textures/mousehelp.jpg b/public/assets/textures/mousehelp.jpg new file mode 100644 index 0000000..42f665c Binary files /dev/null and b/public/assets/textures/mousehelp.jpg differ diff --git a/public/data/data.json b/public/data/data.json deleted file mode 100644 index 8cb51c9..0000000 --- a/public/data/data.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "name": "Chart 1", - "series": [ - { - "name": "series 1", - "values": [ - { - "id": "1", - "start": "2015-01-01", - "end": "2015-12-31", - "value": 1 - }, - { - "id": "2", - "start": "2016-01-01", - "end": "2016-12-31", - "value": 2 - }, - { - "id": "3", - "start": "2017-01-01", - "end": "2017-12-31", - "value": 3 - }, - { - "id": "4", - "start": "2018-01-01", - "end": "2018-12-31", - "value": 4 - } - ] - }, - { - "name": "series 2", - "values": [ - { - "id": "1", - "start": "2015-01-01", - "end": "2015-12-31", - "value": 5 - }, - { - "id": "2", - "start": "2016-01-01", - "end": "2016-12-31", - "value": 6 - }, - { - "id": "3", - "start": "2017-01-01", - "end": "2017-12-31", - "value": 7 - }, - { - "id": "4", - "start": "2018-01-01", - "end": "2018-12-31", - "value": 8 - } - ] - } - ] -} diff --git a/public/environment.env b/public/environment.env deleted file mode 100644 index 77bc89f..0000000 Binary files a/public/environment.env and /dev/null differ diff --git a/public/loading-loading-forever.gif b/public/loading-loading-forever.gif deleted file mode 100644 index b846a13..0000000 Binary files a/public/loading-loading-forever.gif and /dev/null differ diff --git a/public/manifest.webmanifest b/public/manifest.webmanifest index f2e5d2b..d966cfd 100644 --- a/public/manifest.webmanifest +++ b/public/manifest.webmanifest @@ -9,14 +9,14 @@ "description": "Immersive diagraming tool to dig into deeper meaning behind your ideas", "icons": [ { - "src": "/assets/android-icon-192x192.png", - "sizes": "192x192", + "src": "/Android.png", + "sizes": "196x196", "type": "image/png", "purpose": "any" }, { - "src": "/assets/icon-512x512.png", - "sizes": "512x512", + "src": "/iPhone.png", + "sizes": "180x180", "type": "image/png" } ], diff --git a/public/spinner.gif b/public/spinner.gif deleted file mode 100644 index 116ffcb..0000000 Binary files a/public/spinner.gif and /dev/null differ diff --git a/public/sw.js b/public/sw.js index 5ec3ffe..b1b7bdc 100644 --- a/public/sw.js +++ b/public/sw.js @@ -1,10 +1,6 @@ const VERSION = '0'; const CACHE = "pwabuilder-offline"; -const PRECACHE_ASSETS = [ - '/grass1.jpeg', - '/loading-loading-forever.gif', - '/outdoor_field2.jpeg' -] +const PRECACHE_ASSETS = [] importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'); self.addEventListener("message", (event) => { diff --git a/src/controllers/functions/buildRig.ts b/src/controllers/functions/buildRig.ts index 7bb0844..9a742b0 100644 --- a/src/controllers/functions/buildRig.ts +++ b/src/controllers/functions/buildRig.ts @@ -7,56 +7,60 @@ import { PhysicsShapeType, Scene, TransformNode, - Vector3 + Vector3, + WebXRDefaultExperience } from "@babylonjs/core"; import {buildStandardMaterial} from "../../materials/functions/buildStandardMaterial"; -export function buildRig(scene: Scene): Mesh { - const rigMesh = MeshBuilder.CreateCylinder("platform", {diameter: .5, height: 1.6}, scene); - +export function buildRig(scene: Scene, xr: WebXRDefaultExperience): Mesh { + const rigMesh = MeshBuilder.CreateCylinder("platform", {diameter: .5, height: .2}, scene); const cameratransform = new TransformNode("cameraTransform", scene); cameratransform.parent = rigMesh; - cameratransform.position = new Vector3(0, -.8, 0); + xr.baseExperience.onInitialXRPoseSetObservable.add((state) => { + + xr.baseExperience.camera.parent = cameratransform; + xr.baseExperience.camera.position = new Vector3(0, 0, 0); + + + }); for (const cam of scene.cameras) { cam.parent = cameratransform; - console.log(cam.absoluteRotation); + if (cam.getClassName() == "FreeCamera") { + //cameratransform.position = new Vector3(0, 1.6, 0); + //cam.position.set(0, 1.6, 0); + } else { + //cameratransform.position = new Vector3(0, 1.6, 0); + //cam.position.set(0, 0, 0); + } } - - scene.onActiveCameraChanged.add((s) => { + scene.onActiveCameraChanged.add(() => { + for (const cam of scene.cameras) { + cam.parent = cameratransform; + if (cam.getClassName() == "FreeCamera") { + //cameratransform.position = new Vector3(0, 1.6, 0); + //cam.position.set(0, 1.6, 0); + } else { + //cameratransform.position = new Vector3(0, 0, 0); + //cam.position.set(0, 0, 0); + } + } cameratransform.rotation.set(0, Math.PI, 0); - s.activeCamera.parent = cameratransform; + //s.activeCamera.parent = cameratransform; }); rigMesh.material = buildStandardMaterial("rigMaterial", scene, "#2222ff"); rigMesh.setAbsolutePosition(new Vector3(0, .01, 3)); - const home = new AxesViewer(scene, .5); + rigMesh.isPickable = false; + new AxesViewer(scene, .25); rigMesh.lookAt(new Vector3(0, 0.01, 0)); - rigMesh.visibility = 0; + rigMesh.visibility = 1; const rigAggregate = new PhysicsAggregate( rigMesh, PhysicsShapeType.CYLINDER, - {friction: 0, center: Vector3.Zero(), mass: 50, restitution: .1}, + {friction: 0, center: Vector3.Zero(), mass: 50, restitution: .01}, scene); - - - /*const rightFoot = MeshBuilder.CreateBox("rightFoot", {width: .1, height: .1, depth: .2}, scene); - const rightFootAggregate = - new PhysicsAggregate( - rightFoot, - PhysicsShapeType.BOX, - { friction: 0, center: Vector3.Zero(), radius: .2, pointA: new Vector3(0, 0, 0), - pointB: new Vector3(0, 1.5, 0), mass: 50, restitution: .1}, - scene); - rightFootAggregate.body.setMotionType(PhysicsMotionType.ANIMATED); - rightFoot.parent= rigAggregate.transformNode; - rightFoot.material = rigMaterial; - rightFoot.position.y=.05; - rightFoot.position.x=.2; - rightFoot.position.z= 2; - - */ rigAggregate.body.setMotionType(PhysicsMotionType.DYNAMIC); return rigMesh; } diff --git a/src/controllers/rigplatform.ts b/src/controllers/rigplatform.ts index 7b0830a..4b63c5d 100644 --- a/src/controllers/rigplatform.ts +++ b/src/controllers/rigplatform.ts @@ -31,7 +31,7 @@ export class Rigplatform { this.diagramManager = diagramManager; this.controllers = controllers; this.xr = xr; - this.rigMesh = buildRig(scene); + this.rigMesh = buildRig(scene, xr); this.fixRotation(); this.initializeControllers(); @@ -163,7 +163,7 @@ export class Rigplatform { } break; } - this.xr.baseExperience.camera.position = new Vector3(0, 1.6, 0); + //this.xr.baseExperience.camera.position = new Vector3(0, 0, 0); if (controller) { controller.setRig(this); } diff --git a/src/controllers/webController.ts b/src/controllers/webController.ts index 300a320..1932fe4 100644 --- a/src/controllers/webController.ts +++ b/src/controllers/webController.ts @@ -1,4 +1,4 @@ -import {AbstractMesh, MeshBuilder, Scene} from "@babylonjs/core"; +import {AbstractMesh, KeyboardEventTypes, MeshBuilder, Scene} from "@babylonjs/core"; import {Rigplatform} from "./rigplatform"; import {ControllerEventType, Controllers} from "./controllers"; import {DiagramManager} from "../diagram/diagramManager"; @@ -40,20 +40,38 @@ export class WebController { this.scene.onKeyboardObservable.add((kbInfo) => { this.logger.debug(kbInfo); + const canvas = document.querySelector('#gameCanvas'); + + if (canvas && kbInfo.event.target != canvas) { + return; + } + if (kbInfo.type == KeyboardEventTypes.KEYUP) { + this.rig.turn(0); + } if (kbInfo.type == 1) { switch (kbInfo.event.key) { case "ArrowUp": + case "w": this.rig.forwardback(-this.speed); break; case "ArrowDown": + case "s": this.rig.forwardback(this.speed); break; case "ArrowLeft": + case "a": this.rig.leftright(-this.speed); break; + case "A": + this.rig.turn(-this.speed); + break; case "ArrowRight": + case "d": this.rig.leftright(this.speed); break; + case "D": + this.rig.turn(this.speed); + break; case "]": this.speed *= 1.5; break; @@ -70,6 +88,7 @@ export class WebController { } break; default: + this.logger.debug(kbInfo.event); } diff --git a/src/diagram/functions/buildMeshFromDiagramEntity.ts b/src/diagram/functions/buildMeshFromDiagramEntity.ts index b8aa107..f091c0a 100644 --- a/src/diagram/functions/buildMeshFromDiagramEntity.ts +++ b/src/diagram/functions/buildMeshFromDiagramEntity.ts @@ -1,7 +1,7 @@ import {DiagramEntity, DiagramEntityType} from "../types/diagramEntity"; import {AbstractMesh, InstancedMesh, Mesh, Quaternion, Scene, Vector3} from "@babylonjs/core"; import {DiagramConnection} from "../diagramConnection"; -import {TextLabel} from "../../objects/textLabel"; +import {updateTextNode} from "../../util/functions/updateTextNode"; import log from "loglevel"; import {v4 as uuidv4} from 'uuid'; import {buildStandardMaterial} from "../../materials/functions/buildStandardMaterial"; @@ -80,7 +80,7 @@ function mapMetadata(entity: DiagramEntity, newMesh: AbstractMesh, scene: Scene) } if (entity.text) { newMesh.metadata.text = entity.text; - TextLabel.updateTextNode(newMesh, entity.text); + updateTextNode(newMesh, entity.text); } if (entity.from) { newMesh.metadata.from = entity.from; diff --git a/src/diagram/functions/diagramEventHandler.ts b/src/diagram/functions/diagramEventHandler.ts index bf478e6..5d091d0 100644 --- a/src/diagram/functions/diagramEventHandler.ts +++ b/src/diagram/functions/diagramEventHandler.ts @@ -2,7 +2,7 @@ import {DiagramEvent, DiagramEventType} from "../types/diagramEntity"; import log from "loglevel"; import {applyPhysics} from "./diagramShapePhysics"; import {ActionManager, PhysicsMotionType, Scene} from "@babylonjs/core"; -import {TextLabel} from "../../objects/textLabel"; +import {updateTextNode} from "../../util/functions/updateTextNode"; import {Toolbox} from "../../toolbox/toolbox"; import {DiaSounds} from "../../util/diaSounds"; @@ -51,7 +51,7 @@ export function diagramEventHandler(event: DiagramEvent, break; case DiagramEventType.DROP: if (isDiagramEntity(mesh) && (mesh.metadata.template.indexOf('#') > -1)) { - TextLabel.updateTextNode(mesh, entity.text); + updateTextNode(mesh, entity.text); } break; case DiagramEventType.ADD: diff --git a/src/integration/pouchdbPersistenceManager.ts b/src/integration/pouchdbPersistenceManager.ts index c3f6d0a..793b6a5 100644 --- a/src/integration/pouchdbPersistenceManager.ts +++ b/src/integration/pouchdbPersistenceManager.ts @@ -271,9 +271,8 @@ export class PouchdbPersistenceManager { private async beginSync(remoteDbName: string) { try { - //const remoteDbName = "db1"; - const remoteUserName = "user1"; + const remoteUserName = remoteDbName; const password = "password"; const dbs = await axios.get(import.meta.env.VITE_SYNCDB_ENDPOINT + '_all_dbs'); if (dbs.data.indexOf(remoteDbName) == -1) { diff --git a/src/menus/editMenu.ts b/src/menus/editMenu.ts index aa4988a..8b3dd80 100644 --- a/src/menus/editMenu.ts +++ b/src/menus/editMenu.ts @@ -18,7 +18,7 @@ import {DiagramEvent, DiagramEventType} from "../diagram/types/diagramEntity"; import log from "loglevel"; import {InputTextView} from "../information/inputTextView"; import {DiaSounds} from "../util/diaSounds"; -import {TextLabel} from "../objects/textLabel"; +import {updateTextNode} from "../util/functions/updateTextNode"; import {DiagramConnection} from "../diagram/diagramConnection"; import {toDiagramEntity} from "../diagram/functions/toDiagramEntity"; @@ -29,6 +29,7 @@ import {SoccerMenu} from "../soccer/soccerMenu"; import {CameraMenu} from "./cameraMenu"; import {exportGltf} from "../util/functions/exportGltf"; import {isDiagramEntity} from "../diagram/functions/isDiagramEntity"; +import {ScaleMenu} from "./scaleMenu"; export class EditMenu extends AbstractMenu { private state: EditMenuState = EditMenuState.NONE; @@ -161,8 +162,10 @@ export class EditMenu extends AbstractMenu { this.diagramManager.onDiagramEventObservable.notifyObservers(event, -1); } + private scaleMenu: ScaleMenu; constructor(scene: Scene, xr: WebXRDefaultExperience, diagramManager: DiagramManager, controllers: Controllers) { super(scene, xr, controllers); + //this.scaleMenu = new ScaleMenu(this.scene, this.xr, this.controllers); this.sounds = new DiaSounds(scene); this.diagramManager = diagramManager; this.gizmoManager = new GizmoManager(scene); @@ -177,16 +180,16 @@ 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("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("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("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) => { @@ -240,7 +243,7 @@ export class EditMenu extends AbstractMenu { textInput.show(); textInput.onTextObservable.addOnce((value) => { this.persist(mesh, value.text); - TextLabel.updateTextNode(mesh, value.text); + updateTextNode(mesh, value.text); }); @@ -267,19 +270,7 @@ export class EditMenu extends AbstractMenu { private modifyMesh(mesh: AbstractMesh) { if (isDiagramEntity(mesh) && mesh.parent?.parent?.id != "toolbox") { - if (this.gizmoManager.gizmos.boundingBoxGizmo.attachedMesh?.id == mesh.id) { - this.gizmoManager.gizmos.boundingBoxGizmo.attachedMesh = null; - } else { - this.gizmoManager.attachToMesh(mesh); - this.gizmoManager.gizmos.boundingBoxGizmo.onScaleBoxDragObservable.add(() => { - this.diagramManager.onDiagramEventObservable.notifyObservers({ - type: DiagramEventType.MODIFY, - entity: toDiagramEntity(mesh), - }, -1 - ) - this.logger.debug(mesh.scaling); - }); - } + this.scaleMenu.changeMesh(mesh); } } diff --git a/src/menus/scaleMenu.ts b/src/menus/scaleMenu.ts new file mode 100644 index 0000000..c4e78a0 --- /dev/null +++ b/src/menus/scaleMenu.ts @@ -0,0 +1,108 @@ +import {AbstractMesh, Scene, TransformNode, Vector3, WebXRDefaultExperience} from "@babylonjs/core"; + +import {Controllers} from "../controllers/controllers"; +import {DiaSounds} from "../util/diaSounds"; +import {AbstractMenu} from "./abstractMenu"; + +import {GUI3DManager, Slider3D} from "@babylonjs/gui"; + +export class ScaleMenu extends AbstractMenu { + private sounds: DiaSounds; + private mesh: AbstractMesh; + private xSlider: Slider3D; + private ySlider: Slider3D; + private zSlider: Slider3D; + private transformNode: TransformNode; + private xTransformNode: TransformNode; + private yTransformNode: TransformNode; + private zTransformNode: TransformNode; + + 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; + + this.yTransformNode = new TransformNode("yTransformNode", scene); + this.yTransformNode.parent = this.transformNode; + + this.zTransformNode = new TransformNode("zTransformNode", scene); + this.zTransformNode.parent = this.transformNode; + + //super.createHandle(this.transformNode); + this.transformNode.position.y = 0; + this.transformNode.position.z = 0; + this.transformNode.position.x = 0; + + this.buildMenu(); + + //this.transformNode.position.y = 2; + + } + + public changeMesh(mesh: AbstractMesh) { + this.mesh = mesh; + this.xSlider.value = mesh.scaling.x; + this.ySlider.value = mesh.scaling.y; + this.zSlider.value = mesh.scaling.z; + + const two = new Vector3(2, 2, 2); + this.transformNode.position = this.mesh.absolutePosition.clone(); + this.transformNode.rotation = this.mesh.absoluteRotationQuaternion.toEulerAngles(); + + } + + private buildMenu() { + const manager = new GUI3DManager(this.scene); + //manager.rootContainer.position.y = 2; + //manager.rootContainer.node.position.y = 2; + this.xSlider = new Slider3D("xslider"); + this.ySlider = new Slider3D("xslider"); + this.zSlider = new Slider3D("xslider"); + + manager.addControl(this.xSlider); + manager.addControl(this.ySlider); + manager.addControl(this.zSlider); + this.xSlider.linkToTransformNode(this.xTransformNode); + this.ySlider.linkToTransformNode(this.yTransformNode); + this.zSlider.linkToTransformNode(this.zTransformNode); + + this.xTransformNode.position = new Vector3(0, 0, .6); + this.xTransformNode.rotation.y = Math.PI; + this.yTransformNode.position = new Vector3(.6, .6, .6); + this.yTransformNode.rotation.z = Math.PI / 2; + this.zTransformNode.position = new Vector3(.6, .6, 0); + this.zTransformNode.rotation.y = Math.PI / 2; + setValues(this.xSlider); + setValues(this.ySlider); + setValues(this.zSlider); + this.xSlider.onValueChangedObservable.add((value) => { + if (this.mesh) { + this.mesh.scaling.x = value; + } + }); + this.ySlider.onValueChangedObservable.add((value) => { + if (this.mesh) { + this.mesh.scaling.y = value; + } + }); + this.zSlider.onValueChangedObservable.add((value) => { + if (this.mesh) { + this.mesh.scaling.z = value; + } + }); + this.transformNode.scaling.x = .5; + this.transformNode.scaling.y = .5; + this.transformNode.scaling.z = .5; + } + +} + +function setValues(slider: Slider3D) { + slider.minimum = .1; + slider.maximum = 1; + slider.step = .1; + slider.value = .1; +} \ No newline at end of file diff --git a/src/objects/textLabel.ts b/src/objects/textLabel.ts deleted file mode 100644 index 4047070..0000000 --- a/src/objects/textLabel.ts +++ /dev/null @@ -1,75 +0,0 @@ -import {AbstractMesh, DynamicTexture, Material, MeshBuilder, StandardMaterial} from "@babylonjs/core"; -import log from "loglevel"; - -export class TextLabel { - private static logger: log.Logger = log.getLogger('TextLabel'); - - public static updateTextNode(mesh: AbstractMesh, text: string) { - if (!mesh) { - this.logger.error("updateTextNode: mesh is null"); - return null; - } - const textNodes = mesh.getChildren((node) => { - return node.metadata?.label == true; - }); - if (textNodes && textNodes.length > 0) { - textNodes.forEach((node) => { - node.dispose(false, true); - }); - } - - if (!text) { - return null; - } - - //Set font - const height = 0.05; - const font_size = 24; - const font = "bold " + font_size + "px Arial"; - //Set height for dynamic texture - const DTHeight = 1.5 * font_size; //or set as wished - //Calc Ratio - const ratio = height / DTHeight; - - //Use a temporary dynamic texture to calculate the length of the text on the dynamic texture canvas - const temp = new DynamicTexture("DynamicTexture", 32, mesh.getScene()); - const tmpctx = temp.getContext(); - tmpctx.font = font; - const DTWidth = tmpctx.measureText(text).width + 8; - - //Calculate width the plane has to be - const planeWidth = DTWidth * ratio; - - //Create dynamic texture and write the text - const dynamicTexture = new DynamicTexture("DynamicTexture", { - width: DTWidth, - height: DTHeight - }, mesh.getScene(), false); - const mat = new StandardMaterial("mat", mesh.getScene()); - mat.diffuseTexture = dynamicTexture; - //mat.emissiveColor = Color3.White(); - dynamicTexture.drawText(text, null, null, font, "#000000", "#ffffff", true); - //Create plane and set dynamic texture as material - //const plane = MeshBuilder.CreatePlane("text" + text, {width: planeWidth, height: height}, mesh.getScene()); - const plane1 = this.createPlane(mat, mesh, text, planeWidth, height); - const plane2 = this.createPlane(mat, mesh, text, planeWidth, height); - plane2.rotation.y = Math.PI; - } - - private static createPlane(mat: Material, mesh: AbstractMesh, text: string, planeWidth: number, height: number): AbstractMesh { - const plane = MeshBuilder.CreatePlane("text" + text, {width: planeWidth, height: height}, mesh.getScene()); - - plane.material = mat; - //plane.billboardMode = Mesh.BILLBOARDMODE_ALL; - plane.metadata = {exportable: true, label: true}; - - const yOffset = mesh.getBoundingInfo().boundingSphere.maximum.y; - plane.parent = mesh; - - plane.scaling.y = (1 / mesh.scaling.y); - plane.scaling.x = (1 / mesh.scaling.x); - plane.scaling.z = (1 / mesh.scaling.z); - plane.position.y = yOffset + (height * plane.scaling.y); - return plane; - } -} \ No newline at end of file diff --git a/src/soccer/ball.ts b/src/soccer/ball.ts index b928597..1374172 100644 --- a/src/soccer/ball.ts +++ b/src/soccer/ball.ts @@ -45,7 +45,7 @@ export class Ball { private buildBall() { SceneLoader.ImportMesh(null, "/assets/models/", "ball.gltf", this.scene, - (meshes, particleSystems, skeletons, animationGroups) => { + (meshes) => { this.logger.debug('ball loaded'); this.mesh = meshes[0]; this.parent = MeshBuilder.CreateSphere("ballParent", {diameter: .17}, this.scene); diff --git a/src/toolbox/functions/buildColor.ts b/src/toolbox/functions/buildColor.ts index a1c139d..8a38bdc 100644 --- a/src/toolbox/functions/buildColor.ts +++ b/src/toolbox/functions/buildColor.ts @@ -11,6 +11,10 @@ export function buildColor(color: Color3, scene: Scene, parent: TransformNode, i //const material = new PBRMaterial("material-" + color.toHexString(), scene); const material = new StandardMaterial("material-" + color.toHexString(), scene); material.diffuseColor = color; + material.roughness = 1; + material.specularPower = 1; + //material.emissiveColor = color; + //const material = new StandardMaterial("material-" + color.toHexString(), scene); //material.albedoColor = color; //material.metallic = 1; diff --git a/src/toolbox/functions/buildMesh.ts b/src/toolbox/functions/buildMesh.ts index 1ab44f2..5b2428a 100644 --- a/src/toolbox/functions/buildMesh.ts +++ b/src/toolbox/functions/buildMesh.ts @@ -7,16 +7,19 @@ export function buildMesh(type: ToolType, toolname: string, scene: Scene): Mesh return MeshBuilder.CreateBox(toolname, {width: 1, height: 1, depth: 1}, scene); case ToolType.SPHERE: - return MeshBuilder.CreateSphere(toolname, {diameter: 1}, scene); + return MeshBuilder.CreateIcoSphere(toolname, {subdivisions: 5, radius: .5}, scene); + //return MeshBuilder.CreateSphere(toolname, {diameter: 1}, scene); case ToolType.CYLINDER: - return MeshBuilder.CreateCylinder(toolname, {height: 1, diameter: 1}, scene); + return MeshBuilder.CreateCylinder(toolname, {height: 1, diameter: 1, subdivisions: 1, tessellation: 12}, scene); case ToolType.CONE: return MeshBuilder.CreateCylinder(toolname, { diameterTop: 0, + subdivisions: 1, height: 1, - diameterBottom: 1 + diameterBottom: 1, + tessellation: 12 }, scene); case ToolType.PLANE: diff --git a/src/tutorial/introduction.ts b/src/tutorial/introduction.ts index 164c924..68ebb38 100644 --- a/src/tutorial/introduction.ts +++ b/src/tutorial/introduction.ts @@ -17,7 +17,6 @@ import {AppConfig} from "../util/appConfig"; import Hls from "hls.js"; import log, {Logger} from "loglevel"; - export class Introduction { private readonly scene: Scene; private manager: GUI3DManager; diff --git a/src/tutorial/tutorial.ts b/src/tutorial/tutorial.ts new file mode 100644 index 0000000..92d3b88 --- /dev/null +++ b/src/tutorial/tutorial.ts @@ -0,0 +1,24 @@ +import {AppConfig} from "../util/appConfig"; +import {Scene} from "@babylonjs/core"; + +export class Tutorial { + private scene: Scene; + private config: AppConfig; + + constructor(scene: Scene, config: AppConfig) { + this.scene = scene; + this.config = config; + const advance = document.querySelector('#advanceLink'); + if (advance) { + advance.addEventListener('click', () => { + this.advance(); + }); + } + + console.log('Tutorial'); + } + + private advance() { + window.alert('here'); + } +} \ No newline at end of file diff --git a/src/util/customEnvironment.ts b/src/util/customEnvironment.ts index 35b5a61..8138566 100644 --- a/src/util/customEnvironment.ts +++ b/src/util/customEnvironment.ts @@ -1,20 +1,24 @@ import { + Color3, GroundMesh, HemisphericLight, + Material, MeshBuilder, Observable, PBRMaterial, - PhotoDome, PhysicsAggregate, PhysicsShapeType, + PointsCloudSystem, Scene, Sound, Texture, + TransformNode, Vector3 } from "@babylonjs/core"; import {CustomPhysics} from "./customPhysics"; import {DiaSounds} from "./diaSounds"; import {AppConfig} from "./appConfig"; +import {GridMaterial} from "@babylonjs/materials"; export class CustomEnvironment { @@ -25,8 +29,13 @@ export class CustomEnvironment { constructor(scene: Scene, name: string = "default", config: AppConfig) { this.scene = scene; this.name = name; - new HemisphericLight("light1", new Vector3(1, 1, 0), scene); - new HemisphericLight("light2", new Vector3(-1, 1, 0), scene); + const loading = document.querySelector('#loadingGrid'); + if (loading) { + loading.remove(); + } + const light = new HemisphericLight("light1", new Vector3(.1, 1, 0), scene); + light.groundColor = new Color3(.1, .1, .1) + light.intensity = .6; const physics = new CustomPhysics(this.scene, config); physics @@ -35,15 +44,11 @@ export class CustomEnvironment { const ground = this.createGround(); this._groundMeshObservable.notifyObservers(ground); }); + } - - const photo = new PhotoDome('sky', - '/assets/textures/outdoor_field4.jpeg', {}, - scene); - - + private initSounds() { try { - const sounds = new DiaSounds(scene); + const sounds = new DiaSounds(this.scene); window.setTimeout((sound) => { sound.play() }, 2000, sounds.background); @@ -72,38 +77,104 @@ export class CustomEnvironment { } catch (error) { } - - } - public get groundMeshObservable() { return this._groundMeshObservable; } private createGround() { const scene = this.scene; - const groundMaterial = new PBRMaterial("groundMaterial", scene); - const gText = new Texture("/assets/textures/grass1.jpeg", scene); - gText.uScale = 30; - gText.vScale = 30; - groundMaterial.albedoTexture = gText; - groundMaterial.metallic = 0; - groundMaterial.roughness = 1; - const grassBump = new Texture("/assets/textures/grassnormal.png", scene); - grassBump.uScale = 20; - grassBump.vScale = 20; - groundMaterial.bumpTexture = - grassBump; const ground: GroundMesh = MeshBuilder.CreateGround("ground", { - width: 100, - height: 100, + width: 20, + height: 20, subdivisions: 1 }, scene); + createPoints(scene, 20, 20); + ground.material = createGridMaterial(scene, Color3.FromHexString("#aaffaa"), Color3.FromHexString("#111511")); + const color1 = Color3.FromHexString("#ff9999"); + const color2 = Color3.FromHexString("#221111"); + const color3 = Color3.FromHexString("#9999ff"); + const color4 = Color3.FromHexString("#111115"); + + + this.createWall(new Vector3(0, 10, 10), new Vector3(0, 0, 0), color3, color4); + this.createWall(new Vector3(0, 10, -10), new Vector3(0, Math.PI, 0), color3, color4); + this.createWall(new Vector3(10, 10, 0), new Vector3(0, Math.PI / 2, 0), color1, color2); + this.createWall(new Vector3(-10, 10, 0), new Vector3(0, -Math.PI / 2, 0), color1, color2); - ground.material = groundMaterial; new PhysicsAggregate(ground, PhysicsShapeType.BOX, {mass: 0}, scene); //buildAvatar(scene); return ground; } + + private createWall(position: Vector3, rotation: Vector3, color1: Color3, color2: Color3) { + const scene = this.scene; + const wall = MeshBuilder.CreatePlane("wall", {width: 20, height: 20}, scene); + wall.position = position; + wall.rotation = rotation; + wall.material = createGridMaterial(scene, color1, color2); + return wall; + } +} + +async function createPoints(scene: Scene, divisions: number = 10, scale: number = 80) { + const half = .5; + const increment = 1 / divisions; + let x = -half; + let y = -half; + let z = -half; + const baseTransform = new TransformNode("baseTransform", scene); + baseTransform.scaling = new Vector3(scale, scale, scale); + baseTransform.position = new Vector3(0, scale / 2, 0); + const pcs = new PointsCloudSystem("pcs", 1, scene); + + pcs.addPoints((divisions + 1) ** 3, function (particle) { + particle.position.x = x; + particle.position.y = y; + particle.position.z = z; + + x += increment; + if (x > half) { + x = -half + y += increment; + if (y > half) { + y = -half; + z += increment; + if (z > half) { + + } + } + } + }); + const mesh = await pcs.buildMeshAsync(); + mesh.visibility = .5; + mesh.parent = baseTransform; +} + +function createGridMaterial(scene: Scene, lineColor: Color3, mainColor: Color3): Material { + const material = new GridMaterial("gridMaterial", scene); + material.minorUnitVisibility = .1; + material.gridRatio = .1; + material.majorUnitFrequency = 10; + material.mainColor = mainColor; + material.lineColor = lineColor; + + return material; +} + +function createGrassGround(scene: Scene): Material { + const groundMaterial = new PBRMaterial("groundMaterial", scene); + const gText = new Texture("/assets/textures/grass1.jpeg", scene); + gText.uScale = 10; + gText.vScale = 10; + groundMaterial.albedoTexture = gText; + groundMaterial.metallic = 0; + groundMaterial.roughness = 1; + const grassBump = new Texture("/assets/textures/grassnormal.png", scene); + grassBump.uScale = 20; + grassBump.vScale = 20; + groundMaterial.bumpTexture = + grassBump; + return groundMaterial; } \ No newline at end of file diff --git a/src/util/functions/buildQuestLink.ts b/src/util/functions/buildQuestLink.ts index d1453e5..d46da5b 100644 --- a/src/util/functions/buildQuestLink.ts +++ b/src/util/functions/buildQuestLink.ts @@ -11,6 +11,9 @@ export function buildQuestLink() { a.target = "_blank"; a.innerText = "Launch On Quest"; div.appendChild(a); - document.body.appendChild(div); + const main = document.querySelector('#main'); + if (main) { + //main.appendChild(div); + } } \ No newline at end of file diff --git a/src/util/functions/createCloset.ts b/src/util/functions/createCloset.ts new file mode 100644 index 0000000..623e1ba --- /dev/null +++ b/src/util/functions/createCloset.ts @@ -0,0 +1,69 @@ +import { + AssetContainer, + Color3, + Mesh, + MeshBuilder, + Scalar, + Scene, + SceneLoader, + SpotLight, + StandardMaterial, + Vector3 +} from "@babylonjs/core"; + + +export function createCloset(scene: Scene) { + const width = 1.8; + const height = 2.4; + const material = new StandardMaterial("closet", scene); + material.maxSimultaneousLights = 10; + material.diffuseColor = Color3.FromHexString("#ffffee"); + const back = MeshBuilder.CreatePlane("back", {sideOrientation: Mesh.DOUBLESIDE, width: width, height: height}, scene); + back.position.z = -.9 / 2; + back.material = material; + back.position.y = height / 2; + const left = MeshBuilder.CreatePlane("back", {sideOrientation: Mesh.DOUBLESIDE, width: .9, height: height}, scene); + const left2 = MeshBuilder.CreatePlane("back", {sideOrientation: Mesh.DOUBLESIDE, width: .15, height: height}, scene); + left2.position.z = .9 / 2; + left2.position.x = -width / 2 + .15 / 2; + left2.position.y = height / 2; + left.material = material; + left2.material = material; + const right = MeshBuilder.CreatePlane("back", {sideOrientation: Mesh.DOUBLESIDE, width: .9, height: height}, scene); + const right2 = MeshBuilder.CreatePlane("back", {sideOrientation: Mesh.DOUBLESIDE, width: .15, height: height}, scene); + right2.position.x = width / 2 - .15 / 2; + right2.position.y = height / 2; + right2.position.z = .9 / 2; + right2.material = material + right.material = material; + left.position.y = height / 2; + right.position.y = height / 2; + left.position.x = width / 2; + right.position.x = -width / 2; + left.rotation.y = Math.PI / 2; + right.rotation.y = Math.PI / 2; + const front = MeshBuilder.CreatePlane("back", {sideOrientation: Mesh.DOUBLESIDE, width: width - .3, height: .35}, scene); + front.material = material; + front.position.y = height - .35 / 2; + front.position.z = .9 / 2; + const width2 = width * .9; + for (let i = 0; i < 5; i++) { + const l = Scalar.Lerp(-width2 / 2, width2 / 2, (width / 5) * i); + const light = new SpotLight("light", new Vector3(l, 2, (.9 / 2) - .01), + new Vector3(0, 0, -1), Math.PI / 1.5, 5, scene); + light.intensity = .3; + } + + SceneLoader.LoadAssetContainer("/assets/textures/washer/LG Trom Wash Tower Object Collection_2color/LG Trom Wash Tower_white/", "LG Trom Wash.gltf", scene, + (container: AssetContainer) => { + const model = container.instantiateModelsToScene(undefined, false, {doNotInstantiate: true}); + const node = model.rootNodes[0]; + node.scaling.scaleInPlace(.00098); + node.position.x -= .42; + const bounds = node.getHierarchyBoundingVectors(true); + console.log((bounds.max.x - bounds.min.x) * 39.37); + console.log('here'); + }); + + +} \ No newline at end of file diff --git a/src/util/functions/groundMeshObserver.ts b/src/util/functions/groundMeshObserver.ts index 5adcbad..0a5dce0 100644 --- a/src/util/functions/groundMeshObserver.ts +++ b/src/util/functions/groundMeshObserver.ts @@ -20,6 +20,9 @@ export async function groundMeshObserver(ground, scene, diagramManager, controll } }); + xr.baseExperience.onInitialXRPoseSetObservable.add((camera) => { + //camera.position = new Vector3(0, -1.6, 0); + }); if (spinner) { spinner.hide(); @@ -30,17 +33,23 @@ export async function groundMeshObserver(ground, scene, diagramManager, controll this.logger.debug(ev); }); }); + xr.baseExperience.onStateChangedObservable.add((state) => { - if (state == WebXRState.IN_XR) { - scene.audioEnabled = true; - //xr.baseExperience.camera.position = new Vector3(0, 1.6, 0); - //xr.baseExperience.camera.setTarget(new Vector3(0, 1.6, 3)); - window.addEventListener(('pa-button-state-change'), (event: any) => { - if (event.detail) { - log.debug('App', event.detail); - } - }); + switch (state) { + case WebXRState.IN_XR: + scene.audioEnabled = true; + + //xr.baseExperience.camera.position = new Vector3(0, 1.6, 0); + //xr.baseExperience.camera.setTarget(new Vector3(0, 1.6, 3)); + window.addEventListener(('pa-button-state-change'), (event: any) => { + if (event.detail) { + log.debug('App', event.detail); + } + }); + break; + } + }); import('../../controllers/rigplatform').then((rigmodule) => { const rig = new rigmodule.Rigplatform(scene, xr, diagramManager, controllers); @@ -58,8 +67,6 @@ export async function groundMeshObserver(ground, scene, diagramManager, controll } }); const config = new ConfigMenu(scene, xr, controllers, diagramManager.config); - - const webController = new WebController(scene, rig, diagramManager, controllers); }); } \ No newline at end of file diff --git a/src/util/functions/updateTextNode.ts b/src/util/functions/updateTextNode.ts new file mode 100644 index 0000000..0965a2e --- /dev/null +++ b/src/util/functions/updateTextNode.ts @@ -0,0 +1,74 @@ +import {AbstractMesh, DynamicTexture, Material, MeshBuilder, StandardMaterial} from "@babylonjs/core"; +import log from "loglevel"; + + +const textLogger: log.Logger = log.getLogger('TextLabel'); + +export function updateTextNode(mesh: AbstractMesh, text: string) { + if (!mesh) { + textLogger.error("updateTextNode: mesh is null"); + return null; + } + const textNodes = mesh.getChildren((node) => { + return node.metadata?.label == true; + }); + if (textNodes && textNodes.length > 0) { + textNodes.forEach((node) => { + node.dispose(false, true); + }); + } + + if (!text) { + return null; + } + + //Set font + const height = 0.05; + const font_size = 24; + const font = "bold " + font_size + "px Arial"; + //Set height for dynamic texture + const DTHeight = 1.5 * font_size; //or set as wished + //Calc Ratio + const ratio = height / DTHeight; + + //Use a temporary dynamic texture to calculate the length of the text on the dynamic texture canvas + const temp = new DynamicTexture("DynamicTexture", 32, mesh.getScene()); + const tmpctx = temp.getContext(); + tmpctx.font = font; + const DTWidth = tmpctx.measureText(text).width + 8; + + //Calculate width the plane has to be + const planeWidth = DTWidth * ratio; + + //Create dynamic texture and write the text + const dynamicTexture = new DynamicTexture("DynamicTexture", { + width: DTWidth, + height: DTHeight + }, mesh.getScene(), false); + const mat = new StandardMaterial("mat", mesh.getScene()); + mat.diffuseTexture = dynamicTexture; + //mat.emissiveColor = Color3.White(); + dynamicTexture.drawText(text, null, null, font, "#000000", "#ffffff", true); + //Create plane and set dynamic texture as material + //const plane = MeshBuilder.CreatePlane("text" + text, {width: planeWidth, height: height}, mesh.getScene()); + const plane1 = createPlane(mat, mesh, text, planeWidth, height); + const plane2 = createPlane(mat, mesh, text, planeWidth, height); + plane2.rotation.y = Math.PI; +} + +function createPlane(mat: Material, mesh: AbstractMesh, text: string, planeWidth: number, height: number): AbstractMesh { + const plane = MeshBuilder.CreatePlane("text" + text, {width: planeWidth, height: height}, mesh.getScene()); + + plane.material = mat; + //plane.billboardMode = Mesh.BILLBOARDMODE_ALL; + plane.metadata = {exportable: true, label: true}; + + const yOffset = mesh.getBoundingInfo().boundingSphere.maximum.y; + plane.parent = mesh; + + plane.scaling.y = (1 / mesh.scaling.y); + plane.scaling.x = (1 / mesh.scaling.x); + plane.scaling.z = (1 / mesh.scaling.z); + plane.position.y = yOffset + (height * plane.scaling.y); + return plane; +} diff --git a/src/util/spinner.ts b/src/util/spinner.ts index e6c532f..2bf6a12 100644 --- a/src/util/spinner.ts +++ b/src/util/spinner.ts @@ -19,7 +19,6 @@ export class Spinner { constructor(scene: Scene) { this.scene = scene; this.build(); - } public show() { @@ -33,7 +32,7 @@ export class Spinner { } private build() { - const spinner: AbstractMesh = MeshBuilder.CreateSphere("spinner", {diameter: 1}, this.scene); + const spinner: AbstractMesh = MeshBuilder.CreateSphere("spinner", {diameter: 2}, this.scene); const material = new StandardMaterial("spinner", this.scene); const text = new DynamicTexture("spinner", {width: 1024, height: 1024}, this.scene, false); text.drawText("Please Wait", 250, 500, "bold 150px Segoe UI", "white", "transparent", true, true); @@ -82,6 +81,8 @@ export class Spinner { particleSystem.emitter = spinner; particleSystem.parent = spinner; spinner.position.y = 1; + spinner.position.z = 6; + this.spinner = spinner; this.spinner.setEnabled(false); this.particleSystem = particleSystem; diff --git a/src/vrApp.ts b/src/vrApp.ts index 29a3681..bcdc5d3 100644 --- a/src/vrApp.ts +++ b/src/vrApp.ts @@ -12,9 +12,10 @@ import {PouchdbPersistenceManager} from "./integration/pouchdbPersistenceManager import {addSceneInspector} from "./util/functions/sceneInspctor"; import {groundMeshObserver} from "./util/functions/groundMeshObserver"; import {MainMenu} from "./menus/mainMenu"; -import {Introduction} from "./tutorial/introduction"; import {buildQuestLink} from "./util/functions/buildQuestLink"; import {exportGltf} from "./util/functions/exportGltf"; +import {Tutorial} from "./tutorial/tutorial"; + export class VrApp { private scene: Scene; @@ -23,16 +24,11 @@ export class VrApp { private logger: Logger = log.getLogger('App'); constructor() { - log.setDefaultLevel('warn'); - log.getLogger('App').setLevel('debug'); log.getLogger('DiagramManager').setLevel('debug'); - const canvas = document.querySelector('#gameCanvas'); - this.logger.debug('App', 'gameCanvas created'); - } public async initialize(canvas: HTMLCanvasElement) { @@ -46,6 +42,7 @@ 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); @@ -54,18 +51,16 @@ export class VrApp { db.setDiagramManager(diagramManager); db.configObserver.add((newConfig) => { if (!newConfig.demoCompleted) { - const demo = new Introduction(scene, config); + const main = document.querySelector('#main'); + } else { + const create = document.querySelector('#create'); } config.onConfigChangedObservable.notifyObservers(newConfig, 1); }); config.onConfigChangedObservable.add((newConfig) => { db.setConfig(newConfig); }, 2, false, this); - - await db.initialize(); - - const camera: FreeCamera = new FreeCamera("Main Camera", new Vector3(0, 1.6, 0), scene); //camera.setTarget(new Vector3(0, 1.6, -3)); @@ -112,15 +107,6 @@ export class VrApp { exportGltf(scene); }) } - /* - const base = new TransformNode("chart"); - base.position.y = .25; - base.position.z = -5; - const chart = new Timeseries(base); - chart.setData(genData()); -*/ - //const newRelic = new NewRelicQuery(scene); - //newRelic.getSales(); this.logger.info('keydown event listener added, use Ctrl+Shift+Alt+I to toggle debug layer'); let i = 0; this.engine.runRenderLoop(() => {