RenderableInspector.cs 7.8 KB

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