diff --git a/src/controllers/rigplatform.ts b/src/controllers/rigplatform.ts index fd02237..c163415 100644 --- a/src/controllers/rigplatform.ts +++ b/src/controllers/rigplatform.ts @@ -107,11 +107,11 @@ export class Rigplatform { new PhysicsAggregate( this.rigMesh, PhysicsShapeType.CYLINDER, - {friction: 1, center: Vector3.Zero(), radius: .5, mass: 10, restitution: .01}, + {friction: 0, center: Vector3.Zero(), radius: .5, mass: 10, restitution: .01}, scene); rigAggregate.body.setMotionType(PhysicsMotionType.DYNAMIC); - rigAggregate.body.setGravityFactor(.001); + rigAggregate.body.setGravityFactor(.02); this.fixRotation(); this.body = rigAggregate.body; @@ -191,7 +191,7 @@ export class Rigplatform { }); } private fixRotation() { - this.scene.registerBeforeRender(() => { + this.scene.onAfterPhysicsObservable.add(() => { if (AppConfig?.config?.currentTurnSnap?.value > 0) { const q = this.rigMesh.rotationQuaternion; this.body.setAngularVelocity(Vector3.Zero()); @@ -203,7 +203,6 @@ export class Rigplatform { } else { this.body.setAngularVelocity(Vector3.Up().scale(this.turnVelocity)); } - - }); + }, -1, false, this, false); } } \ No newline at end of file diff --git a/src/diagram/diagramManager.ts b/src/diagram/diagramManager.ts index 88d4407..d1c7bab 100644 --- a/src/diagram/diagramManager.ts +++ b/src/diagram/diagramManager.ts @@ -28,6 +28,7 @@ export class DiagramManager { private persistenceManager: IPersistenceManager = null; private readonly scene: Scene; private xr: WebXRExperienceHelper; + private sounds: DiaSounds; public setPersistenceManager(persistenceManager: IPersistenceManager) { @@ -48,12 +49,13 @@ export class DiagramManager { private controllers: Controllers; constructor(scene: Scene, xr: WebXRExperienceHelper, controllers: Controllers) { + this.sounds = new DiaSounds(scene); this.scene = scene; this.xr = xr; this.controllers = controllers; this.actionManager = new ActionManager(this.scene); this.actionManager.registerAction( - new PlaySoundAction(ActionManager.OnPointerOverTrigger, DiaSounds.instance.tick)); + new PlaySoundAction(ActionManager.OnPointerOverTrigger, this.sounds.tick)); this.actionManager.registerAction( new ExecuteCodeAction(ActionManager.OnPointerOverTrigger, (evt) => { this.controllers.controllerObserver.notifyObservers({ @@ -106,7 +108,7 @@ export class DiagramManager { newMesh.material = mesh.material; newMesh.metadata = this.deepCopy(mesh.metadata); - DiagramShapePhysics.applyPhysics(newMesh, this.scene); + DiagramShapePhysics.applyPhysics(this.sounds, newMesh, this.scene); this.persistenceManager.add(newMesh); return newMesh; } @@ -143,7 +145,7 @@ export class DiagramManager { if (event.parent) { mesh.parent = this.scene.getMeshById(event.parent); } - DiagramShapePhysics.applyPhysics(mesh, this.scene, PhysicsMotionType.DYNAMIC); + DiagramShapePhysics.applyPhysics(this.sounds, mesh, this.scene, PhysicsMotionType.DYNAMIC); } private onDiagramEvent(event: DiagramEvent) { @@ -165,7 +167,7 @@ export class DiagramManager { mesh = MeshConverter.fromDiagramEntity(event.entity, this.scene); if (mesh) { mesh.actionManager = this.actionManager; - DiagramShapePhysics.applyPhysics(mesh, this.scene, PhysicsMotionType.DYNAMIC); + DiagramShapePhysics.applyPhysics(this.sounds, mesh, this.scene, PhysicsMotionType.DYNAMIC); } } @@ -188,12 +190,12 @@ export class DiagramManager { mesh.actionManager = this.actionManager; } DiagramShapePhysics - .applyPhysics(mesh, this.scene); + .applyPhysics(this.sounds, mesh, this.scene); break; case DiagramEventType.MODIFY: this.getPersistenceManager()?.modify(mesh); DiagramShapePhysics - .applyPhysics(mesh, this.scene); + .applyPhysics(this.sounds, mesh, this.scene); break; case DiagramEventType.CHANGECOLOR: if (!event.oldColor) { @@ -219,7 +221,7 @@ export class DiagramManager { this.getPersistenceManager()?.remove(mesh) mesh?.physicsBody?.dispose(); mesh.dispose(); - DiaSounds.instance.exit.play(); + this.sounds.exit.play(); } break; @@ -231,7 +233,7 @@ export class DiagramManager { class DiagramShapePhysics { private static logger: log.Logger = log.getLogger('DiagramShapePhysics'); - public static applyPhysics(mesh: AbstractMesh, scene: Scene, motionType?: PhysicsMotionType) { + public static applyPhysics(sounds: DiaSounds, mesh: AbstractMesh, scene: Scene, motionType?: PhysicsMotionType) { if (!AppConfig.config.physicsEnabled) { return; } @@ -285,10 +287,13 @@ class DiagramShapePhysics { } } body.setCollisionCallbackEnabled(true); - body.getCollisionObservable().add((event, state) => { - if (event.distance > .001 && !DiaSounds.instance.low.isPlaying) { - this.logger.debug(event, state); - DiaSounds.instance.low.play(); + body.getCollisionObservable().add((event) => { + + if (event.impulse < 10 && event.impulse > 1) { + const sound = sounds.bounce; + sound.setVolume(event.impulse / 10); + sound.attachToMesh(mesh); + sound.play(); } }, -1, false, this); //body.setMotionType(PhysicsMotionType.ANIMATED); diff --git a/src/menus/configMenu.ts b/src/menus/configMenu.ts index a7ebcc1..888bdcf 100644 --- a/src/menus/configMenu.ts +++ b/src/menus/configMenu.ts @@ -8,12 +8,14 @@ import {DiaSounds} from "../util/diaSounds"; import {BaseMenu} from "./baseMenu"; export class ConfigMenu extends BaseMenu { + private sounds: DiaSounds; private configPlane: AbstractMesh = null; private yObserver; constructor(scene: Scene, xr: WebXRExperienceHelper, controllers: Controllers) { super(scene, xr, controllers); + this.sounds = new DiaSounds(scene); if (!this.yObserver) { this.controllers.controllerObserver.add((event) => { if (event.type == 'y-button') { @@ -26,12 +28,12 @@ export class ConfigMenu extends BaseMenu { public toggle() { if (this.configPlane) { - DiaSounds.instance.exit.play(); + this.sounds.exit.play(); this.configPlane.dispose(); this.configPlane = null; return; } - DiaSounds.instance.enter.play(); + this.sounds.enter.play(); const width = .25; const height = .75; const res = 256; diff --git a/src/menus/editMenu.ts b/src/menus/editMenu.ts index ec1919a..31d751b 100644 --- a/src/menus/editMenu.ts +++ b/src/menus/editMenu.ts @@ -37,6 +37,7 @@ export class EditMenu { private connection: DiagramConnection = null; private panel: PlanePanel; private buttonMaterial: StandardMaterial; + private sounds: DiaSounds; private get isVisible(): boolean { return this.panel.isVisible; @@ -49,37 +50,10 @@ export class EditMenu { }); } - toggle() { - if (this.isVisible) { - DiaSounds.instance.exit.play(); - this.isVisible = false; - - } else { - DiaSounds.instance.enter.play(); - CameraHelper.setMenuPosition(this.manager.rootContainer.children[0].node, this.scene); - this.isVisible = true; - } - } - private getTool(template: string, color: Color3): Mesh { - const baseMeshId = 'tool-' + template + '-' + color.toHexString(); - return (this.scene.getMeshById(baseMeshId) as Mesh); - } - - private persist(mesh: AbstractMesh, text: string) { - if (mesh.metadata) { - mesh.metadata.text = text; - } else { - this.logger.error("mesh has no metadata"); - } - this.diagramManager.onDiagramEventObservable.notifyObservers({ - type: DiagramEventType.MODIFY, - entity: MeshConverter.toDiagramEntity(mesh), - }); - } - constructor(scene: Scene, xr: WebXRDefaultExperience, diagramManager: DiagramManager) { this.scene = scene; this.xr = xr; + this.sounds = new DiaSounds(scene); this.diagramManager = diagramManager; this.gizmoManager = new GizmoManager(scene); this.gizmoManager.boundingBoxGizmoEnabled = true; @@ -132,6 +106,34 @@ export class EditMenu { this.panel = panel; this.isVisible = false; } + private getTool(template: string, color: Color3): Mesh { + const baseMeshId = 'tool-' + template + '-' + color.toHexString(); + return (this.scene.getMeshById(baseMeshId) as Mesh); + } + + private persist(mesh: AbstractMesh, text: string) { + if (mesh.metadata) { + mesh.metadata.text = text; + } else { + this.logger.error("mesh has no metadata"); + } + this.diagramManager.onDiagramEventObservable.notifyObservers({ + type: DiagramEventType.MODIFY, + entity: MeshConverter.toDiagramEntity(mesh), + }); + } + + toggle() { + if (this.isVisible) { + this.sounds.exit.play(); + this.isVisible = false; + + } else { + this.sounds.enter.play(); + CameraHelper.setMenuPosition(this.manager.rootContainer.children[0].node, this.scene); + this.isVisible = true; + } + } makeButton(name: string, id: string) { const button = new Button3D(name); @@ -296,7 +298,7 @@ export class EditMenu { this.showNewRelic(); break; case "export": - GLTF2Export.GLTFAsync(this.scene, 'diagram.gltf', { + GLTF2Export.GLBAsync(this.scene, 'diagram.glb', { shouldExportNode: function (node) { if (node?.metadata?.template) { return true; diff --git a/src/tutorial/introduction.ts b/src/tutorial/introduction.ts index da485f1..62ca5e7 100644 --- a/src/tutorial/introduction.ts +++ b/src/tutorial/introduction.ts @@ -25,12 +25,14 @@ export class Introduction { private step: number = 0; private items: AbstractMesh[] = []; private advance: Button3D; + private sounds: DiaSounds; + constructor(scene: Scene) { + this.sounds = new DiaSounds(scene); this.scene = scene; this.manager = new GUI3DManager(scene); this.physicsHelper = new PhysicsHelper(scene); } - public start() { this.scene.physicsEnabled = true; this.advance = new Button3D("advance"); @@ -96,8 +98,19 @@ export class Introduction { restitution: .1 }, this.scene); aggregate.body.getCollisionObservable().add((collider) => { - if (collider.impulse > .4) { - DiaSounds.instance.low.play(); + 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}); + console.log(volume); + sound.play(); } }); aggregate.body.setCollisionCallbackEnabled(true); diff --git a/src/util/diaSounds.ts b/src/util/diaSounds.ts index c6555d0..dc0c0ea 100644 --- a/src/util/diaSounds.ts +++ b/src/util/diaSounds.ts @@ -5,49 +5,11 @@ export class DiaSounds { 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, { - autoplay: false, - loop: false, - offset: 0, - length: 1.0 - }); - this._exit = new Sound("exit", "/assets/sounds/sounds.mp3", this.scene, null, { - autoplay: false, - loop: false, - offset: 1, - length: 1.0 - }); - this._high = new Sound("high", "/assets/sounds/sounds.mp3", this.scene, null, { - autoplay: false, - loop: false, - offset: 2, - length: 1.0 - }); - this._low = new Sound("low", "/assets/sounds/sounds.mp3", this.scene, null, { - autoplay: false, - loop: false, - offset: 3, - length: 1.0 - }); - this._birds = new Sound("birds", "/assets/sounds/birds.mp3", this.scene, null, { - autoplay: true, - loop: true - }); - //this._enter.autoplay = true; - DiaSounds._instance = this; - } + private volume: number = 0.8; + private readonly _bounce; private readonly _enter: Sound; public get enter() { @@ -71,4 +33,60 @@ export class DiaSounds { public get low() { return this._low; } + + constructor(scene: Scene) { + this.scene = scene; + this._enter = new Sound("enter", "/assets/sounds/sounds.mp3", this.scene, null, { + autoplay: false, + loop: false, + volume: this.volume, + offset: 0, + length: 1.0 + }); + this._exit = new Sound("exit", "/assets/sounds/sounds.mp3", this.scene, null, { + autoplay: false, + loop: false, + offset: 1, + volume: this.volume, + length: 1.0 + }); + this._high = new Sound("high", "/assets/sounds/sounds.mp3", this.scene, null, { + autoplay: false, + loop: false, + offset: 2, + volume: this.volume, + length: 1.0 + }); + this._low = new Sound("low", "/assets/sounds/sounds.mp3", this.scene, null, { + autoplay: false, + loop: false, + offset: 3, + volume: this.volume, + length: 1.0 + }); + + + this._bounce = new Sound("bounce", "/assets/sounds/drumsprite.mp3", this.scene, null, { + autoplay: false, + loop: false, + offset: 0, + length: 0.990 + }); + + + this._birds = new Sound("birds", "/assets/sounds/birds.mp3", this.scene, null, { + autoplay: true, + loop: true + }); + //this._enter.autoplay = true; + } + + public get bounce() { + const bounce = this._bounce.clone(); + bounce.updateOptions({offset: 0, volume: this.volume, length: .990}); + bounce.onEndedObservable.add(() => { + bounce.dispose(); + }); + return bounce; + } }