Skip to content

Commit 62ceb53

Browse files
committed
GLTFLoader/GLTFExporter: Add support for single root scenes
1 parent d51e356 commit 62ceb53

File tree

2 files changed

+33
-11
lines changed

2 files changed

+33
-11
lines changed

examples/jsm/exporters/GLTFExporter.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2542,6 +2542,10 @@ class GLTFWriter {
25422542

25432543
await this.processObjectsAsync( objectsWithoutScene );
25442544

2545+
if ( input.length === 1 ) {
2546+
this.extensionsUsed[ 'GODOT_single_root' ] = true;
2547+
}
2548+
25452549
}
25462550

25472551
for ( let i = 0; i < this.skins.length; ++ i ) {

examples/jsm/loaders/GLTFLoader.js

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ class GLTFLoader extends Loader {
405405
}
406406

407407
/**
408-
* Parses the given FBX data and returns the resulting group.
408+
* Parses the given glTF data and returns the generated data to `onLoad`, with the root Object3D in the `.scene` property.
409409
*
410410
* @param {string|ArrayBuffer} data - The raw glTF data.
411411
* @param {string} path - The URL base path.
@@ -619,7 +619,8 @@ const EXTENSIONS = {
619619
EXT_TEXTURE_WEBP: 'EXT_texture_webp',
620620
EXT_TEXTURE_AVIF: 'EXT_texture_avif',
621621
EXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression',
622-
EXT_MESH_GPU_INSTANCING: 'EXT_mesh_gpu_instancing'
622+
EXT_MESH_GPU_INSTANCING: 'EXT_mesh_gpu_instancing',
623+
GODOT_SINGLE_ROOT: 'GODOT_single_root',
623624
};
624625

625626
/**
@@ -4479,18 +4480,27 @@ class GLTFParser {
44794480

44804481
const extensions = this.extensions;
44814482
const sceneDef = this.json.scenes[ sceneIndex ];
4483+
const nodeIds = sceneDef.nodes || [];
44824484
const parser = this;
4485+
const isSingleRoot = this.json.extensionsUsed.includes( EXTENSIONS.GODOT_SINGLE_ROOT );
44834486

4484-
// Loader returns Group, not Scene.
4485-
// See: https://github.com/mrdoob/three.js/issues/18342#issuecomment-578981172
4486-
const scene = new Group();
4487-
if ( sceneDef.name ) scene.name = parser.createUniqueName( sceneDef.name );
4487+
let scene;
4488+
if ( isSingleRoot ) {
44884489

4489-
assignExtrasToUserData( scene, sceneDef );
4490+
if ( nodeIds.length !== 1 ) {
4491+
throw new Error( 'THREE.GLTFLoader: glTF file with the single root flag must have exactly one scene root node. File is invalid.' );
4492+
}
44904493

4491-
if ( sceneDef.extensions ) addUnknownExtensionsToUserData( extensions, scene, sceneDef );
4494+
} else {
4495+
// Loader returns Group, not Scene.
4496+
// See: https://github.com/mrdoob/three.js/issues/18342#issuecomment-578981172
4497+
scene = new Group();
4498+
if ( sceneDef.name ) scene.name = parser.createUniqueName( sceneDef.name );
44924499

4493-
const nodeIds = sceneDef.nodes || [];
4500+
assignExtrasToUserData( scene, sceneDef );
4501+
4502+
if ( sceneDef.extensions ) addUnknownExtensionsToUserData( extensions, scene, sceneDef );
4503+
}
44944504

44954505
const pending = [];
44964506

@@ -4502,9 +4512,17 @@ class GLTFParser {
45024512

45034513
return Promise.all( pending ).then( function ( nodes ) {
45044514

4505-
for ( let i = 0, il = nodes.length; i < il; i ++ ) {
4515+
if ( isSingleRoot ) {
45064516

4507-
scene.add( nodes[ i ] );
4517+
scene = nodes[ 0 ];
4518+
4519+
} else {
4520+
4521+
for ( let i = 0, il = nodes.length; i < il; i ++ ) {
4522+
4523+
scene.add( nodes[ i ] );
4524+
4525+
}
45084526

45094527
}
45104528

0 commit comments

Comments
 (0)