| 191 | } |
| 192 | |
| 193 | bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index, int32_t *r_face_index) const { |
| 194 | if (!valid) { |
| 195 | return false; |
| 196 | } |
| 197 | |
| 198 | uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth); |
| 199 | |
| 200 | enum { |
| 201 | TEST_AABB_BIT = 0, |
| 202 | VISIT_LEFT_BIT = 1, |
| 203 | VISIT_RIGHT_BIT = 2, |
| 204 | VISIT_DONE_BIT = 3, |
| 205 | VISITED_BIT_SHIFT = 29, |
| 206 | NODE_IDX_MASK = (1 << VISITED_BIT_SHIFT) - 1, |
| 207 | VISITED_BIT_MASK = ~NODE_IDX_MASK, |
| 208 | |
| 209 | }; |
| 210 | |
| 211 | Vector3 n = (p_end - p_begin).normalized(); |
| 212 | real_t d = 1e10; |
| 213 | bool inters = false; |
| 214 | |
| 215 | int level = 0; |
| 216 | |
| 217 | const Triangle *triangleptr = triangles.ptr(); |
| 218 | const Vector3 *vertexptr = vertices.ptr(); |
| 219 | const BVH *bvhptr = bvh.ptr(); |
| 220 | |
| 221 | int pos = bvh.size() - 1; |
| 222 | |
| 223 | stack[0] = pos; |
| 224 | while (true) { |
| 225 | uint32_t node = stack[level] & NODE_IDX_MASK; |
| 226 | const BVH &b = bvhptr[node]; |
| 227 | bool done = false; |
| 228 | |
| 229 | switch (stack[level] >> VISITED_BIT_SHIFT) { |
| 230 | case TEST_AABB_BIT: { |
| 231 | if (!b.aabb.intersects_segment(p_begin, p_end)) { |
| 232 | stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node; |
| 233 | } else { |
| 234 | if (b.face_index >= 0) { |
| 235 | const Triangle &s = triangleptr[b.face_index]; |
| 236 | Face3 f3(vertexptr[s.indices[0]], vertexptr[s.indices[1]], vertexptr[s.indices[2]]); |
| 237 | |
| 238 | Vector3 res; |
| 239 | |
| 240 | if (f3.intersects_segment(p_begin, p_end, &res)) { |
| 241 | real_t nd = n.dot(res); |
| 242 | if (nd < d) { |
| 243 | d = nd; |
| 244 | r_point = res; |
| 245 | r_normal = f3.get_plane().get_normal(); |
| 246 | if (r_surf_index) { |
| 247 | *r_surf_index = s.surface_index; |
| 248 | } |
| 249 | if (r_face_index) { |
| 250 | *r_face_index = b.face_index; |
no test coverage detected