Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
988f39a
chore: bump eslint-config-next to match nextjs version
julien-moreau May 3, 2026
882b981
fix: deactivate prepass renderer fix when no preview camera active to…
May 6, 2026
9ec85d6
feat: rework UI for gizmo snapping
May 6, 2026
915496d
feat: add support of Audio V2
julien-moreau May 10, 2026
477d69d
v5.4.1-rc.1
julien-moreau May 10, 2026
330139d
fix: dispose sound when disposing SoundNode in babylonjs-editor-tools.
May 11, 2026
600b62e
feat: remove support of old Audio Engine
julien-moreau May 11, 2026
10af61f
v5.4.1-rc.2
julien-moreau May 11, 2026
c9f929d
feat: adding support of database
May 12, 2026
faf2eae
feat: now using indexDB when available to load sound nodes and use in…
julien-moreau May 13, 2026
cf66733
v5.4.1-rc.3
julien-moreau May 13, 2026
4a669d4
feat : exclude sprite manager textures from compressed textures tempo…
julien-moreau May 13, 2026
366538c
fix: synchronously create sound instance when using AdvancedAssetCont…
julien-moreau May 14, 2026
ba2cc00
v5.4.1-rc.4
julien-moreau May 14, 2026
88cd4d7
fix: set spatial sounds updated automatically and all together in bab…
May 15, 2026
091399e
fix: disable sync when cloning meshes
julien-moreau May 15, 2026
6b7bb58
v5.4.1-rc.5
julien-moreau May 15, 2026
da7ed2b
fix: use BC3 instead of BC2 for DXT compressed textures when alpha av…
julien-moreau May 15, 2026
bc6f366
fix: always create clustered light container in babylonjs-editor-tools
julien-moreau May 16, 2026
7442d3d
fix: check if indexDB is enabled in Database before loading sound in …
julien-moreau May 16, 2026
0fb9122
v5.4.1-rc.6
julien-moreau May 16, 2026
5487b0e
fix: dispose and remove from assets cache AdvancedAssetContainer when…
julien-moreau May 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "babylonjs-editor-cli",
"version": "5.4.1-rc.0",
"version": "5.4.1-rc.6",
"description": "Babylon.js Editor CLI is a command line interface to help you package your scenes made using the Babylon.js Editor",
"productName": "Babylon.js Editor CLI",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion cli/src/pack/assets/ktx.mts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export async function compressFileToKtxFormat(absolutePath: string, options: Com
break;

case "-dxt.ktx":
command = `"${pvrTexToolAbsolutePath}" -i "${absolutePath}" -flip y -pot + -m -dither -ics lRGB ${hasAlpha ? "-l" : ""} -f ${hasAlpha ? "BC2" : "BC1"},UBN,lRGB -o "${options.destinationFolder}"`;
command = `"${pvrTexToolAbsolutePath}" -i "${absolutePath}" -flip y -pot + -m -dither -ics lRGB ${hasAlpha ? "-l" : ""} -f ${hasAlpha ? "BC3" : "BC1"},UBN,lRGB -o "${options.destinationFolder}"`;
break;

case "-pvrtc.ktx":
Expand Down
25 changes: 25 additions & 0 deletions cli/src/pack/scene.mts
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ export async function createBabylonScene(options: ICreateBabylonSceneOptions) {
})
);

