浏览代码

Added option for creating BufferGeometry in UTF8v2Loader.

For ben model this shrunk creation time 3x (190 ms vs 608 ms). Also memory footprint should be much smaller with BufferGeometry.
alteredq 13 年之前
父节点
当前提交
aad5049c5c
共有 3 个文件被更改,包括 135 次插入318 次删除
  1. 0 300
      build/three.min.js
  2. 125 16
      examples/js/loaders/UTF8v2Loader.js
  3. 10 2
      examples/webgl_loader_utf8_r104.html

文件差异内容过多而无法显示
+ 0 - 300
build/three.min.js


+ 125 - 16
examples/js/loaders/UTF8v2Loader.js

@@ -16,18 +16,112 @@ THREE.UTF8v2Loader = function () {};
  *                   geometryBase: Base url from which to load referenced geometries
  *                   geometryBase: Base url from which to load referenced geometries
  *                   materialBase: Base url from which to load referenced textures
  *                   materialBase: Base url from which to load referenced textures
  */
  */
+
 THREE.UTF8v2Loader.prototype.load = function ( jsonUrl, callback, options ) {
 THREE.UTF8v2Loader.prototype.load = function ( jsonUrl, callback, options ) {
 
 
     this.downloadModelJson( jsonUrl, options, callback );
     this.downloadModelJson( jsonUrl, options, callback );
 
 
 };
 };
 
 
