From fe3c35046e61657befb5d4c49dddc6be42c73833 Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Wed, 14 May 2025 17:16:28 -0700 Subject: [PATCH 1/7] GLTFLoader: Add support for single root scenes --- examples/jsm/loaders/GLTFLoader.js | 41 ++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/examples/jsm/loaders/GLTFLoader.js b/examples/jsm/loaders/GLTFLoader.js index e8593bd4c60d56..49d2075b16ecc5 100644 --- a/examples/jsm/loaders/GLTFLoader.js +++ b/examples/jsm/loaders/GLTFLoader.js @@ -405,7 +405,7 @@ class GLTFLoader extends Loader { } /** - * Parses the given FBX data and returns the resulting group. + * Parses the given glTF data and returns the generated data to `onLoad`, with the root Object3D in the `.scene` property. * * @param {string|ArrayBuffer} data - The raw glTF data. * @param {string} path - The URL base path. @@ -619,7 +619,8 @@ const EXTENSIONS = { EXT_TEXTURE_WEBP: 'EXT_texture_webp', EXT_TEXTURE_AVIF: 'EXT_texture_avif', EXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression', - EXT_MESH_GPU_INSTANCING: 'EXT_mesh_gpu_instancing' + EXT_MESH_GPU_INSTANCING: 'EXT_mesh_gpu_instancing', + GODOT_SINGLE_ROOT: 'GODOT_single_root', }; /** @@ -4479,18 +4480,28 @@ class GLTFParser { const extensions = this.extensions; const sceneDef = this.json.scenes[ sceneIndex ]; + const nodeIds = sceneDef.nodes || []; const parser = this; + const extensionsUsed = this.json.extensionsUsed; + const isSingleRoot = Array.isArray( extensionsUsed ) ? extensionsUsed.includes( EXTENSIONS.GODOT_SINGLE_ROOT ) : false; - // Loader returns Group, not Scene. - // See: https://github.com/mrdoob/three.js/issues/18342#issuecomment-578981172 - const scene = new Group(); - if ( sceneDef.name ) scene.name = parser.createUniqueName( sceneDef.name ); + let scene; + if ( isSingleRoot ) { - assignExtrasToUserData( scene, sceneDef ); + if ( nodeIds.length !== 1 ) { + throw new Error( 'THREE.GLTFLoader: glTF file with the single root flag must have exactly one scene root node. File is invalid.' ); + } - if ( sceneDef.extensions ) addUnknownExtensionsToUserData( extensions, scene, sceneDef ); + } else { + // Loader returns Group, not Scene. + // See: https://github.com/mrdoob/three.js/issues/18342#issuecomment-578981172 + scene = new Group(); + if ( sceneDef.name ) scene.name = parser.createUniqueName( sceneDef.name ); - const nodeIds = sceneDef.nodes || []; + assignExtrasToUserData( scene, sceneDef ); + + if ( sceneDef.extensions ) addUnknownExtensionsToUserData( extensions, scene, sceneDef ); + } const pending = []; @@ -4502,9 +4513,17 @@ class GLTFParser { return Promise.all( pending ).then( function ( nodes ) { - for ( let i = 0, il = nodes.length; i < il; i ++ ) { + if ( isSingleRoot ) { - scene.add( nodes[ i ] ); + scene = nodes[ 0 ]; + + } else { + + for ( let i = 0, il = nodes.length; i < il; i ++ ) { + + scene.add( nodes[ i ] ); + + } } From cdab161d7c4c5755fc5f39456c68fac9a31f6359 Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Sat, 17 May 2025 21:44:42 +0200 Subject: [PATCH 2/7] Update GLTFLoader.js Improve code style. --- examples/jsm/loaders/GLTFLoader.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/jsm/loaders/GLTFLoader.js b/examples/jsm/loaders/GLTFLoader.js index 49d2075b16ecc5..cba5f3de95c122 100644 --- a/examples/jsm/loaders/GLTFLoader.js +++ b/examples/jsm/loaders/GLTFLoader.js @@ -4489,10 +4489,13 @@ class GLTFParser { if ( isSingleRoot ) { if ( nodeIds.length !== 1 ) { + throw new Error( 'THREE.GLTFLoader: glTF file with the single root flag must have exactly one scene root node. File is invalid.' ); + } } else { + // Loader returns Group, not Scene. // See: https://github.com/mrdoob/three.js/issues/18342#issuecomment-578981172 scene = new Group(); @@ -4501,6 +4504,7 @@ class GLTFParser { assignExtrasToUserData( scene, sceneDef ); if ( sceneDef.extensions ) addUnknownExtensionsToUserData( extensions, scene, sceneDef ); + } const pending = []; From e8763848936ac3d343db953213ccb0a8868f06f7 Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Sun, 18 May 2025 11:09:52 +0200 Subject: [PATCH 3/7] Update GLTFLoader.js --- examples/jsm/loaders/GLTFLoader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/jsm/loaders/GLTFLoader.js b/examples/jsm/loaders/GLTFLoader.js index cba5f3de95c122..80e85a3de4ad86 100644 --- a/examples/jsm/loaders/GLTFLoader.js +++ b/examples/jsm/loaders/GLTFLoader.js @@ -405,7 +405,7 @@ class GLTFLoader extends Loader { } /** - * Parses the given glTF data and returns the generated data to `onLoad`, with the root Object3D in the `.scene` property. + * Parses the given glTF data and returns the generated data to `onLoad`. * * @param {string|ArrayBuffer} data - The raw glTF data. * @param {string} path - The URL base path. From 281e4a08a901ab31f662ee0ffdf371e56c77221d Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Sun, 18 May 2025 11:10:25 +0200 Subject: [PATCH 4/7] Update GLTFLoader.js --- examples/jsm/loaders/GLTFLoader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/jsm/loaders/GLTFLoader.js b/examples/jsm/loaders/GLTFLoader.js index 80e85a3de4ad86..baa4588a582d79 100644 --- a/examples/jsm/loaders/GLTFLoader.js +++ b/examples/jsm/loaders/GLTFLoader.js @@ -620,7 +620,7 @@ const EXTENSIONS = { EXT_TEXTURE_AVIF: 'EXT_texture_avif', EXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression', EXT_MESH_GPU_INSTANCING: 'EXT_mesh_gpu_instancing', - GODOT_SINGLE_ROOT: 'GODOT_single_root', + GODOT_SINGLE_ROOT: 'GODOT_single_root' }; /** From 17e9f92f1f073f30b24f8a66d152192006ecadd5 Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Sun, 18 May 2025 11:19:25 +0200 Subject: [PATCH 5/7] Update GLTFLoader.js --- examples/jsm/loaders/GLTFLoader.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/jsm/loaders/GLTFLoader.js b/examples/jsm/loaders/GLTFLoader.js index baa4588a582d79..57874cd9f0482c 100644 --- a/examples/jsm/loaders/GLTFLoader.js +++ b/examples/jsm/loaders/GLTFLoader.js @@ -97,6 +97,7 @@ import { toTrianglesDrawMode } from '../utils/BufferGeometryUtils.js'; * - EXT_texture_webp * - EXT_meshopt_compression * - EXT_mesh_gpu_instancing + * - GODOT_SINGLE_ROOT * * The following glTF 2.0 extension is supported by an external user plugin: * - [KHR_materials_variants]{@link https://github.com/takahirox/three-gltf-extensions} @@ -4483,14 +4484,15 @@ class GLTFParser { const nodeIds = sceneDef.nodes || []; const parser = this; const extensionsUsed = this.json.extensionsUsed; - const isSingleRoot = Array.isArray( extensionsUsed ) ? extensionsUsed.includes( EXTENSIONS.GODOT_SINGLE_ROOT ) : false; + const isGodotSingleRoot = Array.isArray( extensionsUsed ) ? extensionsUsed.includes( EXTENSIONS.GODOT_SINGLE_ROOT ) : false; let scene; - if ( isSingleRoot ) { + + if ( isGodotSingleRoot ) { if ( nodeIds.length !== 1 ) { - throw new Error( 'THREE.GLTFLoader: glTF file with the single root flag must have exactly one scene root node. File is invalid.' ); + throw new Error( 'THREE.GLTFLoader: glTF files using the GODOT_SINGLE_ROOT extension must have exactly one scene root node. File is invalid.' ); } @@ -4517,7 +4519,7 @@ class GLTFParser { return Promise.all( pending ).then( function ( nodes ) { - if ( isSingleRoot ) { + if ( isGodotSingleRoot ) { scene = nodes[ 0 ]; From 37531dfbe33acb996c5a862ff1c643ba51f981cc Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Sun, 18 May 2025 11:20:06 +0200 Subject: [PATCH 6/7] Update GLTFLoader.js --- examples/jsm/loaders/GLTFLoader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/jsm/loaders/GLTFLoader.js b/examples/jsm/loaders/GLTFLoader.js index 57874cd9f0482c..25a9c966350a1d 100644 --- a/examples/jsm/loaders/GLTFLoader.js +++ b/examples/jsm/loaders/GLTFLoader.js @@ -97,7 +97,7 @@ import { toTrianglesDrawMode } from '../utils/BufferGeometryUtils.js'; * - EXT_texture_webp * - EXT_meshopt_compression * - EXT_mesh_gpu_instancing - * - GODOT_SINGLE_ROOT + * - GODOT_single_root * * The following glTF 2.0 extension is supported by an external user plugin: * - [KHR_materials_variants]{@link https://github.com/takahirox/three-gltf-extensions} From 0f6eedef425ec8e6b3a244801d1e77154162ee27 Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Sun, 18 May 2025 13:11:44 -0700 Subject: [PATCH 7/7] Use proper capitalization --- examples/jsm/loaders/GLTFLoader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/jsm/loaders/GLTFLoader.js b/examples/jsm/loaders/GLTFLoader.js index 25a9c966350a1d..eb72301b40e981 100644 --- a/examples/jsm/loaders/GLTFLoader.js +++ b/examples/jsm/loaders/GLTFLoader.js @@ -4492,7 +4492,7 @@ class GLTFParser { if ( nodeIds.length !== 1 ) { - throw new Error( 'THREE.GLTFLoader: glTF files using the GODOT_SINGLE_ROOT extension must have exactly one scene root node. File is invalid.' ); + throw new Error( 'THREE.GLTFLoader: glTF files using the GODOT_single_root extension must have exactly one scene root node. File is invalid.' ); }