File indexing completed on 2024-04-28 03:44:25
0001 /* 0002 SPDX-FileCopyrightText: 2016 Artem Fedoskin <afedoskin3@gmail.com> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "dsosymbolnode.h" 0007 0008 #include "deepskyobject.h" 0009 #include "Options.h" 0010 #include "nodes/ellipsenode.h" 0011 0012 #include <QSGFlatColorMaterial> 0013 0014 void SymbolNode::updateSymbol(float x, float y, float e, float size) 0015 { 0016 zoom = Options::zoomFactor(); 0017 x = 0; 0018 y = 0; 0019 isize = int(size); 0020 0021 dx1 = -0.5 * size; 0022 dx2 = 0.5 * size; 0023 dy1 = -1.0 * e * size / 2.; 0024 dy2 = e * size / 2.; 0025 x1 = x + dx1; 0026 x2 = x + dx2; 0027 y1 = y + dy1; 0028 y2 = y + dy2; 0029 0030 dxa = -size / 4.; 0031 dxb = size / 4.; 0032 dya = -1.0 * e * size / 4.; 0033 dyb = e * size / 4.; 0034 xa = x + dxa; 0035 xb = x + dxb; 0036 ya = y + dya; 0037 yb = y + dyb; 0038 } 0039 0040 StarSymbol::StarSymbol(const QColor &color) : m_ellipse(new EllipseNode(color)) 0041 { 0042 appendChildNode(m_ellipse); 0043 } 0044 0045 void StarSymbol::updateSymbol(float x, float y, float e, float size) 0046 { 0047 SymbolNode::updateSymbol(x, y, e, size); 0048 if (size < 2.) 0049 size = 2.; 0050 if (Options::useAntialias()) 0051 m_ellipse->updateGeometry(0, 0, size, e * size, false); 0052 else 0053 m_ellipse->updateGeometry(0, 0, int(size / 2), int(size / 2), false); 0054 } 0055 0056 AsterismSymbol::AsterismSymbol(const QColor &color) 0057 { 0058 e1 = new EllipseNode(color); 0059 e2 = new EllipseNode(color); 0060 e3 = new EllipseNode(color); 0061 e4 = new EllipseNode(color); 0062 e5 = new EllipseNode(color); 0063 e6 = new EllipseNode(color); 0064 e7 = new EllipseNode(color); 0065 e8 = new EllipseNode(color); 0066 appendChildNode(e1); 0067 appendChildNode(e2); 0068 appendChildNode(e3); 0069 appendChildNode(e4); 0070 appendChildNode(e5); 0071 appendChildNode(e6); 0072 appendChildNode(e7); 0073 appendChildNode(e8); 0074 } 0075 0076 void AsterismSymbol::updateSymbol(float x, float y, float e, float size) 0077 { 0078 SymbolNode::updateSymbol(x, y, e, size); 0079 psize = 2.; 0080 if (size > 50.) 0081 psize *= 2.; 0082 if (size > 100.) 0083 psize *= 2.; 0084 0085 e1->updateGeometry(xa, y1, psize, psize, true); 0086 e2->updateGeometry(xb, y1, psize, psize, true); 0087 e3->updateGeometry(xa, y2, psize, psize, true); 0088 e4->updateGeometry(xb, y2, psize, psize, true); 0089 e5->updateGeometry(x1, ya, psize, psize, true); 0090 e6->updateGeometry(x1, yb, psize, psize, true); 0091 e7->updateGeometry(x2, ya, psize, psize, true); 0092 e8->updateGeometry(x2, yb, psize, psize, true); 0093 } 0094 0095 GlobularClusterSymbol::GlobularClusterSymbol(const QColor &color) : e1(new EllipseNode(color)) 0096 { 0097 appendChildNode(e1); 0098 0099 lines = new QSGGeometryNode; 0100 appendChildNode(lines); 0101 0102 QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 0); 0103 geometry->setDrawingMode(GL_LINES); 0104 geometry->allocate(4); 0105 0106 lines->setGeometry(geometry); 0107 lines->setFlag(QSGNode::OwnsGeometry); 0108 0109 QSGFlatColorMaterial *material = new QSGFlatColorMaterial; 0110 material->setColor(color); 0111 lines->setOpaqueMaterial(material); 0112 lines->setFlag(QSGNode::OwnsMaterial); 0113 } 0114 0115 void GlobularClusterSymbol::updateSymbol(float x, float y, float e, float size) 0116 { 0117 SymbolNode::updateSymbol(x, y, e, size); 0118 0119 if (size < 2.) 0120 size = 2.; 0121 e1->updateGeometry(0, 0, size, e * size, false); 0122 0123 QSGGeometry::Point2D *vertex = lines->geometry()->vertexDataAsPoint2D(); 0124 //First line 0125 vertex[0].set(dx1, 0); 0126 vertex[1].set(dx2, 0); 0127 0128 //Second line 0129 vertex[2].set(0, dy1); 0130 vertex[3].set(0, dy2); 0131 0132 lines->markDirty(QSGNode::DirtyGeometry); 0133 } 0134 0135 DarkNebulaSymbol::DarkNebulaSymbol(const QColor &color) 0136 { 0137 lines = new QSGGeometryNode; 0138 appendChildNode(lines); 0139 0140 QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 0); 0141 geometry->setDrawingMode(GL_LINES); 0142 geometry->allocate(8); 0143 0144 lines->setGeometry(geometry); 0145 lines->setFlag(QSGNode::OwnsGeometry); 0146 0147 QSGFlatColorMaterial *material = new QSGFlatColorMaterial; 0148 material->setColor(color); 0149 lines->setOpaqueMaterial(material); 0150 lines->setFlag(QSGNode::OwnsMaterial); 0151 } 0152 0153 void DarkNebulaSymbol::updateSymbol(float x, float y, float e, float size) 0154 { 0155 SymbolNode::updateSymbol(x, y, e, size); 0156 0157 QSGGeometry::Point2D *vertex = lines->geometry()->vertexDataAsPoint2D(); 0158 //First line 0159 vertex[0].set(dx1, dy1); 0160 vertex[1].set(dx2, dy1); 0161 0162 //Second line 0163 vertex[2].set(dx2, dy1); 0164 vertex[3].set(dx2, dy2); 0165 0166 //Third line 0167 vertex[4].set(dx2, dy2); 0168 vertex[5].set(dx1, dy2); 0169 0170 //Fourth line 0171 vertex[6].set(dx1, dy2); 0172 vertex[7].set(dx1, dy1); 0173 0174 lines->markDirty(QSGNode::DirtyGeometry); 0175 } 0176 0177 PlanetaryNebulaSymbol::PlanetaryNebulaSymbol(const QColor &color) 0178 { 0179 e1 = new EllipseNode(color); 0180 appendChildNode(e1); 0181 0182 lines = new QSGGeometryNode; 0183 appendChildNode(lines); 0184 0185 QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 0); 0186 geometry->setDrawingMode(GL_LINES); 0187 geometry->allocate(8); 0188 0189 lines->setGeometry(geometry); 0190 lines->setFlag(QSGNode::OwnsGeometry); 0191 0192 QSGFlatColorMaterial *material = new QSGFlatColorMaterial; 0193 material->setColor(color); 0194 lines->setOpaqueMaterial(material); 0195 lines->setFlag(QSGNode::OwnsMaterial); 0196 } 0197 0198 void PlanetaryNebulaSymbol::updateSymbol(float x, float y, float e, float size) 0199 { 0200 SymbolNode::updateSymbol(x, y, e, size); 0201 0202 if (size < 2.) 0203 size = 2.; 0204 0205 e1->updateGeometry(0, 0, size, e * size, false); 0206 0207 QSGGeometry::Point2D *vertex = lines->geometry()->vertexDataAsPoint2D(); 0208 //First line 0209 vertex[0].set(0., dy1); 0210 vertex[1].set(0., dy1 - e * size / 2.); 0211 0212 //Second line 0213 vertex[2].set(0., dy2); 0214 vertex[3].set(0., dy2 + e * size / 2.); 0215 0216 //Third line 0217 vertex[4].set(dx1, 0.); 0218 vertex[5].set(dx1 - size / 2., 0.); 0219 0220 //Fourth line 0221 vertex[6].set(dx2, 0.); 0222 vertex[7].set(dx2 + size / 2., 0.); 0223 0224 lines->markDirty(QSGNode::DirtyGeometry); 0225 } 0226 0227 SupernovaRemnantSymbol::SupernovaRemnantSymbol(const QColor &color) 0228 { 0229 lines = new QSGGeometryNode; 0230 appendChildNode(lines); 0231 0232 QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 0); 0233 geometry->setDrawingMode(GL_LINES); 0234 geometry->allocate(8); 0235 0236 lines->setGeometry(geometry); 0237 lines->setFlag(QSGNode::OwnsGeometry); 0238 0239 QSGFlatColorMaterial *material = new QSGFlatColorMaterial; 0240 material->setColor(color); 0241 lines->setOpaqueMaterial(material); 0242 lines->setFlag(QSGNode::OwnsMaterial); 0243 } 0244 0245 void SupernovaRemnantSymbol::updateSymbol(float x, float y, float e, float size) 0246 { 0247 SymbolNode::updateSymbol(x, y, e, size); 0248 0249 QSGGeometry::Point2D *vertex = lines->geometry()->vertexDataAsPoint2D(); 0250 0251 //First line 0252 vertex[0].set(0., dy1); 0253 vertex[1].set(dx2, 0.); 0254 0255 //Second line 0256 vertex[2].set(dx2, 0.); 0257 vertex[3].set(0., dy2); 0258 0259 //Third line 0260 vertex[4].set(0., dy2); 0261 vertex[5].set(dx1, 0.); 0262 0263 //Fourth line 0264 vertex[6].set(dx1, 0.); 0265 vertex[7].set(0., dy1); 0266 0267 lines->markDirty(QSGNode::DirtyGeometry); 0268 } 0269 0270 GalaxySymbol::GalaxySymbol(const QColor &color) : e1(new EllipseNode(color)) 0271 { 0272 appendChildNode(e1); 0273 } 0274 0275 void GalaxySymbol::updateSymbol(float x, float y, float e, float size) 0276 { 0277 SymbolNode::updateSymbol(x, y, e, size); 0278 0279 if (size < 1. && zoom > 20 * MINZOOM) 0280 size = 3.; //force ellipse above zoomFactor 20 0281 if (size < 1. && zoom > 5 * MINZOOM) 0282 size = 1.; //force points above zoomFactor 5 0283 if (size > 2.) 0284 { 0285 e1->updateGeometry(0, 0, size, e * size, false); 0286 } 0287 else if (size > 0.) 0288 { 0289 e1->updateGeometry(0, 0, 1, 1, false); 0290 } 0291 } 0292 0293 GalaxyClusterSymbol::GalaxyClusterSymbol(const QColor &color) : lines(new QSGGeometryNode) 0294 { 0295 QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 0); 0296 geometry->setDrawingMode(GL_LINES); 0297 geometry->allocate(32); 0298 0299 lines->setGeometry(geometry); 0300 lines->setFlag(QSGNode::OwnsGeometry); 0301 0302 QSGFlatColorMaterial *material = new QSGFlatColorMaterial; 0303 material->setColor(color); 0304 lines->setOpaqueMaterial(material); 0305 lines->setFlag(QSGNode::OwnsMaterial); 0306 0307 appendChildNode(lines); 0308 } 0309 0310 void GalaxyClusterSymbol::updateSymbol(float x, float y, float e, float size) 0311 { 0312 SymbolNode::updateSymbol(x, y, e, size); 0313 0314 psize = 1.; 0315 if (size > 50.) 0316 psize *= 2.; 0317 0318 QSGGeometry::Point2D *vertex = lines->geometry()->vertexDataAsPoint2D(); 0319 0320 vertex[0].set(xa - psize, y1); 0321 vertex[1].set(xa + psize, y1); 0322 vertex[2].set(xa, y1 - psize); 0323 vertex[3].set(xa, y1 + psize); 0324 vertex[4].set(xb - psize, y1); 0325 vertex[5].set(xb + psize, y1); 0326 vertex[6].set(xb, y1 - psize); 0327 vertex[7].set(xb, y1 + psize); 0328 vertex[8].set(xa - psize, y2); 0329 vertex[9].set(xa + psize, y2); 0330 vertex[10].set(xa, y2 - psize); 0331 vertex[11].set(xa, y2 + psize); 0332 vertex[12].set(xb - psize, y2); 0333 vertex[13].set(xb + psize, y2); 0334 vertex[14].set(xb, y2 - psize); 0335 vertex[15].set(xb, y2 + psize); 0336 vertex[16].set(x1 - psize, ya); 0337 vertex[17].set(x1 + psize, ya); 0338 vertex[18].set(x1, ya - psize); 0339 vertex[19].set(x1, ya + psize); 0340 vertex[20].set(x1 - psize, yb); 0341 vertex[21].set(x1 + psize, yb); 0342 vertex[22].set(x1, yb - psize); 0343 vertex[23].set(x1, yb + psize); 0344 vertex[24].set(x2 - psize, ya); 0345 vertex[25].set(x2 + psize, ya); 0346 vertex[26].set(x2, ya - psize); 0347 vertex[27].set(x2, ya + psize); 0348 vertex[28].set(x2 - psize, yb); 0349 vertex[29].set(x2 + psize, yb); 0350 vertex[30].set(x2, yb - psize); 0351 vertex[31].set(x2, yb + psize); 0352 0353 lines->markDirty(QSGNode::DirtyGeometry); 0354 } 0355 0356 DSOSymbolNode::DSOSymbolNode(DeepSkyObject *skyObject, const QColor &color) 0357 : m_color(color), m_dso(skyObject) 0358 { 0359 } 0360 0361 void DSOSymbolNode::initSymbol() 0362 { 0363 if (!m_symbol) 0364 { 0365 int type = m_dso->type(); 0366 switch (type) 0367 { 0368 case 0: 0369 case 1: 0370 //catalog star 0371 m_symbol = new StarSymbol(m_color); 0372 break; 0373 case 3: //Open cluster; draw circle of points 0374 case 13: // Asterism 0375 m_symbol = new AsterismSymbol(m_color); 0376 break; 0377 case 4: //Globular Cluster 0378 m_symbol = new GlobularClusterSymbol(m_color); 0379 m_rotate = true; 0380 break; 0381 case 5: //Gaseous Nebula 0382 case 15: // Dark Nebula 0383 m_symbol = new DarkNebulaSymbol(m_color); 0384 m_rotate = true; 0385 break; 0386 case 6: //Planetary Nebula 0387 m_symbol = new PlanetaryNebulaSymbol(m_color); 0388 m_rotate = true; 0389 break; 0390 case 7: //Supernova remnant 0391 m_symbol = new SupernovaRemnantSymbol(m_color); 0392 m_rotate = true; 0393 break; 0394 case 8: //Galaxy 0395 case 16: // Quasar 0396 m_symbol = new GalaxySymbol(m_color); 0397 m_rotate = true; 0398 break; 0399 case 14: // Galaxy cluster - draw a circle of + marks 0400 m_symbol = new GalaxyClusterSymbol(m_color); 0401 m_rotate = true; 0402 break; 0403 default: 0404 break; 0405 } 0406 if (m_symbol) 0407 addChildNode(m_symbol); 0408 } 0409 } 0410 0411 void DSOSymbolNode::changePos(const QPointF &pos, float positionangle) 0412 { 0413 QMatrix4x4 m(1, 0, 0, pos.x(), 0, 1, 0, pos.y(), 0, 0, 1, 0, 0, 0, 0, 1); 0414 //FIXME: this is probably incorrect (inherited from drawDeepSkyImage()) 0415 if (m_rotate) 0416 { 0417 m.rotate(positionangle, 0, 0, 1); 0418 } 0419 0420 setMatrix(m); 0421 markDirty(QSGNode::DirtyMatrix); 0422 } 0423 0424 void DSOSymbolNode::update(float size, const QPointF &pos, float positionangle) 0425 { 0426 initSymbol(); 0427 0428 if (m_symbol) 0429 { 0430 m_symbol->updateSymbol(pos.x(), pos.y(), m_dso->e(), size); 0431 show(); 0432 changePos(pos, positionangle); 0433 } 0434 else 0435 { 0436 qDebug() << "Symbol for object " << m_dso->name() << " wasn't created. Check DSOSymbolNode::initSymbol()"; 0437 } 0438 }