babylon.multiMaterial.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. module BABYLON {
  2. export class MultiMaterial extends Material {
  3. private _subMaterials: Nullable<Material>[];
  4. public get subMaterials(): Nullable<Material>[] {
  5. return this._subMaterials;
  6. }
  7. public set subMaterials(value: Nullable<Material>[]) {
  8. this._subMaterials = value;
  9. this._hookArray(value);
  10. }
  11. constructor(name: string, scene: Scene) {
  12. super(name, scene, true);
  13. scene.multiMaterials.push(this);
  14. this.subMaterials = new Array<Material>();
  15. this.storeEffectOnSubMeshes = true; // multimaterial is considered like a push material
  16. }
  17. private _hookArray(array: Nullable<Material>[]): void {
  18. var oldPush = array.push;
  19. array.push = (...items: Nullable<Material>[]) => {
  20. var result = oldPush.apply(array, items);
  21. this._markAllSubMeshesAsTexturesDirty();
  22. return result;
  23. }
  24. var oldSplice = array.splice;
  25. array.splice = (index: number, deleteCount?: number) => {
  26. var deleted = oldSplice.apply(array, [index, deleteCount]);
  27. this._markAllSubMeshesAsTexturesDirty();
  28. return deleted;
  29. }
  30. }
  31. // Properties
  32. public getSubMaterial(index: number): Nullable<Material> {
  33. if (index < 0 || index >= this.subMaterials.length) {
  34. return this.getScene().defaultMaterial;
  35. }
  36. return this.subMaterials[index];
  37. }
  38. public getActiveTextures(): BaseTexture[] {
  39. return super.getActiveTextures().concat(...this.subMaterials.map(subMaterial => {
  40. if (subMaterial) {
  41. return subMaterial.getActiveTextures();
  42. } else {
  43. return [];
  44. }
  45. }));
  46. }
  47. // Methods
  48. public getClassName(): string {
  49. return "MultiMaterial";
  50. }
  51. public isReadyForSubMesh(mesh: AbstractMesh, subMesh: BaseSubMesh, useInstances?: boolean): boolean {
  52. for (var index = 0; index < this.subMaterials.length; index++) {
  53. var subMaterial = this.subMaterials[index];
  54. if (subMaterial) {
  55. if (subMaterial.storeEffectOnSubMeshes) {
  56. if (!subMaterial.isReadyForSubMesh(mesh, subMesh, useInstances)) {
  57. return false;
  58. }
  59. continue;
  60. }
  61. if (!subMaterial.isReady(mesh)) {
  62. return false;
  63. }
  64. }
  65. }
  66. return true;
  67. }
  68. public clone(name: string, cloneChildren?: boolean): MultiMaterial {
  69. var newMultiMaterial = new MultiMaterial(name, this.getScene());
  70. for (var index = 0; index < this.subMaterials.length; index++) {
  71. var subMaterial: Nullable<Material> = null;
  72. let current = this.subMaterials[index];
  73. if (cloneChildren && current) {
  74. subMaterial = current.clone(name + "-" + current.name);
  75. } else {
  76. subMaterial = this.subMaterials[index];
  77. }
  78. newMultiMaterial.subMaterials.push(subMaterial);
  79. }
  80. return newMultiMaterial;
  81. }
  82. public serialize(): any {
  83. var serializationObject: any = {};
  84. serializationObject.name = this.name;
  85. serializationObject.id = this.id;
  86. if (Tags) {
  87. serializationObject.tags = Tags.GetTags(this);
  88. }
  89. serializationObject.materials = [];
  90. for (var matIndex = 0; matIndex < this.subMaterials.length; matIndex++) {
  91. var subMat = this.subMaterials[matIndex];
  92. if (subMat) {
  93. serializationObject.materials.push(subMat.id);
  94. } else {
  95. serializationObject.materials.push(null);
  96. }
  97. }
  98. return serializationObject;
  99. }
  100. public dispose(forceDisposeEffect?: boolean, forceDisposeTextures?: boolean): void {
  101. var scene = this.getScene();
  102. if (!scene) {
  103. return;
  104. }
  105. var index = scene.multiMaterials.indexOf(this);
  106. if (index >= 0) {
  107. scene.multiMaterials.splice(index, 1);
  108. }
  109. super.dispose(forceDisposeEffect, forceDisposeTextures);
  110. }
  111. }
  112. }