From 1de9c6dd35683ae38ae91e4cb28a72c891505490 Mon Sep 17 00:00:00 2001 From: mitchellhansen Date: Tue, 2 Aug 2016 22:26:56 -0700 Subject: [PATCH] Ahh! It works!! The camera is great now, it yaws and pitches perfectly, just need to limit it to 180 -> -180 on the pitch. There is still a problem when viewing in the negative angles, and as you move the camera closer to 0 things get weird and distorted. But the transfer over to a spherical camera point and a cartesian view plane worked fantastically --- src/Ray.cpp | 37 +++++++--------- src/RayCaster.cpp | 105 +++++++++++++++++++++++++++------------------- 2 files changed, 79 insertions(+), 63 deletions(-) diff --git a/src/Ray.cpp b/src/Ray.cpp index f283056..aba5bcb 100644 --- a/src/Ray.cpp +++ b/src/Ray.cpp @@ -24,7 +24,7 @@ Ray::Ray( sf::Color Ray::Cast() { // Get the cartesian direction for computing - sf::Vector3 cartesian = SphereToCart(direction); + 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); @@ -47,27 +47,27 @@ sf::Color Ray::Cast() { 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 - + // 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. - - // 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){ + if (pixel.y == 200){ int i = 0; i++; } @@ -97,7 +97,7 @@ sf::Color Ray::Cast() { } } - // If the voxel went out of bounds + // If the ray went out of bounds if (voxel.z >= dimensions.z) { return sf::Color(0, 0, 255, 50); } @@ -117,9 +117,8 @@ sf::Color Ray::Cast() { if (voxel.z < 0) { return sf::Color(0, 255, 0, 50); } - // If we found a voxel - // Registers hit on non-zero + // If we hit a voxel switch (map->list[voxel.x + dimensions.x * (voxel.y + dimensions.z * voxel.z)]) { case 1: return sf::Color::Red; @@ -134,11 +133,7 @@ sf::Color Ray::Cast() { 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++; diff --git a/src/RayCaster.cpp b/src/RayCaster.cpp index 0f1e69b..bf447a5 100644 --- a/src/RayCaster.cpp +++ b/src/RayCaster.cpp @@ -33,62 +33,83 @@ RayCaster::~RayCaster() { sf::Color* RayCaster::CastRays(sf::Vector3 camera_direction, sf::Vector3 camera_position) { - // Setup the camera for this cast - this->camera_direction = camera_direction; - camera_direction_cartesian = Normalize(SphereToCart(camera_direction)); - this->camera_position = camera_position; + // Setup the camera for this cast + this->camera_direction = camera_direction; + camera_direction_cartesian = Normalize(SphereToCart(camera_direction)); + 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); + // 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); - - //-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++) { + // A reference to the positive X axis as our base viewport point + sf::Vector3f base_direction(1, 0, 0); - // The direction the final ray will point. - // First take a reference to the base direction to setup the viewport - //Vector3 ray_direction = new Vector3 (base_direction); + int view_plane_distance = 300; + sf::Vector3f *view_plane_vectors = new sf::Vector3f[resolution.x * resolution.y]; - // New method to cast rays using the original intended Spherical coords - // instead of that malarchy with converting them to cartesian from the formula + 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)); + } + } - sf::Vector3f ray_direction( - camera_direction.x, - camera_direction.y + (float)(y_increment_radians * y), - camera_direction.z + (float)(x_increment_radians * x) - ); + //-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++) { - sf::Vector3f ray_cartesian = Normalize(SphereToCart(ray_direction)); - 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_direction.x << " : " << ray_direction.y << " : " << ray_direction.z << "\n"; - } + sf::Vector3f ray = view_plane_vectors[x + resolution.x * y]; - // Setup the ray - Ray r(map, resolution, sf::Vector2i(x, y), camera_position, ray_direction); - // Cast it - sf::Color c = r.Cast(); - if (c.a == 0) - std::cout << "BLACK"; - image[x + resolution.x*y] = c; - } - } + // Then rotate y axis, up down + 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. + 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 + ); - return image; - } +// 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; + } + } + + delete view_plane_vectors; + + return image; +} void RayCaster::moveCamera(sf::Vector2f v) { camera_direction.y += v.x;