materialDefines.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /**
  2. * Manages the defines for the Material
  3. */
  4. export class MaterialDefines {
  5. /**
  6. * Creates a new instance
  7. * @param externalProperties list of external properties to inject into the object
  8. */
  9. constructor(externalProperties) {
  10. /** @internal */
  11. this._keys = [];
  12. this._isDirty = true;
  13. /** @internal */
  14. this._areLightsDirty = true;
  15. /** @internal */
  16. this._areLightsDisposed = false;
  17. /** @internal */
  18. this._areAttributesDirty = true;
  19. /** @internal */
  20. this._areTexturesDirty = true;
  21. /** @internal */
  22. this._areFresnelDirty = true;
  23. /** @internal */
  24. this._areMiscDirty = true;
  25. /** @internal */
  26. this._arePrePassDirty = true;
  27. /** @internal */
  28. this._areImageProcessingDirty = true;
  29. /** @internal */
  30. this._normals = false;
  31. /** @internal */
  32. this._uvs = false;
  33. /** @internal */
  34. this._needNormals = false;
  35. /** @internal */
  36. this._needUVs = false;
  37. this._externalProperties = externalProperties;
  38. // Initialize External Properties
  39. if (externalProperties) {
  40. for (const prop in externalProperties) {
  41. if (Object.prototype.hasOwnProperty.call(externalProperties, prop)) {
  42. this._setDefaultValue(prop);
  43. }
  44. }
  45. }
  46. }
  47. /**
  48. * Specifies if the material needs to be re-calculated
  49. */
  50. get isDirty() {
  51. return this._isDirty;
  52. }
  53. /**
  54. * Marks the material to indicate that it has been re-calculated
  55. */
  56. markAsProcessed() {
  57. this._isDirty = false;
  58. this._areAttributesDirty = false;
  59. this._areTexturesDirty = false;
  60. this._areFresnelDirty = false;
  61. this._areLightsDirty = false;
  62. this._areLightsDisposed = false;
  63. this._areMiscDirty = false;
  64. this._arePrePassDirty = false;
  65. this._areImageProcessingDirty = false;
  66. }
  67. /**
  68. * Marks the material to indicate that it needs to be re-calculated
  69. */
  70. markAsUnprocessed() {
  71. this._isDirty = true;
  72. }
  73. /**
  74. * Marks the material to indicate all of its defines need to be re-calculated
  75. */
  76. markAllAsDirty() {
  77. this._areTexturesDirty = true;
  78. this._areAttributesDirty = true;
  79. this._areLightsDirty = true;
  80. this._areFresnelDirty = true;
  81. this._areMiscDirty = true;
  82. this._arePrePassDirty = false;
  83. this._areImageProcessingDirty = true;
  84. this._isDirty = true;
  85. }
  86. /**
  87. * Marks the material to indicate that image processing needs to be re-calculated
  88. */
  89. markAsImageProcessingDirty() {
  90. this._areImageProcessingDirty = true;
  91. this._isDirty = true;
  92. }
  93. /**
  94. * Marks the material to indicate the lights need to be re-calculated
  95. * @param disposed Defines whether the light is dirty due to dispose or not
  96. */
  97. markAsLightDirty(disposed = false) {
  98. this._areLightsDirty = true;
  99. this._areLightsDisposed = this._areLightsDisposed || disposed;
  100. this._isDirty = true;
  101. }
  102. /**
  103. * Marks the attribute state as changed
  104. */
  105. markAsAttributesDirty() {
  106. this._areAttributesDirty = true;
  107. this._isDirty = true;
  108. }
  109. /**
  110. * Marks the texture state as changed
  111. */
  112. markAsTexturesDirty() {
  113. this._areTexturesDirty = true;
  114. this._isDirty = true;
  115. }
  116. /**
  117. * Marks the fresnel state as changed
  118. */
  119. markAsFresnelDirty() {
  120. this._areFresnelDirty = true;
  121. this._isDirty = true;
  122. }
  123. /**
  124. * Marks the misc state as changed
  125. */
  126. markAsMiscDirty() {
  127. this._areMiscDirty = true;
  128. this._isDirty = true;
  129. }
  130. /**
  131. * Marks the prepass state as changed
  132. */
  133. markAsPrePassDirty() {
  134. this._arePrePassDirty = true;
  135. this._isDirty = true;
  136. }
  137. /**
  138. * Rebuilds the material defines
  139. */
  140. rebuild() {
  141. this._keys.length = 0;
  142. for (const key of Object.keys(this)) {
  143. if (key[0] === "_") {
  144. continue;
  145. }
  146. this._keys.push(key);
  147. }
  148. if (this._externalProperties) {
  149. for (const name in this._externalProperties) {
  150. if (this._keys.indexOf(name) === -1) {
  151. this._keys.push(name);
  152. }
  153. }
  154. }
  155. }
  156. /**
  157. * Specifies if two material defines are equal
  158. * @param other - A material define instance to compare to
  159. * @returns - Boolean indicating if the material defines are equal (true) or not (false)
  160. */
  161. isEqual(other) {
  162. if (this._keys.length !== other._keys.length) {
  163. return false;
  164. }
  165. for (let index = 0; index < this._keys.length; index++) {
  166. const prop = this._keys[index];
  167. if (this[prop] !== other[prop]) {
  168. return false;
  169. }
  170. }
  171. return true;
  172. }
  173. /**
  174. * Clones this instance's defines to another instance
  175. * @param other - material defines to clone values to
  176. */
  177. cloneTo(other) {
  178. if (this._keys.length !== other._keys.length) {
  179. other._keys = this._keys.slice(0);
  180. }
  181. for (let index = 0; index < this._keys.length; index++) {
  182. const prop = this._keys[index];
  183. other[prop] = this[prop];
  184. }
  185. }
  186. /**
  187. * Resets the material define values
  188. */
  189. reset() {
  190. this._keys.forEach((prop) => this._setDefaultValue(prop));
  191. }
  192. _setDefaultValue(prop) {
  193. const type = this._externalProperties?.[prop]?.type ?? typeof this[prop];
  194. const defValue = this._externalProperties?.[prop]?.default;
  195. switch (type) {
  196. case "number":
  197. this[prop] = defValue ?? 0;
  198. break;
  199. case "string":
  200. this[prop] = defValue ?? "";
  201. break;
  202. default:
  203. this[prop] = defValue ?? false;
  204. break;
  205. }
  206. }
  207. /**
  208. * Converts the material define values to a string
  209. * @returns - String of material define information
  210. */
  211. toString() {
  212. let result = "";
  213. for (let index = 0; index < this._keys.length; index++) {
  214. const prop = this._keys[index];
  215. const value = this[prop];
  216. const type = typeof value;
  217. switch (type) {
  218. case "number":
  219. case "string":
  220. result += "#define " + prop + " " + value + "\n";
  221. break;
  222. default:
  223. if (value) {
  224. result += "#define " + prop + "\n";
  225. }
  226. break;
  227. }
  228. }
  229. return result;
  230. }
  231. }
  232. //# sourceMappingURL=materialDefines.js.map