unsafe private void UpdatePointVertical(int py, int jstart, int xstart, int xend)
        {
            int stride = mesh.Stride / sizeof(DisplacementVector);

            CosineInterpolator top = new CosineInterpolator();
            CosineInterpolator bot = new CosineInterpolator();

            for (int i = 0; i < handlesx; ++i)
            {
                top.Add((i + points[i, jstart].X) * xspacing, points[i, jstart].Y * yspacing);
                bot.Add((i + points[i, jstart].X) * xspacing, points[i, jstart].Y * yspacing);
            }

            for (int j = py - 1; j < py + 1; ++j)
            {
                if (j >= -1 && j < height)
                {
                    bot = new CosineInterpolator();
                    for (int i = 0; i < handlesx; ++i)
                    {
                        bot.Add((i + points[i, j + 1].X) * xspacing, points[i, j + 1].Y * yspacing);
                    }
                }

                float jtoytop = j * yspacing;
                float jtoybot = (j + 1) * yspacing;

                for (int x = xstart; x < xend; ++x)
                {
                    float
                        topval    = -(float)(top.Interpolate(x)),
                        bottomval = -(float)(bot.Interpolate(x));

                    int y1 = (int)(jtoytop - topval);
                    int y2 = (int)(jtoybot - bottomval) + 1;

                    float ydif = y2 - y1;

                    if (y1 < 0)
                    {
                        y1 = 0;
                    }
                    if (y2 > mesh.Height)
                    {
                        y2 = mesh.Height;
                    }

                    DisplacementVector *ptr = mesh.GetPointAddressUnchecked(x, y1);

                    for (int y = y1; y < y2; ++y)
                    {
                        float
                            lerp = (y - y1) / ydif,
                            val  = lerp * bottomval + (1 - lerp) * topval;

                        ptr->Y = val;
                        ptr   += stride;
                    }
                }
                top = bot;
            }
        }
Exemple #2
0
        void canvas_CanvasPaint(object sender, PaintEventArgs e)
        {
            if (grid != null && gridvisible)
            {
                float xspacing     = canvas.ZoomFactor * (EffectSourceSurface.Width - 1) / (float)grid.Width;
                float yspacing     = canvas.ZoomFactor * (EffectSourceSurface.Height - 1) / (float)grid.Height;
                float handleradius = 3;

                e.Graphics.SmoothingMode = SmoothingMode.HighQuality;

                //draw horizontal guidelines
                for (int j = 0; j <= grid.Height; ++j)
                {
                    CosineInterpolator si = new CosineInterpolator();

                    for (int i = 0; i <= grid.Width; ++i)
                    {
                        si.Add(i + grid.GetPoint(i, j).X, j + grid.GetPoint(i, j).Y);
                    }

                    int linestart = Math.Max(
                        e.ClipRectangle.Left,
                        (int)(grid.GetPoint(0, j).X *xspacing));

                    int lineend = Math.Min(
                        e.ClipRectangle.Right + 1,
                        (int)((grid.Width + grid.GetPoint(grid.Width, j).X) * xspacing));

                    int len = lineend - linestart;
                    if (len > 1)
                    {
                        PointF[] line = new PointF[len];
                        for (int x = linestart; x < lineend; ++x)
                        {
                            line[x - linestart] = new PointF(x, (float)(si.Interpolate(x / xspacing) * yspacing + 1));
                        }
                        e.Graphics.DrawLines(gridPen, line);
                    }
                }

                //vertical guidelines
                for (int i = 0; i <= grid.Width; ++i)
                {
                    CosineInterpolator si = new CosineInterpolator();

                    for (int j = 0; j <= grid.Height; ++j)
                    {
                        si.Add(j + grid.GetPoint(i, j).Y, i + grid.GetPoint(i, j).X);
                    }

                    int linestart = Math.Max(
                        e.ClipRectangle.Top,
                        (int)(grid.GetPoint(i, 0).Y *yspacing));

                    int lineend = Math.Min(
                        e.ClipRectangle.Bottom + 1,
                        (int)((grid.Height + grid.GetPoint(i, grid.Height).Y) * yspacing));

                    int len = lineend - linestart;
                    if (len > 1)
                    {
                        PointF[] line = new PointF[len];
                        for (int y = linestart; y < lineend; ++y)
                        {
                            line[y - linestart] = new PointF((float)(si.Interpolate(y / yspacing) * xspacing + 1), y);
                        }
                        e.Graphics.DrawLines(gridPen, line);
                    }
                }

                //draw control handles and check if the mouse is hovering over one while we're at it
                hovering = tracking;
                for (int j = 0; j <= grid.Height; ++j)
                {
                    for (int i = 0; i <= grid.Width; ++i)
                    {
                        PointF point = new PointF(
                            (i + grid.GetPoint(i, j).X) * xspacing + 1,
                            (j + grid.GetPoint(i, j).Y) * yspacing + 1);

                        RectangleF dotdrawrect = new RectangleF(point.X - handleradius, point.Y - handleradius, 2 * handleradius, 2 * handleradius);
                        RectangleF hitrect     = RectangleF.Inflate(dotdrawrect, 5, 5);
                        if ((tracking.X == i && tracking.Y == j) ||
                            (tracking.X == -1 && hitrect.Contains(mouselocation.X * canvas.ZoomFactor, mouselocation.Y * canvas.ZoomFactor)))
                        {
                            e.Graphics.FillEllipse(Brushes.Black, RectangleF.Inflate(dotdrawrect, 1, 1));
                            e.Graphics.FillEllipse(Brushes.White, RectangleF.Inflate(dotdrawrect, -1, -1));
                            hovering = new Point(i, j);
                        }
                        else
                        {
                            e.Graphics.FillEllipse(Brushes.Black, dotdrawrect);
                        }
                    }
                }
            }
        }
        unsafe private void UpdatePointHorizontal(int px, int istart, int ystart, int yend)
        {
            CosineInterpolator left  = new CosineInterpolator();
            CosineInterpolator right = new CosineInterpolator();

            for (int j = 0; j < handlesy; ++j)
            {
                left.Add((j + points[istart, j].Y) * yspacing, points[istart, j].X * xspacing);
                right.Add((j + points[istart, j].Y) * yspacing, points[istart, j].X * xspacing);
            }

            for (int i = px - 1; i < px + 1; ++i)
            {
                if (i >= -1 && i < width)
                {
                    right = new CosineInterpolator();
                    for (int j = 0; j < handlesy; ++j)
                    {
                        right.Add((j + points[i + 1, j].Y) * yspacing, points[i + 1, j].X * xspacing);
                    }
                }

                float itoxleft  = i * xspacing;
                float itoxright = (i + 1) * xspacing;

                for (int y = ystart; y < yend; ++y)
                {
                    float
                        leftval  = -(float)(left.Interpolate(y)),
                        rightval = -(float)(right.Interpolate(y));

                    int x1 = (int)(itoxleft - leftval);
                    int x2 = (int)(itoxright - rightval) + 1;

                    float xdif = x2 - x1;

                    if (x1 < 0)
                    {
                        x1 = 0;
                    }
                    if (x2 > mesh.Width)
                    {
                        x2 = mesh.Width;
                    }

                    DisplacementVector *ptr = mesh.GetPointAddressUnchecked(x1, y);

                    for (int x = x1; x < x2; ++x)
                    {
                        float
                            lerp = (x - x1) / xdif,
                            val  = lerp * rightval + (1 - lerp) * leftval;

                        ptr->X = val;
                        ++ptr;
                    }
                }

                left = right;
            }
        }