提交 188f36be 编写于 作者: A alteredq

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

This saves ~22% from size of textured ASCII models.

TODO: make the same for binary model format.
上级 b14f09be
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -241,11 +241,11 @@
bwebgl.addEventListener("click", toggleWebGL, false);
var loader = new THREE.Loader();
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.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" );
......
......@@ -579,7 +579,6 @@ THREE.Loader.prototype = {
init_materials();
init_vertices();
init_uvs();
init_faces();
this.computeCentroids();
......@@ -600,108 +599,177 @@ THREE.Loader.prototype = {
}
function init_uvs() {
function init_faces() {
var i, l, ua, ub, uc, ud, va, vb, vc, vd;
for( i = 0, l = data.uvs_tri.length; i < l; i++ ) {
var i, l;
function add_tri( src, i, stride ) {
var a, b, c, m;
a = src[ i*stride ];
b = src[ i*stride + 1 ];
c = src[ i*stride + 2 ];
ua = data.uvs_tri[ i*6 ];
va = data.uvs_tri[ i*6 + 1 ];
m = src[ i*stride + 3 ];
f3( a, b, c, m );
}
function add_tri_n( src, i, stride ) {
ub = data.uvs_tri[ i*6 + 2 ];
vb = data.uvs_tri[ i*6 + 3 ];
var a, b, c, m, na, nb, nc;
uc = data.uvs_tri[ i*6 + 4 ];
vc = data.uvs_tri[ i*6 + 5 ];
a = src[ i*stride ];
b = src[ i*stride + 1 ];
c = src[ i*stride + 2 ];
uv( ua, va, ub, vb, uc, vc );
m = src[ i*stride + 3 ];
na = src[ i*stride + 4 ];
nb = src[ i*stride + 5 ];
nc = src[ i*stride + 6 ];
f3n( a, b, c, m, na, nb, nc );
}
for( i = 0, l = data.uvs_quad.length; i < l; i++ ) {
function add_quad( src, i, stride ) {
ua = data.uvs_quad[ i*8 ];
va = data.uvs_quad[ i*8 + 1 ];
var a, b, c, d, m;
ub = data.uvs_quad[ i*8 + 2 ];
vb = data.uvs_quad[ i*8 + 3 ];
a = src[ i*stride ];
b = src[ i*stride + 1 ];
c = src[ i*stride + 2 ];
d = src[ i*stride + 3 ];
uc = data.uvs_quad[ i*8 + 4 ];
vc = data.uvs_quad[ i*8 + 5 ];
m = src[ i*stride + 4 ];
ud = data.uvs_quad[ i*8 + 6 ];
vd = data.uvs_quad[ i*8 + 7 ];
f4( a, b, c, d, m );
uv( ua, va, ub, vb, uc, vc, ud, vd );
}
}
function init_faces() {
var i, l, a, b, c, d, m, na, nb, nc, nd;
function add_quad_n( src, i, stride ) {
var a, b, c, d, m, na, nb, nc, nd;
a = src[ i*stride ];
b = src[ i*stride + 1 ];
c = src[ i*stride + 2 ];
d = src[ i*stride + 3 ];
m = src[ i*stride + 4 ];
for( i = 0, l = data.triangles.length/4; i < l; i++ ) {
na = src[ i*stride + 5 ];
nb = src[ i*stride + 6 ];
nc = src[ i*stride + 7 ];
nd = src[ i*stride + 8 ];
a = data.triangles[ i*4 ];
b = data.triangles[ i*4 + 1 ];
c = data.triangles[ i*4 + 2 ];
f4n( a, b, c, d, m, na, nb, nc, nd );
m = data.triangles[ i*4 + 3 ];
}
function add_uv3( src, i, stride, offset ) {
f3( a, b, c, m );
var uva, uvb, uvc, u1, u2, u3, v1, v2, v3;
uva = src[ i*stride + offset ];
uvb = src[ i*stride + offset + 1 ];
uvc = src[ i*stride + offset + 2 ];
u1 = data.uvs[ uva*2 ];
v1 = data.uvs[ uva*2 + 1 ];
u2 = data.uvs[ uvb*2 ];
v2 = data.uvs[ uvb*2 + 1 ];
u3 = data.uvs[ uvc*2 ];
v3 = data.uvs[ uvc*2 + 1 ];
uv( u1, v1, u2, v2, u3, v3 );
}
function add_uv4( src, i, stride, offset ) {
var uva, uvb, uvc, uvd, u1, u2, u3, u4, v1, v2, v3, v4;
uva = src[ i*stride + offset ];
uvb = src[ i*stride + offset + 1 ];
uvc = src[ i*stride + offset + 2 ];
uvd = src[ i*stride + offset + 3 ];
u1 = data.uvs[ uva*2 ];
v1 = data.uvs[ uva*2 + 1 ];
u2 = data.uvs[ uvb*2 ];
v2 = data.uvs[ uvb*2 + 1 ];
u3 = data.uvs[ uvc*2 ];
v3 = data.uvs[ uvc*2 + 1 ];
u4 = data.uvs[ uvd*2 ];
v4 = data.uvs[ uvd*2 + 1 ];
uv( u1, v1, u2, v2, u3, v3, u4, v4 );
}
for( i = 0, l = data.triangles.length/4; i < l; i++ ) {
add_tri( data.triangles, i, 4 );
}
for( i = 0, l = data.triangles_n.length/7; i < l; i++ ) {
for( i = 0, l = data.triangles_uv.length/7; i < l; i++ ) {
a = data.triangles_n[ i*7 ];
b = data.triangles_n[ i*7 + 1 ];
c = data.triangles_n[ i*7 + 2 ];
add_tri( data.triangles_uv, i, 7 );
add_uv3( data.triangles_uv, i, 7, 4 );
}
for( i = 0, l = data.triangles_n.length/7; i < l; i++ ) {
m = data.triangles_n[ i*7 + 3 ];
add_tri_n( data.triangles_n, i, 7 );
na = data.triangles_n[ i*7 + 4 ];
nb = data.triangles_n[ i*7 + 5 ];
nc = data.triangles_n[ i*7 + 6 ];
}
for( i = 0, l = data.triangles_n_uv.length/10; i < l; i++ ) {
f3n( a, b, c, m, na, nb, nc );
add_tri_n( data.triangles_n_uv, i, 10 );
add_uv3( data.triangles_n_uv, i, 10, 7 );
}
for( i = 0, l = data.quads.length/5; i < l; i++ ) {
a = data.quads[ i*5 ];
b = data.quads[ i*5 + 1 ];
c = data.quads[ i*5 + 2 ];
d = data.quads[ i*5 + 3 ];
m = data.quads[ i*5 + 4 ];
add_quad( data.quads, i, 5 );
f4( a, b, c, d, m );
}
for( i = 0, l = data.quads_uv.length/9; i < l; i++ ) {
add_quad( data.quads_uv, i, 9 );
add_uv4( data.quads_uv, i, 9, 5 );
}
for( i = 0, l = data.quads_n.length/9; i < l; i++ ) {
a = data.quads_n[ i*9 ];
b = data.quads_n[ i*9 + 1 ];
c = data.quads_n[ i*9 + 2 ];
d = data.quads_n[ i*9 + 3 ];
m = data.quads_n[ i*9 + 4 ];
add_quad_n( data.quads_n, i, 9 );
na = data.quads_n[ i*9 + 5 ];
nb = data.quads_n[ i*9 + 6 ];
nc = data.quads_n[ i*9 + 7 ];
nd = data.quads_n[ i*9 + 8 ];
}
for( i = 0, l = data.quads_n_uv.length/13; i < l; i++ ) {
f4n( a, b, c, d, m, na, nb, nc, nd );
add_quad_n( data.quads_n_uv, i, 13 );
add_uv4( data.quads_n_uv, i, 13, 9 );
}
}
function v( x, y, z ) {
......@@ -709,14 +777,14 @@ THREE.Loader.prototype = {
scope.vertices.push( new THREE.Vertex( new THREE.Vector3( x, y, z ) ) );
}
function f3( a, b, c, mi ) {
var material = scope.materials[ mi ];
scope.faces.push( new THREE.Face3( a, b, c, null, material ) );
}
function f4( a, b, c, d, mi ) {
var material = scope.materials[ mi ];
......@@ -769,7 +837,7 @@ THREE.Loader.prototype = {
material ) );
}
function uv( u1, v1, u2, v2, u3, v3, u4, v4 ) {
var uv = [];
......
......@@ -156,14 +156,17 @@ var model = {
'vertices': [%(vertices)s],
'uvs_tri': [%(uvs_tri)s],
'uvs_quad': [%(uvs_quad)s],
'uvs': [%(uvs)s],
'triangles': [%(triangles)s],
'triangles_n': [%(triangles_n)s],
'triangles_uv': [%(triangles_uv)s],
'triangles_n_uv': [%(triangles_n_uv)s],
'quads': [%(quads)s],
'quads_n': [%(quads_n)s],
'quads_uv': [%(quads_uv)s],
'quads_n_uv': [%(quads_n_uv)s],
'end': (new Date).getTime()
}
......@@ -197,13 +200,20 @@ TEMPLATE_VERTEX = "%f,%f,%f"
TEMPLATE_UV_TRI = "%f,%f,%f,%f,%f,%f"
TEMPLATE_UV_QUAD = "%f,%f,%f,%f,%f,%f,%f,%f"
TEMPLATE_TRI = "%d,%d,%d,%d"
TEMPLATE_QUAD = "%d,%d,%d,%d,%d"
TEMPLATE_TRI = "%d,%d,%d,%d"
TEMPLATE_QUAD = "%d,%d,%d,%d,%d"
TEMPLATE_TRI_N = "%d,%d,%d,%d,%d,%d,%d"
TEMPLATE_QUAD_N = "%d,%d,%d,%d,%d,%d,%d,%d,%d"
TEMPLATE_TRI_UV = "%d,%d,%d,%d,%d,%d,%d"
TEMPLATE_QUAD_UV = "%d,%d,%d,%d,%d,%d,%d,%d,%d"
TEMPLATE_TRI_N = "%d,%d,%d,%d,%d,%d,%d"
TEMPLATE_QUAD_N = "%d,%d,%d,%d,%d,%d,%d,%d,%d"
TEMPLATE_TRI_N_UV = "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d"
TEMPLATE_QUAD_N_UV = "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d"
TEMPLATE_N = "%f,%f,%f"
TEMPLATE_UV = "%f,%f"
# #####################################################
# Utils
......@@ -548,40 +558,68 @@ def parse_obj(fname):
def generate_vertex(v):
return TEMPLATE_VERTEX % (v[0], v[1], v[2])
def generate_uv_tri(f, uvs):
ui = f['uv']
return TEMPLATE_UV_TRI % (uvs[ui[0]-1][0], 1.0 - uvs[ui[0]-1][1],
uvs[ui[1]-1][0], 1.0 - uvs[ui[1]-1][1],
uvs[ui[2]-1][0], 1.0 - uvs[ui[2]-1][1])
def generate_uv_quad(f, uvs):
ui = f['uv']
return TEMPLATE_UV_QUAD % (uvs[ui[0]-1][0], 1.0 - uvs[ui[0]-1][1],
uvs[ui[1]-1][0], 1.0 - uvs[ui[1]-1][1],
uvs[ui[2]-1][0], 1.0 - uvs[ui[2]-1][1],
uvs[ui[3]-1][0], 1.0 - uvs[ui[3]-1][1])
def generate_triangle(f):
vi = f['vertex']
return TEMPLATE_TRI % (vi[0]-1, vi[1]-1, vi[2]-1, f['material'])
v = f['vertex']
return TEMPLATE_TRI % (v[0]-1, v[1]-1, v[2]-1,
f['material'])
def generate_triangle_uv(f):
v = f['vertex']
uv = f['uv']
return TEMPLATE_TRI_UV % (v[0]-1, v[1]-1, v[2]-1,
f['material'],
uv[0]-1, uv[1]-1, uv[2]-1)
def generate_triangle_n(f):
vi = f['vertex']
ni = f['normal']
return TEMPLATE_TRI_N % (vi[0]-1, vi[1]-1, vi[2]-1, f['material'], ni[0]-1, ni[1]-1, ni[2]-1)
v = f['vertex']
n = f['normal']
return TEMPLATE_TRI_N % (v[0]-1, v[1]-1, v[2]-1,
f['material'],
n[0]-1, n[1]-1, n[2]-1)
def generate_triangle_n_uv(f):
v = f['vertex']
n = f['normal']
uv = f['uv']
return TEMPLATE_TRI_N_UV % (v[0]-1, v[1]-1, v[2]-1,
f['material'],
n[0]-1, n[1]-1, n[2]-1,
uv[0]-1, uv[1]-1, uv[2]-1)
def generate_quad(f):
vi = f['vertex']
return TEMPLATE_QUAD % (vi[0]-1, vi[1]-1, vi[2]-1, vi[3]-1, f['material'])
return TEMPLATE_QUAD % (vi[0]-1, vi[1]-1, vi[2]-1, vi[3]-1,
f['material'])
def generate_quad_uv(f):
v = f['vertex']
uv = f['uv']
return TEMPLATE_QUAD_UV % (v[0]-1, v[1]-1, v[2]-1, v[3]-1,
f['material'],
uv[0]-1, uv[1]-1, uv[2]-1, uv[3]-1)
def generate_quad_n(f):
vi = f['vertex']
ni = f['normal']
return TEMPLATE_QUAD_N % (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)
v = f['vertex']
n = f['normal']
return TEMPLATE_QUAD_N % (v[0]-1, v[1]-1, v[2]-1, v[3]-1,
f['material'],
n[0]-1, n[1]-1, n[2]-1, n[3]-1)
def generate_quad_n_uv(f):
v = f['vertex']
n = f['normal']
uv = f['uv']
return TEMPLATE_QUAD_N_UV % (v[0]-1, v[1]-1, v[2]-1, v[3]-1,
f['material'],
n[0]-1, n[1]-1, n[2]-1, n[3]-1,
uv[0]-1, uv[1]-1, uv[2]-1, uv[3]-1)
def generate_normal(n):
return TEMPLATE_N % (n[0], n[1], n[2])
def generate_uv(uv):
return TEMPLATE_UV % (uv[0], 1.0 - uv[1])
# #####################################################
# Materials
# #####################################################
......@@ -675,16 +713,28 @@ def generate_materials_string(materials, mtllib):
# Faces
# #####################################################
def is_triangle_flat(f):
return len(f['vertex'])==3 and not (f["normal"] and SHADING == "smooth")
return len(f['vertex'])==3 and not (f["normal"] and SHADING == "smooth") and not f['uv']
def is_triangle_flat_uv(f):
return len(f['vertex'])==3 and not (f["normal"] and SHADING == "smooth") and len(f['uv'])==3
def is_triangle_smooth(f):
return len(f['vertex'])==3 and f["normal"] and SHADING == "smooth"
return len(f['vertex'])==3 and f["normal"] and SHADING == "smooth" and not f['uv']
def is_triangle_smooth_uv(f):
return len(f['vertex'])==3 and f["normal"] and SHADING == "smooth" and len(f['uv'])==3
def is_quad_flat(f):
return len(f['vertex'])==4 and not (f["normal"] and SHADING == "smooth")
return len(f['vertex'])==4 and not (f["normal"] and SHADING == "smooth") and not f['uv']
def is_quad_flat_uv(f):
return len(f['vertex'])==4 and not (f["normal"] and SHADING == "smooth") and len(f['uv'])==4
def is_quad_smooth(f):
return len(f['vertex'])==4 and f["normal"] and SHADING == "smooth"
return len(f['vertex'])==4 and f["normal"] and SHADING == "smooth" and not f['uv']
def is_quad_smooth_uv(f):
return len(f['vertex'])==4 and f["normal"] and SHADING == "smooth" and len(f['uv'])==4
# #####################################################
# API - ASCII converter
......@@ -708,27 +758,24 @@ def convert_ascii(infile, outfile):
bottom(vertices)
elif ALIGN == "top":
top(vertices)
uv_string_tri = ""
uv_string_quad = ""
if len(uvs)>0:
uv_string_tri = ",".join([generate_uv_tri(f, uvs) for f in faces if len(f['uv']) == 3])
uv_string_quad = ",".join([generate_uv_quad(f, uvs) for f in faces if len(f['uv']) == 4])
normals_string = ""
if SHADING == "smooth":
normals_string = ",".join(generate_normal(n) for n in normals)
text = TEMPLATE_FILE_ASCII % {
"name" : get_name(outfile),
"vertices" : ",".join([generate_vertex(v) for v in vertices]),
"triangles" : ",".join([generate_triangle(f) for f in faces if is_triangle_flat(f)]),
"triangles_n": ",".join([generate_triangle_n(f) for f in faces if is_triangle_smooth(f)]),
"quads" : ",".join([generate_quad(f) for f in faces if is_quad_flat(f)]),
"quads_n" : ",".join([generate_quad_n(f) for f in faces if is_quad_smooth(f)]),
"uvs_tri" : uv_string_tri,
"uvs_quad" : uv_string_quad,
"normals" : normals_string,
"name" : get_name(outfile),
"vertices" : ",".join([generate_vertex(v) for v in vertices]),
"triangles" : ",".join([generate_triangle(f) for f in faces if is_triangle_flat(f)]),
"triangles_n" : ",".join([generate_triangle_n(f) for f in faces if is_triangle_smooth(f)]),
"triangles_uv" : ",".join([generate_triangle_uv(f) for f in faces if is_triangle_flat_uv(f)]),
"triangles_n_uv": ",".join([generate_triangle_n_uv(f) for f in faces if is_triangle_smooth_uv(f)]),
"quads" : ",".join([generate_quad(f) for f in faces if is_quad_flat(f)]),
"quads_n" : ",".join([generate_quad_n(f) for f in faces if is_quad_smooth(f)]),
"quads_uv" : ",".join([generate_quad_uv(f) for f in faces if is_quad_flat_uv(f)]),
"quads_n_uv" : ",".join([generate_quad_n_uv(f) for f in faces if is_quad_smooth_uv(f)]),
"uvs" : ",".join([generate_uv(uv) for uv in uvs]),
"normals" : normals_string,
"materials" : generate_materials_string(materials, mtllib),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册