RenderableInspector.cs 7.9 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<RRef<Material>, MaterialArrayRow> materialsField;
  20. private List<MaterialParamGUI[]> materialParams = new List<MaterialParamGUI[]>();
  21. private ulong layersValue = 0;
  22. private InspectableState modifyState;
  23. private RRef<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. RRef<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.ValueRef = 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. Material material = materials[i].Value;
  81. if (material != null && materialParams[i] != null)
  82. {
  83. foreach (var param in materialParams[i])
  84. param.Refresh(material);
  85. }
  86. }
  87. }
  88. InspectableState oldState = modifyState;
  89. if (modifyState.HasFlag(InspectableState.Modified))
  90. modifyState = InspectableState.NotModified;
  91. return oldState;
  92. }
  93. /// <summary>
  94. /// Recreates all the GUI elements used by this inspector.
  95. /// </summary>
  96. private void BuildGUI()
  97. {
  98. Layout.Clear();
  99. Renderable renderable = InspectedObject as Renderable;
  100. if (renderable == null)
  101. return;
  102. meshField = new GUIResourceField(typeof(Mesh), new LocEdString("Mesh"));
  103. layersField = new GUIListBoxField(Layers.Names, false, new LocEdString("Layer"));
  104. Layout.AddElement(meshField);
  105. Layout.AddElement(layersField);
  106. layersValue = 0;
  107. materials = renderable.Materials;
  108. materialsField = GUIArrayField<RRef<Material>, MaterialArrayRow>.Create(new LocEdString("Materials"), materials, Layout);
  109. materialsField.OnChanged += x => { materials = x; };
  110. materialsField.IsExpanded = Persistent.GetBool("materialsField_Expanded");
  111. materialsField.OnExpand += x => Persistent.SetBool("materialsField_Expanded", x);
  112. meshField.OnChanged += x =>
  113. {
  114. Mesh mesh = Resources.Load<Mesh>(x.UUID);
  115. renderable.Mesh = mesh;
  116. MarkAsModified();
  117. ConfirmModify();
  118. };
  119. layersField.OnSelectionChanged += x =>
  120. {
  121. ulong layers = 0;
  122. bool[] states = layersField.States;
  123. for (int i = 0; i < states.Length; i++)
  124. layers |= states[i] ? Layers.Values[i] : 0;
  125. layersValue = layers;
  126. renderable.Layers = layers;
  127. MarkAsModified();
  128. ConfirmModify();
  129. };
  130. materialsLayout = Layout.AddLayoutY();
  131. BuildMaterialsGUI();
  132. }
  133. /// <summary>
  134. /// Builds the portion of the GUI that displays details about individual materials.
  135. /// </summary>
  136. private void BuildMaterialsGUI()
  137. {
  138. materialsLayout.Clear();
  139. materialParams.Clear();
  140. if (materials != null)
  141. {
  142. for (int i = 0; i < materials.Length; i++)
  143. {
  144. Material material = materials[i].Value;
  145. if (material == null)
  146. {
  147. materialParams.Add(new MaterialParamGUI[0]);
  148. continue;
  149. }
  150. materialsLayout.AddSpace(10);
  151. MaterialParamGUI[] matParams = MaterialInspector.CreateMaterialGUI(material, materialsLayout);
  152. materialParams.Add(matParams);
  153. }
  154. }
  155. }
  156. /// <summary>
  157. /// Marks the contents of the inspector as modified.
  158. /// </summary>
  159. protected void MarkAsModified()
  160. {
  161. modifyState |= InspectableState.ModifyInProgress;
  162. }
  163. /// <summary>
  164. /// Confirms any queued modifications.
  165. /// </summary>
  166. protected void ConfirmModify()
  167. {
  168. if (modifyState.HasFlag(InspectableState.ModifyInProgress))
  169. modifyState |= InspectableState.Modified;
  170. }
  171. /// <summary>
  172. /// Row element used for displaying GUI for material array elements.
  173. /// </summary>
  174. private class MaterialArrayRow : GUIListFieldRow
  175. {
  176. private GUIResourceField materialField;
  177. /// <inheritdoc/>
  178. protected override GUILayoutX CreateGUI(GUILayoutY layout)
  179. {
  180. GUILayoutX titleLayout = layout.AddLayoutX();
  181. materialField = new GUIResourceField(typeof(Material), new LocEdString(SeqIndex + ". "), 20);
  182. titleLayout.AddElement(materialField);
  183. materialField.OnChanged += x =>
  184. {
  185. SetValue(x.As<Material>());
  186. MarkAsModified();
  187. ConfirmModify();
  188. };
  189. return titleLayout;
  190. }
  191. /// <inheritdoc/>
  192. internal protected override InspectableState Refresh()
  193. {
  194. materialField.ValueRef = GetValue<RRef<Material>>();
  195. return base.Refresh();
  196. }
  197. }
  198. }
  199. /** @} */
  200. }