Пример #1
0
        /// <summary>
        /// Attempts to find a curve under the provided coordinates.
        /// </summary>
        /// <param name="pixelCoords">Coordinates relative to this GUI element in pixels.</param>
        /// <returns>Index of the curve, or -1 if none found.</returns>
        public int FindCurve(Vector2I pixelCoords)
        {
            PixelToCurveSpace(pixelCoords, out var curveCoords, true);

            float time = curveCoords.x;

            float nearestDistance = float.MaxValue;
            int   curveIdx        = -1;

            for (int i = 0; i < curveInfos.Length; i++)
            {
                EdAnimationCurve curve = curveInfos[i].curve;

                float    value       = curve.Evaluate(time, false);
                Vector2I curPixelPos = CurveToPixelSpace(new Vector2(time, value));

                float distanceToKey = Vector2I.Distance(pixelCoords, curPixelPos);
                if (distanceToKey < nearestDistance)
                {
                    nearestDistance = distanceToKey;
                    curveIdx        = i;
                }
            }

            // We're not near any curve
            if (nearestDistance > 5.0f)
            {
                return(-1);
            }

            return(curveIdx);
        }
Пример #2
0
        /// <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)
        {
            float range          = GetRange(true);
            float lengthPerPixel = range / drawableWidth;

            KeyFrame[] keyframes = curve.KeyFrames;
            if (keyframes.Length <= 0)
            {
                return;
            }

            // Draw start line
            {
                float curveStart = keyframes[0].time;
                float curveValue = curve.Evaluate(curveStart, false);

                Vector2I end   = CurveToPixelSpace(new Vector2(curveStart, curveValue));
                Vector2I start = new Vector2I(-GUIGraphTime.PADDING, end.y);

                if (start.x < end.x)
                {
                    canvas.DrawLine(start, end, COLOR_MID_GRAY);
                }
            }

            List <Vector2I> linePoints = new List <Vector2I>();

            // Draw in between keyframes
            float startVisibleTime = rangeOffset;
            float endVisibleTime   = startVisibleTime + range;

            for (int i = 0; i < keyframes.Length - 1; i++)
            {
                float start = keyframes[i].time;
                float end   = keyframes[i + 1].time;

                if (end < startVisibleTime || start > endVisibleTime)
                {
                    continue;
                }

                bool isStep = keyframes[i].outTangent == float.PositiveInfinity ||
                              keyframes[i + 1].inTangent == float.PositiveInfinity;

                // If step tangent, draw the required lines without sampling, as the sampling will miss the step
                if (isStep)
                {
                    float startValue = curve.Evaluate(start, false);
                    float endValue   = curve.Evaluate(end, false);

                    linePoints.Add(CurveToPixelSpace(new Vector2(start, startValue)));
                    linePoints.Add(CurveToPixelSpace(new Vector2(end, startValue)));
                    linePoints.Add(CurveToPixelSpace(new Vector2(end, endValue)));
                }
                else // Draw normally
                {
                    float splitIncrement = LINE_SPLIT_WIDTH * lengthPerPixel;

                    float startValue = keyframes[i].value;
                    float endValue   = keyframes[i + 1].value;

                    Vector2I startPixel = new Vector2I();
                    startPixel.x = (int)(start / lengthPerPixel);
                    startPixel.y = (int)(startValue / lengthPerPixel);

                    Vector2I endPixel = new Vector2I();
                    endPixel.x = (int)(end / lengthPerPixel);
                    endPixel.y = (int)(endValue / lengthPerPixel);

                    int distance = Vector2I.Distance(startPixel, endPixel);

                    int numSplits;
                    if (distance > 0)
                    {
                        float fNumSplits = distance / splitIncrement;

                        numSplits      = MathEx.CeilToInt(fNumSplits);
                        splitIncrement = distance / (float)numSplits;
                    }
                    else
                    {
                        numSplits      = 1;
                        splitIncrement = 0.0f;
                    }

                    for (int j = 0; j < numSplits; j++)
                    {
                        float t     = Math.Min(start + j * splitIncrement, end);
                        float value = curve.Evaluate(t, false);

                        linePoints.Add(CurveToPixelSpace(new Vector2(t, value)));
                    }
                }
            }

            canvas.DrawPolyLine(linePoints.ToArray(), color);

            // Draw end line
            {
                float curveEnd   = keyframes[keyframes.Length - 1].time;
                float curveValue = curve.Evaluate(curveEnd, false);

                Vector2I start = CurveToPixelSpace(new Vector2(curveEnd, curveValue));
                Vector2I end   = new Vector2I(width, start.y);

                if (start.x < end.x)
                {
                    canvas.DrawLine(start, end, COLOR_MID_GRAY);
                }
            }
        }
