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; } }
Color point_tshade(Vector3 p, Vector3 n, Vector3 v, RContext *rc, Material *m, Prim *s) { Vector3 t, du, dv, u; u = sphere_inv_param(p); t = prim_texc(s, u.x, u.y); du = v3_unit(prim_du(s, u.x, u.y)); dv = v3_unit(prim_dv(s, u.x, u.y)); return (*m->luminance)(rc_tset(rc, v3_unit(v), p, n, t, du, dv, m)); }
Poly *prim_polys(Prim *s, Poly *p) { int i; Poly *l = plist_alloc(7, p->n); for (i = 0; i < p->n; i++) { PL(l)->v[i] = SL(l)->v[i] = prim_point(s, p->v[i].x, p->v[i].y); NL(l)->v[i] = prim_normal(s, p->v[i].x, p->v[i].y); TL(l)->v[i] = prim_texc(s, p->v[i].x, p->v[i].y); DUL(l)->v[i] = v3_unit(prim_du(s, p->v[i].x, p->v[i].y)); DVL(l)->v[i] = v3_unit(prim_dv(s, p->v[i].x, p->v[i].y)); } return l; }
void gouraud_shade(Hpoly *c, Hpoly *p, Hpoly *n, Vector3 v, RContext *rc, Material *m) { int i; for (i = 0; i < p->n; i++) c->v[i] = v4_v3conv((*m->luminance)(rc_set(rc, v3_unit(v3_sub(v, v3_v4conv(p->v[i]))), v3_v4conv(p->v[i]), v3_v4conv(n->v[i]), m))); }
int main(int argc, char **argv) { Poly *l, *p, *q = poly_alloc(3); Hpoly *t = hpoly_alloc(3); Item *i; init_sdl(); s = scene_read(); init_render(); for (o = s->objs; o != NULL; o = o->next) { for (l = prim_uv_decomp(o->u.prim, 1.); l != NULL; l = l->next) { p = poly_transform(prim_polys(o->u.prim, l), mclip); if (!is_backfacing(p, v3_unit(v3_scale(-1, poly_centr(p))))) hither_clip(0, p, z_store, plist_free); } } z = z_sort(z); for (i = z->head; i != NULL; i = i->next) { t = hpoly_polyxform(t, S(i), mdpy); q = poly_wz_hpoly(q, W(i), t); texture_wscale(W(i), T(i)); scan_spoly3(q, 2, texture_shadepaint, texture_set(td,W(i),T(i),P(i),N(i),DU(i),DV(i),rc,M(i))); } img_write(s->img, "stdout", 0); exit(0); }
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; }
int main(int argc, char **argv) { Poly *l, *p, *c = poly_alloc(3); Item *i; init_sdl(); s = scene_read(); init_render(); for (o = s->objs; o != NULL; o = o->next) { for (l = prim_uv_decomp(o->u.prim, 1.); l != NULL; l = l->next) { p = poly_transform(prim_polys(o->u.prim, l), mclip); if (!is_backfacing(p, v3_unit(v3_scale(-1, poly_centr(p))))) hither_clip(VIEW_ZMIN(s->view), p, z_store, plist_free); } } z = z_sort(z); for (i = z->head; i != NULL; i = i->next) { gouraud_shade(c, P(i), N(i), s->view->center, rc, M(i)); p = poly_homoxform(S(i),mdpy); scan_poly(p, gouraud_paint, gouraud_set(g,c,s->img)); } img_write(s->img, "stdout", 0); exit(0); }
void phong_shadepaint(Vector4 p, int n, int lv, Real lt, int rv, Real rt, Real st, void *data) { PhongData *d = data; Vector3 pv = v3_v4conv(seg_bilerp(d->pnts, n, st, lv, lt, rv, rt)); Vector3 pn = v3_unit(v3_v4conv(seg_bilerp(d->norms, n, st, lv, lt, rv, rt))); Color c = point_shade(pv, pn, d->v, d->rc, d->rc->m); img_putc(d->rc->img, p.x, p.y, col_dpymap(c)); }
Vector3 torus_normal(Prim *p, Real u, Real v) { Vector3 w; w.x = cos(u)*cos(v); w.y = sin(u)*cos(v); w.z = sin(v); return v3_unit(v3_m3mult(w, m4_transpose(p->ti))); }
Color chrome_map(void *info, Vector3 r) { TextureSrc *src = info; Vector3 t = v3_unit(r); t.x = (t.x / 2) + .5; t.y = (t.y / 2) + .5; return (*src->texfunc)(src->texdata, t); }
Vector3 cylin_normal(Prim *p, Real u, Real v) { Vector3 w; if (u < 0){ w.x = 0; w.y = 0; w.z = -1; } else if (u > 1){ w.x = 0; w.y = 0; w.z = 1; } else { w.x = cos(v); w.y = cos(v); w.z = 0; } return v3_unit(v3_m3mult(w, m4_transpose(p->ti))); }
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; }
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(); }
Color rough_surface(RContext *rc) { Vector3 d = bump_map(rc->m->tinfo, rc->t, rc->n, rc->du, rc->dv); rc->n = v3_unit(v3_add(rc->n, d)); return matte(rc); }
GLvoid sample_world() { // int timing; u_int i,j,d; // float t0,t1,t2; v3* temp; v3* disp; // v3* disp2; float dot; float dm; char* temp_s1; char* temp_s2; for (i = 0; i < PARTICLES; i++) { // printf("adding g %d,%f\n", i,ps[i].v[1]); v3_add(ps[i].v, gr); // ps[i].v->v[1] -= g; v3_mult(ps[i].v, LOSS_V); for (d = 0; d < D; d++) { v3_mult_add(ps[i].c, ps[i].v, 1 / (float) SPS); // ps[i].c[d] += ps[i].v[d] / (float) SPS; if (ps[i].c->v[d] < -B + RADIUS) { disp = v3_new(0,0,0); disp->v[d] = ps[i].c->v[d] + B; dm = 1 / (1 - (RADIUS - v3_mag(disp)) / RADIUS); v3_unit(disp); v3_mult_add(ps[i].v, disp, dm * LOSS_WALL * dt); // ps[i].c->v[d] = -B + RADIUS; // ps[i].v->v[d] *= -1 * LOSS_WALL; } if (ps[i].c->v[d] > B - RADIUS) { disp = v3_new(0,0,0); disp->v[d] = ps[i].c->v[d] - B; // dm = (RADIUS - v3_mag(disp)) / RADIUS; dm = 1 / (1 - (RADIUS - v3_mag(disp)) / RADIUS); v3_unit(disp); v3_mult_add(ps[i].v, disp, dm * LOSS_WALL * dt); // ps[i].c->v[d] = B - RADIUS; // ps[i].v->v[d] *= -1 * LOSS_WALL; } } } for (i = 0; i < PARTICLES; i++) { for (j = 0; j < PARTICLES; j++) { if (i == j) continue; if (v3_dist(ps[i].c, ps[j].c) >= RADIUS * 2) continue; /* temp_s1 = v3_str(ps[i].c); temp_s2 = v3_str(ps[j].c); printf("collision pos: %s %s\n", temp_s1, temp_s2); free(temp_s1); free(temp_s2);*/ /* temp_s1 = v3_str(ps[i].v); temp_s2 = v3_str(ps[j].v); printf("collision vel: %s %s\n", temp_s1, temp_s2); free(temp_s1); free(temp_s2); */ temp = v3_copy(ps[i].v); v3_sub(temp, ps[j].v); /* temp_s1 = v3_str(temp); printf("temp = %s\n", temp_s1); free(temp_s1); */ disp = v3_copy(ps[i].c); v3_sub(disp, ps[j].c); // disp2 = v3_copy(disp); dm = RADIUS - v3_mag(disp) / 2; /* temp_s1 = v3_str(disp); printf("disp = %s\n", temp_s1); free(temp_s1); */ v3_unit(disp); /* temp_s1 = v3_str(disp); printf("disp unit = %s\n", temp_s1); free(temp_s1); */ dot = v3_dot(temp, disp); /* printf("dot = %f\n", dot); */ v3_mult_add(ps[i].v, disp, dm*LOSS_COL*dt); v3_mult_sub(ps[j].v, disp, dm*LOSS_COL*dt); // v3_mult_add(ps[i].c, disp, dm); // v3_mult_sub(ps[j].c, disp, dm); v3_del(disp); v3_del(temp); } } }
Color flat_shade(Hpoly *p, Vector3 v, RContext *rc, Material *m) { Vector3 c = hpoly_centr(p); Vector3 n = hpoly_normal(p); return (*m->luminance)(rc_set(rc, v3_unit(v3_sub(v, c)), c, n, m)); }
Color point_shade(Vector3 p, Vector3 n, Vector3 v, RContext *rc, Material *m) { return (*m->luminance)(rc_set(rc, v3_unit(v3_sub(v, p)), p, n, m)); }
int point_coupling(Cone a, Cone b) { Vector3 d = v3_unit(v3_sub(a.o, b.o)); return dir_coupling(a, d) && dir_coupling(b, v3_scale(-1, d)); }