Esempio n. 1
0
        private void RemoveGrassOnTerrain(GStylizedTerrain t, Color[] maskData)
        {
            GGrassPatch[] patches = t.TerrainData.Foliage.GrassPatches;
            for (int p = 0; p < patches.Length; ++p)
            {
                for (int i = 0; i < GrassPrototypeIndices.Count; ++i)
                {
                    int grassIndex           = GrassPrototypeIndices[i];
                    int removedInstanceCount = patches[p].Instances.RemoveAll(grass =>
                    {
                        if (grass.PrototypeIndex != grassIndex)
                        {
                            return(false);
                        }
                        Vector2 uv  = new Vector2(grass.Position.x, grass.Position.z);
                        float alpha = GUtilities.GetColorBilinear(maskData, MaskResolution, MaskResolution, uv).r;
                        return(Random.value <= alpha);
                    });

                    if (removedInstanceCount > 0)
                    {
                        t.TerrainData.Foliage.SetGrassRegionDirty(patches[p].GetUvRange());
                    }
                }
            }
        }
        private void SpawnGrassesOnTerrain(GStylizedTerrain t, Color[] maskData, List <Vector4> vertices)
        {
            int grassIndex = -1;
            List <GGrassInstance> grassInstances = new List <GGrassInstance>();
            Vector2 v0          = Vector2.zero;
            Vector2 v1          = Vector2.zero;
            Vector2 v2          = Vector2.zero;
            Vector2 center      = Vector2.zero;
            float   radius      = 0;
            Vector2 pos         = Vector2.zero;
            Vector3 bary        = Vector3.zero;
            float   maskValue   = 0;
            int     sampleCount = Mathf.Clamp(GrassDensity * GrassDensity / 10, 1, 1000);

            int trisCount = vertices.Count / 3;

            for (int i = 0; i < trisCount; ++i)
            {
                v0 = t.WorldPointToUV(vertices[i * 3 + 0]);
                v1 = t.WorldPointToUV(vertices[i * 3 + 1]);
                v2 = t.WorldPointToUV(vertices[i * 3 + 2]);

                center = (v0 + v1 + v2) / 3;
                radius = Vector2.Distance(center, v0);

                for (int s = 0; s < sampleCount; ++s)
                {
                    grassIndex = GrassPrototypeIndices[Random.Range(0, GrassPrototypeIndices.Count)];
                    pos        = center + Random.insideUnitCircle * radius;
                    if (pos.x < 0 || pos.x > 1 ||
                        pos.y < 0 || pos.x > 1)
                    {
                        continue;
                    }

                    GUtilities.CalculateBarycentricCoord(pos, v0, v1, v2, ref bary);
                    if (bary.x < 0 || bary.y < 0 || bary.z < 0)
                    {
                        continue;
                    }

                    maskValue = GUtilities.GetColorBilinear(maskData, MaskResolution, MaskResolution, pos).r;
                    if (Random.value > maskValue)
                    {
                        continue;
                    }

                    GGrassInstance grass = GGrassInstance.Create(grassIndex);
                    grass.Position = new Vector3(pos.x, 0, pos.y);
                    grass.Rotation = Quaternion.Euler(0, Random.Range(MinRotation, MaxRotation), 0);
                    grass.Scale    = Vector3.Lerp(MinScale, MaxScale, Random.value);

                    grassInstances.Add(grass);
                }
            }

            t.TerrainData.Foliage.AddGrassInstances(grassInstances);
        }
Esempio n. 3
0
 private void RemoveTreeOnTerrain(GStylizedTerrain t, Color[] maskData)
 {
     for (int i = 0; i < TreePrototypeIndices.Count; ++i)
     {
         int treeIndex = TreePrototypeIndices[i];
         t.TerrainData.Foliage.RemoveTreeInstances(tree =>
         {
             if (tree.PrototypeIndex != treeIndex)
             {
                 return(false);
             }
             Vector2 uv  = new Vector2(tree.Position.x, tree.Position.z);
             float alpha = GUtilities.GetColorBilinear(maskData, MaskResolution, MaskResolution, uv).r;
             return(Random.value <= alpha);
         });
     }
 }
        private void RemoveObjectFromTerrain(GStylizedTerrain t, Color[] maskData)
        {
            for (int i = 0; i < PrototypeIndices.Count; ++i)
            {
                int prototypeIndex = PrototypeIndices[i];
                if (prototypeIndex < 0 || prototypeIndex >= Prototypes.Count)
                {
                    continue;
                }
                GameObject g = Prototypes[prototypeIndex];
                if (g == null)
                {
                    continue;
                }

                GSpawner.DestroyIf(t, g, (instance) =>
                {
                    Vector2 uv  = t.WorldPointToUV(instance.transform.position);
                    float alpha = GUtilities.GetColorBilinear(maskData, MaskResolution, MaskResolution, uv).r;
                    return(Random.value <= alpha);
                });
            }
        }
