public override void Apply(ITerrainSurface target, int x, int y, out TerrainOp op) { op = null; if (!CanApplyTo(target)) { return; } Bound2di outRect; TerrainGob terrain = target.As <TerrainGob>(); ImageData hmImg = terrain.GetSurface(); ComputeBound(hmImg, x, y, out outRect); if (!outRect.isValid || hmImg.Format != ImageDataFORMAT.R32_FLOAT) { return; } op = new TerrainOp(target, outRect); var brushOp = GetBrushOp(); Func <float, float, float> ops = null; if (brushOp == BrushOps.Add) { ops = (a, b) => a + b; } else if (brushOp == BrushOps.Sub) { ops = (a, b) => a - b; } if (ops == null) { throw new ArgumentException("brushOp"); } // start point in kernel space. int bx0 = x - Radius; int by0 = y - Radius; int size = 2 * Radius + 1; for (int cy = outRect.y1; cy < outRect.y2; cy++) { int by = cy - by0; for (int cx = outRect.x1; cx < outRect.x2; cx++) { int bx = cx - bx0; float scrPixel = Kernel[size * by + bx] * m_height; float *destPixel = (float *)hmImg.GetPixel(cx, cy); * destPixel = ops(*destPixel, scrPixel); } } terrain.ApplyDirtyRegion(outRect); }
public override void Apply(ITerrainSurface target, int x, int y, out TerrainOp op) { op = null; if (!CanApplyTo(target)) { return; } Bound2di outRect; TerrainGob terrain = target.As <TerrainGob>(); ImageData hmImg = terrain.GetSurface(); ComputeBound(hmImg, x, y, out outRect); if (!outRect.isValid || hmImg.Format != ImageDataFORMAT.R32_FLOAT) { return; } op = new TerrainOp(target, outRect); // start point in kernel space. int bx0 = x - Radius; int by0 = y - Radius; int size = 2 * Radius + 1; for (int cy = outRect.y1; cy < outRect.y2; cy++) { int by = cy - by0; for (int cx = outRect.x1; cx < outRect.x2; cx++) { int bx = cx - bx0; float k = Kernel[size * by + bx] * m_noise[bx, by] * m_scale; float *destPixel = (float *)hmImg.GetPixel(cx, cy); * destPixel = *destPixel + k; } } terrain.ApplyDirtyRegion(outRect); }
public override void Apply(ITerrainSurface target, int x, int y, out TerrainOp op) { //todo: optimze this function. op = null; if (!CanApplyTo(target)) { return; } TerrainGob terrain = target.As <TerrainGob>(); ImageData hmImg = terrain.GetSurface(); Bound2di outRect; ComputeBound(hmImg, x, y, out outRect); if (!outRect.isValid || hmImg.Format != ImageDataFORMAT.R32_FLOAT) { return; } op = new TerrainOp(target, outRect); Func <int, int, float> getPixel = (px, py) => { px = MathUtil.Clamp(px, 0, hmImg.Width - 1); py = MathUtil.Clamp(py, 0, hmImg.Height - 1); float pixel = *(float *)hmImg.GetPixel(px, py); return(pixel); }; Func <int, int, float> getSmoothPixel = (px, py) => { float r1 = getPixel(px - 1, py - 1) + 2.0f * getPixel(px, py - 1) + getPixel(px + 1, py - 1); float r2 = 2.0f * getPixel(px - 1, py) + 4.0f * getPixel(px, py) + 2.0f * getPixel(px + 1, py); float r3 = getPixel(px - 1, py + 1) + 2.0f * getPixel(px, py + 1) + getPixel(px + 1, py + 1); return((r1 + r2 + r3) / 16.0f); }; m_templist.Clear(); for (int cy = outRect.y1; cy < outRect.y2; cy++) { for (int cx = outRect.x1; cx < outRect.x2; cx++) { m_templist.Add(getSmoothPixel(cx, cy)); } } // start point in kernel space. int bx0 = x - Radius; int by0 = y - Radius; int k = 0; int size = 2 * Radius + 1; for (int cy = outRect.y1; cy < outRect.y2; cy++) { int by = cy - by0; for (int cx = outRect.x1; cx < outRect.x2; cx++) { int bx = cx - bx0; float scrPixel = m_templist[k++]; float lerp = Kernel[size * by + bx]; float *destPixel = (float *)hmImg.GetPixel(cx, cy); * destPixel = Sce.Atf.MathUtil.Interp(lerp, *destPixel, scrPixel); } } terrain.ApplyDirtyRegion(outRect); }