From 4642ab8f0b8c94b4d9d619ab32aabfa76a32c8ac Mon Sep 17 00:00:00 2001 From: MitchellHansen Date: Thu, 13 Jul 2017 22:14:29 -0700 Subject: [PATCH] Fiddling with the traversal algorithm and shoehorning in the DFS algo --- include/map/Octree.h | 2 - kernels/ray_caster_kernel.cl | 3 +- src/map/Map.cpp | 110 +++++++++++++++-------------------- src/map/Octree.cpp | 2 +- 4 files changed, 50 insertions(+), 67 deletions(-) diff --git a/include/map/Octree.h b/include/map/Octree.h index 6eac988..bb7bd27 100644 --- a/include/map/Octree.h +++ b/include/map/Octree.h @@ -18,8 +18,6 @@ struct OctState { // ====== DEBUG ======= char found = 1; - - }; diff --git a/kernels/ray_caster_kernel.cl b/kernels/ray_caster_kernel.cl index 9a933de..086c144 100644 --- a/kernels/ray_caster_kernel.cl +++ b/kernels/ray_caster_kernel.cl @@ -215,8 +215,7 @@ __kernel void raycaster( float3 intersection_t = delta_t * ((*cam_pos) - floor(*cam_pos)) * convert_float3(voxel_step); // for negative values, wrap around the delta_t - intersection_t += delta_t * -convert_float3(isless(intersection_t, 0)); - + intersection_t -= delta_t * convert_float3(isless(intersection_t, 0)); int dist = 0; int3 face_mask = { 0, 0, 0 }; diff --git a/src/map/Map.cpp b/src/map/Map.cpp index e07a76d..eae9bbf 100644 --- a/src/map/Map.cpp +++ b/src/map/Map.cpp @@ -25,8 +25,8 @@ Map::Map(uint32_t dimensions) { octree.Validate(voxel_data, dim3); - sf::Vector2f cam_dir(2, 0.01); - sf::Vector3f cam_pos(10, 10, 10); + sf::Vector2f cam_dir(0.95, 0.81); + sf::Vector3f cam_pos(10.5, 10.5, 10.5); std::vector> list1 = CastRayCharArray(voxel_data, &dim3, &cam_dir, &cam_pos); std::vector> list2 = CastRayOctree(&octree, &dim3, &cam_dir, &cam_pos); @@ -99,9 +99,9 @@ std::vector> Map::CastRayCharArray( ); // for negative values, wrap around the delta_t - intersection_t.x += delta_t.x * -(std::min(intersection_t.x, 0.0f)); - intersection_t.y += delta_t.y * -(std::min(intersection_t.y, 0.0f)); - intersection_t.z += delta_t.z * -(std::min(intersection_t.z, 0.0f)); + intersection_t.x -= delta_t.x * (std::min(intersection_t.x, 0.0f)); + intersection_t.y -= delta_t.y * (std::min(intersection_t.y, 0.0f)); + intersection_t.z -= delta_t.z * (std::min(intersection_t.z, 0.0f)); int dist = 0; @@ -115,7 +115,6 @@ std::vector> Map::CastRayCharArray( face_mask.y = intersection_t.y <= std::min(intersection_t.z, intersection_t.x); face_mask.z = intersection_t.z <= std::min(intersection_t.x, intersection_t.y); - intersection_t.x += delta_t.x * fabs(face_mask.x); intersection_t.y += delta_t.y * fabs(face_mask.y); intersection_t.z += delta_t.z * fabs(face_mask.z); @@ -124,31 +123,6 @@ std::vector> Map::CastRayCharArray( voxel.y += voxel_step.y * face_mask.y; voxel.z += voxel_step.z * face_mask.z; - if ((intersection_t.x) < (intersection_t.y)) { - if ((intersection_t.x) < (intersection_t.z)) { - - voxel.x += voxel_step.x; - intersection_t.x = intersection_t.x + delta_t.x; - } - else { - - voxel.z += voxel_step.z; - intersection_t.z = intersection_t.z + delta_t.z; - } - } - else { - if ((intersection_t.y) < (intersection_t.z)) { - - voxel.y += voxel_step.y; - intersection_t.y = intersection_t.y + delta_t.y; - } - else { - - voxel.z += voxel_step.z; - intersection_t.z = intersection_t.z + delta_t.z; - } - } - if (voxel.x >= map_dim->x || voxel.y >= map_dim->y || voxel.z >= map_dim->z) { return travel_path; } @@ -179,6 +153,15 @@ std::vector> Map::CastRayOctree( sf::Vector3f* cam_pos ) { + // Setup the voxel coords from the camera origin + sf::Vector3i voxel(*cam_pos); + + // THIS DOES NOT HAVE TO RETURN TRUE ON FOUND + // This function when passed a "air" voxel will return as far down + // the IDX stack as it could go. We use this oct-level to determine + // our first position and jump. Updating it as we go + OctState traversal_state = octree->GetVoxel(voxel); + std::vector> travel_path; sf::Vector3f ray_dir(1, 0, 0); @@ -197,6 +180,13 @@ std::vector> Map::CastRayOctree( 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); @@ -205,8 +195,10 @@ std::vector> Map::CastRayOctree( 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); + // 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) + jump_power = pow(2, traversal_state.scale); // Delta T is the units a ray must travel along an axis in order to // traverse an integer split @@ -216,9 +208,16 @@ std::vector> Map::CastRayOctree( fabs(1.0f / ray_dir.z) ); + delta_t *= static_cast(jump_power); + // offset is how far we are into a voxel, enables sub voxel movement // Intersection T is the collection of the next intersection points // for all 3 axis XYZ. + + + // TODO: start here + // set intersection t to the current hierarchy level each time we change levels + // and use that to step sf::Vector3f intersection_t( delta_t.x * (cam_pos->y - floor(cam_pos->x)) * voxel_step.x, delta_t.y * (cam_pos->x - floor(cam_pos->y)) * voxel_step.y, @@ -226,56 +225,43 @@ std::vector> Map::CastRayOctree( ); // for negative values, wrap around the delta_t - intersection_t.x += delta_t.x * -(std::min(intersection_t.x, 0.0f)); - intersection_t.y += delta_t.y * -(std::min(intersection_t.y, 0.0f)); - intersection_t.z += delta_t.z * -(std::min(intersection_t.z, 0.0f)); - + intersection_t.x -= delta_t.x * (std::isless(intersection_t.x, 0.0f)); + intersection_t.y -= delta_t.y * (std::isless(intersection_t.y, 0.0f)); + intersection_t.z -= delta_t.z * (std::isless(intersection_t.z, 0.0f)); int dist = 0; sf::Vector3i face_mask(0, 0, 0); int voxel_data = 0; - OctState traversal_state = octree->GetVoxel(voxel); - // Andrew Woo's raycasting algo do { + + + // check which direction we step in face_mask.x = intersection_t.x <= std::min(intersection_t.y, intersection_t.z); face_mask.y = intersection_t.y <= std::min(intersection_t.z, intersection_t.x); face_mask.z = intersection_t.z <= std::min(intersection_t.x, intersection_t.y); - + // Increment the selected directions intersection, abs the face_mask to stay within the algo constraints intersection_t.x += delta_t.x * fabs(face_mask.x); intersection_t.y += delta_t.y * fabs(face_mask.y); intersection_t.z += delta_t.z * fabs(face_mask.z); - voxel.x += voxel_step.x * face_mask.x; - voxel.y += voxel_step.y * face_mask.y; - voxel.z += voxel_step.z * face_mask.z; - - if ((intersection_t.x) < (intersection_t.y)) { - if ((intersection_t.x) < (intersection_t.z)) { + // step the voxel direction + voxel.x += voxel_step.x * face_mask.x * jump_power; + voxel.y += voxel_step.y * face_mask.y * jump_power; + voxel.z += voxel_step.z * face_mask.z * jump_power; - voxel.x += voxel_step.x; - intersection_t.x = intersection_t.x + delta_t.x; - } - else { - voxel.z += voxel_step.z; - intersection_t.z = intersection_t.z + delta_t.z; - } + if (face_mask.x != 0) { + } - else { - if ((intersection_t.y) < (intersection_t.z)) { + if (face_mask.y != 0) { - voxel.y += voxel_step.y; - intersection_t.y = intersection_t.y + delta_t.y; - } - else { + } + if (face_mask.z != 0) { - voxel.z += voxel_step.z; - intersection_t.z = intersection_t.z + delta_t.z; - } } if (voxel.x >= map_dim->x || voxel.y >= map_dim->y || voxel.z >= map_dim->z) { diff --git a/src/map/Octree.cpp b/src/map/Octree.cpp index bb3dab7..c3b0051 100644 --- a/src/map/Octree.cpp +++ b/src/map/Octree.cpp @@ -93,7 +93,7 @@ OctState Octree::GetVoxel(sf::Vector3i position) { mask_index += 2; - // What is up with the binary operator on this one? TODO + // TODO What is up with the binary operator on this one? state.idx_stack[state.scale] ^= idx_set_y_mask; }