public GroundTextureEditor() { Pencil = new GroundTexturePencil { Type = GroundTexturePencilType.Add, Radius = 1, Color = new Vector4(1, 1, 1, 0) }; }
//float Saturate(float a) //{ // if (a > 1.0f) // return 1.0f; // if (a < 0.0f) // return 0.0f; // return a; //} public void Draw(Vector2 pos, GroundTexturePencil pencil) { System.Drawing.Point hmPos = WorldPositionToTexture(pos); System.Drawing.Point hmRadius = WorldSizeToTexture(new Vector2(pencil.Radius, pencil.Radius)); int yStart = Math.Max(0, hmPos.Y - hmRadius.Y); int yEnd = Math.Min(SoftwareTexture[0].Size.Height - 1, hmPos.Y + hmRadius.Y); if (yStart == yEnd) { return; } int xStart = Math.Max(0, hmPos.X - hmRadius.X); int xEnd = Math.Min(SoftwareTexture[0].Size.Width - 1, hmPos.X + hmRadius.X); if (xStart == xEnd) { return; } Vector4 sum = Vector4.Zero; int count = 0; if (pencil.Type == GroundTexturePencilType.Smooth) { for (int y = yStart; y <= yEnd; y++) { for (int x = xStart; x <= xEnd; x++) { var v = SoftwareTexture[0][y, x]; sum.X += v.R; sum.Y += v.G; sum.Z += v.B; sum.W += v.A; count++; } } } Vector4 avg = sum / (float)count; Vector4 goalColor = Vector4.Zero; if (pencil.Type == GroundTexturePencilType.Smooth) { goalColor = avg; } else if (pencil.Type == GroundTexturePencilType.Flatten) { var v = SoftwareTexture[0][(yStart + yEnd) / 2, (xStart + xEnd) / 2]; goalColor = new Vector4(v.R, v.G, v.B, v.A); } else if (pencil.Type == GroundTexturePencilType.Set) { goalColor = pencil.Color; } for (int y = yStart; y <= yEnd; y++) { for (int x = xStart; x <= xEnd; x++) { var wp = TextureToWorld(new Point(x, y)); var v1 = SoftwareTexture[0][y, x]; float d = (pos - wp).Length(); if (pencil.Shape == GroundTexturePencilShape.Circle && d > pencil.Radius) { continue; } float p = d / pencil.Radius; // d : [0, 1] p = (float)System.Math.Pow(p, pencil.Hardness + 1); p *= 3; // d : [0, 3] float red1 = (float)Common.Math.Gaussian(pencil.Colors[0], 0, 1, p); float green1 = (float)Common.Math.Gaussian(pencil.Colors[1], 0, 1, p); float blue1 = (float)Common.Math.Gaussian(pencil.Colors[2], 0, 1, p); float alpha1 = (float)Common.Math.Gaussian(pencil.Colors[3], 0, 1, p); if (pencil.Type == GroundTexturePencilType.Add) { v1.R += red1; v1.G += green1; v1.B += blue1; v1.A += alpha1; } else if (pencil.Type == GroundTexturePencilType.AddSaturate) { v1.R = Saturate(v1.R + red1); v1.G = Saturate(v1.G + green1); v1.B = Saturate(v1.B + blue1); v1.A = Saturate(v1.A + alpha1); } else if (pencil.Type == GroundTexturePencilType.AddReplace) { //var v2 = SoftwareTexture[1][y, x]; float red2 = (float)Common.Math.Gaussian(pencil.Colors[4], 0, 1, p); float green2 = (float)Common.Math.Gaussian(pencil.Colors[5], 0, 1, p); float blue2 = (float)Common.Math.Gaussian(pencil.Colors[6], 0, 1, p); float alpha2 = (float)Common.Math.Gaussian(pencil.Colors[7], 0, 1, p); //float scale = 0; //if (v1.R > 0 && pencil.Colors[0] < 0) // scale++; //if (v1.G > 0 && pencil.Colors[1] < 0) // scale++; //if (v1.B > 0 && pencil.Colors[2] < 0) // scale++; //if (v1.A > 0 && pencil.Colors[3] < 0) // scale++; //if (v2.R > 0 && pencil.Colors[4] < 0) // scale++; //if (v2.G > 0 && pencil.Colors[5] < 0) // scale++; //if (v2.B > 0 && pencil.Colors[6] < 0) // scale++; //if (v2.A > 0 && pencil.Colors[7] < 0) // scale++; //if (scale != 0) // scale = 1f / scale; //else // scale = 1f; //if (scale < 1) // //Console.WriteLine("hej"); //if(pencil.Colors[0] > 0) // v1.R = Saturate(v1.R + red1); //else // v1.R = Saturate(v1.R + red1 / scale); //if(pencil.Colors[1] > 0) // v1.G = Saturate(v1.G + green1); //else // v1.G = Saturate(v1.G + green1 / scale); //if(pencil.Colors[2] > 0) // v1.B = Saturate(v1.B + blue1); //else // v1.B = Saturate(v1.B + blue1 / scale); //if(pencil.Colors[3] > 0) // v1.A = Saturate(v1.A + alpha1); //else // v1.A = Saturate(v1.A + alpha1 / scale); //if (pencil.Colors[4] > 0) // v2.R = Saturate(v2.R + red2); //else // v2.R = Saturate(v2.R + red2 / scale); //if (pencil.Colors[5] > 0) // v2.G = Saturate(v2.G + green2); //else // v2.G = Saturate(v2.G + green2 / scale); //if (pencil.Colors[6] > 0) // v2.B = Saturate(v2.B + blue2); //else // v2.B = Saturate(v2.B + blue2 / scale); //if (pencil.Colors[7] > 0) // v2.A = Saturate(v2.A + alpha2); //else // v2.A = Saturate(v2.A + alpha2 / scale); var v2 = SoftwareTexture[1][y, x]; Vector4[] tmp = Splat(new Vector4[] { new Vector4(v1.R, v1.G, v1.B, v1.A), new Vector4(v2.R, v2.G, v2.B, v2.A) }, new float[] { red1, green1, blue1, alpha1, red2, green2, blue2, alpha2 }); v1.R = tmp[0].X; v1.G = tmp[0].Y; v1.B = tmp[0].Z; v1.A = tmp[0].W; v2.R = tmp[1].X; v2.G = tmp[1].Y; v2.B = tmp[1].Z; v2.A = tmp[1].W; SoftwareTexture[1][y, x] = v2; //float a = v1.R + v1.G + v1.B + v1.A + v2.R + v2.G + v2.B + v2.A; } else if (pencil.Type == GroundTexturePencilType.Set) { v1.R = goalColor.X; v1.G = goalColor.Y; v1.B = goalColor.Z; v1.A = goalColor.W; } else if (pencil.Type == GroundTexturePencilType.Smooth || pencil.Type == GroundTexturePencilType.Flatten) { v1.R = v1.R * (1 - red1) + goalColor.X * red1; v1.G = v1.G * (1 - green1) + goalColor.Y * green1; v1.B = v1.B * (1 - blue1) + goalColor.Z * blue1; v1.A = v1.A * (1 - alpha1) + goalColor.W * alpha1; } else { throw new ArgumentException(); } SoftwareTexture[0][y, x] = v1; } } if (Texture9 != null && Texture9.Length > 0 && Texture9[0] != null) { Rectangle r = new Rectangle(xStart, yStart, xEnd - xStart, yEnd - yStart); var dr = Texture9[0].LockRectangle(0, r, SlimDX.Direct3D9.LockFlags.None); SoftwareTexture[0].WriteRect(dr, r); Texture9[0].UnlockRectangle(0); } if (Texture9 != null && Texture9.Length > 1 && Texture9[1] != null) { Rectangle r = new Rectangle(xStart, yStart, xEnd - xStart, yEnd - yStart); var dr = Texture9[1].LockRectangle(0, r, SlimDX.Direct3D9.LockFlags.None); SoftwareTexture[1].WriteRect(dr, r); Texture9[1].UnlockRectangle(0); } if (TextureValuesChanged != null) { TextureValuesChanged(this, new TextureValuesChangedEvent { ChangedRegion = new RectangleF( xStart / (float)SoftwareTexture[0].Size.Width, yStart / (float)SoftwareTexture[0].Size.Height, (xEnd - xStart + 1) / (float)SoftwareTexture[0].Size.Width, (yEnd - yStart + 1) / (float)SoftwareTexture[0].Size.Height ) }); } }
//float Saturate(float a) //{ // if (a > 1.0f) // return 1.0f; // if (a < 0.0f) // return 0.0f; // return a; //} public void Draw(Vector2 pos, GroundTexturePencil pencil) { System.Drawing.Point hmPos = WorldPositionToTexture(pos); System.Drawing.Point hmRadius = WorldSizeToTexture(new Vector2(pencil.Radius, pencil.Radius)); int yStart = Math.Max(0, hmPos.Y - hmRadius.Y); int yEnd = Math.Min(SoftwareTexture[0].Size.Height - 1, hmPos.Y + hmRadius.Y); if (yStart == yEnd) return; int xStart = Math.Max(0, hmPos.X - hmRadius.X); int xEnd = Math.Min(SoftwareTexture[0].Size.Width - 1, hmPos.X + hmRadius.X); if (xStart == xEnd) return; Vector4 sum = Vector4.Zero; int count = 0; if (pencil.Type == GroundTexturePencilType.Smooth) { for (int y = yStart; y <= yEnd; y++) for (int x = xStart; x <= xEnd; x++) { var v = SoftwareTexture[0][y, x]; sum.X += v.R; sum.Y += v.G; sum.Z += v.B; sum.W += v.A; count++; } } Vector4 avg = sum / (float)count; Vector4 goalColor = Vector4.Zero; if (pencil.Type == GroundTexturePencilType.Smooth) goalColor = avg; else if (pencil.Type == GroundTexturePencilType.Flatten) { var v = SoftwareTexture[0][(yStart + yEnd) / 2, (xStart + xEnd) / 2]; goalColor = new Vector4(v.R, v.G, v.B, v.A); } else if (pencil.Type == GroundTexturePencilType.Set) goalColor = pencil.Color; for (int y = yStart; y <= yEnd; y++) for (int x = xStart; x <= xEnd; x++) { var wp = TextureToWorld(new Point(x, y)); var v1 = SoftwareTexture[0][y, x]; float d = (pos - wp).Length(); if (pencil.Shape == GroundTexturePencilShape.Circle && d > pencil.Radius) continue; float p = d / pencil.Radius; // d : [0, 1] p = (float)System.Math.Pow(p, pencil.Hardness + 1); p *= 3; // d : [0, 3] float red1 = (float)Common.Math.Gaussian(pencil.Colors[0], 0, 1, p); float green1 = (float)Common.Math.Gaussian(pencil.Colors[1], 0, 1, p); float blue1 = (float)Common.Math.Gaussian(pencil.Colors[2], 0, 1, p); float alpha1 = (float)Common.Math.Gaussian(pencil.Colors[3], 0, 1, p); if (pencil.Type == GroundTexturePencilType.Add) { v1.R += red1; v1.G += green1; v1.B += blue1; v1.A += alpha1; } else if (pencil.Type == GroundTexturePencilType.AddSaturate) { v1.R = Saturate(v1.R + red1); v1.G = Saturate(v1.G + green1); v1.B = Saturate(v1.B + blue1); v1.A = Saturate(v1.A + alpha1); } else if (pencil.Type == GroundTexturePencilType.AddReplace) { //var v2 = SoftwareTexture[1][y, x]; float red2 = (float)Common.Math.Gaussian(pencil.Colors[4], 0, 1, p); float green2 = (float)Common.Math.Gaussian(pencil.Colors[5], 0, 1, p); float blue2 = (float)Common.Math.Gaussian(pencil.Colors[6], 0, 1, p); float alpha2 = (float)Common.Math.Gaussian(pencil.Colors[7], 0, 1, p); //float scale = 0; //if (v1.R > 0 && pencil.Colors[0] < 0) // scale++; //if (v1.G > 0 && pencil.Colors[1] < 0) // scale++; //if (v1.B > 0 && pencil.Colors[2] < 0) // scale++; //if (v1.A > 0 && pencil.Colors[3] < 0) // scale++; //if (v2.R > 0 && pencil.Colors[4] < 0) // scale++; //if (v2.G > 0 && pencil.Colors[5] < 0) // scale++; //if (v2.B > 0 && pencil.Colors[6] < 0) // scale++; //if (v2.A > 0 && pencil.Colors[7] < 0) // scale++; //if (scale != 0) // scale = 1f / scale; //else // scale = 1f; //if (scale < 1) // //Console.WriteLine("hej"); //if(pencil.Colors[0] > 0) // v1.R = Saturate(v1.R + red1); //else // v1.R = Saturate(v1.R + red1 / scale); //if(pencil.Colors[1] > 0) // v1.G = Saturate(v1.G + green1); //else // v1.G = Saturate(v1.G + green1 / scale); //if(pencil.Colors[2] > 0) // v1.B = Saturate(v1.B + blue1); //else // v1.B = Saturate(v1.B + blue1 / scale); //if(pencil.Colors[3] > 0) // v1.A = Saturate(v1.A + alpha1); //else // v1.A = Saturate(v1.A + alpha1 / scale); //if (pencil.Colors[4] > 0) // v2.R = Saturate(v2.R + red2); //else // v2.R = Saturate(v2.R + red2 / scale); //if (pencil.Colors[5] > 0) // v2.G = Saturate(v2.G + green2); //else // v2.G = Saturate(v2.G + green2 / scale); //if (pencil.Colors[6] > 0) // v2.B = Saturate(v2.B + blue2); //else // v2.B = Saturate(v2.B + blue2 / scale); //if (pencil.Colors[7] > 0) // v2.A = Saturate(v2.A + alpha2); //else // v2.A = Saturate(v2.A + alpha2 / scale); var v2 = SoftwareTexture[1][y, x]; Vector4[] tmp = Splat(new Vector4[] { new Vector4(v1.R, v1.G, v1.B, v1.A), new Vector4(v2.R, v2.G, v2.B, v2.A) }, new float[] { red1, green1, blue1, alpha1, red2, green2, blue2, alpha2 }); v1.R = tmp[0].X; v1.G = tmp[0].Y; v1.B = tmp[0].Z; v1.A = tmp[0].W; v2.R = tmp[1].X; v2.G = tmp[1].Y; v2.B = tmp[1].Z; v2.A = tmp[1].W; SoftwareTexture[1][y, x] = v2; //float a = v1.R + v1.G + v1.B + v1.A + v2.R + v2.G + v2.B + v2.A; } else if (pencil.Type == GroundTexturePencilType.Set) { v1.R = goalColor.X; v1.G = goalColor.Y; v1.B = goalColor.Z; v1.A = goalColor.W; } else if (pencil.Type == GroundTexturePencilType.Smooth || pencil.Type == GroundTexturePencilType.Flatten) { v1.R = v1.R * (1 - red1) + goalColor.X * red1; v1.G = v1.G * (1 - green1) + goalColor.Y * green1; v1.B = v1.B * (1 - blue1) + goalColor.Z * blue1; v1.A = v1.A * (1 - alpha1) + goalColor.W * alpha1; } else throw new ArgumentException(); SoftwareTexture[0][y, x] = v1; } if (Texture9 != null && Texture9.Length > 0 && Texture9[0] != null) { Rectangle r = new Rectangle(xStart, yStart, xEnd - xStart, yEnd - yStart); var dr = Texture9[0].LockRectangle(0, r, SlimDX.Direct3D9.LockFlags.None); SoftwareTexture[0].WriteRect(dr, r); Texture9[0].UnlockRectangle(0); } if (Texture9 != null && Texture9.Length > 1 && Texture9[1] != null) { Rectangle r = new Rectangle(xStart, yStart, xEnd - xStart, yEnd - yStart); var dr = Texture9[1].LockRectangle(0, r, SlimDX.Direct3D9.LockFlags.None); SoftwareTexture[1].WriteRect(dr, r); Texture9[1].UnlockRectangle(0); } if (TextureValuesChanged != null) TextureValuesChanged(this, new TextureValuesChangedEvent { ChangedRegion = new RectangleF( xStart / (float)SoftwareTexture[0].Size.Width, yStart / (float)SoftwareTexture[0].Size.Height, (xEnd - xStart + 1) / (float)SoftwareTexture[0].Size.Width, (yEnd - yStart + 1) / (float)SoftwareTexture[0].Size.Height ) }); }