| 190 | } |
| 191 | |
| 192 | bool AABB::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector3 *r_intersection_point, Vector3 *r_normal) const { |
| 193 | #ifdef MATH_CHECKS |
| 194 | if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) { |
| 195 | ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size."); |
| 196 | } |
| 197 | #endif |
| 198 | real_t min = 0, max = 1; |
| 199 | int axis = 0; |
| 200 | real_t sign = 0; |
| 201 | |
| 202 | for (int i = 0; i < 3; i++) { |
| 203 | real_t seg_from = p_from[i]; |
| 204 | real_t seg_to = p_to[i]; |
| 205 | real_t box_begin = position[i]; |
| 206 | real_t box_end = box_begin + size[i]; |
| 207 | real_t cmin, cmax; |
| 208 | real_t csign; |
| 209 | |
| 210 | if (seg_from < seg_to) { |
| 211 | if (seg_from > box_end || seg_to < box_begin) { |
| 212 | return false; |
| 213 | } |
| 214 | real_t length = seg_to - seg_from; |
| 215 | cmin = (seg_from < box_begin) ? ((box_begin - seg_from) / length) : 0; |
| 216 | cmax = (seg_to > box_end) ? ((box_end - seg_from) / length) : 1; |
| 217 | csign = -1.0; |
| 218 | |
| 219 | } else { |
| 220 | if (seg_to > box_end || seg_from < box_begin) { |
| 221 | return false; |
| 222 | } |
| 223 | real_t length = seg_to - seg_from; |
| 224 | cmin = (seg_from > box_end) ? (box_end - seg_from) / length : 0; |
| 225 | cmax = (seg_to < box_begin) ? (box_begin - seg_from) / length : 1; |
| 226 | csign = 1.0; |
| 227 | } |
| 228 | |
| 229 | if (cmin > min) { |
| 230 | min = cmin; |
| 231 | axis = i; |
| 232 | sign = csign; |
| 233 | } |
| 234 | if (cmax < max) { |
| 235 | max = cmax; |
| 236 | } |
| 237 | if (max < min) { |
| 238 | return false; |
| 239 | } |
| 240 | } |
| 241 | |
| 242 | Vector3 rel = p_to - p_from; |
| 243 | |
| 244 | if (r_normal) { |
| 245 | Vector3 normal; |
| 246 | normal[axis] = sign; |
| 247 | *r_normal = normal; |
| 248 | } |
| 249 |
no outgoing calls
no test coverage detected