Esempio n. 5
0
        private void SpawnGrassOnTerrain(GStylizedTerrain t, Color[] maskData, int layerIndex)
        {
            GFoliageStampLayer layer     = Layers[layerIndex];
            Vector3            centerPos = Vector3.zero;
            Vector3            samplePos = Vector3.zero;
            Vector2            uv        = Vector2.zero;
            float   maskValue            = 0;
            Vector3 terrainSize          = new Vector3(
                t.TerrainData.Geometry.Width,
                t.TerrainData.Geometry.Height,
                t.TerrainData.Geometry.Length);
            Vector3 scale = new Vector3(
                GUtilities.InverseLerpUnclamped(0, terrainSize.x, Scale.x),
                1,
                GUtilities.InverseLerpUnclamped(0, terrainSize.z, Scale.z));
            Matrix4x4 matrix = Matrix4x4.TRS(
                t.WorldPointToNormalized(Position),
                Rotation,
                scale);

            int grassIndex                = -1;
            int instanceCount             = 0;
            int attempt                   = 0;
            int maxAttempt                = layer.GrassInstanceCount * 100;
            List <GGrassInstance> grasses = new List <GGrassInstance>();

#if UNITY_EDITOR
            string title           = "Stamping on " + t.name;
            string info            = string.Format("Layer: {0}", !string.IsNullOrEmpty(layer.Name) ? layer.Name : layerIndex.ToString());
            int    currentPercent  = 0;
            int    attemptPercent  = 0;
            int    instancePercent = 0;
            GCommonGUI.CancelableProgressBar(title, info, 0);
#endif

            while (instanceCount < layer.GrassInstanceCount && attempt <= maxAttempt)
            {
                attempt += 1;

#if UNITY_EDITOR
                attemptPercent  = (int)(attempt * 100.0f / maxAttempt);
                instancePercent = (int)(instanceCount * 100.0f / layer.GrassInstanceCount);
                if (currentPercent != Mathf.Max(attemptPercent, instancePercent))
                {
                    currentPercent = Mathf.Max(attemptPercent, instancePercent);
                    GCommonGUI.CancelableProgressBar(title, string.Format("{0} ... {1}%", info, currentPercent), currentPercent / 100.0f);
                }
#endif

                grassIndex = layer.GrassIndices[Random.Range(0, layer.GrassIndices.Count)];

                centerPos.Set(Random.value - 0.5f, 0, Random.value - 0.5f);
                samplePos = matrix.MultiplyPoint(centerPos);
                if (samplePos.x < 0 || samplePos.x > 1 ||
                    samplePos.z < 0 || samplePos.z > 1)
                {
                    continue;
                }
                uv.Set(samplePos.x, samplePos.z);
                maskValue = GUtilities.GetColorBilinear(maskData, MaskResolution, MaskResolution, uv).r;
                if (Random.value > maskValue)
                {
                    continue;
                }

                GGrassInstance grass = GGrassInstance.Create(grassIndex);
                grass.Position = new Vector3(samplePos.x, 0, samplePos.z);
                grass.Rotation = Quaternion.Euler(0, Random.Range(layer.MinRotation, layer.MaxRotation), 0);
                grass.Scale    = Vector3.Lerp(layer.MinScale, layer.MaxScale, Random.value);

                grasses.Add(grass);
                instanceCount += 1;
            }

            t.TerrainData.Foliage.AddGrassInstances(grasses);

#if UNITY_EDITOR
            GCommonGUI.ClearProgressBar();
#endif
        }
        private void SpawnObjectOnTerrain(GStylizedTerrain t, Color[] maskData, int layerIndex)
        {
            GObjectStampLayer layer       = Layers[layerIndex];
            Vector3           centerPos   = Vector3.zero;
            Vector3           samplePos   = Vector3.zero;
            Vector2           uv          = Vector2.zero;
            float             maskValue   = 0;
            Vector3           terrainSize = new Vector3(
                t.TerrainData.Geometry.Width,
                t.TerrainData.Geometry.Height,
                t.TerrainData.Geometry.Length);
            Vector3 scale = new Vector3(
                GUtilities.InverseLerpUnclamped(0, terrainSize.x, Scale.x),
                1,
                GUtilities.InverseLerpUnclamped(0, terrainSize.z, Scale.z));
            Matrix4x4 matrix = Matrix4x4.TRS(
                t.WorldPointToNormalized(Position),
                Rotation,
                scale);

            int        index         = -1;
            int        instanceCount = 0;
            int        attempt       = 0;
            int        maxAttempt    = layer.InstanceCount * 100;
            RaycastHit hit;

#if UNITY_EDITOR
            string title           = "Stamping on " + t.name;
            string info            = string.Format("Layer: {0}", !string.IsNullOrEmpty(layer.Name) ? layer.Name : layerIndex.ToString());
            int    currentPercent  = 0;
            int    attemptPercent  = 0;
            int    instancePercent = 0;
            GCommonGUI.CancelableProgressBar(title, info, 0);
#endif

            while (instanceCount < layer.InstanceCount && attempt <= maxAttempt)
            {
                attempt += 1;

#if UNITY_EDITOR
                attemptPercent  = (int)(attempt * 100.0f / maxAttempt);
                instancePercent = (int)(instanceCount * 100.0f / layer.InstanceCount);
                if (currentPercent != Mathf.Max(attemptPercent, instancePercent))
                {
                    currentPercent = Mathf.Max(attemptPercent, instancePercent);
                    GCommonGUI.CancelableProgressBar(title, string.Format("{0} ... {1}%", info, currentPercent), currentPercent / 100.0f);
                }
#endif

                index = layer.PrototypeIndices[Random.Range(0, layer.PrototypeIndices.Count)];
                if (index < 0 || index >= layer.Prototypes.Count)
                {
                    continue;
                }
                GameObject g = layer.Prototypes[index];
                if (g == null)
                {
                    continue;
                }

                centerPos.Set(Random.value - 0.5f, 0, Random.value - 0.5f);
                samplePos = matrix.MultiplyPoint(centerPos);
                if (samplePos.x < 0 || samplePos.x > 1 ||
                    samplePos.z < 0 || samplePos.z > 1)
                {
                    continue;
                }
                uv.Set(samplePos.x, samplePos.z);
                maskValue = GUtilities.GetColorBilinear(maskData, MaskResolution, MaskResolution, uv).r;
                if (Random.value > maskValue)
                {
                    continue;
                }

                if (t.Raycast(samplePos, out hit))
                {
                    GameObject instance = GSpawner.Spawn(t, g, hit.point);
                    instance.transform.rotation   = Quaternion.Euler(0, Random.Range(layer.MinRotation, layer.MaxRotation), 0);
                    instance.transform.localScale = Vector3.Lerp(layer.MinScale, layer.MaxScale, Random.value);
                    if (layer.AlignToSurface)
                    {
                        instance.transform.up = hit.normal;
                    }

                    instanceCount += 1;
                }
            }
#if UNITY_EDITOR
            GCommonGUI.ClearProgressBar();
#endif
        }
