RenderableInspector.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using BansheeEngine;
  4. namespace BansheeEditor
  5. {
  6. /// <summary>
  7. /// Renders an inspector for the <see cref="Renderable"/> component.
  8. /// </summary>
  9. [CustomInspector(typeof (Renderable))]
  10. internal class RenderableInspector : Inspector
  11. {
  12. private GUIResourceField meshField;
  13. private GUIListBoxField layersField;
  14. private GUIArrayField<Material, MaterialArrayRow> materialsField;
  15. private List<MaterialParamGUI[]> materialParams = new List<MaterialParamGUI[]>();
  16. private ulong layersValue = 0;
  17. private InspectableState modifyState;
  18. private Material[] materials;
  19. private GUILayout materialsLayout;
  20. /// <inheritdoc/>
  21. protected internal override void Initialize()
  22. {
  23. BuildGUI();
  24. }
  25. /// <inheritdoc/>
  26. protected internal override InspectableState Refresh()
  27. {
  28. Renderable renderable = InspectedObject as Renderable;
  29. if (renderable == null)
  30. return InspectableState.NotModified;
  31. bool rebuildMaterialsGUI = false;
  32. Material[] newMaterials = renderable.Materials;
  33. if (newMaterials == null)
  34. rebuildMaterialsGUI = materials != null;
  35. else
  36. {
  37. if (materials == null)
  38. rebuildMaterialsGUI = true;
  39. else
  40. {
  41. if (materials.Length != newMaterials.Length)
  42. rebuildMaterialsGUI = true;
  43. else
  44. {
  45. for (int i = 0; i < materials.Length; i++)
  46. {
  47. if (materials[i] != newMaterials[i])
  48. {
  49. rebuildMaterialsGUI = true;
  50. break;
  51. }
  52. }
  53. }
  54. }
  55. }
  56. if (rebuildMaterialsGUI)
  57. BuildMaterialsGUI();
  58. meshField.Value = renderable.Mesh;
  59. if (layersValue != renderable.Layers)
  60. {
  61. bool[] states = new bool[64];
  62. for (int i = 0; i < states.Length; i++)
  63. states[i] = (renderable.Layers & Layers.Values[i]) == Layers.Values[i];
  64. layersField.States = states;
  65. layersValue = renderable.Layers;
  66. }
  67. InspectableState materialsModified = materialsField.Refresh();
  68. if (materialsModified == InspectableState.Modified)
  69. renderable.Materials = materials;
  70. modifyState |= materialsModified;
  71. if (materials != null)
  72. {
  73. for (int i = 0; i < materialParams.Count; i++)
  74. {
  75. if (materialParams[i] != null)
  76. {
  77. foreach (var param in materialParams[i])
  78. param.Refresh(materials[i]);
  79. }
  80. }
  81. }
  82. InspectableState oldState = modifyState;
  83. if (modifyState.HasFlag(InspectableState.Modified))
  84. modifyState = InspectableState.NotModified;
  85. return oldState;
  86. }
  87. /// <summary>
  88. /// Recreates all the GUI elements used by this inspector.
  89. /// </summary>
  90. private void BuildGUI()
  91. {
  92. Layout.Clear();
  93. Renderable renderable = InspectedObject as Renderable;
  94. if (renderable == null)
  95. return;
  96. meshField = new GUIResourceField(typeof(Mesh), new LocEdString("Mesh"));
  97. layersField = new GUIListBoxField(Layers.Names, true, new LocEdString("Layers"));
  98. Layout.AddElement(meshField);
  99. Layout.AddElement(layersField);
  100. layersValue = 0;
  101. materials = renderable.Materials;
  102. materialsField = GUIArrayField<Material, MaterialArrayRow>.Create(new LocEdString("Materials"), materials, Layout);
  103. materialsField.OnChanged += x => { materials = x; };
  104. meshField.OnChanged += x =>
  105. {
  106. Mesh mesh = Resources.Load<Mesh>(x);
  107. renderable.Mesh = mesh;
  108. MarkAsModified();
  109. ConfirmModify();
  110. };
  111. layersField.OnSelectionChanged += x =>
  112. {
  113. ulong layers = 0;
  114. bool[] states = layersField.States;
  115. for (int i = 0; i < states.Length; i++)
  116. layers |= states[i] ? Layers.Values[i] : 0;
  117. layersValue = layers;
  118. renderable.Layers = layers;
  119. MarkAsModified();
  120. ConfirmModify();
  121. };
  122. materialsLayout = Layout.AddLayoutY();
  123. BuildMaterialsGUI();
  124. }
  125. /// <summary>
  126. /// Builds the portion of the GUI that displays details about individual materials.
  127. /// </summary>
  128. private void BuildMaterialsGUI()
  129. {
  130. materialsLayout.Clear();
  131. materialParams.Clear();
  132. if (materials != null)
  133. {
  134. for (int i = 0; i < materials.Length; i++)
  135. {
  136. if (materials[i] == null)
  137. {
  138. materialParams.Add(new MaterialParamGUI[0]);
  139. continue;
  140. }
  141. materialsLayout.AddSpace(10);
  142. MaterialParamGUI[] matParams = MaterialInspector.CreateMaterialGUI(materials[i], materialsLayout);
  143. materialParams.Add(matParams);
  144. }
  145. }
  146. }
  147. /// <summary>
  148. /// Marks the contents of the inspector as modified.
  149. /// </summary>
  150. protected void MarkAsModified()
  151. {
  152. modifyState |= InspectableState.ModifyInProgress;
  153. }
  154. /// <summary>
  155. /// Confirms any queued modifications.
  156. /// </summary>
  157. protected void ConfirmModify()
  158. {
  159. if (modifyState.HasFlag(InspectableState.ModifyInProgress))
  160. modifyState |= InspectableState.Modified;
  161. }
  162. /// <summary>
  163. /// Row element used for displaying GUI for material array elements.
  164. /// </summary>
  165. public class MaterialArrayRow : GUIListFieldRow
  166. {
  167. private GUIResourceField materialField;
  168. /// <inheritdoc/>
  169. protected override GUILayoutX CreateGUI(GUILayoutY layout)
  170. {
  171. GUILayoutX titleLayout = layout.AddLayoutX();
  172. materialField = new GUIResourceField(typeof(Material), new LocEdString(SeqIndex + ". "), 20);
  173. titleLayout.AddElement(materialField);
  174. materialField.OnChanged += x =>
  175. {
  176. Material material = Resources.Load<Material>(x);
  177. SetValue(material);
  178. MarkAsModified();
  179. ConfirmModify();
  180. };
  181. return titleLayout;
  182. }
  183. /// <inheritdoc/>
  184. internal protected override InspectableState Refresh()
  185. {
  186. materialField.Value = GetValue<Material>();
  187. return base.Refresh();
  188. }
  189. }
  190. }
  191. }