private void Apply(GStylizedTerrain t) { if (t.TerrainData == null) { return; } RenderTexture rt = new RenderTexture(MaskResolution, MaskResolution, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); List <Vector4> vertices = SplineCreator.GenerateVerticesWithFalloff(); Internal_Apply(t, rt, vertices); Texture2D mask = GCommon.CreateTexture(MaskResolution, Color.clear); GCommon.CopyFromRT(mask, rt); mask.wrapMode = TextureWrapMode.Clamp; Color[] maskColors = mask.GetPixels(); if (RemoveTrees) { RemoveTreeOnTerrain(t, maskColors); } if (RemoveGrasses) { RemoveGrassOnTerrain(t, maskColors); t.UpdateGrassPatches(); } t.TerrainData.Foliage.ClearGrassDirtyRegions(); t.TerrainData.SetDirty(GTerrainData.DirtyFlags.Foliage); rt.Release(); GUtilities.DestroyObject(rt); GUtilities.DestroyObject(mask); }
private void OnEnable() { instance = (GStylizedTerrain)target; if (instance.TerrainData != null) { instance.TerrainData.Shading.UpdateMaterials(); } geometryAdditionalContextAction = new List <GGenericMenuItem>(); geometryAdditionalContextAction.Add(new GGenericMenuItem( "Add Height Map Filter", false, () => { GHeightMapFilter filterComponent = instance.GetComponent <GHeightMapFilter>(); if (filterComponent == null) { instance.gameObject.AddComponent <GHeightMapFilter>(); } })); foliageAdditionalContextAction = new List <GGenericMenuItem>(); foliageAdditionalContextAction.Add(new GGenericMenuItem( "Update Trees", false, () => { if (instance.TerrainData != null) { instance.TerrainData.Foliage.SetTreeRegionDirty(new Rect(0, 0, 1, 1)); instance.UpdateTreesPosition(true); instance.TerrainData.Foliage.ClearTreeDirtyRegions(); instance.TerrainData.SetDirty(GTerrainData.DirtyFlags.Foliage); } })); foliageAdditionalContextAction.Add(new GGenericMenuItem( "Update Grasses", false, () => { if (instance.TerrainData != null) { instance.TerrainData.Foliage.SetGrassRegionDirty(new Rect(0, 0, 1, 1)); instance.UpdateGrassPatches(-1, true); instance.TerrainData.Foliage.ClearGrassDirtyRegions(); instance.TerrainData.SetDirty(GTerrainData.DirtyFlags.Foliage); } })); }
private void ClearGrasses(GStylizedTerrain t) { if (t.TerrainData == null) { return; } if (t.TerrainData.Foliage.Grasses == null) { return; } 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), GUtilities.InverseLerpUnclamped(0, terrainSize.y, Scale.y), GUtilities.InverseLerpUnclamped(0, terrainSize.z, Scale.z)); Matrix4x4 matrix = Matrix4x4.TRS( t.WorldPointToNormalized(Position), Rotation, scale); Matrix4x4 normalizeToStamp = matrix.inverse; GGrassPatch[] patches = t.TerrainData.Foliage.GrassPatches; for (int i = 0; i < patches.Length; ++i) { patches[i].Instances.RemoveAll(grass => { Vector3 stampSpacePos = normalizeToStamp.MultiplyPoint(grass.Position); return (stampSpacePos.x >= -0.5f && stampSpacePos.x <= 0.5f && stampSpacePos.y >= 0f && stampSpacePos.y <= 1f && stampSpacePos.z >= -0.5f && stampSpacePos.z <= 0.5f); }); t.TerrainData.Foliage.SetGrassRegionDirty(patches[i].GetUvRange()); } t.UpdateGrassPatches(); t.TerrainData.Foliage.ClearGrassDirtyRegions(); t.TerrainData.SetDirty(GTerrainData.DirtyFlags.Foliage); }
private void Apply(GStylizedTerrain t) { if (t.TerrainData == null) { return; } int heightMapResolution = t.TerrainData.Geometry.HeightMapResolution; RenderTexture rt = new RenderTexture(heightMapResolution, heightMapResolution, 0, GGeometry.HeightMapRTFormat, RenderTextureReadWrite.Linear); List <Vector4> vertices = SplineCreator.GenerateVerticesWithFalloff(); Internal_Apply(t, rt, vertices); Color[] oldHeightMapColors = t.TerrainData.Geometry.HeightMap.GetPixels(); RenderTexture.active = rt; t.TerrainData.Geometry.HeightMap.ReadPixels(new Rect(0, 0, heightMapResolution, heightMapResolution), 0, 0); t.TerrainData.Geometry.HeightMap.Apply(); RenderTexture.active = null; Color[] newHeightMapColors = t.TerrainData.Geometry.HeightMap.GetPixels(); rt.Release(); Object.DestroyImmediate(rt); List <Rect> dirtyRects = new List <Rect>(GCommon.CompareHeightMap(t.TerrainData.Geometry.ChunkGridSize, oldHeightMapColors, newHeightMapColors)); for (int i = 0; i < dirtyRects.Count; ++i) { t.TerrainData.Geometry.SetRegionDirty(dirtyRects[i]); } t.TerrainData.SetDirty(GTerrainData.DirtyFlags.Geometry); for (int i = 0; i < dirtyRects.Count; ++i) { t.TerrainData.Foliage.SetTreeRegionDirty(dirtyRects[i]); t.TerrainData.Foliage.SetGrassRegionDirty(dirtyRects[i]); } t.UpdateTreesPosition(); t.UpdateGrassPatches(); t.TerrainData.Foliage.ClearTreeDirtyRegions(); t.TerrainData.Foliage.ClearGrassDirtyRegions(); t.TerrainData.SetDirty(GTerrainData.DirtyFlags.Foliage); }
private void OnEnable() { terrain = (GStylizedTerrain)target; if (terrain.TerrainData != null) { terrain.TerrainData.Shading.UpdateMaterials(); } geometryAdditionalContextAction = new List <GGenericMenuItem>(); foliageAdditionalContextAction = new List <GGenericMenuItem>(); foliageAdditionalContextAction.Add(new GGenericMenuItem( "Update Trees", false, () => { if (terrain.TerrainData != null) { terrain.TerrainData.Foliage.SetTreeRegionDirty(new Rect(0, 0, 1, 1)); terrain.UpdateTreesPosition(true); terrain.TerrainData.Foliage.ClearTreeDirtyRegions(); terrain.TerrainData.SetDirty(GTerrainData.DirtyFlags.Foliage); } })); foliageAdditionalContextAction.Add(new GGenericMenuItem( "Update Grasses", false, () => { if (terrain.TerrainData != null) { terrain.TerrainData.Foliage.SetGrassRegionDirty(new Rect(0, 0, 1, 1)); terrain.UpdateGrassPatches(-1, true); terrain.TerrainData.Foliage.ClearGrassDirtyRegions(); terrain.TerrainData.SetDirty(GTerrainData.DirtyFlags.Foliage); } })); SceneView.duringSceneGui += DuringSceneGUI; }
public void Paint(GStylizedTerrain terrain, GTexturePainterArgs args) { if (terrain.TerrainData == null) { return; } if (args.MouseEventType == GPainterMouseEventType.Down) { terrain.ForceLOD(0); GGriffinSettings.Instance.IsHidingFoliageOnEditing = true; } if (args.MouseEventType == GPainterMouseEventType.Up) { terrain.ForceLOD(-1); GGriffinSettings.Instance.IsHidingFoliageOnEditing = false; terrain.UpdateTreesPosition(); terrain.UpdateGrassPatches(); terrain.TerrainData.Foliage.ClearTreeDirtyRegions(); terrain.TerrainData.Foliage.ClearGrassDirtyRegions(); return; } Vector2[] uvCorners = new Vector2[args.WorldPointCorners.Length]; for (int i = 0; i < uvCorners.Length; ++i) { uvCorners[i] = terrain.WorldPointToUV(args.WorldPointCorners[i]); } Rect dirtyRect = GUtilities.GetRectContainsPoints(uvCorners); if (!dirtyRect.Overlaps(new Rect(0, 0, 1, 1))) { return; } Texture2D bg = terrain.TerrainData.Geometry.HeightMap; int heightMapResolution = terrain.TerrainData.Geometry.HeightMapResolution; RenderTexture rt = GTerrainTexturePainter.Internal_GetRenderTexture(heightMapResolution); GCommon.CopyToRT(bg, rt); Material mat = GInternalMaterials.SubDivPainterMaterial; mat.SetTexture("_MainTex", bg); mat.SetTexture("_Mask", args.Mask); mat.SetFloat("_Opacity", args.Opacity); int pass = args.ActionType == GPainterActionType.Normal ? 0 : args.ActionType == GPainterActionType.Negative ? 1 : 0; GCommon.DrawQuad(rt, uvCorners, mat, pass); RenderTexture.active = rt; terrain.TerrainData.Geometry.HeightMap.ReadPixels( new Rect(0, 0, heightMapResolution, heightMapResolution), 0, 0); terrain.TerrainData.Geometry.HeightMap.Apply(); RenderTexture.active = null; terrain.TerrainData.Geometry.SetRegionDirty(dirtyRect); terrain.TerrainData.Foliage.SetTreeRegionDirty(dirtyRect); terrain.TerrainData.Foliage.SetGrassRegionDirty(dirtyRect); terrain.TerrainData.SetDirty(GTerrainData.DirtyFlags.Geometry); }
private void Apply(GStylizedTerrain t) { if (t.TerrainData == null) { return; } if (Layers.Count == 0) { return; } GetQuad(worldPoints); GetUvPoints(t, worldPoints, uvPoints); Rect dirtyRect = GUtilities.GetRectContainsPoints(uvPoints); if (!dirtyRect.Overlaps(new Rect(0, 0, 1, 1))) { return; } RenderTexture[] brushes = new RenderTexture[Layers.Count]; for (int i = 0; i < Layers.Count; ++i) { brushes[i] = GetRenderTexture("brush" + i.ToString()); } Internal_RenderBrushes(brushes, t, uvPoints); for (int i = 0; i < Layers.Count; ++i) { StampLayer(t, brushes[i], i); } bool willUpdateTree = Layers.Exists(l => l.StampTrees && l.TreeInstanceCount > 0); bool willUpdateGrass = Layers.Exists(l => l.StampGrasses && l.TreeInstanceCount > 0); #if UNITY_EDITOR string title = "Stamping on " + t.name; string info = "Finishing up..."; GCommonGUI.ProgressBar(title, info, 1); #endif try { t.TerrainData.Foliage.SetTreeRegionDirty(dirtyRect); t.TerrainData.Foliage.SetGrassRegionDirty(dirtyRect); if (willUpdateTree) { t.UpdateTreesPosition(); } if (willUpdateGrass) { t.UpdateGrassPatches(-1, true); } t.TerrainData.Foliage.ClearTreeDirtyRegions(); t.TerrainData.Foliage.ClearGrassDirtyRegions(); } catch (System.Exception e) { Debug.LogError(e); } #if UNITY_EDITOR GCommonGUI.ClearProgressBar(); #endif t.TerrainData.SetDirty(GTerrainData.DirtyFlags.Foliage); }
private void ImportDataAndCreateTerrain() { GameObject terrainRoot = new GameObject(string.Format("{0}-{1}", Root.name, ConversionName)); terrainRoot.transform.parent = Root.transform.parent; terrainRoot.transform.position = Root.transform.position; for (int i = 0; i < Terrains.Count; ++i) { #if UNITY_EDITOR GCommonGUI.CancelableProgressBar("Converting", "Converting " + Terrains[i].name, 1f); #endif GTerrainData data = ScriptableObject.CreateInstance <GTerrainData>(); if (DataTemplate != null) { DataTemplate.Geometry.CopyTo(data.Geometry); DataTemplate.Shading.CopyTo(data.Shading); DataTemplate.Rendering.CopyTo(data.Rendering); DataTemplate.Foliage.CopyTo(data.Foliage); DataTemplate.Mask.CopyTo(data.Mask); } else { if (Application.isPlaying) //Reset() only called in edit mode { data.Reset(); data.Geometry.Reset(); data.Shading.Reset(); data.Rendering.Reset(); data.Foliage.Reset(); data.Mask.Reset(); } } #if UNITY_EDITOR if (!Application.isPlaying) { string assetName = "TerrainData_" + data.Id; AssetDatabase.CreateAsset(data, string.Format("{0}.asset", Path.Combine(DataDirectory, assetName))); } #endif Material templateMaterial = null; if (DataTemplate != null) { templateMaterial = DataTemplate.Shading.CustomMaterial; } Material material = null; if (templateMaterial != null) { material = new Material(templateMaterial.shader); } else { if (ImportSplats) { if (ImportSplatsAsAlbedo && AlbedoUsage == GAlbedoUsage.ColorMap) { material = GRuntimeSettings.Instance.terrainRendering.GetClonedMaterial(GCommon.CurrentRenderPipeline, GLightingModel.PBR, GTexturingModel.ColorMap); } else if (ImportSplatsAsAlbedo && AlbedoUsage == GAlbedoUsage.VertexColor) { material = GRuntimeSettings.Instance.terrainRendering.GetClonedMaterial(GCommon.CurrentRenderPipeline, GLightingModel.PBR, GTexturingModel.VertexColor); data.Geometry.AlbedoToVertexColorMode = GAlbedoToVertexColorMode.Sharp; } else { GSplatPrototypeGroup splats = DataTemplate ? DataTemplate.Shading.Splats : SplatGroups[SplatGroupIndices[i]]; GSplatsModel splatModel = (splats == null || splats.Prototypes.Count <= 4) ? GSplatsModel.Splats4Normals4 : GSplatsModel.Splats8; material = GRuntimeSettings.Instance.terrainRendering.GetClonedMaterial(GCommon.CurrentRenderPipeline, GLightingModel.PBR, GTexturingModel.Splat, splatModel); } } else { material = GRuntimeSettings.Instance.terrainRendering.GetClonedMaterial(GCommon.CurrentRenderPipeline, GLightingModel.PBR, GTexturingModel.Splat, GSplatsModel.Splats4); } } data.Shading.CustomMaterial = material; #if UNITY_EDITOR if (!Application.isPlaying && material != null) { string matName = "TerrainMaterial_" + data.Id; material.name = matName; AssetDatabase.CreateAsset(material, string.Format("{0}.mat", Path.Combine(DataDirectory, matName))); } #endif if (ImportSplats) { data.Shading.Splats = DataTemplate ? DataTemplate.Shading.Splats : SplatGroups[SplatGroupIndices[i]]; data.Shading.UpdateMaterials(); } if (ImportTrees) { data.Foliage.Trees = DataTemplate ? DataTemplate.Foliage.Trees : TreeGroups[TreeGroupIndices[i]]; } if (ImportGrasses) { data.Foliage.Grasses = DataTemplate ? DataTemplate.Foliage.Grasses : GrassGroups[GrassGroupIndices[i]]; } GUnityTerrainDataImporter importer = new GUnityTerrainDataImporter(); importer.SrcData = Terrains[i].terrainData; importer.SrcTerrain = Terrains[i]; importer.DesData = data; importer.DesTerrain = null; importer.ImportGeometry = ImportGeometry; importer.UseUnityTerrainSize = true; importer.ImportSplats = ImportSplats; importer.ImportSplatsAsAlbedo = ImportSplatsAsAlbedo; importer.ImportSplatControlMapsOnly = DataTemplate != null && DataTemplate.Shading.Splats != null; importer.ImportSplatControlMapResolution = DataTemplate == null; importer.CreateNewSplatPrototypesGroup = false; importer.ImportTrees = ImportTrees; importer.ImportTreeInstancesOnly = DataTemplate != null && DataTemplate.Foliage.Trees != null; importer.CreateNewTreePrototypesGroup = false; importer.ImportGrasses = ImportGrasses; importer.ImportGrassInstancesOnly = DataTemplate != null && DataTemplate.Foliage.Grasses != null; importer.CreateNewGrassPrototypesGroup = false; importer.GrassDensity = 1; importer.SkipFoliageSnap = SkipFoliageSnap; importer.Import(); GStylizedTerrain t = CreateTerrain(); t.transform.parent = terrainRoot.transform; t.transform.position = Terrains[i].transform.position; t.name = Terrains[i].name; #if UNITY_2018_3_OR_NEWER t.GroupId = Terrains[i].groupingID; #endif t.TerrainData = data; if (ImportTrees || ImportGrasses) { data.Foliage.SetTreeRegionDirty(GCommon.UnitRect); data.Foliage.SetGrassRegionDirty(GCommon.UnitRect); t.UpdateTreesPosition(); t.UpdateGrassPatches(); data.Foliage.ClearTreeDirtyRegions(); data.Foliage.ClearGrassDirtyRegions(); } ConvertedTerrains.Add(t); #if UNITY_EDITOR //SaveAssets(); GCommonGUI.ClearProgressBar(); #endif } }