SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
SLMesh Class Reference

An SLMesh object is a triangulated mesh, drawn with one draw call. More...

#include <SLMesh.h>

Inheritance diagram for SLMesh:
[legend]

Public Member Functions

 SLMesh (SLAssetManager *assetMgr, const SLstring &name="Mesh")
 Construct a new SLMesh::SLMesh object. More...
 
 ~SLMesh () override
 The destructor deletes everything by calling deleteData. More...
 
virtual void init (SLNode *node)
 SLMesh::shapeInit sets the transparency flag of the AABB. More...
 
virtual void draw (SLSceneView *sv, SLNode *node, SLuint intances=0)
 
void drawIntoDepthBuffer (SLSceneView *sv, SLNode *node, SLMaterial *depthMat)
 Simplified drawing method for shadow map creation. More...
 
void addStats (SLNodeStats &stats)
 
virtual void buildAABB (SLAABBox &aabb, const SLMat4f &wmNode)
 
void updateAccelStruct ()
 
SLbool hit (SLRay *ray, SLNode *node)
 
virtual void preShade (SLRay *ray)
 
virtual void deleteData ()
 SLMesh::deleteData deletes all mesh data and vbo's. More...
 
virtual void deleteDataGpu ()
 
void deleteSelected (SLNode *node)
 Deletes the rectangle selected vertices and the dependent triangles. More...
 
void deleteUnused ()
 Deletes unused vertices (= vertices that are not indexed in I16 or I32) More...
 
virtual void calcMinMax ()
 
virtual void calcNormals ()
 SLMesh::calcNormals recalculates vertex normals for triangle meshes. More...
 
void calcCenterRad (SLVec3f &center, SLfloat &radius)
 
SLbool hitTriangleOS (SLRay *ray, SLNode *node, SLuint iT)
 
virtual void generateVAO (SLGLVertexArray &vao)
 Generate the Vertex Array Object for a specific shader program. More...
 
void computeHardEdgesIndices (float angleRAD, float epsilon)
 computes the hard edges and stores the vertex indexes separately More...
 
void transformSkin (bool forceCPUSkinning, const std::function< void(SLMesh *)> &cbInformNodes)
 Transforms the vertex positions and normals with by joint weights. More...
 
void deselectPartialSelection ()
 
SLMaterialmat () const
 
SLMaterialmatOut () const
 
SLGLPrimitiveType primitive () const
 
const SLAnimSkeletonskeleton () const
 
SLuint numI () const
 
SLGLVertexArrayvao ()
 
SLbool isSelected () const
 
SLfloat edgeAngleDEG () const
 
SLfloat edgeWidth () const
 
SLCol4f edgeColor () const
 
SLVec3f finalP (SLuint i)
 
SLVec3f finalN (SLuint i)
 
SLbool accelStructIsOutOfDate ()
 
void mat (SLMaterial *m)
 
void matOut (SLMaterial *m)
 
void primitive (SLGLPrimitiveType pt)
 
void skeleton (SLAnimSkeleton *skel)
 
void isSelected (bool isSelected)
 
void edgeWidth (SLfloat ew)
 
void edgeAngleDEG (SLfloat ea)
 
void edgeColor (const SLCol4f &ec)
 
void vertexPosEpsilon (SLfloat eps)
 
- Public Member Functions inherited from SLObject
 SLObject (const SLstring &Name="", const SLstring &url="")
 
virtual ~SLObject ()
 
void name (const SLstring &Name)
 
void url (const SLstring &url)
 
const SLstringname () const
 
const SLstringurl () const
 

Static Public Member Functions

static void calcTex3DMatrix (SLNode *node)
 

Public Attributes

SLVVec3f P
 Vector for vertex positions layout (location = 0) More...
 
SLVVec3f N
 Vector for vertex normals (opt.) layout (location = 1) More...
 
SLVVec2f UV [2]
 Array of 2 Vectors for tex. coords. (opt.) layout (location = 2) More...
 
SLVCol4f C
 Vector of vertex colors (opt.) layout (location = 4) More...
 
SLVVec4f T
 Vector of vertex tangents (opt.) layout (location = 5) More...
 
SLVVuchar Ji
 2D Vector of per vertex joint ids (opt.) layout (location = 6) More...
 
SLVVfloat Jw
 2D Vector of per vertex joint weights (opt.) layout (location = 7) More...
 
SLVVec3f skinnedP
 temp. vector for CPU skinned vertex positions More...
 
SLVVec3f skinnedN
 temp. vector for CPU skinned vertex normals More...
 
SLVushort I16
 Vector of vertex indices 16 bit. More...
 
SLVuint I32
 Vector of vertex indices 32 bit. More...
 
SLVuint IS32
 Vector of rectangle selected vertex indices 32 bit. More...
 
SLVushort IE16
 Vector of hard edges vertex indices 16 bit (see computeHardEdgesIndices) More...
 
SLVuint IE32
 Vector of hard edges vertex indices 32 bit (see computeHardEdgesIndices) More...
 
SLVec3f minP
 min. vertex in OS More...
 
SLVec3f maxP
 max. vertex in OS More...
 

Protected Attributes

SLGLPrimitiveType _primitive
 Primitive type (default triangles) More...
 
SLMaterial_mat
 Pointer to the inside material. More...
 
SLMaterial_matOut
 Pointer to the outside material. More...
 
SLGLVertexArray _vao
 Main OpenGL Vertex Array Object for drawing. More...
 
SLGLVertexArrayExt _vaoN
 OpenGL VAO for optional normal drawing. More...
 
SLGLVertexArrayExt _vaoT
 OpenGL VAO for optional tangent drawing. More...
 
SLGLVertexArrayExt _vaoS
 OpenGL VAO for optional selection drawing. More...
 
SLbool _isSelected
 Flag if mesh is partially of fully selected. More...
 
SLfloat _edgeAngleDEG
 Edge crease angle in degrees between face normals (30 deg. default) More...
 
SLfloat _edgeWidth
 Line width for hard edge drawing. More...
 
SLCol4f _edgeColor
 Color for hard edge drawing. More...
 
SLfloat _vertexPosEpsilon
 Vertex position epsilon used in computeHardEdgesIndices. More...
 
SLbool _isVolume
 Flag for RT if mesh is a closed volume. More...
 
SLAccelStruct_accelStruct
 KD-tree or uniform grid. More...
 
SLbool _accelStructIsOutOfDate
 Flag if accel. struct needs update. More...
 
SLAnimSkeleton_skeleton
 The skeleton this mesh is bound to. More...
 
SLVMat4f _jointMatrices
 Joint matrix vector for this mesh. More...
 
SLbool _isCPUSkinned
 Flag if mesh has been skinned on CPU during update. More...
 
SLVVec3f_finalP
 Pointer to final vertex position vector. More...
 
SLVVec3f_finalN
 pointer to final vertex normal vector More...
 
- Protected Attributes inherited from SLObject
SLstring _name
 name of an object More...
 
SLstring _url
 uniform resource locator More...
 

Private Member Functions

void calcTangents ()
 SLMesh::calcTangents computes the tangents per vertex for triangle meshes. More...
 
void drawSelectedVertices ()
 
void handleRectangleSelection (SLSceneView *sv, SLGLState *stateGL, SLNode *node)
 Handles the rectangle section of mesh vertices (partial selection) More...
 

Detailed Description

An SLMesh object is a triangulated mesh, drawn with one draw call.

The SLMesh class represents a single mesh object. The mesh object is drawn with one draw call using the vertex indices in I16 or I32. A mesh can be drawn with triangles, lines or points. The vertex attributes are stored in vectors with equal number of elements:
P (vertex position, mandatory)
N (vertex normals)
C (vertex color)
UV0 optional
UV1 optional
T (vertex tangents) optional
Ji (vertex joint index) optional 2D vector
Jw (vertex joint weights) optional 2D vector
I16 holds the unsigned short vertex indices.
I32 holds the unsigned int vertex indices.
The normals of a vertex are automatically calculated in the method calcNormals() by averaging the face normals of the adjacent triangles. A vertex has always only one normal and is used for the lighting calculation in the shader programs. With such averaged normals you can created a interpolated shading on smooth surfaces such as a sphere.
For objects with sharp edges such as a box you need 4 vertices per box face. All normals of a face point to the same direction. This means, that you have three times the same vertex position but with different normals for one corner of the box.
The following image shows a box with sharp edges and a sphere with mostly smooth but also 4 sharp edges. The smooth red normal as the top vertex got averaged because its position is only once in the vector P. On the other hand are the vertices of the hard edges in the front of the sphere doubled.



The following the example creates the box with 24 vertices:
The vertex positions and normals in P and N:
P.size = 24
P[0] = [1,1,1] N[0] = [1,0,0]
P[1] = [1,0,1] N[1] = [1,0,0]
P[2] = [1,0,0] N[2] = [1,0,0]
P[3] = [1,1,0] N[3] = [1,0,0]

P[4] = [1,1,0] N[4] = [0,0,-1]
P[5] = [1,0,0] N[5] = [0,0,-1]
P[6] = [0,0,0] N[6] = [0,0,-1]
P[7] = [0,1,0] N[7] = [0,0,-1]

P[8] = [0,0,1] N[8] = [-1,0,0]
P[9] = [0,1,1] N[9] = [-1,0,0]
P[10]= [0,1,0] N[10]= [-1,0,0]
P[11]= [0,0,0] N[11]= [-1,0,0]

P[12]= [1,1,1] N[12]= [0,0,1]
P[13]= [0,1,1] N[13]= [0,0,1]
P[14]= [0,0,1] N[14]= [0,0,1]
P[15]= [1,0,1] N[15]= [0,0,1]

P[16]= [1,1,1] N[16]= [0,1,0]
P[17]= [1,1,0] N[17]= [0,1,0]
P[18]= [0,1,0] N[18]= [0,1,0]
P[19]= [0,1,1] N[19]= [0,1,0]

P[20]= [0,0,0] N[20]= [0,-1,0]
P[21]= [1,0,0] N[21]= [0,-1,0]
P[22]= [1,0,1] N[22]= [0,-1,0]
P[23]= [0,0,1] N[23]= [0,-1,0]

The vertex indices in I16:
I16[] = {0,1,2, 0,2,3,
4,5,6, 4,6,7,
8,9,10, 8,10,11,
12,13,14, 12,14,15,
16,17,18, 16,18,19,
20,21,22, 20,22,23}


All vertex attributes are added to the vertex array object _vao (SLVertexArray).
All arrays remain in the main memory for ray tracing. A mesh uses only one material referenced by the SLMesh::mat pointer.

If a mesh is associated with a skeleton all its vertices and normals are transformed every frame by the joint weights. Every vertex of a mesh has weights for 1-n joints by which it can be influenced. This transform is called skinning and is done in CPU in the method transformSkin. The final transformed vertices and normals are stored in _finalP and _finalN.

Remarks
It is important that during instantiation NO OpenGL functions (gl*) get called because this constructor will be most probably called in a parallel thread from within an SLScene::registerAssetsToLoad or SLScene::assemble function. All objects that get rendered have to do their OpenGL initialization when they are used the first time during rendering in the main thread. For this mesh it means that the objects for OpenGL drawing (_vao, _vaoP, _vaoN, _vaoT and _vaoS) remain unused until the first frame is rendered.

Definition at line 129 of file SLMesh.h.

Constructor & Destructor Documentation

◆ SLMesh()

SLMesh::SLMesh ( SLAssetManager assetMgr,
const SLstring name = "Mesh" 
)
explicit

Construct a new SLMesh::SLMesh object.

Meshes can be used in multiple nodes (SLNode). Meshes can belong therefore to the global assets such as meshes (SLMesh), materials (SLMaterial), textures (SLGLTexture) and shader programs (SLGLProgram).
It is important that during instantiation NO OpenGL functions (gl*) get called because this constructor will be most probably called in a parallel thread from within an SLScene::registerAssetsToLoad or SLScene::assemble function. All objects that get rendered have to do their OpenGL initialization when they are used the first time during rendering in the main thread.

Parameters
assetMgrPointer to a global asset manager. If passed the asset manager is the owner of the instance and will do the deallocation. If a nullptr is passed the creator is responsible for the deallocation.
nameName of the mesh

Definition at line 51 of file SLMesh.cpp.

