babylon.multiMaterial.ts 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. module BABYLON {
  2. export class MultiMaterial extends Material {
  3. private _subMaterials: Material[];
  4. public get subMaterials(): Material[] {
  5. return this._subMaterials;
  6. }
  7. public set subMaterials(value: 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: Material[]): void {
  18. var oldPush = array.push;
  19. array.push = (...items: 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) {
  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 => subMaterial.getActiveTextures()));
  40. }
  41. // Methods
  42. public getClassName(): string {
  43. return "MultiMaterial";
  44. }
  45. public isReadyForSubMesh(mesh: AbstractMesh, subMesh: BaseSubMesh, useInstances?: boolean): boolean {
  46. for (var index = 0; index < this.subMaterials.length; index++) {
  47. var subMaterial = this.subMaterials[index];
  48. if (subMaterial) {
  49. if (this.subMaterials[index].storeEffectOnSubMeshes) {
  50. if (!this.subMaterials[index].isReadyForSubMesh(mesh, subMesh, useInstances)) {
  51. return false;
  52. }
  53. continue;
  54. }
  55. if (!this.subMaterials[index].isReady(mesh)) {
  56. return false;
  57. }
  58. }
  59. }
  60. return true;
  61. }
  62. public clone(name: string, cloneChildren?: boolean): MultiMaterial {
  63. var newMultiMaterial = new MultiMaterial(name, this.getScene());
  64. for (var index = 0; index < this.subMaterials.length; index++) {
  65. var subMaterial: Material = null;
  66. if (cloneChildren) {
  67. subMaterial = this.subMaterials[index].clone(name + "-" + this.subMaterials[index].name);
  68. } else {
  69. subMaterial = this.subMaterials[index];
  70. }
  71. newMultiMaterial.subMaterials.push(subMaterial);
  72. }
  73. return newMultiMaterial;
  74. }
  75. public serialize(): any {
  76. var serializationObject: any = {};
  77. serializationObject.name = this.name;
  78. serializationObject.id = this.id;
  79. serializationObject.tags = Tags.GetTags(this);
  80. serializationObject.materials = [];
  81. for (var matIndex = 0; matIndex < this.subMaterials.length; matIndex++) {
  82. var subMat = this.subMaterials[matIndex];
  83. if (subMat) {
  84. serializationObject.materials.push(subMat.id);
  85. } else {
  86. serializationObject.materials.push(null);
  87. }
  88. }
  89. return serializationObject;
  90. }
  91. public dispose(forceDisposeEffect?: boolean, forceDisposeTextures?: boolean): void {
  92. var scene = this.getScene();
  93. if (!scene) {
  94. return;
  95. }
  96. var index = scene.multiMaterials.indexOf(this);
  97. if (index >= 0) {
  98. scene.multiMaterials.splice(index, 1);
  99. }
  100. super.dispose(forceDisposeEffect, forceDisposeTextures);
  101. }
  102. }
  103. }