Mondschein Engine  0.3.0
buffer.cpp
1 /* Mondschein Engine is a fast, powerful, and easy-to-use 3D realtime rendering engine.
2  *
3  * Copyright (C) 2009-2013 by Andreas Amereller
4  * E-Mail: andreas.amereller.dev@googlemail.com
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation; either version 3 of the License, or (at your option)
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 #include "mbd/buffer.h"
22 #include "freeimage/buffer.h"
23 #include <fstream>
24 
25 using namespace mondschein;
26 using namespace io;
27 
28 MBD_Buffer::MBD_Buffer() : Buffer(), version(std::string("MBD\1\0\0",7))
29 {
30  return;
31 }
32 
33 MBD_Buffer::MBD_Buffer(MBD_Buffer_c _b) : Buffer(_b), version(std::string("MBD\1\0\0",7))
34 {
35  return;
36 }
37 
38 MBD_Buffer::~MBD_Buffer()
39 {
40  return;
41 }
42 
43 MBD_Buffer &MBD_Buffer::operator=(MBD_Buffer_c _b)
44 {
45  Buffer::operator=(_b);
46  return *this;
47 }
48 
49 void MBD_Buffer::parse_istream(std::istream &_in)
50 {
51  std::string file_version;
52  for (uint32 i=0; i<6; ++i)
53  {
54  file_version+=_in.get();
55  }
56  if (!check_version(file_version))
57  {
58  std::string err("Mondschein Engine ERROR: MBD version <");
59  err+=file_version;
60  err+="> not supported by this implementation (up to <";
61  err+=version;
62  err+=">. Exception raised in function\n\t";
63  err+="void mondschein::io::MBD_Buffer::parse_istream(std::istream& _in)";
64  throw boost::enable_current_exception(exception()) << exception_error(err);
65  }
66  mbd::data data;
67  data.ParseFromIstream(&_in);
68  parse_pb(data);
69 }
70 
71 void MBD_Buffer::parse_string(const std::string &_in)
72 {
73  std::string file_version;
74  for (uint32 i=0; i<6; ++i)
75  {
76  file_version+=_in.at(i);
77  }
78  if (!check_version(file_version))
79  {
80  std::string err("Mondschein Engine ERROR: MBD version <");
81  err+=file_version;
82  err+="> not supported by this implementation (up to <";
83  err+=version;
84  err+=">. Exception raised in function\n\t";
85  err+="void mondschein::io::MBD_Buffer::parse_istream(std::istream& _in)";
86  throw boost::enable_current_exception(exception()) << exception_error(err);
87  }
88  std::string in=_in.substr(6,_in.size()-6);
89  mbd::data data;
90  data.ParseFromString(in);
91  parse_pb(data);
92 }
93 
94 void MBD_Buffer::serialize_ostream(std::ostream &_out) const
95 {
96 
97 }
98 
99 void MBD_Buffer::serialize_string(std::string &_out) const
100 {
101 
102 }
103 
104 bool MBD_Buffer::check_version(const std::string &_version) const
105 {
106  if (version<_version) return false;
107  else return true;
108 }
109 
110 void MBD_Buffer::parse_pb(const mbd::data &_data)
111 {
112  io_objects_t objects;
113  for (uint32 c=0; c<_data.cameras_size(); ++c) parse_camera(_data.cameras(c),objects);
114  for (uint32 l=0; l<_data.lights_size(); ++l) parse_light(_data.lights(l),objects);
115  for (uint32 m=0; m<_data.materials_size(); ++m) parse_material(_data.materials(m),objects);
116  for (uint32 m=0; m<_data.meshes_size(); ++m) parse_mesh(_data.meshes(m),objects);
117  for (uint32 p=0; p<_data.poses_size(); ++p) parse_pose(_data.poses(p),objects);
118  for (uint32 t=0; t<_data.textures_size(); ++t) parse_texture(_data.textures(t),objects);
119  for (uint32 sg=0; sg<_data.scenegraphs_size(); ++sg) parse_scenegraph(_data.scenegraphs(sg),objects);
120  for (uint32 bc=0; bc<_data.beziercurves_size(); ++bc) parse_beziercurve(_data.beziercurves(bc),objects);
121  for (uint32 bp=0; bp<_data.bezierpatches_size(); ++bp) parse_bezierpatch(_data.bezierpatches(bp),objects);
122  for (uint32 nc=0; nc<_data.nurbscurves_size(); ++nc) parse_nurbscurve(_data.nurbscurves(nc),objects);
123  for (uint32 np=0; np<_data.nurbspatches_size(); ++np) parse_nurbspatch(_data.nurbspatches(np),objects);
124  return;
125 }
126 
127 void MBD_Buffer::parse_camera(const mbd::data_camera &_pb,io_objects_t &_io)
128 {
129  _io.nodes.insert(std::make_pair(_pb.name(),
130  scene::Camera_p(new scene::Camera(_pb.name(),scene::camera_attribs_t(_pb.fovy(),_pb.aspect(),_pb.near(),_pb.far(),
131  _pb.x(),_pb.y(),_pb.w(),_pb.h())))));
132  return;
133 }
134 
135 void MBD_Buffer::parse_light(const mbd::data_light &_pb,io_objects_t &_io)
136 {
137  Eigen::Vector4d ambient(_pb.ambient().x(),_pb.ambient().y(),_pb.ambient().z(),_pb.ambient().w());
138  Eigen::Vector4d diffuse(_pb.diffuse().x(),_pb.diffuse().y(),_pb.diffuse().z(),_pb.diffuse().w());
139  Eigen::Vector4d specular(_pb.specular().x(),_pb.specular().y(),_pb.specular().z(),_pb.specular().w());
140  Eigen::Vector4d position(_pb.position().x(),_pb.position().y(),_pb.position().z(),_pb.position().w());
141  Eigen::Vector4d direction(_pb.direction().x(),_pb.direction().y(),_pb.direction().z(),_pb.direction().w());
142  _io.nodes.insert(std::make_pair(_pb.name(),
143  scene::Light_p(new scene::Light(_pb.name(),scene::light_attribs_t(ambient,diffuse,specular,position,direction,
144  _pb.exponent(),_pb.cutoff(),_pb.const_att(),
145  _pb.lin_att(),_pb.quad_att(),_pb.light_nr())))));
146  return;
147 }
148 
149 void MBD_Buffer::parse_material(const mbd::data_material &_pb,io_objects_t &_io)
150 {
151  Eigen::Vector4d ambient(_pb.ambient().x(),_pb.ambient().y(),_pb.ambient().z(),_pb.ambient().w());
152  Eigen::Vector4d diffuse(_pb.diffuse().x(),_pb.diffuse().y(),_pb.diffuse().z(),_pb.diffuse().w());
153  Eigen::Vector4d specular(_pb.specular().x(),_pb.specular().y(),_pb.specular().z(),_pb.specular().w());
154  Eigen::Vector4d emission(_pb.emission().x(),_pb.emission().y(),_pb.emission().z(),_pb.emission().w());
155  _io.nodes.insert(std::make_pair(_pb.name(),
156  scene::Material_p(new scene::Material(_pb.name(),scene::material_attribs_t(ambient,diffuse,specular,
157  emission,_pb.shininess())))));
158  return;
159 }
160 
161 void MBD_Buffer::parse_mesh(const mbd::data_mesh &_pb,io_objects_t &_io)
162 {
163  std::vector<Eigen::Vector4d> v;
164  std::vector<Eigen::Vector3d> vn;
165  std::vector<Eigen::Vector4d> vt;
166  std::vector<Eigen::Vector4d> vc;
167  for (uint32 i=0; i<_pb.v_size(); ++i) v.push_back(Eigen::Vector4d(_pb.v(i).x(),_pb.v(i).y(),_pb.v(i).z(),_pb.v(i).w()));
168  for (uint32 j=0; j<_pb.vn_size(); ++j) vn.push_back(Eigen::Vector3d(_pb.vn(j).x(),_pb.vn(j).y(),_pb.vn(j).z()));
169  for (uint32 k=0; k<_pb.vt_size(); ++k) vt.push_back(Eigen::Vector4d(_pb.vt(k).x(),_pb.vt(k).y(),_pb.vt(k).z(),_pb.vt(k).w()));
170  for (uint32 l=0; l<_pb.vc_size(); ++l) vc.push_back(Eigen::Vector4d(_pb.vc(l).x(),_pb.vc(l).y(),_pb.vc(l).z(),_pb.vc(l).w()));
171  _io.nodes.insert(std::make_pair(_pb.name(),scene::Mesh_p(new scene::Mesh(_pb.name(),scene::mesh_attribs_t(v,vn,vt,vc)))));
172  return;
173 }
174 
175 void MBD_Buffer::parse_pose(const mbd::data_pose &_pb,io_objects_t &_io)
176 {
177  Eigen::Matrix4d m;
178  m << _pb.c1().x(), _pb.c1().x(), _pb.c3().x(), _pb.c4().x(),
179  _pb.c1().y(), _pb.c1().y(), _pb.c3().y(), _pb.c4().y(),
180  _pb.c1().z(), _pb.c1().z(), _pb.c3().z(), _pb.c4().z(),
181  _pb.c1().w(), _pb.c1().w(), _pb.c3().w(), _pb.c4().w();
182  _io.nodes.insert(std::make_pair(_pb.name(),scene::Pose_p(new scene::Pose(_pb.name(),m))));
183  return;
184 }
185 
186 void MBD_Buffer::parse_texture(const mbd::data_texture &_pb,io_objects_t &_io)
187 {
188  FI_Buffer_p texture;
189  std::ifstream texfile(_pb.image());
190  texture->parse_istream(texfile);
191  scene::Texture_p tex=boost::dynamic_pointer_cast<scene::Texture>(texture->get_io_objects().nodes.at("ID_FI_TEXTURE"));
192  if (tex.get()==NULL)
193  {
194  std::string err("Mondschein Engine ERROR: Conversion to <mondschein::scene::Texture_p> is not possible. ");
195  err+="Exception raised in function\n\t";
196  err+="void mondschein::io::MBD_Buffer::parse_texture(const mondschein::io::mbd::data_texture& _pb,";
197  err+="mondscheim::io_objects_t& _io)";
198  throw boost::enable_current_exception(exception()) << exception_error(err);
199  }
200  scene::texture_attribs_t t=tex->get_texture_attribs();
201  t.unit=_pb.unit();
202  t.texture_filter=static_cast<texture_filtering_e>(_pb.texture_filter());
203  t.anisotropic_filter=_pb.anisotropic_filter();
204  tex->set_texture_attribs(t);
205  tex->set_id(_pb.name());
206  _io.nodes.insert(std::make_pair(_pb.name(),tex));
207  return;
208 }
209 
210 void MBD_Buffer::parse_scenegraph(const mbd::data_scenegraph &_pb,io_objects_t &_io)
211 {
212  std::vector<scene::Scenenode_c> nodes;
213  for (uint32 i=0; i<_pb.nodes_size(); ++i) nodes.push_back(_io.nodes.at(_pb.nodes(i)));
214  boost::adjacency_list<> edges;
215  for (uint32 j=0; j<_pb.edges_size(); ++j) boost::add_edge(_pb.edges(j).src(),_pb.edges(j).dst(),edges);
216  _io.scenegraphs.insert(std::make_pair(_pb.name(),scene::Scenegraph_p(new scene::Scenegraph(scene::scenegraph_attribs_t(nodes,edges)))));
217  return;
218 }
219 
220 void MBD_Buffer::parse_beziercurve(const mbd::data_beziercurve &_pb,io_objects_t &_io)
221 {
222  std::vector<Eigen::Vector4d> points;
223  for (uint32 i=0; i<_pb.points_size(); ++i) points.push_back(Eigen::Vector4d(_pb.points(i).x(),_pb.points(i).y(),
224  _pb.points(i).z(),_pb.points(i).w()));
225  _io.beziercurves.insert(std::make_pair(_pb.name(),math::Beziercurve_p(new math::Beziercurve(points))));
226  return;
227 }
228 
229 void MBD_Buffer::parse_bezierpatch(const mbd::data_bezierpatch &_pb,io_objects_t &_io)
230 {
231  std::vector<math::Beziercurve_p> curves;
232  for (uint32 i=0; i<_pb.curves_size(); ++i) curves.push_back(generate_beziercurve(_pb.curves(i)));
233  _io.bezierpatches.insert(std::make_pair(_pb.name(),math::Bezierpatch_p(new math::Bezierpatch(curves))));
234  return;
235 }
236 
237 void MBD_Buffer::parse_nurbscurve(const mbd::data_nurbscurve &_pb,io_objects_t &_io)
238 {
239  std::vector<Eigen::Vector4d> points;
240  for (uint32 i=0; i<_pb.points_size(); ++i) points.push_back(Eigen::Vector4d(_pb.points(i).x(),_pb.points(i).y(),
241  _pb.points(i).z(),_pb.points(i).w()));
242  _io.nurbscurves.insert(std::make_pair(_pb.name(),math::NURBScurve_p(new math::NURBScurve(_pb.dimension(),points))));
243  return;
244 }
245 
246 void MBD_Buffer::parse_nurbspatch(const mbd::data_nurbspatch &_pb,io_objects_t &_io)
247 {
248  std::vector<math::NURBScurve_p> curves;
249  for (uint32 i=0; i<_pb.curves_size(); ++i) curves.push_back(generate_nurbscurve(_pb.curves(i)));
250  _io.nurbspatches.insert(std::make_pair(_pb.name(),math::NURBSpatch_p(new math::NURBSpatch(_pb.dimension(),curves))));
251  return;
252 }
253 
254 math::Beziercurve_p MBD_Buffer::generate_beziercurve(const mbd::data_beziercurve &_pb)
255 {
256  std::vector<Eigen::Vector4d> points;
257  for (uint32 i=0; i<_pb.points_size(); ++i) points.push_back(Eigen::Vector4d(_pb.points(i).x(),_pb.points(i).y(),
258  _pb.points(i).z(),_pb.points(i).w()));
259  return math::Beziercurve_p(new math::Beziercurve(points));
260 }
261 
262 math::NURBScurve_p MBD_Buffer::generate_nurbscurve(const mbd::data_nurbscurve &_pb)
263 {
264  std::vector<Eigen::Vector4d> points;
265  for (uint32 i=0; i<_pb.points_size(); ++i) points.push_back(Eigen::Vector4d(_pb.points(i).x(),_pb.points(i).y(),
266  _pb.points(i).z(),_pb.points(i).w()));
267  return math::NURBScurve_p(new math::NURBScurve(_pb.dimension(),points));
268 }