Celestia

Форк
0
/
dsodb.cpp 
170 строк · 5.1 Кб
1
// dsodb.cpp
2
//
3
// Copyright (C) 2005-2024, the Celestia Development Team
4
//
5
// Original version:
6
// Author: Toti <root@totibox>, (C) 2005
7
//
8
// This program is free software; you can redistribute it and/or
9
// modify it under the terms of the GNU General Public License
10
// as published by the Free Software Foundation; either version 2
11
// of the License, or (at your option) any later version.
12

13
#include "dsodb.h"
14

15
#include <algorithm>
16
#include <array>
17
#include <utility>
18

19
#include <celutil/gettext.h>
20
#include <celutil/logger.h>
21
#include "name.h"
22

23
namespace engine = celestia::engine;
24

25
using celestia::util::GetLogger;
26

27
DSODatabase::~DSODatabase() = default;
28

29
DSODatabase::DSODatabase(std::unique_ptr<engine::DSOOctree>&& octreeRoot,
30
                         std::unique_ptr<NameDatabase>&& namesDB,
31
                         std::vector<std::uint32_t>&& catalogNumberIndex,
32
                         float avgAbsMag) :
33
    m_octreeRoot(std::move(octreeRoot)),
34
    m_namesDB(std::move(namesDB)),
35
    m_catalogNumberIndex(std::move(catalogNumberIndex)),
36
    m_avgAbsMag(avgAbsMag)
37
{
38
}
39

40
DeepSkyObject*
41
DSODatabase::find(const AstroCatalog::IndexNumber catalogNumber) const
42
{
43
    auto it = std::lower_bound(m_catalogNumberIndex.begin(),
44
                               m_catalogNumberIndex.end(),
45
                               catalogNumber,
46
                               [this](std::uint32_t idx, AstroCatalog::IndexNumber catNum)
47
                               {
48
                                   return (*m_octreeRoot)[idx]->getIndex() < catNum;
49
                               });
50

51
    if (it == m_catalogNumberIndex.end())
52
        return nullptr;
53

54
    DeepSkyObject* dso = (*m_octreeRoot)[*it].get();
55
    return dso->getIndex() == catalogNumber ? dso : nullptr;
56
}
57

58
DeepSkyObject*
59
DSODatabase::find(std::string_view name, bool i18n) const
60
{
61
    if (name.empty())
62
        return nullptr;
63

64
    AstroCatalog::IndexNumber catalogNumber = m_namesDB->getCatalogNumberByName(name, i18n);
65
    return catalogNumber == AstroCatalog::InvalidIndex
66
        ? nullptr
67
        : find(catalogNumber);
68
}
69

70
void
71
DSODatabase::getCompletion(std::vector<std::string>& completion, std::string_view name) const
72
{
73
    // only named DSOs are supported by completion.
74
    if (!name.empty())
75
        m_namesDB->getCompletion(completion, name);
76
}
77

78
std::string
79
DSODatabase::getDSOName(const DeepSkyObject* dso, [[maybe_unused]] bool i18n) const
80
{
81
    AstroCatalog::IndexNumber catalogNumber = dso->getIndex();
82

83
    auto iter = m_namesDB->getFirstNameIter(catalogNumber);
84
    if (iter == m_namesDB->getFinalNameIter())
85
        return {};
86

87
#ifdef ENABLE_NLS
88
    if (i18n)
89
    {
90
        const char* local = D_(iter->second.c_str());
91
        if (iter->second != local)
92
            return local;
93
    }
94
#endif
95

96
    return iter->second;
97
}
98

99
std::string
100
DSODatabase::getDSONameList(const DeepSkyObject* dso, const unsigned int maxNames) const
101
{
102
    std::string dsoNames;
103

104
    auto catalogNumber = dso->getIndex();
105
    auto iter = m_namesDB->getFirstNameIter(catalogNumber);
106

107
    unsigned int count = 0;
108
    while (iter != m_namesDB->getFinalNameIter() && iter->first == catalogNumber && count < maxNames)
109
    {
110
        if (count != 0)
111
            dsoNames.append(" / ");
112

113
        dsoNames.append(D_(iter->second.c_str()));
114
        ++iter;
115
        ++count;
116
    }
117

118
    return dsoNames;
119
}
120

121
void
122
DSODatabase::findVisibleDSOs(engine::DSOHandler& dsoHandler,
123
                             const Eigen::Vector3d& obsPos,
124
                             const Eigen::Quaternionf& obsOrient,
125
                             float fovY,
126
                             float aspectRatio,
127
                             float limitingMag) const
128
{
129
    // Compute the bounding planes of an infinite view frustum
130
    std::array<Eigen::Hyperplane<double, 3>, 5> frustumPlanes;
131

132
    Eigen::Quaterniond obsOrientd = obsOrient.cast<double>();
133
    Eigen::Matrix3d rot = obsOrientd.toRotationMatrix().transpose();
134
    double h = std::tan(fovY / 2);
135
    double w = h * aspectRatio;
136

137
    std::array<Eigen::Vector3d, 5> planeNormals
138
    {
139
        Eigen::Vector3d( 0,  1, -h),
140
        Eigen::Vector3d( 0, -1, -h),
141
        Eigen::Vector3d( 1,  0, -w),
142
        Eigen::Vector3d(-1,  0, -w),
143
        Eigen::Vector3d( 0,  0, -1),
144
    };
145

146
    for (int i = 0; i < 5; ++i)
147
    {
148
        planeNormals[i]  = rot * planeNormals[i].normalized();
149
        frustumPlanes[i] = Eigen::Hyperplane<double, 3>(planeNormals[i], obsPos);
150
    }
151

152
    engine::DSOOctreeVisibleObjectsProcessor processor(&dsoHandler,
153
                                                       obsPos,
154
                                                       frustumPlanes,
155
                                                       limitingMag);
156

157
    m_octreeRoot->processDepthFirst(processor);
158
}
159

160
void
161
DSODatabase::findCloseDSOs(engine::DSOHandler& dsoHandler,
162
                           const Eigen::Vector3d& obsPos,
163
                           float radius) const
164
{
165
    engine::DSOOctreeCloseObjectsProcessor processor(&dsoHandler,
166
                                                     obsPos,
167
                                                     radius);
168

169
    m_octreeRoot->processDepthFirst(processor);
170
}
171

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.