Ejemplo n.º 1
0
Archivo: cylin.c Proyecto: 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;
}
Ejemplo n.º 2
0
Archivo: torus.c Proyecto: 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;
  }
}
Ejemplo n.º 3
0
Archivo: main.c Proyecto: 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);
}
Ejemplo n.º 4
0
/**
 * Calculate the intersection of an object and a ray with
 * distance within the given bounds.
 * First triest to find out if the ray intersects the bounding box.
 * \note The diffrence between this function and the virtual method
 * object::get_intersection is that this method works in the world
 * coordinates.
 */
float object_ray_intersection(struct object *o, const struct ray *r,
	float lowerBound, float upperBound){

	if(!bounding_box_ray_intersection(
		&(o->boundingBox), r, lowerBound, upperBound)){
		return NAN;
	}

	struct ray transformed;
	float ratio = ray_transform(r, &(o->invTransform), &transformed);

	lowerBound *= ratio;
	upperBound *= ratio;

	return (o->get_intersection(o, &transformed, lowerBound, upperBound)) / ratio;
}
Ejemplo n.º 5
0
Archivo: main.c Proyecto: mattjakob/s3d
main(int argc, char **argv)
{
    Color c;
    int u, v;
    Ray r;

    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));
            c = ray_shade(0, 1., r, rc, s->objs);
            img_putc(s->img, u, v, col_dpymap(c));
        }
    }
    img_write(s->img,"stdout",0);
    exit(0);
}
Ejemplo n.º 6
0
bool CEntityMiscModel::TestRay( const ray_t *ray, vec_t *dist ) const {
	vec_t dist_start = *dist;
	vec_t dist_local = *dist;
	ray_t ray_local = *ray;

	if ( aabb_test_ray( &m_BBox, ray ) == 0 ) {
		return false;
	}

	ray_transform( &ray_local, m_inverse_transform );

	if ( m_model && m_model->pSelect ) {
		if ( m_model->pSelect->TestRay( &ray_local, &dist_local ) ) {
			*dist = dist_local;
		}
	}
	else{ *dist = dist_local; }

	return *dist < dist_start;
}