Пример #3
0
        /// <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)
        {
            float range          = GetRange();
            float lengthPerPixel = range / drawableWidth;

            KeyFrame[] keyframes = curve.KeyFrames;
            if (keyframes.Length <= 0)
            {
                return;
            }

            // Draw start line
            {
                float curveStart = MathEx.Clamp(keyframes[0].time, 0.0f, range);
                float curveValue = curve.Evaluate(0.0f, false);

                Vector2I start = CurveToPixelSpace(new Vector2(0.0f, curveValue));
                start.x -= GUIGraphTime.PADDING;

                Vector2I end = CurveToPixelSpace(new Vector2(curveStart, curveValue));

                canvas.DrawLine(start, end, COLOR_MID_GRAY);
            }

            List <Vector2I> linePoints = new List <Vector2I>();

            // Draw in between keyframes
            for (int i = 0; i < keyframes.Length - 1; i++)
            {
                float start = MathEx.Clamp(keyframes[i].time, 0.0f, range);
                float end   = MathEx.Clamp(keyframes[i + 1].time, 0.0f, range);

                bool isStep = keyframes[i].outTangent == float.PositiveInfinity ||
                              keyframes[i + 1].inTangent == float.PositiveInfinity;

                // If step tangent, draw the required lines without sampling, as the sampling will miss the step
                if (isStep)
                {
                    float startValue = curve.Evaluate(start, false);
                    float endValue   = curve.Evaluate(end, false);

                    linePoints.Add(CurveToPixelSpace(new Vector2(start, startValue)));
                    linePoints.Add(CurveToPixelSpace(new Vector2(end, startValue)));
                    linePoints.Add(CurveToPixelSpace(new Vector2(end, endValue)));
                }
                else // Draw normally
                {
                    float timeIncrement = LINE_SPLIT_WIDTH * lengthPerPixel;

                    int startPixel = (int)(start / lengthPerPixel);
                    int endPixel   = (int)(end / lengthPerPixel);

                    int numSplits;
                    if (startPixel != endPixel)
                    {
                        float fNumSplits = (end - start) / timeIncrement;

                        numSplits = MathEx.FloorToInt(fNumSplits);
                        float remainder = fNumSplits - numSplits;

                        float lengthRounded = (end - start) * (numSplits / fNumSplits);
                        timeIncrement = lengthRounded / numSplits;

                        numSplits += MathEx.CeilToInt(remainder) + 1;
                    }
                    else
                    {
                        numSplits     = 1;
                        timeIncrement = 0.0f;
                    }

                    for (int j = 0; j < numSplits; j++)
                    {
                        float t     = Math.Min(start + j * timeIncrement, end);
                        float value = curve.Evaluate(t, false);

                        linePoints.Add(CurveToPixelSpace(new Vector2(t, value)));
                    }
                }
            }

            canvas.DrawPolyLine(linePoints.ToArray(), color);

            // Draw end line
            {
                float curveEnd   = MathEx.Clamp(keyframes[keyframes.Length - 1].time, 0.0f, range);
                float curveValue = curve.Evaluate(range, false);

                Vector2I start = CurveToPixelSpace(new Vector2(curveEnd, curveValue));
                Vector2I end   = new Vector2I(width, start.y);

                canvas.DrawLine(start, end, COLOR_MID_GRAY);
            }
        }