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.
This commit is contained in:
alteredq
2010-11-08 23:20:25 +01:00
parent ecf97e0d4c
commit a0fa2ae3dd
10 changed files with 530 additions and 304 deletions
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+6 -6
View File
@@ -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" );
}
+353 -221
View File
@@ -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 ),
'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 + 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 ),
'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( "vertex_index_bytes: " + metaData.vertex_index_bytes );
log( "normal_index_bytes: " + metaData.normal_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( "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( "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,199 +292,6 @@ THREE.Loader.prototype = {
}
function init_triangles_flat( start ) {
var i, a, b, c, m, material,
stride = md.vertex_index_bytes * 3 + md.material_index_bytes;
for( i = 0; i < md.ntri_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 );
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 ) );
}
return md.ntri_flat * 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;
for( i = 0; i < md.ntri_smooth; ++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 );
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 ) );
}
return md.ntri_smooth * stride;
}
function init_quads_flat( start ) {
var i, a, b, c, d, m, material,
stride = md.vertex_index_bytes * 4 + md.material_index_bytes;;
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 );
material = scope.materials[ m ];
scope.faces.push( new THREE.Face4( a, b, c, d, null, material ) );
}
return md.nquad_flat * stride;
}
function init_quads_smooth( 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;
for( i = 0; i < md.nquad_smooth; ++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 );
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;
}
function init_uvs_tri( start ) {
var i, ua, ub, uc, va, vb, vc, uv,
stride = md.uv_coordinate_bytes * 6;
for( i = 0; i < md.nuvtri; i++ ) {
ua = parseFloat32( data, start + i*stride );
va = parseFloat32( data, start + i*stride + 4 );
ub = parseFloat32( data, start + i*stride + 8 );
vb = parseFloat32( data, start + i*stride + 12 );
uc = parseFloat32( data, start + i*stride + 16 );
vc = parseFloat32( data, start + i*stride + 20 );
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 );
}
return md.nuvtri * stride;
}
function init_uvs_quad( start ) {
var i, ua, ub, uc, ud, va, vb, vc, vd, uv,
stride = md.uv_coordinate_bytes * 8;
for( i = 0; i < md.nuvquad; i++ ) {
ua = parseFloat32( data, start + i*stride );
va = parseFloat32( data, start + i*stride + 4 );
ub = parseFloat32( data, start + i*stride + 8 );
vb = parseFloat32( data, start + i*stride + 12 );
uc = parseFloat32( data, start + i*stride + 16 );
vc = parseFloat32( data, start + i*stride + 20 );
ud = parseFloat32( data, start + i*stride + 24 );
vd = parseFloat32( data, start + i*stride + 28 );
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 );
}
return md.nuvquad * stride;
}
function init_normals( start ) {
var i, x, y, z,
@@ -482,6 +310,311 @@ THREE.Loader.prototype = {
return md.nnormals * stride;
}
function init_uvs( start ) {
var i, u, v,
stride = md.uv_coordinate_bytes * 2;
for( i = 0; i < md.nuvs; ++i ) {
u = parseFloat32( data, start + i*stride );
v = parseFloat32( data, start + i*stride + md.uv_coordinate_bytes );
uvs.push( u, v );
}
return md.nuvs * stride;
}
function add_tri( start, i, stride ) {
var a, b, c, 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 );
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 ];
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 uva, uvb, uvc, u1, u2, u3, v1, v2, v3, 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 );
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 ) {
add_tri( start, i, stride );
}
return md.ntri_flat * stride;
}
function init_triangles_flat_uv( start ) {
var i, offset = md.vertex_index_bytes * 3 + md.material_index_bytes,
stride = offset + md.uv_index_bytes * 3;
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 );
}
return md.ntri_flat_uv * stride;
}
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.ntri_smooth; ++i ) {
add_tri_n( start, i, stride );
}
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 ) {
add_tri_n( start, i, stride );
add_uv3( start, i, stride, offset );
}
return md.ntri_smooth * stride;
}
function init_quads_flat( start ) {
var i, stride = md.vertex_index_bytes * 4 + md.material_index_bytes;
for( i = 0; i < md.nquad_flat; ++i ) {
add_quad( start, i, stride );
}
return md.nquad_flat * stride;
}
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 ) {
add_quad( start, i, stride );
add_uv4( start, i, offset );
}
return md.nquad_flat * stride;
}
function init_quads_smooth( start ) {
var i, stride = md.vertex_index_bytes * 4 + md.material_index_bytes + md.normal_index_bytes * 4;
for( i = 0; i < md.nquad_smooth; ++i ) {
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.nquad_smooth * stride;
}
function init_materials() {
@@ -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++ ) {
+169 -75
View File
@@ -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
vertex_index_bytes = 4
normal_index_bytes = 4
material_index_bytes = 2
normal_coordinate_bytes = 1
uv_coordinate_bytes = 4
vertex_index_bytes = 4
normal_index_bytes = 4
uv_index_bytes = 4
material_index_bytes = 2
# header_bytes unsigned char 1
# vertex_coordinate_bytes unsigned char 1
# vertex_index_bytes unsigned char 1
# normal_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,
# vertex_index_bytes unsigned char 1
# normal_index_bytes unsigned char 1
# uv_index_bytes unsigned char 1
# material_index_bytes unsigned char 1
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)