mirror of
https://github.com/CesiumGS/obj2gltf.git
synced 2025-03-03 06:51:43 -05:00
Read lines from stream and handle negative indices
This commit is contained in:
parent
fec860ede0
commit
31760c34a8
@ -327,7 +327,7 @@ function createGltf(data, inputPath, modelName, done) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bufferSeparate) {
|
if (bufferSeparate) {
|
||||||
var bufferPath = path.join(path.dirname(inputPath), modelName + '.bin');
|
var bufferPath = path.join(inputPath, modelName + '.bin');
|
||||||
fs.writeFile(bufferPath, buffer, function(err) {
|
fs.writeFile(bufferPath, buffer, function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
|
152
lib/obj.js
152
lib/obj.js
@ -2,6 +2,7 @@
|
|||||||
var async = require('async');
|
var async = require('async');
|
||||||
var fs = require('fs-extra');
|
var fs = require('fs-extra');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
|
var readline = require('readline');
|
||||||
var loadImage = require('./image');
|
var loadImage = require('./image');
|
||||||
var Material = require('./mtl');
|
var Material = require('./mtl');
|
||||||
var Cesium = require('cesium');
|
var Cesium = require('cesium');
|
||||||
@ -33,7 +34,7 @@ function processObj(objFile, info, materials, images, done) {
|
|||||||
var uvs = [];
|
var uvs = [];
|
||||||
|
|
||||||
var positionMin = [Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE];
|
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 hasNormals = info.hasNormals;
|
||||||
var hasUVs = info.hasUVs;
|
var hasUVs = info.hasUVs;
|
||||||
@ -67,12 +68,22 @@ function processObj(objFile, info, materials, images, done) {
|
|||||||
useDefaultMaterial();
|
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) {
|
function createVertex(p, u, n) {
|
||||||
// Positions
|
// Positions
|
||||||
var pi = (parseInt(p) - 1) * 3;
|
var pi = getOffset(p, positions, 3);
|
||||||
var px = positions[pi + 0];
|
var px = positions[pi + 0];
|
||||||
var py = positions[pi + 1];
|
var py = positions[pi + 1];
|
||||||
var pz = positions[pi + 2];
|
var pz = positions[pi + 2];
|
||||||
|
|
||||||
positionMin[0] = Math.min(px, positionMin[0]);
|
positionMin[0] = Math.min(px, positionMin[0]);
|
||||||
positionMin[1] = Math.min(py, positionMin[1]);
|
positionMin[1] = Math.min(py, positionMin[1]);
|
||||||
positionMin[2] = Math.min(pz, positionMin[2]);
|
positionMin[2] = Math.min(pz, positionMin[2]);
|
||||||
@ -83,7 +94,7 @@ function processObj(objFile, info, materials, images, done) {
|
|||||||
|
|
||||||
// Normals
|
// Normals
|
||||||
if (hasNormals) {
|
if (hasNormals) {
|
||||||
var ni = (parseInt(n) - 1) * 3;
|
var ni = getOffset(n, normals, 3);
|
||||||
var nx = normals[ni + 0];
|
var nx = normals[ni + 0];
|
||||||
var ny = normals[ni + 1];
|
var ny = normals[ni + 1];
|
||||||
var nz = normals[ni + 2];
|
var nz = normals[ni + 2];
|
||||||
@ -93,7 +104,7 @@ function processObj(objFile, info, materials, images, done) {
|
|||||||
// UVs
|
// UVs
|
||||||
if (hasUVs) {
|
if (hasUVs) {
|
||||||
if (defined(u)) {
|
if (defined(u)) {
|
||||||
var ui = (parseInt(u) - 1) * 2;
|
var ui = getOffset(u, uvs, 2);
|
||||||
var ux = uvs[ui + 0];
|
var ux = uvs[ui + 0];
|
||||||
var uy = uvs[ui + 1];
|
var uy = uvs[ui + 1];
|
||||||
vertexArray.push(ux, uy);
|
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 facePattern4 = /f( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))?/;
|
||||||
|
|
||||||
var stream = fs.createReadStream(objFile, 'utf8');
|
var stream = fs.createReadStream(objFile, 'utf8');
|
||||||
|
var reader = readline.createInterface({
|
||||||
|
input : stream
|
||||||
|
});
|
||||||
|
|
||||||
stream.on('data', function(chunk) {
|
reader.on('line', function(line) {
|
||||||
var lines = chunk.split('\n');
|
line = line.trim();
|
||||||
length = lines.length;
|
var result;
|
||||||
for (i = 0; i < length; ++i) {
|
if ((line.length === 0) || (line.charAt(0) === '#')) {
|
||||||
var line = lines[i].trim();
|
// Nothing to process
|
||||||
var result;
|
} else if ((result = vertexPattern.exec(line)) !== null) {
|
||||||
if ((line.length === 0) || (line.charAt(0) === '#')) {
|
positions.push(
|
||||||
continue;
|
parseFloat(result[1]),
|
||||||
} else if ((result = vertexPattern.exec(line)) !== null) {
|
parseFloat(result[2]),
|
||||||
positions.push(
|
parseFloat(result[3])
|
||||||
parseFloat(result[1]),
|
);
|
||||||
parseFloat(result[2]),
|
} else if ((result = normalPattern.exec(line) ) !== null) {
|
||||||
parseFloat(result[3])
|
var nx = parseFloat(result[1]);
|
||||||
);
|
var ny = parseFloat(result[2]);
|
||||||
} else if ((result = normalPattern.exec(line) ) !== null) {
|
var nz = parseFloat(result[3]);
|
||||||
var nx = parseFloat(result[1]);
|
var normal = Cartesian3.normalize(new Cartesian3(nx, ny, nz), new Cartesian3());
|
||||||
var ny = parseFloat(result[2]);
|
normals.push(normal.x, normal.y, normal.z);
|
||||||
var nz = parseFloat(result[3]);
|
} else if ((result = uvPattern.exec(line)) !== null) {
|
||||||
var normal = Cartesian3.normalize(new Cartesian3(nx, ny, nz), new Cartesian3());
|
uvs.push(
|
||||||
normals.push(normal.x, normal.y, normal.z);
|
parseFloat(result[1]),
|
||||||
} else if ((result = uvPattern.exec(line)) !== null) {
|
parseFloat(result[2])
|
||||||
uvs.push(
|
);
|
||||||
parseFloat(result[1]),
|
} else if ((result = facePattern1.exec(line)) !== null) {
|
||||||
parseFloat(result[2])
|
addFace(
|
||||||
);
|
result[1], result[1], undefined, undefined,
|
||||||
} else if ((result = facePattern1.exec(line)) !== null) {
|
result[2], result[2], undefined, undefined,
|
||||||
addFace(
|
result[3], result[3], undefined, undefined,
|
||||||
result[1], result[1], undefined, undefined,
|
result[4], result[4], undefined, undefined
|
||||||
result[2], result[2], undefined, undefined,
|
);
|
||||||
result[3], result[3], undefined, undefined,
|
} else if ((result = facePattern2.exec(line)) !== null) {
|
||||||
result[4], result[4], undefined, undefined
|
addFace(
|
||||||
);
|
result[1], result[2], result[3], undefined,
|
||||||
} else if ((result = facePattern2.exec(line)) !== null) {
|
result[4], result[5], result[6], undefined,
|
||||||
addFace(
|
result[7], result[8], result[9], undefined,
|
||||||
result[1], result[2], result[3], undefined,
|
result[10], result[11], result[12], undefined
|
||||||
result[4], result[5], result[6], undefined,
|
);
|
||||||
result[7], result[8], result[9], undefined,
|
} else if ((result = facePattern3.exec(line)) !== null) {
|
||||||
result[10], result[11], result[12], undefined
|
addFace(
|
||||||
);
|
result[1], result[2], result[3], result[4],
|
||||||
} else if ((result = facePattern3.exec(line)) !== null) {
|
result[5], result[6], result[7], result[8],
|
||||||
addFace(
|
result[9], result[10], result[11], result[12],
|
||||||
result[1], result[2], result[3], result[4],
|
result[13], result[14], result[15], result[16]
|
||||||
result[5], result[6], result[7], result[8],
|
);
|
||||||
result[9], result[10], result[11], result[12],
|
} else if ((result = facePattern4.exec(line)) !== null) {
|
||||||
result[13], result[14], result[15], result[16]
|
addFace(
|
||||||
);
|
result[1], result[2], undefined, result[3],
|
||||||
} else if ((result = facePattern4.exec(line)) !== null) {
|
result[4], result[5], undefined, result[6],
|
||||||
addFace(
|
result[7], result[8], undefined, result[9],
|
||||||
result[1], result[2], undefined, result[3],
|
result[10], result[11], undefined, result[12]
|
||||||
result[4], result[5], undefined, result[6],
|
);
|
||||||
result[7], result[8], undefined, result[9],
|
} else if (/^usemtl /.test(line)) {
|
||||||
result[10], result[11], undefined, result[12]
|
var materialName = line.substring(7).trim();
|
||||||
);
|
useMaterial(materialName);
|
||||||
} else if (/^usemtl /.test(line)) {
|
|
||||||
var materialName = line.substring(7).trim();
|
|
||||||
useMaterial(materialName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
stream.on('end', function() {
|
reader.on('close', function() {
|
||||||
done({
|
done({
|
||||||
vertexCount : vertexCount,
|
vertexCount : vertexCount,
|
||||||
vertexArray : vertexArray,
|
vertexArray : vertexArray,
|
||||||
@ -299,9 +309,13 @@ function getObjInfo(objFile, inputPath, done) {
|
|||||||
var hasUVs = false;
|
var hasUVs = false;
|
||||||
|
|
||||||
var stream = fs.createReadStream(objFile, 'utf8');
|
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)) {
|
if (!defined(mtlPath)) {
|
||||||
var mtllibMatches = chunk.match(/^mtllib.*/gm);
|
var mtllibMatches = line.match(/^mtllib.*/gm);
|
||||||
if (mtllibMatches !== null) {
|
if (mtllibMatches !== null) {
|
||||||
var mtlFile = mtllibMatches[0].substring(7).trim();
|
var mtlFile = mtllibMatches[0].substring(7).trim();
|
||||||
mtlPath = mtlFile;
|
mtlPath = mtlFile;
|
||||||
@ -311,20 +325,20 @@ function getObjInfo(objFile, inputPath, done) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!hasMaterialGroups) {
|
if (!hasMaterialGroups) {
|
||||||
hasMaterialGroups = /^usemtl/gm.test(chunk);
|
hasMaterialGroups = /^usemtl/gm.test(line);
|
||||||
}
|
}
|
||||||
if (!hasPositions) {
|
if (!hasPositions) {
|
||||||
hasPositions = /^v\s/gm.test(chunk);
|
hasPositions = /^v\s/gm.test(line);
|
||||||
}
|
}
|
||||||
if (!hasNormals) {
|
if (!hasNormals) {
|
||||||
hasNormals = /^vn/gm.test(chunk);
|
hasNormals = /^vn/gm.test(line);
|
||||||
}
|
}
|
||||||
if (!hasUVs) {
|
if (!hasUVs) {
|
||||||
hasUVs = /^vt/gm.test(chunk);
|
hasUVs = /^vt/gm.test(line);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
stream.on('end', function() {
|
reader.on('close', function() {
|
||||||
if (!hasPositions) {
|
if (!hasPositions) {
|
||||||
throw new Error('Could not process OBJ file, no positions.');
|
throw new Error('Could not process OBJ file, no positions.');
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user