SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
SLMesh.h
Go to the documentation of this file.
1 /**
2  * \file SLMesh.h
3  * \date July 2014
4  * \authors Marcus Hudritsch
5  * \copyright http://opensource.org/licenses/GPL-3.0
6  * \remarks Please use clangformat to format the code. See more code style on
7  * https://github.com/cpvrlab/SLProject4/wiki/SLProject-Coding-Style
8 */
9 
10 #ifndef SLMESH_H
11 #define SLMESH_H
12 
13 #include <SLAABBox.h>
14 #include <SLEnums.h>
15 #include <SLGLVertexArray.h>
16 #include <SLObject.h>
17 #include <SLOptixAccelStruct.h>
18 #include <SLOptixDefinitions.h>
19 
20 class SLSceneView;
21 class SLNode;
22 class SLAccelStruct;
23 struct SLNodeStats;
24 class SLMaterial;
25 class SLRay;
26 class SLAnimSkeleton;
27 class SLGLState;
28 class SLGLProgram;
29 class SLAssetManager;
30 
31 //-----------------------------------------------------------------------------
32 /**
33  * @brief An SLMesh object is a triangulated mesh, drawn with one draw call.
34  * @details The SLMesh class represents a single mesh object. The mesh object
35  * is drawn with one draw call using the vertex indices in I16 or I32. A mesh
36  * can be drawn with triangles, lines or points.
37  * The vertex attributes are stored in vectors with equal number of elements:
38  * \n P (vertex position, mandatory)
39  * \n N (vertex normals)
40  * \n C (vertex color)
41  * \n UV[0] (1st. vertex texture coordinates) optional
42  * \n UV[1] (2nd. vertex texture coordinates) optional
43  * \n T (vertex tangents) optional
44  * \n Ji (vertex joint index) optional 2D vector
45  * \n Jw (vertex joint weights) optional 2D vector
46  * \n I16 holds the unsigned short vertex indices.
47  * \n I32 holds the unsigned int vertex indices.
48  * \n
49  * The normals of a vertex are automatically calculated in the method calcNormals()
50  * by averaging the face normals of the adjacent triangles. A vertex has always
51  * only <b>one</b> normal and is used for the lighting calculation in the shader
52  * programs. With such averaged normals you can created a interpolated shading on
53  * smooth surfaces such as a sphere.
54  * \n
55  * For objects with sharp edges such as a box you need 4 vertices per box face.
56  * All normals of a face point to the same direction. This means, that you have
57  * three times the same vertex position but with different normals for one corner
58  * of the box.
59  * \n
60  * The following image shows a box with sharp edges and a sphere with mostly
61  * smooth but also 4 sharp edges. The smooth red normal as the top vertex got
62  * averaged because its position is only once in the vector P. On the other hand
63  * are the vertices of the hard edges in the front of the sphere doubled.
64  * \n
65  * @image html images/sharpAndSmoothEdges.png
66  * \n
67  * \n The following the example creates the box with 24 vertices:
68  * \n The vertex positions and normals in P and N:
69  * \n P.size = 24
70  * \n P[0] = [1,1,1] N[0] = [1,0,0]
71  * \n P[1] = [1,0,1] N[1] = [1,0,0]
72  * \n P[2] = [1,0,0] N[2] = [1,0,0]
73  * \n P[3] = [1,1,0] N[3] = [1,0,0]
74  * \n
75  * \n P[4] = [1,1,0] N[4] = [0,0,-1]
76  * \n P[5] = [1,0,0] N[5] = [0,0,-1]
77  * \n P[6] = [0,0,0] N[6] = [0,0,-1]
78  * \n P[7] = [0,1,0] N[7] = [0,0,-1]
79  * \n
80  * \n P[8] = [0,0,1] N[8] = [-1,0,0]
81  * \n P[9] = [0,1,1] N[9] = [-1,0,0]
82  * \n P[10]= [0,1,0] N[10]= [-1,0,0]
83  * \n P[11]= [0,0,0] N[11]= [-1,0,0]
84  * \n
85  * \n P[12]= [1,1,1] N[12]= [0,0,1]
86  * \n P[13]= [0,1,1] N[13]= [0,0,1]
87  * \n P[14]= [0,0,1] N[14]= [0,0,1]
88  * \n P[15]= [1,0,1] N[15]= [0,0,1]
89  * \n
90  * \n P[16]= [1,1,1] N[16]= [0,1,0]
91  * \n P[17]= [1,1,0] N[17]= [0,1,0]
92  * \n P[18]= [0,1,0] N[18]= [0,1,0]
93  * \n P[19]= [0,1,1] N[19]= [0,1,0]
94  * \n
95  * \n P[20]= [0,0,0] N[20]= [0,-1,0]
96  * \n P[21]= [1,0,0] N[21]= [0,-1,0]
97  * \n P[22]= [1,0,1] N[22]= [0,-1,0]
98  * \n P[23]= [0,0,1] N[23]= [0,-1,0]
99  * \n
100  * \n The vertex indices in I16:
101  * \n I16[] = {0,1,2, 0,2,3,
102  * \n 4,5,6, 4,6,7,
103  * \n 8,9,10, 8,10,11,
104  * \n 12,13,14, 12,14,15,
105  * \n 16,17,18, 16,18,19,
106  * \n 20,21,22, 20,22,23}
107  * \n
108  * @image html images/boxVertices.png
109  * \n
110  * All vertex attributes are added to the vertex array object _vao (SLVertexArray).
111  * \n
112  * All arrays remain in the main memory for ray tracing.
113  * A mesh uses only one material referenced by the SLMesh::mat pointer.
114  * \n\n
115  * If a mesh is associated with a skeleton all its vertices and normals are
116  * transformed every frame by the joint weights. Every vertex of a mesh has
117  * weights for 1-n joints by which it can be influenced. This transform is
118  * called skinning and is done in CPU in the method transformSkin. The final
119  * transformed vertices and normals are stored in _finalP and _finalN.
120  * \n
121  * @remarks It is important that during instantiation NO OpenGL functions (gl*)
122  * get called because this constructor will be most probably called in a parallel
123  * thread from within an SLScene::registerAssetsToLoad or SLScene::assemble
124  * function. All objects that get rendered have to do their OpenGL initialization
125  * when they are used the first time during rendering in the main thread.
126  * For this mesh it means that the objects for OpenGL drawing (_vao, _vaoP,
127  * _vaoN, _vaoT and _vaoS) remain unused until the first frame is rendered.
128  */
129 class SLMesh : public SLObject
130 #ifdef SL_HAS_OPTIX
131  , public SLOptixAccelStruct
132 #endif
133 
134 {
135 public:
136  explicit SLMesh(SLAssetManager* assetMgr,
137  const SLstring& name = "Mesh");
138  ~SLMesh() override;
139 
140  virtual void init(SLNode* node);
141  virtual void draw(SLSceneView* sv, SLNode* node, SLuint intances = 0);
143  SLNode* node,
144  SLMaterial* depthMat);
145  void addStats(SLNodeStats& stats);
146  virtual void buildAABB(SLAABBox& aabb, const SLMat4f& wmNode);
147  void updateAccelStruct();
148  SLbool hit(SLRay* ray, SLNode* node);
149  virtual void preShade(SLRay* ray);
150 
151  virtual void deleteData();
152  virtual void deleteDataGpu();
153  void deleteSelected(SLNode* node);
154  void deleteUnused();
155  static void calcTex3DMatrix(SLNode* node);
156  virtual void calcMinMax();
157  virtual void calcNormals();
158  void calcCenterRad(SLVec3f& center, SLfloat& radius);
159  SLbool hitTriangleOS(SLRay* ray, SLNode* node, SLuint iT);
160  virtual void generateVAO(SLGLVertexArray& vao);
161  void computeHardEdgesIndices(float angleRAD, float epsilon);
162  void transformSkin(bool forceCPUSkinning,
163  const std::function<void(SLMesh*)>& cbInformNodes);
165 
166 #ifdef SL_HAS_OPTIX
167  void allocAndUploadData();
168  void uploadData();
169  virtual void createMeshAccelerationStructure();
170  virtual void updateMeshAccelerationStructure();
171  virtual ortHitData createHitData();
172  unsigned int sbtIndex() const { return _sbtIndex; }
173  static unsigned int meshIndex;
174 #endif
175 
176  // Getters
177  SLMaterial* mat() const { return _mat; }
178  SLMaterial* matOut() const { return _matOut; }
180  const SLAnimSkeleton* skeleton() const { return _skeleton; }
181  SLuint numI() const { return (SLuint)(!I16.empty() ? I16.size() : I32.size()); }
182  SLGLVertexArray& vao() { return _vao; }
183  SLbool isSelected() const { return _isSelected; }
184  SLfloat edgeAngleDEG() const { return _edgeAngleDEG; }
185  SLfloat edgeWidth() const { return _edgeWidth; }
186  SLCol4f edgeColor() const { return _edgeColor; }
187  SLVec3f finalP(SLuint i) { return _finalP->operator[](i); }
188  SLVec3f finalN(SLuint i) { return _finalN->operator[](i); }
190 
191  // Setters
192  void mat(SLMaterial* m) { _mat = m; }
193  void matOut(SLMaterial* m) { _matOut = m; }
195  void skeleton(SLAnimSkeleton* skel) { _skeleton = skel; }
197  void edgeWidth(SLfloat ew) { _edgeWidth = ew; }
198  void edgeAngleDEG(SLfloat ea) { _edgeAngleDEG = ea; }
199  void edgeColor(const SLCol4f& ec) { _edgeColor = ec; }
201 
202  // vertex attributes
203  SLVVec3f P; //!< Vector for vertex positions layout (location = 0)
204  SLVVec3f N; //!< Vector for vertex normals (opt.) layout (location = 1)
205  SLVVec2f UV[2]; //!< Array of 2 Vectors for tex. coords. (opt.) layout (location = 2)
206  SLVCol4f C; //!< Vector of vertex colors (opt.) layout (location = 4)
207  SLVVec4f T; //!< Vector of vertex tangents (opt.) layout (location = 5)
208  SLVVuchar Ji; //!< 2D Vector of per vertex joint ids (opt.) layout (location = 6)
209  SLVVfloat Jw; //!< 2D Vector of per vertex joint weights (opt.) layout (location = 7)
210  SLVVec3f skinnedP; //!< temp. vector for CPU skinned vertex positions
211  SLVVec3f skinnedN; //!< temp. vector for CPU skinned vertex normals
212 
213  // vertex indices
214  SLVushort I16; //!< Vector of vertex indices 16 bit
215  SLVuint I32; //!< Vector of vertex indices 32 bit
216  SLVuint IS32; //!< Vector of rectangle selected vertex indices 32 bit
217  SLVushort IE16; //!< Vector of hard edges vertex indices 16 bit (see computeHardEdgesIndices)
218  SLVuint IE32; //!< Vector of hard edges vertex indices 32 bit (see computeHardEdgesIndices)
219 
220  SLVec3f minP; //!< min. vertex in OS
221  SLVec3f maxP; //!< max. vertex in OS
222 
223 private:
224  void calcTangents();
225  void drawSelectedVertices();
227  SLGLState* stateGL,
228  SLNode* node);
229 
230 protected:
231  SLGLPrimitiveType _primitive; //!< Primitive type (default triangles)
232  SLMaterial* _mat; //!< Pointer to the inside material
233  SLMaterial* _matOut; //!< Pointer to the outside material
234  SLGLVertexArray _vao; //!< Main OpenGL Vertex Array Object for drawing
235  SLGLVertexArrayExt _vaoN; //!< OpenGL VAO for optional normal drawing
236  SLGLVertexArrayExt _vaoT; //!< OpenGL VAO for optional tangent drawing
237  SLGLVertexArrayExt _vaoS; //!< OpenGL VAO for optional selection drawing
238  SLbool _isSelected; //!< Flag if mesh is partially of fully selected
239  SLfloat _edgeAngleDEG; //!< Edge crease angle in degrees between face normals (30 deg. default)
240  SLfloat _edgeWidth; //!< Line width for hard edge drawing
241  SLCol4f _edgeColor; //!< Color for hard edge drawing
242  SLfloat _vertexPosEpsilon; //!< Vertex position epsilon used in computeHardEdgesIndices
243 
244 #ifdef SL_HAS_OPTIX
245  SLOptixCudaBuffer<SLVec3f> _vertexBuffer;
246  SLOptixCudaBuffer<SLVec3f> _normalBuffer;
247  SLOptixCudaBuffer<SLVec2f> _textureBuffer;
248  SLOptixCudaBuffer<SLushort> _indexShortBuffer;
249  SLOptixCudaBuffer<SLuint> _indexIntBuffer;
250  unsigned int _sbtIndex;
251 #endif
252 
253  SLbool _isVolume; //!< Flag for RT if mesh is a closed volume
254  SLAccelStruct* _accelStruct; //!< KD-tree or uniform grid
255  SLbool _accelStructIsOutOfDate; //!< Flag if accel. struct needs update
256  SLAnimSkeleton* _skeleton; //!< The skeleton this mesh is bound to
257  SLVMat4f _jointMatrices; //!< Joint matrix vector for this mesh
258  SLbool _isCPUSkinned; //!< Flag if mesh has been skinned on CPU during update
259  SLVVec3f* _finalP; //!< Pointer to final vertex position vector
260  SLVVec3f* _finalN; //!< pointer to final vertex normal vector
261 };
262 //-----------------------------------------------------------------------------
263 typedef vector<SLMesh*> SLVMesh;
264 //-----------------------------------------------------------------------------
265 #endif // SLMESH_H
float SLfloat
Definition: SL.h:173
unsigned int SLuint
Definition: SL.h:171
bool SLbool
Definition: SL.h:175
vector< vector< SLfloat > > SLVVfloat
Definition: SL.h:205
vector< SLushort > SLVushort
Definition: SL.h:195
vector< SLuint > SLVuint
Definition: SL.h:197
vector< vector< SLuchar > > SLVVuchar
Definition: SL.h:206
string SLstring
Definition: SL.h:158
SLGLPrimitiveType
Definition: SLGLEnums.h:30
Wrapper class around OpenGL Vertex Array Objects (VAO)
vector< SLMat4f > SLVMat4f
Definition: SLMat4.h:1585
vector< SLMesh * > SLVMesh
Definition: SLMesh.h:263
vector< SLVec2f > SLVVec2f
Definition: SLVec2.h:143
vector< SLVec3f > SLVVec3f
Definition: SLVec3.h:325
vector< SLVec4f > SLVVec4f
Definition: SLVec4.h:239
vector< SLCol4f > SLVCol4f
Definition: SLVec4.h:241
Defines an axis aligned bounding box.
Definition: SLAABBox.h:34
SLAccelStruct is an abstract base class for acceleration structures.
Definition: SLAccelStruct.h:22
SLAnimSkeleton keeps track of a skeletons joints and animations.
Toplevel holder of the assets meshes, materials, textures and shaders.
Encapsulation of an OpenGL shader program object.
Definition: SLGLProgram.h:56
Singleton class holding all OpenGL states.
Definition: SLGLState.h:71
SLGLVertexArray adds Helper Functions for quick Line & Point Drawing.
SLGLVertexArray encapsulates the core OpenGL drawing.
Defines a standard CG material with textures and a shader program.
Definition: SLMaterial.h:56
An SLMesh object is a triangulated mesh, drawn with one draw call.
Definition: SLMesh.h:134
SLMesh(SLAssetManager *assetMgr, const SLstring &name="Mesh")
Construct a new SLMesh::SLMesh object.
Definition: SLMesh.cpp:51
SLfloat edgeWidth() const
Definition: SLMesh.h:185
SLVec3f maxP
max. vertex in OS
Definition: SLMesh.h:221
void handleRectangleSelection(SLSceneView *sv, SLGLState *stateGL, SLNode *node)
Handles the rectangle section of mesh vertices (partial selection)
Definition: SLMesh.cpp:606
void updateAccelStruct()
Definition: SLMesh.cpp:1133
SLVuint IS32
Vector of rectangle selected vertex indices 32 bit.
Definition: SLMesh.h:216
SLVuint I32
Vector of vertex indices 32 bit.
Definition: SLMesh.h:215
SLGLPrimitiveType primitive() const
Definition: SLMesh.h:179
SLVushort I16
Vector of vertex indices 16 bit.
Definition: SLMesh.h:214
SLVec3f finalP(SLuint i)
Definition: SLMesh.h:187
virtual void calcNormals()
SLMesh::calcNormals recalculates vertex normals for triangle meshes.
Definition: SLMesh.cpp:1165
void isSelected(bool isSelected)
Definition: SLMesh.h:196
void deselectPartialSelection()
Definition: SLMesh.cpp:698
void mat(SLMaterial *m)
Definition: SLMesh.h:192
void vertexPosEpsilon(SLfloat eps)
Definition: SLMesh.h:200
SLbool _isVolume
Flag for RT if mesh is a closed volume.
Definition: SLMesh.h:253
SLGLVertexArrayExt _vaoT
OpenGL VAO for optional tangent drawing.
Definition: SLMesh.h:236
SLVVec4f T
Vector of vertex tangents (opt.) layout (location = 5)
Definition: SLMesh.h:207
void transformSkin(bool forceCPUSkinning, const std::function< void(SLMesh *)> &cbInformNodes)
Transforms the vertex positions and normals with by joint weights.
Definition: SLMesh.cpp:1573
virtual void calcMinMax()
Definition: SLMesh.cpp:978
SLVuint IE32
Vector of hard edges vertex indices 32 bit (see computeHardEdgesIndices)
Definition: SLMesh.h:218
SLfloat _edgeAngleDEG
Edge crease angle in degrees between face normals (30 deg. default)
Definition: SLMesh.h:239
virtual void init(SLNode *node)
SLMesh::shapeInit sets the transparency flag of the AABB.
Definition: SLMesh.cpp:296
SLbool accelStructIsOutOfDate()
Definition: SLMesh.h:189
virtual void draw(SLSceneView *sv, SLNode *node, SLuint intances=0)
Definition: SLMesh.cpp:389
void calcCenterRad(SLVec3f &center, SLfloat &radius)
Definition: SLMesh.cpp:1000
SLbool hit(SLRay *ray, SLNode *node)
Definition: SLMesh.cpp:910
SLbool _isSelected
Flag if mesh is partially of fully selected.
Definition: SLMesh.h:238
SLfloat _vertexPosEpsilon
Vertex position epsilon used in computeHardEdgesIndices.
Definition: SLMesh.h:242
SLVCol4f C
Vector of vertex colors (opt.) layout (location = 4)
Definition: SLMesh.h:206
SLVVec3f skinnedN
temp. vector for CPU skinned vertex normals
Definition: SLMesh.h:211
void computeHardEdgesIndices(float angleRAD, float epsilon)
computes the hard edges and stores the vertex indexes separately
Definition: SLMesh.cpp:819
void deleteSelected(SLNode *node)
Deletes the rectangle selected vertices and the dependent triangles.
Definition: SLMesh.cpp:148
void edgeAngleDEG(SLfloat ea)
Definition: SLMesh.h:198
void drawSelectedVertices()
Definition: SLMesh.cpp:708
virtual void deleteDataGpu()
Definition: SLMesh.cpp:128
void addStats(SLNodeStats &stats)
Definition: SLMesh.cpp:950
SLVushort IE16
Vector of hard edges vertex indices 16 bit (see computeHardEdgesIndices)
Definition: SLMesh.h:217
SLGLPrimitiveType _primitive
Primitive type (default triangles)
Definition: SLMesh.h:231
virtual void generateVAO(SLGLVertexArray &vao)
Generate the Vertex Array Object for a specific shader program.
Definition: SLMesh.cpp:738
SLVVec3f * _finalN
pointer to final vertex normal vector
Definition: SLMesh.h:260
static void calcTex3DMatrix(SLNode *node)
Definition: SLMesh.cpp:1319
SLfloat _edgeWidth
Line width for hard edge drawing.
Definition: SLMesh.h:240
SLGLVertexArrayExt _vaoN
OpenGL VAO for optional normal drawing.
Definition: SLMesh.h:235
SLAnimSkeleton * _skeleton
The skeleton this mesh is bound to.
Definition: SLMesh.h:256
SLVVec3f N
Vector for vertex normals (opt.) layout (location = 1)
Definition: SLMesh.h:204
SLVec3f minP
min. vertex in OS
Definition: SLMesh.h:220
SLCol4f edgeColor() const
Definition: SLMesh.h:186
virtual void deleteData()
SLMesh::deleteData deletes all mesh data and vbo's.
Definition: SLMesh.cpp:88
void calcTangents()
SLMesh::calcTangents computes the tangents per vertex for triangle meshes.
Definition: SLMesh.cpp:1229
SLVVec2f UV[2]
Array of 2 Vectors for tex. coords. (opt.) layout (location = 2)
Definition: SLMesh.h:205
SLVMat4f _jointMatrices
Joint matrix vector for this mesh.
Definition: SLMesh.h:257
SLVVec3f * _finalP
Pointer to final vertex position vector.
Definition: SLMesh.h:259
void primitive(SLGLPrimitiveType pt)
Definition: SLMesh.h:194
void matOut(SLMaterial *m)
Definition: SLMesh.h:193
SLbool hitTriangleOS(SLRay *ray, SLNode *node, SLuint iT)
Definition: SLMesh.cpp:1345
void drawIntoDepthBuffer(SLSceneView *sv, SLNode *node, SLMaterial *depthMat)
Simplified drawing method for shadow map creation.
Definition: SLMesh.cpp:330
void edgeWidth(SLfloat ew)
Definition: SLMesh.h:197
SLVVuchar Ji
2D Vector of per vertex joint ids (opt.) layout (location = 6)
Definition: SLMesh.h:208
SLCol4f _edgeColor
Color for hard edge drawing.
Definition: SLMesh.h:241
SLGLVertexArray & vao()
Definition: SLMesh.h:182
virtual void buildAABB(SLAABBox &aabb, const SLMat4f &wmNode)
Definition: SLMesh.cpp:1111
void deleteUnused()
Deletes unused vertices (= vertices that are not indexed in I16 or I32)
Definition: SLMesh.cpp:244
SLfloat edgeAngleDEG() const
Definition: SLMesh.h:184
SLGLVertexArrayExt _vaoS
OpenGL VAO for optional selection drawing.
Definition: SLMesh.h:237
SLbool _accelStructIsOutOfDate
Flag if accel. struct needs update.
Definition: SLMesh.h:255
SLbool isSelected() const
Definition: SLMesh.h:183
SLGLVertexArray _vao
Main OpenGL Vertex Array Object for drawing.
Definition: SLMesh.h:234
~SLMesh() override
The destructor deletes everything by calling deleteData.
Definition: SLMesh.cpp:82
SLVVec3f skinnedP
temp. vector for CPU skinned vertex positions
Definition: SLMesh.h:210
SLVVfloat Jw
2D Vector of per vertex joint weights (opt.) layout (location = 7)
Definition: SLMesh.h:209
const SLAnimSkeleton * skeleton() const
Definition: SLMesh.h:180
SLVec3f finalN(SLuint i)
Definition: SLMesh.h:188
SLAccelStruct * _accelStruct
KD-tree or uniform grid.
Definition: SLMesh.h:254
SLVVec3f P
Vector for vertex positions layout (location = 0)
Definition: SLMesh.h:203
SLMaterial * _matOut
Pointer to the outside material.
Definition: SLMesh.h:233
SLMaterial * matOut() const
Definition: SLMesh.h:178
void edgeColor(const SLCol4f &ec)
Definition: SLMesh.h:199
SLuint numI() const
Definition: SLMesh.h:181
void skeleton(SLAnimSkeleton *skel)
Definition: SLMesh.h:195
SLMaterial * mat() const
Definition: SLMesh.h:177
virtual void preShade(SLRay *ray)
Definition: SLMesh.cpp:1470
SLbool _isCPUSkinned
Flag if mesh has been skinned on CPU during update.
Definition: SLMesh.h:258
SLMaterial * _mat
Pointer to the inside material.
Definition: SLMesh.h:232
SLNode represents a node in a hierarchical scene graph.
Definition: SLNode.h:147
Base class for all other classes.
Definition: SLObject.h:23
const SLstring & name() const
Definition: SLObject.h:38
Ray class with ray and intersection properties.
Definition: SLRay.h:40
SceneView class represents a dynamic real time 3D view onto the scene.
Definition: SLSceneView.h:69
Struct for scene graph statistics.
Definition: SLNode.h:37