import Check from "../Core/Check.js"; import defined from "../Core/defined.js"; import DeveloperError from "../Core/DeveloperError.js"; /** * An enum describing the built-in vertex attribute semantics. * * @enum {String} * * @private */ const VertexAttributeSemantic = { /** * Per-vertex position. * * @type {String} * @constant */ POSITION: "POSITION", /** * Per-vertex normal. * * @type {String} * @constant */ NORMAL: "NORMAL", /** * Per-vertex tangent. * * @type {String} * @constant */ TANGENT: "TANGENT", /** * Per-vertex texture coordinates. * * @type {String} * @constant */ TEXCOORD: "TEXCOORD", /** * Per-vertex color. * * @type {String} * @constant */ COLOR: "COLOR", /** * Per-vertex joint IDs for skinning. * * @type {String} * @constant */ JOINTS: "JOINTS", /** * Per-vertex joint weights for skinning. * * @type {String} * @constant */ WEIGHTS: "WEIGHTS", /** * Per-vertex feature ID. * * @type {String} * @constant */ FEATURE_ID: "_FEATURE_ID", }; function semanticToVariableName(semantic) { switch (semantic) { case VertexAttributeSemantic.POSITION: return "positionMC"; case VertexAttributeSemantic.NORMAL: return "normalMC"; case VertexAttributeSemantic.TANGENT: return "tangentMC"; case VertexAttributeSemantic.TEXCOORD: return "texCoord"; case VertexAttributeSemantic.COLOR: return "color"; case VertexAttributeSemantic.JOINTS: return "joints"; case VertexAttributeSemantic.WEIGHTS: return "weights"; case VertexAttributeSemantic.FEATURE_ID: return "featureId"; //>>includeStart('debug', pragmas.debug); default: throw new DeveloperError("semantic is not a valid value."); //>>includeEnd('debug'); } } /** * Returns whether the vertex attribute semantic can have a set index. * * @param {VertexAttributeSemantic} semantic The semantic. * * @returns {Boolean} Whether the semantic can have a set index. * * @private */ VertexAttributeSemantic.hasSetIndex = function (semantic) { //>>includeStart('debug', pragmas.debug); Check.typeOf.string("semantic", semantic); //>>includeEnd('debug'); switch (semantic) { case VertexAttributeSemantic.POSITION: case VertexAttributeSemantic.NORMAL: case VertexAttributeSemantic.TANGENT: return false; case VertexAttributeSemantic.TEXCOORD: case VertexAttributeSemantic.COLOR: case VertexAttributeSemantic.JOINTS: case VertexAttributeSemantic.WEIGHTS: case VertexAttributeSemantic.FEATURE_ID: return true; //>>includeStart('debug', pragmas.debug); default: throw new DeveloperError("semantic is not a valid value."); //>>includeEnd('debug'); } }; /** * Gets the vertex attribute semantic matching the glTF semantic. * * @param {String} gltfSemantic The glTF semantic. * * @returns {VertexAttributeSemantic|undefined} The vertex attribute semantic, or undefined if there is no match. * * @private */ VertexAttributeSemantic.fromGltfSemantic = function (gltfSemantic) { //>>includeStart('debug', pragmas.debug); Check.typeOf.string("gltfSemantic", gltfSemantic); //>>includeEnd('debug'); let semantic = gltfSemantic; // Strip the set index from the semantic const setIndexRegex = /^(\w+)_\d+$/; const setIndexMatch = setIndexRegex.exec(gltfSemantic); if (setIndexMatch !== null) { semantic = setIndexMatch[1]; } switch (semantic) { case "POSITION": return VertexAttributeSemantic.POSITION; case "NORMAL": return VertexAttributeSemantic.NORMAL; case "TANGENT": return VertexAttributeSemantic.TANGENT; case "TEXCOORD": return VertexAttributeSemantic.TEXCOORD; case "COLOR": return VertexAttributeSemantic.COLOR; case "JOINTS": return VertexAttributeSemantic.JOINTS; case "WEIGHTS": return VertexAttributeSemantic.WEIGHTS; case "_FEATURE_ID": return VertexAttributeSemantic.FEATURE_ID; } return undefined; }; /** * Gets the vertex attribute semantic matching the pnts semantic. * * @param {String} pntsSemantic The pnts semantic. * * @returns {VertexAttributeSemantic|undefined} The vertex attribute semantic, or undefined if there is no match. * * @private */ VertexAttributeSemantic.fromPntsSemantic = function (pntsSemantic) { //>>includeStart('debug', pragmas.debug); Check.typeOf.string("pntsSemantic", pntsSemantic); //>>includeEnd('debug'); switch (pntsSemantic) { case "POSITION": case "POSITION_QUANTIZED": return VertexAttributeSemantic.POSITION; case "RGBA": case "RGB": case "RGB565": return VertexAttributeSemantic.COLOR; case "NORMAL": case "NORMAL_OCT16P": return VertexAttributeSemantic.NORMAL; case "BATCH_ID": return VertexAttributeSemantic.FEATURE_ID; //>>includeStart('debug', pragmas.debug); default: throw new DeveloperError("pntsSemantic is not a valid value."); //>>includeEnd('debug'); } }; /** * Gets the GLSL type (such as vec3 or int) for the * given vertex attribute. * * @param {VertexAttributeSemantic} semantic The semantic. * * @returns {String} The shader type. * * @private */ VertexAttributeSemantic.getGlslType = function (semantic) { //>>includeStart('debug', pragmas.debug); Check.typeOf.string("semantic", semantic); //>>includeEnd('debug'); switch (semantic) { case VertexAttributeSemantic.POSITION: case VertexAttributeSemantic.NORMAL: case VertexAttributeSemantic.TANGENT: return "vec3"; case VertexAttributeSemantic.TEXCOORD: return "vec2"; case VertexAttributeSemantic.COLOR: return "vec4"; case VertexAttributeSemantic.JOINTS: return "ivec4"; case VertexAttributeSemantic.WEIGHTS: return "vec4"; case VertexAttributeSemantic.FEATURE_ID: return "int"; //>>includeStart('debug', pragmas.debug); default: throw new DeveloperError("semantic is not a valid value."); //>>includeEnd('debug'); } }; /** * Gets the variable name for the given semantic and set index. * * @param {VertexAttributeSemantic} semantic The semantic. * @param {Number} [setIndex] The set index. * * @returns {String} The variable name. * * @private */ VertexAttributeSemantic.getVariableName = function (semantic, setIndex) { //>>includeStart('debug', pragmas.debug); Check.typeOf.string("semantic", semantic); //>>includeEnd('debug'); let variableName = semanticToVariableName(semantic); if (defined(setIndex)) { variableName += `_${setIndex}`; } return variableName; }; export default Object.freeze(VertexAttributeSemantic);