Browse Source

Optimized binary model format to use indexed UVs. Updated OBJ slim converter and Loader accordingly.

This saves about 10% from size of textured binary models.
alteredq 14 years ago
parent
commit
a0fa2ae3dd

File diff suppressed because it is too large
+ 0 - 0
build/Three.js


File diff suppressed because it is too large
+ 0 - 0
build/ThreeDebug.js


BIN
examples/obj/female02/Female02_bin.bin


BIN
examples/obj/lucy/Lucy100k_bin.bin


BIN
examples/obj/male02/Male02_bin.bin


BIN
examples/obj/torus/Torus_bin.bin


BIN
examples/obj/walt/WaltHead_bin.bin


+ 6 - 6
examples/obj_convert_test.html

@@ -15,7 +15,7 @@
 			h1 { }
 			a { color:skyblue }
 			canvas { pointer-events:none; z-index:10; position:relative; }
-			#log { position:absolute; top:0; display:none }
+			#log { position:absolute; top:0; display:block; text-align:left; z-index:1000 }
 			#d { text-align:center; margin:1em 0 -15.7em 0; z-index:0; position:relative; display:block }
 			.button { background:#000; color:#fff; padding:0.2em 0.5em; cursor:pointer }
 			.inactive { background:#999; color:#eee }
@@ -40,7 +40,7 @@
 			<p>Canvas renderer is very slow on anything other than Chrome.
 		</div>
 		
-		<div id="log"></div>
+		<pre id="log"></pre>
 
 		<script type="text/javascript" src="../build/Three.js"></script> 
 		<!--
@@ -244,11 +244,11 @@
 				//loader.loadAsciiOld( "obj/male02/male02.js",     function() { createScene( new Male02( "obj/male02" ),      90, 50, FLOOR, 105 ) } );
 				//loader.loadAsciiOld( "obj/female02/female02.js", function() { createScene( new Female02( "obj/female02" ), -80, 50, FLOOR, 0 ) } );
 				
-				loader.loadAscii( "obj/male02/Male02_slim.js",     function( geometry ) { createScene( geometry,  90, 50, FLOOR, 105 ) }, "obj/male02" );
-				loader.loadAscii( "obj/female02/Female02_slim.js", function( geometry ) { createScene( geometry, -80, 50, FLOOR, 0 ) },   "obj/female02" );
+				//loader.loadAscii( "obj/male02/Male02_slim.js",     function( geometry ) { createScene( geometry,  90, 50, FLOOR, 105 ) }, "obj/male02" );
+				//loader.loadAscii( "obj/female02/Female02_slim.js", function( geometry ) { createScene( geometry, -80, 50, FLOOR, 0 ) },   "obj/female02" );
                 
-                //loader.loadBinary( "obj/male02/Male02_bin.js",     function( geometry ) { createScene( geometry,  90, 50, FLOOR, 105 ) }, "obj/male02" );
-				//loader.loadBinary( "obj/female02/Female02_bin.js", function( geometry ) { createScene( geometry, -80, 50, FLOOR, 0 ) },   "obj/female02" );
+                loader.loadBinary( "obj/male02/Male02_bin.js",     function( geometry ) { createScene( geometry,  90, 50, FLOOR, 105 ) }, "obj/male02" );
+				loader.loadBinary( "obj/female02/Female02_bin.js", function( geometry ) { createScene( geometry, -80, 50, FLOOR, 0 ) },   "obj/female02" );
 
 			}
 

+ 305 - 173
src/io/Loader.js

@@ -123,7 +123,8 @@ THREE.Loader.prototype = {
 			var scope = this,
 				currentOffset = 0, 
 				md,
-				normals = [];
+				normals = [],
+				uvs = [];
 
 			
 			THREE.Geometry.call(this);
@@ -135,14 +136,18 @@ THREE.Loader.prototype = {
 			
 			currentOffset += init_vertices( currentOffset );
 			currentOffset += init_normals( currentOffset );
+			currentOffset += init_uvs( currentOffset );
+			
 			currentOffset += init_triangles_flat( currentOffset );
 			currentOffset += init_triangles_smooth( currentOffset );
+			currentOffset += init_triangles_flat_uv( currentOffset );
+			currentOffset += init_triangles_smooth_uv( currentOffset );
+			
 			currentOffset += init_quads_flat( currentOffset );
 			currentOffset += init_quads_smooth( currentOffset );
-			currentOffset += init_uvs_tri( currentOffset );
-			
-			init_uvs_quad( data, currentOffset, md.nuvtri );
-			
+			currentOffset += init_quads_flat_uv( currentOffset );
+			currentOffset += init_quads_smooth_uv( currentOffset );
+
 			this.computeCentroids();
 			this.computeNormals();
 			
@@ -153,24 +158,33 @@ THREE.Loader.prototype = {
 			function parseMetaData( data, offset ) {
 				
 				var metaData = {
-					'signature'               :parseString( data, offset, 8 ),
 					
+					'signature'               :parseString( data, offset, 8 ),
 					'header_bytes'            :parseUChar8( data, offset + 8 ),
+					
 					'vertex_coordinate_bytes' :parseUChar8( data, offset + 9 ),
-					'vertex_index_bytes'      :parseUChar8( data, offset + 10 ),
-					'normal_index_bytes'      :parseUChar8( data, offset + 11 ),
-					'material_index_bytes'    :parseUChar8( data, offset + 12 ),
-					'normal_coordinate_bytes' :parseUChar8( data, offset + 13 ),
-					'uv_coordinate_bytes'     :parseUChar8( data, offset + 14 ),
-				
-					'nvertices'    :parseUInt32( data, offset + 15 ),
-					'ntri_flat'    :parseUInt32( data, offset + 15 + 4*1 ),
-					'ntri_smooth'  :parseUInt32( data, offset + 15 + 4*2 ),
-					'nquad_flat'   :parseUInt32( data, offset + 15 + 4*3 ),
-					'nquad_smooth' :parseUInt32( data, offset + 15 + 4*4 ),
-					'nnormals'     :parseUInt32( data, offset + 15 + 4*5 ),
-					'nuvtri'       :parseUInt32( data, offset + 15 + 4*6 ),
-					'nuvquad'      :parseUInt32( data, offset + 15 + 4*7 ),
+					'normal_coordinate_bytes' :parseUChar8( data, offset + 10 ),
+					'uv_coordinate_bytes'     :parseUChar8( data, offset + 11 ),
+					
+					'vertex_index_bytes'      :parseUChar8( data, offset + 12 ),
+					'normal_index_bytes'      :parseUChar8( data, offset + 13 ),
+					'uv_index_bytes'          :parseUChar8( data, offset + 14 ),
+					'material_index_bytes'    :parseUChar8( data, offset + 15 ),
+				
+					'nvertices'    :parseUInt32( data, offset + 16 ),
+					'nnormals'     :parseUInt32( data, offset + 16 + 4*1 ),
+					'nuvs'         :parseUInt32( data, offset + 16 + 4*2 ),
+					
+					'ntri_flat'      :parseUInt32( data, offset + 16 + 4*3 ),
+					'ntri_smooth'    :parseUInt32( data, offset + 16 + 4*4 ),
+					'ntri_flat_uv'   :parseUInt32( data, offset + 16 + 4*5 ),
+					'ntri_smooth_uv' :parseUInt32( data, offset + 16 + 4*6 ),
+					
+					'nquad_flat'      :parseUInt32( data, offset + 16 + 4*7 ),
+					'nquad_smooth'    :parseUInt32( data, offset + 16 + 4*8 ),
+					'nquad_flat_uv'   :parseUInt32( data, offset + 16 + 4*9 ),
+					'nquad_smooth_uv' :parseUInt32( data, offset + 16 + 4*10 )
+					
 				};
 
 				/*
@@ -178,20 +192,27 @@ THREE.Loader.prototype = {
 				
 				log( "header_bytes: " + metaData.header_bytes );
 				log( "vertex_coordinate_bytes: " + metaData.vertex_coordinate_bytes );
+				log( "normal_coordinate_bytes: " + metaData.normal_coordinate_bytes );
+				log( "uv_coordinate_bytes: " + metaData.uv_coordinate_bytes );
+				
 				log( "vertex_index_bytes: " + metaData.vertex_index_bytes );
 				log( "normal_index_bytes: " + metaData.normal_index_bytes );
+				log( "uv_index_bytes: " + metaData.uv_index_bytes );
 				log( "material_index_bytes: " + metaData.material_index_bytes );
-				log( "normal_coordinate_bytes: " + metaData.normal_coordinate_bytes );
-				log( "uv_coordinate_bytes: " + metaData.uv_coordinate_bytes );
 				
 				log( "nvertices: " + metaData.nvertices );
+				log( "nnormals: " + metaData.nnormals );
+				log( "nuvs: " + metaData.nuvs );
+				
 				log( "ntri_flat: " + metaData.ntri_flat );
 				log( "ntri_smooth: " + metaData.ntri_smooth );
+				log( "ntri_flat_uv: " + metaData.ntri_flat_uv );
+				log( "ntri_smooth_uv: " + metaData.ntri_smooth_uv );
+				
 				log( "nquad_flat: " + metaData.nquad_flat );
 				log( "nquad_smooth: " + metaData.nquad_smooth );
-				log( "nnormals: " + metaData.nnormals );
-				log( "nuvtri: " + metaData.nuvtri );
-				log( "nuvquad: " + metaData.nuvquad );
+				log( "nquad_flat_uv: " + metaData.nquad_flat_uv );
+				log( "nquad_smooth_uv: " + metaData.nquad_smooth_uv );
 				*/
 				
 				return metaData;
@@ -271,215 +292,327 @@ THREE.Loader.prototype = {
 				
 			}
 			
-			function init_triangles_flat( start ) {
+			function init_normals( start ) {
 				
-				var i, a, b, c, m, material, 
-					stride = md.vertex_index_bytes * 3 + md.material_index_bytes;
+				var i, x, y, z, 
+					stride = md.normal_coordinate_bytes * 3;
 				
-				for( i = 0; i < md.ntri_flat; ++i ) {
+				for( i = 0; i < md.nnormals; ++i ) {
 					
-					a = parseUInt32( data, start + i*stride );
-					b = parseUInt32( data, start + i*stride + md.vertex_index_bytes );
-					c = parseUInt32( data, start + i*stride + md.vertex_index_bytes*2 );
-					m = parseUInt16( data, start + i*stride + md.vertex_index_bytes*3 );
+					x = parseSChar8( data, start + i*stride );
+					y = parseSChar8( data, start + i*stride + md.normal_coordinate_bytes );
+					z = parseSChar8( data, start + i*stride + md.normal_coordinate_bytes*2 );
 					
-					material = scope.materials[ m ];
-					scope.faces.push( new THREE.Face3( a, b, c, null, material ) );
+					normals.push( x/127, y/127, z/127 );
 					
 				}
 				
-				return md.ntri_flat * stride;
+				return md.nnormals * stride;
 				
 			}
-			
-			function init_triangles_smooth( start ) {
-			
-				var i, a, b, c, m, na, nb, nc, material,
-					nax, nay, naz, nbx, nby, nbz, ncx, ncy, ncz,
-					stride = md.vertex_index_bytes * 3 + md.material_index_bytes + md.normal_index_bytes * 3;
+
+			function init_uvs( start ) {
 				
-				for( i = 0; i < md.ntri_smooth; ++i ) {
+				var i, u, v, 
+					stride = md.uv_coordinate_bytes * 2;
+				
+				for( i = 0; i < md.nuvs; ++i ) {
 					
-					a  = parseUInt32( data, start + i*stride );
-					b  = parseUInt32( data, start + i*stride + md.vertex_index_bytes );
-					c  = parseUInt32( data, start + i*stride + md.vertex_index_bytes*2 );
-					m  = parseUInt16( data, start + i*stride + md.vertex_index_bytes*3 );
-					na = parseUInt32( data, start + i*stride + md.vertex_index_bytes*3 + md.material_index_bytes );
-					nb = parseUInt32( data, start + i*stride + md.vertex_index_bytes*3 + md.material_index_bytes + md.normal_index_bytes );
-					nc = parseUInt32( data, start + i*stride + md.vertex_index_bytes*3 + md.material_index_bytes + md.normal_index_bytes*2 );
+					u = parseFloat32( data, start + i*stride );
+					v = parseFloat32( data, start + i*stride + md.uv_coordinate_bytes );
 					
-					material = scope.materials[ m ];
+					uvs.push( u, v );
 					
-					nax = normals[ na*3     ],
-					nay = normals[ na*3 + 1 ],
-					naz = normals[ na*3 + 2 ],
+				}
 				
-					nbx = normals[ nb*3     ],
-					nby = normals[ nb*3 + 1 ],
-					nbz = normals[ nb*3 + 2 ],
+				return md.nuvs * stride;
 				
-					ncx = normals[ nc*3     ],
-					ncy = normals[ nc*3 + 1 ],
-					ncz = normals[ nc*3 + 2 ];
+			}
+			
+			function add_tri( start, i, stride ) {
 				
-					scope.faces.push( new THREE.Face3( a, b, c, 
-								  [new THREE.Vector3( nax, nay, naz ), 
-								   new THREE.Vector3( nbx, nby, nbz ), 
-								   new THREE.Vector3( ncx, ncy, ncz )], 
-								  material ) );
-					
-				}
+				var a, b, c, m, material;
 				
-				return md.ntri_smooth * stride;
+				a = parseUInt32( data, start + i*stride );
+				b = parseUInt32( data, start + i*stride + md.vertex_index_bytes );
+				c = parseUInt32( data, start + i*stride + md.vertex_index_bytes*2 );
+				
+				m = parseUInt16( data, start + i*stride + md.vertex_index_bytes*3 );
+				
+				material = scope.materials[ m ];
+				scope.faces.push( new THREE.Face3( a, b, c, null, material ) );
+				
+			}
+			
+			function add_tri_n( start, i, stride ) {
+				
+				var a, b, c, m, na, nb, nc, material,
+					nax, nay, naz, nbx, nby, nbz, ncx, ncy, ncz;
+				
+				a  = parseUInt32( data, start + i*stride );
+				b  = parseUInt32( data, start + i*stride + md.vertex_index_bytes );
+				c  = parseUInt32( data, start + i*stride + md.vertex_index_bytes*2 );
+				
+				m  = parseUInt16( data, start + i*stride + md.vertex_index_bytes*3 );
+				
+				na = parseUInt32( data, start + i*stride + md.vertex_index_bytes*3 + md.material_index_bytes );
+				nb = parseUInt32( data, start + i*stride + md.vertex_index_bytes*3 + md.material_index_bytes + md.normal_index_bytes );
+				nc = parseUInt32( data, start + i*stride + md.vertex_index_bytes*3 + md.material_index_bytes + md.normal_index_bytes*2 );
+				
+				material = scope.materials[ m ];
+				
+				nax = normals[ na*3     ],
+				nay = normals[ na*3 + 1 ],
+				naz = normals[ na*3 + 2 ],
+			
+				nbx = normals[ nb*3     ],
+				nby = normals[ nb*3 + 1 ],
+				nbz = normals[ nb*3 + 2 ],
+			
+				ncx = normals[ nc*3     ],
+				ncy = normals[ nc*3 + 1 ],
+				ncz = normals[ nc*3 + 2 ];
+			
+				scope.faces.push( new THREE.Face3( a, b, c, 
+							  [new THREE.Vector3( nax, nay, naz ), 
+							   new THREE.Vector3( nbx, nby, nbz ), 
+							   new THREE.Vector3( ncx, ncy, ncz )], 
+							  material ) );
+							  
+			}
+			
+			function add_quad( start, i, stride ) {
+				
+				var a, b, c, d, m, material;
+				
+				a = parseUInt32( data, start + i*stride );
+				b = parseUInt32( data, start + i*stride + md.vertex_index_bytes );
+				c = parseUInt32( data, start + i*stride + md.vertex_index_bytes*2 );
+				d = parseUInt32( data, start + i*stride + md.vertex_index_bytes*3 );
+				
+				m = parseUInt16( data, start + i*stride + md.vertex_index_bytes*4 );
+				
+				material = scope.materials[ m ];
+				scope.faces.push( new THREE.Face4( a, b, c, d, null, material ) );
 				
 			}
+			
+			function add_quad_n( start, i, stride ) {
+				
+				var a, b, c, d, m, na, nb, nc, nd, material,
+					nax, nay, naz, nbx, nby, nbz, ncx, ncy, ncz, ndx, ndy, ndz;
+				
+				a  = parseUInt32( data, start + i*stride );
+				b  = parseUInt32( data, start + i*stride + md.vertex_index_bytes );
+				c  = parseUInt32( data, start + i*stride + md.vertex_index_bytes*2 );
+				d  = parseUInt32( data, start + i*stride + md.vertex_index_bytes*3 );
+				
+				m  = parseUInt16( data, start + i*stride + md.vertex_index_bytes*4 );
+				
+				na = parseUInt32( data, start + i*stride + md.vertex_index_bytes*4 + md.material_index_bytes );
+				nb = parseUInt32( data, start + i*stride + md.vertex_index_bytes*4 + md.material_index_bytes + md.normal_index_bytes );
+				nc = parseUInt32( data, start + i*stride + md.vertex_index_bytes*4 + md.material_index_bytes + md.normal_index_bytes*2 );
+				nd = parseUInt32( data, start + i*stride + md.vertex_index_bytes*4 + md.material_index_bytes + md.normal_index_bytes*3 );
+				
+				material = scope.materials[ m ];
+				
+				nax = normals[ na*3     ],
+				nay = normals[ na*3 + 1 ],
+				naz = normals[ na*3 + 2 ],
+			
+				nbx = normals[ nb*3     ],
+				nby = normals[ nb*3 + 1 ],
+				nbz = normals[ nb*3 + 2 ],
+			
+				ncx = normals[ nc*3     ],
+				ncy = normals[ nc*3 + 1 ],
+				ncz = normals[ nc*3 + 2 ];
 
-			function init_quads_flat( start ) {
+				ndx = normals[ nd*3     ],
+				ndy = normals[ nd*3 + 1 ],
+				ndz = normals[ nd*3 + 2 ];
+
+				scope.faces.push( new THREE.Face4( a, b, c, d,
+							  [new THREE.Vector3( nax, nay, naz ), 
+							   new THREE.Vector3( nbx, nby, nbz ), 
+							   new THREE.Vector3( ncx, ncy, ncz ),
+							   new THREE.Vector3( ndx, ndy, ndz )], 
+							  material ) );
+
+			}
+			
+			function add_uv3( start, i, stride, offset ) {
 				
-				var i, a, b, c, d, m, material,
-					stride = md.vertex_index_bytes * 4 + md.material_index_bytes;;
+				var uva, uvb, uvc, u1, u2, u3, v1, v2, v3, uv;
 				
-				for( i = 0; i < md.nquad_flat; ++i ) {
-					
-					a = parseUInt32( data, start + i*stride );
-					b = parseUInt32( data, start + i*stride + md.vertex_index_bytes );
-					c = parseUInt32( data, start + i*stride + md.vertex_index_bytes*2 );
-					d = parseUInt32( data, start + i*stride + md.vertex_index_bytes*3 );
-					m = parseUInt16( data, start + i*stride + md.vertex_index_bytes*4 );
+				uva = parseUInt32( data, start + i*stride + offset );
+				uvb = parseUInt32( data, start + i*stride + offset + md.uv_index_bytes );
+				uvc = parseUInt32( data, start + i*stride + offset + md.uv_index_bytes * 2 );					
+				
+				u1 = uvs[ uva*2 ];
+				v1 = uvs[ uva*2 + 1];
+				
+				u2 = uvs[ uvb*2 ];
+				v2 = uvs[ uvb*2 + 1];
+				
+				u3 = uvs[ uvc*2 ];
+				v3 = uvs[ uvc*2 + 1];
+				
+				uv = [];
+				uv.push( new THREE.UV( u1, v1 ) );
+				uv.push( new THREE.UV( u2, v2 ) );
+				uv.push( new THREE.UV( u3, v3 ) );
+				
+				scope.uvs.push( uv );
+				
+			}
+			
+			function add_uv4( start, i, stride, offset ) {
+				
+				var uva, uvb, uvc, uvd, u1, u2, u3, u4, v1, v2, v3, v4, uv;
+				
+				uva = parseUInt32( data, start + i*stride + offset );
+				uvb = parseUInt32( data, start + i*stride + offset + md.uv_index_bytes );
+				uvc = parseUInt32( data, start + i*stride + offset + md.uv_index_bytes * 2 );					
+				uvd = parseUInt32( data, start + i*stride + offset + md.uv_index_bytes * 3 );					
+				
+				u1 = uvs[ uva*2 ];
+				v1 = uvs[ uva*2 + 1];
+				
+				u2 = uvs[ uvb*2 ];
+				v2 = uvs[ uvb*2 + 1];
+				
+				u3 = uvs[ uvc*2 ];
+				v3 = uvs[ uvc*2 + 1];
+
+				u4 = uvs[ uvd*2 ];
+				v4 = uvs[ uvd*2 + 1];
+				
+				uv = [];
+				uv.push( new THREE.UV( u1, v1 ) );
+				uv.push( new THREE.UV( u2, v2 ) );
+				uv.push( new THREE.UV( u3, v3 ) );
+				uv.push( new THREE.UV( u4, v4 ) );
+				
+				scope.uvs.push( uv );
+				
+			}
+			
+			function init_triangles_flat( start ) {
+				
+				var i, stride = md.vertex_index_bytes * 3 + md.material_index_bytes;
+				
+				for( i = 0; i < md.ntri_flat; ++i ) {					
 					
-					material = scope.materials[ m ];
-					scope.faces.push( new THREE.Face4( a, b, c, d, null, material ) );
+					add_tri( start, i, stride );
 					
 				}
 				
-				return md.nquad_flat * stride;
+				return md.ntri_flat * stride;
 				
 			}
 
-			function init_quads_smooth( start ) {
+			function init_triangles_flat_uv( start ) {
 				
-				var i, a, b, c, d, m, na, nb, nc, nd, material,
-					nax, nay, naz, nbx, nby, nbz, ncx, ncy, ncz, ndx, ndy, ndz,
-					stride = md.vertex_index_bytes * 4 + md.material_index_bytes + md.normal_index_bytes * 4;
+				var i, offset = md.vertex_index_bytes * 3 + md.material_index_bytes,
+					stride = offset + md.uv_index_bytes * 3;
 				
-				for( i = 0; i < md.nquad_smooth; ++i ) {
+				for( i = 0; i < md.ntri_flat_uv; ++i ) {
+					
+					add_tri( start, i, stride );
+					add_uv3( start, i, stride, md.vertex_index_bytes*3 + md.material_index_bytes );
 					
-					a  = parseUInt32( data, start + i*stride );
-					b  = parseUInt32( data, start + i*stride + md.vertex_index_bytes );
-					c  = parseUInt32( data, start + i*stride + md.vertex_index_bytes*2 );
-					d  = parseUInt32( data, start + i*stride + md.vertex_index_bytes*3 );
-					m  = parseUInt16( data, start + i*stride + md.vertex_index_bytes*4 );
-					na = parseUInt32( data, start + i*stride + md.vertex_index_bytes*4 + md.material_index_bytes );
-					nb = parseUInt32( data, start + i*stride + md.vertex_index_bytes*4 + md.material_index_bytes + md.normal_index_bytes );
-					nc = parseUInt32( data, start + i*stride + md.vertex_index_bytes*4 + md.material_index_bytes + md.normal_index_bytes*2 );
-					nd = parseUInt32( data, start + i*stride + md.vertex_index_bytes*4 + md.material_index_bytes + md.normal_index_bytes*3 );
-					
-					material = scope.materials[ m ];
-					
-					nax = normals[ na*3     ],
-					nay = normals[ na*3 + 1 ],
-					naz = normals[ na*3 + 2 ],
-				
-					nbx = normals[ nb*3     ],
-					nby = normals[ nb*3 + 1 ],
-					nbz = normals[ nb*3 + 2 ],
-				
-					ncx = normals[ nc*3     ],
-					ncy = normals[ nc*3 + 1 ],
-					ncz = normals[ nc*3 + 2 ];
-
-					ndx = normals[ nd*3     ],
-					ndy = normals[ nd*3 + 1 ],
-					ndz = normals[ nd*3 + 2 ];
-
-					scope.faces.push( new THREE.Face4( a, b, c, d,
-								  [new THREE.Vector3( nax, nay, naz ), 
-								   new THREE.Vector3( nbx, nby, nbz ), 
-								   new THREE.Vector3( ncx, ncy, ncz ),
-								   new THREE.Vector3( ndx, ndy, ndz )], 
-								  material ) );
 				}
 				
-				return md.nquad_smooth * stride;
+				return md.ntri_flat_uv * stride;
 				
 			}
 			
-			function init_uvs_tri( start ) {
-				
-				var i, ua, ub, uc, va, vb, vc, uv,
-					stride = md.uv_coordinate_bytes * 6;
+			function init_triangles_smooth( start ) {
+			
+				var i, stride = md.vertex_index_bytes * 3 + md.material_index_bytes + md.normal_index_bytes * 3;
 				
-				for( i = 0; i < md.nuvtri; i++ ) {
-					
-					ua = parseFloat32( data, start + i*stride );
-					va = parseFloat32( data, start + i*stride + 4 );
+				for( i = 0; i < md.ntri_smooth; ++i ) {
 					
-					ub = parseFloat32( data, start + i*stride + 8 );
-					vb = parseFloat32( data, start + i*stride + 12 );
+					add_tri_n( start, i, stride );
 					
-					uc = parseFloat32( data, start + i*stride + 16 );
-					vc = parseFloat32( data, start + i*stride + 20 );
+				}
+				
+				return md.ntri_smooth * stride;
+				
+			}
+
+			function init_triangles_smooth_uv( start ) {
+			
+				var i, offset = md.vertex_index_bytes * 3 + md.material_index_bytes + md.normal_index_bytes * 3,
+					stride = offset + md.uv_index_bytes * 3;
+				
+				for( i = 0; i < md.ntri_smooth_uv; ++i ) {
 					
-					uv = [];
-					uv.push( new THREE.UV( ua, va ) );
-					uv.push( new THREE.UV( ub, vb ) );
-					uv.push( new THREE.UV( uc, vc ) );
-					scope.uvs.push( uv );
+					add_tri_n( start, i, stride );
+					add_uv3( start, i, stride, offset );
 					
 				}
 				
-				return md.nuvtri * stride;
+				return md.ntri_smooth * stride;
 				
 			}
 
-			function init_uvs_quad( start ) {
+			function init_quads_flat( start ) {
 				
-				var i, ua, ub, uc, ud, va, vb, vc, vd, uv,
-					stride = md.uv_coordinate_bytes * 8;
+				var i, stride = md.vertex_index_bytes * 4 + md.material_index_bytes;
 				
-				for( i = 0; i < md.nuvquad; i++ ) {
-					
-					ua = parseFloat32( data, start + i*stride );
-					va = parseFloat32( data, start + i*stride + 4 );
+				for( i = 0; i < md.nquad_flat; ++i ) {
 					
-					ub = parseFloat32( data, start + i*stride + 8 );
-					vb = parseFloat32( data, start + i*stride + 12 );
+					add_quad( start, i, stride );
 					
-					uc = parseFloat32( data, start + i*stride + 16 );
-					vc = parseFloat32( data, start + i*stride + 20 );
+				}
+				
+				return md.nquad_flat * stride;
+				
+			}
 
-					ud = parseFloat32( data, start + i*stride + 24 );
-					vd = parseFloat32( data, start + i*stride + 28 );
+			function init_quads_flat_uv( start ) {
+				
+				var i, offset = md.vertex_index_bytes * 4 + md.material_index_bytes,
+					stride = offset + md.uv_index_bytes * 4;
+				
+				for( i = 0; i < md.nquad_flat_uv; ++i ) {
 					
-					uv = [];
-					uv.push( new THREE.UV( ua, va ) );
-					uv.push( new THREE.UV( ub, vb ) );
-					uv.push( new THREE.UV( uc, vc ) );
-					uv.push( new THREE.UV( ud, vd ) );
-					scope.uvs.push( uv );
+					add_quad( start, i, stride );
+					add_uv4( start, i, offset );
 					
 				}
 				
-				return md.nuvquad * stride;
+				return md.nquad_flat * stride;
 				
 			}
-			
-			function init_normals( start ) {
+
+			function init_quads_smooth( start ) {
 				
-				var i, x, y, z, 
-					stride = md.normal_coordinate_bytes * 3;
+				var i, stride = md.vertex_index_bytes * 4 + md.material_index_bytes + md.normal_index_bytes * 4;
 				
-				for( i = 0; i < md.nnormals; ++i ) {
-					
-					x = parseSChar8( data, start + i*stride );
-					y = parseSChar8( data, start + i*stride + md.normal_coordinate_bytes );
-					z = parseSChar8( data, start + i*stride + md.normal_coordinate_bytes*2 );
+				for( i = 0; i < md.nquad_smooth; ++i ) {
 					
-					normals.push( x/127, y/127, z/127 );
+					add_quad_n( start, i, stride );					
+				}
+				
+				return md.nquad_smooth * stride;
+				
+			}
+
+			function init_quads_smooth_uv( start ) {
+				
+				var i, offset = md.vertex_index_bytes * 4 + md.material_index_bytes + md.normal_index_bytes * 4, 
+					stride =  offset + md.uv_index_bytes * 4;
+				
+				for( i = 0; i < md.nquad_smooth_uv; ++i ) {
 					
+					add_quad_n( start, i, stride );
+					add_uv4( start, i, stride, offset );					
 				}
 				
-				return md.nnormals * stride;
+				return md.nquad_smooth * stride;
 				
 			}
 			
@@ -557,9 +690,9 @@ THREE.Loader.prototype = {
 				}
 
 				return material;
+				
 			}
 			
-			
 		}
 		
 		Model.prototype = new THREE.Geometry();
@@ -601,8 +734,6 @@ THREE.Loader.prototype = {
 
 			function init_faces() {
 			
-				var i, l;
-
 				function add_tri( src, i, stride ) {
 
 					var a, b, c, m;
@@ -716,6 +847,7 @@ THREE.Loader.prototype = {
 					
 				}
 				
+				var i, l;
 				
 				for( i = 0, l = data.triangles.length/4; i < l; i++ ) {
 				

+ 167 - 73
utils/exporters/convert_obj_threejs_slim.py

@@ -838,27 +838,35 @@ def convert_binary(infile, outfile):
     # ###################
         
     # preprocess faces
+    
     triangles_flat = []
+    triangles_flat_uv = []
     triangles_smooth = []
+    triangles_smooth_uv = []
+    
     quads_flat = []
+    quads_flat_uv = []
     quads_smooth = []
-    faces_uv_tri = []
-    faces_uv_quad = []
+    quads_smooth_uv = []
+    
     for f in faces:
         if is_triangle_flat(f):
             triangles_flat.append(f)
+        elif is_triangle_flat_uv(f):
+            triangles_flat_uv.append(f)
         elif is_triangle_smooth(f):
             triangles_smooth.append(f)
+        elif is_triangle_smooth_uv(f):
+            triangles_smooth_uv.append(f)
+        
         elif is_quad_flat(f):
             quads_flat.append(f)
+        elif is_quad_flat_uv(f):
+            quads_flat_uv.append(f)
         elif is_quad_smooth(f):
             quads_smooth.append(f)
-            
-        ui = f['uv']
-        if len(ui) == 3:
-            faces_uv_tri.append(f)
-        elif len(ui) == 4:
-            faces_uv_quad.append(f)
+        elif is_quad_smooth_uv(f):
+            quads_smooth_uv.append(f)
     
     if SHADING == "smooth":
         nnormals = len(normals)
@@ -870,51 +878,65 @@ def convert_binary(infile, outfile):
     # header
     # ------
     header_bytes  = struct.calcsize('<8s')
-    header_bytes += struct.calcsize('<BBBBBBB')
-    header_bytes += struct.calcsize('<IIIIIIII')
+    header_bytes += struct.calcsize('<BBBBBBBB')
+    header_bytes += struct.calcsize('<IIIIIIIIIII')
     
     # signature
     signature = struct.pack('<8s', 'Three.js')
     
     # metadata (all data is little-endian)
     vertex_coordinate_bytes = 4
+    normal_coordinate_bytes = 1
+    uv_coordinate_bytes = 4
+    
     vertex_index_bytes = 4
     normal_index_bytes = 4
+    uv_index_bytes = 4
     material_index_bytes = 2
-    normal_coordinate_bytes = 1
-    uv_coordinate_bytes = 4
     
     # header_bytes            unsigned char   1
+    
     # vertex_coordinate_bytes unsigned char   1
+    # normal_coordinate_bytes unsigned char   1
+    # uv_coordinate_bytes     unsigned char   1
+    
     # vertex_index_bytes      unsigned char   1
     # normal_index_bytes      unsigned char   1
+    # uv_index_bytes          unsigned char   1
     # material_index_bytes    unsigned char   1
-    # normal_coordinate_bytes unsigned char   1
-    # uv_coordinate_bytes     unsigned char   1
-    bdata = struct.pack('<BBBBBBB', header_bytes,
+    bdata = struct.pack('<BBBBBBBB', header_bytes,
                                vertex_coordinate_bytes, 
+                               normal_coordinate_bytes,
+                               uv_coordinate_bytes,
                                vertex_index_bytes, 
                                normal_index_bytes,
-                               material_index_bytes,
-                               normal_coordinate_bytes,
-                               uv_coordinate_bytes)
-                                   
-    # nvertices    unsigned int    4
-    # ntri_flat    unsigned int    4
-    # ntri_smooth  unsigned int    4
-    # nquad_flat   unsigned int    4
-    # nquad_smooth unsigned int    4
-    # nnormals     unsigned int    4
-    # nuvtri       unsigned int    4
-    # nuvquad      unsigned int    4
-    ndata = struct.pack('<IIIIIIII', len(vertices), 
+                               uv_index_bytes,
+                               material_index_bytes)
+
+    # nvertices       unsigned int    4
+    # nnormals        unsigned int    4
+    # nuvs            unsigned int    4
+    
+    # ntri_flat       unsigned int    4
+    # ntri_smooth     unsigned int    4
+    # ntri_flat_uv    unsigned int    4
+    # ntri_smooth_uv  unsigned int    4
+    
+    # nquad_flat      unsigned int    4
+    # nquad_smooth    unsigned int    4
+    # nquad_flat_uv   unsigned int    4
+    # nquad_smooth_uv unsigned int    4    
+    ndata = struct.pack('<IIIIIIIIIII', len(vertices), 
+                               nnormals,
+                               len(uvs),
                                len(triangles_flat), 
                                len(triangles_smooth),
+                               len(triangles_flat_uv), 
+                               len(triangles_smooth_uv),
                                len(quads_flat),
                                len(quads_smooth),
-                               nnormals,
-                               len(faces_uv_tri),
-                               len(faces_uv_quad)) 
+                               len(quads_flat_uv),
+                               len(quads_smooth_uv))
     buffer.append(signature)
     buffer.append(bdata)
     buffer.append(ndata)
@@ -936,11 +958,20 @@ def convert_binary(infile, outfile):
     if SHADING == "smooth":
         for n in normals:
             normalize(n)
-            data = struct.pack('<bbb', math.floor(n[0]*127+0.5), math.floor(n[1]*127+0.5), math.floor(n[2]*127+0.5))
+            data = struct.pack('<bbb', math.floor(n[0]*127+0.5),
+                                       math.floor(n[1]*127+0.5),
+                                       math.floor(n[2]*127+0.5))
             buffer.append(data)
-
     
-    # 3. flat triangles
+    # 3. uvs
+    # -----------
+    # u float   4
+    # v float   4
+    for uv in uvs:
+        data = struct.pack('<ff', uv[0], 1.0-uv[1])
+        buffer.append(data)
+    
+    # 4. flat triangles
     # ------------------
     # a unsigned int   4
     # b unsigned int   4
@@ -948,10 +979,12 @@ def convert_binary(infile, outfile):
     # m unsigned short 2
     for f in triangles_flat:
         vi = f['vertex']
-        data = struct.pack('<IIIH', vi[0]-1, vi[1]-1, vi[2]-1, f['material'])
+        data = struct.pack('<IIIH', 
+                            vi[0]-1, vi[1]-1, vi[2]-1, 
+                            f['material'])
         buffer.append(data)
 
-    # 4. smooth triangles
+    # 5. smooth triangles
     # -------------------
     # a  unsigned int   4
     # b  unsigned int   4
@@ -963,10 +996,54 @@ def convert_binary(infile, outfile):
     for f in triangles_smooth:
         vi = f['vertex']
         ni = f['normal']
-        data = struct.pack('<IIIHIII', vi[0]-1, vi[1]-1, vi[2]-1, f['material'], ni[0]-1, ni[1]-1, ni[2]-1)
+        data = struct.pack('<IIIHIII', 
+                            vi[0]-1, vi[1]-1, vi[2]-1, 
+                            f['material'], 
+                            ni[0]-1, ni[1]-1, ni[2]-1)
         buffer.append(data)
-    
-    # 5. flat quads
+
+    # 6. flat triangles uv
+    # --------------------
+    # a  unsigned int    4
+    # b  unsigned int    4
+    # c  unsigned int    4
+    # m  unsigned short  2
+    # ua unsigned int    4
+    # ub unsigned int    4
+    # uc unsigned int    4
+    for f in triangles_flat_uv:
+        vi = f['vertex']
+        ui = f['uv']
+        data = struct.pack('<IIIHIII', 
+                            vi[0]-1, vi[1]-1, vi[2]-1, 
+                            f['material'], 
+                            ui[0]-1, ui[1]-1, ui[2]-1)
+        buffer.append(data)
+
+    # 7. smooth triangles uv
+    # ----------------------
+    # a  unsigned int    4
+    # b  unsigned int    4
+    # c  unsigned int    4
+    # m  unsigned short  2
+    # na unsigned int    4
+    # nb unsigned int    4
+    # nc unsigned int    4
+    # ua unsigned int    4
+    # ub unsigned int    4
+    # uc unsigned int    4
+    for f in triangles_smooth_uv:
+        vi = f['vertex']
+        ni = f['normal']
+        ui = f['uv']
+        data = struct.pack('<IIIHIIIIII', 
+                            vi[0]-1, vi[1]-1, vi[2]-1, 
+                            f['material'], 
+                            ni[0]-1, ni[1]-1, ni[2]-1,
+                            ui[0]-1, ui[1]-1, ui[2]-1)
+        buffer.append(data)
+
+    # 8. flat quads
     # ------------------
     # a unsigned int   4
     # b unsigned int   4
@@ -975,10 +1052,12 @@ def convert_binary(infile, outfile):
     # m unsigned short 2
     for f in quads_flat:
         vi = f['vertex']
-        data = struct.pack('<IIIIH', vi[0]-1, vi[1]-1, vi[2]-1, vi[3]-1, f['material'])
+        data = struct.pack('<IIIIH', 
+                            vi[0]-1, vi[1]-1, vi[2]-1, vi[3]-1, 
+                            f['material'])
         buffer.append(data)
             
-    # 6. smooth quads
+    # 9. smooth quads
     # -------------------
     # a  unsigned int   4
     # b  unsigned int   4
@@ -992,42 +1071,57 @@ def convert_binary(infile, outfile):
     for f in quads_smooth:
         vi = f['vertex']
         ni = f['normal']
-        data = struct.pack('<IIIIHIIII', vi[0]-1, vi[1]-1, vi[2]-1, vi[3]-1, f['material'], ni[0]-1, ni[1]-1, ni[2]-1, ni[3]-1)
+        data = struct.pack('<IIIIHIIII', 
+                            vi[0]-1, vi[1]-1, vi[2]-1, vi[3]-1, 
+                            f['material'], 
+                            ni[0]-1, ni[1]-1, ni[2]-1, ni[3]-1)
         buffer.append(data)
     
-    # 7. uvs triangles
-    # ----------------
-    # ua float      4
-    # va float      4
-    # ub float      4
-    # vb float      4
-    # uc float      4
-    # vc float      4
-    for f in faces_uv_tri:
+    # 10. flat quads uv
+    # ------------------
+    # a unsigned int   4
+    # b unsigned int   4
+    # c unsigned int   4
+    # d unsigned int   4
+    # m unsigned short 2
+    # ua unsigned int  4
+    # ub unsigned int  4
+    # uc unsigned int  4
+    # ud unsigned int  4
+    for f in quads_flat_uv:
+        vi = f['vertex']
         ui = f['uv']
-        for i in ui:
-            u = uvs[i-1][0]
-            v = 1.0 - uvs[i-1][1]
-            data = struct.pack('<ff', u,v)
-            buffer.append(data)
-    
-    # 8. uvs quads
-    # ----------------
-    # ua float      4
-    # va float      4
-    # ub float      4
-    # vb float      4
-    # uc float      4
-    # vc float      4
-    # ud float      4
-    # vd float      4
-    for f in faces_uv_quad:
+        data = struct.pack('<IIIIHIIII', 
+                            vi[0]-1, vi[1]-1, vi[2]-1, vi[3]-1, 
+                            f['material'],
+                            ui[0]-1, ui[1]-1, ui[2]-1, ui[3]-1)
+        buffer.append(data)
+
+    # 11. smooth quads uv
+    # -------------------
+    # a  unsigned int   4
+    # b  unsigned int   4
+    # c  unsigned int   4
+    # d  unsigned int   4
+    # m  unsigned short 2
+    # na unsigned int   4
+    # nb unsigned int   4
+    # nc unsigned int   4
+    # nd unsigned int   4
+    # ua unsigned int   4
+    # ub unsigned int   4
+    # uc unsigned int   4
+    # ud unsigned int   4
+    for f in quads_smooth_uv:
+        vi = f['vertex']
+        ni = f['normal']
         ui = f['uv']
-        for i in ui:
-            u = uvs[i-1][0]
-            v = 1.0 - uvs[i-1][1]
-            data = struct.pack('<ff', u,v)
-            buffer.append(data)
+        data = struct.pack('<IIIIHIIIIIIII', 
+                            vi[0]-1, vi[1]-1, vi[2]-1, vi[3]-1, 
+                            f['material'], 
+                            ni[0]-1, ni[1]-1, ni[2]-1, ni[3]-1,
+                            ui[0]-1, ui[1]-1, ui[2]-1, ui[3]-1)
+        buffer.append(data)
 
     path = os.path.dirname(outfile)
     fname = os.path.join(path, binfile)

Some files were not shown because too many files changed in this diff