Skip to content

Commit

Permalink
Renamed intersection
Browse files Browse the repository at this point in the history
  • Loading branch information
xelatihy committed Jan 30, 2024
1 parent b05bfb9 commit 940fdbc
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 204 deletions.
188 changes: 48 additions & 140 deletions libs/yocto/yocto_raycasting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,6 @@ static bvh_tree make_elements_bvh(size_t num, bool highquality, BBox&& bbox) {
auto bvh = bvh_tree{};

// prepare to build nodes
bvh.nodes.clear();
bvh.nodes.reserve(num * 2);

// prepare bboxes
Expand Down Expand Up @@ -322,7 +321,7 @@ static void refit_elements_bvh(bvh_tree& bvh, BBox&& bbox) {
// Intersect ray with a bvh.
template <typename Intersect>
static shape_intersection intersect_elements_bvh(const bvh_tree& bvh,
Intersect&& intersect_element, const ray3f& ray_, bool find_any) {
const ray3f& ray_, bool find_any, Intersect&& intersect_element) {
// check empty
if (bvh.nodes.empty()) return {};

Expand Down Expand Up @@ -383,8 +382,8 @@ static shape_intersection intersect_elements_bvh(const bvh_tree& bvh,

// Intersect ray with a bvh.
template <typename Overlap>
static shape_intersection overlap_elements_bvh(const bvh_tree& bvh,
Overlap&& overlap_element, vec3f pos, float max_distance, bool find_any) {
static shape_intersection overlap_elements_bvh(const bvh_tree& bvh, vec3f pos,
float max_distance, bool find_any, Overlap&& overlap_element) {
// check if empty
if (bvh.nodes.empty()) return {};

Expand Down Expand Up @@ -513,48 +512,40 @@ shape_intersection intersect_points_bvh(const bvh_tree& bvh,
const vector<int>& points, const vector<vec3f>& positions,
const vector<float>& radius, const ray3f& ray, bool find_any) {
return intersect_elements_bvh(
bvh,
[&](int idx, const ray3f& ray) {
bvh, ray, find_any, [&](int idx, const ray3f& ray) {
auto& p = points[idx];
return intersect_point(ray, positions[p], radius[p]);
},
ray, find_any);
});
}
shape_intersection intersect_lines_bvh(const bvh_tree& bvh,
const vector<vec2i>& lines, const vector<vec3f>& positions,
const vector<float>& radius, const ray3f& ray, bool find_any) {
return intersect_elements_bvh(
bvh,
[&](int idx, const ray3f& ray) {
bvh, ray, find_any, [&](int idx, const ray3f& ray) {
auto& l = lines[idx];
return intersect_line(
ray, positions[l.x], positions[l.y], radius[l.x], radius[l.y]);
},
ray, find_any);
});
}
shape_intersection intersect_triangles_bvh(const bvh_tree& bvh,
const vector<vec3i>& triangles, const vector<vec3f>& positions,
const ray3f& ray, bool find_any) {
return intersect_elements_bvh(
bvh,
[&](int idx, const ray3f& ray) {
bvh, ray, find_any, [&](int idx, const ray3f& ray) {
auto& t = triangles[idx];
return intersect_triangle(
ray, positions[t.x], positions[t.y], positions[t.z]);
},
ray, find_any);
});
}
shape_intersection intersect_quads_bvh(const bvh_tree& bvh,
const vector<vec4i>& quads, const vector<vec3f>& positions,
const ray3f& ray, bool find_any) {
return intersect_elements_bvh(
bvh,
[&](int idx, const ray3f& ray) {
bvh, ray, find_any, [&](int idx, const ray3f& ray) {
auto& t = quads[idx];
return intersect_quad(ray, positions[t.x], positions[t.y],
positions[t.z], positions[t.w]);
},
ray, find_any);
});
}

// Find a shape element that overlaps a point within a given distance
Expand All @@ -564,52 +555,44 @@ shape_intersection intersect_quads_bvh(const bvh_tree& bvh,
shape_intersection overlap_points_bvh(const bvh_tree& bvh,
const vector<int>& points, const vector<vec3f>& positions,
const vector<float>& radius, vec3f pos, float max_distance, bool find_any) {
return overlap_elements_bvh(
bvh,
return overlap_elements_bvh(bvh, pos, max_distance, find_any,
[&points, &positions, &radius](int idx, vec3f pos, float max_distance) {
auto& p = points[idx];
return overlap_point(pos, max_distance, positions[p], radius[p]);
},
pos, max_distance, find_any);
});
}
shape_intersection overlap_lines_bvh(const bvh_tree& bvh,
const vector<vec2i>& lines, const vector<vec3f>& positions,
const vector<float>& radius, vec3f pos, float max_distance, bool find_any) {
return overlap_elements_bvh(
bvh,
return overlap_elements_bvh(bvh, pos, max_distance, find_any,
[&lines, &positions, &radius](int idx, vec3f pos, float max_distance) {
auto& l = lines[idx];
return overlap_line(pos, max_distance, positions[l.x], positions[l.y],
radius[l.x], radius[l.y]);
},
pos, max_distance, find_any);
});
}
shape_intersection overlap_triangles_bvh(const bvh_tree& bvh,
const vector<vec3i>& triangles, const vector<vec3f>& positions,
const vector<float>& radius, vec3f pos, float max_distance, bool find_any) {
return overlap_elements_bvh(
bvh,
return overlap_elements_bvh(bvh, pos, max_distance, find_any,
[&triangles, &positions, &radius](
int idx, vec3f pos, float max_distance) {
auto& t = triangles[idx];
return overlap_triangle(pos, max_distance, positions[t.x],
positions[t.y], positions[t.z], radius[t.x], radius[t.y],
radius[t.z]);
},
pos, max_distance, find_any);
});
}
shape_intersection overlap_quads_bvh(const bvh_tree& bvh,
const vector<vec4i>& quads, const vector<vec3f>& positions,
const vector<float>& radius, vec3f pos, float max_distance, bool find_any) {
return overlap_elements_bvh(
bvh,
return overlap_elements_bvh(bvh, pos, max_distance, find_any,
[&quads, &positions, &radius](int idx, vec3f pos, float max_distance) {
auto& q = quads[idx];
return overlap_quad(pos, max_distance, positions[q.x], positions[q.y],
positions[q.z], positions[q.w], radius[q.x], radius[q.y],
radius[q.z], radius[q.w]);
},
pos, max_distance, find_any);
});
}

} // namespace yocto
Expand Down Expand Up @@ -672,7 +655,7 @@ scene_bvh make_scene_bvh(
return bvh;
}

