106 lines
3.2 KiB
C#
106 lines
3.2 KiB
C#
using UnityEngine;
|
|
|
|
public struct IsSolidNodeAnswere
|
|
{
|
|
public float penetrationFactor;
|
|
public float reflexionFactor;
|
|
public bool isSolid;
|
|
public GameObject Go;
|
|
}
|
|
|
|
public class VoxelTreeManager : MonoBehaviour
|
|
{
|
|
public LayerMask solidLayerMask;
|
|
public float voxelSize = 2f; // Minimum voxel size
|
|
public int maxDepth = 6; // Tree subdivision limit
|
|
public float boundsSize = 300f; // World size covered by the voxel tree
|
|
public ComputeShader computeShader;
|
|
public ComputeShader clusteringShader;
|
|
private OctreeNode root;
|
|
private VoxelTreeRaycaster raycaster = new VoxelTreeRaycaster();
|
|
public VoxelRaycastGpuManager gpuRayCaster;
|
|
|
|
void Start()
|
|
{
|
|
Debug.Log($"Building voxel tree with LayerMask: {LayerMaskToString(solidLayerMask)}");
|
|
|
|
var builder = new VoxelTreeBuilder(maxDepth, voxelSize);
|
|
root = builder.Build(new Bounds(Vector3.zero, Vector3.one * boundsSize), IsSolid);
|
|
|
|
var dbg = FindObjectOfType<VoxelTreeDebugger>();
|
|
if (dbg) dbg.root = root;
|
|
|
|
gpuRayCaster = new VoxelRaycastGpuManager(computeShader, clusteringShader, root);
|
|
}
|
|
|
|
// This function replaces pos => pos.magnitude < 100f
|
|
private IsSolidNodeAnswere IsSolid(Vector3 pos, float size)
|
|
{
|
|
IsSolidNodeAnswere answere;
|
|
|
|
answere.Go = null;
|
|
|
|
answere.penetrationFactor = 1;
|
|
answere.reflexionFactor = 1;
|
|
|
|
float overlapMargin = size / 3f;
|
|
answere.isSolid = false;
|
|
|
|
Collider[] hits = Physics.OverlapSphere(pos, overlapMargin, solidLayerMask, QueryTriggerInteraction.Ignore);
|
|
|
|
if (hits.Length > 0)
|
|
{
|
|
answere.isSolid = true;
|
|
for (int i = 0; i < hits.Length; i++)
|
|
{
|
|
AudioObject audioObj = hits[i].GetComponent<AudioObject>();
|
|
|
|
if (audioObj)
|
|
{
|
|
answere.penetrationFactor = audioObj.audioMaterialSettings.penetrationFactor;
|
|
answere.reflexionFactor = audioObj.audioMaterialSettings.reflexionFactor;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return answere;
|
|
}
|
|
|
|
return answere;
|
|
}
|
|
|
|
private static string LayerMaskToString(LayerMask mask)
|
|
{
|
|
string names = "";
|
|
for (int i = 0; i < 32; i++)
|
|
{
|
|
if (((1 << i) & mask.value) != 0)
|
|
{
|
|
names += LayerMask.LayerToName(i) + " ";
|
|
}
|
|
}
|
|
return names.Trim();
|
|
}
|
|
|
|
public bool CastRay(Vector3 origin, Vector3 dir, float distance, out VoxelTreeRaycaster.HitInfo outHit)
|
|
{
|
|
if (raycaster.Raycast(root, origin, dir, distance, out var hit))
|
|
{
|
|
outHit = hit;
|
|
// Debug.Log($"Ray hit voxel at {hit.point}, dist={hit.distance:F2}");
|
|
//Debug.DrawLine(origin, hit.point, Color.red, 2f);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
outHit = hit;
|
|
//Debug.Log("No voxel hit");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public VoxelRaycastGPU.BatchData[] CastGpuRay( in VoxelRaycastGPU.BatchData[] batchData, int datasLenght )
|
|
{
|
|
return gpuRayCaster.Raycast( in batchData, datasLenght );
|
|
}
|
|
} |