Introduction revamp.

This commit is contained in:
Michael Mainguy 2024-04-24 07:19:15 -05:00
parent c81dd8c24a
commit fbc39f2103
5 changed files with 88 additions and 192 deletions

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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');
}
}

View File

@ -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() {