Scene3D Simple Scene Viewer
Scene3D.h
1 
6 #ifndef SCENE3D_H
7 #define SCENE3D_H
8 
9 #include <vector>
10 #include <map>
11 #include <fstream>
12 #include <string>
13 #include <sstream>
14 #include <iostream>
15 #include <math.h>
16 #define PI 3.14159265
17 
18 using namespace std;
19 
20 class Scene3D {
21  private:
22  vector<double*> cameras; // xyzr
23  vector<double*> lights; // xyz, rgb
24  map<string, int> colors; // Index "r_g_b" -> ID
25  vector<string> shapesJSON; // JSON strings of shapes
26 
35  string getColorString(double r, double g, double b) {
36  stringstream sstr;
37  sstr << r/255 << "," << g/255 << "," << b/255;
38  string hash = sstr.str();
39  if (colors.find(hash) == colors.end()) {
40  colors[hash] = colors.size();
41  }
42  stringstream ret;
43  ret << "color" << colors[hash];
44  return ret.str();
45  }
46 
52  string getMaterialsJSON() {
53  stringstream json;
54  json << "\"materials\":{\n";
55  size_t i = 0;
56  for (const pair<string, int>& c : colors) {
57  json << "\t\"color" << c.second << "\": {";
58  json << "\"kd\":[" << c.first << "]}";
59  if (i+1 < colors.size()) {
60  json << ",";
61  }
62  json << "\n";
63  i++;
64  }
65  json << "}";
66  return json.str();
67  }
68 
74  string getLightsJSON() {
75  stringstream json;
76  json << "\"lights\":[\n";
77  for (size_t i = 0; i < lights.size(); i++) {
78  double* L = lights.at(i);
79  json << "{\n";
80  json << "\t\"pos\":[" << L[0] << ", " << L[1] << ", " << L[2] << "],\n";
81  json << "\t\"color\":[" << L[3] << ", " << L[4] << ", " << L[5] << "]\n";
82  json << "}";
83  if (i < lights.size() - 1) {
84  json << ",";
85  }
86  json << "\n";
87  }
88  json << "]";
89  return json.str();
90  }
91 
97  string getCamerasJSON() {
98  stringstream json;
99  json << "\"cameras\":[\n";
100  for (size_t i = 0; i < cameras.size(); i++) {
101  double* c = cameras.at(i);
102  json << "{\n";
103  json << "\t\"pos\":[" << c[0] << ", " << c[1] << ", " << c[2] << "],\n";
104  // Compute quaternion for y rotation
105  double sh = sin(c[3]*PI/360);
106  double ch = cos(c[3]*PI/360);
107  json << "\t\"rot\": [0, " << sh << ", 0, " << ch << "]\n";
108  json << "}";
109  if (i+1 < cameras.size()) {
110  json << ",";
111  }
112  json << "\n";
113  }
114  json << "]";
115  return json.str();
116  }
117 
123  string getShapesJSON() {
124  stringstream json;
125  json << "\"children\":[\n";
126  for (size_t i = 0; i < shapesJSON.size(); i++) {
127  json << shapesJSON.at(i);
128  if (i+1 < shapesJSON.size()) {
129  json << ",";
130  }
131  json << "\n";
132  }
133  json << "]\n";
134  return json.str();
135  }
136 
137 
138 
139  public:
140  Scene3D() {}
141  ~Scene3D() {
142  for (size_t i = 0; i < cameras.size(); i++) {
143  delete[] cameras.at(i);
144  }
145  for (size_t i = 0; i < lights.size(); i++) {
146  delete[] lights.at(i);
147  }
148  }
149 
161  string getTransformationHierarchy(double tx, double ty, double tz,
162  double rx, double ry, double rz,
163  double sx, double sy, double sz, string shape) {
164  stringstream json;
165  json << "{\n";
166  // Translation
167  json << "\"transform\":[1, 0, 0, " << tx << ", 0, 1, 0, " << ty << ", 0, 0, 1, " << tz << ", 0, 0, 0, 1],\n";
168  json << "\"children\":[{";
169  // Rotation about z
170  double c = cos(rz*PI/180);
171  double s = sin(rz*PI/180);
172  json << "\"transform\":[" << c << ", " << -s << ", 0, 0, " << s << ", " << c << ", 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],\n";
173  json << "\"children\":[{\n";
174  // Rotation about y
175  c = cos(ry*PI/180);
176  s = sin(ry*PI/180);
177  json << "\"transform\":[" << c << ", 0, " << s << ", 0, 0, 1, 0, 0, " << -s << ", 0, " << c << ", 0, 0, 0, 0, 1],\n";
178  json << "\"children\":[{\n";
179  // Rotation about x
180  c = cos(rx*PI/180);
181  s = sin(rx*PI/180);
182  json << "\"transform\":[1, 0, 0, 0, 0, " << c << ", " << -s << ", 0, 0, " << s << ", " << c << ", 0, 0, 0, 0, 1],\n";
183  json << "\"children\":[{\n";
184  json << "\"transform\":[" << sx << ", 0, 0, 0, 0, " << sy << ", 0, 0, 0, 0, " << sz << ", 0, 0, 0, 0, 1],\n";
185  json << "\"shapes\":[\n";
186  json << shape;
187  json << "]\n";
188  json << "}]\n"; // End rotation about z
189  json << "}]\n"; // End rotation about y
190  json << "}]\n"; // End rotation about x
191  json << "}]\n"; // End translation
192  json << "}";
193  return json.str();
194  }
195 
211  void addBox(double cx, double cy, double cz, double xlen,
212  double ylen, double zlen,
213  double r, double g, double b,
214  double rx, double ry, double rz) {
215  stringstream boxJSON;
216  boxJSON << "{\"type\":\"box\",\n";
217  boxJSON << "\"material\":\"" << getColorString(r, g, b) << "\"}";
218  shapesJSON.push_back(getTransformationHierarchy(cx, cy, cz, rx, ry, rz, xlen, ylen, zlen, boxJSON.str()));
219  }
220 
233  void addBox(double cx, double cy, double cz,
234  double xlen, double ylen, double zlen,
235  double r, double g, double b) {
236  addBox(cx, cy, cz, xlen, ylen, zlen, r, g, b, 0, 0, 0);
237  }
238 
256  void addCylinder(double cx, double cy, double cz, double radius,
257  double height, double r, double g, double b,
258  double rx, double ry, double rz,
259  double sx, double sy, double sz) {
260  stringstream cylinderJSON;
261  cylinderJSON << "{\"type\":\"cylinder\",\n";
262  cylinderJSON << "\"radius\":" << radius << ",\n";
263  cylinderJSON << "\"height\":" << height << ",\n";
264  cylinderJSON << "\"material\":\"" << getColorString(r, g, b) << "\"}";
265  shapesJSON.push_back(getTransformationHierarchy(cx, cy, cz, rx, ry, rz, sx, sy, sz, cylinderJSON.str()));
266  }
267 
279  void addCylinder(double cx, double cy, double cz, double radius,
280  double height, double r, double g, double b) {
281  addCylinder(cx, cy, cz, radius, height, r, g, b, 0, 0, 0, 1, 1, 1);
282  }
283 
301  void addCone(double cx, double cy, double cz, double radius,
302  double height, double r, double g, double b,
303  double rx, double ry, double rz,
304  double sx, double sy, double sz) {
305  stringstream coneJSON;
306  coneJSON << "{\"type\":\"cone\",\n";
307  coneJSON << "\"radius\":" << radius << ",\n";
308  coneJSON << "\"height\":" << height << ",\n";
309  coneJSON << "\"material\":\"" << getColorString(r, g, b) << "\"}";
310  shapesJSON.push_back(getTransformationHierarchy(cx, cy, cz, rx, ry, rz, sx, sy, sz, coneJSON.str()));
311  }
312 
324  void addCone(double cx, double cy, double cz, double radius,
325  double height, double r, double g, double b) {
326  addCone(cx, cy, cz, radius, height, r, g, b, 0, 0, 0, 1, 1, 1);
327  }
328 
344  void addEllipsoid(double cx, double cy, double cz,
345  double radx, double rady, double radz,
346  double r, double g, double b,
347  double rx, double ry, double rz) {
348  stringstream ellipsoidJSON;
349  ellipsoidJSON << "{\"type\":\"sphere\",\n";
350  ellipsoidJSON << "\"material\":\"" << getColorString(r, g, b) << "\"}";
351  shapesJSON.push_back(getTransformationHierarchy(cx, cy, cz, rx, ry, rz, radx, rady, radz, ellipsoidJSON.str()));
352  }
353 
366  void addEllipsoid(double cx, double cy, double cz,
367  double radx, double rady, double radz,
368  double r, double g, double b) {
369  addEllipsoid(cx, cy, cz, radx, rady, radz, r, g, b, 0, 0, 0);
370  }
371 
382  void addSphere(double cx, double cy, double cz, double radius,
383  double r, double g, double b) {
384  addEllipsoid(cx, cy, cz, radius, radius, radius, r, g, b);
385  }
386 
404  void addSpecialMesh(string meshName,
405  double cx, double cy, double cz,
406  double rx, double ry, double rz,
407  double sx, double sy, double sz,
408  double r, double g, double b) {
409  stringstream meshJSON;
410  meshJSON << "{\"type\":\"mesh\",\n";
411  meshJSON << "\"material\":\"" << getColorString(r, g, b) << "\",\n";
412  meshJSON << "\"filename\":\"../meshes/" << meshName << ".off\"}";
413  shapesJSON.push_back(getTransformationHierarchy(cx, cy, cz, rx, ry, rz, sx, sy, sz, meshJSON.str()));
414  }
415 
416 
424  void addCamera(double x, double y, double z, double rot) {
425  double* xyzr = new double[4];
426  xyzr[0] = x;
427  xyzr[1] = y;
428  xyzr[2] = z;
429  xyzr[3] = rot;
430  cameras.push_back(xyzr);
431  }
432 
443  void addLight(double x, double y, double z, double r, double g, double b) {
444  double* light = new double[6];
445  light[0] = x;
446  light[1] = y;
447  light[2] = z;
448  light[3] = r;
449  light[4] = g;
450  light[5] = b;
451  lights.push_back(light);
452  }
453 
454 
460  void saveScene(string filename, string sceneName) {
461  stringstream json;
462  json << "{\n\"name\":\"" << sceneName << "\",\n";
463  json << getMaterialsJSON() << ",\n";
464  json << getLightsJSON() << ",\n";
465  json << getCamerasJSON() << ",\n";
466  json << getShapesJSON() << "\n}";
467  std::ofstream out(filename.c_str());
468  out << json.str();
469  out.close();
470  }
471 };
472 
473 #endif
Scene3D::saveScene
void saveScene(string filename, string sceneName)
Definition: Scene3D.h:460
Scene3D::addCylinder
void addCylinder(double cx, double cy, double cz, double radius, double height, double r, double g, double b, double rx, double ry, double rz, double sx, double sy, double sz)
Definition: Scene3D.h:256
Scene3D::addSpecialMesh
void addSpecialMesh(string meshName, double cx, double cy, double cz, double rx, double ry, double rz, double sx, double sy, double sz, double r, double g, double b)
Definition: Scene3D.h:404
Scene3D::addEllipsoid
void addEllipsoid(double cx, double cy, double cz, double radx, double rady, double radz, double r, double g, double b)
Definition: Scene3D.h:366
Scene3D::addEllipsoid
void addEllipsoid(double cx, double cy, double cz, double radx, double rady, double radz, double r, double g, double b, double rx, double ry, double rz)
Definition: Scene3D.h:344
Scene3D::addBox
void addBox(double cx, double cy, double cz, double xlen, double ylen, double zlen, double r, double g, double b, double rx, double ry, double rz)
Definition: Scene3D.h:211
Scene3D::addSphere
void addSphere(double cx, double cy, double cz, double radius, double r, double g, double b)
Definition: Scene3D.h:382
Scene3D::addCamera
void addCamera(double x, double y, double z, double rot)
Definition: Scene3D.h:424
Scene3D::getTransformationHierarchy
string getTransformationHierarchy(double tx, double ty, double tz, double rx, double ry, double rz, double sx, double sy, double sz, string shape)
Definition: Scene3D.h:161
Scene3D
Definition: Scene3D.h:20
Scene3D::addCone
void addCone(double cx, double cy, double cz, double radius, double height, double r, double g, double b)
Definition: Scene3D.h:324
Scene3D::addLight
void addLight(double x, double y, double z, double r, double g, double b)
Definition: Scene3D.h:443
Scene3D::addBox
void addBox(double cx, double cy, double cz, double xlen, double ylen, double zlen, double r, double g, double b)
Definition: Scene3D.h:233
Scene3D::addCylinder
void addCylinder(double cx, double cy, double cz, double radius, double height, double r, double g, double b)
Definition: Scene3D.h:279
Scene3D::addCone
void addCone(double cx, double cy, double cz, double radius, double height, double r, double g, double b, double rx, double ry, double rz, double sx, double sy, double sz)
Definition: Scene3D.h:301