A decent amount of progress on voxel traversal. Converted most of it to C code to make the CL version easier

master
MitchellHansen 8 years ago
parent 04a68c1dec
commit 0a457f50a6

@ -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) { bool get_voxel(sf::Vector3i position) {
// Init the parent stack and push the head node // Init the parent stack and push the head node
std::queue<uint64_t> parent_stack; //std::queue<uint64_t> parent_stack;
int parent_stack_position = 0;
uint64_t parent_stack[32] = {0};
uint64_t head = block_stack.front()[stack_pos]; 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 // Get the index of the first child of the head node
uint64_t index = head & child_pointer_mask; uint64_t index = head & child_pointer_mask;
uint8_t scale = 0;
uint8_t idx_stack[32] = {0};
// Init the idx stack // Init the idx stack
std::vector<std::bitset<3>> scale_stack(log2(OCT_DIM)); std::vector<std::bitset<3>> scale_stack(log2(OCT_DIM));
@ -100,31 +123,83 @@ public:
while (dimension > 1) { 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) { 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); 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); scale_stack.at(log2(OCT_DIM) - log2(dimension)).set(0);
} }
if (position.y >= (dimension / 2) + quad_position.y) { 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); scale_stack.at(log2(OCT_DIM) - log2(dimension)).set(1);
} }
if (position.z >= (dimension / 2) + quad_position.z) { if (position.z >= (dimension / 2) + quad_position.z) {
quad_position.z += (dimension / 2); quad_position.z += (dimension / 2);
mask_index += 4;
idx_stack[scale] |= idx_set_z_mask;
scale_stack.at(log2(OCT_DIM) - log2(dimension)).set(2); scale_stack.at(log2(OCT_DIM) - log2(dimension)).set(2);
} }
// Set the new dimension // 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; 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); std::bitset<64> t(index);
auto val = t.count(); auto val = t.count();

@ -272,3 +272,25 @@ inline std::vector<float> 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;
}

@ -68,7 +68,11 @@ sf::Texture window_texture;
// Y: 1.57 is straight down // 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() { int main() {
@ -92,7 +96,7 @@ int main() {
_map.a.get_voxel(sf::Vector3i(5, 5, 0)); _map.a.get_voxel(sf::Vector3i(5, 5, 0));
// ============================= // =============================
return 0;
sf::RenderWindow window(sf::VideoMode(WINDOW_X, WINDOW_Y), "SFML"); sf::RenderWindow window(sf::VideoMode(WINDOW_X, WINDOW_Y), "SFML");
window.setMouseCursorVisible(false); window.setMouseCursorVisible(false);

Loading…
Cancel
Save