diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/include/Map.h b/include/Map.h index 6034a50..b001d9b 100644 --- a/include/Map.h +++ b/include/Map.h @@ -1,6 +1,8 @@ #pragma once #include +#include #include +#include class Map { public: @@ -10,47 +12,19 @@ public: list[i] = 0; } - for (int i = 51; i < 52; i++) { - list[55 + dim.x * (55 + dim.z * i)] = 1; - } - - // The X walls get red and magenta - for (int x = 0; x < dim.x; x += 2) { - for (int y = 0; y < dim.y; y += 2) { - list[x + dim.x * (y + dim.z * 1)] = 1; - } - } - for (int x = 0; x < dim.x; x += 2) { - for (int y = 0; y < dim.y; y += 2) { - list[x + dim.x * (y + dim.z * 99)] = 2; - } - } - - // The Z walls get yellow and some other color - for (int x = 0; x < dim.x; x += 2) { - for (int z = 0; z < dim.z; z += 2) { - list[x + dim.x * (99 + dim.z * z)] = 3; - } - } - for (int x = 0; x < dim.x; x += 2) { - for (int z = 0; z < dim.z; z += 2) { - list[x + dim.x * (1 + dim.z * z)] = 4; - } - } - - - for (int y = 0; y < dim.y; y += 2) { - for (int z = 0; z < dim.z; z += 2) { - list[99 + dim.x * (y + dim.z * z)] = 5; - } - } - for (int y = 0; y < dim.y; y += 2) { - for (int z = 0; z < dim.z; z += 2) { - list[1 + dim.x * (y + dim.z * z)] = 6; - } - } + for (int x = 0; x < dim.x; x++) { + for (int y = 0; y < dim.y; y++) { + for (int z = 0; z < dim.z; z++) { + if (rand() % 100 < 1) + list[x + dim.x * (y + dim.z * z)] = rand() % 6; + else + list[x + dim.x * (y + dim.z * z)] = 0; + } + } + } dimensions = dim; + global_light = sf::Vector3f(0.2, 0.4, 1); } ~Map() { @@ -60,6 +34,9 @@ public: char *list; sf::Vector3i dimensions; + void moveLight(sf::Vector2f in); + sf::Vector3f global_light; + protected: private: diff --git a/include/util.hpp b/include/util.hpp index 9e1251f..8b5591c 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -68,6 +68,19 @@ inline sf::Vector3f Normalize(sf::Vector3f in) { } + +inline float DotProduct(sf::Vector3f a, sf::Vector3f b){ + return a.x * b.x + a.y * b.y + a.z * b.z; +} + +inline float Magnitude(sf::Vector3f in){ + return sqrt(in.x * in.x + in.y * in.y + in.z * in.z); +} + +inline float AngleBetweenVectors(sf::Vector3f a, sf::Vector3f b){ + return acos(DotProduct(a, b) / (Magnitude(a) * Magnitude(b))); +} + inline float DegreesToRadians(float in) { return in * PI / 180.0f; } diff --git a/src/Map.cpp b/src/Map.cpp index 9a27686..cda7e77 100644 --- a/src/Map.cpp +++ b/src/Map.cpp @@ -2,7 +2,72 @@ #include "Map.h" #include #include +#include +#include "util.hpp" sf::Vector3i Map::getDimensions() { return dimensions; -} \ No newline at end of file +} + +void Map::moveLight(sf::Vector2f in) { + + sf::Vector3f light_spherical = CartToSphere(global_light); + + light_spherical.y += in.y; + light_spherical.x += in.x; + + global_light = SphereToCart(light_spherical); + + return; + +} + +//void Map::GenerateFloor(){ +//} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Ray.cpp b/src/Ray.cpp index 69a0384..bddc135 100644 --- a/src/Ray.cpp +++ b/src/Ray.cpp @@ -51,27 +51,34 @@ sf::Color Ray::Cast() { delta_t.z ); + int dist = 0; + int face = -1; + // X:0, Y:1, Z:2 // Andrew Woo's raycasting algo do { if ((intersection_t.x) < (intersection_t.y)) { if ((intersection_t.x) < (intersection_t.z)) { + face = 0; voxel.x += voxel_step.x; intersection_t.x = intersection_t.x + delta_t.x; } else { + face = 2; voxel.z += voxel_step.z; intersection_t.z = intersection_t.z + delta_t.z; } } else { if ((intersection_t.y) < (intersection_t.z)) { + face = 1; voxel.y += voxel_step.y; intersection_t.y = intersection_t.y + delta_t.y; } else { + face = 2; voxel.z += voxel_step.z; intersection_t.z = intersection_t.z + delta_t.z; } @@ -100,19 +107,43 @@ sf::Color Ray::Cast() { // If we hit a voxel int index = voxel.x + dimensions.x * (voxel.y + dimensions.z * voxel.z); - switch (map->list[index]) { + int voxel_data = map->list[index]; + + float alpha = 0; + if (face == 0) { + + alpha = AngleBetweenVectors(sf::Vector3f(1, 0, 0), map->global_light); + alpha = fmod(alpha, 0.785) * 2; + + } else if (face == 1) { + + alpha = AngleBetweenVectors(sf::Vector3f(0, 1, 0), map->global_light); + alpha = fmod(alpha, 0.785) * 2; + + } else if (face == 2){ + + //alpha = 1.57 / 2; + alpha = AngleBetweenVectors(sf::Vector3f(0, 0, 1), map->global_light); + alpha = fmod(alpha, 0.785) * 2; + } + + alpha *= 162; + + switch (voxel_data) { case 1: - return sf::Color::Red; + // AngleBew0 - 1.57 * 162 = 0 - 255 + + return sf::Color(255, 0, 0, alpha); case 2: - return sf::Color::Magenta; + return sf::Color(255, 10, 0, alpha); case 3: - return sf::Color::Yellow; + return sf::Color(255, 0, 255, alpha); case 4: - return sf::Color(80, 0, 150, 255); + return sf::Color(80, 0, 150, alpha); case 5: - return sf::Color(255, 120, 255, 255); + return sf::Color(255, 120, 255, alpha); case 6: - return sf::Color(150, 80, 220, 255); + return sf::Color(150, 80, 220, alpha); } dist++; diff --git a/src/main.cpp b/src/main.cpp index cb63a86..2ee2da9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,8 +6,8 @@ #include "RayCaster.h" #include -const int WINDOW_X = 600; -const int WINDOW_Y = 600; +const int WINDOW_X = 200; +const int WINDOW_Y = 200; float elap_time(){ @@ -27,23 +27,44 @@ float elap_time(){ sf::Sprite window_sprite; sf::Texture window_texture; +// Y: -1.57 is straight up +// Y: 1.57 is straight down + +void test_ray_reflection(){ + + sf::Vector3f r(0.588, -0.78, -0.196); + sf::Vector3f i(0, 0.928, 0.37); + + // is this needed? free spin but bounded 0 < z < pi + if (i.z > PI) + i.z -= PI; + else if (i.z < 0) + i.z += PI; + + std::cout << AngleBetweenVectors(r, i); + + + + return; +} + int main() { - // Initialize the render window - sf::RenderWindow window(sf::VideoMode(WINDOW_X, WINDOW_Y), "SFML"); + // Initialize the render window + sf::RenderWindow window(sf::VideoMode(WINDOW_X, WINDOW_Y), "SFML"); - // The step size in milliseconds between calls to Update() - // Lets set it to 16.6 milliseonds (60FPS) - float step_size = 0.0166f; + // The step size in milliseconds between calls to Update() + // Lets set it to 16.6 milliseonds (60FPS) + float step_size = 0.0166f; - // Timekeeping values for the loop - double frame_time = 0.0, - elapsed_time = 0.0, - delta_time = 0.0, - accumulator_time = 0.0, - current_time = 0.0; + // Timekeeping values for the loop + double frame_time = 0.0, + elapsed_time = 0.0, + delta_time = 0.0, + accumulator_time = 0.0, + current_time = 0.0; - fps_counter fps; + fps_counter fps; // ============================= RAYCASTER SETUP ================================== @@ -52,7 +73,7 @@ int main() { window_sprite.setPosition(0, 0); // State values - sf::Vector3i map_dim(200, 200, 200); + sf::Vector3i map_dim(50, 50, 50); sf::Vector2i view_res(WINDOW_X, WINDOW_Y); sf::Vector3f cam_dir(1.0f, 0.0f, 1.57f); sf::Vector3f cam_pos(50, 50, 50); @@ -147,10 +168,12 @@ int main() { // Take away a step from the accumulator accumulator_time -= step_size; + // And update the application for the amount of time alotted for one step // Update(step_size); } + map->moveLight(sf::Vector2f(0.3, 0)); window.clear(sf::Color::Black);