51  : SLObject(name)
52 {
54  _mat = nullptr;
55  _matOut = nullptr;
56  _finalP = &P;
57  _finalN = &N;
58  minP.set(FLT_MAX, FLT_MAX, FLT_MAX);
59  maxP.set(-FLT_MAX, -FLT_MAX, -FLT_MAX);
60 
61  _skeleton = nullptr;
62  _isVolume = true; // is used for RT to decide inside/outside
63  _accelStruct = nullptr; // no initial acceleration structure
65  _isSelected = false;
66  _edgeAngleDEG = 30.0f;
67  _edgeWidth = 2.0f;
69  _vertexPosEpsilon = 0.001f;
70 
71  // Add this mesh to the global resource vector for deallocation
72  if (assetMgr)
73  assetMgr->meshes().push_back(this);
74 }
@ PT_triangles
Definition: SLGLEnums.h:35
SLVMesh & meshes()
SLVec3f maxP
max. vertex in OS
Definition: SLMesh.h:221
SLbool _isVolume
Flag for RT if mesh is a closed volume.
Definition: SLMesh.h:253
SLfloat _edgeAngleDEG
Edge crease angle in degrees between face normals (30 deg. default)
Definition: SLMesh.h:239
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
SLGLPrimitiveType _primitive
Primitive type (default triangles)
Definition: SLMesh.h:231
SLVVec3f * _finalN
pointer to final vertex normal vector
Definition: SLMesh.h:260
SLfloat _edgeWidth
Line width for hard edge drawing.
Definition: SLMesh.h:240
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
SLVVec3f * _finalP
Pointer to final vertex position vector.
Definition: SLMesh.h:259
SLCol4f _edgeColor
Color for hard edge drawing.
Definition: SLMesh.h:241
SLbool _accelStructIsOutOfDate
Flag if accel. struct needs update.
Definition: SLMesh.h:255
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 * _mat
Pointer to the inside material.
Definition: SLMesh.h:232
SLObject(const SLstring &Name="", const SLstring &url="")
Definition: SLObject.h:25
const SLstring & name() const
Definition: SLObject.h:38
void set(const T X, const T Y, const T Z)
Definition: SLVec3.h:59
static SLVec4 WHITE
Definition: SLVec4.h:215

◆ ~SLMesh()

SLMesh::~SLMesh ( )
override

The destructor deletes everything by calling deleteData.

The destructor should be called by the owner of the mesh. If an asset manager was passed in the constructor it will do it after scene destruction. The material (SLMaterial) that the mesh uses will not be deallocated.

Definition at line 82 of file SLMesh.cpp.

83 {
84  deleteData();
85 }
virtual void deleteData()
SLMesh::deleteData deletes all mesh data and vbo's.
Definition: SLMesh.cpp:88

Member Function Documentation

◆ accelStructIsOutOfDate()

SLbool SLMesh::accelStructIsOutOfDate ( )
inline

Definition at line 189 of file SLMesh.h.

189 { return _accelStructIsOutOfDate; }

◆ addStats()

void SLMesh::addStats ( SLNodeStats stats)

SLMesh::updateStats updates the parent node statistics.

Definition at line 950 of file SLMesh.cpp.

951 {
952  stats.numBytes += sizeof(SLMesh);
953  if (!P.empty()) stats.numBytes += SL_sizeOfVector(P);
954  if (!N.empty()) stats.numBytes += SL_sizeOfVector(N);
955  if (!UV[0].empty()) stats.numBytes += SL_sizeOfVector(UV[0]);
956  if (!UV[1].empty()) stats.numBytes += SL_sizeOfVector(UV[1]);
957  if (!C.empty()) stats.numBytes += SL_sizeOfVector(C);
958  if (!T.empty()) stats.numBytes += SL_sizeOfVector(T);
959  if (!Ji.empty()) stats.numBytes += SL_sizeOfVector(Ji);
960  if (!Jw.empty()) stats.numBytes += SL_sizeOfVector(Jw);
961 
962  if (!I16.empty())
963  stats.numBytes += (SLuint)(I16.size() * sizeof(SLushort));
964  else
965  stats.numBytes += (SLuint)(I32.size() * sizeof(SLuint));
966 
967  stats.numMeshes++;
968  if (_primitive == PT_triangles) stats.numTriangles += numI() / 3;
969  if (_primitive == PT_lines) stats.numLines += numI() / 2;
970 
971  if (_accelStruct)
972  _accelStruct->updateStats(stats);
973 }
unsigned int SLuint
Definition: SL.h:171
unsigned short SLushort
Definition: SL.h:169
SLuint SL_sizeOfVector(const T &vector)
Definition: SL.h:217
@ PT_lines
Definition: SLGLEnums.h:32
virtual void updateStats(SLNodeStats &stats)=0
SLMesh(SLAssetManager *assetMgr, const SLstring &name="Mesh")
Construct a new SLMesh::SLMesh object.
Definition: SLMesh.cpp:51
SLVuint I32
Vector of vertex indices 32 bit.
Definition: SLMesh.h:215
SLVushort I16
Vector of vertex indices 16 bit.
Definition: SLMesh.h:214
SLVVec4f T
Vector of vertex tangents (opt.) layout (location = 5)
Definition: SLMesh.h:207
SLVCol4f C
Vector of vertex colors (opt.) layout (location = 4)
Definition: SLMesh.h:206
SLVVec2f UV[2]
Array of 2 Vectors for tex. coords. (opt.) layout (location = 2)
Definition: SLMesh.h:205
SLVVuchar Ji
2D Vector of per vertex joint ids (opt.) layout (location = 6)
Definition: SLMesh.h:208
SLVVfloat Jw
2D Vector of per vertex joint weights (opt.) layout (location = 7)
Definition: SLMesh.h:209
SLuint numI() const
Definition: SLMesh.h:181
SLuint numMeshes
NO. of meshes in node.
Definition: SLNode.h:45
SLuint numTriangles
NO. of triangles in mesh.
Definition: SLNode.h:47
SLuint numLines
NO. of lines in mesh.
Definition: SLNode.h:48
SLuint numBytes
NO. of bytes allocated.
Definition: SLNode.h:39

◆ buildAABB()

void SLMesh::buildAABB ( SLAABBox aabb,
const SLMat4f wmNode 
)
virtual

SLMesh::buildAABB builds the passed axis-aligned bounding box in OS and updates the min & max points in WS with the passed WM of the node.

Reimplemented in SLParticleSystem.

Definition at line 1111 of file SLMesh.cpp.

1112 {
1113  // Update acceleration struct and calculate min max
1114  if (_skeleton)
1115  {
1116  minP = _skeleton->minOS();
1117  maxP = _skeleton->maxOS();
1118  }
1119  else
1120  {
1121  // For now, we just update the acceleration struct for non-skinned meshes
1122  // Building the entire voxelization of a mesh every frame is not feasible
1125  }
1126  // Apply world matrix
1127  aabb.fromOStoWS(minP, maxP, wmNode);
1128 }
void fromOStoWS(const SLVec3f &minOS, const SLVec3f &maxOS, const SLMat4f &wm)
Recalculate min and max after transformation in world coords.
Definition: SLAABBox.cpp:46
const SLVec3f & maxOS()
const SLVec3f & minOS()
void updateAccelStruct()
Definition: SLMesh.cpp:1133

◆ calcCenterRad()

void SLMesh::calcCenterRad ( SLVec3f center,
SLfloat radius 
)

SLMesh::calcCenterRad calculates the center and the radius of an almost minimal bounding sphere. Code by Jack Ritter from Graphic Gems.

Definition at line 1000 of file SLMesh.cpp.

1001 {
1002  SLulong i;
1003  SLfloat dx, dy, dz;
1004  SLfloat radius2, xspan, yspan, zspan, maxspan;
1005  SLfloat old_to_p, old_to_p_sq, old_to_new;
1006  SLVec3f xmin, xmax, ymin, ymax, zmin, zmax, dia1, dia2;
1007 
1008  // FIRST PASS: find 6 minima/maxima points
1009  xmin.x = ymin.y = zmin.z = FLT_MAX;
1010  xmax.x = ymax.y = zmax.z = -FLT_MAX;
1011 
1012  for (i = 0; i < P.size(); ++i)
1013  {
1014  if (P[i].x < xmin.x)
1015  xmin = P[i];
1016  else if (P[i].x > xmax.x)
1017  xmax = P[i];
1018  if (P[i].y < ymin.y)
1019  ymin = P[i];
1020  else if (P[i].y > ymax.y)
1021  ymax = P[i];
1022  if (P[i].z < zmin.z)
1023  zmin = P[i];
1024  else if (P[i].z > zmax.z)
1025  zmax = P[i];
1026  }
1027 
1028  // Set xspan = distance between the 2 points xmin & xmax (squared)
1029  dx = xmax.x - xmin.x;
1030  dy = xmax.y - xmin.y;
1031  dz = xmax.z - xmin.z;
1032  xspan = dx * dx + dy * dy + dz * dz;
1033 
1034  // Same for y & z spans
1035  dx = ymax.x - ymin.x;
1036  dy = ymax.y - ymin.y;
1037  dz = ymax.z - ymin.z;
1038  yspan = dx * dx + dy * dy + dz * dz;
1039 
1040  dx = zmax.x - zmin.x;
1041  dy = zmax.y - zmin.y;
1042  dz = zmax.z - zmin.z;
1043  zspan = dx * dx + dy * dy + dz * dz;
1044 
1045  // Set points dia1 & dia2 to the maximally separated pair
1046  dia1 = xmin;
1047  dia2 = xmax; // assume xspan biggest
1048  maxspan = xspan;
1049  if (yspan > maxspan)
1050  {
1051  maxspan = yspan;
1052  dia1 = ymin;
1053  dia2 = ymax;
1054  }
1055  if (zspan > maxspan)
1056  {
1057  dia1 = zmin;
1058  dia2 = zmax;
1059  }
1060 
1061  // dia1,dia2 is a diameter of initial sphere
1062  // calc initial center
1063  center.x = (dia1.x + dia2.x) * 0.5f;
1064  center.y = (dia1.y + dia2.y) * 0.5f;
1065  center.z = (dia1.z + dia2.z) * 0.5f;
1066 
1067  // calculate initial radius*radius and radius
1068  dx = dia2.x - center.x; // x component of radius vector
1069  dy = dia2.y - center.y; // y component of radius vector
1070  dz = dia2.z - center.z; // z component of radius vector
1071  radius2 = dx * dx + dy * dy + dz * dz;
1072  radius = sqrt(radius2);
1073 
1074  // SECOND PASS: increment current sphere
1075  for (i = 0; i < P.size(); ++i)
1076  {
1077  dx = P[i].x - center.x;
1078  dy = P[i].y - center.y;
1079  dz = P[i].z - center.z;
1080  old_to_p_sq = dx * dx + dy * dy + dz * dz;
1081 
1082  if (old_to_p_sq > radius2) // do r**2 test first
1083  {
1084  // this point is outside of current sphere
1085  old_to_p = sqrt(old_to_p_sq);
1086 
1087  // calc radius of new sphere
1088  radius = (radius + old_to_p) * 0.5f;
1089  radius2 = radius * radius; // for next r**2 compare
1090  old_to_new = old_to_p - radius;
1091 
1092  // calc center of new sphere
1093  center.x = (radius * center.x + old_to_new * P[i].x) / old_to_p;
1094  center.y = (radius * center.y + old_to_new * P[i].y) / old_to_p;
1095  center.z = (radius * center.z + old_to_new * P[i].z) / old_to_p;
1096 
1097  // Suppress if desired
1098  SL_LOG("\n New sphere: center,radius = %f %f %f %f",
1099  center.x,
1100  center.y,
1101  center.z,
1102  radius);
1103  }
1104  }
1105 }
float SLfloat
Definition: SL.h:173
#define SL_LOG(...)
Definition: SL.h:233
unsigned long SLulong
Definition: SL.h:165
T y
Definition: SLVec3.h:43
T x
Definition: SLVec3.h:43
T z
Definition: SLVec3.h:43

◆ calcMinMax()

void SLMesh::calcMinMax ( )
virtual

SLMesh::calcMinMax calculates the axis alligned minimum and maximum point

Definition at line 978 of file SLMesh.cpp.

979 {
980  // init min & max points
981  minP.set(FLT_MAX, FLT_MAX, FLT_MAX);
982  maxP.set(-FLT_MAX, -FLT_MAX, -FLT_MAX);
983 
984  // calc min and max point of all vertices
985  for (SLulong i = 0; i < P.size(); ++i)
986  {
987  if (finalP((SLuint)i).x < minP.x) minP.x = finalP((SLuint)i).x;
988  if (finalP((SLuint)i).x > maxP.x) maxP.x = finalP((SLuint)i).x;
989  if (finalP((SLuint)i).y < minP.y) minP.y = finalP((SLuint)i).y;
990  if (finalP((SLuint)i).y > maxP.y) maxP.y = finalP((SLuint)i).y;
991  if (finalP((SLuint)i).z < minP.z) minP.z = finalP((SLuint)i).z;
992  if (finalP((SLuint)i).z > maxP.z) maxP.z = finalP((SLuint)i).z;
993  }
994 }
SLVec3f finalP(SLuint i)
Definition: SLMesh.h:187

◆ calcNormals()

void SLMesh::calcNormals ( )
virtual

SLMesh::calcNormals recalculates vertex normals for triangle meshes.

SLMesh::calcNormals recalculates the normals only from the vertices. This algorithms doesn't know anything about smoothgroups. It just loops over the triangle of the material faces and sums up the normal for each of its vertices. Note that the face normals are not normalized. The cross product of 2 vectors is proportional to the area of the triangle. Like this the normal of big triangles are more weighted than small triangles and we get a better normal quality. At the end all vertex normals are normalized.

Reimplemented in SLParticleSystem.

Definition at line 1165 of file SLMesh.cpp.

