From 8a93587eaa61d124298ab5d9c1cdf5fcd3a64f30 Mon Sep 17 00:00:00 2001 From: Thomas Prowse <152029833+SardineMilk@users.noreply.github.com> Date: Thu, 12 Mar 2026 10:36:53 +0000 Subject: [PATCH] Fix raycasting logic in models_basic_voxel.c (#5643) The original logic iterated through the world and broke at the first found voxel that intersected the ray. This broke in some cases, removing a voxel out of view. I changed the algorithm to track the closest found voxel, and remove it at the end of the loop if one was found. --- examples/models/models_basic_voxel.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/examples/models/models_basic_voxel.c b/examples/models/models_basic_voxel.c index b0f4bc65e..2e2756f2b 100644 --- a/examples/models/models_basic_voxel.c +++ b/examples/models/models_basic_voxel.c @@ -72,6 +72,7 @@ int main(void) UpdateCamera(&camera, CAMERA_FIRST_PERSON); // Handle voxel removal with mouse click + // This method is quite inefficient. Ray marching through the voxel grid using DDA would be faster, but more complex. if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) { // Cast a ray from the screen center (where crosshair would be) @@ -79,12 +80,14 @@ int main(void) Ray ray = GetMouseRay(screenCenter, camera); // Check ray collision with all voxels - bool voxelRemoved = false; - for (int x = 0; (x < WORLD_SIZE) && !voxelRemoved; x++) + float closestDistance = 99999.0f; + Vector3 closestVoxelPosition = { -1, -1, -1 }; + bool voxelFound = false; + for (int x = 0; x < WORLD_SIZE; x++) { - for (int y = 0; (y < WORLD_SIZE) && !voxelRemoved; y++) + for (int y = 0; y < WORLD_SIZE; y++) { - for (int z = 0; (z < WORLD_SIZE) && !voxelRemoved; z++) + for (int z = 0; z < WORLD_SIZE; z++) { if (!voxels[x][y][z]) continue; // Skip empty voxels @@ -97,14 +100,23 @@ int main(void) // Check ray-box collision RayCollision collision = GetRayCollisionBox(ray, box); - if (collision.hit) + if (collision.hit && (collision.distance < closestDistance)) { - voxels[x][y][z] = false; // Remove this voxel - voxelRemoved = true; // Exit all loops + closestDistance = collision.distance; + closestVoxelPosition = (Vector3){ x, y, z }; + voxelFound = true; } } } } + + // Remove the closest voxel if one was hit + if (voxelFound) + { + voxels[(int)closestVoxelPosition.x] + [(int)closestVoxelPosition.y] + [(int)closestVoxelPosition.z] = false; + } } //----------------------------------------------------------------------------------