Rasagar/Library/PackageCache/com.unity.terrain-tools/Editor/TerrainTools/BrushControllers/BrushRenderWithTerrainUiGroup.cs

221 lines
8.5 KiB
C#
Raw Normal View History

2024-08-26 13:07:20 -07:00
using UnityEngine;
using UnityEngine.TerrainTools;
namespace UnityEditor.TerrainTools
{
internal class BrushRenderWithTerrainUIGroup : IBrushRenderWithTerrain
{
private readonly IBrushUIGroup m_UiGroup;
private readonly string m_Name;
private readonly Texture m_BrushTexture;
private PaintContext m_HeightmapContext;
private bool m_WriteToHeightmap;
private PaintContext m_TextureContext;
private bool m_WriteToTexture;
private PaintContext m_NormalmapContext;
private bool m_WriteToHoles;
private PaintContext m_HolesContext;
private float brushSize => m_UiGroup.brushSize;
private float brushRotation => m_UiGroup.brushRotation;
private float brushStrength => m_UiGroup.brushStrength;
public IBrushUIGroup uiGroup => m_UiGroup;
public Texture brushTexture => m_BrushTexture;
public BrushRenderWithTerrainUIGroup(IBrushUIGroup uiGroup, string name, Texture brushTexture)
{
m_UiGroup = uiGroup;
m_Name = name;
m_BrushTexture = brushTexture;
}
public virtual bool CalculateBrushTransform(Terrain terrain, Vector2 uv, float size, float rotation, out BrushTransform brushTransform)
{
if (m_UiGroup.ScatterBrushStamp(ref terrain, ref uv))
{
brushTransform = TerrainPaintUtility.CalculateBrushTransform(terrain, uv, size, rotation);
return true;
}
else
{
brushTransform = new BrushTransform();
return false;
}
}
public bool CalculateBrushTransform(Terrain terrain, Vector2 uv, float size, out BrushTransform brushTransform)
{
return CalculateBrushTransform(terrain, uv, size, brushRotation, out brushTransform);
}
public bool CalculateBrushTransform(Terrain terrain, Vector2 uv, out BrushTransform brushTransform)
{
return CalculateBrushTransform(terrain, uv, brushSize, brushRotation, out brushTransform);
}
public void SetupTerrainToolMaterialProperties(PaintContext paintContext, BrushTransform brushTransform, Material material)
{
Utility.SetupMaterialForPainting(paintContext, brushTransform, material);
}
public void RenderBrush(PaintContext paintContext, Material material, int pass)
{
Texture sourceTexture = paintContext.sourceRenderTexture;
RenderTexture destinationTexture = paintContext.destinationRenderTexture;
Graphics.Blit(sourceTexture, destinationTexture, material, pass);
}
public PaintContext AcquireHeightmap(bool writable, Terrain terrain, Rect boundsInTerrainSpace, int extraBorderPixels = 0)
{
if (m_HeightmapContext != null) return m_HeightmapContext;
m_WriteToHeightmap = writable;
m_HeightmapContext = TerrainPaintUtility.BeginPaintHeightmap(terrain, boundsInTerrainSpace, extraBorderPixels);
if (m_HeightmapContext == null)
return null;
m_HeightmapContext.sourceRenderTexture.name = $"{m_Name}::HeightmapContext::SourceRT";
m_HeightmapContext.destinationRenderTexture.name = $"{m_Name}::HeightmapContext::DestRT";
return m_HeightmapContext;
}
public PaintContext AcquireTexture(bool writable, Terrain terrain, Rect boundsInTerrainSpace, TerrainLayer layer, int extraBorderPixels = 0)
{
if (m_TextureContext != null) return m_TextureContext;
m_WriteToTexture = writable;
m_TextureContext = TerrainPaintUtility.BeginPaintTexture(terrain, boundsInTerrainSpace, layer, extraBorderPixels);
if (m_TextureContext == null)
return null;
m_TextureContext.sourceRenderTexture.name = $"{m_Name}::TextureContext::SourceRT";
m_TextureContext.destinationRenderTexture.name = $"{m_Name}::TextureContext::DestRT";
return m_TextureContext;
}
public PaintContext AcquireNormalmap(bool writable, Terrain terrain, Rect boundsInTerrainSpace, int extraBorderPixels = 0)
{
if (m_NormalmapContext != null) return m_NormalmapContext;
m_NormalmapContext = TerrainPaintUtility.CollectNormals(terrain, boundsInTerrainSpace, extraBorderPixels);
if (m_NormalmapContext == null)
return null;
m_NormalmapContext.sourceRenderTexture.name = $"{m_Name}::NormalContext::SourceRT";
m_NormalmapContext.destinationRenderTexture.name = $"{m_Name}::NormalContext::DestRT";
return m_NormalmapContext;
}
public PaintContext AcquireHolesTexture(bool writable, Terrain terrain, Rect boundsInTerrainSpace, int extraBorderPixels = 0)
{
if (m_HolesContext != null) return m_HolesContext;
m_WriteToHoles = writable;
#if UNITY_2019_3_OR_NEWER
m_HolesContext = TerrainPaintUtility.BeginPaintHoles(terrain, boundsInTerrainSpace, extraBorderPixels);
if (m_HolesContext == null)
return null;
m_HolesContext.sourceRenderTexture.name = $"{m_Name}::HolesContext::SourceRT";
m_HolesContext.destinationRenderTexture.name = $"{m_Name}::HolesContext::DestRT";
#endif
return m_HolesContext;
}
public void Release(PaintContext paintContext)
{
if (ReferenceEquals(paintContext, m_HeightmapContext))
{
if (m_WriteToHeightmap)
{
TerrainPaintUtility.EndPaintHeightmap(m_HeightmapContext, $"{m_Name} - Heightmap");
}
else
{
TerrainPaintUtility.ReleaseContextResources(m_HeightmapContext);
}
m_HeightmapContext = null;
}
else if (ReferenceEquals(paintContext, m_NormalmapContext))
{
TerrainPaintUtility.ReleaseContextResources(m_NormalmapContext);
m_NormalmapContext = null;
}
else if (ReferenceEquals(paintContext, m_TextureContext))
{
if (m_WriteToTexture)
{
TerrainPaintUtility.EndPaintTexture(m_TextureContext, $"{m_Name} - Texture");
}
else
{
TerrainPaintUtility.ReleaseContextResources(m_TextureContext);
}
m_TextureContext = null;
}
#if UNITY_2019_3_OR_NEWER
else if (ReferenceEquals(paintContext, m_HolesContext))
{
if (m_WriteToHoles)
{
TerrainPaintUtility.EndPaintHoles(m_HolesContext, "Terrain Paint - Paint Holes");
}
else
{
TerrainPaintUtility.ReleaseContextResources(m_HolesContext);
}
m_HolesContext = null;
}
#endif
}
public void Dispose()
{
if (m_HeightmapContext != null)
{
Release(m_HeightmapContext);
}
if (m_NormalmapContext != null)
{
Release(m_NormalmapContext);
}
if (m_TextureContext != null)
{
Release(m_TextureContext);
}
}
}
internal class BrushRenderPreviewWithTerrainUiGroup : BrushRenderWithTerrainUIGroup, IBrushRenderPreviewWithTerrain
{
public BrushRenderPreviewWithTerrainUiGroup(IBrushUIGroup uiGroup, string name, Texture brushTexture) : base(uiGroup, name, brushTexture)
{
}
public override bool CalculateBrushTransform(Terrain terrain, Vector2 uv, float size, float rotation, out BrushTransform brushTransform)
{
// TODO: Remove this method and replace the preview with a radius effect and scatter at the correct position...
brushTransform = TerrainPaintUtility.CalculateBrushTransform(terrain, uv, size, rotation);
return true;
}
public void RenderBrushPreview(PaintContext paintContext, TerrainBrushPreviewMode previewTexture, BrushTransform brushTransform, Material material, int pass)
{
TerrainPaintUtilityEditor.DrawBrushPreview(paintContext, previewTexture, brushTexture, brushTransform, material, pass);
}
}
}