Skip to content

Commit

Permalink
add: sound support #309
Browse files Browse the repository at this point in the history
  • Loading branch information
brianzinn committed Feb 17, 2024
1 parent ccebbec commit ec2c321
Show file tree
Hide file tree
Showing 12 changed files with 24,061 additions and 7 deletions.
4 changes: 3 additions & 1 deletion packages/react-babylonjs/docs/api.md
Expand Up @@ -109,7 +109,9 @@ Shadows, Textures, etc.)

12. **Sprites** spriteManager, spritePackedManager, thinSprite, sprite

13. **Others** - adtForMesh, adtForMeshTexture, adtFullScreenUi,
13. **Sound** sound

14. **Others** - adtForMesh, adtForMeshTexture, adtFullScreenUi,
environmentHelper, physicsImpostor, pointsCloudSystem, shadowGenerator /
cascadedShadowGenerator, layer, utilityLayerRenderer, viewport,
vrExperienceHelper
Expand Down
7 changes: 5 additions & 2 deletions packages/react-babylonjs/src/Engine.tsx
Expand Up @@ -120,7 +120,7 @@ const ReactBabylonjsEngine: React.FC<EngineProps> = (props: EngineProps, context

useEffect(() => {
if (!canvasReady) {
return;
return
}

if (canvasRef.current === null) {
Expand Down Expand Up @@ -207,7 +207,10 @@ const ReactBabylonjsEngine: React.FC<EngineProps> = (props: EngineProps, context
<canvas
{...opts}
{...canvasProps}
ref={(view) => {canvasRef.current = view; setCanvasReady(true)}}
ref={(view) => {
canvasRef.current = view
setCanvasReady(true)
}}
style={{ width: '100%', height: '100%', ...style }}
>
{engine.current !== null && props.children}
Expand Down
153 changes: 153 additions & 0 deletions packages/react-babylonjs/src/generatedCode.ts
@@ -1,4 +1,5 @@
import { AbstractScene as BabylonjsCoreAbstractScene } from '@babylonjs/core/abstractScene.js'
import { Sound as BabylonjsCoreSound } from '@babylonjs/core/Audio/sound.js'
import { AutoRotationBehavior as BabylonjsCoreAutoRotationBehavior } from '@babylonjs/core/Behaviors/Cameras/autoRotationBehavior.js'
import { BouncingBehavior as BabylonjsCoreBouncingBehavior } from '@babylonjs/core/Behaviors/Cameras/bouncingBehavior.js'
import { FramingBehavior as BabylonjsCoreFramingBehavior } from '@babylonjs/core/Behaviors/Cameras/framingBehavior.js'
Expand Down Expand Up @@ -439,6 +440,7 @@ import {
FiberSlateGizmoProps,
FiberSlider3DProps,
FiberSliderProps,
FiberSoundProps,
FiberSpherePanelProps,
FiberSpotLightProps,
FiberSpriteManagerProps,
Expand Down Expand Up @@ -17079,6 +17081,153 @@ export class FiberSprite implements HasPropsHandlers<FiberThinSpriteProps> {
}
}

export class FiberSoundPropsHandler implements PropsHandler<FiberSoundProps> {
getPropertyUpdates(
oldProps: FiberSoundProps,
newProps: FiberSoundProps
): PropertyUpdate[] | null {
const changedProps: PropertyUpdate[] = []
checkPrimitiveDiff(oldProps.autoplay, newProps.autoplay, 'autoplay', changedProps)
checkPrimitiveDiff(
oldProps.directionalConeInnerAngle,
newProps.directionalConeInnerAngle,
'directionalConeInnerAngle',
changedProps
)
checkPrimitiveDiff(
oldProps.directionalConeOuterAngle,
newProps.directionalConeOuterAngle,
'directionalConeOuterAngle',
changedProps
)
checkPrimitiveDiff(
oldProps.distanceModel,
newProps.distanceModel,
'distanceModel',
changedProps
)
checkPrimitiveDiff(oldProps.isPaused, newProps.isPaused, 'isPaused', changedProps)
checkPrimitiveDiff(oldProps.isPlaying, newProps.isPlaying, 'isPlaying', changedProps)
checkPrimitiveDiff(oldProps.loop, newProps.loop, 'loop', changedProps)
checkPrimitiveDiff(oldProps.maxDistance, newProps.maxDistance, 'maxDistance', changedProps)
// type: 'any' property (not coded) BabylonjsCoreSound.metadata.
checkPrimitiveDiff(oldProps.name, newProps.name, 'name', changedProps)
checkLambdaDiff(oldProps.onended, newProps.onended, 'onended', changedProps)
checkObservableDiff(
oldProps.onEndedObservable,
newProps.onEndedObservable,
'onEndedObservable',
changedProps
)
checkPrimitiveDiff(oldProps.refDistance, newProps.refDistance, 'refDistance', changedProps)
checkPrimitiveDiff(
oldProps.rolloffFactor,
newProps.rolloffFactor,
'rolloffFactor',
changedProps
)
checkPrimitiveDiff(oldProps.soundTrackId, newProps.soundTrackId, 'soundTrackId', changedProps)
checkPrimitiveDiff(oldProps.spatialSound, newProps.spatialSound, 'spatialSound', changedProps)
checkPrimitiveDiff(
oldProps.useCustomAttenuation,
newProps.useCustomAttenuation,
'useCustomAttenuation',
changedProps
)
checkMethodDiff(
oldProps.setAttenuationFunction,
newProps.setAttenuationFunction,
'setAttenuationFunction',
changedProps
)
checkMethodDiff(
oldProps.setAudioBuffer,
newProps.setAudioBuffer,
'setAudioBuffer',
changedProps
)
checkMethodDiff(
oldProps.setDirectionalCone,
newProps.setDirectionalCone,
'setDirectionalCone',
changedProps
)
checkMethodDiff(
oldProps.setLocalDirectionToMesh,
newProps.setLocalDirectionToMesh,
'setLocalDirectionToMesh',
changedProps
)
checkMethodDiff(
oldProps.setPlaybackRate,
newProps.setPlaybackRate,
'setPlaybackRate',
changedProps
)
checkMethodDiff(oldProps.setPosition, newProps.setPosition, 'setPosition', changedProps)
checkMethodDiff(oldProps.setVolume, newProps.setVolume, 'setVolume', changedProps)
return changedProps.length === 0 ? null : changedProps
}
}

/**
* Defines a sound that can be played in the application.
* The sound can either be an ambient track or a simple sound played in reaction to a user action.
*
* This code has been generated
*/
export class FiberSound implements HasPropsHandlers<FiberSoundProps> {
private propsHandlers: PropsHandler<FiberSoundProps>[]

constructor() {
this.propsHandlers = [new FiberSoundPropsHandler()]
}

getPropsHandlers(): PropsHandler<FiberSoundProps>[] {
return this.propsHandlers
}

addPropsHandler(propHandler: PropsHandler<FiberSoundProps>): void {
this.propsHandlers.push(propHandler)
}

public static readonly CreateInfo = {
creationType: 'Constructor',
libraryLocation: 'Sound',
namespace: '@babylonjs/core',
parameters: [
{
name: 'name',
type: 'string',
optional: false,
},
{
name: 'urlOrArrayBuffer',
type: 'any',
optional: false,
},
{
name: 'scene',
type: 'BabylonjsCoreScene',
optional: true,
},
{
name: 'readyToPlayCallback',
type: '() => void',
optional: true,
},
{
name: 'options',
type: 'BabylonjsCoreISoundOptions',
optional: true,
},
],
}
public static readonly Metadata: CreatedInstanceMetadata = {
className: 'FiberSound',
}
}

export class FiberEffectLayerPropsHandler implements PropsHandler<FiberEffectLayerProps> {
getPropertyUpdates(
oldProps: FiberEffectLayerProps,
Expand Down Expand Up @@ -30690,6 +30839,7 @@ export const ADTForMesh: string = 'ADTForMesh',
SlateGizmo: string = 'SlateGizmo',
Slider: string = 'Slider',
Slider3D: string = 'Slider3D',
Sound: string = 'Sound',
Sphere: string = 'Sphere',
SpherePanel: string = 'SpherePanel',
SpotLight: string = 'SpotLight',
Expand Down Expand Up @@ -30755,6 +30905,8 @@ const classesMap: Record<string, any> = {
Scene: BabylonjsCoreScene,
dynamicTerrain: ExtensionsDynamicTerrain,
DynamicTerrain: ExtensionsDynamicTerrain,
sound: BabylonjsCoreSound,
Sound: BabylonjsCoreSound,
camera: BabylonjsCoreCamera,
Camera: BabylonjsCoreCamera,
gizmo: BabylonjsCoreGizmo,
Expand Down Expand Up @@ -31240,6 +31392,7 @@ export const intrinsicClassMap: object = {
abstractScene: 'AbstractScene',
scene: 'Scene',
dynamicTerrain: 'DynamicTerrain',
sound: 'Sound',
camera: 'Camera',
gizmo: 'Gizmo',
gizmoManager: 'GizmoManager',
Expand Down
35 changes: 35 additions & 0 deletions packages/react-babylonjs/src/generatedProps.ts
Expand Up @@ -2,6 +2,8 @@ import { AbstractActionManager as BabylonjsCoreAbstractActionManager } from '@ba
import { ActionManager as BabylonjsCoreActionManager } from '@babylonjs/core/Actions/actionManager.js'
import { Animation as BabylonjsCoreAnimation } from '@babylonjs/core/Animations/animation.js'
import { AnimationPropertiesOverride as BabylonjsCoreAnimationPropertiesOverride } from '@babylonjs/core/Animations/animationPropertiesOverride.js'
import { ISoundOptions as BabylonjsCoreISoundOptions } from '@babylonjs/core/Audio/Interfaces/ISoundOptions.js'
import { Sound as BabylonjsCoreSound } from '@babylonjs/core/Audio/sound.js'
import { IBakedVertexAnimationManager as BabylonjsCoreIBakedVertexAnimationManager } from '@babylonjs/core/BakedVertexAnimation/bakedVertexAnimationManager.js'
import { AutoRotationBehavior as BabylonjsCoreAutoRotationBehavior } from '@babylonjs/core/Behaviors/Cameras/autoRotationBehavior.js'
import { BouncingBehavior as BabylonjsCoreBouncingBehavior } from '@babylonjs/core/Behaviors/Cameras/bouncingBehavior.js'
Expand Down Expand Up @@ -826,6 +828,7 @@ declare global {
FiberThinSpritePropsCtor &
BabylonNode<BabylonjsCoreThinSprite>
sprite: FiberSpriteProps & FiberSpritePropsCtor & BabylonNode<BabylonjsCoreSprite>
sound: FiberSoundProps & FiberSoundPropsCtor & BabylonNode<BabylonjsCoreSound>
effectLayer: FiberEffectLayerProps &
FiberEffectLayerPropsCtor &
BabylonNode<BabylonjsCoreEffectLayer>
Expand Down Expand Up @@ -3845,6 +3848,38 @@ export type FiberSpritePropsCtor = {
name: string
manager?: BabylonjsCoreISpriteManager
}
export type FiberSoundProps = {
autoplay?: boolean
directionalConeInnerAngle?: number
directionalConeOuterAngle?: number
distanceModel?: string
isPaused?: boolean
isPlaying?: boolean
loop?: boolean
maxDistance?: number
metadata?: any
name?: string
onended?: () => any
onEndedObservable?: any
refDistance?: number
rolloffFactor?: number
setAttenuationFunction?: any
setAudioBuffer?: any
setDirectionalCone?: any
setLocalDirectionToMesh?: any
setPlaybackRate?: any
setPosition?: any
setVolume?: any
soundTrackId?: number
spatialSound?: boolean
useCustomAttenuation?: boolean
} & CustomProps
export type FiberSoundPropsCtor = {
name: string
urlOrArrayBuffer: any
readyToPlayCallback?: () => void
options?: BabylonjsCoreISoundOptions
}
export type FiberEffectLayerProps = {
disableBoundingBoxesFromEffectLayer?: boolean
isEnabled?: boolean
Expand Down
9 changes: 6 additions & 3 deletions packages/react-babylonjs/tools/generate-code.ts
Expand Up @@ -224,6 +224,7 @@ const classesToGenerate: String[] = [
'MaterialPluginBase',
'SpriteManager',
'Sprite',
'Sound',
]

let MeshBuilderVariableDeclaration: Nullable<VariableDeclaration> = null
Expand Down Expand Up @@ -2200,15 +2201,13 @@ const generateCode = async () => {
)
}

if (isDefined('SpriteManager')) {
if (isDefined('SpriteManager') && isDefined('Sprite')) {
createClassesInheritedFrom(
generatedCodeSourceFile,
generatedPropsSourceFile,
classesOfInterest.get('SpriteManager')!,
() => ({})
)
}
if (isDefined('Sprite')) {
createClassesDerivedFrom(
generatedCodeSourceFile,
generatedPropsSourceFile,
Expand All @@ -2217,6 +2216,10 @@ const generateCode = async () => {
)
}

if (isDefined('Sound')) {
createSingleClass('Sound', generatedCodeSourceFile, generatedPropsSourceFile)
}

if (isDefined('EffectLayer')) {
const metadataFromClassName = (className: string) => ({
isEffectLayer: true,
Expand Down
3 changes: 2 additions & 1 deletion packages/static/content/examples/basic/index.mdx
Expand Up @@ -18,8 +18,9 @@ title: 'Basic'
- [Instanced Meshes](./instanced-mesh-hex)
- [createPortal](./create-portal)
- [CSG](./extrude-csg)
- [Sound](./sound)
- [Snippet Material](./snippet-material)
- [Toggle Mesh](./toggle-mesh)
- [Toggle Scene](./toggle-scene)
- [Transform Node](./transform-node)
- [Viewport](./viewport
- [Viewport](./viewport)
22 changes: 22 additions & 0 deletions packages/static/content/examples/basic/sound/Sound.tsx
@@ -0,0 +1,22 @@
import { Vector3 } from '@babylonjs/core/Maths/math.vector'
import React from 'react'
import { Engine, Scene } from 'react-babylonjs'

const Sound = () => (
<div style={{ flex: 1, display: 'flex' }}>
<Engine antialias adaptToDeviceRatio canvasId="babylon-js">
<Scene>
<freeCamera name="camera1" position={new Vector3(0, 5, -10)} setTarget={[Vector3.Zero()]} />
<hemisphericLight name="light1" intensity={0.7} direction={Vector3.Up()} />
<sound
name="sound"
urlOrArrayBuffer={`../../../assets/sounds/violons11.wav`}
loop
autoplay
/>
</Scene>
</Engine>
</div>
)

export default Sound
9 changes: 9 additions & 0 deletions packages/static/content/examples/basic/sound/index.mdx
@@ -0,0 +1,9 @@
---
title: 'Sound'
---

# Sound example

https://playground.babylonjs.com/#PCY1J

[devtool:Sound.tsx]
1 change: 1 addition & 0 deletions packages/static/content/examples/index.mdx
Expand Up @@ -17,6 +17,7 @@ library and many more!
- [Materials](./materials) - Materials (dynamic registration)
- [3D Models](./models) - Model loading and interaction demos
- [Physics](./physics) - Declarative Physics
- [Sprite](./sprites) - Declarative Sprites
- [Post Process](./post-process) - Post Processing examples
- [Special FX](./special-fx) - Layers for visual effects
- [Textures](./textures) - PBR, procedural and configurations/parameters.
Expand Down
1 change: 1 addition & 0 deletions packages/static/content/nav.js
Expand Up @@ -29,6 +29,7 @@ const toc = [
'/examples/basic/instanced-mesh-hex',
'/examples/basic/create-portal',
'/examples/basic/extrude-csg',
'/examples/basic/sound',
'/examples/basic/snippet-material',
'/examples/basic/toggle-mesh',
'/examples/basic/toggle-scene',
Expand Down
Binary file not shown.

0 comments on commit ec2c321

Please sign in to comment.