1166 {
1167  // Set vector for the normals & Zero out the normals vector
1168  N.clear();
1169 
1170  if (_primitive != PT_triangles)
1171  return;
1172 
1173  // Create vector and fill with zero vectors
1174  N.resize(P.size());
1175  std::fill(N.begin(), N.end(), SLVec3f::ZERO);
1176 
1177  if (!I16.empty())
1178  {
1179  // Loop over all triangles
1180  for (SLulong i = 0; i < I16.size(); i += 3)
1181  {
1182  // Calculate the face's normal
1183  SLVec3f e1, e2, n;
1184 
1185  // Calculate edges of triangle
1186  e1.sub(P[I16[i + 1]], P[I16[i + 2]]); // e1 = B - C
1187  e2.sub(P[I16[i + 1]], P[I16[i]]); // e2 = B - A
1188 
1189  // Build normal with cross product but do NOT normalize it.
1190  n.cross(e1, e2); // n = e1 x e2
1191 
1192  // Add this normal to its vertices normals
1193  N[I16[i]] += n;
1194  N[I16[i + 1]] += n;
1195  N[I16[i + 2]] += n;
1196  }
1197  }
1198  else
1199  {
1200  for (SLulong i = 0; i < I32.size(); i += 3)
1201  {
1202  // Calculate the face's normal
1203  SLVec3f e1, e2, n;
1204 
1205  // Calculate edges of triangle
1206  e1.sub(P[I32[i + 1]], P[I32[i + 2]]); // e1 = B - C
1207  e2.sub(P[I32[i + 1]], P[I32[i]]); // e2 = B - A
1208 
1209  // Build normal with cross product but do NOT normalize it.
1210  n.cross(e1, e2); // n = e1 x e2
1211 
1212  // Add this normal to its vertices normals
1213  N[I32[i]] += n;
1214  N[I32[i + 1]] += n;
1215  N[I32[i + 2]] += n;
1216  }
1217  }
1218 
1219  // normalize vertex normals
1220  for (SLulong i = 0; i < P.size(); ++i)
1221  N[i].normalize();
1222 }
void cross(const SLVec3 &a, const SLVec3 &b)
Definition: SLVec3.h:118
void sub(const SLVec3 &a, const SLVec3 &b)
Definition: SLVec3.h:113
static SLVec3 ZERO
Definition: SLVec3.h:285

◆ calcTangents()

void SLMesh::calcTangents ( )
private

SLMesh::calcTangents computes the tangents per vertex for triangle meshes.

SLMesh::calcTangents computes the tangent and bi-tangent per vertex used for GLSL normal map bump mapping. The code and mathematical derivation is in detail explained in: http://www.terathon.com/code/tangent.html

Definition at line 1229 of file SLMesh.cpp.

1230 {
1231  if (!P.empty() &&
1232  !N.empty() && !UV[0].empty() &&
1233  (!I16.empty() || !I32.empty()))
1234  {
1235  // Delete old tangents
1236  T.clear();
1237 
1238  if (_primitive != PT_triangles)
1239  return;
1240 
1241  // allocate tangents
1242  T.resize(P.size());
1243 
1244  // allocate temp arrays for tangents
1245  SLVVec3f T1;
1246  T1.resize(P.size());
1247  fill(T1.begin(), T1.end(), SLVec3f::ZERO);
1248  SLVVec3f T2;
1249  T2.resize(P.size());
1250  fill(T2.begin(), T2.end(), SLVec3f::ZERO);
1251 
1252  SLuint iVA, iVB, iVC;
1253  SLuint numT = numI() / 3; // NO. of triangles
1254 
1255  for (SLuint t = 0; t < numT; ++t)
1256  {
1257  SLuint i = t * 3; // vertex index
1258 
1259  // Get the 3 vertex indices
1260  if (!I16.empty())
1261  {
1262  iVA = I16[i];
1263  iVB = I16[i + 1];
1264  iVC = I16[i + 2];
1265  }
1266  else
1267  {
1268  iVA = I32[i];
1269  iVB = I32[i + 1];
1270  iVC = I32[i + 2];
1271  }
1272 
1273  float x1 = P[iVB].x - P[iVA].x;
1274  float x2 = P[iVC].x - P[iVA].x;
1275  float y1 = P[iVB].y - P[iVA].y;
1276  float y2 = P[iVC].y - P[iVA].y;
1277  float z1 = P[iVB].z - P[iVA].z;
1278  float z2 = P[iVC].z - P[iVA].z;
1279 
1280  float s1 = UV[0][iVB].x - UV[0][iVA].x;
1281  float s2 = UV[0][iVC].x - UV[0][iVA].x;
1282  float t1 = UV[0][iVB].y - UV[0][iVA].y;
1283  float t2 = UV[0][iVC].y - UV[0][iVA].y;
1284 
1285  float r = 1.0F / (s1 * t2 - s2 * t1);
1286  SLVec3f sdir((t2 * x1 - t1 * x2) * r,
1287  (t2 * y1 - t1 * y2) * r,
1288  (t2 * z1 - t1 * z2) * r);
1289  SLVec3f tdir((s1 * x2 - s2 * x1) * r,
1290  (s1 * y2 - s2 * y1) * r,
1291  (s1 * z2 - s2 * z1) * r);
1292 
1293  T1[iVA] += sdir;
1294  T1[iVB] += sdir;
1295  T1[iVC] += sdir;
1296 
1297  T2[iVA] += tdir;
1298  T2[iVB] += tdir;
1299  T2[iVC] += tdir;
1300  }
1301 
1302  for (SLulong i = 0; i < P.size(); ++i)
1303  {
1304  // Gram-Schmidt orthogonalization
1305  T[i] = T1[i] - N[i] * N[i].dot(T1[i]);
1306  T[i].normalize();
1307 
1308  // Calculate temp. bi-tangent and store its handedness in T.w
1309  SLVec3f bitangent;
1310  bitangent.cross(N[i], T1[i]);
1311  T[i].w = (bitangent.dot(T2[i]) < 0.0f) ? -1.0f : 1.0f;
1312  }
1313  }
1314 }
vector< SLVec3f > SLVVec3f
Definition: SLVec3.h:325
T dot(const SLVec3 &v) const
Definition: SLVec3.h:117

◆ calcTex3DMatrix()

void SLMesh::calcTex3DMatrix ( SLNode node)
static

Definition at line 1319 of file SLMesh.cpp.

1320 {
1321  SLVec3f max = node->aabb()->maxOS();
1322  SLVec3f ctr = node->aabb()->centerOS();
1323  SLVec3f ext = max - ctr;
1324 
1325  // determine the scale factor s from the max. AABB extension
1326  SLint dim;
1327  SLfloat maxExt = ext.maxXYZ(dim);
1328  SLfloat s = 1.0f / (2.0f * maxExt);
1329 
1330  // scale and translate the texture matrix
1331  SLGLState* stateGL = SLGLState::instance();
1332  stateGL->textureMatrix.identity();
1333  stateGL->textureMatrix.scale(s);
1334  stateGL->textureMatrix.translate(-ctr);
1335  stateGL->textureMatrix.translate(-ext.comp[dim],
1336  -ext.comp[dim],
1337  -ext.comp[dim]);
1338 }
int SLint
Definition: SL.h:170
void maxOS(const SLVec3f &maxC)
Definition: SLAABBox.h:42
SLVec3f centerOS()
Definition: SLAABBox.h:54
Singleton class holding all OpenGL states.
Definition: SLGLState.h:71
SLMat4f textureMatrix
matrix for the texture transform
Definition: SLGLState.h:92
static SLGLState * instance()
Public static instance getter for singleton pattern.
Definition: SLGLState.h:74
void scale(T sxyz)
Definition: SLMat4.h:667
void identity()
Sets the identity matrix.
Definition: SLMat4.h:1333
void translate(T tx, T ty, T tz=0)
Definition: SLMat4.h:601
SLAABBox * aabb()
Definition: SLNode.h:301
The SLScene class represents the top level instance holding the scene structure.
Definition: SLScene.h:47
T comp[3]
Definition: SLVec3.h:46
T maxXYZ()
Definition: SLVec3.h:150

◆ computeHardEdgesIndices()

void SLMesh::computeHardEdgesIndices ( float  angleDEG,
float  epsilon 
)

computes the hard edges and stores the vertex indexes separately

Hard edges are edges between faces where there normals have an angle greater than angleDEG (by default 30°). If a mesh has only smooth edges such as a sphere there will be no hard edges. The indices of those hard edges are stored in the vector IE16 or IE32. For rendering these indices are appended behind the indices for the triangle drawing. This is because the index the same vertices of the same VAO. See SLMesh::generateVAO for the details.

Definition at line 819 of file SLMesh.cpp.

821 {
822  // dihedral angle considered to sharp
823  float angleRAD = angleDEG * Utils::DEG2RAD;
824 
825  if (_primitive != PT_triangles)
826  return;
827 
828  Eigen::MatrixXf V; // Input vertices for igl
829  Eigen::MatrixXi F; // Input faces (=triangle) indices for igl
830  Eigen::MatrixXf newV; // new vertices after duplicate removal
831  Eigen::MatrixXi newF; // new face indices after duplicate removal
832  Eigen::MatrixXi edges; // all edges
833  Eigen::MatrixXi edgeMap;
834  Eigen::MatrixXi uniqueEdges;
835  Eigen::MatrixXf faceN; // face normals
836  Eigen::VectorXi SVI; // new to old index mapping
837  Eigen::VectorXi SVJ; // old to new index mapping
838 
839  vector<vector<int>> uE2E;
840 
841  // fill input matrices
842  V.resize((Eigen::Index)_finalP->size(), 3);
843  for (int i = 0; i < _finalP->size(); i++)
844  V.row(i) << finalP(i).x, finalP(i).y, finalP(i).z;
845 
846  if (!I16.empty())
847  {
848  F.resize((Eigen::Index)I16.size() / 3, 3);
849  for (int j = 0, i = 0; i < I16.size(); j++, i += 3)
850  F.row(j) << I16[i], I16[i + 1], I16[i + 2];
851  }
852  if (!I32.empty())
853  {
854  F.resize((Eigen::Index)I32.size() / 3, 3);
855  for (int j = 0, i = 0; i < I32.size(); j++, i += 3)
856  F.row(j) << (int)I32[i], (int)I32[i + 1], (int)I32[i + 2];
857  }
858 
859  // extract sharp edges
860  igl::remove_duplicate_vertices(V, F, epsilon, newV, SVI, SVJ, newF);
861  igl::per_face_normals(newV, newF, faceN);
862  igl::unique_edge_map(newF, edges, uniqueEdges, edgeMap, uE2E);
863 
864  for (int u = 0; u < uE2E.size(); u++)
865  {
866  bool sharp = false;
867  if (uE2E[u].size() == 1) // edges at the border (with only one triangle)
868  sharp = true;
869 
870  // if more than one edge is passing here, compute dihedral angles
871  for (int i = 0; i < uE2E[u].size(); i++)
872  {
873  for (int j = i + 1; j < uE2E[u].size(); j++)
874  {
875  // E[faceId + |F| * c] opposite of vertex F[faceId][c]
876  // ei = fi + |F| * c -> ei % |F| = fi % |F| = fi; fi is the face adjacent to ei
877  // ej = fj + |F| * c -> ej % |F| = fj % |F| = fj; fj is the face adjacent to ej
878  const int ei = uE2E[u][i]; // edge i
879  const int fi = ei % (int)newF.rows();
880  const int ej = uE2E[u][j]; // edge j
881  const int fj = ej % (int)newF.rows();
882  Eigen::Matrix<float, 1, 3> ni = faceN.row(fi);
883  Eigen::Matrix<float, 1, 3> nj = faceN.row(fj);
884  Eigen::Matrix<float, 1, 3> ev = (newV.row(edges(ei, 1)) - newV.row(edges(ei, 0))).normalized();
885  float dij = Utils::PI - atan2((ni.cross(nj)).dot(ev), ni.dot(nj));
886  sharp = std::abs(dij - Utils::PI) > angleRAD;
887  }
888  }
889 
890  if (sharp)
891  {
892  if (!I16.empty())
893  {
894  IE16.push_back(SVI[uniqueEdges(u, 0)]);
895  IE16.push_back(SVI[uniqueEdges(u, 1)]);
896  }
897  else if (!I32.empty())
898  {
899  IE32.push_back(SVI[uniqueEdges(u, 0)]);
900  IE32.push_back(SVI[uniqueEdges(u, 1)]);
901  }
902  }
903  }
904 }
SLVuint IE32
Vector of hard edges vertex indices 32 bit (see computeHardEdgesIndices)
Definition: SLMesh.h:218
SLVushort IE16
Vector of hard edges vertex indices 16 bit (see computeHardEdgesIndices)
Definition: SLMesh.h:217
static const float DEG2RAD
Definition: Utils.h:239
T abs(T a)
Definition: Utils.h:249
static const float PI
Definition: Utils.h:237

◆ deleteData()

void SLMesh::deleteData ( )
virtual

SLMesh::deleteData deletes all mesh data and vbo's.

Definition at line 88 of file SLMesh.cpp.

