UNPKG

playcanvas

Version:

Open-source WebGL/WebGPU 3D engine for the web

128 lines (127 loc) 4.61 kB
import { Color } from "../../../core/math/color.js"; import { Vec2 } from "../../../core/math/vec2.js"; import { Vec3 } from "../../../core/math/vec3.js"; import { Texture } from "../../../platform/graphics/texture.js"; import { BoundingBox } from "../../../core/shape/bounding-box.js"; import { StandardMaterial } from "../../../scene/materials/standard-material.js"; import { StandardMaterialValidator } from "../../../scene/materials/standard-material-validator.js"; import { standardMaterialParameterTypes } from "../../../scene/materials/standard-material-parameters.js"; class JsonStandardMaterialParser { constructor() { this._validator = null; } parse(input) { const migrated = this.migrate(input); const validated = this._validate(migrated); const material = new StandardMaterial(); this.initialize(material, validated); return material; } /** * Initialize material properties from the material data block e.g. Loading from server. * * @param {StandardMaterial} material - The material to be initialized. * @param {object} data - The data block that is used to initialize. */ initialize(material, data) { if (!data.validated) { data = this._validate(data); } if (data.chunks) { if (data.chunks && Object.keys(data.chunks).length > 0) { const dstMap = material.shaderChunks.glsl; Object.entries(data.chunks).forEach(([key, value]) => dstMap.set(key, value)); } } for (const key in data) { const type = standardMaterialParameterTypes[key]; const value = data[key]; if (type === "vec2") { material[key] = new Vec2(value[0], value[1]); } else if (type === "rgb") { material[key] = new Color(value[0], value[1], value[2]); } else if (type === "texture") { if (value instanceof Texture) { material[key] = value; } else if (!(material[key] instanceof Texture && typeof value === "number" && value > 0)) { material[key] = null; } } else if (type === "cubemap") { if (value instanceof Texture) { material[key] = value; } else if (!(material[key] instanceof Texture && typeof value === "number" && value > 0)) { material[key] = null; } if (key === "cubeMap" && !value) { material.prefilteredCubemaps = null; } } else if (type === "boundingbox") { const center = new Vec3(value.center[0], value.center[1], value.center[2]); const halfExtents = new Vec3(value.halfExtents[0], value.halfExtents[1], value.halfExtents[2]); material[key] = new BoundingBox(center, halfExtents); } else { material[key] = data[key]; } } material.update(); } // convert any properties that are out of date // or from old versions into current version migrate(data) { if (data.shader) delete data.shader; if (data.mapping_format) { data.mappingFormat = data.mapping_format; delete data.mapping_format; } let i; const RENAMED_PROPERTIES = [ ["bumpMapFactor", "bumpiness"], ["aoUvSet", "aoMapUv"], ["aoMapVertexColor", "aoVertexColor"], ["diffuseMapVertexColor", "diffuseVertexColor"], ["emissiveMapVertexColor", "emissiveVertexColor"], ["specularMapVertexColor", "specularVertexColor"], ["metalnessMapVertexColor", "metalnessVertexColor"], ["opacityMapVertexColor", "opacityVertexColor"], ["glossMapVertexColor", "glossVertexColor"], ["lightMapVertexColor", "lightVertexColor"], ["specularMapTint", "specularTint"], ["metalnessMapTint", "metalnessTint"], ["clearCoatGlossiness", "clearCoatGloss"] ]; for (i = 0; i < RENAMED_PROPERTIES.length; i++) { const _old = RENAMED_PROPERTIES[i][0]; const _new = RENAMED_PROPERTIES[i][1]; if (data[_old] !== void 0) { if (data[_new] === void 0) { data[_new] = data[_old]; } delete data[_old]; } } const DEPRECATED_PROPERTIES = [ "fresnelFactor", "shadowSampleType" ]; for (i = 0; i < DEPRECATED_PROPERTIES.length; i++) { const name = DEPRECATED_PROPERTIES[i]; if (data.hasOwnProperty(name)) { delete data[name]; } } return data; } // check for invalid properties _validate(data) { if (!data.validated) { if (!this._validator) { this._validator = new StandardMaterialValidator(); } this._validator.validate(data); } return data; } } export { JsonStandardMaterialParser };