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); }
int intersect_prim(t_env *e, t_ray *ray, size_t prim, double *t) { if (e->prim[prim]->type == PRIM_SPHERE) return (intersect_sphere(ray, e->prim[prim], t)); if (e->prim[prim]->type == PRIM_HEMI_SPHERE) return (intersect_hemi_sphere(ray, e->prim[prim], t)); if (e->prim[prim]->type == PRIM_PLANE) return (intersect_plane(ray, e->prim[prim], t)); if (e->prim[prim]->type == PRIM_CYLINDER) return (intersect_cylinder(ray, e->prim[prim], t)); if (e->prim[prim]->type == PRIM_CONE) return (intersect_cone(ray, e->prim[prim], t)); if (e->prim[prim]->type == PRIM_DISK) return (intersect_disk(ray, e->prim[prim], t)); return (0); }
/* * Compute the dimensions of the pixel footprint's AABB in uv-space. * * First intersect the four rays through the pixel corners with * the tangent plane at the given intersection. * * Then the given code computes uv-coordinates for these * intersection points. * * Finally use the uv-coordinates and compute the AABB in * uv-space. * * Return width (du) and height (dv) of the AABB. * */ glm::vec2 Object:: compute_uv_aabb_size(const Ray rays[4], Intersection const& isect) { // TODO: compute intersection positions glm::vec3 intersection_positions[4] = { isect.position, isect.position, isect.position, isect.position }; for (int i = 0; i < 4; ++i) { // todo: compute intersection positions using a ray->plane // intersection float t; if (intersect_plane(rays[i].origin, rays[i].direction, isect.position, isect.normal, &t)) { intersection_positions[i] = rays[i].origin + rays[i].direction * t; } } // compute uv coordinates from intersection positions glm::vec2 intersection_uvs[4]; get_intersection_uvs(intersection_positions, isect, intersection_uvs); glm::vec2 iu[4] = intersection_uvs; // Get the extremities on each axis. // Because its a 4 vertex polygon in row major order there are always 2 // vertices that can be the searched value. float uvs_min_y = iu[0][1]; float uvs_min_x = iu[0][0]; float uvs_max_y = iu[0][1]; float uvs_max_x = iu[0][0]; for (int i = 0; i < 4; i++) { uvs_min_y = fmin(iu[i][1], uvs_min_y); uvs_min_x = fmin(iu[i][0], uvs_min_x); uvs_max_y = fmax(iu[i][1], uvs_max_y); uvs_max_x = fmax(iu[i][0], uvs_max_x); } // TODO: compute dudv = length of sides of AABB in uv space return glm::vec2(uvs_max_x - uvs_min_x, uvs_max_y - uvs_min_y); }
static inline void trace_ray(rt_context_t *rtx) { rtx->dist = FARDIST; rtx->hit = NOHIT; unsigned int i; for (i = 0; i < rtx->objnum; i++) { int hit = 0; switch (rtx->obj[i].type) { case SPHERE: hit = intersect_sphere(rtx, i); break; case PLANE: hit = intersect_plane(rtx, i); break; default: break; } rtx->hit = (hit == 1) ? i : rtx->hit; } }
RGB_float recursive_ray_trace(Vector ray, Point p, int step) { RGB_float color = background_clr; RGB_float reflected_color = {0,0,0}; RGB_float refracted_color = {0,0,0}; Spheres *closest_sph; Point *hit = new Point; closest_sph = intersect_scene(p, ray, scene, hit); //get the point color here //intersects a sphere Point *plane_hit = new Point; color = background_clr; if(chessboard_on && intersect_plane(p, ray, N_plane, p0, plane_hit)) { Vector eye_vec = get_vec(*plane_hit, eye_pos); Vector light_vec = get_vec(*plane_hit, p); normalize(&light_vec); normalize(&eye_vec); color = colorPlane(*plane_hit); Vector shadow_vec = get_vec(*plane_hit, light1); Spheres *sph = NULL; if(inShadow(*plane_hit, shadow_vec, scene, sph) && shadow_on) { color = clr_scale(color, .5); } } if(closest_sph != NULL) { Vector eye_vec = get_vec(*hit, eye_pos); Vector surf_norm = sphere_normal(*hit, closest_sph); Vector light_vec = get_vec(*hit, p); normalize(&light_vec); normalize(&surf_norm); normalize(&eye_vec); color = phong(*hit, eye_vec, surf_norm, closest_sph); if(step < step_max && reflection_on) { Vector reflect_vec = vec_minus(vec_scale(surf_norm, vec_dot(surf_norm, light_vec)*2), light_vec); step += 1; normalize(&reflect_vec); reflected_color = recursive_ray_trace(reflect_vec, *hit, step); reflected_color = clr_scale(reflected_color, closest_sph->reflectance); color = clr_add(color, reflected_color); } if(step < step_max && refraction_on) { Vector refracted_ray = getRefractedRay(1.51, closest_sph, surf_norm, light_vec); step += 1; normalize(&refracted_ray); refracted_ray.x = hit->x + refracted_ray.x; refracted_ray.y = hit->x + refracted_ray.y; refracted_ray.z = hit->x + refracted_ray.z; refracted_color = recursive_ray_trace(refracted_ray, *hit, step); color = clr_add(color, reflected_color); } return color; } else { return color; } }
static void check_collision ( collision_data& coldat ) { float radius; if ( coldat.BoundingSphere.x == coldat.BoundingSphere.y && coldat.BoundingSphere.x == coldat.BoundingSphere.z ) { radius = coldat.BoundingSphere.x; } else { radius = 1.0f; // scale polygon for ( small x = 0; x < cache.count; x++ ) { cache.vertex [ x ].x /= coldat.BoundingSphere.x; cache.vertex [ x ].y /= coldat.BoundingSphere.y; cache.vertex [ x ].z /= coldat.BoundingSphere.z; } CalcNormal ( cache.vertex, &cache.normal ); D3DXVec3Normalize ( &cache.normal, &cache.normal ); } D3DXVECTOR3 r; D3DXVECTOR3 pt = cache.vertex [ 0 ]; D3DXVECTOR3 n = cache.normal; D3DXVECTOR3 s = coldat.src - n * radius; float t = D3DXVec3Dot ( &( s - pt ), &n ); if ( t > coldat.dir_len ) { return; } if ( t < -2 * radius ) { return; } if ( t < 0.0f ) { if ( !intersect_plane ( s, n * radius, pt, r ) ) return; } else { if ( !intersect_plane ( s, coldat.dir, pt, r ) ) return; } if ( !point_in_poly ( r ) ) { D3DXVECTOR3 line_dir; r = closest_on_poly ( r, &line_dir ); // mj change - sticky collision fix 27/08/02 D3DXVECTOR3 ndir; //D3DXVec3Cross ( &ndir, &coldat.ndir, &line_dir ); //D3DXVec3Cross ( &ndir, &line_dir, &ndir ); //D3DXVec3Normalize ( &ndir, &ndir ); ndir = coldat.ndir; t = intersect_sphere ( r, -ndir, coldat.src, radius ); } else { t = intersect_sphere ( r, -coldat.ndir, coldat.src, radius ); } if ( t >= 0.0f && t <= coldat.dir_len ) { if ( !coldat.found || t < coldat.dist ) { coldat.found = true; coldat.dist = t; coldat.nearest_poly = r; } } }