/** * @author Kai Salmen / https://kaisalmen.de * Development repository: https://github.com/kaisalmen/WWOBJLoader */ import { LineBasicMaterial, MaterialLoader, MeshStandardMaterial, PointsMaterial, VertexColors } from "../../../../../build/three.module.js"; const MaterialHandler = function () { this.logging = { enabled: false, debug: false }; this.callbacks = { onLoadMaterials: null }; this.materials = {}; }; MaterialHandler.prototype = { constructor: MaterialHandler, /** * Enable or disable logging in general (except warn and error), plus enable or disable debug logging. * * @param {boolean} enabled True or false. * @param {boolean} debug True or false. */ setLogging: function ( enabled, debug ) { this.logging.enabled = enabled === true; this.logging.debug = debug === true; }, _setCallbacks: function ( onLoadMaterials ) { if ( onLoadMaterials !== undefined && onLoadMaterials !== null && onLoadMaterials instanceof Function ) { this.callbacks.onLoadMaterials = onLoadMaterials; } }, /** * Creates default materials and adds them to the materials object. * * @param overrideExisting boolean Override existing material */ createDefaultMaterials: function ( overrideExisting ) { let defaultMaterial = new MeshStandardMaterial( { color: 0xDCF1FF } ); defaultMaterial.name = 'defaultMaterial'; let defaultVertexColorMaterial = new MeshStandardMaterial( { color: 0xDCF1FF } ); defaultVertexColorMaterial.name = 'defaultVertexColorMaterial'; defaultVertexColorMaterial.vertexColors = VertexColors; let defaultLineMaterial = new LineBasicMaterial(); defaultLineMaterial.name = 'defaultLineMaterial'; let defaultPointMaterial = new PointsMaterial( { size: 0.1 } ); defaultPointMaterial.name = 'defaultPointMaterial'; let runtimeMaterials = {}; runtimeMaterials[ defaultMaterial.name ] = defaultMaterial; runtimeMaterials[ defaultVertexColorMaterial.name ] = defaultVertexColorMaterial; runtimeMaterials[ defaultLineMaterial.name ] = defaultLineMaterial; runtimeMaterials[ defaultPointMaterial.name ] = defaultPointMaterial; this.addMaterials( runtimeMaterials, overrideExisting ); }, /** * Updates the materials with contained material objects (sync) or from alteration instructions (async). * * @param {Object} materialPayload Material update instructions * @returns {Object} Map of {@link Material} */ addPayloadMaterials: function ( materialPayload ) { let material, materialName; let materialCloneInstructions = materialPayload.materials.materialCloneInstructions; let newMaterials = {}; if ( materialCloneInstructions !== undefined && materialCloneInstructions !== null ) { let materialNameOrg = materialCloneInstructions.materialNameOrg; materialNameOrg = ( materialNameOrg !== undefined && materialNameOrg !== null ) ? materialNameOrg : ""; let materialOrg = this.materials[ materialNameOrg ]; if ( materialOrg ) { material = materialOrg.clone(); materialName = materialCloneInstructions.materialName; material.name = materialName; Object.assign( material, materialCloneInstructions.materialProperties ); this.materials[ materialName ] = material; newMaterials[ materialName ] = material; } else { if ( this.logging.enabled ) { console.info( 'Requested material "' + materialNameOrg + '" is not available!' ); } } } let materials = materialPayload.materials.serializedMaterials; if ( materials !== undefined && materials !== null && Object.keys( materials ).length > 0 ) { let loader = new MaterialLoader(); let materialJson; for ( materialName in materials ) { materialJson = materials[ materialName ]; if ( materialJson !== undefined && materialJson !== null ) { material = loader.parse( materialJson ); if ( this.logging.enabled ) { console.info( 'De-serialized material with name "' + materialName + '" will be added.' ); } this.materials[ materialName ] = material; newMaterials[ materialName ] = material; } } } materials = materialPayload.materials.runtimeMaterials; newMaterials = this.addMaterials( materials, true, newMaterials ); return newMaterials; }, /** * Set materials loaded by any supplier of an Array of {@link Material}. * * @param materials Object with named {@link Material} * @param overrideExisting boolean Override existing material * @param newMaterials [Object] with named {@link Material} */ addMaterials: function ( materials, overrideExisting, newMaterials ) { if ( newMaterials === undefined || newMaterials === null ) { newMaterials = {}; } if ( materials !== undefined && materials !== null && Object.keys( materials ).length > 0 ) { let material; let existingMaterial; let add; for ( let materialName in materials ) { material = materials[ materialName ]; add = overrideExisting === true; if ( ! add ) { existingMaterial = this.materials[ materialName ]; add = ( existingMaterial === null || existingMaterial === undefined ); } if ( add ) { this.materials[ materialName ] = material; newMaterials[ materialName ] = material; } if ( this.logging.enabled && this.logging.debug ) { console.info( 'Material with name "' + materialName + '" was added.' ); } } } if ( this.callbacks.onLoadMaterials ) { this.callbacks.onLoadMaterials( newMaterials ); } return newMaterials; }, /** * Returns the mapping object of material name and corresponding material. * * @returns {Object} Map of {@link Material} */ getMaterials: function () { return this.materials; }, /** * * @param {String} materialName * @returns {Material} */ getMaterial: function ( materialName ) { return this.materials[ materialName ]; }, /** * Returns the mapping object of material name and corresponding jsonified material. * * @returns {Object} Map of Materials in JSON representation */ getMaterialsJSON: function () { let materialsJSON = {}; let material; for ( let materialName in this.materials ) { material = this.materials[ materialName ]; materialsJSON[ materialName ] = material.toJSON(); } return materialsJSON; }, /** * Removes all materials */ clearMaterials: function () { this.materials = {}; } }; export { MaterialHandler };