SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
SLRevolver.cpp
Go to the documentation of this file.
1 /**
2  * \file SLRevolver.cpp
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 #include <SLRevolver.h>
11 
12 //-----------------------------------------------------------------------------
13 /*!
14 SLRevolver::SLRevolver ctor for generic revolution object.
15 */
17  SLVVec3f revolvePoints,
18  SLVec3f revolveAxis,
19  SLuint slices,
20  SLbool smoothFirst,
21  SLbool smoothLast,
22  SLstring name,
23  SLMaterial* mat) : SLMesh(assetMgr, name)
24 {
25  assert(revolvePoints.size() >= 2 && "Error: Not enough revolve points.");
26  assert(revolveAxis != SLVec3f::ZERO && "Error axis is a zero vector.");
27  assert(slices >= 3 && "Error: Not enough slices.");
28 
29  _revPoints = revolvePoints;
30  _revAxis = revolveAxis;
31  _slices = slices;
32  _smoothFirst = smoothFirst;
33  _smoothLast = smoothLast;
34 
36 
37  buildMesh(mat);
38 }
39 //-----------------------------------------------------------------------------
40 /*!
41 SLRevolver::buildMesh builds the underlying mesh data structure
42 */
44 {
45  deleteData();
46 
47  ///////////////////////////////
48  // Vertices & Texture coords //
49  ///////////////////////////////
50 
51  // calculate no. of vertices & allocate vectors for P, UV1 & N.
52  // On one stack it has one vertex more at the end that is identical with the
53  // first vertex of the stack. This is for cylindrical texture mapping where
54  // we need 2 different texture s-coords (0 & 1) at the same point.
55  P.clear();
56  P.resize((_slices + 1) * _revPoints.size());
57  N.clear();
58  N.resize(P.size());
59  UV[0].clear();
60  UV[0].resize(P.size());
61  UV[1].clear();
62 
63  // calculate length of segments for texture coords
64  SLfloat totalLenght = 0;
65  SLVfloat segments;
66  segments.push_back(0);
67  for (SLuint r = 0; r < _revPoints.size() - 1; ++r)
68  {
69  SLVec3f s = _revPoints[r + 1] - _revPoints[r];
70  SLfloat len = s.length();
71  totalLenght += len;
72  segments.push_back(len);
73  }
74 
75  // Normalize segment lengths for texture coords
76  for (auto& segment : segments)
77  segment /= totalLenght;
78 
79  // Texture coordinate
80  SLVec2f uv1(0, 0); // y is increased by segment[r]
81  SLfloat deltaS = 1.0f / _slices; // increase value for s-tecCoord
82 
83  // define matrix & angles for rotation
84  SLMat4f m;
85  SLfloat dPhi = 360.0f / _slices;
86 
87  // calculate vertices & texture coords for all revolution points
88  SLuint iV = 0;
89  for (SLuint r = 0; r < _revPoints.size(); ++r)
90  {
91  m.identity();
92  uv1.x = 0;
93  uv1.y += segments[r];
94  for (SLuint s = 0; s <= _slices; ++s)
95  {
96  if (s == 0 || s == _slices)
97  P[iV] = _revPoints[r];
98  else
99  P[iV] = m.multVec(_revPoints[r]);
100 
101  UV[0][iV++] = uv1;
102  m.rotate(dPhi, _revAxis);
103  uv1.x += deltaS;
104  }
105  }
106 
107  /////////////////
108  // Faces //
109  /////////////////
110 
111  vector<SLVec3ui> faces;
112 
113  // set faces (triangles) for all revolution segments
114  SLVec3ui f;
115  SLuint iV1, iV2;
116  for (SLuint r = 0; r < _revPoints.size() - 1; ++r)
117  {
118  iV1 = r * (_slices + 1);
119  iV2 = (r + 1) * (_slices + 1);
120 
121  // only define faces if neighboring points are different
122  if (_revPoints[r] != _revPoints[r + 1])
123  {
124  for (SLuint s = 0; s < _slices; ++s)
125  {
126  // Add two triangles if real quad is visible
127  // Add upper triangle only iB (or iC) are not on rev. axis
128  if (_revAxis.distSquared(P[iV2 + s]) > FLT_EPSILON)
129  {
130  f.x = iV1 + s;
131  f.y = iV2 + s + 1;
132  f.z = iV2 + s;
133  faces.push_back(f);
134  }
135 
136  // Add lower triangle only iA (or iB) are not on rev. axis
137  if (_revAxis.distSquared(P[iV1 + s]) > FLT_EPSILON)
138  {
139  f.x = iV1 + s;
140  f.y = iV1 + s + 1;
141  f.z = iV2 + s + 1;
142  faces.push_back(f);
143  }
144  }
145  }
146  }
147 
148  assert(!faces.empty() && "SLRevolver::buildMesh: No faces defined!");
149 
150  // calculate no. of faces (triangles) & allocate arrays
151  SLuint i = 0;
152  if (P.size() < 65536)
153  {
154  I16.clear();
155  I16.resize(faces.size() * 3);
156  for (auto face : faces)
157  {
158  I16[i++] = (SLushort)face.x;
159  I16[i++] = (SLushort)face.y;
160  I16[i++] = (SLushort)face.z;
161  }
162  }
163  else
164  {
165  I32.clear();
166  I32.resize(faces.size() * 3);
167  for (auto face : faces)
168  {
169  I32[i++] = face.x;
170  I32[i++] = face.y;
171  I32[i++] = face.z;
172  }
173  }
174 
175  // Set one default material index
176  mat(material);
177 
178  /////////////////
179  // Normals //
180  /////////////////
181 
182  // Calculate normals with the SLMesh method
183  calcNormals();
184 
185  // correct normals at the first point
186  if (_smoothFirst)
187  {
188  for (SLuint s = 0; s < _slices; ++s)
189  {
190  N[s] = -_revAxis;
191  N[s + 1] = -_revAxis;
192  }
193  }
194 
195  // correct normals at the first point
196  if (_smoothLast)
197  {
198  for (SLuint s = 0; s < _slices; ++s)
199  {
200  N[P.size() - s - 1] = _revAxis;
201  N[P.size() - s - 2] = _revAxis;
202  }
203  }
204 
205  // correct (smooth) the start normal and the end normal of a stack
206  for (SLuint r = 0; r < _revPoints.size(); ++r)
207  {
208  iV1 = r * (_slices + 1);
209  iV2 = iV1 + _slices;
210  N[iV1] += N[iV2];
211  N[iV1].normalize();
212  N[iV2] = N[iV1];
213  }
214 }
215 //-----------------------------------------------------------------------------
float SLfloat
Definition: SL.h:173
unsigned int SLuint
Definition: SL.h:171
bool SLbool
Definition: SL.h:175
unsigned short SLushort
Definition: SL.h:169
vector< SLfloat > SLVfloat
Definition: SL.h:200
string SLstring
Definition: SL.h:158
SLScene * s
Definition: SLScene.h:31
vector< SLVec3f > SLVVec3f
Definition: SLVec3.h:325
Toplevel holder of the assets meshes, materials, textures and shaders.
void rotate(T degAng, T axisx, T axisy, T axisz)
Definition: SLMat4.h:656
SLVec3< T > multVec(SLVec3< T > v) const
Definition: SLMat4.h:576
void identity()
Sets the identity matrix.
Definition: SLMat4.h:1333
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
SLVuint I32
Vector of vertex indices 32 bit.
Definition: SLMesh.h:215
SLVushort I16
Vector of vertex indices 16 bit.
Definition: SLMesh.h:214
virtual void calcNormals()
SLMesh::calcNormals recalculates vertex normals for triangle meshes.
Definition: SLMesh.cpp:1165
SLVVec3f N
Vector for vertex normals (opt.) layout (location = 1)
Definition: SLMesh.h:204
virtual void deleteData()
SLMesh::deleteData deletes all mesh data and vbo's.
Definition: SLMesh.cpp:88
SLVVec2f UV[2]
Array of 2 Vectors for tex. coords. (opt.) layout (location = 2)
Definition: SLMesh.h:205
SLVVec3f P
Vector for vertex positions layout (location = 0)
Definition: SLMesh.h:203
SLMaterial * mat() const
Definition: SLMesh.h:177
SLbool _smoothLast
flag if the normal of the last point is eqaual to revAxis
Definition: SLRevolver.h:67
SLVec3f _revAxis
axis of revolution
Definition: SLRevolver.h:59
SLuint slices()
Definition: SLRevolver.h:55
SLbool _smoothFirst
flag if the normal of the first point is eqaual to -revAxis
Definition: SLRevolver.h:64
SLuint _slices
NO. of slices.
Definition: SLRevolver.h:61
void buildMesh(SLMaterial *mat=nullptr)
Definition: SLRevolver.cpp:43
SLVVec3f _revPoints
Array revolving points.
Definition: SLRevolver.h:58
SLRevolver(SLAssetManager *assetMgr, SLVVec3f revolvePoints, SLVec3f revolveAxis, SLuint slices=36, SLbool smoothFirst=false, SLbool smoothLast=false, SLstring name="revolver mesh", SLMaterial *mat=nullptr)
ctor for generic revolver mesh
Definition: SLRevolver.cpp:16
The SLScene class represents the top level instance holding the scene structure.
Definition: SLScene.h:47
T y
Definition: SLVec2.h:30
T x
Definition: SLVec2.h:30
T y
Definition: SLVec3.h:43
T x
Definition: SLVec3.h:43
SLVec3 & normalize()
Definition: SLVec3.h:124
T z
Definition: SLVec3.h:43
T distSquared(const SLVec3 &q)
Calculate the squared distance from the vector to point q.
Definition: SLVec3.h:172
static SLVec3 ZERO
Definition: SLVec3.h:285