89 {
90  P.clear();
91  N.clear();
92  C.clear();
93  T.clear();
94  UV[0].clear();
95  UV[1].clear();
96  for (auto i : Ji) i.clear();
97  Ji.clear();
98  for (auto i : Jw) i.clear();
99  Jw.clear();
100  I16.clear();
101  I32.clear();
102  IS32.clear();
103  IE16.clear();
104  IE32.clear();
105 
106  _jointMatrices.clear();
107  skinnedP.clear();
108  skinnedN.clear();
109 
110  if (_accelStruct)
111  {
112  delete _accelStruct;
113  _accelStruct = nullptr;
114  }
115 
116  _vao.deleteGL();
117  _vaoN.deleteGL();
118  _vaoT.deleteGL();
119 
120 #ifdef SL_HAS_OPTIX
121  _vertexBuffer.free();
122  _normalBuffer.free();
123  _indexShortBuffer.free();
124  _indexIntBuffer.free();
125 #endif
126 }
void deleteGL()
Deletes all vertex array & vertex buffer objects.
SLVuint IS32
Vector of rectangle selected vertex indices 32 bit.
Definition: SLMesh.h:216
SLGLVertexArrayExt _vaoT
OpenGL VAO for optional tangent drawing.
Definition: SLMesh.h:236
SLVVec3f skinnedN
temp. vector for CPU skinned vertex normals
Definition: SLMesh.h:211
SLGLVertexArrayExt _vaoN
OpenGL VAO for optional normal drawing.
Definition: SLMesh.h:235
SLVMat4f _jointMatrices
Joint matrix vector for this mesh.
Definition: SLMesh.h:257
SLGLVertexArray _vao
Main OpenGL Vertex Array Object for drawing.
Definition: SLMesh.h:234
SLVVec3f skinnedP
temp. vector for CPU skinned vertex positions
Definition: SLMesh.h:210

◆ deleteDataGpu()

void SLMesh::deleteDataGpu ( )
virtual

Definition at line 128 of file SLMesh.cpp.

129 {
130  _vao.deleteGL();
131  _vaoN.deleteGL();
132  _vaoT.deleteGL();
133 
134 #ifdef SL_HAS_OPTIX
135  _vertexBuffer.free();
136  _normalBuffer.free();
137  _indexShortBuffer.free();
138  _indexIntBuffer.free();
139 #endif
140 }

◆ deleteSelected()

void SLMesh::deleteSelected ( SLNode node)

Deletes the rectangle selected vertices and the dependent triangles.

The selection rectangle is defined in SLScene::selectRect and gets set and drawn in SLCamera::onMouseDown and SLCamera::onMouseMove. All vertices that are within the selectRect are listed in SLMesh::IS32. The selection evaluation is done during drawing in SLMesh::handleRectangleSelection and is only valid for the current frame. See also SLMesh::handleRectangleSelection.

Definition at line 148 of file SLMesh.cpp.

149 {
150  // Loop over all rectangle selected indexes in IS32
151  for (SLulong i = 0; i < IS32.size(); ++i)
152  {
153  SLulong ixDel = IS32[i] - i;
154 
155  if (ixDel < P.size()) P.erase(P.begin() + ixDel);
156  if (ixDel < N.size()) N.erase(N.begin() + ixDel);
157  if (ixDel < C.size()) C.erase(C.begin() + ixDel);
158  if (ixDel < T.size()) T.erase(T.begin() + ixDel);
159  if (ixDel < UV[0].size()) UV[0].erase(UV[0].begin() + ixDel);
160  if (ixDel < UV[1].size()) UV[1].erase(UV[1].begin() + ixDel);
161  if (ixDel < Ji.size()) Ji.erase(Ji.begin() + ixDel);
162  if (ixDel < Jw.size()) Jw.erase(Jw.begin() + ixDel);
163 
164  // Loop over all 16 bit triangles indexes
165  if (!I16.empty())
166  {
167  SLVushort i16;
168  // copy the triangle that do not contain the index to delete
169  for (SLulong t = 0; t < I16.size(); t += 3)
170  {
171  if (I16[t] != ixDel &&
172  I16[t + 1] != ixDel &&
173  I16[t + 2] != ixDel)
174  {
175  if (I16[t] < ixDel)
176  i16.push_back(I16[t]);
177  else
178  i16.push_back(I16[t] - 1);
179  if (I16[t + 1] < ixDel)
180  i16.push_back(I16[t + 1]);
181  else
182  i16.push_back(I16[t + 1] - 1);
183  if (I16[t + 2] < ixDel)
184  i16.push_back(I16[t + 2]);
185  else
186  i16.push_back(I16[t + 2] - 1);
187  }
188  }
189  I16 = i16;
190  }
191 
192  // Loop over all 32 bit triangles indexes
193  if (!I32.empty())
194  {
195  SLVuint i32;
196  // copy the triangle that do not contain the index to delete
197  for (SLulong t = 0; t < I32.size(); t += 3)
198  {
199  if (I32[t] != ixDel &&
200  I32[t + 1] != ixDel &&
201  I32[t + 2] != ixDel)
202  {
203  if (I32[t] < ixDel)
204  i32.push_back(I32[t]);
205  else
206  i32.push_back(I32[t] - 1);
207  if (I32[t + 1] < ixDel)
208  i32.push_back(I32[t + 1]);
209  else
210  i32.push_back(I32[t + 1] - 1);
211  if (I32[t + 2] < ixDel)
212  i32.push_back(I32[t + 2]);
213  else
214  i32.push_back(I32[t + 2] - 1);
215  }
216  }
217  I32 = i32;
218  }
219  }
220 
221  deleteUnused();
222 
223  calcNormals();
224 
225  // build tangents for bump mapping
226  if (mat()->needsTangents() && !UV[0].empty() && T.empty())
227  calcTangents();
228 
229  // delete vertex array object so it gets regenerated
230  _vao.clearAttribs();
231  _vaoS.deleteGL();
232  _vaoN.deleteGL();
233  _vaoT.deleteGL();
234 
235  // delete the selection indexes
236  IS32.clear();
237 
238  // flag aabb and aceleration structure to be updated
239  node->needAABBUpdate();
241 }
vector< SLushort > SLVushort
Definition: SL.h:195
vector< SLuint > SLVuint
Definition: SL.h:197
void clearAttribs()
Clears the attribute definition.
virtual void calcNormals()
SLMesh::calcNormals recalculates vertex normals for triangle meshes.
Definition: SLMesh.cpp:1165
void calcTangents()
SLMesh::calcTangents computes the tangents per vertex for triangle meshes.
Definition: SLMesh.cpp:1229
void deleteUnused()
Deletes unused vertices (= vertices that are not indexed in I16 or I32)
Definition: SLMesh.cpp:244
SLGLVertexArrayExt _vaoS
OpenGL VAO for optional selection drawing.
Definition: SLMesh.h:237
SLMaterial * mat() const
Definition: SLMesh.h:177
void needAABBUpdate()
Definition: SLNode.cpp:665

◆ deleteUnused()

void SLMesh::deleteUnused ( )

Deletes unused vertices (= vertices that are not indexed in I16 or I32)

Definition at line 244 of file SLMesh.cpp.

245 {
246  // SLPoints have no indexes, so nothing to remove
247  if (I16.empty() && I32.empty())
248  return;
249 
250  // A boolean for each vertex to flag it as used or not
251  SLVbool used(P.size());
252  for (auto&& u : used)
253  u = false;
254 
255  // Loop over all indexes and mark them as used
256  for (unsigned short i : I16)
257  used[i] = true;
258 
259  for (unsigned int i : I32)
260  used[i] = true;
261 
262  SLuint unused = 0;
263  for (SLulong u = 0; u < used.size(); ++u)
264  {
265  if (!used[u])
266  {
267  unused++;
268  SLulong ixDel = u - (unused - 1);
269 
270  if (ixDel < P.size()) P.erase(P.begin() + ixDel);
271  if (ixDel < N.size()) N.erase(N.begin() + ixDel);
272  if (ixDel < C.size()) C.erase(C.begin() + ixDel);
273  if (ixDel < T.size()) T.erase(T.begin() + ixDel);
274  if (ixDel < UV[0].size()) UV[0].erase(UV[0].begin() + ixDel);
275  if (ixDel < UV[1].size()) UV[1].erase(UV[1].begin() + ixDel);
276  if (ixDel < Ji.size()) Ji.erase(Ji.begin() + ixDel);
277  if (ixDel < Jw.size()) Jw.erase(Jw.begin() + ixDel);
278 
279  // decrease the indexes smaller than the deleted on
280  for (unsigned short& i : I16)
281  {
282  if (i > ixDel)
283  i--;
284  }
285 
286  for (unsigned int& i : I32)
287  {
288  if (i > ixDel)
289  i--;
290  }
291  }
292  }
293 }
vector< SLbool > SLVbool
Definition: SL.h:189

◆ deselectPartialSelection()

void SLMesh::deselectPartialSelection ( )

Clears the partial selection but not the flag SLMesh::_isSelected See also SLMesh::handleRectangleSelection.

Definition at line 698 of file SLMesh.cpp.

699 {
701  IS32.clear();
702 }

◆ draw()

void SLMesh::draw ( SLSceneView sv,
SLNode node,
SLuint  instances = 0 
)
virtual

SLMesh::draw does the OpenGL rendering of the mesh. The GL_TRIANGLES primitives are rendered normally with the vertex position vector P, the normal vector N, the vector UV1 and the index vector I16 or I32. GL_LINES & GL_POINTS don't have normals and tex.coords. GL_POINTS don't have indexes (I16,I32) and are rendered with glDrawArrays instead glDrawElements. Optionally you can draw the normals and/or the uniform grid voxels.

The method performs the following steps:

1) Apply the drawing bits
2) Generate Vertex Array Object once
3) Apply the uniform variables to the shader
3a) Activate a shader program if it is not yet in use and apply all its material parameters.
3b) Pass the standard matrices to the shader program.
4) Finally do the draw call by calling SLGLVertexArray::drawElementsAs
5) Draw optional normals & tangents
6) Draw optional acceleration structure
7) Draw selected mesh with points

Please view also the full process of rendering one frame

Reimplemented in SLParticleSystem.

Definition at line 389 of file SLMesh.cpp.

