RenderableInspector.cs 7.7 KB

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