#include
#include "scene_parser.h"
#include "camera.h"
#include "sphere.h"
#include "group.h"
// ====================================================================
// ====================================================================
// CONSTRUCTORS, DESTRUCTOR & INITIALIZE
SceneParser::SceneParser() {
initialize();
}
SceneParser::SceneParser(const char* filename) {
initialize();
// open the file
assert(filename != NULL);
const char *ext = &filename[strlen(filename)-4];
assert(!strcmp(ext,".txt"));
file = fopen(filename,"r");
assert (file != NULL);
// parse the scene
parseFile();
// close the file
fclose(file);
file = NULL;
}
SceneParser::~SceneParser() {
if (group != NULL)
delete group;
if (camera != NULL)
delete camera;
}
void SceneParser::initialize() {
// initialize some reasonable default values
group = NULL;
camera = NULL;
background_color = Vec3f(0.5,0.5,0.5);
current_object_color = Vec3f(1,1,1);
file = NULL;
}
// ====================================================================
// ====================================================================
void SceneParser::parseFile() {
//
// at the top level, the scene can have a camera,
// background color and a group of objects
// (we will add lights and other things in future assignments)
//
char token[MAX_PARSER_TOKEN_LENGTH];
while (getToken(token)) {
if (!strcmp(token, "OrthographicCamera")) {
camera = parseOrthographicCamera();
} else if (!strcmp(token, "Background")) {
parseBackground();
} else if (!strcmp(token, "Group")) {
group = parseGroup();
} else {
printf ("Unknown token in parseFile: '%s'\n", token);
exit(0);
}
}
}
Group* SceneParser::parseGroup() {
//
// each group starts with an integer that specifies
// the number of objects in the group
//
// the material node sets the color of all objects which
// follow, until the next material node
//
char token[MAX_PARSER_TOKEN_LENGTH];
getToken(token); assert (!strcmp(token, "{"));
// read in the number of objects
int num_objects;
getToken(token); assert (!strcmp(token, "num_objects"));
fscanf(file,"%d", &num_objects);
// ++++++++++++++++++++++++++++++++++++++++++++++++++++
// CALLING ASSIGNMENT 1 CODE
// create a new Group with the right number of objects
Group *answer = new Group(num_objects);
// ++++++++++++++++++++++++++++++++++++++++++++++++++++
// read in the objects
int count = 0;
while (num_objects > count) {
getToken(token);
if (!strcmp(token, "Material")) {
parseMaterial();
} else if (!strcmp(token, "Sphere")) {
Sphere *sphere = parseSphere();
// ++++++++++++++++++++++++++++++++++++++++++++++++
// CALLING ASSIGNMENT 1 CODE
// add this object to the group
answer->addObject(count,sphere);
// ++++++++++++++++++++++++++++++++++++++++++++++++
count++;
} else {
printf ("Unknown token in parseGroup: '%s'\n", token);
exit(0);
}
}
getToken(token); assert (!strcmp(token, "}"));
// return the group
return answer;
}
// ====================================================================
// ====================================================================
Camera* SceneParser::parseOrthographicCamera() {
char token[MAX_PARSER_TOKEN_LENGTH];
float c0,c1,c2;
float d0,d1,d2;
float u0,u1,u2;
float size;
// read in the camera parameters
getToken(token); assert (!strcmp(token, "{"));
getToken(token); assert (!strcmp(token, "center"));
fscanf(file,"%f %f %f", &c0,&c1,&c2);
getToken(token); assert (!strcmp(token, "direction"));
fscanf(file,"%f %f %f", &d0,&d1,&d2);
getToken(token); assert (!strcmp(token, "up"));
fscanf(file,"%f %f %f", &u0,&u1,&u2);
getToken(token); assert (!strcmp(token, "size"));
fscanf(file,"%f", &size);
getToken(token); assert (!strcmp(token, "}"));
Vec3f center = Vec3f(c0,c1,c2);
Vec3f direction = Vec3f (d0,d1,d2);
Vec3f up = Vec3f(u0,u1,u2);
// ++++++++++++++++++++++++++++++++++++++++++++++++++++
// CALLING ASSIGNMENT 1 CODE
// create a new orthographic camera and return it
return new OrthographicCamera(center,direction,up,size);
// ++++++++++++++++++++++++++++++++++++++++++++++++++++
}
void SceneParser::parseBackground() {
char token[MAX_PARSER_TOKEN_LENGTH];
float c0,c1,c2;
// read in the background color
getToken(token); assert (!strcmp(token, "{"));
getToken(token); assert (!strcmp(token, "color"));
fscanf(file,"%f %f %f",&c0,&c1,&c2);
getToken(token); assert (!strcmp(token, "}"));
// set the background color
background_color = Vec3f(c0,c1,c2);
}
// ====================================================================
// ====================================================================
void SceneParser::parseMaterial() {
char token[MAX_PARSER_TOKEN_LENGTH];
float c0,c1,c2;
// read in the material color
getToken(token); assert (!strcmp(token, "{"));
getToken(token); assert (!strcmp(token, "diffuseColor"));
fscanf(file,"%f %f %f", &c0,&c1,&c2);
getToken(token); assert (!strcmp(token, "}"));
// change the current object color
// scoping for the materials is very simplistic,
// and essentially ignores any tree hierarchy
current_object_color = Vec3f(c0,c1,c2);
}
Sphere* SceneParser::parseSphere() {
char token[MAX_PARSER_TOKEN_LENGTH];
float c0,c1,c2;
float radius;
// read in the sphere parameters
getToken(token); assert (!strcmp(token, "{"));
getToken(token); assert (!strcmp(token, "center"));
fscanf(file,"%f %f %f", &c0,&c1,&c2);
getToken(token); assert (!strcmp(token, "radius"));
fscanf(file,"%f", &radius);
getToken(token); assert (!strcmp(token, "}"));
Vec3f center = Vec3f(c0,c1,c2);
Vec3f color = current_object_color;
// ++++++++++++++++++++++++++++++++++++++++++++++++++++
// CALLING ASSIGNMENT 1 CODE
// create a new sphere object and return it
return new Sphere(center,radius,color);
// ++++++++++++++++++++++++++++++++++++++++++++++++++++
}
// ====================================================================
// ====================================================================
int SceneParser::getToken(char token[MAX_PARSER_TOKEN_LENGTH]) {
// for simplicity, tokens must be separated by whitespace
assert (file != NULL);
int success = fscanf(file,"%s ",token);
if (success == EOF) {
token[0] = '\0';
return 0;
}
return 1;
}
// ====================================================================
// ====================================================================