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(); 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(); 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 ); } }