void Paint(Vector3 AtPosition, int id = 0)
        {
            int BrushPaintType = SelectedBrush;


            if (Smooth)
            {
                BrushPaintType = 2;                 // Smooth
            }
            int hmWidth  = ScmapEditor.Current.Teren.terrainData.heightmapWidth;
            int hmHeight = ScmapEditor.Current.Teren.terrainData.heightmapHeight;

            Vector3 tempCoord = ScmapEditor.Current.Teren.gameObject.transform.InverseTransformPoint(AtPosition);
            Vector3 coord     = Vector3.zero;

            coord.x = tempCoord.x / ScmapEditor.Current.Teren.terrainData.size.x;
            //coord.y = tempCoord.y / ScmapEditor.Current.Teren.terrainData.size.y;
            coord.z = tempCoord.z / ScmapEditor.Current.Teren.terrainData.size.z;

            if (coord.x > 1)
            {
                return;
            }
            if (coord.x < 0)
            {
                return;
            }
            if (coord.z > 1)
            {
                return;
            }
            if (coord.z < 0)
            {
                return;
            }

            // get the position of the terrain heightmap where this game object is
            int posXInTerrain = (int)(coord.x * hmWidth);
            int posYInTerrain = (int)(coord.z * hmHeight);
            // we set an offset so that all the raising terrain is under this game object
            int size = BrushSize.intValue;

            if (BrushPaintType == 2 && size < 8)
            {
                size = 8;
            }


            int offset = size / 2;
            // get the heights of the terrain under this game object

            // Horizontal Brush Offsets
            int OffsetLeft = 0;

            if (posXInTerrain - offset < 0)
            {
                OffsetLeft = Mathf.Abs(posXInTerrain - offset);
            }
            int OffsetRight = 0;

            if (posXInTerrain - offset + size > ScmapEditor.Current.Teren.terrainData.heightmapWidth)
            {
                OffsetRight = posXInTerrain - offset + size - ScmapEditor.Current.Teren.terrainData.heightmapWidth;
            }

            // Vertical Brush Offsets
            int OffsetDown = 0;

            if (posYInTerrain - offset < 0)
            {
                OffsetDown = Mathf.Abs(posYInTerrain - offset);
            }
            int OffsetTop = 0;

            if (posYInTerrain - offset + size > ScmapEditor.Current.Teren.terrainData.heightmapWidth)
            {
                OffsetTop = posYInTerrain - offset + size - ScmapEditor.Current.Teren.terrainData.heightmapWidth;
            }

            //float[,] heights = ScmapEditor.Current.Teren.terrainData.GetHeights(posXInTerrain - offset + OffsetLeft, posYInTerrain - offset + OffsetDown, (size - OffsetLeft) - OffsetRight, (size - OffsetDown) - OffsetTop);

            int GetX = posXInTerrain - offset + OffsetLeft;
            int GetY = posYInTerrain - offset + OffsetDown;


            int SizeDown = (size - OffsetDown) - OffsetTop;
            int SizeLeft = (size - OffsetLeft) - OffsetRight;

            ScmapEditor.GetValues(GetX, GetY, SizeDown, SizeLeft);


            float CenterHeight = 0;

            int   i           = 0;
            int   j           = 0;
            int   x           = 0;
            int   y           = 0;
            float SampleBrush = 0;
            float PixelPower  = 0;

            if (SelectedBrush == 1)
            {
                float Count = 0;
                for (i = 0; i < ScmapEditor.LastGetWidth; i++)
                {
                    for (j = 0; j < ScmapEditor.LastGetHeight; j++)
                    {
                        // Brush strength
                        x = (int)(((i + OffsetDown) / (float)size) * BrushGenerator.Current.PaintImageWidths[id]);
                        y = (int)(((j + OffsetLeft) / (float)size) * BrushGenerator.Current.PaintImageHeights[id]);

                        if (x < 0 || y < 0 || x >= BrushGenerator.Current.PaintImageWidths[id] || y >= BrushGenerator.Current.PaintImageHeights[id])
                        {
                            continue;
                        }
                        SampleBrush   = Mathf.Clamp01(BrushGenerator.Current.Values[id][y + BrushGenerator.Current.PaintImageHeights[id] * x] - 0.0255f);
                        CenterHeight += ScmapEditor.ReturnValues[i, j] * SampleBrush;
                        Count        += SampleBrush;
                    }
                }
                CenterHeight /= Count;
            }
            else if (SelectedBrush == 3)
            {
                float Count = 0;
                for (i = 0; i < ScmapEditor.LastGetWidth; i++)
                {
                    for (j = 0; j < ScmapEditor.LastGetHeight; j++)
                    {
                        // Brush strength
                        x = (int)(((i + OffsetDown) / (float)size) * BrushGenerator.Current.PaintImageWidths[id]);
                        y = (int)(((j + OffsetLeft) / (float)size) * BrushGenerator.Current.PaintImageHeights[id]);

                        if (x < 0 || y < 0 || x >= BrushGenerator.Current.PaintImageWidths[id] || y >= BrushGenerator.Current.PaintImageHeights[id])
                        {
                            continue;
                        }
                        SampleBrush   = Mathf.Clamp01(BrushGenerator.Current.Values[id][y + BrushGenerator.Current.PaintImageHeights[id] * x] - 0.0255f);
                        CenterHeight += ScmapEditor.ReturnValues[i, j] * SampleBrush;
                        Count        += SampleBrush;
                    }
                }
                CenterHeight /= Count;
            }


            float TargetHeight = Mathf.Clamp(((Invert?(256):(BrushTarget.value)) / ScmapEditor.Current.Data.size.y) / 10f, Min, Max);

            float BrushStrenghtValue = BrushStrength.value;
            //float PaintStrength = BrushStrenghtValue * 0.00005f * (Invert ? (-1) : 1);

            float StrengthMultiplier = 1;

            switch (BrushPaintType)
            {
            case 1:                     // Flatten
                StrengthMultiplier = BrushGenerator.Current.HeightmapBlurStrength.Evaluate(BrushStrenghtValue) * 0.00008f;
                break;

            case 2:                     // Smooth
                StrengthMultiplier = BrushGenerator.Current.HeightmapBlurStrength.Evaluate(BrushStrenghtValue) * Mathf.Clamp(size / 10f, 0, 20) * 0.01f;
                break;

            case 3:                     // Sharp
                StrengthMultiplier = BrushGenerator.Current.HeightmapBlurStrength.Evaluate(BrushStrenghtValue) * 0.00008f;
                break;

            default:
                StrengthMultiplier = BrushGenerator.Current.HeightmapPaintStrength.Evaluate(BrushStrenghtValue) * 0.00008f * (Invert ? (-1) : 1);
                break;
            }

            //float SizeSmooth = Mathf.Clamp01(size / 10f) * 15;


            for (i = 0; i < ScmapEditor.LastGetWidth; i++)
            {
                for (j = 0; j < ScmapEditor.LastGetHeight; j++)
                {
                    // Brush strength
                    x = (int)(((i + OffsetDown) / (float)size) * BrushGenerator.Current.PaintImageWidths[id]);
                    y = (int)(((j + OffsetLeft) / (float)size) * BrushGenerator.Current.PaintImageHeights[id]);

                    if (x < 0 || y < 0 || x >= BrushGenerator.Current.PaintImageWidths[id] || y >= BrushGenerator.Current.PaintImageHeights[id])
                    {
                        continue;
                    }
                    SampleBrush = Mathf.Clamp01(BrushGenerator.Current.Values[id][y + BrushGenerator.Current.PaintImageHeights[id] * x] - 0.0255f);


                    if (SampleBrush > 0)
                    {
                        //if (i < 0 || j < 0 || i >= ScmapEditor.LastGetWidth || j >= ScmapEditor.LastGetHeight)
                        //	continue;

                        switch (BrushPaintType)
                        {
                        case 1:                                 // Flatten
                            PixelPower  = Mathf.Pow(Mathf.Abs(ScmapEditor.ReturnValues[i, j] - CenterHeight), 0.454545f) + 1;
                            PixelPower /= 2f;

                            //if (PixelPower < 0.001f)
                            //	heights[i, j] = CenterHeight;
                            //else {
                            //float FlattenStrenght = PixelPower * StrengthMultiplier * Mathf.Pow(SampleBrush, 2);
                            //heights[i, j] += FlattenStrenght;
                            ScmapEditor.ReturnValues[i, j] = MoveToValue(ScmapEditor.ReturnValues[i, j], CenterHeight, StrengthMultiplier * SampleBrush * PixelPower, 0, ScmapEditor.MaxElevation);
                            //}

                            break;

                        case 2:                                 // Smooth
                            CenterHeight = GetNearValues(ref ScmapEditor.ReturnValues, i, j);

                            PixelPower  = Mathf.Pow(Mathf.Abs(ScmapEditor.ReturnValues[i, j] - CenterHeight), 0.454545f) + 1;
                            PixelPower /= 2f;
                            //PixelPower = 10;

                            //heights[i, j] = Mathf.Lerp(heights[i, j], CenterHeight, BrushStrenghtValue * Mathf.Pow(SampleBrush, 2) * PixelPower);
                            ScmapEditor.ReturnValues[i, j] = Mathf.Lerp(ScmapEditor.ReturnValues[i, j], CenterHeight, PixelPower * StrengthMultiplier * Mathf.Pow(SampleBrush, 2));

                            break;

                        case 3:                                 // Sharp
                            PixelPower  = Mathf.Pow(Mathf.Abs(ScmapEditor.ReturnValues[i, j] - CenterHeight), 0.454545f) + 1;
                            PixelPower /= 2f;
                            //heights[i, j] += Mathf.Lerp(PixelPower, 0, PixelPower * 10) * BrushStrenghtValue * 0.01f * Mathf.Pow(SampleBrush, 2);
                            ScmapEditor.ReturnValues[i, j] = MoveToValue(ScmapEditor.ReturnValues[i, j], CenterHeight, -StrengthMultiplier * SampleBrush * PixelPower, Min, Max);
                            break;

                        default:
                            //heights[i, j] += SampleBrush * StrengthMultiplier;
                            ScmapEditor.ReturnValues[i, j] = MoveToValue(ScmapEditor.ReturnValues[i, j], TargetHeight, SampleBrush * StrengthMultiplier, Min, Max);
                            break;
                        }
                    }
                }
            }

            // set the new height
            if (!TerainChanged)
            {
                ScmapEditor.GetAllHeights(ref beginHeights);

                TerainChanged = true;
            }

            //ScmapEditor.Current.Teren.terrainData.SetHeightsDelayLOD(posXInTerrain - offset + OffsetLeft, posYInTerrain - offset + OffsetDown, heights);

            ScmapEditor.ApplyChanges(GetX, GetY);

            //Markers.MarkersControler.UpdateMarkersHeights();

            OnTerrainChanged();
        }