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(); }
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]; }
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(); } }