Newer
Older
casic-smartcity-well-front / static / Cesium / ThirdParty / GltfPipeline / addDefaults.js
[wangxitong] on 8 Jul 2021 7 KB mars3d总览
import addToArray from './addToArray.js'
import ForEach from './ForEach.js'
import getAccessorByteStride from './getAccessorByteStride.js'
import defaultValue from '../../Core/defaultValue.js'
import defined from '../../Core/defined.js'
import WebGLConstants from '../../Core/WebGLConstants.js'

    /**
     * Adds default glTF values if they don't exist.
     *
     * @param {Object} gltf A javascript object containing a glTF asset.
     * @returns {Object} The modified glTF.
     *
     * @private
     */
    function addDefaults(gltf) {
        ForEach.accessor(gltf, function(accessor) {
            if (defined(accessor.bufferView)) {
                accessor.byteOffset = defaultValue(accessor.byteOffset, 0);
            }
        });

        ForEach.bufferView(gltf, function(bufferView) {
            if (defined(bufferView.buffer)) {
                bufferView.byteOffset = defaultValue(bufferView.byteOffset, 0);
            }
        });

        ForEach.mesh(gltf, function(mesh) {
            ForEach.meshPrimitive(mesh, function(primitive) {
                primitive.mode = defaultValue(primitive.mode, WebGLConstants.TRIANGLES);
                if (!defined(primitive.material)) {
                    if (!defined(gltf.materials)) {
                        gltf.materials = [];
                    }
                    var defaultMaterial = {
                        name: 'default'
                    };
                    primitive.material = addToArray(gltf.materials, defaultMaterial);
                }
            });
        });

        ForEach.accessorContainingVertexAttributeData(gltf, function(accessorId) {
            var accessor = gltf.accessors[accessorId];
            var bufferViewId = accessor.bufferView;
            accessor.normalized = defaultValue(accessor.normalized, false);
            if (defined(bufferViewId)) {
                var bufferView = gltf.bufferViews[bufferViewId];
                bufferView.byteStride = getAccessorByteStride(gltf, accessor);
                bufferView.target = WebGLConstants.ARRAY_BUFFER;
            }
        });

        ForEach.accessorContainingIndexData(gltf, function(accessorId) {
            var accessor = gltf.accessors[accessorId];
            var bufferViewId = accessor.bufferView;
            if (defined(bufferViewId)) {
                var bufferView = gltf.bufferViews[bufferViewId];
                bufferView.target = WebGLConstants.ELEMENT_ARRAY_BUFFER;
            }
        });

        ForEach.material(gltf, function(material) {
            var extensions = defaultValue(material.extensions, defaultValue.EMPTY_OBJECT);
            var materialsCommon = extensions.KHR_materials_common;
            if (defined(materialsCommon)) {
                var technique = materialsCommon.technique;
                var values = defined(materialsCommon.values) ? materialsCommon.values : {};
                materialsCommon.values = values;

                values.ambient = defined(values.ambient) ? values.ambient : [0.0, 0.0, 0.0, 1.0];
                values.emission = defined(values.emission) ? values.emission : [0.0, 0.0, 0.0, 1.0];

                values.transparency = defaultValue(values.transparency, 1.0);
                values.transparent = defaultValue(values.transparent, false);
                values.doubleSided = defaultValue(values.doubleSided, false);

                if (technique !== 'CONSTANT') {
                    values.diffuse = defined(values.diffuse) ? values.diffuse : [0.0, 0.0, 0.0, 1.0];
                    if (technique !== 'LAMBERT') {
                        values.specular = defined(values.specular) ? values.specular : [0.0, 0.0, 0.0, 1.0];
                        values.shininess = defaultValue(values.shininess, 0.0);
                    }
                }
                return;
            }

            material.emissiveFactor = defaultValue(material.emissiveFactor, [0.0, 0.0, 0.0]);
            material.alphaMode = defaultValue(material.alphaMode, 'OPAQUE');
            material.doubleSided = defaultValue(material.doubleSided, false);

            if (material.alphaMode === 'MASK') {
                material.alphaCutoff = defaultValue(material.alphaCutoff, 0.5);
            }

            var techniquesExtension = extensions.KHR_techniques_webgl;
            if (defined(techniquesExtension)) {
                ForEach.materialValue(material, function (materialValue) {
                    // Check if material value is a TextureInfo object
                    if (defined(materialValue.index)) {
                        addTextureDefaults(materialValue);
                    }
                });
            }

            addTextureDefaults(material.emissiveTexture);
            addTextureDefaults(material.normalTexture);
            addTextureDefaults(material.occlusionTexture);

            var pbrMetallicRoughness = material.pbrMetallicRoughness;
            if (defined(pbrMetallicRoughness)) {
                pbrMetallicRoughness.baseColorFactor = defaultValue(pbrMetallicRoughness.baseColorFactor, [1.0, 1.0, 1.0, 1.0]);
                pbrMetallicRoughness.metallicFactor = defaultValue(pbrMetallicRoughness.metallicFactor, 1.0);
                pbrMetallicRoughness.roughnessFactor = defaultValue(pbrMetallicRoughness.roughnessFactor, 1.0);
                addTextureDefaults(pbrMetallicRoughness.baseColorTexture);
                addTextureDefaults(pbrMetallicRoughness.metallicRoughnessTexture);
            }

            var pbrSpecularGlossiness = extensions.pbrSpecularGlossiness;
            if (defined(pbrSpecularGlossiness)) {
                pbrSpecularGlossiness.diffuseFactor = defaultValue(pbrSpecularGlossiness.diffuseFactor, [1.0, 1.0, 1.0, 1.0]);
                pbrSpecularGlossiness.specularFactor = defaultValue(pbrSpecularGlossiness.specularFactor, [1.0, 1.0, 1.0]);
                pbrSpecularGlossiness.glossinessFactor = defaultValue(pbrSpecularGlossiness.glossinessFactor, 1.0);
                addTextureDefaults(pbrSpecularGlossiness.specularGlossinessTexture);
            }
        });

        ForEach.animation(gltf, function(animation) {
            ForEach.animationSampler(animation, function(sampler) {
                sampler.interpolation = defaultValue(sampler.interpolation, 'LINEAR');
            });
        });

        var animatedNodes = getAnimatedNodes(gltf);
        ForEach.node(gltf, function(node, id) {
            var animated = defined(animatedNodes[id]);
            if (animated || defined(node.translation) || defined(node.rotation) || defined(node.scale)) {
                node.translation = defaultValue(node.translation, [0.0, 0.0, 0.0]);
                node.rotation = defaultValue(node.rotation, [0.0, 0.0, 0.0, 1.0]);
                node.scale = defaultValue(node.scale, [1.0, 1.0, 1.0]);
            } else {
                node.matrix = defaultValue(node.matrix, [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]);
            }
        });

        ForEach.sampler(gltf, function(sampler) {
            sampler.wrapS = defaultValue(sampler.wrapS, WebGLConstants.REPEAT);
            sampler.wrapT = defaultValue(sampler.wrapT, WebGLConstants.REPEAT);
        });

        if (defined(gltf.scenes) && !defined(gltf.scene)) {
            gltf.scene = 0;
        }

        return gltf;
    }

    function getAnimatedNodes(gltf) {
        var nodes = {};
        ForEach.animation(gltf, function(animation) {
            ForEach.animationChannel(animation, function(channel) {
                var target = channel.target;
                var nodeId = target.node;
                var path = target.path;
                // Ignore animations that target 'weights'
                if (path === 'translation' || path === 'rotation' || path === 'scale') {
                    nodes[nodeId] = true;
                }
            });
        });
        return nodes;
    }

    function addTextureDefaults(texture) {
        if (defined(texture)) {
            texture.texCoord = defaultValue(texture.texCoord, 0);
        }
    }

    export default addDefaults;