390 {
391  SLGLState* stateGL = SLGLState::instance();
392 
393  // Check data
394  SLstring msg;
395  if (P.empty())
396  msg = "No vertex positions (P)\n";
397  if (_primitive != PT_points && I16.empty() && I32.empty())
398  msg += "No vertex indices (I16 or I32)\n";
399  if (msg.length() > 0)
400  {
401  SL_WARN_MSG((msg + "in SLMesh::draw: " + _name).c_str());
402  return;
403  }
404 
405  ////////////////////////
406  // 1) Apply Drawing Bits
407  ////////////////////////
408 
409  // Return if hidden
410  if (sv->drawBit(SL_DB_HIDDEN) || node->drawBit(SL_DB_HIDDEN))
411  return;
412 
413  SLGLPrimitiveType primitiveType = _primitive;
414 
415  // Set polygon mode
416  if ((sv->drawBit(SL_DB_MESHWIRED) || node->drawBit(SL_DB_MESHWIRED)) &&
417  typeid(*node) != typeid(SLSkybox))
418  {
419 #ifdef SL_GLES
420  primitiveType = PT_lineLoop; // There is no polygon line or point mode on ES2!
421 #else
422  stateGL->polygonLine(true);
423 #endif
424  }
425  else
426  stateGL->polygonLine(false);
427 
428  // Set face culling
429  bool noFaceCulling = sv->drawBit(SL_DB_CULLOFF) || node->drawBit(SL_DB_CULLOFF);
430  stateGL->cullFace(!noFaceCulling);
431 
432  // enable polygon offset if voxels are drawn to avoid stitching
433  if (sv->drawBit(SL_DB_VOXELS) || node->drawBit(SL_DB_VOXELS))
434  stateGL->polygonOffsetLine(true, -1.0f, -1.0f);
435 
436  ///////////////////////////////////////
437  // 2) Generate Vertex Array Object once
438  ///////////////////////////////////////
439 
440  if (!_vao.vaoID())
441  generateVAO(_vao);
442 
443  /////////////////////////////
444  // 3) Apply Uniform Variables
445  /////////////////////////////
446 
447  // 3.a) Apply mesh material if exists & differs from current
448  // If a material is not created so far, it will be created here
449  _mat->activate(sv->camera(),
450  &sv->s()->lights(),
451  (!Ji.empty() && !Jw.empty()));
452 
453  // 3.b) Pass the standard matrices to the shader program
454  SLGLProgram* sp = _mat->program();
455  sp->uniformMatrix4fv("u_mMatrix", 1, (SLfloat*)&stateGL->modelMatrix);
456  sp->uniformMatrix4fv("u_vMatrix", 1, (SLfloat*)&stateGL->viewMatrix);
457  sp->uniformMatrix4fv("u_pMatrix", 1, (SLfloat*)&stateGL->projectionMatrix);
458 
459  // Pass skeleton joint matrices to the shader program
460  if (!Ji.empty() && !Jw.empty())
461  {
462  // Only perform skinning in the shader if we haven't performed CPU skinning and if there are joint IDs
463  SLbool skinningEnabled = !_isCPUSkinned;
464  sp->uniform1i("u_skinningEnabled", skinningEnabled);
465 
466  if (skinningEnabled && !_jointMatrices.empty())
467  sp->uniformMatrix4fv("u_jointMatrices",
468  (SLsizei)_jointMatrices.size(),
469  (SLfloat*)&_jointMatrices[0]);
470  }
471 
472  SLint locTM = sp->getUniformLocation("u_tMatrix");
473  if (locTM >= 0)
474  {
475  if (_mat->has3DTexture() && _mat->textures3d()[0]->autoCalcTM3D())
476  calcTex3DMatrix(node);
477  else
478  stateGL->textureMatrix = _mat->textures(TT_diffuse)[0]->tm();
479  sp->uniformMatrix4fv(locTM, 1, (SLfloat*)&stateGL->textureMatrix);
480  }
481 
482  ///////////////////////////////
483  // 4): Finally do the draw call
484  ///////////////////////////////
485 
486  if ((sv->drawBit(SL_DB_ONLYEDGES) || node->drawBit(SL_DB_ONLYEDGES)) &&
487  (!IE32.empty() || !IE16.empty()))
489  else
490  {
491  if (_primitive == PT_points)
493  else
494  {
495  if (instances > 1)
496  _vao.drawElementsInstanced(primitiveType, instances);
497  else
498  _vao.drawElementsAs(primitiveType);
499 
500  if ((sv->drawBit(SL_DB_WITHEDGES) || node->drawBit(SL_DB_WITHEDGES)) &&
501  (!IE32.empty() || !IE16.empty()))
502  {
503  stateGL->polygonOffsetLine(true, 1.0f, 1.0f);
505  stateGL->polygonOffsetLine(false);
506  }
507  }
508  }
509 
510  //////////////////////////////////////
511  // 5) Draw optional normals & tangents
512  //////////////////////////////////////
513 
514  // All helper lines must be drawn without blending
515  SLbool blended = stateGL->blend();
516  if (blended) stateGL->blend(false);
517 
518  if (!N.empty() && (sv->drawBit(SL_DB_NORMALS) || node->drawBit(SL_DB_NORMALS)))
519  {
520  // Scale factor r 2% from scaled radius for normals & tangents
521  // Build array between vertex and normal target point
522  float r = node->aabb()->radiusOS() * 0.02f;
523  SLVVec3f V2;
524  V2.resize(P.size() * 2);
525  for (SLulong i = 0; i < P.size(); ++i)
526  {
527  V2[i << 1] = finalP((SLuint)i);
528  V2[(i << 1) + 1].set(finalP((SLuint)i) + finalN((SLuint)i) * r);
529  }
530 
531  // Create or update VAO for normals
533 
534  if (!T.empty())
535  {
536  for (SLulong i = 0; i < P.size(); ++i)
537  {
538  V2[(i << 1) + 1].set(finalP((SLuint)i).x + T[i].x * r,
539  finalP((SLuint)i).y + T[i].y * r,
540  finalP((SLuint)i).z + T[i].z * r);
541  }
542 
543  // Create or update VAO for tangents
545  }
546 
547  // Draw normals
549 
550  // Draw tangents if available
551  if (!T.empty())
553  if (blended)
554  stateGL->blend(false);
555  }
556  else
557  { // release buffer objects for normal & tangent rendering
558  if (_vaoN.vaoID())
559  _vaoN.deleteGL();
560  if (_vaoT.vaoID())
561  _vaoT.deleteGL();
562  }
563 
564  //////////////////////////////////////////
565  // 6) Draw optional acceleration structure
566  //////////////////////////////////////////
567 
568  if (_accelStruct)
569  {
570  if (sv->drawBit(SL_DB_VOXELS) || node->drawBit(SL_DB_VOXELS))
571  {
572  _accelStruct->draw(sv);
573  stateGL->polygonOffsetLine(false);
574  }
575  else
576  { // Delete the visualization VBO if not rendered anymore
578  }
579  }
580 
581  ////////////////////////////////////
582  // 7: Draw selected mesh with points
583  ////////////////////////////////////
584 
585  if (!node->drawBit(SL_DB_NOTSELECTABLE))
586  handleRectangleSelection(sv, stateGL, node);
587 
588  if (blended)
589  stateGL->blend(true);
590 }
#define SL_WARN_MSG(message)
Definition: SL.h:241
bool SLbool
Definition: SL.h:175
int SLsizei
Definition: SL.h:172
string SLstring
Definition: SL.h:158
#define SL_DB_ONLYEDGES
Draw only hard edges.
Definition: SLDrawBits.h:31
#define SL_DB_NORMALS
Draw the vertex normals.
Definition: SLDrawBits.h:23
#define SL_DB_WITHEDGES
Draw faces with hard edges.
Definition: SLDrawBits.h:30
#define SL_DB_NOTSELECTABLE
Flags an object as selected.
Definition: SLDrawBits.h:21
#define SL_DB_VOXELS
Draw the voxels of the uniform grid.
Definition: SLDrawBits.h:26
#define SL_DB_CULLOFF
Turn off face culling.
Definition: SLDrawBits.h:28
#define SL_DB_MESHWIRED
Draw polygons as wired mesh.
Definition: SLDrawBits.h:22
#define SL_DB_HIDDEN
Flags an object as hidden.
Definition: SLDrawBits.h:20
SLGLPrimitiveType
Definition: SLGLEnums.h:30
@ PT_points
Definition: SLGLEnums.h:31
@ PT_lineLoop
Definition: SLGLEnums.h:33
@ TT_diffuse
Definition: SLGLTexture.h:78
SLfloat radiusOS()
Definition: SLAABBox.h:55
virtual void draw(SLSceneView *sv)=0
virtual void disposeBuffers()=0
Encapsulation of an OpenGL shader program object.
Definition: SLGLProgram.h:56
SLint uniformMatrix4fv(const SLchar *name, SLsizei count, const SLfloat *value, GLboolean transpose=false) const
Passes a 4x4 float matrix values py pointer to the uniform variable "name".
SLint getUniformLocation(const SLchar *name) const
SLint uniform1i(const SLchar *name, SLint v0) const
Passes the int values v0 to the uniform variable "name".
SLMat4f modelMatrix
Init all states.
Definition: SLGLState.h:89
void polygonOffsetLine(SLbool enabled, SLfloat factor=-1.0f, SLfloat units=-1.0f)
Definition: SLGLState.cpp:335
SLMat4f viewMatrix
matrix for the active cameras view transform
Definition: SLGLState.h:91
void blend(SLbool state)
Definition: SLGLState.cpp:236
SLMat4f projectionMatrix
matrix for projection transform
Definition: SLGLState.h:90
void polygonLine(SLbool state)
Definition: SLGLState.cpp:290
void cullFace(SLbool state)
Definition: SLGLState.cpp:219
void generateVertexPos(SLVVec2f *p)
Adds or updates & generates a position vertex attribute for colored line or point drawing.
void drawArrayAsColored(SLGLPrimitiveType primitiveType, SLCol4f color, SLfloat lineOrPointSize=1.0f, SLuint indexFirstVertex=0, SLuint countVertices=0)
Draws the array as the specified primitive with the color.
void drawElementsAs(SLGLPrimitiveType primitiveType, SLuint numIndexes=0, SLuint indexOffsetBytes=0)
Draws the VAO by element indices with a primitive type.
void drawArrayAs(SLGLPrimitiveType primitiveType, SLint firstVertex=0, SLsizei countVertices=0)
Draws the VAO as an array with a primitive type.
void drawElementsInstanced(SLGLPrimitiveType primitiveType, SLuint countInstance=0, SLuint numIndexes=0, SLuint indexOffset=0)
Draws the VAO as an array with instance primitive type.
SLuint vaoID() const
Returns either the VAO id or the VBO id.
void drawEdges(SLCol4f color, SLfloat lineWidth=1.0f)
Draws the hard edges of the VAO with the edge indices.
SLbool has3DTexture()
Returns true if a material has a 3D texture.
Definition: SLMaterial.h:139
void activate(SLCamera *cam, SLVLight *lights, SLbool supportGPUSkinning)
Definition: SLMaterial.cpp:507
SLVGLTexture & textures(SLTextureType type)
Definition: SLMaterial.h:233
SLVGLTexture & textures3d()
Definition: SLMaterial.h:234
void program(SLGLProgram *sp)
Definition: SLMaterial.h:205
void handleRectangleSelection(SLSceneView *sv, SLGLState *stateGL, SLNode *node)
Handles the rectangle section of mesh vertices (partial selection)
Definition: SLMesh.cpp:606
virtual void generateVAO(SLGLVertexArray &vao)
Generate the Vertex Array Object for a specific shader program.
Definition: SLMesh.cpp:738
static void calcTex3DMatrix(SLNode *node)
Definition: SLMesh.cpp:1319
SLVec3f finalN(SLuint i)
Definition: SLMesh.h:188
SLbool _isCPUSkinned
Flag if mesh has been skinned on CPU during update.
Definition: SLMesh.h:258
SLbool drawBit(SLuint bit)
Definition: SLNode.h:300
SLstring _name
name of an object
Definition: SLObject.h:42
SLVLight & lights()
Definition: SLScene.h:107
SceneView class represents a dynamic real time 3D view onto the scene.
Definition: SLSceneView.h:69
void camera(SLCamera *camera)
Definition: SLSceneView.h:145
SLbool drawBit(SLuint bit)
Definition: SLSceneView.h:199
SLScene * s()
Definition: SLSceneView.h:167
Skybox node class with a SLBox mesh.
Definition: SLSkybox.h:29
static SLVec4 RED
Definition: SLVec4.h:216
static SLVec4 BLUE
Definition: SLVec4.h:218
void set(std::string path, const std::vector< char > &data)
Definition: SLIOMemory.cpp:29

◆ drawIntoDepthBuffer()

void SLMesh::drawIntoDepthBuffer ( SLSceneView sv,
SLNode node,
SLMaterial depthMat 
)

Simplified drawing method for shadow map creation.

This is used from within SLShadowMap::drawNodesIntoDepthBufferRec

Definition at line 330 of file SLMesh.cpp.

333 {
334  SLGLState* stateGL = SLGLState::instance();
335 
336  // Check data
337  SLstring msg;
338  if (P.empty())
339  msg = "No vertex positions (P)\n";
340 
341  if (_primitive == PT_points && I16.empty() && I32.empty())
342  msg += "No vertex indices (I16 or I32)\n";
343 
344  if (msg.length() > 0)
345  {
346  SL_WARN_MSG((msg + "in SLMesh::draw: " + _name).c_str());
347  return;
348  }
349 
350  // Return if hidden
351  if (node->levelForSM() == 0 &&
352  (node->drawBit(SL_DB_HIDDEN) || _primitive == PT_points))
353  return;
354 
355  if (!_vao.vaoID())
356  generateVAO(_vao);
357 
358  // Now use the depth material
359  SLGLProgram* sp = depthMat->program();
360  sp->useProgram();
361  sp->uniformMatrix4fv("u_mMatrix", 1, (SLfloat*)&stateGL->modelMatrix);
362  sp->uniformMatrix4fv("u_vMatrix", 1, (SLfloat*)&stateGL->viewMatrix);
363  sp->uniformMatrix4fv("u_pMatrix", 1, (SLfloat*)&stateGL->projectionMatrix);
364 
366 }
void useProgram()
void levelForSM(SLubyte lfsm)
Definition: SLNode.h:288

◆ drawSelectedVertices()

void SLMesh::drawSelectedVertices ( )
private

If the entire mesh is selected all points will be drawn with an the vertex array only without indices. If a subset is selected we use the extra index array IS32. See also SLMesh::handleRectangleSelection.

Definition at line 708 of file SLMesh.cpp.

710 {
711  SLGLState* stateGL = SLGLState::instance();
712  stateGL->polygonOffsetPoint(true);
713  stateGL->depthMask(false);
714  stateGL->depthTest(false);
715 
716  if (IS32.empty())
717  {
718  // Draw all
721  }
722  else
723  {
724  // Draw only selected
729  }
730 
731  stateGL->polygonLine(false);
732  stateGL->polygonOffsetPoint(false);
733  stateGL->depthMask(true);
734  stateGL->depthTest(true);
735 }
void polygonOffsetPoint(SLbool enabled, SLfloat factor=-1.0f, SLfloat units=-1.0f)
Definition: SLGLState.cpp:311
void depthMask(SLbool state)
Definition: SLGLState.cpp:190
void depthTest(SLbool state)
Definition: SLGLState.cpp:172
void drawElementAsColored(SLGLPrimitiveType primitiveType, SLCol4f color, SLfloat pointSize, SLuint indexFirstVertex=0, SLuint countVertices=0)
Draws the VAO by element indices with the specified primitive with the color.
void setIndices(SLuint numIndicesElements, SLGLBufferType indexDataType, void *indexDataElements, SLuint numIndicesEdges=0, void *indexDataEdges=nullptr)
Adds the index array for indexed element drawing.
static SLVec4 YELLOW
Definition: SLVec4.h:219

