Esempio n. 1
0
File: cylin.c Progetto: cheque/s3d
Inode *cylin_intersect(Prim *p, Ray ro)
{
  double a, b, c, disc, t0, t1, t2, t3;
  Inode *i0, *i1;
  int flag[4] = {FALSE, FALSE, FALSE, FALSE};
  Ray r = ray_transform(ro, p->ti);
  Vector3 Sol0, Sol1, Sol2, Sol3;
  
  a = SQR(r.d.x) + SQR(r.d.y);
  b = 2 * (r.o.x * r.d.x + r.o.y * r.d.y);
  c = SQR(r.o.x) + SQR(r.o.y) - 1;

  // Case 0: no solution / infinite solutions
  if ((disc = SQR(b) - 4 * a * c) <= 0)
    return (Inode *)0;

  if ( fabs(a) < RAY_EPS ) {
    	return (Inode *)0;
  } else {  
    t0 = (-b - sqrt(disc)) / (2 * a);
    t1 = (-b + sqrt(disc)) / (2 * a);
    Sol0 = ray_point(r, t0);
    Sol1 = ray_point(r, t1);
    if (t1 > RAY_EPS && Sol1.z >= 0 && Sol1.z <= 1){
    	flag[1] = TRUE;
    }
    if (t0 > RAY_EPS && Sol0.z >= 0 && Sol0.z <= 1){
    	flag[0] = TRUE;
    }
  }

  // Ray NOT parallel to base caps --> Cap intersections
  if ( fabs(r.d.z) > RAY_EPS ){
  	 t2 = - (r.o.z) / (r.d.z);
  	 t3 = (1 - (r.o.z)) / (r.d.z);
  	 Sol2 = ray_point(r,t2);
  	 Sol3 = ray_point(r,t3);
  	 if (t2 > RAY_EPS && (SQR(Sol2.x) + SQR(Sol2.y)) <= 1)
  	 	flag[2] = TRUE;
 	 if (t3 > RAY_EPS && (SQR(Sol3.x) + SQR(Sol3.y)) <= 1)
  	 	flag[3] = TRUE;
  }
  
  int k = 0, nsols = 0;
  double t[4] = {t0, t1, t2, t3};
  while (k < 4 && nsols < 2){
  		if (flag[k]){
  			Vector3 n = v3_unit(cylin_gradient(p, ray_point(ro, t[k])));
  			if ( nsols == 0 ){
  				i0 = inode_alloc(t[k], n, TRUE);
  			} else {
  				i1 = inode_alloc(t[k], n, FALSE);
  				i0->next = i1;
  			}
  			nsols++;
  		}
  		k++;
  }
  return i0;
}
Esempio n. 2
0
File: torus.c Progetto: cheque/s3d
Inode *torus_intersect(Prim *p, Ray ro)
{
  double a, b, c, disc, t0, t1;
  Inode *i0, *i1;
  Ray r = ray_transform(ro, p->ti);

  a = v3_sqrnorm(r.d);
  b = 2 * v3_dot(r.d, r.o);
  c = v3_sqrnorm(r.o) - 1;
  if ((disc = SQR(b) - 4 * a * c) <= 0)
    return (Inode *)0;
  t0 = (-b - sqrt(disc)) / (2 * a);
  t1 = (-b + sqrt(disc)) / (2 * a);
  if (t1 < RAY_EPS)
    return (Inode *)0;
  if (t0 < RAY_EPS) {
    Vector3 n1 = v3_unit(torus_gradient(p, ray_point(r, t1)));
    return inode_alloc(t1, n1, FALSE);
  } else {
    Vector3 n0 = v3_unit(torus_gradient(p, ray_point(ro, t0)));
    Vector3 n1 = v3_unit(torus_gradient(p, ray_point(ro, t1)));
    i0 = inode_alloc(t0, n0, TRUE);
    i1 = inode_alloc(t1, n1, FALSE);
    i0->next = i1;
    return i0;
  }
}
Esempio n. 3
0
File: value.c Progetto: kebekus/srt
static inline v4su sign_test(v4sf n, struct ray ray, float a)
{
	m34sf p = ray_point(n, ray);
	v4sf v = curve(p, a);
	m34sf p0 = ray_point(n + v4sf_set1(-0.0001), ray);
	m34sf p1 = ray_point(n + v4sf_set1(0.0001), ray);
	v4sf v0 = curve(p0, a);
	v4sf v1 = curve(p1, a);
	return sign_change(v, v0) | sign_change(v, v1);
}
Esempio n. 4
0
File: value.c Progetto: kebekus/srt
static inline v4sf bisect(i4sf l, struct ray ray, float a)
{
	i4sf k = l;
	m34sf p0 = ray_point(k.min, ray);
	v4sf v0 = curve(p0, a);
	for (int i = 0; i < 20; i++) {
		v4sf x = v4sf_set1(0.5) * (k.min + k.max);
		m34sf p1 = ray_point(x, ray);
		v4su test = sign_change(v0, curve(p1, a));
		k.min = v4sf_select(test, k.min, x);
		k.max = v4sf_select(test, x, k.max);
	}
	return v4sf_set1(0.5) * (k.min + k.max);
}
Esempio n. 5
0
CollisionResult collision_ray_scene_union(const Ray* ray, const Scene* scene) {
	const Scene* scene1 = ((ScenePair*)scene->data)->scene1;
	const Scene* scene2 = ((ScenePair*)scene->data)->scene2;

	const int max_iterations = 10;

	CollisionResult r1;
	{
		Ray ray2 = *ray;
		Vec3 p;
		for (int i = 0; i < max_iterations; ++i) {
			r1 = collision_ray_scene(&ray2, scene1);
			if (r1.type == None) { break; }
			p = ray_point(&ray2, r1.time);
			if (!scene_is_point_in_solid(scene2, &p)) { break; }
			Vec3 ro = ray_point(&ray2, r1.time+0.1);
			ray2 = ray_init(&ro, &ray2.direction);
		}
		if (r1.type != None) {
			Vec3 v = vec3_sub(&p, &ray->origin);
			r1.time = vec3_dot(&ray->direction, &v);
		}
	}

	CollisionResult r2;
	{
		Ray ray2 = *ray;
		Vec3 p;
		for (int i = 0; i < max_iterations; ++i) {
			r2 = collision_ray_scene(&ray2, scene2);
			if (r2.type == None) { break; }
			p = ray_point(&ray2, r2.time);
			if (!scene_is_point_in_solid(scene1, &p)) { break; }
			Vec3 ro = ray_point(&ray2, r2.time+0.1);
			ray2 = ray_init(&ro, &ray2.direction);
		}
		if (r2.type != None) {
			Vec3 v = vec3_sub(&p, &ray->origin);
			r2.time = vec3_dot(&ray->direction, &v);
		}
	}

	if (r1.type == None) {
		if (r2.type == None) {
			return (CollisionResult){.type=None};
		} else {
			return r2;
		}
	} else {
Esempio n. 6
0
File: main.c Progetto: mattjakob/s3d
main(int argc, char **argv)
{
  Prim *o;
  Color c; int u, v;
  Ray r; Inode *l;

  o = sphere_instance(&sphere_funcs);
  init_sdl();
  s = scene_read();
  init_render();

  for (v = s->view->sc.ll.y; v < s->view->sc.ur.y; v += 1) {
    for (u = s->view->sc.ll.x; u < s->view->sc.ur.x; u += 1) {
      r = ray_unit(ray_transform(ray_view(u, v), mclip));
      if ((l = ray_intersect(s->objs, r)) != NULL) 
        c = point_tshade(ray_point(r, l->t), l->n, s->view->center, rc, l->m, o);
      else 
	c = bgcolor;
      inode_free(l);
      img_putc(s->img, u, v, col_dpymap(c));
    }
  }
  img_write(s->img,"stdout",0);
  exit(0);
}
Esempio n. 7
0
File: value.c Progetto: kebekus/srt
static inline v4su epsilon_test(v4sf n, struct ray ray, float a)
{
	float epsilon = 0.0000000001;
	m34sf p = ray_point(n, ray);
	v4sf v = curve(p, a);
	return v4sf_lt(v4sf_abs(v), v4sf_set1(epsilon));
}
Esempio n. 8
0
Color ray_shade(int level, Real w, Ray v, RContext *rc, Object *ol)
{
  Inode *i = ray_intersect(ol, v);
  if (i != NULL) { Light *l; Real wf;
    Material *m = i->m;
    Vector3 p = ray_point(v, i->t); 
    Cone  recv = cone_make(p, i->n, PIOVER2);
    Color c = c_mult(m->c, c_scale(m->ka, ambient(rc)));
    rc->p = p;

    for (l = rc->l; l != NULL; l = l->next) 
      if ((*l->transport)(l, recv, rc) && (wf = shadow(l, p, ol)) > RAY_WF_MIN)
	c = c_add(c, c_mult(m->c,
		     c_scale(wf * m->kd * v3_dot(l->outdir,i->n), l->outcol)));

    if (level++ < MAX_RAY_LEVEL) {
      if ((wf = w * m->ks) > RAY_WF_MIN) {
	Ray r = ray_make(p, reflect_dir(v.d, i->n));
        c = c_add(c, c_mult(m->s,
		     c_scale(m->ks, ray_shade(level, wf, r, rc, ol))));
      }
      if ((wf = w * m->kt) > RAY_WF_MIN) {
	Ray t = ray_make(p, refract_dir(v.d, i->n, (i->enter)? 1/m->ir: m->ir));
	if (v3_sqrnorm(t.d) > 0) {
	  c = c_add(c, c_mult(m->s,
		       c_scale(m->kt, ray_shade(level, wf, t, rc, ol))));
	}
      }
    }
    inode_free(i); 
    return c;
  } else {
    return BG_COLOR;
  }
}
Esempio n. 9
0
File: value.c Progetto: kebekus/srt
static inline v4sf newton(v4sf n, struct ray ray, float a)
{
	for (int i = 0; i < 20; i++) {
		m34sf p = ray_point(n, ray);
		n -= curve(p, a) / m34sf_dot(ray.d, gradient(p, a));
	}
	return n;
}
Esempio n. 10
0
File: value.c Progetto: kebekus/srt
static inline v4sf newton_bisect(i4sf l, struct ray ray, float a)
{
	i4sf k = l;
	m34sf p0 = ray_point(k.min, ray);
	v4sf v0 = curve(p0, a);
	for (int i = 0; i < 20; i++) {
		v4sf x = v4sf_set1(0.5) * (k.min + k.max);
		m34sf p1 = ray_point(x, ray);
		v4sf n = x - curve(p1, a) / m34sf_dot(ray.d, gradient(p1, a));
		v4su inside = v4sf_lt(k.min, n) & v4sf_lt(n, k.max);
		v4sf nx = v4sf_select(inside, n, x);
		m34sf p2 = ray_point(nx, ray);
		v4su test = sign_change(v0, curve(p2, a));
		k.min = v4sf_select(test, k.min, nx);
		k.max = v4sf_select(test, nx, k.max);
	}
	return v4sf_set1(0.5) * (k.min + k.max);
}
Esempio n. 11
0
File: value.c Progetto: kebekus/srt
static inline v4sf newton_forward(v4sf n, struct ray ray, float a)
{
	for (int i = 0; i < 20; i++) {
		m34sf p = ray_point(n, ray);
		v4sf x = - curve(p, a) / m34sf_dot(ray.d, gradient(p, a));
		n += v4sf_max(x, v4sf_set1(0));
	}
	return n;
}
Esempio n. 12
0
File: value.c Progetto: kebekus/srt
static inline m34sf color(v4sf n, v4su test, struct ray ray, float a)
{
	m34sf p = ray_point(n, ray);
	v4sf diff = m34sf_dot(ray.d, m34sf_normal(gradient(p, a)));
	v4su face = v4sf_gt(diff, v4sf_set1(0));
	v4sf r = v4sf_and(test & face, diff);
	v4sf g = v4sf_and(test & ~face, -diff);
	v4sf b = v4sf_set1(0);
	return (m34sf) { r, g, b };
}
Esempio n. 13
0
File: value.c Progetto: kebekus/srt
static inline v4su localize(i4sf *l, struct ray ray, float a)
{
	float coarse = 0.05;
	float fine = 0.001;
	i4sf k = *l;
	m34sf p0 = ray_point(k.min, ray);
	v4sf v0 = curve(p0, a);
	v4su test = v4su_set1(0);
	while (!v4su_all_ones(test | v4sf_ge(k.min, l->max))) {
		v4sf x = v0 / m34sf_dot(ray.d, gradient(p0, a));
		v4sf step = v4sf_clamp(v4sf_abs(x), v4sf_set1(fine), v4sf_set1(coarse));
		k.max = v4sf_select(test, k.max, k.min + step);
		m34sf p1 = ray_point(k.max, ray);
		v4sf v1 = curve(p1, a);
		test |= v4sf_lt(k.max, l->max) & sign_change(v0, v1);
		k.min = v4sf_select(test, k.min, k.max);
		v0 = v1;
		p0 = p1;
	}
	l->min = v4sf_select(test, k.min, l->min);
	l->max = v4sf_select(test, k.max, l->max);
	return test;
}
Esempio n. 14
0
File: value.c Progetto: kebekus/srt
static inline v4su zero_test(v4sf n, struct ray ray, float a)
{
	m34sf p = ray_point(n, ray);
	v4sf v = curve(p, a);
	return v4sf_eq(v4sf_set1(0), v);
}