//------------------------------------------------------
        // Get Animation Data
        //------------------------------------------------------

        // Perform Bezier interpolation between the key frames
        private float bezierInterpolation(KeyFrame previous_frame, KeyFrame next_frame, float current_time)
        {
            BezierCurveCubic temp_bezier = new BezierCurveCubic();

            temp_bezier.StartAnchor        = new Vector2(previous_frame.time, previous_frame.data);
            temp_bezier.FirstControlPoint  = previous_frame.bezier_values.Zw;
            temp_bezier.SecondControlPoint = next_frame.bezier_values.Xy;
            temp_bezier.EndAnchor          = new Vector2(next_frame.time, next_frame.data);

            return(temp_bezier.CalculatePoint(current_time).Y);
        }
Exemple #2
0
        public static TweenFunc <float> CubicBezier(float mx1, float my1, float mx2, float my2)
        {
            var curve = new BezierCurveCubic(
                new Vector2(0f, 0f),
                new Vector2(1f, 1f),
                new Vector2(mx1, my1),
                new Vector2(mx2, my2)
                );

            return((from, to, t) => {
                return from + (to - from) * curve.CalculatePoint(t).Y;
            });
        }
Exemple #3
0
        public static List <Vector2> nsvg__pathArcTo(Vector2d start, ArcTo a2)
        {
            List <Vector2> ret = new List <Vector2>();
            Vector2d       end = start;
            // Ported from canvg (https://code.google.com/p/canvg/)
            double rx, ry, rotx;
            double x1, y1, x2, y2, cx, cy, dx, dy, d;
            double x1p, y1p, cxp, cyp, s, sa, sb;
            double ux, uy, vx, vy, a1, da;
            double x, y, tanx, tany, a, px = 0, py = 0, ptanx = 0, ptany = 0;

            double[] t = new double[6];
            double   sinrx, cosrx;
            bool     fa, fs;
            int      ndivs;
            double   hda, kappa;

            rx   = Math.Abs(a2.Radius.Width);
            ry   = Math.Abs(a2.Radius.Height);
            rotx = a2.xrotation / 180.0f * Math.PI;      // x rotation engle
            fa   = a2.LargeArc;
            fs   = a2.SweepClockwise;
            x1   = start.X;                        // start point
            y1   = start.Y;

            x2 = a2.EndPoint.X;
            y2 = a2.EndPoint.Y;

            dx = x1 - x2;
            dy = y1 - y2;
            d  = Math.Sqrt(dx * dx + dy * dy);
            if (d < 1e-6f || rx < 1e-6f || ry < 1e-6f)
            {
                // The arc degenerates to a line
                //nsvg__lineTo(p, x2, y2);
                end.X = x2;
                end.Y = y2;
                ret.Add((Vector2)end);
                return(ret);
            }

            sinrx = Math.Sin(rotx);
            cosrx = Math.Cos(rotx);

            // Convert to center point parameterization.
            // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
            // 1) Compute x1', y1'
            x1p = cosrx * dx / 2.0f + sinrx * dy / 2.0f;
            y1p = -sinrx * dx / 2.0f + cosrx * dy / 2.0f;
            d   = sqr(x1p) / sqr(rx) + sqr(y1p) / sqr(ry);
            if (d > 1)
            {
                d   = Math.Sqrt(d);
                rx *= d;
                ry *= d;
            }
            // 2) Compute cx', cy'
            s  = 0.0f;
            sa = sqr(rx) * sqr(ry) - sqr(rx) * sqr(y1p) - sqr(ry) * sqr(x1p);
            sb = sqr(rx) * sqr(y1p) + sqr(ry) * sqr(x1p);
            if (sa < 0.0f)
            {
                sa = 0.0f;
            }
            if (sb > 0.0f)
            {
                s = Math.Sqrt(sa / sb);
            }
            if (fa == fs)
            {
                s = -s;
            }
            cxp = s * rx * y1p / ry;
            cyp = s * -ry * x1p / rx;

            // 3) Compute cx,cy from cx',cy'
            cx = (x1 + x2) / 2.0f + cosrx * cxp - sinrx * cyp;
            cy = (y1 + y2) / 2.0f + sinrx * cxp + cosrx * cyp;

            // 4) Calculate theta1, and delta theta.
            ux = (x1p - cxp) / rx;
            uy = (y1p - cyp) / ry;
            vx = (-x1p - cxp) / rx;
            vy = (-y1p - cyp) / ry;
            a1 = nsvg__vecang(1.0, 0.0, ux, uy);  // Initial angle
            da = nsvg__vecang(ux, uy, vx, vy);    // Delta angle

            //      if (nsvg__vecrat(ux,uy,vx,vy) <= -1.0f) da = Math.PI;
            //      if (nsvg__vecrat(ux,uy,vx,vy) >= 1.0f) da = 0;

            if (fa)
            {
                // Choose large arc
                if (da > 0.0f)
                {
                    da = da - 2 * Math.PI;
                }
                else
                {
                    da = 2 * Math.PI + da;
                }
            }

            // Approximate the arc using cubic spline segments.
            t[0] = cosrx;
            t[1] = sinrx;
            t[2] = -sinrx;
            t[3] = cosrx;
            t[4] = cx;
            t[5] = cy;

            // Split arc into max 90 degree segments.
            // The loop assumes an iteration per end point (including start and end), this +1.
            ndivs = (int)(Math.Abs(da) / (Math.PI * 0.5f) + 1.0f);
            hda   = (da / (double)ndivs) / 2.0f;
            kappa = Math.Abs(4.0f / 3.0f * (1.0f - Math.Cos(hda)) / Math.Sin(hda));
            if (da < 0.0f)
            {
                kappa = -kappa;
            }

            var last = (Vector2)start;

            for (int i = 0; i <= ndivs; i++)
            {
                a  = a1 + da * (i / (double)ndivs);
                dx = Math.Cos(a);
                dy = Math.Sin(a);
                nsvg__xformPoint(out x, out y, dx * rx, dy * ry, t);                      // position
                nsvg__xformVec(out tanx, out tany, -dy * rx * kappa, dx * ry * kappa, t); // tangent
                if (i > 0)
                {
                    BezierCurveCubic b = new BezierCurveCubic((Vector2)last, new Vector2((float)x, (float)y),
                                                              (Vector2) new Vector2d(px + ptanx, py + ptany),
                                                              (Vector2) new Vector2d(x - tanx, y - tany));
                    Vector2 old = b.CalculatePoint(0f);
                    ret.Add(old);
                    var precision = 0.05f;
                    for (float p = precision; p < 1f + precision; p += precision)
                    {
                        Vector2 j = b.CalculatePoint(p);
                        ret.Add(j);
                    }
                    last = b.CalculatePoint(1.0f);
                }
                px    = x;
                py    = y;
                ptanx = tanx;
                ptany = tany;
            }

            end.X = x2;
            end.Y = y2;
            ret.Add((Vector2)end);
            return(ret);
        }
