diff --git a/lib/loadObj.js b/lib/loadObj.js index 148ff31..eb8b464 100644 --- a/lib/loadObj.js +++ b/lib/loadObj.js @@ -44,11 +44,13 @@ function Primitive() { var vertexPattern = /v( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)/; // v float float float var normalPattern = /vn( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)/; // vn float float float var uvPattern = /vt( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)/; // vt float float -var facePattern1 = /f( +-?\d+)\/?( +-?\d+)\/?( +-?\d+)\/?( +-?\d+)?\/?/; // f vertex vertex vertex ... -var facePattern2 = /f( +(-?\d+)\/(-?\d+)\/?)( +(-?\d+)\/(-?\d+)\/?)( +(-?\d+)\/(-?\d+)\/?)( +(-?\d+)\/(-?\d+)\/?)?/; // f vertex/uv vertex/uv vertex/uv ... -var facePattern3 = /f( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))?/; // f vertex/uv/normal vertex/uv/normal vertex/uv/normal ... -var facePattern4 = /f( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))?/; // f vertex//normal vertex//normal vertex//normal ... +var facePattern1 = /f(\s+-?\d+\/?\/?){3,}/; // f vertex vertex vertex ... +var facePattern2 = /f(\s+-?\d+\/-?\d+){3,}/; // f vertex/uv vertex/uv vertex/uv ... +var facePattern3 = /f(\s+-?\d+\/-?\d+\/-?\d+){3,}/; // f vertex/uv/normal vertex/uv/normal vertex/uv/normal ... +var facePattern4 = /f(\s+-?\d+\/\/-?\d+){3,}/; // f vertex//normal vertex//normal vertex//normal ... +var faceSpacePattern = /f?\s+/; +var faceSpaceOrSlashPattern = /(f?\s+)|(\/+\s*)/g; var scratchCartesian = new Cartesian3(); /** @@ -195,7 +197,33 @@ function loadObj(objPath, options) { return index; } - function addFace(v1, p1, u1, n1, v2, p2, u2, n2, v3, p3, u3, n3, v4, p4, u4, n4) { + function addFace(vertices, positions, uvs, normals) { + + var u1, u2, u3, u4, n1, n2, n3, n4; + + var v1 = vertices[0]; + var v2 = vertices[1]; + var v3 = vertices[2]; + var v4 = vertices[3]; + var p1 = positions[0]; + var p2 = positions[1]; + var p3 = positions[2]; + var p4 = positions[3]; + + if (uvs) { + u1 = uvs[0]; + u2 = uvs[1]; + u3 = uvs[2]; + u4 = uvs[3]; + } + + if (normals) { + n1 = normals[0]; + n2 = normals[1]; + n3 = normals[2]; + n4 = normals[3]; + } + var index1 = addVertex(v1, p1, u1, n1); var index2 = addVertex(v2, p2, u2, n2); var index3 = addVertex(v3, p3, u3, n3); @@ -211,6 +239,7 @@ function loadObj(objPath, options) { primitive.indices.push(index3); primitive.indices.push(index4); } + } function parseLine(line) { @@ -256,34 +285,47 @@ function loadObj(objPath, options) { } else if ((result = uvPattern.exec(line)) !== null) { uvs.push(parseFloat(result[1])); uvs.push(1.0 - parseFloat(result[2])); // Flip y so 0.0 is the bottom of the image - } else if ((result = facePattern1.exec(line)) !== null) { - addFace( - result[1], result[1], undefined, undefined, - result[2], result[2], undefined, undefined, - result[3], result[3], undefined, undefined, - result[4], result[4], undefined, undefined - ); - } else if ((result = facePattern2.exec(line)) !== null) { - addFace( - result[1], result[2], result[3], undefined, - result[4], result[5], result[6], undefined, - result[7], result[8], result[9], undefined, - result[10], result[11], result[12], undefined - ); - } else if ((result = facePattern3.exec(line)) !== null) { - addFace( - result[1], result[2], result[3], result[4], - result[5], result[6], result[7], result[8], - result[9], result[10], result[11], result[12], - result[13], result[14], result[15], result[16] - ); - } else if ((result = facePattern4.exec(line)) !== null) { - addFace( - result[1], result[2], undefined, result[3], - result[4], result[5], undefined, result[6], - result[7], result[8], undefined, result[9], - result[10], result[11], undefined, result[12] - ); + } else if (facePattern1.test(line)) { // format "f v v v ..." + var faceVertices = line.replace(faceSpaceOrSlashPattern, ' ').substring(1).split(' '); // get vertices + addFace(faceVertices, faceVertices, undefined, undefined); + } else if (facePattern2.test(line)) { // format "f v/uv v/uv v/uv ..." + var faceVertices = line.replace(faceSpacePattern, ' ').substring(1).split(' '); // get vertex data (attributes '/' separated) + var faceAttributes = line.replace(faceSpaceOrSlashPattern, ' ').substring(1).split(' '); // get vertex attributes + + var facePositions = []; + var faceUvs = []; + for (var i=0; i <= faceAttributes.length - 2; i += 2) + { + facePositions.push(faceAttributes[i]); + faceUvs.push(faceAttributes[i+1]); + } + addFace(faceVertices, facePositions, faceUvs, undefined); + } else if (facePattern3.test(line)) { // format "v/uv/n v/uv/n v/uv/n ..." + var faceVertices = line.replace(faceSpacePattern, ' ').substring(1).split(' '); // get vertex data (attributes '/' separated) + var faceAttributes = line.replace(faceSpaceOrSlashPattern, ' ').substring(1).split(' '); // get vertex attributes + + var facePositions = []; + var faceUvs = []; + var faceNormals = []; + for (var i=0; i <= faceAttributes.length - 3; i += 3) + { + facePositions.push(faceAttributes[i]); + faceUvs.push(faceAttributes[i+1]); + faceNormals.push(faceAttributes[i+2]); + } + addFace(faceVertices, facePositions, faceUvs, faceNormals); + } else if (facePattern4.test(line)) { // format "v//n v//n v//n ..." + var faceVertices = line.replace(faceSpacePattern, ' ').substring(1).split(' '); // get vertex data (attributes '/' separated) + var faceAttributes = line.replace(faceSpaceOrSlashPattern, ' ').substring(1).split(' '); // get vertex attributes + + var facePositions = []; + var faceNormals = []; + for (var i=0; i <= faceAttributes.length - 2; i += 2) + { + facePositions.push(faceAttributes[i]); + faceNormals.push(faceAttributes[i+1]); + } + addFace(faceVertices, facePositions, undefined, faceNormals); } }