◆ edgeAngleDEG() [1/2]

SLfloat SLMesh::edgeAngleDEG ( ) const
inline

Definition at line 184 of file SLMesh.h.

184 { return _edgeAngleDEG; }

◆ edgeAngleDEG() [2/2]

void SLMesh::edgeAngleDEG ( SLfloat  ea)
inline

Definition at line 198 of file SLMesh.h.

198 { _edgeAngleDEG = ea; }

◆ edgeColor() [1/2]

SLCol4f SLMesh::edgeColor ( ) const
inline

Definition at line 186 of file SLMesh.h.

186 { return _edgeColor; }

◆ edgeColor() [2/2]

void SLMesh::edgeColor ( const SLCol4f ec)
inline

Definition at line 199 of file SLMesh.h.

199 { _edgeColor = ec; }

◆ edgeWidth() [1/2]

SLfloat SLMesh::edgeWidth ( ) const
inline

Definition at line 185 of file SLMesh.h.

185 { return _edgeWidth; }

◆ edgeWidth() [2/2]

void SLMesh::edgeWidth ( SLfloat  ew)
inline

Definition at line 197 of file SLMesh.h.

197 { _edgeWidth = ew; }

◆ finalN()

SLVec3f SLMesh::finalN ( SLuint  i)
inline

Definition at line 188 of file SLMesh.h.

188 { return _finalN->operator[](i); }

◆ finalP()

SLVec3f SLMesh::finalP ( SLuint  i)
inline

Definition at line 187 of file SLMesh.h.

187 { return _finalP->operator[](i); }

◆ generateVAO()

void SLMesh::generateVAO ( SLGLVertexArray vao)
virtual

Generate the Vertex Array Object for a specific shader program.

Definition at line 738 of file SLMesh.cpp.

739 {
741 
743  if (!N.empty()) vao.setAttrib(AT_normal, AT_normal, _finalN);
744  if (!UV[0].empty()) vao.setAttrib(AT_uv1, AT_uv1, &UV[0]);
745  if (!UV[1].empty()) vao.setAttrib(AT_uv2, AT_uv2, &UV[1]);
746  if (!C.empty()) vao.setAttrib(AT_color, AT_color, &C);
747  if (!T.empty()) vao.setAttrib(AT_tangent, AT_tangent, &T);
748 
749  if (!I16.empty() || !I32.empty())
750  {
751  // for triangle meshes compute hard edges and store indices behind the ones of the triangles
752  if (_primitive == PT_triangles)
753  {
754  IE16.clear();
755  IE32.clear();
757  if (!I16.empty()) vao.setIndices(&I16, &IE16);
758  if (!I32.empty()) vao.setIndices(&I32, &IE32);
759  }
760  else
761  {
762  // for points there are no indices at all
763  if (!I16.empty()) vao.setIndices(&I16);
764  if (!I32.empty()) vao.setIndices(&I32);
765  }
766  }
767 
768  SLVVec4i jointIndicesData; // indices are passed to the shader as ivec4s
769  SLVVec4f jointWeightsData; // weights are passed to the shader as vec4s
770 
771  if (!Ji.empty() && !Jw.empty())
772  {
773  assert(Ji.size() == P.size());
774  assert(Jw.size() == P.size());
775 
776  jointIndicesData = SLVVec4i(P.size(), SLVec4i(0, 0, 0, 0));
777  jointWeightsData = SLVVec4f(P.size(), SLVec4f(0.0f, 0.0f, 0.0f, 0.0f));
778 
779  // create the vec4 of indices for all points
780  for (unsigned i = 0; i < P.size(); i++)
781  {
782  const SLVuchar& curIndices = Ji[i];
783  assert(!curIndices.empty());
784 
785  jointIndicesData[i] = SLVec4i(curIndices.size() >= 1 ? curIndices[0] : 0,
786  curIndices.size() >= 2 ? curIndices[1] : 0,
787  curIndices.size() >= 3 ? curIndices[2] : 0,
788  curIndices.size() >= 4 ? curIndices[3] : 0);
789  }
790 
791  // create the vec4 of weights for all points
792  for (unsigned i = 0; i < P.size(); i++)
793  {
794  const SLVfloat& curWeights = Jw[i];
795  assert(curWeights.size() == Ji[i].size());
796 
797  jointWeightsData[i] = SLVec4f(curWeights.size() >= 1 ? curWeights[0] : 0.0f,
798  curWeights.size() >= 2 ? curWeights[1] : 0.0f,
799  curWeights.size() >= 3 ? curWeights[2] : 0.0f,
800  curWeights.size() >= 4 ? curWeights[3] : 0.0f);
801  }
802  vao.setAttrib(AT_jointIndex, AT_jointIndex, &jointIndicesData);
803  vao.setAttrib(AT_jointWeight, AT_jointWeight, &jointWeightsData);
804  }
805 
806  vao.generate((SLuint)P.size(),
807  !Ji.empty() ? BU_stream : BU_static,
808  Ji.empty());
809 }
#define PROFILE_FUNCTION()
Definition: Instrumentor.h:41
vector< SLuchar > SLVuchar
Definition: SL.h:193
vector< SLfloat > SLVfloat
Definition: SL.h:200
@ AT_jointWeight
Vertex joint weight for vertex skinning.
Definition: SLGLEnums.h:65
@ AT_jointIndex
Vertex joint id for vertex skinning.
Definition: SLGLEnums.h:64
@ AT_position
Vertex position as a 2, 3 or 4 component vectors.
Definition: SLGLEnums.h:58
@ AT_normal
Vertex normal as a 3 component vector.
Definition: SLGLEnums.h:59
@ AT_color
Vertex color as 3 or 4 component vector.
Definition: SLGLEnums.h:62
@ AT_uv1
Vertex 1st texture coordinate as 2 component vector.
Definition: SLGLEnums.h:60
@ AT_uv2
Vertex 2nd texture coordinate as 2 component vector.
Definition: SLGLEnums.h:61
@ AT_tangent
Vertex tangent as a 4 component vector (see SLMesh)
Definition: SLGLEnums.h:63
@ BU_stream
Buffer will be modified once and used at most a few times.
Definition: SLGLEnums.h:92
@ BU_static
Buffer will be modified once and used many times.
Definition: SLGLEnums.h:91
vector< SLVec4f > SLVVec4f
Definition: SLVec4.h:239
vector< SLVec4i > SLVVec4i
Definition: SLVec4.h:240
SLVec4< SLint > SLVec4i
Definition: SLVec4.h:236
SLVec4< SLfloat > SLVec4f
Definition: SLVec4.h:235
void setAttrib(SLGLAttributeType type, SLint elementSize, SLint location, void *dataPointer, SLGLBufferType dataType=BT_float)
Adds a vertex attribute with data pointer and an element size.
void generate(SLuint numVertices, SLGLBufferUsage usage=BU_static, SLbool outputInterleaved=true, SLuint divisor=0)
Generates the VA & VB objects for a NO. of vertices.
void computeHardEdgesIndices(float angleRAD, float epsilon)
computes the hard edges and stores the vertex indexes separately
Definition: SLMesh.cpp:819
SLGLVertexArray & vao()
Definition: SLMesh.h:182

◆ handleRectangleSelection()

void SLMesh::handleRectangleSelection ( SLSceneView sv,
SLGLState stateGL,
SLNode node 
)
private

Handles the rectangle section of mesh vertices (partial selection)

Definition at line 606 of file SLMesh.cpp.

609 {
610  SLScene* s = sv->s();
611  SLCamera* cam = sv->camera();
612 
613  // Single node and mesh is selected
614  if (cam->selectRect().isEmpty() && cam->deselectRect().isEmpty())
615  {
616  if (node->isSelected() && _isSelected)
618  }
619  else // rect selection or deselection is going on
620  {
621  // Build full viewport-modelview-projection transform matrix
622  SLMat4f mvp(stateGL->projectionMatrix * stateGL->viewMatrix * node->updateAndGetWM());
623  SLMat4f v;
624  SLRecti vp = sv->viewportRect();
625  v.viewport((SLfloat)vp.x,
626  (SLfloat)vp.y,
627  (SLfloat)vp.width,
628  (SLfloat)vp.height);
629  SLMat4f v_mvp = v * mvp;
630  set<SLuint> tempIselected; // Temp. vector for selected vertex indices
631 
632  if (!cam->selectRect().isEmpty()) // Do rectangle Selection
633  {
634  // Select by transform all vertices and add the ones in the rect to tempInRect
635  set<SLuint> tempInRect;
636  for (SLulong i = 0; i < P.size(); ++i)
637  {
638  SLVec3f p = v_mvp * P[i];
639  if (cam->selectRect().contains(SLVec2f(p.x, p.y)))
640  tempInRect.insert((SLuint)i);
641  }
642 
643  // Merge the rectangle selected by doing a set union operation
644  set<SLuint> IS32set(IS32.begin(), IS32.end());
645  std::set_union(IS32set.begin(),
646  IS32set.end(),
647  tempInRect.begin(),
648  tempInRect.end(),
649  inserter(tempIselected, tempIselected.begin()));
650  }
651  else if (!cam->deselectRect().isEmpty()) // Do rectangle Deselection
652  {
653  // Deselect by transform all vertices and add the ones in the rect to tempIdeselected
654  set<SLuint> tempIdeselected; // Temp. vector for deselected vertex indices
655  for (SLulong i = 0; i < P.size(); ++i)
656  {
657  SLVec3f p = v_mvp * P[i];
658  if (cam->deselectRect().contains(SLVec2f(p.x, p.y)))
659  tempIdeselected.insert((SLuint)i);
660  }
661 
662  // Remove the deselected ones by doing a set difference operation
663  tempIselected.clear();
664  set<SLuint> IS32set(IS32.begin(), IS32.end());
665  std::set_difference(IS32set.begin(),
666  IS32set.end(),
667  tempIdeselected.begin(),
668  tempIdeselected.end(),
669  inserter(tempIselected, tempIselected.begin()));
670  }
671 
672  // Flag node and mesh for the first time a mesh gets rectangle selected.
673  if (!tempIselected.empty() && !node->isSelected() && !_isSelected)
674  {
675  node->isSelected(true);
676  s->selectedNodes().push_back(node);
677  _isSelected = true;
678  s->selectedMeshes().push_back(this);
680  }
681 
682  // Do not rect-select if the mesh is not selected because it got
683  // selected within another node.
684  if (node->isSelected() && _isSelected)
685  {
686  if (!tempIselected.empty())
687  IS32.assign(tempIselected.begin(), tempIselected.end());
688 
689  if (!IS32.empty())
691  }
692  }
693 }
Active or visible camera node class.
Definition: SLCamera.h:54
SLRectf & deselectRect()
Definition: SLCamera.h:172
SLRectf & selectRect()
Definition: SLCamera.h:171
void viewport(T x, T y, T ww, T wh, T n=0.0f, T f=1.0f)
Defines the viewport matrix.
Definition: SLMat4.h:930
void drawSelectedVertices()
Definition: SLMesh.cpp:708
const SLMat4f & updateAndGetWM() const
Definition: SLNode.cpp:703
void isSelected(bool isSelected)
Definition: SLNode.h:286
T width
Definition: SLRect.h:29
T y
Definition: SLRect.h:29
SLbool isEmpty() const
Definition: SLRect.h:74
T x
Definition: SLRect.h:29
SLbool contains(T X, T Y)
Definition: SLRect.h:76
T height
Definition: SLRect.h:29
SLVMesh & selectedMeshes()
Definition: SLScene.h:125
SLVNode & selectedNodes()
Definition: SLScene.h:124
SLRecti viewportRect() const
Definition: SLSceneView.h:176

◆ hit()

SLbool SLMesh::hit ( SLRay ray,
SLNode node 
)

SLMesh::hit does the ray-mesh intersection test. If no acceleration structure is defined all triangles are tested in a brute force manner.

Definition at line 910 of file SLMesh.cpp.

911 {
912  // return true for point & line objects
913  if (_primitive != PT_triangles)
914  {
915  ray->hitNode = node;
916  ray->hitMesh = this;
917  SLVec3f OC = node->aabb()->centerWS() - ray->origin;
918  ray->length = OC.length();
919  return true;
920  }
921 
922  // Force the mesh to be skinned in software even if it would be normally
923  // skinned on the GPU. We need the results from the skinning on the CPU to
924  // perform the ray-triangle intersection.
925  if (_skeleton && _mat && (!Ji.empty() && !Jw.empty()) && !_isCPUSkinned)
926  transformSkin(true, [](SLMesh*) {});
927 
928  if (_accelStruct)
929  {
932 
933  return _accelStruct->intersect(ray, node);
934  }
935  else
936  { // intersect against all faces
937  SLbool wasHit = false;
938 
939  for (SLuint t = 0; t < numI(); t += 3)
940  if (hitTriangleOS(ray, node, t) && !wasHit)
941  wasHit = true;
942 
943  return wasHit;
944  }
945 }
SLVec3f centerWS()
Definition: SLAABBox.h:50
virtual SLbool intersect(SLRay *ray, SLNode *node)=0
An SLMesh object is a triangulated mesh, drawn with one draw call.
Definition: SLMesh.h:134
void transformSkin(bool forceCPUSkinning, const std::function< void(SLMesh *)> &cbInformNodes)
Transforms the vertex positions and normals with by joint weights.
Definition: SLMesh.cpp:1573
SLbool hitTriangleOS(SLRay *ray, SLNode *node, SLuint iT)
Definition: SLMesh.cpp:1345
SLVec3f origin
Vector to the origin of ray in WS.
Definition: SLRay.h:75
SLMesh * hitMesh
Points to the intersected mesh.
Definition: SLRay.h:106
SLfloat length
length from origin to an intersection
Definition: SLRay.h:77
SLNode * hitNode
Points to the intersected node.
Definition: SLRay.h:105
T length() const
Definition: SLVec3.h:122

