浏览代码

Merge pull request #15348 from donmccurdy/feat-gltfexporter-cache-geometry

GLTFExporter: Instance meshes and attributes.
Mr.doob 6 年之前
父节点
当前提交
21cb7e4bc7
共有 1 个文件被更改,包括 49 次插入9 次删除
  1. 49 9
      examples/js/exporters/GLTFExporter.js

+ 49 - 9
examples/js/exporters/GLTFExporter.js

@@ -111,7 +111,9 @@ THREE.GLTFExporter.prototype = {
 		var extensionsUsed = {};
 		var cachedData = {
 
+			meshes: new Map(),
 			attributes: new Map(),
+			attributesNormalized: new Map(),
 			materials: new Map(),
 			textures: new Map(),
 			images: new Map()
@@ -221,7 +223,7 @@ THREE.GLTFExporter.prototype = {
 		 */
 		function isNormalizedNormalAttribute( normal ) {
 
-			if ( cachedData.attributes.has( normal ) ) {
+			if ( cachedData.attributesNormalized.has( normal ) ) {
 
 				return false;
 
@@ -249,9 +251,9 @@ THREE.GLTFExporter.prototype = {
 		 */
 		function createNormalizedNormalAttribute( normal ) {
 
-			if ( cachedData.attributes.has( normal ) ) {
+			if ( cachedData.attributesNormalized.has( normal ) ) {
 
-				return cachedData.attributes.get( normal );
+				return cachedData.attributesNormalized.get( normal );
 
 			}
 
@@ -278,7 +280,7 @@ THREE.GLTFExporter.prototype = {
 
 			}
 
-			cachedData.attributes.set( normal, attribute );
+			cachedData.attributesNormalized.set( normal, attribute );
 
 			return attribute;
 
@@ -1008,6 +1010,13 @@ THREE.GLTFExporter.prototype = {
 		 */
 		function processMesh( mesh ) {
 
+			var cacheKey = mesh.geometry.uuid + ':' + mesh.material.uuid;
+			if ( cachedData.meshes.has( cacheKey ) ) {
+
+				return cachedData.meshes.get( cacheKey );
+
+			}
+
 			var geometry = mesh.geometry;
 
 			var mode;
@@ -1090,23 +1099,32 @@ THREE.GLTFExporter.prototype = {
 				var attribute = geometry.attributes[ attributeName ];
 				attributeName = nameConversion[ attributeName ] || attributeName.toUpperCase();
 
+				if ( cachedData.attributes.has( attribute ) ) {
+
+					attributes[ attributeName ] = cachedData.attributes.get( attribute );
+					continue;
+
+				}
+
 				// JOINTS_0 must be UNSIGNED_BYTE or UNSIGNED_SHORT.
+				var modifiedAttribute;
 				var array = attribute.array;
 				if ( attributeName === 'JOINTS_0' &&
 					! ( array instanceof Uint16Array ) &&
 					! ( array instanceof Uint8Array ) ) {
 
 					console.warn( 'GLTFExporter: Attribute "skinIndex" converted to type UNSIGNED_SHORT.' );
-					attribute = new THREE.BufferAttribute( new Uint16Array( array ), attribute.itemSize, attribute.normalized );
+					modifiedAttribute = new THREE.BufferAttribute( new Uint16Array( array ), attribute.itemSize, attribute.normalized );
 
 				}
 
 				if ( attributeName.substr( 0, 5 ) !== 'MORPH' ) {
 
-					var accessor = processAccessor( attribute, geometry );
+					var accessor = processAccessor( modifiedAttribute || attribute, geometry );
 					if ( accessor !== null ) {
 
 						attributes[ attributeName ] = accessor;
+						cachedData.attributes.set( attribute, accessor );
 
 					}
 
@@ -1165,6 +1183,7 @@ THREE.GLTFExporter.prototype = {
 						}
 
 						var attribute = geometry.morphAttributes[ attributeName ][ i ];
+						var gltfAttributeName = attributeName.toUpperCase();
 
 						// Three.js morph attribute has absolute values while the one of glTF has relative values.
 						//
@@ -1172,6 +1191,14 @@ THREE.GLTFExporter.prototype = {
 						// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#morph-targets
 
 						var baseAttribute = geometry.attributes[ attributeName ];
+
+						if ( cachedData.attributes.has( baseAttribute ) ) {
+
+							target[ gltfAttributeName ] = cachedData.attributes.get( baseAttribute );
+							continue;
+
+						}
+
 						// Clones attribute not to override
 						var relativeAttribute = attribute.clone();
 
@@ -1186,7 +1213,8 @@ THREE.GLTFExporter.prototype = {
 
 						}
 
-						target[ attributeName.toUpperCase() ] = processAccessor( relativeAttribute, geometry );
+						target[ gltfAttributeName ] = processAccessor( relativeAttribute, geometry );
+						cachedData.attributes.set( baseAttribute, target[ gltfAttributeName ] );
 
 					}
 
@@ -1257,7 +1285,16 @@ THREE.GLTFExporter.prototype = {
 
 				if ( geometry.index !== null ) {
 
-					primitive.indices = processAccessor( geometry.index, geometry, groups[ i ].start, groups[ i ].count );
+					if ( cachedData.attributes.has( geometry.index ) ) {
+
+						primitive.indices = cachedData.attributes.get( geometry.index );
+
+					} else {
+
+						primitive.indices = processAccessor( geometry.index, geometry, groups[ i ].start, groups[ i ].count );
+						cachedData.attributes.set( geometry.index, primitive.indices );
+
+					}
 
 				}
 
@@ -1289,7 +1326,10 @@ THREE.GLTFExporter.prototype = {
 
 			outputJSON.meshes.push( gltfMesh );
 
-			return outputJSON.meshes.length - 1;
+			var index = outputJSON.meshes.length - 1;
+			cachedData.meshes.set( cacheKey, index );
+
+			return index;
 
 		}