Fixed raycasting
This commit is contained in:
parent
bee594d4b9
commit
68acdc5183
BIN
.attachments/fixed-raycast.png
Normal file
BIN
.attachments/fixed-raycast.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
@ -35,3 +35,9 @@ Different voxel types are now supported in the data structures and passed to the
|
||||
When placing a block, the program now raycasts to place where the camera is looking.
|
||||
|
||||

|
||||
|
||||
### 0.6.1 : Raycast Bug Fixes - 11/17/25
|
||||
|
||||
It took me a couple of days to fix the ray casting. I forgot that my mesh is offset by 0.5, so 3/4 raycasts looked at least a block off of what the camera was looking at.
|
||||
|
||||

|
||||
|
||||
@ -74,7 +74,11 @@ std::optional<std::pair<glm::ivec3, glm::ivec3>> World::raycast_voxel(glm::vec3
|
||||
// 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));
|
||||
// Adjust start position to account for voxels being centered at integer + 0.5
|
||||
// (voxel at pos (0,0,0) occupies space from (-0.5,-0.5,-0.5) to (0.5,0.5,0.5))
|
||||
glm::vec3 adjusted_start = start + glm::vec3(0.5f, 0.5f, 0.5f);
|
||||
|
||||
glm::ivec3 pos = glm::ivec3(std::floor(adjusted_start.x), std::floor(adjusted_start.y), std::floor(adjusted_start.z));
|
||||
// std::cout << "[RAYCAST] Starting voxel: (" << pos.x << ", " << pos.y << ", " << pos.z << ")" << std::endl;
|
||||
|
||||
// (+1, -1, or 0 for each axis)
|
||||
@ -94,7 +98,7 @@ std::optional<std::pair<glm::ivec3, glm::ivec3>> World::raycast_voxel(glm::vec3
|
||||
|
||||
// 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 fract = adjusted_start - glm::vec3(pos);
|
||||
|
||||
// For each axis, calculate distance to the next boundary
|
||||
if (step_dir.x > 0)
|
||||
|
||||
83
src/main.cpp
83
src/main.cpp
@ -13,6 +13,8 @@
|
||||
unsigned int SCR_WIDTH = 1920;
|
||||
unsigned int SCR_HEIGHT = 1080;
|
||||
|
||||
const int EDIT_RANGE = 5;
|
||||
|
||||
// Jump
|
||||
const float JUMP_COOLDOWN = 0.0f;
|
||||
const float JUMP_POWER = 10.0f; // Initial Jump Speed
|
||||
@ -96,12 +98,22 @@ void processInput(GLFWwindow *window)
|
||||
{
|
||||
float current_time = glfwGetTime();
|
||||
|
||||
if (glfwGetKey(window, GLFW_KEY_P) == GLFW_PRESS) {
|
||||
glm::vec3 eye = camera.getEyePosition();
|
||||
glm::mat4 view = camera.getView();
|
||||
glm::vec3 forward = -glm::vec3(view[0][2], view[1][2], view[2][2]); // Extract forward from view matrix
|
||||
|
||||
std::cout << "Camera target (from pitch/yaw): (" << camera.target.x << ", " << camera.target.y << ", " << camera.target.z << ")" << std::endl;
|
||||
std::cout << "Camera forward (from view matrix): (" << forward.x << ", " << forward.y << ", " << forward.z << ")" << std::endl;
|
||||
std::cout << "Match: " << (glm::length(camera.target - forward) < 0.01f ? "YES" : "NO") << std::endl;
|
||||
}
|
||||
|
||||
// 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);
|
||||
world.raycast_voxel(camera.getEyePosition(), camera.target, EDIT_RANGE);
|
||||
if (raycast_result.has_value()) {
|
||||
targeted_block = raycast_result.value().first;
|
||||
|
||||
|
||||
// Debug: print occasionally
|
||||
static int frame_count = 0;
|
||||
if (frame_count % 60 == 0) {
|
||||
@ -203,10 +215,10 @@ void processInput(GLFWwindow *window)
|
||||
std::cout << "\n=== LEFT CLICK (PLACE) ===" << std::endl;
|
||||
std::cout << "Camera eye pos: (" << camera.getEyePosition().x << ", " << camera.getEyePosition().y << ", " << camera.getEyePosition().z << ")" << std::endl;
|
||||
std::cout << "Camera target: (" << camera.target.x << ", " << camera.target.y << ", " << camera.target.z << ")" << std::endl;
|
||||
|
||||
|
||||
std::optional<std::pair<glm::ivec3, glm::ivec3>> raycast_result =
|
||||
world.raycast_voxel(camera.getEyePosition(), camera.target, 3);
|
||||
|
||||
world.raycast_voxel(camera.getEyePosition(), camera.target, EDIT_RANGE);
|
||||
|
||||
if (raycast_result.has_value()) {
|
||||
auto [target_block, normal] = raycast_result.value();
|
||||
std::cout << "Hit block at: (" << target_block.x << ", " << target_block.y << ", " << target_block.z << ")" << std::endl;
|
||||
@ -228,10 +240,10 @@ void processInput(GLFWwindow *window)
|
||||
std::cout << "\n=== RIGHT CLICK (REMOVE) ===" << std::endl;
|
||||
std::cout << "Camera eye pos: (" << camera.getEyePosition().x << ", " << camera.getEyePosition().y << ", " << camera.getEyePosition().z << ")" << std::endl;
|
||||
std::cout << "Camera target: (" << camera.target.x << ", " << camera.target.y << ", " << camera.target.z << ")" << std::endl;
|
||||
|
||||
|
||||
std::optional<std::pair<glm::ivec3, glm::ivec3>> raycast_result =
|
||||
world.raycast_voxel(camera.getEyePosition(), camera.target, 3);
|
||||
|
||||
world.raycast_voxel(camera.getEyePosition(), camera.target, EDIT_RANGE);
|
||||
|
||||
if (raycast_result.has_value()) {
|
||||
auto [target_block, normal] = raycast_result.value();
|
||||
std::cout << "Hit block at: (" << target_block.x << ", " << target_block.y << ", " << target_block.z << ")" << std::endl;
|
||||
@ -257,7 +269,7 @@ int main() {
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
// 2. --- Create a Window ---
|
||||
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Voxel Engine 0.6.0", NULL, NULL);
|
||||
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Voxel Engine 0.6.1", NULL, NULL);
|
||||
if (window == NULL) {
|
||||
std::cerr << "Failed to create GLFW window" << std::endl;
|
||||
glfwTerminate();
|
||||
@ -299,10 +311,10 @@ int main() {
|
||||
unsigned int crosshairVAO, crosshairVBO;
|
||||
glGenVertexArrays(1, &crosshairVAO);
|
||||
glGenBuffers(1, &crosshairVBO);
|
||||
|
||||
|
||||
glBindVertexArray(crosshairVAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, crosshairVBO);
|
||||
|
||||
|
||||
// Crosshair vertices in NDC (Normalized Device Coordinates: -1 to 1)
|
||||
float crosshairSize = 0.02f; // Size in NDC
|
||||
float crosshairVertices[] = {
|
||||
@ -313,7 +325,7 @@ int main() {
|
||||
0.0f, -crosshairSize, 0.0f,
|
||||
0.0f, crosshairSize, 0.0f
|
||||
};
|
||||
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(crosshairVertices), crosshairVertices, GL_STATIC_DRAW);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
@ -324,10 +336,10 @@ int main() {
|
||||
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[] = {
|
||||
@ -341,7 +353,7 @@ int main() {
|
||||
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
|
||||
@ -351,11 +363,11 @@ int main() {
|
||||
// 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);
|
||||
@ -364,7 +376,7 @@ int main() {
|
||||
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
|
||||
@ -490,39 +502,6 @@ int main() {
|
||||
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();
|
||||
@ -548,4 +527,4 @@ int main() {
|
||||
|
||||
glfwTerminate(); // Clean up GLFW
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user