remove texture options from texture name

This commit is contained in:
Tim Knip 2017-10-10 13:23:09 +02:00
parent 3e41cdc7f6
commit fab88cfdfa
11 changed files with 110 additions and 60 deletions

View File

@ -77,6 +77,21 @@ function loadMtl(mtlPath, options) {
materials.push(material);
}
/**
* Removes texture options from texture name
* NOTE: assumes no spaces in texture name
*
* @param {String} name
* @returns {String} The clean texture name
*/
function cleanTextureName (name) {
var re = /-(bm|t|s|o|blendu|blendv|boost|mm|texres|clamp|imfchan|type)/;
if (re.test(name)) {
return name.split(/\s+/).pop();
}
return name;
}
function parseLine(line) {
line = line.trim();
if (/^newmtl /i.test(line)) {
@ -125,32 +140,32 @@ function loadMtl(mtlPath, options) {
material.alpha = correctAlpha(1.0 - parseFloat(value));
} else if (/^map_Ka /i.test(line)) {
if (!defined(overridingAmbientTexture)) {
texturePath = path.resolve(mtlDirectory, line.substring(7).trim());
texturePath = path.resolve(mtlDirectory, cleanTextureName(line.substring(7).trim()));
loadMaterialTexture(material, 'ambientTexture', texturePath, ambientTextureOptions, mtlDirectory, texturePromiseMap, texturePromises, options);
}
} else if (/^map_Ke /i.test(line)) {
if (!defined(overridingEmissiveTexture)) {
texturePath = path.resolve(mtlDirectory, line.substring(7).trim());
texturePath = path.resolve(mtlDirectory, cleanTextureName(line.substring(7).trim()));
loadMaterialTexture(material, 'emissiveTexture', texturePath, emissiveTextureOptions, mtlDirectory, texturePromiseMap, texturePromises, options);
}
} else if (/^map_Kd /i.test(line)) {
if (!defined(overridingDiffuseTexture)) {
texturePath = path.resolve(mtlDirectory, line.substring(7).trim());
texturePath = path.resolve(mtlDirectory, cleanTextureName(line.substring(7).trim()));
loadMaterialTexture(material, 'diffuseTexture', texturePath, diffuseTextureOptions, mtlDirectory, texturePromiseMap, texturePromises, options);
}
} else if (/^map_Ks /i.test(line)) {
if (!defined(overridingSpecularTexture)) {
texturePath = path.resolve(mtlDirectory, line.substring(7).trim());
texturePath = path.resolve(mtlDirectory, cleanTextureName(line.substring(7).trim()));
loadMaterialTexture(material, 'specularTexture', texturePath, specularTextureOptions, mtlDirectory, texturePromiseMap, texturePromises, options);
}
} else if (/^map_Ns /i.test(line)) {
if (!defined(overridingSpecularShininessTexture)) {
texturePath = path.resolve(mtlDirectory, line.substring(7).trim());
texturePath = path.resolve(mtlDirectory, cleanTextureName(line.substring(7).trim()));
loadMaterialTexture(material, 'specularShininessTexture', texturePath, specularShinessTextureOptions, mtlDirectory, texturePromiseMap, texturePromises, options);
}
} else if (/^map_Bump /i.test(line)) {
if (!defined(overridingNormalTexture)) {
texturePath = path.resolve(mtlDirectory, line.substring(9).trim());
texturePath = path.resolve(mtlDirectory, cleanTextureName(line.substring(9).trim()));
loadMaterialTexture(material, 'normalTexture', texturePath, normalTextureOptions, mtlDirectory, texturePromiseMap, texturePromises, options);
}
}
@ -195,65 +210,11 @@ loadMtl._createMaterial = function(materialOptions, options) {
return convertMaterial(combine(materialOptions, new Material()), options);
};
/**
* Parses texture map options like -o, -s, -bm which end up in the texturePath
*
* @param {String} texturePath The original texture path
* @param {Object} textureOptions This object will be filled with the options
*
* @return {String} The fixed texturePath or undefined when there's no texture options
*/
function parseMapOptions (texturePath, textureOptions) {
var re = /[\\\/]-(bm|t|s|o|blendu|blendv|boost|mm|texres|clamp|imfchan|type)/;
if (!re.test(texturePath)) {
return;
}
if (re.test('/'+path.basename(texturePath))) {
// options ended up in filename, eg: map_bump -bm 0.1 foo.jpg
// assume no spaces in texture filename
var parts = path.basename(texturePath).split(/\s+/);
var texture = parts.pop();
// handle options below
texturePath = path.join(path.dirname(texturePath), parts.join(' '), texture);
}
var pathParts = texturePath.split(/[\\\/]/);
if (pathParts.length && pathParts.length > 2) {
var mapOptions = pathParts[pathParts.length - 2].split(/\s+/);
var currPart = null;
mapOptions.reduce(function (p, part) {
if (re.test('/'+part)) {
currPart = part;
p[part] = [];
} else if (currPart) {
p[currPart].push(part);
}
return p;
}, textureOptions);
pathParts.splice(pathParts.length - 2, 1);
return path.join.apply(null, pathParts);
}
}
function loadMaterialTexture(material, name, texturePath, textureOptions, mtlDirectory, texturePromiseMap, texturePromises, options) {
if (!defined(texturePath)) {
return;
}
textureOptions = textureOptions || {};
var newTexturePath = parseMapOptions(texturePath, textureOptions);
// TODO: handle texture options
// NOTE: this might not be a good place to do this
texturePath = newTexturePath ? newTexturePath : texturePath;
var texturePromise = texturePromiseMap[texturePath];
if (!defined(texturePromise)) {
if (options.secure && outsideDirectory(texturePath, mtlDirectory)) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -0,0 +1,20 @@
# Blender MTL File: 'box.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 0.200000 0.200000 0.200000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.100000 0.100000 0.100000
Ni 1.000000
d 0.900000
Tr 0.100000
map_Ka -s 1.0 1.0 1.0 -o 0.0 0.0 0.0 ambient.gif
map_Ke -s 1.0 1.0 1.0 -o 0.0 0.0 0.0 emission.jpg
map_Kd -s 1.0 1.0 1.0 -o 0.0 0.0 0.0 diffuse.png
map_Ks -s 1.0 1.0 1.0 -o 0.0 0.0 0.0 specular.jpeg
map_Ns -s 1.0 1.0 1.0 -o 0.0 0.0 0.0 shininess.png
map_Bump -bm 0.2 bump.png
map_d alpha.png
illum 2

View File

@ -0,0 +1,46 @@
# Blender v2.78 (sub 0) OBJ File: 'box.blend'
# www.blender.org
mtllib box-texture-options.mtl
o Cube
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 0.0000
vt 1.0000 1.0000
vt 0.0000 0.0000
vt 0.0000 1.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 1.0000
vn 0.0000 -1.0000 0.0000
vn 0.0000 1.0000 0.0000
usemtl Material
s off
f 1/1/1 2/2/1 4/3/1 3/4/1
f 3/5/2 4/6/2 8/7/2 7/8/2
f 7/9/3 8/10/3 6/11/3 5/12/3
f 5/13/4 6/14/4 2/15/4 1/16/4
f 3/5/5 7/17/5 5/18/5 1/16/5
f 8/19/6 4/6/6 2/15/6 6/20/6

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -11,6 +11,7 @@ var clone = Cesium.clone;
var coloredMaterialPath = 'specs/data/box/box.mtl';
var texturedMaterialPath = 'specs/data/box-complex-material/box-complex-material.mtl';
var texturedWithOptionsMaterialPath = 'specs/data/box-texture-options/box-texture-options.mtl';
var multipleMaterialsPath = 'specs/data/box-multiple-materials/box-multiple-materials.mtl';
var externalMaterialPath = 'specs/data/box-external-resources/box-external-resources.mtl';
var transparentMaterialPath = 'specs/data/box-transparent/box-transparent.mtl';
@ -131,6 +132,28 @@ describe('loadMtl', function() {
}), done).toResolve();
});
it('loads mtl with textures having options', function(done) {
options.metallicRoughness = true;
expect(loadMtl(texturedWithOptionsMaterialPath, options)
.then(function(materials) {
expect(materials.length).toBe(1);
var material = materials[0];
var pbr = material.pbrMetallicRoughness;
expect(pbr.baseColorTexture).toBeDefined();
expect(pbr.metallicRoughnessTexture).toBeDefined();
expect(pbr.baseColorFactor).toEqual([1.0, 1.0, 1.0, 0.9]);
expect(pbr.metallicFactor).toBe(1.0);
expect(pbr.roughnessFactor).toBe(1.0);
expect(material.name).toBe('Material');
expect(material.emissiveTexture).toBeDefined();
expect(material.normalTexture).toBeDefined();
expect(material.occlusionTexture).toBeDefined();
expect(material.emissiveFactor).toEqual([1.0, 1.0, 1.0]);
expect(material.alphaMode).toBe('BLEND');
expect(material.doubleSided).toBe(true);
}), done).toResolve();
});
it('loads mtl with multiple materials', function(done) {
options.metallicRoughness = true;
expect(loadMtl(multipleMaterialsPath, options)