From a40b5545e8e4f3dfd7a6f10e6d757bee24cfdf80 Mon Sep 17 00:00:00 2001 From: MitchellHansen Date: Sat, 15 Apr 2017 01:50:01 -0700 Subject: [PATCH] Removed the class heirarchy for the raycaster. I was aiming for maximum compatability but realistically, this project will never run at any sort of acceptable speed on the cpu. Also in the previous commit fixed multiple longterm bugs as well as fixed bugs in the event system and made it much safer --- include/LightController.h | 1 - include/raycaster/Hardware_Caster.h | 1 - include/raycaster/RayCaster.h | 55 ----- include/raycaster/Software_Caster.h | 40 ---- src/Camera.cpp | 1 - src/Input.cpp | 1 - src/main.cpp | 2 +- src/raycaster/Hardware_Caster.cpp | 8 +- src/raycaster/RayCaster.cpp | 7 - src/raycaster/Software_Caster.cpp | 343 ---------------------------- 10 files changed, 5 insertions(+), 454 deletions(-) delete mode 100644 include/raycaster/RayCaster.h delete mode 100644 include/raycaster/Software_Caster.h delete mode 100644 src/raycaster/RayCaster.cpp delete mode 100644 src/raycaster/Software_Caster.cpp diff --git a/include/LightController.h b/include/LightController.h index 2251081..004a98f 100644 --- a/include/LightController.h +++ b/include/LightController.h @@ -4,7 +4,6 @@ #include #include "util.hpp" #include "Pub_Sub.h" -#include "raycaster/RayCaster.h" #include "raycaster/Hardware_Caster.h" #include "LightHandle.h" diff --git a/include/raycaster/Hardware_Caster.h b/include/raycaster/Hardware_Caster.h index de7873f..3a2c577 100644 --- a/include/raycaster/Hardware_Caster.h +++ b/include/raycaster/Hardware_Caster.h @@ -1,5 +1,4 @@ #pragma once -#include #include #include #include diff --git a/include/raycaster/RayCaster.h b/include/raycaster/RayCaster.h deleted file mode 100644 index 97db676..0000000 --- a/include/raycaster/RayCaster.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once -#include "Vector4.hpp" -#include -#include - - -class Old_Map; -class Camera; -struct PackedData; - - -class RayCaster { -public: - - enum ERROR_CODES { - SHARING_NOT_SUPPORTED = 800, - OPENCL_NOT_SUPPORTED = 801, - OPENCL_ERROR = 802, - ERR = 803 - }; - - RayCaster(); - virtual ~RayCaster(); - - virtual int init() = 0; - - virtual void assign_map(Old_Map *map) = 0; - virtual void assign_camera(Camera *camera) = 0; - virtual void create_viewport(int width, int height, float v_fov, float h_fov) = 0; - virtual void assign_lights(std::vector *data) = 0; - virtual void validate() = 0; - - // draw will abstract the gl sharing and software rendering - // methods of retrieving the screen buffer - virtual void compute() = 0; - virtual void draw(sf::RenderWindow* window) = 0; - -protected: - - sf::Sprite viewport_sprite; - sf::Texture viewport_texture; - - Old_Map * map = nullptr; - Camera *camera = nullptr; -// std::vector *lights; - std::vector *lights; - int light_count = 0; - sf::Uint8 *viewport_image = nullptr; - sf::Vector4f *viewport_matrix = nullptr; - sf::Vector2i viewport_resolution; - - int error = 0; - -}; - diff --git a/include/raycaster/Software_Caster.h b/include/raycaster/Software_Caster.h deleted file mode 100644 index 321bacc..0000000 --- a/include/raycaster/Software_Caster.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once -#include "raycaster/RayCaster.h" -#include -#include "map/Old_Map.h" -#include "Camera.h" - -struct PackedData; - -class Software_Caster : public RayCaster -{ -public: - Software_Caster(); - - virtual ~Software_Caster(); - - int init() override; - - // In interop mode, this will create a GL texture that we share - // Otherwise, it will create the pixel buffer and pass that in as an image, retrieving it each draw - // Both will create the view matrix, view res buffer - void create_viewport(int width, int height, float v_fov, float h_fov) override; - - void assign_lights(std::vector *data) override; - void assign_map(Old_Map *map) override; - void assign_camera(Camera *camera) override; - void validate() override; - - // draw will abstract the gl sharing and software rendering - // methods of retrieving the screen buffer - void compute() override; - void draw(sf::RenderWindow* window) override; - -private: - - void cast_viewport(); - void cast_thread(int start_id, int end_id); - void cast_ray(int id); - void blit_pixel(sf::Color color, sf::Vector2i position, sf::Vector3i mask); - sf::Color global_light(sf::Color in, sf::Vector3i mask); -}; diff --git a/src/Camera.cpp b/src/Camera.cpp index 89fa6a6..84f461d 100644 --- a/src/Camera.cpp +++ b/src/Camera.cpp @@ -54,7 +54,6 @@ int Camera::add_relative_impulse(DIRECTION impulse_direction, float speed) { } - std::cout << movement.x << " : " << movement.y << " : " << movement.z << std::endl; movement += SphereToCart(dir) * speed; return 1; diff --git a/src/Input.cpp b/src/Input.cpp index a425b38..75d44f0 100644 --- a/src/Input.cpp +++ b/src/Input.cpp @@ -112,7 +112,6 @@ void Input::handle_held_keys() { void Input::dispatch_events() { - std::cout << event_queue.size() << std::endl; while (event_queue.size() != 0) { notify_subscribers(std::move(event_queue.front())); event_queue.pop_front(); diff --git a/src/main.cpp b/src/main.cpp index 40ef67e..079030d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -29,7 +29,6 @@ #include #include #include "map/Old_Map.h" -#include "raycaster/RayCaster.h" #include "raycaster/Hardware_Caster.h" #include "Vector4.hpp" #include "Camera.h" @@ -39,6 +38,7 @@ #include "LightHandle.h" #include "imgui/imgui-SFML.h" #include "imgui/imgui.h" +#include "map/Map.h" const int WINDOW_X = 1536; const int WINDOW_Y = 1024; diff --git a/src/raycaster/Hardware_Caster.cpp b/src/raycaster/Hardware_Caster.cpp index 2b62460..e30d80d 100644 --- a/src/raycaster/Hardware_Caster.cpp +++ b/src/raycaster/Hardware_Caster.cpp @@ -1002,16 +1002,16 @@ bool Hardware_Caster::vr_assert(int error_code, std::string function_name) { case CL_PLATFORM_NOT_FOUND_KHR : err_msg = "CL_PLATFORM_NOT_FOUND_KHR"; break; - case RayCaster::SHARING_NOT_SUPPORTED: + case Hardware_Caster::SHARING_NOT_SUPPORTED: err_msg = "SHARING_NOT_SUPPORTED"; break; - case RayCaster::OPENCL_NOT_SUPPORTED: + case Hardware_Caster::OPENCL_NOT_SUPPORTED: err_msg = "OPENCL_NOT_SUPPORTED"; break; - case RayCaster::OPENCL_ERROR: + case Hardware_Caster::OPENCL_ERROR: err_msg = "OPENCL_ERROR"; break; - case RayCaster::ERR: + case Hardware_Caster::ERR: err_msg = "ERROR"; break; } diff --git a/src/raycaster/RayCaster.cpp b/src/raycaster/RayCaster.cpp deleted file mode 100644 index bbbc3aa..0000000 --- a/src/raycaster/RayCaster.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "raycaster/RayCaster.h" - -RayCaster::RayCaster() { -} - -RayCaster::~RayCaster() { -} \ No newline at end of file diff --git a/src/raycaster/Software_Caster.cpp b/src/raycaster/Software_Caster.cpp deleted file mode 100644 index 13d4a6f..0000000 --- a/src/raycaster/Software_Caster.cpp +++ /dev/null @@ -1,343 +0,0 @@ -#include "raycaster/Software_Caster.h" - - - -Software_Caster::Software_Caster() -{ -} - - -Software_Caster::~Software_Caster() -{ -} - -int Software_Caster::init() -{ - return 1; -} - -void Software_Caster::create_viewport(int width, int height, float v_fov, float h_fov) -{ - // CL needs the screen resolution - viewport_resolution = sf::Vector2i(width, height); - - // And an array of vectors describing the way the "lens" of our - // camera works - // This could be modified to make some odd looking camera lenses - - double y_increment_radians = DegreesToRadians(v_fov / viewport_resolution.y); - double x_increment_radians = DegreesToRadians(h_fov / viewport_resolution.x); - - viewport_matrix = new sf::Vector4f[width * height * 4]; - - for (int y = -viewport_resolution.y / 2; y < viewport_resolution.y / 2; y++) { - for (int x = -viewport_resolution.x / 2; x < viewport_resolution.x / 2; x++) { - - // The base ray direction to slew from - sf::Vector3f ray(1, 0, 0); - - // Y axis, pitch - ray = sf::Vector3f( - static_cast(ray.z * sin(y_increment_radians * y) + ray.x * cos(y_increment_radians * y)), - static_cast(ray.y), - static_cast(ray.z * cos(y_increment_radians * y) - ray.x * sin(y_increment_radians * y)) - ); - - - // Z axis, yaw - ray = sf::Vector3f( - static_cast(ray.x * cos(x_increment_radians * x) - ray.y * sin(x_increment_radians * x)), - static_cast(ray.x * sin(x_increment_radians * x) + ray.y * cos(x_increment_radians * x)), - static_cast(ray.z) - ); - - int index = (x + viewport_resolution.x / 2) + viewport_resolution.x * (y + viewport_resolution.y / 2); - ray = Normalize(ray); - - viewport_matrix[index] = sf::Vector4f( - ray.x, - ray.y, - ray.z, - 0 - ); - } - } - - // Create the image that opencl's rays write to - viewport_image = new sf::Uint8[width * height * 4]; - - for (int i = 0; i < width * height * 4; i += 4) { - - viewport_image[i] = 255; // R - viewport_image[i + 1] = 255; // G - viewport_image[i + 2] = 255; // B - viewport_image[i + 3] = 255; // A - } - - // Interop lets us keep a reference to it as a texture - viewport_texture.create(width, height); - viewport_texture.update(viewport_image); - viewport_sprite.setTexture(viewport_texture); - - -} - -void Software_Caster::assign_lights(std::vector *data) { - -// this->lights = data; - -// int light_count = static_cast(data->size()); -} - -void Software_Caster::assign_map(Old_Map * map) { - this->map = map; -} - -void Software_Caster::assign_camera(Camera * camera) { - this->camera = camera; -} - -void Software_Caster::validate() { - // Check to make sure everything has been entered; - if (camera == nullptr || - map == nullptr || - viewport_image == nullptr || - viewport_matrix == nullptr) { - - std::cout << "Raycaster.validate() failed, camera, map, or viewport not initialized"; - - } -} - -void Software_Caster::compute() { - cast_viewport(); -} - -void Software_Caster::draw(sf::RenderWindow * window) { - viewport_texture.update(viewport_image); - window->draw(viewport_sprite); -} - -void Software_Caster::cast_viewport() { - - std::vector threads; - for (int i = 0; i < 13; i++) { - int s = viewport_resolution.x * ((viewport_resolution.y / 13) * i); - int e = viewport_resolution.x * ((viewport_resolution.y / 13) * (i + 1)); - threads.push_back(new std::thread(&Software_Caster::cast_thread, this, s, e)); - } - - for (auto i : threads) { - i->join(); - delete i; - } -} - -void Software_Caster::cast_thread(int start_id, int end_id) { - - for (int i = start_id; i < end_id; i++) { - cast_ray(i); - } - -} - -void Software_Caster::cast_ray(int id) -{ - sf::Vector2i pixel = { id % viewport_resolution.x, id / viewport_resolution.x }; - - // 4f 3f ?? - sf::Vector4f ray_dir = viewport_matrix[pixel.x + viewport_resolution.x * pixel.y]; - - ray_dir = sf::Vector4f( - ray_dir.z * sin(camera->get_direction().x) + ray_dir.x * cos(camera->get_direction().x), - ray_dir.y, - ray_dir.z * cos(camera->get_direction().x) - ray_dir.x * sin(camera->get_direction().x), - 0 - ); - - ray_dir = sf::Vector4f( - ray_dir.x * cos(camera->get_direction().y) - ray_dir.y * sin(camera->get_direction().y), - ray_dir.x * sin(camera->get_direction().y) + ray_dir.y * cos(camera->get_direction().y), - ray_dir.z, - 0 - ); - - // Setup the voxel step based on what direction the ray is pointing - sf::Vector3i voxel_step = sf::Vector3i( - static_cast(1 * (abs(ray_dir.x) / ray_dir.x)), - static_cast(1 * (abs(ray_dir.y) / ray_dir.y)), - static_cast(1 * (abs(ray_dir.z) / ray_dir.z)) - ); - - // Setup the voxel coords from the camera origin - sf::Vector3i voxel = sf::Vector3i( - static_cast(camera->get_position().x), - static_cast(camera->get_position().y), - static_cast(camera->get_position().z) - ); - - // Delta T is the units a ray must travel along an axis in order to - // traverse an integer split - sf::Vector3f delta_t = sf::Vector3f( - fabs(1.0f / ray_dir.x), - fabs(1.0f / ray_dir.y), - fabs(1.0f / ray_dir.z) - ); - - // offset is how far we are into a voxel, enables sub voxel movement - sf::Vector3f offset = sf::Vector3f( - (camera->get_position().x - floor(camera->get_position().x)) * voxel_step.x, - (camera->get_position().y - floor(camera->get_position().y)) * voxel_step.y, - (camera->get_position().z - floor(camera->get_position().z)) * voxel_step.z - ); - - // Intersection T is the collection of the next intersection points - // for all 3 axis XYZ. - sf::Vector3f intersection_t = sf::Vector3f( - delta_t.x * offset.x, - delta_t.y * offset.y, - delta_t.z * offset.z - ); - - // for negative values, wrap around the delta_t, rather not do this - // component wise, but it doesn't appear to want to work - if (intersection_t.x < 0) { - intersection_t.x += delta_t.x; - } - if (intersection_t.y < 0) { - intersection_t.y += delta_t.y; - } - if (intersection_t.z < 0) { - intersection_t.z += delta_t.z; - } - - // use a ghetto ass rng to give rays a "fog" appearance - sf::Vector2i randoms = { 3, 14 }; - int seed = randoms.x + id; - int t = seed ^ (seed << 11); - int result = randoms.y ^ (randoms.y >> 19) ^ (t ^ (t >> 8)); - - int max_dist = 800 + result % 50; - int dist = 0; - - sf::Vector3i mask = { 0, 0, 0 }; - - // Andrew Woo's raycasting algo - do { - - if ((intersection_t.x) < (intersection_t.y)) { - if ((intersection_t.x) < (intersection_t.z)) { - - mask.x = 1; - voxel.x += voxel_step.x; - intersection_t.x = intersection_t.x + delta_t.x; - } - else { - - mask.z = 1; - voxel.z += voxel_step.z; - intersection_t.z = intersection_t.z + delta_t.z; - } - } - else { - if ((intersection_t.y) < (intersection_t.z)) { - - mask.y = 1; - voxel.y += voxel_step.y; - intersection_t.y = intersection_t.y + delta_t.y; - } - else { - - mask.z = 1; - voxel.z += voxel_step.z; - intersection_t.z = intersection_t.z + delta_t.z; - } - } - - - // If the ray went out of bounds - sf::Vector3i overshoot = sf::Vector3i( - voxel.x <= map->getDimensions().x, - voxel.y <= map->getDimensions().y, - voxel.z <= map->getDimensions().z - ); - - sf::Vector3i undershoot = sf::Vector3i( - voxel.x > 0, - voxel.y > 0, - voxel.z > 0 - ); - - if (overshoot.x == 0 || overshoot.y == 0 || overshoot.z == 0 || undershoot.x == 0 || undershoot.y == 0) { - blit_pixel(sf::Color::Yellow, sf::Vector2i{ pixel.x,pixel.y }, mask); - return; - } - if (undershoot.z == 0) { - blit_pixel(sf::Color::Yellow, sf::Vector2i{ pixel.x,pixel.y }, mask); - return; - } - - // If we hit a voxel - //int index = voxel.x * (*map_dim).y * (*map_dim).z + voxel.z * (*map_dim).z + voxel.y; - // Why the off by one on voxel.y? - int index = voxel.x + map->getDimensions().x * (voxel.y + map->getDimensions().z * (voxel.z - 1)); - int voxel_data = map->get_voxel_data()[index]; - - if (voxel_data != 0) { - switch (voxel_data) { - case 1: - blit_pixel(sf::Color::Green, sf::Vector2i{ pixel.x,pixel.y }, mask); - return; - case 2: - blit_pixel(sf::Color::Green, sf::Vector2i{ pixel.x,pixel.y }, mask); - return; - case 3: - blit_pixel(sf::Color::Green, sf::Vector2i{ pixel.x,pixel.y }, mask); - return; - case 4: - blit_pixel(sf::Color::Green, sf::Vector2i{ pixel.x,pixel.y }, mask); - return; - case 5: - blit_pixel(sf::Color(30, 10, 200, 100), sf::Vector2i{ pixel.x,pixel.y }, mask); - return; - case 6: - blit_pixel(sf::Color::Green, sf::Vector2i{ pixel.x,pixel.y }, mask); - return; - default: - //write_imagef(image, pixel, (float4)(.30, .2550, .2550, 255.00)); - return; - } - } - - dist++; - } while (dist < max_dist); - - blit_pixel(sf::Color::Red, sf::Vector2i{ pixel.x,pixel.y }, mask); - return; -} - -void Software_Caster::blit_pixel(sf::Color color, sf::Vector2i position, sf::Vector3i mask) { - - sf::Color t = global_light(color, mask); - viewport_image[(position.x + viewport_resolution.x * position.y) * 4 + 0] = t.r; - viewport_image[(position.x + viewport_resolution.x * position.y) * 4 + 1] = t.g; - viewport_image[(position.x + viewport_resolution.x * position.y) * 4 + 2] = t.b; - viewport_image[(position.x + viewport_resolution.x * position.y) * 4 + 3] = t.a; -} - -sf::Color Software_Caster::global_light(sf::Color in, sf::Vector3i mask) { - - // I think I may scrap this whole software fallback caster thing - - //sf::Vector3f mask_f(mask); - - //in.a = in.a + (int)acos( - // DotProduct( - // Normalize(lights->at(0).direction_cartesian), - // Normalize(mask_f) - // ) - // )/ 2; - - return in; - -} \ No newline at end of file