20 #ifndef _STELCIRCLEARCRENDERER_HPP_
21 #define _STELCIRCLEARCRENDERER_HPP_
23 #include <QLinkedList>
25 #include "GenericVertexTypes.hpp"
26 #include "StelProjector.hpp"
28 #include "StelRenderer.hpp"
60 , projector(&(*projector))
71 , projector(projector)
79 delete smallCircleVertexBuffer;
101 void (*viewportEdgeIntersectCallback)
102 (
const Vec3d& screenPos,
const Vec3d& direction,
void* userData) = NULL,
103 void* userData = NULL)
106 rotCenter =
Vec3d(0);
107 if (NULL != clippingCap)
111 if (clippingCap->clipGreatCircle(pt1, pt2))
144 Q_ASSERT_X(points.size() != 1, Q_FUNC_INFO,
145 "Need zero or at least 2 points to draw circle arcs");
146 switch(primitiveType)
148 case PrimitiveType_Lines:
149 Q_ASSERT_X(points.size() % 2 == 0, Q_FUNC_INFO,
150 "Need an even number of points to draw great circle arcs from a "
151 "lines primitive type.");
152 for (
int p = 0; p < points.size(); p += 2 )
157 case PrimitiveType_LineLoop:
158 if(points.size() > 0)
162 case PrimitiveType_LineStrip:
163 for (
int p = 1; p < points.size(); p++)
169 Q_ASSERT_X(
false, Q_FUNC_INFO,
"Unsupported primitive type to draw circle arcs from");
200 void (*viewportEdgeIntersectCallback)
201 (
const Vec3d& screenPos,
const Vec3d& direction,
void* userData),
204 Q_ASSERT_X(smallCircleVertexBuffer->
length() == 0, Q_FUNC_INFO,
205 "Small circle buffer must be empty before drawing");
207 smallCircleVertexBuffer->
unlock();
211 win1[2] = projector->
project(start, win1) ? 1.0 : -1.1;
212 win2[2] = projector->
project(stop, win2) ? 1.0 : -1.0;
213 vertexList.append(win1);
215 if (rotCenter.lengthSquared() < 0.00000001)
219 fIter(start, stop, win1, win2,
220 vertexList.insert(vertexList.end(), win2), 1.0);
224 const Vec3d tmp = (rotCenter ^ start) / rotCenter.length();
225 const double radius = fabs(tmp.length());
227 fIter(start - rotCenter, stop - rotCenter, win1, win2,
228 vertexList.insert(vertexList.end(), win2), radius);
232 QLinkedList<Vec3d>::ConstIterator i = vertexList.constBegin();
233 while (i + 1 != vertexList.constEnd())
235 const Vec3d& p1 = *i;
236 const Vec3d& p2 = *(++i);
240 if ((p1[2] > 0.0 && p1InViewport) || (p2[2] > 0.0 && p2InViewport))
243 if (i + 1 == vertexList.constEnd())
246 drawSmallCircleVertexBuffer();
249 if (NULL != viewportEdgeIntersectCallback && p1InViewport != p2InViewport)
252 const Vec3d& a = p1InViewport ? p1 : p2;
253 const Vec3d& b = p1InViewport ? p2 : p1;
263 if (smallCircleVertexBuffer->
length() > 0)
267 drawSmallCircleVertexBuffer();
271 Q_ASSERT_X(smallCircleVertexBuffer->
length() == 0, Q_FUNC_INFO,
272 "Small circle buffer must be empty after drawing");
286 QLinkedList<Vec3d> vertexList;
293 const QLinkedList<Vec3d>::iterator& iter,
double radius,
294 int nbI = 0,
bool checkCrossDiscontinuity =
true)
296 const bool crossDiscontinuity =
297 checkCrossDiscontinuity &&
300 if (crossDiscontinuity && nbI >= 5)
304 vertexList.insert(iter, win1);
305 vertexList.insert(iter, win2);
310 Vec3d newVertex(p1 + p2);
311 newVertex.normalize();
313 Vec3d win3(newVertex + rotCenter);
316 const float v10 = win1[0] - win3[0];
317 const float v11 = win1[1] - win3[1];
318 const float v20 = win2[0] - win3[0];
319 const float v21 = win2[1] - win3[1];
321 const float dist = std::sqrt((v10 * v10 + v11 * v11) * (v20 * v20 + v21 * v21));
322 const float cosAngle = (v10 * v20 + v11 * v21) / dist;
323 if ((cosAngle > -0.999f || dist > 50 * 50 || crossDiscontinuity) && nbI < 5)
326 win3[2]= isValidVertex ? 1.0 : -1.0;
327 fIter(p1, newVertex, win1, win3, vertexList.insert(iter, win3),
328 radius, nbI + 1, crossDiscontinuity || dist > 50 * 50);
329 fIter(newVertex, p2, win3, win2, iter,
330 radius, nbI + 1, crossDiscontinuity || dist > 50 * 50);
335 void drawSmallCircleVertexBuffer()
337 smallCircleVertexBuffer->
lock();
339 smallCircleVertexBuffer->
unlock();
340 smallCircleVertexBuffer->
clear();
344 #endif // _STELCIRCLEARCRENDERER_HPP_