Reduce indirection, re-use custom templates if possible
parent
31b67185dd
commit
e8782ceeb0
|
@ -11,9 +11,11 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstddef>
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <map>
|
||||||
|
#include <optional>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <fmt/printf.h>
|
#include <fmt/printf.h>
|
||||||
|
@ -57,7 +59,7 @@ using BlobVector = std::vector<Blob>;
|
||||||
class GalacticForm
|
class GalacticForm
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BlobVector* blobs;
|
BlobVector blobs;
|
||||||
Eigen::Vector3f scale;
|
Eigen::Vector3f scale;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,9 +78,10 @@ constexpr float MAX_SPIRAL_THICKNESS = 0.06f;
|
||||||
|
|
||||||
bool formsInitialized = false;
|
bool formsInitialized = false;
|
||||||
|
|
||||||
GalacticForm** spiralForms = nullptr;
|
constexpr std::size_t GalacticFormsReserve = 32;
|
||||||
GalacticForm** ellipticalForms = nullptr;
|
|
||||||
GalacticForm* irregularForm = nullptr;
|
std::vector<std::optional<GalacticForm>> galacticForms;
|
||||||
|
std::map<fs::path, std::size_t> customForms;
|
||||||
|
|
||||||
Texture* galaxyTex = nullptr;
|
Texture* galaxyTex = nullptr;
|
||||||
Texture* colorTex = nullptr;
|
Texture* colorTex = nullptr;
|
||||||
|
@ -86,30 +89,30 @@ Texture* colorTex = nullptr;
|
||||||
struct GalaxyTypeName
|
struct GalaxyTypeName
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
Galaxy::GalaxyType type;
|
GalaxyType type;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr const GalaxyTypeName GalaxyTypeNames[] =
|
constexpr const GalaxyTypeName GalaxyTypeNames[] =
|
||||||
{
|
{
|
||||||
{ "S0", Galaxy::S0 },
|
{ "Irr", GalaxyType::Irr },
|
||||||
{ "Sa", Galaxy::Sa },
|
{ "S0", GalaxyType::S0 },
|
||||||
{ "Sb", Galaxy::Sb },
|
{ "Sa", GalaxyType::Sa },
|
||||||
{ "Sc", Galaxy::Sc },
|
{ "Sb", GalaxyType::Sb },
|
||||||
{ "SBa", Galaxy::SBa },
|
{ "Sc", GalaxyType::Sc },
|
||||||
{ "SBb", Galaxy::SBb },
|
{ "SBa", GalaxyType::SBa },
|
||||||
{ "SBc", Galaxy::SBc },
|
{ "SBb", GalaxyType::SBb },
|
||||||
{ "E0", Galaxy::E0 },
|
{ "SBc", GalaxyType::SBc },
|
||||||
{ "E1", Galaxy::E1 },
|
{ "E0", GalaxyType::E0 },
|
||||||
{ "E2", Galaxy::E2 },
|
{ "E1", GalaxyType::E1 },
|
||||||
{ "E3", Galaxy::E3 },
|
{ "E2", GalaxyType::E2 },
|
||||||
{ "E4", Galaxy::E4 },
|
{ "E3", GalaxyType::E3 },
|
||||||
{ "E5", Galaxy::E5 },
|
{ "E4", GalaxyType::E4 },
|
||||||
{ "E6", Galaxy::E6 },
|
{ "E5", GalaxyType::E5 },
|
||||||
{ "E7", Galaxy::E7 },
|
{ "E6", GalaxyType::E6 },
|
||||||
{ "Irr", Galaxy::Irr },
|
{ "E7", GalaxyType::E7 },
|
||||||
};
|
};
|
||||||
|
|
||||||
void GalaxyTextureEval(float u, float v, float /*w*/, unsigned char *pixel)
|
void galaxyTextureEval(float u, float v, float /*w*/, unsigned char *pixel)
|
||||||
{
|
{
|
||||||
float r = 0.9f - std::sqrt(u * u + v * v );
|
float r = 0.9f - std::sqrt(u * u + v * v );
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -122,7 +125,7 @@ void GalaxyTextureEval(float u, float v, float /*w*/, unsigned char *pixel)
|
||||||
pixel[3] = pixVal;
|
pixel[3] = pixVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorTextureEval(float u, float /*v*/, float /*w*/, unsigned char *pixel)
|
void colorTextureEval(float u, float /*v*/, float /*w*/, unsigned char *pixel)
|
||||||
{
|
{
|
||||||
unsigned int i = static_cast<unsigned int>((static_cast<float>(u)*0.5f + 0.5f)*255.99f); // [-1, 1] -> [0, 255]
|
unsigned int i = static_cast<unsigned int>((static_cast<float>(u)*0.5f + 0.5f)*255.99f); // [-1, 1] -> [0, 255]
|
||||||
|
|
||||||
|
@ -159,10 +162,10 @@ GalaxyVertex *g_vertices = nullptr;
|
||||||
GLushort *g_indices = nullptr;
|
GLushort *g_indices = nullptr;
|
||||||
constexpr const std::size_t maxPoints = 8192; // 256k buffer
|
constexpr const std::size_t maxPoints = 8192; // 256k buffer
|
||||||
|
|
||||||
GalacticForm* buildGalacticForms(const fs::path& filename)
|
std::optional<GalacticForm> buildGalacticForm(const fs::path& filename)
|
||||||
{
|
{
|
||||||
Blob b;
|
Blob b;
|
||||||
BlobVector* galacticPoints = new BlobVector;
|
BlobVector galacticPoints;
|
||||||
|
|
||||||
// Load templates in standard .png format
|
// Load templates in standard .png format
|
||||||
int width, height, rgb, j = 0, kmin = 9;
|
int width, height, rgb, j = 0, kmin = 9;
|
||||||
|
@ -172,8 +175,7 @@ GalacticForm* buildGalacticForms(const fs::path& filename)
|
||||||
if (img == nullptr)
|
if (img == nullptr)
|
||||||
{
|
{
|
||||||
celestia::util::GetLogger()->error("The galaxy template *** {} *** could not be loaded!\n", filename);
|
celestia::util::GetLogger()->error("The galaxy template *** {} *** could not be loaded!\n", filename);
|
||||||
delete galacticPoints;
|
return std::nullopt;
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
width = img->getWidth();
|
width = img->getWidth();
|
||||||
height = img->getHeight();
|
height = img->getHeight();
|
||||||
|
@ -199,7 +201,7 @@ GalacticForm* buildGalacticForms(const fs::path& filename)
|
||||||
if (filename != "models/E0.png")
|
if (filename != "models/E0.png")
|
||||||
{
|
{
|
||||||
float y0 = 0.5f * MAX_SPIRAL_THICKNESS * std::sqrt(static_cast<float>(value)/256.0f) * std::exp(- 5.0f * r2);
|
float y0 = 0.5f * MAX_SPIRAL_THICKNESS * std::sqrt(static_cast<float>(value)/256.0f) * std::exp(- 5.0f * r2);
|
||||||
float B = (r2 > 0.35f)? 1.0f: 0.75f; // the darkness of the "dust lane", 0 < B < 1
|
float B = (r2 > 0.35f) ? 1.0f: 0.75f; // the darkness of the "dust lane", 0 < B < 1
|
||||||
float p0 = 1.0f - B * std::exp(-h * h); // the uniform reference probability, envelopping prob*p0.
|
float p0 = 1.0f - B * std::exp(-h * h); // the uniform reference probability, envelopping prob*p0.
|
||||||
float yr, prob;
|
float yr, prob;
|
||||||
do
|
do
|
||||||
|
@ -209,7 +211,6 @@ GalacticForm* buildGalacticForms(const fs::path& filename)
|
||||||
|
|
||||||
yr = celmath::RealDists<float>::SignedUnit(rng) * h;
|
yr = celmath::RealDists<float>::SignedUnit(rng) * h;
|
||||||
prob = (1.0f - B * exp(-yr * yr))/p0;
|
prob = (1.0f - B * exp(-yr * yr))/p0;
|
||||||
|
|
||||||
} while (celmath::RealDists<float>::Unit(rng) > prob);
|
} while (celmath::RealDists<float>::Unit(rng) > prob);
|
||||||
b.brightness = value * prob;
|
b.brightness = value * prob;
|
||||||
y = y0 * yr / h;
|
y = y0 * yr / h;
|
||||||
|
@ -232,80 +233,40 @@ GalacticForm* buildGalacticForms(const fs::path& filename)
|
||||||
b.position = Eigen::Vector4f(x, y, z, 1.0f);
|
b.position = Eigen::Vector4f(x, y, z, 1.0f);
|
||||||
unsigned int rr = static_cast<unsigned int>(b.position.head(3).norm() * 511);
|
unsigned int rr = static_cast<unsigned int>(b.position.head(3).norm() * 511);
|
||||||
b.colorIndex = rr < 256 ? rr : 255;
|
b.colorIndex = rr < 256 ? rr : 255;
|
||||||
galacticPoints->push_back(b);
|
galacticPoints.push_back(b);
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete img;
|
delete img;
|
||||||
galacticPoints->reserve(j);
|
galacticPoints.reserve(j);
|
||||||
|
|
||||||
// sort to start with the galaxy center region (x^2 + y^2 + z^2 ~ 0), such that
|
// sort to start with the galaxy center region (x^2 + y^2 + z^2 ~ 0), such that
|
||||||
// the biggest (brightest) sprites will be localized there!
|
// the biggest (brightest) sprites will be localized there!
|
||||||
|
|
||||||
std::sort(galacticPoints->begin(), galacticPoints->end());
|
std::sort(galacticPoints.begin(), galacticPoints.end());
|
||||||
|
|
||||||
// reshuffle the galaxy points randomly...except the first kmin+1 in the center!
|
// reshuffle the galaxy points randomly...except the first kmin+1 in the center!
|
||||||
// the higher that number the stronger the central "glow"
|
// the higher that number the stronger the central "glow"
|
||||||
|
|
||||||
std::shuffle(galacticPoints->begin() + kmin, galacticPoints->end(), celmath::getRNG());
|
std::shuffle(galacticPoints.begin() + kmin, galacticPoints.end(), celmath::getRNG());
|
||||||
|
|
||||||
auto* galacticForm = new GalacticForm();
|
std::optional<GalacticForm> galacticForm(std::in_place);
|
||||||
galacticForm->blobs = galacticPoints;
|
galacticForm->blobs = std::move(galacticPoints);
|
||||||
galacticForm->scale = Eigen::Vector3f::Ones();
|
galacticForm->scale = Eigen::Vector3f::Ones();
|
||||||
|
|
||||||
return galacticForm;
|
return galacticForm;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeForms()
|
void initializeForms()
|
||||||
{
|
{
|
||||||
// Spiral Galaxies, 7 classical Hubble types
|
// Irregular Galaxies
|
||||||
|
|
||||||
spiralForms = new GalacticForm*[7];
|
|
||||||
|
|
||||||
spiralForms[Galaxy::S0] = buildGalacticForms("models/S0.png");
|
|
||||||
spiralForms[Galaxy::Sa] = buildGalacticForms("models/Sa.png");
|
|
||||||
spiralForms[Galaxy::Sb] = buildGalacticForms("models/Sb.png");
|
|
||||||
spiralForms[Galaxy::Sc] = buildGalacticForms("models/Sc.png");
|
|
||||||
spiralForms[Galaxy::SBa] = buildGalacticForms("models/SBa.png");
|
|
||||||
spiralForms[Galaxy::SBb] = buildGalacticForms("models/SBb.png");
|
|
||||||
spiralForms[Galaxy::SBc] = buildGalacticForms("models/SBc.png");
|
|
||||||
|
|
||||||
// Elliptical Galaxies , 8 classical Hubble types, E0..E7,
|
|
||||||
//
|
|
||||||
// To save space: generate spherical E0 template from S0 disk
|
|
||||||
// via rescaling by (1.0f, 3.8f, 1.0f).
|
|
||||||
|
|
||||||
ellipticalForms = new GalacticForm*[8];
|
|
||||||
for (unsigned int eform = 0; eform <= 7; ++eform)
|
|
||||||
{
|
|
||||||
float ell = 1.0f - static_cast<float>(eform) / 8.0f;
|
|
||||||
|
|
||||||
// note the correct x,y-alignment of 'ell' scaling!!
|
|
||||||
// build all elliptical templates from rescaling E0
|
|
||||||
|
|
||||||
ellipticalForms[eform] = buildGalacticForms("models/E0.png");
|
|
||||||
if (*ellipticalForms)
|
|
||||||
ellipticalForms[eform]->scale = Eigen::Vector3f(ell, ell, 1.0f);
|
|
||||||
|
|
||||||
// account for reddening of ellipticals rel.to spirals
|
|
||||||
if (*ellipticalForms)
|
|
||||||
{
|
|
||||||
unsigned int nPoints = static_cast<unsigned int>(ellipticalForms[eform]->blobs->size());
|
|
||||||
for (unsigned int i = 0; i < nPoints; ++i)
|
|
||||||
{
|
|
||||||
(*ellipticalForms[eform]->blobs)[i].colorIndex =
|
|
||||||
static_cast<unsigned int>(std::ceil(0.76f * static_cast<float>((*ellipticalForms[eform]->blobs)[i].colorIndex)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Irregular Galaxies
|
|
||||||
unsigned int galaxySize = GALAXY_POINTS, ip = 0;
|
unsigned int galaxySize = GALAXY_POINTS, ip = 0;
|
||||||
Blob b;
|
Blob b;
|
||||||
Eigen::Vector3f p;
|
Eigen::Vector3f p;
|
||||||
|
|
||||||
BlobVector* irregularPoints = new BlobVector;
|
BlobVector irregularPoints;
|
||||||
irregularPoints->reserve(galaxySize);
|
irregularPoints.reserve(galaxySize);
|
||||||
|
|
||||||
auto& rng = celmath::getRNG();
|
auto& rng = celmath::getRNG();
|
||||||
while (ip < galaxySize)
|
while (ip < galaxySize)
|
||||||
|
@ -323,18 +284,69 @@ void InitializeForms()
|
||||||
b.brightness = 64u;
|
b.brightness = 64u;
|
||||||
auto rr = static_cast<unsigned int>(r * 511);
|
auto rr = static_cast<unsigned int>(r * 511);
|
||||||
b.colorIndex = rr < 256 ? rr : 255;
|
b.colorIndex = rr < 256 ? rr : 255;
|
||||||
irregularPoints->push_back(b);
|
irregularPoints.push_back(b);
|
||||||
++ip;
|
++ip;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
irregularForm = new GalacticForm();
|
|
||||||
irregularForm->blobs = irregularPoints;
|
GalacticForm& irregularForm = *galacticForms.emplace_back(std::in_place);
|
||||||
irregularForm->scale = Eigen::Vector3f::Constant(0.5f);
|
irregularForm.blobs = std::move(irregularPoints);
|
||||||
|
irregularForm.scale = Eigen::Vector3f::Constant(0.5f);
|
||||||
|
|
||||||
|
// Spiral Galaxies, 7 classical Hubble types
|
||||||
|
|
||||||
|
galacticForms.reserve(GalacticFormsReserve);
|
||||||
|
|
||||||
|
galacticForms.push_back(buildGalacticForm("models/S0.png"));
|
||||||
|
galacticForms.push_back(buildGalacticForm("models/Sa.png"));
|
||||||
|
galacticForms.push_back(buildGalacticForm("models/Sb.png"));
|
||||||
|
galacticForms.push_back(buildGalacticForm("models/Sc.png"));
|
||||||
|
galacticForms.push_back(buildGalacticForm("models/SBa.png"));
|
||||||
|
galacticForms.push_back(buildGalacticForm("models/SBb.png"));
|
||||||
|
galacticForms.push_back(buildGalacticForm("models/SBc.png"));
|
||||||
|
|
||||||
|
// Elliptical Galaxies , 8 classical Hubble types, E0..E7,
|
||||||
|
//
|
||||||
|
// To save space: generate spherical E0 template from S0 disk
|
||||||
|
// via rescaling by (1.0f, 3.8f, 1.0f).
|
||||||
|
|
||||||
|
for (unsigned int eform = 0; eform <= 7; ++eform)
|
||||||
|
{
|
||||||
|
float ell = 1.0f - static_cast<float>(eform) / 8.0f;
|
||||||
|
|
||||||
|
// note the correct x,y-alignment of 'ell' scaling!!
|
||||||
|
// build all elliptical templates from rescaling E0
|
||||||
|
|
||||||
|
galacticForms.push_back(buildGalacticForm("models/E0.png"));
|
||||||
|
if (!galacticForms.back().has_value()) { continue; }
|
||||||
|
|
||||||
|
GalacticForm& ellipticalForm = *galacticForms.back();
|
||||||
|
ellipticalForm.scale = Eigen::Vector3f(ell, ell, 1.0f);
|
||||||
|
|
||||||
|
for (Blob& blob : ellipticalForm.blobs)
|
||||||
|
{
|
||||||
|
blob.colorIndex = static_cast<unsigned int>(std::ceil(0.76f * static_cast<float>(blob.colorIndex)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
formsInitialized = true;
|
formsInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::size_t customForm(const fs::path& path)
|
||||||
|
{
|
||||||
|
auto iter = customForms.find(path);
|
||||||
|
if (iter != customForms.end())
|
||||||
|
{
|
||||||
|
return iter->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t result = galacticForms.size();
|
||||||
|
customForms[path] = result;
|
||||||
|
galacticForms.push_back(buildGalacticForm(path));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
} // end unnamed namespace
|
} // end unnamed namespace
|
||||||
|
|
||||||
|
|
||||||
|
@ -350,22 +362,6 @@ void Galaxy::setDetail(float d)
|
||||||
detail = d;
|
detail = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Galaxy::setCustomTmpName(const std::string& tmpNameStr)
|
|
||||||
{
|
|
||||||
if (customTmpName == nullptr)
|
|
||||||
customTmpName = new std::string(tmpNameStr);
|
|
||||||
else
|
|
||||||
*customTmpName = tmpNameStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Galaxy::getCustomTmpName() const
|
|
||||||
{
|
|
||||||
if (customTmpName == nullptr)
|
|
||||||
return "";
|
|
||||||
else
|
|
||||||
return *customTmpName;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* Galaxy::getType() const
|
const char* Galaxy::getType() const
|
||||||
{
|
{
|
||||||
return GalaxyTypeNames[static_cast<std::size_t>(type)].name;
|
return GalaxyTypeNames[static_cast<std::size_t>(type)].name;
|
||||||
|
@ -373,47 +369,25 @@ const char* Galaxy::getType() const
|
||||||
|
|
||||||
void Galaxy::setType(const std::string& typeStr)
|
void Galaxy::setType(const std::string& typeStr)
|
||||||
{
|
{
|
||||||
type = Galaxy::Irr;
|
type = GalaxyType::Irr;
|
||||||
auto iter = std::find_if(std::begin(GalaxyTypeNames), std::end(GalaxyTypeNames),
|
auto iter = std::find_if(std::begin(GalaxyTypeNames), std::end(GalaxyTypeNames),
|
||||||
[&](const GalaxyTypeName& g) { return g.name == typeStr; });
|
[&](const GalaxyTypeName& g) { return g.name == typeStr; });
|
||||||
if (iter != std::end(GalaxyTypeNames))
|
if (iter != std::end(GalaxyTypeNames))
|
||||||
type = iter->type;
|
type = iter->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Galaxy::setForm(const std::string& customTmpName)
|
||||||
|
{
|
||||||
if (!formsInitialized)
|
if (!formsInitialized)
|
||||||
InitializeForms();
|
initializeForms();
|
||||||
|
|
||||||
if (customTmpName != nullptr)
|
if (customTmpName.empty())
|
||||||
{
|
{
|
||||||
form = buildGalacticForms(fs::path("models") / *customTmpName);
|
form = static_cast<std::size_t>(type);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (type)
|
form = customForm(fs::path("models") / customTmpName);
|
||||||
{
|
|
||||||
case S0:
|
|
||||||
case Sa:
|
|
||||||
case Sb:
|
|
||||||
case Sc:
|
|
||||||
case SBa:
|
|
||||||
case SBb:
|
|
||||||
case SBc:
|
|
||||||
form = spiralForms[type - S0];
|
|
||||||
break;
|
|
||||||
case E0:
|
|
||||||
case E1:
|
|
||||||
case E2:
|
|
||||||
case E3:
|
|
||||||
case E4:
|
|
||||||
case E5:
|
|
||||||
case E6:
|
|
||||||
case E7:
|
|
||||||
form = ellipticalForms[type - E0];
|
|
||||||
//form = nullptr;
|
|
||||||
break;
|
|
||||||
case Irr:
|
|
||||||
form = irregularForm;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,11 +396,6 @@ std::string Galaxy::getDescription() const
|
||||||
return fmt::sprintf(_("Galaxy (Hubble type: %s)"), getType());
|
return fmt::sprintf(_("Galaxy (Hubble type: %s)"), getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
GalacticForm* Galaxy::getForm() const
|
|
||||||
{
|
|
||||||
return form;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* Galaxy::getObjTypeName() const
|
const char* Galaxy::getObjTypeName() const
|
||||||
{
|
{
|
||||||
return "galaxy";
|
return "galaxy";
|
||||||
|
@ -436,19 +405,20 @@ bool Galaxy::pick(const Eigen::ParametrizedLine<double, 3>& ray,
|
||||||
double& distanceToPicker,
|
double& distanceToPicker,
|
||||||
double& cosAngleToBoundCenter) const
|
double& cosAngleToBoundCenter) const
|
||||||
{
|
{
|
||||||
if (form == nullptr)
|
if (!galacticForms[form].has_value() || !isVisible())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!isVisible())
|
GalacticForm& galacticForm = *galacticForms[form];
|
||||||
return false;
|
|
||||||
|
|
||||||
// The ellipsoid should be slightly larger to compensate for the fact
|
// The ellipsoid should be slightly larger to compensate for the fact
|
||||||
// that blobs are considered points when galaxies are built, but have size
|
// that blobs are considered points when galaxies are built, but have size
|
||||||
// when they are drawn.
|
// when they are drawn.
|
||||||
float yscale = (type < E0 )? MAX_SPIRAL_THICKNESS: form->scale.y() + RADIUS_CORRECTION;
|
float yscale = (type > GalaxyType::Irr && type < GalaxyType::E0)
|
||||||
Eigen::Vector3d ellipsoidAxes(getRadius()*(form->scale.x() + RADIUS_CORRECTION),
|
? MAX_SPIRAL_THICKNESS
|
||||||
|
: galacticForm.scale.y() + RADIUS_CORRECTION;
|
||||||
|
Eigen::Vector3d ellipsoidAxes(getRadius()*(galacticForm.scale.x() + RADIUS_CORRECTION),
|
||||||
getRadius()* yscale,
|
getRadius()* yscale,
|
||||||
getRadius()*(form->scale.z() + RADIUS_CORRECTION));
|
getRadius()*(galacticForm.scale.z() + RADIUS_CORRECTION));
|
||||||
|
|
||||||
Eigen::Matrix3d rotation = getOrientation().cast<double>().toRotationMatrix();
|
Eigen::Matrix3d rotation = getOrientation().cast<double>().toRotationMatrix();
|
||||||
return celmath::testIntersection(
|
return celmath::testIntersection(
|
||||||
|
@ -466,12 +436,12 @@ bool Galaxy::load(AssociativeArray* params, const fs::path& resPath)
|
||||||
setDetail(static_cast<float>(detail));
|
setDetail(static_cast<float>(detail));
|
||||||
|
|
||||||
std::string customTmpName;
|
std::string customTmpName;
|
||||||
if(params->getString("CustomTemplate", customTmpName))
|
params->getString("CustomTemplate", customTmpName);
|
||||||
setCustomTmpName(customTmpName);
|
|
||||||
|
|
||||||
std::string typeName;
|
std::string typeName;
|
||||||
params->getString("Type", typeName);
|
params->getString("Type", typeName);
|
||||||
setType(typeName);
|
setType(typeName);
|
||||||
|
setForm(customTmpName);
|
||||||
|
|
||||||
return DeepSkyObject::load(params, resPath);
|
return DeepSkyObject::load(params, resPath);
|
||||||
}
|
}
|
||||||
|
@ -480,29 +450,14 @@ void Galaxy::render(const Eigen::Vector3f& offset,
|
||||||
const Eigen::Quaternionf& viewerOrientation,
|
const Eigen::Quaternionf& viewerOrientation,
|
||||||
float brightness,
|
float brightness,
|
||||||
float pixelSize,
|
float pixelSize,
|
||||||
const Matrices& m,
|
const Matrices& ms,
|
||||||
Renderer* renderer)
|
Renderer* renderer)
|
||||||
{
|
{
|
||||||
if (form == nullptr)
|
if (!galacticForms[form].has_value())
|
||||||
{
|
|
||||||
//renderGalaxyEllipsoid(offset, viewerOrientation, brightness, pixelSize);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
renderGalaxyPointSprites(offset, viewerOrientation, brightness, pixelSize, m, renderer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Galaxy::renderGalaxyPointSprites(const Eigen::Vector3f& offset,
|
|
||||||
const Eigen::Quaternionf& viewerOrientation,
|
|
||||||
float brightness,
|
|
||||||
float pixelSize,
|
|
||||||
const Matrices& ms,
|
|
||||||
Renderer* renderer)
|
|
||||||
{
|
|
||||||
if (form == nullptr)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const GalacticForm& galacticForm = *galacticForms[form];
|
||||||
|
|
||||||
/* We'll first see if the galaxy's apparent size is big enough to
|
/* We'll first see if the galaxy's apparent size is big enough to
|
||||||
be noticeable on screen; if it's not we'll break right here,
|
be noticeable on screen; if it's not we'll break right here,
|
||||||
avoiding all the overhead of the matrix transformations and
|
avoiding all the overhead of the matrix transformations and
|
||||||
|
@ -524,7 +479,7 @@ void Galaxy::renderGalaxyPointSprites(const Eigen::Vector3f& offset,
|
||||||
if (galaxyTex == nullptr)
|
if (galaxyTex == nullptr)
|
||||||
{
|
{
|
||||||
galaxyTex = CreateProceduralTexture(width, height, celestia::PixelFormat::RGBA,
|
galaxyTex = CreateProceduralTexture(width, height, celestia::PixelFormat::RGBA,
|
||||||
GalaxyTextureEval);
|
galaxyTextureEval);
|
||||||
}
|
}
|
||||||
assert(galaxyTex != nullptr);
|
assert(galaxyTex != nullptr);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
@ -533,7 +488,7 @@ void Galaxy::renderGalaxyPointSprites(const Eigen::Vector3f& offset,
|
||||||
if (colorTex == nullptr)
|
if (colorTex == nullptr)
|
||||||
{
|
{
|
||||||
colorTex = CreateProceduralTexture(256, 1, celestia::PixelFormat::RGBA,
|
colorTex = CreateProceduralTexture(256, 1, celestia::PixelFormat::RGBA,
|
||||||
ColorTextureEval,
|
colorTextureEval,
|
||||||
Texture::EdgeClamp,
|
Texture::EdgeClamp,
|
||||||
Texture::NoMipMaps);
|
Texture::NoMipMaps);
|
||||||
}
|
}
|
||||||
|
@ -552,7 +507,7 @@ void Galaxy::renderGalaxyPointSprites(const Eigen::Vector3f& offset,
|
||||||
v3.head(3) = viewMat * Eigen::Vector3f(-1, 1, 0) * size;
|
v3.head(3) = viewMat * Eigen::Vector3f(-1, 1, 0) * size;
|
||||||
|
|
||||||
Eigen::Quaternionf orientation = getOrientation().conjugate();
|
Eigen::Quaternionf orientation = getOrientation().conjugate();
|
||||||
Eigen::Matrix3f mScale = form->scale.asDiagonal() * size;
|
Eigen::Matrix3f mScale = galacticForm.scale.asDiagonal() * size;
|
||||||
Eigen::Matrix3f mLinear = orientation.toRotationMatrix() * mScale;
|
Eigen::Matrix3f mLinear = orientation.toRotationMatrix() * mScale;
|
||||||
|
|
||||||
Eigen::Matrix4f m = Eigen::Matrix4f::Identity();
|
Eigen::Matrix4f m = Eigen::Matrix4f::Identity();
|
||||||
|
@ -561,21 +516,21 @@ void Galaxy::renderGalaxyPointSprites(const Eigen::Vector3f& offset,
|
||||||
|
|
||||||
int pow2 = 1;
|
int pow2 = 1;
|
||||||
|
|
||||||
BlobVector* points = form->blobs;
|
const BlobVector& points = galacticForm.blobs;
|
||||||
unsigned int nPoints = static_cast<unsigned int>(points->size() * std::clamp(getDetail(), 0.0f, 1.0f));
|
unsigned int nPoints = static_cast<unsigned int>(points.size() * std::clamp(getDetail(), 0.0f, 1.0f));
|
||||||
// corrections to avoid excessive brightening if viewed e.g. edge-on
|
// corrections to avoid excessive brightening if viewed e.g. edge-on
|
||||||
|
|
||||||
float brightness_corr = 1.0f;
|
float brightness_corr = 1.0f;
|
||||||
float cosi;
|
float cosi;
|
||||||
|
|
||||||
if (type < E0 || type > E3) //all galaxies, except ~round elliptics
|
if (type < GalaxyType::E0 || type > GalaxyType::E3) //all galaxies, except ~round elliptics
|
||||||
{
|
{
|
||||||
cosi = (orientation * Eigen::Vector3f::UnitY()).dot(offset) / offset.norm();
|
cosi = (orientation * Eigen::Vector3f::UnitY()).dot(offset) / offset.norm();
|
||||||
brightness_corr = std::sqrt(std::abs(cosi));
|
brightness_corr = std::sqrt(std::abs(cosi));
|
||||||
if (brightness_corr < 0.2f)
|
if (brightness_corr < 0.2f)
|
||||||
brightness_corr = 0.2f;
|
brightness_corr = 0.2f;
|
||||||
}
|
}
|
||||||
if (type > E3) // only elliptics with higher ellipticities
|
if (type > GalaxyType::E3) // only elliptics with higher ellipticities
|
||||||
{
|
{
|
||||||
cosi = (orientation * Eigen::Vector3f::UnitX()).dot(offset) / offset.norm();
|
cosi = (orientation * Eigen::Vector3f::UnitX()).dot(offset) / offset.norm();
|
||||||
brightness_corr = brightness_corr * std::abs(cosi);
|
brightness_corr = brightness_corr * std::abs(cosi);
|
||||||
|
@ -585,7 +540,7 @@ void Galaxy::renderGalaxyPointSprites(const Eigen::Vector3f& offset,
|
||||||
|
|
||||||
Eigen::Matrix4f mv = vecgl::translate(*ms.modelview, Eigen::Vector3f(-offset));
|
Eigen::Matrix4f mv = vecgl::translate(*ms.modelview, Eigen::Vector3f(-offset));
|
||||||
|
|
||||||
const float btot = ((type > SBc) && (type < Irr)) ? 2.5f : 5.0f;
|
const float btot = (type == GalaxyType::Irr || type >= GalaxyType::E0) ? 2.5f : 5.0f;
|
||||||
const float spriteScaleFactor = 1.0f / 1.55f;
|
const float spriteScaleFactor = 1.0f / 1.55f;
|
||||||
|
|
||||||
glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
|
glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
|
||||||
|
@ -618,7 +573,7 @@ void Galaxy::renderGalaxyPointSprites(const Eigen::Vector3f& offset,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Blob& b = (*points)[i];
|
const Blob& b = points[i];
|
||||||
Eigen::Vector4f p = m * b.position;
|
Eigen::Vector4f p = m * b.position;
|
||||||
float br = b.brightness / 255.0f;
|
float br = b.brightness / 255.0f;
|
||||||
|
|
||||||
|
@ -693,7 +648,7 @@ void Galaxy::setLightGain(float lg)
|
||||||
lightGain = std::clamp(lg, 0.0f, 1.0f);
|
lightGain = std::clamp(lg, 0.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& s, const Galaxy::GalaxyType& sc)
|
std::ostream& operator<<(std::ostream& s, const GalaxyType& sc)
|
||||||
{
|
{
|
||||||
return s << GalaxyTypeNames[static_cast<std::size_t>(sc)].name;
|
return s << GalaxyTypeNames[static_cast<std::size_t>(sc)].name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <cstddef>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <Eigen/Core>
|
#include <Eigen/Core>
|
||||||
|
@ -25,7 +26,25 @@ struct Matrices;
|
||||||
class Renderer;
|
class Renderer;
|
||||||
|
|
||||||
|
|
||||||
class GalacticForm;
|
enum class GalaxyType {
|
||||||
|
Irr = 0,
|
||||||
|
S0 = 1,
|
||||||
|
Sa = 2,
|
||||||
|
Sb = 3,
|
||||||
|
Sc = 4,
|
||||||
|
SBa = 5,
|
||||||
|
SBb = 6,
|
||||||
|
SBc = 7,
|
||||||
|
E0 = 8,
|
||||||
|
E1 = 9,
|
||||||
|
E2 = 10,
|
||||||
|
E3 = 11,
|
||||||
|
E4 = 12,
|
||||||
|
E5 = 13,
|
||||||
|
E6 = 14,
|
||||||
|
E7 = 15,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class Galaxy : public DeepSkyObject
|
class Galaxy : public DeepSkyObject
|
||||||
{
|
{
|
||||||
|
@ -33,8 +52,6 @@ class Galaxy : public DeepSkyObject
|
||||||
const char* getType() const override;
|
const char* getType() const override;
|
||||||
void setType(const std::string&) override;
|
void setType(const std::string&) override;
|
||||||
std::string getDescription() const override;
|
std::string getDescription() const override;
|
||||||
std::string getCustomTmpName() const;
|
|
||||||
void setCustomTmpName(const std::string&);
|
|
||||||
|
|
||||||
float getDetail() const;
|
float getDetail() const;
|
||||||
void setDetail(float);
|
void setDetail(float);
|
||||||
|
@ -50,8 +67,6 @@ class Galaxy : public DeepSkyObject
|
||||||
const Matrices& m,
|
const Matrices& m,
|
||||||
Renderer* r) override;
|
Renderer* r) override;
|
||||||
|
|
||||||
GalacticForm* getForm() const;
|
|
||||||
|
|
||||||
static void increaseLightGain();
|
static void increaseLightGain();
|
||||||
static void decreaseLightGain();
|
static void decreaseLightGain();
|
||||||
static float getLightGain();
|
static float getLightGain();
|
||||||
|
@ -62,38 +77,12 @@ class Galaxy : public DeepSkyObject
|
||||||
|
|
||||||
const char* getObjTypeName() const override;
|
const char* getObjTypeName() const override;
|
||||||
|
|
||||||
public:
|
|
||||||
enum GalaxyType {
|
|
||||||
S0 = 0,
|
|
||||||
Sa = 1,
|
|
||||||
Sb = 2,
|
|
||||||
Sc = 3,
|
|
||||||
SBa = 4,
|
|
||||||
SBb = 5,
|
|
||||||
SBc = 6,
|
|
||||||
E0 = 7,
|
|
||||||
E1 = 8,
|
|
||||||
E2 = 9,
|
|
||||||
E3 = 10,
|
|
||||||
E4 = 11,
|
|
||||||
E5 = 12,
|
|
||||||
E6 = 13,
|
|
||||||
E7 = 14,
|
|
||||||
Irr = 15
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void renderGalaxyPointSprites(const Eigen::Vector3f& offset,
|
void setForm(const std::string&);
|
||||||
const Eigen::Quaternionf& viewerOrientation,
|
|
||||||
float brightness,
|
|
||||||
float pixelSize,
|
|
||||||
const Matrices& mvp,
|
|
||||||
Renderer* r);
|
|
||||||
|
|
||||||
float detail{ 1.0f };
|
float detail{ 1.0f };
|
||||||
std::string* customTmpName{ nullptr };
|
GalaxyType type{ GalaxyType::Irr };
|
||||||
GalaxyType type{ S0 };
|
std::size_t form{ 0 };
|
||||||
GalacticForm* form{ nullptr };
|
|
||||||
|
|
||||||
static float lightGain;
|
static float lightGain;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue