File indexing completed on 2024-04-14 03:42:50
0001 /* 0002 SPDX-FileCopyrightText: 2016 Artem Fedoskin <afedoskin3@gmail.com> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "staritem.h" 0007 0008 #include "deepstaritem.h" 0009 #include "labelsitem.h" 0010 #include "Options.h" 0011 #include "rootnode.h" 0012 #include "skymesh.h" 0013 #include "skyopacitynode.h" 0014 #include "starblockfactory.h" 0015 #include "starcomponent.h" 0016 #include "htmesh/MeshIterator.h" 0017 #include "projections/projector.h" 0018 #include "skynodes/pointsourcenode.h" 0019 #include "skynodes/trixelnode.h" 0020 0021 #include <QLinkedList> 0022 0023 StarItem::StarItem(StarComponent *starComp, RootNode *rootNode) 0024 : SkyItem(LabelsItem::label_t::STAR_LABEL, rootNode), m_starComp(starComp), m_stars(new SkyOpacityNode), 0025 m_deepStars(new SkyOpacityNode), m_starLabels(rootNode->labelsItem()->getLabelNode(labelType())) 0026 0027 { 0028 StarIndex *trixels = m_starComp->m_starIndex.get(); 0029 0030 appendChildNode(m_stars); 0031 0032 //Test 0033 Options::setShowStarMagnitudes(false); 0034 Options::setShowStarNames(true); 0035 0036 for (int i = 0; i < trixels->size(); ++i) 0037 { 0038 StarList *skyList = trixels->at(i); 0039 TrixelNode *trixel = new TrixelNode(i); 0040 m_stars->appendChildNode(trixel); 0041 0042 for (int c = 0; c < skyList->size(); ++c) 0043 { 0044 StarObject *star = skyList->at(c); 0045 if (star) 0046 { 0047 trixel->m_nodes.append(QPair<SkyObject *, SkyNode *>(star, 0)); 0048 } 0049 } 0050 } 0051 0052 appendChildNode(m_deepStars); 0053 0054 QVector<DeepStarComponent *> deepStars = m_starComp->m_DeepStarComponents; 0055 int deepSize = deepStars.size(); 0056 0057 for (int i = 0; i < deepSize; ++i) 0058 { 0059 DeepStarItem *deepStar = new DeepStarItem(deepStars[i], rootNode); 0060 rootNode->removeChildNode(deepStar); 0061 m_deepStars->appendChildNode(deepStar); 0062 } 0063 0064 m_skyMesh = SkyMesh::Instance(); 0065 m_StarBlockFactory = StarBlockFactory::Instance(); 0066 } 0067 0068 void StarItem::update() 0069 { 0070 if (!m_starComp->selected()) 0071 { 0072 hide(); 0073 return; 0074 } 0075 show(); 0076 0077 SkyMapLite *map = SkyMapLite::Instance(); 0078 KStarsData *data = KStarsData::Instance(); 0079 0080 bool checkSlewing = (map->isSlewing() && Options::hideOnSlew()); 0081 bool hideLabel = checkSlewing || !(Options::showStarMagnitudes() || Options::showStarNames()); 0082 if (hideLabel) 0083 hideLabels(); 0084 0085 //shortcuts to inform whether to draw different objects 0086 bool hideFaintStars = checkSlewing && Options::hideStars(); 0087 double hideStarsMag = Options::magLimitHideStar(); 0088 bool reIndex = m_starComp->reindex(data->updateNum()); 0089 0090 double lgmin = log10(MINZOOM); 0091 double lgmax = log10(MAXZOOM); 0092 double lgz = log10(Options::zoomFactor()); 0093 0094 double maglim; 0095 double m_zoomMagLimit; //Check it later. Needed for labels 0096 m_zoomMagLimit = maglim = StarComponent::zoomMagnitudeLimit(); 0097 map->setSizeMagLim(m_zoomMagLimit); 0098 0099 double labelMagLim = Options::starLabelDensity() / 5.0; 0100 labelMagLim += (12.0 - labelMagLim) * (lgz - lgmin) / (lgmax - lgmin); 0101 if (labelMagLim > 8.0) 0102 labelMagLim = 8.0; 0103 0104 //Calculate sizeMagLim 0105 // Old formula: 0106 // float sizeMagLim = ( 2.000 + 2.444 * Options::memUsage() / 10.0 ) * ( lgz - lgmin ) + 5.8; 0107 0108 // Using the maglim to compute the sizes of stars reduces 0109 // discernability between brighter and fainter stars at high zoom 0110 // levels. To fix that, we use an "arbitrary" constant in place of 0111 // the variable star density. 0112 // Not using this formula now. 0113 // float sizeMagLim = 4.444 * ( lgz - lgmin ) + 5.0; 0114 0115 /*float sizeMagLim = zoomMagnitudeLimit(); 0116 if( sizeMagLim > faintMagnitude() * ( 1 - 1.5/16 ) ) 0117 sizeMagLim = faintMagnitude() * ( 1 - 1.5/16 ); 0118 skyp->setSizeMagLimit(sizeMagLim);*/ 0119 0120 //Loop for drawing star images 0121 0122 float radius = map->projector()->fov(); 0123 if (radius > 90.0) 0124 radius = 90.0; 0125 0126 m_skyMesh->inDraw(true); 0127 0128 SkyPoint *focus = map->focus(); 0129 m_skyMesh->aperture(focus, radius + 1.0, DRAW_BUF); // divide by 2 for testing 0130 0131 MeshIterator region(m_skyMesh, DRAW_BUF); 0132 0133 // If we are hiding faint stars, then maglim is really the brighter of hideStarsMag and maglim 0134 if (hideFaintStars && maglim > hideStarsMag) 0135 maglim = hideStarsMag; 0136 0137 m_StarBlockFactory->drawID = m_skyMesh->drawID(); 0138 0139 int regionID = -1; 0140 if (region.hasNext()) 0141 { 0142 regionID = region.next(); 0143 } 0144 0145 int trixelID = 0; 0146 0147 QSGNode *firstTrixel = m_stars->firstChild(); 0148 TrixelNode *trixel = static_cast<TrixelNode *>(firstTrixel); 0149 0150 QSGNode *firstLabel = m_starLabels->firstChild(); 0151 TrixelNode *label = static_cast<TrixelNode *>(firstLabel); 0152 0153 StarIndex *index = m_starComp->m_starIndex.get(); 0154 0155 if (reIndex) 0156 rootNode()->labelsItem()->deleteLabels(labelType()); 0157 0158 const Projector *projector = SkyMapLite::Instance()->projector(); 0159 0160 double delLim = SkyMapLite::deleteLimit(); 0161 0162 while (trixel != 0) 0163 { 0164 if (reIndex) 0165 { 0166 StarList *skyList = index->at(trixelID); 0167 0168 QSGNode *n = trixel->firstChild(); 0169 0170 //Delete nodes 0171 while (n != 0) 0172 { 0173 QSGNode *c = n; 0174 n = n->nextSibling(); 0175 0176 trixel->removeChildNode(c); 0177 delete c; 0178 } 0179 0180 //Delete all pairs that represent stars 0181 trixel->m_nodes.clear(); 0182 0183 for (int c = 0; c < skyList->size(); ++c) 0184 { 0185 StarObject *star = skyList->at(c); 0186 if (star) 0187 { 0188 //Add new pair with reindexed star 0189 trixel->m_nodes.append(QPair<SkyObject *, SkyNode *>(star, 0)); 0190 } 0191 } 0192 } 0193 0194 if (trixelID != regionID) 0195 { 0196 trixel->hide(); 0197 label->hide(); 0198 0199 if (trixel->hideCount() > delLim) 0200 { 0201 trixel->deleteAllChildNodes(); 0202 } 0203 } 0204 else 0205 { 0206 trixel->show(); 0207 label->show(); 0208 0209 if (region.hasNext()) 0210 { 0211 regionID = region.next(); 0212 } 0213 0214 QLinkedList<QPair<SkyObject *, SkyNode *>> *nodes = &trixel->m_nodes; 0215 QLinkedList<QPair<SkyObject *, SkyNode *>>::iterator i = nodes->begin(); 0216 bool hide = false; 0217 0218 while (i != nodes->end()) 0219 { 0220 bool drawLabel = false; 0221 0222 StarObject *starObj = static_cast<StarObject *>((*i).first); 0223 SkyNode *node = (*i).second; 0224 0225 int mag = starObj->mag(); 0226 0227 // break loop if maglim is reached 0228 if (mag > maglim) 0229 hide = true; 0230 if (!(hideLabel || mag > labelMagLim)) 0231 drawLabel = true; 0232 if (starObj->updateID != KStarsData::Instance()->updateID()) 0233 starObj->JITupdate(); 0234 0235 if (node) 0236 { 0237 if (node->hideCount() > delLim || hide) 0238 { 0239 trixel->removeChildNode(node); 0240 delete node; 0241 *i = QPair<SkyObject *, SkyNode *>((*i).first, 0); 0242 } 0243 else 0244 { 0245 if (!hide) 0246 { 0247 node->update(drawLabel); 0248 } 0249 else 0250 { 0251 node->hide(); 0252 } 0253 } 0254 } 0255 else 0256 { 0257 if (!hide && projector->checkVisibility(starObj)) 0258 { 0259 QPointF pos; 0260 0261 bool visible = false; 0262 pos = projector->toScreen(starObj, true, &visible); 0263 if (visible && projector->onScreen(pos)) 0264 { 0265 PointSourceNode *point = 0266 new PointSourceNode(starObj, rootNode(), LabelsItem::label_t::STAR_LABEL, 0267 starObj->spchar(), starObj->mag(), trixelID); 0268 trixel->appendChildNode(point); 0269 0270 *i = QPair<SkyObject *, SkyNode *>((*i).first, static_cast<SkyNode *>(point)); 0271 point->updatePos(pos, drawLabel); 0272 } 0273 } 0274 } 0275 ++i; 0276 } 0277 } 0278 trixel = static_cast<TrixelNode *>(trixel->nextSibling()); 0279 label = static_cast<TrixelNode *>(label->nextSibling()); 0280 0281 ++trixelID; 0282 } 0283 0284 // Draw focusStar if not null 0285 /*if( focusStar ) { 0286 if ( focusStar->updateID != updateID ) 0287 focusStar->JITupdate(); 0288 float mag = focusStar->mag(); 0289 skyp->drawPointSource(focusStar, mag, focusStar->spchar() ); 0290 }*/ 0291 0292 // Now draw each of our DeepStarComponents 0293 QSGNode *deep = m_deepStars->firstChild(); 0294 while (deep != 0) 0295 { 0296 DeepStarItem *deepStars = static_cast<DeepStarItem *>(deep); 0297 deep = deep->nextSibling(); 0298 deepStars->update(); 0299 } 0300 0301 QSGNode *n = m_stars->firstChild(); 0302 while (n != 0) 0303 { 0304 n = n->nextSibling(); 0305 } 0306 m_skyMesh->inDraw(false); 0307 }