From a37618737a634bce8dd7982dd0abd2feef743926 Mon Sep 17 00:00:00 2001 From: Michael Mainguy Date: Fri, 18 Aug 2023 09:49:45 -0500 Subject: [PATCH] Added some missing html5 boilerplate and service worker. --- src/app.ts | 7 +- src/tutorial/introduction.ts | 123 ++++++++++++++++++++++++++++++++++ src/util/customEnvironment.ts | 8 ++- src/util/diaSounds.ts | 29 ++++---- 4 files changed, 152 insertions(+), 15 deletions(-) create mode 100644 src/tutorial/introduction.ts diff --git a/src/app.ts b/src/app.ts index 8640e63..2f62fb6 100644 --- a/src/app.ts +++ b/src/app.ts @@ -18,6 +18,7 @@ import {CustomEnvironment} from "./util/customEnvironment"; import {VoiceManager} from "./integration/voiceManager"; import {TranscriptType} from "./integration/voiceTranscript"; import {Controllers} from "./controllers/controllers"; +import {Introduction} from "./tutorial/introduction"; export class App { @@ -59,9 +60,9 @@ export class App { const environment = new CustomEnvironment(scene); - const camera: ArcRotateCamera = new ArcRotateCamera("Camera", Math.PI / 2, Math.PI / 2, 2, + const camera: ArcRotateCamera = new ArcRotateCamera("Camera", -Math.PI / 2, Math.PI / 2, 4, new Vector3(0, 1.6, 0), scene); - camera.radius = 0; + camera.attachControl(canvas, true); new HemisphericLight("light1", new Vector3(1, 1, 0), scene); @@ -103,6 +104,8 @@ export class App { diagramManager.setPersistenceManager(persistenceManager); AppConfig.config.setPersistenceManager(persistenceManager); persistenceManager.initialize(); + const intro = new Introduction(scene); + intro.start(); //const newRelicData = new NewRelicData(persistenceManager, scene); }); diff --git a/src/tutorial/introduction.ts b/src/tutorial/introduction.ts new file mode 100644 index 0000000..85563b5 --- /dev/null +++ b/src/tutorial/introduction.ts @@ -0,0 +1,123 @@ +import { + AbstractMesh, + DynamicTexture, + MeshBuilder, + PhysicsAggregate, + PhysicsHelper, + PhysicsShapeType, + Scene, + StandardMaterial, + Vector3, + VideoTexture +} from "@babylonjs/core"; +import {Button3D, GUI3DManager, TextBlock} from "@babylonjs/gui"; +import {DiaSounds} from "../util/diaSounds"; + + +export class Introduction { + private scene: Scene; + private manager: GUI3DManager; + private physicsHelper: PhysicsHelper; + private current: AbstractMesh[] = []; + private step: number = 0; + private items: AbstractMesh[] = []; + + constructor(scene: Scene) { + this.scene = scene; + this.manager = new GUI3DManager(scene); + this.physicsHelper = new PhysicsHelper(scene); + } + + public start() { + this.scene.physicsEnabled = true; + const advance = new Button3D("advance"); + const text = new TextBlock("advance", "Click Me"); + text.fontSize = "48px"; + text.color = "#ffffff"; + text.alpha = 1; + advance.content = text; + + advance.onPointerClickObservable.add(() => { + console.log("click"); + this.takeStep(); + }, -1, false, this, false); + this.manager.addControl(advance); + advance.isVisible = false; + advance.position.y = 0; + advance.position.x = 2; + this.scene.onReadyObservable.add(() => { + advance.isVisible = true; + }); + + } + + buildVideo(url: string, size: number, position: Vector3): AbstractMesh { + const texture = new VideoTexture("video", url, this.scene, true); + const mesh = this.makeObject("video", position, size); + mesh.material = new StandardMaterial("video_material", this.scene); + (mesh.material as StandardMaterial).diffuseTexture = texture; + texture.update(); + return mesh; + } + + makeObject(text: string, position: Vector3, size: number): AbstractMesh { + const welcome = MeshBuilder.CreateTiledBox(text + "_box", {width: 1, height: 1, depth: 1}, this.scene); + welcome.position = position; + welcome.scaling = new Vector3(size, size / 2, size); + const aggregate = new PhysicsAggregate(welcome, PhysicsShapeType.BOX, { + friction: 1, + mass: 1, + restitution: .1 + }, this.scene); + aggregate.body.getCollisionObservable().add((collider) => { + if (collider.impulse > .4) { + DiaSounds.instance.low.play(); + } + }); + aggregate.body.setCollisionCallbackEnabled(true); + welcome.isPickable = true; + return welcome; + } + + buildText(text: string, size: number, textureSize: number, position: Vector3): AbstractMesh { + const mesh = this.makeObject(text, position, size); + const texture = new DynamicTexture("dynamic texture", { + width: textureSize, + height: textureSize / 2 + }, this.scene, true); + texture.drawText(text, null, null, "bold 128px Arial", "white", "#00f", true, true); + mesh.material = new StandardMaterial(text + "_material", this.scene); + mesh.material.alpha = .9; + (mesh.material as StandardMaterial).diffuseTexture = texture; + texture.update(); + return mesh; + } + + private takeStep() { + this.current.forEach((mesh) => { + const pos = mesh.getAbsolutePosition(); + pos.x = pos.x - .1; + mesh.physicsBody.applyImpulse(new Vector3(0, 5, 16), pos); + }); + + switch (this.step) { + case 0: + this.items.push(this.buildText("Welcome To", 1.5, 1024, new Vector3(0, 7, 5))); + this.items.push(this.buildText("Deep Diagram", 2, 1024, new Vector3(0, 5, 5))); + this.current = this.items.slice(-2); + break; + case 1: + this.items.push(this.buildText("Let us show you", 2.3, 1024, new Vector3(0, 8, 5))); + this.items.push(this.buildText("what you can build", 3, 1200, new Vector3(0, 5, 5))); + this.current = this.items.slice(-2); + break; + case 2: + this.items.push(this.buildText("A quick video", 2, 1024, new Vector3(0, 5, 5))); + case 3: + this.items.push(this.buildVideo("A quick video", 2, new Vector3(0, 5, 5))); + } + this.step++; + + } + +} \ No newline at end of file diff --git a/src/util/customEnvironment.ts b/src/util/customEnvironment.ts index 97429a8..fca23d7 100644 --- a/src/util/customEnvironment.ts +++ b/src/util/customEnvironment.ts @@ -20,7 +20,7 @@ export class CustomEnvironment { constructor(scene: Scene, name: string = "default") { this.scene = scene; this.name = name; - new DiaSounds(scene); + const physics = new CustomPhysics(this.scene); physics .initializeAsync() @@ -31,6 +31,12 @@ export class CustomEnvironment { const photo = new PhotoDome('sky', '/assets/textures/outdoor_field2.jpeg', {}, scene); + try { + new DiaSounds(scene); + } catch (error) { + console.log(error); + } + } diff --git a/src/util/diaSounds.ts b/src/util/diaSounds.ts index a4381c0..c6555d0 100644 --- a/src/util/diaSounds.ts +++ b/src/util/diaSounds.ts @@ -3,6 +3,18 @@ import {Scene, Sound} from "@babylonjs/core"; export class DiaSounds { private readonly scene: Scene; + private readonly _birds: Sound; + + private static _instance: DiaSounds; + + public static get instance() { + return DiaSounds._instance; + } + + public get tick() { + return new Sound("tick", '/assets/sounds/tick.mp3', this.scene); + } + constructor(scene: Scene) { this.scene = scene; this._enter = new Sound("enter", "/assets/sounds/sounds.mp3", this.scene, null, { @@ -29,20 +41,13 @@ export class DiaSounds { offset: 3, length: 1.0 }); - this._enter.autoplay = true; + this._birds = new Sound("birds", "/assets/sounds/birds.mp3", this.scene, null, { + autoplay: true, + loop: true + }); + //this._enter.autoplay = true; DiaSounds._instance = this; } - - private static _instance: DiaSounds; - - public static get instance() { - return DiaSounds._instance; - } - - public get tick() { - return new Sound("tick", '/assets/sounds/tick.mp3', this.scene); - } - private readonly _enter: Sound; public get enter() {