MaterialHandler.js 6.2 KB

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