debugging this raycasting

This commit is contained in:
JISAUAY 2025-11-13 16:02:14 -06:00
parent ae5b2a0185
commit bee594d4b9
2 changed files with 168 additions and 25 deletions

View File

@ -71,32 +71,52 @@ std::optional<std::pair<glm::ivec3, glm::ivec3>> World::raycast_voxel(glm::vec3
// Normalize direction to ensure consistent behavior
direction = glm::normalize(direction);
std::cout << "[RAYCAST] Start: (" << start.x << ", " << start.y << ", " << start.z << ")" << std::endl;
std::cout << "[RAYCAST] Direction: (" << direction.x << ", " << direction.y << ", " << direction.z << ")" << std::endl;
// std::cout << "[RAYCAST] Start: (" << start.x << ", " << start.y << ", " << start.z << ")" << std::endl;
// std::cout << "[RAYCAST] Direction: (" << direction.x << ", " << direction.y << ", " << direction.z << ")" << std::endl;
glm::ivec3 pos = glm::ivec3(std::floor(start.x), std::floor(start.y), std::floor(start.z));
std::cout << "[RAYCAST] Starting voxel: (" << pos.x << ", " << pos.y << ", " << pos.z << ")" << std::endl;
// std::cout << "[RAYCAST] Starting voxel: (" << pos.x << ", " << pos.y << ", " << pos.z << ")" << std::endl;
// (+1 or -1 for each axis)
glm::ivec3 step_dir = glm::sign(direction);
std::cout << "[RAYCAST] Step direction: (" << step_dir.x << ", " << step_dir.y << ", " << step_dir.z << ")" << std::endl;
// (+1, -1, or 0 for each axis)
glm::ivec3 step_dir = glm::ivec3(
direction.x > 0 ? 1 : (direction.x < 0 ? -1 : 0),
direction.y > 0 ? 1 : (direction.y < 0 ? -1 : 0),
direction.z > 0 ? 1 : (direction.z < 0 ? -1 : 0)
);
// std::cout << "[RAYCAST] Step direction: (" << step_dir.x << ", " << step_dir.y << ", " << step_dir.z << ")" << std::endl;
// How far to step in each axis
const float epsilon = 0.0001f;
glm::vec3 safe_dir = glm::vec3(
abs(direction.x) < epsilon ? epsilon : direction.x,
abs(direction.y) < epsilon ? epsilon : direction.y,
abs(direction.z) < epsilon ? epsilon : direction.z
// Delta: how far along the ray we move for a full voxel step in each axis
glm::vec3 delta = glm::vec3(
step_dir.x != 0 ? std::abs(1.0f / direction.x) : FLT_MAX,
step_dir.y != 0 ? std::abs(1.0f / direction.y) : FLT_MAX,
step_dir.z != 0 ? std::abs(1.0f / direction.z) : FLT_MAX
);
glm::vec3 delta = glm::abs(1.0f / safe_dir);
// Calculate t_max: distance along ray to next voxel boundary for each axis
glm::vec3 t_max;
glm::vec3 fract = start - glm::vec3(pos);
glm::vec3 t_max = glm::vec3(
(step_dir.x > 0 ? (1.0f - fract.x) : fract.x) * delta.x,
(step_dir.y > 0 ? (1.0f - fract.y) : fract.y) * delta.y,
(step_dir.z > 0 ? (1.0f - fract.z) : fract.z) * delta.z
);
// For each axis, calculate distance to the next boundary
if (step_dir.x > 0)
t_max.x = (1.0f - fract.x) * delta.x;
else if (step_dir.x < 0)
t_max.x = fract.x * delta.x;
else
t_max.x = FLT_MAX;
if (step_dir.y > 0)
t_max.y = (1.0f - fract.y) * delta.y;
else if (step_dir.y < 0)
t_max.y = fract.y * delta.y;
else
t_max.y = FLT_MAX;
if (step_dir.z > 0)
t_max.z = (1.0f - fract.z) * delta.z;
else if (step_dir.z < 0)
t_max.z = fract.z * delta.z;
else
t_max.z = FLT_MAX;
float dist = 0.0f;
glm::ivec3 last_move = glm::ivec3(0, 0, 0);
@ -107,11 +127,11 @@ std::optional<std::pair<glm::ivec3, glm::ivec3>> World::raycast_voxel(glm::vec3
while (dist < max_dist && iterations < max_iterations) {
iterations++;
std::cout << "[RAYCAST] Iteration " << iterations << " at voxel (" << pos.x << ", " << pos.y << ", " << pos.z << ")" << std::endl;
// std::cout << "[RAYCAST] Iteration " << iterations << " at voxel (" << pos.x << ", " << pos.y << ", " << pos.z << ")" << std::endl;
if (this->get_voxel(pos).has_value()) {
std::cout << "[RAYCAST] Hit voxel at (" << pos.x << ", " << pos.y << ", " << pos.z << ") after " << iterations << " iterations" << std::endl;
std::cout << "[RAYCAST] Returning normal: (" << -last_move.x << ", " << -last_move.y << ", " << -last_move.z << ")" << std::endl;
// std::cout << "[RAYCAST] Hit voxel at (" << pos.x << ", " << pos.y << ", " << pos.z << ") after " << iterations << " iterations" << std::endl;
// std::cout << "[RAYCAST] Returning normal: (" << -last_move.x << ", " << -last_move.y << ", " << -last_move.z << ")" << std::endl;
return std::make_pair(pos, -last_move);
}
@ -134,7 +154,7 @@ std::optional<std::pair<glm::ivec3, glm::ivec3>> World::raycast_voxel(glm::vec3
}
}
std::cout << "[RAYCAST] No voxel hit after " << iterations << " iterations, dist=" << dist << std::endl;
// std::cout << "[RAYCAST] No voxel hit after " << iterations << " iterations, dist=" << dist << std::endl;
return std::nullopt;
}

View File

@ -35,6 +35,9 @@ bool W_pressed, S_pressed, A_pressed, D_pressed = false;
glm::mat4 projection = glm::mat4(1.0f);
Camera camera = Camera(CAMERA_SPEED, glm::vec3(0.0f, 0.0f, 0.0f));
// Targeted block for highlighting
std::optional<glm::ivec3> targeted_block = std::nullopt;
// Callback function for when the window is resized
// glfw: whenever the window size changed (by OS or user resize) this callback function executes
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
@ -60,7 +63,7 @@ World world;
void mouse_callback(GLFWwindow * window, double xpos, double ypos)
{
float x_offset = xpos - last_x;
float y_offset = ypos - last_y;
float y_offset = last_y - ypos; // Inverted Y for typical FPS controls
last_x = xpos;
last_y = ypos;
@ -83,7 +86,7 @@ void mouse_callback(GLFWwindow * window, double xpos, double ypos)
glm::vec3 direction;
direction.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
direction.y = -sin(glm::radians(pitch));
direction.y = sin(glm::radians(pitch)); // Positive Y is up
direction.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
camera.target = glm::normalize(direction);
}
@ -93,6 +96,24 @@ void processInput(GLFWwindow *window)
{
float current_time = glfwGetTime();
// Update targeted block every frame for highlight
std::optional<std::pair<glm::ivec3, glm::ivec3>> raycast_result =
world.raycast_voxel(camera.getEyePosition(), camera.target, 5);
if (raycast_result.has_value()) {
targeted_block = raycast_result.value().first;
// Debug: print occasionally
static int frame_count = 0;
if (frame_count % 60 == 0) {
std::cout << "Camera eye: (" << camera.getEyePosition().x << ", " << camera.getEyePosition().y << ", " << camera.getEyePosition().z << ")" << std::endl;
std::cout << "Camera target dir: (" << camera.target.x << ", " << camera.target.y << ", " << camera.target.z << ")" << std::endl;
std::cout << "Highlighted block: (" << targeted_block.value().x << ", " << targeted_block.value().y << ", " << targeted_block.value().z << ")" << std::endl;
}
frame_count++;
} else {
targeted_block = std::nullopt;
}
if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
// if (mouse_lock) {
// glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
@ -298,6 +319,59 @@ int main() {
glEnableVertexAttribArray(0);
glBindVertexArray(0);
// Setup highlight box (cube outline)
unsigned int highlightVAO, highlightVBO, highlightEBO;
glGenVertexArrays(1, &highlightVAO);
glGenBuffers(1, &highlightVBO);
glGenBuffers(1, &highlightEBO);
glBindVertexArray(highlightVAO);
glBindBuffer(GL_ARRAY_BUFFER, highlightVBO);
// Cube outline vertices (slightly larger than 1 unit cube for visibility)
float offset = 0.001f; // Slight offset to prevent z-fighting
float highlightVertices[] = {
// 8 corners of a cube
-0.5f - offset, -0.5f - offset, -0.5f - offset, // 0
0.5f + offset, -0.5f - offset, -0.5f - offset, // 1
0.5f + offset, 0.5f + offset, -0.5f - offset, // 2
-0.5f - offset, 0.5f + offset, -0.5f - offset, // 3
-0.5f - offset, -0.5f - offset, 0.5f + offset, // 4
0.5f + offset, -0.5f - offset, 0.5f + offset, // 5
0.5f + offset, 0.5f + offset, 0.5f + offset, // 6
-0.5f - offset, 0.5f + offset, 0.5f + offset // 7
};
// Indices for the 12 edges of the cube
unsigned int highlightIndices[] = {
// Bottom face
0, 1, 1, 2, 2, 3, 3, 0,
// Top face
4, 5, 5, 6, 6, 7, 7, 4,
// Vertical edges
0, 4, 1, 5, 2, 6, 3, 7
};
glBufferData(GL_ARRAY_BUFFER, sizeof(highlightVertices), highlightVertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, highlightEBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(highlightIndices), highlightIndices, GL_STATIC_DRAW);
glBindVertexArray(0);
// Setup debug ray
unsigned int debugRayVAO, debugRayVBO;
glGenVertexArrays(1, &debugRayVAO);
glGenBuffers(1, &debugRayVBO);
glBindVertexArray(debugRayVAO);
glBindBuffer(GL_ARRAY_BUFFER, debugRayVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6, nullptr, GL_DYNAMIC_DRAW); // 2 points * 3 coords
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindVertexArray(0);
glm::mat4 view;
double start_time = glfwGetTime();
double move_time = glfwGetTime();
@ -400,6 +474,55 @@ int main() {
// --- Reset polygon mode for next frame (good practice) ---
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// ---- Draw Highlighted Block ----
if (targeted_block.has_value()) {
shader.use();
glm::mat4 model = glm::mat4(1.0f);
// Voxels are centered on integer coordinates, so no need to add 0.5
model = glm::translate(model, glm::vec3(targeted_block.value()));
glm::mat4 mvp = projection * view * model;
shader.setMat4("u_mvp", mvp);
shader.setVec3("u_Color", glm::vec3(0.0f, 0.0f, 0.0f)); // Black outline
glLineWidth(2.0f);
glBindVertexArray(highlightVAO);
glDrawElements(GL_LINES, 24, GL_UNSIGNED_INT, 0); // 24 indices = 12 edges
glBindVertexArray(0);
}
// ---- Draw Debug Ray ----
{
shader.use();
glm::vec3 ray_start = camera.getEyePosition();
static bool printed_debug = false;
// Draw multiple small cubes along the ray path to make it visible
for (int i = 1; i <= 10; i++) {
float distance = i * 0.5f;
glm::vec3 point = ray_start + camera.target * distance;
if (!printed_debug && i == 1) {
std::cout << "\n[DEBUG RAY]" << std::endl;
std::cout << "Ray start: (" << ray_start.x << ", " << ray_start.y << ", " << ray_start.z << ")" << std::endl;
std::cout << "Ray direction: (" << camera.target.x << ", " << camera.target.y << ", " << camera.target.z << ")" << std::endl;
std::cout << "First marker at: (" << point.x << ", " << point.y << ", " << point.z << ")" << std::endl;
printed_debug = true;
}
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, point);
model = glm::scale(model, glm::vec3(0.1f)); // Small marker
glm::mat4 mvp = projection * view * model;
shader.setMat4("u_mvp", mvp);
shader.setVec3("u_Color", glm::vec3(1.0f, 0.0f, 0.0f)); // Red markers
glBindVertexArray(highlightVAO);
glDrawElements(GL_LINES, 24, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
}
// ---- Draw Crosshair ----
glDisable(GL_DEPTH_TEST); // Draw on top of everything
shader.use();