ScaleTool.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // River Modeler
  2. // Staggart Creations (http://staggart.xyz)
  3. // Copyright protected under Unity Asset Store EULA
  4. // Copying or referencing source code for the production of new asset store content is strictly prohibited.
  5. using UnityEngine;
  6. using UnityEditor;
  7. using sc.modeling.river.runtime;
  8. using UnityEditor.EditorTools;
  9. #if SPLINES
  10. using UnityEditor.Splines;
  11. using UnityEngine.Splines;
  12. #endif
  13. #if MATHEMATICS
  14. using Unity.Mathematics;
  15. #endif
  16. namespace sc.modeling.river.editor
  17. {
  18. #if SPLINES && MATHEMATICS
  19. [EditorTool(NAME, typeof(RiverModeler))]
  20. public class ScaleTool : RiverAttributeTool<float3>, IDrawSelectedHandles
  21. {
  22. private const string NAME = "River Scale Tool";
  23. public const string IconName = "river-scale-tool-64px";
  24. void OnEnable()
  25. {
  26. name = NAME;
  27. m_IconContent = new GUIContent()
  28. {
  29. image = Resources.Load<Texture2D>(IconName),
  30. text = "Scale Tool",
  31. tooltip = "Adjust the width and displacement scale of the created river mesh."
  32. };
  33. changeFlag = RiverModeler.ChangeFlags.Scale | RiverModeler.ChangeFlags.Data;
  34. }
  35. public override void OnToolGUI(EditorWindow window)
  36. {
  37. var modeler = target as RiverModeler;
  38. if (modeler == null || modeler.splineContainer == null)
  39. return;
  40. base.OnToolGUI(window);
  41. Handles.color = Color.green;
  42. m_DisableHandles = false;
  43. var splines = modeler.splineContainer.Splines;
  44. for (var i = 0; i < splines.Count; i++)
  45. {
  46. if (i < modeler.ScaleData.Count)
  47. {
  48. var nativeSpline = new NativeSpline(splines[i], modeler.splineContainer.transform.localToWorldMatrix);
  49. Undo.RecordObject(modeler, "Modifying River Scale");
  50. // User defined handles to manipulate width
  51. DrawDataPoints(nativeSpline, modeler.ScaleData[i]);
  52. // Using the out-of the box behaviour to manipulate indexes
  53. nativeSpline.DataPointHandles(modeler.ScaleData[i], true, i);
  54. if (GUI.changed)
  55. {
  56. modeler.Rebuild(changeFlag);
  57. }
  58. }
  59. }
  60. }
  61. public void OnDrawHandles()
  62. {
  63. if (Asset.Preferences.ShowToolPoints == false) return;
  64. var splineDataTarget = target as RiverModeler;
  65. if (ToolManager.IsActiveTool(this) || splineDataTarget.splineContainer == null)
  66. return;
  67. Color color = Color.green;
  68. color.a = 0.5f;
  69. Handles.color = color;
  70. m_DisableHandles = true;
  71. var splines = splineDataTarget.splineContainer.Splines;
  72. for (var i = 0; i < splines.Count; i++)
  73. {
  74. if (i < splineDataTarget.ScaleData.Count)
  75. {
  76. var nativeSpline = new NativeSpline(splines[i], splineDataTarget.splineContainer.transform.localToWorldMatrix);
  77. DrawDataPoints(nativeSpline, splineDataTarget.ScaleData[i]);
  78. }
  79. }
  80. }
  81. protected override bool DrawDataPoint(Vector3 position, Vector3 tangent, Vector3 up, float3 inValue, out float3 outValue)
  82. {
  83. int id = m_DisableHandles ? -1 : GUIUtility.GetControlID(FocusType.Passive);
  84. int id2 = m_DisableHandles ? -1 : GUIUtility.GetControlID(FocusType.Passive);
  85. outValue = inValue;
  86. if (tangent == Vector3.zero)
  87. return false;
  88. if (Event.current.type == EventType.MouseUp
  89. && Event.current.button != 0
  90. && (GUIUtility.hotControl == id || GUIUtility.hotControl == id2))
  91. {
  92. Event.current.Use();
  93. return false;
  94. }
  95. var handleColor = Handles.color;
  96. if ((GUIUtility.hotControl == id || GUIUtility.hotControl == id2))
  97. handleColor = Handles.selectedColor;
  98. else if (GUIUtility.hotControl == 0 && (HandleUtility.nearestControl == id || HandleUtility.nearestControl == id2))
  99. handleColor = Handles.preselectionColor;
  100. var splineDataTarget = target as RiverModeler;
  101. float riverWidth = splineDataTarget.settings.shape.width * 0.5f;
  102. up = math.up();
  103. Vector3 right = math.normalize(math.cross(tangent, up));
  104. float handleScale = HandleUtility.GetHandleSize(position);
  105. Vector3 x = position + (right * inValue.x * riverWidth);
  106. Vector3 y = position + (up * inValue.y * handleScale);
  107. Vector3 width, height;
  108. using (new Handles.DrawingScope(handleColor))
  109. {
  110. Handles.color = Color.red;;
  111. if (Event.current.type == EventType.Repaint)
  112. {
  113. Handles.DrawAAPolyLine(Texture2D.whiteTexture, 3f, new []{position, x});
  114. }
  115. width = Handles.Slider(id, x, right, k_HandleSize * handleScale, CustomHandleCap, 0);
  116. Handles.color = Color.green;
  117. if (Event.current.type == EventType.Repaint)
  118. {
  119. Handles.DrawAAPolyLine(Texture2D.whiteTexture, 3f, new []{position, y});
  120. }
  121. height = Handles.Slider(id2, y, up, k_HandleSize * handleScale, CustomHandleCap, 0);
  122. }
  123. if (GUIUtility.hotControl == id && math.abs(width.x - x.x) > 0f)
  124. {
  125. outValue.x = math.distance(width, position) / riverWidth;
  126. return true;
  127. }
  128. if (GUIUtility.hotControl == id2 && math.abs(height.y - y.y) > 0f)
  129. {
  130. outValue.y = math.distance(height, position) / handleScale;
  131. return true;
  132. }
  133. return false;
  134. }
  135. public void CustomHandleCap(int controlID, Vector3 position, Quaternion rotation, float size, EventType eventType)
  136. {
  137. if (m_DisableHandles) // If disabled, do nothing unless it's a repaint event
  138. {
  139. if (Event.current.type == EventType.Repaint)
  140. Handles.CubeHandleCap(controlID, position, rotation, size, eventType);
  141. }
  142. else
  143. Handles.CubeHandleCap(controlID, position, rotation, size, eventType);
  144. }
  145. }
  146. #endif
  147. }