Skip to content

Commit b7ae735

Browse files
committed
Add dedicated renderers for deep sky objects
1 parent 4616f5f commit b7ae735

26 files changed

+2071
-1511
lines changed

src/celengine/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ set(CELENGINE_SOURCES
3737
frametree.h
3838
galaxy.cpp
3939
galaxy.h
40+
galaxyform.cpp
41+
galaxyform.h
4042
geometry.h
4143
glmarker.cpp
4244
globular.cpp

src/celengine/deepskyobj.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,6 @@ class DeepSkyObject
8181
double& distanceToPicker,
8282
double& cosAngleToBoundCenter) const = 0;
8383
virtual bool load(const AssociativeArray*, const fs::path& resPath);
84-
virtual void render(const Eigen::Vector3f& offset,
85-
const Eigen::Quaternionf& viewerOrientation,
86-
float brightness,
87-
float pixelSize,
88-
const Matrices& m,
89-
Renderer*) = 0;
9084

9185
virtual uint64_t getRenderMask() const { return 0; }
9286
virtual unsigned int getLabelMask() const { return 0; }

src/celengine/dsorenderer.cpp

Lines changed: 85 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,67 @@
1010

1111
#include <celengine/dsodb.h>
1212
#include <celengine/deepskyobj.h>
13-
#include <celmath/geomutil.h>
14-
#include <celmath/vecgl.h>
15-
#include "glsupport.h"
13+
#include <celrender/galaxyrenderer.h>
14+
#include <celrender/globularrenderer.h>
15+
#include <celrender/nebularenderer.h>
16+
#include <celrender/openclusterrenderer.h>
1617
#include "render.h"
17-
1818
#include "dsorenderer.h"
1919

20-
using namespace Eigen;
21-
using namespace celestia;
22-
using namespace celmath;
2320

21+
namespace
22+
{
2423
// The parameter 'enhance' adjusts the DSO brightness as viewed from "inside"
25-
// (e.g. MilkyWay as seen from Earth). It provides an enhanced apparent core
24+
// (e.g. MilkyWay as seen from Earth). It provides an enhanced apparent core
2625
// brightness appMag ~ absMag - enhance. 'enhance' thus serves to uniformly
2726
// enhance the too low sprite luminosity at close distance.
28-
constexpr const double enhance = 4.0;
29-
constexpr const double pc10 = 32.6167; // 10 parsecs
30-
static const float CubeCornerToCenterDistance = sqrt(3.0f);
27+
constexpr double enhance = 4.0;
28+
constexpr double pc10 = 32.6167; // 10 parsecs
29+
constexpr float CubeCornerToCenterDistance = 1.7320508075688772f;
30+
31+
enum class DeepSkyObjectType
32+
{
33+
Galaxy,
34+
Globular,
35+
Nebula,
36+
OpenCluster
37+
};
38+
39+
DeepSkyObjectType
40+
GetDSOType(const DeepSkyObject* dso)
41+
{
42+
if (!strcmp(dso->getObjTypeName(), "galaxy"))
43+
return DeepSkyObjectType::Galaxy;
44+
45+
if (!strcmp(dso->getObjTypeName(), "globular"))
46+
return DeepSkyObjectType::Globular;
47+
48+
if (!strcmp(dso->getObjTypeName(), "nebula"))
49+
return DeepSkyObjectType::Nebula;
50+
51+
if (!strcmp(dso->getObjTypeName(), "opencluster"))
52+
return DeepSkyObjectType::OpenCluster;
53+
}
54+
55+
float
56+
brightness(float avgAbsMag, float absMag, float appMag, float brightnessCorr, float faintestMag)
57+
{
58+
// Input: display looks satisfactory for 0.2 < brightness < O(1.0)
59+
// Ansatz: brightness = a - b * appMag(distanceToDSO), emulating eye sensitivity...
60+
// determine a,b such that
61+
// a - b * absMag = absMag / avgAbsMag ~ 1; a - b * faintestMag = 0.2.
62+
// The 2nd eq. guarantees that the faintest galaxies are still visible.
63+
64+
float r = absMag / avgAbsMag;
65+
float b = r - (r - 0.2f) * (absMag - appMag) / (absMag - faintestMag);
66+
67+
// obviously, brightness(appMag = absMag) = r and
68+
// brightness(appMag = faintestMag) = 0.2, as desired.
69+
70+
return std::max(0.0f, b * brightnessCorr);
71+
}
72+
73+
} // anonymous namespace
3174

