REMOVE TERRAIN DETAILS : using UnityEngine;
using GPUInstancer;
using System.Collections.Generic;

public  class removeGrass : MonoBehaviour
{

    public GPUInstancerManager instancer;

    public static GPUInstancerManager instancerStatic;

    static removeGrass me;

    public buildingPlacer placer;

    public LayerMask groundLayer;


    public bool removeTerrainDetailsToo = false;

    public int groundTextureIndex = 3;
    private void Start()
    {
        me = this;
        if(instancer)
            instancerStatic = instancer;

        if(instancer)
            instancer.minCullingDistance = 1000;
    }


    public static bool grassInitialised()
    {
        return instancerStatic.isInitialized;
    }


  /*  public static void removeGrassByInstancerUsingRenderer(Renderer b,float offset,bool destroyCollider,bool withTextureUpdate=true)
    {
        // instancer.RemoveInstancesInsideBounds(b,0.2f);
       
       instancerStatic.RemoveInstancesInsideBounds(b.bounds, offset);

       if(withTextureUpdate)
            me.updateTextureWithinBounds(b);
        

        if (destroyCollider)
            Destroy(b);

    }*/

    public static void removeGrassByInstancerUsingCollider(Collider b, float offset, bool destroyCollider, bool withTextureUpdate = true)
    {
        // instancer.RemoveInstancesInsideBounds(b,0.2f);

        if(instancerStatic)
            instancerStatic.RemoveInstancesInsideCollider(b, offset);

        if (withTextureUpdate)
            me.updateTextureWithinBounds(b.GetComponent<Renderer>());


        if (destroyCollider)
            Destroy(b);

    }

    public void updateTextureWithinBounds(Renderer col)
    {
        Terrain currentTerrain = null;
        RaycastHit hit;
        if (Physics.Raycast(col.transform.position + Vector3.up * 3, Vector3.down, out hit, 20, groundLayer))
        {
            Terrain terrain = hit.collider.GetComponent<Terrain>();
            if (terrain != null)
                currentTerrain = terrain;
        }

        if (currentTerrain)
        {
            TerrainData terrainData = currentTerrain.terrainData;

            Vector3 worldPos1 = new Vector3(col.bounds.min.x, col.transform.position.y, col.bounds.min.z);
            Vector3 worldPos2 = new Vector3(col.bounds.max.x, col.transform.position.y, col.bounds.max.z);

            Vector3 pos1 = getTerrainRelativePosition(worldPos1, currentTerrain);
            Vector3 pos2 = getTerrainRelativePosition(worldPos2, currentTerrain);

            int x1 = Mathf.Clamp((int)pos1.x, 0, terrainData.alphamapWidth - 1);
            int y1 = Mathf.Clamp((int)pos1.y, 0, terrainData.alphamapHeight - 1);
            int x2 = Mathf.Clamp((int)pos2.x, 0, terrainData.alphamapWidth - 1);
            int y2 = Mathf.Clamp((int)pos2.y, 0, terrainData.alphamapHeight - 1);

            int originX = Mathf.Min(x1, x2);
            int originY = Mathf.Min(y1, y2);

            int width = Mathf.Abs(x2 - x1);
            int height = Mathf.Abs(y2 - y1);

            float[,,] alphas = terrainData.GetAlphamaps(originX, originY, width, height);
            int textureIndex = groundTextureIndex;

            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    alphas[i, j, textureIndex] = 1.0f;

                    for (int layer = 0; layer < alphas.GetLength(2); layer++)
                    {
                        if (layer != textureIndex)
                        {
                            alphas[i, j, layer] = 0.0f;
                        }
                    }
                }
            }

            terrainData.SetAlphamaps(originX, originY, alphas);

            if (removeTerrainDetailsToo) // TERRAIN BUSHES
            {
          
            }
            else
            {
                Debug.Log("No terrain detected under player");
            }


        }
    }



    private Vector3 getTerrainRelativePosition(Vector3 pos, Terrain terrain)
    {
        // Terrain terrain = Terrain.activeTerrain;

        Vector3 tempCoord = pos - terrain.gameObject.transform.position;
        Vector3 coord;

        coord.x = tempCoord.x / terrain.terrainData.size.x;
        coord.y = tempCoord.y / terrain.terrainData.size.y;
        coord.z = tempCoord.z / terrain.terrainData.size.z;

        int hmWidth = terrain.terrainData.heightmapResolution;
        int hmHeight = terrain.terrainData.heightmapResolution;

        // get the position of the terrain heightmap where this game object is
        float posXInTerrain = coord.x * hmWidth;
        float posYInTerrain = coord.z * hmHeight;

        return new Vector3(posXInTerrain, posYInTerrain);
    }




}