示例#1
0
int	intersect_shadow(float t, t_scene *scene, t_ray *ray)
{
	t_vec3	intersect_pt;
	t_ray	shadow;
	float	t_tmp;

	intersect_pt.x = ray->o.x + t * ray->d.x;
	intersect_pt.y = ray->o.y + t * ray->d.y;
	intersect_pt.z = ray->o.z + t * ray->d.z;
	init_coord(&shadow.o, 0, 0, -30);
	init_vec3(&(shadow.d), shadow.o.x - intersect_pt.x, shadow.o.y - intersect_pt.y, shadow.o.z - intersect_pt.z);
	t_tmp = -1;
	while (scene != NULL)
	{
		if (scene->type == CIRCLE)
			t_tmp = intersect_circle(&shadow, scene->object);
		else if (scene->type == PLANE)
			t_tmp = intersect_plane(&shadow, scene->object);
		else if (scene->type == CYLINDER)
			t_tmp = intersect_cylinder(&shadow, scene->object);
		if (t_tmp > 0)
		{
			return (1);
		}
		scene = scene->next;
	}
	return (0);
}
示例#2
0
static gboolean
intersect_cylinder (GimpVector3        vp,
		    GimpVector3        dir,
		    FaceIntersectInfo *face_intersect)
{
  gdouble  a, b, c, d, e, f, tmp, l;
  gboolean result = FALSE;
  gint     i;

#define sqr(a) (a*a)

  a = sqr (dir.x) + sqr (dir.z);
  b = 2.0 * (vp.x * dir.x + vp.z * dir.z);
  c = sqr (vp.x) + sqr (vp.z) - sqr (mapvals.cylinder_radius);

  d = sqr (b) - 4.0 * a * c;

  if (d >= 0.0)
    {
      e = sqrt (d);
      f = 2.0 * a;

      if (f != 0.0)
        {
          result = TRUE;

          face_intersect[0].t = (-b+e)/f;
          face_intersect[1].t = (-b-e)/f;

          if (face_intersect[0].t>face_intersect[1].t)
            {
              tmp = face_intersect[0].t;
              face_intersect[0].t = face_intersect[1].t;
              face_intersect[1].t = tmp;
            }

          for (i = 0; i < 2; i++)
            {
              face_intersect[i].s.x = vp.x + face_intersect[i].t * dir.x;
              face_intersect[i].s.y = vp.y + face_intersect[i].t * dir.y;
              face_intersect[i].s.z = vp.z + face_intersect[i].t * dir.z;

              face_intersect[i].n = face_intersect[i].s;
              face_intersect[i].n.y = 0.0;
              gimp_vector3_normalize(&face_intersect[i].n);

              l = mapvals.cylinder_length/2.0;

              face_intersect[i].u = (atan2(face_intersect[i].s.x,face_intersect[i].s.z)+G_PI)/(2.0*G_PI);
              face_intersect[i].v = (face_intersect[i].s.y+l)/mapvals.cylinder_length;

              /* Mark hitpoint as on the cylinder hull */
              /* ===================================== */

              face_intersect[i].face = 0;

              /* Check if we're completely off the cylinder axis */
              /* =============================================== */

              if (face_intersect[i].s.y>l || face_intersect[i].s.y<-l)
                {
                  /* Check if we've hit a cap */
                  /* ======================== */

                  if (face_intersect[i].s.y>l)
                    {
                      if (intersect_circle(vp,dir,l,&face_intersect[i])==FALSE)
                        result = FALSE;
                      else
                        {
                          face_intersect[i].face = 2;
                          face_intersect[i].v = 1 - face_intersect[i].v;
                          gimp_vector3_set(&face_intersect[i].n, 0.0, 1.0, 0.0);
                        }
                    }
                  else
                    {
                      if (intersect_circle(vp,dir,-l,&face_intersect[i])==FALSE)
                        result = FALSE;
                      else
                        {
                          face_intersect[i].face = 1;
                          gimp_vector3_set(&face_intersect[i].n, 0.0, -1.0, 0.0);
                        }
                    }
                }
            }
        }
    }

#undef sqr

  return result;
}