This commit is contained in:
Sean Lilley 2018-10-29 23:15:47 -04:00
parent bab00f2558
commit c60f4ebde3
1 changed files with 73 additions and 16 deletions

View File

@ -3,8 +3,9 @@ var Cesium = require('cesium');
var path = require('path');
var Material = require('./Material');
var defined = Cesium.defined;
var clone = Cesium.clone;
var defaultValue = Cesium.defaultValue;
var defined = Cesium.defined;
var WebGLConstants = Cesium.WebGLConstants;
module.exports = createGltf;
@ -27,6 +28,9 @@ function createGltf(objData, options) {
var vertexBufferViewId = 'bufferView_vertex';
var indexBufferViewId = 'bufferView_index';
// Split materials used by primitives with different types of attributes
materials = splitIncompatibleMaterials(nodes, materials);
var gltf = {
accessors : {},
asset : {},
@ -290,23 +294,8 @@ function createGltf(objData, options) {
primitive.uvs = undefined;
primitive.indices = undefined;
if (!defined(materialId)) {
// Create a default material if the primitive does not specify one
materialId = 'default';
}
var material = materials[materialId];
material = defined(material) ? material : new Material();
var gltfMaterial = gltf.materials[materialId];
if (defined(gltfMaterial)) {
// Check if this material has already been added but with incompatible shading
var normalShading = (gltfMaterial.extensions.KHR_materials_common.technique !== 'CONSTANT');
if (hasNormals !== normalShading) {
materialId += (hasNormals ? '_shaded' : '_constant');
gltfMaterial = gltf.materials[materialId];
}
}
if (!defined(gltfMaterial)) {
gltf.materials[materialId] = createMaterial(material, hasNormals, options);
}
@ -350,3 +339,71 @@ function createGltf(objData, options) {
return gltf;
}
function primitiveInfoMatch(a, b) {
return a.hasUvs === b.hasUvs &&
a.hasNormals === b.hasNormals;
}
function cloneMaterial(material, removeTextures) {
material = clone(material, true);
if (removeTextures) {
material.ambientTexture = undefined;
material.emissionTexture = undefined;
material.diffuseTexture = undefined;
material.specularTexture = undefined;
material.specularShininessMap = undefined;
material.normalMap = undefined;
material.alphaMap = undefined;
}
return material;
}
function splitIncompatibleMaterials(nodes, materials) {
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 = splitMaterials[materialName];
if (defined(material)) {
continue;
}
material = materials[originalMaterialName];
if (defined(material)) {
material = cloneMaterial(material, !hasUvs);
} else {
material = new Material();
}
splitMaterials[materialName] = material;
}
}
}
return splitMaterials;
}