mirror of
https://github.com/raysan5/raylib.git
synced 2026-03-19 15:18:11 +00:00
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.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user