Created
November 2, 2019 23:49
-
-
Save gamemachine/0606a56361f019b8f11a69a1bde85adf to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Sirenix.OdinInspector; | |
using System.Collections.Generic; | |
using Unity.Mathematics; | |
using UnityEngine; | |
namespace AiGame.Terrains | |
{ | |
public class MicroSplatBoundsHole : MonoBehaviour | |
{ | |
private const int MaxHoles = 50; | |
[SerializeField] | |
private MicroSplatTerrain MicroSplatTerrain; | |
[SerializeField] | |
private BoxCollider Collider; | |
[SerializeField] | |
private List<float3x2> Holes = new List<float3x2>(); | |
private void Start() | |
{ | |
MicroSplatTerrain.OnMaterialSync += OnMaterialSync; | |
MicroSplatTerrain.Sync(); | |
} | |
private void OnMaterialSync(Material m) | |
{ | |
MicroSplatTerrain.OnMaterialSync -= OnMaterialSync; | |
Vector4[] shaderArray = new Vector4[MaxHoles * 2]; | |
int index = 0; | |
for (int i=0;i<Holes.Count;i++) | |
{ | |
float3x2 hole = Holes[i]; | |
shaderArray[index] = new Vector4(hole.c0.x, hole.c0.y, hole.c0.z); | |
index++; | |
shaderArray[index] = new Vector4(hole.c1.x, hole.c1.y, hole.c1.z); | |
index++; | |
} | |
m.SetVectorArray("_BoundsHoleArray", shaderArray); | |
m.SetInt("_BoundsHoleCount", Holes.Count); | |
} | |
[Button("SetHole")] | |
public void SetHole() | |
{ | |
SetHole(Collider.bounds); | |
} | |
public void SetHole(Bounds bounds) | |
{ | |
if (Holes.Count > MaxHoles) | |
{ | |
throw new UnityException("MaxHoles exceeded"); | |
} | |
Holes.Add(new float3x2(bounds.min, bounds.max)); | |
MicroSplatTerrain.OnMaterialSync += OnMaterialSync; | |
MicroSplatTerrain.Sync(); | |
} | |
[Button("ClearHoles")] | |
public void ClearHoles() | |
{ | |
Holes.Clear(); | |
MicroSplatTerrain.OnMaterialSync += OnMaterialSync; | |
MicroSplatTerrain.Sync(); | |
} | |
} | |
} | |
// shader content | |
// Surface function should call ClipAllBounds with i.worldPos | |
// property | |
_BoundsHoleCount("BoundsHoleCount", Int) = 0 | |
// shared | |
float4 _BoundsHoleArray[100]; | |
int _BoundsHoleCount; | |
void ClipBounds(float3 min, float3 max, float3 pos) { | |
float a = step(min.x, pos.x); | |
float b = step(pos.x, max.x); | |
float c = step(min.y, pos.y); | |
float d = step(pos.y, max.y); | |
float e = step(min.z, pos.z); | |
float f = step(pos.z, max.z); | |
clip(5.0f - a - b - c - d - e - f); | |
} | |
void ClipAllBounds(float3 worldPos) | |
{ | |
int index = 0; | |
for(int i=0;i<_BoundsHoleCount;i++) | |
{ | |
float4 min = _BoundsHoleArray[index]; | |
index++; | |
if (min.x > 0.0f) | |
{ | |
float4 max = _BoundsHoleArray[index]; | |
ClipBounds(min.xyz, max.xyz, worldPos); | |
} | |
index++; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment