示例#1
0
文件: intersect.ray.c 项目: ifbe/42
//0: 0 intersection
//1: 1 intersections
//-1: infinite intersections
int ray_rect(vec3 ray[], vec3 rect[], vec3 out)
{
	int ret;
	vec3 v;
	vec3 plane[2];
	float vx,vy,xx,yy;
	float* c = rect[0];
	float* r = rect[1];
	float* f = rect[2];
	float* u = rect[3];

	plane[0][0] = c[0];
	plane[0][1] = c[1];
	plane[0][2] = c[2];
	plane[1][0] = u[0];
	plane[1][1] = u[1];
	plane[1][2] = u[2];
	ret = ray_plane(ray, plane, out);
	if(ret <= 0)return ret;

	v[0] = out[0] - c[0];
	v[1] = out[1] - c[1];
	v[2] = out[2] - c[2];
	vx= v[0]*r[0] + v[1]*r[1] + v[2]*r[2];
	vy= v[0]*f[0] + v[1]*f[1] + v[2]*f[2];
	xx= r[0]*r[0] + r[1]*r[1] + r[2]*r[2];
	yy= f[0]*f[0] + f[1]*f[1] + f[2]*f[2];
	if((vx>-xx)&&(vx<xx)&&(vy>-yy)&&(vy<yy))return 1;
	return 0;
}
示例#2
0
// assumes a parallelogram
BOOL ray_quadrangle(const LLVector3 &ray_point, const LLVector3 &ray_direction,
                    const LLVector3 &point_0, const LLVector3 &point_1, const LLVector3 &point_2,
                    LLVector3 &intersection, LLVector3 &intersection_normal)
{
    LLVector3 side_01 = point_1 - point_0;
    LLVector3 side_12 = point_2 - point_1;

    intersection_normal = side_01 % side_12;
    intersection_normal.normVec();

    if (ray_plane(ray_point, ray_direction, point_0, intersection_normal, intersection))
    {
        LLVector3 point_3 = point_0 + (side_12);
        LLVector3 side_23 = point_3 - point_2;
        LLVector3 side_30 = point_0 - point_3;
        if (intersection_normal * (side_01 % (intersection - point_0)) >= 0.0f  &&
                intersection_normal * (side_12 % (intersection - point_1)) >= 0.0f  &&
                intersection_normal * (side_23 % (intersection - point_2)) >= 0.0f  &&
                intersection_normal * (side_30 % (intersection - point_3)) >= 0.0f)
        {
            return TRUE;
        }
    }
    return FALSE;
}
示例#3
0
BOOL ray_circle(const LLVector3 &ray_point, const LLVector3 &ray_direction,
                const LLVector3 &circle_center, const LLVector3 plane_normal, F32 circle_radius,
                LLVector3 &intersection)
{
    if (ray_plane(ray_point, ray_direction, circle_center, plane_normal, intersection))
    {
        if (circle_radius >= (intersection - circle_center).magVec())
        {
            return TRUE;
        }
    }
    return FALSE;
}
示例#4
0
    /*! \brief A parabola-plane intersection test which ignores
      negative time intersections.
     
      \param T The origin of the ray relative to a point on the plane.
      \param D The direction/velocity of the ray.
      \param A The acceleration of the ray.
      \param N The normal of the plane.
      \param d The thickness of the plane.
      \return The time until the intersection, or HUGE_VAL if no intersection.
     */
    inline double parabola_plane(const math::Vector& T, const math::Vector& D, const math::Vector& A, math::Vector N, const double d)
    {
      //Check if this is actually a ray-plane test
      double adot = A | N;
      if (adot == 0) return ray_plane(T, D, N, d);

      //Create the rest of the variables
      double rdot = T | N;
      
      //Ensure that the normal is pointing towards the particle
      //position (so that (rdot < d) is a test if the particle is
      //overlapped)
      if (rdot < 0)
	{ adot = -adot; rdot = -rdot; N = -N; }
      
      double vdot = D | N;

      //Check for overlapped and approaching dynamics
      if ((rdot <= d) && (vdot < 0)) return 0;

      double arg = vdot * vdot - 2 * (rdot - d) * adot;
      double minimum = - vdot / adot;

      if (adot < 0)
	{ //Particle will always hit the wall
	  
	  //If there are no real roots, the particle is arcing inside
	  //the wall and there is a collision at the minimum
	  if (arg < 0) return minimum;
	  
	  std::pair<double, double> roots
	    = magnet::math::quadraticEquation(0.5 * adot, vdot, rdot - d);
	  return std::max(roots.first, roots.second);
	}
      else
	{ //Particle can curve away from the wall

	  //Check if the particle misses the wall completely or we're
	  //passed the minimum
	  if ((arg < 0) || (minimum < 0)) return HUGE_VAL;
	  
	  std::pair<double, double> roots
	    = magnet::math::quadraticEquation(0.5 * adot, vdot, rdot - d);
	  return std::min(roots.first, roots.second);	  
	}
    }