Esempio n. 7
0
        private void SpawnObjectsOnTerrain(GStylizedTerrain t, Color[] maskData, List <Vector4> vertices)
        {
            int        prototypeIndex = -1;
            Vector2    v0             = Vector2.zero;
            Vector2    v1             = Vector2.zero;
            Vector2    v2             = Vector2.zero;
            Vector2    center         = Vector2.zero;
            float      radius         = 0;
            Vector2    pos            = Vector2.zero;
            Vector3    bary           = Vector3.zero;
            float      maskValue      = 0;
            RaycastHit hit;

            int trisCount = vertices.Count / 3;

            for (int i = 0; i < trisCount; ++i)
            {
                v0 = t.WorldPointToUV(vertices[i * 3 + 0]);
                v1 = t.WorldPointToUV(vertices[i * 3 + 1]);
                v2 = t.WorldPointToUV(vertices[i * 3 + 2]);

                center = (v0 + v1 + v2) / 3;
                radius = Vector2.Distance(center, v0);

                for (int s = 0; s < Density; ++s)
                {
                    prototypeIndex = PrototypeIndices[Random.Range(0, PrototypeIndices.Count)];
                    if (prototypeIndex < 0 || prototypeIndex >= Prototypes.Count)
                    {
                        continue;
                    }
                    GameObject g = Prototypes[prototypeIndex];
                    if (g == null)
                    {
                        continue;
                    }

                    pos = center + Random.insideUnitCircle * radius;
                    if (pos.x < 0 || pos.x > 1 ||
                        pos.y < 0 || pos.x > 1)
                    {
                        continue;
                    }

                    GUtilities.CalculateBarycentricCoord(pos, v0, v1, v2, ref bary);
                    if (bary.x < 0 || bary.y < 0 || bary.z < 0)
                    {
                        continue;
                    }

                    maskValue = GUtilities.GetColorBilinear(maskData, MaskResolution, MaskResolution, pos).r;
                    if (Random.value > maskValue)
                    {
                        continue;
                    }

                    if (t.Raycast(pos.ToX0Y(), out hit))
                    {
                        GameObject instance = GSpawner.Spawn(t, g, hit.point);
                        instance.transform.rotation   = Quaternion.Euler(0, Random.Range(MinRotation, MaxRotation), 0);
                        instance.transform.localScale = Vector3.Lerp(MinScale, MaxScale, Random.value);
                        if (AlignToSurface)
                        {
                            instance.transform.up = hit.normal;
                        }
                    }
                }
            }
        }
