public unsafe void Clear() { for (int y = 0; y < height; ++y) { DisplacementVector *ptr = GetPointAddressUnchecked(0, y); for (int x = 0; x < width; ++x) { ptr->X = 0; ptr->Y = 0; ++ptr; } } }
private unsafe void LoadData(BinaryReader br) { long length = Math.Min((br.BaseStream.Length - br.BaseStream.Position) / 8 - 1, (long)width * height); DisplacementVector *ptr = (DisplacementVector *)Scan0; for (long i = 0; i < length; ++i) { ptr->X = br.ReadSingle(); ptr->Y = br.ReadSingle(); ++ptr; } }
public unsafe void Copy(DisplacementMesh srcMesh, Point dstOffset, Rectangle srcRect) { for (int y = 0; y < srcRect.Height; ++y) { DisplacementVector * src = srcMesh.GetPointAddressUnchecked(srcRect.X, y + srcRect.Y), dst = this.GetPointAddressUnchecked(dstOffset.X, y + dstOffset.Y); for (int x = 0; x < srcRect.Width; ++x) { *dst = *src; ++src; ++dst; } } }
public unsafe DisplacementVector GetBilinearSample(float x, float y) { int x0, y0; if (x >= width - 1) { x = width - 1; x0 = width - 2; } else { if (x < 0) { x = 0; } x0 = (int)x; } if (y >= height - 1) { y = height - 1; y0 = height - 2; } else { if (y < 0) { y = 0; } y0 = (int)y; } float factorX = x - x0; DisplacementVector * tl = GetPointAddressUnchecked(x0, y0), bl = tl + width; DisplacementVector t = DisplacementVector.Lerp(*tl, *(tl + 1), factorX), b = DisplacementVector.Lerp(*bl, *(bl + 1), factorX); return(DisplacementVector.Lerp(t, b, y - y0)); }
public unsafe void Render(ISurface <ColorBgra> dst, ISurface <ColorBgra> src, Rectangle rect) { if (rect.Width == 0) { return; } for (int y = rect.Top; y < rect.Bottom; ++y) { DisplacementVector *offset = this.GetPointAddressUnchecked(rect.Left, y); ColorBgra * dstPixel = (ColorBgra *)dst.GetPointPointer(rect.Left, y); for (int x = rect.Left; x < rect.Right; ++x) { *dstPixel = src.GetBilinearSample(x + offset->X, y + offset->Y); ++offset; ++dstPixel; } } }
public unsafe DisplacementMesh Resize(Size size) { DisplacementMesh ret = new DisplacementMesh(size); float xfactor = (float)width / size.Width; float yfactor = (float)height / size.Height; for (int y = 0; y < size.Height; ++y) { DisplacementVector *ptr = ret.GetPointAddressUnchecked(0, y); float srcy = y * yfactor;; for (int x = 0; x < size.Width; ++x) { float srcx = x * xfactor; DisplacementVector v = GetBilinearSample(srcx, srcy); ptr->X = v.X / xfactor; ptr->Y = v.Y / yfactor; ++ptr; } } return(ret); }
public unsafe void Save(Stream s) { // [NUL][NUL][NUL][STX]yfqLhseM[STX][NUL][NUL][NUL] byte[] header = { 0, 0, 0, 2, 0x79, 0x66, 0x71, 0x4c, 0x68, 0x73, 0x65, 0x4d, 2, 0, 0, 0 }; using (BinaryWriter bw = new BinaryWriter(s)) { bw.Write(header); bw.Write(width); bw.Write(height); long length = (long)width * height; DisplacementVector *ptr = (DisplacementVector *)Scan0; for (long i = 0; i < length; ++i) { bw.Write(ptr->X); bw.Write(ptr->Y); ++ptr; } bw.Write((long)0); } }
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; } }
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; } }