#pragma once #include #include #include "Map.h" #include #include "util.hpp" Ray::Ray( Map *map, sf::Vector2 resolution, sf::Vector2 pixel, sf::Vector3 camera_position, sf::Vector3 ray_direction) { this->pixel = pixel; this->map = map; origin = camera_position; direction = ray_direction; dimensions = map->getDimensions(); } sf::Color Ray::Cast() { // Get the cartesian direction for computing sf::Vector3 cartesian = SphereToCart(direction); // Setup the voxel step based on what direction the ray is pointing sf::Vector3 voxel_step(1, 1, 1); voxel_step.x *= (cartesian.x > 0) - (cartesian.x < 0); voxel_step.y *= (cartesian.y > 0) - (cartesian.y < 0); voxel_step.z *= (cartesian.z > 0) - (cartesian.z < 0); // Setup the voxel coords from the camera origin voxel = sf::Vector3( (int) origin.x, (int) origin.y, (int) origin.z ); // Delta T is the units a ray must travel along an axis in order to // traverse an integer split delta_t = sf::Vector3( fabsf((float) (1.0 / cartesian.x)), fabsf((float) (1.0 / cartesian.y)), fabsf((float) (1.0 / cartesian.z)) ); //97, 25, 34 is an interesting example of the problems // Ahhh, ya know what? This is a problem with how spherical coords // work when approaching 0 on the chi axis as rotation about // the theta axis is completely useless. A viewing frustum will // be needed unfortunately // Intersection T is the collection of the next intersection points // for all 3 axis XYZ. // I think this is where the hangup is currently. It's taking the delta_t which is signed // and multiplying it by the voxel_step which is also signed. On top of this. Computing the // camera position by voxel coord is debug only so I need to do the math to account for the // origin being anywhere inside a voxel intersection_t = sf::Vector3( delta_t.x + origin.x, delta_t.y + origin.y, delta_t.z + origin.z ); if (pixel.x == 0){ int i = 0; i++; } int dist = 0; do { if ((intersection_t.x) < (intersection_t.y)) { if ((intersection_t.x) < (intersection_t.z)) { voxel.x += voxel_step.x; intersection_t.x = intersection_t.x + delta_t.x; } else { voxel.z += voxel_step.z; intersection_t.z = intersection_t.z + delta_t.z; } } else { if ((intersection_t.y) < (intersection_t.z)) { voxel.y += voxel_step.y; intersection_t.y = intersection_t.y + delta_t.y; } else { voxel.z += voxel_step.z; intersection_t.z = intersection_t.z + delta_t.z; } } // If the voxel went out of bounds if (voxel.z >= dimensions.z) { return sf::Color(0, 0, 255, 50); } if (voxel.x >= dimensions.x) { return sf::Color(0, 0, 255, 100); } if (voxel.y >= dimensions.x) { return sf::Color(0, 0, 255, 150); } if (voxel.x < 0) { return sf::Color(0, 255, 0, 150); } if (voxel.y < 0) { return sf::Color(0, 255, 0, 100); } if (voxel.z < 0) { return sf::Color(0, 255, 0, 50); } // If we found a voxel // Registers hit on non-zero switch (map->list[voxel.x + dimensions.x * (voxel.y + dimensions.z * voxel.z)]) { case 1: return sf::Color::Red; case 2: return sf::Color::Magenta; case 3: return sf::Color::Yellow; case 4: return sf::Color(40, 230, 96, 200); case 5: return sf::Color(80, 120, 96, 100); case 6: return sf::Color(150, 80, 220, 200); } //else if (map->list[voxel.x + dimensions.x * (voxel.y + dimensions.z * voxel.z)] != 0){ // // //TODO: Switch that assigns color on voxel data // return sf::Color::Red; //} dist++; } while (dist < 200); return sf::Color::Cyan; }