From fbc39f21036a0e5d44a524ca13877895a8d8233f Mon Sep 17 00:00:00 2001 From: Michael Mainguy Date: Wed, 24 Apr 2024 07:19:15 -0500 Subject: [PATCH] Introduction revamp. --- src/diagram/diagramConnection.ts | 22 ++- src/toolbox/functions/buildColor.ts | 16 +-- src/tutorial/introduction.ts | 215 +++++++++------------------- src/tutorial/tutorial.ts | 24 ---- src/vrApp.ts | 3 +- 5 files changed, 88 insertions(+), 192 deletions(-) delete mode 100644 src/tutorial/tutorial.ts diff --git a/src/diagram/diagramConnection.ts b/src/diagram/diagramConnection.ts index 4b1044d..bdf0d74 100644 --- a/src/diagram/diagramConnection.ts +++ b/src/diagram/diagramConnection.ts @@ -3,13 +3,14 @@ import {v4 as uuidv4} from 'uuid'; import log, {Logger} from "loglevel"; import {buildStandardMaterial} from "../materials/functions/buildStandardMaterial"; +const logger: Logger = log.getLogger('DiagramConnection'); export class DiagramConnection { - private logger: Logger = log.getLogger('DiagramConnection'); + private readonly id: string; constructor(from: string, to: string, id: string, scene?: Scene, gripTransform?: TransformNode, clickPoint?: Vector3) { - this.logger.debug('buildConnection constructor'); + logger.debug('buildConnection constructor'); if (id) { this.id = id; } else { @@ -45,7 +46,7 @@ export class DiagramConnection { this.toAnchor = to; } else { - this.logger.info("no fromMesh yet, will build when toMesh is available"); + logger.info("no fromMesh yet, will build when toMesh is available"); } } this.buildConnection(); @@ -126,7 +127,7 @@ export class DiagramConnection { } private buildConnection() { - this.logger.debug(`buildConnection from ${this._from} to ${this._to}`); + logger.debug(`buildConnection from ${this._from} to ${this._to}`); this._mesh = MeshBuilder.CreateCylinder(this.id + "_connection", {diameter: .025, height: 1}, this.scene); this.transformNode = new TransformNode(this.id + "_transform", this.scene); this.transformNode.metadata = {exportable: true}; @@ -158,7 +159,7 @@ export class DiagramConnection { } } private removeConnection = () => { - this.logger.debug("removeConnection"); + logger.debug("removeConnection"); this.scene.onBeforeRenderObservable.removeCallback(this.beforeRender); this._mesh.onDisposeObservable.removeCallback(this.removeConnection); this.removeObserver(); @@ -175,25 +176,22 @@ export class DiagramConnection { if (this.scene) { this.scene = null; } - if (this.logger) { - this.logger = null; - } } private onMeshAdded = (mesh: AbstractMesh) => { if (mesh && mesh.id) { if (!this.toAnchor || !this.fromAnchor) { if (mesh?.id == this?._to) { - this.logger.debug("Found to anchor"); + logger.debug("Found to anchor"); this.toAnchor = mesh; this._mesh.metadata.to = this.to; } if (mesh?.id == this?._from) { - this.logger.debug("Found from anchor"); + logger.debug("Found from anchor"); this.fromAnchor = mesh; this._mesh.metadata.from = this.from; } if (this.toAnchor && this.fromAnchor) { - this.logger.debug(`connection built from ${this._from} to ${this._to}`); + logger.debug(`connection built from ${this._from} to ${this._to}`); this.removeObserver(); } } @@ -201,7 +199,7 @@ export class DiagramConnection { } private removeObserver() { - this.logger.debug("removing observer"); + logger.debug("removing observer"); this.scene.onNewMeshAddedObservable.removeCallback(this.onMeshAdded); } } diff --git a/src/toolbox/functions/buildColor.ts b/src/toolbox/functions/buildColor.ts index 00badae..65db685 100644 --- a/src/toolbox/functions/buildColor.ts +++ b/src/toolbox/functions/buildColor.ts @@ -5,22 +5,18 @@ import {buildTool} from "./buildTool"; export function buildColor(color: Color3, scene: Scene, parent: TransformNode, index: number): Node { const width = .1; - const depth = .1; - const height = .01; + const height = .1; const material = new StandardMaterial("material-" + color.toHexString(), scene); material.diffuseColor = color; material.ambientColor = color; + material.roughness = .1; + material.maxSimultaneousLights = 1; - //material.emissiveColor = new Color3(.1,.1,.1); - //material.roughness = 1; - //material.specularPower = .0001; - - const colorBoxMesh = MeshBuilder.CreateBox("toolbox-color-" + color.toHexString(), { + const colorBoxMesh = MeshBuilder.CreatePlane("toolbox-color-" + color.toHexString(), { width: width, - height: height, - depth: depth + height: height }, scene); - colorBoxMesh.rotation.x = Math.PI / 2; + //colorBoxMesh.rotation.x = Math.PI / 2; colorBoxMesh.material = material; const rowLength = 8; colorBoxMesh.position.x = -.45 + ((index % rowLength) / rowLength); diff --git a/src/tutorial/introduction.ts b/src/tutorial/introduction.ts index c1dd6b6..d849d81 100644 --- a/src/tutorial/introduction.ts +++ b/src/tutorial/introduction.ts @@ -1,88 +1,39 @@ +import log from "loglevel"; import { AbstractMesh, + ActionEvent, Color3, - DynamicTexture, MeshBuilder, - PhysicsAggregate, - PhysicsHelper, - PhysicsShapeType, Scene, StandardMaterial, Vector3, VideoTexture } from "@babylonjs/core"; -import {Button3D, GUI3DManager, TextBlock} from "@babylonjs/gui"; -import {DiaSounds} from "../util/diaSounds"; -import {AppConfig} from "../util/appConfig"; +import {DefaultScene} from "../defaultScene"; +import {HtmlButton} from "../../../babylon-html"; import Hls from "hls.js"; -import log, {Logger} from "loglevel"; +const logger = log.getLogger('Introduction'); export class Introduction { - private readonly scene: Scene; - private manager: GUI3DManager; - private physicsHelper: PhysicsHelper; - private current: AbstractMesh[] = []; - private step: number = 0; - private items: AbstractMesh[] = []; - private advance: Button3D; - private sounds: DiaSounds; - private config: AppConfig; - private logger: Logger = log.getLogger('Introduction'); - + private readonly _scene: Scene; private videoElement: HTMLVideoElement; - constructor(scene: Scene, config: AppConfig) { - this.sounds = new DiaSounds(scene); - this.scene = scene; - this.config = config; - this.manager = new GUI3DManager(scene); - this.physicsHelper = new PhysicsHelper(scene); - - this.scene.onReadyObservable.add(() => { - setTimeout((s) => { - s.start() - }, 2000, this); - }); - + constructor() { + logger.info('Introduction constructor'); + this._scene = DefaultScene.Scene; + this.initialize(); } - public start() { - this.scene.physicsEnabled = true; - this.manager.controlScaling = .5; - this.advance = new Button3D("advance"); - - const text = new TextBlock("advance", "Click Me"); - text.fontSize = "48px"; - text.color = "#ffffff"; - text.alpha = 1; - this.advance.content = text; - - this.advance.onPointerClickObservable.add(() => { - this.takeStep(); - }, -1, false, this, false); - this.manager.addControl(this.advance); - this.advance.isVisible = false; - - this.scene.onReadyObservable.add(() => { - this.advance.isVisible = true; - this.advance.node.position = new Vector3(0, .2, -1); - this.advance.node.rotation = new Vector3(0, Math.PI, 0); - }); - } - - buildVideo(src: string, size: number, position: Vector3): AbstractMesh { + buildVideo(src: string, position: Vector3): AbstractMesh { const vid = document.createElement("video"); this.videoElement = vid; vid.setAttribute('autoplay', 'true'); vid.setAttribute('playsinline', 'true'); - - vid.setAttribute('src', src); - const texture = new VideoTexture("video", vid, this.scene, true); - - const mesh = this.makeObject("video", position, size, 16 / 9); - const material = new StandardMaterial("video_material", this.scene); + const texture = new VideoTexture("video", vid, this._scene, true); + const mesh = this.makeObject("video", position); + const material = new StandardMaterial("video_material", this._scene); material.diffuseTexture = texture; material.diffuseColor = new Color3(1, 1, 1); material.emissiveColor = new Color3(1, 1, 1); @@ -104,99 +55,73 @@ export class Introduction { }); }); } + //document.body.appendChild(vid); + mesh.metadata = {video: vid}; return mesh; } - makeObject(text: string, position: Vector3, size: number, ratio: number = 2): AbstractMesh { - const welcome = MeshBuilder.CreateTiledBox(text + "_box", {width: 1, height: 1, depth: 1}, this.scene); - welcome.position = position; - welcome.scaling = new Vector3(size, size / ratio, size); - - const aggregate = new PhysicsAggregate(welcome, PhysicsShapeType.BOX, { - friction: 1, - mass: 1, - restitution: .1 - }, this.scene); - aggregate.body.getCollisionObservable().add((collider) => { - if (collider.impulse < .5) { - return; - } - let volume = 0; - const sound = this.sounds.bounce; - if (collider.impulse > 1 && collider.impulse < 10) { - volume = collider.impulse / 10; - } - if (volume > 0) { - sound.attachToMesh(aggregate.body.transformNode); - sound.updateOptions({offset: 0, volume: volume, length: .990}); - - sound.play(); - } - }); - aggregate.body.setCollisionCallbackEnabled(true); - - return welcome; + private initialize() { + /* + const talkTrack = new Sound("talkTrack", "assets/sounds/introTalkTrack.mp3", this._scene, () => { + this.ready(); + }, { + loop: false, + autoplay: false, + volume: 1 + });*/ + this.ready(); } - 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 = 1; - (mesh.material as StandardMaterial).diffuseTexture = texture; - texture.update(); - return mesh; + private ready() { + const startButton = this.buildButton('Begin Tutorial'); + startButton.onPointerObservable.add((eventData: ActionEvent) => { + if (eventData.sourceEvent.type === "pointerup") { + this.start(startButton); + } + }, -1, true, this, false); + } - private takeStep() { - this.current.forEach((mesh) => { - const pos = mesh.physicsBody.transformNode.absolutePosition.clone(); - pos.x = pos.x - .1; - mesh.physicsBody.applyImpulse(new Vector3(0, 10, -12), pos); - }); + private buildButton(name: string): HtmlButton { + const button = new HtmlButton(name, name, this._scene, null, + {html: null, image: {width: 512, height: 512}, width: .5, height: .5}); + button.transform.position.y = .4; + return button; + } - switch (this.step) { - case 0: - this.items.push(this.buildText("Welcome To", 3, 1024, new Vector3(0, 15, -4))); - this.items.push(this.buildText("Deep Diagram", 5, 1024, new Vector3(0, 10, -4))); - this.current = this.items.slice(-2); - break; - case 1: - this.items.push(this.buildText("Let us show you", 3, 1024, new Vector3(2, 16, -5))); - this.items.push(this.buildText("what you can build", 4, 1200, new Vector3(-1.6, 12, -5))); - this.current = this.items.slice(-2); - break; - case 2: - this.items.push(this.buildText("A quick video", 5, 1024, new Vector3(0, 15, -5))); - this.current = this.items.slice(-1); - break; - case 3: + private start(prev: HtmlButton) { + prev.dispose(); + const controllerButton = this.buildButton('Controllers'); + const video = this.buildVideo('https://customer-l4pyjzbav11fzy04.cloudflarestream.com/8b906146c75bb5d81e03d199707ed0e9/manifest/video.m3u8', new Vector3(0, 1.8, -.5)); + controllerButton.onPointerObservable.add((eventData: ActionEvent) => { + if (eventData.sourceEvent.type === "pointerup") { + this.controllers(controllerButton, video); + } + }, -1, true, this, false); - const src = 'https://customer-l4pyjzbav11fzy04.cloudflarestream.com/8b906146c75bb5d81e03d199707ed0e9/manifest/video.m3u8' - this.items.push(this.buildVideo(src, 7, new Vector3(0, 15, -6))); - this.current = this.items.slice(-1); - break; - case 4: - this.items.forEach((mesh) => { - mesh.physicsBody.dispose(); - mesh.dispose(); - }); - this.advance.dispose(); - this.manager.dispose(); - this.config.setDemoCompleted(true); - this.items = []; - if (this.videoElement) { - this.videoElement.pause(); - this.videoElement.remove(); - this.videoElement = null; - } + } + + private controllers(prev: HtmlButton, prevVideo: AbstractMesh) { + if (prevVideo.metadata) { + prevVideo.metadata.video.pause(); + prevVideo.metadata.video.remove(); + prevVideo.dispose(); } - this.step++; + prev.dispose(); + const controllerButton = this.buildButton('Controllers 2'); + const video = this.buildVideo('https://customer-l4pyjzbav11fzy04.cloudflarestream.com/8b906146c75bb5d81e03d199707ed0e9/manifest/video.m3u8', new Vector3(0, 1.8, -.5)); + } + + private showVideo(url: string) { } + private makeObject(text: string, position: Vector3): AbstractMesh { + const videoScale = 2.8; + const video = MeshBuilder.CreatePlane(text + "_plane", {width: 1.6, height: .9}, this._scene); + video.rotation.y = Math.PI; + video.scaling.set(videoScale, videoScale, videoScale); + video.position = position; + return video; + } } \ No newline at end of file diff --git a/src/tutorial/tutorial.ts b/src/tutorial/tutorial.ts deleted file mode 100644 index b2fa786..0000000 --- a/src/tutorial/tutorial.ts +++ /dev/null @@ -1,24 +0,0 @@ -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(); - }); - } - - - } - - private advance() { - window.alert('here'); - } -} \ No newline at end of file diff --git a/src/vrApp.ts b/src/vrApp.ts index 9fcac42..3a1074d 100644 --- a/src/vrApp.ts +++ b/src/vrApp.ts @@ -29,6 +29,7 @@ export class VrApp { public async initialize() { const scene = DefaultScene.Scene; + const spinner = new Spinner(); spinner.show(); @@ -59,11 +60,11 @@ export class VrApp { }) } this.logger.info('keydown event listener added, use Ctrl+Shift+Alt+I to toggle debug layer'); + //const intro = new Introduction(); this.engine.runRenderLoop(() => { scene.render(); }); this.logger.info('Render loop started'); - } private async initializeEngine() {