Load mtllib that has spaces in its path

This commit is contained in:
Sean Lilley 2017-11-17 11:53:04 -05:00
parent 42c4b33521
commit 78a41c35a7
6 changed files with 126 additions and 2 deletions

View File

@ -437,8 +437,8 @@ function loadObj(objPath, options) {
var materialName = line.substring(7).trim();
useMaterial(materialName);
} else if (/^mtllib/i.test(line)) {
var paths = line.substring(7).trim().split(' ');
mtlPaths = mtlPaths.concat(paths);
var mtllibLine = line.substring(7).trim();
mtlPaths = mtlPaths.concat(getMtlPaths(mtllibLine));
} else if ((result = vertexPattern.exec(line)) !== null) {
positions.push(parseFloat(result[1]));
positions.push(parseFloat(result[2]));
@ -495,6 +495,23 @@ function loadObj(objPath, options) {
});
}
function getMtlPaths(mtllibLine) {
// Handle paths with spaces. E.g. mtllib my material file.mtl
var mtlPaths = [];
var splits = mtllibLine.split(' ');
var length = splits.length;
var startIndex = 0;
for (var i = 0; i < length; ++i) {
if (path.extname(splits[i]) === '') {
continue;
}
var mtlPath = splits.slice(startIndex, i + 1).join(' ');
mtlPaths.push(mtlPath);
startIndex = i + 1;
}
return mtlPaths;
}
function finishLoading(nodes, mtlPaths, objPath, options) {
nodes = cleanNodes(nodes);
if (nodes.length === 0) {

View File

@ -0,0 +1,12 @@
# Blender MTL File: 'box-multiple-materials.blend'
# Material Count: 1
newmtl Blue
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 0.000000 0.000000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

View File

@ -0,0 +1,12 @@
# Blender MTL File: 'box-multiple-materials.blend'
# Material Count: 1
newmtl Green
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 0.000000 0.640000 0.000000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

View File

@ -0,0 +1,12 @@
# Blender MTL File: 'box-multiple-materials.blend'
# Material Count: 1
newmtl Red
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 0.640000 0.000000 0.000000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

View File

@ -0,0 +1,50 @@
# Blender v2.78 (sub 0) OBJ File: 'box-multiple-materials.blend'
# www.blender.org
mtllib box mtllib red.mtl
mtllib box mtllib green.mtl box mtllib blue.mtl
v -1.000000 -1.000000 1.000000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -1.000000
vt 0.0000 0.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 0.0000 0.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 0.0000 0.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 0.0000 0.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 0.0000 0.0000
vt 1.0000 0.0000
vn 0.0000 -1.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
usemtl Red
f 3/1/1 7/2/1 5/3/1 1/4/1
usemtl Green
f 1/9/3 2/10/3 4/11/3 3/12/3
usemtl Blue
f 3/1/5 4/6/5 8/17/5 7/18/5
usemtl Red
f 8/5/2 4/6/2 2/7/2 6/8/2
usemtl Green
f 7/13/4 8/14/4 6/15/4 5/16/4
usemtl Blue
f 5/19/6 6/20/6 2/7/6 1/4/6

View File

@ -21,6 +21,7 @@ var objNoMaterialsPath = 'specs/data/box-no-materials/box-no-materials.obj';
var objMultipleMaterialsPath = 'specs/data/box-multiple-materials/box-multiple-materials.obj';
var objUncleanedPath = 'specs/data/box-uncleaned/box-uncleaned.obj';
var objMtllibPath = 'specs/data/box-mtllib/box-mtllib.obj';
var objMtllibSpacesPath = 'specs/data/box-mtllib-spaces/box mtllib.obj';
var objMissingMtllibPath = 'specs/data/box-missing-mtllib/box-missing-mtllib.obj';
var objExternalResourcesPath = 'specs/data/box-external-resources/box-external-resources.obj';
var objTexturedPath = 'specs/data/box-textured/box-textured.obj';
@ -289,6 +290,26 @@ describe('loadObj', function() {
}), done).toResolve();
});
it('loads obj with mtllib paths with spaces', function(done) {
expect(loadObj(objMtllibSpacesPath, options)
.then(function(data) {
var materials = data.materials;
expect(materials.length).toBe(3);
// .mtl files are loaded in an arbitrary order, so sort for testing purposes
materials.sort(function(a, b){
return a.name.localeCompare(b.name);
});
expect(materials[0].name).toBe('Blue');
expect(materials[0].pbrMetallicRoughness.baseColorFactor).toEqual([0.0, 0.0, 0.64, 1.0]);
expect(materials[1].name).toBe('Green');
expect(materials[1].pbrMetallicRoughness.baseColorFactor).toEqual([0.0, 0.64, 0.0, 1.0]);
expect(materials[2].name).toBe('Red');
expect(materials[2].pbrMetallicRoughness.baseColorFactor).toEqual([0.64, 0.0, 0.0, 1.0]);
}), done).toResolve();
});
it('loads obj with missing mtllib', function(done) {
var spy = jasmine.createSpy('logger');
options.logger = spy;