//////////////////////////////////////////////////// // Fast ray/AABB intersection test. // Implementation inspired by zacharmarz. // https://gamedev.stackexchange.com/questions/18436/most-efficient-aabb-vs-ray-collision-algorithms //////////////////////////////////////////////////// bool Intersections::aabbIntersect( boundingBox bbox, glm::vec3 ray_o, glm::vec3 ray_dir, float &t_near, float &t_far ) { glm::vec3 dirfrac( 1.0f / ray_dir.x, 1.0f / ray_dir.y, 1.0f / ray_dir.z ); float t1 = ( bbox.min.x - ray_o.x ) * dirfrac.x; float t2 = ( bbox.max.x - ray_o.x ) * dirfrac.x; float t3 = ( bbox.min.y - ray_o.y ) * dirfrac.y; float t4 = ( bbox.max.y - ray_o.y ) * dirfrac.y; float t5 = ( bbox.min.z - ray_o.z ) * dirfrac.z; float t6 = ( bbox.max.z - ray_o.z ) * dirfrac.z; float tmin = std::max( std::max( std::min( t1, t2 ), std::min( t3, t4 ) ), std::min( t5, t6 ) ); float tmax = std::min( std::min( std::max( t1, t2 ), std::max( t3, t4 ) ), std::max( t5, t6 ) ); // If tmax < 0, ray intersects AABB, but entire AABB is behind ray, so reject. if ( tmax < 0.0f ) { return false; } // If tmin > tmax, ray does not intersect AABB. if ( tmin > tmax ) { return false; } t_near = tmin; t_far = tmax; return true; }
std::pair<bool, float> BoundingBox::intersects( const glm::vec3& origin, const glm::vec3& direction) const { // r.dir is unit direction vector of ray glm::vec3 dirfrac(1.0f / direction.x, 1.0f / direction.y, 1.0f / direction.z); // lb is the corner of AABB with minimal coordinates - left bottom, // rt is maximal corner // r.org is the origin of ray float t1 = (_min.x - origin.x)*dirfrac.x; float t2 = (_max.x - origin.x)*dirfrac.x; float t3 = (_min.y - origin.y)*dirfrac.y; float t4 = (_max.y - origin.y)*dirfrac.y; float t5 = (_min.z - origin.z)*dirfrac.z; float t6 = (_max.z - origin.z)*dirfrac.z; float tmin = glm::max( glm::max(glm::min(t1, t2), glm::min(t3, t4)), glm::min(t5, t6)); float tmax = glm::min( glm::min(glm::max(t1, t2), glm::max(t3, t4)), glm::max(t5, t6)); // if tmax < 0, ray (line) is intersecting AABB, but whole AABB is behing us if (tmax < 0) { return {false, tmax}; } // if tmin > tmax, ray doesn't intersect AABB if (tmin > tmax) { return {false, tmax}; } return {true, tmin}; }