int BasicPrimitiveTests::IntersectingSegmentAgainstOBB(const LineSegment & segment, const OBB & obb, float & rtn_t1, float & rtn_t2) { Eigen::Matrix3f obb_rotation; obb.GetRotationMatrix(obb_rotation); Eigen::Vector3f segment_A_obb = obb_rotation * (segment.GetPointA() - obb.GetCenter()); Eigen::Vector3f segment_B_obb = obb_rotation * (segment.GetPointB() - obb.GetCenter()); rtn_t1 = 0.0f; rtn_t2 = FLT_MAX; Eigen::Vector3f aabb_min = -obb.GetExtents(); Eigen::Vector3f aabb_max = obb.GetExtents(); Eigen::Vector3f segment_direction = segment_B_obb - segment_A_obb; for (int i = 0; i < 3; ++i) { if (abs(segment_direction[i]) < EPSILON) { //Ray is parallel to slab. Not hit if origin not within slab. if (segment_A_obb[i] < aabb_min[i] || segment_A_obb[i] > aabb_max[i]) { return 0; } } else { float one_over_direction = 1.0f / segment_direction[i]; float t1 = (aabb_min[i] - segment_A_obb[i]) * one_over_direction; float t2 = (aabb_max[i] - segment_A_obb[i]) * one_over_direction; if (t1 > 1.0f && t2 > 1.0f) { return 0; } if (t1 > t2) Swap(t1, t2); if (t1 > rtn_t1) rtn_t1 = t1; if (t2 > rtn_t2) rtn_t2 = t2; if (rtn_t1 > rtn_t2) return 0; } } if (rtn_t1 >= 0.0f && rtn_t1 <= 1.0f) { if (rtn_t2 >= 0.0f && rtn_t2 <= 1.0f) { return 2; } else { return 1; } } else { Swap(rtn_t1, rtn_t2); if (rtn_t1 >= 0.0f && rtn_t1 <= 1.0f) { return 1; } return 0; } }
bool BasicPrimitiveTests::IntersectingRayAgainstOBB(const Ray & ray, const OBB & obb, float & rtn_t) { Eigen::Matrix3f obb_rotation; obb.GetRotationMatrix(obb_rotation); Eigen::Vector3f ray_d_obb = obb_rotation * ray.GetDirection(); Eigen::Vector3f ray_o_obb = obb_rotation * (ray.GetOrigin() - obb.GetCenter()); rtn_t = 0.0f; float tmax = FLT_MAX; Eigen::Vector3f aabb_min = -obb.GetExtents(); Eigen::Vector3f aabb_max = obb.GetExtents(); for (int i = 0; i < 3; ++i) { if (abs(ray_d_obb[i]) < EPSILON) { //Ray is parallel to slab. Not hit if origin not within slab. if (ray_o_obb[i] < aabb_min[i] || ray_o_obb[i] > aabb_max[i]) { return false; } } else { float one_over_direction = 1.0f / ray_d_obb[i]; float t1 = (aabb_min[i] - ray_o_obb[i]) * one_over_direction; float t2 = (aabb_max[i] - ray_o_obb[i]) * one_over_direction; if (t1 > t2) Swap(t1, t2); if (t1 > rtn_t) rtn_t = t1; if (t2 > tmax) tmax = t2; if (rtn_t > tmax) return false; } } return true; }