mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-06 19:50:03 -06:00
KDTree refactor and some star render tweaks
Co-Authored-By: Wilhelm Björkström <143391787+Grantallkotten@users.noreply.github.com>
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
#include <queue>
|
||||
|
||||
namespace {
|
||||
glm::vec3 cartesianToSpherical(const glm::vec3& cartesian) {
|
||||
glm::vec3 cartesianToSpherical(glm::vec3 const& cartesian) {
|
||||
float radius = glm::length(cartesian);
|
||||
float theta = std::atan2(glm::sqrt(cartesian.x * cartesian.x + cartesian.y * cartesian.y), cartesian.z);
|
||||
float phi = std::atan2(cartesian.y, cartesian.x);
|
||||
@@ -15,17 +15,25 @@ namespace {
|
||||
}
|
||||
}
|
||||
namespace openspace {
|
||||
void KDTree::build(std::string const& filePath, glm::vec3 const& origin) {
|
||||
KDTree::KDTree(std::string const& filePath, glm::vec3 const& localWorldCenter, float const renderDistance) {
|
||||
build(filePath, localWorldCenter, renderDistance);
|
||||
}
|
||||
|
||||
void KDTree::build(std::string const& filePath, glm::vec3 const& localWorldCenter, float const renderDistance)
|
||||
{
|
||||
std::vector<Node> tree{};
|
||||
const std::filesystem::path file{ absPath(filePath) };
|
||||
dataloader::Dataset dataset = dataloader::data::loadFileWithCache(file);
|
||||
|
||||
|
||||
|
||||
#pragma omp parallel for
|
||||
for (size_t i = 0; i < dataset.entries.size(); ++i) {
|
||||
dataset.entries[i].position = cartesianToSpherical(dataset.entries[i].position - origin);
|
||||
for (auto& entry : dataset.entries) {
|
||||
entry.position = cartesianToSpherical(entry.position - localWorldCenter);
|
||||
}
|
||||
|
||||
std::erase_if(dataset.entries, [renderDistance](const dataloader::Dataset::Entry& e) {
|
||||
return e.position.x > renderDistance;
|
||||
});
|
||||
|
||||
size_t numberOfStars = dataset.entries.size();
|
||||
tree.resize(numberOfStars);
|
||||
@@ -45,7 +53,6 @@ namespace openspace {
|
||||
if (node.start >= node.end) continue;
|
||||
|
||||
int axis = node.depth % 2 + 1;
|
||||
|
||||
auto comparetor = [axis](dataloader::Dataset::Entry const& a, dataloader::Dataset::Entry const& b) -> bool {
|
||||
return a.position[axis] < b.position[axis];
|
||||
};
|
||||
@@ -56,10 +63,9 @@ namespace openspace {
|
||||
dataset.entries.begin() + node.end,
|
||||
comparetor
|
||||
);
|
||||
|
||||
size_t medianIndex{ (node.start + node.end) / 2 };
|
||||
dataloader::Dataset::Entry const& entry{ dataset.entries[medianIndex] };
|
||||
|
||||
dataloader::Dataset::Entry const& entry{ dataset.entries[medianIndex] };
|
||||
glm::vec3 const& position{ entry.position };
|
||||
float const color{ entry.data[0] };
|
||||
float const lum{ entry.data[1] };
|
||||
@@ -68,19 +74,18 @@ namespace openspace {
|
||||
if (node.index >= tree.size()) {
|
||||
tree.resize(std::max(tree.size() * 2, node.index + 1));
|
||||
}
|
||||
|
||||
tree.emplace(
|
||||
tree.begin() + node.index, position, color, lum, absMag
|
||||
);
|
||||
|
||||
|
||||
// Enqueue left and right children
|
||||
q.emplace(2 * node.index + 1, node.depth + 1, node.start, medianIndex);
|
||||
q.emplace(2 * node.index + 2, node.depth + 1, medianIndex + 1, node.end);
|
||||
}
|
||||
flatTree = flattenTree(tree);
|
||||
}
|
||||
|
||||
std::vector<float> KDTree::flatTree() const {
|
||||
std::vector<float> KDTree::flattenTree(std::vector<Node> const& tree) const {
|
||||
std::vector<float> flatData;
|
||||
flatData.resize(tree.size() * 6);
|
||||
|
||||
|
||||
@@ -3,28 +3,37 @@
|
||||
#include <glm/glm.hpp>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <limits>
|
||||
|
||||
namespace openspace {
|
||||
namespace kdtree{}
|
||||
namespace kdtree {}
|
||||
class KDTree {
|
||||
public:
|
||||
KDTree() {};
|
||||
|
||||
size_t size() { return tree.size() * 6; };
|
||||
KDTree(std::string const& filePath, glm::vec3 const& localWorldCenter, float const renderDistance = std::numeric_limits<float>::max());
|
||||
|
||||
void build(std::string const& filePath, glm::vec3 const & origin);
|
||||
size_t size() { return flatTree.size(); };
|
||||
|
||||
std::vector<float> flatTree() const;
|
||||
void* data() {
|
||||
return flatTree.data();
|
||||
}
|
||||
|
||||
void build(
|
||||
std::string const& constfilePath,
|
||||
glm::vec3 const& localWorldCenter,
|
||||
float const renderDistance = std::numeric_limits<float>::max()
|
||||
);
|
||||
|
||||
private:
|
||||
struct Node {
|
||||
glm::fvec3 position;
|
||||
float color;
|
||||
float lum;
|
||||
float absMag;
|
||||
glm::fvec3 position{};
|
||||
float color{};
|
||||
float lum{};
|
||||
float absMag{};
|
||||
};
|
||||
|
||||
std::vector<Node> tree{};
|
||||
std::vector<float> flattenTree(std::vector<Node> const& tree) const;
|
||||
std::vector<float> flatTree{};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -113,8 +113,7 @@ namespace openspace {
|
||||
|
||||
void RenderableBlackHole::update(const UpdateData& data) {
|
||||
if (data.modelTransform.translation != _lastTranslation) {
|
||||
_starKDTree.build("${BASE}/sync/http/stars_du/6/stars.speck", data.modelTransform.translation);
|
||||
flatDataStar = _starKDTree.flatTree();
|
||||
_starKDTree.build("${BASE}/sync/http/stars_du/6/stars.speck", data.modelTransform.translation, 100.0f);
|
||||
_lastTranslation = data.modelTransform.translation;
|
||||
}
|
||||
|
||||
@@ -122,7 +121,7 @@ namespace openspace {
|
||||
|
||||
glm::vec3 cameraPosition = global::navigationHandler->camera()->positionVec3();
|
||||
glm::vec3 anchorNodePosition = global::navigationHandler->anchorNode()->position();
|
||||
float distanceToAnchor = (float)glm::distance(cameraPosition, anchorNodePosition) / distanceconstants::LightYear;
|
||||
float distanceToAnchor = glm::distance(cameraPosition, anchorNodePosition) / static_cast<float>(distanceconstants::LightYear);
|
||||
if (abs(_rCamera - distanceToAnchor) > _rs * 0.01) {
|
||||
|
||||
_rCamera = distanceToAnchor;
|
||||
@@ -161,18 +160,20 @@ namespace openspace {
|
||||
);
|
||||
|
||||
// Calculate the camera planes rotation to make sure fisheye works correcly (dcm in sgct projection.cpp)
|
||||
glm::fmat4 invViewPlaneTranslationMatrix = glm::translate(glm::mat4(1.f), glm::vec3(renderData.camera.eyePositionVec3().x));
|
||||
glm::fmat4 viewMatrix = renderData.camera.viewMatrix();
|
||||
glm::fmat4 const CameraPlaneRotation = glm::inverse(viewMatrix * invViewPlaneTranslationMatrix);
|
||||
glm::mat4 invViewPlaneTranslationMatrix = glm::translate(
|
||||
glm::mat4(1.f), glm::vec3(static_cast<float>(renderData.camera.eyePositionVec3().x))
|
||||
);
|
||||
glm::mat4 viewMatrix = renderData.camera.viewMatrix();
|
||||
glm::mat4 const CameraPlaneRotation = glm::inverse(viewMatrix * invViewPlaneTranslationMatrix);
|
||||
|
||||
_program->setUniform(
|
||||
_uniformCache.cameraRotationMatrix,
|
||||
glm::fmat4(glm::mat4_cast(camRot.localRotation)) * CameraPlaneRotation
|
||||
glm::mat4(glm::mat4_cast(camRot.localRotation)) * CameraPlaneRotation
|
||||
);
|
||||
|
||||
_program->setUniform(
|
||||
_uniformCache.worldRotationMatrix,
|
||||
glm::fmat4(glm::mat4_cast(camRot.globalRotation))
|
||||
glm::mat4(glm::mat4_cast(camRot.globalRotation))
|
||||
);
|
||||
|
||||
drawQuad();
|
||||
@@ -201,12 +202,12 @@ namespace openspace {
|
||||
{
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, _ssboStarKDTree);
|
||||
|
||||
const size_t indexBufferSize = flatDataStar.size() * sizeof(float);
|
||||
const size_t indexBufferSize = _starKDTree.size() * sizeof(float);
|
||||
|
||||
glBufferData(
|
||||
GL_SHADER_STORAGE_BUFFER,
|
||||
indexBufferSize,
|
||||
flatDataStar.data(),
|
||||
_starKDTree.data(),
|
||||
GL_STREAM_DRAW
|
||||
);
|
||||
|
||||
|
||||
@@ -157,14 +157,13 @@ vec3 BVIndex2rgb(float color) {
|
||||
return texture(colorBVMap, st).rgb;
|
||||
}
|
||||
|
||||
const float ONE_PARSEC = 3.08567758e16; // 1 Parsec
|
||||
|
||||
float angularDist(vec2 a, vec2 b) {
|
||||
float dTheta = a.x - b.x;
|
||||
float dPhi = a.y - b.y;
|
||||
return sqrt(dTheta * dTheta + sin(a.x) * sin(b.x) * dPhi * dPhi);
|
||||
}
|
||||
|
||||
|
||||
vec4 searchNearestStar(vec3 sphericalCoords) {
|
||||
const int NODE_SIZE = 6;
|
||||
const int SIZE = starKDTree.length() / NODE_SIZE;
|
||||
@@ -172,21 +171,22 @@ vec4 searchNearestStar(vec3 sphericalCoords) {
|
||||
int nodeIndex = 0;
|
||||
int depth = 0;
|
||||
int axis = -1;
|
||||
const float starRadius = 0.0025f;
|
||||
const float starRadius = 0.007f;
|
||||
|
||||
while(index < SIZE && starKDTree[nodeIndex] > 0.0f){
|
||||
float distToStar = angularDist(sphericalCoords.yz, vec2(starKDTree[nodeIndex + 1], starKDTree[nodeIndex + 2]));
|
||||
if (distToStar < starRadius){
|
||||
float luminosity = pow(10.0f, 1.89f - 0.4f * starKDTree[nodeIndex + 4]);
|
||||
float alpha = starRadius / distToStar;
|
||||
float alpha = pow((starRadius-distToStar) / starRadius, 3.0f);
|
||||
|
||||
float observedDistance = starKDTree[nodeIndex];
|
||||
luminosity /= pow(observedDistance, 1.2f);
|
||||
luminosity /= pow(observedDistance, 1.1f);
|
||||
|
||||
// If luminosity is really really small then set it to a static low number.
|
||||
if (luminosity < LUM_LOWER_CAP) {
|
||||
luminosity = LUM_LOWER_CAP;
|
||||
}
|
||||
return vec4(BVIndex2rgb(starKDTree[nodeIndex + 3]), alpha) * luminosity;
|
||||
return vec4(BVIndex2rgb(starKDTree[nodeIndex + 3]), alpha * luminosity);
|
||||
}
|
||||
|
||||
|
||||
@@ -199,7 +199,7 @@ vec4 searchNearestStar(vec3 sphericalCoords) {
|
||||
nodeIndex = index * NODE_SIZE;
|
||||
depth += 1;
|
||||
}
|
||||
return vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
return vec4(0.0f);
|
||||
}
|
||||
|
||||
|
||||
@@ -252,7 +252,7 @@ Fragment getFragment() {
|
||||
vec4 texColor = texture(environmentTexture, uv);
|
||||
|
||||
vec4 starColor = searchNearestStar(vec3(0.0f, sphericalCoords.x, sphericalCoords.y));
|
||||
texColor = clamp(texColor + starColor, 0.f, 1.f);
|
||||
texColor = vec4((starColor.rgb * starColor.a) + (texColor.rgb * (1-starColor.a)), 1.0f);
|
||||
frag.color = texColor;
|
||||
return frag;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user