void IManipulator.Render(ViewControl vc) { TerrainGob terrain = m_terrainEditor.TerrainEditorControl.SelectedTerrain; TerrainBrush brush = m_terrainEditor.TerrainEditorControl.SelectedBrush; TerrainMap terrainMap = m_terrainEditor.TerrainEditorControl.SelectedTerrainMap; if (brush == null || (!brush.CanApplyTo(terrain) && !brush.CanApplyTo(terrainMap))) { return; } Vec2F drawscale = new Vec2F(1.0f, 1.0f); if (brush.CanApplyTo(terrainMap)) { ImageData mapImg = terrainMap.GetSurface(); ImageData hmImg = terrain.GetSurface(); drawscale.X = (float)hmImg.Width / (float)mapImg.Width; drawscale.Y = (float)hmImg.Height / (float)mapImg.Height; } Point scrPt = vc.PointToClient(Control.MousePosition); if (!vc.ClientRectangle.Contains(scrPt)) { return; } Ray3F rayw = vc.GetWorldRay(scrPt); TerrainGob.RayPickRetVal retval; if (terrain.RayPick(rayw, out retval)) { terrain.DrawBrush(brush, drawscale, retval.hitpos); } }
public override void Apply(ITerrainSurface target, int x, int y, out TerrainOp op) { op = null; if (!CanApplyTo(target)) { return; } Bound2di outRect; TerrainMap tmap = target.As <TerrainMap>(); ImageData mask = tmap.GetSurface(); ComputeBound(mask, x, y, out outRect); bool validArgs = outRect.isValid && mask.Format == ImageDataFORMAT.R8_UNORM; System.Diagnostics.Debug.Assert(validArgs); if (validArgs == false) { return; } op = new TerrainOp(target, outRect); var brushOp = GetBrushOp(); float minheight = tmap.MinHeight; float maxheight = tmap.MaxHeight; float minslope = tmap.MinSlope; float maxslope = tmap.MaxSlope; ImageData hmImg = tmap.Parent.GetSurface(); float dx = (float)hmImg.Width / (float)mask.Width; float dy = (float)hmImg.Height / (float)mask.Height; int pixelstrength = (int)Math.Round(255.0f * Strength); Func <int, int, byte> ops = null; if (brushOp == BrushOps.Paint) { ops = (px, py) => { if (px >= pixelstrength) { return((byte)px); } else { return((byte)Math.Min(pixelstrength, px + py)); } }; } else { ops = (px, py) => (byte)MathUtil.Clamp <int>(px - py, 0, 255); } // start point in kernel space. int bx0 = x - Radius; int by0 = y - Radius; float run = 2.0f * tmap.Parent.CellSize; 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; // test for height and slope. // xform px and py to heightmap space hx, hy. if (brushOp == BrushOps.Paint) { int hx = (int)Math.Round(cx * dx); int hy = (int)Math.Round(cy * dy); float height = hmImg.GetPixelFloat(hx, hy); if (height < minheight || height > maxheight) { continue; } // check slope float slopex = hmImg.GetPixelFloat(hx + 1, hy) - hmImg.GetPixelFloat(hx - 1, hy); float slopeY = hmImg.GetPixelFloat(hx, hy + 1) - hmImg.GetPixelFloat(hx, hy - 1); float slope = Math.Max(Math.Abs(slopex), Math.Abs(slopeY)) / run; float deg = MathHelper.ToDegree((float)Math.Atan(slope)); if (deg < minslope || deg > maxslope) { continue; } } float scrPixel = Kernel[size * by + bx]; byte *destPixel = mask.GetPixel(cx, cy); * destPixel = ops(*destPixel, (int)Math.Round(scrPixel * 255.0f)); } } tmap.ApplyDirtyRegion(outRect); }