RenderableInspector.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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. meshField.OnChanged += x =>
  104. {
  105. Mesh mesh = Resources.Load<Mesh>(x);
  106. renderable.Mesh = mesh;
  107. MarkAsModified();
  108. ConfirmModify();
  109. };
  110. layersField.OnSelectionChanged += x =>
  111. {
  112. ulong layers = 0;
  113. bool[] states = layersField.States;
  114. for (int i = 0; i < states.Length; i++)
  115. layers |= states[i] ? Layers.Values[i] : 0;
  116. layersValue = layers;
  117. renderable.Layers = layers;
  118. MarkAsModified();
  119. ConfirmModify();
  120. };
  121. materialsLayout = Layout.AddLayoutY();
  122. BuildMaterialsGUI();
  123. }
  124. /// <summary>
  125. /// Builds the portion of the GUI that displays details about individual materials.
  126. /// </summary>
  127. private void BuildMaterialsGUI()
  128. {
  129. materialsLayout.Clear();
  130. materialParams.Clear();
  131. if (materials != null)
  132. {
  133. for (int i = 0; i < materials.Length; i++)
  134. {
  135. if (materials[i] == null)
  136. {
  137. materialParams.Add(new MaterialParamGUI[0]);
  138. continue;
  139. }
  140. materialsLayout.AddSpace(10);
  141. MaterialParamGUI[] matParams = MaterialInspector.CreateMaterialGUI(materials[i], materialsLayout);
  142. materialParams.Add(matParams);
  143. }
  144. }
  145. }
  146. /// <summary>
  147. /// Marks the contents of the inspector as modified.
  148. /// </summary>
  149. protected void MarkAsModified()
  150. {
  151. modifyState |= InspectableState.ModifyInProgress;
  152. }
  153. /// <summary>
  154. /// Confirms any queued modifications.
  155. /// </summary>
  156. protected void ConfirmModify()
  157. {
  158. if (modifyState.HasFlag(InspectableState.ModifyInProgress))
  159. modifyState |= InspectableState.Modified;
  160. }
  161. /// <summary>
  162. /// Row element used for displaying GUI for material array elements.
  163. /// </summary>
  164. public class MaterialArrayRow : GUIListFieldRow
  165. {
  166. private GUIResourceField materialField;
  167. /// <inheritdoc/>
  168. protected override GUILayoutX CreateGUI(GUILayoutY layout)
  169. {
  170. GUILayoutX titleLayout = layout.AddLayoutX();
  171. materialField = new GUIResourceField(typeof(Material), new LocEdString(SeqIndex + ". "), 20);
  172. titleLayout.AddElement(materialField);
  173. materialField.OnChanged += x =>
  174. {
  175. Material material = Resources.Load<Material>(x);
  176. SetValue(material);
  177. MarkAsModified();
  178. ConfirmModify();
  179. };
  180. return titleLayout;
  181. }
  182. /// <inheritdoc/>
  183. internal protected override InspectableState Refresh()
  184. {
  185. materialField.Value = GetValue<Material>();
  186. return base.Refresh();
  187. }
  188. }
  189. }
  190. }