void update_shape_bvh(shape_bvh& sbvh, const shape_data& shape) {
void refit_shape_bvh(shape_bvh& sbvh, const shape_data& shape) {
// update primitives
if (!shape.points.empty()) {
refit_points_bvh(sbvh.bvh, shape.points, shape.positions, shape.radius);
Expand All @@ -685,11 +668,11 @@ void update_shape_bvh(shape_bvh& sbvh, const shape_data& shape) {
}
}

void update_scene_bvh(scene_bvh& sbvh, const scene_data& scene,
void refit_scene_bvh(scene_bvh& sbvh, const scene_data& scene,
const vector<int>& updated_instances, const vector<int>& updated_shapes) {
// update shapes
for (auto shape : updated_shapes) {
update_shape_bvh(sbvh.shapes[shape], scene.shapes[shape]);
refit_shape_bvh(sbvh.shapes[shape], scene.shapes[shape]);
}

// update nodes
Expand Down Expand Up @@ -731,99 +714,24 @@ namespace yocto {

shape_intersection intersect_shape_bvh(const shape_bvh& sbvh,
const shape_data& shape, const ray3f& ray_, bool find_any) {
// get bvh tree
auto& bvh = sbvh.bvh;

// check empty
if (bvh.nodes.empty()) return {};

// node stack
auto node_stack = array<int, 128>{};
auto node_cur = 0;
node_stack[node_cur++] = 0;

// shared variables
auto intersection = shape_intersection{};

// copy ray to modify it
auto ray = ray_;

// prepare ray for fast queries
auto ray_dinv = vec3f{1 / ray.d.x, 1 / ray.d.y, 1 / ray.d.z};
auto ray_dsign = vec3i{(ray_dinv.x < 0) ? 1 : 0, (ray_dinv.y < 0) ? 1 : 0,
(ray_dinv.z < 0) ? 1 : 0};

// walking stack
while (node_cur != 0) {
// grab node
auto& node = bvh.nodes[node_stack[--node_cur]];

// intersect bbox
// if (!intersect_bbox(ray, ray_dinv, ray_dsign, node.bbox)) continue;
if (!intersect_bbox(ray, ray_dinv, node.bbox)) continue;

// intersect node, switching based on node type
// for each type, iterate over the the primitive list
if (node.internal) {
// for internal nodes, attempts to proceed along the
// split axis from smallest to largest nodes
if (ray_dsign[node.axis] != 0) {
node_stack[node_cur++] = node.start + 0;
node_stack[node_cur++] = node.start + 1;
} else {
node_stack[node_cur++] = node.start + 1;
node_stack[node_cur++] = node.start + 0;
}
} else if (!shape.points.empty()) {
for (auto idx = node.start; idx < node.start + node.num; idx++) {
auto& p = shape.points[bvh.primitives[idx]];
auto pintersection = intersect_point(
ray, shape.positions[p], shape.radius[p]);
if (!pintersection.hit) continue;
intersection = {bvh.primitives[idx], pintersection.uv,
pintersection.distance, true};
ray.tmax = pintersection.distance;
}
} else if (!shape.lines.empty()) {
for (auto idx = node.start; idx < node.start + node.num; idx++) {
auto& l = shape.lines[bvh.primitives[idx]];
auto pintersection = intersect_line(ray, shape.positions[l.x],
shape.positions[l.y], shape.radius[l.x], shape.radius[l.y]);
if (!pintersection.hit) continue;
intersection = {bvh.primitives[idx], pintersection.uv,
pintersection.distance, true};
ray.tmax = pintersection.distance;
}
} else if (!shape.triangles.empty()) {
for (auto idx = node.start; idx < node.start + node.num; idx++) {
auto& t = shape.triangles[bvh.primitives[idx]];
auto pintersection = intersect_triangle(ray, shape.positions[t.x],
shape.positions[t.y], shape.positions[t.z]);
if (!pintersection.hit) continue;
intersection = {bvh.primitives[idx], pintersection.uv,
pintersection.distance, true};
ray.tmax = pintersection.distance;
}
} else if (!shape.quads.empty()) {
for (auto idx = node.start; idx < node.start + node.num; idx++) {
auto& q = shape.quads[bvh.primitives[idx]];
auto pintersection = intersect_quad(ray, shape.positions[q.x],
shape.positions[q.y], shape.positions[q.z], shape.positions[q.w]);
if (!pintersection.hit) continue;
intersection = {bvh.primitives[idx], pintersection.uv,
pintersection.distance, true};
ray.tmax = pintersection.distance;
}
}

// check for early exit
if (find_any && intersection.hit) return intersection;
if (!shape.points.empty()) {
return intersect_points_bvh(
sbvh.bvh, shape.points, shape.positions, shape.radius, ray_, find_any);
} else if (!shape.lines.empty()) {
return intersect_lines_bvh(
sbvh.bvh, shape.lines, shape.positions, shape.radius, ray_, find_any);
} else if (!shape.triangles.empty()) {
return intersect_triangles_bvh(
sbvh.bvh, shape.triangles, shape.positions, ray_, find_any);
} else if (!shape.quads.empty()) {
return intersect_quads_bvh(
sbvh.bvh, shape.quads, shape.positions, ray_, find_any);
} else {
return {};
}

return intersection;
}

scene_intersection intersect_scene_bvh(const scene_bvh& sbvh,
intersection3f intersect_scene_bvh(const scene_bvh& sbvh,
const scene_data& scene, const ray3f& ray_, bool find_any) {
// get instances bvh
auto& bvh = sbvh.bvh;
Expand All @@ -837,7 +745,7 @@ scene_intersection intersect_scene_bvh(const scene_bvh& sbvh,
node_stack[node_cur++] = 0;

// intersection
auto intersection = scene_intersection{};
auto intersection = intersection3f{};

// copy ray to modify it
auto ray = ray_;
Expand Down Expand Up @@ -888,7 +796,7 @@ scene_intersection intersect_scene_bvh(const scene_bvh& sbvh,
return intersection;
}

scene_intersection intersect_instance_bvh(const scene_bvh& sbvh,
intersection3f intersect_instance_bvh(const scene_bvh& sbvh,
const scene_data& scene, int instance_, const ray3f& ray, bool find_any) {
auto& instance = scene.instances[instance_];
auto inv_ray = transform_ray(inverse(instance.frame, true), ray);
Expand Down Expand Up @@ -995,8 +903,8 @@ shape_intersection overlap_shape_bvh(const shape_bvh& sbvh,
}

// Intersect ray with a bvh.
scene_intersection overlap_scene_bvh(const scene_bvh& sbvh,
const scene_data& scene, vec3f pos, float max_distance, bool find_any) {
intersection3f overlap_scene_bvh(const scene_bvh& sbvh, const scene_data& scene,
vec3f pos, float max_distance, bool find_any) {
// get instances bvh
auto& bvh = sbvh.bvh;

Expand All @@ -1009,7 +917,7 @@ scene_intersection overlap_scene_bvh(const scene_bvh& sbvh,
node_stack[node_cur++] = 0;

// intersection
auto intersection = scene_intersection{};
auto intersection = intersection3f{};

// walking stack
while (node_cur != 0) {
Expand Down Expand Up @@ -1295,10 +1203,10 @@ scene_ebvh make_scene_ebvh(
}

// Refit bvh data
void update_shape_ebvh(shape_ebvh& sbvh, const shape_data& shape) {
void refit_shape_ebvh(shape_ebvh& sbvh, const shape_data& shape) {
throw embree_error{"feature not supported"};
}
void update_scene_ebvh(scene_ebvh& sbvh, const scene_data& scene,
void refit_scene_ebvh(scene_ebvh& sbvh, const scene_data& scene,
const vector<int>& updated_instances, const vector<int>& updated_shapes) {
// scene bvh
auto escene = (RTCScene)sbvh.ebvh.get();
Expand Down Expand Up @@ -1341,7 +1249,7 @@ shape_intersection intersect_shape_ebvh(const shape_ebvh& sbvh,
return {element, uv, distance, true};
}

scene_intersection intersect_scene_ebvh(const scene_ebvh& sbvh,
intersection3f intersect_scene_ebvh(const scene_ebvh& sbvh,
const scene_data& scene, const ray3f& ray, bool find_any) {
RTCRayHit embree_ray;
embree_ray.ray.org_x = ray.o.x;
Expand All @@ -1366,7 +1274,7 @@ scene_intersection intersect_scene_ebvh(const scene_ebvh& sbvh,
return {instance, element, uv, distance, true};
}

scene_intersection intersect_instance_ebvh(const scene_ebvh& sbvh,
intersection3f intersect_instance_ebvh(const scene_ebvh& sbvh,
const scene_data& scene, int instance_, const ray3f& ray, bool find_any) {
auto& instance = scene.instances[instance_];
auto inv_ray = transform_ray(inverse(instance.frame, true), ray);
Expand Down Expand Up @@ -1405,11 +1313,11 @@ shape_intersection intersect_shape_ebvh(const shape_ebvh& sbvh,
const shape_data& shape, const ray3f& ray, bool find_any) {
throw embree_error{"Embree not available"};
}
scene_intersection intersect_scene_ebvh(const scene_ebvh& sbvh,
intersection3f intersect_scene_ebvh(const scene_ebvh& sbvh,
const scene_data& scene, const ray3f& ray, bool find_any) {
throw embree_error{"Embree not available"};
}
scene_intersection intersect_instance_ebvh(const scene_ebvh& sbvh,
intersection3f intersect_instance_ebvh(const scene_ebvh& sbvh,
const scene_data& scene, int instance, const ray3f& ray, bool find_any) {
throw embree_error{"Embree not available"};
}
Expand Down
Loading

0 comments on commit 940fdbc

Please sign in to comment.