From 8894d5e3a7aa9bb4bcf6ae20d2b0f8a92657d907 Mon Sep 17 00:00:00 2001 From: MitchellHansen Date: Fri, 13 Oct 2017 20:57:05 -0700 Subject: [PATCH] Still plucking away at the octree traversal --- include/map/Octree.h | 53 ++++++++++++++------------- src/map/Map.cpp | 85 +++++++++++++++++++++++++++++++++++++++----- src/map/Octree.cpp | 19 +++++----- 3 files changed, 116 insertions(+), 41 deletions(-) diff --git a/include/map/Octree.h b/include/map/Octree.h index c96688e..bd2df4c 100644 --- a/include/map/Octree.h +++ b/include/map/Octree.h @@ -14,6 +14,8 @@ struct OctState { uint64_t current_descriptor; + sf::Vector3i oct_pos; + // ====== DEBUG ======= char found = 1; }; @@ -68,26 +70,11 @@ public: bool Validate(char* data, sf::Vector3i dimensions); unsigned int getDimensions(); -private: - - unsigned int oct_dimensions = 1; - - std::tuple GenerationRecursion( - char* data, // raw octree data - sf::Vector3i dimensions, // dimensions of the raw data - sf::Vector3i pos, // position of this generation node - unsigned int voxel_scale // the voxel scale of this node - ); - - char get1DIndexedVoxel(char* data, sf::Vector3i dimensions, sf::Vector3i position); - - std::vector anchor_stack; - unsigned int octree_voxel_dimension = 32; // (X, Y, Z) mask for the idx - const uint8_t idx_set_x_mask = 0x1; - const uint8_t idx_set_y_mask = 0x2; - const uint8_t idx_set_z_mask = 0x4; + static const uint8_t idx_set_x_mask = 0x1; + static const uint8_t idx_set_y_mask = 0x2; + static const uint8_t idx_set_z_mask = 0x4; // Mask for checking if valid or leaf const uint8_t mask_8[8] = { @@ -103,12 +90,30 @@ private: // uint64_t manipulation masks - const uint64_t child_pointer_mask = 0x0000000000007fff; - const uint64_t far_bit_mask = 0x8000; - const uint64_t valid_mask = 0xFF0000; - const uint64_t leaf_mask = 0xFF000000; - const uint64_t contour_pointer_mask = 0xFFFFFF00000000; - const uint64_t contour_mask = 0xFF00000000000000; + static const uint64_t child_pointer_mask = 0x0000000000007fff; + static const uint64_t far_bit_mask = 0x8000; + static const uint64_t valid_mask = 0xFF0000; + static const uint64_t leaf_mask = 0xFF000000; + static const uint64_t contour_pointer_mask = 0xFFFFFF00000000; + static const uint64_t contour_mask = 0xFF00000000000000; + +private: + + unsigned int oct_dimensions = 1; + + std::tuple GenerationRecursion( + char* data, // raw octree data + sf::Vector3i dimensions, // dimensions of the raw data + sf::Vector3i pos, // position of this generation node + unsigned int voxel_scale // the voxel scale of this node + ); + + char get1DIndexedVoxel(char* data, sf::Vector3i dimensions, sf::Vector3i position); + + std::vector anchor_stack; + unsigned int octree_voxel_dimension = 32; + + // ======= DEBUG =========== diff --git a/src/map/Map.cpp b/src/map/Map.cpp index 2b8f19a..3ab0b32 100644 --- a/src/map/Map.cpp +++ b/src/map/Map.cpp @@ -80,6 +80,8 @@ std::vector> Map::CastRayCharArray( sf::Vector2f* cam_dir, sf::Vector3f* cam_pos ) { + // Setup the voxel coords from the camera origin + sf::Vector3i voxel(*cam_pos); std::vector> travel_path; @@ -99,6 +101,13 @@ std::vector> Map::CastRayCharArray( ray_dir.z ); + // correct for the base ray pointing to (1, 0, 0) as (0, 0). Should equal (1.57, 0) + ray_dir = sf::Vector3f( + static_cast(ray_dir.z * sin(-1.57) + ray_dir.x * cos(-1.57)), + static_cast(ray_dir.y), + static_cast(ray_dir.z * cos(-1.57) - ray_dir.x * sin(-1.57)) + ); + // Setup the voxel step based on what direction the ray is pointing sf::Vector3i voxel_step(1, 1, 1); @@ -107,8 +116,12 @@ std::vector> Map::CastRayCharArray( voxel_step.y *= (ray_dir.y > 0) - (ray_dir.y < 0); voxel_step.z *= (ray_dir.z > 0) - (ray_dir.z < 0); - // Setup the voxel coords from the camera origin - sf::Vector3i voxel(*cam_pos); + + // ================================================================================================= + // ================================================================================================= + // ================================================================================================= + // ================================================================================================= + // Delta T is the units a ray must travel along an axis in order to // traverse an integer split @@ -223,7 +236,7 @@ std::vector> Map::CastRayOctree( voxel_step.x *= (ray_dir.x > 0) - (ray_dir.x < 0); voxel_step.y *= (ray_dir.y > 0) - (ray_dir.y < 0); voxel_step.z *= (ray_dir.z > 0) - (ray_dir.z < 0); - + // set the jump multiplier based on the traversal state vs the log base 2 of the maps dimensions int jump_power = 1; if (log2(map_dim->x) != traversal_state.scale) @@ -287,17 +300,73 @@ std::vector> Map::CastRayOctree( voxel.y += voxel_step.y * face_mask.y * jump_power; voxel.z += voxel_step.z * face_mask.z * jump_power; + uint8_t prev_val = traversal_state.idx_stack[traversal_state.scale]; + uint8_t this_face_mask = 0; - if (face_mask.x != 0) { - + // Check the voxel face that we traversed + // and increment the idx in the idx stack + if (face_mask.x) { + this_face_mask = Octree::idx_set_x_mask; } - if (face_mask.y != 0) { - + else if (face_mask.y) { + this_face_mask = Octree::idx_set_y_mask; } - if (face_mask.z != 0) { + else if (face_mask.z) { + this_face_mask = Octree::idx_set_z_mask; + } + + traversal_state.idx_stack[traversal_state.scale] ^= this_face_mask; + + // Check to see if the idx increased or decreased + // If it decreased + // Pop up the stack until the oct that the ray is within is valid. + while (traversal_state.idx_stack[traversal_state.scale] < prev_val) { + + jump_power *= 2; + + traversal_state.oct_pos.x; + traversal_state.oct_pos.y; + traversal_state.oct_pos.z; + + // Clear and pop the idx stack + traversal_state.idx_stack[traversal_state.scale] = 0; + traversal_state.scale--; + + // Update the prev_val for our new idx + prev_val = traversal_state.idx_stack[traversal_state.scale]; + + // Clear and pop the parent stack, maybe off by one error? + traversal_state.parent_stack[traversal_state.parent_stack_position] = 0; + traversal_state.parent_stack_position--; + + // Set the current CD to the one on top of the stack + traversal_state.current_descriptor = + traversal_state.parent_stack[traversal_state.parent_stack_position]; + + // Apply the face mask to the new idx for the while check + traversal_state.idx_stack[traversal_state.scale] ^= this_face_mask; } + + + // Check to see if we are on top of a valid branch + // Traverse down to the lowest valid oct that the ray is within + + // When we pass a split, then that means that we traversed SCALE number of voxels in that direction + + + // while the bit is valid and we are not bottomed out + // get the cp of the valid branch + // + // + // + // + + + + + if (voxel.x >= map_dim->x || voxel.y >= map_dim->y || voxel.z >= map_dim->z) { return travel_path; } diff --git a/src/map/Octree.cpp b/src/map/Octree.cpp index 0177b34..5490945 100644 --- a/src/map/Octree.cpp +++ b/src/map/Octree.cpp @@ -45,6 +45,8 @@ OctState Octree::GetVoxel(sf::Vector3i position) { // Struct that holds the state necessary to continue the traversal from the found voxel OctState state; + state.oct_pos = sf::Vector3i(0,0,0); + // push the root node to the parent stack uint64_t current_index = root_index; uint64_t head = descriptor_buffer[current_index]; @@ -54,7 +56,6 @@ OctState Octree::GetVoxel(sf::Vector3i position) { // Set our initial dimension and the position at the corner of the oct to keep track of our position int dimension = oct_dimensions; - sf::Vector3i quad_position(0, 0, 0); // While we are not at the required resolution // Traverse down by setting the valid/leaf mask to the subvoxel @@ -75,10 +76,10 @@ OctState Octree::GetVoxel(sf::Vector3i position) { // Do the logic steps to find which sub oct we step down into - if (position.x >= (dimension / 2) + quad_position.x) { + if (position.x >= (dimension / 2) + state.oct_pos.x) { // Set our voxel position to the (0,0) of the correct oct - quad_position.x += (dimension / 2); + state.oct_pos.x += (dimension / 2); // increment the mask index and mentioned above mask_index += 1; @@ -87,19 +88,19 @@ OctState Octree::GetVoxel(sf::Vector3i position) { state.idx_stack[state.scale] |= idx_set_x_mask; } - if (position.y >= (dimension / 2) + quad_position.y) { + if (position.y >= (dimension / 2) + state.oct_pos.y) { - quad_position.y |= (dimension / 2); + state.oct_pos.y |= (dimension / 2); mask_index += 2; - // TODO What is up with the binary operator on this one? - state.idx_stack[state.scale] ^= idx_set_y_mask; + // TODO What is up with the XOR operator that was on this one? + state.idx_stack[state.scale] |= idx_set_y_mask; } - if (position.z >= (dimension / 2) + quad_position.z) { + if (position.z >= (dimension / 2) + state.oct_pos.z) { - quad_position.z += (dimension / 2); + state.oct_pos.z += (dimension / 2); mask_index += 4;