File indexing completed on 2024-05-12 03:45:46
0001 /* 0002 SPDX-FileCopyrightText: 2016 Artem Fedoskin <afedoskin3@gmail.com> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "linenode.h" 0007 0008 #include "skymaplite.h" 0009 #include "projections/projector.h" 0010 #include "skycomponents/skiphashlist.h" 0011 0012 #include <QLinkedList> 0013 #include <QSGFlatColorMaterial> 0014 0015 LineNode::LineNode(LineList *lineList, SkipHashList *skipList, QColor color, int width, Qt::PenStyle drawStyle) 0016 : m_geometryNode(new QSGGeometryNode), m_lineList(lineList), m_skipList(skipList), 0017 m_material(new QSGFlatColorMaterial), m_drawStyle(drawStyle) 0018 { 0019 m_geometryNode->setOpaqueMaterial(m_material); 0020 //m_geometryNode->setFlag(QSGNode::OwnsMaterial); 0021 m_material->setColor(color); 0022 0023 m_geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 0); 0024 m_geometryNode->setGeometry(m_geometry); 0025 //m_geometryNode->setFlag(QSGNode::OwnsGeometry); 0026 setWidth(width); 0027 0028 appendChildNode(m_geometryNode); 0029 } 0030 0031 LineNode::~LineNode() 0032 { 0033 delete m_geometry; 0034 delete m_material; 0035 } 0036 0037 void LineNode::setColor(QColor color) 0038 { 0039 if (m_material->color() != color) 0040 { 0041 m_material->setColor(color); 0042 m_color = color; 0043 m_geometryNode->markDirty(QSGNode::DirtyMaterial); 0044 } 0045 } 0046 0047 void LineNode::setWidth(int width) 0048 { 0049 m_geometry->setLineWidth(width); 0050 m_geometryNode->markDirty(QSGNode::DirtyGeometry); 0051 } 0052 0053 void LineNode::setDrawStyle(Qt::PenStyle style) 0054 { 0055 m_drawStyle = style; 0056 } 0057 0058 void LineNode::setStyle(QColor color, int width, Qt::PenStyle drawStyle) 0059 { 0060 setColor(color); 0061 setWidth(width); 0062 setDrawStyle(drawStyle); 0063 } 0064 0065 void LineNode::updateGeometry() 0066 { 0067 SkyList *points = m_lineList->points(); 0068 0069 m_geometry->setDrawingMode(GL_LINES); 0070 0071 const Projector *m_proj = SkyMapLite::Instance()->projector(); 0072 0073 bool isVisible, isVisibleLast; 0074 0075 QPointF oLast = m_proj->toScreen(points->first().get(), true, &isVisibleLast); 0076 0077 // & with the result of checkVisibility to clip away things below horizon 0078 isVisibleLast &= m_proj->checkVisibility(points->first().get()); 0079 QPointF oThis; 0080 0081 QLinkedList<QPointF> newPoints; 0082 0083 for (int j = 1; j < points->size(); j++) 0084 { 0085 SkyPoint *pThis = points->at(j).get(); 0086 0087 /*In regular KStars we first call checkVisibility and then toScreen 0088 Here we minimize the number of calls to toScreen by proceeding only if 0089 checkVisibility is true*/ 0090 oThis = m_proj->toScreen(pThis, true, &isVisible); 0091 // & with the result of checkVisibility to clip away things below horizon 0092 isVisible &= m_proj->checkVisibility(pThis); 0093 bool doSkip = false; 0094 if (m_skipList) 0095 { 0096 doSkip = m_skipList->skip(j); 0097 } 0098 0099 bool pointsVisible = false; 0100 //Temporary solution to avoid random lines in Gnomonic projection and draw lines up to horizon 0101 if (SkyMapLite::Instance()->projector()->type() == Projector::Gnomonic) 0102 { 0103 if (isVisible && isVisibleLast) 0104 pointsVisible = true; 0105 } 0106 else 0107 { 0108 if (isVisible || isVisibleLast) 0109 pointsVisible = true; 0110 } 0111 0112 if (!doSkip) 0113 { 0114 if (pointsVisible) 0115 { 0116 newPoints.append(oLast); 0117 newPoints.append(oThis); 0118 } 0119 } 0120 oLast = oThis; 0121 isVisibleLast = isVisible; 0122 } 0123 0124 int size = newPoints.size(); 0125 m_geometry->allocate(size); 0126 0127 QSGGeometry::Point2D *vertex = m_geometry->vertexDataAsPoint2D(); 0128 0129 QLinkedList<QPointF>::const_iterator i = newPoints.constBegin(); 0130 int c = 0; 0131 0132 while (i != newPoints.constEnd()) 0133 { 0134 vertex[c].x = (*i).x(); 0135 vertex[c].y = (*i).y(); 0136 ++c; 0137 ++i; 0138 } 0139 m_geometryNode->markDirty(QSGNode::DirtyGeometry); 0140 }