diff --git a/lib/loadObj.js b/lib/loadObj.js index bdca9b4..7fdf897 100644 --- a/lib/loadObj.js +++ b/lib/loadObj.js @@ -109,10 +109,7 @@ function loadObj(objPath, options) { var mtlPaths = []; // Buffers for face data that spans multiple lines - var faceVertices = []; - var facePositions = []; - var faceUvs = []; - var faceNormals = []; + var lineBuffer = ""; function getName(name) { return (name === '' ? undefined : name); @@ -455,10 +452,14 @@ function loadObj(objPath, options) { function parseFaceLine(line, hasUvs, hasNormals) { // get vertex data (attributes '/' separated) - faceVertices = faceVertices.concat(line.replace(faceSpacePattern, ' ').split(' ').filter(trimEmpty)); + var faceVertices = line.replace(faceSpacePattern, ' ').split(' ').filter(trimEmpty); // get all vertex attributes for this line var faceAttributes = line.replace(faceSpaceOrSlashPattern, ' ').split(' ').filter(trimEmpty); + var facePositions = []; + var faceUvs = []; + var faceNormals = []; + var i; if (hasUvs && hasNormals) { for (i=0; i <= faceAttributes.length - 3; i += 3) @@ -489,19 +490,7 @@ function loadObj(objPath, options) { faceUvs = undefined; faceNormals = undefined; } - - // If there's a line continuation, buffer the results and don't create face yet - if (line.slice(-1) === '\\') { - return; - } - addFace(faceVertices, facePositions, faceUvs, faceNormals); - - // Clear buffered data once face has been added. - faceVertices = []; - facePositions = []; - faceUvs = []; - faceNormals = []; } function parseLine(line) { @@ -548,18 +537,25 @@ function loadObj(objPath, options) { uvs.push(parseFloat(result[1])); uvs.push(1.0 - parseFloat(result[2])); // Flip y so 0.0 is the bottom of the image } else { // face line or invalid line - // If we already have buffered data, this is a continued line - var continuedLine = faceVertices.length > 0; - if (facePattern1.test(line) || (continuedLine && facePattern5.test(line))) { // format "f v v v ..." + // Because face lines can contain n vertices, we use a line buffer in case the face data spans multiple lines. + // If there's a line continuation don't create face yet + if (line.slice(-1) === '\\') { + lineBuffer += line.substring(0, -1); + return; + } + + lineBuffer += line; + if (facePattern1.test(lineBuffer)) { // format "f v v v ..." parseFaceLine(line, false, false); - } else if (facePattern2.test(line) || (continuedLine && facePattern6.test(line))) { // format "f v/uv v/uv v/uv ..." + } else if (facePattern2.test(lineBuffer)) { // format "f v/uv v/uv v/uv ..." parseFaceLine(line, true, false); - } else if (facePattern3.test(line) || (continuedLine && facePattern7.test(line))) { // format "v/uv/n v/uv/n v/uv/n ..." + } else if (facePattern3.test(lineBuffer)) { // format "v/uv/n v/uv/n v/uv/n ..." parseFaceLine(line, true, true); - } else if (facePattern4.test(line) || (continuedLine && facePattern8.test(line))) { // format "v//n v//n v//n ..." + } else if (facePattern4.test(lineBuffer)) { // format "v//n v//n v//n ..." parseFaceLine(line, false, true); } + lineBuffer = ""; } }