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,15 +166,15 @@ 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();
reader.on('line', function(line) {
line = line.trim();
var result;
if ((line.length === 0) || (line.charAt(0) === '#')) {
continue;
// Nothing to process
} else if ((result = vertexPattern.exec(line)) !== null) {
positions.push(
parseFloat(result[1]),
@ -213,10 +224,9 @@ function processObj(objFile, info, materials, images, done) {
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.');
}