+// BufferGeometryCreator
+
+THREE.UTF8v2Loader.BufferGeometryCreator = function () {
+};
+
+THREE.UTF8v2Loader.BufferGeometryCreator.prototype.create = function ( attribArray, indexArray ) {
+
+	var ntris = indexArray.length / 3;
+
+	var geometry = new THREE.BufferGeometry();
+
+	var positionArray = new Float32Array( 3 * 3 * ntris );
+	var normalArray = new Float32Array( 3 * 3 * ntris );
+	var uvArray = new Float32Array( 2 * 3 * ntris );
+
+	var i, j, offset;
+	var x, y, z;
+	var u, v;
+
+	var end = attribArray.length;
+	var stride = 8;
+
+	// extract positions
+
+	j = 0;
+	offset = 0;
+
+	for( i = offset; i < end; i += stride ) {
+
+		x = attribArray[ i ];
+		y = attribArray[ i + 1 ];
+		z = attribArray[ i + 2 ];
+
+		positionArray[ j++ ] = x;
+		positionArray[ j++ ] = y;
+		positionArray[ j++ ] = z;
+
+	}
+
+	// extract uvs
+
+	j = 0;
+	offset = 3;
+
+	for( i = offset; i < end; i += stride ) {
+
+		u = attribArray[ i ];
+		v = attribArray[ i + 1 ];
+
+		uvArray[ j++ ] = u;
+		uvArray[ j++ ] = v;
+
+	}
+
+	// extract normals
+
+	j = 0;
+	offset = 5;
+
+	for( i = offset; i < end; i += stride ) {
+
+		x = attribArray[ i ];
+		y = attribArray[ i + 1 ];
+		z = attribArray[ i + 2 ];
+
+		normalArray[ j++ ] = x;
+		normalArray[ j++ ] = y;
+		normalArray[ j++ ] = z;
+
+	}
+
+	// create attributes
+
+	var attributes = geometry.attributes;
+
+	attributes[ "index" ]    = { itemSize: 1, array: indexArray, numItems: indexArray.length };
+	attributes[ "position" ] = { itemSize: 3, array: positionArray, numItems: positionArray.length };
+	attributes[ "normal" ]   = { itemSize: 3, array: normalArray, numItems: normalArray.length };
+	attributes[ "uv" ] 		 = { itemSize: 2, array: uvArray, numItems: uvArray.length };
+
+	// create offsets
+	// (all triangles should fit in a single chunk)
+
+	geometry.offsets = [ { start: 0, count: indexArray.length, index: 0 } ];
+
+	geometry.computeBoundingSphere();
+
+	return geometry;
+
+};
+
+// GeometryCreator
+
 THREE.UTF8v2Loader.GeometryCreator = function () {
 THREE.UTF8v2Loader.GeometryCreator = function () {
 };
 };
 
 
 THREE.UTF8v2Loader.GeometryCreator.prototype = {
 THREE.UTF8v2Loader.GeometryCreator.prototype = {
 
 
-    create: function ( attribArray, indexArray, bboxen ) {
+    create: function ( attribArray, indexArray ) {
 
 
         var geometry = new THREE.Geometry();
         var geometry = new THREE.Geometry();
 
 
@@ -148,15 +242,15 @@ THREE.UTF8v2Loader.GeometryCreator.prototype = {
 
 
     f3n: function( scope, normals, a, b, c, mi, nai, nbi, nci ) {
     f3n: function( scope, normals, a, b, c, mi, nai, nbi, nci ) {
 
 
-        var nax = normals[ nai * 3     ],
+        var nax = normals[ nai * 3 ],
             nay = normals[ nai * 3 + 1 ],
             nay = normals[ nai * 3 + 1 ],
             naz = normals[ nai * 3 + 2 ],
             naz = normals[ nai * 3 + 2 ],
 
 
-            nbx = normals[ nbi * 3     ],
+            nbx = normals[ nbi * 3 ],
             nby = normals[ nbi * 3 + 1 ],
             nby = normals[ nbi * 3 + 1 ],
             nbz = normals[ nbi * 3 + 2 ],
             nbz = normals[ nbi * 3 + 2 ],
 
 
-            ncx = normals[ nci * 3     ],
+            ncx = normals[ nci * 3 ],
             ncy = normals[ nci * 3 + 1 ],
             ncy = normals[ nci * 3 + 1 ],
             ncz = normals[ nci * 3 + 2 ];
             ncz = normals[ nci * 3 + 2 ];
 
 
@@ -350,8 +444,7 @@ THREE.UTF8v2Loader.prototype.decompressMesh =  function ( str, meshParams, decod
 
 
     if ( bboxOffset ) {
     if ( bboxOffset ) {
 
 
-        bboxen = this.decompressAABBs_( str, bboxOffset, meshParams.names.length,
-            decodeOffsets, decodeScales );
+        bboxen = this.decompressAABBs_( str, bboxOffset, meshParams.names.length, decodeOffsets, decodeScales );
     }
     }
 
 
     callback( name, idx, attribsOut, indicesOut, bboxen, meshParams );
     callback( name, idx, attribsOut, indicesOut, bboxen, meshParams );
@@ -703,16 +796,19 @@ THREE.UTF8v2Loader.prototype.createMeshCallback = function( materialBaseUrl, loa
 
 
     var model = new THREE.Object3D();
     var model = new THREE.Object3D();
 
 
-    var geometryCreator = new THREE.UTF8v2Loader.GeometryCreator();
+    // Prepare materials first...
 
 
     var materialCreator = new THREE.MTLLoader.MaterialCreator( materialBaseUrl, loadModelInfo.options );
     var materialCreator = new THREE.MTLLoader.MaterialCreator( materialBaseUrl, loadModelInfo.options );
-    materialCreator.setMaterials(loadModelInfo.materials);
-
-    // Prepare materials first...
+    materialCreator.setMaterials( loadModelInfo.materials );
 
 
     materialCreator.preload();
     materialCreator.preload();
 
 
-    return function( name, idx, attribArray, indexArray, bboxen, meshParams ) {
+	// Create callback for creating mesh parts
+
+    var geometryCreator = new THREE.UTF8v2Loader.GeometryCreator();
+	var bufferGeometryCreator = new THREE.UTF8v2Loader.BufferGeometryCreator();
+
+	var meshCallback = function( name, idx, attribArray, indexArray, bboxen, meshParams ) {
 
 
         // Got ourselves a new mesh
         // Got ourselves a new mesh
 
 
@@ -723,16 +819,26 @@ THREE.UTF8v2Loader.prototype.createMeshCallback = function( materialBaseUrl, loa
         // bboxen defines the bounding box
         // bboxen defines the bounding box
         // meshParams contains the material info
         // meshParams contains the material info
 
 
-        var geometry = geometryCreator.create( attribArray, indexArray, bboxen );
+		if ( loadModelInfo.options.useBuffers ) {
+
+			var geometry = bufferGeometryCreator.create( attribArray, indexArray );
+
+		} else {
+
+			var geometry = geometryCreator.create( attribArray, indexArray );
+
+		}
+
         var material = materialCreator.create( meshParams.material );
         var material = materialCreator.create( meshParams.material );
 
 
-        modelParts[name].add( new THREE.Mesh( geometry, material  ));
+		var mesh = new THREE.Mesh( geometry, material );
+        modelParts[ name ].add( mesh );
 
 
         //model.add(new THREE.Mesh(geometry, material));
         //model.add(new THREE.Mesh(geometry, material));
 
 
         decodedMeshesPerUrl[ name ] ++;
         decodedMeshesPerUrl[ name ] ++;
 
 
-        if ( decodedMeshesPerUrl[name] === expectedMeshesPerUrl[name] ) {
+        if ( decodedMeshesPerUrl[ name ] === expectedMeshesPerUrl[ name ] ) {
 
 
             nCompletedUrls ++;
             nCompletedUrls ++;
 
 
@@ -748,7 +854,9 @@ THREE.UTF8v2Loader.prototype.createMeshCallback = function( materialBaseUrl, loa
 
 
         }
         }
 
 
-    }
+    };
+
+	return meshCallback;
 
 
 };
 };
 
 
@@ -763,7 +871,7 @@ THREE.UTF8v2Loader.prototype.downloadModelJson = function ( jsonUrl, options, ca
 
 
     getJsonRequest( jsonUrl, function( loaded ) {
     getJsonRequest( jsonUrl, function( loaded ) {
 
 
-        if ( !loaded.decodeParams ) {
+        if ( ! loaded.decodeParams ) {
 
 
             if ( options && options.decodeParams ) {
             if ( options && options.decodeParams ) {
 
 
@@ -803,6 +911,7 @@ THREE.UTF8v2Loader.prototype.downloadModelJson = function ( jsonUrl, options, ca
                 materialBase = materialBase  + "/";
                 materialBase = materialBase  + "/";
 
 
             }
             }
+
         }
         }
 
 
         this.downloadModel( geometryBase, materialBase, loaded, callback );
         this.downloadModel( geometryBase, materialBase, loaded, callback );

+ 10 - 2
examples/webgl_loader_utf8_r104.html

@@ -136,10 +136,15 @@
 				stats.domElement.style.zIndex = 100;
 				stats.domElement.style.zIndex = 100;
 				container.appendChild( stats.domElement );
 				container.appendChild( stats.domElement );
 
 
+				var start = Date.now();
+
 				var loader = new THREE.UTF8v2Loader();
 				var loader = new THREE.UTF8v2Loader();
 
 
 				loader.load( "models/utf8_r104/hand.js", function ( object ) {
 				loader.load( "models/utf8_r104/hand.js", function ( object ) {
 
 
+					var end = Date.now();
+					console.log( "hand", end - start, "ms" );
+
 					var s = 350;
 					var s = 350;
 					object.scale.set( s, s, s );
 					object.scale.set( s, s, s );
 					object.position.x = 125;
 					object.position.x = 125;
@@ -160,10 +165,13 @@
 
 
 					} );
 					} );
 
 
-				}, { normalizeRGB: true } );
+				}, { normalizeRGB: true, useBuffers: true } );
 
 
 				loader.load( "models/utf8_r104/ben.js", function ( object ) {
 				loader.load( "models/utf8_r104/ben.js", function ( object ) {
 
 
+					var end = Date.now();
+					console.log( "ben", end - start, "ms" );
+
 					var s = 350;
 					var s = 350;
 					object.scale.set( s, s, s );
 					object.scale.set( s, s, s );
 					object.position.x = -125;
 					object.position.x = -125;
@@ -184,7 +192,7 @@
 
 
 					} );
 					} );
 
 
-				}, { normalizeRGB: true } );
+				}, { normalizeRGB: true, useBuffers: true } );
 
 
 				//
 				//
 
 

部分文件因为文件数量过多而无法显示