/******************************************* * set up the default scene - DO NOT CHANGE *******************************************/ void set_up_default_scene() { // set background color background_clr.r = 0.5; background_clr.g = 0.05; background_clr.b = 0.8; // set up global ambient term global_ambient[0] = global_ambient[1] = global_ambient[2] = 0.2; // set up light 1 light1.x = -2.0; light1.y = 5.0; light1.z = 1.0; light1_intensity[0] = light1_intensity[1] = light1_intensity[2] = 1.0; // set up decay parameters decay_a = 0.5; decay_b = 0.3; decay_c = 0.0; // sphere 1 Point sphere1_ctr = {1.5, -0.2, -3.2}; float sphere1_rad = 1.23; float sphere1_ambient[] = {0.7, 0.7, 0.7}; float sphere1_diffuse[] = {0.1, 0.5, 0.8}; float sphere1_specular[] = {1.0, 1.0, 1.0}; float sphere1_shineness = 10; float sphere1_reflectance = 0.4; scene = add_sphere(scene, sphere1_ctr, sphere1_rad, sphere1_ambient, sphere1_diffuse, sphere1_specular, sphere1_shineness, sphere1_reflectance, 1); // sphere 2 Point sphere2_ctr = {-1.5, 0.0, -3.5}; float sphere2_rad = 1.5; float sphere2_ambient[] = {0.6, 0.6, 0.6}; float sphere2_diffuse[] = {1.0, 0.0, 0.25}; float sphere2_specular[] = {1.0, 1.0, 1.0}; float sphere2_shineness = 6; float sphere2_reflectance = 0.3; scene = add_sphere(scene, sphere2_ctr, sphere2_rad, sphere2_ambient, sphere2_diffuse, sphere2_specular, sphere2_shineness, sphere2_reflectance, 2); // sphere 3 Point sphere3_ctr = {-0.35, 1.75, -2.25}; float sphere3_rad = 0.5; float sphere3_ambient[] = {0.2, 0.2, 0.2}; float sphere3_diffuse[] = {0.0, 1.0, 0.25}; float sphere3_specular[] = {0.0, 1.0, 0.0}; float sphere3_shineness = 30; float sphere3_reflectance = 0.3; scene = add_sphere(scene, sphere3_ctr, sphere3_rad, sphere3_ambient, sphere3_diffuse, sphere3_specular, sphere3_shineness, sphere3_reflectance, 3); }
int main( int argc, char** argv ) { screen s; struct matrix *edges; struct matrix *transform; color c; c.red = 200; c.blue = 150; c.green = 150; edges = new_matrix(4, 4); transform = new_matrix(4, 4); clear_screen( s ); add_sphere( edges, 250, 250, 50, .01 ); add_torus( edges, 200, 200, 25, 50, .01 ); add_box( edges, 250, 250, 0, 100, 100, 100 ); draw_lines( edges, s, c ); /* if ( argc == 2 ) parse_file( argv[1], transform, edges, s ); else parse_file( "stdin", transform, edges, s ); */ display(s); printf("hi\n"); save_ppm( s, "curves.ppm" ); free_matrix( transform ); free_matrix( edges ); }
void CEditShape::Attach(CEditShape* from) { ApplyScale (); // transfer data from->ApplyScale (); Fmatrix M = from->_Transform(); M.mulA_43 (_ITransform()); for (ShapeIt it=from->shapes.begin(); it!=from->shapes.end(); it++){ switch (it->type){ case cfSphere:{ Fsphere& T = it->data.sphere; M.transform_tiny(T.P); add_sphere (T); }break; case cfBox:{ Fmatrix B = it->data.box; B.mulA_43 (M); add_box (B); }break; default: THROW; } } // common Scene->RemoveObject (from,true,true); xr_delete (from); ComputeBounds (); }
group::group(sphere *spheres_, int start_, unsigned int count_) : negative(NULL), positive(NULL), spheres(spheres_), start(start_), count(count_) { box_init(boxmin, boxmax); for(unsigned int i = 0; i < count; i++) { add_sphere(&boxmin, &boxmax, spheres[start + i].center, spheres[start + i].radius); } }
/*======== void my_main() ========== Inputs: int polygons Returns: This is the main engine of the interpreter, it should handle most of the commadns in mdl. If frames is not present in the source (and therefore num_frames is 1, then process_knobs should be called. If frames is present, the enitre op array must be applied frames time. At the end of each frame iteration save the current screen to a file named the provided basename plus a numeric string such that the files will be listed in order, then clear the screen and reset any other data structures that need it. Important note: you cannot just name your files in regular sequence, like pic0, pic1, pic2, pic3... if that is done, then pic1, pic10, pic11... will come before pic2 and so on. In order to keep things clear, add leading 0s to the numeric portion of the name. If you use sprintf, you can use "%0xd" for this purpose. It will add at most x 0s in front of a number, if needed, so if used correctly, and x = 4, you would get numbers like 0001, 0002, 0011, 0487 05/17/12 09:41:35 jdyrlandweaver ====================*/ void my_main( int polygons ) { int i, f, j, n; double step; double xval, yval, zval, knob_value; struct matrix *transform; struct matrix *tmp; struct stack *s; struct vary_node ** knobs; struct vary_node * link; screen t; color g; char q; num_frames = 1; step = 0.05; g.red = 0; g.green = 255; g.blue = 255; s = new_stack(); tmp = new_matrix(4, 1000); clear_screen( t ); first_pass(); if(num_frames > 1) { knobs = second_pass(); } int toomanyvariables; for(toomanyvariables = 0; toomanyvariables < num_frames; toomanyvariables++) { s = new_stack(); tmp = new_matrix(4, 1000); clear_screen( t ); for (j = 0; j < lastsym; j++) { if (symtab[j].type == SYM_VALUE) { link = knobs[toomanyvariables]; while (strcmp(link->name, symtab[j].name) != 0) { link = link->next; } if(link) { (&symtab[j])->s.value = link->value; } } } for (i=0;i<lastop;i++) { switch (op[i].opcode) { case SET: n = op[i].op.set.p->s.value; set_value(lookup_symbol(op[i].op.set.p->name),n); break; case SETKNOBS: n = op[i].op.setknobs.value; for (j = 0; j < lastsym; j++) { if (symtab[j].type == SYM_VALUE) { set_value(&(symtab[j]), n); } } break; case SPHERE: add_sphere( tmp,op[i].op.sphere.d[0], //cx op[i].op.sphere.d[1], //cy op[i].op.sphere.d[2], //cz op[i].op.sphere.r, step); //apply the current top origin matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case TORUS: add_torus( tmp, op[i].op.torus.d[0], //cx op[i].op.torus.d[1], //cy op[i].op.torus.d[2], //cz op[i].op.torus.r0, op[i].op.torus.r1, step); matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case BOX: add_box( tmp, op[i].op.box.d0[0], op[i].op.box.d0[1], op[i].op.box.d0[2], op[i].op.box.d1[0], op[i].op.box.d1[1], op[i].op.box.d1[2]); matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case LINE: add_edge( tmp, op[i].op.line.p0[0], op[i].op.line.p0[1], op[i].op.line.p0[1], op[i].op.line.p1[0], op[i].op.line.p1[1], op[i].op.line.p1[1]); draw_lines( tmp, t, g ); tmp->lastcol = 0; break; case MOVE: //get the factors xval = op[i].op.move.d[0]; yval = op[i].op.move.d[1]; zval = op[i].op.move.d[2]; if (op[i].op.move.p) { SYMTAB * variable = (lookup_symbol(op[i].op.move.p->name)); xval = xval * variable->s.value; yval = yval * variable->s.value; zval = zval * variable->s.value; } transform = make_translate( xval, yval, zval ); //multiply by the existing origin matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case SCALE: xval = op[i].op.scale.d[0]; yval = op[i].op.scale.d[1]; zval = op[i].op.scale.d[2]; if (op[i].op.scale.p) { SYMTAB * variable = (lookup_symbol(op[i].op.scale.p->name)); xval = xval * variable->s.value; yval = yval * variable->s.value; zval = zval * variable->s.value; } transform = make_scale( xval, yval, zval ); matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case ROTATE: xval = op[i].op.rotate.degrees * ( M_PI / 180 ); if (op[i].op.rotate.p) { SYMTAB * variable = (lookup_symbol(op[i].op.rotate.p->name)); xval = xval * variable->s.value; } //get the axis if ( op[i].op.rotate.axis == 0 ) transform = make_rotX( xval ); else if ( op[i].op.rotate.axis == 1 ) transform = make_rotY( xval ); else if ( op[i].op.rotate.axis == 2 ) transform = make_rotZ( xval ); matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case PUSH: push( s ); break; case POP: pop( s ); break; case SAVE: save_extension( t, op[i].op.save.p->name ); break; case DISPLAY: display( t ); break; } } char directoryname[256]; char index[256]; strcpy(directoryname, "animations/"); strcat(directoryname, name); sprintf(index, "%03d", toomanyvariables); strcat(directoryname, index); strcat(directoryname, ".png"); save_extension(t, directoryname); printf("Saved %s\n", directoryname); } free_stack( s ); free_matrix( tmp ); //free_matrix( transform ); }
/*======== void parse_file () ========== Inputs: char * filename struct matrix * transform, struct matrix * pm, screen s Returns: Goes through the file named filename and performs all of the actions listed in that file. The file follows the following format: Every command is a single character that takes up a line Any command that requires arguments must have those arguments in the second line. The commands are as follows: line: add a line to the edge matrix - takes 6 arguemnts (x0, y0, z0, x1, y1, z1) circle: add a circle to the edge matrix - takes 3 arguments (cx, cy, r) hermite: add a hermite curve to the edge matrix - takes 8 arguments (x0, y0, x1, y1, x2, y2, x3, y3) bezier: add a bezier curve to the edge matrix - takes 8 arguments (x0, y0, x1, y1, x2, y2, x3, y3) sphere: add a sphere to the edge matrix - takes 3 arguemnts (cx, cy, r) torus: add a torus to the edge matrix - takes 4 arguemnts (cx, cy, r1, r2) box: add a rectangular prism to the edge matrix - takes 6 arguemnts (x, y, z, width, height, depth) clear: clear the currnt edge matrix - takes 0 arguments ident: set the transform matrix to the identity matrix - scale: create a scale matrix, then multiply the transform matrix by the scale matrix - takes 3 arguments (sx, sy, sz) translate: create a translation matrix, then multiply the transform matrix by the translation matrix - takes 3 arguments (tx, ty, tz) xrotate: create an x-axis rotation matrix, then multiply the transform matrix by the rotation matrix - takes 1 argument (theta) yrotate: create an y-axis rotation matrix, then multiply the transform matrix by the rotation matrix - takes 1 argument (theta) zrotate: create an z-axis rotation matrix, then multiply the transform matrix by the rotation matrix - takes 1 argument (theta) apply: apply the current transformation matrix to the edge matrix display: draw the lines of the edge matrix to the screen display the screen save: draw the lines of the edge matrix to the screen save the screen to a file - takes 1 argument (file name) quit: end parsing See the file script for an example of the file format IMPORTANT MATH NOTE: the trig functions int math.h use radian mesure, but us normal humans use degrees, so the file will contain degrees for rotations, be sure to conver those degrees to radians (M_PI is the constant for PI) ====================*/ void parse_file ( char * filename, struct matrix * transform, struct matrix * pm, screen s) { FILE *f; char line[256]; struct matrix * tmp; double angle; color g; struct stack * STACK = new_stack(); g.red = 0; g.green = 255; g.blue = 0; clear_screen(s); if ( strcmp(filename, "stdin") == 0 ) f = stdin; else f = fopen(filename, "r"); while ( fgets(line, 255, f) != NULL ) { line[strlen(line)-1]='\0'; //printf(":%s:\n",line); double x, y, z, x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4; if ( strncmp(line, "line", strlen(line)) == 0 ) { // printf("LINE!\n"); fgets(line, 255, f); // printf("\t%s", line); //line[strlen(line)-1]='\0'; sscanf(line, "%lf %lf %lf %lf %lf %lf", &x, &y, &z, &x1, &y1, &z1); add_edge(pm, x, y, z, x1, y1, z1); // printf( "%lf %lf %lf %lf %lf %lf\n", x, y, z, x1, y1, z1); matrix_mult( STACK->data[ STACK->top], pm); draw_lines( pm, s, g); pm->lastcol = 0; } else if ( strncmp(line, "circle", strlen(line)) == 0 ) { //printf("CIRCLE\n"); fgets(line, 255, f); sscanf(line, "%lf %lf %lf", &x, &y, &z); add_circle(pm, x, y, z, 0.01); //printf( "%lf %lf %lf\n", x, y, z); matrix_mult( STACK->data[ STACK->top], pm); draw_lines( pm, s, g); pm->lastcol = 0; } else if ( strncmp(line, "bezier", strlen(line)) == 0 ) { fgets(line, 255, f); sscanf(line, "%lf %lf %lf %lf %lf %lf %lf %lf", &x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4); add_curve(pm, x1, y1, x2, y2, x3, y3, x4, y4, 0.01, BEZIER_MODE ); //printf( "%lf %lf %lf\n", x, y, z); matrix_mult( STACK->data[ STACK->top], pm); draw_lines( pm, s, g); pm->lastcol = 0; } else if ( strncmp(line, "hermite", strlen(line)) == 0 ) { //printf("HERMITE\n"); fgets(line, 255, f); sscanf(line, "%lf %lf %lf %lf %lf %lf %lf %lf", &x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4); add_curve(pm, x1, y1, x2, y2, x3, y3, x4, y4, 0.01, HERMITE_MODE ); //printf( "%lf %lf %lf\n", x, y, z); matrix_mult( STACK->data[ STACK->top], pm); draw_lines( pm, s, g); pm->lastcol = 0; } else if ( strncmp(line, "box", strlen(line)) == 0 ) { fgets(line, 255, f); sscanf(line, "%lf %lf %lf %lf %lf %lf", &x, &y, &z, &x1, &y1, &z1); add_box(pm, x, y, z, x1, y1, z1); matrix_mult( STACK->data[ STACK->top ], pm); draw_polygons( pm, s, g ); pm->lastcol = 0; } else if (strncmp(line, "sphere", strlen(line)) == 0 ) { fgets(line, 255, f); sscanf(line, "%lf %lf %lf", &x, &y, &z); add_sphere(pm, x, y, z, 10); matrix_mult( STACK->data[ STACK->top ], pm); draw_polygons( pm, s, g ); pm->lastcol = 0; } else if (strncmp(line, "torus", strlen(line)) == 0 ) { fgets(line, 255, f); sscanf(line, "%lf %lf %lf %lf", &x, &y, &z, &z1); add_torus(pm, x, y, z, z1, 10); matrix_mult( STACK->data[ STACK->top ], pm); draw_polygons( pm, s, g ); pm->lastcol = 0; } else if ( strncmp(line, "scale", strlen(line)) == 0 ) { fgets(line, 255, f); //line[strlen(line)-1]='\0'; sscanf(line, "%lf %lf %lf", &x, &y, &z); tmp = make_scale(x, y, z); //matrix_mult(tmp, transform); //print_matrix(transform); //matrix_mult( tmp, STACK->data[ STACK->top ] ); matrix_mult( STACK->data[ STACK->top ], tmp ); copy_matrix( tmp, STACK->data[ STACK->top ] ); } else if ( strncmp(line, "translate", strlen(line)) == 0 ) { //printf("TRANSLATE\n"); fgets(line, 255, f); sscanf(line, "%lf %lf %lf", &x, &y, &z); tmp = make_translate(x, y, z); //matrix_mult(tmp, transform); //matrix_mult( tmp, STACK->data[ STACK->top ] ); matrix_mult( STACK->data[ STACK->top ], tmp ); copy_matrix( tmp, STACK->data[ STACK->top ] ); } else if ( strncmp(line, "xrotate", strlen(line)) == 0 ) { //printf("ROTATE!\n"); fgets(line, 255, f); sscanf(line, "%lf", &angle); angle = angle * (M_PI / 180); tmp = make_rotX( angle); //matrix_mult(tmp, transform); //matrix_mult( tmp, STACK->data[ STACK->top ] ); matrix_mult( STACK->data[ STACK->top ], tmp ); copy_matrix( tmp, STACK->data[ STACK->top ] ); } else if ( strncmp(line, "yrotate", strlen(line)) == 0 ) { //printf("ROTATE!\n"); fgets(line, 255, f); sscanf(line, "%lf", &angle); angle = angle * (M_PI / 180); tmp = make_rotY( angle); //matrix_mult(tmp, transform); //matrix_mult( tmp, STACK->data[ STACK->top ] ); matrix_mult( STACK->data[ STACK->top ], tmp ); copy_matrix( tmp, STACK->data[ STACK->top ] ); } else if ( strncmp(line, "zrotate", strlen(line)) == 0 ) { //printf("ROTATE!\n"); fgets(line, 255, f); sscanf(line, "%lf", &angle); angle = angle * (M_PI / 180); tmp = make_rotZ( angle); //matrix_mult(tmp, transform); //matrix_mult( tmp, STACK->data[ STACK->top ] ); matrix_mult( STACK->data[ STACK->top ], tmp ); copy_matrix( tmp, STACK->data[ STACK->top ] ); } else if ( strncmp(line, "ident", strlen(line)) == 0 ) { ident(transform); } else if ( strncmp(line, "apply", strlen(line)) == 0 ) { //printf("APPLY!\n"); //print_matrix( transform ); // print_matrix(pm); matrix_mult(transform, pm); } else if ( strncmp(line, "print", strlen(line)) == 0) { print_matrix( STACK->data[ STACK->top ] ); } else if ( strncmp(line, "display", strlen(line)) == 0 ) { display(s); } else if ( strncmp(line, "save", strlen(line)) == 0 ) { fgets(line, 255, f); // line[strlen(line)-1] = '\0'; //clear_screen(s); //draw_polygons(pm, s, g); save_extension(s, line); } else if ( strncmp(line, "clear", strlen(line)) == 0 ) { pm->lastcol = 0; } else if ( strncmp(line, "quit", strlen(line)) == 0 ) { return; } else if ( strncmp(line, "push", strlen(line)) == 0 ) { push( STACK ); //seg fault printf("Pushed\n"); } else if ( strncmp(line, "pop", strlen(line)) == 0 ) { pop( STACK ); printf("Popped\n"); } else if ( line[0] != '#' ) { printf("Invalid command\n"); } } free_matrix(tmp); fclose(f); //printf("END PARSE\n"); }
void generate( int polygons ) { double knob_value; vary_node *knobs; vary_node vn; char frame_name[128]; if (first_pass()) { knobs = second_pass(); } else { num_frames = 1; } // Default values char color_type = PNG_RGB, shading = GOROUD; int width = 1000, height = 1000, segments = 20; screen s = make_screen(width, height); vertex_list vlist = new_vlist(100); face_list flist = new_flist(100); edge_list elist = new_elist(100); stack coord_systems = new_stack(5); vector center = new_vector(0, 0, 0); vector eye = new_vector(0, 0, 200); double distance = 200; vertex text0, text1; text0.x = -100; text0.y = 0; text0.z = 0; text1.x = 100; text1.y = 0; text1.z = 0; text0.nx = text1.x - text0.x; text0.ny = text1.y - text0.y; text0.nz = text1.z - text0.z; text1.nx = text0.nx * text0.nx + text0.ny * text0.ny + text0.nz * text0.nz; text0.color = rgb(255, 255, 255); text0.shine = 3; text1.color = rgb(255, 0, 255); text1.shine = 3; uint32_t amb_color = rgb(255, 255, 255), light_color = rgb(0, 255, 255), wire_color = rgb(255, 255, 255); vector light_source = new_vector(0, 100, 200); double amb_ref_constant = 0.1, diff_ref_constant = 1, spec_ref_constant = 1; int frame, i, j; double temp; for (frame = 0; frame < num_frames; frame++) { if (num_frames > 1) { for (vn = knobs[frame]; vn != NULL; vn = vn->next) { set_value(lookup_symbol(vn->name), vn->value); } } for (i = 0; i < lastop; i++) { switch (op[i].opcode) { case TEXTURE: text0.x = op[lastop].op.texture.d0[0]; text0.y = op[lastop].op.texture.d0[1]; text0.z = op[lastop].op.texture.d0[2]; text1.x = op[lastop].op.texture.d1[0]; text1.y = op[lastop].op.texture.d1[1]; text1.z = op[lastop].op.texture.d1[2]; text0.nx = text1.x - text0.x; text0.ny = text1.y - text0.y; text0.nz = text1.z - text0.z; text1.nx = text0.nx * text0.nx + text0.ny * text0.ny + text0.nz * text0.nz; text0.color = rgb( (uint8_t) max(0, min(0xFF, op[lastop].op.texture.d2[0])), (uint8_t) max(0, min(0xFF, op[lastop].op.texture.d2[1])), (uint8_t) max(0, min(0xFF, op[lastop].op.texture.d2[2])) ); text0.shine = op[lastop].op.texture.d2[3]; text1.color = rgb( (uint8_t) max(0, min(0xFF, op[lastop].op.texture.d3[0])), (uint8_t) max(0, min(0xFF, op[lastop].op.texture.d3[1])), (uint8_t) max(0, min(0xFF, op[lastop].op.texture.d3[2])) ); text1.shine = op[lastop].op.texture.d3[3]; break; case CAMERA: eye.x = op[lastop].op.camera.eye[0]; eye.y = op[lastop].op.camera.eye[1]; eye.z = op[lastop].op.camera.eye[2]; center.x = eye.x + op[lastop].op.camera.aim[0]; center.y = eye.y + op[lastop].op.camera.aim[1]; center.z = eye.z + op[lastop].op.camera.aim[2]; break; case FOCAL: distance = op[lastop].op.focal.value; break; case AMBIENT: amb_color = rgb( (uint8_t) max(0, min(0xFF, op[lastop].op.ambient.c[0])), (uint8_t) max(0, min(0xFF, op[lastop].op.ambient.c[1])), (uint8_t) max(0, min(0xFF, op[lastop].op.ambient.c[2])) ); break; case LIGHT: light_color = rgb( (uint8_t) max(0, min(0xFF, op[lastop].op.light.c[0])), (uint8_t) max(0, min(0xFF, op[lastop].op.light.c[1])), (uint8_t) max(0, min(0xFF, op[lastop].op.light.c[2])) ); light_source = new_vector( op[lastop].op.light.l[0], op[lastop].op.light.l[1], op[lastop].op.light.l[2] ); break; case SHADING: if (strcmp(op[i].op.shading.p->name, "GOROUD") == 0) { shading = GOROUD; } else { shading = WIRE; } break; case SPHERE: add_sphere( vlist, elist, flist, op[i].op.sphere.d[0], op[i].op.sphere.d[1], op[i].op.sphere.d[2], op[i].op.sphere.r, segments, text0, text1 ); transform(vlist, peek(coord_systems)); if (shading == GOROUD) { draw_faces( s, vlist, flist, center, eye, distance, amb_color, light_color, light_source, amb_ref_constant, diff_ref_constant, spec_ref_constant ); } else { draw_edges( s, vlist, elist, center, eye, distance, wire_color ); } clear_vlist(vlist); clear_elist(elist); clear_flist(flist); break; case BOX: add_box( vlist, elist, flist, op[i].op.box.d0[0], op[i].op.box.d0[1], op[i].op.box.d0[2], op[i].op.box.d1[0], op[i].op.box.d1[1], op[i].op.box.d1[2], text0, text1 ); transform(vlist, peek(coord_systems)); if (shading == GOROUD) { draw_faces( s, vlist, flist, center, eye, distance, amb_color, light_color, light_source, amb_ref_constant, diff_ref_constant, spec_ref_constant ); } else { draw_edges( s, vlist, elist, center, eye, distance, wire_color ); } clear_vlist(vlist); clear_elist(elist); clear_flist(flist); break; case LINE: add_line( vlist, elist, op[i].op.line.p0[0], op[i].op.line.p0[1], op[i].op.line.p0[2], op[i].op.line.p1[0], op[i].op.line.p1[1], op[i].op.line.p1[2], text0, text1 ); transform(vlist, peek(coord_systems)); draw_edges(s, vlist, elist, center, eye, distance, wire_color); clear_vlist(vlist); clear_elist(elist); break; case MOVE: if (op[i].op.move.p == NULL){ knob_value = 1; } else { knob_value = op[i].op.move.p->s.value; } translate( op[i].op.move.d[0] * knob_value, op[i].op.move.d[1] * knob_value, op[i].op.move.d[2] * knob_value, peek(coord_systems) ); break; case SCALE: if (op[i].op.scale.p == NULL){ knob_value = 1; } else { knob_value = op[i].op.scale.p->s.value; } scale( op[i].op.scale.d[0] * knob_value, op[i].op.scale.d[1] * knob_value, op[i].op.scale.d[2] * knob_value, peek(coord_systems) ); break; case ROTATE: if (op[i].op.rotate.p == NULL){ knob_value = 1; } else { knob_value = op[i].op.rotate.p->s.value; } temp = op[i].op.rotate.axis; if (temp == 0) { rotate_x( op[i].op.rotate.degrees * knob_value, peek(coord_systems) ); } else if (temp == 1) { rotate_y( op[i].op.rotate.degrees * knob_value, peek(coord_systems) ); } else { rotate_z( op[i].op.rotate.degrees * knob_value, peek(coord_systems) ); } break; case SET: set_value( lookup_symbol(op[i].op.set.p->name), op[i].op.set.val ); break; case SETKNOBS: for (j = 0; j < lastsym; j++) { set_value(&symtab[j], op[j].op.setknobs.value); } break; case PUSH: push(coord_systems); break; case POP: pop(coord_systems); break; case SAVE: make_png(op[i].op.save.p->name, s, color_type); break; case DISPLAY: display_png(s, color_type); break; } } if (num_frames > 1){ sprintf(frame_name, "anim/%s%03d.png", name, frame); make_png(frame_name, s, color_type); clear_screen(s); clear_stack(coord_systems); } } free_screen(s); free_vlist(vlist); free_flist(flist); free_elist(elist); free(coord_systems); }
void my_main( int polygons ) { int i; double step; double xval, yval, zval; struct matrix *transform; struct matrix *tmp; struct stack *s; screen t; color g; s = new_stack(); tmp = new_matrix(4, 1000); clear_screen( t ); for (i=0;i<lastop;i++) { switch (op[i].opcode) { //simple cases //i realized that you already defined these constants in another //file after looking at this for 30 min -_- case POP: pop(s); break; case PUSH: push(s); break; //move,scale,rotate case MOVE: transform = make_translate(op[i].op.move.d[0],op[i].op.move.d[1], op[i].op.move.d[2]); matrix_mult(transform,s->data[s->top]); free_matrix(transform); break; case ROTATE: //there are 3 rotations possible, SO SWITCH-CEPTION! switch((int)op[i].op.rotate.axis) { case ROT_X: transform = make_rotX(op[i].op.rotate.degrees); break; case ROT_Y: transform = make_rotY(op[i].op.rotate.degrees); break; case ROT_Z: transform = make_rotZ(op[i].op.rotate.degrees); break; } matrix_mult(transform,s->data[s->top]); free_matrix(transform); break; case SCALE: transform = make_scale(op[i].op.scale.d[0],op[i].op.scale.d[1], op[i].op.scale.d[2]); matrix_mult(transform,s->data[s->top]); free_matrix(transform); break; //box,sphere,torus case BOX: add_box(tmp,op[i].op.box.d0[0],op[i].op.box.d0[1],op[i].op.box.d0[2], op[i].op.box.d1[0],op[i].op.box.d1[1],op[i].op.box.d1[2]); matrix_mult(s->data[s->top],tmp); draw_polygons(tmp,t,g); free_matrix(tmp); //reset tmp=new_matrix(4,1000); break; case SPHERE: add_sphere(tmp,op[i].op.sphere.d[0],op[i].op.sphere.d[1], op[i].op.sphere.d[2],op[i].op.sphere.r,0.01); matrix_mult(s->data[s->top],tmp); draw_polygons(tmp,t,g); free_matrix(tmp); //reset tmp=new_matrix(4,1000); break; case TORUS: add_torus(tmp,op[i].op.torus.d[0],op[i].op.torus.d[1],op[i].op.torus.d[2], op[i].op.torus.r0,op[i].op.torus.r1,0.01); matrix_mult(s->data[s->top],tmp); draw_polygons(tmp,t,g); free_matrix(tmp); //reset tmp=new_matrix(4,1000); break; //line case LINE: add_edge(tmp,op[i].op.line.p0[0],op[i].op.line.p0[1],op[i].op.line.p0[2], op[i].op.line.p1[0],op[i].op.line.p1[1],op[i].op.line.p1[2]); matrix_mult(s->data[s->top],tmp); draw_lines(tmp,t,g); free_matrix(tmp); tmp=new_matrix(4,1000);//RESET break; //EVERYTIN else case SAVE: save_extension(t,op[i].op.save.p->name); break; case DISPLAY: display(t); break; default: break; } } }
/*======== void my_main() ========== Inputs: int polygons Returns: This is the main engine of the interpreter, it should handle most of the commadns in mdl. If frames is not present in the source (and therefore num_frames is 1, then process_knobs should be called. If frames is present, the enitre op array must be applied frames time. At the end of each frame iteration save the current screen to a file named the provided basename plus a numeric string such that the files will be listed in order, then clear the screen and reset any other data structures that need it. Important note: you cannot just name your files in regular sequence, like pic0, pic1, pic2, pic3... if that is done, then pic1, pic10, pic11... will come before pic2 and so on. In order to keep things clear, add leading 0s to the numeric portion of the name. If you use sprintf, you can use "%0xd" for this purpose. It will add at most x 0s in front of a number, if needed, so if used correctly, and x = 4, you would get numbers like 0001, 0002, 0011, 0487 05/17/12 09:41:35 jdyrlandweaver ====================*/ void my_main( int polygons ) { int i, f, j, k; double step; double xval, yval, zval, knob_value; struct matrix *transform; struct matrix *tmp; struct stack *s; screen t; color g; char q; char dir[256]; char p[256]; num_frames = 1; step = 0.05 ; g.red = 0; g.green = 255; g.blue = 255; s = new_stack(); tmp = new_matrix(4, 1000); clear_screen( t ); first_pass(); if (num_frames == -1) return; int variable; struct vary_node **table; table = second_pass(); struct vary_node* inside; for (variable = 0; variable < num_frames; variable++){ clear_screen(t); free_stack(s); s = new_stack(); inside = table[variable]; while(inside){ set_value(lookup_symbol(inside->name),inside->value); inside = inside -> next; } for (i=0;i<lastop;i++) { switch (op[i].opcode) { case SPHERE: add_sphere( tmp,op[i].op.sphere.d[0], //cx op[i].op.sphere.d[1], //cy op[i].op.sphere.d[2], //cz op[i].op.sphere.r, step); //apply the current top origin matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case TORUS: add_torus( tmp, op[i].op.torus.d[0], //cx op[i].op.torus.d[1], //cy op[i].op.torus.d[2], //cz op[i].op.torus.r0, op[i].op.torus.r1, step); matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case BOX: add_box( tmp, op[i].op.box.d0[0], op[i].op.box.d0[1], op[i].op.box.d0[2], op[i].op.box.d1[0], op[i].op.box.d1[1], op[i].op.box.d1[2]); matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case LINE: add_edge( tmp, op[i].op.line.p0[0], op[i].op.line.p0[1], op[i].op.line.p0[1], op[i].op.line.p1[0], op[i].op.line.p1[1], op[i].op.line.p1[1]); draw_lines( tmp, t, g ); tmp->lastcol = 0; break; case MOVE: //get the factors if( op[ i ].op.move.p ) knob_value = lookup_symbol( op[ i ].op.move.p->name )->s.value; else knob_value = 1; xval = op[i].op.move.d[0] * knob_value; yval = op[i].op.move.d[1] * knob_value; zval = op[i].op.move.d[2] * knob_value; transform = make_translate( xval, yval, zval ); //multiply by the existing origin matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case SCALE: if( op[ i ].op.scale.p ) knob_value = lookup_symbol( op[ i ].op.scale.p->name )->s.value; else knob_value = 1; xval = op[i].op.scale.d[0] * knob_value; yval = op[i].op.scale.d[1] * knob_value; zval = op[i].op.scale.d[2] * knob_value; transform = make_scale( xval, yval, zval ); matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case ROTATE: if( op[ i ].op.rotate.p ) knob_value = lookup_symbol( op[ i ].op.rotate.p->name )->s.value; else knob_value = 1; xval = op[i].op.rotate.degrees * ( M_PI / 180 ); //get the axis if ( op[i].op.rotate.axis == 0 ) transform = make_rotX( xval * knob_value ); else if ( op[i].op.rotate.axis == 1 ) transform = make_rotY( xval * knob_value ); else if ( op[i].op.rotate.axis == 2 ) transform = make_rotZ( xval * knob_value ); matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case PUSH: push( s ); break; case POP: pop( s ); break; case SAVE: save_extension( t, op[i].op.save.p->name ); break; case DISPLAY: display( t ); break; case SET: set_value( lookup_symbol( op[ i ].op.set.p->name ), op[ i ].op.set.val ); break; case SETKNOBS: for( k = 0; k < lastsym; k++ ) if( symtab[ k ].type == SYM_VALUE ) symtab[ k ].s.value = op[ i ].op.setknobs.value; break; default: break; } } strcpy(dir,name); sprintf(p,"%03d", variable); strcat(dir,p); strcat(dir, ".png"); save_extension(t, dir); printf("%s \n", dir); } free(table); free_stack( s ); free_matrix( tmp ); //free_matrix( transform ); }
/*======== void my_main() ========== Inputs: int polygons Returns: This is the main engine of the interpreter, it should handle most of the commadns in mdl. If frames is not present in the source (and therefore num_frames is 1, then process_knobs should be called. If frames is present, the enitre op array must be applied frames time. At the end of each frame iteration save the current screen to a file named the provided basename plus a numeric string such that the files will be listed in order, then clear the screen and reset any other data structures that need it. Important note: you cannot just name your files in regular sequence, like pic0, pic1, pic2, pic3... if that is done, then pic1, pic10, pic11... will come before pic2 and so on. In order to keep things clear, add leading 0s to the numeric portion of the name. If you use sprintf, you can use "%0xd" for this purpose. It will add at most x 0s in front of a number, if needed, so if used correctly, and x = 4, you would get numbers like 0001, 0002, 0011, 0487 05/17/12 09:41:35 jdyrlandweaver ====================*/ void my_main( int polygons ) { int i, j; zbuf = (double **)malloc(500 * sizeof(double*)); for(i = 0; i < 500; i++){ zbuf[i] = (double*)malloc(500 * sizeof(double)); for (j = 0; j < 500; j++){ zbuf[i][j] = -DBL_MAX; } } lclist = (lcons*)malloc(sizeof(lcons)); lclist->next = NULL; i = 0; j = 0; int f; double step; double xval, yval, zval, knob_value; struct matrix *transform; struct matrix *tmp; struct stack *s; screen t; color g; char q; obj = 0; cbmt[0] = ib; cbmt[1] = im; cbmt[2] = it; int jkl = 0; for ( i=0; i < lastsym; i++ ) { if ( symtab[i].type == SYM_LIGHT ) { jkl++; } } ptl = jkl; ptlights = (double**)malloc(j * sizeof(double*)); for (i = 0; i < jkl; i++){ ptlights[i] = (double*)malloc(6 * sizeof(double)); } jkl = 0; for ( i=0; i < lastsym; i++ ) { if ( symtab[i].type == SYM_LIGHT ) { ptlights[jkl][0] = symtab[i].s.l->l[0]; ptlights[jkl][1] = symtab[i].s.l->l[1]; ptlights[jkl][2] = symtab[i].s.l->l[2]; ptlights[jkl][3] = symtab[i].s.l->c[0]; ptlights[jkl][4] = symtab[i].s.l->c[1]; ptlights[jkl][5] = symtab[i].s.l->c[2]; jkl++; } } for(i = 0;i < ptl; i++){ printf("%lf,%lf,%lf light at (%lf,%lf,%lf)\n",ptlights[i][3],ptlights[i][4],ptlights[i][5],ptlights[i][0],ptlights[i][1],ptlights[i][2]); } clear_screen( t ); num_frames = 1; step = 0.02; g.red = 40; g.green = 50; g.blue = 60; s = new_stack(); tmp = new_matrix(4, 1000); first_pass(); srand(time(NULL)); if (num_frames < 0){ printf("ERROR- can't vary knobs when there's only 1 frame.\n"); } if (num_frames >= 1){ struct vary_node ** klist = second_pass(); for (f = 0; f < num_frames; f++){ for ( i = 0; i < 500; i++){ for (j = 0; j < 500; j++){ zbuf[i][j] = -DBL_MAX; } } for (i=0;i<lastop;i++) { setc = 0; struct vary_node* v = klist[f]; SYMTAB * vvv; while ( v != NULL){ //printf("set %s %lf \n",v->name, v->value ); vvv = lookup_symbol(v->name); if (vvv != NULL){ set_value(vvv, v->value); } else{ add_symbol(v->name,SYM_VALUE,(void *)&(v->value)); } v = v->next; } //print_knobs(); switch (op[i].opcode) { case SETKNOBS: xval = 0; double abcdef = op[i].op.setknobs.value; //printf("Setting knobs to %lf.\n",abcdef); for ( i=0; i < lastsym; i++ ) { if ( symtab[i].type == SYM_VALUE ) { set_value(&(symtab[i]), abcdef); } } break; case AMBIENT: g.red = op[i].op.ambient.c[0]; g.green = op[i].op.ambient.c[1]; g.blue = op[i].op.ambient.c[2]; break; case SPHERE: add_sphere( tmp,op[i].op.sphere.d[0], //cx op[i].op.sphere.d[1], //cy op[i].op.sphere.d[2], //cz op[i].op.sphere.r, step); //apply the current top origin matrix_mult( s->data[ s->top ], tmp ); ///////////////////////////lcons if (f == 0){ lcons * v = lclist; while (v->next != NULL){ v = v->next; } v->next = (lcons*)malloc(sizeof(lcons)); v->next->next = NULL; v->next->kar = .685* rand() / (double)RAND_MAX; v->next->kag = .685* rand() / (double)RAND_MAX; v->next->kab = .685* rand() / (double)RAND_MAX; v->next->kdr = .685* rand() / (double)RAND_MAX; v->next->kdg = .685* rand() / (double)RAND_MAX; v->next->kdb = .685* rand() / (double)RAND_MAX; v->next->ksr = .685* rand() / (double)RAND_MAX; v->next->ksg = .685* rand() / (double)RAND_MAX; v->next->ksb = .685* rand() / (double)RAND_MAX; } draw_polygons( tmp, t, g ); tmp->lastcol = 0; obj++; break; case TORUS: add_torus( tmp, op[i].op.torus.d[0], //cx op[i].op.torus.d[1], //cy op[i].op.torus.d[2], //cz op[i].op.torus.r0, op[i].op.torus.r1, step); matrix_mult( s->data[ s->top ], tmp ); ///////////////////////////lcons if (f == 0){ lcons * v = lclist; while (v->next != NULL){ v = v->next; } v->next = (lcons*)malloc(sizeof(lcons)); v->next->next = NULL; v->next->kar = .685* rand() / (double)RAND_MAX; v->next->kag = .685* rand() / (double)RAND_MAX; v->next->kab = .685* rand() / (double)RAND_MAX; v->next->kdr = .685* rand() / (double)RAND_MAX; v->next->kdg = .685* rand() / (double)RAND_MAX; v->next->kdb = .685* rand() / (double)RAND_MAX; v->next->ksr = .685* rand() / (double)RAND_MAX; v->next->ksg = .685* rand() / (double)RAND_MAX; v->next->ksb = .685* rand() / (double)RAND_MAX; } draw_polygons( tmp, t, g ); tmp->lastcol = 0; obj++; break; case BOX: add_box( tmp, op[i].op.box.d0[0], op[i].op.box.d0[1], op[i].op.box.d0[2], op[i].op.box.d1[0], op[i].op.box.d1[1], op[i].op.box.d1[2]); matrix_mult( s->data[ s->top ], tmp ); ///////////////////////////lcons if (f == 0){ lcons * v = lclist; while (v->next != NULL){ v = v->next; } v->next = (lcons*)malloc(sizeof(lcons)); v->next->next = NULL; v->next->kar = .685* rand() / (double)RAND_MAX; v->next->kag = .685* rand() / (double)RAND_MAX; v->next->kab = .685* rand() / (double)RAND_MAX; v->next->kdr = .685* rand() / (double)RAND_MAX; v->next->kdg = .685* rand() / (double)RAND_MAX; v->next->kdb = .685* rand() / (double)RAND_MAX; v->next->ksr = .685* rand() / (double)RAND_MAX; v->next->ksg = .685* rand() / (double)RAND_MAX; v->next->ksb = .685* rand() / (double)RAND_MAX; } draw_polygons( tmp, t, g ); tmp->lastcol = 0; obj++; break; case LINE: add_edge( tmp, op[i].op.line.p0[0], op[i].op.line.p0[1], op[i].op.line.p0[2], op[i].op.line.p1[0], op[i].op.line.p1[1], op[i].op.line.p1[2]); matrix_mult( s->data[ s->top ], tmp ); ///////////////////////////lcons if (f == 0){ lcons * v = lclist; while (v->next != NULL){ v = v->next; } v->next = (lcons*)malloc(sizeof(lcons)); v->next->next = NULL; v->next->kar = .685* rand() / (double)RAND_MAX; v->next->kag = .685* rand() / (double)RAND_MAX; v->next->kab = .685* rand() / (double)RAND_MAX; v->next->kdr = .685* rand() / (double)RAND_MAX; v->next->kdg = .685* rand() / (double)RAND_MAX; v->next->kdb = .685* rand() / (double)RAND_MAX; v->next->ksr = .685* rand() / (double)RAND_MAX; v->next->ksg = .685* rand() / (double)RAND_MAX; v->next->ksb = .685* rand() / (double)RAND_MAX; } draw_lines( tmp, t, g ); tmp->lastcol = 0; obj++; break; case MOVE: //get the factors xval = op[i].op.move.d[0]; yval = op[i].op.move.d[1]; zval = op[i].op.move.d[2]; //printf("MOVE %lf %lf %lf\n",xval,yval,zval); if (op[i].op.move.p != NULL){ SYMTAB* thing = (lookup_symbol(op[i].op.move.p->name)); xval *= thing->s.value; yval *= thing->s.value; zval *= thing->s.value; //printf("new MOVE %lf %lf %lf\n",xval,yval,zval); } transform = make_translate( xval, yval, zval ); //multiply by the existing origin matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case SCALE: xval = op[i].op.scale.d[0]; yval = op[i].op.scale.d[1]; zval = op[i].op.scale.d[2]; //printf("scalE %lf %lf %lf\n",xval,yval,zval); if (op[i].op.scale.p != NULL){ SYMTAB* thing = (lookup_symbol(op[i].op.scale.p->name)); xval *= thing->s.value; yval *= thing->s.value; zval *= thing->s.value; //printf("new scale %lf %lf %lf\n",xval,yval,zval); } transform = make_scale( xval, yval, zval ); matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case ROTATE: xval = op[i].op.rotate.degrees * ( M_PI / 180 ); //printf("rotate %lf\n",xval); if (op[i].op.rotate.p != NULL){ xval *= (lookup_symbol(op[i].op.rotate.p->name))->s.value; //printf("new rotate%lf\n",xval); } //get the axis if ( op[i].op.rotate.axis == 0 ) transform = make_rotX( xval ); else if ( op[i].op.rotate.axis == 1 ) transform = make_rotY( xval ); else if ( op[i].op.rotate.axis == 2 ) transform = make_rotZ( xval ); matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case PUSH: push( s ); break; case POP: pop( s ); break; case SAVE: save_extension( t, op[i].op.save.p->name ); break; case DISPLAY: display( t ); break; } } if (num_frames > 1){ char nopq[256]; char rst[256]; strcpy(nopq,"animations/"); strcat(nopq, name); sprintf (rst, "%03d", f ); strcat(nopq,rst); strcat(nopq,".png"); printf("Saved frame %d to %s\n", (f+1) ,nopq); save_extension( t, nopq ); clear_screen( t ); screen t; if (f < num_frames - 1){ obj = 0; g.red = 40; g.green = 50; g.blue = 60; } free_stack( s ); free_matrix( tmp ); s = new_stack(); tmp = new_matrix(4, 1000); } //printf("finished frame %d\n",f); } //////////////////////////////////////////////////////////// for (j = 0; j < num_frames; j++){ struct vary_node * v2 = klist[j]; struct vary_node * v = klist[j]; while (v2 != NULL){ v = v2; v2 = v2->next; free(v); } } free(klist); } ///////////////////////////////////////////////////// lcons* v2 = lclist; lcons* v = lclist; while (v2 != NULL){ v = v2; v2 = v2->next; free(v); } //////////////////////////////////////////////// /*for ( i=0; i < lastsym; i++ ) { if ( symtab[i].type == SYM_LIGHT ) { //printf( "Freeing %s:\n", symtab[i].name); //print_light(symtab[i].s.l); //free(symtab[i].s.l); } }*/ //////////////////////////////////////////////////// free_stack( s ); free_matrix( tmp ); for(i = 0; i < 500; i++){ free(zbuf[i]); } for (i = 0; i < ptl; i++){ free(ptlights[i]); } free(ptlights); free(zbuf); printf("ambient light = %d,%d,%d\n",g.red,g.green,g.blue); //free_matrix( transform ); }
void my_main( int polygons ) { int i, axis; double xval, xval1, yval, yval1, zval, zval1, degrees, width, height, depth, r, r1; struct matrix *transform; struct matrix *tmp; struct stack *s; screen t; color g; g = change_color(0); s = new_stack(); tmp = new_matrix(4, 1000); clear_screen( t ); for (i=0;i<lastop;i++) { switch (op[i].opcode) { case PUSH: push(s); break; case POP: pop(s); break; case MOVE: xval = op[i].op.move.d[0]; yval = op[i].op.move.d[1]; zval = op[i].op.move.d[2]; transform = make_translate(xval, yval, zval); matrix_mult(transform, s->data[s->top]); break; case SCALE: xval = op[i].op.scale.d[0]; yval = op[i].op.scale.d[1]; zval = op[i].op.scale.d[2]; transform = make_scale(xval, yval, zval); matrix_mult(transform, s->data[s->top]); break; case ROTATE: axis = op[i].op.rotate.axis; degrees = op[i].op.rotate.degrees; if(axis == 0) transform = make_rotX(degrees); else if(axis == 1) transform = make_rotY(degrees); else if(axis == 2) transform = make_rotZ(degrees); matrix_mult(transform, s->data[s->top]); break; case BOX: free_matrix(tmp); tmp = new_matrix(4, 1000); xval = op[i].op.box.d0[0]; yval = op[i].op.box.d0[1]; zval = op[i].op.box.d0[2]; width = op[i].op.box.d1[0]; height = op[i].op.box.d1[1]; depth = op[i].op.box.d1[2]; add_box(tmp, xval, yval, zval, width, height, depth); matrix_mult(s->data[s->top], tmp); draw_polygons(tmp, t, g); break; case SPHERE: free_matrix(tmp); tmp = new_matrix(4, 1000); xval = op[i].op.sphere.d[0]; yval = op[i].op.sphere.d[1]; zval = op[i].op.sphere.d[2]; r = op[i].op.sphere.r; add_sphere(tmp, xval, yval, zval, r, 0.05); matrix_mult(s->data[s->top], tmp); draw_polygons(tmp, t, g); break; case TORUS: free_matrix(tmp); tmp = new_matrix(4, 1000); xval = op[i].op.torus.d[0]; yval = op[i].op.torus.d[1]; zval = op[i].op.torus.d[2]; r = op[i].op.torus.r0; r1 = op[i].op.torus.r1; add_torus(tmp, xval, yval, zval, r, r1, 0.05); matrix_mult(s->data[s->top], tmp); draw_polygons(tmp, t, g); break; case LINE: free_matrix(tmp); tmp = new_matrix(4, 1000); xval = op[i].op.line.p0[0]; yval = op[i].op.line.p0[1]; zval = op[i].op.line.p0[2]; xval1 = op[i].op.line.p1[0]; yval1 = op[i].op.line.p1[1]; zval1 = op[i].op.line.p1[2]; add_edge(tmp, xval, yval, zval, xval1, yval1, zval1); matrix_mult(s->data[s->top], tmp); draw_lines(tmp, t, g); break; case SAVE: save_extension(t, op[i].op.save.p->name); break; case DISPLAY: display(t); break; } } free_stack(s); free_matrix(tmp); }
void my_main( int polygons ) { int i, j; double step = 0.05; // Decided to make step this value double xval, yval, zval; struct matrix *transform; struct matrix *tmp; struct stack *s; screen t; color g; g = change_color(2); int axis; // 0,1,2 correspond to x,y,z axes of rotation, respectively double measure; // corresponds to angle of rotation double width, height, depth; // For box double radius; // For sphere double r1, r2; // For torus double x2,y2,z2; // For line s = new_stack(); tmp = new_matrix(4, 1000); clear_screen( t ); for (i=0;i<lastop;i++) { switch (op[i].opcode) { case COMMENT: break; case PUSH: push(s); break; case POP: pop(s); break; case MOVE: xval = op[i].op.move.d[0]; yval = op[i].op.move.d[1]; zval = op[i].op.move.d[2]; transform = make_translate(xval, yval, zval); matrix_mult(s->data[s->top], transform); s->data[s->top] = transform; break; case SCALE: xval = op[i].op.scale.d[0]; yval = op[i].op.scale.d[1]; zval = op[i].op.scale.d[2]; transform = make_scale(xval, yval, zval); matrix_mult(s->data[s->top], transform); s->data[s->top] = transform; break; case ROTATE: axis = op[i].op.rotate.axis; measure = op[i].op.rotate.degrees; if(axis == 0){ transform = make_rotX(measure);} if(axis == 1){ transform = make_rotY(measure);} if(axis == 2){ transform = make_rotZ(measure);} matrix_mult(s->data[s->top], transform); s->data[s->top] = transform; break; case BOX: for(j = 0; j < tmp->lastcol; j++){ tmp->m[0][j] = 0; tmp->m[1][j] = 0; tmp->m[2][j] = 0; } tmp->lastcol = 0; xval = op[i].op.box.d0[0]; yval = op[i].op.box.d0[1]; zval = op[i].op.box.d0[2]; width = op[i].op.box.d1[0]; height = op[i].op.box.d1[1]; depth = op[i].op.box.d1[2]; add_box(tmp, xval, yval, zval, width, height, depth); matrix_mult(s->data[s->top], tmp); //matrix_mult(transform, tmp); draw_polygons(tmp, t, g); //free_matrix(tmp); break; case SPHERE: for(j = 0; j < tmp->lastcol; j++){ tmp->m[0][j] = 0; tmp->m[1][j] = 0; tmp->m[2][j] = 0; } tmp->lastcol = 0; xval = op[i].op.sphere.d[0]; yval = op[i].op.sphere.d[1]; zval = op[i].op.sphere.d[2]; radius = op[i].op.sphere.r; add_sphere(tmp, xval, yval, zval, radius, step); matrix_mult(s->data[s->top], tmp); draw_polygons(tmp, t, g); break; case TORUS: for(j = 0; j < tmp->lastcol; j++){ tmp->m[0][j] = 0; tmp->m[1][j] = 0; tmp->m[2][j] = 0; } tmp->lastcol = 0; xval = op[i].op.torus.d[0]; yval = op[i].op.torus.d[1]; zval = op[i].op.torus.d[2]; r1 = op[i].op.torus.r0; r2 = op[i].op.torus.r1; add_torus(tmp, xval, yval, zval, r1, r2, step); matrix_mult(s->data[s->top], tmp); draw_polygons(tmp, t, g); break; case LINE: for(j = 0; j < tmp->lastcol; j++){ tmp->m[0][j] = 0; tmp->m[1][j] = 0; tmp->m[2][j] = 0; } tmp->lastcol = 0; xval = op[i].op.line.p0[0]; yval = op[i].op.line.p0[1]; zval = op[i].op.line.p0[2]; x2 = op[i].op.line.p1[0]; y2 = op[i].op.line.p1[1]; z2 = op[i].op.line.p1[2]; add_edge(tmp, xval, yval, zval, x2, y2, z2); matrix_mult(s->data[s->top], tmp); draw_lines(tmp, t, g); break; case SAVE: save_extension(t, op[i].op.save.p->name); break; case DISPLAY: display(t); break; } } //free_stack(s); //free_matrix(transform); }
void my_main( int polygons ) { int i, ax; double step; double xval, yval, zval, x2, y2, z2; double w, h, d, r1, r2, m; struct matrix *transform; struct matrix *tmp; struct stack *s; screen t; color g; g.red = 250; g.blue = 0; g.green = 0; s = new_stack(); tmp = new_matrix(4, 1000); clear_screen( t ); for (i=0; i<lastop; i++) { switch (op[i].opcode) { case COMMENT: break; case PUSH: push(s); break; case POP: pop(s); break; case MOVE: xval = op[i].op.move.d[0]; yval = op[i].op.move.d[1]; zval = op[i].op.move.d[2]; transform = make_translate(xval, yval, zval); matrix_mult(transform, s->data[s->top]); break; case SCALE: xval = op[i].op.scale.d[0]; yval = op[i].op.scale.d[1]; zval = op[i].op.scale.d[2]; transform = make_scale(xval, yval, zval); matrix_mult(transform, s->data[s->top]); break; case ROTATE: ax = op[i].op.rotate.axis; m = op[i].op.rotate.degrees; if(ax == 0) transform = make_rotX(m); if(ax == 1) transform = make_rotY(m); if(ax ==2) transform = make_rotZ(m); matrix_mult(transform, s->data[s->top]); break; case BOX: xval = op[i].op.box.d0[0]; yval = op[i].op.box.d0[1]; zval = op[i].op.box.d0[2]; w = op[i].op.box.d1[0]; h = op[i].op.box.d1[1]; d = op[i].op.box.d1[2]; add_box(tmp, xval, yval, zval, w, h, d); matrix_mult(s->data[s->top], tmp); draw_polygons(tmp, t, g); break; case SPHERE: xval = op[i].op.sphere.d[0]; yval = op[i].op.sphere.d[1]; zval = op[i].op.sphere.d[2]; r1 = op[i].op.sphere.r; add_sphere(tmp, xval, yval, zval, r1, .01); matrix_mult(s->data[s->top], tmp); draw_polygons(tmp, t, g); break; case TORUS: xval = op[i].op.torus.d[0]; yval = op[i].op.torus.d[1]; zval = op[i].op.torus.d[2]; r1 = op[i].op.torus.r0; r2 = op[i].op.torus.r1; add_torus(tmp, xval, yval, zval, r1, r2, .01); matrix_mult(s->data[s->top], tmp); draw_polygons(tmp, t, g); break; case LINE: xval = op[i].op.line.p0[0]; yval = op[i].op.line.p0[1]; zval = op[i].op.line.p0[2]; x2 = op[i].op.line.p1[0]; y2 = op[i].op.line.p1[1]; z2 = op[i].op.line.p1[2]; add_edge(tmp, xval, yval, zval, x2, y2, z2); matrix_mult(s->data[s->top], tmp); draw_lines(tmp, t, g); break; case SAVE: save_extension(t, op[i].op.save.p->name); break; case DISPLAY: display(t); break; } } }
/*======== void my_main() ========== Inputs: Returns: This is the main engine of the interpreter, it should handle most of the commadns in mdl. If frames is not present in the source (and therefore num_frames is 1, then process_knobs should be called. If frames is present, the enitre op array must be applied frames time. At the end of each frame iteration save the current screen to a file named the provided basename plus a numeric string such that the files will be listed in order, then clear the screen and reset any other data structures that need it. Important note: you cannot just name your files in regular sequence, like pic0, pic1, pic2, pic3... if that is done, then pic1, pic10, pic11... will come before pic2 and so on. In order to keep things clear, add leading 0s to the numeric portion of the name. If you use sprintf, you can use "%0xd" for this purpose. It will add at most x 0s in front of a number, if needed, so if used correctly, and x = 4, you would get numbers like 0001, 0002, 0011, 0487 05/17/12 09:41:35 jdyrlandweaver ====================*/ void my_main( int polygons ) { int i, f, j; double step; double xval, yval, zval, knob_value; struct matrix *transform; struct matrix *tmp; struct stack *s; screen t; color g; struct vary_node **knobs; struct vary_node *vn; char frame_name[128]; num_frames = 1; step = 5; g.red = 0; g.green = 255; g.blue = 255; first_pass(); if (num_frames>1){ knobs = second_pass(); } int cur_frame; char frame_num_string[4]; for (cur_frame=0;cur_frame<num_frames-1;cur_frame++){ strcpy(frame_name,"animation_frames/"); strcat(frame_name,name); sprintf(frame_num_string,"%03d",cur_frame+1); strcat(frame_name,frame_num_string); s = new_stack(); tmp = new_matrix(4,0); for (i=0;i<lastop;i++) { switch (op[i].opcode) { case SPHERE: add_sphere( tmp,op[i].op.sphere.d[0], //cx op[i].op.sphere.d[1], //cy op[i].op.sphere.d[2], //cz op[i].op.sphere.r, step); //apply the current top origin matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case TORUS: add_torus( tmp, op[i].op.torus.d[0], //cx op[i].op.torus.d[1], //cy op[i].op.torus.d[2], //cz op[i].op.torus.r0, op[i].op.torus.r1, step); matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case BOX: add_box( tmp, op[i].op.box.d0[0], op[i].op.box.d0[1], op[i].op.box.d0[2], op[i].op.box.d1[0], op[i].op.box.d1[1], op[i].op.box.d1[2]); matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case LINE: add_edge( tmp, op[i].op.line.p0[0], op[i].op.line.p0[1], op[i].op.line.p0[1], op[i].op.line.p1[0], op[i].op.line.p1[1], op[i].op.line.p1[1]); draw_lines( tmp, t, g ); tmp->lastcol = 0; break; case SET: vn = knobs[cur_frame]; while (vn != NULL){ if (strcmp(vn->name,op[i].op.set.p->name)==0){ vn->value = op[i].op.set.val; } vn = vn->next; } break; case SETKNOBS: vn = knobs[cur_frame]; while (vn != NULL){ vn->value = op[i].op.setknobs.value; vn = vn->next; } break; case MOVE: //get the factors xval = op[i].op.move.d[0]; yval = op[i].op.move.d[1]; zval = op[i].op.move.d[2]; if (op[i].op.move.p != NULL){ vn = knobs[cur_frame]; while (vn != NULL){ if (strcmp(vn->name,op[i].op.scale.p->name)==0){ xval*=vn->value; yval*=vn->value; zval*=vn->value; } vn = vn->next; } } transform = make_translate( xval, yval, zval ); //multiply by the existing origin matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case SCALE: xval = op[i].op.scale.d[0]; yval = op[i].op.scale.d[1]; zval = op[i].op.scale.d[2]; if (op[i].op.scale.p != NULL){ vn = knobs[cur_frame]; while (vn != NULL){ if (strcmp(vn->name,op[i].op.scale.p->name)==0){ xval*=vn->value; yval*=vn->value; zval*=vn->value; } vn = vn->next; } } transform = make_scale( xval, yval, zval ); matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case ROTATE: xval = op[i].op.rotate.degrees * ( M_PI / 180 ); if (op[i].op.scale.p == NULL){ vn = knobs[cur_frame]; while (vn != NULL){ if (strcmp(vn->name,op[i].op.rotate.p->name)==0){ xval*=vn->value; } vn = vn->next; } } //get the axis if ( op[i].op.rotate.axis == 0 ) transform = make_rotX( xval ); else if ( op[i].op.rotate.axis == 1 ) transform = make_rotY( xval ); else if ( op[i].op.rotate.axis == 2 ) transform = make_rotZ( xval ); matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case PUSH: push( s ); break; case POP: pop( s ); break; case SAVE: save_extension( t, op[i].op.save.p->name ); break; case DISPLAY: display( t ); break; } } if (num_frames > 1){ save_extension( t, frame_name ); clear_screen(t); free_stack( s ); free_matrix( tmp ); } } }
void my_main( int polygons ) { int i; double step; double xval, yval, zval, xcor, ycor, zcor, angle, radius; struct matrix *transform; struct matrix *tmp; screen t; color g; g.red = 0; g.green = 255; g.blue = 0; struct stack *s; s = new_stack(); tmp = new_matrix(4, 1000); clear_screen( t ); for (i=0;i<lastop;i++) { printf("loop %d\n", i); switch (op[i].opcode){ case PUSH: push(s); printf("%s\n", "pop\n"); break; case POP: pop(s); printf("%s\n", "pop\n"); break; case MOVE: xval = op[i].op.move.d[0]; yval = op[i].op.move.d[1]; zval = op[i].op.move.d[2]; tmp = make_translate(xval, yval, zval); matrix_mult(s->data[s->top], tmp); copy_matrix(tmp, s->data[s->top]); printf("%s\n", "move\n"); break; case SCALE: xval = op[i].op.scale.d[0]; yval = op[i].op.scale.d[1]; zval = op[i].op.scale.d[2]; tmp = make_scale(xval, yval, zval); matrix_mult(s->data[s->top], tmp); copy_matrix(tmp, s->data[s->top]); printf("%s\n", "scale\n"); break; case ROTATE: angle = op[i].op.rotate.degrees * M_PI / 180; if(op[i].op.rotate.axis == 0){ tmp = make_rotX(angle); matrix_mult(s->data[s->top], tmp); copy_matrix(tmp, s->data[s->top]); } else if(op[i].op.rotate.axis == 1){ tmp = make_rotY(angle); matrix_mult(s->data[s->top], tmp); copy_matrix(tmp, s->data[s->top]); } else{ tmp = make_rotZ(angle); matrix_mult(s->data[s->top], tmp); copy_matrix(tmp, s->data[s->top]); } printf("%s\n", "rotate\n"); break; case BOX: xval = op[i].op.box.d0[0]; yval = op[i].op.box.d0[1]; zval = op[i].op.box.d0[2]; xcor = op[i].op.box.d0[0]; ycor = op[i].op.box.d0[1]; zcor = op[i].op.box.d0[2]; add_box(tmp, xval, yval, zval, xcor, ycor, zcor); matrix_mult(s->data[s->top], tmp); draw_polygons(tmp, t, g); printf("box\n"); break; case SPHERE: xval = op[i].op.sphere.d[0]; yval = op[i].op.sphere.d[1]; zval = op[i].op.sphere.d[2]; radius = op[i].op.sphere.r; add_sphere(tmp, xval, yval, zval, radius, 10); matrix_mult(s->data[s->top], tmp); draw_polygons(tmp, t, g); printf("%s\n", "sphere\n"); break; case TORUS: xval = op[i].op.torus.d[0]; yval = op[i].op.torus.d[1]; zval = op[i].op.torus.d[2]; double inner = op[i].op.torus.r0; double outer = op[i].op.torus.r1; add_torus(tmp, xval, yval, zval, inner, outer, 10); matrix_mult(s->data[s->top], tmp); draw_polygons(tmp, t, g); printf("%s\n", "torus\n"); break; case LINE: xval = op[i].op.line.d[0]; yval = op[i].op.line.d[1]; zval = op[i].op.line.d[2]; xcor = op[i].op.line.d[0]; ycor = op[i].op.line.d[1]; zcor = op[i].op.line.d[2]; add_edge(tmp, xval, yval, zval, xcor, ycor, zcor); matrix_mult(s->data[s->top], tmp); draw_lines(tmp, t, g); printf("%s\n", "line\n"); break; case SAVE: save_extension(t, op[i].op.save.p->name); printf("%s\n", "save\n"); break; case DISPLAY: display(t); printf("%s\n", "display\n"); } } }
group* make_tree(sphere* spheres, int start, unsigned int count, int level = 0) { if(level == 0) { previous = time(NULL); if(getenv("DEBUG_BVH") != NULL) { bvh_spheres_debug_output = fopen("bvh.r9", "w"); } } if(time(NULL) > previous) { fprintf(stderr, "total treed = %d\n", total_treed); previous = time(NULL); } if((level >= bvh_max_depth) || count <= bvh_leaf_max) { total_treed += count; group* g = new group(spheres, start, count); if(bvh_spheres_debug_output != NULL) { // fprintf(bvh_spheres_debug_output, "sphere 7 %f %f %f %f 1 1 1 # %d\n", g->radius, g->center.x, g->center.y, g->center.z, level ); if(level == 0) { fclose(bvh_spheres_debug_output); bvh_spheres_debug_output = NULL; } } bvh_leaf_size_counts[std::min(63U, count)]++; bvh_leaf_count++; bvh_level_counts[level]++; bvh_node_count++; return g; } vec3 split_pivot; vec3 split_plane_normal; // find bounding box vec3 boxmin, boxmax; box_init(boxmin, boxmax); for(unsigned int i = 0; i < count; i++) { sphere &s = spheres[start + i]; vec3 spheremin = vec3_subtract(s.center, vec3(s.radius)); vec3 spheremax = vec3_add(s.center, vec3(s.radius)); box_extend(boxmin, boxmax, spheremin, spheremax); } split_pivot = vec3_scale(vec3_add(boxmin, boxmax), .5); vec3 boxdim = vec3_subtract(boxmax, boxmin); if(boxdim.x > boxdim.y && boxdim.x > boxdim.z) { split_plane_normal = vec3(1, 0, 0); } else if(boxdim.y > boxdim.z) { split_plane_normal = vec3(0, 1, 0); } else { split_plane_normal = vec3(0, 0, 1); } // XXX output split plane to BVH debug file int startA; int countA; int startB; int countB; if(!bvh_split_median) { int s1 = start - 1; int s2 = start + count; do { // from start to s1, not including s1, is negative // from s2 to start + count - 1 is positive do { s1 += 1; } while((s1 < s2) && vec3_dot(vec3_subtract(spheres[s1].center, split_pivot), split_plane_normal) < 0); // If there wasn't a positive sphere before s2, done. if(s1 >= s2) break; // s1 is now location of lowest positive sphere do { s2 -= 1; } while((s1 < s2) && vec3_dot(vec3_subtract(spheres[s2].center, split_pivot), split_plane_normal) >= 0); // If there wasn't a negative sphere between s1 and s2, done if(s1 >= s2) break; // s2 is now location of highest negative sphere std::swap(spheres[s1], spheres[s2]); } while(true); // s1 is the first of the positive spheres startA = start; countA = s1 - startA; startB = s1; countB = start + count - s1; } else { sphere_sorter sorter(split_plane_normal); std::sort(spheres + start, spheres + start + count - 1, sorter); startA = start; countA = count / 2; startB = startA + countA; countB = count - countA; } group *g; if(countA > 0 && countB > 0) { // get a tighter bound around children than hierarchical bounds vec3 boxmin, boxmax; box_init(boxmin, boxmax); for(unsigned int i = 0; i < count; i++) { add_sphere(&boxmin, &boxmax, spheres[start + i].center, spheres[start + i].radius); } // construct children group *g1 = make_tree(spheres, startA, countA, level + 1); g = new group(spheres, g1, NULL, split_plane_normal, boxmin, boxmax); group *g2 = make_tree(spheres, startB, countB, level + 1); g->positive = g2; bvh_level_counts[level]++; bvh_node_count++; } else { total_treed += count; fprintf(stderr, "Leaf node at %d, %u spheres, total %d\n", level, count, total_treed); g = new group(spheres, start, count); bvh_leaf_size_counts[std::min(63U, count)]++; bvh_leaf_count++; bvh_level_counts[level]++; bvh_node_count++; } if(bvh_spheres_debug_output != NULL) { // fprintf(bvh_spheres_debug_output, "sphere 7 %f %f %f %f 1 1 1 # %d\n", g->radius, g->center.x, g->center.y, g->center.z, level ); if(level == 0) { fclose(bvh_spheres_debug_output); bvh_spheres_debug_output = NULL; } } return g; }
/*======== void parse_file () ========== Inputs: char * filename struct matrix * transform, struct matrix * pm, screen s Returns: Goes through the file named filename and performs all of the actions listed in that file. The file follows the following format: Every command is a single character that takes up a line Any command that requires arguments must have those arguments in the second line. The commands are as follows: line: add a line to the edge matrix - takes 6 arguemnts (x0, y0, z0, x1, y1, z1) circle: add a circle to the edge matrix - takes 3 arguments (cx, cy, r) hermite: add a hermite curve to the edge matrix - takes 8 arguments (x0, y0, x1, y1, x2, y2, x3, y3) bezier: add a bezier curve to the edge matrix - takes 8 arguments (x0, y0, x1, y1, x2, y2, x3, y3) sphere: add a sphere to the edge matrix - takes 3 arguemnts (cx, cy, r) torus: add a torus to the edge matrix - takes 4 arguemnts (cx, cy, r1, r2) box: add a rectangular prism to the edge matrix - takes 6 arguemnts (x, y, z, width, height, depth) clear: clear the currnt edge matrix - takes 0 arguments ident: set the transform matrix to the identity matrix - scale: create a scale matrix, then multiply the transform matrix by the scale matrix - takes 3 arguments (sx, sy, sz) translate: create a translation matrix, then multiply the transform matrix by the translation matrix - takes 3 arguments (tx, ty, tz) xrotate: create an x-axis rotation matrix, then multiply the transform matrix by the rotation matrix - takes 1 argument (theta) yrotate: create an y-axis rotation matrix, then multiply the transform matrix by the rotation matrix - takes 1 argument (theta) zrotate: create an z-axis rotation matrix, then multiply the transform matrix by the rotation matrix - takes 1 argument (theta) apply: apply the current transformation matrix to the edge matrix display: draw the lines of the edge matrix to the screen display the screen save: draw the lines of the edge matrix to the screen save the screen to a file - takes 1 argument (file name) quit: end parsing See the file script for an example of the file format IMPORTANT MATH NOTE: the trig functions int math.h use radian mesure, but us normal humans use degrees, so the file will contain degrees for rotations, be sure to conver those degrees to radians (M_PI is the constant for PI) ====================*/ void parse_file ( char * filename, struct matrix * transform, struct matrix * pm, screen s) { FILE *f; char line[256]; struct matrix * tmp; double angle; color g; struct stack* shakestack; //relative coordinate system stack int draw_mode=-1; //equals 0 if draw_edges, equals 1 if draw_polygons shakestack = new_stack(); g.red = 0; g.green = 255; g.blue = 0; clear_screen(s); if ( strcmp(filename, "stdin") == 0 ) f = stdin; else f = fopen(filename, "r"); while ( fgets(line, 255, f) != NULL ) { line[strlen(line)-1]='\0'; //printf(":%s:\n",line); double x, y, z, x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4; if ( strncmp(line, "line", strlen(line)) == 0 ) { // printf("LINE!\n"); fgets(line, 255, f); // printf("\t%s", line); //line[strlen(line)-1]='\0'; sscanf(line, "%lf %lf %lf %lf %lf %lf", &x, &y, &z, &x1, &y1, &z1); add_edge(pm, x, y, z, x1, y1, z1); // printf( "%lf %lf %lf %lf %lf %lf\n", x, y, z, x1, y1, z1); draw_mode = 0; } else if ( strncmp(line, "circle", strlen(line)) == 0 ) { //printf("CIRCLE\n"); fgets(line, 255, f); sscanf(line, "%lf %lf %lf", &x, &y, &z); add_circle(pm, x, y, z, 0.01); //printf( "%lf %lf %lf\n", x, y, z); draw_mode = 0; } else if ( strncmp(line, "bezier", strlen(line)) == 0 ) { //printf("BEZIER\n"); fgets(line, 255, f); sscanf(line, "%lf %lf %lf %lf %lf %lf %lf %lf", &x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4); add_curve(pm, x1, y1, x2, y2, x3, y3, x4, y4, 0.01, BEZIER_MODE ); //printf( "%lf %lf %lf\n", x, y, z); draw_mode = 0; } else if ( strncmp(line, "hermite", strlen(line)) == 0 ) { //printf("HERMITE\n"); fgets(line, 255, f); sscanf(line, "%lf %lf %lf %lf %lf %lf %lf %lf", &x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4); add_curve(pm, x1, y1, x2, y2, x3, y3, x4, y4, 0.01, HERMITE_MODE ); //printf( "%lf %lf %lf\n", x, y, z); draw_mode = 0; } else if ( strncmp(line, "box", strlen(line)) == 0 ) { fgets(line, 255, f); sscanf(line, "%lf %lf %lf %lf %lf %lf", &x, &y, &z, &x1, &y1, &z1); add_box(pm, x, y, z, x1, y1, z1); // printf( "%lf %lf %lf %lf %lf %lf\n", x, y, z, x1, y1, z1); draw_mode = 1; } else if (strncmp(line, "sphere", strlen(line)) == 0 ) { fgets(line, 255, f); sscanf(line, "%lf %lf %lf", &x, &y, &z); add_sphere(pm, x, y, z, 10); //printf( "%lf %lf %lf\n", x, y, z); draw_mode = 1; } else if (strncmp(line, "torus", strlen(line)) == 0 ) { fgets(line, 255, f); sscanf(line, "%lf %lf %lf %lf", &x, &y, &z, &z1); add_torus(pm, x, y, z, z1, 10); //printf( "%lf %lf %lf\n", x, y, z); draw_mode = 1; } else if ( strncmp(line, "scale", strlen(line)) == 0 ) { //printf("SCALE\n"); fgets(line, 255, f); //line[strlen(line)-1]='\0'; sscanf(line, "%lf %lf %lf", &x, &y, &z); tmp = make_scale(x, y, z); //matrix_mult(tmp, transform); //print_matrix(transform); matrix_mult(tmp, shakestack->data[ shakestack->top ]); } else if ( strncmp(line, "translate", strlen(line)) == 0 ) { //printf("TRANSLATE\n"); fgets(line, 255, f); // line[strlen(line)-1]='\0'; sscanf(line, "%lf %lf %lf", &x, &y, &z); tmp = make_translate(x, y, z); //matrix_mult(tmp, transform); //print_matrix(transform); matrix_mult(tmp, shakestack->data[ shakestack->top ]); } else if ( strncmp(line, "xrotate", strlen(line)) == 0 ) { //printf("ROTATE!\n"); fgets(line, 255, f); sscanf(line, "%lf", &angle); angle = angle * (M_PI / 180); tmp = make_rotX( angle); //matrix_mult(tmp, transform); matrix_mult(tmp, shakestack->data[ shakestack->top ]); } else if ( strncmp(line, "yrotate", strlen(line)) == 0 ) { //printf("ROTATE!\n"); fgets(line, 255, f); sscanf(line, "%lf", &angle); angle = angle * (M_PI / 180); tmp = make_rotY( angle); //matrix_mult(tmp, transform); matrix_mult(tmp, shakestack->data[ shakestack->top ]); } else if ( strncmp(line, "zrotate", strlen(line)) == 0 ) { //printf("ROTATE!\n"); fgets(line, 255, f); sscanf(line, "%lf", &angle); angle = angle * (M_PI / 180); tmp = make_rotZ( angle); //matrix_mult(tmp, transform); matrix_mult(tmp, shakestack->data[ shakestack->top ]); } else if ( strncmp(line, "ident", strlen(line)) == 0 ) { ident(transform); } else if ( strncmp(line, "apply", strlen(line)) == 0 ) { //printf("APPLY!\n"); //print_matrix( transform ); // print_matrix(pm); //matrix_mult(transform, pm); matrix_mult(shakestack->data[ shakestack->top ], pm); } else if ( strncmp(line, "display", strlen(line)) == 0 ) { clear_screen(s); if( draw_mode==0 ) { draw_lines(pm, s, g); } else { draw_polygons(pm, s, g); } display(s); } else if ( strncmp(line, "save", strlen(line)) == 0 ) { fgets(line, 255, f); // line[strlen(line)-1] = '\0'; clear_screen(s); if( draw_mode==0 ) { draw_lines(pm, s, g); } else { draw_polygons(pm, s, g); } save_extension(s, line); } else if ( strncmp(line, "clear", strlen(line)) == 0 ) { pm->lastcol = 0; } else if ( strncmp(line, "quit", strlen(line)) == 0 ) { return; } //==================STACK COMMANDS================================= else if( strncmp(line, "push", strlen(line)) == 0 ) { push(shakestack); print_stack(shakestack); } else if( strncmp(line, "pop", strlen(line)) == 0 ) { pop(shakestack); print_stack(shakestack); } else if ( line[0] == '#' ) { printf("Invalid command\n"); } //adding color coommand================== else if( strncmp(line, "color", strlen(line)) == 0 ) { fgets(line, 255, f); sscanf(line, "%i %i %i", &x, &y, &z); g.red = x; g.green = y; g.blue = z; } else { printf("Invalid command\n"); } } free_matrix(tmp); fclose(f); //printf("END PARSE\n"); }
void my_main( int polygons ) { int i; double step; double xval, yval, zval; struct matrix *transform; struct matrix *tmp; struct stack *s; screen t; color g; s = new_stack(); tmp = new_matrix(4, 1000); clear_screen( t ); void clear_tmp(){ for(j = 0; j < tmp->lastcol; j++){ tmp->m[0][j] = 0; tmp->m[1][j] = 0; tmp->m[2][j] = 0; } tmp->lastcol = 0; } for (i=0;i<lastop;i++) { clear_tmp(); switch (op[i].opcode) { case COMMENT: break; case PUSH: push(s); break; case POP: pop(s); break; case SAVE: save_extension(t, op[i].op.save.p->name); break; case MOVE: xval = op[i].op.move.d[0]; yval = op[i].op.move.d[1]; zval = op[i].op.move.d[2]; transform = make_translate(xval, yval, zval); matrix_mult(s->data[s->top], transform); s->data[s->top]=transform; break; case SCALE: xval = op[i].op.move.d[0]; yval = op[i].op.move.d[1]; zval = op[i].op.move.d[2]; transform = make_scale(xval, yval, zval); matrix_mult(s->data[s->top], transform); s->data[s->top]=transform; break; case LINE: xval = op[i].op.line.p0[0]; yval = op[i].op.line.p0[1]; zval = op[i].op.line.p0[2]; x2 = op[i].op.line.p1[0]; y2 = op[i].op.line.p1[1]; z2 = op[i].op.line.p1[2]; add_edge(tmp, xval, yval, zval, x2, y2, z2); matrix_mult(s->data[s->top], tmp); draw_lines(tmp, t, g); break; case BOX: xval = op[i].op.box.d0[0]; yval = op[i].op.box.d0[1]; zval = op[i].op.box.d0[2]; width = op[i].op.box.d1[0]; height = op[i].op.box.d1[1]; depth = op[i].op.box.d1[2]; add_box(tmp, xval, yval, zval, width, height, depth); matrix_mult(s->data[s->top], tmp); draw_polygons(tmp, t, g); break; case SPHERE: xval = op[i].op.sphere.d[0]; yval = op[i].op.sphere.d[1]; zval = op[i].op.sphere.d[2]; radius = op[i].op.sphere.r; add_sphere(tmp, xval, yval, zval, radius, step); matrix_mult(s->data[s->top], tmp); draw_polygons(tmp, t, g); break; case TORUS: xval = op[i].op.torus.d[0]; yval = op[i].op.torus.d[1]; zval = op[i].op.torus.d[2]; r1 = op[i].op.torus.r0; r2 = op[i].op.torus.r1; add_torus(tmp, xval, yval, zval, r1, r2, step); matrix_mult(s->data[s->top], tmp); draw_polygons(tmp, t, g); break; case DISPLAY: display(t); break; } } }
void my_main( int polygons ) { int i,ROT_AXIS; double step; double xval, yval, zval; struct matrix *transform; struct matrix *tmp; struct stack *s; screen t; color g; g.red = 122; g.green = 218; g.blue = 225; s = new_stack(); tmp = new_matrix(4, 1000); clear_screen( t ); for (i=0;i<lastop;i++) { switch (op[i].opcode) { case PUSH: push(s); break; case POP: pop(s); break; case DISPLAY: display(t); break; case SAVE: save_extension(t,op[i].op.save.p->name); break; case MOVE: transform = make_translate(op[i].op.move.d[0], op[i].op.move.d[1], op[i].op.move.d[2]); matrix_mult(transform,s->data[s->top]); break; case SCALE: transform = make_scale(op[i].op.scale.d[0], op[i].op.scale.d[1], op[i].op.scale.d[2]); matrix_mult(transform,s->data[s->top]); break; case ROTATE: ROT_AXIS = op[i].op.rotate.axis; if(ROT_AXIS = 0) transform = make_rotX(op[i].op.rotate.degrees); else if(ROT_AXIS = 1) transform = make_rotY(op[i].op.rotate.degrees); else if(ROT_AXIS = 2) transform = make_rotZ(op[i].op.rotate.degrees); matrix_mult(transform,s->data[s->top]); break; case LINE: add_edge(tmp, op[i].op.line.p0[0], op[i].op.line.p0[1], op[i].op.line.p0[2], op[i].op.line.p1[0], op[i].op.line.p1[1], op[i].op.line.p1[2]); matrix_mult(s->data[s->top],tmp); draw_lines(tmp,t,g); break; case SPHERE: add_sphere(tmp,op[i].op.sphere.d[0], op[i].op.sphere.d[1], op[i].op.sphere.d[3], op[i].op.sphere.r, .1); matrix_mult(s->data[s->top],tmp); draw_polygons(tmp,t,g); break; case BOX: add_box(tmp,op[i].op.box.d0[0], op[i].op.box.d0[1], op[i].op.box.d0[2], op[i].op.box.d1[0], op[i].op.box.d1[1], op[i].op.box.d1[2]); matrix_mult(s->data[s->top],tmp); draw_polygons(tmp,t,g); break; case TORUS: add_torus(tmp,op[i].op.torus.d[0], op[i].op.torus.d[1], op[i].op.torus.d[2], op[i].op.torus.r0, op[i].op.torus.r1, .1); matrix_mult(s->data[s->top],tmp); draw_polygons(tmp,t,g); break; } } }
void my_main( int polygons ) { int i; double step = .05; double xval, yval, zval; struct matrix *transform; struct matrix *tmp; struct stack *s; screen t; color g; g = change_color(4); s = new_stack(); tmp = new_matrix(4, 1000); clear_screen( t ); for (i=0;i<lastop;i++) { switch (op[i].opcode) { case COMMENT: break; case PUSH: push(s); break; case POP: pop(s); break; case MOVE: xval = op[i].op.move.d[0]; yval = op[i].op.move.d[1]; zval = op[i].op.move.d[2]; transform = make_translate(xval, yval, zval); matrix_mult(s->data[s->top], transform); s->data[s->top] = transform; break; case SCALE: xval = op[i].op.scale.d[0]; yval = op[i].op.scale.d[1]; zval = op[i].op.scale.d[2]; transform - make_scale(xval, yval, zval); matrix_mult(s->data[s->top], transform); s->data[s->top] = transform; break; case ROTATE: switch ((int)op[i].op.rotate.axis) { double theta = op[i].op.rotate.degrees; case 0: transform = make_rotX(theta); break; case 1: transform = make_rotY(theta); break; case 2: transform = make_rotZ(theta); break; } matrix_mult(s->data[s->top], transform); s->data[s->top] = transform; break; case BOX: empty_matrix(tmp); xval = op[i].op.box.d0[0]; yval = op[i].op.box.d0[1]; zval = op[i].op.box.d0[2]; double width = op[i].op.box.d1[0]; double height = op[i].op.box.d1[1]; double depth = op[i].op.box.d1[2]; add_box(tmp, xval, yval, zval, width, height, depth); matrix_mult(s->data[s->top], tmp); draw_polygons(tmp, t, g); break; case SPHERE: empty_matrix(tmp); xval = op[i].op.sphere.d[0]; yval = op[i].op.sphere.d[1]; zval = op[i].op.sphere.d[2]; double radius = op[i].op.sphere.r; add_sphere(tmp, xval, yval, zval, radius, step); matrix_mult(s->data[s->top], tmp); draw_polygons(tmp, t, g); break; case TORUS: empty_matrix(tmp); xval = op[i].op.torus.d[0]; yval = op[i].op.torus.d[1]; zval = op[i].op.torus.d[2]; double r1 = op[i].op.torus.r0; double r2 = op[i].op.torus.r1; add_torus(tmp, xval, yval, zval, r1, r2, step); matrix_mult(s->data[s->top], tmp); draw_polygons(tmp, t, g); break; case LINE: empty_matrix(tmp); add_edge(tmp, op[i].op.line.p0[0], op[i].op.line.p0[1], op[i].op.line.p0[2], op[i].op.line.p1[0], op[i].op.line.p1[1], op[i].op.line.p1[2]); draw_lines(tmp, t, g); break; case SAVE: save_extension(t, op[i].op.save.p->name); break; case DISPLAY: display(t); break; } } }
void my_main( int polygons ) { int i; double step = 0.01; double xval, yval, zval; double theta; // rotation angle measure int xyz; // rotation axis double w,h,d; // box dimensions double rad; // sphere/torus radius double rad2; // torus radius 2 struct matrix *transform; struct matrix *tmp; struct stack *s; screen t; color g; g = change_color(6); s = new_stack(); tmp = new_matrix(4, 1000); clear_screen( t ); for (i=0; i<lastop; i++) { switch (op[i].opcode) { case PUSH: //if (i == 0) { tmp = new_matrix(4,4); ident(tmp); //} push(s); continue; case POP: pop(s); continue; case MOVE: xval = op[i].op.move.d[0]; yval = op[i].op.move.d[1]; zval = op[i].op.move.d[2]; transform = make_translate(xval, yval, zval); matrix_mult(s->data[s->top], transform); s->data[s->top] = transform; continue; case SCALE: xval = op[i].op.scale.d[0]; yval = op[i].op.scale.d[1]; zval = op[i].op.scale.d[2]; transform = make_scale(xval, yval, zval); matrix_mult(s->data[s->top], transform); s->data[s->top] = transform; continue; case ROTATE: xyz = op[i].op.rotate.axis; theta = op[i].op.rotate.degrees; if (xyz == 0) transform = make_rotX(theta); if (xyz == 1) transform = make_rotY(theta); if (xyz == 2) transform = make_rotZ(theta); matrix_mult(s->data[s->top], transform); s->data[s->top] = transform; continue; case BOX: xval = op[i].op.box.d0[0]; yval = op[i].op.box.d0[1]; zval = op[i].op.box.d0[2]; w = op[i].op.box.d1[0]; h = op[i].op.box.d1[1]; d = op[i].op.box.d1[2]; add_box(tmp, xval, yval, zval, w, h, d); matrix_mult(s->data[s->top], tmp); draw_polygons(tmp, t, g); continue; case SPHERE: xval = op[i].op.sphere.d[0]; yval = op[i].op.sphere.d[1]; zval = op[i].op.sphere.d[2]; rad = op[i].op.sphere.r; add_sphere(tmp, xval, yval, zval, rad, step); matrix_mult(s->data[s->top], tmp); draw_polygons(tmp, t, g); continue; case TORUS: xval = op[i].op.torus.d[0]; yval = op[i].op.torus.d[1]; zval = op[i].op.torus.d[2]; rad = op[i].op.torus.r0; rad2 = op[i].op.torus.r1; add_torus(tmp, xval, yval, zval, rad, rad2, step); matrix_mult(s->data[s->top], tmp); draw_polygons(tmp, t, g); continue; case LINE: xval = op[i].op.line.p0[0]; yval = op[i].op.line.p0[1]; zval = op[i].op.line.p0[2]; w = op[i].op.line.p1[0]; h = op[i].op.line.p1[1]; d = op[i].op.line.p1[2]; add_edge(tmp, xval, yval, zval, w, h, d); matrix_mult(s->data[s->top], tmp); draw_lines(tmp, t, g); continue; case SAVE: save_extension(t, op[i].op.save.p->name); continue; case DISPLAY: display(t); continue; case COMMENT: continue; } } }
void my_main( int polygons ) { int i; double step; double xval, yval, zval; struct matrix *transform; struct matrix *temp; struct stack *stax; screen t; color g; g.red = 225; g.blue = 0; g.green = 0; stax = new_stack(); temp = new_matrix(4, 1000); transform = new_matrix(4, 4); clear_screen( t ); for (i=0;i<lastop;i++) { switch (op[i].opcode) { case BOX: add_box(temp, op[i].op.box.d0[0], op[i].op.box.d0[1], op[i].op.box.d0[2], op[i].op.box.d1[0], op[i].op.box.d1[1], op[i].op.box.d1[2]); matrix_mult(stax->data[stax->top], temp); draw_polygons(temp, t, g); free_matrix(temp); break; case SPHERE: add_sphere(temp, op[i].op.sphere.d[0], op[i].op.sphere.d[1], op[i].op.sphere.d[2], op[i].op.sphere.r, 10); matrix_mult(stax->data[stax->top], temp); draw_polygons(temp, t, g); free_matrix(temp); break; case TORUS: add_torus(temp, op[i].op.torus.d[0], op[i].op.torus.d[1], op[i].op.torus.d[2], op[i].op.torus.r0,op[i].op.torus.r1, 10); matrix_mult(stax->data[stax->top], temp); draw_polygons(temp, t, g); free_matrix(temp); break; case SCALE: transform = make_scale(op[i].op.scale.d[0], op[i].op.scale.d[1], op[i].op.scale.d[2]); matrix_mult(stax->data[stax->top], transform); copy_matrix(transform, stax->data[stax->top]); free_matrix(transform); break; case MOVE: transform = make_translate(op[i].op.move.d[0], op[i].op.move.d[1], op[i].op.move.d[2]); matrix_mult(stax->data[stax->top], transform); copy_matrix(transform, stax->data[stax->top]); free_matrix(transform); break; case PUSH: push(stax); break; case POP: pop(stax); break; case ROTATE: if (op[i].op.rotate.axis == 0) //case X transform = make_rotX(op[i].op.rotate.degrees * M_PI/180 ); else if (op[lastop].op.rotate.axis == 1) //case Y transform = make_rotY(op[i].op.rotate.degrees * M_PI/180 ); else if (op[lastop].op.rotate.axis == 2) //case Z transform = make_rotZ(op[i].op.rotate.degrees * M_PI/180 ); matrix_mult(stax->data[stax->top], transform); copy_matrix(transform, stax->data[stax->top]); free_matrix(transform); break; case LINE: add_edge(temp, op[i].op.line.p0[0],op[i].op.line.p0[1],op[i].op.line.p0[2], op[i].op.line.p1[0],op[i].op.line.p1[1],op[i].op.line.p1[2]); matrix_mult(stax->data[stax->top], temp); draw_lines(temp, t, g); free_matrix(temp); break; case SAVE: save_extension(t,op[i].op.save.p->name); break; case DISPLAY: display(t); break; } } free_matrix(temp); free_matrix(transform); free_stack(stax); }
/*======== void my_main() ========== Inputs: int polygons Returns: This is the main engine of the interpreter, it should handle most of the commadns in mdl. If frames is not present in the source (and therefore num_frames is 1, then process_knobs should be called. If frames is present, the enitre op array must be applied frames time. At the end of each frame iteration save the current screen to a file named the provided basename plus a numeric string such that the files will be listed in order, then clear the screen and reset any other data structures that need it. Important note: you cannot just name your files in regular sequence, like pic0, pic1, pic2, pic3... if that is done, then pic1, pic10, pic11... will come before pic2 and so on. In order to keep things clear, add leading 0s to the numeric portion of the name. If you use sprintf, you can use "%0xd" for this purpose. It will add at most x 0s in front of a number, if needed, so if used correctly, and x = 4, you would get numbers like 0001, 0002, 0011, 0487 05/17/12 09:41:35 jdyrlandweaver ====================*/ void my_main (int polygons) { int i, f, j; double step; double xval, yval, zval, knob_value; struct matrix *transform; struct matrix *tmp; struct stack *s; screen t; color g; char q; num_frames = 1; step = 0.05; g.red = 0; g.green = 255; g.blue = 255; s = new_stack (); tmp = new_matrix (4, 1000); clear_screen (t); for (i = 0; i < lastop; i++) { switch (op[i].opcode) { case SPHERE: add_sphere (tmp, op[i].op.sphere.d[0], //cx op[i].op.sphere.d[1], //cy op[i].op.sphere.d[2], //cz op[i].op.sphere.r, step); //apply the current top origin matrix_mult (s->data[s->top], tmp); draw_polygons (tmp, t, g); tmp->lastcol = 0; break; case TORUS: add_torus (tmp, op[i].op.torus.d[0], //cx op[i].op.torus.d[1], //cy op[i].op.torus.d[2], //cz op[i].op.torus.r0, op[i].op.torus.r1, step); matrix_mult (s->data[s->top], tmp); draw_polygons (tmp, t, g); tmp->lastcol = 0; break; case BOX: add_box (tmp, op[i].op.box.d0[0], op[i].op.box.d0[1], op[i].op.box.d0[2], op[i].op.box.d1[0], op[i].op.box.d1[1], op[i].op.box.d1[2]); matrix_mult (s->data[s->top], tmp); draw_polygons (tmp, t, g); tmp->lastcol = 0; break; case LINE: add_edge (tmp, op[i].op.line.p0[0], op[i].op.line.p0[1], op[i].op.line.p0[1], op[i].op.line.p1[0], op[i].op.line.p1[1], op[i].op.line.p1[1]); draw_lines (tmp, t, g); tmp->lastcol = 0; break; case MOVE: //get the factors xval = op[i].op.move.d[0]; yval = op[i].op.move.d[1]; zval = op[i].op.move.d[2]; transform = make_translate (xval, yval, zval); //multiply by the existing origin matrix_mult (s->data[s->top], transform); //put the new matrix on the top copy_matrix (transform, s->data[s->top]); free_matrix (transform); break; case SCALE: xval = op[i].op.scale.d[0]; yval = op[i].op.scale.d[1]; zval = op[i].op.scale.d[2]; transform = make_scale (xval, yval, zval); matrix_mult (s->data[s->top], transform); //put the new matrix on the top copy_matrix (transform, s->data[s->top]); free_matrix (transform); break; case ROTATE: xval = op[i].op.rotate.degrees * (M_PI / 180); //get the axis if (op[i].op.rotate.axis == 0) transform = make_rotX (xval); else if (op[i].op.rotate.axis == 1) transform = make_rotY (xval); else if (op[i].op.rotate.axis == 2) transform = make_rotZ (xval); matrix_mult (s->data[s->top], transform); //put the new matrix on the top copy_matrix (transform, s->data[s->top]); free_matrix (transform); break; case PUSH: push (s); break; case POP: pop (s); break; case SAVE: save_extension (t, op[i].op.save.p->name); break; case DISPLAY: display (t); break; } } free_stack (s); free_matrix (tmp); //free_matrix( transform ); }
/*======== void my_main() ========== Inputs: int polygons Returns: This is the main engine of the interpreter, it should handle most of the commadns in mdl. If frames is not present in the source (and therefore num_frames is 1, then process_knobs should be called. If frames is present, the enitre op array must be applied frames time. At the end of each frame iteration save the current screen to a file named the provided basename plus a numeric string such that the files will be listed in order, then clear the screen and reset any other data structures that need it. Important note: you cannot just name your files in regular sequence, like pic0, pic1, pic2, pic3... if that is done, then pic1, pic10, pic11... will come before pic2 and so on. In order to keep things clear, add leading 0s to the numeric portion of the name. If you use sprintf, you can use "%0xd" for this purpose. It will add at most x 0s in front of a number, if needed, so if used correctly, and x = 4, you would get numbers like 0001, 0002, 0011, 0487 05/17/12 09:41:35 jdyrlandweaver ====================*/ void my_main( int polygons ) { int i, j; zbuf = (double **)malloc(500 * sizeof(double*)); for(i = 0; i < 500; i++){ zbuf[i] = (double*)malloc(500 * sizeof(double)); for (j = 0; j < 500; j++){ zbuf[i][j] = -DBL_MAX; } } i = 0; j = 0; int f; double step; double xval, yval, zval, knob_value; struct matrix *transform; struct matrix *tmp; struct stack *s; screen t; color g; char q; clear_screen( t ); num_frames = 1; step = 0.05; g.red = 0; g.green = 125; g.blue = 255; s = new_stack(); tmp = new_matrix(4, 1000); first_pass(); if (num_frames < 0){ printf("ERROR- can't vary knobs when there's only 1 frame.\n"); } if (num_frames >= 1){ struct vary_node ** klist = second_pass(); for (f = 0; f < num_frames; f++){ for ( i = 0; i < 500; i++){ for (j = 0; j < 500; j++){ zbuf[i][j] = -DBL_MAX; } } for (i=0;i<lastop;i++) { struct vary_node* v = klist[f]; SYMTAB * vvv; while ( v != NULL){ //printf("set %s %lf \n",v->name, v->value ); vvv = lookup_symbol(v->name); if (vvv != NULL){ set_value(vvv, v->value); } else{ add_symbol(v->name,SYM_VALUE,(void *)&(v->value)); } v = v->next; } //print_knobs(); switch (op[i].opcode) { case SETKNOBS: xval = 0; double abcdef = op[i].op.setknobs.value; //printf("Setting knobs to %lf.\n",abcdef); for ( i=0; i < lastsym; i++ ) { if ( symtab[i].type == SYM_VALUE ) { set_value(&(symtab[i]), abcdef); } } break; case SPHERE: add_sphere( tmp,op[i].op.sphere.d[0], //cx op[i].op.sphere.d[1], //cy op[i].op.sphere.d[2], //cz op[i].op.sphere.r, step); //apply the current top origin matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case TORUS: add_torus( tmp, op[i].op.torus.d[0], //cx op[i].op.torus.d[1], //cy op[i].op.torus.d[2], //cz op[i].op.torus.r0, op[i].op.torus.r1, step); matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case BOX: add_box( tmp, op[i].op.box.d0[0], op[i].op.box.d0[1], op[i].op.box.d0[2], op[i].op.box.d1[0], op[i].op.box.d1[1], op[i].op.box.d1[2]); matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case LINE: add_edge( tmp, op[i].op.line.p0[0], op[i].op.line.p0[1], op[i].op.line.p0[1], op[i].op.line.p1[0], op[i].op.line.p1[1], op[i].op.line.p1[1]); draw_lines( tmp, t, g ); tmp->lastcol = 0; break; case MOVE: //get the factors xval = op[i].op.move.d[0]; yval = op[i].op.move.d[1]; zval = op[i].op.move.d[2]; //printf("MOVE %lf %lf %lf\n",xval,yval,zval); if (op[i].op.move.p != NULL){ SYMTAB* thing = (lookup_symbol(op[i].op.move.p->name)); xval *= thing->s.value; yval *= thing->s.value; zval *= thing->s.value; //printf("new MOVE %lf %lf %lf\n",xval,yval,zval); } transform = make_translate( xval, yval, zval ); //multiply by the existing origin matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case SCALE: xval = op[i].op.scale.d[0]; yval = op[i].op.scale.d[1]; zval = op[i].op.scale.d[2]; //printf("scalE %lf %lf %lf\n",xval,yval,zval); if (op[i].op.scale.p != NULL){ SYMTAB* thing = (lookup_symbol(op[i].op.scale.p->name)); xval *= thing->s.value; yval *= thing->s.value; zval *= thing->s.value; //printf("new scale %lf %lf %lf\n",xval,yval,zval); } transform = make_scale( xval, yval, zval ); matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case ROTATE: xval = op[i].op.rotate.degrees * ( M_PI / 180 ); //printf("rotate %lf\n",xval); if (op[i].op.rotate.p != NULL){ xval *= (lookup_symbol(op[i].op.rotate.p->name))->s.value; //printf("new rotate%lf\n",xval); } //get the axis if ( op[i].op.rotate.axis == 0 ) transform = make_rotX( xval ); else if ( op[i].op.rotate.axis == 1 ) transform = make_rotY( xval ); else if ( op[i].op.rotate.axis == 2 ) transform = make_rotZ( xval ); matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case PUSH: push( s ); break; case POP: pop( s ); break; case SAVE: save_extension( t, op[i].op.save.p->name ); break; case DISPLAY: display( t ); break; } } if (num_frames > 1){ char nopq[256]; char rst[256]; strcpy(nopq,"animations/"); strcat(nopq, name); sprintf (rst, "%03d", f ); strcat(nopq,rst); strcat(nopq,".png"); //printf("Saved frame %d to %s\n", (f+1) ,nopq); save_extension( t, nopq ); clear_screen( t ); screen t; g.red = 0; g.green = 255; g.blue = 255; free_stack( s ); free_matrix( tmp ); s = new_stack(); tmp = new_matrix(4, 1000); } //printf("finished frame %d\n",f); } //////////////////////////////////////////////////////////// for (j = 0; j < num_frames; j++){ struct vary_node * v2 = klist[j]; struct vary_node * v = klist[j]; while (v2 != NULL){ v = v2; v2 = v2->next; free(v); } } free(klist); } //////////////////////////////////////////////// free_stack( s ); free_matrix( tmp ); for(i = 0; i < 500; i++){ free(zbuf[i]); } free(zbuf); //free_matrix( transform ); }
/*======== void my_main() ========== Inputs: Returns: This is the main engine of the interpreter, it should handle most of the commadns in mdl. If frames is not present in the source (and therefore num_frames is 1, then process_knobs should be called. If frames is present, the enitre op array must be applied frames time. At the end of each frame iteration save the current screen to a file named the provided basename plus a numeric string such that the files will be listed in order, then clear the screen and reset any other data structures that need it. Important note: you cannot just name your files in regular sequence, like pic0, pic1, pic2, pic3... if that is done, then pic1, pic10, pic11... will come before pic2 and so on. In order to keep things clear, add leading 0s to the numeric portion of the name. If you use sprintf, you can use "%0xd" for this purpose. It will add at most x 0s in front of a number, if needed, so if used correctly, and x = 4, you would get numbers like 0001, 0002, 0011, 0487 05/17/12 09:41:35 jdyrlandweaver ====================*/ void my_main( int polygons ) { int i, f, j; double step; double xval, yval, zval, knob_value; struct matrix *transform; struct matrix *tmp; struct stack *s; screen t; color g; struct vary_node **knobs; struct vary_node *vn; char frame_name[128]; num_frames = 1; step = 5; f=0; g.red = 0; g.green = 255; g.blue = 255; first_pass(); knobs = second_pass(); for(f = 0;f<num_frames; f++){ struct vary_node *curr = (struct vary_node *)calloc(1, sizeof(struct vary_node)); curr = knobs[f]; while(curr){ printf("%s : %f\n", curr->name, curr->value); curr = curr->next; } } for(f=0;f<num_frames;f++){ s = new_stack(); tmp = new_matrix(4, 4); transform = new_matrix(4, 4); if(num_frames>1){ vn = knobs[f]; while(vn){ SYMTAB *symb = lookup_symbol(vn->name); set_value(symb, vn->value); vn = vn->next; } } //print_knobs(); for (i=0;i<lastop;i++) { SYMTAB *v; switch (op[i].opcode) { case SPHERE: //printf("Add sphere\n"); add_sphere( tmp,op[i].op.sphere.d[0], //cx op[i].op.sphere.d[1], //cy op[i].op.sphere.d[2], //cz op[i].op.sphere.r, step); //apply the current top origin matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case TORUS: //printf("Add Torus\n"); add_torus( tmp, op[i].op.torus.d[0], //cx op[i].op.torus.d[1], //cy op[i].op.torus.d[2], //cz op[i].op.torus.r0, op[i].op.torus.r1, step); matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case BOX: //printf("Add box\n"); add_box( tmp, op[i].op.box.d0[0], op[i].op.box.d0[1], op[i].op.box.d0[2], op[i].op.box.d1[0], op[i].op.box.d1[1], op[i].op.box.d1[2]); matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case LINE: //printf("Line\n"); add_edge( tmp, op[i].op.line.p0[0], op[i].op.line.p0[1], op[i].op.line.p0[1], op[i].op.line.p1[0], op[i].op.line.p1[1], op[i].op.line.p1[1]); draw_lines( tmp, t, g ); tmp->lastcol = 0; break; case MOVE: //printf("Move\n"); //get the factors xval = op[i].op.move.d[0]; yval = op[i].op.move.d[1]; zval = op[i].op.move.d[2]; v = op[i].op.move.p; if(v){ xval = xval * v->s.value; yval = yval * v->s.value; zval = zval * v->s.value; } //printf("x: %f y: %f z: %f\n", xval, yval, zval); transform = make_translate( xval, yval, zval ); //multiply by the existing origin matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case SCALE: //printf("Scale\n"); xval = op[i].op.scale.d[0]; yval = op[i].op.scale.d[1]; zval = op[i].op.scale.d[2]; v = op[i].op.scale.p; if(v){ //printf("I'm not null Scale\n"); xval *= v->s.value; yval *= v->s.value; zval *= v->s.value; } transform = make_scale( xval, yval, zval ); matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case ROTATE: //printf("Rotate\n"); xval = op[i].op.rotate.degrees * ( M_PI / 180 ); v = op[i].op.rotate.p; if(v){ xval *= v->s.value; } //get the axis if ( op[i].op.rotate.axis == 0 ) transform = make_rotX( xval ); else if ( op[i].op.rotate.axis == 1 ) transform = make_rotY( xval ); else if ( op[i].op.rotate.axis == 2 ) transform = make_rotZ( xval ); matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case PUSH: //printf("Push\n"); push( s ); break; case POP: //printf("Pop\n"); pop( s ); break; case SAVE: //printf("Save\n"); save_extension( t, op[i].op.save.p->name ); break; case DISPLAY: //printf("Display\n"); display( t ); break; } } if(num_frames>1){ sprintf (frame_name, "%s%03d.png", name, f); save_extension(t, frame_name); } clear_screen(t); free_stack(s); free_matrix(tmp); } //free_stack( s ); //free_matrix( tmp ); //free_matrix( transform ); }
/*======== void my_main() ========== Inputs: int polygons Returns: This is the main engine of the interpreter, it should handle most of the commadns in mdl. If frames is not present in the source (and therefore num_frames is 1) then process_knobs should be called. If frames is present, the enitre op array must be applied frames time. At the end of each frame iteration save the current screen to a file named the provided basename plus a numeric string such that the files will be listed in order, then clear the screen and reset any other data structures that need it. Important note: you cannot just name your files in regular sequence, like pic0, pic1, pic2, pic3... if that is done, then pic1, pic10, pic11... will come before pic2 and so on. In order to keep things clear, add leading 0s to the numeric portion of the name. If you use sprintf, you can use "%0xd" for this purpose. It will add at most x 0s in front of a number, if needed, so if used correctly, and x = 4, you would get numbers like 0001, 0002, 0011, 0487 05/17/12 09:41:35 jdyrlandweaver ====================*/ void my_main( int polygons ) { int i, f, j, k, frame, num; double step; double xval, yval, zval, knob_value; struct matrix *transform; struct matrix *tmp; struct stack *s; char fname[100]; char number[4]; screen t; color g; char q; step = 0.05; g.red = 0; g.green = 255; g.blue = 255; s = new_stack(); tmp = new_matrix(4, 1000); clear_screen( t ); first_pass(); if(num_frames == -1){ printf("Stop being silly and give num_frames a value please!"); return; } if(num_frames == 0){ for (i=0;i<lastop;i++) { switch (op[i].opcode) { case SPHERE: add_sphere( tmp,op[i].op.sphere.d[0], //cx op[i].op.sphere.d[1], //cy op[i].op.sphere.d[2], //cz op[i].op.sphere.r, step); //apply the current top origin matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case TORUS: add_torus( tmp, op[i].op.torus.d[0], //cx op[i].op.torus.d[1], //cy op[i].op.torus.d[2], //cz op[i].op.torus.r0, op[i].op.torus.r1, step); matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case BOX: add_box( tmp, op[i].op.box.d0[0], op[i].op.box.d0[1], op[i].op.box.d0[2], op[i].op.box.d1[0], op[i].op.box.d1[1], op[i].op.box.d1[2]); matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case LINE: add_edge( tmp, op[i].op.line.p0[0], op[i].op.line.p0[1], op[i].op.line.p0[1], op[i].op.line.p1[0], op[i].op.line.p1[1], op[i].op.line.p1[1]); draw_lines( tmp, t, g ); tmp->lastcol = 0; break; case PUSH: push( s ); break; case POP: pop( s ); break; case SAVE: save_extension( t, op[i].op.save.p->name ); break; case DISPLAY: display( t ); break; } } } else{ struct vary_node **knobs = second_pass(); for(frame = 0; frame < num_frames; frame++){ clear_screen(t); free_stack(s); s = new_stack(); struct vary_node *curr = (struct vary_node *)malloc(sizeof(struct vary_node *)); curr = knobs[frame]; while(curr){ set_value(lookup_symbol(curr->name), curr->value); curr = curr->next; } free(curr); for (i=0;i<lastop;i++) { switch (op[i].opcode) { case SET: set_value(lookup_symbol(op[i].op.set.p->name), op[i].op.set.val); break; case SETKNOBS: for(k=0; k<lastsym; k++){ if(symtab[k].type == SYM_VALUE) symtab[k].s.value = op[i].op.setknobs.value; } break; case SPHERE: add_sphere( tmp,op[i].op.sphere.d[0], //cx op[i].op.sphere.d[1], //cy op[i].op.sphere.d[2], //cz op[i].op.sphere.r, step); //apply the current top origin matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case TORUS: add_torus( tmp, op[i].op.torus.d[0], //cx op[i].op.torus.d[1], //cy op[i].op.torus.d[2], //cz op[i].op.torus.r0, op[i].op.torus.r1, step); matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case BOX: add_box( tmp, op[i].op.box.d0[0], op[i].op.box.d0[1], op[i].op.box.d0[2], op[i].op.box.d1[0], op[i].op.box.d1[1], op[i].op.box.d1[2]); matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case LINE: add_edge( tmp, op[i].op.line.p0[0], op[i].op.line.p0[1], op[i].op.line.p0[1], op[i].op.line.p1[0], op[i].op.line.p1[1], op[i].op.line.p1[1]); draw_lines( tmp, t, g ); tmp->lastcol = 0; break; case MOVE: //get the factors xval = op[i].op.move.d[0]; yval = op[i].op.move.d[1]; zval = op[i].op.move.d[2]; transform = make_translate( xval, yval, zval ); //multiply by the existing origin matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case SCALE: xval = op[i].op.scale.d[0]; yval = op[i].op.scale.d[1]; zval = op[i].op.scale.d[2]; if (op[i].op.scale.p != NULL){ knob_value = lookup_symbol(op[i].op.scale.p->name)->s.value; xval = xval * knob_value; yval = yval * knob_value; zval = zval * knob_value; } transform = make_scale( xval, yval, zval ); matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case ROTATE: xval = op[i].op.rotate.degrees * ( M_PI / 180 ); if (op[i].op.rotate.p != NULL){ knob_value = lookup_symbol(op[i].op.rotate.p->name)->s.value; xval = xval * knob_value; } //get the axis if ( op[i].op.rotate.axis == 0 ) transform = make_rotX( xval ); else if ( op[i].op.rotate.axis == 1 ) transform = make_rotY( xval ); else if ( op[i].op.rotate.axis == 2 ) transform = make_rotZ( xval ); matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case PUSH: push( s ); break; case POP: pop( s ); break; case SAVE: save_extension( t, op[i].op.save.p->name ); break; case DISPLAY: display( t ); break; } } sprintf(number,"%03d",frame); strcpy(fname,name); strcat(fname,number); strcat(fname,".png"); save_extension(t,fname); printf("Saving %s ...\n",fname); } struct vary_node *current; struct vary_node *previous; int index; for(index = 0; index < num_frames; index++){ current = knobs[index]; previous = knobs[index]; while(current && current->next){ current = current->next; free(previous); previous = current; } free(current); } free_stack( s ); free_matrix( tmp ); //free_matrix( transform ); } }
/*======== void parse_file () ========== Inputs: char * filename struct matrix * transform, struct matrix * pm, screen s Returns: Goes through the file named filename and performs all of the actions listed in that file. The file follows the following format: Every command is a single character that takes up a line Any command that requires arguments must have those arguments in the second line. The commands are as follows: l: add a line to the edge matrix - takes 6 arguments (x0, y0, z0, x1, y1, z1) b: add a hermite curve to the edge matrix - takes 8 arguments (x0, y0, x1, y1, x2, y2, x3, y3) h: add a bezier to the edge matrix - takes 8 arguments (x0, y0, x1, y1, x2, y2, x3, y3) c: add a circle to the edge matrix - takes 3 arguments (cx, cy, r) m: add a sphere to the edge matrix - takes 3 arguments (cx, cy, r) d: add a torus to the edge matrix - takes 4 arguments (cx, cy, r1, r2) p: add a rectangular prism to the edge matrix - takes 6 arguments (x, y, z, width, height, depth) w: clear the current edge matrix - takes 0 arguments i: set the transform matrix to the identity matrix - s: create a scale matrix, then multiply the transform matrix by the scale matrix - takes 3 arguments (sx, sy, sz) t: create a translation matrix, then multiply the transform matrix by the translation matrix - takes 3 arguments (tx, ty, tz) x: create an x-axis rotation matrix, then multiply the transform matrix by the rotation matrix - takes 1 argument (theta) y: create an y-axis rotation matrix, then multiply the transform matrix by the rotation matrix - takes 1 argument (theta) z: create an z-axis rotation matrix, then multiply the transform matrix by the rotation matrix - takes 1 argument (theta) a: apply the current transformation matrix to the edge matrix v: draw the lines of the edge matrix to the screen display the screen g: draw the lines of the edge matrix to the screen save the screen to a file - takes 1 argument (file name) q: end parsing See the file script for an example of the file format IMPORTANT MATH NOTE: the trig functions int math.h use radian mesure, but us normal humans use degrees, so the file will contain degrees for rotations, be sure to conver those degrees to radians (M_PI is the constant for PI) 03/08/12 16:22:10 jdyrlandweaver ====================*/ void parse_file ( char * filename, struct matrix * transform, struct matrix * pm, screen s) { FILE *f; char line[256]; struct matrix * tmp; double angle; color g; g.red = 0; g.green = 255; g.blue = 255; clear_screen(s); if ( strcmp(filename, "stdin") == 0 ) f = stdin; else f = fopen(filename, "r"); while ( fgets(line, 255, f) != NULL ) { line[strlen(line)-1]='\0'; //printf(":%s:\n",line); char c; double x, y, z, x1, y1, z1, x2, y2, x3, y3, x4, y4; c = line[0]; switch (c) { case 'l': // printf("LINE!\n"); fgets(line, 255, f); // printf("\t%s", line); //line[strlen(line)-1]='\0'; sscanf(line, "%lf %lf %lf %lf %lf %lf", &x, &y, &z, &x1, &y1, &z1); add_edge(pm, x, y, z, x1, y1, z1); // printf( "%lf %lf %lf %lf %lf %lf\n", x, y, z, x1, y1, z1); break; case 'p': fgets(line, 255, f); sscanf(line, "%lf %lf %lf %lf %lf %lf", &x, &y, &z, &x1, &y1, &z1); add_box(pm, x, y, z, x1, y1, z1); // printf( "%lf %lf %lf %lf %lf %lf\n", x, y, z, x1, y1, z1); break; case 'm': fgets(line, 255, f); sscanf(line, "%lf %lf %lf", &x, &y, &z); add_sphere(pm, x, y, z, 0.05); //printf( "%lf %lf %lf\n", x, y, z); break; case 'd': fgets(line, 255, f); sscanf(line, "%lf %lf %lf %lf", &x, &y, &z, &z1); add_torus(pm, x, y, z, z1, 0.05); //printf( "%lf %lf %lf\n", x, y, z); break; case 'c': fgets(line, 255, f); sscanf(line, "%lf %lf %lf", &x, &y, &z); add_circle(pm, x, y, z, 0.01); //printf( "%lf %lf %lf\n", x, y, z); break; case 'b': fgets(line, 255, f); sscanf(line, "%lf %lf %lf %lf %lf %lf %lf %lf", &x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4); add_curve(pm, x1, y1, x2, y2, x3, y3, x4, y4, 0.01, BEZIER_MODE ); //printf( "%lf %lf %lf\n", x, y, z); break; case 'h': fgets(line, 255, f); sscanf(line, "%lf %lf %lf %lf %lf %lf %lf %lf", &x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4); add_curve(pm, x1, y1, x2, y2, x3, y3, x4, y4, 0.01, HERMITE_MODE ); //printf( "%lf %lf %lf\n", x, y, z); break; case 's': //printf("SCALE\n"); fgets(line, 255, f); //line[strlen(line)-1]='\0'; sscanf(line, "%lf %lf %lf", &x, &y, &z); tmp = make_scale(x, y, z); matrix_mult(tmp, transform); //print_matrix(transform); break; case 't': //printf("TRANSLATE\n"); fgets(line, 255, f); // line[strlen(line)-1]='\0'; sscanf(line, "%lf %lf %lf", &x, &y, &z); tmp = make_translate(x, y, z); matrix_mult(tmp, transform); //print_matrix(transform); break; case 'x': //printf("ROTATE!\n"); fgets(line, 255, f); sscanf(line, "%lf", &angle); angle = angle * (M_PI / 180); tmp = make_rotX( angle); matrix_mult(tmp, transform); break; case 'y': //printf("ROTATE!\n"); fgets(line, 255, f); sscanf(line, "%lf", &angle); angle = angle * (M_PI / 180); tmp = make_rotY( angle); matrix_mult(tmp, transform); break; case 'z': //printf("ROTATE!\n"); fgets(line, 255, f); sscanf(line, "%lf", &angle); angle = angle * (M_PI / 180); tmp = make_rotZ( angle); matrix_mult(tmp, transform); break; case 'i': ident(transform); break; case 'a': //printf("APPLY!\n"); //print_matrix( transform ); // print_matrix(pm); matrix_mult(transform, pm); break; case 'v': /* clear_screen(s); draw_lines(pm, s, g); display(s); break; */ // Second version for triangles: clear_screen(s); draw_polygons(pm, s, g); display(s); break; case 'w': pm->lastcol = 0; break; case 'g': fgets(line, 255, f); // line[strlen(line)-1] = '\0'; clear_screen(s); draw_polygons(pm, s, g); save_extension(s, line); break; case 'q': return; case '#': break; default: printf("Invalid command\n"); break; } } free_matrix(tmp); fclose(f); //printf("END PARSE\n"); }
/*======== void parse_file () ========== Inputs: char * filename struct matrix * transform, struct matrix * pm, screen s Returns: Goes through the file named filename and performs all of the actions listed in that file. The file follows the following format: Every command is a single character that takes up a line Any command that requires arguments must have those arguments in the second line. The commands are as follows: l: add a line to the edge matrix - takes 6 arguemnts (x0, y0, z0, x1, y1, z1) i: set the transform matrix to the identity matrix - s: create a scale matrix, then multiply the transform matrix by the scale matrix - takes 3 arguments (sx, sy, sz) t: create a translation matrix, then multiply the transform matrix by the translation matrix - takes 3 arguments (tx, ty, tz) x: create an x-axis rotation matrix, then multiply the transform matrix by the rotation matrix - takes 1 argument (theta) y: create an y-axis rotation matrix, then multiply the transform matrix by the rotation matrix - takes 1 argument (theta) z: create an z-axis rotation matrix, then multiply the transform matrix by the rotation matrix - takes 1 argument (theta) a: apply the current transformation matrix to the edge matrix v: draw the lines of the edge matrix to the screen display the screen g: draw the lines of the edge matrix to the screen save the screen to a file - takes 1 argument (file name) q: end parsing See the file script for an example of the file format IMPORTANT MATH NOTE: the trig functions int math.h use radian mesure, but us normal humans use degrees, so the file will contain degrees for rotations, be sure to conver those degrees to radians (M_PI is the constant for PI) jdyrlandweaver ====================*/ void parse_file ( char * filename, struct matrix * transform, struct matrix * pm, screen s) { char temp; float a,b,c,d,e,f,g,h; int i,j; char * ImgName; FILE * file = fopen(filename, "r"); while(fscanf(file,"%c", &temp) ==1){ //add torus if(temp == 'd'){ fscanf(file,"%c",&temp); if(fscanf(file,"%f %f %f %f",&a,&b,&c,&d) == 4) add_torus(pm,a,b,c,d,0.01); else printf("somethings wrong that need to be fix in d"); } //add sphere if(temp == 'm'){ fscanf(file,"%c",&temp); if(fscanf(file,"%f %f %f", &a,&b,&c) == 3) add_sphere(pm,a,b,c,0.01); else printf("somethings wrong that need to be fix in m"); } //add box point if(temp == 'p'){ fscanf(file,"%c",&temp); if(fscanf(file,"%f %f %f %f %f %f",&a,&b,&c,&d,&e,&f) ==6) add_box(pm,a,b,c,d,e,f); else printf("somethings wrong that need to be fix in p\n"); } //add edge if(temp == 'l'){ fscanf(file,"%c",&temp); if(fscanf(file,"%f %f %f %f %f %f",&a,&b,&c,&d,&e,&f) == 6) add_edge(pm,a,b,c,d,e,f); else printf("SomeThings wrong that need to be fix in l\n"); } //add circle if(temp == 'c'){ fscanf(file,"%c", &temp); if(fscanf(file,"%f %f %f",&a,&b,&c) == 3) add_circle(pm,a,b,c,M_PI/20); else printf("fix in c\n"); } //add hermite if(temp == 'h'){ fscanf(file,"%c", &temp); if(fscanf(file,"%f %f %f %f %f %f %f %f", &a, &b,&c,&d,&e,&f,&g,&h) == 8) add_curve(pm,a,b,c,d,e,f,g,h,0.001,0); else printf("fix in h\n"); } //add bezier if(temp == 'b'){ fscanf(file,"%c", &temp); if(fscanf(file, "%f %f %f %f %f %f %f %f", &a, &b,&c,&d,&e,&f,&g,&h) == 8) add_curve(pm,a,b,c,d,e,f,g,h,0.001,1); else printf("fix in b\n"); } //ident transform else if(temp == 'i'){ ident(transform); } //scaling else if(temp == 's'){ fscanf(file,"%c",&temp); if(fscanf(file,"%f %f %f", &a,&b,&c) == 3){ struct matrix * scalar = make_scale(a,b,c); matrix_mult(scalar,transform); } else printf("Somethings wrong that need to be fix in s\n"); } //Translating else if (temp == 't'){ fscanf(file,"%c",&temp); if(fscanf(file,"%f %f %f", &d,&e,&f) == 3){ struct matrix * tranlator = make_translate(d,e,f); matrix_mult(tranlator, transform); } else printf("somethings wrong that need to be fix in t\n"); } //Rotating with x else if(temp == 'x'){ fscanf(file,"%c",&temp); if(fscanf(file,"%f",&a) ==1){ struct matrix * rotX = make_rotX(a); matrix_mult(rotX,transform); } else{ printf("something wrong that need to be fix in x\n"); } } //Rotating with Y else if(temp == 'y'){ fscanf(file,"%c",&temp); if(fscanf(file,"%f",&b) ==1){ struct matrix * rotY = make_rotY(b); matrix_mult(rotY,transform); } else{ printf("something wrong that need to be fix in y\n"); } } //Rotating with Z else if(temp == 'z'){ fscanf(file,"%c",&temp); if(fscanf(file,"%f",&c) ==1){ struct matrix * rotZ = make_rotZ(a); matrix_mult(rotZ,transform); } else{ printf("something wrong that need to be fix in z\n"); } } //Applying Transformation else if(temp == 'a'){ matrix_mult(transform,pm); } else if(temp == 'v'){ color c; c.red = 122; c.green = 218; c.blue = 225; clear_screen(s); for( i=0; i<XRES; i++){ for ( j=0; j<YRES; j++){ //c.red = random() % (MAX_COLOR + 1); //c.green = random() % (MAX_COLOR + 1); //c.blue = random() % (MAX_COLOR + 1); plot( s, c, i, j); } } c.green = 40; draw_lines(pm,s,c); display(s); } else if(temp == 'g'){ color c; c.red = 122; c.green = 218; c.blue = 225; clear_screen(s); for( i=0; i<XRES; i++){ for ( j=0; j<YRES; j++){ //c.red = random() % (MAX_COLOR + 1); //c.green = random() % (MAX_COLOR + 1); //c.blue = random() % (MAX_COLOR + 1); plot( s, c, i, j); } } c.green = 40; draw_lines(pm,s,c); ImgName = (char *)malloc(256); fscanf(file,"%c",&temp); if(fscanf(file,"%s",ImgName) ==1){ ImgName = strsep(&ImgName, "."); save_ppm(s,ImgName); ImgName = strncat(ImgName,".png",4); save_extension(s,ImgName); free(ImgName); } else printf("Something wrong that need to be fix in g\n"); } else if (temp == 'q'){ return; } } }
/*======== void parse_file () ========== Inputs: char * filename struct matrix * transform, struct matrix * pm, screen s Returns: Goes through the file named filename and performs all of the actions listed in that file. The file follows the following format: Every command is a single character that takes up a line Any command that requires arguments must have those arguments in the second line. The commands are as follows: line: add a line to the edge matrix - takes 6 arguemnts (x0, y0, z0, x1, y1, z1) circle: add a circle to the edge matrix - takes 3 arguments (cx, cy, r) hermite: add a hermite curve to the edge matrix - takes 8 arguments (x0, y0, x1, y1, x2, y2, x3, y3) bezier: add a bezier curve to the edge matrix - takes 8 arguments (x0, y0, x1, y1, x2, y2, x3, y3) ident: set the transform matrix to the identity matrix - scale: create a scale matrix, then multiply the transform matrix by the scale matrix - takes 3 arguments (sx, sy, sz) translate: create a translation matrix, then multiply the transform matrix by the translation matrix - takes 3 arguments (tx, ty, tz) xrotate: create an x-axis rotation matrix, then multiply the transform matrix by the rotation matrix - takes 1 argument (theta) yrotate: create an y-axis rotation matrix, then multiply the transform matrix by the rotation matrix - takes 1 argument (theta) zrotate: create an z-axis rotation matrix, then multiply the transform matrix by the rotation matrix - takes 1 argument (theta) apply: apply the current transformation matrix to the edge matrix display: draw the lines of the edge matrix to the screen display the screen save: draw the lines of the edge matrix to the screen save the screen to a file - takes 1 argument (file name) quit: end parsing See the file script for an example of the file format IMPORTANT MATH NOTE: the trig functions int math.h use radian mesure, but us normal humans use degrees, so the file will contain degrees for rotations, be sure to conver those degrees to radians (M_PI is the constant for PI) ====================*/ void parse_file ( char * filename, struct matrix * transform, struct matrix * pm, screen s) { FILE *f; char line[256]; struct matrix * tmp; double angle; color g; g.red = 255; g.green = 0; g.blue = 255; clear_screen(s); if ( strcmp(filename, "stdin") == 0 ) f = stdin; else f = fopen(filename, "r"); while ( fgets(line, 255, f) != NULL ) { line[strlen(line)-1]='\0'; //printf(":%s:\n",line); double x, y, z, x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4; double width, height, depth, radius, radius1, radius2; if ( strncmp(line, "line", strlen(line)) == 0 ) { // printf("LINE!\n"); fgets(line, 255, f); // printf("\t%s", line); //line[strlen(line)-1]='\0'; sscanf(line, "%lf %lf %lf %lf %lf %lf", &x, &y, &z, &x1, &y1, &z1); add_edge(pm, x, y, z, x1, y1, z1); // printf( "%lf %lf %lf %lf %lf %lf\n", x, y, z, x1, y1, z1); } else if ( strncmp(line, "circle", strlen(line)) == 0 ) { //printf("CIRCLE\n"); fgets(line, 255, f); sscanf(line, "%lf %lf %lf", &x, &y, &z); add_circle(pm, x, y, z, 0.01); //printf( "%lf %lf %lf\n", x, y, z); } else if ( strncmp(line, "bezier", strlen(line)) == 0 ) { //printf("BEZIER\n"); fgets(line, 255, f); sscanf(line, "%lf %lf %lf %lf %lf %lf %lf %lf", &x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4); add_curve(pm, x1, y1, x2, y2, x3, y3, x4, y4, 0.01, BEZIER_MODE ); //printf( "%lf %lf %lf\n", x, y, z); } else if ( strncmp(line, "hermite", strlen(line)) == 0 ) { //printf("HERMITE\n"); fgets(line, 255, f); sscanf(line, "%lf %lf %lf %lf %lf %lf %lf %lf", &x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4); add_curve(pm, x1, y1, x2, y2, x3, y3, x4, y4, 0.01, HERMITE_MODE ); //printf( "%lf %lf %lf\n", x, y, z); } else if ( strncmp(line, "box", strlen(line)) == 0 ) { //printf("BOX\n"); fgets(line, 255, f); sscanf(line, "%lf %lf %lf %lf %lf %lf", &x, &y, &z, &width, &height, &depth); add_box(pm, x, y, z, width, height, depth); //printf( "%lf %lf %lf\n", x, y, z); } else if ( strncmp(line, "sphere", strlen(line)) == 0 ) { //printf("SPHERE\n"); fgets(line, 255, f); sscanf(line, "%lf %lf %lf", &x, &y, &radius); add_sphere(pm, x, y, radius, 0.01); //printf( "%lf %lf %lf\n", x, y, z); } else if ( strncmp(line, "torus", strlen(line)) == 0 ) { //printf("TORUS\n");ds fgets(line, 255, f); sscanf(line, "%lf %lf %lf %lf", &x, &y, &radius1, &radius2 ); add_torus(pm, x, y, radius1, radius2, 0.01); //printf( "%lf %lf %lf\n", x, y, z); } else if ( strncmp(line, "scale", strlen(line)) == 0 ) { //printf("SCALE\n"); fgets(line, 255, f); //line[strlen(line)-1]='\0'; sscanf(line, "%lf %lf %lf", &x, &y, &z); tmp = make_scale(x, y, z); matrix_mult(tmp, transform); //print_matrix(transform); } else if ( strncmp(line, "translate", strlen(line)) == 0 ) { //printf("TRANSLATE\n"); fgets(line, 255, f); // line[strlen(line)-1]='\0'; sscanf(line, "%lf %lf %lf", &x, &y, &z); tmp = make_translate(x, y, z); matrix_mult(tmp, transform); //print_matrix(transform); } else if ( strncmp(line, "xrotate", strlen(line)) == 0 ) { //printf("ROTATE!\n"); fgets(line, 255, f); sscanf(line, "%lf", &angle); angle = angle * (M_PI / 180); tmp = make_rotX( angle); matrix_mult(tmp, transform); } else if ( strncmp(line, "yrotate", strlen(line)) == 0 ) { //printf("ROTATE!\n"); fgets(line, 255, f); sscanf(line, "%lf", &angle); angle = angle * (M_PI / 180); tmp = make_rotY( angle); matrix_mult(tmp, transform); } else if ( strncmp(line, "zrotate", strlen(line)) == 0 ) { //printf("ROTATE!\n"); fgets(line, 255, f); sscanf(line, "%lf", &angle); angle = angle * (M_PI / 180); tmp = make_rotZ( angle); matrix_mult(tmp, transform); } else if ( strncmp(line, "ident", strlen(line)) == 0 ) { ident(transform); } else if ( strncmp(line, "apply", strlen(line)) == 0 ) { //printf("APPLY!\n"); //print_matrix( transform ); // print_matrix(pm); matrix_mult(transform, pm); } else if ( strncmp(line, "display", strlen(line)) == 0 ) { clear_screen(s); draw_lines(pm, s, g); display(s); } else if ( strncmp(line, "save", strlen(line)) == 0 ) { fgets(line, 255, f); // line[strlen(line)-1] = '\0'; clear_screen(s); draw_lines(pm, s, g); save_extension(s, line); } else if ( strncmp(line, "clear", strlen(line)) == 0 ) { fgets(line, 255, f); // line[strlen(line)-1] = '\0'; clear_screen(s); } else if ( strncmp(line, "quit", strlen(line)) == 0 ) { return; } else if (strncmp(line, "#", strlen(1)) == 0){ } else { printf("Invalid command\n"); } } free_matrix(tmp); fclose(f); //printf("END PARSE\n"); }
/*======== void my_main() ========== Inputs: int polygons Returns: This is the main engine of the interpreter, it should handle most of the commadns in mdl. If frames is not present in the source (and therefore num_frames is 1, then process_knobs should be called. If frames is present, the enitre op array must be applied frames time. At the end of each frame iteration save the current screen to a file named the provided basename plus a numeric string such that the files will be listed in order, then clear the screen and reset any other data structures that need it. Important note: you cannot just name your files in regular sequence, like pic0, pic1, pic2, pic3... if that is done, then pic1, pic10, pic11... will come before pic2 and so on. In order to keep things clear, add leading 0s to the numeric portion of the name. If you use sprintf, you can use "%0xd" for this purpose. It will add at most x 0s in front of a number, if needed, so if used correctly, and x = 4, you would get numbers like 0001, 0002, 0011, 0487 05/17/12 09:41:35 jdyrlandweaver ====================*/ void my_main( int polygons ) { int i, f, j; double step; double xval, yval, zval, knob_value; struct matrix *transform; struct matrix *tmp; struct stack *s; screen t; color g; char q; extern double zbuff[XRES][YRES]; num_frames = -1; step = 0.05; strcpy(name, "lol\0"); g.red = 0; g.green = 255; g.blue = 255; s = new_stack(); tmp = new_matrix(4, 1000); clear_screen( t ); instantiate_zbuff(); first_pass(); struct vary_node** frames = second_pass(); //test_second_pass(frames); if (num_frames < 2) { for (i=0;i<lastop;i++) { switch (op[i].opcode) { case SPHERE: add_sphere( tmp,op[i].op.sphere.d[0], //cx op[i].op.sphere.d[1], //cy op[i].op.sphere.d[2], //cz op[i].op.sphere.r, step); //apply the current top origin matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case TORUS: add_torus( tmp, op[i].op.torus.d[0], //cx op[i].op.torus.d[1], //cy op[i].op.torus.d[2], //cz op[i].op.torus.r0, op[i].op.torus.r1, step); matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case BOX: add_box( tmp, op[i].op.box.d0[0], op[i].op.box.d0[1], op[i].op.box.d0[2], op[i].op.box.d1[0], op[i].op.box.d1[1], op[i].op.box.d1[2]); matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case LINE: add_edge( tmp, op[i].op.line.p0[0], op[i].op.line.p0[1], op[i].op.line.p0[1], op[i].op.line.p1[0], op[i].op.line.p1[1], op[i].op.line.p1[1]); draw_lines( tmp, t, g ); tmp->lastcol = 0; break; case MOVE: //get the factors xval = op[i].op.move.d[0]; yval = op[i].op.move.d[1]; zval = op[i].op.move.d[2]; transform = make_translate( xval, yval, zval ); //multiply by the existing origin matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case SCALE: xval = op[i].op.scale.d[0]; yval = op[i].op.scale.d[1]; zval = op[i].op.scale.d[2]; transform = make_scale( xval, yval, zval ); matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case ROTATE: xval = op[i].op.rotate.degrees * ( M_PI / 180 ); //get the axis if ( op[i].op.rotate.axis == 0 ) transform = make_rotX( xval ); else if ( op[i].op.rotate.axis == 1 ) transform = make_rotY( xval ); else if ( op[i].op.rotate.axis == 2 ) transform = make_rotZ( xval ); matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case PUSH: push( s ); break; case POP: pop( s ); break; case SAVE: save_extension( t, op[i].op.save.p->name ); break; case DISPLAY: display( t ); break; } } } else { int currframe; for (currframe = 0; currframe < num_frames; currframe++) { //Caryy out all commands once per frame. struct vary_node*knobs = frames[currframe]; for (i=0;i<lastop;i++) { switch (op[i].opcode) { /*EXPLANATION case COMMAND: If op[i].op.command.cs == NULL, then no knob is defined for this command. Then do it normally. Otherwise, iterate to the "end. But there are two "ends"... If the value of this knob is -1, you went to the end of the list without finding the corresponding knob. That means it isnt there. Since the command is meant to be varied, but isn't defined for this frame, then don't draw it at this time. If the name of this knob in the linked list matches the name of the corresponding knob, then crry out the command in its knob'd format. */ case SET: while ( (knobs->value != -1) && strcmp( op[i].op.set.p->name, knobs->name ) ) knobs = knobs->next; if (knobs->value == -1) break; knobs->value = op[i].op.set.val; break; case SETKNOBS: while ( knobs->value != -1 ) { knobs->value = op[i].op.set.val; knobs = knobs->next; } break; case SPHERE: if (!op[i].op.sphere.cs) { add_sphere( tmp,op[i].op.sphere.d[0], //cx op[i].op.sphere.d[1], //cy op[i].op.sphere.d[2], //cz op[i].op.sphere.r, step); } else { while ( (knobs->value != -1) && strcmp( op[i].op.sphere.cs->name, knobs->name ) ) knobs = knobs->next; double value = knobs->value; if (value == -1) break; add_sphere( tmp,op[i].op.sphere.d[0], //cx op[i].op.sphere.d[1], //cy op[i].op.sphere.d[2], //cz op[i].op.sphere.r*value, step); } //apply the current top origin matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case TORUS: if (!op[i].op.torus.cs) { add_torus( tmp, op[i].op.torus.d[0], //cx op[i].op.torus.d[1], //cy op[i].op.torus.d[2], //cz op[i].op.torus.r0, op[i].op.torus.r1, step); } else { while ( (knobs->value != -1) && strcmp( op[i].op.torus.cs->name, knobs->name ) ) knobs = knobs->next; double value = knobs->value; if (value == -1) break; add_torus( tmp, op[i].op.torus.d[0], //cx op[i].op.torus.d[1], //cy op[i].op.torus.d[2], //cz op[i].op.torus.r0*value, op[i].op.torus.r1*value, step); } matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case BOX: if (!op[i].op.box.cs) { add_box( tmp, op[i].op.box.d0[0], op[i].op.box.d0[1], op[i].op.box.d0[2], op[i].op.box.d1[0], op[i].op.box.d1[1], op[i].op.box.d1[2]); } else { while ( (knobs->value != -1) && strcmp( op[i].op.box.cs->name, knobs->name ) ) knobs = knobs->next; double value = knobs->value; if (value == -1) break; add_box( tmp, op[i].op.box.d0[0], op[i].op.box.d0[1], op[i].op.box.d0[2], op[i].op.box.d1[0]*value, op[i].op.box.d1[1]*value, op[i].op.box.d1[2]*value); } matrix_mult( s->data[ s->top ], tmp ); draw_polygons( tmp, t, g ); tmp->lastcol = 0; break; case LINE: add_edge( tmp, op[i].op.line.p0[0], op[i].op.line.p0[1], op[i].op.line.p0[1], op[i].op.line.p1[0], op[i].op.line.p1[1], op[i].op.line.p1[1]); draw_lines( tmp, t, g ); tmp->lastcol = 0; break; case MOVE: //get the factors xval = op[i].op.move.d[0]; yval = op[i].op.move.d[1]; zval = op[i].op.move.d[2]; transform = make_translate( xval, yval, zval ); //multiply by the existing origin matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case SCALE: if (!op[i].op.scale.p) { xval = op[i].op.scale.d[0]; yval = op[i].op.scale.d[1]; zval = op[i].op.scale.d[2]; } else { while ( (knobs->value != -1) && strcmp( op[i].op.scale.p->name, knobs->name ) ) knobs = knobs->next; double value = knobs->value; if (value == -1) break; xval = op[i].op.scale.d[0]*value; yval = op[i].op.scale.d[1]*value; zval = op[i].op.scale.d[2]*value; } transform = make_scale( xval, yval, zval ); matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case ROTATE: if (!op[i].op.rotate.p) { xval = op[i].op.rotate.degrees * ( M_PI / 180 ); } else { while ( (knobs->value != -1) && strcmp( op[i].op.rotate.p->name, knobs->name ) ) knobs = knobs->next; double value = knobs->value; if (value == -1) break; xval = op[i].op.rotate.degrees * ( M_PI / 180 ) * value; } //get the axis if ( op[i].op.rotate.axis == 0 ) transform = make_rotX( xval ); else if ( op[i].op.rotate.axis == 1 ) transform = make_rotY( xval ); else if ( op[i].op.rotate.axis == 2 ) transform = make_rotZ( xval ); matrix_mult( s->data[ s->top ], transform ); //put the new matrix on the top copy_matrix( transform, s->data[ s->top ] ); free_matrix( transform ); break; case PUSH: push( s ); break; case POP: pop( s ); break; case SAVE: save_extension( t, op[i].op.save.p->name ); break; case DISPLAY: display( t ); break; } } char framename[256]; mkdir("animation", 0777); sprintf(framename, "animation/%s%04d.png", name, currframe); save_extension( t, framename); clear_screen( t ); } } free_stack( s ); free_matrix( tmp ); //free_matrix( transform ); }