cesium
Version:
CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.
777 lines (701 loc) • 33.9 kB
JavaScript
define([
'../Core/Cartesian2',
'../Core/Cartesian3',
'../Core/Cartesian4',
'../Core/defined',
'../Core/defineProperties',
'../Core/Matrix2',
'../Core/Matrix3',
'../Core/Matrix4',
'../Core/Quaternion',
'../Core/RuntimeError',
'../Core/WebGLConstants',
'../Renderer/ShaderSource',
'./AttributeType'
], function(
Cartesian2,
Cartesian3,
Cartesian4,
defined,
defineProperties,
Matrix2,
Matrix3,
Matrix4,
Quaternion,
RuntimeError,
WebGLConstants,
ShaderSource,
AttributeType) {
'use strict';
/**
* @private
*/
var ModelUtility = {};
ModelUtility.getAccessorMinMax = function(gltf, accessorId) {
var accessor = gltf.accessors[accessorId];
var extensions = accessor.extensions;
var accessorMin = accessor.min;
var accessorMax = accessor.max;
// If this accessor is quantized, we should use the decoded min and max
if (defined(extensions)) {
var quantizedAttributes = extensions.WEB3D_quantized_attributes;
if (defined(quantizedAttributes)) {
accessorMin = quantizedAttributes.decodedMin;
accessorMax = quantizedAttributes.decodedMax;
}
}
return {
min : accessorMin,
max : accessorMax
};
};
ModelUtility.getAttributeOrUniformBySemantic = function(gltf, semantic, programId, ignoreNodes) {
var techniques = gltf.techniques;
var parameter;
for (var techniqueName in techniques) {
if (techniques.hasOwnProperty(techniqueName)) {
var technique = techniques[techniqueName];
if (defined(programId) && (technique.program !== programId)) {
continue;
}
var parameters = technique.parameters;
var attributes = technique.attributes;
var uniforms = technique.uniforms;
for (var attributeName in attributes) {
if (attributes.hasOwnProperty(attributeName)) {
parameter = parameters[attributes[attributeName]];
if (defined(parameter) && parameter.semantic === semantic && (!ignoreNodes || !defined(parameter.node))) {
return attributeName;
}
}
}
for (var uniformName in uniforms) {
if (uniforms.hasOwnProperty(uniformName)) {
parameter = parameters[uniforms[uniformName]];
if (defined(parameter) && parameter.semantic === semantic && (!ignoreNodes || !defined(parameter.node))) {
return uniformName;
}
}
}
}
}
return undefined;
};
ModelUtility.getDiffuseAttributeOrUniform = function(gltf, programId) {
var diffuseUniformName = ModelUtility.getAttributeOrUniformBySemantic(gltf, 'COLOR_0', programId);
if (!defined(diffuseUniformName)) {
diffuseUniformName = ModelUtility.getAttributeOrUniformBySemantic(gltf, '_3DTILESDIFFUSE', programId);
}
return diffuseUniformName;
};
var nodeTranslationScratch = new Cartesian3();
var nodeQuaternionScratch = new Quaternion();
var nodeScaleScratch = new Cartesian3();
ModelUtility.getTransform = function(node, result) {
if (defined(node.matrix)) {
return Matrix4.fromColumnMajorArray(node.matrix, result);
}
return Matrix4.fromTranslationQuaternionRotationScale(
Cartesian3.fromArray(node.translation, 0, nodeTranslationScratch),
Quaternion.unpack(node.rotation, 0, nodeQuaternionScratch),
Cartesian3.fromArray(node.scale, 0, nodeScaleScratch),
result);
};
ModelUtility.getUsedExtensions = function(gltf) {
var extensionsUsed = gltf.extensionsUsed;
var cachedExtensionsUsed = {};
if (defined(extensionsUsed)) {
var extensionsUsedLength = extensionsUsed.length;
for (var i = 0; i < extensionsUsedLength; i++) {
var extension = extensionsUsed[i];
cachedExtensionsUsed[extension] = true;
}
}
return cachedExtensionsUsed;
};
ModelUtility.getRequiredExtensions = function(gltf) {
var extensionsRequired = gltf.extensionsRequired;
var cachedExtensionsRequired = {};
if (defined(extensionsRequired)) {
var extensionsRequiredLength = extensionsRequired.length;
for (var i = 0; i < extensionsRequiredLength; i++) {
var extension = extensionsRequired[i];
cachedExtensionsRequired[extension] = true;
}
}
return cachedExtensionsRequired;
};
ModelUtility.checkSupportedExtensions = function(extensionsRequired) {
for (var extension in extensionsRequired) {
if (extensionsRequired.hasOwnProperty(extension)) {
if (extension !== 'CESIUM_RTC' &&
extension !== 'KHR_technique_webgl' &&
extension !== 'KHR_binary_glTF' &&
extension !== 'KHR_materials_common' &&
extension !== 'WEB3D_quantized_attributes' &&
extension !== 'KHR_draco_mesh_compression') {
throw new RuntimeError('Unsupported glTF Extension: ' + extension);
}
}
}
};
ModelUtility.checkSupportedGlExtensions = function(extensionsUsed, context) {
if (defined(extensionsUsed)) {
var glExtensionsUsedLength = extensionsUsed.length;
for (var i = 0; i < glExtensionsUsedLength; i++) {
var extension = extensionsUsed[i];
if (extension !== 'OES_element_index_uint') {
throw new RuntimeError('Unsupported WebGL Extension: ' + extension);
} else if (!context.elementIndexUint) {
throw new RuntimeError('OES_element_index_uint WebGL extension is not enabled.');
}
}
}
};
function replaceAllButFirstInString(string, find, replace) {
// Limit search to strings that are not a subset of other tokens.
find += '(?!\\w)';
find = new RegExp(find, 'g');
var index = string.search(find);
return string.replace(find, function(match, offset) {
return index === offset ? match : replace;
});
}
function getQuantizedAttributes(gltf, accessorId) {
var accessor = gltf.accessors[accessorId];
var extensions = accessor.extensions;
if (defined(extensions)) {
return extensions.WEB3D_quantized_attributes;
}
return undefined;
}
function getAttributeVariableName(gltf, primitive, attributeSemantic) {
var materialId = primitive.material;
var material = gltf.materials[materialId];
var techniqueId = material.technique;
var technique = gltf.techniques[techniqueId];
for (var parameter in technique.parameters) {
if (technique.parameters.hasOwnProperty(parameter)) {
var semantic = technique.parameters[parameter].semantic;
if (semantic === attributeSemantic) {
var attributes = technique.attributes;
for (var attributeVarName in attributes) {
if (attributes.hasOwnProperty(attributeVarName)) {
var name = attributes[attributeVarName];
if (name === parameter) {
return attributeVarName;
}
}
}
}
}
}
return undefined;
}
ModelUtility.modifyShaderForDracoQuantizedAttributes = function(gltf, primitive, shader, decodedAttributes) {
var quantizedUniforms = {};
for (var attributeSemantic in decodedAttributes) {
if (decodedAttributes.hasOwnProperty(attributeSemantic)) {
var attribute = decodedAttributes[attributeSemantic];
var quantization = attribute.quantization;
if (!defined(quantization)) {
continue;
}
var attributeVarName = getAttributeVariableName(gltf, primitive, attributeSemantic);
if (attributeSemantic.charAt(0) === '_') {
attributeSemantic = attributeSemantic.substring(1);
}
var decodeUniformVarName = 'gltf_u_dec_' + attributeSemantic.toLowerCase();
if (!defined(quantizedUniforms[decodeUniformVarName])) {
var newMain = 'gltf_decoded_' + attributeSemantic;
var decodedAttributeVarName = attributeVarName.replace('a_', 'gltf_a_dec_');
var size = attribute.componentsPerAttribute;
// replace usages of the original attribute with the decoded version, but not the declaration
shader = replaceAllButFirstInString(shader, attributeVarName, decodedAttributeVarName);
// declare decoded attribute
var variableType;
if (quantization.octEncoded) {
variableType = 'vec3';
} else if (size > 1) {
variableType = 'vec' + size;
} else {
variableType = 'float';
}
shader = variableType + ' ' + decodedAttributeVarName + ';\n' + shader;
// splice decode function into the shader
var decode = '';
if (quantization.octEncoded) {
var decodeUniformVarNameRangeConstant = decodeUniformVarName + '_rangeConstant';
shader = 'uniform float ' + decodeUniformVarNameRangeConstant + ';\n' + shader;
decode = '\n' +
'void main() {\n' +
// Draco oct-encoding decodes to zxy order
' ' + decodedAttributeVarName + ' = czm_octDecode(' + attributeVarName + '.xy, ' + decodeUniformVarNameRangeConstant + ').zxy;\n' +
' ' + newMain + '();\n' +
'}\n';
} else {
var decodeUniformVarNameNormConstant = decodeUniformVarName + '_normConstant';
var decodeUniformVarNameMin = decodeUniformVarName + '_min';
shader = 'uniform float ' + decodeUniformVarNameNormConstant + ';\n' +
'uniform ' + variableType + ' ' + decodeUniformVarNameMin + ';\n' + shader;
decode = '\n' +
'void main() {\n' +
' ' + decodedAttributeVarName + ' = ' + decodeUniformVarNameMin + ' + ' + attributeVarName + ' * ' + decodeUniformVarNameNormConstant + ';\n' +
' ' + newMain + '();\n' +
'}\n';
}
shader = ShaderSource.replaceMain(shader, newMain);
shader += decode;
}
}
}
return {
shader : shader
};
};
ModelUtility.modifyShaderForQuantizedAttributes = function(gltf, primitive, shader) {
var quantizedUniforms = {};
var attributes = primitive.attributes;
for (var attributeSemantic in attributes) {
if (attributes.hasOwnProperty(attributeSemantic)) {
var attributeVarName = getAttributeVariableName(gltf, primitive, attributeSemantic);
var accessorId = primitive.attributes[attributeSemantic];
if (attributeSemantic.charAt(0) === '_') {
attributeSemantic = attributeSemantic.substring(1);
}
var decodeUniformVarName = 'gltf_u_dec_' + attributeSemantic.toLowerCase();
var decodeUniformVarNameScale = decodeUniformVarName + '_scale';
var decodeUniformVarNameTranslate = decodeUniformVarName + '_translate';
if (!defined(quantizedUniforms[decodeUniformVarName]) && !defined(quantizedUniforms[decodeUniformVarNameScale])) {
var quantizedAttributes = getQuantizedAttributes(gltf, accessorId);
if (defined(quantizedAttributes)) {
var decodeMatrix = quantizedAttributes.decodeMatrix;
var newMain = 'gltf_decoded_' + attributeSemantic;
var decodedAttributeVarName = attributeVarName.replace('a_', 'gltf_a_dec_');
var size = Math.floor(Math.sqrt(decodeMatrix.length));
// replace usages of the original attribute with the decoded version, but not the declaration
shader = replaceAllButFirstInString(shader, attributeVarName, decodedAttributeVarName);
// declare decoded attribute
var variableType;
if (size > 2) {
variableType = 'vec' + (size - 1);
} else {
variableType = 'float';
}
shader = variableType + ' ' + decodedAttributeVarName + ';\n' + shader;
// splice decode function into the shader - attributes are pre-multiplied with the decode matrix
// uniform in the shader (32-bit floating point)
var decode = '';
if (size === 5) {
// separate scale and translate since glsl doesn't have mat5
shader = 'uniform mat4 ' + decodeUniformVarNameScale + ';\n' + shader;
shader = 'uniform vec4 ' + decodeUniformVarNameTranslate + ';\n' + shader;
decode = '\n' +
'void main() {\n' +
' ' + decodedAttributeVarName + ' = ' + decodeUniformVarNameScale + ' * ' + attributeVarName + ' + ' + decodeUniformVarNameTranslate + ';\n' +
' ' + newMain + '();\n' +
'}\n';
quantizedUniforms[decodeUniformVarNameScale] = {mat : 4};
quantizedUniforms[decodeUniformVarNameTranslate] = {vec : 4};
}
else {
shader = 'uniform mat' + size + ' ' + decodeUniformVarName + ';\n' + shader;
decode = '\n' +
'void main() {\n' +
' ' + decodedAttributeVarName + ' = ' + variableType + '(' + decodeUniformVarName + ' * vec' + size + '(' + attributeVarName + ',1.0));\n' +
' ' + newMain + '();\n' +
'}\n';
quantizedUniforms[decodeUniformVarName] = {mat : size};
}
shader = ShaderSource.replaceMain(shader, newMain);
shader += decode;
}
}
}
}
return {
shader : shader,
uniforms : quantizedUniforms
};
};
ModelUtility.toClipCoordinatesGLSL = function(gltf, shader) {
var positionName = ModelUtility.getAttributeOrUniformBySemantic(gltf, 'POSITION');
var decodedPositionName = positionName.replace('a_', 'gltf_a_dec_');
if (shader.indexOf(decodedPositionName) !== -1) {
positionName = decodedPositionName;
}
var modelViewProjectionName = ModelUtility.getAttributeOrUniformBySemantic(gltf, 'MODELVIEWPROJECTION', undefined, true);
if (!defined(modelViewProjectionName) || shader.indexOf(modelViewProjectionName) === -1) {
var projectionName = ModelUtility.getAttributeOrUniformBySemantic(gltf, 'PROJECTION', undefined, true);
var modelViewName = ModelUtility.getAttributeOrUniformBySemantic(gltf, 'MODELVIEW', undefined, true);
if (shader.indexOf('czm_instanced_modelView ') !== -1) {
modelViewName = 'czm_instanced_modelView';
} else if (!defined(modelViewName)) {
modelViewName = ModelUtility.getAttributeOrUniformBySemantic(gltf, 'CESIUM_RTC_MODELVIEW', undefined, true);
}
modelViewProjectionName = projectionName + ' * ' + modelViewName;
}
return modelViewProjectionName + ' * vec4(' + positionName + '.xyz, 1.0)';
};
ModelUtility.modifyFragmentShaderForLogDepth = function(shader) {
shader = ShaderSource.replaceMain(shader, 'czm_depth_main');
shader +=
'\n' +
'void main() \n' +
'{ \n' +
' czm_depth_main(); \n' +
' czm_writeLogDepth(); \n' +
'} \n';
return shader;
};
ModelUtility.modifyVertexShaderForLogDepth = function(shader, toClipCoordinatesGLSL) {
shader = ShaderSource.replaceMain(shader, 'czm_depth_main');
shader +=
'\n' +
'void main() \n' +
'{ \n' +
' czm_depth_main(); \n' +
' czm_vertexLogDepth(' + toClipCoordinatesGLSL + '); \n' +
'} \n';
return shader;
};
function getScalarUniformFunction(value) {
var that = {
value : value,
clone : function(source, result) {
return source;
},
func : function() {
return that.value;
}
};
return that;
}
function getVec2UniformFunction(value) {
var that = {
value : Cartesian2.fromArray(value),
clone : Cartesian2.clone,
func : function() {
return that.value;
}
};
return that;
}
function getVec3UniformFunction(value) {
var that = {
value : Cartesian3.fromArray(value),
clone : Cartesian3.clone,
func : function() {
return that.value;
}
};
return that;
}
function getVec4UniformFunction(value) {
var that = {
value : Cartesian4.fromArray(value),
clone : Cartesian4.clone,
func : function() {
return that.value;
}
};
return that;
}
function getMat2UniformFunction(value) {
var that = {
value : Matrix2.fromColumnMajorArray(value),
clone : Matrix2.clone,
func : function() {
return that.value;
}
};
return that;
}
function getMat3UniformFunction(value) {
var that = {
value : Matrix3.fromColumnMajorArray(value),
clone : Matrix3.clone,
func : function() {
return that.value;
}
};
return that;
}
function getMat4UniformFunction(value) {
var that = {
value : Matrix4.fromColumnMajorArray(value),
clone : Matrix4.clone,
func : function() {
return that.value;
}
};
return that;
}
///////////////////////////////////////////////////////////////////////////
function DelayLoadedTextureUniform(value, textures, defaultTexture) {
this._value = undefined;
this._textureId = value.index;
this._textures = textures;
this._defaultTexture = defaultTexture;
}
defineProperties(DelayLoadedTextureUniform.prototype, {
value : {
get : function() {
// Use the default texture (1x1 white) until the model's texture is loaded
if (!defined(this._value)) {
var texture = this._textures[this._textureId];
if (defined(texture)) {
this._value = texture;
} else {
return this._defaultTexture;
}
}
return this._value;
},
set : function(value) {
this._value = value;
}
}
});
DelayLoadedTextureUniform.prototype.clone = function(source) {
return source;
};
DelayLoadedTextureUniform.prototype.func = undefined;
///////////////////////////////////////////////////////////////////////////
function getTextureUniformFunction(value, texture, defaultTexture) {
var uniform = new DelayLoadedTextureUniform(value, texture, defaultTexture);
// Define function here to access closure since 'this' can't be
// used when the Renderer sets uniforms.
uniform.func = function() {
return uniform.value;
};
return uniform;
}
var gltfUniformFunctions = {};
gltfUniformFunctions[WebGLConstants.FLOAT] = getScalarUniformFunction;
gltfUniformFunctions[WebGLConstants.FLOAT_VEC2] = getVec2UniformFunction;
gltfUniformFunctions[WebGLConstants.FLOAT_VEC3] = getVec3UniformFunction;
gltfUniformFunctions[WebGLConstants.FLOAT_VEC4] = getVec4UniformFunction;
gltfUniformFunctions[WebGLConstants.INT] = getScalarUniformFunction;
gltfUniformFunctions[WebGLConstants.INT_VEC2] = getVec2UniformFunction;
gltfUniformFunctions[WebGLConstants.INT_VEC3] = getVec3UniformFunction;
gltfUniformFunctions[WebGLConstants.INT_VEC4] = getVec4UniformFunction;
gltfUniformFunctions[WebGLConstants.BOOL] = getScalarUniformFunction;
gltfUniformFunctions[WebGLConstants.BOOL_VEC2] = getVec2UniformFunction;
gltfUniformFunctions[WebGLConstants.BOOL_VEC3] = getVec3UniformFunction;
gltfUniformFunctions[WebGLConstants.BOOL_VEC4] = getVec4UniformFunction;
gltfUniformFunctions[WebGLConstants.FLOAT_MAT2] = getMat2UniformFunction;
gltfUniformFunctions[WebGLConstants.FLOAT_MAT3] = getMat3UniformFunction;
gltfUniformFunctions[WebGLConstants.FLOAT_MAT4] = getMat4UniformFunction;
gltfUniformFunctions[WebGLConstants.SAMPLER_2D] = getTextureUniformFunction;
// GLTF_SPEC: Support SAMPLER_CUBE. https://github.com/KhronosGroup/glTF/issues/40
ModelUtility.createUniformFunction = function(type, value, textures, defaultTexture) {
return gltfUniformFunctions[type](value, textures, defaultTexture);
};
function scaleFromMatrix5Array(matrix) {
return [matrix[0], matrix[1], matrix[2], matrix[3],
matrix[5], matrix[6], matrix[7], matrix[8],
matrix[10], matrix[11], matrix[12], matrix[13],
matrix[15], matrix[16], matrix[17], matrix[18]];
}
function translateFromMatrix5Array(matrix) {
return [matrix[20], matrix[21], matrix[22], matrix[23]];
}
ModelUtility.createUniformsForDracoQuantizedAttributes = function(decodedAttributes) {
var uniformMap = {};
for (var attribute in decodedAttributes) {
if (decodedAttributes.hasOwnProperty(attribute)) {
var decodedData = decodedAttributes[attribute];
var quantization = decodedData.quantization;
if (!defined(quantization)) {
continue;
}
if (attribute.charAt(0) === '_'){
attribute = attribute.substring(1);
}
var uniformVarName = 'gltf_u_dec_' + attribute.toLowerCase();
if (quantization.octEncoded) {
var uniformVarNameRangeConstant = uniformVarName + '_rangeConstant';
var rangeConstant = (1 << quantization.quantizationBits) - 1.0;
uniformMap[uniformVarNameRangeConstant] = getScalarUniformFunction(rangeConstant).func;
continue;
}
var uniformVarNameNormConstant = uniformVarName + '_normConstant';
var normConstant = quantization.range / (1 << quantization.quantizationBits);
uniformMap[uniformVarNameNormConstant] = getScalarUniformFunction(normConstant).func;
var uniformVarNameMin = uniformVarName + '_min';
switch (decodedData.componentsPerAttribute) {
case 1:
uniformMap[uniformVarNameMin] = getScalarUniformFunction(quantization.minValues).func;
break;
case 2:
uniformMap[uniformVarNameMin] = getVec2UniformFunction(quantization.minValues).func;
break;
case 3:
uniformMap[uniformVarNameMin] = getVec3UniformFunction(quantization.minValues).func;
break;
case 4:
uniformMap[uniformVarNameMin] = getVec4UniformFunction(quantization.minValues).func;
break;
}
}
}
return uniformMap;
};
ModelUtility.createUniformsForQuantizedAttributes = function(gltf, primitive, quantizedUniforms) {
var accessors = gltf.accessors;
var setUniforms = {};
var uniformMap = {};
var attributes = primitive.attributes;
for (var attribute in attributes) {
if (attributes.hasOwnProperty(attribute)) {
var accessorId = attributes[attribute];
var a = accessors[accessorId];
var extensions = a.extensions;
if (attribute.charAt(0) === '_') {
attribute = attribute.substring(1);
}
if (defined(extensions)) {
var quantizedAttributes = extensions.WEB3D_quantized_attributes;
if (defined(quantizedAttributes)) {
var decodeMatrix = quantizedAttributes.decodeMatrix;
var uniformVariable = 'gltf_u_dec_' + attribute.toLowerCase();
switch (a.type) {
case AttributeType.SCALAR:
uniformMap[uniformVariable] = getMat2UniformFunction(decodeMatrix).func;
setUniforms[uniformVariable] = true;
break;
case AttributeType.VEC2:
uniformMap[uniformVariable] = getMat3UniformFunction(decodeMatrix).func;
setUniforms[uniformVariable] = true;
break;
case AttributeType.VEC3:
uniformMap[uniformVariable] = getMat4UniformFunction(decodeMatrix).func;
setUniforms[uniformVariable] = true;
break;
case AttributeType.VEC4:
// VEC4 attributes are split into scale and translate because there is no mat5 in GLSL
var uniformVariableScale = uniformVariable + '_scale';
var uniformVariableTranslate = uniformVariable + '_translate';
uniformMap[uniformVariableScale] = getMat4UniformFunction(scaleFromMatrix5Array(decodeMatrix)).func;
uniformMap[uniformVariableTranslate] = getVec4UniformFunction(translateFromMatrix5Array(decodeMatrix)).func;
setUniforms[uniformVariableScale] = true;
setUniforms[uniformVariableTranslate] = true;
break;
}
}
}
}
}
// If there are any unset quantized uniforms in this program, they should be set to the identity
for (var quantizedUniform in quantizedUniforms) {
if (quantizedUniforms.hasOwnProperty(quantizedUniform)) {
if (!setUniforms[quantizedUniform]) {
var properties = quantizedUniforms[quantizedUniform];
if (defined(properties.mat)) {
if (properties.mat === 2) {
uniformMap[quantizedUniform] = getMat2UniformFunction(Matrix2.IDENTITY).func;
} else if (properties.mat === 3) {
uniformMap[quantizedUniform] = getMat3UniformFunction(Matrix3.IDENTITY).func;
} else if (properties.mat === 4) {
uniformMap[quantizedUniform] = getMat4UniformFunction(Matrix4.IDENTITY).func;
}
}
if (defined(properties.vec)) {
if (properties.vec === 4) {
uniformMap[quantizedUniform] = getVec4UniformFunction([0, 0, 0, 0]).func;
}
}
}
}
}
return uniformMap;
};
// This doesn't support LOCAL, which we could add if it is ever used.
var scratchTranslationRtc = new Cartesian3();
var gltfSemanticUniforms = {
MODEL : function(uniformState, model) {
return function() {
return uniformState.model;
};
},
VIEW : function(uniformState, model) {
return function() {
return uniformState.view;
};
},
PROJECTION : function(uniformState, model) {
return function() {
return uniformState.projection;
};
},
MODELVIEW : function(uniformState, model) {
return function() {
return uniformState.modelView;
};
},
CESIUM_RTC_MODELVIEW : function(uniformState, model) {
// CESIUM_RTC extension
var mvRtc = new Matrix4();
return function() {
if (defined(model._rtcCenter)) {
Matrix4.getTranslation(uniformState.model, scratchTranslationRtc);
Cartesian3.add(scratchTranslationRtc, model._rtcCenter, scratchTranslationRtc);
Matrix4.multiplyByPoint(uniformState.view, scratchTranslationRtc, scratchTranslationRtc);
return Matrix4.setTranslation(uniformState.modelView, scratchTranslationRtc, mvRtc);
}
return uniformState.modelView;
};
},
MODELVIEWPROJECTION : function(uniformState, model) {
return function() {
return uniformState.modelViewProjection;
};
},
MODELINVERSE : function(uniformState, model) {
return function() {
return uniformState.inverseModel;
};
},
VIEWINVERSE : function(uniformState, model) {
return function() {
return uniformState.inverseView;
};
},
PROJECTIONINVERSE : function(uniformState, model) {
return function() {
return uniformState.inverseProjection;
};
},
MODELVIEWINVERSE : function(uniformState, model) {
return function() {
return uniformState.inverseModelView;
};
},
MODELVIEWPROJECTIONINVERSE : function(uniformState, model) {
return function() {
return uniformState.inverseModelViewProjection;
};
},
MODELINVERSETRANSPOSE : function(uniformState, model) {
return function() {
return uniformState.inverseTransposeModel;
};
},
MODELVIEWINVERSETRANSPOSE : function(uniformState, model) {
return function() {
return uniformState.normal;
};
},
VIEWPORT : function(uniformState, model) {
return function() {
return uniformState.viewportCartesian4;
};
}
// JOINTMATRIX created in createCommand()
};
ModelUtility.getGltfSemanticUniforms = function() {
return gltfSemanticUniforms;
};
return ModelUtility;
});