Stellarium  0.16.1
StelOBJ.hpp
1 /*
2  * Stellarium
3  * Copyright (C) 2012 Andrei Borza
4  * Copyright (C) 2016 Florian Schaukowitsch
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
19  */
20 
21 #ifndef _STELOBJ_HPP_
22 #define _STELOBJ_HPP_
23 
24 #include "GeomMath.hpp"
25 
26 #include <qopengl.h>
27 #include <QLoggingCategory>
28 #include <QString>
29 #include <QIODevice>
30 #include <QVector>
31 #include <QHash>
32 
33 Q_DECLARE_LOGGING_CATEGORY(stelOBJ)
34 
35 class StelOBJ
38 {
39 public:
42  {
43  XYZ, XZY, YXZ, YZX, ZXY, ZYX
44  };
45 
48  struct Vertex
49  {
51  GLfloat position[3];
53  GLfloat texCoord[2];
55  GLfloat normal[3];
57  GLfloat tangent[4];
59  GLfloat bitangent[3];
60 
62  bool operator==(const Vertex& b) const { return !memcmp(this,&b,sizeof(Vertex)); }
63  };
64 
68  struct Material
69  {
72  enum Illum { I_NONE=-1, I_DIFFUSE=0, I_DIFFUSE_AND_AMBIENT=1, I_SPECULAR=2, I_TRANSLUCENT=9 } illum;
73 
74  Material()
75  : illum(I_NONE),
76  Ka(-1.0f,-1.0f,-1.0f),Kd(-1.0f,-1.0f,-1.0f),Ks(-1.0f,-1.0f,-1.0f),Ke(-1.0f,-1.0f,-1.0f),
77  Ns(8.0f), d(-1.0f)
78  {
79 
80  }
81 
83  QString name;
84 
86  QVector3D Ka;
88  QVector3D Kd;
90  QVector3D Ks;
92  QVector3D Ke;
94  float Ns;
97  float d;
98 
100  QString map_Ka;
102  QString map_Kd;
104  QString map_Ks;
106  QString map_Ke;
108  QString map_bump;
110  QString map_height;
111 
112 
113  typedef QMap<QString,QStringList> ParamsMap;
118  ParamsMap additionalParams;
119 
123  static QVector<Material> loadFromFile(const QString& filename);
124  protected:
128  static bool parseBool(const QStringList& params, bool &out);
132  static bool parseFloat(const QStringList &params, float &out);
136  static bool parseVec2d(const QStringList &params, Vec2d &out);
137  };
138 
139 
143  MaterialGroup()
144  : startIndex(0),
145  indexCount(0),
146  objectIndex(-1),
147  materialIndex(-1),
148  centroid(0.)
149  {
150  }
151 
156 
161 
169  };
170 
171  typedef QVector<MaterialGroup> MaterialGroupList;
172 
175  struct Object
176  {
177  Object()
178  : isDefaultObject(false),
179  centroid(0.)
180  {
181  }
182 
186 
188  QString name;
189 
197 
199  MaterialGroupList groups;
200  private:
201  void postprocess(const StelOBJ& obj, Vec3d& centroid);
202  friend class StelOBJ;
203  };
204 
205  typedef QVector<Vec3f> V3Vec;
206  typedef QVector<Vec2f> V2Vec;
207  typedef QVector<Vertex> VertexList;
208  typedef QVector<unsigned int> IndexList;
209  typedef QVector<unsigned short> ShortIndexList;
210  typedef QVector<Material> MaterialList;
211  typedef QMap<QString, int> MaterialMap;
212  typedef QVector<Object> ObjectList;
213  typedef QMap<QString, int> ObjectMap;
214 
216  StelOBJ();
217  virtual ~StelOBJ();
218 
220  void clear();
221 
224  inline unsigned int getFaceCount() const { return m_indices.size() / 3; }
225 
227  inline const VertexList& getVertexList() const { return m_vertices; }
229  inline const IndexList& getIndexList() const { return m_indices; }
231  inline const MaterialList& getMaterialList() const { return m_materials; }
233  inline const ObjectList& getObjectList() const { return m_objects; }
235  inline const ObjectMap& getObjectMap() const { return m_objectMap; }
237  inline const AABBox& getAABBox() const { return m_bbox; }
242  inline const Vec3f& getCentroid() const { return m_centroid; }
243 
247  bool load(const QString& filename, const VertexOrder vertexOrder = VertexOrder::XYZ);
253  bool load(QIODevice& device, const QString& basePath, const VertexOrder vertexOrder = VertexOrder::XYZ);
254 
256  bool isLoaded() const { return m_isLoaded; }
257 
259  void rebuildNormals();
260 
264  inline bool canUseShortIndices() const { return m_vertices.size() < std::numeric_limits<unsigned short>::max(); }
265 
270  ShortIndexList getShortIndexList() const;
271 
277  void scale(double factor);
278 
281  void transform(const QMatrix4x4& mat, bool onlyPosition = false);
282 
285  void splitVertexData(V3Vec* position,
286  V2Vec* texCoord = Q_NULLPTR,
287  V3Vec* normal = Q_NULLPTR,
288  V3Vec* tangent = Q_NULLPTR,
289  V3Vec* bitangent = Q_NULLPTR) const;
290 
298  void clearVertexData();
299 private:
300  typedef QVector<QStringRef> ParseParams;
301  typedef QHash<Vertex, int> VertexCache;
302 
303  struct CurrentParserState
304  {
305  int currentMaterialIdx;
306  MaterialGroup* currentMaterialGroup;
307  Object* currentObject;
308  };
309 
310  bool m_isLoaded;
311  //all vertex data is contained in this list
312  VertexList m_vertices;
313  //all index data is contained in this list
314  IndexList m_indices;
315  //all material data is contained in this list
316  MaterialList m_materials;
317  MaterialMap m_materialMap;
318  ObjectList m_objects;
319  ObjectMap m_objectMap;
320 
321  //global bounding box
322  AABBox m_bbox;
323  //global centroid
324  Vec3f m_centroid;
325 
327  inline Object* getCurrentObject(CurrentParserState& state);
329  inline MaterialGroup* getCurrentMaterialGroup(CurrentParserState& state);
331  inline int getCurrentMaterialIndex(CurrentParserState& state);
333  inline static bool parseBool(const ParseParams& params, bool& out, int paramsStart=1);
335  inline static bool parseInt(const ParseParams& params, int& out, int paramsStart=1);
337  inline static bool parseString(const ParseParams &params, QString &out, int paramsStart=1);
338  inline static QString getRestOfString(const QString &strip, const QString& line);
340  inline static bool parseFloat(const ParseParams& params, float& out, int paramsStart=1);
344  template<typename T>
345  inline static bool parseVec3(const ParseParams& params, T& out, int paramsStart=1);
349  template<typename T>
350  inline static bool parseVec2(const ParseParams& params, T& out, int paramsStart=1);
351  inline bool parseFace(const ParseParams& params, const V3Vec& posList, const V3Vec& normList, const V2Vec& texList,
352  CurrentParserState &state, VertexCache& vertCache);
353 
354  inline void addObject(const QString& name, CurrentParserState& state);
355 
357  void generateNormals();
358 
360  void generateTangents();
361 
363  void generateAABB();
364 
367  void performPostProcessing(bool genNormals);
368 };
369 
371 inline uint qHash(const StelOBJ::Vertex& key, uint seed)
372 {
373 #if (QT_VERSION >= QT_VERSION_CHECK(5,4,0))
374  //hash the whole vertex raw memory directly
375  return qHashBits(&key, sizeof(StelOBJ::Vertex), seed);
376 #else
377  //no qHashBits, hash just the position and first uv coord
378  uint h1 = qHash(reinterpret_cast<const quint64*>(key.position)[0], seed);
379  uint h2 = qHash(reinterpret_cast<const quint64*>(key.position)[1], seed);
380 
381  return ((h1 << 16) | (h1 >> 16)) ^ h2 ^ seed;
382 #endif
383 }
384 
385 #endif // _STELOBJ_HPP_
GLfloat bitangent[3]
The vertex bitangent.
Definition: StelOBJ.hpp:59
Vec3f centroid
The centroid of this object at load time.
Definition: StelOBJ.hpp:194
bool isLoaded() const
Returns true if this object contains valid data from a load() method.
Definition: StelOBJ.hpp:256
AABBox boundingbox
The AABB of this group at load time.
Definition: StelOBJ.hpp:168
GLfloat tangent[4]
The vertex tangent.
Definition: StelOBJ.hpp:57
QString name
The name of the object. May be empty.
Definition: StelOBJ.hpp:188
GLfloat normal[3]
The vertex normal.
Definition: StelOBJ.hpp:55
QString map_Ke
The emissive texture map file path.
Definition: StelOBJ.hpp:106
Vec3f centroid
The centroid of this group at load time.
Definition: StelOBJ.hpp:166
int startIndex
The starting index in the index list.
Definition: StelOBJ.hpp:153
GLfloat texCoord[2]
The UV texture coordinate.
Definition: StelOBJ.hpp:53
int materialIndex
The index of the material that this group uses.
Definition: StelOBJ.hpp:160
QVector3D Ka
Ambient coefficient. Contains all -1 if not set by .mtl.
Definition: StelOBJ.hpp:86
bool operator==(const Vertex &b) const
Checks if the 2 vertices correspond to the same data using memcmp.
Definition: StelOBJ.hpp:62
QString name
Name of the material as defined in the .mtl, default empty.
Definition: StelOBJ.hpp:83
const ObjectMap & getObjectMap() const
Returns the object map (mapping the object names to their indices in the object list) ...
Definition: StelOBJ.hpp:235
const MaterialList & getMaterialList() const
Returns the list of materials.
Definition: StelOBJ.hpp:231
void rebuildNormals()
Rebuilds vertex normals as the average of face normals.
void clearVertexData()
Clears the internal vertex list to save space, meaning getVertexList() returns an empty list! The oth...
int indexCount
The amount of indices after the start index which belong to this material group.
Definition: StelOBJ.hpp:155
bool isDefaultObject
True if this object was automatically generated because no &#39;o&#39; statements were before the first &#39;f&#39; s...
Definition: StelOBJ.hpp:185
QVector3D Ks
Specular coefficient. Contains all -1 if not set by .mtl.
Definition: StelOBJ.hpp:90
void transform(const QMatrix4x4 &mat, bool onlyPosition=false)
Applies the given transformation matrix to the vertex data.
unsigned int getFaceCount() const
Returns the number of faces.
Definition: StelOBJ.hpp:224
Defines a material loaded from an .mtl file.
Definition: StelOBJ.hpp:68
QString map_bump
The bump/normal texture map file path.
Definition: StelOBJ.hpp:108
QString map_Ka
The ambient texture map file path.
Definition: StelOBJ.hpp:100
int objectIndex
The index of the object this group belongs to.
Definition: StelOBJ.hpp:158
GLfloat position[3]
The XYZ position.
Definition: StelOBJ.hpp:51
ShortIndexList getShortIndexList() const
Converts the index list (as returned by getIndexList()) to use unsigned short instead of integer...
QVector3D Kd
Diffuse coefficient. Contains all -1 if not set by .mtl.
Definition: StelOBJ.hpp:88
bool canUseShortIndices() const
Returns if unsigned short indices can be used instead of unsigned int indices, to save some memory...
Definition: StelOBJ.hpp:264
Illum
MTL Illumination models, see the developer doc for info.
Definition: StelOBJ.hpp:72
const ObjectList & getObjectList() const
Returns the list of objects.
Definition: StelOBJ.hpp:233
ParamsMap additionalParams
Contains all other material parameters that are not recognized by this class, but can still be access...
Definition: StelOBJ.hpp:118
void splitVertexData(V3Vec *position, V2Vec *texCoord=Q_NULLPTR, V3Vec *normal=Q_NULLPTR, V3Vec *tangent=Q_NULLPTR, V3Vec *bitangent=Q_NULLPTR) const
Splits the vertex data into separate arrays.
QString map_Kd
The diffuse texture map file path.
Definition: StelOBJ.hpp:102
const VertexList & getVertexList() const
Returns an vertex list, suitable for loading into OpenGL arrays.
Definition: StelOBJ.hpp:227
const Vec3f & getCentroid() const
Returns the global centroid of all vertices of the OBJ.
Definition: StelOBJ.hpp:242
const AABBox & getAABBox() const
Returns the global AABB of all vertices of the OBJ.
Definition: StelOBJ.hpp:237
Representation of a custom subset of a Wavefront .obj file, including only triangle data and material...
Definition: StelOBJ.hpp:37
A Vertex struct holds the vertex itself (position), corresponding texture coordinates, normals, tangents and bitangents It does not use Vec3f etc.
Definition: StelOBJ.hpp:48
Represents a bunch of faces following after each other that use the same material.
Definition: StelOBJ.hpp:142
Represents an OBJ object as defined with the &#39;o&#39; statement.
Definition: StelOBJ.hpp:175
bool load(const QString &filename, const VertexOrder vertexOrder=VertexOrder::XYZ)
Loads an .obj file by name.
MaterialGroupList groups
The list of material groups in this object.
Definition: StelOBJ.hpp:199
QString map_Ks
The specular texture map file path.
Definition: StelOBJ.hpp:104
float d
Alpha value (1 means opaque).
Definition: StelOBJ.hpp:97
AABBox boundingbox
The AABB of this object at load time.
Definition: StelOBJ.hpp:196
An axis-aligned bounding-box class.
Definition: GeomMath.hpp:31
void scale(double factor)
Scales the vertex positions according to the given factor.
StelOBJ()
Constructs an empty StelOBJ. Use load() to load data from a .obj file.
QVector3D Ke
Emissive coefficient. Contains all -1 if not set by .mtl.
Definition: StelOBJ.hpp:92
This header contains useful classes for common geometric operations that are useful for 3D rendering...
const IndexList & getIndexList() const
Returns an index list, suitable for use with OpenGL element arrays.
Definition: StelOBJ.hpp:229
float Ns
Specular shininess (exponent), should be > 0. Default 8.0.
Definition: StelOBJ.hpp:94
VertexOrder
Possible vertex orderings with load()
Definition: StelOBJ.hpp:41
QString map_height
The height map texture file path.
Definition: StelOBJ.hpp:110
void clear()
Resets all data contained in this StelOBJ.