Beispiel #1
0
////////////////////////////////////////////////////
// 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};
}