◆ hitTriangleOS()

SLbool SLMesh::hitTriangleOS ( SLRay ray,
SLNode node,
SLuint  iT 
)

SLMesh::hitTriangleOS is the fast and minimum storage ray-triangle intersection test by Tomas Moeller and Ben Trumbore (Journal of graphics tools 2, 1997).

Definition at line 1345 of file SLMesh.cpp.

1346 {
1347  assert(ray && "ray pointer is null");
1348  assert(node && "node pointer is null");
1349  assert(_mat && "material pointer is null");
1350 
1351  ++SLRay::tests;
1352 
1353  if (_primitive != PT_triangles)
1354  return false;
1355 
1356  // prevent self-intersection of triangle
1357  if (ray->srcMesh == this && ray->srcTriangle == (SLint)iT)
1358  return false;
1359 
1360  SLVec3f cornerA, cornerB, cornerC;
1361  SLVec3f e1, e2; // edge 1 and 2
1362  SLVec3f AO, K, Q;
1363 
1364  // get the corner vertices
1365  if (!I16.empty())
1366  {
1367  cornerA = finalP(I16[iT]);
1368  cornerB = finalP(I16[iT + 1]);
1369  cornerC = finalP(I16[iT + 2]);
1370  }
1371  else
1372  {
1373  cornerA = finalP(I32[iT]);
1374  cornerB = finalP(I32[iT + 1]);
1375  cornerC = finalP(I32[iT + 2]);
1376  }
1377 
1378  // find vectors for two edges sharing the triangle vertex A
1379  e1.sub(cornerB, cornerA);
1380  e2.sub(cornerC, cornerA);
1381 
1382  // begin calculating determinant - also used to calculate U parameter
1383  K.cross(ray->dirOS, e2);
1384 
1385  // if determinant is near zero, ray lies in plane of triangle
1386  const SLfloat det = e1.dot(K);
1387 
1388  SLfloat inv_det, t, u, v;
1389 
1390  // if ray is outside do test with face culling
1391  if (ray->isOutside && _isVolume)
1392  { // check only front side triangles
1393 
1394  // exit if ray is from behind or parallel
1395  if (det < FLT_EPSILON) return false;
1396 
1397  // calculate distance from corner A to ray origin
1398  AO.sub(ray->originOS, cornerA);
1399 
1400  // Calculate barycentric coordinates: u>0 && v>0 && u+v<=1
1401  u = AO.dot(K);
1402  if (u < 0.0f || u > det) return false;
1403 
1404  // prepare to test v parameter
1405  Q.cross(AO, e1);
1406 
1407  // calculate v parameter and test bounds
1408  v = Q.dot(ray->dirOS);
1409  if (v < 0.0f || u + v > det) return false;
1410 
1411  // calculate intersection distance t
1412  inv_det = 1.0f / det;
1413  t = e2.dot(Q) * inv_det;
1414 
1415  // if intersection is closer replace ray intersection parameters
1416  if (t > ray->length || t < 0.0f) return false;
1417 
1418  ray->length = t;
1419 
1420  // scale down u & v so that u+v<=1
1421  ray->hitU = u * inv_det;
1422  ray->hitV = v * inv_det;
1423  }
1424  else
1425  { // check front & backside triangles
1426  // exit if ray is parallel
1427  if (det < FLT_EPSILON && det > -FLT_EPSILON) return false;
1428 
1429  inv_det = 1.0f / det;
1430 
1431  // calculate distance from corner A to ray origin
1432  AO.sub(ray->originOS, cornerA);
1433 
1434  // Calculate barycentric coordinates: u>0 && v>0 && u+v<=1
1435  u = AO.dot(K) * inv_det;
1436  if (u < 0.0f || u > 1.0f) return false;
1437 
1438  // prepare to test v parameter
1439  Q.cross(AO, e1);
1440 
1441  // calculate v parameter and test bounds
1442  v = Q.dot(ray->dirOS) * inv_det;
1443  if (v < 0.0f || u + v > 1.0f) return false;
1444 
1445  // calculate t, ray intersects triangle
1446  t = e2.dot(Q) * inv_det;
1447 
1448  // if intersection is closer replace ray intersection parameters
1449  if (t > ray->length || t < 0.0f) return false;
1450 
1451  ray->length = t;
1452  ray->hitU = u;
1453  ray->hitV = v;
1454  }
1455 
1456  ray->hitTriangle = (SLint)iT;
1457  ray->hitNode = node;
1458  ray->hitMesh = this;
1459 
1461 
1462  return true;
1463 }
SLint hitTriangle
Points to the intersected triangle.
Definition: SLRay.h:107
static SLuint intersections
NO. of intersection.
Definition: SLRay.h:133
SLint srcTriangle
Points to the triangle at ray origin.
Definition: SLRay.h:99
static SLuint tests
NO. of intersection tests.
Definition: SLRay.h:132
SLbool isOutside
Flag if ray is inside of a material.
Definition: SLRay.h:95
SLMesh * srcMesh
Points to the mesh at ray origin.
Definition: SLRay.h:98
SLVec3f dirOS
Direction vector of ray in OS.
Definition: SLRay.h:81
SLVec3f originOS
Vector to the origin of ray in OS.
Definition: SLRay.h:80
SLfloat hitV
barycentric coords in hit triangle
Definition: SLRay.h:104
SLfloat hitU
Definition: SLRay.h:104

◆ init()

void SLMesh::init ( SLNode node)
virtual

SLMesh::shapeInit sets the transparency flag of the AABB.

Definition at line 296 of file SLMesh.cpp.

297 {
298  // Check data
299  SLstring msg;
300  if (P.empty())
301  msg = "No vertex positions (P)\n";
302  if (_primitive != PT_points && I16.empty() && I32.empty())
303  msg += "No vertex indices (I16 or I32)\n";
304  if (msg.length() > 0)
305  SL_EXIT_MSG((msg + "in SLMesh::init: " + _name).c_str());
306 
307  if (N.empty()) calcNormals();
308 
309  // Set default materials if no materials are assigned
310  // If colors are available use diffuse color attribute shader
311  // otherwise use the default gray material
312  if (!mat())
313  {
314  if (!C.empty())
316  else
318  }
319 
320  // build tangents for bump mapping
321  if (mat()->needsTangents() && !UV[0].empty() && T.empty())
322  calcTangents();
323 
324  _isSelected = false;
325 }
#define SL_EXIT_MSG(message)
Definition: SL.h:240
static SLMaterialDefaultColorAttribute * instance()
Definition: SLMaterial.h:315
static SLMaterialDefaultGray * instance()
Definition: SLMaterial.h:286

◆ isSelected() [1/2]

SLbool SLMesh::isSelected ( ) const
inline

Definition at line 183 of file SLMesh.h.

183 { return _isSelected; }

◆ isSelected() [2/2]

void SLMesh::isSelected ( bool  isSelected)
inline

Definition at line 196 of file SLMesh.h.

196 { _isSelected = isSelected; }
SLbool isSelected() const
Definition: SLMesh.h:183

◆ mat() [1/2]

SLMaterial* SLMesh::mat ( ) const
inline

Definition at line 177 of file SLMesh.h.

177 { return _mat; }

◆ mat() [2/2]

void SLMesh::mat ( SLMaterial m)
inline

Definition at line 192 of file SLMesh.h.

192 { _mat = m; }

◆ matOut() [1/2]

SLMaterial* SLMesh::matOut ( ) const
inline

Definition at line 178 of file SLMesh.h.

178 { return _matOut; }

◆ matOut() [2/2]

void SLMesh::matOut ( SLMaterial m)
inline

Definition at line 193 of file SLMesh.h.

193 { _matOut = m; }

◆ numI()

SLuint SLMesh::numI ( ) const
inline

Definition at line 181 of file SLMesh.h.

181 { return (SLuint)(!I16.empty() ? I16.size() : I32.size()); }

◆ preShade()

void SLMesh::preShade ( SLRay ray)
virtual

SLMesh::preShade calculates the rest of the intersection information after the final hit point is determined. Should be called just before the shading when the final intersection point of the closest triangle was found.

Definition at line 1470 of file SLMesh.cpp.

1471 {
1472  if (_primitive != PT_triangles)
1473  return;
1474 
1475  // Get the triangle indices
1476  SLuint iA, iB, iC;
1477  if (!I16.empty())
1478  {
1479  iA = I16[(SLushort)ray->hitTriangle];
1480  iB = I16[(SLushort)ray->hitTriangle + 1];
1481  iC = I16[(SLushort)ray->hitTriangle + 2];
1482  }
1483  else
1484  {
1485  iA = I32[(SLuint)ray->hitTriangle];
1486  iB = I32[(SLuint)ray->hitTriangle + 1];
1487  iC = I32[(SLuint)ray->hitTriangle + 2];
1488  }
1489 
1490  // calculate the hit point in world space
1491  ray->hitPoint.set(ray->origin + ray->length * ray->dir);
1492 
1493  // calculate the interpolated normal with vertex normals in object space
1494  ray->hitNormal.set(finalN(iA) * (1 - (ray->hitU + ray->hitV)) +
1495  finalN(iB) * ray->hitU +
1496  finalN(iC) * ray->hitV);
1497 
1498  // transform normal back to world space
1499  SLMat3f wmN(ray->hitNode->updateAndGetWM().mat3());
1500  ray->hitNormal.set(wmN * ray->hitNormal);
1501 
1502  // for shading the normal is expected to be unit length
1503  ray->hitNormal.normalize();
1504 
1505  // calculate interpolated texture coordinates
1506  SLVGLTexture& diffuseTex = ray->hitMesh->mat()->textures(TT_diffuse);
1507 
1508  if (!diffuseTex.empty() &&
1509  !diffuseTex[0]->images().empty() &&
1510  !UV[0].empty())
1511  {
1512  SLVec2f Tu(UV[0][iB] - UV[0][iA]);
1513  SLVec2f Tv(UV[0][iC] - UV[0][iA]);
1514  SLVec2f tc(UV[0][iA] + ray->hitU * Tu + ray->hitV * Tv);
1515  ray->hitTexColor.set(diffuseTex[0]->getTexelf(tc.x, tc.y));
1516 
1517  // bump mapping
1518  SLVGLTexture& bumpTex = ray->hitMesh->mat()->textures(TT_normal);
1519  if (!bumpTex.empty() && !bumpTex[0]->images().empty())
1520  {
1521  if (!T.empty())
1522  {
1523  // calculate the interpolated tangent with vertex tangent in object space
1524  SLVec4f hitT(T[iA] * (1 - (ray->hitU + ray->hitV)) +
1525  T[iB] * ray->hitU +
1526  T[iC] * ray->hitV);
1527 
1528  SLVec3f T3(hitT.x, hitT.y, hitT.z); // tangent with 3 components
1529  T3.set(wmN * T3); // transform tangent back to world space
1530  SLVec2f d = bumpTex[0]->dudv(tc.x, tc.y); // slope of bump-map at tc
1531  SLVec3f Nrm = ray->hitNormal; // unperturbated normal
1532  SLVec3f B(Nrm ^ T3); // bi-normal tangent B
1533  B *= T[iA].w; // correct handedness
1534  SLVec3f D(d.x * T3 + d.y * B); // perturbation vector D
1535  Nrm += D;
1536  Nrm.normalize();
1537  ray->hitNormal.set(Nrm);
1538  }
1539  }
1540 
1541  // Get ambient occlusion
1542  SLVGLTexture& aoTex = ray->hitMesh->mat()->textures(TT_occlusion);
1543  if (!UV[1].empty())
1544  {
1545  SLVec2f Tu2(UV[1][iB] - UV[1][iA]);
1546  SLVec2f Tv2(UV[1][iC] - UV[1][iA]);
1547  SLVec2f tc2(UV[1][iA] + ray->hitU * Tu2 + ray->hitV * Tv2);
1548 
1549  if (!aoTex.empty())
1550  ray->hitAO = aoTex[0]->getTexelf(tc2.x, tc2.y).r;
1551  }
1552  }
1553 
1554  // calculate interpolated color for meshes with color attributes
1555  if (!ray->hitMesh->C.empty())
1556  {
1557  SLCol4f CA = ray->hitMesh->C[iA];
1558  SLCol4f CB = ray->hitMesh->C[iB];
1559  SLCol4f CC = ray->hitMesh->C[iC];
1560  ray->hitTexColor.set(CA * (1 - (ray->hitU + ray->hitV)) +
1561  CB * ray->hitU +
1562  CC * ray->hitV);
1563  }
1564 }
@ TT_normal
Definition: SLGLTexture.h:79
@ TT_occlusion
Definition: SLGLTexture.h:83
vector< SLGLTexture * > SLVGLTexture
STL vector of SLGLTexture pointers.
Definition: SLGLTexture.h:342
SLMat3< T > mat3() const
Definition: SLMat4.h:98
SLfloat hitAO
Ambient occlusion factor at intersection point.
Definition: SLRay.h:113
SLVec3f dir
Direction vector of ray in WS.
Definition: SLRay.h:76
SLVec3f hitPoint
Point of intersection.
Definition: SLRay.h:110
SLCol4f hitTexColor
Color at intersection for texture or color attributes.
Definition: SLRay.h:112
SLVec3f hitNormal
Surface normal at intersection point.
Definition: SLRay.h:111
T y
Definition: SLVec2.h:30
T x
Definition: SLVec2.h:30
SLVec3 & normalize()
Definition: SLVec3.h:124
void set(const T X, const T Y, const T Z, const T W=1)
Definition: SLVec4.h:49

