@openhps/core
Version:
Open Hybrid Positioning System - Core component
320 lines (306 loc) • 16.8 kB
JavaScript
import { Color } from '../math/Color.js';
import { Vector2 } from '../math/Vector2.js';
import { Vector3 } from '../math/Vector3.js';
import { Vector4 } from '../math/Vector4.js';
import { Matrix3 } from '../math/Matrix3.js';
import { Matrix4 } from '../math/Matrix4.js';
import { FileLoader } from './FileLoader.js';
import { Loader } from './Loader.js';
import { ShadowMaterial, SpriteMaterial, RawShaderMaterial, ShaderMaterial, PointsMaterial, MeshPhysicalMaterial, MeshStandardMaterial, MeshPhongMaterial, MeshToonMaterial, MeshNormalMaterial, MeshLambertMaterial, MeshDepthMaterial, MeshDistanceMaterial, MeshBasicMaterial, MeshMatcapMaterial, LineDashedMaterial, LineBasicMaterial, Material } from '../materials/Materials.js';
/**
* Class for loading geometries. The files are internally
* loaded via {@link FileLoader}.
*
* ```js
* const loader = new THREE.MaterialLoader();
* const material = await loader.loadAsync( 'material.json' );
* ```
* This loader does not support node materials. Use {@link NodeMaterialLoader} instead.
*
* @augments Loader
*/
class MaterialLoader extends Loader {
/**
* Constructs a new material loader.
*
* @param {LoadingManager} [manager] - The loading manager.
*/
constructor(manager) {
super(manager);
/**
* A dictionary holding textures used by the material.
*
* @type {Object<string,Texture>}
*/
this.textures = {};
}
/**
* Starts loading from the given URL and pass the loaded material to the `onLoad()` callback.
*
* @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.
* @param {function(Material)} onLoad - Executed when the loading process has been finished.
* @param {onProgressCallback} onProgress - Executed while the loading is in progress.
* @param {onErrorCallback} onError - Executed when errors occur.
*/
load(url, onLoad, onProgress, onError) {
const scope = this;
const loader = new FileLoader(scope.manager);
loader.setPath(scope.path);
loader.setRequestHeader(scope.requestHeader);
loader.setWithCredentials(scope.withCredentials);
loader.load(url, function (text) {
try {
onLoad(scope.parse(JSON.parse(text)));
} catch (e) {
if (onError) {
onError(e);
} else {
console.error(e);
}
scope.manager.itemError(url);
}
}, onProgress, onError);
}
/**
* Parses the given JSON object and returns a material.
*
* @param {Object} json - The serialized material.
* @return {Material} The parsed material.
*/
parse(json) {
const textures = this.textures;
function getTexture(name) {
if (textures[name] === undefined) {
console.warn('THREE.MaterialLoader: Undefined texture', name);
}
return textures[name];
}
const material = this.createMaterialFromType(json.type);
if (json.uuid !== undefined) material.uuid = json.uuid;
if (json.name !== undefined) material.name = json.name;
if (json.color !== undefined && material.color !== undefined) material.color.setHex(json.color);
if (json.roughness !== undefined) material.roughness = json.roughness;
if (json.metalness !== undefined) material.metalness = json.metalness;
if (json.sheen !== undefined) material.sheen = json.sheen;
if (json.sheenColor !== undefined) material.sheenColor = new Color().setHex(json.sheenColor);
if (json.sheenRoughness !== undefined) material.sheenRoughness = json.sheenRoughness;
if (json.emissive !== undefined && material.emissive !== undefined) material.emissive.setHex(json.emissive);
if (json.specular !== undefined && material.specular !== undefined) material.specular.setHex(json.specular);
if (json.specularIntensity !== undefined) material.specularIntensity = json.specularIntensity;
if (json.specularColor !== undefined && material.specularColor !== undefined) material.specularColor.setHex(json.specularColor);
if (json.shininess !== undefined) material.shininess = json.shininess;
if (json.clearcoat !== undefined) material.clearcoat = json.clearcoat;
if (json.clearcoatRoughness !== undefined) material.clearcoatRoughness = json.clearcoatRoughness;
if (json.dispersion !== undefined) material.dispersion = json.dispersion;
if (json.iridescence !== undefined) material.iridescence = json.iridescence;
if (json.iridescenceIOR !== undefined) material.iridescenceIOR = json.iridescenceIOR;
if (json.iridescenceThicknessRange !== undefined) material.iridescenceThicknessRange = json.iridescenceThicknessRange;
if (json.transmission !== undefined) material.transmission = json.transmission;
if (json.thickness !== undefined) material.thickness = json.thickness;
if (json.attenuationDistance !== undefined) material.attenuationDistance = json.attenuationDistance;
if (json.attenuationColor !== undefined && material.attenuationColor !== undefined) material.attenuationColor.setHex(json.attenuationColor);
if (json.anisotropy !== undefined) material.anisotropy = json.anisotropy;
if (json.anisotropyRotation !== undefined) material.anisotropyRotation = json.anisotropyRotation;
if (json.fog !== undefined) material.fog = json.fog;
if (json.flatShading !== undefined) material.flatShading = json.flatShading;
if (json.blending !== undefined) material.blending = json.blending;
if (json.combine !== undefined) material.combine = json.combine;
if (json.side !== undefined) material.side = json.side;
if (json.shadowSide !== undefined) material.shadowSide = json.shadowSide;
if (json.opacity !== undefined) material.opacity = json.opacity;
if (json.transparent !== undefined) material.transparent = json.transparent;
if (json.alphaTest !== undefined) material.alphaTest = json.alphaTest;
if (json.alphaHash !== undefined) material.alphaHash = json.alphaHash;
if (json.depthFunc !== undefined) material.depthFunc = json.depthFunc;
if (json.depthTest !== undefined) material.depthTest = json.depthTest;
if (json.depthWrite !== undefined) material.depthWrite = json.depthWrite;
if (json.colorWrite !== undefined) material.colorWrite = json.colorWrite;
if (json.blendSrc !== undefined) material.blendSrc = json.blendSrc;
if (json.blendDst !== undefined) material.blendDst = json.blendDst;
if (json.blendEquation !== undefined) material.blendEquation = json.blendEquation;
if (json.blendSrcAlpha !== undefined) material.blendSrcAlpha = json.blendSrcAlpha;
if (json.blendDstAlpha !== undefined) material.blendDstAlpha = json.blendDstAlpha;
if (json.blendEquationAlpha !== undefined) material.blendEquationAlpha = json.blendEquationAlpha;
if (json.blendColor !== undefined && material.blendColor !== undefined) material.blendColor.setHex(json.blendColor);
if (json.blendAlpha !== undefined) material.blendAlpha = json.blendAlpha;
if (json.stencilWriteMask !== undefined) material.stencilWriteMask = json.stencilWriteMask;
if (json.stencilFunc !== undefined) material.stencilFunc = json.stencilFunc;
if (json.stencilRef !== undefined) material.stencilRef = json.stencilRef;
if (json.stencilFuncMask !== undefined) material.stencilFuncMask = json.stencilFuncMask;
if (json.stencilFail !== undefined) material.stencilFail = json.stencilFail;
if (json.stencilZFail !== undefined) material.stencilZFail = json.stencilZFail;
if (json.stencilZPass !== undefined) material.stencilZPass = json.stencilZPass;
if (json.stencilWrite !== undefined) material.stencilWrite = json.stencilWrite;
if (json.wireframe !== undefined) material.wireframe = json.wireframe;
if (json.wireframeLinewidth !== undefined) material.wireframeLinewidth = json.wireframeLinewidth;
if (json.wireframeLinecap !== undefined) material.wireframeLinecap = json.wireframeLinecap;
if (json.wireframeLinejoin !== undefined) material.wireframeLinejoin = json.wireframeLinejoin;
if (json.rotation !== undefined) material.rotation = json.rotation;
if (json.linewidth !== undefined) material.linewidth = json.linewidth;
if (json.dashSize !== undefined) material.dashSize = json.dashSize;
if (json.gapSize !== undefined) material.gapSize = json.gapSize;
if (json.scale !== undefined) material.scale = json.scale;
if (json.polygonOffset !== undefined) material.polygonOffset = json.polygonOffset;
if (json.polygonOffsetFactor !== undefined) material.polygonOffsetFactor = json.polygonOffsetFactor;
if (json.polygonOffsetUnits !== undefined) material.polygonOffsetUnits = json.polygonOffsetUnits;
if (json.dithering !== undefined) material.dithering = json.dithering;
if (json.alphaToCoverage !== undefined) material.alphaToCoverage = json.alphaToCoverage;
if (json.premultipliedAlpha !== undefined) material.premultipliedAlpha = json.premultipliedAlpha;
if (json.forceSinglePass !== undefined) material.forceSinglePass = json.forceSinglePass;
if (json.visible !== undefined) material.visible = json.visible;
if (json.toneMapped !== undefined) material.toneMapped = json.toneMapped;
if (json.userData !== undefined) material.userData = json.userData;
if (json.vertexColors !== undefined) {
if (typeof json.vertexColors === 'number') {
material.vertexColors = json.vertexColors > 0 ? true : false;
} else {
material.vertexColors = json.vertexColors;
}
}
// Shader Material
if (json.uniforms !== undefined) {
for (const name in json.uniforms) {
const uniform = json.uniforms[name];
material.uniforms[name] = {};
switch (uniform.type) {
case 't':
material.uniforms[name].value = getTexture(uniform.value);
break;
case 'c':
material.uniforms[name].value = new Color().setHex(uniform.value);
break;
case 'v2':
material.uniforms[name].value = new Vector2().fromArray(uniform.value);
break;
case 'v3':
material.uniforms[name].value = new Vector3().fromArray(uniform.value);
break;
case 'v4':
material.uniforms[name].value = new Vector4().fromArray(uniform.value);
break;
case 'm3':
material.uniforms[name].value = new Matrix3().fromArray(uniform.value);
break;
case 'm4':
material.uniforms[name].value = new Matrix4().fromArray(uniform.value);
break;
default:
material.uniforms[name].value = uniform.value;
}
}
}
if (json.defines !== undefined) material.defines = json.defines;
if (json.vertexShader !== undefined) material.vertexShader = json.vertexShader;
if (json.fragmentShader !== undefined) material.fragmentShader = json.fragmentShader;
if (json.glslVersion !== undefined) material.glslVersion = json.glslVersion;
if (json.extensions !== undefined) {
for (const key in json.extensions) {
material.extensions[key] = json.extensions[key];
}
}
if (json.lights !== undefined) material.lights = json.lights;
if (json.clipping !== undefined) material.clipping = json.clipping;
// for PointsMaterial
if (json.size !== undefined) material.size = json.size;
if (json.sizeAttenuation !== undefined) material.sizeAttenuation = json.sizeAttenuation;
// maps
if (json.map !== undefined) material.map = getTexture(json.map);
if (json.matcap !== undefined) material.matcap = getTexture(json.matcap);
if (json.alphaMap !== undefined) material.alphaMap = getTexture(json.alphaMap);
if (json.bumpMap !== undefined) material.bumpMap = getTexture(json.bumpMap);
if (json.bumpScale !== undefined) material.bumpScale = json.bumpScale;
if (json.normalMap !== undefined) material.normalMap = getTexture(json.normalMap);
if (json.normalMapType !== undefined) material.normalMapType = json.normalMapType;
if (json.normalScale !== undefined) {
let normalScale = json.normalScale;
if (Array.isArray(normalScale) === false) {
// Blender exporter used to export a scalar. See #7459
normalScale = [normalScale, normalScale];
}
material.normalScale = new Vector2().fromArray(normalScale);
}
if (json.displacementMap !== undefined) material.displacementMap = getTexture(json.displacementMap);
if (json.displacementScale !== undefined) material.displacementScale = json.displacementScale;
if (json.displacementBias !== undefined) material.displacementBias = json.displacementBias;
if (json.roughnessMap !== undefined) material.roughnessMap = getTexture(json.roughnessMap);
if (json.metalnessMap !== undefined) material.metalnessMap = getTexture(json.metalnessMap);
if (json.emissiveMap !== undefined) material.emissiveMap = getTexture(json.emissiveMap);
if (json.emissiveIntensity !== undefined) material.emissiveIntensity = json.emissiveIntensity;
if (json.specularMap !== undefined) material.specularMap = getTexture(json.specularMap);
if (json.specularIntensityMap !== undefined) material.specularIntensityMap = getTexture(json.specularIntensityMap);
if (json.specularColorMap !== undefined) material.specularColorMap = getTexture(json.specularColorMap);
if (json.envMap !== undefined) material.envMap = getTexture(json.envMap);
if (json.envMapRotation !== undefined) material.envMapRotation.fromArray(json.envMapRotation);
if (json.envMapIntensity !== undefined) material.envMapIntensity = json.envMapIntensity;
if (json.reflectivity !== undefined) material.reflectivity = json.reflectivity;
if (json.refractionRatio !== undefined) material.refractionRatio = json.refractionRatio;
if (json.lightMap !== undefined) material.lightMap = getTexture(json.lightMap);
if (json.lightMapIntensity !== undefined) material.lightMapIntensity = json.lightMapIntensity;
if (json.aoMap !== undefined) material.aoMap = getTexture(json.aoMap);
if (json.aoMapIntensity !== undefined) material.aoMapIntensity = json.aoMapIntensity;
if (json.gradientMap !== undefined) material.gradientMap = getTexture(json.gradientMap);
if (json.clearcoatMap !== undefined) material.clearcoatMap = getTexture(json.clearcoatMap);
if (json.clearcoatRoughnessMap !== undefined) material.clearcoatRoughnessMap = getTexture(json.clearcoatRoughnessMap);
if (json.clearcoatNormalMap !== undefined) material.clearcoatNormalMap = getTexture(json.clearcoatNormalMap);
if (json.clearcoatNormalScale !== undefined) material.clearcoatNormalScale = new Vector2().fromArray(json.clearcoatNormalScale);
if (json.iridescenceMap !== undefined) material.iridescenceMap = getTexture(json.iridescenceMap);
if (json.iridescenceThicknessMap !== undefined) material.iridescenceThicknessMap = getTexture(json.iridescenceThicknessMap);
if (json.transmissionMap !== undefined) material.transmissionMap = getTexture(json.transmissionMap);
if (json.thicknessMap !== undefined) material.thicknessMap = getTexture(json.thicknessMap);
if (json.anisotropyMap !== undefined) material.anisotropyMap = getTexture(json.anisotropyMap);
if (json.sheenColorMap !== undefined) material.sheenColorMap = getTexture(json.sheenColorMap);
if (json.sheenRoughnessMap !== undefined) material.sheenRoughnessMap = getTexture(json.sheenRoughnessMap);
return material;
}
/**
* Textures are not embedded in the material JSON so they have
* to be injected before the loading process starts.
*
* @param {Object} value - A dictionary holding textures for material properties.
* @return {MaterialLoader} A reference to this material loader.
*/
setTextures(value) {
this.textures = value;
return this;
}
/**
* Creates a material for the given type.
*
* @param {string} type - The material type.
* @return {Material} The new material.
*/
createMaterialFromType(type) {
return MaterialLoader.createMaterialFromType(type);
}
/**
* Creates a material for the given type.
*
* @static
* @param {string} type - The material type.
* @return {Material} The new material.
*/
static createMaterialFromType(type) {
const materialLib = {
ShadowMaterial,
SpriteMaterial,
RawShaderMaterial,
ShaderMaterial,
PointsMaterial,
MeshPhysicalMaterial,
MeshStandardMaterial,
MeshPhongMaterial,
MeshToonMaterial,
MeshNormalMaterial,
MeshLambertMaterial,
MeshDepthMaterial,
MeshDistanceMaterial,
MeshBasicMaterial,
MeshMatcapMaterial,
LineDashedMaterial,
LineBasicMaterial,
Material
};
return new materialLib[type]();
}
}
export { MaterialLoader };