mirror of https://github.com/CesiumGS/obj2gltf.git
Split incompatible materials
This commit is contained in:
parent
b781459234
commit
9cc1ba8ec5
|
@ -4,6 +4,7 @@ var getBufferPadded = require('./getBufferPadded');
|
||||||
var getDefaultMaterial = require('./loadMtl').getDefaultMaterial;
|
var getDefaultMaterial = require('./loadMtl').getDefaultMaterial;
|
||||||
var Texture = require('./Texture');
|
var Texture = require('./Texture');
|
||||||
|
|
||||||
|
var defaultValue = Cesium.defaultValue;
|
||||||
var defined = Cesium.defined;
|
var defined = Cesium.defined;
|
||||||
var WebGLConstants = Cesium.WebGLConstants;
|
var WebGLConstants = Cesium.WebGLConstants;
|
||||||
|
|
||||||
|
@ -23,6 +24,9 @@ function createGltf(objData, options) {
|
||||||
var materials = objData.materials;
|
var materials = objData.materials;
|
||||||
var name = objData.name;
|
var name = objData.name;
|
||||||
|
|
||||||
|
// Split materials used by primitives with different types of attributes
|
||||||
|
materials = splitIncompatibleMaterials(nodes, materials, options);
|
||||||
|
|
||||||
var gltf = {
|
var gltf = {
|
||||||
accessors : [],
|
accessors : [],
|
||||||
asset : {},
|
asset : {},
|
||||||
|
@ -70,14 +74,14 @@ function createGltf(objData, options) {
|
||||||
var meshIndex;
|
var meshIndex;
|
||||||
|
|
||||||
if (meshesLength === 1) {
|
if (meshesLength === 1) {
|
||||||
meshIndex = addMesh(gltf, materials, bufferState, uint32Indices, meshes[0], options);
|
meshIndex = addMesh(gltf, materials, bufferState, uint32Indices, meshes[0]);
|
||||||
addNode(gltf, node.name, meshIndex, undefined);
|
addNode(gltf, node.name, meshIndex, undefined);
|
||||||
} else {
|
} else {
|
||||||
// Add meshes as child nodes
|
// Add meshes as child nodes
|
||||||
var parentIndex = addNode(gltf, node.name);
|
var parentIndex = addNode(gltf, node.name);
|
||||||
for (var j = 0; j < meshesLength; ++j) {
|
for (var j = 0; j < meshesLength; ++j) {
|
||||||
var mesh = meshes[j];
|
var mesh = meshes[j];
|
||||||
meshIndex = addMesh(gltf, materials, bufferState, uint32Indices, mesh, options);
|
meshIndex = addMesh(gltf, materials, bufferState, uint32Indices, mesh);
|
||||||
addNode(gltf, mesh.name, meshIndex, parentIndex);
|
addNode(gltf, mesh.name, meshIndex, parentIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,6 +198,31 @@ function getTexture(gltf, texture) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cloneMaterial(material, removeTextures) {
|
||||||
|
if (material === null || typeof material !== 'object') {
|
||||||
|
return material;
|
||||||
|
} else if (material instanceof Texture) {
|
||||||
|
if (removeTextures) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return material;
|
||||||
|
} else if (Array.isArray(material)) {
|
||||||
|
var length = material.length;
|
||||||
|
var clonedArray = new Array(length);
|
||||||
|
for (var i = 0; i < length; ++i) {
|
||||||
|
clonedArray[i] = cloneMaterial(material[i], removeTextures);
|
||||||
|
}
|
||||||
|
return clonedArray;
|
||||||
|
}
|
||||||
|
var clonedObject = {};
|
||||||
|
for (var name in material) {
|
||||||
|
if (material.hasOwnProperty(name)) {
|
||||||
|
clonedObject[name] = cloneMaterial(material[name], removeTextures);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return clonedObject;
|
||||||
|
}
|
||||||
|
|
||||||
function resolveTextures(gltf, material) {
|
function resolveTextures(gltf, material) {
|
||||||
for (var name in material) {
|
for (var name in material) {
|
||||||
if (material.hasOwnProperty(name)) {
|
if (material.hasOwnProperty(name)) {
|
||||||
|
@ -214,35 +243,27 @@ function addMaterial(gltf, material) {
|
||||||
return materialIndex;
|
return materialIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMaterial(gltf, materials, materialName, options) {
|
function getMaterialByName(materials, materialName) {
|
||||||
if (!defined(materialName)) {
|
|
||||||
// Create a default material if the primitive does not specify one
|
|
||||||
materialName = 'default';
|
|
||||||
}
|
|
||||||
|
|
||||||
var i;
|
|
||||||
var material;
|
|
||||||
var materialsLength = materials.length;
|
var materialsLength = materials.length;
|
||||||
for (i = 0; i < materialsLength; ++i) {
|
for (var i = 0; i < materialsLength; ++i) {
|
||||||
if (materials[i].name === materialName) {
|
if (materials[i].name === materialName) {
|
||||||
material = materials[i];
|
return materials[i];
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!defined(material)) {
|
function getMaterialIndex(materials, materialName) {
|
||||||
material = getDefaultMaterial(options);
|
var materialsLength = materials.length;
|
||||||
material.name = materialName;
|
for (var i = 0; i < materialsLength; ++i) {
|
||||||
}
|
if (materials[i].name === materialName) {
|
||||||
|
return i;
|
||||||
var materialIndex;
|
|
||||||
materialsLength = gltf.materials.length;
|
|
||||||
for (i = 0; i < materialsLength; ++i) {
|
|
||||||
if (gltf.materials[i].name === materialName) {
|
|
||||||
materialIndex = i;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMaterial(gltf, materials, materialName) {
|
||||||
|
var material = getMaterialByName(materials, materialName);
|
||||||
|
var materialIndex = getMaterialIndex(gltf.materials, materialName);
|
||||||
|
|
||||||
if (!defined(materialIndex)) {
|
if (!defined(materialIndex)) {
|
||||||
materialIndex = addMaterial(gltf, material);
|
materialIndex = addMaterial(gltf, material);
|
||||||
|
@ -251,6 +272,61 @@ function getMaterial(gltf, materials, materialName, options) {
|
||||||
return materialIndex;
|
return materialIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function primitiveInfoMatch(a, b) {
|
||||||
|
return a.hasUvs === b.hasUvs &&
|
||||||
|
a.hasNormals === b.hasNormals;
|
||||||
|
}
|
||||||
|
|
||||||
|
function splitIncompatibleMaterials(nodes, materials, options) {
|
||||||
|
var splitMaterials = [];
|
||||||
|
var primitiveInfoByMaterial = {};
|
||||||
|
var nodesLength = nodes.length;
|
||||||
|
for (var i = 0; i < nodesLength; ++i) {
|
||||||
|
var meshes = nodes[i].meshes;
|
||||||
|
var meshesLength = meshes.length;
|
||||||
|
for (var j = 0; j < meshesLength; ++j) {
|
||||||
|
var primitives = meshes[j].primitives;
|
||||||
|
var primitivesLength = primitives.length;
|
||||||
|
for (var k = 0; k < primitivesLength; ++k) {
|
||||||
|
var primitive = primitives[k];
|
||||||
|
var hasUvs = primitive.uvs.length > 0;
|
||||||
|
var hasNormals = primitive.normals.length > 0;
|
||||||
|
var primitiveInfo = {
|
||||||
|
hasUvs : hasUvs,
|
||||||
|
hasNormals : hasNormals
|
||||||
|
};
|
||||||
|
var originalMaterialName = defaultValue(primitive.material, 'default');
|
||||||
|
var materialName = originalMaterialName;
|
||||||
|
var suffix = 2;
|
||||||
|
while (defined(primitiveInfoByMaterial[materialName])) {
|
||||||
|
if (primitiveInfoMatch(primitiveInfo, primitiveInfoByMaterial[materialName])) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
materialName = originalMaterialName + '-' + suffix++;
|
||||||
|
}
|
||||||
|
|
||||||
|
primitive.material = materialName;
|
||||||
|
primitiveInfoByMaterial[materialName] = primitiveInfo;
|
||||||
|
|
||||||
|
var material = getMaterialByName(splitMaterials, materialName);
|
||||||
|
if (defined(material)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
material = getMaterialByName(materials, originalMaterialName);
|
||||||
|
if (defined(material)) {
|
||||||
|
material = cloneMaterial(material, !hasUvs);
|
||||||
|
} else {
|
||||||
|
material = getDefaultMaterial(options);
|
||||||
|
}
|
||||||
|
material.name = materialName;
|
||||||
|
splitMaterials.push(material);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return splitMaterials;
|
||||||
|
}
|
||||||
|
|
||||||
function addVertexAttribute(gltf, array, components, name) {
|
function addVertexAttribute(gltf, array, components, name) {
|
||||||
var count = array.length / components;
|
var count = array.length / components;
|
||||||
var minMax = array.getMinMax(components);
|
var minMax = array.getMinMax(components);
|
||||||
|
@ -309,7 +385,7 @@ function requiresUint32Indices(nodes) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addPrimitive(gltf, materials, bufferState, uint32Indices, mesh, primitive, index, options) {
|
function addPrimitive(gltf, materials, bufferState, uint32Indices, mesh, primitive, index) {
|
||||||
var hasPositions = primitive.positions.length > 0;
|
var hasPositions = primitive.positions.length > 0;
|
||||||
var hasNormals = primitive.normals.length > 0;
|
var hasNormals = primitive.normals.length > 0;
|
||||||
var hasUVs = primitive.uvs.length > 0;
|
var hasUVs = primitive.uvs.length > 0;
|
||||||
|
@ -346,7 +422,7 @@ function addPrimitive(gltf, materials, bufferState, uint32Indices, mesh, primiti
|
||||||
primitive.uvs = undefined;
|
primitive.uvs = undefined;
|
||||||
primitive.indices = undefined;
|
primitive.indices = undefined;
|
||||||
|
|
||||||
var materialIndex = getMaterial(gltf, materials, primitive.material, options);
|
var materialIndex = getMaterial(gltf, materials, primitive.material);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
attributes : attributes,
|
attributes : attributes,
|
||||||
|
@ -356,12 +432,12 @@ function addPrimitive(gltf, materials, bufferState, uint32Indices, mesh, primiti
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function addMesh(gltf, materials, bufferState, uint32Indices, mesh, options) {
|
function addMesh(gltf, materials, bufferState, uint32Indices, mesh) {
|
||||||
var gltfPrimitives = [];
|
var gltfPrimitives = [];
|
||||||
var primitives = mesh.primitives;
|
var primitives = mesh.primitives;
|
||||||
var primitivesLength = primitives.length;
|
var primitivesLength = primitives.length;
|
||||||
for (var i = 0; i < primitivesLength; ++i) {
|
for (var i = 0; i < primitivesLength; ++i) {
|
||||||
gltfPrimitives.push(addPrimitive(gltf, materials, bufferState, uint32Indices, mesh, primitives[i], i, options));
|
gltfPrimitives.push(addPrimitive(gltf, materials, bufferState, uint32Indices, mesh, primitives[i], i));
|
||||||
}
|
}
|
||||||
|
|
||||||
var gltfMesh = {
|
var gltfMesh = {
|
||||||
|
|
Loading…
Reference in New Issue