static int refract_obj(t_env *e, t_env *refract, t_vector n) { double cos; double factor; double index; cos = vdot(e->ray.dir, n); if (cos > 0.0) { index = e->material[e->object_hit->material]->ior; factor = 1.0 - (1.0 - cos * cos) * index * index; if (factor <= 0.0) return (0); factor = -cos * index + sqrt(factor); } else { index = 1.0 / e->material[e->object_hit->material]->ior; factor = 1.0 - (1.0 - cos * cos) * index * index; if (factor <= 0.0) return (0); factor = -cos * index - sqrt(factor); } refract->ray.dir = vadd(vmult(e->ray.dir, index), vmult(n, factor)); return (1); }
void get_ray_dir(t_env *e, double x, double y) { e->ray.dir = vunit(vsub(vsub( vadd(e->camera.l, vmult(e->camera.u, x * e->camera.stepx)), vmult(e->camera.v, y * e->camera.stepy)), e->camera.loc)); e->ray.loc = e->camera.loc; e->ray.o_in = NULL; e->ray.ior = 1; }
void vsphereSort( const mat* m, u32* inds, const triple* vs, const f32* radiuss, u32 sz ){ static u32 vlshmap = 0; static u32 vlshmasz = 0; u32 i; for( i = 0; i < sz; ++i ) inds[ i ] = i; if( vlshma == NULL ){ vlshmasz = sz; vlshmap = vmalloc( sz * sizeof( f32 ) ); vlshma = vmem( vlshmap ); }else if( vlshmasz < sz ){ vgrow( vlshmap, ( sz - vlshmasz ) ); vlshma = vmem( vlshmap ); } for( i = 0; i < sz; ++i ){ f32 d2, n, r2, d; triple v = vs[ i ]; vmult( &v, m ); r2 = radiuss[ i ] * radiuss[ i ]; d2 = vdot( &v, &v ); d = vsqrt( d2 ); if( d2 > r2 ) n = ( r2 * 0.5f ) / vsqrt( d2 - r2 ); else n = ( r2 * 0.5f ) / vsqrt( r2 - d2 ); vlshma[ i ] = d - n; } vqsort( (u8*)inds, sz, sizeof( u32 ), vsphereSortHelper ); }
void vface( triple* v, f32 xrot, f32 yrot ){ static const triple xr = { 0.0f, 1.0f, 0.0f }; static const triple yr = { 1.0f, 0.0f, 0.0f }; static mat m; midentity( &m ); mrotate( &m, &xr, xrot * torad ); mrotate( &m, &yr, yrot * torad ); v->x = v->y = 0.0f; v->z = 1.0f; vmult( v, &m ); }
void setup_camera_plane(t_env *e) { t_vector n; t_vector c; double w; double h; h = 18.0 * ARBITRARY_NUMBER / 35.0; w = h * (double)e->x / (double)e->y; n = vunit(vsub(e->camera.loc, e->camera.dir)); e->camera.u = vunit(vcross(e->camera.up, n)); e->camera.v = vunit(vcross(n, e->camera.u)); c = vsub(e->camera.loc, vmult(n, ARBITRARY_NUMBER)); e->camera.l = vadd(vsub(c, vmult(e->camera.u, w / 2.0)), vmult(e->camera.v, h / 2.0)); e->camera.stepx = w / (double)e->x; e->camera.stepy = h / (double)e->y; }
static void set_refract_ray_prim(t_env *e, t_env *refract) { t_vector n; refract->ray.loc = vadd(e->ray.loc, vmult(e->ray.dir, e->t)); n = get_normal(e, refract->ray.loc); if (refract->flags & RAY_INSIDE) { n = vunit(vsub((t_vector){0.0, 0.0, 0.0}, n)); if (refract_prim(e, refract, n)) refract->flags &= ~RAY_INSIDE; else set_reflect_ray(e, refract); } else { if (refract_prim(e, refract, n)) refract->flags |= RAY_INSIDE; else set_reflect_ray(e, refract); } }
int intersect_disk(t_ray *r, t_prim *o, double *t) { t_vector point; double denominator; double numerator; double t0; if ((denominator = vdot(r->dir, o->normal)) == 0) return (0); numerator = vdot(o->loc, o->normal) - vdot(r->loc, o->normal); t0 = numerator / denominator; if (t0 > EPSILON) { point = vadd(r->loc, vmult(r->dir, t0)); if (vnormalize(vsub(point, o->loc)) <= o->radius) { *t = t0; return (1); } return (0); } return (0); }
void vmultAll( triple* vs, const mat* m, u32 sz ){ u32 i; for( i = 0; i < sz; ++i ) vmult( vs + i, m ); }