◆ primitive() [1/2]

SLGLPrimitiveType SLMesh::primitive ( ) const
inline

Definition at line 179 of file SLMesh.h.

179 { return _primitive; }

◆ primitive() [2/2]

void SLMesh::primitive ( SLGLPrimitiveType  pt)
inline

Definition at line 194 of file SLMesh.h.

194 { _primitive = pt; }

◆ skeleton() [1/2]

const SLAnimSkeleton* SLMesh::skeleton ( ) const
inline

Definition at line 180 of file SLMesh.h.

180 { return _skeleton; }

◆ skeleton() [2/2]

void SLMesh::skeleton ( SLAnimSkeleton skel)
inline

Definition at line 195 of file SLMesh.h.

195 { _skeleton = skel; }

◆ transformSkin()

void SLMesh::transformSkin ( bool  forceCPUSkinning,
const std::function< void(SLMesh *)> &  cbInformNodes 
)

Transforms the vertex positions and normals with by joint weights.

If the mesh is used for skinned skeleton animation this method transforms each vertex and normal by max. four joints of the skeleton. Each joint has a weight and an index. After the transform the VBO have to be updated. This skinning process can also be done (a lot faster) on the GPU. This software skinning is also needed for ray or path tracing.

Definition at line 1573 of file SLMesh.cpp.

1575 {
1576  if (_isSelected)
1577  forceCPUSkinning = true;
1578 
1579  // create the secondary buffers for P and N once
1580  if (skinnedP.empty())
1581  {
1582  skinnedP.resize(P.size());
1583  for (SLulong i = 0; i < P.size(); ++i)
1584  skinnedP[i] = P[i];
1585  }
1586  if (skinnedN.empty() && !N.empty())
1587  {
1588  skinnedN.resize(P.size());
1589  for (SLulong i = 0; i < P.size(); ++i)
1590  skinnedN[i] = N[i];
1591  }
1592 
1593  // Create array for joint matrices once
1594  if (_jointMatrices.empty())
1595  {
1596  _jointMatrices.clear();
1598  }
1599 
1600  // update the joint matrix array
1602 
1603  // notify parent nodes to update AABB
1604  cbInformNodes(this);
1605 
1606  // flag acceleration structure to be rebuilt
1607  _accelStructIsOutOfDate = true;
1608 
1609  // remember if this node has been skinned on the CPU
1610  _isCPUSkinned = forceCPUSkinning;
1611 
1612  // Perform software skinning if the material doesn't support CPU skinning or
1613  // if the results of the skinning process are required somewhere else.
1614  if (forceCPUSkinning)
1615  {
1616  _finalP = &skinnedP;
1617  _finalN = &skinnedN;
1618 
1619  // iterate over all vertices and write to new buffers
1620  for (SLulong i = 0; i < P.size(); ++i)
1621  {
1622  skinnedP[i] = SLVec3f::ZERO;
1623  if (!N.empty()) skinnedN[i] = SLVec3f::ZERO;
1624 
1625  // accumulate final normal and positions
1626  for (SLulong j = 0; j < Ji[i].size(); ++j)
1627  {
1628  const SLMat4f& jm = _jointMatrices[Ji[i][j]];
1629  SLVec4f tempPos = SLVec4f(jm * P[i]);
1630  skinnedP[i].x += tempPos.x * Jw[i][j];
1631  skinnedP[i].y += tempPos.y * Jw[i][j];
1632  skinnedP[i].z += tempPos.z * Jw[i][j];
1633 
1634  if (!N.empty())
1635  {
1636  // Build the 3x3 submatrix in GLSL 110 (= mat3 jt3 = mat3(jt))
1637  // for the normal transform that is the normally the inverse transpose.
1638  // The inverse transpose can be ignored as long as we only have
1639  // rotation and uniform scaling in the 3x3 submatrix.
1640  SLMat3f jnm = jm.mat3();
1641  skinnedN[i] += jnm * N[i] * Jw[i][j];
1642  }
1643  }
1644  }
1645  }
1646  else
1647  {
1648  _finalP = &P;
1649  _finalN = &N;
1650  }
1651 
1652  // update or create buffers
1653  if (_vao.vaoID())
1654  {
1656  if (!N.empty()) _vao.updateAttrib(AT_normal, _finalN);
1657  }
1658 }
SLint numJoints() const
void getJointMatrices(SLVMat4f &jointWM)
void updateAttrib(SLGLAttributeType type, SLint elementSize, void *dataPointer)
Updates a specific vertex attribute in the VBO.
T z
Definition: SLVec4.h:32
T y
Definition: SLVec4.h:32
T x
Definition: SLVec4.h:32

◆ updateAccelStruct()

void SLMesh::updateAccelStruct ( )

SLMesh::updateAccelStruct rebuilds the acceleration structure if the dirty flag is set. This can happen for mesh animations.

Definition at line 1133 of file SLMesh.cpp.

1134 {
1135  calcMinMax();
1136 
1137  // Add half a percent in each direction to avoid zero size dimensions
1138  SLVec3f distMinMax = maxP - minP;
1139  SLfloat addon = distMinMax.length() * 0.005f;
1140  minP -= addon;
1141  maxP += addon;
1142 
1143  if (_primitive != PT_triangles)
1144  return;
1145 
1146  if (_accelStruct == nullptr)
1147  _accelStruct = new SLCompactGrid(this);
1148 
1149  if (_accelStruct && numI() > 15)
1150  {
1152  _accelStructIsOutOfDate = false;
1153  }
1154 }
virtual void build(SLVec3f minV, SLVec3f maxV)=0
Class for compact uniform grid acceleration structure.
Definition: SLCompactGrid.h:30
virtual void calcMinMax()
Definition: SLMesh.cpp:978

◆ vao()

SLGLVertexArray& SLMesh::vao ( )
inline

Definition at line 182 of file SLMesh.h.

182 { return _vao; }

◆ vertexPosEpsilon()

void SLMesh::vertexPosEpsilon ( SLfloat  eps)
inline

Definition at line 200 of file SLMesh.h.

200 { _vertexPosEpsilon = eps; }

Member Data Documentation

◆ _accelStruct

SLAccelStruct* SLMesh::_accelStruct
protected

KD-tree or uniform grid.

Definition at line 254 of file SLMesh.h.

◆ _accelStructIsOutOfDate

SLbool SLMesh::_accelStructIsOutOfDate
protected

Flag if accel. struct needs update.

Definition at line 255 of file SLMesh.h.

◆ _edgeAngleDEG

SLfloat SLMesh::_edgeAngleDEG
protected

Edge crease angle in degrees between face normals (30 deg. default)

Definition at line 239 of file SLMesh.h.

◆ _edgeColor

SLCol4f SLMesh::_edgeColor
protected

Color for hard edge drawing.

Definition at line 241 of file SLMesh.h.

◆ _edgeWidth

SLfloat SLMesh::_edgeWidth
protected

Line width for hard edge drawing.

Definition at line 240 of file SLMesh.h.

◆ _finalN

SLVVec3f* SLMesh::_finalN
protected

pointer to final vertex normal vector

Definition at line 260 of file SLMesh.h.

◆ _finalP

SLVVec3f* SLMesh::_finalP
protected

Pointer to final vertex position vector.

Definition at line 259 of file SLMesh.h.

◆ _isCPUSkinned

SLbool SLMesh::_isCPUSkinned
protected

Flag if mesh has been skinned on CPU during update.

Definition at line 258 of file SLMesh.h.

◆ _isSelected

SLbool SLMesh::_isSelected
protected

Flag if mesh is partially of fully selected.

Definition at line 238 of file SLMesh.h.

◆ _isVolume

SLbool SLMesh::_isVolume
protected

Flag for RT if mesh is a closed volume.

Definition at line 253 of file SLMesh.h.

◆ _jointMatrices

SLVMat4f SLMesh::_jointMatrices
protected

Joint matrix vector for this mesh.

Definition at line 257 of file SLMesh.h.

◆ _mat

SLMaterial* SLMesh::_mat
protected

Pointer to the inside material.

Definition at line 232 of file SLMesh.h.

◆ _matOut

SLMaterial* SLMesh::_matOut
protected

Pointer to the outside material.

Definition at line 233 of file SLMesh.h.

◆ _primitive

SLGLPrimitiveType SLMesh::_primitive
protected

Primitive type (default triangles)

Definition at line 231 of file SLMesh.h.

◆ _skeleton

SLAnimSkeleton* SLMesh::_skeleton
protected

The skeleton this mesh is bound to.

Definition at line 256 of file SLMesh.h.

◆ _vao

SLGLVertexArray SLMesh::_vao
protected

Main OpenGL Vertex Array Object for drawing.

Definition at line 234 of file SLMesh.h.

◆ _vaoN

SLGLVertexArrayExt SLMesh::_vaoN
protected

OpenGL VAO for optional normal drawing.

Definition at line 235 of file SLMesh.h.

◆ _vaoS

SLGLVertexArrayExt SLMesh::_vaoS
protected

OpenGL VAO for optional selection drawing.

Definition at line 237 of file SLMesh.h.

◆ _vaoT

SLGLVertexArrayExt SLMesh::_vaoT
protected

OpenGL VAO for optional tangent drawing.

Definition at line 236 of file SLMesh.h.

◆ _vertexPosEpsilon

SLfloat SLMesh::_vertexPosEpsilon
protected

Vertex position epsilon used in computeHardEdgesIndices.

Definition at line 242 of file SLMesh.h.

◆ C

SLVCol4f SLMesh::C

Vector of vertex colors (opt.) layout (location = 4)

Definition at line 206 of file SLMesh.h.

◆ I16

SLVushort SLMesh::I16

Vector of vertex indices 16 bit.

Definition at line 214 of file SLMesh.h.

◆ I32

SLVuint SLMesh::I32

Vector of vertex indices 32 bit.

Definition at line 215 of file SLMesh.h.

◆ IE16

SLVushort SLMesh::IE16

Vector of hard edges vertex indices 16 bit (see computeHardEdgesIndices)

Definition at line 217 of file SLMesh.h.

◆ IE32

SLVuint SLMesh::IE32

Vector of hard edges vertex indices 32 bit (see computeHardEdgesIndices)

Definition at line 218 of file SLMesh.h.

◆ IS32

SLVuint SLMesh::IS32

Vector of rectangle selected vertex indices 32 bit.

Definition at line 216 of file SLMesh.h.

◆ Ji

SLVVuchar SLMesh::Ji

2D Vector of per vertex joint ids (opt.) layout (location = 6)

Definition at line 208 of file SLMesh.h.

◆ Jw

SLVVfloat SLMesh::Jw

2D Vector of per vertex joint weights (opt.) layout (location = 7)

Definition at line 209 of file SLMesh.h.

◆ maxP

SLVec3f SLMesh::maxP

max. vertex in OS

Definition at line 221 of file SLMesh.h.

◆ minP

SLVec3f SLMesh::minP

min. vertex in OS

Definition at line 220 of file SLMesh.h.

◆ N

SLVVec3f SLMesh::N

Vector for vertex normals (opt.) layout (location = 1)

Definition at line 204 of file SLMesh.h.

◆ P

SLVVec3f SLMesh::P

Vector for vertex positions layout (location = 0)

Definition at line 203 of file SLMesh.h.

◆ skinnedN

SLVVec3f SLMesh::skinnedN

temp. vector for CPU skinned vertex normals

Definition at line 211 of file SLMesh.h.

◆ skinnedP

SLVVec3f SLMesh::skinnedP

temp. vector for CPU skinned vertex positions

Definition at line 210 of file SLMesh.h.

◆ T

SLVVec4f SLMesh::T

Vector of vertex tangents (opt.) layout (location = 5)

Definition at line 207 of file SLMesh.h.

◆ UV

SLVVec2f SLMesh::UV[2]

Array of 2 Vectors for tex. coords. (opt.) layout (location = 2)

Definition at line 205 of file SLMesh.h.


The documentation for this class was generated from the following files: