From 0a457f50a606bc8e216aaadf3a6b685e56aea2be Mon Sep 17 00:00:00 2001 From: MitchellHansen Date: Mon, 6 Mar 2017 01:01:48 -0800 Subject: [PATCH] A decent amount of progress on voxel traversal. Converted most of it to C code to make the CL version easier --- include/Map.h | 95 +++++++++++++++++++++++++++++++++++++++++++----- include/util.hpp | 22 +++++++++++ src/Map.cpp | 12 +++--- src/main.cpp | 8 +++- 4 files changed, 119 insertions(+), 18 deletions(-) diff --git a/include/Map.h b/include/Map.h index 8af3ecf..e31d00b 100644 --- a/include/Map.h +++ b/include/Map.h @@ -79,18 +79,41 @@ public: } + // (X, Y, Z) mask for the idx + uint8_t idx_set_x_mask = 0x1; + uint8_t idx_set_y_mask = 0x2; + uint8_t idx_set_z_mask = 0x4; + + uint8_t mask_8[8] = { + 0x0, 0x1, 0x2, 0x3, + 0x4, 0x5, 0x6, 0x7 + }; + + uint8_t count_mask_8[8]{ + 0x1, 0x3, 0x7, 0xF, + 0x1F, 0x3F, 0x7F, 0xFF + }; + // With a position and the head of the stack. Traverse down the voxel hierarchy to find + // the IDX and stack position of the highest resolution (maybe set resolution?) oct bool get_voxel(sf::Vector3i position) { // Init the parent stack and push the head node - std::queue parent_stack; + //std::queue parent_stack; + + int parent_stack_position = 0; + uint64_t parent_stack[32] = {0}; uint64_t head = block_stack.front()[stack_pos]; - parent_stack.push(head); + parent_stack[parent_stack_position] = head; + // Get the index of the first child of the head node uint64_t index = head & child_pointer_mask; + uint8_t scale = 0; + uint8_t idx_stack[32] = {0}; + // Init the idx stack std::vector> scale_stack(log2(OCT_DIM)); @@ -100,31 +123,83 @@ public: while (dimension > 1) { - // Do the logic steps to find which sub oct we step down into + // So we can be a little bit tricky here and increment our + // array index that holds our masks as we build the idx. + // Adding 1 for X, 2 for Y, and 4 for Z + int mask_index = 0; + + // Do the logic steps to find which sub oct we step down into if (position.x >= (dimension / 2) + quad_position.x) { + + // Set our voxel position to the (0,0) of the correct oct quad_position.x += (dimension / 2); + + // increment the mask index and mentioned above + mask_index += 1; + + // Set the idx to represent the move + idx_stack[scale] |= idx_set_x_mask; + + // Debug scale_stack.at(log2(OCT_DIM) - log2(dimension)).set(0); + } if (position.y >= (dimension / 2) + quad_position.y) { - quad_position.y += (dimension / 2); + + quad_position.y |= (dimension / 2); + + mask_index += 2; + + idx_stack[scale] ^= idx_set_y_mask; scale_stack.at(log2(OCT_DIM) - log2(dimension)).set(1); } if (position.z >= (dimension / 2) + quad_position.z) { + quad_position.z += (dimension / 2); - scale_stack.at(log2(OCT_DIM) - log2(dimension)).set(2); - } - // Set the new dimension - dimension /= 2; + mask_index += 4; + idx_stack[scale] |= idx_set_z_mask; + scale_stack.at(log2(OCT_DIM) - log2(dimension)).set(2); + } + // Check to see if we are on a valid oct + if ((head >> 16) & mask_8[mask_index]) { + + // Check to see if it is a leaf + if ((head >> 24) & mask_8[mask_index]) { + + // If it is, then we cannot traverse further as CP's won't have been generated + break; + } + + // If all went well and we found a valid non-leaf oct then we will traverse further down the hierarchy + scale++; + dimension /= 2; + + // We also need to traverse to the correct child pointer + + // Count the number of non-leaf octs that come before and add it to the current parent stack position + int count = count_bits((uint8_t)(head >> 24) ^ count_mask_8[mask_index]); + int index = (parent_stack[parent_stack_position] & child_pointer_mask) + count; + + // Increment the parent stack position and put the new oct node as the parent + parent_stack_position++; + parent_stack[parent_stack_position] = block_stack.front()[index]; + + } else { + // If the oct was not valid, then no CP's exists any further + // It appears that the traversal is now working but I need + // to focus on how to now take care of the end condition. + // Currently it adds the last parent on the second to lowest + // oct CP. Not sure if thats correct + break; + } } - uint64_t child1 = block_stack.front()[index]; - uint64_t child2 = block_stack.front()[index+1]; std::bitset<64> t(index); auto val = t.count(); diff --git a/include/util.hpp b/include/util.hpp index 4be91fd..61596d5 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -272,3 +272,25 @@ inline std::vector sfml_get_float_input(sf::RenderWindow *window) { } +inline int count_bits(int32_t v) { + + v = v - ((v >> 1) & 0x55555555); // reuse input as temporary + v = (v & 0x33333333) + ((v >> 2) & 0x33333333); // temp + return (((v + (v >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24; // count +} + +inline int count_bits(int64_t v) { + + int32_t left = (int32_t)(v); + int32_t right = (int32_t)(v >> 32); + + left = left - ((left >> 1) & 0x55555555); // reuse input as temporary + left = (left & 0x33333333) + ((left >> 2) & 0x33333333); // temp + left = ((left + (left >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // count + + right = right - ((right >> 1) & 0x55555555); // reuse input as temporary + right = (right & 0x33333333) + ((right >> 2) & 0x33333333); // temp + right = ((right + (right >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // count + + return left + right; +} \ No newline at end of file diff --git a/src/Map.cpp b/src/Map.cpp index 48c40a5..4d2ed07 100644 --- a/src/Map.cpp +++ b/src/Map.cpp @@ -86,13 +86,13 @@ uint64_t Map::generate_children(sf::Vector3i pos, int dim) { // The 8 subvoxel coords starting from the 1th direction, the direction of the origin of the 3d grid // XY, Z++, XY std::vector v = { - sf::Vector3i(pos.x, pos.y, pos.z), - sf::Vector3i(pos.x + dim, pos.y, pos.z), - sf::Vector3i(pos.x, pos.y + dim, pos.z), + sf::Vector3i(pos.x , pos.y , pos.z), + sf::Vector3i(pos.x + dim, pos.y , pos.z), + sf::Vector3i(pos.x , pos.y + dim, pos.z), sf::Vector3i(pos.x + dim, pos.y + dim, pos.z), - sf::Vector3i(pos.x, pos.y, pos.z + dim), - sf::Vector3i(pos.x + dim, pos.y, pos.z + dim), - sf::Vector3i(pos.x, pos.y + dim, pos.z + dim), + sf::Vector3i(pos.x , pos.y , pos.z + dim), + sf::Vector3i(pos.x + dim, pos.y , pos.z + dim), + sf::Vector3i(pos.x , pos.y + dim, pos.z + dim), sf::Vector3i(pos.x + dim, pos.y + dim, pos.z + dim) }; diff --git a/src/main.cpp b/src/main.cpp index 01b2602..fec3ce5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -68,7 +68,11 @@ sf::Texture window_texture; // Y: 1.57 is straight down - +// TODO: +// - Texture axis sign flipping issue +// - Diffuse fog hard cut off +// - Infinite light distance, no inverse square +// - Inconsistent lighting constants. GUI manipulation int main() { @@ -92,7 +96,7 @@ int main() { _map.a.get_voxel(sf::Vector3i(5, 5, 0)); // ============================= - + return 0; sf::RenderWindow window(sf::VideoMode(WINDOW_X, WINDOW_Y), "SFML"); window.setMouseCursorVisible(false);