Browse Source

add BufferGeometry de-duplication to GLTF parser

mattdesl 7 years ago
parent
commit
b3c37c589f
1 changed files with 76 additions and 0 deletions
  1. 76 0
      examples/js/loaders/GLTFLoader.js

+ 76 - 0
examples/js/loaders/GLTFLoader.js

@@ -1298,6 +1298,60 @@ THREE.GLTFLoader = ( function () {
 
 	}
 
+	function isPrimitiveEqual ( a, b ) {
+
+		if ( a.indices !== b.indices ) {
+
+			return false;
+
+		}
+
+		var attribA = a.attributes || {};
+		var attribB = b.attributes || {};
+		var keysA = Object.keys(attribA);
+		var keysB = Object.keys(attribB);
+		var i;
+
+		for ( i = 0; i < keysA.length; i++ ) {
+
+			var key = keysA[i];
+
+			if ( attribA[key] !== attribB[key] ) {
+
+				return false;
+
+			}
+		}
+
+		for ( i = 0; i < keysB.length; i++ ) {
+
+			var key = keysB[i];
+
+			if ( attribA[key] !== attribB[key] ) {
+
+				return false;
+
+			}
+		}
+
+		return true;
+	}
+
+	function getCachedGeometry ( cache, newPrimitive ) {
+
+		for ( var i = 0; i < cache.length; i++ ) {
+			var cached = cache[i];
+
+			if ( isPrimitiveEqual( cached.primitive, newPrimitive ) ) {
+
+				return cached.geometry;
+
+			}
+		}
+
+		return null;
+	}
+
 	/* GLTF PARSER */
 
 	function GLTFParser( json, extensions, options ) {
@@ -1309,6 +1363,9 @@ THREE.GLTFLoader = ( function () {
 		// loader object cache
 		this.cache = new GLTFRegistry();
 
+		// BufferGeometry caching
+		this.primitiveCache = [];
+
 		this.textureLoader = new THREE.TextureLoader( this.options.manager );
 		this.textureLoader.setCrossOrigin( this.options.crossOrigin );
 
@@ -1817,6 +1874,8 @@ THREE.GLTFLoader = ( function () {
 
 	GLTFParser.prototype.loadGeometries = function ( primitives ) {
 
+		var cache = this.primitiveCache;
+
 		return this._withDependencies( [
 
 			'accessors',
@@ -1825,6 +1884,15 @@ THREE.GLTFLoader = ( function () {
 
 			return _each( primitives, function ( primitive ) {
 
+				// See if we've already created this geometry
+				var cached = getCachedGeometry( cache, primitive );
+
+				if (cached) {
+
+					return cached;
+
+				}
+
 				var geometry = new THREE.BufferGeometry();
 
 				var attributes = primitive.attributes;
@@ -1890,6 +1958,14 @@ THREE.GLTFLoader = ( function () {
 
 				}
 
+				// Cache this geometry
+				cache.push( {
+
+					primitive: primitive,
+					geometry: geometry
+
+				} );
+
 				return geometry;
 
 			} );