<?php
readObj = function(txt)
{
console.log('readObj...');
let objects = [];
let materials = [];
objects.push( { 'name':'test', 'v':[], 'vt':[], 'vn':[], 'f':[], 'usemtl':'' } );
let data = { 'v':[], 'n':[], 'f':[], 'm':[] };
txt = txt.replaceAll(' ', ' ');
let lines = txt.split('\n');
console.log('num lines:', lines.length );
let curmat = -1;
for (let i=0; i<lines.length; i++)
{
let line = lines[i];
line = line.trim()
if ( line.length < 2 ) continue;
if ( line[0] == '#' ) continue;
let parts = line.split(' ');
if ( parts.length < 1 ) continue;
try{
switch( parts[0] )
{
case 'usemtl':
{
let matname = parts[1];
if ( !materials.includes( matname ) )
{
materials.push( matname );
}
curmat = materials.indexOf( matname );
//console.log( 'curmat:', curmat );
}
break;
case 'v': // v 0.089624 1.419387 0.052847
{
objects.reverse()[0].v.push( parts[1] );
objects.reverse()[0].v.push( parts[2] );
objects.reverse()[0].v.push( parts[3] );
}
break;
case 'vt': // vt 0.818181 0.000000
{
objects.reverse()[0].vt.push( parts[1] );
objects.reverse()[0].vt.push( parts[2] );
}
break;
case 'vn': // vn 0.5499 0.7413 0.3847
{
objects.reverse()[0].vn.push( parts[1] );
objects.reverse()[0].vn.push( parts[2] );
objects.reverse()[0].vn.push( parts[3] );
}
break;
case 'f': // f 1/1/1 14/2/1 13/3/1
{
// f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 ...
// f v1//vn1 v2//vn2 v3//vn3 ... (double slashes)
/*
If you have 4 indices, e.g.:
0 1 2 3
The division into two triangles would be one with the first 3 indices, and one with the first, third, and fourth. In this example:
0 1 2
0 2 3
Let's try some ASCII art to illustrate this:
3-------2
| /|
| / |
| / |
|/ |
0-------1
*/
let i0 = parts[1].split('/')[0]-1;
let i1 = parts[2].split('/')[0]-1;
let i2 = parts[3].split('/')[0]-1;
let i3 = parts.length ==4 ? undefined : (parts[4].split('/')[0]-1);
let n0 = parts[1].split('/')[2]-1;
let n1 = parts[2].split('/')[2]-1;
let n2 = parts[3].split('/')[2]-1;
let n3 = parts.length ==4 ? undefined : (parts[4].split('/')[2]-1);
if ( parts[1].includes('//') )
{
n0 = parts[1].split('//')[1]-1;
n1 = parts[2].split('//')[1]-1;
n2 = parts[3].split('//')[1]-1;
n3 = parts.length == 4 ? undefined : (parts[4].split('//')[1]-1);
}
if ( i3 == undefined ) // triangles
{
let v = []
for (let g=0; g<3; g++)
{
let idx = [i0,i1,i2][g];
let x0 = objects.reverse()[0].v[ (3* idx)+0 ];
let y0 = objects.reverse()[0].v[ (3* idx)+1 ];
let z0 = objects.reverse()[0].v[ (3* idx)+2 ];
v.push( { x:x0, y:y0, z:z0 } );
}
data.v.push( v[0].x ); data.v.push( v[0].y ); data.v.push( v[0].z );
data.v.push( v[1].x ); data.v.push( v[1].y ); data.v.push( v[1].z );
data.v.push( v[2].x ); data.v.push( v[2].y ); data.v.push( v[2].z );
data.m.push( curmat );
data.m.push( curmat );
data.m.push( curmat );
data.f.push( data.f.length );
data.f.push( data.f.length );
data.f.push( data.f.length );
let n = [];
for (let g=0; g<[n0,n1,n2].length; g++)
{
let nx0 = objects.reverse()[0].vn[ 3*[n0,n1,n2][g]+0 ];
let ny0 = objects.reverse()[0].vn[ 3*[n0,n1,n2][g]+1 ];
let nz0 = objects.reverse()[0].vn[ 3*[n0,n1,n2][g]+2 ];
n.push( { x:nx0, y:ny0, z:nz0 } );
}
data.n.push( n[0].x ); data.n.push( n[0].y ); data.n.push( n[0].z );
data.n.push( n[1].x ); data.n.push( n[1].y ); data.n.push( n[1].z );
data.n.push( n[2].x ); data.n.push( n[2].y ); data.n.push( n[2].z );
}
else // quads
{
let v = [];
for (let g=0; g<4; g++)
{
let idx = [i0,i1,i2,i3][g];
let x0 = objects.reverse()[0].v[ (3* idx)+0 ];
let y0 = objects.reverse()[0].v[ (3* idx)+1 ];
let z0 = objects.reverse()[0].v[ (3* idx)+2 ];
v.push( { x:x0, y:y0, z:z0 } );
}
data.v.push( v[0].x ); data.v.push( v[0].y ); data.v.push( v[0].z );
data.v.push( v[1].x ); data.v.push( v[1].y ); data.v.push( v[1].z );
data.v.push( v[2].x ); data.v.push( v[2].y ); data.v.push( v[2].z );
data.m.push( curmat );
data.m.push( curmat );
data.m.push( curmat );
data.f.push( data.f.length );
data.f.push( data.f.length );
data.f.push( data.f.length );
data.v.push( v[0].x ); data.v.push( v[0].y ); data.v.push( v[0].z );
data.v.push( v[2].x ); data.v.push( v[2].y ); data.v.push( v[2].z );
data.v.push( v[3].x ); data.v.push( v[3].y ); data.v.push( v[3].z );
data.m.push( curmat );
data.m.push( curmat );
data.m.push( curmat );
data.f.push( data.f.length );
data.f.push( data.f.length );
data.f.push( data.f.length );
let n = [];
for (let g=0; g<4; g++)
{
let idx = [n0,n1,n2,n3][g];
let nx0 = objects.reverse()[0].vn[ (3* idx)+0 ];
let ny0 = objects.reverse()[0].vn[ (3* idx)+1 ];
let nz0 = objects.reverse()[0].vn[ (3* idx)+2 ];
n.push( { x:nx0, y:ny0, z:nz0 } );
}
data.n.push( n[0].x ); data.n.push( n[0].y ); data.n.push( n[0].z );
data.n.push( n[1].x ); data.n.push( n[1].y ); data.n.push( n[1].z );
data.n.push( n[2].x ); data.n.push( n[2].y ); data.n.push( n[2].z );
data.n.push( n[0].x ); data.n.push( n[0].y ); data.n.push( n[0].z );
data.n.push( n[2].x ); data.n.push( n[2].y ); data.n.push( n[2].z );
data.n.push( n[3].x ); data.n.push( n[3].y ); data.n.push( n[3].z );
}
}
break;
}// end switch(..)
}catch(e){ }
}// for
console.log( 'dump:', data.m.slice(0, 20) );
return [ data ];
}// readObj(..)