Read lines from stream and handle negative indices

This commit is contained in:
Sean Lilley 2016-06-22 16:16:29 -04:00
parent fec860ede0
commit 31760c34a8
2 changed files with 84 additions and 70 deletions

View File

@ -327,7 +327,7 @@ function createGltf(data, inputPath, modelName, done) {
}
if (bufferSeparate) {
var bufferPath = path.join(path.dirname(inputPath), modelName + '.bin');
var bufferPath = path.join(inputPath, modelName + '.bin');
fs.writeFile(bufferPath, buffer, function(err) {
if (err) {
throw err;

View File

@ -2,6 +2,7 @@
var async = require('async');
var fs = require('fs-extra');
var path = require('path');
var readline = require('readline');
var loadImage = require('./image');
var Material = require('./mtl');
var Cesium = require('cesium');
@ -33,7 +34,7 @@ function processObj(objFile, info, materials, images, done) {
var uvs = [];
var positionMin = [Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE];
var positionMax = [Number.MIN_VALUE, Number.MIN_VALUE, Number.MIN_VALUE];
var positionMax = [-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE];
var hasNormals = info.hasNormals;
var hasUVs = info.hasUVs;
@ -67,12 +68,22 @@ function processObj(objFile, info, materials, images, done) {
useDefaultMaterial();
}
function getOffset(a, data, components) {
var i = parseInt(a);
if (i < 0) {
// Negative vertex indexes reference the vertices immediately above it
return (data.length / components + i) * components;
}
return (i - 1) * components;
}
function createVertex(p, u, n) {
// Positions
var pi = (parseInt(p) - 1) * 3;
var pi = getOffset(p, positions, 3);
var px = positions[pi + 0];
var py = positions[pi + 1];
var pz = positions[pi + 2];
positionMin[0] = Math.min(px, positionMin[0]);
positionMin[1] = Math.min(py, positionMin[1]);
positionMin[2] = Math.min(pz, positionMin[2]);
@ -83,7 +94,7 @@ function processObj(objFile, info, materials, images, done) {
// Normals
if (hasNormals) {
var ni = (parseInt(n) - 1) * 3;
var ni = getOffset(n, normals, 3);
var nx = normals[ni + 0];
var ny = normals[ni + 1];
var nz = normals[ni + 2];
@ -93,7 +104,7 @@ function processObj(objFile, info, materials, images, done) {
// UVs
if (hasUVs) {
if (defined(u)) {
var ui = (parseInt(u) - 1) * 2;
var ui = getOffset(u, uvs, 2);
var ux = uvs[ui + 0];
var uy = uvs[ui + 1];
vertexArray.push(ux, uy);
@ -155,68 +166,67 @@ function processObj(objFile, info, materials, images, done) {
var facePattern4 = /f( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))?/;
var stream = fs.createReadStream(objFile, 'utf8');
var reader = readline.createInterface({
input : stream
});
stream.on('data', function(chunk) {
var lines = chunk.split('\n');
length = lines.length;
for (i = 0; i < length; ++i) {
var line = lines[i].trim();
var result;
if ((line.length === 0) || (line.charAt(0) === '#')) {
continue;
} else if ((result = vertexPattern.exec(line)) !== null) {
positions.push(
parseFloat(result[1]),
parseFloat(result[2]),
parseFloat(result[3])
);
} else if ((result = normalPattern.exec(line) ) !== null) {
var nx = parseFloat(result[1]);
var ny = parseFloat(result[2]);
var nz = parseFloat(result[3]);
var normal = Cartesian3.normalize(new Cartesian3(nx, ny, nz), new Cartesian3());
normals.push(normal.x, normal.y, normal.z);
} else if ((result = uvPattern.exec(line)) !== null) {
uvs.push(
parseFloat(result[1]),
parseFloat(result[2])
);
} 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 (/^usemtl /.test(line)) {
var materialName = line.substring(7).trim();
useMaterial(materialName);
}
reader.on('line', function(line) {
line = line.trim();
var result;
if ((line.length === 0) || (line.charAt(0) === '#')) {
// Nothing to process
} else if ((result = vertexPattern.exec(line)) !== null) {
positions.push(
parseFloat(result[1]),
parseFloat(result[2]),
parseFloat(result[3])
);
} else if ((result = normalPattern.exec(line) ) !== null) {
var nx = parseFloat(result[1]);
var ny = parseFloat(result[2]);
var nz = parseFloat(result[3]);
var normal = Cartesian3.normalize(new Cartesian3(nx, ny, nz), new Cartesian3());
normals.push(normal.x, normal.y, normal.z);
} else if ((result = uvPattern.exec(line)) !== null) {
uvs.push(
parseFloat(result[1]),
parseFloat(result[2])
);
} 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 (/^usemtl /.test(line)) {
var materialName = line.substring(7).trim();
useMaterial(materialName);
}
});
stream.on('end', function() {
reader.on('close', function() {
done({
vertexCount : vertexCount,
vertexArray : vertexArray,
@ -299,9 +309,13 @@ function getObjInfo(objFile, inputPath, done) {
var hasUVs = false;
var stream = fs.createReadStream(objFile, 'utf8');
stream.on('data', function(chunk) {
var reader = readline.createInterface({
input : stream
});
reader.on('line', function(line) {
if (!defined(mtlPath)) {
var mtllibMatches = chunk.match(/^mtllib.*/gm);
var mtllibMatches = line.match(/^mtllib.*/gm);
if (mtllibMatches !== null) {
var mtlFile = mtllibMatches[0].substring(7).trim();
mtlPath = mtlFile;
@ -311,20 +325,20 @@ function getObjInfo(objFile, inputPath, done) {
}
}
if (!hasMaterialGroups) {
hasMaterialGroups = /^usemtl/gm.test(chunk);
hasMaterialGroups = /^usemtl/gm.test(line);
}
if (!hasPositions) {
hasPositions = /^v\s/gm.test(chunk);
hasPositions = /^v\s/gm.test(line);
}
if (!hasNormals) {
hasNormals = /^vn/gm.test(chunk);
hasNormals = /^vn/gm.test(line);
}
if (!hasUVs) {
hasUVs = /^vt/gm.test(chunk);
hasUVs = /^vt/gm.test(line);
}
});
stream.on('end', function() {
reader.on('close', function() {
if (!hasPositions) {
throw new Error('Could not process OBJ file, no positions.');
}