#include #include #include #include #include #include #define LIGHT 10 #define SPHERE 11 class material_t { public: material_t(); material_t(FILE *); int load_material(FILE *); void dump_material(FILE *); protected: double ambient[3]; /* Reflectivity for materials */ double diffuse[3]; double specular[3]; }; int material_t::load_material( FILE *in) { int sum = 0; char buf[256]; sum += fscanf(in, "%lf %lf %lf", ambient + 0, ambient + 1, ambient + 2); fgets(buf, 256, in); sum += fscanf(in, "%lf %lf %lf", diffuse + 0, diffuse + 1, diffuse + 2); fgets(buf, 256, in); sum += fscanf(in, "%lf %lf %lf", specular + 0, specular + 1, specular + 2); fgets(buf, 256, in); return(sum); } material_t::material_t(){} material_t::material_t( FILE *in) { int sum = 0; char buf[256]; sum += fscanf(in, "%lf %lf %lf", ambient + 0, ambient + 1, ambient + 2); fgets(buf, 256, in); sum += fscanf(in, "%lf %lf %lf", diffuse + 0, diffuse + 1, diffuse + 2); fgets(buf, 256, in); sum += fscanf(in, "%lf %lf %lf", specular + 0, specular + 1, specular + 2); fgets(buf, 256, in); if (sum != 9) { fprintf(stderr, "Material load failed with %d points \n", sum); exit(2); } } void material_t::dump_material( FILE *out) { fprintf(out, "Ambient - "); fprintf(out, "%6.2lf %6.2lf %6.2lf \n", ambient[0], ambient[1], ambient[2]); fprintf(out, "Diffuse - "); fprintf(out, "%6.2lf %6.2lf %6.2lf \n", diffuse[0], diffuse[1], diffuse[2]); fprintf(out, "Specular - "); fprintf(out, "%6.2lf %6.2lf %6.2lf \n", specular[0], specular[1], specular[2]); } class illum_t { public: illum_t(); illum_t(FILE *); void dump_illum(FILE *); protected: double emissivity[3]; /* Emissivity for lights */ }; void illum_t::dump_illum( FILE *out) { fprintf(out, "Emmisivity - "); fprintf(out, "%6.2lf %6.2lf %6.2lf \n", emissivity[0], emissivity[1], emissivity[2]); } illum_t::illum_t(){} illum_t::illum_t( FILE *in) { int rc; rc = fscanf(in, "%6.2lf %6.2lf %6.2lf \n", emissivity + 0, emissivity + 1, emissivity + 2); if (rc != 3) { fprintf(stderr, "load illum got %d values \n", rc); exit(1); } } //=============================== class obj_t { public: obj_t(); obj_t(int, int); double (*hits)(void); void (*uninorm)(void); void dump_core(FILE *); virtual void dump_obj(FILE *){}; /* Optional plugins for retrieval of reflectivity */ /* useful for the ever-popular tiled floor */ void (*getamb)(void); void (*getdiff)(void); void (*getspec)(void); public: int objid; int objtype; void *priv; /* Private type-dependent data */ double hitloc[3]; /* Last hit point */ double normal[3]; /* Normal at hit point */ }; /* Absence of this fellow creates havoc at link */ /* time <=> inheritence is in play. */ obj_t::obj_t() { printf("obj_t null constructor \n"); } obj_t::obj_t( int otype, int oid) { printf("obj_t oid constructor \n"); objid = oid; objtype = otype; } void obj_t::dump_core(FILE *out) { fprintf(out, "Type = %d and ID = %d \n", objtype, objid); } //=============================================== class sphere_t: public obj_t, public material_t { public: sphere_t(); sphere_t(FILE *, FILE *); sphere_t(FILE *, FILE *, int otype, int oid); virtual void dump_obj(FILE *); protected: double center[3]; double radius; }; sphere_t::sphere_t(){} sphere_t::sphere_t( FILE *in, FILE *out) { printf("sphere_t constructed with in/on \n"); } sphere_t::sphere_t( FILE *in, FILE *out, int otype, int oid) : obj_t(otype, oid), material_t(in) { int pcount; char buf[256]; printf("sphere_t constructed with in/on/ot/oi \n"); pcount = fscanf(in, "%lf %lf %lf", center + 0, center + 1, center + 2); fgets(buf, 256, in); pcount += fscanf(in, "%lf", &radius); fgets(buf, 256, in); if (pcount != 4) { fprintf(stderr, "Sphere geom loaded %d points \n", pcount); exit(1); } } void sphere_t::dump_obj( FILE *out) { fprintf(out, "\nSphere data \n"); dump_core(out); fprintf(out, "Center \n"); fprintf(out, "%6.2lf %6.2lf %6.2lf \n", center[0], center[1], center[2]); fprintf(out, "Radius \n"); fprintf(out, "%6.2lf \n", radius); dump_material(out); } class light_t: public illum_t, public sphere_t { public: light_t(); light_t(FILE *, FILE *, int otype, int oid); virtual void dump_obj(FILE *); }; light_t::light_t( FILE *in, FILE *out, int otype, int oid) : illum_t(in), sphere_t(in, out, otype, oid) { int pcount; char buf[256]; printf("light_t constructed with in/on/ot/oi \n"); } void light_t::dump_obj( FILE *out) { fprintf(out, "\nLight data \n"); dump_core(out); fprintf(out, "Center \n"); fprintf(out, "%6.2lf %6.2lf %6.2lf \n", center[0], center[1], center[2]); fprintf(out, "Radius \n"); fprintf(out, "%6.2lf \n", radius); dump_illum(out); } //=================================== class link_t { public: link_t(void); // constructor link_t(obj_t *); // constructor void set_next(link_t *); link_t *get_next(); obj_t *get_object(); private: link_t *next; obj_t *obj; }; link_t::link_t(obj_t *newobj) { next = NULL; obj = newobj; } void link_t::set_next(link_t *new_next) { next = new_next; } link_t * link_t::get_next() { return(next); } obj_t * link_t::get_object() { return(obj); } class list_t { public: list_t(void); // constructor void add(obj_t *obj); // add object to end of list link_t *start(); // set current to start of list link_t *next(); // advance to next element in list obj_t *access(); // return current object private: link_t *first; link_t *last; link_t *current; }; void list_t::add(obj_t *obj) { link_t *link; link = new link_t(obj); if (first == NULL) { first = last = link; } else { last->set_next(link); last = link; } } link_t * list_t::start(void) { current = first; return(current); } link_t * list_t::next(void) { link_t *link; link = current->get_next(); if (link != NULL) current = link; return(link); } obj_t * list_t::access(void) { return(current->get_object()); } class view_t { public: view_t(void); view_t(FILE *in, FILE *out); int load_view(FILE *); void print_view(FILE *); private: int win_x_size; int win_y_size; double world_x_size; double world_y_size; double viewpt[3]; }; class model_t { public: model_t(); model_t(FILE *in, FILE *out); private: class view_t *view; class list_t *list; }; /**/ /* Constructor for the model_t class. */ model_t::model_t( FILE *in, FILE *out) { int objtype; sphere_t *sphere; light_t *light; int objid = 0; obj_t *obj; link_t *link; view = new view_t(in, out); list = new list_t(); while (fscanf(in, "%d", &objtype) == 1) { switch (objtype) { case SPHERE: sphere = new sphere_t(in, out, objtype, objid); list->add(sphere); case LIGHT: light = new light_t(in, out, objtype, objid); list->add(light); default: ; } objid += 1; } link = list->start(); while (link != NULL) { obj = list->access(); obj->dump_obj(out); link = list->next(); } } view_t::view_t(void) { } view_t::view_t(FILE *in, FILE *out) { load_view(in); print_view(out); } link_t::link_t(void) { next = NULL; obj = NULL; } list_t::list_t(void) { first = last = NULL; } int view_t::load_view(FILE *in) { int vc; char buf[256]; vc = fscanf(in, "%lf %lf", &world_x_size, &world_y_size); fgets(buf, 256, in); vc += fscanf(in, "%lf %lf %lf", viewpt, viewpt + 1, viewpt + 2); fgets(buf, 256, in); if (vc == 5) return(0); else return(-1); } void view_t::print_view(FILE *out) { fprintf(out, "World to window mapping \n"); fprintf(out, "%6.0lf %6.0lf \n", world_x_size, world_y_size); fprintf(out, "\nViewpoint \n"); fprintf(out, "%6.1lf %6.1lf %6.1lf\n", viewpt[0], viewpt[1], viewpt[2]); return; } int main() { model_t model(stdin, stderr); }