|
@@ -10,7 +10,10 @@ namespace BansheeEditor
|
|
|
* @{
|
|
* @{
|
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
- // TODO DOC
|
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Draws one or multiple curves over the specified physical area. User can specify horizontal and vertical range to
|
|
|
|
|
+ /// display, as well as physical size of the GUI area.
|
|
|
|
|
+ /// </summary>
|
|
|
internal class GUICurveDrawing
|
|
internal class GUICurveDrawing
|
|
|
{
|
|
{
|
|
|
private const int LINE_SPLIT_WIDTH = 2;
|
|
private const int LINE_SPLIT_WIDTH = 2;
|
|
@@ -27,20 +30,31 @@ namespace BansheeEditor
|
|
|
|
|
|
|
|
private int drawableWidth;
|
|
private int drawableWidth;
|
|
|
private GUICanvas canvas;
|
|
private GUICanvas canvas;
|
|
|
- private GUITicks tickHandler;
|
|
|
|
|
-
|
|
|
|
|
|
|
+ private GUIGraphTicks tickHandler;
|
|
|
|
|
+
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Creates a new curve drawing GUI element.
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ /// <param name="layout">Layout into which to add the GUI element.</param>
|
|
|
|
|
+ /// <param name="width">Width of the element in pixels.</param>
|
|
|
|
|
+ /// <param name="height">Height of the element in pixels.</param>
|
|
|
|
|
+ /// <param name="curves">Initial set of curves to display. </param>
|
|
|
public GUICurveDrawing(GUILayout layout, int width, int height, EdAnimationCurve[] curves)
|
|
public GUICurveDrawing(GUILayout layout, int width, int height, EdAnimationCurve[] curves)
|
|
|
{
|
|
{
|
|
|
canvas = new GUICanvas();
|
|
canvas = new GUICanvas();
|
|
|
layout.AddElement(canvas);
|
|
layout.AddElement(canvas);
|
|
|
|
|
|
|
|
- tickHandler = new GUITicks(GUITickStepType.Time);
|
|
|
|
|
|
|
+ tickHandler = new GUIGraphTicks(GUITickStepType.Time);
|
|
|
|
|
|
|
|
this.curves = curves;
|
|
this.curves = curves;
|
|
|
|
|
|
|
|
SetSize(width, height);
|
|
SetSize(width, height);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Change the set of curves to display.
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ /// <param name="curves">New set of curves to draw on the GUI element.</param>
|
|
|
public void SetCurves(EdAnimationCurve[] curves)
|
|
public void SetCurves(EdAnimationCurve[] curves)
|
|
|
{
|
|
{
|
|
|
this.curves = curves;
|
|
this.curves = curves;
|
|
@@ -48,6 +62,11 @@ namespace BansheeEditor
|
|
|
Rebuild();
|
|
Rebuild();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Change the physical size of the GUI element.
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ /// <param name="width">Width of the element in pixels.</param>
|
|
|
|
|
+ /// <param name="height">Height of the element in pixels.</param>
|
|
|
public void SetSize(int width, int height)
|
|
public void SetSize(int width, int height)
|
|
|
{
|
|
{
|
|
|
this.width = width;
|
|
this.width = width;
|
|
@@ -56,13 +75,19 @@ namespace BansheeEditor
|
|
|
canvas.SetWidth(width);
|
|
canvas.SetWidth(width);
|
|
|
canvas.SetHeight(height);
|
|
canvas.SetHeight(height);
|
|
|
|
|
|
|
|
- drawableWidth = Math.Max(0, width - GUITimeline.PADDING * 2);
|
|
|
|
|
|
|
+ drawableWidth = Math.Max(0, width - GUIGraphTime.PADDING * 2);
|
|
|
|
|
|
|
|
tickHandler.SetRange(0.0f, xRange, drawableWidth);
|
|
tickHandler.SetRange(0.0f, xRange, drawableWidth);
|
|
|
|
|
|
|
|
Rebuild();
|
|
Rebuild();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Changes the visible range that the GUI element displays.
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ /// <param name="xRange">Range of the horizontal area. Displayed area will range from [0, xRange].</param>
|
|
|
|
|
+ /// <param name="yRange">Range of the vertical area. Displayed area will range from
|
|
|
|
|
+ /// [-yRange * 0.5, yRange * 0.5]</param>
|
|
|
public void SetRange(float xRange, float yRange)
|
|
public void SetRange(float xRange, float yRange)
|
|
|
{
|
|
{
|
|
|
this.xRange = xRange;
|
|
this.xRange = xRange;
|
|
@@ -73,6 +98,10 @@ namespace BansheeEditor
|
|
|
Rebuild();
|
|
Rebuild();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Number of frames per second, used for frame selection and marking.
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ /// <param name="fps">Number of prames per second.</param>
|
|
|
public void SetFPS(int fps)
|
|
public void SetFPS(int fps)
|
|
|
{
|
|
{
|
|
|
this.fps = Math.Max(1, fps);
|
|
this.fps = Math.Max(1, fps);
|
|
@@ -82,7 +111,10 @@ namespace BansheeEditor
|
|
|
Rebuild();
|
|
Rebuild();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Set to -1 to clear it
|
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Sets the frame at which to display the frame marker.
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ /// <param name="frameIdx">Index of the frame to display the marker on, or -1 to clear the marker.</param>
|
|
|
public void SetMarkedFrame(int frameIdx)
|
|
public void SetMarkedFrame(int frameIdx)
|
|
|
{
|
|
{
|
|
|
markedFrameIdx = frameIdx;
|
|
markedFrameIdx = frameIdx;
|
|
@@ -90,18 +122,25 @@ namespace BansheeEditor
|
|
|
Rebuild();
|
|
Rebuild();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Calculates the curve coordinates that are under the provided window coordinates.
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ /// <param name="windowCoords">Coordinate relative to the window the GUI element is on.</param>
|
|
|
|
|
+ /// <param name="curveCoords">Curve coordinates within the range as specified by <see cref="SetRange"/>. Only
|
|
|
|
|
+ /// Valid when function returns true.</param>
|
|
|
|
|
+ /// <returns>True if the window coordinates were within the curve area, false otherwise.</returns>
|
|
|
public bool GetCurveCoordinates(Vector2I windowCoords, out Vector2 curveCoords)
|
|
public bool GetCurveCoordinates(Vector2I windowCoords, out Vector2 curveCoords)
|
|
|
{
|
|
{
|
|
|
Rect2I bounds = canvas.Bounds;
|
|
Rect2I bounds = canvas.Bounds;
|
|
|
|
|
|
|
|
- if (windowCoords.x < (bounds.x + GUITimeline.PADDING) || windowCoords.x >= (bounds.x + bounds.width - GUITimeline.PADDING) ||
|
|
|
|
|
|
|
+ if (windowCoords.x < (bounds.x + GUIGraphTime.PADDING) || windowCoords.x >= (bounds.x + bounds.width - GUIGraphTime.PADDING) ||
|
|
|
windowCoords.y < bounds.y || windowCoords.y >= (bounds.y + bounds.height))
|
|
windowCoords.y < bounds.y || windowCoords.y >= (bounds.y + bounds.height))
|
|
|
{
|
|
{
|
|
|
curveCoords = new Vector2();
|
|
curveCoords = new Vector2();
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- Vector2I relativeCoords = windowCoords - new Vector2I(bounds.x + GUITimeline.PADDING, bounds.y);
|
|
|
|
|
|
|
+ Vector2I relativeCoords = windowCoords - new Vector2I(bounds.x + GUIGraphTime.PADDING, bounds.y);
|
|
|
|
|
|
|
|
float lengthPerPixel = xRange / drawableWidth;
|
|
float lengthPerPixel = xRange / drawableWidth;
|
|
|
float heightPerPixel = yRange / height;
|
|
float heightPerPixel = yRange / height;
|
|
@@ -115,9 +154,14 @@ namespace BansheeEditor
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Draws a vertical frame marker on the curve area.
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ /// <param name="t">Time at which to draw the marker.</param>
|
|
|
|
|
+ /// <param name="color">Color with which to draw the marker.</param>
|
|
|
private void DrawFrameMarker(float t, Color color)
|
|
private void DrawFrameMarker(float t, Color color)
|
|
|
{
|
|
{
|
|
|
- int xPos = (int)((t / GetRange()) * drawableWidth) + GUITimeline.PADDING;
|
|
|
|
|
|
|
+ int xPos = (int)((t / GetRange()) * drawableWidth) + GUIGraphTime.PADDING;
|
|
|
|
|
|
|
|
Vector2I start = new Vector2I(xPos, 0);
|
|
Vector2I start = new Vector2I(xPos, 0);
|
|
|
Vector2I end = new Vector2I(xPos, height);
|
|
Vector2I end = new Vector2I(xPos, height);
|
|
@@ -125,6 +169,9 @@ namespace BansheeEditor
|
|
|
canvas.DrawLine(start, end, color);
|
|
canvas.DrawLine(start, end, color);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Draws a horizontal line representing the line at y = 0.
|
|
|
|
|
+ /// </summary>
|
|
|
private void DrawCenterLine()
|
|
private void DrawCenterLine()
|
|
|
{
|
|
{
|
|
|
int heightOffset = height / 2; // So that y = 0 is at center of canvas
|
|
int heightOffset = height / 2; // So that y = 0 is at center of canvas
|
|
@@ -135,7 +182,10 @@ namespace BansheeEditor
|
|
|
canvas.DrawLine(start, end, COLOR_DARK_GRAY);
|
|
canvas.DrawLine(start, end, COLOR_DARK_GRAY);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Returns range rounded to the nearest multiple of FPS
|
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Returns the range of times displayed by the timeline rounded to the multiple of FPS.
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ /// <returns>Time range rounded to a multiple of FPS.</returns>
|
|
|
private float GetRange()
|
|
private float GetRange()
|
|
|
{
|
|
{
|
|
|
float spf = 1.0f / fps;
|
|
float spf = 1.0f / fps;
|
|
@@ -143,6 +193,9 @@ namespace BansheeEditor
|
|
|
return ((int)xRange / spf) * spf;
|
|
return ((int)xRange / spf) * spf;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Rebuilds the internal GUI elements. Should be called whenever timeline properties change.
|
|
|
|
|
+ /// </summary>
|
|
|
private void Rebuild()
|
|
private void Rebuild()
|
|
|
{
|
|
{
|
|
|
canvas.Clear();
|
|
canvas.Clear();
|
|
@@ -160,7 +213,7 @@ namespace BansheeEditor
|
|
|
for (int j = 0; j < ticks.Length; j++)
|
|
for (int j = 0; j < ticks.Length; j++)
|
|
|
{
|
|
{
|
|
|
Color color = COLOR_DARK_GRAY;
|
|
Color color = COLOR_DARK_GRAY;
|
|
|
- color.a *= MathEx.Clamp01(strength);
|
|
|
|
|
|
|
+ color.a *= strength;
|
|
|
|
|
|
|
|
DrawFrameMarker(ticks[j], color);
|
|
DrawFrameMarker(ticks[j], color);
|
|
|
}
|
|
}
|
|
@@ -189,6 +242,12 @@ namespace BansheeEditor
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Generates a unique color based on the provided index.
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ /// <param name="idx">Index to use for generating a color. Should be less than 30 in order to guarantee reasonably
|
|
|
|
|
+ /// different colors.</param>
|
|
|
|
|
+ /// <returns>Unique color.</returns>
|
|
|
private Color GetUniqueColor(int idx)
|
|
private Color GetUniqueColor(int idx)
|
|
|
{
|
|
{
|
|
|
const int COLOR_SPACING = 359 / 15;
|
|
const int COLOR_SPACING = 359 / 15;
|
|
@@ -197,6 +256,11 @@ namespace BansheeEditor
|
|
|
return Color.HSV2RGB(new Color(hue, 175.0f / 255.0f, 175.0f / 255.0f));
|
|
return Color.HSV2RGB(new Color(hue, 175.0f / 255.0f, 175.0f / 255.0f));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Draws the curve using the provided color.
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ /// <param name="curve">Curve to draw within the currently set range. </param>
|
|
|
|
|
+ /// <param name="color">Color to draw the curve with.</param>
|
|
|
private void DrawCurve(EdAnimationCurve curve, Color color)
|
|
private void DrawCurve(EdAnimationCurve curve, Color color)
|
|
|
{
|
|
{
|
|
|
float lengthPerPixel = xRange/drawableWidth;
|
|
float lengthPerPixel = xRange/drawableWidth;
|
|
@@ -214,7 +278,7 @@ namespace BansheeEditor
|
|
|
int startPixel = (int)(start / lengthPerPixel);
|
|
int startPixel = (int)(start / lengthPerPixel);
|
|
|
|
|
|
|
|
int xPosStart = 0;
|
|
int xPosStart = 0;
|
|
|
- int xPosEnd = GUITimeline.PADDING + startPixel;
|
|
|
|
|
|
|
+ int xPosEnd = GUIGraphTime.PADDING + startPixel;
|
|
|
|
|
|
|
|
int yPos = (int)(curve.Native.Evaluate(0.0f, false) * pixelsPerHeight);
|
|
int yPos = (int)(curve.Native.Evaluate(0.0f, false) * pixelsPerHeight);
|
|
|
yPos = heightOffset - yPos; // Offset and flip height (canvas Y goes down)
|
|
yPos = heightOffset - yPos; // Offset and flip height (canvas Y goes down)
|
|
@@ -247,16 +311,16 @@ namespace BansheeEditor
|
|
|
int yPosStart = (int)(curve.Native.Evaluate(start, false) * pixelsPerHeight);
|
|
int yPosStart = (int)(curve.Native.Evaluate(start, false) * pixelsPerHeight);
|
|
|
yPosStart = heightOffset - yPosStart; // Offset and flip height (canvas Y goes down)
|
|
yPosStart = heightOffset - yPosStart; // Offset and flip height (canvas Y goes down)
|
|
|
|
|
|
|
|
- linePoints.Add(new Vector2I(GUITimeline.PADDING + xPos, yPosStart));
|
|
|
|
|
|
|
+ linePoints.Add(new Vector2I(GUIGraphTime.PADDING + xPos, yPosStart));
|
|
|
|
|
|
|
|
xPos = endPixel;
|
|
xPos = endPixel;
|
|
|
- linePoints.Add(new Vector2I(GUITimeline.PADDING + xPos, yPosStart));
|
|
|
|
|
|
|
+ linePoints.Add(new Vector2I(GUIGraphTime.PADDING + xPos, yPosStart));
|
|
|
|
|
|
|
|
// Line representing the step
|
|
// Line representing the step
|
|
|
int yPosEnd = (int)(curve.Native.Evaluate(end, false) * pixelsPerHeight);
|
|
int yPosEnd = (int)(curve.Native.Evaluate(end, false) * pixelsPerHeight);
|
|
|
yPosEnd = heightOffset - yPosEnd; // Offset and flip height (canvas Y goes down)
|
|
yPosEnd = heightOffset - yPosEnd; // Offset and flip height (canvas Y goes down)
|
|
|
|
|
|
|
|
- linePoints.Add(new Vector2I(GUITimeline.PADDING + xPos, yPosEnd));
|
|
|
|
|
|
|
+ linePoints.Add(new Vector2I(GUIGraphTime.PADDING + xPos, yPosEnd));
|
|
|
}
|
|
}
|
|
|
else // Draw normally
|
|
else // Draw normally
|
|
|
{
|
|
{
|
|
@@ -288,7 +352,7 @@ namespace BansheeEditor
|
|
|
int yPos = (int)(curve.Native.Evaluate(t, false) * pixelsPerHeight);
|
|
int yPos = (int)(curve.Native.Evaluate(t, false) * pixelsPerHeight);
|
|
|
yPos = heightOffset - yPos; // Offset and flip height (canvas Y goes down)
|
|
yPos = heightOffset - yPos; // Offset and flip height (canvas Y goes down)
|
|
|
|
|
|
|
|
- linePoints.Add(new Vector2I(GUITimeline.PADDING + xPos, yPos));
|
|
|
|
|
|
|
+ linePoints.Add(new Vector2I(GUIGraphTime.PADDING + xPos, yPos));
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -300,7 +364,7 @@ namespace BansheeEditor
|
|
|
float end = MathEx.Clamp(keyframes[keyframes.Length - 1].time, 0.0f, xRange);
|
|
float end = MathEx.Clamp(keyframes[keyframes.Length - 1].time, 0.0f, xRange);
|
|
|
int endPixel = (int)(end / lengthPerPixel);
|
|
int endPixel = (int)(end / lengthPerPixel);
|
|
|
|
|
|
|
|
- int xPosStart = GUITimeline.PADDING + endPixel;
|
|
|
|
|
|
|
+ int xPosStart = GUIGraphTime.PADDING + endPixel;
|
|
|
int xPosEnd = width;
|
|
int xPosEnd = width;
|
|
|
|
|
|
|
|
int yPos = (int)(curve.Native.Evaluate(xRange, false) * pixelsPerHeight);
|
|
int yPos = (int)(curve.Native.Evaluate(xRange, false) * pixelsPerHeight);
|