Ejemplo n.º 1
0
        private static void FindBounds(
            out float outMin, out float outMax,
            float start, float startLeaveTan, float startT,
            float end, float endArriveTan, float endT,
            bool curve)
        {
            outMin = FMath.Min(start, end);
            outMax = FMath.Max(start, end);

            // Do we need to consider extermeties of a curve?
            if (curve)
            {
                // Scale tangents based on time interval, so this code matches the behaviour in FInterpCurve::Eval
                float diff = endT - startT;
                startLeaveTan *= diff;
                endArriveTan  *= diff;

                float a = 6.0f * start + 3.0f * startLeaveTan + 3.0f * endArriveTan - 6.0f * end;
                float b = -6.0f * start - 4.0f * startLeaveTan - 2.0f * endArriveTan + 6.0f * end;
                float c = startLeaveTan;

                float discriminant = (b * b) - (4.0f * a * c);
                if (discriminant > 0.0f && !FMath.IsNearlyZero(a)) // Solving doesn't work if a is zero, which usually indicates co-incident start and end, and zero tangents anyway
                {
                    float sqrtDisc = FMath.Sqrt(discriminant);

                    float x0 = (-b + sqrtDisc) / (2.0f * a);  // x0 is the 'Alpha' ie between 0 and 1
                    float t0 = startT + x0 * (endT - startT); // Then t0 is the actual 'time' on the curve
                    if (t0 > startT && t0 < endT)
                    {
                        float val = FMath.CubicInterp(start, startLeaveTan, end, endArriveTan, x0);

                        outMin = FMath.Min(outMin, val);
                        outMax = FMath.Max(outMax, val);
                    }

                    float x1 = (-b - sqrtDisc) / (2.0f * a);
                    float t1 = startT + x1 * (endT - startT);
                    if (t1 > startT && t1 < endT)
                    {
                        float val = FMath.CubicInterp(start, startLeaveTan, end, endArriveTan, x1);

                        outMin = FMath.Min(outMin, val);
                        outMax = FMath.Max(outMax, val);
                    }
                }
            }
        }