mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-04-28 23:09:32 -05:00
Merge branch 'master' into thesis/2018/dsn
# Conflicts: # ext/ghoul
This commit is contained in:
@@ -20,3 +20,9 @@
|
||||
[submodule "apps/OpenSpace/ext/sgct"]
|
||||
path = apps/OpenSpace/ext/sgct
|
||||
url = https://github.com/opensgct/sgct
|
||||
[submodule "modules/fitsfilereader/ext/CCfits"]
|
||||
path = modules/fitsfilereader/ext/CCfits
|
||||
url = https://github.com/OpenSpace/CCfits.git
|
||||
[submodule "modules/fitsfilereader/ext/cfitsio"]
|
||||
path = modules/fitsfilereader/ext/cfitsio
|
||||
url = https://github.com/OpenSpace/cfitsio.git
|
||||
|
||||
+4
-2
@@ -231,8 +231,10 @@ if (OPENSPACE_MODULE_WEBBROWSER AND CEF_ROOT)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${WEBBROWSER_MODULE_PATH}/cmake")
|
||||
include(webbrowser_helpers)
|
||||
|
||||
set_cef_targets("${CEF_ROOT}" OpenSpaceTest)
|
||||
run_cef_platform_config("${CEF_ROOT}" "${CEF_TARGET}" "${WEBBROWSER_MODULE_PATH}")
|
||||
if (TARGET OpenSpaceTest)
|
||||
set_cef_targets("${CEF_ROOT}" OpenSpaceTest)
|
||||
run_cef_platform_config("${CEF_ROOT}" "${CEF_TARGET}" "${WEBBROWSER_MODULE_PATH}")
|
||||
endif ()
|
||||
elseif (OPENSPACE_MODULE_WEBBROWSER)
|
||||
message(WARNING "Web configured to be included, but no CEF_ROOT was found, please try configuring CMake again.")
|
||||
endif ()
|
||||
|
||||
+13
-10
@@ -143,10 +143,10 @@ LONG WINAPI generateMiniDump(EXCEPTION_POINTERS* exceptionPointers) {
|
||||
dumpFile.c_str(),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_WRITE | FILE_SHARE_READ,
|
||||
0,
|
||||
nullptr,
|
||||
CREATE_ALWAYS,
|
||||
0,
|
||||
0
|
||||
nullptr
|
||||
);
|
||||
|
||||
MINIDUMP_EXCEPTION_INFORMATION exceptionParameter;
|
||||
@@ -358,13 +358,13 @@ void mainPreSyncFunc() {
|
||||
if (!state.isConnected) {
|
||||
// Joystick was added
|
||||
state.isConnected = true;
|
||||
state.name = SgctEngine->getJoystickName(i);
|
||||
state.name = sgct::Engine::getJoystickName(i);
|
||||
|
||||
std::fill(state.axes.begin(), state.axes.end(), 0.f);
|
||||
std::fill(state.buttons.begin(), state.buttons.end(), JoystickAction::Idle);
|
||||
}
|
||||
|
||||
const float* axes = SgctEngine->getJoystickAxes(i, &state.nAxes);
|
||||
const float* axes = sgct::Engine::getJoystickAxes(i, &state.nAxes);
|
||||
if (state.nAxes > JoystickInputState::MaxAxes) {
|
||||
LWARNING(fmt::format(
|
||||
"Joystick/Gamepad {} has {} axes, but only {} axes are supported. "
|
||||
@@ -375,7 +375,10 @@ void mainPreSyncFunc() {
|
||||
}
|
||||
std::memcpy(state.axes.data(), axes, state.nAxes * sizeof(float));
|
||||
|
||||
const unsigned char* buttons = SgctEngine->getJoystickButtons(i, &state.nButtons);
|
||||
const unsigned char* buttons = sgct::Engine::getJoystickButtons(
|
||||
i,
|
||||
&state.nButtons
|
||||
);
|
||||
|
||||
if (state.nButtons > JoystickInputState::MaxButtons) {
|
||||
LWARNING(fmt::format(
|
||||
@@ -441,7 +444,7 @@ void mainRenderFunc() {
|
||||
LTRACE("main::mainRenderFunc(begin)");
|
||||
|
||||
glm::mat4 viewMatrix = SgctEngine->getCurrentViewMatrix() *
|
||||
glm::translate(glm::mat4(1.f), SgctEngine->getDefaultUserPtr()->getPos());
|
||||
glm::translate(glm::mat4(1.f), sgct::Engine::getDefaultUserPtr()->getPos());
|
||||
|
||||
glm::mat4 projectionMatrix = SgctEngine->getCurrentProjectionMatrix();
|
||||
#ifdef OPENVR_SUPPORT
|
||||
@@ -640,14 +643,14 @@ void setSgctDelegateFunctions() {
|
||||
sgctDelegate.mousePosition = []() {
|
||||
int id = sgct::Engine::instance()->getCurrentWindowPtr()->getId();
|
||||
double posX, posY;
|
||||
sgct::Engine::instance()->getMousePos(id, &posX, &posY);
|
||||
sgct::Engine::getMousePos(id, &posX, &posY);
|
||||
return glm::vec2(posX, posY);
|
||||
};
|
||||
sgctDelegate.mouseButtons = [](int maxNumber) {
|
||||
int id = sgct::Engine::instance()->getCurrentWindowPtr()->getId();
|
||||
uint32_t result = 0;
|
||||
for (int i = 0; i < maxNumber; ++i) {
|
||||
bool button = (sgct::Engine::instance()->getMouseButton(id, i) != 0);
|
||||
bool button = (sgct::Engine::getMouseButton(id, i) != 0);
|
||||
if (button) {
|
||||
result |= (1 << i);
|
||||
}
|
||||
@@ -739,10 +742,10 @@ void setSgctDelegateFunctions() {
|
||||
};
|
||||
sgctDelegate.isMaster = []() { return sgct::Engine::instance()->isMaster(); };
|
||||
sgctDelegate.isUsingSwapGroups = []() {
|
||||
return sgct::Engine::instance()->getCurrentWindowPtr()->isUsingSwapGroups();
|
||||
return sgct::SGCTWindow::isUsingSwapGroups();
|
||||
};
|
||||
sgctDelegate.isSwapGroupMaster = []() {
|
||||
return sgct::Engine::instance()->getCurrentWindowPtr()->isSwapGroupMaster();
|
||||
return sgct::SGCTWindow::isSwapGroupMaster();
|
||||
};
|
||||
sgctDelegate.viewProjectionMatrix = []() {
|
||||
return sgct::Engine::instance()->getCurrentModelViewProjectionMatrix();
|
||||
|
||||
@@ -68,6 +68,10 @@ local Keybindings = {
|
||||
|
||||
local earthAsset = asset.require('scene/solarsystem/planets/earth/earth')
|
||||
|
||||
assetHelper.registerInterestingNodes(asset, {
|
||||
"Earth", "Mars", "Moon", "Sun"
|
||||
})
|
||||
|
||||
asset.onInitialize(function ()
|
||||
local now = openspace.time.currentWallTime()
|
||||
-- Jump back one day to show a complete planet
|
||||
@@ -81,10 +85,6 @@ asset.onInitialize(function ()
|
||||
openspace.absPath("${DATA}/globebrowsing_servers.lua")
|
||||
)
|
||||
|
||||
openspace.markInterestingNodes({
|
||||
"Earth", "Mars", "Moon"
|
||||
})
|
||||
|
||||
openspace.addVirtualProperty(
|
||||
"BoolProperty",
|
||||
"Show Trails",
|
||||
@@ -108,8 +108,4 @@ asset.onDeinitialize(function ()
|
||||
sceneHelper.unbindKeys(Keybindings)
|
||||
|
||||
openspace.removeVirtualProperty("*Trail.Renderable.Enabled")
|
||||
|
||||
openspace.removeInterestingNodes({
|
||||
"Earth", "Mars", "Moon"
|
||||
})
|
||||
end)
|
||||
|
||||
@@ -11,7 +11,7 @@ asset.onInitialize(function ()
|
||||
helper.addSlide(deck, "${DATA}/test2.jpg")
|
||||
helper.addSlide(deck, "${DATA}/test3.jpg")
|
||||
|
||||
local interpolationDuration = 0
|
||||
local interpolationDuration = 0.5
|
||||
|
||||
function nextSlide()
|
||||
helper.goToNextSlide(deck, interpolationDuration)
|
||||
@@ -21,9 +21,14 @@ asset.onInitialize(function ()
|
||||
helper.goToPreviousSlide(deck, interpolationDuration)
|
||||
end
|
||||
|
||||
function toggleSlides()
|
||||
helper.toggleSlides(deck, interpolationDuration)
|
||||
end
|
||||
|
||||
helper.setCurrentSlide(deck, 1)
|
||||
openspace.bindKey("RIGHT", "nextSlide()")
|
||||
openspace.bindKey("LEFT", "previousSlide()")
|
||||
openspace.bindKey("RIGHT", "nextSlide()", "Next slide", "Next slide", "/Slides")
|
||||
openspace.bindKey("LEFT", "previousSlide()", "Previous slide", "Previous slide", "/Slides")
|
||||
openspace.bindKey("UP", "toggleSlides()", "Toggle slides", "Toggle slides", "/Slides")
|
||||
|
||||
end)
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
local has_gaia = openspace.modules.isLoaded('gaia')
|
||||
if not has_gaia then
|
||||
openspace.printFatal('Could not load scene "' .. asset.filePath .. '" due to missing module "gaia"')
|
||||
do return end
|
||||
end
|
||||
|
||||
local assetHelper = asset.require('util/asset_helper')
|
||||
|
||||
asset.require('default')
|
||||
|
||||
-- Augment default scene with gaia data, 3D model and trail
|
||||
asset.require('scene/milkyway/gaia/gaiastars')
|
||||
asset.require('scene/milkyway/gaia/apogee')
|
||||
asset.require('scene/milkyway/gaia/galah')
|
||||
asset.require('scene/solarsystem/missions/gaia/gaia')
|
||||
asset.require('scene/solarsystem/missions/gaia/trail')
|
||||
|
||||
assetHelper.registerDashboardItems(asset, {
|
||||
{
|
||||
Type = "DashboardItemDistance",
|
||||
Identifier = "GaiaEarthDistance",
|
||||
GuiName = "Gaia Earth Distance",
|
||||
SourceType = "Node",
|
||||
SourceNodeName = "Gaia",
|
||||
DestinationType = "Node Surface",
|
||||
DestinationNodeName = "Earth"
|
||||
}
|
||||
})
|
||||
|
||||
assetHelper.registerInterestingNodes(asset, { "Gaia" })
|
||||
|
||||
asset.onInitialize(function ()
|
||||
openspace.setPropertyValueSingle('Scene.Stars.Renderable.Enabled', false);
|
||||
|
||||
openspace.navigation.setCameraState({
|
||||
Focus = "Gaia",
|
||||
Position = { 1000000000000.0, 1000000000000.0, 1000000000000.0 },
|
||||
Rotation = { 0.683224, -0.765934, -0.601234, -0.418073 },
|
||||
})
|
||||
end)
|
||||
@@ -18,6 +18,10 @@ asset.require('util/webgui')
|
||||
|
||||
local junoAsset = asset.require('scene/solarsystem/missions/juno/juno')
|
||||
|
||||
assetHelper.registerInterestingNodes(asset, {
|
||||
"Jupiter", "Juno"
|
||||
})
|
||||
|
||||
asset.onInitialize(function ()
|
||||
openspace.time.setTime("2016-07-01T10:05:00.00")
|
||||
|
||||
@@ -28,10 +32,6 @@ asset.onInitialize(function ()
|
||||
28800, 57600, 115200, 230400, 460800, 921600, 1843200, 3686400, 7372800, 14745600
|
||||
})
|
||||
|
||||
openspace.markInterestingNodes({
|
||||
"Jupiter", "Juno"
|
||||
})
|
||||
|
||||
openspace.addVirtualProperty(
|
||||
"BoolProperty",
|
||||
"Show Trails",
|
||||
@@ -51,8 +51,4 @@ end)
|
||||
|
||||
asset.onDeinitialize(function ()
|
||||
openspace.removeVirtualProperty("*Trail.Renderable.Enabled")
|
||||
|
||||
openspace.removeInterestingNodes({
|
||||
"Jupiter", "Juno"
|
||||
})
|
||||
end)
|
||||
|
||||
@@ -37,6 +37,9 @@ assetHelper.registerDashboardItems(asset, {
|
||||
}
|
||||
})
|
||||
|
||||
assetHelper.registerInterestingNodes(asset, {
|
||||
"Mercury", "Messenger", "Earth", "Sun"
|
||||
})
|
||||
|
||||
asset.onInitialize(function ()
|
||||
|
||||
@@ -49,11 +52,7 @@ asset.onInitialize(function ()
|
||||
28800, 57600, 115200, 230400, 460800, 921600, 1843200, 3686400, 7372800, 14745600
|
||||
})
|
||||
|
||||
openspace.markInterestingNodes({
|
||||
"Mercury", "Messenger", "Earth", "Sun"
|
||||
})
|
||||
|
||||
openspace.addVirtualProperty(
|
||||
openspace.addVirtualProperty(
|
||||
"BoolProperty",
|
||||
"Show Trails",
|
||||
"Scene.*Trail.Renderable.Enabled",
|
||||
@@ -63,17 +62,9 @@ asset.onInitialize(function ()
|
||||
nil
|
||||
)
|
||||
|
||||
|
||||
openspace.navigation.setCameraState({
|
||||
Focus = "Mercury",
|
||||
Position = { 526781518487.171326, 257168309890.072144, -1381125204152.817383 },
|
||||
Rotation = {0.180662, 0.021334, 0.979084, 0.091111},
|
||||
})
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function ()
|
||||
openspace.removeInterestingNodes({
|
||||
"Mercury", "Messenger", "Earth", "Sun"
|
||||
})
|
||||
end)
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ asset.require('util/default_joystick')
|
||||
|
||||
asset.require('util/webgui')
|
||||
|
||||
asset.request('customization/globebrowsing')
|
||||
|
||||
-- Custom Keybindings
|
||||
local Keybindings = {
|
||||
{
|
||||
@@ -44,6 +46,18 @@ local Keybindings = {
|
||||
GuiPath = "/New Horizons",
|
||||
Local = false
|
||||
},
|
||||
{
|
||||
Key = "F7",
|
||||
Command =
|
||||
[[local enabled = openspace.getPropertyValue('Scene.Pluto.Renderable.ProjectionComponent.PerformProjection')
|
||||
openspace.setPropertyValue('Scene.Pluto.Renderable.ProjectionComponent.PerformProjection', not enabled)
|
||||
openspace.setPropertyValue('Scene.Charon.Renderable.ProjectionComponent.PerformProjection', not enabled)
|
||||
openspace.setPropertyValueSingle("Dashboard.NewHorizonsInstruments.Enabled", not enabled)]],
|
||||
Documentation = "Toggles New Horizons image projection.",
|
||||
Name = "Toggle NH Image Projection",
|
||||
GuiPath = "/New Horizons",
|
||||
Local = false
|
||||
},
|
||||
{
|
||||
Key = "F8",
|
||||
Command = "openspace.setPropertyValue('Scene.Pluto.Renderable.ProjectionComponent.ClearAllProjections', true);" ..
|
||||
@@ -65,7 +79,7 @@ local Keybindings = {
|
||||
},
|
||||
{
|
||||
Key = "KP_8",
|
||||
Command = propertyHelper.increment('Scene.Pluto.Renderable.HeightExaggeration', 5000000),
|
||||
Command = propertyHelper.increment('Scene.Pluto.Renderable.HeightExaggeration', 5000),
|
||||
Documentation = "Increases the height map exaggeration on Pluto.",
|
||||
Name = "Pluto HeightExaggeration +",
|
||||
GuiPath = "/New Horizons",
|
||||
@@ -73,7 +87,7 @@ local Keybindings = {
|
||||
},
|
||||
{
|
||||
Key = "KP_2",
|
||||
Command = propertyHelper.decrement('Scene.Pluto.Renderable.HeightExaggeration', 5000000),
|
||||
Command = propertyHelper.decrement('Scene.Pluto.Renderable.HeightExaggeration', 5000),
|
||||
Documentation = "Decreases the height map exaggeration on Pluto.",
|
||||
Name = "Pluto HeightExaggeration -",
|
||||
GuiPath = "/New Horizons",
|
||||
@@ -81,7 +95,7 @@ local Keybindings = {
|
||||
},
|
||||
{
|
||||
Key = "KP_9",
|
||||
Command = propertyHelper.increment('Scene.Charon.Renderable.HeightExaggeration', 5000000),
|
||||
Command = propertyHelper.increment('Scene.Charon.Renderable.HeightExaggeration', 5000),
|
||||
Documentation = "Increases the height map exaggeration on Charon.",
|
||||
Name = "Charon HeightExaggeration +",
|
||||
GuiPath = "/New Horizons",
|
||||
@@ -89,7 +103,7 @@ local Keybindings = {
|
||||
},
|
||||
{
|
||||
Key = "KP_3",
|
||||
Command = propertyHelper.decrement('Scene.Charon.Renderable.HeightExaggeration', 5000000),
|
||||
Command = propertyHelper.decrement('Scene.Charon.Renderable.HeightExaggeration', 5000),
|
||||
Documentation = "Decreases the height map exaggeration on Charon.",
|
||||
Name = "Charon HeightExaggeration -",
|
||||
GuiPath = "/New Horizons",
|
||||
@@ -140,13 +154,22 @@ local Keybindings = {
|
||||
Local = false
|
||||
},
|
||||
{
|
||||
Key = "t",
|
||||
Key = "Shift+t",
|
||||
Command = renderableHelper.toggle('Scene.PlutoShadow') .. renderableHelper.toggle('Scene.CharonShadow'),
|
||||
Documentation = "Toggles the visibility of the shadow visualization of Pluto and Charon.",
|
||||
Name = "Toggle Shadows",
|
||||
GuiPath = "/New Horizons",
|
||||
Local = false
|
||||
},
|
||||
{
|
||||
Key = "t",
|
||||
Command = renderableHelper.toggle('Scene.NewHorizonsTrailPluto'),
|
||||
Documentation = "Toggles the trail of New Horizons.",
|
||||
Name = "Toggle NH Trail",
|
||||
GuiPath = "/New Horizons",
|
||||
Local = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
local NewHorizonsAsset = asset.require('scene/solarsystem/missions/newhorizons/model')
|
||||
@@ -174,6 +197,10 @@ assetHelper.registerDashboardItems(asset, {
|
||||
}
|
||||
})
|
||||
|
||||
assetHelper.registerInterestingNodes(asset, {
|
||||
"Pluto", "NewHorizons", "Charon"
|
||||
})
|
||||
|
||||
asset.onInitialize(function ()
|
||||
openspace.time.setTime("2015-07-14T08:00:00.00")
|
||||
sceneHelper.bindKeys(Keybindings)
|
||||
@@ -185,10 +212,6 @@ asset.onInitialize(function ()
|
||||
2160, 4320, 8640
|
||||
})
|
||||
|
||||
openspace.markInterestingNodes({
|
||||
"Pluto", "NewHorizons", "Charon"
|
||||
})
|
||||
|
||||
openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.FollowFocusNodeRotationDistance', 20.000000);
|
||||
|
||||
openspace.addVirtualProperty(
|
||||
@@ -212,7 +235,4 @@ asset.onDeinitialize(function ()
|
||||
sceneHelper.unbindKeys(Keybindings)
|
||||
|
||||
openspace.removeVirtualProperty("*Trail.Renderable.Enabled")
|
||||
openspace.removeInterestingNodes({
|
||||
"Pluto", "NewHorizons", "Charon"
|
||||
})
|
||||
end)
|
||||
|
||||
@@ -19,6 +19,8 @@ asset.require('util/default_joystick')
|
||||
|
||||
asset.require('util/webgui')
|
||||
|
||||
asset.request('customization/globebrowsing')
|
||||
|
||||
-- Custom Keybindings
|
||||
local Keybindings = {
|
||||
{
|
||||
@@ -109,6 +111,10 @@ assetHelper.registerDashboardItems(asset, {
|
||||
}
|
||||
})
|
||||
|
||||
assetHelper.registerInterestingNodes(asset, {
|
||||
"67P", "Rosetta", "Philae"
|
||||
})
|
||||
|
||||
asset.onInitialize(function ()
|
||||
openspace.time.setTime("2014-08-01T03:05:00.000")
|
||||
sceneHelper.bindKeys(Keybindings)
|
||||
@@ -120,10 +126,6 @@ asset.onInitialize(function ()
|
||||
28800, 57600, 115200, 230400, 460800, 921600, 1843200, 3686400, 7372800, 14745600
|
||||
})
|
||||
|
||||
openspace.markInterestingNodes({
|
||||
"67P", "Rosetta", "Philae"
|
||||
})
|
||||
|
||||
openspace.addVirtualProperty(
|
||||
"BoolProperty",
|
||||
"Show Trails",
|
||||
@@ -147,7 +149,4 @@ asset.onDeinitialize(function ()
|
||||
sceneHelper.unbindKeys(Keybindings)
|
||||
|
||||
openspace.removeVirtualProperty("*Trail.Renderable.Enabled")
|
||||
openspace.removeInterestingNodes({
|
||||
"67PBarycenter", "Rosetta", "Philae"
|
||||
})
|
||||
end)
|
||||
|
||||
@@ -20,10 +20,10 @@ local colorLUT = asset.syncedResource({
|
||||
Name = "Stars Color Table",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "stars_colormap",
|
||||
Version = 1
|
||||
Version = 2
|
||||
})
|
||||
|
||||
local object = {
|
||||
local stars = {
|
||||
Identifier = "Stars",
|
||||
Renderable = {
|
||||
Type = "RenderableStars",
|
||||
@@ -36,6 +36,4 @@ local object = {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, { object })
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, { stars })
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
local assetHelper = asset.require('util/asset_helper')
|
||||
|
||||
|
||||
|
||||
local textures = asset.syncedResource({
|
||||
Name = "Stars Textures",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "stars_textures",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local speck = asset.syncedResource({
|
||||
Name = "Apogee Speck Files",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "gaia_apogee",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local colorLUT = asset.syncedResource({
|
||||
Name = "Stars Color Table",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "stars_colormap",
|
||||
Version = 2
|
||||
})
|
||||
|
||||
local gaia_abundance_apogee = {
|
||||
Identifier = "Gaia Abundance Apogee",
|
||||
Renderable = {
|
||||
Type = "RenderableStars",
|
||||
Enabled = false,
|
||||
File = speck .. "/GaiaAbundApogee.speck",
|
||||
ColorOption = "Other Data",
|
||||
OtherData = "FeH",
|
||||
ScaleFactor = 100,
|
||||
Texture = textures .. "/halo.png",
|
||||
ColorMap = colorLUT .. "/colorbv.cmap",
|
||||
OtherDataColorMap = colorLUT .. "/viridis.cmap",
|
||||
StaticFilter = -9999,
|
||||
StaticFilterReplacement = 0.0
|
||||
},
|
||||
GUI = {
|
||||
Path = "/Milky Way/Gaia"
|
||||
}
|
||||
}
|
||||
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, { gaia_abundance_apogee })
|
||||
@@ -0,0 +1,19 @@
|
||||
-- Download a dataset of 618 million stars (28 GB), already preprocessed and stored in a binary octree.
|
||||
-- The octree was generated from the full DR2 by filtering away all stars with a parallax error higher than 0.5
|
||||
-- Max Star Per Node = 50,000 and max distance = 500kpc
|
||||
asset.syncedResource({
|
||||
Name = "Gaia DR2 618M Octree",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "gaia_stars_618M_octree",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
-- Download the full DR2 dataset with 24 values per star (preprocessed with theReadFitsTask (gaia_read.task) into 8 binary files).
|
||||
-- From these files new subsets can be created with the ConstructOctreeTask (gaia_octree.task).
|
||||
-- Total size of download is 151 GB.
|
||||
asset.syncedResource({
|
||||
Name = "Gaia DR2 Full Raw",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "gaia_stars_dr2_raw",
|
||||
Version = 1
|
||||
})
|
||||
@@ -0,0 +1,60 @@
|
||||
local assetHelper = asset.require("util/asset_helper")
|
||||
|
||||
local textures = asset.syncedResource({
|
||||
Name = "Stars Textures",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "stars_textures",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local colorLUT = asset.syncedResource({
|
||||
Name = "Stars Color Table",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "stars_colormap",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
-- Download a preprocessed binary octree of Radial Velocity subset values per star (preprocessed into 8 binary files).
|
||||
local starsFolder = asset.syncedResource({
|
||||
Name = "Gaia Stars RV",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "gaia_stars_rv_octree",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local GaiaStars = {
|
||||
Identifier = "GaiaStars",
|
||||
Renderable = {
|
||||
Type = "RenderableGaiaStars",
|
||||
File = starsFolder .. "/",
|
||||
FileReaderOption = "StreamOctree",
|
||||
RenderOption = "Motion",
|
||||
ShaderOption = "Point_SSBO",
|
||||
Texture = textures .. "/halo.png",
|
||||
ColorMap = colorLUT .. "/colorbv.cmap",
|
||||
LuminosityMultiplier = 35,
|
||||
MagnitudeBoost = 25,
|
||||
CutOffThreshold = 38,
|
||||
BillboardSize = 1,
|
||||
CloseUpBoostDist = 250,
|
||||
Sharpness = 1.45,
|
||||
LodPixelThreshold = 0,
|
||||
MaxGpuMemoryPercent = 0.24,
|
||||
MaxCpuMemoryPercent = 0.4,
|
||||
FilterSize = 5,
|
||||
Sigma = 0.5,
|
||||
AdditionalNodes = {3.0, 2.0},
|
||||
FilterPosX = {0.0, 0.0},
|
||||
FilterPosY = {0.0, 0.0},
|
||||
FilterPosZ = {0.0, 0.0},
|
||||
FilterGMag = {20.0, 20.0},
|
||||
FilterBpRp = {0.0, 0.0},
|
||||
FilterDist = {9.0, 9.0},
|
||||
},
|
||||
GUI = {
|
||||
Name = "Gaia Stars",
|
||||
Path = "/Milky Way"
|
||||
}
|
||||
}
|
||||
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, { GaiaStars })
|
||||
@@ -0,0 +1,46 @@
|
||||
local assetHelper = asset.require('util/asset_helper')
|
||||
|
||||
|
||||
|
||||
local textures = asset.syncedResource({
|
||||
Name = "Stars Textures",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "stars_textures",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local speck = asset.syncedResource({
|
||||
Name = "Galah Speck Files",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "gaia_galah",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local colorLUT = asset.syncedResource({
|
||||
Name = "Stars Color Table",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "stars_colormap",
|
||||
Version = 2
|
||||
})
|
||||
|
||||
local gaia_abundance_galah = {
|
||||
Identifier = "Gaia Abundance Galah",
|
||||
Renderable = {
|
||||
Type = "RenderableStars",
|
||||
Enabled = false,
|
||||
File = speck .. "/GaiaAbundGalah.speck",
|
||||
Texture = textures .. "/halo.png",
|
||||
ColorOption = "Other Data",
|
||||
OtherData = "FeH",
|
||||
ScaleFactor = 100,
|
||||
ColorMap = colorLUT .. "/colorbv.cmap",
|
||||
OtherDataColorMap = colorLUT .. "/viridis.cmap",
|
||||
StaticFilter = -9999,
|
||||
StaticFilterReplacement = 0.0
|
||||
},
|
||||
GUI = {
|
||||
Path = "/Milky Way/Gaia"
|
||||
}
|
||||
}
|
||||
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, { gaia_abundance_galah })
|
||||
@@ -20,7 +20,7 @@ local colorLUT = asset.syncedResource({
|
||||
Name = "Stars Color Table",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "stars-denver_colormap",
|
||||
Version = 1
|
||||
Version = 2
|
||||
})
|
||||
|
||||
local object = {
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
local assetHelper = asset.require('util/asset_helper')
|
||||
local transforms = asset.require('./transforms')
|
||||
local sunTransforms = asset.require('scene/solarsystem/sun/transforms')
|
||||
|
||||
|
||||
local textures = asset.syncedResource({
|
||||
Name = "Gaia Textures",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "gaia_textures",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local model = asset.syncedResource({
|
||||
Name = "Gaia Model",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "gaia_model",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
|
||||
local Gaia = {
|
||||
Identifier = "Gaia",
|
||||
Parent = transforms.GaiaPosition.Identifier,
|
||||
Transform = {
|
||||
Rotation = {
|
||||
Type = "FixedRotation",
|
||||
Attached = "Gaia",
|
||||
XAxis = { 1.0, 0.0, 0.0 },
|
||||
XAxisOrthogonal = true,
|
||||
YAxis = "Sun",
|
||||
YAxisInverted = true
|
||||
},
|
||||
Scale = {
|
||||
Type = "StaticScale",
|
||||
Scale = 10.0
|
||||
}
|
||||
},
|
||||
-- X Orthogonal
|
||||
Renderable = {
|
||||
Type = "RenderableModel",
|
||||
Body = "GAIA",
|
||||
Geometry = {
|
||||
Type = "MultiModelGeometry",
|
||||
GeometryFile = model .. "/gaia.obj"
|
||||
},
|
||||
ColorTexture = textures .. "/gaia-baked.png",
|
||||
LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 0.3
|
||||
},
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.4
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Gaia",
|
||||
Path = "/Solar System/Missions/Gaia"
|
||||
}
|
||||
}
|
||||
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, { Gaia })
|
||||
@@ -0,0 +1,64 @@
|
||||
local assetHelper = asset.require('util/asset_helper')
|
||||
local earthTransforms = asset.require('scene/solarsystem/planets/earth/transforms')
|
||||
local sunTransforms = asset.require('scene/solarsystem/sun/transforms')
|
||||
|
||||
local trail = asset.syncedResource({
|
||||
Name = "Gaia Trail",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "gaia_trail",
|
||||
Version = 2
|
||||
})
|
||||
|
||||
local GaiaTrail = {
|
||||
Identifier = "GaiaTrail",
|
||||
Parent = earthTransforms.EarthBarycenter.Identifier,
|
||||
Renderable = {
|
||||
Type = "RenderableTrailTrajectory",
|
||||
Enabled = false,
|
||||
Translation = {
|
||||
Type = "HorizonsTranslation",
|
||||
HorizonsTextFile = trail .. "/gaia_orbit_horizons.dat"
|
||||
},
|
||||
Color = { 0.0, 0.8, 0.7 },
|
||||
ShowFullTrail = false,
|
||||
StartTime = "2013 DEC 19 09:55:10",
|
||||
EndTime = "2019 JUN 20 05:55:10",
|
||||
PointSize = 5,
|
||||
SampleInterval = 12000,
|
||||
TimeStampSubsampleFactor = 1,
|
||||
EnableFade = false,
|
||||
Rendering = "Lines"
|
||||
},
|
||||
GUI = {
|
||||
Name = "Gaia Trail",
|
||||
Path = "/Solar System/Missions/Gaia"
|
||||
}
|
||||
}
|
||||
|
||||
local GaiaTrailEclip = {
|
||||
Identifier = "GaiaTrail_Eclip",
|
||||
Parent = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Renderable = {
|
||||
Type = "RenderableTrailTrajectory",
|
||||
Enabled = false,
|
||||
Translation = {
|
||||
Type = "HorizonsTranslation",
|
||||
HorizonsTextFile = trail .. "/gaia_orbit_horizons_sun.dat"
|
||||
},
|
||||
Color = { 1.0, 0.0, 0.0 },
|
||||
ShowFullTrail = false,
|
||||
StartTime = "2013 DEC 19 09:55:10",
|
||||
EndTime = "2019 JUN 20 05:55:10",
|
||||
PointSize = 5,
|
||||
SampleInterval = 6000,
|
||||
TimeStampSubsampleFactor = 1,
|
||||
EnableFade = false,
|
||||
Rendering = "Lines"
|
||||
},
|
||||
GUI = {
|
||||
Name = "Gaia Ecliptic Trail",
|
||||
Path = "/Solar System/Missions/Gaia"
|
||||
}
|
||||
}
|
||||
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, { GaiaTrail, GaiaTrailEclip } )
|
||||
@@ -0,0 +1,27 @@
|
||||
local assetHelper = asset.require('util/asset_helper')
|
||||
local earthTransforms = asset.require('scene/solarsystem/planets/earth/transforms')
|
||||
|
||||
|
||||
local trail = asset.syncedResource({
|
||||
Name = "Gaia Trail",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "gaia_trail",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local GaiaPosition = {
|
||||
Identifier = "GaiaPosition",
|
||||
Parent = earthTransforms.EarthBarycenter.Identifier,
|
||||
Transform = {
|
||||
Translation = {
|
||||
Type = "HorizonsTranslation",
|
||||
HorizonsTextFile = trail .. "/gaia_orbit_horizons.dat"
|
||||
},
|
||||
},
|
||||
GUI = {
|
||||
Name = "Position",
|
||||
Path = "/Solar System/Missions/Gaia"
|
||||
}
|
||||
}
|
||||
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, { GaiaPosition })
|
||||
@@ -5,6 +5,8 @@ asset.request('./trail')
|
||||
local kernel = asset.require('../kernels').jup310
|
||||
|
||||
|
||||
local map_service_configs = asset.localResource("map_service_configs")
|
||||
|
||||
|
||||
local textures = asset.syncedResource({
|
||||
Name = "Europa Textures",
|
||||
@@ -39,8 +41,15 @@ local Europa = {
|
||||
{
|
||||
Identifier = "Texture",
|
||||
FilePath = textures .. "/europa.jpg",
|
||||
-- Enabled = true
|
||||
},
|
||||
{
|
||||
Identifier = "Voyager_Global_Mosaic",
|
||||
Name = "Voyager Global Mosaic [Sweden]",
|
||||
FilePath = map_service_configs .. "/LiU/Voyager_GalileoSSI_global_mosaic_500m.wms",
|
||||
BlendMode = "Color",
|
||||
Enabled = true
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<GDAL_WMS>
|
||||
<Service name="TMS">
|
||||
<ServerUrl>http://wms.itn.liu.se/Europa/Voyager_GalileoSSI_global_mosaic_500m/tile/${z}/${y}/${x}</ServerUrl>
|
||||
</Service>
|
||||
<DataWindow>
|
||||
<UpperLeftX>-180.0</UpperLeftX>
|
||||
<UpperLeftY>90.0</UpperLeftY>
|
||||
<LowerRightX>180.0</LowerRightX>
|
||||
<LowerRightY>-90.0</LowerRightY>
|
||||
<SizeX>19631</SizeX>
|
||||
<SizeY>9816</SizeY>
|
||||
<TileLevel>7</TileLevel>
|
||||
<YOrigin>top</YOrigin>
|
||||
</DataWindow>
|
||||
<Projection>EPSG:4326</Projection>
|
||||
<BlockSizeX>256</BlockSizeX>
|
||||
<BlockSizeY>256</BlockSizeY>
|
||||
<BandsCount>1</BandsCount>
|
||||
<MaxConnections>10</MaxConnections>
|
||||
</GDAL_WMS>
|
||||
+4
-3
@@ -10,12 +10,13 @@
|
||||
<SizeX>46080</SizeX>
|
||||
<SizeY>23040</SizeY>
|
||||
<TileLevel>6</TileLevel>
|
||||
<YOrigin>bottom</YOrigin>
|
||||
<YOrigin>top</YOrigin>
|
||||
</DataWindow>
|
||||
<DataType>Int16</DataType>
|
||||
<Projection>GEOGCS["GCS_Mars_2000_Sphere",DATUM["D_Mars_2000_Sphere",SPHEROID["Mars_2000_Sphere_IAU_IAG",3396190.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]</Projection>
|
||||
<BlockSizeX>256</BlockSizeX>
|
||||
<BlockSizeY>256</BlockSizeY>
|
||||
<BlockSizeX>360</BlockSizeX>
|
||||
<BlockSizeY>360</BlockSizeY>
|
||||
<BandsCount>1</BandsCount>
|
||||
<MaxConnections>10</MaxConnections>
|
||||
<Timeout>5</Timeout>
|
||||
</GDAL_WMS>
|
||||
|
||||
@@ -12,6 +12,8 @@ local textures = asset.syncedResource({
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local mapServiceConfigsPath = asset.localResource("map_service_configs")
|
||||
|
||||
local Enceladus = {
|
||||
Identifier = "Enceladus",
|
||||
Parent = transforms.SaturnBarycenter.Identifier,
|
||||
@@ -37,8 +39,13 @@ local Enceladus = {
|
||||
{
|
||||
Identifier = "Texture",
|
||||
FilePath = textures .. "/enceladus.jpg",
|
||||
Enabled = true
|
||||
}
|
||||
},
|
||||
{
|
||||
Identifier = "Global_Mosaic_100m_HPF",
|
||||
Name = "Cassini Global Mosaic 100m HPF",
|
||||
FilePath = mapServiceConfigsPath .. "/Cassini_ISS_Global_Mosaic_100m_HPF.wms",
|
||||
Enabled = true,
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<GDAL_WMS>
|
||||
<Service name="TMS">
|
||||
<ServerUrl>http://wms.itn.liu.se/Enceladus/Cassini_ISS_Global_Mosaic_100m_HPF/tile/${z}/${y}/${x}</ServerUrl>
|
||||
</Service>
|
||||
<DataWindow>
|
||||
<UpperLeftX>-180.0</UpperLeftX>
|
||||
<UpperLeftY>90.0</UpperLeftY>
|
||||
<LowerRightX>180.0</LowerRightX>
|
||||
<LowerRightY>-90.0</LowerRightY>
|
||||
<SizeX>15840</SizeX>
|
||||
<SizeY>7920</SizeY>
|
||||
<TileLevel>5</TileLevel>
|
||||
<YOrigin>top</YOrigin>
|
||||
</DataWindow>
|
||||
<Projection>EPSG:4326</Projection>
|
||||
<BlockSizeX>512</BlockSizeX>
|
||||
<BlockSizeY>512</BlockSizeY>
|
||||
<BandsCount>1</BandsCount>
|
||||
<MaxConnections>10</MaxConnections>
|
||||
</GDAL_WMS>
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<GDAL_WMS>
|
||||
<Service name="TMS">
|
||||
<ServerUrl>http://wms.itn.liu.se/Titan/ISS_P19658_Mosaic_Global_4km/tile/${z}/${y}/${x}</ServerUrl>
|
||||
</Service>
|
||||
<DataWindow>
|
||||
<UpperLeftX>-180.0</UpperLeftX>
|
||||
<UpperLeftY>90.0</UpperLeftY>
|
||||
<LowerRightX>180.0</LowerRightX>
|
||||
<LowerRightY>-90.0</LowerRightY>
|
||||
<SizeX>4040</SizeX>
|
||||
<SizeY>2020</SizeY>
|
||||
<TileLevel>4</TileLevel>
|
||||
<YOrigin>top</YOrigin>
|
||||
</DataWindow>
|
||||
<Projection>EPSG:4326</Projection>
|
||||
<BlockSizeX>256</BlockSizeX>
|
||||
<BlockSizeY>256</BlockSizeY>
|
||||
<BandsCount>1</BandsCount>
|
||||
<MaxConnections>10</MaxConnections>
|
||||
</GDAL_WMS>
|
||||
@@ -4,6 +4,7 @@ local kernel = asset.require('../kernels').sat375
|
||||
asset.request('./trail')
|
||||
|
||||
|
||||
local map_service_configs = asset.localResource("map_service_configs")
|
||||
|
||||
local textures = asset.syncedResource({
|
||||
Type = "HttpSynchronization",
|
||||
@@ -37,6 +38,12 @@ local Titan = {
|
||||
{
|
||||
Identifier = "Texture",
|
||||
FilePath = textures .. "/titan.jpg",
|
||||
-- Enabled = true
|
||||
},
|
||||
{
|
||||
Identifier = "Cassini_ISS_Global_Mosaic_4km_LiU",
|
||||
Name = "Cassini ISS Global Mosaic [Sweden]",
|
||||
FilePath = map_service_configs .. "/LiU/ISS_P19658_Mosaic_Global_4km.wms",
|
||||
Enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,15 @@ local registerSceneGraphNodesAndExport = function (sceneAsset, nodes, override)
|
||||
end
|
||||
end
|
||||
|
||||
local registerInterestingNodes = function (sceneAsset, nodes)
|
||||
sceneAsset.onInitialize(function ()
|
||||
openspace.markInterestingNodes(nodes)
|
||||
end)
|
||||
sceneAsset.onDeinitialize(function ()
|
||||
openspace.removeInterestingNodes(nodes)
|
||||
end)
|
||||
end
|
||||
|
||||
local requireAll = function (sceneAsset, directory)
|
||||
function string.ends(String,End)
|
||||
return End=='' or string.sub(String,-string.len(End))==End
|
||||
@@ -125,5 +134,6 @@ asset.export("registerSceneGraphNodes", registerSceneGraphNodes)
|
||||
asset.export("registerSceneGraphNodesAndExport", registerSceneGraphNodesAndExport)
|
||||
asset.export("registerSpiceKernels", registerSpiceKernels)
|
||||
asset.export("registerDashboardItems", registerDashboardItems)
|
||||
asset.export("registerInterestingNodes", registerInterestingNodes)
|
||||
asset.export("requireAll", requireAll)
|
||||
asset.export("requestAll", requestAll)
|
||||
|
||||
@@ -3,36 +3,10 @@ local propertyHelper = asset.require('./property_helper')
|
||||
|
||||
local Keybindings = {
|
||||
{
|
||||
Key = "F2",
|
||||
Name = "Show Scene Menu",
|
||||
Command =
|
||||
[[local b = openspace.getPropertyValue('Modules.ImGUI.Main.SceneProperties.Enabled');
|
||||
local c = openspace.getPropertyValue('Modules.ImGUI.Main.IsHidden');
|
||||
openspace.setPropertyValue('Modules.ImGUI.*.Enabled', false);
|
||||
if b and c then
|
||||
-- This can happen if the main properties window is enabled, the main gui is enabled
|
||||
-- and then closed again. So the main properties window is enabled, but also all
|
||||
-- windows are hidden
|
||||
openspace.setPropertyValueSingle('Modules.ImGUI.Main.IsHidden', false);
|
||||
openspace.setPropertyValueSingle('Modules.ImGUI.Main.SceneProperties.Enabled', true);
|
||||
openspace.setPropertyValueSingle('Modules.ImGUI.Main.SpaceTime.Enabled', true);
|
||||
else
|
||||
openspace.setPropertyValueSingle('Modules.ImGUI.Main.SceneProperties.Enabled', not b);
|
||||
openspace.setPropertyValueSingle('Modules.ImGUI.Main.SpaceTime.Enabled', not b);
|
||||
openspace.setPropertyValueSingle('Modules.ImGUI.Main.IsHidden', b);
|
||||
end]],
|
||||
Documentation = "Shows or hides the properties window",
|
||||
GuiPath = "/Native GUI",
|
||||
Local = true
|
||||
},
|
||||
{
|
||||
Key = "F3",
|
||||
Name = "Show Global Menu",
|
||||
Command =
|
||||
[[local b = openspace.getPropertyValue('Modules.ImGUI.Main.Enabled');
|
||||
openspace.setPropertyValueSingle('Modules.ImGUI.Main.Enabled', not b);
|
||||
openspace.setPropertyValueSingle('Modules.ImGUI.Main.IsHidden', b);]],
|
||||
Documentation = "Shows or hides the entire user interface",
|
||||
Key = "F1",
|
||||
Name = "Show Native GUI",
|
||||
Command = propertyHelper.invert('Modules.ImGUI.Main.Enabled'),
|
||||
Documentation = "Shows or hides the native UI",
|
||||
GuiPath = "/Native GUI",
|
||||
Local = true
|
||||
},
|
||||
|
||||
@@ -4,6 +4,7 @@ local createDeck = function (identifier, defaultRenderableProperties)
|
||||
IdentifierPrefix = identifier,
|
||||
CurrentSlideIndex = 1,
|
||||
DefaultRenderableProperties = defaultRenderableProperties,
|
||||
Visible = true
|
||||
}
|
||||
end
|
||||
|
||||
@@ -49,6 +50,10 @@ local setCurrentSlide = function (deck, index, interpolationDuration)
|
||||
|
||||
deck.CurrentSlideIndex = index
|
||||
|
||||
if not deck.Visible then
|
||||
return
|
||||
end
|
||||
|
||||
for i, identifier in pairs(deck.SlideIdentifiers) do
|
||||
local opacity = 0
|
||||
if (index == i) then
|
||||
@@ -56,7 +61,7 @@ local setCurrentSlide = function (deck, index, interpolationDuration)
|
||||
end
|
||||
openspace.setPropertyValueSingle(
|
||||
"ScreenSpace." .. identifier .. ".Alpha", opacity,
|
||||
interpolationDuration)
|
||||
interpolationDuration, "QuadraticEaseOut")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -68,9 +73,31 @@ local goToPreviousSlide = function (deck, interpolationDuration)
|
||||
setCurrentSlide(deck, deck.CurrentSlideIndex - 1, interpolationDuration)
|
||||
end
|
||||
|
||||
local toggleSlides = function (deck, interpolationDuration)
|
||||
deck.Visible = not deck.Visible
|
||||
if deck.Visible then
|
||||
for i, identifier in pairs(deck.SlideIdentifiers) do
|
||||
local opacity = 0
|
||||
if (i == deck.CurrentSlideIndex) then
|
||||
opacity = 1
|
||||
end
|
||||
openspace.setPropertyValueSingle(
|
||||
"ScreenSpace." .. identifier .. ".Alpha", opacity,
|
||||
interpolationDuration, "QuadraticEaseOut")
|
||||
end
|
||||
else
|
||||
for i, identifier in pairs(deck.SlideIdentifiers) do
|
||||
openspace.setPropertyValueSingle(
|
||||
"ScreenSpace." .. identifier .. ".Alpha", 0,
|
||||
interpolationDuration, "QuadraticEaseOut")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
asset.export('createDeck', createDeck)
|
||||
asset.export('removeDeck', removeDeck)
|
||||
asset.export('addSlide', addSlide)
|
||||
asset.export('setCurrentSlide', setCurrentSlide)
|
||||
asset.export('goToNextSlide', goToNextSlide)
|
||||
asset.export('goToPreviousSlide', goToPreviousSlide)
|
||||
asset.export('toggleSlides', toggleSlides)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
return {
|
||||
{
|
||||
Type = "SyncAssetTask",
|
||||
Asset = "scene/milkyway/gaia/gaia_dr2_download_stars"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
local dataFolder = "E:/gaia_sync_data"
|
||||
return {
|
||||
{
|
||||
Type = "ConstructOctreeTask",
|
||||
InFileOrFolderPath = dataFolder .. "/Gaia_DR2_full_24columns/",
|
||||
OutFileOrFolderPath = dataFolder .. "/DR2_full_Octree_test_50,50/",
|
||||
MaxDist = 500,
|
||||
MaxStarsPerNode = 50000,
|
||||
SingleFileInput = false,
|
||||
-- Specify filter thresholds
|
||||
--FilterPosX = {0.0, 0.0},
|
||||
--FilterPosY = {0.0, 0.0},
|
||||
--FilterPosZ = {0.0, 0.0},
|
||||
FilterGMag = {20.0, 20.0},
|
||||
FilterBpRp = {0.0, 0.0},
|
||||
--FilterVelX = {0.0, 0.0},
|
||||
--FilterVelY = {0.0, 0.0},
|
||||
--FilterVelZ = {0.0, 0.0},
|
||||
--FilterBpMag = {20.0, 20.0},
|
||||
--FilterRpMag = {20.0, 20.0},
|
||||
--FilterBpG = {0.0, 0.0},
|
||||
--FilterGRp = {0.0, 0.0},
|
||||
--FilterRa = {0.0, 0.0},
|
||||
--FilterRaError = {0.0, 0.0},
|
||||
--FilterDec = {0.0, 0.0},
|
||||
--FilterDecError = {0.0, 0.0},
|
||||
FilterParallax = {0.01, 0.0},
|
||||
FilterParallaxError = {0.00001, 0.5},
|
||||
--FilterPmra = {0.0, 0.0},
|
||||
--FilterPmraError = {0.0, 0.0},
|
||||
--FilterPmdec = {0.0, 0.0},
|
||||
--FilterPmdecError = {0.0, 0.0},
|
||||
--FilterRv = {0.0, 0.0},
|
||||
--FilterRvError = {0.0, 0.0},
|
||||
},
|
||||
|
||||
-- {
|
||||
-- Type = "ConstructOctreeTask",
|
||||
-- InFileOrFolderPath = dataFolder .. "/AMNH/Binary/GaiaUMS.bin",
|
||||
-- OutFileOrFolderPath = dataFolder .. "/AMNH/Octree/GaiaUMS_Octree.bin",
|
||||
-- MaxDist = 10,
|
||||
-- MaxStarsPerNode = 20000,
|
||||
-- SingleFileInput = true,
|
||||
-- },
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
local dataFolder = "E:/gaia_sync_data"
|
||||
return {
|
||||
{
|
||||
Type = "ReadFitsTask",
|
||||
InFileOrFolderPath = "L:/Gaia_DR2/gaia_source/fits/",
|
||||
OutFileOrFolderPath = dataFolder .. "/Gaia_DR2_full_24columns/",
|
||||
SingleFileProcess = false,
|
||||
ThreadsToUse = 8,
|
||||
},
|
||||
|
||||
--{
|
||||
-- Type = "ReadSpeckTask",
|
||||
-- InFilePath = dataFolder .. "/AMNH/GaiaUMS/GaiaUMS.speck",
|
||||
-- OutFilePath = dataFolder .. "/AMNH/Binary/GaiaUMS.bin",
|
||||
--},
|
||||
}
|
||||
+1
-1
Submodule ext/ghoul updated: a6bb81f5b5...c0f31b5e55
@@ -308,21 +308,19 @@ void testSpecificationAndThrow(const Documentation& documentation,
|
||||
namespace ghoul {
|
||||
|
||||
template <>
|
||||
std::string to_string(const openspace::documentation::TestResult& testResult);
|
||||
std::string to_string(const openspace::documentation::TestResult& value);
|
||||
|
||||
template <>
|
||||
std::string to_string(const openspace::documentation::TestResult::Offense& offense);
|
||||
std::string to_string(const openspace::documentation::TestResult::Offense& value);
|
||||
|
||||
template <>
|
||||
std::string to_string(
|
||||
const openspace::documentation::TestResult::Offense::Reason& reason);
|
||||
std::string to_string(const openspace::documentation::TestResult::Offense::Reason& value);
|
||||
|
||||
template <>
|
||||
std::string to_string(const openspace::documentation::TestResult::Warning& warning);
|
||||
std::string to_string(const openspace::documentation::TestResult::Warning& value);
|
||||
|
||||
template <>
|
||||
std::string to_string(
|
||||
const openspace::documentation::TestResult::Warning::Reason& reason);
|
||||
std::string to_string(const openspace::documentation::TestResult::Warning::Reason& value);
|
||||
|
||||
} // namespace ghoul
|
||||
|
||||
|
||||
@@ -106,7 +106,8 @@ private:
|
||||
namespace ghoul {
|
||||
|
||||
template <>
|
||||
std::string to_string(const openspace::interaction::JoystickCameraStates::AxisType& type);
|
||||
std::string to_string(
|
||||
const openspace::interaction::JoystickCameraStates::AxisType& value);
|
||||
|
||||
template <>
|
||||
openspace::interaction::JoystickCameraStates::AxisType
|
||||
|
||||
@@ -113,7 +113,7 @@ struct JoystickInputStates : public std::array<JoystickInputState, MaxJoysticks>
|
||||
namespace ghoul {
|
||||
|
||||
template <>
|
||||
std::string to_string(const openspace::interaction::JoystickAction& action);
|
||||
std::string to_string(const openspace::interaction::JoystickAction& value);
|
||||
|
||||
template <>
|
||||
openspace::interaction::JoystickAction from_string(const std::string& str);
|
||||
|
||||
@@ -104,7 +104,7 @@ private:
|
||||
SceneGraphNode* _focusNode = nullptr;
|
||||
glm::dvec3 _previousFocusNodePosition;
|
||||
glm::dquat _previousFocusNodeRotation;
|
||||
double _currentCameraToSurfaceDistance;
|
||||
double _currentCameraToSurfaceDistance = 0.0;
|
||||
bool _directlySetStereoDistance = false;
|
||||
|
||||
Interpolator<double> _rotateToFocusNodeInterpolator;
|
||||
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
* \param filename file saved with recorded keyframes.
|
||||
* \returns true if recording to file starts without errors.
|
||||
*/
|
||||
bool startRecording(std::string filename);
|
||||
bool startRecording(const std::string& filename);
|
||||
|
||||
/**
|
||||
* Starts a recording session, which will save data to the provided filename
|
||||
@@ -160,10 +160,10 @@ private:
|
||||
};
|
||||
ExternInteraction _externInteract;
|
||||
bool _isRecording = false;
|
||||
double _timestampRecordStarted;
|
||||
double _timestampPlaybackStarted_application;
|
||||
double _timestampPlaybackStarted_simulation;
|
||||
double _timestampApplicationStarted_simulation;
|
||||
double _timestampRecordStarted = 0.0;
|
||||
double _timestampPlaybackStarted_application = 0.0;
|
||||
double _timestampPlaybackStarted_simulation = 0.0;
|
||||
double _timestampApplicationStarted_simulation = 0.0;
|
||||
bool hasCameraChangedFromPrev(datamessagestructures::CameraKeyframe kfNew);
|
||||
double appropriateTimestamp(double timeOs, double timeRec, double timeSim);
|
||||
double equivalentSimulationTime(double timeOs, double timeRec, double timeSim);
|
||||
@@ -179,7 +179,7 @@ private:
|
||||
void writeToFileBuffer(std::vector<char>& cvec);
|
||||
void writeToFileBuffer(const unsigned char c);
|
||||
void writeToFileBuffer(bool b);
|
||||
void saveStringToFile(const std::string s);
|
||||
void saveStringToFile(const std::string& s);
|
||||
void saveKeyframeToFileBinary(unsigned char* bufferSource, size_t size);
|
||||
void findFirstCameraKeyframeInTimeline();
|
||||
std::string readHeaderElement(size_t readLen_chars);
|
||||
|
||||
@@ -95,7 +95,7 @@ private:
|
||||
void setHostName(const std::string& hostName);
|
||||
void setNConnections(size_t nConnections);
|
||||
|
||||
double convertTimestamp(double originalTime);
|
||||
double convertTimestamp(double messageTimestamp);
|
||||
void analyzeTimeDifference(double messageTimestamp);
|
||||
|
||||
properties::StringProperty _password;
|
||||
|
||||
@@ -65,10 +65,9 @@ private:
|
||||
ParallelConnection::Message message;
|
||||
};
|
||||
|
||||
bool isConnected(std::shared_ptr<Peer> peer) const;
|
||||
bool isConnected(const Peer& peer) const;
|
||||
|
||||
void sendMessage(std::shared_ptr<Peer> peer,
|
||||
ParallelConnection::MessageType messageType,
|
||||
void sendMessage(Peer& peer, ParallelConnection::MessageType messageType,
|
||||
const std::vector<char>& message);
|
||||
|
||||
void sendMessageToAll(ParallelConnection::MessageType messageType,
|
||||
@@ -77,17 +76,17 @@ private:
|
||||
void sendMessageToClients(ParallelConnection::MessageType messageType,
|
||||
const std::vector<char>& message);
|
||||
|
||||
void disconnect(std::shared_ptr<Peer> peer);
|
||||
void setName(std::shared_ptr<Peer> peer, std::string name);
|
||||
void disconnect(Peer& peer);
|
||||
void setName(Peer& peer, std::string name);
|
||||
void assignHost(std::shared_ptr<Peer> newHost);
|
||||
void setToClient(std::shared_ptr<Peer> peer);
|
||||
void setToClient(Peer& peer);
|
||||
void setNConnections(size_t nConnections);
|
||||
void sendConnectionStatus(std::shared_ptr<Peer> peer);
|
||||
void sendConnectionStatus(Peer& peer);
|
||||
|
||||
void handleAuthentication(std::shared_ptr<Peer> peer, std::vector<char> message);
|
||||
void handleData(std::shared_ptr<Peer> peer, std::vector<char> data);
|
||||
void handleData(const Peer& peer, std::vector<char> data);
|
||||
void handleHostshipRequest(std::shared_ptr<Peer> peer, std::vector<char> message);
|
||||
void handleHostshipResignation(std::shared_ptr<Peer> peer, std::vector<char> data);
|
||||
void handleHostshipResignation(Peer& peer);
|
||||
void handleDisconnection(std::shared_ptr<Peer> peer);
|
||||
|
||||
void handleNewPeers();
|
||||
|
||||
@@ -45,14 +45,14 @@ struct PerformanceLayout {
|
||||
float updateRotation[NumberValues];
|
||||
float updateScaling[NumberValues];
|
||||
};
|
||||
SceneGraphPerformanceLayout sceneGraphEntries[MaxValues];
|
||||
SceneGraphPerformanceLayout sceneGraphEntries[MaxValues] = {};
|
||||
int16_t nScaleGraphEntries = 0;
|
||||
|
||||
struct FunctionPerformanceLayout {
|
||||
char name[LengthName];
|
||||
float time[NumberValues];
|
||||
};
|
||||
FunctionPerformanceLayout functionEntries[MaxValues];
|
||||
FunctionPerformanceLayout functionEntries[MaxValues] = {};
|
||||
int16_t nFunctionEntries = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -42,8 +42,6 @@ public:
|
||||
static void CreateGlobalSharedMemory();
|
||||
static void DestroyGlobalSharedMemory();
|
||||
|
||||
~PerformanceManager();
|
||||
|
||||
void setEnabled(bool enabled);
|
||||
bool isEnabled() const;
|
||||
|
||||
|
||||
@@ -102,13 +102,21 @@ public:
|
||||
void addOption(int value, std::string desc);
|
||||
|
||||
/**
|
||||
* Adds multiple options to the OptionProperty. Each value in the vector consists of
|
||||
* an integer value and a string description.
|
||||
*
|
||||
* \param options Pairs of <option, description> that are added to the OptionProperty
|
||||
*/
|
||||
* Adds multiple options to the OptionProperty. Each value in the vector consists of
|
||||
* an integer value and a string description.
|
||||
*
|
||||
* \param options Pairs of <option, description> that are added to the OptionProperty
|
||||
*/
|
||||
void addOptions(std::vector<std::pair<int, std::string>> options);
|
||||
|
||||
/**
|
||||
* Adds multiple options to the OptionProperty. Each value in the vector is assigned
|
||||
* to its location.
|
||||
*
|
||||
* \param options A list of options that should be added to the OptionProperty
|
||||
*/
|
||||
void addOptions(std::vector<std::string> options);
|
||||
|
||||
/**
|
||||
* Returns the list of available options.
|
||||
*
|
||||
|
||||
@@ -160,6 +160,12 @@ public:
|
||||
*/
|
||||
bool hasProperty(const std::string& uri) const;
|
||||
|
||||
/**
|
||||
* This method checks if a Property exists in this PropertyOwner.
|
||||
* \return <code>true</code> if the Property existed, <code>false</code> otherwise.
|
||||
*/
|
||||
bool hasProperty(const Property* prop) const;
|
||||
|
||||
void setPropertyOwner(PropertyOwner* owner) { _owner = owner; }
|
||||
PropertyOwner* owner() const { return _owner; }
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
#include <openspace/rendering/dashboarditem.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
@@ -36,12 +37,10 @@ namespace openspace {
|
||||
|
||||
namespace scripting { struct LuaLibrary; }
|
||||
|
||||
class DashboardItem;
|
||||
|
||||
class Dashboard : public properties::PropertyOwner {
|
||||
public:
|
||||
Dashboard();
|
||||
~Dashboard();
|
||||
~Dashboard() = default;
|
||||
|
||||
void render(glm::vec2& penPosition);
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ public:
|
||||
void tickItem();
|
||||
|
||||
enum class Phase {
|
||||
PreStart,
|
||||
Construction,
|
||||
Synchronization,
|
||||
Initialization
|
||||
@@ -97,7 +98,7 @@ private:
|
||||
bool _showNodeNames;
|
||||
bool _showProgressbar;
|
||||
|
||||
Phase _phase;
|
||||
Phase _phase = Phase::PreStart;
|
||||
std::atomic_int _iProgress = 0;
|
||||
std::atomic_int _nItems = 0;
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ public:
|
||||
private:
|
||||
void setState(State state);
|
||||
|
||||
void requiredAssetChangedState(std::shared_ptr<Asset> asset, Asset::State childState);
|
||||
void requiredAssetChangedState(Asset::State childState);
|
||||
void requestedAssetChangedState(Asset* child, Asset::State childState);
|
||||
|
||||
bool isSyncResolveReady();
|
||||
|
||||
@@ -58,8 +58,7 @@ public:
|
||||
* \param component The optional compoment that caused this exception to be thrown
|
||||
* \pre message may not be empty
|
||||
*/
|
||||
explicit InvalidSceneError(const std::string& msg,
|
||||
const std::string& comp = "");
|
||||
explicit InvalidSceneError(std::string msg, std::string comp = "");
|
||||
};
|
||||
|
||||
/// This struct describes a time that has some intrinsic interesting-ness to this
|
||||
|
||||
@@ -289,6 +289,8 @@ constexpr double convertDistance(double meters, DistanceUnit requestedUnit) {
|
||||
}
|
||||
}
|
||||
|
||||
float convertMasPerYearToMeterPerSecond(float masPerYear, float parallax);
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_CORE___DISTANCECONVERSION___H__
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
#ifdef WIN32
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif // WIN32
|
||||
#include <math.h>
|
||||
#include <cmath>
|
||||
|
||||
|
||||
namespace {
|
||||
@@ -1218,8 +1218,9 @@ void AtmosphereDeferredcaster::executeCalculations(GLuint quadCalcVAO,
|
||||
}
|
||||
|
||||
// Restores OpenGL blending state
|
||||
if (blendEnabled)
|
||||
if (blendEnabled) {
|
||||
glEnable(GL_BLEND);
|
||||
}
|
||||
|
||||
glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha);
|
||||
glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha);
|
||||
|
||||
@@ -186,7 +186,7 @@ private:
|
||||
int _nu_samples;
|
||||
|
||||
glm::dmat4 _modelTransform;
|
||||
double _time;
|
||||
double _time = 0.0;
|
||||
|
||||
// Eclipse Shadows
|
||||
std::vector<ShadowConfiguration> _shadowConfArray;
|
||||
|
||||
@@ -39,6 +39,7 @@ set(HEADER_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/lightsource/scenegraphlightsource.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/modelgeometry.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/multimodelgeometry.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableboxgrid.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablecartesianaxes.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablemodel.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableplane.h
|
||||
@@ -82,6 +83,7 @@ set(SOURCE_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/lightsource/scenegraphlightsource.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/modelgeometry.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/multimodelgeometry.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableboxgrid.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablecartesianaxes.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablemodel.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableplane.cpp
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <modules/base/dashboard/dashboarditempropertyvalue.h>
|
||||
#include <modules/base/dashboard/dashboarditemsimulationincrement.h>
|
||||
#include <modules/base/dashboard/dashboarditemspacing.h>
|
||||
#include <modules/base/rendering/renderableboxgrid.h>
|
||||
#include <modules/base/dashboard/dashboarditemvelocity.h>
|
||||
#include <modules/base/lightsource/cameralightsource.h>
|
||||
#include <modules/base/lightsource/scenegraphlightsource.h>
|
||||
@@ -117,6 +118,7 @@ void BaseModule::internalInitialize(const ghoul::Dictionary&) {
|
||||
auto fRenderable = FactoryManager::ref().factory<Renderable>();
|
||||
ghoul_assert(fRenderable, "Renderable factory was not created");
|
||||
|
||||
fRenderable->registerClass<RenderableBoxGrid>("RenderableBoxGrid");
|
||||
fRenderable->registerClass<RenderableCartesianAxes>("RenderableCartesianAxes");
|
||||
fRenderable->registerClass<RenderableModel>("RenderableModel");
|
||||
fRenderable->registerClass<RenderablePlaneImageLocal>("RenderablePlaneImageLocal");
|
||||
@@ -181,6 +183,7 @@ std::vector<documentation::Documentation> BaseModule::documentations() const {
|
||||
DashboardItemSpacing::Documentation(),
|
||||
DashboardItemVelocity::Documentation(),
|
||||
|
||||
RenderableBoxGrid::Documentation(),
|
||||
RenderableModel::Documentation(),
|
||||
RenderablePlane::Documentation(),
|
||||
RenderableSphere::Documentation(),
|
||||
|
||||
@@ -61,8 +61,7 @@ documentation::Documentation CameraLightSource::Documentation() {
|
||||
}
|
||||
|
||||
CameraLightSource::CameraLightSource()
|
||||
: LightSource()
|
||||
, _intensity(IntensityInfo, 1.f, 0.f, 1.f)
|
||||
: _intensity(IntensityInfo, 1.f, 0.f, 1.f)
|
||||
{
|
||||
addProperty(_intensity);
|
||||
}
|
||||
|
||||
@@ -76,8 +76,7 @@ documentation::Documentation SceneGraphLightSource::Documentation() {
|
||||
}
|
||||
|
||||
SceneGraphLightSource::SceneGraphLightSource()
|
||||
: LightSource()
|
||||
, _intensity(IntensityInfo, 1.f, 0.f, 1.f)
|
||||
: _intensity(IntensityInfo, 1.f, 0.f, 1.f)
|
||||
, _sceneGraphNodeReference(NodeInfo, "")
|
||||
{
|
||||
addProperty(_intensity);
|
||||
|
||||
@@ -0,0 +1,320 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/base/rendering/renderableboxgrid.h>
|
||||
|
||||
#include <modules/base/basemodule.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* ProgramName = "GridProgram";
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo GridColorInfo = {
|
||||
"GridColor",
|
||||
"Grid Color",
|
||||
"This value determines the color of the grid lines that are rendered."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo GridMatrixInfo = {
|
||||
"GridMatrix",
|
||||
"Grid Matrix",
|
||||
"This value specifies the local transformation matrix that defines the "
|
||||
"orientation of this grid relative to the parent's rotation."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo SegmentsInfo = {
|
||||
"Segments",
|
||||
"Number of Segments",
|
||||
"This value specifies the number of segments that are used to render the "
|
||||
"surrounding sphere."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo LineWidthInfo = {
|
||||
"LineWidth",
|
||||
"Line Width",
|
||||
"This value specifies the line width of the spherical grid."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo SizeInfo = {
|
||||
"Size",
|
||||
"Grid Size",
|
||||
"This value species the size of each dimensions of the box"
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderableBoxGrid::Documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"RenderableSphericalGrid",
|
||||
"base_renderable_sphericalgrid",
|
||||
{
|
||||
{
|
||||
GridMatrixInfo.identifier,
|
||||
new DoubleMatrix4x4Verifier,
|
||||
Optional::Yes,
|
||||
GridMatrixInfo.description
|
||||
},
|
||||
{
|
||||
GridColorInfo.identifier,
|
||||
new DoubleVector4Verifier,
|
||||
Optional::Yes,
|
||||
GridColorInfo.description
|
||||
},
|
||||
{
|
||||
SegmentsInfo.identifier,
|
||||
new IntVerifier,
|
||||
Optional::Yes,
|
||||
SegmentsInfo.description
|
||||
},
|
||||
{
|
||||
LineWidthInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
LineWidthInfo.description
|
||||
},
|
||||
{
|
||||
SizeInfo.identifier,
|
||||
new DoubleVector3Verifier,
|
||||
Optional::Yes,
|
||||
SizeInfo.description
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
RenderableBoxGrid::RenderableBoxGrid(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
, _gridMatrix(GridMatrixInfo, glm::mat4(1.f))
|
||||
, _gridColor(
|
||||
GridColorInfo,
|
||||
glm::vec4(0.5f, 0.5, 0.5f, 1.f),
|
||||
glm::vec4(0.f),
|
||||
glm::vec4(1.f)
|
||||
)
|
||||
, _segments(SegmentsInfo, 36, 4, 200)
|
||||
, _lineWidth(LineWidthInfo, 0.5f, 0.f, 20.f)
|
||||
, _size(SizeInfo, glm::vec3(1e20f), glm::vec3(1.f), glm::vec3(1e35f))
|
||||
{
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
dictionary,
|
||||
"RenderableBoxGrid"
|
||||
);
|
||||
|
||||
addProperty(_opacity);
|
||||
registerUpdateRenderBinFromOpacity();
|
||||
|
||||
if (dictionary.hasKey(GridMatrixInfo.identifier)) {
|
||||
_gridMatrix = dictionary.value<glm::dmat4>(GridMatrixInfo.identifier);
|
||||
}
|
||||
addProperty(_gridMatrix);
|
||||
|
||||
if (dictionary.hasKey(GridColorInfo.identifier)) {
|
||||
_gridColor = dictionary.value<glm::vec4>(GridColorInfo.identifier);
|
||||
}
|
||||
_gridColor.setViewOption(properties::Property::ViewOptions::Color);
|
||||
addProperty(_gridColor);
|
||||
|
||||
if (dictionary.hasKey(SegmentsInfo.identifier)) {
|
||||
_segments = static_cast<int>(dictionary.value<double>(SegmentsInfo.identifier));
|
||||
}
|
||||
_segments.onChange([&]() { _gridIsDirty = true; });
|
||||
addProperty(_segments);
|
||||
|
||||
if (dictionary.hasKey(LineWidthInfo.identifier)) {
|
||||
_lineWidth = static_cast<float>(
|
||||
dictionary.value<double>(LineWidthInfo.identifier)
|
||||
);
|
||||
}
|
||||
addProperty(_lineWidth);
|
||||
|
||||
if (dictionary.hasKey(SizeInfo.identifier)) {
|
||||
_size = dictionary.value<glm::vec3>(SizeInfo.identifier);
|
||||
}
|
||||
_size.onChange([&]() { _gridIsDirty = true; });
|
||||
addProperty(_size);
|
||||
}
|
||||
|
||||
bool RenderableBoxGrid::isReady() const {
|
||||
return _gridProgram != nullptr;
|
||||
}
|
||||
|
||||
void RenderableBoxGrid::initializeGL() {
|
||||
_gridProgram = BaseModule::ProgramObjectManager.request(
|
||||
ProgramName,
|
||||
[]() -> std::unique_ptr<ghoul::opengl::ProgramObject> {
|
||||
return global::renderEngine.buildRenderProgram(
|
||||
ProgramName,
|
||||
absPath("${MODULE_BASE}/shaders/grid_vs.glsl"),
|
||||
absPath("${MODULE_BASE}/shaders/grid_fs.glsl")
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
glGenVertexArrays(1, &_vaoID);
|
||||
glGenBuffers(1, &_vBufferID);
|
||||
|
||||
glBindVertexArray(_vaoID);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vBufferID);
|
||||
glEnableVertexAttribArray(0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void RenderableBoxGrid::deinitializeGL() {
|
||||
glDeleteVertexArrays(1, &_vaoID);
|
||||
_vaoID = 0;
|
||||
|
||||
glDeleteBuffers(1, &_vBufferID);
|
||||
_vBufferID = 0;
|
||||
|
||||
BaseModule::ProgramObjectManager.release(
|
||||
ProgramName,
|
||||
[](ghoul::opengl::ProgramObject* p) {
|
||||
global::renderEngine.removeRenderProgram(p);
|
||||
}
|
||||
);
|
||||
_gridProgram = nullptr;
|
||||
}
|
||||
|
||||
void RenderableBoxGrid::render(const RenderData& data, RendererTasks&){
|
||||
_gridProgram->activate();
|
||||
|
||||
_gridProgram->setUniform("opacity", _opacity);
|
||||
|
||||
glm::dmat4 modelTransform =
|
||||
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * // Translation
|
||||
glm::dmat4(data.modelTransform.rotation) * // Spice rotation
|
||||
glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale));
|
||||
|
||||
glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform;
|
||||
|
||||
_gridProgram->setUniform("modelViewTransform", glm::mat4(modelViewTransform));
|
||||
_gridProgram->setUniform("projectionTransform", data.camera.projectionMatrix());
|
||||
|
||||
_gridProgram->setUniform("gridColor", _gridColor);
|
||||
|
||||
glLineWidth(_lineWidth);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_BLEND);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
|
||||
glBindVertexArray(_vaoID);
|
||||
glDrawArrays(_mode, 0, static_cast<GLsizei>(_varray.size()));
|
||||
glBindVertexArray(0);
|
||||
|
||||
_gridProgram->deactivate();
|
||||
}
|
||||
|
||||
void RenderableBoxGrid::update(const UpdateData&) {
|
||||
if (_gridIsDirty) {
|
||||
//_vsize = (_segments + 1) * (_segments + 1);
|
||||
//_varray.resize(_vsize);
|
||||
|
||||
const glm::vec3 llf = -_size.value() / 2.f;
|
||||
const glm::vec3 urb = _size.value() / 2.f;
|
||||
|
||||
// 7
|
||||
// -------------------- 6
|
||||
// / /
|
||||
// /| /|
|
||||
// 4 / | / |
|
||||
// x-------------------x |
|
||||
// | | |5 |
|
||||
// | | | |
|
||||
// | | | |
|
||||
// | 3/----------------|--/ 2
|
||||
// | / | /
|
||||
// |/ |/
|
||||
// x-------------------x
|
||||
// 0 1
|
||||
//
|
||||
//
|
||||
// For Line strip:
|
||||
// 0 -> 1 -> 2 -> 3 -> 0 -> 4 -> 5 -> 6 -> 7 -> 4 -> 5(d) -> 1 -> 2(d) -> 6
|
||||
// -> 7(d) -> 3
|
||||
|
||||
const glm::vec3 v0 = { llf.x, llf.y, llf.z };
|
||||
const glm::vec3 v1 = { urb.x, llf.y, llf.z };
|
||||
const glm::vec3 v2 = { urb.x, urb.y, llf.z };
|
||||
const glm::vec3 v3 = { llf.x, urb.y, llf.z };
|
||||
const glm::vec3 v4 = { llf.x, llf.y, urb.z };
|
||||
const glm::vec3 v5 = { urb.x, llf.y, urb.z };
|
||||
const glm::vec3 v6 = { urb.x, urb.y, urb.z };
|
||||
const glm::vec3 v7 = { llf.x, urb.y, urb.z };
|
||||
|
||||
// First add the bounds
|
||||
_varray.push_back({ v0.x, v0.y, v0.z });
|
||||
_varray.push_back({ v1.x, v1.y, v1.z });
|
||||
_varray.push_back({ v2.x, v2.y, v2.z });
|
||||
_varray.push_back({ v3.x, v3.y, v3.z });
|
||||
_varray.push_back({ v0.x, v0.y, v0.z });
|
||||
_varray.push_back({ v4.x, v4.y, v4.z });
|
||||
_varray.push_back({ v5.x, v5.y, v5.z });
|
||||
_varray.push_back({ v6.x, v6.y, v6.z });
|
||||
_varray.push_back({ v7.x, v7.y, v7.z });
|
||||
_varray.push_back({ v4.x, v4.y, v4.z });
|
||||
_varray.push_back({ v5.x, v5.y, v5.z });
|
||||
_varray.push_back({ v1.x, v1.y, v1.z });
|
||||
_varray.push_back({ v2.x, v2.y, v2.z });
|
||||
_varray.push_back({ v6.x, v6.y, v6.z });
|
||||
_varray.push_back({ v7.x, v7.y, v7.z });
|
||||
_varray.push_back({ v3.x, v3.y, v3.z });
|
||||
|
||||
|
||||
glBindVertexArray(_vaoID);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vBufferID);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
_varray.size() * sizeof(Vertex),
|
||||
_varray.data(),
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
|
||||
glVertexAttribPointer(
|
||||
0,
|
||||
3,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
sizeof(Vertex),
|
||||
nullptr // = reinterpret_cast<const GLvoid*>(offsetof(Vertex, location))
|
||||
);
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
_gridIsDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -0,0 +1,83 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_BASE___RENDERABLEBOXGRID___H__
|
||||
#define __OPENSPACE_MODULE_BASE___RENDERABLEBOXGRID___H__
|
||||
|
||||
#include <openspace/rendering/renderable.h>
|
||||
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/matrix/dmat4property.h>
|
||||
#include <openspace/properties/scalar/intproperty.h>
|
||||
#include <openspace/properties/vector/vec3property.h>
|
||||
#include <openspace/properties/vector/vec4property.h>
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
|
||||
namespace ghoul::opengl {
|
||||
class ProgramObject;
|
||||
} // namespace ghoul::opengl
|
||||
|
||||
namespace openspace::documentation { struct Documentation; }
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class RenderableBoxGrid : public Renderable {
|
||||
public:
|
||||
RenderableBoxGrid(const ghoul::Dictionary& dictionary);
|
||||
|
||||
void initializeGL() override;
|
||||
void deinitializeGL() override;
|
||||
|
||||
bool isReady() const override;
|
||||
|
||||
void render(const RenderData& data, RendererTasks& rendererTask) override;
|
||||
void update(const UpdateData& data) override;
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
protected:
|
||||
struct Vertex {
|
||||
float location[3];
|
||||
};
|
||||
|
||||
ghoul::opengl::ProgramObject* _gridProgram = nullptr;
|
||||
|
||||
properties::DMat4Property _gridMatrix;
|
||||
properties::Vec4Property _gridColor;
|
||||
properties::IntProperty _segments;
|
||||
properties::FloatProperty _lineWidth;
|
||||
properties::Vec3Property _size;
|
||||
|
||||
bool _gridIsDirty = true;
|
||||
|
||||
GLuint _vaoID = 0;
|
||||
GLuint _vBufferID = 0;
|
||||
|
||||
GLenum _mode = GL_LINE_STRIP;
|
||||
std::vector<Vertex> _varray;
|
||||
};
|
||||
|
||||
}// namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_BASE___RENDERABLEBOXGRID___H__
|
||||
@@ -240,8 +240,6 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
|
||||
addProperty(_performShading);
|
||||
}
|
||||
|
||||
RenderableModel::~RenderableModel() {}
|
||||
|
||||
bool RenderableModel::isReady() const {
|
||||
return _program && _texture;
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace modelgeometry { class ModelGeometry; }
|
||||
class RenderableModel : public Renderable {
|
||||
public:
|
||||
RenderableModel(const ghoul::Dictionary& dictionary);
|
||||
~RenderableModel();
|
||||
~RenderableModel() = default;
|
||||
|
||||
void initialize() override;
|
||||
void initializeGL() override;
|
||||
|
||||
@@ -57,7 +57,7 @@ private:
|
||||
void loadTexture();
|
||||
|
||||
properties::StringProperty _texturePath;
|
||||
ghoul::opengl::Texture* _texture;
|
||||
ghoul::opengl::Texture* _texture = nullptr;
|
||||
std::unique_ptr<ghoul::filesystem::File> _textureFile;
|
||||
|
||||
bool _textureIsDirty = false;
|
||||
|
||||
@@ -217,6 +217,12 @@ documentation::Documentation FixedRotation::Documentation() {
|
||||
Optional::Yes,
|
||||
XAxisOrthogonalVectorInfo.description
|
||||
},
|
||||
{
|
||||
XAxisInvertObjectInfo.identifier,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
XAxisInvertObjectInfo.description
|
||||
},
|
||||
{
|
||||
KeyYAxis,
|
||||
new OrVerifier({ new StringVerifier, new DoubleVector3Verifier, }),
|
||||
@@ -234,6 +240,12 @@ documentation::Documentation FixedRotation::Documentation() {
|
||||
Optional::Yes,
|
||||
YAxisOrthogonalVectorInfo.description
|
||||
},
|
||||
{
|
||||
YAxisInvertObjectInfo.identifier,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
YAxisInvertObjectInfo.description
|
||||
},
|
||||
{
|
||||
KeyZAxis,
|
||||
new OrVerifier({ new StringVerifier, new DoubleVector3Verifier, }),
|
||||
@@ -251,6 +263,12 @@ documentation::Documentation FixedRotation::Documentation() {
|
||||
Optional::Yes,
|
||||
ZAxisOrthogonalVectorInfo.description
|
||||
},
|
||||
{
|
||||
ZAxisInvertObjectInfo.identifier,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
ZAxisInvertObjectInfo.description
|
||||
},
|
||||
{
|
||||
AttachedInfo.identifier,
|
||||
new StringVerifier,
|
||||
@@ -454,6 +472,11 @@ bool FixedRotation::initialize() {
|
||||
if (_constructorDictionary.hasKey(KeyXAxisOrthogonal)) {
|
||||
_xAxis.isOrthogonal = _constructorDictionary.value<bool>(KeyXAxisOrthogonal);
|
||||
}
|
||||
if (_constructorDictionary.hasKey(XAxisInvertObjectInfo.identifier)) {
|
||||
_xAxis.invertObject = _constructorDictionary.value<bool>(
|
||||
XAxisInvertObjectInfo.identifier
|
||||
);
|
||||
}
|
||||
if (_xAxis.isOrthogonal) {
|
||||
_xAxis.type = Axis::Type::OrthogonalVector;
|
||||
}
|
||||
@@ -474,6 +497,11 @@ bool FixedRotation::initialize() {
|
||||
if (_constructorDictionary.hasKey(KeyYAxisOrthogonal)) {
|
||||
_yAxis.isOrthogonal = _constructorDictionary.value<bool>(KeyYAxisOrthogonal);
|
||||
}
|
||||
if (_constructorDictionary.hasKey(YAxisInvertObjectInfo.identifier)) {
|
||||
_yAxis.invertObject = _constructorDictionary.value<bool>(
|
||||
YAxisInvertObjectInfo.identifier
|
||||
);
|
||||
}
|
||||
if (_yAxis.isOrthogonal) {
|
||||
_yAxis.type = Axis::Type::OrthogonalVector;
|
||||
}
|
||||
@@ -494,12 +522,16 @@ bool FixedRotation::initialize() {
|
||||
if (_constructorDictionary.hasKey(KeyZAxisOrthogonal)) {
|
||||
_zAxis.isOrthogonal = _constructorDictionary.value<bool>(KeyZAxisOrthogonal);
|
||||
}
|
||||
if (_constructorDictionary.hasKey(ZAxisInvertObjectInfo.identifier)) {
|
||||
_yAxis.invertObject = _constructorDictionary.value<bool>(
|
||||
ZAxisInvertObjectInfo.identifier
|
||||
);
|
||||
}
|
||||
if (_zAxis.isOrthogonal) {
|
||||
_zAxis.type = Axis::Type::OrthogonalVector;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!hasXAxis && hasYAxis && hasZAxis) {
|
||||
_xAxis.type = Axis::Type::CoordinateSystemCompletion;
|
||||
}
|
||||
@@ -554,11 +586,14 @@ glm::vec3 FixedRotation::xAxis() const {
|
||||
return glm::vec3(1.f, 0.f, 0.f);
|
||||
case Axis::Type::Object:
|
||||
if (_xAxis.node && _attachedNode) {
|
||||
glm::vec3 dir = glm::vec3(glm::normalize(
|
||||
_xAxis.node->worldPosition() -
|
||||
_attachedNode->worldPosition()
|
||||
));
|
||||
return _xAxis.invertObject ? -dir : dir;
|
||||
glm::dvec3 dir = _xAxis.node->worldPosition() -
|
||||
_attachedNode->worldPosition();
|
||||
|
||||
if (dir == glm::dvec3(0.0)) {
|
||||
dir = glm::dvec3(1.0, 0.0, 0.0);
|
||||
}
|
||||
glm::vec3 dirNorm = glm::vec3(glm::normalize(dir));
|
||||
return _xAxis.invertObject ? -dirNorm : dirNorm;
|
||||
}
|
||||
else {
|
||||
if (_xAxis.node) {
|
||||
|
||||
@@ -114,8 +114,7 @@ TimeFrameInterval::TimeFrameInterval()
|
||||
}
|
||||
|
||||
TimeFrameInterval::TimeFrameInterval(const ghoul::Dictionary& dictionary)
|
||||
: TimeFrame()
|
||||
, _hasStart(HasStartInfo, false)
|
||||
: _hasStart(HasStartInfo, false)
|
||||
, _start(StartInfo, 0, 0, 1E9)
|
||||
, _hasEnd(HasEndInfo, false)
|
||||
, _end(EndInfo, 0, 0, 1E9)
|
||||
|
||||
@@ -73,8 +73,6 @@ bool TimeFrameUnion::isActive(const Time& time) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
TimeFrameUnion::TimeFrameUnion() {}
|
||||
|
||||
TimeFrameUnion::TimeFrameUnion(const ghoul::Dictionary& dictionary)
|
||||
: TimeFrame()
|
||||
{
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace documentation { struct Documentation; }
|
||||
|
||||
class TimeFrameUnion : public TimeFrame {
|
||||
public:
|
||||
TimeFrameUnion();
|
||||
TimeFrameUnion() = default;
|
||||
TimeFrameUnion(const ghoul::Dictionary& dictionary);
|
||||
bool isActive(const Time&) const override;
|
||||
|
||||
|
||||
@@ -139,11 +139,11 @@ void CefWebGuiModule::internalInitialize(const ghoul::Dictionary& configuration)
|
||||
_visible = configuration.hasValue<bool>(VisibleInfo.identifier) &&
|
||||
configuration.value<bool>(VisibleInfo.identifier);
|
||||
|
||||
global::callback::initializeGL.push_back([this]() {
|
||||
global::callback::initializeGL.emplace_back([this]() {
|
||||
startOrStopGui();
|
||||
});
|
||||
|
||||
global::callback::draw2D.push_back([this](){
|
||||
global::callback::draw2D.emplace_back([this](){
|
||||
const bool isGuiWindow =
|
||||
global::windowDelegate.hasGuiWindow() ?
|
||||
global::windowDelegate.isGuiWindow() :
|
||||
@@ -160,7 +160,7 @@ void CefWebGuiModule::internalInitialize(const ghoul::Dictionary& configuration)
|
||||
}
|
||||
});
|
||||
|
||||
global::callback::deinitializeGL.push_back([this]() {
|
||||
global::callback::deinitializeGL.emplace_back([this]() {
|
||||
_enabled = false;
|
||||
startOrStopGui();
|
||||
});
|
||||
|
||||
@@ -31,8 +31,8 @@ namespace openspace {
|
||||
GUIKeyboardHandler::GUIKeyboardHandler() {
|
||||
_keyConsumed = false;
|
||||
|
||||
global::callback::keyboard.push_back(
|
||||
[&](Key key, KeyModifier mod, KeyAction action) -> bool {
|
||||
global::callback::keyboard.emplace_back(
|
||||
[&](Key, KeyModifier, KeyAction) -> bool {
|
||||
const bool previous = _keyConsumed;
|
||||
_keyConsumed = false;
|
||||
return previous;
|
||||
|
||||
@@ -57,7 +57,7 @@ GUIRenderHandler::GUIRenderHandler() {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), nullptr);
|
||||
glBindVertexArray(0);
|
||||
LDEBUG("Initializing CEF GL environment... done!");
|
||||
}
|
||||
|
||||
@@ -55,8 +55,6 @@ DebugRenderer::DebugRenderer(std::unique_ptr<ghoul::opengl::ProgramObject> progr
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
DebugRenderer::~DebugRenderer() { }
|
||||
|
||||
const DebugRenderer& DebugRenderer::ref() {
|
||||
if (!_reference) {
|
||||
try {
|
||||
@@ -70,7 +68,7 @@ const DebugRenderer& DebugRenderer::ref() {
|
||||
}
|
||||
|
||||
void DebugRenderer::renderVertices(const Vertices& clippingSpacePoints, GLenum mode,
|
||||
const glm::vec4& rgba) const
|
||||
const glm::vec4& color) const
|
||||
{
|
||||
if (clippingSpacePoints.empty()) {
|
||||
return;
|
||||
@@ -88,7 +86,7 @@ void DebugRenderer::renderVertices(const Vertices& clippingSpacePoints, GLenum m
|
||||
|
||||
// Activate the shader program and set the uniform color within the shader
|
||||
_programObject->activate();
|
||||
_programObject->setUniform("color", rgba);
|
||||
_programObject->setUniform("color", color);
|
||||
|
||||
glBindVertexArray(_vaoID);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferID);
|
||||
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
* Instantiate a new DebugRenderer with a custom shader program
|
||||
*/
|
||||
DebugRenderer(std::unique_ptr<ghoul::opengl::ProgramObject> programObject);
|
||||
~DebugRenderer();
|
||||
~DebugRenderer() = default;
|
||||
|
||||
/**
|
||||
* Access the static reference
|
||||
|
||||
@@ -173,8 +173,6 @@ RenderableDebugPlane::RenderableDebugPlane(const ghoul::Dictionary& dictionary)
|
||||
setBoundingSphere(_size);
|
||||
}
|
||||
|
||||
RenderableDebugPlane::~RenderableDebugPlane() {}
|
||||
|
||||
bool RenderableDebugPlane::isReady() const {
|
||||
bool ready = true;
|
||||
if (!_shader) {
|
||||
@@ -220,7 +218,7 @@ void RenderableDebugPlane::render(const RenderData& data, RendererTasks&) {
|
||||
|
||||
_shader->setUniform("ViewProjection", data.camera.viewProjectionMatrix());
|
||||
_shader->setUniform("ModelTransform", transform);
|
||||
setPscUniforms(*_shader.get(), data.camera, data.position);
|
||||
setPscUniforms(*_shader, data.camera, data.position);
|
||||
|
||||
ghoul::opengl::TextureUnit unit;
|
||||
unit.activate();
|
||||
|
||||
@@ -48,7 +48,7 @@ struct UpdateStructure;
|
||||
class RenderableDebugPlane : public Renderable {
|
||||
public:
|
||||
RenderableDebugPlane(const ghoul::Dictionary& dictionary);
|
||||
~RenderableDebugPlane();
|
||||
~RenderableDebugPlane() = default;
|
||||
|
||||
void initializeGL() override;
|
||||
void deinitializeGL() override;
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
#include <glm/gtx/string_cast.hpp>
|
||||
#include <array>
|
||||
#include <fstream>
|
||||
#include <stdint.h>
|
||||
#include <cstdint>
|
||||
#include <locale>
|
||||
#include <string>
|
||||
|
||||
@@ -423,8 +423,7 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di
|
||||
if (dictionary.hasKey(KeyFile)) {
|
||||
_speckFile = absPath(dictionary.value<std::string>(KeyFile));
|
||||
_hasSpeckFile = true;
|
||||
_drawElements.onChange([&]() {
|
||||
_hasSpeckFile = _hasSpeckFile == true? false : true; });
|
||||
_drawElements.onChange([&]() { _hasSpeckFile = !_hasSpeckFile; });
|
||||
addProperty(_drawElements);
|
||||
}
|
||||
|
||||
@@ -1163,7 +1162,7 @@ bool RenderableBillboardsCloud::readSpeckFile() {
|
||||
// The beginning of the speck file has a header that either contains comments
|
||||
// (signaled by a preceding '#') or information about the structure of the file
|
||||
// (signaled by the keywords 'datavar', 'texturevar', and 'texture')
|
||||
std::string line = "";
|
||||
std::string line;
|
||||
while (true) {
|
||||
std::streampos position = file.tellg();
|
||||
std::getline(file, line);
|
||||
@@ -1253,7 +1252,7 @@ bool RenderableBillboardsCloud::readColorMapFile() {
|
||||
// The beginning of the speck file has a header that either contains comments
|
||||
// (signaled by a preceding '#') or information about the structure of the file
|
||||
// (signaled by the keywords 'datavar', 'texturevar', and 'texture')
|
||||
std::string line = "";
|
||||
std::string line;
|
||||
while (true) {
|
||||
// std::streampos position = file.tellg();
|
||||
std::getline(file, line);
|
||||
@@ -1300,7 +1299,7 @@ bool RenderableBillboardsCloud::readLabelFile() {
|
||||
// The beginning of the speck file has a header that either contains comments
|
||||
// (signaled by a preceding '#') or information about the structure of the file
|
||||
// (signaled by the keywords 'datavar', 'texturevar', and 'texture')
|
||||
std::string line = "";
|
||||
std::string line;
|
||||
while (true) {
|
||||
std::streampos position = file.tellg();
|
||||
std::getline(file, line);
|
||||
@@ -1375,7 +1374,7 @@ bool RenderableBillboardsCloud::readLabelFile() {
|
||||
glm::vec3 transformedPos = glm::vec3(
|
||||
_transformationMatrix * glm::dvec4(position, 1.0)
|
||||
);
|
||||
_labelData.push_back(std::make_pair(transformedPos, label));
|
||||
_labelData.emplace_back(std::make_pair(transformedPos, label));
|
||||
} while (!file.eof());
|
||||
|
||||
return true;
|
||||
@@ -1411,12 +1410,10 @@ bool RenderableBillboardsCloud::loadCachedFile(const std::string& file) {
|
||||
for (int i = 0; i < nItems; ++i) {
|
||||
int32_t keySize = 0;
|
||||
fileStream.read(reinterpret_cast<char*>(&keySize), sizeof(int32_t));
|
||||
std::string key;
|
||||
for (int c = 0; c < keySize; ++c) {
|
||||
char t;
|
||||
fileStream.read(&t, sizeof(char));
|
||||
key.append(1, t);
|
||||
}
|
||||
std::vector<char> buffer(keySize);
|
||||
fileStream.read(buffer.data(), keySize);
|
||||
|
||||
std::string key(buffer.begin(), buffer.end());
|
||||
int32_t value = 0;
|
||||
fileStream.read(reinterpret_cast<char*>(&value), sizeof(int32_t));
|
||||
|
||||
@@ -1461,23 +1458,21 @@ bool RenderableBillboardsCloud::saveCachedFile(const std::string& file) const {
|
||||
int32_t nItems = static_cast<int32_t>(_variableDataPositionMap.size());
|
||||
fileStream.write(reinterpret_cast<const char*>(&nItems), sizeof(int32_t));
|
||||
|
||||
for (auto pair : _variableDataPositionMap) {
|
||||
for (const std::pair<const std::string, int>& pair :
|
||||
_variableDataPositionMap)
|
||||
{
|
||||
int32_t keySize = static_cast<int32_t>(pair.first.size());
|
||||
fileStream.write(
|
||||
reinterpret_cast<const char*>(&keySize),
|
||||
sizeof(int32_t)
|
||||
);
|
||||
for (size_t c = 0; c < pair.first.size(); ++c) {
|
||||
char keyChar = static_cast<int32_t>(pair.first[c]);
|
||||
fileStream.write(&keyChar, sizeof(char));
|
||||
}
|
||||
fileStream.write(pair.first.data(), keySize);
|
||||
int32_t value = static_cast<int32_t>(pair.second);
|
||||
fileStream.write(reinterpret_cast<const char*>(&value), sizeof(int32_t));
|
||||
}
|
||||
}
|
||||
|
||||
bool success = fileStream.good();
|
||||
return success;
|
||||
return fileStream.good();
|
||||
}
|
||||
else {
|
||||
LERROR(fmt::format("Error opening file '{}' for save cache file", file));
|
||||
@@ -1532,8 +1527,9 @@ void RenderableBillboardsCloud::createDataSlice() {
|
||||
int c = static_cast<int>(colorBins.size() - 1);
|
||||
while (variableColor < colorBins[c]) {
|
||||
--c;
|
||||
if (c == 0)
|
||||
if (c == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int colorIndex =
|
||||
|
||||
@@ -131,8 +131,8 @@ private:
|
||||
// DEBUG:
|
||||
properties::OptionProperty _renderOption;
|
||||
|
||||
ghoul::opengl::Texture* _polygonTexture;
|
||||
ghoul::opengl::Texture* _spriteTexture;
|
||||
ghoul::opengl::Texture* _polygonTexture = nullptr;
|
||||
ghoul::opengl::Texture* _spriteTexture = nullptr;
|
||||
ghoul::opengl::ProgramObject* _program = nullptr;
|
||||
ghoul::opengl::ProgramObject* _renderToPolygonProgram = nullptr;
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
#include <array>
|
||||
#include <fstream>
|
||||
#include <stdint.h>
|
||||
#include <cstdint>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "RenderableDUMeshes";
|
||||
@@ -268,8 +268,7 @@ RenderableDUMeshes::RenderableDUMeshes(const ghoul::Dictionary& dictionary)
|
||||
if (dictionary.hasKey(KeyFile)) {
|
||||
_speckFile = absPath(dictionary.value<std::string>(KeyFile));
|
||||
_hasSpeckFile = true;
|
||||
_drawElements.onChange([&]() {
|
||||
_hasSpeckFile = _hasSpeckFile == true ? false : true; });
|
||||
_drawElements.onChange([&]() { _hasSpeckFile = !_hasSpeckFile; });
|
||||
addProperty(_drawElements);
|
||||
}
|
||||
|
||||
@@ -706,7 +705,7 @@ bool RenderableDUMeshes::readSpeckFile() {
|
||||
// The beginning of the speck file has a header that either contains comments
|
||||
// (signaled by a preceding '#') or information about the structure of the file
|
||||
// (signaled by the keywords 'datavar', 'texturevar', and 'texture')
|
||||
std::string line = "";
|
||||
std::string line;
|
||||
while (true) {
|
||||
std::streampos position = file.tellg();
|
||||
std::getline(file, line);
|
||||
@@ -827,7 +826,7 @@ bool RenderableDUMeshes::readLabelFile() {
|
||||
// The beginning of the speck file has a header that either contains comments
|
||||
// (signaled by a preceding '#') or information about the structure of the file
|
||||
// (signaled by the keywords 'datavar', 'texturevar', and 'texture')
|
||||
std::string line = "";
|
||||
std::string line;
|
||||
while (true) {
|
||||
std::streampos position = file.tellg();
|
||||
std::getline(file, line);
|
||||
@@ -899,7 +898,7 @@ bool RenderableDUMeshes::readLabelFile() {
|
||||
glm::vec3 transformedPos = glm::vec3(
|
||||
_transformationMatrix * glm::dvec4(position, 1.0)
|
||||
);
|
||||
_labelData.push_back(std::make_pair(transformedPos, label));
|
||||
_labelData.emplace_back(std::make_pair(transformedPos, label));
|
||||
|
||||
} while (!file.eof());
|
||||
|
||||
|
||||
@@ -873,7 +873,7 @@ bool RenderablePlanesCloud::readSpeckFile() {
|
||||
// The beginning of the speck file has a header that either contains comments
|
||||
// (signaled by a preceding '#') or information about the structure of the file
|
||||
// (signaled by the keywords 'datavar', 'texturevar', and 'texture')
|
||||
std::string line = "";
|
||||
std::string line;
|
||||
while (true) {
|
||||
std::streampos position = file.tellg();
|
||||
std::getline(file, line);
|
||||
@@ -950,7 +950,7 @@ bool RenderablePlanesCloud::readSpeckFile() {
|
||||
if (line.substr(0, 8) == "texture ") {
|
||||
std::stringstream str(line);
|
||||
|
||||
std::size_t found = line.find("-");
|
||||
std::size_t found = line.find('-');
|
||||
|
||||
int textureIndex = 0;
|
||||
|
||||
@@ -1055,7 +1055,7 @@ bool RenderablePlanesCloud::readLabelFile() {
|
||||
// The beginning of the speck file has a header that either contains comments
|
||||
// (signaled by a preceding '#') or information about the structure of the file
|
||||
// (signaled by the keywords 'datavar', 'texturevar', and 'texture')
|
||||
std::string line = "";
|
||||
std::string line;
|
||||
while (true) {
|
||||
std::streampos position = file.tellg();
|
||||
std::getline(file, line);
|
||||
@@ -1125,7 +1125,7 @@ bool RenderablePlanesCloud::readLabelFile() {
|
||||
glm::vec3 transformedPos = glm::vec3(
|
||||
_transformationMatrix * glm::dvec4(position, 1.0)
|
||||
);
|
||||
_labelData.push_back(std::make_pair(transformedPos, label));
|
||||
_labelData.emplace_back(std::make_pair(transformedPos, label));
|
||||
|
||||
} while (!file.eof());
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ private:
|
||||
const glm::dmat4& projectionMatrix, float fadeInVariable);
|
||||
void renderLabels(const RenderData& data,
|
||||
const glm::dmat4& modelViewProjectionMatrix, const glm::dvec3& orthoRight,
|
||||
const glm::dvec3& orthoUp, float fadeInVarible);
|
||||
const glm::dvec3& orthoUp, float fadeInVariable);
|
||||
|
||||
bool loadData();
|
||||
bool loadTextures();
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
#include <array>
|
||||
#include <fstream>
|
||||
#include <locale>
|
||||
#include <stdint.h>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace {
|
||||
@@ -406,7 +406,7 @@ void RenderablePoints::update(const UpdateData&) {
|
||||
if (_hasSpriteTexture && _spriteTextureIsDirty) {
|
||||
LDEBUG("Reloading Sprite Texture");
|
||||
_spriteTexture = nullptr;
|
||||
if (_spriteTexturePath.value() != "") {
|
||||
if (!_spriteTexturePath.value().empty()) {
|
||||
_spriteTexture = ghoul::io::TextureReader::ref().loadTexture(
|
||||
absPath(_spriteTexturePath)
|
||||
);
|
||||
@@ -489,7 +489,7 @@ bool RenderablePoints::readSpeckFile() {
|
||||
// The beginning of the speck file has a header that either contains comments
|
||||
// (signaled by a preceding '#') or information about the structure of the file
|
||||
// (signaled by the keywords 'datavar', 'texturevar', and 'texture')
|
||||
std::string line = "";
|
||||
std::string line;
|
||||
while (true) {
|
||||
std::streampos position = file.tellg();
|
||||
std::getline(file, line);
|
||||
@@ -556,7 +556,7 @@ bool RenderablePoints::readColorMapFile() {
|
||||
// The beginning of the speck file has a header that either contains comments
|
||||
// (signaled by a preceding '#') or information about the structure of the file
|
||||
// (signaled by the keywords 'datavar', 'texturevar', and 'texture')
|
||||
std::string line = "";
|
||||
std::string line;
|
||||
while (true) {
|
||||
// std::streampos position = file.tellg();
|
||||
std::getline(file, line);
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
##########################################################################################
|
||||
# #
|
||||
# OpenSpace #
|
||||
# #
|
||||
# Copyright (c) 2014-2018 #
|
||||
# #
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy of this #
|
||||
# software and associated documentation files (the "Software"), to deal in the Software #
|
||||
# without restriction, including without limitation the rights to use, copy, modify, #
|
||||
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to #
|
||||
# permit persons to whom the Software is furnished to do so, subject to the following #
|
||||
# conditions: #
|
||||
# #
|
||||
# The above copyright notice and this permission notice shall be included in all copies #
|
||||
# or substantial portions of the Software. #
|
||||
# #
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, #
|
||||
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A #
|
||||
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT #
|
||||
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF #
|
||||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE #
|
||||
# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #
|
||||
##########################################################################################
|
||||
|
||||
include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake)
|
||||
include(${GHOUL_BASE_DIR}/support/cmake/handle_external_library.cmake)
|
||||
|
||||
set(HEADER_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/fitsfilereadermodule.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/fitsfilereader.h
|
||||
)
|
||||
source_group("Header Files" FILES ${HEADER_FILES})
|
||||
|
||||
set(SOURCE_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/fitsfilereadermodule.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/fitsfilereader.cpp
|
||||
)
|
||||
source_group("Source Files" FILES ${SOURCE_FILES})
|
||||
|
||||
create_new_module(
|
||||
"FitsFileReader"
|
||||
fitsfilereader
|
||||
${HEADER_FILES}
|
||||
${SOURCE_FILES}
|
||||
)
|
||||
|
||||
# Set root directories for external libraries.
|
||||
set(CFITSIO_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ext/cfitsio/")
|
||||
set(CCFITS_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ext/CCfits/")
|
||||
set(INCLUDES_FOR_TARGET ${CCFITS_ROOT_DIR} "${CCFITS_ROOT_DIR}/../" ${CFITSIO_ROOT_DIR})
|
||||
set(MODULE_NAME openspace-module-fitsfilereader)
|
||||
|
||||
# CCfits is dependent on cfitsio, let it handle the internal linking
|
||||
add_subdirectory(${CFITSIO_ROOT_DIR})
|
||||
set_folder_location(cfitsio "External")
|
||||
|
||||
add_subdirectory(${CCFITS_ROOT_DIR})
|
||||
set_folder_location(CCfits "External")
|
||||
|
||||
|
||||
TARGET_INCLUDE_DIRECTORIES(${MODULE_NAME} SYSTEM PUBLIC ${INCLUDES_FOR_TARGET})
|
||||
TARGET_LINK_LIBRARIES(${MODULE_NAME} CCfits)
|
||||
Submodule
+1
Submodule modules/fitsfilereader/ext/CCfits added at 48400ae262
Submodule
+1
Submodule modules/fitsfilereader/ext/cfitsio added at b267f17603
@@ -0,0 +1,31 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/fitsfilereader/fitsfilereadermodule.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
FitsFileReaderModule::FitsFileReaderModule() : OpenSpaceModule(Name) {}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -0,0 +1,41 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_FITSFILEREADER___FITSFILEREADERMODULE___H__
|
||||
#define __OPENSPACE_MODULE_FITSFILEREADER___FITSFILEREADERMODULE___H__
|
||||
|
||||
#include <openspace/util/openspacemodule.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class FitsFileReaderModule : public OpenSpaceModule {
|
||||
public:
|
||||
constexpr static const char* Name = "FitsFileReader";
|
||||
|
||||
FitsFileReaderModule();
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_FITSFILEREADER___FITSFILEREADERMODULE___H__
|
||||
@@ -0,0 +1,116 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_FITSFILEREADER___FITSFILEREADER___H__
|
||||
#define __OPENSPACE_MODULE_FITSFILEREADER___FITSFILEREADER___H__
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
#include <valarray>
|
||||
#include <vector>
|
||||
|
||||
namespace CCfits {
|
||||
class FITS;
|
||||
class PHDU;
|
||||
class ExtHDU;
|
||||
} // namespace CCfits
|
||||
|
||||
namespace ghoul::opengl { class Texture; }
|
||||
|
||||
namespace openspace {
|
||||
|
||||
template<typename T>
|
||||
struct ImageData {
|
||||
std::valarray<T> contents;
|
||||
long int width;
|
||||
long int height;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct TableData {
|
||||
std::unordered_map<std::string, std::vector<T>> contents;
|
||||
int readRows;
|
||||
long int optimalRowsize;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
class FitsFileReader {
|
||||
public:
|
||||
FitsFileReader(bool verboseMode);
|
||||
~FitsFileReader();
|
||||
|
||||
template<typename T>
|
||||
std::shared_ptr<ImageData<T>> readImage(const std::string& path);
|
||||
|
||||
template<typename T>
|
||||
std::shared_ptr<std::unordered_map<std::string, T>> readHeader(
|
||||
std::vector<std::string>& keywords);
|
||||
template<typename T>
|
||||
std::shared_ptr<T> readHeaderValue(const std::string key);
|
||||
|
||||
/**
|
||||
* Read specified table columns from fits file.
|
||||
* If <code>readAll</code> is set to true the entire table will be read before the
|
||||
* selected columns, which makes the function take a lot longer if it's a big file.
|
||||
* If no HDU index is given the current Extension HDU will be read from.
|
||||
*/
|
||||
template<typename T>
|
||||
std::shared_ptr<TableData<T>> readTable(std::string& path,
|
||||
const std::vector<std::string>& columnNames, int startRow = 1, int endRow = 10,
|
||||
int hduIdx = 1, bool readAll = false);
|
||||
|
||||
/**
|
||||
* Reads a single FITS file with pre-defined columns (defined for Viennas TGAS-file).
|
||||
* Returns a vector with all read stars with <code>nValuesPerStar</code>.
|
||||
* If additional columns are given by <code>filterColumnNames</code>, they will be
|
||||
* read but it will slow doen the reading tremendously.
|
||||
*/
|
||||
std::vector<float> readFitsFile(std::string filePath, int& nValuesPerStar,
|
||||
int firstRow, int lastRow, std::vector<std::string> filterColumnNames,
|
||||
int multiplier = 1);
|
||||
|
||||
/**
|
||||
* Reads a single SPECK file and returns a vector with <code>nRenderValues</code>
|
||||
* per star. Reads data in pre-defined order based on AMNH's star data files.
|
||||
*/
|
||||
std::vector<float> readSpeckFile(const std::string& filePath, int& nRenderValues);
|
||||
|
||||
private:
|
||||
std::unique_ptr<CCfits::FITS> _infile;
|
||||
bool _verboseMode;
|
||||
|
||||
bool isPrimaryHDU();
|
||||
template<typename T>
|
||||
const std::shared_ptr<ImageData<T>> readImageInternal(CCfits::PHDU& image);
|
||||
template<typename T>
|
||||
const std::shared_ptr<ImageData<T>> readImageInternal(CCfits::ExtHDU& image);
|
||||
|
||||
mutable std::mutex _mutex;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_FITSFILEREADER___FITSFILEREADER___H__
|
||||
@@ -0,0 +1,669 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/fitsfilereader/include/fitsfilereader.h>
|
||||
|
||||
#include <openspace/util/distanceconversion.h>
|
||||
#include <ghoul/fmt.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
#include <CCfits>
|
||||
#include <fstream>
|
||||
|
||||
using namespace CCfits;
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "FitsFileReader";
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
FitsFileReader::FitsFileReader(bool verboseMode) {
|
||||
_verboseMode = verboseMode;
|
||||
FITS::setVerboseMode(_verboseMode);
|
||||
}
|
||||
|
||||
FitsFileReader::~FitsFileReader() {
|
||||
if (_infile) {
|
||||
_infile->destroy();
|
||||
_infile = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool FitsFileReader::isPrimaryHDU() {
|
||||
return _infile->extension().empty();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::shared_ptr<ImageData<T>> FitsFileReader::readImage(const std::string& path) {
|
||||
try {
|
||||
_infile = std::make_unique<FITS>(path, Read, true);
|
||||
// Primary HDU Object
|
||||
if (isPrimaryHDU()) {
|
||||
return readImageInternal<T>(_infile->pHDU());
|
||||
}
|
||||
// Extension HDU Object
|
||||
return readImageInternal<T>(_infile->currentExtension());
|
||||
} catch (const FitsException& e){
|
||||
LERROR("Could not read FITS image from table. " + e.message() );
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::shared_ptr<std::unordered_map<std::string, T>> FitsFileReader::readHeader(
|
||||
std::vector<std::string>& keywords)
|
||||
{
|
||||
try {
|
||||
HDU& image = isPrimaryHDU() ?
|
||||
static_cast<HDU&>(_infile->pHDU()) :
|
||||
static_cast<HDU&>(_infile->currentExtension());
|
||||
|
||||
std::vector<T> values;
|
||||
image.readKeys(keywords, values);
|
||||
|
||||
if (values.size() != keywords.size()) {
|
||||
LERROR("Number of keywords does not match number of values");
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, T> result;
|
||||
std::transform(
|
||||
keywords.begin(),
|
||||
keywords.end(),
|
||||
values.begin(),
|
||||
std::inserter(
|
||||
result,
|
||||
result.end()
|
||||
),
|
||||
[](std::string key, T value) { return std::make_pair(key, value); }
|
||||
);
|
||||
return std::make_shared<std::unordered_map<std::string, T>>(std::move(result));
|
||||
} catch (const FitsException& e) {
|
||||
LERROR("Could not read FITS header. " + e.message() );
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::shared_ptr<T> FitsFileReader::readHeaderValue(const std::string key) {
|
||||
try {
|
||||
HDU& image = isPrimaryHDU() ?
|
||||
static_cast<HDU&>(_infile->pHDU()) :
|
||||
static_cast<HDU&>(_infile->currentExtension());
|
||||
|
||||
T value;
|
||||
image.readKey(key, value);
|
||||
return std::make_unique<T>(value);
|
||||
} catch (FitsException& e) {
|
||||
LERROR("Could not read FITS key. " + e.message() );
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::shared_ptr<TableData<T>> FitsFileReader::readTable(std::string& path,
|
||||
const std::vector<std::string>& columnNames,
|
||||
int startRow,
|
||||
int endRow,
|
||||
int hduIdx,
|
||||
bool readAll)
|
||||
{
|
||||
// We need to lock reading when using multithreads because CCfits can't handle
|
||||
// multiple I/O drivers.
|
||||
std::lock_guard g(_mutex);
|
||||
|
||||
try {
|
||||
_infile = std::make_unique<FITS>(path, Read, readAll);
|
||||
|
||||
// Make sure FITS file is not a Primary HDU Object (aka an image).
|
||||
if (!isPrimaryHDU()) {
|
||||
ExtHDU& table = _infile->extension(hduIdx);
|
||||
int numCols = columnNames.size();
|
||||
int numRowsInTable = table.rows();
|
||||
std::unordered_map<string, std::vector<T>> contents;
|
||||
//LINFO("Read file: " + _infile->name());
|
||||
|
||||
int firstRow = std::max(startRow, 1);
|
||||
|
||||
if (endRow < firstRow) {
|
||||
endRow = numRowsInTable;
|
||||
}
|
||||
|
||||
for (int i = 0; i < numCols; ++i) {
|
||||
std::vector<T> columnData;
|
||||
//LINFO("Read column: " + columnNames[i]);
|
||||
table.column(columnNames[i]).read(columnData, firstRow, endRow);
|
||||
contents[columnNames[i]] = columnData;
|
||||
}
|
||||
|
||||
// Create TableData object of table contents.
|
||||
TableData<T> loadedTable = {
|
||||
std::move(contents),
|
||||
static_cast<int>(table.rows()),
|
||||
table.getRowsize(),
|
||||
table.name()
|
||||
};
|
||||
|
||||
return std::make_shared<TableData<T>>(loadedTable);
|
||||
}
|
||||
}
|
||||
catch (FitsException& e) {
|
||||
LERROR(fmt::format(
|
||||
"Could not read FITS table from file '{}'. Make sure it's not an image file.",
|
||||
e.message()
|
||||
));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<float> FitsFileReader::readFitsFile(std::string filePath, int& nValuesPerStar,
|
||||
int firstRow, int lastRow,
|
||||
std::vector<std::string> filterColumnNames,
|
||||
int multiplier)
|
||||
{
|
||||
std::vector<float> fullData;
|
||||
srand(1234567890);
|
||||
if (firstRow <= 0) {
|
||||
firstRow = 1;
|
||||
}
|
||||
|
||||
// Define what columns to read.
|
||||
std::vector<std::string> allColumnNames = {
|
||||
"Position_X",
|
||||
"Position_Y",
|
||||
"Position_Z",
|
||||
"Velocity_X",
|
||||
"Velocity_Y",
|
||||
"Velocity_Z",
|
||||
"Gaia_Parallax",
|
||||
"Gaia_G_Mag",
|
||||
"Tycho_B_Mag",
|
||||
"Tycho_V_Mag",
|
||||
"Gaia_Parallax_Err",
|
||||
"Gaia_Proper_Motion_RA",
|
||||
"Gaia_Proper_Motion_RA_Err",
|
||||
"Gaia_Proper_Motion_Dec",
|
||||
"Gaia_Proper_Motion_Dec_Err",
|
||||
"Tycho_B_Mag_Err",
|
||||
"Tycho_V_Mag_Err"
|
||||
};
|
||||
|
||||
// Append additional filter parameters to default rendering parameters.
|
||||
allColumnNames.insert(
|
||||
allColumnNames.end(),
|
||||
filterColumnNames.begin(),
|
||||
filterColumnNames.end()
|
||||
);
|
||||
|
||||
std::string allNames = "Columns to read: \n";
|
||||
for (const std::string& colName : allColumnNames) {
|
||||
allNames += colName + "\n";
|
||||
}
|
||||
LINFO(allNames);
|
||||
|
||||
// Read columns from FITS file. If rows aren't specified then full table will be read.
|
||||
std::shared_ptr<TableData<float>> table = readTable<float>(
|
||||
filePath,
|
||||
allColumnNames,
|
||||
firstRow,
|
||||
lastRow
|
||||
);
|
||||
|
||||
if (!table) {
|
||||
throw ghoul::RuntimeError(fmt::format("Failed to open Fits file '{}'", filePath));
|
||||
}
|
||||
|
||||
int nStars = table->readRows - firstRow + 1;
|
||||
|
||||
int nNullArr = 0;
|
||||
size_t nColumnsRead = allColumnNames.size();
|
||||
size_t defaultCols = 17; // Number of columns that are copied by predefined code.
|
||||
if (nColumnsRead != defaultCols) {
|
||||
LINFO("Additional columns will be read! Consider add column in code for "
|
||||
"significant speedup!");
|
||||
}
|
||||
// Declare how many values to save per star
|
||||
nValuesPerStar = nColumnsRead + 1; // +1 for B-V color value.
|
||||
|
||||
// Copy columns to local variables.
|
||||
std::unordered_map<std::string, std::vector<float>>& tableContent = table->contents;
|
||||
|
||||
// Default render parameters!
|
||||
std::vector<float> posXcol = std::move(tableContent[allColumnNames[0]]);
|
||||
std::vector<float> posYcol = std::move(tableContent[allColumnNames[1]]);
|
||||
std::vector<float> posZcol = std::move(tableContent[allColumnNames[2]]);
|
||||
std::vector<float> velXcol = std::move(tableContent[allColumnNames[3]]);
|
||||
std::vector<float> velYcol = std::move(tableContent[allColumnNames[4]]);
|
||||
std::vector<float> velZcol = std::move(tableContent[allColumnNames[5]]);
|
||||
std::vector<float> parallax = std::move(tableContent[allColumnNames[6]]);
|
||||
std::vector<float> magCol = std::move(tableContent[allColumnNames[7]]);
|
||||
std::vector<float> tycho_b = std::move(tableContent[allColumnNames[8]]);
|
||||
std::vector<float> tycho_v = std::move(tableContent[allColumnNames[9]]);
|
||||
|
||||
// Default filter parameters
|
||||
// Additional filter parameters are handled as well but slows down reading
|
||||
std::vector<float> parallax_err = std::move(tableContent[allColumnNames[10]]);
|
||||
std::vector<float> pr_mot_ra = std::move(tableContent[allColumnNames[11]]);
|
||||
std::vector<float> pr_mot_ra_err = std::move(tableContent[allColumnNames[12]]);
|
||||
std::vector<float> pr_mot_dec = std::move(tableContent[allColumnNames[13]]);
|
||||
std::vector<float> pr_mot_dec_err = std::move(tableContent[allColumnNames[14]]);
|
||||
std::vector<float> tycho_b_err = std::move(tableContent[allColumnNames[15]]);
|
||||
std::vector<float> tycho_v_err = std::move(tableContent[allColumnNames[16]]);
|
||||
|
||||
// Construct data array. OBS: ORDERING IS IMPORTANT! This is where slicing happens.
|
||||
for (int i = 0; i < nStars * multiplier; ++i) {
|
||||
std::vector<float> values(nValuesPerStar);
|
||||
size_t idx = 0;
|
||||
|
||||
// Default order for rendering:
|
||||
// Position [X, Y, Z]
|
||||
// Absolute Magnitude
|
||||
// B-V Color
|
||||
// Velocity [X, Y, Z]
|
||||
|
||||
// Store positions.
|
||||
values[idx++] = posXcol[i % nStars];
|
||||
values[idx++] = posYcol[i % nStars];
|
||||
values[idx++] = posZcol[i % nStars];
|
||||
|
||||
// Return early if star doesn't have a measured position.
|
||||
if (values[0] == -999 && values[1] == -999 && values[2] == -999) {
|
||||
nNullArr++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Store color values.
|
||||
values[idx++] = magCol[i % nStars] == -999 ? 20.f : magCol[i % nStars];
|
||||
values[idx++] = tycho_b[i % nStars] - tycho_v[i % nStars];
|
||||
|
||||
// Store velocity. Convert it to m/s with help by parallax.
|
||||
values[idx++] = convertMasPerYearToMeterPerSecond(
|
||||
velXcol[i % nStars],
|
||||
parallax[i % nStars]
|
||||
);
|
||||
values[idx++] = convertMasPerYearToMeterPerSecond(
|
||||
velYcol[i % nStars],
|
||||
parallax[i % nStars]
|
||||
);
|
||||
values[idx++] = convertMasPerYearToMeterPerSecond(
|
||||
velZcol[i % nStars],
|
||||
parallax[i % nStars]
|
||||
);
|
||||
|
||||
// Store additional parameters to filter by.
|
||||
values[idx++] = parallax[i % nStars];
|
||||
values[idx++] = parallax_err[i % nStars];
|
||||
values[idx++] = pr_mot_ra[i % nStars];
|
||||
values[idx++] = pr_mot_ra_err[i % nStars];
|
||||
values[idx++] = pr_mot_dec[i % nStars];
|
||||
values[idx++] = pr_mot_dec_err[i % nStars];
|
||||
values[idx++] = tycho_b[i % nStars];
|
||||
values[idx++] = tycho_b_err[i % nStars];
|
||||
values[idx++] = tycho_v[i % nStars];
|
||||
values[idx++] = tycho_v_err[i % nStars];
|
||||
|
||||
// Read extra columns, if any. This will slow down the sorting tremendously!
|
||||
for (size_t col = defaultCols; col < nColumnsRead; ++col) {
|
||||
std::vector<float> vecData = std::move(tableContent[allColumnNames[col]]);
|
||||
values[idx++] = vecData[i];
|
||||
}
|
||||
|
||||
for (size_t j = 0; j < nValuesPerStar; ++j) {
|
||||
// The astronomers in Vienna use -999 as default value. Change it to 0.
|
||||
if (values[j] == -999) {
|
||||
values[j] = 0.f;
|
||||
}
|
||||
else if (multiplier > 1) {
|
||||
values[j] *= static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
fullData.insert(fullData.end(), values.begin(), values.end());
|
||||
}
|
||||
|
||||
// Define what columns to read.
|
||||
/*auto allColumnNames = std::vector<std::string>({
|
||||
"ra",
|
||||
"dec",
|
||||
"parallax",
|
||||
"pmra",
|
||||
"pmdec",
|
||||
"phot_g_mean_mag",
|
||||
"phot_bp_mean_mag",
|
||||
"phot_rp_mean_mag",
|
||||
"radial_velocity",
|
||||
});
|
||||
// Append additional filter parameters to default rendering parameters.
|
||||
allColumnNames.insert(allColumnNames.end(), filterColumnNames.begin(),
|
||||
filterColumnNames.end());
|
||||
|
||||
std::string allNames = "Columns to read: \n";
|
||||
for (auto colName : allColumnNames) {
|
||||
allNames += colName + "\n";
|
||||
}
|
||||
LINFO(allNames);
|
||||
|
||||
// Read columns from FITS file. If rows aren't specified then full table will be read.
|
||||
auto table = readTable<float>(filePath, allColumnNames, firstRow, lastRow);
|
||||
|
||||
if (!table) {
|
||||
throw ghoul::RuntimeError(fmt::format("Failed to open Fits file '{}'", filePath));
|
||||
}
|
||||
|
||||
int nStars = table->readRows - firstRow + 1;
|
||||
|
||||
int nNullArr = 0;
|
||||
size_t nColumnsRead = allColumnNames.size();
|
||||
size_t defaultCols = 9; // Number of columns that are copied by predefined code.
|
||||
if (nColumnsRead != defaultCols) {
|
||||
LINFO("Additional columns will be read! Consider add column in code for "
|
||||
"significant speedup!");
|
||||
}
|
||||
// Declare how many values to save per star
|
||||
nValuesPerStar = 8;
|
||||
|
||||
// Copy columns to local variables.
|
||||
std::unordered_map<std::string, std::vector<float>>& tableContent = table->contents;
|
||||
|
||||
std::vector<float> ra = std::move(tableContent[allColumnNames[0]]);
|
||||
std::vector<float> dec = std::move(tableContent[allColumnNames[1]]);
|
||||
std::vector<float> parallax = std::move(tableContent[allColumnNames[2]]);
|
||||
std::vector<float> pmra = std::move(tableContent[allColumnNames[3]]);
|
||||
std::vector<float> pmdec = std::move(tableContent[allColumnNames[4]]);
|
||||
std::vector<float> meanMagG = std::move(tableContent[allColumnNames[5]]);
|
||||
std::vector<float> meanMagBp = std::move(tableContent[allColumnNames[6]]);
|
||||
std::vector<float> meanMagRp = std::move(tableContent[allColumnNames[7]]);
|
||||
std::vector<float> radial_vel = std::move(tableContent[allColumnNames[8]]);
|
||||
|
||||
// Construct data array. OBS: ORDERING IS IMPORTANT! This is where slicing happens.
|
||||
for (int i = 0; i < nStars; ++i) {
|
||||
std::vector<float> values(nValuesPerStar);
|
||||
size_t idx = 0;
|
||||
|
||||
// Default order for rendering:
|
||||
// Position [X, Y, Z]
|
||||
// Mean G-band Magnitude
|
||||
// Bp-Rp Color
|
||||
// Velocity [X, Y, Z]
|
||||
|
||||
// Return early if star doesn't have a measured position.
|
||||
if (std::isnan(ra[i]) || std::isnan(dec[i])) {
|
||||
nNullArr++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Store positions. Set to a default distance if parallax doesn't exist.
|
||||
float radiusInKiloParsec = 9.0;
|
||||
if (!std::isnan(parallax[i])) {
|
||||
// Parallax is in milliArcseconds -> distance in kiloParsecs
|
||||
// https://gea.esac.esa.int/archive/documentation/GDR2/Gaia_archive/
|
||||
// chap_datamodel/sec_dm_main_tables/ssec_dm_gaia_source.html
|
||||
radiusInKiloParsec = 1.0 / parallax[i];
|
||||
}
|
||||
// Convert to Galactic Coordinates from Galactic Lon & Lat.
|
||||
// https://gea.esac.esa.int/archive/documentation/GDR2/Data_processing/
|
||||
// chap_cu3ast/sec_cu3ast_intro/ssec_cu3ast_intro_tansforms.html#SSS1
|
||||
//values[idx++] = radiusInKiloParsec * cos(glm::radians(b_latitude[i])) *
|
||||
//cos(glm::radians(l_longitude[i])); // Pos X
|
||||
//values[idx++] = radiusInKiloParsec * cos(glm::radians(b_latitude[i])) *
|
||||
//sin(glm::radians(l_longitude[i])); // Pos Y
|
||||
//values[idx++] = radiusInKiloParsec * sin(glm::radians(b_latitude[i])); // Pos Z
|
||||
|
||||
|
||||
// Convert ICRS Equatorial Ra and Dec to Galactic latitude and longitude.
|
||||
glm::mat3 aPrimG = glm::mat3(
|
||||
// Col 0
|
||||
glm::vec3(-0.0548755604162154, 0.4941094278755837, -0.8676661490190047),
|
||||
// Col 1
|
||||
glm::vec3(-0.8734370902348850, -0.4448296299600112, -0.1980763734312015),
|
||||
// Col 2
|
||||
glm::vec3(-0.4838350155487132, 0.7469822444972189, 0.4559837761750669)
|
||||
);
|
||||
glm::vec3 rICRS = glm::vec3(
|
||||
cos(glm::radians(ra[i])) * cos(glm::radians(dec[i])),
|
||||
sin(glm::radians(ra[i])) * cos(glm::radians(dec[i])),
|
||||
sin(glm::radians(dec[i]))
|
||||
);
|
||||
glm::vec3 rGal = aPrimG * rICRS;
|
||||
values[idx++] = radiusInKiloParsec * rGal.x; // Pos X
|
||||
values[idx++] = radiusInKiloParsec * rGal.y; // Pos Y
|
||||
values[idx++] = radiusInKiloParsec * rGal.z; // Pos Z
|
||||
|
||||
// Store magnitude render value. (Set default to high mag = low brightness)
|
||||
values[idx++] = std::isnan(meanMagG[i]) ? 20.f : meanMagG[i]; // Mean G-band Mag
|
||||
|
||||
// Store color render value. (Default value is bluish stars)
|
||||
values[idx++] = std::isnan(meanMagBp[i]) && std::isnan(meanMagRp[i]) ? 0.f
|
||||
: meanMagBp[i] - meanMagRp[i]; // Bp-Rp Color
|
||||
|
||||
// Store velocity.
|
||||
if (std::isnan(pmra[i])) pmra[i] = 0.f;
|
||||
if (std::isnan(pmdec[i])) pmdec[i] = 0.f;
|
||||
|
||||
// Convert Proper Motion from ICRS [Ra,Dec] to Galactic Tanget Vector [l,b].
|
||||
glm::vec3 uICRS = glm::vec3(
|
||||
-sin(glm::radians(ra[i])) * pmra[i] -
|
||||
cos(glm::radians(ra[i])) * sin(glm::radians(dec[i])) * pmdec[i],
|
||||
cos(glm::radians(ra[i])) * pmra[i] -
|
||||
sin(glm::radians(ra[i])) * sin(glm::radians(dec[i])) * pmdec[i],
|
||||
cos(glm::radians(dec[i])) * pmdec[i]
|
||||
);
|
||||
glm::vec3 pmVecGal = aPrimG * uICRS;
|
||||
|
||||
// Convert to Tangential vector [m/s] from Proper Motion vector [mas/yr]
|
||||
float tanVelX = 1000.0 * 4.74 * radiusInKiloParsec * pmVecGal.x;
|
||||
float tanVelY = 1000.0 * 4.74 * radiusInKiloParsec * pmVecGal.y;
|
||||
float tanVelZ = 1000.0 * 4.74 * radiusInKiloParsec * pmVecGal.z;
|
||||
|
||||
// Calculate True Space Velocity [m/s] if we have the radial velocity
|
||||
if (!std::isnan(radial_vel[i])) {
|
||||
// Calculate Radial Velocity in the direction of the star.
|
||||
// radial_vel is given in [km/s] -> convert to [m/s].
|
||||
float radVelX = 1000.0 * radial_vel[i] * rGal.x;
|
||||
float radVelY = 1000.0 * radial_vel[i] * rGal.y;
|
||||
float radVelZ = 1000.0 * radial_vel[i] * rGal.z;
|
||||
|
||||
// Use Pythagoras theorem for the final Space Velocity [m/s].
|
||||
values[idx++] = sqrt(pow(radVelX, 2) + pow(tanVelX, 2)); // Vel X [U]
|
||||
values[idx++] = sqrt(pow(radVelY, 2) + pow(tanVelY, 2)); // Vel Y [V]
|
||||
values[idx++] = sqrt(pow(radVelZ, 2) + pow(tanVelZ, 2)); // Vel Z [W]
|
||||
}
|
||||
// Otherwise use the vector [m/s] we got from proper motion.
|
||||
else {
|
||||
radial_vel[i] = 0.f;
|
||||
values[idx++] = tanVelX; // Vel X [U]
|
||||
values[idx++] = tanVelY; // Vel Y [V]
|
||||
values[idx++] = tanVelZ; // Vel Z [W]
|
||||
}
|
||||
|
||||
fullData.insert(fullData.end(), values.begin(), values.end());
|
||||
}*/
|
||||
|
||||
LINFO(fmt::format("{} out of {} read stars were null arrays", nNullArr, nStars));
|
||||
LINFO(fmt::format("Multiplier: {}", multiplier));
|
||||
|
||||
return fullData;
|
||||
}
|
||||
|
||||
std::vector<float> FitsFileReader::readSpeckFile(const std::string& filePath,
|
||||
int& nRenderValues)
|
||||
{
|
||||
std::vector<float> fullData;
|
||||
|
||||
std::ifstream fileStream(filePath);
|
||||
|
||||
if (!fileStream.good()) {
|
||||
LERROR(fmt::format("Failed to open Speck file '{}'", filePath));
|
||||
return fullData;
|
||||
}
|
||||
|
||||
int nValuesPerStar = 0;
|
||||
int nNullArr = 0;
|
||||
size_t nStars = 0;
|
||||
|
||||
// The beginning of the speck file has a header that either contains comments
|
||||
// (signaled by a preceding '#') or information about the structure of the file
|
||||
// (signaled by the keywords 'datavar', 'texturevar', 'texture' and 'maxcomment')
|
||||
std::string line;
|
||||
while (true) {
|
||||
std::streampos position = fileStream.tellg();
|
||||
std::getline(fileStream, line);
|
||||
|
||||
if (line[0] == '#' || line.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line.substr(0, 7) != "datavar" && line.substr(0, 10) != "texturevar" &&
|
||||
line.substr(0, 7) != "texture" && line.substr(0, 10) != "maxcomment")
|
||||
{
|
||||
// We read a line that doesn't belong to the header, so we have to jump back
|
||||
// before the beginning of the current line.
|
||||
fileStream.seekg(position);
|
||||
break;
|
||||
}
|
||||
|
||||
if (line.substr(0, 7) == "datavar") {
|
||||
// datavar lines are structured as follows:
|
||||
// datavar # description
|
||||
// where # is the index of the data variable; so if we repeatedly overwrite
|
||||
// the 'nValues' variable with the latest index, we will end up with the total
|
||||
// number of values (+3 since X Y Z are not counted in the Speck file index)
|
||||
std::stringstream str(line);
|
||||
|
||||
std::string dummy;
|
||||
str >> dummy;
|
||||
str >> nValuesPerStar;
|
||||
nValuesPerStar += 1; // We want the number, but the index is 0 based
|
||||
}
|
||||
}
|
||||
|
||||
nValuesPerStar += 3; // X Y Z are not counted in the Speck file indices
|
||||
|
||||
// Order in DR1 file: DR2 - GaiaGroupMembers:
|
||||
// 0 BVcolor 0 color
|
||||
// 1 lum 1 lum
|
||||
// 2 Vabsmag 2 absmag
|
||||
// 3 Vappmag 3 Gmag
|
||||
// 4 distly 4 distpc
|
||||
// 5 distpcPctErr 5 plx
|
||||
// 6 U 6 ra
|
||||
// 7 V 7 dec
|
||||
// 8 W 8 RadVel
|
||||
// 9 speed 9 Teff
|
||||
// 10 sptypeindex 10 vx
|
||||
// 11 lumclassindex 11 vy
|
||||
// 12 catsource 12 vz
|
||||
// 13 texture 13 speed
|
||||
// 14 texture
|
||||
|
||||
do {
|
||||
std::vector<float> readValues(nValuesPerStar);
|
||||
nStars++;
|
||||
|
||||
std::getline(fileStream, line);
|
||||
std::stringstream str(line);
|
||||
|
||||
// Read values.
|
||||
for (int i = 0; i < nValuesPerStar; ++i) {
|
||||
str >> readValues[i];
|
||||
}
|
||||
|
||||
// Check if star is a nullArray.
|
||||
bool nullArray = true;
|
||||
for (float f : readValues) {
|
||||
if (f != 0.0) {
|
||||
nullArray = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Insert to data if we found some values.
|
||||
if (!nullArray) {
|
||||
// Re-order data here because Octree expects the data in correct order when
|
||||
// read.
|
||||
// Default order for rendering:
|
||||
// Position [X, Y, Z]
|
||||
// Absolute Magnitude
|
||||
// B-V Color
|
||||
// Velocity [X, Y, Z]
|
||||
|
||||
nRenderValues = 8;
|
||||
std::vector<float> renderValues(nRenderValues);
|
||||
|
||||
// Gaia DR1 data from AMNH measures positions in Parsec, but
|
||||
// RenderableGaiaStars expects kiloParsec (because fits file from Vienna had
|
||||
// in kPc).
|
||||
// Thus we need to convert positions twice atm.
|
||||
renderValues[0] = readValues[0] / 1000.0; // PosX
|
||||
renderValues[1] = readValues[1] / 1000.0; // PosY
|
||||
renderValues[2] = readValues[2] / 1000.0; // PosZ
|
||||
renderValues[3] = readValues[6]; // AbsMag
|
||||
renderValues[4] = readValues[3]; // color
|
||||
renderValues[5] = readValues[13] * readValues[16]; // Vel X
|
||||
renderValues[6] = readValues[14] * readValues[16]; // Vel Y
|
||||
renderValues[7] = readValues[15] * readValues[16]; // Vel Z
|
||||
|
||||
fullData.insert(fullData.end(), renderValues.begin(), renderValues.end());
|
||||
}
|
||||
else {
|
||||
nNullArr++;
|
||||
}
|
||||
|
||||
} while (!fileStream.eof());
|
||||
|
||||
LINFO(fmt::format("{} out of {} read stars were null arrays", nNullArr, nStars));
|
||||
|
||||
return fullData;
|
||||
}
|
||||
|
||||
// This is pretty annoying, the read method is not derived from the HDU class
|
||||
// in CCfits - need to explicitly cast to the sub classes to access read
|
||||
template<typename T>
|
||||
const std::shared_ptr<ImageData<T>> FitsFileReader::readImageInternal(ExtHDU& image) {
|
||||
try {
|
||||
std::valarray<T> contents;
|
||||
image.read(contents);
|
||||
ImageData<T> im = { std::move(contents), image.axis(0), image.axis(1) };
|
||||
return std::make_shared<ImageData<T>>(im);
|
||||
} catch (const FitsException& e){
|
||||
LERROR("Could not read FITS image EXTHDU. " + e.message() );
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const std::shared_ptr<ImageData<T>> FitsFileReader::readImageInternal(PHDU& image) {
|
||||
try {
|
||||
std::valarray<T> contents;
|
||||
image.read(contents);
|
||||
ImageData<T> im = { std::move(contents), image.axis(0), image.axis(1) };
|
||||
return std::make_shared<ImageData<T>>(im);
|
||||
} catch (const FitsException& e){
|
||||
LERROR("Could not read FITS image PHDU. " + e.message() );
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -0,0 +1,71 @@
|
||||
##########################################################################################
|
||||
# #
|
||||
# OpenSpace #
|
||||
# #
|
||||
# Copyright (c) 2014-2018 #
|
||||
# #
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy of this #
|
||||
# software and associated documentation files (the "Software"), to deal in the Software #
|
||||
# without restriction, including without limitation the rights to use, copy, modify, #
|
||||
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to #
|
||||
# permit persons to whom the Software is furnished to do so, subject to the following #
|
||||
# conditions: #
|
||||
# #
|
||||
# The above copyright notice and this permission notice shall be included in all copies #
|
||||
# or substantial portions of the Software. #
|
||||
# #
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, #
|
||||
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A #
|
||||
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT #
|
||||
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF #
|
||||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE #
|
||||
# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #
|
||||
##########################################################################################
|
||||
|
||||
include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake)
|
||||
|
||||
set(HEADER_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gaiamodule.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablegaiastars.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/octreemanager.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/octreeculler.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tasks/readfilejob.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tasks/readfitstask.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tasks/readspecktask.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tasks/constructoctreetask.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gaiaoptions.h
|
||||
)
|
||||
source_group("Header Files" FILES ${HEADER_FILES})
|
||||
|
||||
set(SOURCE_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gaiamodule.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablegaiastars.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/octreemanager.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/octreeculler.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tasks/readfilejob.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tasks/readfitstask.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tasks/readspecktask.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tasks/constructoctreetask.cpp
|
||||
)
|
||||
source_group("Source Files" FILES ${SOURCE_FILES})
|
||||
|
||||
set(SHADER_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/gaia_vbo_vs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/gaia_ssbo_vs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/gaia_billboard_nofbo_fs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/gaia_billboard_fs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/gaia_billboard_ge.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/gaia_point_fs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/gaia_point_ge.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/gaia_tonemapping_vs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/gaia_tonemapping_point_fs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/gaia_tonemapping_billboard_fs.glsl
|
||||
)
|
||||
source_group("Shader Files" FILES ${SHADER_FILES})
|
||||
|
||||
create_new_module(
|
||||
"Gaia"
|
||||
gaia
|
||||
STATIC
|
||||
${HEADER_FILES} ${SOURCE_FILES} ${SHADER_FILES}
|
||||
)
|
||||
@@ -0,0 +1,72 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/gaia/gaiamodule.h>
|
||||
|
||||
#include <modules/gaia/tasks/constructoctreetask.h>
|
||||
#include <modules/gaia/rendering/renderablegaiastars.h>
|
||||
#include <modules/gaia/tasks/readfitstask.h>
|
||||
#include <modules/gaia/tasks/readspecktask.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/misc/assert.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
GaiaModule::GaiaModule() : OpenSpaceModule(Name) {}
|
||||
|
||||
void GaiaModule::internalInitialize(const ghoul::Dictionary&) {
|
||||
auto fRenderable = FactoryManager::ref().factory<Renderable>();
|
||||
ghoul_assert(fRenderable, "No renderable factory existed");
|
||||
fRenderable->registerClass<RenderableGaiaStars>("RenderableGaiaStars");
|
||||
|
||||
auto fTask = FactoryManager::ref().factory<Task>();
|
||||
ghoul_assert(fRenderable, "No task factory existed");
|
||||
fTask->registerClass<ReadFitsTask>("ReadFitsTask");
|
||||
fTask->registerClass<ReadSpeckTask>("ReadSpeckTask");
|
||||
fTask->registerClass<ConstructOctreeTask>("ConstructOctreeTask");
|
||||
}
|
||||
|
||||
std::vector<documentation::Documentation> GaiaModule::documentations() const {
|
||||
return {
|
||||
RenderableGaiaStars::Documentation(),
|
||||
ReadFitsTask::Documentation(),
|
||||
ReadSpeckTask::Documentation(),
|
||||
ConstructOctreeTask::Documentation(),
|
||||
};
|
||||
}
|
||||
|
||||
scripting::LuaLibrary GaiaModule::luaLibrary() const {
|
||||
scripting::LuaLibrary res;
|
||||
res.name = "gaia";
|
||||
res.scripts = {
|
||||
absPath("${MODULE_GAIA}/scripts/filtering.lua")
|
||||
};
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -0,0 +1,50 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GAIA___GAIAMODULE___H__
|
||||
#define __OPENSPACE_MODULE_GAIA___GAIAMODULE___H__
|
||||
|
||||
#include <openspace/util/openspacemodule.h>
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class GaiaModule : public OpenSpaceModule {
|
||||
public:
|
||||
constexpr static const char* Name = "Gaia";
|
||||
|
||||
GaiaModule();
|
||||
virtual ~GaiaModule() = default;
|
||||
|
||||
std::vector<documentation::Documentation> documentations() const override;
|
||||
scripting::LuaLibrary luaLibrary() const override;
|
||||
|
||||
private:
|
||||
void internalInitialize(const ghoul::Dictionary&) override;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GAIA___GAIAMODULE___H__
|
||||
@@ -0,0 +1,6 @@
|
||||
set(DEFAULT_MODULE ON)
|
||||
|
||||
set(OPENSPACE_DEPENDENCIES
|
||||
fitsfilereader
|
||||
globebrowsing
|
||||
)
|
||||
@@ -0,0 +1,54 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GAIA___GAIAOPTIONS___H__
|
||||
#define __OPENSPACE_MODULE_GAIA___GAIAOPTIONS___H__
|
||||
|
||||
namespace openspace::gaia {
|
||||
|
||||
enum RenderOption {
|
||||
Static = 0,
|
||||
Color = 1,
|
||||
Motion = 2
|
||||
};
|
||||
|
||||
enum FileReaderOption {
|
||||
Fits = 0,
|
||||
Speck = 1,
|
||||
BinaryRaw = 2,
|
||||
BinaryOctree = 3,
|
||||
StreamOctree = 4
|
||||
};
|
||||
|
||||
enum ShaderOption {
|
||||
Point_SSBO = 0,
|
||||
Point_VBO = 1,
|
||||
Billboard_SSBO = 2,
|
||||
Billboard_VBO = 3,
|
||||
Billboard_SSBO_noFBO = 4
|
||||
};
|
||||
|
||||
} // namespace openspace::gaiamission
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GAIA___GAIAOPTIONS___H__
|
||||
@@ -0,0 +1,86 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/gaia/rendering/octreeculler.h>
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "OctreeCuller";
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
namespace {
|
||||
bool intersects(const globebrowsing::AABB3& bb, const globebrowsing::AABB3& o) {
|
||||
return (bb.min.x <= o.max.x) && (o.min.x <= bb.max.x)
|
||||
&& (bb.min.y <= o.max.y) && (o.min.y <= bb.max.y)
|
||||
&& (bb.min.z <= o.max.z) && (o.min.z <= bb.max.z);
|
||||
}
|
||||
|
||||
void expand(globebrowsing::AABB3& bb, const glm::vec3& p) {
|
||||
bb.min = glm::min(bb.min, p);
|
||||
bb.max = glm::max(bb.max, p);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
OctreeCuller::OctreeCuller(globebrowsing::AABB3 viewFrustum)
|
||||
: _viewFrustum(std::move(viewFrustum))
|
||||
{}
|
||||
|
||||
bool OctreeCuller::isVisible(const std::vector<glm::dvec4>& corners,
|
||||
const glm::dmat4& mvp)
|
||||
{
|
||||
createNodeBounds(corners, mvp);
|
||||
return intersects(_viewFrustum, _nodeBounds);
|
||||
}
|
||||
|
||||
glm::vec2 OctreeCuller::getNodeSizeInPixels(const std::vector<glm::dvec4>& corners,
|
||||
const glm::dmat4& mvp,
|
||||
const glm::vec2& screenSize)
|
||||
{
|
||||
|
||||
createNodeBounds(corners, mvp);
|
||||
|
||||
// Screen space is mapped to [-1, 1] so divide by 2 and multiply with screen size.
|
||||
glm::vec3 size = (_nodeBounds.max - _nodeBounds.min) / 2.f;
|
||||
size = glm::abs(size);
|
||||
return glm::vec2(size.x * screenSize.x, size.y * screenSize.y);
|
||||
}
|
||||
|
||||
void OctreeCuller::createNodeBounds(const std::vector<glm::dvec4>& corners,
|
||||
const glm::dmat4& mvp)
|
||||
{
|
||||
// Create a bounding box in clipping space from node boundaries.
|
||||
_nodeBounds = globebrowsing::AABB3();
|
||||
|
||||
for (size_t i = 0; i < 8; ++i) {
|
||||
glm::dvec4 cornerClippingSpace = mvp * corners[i];
|
||||
glm::dvec4 ndc = (1.f / glm::abs(cornerClippingSpace.w)) * cornerClippingSpace;
|
||||
expand(_nodeBounds, glm::dvec3(ndc));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -0,0 +1,76 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GAIA___OCTREECULLER___H__
|
||||
#define __OPENSPACE_MODULE_GAIA___OCTREECULLER___H__
|
||||
|
||||
#include <modules/globebrowsing/src/basictypes.h>
|
||||
#include <vector>
|
||||
|
||||
// TODO: Move /geometry/* to libOpenSpace so as not to depend on globebrowsing.
|
||||
|
||||
namespace openspace {
|
||||
|
||||
/**
|
||||
* Culls all octree nodes that are completely outside the view frustum.
|
||||
*
|
||||
* The frustum culling uses a 2D axis aligned bounding box for the OctreeNode in
|
||||
* screen space.
|
||||
*/
|
||||
|
||||
class OctreeCuller {
|
||||
public:
|
||||
|
||||
/**
|
||||
* \param viewFrustum is the view space in normalized device coordinates space.
|
||||
* Hence it is an axis aligned bounding box and not a real frustum.
|
||||
*/
|
||||
OctreeCuller(globebrowsing::AABB3 viewFrustum);
|
||||
|
||||
~OctreeCuller() = default;
|
||||
|
||||
/**
|
||||
* \return true if any part of the node is visible in the current view.
|
||||
*/
|
||||
bool isVisible(const std::vector<glm::dvec4>& corners, const glm::dmat4& mvp);
|
||||
|
||||
/**
|
||||
* \return the size [in pixels] of the node in clipping space.
|
||||
*/
|
||||
glm::vec2 getNodeSizeInPixels(const std::vector<glm::dvec4>& corners,
|
||||
const glm::dmat4& mvp, const glm::vec2& screenSize);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Creates an axis-aligned bounding box containing all \p corners in clipping space.
|
||||
*/
|
||||
void createNodeBounds(const std::vector<glm::dvec4>& corners, const glm::dmat4& mvp);
|
||||
|
||||
const globebrowsing::AABB3 _viewFrustum;
|
||||
globebrowsing::AABB3 _nodeBounds;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GAIA___OCTREECULLER___H__
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,387 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GAIA___OCTREEMANAGER___H__
|
||||
#define __OPENSPACE_MODULE_GAIA___OCTREEMANAGER___H__
|
||||
|
||||
#include <modules/gaia/rendering/gaiaoptions.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class OctreeCuller;
|
||||
|
||||
class OctreeManager {
|
||||
public:
|
||||
struct OctreeNode {
|
||||
std::shared_ptr<OctreeNode> Children[8];
|
||||
std::vector<float> posData;
|
||||
std::vector<float> colData;
|
||||
std::vector<float> velData;
|
||||
std::vector<std::pair<float, size_t>> magOrder;
|
||||
float originX;
|
||||
float originY;
|
||||
float originZ;
|
||||
float halfDimension;
|
||||
size_t numStars;
|
||||
bool isLeaf;
|
||||
bool isLoaded;
|
||||
bool hasLoadedDescendant;
|
||||
std::mutex loadingLock;
|
||||
int bufferIndex;
|
||||
unsigned long long octreePositionIndex;
|
||||
};
|
||||
|
||||
OctreeManager() = default;
|
||||
~OctreeManager() = default;
|
||||
|
||||
/**
|
||||
* Initializes a one layer Octree with root and 8 children that covers all stars.
|
||||
*
|
||||
* \param maxDist together with \param maxstarsPerNode (if defined) determines the
|
||||
* depth of the tree as well as how many nodes will be created.
|
||||
*/
|
||||
void initOctree(long long cpuRamBudget = 0, int maxDist = 0, int maxStarsPerNode = 0);
|
||||
|
||||
/**
|
||||
* Initializes a stack of size \param maxNodes that keeps track of all free spot in
|
||||
* buffer stream. Can be used to trigger a rebuild of buffer(s).
|
||||
*
|
||||
* \param useVBO defines if VBO or SSBO is used as buffer(s)
|
||||
* \param datasetFitInMemory defines if streaming of nodes during runtime is used
|
||||
*/
|
||||
void initBufferIndexStack(long long maxNodes, bool useVBO, bool datasetFitInMemory);
|
||||
|
||||
/**
|
||||
* Inserts star values in correct position in Octree. Makes use of a recursive
|
||||
* traversal strategy. Internally calls <code>insertInNode()</code>
|
||||
*/
|
||||
void insert(const std::vector<float>& starValues);
|
||||
|
||||
/**
|
||||
* Slices LOD data so only the MAX_STARS_PER_NODE brightest stars are stored in inner
|
||||
* nodes. If \p branchIndex is defined then only that branch will be sliced.
|
||||
* Calls <code>sliceNodeLodCache()</code> internally.
|
||||
*/
|
||||
void sliceLodData(size_t branchIndex = 8);
|
||||
|
||||
/**
|
||||
* Prints the whole tree structure, including number of stars per node, number of
|
||||
* nodes, tree depth and if node is a leaf.
|
||||
* Calls <code>printStarsPerNode(node, prefix)</code> internally.
|
||||
*/
|
||||
void printStarsPerNode() const;
|
||||
|
||||
/**
|
||||
* Used while streaming nodes from files. Checks if any nodes need to be loaded or
|
||||
* unloaded. If entire dataset fits in RAM then the whole dataset will be loaded
|
||||
* asynchronously. Otherwise only nodes close to the camera will be fetched.
|
||||
* When RAM stars to fill up least-recently used nodes will start to unload.
|
||||
* Calls <code>findAndFetchNeighborNode()</code> and
|
||||
* <code>removeNodesFromRam()</code> internally.
|
||||
*/
|
||||
void fetchSurroundingNodes(const glm::dvec3& cameraPos, size_t chunkSizeInBytes,
|
||||
const glm::ivec2& additionalNodes);
|
||||
|
||||
/**
|
||||
* Builds render data structure by traversing the Octree and checking for intersection
|
||||
* with view frustum. Every vector in map contains data for one node.
|
||||
* The corresponding integer key is the index where chunk should be inserted into
|
||||
* streaming buffer. Calls <code>checkNodeIntersection()</code> for every branch.
|
||||
* \pdeltaStars keeps track of how many stars that were added/removed this render
|
||||
* call.
|
||||
*/
|
||||
std::map<int, std::vector<float>> traverseData(const glm::dmat4& mvp,
|
||||
const glm::vec2& screenSize, int& deltaStars, gaia::RenderOption option,
|
||||
float lodPixelThreshold);
|
||||
|
||||
/**
|
||||
* Builds full render data structure by traversing all leaves in the Octree.
|
||||
*/
|
||||
std::vector<float> getAllData(gaia::RenderOption option);
|
||||
|
||||
/**
|
||||
* Removes all data from Octree, or only from a specific branch if specified.
|
||||
* \param branchIndex defined which branch to clear if defined.
|
||||
*/
|
||||
void clearAllData(int branchIndex = -1);
|
||||
|
||||
/**
|
||||
* Write entire Octree structure to a binary file. \param writeData defines if data
|
||||
* should be included or if only structure should be written to the file.
|
||||
* Calls <code>writeNodeToFile()</code> which recursively writes all nodes.
|
||||
*/
|
||||
void writeToFile(std::ofstream& outFileStream, bool writeData);
|
||||
|
||||
/**
|
||||
* Read a constructed Octree from a file. \returns the total number of (distinct)
|
||||
* stars read.
|
||||
*
|
||||
* \param readData defines if full data or only structure should be read.
|
||||
* Calls <code>readNodeFromFile()</code> which recursively reads all nodes.
|
||||
*/
|
||||
int readFromFile(std::ifstream& inFileStream, bool readData,
|
||||
const std::string& folderPath = std::string());
|
||||
|
||||
/**
|
||||
* Write specified part of Octree to multiple files, including all data.
|
||||
* \param branchIndex defines which branch to write.
|
||||
* Clears specified branch after writing is done.
|
||||
* Calls <code>writeNodeToMultipleFiles()</code> for the specified branch.
|
||||
*/
|
||||
void writeToMultipleFiles(const std::string& outFolderPath, size_t branchIndex);
|
||||
|
||||
/**
|
||||
* Getters.
|
||||
*/
|
||||
size_t numLeafNodes() const;
|
||||
size_t numInnerNodes() const;
|
||||
size_t totalNodes() const;
|
||||
size_t totalDepth() const;
|
||||
size_t maxDist() const;
|
||||
size_t maxStarsPerNode() const;
|
||||
size_t biggestChunkIndexInUse() const;
|
||||
size_t numFreeSpotsInBuffer() const;
|
||||
bool isRebuildOngoing() const;
|
||||
|
||||
/**
|
||||
* \returns current CPU RAM budget in bytes.
|
||||
*/
|
||||
long long cpuRamBudget() const;
|
||||
|
||||
private:
|
||||
const size_t POS_SIZE = 3;
|
||||
const size_t COL_SIZE = 2;
|
||||
const size_t VEL_SIZE = 3;
|
||||
|
||||
// MAX_DIST [kPc] - Determines the depth of Octree together with MAX_STARS_PER_NODE.
|
||||
// A smaller distance is better (i.e. a smaller total depth) and a smaller MAX_STARS
|
||||
// is also better (i.e. finer borders and fewer nodes/less data needs to be uploaded
|
||||
// to the GPU), but MAX_STARS still needs to be big enough to be able to swallow all
|
||||
// stars that falls outside of top border nodes, otherwise it causes a stack overflow
|
||||
// when building Octree. However, fewer total nodes (i.e. bigger Stars/Node) reduces
|
||||
// traversing time which is preferable, especially with big datasets
|
||||
// DR1_TGAS [2M] - A MAX_DIST of 5 kPc works fine with down to 1 kSPN.
|
||||
// DR1_full [1.2B] - A MAX_DIST of 10 kPc works fine with most SPN.
|
||||
// DR2_rv [7.2M] - A MAX_DIST of 15 kPc works fine with down to 10 kSPN.
|
||||
// DR2_subset [42.9M] - A MAX_DIST of 100 kPc works fine with 20 kSPN.
|
||||
// DR2_full [1.7B] - A MAX_DIST of 250 kPc works fine with 150 kSPN.
|
||||
size_t MAX_DIST = 2; // [kPc]
|
||||
size_t MAX_STARS_PER_NODE = 2000;
|
||||
|
||||
const int DEFAULT_INDEX = -1;
|
||||
const std::string BINARY_SUFFIX = ".bin";
|
||||
|
||||
/**
|
||||
* \returns the correct index of child node. Maps [1,1,1] to 0 and [-1,-1,-1] to 7.
|
||||
*/
|
||||
size_t getChildIndex(float posX, float posY, float posZ, float origX = 0.f,
|
||||
float origY = 0.f, float origZ = 0.f);
|
||||
|
||||
/**
|
||||
* Private help function for <code>insert()</code>. Inserts star into node if leaf and
|
||||
* numStars < MAX_STARS_PER_NODE. If a leaf goes above the threshold it is subdivided
|
||||
* into 8 new nodes.
|
||||
* If node is an inner node, then star is stores in LOD cache if it is among the
|
||||
* brightest stars in all children.
|
||||
*/
|
||||
bool insertInNode(OctreeNode& node, const std::vector<float>& starValues,
|
||||
int depth = 1);
|
||||
|
||||
/**
|
||||
* Slices LOD cache data in node to the MAX_STARS_PER_NODE brightest stars. This needs
|
||||
* to be called after the last star has been inserted into Octree but before it is
|
||||
* saved to file(s). Slices all descendants recursively.
|
||||
*/
|
||||
void sliceNodeLodCache(OctreeNode& node);
|
||||
|
||||
/**
|
||||
* Private help function for <code>insertInNode()</code>. Stores star data in node and
|
||||
* keeps track of the brightest stars all children.
|
||||
*/
|
||||
void storeStarData(OctreeNode& node, const std::vector<float>& starValues);
|
||||
|
||||
/**
|
||||
* Private help function for <code>printStarsPerNode()</code>. \returns an accumulated
|
||||
* string containing all descendant nodes.
|
||||
*/
|
||||
std::string printStarsPerNode(const OctreeNode& node,
|
||||
const std::string& prefix) const;
|
||||
|
||||
/**
|
||||
* Private help function for <code>traverseData()</code>. Recursively checks which
|
||||
* nodes intersect with the view frustum (interpreted as an AABB) and decides if data
|
||||
* should be optimized away or not. Keeps track of which nodes that are visible and
|
||||
* loaded (if streaming). \param deltaStars keeps track of how many stars that were
|
||||
* added/removed this render call.
|
||||
*/
|
||||
std::map<int, std::vector<float>> checkNodeIntersection(OctreeNode& node,
|
||||
const glm::dmat4& mvp, const glm::vec2& screenSize, int& deltaStars,
|
||||
gaia::RenderOption option);
|
||||
|
||||
/**
|
||||
* Checks if specified node existed in cache, and removes it if that's the case.
|
||||
* If node is an inner node then all children will be checked recursively as well as
|
||||
* long as \param recursive is not set to false. \param deltaStars keeps track of how
|
||||
* many stars that were removed.
|
||||
*/
|
||||
std::map<int, std::vector<float>> removeNodeFromCache(OctreeNode& node,
|
||||
int& deltaStars, bool recursive = true);
|
||||
|
||||
/**
|
||||
* Get data in node and its descendants regardless if they are visible or not.
|
||||
*/
|
||||
std::vector<float> getNodeData(const OctreeNode& node, gaia::RenderOption option);
|
||||
|
||||
/**
|
||||
* Clear data from node and its descendants and shrink vectors to deallocate memory.
|
||||
*/
|
||||
void clearNodeData(OctreeNode& node);
|
||||
|
||||
/**
|
||||
* Contruct default children nodes for specified node.
|
||||
*/
|
||||
void createNodeChildren(OctreeNode& node);
|
||||
|
||||
/**
|
||||
* Checks if node should be inserted into stream or not. \returns true if it should,
|
||||
* (i.e. it doesn't already exists, there is room for it in the buffer and node data
|
||||
* is loaded if streaming). \returns false otherwise.
|
||||
*/
|
||||
bool updateBufferIndex(OctreeNode& node);
|
||||
|
||||
/**
|
||||
* Node should be inserted into stream. This function \returns the data to be
|
||||
* inserted. If VBOs are used then the chunks will be appended by zeros, otherwise
|
||||
* only the star data corresponding to RenderOption \param option will be inserted.
|
||||
*
|
||||
* \param deltaStars keeps track of how many stars that were added.
|
||||
*/
|
||||
std::vector<float> constructInsertData(const OctreeNode& node,
|
||||
gaia::RenderOption option, int& deltaStars);
|
||||
|
||||
/**
|
||||
* Write a node to outFileStream. \param writeData defines if data should be included
|
||||
* or if only structure should be written.
|
||||
*/
|
||||
void writeNodeToFile(std::ofstream& outFileStream, const OctreeNode& node,
|
||||
bool writeData);
|
||||
|
||||
/**
|
||||
* Read a node from file and its potential children. \param readData defines if full
|
||||
* data or only structure should be read.
|
||||
* \returns accumulated sum of all read stars in node and its descendants.
|
||||
*/
|
||||
int readNodeFromFile(std::ifstream& inFileStream, OctreeNode& node, bool readData);
|
||||
|
||||
/**
|
||||
* Write node data to a file. \param outFilePrefix specifies the accumulated path
|
||||
* and name of the file. If \param threadWrites is set to true then one new thread
|
||||
* will be created for each child to write its descendents.
|
||||
*/
|
||||
void writeNodeToMultipleFiles(const std::string& outFilePrefix, OctreeNode& node,
|
||||
bool threadWrites);
|
||||
|
||||
/**
|
||||
* Finds the neighboring node on the same level (or a higher level if there is no
|
||||
* corresponding level) in the specified direction. Also fetches data from found node
|
||||
* if it's not already loaded. \param additionalLevelsToFetch determines if any
|
||||
* descendants of the found node should be fetched as well (if they exists).
|
||||
*/
|
||||
void findAndFetchNeighborNode(unsigned long long firstParentId, int x, int y, int z,
|
||||
int additionalLevelsToFetch);
|
||||
|
||||
/**
|
||||
* Fetches data from all children of \param parentNode, as long as it's not already
|
||||
* fetched, it exists and it can fit in RAM.
|
||||
* \param additionalLevelsToFetch determines how many levels of descendants to fetch.
|
||||
* If it is set to 0 no additional level will be fetched.
|
||||
* If it is set to a negative value then all descendants will be fetched recursively.
|
||||
* Calls <code>fetchNodeDataFromFile()</code> for every child that passes the tests.
|
||||
*/
|
||||
void fetchChildrenNodes(OctreeNode& parentNode, int additionalLevelsToFetch);
|
||||
|
||||
/**
|
||||
* Fetches data for specified node from file.
|
||||
* OBS! Only call if node file exists (i.e. node has any data, node->numStars > 0)
|
||||
* and is not already loaded.
|
||||
*/
|
||||
void fetchNodeDataFromFile(OctreeNode& node);
|
||||
|
||||
/**
|
||||
* Loops though all nodes in \param nodesToRemove and clears them from RAM.
|
||||
* Also checks if any ancestor should change the <code>hasLoadedDescendant</code> flag
|
||||
* by calling <code>propagateUnloadedNodes()</code> with all ancestors.
|
||||
*/
|
||||
void removeNodesFromRam(const std::vector<unsigned long long>& nodesToRemove);
|
||||
|
||||
/**
|
||||
* Removes data in specified node from main memory and updates RAM budget and flags
|
||||
* accordingly.
|
||||
*/
|
||||
void removeNode(OctreeNode& node);
|
||||
|
||||
/**
|
||||
* Loops through \param ancestorNodes backwards and checks if parent node has any
|
||||
* loaded descendants left. If not, then flag <code>hasLoadedDescendant</code> will be
|
||||
* set to false for that parent node and next parent in line will be checked.
|
||||
*/
|
||||
void propagateUnloadedNodes(std::vector<std::shared_ptr<OctreeNode>> ancestorNodes);
|
||||
|
||||
std::shared_ptr<OctreeNode> _root;
|
||||
std::unique_ptr<OctreeCuller> _culler;
|
||||
std::stack<int> _freeSpotsInBuffer;
|
||||
std::set<int> _removedKeysInPrevCall;
|
||||
std::queue<unsigned long long> _leastRecentlyFetchedNodes;
|
||||
std::mutex _leastRecentlyFetchedNodesMutex;
|
||||
|
||||
size_t _totalDepth = 0;
|
||||
size_t _numLeafNodes = 0;
|
||||
size_t _numInnerNodes = 0;
|
||||
size_t _biggestChunkIndexInUse = 0;
|
||||
size_t _valuesPerStar = 0;
|
||||
float _minTotalPixelsLod = 0.f;
|
||||
|
||||
size_t _maxStackSize = 0;
|
||||
bool _rebuildBuffer = false;
|
||||
bool _useVBO = false;
|
||||
bool _streamOctree = false;
|
||||
bool _datasetFitInMemory = false;
|
||||
long long _cpuRamBudget = 0;
|
||||
long long _maxCpuRamBudget = 0;
|
||||
unsigned long long _parentNodeOfCamera = 8;
|
||||
std::string _streamFolderPath;
|
||||
size_t _traversedBranchesInRenderCall = 0;
|
||||
|
||||
}; // class OctreeManager
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GAIA___OCTREEMANAGER___H__
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,216 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GAIA___RENDERABLEGAIASTARS___H__
|
||||
#define __OPENSPACE_MODULE_GAIA___RENDERABLEGAIASTARS___H__
|
||||
|
||||
#include <openspace/rendering/renderable.h>
|
||||
|
||||
#include <modules/gaia/rendering/octreemanager.h>
|
||||
#include <openspace/properties/optionproperty.h>
|
||||
#include <openspace/properties/stringlistproperty.h>
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
#include <openspace/properties/scalar/intproperty.h>
|
||||
#include <openspace/properties/vector/vec2property.h>
|
||||
#include <openspace/properties/vector/ivec2property.h>
|
||||
#include <ghoul/opengl/bufferbinding.h>
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
#include <ghoul/opengl/uniformcache.h>
|
||||
|
||||
namespace ghoul::filesystem { class File; }
|
||||
namespace ghoul::opengl {
|
||||
class ProgramObject;
|
||||
class Texture;
|
||||
} // namespace ghoul::opengl
|
||||
|
||||
namespace openspace {
|
||||
|
||||
namespace documentation { struct Documentation; }
|
||||
|
||||
class RenderableGaiaStars : public Renderable {
|
||||
public:
|
||||
explicit RenderableGaiaStars(const ghoul::Dictionary& dictionary);
|
||||
virtual ~RenderableGaiaStars() = default;
|
||||
|
||||
void initializeGL() override;
|
||||
void deinitializeGL() override;
|
||||
|
||||
bool isReady() const override;
|
||||
|
||||
void render(const RenderData& data, RendererTasks& rendererTask) override;
|
||||
void update(const UpdateData& data) override;
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
private:
|
||||
/**
|
||||
* Reads data file in format defined by FileReaderOption.
|
||||
*
|
||||
* \return true if data was successfully read.
|
||||
*/
|
||||
bool readDataFile();
|
||||
|
||||
/**
|
||||
* Reads a FITS file by using FitsFileReader.readFitsFile() and constructs an octree.
|
||||
*
|
||||
* \return the number of stars read.
|
||||
*/
|
||||
int readFitsFile(const std::string& filePath);
|
||||
|
||||
/**
|
||||
* Read a SPECK file by using FitsFileReader.readSpeckFile() and constructs an octree.
|
||||
*
|
||||
* \return the number of stars read.
|
||||
*/
|
||||
int readSpeckFile(const std::string& filePath);
|
||||
|
||||
/**
|
||||
* Reads a preprocessed binary file and constructs an octree.
|
||||
*
|
||||
* \return the number of stars read.
|
||||
*/
|
||||
int readBinaryRawFile(const std::string& filePath);
|
||||
|
||||
/**
|
||||
* Reads a pre-constructed octree, with all data, from a binary file.
|
||||
*
|
||||
* \return the number of stars read.
|
||||
*/
|
||||
int readBinaryOctreeFile(const std::string& filePath);
|
||||
|
||||
/**
|
||||
* Reads the structure of a pre-constructed octree from a binary file, without any
|
||||
* data.
|
||||
*
|
||||
* \return the number of stars read.
|
||||
*/
|
||||
int readBinaryOctreeStructureFile(const std::string& folderPath);
|
||||
|
||||
/**
|
||||
* Checks for any OpenGL errors and reports these to the log if _reportGlErrors is
|
||||
* set to true.
|
||||
*/
|
||||
void checkGlErrors(const std::string& identifier) const;
|
||||
|
||||
properties::StringProperty _filePath;
|
||||
std::unique_ptr<ghoul::filesystem::File> _dataFile;
|
||||
bool _dataIsDirty = true;
|
||||
bool _buffersAreDirty = true;
|
||||
bool _shadersAreDirty = false;
|
||||
|
||||
properties::StringProperty _pointSpreadFunctionTexturePath;
|
||||
std::unique_ptr<ghoul::opengl::Texture> _pointSpreadFunctionTexture;
|
||||
std::unique_ptr<ghoul::filesystem::File> _pointSpreadFunctionFile;
|
||||
bool _pointSpreadFunctionTextureIsDirty = true;
|
||||
|
||||
properties::StringProperty _colorTexturePath;
|
||||
std::unique_ptr<ghoul::opengl::Texture> _colorTexture;
|
||||
std::unique_ptr<ghoul::filesystem::File> _colorTextureFile;
|
||||
bool _colorTextureIsDirty = true;
|
||||
|
||||
properties::FloatProperty _luminosityMultiplier;
|
||||
properties::FloatProperty _magnitudeBoost;
|
||||
properties::FloatProperty _cutOffThreshold;
|
||||
properties::FloatProperty _sharpness;
|
||||
properties::FloatProperty _billboardSize;
|
||||
properties::FloatProperty _closeUpBoostDist;
|
||||
properties::IntProperty _tmPointFilterSize;
|
||||
properties::FloatProperty _tmPointSigma;
|
||||
properties::IVec2Property _additionalNodes;
|
||||
properties::FloatProperty _tmPointPixelWeightThreshold;
|
||||
properties::FloatProperty _lodPixelThreshold;
|
||||
|
||||
properties::Vec2Property _posXThreshold;
|
||||
properties::Vec2Property _posYThreshold;
|
||||
properties::Vec2Property _posZThreshold;
|
||||
properties::Vec2Property _gMagThreshold;
|
||||
properties::Vec2Property _bpRpThreshold;
|
||||
properties::Vec2Property _distThreshold;
|
||||
|
||||
properties::IntProperty _firstRow;
|
||||
properties::IntProperty _lastRow;
|
||||
properties::StringListProperty _columnNamesList;
|
||||
std::vector<std::string> _columnNames;
|
||||
properties::OptionProperty _fileReaderOption;
|
||||
properties::OptionProperty _renderOption;
|
||||
properties::OptionProperty _shaderOption;
|
||||
properties::IntProperty _nRenderedStars;
|
||||
// LongLongProperty doesn't show up in menu, use FloatProperty instead.
|
||||
properties::FloatProperty _cpuRamBudgetProperty;
|
||||
properties::FloatProperty _gpuStreamBudgetProperty;
|
||||
properties::FloatProperty _maxGpuMemoryPercent;
|
||||
properties::FloatProperty _maxCpuMemoryPercent;
|
||||
|
||||
properties::BoolProperty _reportGlErrors;
|
||||
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _program;
|
||||
UniformCache(model, view, cameraPos, cameraLookUp, viewScaling, projection,
|
||||
renderOption, luminosityMultiplier, magnitudeBoost, cutOffThreshold,
|
||||
sharpness, billboardSize, closeUpBoostDist, screenSize, psfTexture,
|
||||
time, colorTexture, nChunksToRender, valuesPerStar, maxStarsPerNode)
|
||||
_uniformCache;
|
||||
|
||||
UniformCache(posXThreshold, posYThreshold, posZThreshold, gMagThreshold,
|
||||
bpRpThreshold, distThreshold) _uniformFilterCache;
|
||||
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _programTM;
|
||||
UniformCache(renderedTexture, screenSize, filterSize, sigma, pixelWeightThreshold,
|
||||
projection) _uniformCacheTM;
|
||||
std::unique_ptr<ghoul::opengl::Texture> _fboTexture;
|
||||
|
||||
OctreeManager _octreeManager;
|
||||
std::unique_ptr<ghoul::opengl::BufferBinding<
|
||||
ghoul::opengl::bufferbinding::Buffer::ShaderStorage>> _ssboIdxBinding;
|
||||
std::unique_ptr<ghoul::opengl::BufferBinding<
|
||||
ghoul::opengl::bufferbinding::Buffer::ShaderStorage>> _ssboDataBinding;
|
||||
|
||||
std::vector<int> _accumulatedIndices;
|
||||
size_t _nRenderValuesPerStar = 0;
|
||||
int _nStarsToRender = 0;
|
||||
bool _firstDrawCalls = true;
|
||||
glm::dquat _previousCameraRotation;
|
||||
bool _useVBO = false;
|
||||
long long _cpuRamBudgetInBytes = 0;
|
||||
long long _totalDatasetSizeInBytes = 0;
|
||||
long long _gpuMemoryBudgetInBytes = 0;
|
||||
long long _maxStreamingBudgetInBytes = 0;
|
||||
size_t _chunkSize = 0;
|
||||
|
||||
GLuint _vao = 0;
|
||||
GLuint _vaoEmpty = 0;
|
||||
GLuint _vboPos = 0;
|
||||
GLuint _vboCol = 0;
|
||||
GLuint _vboVel = 0;
|
||||
GLuint _ssboIdx = 0;
|
||||
GLuint _ssboData = 0;
|
||||
GLuint _vaoQuad = 0;
|
||||
GLuint _vboQuad = 0;
|
||||
GLuint _fbo = 0;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GAIA___RENDERABLEGAIASTARS___H__
|
||||
@@ -0,0 +1,102 @@
|
||||
openspace.gaia.documentation = {
|
||||
{
|
||||
Name = "addClippingBox",
|
||||
Arguments = "string, vec3, vec3",
|
||||
Documentation = "Creates a clipping box for the Gaia renderable in the first argument"
|
||||
},
|
||||
{
|
||||
Name = "removeClippingBox",
|
||||
Arguments = "",
|
||||
Documentation = ""
|
||||
},
|
||||
{
|
||||
Name = "addClippingSphere",
|
||||
Arguments = "string, float",
|
||||
Documentation = "Creates a clipping sphere for the Gaia renderable in the first argument"
|
||||
},
|
||||
{
|
||||
Name = "removeClippingBox",
|
||||
Arguments = "",
|
||||
Documentation = ""
|
||||
}
|
||||
}
|
||||
|
||||
openspace.gaia.addClippingBox = function (name, size, position)
|
||||
local grid_identifier = "Filtering_Box"
|
||||
local kilo_parsec_in_meter = 30856775814913700000
|
||||
|
||||
if openspace.hasSceneGraphNode(grid_identifier) then
|
||||
openspace.removeSceneGraphNode(grid_identifier)
|
||||
end
|
||||
|
||||
local grid = {
|
||||
Identifier = grid_identifier,
|
||||
Transform = {
|
||||
Translation = {
|
||||
Type = "StaticTranslation",
|
||||
Position = { position[1] * kilo_parsec_in_meter, position[2] * kilo_parsec_in_meter, position[3] * kilo_parsec_in_meter }
|
||||
}
|
||||
},
|
||||
Renderable = {
|
||||
Type = "RenderableBoxGrid",
|
||||
GridColor = { 0.6, 0.5, 0.7, 1.0 },
|
||||
LineWidth = 2.0,
|
||||
Size = { size[1] * kilo_parsec_in_meter, size[2] * kilo_parsec_in_meter, size[3] * kilo_parsec_in_meter}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Filtering Grid",
|
||||
Path = "/Other/Grids"
|
||||
}
|
||||
}
|
||||
|
||||
openspace.addSceneGraphNode(grid)
|
||||
|
||||
openspace.setPropertyValue('Scene.' .. name .. '.renderable.FilterPosX', { (position[1] - size[1] / 2) * kilo_parsec_in_meter, (position[1] + size[1] / 2) * kilo_parsec_in_meter })
|
||||
openspace.setPropertyValue('Scene.' .. name .. '.renderable.FilterPosY', { (position[2] - size[2] / 2) * kilo_parsec_in_meter, (position[2] + size[2] / 2) * kilo_parsec_in_meter })
|
||||
openspace.setPropertyValue('Scene.' .. name .. '.renderable.FilterPosZ', { (position[3] - size[3] / 2) * kilo_parsec_in_meter, (position[3] + size[3] / 2) * kilo_parsec_in_meter })
|
||||
end
|
||||
|
||||
openspace.gaia.removeClippingBox = function()
|
||||
local grid_identifier = "Filtering_Box"
|
||||
|
||||
if openspace.hasSceneGraphNode(grid_identifier) then
|
||||
openspace.removeSceneGraphNode(grid_identifier)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
openspace.gaia.addClippingSphere = function (name, radius)
|
||||
local grid_identifier = "Filtering_Sphere"
|
||||
local kilo_parsec_in_meter = 30856775814913700000
|
||||
|
||||
|
||||
if openspace.hasSceneGraphNode(grid_identifier) then
|
||||
openspace.removeSceneGraphNode(grid_identifier)
|
||||
end
|
||||
|
||||
local grid = {
|
||||
Identifier = grid_identifier,
|
||||
Renderable = {
|
||||
Type = "RenderableSphericalGrid",
|
||||
GridColor = { 0.6, 0.5, 0.7, 1.0 },
|
||||
LineWidth = 1.0,
|
||||
Radius = radius * kilo_parsec_in_meter
|
||||
},
|
||||
GUI = {
|
||||
Name = "Filtering Sphere",
|
||||
Path = "/Other/Grids"
|
||||
}
|
||||
}
|
||||
|
||||
openspace.addSceneGraphNode(grid)
|
||||
|
||||
openspace.setPropertyValue('Scene.' .. name .. '.renderable.FilterDist', radius * kilo_parsec_in_meter)
|
||||
end
|
||||
|
||||
openspace.gaia.removeClippingSphere = function()
|
||||
local grid_identifier = "Filtering_Sphere"
|
||||
|
||||
if openspace.hasSceneGraphNode(grid_identifier) then
|
||||
openspace.removeSceneGraphNode(grid_identifier)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,114 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "floatoperations.glsl"
|
||||
|
||||
layout (location = 0) out vec4 outColor;
|
||||
|
||||
// Keep in sync with gaiaoptions.h:RenderOption enum
|
||||
const int RENDEROPTION_STATIC = 0;
|
||||
const int RENDEROPTION_COLOR = 1;
|
||||
const int RENDEROPTION_MOTION = 2;
|
||||
const float ONE_PARSEC = 3.08567758e16; // 1 Parsec
|
||||
const float FLT_MAX = 3.402823466e38; // Max float constant in GLSL
|
||||
const float LUM_LOWER_CAP = 0.01;
|
||||
|
||||
in vec2 ge_brightness;
|
||||
in vec4 ge_gPosition;
|
||||
in vec2 texCoord;
|
||||
in float ge_starDistFromSun;
|
||||
in float ge_cameraDistFromSun;
|
||||
in float ge_observedDist;
|
||||
|
||||
uniform sampler2D psfTexture;
|
||||
uniform sampler1D colorTexture;
|
||||
uniform float luminosityMultiplier;
|
||||
uniform float sharpness;
|
||||
uniform int renderOption;
|
||||
|
||||
vec3 color2rgb(float color) {
|
||||
// BV is [-0.4, 2.0]
|
||||
float st = (color + 0.4) / (2.0 + 0.4);
|
||||
|
||||
// Bp-Rp[-2.0, 6.5], Bp-G[-2.1, 5.0], G-Rp[-1.0, 3.0]
|
||||
//float st = (color + 1.0) / (5.0 + 1.0);
|
||||
|
||||
return texture(colorTexture, st).rgb;
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
// Assume all stars has equal luminosity as the Sun when no magnitude is loaded.
|
||||
float luminosity = 0.05;
|
||||
vec3 color = vec3(luminosity);
|
||||
float ratioMultiplier = 0.05;
|
||||
|
||||
vec4 textureColor = texture(psfTexture, texCoord);
|
||||
textureColor.a = pow(textureColor.a, sharpness);
|
||||
if (textureColor.a < 0.001) {
|
||||
discard;
|
||||
}
|
||||
|
||||
// Calculate the color and luminosity if we have the magnitude and B-V color.
|
||||
if ( renderOption != RENDEROPTION_STATIC ) {
|
||||
color = color2rgb(ge_brightness.y);
|
||||
ratioMultiplier = 0.5;
|
||||
|
||||
// Absolute magnitude is brightness a star would have at 10 pc away.
|
||||
float absoluteMagnitude = ge_brightness.x;
|
||||
|
||||
// From formula: MagSun - MagStar = 2.5*log(LumStar / LumSun), it gives that:
|
||||
// LumStar = 10^(1.89 - 0.4*Magstar) , if LumSun = 1 and MagSun = 4.72
|
||||
luminosity = pow(10.0, 1.89 - 0.4 * absoluteMagnitude);
|
||||
|
||||
// If luminosity is really really small then set it to a static low number.
|
||||
if (luminosity < LUM_LOWER_CAP) {
|
||||
luminosity = LUM_LOWER_CAP;
|
||||
}
|
||||
}
|
||||
|
||||
// Luminosity decrease by {squared} distance [measured in Pc].
|
||||
float observedDistance = ge_observedDist / ONE_PARSEC;
|
||||
luminosity /= pow(observedDistance, 2.0);
|
||||
|
||||
// Multiply our color with the luminosity as well as a user-controlled property.
|
||||
color *= luminosity * pow(luminosityMultiplier, 3.0);
|
||||
|
||||
// Decrease contributing brightness for stars in central cluster.
|
||||
if ( ge_cameraDistFromSun > ge_starDistFromSun ) {
|
||||
float ratio = ge_starDistFromSun / ge_cameraDistFromSun;
|
||||
//color *= ratio * ratioMultiplier;
|
||||
}
|
||||
|
||||
// Use truncating tonemapping here so we don't overexposure individual stars.
|
||||
//color = 1.0 - 1.0 * exp(-5.0 * color.rgb);
|
||||
float maxVal = max(max(color.r, color.g), color.b);
|
||||
if (maxVal > 1.0) {
|
||||
color /= maxVal;
|
||||
}
|
||||
|
||||
outColor = vec4(color, textureColor.a);
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "floatoperations.glsl"
|
||||
|
||||
// Keep in sync with gaiaoptions.h:RenderOption enum
|
||||
const int RENDEROPTION_STATIC = 0;
|
||||
const int RENDEROPTION_COLOR = 1;
|
||||
const int RENDEROPTION_MOTION = 2;
|
||||
const float EPS = 1e-5;
|
||||
|
||||
layout(points) in;
|
||||
in vec2 vs_brightness[];
|
||||
in vec4 vs_gPosition[];
|
||||
in float vs_starDistFromSun[];
|
||||
in float vs_cameraDistFromSun[];
|
||||
|
||||
layout(triangle_strip, max_vertices = 4) out;
|
||||
out vec2 ge_brightness;
|
||||
out vec4 ge_gPosition;
|
||||
out vec2 texCoord;
|
||||
out float ge_starDistFromSun;
|
||||
out float ge_cameraDistFromSun;
|
||||
out float ge_observedDist;
|
||||
|
||||
uniform dmat4 view;
|
||||
uniform dmat4 projection;
|
||||
|
||||
uniform dvec3 cameraPos;
|
||||
uniform dvec3 cameraLookUp;
|
||||
uniform float viewScaling;
|
||||
uniform float cutOffThreshold;
|
||||
uniform float closeUpBoostDist;
|
||||
uniform float billboardSize;
|
||||
uniform int renderOption;
|
||||
uniform float magnitudeBoost;
|
||||
|
||||
const vec2 corners[4] = vec2[4](
|
||||
vec2(0.0, 1.0),
|
||||
vec2(0.0, 0.0),
|
||||
vec2(1.0, 1.0),
|
||||
vec2(1.0, 0.0)
|
||||
);
|
||||
|
||||
|
||||
void main() {
|
||||
|
||||
ge_brightness = vs_brightness[0];
|
||||
ge_starDistFromSun = vs_starDistFromSun[0];
|
||||
ge_cameraDistFromSun = vs_cameraDistFromSun[0];
|
||||
|
||||
vec4 viewPosition = vec4(view * vs_gPosition[0]);
|
||||
|
||||
// Make closer stars look a bit bigger.
|
||||
ge_observedDist = safeLength(viewPosition / viewScaling);
|
||||
float closeUpBoost = closeUpBoostDist / ge_observedDist;
|
||||
float initStarSize = billboardSize;
|
||||
|
||||
// Use magnitude for size boost as well.
|
||||
if ( renderOption != RENDEROPTION_STATIC ) {
|
||||
// DR1 magnitudes are [4, 20], but could be [-15, 20] according to this chart:
|
||||
// https://qph.fs.quoracdn.net/main-qimg-317a18e3b228efc7d7f67a1632a55961
|
||||
// Negative magnitude => Giants
|
||||
// Big positive magnitude => Dwarfs
|
||||
float absoluteMagnitude = vs_brightness[0].x;
|
||||
float normalizedMagnitude = (absoluteMagnitude - 20) / -1; // (-15 - 20);
|
||||
|
||||
// TODO: A linear scale is prabably not the best!
|
||||
initStarSize += normalizedMagnitude * (magnitudeBoost / 50);
|
||||
}
|
||||
|
||||
vec4 position = gl_in[0].gl_Position;
|
||||
vec2 starSize = vec2(initStarSize + closeUpBoost) * position.w / 1000.0;
|
||||
|
||||
float distThreshold = cutOffThreshold - log(ge_observedDist) / log(4.0);
|
||||
|
||||
// Discard geometry if star has no position (but wasn't a nullArray).
|
||||
// Or if observed distance is above threshold set by cutOffThreshold.
|
||||
// By discarding in gs instead of fs we save computations for when nothing is visible.
|
||||
if( length(position) < EPS || distThreshold <= 0){
|
||||
return;
|
||||
}
|
||||
|
||||
vec4 centerWorldPos = vs_gPosition[0];
|
||||
|
||||
dvec3 cameraNormal = normalize(cameraPos - dvec3(centerWorldPos.xyz));
|
||||
dvec3 newRight = normalize(cross(cameraLookUp, cameraNormal));
|
||||
dvec3 newUp = cross(cameraNormal, newRight);
|
||||
vec4 wCameraRight = vec4(newRight, 0.0);
|
||||
vec4 wCameraUp = vec4(newUp, 0.0);
|
||||
|
||||
float multiplier = float(length(cameraPos));
|
||||
starSize *= float(multiplier/1E1);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
// Always turn the billboard towards the camera (needed for warped screen).
|
||||
vec4 cornerPoint = centerWorldPos
|
||||
+ wCameraRight * starSize.x * (corners[i].x - 0.5)
|
||||
+ wCameraUp * starSize.y * (corners[i].y - 0.5);
|
||||
gl_Position = vec4(projection * view * cornerPoint);
|
||||
gl_Position.z = 0.0;
|
||||
texCoord = corners[i];
|
||||
ge_gPosition = viewPosition;
|
||||
|
||||
EmitVertex();
|
||||
}
|
||||
|
||||
EndPrimitive();
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include "fragment.glsl"
|
||||
#include "floatoperations.glsl"
|
||||
|
||||
// Keep in sync with gaiaoptions.h:RenderOption enum
|
||||
const int RENDEROPTION_STATIC = 0;
|
||||
const int RENDEROPTION_COLOR = 1;
|
||||
const int RENDEROPTION_MOTION = 2;
|
||||
const float ONE_PARSEC = 3.08567758e16; // 1 Parsec
|
||||
const float DEFAULT_DEPTH = 3.08567758e19; // 1000 Pc
|
||||
const float LUM_LOWER_CAP = 0.01;
|
||||
|
||||
in vec2 ge_brightness;
|
||||
in vec4 ge_gPosition;
|
||||
in vec2 texCoord;
|
||||
in float ge_starDistFromSun;
|
||||
in float ge_cameraDistFromSun;
|
||||
in float ge_observedDist;
|
||||
|
||||
uniform sampler2D psfTexture;
|
||||
uniform sampler1D colorTexture;
|
||||
uniform float luminosityMultiplier;
|
||||
uniform float sharpness;
|
||||
uniform int renderOption;
|
||||
|
||||
vec3 color2rgb(float color) {
|
||||
// BV is [-0.4, 2.0]
|
||||
float st = (color + 0.4) / (2.0 + 0.4);
|
||||
|
||||
// Bp-Rp[-2.0, 6.5], Bp-G[-2.1, 5.0], G-Rp[-1.0, 3.0]
|
||||
//float st = (color + 1.0) / (5.0 + 1.0);
|
||||
|
||||
return texture(colorTexture, st).rgb;
|
||||
}
|
||||
|
||||
Fragment getFragment() {
|
||||
|
||||
// Assume all stars has equal luminosity as the Sun when no magnitude is loaded.
|
||||
float luminosity = 1.0;
|
||||
vec3 color = vec3(luminosity);
|
||||
float ratioMultiplier = 0.03;
|
||||
|
||||
vec4 textureColor = texture(psfTexture, texCoord);
|
||||
textureColor.a = pow(textureColor.a, sharpness);
|
||||
if (textureColor.a < 0.001) {
|
||||
discard;
|
||||
}
|
||||
|
||||
// Calculate the color and luminosity if we have the magnitude and B-V color.
|
||||
if ( renderOption != RENDEROPTION_STATIC ) {
|
||||
color = color2rgb(ge_brightness.y);
|
||||
ratioMultiplier = 0.5;
|
||||
|
||||
// Absolute magnitude is brightness a star would have at 10 pc away.
|
||||
float absoluteMagnitude = ge_brightness.x;
|
||||
|
||||
// From formula: MagSun - MagStar = 2.5*log(LumStar / LumSun), it gives that:
|
||||
// LumStar = 10^(1.89 - 0.4*Magstar) , if LumSun = 1 and MagSun = 4.72
|
||||
luminosity = pow(10.0, 1.89 - 0.4 * absoluteMagnitude);
|
||||
|
||||
// If luminosity is really really small then set it to a static low number.
|
||||
if (luminosity < LUM_LOWER_CAP) {
|
||||
luminosity = LUM_LOWER_CAP;
|
||||
}
|
||||
}
|
||||
|
||||
// Luminosity decrease by {squared} distance [measured in Pc].
|
||||
float observedDistance = ge_observedDist / ONE_PARSEC;
|
||||
luminosity /= pow(observedDistance, 2.0);
|
||||
|
||||
// Multiply our color with the luminosity as well as a user-controlled property.
|
||||
color *= luminosity * pow(luminosityMultiplier, 3.0);
|
||||
|
||||
// Decrease contributing brightness for stars in central cluster.
|
||||
if ( ge_cameraDistFromSun > ge_starDistFromSun ) {
|
||||
float ratio = ge_starDistFromSun / ge_cameraDistFromSun;
|
||||
//color *= ratio * ratioMultiplier;
|
||||
}
|
||||
|
||||
// Use truncating tonemapping here so we don't overexposure individual stars.
|
||||
//color = 1.0 - 1.0 * exp(-5.0 * color.rgb);
|
||||
float maxVal = max(max(color.r, color.g), color.b);
|
||||
if (maxVal > 1.0) {
|
||||
color /= maxVal;
|
||||
}
|
||||
|
||||
if (length(color) < 0.01) {
|
||||
discard;
|
||||
}
|
||||
|
||||
Fragment frag;
|
||||
frag.color = vec4(color, textureColor.a);;
|
||||
// Place stars at back to begin with.
|
||||
frag.depth = DEFAULT_DEPTH;
|
||||
frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
frag.blend = BLEND_MODE_NORMAL;
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user