public override void draw(float x, float z)
    {
        var random = new System.Random();
        int tot    = terrain.getObjectCount();
        List <TreeInstance> curr  = new List <TreeInstance>();
        List <Vector3>      currp = new List <Vector3>();

        for (int i = 0; i < tot; i++)
        {
            TreeInstance o = terrain.getObject(i);
            Vector3      v = terrain.getObjectLoc(i);
            if (v.x <= x + radius && v.x >= x - radius && v.z <= z + radius && v.z >= z - radius)
            {
                curr.Add(o);
                currp.Add(v);
            }
        }

        int left = maxObjects - curr.Count;

        left = maxObjects;
        if (left > 0)
        {
            Array values = Enum.GetValues(typeof(TreeTextures));
            for (int i = 0; i < left; i++)
            {
                float xi = ((float)random.NextDouble()) * 2.0f - 1;
                float zi = ((float)random.NextDouble()) * 2.0f - 1;
                xi = xi * radius;
                zi = zi * radius;
                Vector3 p = givePos(x, z);
                for (int j = 0; j < currp.Count; j++)
                {
                    Vector3 d = (p - currp[j]);
                    float   D = d.sqrMagnitude;
                    if (D <= min_distance)
                    {
                        p = p + (d * (D + 0.01f));
                    }
                }

                if (p.x <= x + radius && p.x >= x - radius && p.z <= z + radius && p.z >= z - radius)
                {
                    if (zone == Zone.Random)
                    {
                        Zone obs = ((Zone)values.GetValue(random.Next(values.Length)));
                        if (obs == Zone.Random)
                        {
                            obs = Zone.FootHill;
                        }
                        zone = obs;
                    }
                    VegetationConstraint v = terrain.getVegetationFromZone(zone);
                    int index = random.Next(0, v.objects.Length);
                    if (v.objects == null || v.objects.Length == 0)
                    {
                        return;
                    }
                    terrain.object_prefab = v.objects[index];
                    setPrefab(terrain.registerPrefab(terrain.object_prefab));
                    if (v.place(p.x, p.z, ref terrain, true))
                    {
                        currp.Add(p);
                        spawnObject(p.x, p.z);
                    }
                }
                //print("---" + i + 'p'+GetType());
                //terrain.object_prefab;
                //getPrefable, terrain.getObject, terrain.countexistingObejects, check current object index
            }
        }
    }
 protected void fill(float[] weights, int x, int z, int amap_width, int amap_height, int tot_layers, VegetationConstraint v = null)
 {
     float[,,] alphamaps = terrain.getTextures();
     if (!randomPoints)
     {
         for (int h = z - radius; h <= z + radius; h++)
         {
             for (int w = x - radius; w <= x + radius; w++)
             {
                 if (h < 0 || w < 0 || h >= amap_height || w >= amap_width)
                 {
                     continue;
                 }
                 if (v != null && !v.place(w, h, ref terrain))
                 {
                     continue;
                 }
                 float maxCoef = 0;
                 int   maxIdx  = 0;
                 for (int r = weights.Length; r < tot_layers; r++)
                 {
                     alphamaps[h, w, r] = 0.0f;
                 }
                 for (int l = 0; l < weights.Length; l++)
                 {
                     alphamaps[h, w, l] = weights[l];
                     if (weights[l] > maxCoef)
                     {
                         maxCoef = weights[l];
                         maxIdx  = l;
                     }
                 }
                 terrain.setOccupance(h, w, layersType[maxIdx]);
             }
         }
     }
     else
     {
         Vector2[] points = ramdPoints(x, z);
         foreach (Vector2 p in points)
         {
             int h = (int)p.y;
             int w = (int)p.x;
             if (h < 0 || w < 0 || h >= amap_height || w >= amap_width)
             {
                 continue;
             }
             if (v != null && !v.place(w, h, ref terrain))
             {
                 continue;
             }
             float maxCoef = 0;
             int   maxIdx  = 0;
             for (int r = weights.Length; r < tot_layers; r++)
             {
                 alphamaps[h, w, r] = 0.0f;
             }
             for (int l = 0; l < weights.Length; l++)
             {
                 alphamaps[h, w, l] = weights[l];
                 if (weights[l] > maxCoef)
                 {
                     maxCoef = weights[l];
                     maxIdx  = l;
                 }
             }
             terrain.setOccupance(h, w, layersType[maxIdx]);
         }
     }
     terrain.setTextures(alphamaps);
     terrain.saveTextures();
 }