diff --git a/include/Ray.h b/include/Ray.h index 64264c1..d95fd52 100644 --- a/include/Ray.h +++ b/include/Ray.h @@ -7,7 +7,7 @@ class Ray { private: - // The Tail of the vector + // The Tail of the vector sf::Vector3 origin; // Direction / Length of the vector diff --git a/include/RayCaster.h b/include/RayCaster.h index e0232f9..a938ab0 100644 --- a/include/RayCaster.h +++ b/include/RayCaster.h @@ -10,6 +10,8 @@ public: sf::Vector2 viewport_resolution); ~RayCaster(); + void setFOV(float fov); + void setResolution(sf::Vector2 resolution); sf::Color* CastRays(sf::Vector3 camera_direction, sf::Vector3 camera_position); void moveCamera(sf::Vector2f v); @@ -33,5 +35,12 @@ private: // The world-space position of the camera sf::Vector3 camera_position; + + // The distance in units the view plane is from the iris point + int view_plane_distance = 300; + + // Precalculated values for the view plane rays + sf::Vector3f *view_plane_vectors; + }; diff --git a/src/Ray.cpp b/src/Ray.cpp index aba5bcb..d6c1231 100644 --- a/src/Ray.cpp +++ b/src/Ray.cpp @@ -17,48 +17,32 @@ Ray::Ray( 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 = direction;//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); + voxel_step.x *= (direction.x > 0) - (direction.x < 0); + voxel_step.y *= (direction.y > 0) - (direction.y < 0); + voxel_step.z *= (direction.z > 0) - (direction.z < 0); // Setup the voxel coords from the camera origin voxel = sf::Vector3( - (int) origin.x, - (int) origin.y, - (int) origin.z + floorf(origin.x), + floorf(origin.y), + floorf(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)) + fabsf(1.0f / direction.x), + fabsf(1.0f / direction.y), + fabsf(1.0f / direction.z) ); - // So the way I need to do the camera is this. - // 1.) Setup the viewplane and then store the values - // - Camera origin - // - Resolution of the view plane X, Y - // - Focal length to determine FOV - // - // 2.) For each draw. Get a copy of the view plane - // 3.) Rotate around the X axis first, left and right - // 4.) Then rotate alond the Y axis, up and down. - // 5.) Make sure to limit the camera Y Rotation to 180 and -180 degrees - // - Rays will still go pas 180 for the amount of FOV the camera has! - // Intersection T is the collection of the next intersection points // for all 3 axis XYZ. intersection_t = sf::Vector3( @@ -67,13 +51,9 @@ sf::Color Ray::Cast() { delta_t.z + origin.z ); - if (pixel.y == 200){ - int i = 0; - i++; - } - int dist = 0; + // Andrew Woo's raycasting algo do { if ((intersection_t.x) < (intersection_t.y)) { if ((intersection_t.x) < (intersection_t.z)) { @@ -139,6 +119,7 @@ sf::Color Ray::Cast() { } while (dist < 200); + // Ray timeout color return sf::Color::Cyan; } diff --git a/src/RayCaster.cpp b/src/RayCaster.cpp index bf447a5..fed5948 100644 --- a/src/RayCaster.cpp +++ b/src/RayCaster.cpp @@ -14,19 +14,25 @@ RayCaster::RayCaster( //this.camera_direction = new Vector3 (1f, 0f, .8f); //this.camera_position = new Vector3 (1, 10, 10); - this->map_dimensions = map_dimensions; this->map = map; resolution = viewport_resolution; image = new sf::Color[resolution.x * resolution.y]; - - + // Calculate the view plane vectors + view_plane_vectors = new sf::Vector3f[resolution.x * resolution.y]; + for (int y = -resolution.y / 2 ; y < resolution.y / 2; y++) { + for (int x = -resolution.x / 2; x < resolution.x / 2; x++) { + view_plane_vectors[(x + resolution.x / 2) + resolution.x * (y + resolution.y / 2)] = Normalize(sf::Vector3f(view_plane_distance, x, y)); + } + } } RayCaster::~RayCaster() { + delete image; + delete view_plane_vectors; } @@ -39,75 +45,38 @@ sf::Color* RayCaster::CastRays(sf::Vector3 camera_direction, sf::Vector3< this->camera_position = camera_position; - // The radian increment each ray is spaced from one another - double y_increment_radians = DegreesToRadians(60.0 / resolution.y); - double x_increment_radians = DegreesToRadians(80.0 / resolution.x); - - - // A reference to the positive X axis as our base viewport point - sf::Vector3f base_direction(1, 0, 0); - - int view_plane_distance = 300; - sf::Vector3f *view_plane_vectors = new sf::Vector3f[resolution.x * resolution.y]; - - for (int y = -resolution.y / 2 ; y < resolution.y / 2; y++) { - for (int x = -resolution.x / 2; x < resolution.x / 2; x++) { - - view_plane_vectors[(x + resolution.x / 2) + resolution.x * (y + resolution.y / 2)] = Normalize(sf::Vector3f(view_plane_distance, x, y)); - } - } - - //-resolution.y / 2 // Start the loop at the top left, scan right and work down for (int y = 0; y < resolution.y; y++) { for (int x = 0; x < resolution.x; x++) { - + // Get the ray at the base direction sf::Vector3f ray = view_plane_vectors[x + resolution.x * y]; + // Rotate it to the correct pitch and yaw - // Then rotate y axis, up down + // Y axis, pitch ray = sf::Vector3f( ray.z * sin(camera_direction.y) + ray.x * cos(camera_direction.y), ray.y, ray.z * cos(camera_direction.y) - ray.x * sin(camera_direction.y) ); -// // Rotate z axis, left to right. + // Z axis, yaw ray = sf::Vector3f( ray.x * cos(camera_direction.z) - ray.y * sin(camera_direction.z), ray.x * sin(camera_direction.z) + ray.y * cos(camera_direction.z), ray.z ); -// sf::Vector3f ray_direction( -// camera_direction.x, -// camera_direction.y + (float)(y_increment_radians * y), -// camera_direction.z + (float)(x_increment_radians * x) -// ); - - sf::Vector3f ray_cartesian = Normalize(SphereToCart(ray)); - sf::Vector3f cam_cartesian = Normalize(SphereToCart(camera_direction)); - - if ((y == -99 || y == 0 || y == 99) && (/*x == 99 || x == 0 || */x == -99)) { - std::cout << "X : " << x << "\n"; - std::cout << "Y : " << y << "\n"; - std::cout << ray.x << " : " << ray.y << " : " << ray.z << "\n"; - } // Setup the ray Ray r(map, resolution, sf::Vector2i(x, y), camera_position, ray); - // Cast it - sf::Color c = r.Cast(); - if (c.a == 0) - std::cout << "BLACK"; - image[x + resolution.x*y] = c; + // Cast it and assign its return value + image[x + resolution.x*y] = r.Cast(); } } - delete view_plane_vectors; - return image; } diff --git a/src/main.cpp b/src/main.cpp index b3f9d2c..7199334 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -157,12 +157,10 @@ int main() { // Cast the rays and get the image sf::Color* pixel_colors = ray_caster.CastRays(cam_dir, cam_pos); - /*for (int i = 0; i < img_size; i++) { - pixel_colors[i] = sf::Color::Green; - }*/ - + // Cast it to an array of Uint8's auto out = (sf::Uint8*)pixel_colors; - window_texture.update(out); + + window_texture.update(out); window_sprite.setTexture(window_texture); window.draw(window_sprite);