public GroundTextureEditor()
 {
     Pencil = new GroundTexturePencil
     {
         Type = GroundTexturePencilType.Add,
         Radius = 1,
         Color = new Vector4(1, 1, 1, 0)
     };
 }
Ejemplo n.º 2
0
 public GroundTextureEditor()
 {
     Pencil = new GroundTexturePencil
     {
         Type   = GroundTexturePencilType.Add,
         Radius = 1,
         Color  = new Vector4(1, 1, 1, 0)
     };
 }
Ejemplo n.º 3
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
                        ) });
        }