Still plucking away at the octree traversal

master
MitchellHansen 7 years ago
parent 618535fed7
commit 8894d5e3a7

@ -14,6 +14,8 @@ struct OctState {
uint64_t current_descriptor; uint64_t current_descriptor;
sf::Vector3i oct_pos;
// ====== DEBUG ======= // ====== DEBUG =======
char found = 1; char found = 1;
}; };
@ -68,26 +70,11 @@ public:
bool Validate(char* data, sf::Vector3i dimensions); bool Validate(char* data, sf::Vector3i dimensions);
unsigned int getDimensions(); unsigned int getDimensions();
private:
unsigned int oct_dimensions = 1;
std::tuple<uint64_t, uint64_t> 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<uint64_t> anchor_stack;
unsigned int octree_voxel_dimension = 32;
// (X, Y, Z) mask for the idx // (X, Y, Z) mask for the idx
const uint8_t idx_set_x_mask = 0x1; static const uint8_t idx_set_x_mask = 0x1;
const uint8_t idx_set_y_mask = 0x2; static const uint8_t idx_set_y_mask = 0x2;
const uint8_t idx_set_z_mask = 0x4; static const uint8_t idx_set_z_mask = 0x4;
// Mask for checking if valid or leaf // Mask for checking if valid or leaf
const uint8_t mask_8[8] = { const uint8_t mask_8[8] = {
@ -103,12 +90,30 @@ private:
// uint64_t manipulation masks // uint64_t manipulation masks
const uint64_t child_pointer_mask = 0x0000000000007fff; static const uint64_t child_pointer_mask = 0x0000000000007fff;
const uint64_t far_bit_mask = 0x8000; static const uint64_t far_bit_mask = 0x8000;
const uint64_t valid_mask = 0xFF0000; static const uint64_t valid_mask = 0xFF0000;
const uint64_t leaf_mask = 0xFF000000; static const uint64_t leaf_mask = 0xFF000000;
const uint64_t contour_pointer_mask = 0xFFFFFF00000000; static const uint64_t contour_pointer_mask = 0xFFFFFF00000000;
const uint64_t contour_mask = 0xFF00000000000000; static const uint64_t contour_mask = 0xFF00000000000000;
private:
unsigned int oct_dimensions = 1;
std::tuple<uint64_t, uint64_t> 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<uint64_t> anchor_stack;
unsigned int octree_voxel_dimension = 32;
// ======= DEBUG =========== // ======= DEBUG ===========

@ -80,6 +80,8 @@ std::vector<std::tuple<sf::Vector3i, char>> Map::CastRayCharArray(
sf::Vector2f* cam_dir, sf::Vector2f* cam_dir,
sf::Vector3f* cam_pos sf::Vector3f* cam_pos
) { ) {
// Setup the voxel coords from the camera origin
sf::Vector3i voxel(*cam_pos);
std::vector<std::tuple<sf::Vector3i, char>> travel_path; std::vector<std::tuple<sf::Vector3i, char>> travel_path;
@ -99,6 +101,13 @@ std::vector<std::tuple<sf::Vector3i, char>> Map::CastRayCharArray(
ray_dir.z 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<float>(ray_dir.z * sin(-1.57) + ray_dir.x * cos(-1.57)),
static_cast<float>(ray_dir.y),
static_cast<float>(ray_dir.z * cos(-1.57) - ray_dir.x * sin(-1.57))
);
// Setup the voxel step based on what direction the ray is pointing // Setup the voxel step based on what direction the ray is pointing
sf::Vector3i voxel_step(1, 1, 1); sf::Vector3i voxel_step(1, 1, 1);
@ -107,8 +116,12 @@ std::vector<std::tuple<sf::Vector3i, char>> Map::CastRayCharArray(
voxel_step.y *= (ray_dir.y > 0) - (ray_dir.y < 0); voxel_step.y *= (ray_dir.y > 0) - (ray_dir.y < 0);
voxel_step.z *= (ray_dir.z > 0) - (ray_dir.z < 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 // Delta T is the units a ray must travel along an axis in order to
// traverse an integer split // traverse an integer split
@ -223,7 +236,7 @@ std::vector<std::tuple<sf::Vector3i, char>> Map::CastRayOctree(
voxel_step.x *= (ray_dir.x > 0) - (ray_dir.x < 0); voxel_step.x *= (ray_dir.x > 0) - (ray_dir.x < 0);
voxel_step.y *= (ray_dir.y > 0) - (ray_dir.y < 0); voxel_step.y *= (ray_dir.y > 0) - (ray_dir.y < 0);
voxel_step.z *= (ray_dir.z > 0) - (ray_dir.z < 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 // set the jump multiplier based on the traversal state vs the log base 2 of the maps dimensions
int jump_power = 1; int jump_power = 1;
if (log2(map_dim->x) != traversal_state.scale) if (log2(map_dim->x) != traversal_state.scale)
@ -287,17 +300,73 @@ std::vector<std::tuple<sf::Vector3i, char>> Map::CastRayOctree(
voxel.y += voxel_step.y * face_mask.y * jump_power; voxel.y += voxel_step.y * face_mask.y * jump_power;
voxel.z += voxel_step.z * face_mask.z * 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) { if (voxel.x >= map_dim->x || voxel.y >= map_dim->y || voxel.z >= map_dim->z) {
return travel_path; return travel_path;
} }

@ -45,6 +45,8 @@ OctState Octree::GetVoxel(sf::Vector3i position) {
// Struct that holds the state necessary to continue the traversal from the found voxel // Struct that holds the state necessary to continue the traversal from the found voxel
OctState state; OctState state;
state.oct_pos = sf::Vector3i(0,0,0);
// push the root node to the parent stack // push the root node to the parent stack
uint64_t current_index = root_index; uint64_t current_index = root_index;
uint64_t head = descriptor_buffer[current_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 // Set our initial dimension and the position at the corner of the oct to keep track of our position
int dimension = oct_dimensions; int dimension = oct_dimensions;
sf::Vector3i quad_position(0, 0, 0);
// While we are not at the required resolution // While we are not at the required resolution
// Traverse down by setting the valid/leaf mask to the subvoxel // 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 // 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 // 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 // increment the mask index and mentioned above
mask_index += 1; mask_index += 1;
@ -87,19 +88,19 @@ OctState Octree::GetVoxel(sf::Vector3i position) {
state.idx_stack[state.scale] |= idx_set_x_mask; 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; mask_index += 2;
// TODO What is up with the binary operator on this one? // TODO What is up with the XOR operator that was on this one?
state.idx_stack[state.scale] ^= idx_set_y_mask; 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; mask_index += 4;

Loading…
Cancel
Save