20 #ifndef _STELGEOMETRYBUILDER_HPP_
21 #define _STELGEOMETRYBUILDER_HPP_
24 #include "GenericVertexTypes.hpp"
25 #include "StelIndexBuffer.hpp"
26 #include "StelLight.hpp"
27 #include "StelProjector.hpp"
28 #include "StelVertexBuffer.hpp"
29 #include "VecMath.hpp"
155 if(NULL != unlitVertices)
157 Q_ASSERT_X(NULL == litVertices, Q_FUNC_INFO,
158 "Both lit and unlit vertex buffers are used");
159 delete unlitVertices;
160 unlitVertices = NULL;
162 if(NULL != litVertices)
164 Q_ASSERT_X(NULL == unlitVertices, Q_FUNC_INFO,
165 "Both lit and unlit vertex buffers are used");
169 for(
int row = 0; row < rowIndices.size(); ++row)
171 delete rowIndices[row];
187 Q_ASSERT_X(radius > 0.0f, Q_FUNC_INFO,
"Sphere radius must be greater than zero");
188 this->radius = radius;
199 Q_ASSERT_X(oneMinusOblateness >= 0.0f && oneMinusOblateness <= 1.0f, Q_FUNC_INFO,
200 "Sphere oneMinusOblateness parameter must be at least zero and at most one");
201 this->oneMinusOblateness = oneMinusOblateness;
216 Q_ASSERT_X(stacks >= 3 && stacks < 4096, Q_FUNC_INFO,
217 "There must be at least 3 stacks in a sphere, and at most 4096.");
218 Q_ASSERT_X(slices >= 3 && slices < 4096, Q_FUNC_INFO,
219 "There must be at least 3 slices in a sphere, and at most 4096.");
220 this->stacks = stacks;
221 this->slices = slices;
228 this->orientInside = orientInside;
235 this->flipTexture = flipTexture;
242 Q_ASSERT_X(type == SphereType_Lit, Q_FUNC_INFO,
243 "Trying to set light for an unlit sphere");
244 if(this->light == light){
return;}
251 const SphereType type;
261 float oneMinusOblateness;
272 const float fisheyeTextureFov;
284 QVector<StelIndexBuffer*> rowIndices;
300 , oneMinusOblateness(0.0f)
303 , orientInside(false)
305 , fisheyeTextureFov(textureFov)
307 , unlitVertices(NULL)
310 if(type == SphereType_Fisheye)
312 Q_ASSERT_X(textureFov > 0.0f, Q_FUNC_INFO,
313 "Fisheye sphere texture FOV must be greater than zero");
425 if(NULL != texturedVertices)
427 Q_ASSERT_X(NULL == plain2DVertices, Q_FUNC_INFO,
428 "Both textured and 2D vertex buffers are used");
429 delete texturedVertices;
430 texturedVertices = NULL;
432 if(NULL != plain2DVertices)
434 Q_ASSERT_X(NULL == texturedVertices, Q_FUNC_INFO,
435 "Both textured and 2D vertex buffers are used");
436 delete plain2DVertices;
437 plain2DVertices = NULL;
439 for(
int loop = 0; loop < loopIndices.size(); ++loop)
441 delete loopIndices[loop];
459 Q_ASSERT_X(inner > 0.0f, Q_FUNC_INFO,
"Inner ring radius must be greater than zero");
462 if(inner == this->innerRadius && outer == this->outerRadius) {
return;}
464 this->innerRadius = inner;
465 this->outerRadius = outer;
479 Q_ASSERT_X(loops >= 1, Q_FUNC_INFO,
"There must be at least 1 loop in a ring");
481 Q_ASSERT_X(slices >= 3 && slices <= 4096, Q_FUNC_INFO,
482 "There must be at least 3 and at most 4096 slices in a ring.");
485 if(slices == this->slices && loops == this->loops) {
return;}
488 this->slices = slices;
496 if(flipFaces == this->flipFaces) {
return;}
497 this->flipFaces = flipFaces;
505 if(offset == this->offset) {
return;}
506 this->offset = offset;
539 QVector<StelIndexBuffer*> loopIndices;
556 , offset(0.0f, 0.0f, 0.0f)
557 , texturedVertices(NULL)
558 , plain2DVertices(NULL)
585 const float x,
const float y,
const float radius,
586 const int segments = 128)
588 Q_ASSERT_X(radius > 0.0f, Q_FUNC_INFO,
"Circle must have a radius greater than zero");
589 Q_ASSERT_X(segments > 3, Q_FUNC_INFO,
"Circle must have at least 3 segments");
590 Q_ASSERT_X(vertexBuffer->
length() == 0, Q_FUNC_INFO,
591 "Need an empty vertex buffer to build a circle");
592 Q_ASSERT_X(vertexBuffer->
primitiveType() == PrimitiveType_LineStrip, Q_FUNC_INFO,
593 "Need a line loop vertex buffer to build a circle");
595 const Vec2f center(x,y);
596 const float phi = 2.0f * M_PI / segments;
597 const float cp = std::cos(phi);
598 const float sp = std::sin(phi);
604 for (
int i = 0; i < segments; i++)
607 const float dxNew = dx * cp - dy * sp;
608 dy = dx * sp + dy * cp;
612 vertexBuffer->
lock();
625 const float radius,
const float height,
const int slices,
626 const bool orientInside =
false)
631 Q_ASSERT_X(vertexBuffer->
length() == 0, Q_FUNC_INFO,
632 "Need an empty vertex buffer to start building a cylinder");
633 Q_ASSERT_X(vertexBuffer->
primitiveType() == PrimitiveType_TriangleStrip,
634 Q_FUNC_INFO,
"Need a triangle strip vertex buffer to build a cylinder");
635 Q_ASSERT_X(slices >= 3, Q_FUNC_INFO,
636 "can't build a cylinder with less than 3 slices");
639 float texCoord = orientInside ? 1.0f : 0.0f;
643 const float sign = orientInside ? -1.0f : 1.0f;
644 const float deltaTexCoord = 1.0f / slices;
645 const float deltaAngle = 2.0f * M_PI / slices;
647 for (
int i = 0; i <= slices; ++i)
649 const float x = std::sin(angle) * radius;
650 const float y = std::cos(angle) * radius;
657 texCoord += sign * deltaTexCoord;
658 angle += sign * deltaAngle;
660 vertexBuffer->
lock();
679 const int innerFanSlices,
const int level);
802 #endif // _STELGEOMETRYBUILDER_HPP_