diff options
-rw-r--r-- | hackvr.c | 168 |
1 files changed, 130 insertions, 38 deletions
@@ -21,6 +21,7 @@ int fps=0; //TODO: use different patterns on triangles for different shading. //TODO: don't forget to remake gophervr with this. +//TODO: line and triangle intersection for finding what object was clicked on #define CAMERA_SEPARATION 4 @@ -320,6 +321,12 @@ c3_t rotate_c3_zr(c3_t p1,c3_t p2,real zr) {//rotate x and y around camera based return (c3_t){tmp.x,tmp.y,p1.z}; } +void rotate_triangle_yr(struct c3_triangle *t) {//changes input value! + t->p1=rotate_c3_yr(t->p1,camera.p,camera.yr); + t->p2=rotate_c3_yr(t->p2,camera.p,camera.yr); + t->p3=rotate_c3_yr(t->p3,camera.p,camera.yr); +} + c2_t c3_to_c2(c3_t p3) { //DO NOT DRAW STUFF IN HERE c2_t p2; // c3_t tmp1; @@ -327,8 +334,8 @@ c2_t c3_to_c2(c3_t p3) { //DO NOT DRAW STUFF IN HERE // c3_t tmp3; int colori=100; c3_t final; -// final=rotate_c3_yr(p3,camera.p,d2r(camera.yr)); - final=rotate_c3_yr(p3,(c3_t){0,0,0},d2r(camera.yr)); + final=rotate_c3_yr(p3,camera.p,d2r(camera.yr));//rotate everything around the camera's location. +// final=rotate_c3_yr(p3,(c3_t){0,0,0},d2r(camera.yr));//rotate everything around the center no matter what. // tmp2=rotate_c3_xr(tmp1,camera.p,d2r(camera.xr)); // final=rotate_c3_zr(tmp2,camera.p,d2r(camera.zr)); real delta_x=(camera.p.x - final.x); @@ -336,8 +343,8 @@ c2_t c3_to_c2(c3_t p3) { //DO NOT DRAW STUFF IN HERE real delta_z=(camera.p.z - final.z); // XSetForeground(global.dpy, global.gc, global.green.pixel); if(global.greyscale) { - if(delta_z*10 > 0) { - if(delta_z*10 < 100) { + if(delta_z*2 > 0) { + if(delta_z*2 < 100) { colori=delta_z*10; } } @@ -350,17 +357,19 @@ c2_t c3_to_c2(c3_t p3) { //DO NOT DRAW STUFF IN HERE } void draw_c3_line(c3_t p1,c3_t p2) { - if(global.drawminimap == 1) { - draw_c2_line((c2_t){(camera.p.x-2)*global.mmz,(camera.p.z+2)*global.mmz},(c2_t){(camera.p.x+2)*global.mmz,(camera.p.z-2)*global.mmz}); - draw_c2_line((c2_t){(camera.p.x+2)*global.mmz,(camera.p.z+2)*global.mmz},(c2_t){(camera.p.x-2)*global.mmz,(camera.p.z-2)*global.mmz}); - draw_c2_line((c2_t){p1.x*global.mmz,p1.z*global.mmz},(c2_t){p2.x*global.mmz,p2.z*global.mmz}); - } - if(global.drawminimap == 2) {//map rotates. - c3_t t1=rotate_c3_yr(p1,camera.p,d2r(camera.yr)); - c3_t t2=rotate_c3_yr(p2,camera.p,d2r(camera.yr)); - draw_c2_line((c2_t){t1.x*global.mmz,t1.z*global.mmz},(c2_t){t2.x*global.mmz,t2.z*global.mmz}); - } - if(global.draw3d != 0) draw_c2_line(c3_to_c2(p1),c3_to_c2(p2)); + if(!between_angles(points_to_angle((c2_t){camera.p.x,camera.p.z},(c2_t){p1.x,p1.z}),0,90) || + !between_angles(points_to_angle((c2_t){camera.p.x,camera.p.z},(c2_t){p2.x,p2.z}),0,90)) return; + if(global.drawminimap == 1) { + draw_c2_line((c2_t){(camera.p.x-2)*global.mmz,(camera.p.z+2)*global.mmz},(c2_t){(camera.p.x+2)*global.mmz,(camera.p.z-2)*global.mmz}); + draw_c2_line((c2_t){(camera.p.x+2)*global.mmz,(camera.p.z+2)*global.mmz},(c2_t){(camera.p.x-2)*global.mmz,(camera.p.z-2)*global.mmz}); + draw_c2_line((c2_t){p1.x*global.mmz,p1.z*global.mmz},(c2_t){p2.x*global.mmz,p2.z*global.mmz}); + } + if(global.drawminimap == 2) {//map rotates. + c3_t t1=rotate_c3_yr(p1,camera.p,d2r(camera.yr)); + c3_t t2=rotate_c3_yr(p2,camera.p,d2r(camera.yr)); + draw_c2_line((c2_t){t1.x*global.mmz,t1.z*global.mmz},(c2_t){t2.x*global.mmz,t2.z*global.mmz}); + } + if(global.draw3d != 0) draw_c2_line(c3_to_c2(p1),c3_to_c2(p2)); } cs_t c3_to_cs(c3_t p) { @@ -387,13 +396,61 @@ void XDrawFilledTriangle(cs_t p1,cs_t p2,cs_t p3) { XFillPolygon(global.dpy,global.backbuffer,global.backgc,p,3,Convex,CoordModeOrigin); } +real shitdist2(c3_t p1,c3_t p2) { + return sqrtl(((p1.x - p2.x) * (p1.x - p2.x)) + + ((p1.y - p2.y) * (p1.y - p2.y)) + + ((p1.z - p2.z) * (p1.z - p2.z))); +} + +real shitdist(struct c3_triangle t,c3_t p) { +// apply rotation then find distance? + struct c3_triangle t_; + t_=t; + rotate_triangle_yr(&t_); + return (shitdist2(t_.p1,p) + shitdist2(t_.p2,p) + shitdist2(t_.p3,p)) / 3.0l; +} + +//^ subdivision algorithm for display purposes only. +//black out the rest of the triangle first? +//sounds alright to me... + + +void HatchLines(c2_t p1,c2_t p2,c2_t p3,int density) { + real i=0; + for(i=1;i<density;i=i+1) {//only need 1/2, not 0/2 and 2/2, those are edges of the triangle. + draw_c2_line( + (c2_t){((i*p1.x)+((density-i)*p3.x))/density, + ((i*p1.y)+((density-i)*p3.y))/density}, + (c2_t){((i*p2.x)+((density-i)*p3.x))/density, + ((i*p2.y)+((density-i)*p3.y))/density} + ); + } +} + +void DrawHatchedTriangle(struct c3_triangle t,int d) { + c2_t p1,p2,p3; + p1=c3_to_c2(t.p1); + p2=c3_to_c2(t.p2); + p3=c3_to_c2(t.p3); + HatchLines(p1,p2,p3,d); + HatchLines(p2,p3,p1,d); + HatchLines(p1,p3,p2,d); +} + + void draw_c3_triangle(struct c3_triangle t) { - draw_c3_line(t.p1,t.p2); - draw_c3_line(t.p2,t.p3); - draw_c3_line(t.p3,t.p1); if(global.draw3d == 2) { //draw it filled in XDrawFilledTriangle(c3_to_cs(t.p1),c3_to_cs(t.p2),c3_to_cs(t.p3)); } + if(global.draw3d == 3) { //hashed + XSetForeground(global.dpy, global.backgc, global.colors[0].pixel); + //XDrawFilledTriangle(c3_to_cs(t.p1),c3_to_cs(t.p2),c3_to_cs(t.p3));//clear out this triangle. + XSetForeground(global.dpy, global.backgc, global.green.pixel); + DrawHatchedTriangle(t,10 - (shitdist(t,camera.p) / 10));//how to get density? + } + draw_c3_line(t.p1,t.p2); + draw_c3_line(t.p2,t.p3); + draw_c3_line(t.p3,t.p1); } //is basing this all on triangles best, or should I use polygons? @@ -406,16 +463,6 @@ void draw_c3_triangle(struct c3_triangle t) { // pushTriangle(); // pushTriangle(); //} -real shitdist2(c3_t p1,c3_t p2) { - return ((p1.x - p2.x) * (p1.x - p2.x)) + - ((p1.y - p2.y) * (p1.y - p2.y)) + - ((p1.z - p2.z) * (p1.z - p2.z)); -} - -real shitdist(struct c3_triangle t,c3_t p) { - return (shitdist2(t.p1,p) + shitdist2(t.p2,p) + shitdist2(t.p3,p)) / 3.0l; -} - typedef struct { struct c3_triangle *t; @@ -423,11 +470,11 @@ typedef struct { } zsort_t; int compar(zsort_t *a,zsort_t *b) { - return (a->d > b->d); + return (a->d < b->d); } void draw_screen(Display *dpy,Window w,GC gc) { - int i; + int i,j; int cn=0;//camera number. XFontStruct *font=XLoadQueryFont(global.dpy,"fixed"); XCharStruct overall; @@ -515,19 +562,22 @@ void draw_screen(Display *dpy,Window w,GC gc) { */ //floor grid -/* for(i=-21;i<21;i+=3) { + for(i=-21;i<21;i+=3) { for(j=-21;j<21;j+=3) { //draw_c3_triangle((struct c3_triangle){"id",(c3_t){i,0,j},(c3_t){i,0,j+3},(c3_t){i+3,0,j}}); draw_c3_line((c3_t){i,0,j},(c3_t){i,0,j+3}); draw_c3_line((c3_t){i,0,j},(c3_t){i+3,0,j}); } - }*/ + } - //zsort (only if I don't do wireframe) + //apply rotation? + + // load up the triangles to render... after applying rotation? for(i=0;global.triangle[i];i++) { zs[i].t=global.triangle[i]; - //zs[i].d=shitdist(*(zs[i].t),camera.p); + //rotate_triangle(zs[i].t); } + // if(global.zsort) { for(i=0;global.triangle[i];i++) { zs[i].d=shitdist(*(zs[i].t),camera.p); @@ -577,6 +627,7 @@ void draw_screen(Display *dpy,Window w,GC gc) { // XCopyPlane(global.dpy,global.backbuffer,w,gc,0,0,global.width,global.height,0,0,0x000100);//move backbuffer to window } +/* does not return the newline. */ char *read_line_hack(FILE *fp,int len) { short in; char *t; @@ -591,11 +642,40 @@ char *read_line_hack(FILE *fp,int len) { return t; } +//warning: clobbers input +//compresses multiple spaces to one. +char **line_splitter(char *line) { + char **a; + int len,i; + len=1; + for(i=0;line[i];i++) { + if(line[i] != ' ') { + len++; + for(;line[i] != ' ';i++); + } + } + + a=malloc(sizeof(char *) * len); + a[len]=0; + len=0;//reuse! + for(i=0;line[i];i++) { + if(line[i] != ' ') { + a[len]=line+i; + len++; + for(;line[i] != ' ';i++); + } + } + return a;//only the returned value needs to be free()d +} + + int load_file(FILE *fp) { struct c3_triangle *to; struct c3_triangle t; // struct c3_line l; char *command; + char *line; + char **a; int ret=0; int j,k; static int i=0;//used to store the last triangle. @@ -605,11 +685,15 @@ int load_file(FILE *fp) { for(;;) { if(feof(fp)) { - //printf("resetting EOF\n"); clearerr(fp); } //REWRITE THIS SHIT TO BE AN ACTUAL PARSER INSTEAD OF FSCANF!!!! //read a line... + //line=read_line_hack(fp,0); + //split on spaces and mangle the line. + //if(*line == '#') break; + //a=line_splitter(line); + //t.p1.x=strtod("",0);//second arg is just for a return value. set to 0 if you don't want it. if(fscanf(fp,"%ms %ms %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf",&(t.id),&command,&(t.p1.x),&(t.p1.y),&(t.p1.z),&(t.p2.x),&(t.p2.y),&(t.p2.z),&(t.p3.x),&(t.p3.y),&(t.p3.z)) > 0) { // if(fscanf(fp,"%ms %ms %f %f %f %f %f %f %f %f %f",&(t.id),&command,&(t.p1.x),&(t.p1.y),&(t.p1.z),&(t.p2.x),&(t.p2.y),&(t.p2.z),&(t.p3.x),&(t.p3.y),&(t.p3.z)) > 0) { ret=1; @@ -671,13 +755,21 @@ int load_file(FILE *fp) { } } } +/* if(!strcmp(command,"rotate")) { + for(i=0;global.triangle[i];i++) { + global.triangle[i]->p1=rotate_c3_about() + global.triangle[i]->p2= + global.triangle[i]->p3= + } + }*/ i++; global.triangles=i; global.triangle[i]=0; } else { break; } - //draw_screen(global.dpy,global.w,global.gc); + //free(a); + //free(line); } return ret; } @@ -779,7 +871,7 @@ int keypress_handler(int sym) { break; case XK_3: global.draw3d += 1; - global.draw3d %= 3; + global.draw3d %= 4; break; case XK_Escape: return -1; @@ -888,7 +980,7 @@ int main(int argc,char *argv[]) { camera.zr=0; global.mmz=1; camera.p.x=0; - camera.p.z=0; + camera.p.z=7; camera.p.y=5; for(;;) { redraw=0; |