// Sprite managers
const spriteManagersResult = await Promise.all(
options.directories.spriteManagerFiles.map(async (file) => {
const data = await fs.readJSON(join(options.sceneFile, "sprite-managers", file));
Expand All @@ -248,6 +249,7 @@ export async function createBabylonScene(options: ICreateBabylonSceneOptions) {
})
);

// Sprite maps
const spriteMapsResult = await Promise.all(
options.directories.spriteMapFiles.map(async (file) => {
const data = await fs.readJSON(join(options.sceneFile, "sprite-maps", file));
Expand All @@ -270,6 +272,29 @@ export async function createBabylonScene(options: ICreateBabylonSceneOptions) {
})
);

// Sound nodes
const soundNodesResults = await Promise.all(
options.directories.soundNodeFiles.map(async (file) => {
const data = await fs.readJSON(join(options.sceneFile, "soundNodes", file));

if (data.metadata?.doNotSerialize) {
return null;
}

if (data.metadata?.parentId) {
data.parentId = data.metadata.parentId;
}

return data;
})
);

transformNodes.push(
...soundNodesResults.filter((soundNode) => {
return soundNode !== null;
})
);

// Lights
const lightsResult = await Promise.all(
options.directories.lightsFiles.map(async (file) => {
Expand Down
4 changes: 4 additions & 0 deletions cli/src/tools/scene.mts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export async function ensureSceneDirectories(scenePath: string) {
fs.ensureDir(join(scenePath, "sceneLinks")),
fs.ensureDir(join(scenePath, "gui")),
fs.ensureDir(join(scenePath, "sounds")),
fs.ensureDir(join(scenePath, "soundNodes")),
fs.ensureDir(join(scenePath, "particleSystems")),
fs.ensureDir(join(scenePath, "morphTargetManagers")),
fs.ensureDir(join(scenePath, "morphTargets")),
Expand All @@ -38,6 +39,7 @@ export async function readSceneDirectories(scenePath: string) {
sceneLinkFiles,
guiFiles,
soundFiles,
soundNodeFiles,
particleSystemFiles,
morphTargetManagerFiles,
morphTargetFiles,
Expand All @@ -57,6 +59,7 @@ export async function readSceneDirectories(scenePath: string) {
readdir(join(scenePath, "sceneLinks")),
readdir(join(scenePath, "gui")),
readdir(join(scenePath, "sounds")),
readdir(join(scenePath, "soundNodes")),
readdir(join(scenePath, "particleSystems")),
readdir(join(scenePath, "morphTargetManagers")),
readdir(join(scenePath, "morphTargets")),
Expand All @@ -78,6 +81,7 @@ export async function readSceneDirectories(scenePath: string) {
sceneLinkFiles,
guiFiles,
soundFiles,
soundNodeFiles,
particleSystemFiles,
morphTargetManagerFiles,
morphTargetFiles,
Expand Down
2 changes: 1 addition & 1 deletion editor/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "babylonjs-editor",
"version": "5.4.1-rc.0",
"version": "5.4.1-rc.6",
"description": "Babylon.js Editor is a Web Application helping artists to work with Babylon.js",
"productName": "Babylon.js Editor",
"main": "build/src/index.js",
Expand Down
7 changes: 2 additions & 5 deletions editor/src/editor/dialogs/command-palette/command-palette.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { FaCirclePlus } from "react-icons/fa6";
import { IoSparklesSharp } from "react-icons/io5";
import { HiMiniCommandLine } from "react-icons/hi2";

import { Node, IParticleSystem, Sound } from "babylonjs";
import { Node, IParticleSystem } from "babylonjs";

import { normalizedGlob } from "../../../tools/fs";
import { isNodeVisibleInGraph } from "../../../tools/node/metadata";
Expand Down Expand Up @@ -168,10 +168,7 @@ export class CommandPalette extends Component<ICommandPaletteProps, ICommandPale
private _refreshEntities(): void {
const scene = this.props.editor.layout.preview.scene;

let objects = [...scene.meshes, ...scene.lights, ...scene.cameras, ...scene.particleSystems, ...scene.transformNodes] as (Node | IParticleSystem | Sound)[];
scene.soundTracks?.forEach((soundTrack) => {
objects.push(...soundTrack.soundCollection);
});
let objects = [...scene.meshes, ...scene.lights, ...scene.cameras, ...scene.particleSystems, ...scene.transformNodes] as (Node | IParticleSystem)[];

objects = objects.filter((o) => {
if (isNode(o) && !isNodeVisibleInGraph(o)) {
Expand Down
12 changes: 5 additions & 7 deletions editor/src/editor/layout/assets-browser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ import { EditorAssetsTreeLabel } from "./assets-browser/label";
import "babylonjs-loaders";

import { AssimpJSLoader } from "../../loader/assimpjs";
import { isSoundNode } from "../../tools/guards/sound";

const HDRSelectable = createSelectable(AssetBrowserHDRItem);
const GuiSelectable = createSelectable(AssetBrowserGUIItem);
Expand Down Expand Up @@ -481,13 +482,10 @@ export class EditorAssetsBrowser extends Component<IEditorAssetsBrowserProps, IE
});

// Sounds
scene.soundTracks?.forEach((soundtrack) => {
soundtrack.soundCollection.forEach((sound) => {
if (sound.name === oldRelativePath) {
sound.name = newRelativePath;
sound["_url"] = newRelativePath;
}
});
scene.transformNodes.forEach((node) => {
if (isSoundNode(node) && node.soundRelativePath === oldRelativePath) {
node.soundRelativePath = newRelativePath;
}
});

// Scripts
Expand Down
10 changes: 5 additions & 5 deletions editor/src/editor/layout/cinematic/inspector/sound.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Sound } from "babylonjs";
import { ICinematicSound, ICinematicTrack } from "babylonjs-editor-tools";

import { CinematicEditor } from "../editor";

import { SoundNode } from "../../../nodes/sound";

import { EditorInspectorNumberField } from "../../inspector/fields/number";
import { EditorInspectorSectionField } from "../../inspector/fields/section";

Expand All @@ -13,14 +14,13 @@ export interface ICinematicEditorSoundKeyInspectorProps {
}

export function CinematicEditorSoundKeyInspector(props: ICinematicEditorSoundKeyInspectorProps) {
const sound = props.track.sound as Sound | null;
const buffer = sound?.getAudioBuffer();
const node = props.track.sound as SoundNode | null;

if (!sound || !buffer) {
if (!node || !node.sound?.buffer) {
return null;
}

const endFrame = buffer.duration * props.cinematicEditor.cinematic.framesPerSecond;
const endFrame = node.sound.duration * props.cinematicEditor.cinematic.framesPerSecond;

return (
<EditorInspectorSectionField title="Sound">
Expand Down
9 changes: 5 additions & 4 deletions editor/src/editor/layout/cinematic/serialization/parse.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Scene, Sound, Vector3, Animation } from "babylonjs";
import { Scene, Vector3, Animation } from "babylonjs";
import { ICinematic, ICinematicKey, ICinematicKeyCut, ICinematicTrack, parseCinematicKeyValue, getAnimationTypeForObject } from "babylonjs-editor-tools";

import { getSoundById } from "../../../../tools/sound/tools";
import { getInspectorPropertyValue } from "../../../../tools/property";

import { getDefaultRenderingPipeline } from "../../../rendering/default-pipeline";

import { SoundNode } from "../../../nodes/sound";

export function parseCinematic(data: ICinematic, scene: Scene) {
const tracks = data.tracks.map((track) => {
return parseCinematicTrack(track, scene);
Expand Down Expand Up @@ -41,9 +42,9 @@ export function parseCinematicTrack(track: ICinematicTrack, scene: Scene) {
animationType = getAnimationTypeForObject(value);
}

let sound: Sound | null = null;
let sound: SoundNode | null = null;
if (track.sound) {
sound = getSoundById(track.sound, scene);
sound = scene.getNodeById(track.sound) as SoundNode;
}

return {
Expand Down
13 changes: 7 additions & 6 deletions editor/src/editor/layout/cinematic/timelines/add.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { Sound, AnimationGroup } from "babylonjs";
import { AnimationGroup } from "babylonjs";
import { ICinematicAnimationGroup, ICinematicKey, ICinematicKeyCut, ICinematicKeyEvent, ICinematicSound, ICinematicTrack, isCinematicKeyCut } from "babylonjs-editor-tools";

import { showAlert } from "../../../../ui/dialog";

import { registerUndoRedo } from "../../../../tools/undoredo";
import { getInspectorPropertyValue } from "../../../../tools/property";

import { showAlert } from "../../../../ui/dialog";
import { SoundNode } from "../../../nodes/sound";

import { getDefaultRenderingPipeline } from "../../../rendering/default-pipeline";

Expand Down Expand Up @@ -116,17 +118,16 @@ export function addSoundKey(cinematicEditor: CinematicEditor, track: ICinematicT
return;
}

const sound = track.sound as Sound;
const buffer = sound.getAudioBuffer();
const node = track.sound as SoundNode;

if (!buffer) {
if (!node.sound?.buffer) {
return showAlert(
"Can't add sound track",
"The sound track is not ready yet, please wait until the sound is loaded. If this problem persists, please verify the sound file is correctly loaded."
);
}

const duration = buffer.duration;
const duration = node.sound.buffer.duration;
const fps = cinematicEditor.cinematic.framesPerSecond;

const key = {
Expand Down
11 changes: 7 additions & 4 deletions editor/src/editor/layout/cinematic/tools/sync.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { AnimationGroup, Sound } from "babylonjs";
import { AnimationGroup } from "babylonjs";

import { ICinematic } from "babylonjs-editor-tools";
import { SoundNode } from "../../../nodes/sound";

export interface ISyncAnimationGroupsToFrameOptions {
pauseAfterSync: boolean;
Expand Down Expand Up @@ -44,8 +45,8 @@ export function syncAnimationGroupsToFrame(frame: number, cinematic: ICinematic,

export function syncSoundsToFrame(frame: number, cinematic: ICinematic) {
cinematic.tracks.forEach((track) => {
const sound = track.sound as Sound;
if (!sound) {
const node = track.sound as SoundNode;
if (!node) {
return;
}

Expand All @@ -59,7 +60,9 @@ export function syncSoundsToFrame(frame: number, cinematic: ICinematic) {

if (frameDiff > 0) {
const offset = frameDiff / cinematic.framesPerSecond;
sound.play(0, offset);
node.play({
startOffset: offset,
});
}
});
});
Expand Down
11 changes: 8 additions & 3 deletions editor/src/editor/layout/cinematic/tracks/sound.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import { HiSpeakerWave } from "react-icons/hi2";

import { ICinematicTrack } from "babylonjs-editor-tools";

import { getSoundById } from "../../../../tools/sound/tools";
import { Button } from "../../../../ui/shadcn/ui/button";

import { isSoundNode } from "../../../../tools/guards/sound";
import { registerUndoRedo } from "../../../../tools/undoredo";

import { CinematicEditor } from "../editor";

import { CinematicEditorRemoveTrackButton } from "./remove";
import { Button } from "../../../../ui/shadcn/ui/button";

export interface ICinematicEditorSoundTrackProps {
track: ICinematicTrack;
Expand Down Expand Up @@ -37,7 +38,11 @@ export function CinematicEditorSoundTrack(props: ICinematicEditorSoundTrackProps
setDragOver(false);

const data = JSON.parse(event.dataTransfer.getData("graph/node")) as string[];
const sound = getSoundById(data[0], props.cinematicEditor.editor.layout.preview.scene);

let sound = props.cinematicEditor.editor.layout.preview.scene.getNodeById(data[0]);
if (!isSoundNode(sound)) {
sound = null;
}

if (sound && sound !== props.track.sound) {
const oldSound = props.track.node;
Expand Down
Loading