Esempio n. 8
0
        private void SpawnTreesOnTerrain(GStylizedTerrain t, Color[] maskData, List <Vector4> vertices)
        {
            int     treeIndex      = -1;
            Vector2 v0             = Vector2.zero;
            Vector2 v1             = Vector2.zero;
            Vector2 v2             = Vector2.zero;
            Vector2 center         = Vector2.zero;
            float   radius         = 0;
            Vector2 pos            = Vector2.zero;
            Vector3 bary           = Vector3.zero;
            float   maskValue      = 0;
            int     prototypeCount = t.TerrainData.Foliage.Trees.Prototypes.Count;

            List <GTreeInstance> newInstances = new List <GTreeInstance>();
            int trisCount = vertices.Count / 3;

            for (int i = 0; i < trisCount; ++i)
            {
                v0 = t.WorldPointToUV(vertices[i * 3 + 0]);
                v1 = t.WorldPointToUV(vertices[i * 3 + 1]);
                v2 = t.WorldPointToUV(vertices[i * 3 + 2]);

                center = (v0 + v1 + v2) / 3;
                radius = Vector2.Distance(center, v0);

                for (int s = 0; s < TreeDensity; ++s)
                {
                    treeIndex = TreePrototypeIndices[Random.Range(0, TreePrototypeIndices.Count)];
                    if (treeIndex < 0 || treeIndex >= prototypeCount)
                    {
                        continue;
                    }

                    pos = center + Random.insideUnitCircle * radius;
                    if (pos.x < 0 || pos.x > 1 ||
                        pos.y < 0 || pos.x > 1)
                    {
                        continue;
                    }

                    GUtilities.CalculateBarycentricCoord(pos, v0, v1, v2, ref bary);
                    if (bary.x < 0 || bary.y < 0 || bary.z < 0)
                    {
                        continue;
                    }

                    maskValue = GUtilities.GetColorBilinear(maskData, MaskResolution, MaskResolution, pos).r;
                    if (Random.value > maskValue)
                    {
                        continue;
                    }


                    GTreeInstance tree = GTreeInstance.Create(treeIndex);
                    tree.Position = new Vector3(pos.x, 0, pos.y);
                    tree.Rotation = Quaternion.Euler(0, Random.Range(MinRotation, MaxRotation), 0);
                    tree.Scale    = Vector3.Lerp(MinScale, MaxScale, Random.value);

                    newInstances.Add(tree);
                }
            }
            t.TerrainData.Foliage.AddTreeInstances(newInstances);
            newInstances.Clear();
        }