143 lines
5.6 KiB
C#
143 lines
5.6 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace Pinwheel.Griffin.PaintTool
|
|
{
|
|
public class GSubDivPainter : IGTexturePainter, IGTexturePainterWithLivePreview
|
|
{
|
|
public string Instruction
|
|
{
|
|
get
|
|
{
|
|
string s = string.Format(
|
|
"Add more sub division to a particular area of the terrain.\n" +
|
|
" - Hold Left Mouse to add.\n" +
|
|
" - Hold {0} & Left Mouse to subtract.",
|
|
"Ctrl");
|
|
return s;
|
|
}
|
|
}
|
|
|
|
public string HistoryPrefix
|
|
{
|
|
get
|
|
{
|
|
return "Sub Div Painting";
|
|
}
|
|
}
|
|
|
|
public List<GTerrainResourceFlag> GetResourceFlagForHistory(GTexturePainterArgs args)
|
|
{
|
|
return GCommon.HeightMapAndFoliageResourceFlags;
|
|
}
|
|
|
|
public void Paint(GStylizedTerrain terrain, GTexturePainterArgs args)
|
|
{
|
|
if (terrain.TerrainData == null)
|
|
return;
|
|
if (args.MouseEventType == GPainterMouseEventType.Down)
|
|
{
|
|
terrain.ForceLOD(0);
|
|
GRuntimeSettings.Instance.isEditingGeometry = true;
|
|
}
|
|
if (args.MouseEventType == GPainterMouseEventType.Up)
|
|
{
|
|
terrain.ForceLOD(-1);
|
|
GRuntimeSettings.Instance.isEditingGeometry = 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.BrushMask);
|
|
mat.SetFloat("_Opacity", Mathf.Pow(args.Opacity, GTerrainTexturePainter.GEOMETRY_OPACITY_EXPONENT));
|
|
if (args.EnableTerrainMask)
|
|
{
|
|
mat.SetTexture("_TerrainMask", terrain.TerrainData.Mask.MaskMapOrDefault);
|
|
}
|
|
else
|
|
{
|
|
mat.SetTexture("_TerrainMask", Texture2D.blackTexture);
|
|
}
|
|
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);
|
|
}
|
|
|
|
public void Editor_DrawLivePreview(GStylizedTerrain terrain, GTexturePainterArgs args, Camera cam)
|
|
{
|
|
#if UNITY_EDITOR
|
|
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(terrain, heightMapResolution);
|
|
GCommon.CopyToRT(bg, rt);
|
|
|
|
Material mat = GInternalMaterials.SubDivPainterMaterial;
|
|
mat.SetTexture("_MainTex", bg);
|
|
mat.SetTexture("_Mask", args.BrushMask);
|
|
mat.SetFloat("_Opacity", Mathf.Pow(args.Opacity, GTerrainTexturePainter.GEOMETRY_OPACITY_EXPONENT));
|
|
if (args.EnableTerrainMask)
|
|
{
|
|
mat.SetTexture("_TerrainMask", terrain.TerrainData.Mask.MaskMapOrDefault);
|
|
}
|
|
else
|
|
{
|
|
mat.SetTexture("_TerrainMask", Texture2D.blackTexture);
|
|
}
|
|
int pass =
|
|
args.ActionType == GPainterActionType.Normal ? 0 :
|
|
args.ActionType == GPainterActionType.Negative ? 1 : 0;
|
|
GCommon.DrawQuad(rt, uvCorners, mat, pass);
|
|
|
|
Matrix4x4 worldToMaskMatrix = Matrix4x4.TRS(
|
|
args.WorldPointCorners[0],
|
|
Quaternion.Euler(0, args.Rotation, 0),
|
|
args.Radius * 2 * Vector3.one).inverse;
|
|
|
|
GLivePreviewDrawer.DrawSubdivLivePreview(terrain, cam, rt, dirtyRect, args.BrushMask, worldToMaskMatrix);
|
|
#endif
|
|
}
|
|
}
|
|
}
|