MaterialHandler.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /**
  2. * @author Kai Salmen / https://kaisalmen.de
  3. * Development repository: https://github.com/kaisalmen/WWOBJLoader
  4. */
  5. import {
  6. LineBasicMaterial,
  7. MaterialLoader,
  8. MeshStandardMaterial,
  9. PointsMaterial
  10. } from "../../../../../build/three.module.js";
  11. const MaterialHandler = function () {
  12. this.logging = {
  13. enabled: false,
  14. debug: false
  15. };
  16. this.callbacks = {
  17. onLoadMaterials: null
  18. };
  19. this.materials = {};
  20. };
  21. MaterialHandler.prototype = {
  22. constructor: MaterialHandler,
  23. /**
  24. * Enable or disable logging in general (except warn and error), plus enable or disable debug logging.
  25. *
  26. * @param {boolean} enabled True or false.
  27. * @param {boolean} debug True or false.
  28. */
  29. setLogging: function ( enabled, debug ) {
  30. this.logging.enabled = enabled === true;
  31. this.logging.debug = debug === true;
  32. },
  33. _setCallbacks: function ( onLoadMaterials ) {
  34. if ( onLoadMaterials !== undefined && onLoadMaterials !== null && onLoadMaterials instanceof Function ) {
  35. this.callbacks.onLoadMaterials = onLoadMaterials;
  36. }
  37. },
  38. /**
  39. * Creates default materials and adds them to the materials object.
  40. *
  41. * @param overrideExisting boolean Override existing material
  42. */
  43. createDefaultMaterials: function ( overrideExisting ) {
  44. let defaultMaterial = new MeshStandardMaterial( { color: 0xDCF1FF } );
  45. defaultMaterial.name = 'defaultMaterial';
  46. let defaultVertexColorMaterial = new MeshStandardMaterial( { color: 0xDCF1FF } );
  47. defaultVertexColorMaterial.name = 'defaultVertexColorMaterial';
  48. defaultVertexColorMaterial.vertexColors = true;
  49. let defaultLineMaterial = new LineBasicMaterial();
  50. defaultLineMaterial.name = 'defaultLineMaterial';
  51. let defaultPointMaterial = new PointsMaterial( { size: 0.1 } );
  52. defaultPointMaterial.name = 'defaultPointMaterial';
  53. let runtimeMaterials = {};
  54. runtimeMaterials[ defaultMaterial.name ] = defaultMaterial;
  55. runtimeMaterials[ defaultVertexColorMaterial.name ] = defaultVertexColorMaterial;
  56. runtimeMaterials[ defaultLineMaterial.name ] = defaultLineMaterial;
  57. runtimeMaterials[ defaultPointMaterial.name ] = defaultPointMaterial;
  58. this.addMaterials( runtimeMaterials, overrideExisting );
  59. },
  60. /**
  61. * Updates the materials with contained material objects (sync) or from alteration instructions (async).
  62. *
  63. * @param {Object} materialPayload Material update instructions
  64. * @returns {Object} Map of {@link Material}
  65. */
  66. addPayloadMaterials: function ( materialPayload ) {
  67. let material, materialName;
  68. let materialCloneInstructions = materialPayload.materials.materialCloneInstructions;
  69. let newMaterials = {};
  70. if ( materialCloneInstructions !== undefined && materialCloneInstructions !== null ) {
  71. let materialNameOrg = materialCloneInstructions.materialNameOrg;
  72. materialNameOrg = ( materialNameOrg !== undefined && materialNameOrg !== null ) ? materialNameOrg : "";
  73. let materialOrg = this.materials[ materialNameOrg ];
  74. if ( materialOrg ) {
  75. material = materialOrg.clone();
  76. materialName = materialCloneInstructions.materialName;
  77. material.name = materialName;
  78. Object.assign( material, materialCloneInstructions.materialProperties );
  79. this.materials[ materialName ] = material;
  80. newMaterials[ materialName ] = material;
  81. } else {
  82. if ( this.logging.enabled ) {
  83. console.info( 'Requested material "' + materialNameOrg + '" is not available!' );
  84. }
  85. }
  86. }
  87. let materials = materialPayload.materials.serializedMaterials;
  88. if ( materials !== undefined && materials !== null && Object.keys( materials ).length > 0 ) {
  89. let loader = new MaterialLoader();
  90. let materialJson;
  91. for ( materialName in materials ) {
  92. materialJson = materials[ materialName ];
  93. if ( materialJson !== undefined && materialJson !== null ) {
  94. material = loader.parse( materialJson );
  95. if ( this.logging.enabled ) {
  96. console.info( 'De-serialized material with name "' + materialName + '" will be added.' );
  97. }
  98. this.materials[ materialName ] = material;
  99. newMaterials[ materialName ] = material;
  100. }
  101. }
  102. }
  103. materials = materialPayload.materials.runtimeMaterials;
  104. newMaterials = this.addMaterials( materials, true, newMaterials );
  105. return newMaterials;
  106. },
  107. /**
  108. * Set materials loaded by any supplier of an Array of {@link Material}.
  109. *
  110. * @param materials Object with named {@link Material}
  111. * @param overrideExisting boolean Override existing material
  112. * @param newMaterials [Object] with named {@link Material}
  113. */
  114. addMaterials: function ( materials, overrideExisting, newMaterials ) {
  115. if ( newMaterials === undefined || newMaterials === null ) {
  116. newMaterials = {};
  117. }
  118. if ( materials !== undefined && materials !== null && Object.keys( materials ).length > 0 ) {
  119. let material;
  120. let existingMaterial;
  121. let add;
  122. for ( let materialName in materials ) {
  123. material = materials[ materialName ];
  124. add = overrideExisting === true;
  125. if ( ! add ) {
  126. existingMaterial = this.materials[ materialName ];
  127. add = ( existingMaterial === null || existingMaterial === undefined );
  128. }
  129. if ( add ) {
  130. this.materials[ materialName ] = material;
  131. newMaterials[ materialName ] = material;
  132. }
  133. if ( this.logging.enabled && this.logging.debug ) {
  134. console.info( 'Material with name "' + materialName + '" was added.' );
  135. }
  136. }
  137. }
  138. if ( this.callbacks.onLoadMaterials ) {
  139. this.callbacks.onLoadMaterials( newMaterials );
  140. }
  141. return newMaterials;
  142. },
  143. /**
  144. * Returns the mapping object of material name and corresponding material.
  145. *
  146. * @returns {Object} Map of {@link Material}
  147. */
  148. getMaterials: function () {
  149. return this.materials;
  150. },
  151. /**
  152. *
  153. * @param {String} materialName
  154. * @returns {Material}
  155. */
  156. getMaterial: function ( materialName ) {
  157. return this.materials[ materialName ];
  158. },
  159. /**
  160. * Returns the mapping object of material name and corresponding jsonified material.
  161. *
  162. * @returns {Object} Map of Materials in JSON representation
  163. */
  164. getMaterialsJSON: function () {
  165. let materialsJSON = {};
  166. let material;
  167. for ( let materialName in this.materials ) {
  168. material = this.materials[ materialName ];
  169. materialsJSON[ materialName ] = material.toJSON();
  170. }
  171. return materialsJSON;
  172. },
  173. /**
  174. * Removes all materials
  175. */
  176. clearMaterials: function () {
  177. this.materials = {};
  178. }
  179. };
  180. export { MaterialHandler };