Phongo Clap RT  1.0
Simple Raytracing Renderer
Parser.h
Go to the documentation of this file.
1 #ifndef _PARSER_H_
2 #define _PARSER_H_
3 
8 
9 #include <boost/tokenizer.hpp>
10 #include <string>
11 #include <iostream>
12 #include <fstream>
13 #include <streambuf>
14 #include <vector>
15 #include <ngl/Vec3.h>
16 #include <ngl/Colour.h>
17 
18 #include "Light.h"
19 #include "Shape.h"
20 #include "Plane.h"
21 #include "Sphere.h"
22 //----------------------------------------------------------------------------------------------------------------------
27 //----------------------------------------------------------------------------------------------------------------------
28 class Parser
29 {
30 public:
31  //--------------------------------------------------------------------------------------------------------------------
47  // -------------------------------------------------------------------------------------------------------------------
48  Parser(std::string &_image_name,
49  std::string &_text_file,
50  int &_width,
51  int &_height,
52  float &_camPosX,
53  float &_camPosY,
54  float &_camPosZ,
55  float &_lookAtX,
56  float &_lookAtY,
57  float &_lookAtZ,
58  int &_max_depth,
59  int &_anti_aliasing,
60  std::vector<Light*> &_scene_lights,
61  std::vector<geo::Shape*> &_scene_objects)
62  {
63  typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
64  boost::char_separator<char> quote{"\""};
65 
66  std::string text;
67  std::ifstream sceneFile(_text_file);
68 
69  sceneFile.seekg(0, std::ios::end);
70  text.reserve(sceneFile.tellg());
71  sceneFile.seekg(0, std::ios::beg);
72 
73  text.assign((std::istreambuf_iterator<char>(sceneFile)), std::istreambuf_iterator<char>());
74 
75  tokenizer tok{text,quote};
76  tokenizer::iterator it = tok.begin();
77  std::string tmp;
78 
79  std::cout << "Parsing filename...\n"; ++it;
80 
81  _image_name = *it;
82 
83  std::cout << "OK! Filename: " << _image_name << std::endl; ++it; ++it;
84  std::cout << "Parsing file dimensions...\n";
85 
86  tmp = *it; _width = atoi(tmp.c_str()); ++it; ++it; // WIDTH parsed
87  tmp = *it; _height = atoi(tmp.c_str()); // HEIGHT parsed
88 
89  std::cout << "OK! " << _width << "x" << _height << " image specified.\n";
90 
91  std::cout << "Parsing camera...\n"; ++it; ++it;
92  tmp = *it; _camPosX = atof(tmp.c_str()); ++it; ++it; // camPosX parsed
93  tmp = *it; _camPosY = atof(tmp.c_str()); ++it; ++it; // camPosY parsed
94  tmp = *it; _camPosZ = atof(tmp.c_str()); ++it; ++it; // camPosZ parsed
95  tmp = *it; _lookAtX = atof(tmp.c_str()); ++it; ++it; // lookAtX parsed
96  tmp = *it; _lookAtY = atof(tmp.c_str()); ++it; ++it; // lookAtY parsed
97  tmp = *it; _lookAtZ = atof(tmp.c_str()); // lookAtZ parsed
98 
99  std::cout << "OK! Camera parsed with pos["<<_camPosX <<","<<_camPosY<<","<<_camPosZ<<"] and lookup["<<_lookAtX<<","
100  <<_lookAtY<<","<<_lookAtZ<<"]\n"; ++it; ++it;
101 
102  tmp = *it; _max_depth = atoi(tmp.c_str()); ++it; ++it; // max_depth parsed
103  tmp = *it; _anti_aliasing = atoi(tmp.c_str()); ++it; ++it; // anti_aliasing parsed
104 
105  std::cout << "Parsing lights...\n";
106  parseLights(text, _scene_lights);
107 
108  std::cout << "Parsing objects...\n";
109  parseObjects(text, _scene_objects);
110  }
111  //--------------------------------------------------------------------------------------------------------------------
113  // -------------------------------------------------------------------------------------------------------------------
114  ~Parser() {}
115  //--------------------------------------------------------------------------------------------------------------------
119  // -------------------------------------------------------------------------------------------------------------------
120  void parseObjects(std::string& _text, std::vector<geo::Shape*> &_scene_objects)
121  {
122  typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
123  boost::char_separator<char> dollar{"$"};
124  tokenizer tok{_text,dollar};
125  tokenizer::iterator it = tok.begin();
126  it++;
127 
128  std::string tmp;
129 
130  while(it != tok.end())
131  {
132  tmp = *it;
133  if (tmp.at(0) == '}') break;
134  if (tmp.at(0) == 'P')
135  {
136  // parse plane
137  parsePlane(tmp,_scene_objects);
138  }
139  else if (tmp.at(0) == 'S')
140  {
141  // parse sphere
142  parseSphere(tmp,_scene_objects);
143  }
144  ++it;
145  }
146  }
147  //--------------------------------------------------------------------------------------------------------------------
151  // -------------------------------------------------------------------------------------------------------------------
152  void parseLights(std::string& _text, std::vector<Light*> &_scene_lights)
153  {
154  typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
155  boost::char_separator<char> plus{"+"};
156  tokenizer tok{_text,plus};
157  tokenizer::iterator it = tok.begin();
158  ++it;
159 
160  std::string tmp;
161 
162  while(it != tok.end())
163  {
164  tmp = *it;
165  if (tmp.at(0) == '}') break;
166  parseSingleLight(tmp, _scene_lights);
167  ++it;
168  }
169  }
170  //--------------------------------------------------------------------------------------------------------------------
174  // -------------------------------------------------------------------------------------------------------------------
175  void parseSingleLight(std::string &_text_light, std::vector<Light*> &_scene_lights)
176  {
177  typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
178  boost::char_separator<char> space{" "};
179  tokenizer tok{_text_light,space};
180  tokenizer::iterator it = tok.begin();
181  std::string tmp;
182  std::string light_name;
183 
184  ngl::Vec3 position;
185  ngl::Colour diffuse_col, specular_col;
186  float diff_int, spec_int, falloff;
187 
188  light_name = *it; it++;it++;
189 
190  tmp = *it; position.m_x = atof(tmp.c_str()); it++; // light x position
191  tmp = *it; position.m_y = atof(tmp.c_str()); it++; // light y position
192  tmp = *it; position.m_z = atof(tmp.c_str()); it++;it++;it++; // light z position
193  tmp = *it; diffuse_col.m_r = atof(tmp.c_str()); it++; // light r diffuse value
194  tmp = *it; diffuse_col.m_g = atof(tmp.c_str()); it++; // light g diffuse value
195  tmp = *it; diffuse_col.m_b = atof(tmp.c_str()); it++;it++;it++; // light b diffuse value
196  tmp = *it; specular_col.m_r = atof(tmp.c_str()); it++; // light r specular value
197  tmp = *it; specular_col.m_g = atof(tmp.c_str()); it++; // light g specular value
198  tmp = *it; specular_col.m_b = atof(tmp.c_str()); it++;it++; // light b specular value
199  tmp = *it; diff_int = atof(tmp.c_str()); it++; // light diffuse intensity
200  tmp = *it; spec_int = atof(tmp.c_str()); it++; // light specular intensity
201  tmp = *it; falloff = atof(tmp.c_str()); // light falloff
202 
203  PointLight* light = new PointLight(position, diffuse_col, specular_col, diff_int, spec_int, falloff);
204  _scene_lights.push_back(light);
205  std::cout << "OK! Light with name " << light_name << " has been parsed.\n";
206  }
207  //--------------------------------------------------------------------------------------------------------------------
211  // -------------------------------------------------------------------------------------------------------------------
212  void parsePlane(std::string& _text, std::vector<geo::Shape*> &_scene_objects)
213  {
214  typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
215  boost::char_separator<char> space{" "};
216  tokenizer tok{_text,space};
217  tokenizer::iterator it = tok.begin();
218  ++it;
219 
220  std::string tmp;
221  float nX, nY, nZ;
222  float distance;
223 
224  std::string plane_name = *it; it++;
225 
226  tmp = *it; distance = atof(tmp.c_str()); it++;it++; // distance
227  tmp = *it; nX = atof(tmp.c_str()); it++; // normal x component
228  tmp = *it; nY = atof(tmp.c_str()); it++; // normal y component
229  tmp = *it; nZ = atof(tmp.c_str()); it++;it++; // normal z component
230  tmp = *it;
231  if (tmp == "@checker")
232  {
233  float col1_r, col1_g, col1_b, col2_r, col2_g, col2_b; it++;it++;
234 
235  tmp = *it; col1_r = atof(tmp.c_str());it++; // colour1 r
236  tmp = *it; col1_g = atof(tmp.c_str());it++; // colour1 g
237  tmp = *it; col1_b = atof(tmp.c_str());it++; it++; it++; // colour1 b
238  tmp = *it; col2_r = atof(tmp.c_str());it++; // colour2 r
239  tmp = *it; col2_g = atof(tmp.c_str());it++; // colour2 g
240  tmp = *it; col2_b = atof(tmp.c_str());it++; it++; // colour2 b
241  tmp = *it;
242 
243  if (tmp == "@specularHardness")
244  {
245  it++;
246  float specularHardness;
247  tmp = *it; specularHardness = atof(tmp.c_str()); // specular hardness
248 
249  geo::Shape* plane = new geo::Plane(distance,ngl::Vec3(nX,nY,nZ),ngl::Colour(col1_r,col1_g,col1_b,1), ngl::Colour(col2_r,col2_g,col2_b,1));
250  plane->getMaterial()->m_spec_hardness = specularHardness;
251  _scene_objects.push_back(plane);
252 
253  std::cout << "OK! Plane " << plane_name << " has been parsed successfully.\n";
254  }
255  else
256  {
257  geo::Shape* plane = new geo::Plane(distance,ngl::Vec3(nX,nY,nZ),ngl::Colour(col1_r,col1_g,col1_b,1), ngl::Colour(col2_r,col2_g,col2_b,1));
258  _scene_objects.push_back(plane);
259 
260  std::cout << "OK! Plane " << plane_name << " has been parsed successfully.\n";
261  }
262  }
263  else
264  {
265  float col_r, col_g, col_b;
266  it++;
267  tmp = *it; col_r = atof(tmp.c_str()); it++; // colour1 r
268  tmp = *it; col_g = atof(tmp.c_str()); it++; // colour1 g
269  tmp = *it; col_b = atof(tmp.c_str()); it++; it++; // colour1 b
270  tmp = *it;
271 
272  if(tmp == "@specularHardness")
273  {
274  it++;
275  float specularHardness;
276  tmp = *it; specularHardness = atof(tmp.c_str()); // specular hardness
277 
278  geo::Shape* plane = new geo::Plane(distance,ngl::Vec3(nX,nY,nZ),ngl::Colour(col_r,col_g,col_b,1));
279  plane->getMaterial()->m_spec_hardness = specularHardness;
280  _scene_objects.push_back(plane);
281 
282  std::cout << "OK! Plane " << plane_name << " has been parsed successfully.\n";
283  }
284  else
285  {
286  geo::Shape* plane = new geo::Plane(distance,ngl::Vec3(nX,nY,nZ),ngl::Colour(col_r,col_g,col_b,1));
287  _scene_objects.push_back(plane);
288  std::cout << "OK! Plane " << plane_name << " has been parsed successfully.\n";
289  }
290  }
291  }
292  //--------------------------------------------------------------------------------------------------------------------
296  // -------------------------------------------------------------------------------------------------------------------
297  void parseSphere(std::string& _text, std::vector<geo::Shape*> &_scene_objects)
298  {
299  typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
300  boost::char_separator<char> space{" "};
301  tokenizer tok{_text,space};
302  tokenizer::iterator it = tok.begin();
303  ++it;
304 
305  std::string tmp;
306 
307  float posX, posY, posZ;
308  float colX, colY, colZ;
309  float radius;
310 
311  std::string sphere_name = *it;
312  it++;it++;
313 
314  tmp = *it; posX = atof(tmp.c_str()); it++; // sphere center x
315  tmp = *it; posY = atof(tmp.c_str()); it++; // sphere center y
316  tmp = *it; posZ = atof(tmp.c_str()); it++;it++; // sphere center z
317  tmp = *it; radius = atof(tmp.c_str()); it++;it++; // sphere radius
318  tmp = *it; colX = atof(tmp.c_str()); it++; // sphere colour r
319  tmp = *it; colY = atof(tmp.c_str()); it++; // sphere colour g
320  tmp = *it; colZ = atof(tmp.c_str()); it++;it++; // sphere colour b
321  tmp = *it;
322 
323  if(tmp == "@specularHardness") {
324  it++;
325 
326  tmp = *it;
327  float specularHardness = atof(tmp.c_str());
328 
329  geo::Shape* sphere = new geo::Sphere(ngl::Vec3(posX,posY,posZ),radius, ngl::Colour(colX,colY,colZ,1));
330  sphere->getMaterial()->m_spec_hardness = specularHardness;
331  _scene_objects.push_back(sphere);
332 
333  std::cout << "OK! Sphere " << sphere_name << " has been parsed successfully.\n";
334  }
335  else if(tmp == "@reflective") {
336  it++;
337  tmp = *it; float reflection_ratio = atof(tmp.c_str()) / 100.0f; // reflection amount
338 
339  geo::Shape* sphere = new geo::Sphere(ngl::Vec3(posX,posY,posZ),radius, ngl::Colour(colX,colY,colZ,1));
340  sphere->hasReflection(reflection_ratio, 1.0f-reflection_ratio);
341  _scene_objects.push_back(sphere);
342 
343  std::cout << "OK! Sphere " << sphere_name << " has been parsed successfully.\n";
344  }
345  else if(tmp == "@refractive") {
346  it++;
347  tmp = *it; float ior = atof(tmp.c_str()); it++; // index of refraction
348  tmp = *it; float refraction_ratio = atof(tmp.c_str()) / 100.0f; // refraction amount
349 
350  geo::Shape* sphere = new geo::Sphere(ngl::Vec3(posX,posY,posZ),radius, ngl::Colour(colX,colY,colZ,1));
351  sphere->hasRefraction(ior, refraction_ratio, 1.0f-refraction_ratio);
352  _scene_objects.push_back(sphere);
353 
354  std::cout << "OK! Sphere " << sphere_name << " has been parsed successfully.\n";
355  }
356  else {
357  geo::Shape* sphere = new geo::Sphere(ngl::Vec3(posX,posY,posZ),radius, ngl::Colour(colX,colY,colZ,1));
358  _scene_objects.push_back(sphere);
359  }
360  }
361 };
362 
363 #endif
void parseSingleLight(std::string &_text_light, std::vector< Light * > &_scene_lights)
Read the text line that defines a light and push it into the vector container.
Definition: Parser.h:175
Class that hold an implicit definition of a sphere through center and radius parameters. It also implements a method for finding intersections.
Definition: Sphere.h:23
Implements the interface for creating a plane shape and the methods for finding its intersections...
A class for implicit sphere definitions.
~Parser()
Default destructor for the parser.
Definition: Parser.h:114
A class for the lights in the scene. There is no sepparate .cpp file due to its simplicity.
void parsePlane(std::string &_text, std::vector< geo::Shape * > &_scene_objects)
Read the text line that defines a plane and push it into the vector container.
Definition: Parser.h:212
Inherits from shape. Implements functionability for plane shape and its materials. and the ray-plane intersections algorithms.
Definition: Plane.h:22
void parseLights(std::string &_text, std::vector< Light * > &_scene_lights)
Read objects snippet of text and push elements to the object vector on the go.
Definition: Parser.h:152
Parser(std::string &_image_name, std::string &_text_file, int &_width, int &_height, float &_camPosX, float &_camPosY, float &_camPosZ, float &_lookAtX, float &_lookAtY, float &_lookAtZ, int &_max_depth, int &_anti_aliasing, std::vector< Light * > &_scene_lights, std::vector< geo::Shape * > &_scene_objects)
Default constructor for the parser.
Definition: Parser.h:48
void parseSphere(std::string &_text, std::vector< geo::Shape * > &_scene_objects)
Read the text line that defines a sphere and push it into the vector container.
Definition: Parser.h:297
void parseObjects(std::string &_text, std::vector< geo::Shape * > &_scene_objects)
Read objects snippet of text and push elements to the object vector on the go.
Definition: Parser.h:120
Semi abstract class with virtual methods that holds all the calls for getting intersections, getting normals, also for specifying the properties of the material that will be hold by the Material member of this class.
Definition: Shape.h:21
Point light constructor.
Definition: Light.h:82
Reads from text file and iterates using boost tokenizer to "pickup" and store values based on syntax...
Definition: Parser.h:28