From bb9fab630589203c4b52c9b7a27aea9470608b05 Mon Sep 17 00:00:00 2001 From: MitchellHansen Date: Fri, 30 Dec 2016 21:02:04 -0800 Subject: [PATCH] Added lookat function. Fixed various coordinate missmatches and issues. Fixed camera movement. Added some input functions. I need some way to log fps and find those hitches --- include/Camera.h | 4 ++ include/Map.h | 38 ++++++------ include/util.hpp | 72 +++++++++++++++++++++++ kernels/ray_caster_kernel.cl | 10 +++- src/Camera.cpp | 38 +++++++++--- src/Map.cpp | 108 +++++++++++------------------------ src/Old_map.cpp | 2 + src/main.cpp | 26 +++++++-- 8 files changed, 191 insertions(+), 107 deletions(-) diff --git a/include/Camera.h b/include/Camera.h index 56548a2..817f9fb 100644 --- a/include/Camera.h +++ b/include/Camera.h @@ -18,9 +18,13 @@ public: int add_relative_impulse(DIRECTION direction, float speed); int slew_camera(sf::Vector2f input); + void set_camera(sf::Vector2f input); + void set_camera(sf::Vector3f input); int update(double delta_time); + void look_at_center(); + sf::Vector2f* get_direction_pointer(); sf::Vector3f* get_position_pointer(); sf::Vector3f* get_movement_pointer(); diff --git a/include/Map.h b/include/Map.h index 11eabe3..93e7f4f 100644 --- a/include/Map.h +++ b/include/Map.h @@ -19,36 +19,28 @@ #define CHUNK_DIM 32 #define OCT_DIM 64 -struct KeyHasher { +struct XYZHasher { std::size_t operator()(const sf::Vector3i& k) const { - return ((std::hash()(k.x) ^ (std::hash()(k.y) << 1)) >> 1) ^ (std::hash()(k.z) << 1); } }; -struct Chunk { - Chunk(int type) { voxel_data = new int[CHUNK_DIM * CHUNK_DIM * CHUNK_DIM]; set(type); }; - Chunk() { }; - void set(int type); - ~Chunk() { voxel_data = nullptr; }; - int* voxel_data; -}; - class Octree { - public: Octree() { - dat = new uint64_t[(int)pow(2, 15)]; - for (int i = 0; i < (int)pow(2, 15); i++) { - dat[i] = 0; + + // initialize the first stack block + stack.push_back(new uint64_t[0x8000]); + for (int i = 0; i < 0x8000; i++) { + stack.back() = 0; } }; ~Octree() {}; - uint64_t *dat; + std::list stack; uint64_t stack_pos = 0x8000; uint64_t global_pos = 0; @@ -65,7 +57,7 @@ public: // Check for the far bit - memcpy(&dat[stack_pos + global_pos], children.data(), children.size() * sizeof(uint64_t)); + memcpy(&stack.front()[stack_pos + global_pos], children.data(), children.size() * sizeof(uint64_t)); // Return the bitmask encoding the index of that value // If we tripped the far bit, allocate a far index to the stack and place @@ -76,6 +68,17 @@ public: return stack_pos; }; + void print_block(int block_pos) { + std::stringstream sss; + for (int i = 0; i < (int)pow(2, 15); i++) { + PrettyPrintUINT64(stack.front()[i], &sss); + sss << "\n"; + } + DumpLog(&sss, "raw_data.txt"); + } + + + }; @@ -84,6 +87,7 @@ public: class Map { public: + Map(sf::Vector3i dim); void generate_octree(); @@ -118,7 +122,7 @@ private: char getVoxel(sf::Vector3i pos); char* voxel_data = new char[OCT_DIM * OCT_DIM * OCT_DIM]; - std::unordered_map chunk_map; + //std::unordered_map chunk_map; double* height_map; diff --git a/include/util.hpp b/include/util.hpp index feaedbd..a33caa6 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -7,6 +7,9 @@ #include "Vector4.hpp" #include #include +#include +#include + const double PI = 3.141592653589793238463; const float PI_F = 3.14159265358979f; @@ -125,6 +128,20 @@ inline sf::Vector3f CartToSphere(sf::Vector3f in) { return r; }; +inline sf::Vector2f CartToNormalizedSphere(sf::Vector3f in) { + + auto r = sf::Vector2f( + atan2(sqrt(in.x * in.x + in.y * in.y), in.z), + atan2(in.y, in.x) + ); + + return r; +} + +inline sf::Vector3f FixOrigin(sf::Vector3f base, sf::Vector3f head) { + return head - base; +} + inline sf::Vector3f Normalize(sf::Vector3f in) { @@ -202,4 +219,59 @@ inline void DumpLog(std::stringstream* ss, std::string file_name) { log_file.close(); +} + +inline std::string sfml_get_input(sf::RenderWindow *window) { + + std::stringstream ss; + + sf::Event event; + while (window->pollEvent(event)) { + if (event.type == sf::Event::TextEntered) { + ss << event.text.unicode; + } + + else if (event.type == sf::Event::KeyPressed) { + if (event.key.code == sf::Keyboard::Return) { + return ss.str(); + } + } + } +} + +inline std::vector sfml_get_float_input(sf::RenderWindow *window) { + + std::stringstream ss; + + sf::Event event; + while (true) { + + if (window->pollEvent(event)) { + + if (event.type == sf::Event::TextEntered) { + if (event.text.unicode > 47 && event.text.unicode < 58 || event.text.unicode == 32) + ss << static_cast(event.text.unicode); + } + + else if (event.type == sf::Event::KeyPressed) { + + if (event.key.code == sf::Keyboard::Return) { + break; + } + } + } + } + + std::istream_iterator begin(ss); + std::istream_iterator end; + std::vector vstrings(begin, end); + + std::vector ret; + + for (auto i: vstrings) { + ret.push_back(std::stof(i)); + } + + return ret; + } \ No newline at end of file diff --git a/kernels/ray_caster_kernel.cl b/kernels/ray_caster_kernel.cl index 1c01ca0..078851f 100644 --- a/kernels/ray_caster_kernel.cl +++ b/kernels/ray_caster_kernel.cl @@ -111,10 +111,16 @@ __kernel void raycaster( int2 pixel = {id % (*resolution).x, id / (*resolution).x}; float3 ray_dir = projection_matrix[pixel.x + (*resolution).x * pixel.y]; + if (pixel.x == 960 && pixel.y == 540) { + write_imagef(image, pixel, (float4)(0.00, 1.00, 0.00, 1.00)); + return; + } + ray_dir = (float3)( - ray_dir.z * sin((*cam_dir).x) + ray_dir.x * cos((*cam_dir).x), + // 1.57s are temp fix until view matrix is tweaked + ray_dir.z * sin((*cam_dir).x - 1.57) + ray_dir.x * cos((*cam_dir).x - 1.57), ray_dir.y, - ray_dir.z * cos((*cam_dir).x) - ray_dir.x * sin((*cam_dir).x) + ray_dir.z * cos((*cam_dir).x - 1.57) - ray_dir.x * sin((*cam_dir).x - 1.57) ); ray_dir = (float3)( diff --git a/src/Camera.cpp b/src/Camera.cpp index 3be57ef..0710593 100644 --- a/src/Camera.cpp +++ b/src/Camera.cpp @@ -33,22 +33,22 @@ int Camera::add_relative_impulse(DIRECTION impulse_direction, float speed) { switch (impulse_direction) { - case DIRECTION::UP: - dir = sf::Vector2f(direction.y, direction.x + PI_F); - break; - case DIRECTION::DOWN: + case DIRECTION::FORWARD: dir = sf::Vector2f(direction.y, direction.x); break; + case DIRECTION::REARWARD: + dir = sf::Vector2f(direction.y, direction.x + PI_F); + break; case DIRECTION::LEFT: dir = sf::Vector2f(direction.y + PI_F + PI_F / 2, PI_F / 2); break; case DIRECTION::RIGHT: dir = sf::Vector2f(direction.y + PI_F / 2, PI_F / 2); break; - case DIRECTION::FORWARD: + case DIRECTION::UP: dir = sf::Vector2f(direction.y, direction.x + PI_F / 2); break; - case DIRECTION::REARWARD: + case DIRECTION::DOWN: dir = sf::Vector2f(direction.y + PI_F, (direction.x * -1) + PI_F / 2 ); break; @@ -65,10 +65,16 @@ int Camera::slew_camera(sf::Vector2f input) { return 1; } +void Camera::set_camera(sf::Vector2f input) { + direction = input; +} + +void Camera::set_camera(sf::Vector3f input) { + direction = CartToNormalizedSphere(input); +} + int Camera::update(double delta_time) { - // so vector multiplication broke? - // have to do it component wise double multiplier = 40; position.x += static_cast(movement.x * delta_time * multiplier); @@ -80,6 +86,22 @@ int Camera::update(double delta_time) { return 1; } +void Camera::look_at_center() { + //std::cout << "X:" << position.x << std::endl; + //std::cout << "Y:" << position.y << std::endl; + //std::cout << "Z:" << position.z << std::endl; + + //std::cout << "dx:" << direction.x << std::endl; + //std::cout << "dy:" << direction.y << std::endl; + + direction = CartToNormalizedSphere(sf::Vector3f(75, 75, 75) - position); + + //std::cout << "dx:" << direction.x << std::endl; + //std::cout << "dy:" << direction.y << std::endl; + +} + + sf::Vector2f* Camera::get_direction_pointer() { return &direction; } diff --git a/src/Map.cpp b/src/Map.cpp index 8e1b5ea..2432112 100644 --- a/src/Map.cpp +++ b/src/Map.cpp @@ -174,69 +174,40 @@ void Map::generate_octree() { generate_children(sf::Vector3i(0, 0, 0), OCT_DIM/2); DumpLog(&ss, "raw_output.txt"); - std::stringstream sss; - for (int i = 0; i < (int)pow(2, 15); i++) { - PrettyPrintUINT64(a.dat[i], &sss); - sss << "\n"; - } - DumpLog(&sss, "raw_data.txt"); - - // levels defines how many levels to traverse before we hit raw data - // Will be the map width I presume. Will still need to handle how to swap in and out data. - // Possible have some upper static nodes that will stay full regardless of contents? - int levels = static_cast(log2(64)); - - - std::list parent_stack; - - int byte_pos = 0; - - unsigned int parent = 0; - for (int i = 0; i < 16; i++) { - parent ^= 1 << i; - } - - unsigned int leafmask = 255; - unsigned int validmask = leafmask << 8; - - parent &= validmask; - parent &= leafmask; + a.print_block(0); - std::cout << BitCount(parent & leafmask); - - unsigned int children[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; } void Map::load_unload(sf::Vector3i world_position) { - sf::Vector3i chunk_pos(world_to_chunk(world_position)); - - //Don't forget the middle chunk - if (chunk_map.find(chunk_pos) == chunk_map.end()) { - chunk_map[chunk_pos] = Chunk(5); - } - - for (int x = chunk_pos.x - chunk_radius / 2; x < chunk_pos.x + chunk_radius / 2; x++) { - for (int y = chunk_pos.y - chunk_radius / 2; y < chunk_pos.y + chunk_radius / 2; y++) { - for (int z = chunk_pos.z - chunk_radius / 2; z < chunk_pos.z + chunk_radius / 2; z++) { - - if (chunk_map.find(sf::Vector3i(x, y, z)) == chunk_map.end()) { - chunk_map.emplace(sf::Vector3i(x, y, z), Chunk(rand() % 6)); - //chunk_map[sf::Vector3i(x, y, z)] = Chunk(rand() % 6); - } - } - } - } + //sf::Vector3i chunk_pos(world_to_chunk(world_position)); + // + ////Don't forget the middle chunk + //if (chunk_map.find(chunk_pos) == chunk_map.end()) { + // chunk_map[chunk_pos] = Chunk(5); + //} + + //for (int x = chunk_pos.x - chunk_radius / 2; x < chunk_pos.x + chunk_radius / 2; x++) { + // for (int y = chunk_pos.y - chunk_radius / 2; y < chunk_pos.y + chunk_radius / 2; y++) { + // for (int z = chunk_pos.z - chunk_radius / 2; z < chunk_pos.z + chunk_radius / 2; z++) { + + // if (chunk_map.find(sf::Vector3i(x, y, z)) == chunk_map.end()) { + // chunk_map.emplace(sf::Vector3i(x, y, z), Chunk(rand() % 6)); + // //chunk_map[sf::Vector3i(x, y, z)] = Chunk(rand() % 6); + // } + // } + // } + //} } void Map::load_single(sf::Vector3i world_position) { - sf::Vector3i chunk_pos(world_to_chunk(world_position)); + //sf::Vector3i chunk_pos(world_to_chunk(world_position)); - //Don't forget the middle chunk - if (chunk_map.find(chunk_pos) == chunk_map.end()) { - chunk_map[chunk_pos] = Chunk(0); - } + ////Don't forget the middle chunk + //if (chunk_map.find(chunk_pos) == chunk_map.end()) { + // chunk_map[chunk_pos] = Chunk(0); + //} } sf::Vector3i Map::getDimensions() { @@ -245,16 +216,16 @@ sf::Vector3i Map::getDimensions() { void Map::setVoxel(sf::Vector3i world_position, int val) { - load_single(world_position); - sf::Vector3i chunk_pos(world_to_chunk(world_position)); - sf::Vector3i in_chunk_pos( - world_position.x % CHUNK_DIM, - world_position.y % CHUNK_DIM, - world_position.z % CHUNK_DIM - ); + //load_single(world_position); + //sf::Vector3i chunk_pos(world_to_chunk(world_position)); + //sf::Vector3i in_chunk_pos( + // world_position.x % CHUNK_DIM, + // world_position.y % CHUNK_DIM, + // world_position.z % CHUNK_DIM + //); - chunk_map.at(chunk_pos).voxel_data[in_chunk_pos.x + CHUNK_DIM * (in_chunk_pos.y + CHUNK_DIM * in_chunk_pos.z)] - = val; + //chunk_map.at(chunk_pos).voxel_data[in_chunk_pos.x + CHUNK_DIM * (in_chunk_pos.y + CHUNK_DIM * in_chunk_pos.z)] + // = val; } @@ -262,16 +233,3 @@ char Map::getVoxel(sf::Vector3i pos){ return voxel_data[pos.x + OCT_DIM * (pos.y + OCT_DIM * pos.z)]; } - -void Chunk::set(int type) { - for (int i = 0; i < CHUNK_DIM * CHUNK_DIM * CHUNK_DIM; i++) { - voxel_data[i] = 0; - } - - for (int x = 0; x < CHUNK_DIM; x+=2) { - for (int y = 0; y < CHUNK_DIM; y+=2) { - //list[x + dim.x * (y + dim.z * z)] - voxel_data[x + CHUNK_DIM * (y + CHUNK_DIM * 1)] = type; - } - } -} diff --git a/src/Old_map.cpp b/src/Old_map.cpp index e4a5d43..35a5ac6 100644 --- a/src/Old_map.cpp +++ b/src/Old_map.cpp @@ -26,6 +26,8 @@ void Old_Map::generate_terrain() { voxel_data[i] = 0; } + set_voxel(sf::Vector3i(75, 75, 75), 5); + for (int i = 0; i < dimensions.x * dimensions.y; i++) { height_map[i] = 0; } diff --git a/src/main.cpp b/src/main.cpp index 3e2f896..85c4277 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -65,8 +65,8 @@ sf::Texture window_texture; int main() { - Map _map(sf::Vector3i(0, 0, 0)); - _map.generate_octree(); + //Map _map(sf::Vector3i(0, 0, 0)); + //_map.generate_octree(); glewInit(); @@ -101,8 +101,8 @@ int main() { rc->assign_map(map); Camera *camera = new Camera( - sf::Vector3f(10, 11, 12), - sf::Vector2f(0.1f, 1.00f) + sf::Vector3f(50, 50, 50), + sf::Vector2f(0.0f, 1.5707f) ); rc->assign_camera(camera); @@ -126,6 +126,9 @@ int main() { sf::Vector2f *dp = camera->get_direction_pointer(); debug_text cam_text_x(1, 30, &dp->x, "incli: "); debug_text cam_text_y(2, 30, &dp->y, "asmth: "); + debug_text cam_text_pos_x(3, 30, &camera->get_position_pointer()->x, "x: "); + debug_text cam_text_pos_y(4, 30, &camera->get_position_pointer()->y, "y: "); + debug_text cam_text_pos_z(5, 30, &camera->get_position_pointer()->z, "z: "); // =========================== @@ -154,13 +157,19 @@ int main() { window.close(); if (event.type == sf::Event::KeyPressed) { - if (event.key.code == sf::Keyboard::Space) { + if (event.key.code == sf::Keyboard::M) { if (mouse_enabled) mouse_enabled = false; else mouse_enabled = true; } if (event.key.code == sf::Keyboard::R) { reset = true; + } if (event.key.code == sf::Keyboard::X) { + std::vector tvf = sfml_get_float_input(&window); + if (tvf.size() == 3){ + sf::Vector3f tv3(tvf.at(0), tvf.at(1), tvf.at(2)); + camera->set_position(tv3); + } } } } @@ -170,6 +179,9 @@ int main() { if (sf::Keyboard::isKeyPressed(sf::Keyboard::LShift)) { speed = 0.2f; } + if (sf::Keyboard::isKeyPressed(sf::Keyboard::L)) { + camera->look_at_center(); + } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Q)) { camera->add_relative_impulse(Camera::DIRECTION::DOWN, speed); } @@ -252,6 +264,10 @@ int main() { cam_text_x.draw(&window); cam_text_y.draw(&window); + cam_text_pos_x.draw(&window); + cam_text_pos_y.draw(&window); + cam_text_pos_z.draw(&window); + window.display(); }