Пример #1
0
        void FillTerrain(MicroSplatTerrainJob t, int channel, float val)
        {
            InitTerrains();
            t.RegisterUndo();
            Texture2D tex    = t.terrainTex;
            int       width  = tex.width;
            int       height = tex.height;

            for (int x = 0; x < width; ++x)
            {
                for (int y = 0; y < height; ++y)
                {
                    var c = tex.GetPixel(x, y);

                    Vector3 normal = t.terrain.terrainData.GetInterpolatedNormal((float)x / tex.width, (float)y / tex.height);
                    float   dt     = Vector3.Dot(normal, Vector3.up);
                    dt = 1 - Mathf.Clamp01(dt);
                    bool filtered = dt <slopeRange.x || dt> slopeRange.y;

                    if (!filtered)
                    {
                        c[channel] = val;

                        tex.SetPixel(x, y, c);
                    }
                }
            }
            tex.Apply();
        }
Пример #2
0
        void InitTerrains()
        {
            Object[] objs = Selection.GetFiltered(typeof(Terrain), SelectionMode.Editable | SelectionMode.OnlyUserModifiable | SelectionMode.Deep);
            List <MicroSplatTerrainJob> ts = new List <MicroSplatTerrainJob>();

            rawTerrains.Clear();
            for (int i = 0; i < objs.Length; ++i)
            {
                Terrain           t   = objs[i] as Terrain;
                MicroSplatTerrain mst = t.GetComponent <MicroSplatTerrain>();
                if (mst == null)
                {
                    continue;
                }
                rawTerrains.Add(t);
                if (t.materialType == Terrain.MaterialType.Custom && t.materialTemplate != null)
                {
                    if (!t.materialTemplate.HasProperty("_StreamControl"))
                    {
                        continue;
                    }
                    if (mst.streamTexture == null)
                    {
                        CreateTexture(t);
                    }

                    var tj = FindJob(t);
                    if (tj != null)
                    {
                        tj.collider   = t.GetComponent <Collider>();
                        tj.terrainTex = mst.streamTexture;
                        ts.Add(tj);
                    }
                    else
                    {
                        tj            = MicroSplatTerrainJob.CreateInstance <MicroSplatTerrainJob>();
                        tj.terrain    = t;
                        tj.collider   = t.GetComponent <Collider>();
                        tj.terrainTex = mst.streamTexture;
                        ts.Add(tj);
                    }
                }
            }
            if (terrains != null)
            {
                // clear out old terrains
                for (int i = 0; i < terrains.Length; ++i)
                {
                    if (!ts.Contains(terrains[i]))
                    {
                        DestroyImmediate(terrains[i]);
                    }
                }
            }

            terrains = ts.ToArray();
            jobEdits = new bool[ts.Count];
        }
Пример #3
0
        void PaintTerrain(MicroSplatTerrainJob tj, Vector3 worldPoint, Vector2 uv)
        {
            if (tj == null || tj.terrainTex == null)
            {
                return;
            }

            // convert point into local space, so we don't have to convert every point
            var     mtx        = Matrix4x4.TRS(tj.terrain.transform.position, tj.terrain.transform.rotation, Vector3.one).inverse;
            Vector3 localPoint = mtx.MultiplyPoint3x4(worldPoint);

            float bz = brushSize;

            float pressure = Event.current.pressure > 0 ? Event.current.pressure : 1.0f;

            Texture2D splatTex = tj.terrainTex;

            if (splatTex == null)
            {
                return;
            }
            Vector3 terPoint = WorldToTerrain(tj.terrain, localPoint, splatTex);

            if (terPoint.x >= 0 && terPoint.z >= 0 && terPoint.x < splatTex.width || terPoint.z < splatTex.height)
            {
                // scale brush into texture space
                Vector3 offsetPnt   = localPoint - new Vector3(bz, 0, bz);
                Vector3 beginTerPnt = WorldToTerrain(tj.terrain, offsetPnt, splatTex);
                beginTerPnt.x = Mathf.Clamp(beginTerPnt.x, 0, splatTex.width);
                beginTerPnt.z = Mathf.Clamp(beginTerPnt.z, 0, splatTex.height);

                Vector3 offset = terPoint - beginTerPnt;
                int     pbx    = (int)beginTerPnt.x;
                int     pby    = (int)beginTerPnt.z;
                int     pex    = (int)(terPoint.x + offset.x * 2.0f);
                int     pey    = (int)(terPoint.z + offset.z * 2.0f);

                pex = Mathf.Clamp(pex, 0, splatTex.width);
                pey = Mathf.Clamp(pey, 0, splatTex.height);

                for (int x = pbx; x < pex; ++x)
                {
                    for (int y = pby; y < pey; ++y)
                    {
                        float h   = tj.terrain.terrainData.GetHeight(x, y);
                        float d   = Vector3.Distance(terPoint, new Vector3(x, h, y));
                        float str = 1.0f - d / bz;
                        str = Mathf.Pow(str, brushFalloff);
                        float finalStr = str * (float)deltaTime * brushFlow * pressure;
                        if (finalStr > 0)
                        {
                            Vector3 normal = tj.terrain.terrainData.GetInterpolatedNormal((float)x / splatTex.width, (float)y / splatTex.height);
                            float   dt     = Vector3.Dot(normal, Vector3.up);
                            dt = 1 - Mathf.Clamp01(dt);
                            bool filtered = dt <slopeRange.x || dt> slopeRange.y;
                            if (!filtered)
                            {
                                if (tab == Tab.Wetness)
                                {
                                    Color c = splatTex.GetPixel(x, y);
                                    c.r = Mathf.Lerp(c.r, paintValue, finalStr);
                                    splatTex.SetPixel(x, y, c);
                                }
                                else if (tab == Tab.Puddles)
                                {
                                    Color c = splatTex.GetPixel(x, y);
                                    c.g = Mathf.Lerp(c.g, paintValue, finalStr);
                                    splatTex.SetPixel(x, y, c);
                                }
                                else if (tab == Tab.Streams)
                                {
                                    Color c = splatTex.GetPixel(x, y);
                                    c.b = Mathf.Lerp(c.b, paintValue, finalStr);
                                    splatTex.SetPixel(x, y, c);
                                }
                                else if (tab == Tab.Lava)
                                {
                                    Color c = splatTex.GetPixel(x, y);
                                    c.a = Mathf.Lerp(c.a, paintValue, finalStr);
                                    splatTex.SetPixel(x, y, c);
                                }
                            }
                        }
                    }
                }
                splatTex.Apply();
            }
        }