#include #include #include #include #include "3d.h" #include "model.h" typedef struct ppt PPT; struct ppt { int mx; PT3 loc; } ; static MODEL *m; int main(void); int main(void) { PPT oloc[6]; PPT cloc[8]; int ot[8]; int not; int ct[6*2]; int nct; int omat; int cmat; MATERIAL *mat; double cscale; PPT add_loc(PT3 at) { int inx; inx = new_location(m); get_location(m,inx)->l = (XYZ){at.x,at.y,at.z}; return((PPT){.mx=inx,.loc=at}); } void oface(int x1, int x2, int x3) { int p1; int p2; int p3; POINT *p; int tx; TRIANGLE *t; PT3 n; n = unit3(add3(oloc[x1].loc,add3(oloc[x2].loc,oloc[x3].loc))); if (dot3(cross(sub3(oloc[x3].loc,oloc[x1].loc), sub3(oloc[x2].loc,oloc[x1].loc)),n) < 0) { tx = x2; x2 = x3; x3 = tx; } p1 = new_point(m); p2 = new_point(m); p3 = new_point(m); p = get_point(m,p1); p->loc = oloc[x1].mx; p->type = PT_SURFACE; p->normal = (XYZ){.x=n.x,.y=n.y,.z=n.z}; p = get_point(m,p2); p->loc = oloc[x2].mx; p->type = PT_SURFACE; p->normal = (XYZ){.x=n.x,.y=n.y,.z=n.z}; p = get_point(m,p3); p->loc = oloc[x3].mx; p->type = PT_SURFACE; p->normal = (XYZ){.x=n.x,.y=n.y,.z=n.z}; tx = new_triangle(m); ot[not++] = tx; t = get_triangle(m,tx); t->material = omat; t->corner[0] = p1; t->corner[1] = p2; t->corner[2] = p3; } void cface(int x1, int x2, int x3, int x4) { int x[4]; int p[4]; POINT *pt; int tx; TRIANGLE *t; PT3 n; int k; double xd; double d; n = unit3(add3(add3(cloc[x1].loc,cloc[x2].loc), add3(cloc[x3].loc,cloc[x4].loc))); x[0] = x1; x[2] = x2; x[1] = x3; x[3] = x4; xd = norm3(sub3(cloc[x2].loc,cloc[x1].loc)); d = norm3(sub3(cloc[x3].loc,cloc[x1].loc)); if (d > xd) { x[1] = x2; x[2] = x3; x[3] = x4; xd = d; } d = norm3(sub3(cloc[x4].loc,cloc[x1].loc)); if (d > xd) { x[1] = x2; x[2] = x4; x[3] = x3; } if (dot3(cross(sub3(cloc[x[3]].loc,cloc[x[0]].loc), sub3(cloc[x[1]].loc,cloc[x[0]].loc)),n) < 0) { k = x[1]; x[1] = x[3]; x[3] = k; } for (k=4-1;k>=0;k--) { p[k] = new_point(m); pt = get_point(m,p[k]); pt->loc = cloc[x[k]].mx; pt->type = PT_SURFACE; pt->normal = (XYZ){.x=n.x,.y=n.y,.z=n.z}; } tx = new_triangle(m); ct[nct++] = tx; t = get_triangle(m,tx); t->material = cmat; t->corner[0] = p[0]; t->corner[1] = p[1]; t->corner[2] = p[2]; tx = new_triangle(m); ct[nct++] = tx; t = get_triangle(m,tx); t->material = cmat; t->corner[0] = p[0]; t->corner[1] = p[2]; t->corner[2] = p[3]; } void add_obj(int nt, int *txv) { OBJECT *o; o = get_object(m,new_object(m)); o->ntriangles = nt; free(o->triangles); o->triangles = malloc(nt*sizeof(*o->triangles)); bcopy(txv,o->triangles,nt*sizeof(int)); } void compute_cscale(void) { PT3 omid; PT3 cp1; PT3 cp2; PT3 cmid; omid = interp3(oloc[0].loc,.5,oloc[2].loc); cp1 = add3(add3(oloc[0].loc,oloc[2].loc),oloc[4].loc); cp2 = add3(add3(oloc[0].loc,oloc[2].loc),oloc[5].loc); cmid = interp3(cp1,.5,cp2); cscale = norm3(omid) / norm3(cmid); } m = new_model(); omat = new_material(m); cmat = new_material(m); mat = get_material(m,omat); mat->name = strdup("O"); mat->selflum = (RGB){0,0,0}; mat->reflect = (RGB){.6,1,.6}; mat->spec_exp = 10; mat->spec_mul = .5; mat = get_material(m,cmat); mat->name = strdup("C"); mat->selflum = (RGB){0,0,0}; mat->reflect = (RGB){1,.6,.6}; mat->spec_exp = 10; mat->spec_mul = .5; oloc[0] = add_loc(MAKEPT3( 1, 0, 0)); oloc[1] = add_loc(MAKEPT3(-1, 0, 0)); oloc[2] = add_loc(MAKEPT3( 0, 1, 0)); oloc[3] = add_loc(MAKEPT3( 0,-1, 0)); oloc[4] = add_loc(MAKEPT3( 0, 0, 1)); oloc[5] = add_loc(MAKEPT3( 0, 0,-1)); compute_cscale(); cloc[0] = add_loc(smul3(cscale,add3(add3(oloc[0].loc,oloc[2].loc),oloc[4].loc))); cloc[1] = add_loc(smul3(cscale,add3(add3(oloc[0].loc,oloc[2].loc),oloc[5].loc))); cloc[2] = add_loc(smul3(cscale,add3(add3(oloc[0].loc,oloc[3].loc),oloc[4].loc))); cloc[3] = add_loc(smul3(cscale,add3(add3(oloc[0].loc,oloc[3].loc),oloc[5].loc))); cloc[4] = add_loc(smul3(cscale,add3(add3(oloc[1].loc,oloc[2].loc),oloc[4].loc))); cloc[5] = add_loc(smul3(cscale,add3(add3(oloc[1].loc,oloc[2].loc),oloc[5].loc))); cloc[6] = add_loc(smul3(cscale,add3(add3(oloc[1].loc,oloc[3].loc),oloc[4].loc))); cloc[7] = add_loc(smul3(cscale,add3(add3(oloc[1].loc,oloc[3].loc),oloc[5].loc))); not = 0; oface(0,2,4); oface(0,2,5); oface(0,3,4); oface(0,3,5); oface(1,2,4); oface(1,2,5); oface(1,3,4); oface(1,3,5); nct = 0; cface(0,2,4,6); cface(1,3,5,7); cface(0,1,4,5); cface(2,3,6,7); cface(0,1,2,3); cface(4,5,6,7); add_obj(not,&ot[0]); add_obj(nct,&ct[0]); save_model(m,stdout); return(0); }