Ejemplo n.º 1
0
photon sphere_scatter(photon g, sphere s,double d){
    // no absorption
    g.pos = vec_add(g.pos, scale(d,g.dir));
    // normal reflection
    g.dir = vec_add(g.pos, vec_neg(s.centre));
    return g;
}
Ejemplo n.º 2
0
rgb lighting(scene s, ray r, hit_test h)
{
  rgb result;
  if (h.miss)
    return s.bg;
  vec hit_position = ray_position(r, h.dist);
  if (shadow(hit_position, s.light, s.spheres)) {
    result = rgb_modulate(h.surf, s.amb);
  }
  else {  
    double dot = vec_dot(h.surf_norm, s.light.direction);
    double d = double_max(0, dot);
    rgb diffuse_light = rgb_scale(d, s.light.color);
    rgb lsum = rgb_add(s.amb, diffuse_light);
    result = rgb_modulate(h.surf, lsum);
  }
  /**** === implement specular reflection here === ****/
 
  if (rgb_nonzero(h.shine)) {
    rgb ss;
    vec N = h.surf_norm;
    vec L = s.light.direction;
    rgb S = h.shine;
    vec R = vec_sub( vec_scale(2* vec_dot(N,L),N),L);
    vec V = vec_neg(r.direction);
    if (vec_dot(N,L)>0){
      ss = rgb_scale( pow( double_max( vec_dot(R,V),0), 6), S);
      //rgb_print(k);
    }
    else
      ss = rgb_expr(0,0,0);
    return rgb_add(result,ss);
  }
  return result;
}
Ejemplo n.º 3
0
void
ui_set_modelview_matrix(struct matrix *mv)
{
	struct matrix ry, rx, rm;
	struct vector p, o;
	struct matrix c, t, r, v;

	mat_make_rotation_around_y(&ry, ui.rotation);
	mat_make_rotation_around_x(&rx, ui.tilt);
	mat_mul_copy(&rm, &ry, &rx);

	vec_zero(&o); /* look at */

	vec_set(&p, 0.f, 0.f, -ui.distance); /* camera position */
	mat_rotate(&p, &rm);

	mat_make_look_at(&c, &o, &p);

	vec_neg(&p);
	mat_make_translation_from_vec(&t, &p);
	mat_mul_copy(&v, &c, &t);

	mat_make_rotation_around_x(&r, -M_PI/2.);

	mat_mul_copy(mv, &v, &r);
}
Ejemplo n.º 4
0
__SIMDd _SIMD_neg_pd(__SIMDd a)
{
#ifdef  USE_SSE
  return _mm_xor_pd(a, _mm_set1_pd(-0.0f));
#elif defined USE_AVX
  return _mm256_xor_pd(a, _mm_set1_pd(-0.0f));
#elif defined USE_IBM
  return vec_neg(a);
#endif
}
Ejemplo n.º 5
0
mat_t *mat_set_view(vec_t eye, vec_t u, vec_t v, vec_t w, mat_t *a){
	mat_t *b = mat_set_trans(vec_neg(eye),mat_new_zero());
	mat_set_row(0,u,a);
	mat_set_row(1,v,a);
	mat_set_row(2,w,a);
	mat_set_row(3,vec_new(0,0,0,1),a);
	mat_set_col(3,vec_new(0,0,0,1),a);
	mat_mult(a,b);
	mat_free(b);
	return a;
}
Ejemplo n.º 6
0
/* Computes the phong hilight */
static void ga_shade_phong(vec_t *color, const ga_material_t *mat,const vec_t *lcolor, const vec_t *ldir, const vec_t *dir, const vec_t *norm, float factor){
	vec_t r;
	float fact;
	float power;
	r = vec_sub(
		vec_scale(2.0f,vec_scale(vec_dot(*norm,*ldir),*norm)),
		*ldir);	
	if((fact = vec_dot(r,vec_neg(*dir))) > 0.0f){
		power = powf(fact,mat->spec_power)*mat->spec_factor;
		*color = vec_add(*color, vec_scale( power*factor,
				vec_mult(mat->spec_color,*lcolor)));
	}
}
Ejemplo n.º 7
0
double sphere_distance(photon g, sphere s){
    // (centre-x)^2=radius^2
    // x=pos+l*dir
    // solve this quadratic system for l, the path length to intersection
    
    double a = dot(g.dir,g.dir); //for clarity, will optimise away
    double b = 2*dot(g.dir,vec_add(g.pos,vec_neg(s.centre)));
    double c = dot(s.centre,s.centre) - s.radius*s.radius - 2*dot(g.pos,s.centre);
    
    double discriminant = b*b-4*a*c;
    
    printf("sphere distance dis=%e\n",discriminant);
    
    // if the ray doesn't intersect the object the system has no real solution
    if (discriminant<0) return 0;
    
    puts("hit sphere!");
    
    // if there is a solution we want the smallest positive root
    // for the moment assume we are not inside (otherwise pick the other root)
    return (-b-sqrt(discriminant))/(2*a);
}
Ejemplo n.º 8
0
// This function is adapted from geom.cpp in ODE, which
// is copyright Russell Smith.
// given two line segments A and B with endpoints a1-a2 and b1-b2, return the
// points on A and B that are closest to each other (in cp1 and cp2).
// in the case of parallel lines where there are multiple solutions, a
// solution involving the endpoint of at least one line will be returned.
// this will work correctly for zero length lines, e.g. if a1==a2 and/or
// b1==b2.
//
// the algorithm works by applying the voronoi clipping rule to the features
// of the line segments. the three features of each line segment are the two
// endpoints and the line between them. the voronoi clipping rule states that,
// for feature X on line A and feature Y on line B, the closest points PA and
// PB between X and Y are globally the closest points if PA is in V(Y) and
// PB is in V(X), where V(X) is the voronoi region of X.
void line_segment_closest_points(double a1[3], double a2[3],
				 double b1[3], double b2[3],
				 double cp1[3], double cp2[3])
{
  double la, lb, k, da1, da2, da3, da4, db1, db2, db3, db4, det;
  double a1a2[3], b1b2[3], a1b1[3], a1b2[3], a2b1[3], a2b2[3], n[3], tmp[3];

  // check vertex-vertex features

  vec_subt(a1a2, a2, a1);
  vec_subt(b1b2, b2, b1);
  vec_subt(a1b1, b1, a1);

  da1 = vec_dot(a1a2, a1b1);
  db1 = vec_dot(b1b2, a1b1);

  if ((da1 <= 0) && (db1 >= 0)) {
    vec_copy(cp1, a1);
    vec_copy(cp2, b1);
    return;
  }

  vec_subt(a1b2, b2, a1);
  da2 = vec_dot(a1a2, a1b2);
  db2 = vec_dot(b1b2,a1b2);
  if ((da2 <= 0) && (db2 <= 0)) {
    vec_copy(cp1, a1);
    vec_copy(cp2, b2);
    return;
  }

  vec_subt(a2b1, b1, a2);
  da3 = vec_dot(a1a2, a2b1);
  db3 = vec_dot(b1b2, a2b1);
  if ((da3 >= 0) && (db3 >= 0)) {
    vec_copy(cp1, a2);
    vec_copy(cp2, b1);
    return;
  }

  vec_subt(a2b2, b2, a2);
  da4 = vec_dot(a1a2, a2b2);
  db4 = vec_dot(b1b2, a2b2);
  if ((da4 >= 0) && (db4 <= 0)) {
    vec_copy(cp1, a2);
    vec_copy(cp2, b2);
    return;
  }

  // check edge-vertex features.
  // if one or both of the lines has zero length, we will never get to here,
  // so we do not have to worry about the following divisions by zero.

  la = vec_dot(a1a2, a1a2);
  if ((da1 >= 0) && (da3 <= 0.0)) {
    k = da1 / la;
    vsv_mult(tmp, k, a1a2);
    vec_subt(n, a1b1, tmp);

    if (vec_dot(b1b2, n) >= 0.0) {
      vec_plus(cp1, a1, tmp);
      vec_copy(cp2, b1);
      return;
    }
  }

  if ((da2 >= 0) && (da4 <= 0)) {
    k = da2 / la;
    vsv_mult(tmp, k, a1a2);
    vec_subt(n, a1b2, tmp);
    if (vec_dot(b1b2, n) <= 0.0) {
      vec_plus(cp1, a1, tmp);
      vec_copy(cp2, b2);
      return;
    }
  }

  lb = vec_dot(b1b2, b1b2);
  if ((db1 <= 0) && (db2 >= 0.0)) {
    k = -db1 / lb;
    vsv_mult(tmp, k, b1b2);
    vec_neg(a1b1);
    vec_subt(n, a1b1, tmp);
    if (vec_dot(a1a2, n) >= 0.0) {
      vec_copy(cp1,a1);
      vec_plus(cp2, b1, tmp);
      return;
    }
  }

  if ((db3 <= 0.0) && (db4 >= 0.0)) {
    k = -db3 / lb;
    vsv_mult(tmp, k, b1b2);
    vec_neg(a2b1);
    vec_subt(n, a2b1, tmp);
    if (vec_dot(a1a2, n) <= 0.0) {
      vec_copy(cp1,a2);
      vec_plus(cp2, b1, tmp);
      return;
    }
  }

  // it must be edge-edge

  k = vec_dot(a1a2, b1b2);
  det = la*lb - k*k;
  if (det <= 0.0) {
    // this should never happen, but just in case...
    vec_copy(cp1, a1);
    vec_copy(cp2, b1);
    return;
  }

  det = 1.0/det;
  double alpha = (lb*da1 -  k*db1) * det;
  double beta  = ( k*da1 - la*db1) * det;

  vs_mult(a1a2, alpha);
  vec_plus(cp1, a1, a1a2);

  vs_mult(b1b2, beta);
  vec_plus(cp2, b1, b1b2);
}