public static void PaintLine(Stroke stroke, ref Texture2D tex) { //var width = stroke.width * 2; var extent = stroke.width; var stY = Mathf.Clamp(Mathf.Min(stroke.start.y, stroke.end.y) - extent, 0, tex.height); var stX = Mathf.Clamp(Mathf.Min(stroke.start.x, stroke.end.x) - extent, 0, tex.width); var endY = Mathf.Clamp(Mathf.Max(stroke.start.y, stroke.end.y) + extent, 0, tex.height); var endX = Mathf.Clamp(Mathf.Max(stroke.start.x, stroke.end.x) + extent, 0, tex.width); var lengthX = endX - stX; var lengthY = endY - stY; //var sqrRad = stroke.width * stroke.width; var sqrRad2 = (stroke.width + 1) * (stroke.width + 1); var start = new Vector2(stX, stY); Vector2 p = new Vector2(); Vector2 center = new Vector2(); float dist; for (int y = 0; y < (int)lengthY; y++) { for (int x = 0; x < (int)lengthX; x++) { p.Set(x, y); p += start; center = p + Vector2.one * 0.5f; dist = (center - Mathfx.NearestPointStrict(stroke.start, stroke.end, center)).sqrMagnitude; if (dist > sqrRad2) { continue; } dist = Mathfx.GaussFalloff(Mathf.Sqrt(dist), stroke.width) * stroke.hardness; if (dist > 0) { tex.SetPixel(x + (int)stX, y + (int)stY, stroke.color); } } } tex.Apply(false); }
public static Texture2D DrawLine(Vector2 from, Vector2 to, float w, Color col, Texture2D tex, bool stroke, Color strokeCol, float strokeWidth) { w = Mathf.Round(w);//It is important to round the numbers otherwise it will mess up with the texture width strokeWidth = Mathf.Round(strokeWidth); var extent = w + strokeWidth; var stY = Mathf.Clamp(Mathf.Min(from.y, to.y) - extent, 0, tex.height);//This is the topmost Y value var stX = Mathf.Clamp(Mathf.Min(from.x, to.x) - extent, 0, tex.width); var endY = Mathf.Clamp(Mathf.Max(from.y, to.y) + extent, 0, tex.height); var endX = Mathf.Clamp(Mathf.Max(from.x, to.x) + extent, 0, tex.width);//This is the rightmost Y value strokeWidth = strokeWidth / 2; var strokeInner = (w - strokeWidth) * (w - strokeWidth); var strokeOuter = (w + strokeWidth) * (w + strokeWidth); var strokeOuter2 = (w + strokeWidth + 1) * (w + strokeWidth + 1); var sqrW = w * w;//It is much faster to calculate with squared values var lengthX = endX - stX; var lengthY = endY - stY; var start = new Vector2(stX, stY); Color[] pixels = tex.GetPixels((int)stX, (int)stY, (int)lengthX, (int)lengthY, 0);//Get all pixels for (int y = 0; y < lengthY; y++) { for (int x = 0; x < lengthX; x++) {//Loop through the pixels var p = new Vector2(x, y) + start; var center = p + new Vector2(0.5f, 0.5f); float dist = (center - Mathfx.NearestPointStrict(from, to, center)).sqrMagnitude;//The squared distance from the center of the pixels to the nearest point on the line if (dist <= strokeOuter2) { var samples = Sample(p); var c = Color.black; var pc = pixels[y * (int)lengthX + x]; for (int i = 0; i < samples.Length; i++) { //Loop through the samples dist = (samples[i] - Mathfx.NearestPointStrict(from, to, samples[i])).sqrMagnitude; //The squared distance from the sample to the line if (stroke) { if (dist <= strokeOuter && dist >= strokeInner) { c += strokeCol; } else if (dist < sqrW) { c += col; } else { c += pc; } } else { if (dist < sqrW) {//Is the distance smaller than the width of the line c += col; } else { c += pc;//No it wasn't, set it to be the original colour } } } c /= samples.Length;//Get the avarage colour pixels[y * (int)lengthX + x] = c; } } } tex.SetPixels((int)stX, (int)stY, (int)lengthX, (int)lengthY, pixels, 0); tex.Apply(); return(tex); }