Exemple #4
0
        public void DrawPath(Path path, VBO vbo)
        {
            List <List <Vector2> > shapes     = new List <List <Vector2> >();
            List <Vector2>         positions  = new List <Vector2>();
            List <Vector2>         tesselated = new List <Vector2>();
            Point position = new Point();

            foreach (var op in path.Operations)
            {
                var mt = op as MoveTo;
                if (mt != null)
                {
                    shapes.Add(positions);
                    positions = new List <Vector2>();

                    positions.Add(Vec2(mt.Point));
                    position = mt.Point;
                    continue;
                }
                var lt = op as LineTo;
                if (lt != null)
                {
                    positions.Add(Vec2(lt.Point));
                    position = lt.Point;
                    continue;
                }
                var at = op as ArcTo;
                if (at != null)
                {
                    var p = nsvg.nsvg__pathArcTo((Vector2d)Vec2(position), at);
                    positions.AddRange(p);
                    position = at.Point;
                    continue;
                }
                var ct = op as CurveTo;
                if (ct != null)
                {
                    if (double.IsNaN(ct.Control1.X) && double.IsNaN(ct.Control1.Y))
                    {
                        BezierCurveQuadric b = new BezierCurveQuadric(Vec2(position), Vec2(ct.EndPoint),
                                                                      Vec2(ct.Control2));
                        Vector2 old = b.CalculatePoint(0f);
                        positions.Add(old);
                        var precision = 0.05f;
                        for (float i = precision; i < 1f + precision; i += precision)
                        {
                            Vector2 j = b.CalculatePoint(i);
                            positions.Add(j);
                            old = j;
                        }
                    }
                    else
                    {
                        BezierCurveCubic b = new BezierCurveCubic(Vec2(position), Vec2(ct.EndPoint), Vec2(ct.Control1),
                                                                  Vec2(ct.Control2));
                        Vector2 old = b.CalculatePoint(0f);
                        positions.Add(old);
                        var precision = 0.05f;
                        for (float i = precision; i < 1f + precision; i += precision)
                        {
                            Vector2 j = b.CalculatePoint(i);
                            positions.Add(j);
                        }
                    }
                    position = ct.EndPoint;
                }
                var cp = op as ClosePath;
                if (cp != null)
                {
                    if (positions.Count > 0)
                    {
                        positions.Add(positions[0]);
                        shapes.Add(positions);
                    }
                    positions = new List <Vector2>();
                    position  = new Point();
                    continue;
                }
            }
            shapes.Add(positions);

            brushcheck(path.Brush);
            LibTessDotNet.Tess t        = new LibTessDotNet.Tess();
            List <Vec3>        vertices = new List <Vec3>();

            foreach (var s in shapes)
            {
                ContourVertex[] cv = new ContourVertex[s.Count];
                for (int i = 0; i < s.Count; i++)
                {
                    var v = s[i];
                    cv[i] = new ContourVertex()
                    {
                        Position = new Vec3()
                        {
                            X = v.X, Y = v.Y
                        }
                    };
                }
                t.AddContour(cv);
            }
            var rule = LibTessDotNet.WindingRule.NonZero;

            if (path.Brush != null)
            {
                rule = path.Brush.FillMode == FillMode.EvenOdd ? LibTessDotNet.WindingRule.EvenOdd : LibTessDotNet.WindingRule.NonZero;
            }
            t.Tessellate(rule, LibTessDotNet.ElementType.Polygons, 3);
            for (var i = 0; i < t.ElementCount; i++)
            {
                for (var tri = 0; tri < 3; tri++)
                {
                    vertices.Add(t.Vertices[t.Elements[(i * 3) + tri]].Position);
                }
            }
            for (int i = 0; i < vertices.Count; i++)
            {
                tesselated.Add(new Vector2(vertices[i].X, vertices[i].Y));
            }
            var lineshapes = new List <List <Vector2> >();

            foreach (var s in shapes)
            {
                if (s.Count == 0)
                {
                    continue;
                }
                List <Vector2> add = new List <Vector2>();
                for (int i = 0; i < s.Count; i++)
                {
                    add.Add(new Vector2(s[i].X, s[i].Y));
                }
                lineshapes.Add(add);
            }

            if (path.Brush is SolidBrush || path.Pen != null)
            {
                if (path.Brush is SolidBrush)
                {
                    var sb = path.Brush as SolidBrush;
                    for (int i = 0; i < tesselated.Count; i++)
                    {
                        vbo.AddVertex(new Vertex(tesselated[i], color(sb.Color)));
                    }
                }
                if (path.Pen != null)
                {
                    foreach (var list in lineshapes)
                    {
                        foreach (var v in TesselateLines(list, path.Pen))
                        {
                            vbo.AddVertex(v);
                        }
                    }
                }
            }
        }