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); }
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; }