using UnityEngine; using System.Diagnostics; using System.Runtime.InteropServices; using System.Collections.Generic; public class Player : MonoBehaviour { public VoxelTreeManager voxelManager; public bool EnableDebug = false; int totalCastDone = 0; public float longitudeStep = 45f; public float lateralStep = 45f; int rayCount; // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { InitPrebuildArray(); VoxelRaycastGPU.Ray[] rays = new VoxelRaycastGPU.Ray[rayCount]; FillRaysArray(rays); voxelManager.gpuRayCaster.Init(rayCount, rays); } void Cast( ref VoxelRaycastGPU.BatchData[] batchData, int batchCount, int iIteration ) { ComputeBuffer hitBuffer = new ComputeBuffer(rayCount * batchCount, Marshal.SizeOf(typeof(VoxelRaycastGPU.Hit)), ComputeBufferType.Append); Stopwatch sw = Stopwatch.StartNew(); totalCastDone += batchCount * rayCount; VoxelRaycastGPU.BatchData[] hits = voxelManager.CastGpuRay(in batchData, batchCount); /*for( int i = 0; i < hits.Length; i++ ) { GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); sphere.transform.position = hits[i].origin; sphere.transform.localScale = Vector3.one * 0.5f; }*/ sw.Stop(); } Vector3[] prebuildArrayDirection; void InitPrebuildArray() { var dirs = new List(); const float EPS = 1e-6f; // Elevation (longitude in your naming): from -90 to +90 inclusive for (float lonDeg = -90f; lonDeg <= 90f + 1e-6f; lonDeg += longitudeStep) { float lonRad = lonDeg * Mathf.Deg2Rad; float cosLon = Mathf.Cos(lonRad); float sinLon = Mathf.Sin(lonRad); // If cosLon is ~0, we are at a pole: all azimuths collapse to the same vector. if (Mathf.Abs(cosLon) < EPS) { // Add a single pole direction (north or south) dirs.Add(new Vector3(0f, sinLon, 0f)); continue; // skip azimuth loop for this elevation } // Otherwise loop over azimuth (lateral) for (float latDeg = 0f; latDeg < 360f - 1e-6f; latDeg += lateralStep) { float latRad = latDeg * Mathf.Deg2Rad; float cosLat = Mathf.Cos(latRad); float sinLat = Mathf.Sin(latRad); Vector3 dir = new Vector3( cosLon * cosLat, sinLon, cosLon * sinLat ); dirs.Add(dir.normalized); } } prebuildArrayDirection = dirs.ToArray(); rayCount = dirs.Count; } void FillRaysArray( VoxelRaycastGPU.Ray[] rays ) { for (int i = 0; i < prebuildArrayDirection.Length; i++) { rays[i].direction = prebuildArrayDirection[i]; } } // Update is called once per frame void Update() { if (Input.GetKeyDown(KeyCode.R)) { //VoxelTreeRaycaster.HitInfo outHit; Vector3 origin = GetComponent().position; UnityEngine.Debug.Log(origin); //int iNbCast = 0; /*Stopwatch sw = Stopwatch.StartNew(); for (float el = -90f; el <= 90f; el += elStep) { for (float az = 0f; az < 360f; az += azStep) { float elRad = el * Mathf.Deg2Rad; float azRad = az * Mathf.Deg2Rad; Vector3 dir = new Vector3( Mathf.Cos(elRad) * Mathf.Cos(azRad), Mathf.Sin(elRad), Mathf.Cos(elRad) * Mathf.Sin(azRad) ).normalized; iNbCast++; bool hit = voxelManager.CastRay(origin, dir, 100f, out outHit); } } sw.Stop(); UnityEngine.Debug.Log($"RayCast done in {sw.Elapsed.TotalMilliseconds}ms for {iNbCast} casts");*/ Stopwatch sw = Stopwatch.StartNew(); totalCastDone = 0; VoxelRaycastGPU.Ray[] rays = new VoxelRaycastGPU.Ray[rayCount]; VoxelRaycastGPU.BatchData[] batchDatas = new VoxelRaycastGPU.BatchData[1]; batchDatas[0].origin = origin; batchDatas[0].maxDistance = 100; Cast(ref batchDatas, 1, 0); sw.Stop(); UnityEngine.Debug.Log($"Gpu RayCast done in {sw.Elapsed.TotalMilliseconds}ms for {totalCastDone} casts"); } } }