Exemplo n.º 1
0
t_mat4		m4_look_at(t_vec3 from, t_vec3 to, t_vec3 up)
{
	t_vec3	x;
	t_vec3	y;
	t_vec3	z;

	z = v3_muls(v3_norm(v3_sub(to, from)), -1);
	x = v3_norm(v3_cross(up, z));
	y = v3_cross(z, x);
	return (mat4(
				 x.x, x.y, x.z, -v3_dot(from, x),
				 y.x, y.y, y.z, -v3_dot(from, y),
				 z.x, z.y, z.z, -v3_dot(from, z),
				 0,   0,   0,    1
				 ));
}
Exemplo n.º 2
0
Arquivo: map.c Projeto: cheque/s3d
Vector3 sph_coord(Vector3 r)
{
  Real len = v3_norm(r);
  Real theta = atan2(r.y/len, r.x/len);
  Real phi = asin(r.z/len);

  return v3_make(theta, phi, len);
}  
Exemplo n.º 3
0
Arquivo: mesh.c Projeto: mattjakob/s3d
static void tri_refine(Vector3 v0, Vector3 v1, Vector3 v2, Real s, int maxrec)
{
    Real l1 = v3_norm(v3_sub(v0, v1));
    Real l2 = v3_norm(v3_sub(v1, v2));
    Real l3 = v3_norm(v3_sub(v2, v0));

    if ((MAX(l1, MAX(l2, l3))) <= s || --maxrec < 0) {
        plist = poly_insert(plist, poly3_make(v0, v1, v2));
    } else {
        Vector3 m1 = v3_scale(0.5, v3_add(v0, v1));
        Vector3 m2 = v3_scale(0.5, v3_add(v1, v2));
        Vector3 m3 = v3_scale(0.5, v3_add(v2, v0));

        tri_refine(m1, v1, m2, s, maxrec);
        tri_refine(m2, v2, m3, s, maxrec);
        tri_refine(m3, v0, m1, s, maxrec);
        tri_refine(m1, m2, m3, s, maxrec);
    }
}
Exemplo n.º 4
0
Arquivo: intersect.c Projeto: gaibo/C
hit_test intersect(ray r, object obj) {
    v3 ro = r.origin;
    v3 rd = r.direction;
    double t;
    hit_test ht_out;
    
    switch (obj.tag) {
        case SPHERE: {
            v3 sc = obj.o.s.center;
            double sr = obj.o.s.radius;
            v3 A = v3_sub(ro, sc);
            double B = v3_dot(A, rd);
            double C = v3_dot(A, A) - sr*sr;
            double D = B*B - C;
            t = -B - sqrt(D);
            if (D > 0 && t > 0) {
                v3 ray_pos = ray_position(r, t);
                ht_out.miss = HIT;
                ht_out.t = t;
                ht_out.hit_point = ray_pos;
                ht_out.surf = \
                    (*(obj.o.s.surface_color))(obj.o.s.center, ray_pos);
                ht_out.shine = obj.o.s.shine;
                ht_out.surf_norm = v3_norm(v3_sub(ray_pos, obj.o.s.center));
            } else {
                ht_out.miss = MISS;
            }
            break;
        }
        case POSTER: {
            v3 n = v3_expr(0, 0, -1);
            double d = obj.o.p.upper_left.z;
            t = -(v3_dot(ro, n) + d) / v3_dot(rd, n);
            v3 ray_pos = ray_position(r, t);
            if (t > 0 && is_on_poster(ray_pos, obj.o.p)) {
                ht_out.miss = HIT;
                ht_out.t = t;
                ht_out.hit_point = ray_pos;
                ht_out.surf = \
                    (*(obj.o.p.surface_color))(obj.o.p.upper_left, ray_pos);
                ht_out.shine = obj.o.p.shine;
                ht_out.surf_norm = n;
            } else {
                ht_out.miss = MISS;
            }
            break;
        }
        default:
            fprintf(stderr, "error in intersect: unrecognized tag\n");
            exit(1);
    }
    
    return ht_out;
}
Exemplo n.º 5
0
hit_test intersect_cylinder (ray r, cylinder c) {
  hit_test result;
  v3 rp = v3_expr(r.direction.x,0,r.direction.z);
  double mp = v3_mag(rp);
  v3 np = v3_norm(rp);
  double xbar = r.origin.x - c.center.x;
  double zbar = r.origin.z - c.center.z;
  double a = pow(np.x,2) + pow(np.z,2);
  double b = 2 * ( (xbar*np.x) + (zbar*np.z) );
  double c1 = pow(xbar,2) + pow(zbar,2) - pow(c.radius,2);
  double d = pow(b,2) - (4*a*c1);
  result.miss = MISS;
  if(d >= 0) {
    double t_front = (-b - sqrt(d)) / (2*a);
    double t_back = (-b + sqrt(d)) / (2*a);
    v3 p_front = ray_position(r, t_front/mp);
    v3 p_back = ray_position(r, t_back/mp);
    if( (t_front < t_back) &&
	(t_front > 0) &&
	(p_front.y >= c.center.y) && (on_cylinder(p_front, c))) {
      result.miss = HIT;
      result.t = (t_front/mp);
      result.hit_point = p_front;
      result.surf = c.surface_color(c.center, p_front);
      result.shine = c.shine;
      v3 c2 = v3_expr(c.center.x, p_front.y, c.center.z);
      result.surf_norm = v3_norm(v3_sub(p_front,c2));
    } else if( (t_back > 0) &&
	       (p_back.y >= c.center.y) &&
	       (on_cylinder(p_back, c)) ) {
      result.miss = HIT;
      result.t = (t_back/mp);
      result.hit_point = p_back;
      result.surf = c.surface_color(c.center, p_back);
      result.shine = c.shine;
      v3 c3 = v3_expr(c.center.x, p_back.y, c.center.z);
      result.surf_norm = v3_norm(v3_sub(c3,p_back));
    }
  }
  return result;
}
Exemplo n.º 6
0
void line_projection3d_p(v3 *a, v3 *b, v3 *p, v3 *out) {
	v3 BmA, PmA, res;
	DAFLOAT coef, normed, doted;
	v3_diff_p(b, a, &BmA);
	v3_diff_p(p, a, &PmA);
	doted = v3_dot_p(&BmA, &PmA);
	normed = v3_norm(BmA);
	normed = normed * normed;
	coef = doted / normed;
	v3_mult_p(&BmA, coef, &res);
	v3_sum_p(a, &res, out);
}
Exemplo n.º 7
0
Arquivo: set.c Projeto: mattjakob/s3d
void makeviewVi(void)
{
  Vector3 n,u,v,t;

  view->Vinv = m4_ident();
  n = view->normal;
  v = v3_sub(view->up, v3_scale(v3_dot(view->up, n), n));
  if (v3_norm(v) < ROUNDOFF)
    error("view up parallel to view normal");
  v = v3_unit(v);
  u = v3_cross(n, v);
  t = view->center;

  view->Vinv = m4_ident();
  view->Vinv.r1.x = u.x; view->Vinv.r2.x = u.y; view->Vinv.r3.x = u.z;
  view->Vinv.r1.y = v.x; view->Vinv.r2.y = v.y; view->Vinv.r3.y = v.z;
  view->Vinv.r1.z = n.x; view->Vinv.r2.z = n.y; view->Vinv.r3.z = n.z;
  view->Vinv.r1.w = t.x; view->Vinv.r2.w = t.y; view->Vinv.r3.w = t.z;
}
Exemplo n.º 8
0
void display_generate_line(int subDiv, t_v3* min, t_v3* max, float sphere_radius, uint8* vb, t_mesh_definition* def, uint16* ib, uint16 start)
{
	t_v3 direction;
	t_v3 normal;

	v3_set(&normal, 0, 0, 1);
	v3_sub(max, min, &direction);
	v3_norm(&direction, &direction);
	v3_cross(&direction, &normal, &normal);

	normal.x *= sphere_radius;
	normal.y *= sphere_radius;
	normal.z *= sphere_radius;

	float  vs[] = {
		min->x - normal.x, min->y - normal.y, min->z,
		min->x + normal.x, min->y + normal.y, min->z,
		max->x - normal.x, max->y - normal.y, max->z,
		max->x + normal.x, max->y + normal.y, max->z,
	};

	float* vsp = vs;
	int32 i;

	for (i = 0; i < 4; ++i)
	{
		t_v3* v = (t_v3*)(vb + def->vertex_offset);
		t_v3* n = (t_v3*)(vb + def->normal_offset);
		v3_set(v, *vsp, *(vsp + 1), *(vsp + 2));
		vsp += 3;
		if (def->normal_offset != -1)
			v3_set(n, 0.0f, 0.0f, 1.0f);
		vb += def->stride;
	}

	*ib++ = start + 0;
	*ib++ = start + 1;
	*ib++ = start + 3;

	*ib++ = start + 0;
	*ib++ = start + 3;
	*ib++ = start + 2;
}
Exemplo n.º 9
0
t_mat4		m4_rotation(float angle_in_rad, t_vec3 axis)
{
	t_vec3	normalized_axis;
	t_vec3	xyz;
	float 	c;
	float 	s;

	normalized_axis = v3_norm(axis);
	xyz.x = normalized_axis.x;
	xyz.y = normalized_axis.y;
	xyz.z = normalized_axis.z;
	c = cosf(angle_in_rad);
	s = sinf(angle_in_rad);
	return (mat4(
	c + xyz.x * xyz.x * (1 - c), xyz.x * xyz.y * (1 - c) - xyz.z * s, xyz.x * xyz.z * (1 - c) + xyz.y * s, 0,
	xyz.y * xyz.x * (1 - c) + xyz.z * s,  c + xyz.y * xyz.y * (1 - c), xyz.y * xyz.z * (1 - c) - xyz.x * s, 0,
	xyz.z* xyz.x * (1 - c) - xyz.y * s, xyz.z * xyz.y * (1 - c) + xyz.x * s,  c + xyz.z * xyz.z * (1 - c), 0,
	0, 0, 0, 1
	));
}
Exemplo n.º 10
0
hit_test intersect_sphere (ray r, sphere s)
{
  hit_test result = {0};
  v3 sc = s.center;
  double sr = s.radius;
  v3 a = v3_sub(r.origin, sc);
  double b = v3_dot(a, r.direction);
  double c = v3_dot(a, a) - (sr * sr);
  double d = (b * b) - c;
  double t = -b - sqrt(d);
  result.miss = MISS;
  if (d > 0 && t > 0) {
    v3 intersection = ray_position(r, t);  
    result.miss = HIT;
    result.t = t;
    result.hit_point = intersection;
    result.surf = s.surface_color(sc, intersection);
    result.shine = s.shine;
    result.surf_norm = v3_norm(v3_sub(intersection, sc));
  }
  return result;
}
Exemplo n.º 11
0
void display_generate_sphere(int subDiv, t_v3* center, float sphere_radius, uint8* vb, t_mesh_definition* def, uint16* ib, uint16 start)
{
	float pi = DISPLAY_M_PI;
	int32 i, j;
	for (i = 0; i < subDiv; ++i)
	{
		float theta = (float)i / (subDiv - 1);
		for (j = 0; j < subDiv; ++j)
		{
			float phi = (float)j / subDiv;
			float radius = sinf(theta * pi) * sphere_radius;

			t_v3*	v = (t_v3*)(vb + def->vertex_offset);
			t_v3*	n = (t_v3*)(vb + def->normal_offset);

			v->x = sinf(phi * 2.0f * pi) * radius;
			v->y = cosf(phi * 2.0f * pi) * radius;
			v->z = cosf(theta * pi) * sphere_radius;
			if (def->normal_offset != -1)
				v3_norm(v, n);
			v3_add(v, center, v);
			vb += def->stride;
		}
	}

	for (i = 0; i < subDiv - 1; ++i)
	{
		for (j = 0; j < subDiv; ++j)
		{
			int32 i0 = start + (i + 0) * subDiv + j;
			int32 i1 = start + (i + 1) * subDiv + j;
			int32 i2 = start + (i + 1) * subDiv + ((j + 1) % subDiv);
			int32 i3 = start + (i + 0) * subDiv + ((j + 1) % subDiv);

			*ib++ = i0, *ib++ = i1, *ib++ = i2;
			*ib++ = i0, *ib++ = i2, *ib++ = i3;
		}
	}
}
Exemplo n.º 12
0
Arquivo: set.c Projeto: cheque/s3d
void makeviewV(void)
{
  Vector3 n,u,v,t;

  n = view->normal;
  v = v3_sub(view->up, v3_scale(v3_dot(view->up, n), n));
  if (v3_norm(v) < ROUNDOFF)
    error("view up parallel to view normal");
  v = v3_unit(v);
  u = v3_cross(n, v);
  v = v3_cross(u, n);
  n = v3_scale(-1.0, n);
  t.x = v3_dot(view->center, u);
  t.y = v3_dot(view->center, v);
  t.z = v3_dot(view->center, n);

  view->V = m4_ident();
  view->V.r1.x =  u.x; view->V.r2.x =  v.x; view->V.r3.x =  n.x;
  view->V.r1.y =  u.y; view->V.r2.y =  v.y; view->V.r3.y =  n.y;
  view->V.r1.z =  u.z; view->V.r2.z =  v.z; view->V.r3.z =  n.z;
  view->V.r1.w = -t.x; view->V.r2.w = -t.y; view->V.r3.w = -t.z;

  makeviewVi();
}
Exemplo n.º 13
0
void
camera_setup(
	camera_t * const c,
	v3_t eye,
	v3_t lookat,
	v3_t up,
	float fov
)
{
	// compute the basis for the camera
	// negative look direction from eye to destination
	v3_t w = v3_norm(v3_sub(eye, lookat));

	// compute the side axis
	v3_t u = v3_norm(v3_cross(up, w));

	// and the "up" normal
	v3_t v = v3_norm(v3_cross(w, u));

	m44_t cam = {{
		{ u.p[0], u.p[1], u.p[2], -v3_dot(u,eye) },
		{ v.p[0], v.p[1], v.p[2], -v3_dot(v,eye) },
		{ w.p[0], w.p[1], w.p[2], -v3_dot(w,eye) },
		{ 0,      0,      0,      1 },
	}};


	fprintf(stderr, "Camera:\n");
	for(int i = 0 ; i < 4 ; i++)
	{
		for(int j = 0 ; j < 4 ; j++)
			fprintf(stderr, " %+5.3f", cam.m[i][j]);
		fprintf(stderr, "\n");
	}

	// now compute the perspective projection matrix
if(1) {
	float s = 1000.0 / tan(fov * M_PI / 180 / 2);
	c->near = 1;
	c->far = 200;
	float f1 = - c->far / (c->far - c->near);
	float f2 = - c->far * c->near / (c->far - c->near);

	m44_t pers = {{
		{ s, 0, 0, 0 },
		{ 0, s, 0, 0 },
		{ 0, 0, f2, -1 },
		{ 0, 0, f1, 0 },
	}};

	fprintf(stderr, "Perspective:\n");
	for(int i = 0 ; i < 4 ; i++)
	{
		for(int j = 0 ; j < 4 ; j++)
			fprintf(stderr, " %+5.3f", pers.m[i][j]);
		fprintf(stderr, "\n");
	}
	m44_mult(&c->r, &pers, &cam);
} else {
	// no perspective
	m44_t pers = {{
		{ 1, 0, 0, 0 },
		{ 0, 1, 0, 0 },
		{ 0, 0, 1, 0 },
		{ 0, 0, 0, 1 },
	}};
	// and apply it to the camera matrix to generate transform
	m44_mult(&c->r, &pers, &cam);
}


	fprintf(stderr, "Cam*Pers\n");
	for(int i = 0 ; i < 4 ; i++)
	{
		for(int j = 0 ; j < 4 ; j++)
			fprintf(stderr, " %+5.3f", c->r.m[i][j]);
		fprintf(stderr, "\n");
	}

}
Exemplo n.º 14
0
Arquivo: torus.c Projeto: cheque/s3d
int torus_classify(Prim *p, Vector3 q)
{
  Vector3 w = v3_m4mult(q, p->ti);
  Real d = v3_norm(w);
  return (d < 1)? PRIM_IN : ((d > 1)? PRIM_OUT : PRIM_ON);
}
Exemplo n.º 15
0
static void
find_normal(
	const stl_3d_t * const stl,
	const stl_vertex_t * const v,
	const float inset_distance,
	v3_t * const avg
)
{
	int * const face_used
		= calloc(sizeof(*face_used), stl->num_face);

	// generate all of the coplanar polygons at this vertex
	const stl_vertex_t ** const vertex_list
		= calloc(sizeof(**vertex_list), stl->num_vertex);

	for (int j = 0 ; j < v->num_face; j++)
	{
		// generate the polygon face for this vertex
		const stl_face_t * const f = v->face[j];
		if (face_used[f - stl->face])
			continue;

		//ref.origin.p[0] = 0;
		//ref.origin.p[1] = 0;
		//ref.origin.p[2] = 0;

		const int start_vertex = v->face_num[j];
		const int vertex_count = stl_trace_face(
			stl,
			f,
			vertex_list,
			face_used,
			start_vertex
		);

		// find this vertex in the vertex list
		// and compute the vector that subdivides the
		// two outbound edges
		for (int k = 0 ; k < vertex_count ; k++)
		{
			if (vertex_list[k] != v)
				continue;

			v3_t p1 = vertex_list[(k+vertex_count-1) % vertex_count]->p;
			v3_t p2 = vertex_list[k % vertex_count]->p;
			v3_t p3 = vertex_list[(k+1) % vertex_count]->p;

			refframe_t ref;
			refframe_init(
				&ref,
				p2,
				p3,
				p1
			);

			double x, y;
			refframe_inset(&ref, inset_distance, &x, &y, p1, p2, p3);

			v3_t hole = refframe_project(&ref, (v3_t){{x,y,0}});
			//hole = refframe_project(&ref, (v3_t){{10,0,0}});
			//hole.p[0] = 10*ref.x.p[0]; // + ref.origin.p[0];
			//hole.p[1] = 10*ref.x.p[1]; // + ref.origin.p[1];
			//hole.p[2] = 10*ref.x.p[2]; // + ref.origin.p[2];
			fprintf(stderr, "**** %p [%f,%f]=>%f,%f,%f\n", v, x, y,
				hole.p[0],
				hole.p[1],
				hole.p[2]
			);

			//*avg = v3_add(*avg, ref.z);
			*avg = v3_add(*avg, v3_norm(v3_sub(ref.origin, hole)));
			//*avg = v3_add(*avg, (v3_sub(hole, ref.origin)));
		}
	}

	free(face_used);
	free(vertex_list);
}