From 166d2866b3e427339082f6bbdc7d391d4b91e784 Mon Sep 17 00:00:00 2001 From: ShuangLiu Date: Fri, 15 Sep 2023 21:46:29 +0800 Subject: [PATCH] feat(audio): move audio to @orillusion/media-extension add audio samples --- .../media-extention}/AudioListener.ts | 6 +- .../media-extention}/PositionAudio.ts | 21 +-- .../media-extention}/StaticAudio.ts | 7 +- packages/media-extention/index.ts | 5 +- packages/media-extention/package.json | 2 +- samples/audio/Sample_DynamicAudio.ts | 139 ++++++++++++++++++ samples/audio/Sample_StaticAudio.ts | 105 +++++++++++++ src/index.ts | 3 - 8 files changed, 260 insertions(+), 28 deletions(-) rename {src/components/audio => packages/media-extention}/AudioListener.ts (95%) rename {src/components/audio => packages/media-extention}/PositionAudio.ts (91%) rename {src/components/audio => packages/media-extention}/StaticAudio.ts (95%) create mode 100644 samples/audio/Sample_DynamicAudio.ts create mode 100644 samples/audio/Sample_StaticAudio.ts diff --git a/src/components/audio/AudioListener.ts b/packages/media-extention/AudioListener.ts similarity index 95% rename from src/components/audio/AudioListener.ts rename to packages/media-extention/AudioListener.ts index 0148945b..bc02ffd9 100644 --- a/src/components/audio/AudioListener.ts +++ b/packages/media-extention/AudioListener.ts @@ -1,4 +1,4 @@ -import { ComponentBase } from '../ComponentBase'; +import { ComponentBase } from '@orillusion/core'; /** * Audio Listener @@ -14,9 +14,6 @@ export class AudioListener extends ComponentBase { this.context = new AudioContext(); this.gain = this.context.createGain(); this.gain.connect(this.context.destination); - } - public start() { - } public onUpdate() { if (!this.context) { @@ -45,7 +42,6 @@ export class AudioListener extends ComponentBase { listener.setOrientation(_orientation.x, _orientation.y, _orientation.z, up.x, up.y, up.z); } } - destroy() { this.gain.disconnect(); this.context.close(); diff --git a/src/components/audio/PositionAudio.ts b/packages/media-extention/PositionAudio.ts similarity index 91% rename from src/components/audio/PositionAudio.ts rename to packages/media-extention/PositionAudio.ts index 6b48cbc2..f42f3942 100644 --- a/src/components/audio/PositionAudio.ts +++ b/packages/media-extention/PositionAudio.ts @@ -1,9 +1,4 @@ -import { Object3D } from '../../core/entities/Object3D'; -import { UnLitMaterial } from '../../materials/UnLitMaterial'; -import { Color } from '../../math/Color'; -import { Vector3 } from '../../math/Vector3'; -import { BoxGeometry } from '../../shape/BoxGeometry'; -import { MeshRenderer } from '../renderer/MeshRenderer'; +import { BoxGeometry, Color, MeshRenderer, Object3D, UnLitMaterial, Vector3 } from '@orillusion/core'; import { AudioListener } from './AudioListener'; import { StaticAudio } from './StaticAudio'; /** @@ -20,8 +15,8 @@ export class PositionAudio extends StaticAudio { constructor() { super(); } - public setLister(listener: AudioListener): this { - super.setLister(listener); + public setLisenter(listener: AudioListener): this { + super.setLisenter(listener); this.panner = this.context?.createPanner() as PannerNode; this.panner.panningModel = 'HRTF'; this.panner.connect(this.gainNode as GainNode); @@ -41,7 +36,6 @@ export class PositionAudio extends StaticAudio { let refLength = this.panner.refDistance; let maxLength = this.panner.maxDistance; let box = new BoxGeometry(1, 1, 1); - let m1 = new UnLitMaterial(); m1.baseColor = new Color(1, 0, 0); let m2 = new UnLitMaterial(); @@ -50,6 +44,7 @@ export class PositionAudio extends StaticAudio { m3.baseColor = new Color(0, 1, 0); let m4 = new UnLitMaterial(); m4.baseColor = new Color(1, 1, 0); + for (let i = 0; i < this._step; i++) { let group = new Object3D(); let angle = (i * outerAngle) / (this._step - 1); @@ -83,10 +78,10 @@ export class PositionAudio extends StaticAudio { } public hideHelper() { this._helper = false; - for (let l of this._lines) { - l.removeAllChild(); - l.removeFromParent(); - l.destroy(); + for(let g of this._lines){ + while(g.entityChildren.length > 0) + g.entityChildren[0].destroy() + g.destroy() } this._lines.length = 0; } diff --git a/src/components/audio/StaticAudio.ts b/packages/media-extention/StaticAudio.ts similarity index 95% rename from src/components/audio/StaticAudio.ts rename to packages/media-extention/StaticAudio.ts index 1b5f5010..a5eb2efa 100644 --- a/src/components/audio/StaticAudio.ts +++ b/packages/media-extention/StaticAudio.ts @@ -1,4 +1,4 @@ -import { ComponentBase } from '../ComponentBase'; +import { ComponentBase } from '@orillusion/core'; import { AudioListener } from './AudioListener'; /** * Static audio component, volume level does not vary depending on the position of the monitor @@ -20,7 +20,7 @@ export class StaticAudio extends ComponentBase { constructor() { super(); } - public setLister(listener: AudioListener): this { + public setLisenter(listener: AudioListener): this { this.listener = listener; this.context = listener.context as AudioContext; this.gainNode = this.context.createGain(); @@ -103,9 +103,6 @@ export class StaticAudio extends ComponentBase { protected connect() { this.source?.connect(this.gainNode as GainNode); } - public onUpdate() { - super.onUpdate(); - } public destroy(force?: boolean) { this.stop(); this.gainNode?.disconnect(); diff --git a/packages/media-extention/index.ts b/packages/media-extention/index.ts index f031cc34..89f8d3da 100644 --- a/packages/media-extention/index.ts +++ b/packages/media-extention/index.ts @@ -2,5 +2,8 @@ import { ChromaKeyMaterial } from './ChromaKeyMaterial' import { ImageMaterial } from './ImageMaterial' import { VideoMaterial } from './VideoMaterial' import { VideoTexture } from './VideoTexture' +import { AudioListener } from './AudioListener' +import { PositionAudio } from './PositionAudio' +import { StaticAudio } from './StaticAudio' -export {ChromaKeyMaterial, ImageMaterial, VideoMaterial, VideoTexture} \ No newline at end of file +export {ChromaKeyMaterial, ImageMaterial, VideoMaterial, VideoTexture, AudioListener, StaticAudio, PositionAudio} \ No newline at end of file diff --git a/packages/media-extention/package.json b/packages/media-extention/package.json index 3b242137..13e92ff0 100644 --- a/packages/media-extention/package.json +++ b/packages/media-extention/package.json @@ -1,6 +1,6 @@ { "name": "@orillusion/media-extention", - "version": "0.2.3", + "version": "0.3.1", "author": "Orillusion", "description": "Orillusion Media Material Extention", "main": "./dist/media.umd.js", diff --git a/samples/audio/Sample_DynamicAudio.ts b/samples/audio/Sample_DynamicAudio.ts new file mode 100644 index 00000000..73efc9ae --- /dev/null +++ b/samples/audio/Sample_DynamicAudio.ts @@ -0,0 +1,139 @@ +import { BoxGeometry, Camera3D, DirectLight, Engine3D, LitMaterial, KelvinUtil, MeshRenderer, Object3D, Scene3D, Vector3, Color, OrbitController, View3D, AtmosphericComponent } from '@orillusion/core'; +import { PositionAudio, AudioListener } from '@orillusion/media-extention' +import { GUIHelp } from '@orillusion/debug/GUIHelp'; + +export class Static_Audio { + lightObj: Object3D; + scene: Scene3D; + camera: Object3D + mats: any[]; + audio: PositionAudio + private a = 40 + private b = 80 + private angle = 0 + constructor() {} + + async run() { + Engine3D.setting.shadow.autoUpdate = true; + Engine3D.setting.shadow.updateFrameRate = 1; + Engine3D.setting.shadow.type = 'HARD'; + Engine3D.setting.shadow.shadowBound = 100; + + await Engine3D.init({ + renderLoop: this.loop.bind(this) + }); + this.scene = new Scene3D(); + this.scene.addComponent(AtmosphericComponent); + + this.camera = new Object3D() + this.camera.localPosition = new Vector3(0, 20, 50) + let mainCamera = this.camera.addComponent(Camera3D) + this.scene.addChild(this.camera) + + mainCamera.perspective(60, Engine3D.aspect, 0.1, 20000.0); + let orbit = this.camera.addComponent(OrbitController) + orbit.target = new Vector3(0, 4, 0) + orbit.minDistance = 10 + orbit.maxDistance = 200 + + let view = new View3D(); + view.scene = this.scene; + view.camera = mainCamera; + + Engine3D.startRenderView(view); + await this.initScene(); + } + + async initScene() { + { + let [speaker, man, music] = await Promise.all([ + Engine3D.res.loadGltf('gltfs/speaker/scene.gltf'), + Engine3D.res.loadGltf('gltfs/glb/CesiumMan.glb'), + fetch('https://cdn.orillusion.com/audio.ogg').then(res=>res.arrayBuffer()) + ]) + speaker.localScale.set(4,4,4) + speaker.rotationX = -120 + speaker.y = 0.5 + let group = new Object3D() + group.addChild(speaker) + group.y = 2 + this.scene.addChild(group) + + man.name = 'man' + man.scaleX = 10; + man.scaleY = 10; + man.scaleZ = 10; + man.rotationX = -90; + man.rotationY = -90 + man.localPosition.set(0, 0.5, 30) + this.scene.addChild(man) + + let listener = man.addComponent(AudioListener) + let audio = group.addComponent(PositionAudio) + audio.setLisenter(listener) + await audio.loadBuffer(music) + audio.refDistance = 10; + audio.maxDistance = 100; + audio.setDirectionalCone( 180, 230, 0.1 ); + audio.showHelper() + + GUIHelp.init(); + GUIHelp.addButton('play', ()=>{ + audio.play() + }) + GUIHelp.addButton('pause', ()=>{ + audio.pause() + }) + GUIHelp.addButton('stop', ()=>{ + audio.stop() + }) + GUIHelp.add({volume:1}, 'volume', 0, 1, 0.01).onChange( (v:number) =>{ + audio.setVolume(v) + }) + GUIHelp.addButton('Toggle Helper', ()=>{ + audio.toggleHelper() + }) + GUIHelp.open() + } + { + let wall = new Object3D() + let mr = wall.addComponent(MeshRenderer) + mr.geometry = new BoxGeometry(40, 30, 1) + let mat = new LitMaterial() + mat.baseColor = new Color(1,0,0) + mr.material = mat + this.scene.addChild(wall) + wall.z = -5 + } + { + let floor = new Object3D(); + let mr = floor.addComponent(MeshRenderer); + mr.geometry = new BoxGeometry(3000, 1, 3000); + let mat = new LitMaterial(); + mr.material = mat; + this.scene.addChild(floor); + } + + /******** light *******/ + { + this.lightObj = new Object3D(); + this.lightObj.rotationX = 35; + this.lightObj.rotationY = 110; + this.lightObj.rotationZ = 0; + let directLight = this.lightObj.addComponent(DirectLight); + directLight.lightColor = KelvinUtil.color_temperature_to_rgb(5355); + directLight.castShadow = true; + directLight.intensity = 30; + this.scene.addChild(this.lightObj); + } + } + loop(){ + let man = this.scene.getChildByName('man') as Object3D + if(man){ + this.angle += 0.005 + man.x = this.a * Math.cos(this.angle) + man.z = this.b * Math.sin(this.angle) + 30 + man.rotationY -= 0.005 * 180 / Math.PI + } + } +} \ No newline at end of file diff --git a/samples/audio/Sample_StaticAudio.ts b/samples/audio/Sample_StaticAudio.ts new file mode 100644 index 00000000..9797c66d --- /dev/null +++ b/samples/audio/Sample_StaticAudio.ts @@ -0,0 +1,105 @@ +import { BoxGeometry, Camera3D, DirectLight, Engine3D, LitMaterial, KelvinUtil, MeshRenderer, Object3D, Scene3D, Vector3, Color, OrbitController, View3D, AtmosphericComponent } from '@orillusion/core'; +import { StaticAudio, AudioListener } from '@orillusion/media-extention' +import { GUIHelp } from '@orillusion/debug/GUIHelp'; + +export class Static_Audio { + lightObj: Object3D; + scene: Scene3D; + camera: Object3D + mats: any[]; + audio: StaticAudio + constructor() {} + + async run() { + Engine3D.setting.shadow.autoUpdate = true; + Engine3D.setting.shadow.updateFrameRate = 1; + Engine3D.setting.shadow.type = 'HARD'; + Engine3D.setting.shadow.shadowBound = 100; + + await Engine3D.init(); + this.scene = new Scene3D(); + this.scene.addComponent(AtmosphericComponent); + + this.camera = new Object3D() + this.camera.localPosition = new Vector3(0, 20, 50) + let mainCamera = this.camera.addComponent(Camera3D) + this.scene.addChild(this.camera) + + mainCamera.perspective(60, Engine3D.aspect, 0.1, 20000.0); + let orbit = this.camera.addComponent(OrbitController) + orbit.target = new Vector3(0, 4, 0) + orbit.minDistance = 10 + orbit.maxDistance = 200 + + let view = new View3D(); + view.scene = this.scene; + view.camera = mainCamera; + + Engine3D.startRenderView(view); + await this.initScene(); + } + + async initScene() { + { + let group = new Object3D() + let speaker = await Engine3D.res.loadGltf('gltfs/speaker/scene.gltf') + speaker.localScale.set(4,4,4) + speaker.rotationX = -120 + //speaker.y = 1.5 + group.addChild(speaker) + group.y = 2 + this.scene.addChild(group) + + let listener = this.camera.addComponent(AudioListener) + let audio = group.addComponent(StaticAudio) + audio.setLisenter(listener) + + await audio.load('https://cdn.orillusion.com/audio.ogg') + GUIHelp.init(); + GUIHelp.addButton('play', ()=>{ + audio.play() + }) + GUIHelp.addButton('pause', ()=>{ + audio.pause() + }) + GUIHelp.addButton('stop', ()=>{ + audio.stop() + }) + GUIHelp.add({volume:1}, 'volume', 0, 1, 0.01).onChange( (v:number) =>{ + audio.setVolume(v) + }) + GUIHelp.open() + } + { + let wall = new Object3D() + let mr = wall.addComponent(MeshRenderer) + mr.geometry = new BoxGeometry(40, 30, 1) + let mat = new LitMaterial() + mat.baseColor = new Color(1,0,0) + mr.material = mat + this.scene.addChild(wall) + wall.z = -5 + } + { + let floor = new Object3D(); + let mr = floor.addComponent(MeshRenderer); + mr.geometry = new BoxGeometry(3000, 1, 3000); + let mat = new LitMaterial(); + mr.material = mat; + this.scene.addChild(floor); + } + + /******** light *******/ + { + this.lightObj = new Object3D(); + this.lightObj.rotationX = 35; + this.lightObj.rotationY = 110; + this.lightObj.rotationZ = 0; + let directLight = this.lightObj.addComponent(DirectLight); + directLight.lightColor = KelvinUtil.color_temperature_to_rgb(5355); + directLight.castShadow = true; + directLight.intensity = 30; + this.scene.addChild(this.lightObj); + } + } +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 9fd30b1e..845da1b6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -121,9 +121,6 @@ export * from "./components/anim/skeletonAnim/buffer/SkeletonBlendComputeArgs" export * from "./components/anim/skeletonAnim/buffer/SkeletonTransformComputeArgs" export * from "./components/anim/skeletonAnim/shader/compute_skeleton_blend" export * from "./components/anim/skeletonAnim/shader/compute_skeleton_transform" -export * from "./components/audio/AudioListener" -export * from "./components/audio/PositionAudio" -export * from "./components/audio/StaticAudio" export * from "./components/controller/CameraControllerBase" export * from "./components/controller/FirstPersonCameraController" export * from "./components/controller/FlyCameraController"