Просмотр исходного кода

GLTFLoader: Allow multiple associations (#21737)

* GLTFLoader: Allow multiple associations

* Tests: Add GLTFLoader associations unit test
Takahiro 3 лет назад
Родитель
Сommit
aca1c4f450
2 измененных файлов с 76 добавлено и 6 удалено
  1. 20 6
      examples/jsm/loaders/GLTFLoader.js
  2. 56 0
      test/unit/example/loaders/GLTFLoader.tests.js

+ 20 - 6
examples/jsm/loaders/GLTFLoader.js

@@ -2826,10 +2826,7 @@ class GLTFParser {
 			texture.wrapS = WEBGL_WRAPPINGS[ sampler.wrapS ] || RepeatWrapping;
 			texture.wrapT = WEBGL_WRAPPINGS[ sampler.wrapT ] || RepeatWrapping;
 
-			parser.associations.set( texture, {
-				type: 'textures',
-				index: textureIndex
-			} );
+			parser.associations.set( texture, { textures: textureIndex } );
 
 			return texture;
 
@@ -3169,7 +3166,7 @@ class GLTFParser {
 
 			assignExtrasToUserData( material, materialDef );
 
-			parser.associations.set( material, { type: 'materials', index: materialIndex } );
+			parser.associations.set( material, { materials: materialIndex } );
 
 			if ( materialDef.extensions ) addUnknownExtensionsToUserData( extensions, material, materialDef );
 
@@ -3382,6 +3379,15 @@ class GLTFParser {
 
 			}
 
+			for ( let i = 0, il = meshes.length; i < il; i ++ ) {
+
+				parser.associations.set( meshes[ i ], {
+					meshes: meshIndex,
+					primitives: i
+				} );
+
+			}
+
 			if ( meshes.length === 1 ) {
 
 				return meshes[ 0 ];
@@ -3390,6 +3396,8 @@ class GLTFParser {
 
 			const group = new Group();
 
+			parser.associations.set( group, { meshes: meshIndex } );
+
 			for ( let i = 0, il = meshes.length; i < il; i ++ ) {
 
 				group.add( meshes[ i ] );
@@ -3799,7 +3807,13 @@ class GLTFParser {
 
 			}
 
-			parser.associations.set( node, { type: 'nodes', index: nodeIndex } );
+			if ( ! parser.associations.has( node ) ) {
+
+				parser.associations.set( node, {} );
+
+			}
+
+			parser.associations.get( node ).nodes = nodeIndex;
 
 			return node;
 

+ 56 - 0
test/unit/example/loaders/GLTFLoader.tests.js

@@ -6,10 +6,12 @@ import { GLTFLoader } from '../../../../examples/jsm/loaders/GLTFLoader';
 import { AnimationClip } from '../../../../src/animation/AnimationClip';
 import { BufferAttribute } from '../../../../src/core/BufferAttribute';
 import { BufferGeometry } from '../../../../src/core/BufferGeometry';
+import { BoxBufferGeometry } from '../../../../src/geometries/BoxGeometry';
 import { Mesh } from '../../../../src/objects/Mesh';
 import { MeshStandardMaterial } from '../../../../src/materials/MeshStandardMaterial';
 import { Object3D } from '../../../../src/core/Object3D';
 import { Scene } from '../../../../src/scenes/Scene';
+import { DataTexture } from '../../../../src/textures/DataTexture';
 import { VectorKeyframeTrack } from '../../../../src/animation/tracks/VectorKeyframeTrack';
 
 export default QUnit.module( 'Loaders', () => {
@@ -113,6 +115,60 @@ export default QUnit.module( 'Loaders', () => {
 
 		} );
 
+		QUnit.test( 'parser - associations', ( assert ) => {
+
+			var done = assert.async();
+
+			var scene = new Scene();
+			scene.add( new Mesh(
+				new BoxBufferGeometry(),
+				new MeshStandardMaterial( { map: new DataTexture( new Uint8ClampedArray( [ 0, 0, 0, 0 ] ), 1, 1 ) } )
+			) );
+
+			var exporter = new GLTFExporter();
+			var loader = new GLTFLoader();
+
+			exporter.parse( scene, function ( binary ) {
+
+				loader.parse( binary, './', function ( gltf ) {
+
+					var parser = gltf.parser;
+					var associations = parser.associations;
+
+					gltf.scene.traverse( function ( object ) {
+
+						if ( object.isMesh ) {
+
+							assert.smartEqual( associations.get( object ), {
+								meshes: 0,
+								nodes: 0,
+								primitives: 0
+							}, 'Mesh has a proper association' );
+
+							assert.smartEqual( associations.get( object.material ), {
+								materials: 0
+							}, 'Material has a proper association' );
+
+							assert.smartEqual( associations.get( object.material.map ), {
+								textures: 0
+							}, 'Texture has a proper association' );
+
+						}
+
+					} );
+
+					done();
+
+				}, undefined, function ( e ) {
+
+					console.error( e );
+
+				} );
+
+			}, { binary: true } );
+
+		} );
+
 	} );
 
 } );