3275
DSORenderer::DSORenderer() :
3376
ObjectRenderer<DeepSkyObject*, double>(DSO_OCTREE_ROOT_SIZE)
@@ -41,15 +84,15 @@ void DSORenderer::process(DeepSkyObject* const &dso,
4184
if (distanceToDSO > distanceLimit || !dso->isVisible())
4285
return;
4386

44-
Vector3f relPos = (dso->getPosition() - obsPos).cast<float>();
45-
Vector3f center = orientationMatrixT * relPos;
87+
Eigen::Vector3f relPos = (dso->getPosition() - obsPos).cast<float>();
88+
Eigen::Vector3f center = orientationMatrixT * relPos;
4689

4790
// Test the object's bounding sphere against the view frustum. If we
4891
// avoid this stage, overcrowded octree cells may hit performance badly:
4992
// each object (even if it's not visible) would be sent to the OpenGL
5093
// pipeline.
5194
double dsoRadius = dso->getBoundingSphereRadius();
52-
if (frustum.testSphere(center, (float) dsoRadius) == Frustum::Outside)
95+
if (frustum.testSphere(center, (float) dsoRadius) == celmath::Frustum::Outside)
5396
return;
5497

5598
float appMag;
@@ -62,59 +105,45 @@ void DSORenderer::process(DeepSkyObject* const &dso,
62105
{
63106
dsosProcessed++;
64107

65-
// Input: display looks satisfactory for 0.2 < brightness < O(1.0)
66-
// Ansatz: brightness = a - b * appMag(distanceToDSO), emulating eye sensitivity...
67-
// determine a,b such that
68-
// a - b * absMag = absMag / avgAbsMag ~ 1; a - b * faintestMag = 0.2.
69-
// The 2nd eq. guarantees that the faintest galaxies are still visible.
70-
71-
if (!strcmp(dso->getObjTypeName(), "globular"))
72-
avgAbsMag = -6.86f; // average over 150 globulars in globulars.dsc.
73-
else if (!strcmp(dso->getObjTypeName(), "galaxy"))
74-
avgAbsMag = -19.04f; // average over 10937 galaxies in galaxies.dsc.
75-
76-
float r = absMag / avgAbsMag;
77-
float brightness = r - (r - 0.2f) * (absMag - appMag) / (absMag - faintestMag);
78-
79-
// obviously, brightness(appMag = absMag) = r and
80-
// brightness(appMag = faintestMag) = 0.2, as desired.
81-
82-
brightness *= 2.3f * (faintestMag - 4.75f) / renderer->getFaintestAM45deg();
83-
84-
if (brightness < 0)
85-
brightness = 0;
86-
87-
Matrix4f mv = celmath::translate(renderer->getModelViewMatrix(), relPos);
88-
Matrix4f pr;
89-
108+
float nearZ = 0.0f, farZ = 0.0f;
90109
if (dsoRadius < 1000.0)
91110
{
92111
// Small objects may be prone to clipping; give them special
93112
// handling. We don't want to always set the projection
94113
// matrix, since that could be expensive with large galaxy
95114
// catalogs.
96-
auto nearZ = (float)(distanceToDSO / 2);
97-
auto farZ = (float)(distanceToDSO + dsoRadius * 2 * CubeCornerToCenterDistance);
98-
if (nearZ < dsoRadius * 0.001)
115+
nearZ = static_cast<float>(distanceToDSO / 2.0);
116+
farZ = static_cast<float>(distanceToDSO + dsoRadius * 2.0 * CubeCornerToCenterDistance);
117+
auto minZ = static_cast<float>(dsoRadius * 0.001);
118+
if (nearZ < minZ)
99119
{
100-
nearZ = (float)(dsoRadius * 0.001);
120+
nearZ = minZ;
101121
farZ = nearZ * 10000.0f;
102122
}
103-
104-
float t = renderer->getAspectRatio();
105-
if (renderer->getProjectionMode() == Renderer::ProjectionMode::FisheyeMode)
106-
pr = Ortho(-t, t, -1.0f, 1.0f, nearZ, farZ);
107-
else
108-
pr = Perspective(fov, t, nearZ, farZ);
109123
}
110-
else
124+
125+
float b = 2.3f * (faintestMag - 4.75f) / renderer->getFaintestAM45deg(); // brightnesCorr
126+
switch (GetDSOType(dso))
111127
{
112-
pr = renderer->getProjectionMatrix();
128+
case DeepSkyObjectType::Galaxy:
129+
// -19.04f == average over 10937 galaxies in galaxies.dsc.
130+
b = brightness(-19.04f, absMag, appMag, b, faintestMag);
131+
galaxyRenderer->add(reinterpret_cast<Galaxy*>(dso), relPos, b, nearZ, farZ);
132+
break;
133+
case DeepSkyObjectType::Globular:
134+
// -6.86f == average over 150 globulars in globulars.dsc.
135+
b = brightness(-6.86f, absMag, appMag, b, faintestMag);
136+
globularRenderer->add(reinterpret_cast<Globular*>(dso), relPos, b, nearZ, farZ);
137+
break;
138+
case DeepSkyObjectType::Nebula:
139+
b = brightness(avgAbsMag, absMag, appMag, b, faintestMag);
140+
nebulaRenderer->add(reinterpret_cast<Nebula*>(dso), relPos, b, nearZ, farZ);
141+
break;
142+
case DeepSkyObjectType::OpenCluster:
143+
b = brightness(avgAbsMag, absMag, appMag, b, faintestMag);
144+
openClusterRenderer->add(reinterpret_cast<OpenCluster*>(dso), relPos, b, nearZ, farZ);
145+
break;
113146
}
114-
115-
dso->render(relPos, observer->getOrientationf(), brightness,
116-
pixelSize, { &pr, &mv }, renderer);
117-
118147
} // renderFlags check
119148

120149
// Only render those labels that are in front of the camera:
@@ -169,9 +198,7 @@ void DSORenderer::process(DeepSkyObject* const &dso,
169198
if (appMagEff < labelThresholdMag)
170199
{
171200
// introduce distance dependent label transparency.
172-
float distr = step * (labelThresholdMag - appMagEff) / labelThresholdMag;
173-
if (distr > 1.0f)
174-
distr = 1.0f;
201+
float distr = std::min(1.0f, step * (labelThresholdMag - appMagEff) / labelThresholdMag);
175202
labelColor.alpha(distr * labelColor.alpha());
176203

177204
renderer->addBackgroundAnnotation(rep,

src/celengine/dsorenderer.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// dsorenderer.h
22
//
3-
// Copyright (C) 2001-2020, the Celestia Development Team
3+
// Copyright (C) 2001-present, the Celestia Development Team
44
// Original version by Chris Laurel <[email protected]>
55
//
66
// This program is free software; you can redistribute it and/or
@@ -12,23 +12,29 @@
1212

1313
#include <Eigen/Core>
1414
#include <celmath/frustum.h>
15+
#include <celrender/rendererfwd.h>
1516
#include "objectrenderer.h"
1617

1718
class DeepSkyObject;
1819

1920
class DSORenderer : public ObjectRenderer<DeepSkyObject*, double>
2021
{
21-
public:
22+
public:
2223
DSORenderer();
2324

2425
void process(DeepSkyObject* const &, double, float);
2526

26-
public:
2727
Eigen::Vector3d obsPos;
2828
Eigen::Matrix3f orientationMatrixT;
2929
celmath::Frustum frustum { 45.0_deg, 1.0f, 1.0f };
3030
DSODatabase* dsoDB { nullptr };
3131

3232
float avgAbsMag { 0.0f };
3333
uint32_t dsosProcessed { 0 };
34+
35+
celestia::render::GalaxyRenderer *galaxyRenderer{ nullptr };
36+
celestia::render::GlobularRenderer *globularRenderer{ nullptr };
37+
celestia::render::NebulaRenderer *nebulaRenderer{ nullptr };
38+
celestia::render::OpenClusterRenderer *openClusterRenderer{ nullptr };
39+
3440
};

0 commit comments

Comments
 (0)