mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-25 05:48:59 -05:00
Merge branch 'master' into project/infravis-2025-visA
This commit is contained in:
@@ -38,6 +38,18 @@ set(OPENSPACE_VERSION_MAJOR)
|
||||
set(OPENSPACE_VERSION_MINOR)
|
||||
set(OPENSPACE_VERSION_PATCH)
|
||||
|
||||
# Optionally disable vcpkg to prevent dependency conflicts
|
||||
set(DISABLE_VCPKG OFF CACHE BOOL "Disable the use of vcpkg libs for Windows builds")
|
||||
if (WIN32 AND DISABLE_VCPKG)
|
||||
# This works for all subprojects due to MSBuild's hierarchical search
|
||||
configure_file(
|
||||
"${CMAKE_SOURCE_DIR}/support/cmake/Directory.Build.Props.template"
|
||||
"${CMAKE_BINARY_DIR}/Directory.Build.props"
|
||||
COPYONLY
|
||||
)
|
||||
message(STATUS "Vcpkg disabled through CMake option DISABLE_VCPKG")
|
||||
endif ()
|
||||
|
||||
include(${PROJECT_SOURCE_DIR}/support/cmake/module_common.cmake)
|
||||
include(${PROJECT_SOURCE_DIR}/ext/ghoul/support/cmake/message_macros.cmake)
|
||||
|
||||
|
||||
@@ -85,7 +85,8 @@ namespace {
|
||||
const int levelChange = elem.level - level;
|
||||
|
||||
if (levelChange == 0) {
|
||||
parent->insertChildren(++nChildInsert, 1, 3);
|
||||
nChildInsert++;
|
||||
parent->insertChildren(nChildInsert, 1, 3);
|
||||
parent->child(nChildInsert)->setData(
|
||||
0,
|
||||
QString::fromStdString(elem.line)
|
||||
|
||||
+1
-1
Submodule apps/OpenSpace/ext/sgct updated: 314b23bb66...98be6301fb
@@ -1336,7 +1336,7 @@ int main(int argc, char* argv[]) {
|
||||
LINFO(std::format("Configuration Path '{}'", configurationFilePath));
|
||||
|
||||
// Register the base path as the directory where the configuration file lives
|
||||
std::filesystem::path base = configurationFilePath.parent_path();
|
||||
std::filesystem::path base = findConfiguration().parent_path();
|
||||
FileSys.registerPathToken("${BASE}", std::move(base));
|
||||
|
||||
// The previous incarnation of this was initializing GLFW to get the primary
|
||||
|
||||
@@ -15,13 +15,12 @@ local AddSunTrail = {
|
||||
date = openspace.time.UTC()
|
||||
end
|
||||
|
||||
local datePlus = openspace.time.advancedTime(date, '1d')
|
||||
|
||||
date = string.sub(date, 1, string.find(date, "T") - 1)
|
||||
datePlus = string.sub(datePlus, 1, string.find(datePlus, "T") - 1)
|
||||
dateSub = string.sub(date, 1, string.find(date, "T") - 1)
|
||||
date = dateSub .. "T00:00:00Z"
|
||||
local datePlus = dateSub .. "T23:59:59Z"
|
||||
|
||||
local SunTrailEarth = {
|
||||
Identifier = "SunTrailEarth" .. date,
|
||||
Identifier = "SunTrailEarth" .. dateSub,
|
||||
Parent = "Earth",
|
||||
Renderable = {
|
||||
Type = "RenderableTrailTrajectory",
|
||||
@@ -40,12 +39,16 @@ local AddSunTrail = {
|
||||
},
|
||||
Tag = { "sun_trail" },
|
||||
GUI = {
|
||||
Name = "Sun Trail " .. date,
|
||||
Name = "Sun Trail " .. dateSub,
|
||||
Path = "/Night Sky/Sun Trails",
|
||||
}
|
||||
}
|
||||
|
||||
openspace.addSceneGraphNode(SunTrailEarth)
|
||||
|
||||
if not openspace.hasSceneGraphNode(SunTrailEarth.Identifier) then
|
||||
openspace.addSceneGraphNode(SunTrailEarth)
|
||||
else
|
||||
openspace.printWarning("Sun trail for date " .. dateSub .. " already exists.")
|
||||
end
|
||||
]],
|
||||
Documentation = [[
|
||||
Adds a trail for the sun, if an argument is provided, that date will be used instead of now
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- No Decorations
|
||||
-- This example adds a new DashboardItem that shows the current in-game simulation date
|
||||
-- without any additional text surrounding the current date
|
||||
-- without any additional text surrounding the current date.
|
||||
|
||||
local Item = {
|
||||
Identifier = "DashboardItemDate_Example_NoDecoration",
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
local sun = asset.require("scene/solarsystem/sun/transforms")
|
||||
local earth = asset.require("scene/solarsystem/planets/earth/earth")
|
||||
|
||||
|
||||
|
||||
local models = asset.resource({
|
||||
Name = "New Horizons Model",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "newhorizons_model",
|
||||
Version = 2
|
||||
})
|
||||
|
||||
|
||||
local ExampleFixedHeight = {
|
||||
Identifier = "ExampleFixedHeight",
|
||||
Parent = earth.Earth.Identifier,
|
||||
Transform = {
|
||||
Translation = {
|
||||
Type = "GlobeTranslation",
|
||||
Globe = earth.Earth.Identifier,
|
||||
Latitude = 40.7128,
|
||||
Longitude = -74.006,
|
||||
Altitude = 100000.0
|
||||
}
|
||||
},
|
||||
Renderable = {
|
||||
Type = "RenderableModel",
|
||||
GeometryFile = models .. "NewHorizonsCleanModel.obj",
|
||||
LightSources = {
|
||||
sun.LightSource
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "GlobeTranslation - Fixed Height",
|
||||
Path = "/Examples"
|
||||
}
|
||||
}
|
||||
|
||||
local ExampleAdaptiveHeight = {
|
||||
Identifier = "ExampleAdaptiveHeight",
|
||||
Parent = earth.Earth.Identifier,
|
||||
Transform = {
|
||||
Translation = {
|
||||
Type = "GlobeTranslation",
|
||||
Globe = earth.Earth.Identifier,
|
||||
Latitude = 40.7128,
|
||||
Longitude = -74.006,
|
||||
UseHeightmap = true
|
||||
}
|
||||
},
|
||||
Renderable = {
|
||||
Type = "RenderableModel",
|
||||
GeometryFile = models .. "NewHorizonsCleanModel.obj",
|
||||
LightSources = {
|
||||
sun.LightSource
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "GlobeTranslation - Adaptive Height",
|
||||
Path = "/Examples"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(ExampleFixedHeight)
|
||||
openspace.addSceneGraphNode(ExampleAdaptiveHeight)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeSceneGraphNode(ExampleAdaptiveHeight)
|
||||
openspace.removeSceneGraphNode(ExampleFixedHeight)
|
||||
end)
|
||||
|
||||
asset.export(ExampleFixedHeight)
|
||||
asset.export(ExampleAdaptiveHeight)
|
||||
|
||||
|
||||
|
||||
asset.meta = {
|
||||
Name = "GlobeTranslation Example",
|
||||
Description = [[An example that demonstrates how to place an object on a planet surface
|
||||
using the "GlobeTranslation" transform. For the altitude, a fixed height can be used,
|
||||
or the height can be queried from the height map]],
|
||||
Author = "OpenSpace Team",
|
||||
URL = "http://openspaceproject.com",
|
||||
License = "MIT license"
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
local AU = 149597870700 -- 1 AU
|
||||
|
||||
local Circle = {
|
||||
Identifier = "ExampleCircle",
|
||||
Transform = {
|
||||
Scale = {
|
||||
Type = "StaticScale",
|
||||
Scale = AU
|
||||
}
|
||||
},
|
||||
Renderable = {
|
||||
Type = "RenderableRadialGrid",
|
||||
Color = { 0.6, 0.6, 0.8 },
|
||||
LineWidth = 3.0,
|
||||
GridSegments = { 1, 1 },
|
||||
CircleSegments = 64,
|
||||
Radii = { 0.0, 1.0 }
|
||||
},
|
||||
GUI = {
|
||||
Name = "Example Circle",
|
||||
Path = "/Examples/Primitives"
|
||||
}
|
||||
}
|
||||
|
||||
local Ellipse = {
|
||||
Identifier = "ExampleEllipse",
|
||||
Transform = {
|
||||
Scale = {
|
||||
Type = "NonUniformStaticScale",
|
||||
Scale = { 1.5, 1.0, 1.0 }
|
||||
}
|
||||
},
|
||||
Renderable = {
|
||||
Type = "RenderableRadialGrid",
|
||||
Color = { 0.6, 0.8, 0.6 },
|
||||
LineWidth = 3.0,
|
||||
GridSegments = { 1, 1 },
|
||||
CircleSegments = 64,
|
||||
Radii = { 0.0, AU }
|
||||
},
|
||||
GUI = {
|
||||
Name = "Example Ellipse",
|
||||
Path = "/Examples/Primitives"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(Circle)
|
||||
openspace.addSceneGraphNode(Ellipse)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeSceneGraphNode(Ellipse)
|
||||
openspace.removeSceneGraphNode(Circle)
|
||||
end)
|
||||
|
||||
asset.export(Circle)
|
||||
asset.export(Ellipse)
|
||||
|
||||
|
||||
|
||||
asset.meta = {
|
||||
Name = "Primitives Example",
|
||||
Description = [[Examples of different simple rendered primitives, such as circles
|
||||
and ellipses.]],
|
||||
Author = "OpenSpace Team",
|
||||
URL = "http://openspaceproject.com",
|
||||
License = "MIT license"
|
||||
}
|
||||
+10
-27
@@ -1,6 +1,6 @@
|
||||
local transforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
|
||||
|
||||
-- With Custom Shader
|
||||
-- This example creates a rendering of the volumetric milky way galaxy, but using a custom
|
||||
-- shader to highlight the arms of the galaxy.
|
||||
|
||||
local data = asset.resource({
|
||||
Name = "Milkyway Volume Data",
|
||||
@@ -12,15 +12,13 @@ local data = asset.resource({
|
||||
|
||||
local KiloParsec = 3.086E19
|
||||
|
||||
local MilkyWayVolume = {
|
||||
Identifier = "MilkyWayVolume_CustomShader",
|
||||
Parent = transforms.SolarSystemBarycenter.Identifier,
|
||||
local Node = {
|
||||
Identifier = "RenderableGalaxy_Example_CustomShader",
|
||||
Transform = {
|
||||
Translation = {
|
||||
Type = "StaticTranslation",
|
||||
-- The center of the Milky Way is approximately 8 kiloparsec from the Sun.
|
||||
-- The x-axis of galactic coordinates points from the sun towards the center
|
||||
-- of the galaxy.
|
||||
-- The x-axis of galactic coordinates points from the Sun towards the galaxy center
|
||||
Position = { 8 * KiloParsec, 0, 0 }
|
||||
}
|
||||
},
|
||||
@@ -46,30 +44,15 @@ local MilkyWayVolume = {
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Path = "/Milky Way",
|
||||
Name = "Milky Way Volume (Custom Shader)",
|
||||
Description = "Volumetric rendering of Milky Way galaxy based on simulation from NAOJ"
|
||||
Name = "RenderableGalaxy - Custom Shader",
|
||||
Path = "/Examples"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(MilkyWayVolume)
|
||||
openspace.addSceneGraphNode(Node)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeSceneGraphNode(MilkyWayVolume)
|
||||
openspace.removeSceneGraphNode(Node)
|
||||
end)
|
||||
|
||||
asset.export(MilkyWayVolume)
|
||||
|
||||
|
||||
|
||||
asset.meta = {
|
||||
Name = "Milky Way Volume",
|
||||
Description = [[Volumetric rendering of Milky Way galaxy based on simulations from "
|
||||
"NAOJ with a custom shader]],
|
||||
Author = "OpenSpace Team",
|
||||
URL = "http://openspaceproject.com",
|
||||
License = "MIT License"
|
||||
}
|
||||
-2
@@ -4,8 +4,6 @@
|
||||
-- the plane does not become larger or smaller than a given max height and min height, in
|
||||
-- meters.
|
||||
|
||||
local earth = asset.require("scene/solarsystem/planets/earth/earth")
|
||||
|
||||
local Node = {
|
||||
Identifier = "RenderablePlaneImageLocal_Example_ScaleByDistance",
|
||||
Renderable = {
|
||||
|
||||
+4
-4
@@ -1,16 +1,16 @@
|
||||
-- Ring
|
||||
-- The `RenderableRadialGrid` can also be used to create a simple ring. This is done by
|
||||
-- Circle
|
||||
-- The `RenderableRadialGrid` can also be used to create a simple circle. This is done by
|
||||
-- setting the number of segments in each direction to 1 and make sure the inner radius
|
||||
-- is zero (which is the default).
|
||||
|
||||
local Node = {
|
||||
Identifier = "RenderableRadialGrid_Example_Ring",
|
||||
Identifier = "RenderableRadialGrid_Example_Circle",
|
||||
Renderable = {
|
||||
Type = "RenderableRadialGrid",
|
||||
GridSegments = { 1, 1 }
|
||||
},
|
||||
GUI = {
|
||||
Name = "RenderableRadialGrid - Ring",
|
||||
Name = "RenderableRadialGrid - Circle",
|
||||
Path = "/Examples"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
-- Ellipse
|
||||
-- The `RenderableRadialGrid` can also be used to create a simple ellipse. This is done by
|
||||
-- setting the number of segments in each direction to 1 and make sure the inner radius
|
||||
-- is zero (which is the default). By then applying a
|
||||
-- [NonUniformStaticScale](#base_transform_scale_nonuniformstatic) to the scene graph node
|
||||
-- this circle can be deformed into an ellipse.
|
||||
|
||||
local Node = {
|
||||
Identifier = "RenderableRadialGrid_Example_Ellipse",
|
||||
Transform = {
|
||||
Scale = {
|
||||
Type = "NonUniformStaticScale",
|
||||
Scale = { 1.5, 1.0, 1.0 }
|
||||
}
|
||||
},
|
||||
Renderable = {
|
||||
Type = "RenderableRadialGrid",
|
||||
GridSegments = { 1, 1 }
|
||||
},
|
||||
GUI = {
|
||||
Name = "RenderableRadialGrid - Ellipse",
|
||||
Path = "/Examples"
|
||||
}
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(Node)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeSceneGraphNode(Node)
|
||||
end)
|
||||
@@ -0,0 +1,25 @@
|
||||
-- Basic
|
||||
-- A simple example of a toy volume rendered using direct volume rendering.
|
||||
|
||||
local Node = {
|
||||
Identifier = "RenderableToyVolume_Example",
|
||||
Renderable = {
|
||||
Type = "RenderableToyVolume",
|
||||
Size = { 5, 5, 5 },
|
||||
ScalingExponent = 11,
|
||||
StepSize = 0.01,
|
||||
Color = { 1.0, 0.0, 0.0 }
|
||||
},
|
||||
GUI = {
|
||||
Name = "RenderableToyVolume - Basic",
|
||||
Path = "/Examples"
|
||||
}
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(Node)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeSceneGraphNode(Node)
|
||||
end)
|
||||
@@ -1,7 +1,7 @@
|
||||
-- Basic
|
||||
-- This asset creates a rotation that places a coordinate axes on the surface of a
|
||||
-- planetary body. The rotation causes the coordinate axes to remain fixed to the surface
|
||||
-- of the globe.
|
||||
-- This asset creates a rotation that places coordinate axes on the surface of a planetary
|
||||
-- body. The rotation causes the coordinate axes to remain fixed to the surface of the
|
||||
-- globe.
|
||||
--
|
||||
-- In order for this feature to work properly, the coordinate axes need to be located at
|
||||
-- the same place as well, so this example also needs a `GlobeTranslation` applied.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
-- Angle
|
||||
-- This asset creates a rotation that places a coordinate axes on the surface of a
|
||||
-- planetary body. The rotation causes the coordinate axes to remain fixed to the surface
|
||||
-- of the globe. Additionally, the coordinate axes are rotated around the up-axis by a
|
||||
-- fixed amount.
|
||||
-- This asset creates a rotation that places coordinate axes on the surface of a planetary
|
||||
-- body. The rotation causes the coordinate axes to remain fixed to the surface of the
|
||||
-- globe. Additionally, the coordinate axes are rotated around the up-axis by a fixed
|
||||
-- amount.
|
||||
--
|
||||
-- In order for this feature to work properly, the coordinate axes need to be located at
|
||||
-- the same place as well, so this example also needs a `GlobeTranslation` applied.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
-- UseCamera
|
||||
-- This asset creates a rotation that places a coordinate axes on the surface of a
|
||||
-- planetary body. The rotation causes the coordinate axes to remain fixed to the surface
|
||||
-- of the globe. In this example, the rotation of the object will be updated based on the
|
||||
-- location of the camera. When loading this example, make sure to focus the camera on
|
||||
-- the Globe object for the follow-function to work.
|
||||
-- This asset creates a rotation that places coordinate axes on the surface of a planetary
|
||||
-- body. The rotation causes the coordinate axes to remain fixed to the surface of the
|
||||
-- globe. In this example, the rotation of the object will be updated based on the
|
||||
-- location of the camera. When loading this example, make sure to focus the camera on the
|
||||
-- Globe object for the follow-function to work.
|
||||
--
|
||||
-- In order for this feature to work properly, the coordinate axes need to be located at
|
||||
-- the same place as well, so this example also needs a `GlobeTranslation` applied, which
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
-- Basic
|
||||
-- This example shows how to load and show a webpage in the rendering, in screen space.
|
||||
|
||||
local Object = {
|
||||
local Item = {
|
||||
Type = "ScreenSpaceBrowser",
|
||||
Identifier = "ScreenSpaceBrowser_Example",
|
||||
Url = "https://www.openspaceproject.com/",
|
||||
@@ -9,9 +9,9 @@ local Object = {
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(Object)
|
||||
openspace.addScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(Object)
|
||||
openspace.removeScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
-- This example shows how to display dashboard items in a screen space. In this specific
|
||||
-- example it is show the date in the simulation, but any #DashboardItem is supported.
|
||||
|
||||
local Object = {
|
||||
local Item = {
|
||||
Type = "ScreenSpaceDashboard",
|
||||
Identifier = "ScreenSpaceDashboard_Example",
|
||||
Name = "ScreenSpaceDashboard Example - Basic",
|
||||
@@ -15,9 +15,9 @@ local Object = {
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(Object)
|
||||
openspace.addScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(Object)
|
||||
openspace.removeScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
-- Basic
|
||||
-- This example creates a screen space renderable that shows the current simulation time.
|
||||
|
||||
local Item = {
|
||||
Type = "ScreenSpaceDate",
|
||||
Identifier = "ScreenSpaceDate_Example",
|
||||
Name = "ScreenSpace Date Example - Basic"
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(Item)
|
||||
end)
|
||||
@@ -0,0 +1,18 @@
|
||||
-- Day of Year
|
||||
-- This example creates a screen space renderable that shows the current simulation time
|
||||
-- with the current year and the number of days that have passed in the year.
|
||||
|
||||
local Item = {
|
||||
Type = "ScreenSpaceDate",
|
||||
Identifier = "ScreenSpaceDate_Example_DayOfYear",
|
||||
Name = "ScreenSpace Date Example - Day of Year",
|
||||
TimeFormat = "YYYY DOY"
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(Item)
|
||||
end)
|
||||
@@ -0,0 +1,19 @@
|
||||
-- Font
|
||||
-- This example creates a screen space renderable that shows the current simulation time
|
||||
-- with a non-standard font. This is using one of the fonts that is loaded by default in the
|
||||
-- openspace.cfg file.
|
||||
|
||||
local Item = {
|
||||
Type = "ScreenSpaceDate",
|
||||
Identifier = "ScreenSpaceDate_Example_Font",
|
||||
Name = "ScreenSpace Date Example - Font",
|
||||
FontName = "Light"
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(Item)
|
||||
end)
|
||||
@@ -0,0 +1,21 @@
|
||||
-- Font Size
|
||||
-- This example creates a screen space renderable that shows the current simulation time
|
||||
-- with a larger font. The FontSize parameter is increased to improve the fidelity of the
|
||||
-- text being rendered. The Scale parameter will make the text show up larger on the
|
||||
-- screen.
|
||||
|
||||
local Item = {
|
||||
Type = "ScreenSpaceDate",
|
||||
Identifier = "ScreenSpaceDate_Example_FontSize",
|
||||
Name = "ScreenSpace Date Example - Font Size",
|
||||
Scale = 0.5,
|
||||
FontSize = 72
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(Item)
|
||||
end)
|
||||
@@ -0,0 +1,18 @@
|
||||
-- No Decorations
|
||||
-- This example creates a screen space renderable that shows the current simulation time
|
||||
-- without any additional text surrounding the current date.
|
||||
|
||||
local Item = {
|
||||
Type = "ScreenSpaceDate",
|
||||
Identifier = "ScreenSpaceDate_Example_NoDecoration",
|
||||
Name = "ScreenSpace Date Example - No Decoration",
|
||||
FormatString = "{}"
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(Item)
|
||||
end)
|
||||
@@ -0,0 +1,18 @@
|
||||
-- Timezone
|
||||
-- This example creates a screen space renderable that shows the current simulation time
|
||||
-- with a timezone of UTC-7 (=PDT)
|
||||
|
||||
local Item = {
|
||||
Type = "ScreenSpaceDate",
|
||||
Identifier = "ScreenSpaceDate_Example_Timezone",
|
||||
Name = "ScreenSpace Date Example - Timezone",
|
||||
TimeFormat = "YYYY MON DD HR:MN:SC.### PDT ::UTC-7"
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(Item)
|
||||
end)
|
||||
@@ -0,0 +1,18 @@
|
||||
-- Year Month Day
|
||||
-- This example creates a screen space renderable that shows the current simulation time
|
||||
-- with a resolution of days.
|
||||
|
||||
local Item = {
|
||||
Type = "ScreenSpaceDate",
|
||||
Identifier = "ScreenSpaceDate_Example_YearMonthDay",
|
||||
Name = "ScreenSpace Date Example - Year/Month/Day",
|
||||
TimeFormat = "YYYY MON DD"
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(Item)
|
||||
end)
|
||||
@@ -4,7 +4,7 @@
|
||||
--
|
||||
-- The texture that is displayed can be changed during runtime. Here it is just set to 1.
|
||||
|
||||
local Object = {
|
||||
local Item = {
|
||||
Identifier = "ScreenSpaceDebugPlane_Example",
|
||||
Type = "ScreenSpaceDebugPlane",
|
||||
Texture = 1,
|
||||
@@ -12,9 +12,9 @@ local Object = {
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(Object)
|
||||
openspace.addScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(Object)
|
||||
openspace.removeScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
-- Create a screenspace image plane that shows the content of a local image file on disk.
|
||||
-- In this case we use a test image from the OpenSpace/data folder.
|
||||
|
||||
local Object = {
|
||||
local Item = {
|
||||
Type = "ScreenSpaceImageLocal",
|
||||
Identifier = "ScreenSpaceImageLocal_Example",
|
||||
TexturePath = openspace.absPath("${DATA}/test3.jpg"),
|
||||
@@ -10,9 +10,9 @@ local Object = {
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(Object)
|
||||
openspace.addScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(Object)
|
||||
openspace.removeScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
-- Basic
|
||||
-- Create a screenspace image plane that shows the content of an image from a web URL.
|
||||
|
||||
local Object = {
|
||||
local Item = {
|
||||
Type = "ScreenSpaceImageOnline",
|
||||
Identifier = "ScreenSpaceImageOnline_Example",
|
||||
URL = "https://data.openspaceproject.com/moon_mars/apollo8/earthrise.jpg",
|
||||
@@ -9,9 +9,9 @@ local Object = {
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(Object)
|
||||
openspace.addScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(Object)
|
||||
openspace.removeScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
+4
-4
@@ -2,12 +2,12 @@
|
||||
-- Creates a screenspace image plane with controls to for a blackout shape. Can be used
|
||||
-- when using a secondary projector to project content on a dome surface.
|
||||
|
||||
local inset = {
|
||||
local Item = {
|
||||
Identifier = "ScreenSpaceInsetBlackout_Example",
|
||||
Type = "ScreenSpaceInsetBlackout",
|
||||
Name = "ScreenSpaceInsetBlackout Example - Basic",
|
||||
Blackoutshape = {
|
||||
-- Must always contain four corners in the following order:
|
||||
-- Must always contain four corners in the following order:
|
||||
-- top-left, top-right, bottom-right, bottom-left
|
||||
Corners = { {0.0, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {0.0, 0.0} }
|
||||
},
|
||||
@@ -15,9 +15,9 @@ local inset = {
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(inset)
|
||||
openspace.addScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(inset)
|
||||
openspace.removeScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
+3
-3
@@ -9,7 +9,7 @@ local texturePath = asset.resource({
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local inset = {
|
||||
local Item = {
|
||||
Identifier = "ScreenSpaceInsetBlackout_Example_Calibration_Pattern",
|
||||
Type = "ScreenSpaceInsetBlackout",
|
||||
Name = "ScreenSpaceInsetBlackout Example - Calibration Pattern",
|
||||
@@ -24,9 +24,9 @@ local inset = {
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(inset)
|
||||
openspace.addScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(inset)
|
||||
openspace.removeScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
+3
-3
@@ -2,7 +2,7 @@
|
||||
-- Creates a screenspace image plane with controls to for a blackout shape. Can be used
|
||||
-- when using a secondary projector to project content on a dome surface.
|
||||
|
||||
local inset = {
|
||||
local Item = {
|
||||
Identifier = "ScreenSpaceInsetBlackout_Example_Points",
|
||||
Type = "ScreenSpaceInsetBlackout",
|
||||
Name = "ScreenSpaceInsetBlackout Example - Points",
|
||||
@@ -27,9 +27,9 @@ local inset = {
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(inset)
|
||||
openspace.addScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(inset)
|
||||
openspace.removeScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
+3
-3
@@ -2,7 +2,7 @@
|
||||
-- Creates a screenspace image that shows a spherical grid as an example for any
|
||||
-- [Renderable](#renderable) that can be displayed.
|
||||
|
||||
local Object = {
|
||||
local Item = {
|
||||
Type = "ScreenSpaceRenderableRenderable",
|
||||
Identifier = "ScreenSpaceRenderableRenderable_Example",
|
||||
Renderable = {
|
||||
@@ -14,9 +14,9 @@ local Object = {
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(Object)
|
||||
openspace.addScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(Object)
|
||||
openspace.removeScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
+3
-3
@@ -4,7 +4,7 @@
|
||||
-- onto the axes and increases the field of view of the camera to a wider degree. We also
|
||||
-- set the background color to be fully opaque to make it easier to see the axes.
|
||||
|
||||
local Object = {
|
||||
local Item = {
|
||||
Type = "ScreenSpaceRenderableRenderable",
|
||||
Identifier = "ScreenSpaceRenderableRenderable_Example_Axes",
|
||||
Renderable = {
|
||||
@@ -16,9 +16,9 @@ local Object = {
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(Object)
|
||||
openspace.addScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(Object)
|
||||
openspace.removeScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
+3
-3
@@ -12,7 +12,7 @@ local modelFolder = asset.resource({
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local Object = {
|
||||
local Item = {
|
||||
Type = "ScreenSpaceRenderableRenderable",
|
||||
Identifier = "ScreenSpaceRenderableRenderable_Example_ModelDistance",
|
||||
Renderable = {
|
||||
@@ -33,9 +33,9 @@ local Object = {
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(Object)
|
||||
openspace.addScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(Object)
|
||||
openspace.removeScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
+3
-3
@@ -12,7 +12,7 @@ local modelFolder = asset.resource({
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local Object = {
|
||||
local Item = {
|
||||
Type = "ScreenSpaceRenderableRenderable",
|
||||
Identifier = "ScreenSpaceRenderableRenderable_Example_Model",
|
||||
Transform = {
|
||||
@@ -39,9 +39,9 @@ local Object = {
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(Object)
|
||||
openspace.addScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(Object)
|
||||
openspace.removeScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
-- Basic
|
||||
-- This example creates a screen space renderable that displays a static text.
|
||||
|
||||
local Item = {
|
||||
Type = "ScreenSpaceText",
|
||||
Identifier = "ScreenSpaceText_Example",
|
||||
Text = "Example Text"
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(Item)
|
||||
end)
|
||||
@@ -0,0 +1,19 @@
|
||||
-- Changing Font
|
||||
-- This example creates a screen space renderable that displays a static text with a
|
||||
-- non-standard font. This is using one of the fonts that is loaded by default in the
|
||||
-- openspace.cfg file.
|
||||
|
||||
local Item = {
|
||||
Type = "ScreenSpaceText",
|
||||
Identifier = "ScreenSpaceText_Example_Font",
|
||||
Text = "Example Text - Font",
|
||||
FontName = "Light"
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(Item)
|
||||
end)
|
||||
@@ -0,0 +1,20 @@
|
||||
-- Font Size
|
||||
-- This example creates a screen space renderable that displays a static text with a
|
||||
-- larger font. The FontSize parameter is increased to improve the fidelity of the text
|
||||
-- being rendered. The Scale parameter will make the text show up larger on the screen.
|
||||
|
||||
local Item = {
|
||||
Type = "ScreenSpaceText",
|
||||
Identifier = "ScreenSpaceText_Example_FontSize",
|
||||
Text = "Example Text - Font Size",
|
||||
Scale = 0.5,
|
||||
FontSize = 72
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable(Item)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable(Item)
|
||||
end)
|
||||
@@ -0,0 +1,47 @@
|
||||
-- Basic
|
||||
-- This asset creates a translation that places coordinate axes on the surface of a
|
||||
-- planetary body. Note that this examples only the position of the coordinate axes, but
|
||||
-- leaves the orientation unchanged, causing their rotation to be inherited from the
|
||||
-- parent node.
|
||||
|
||||
-- The example needs a `RenderableGlobe` as a parent to function
|
||||
local Globe = {
|
||||
Identifier = "GlobeTranslation_Example_Globe",
|
||||
Renderable = {
|
||||
Type = "RenderableGlobe"
|
||||
},
|
||||
GUI = {
|
||||
Name = "GlobeTranslation - Basic (Globe)",
|
||||
Path = "/Examples"
|
||||
}
|
||||
}
|
||||
|
||||
local Node = {
|
||||
Identifier = "GlobeTranslation_Example",
|
||||
Parent = "GlobeTranslation_Example_Globe",
|
||||
Transform = {
|
||||
Translation = {
|
||||
Type = "GlobeTranslation",
|
||||
Globe = "GlobeTranslation_Example_Globe",
|
||||
Latitude = 20.0,
|
||||
Longitude = -45.0
|
||||
}
|
||||
},
|
||||
Renderable = {
|
||||
Type = "RenderableCartesianAxes"
|
||||
},
|
||||
GUI = {
|
||||
Name = "GlobeTranslation - Basic",
|
||||
Path = "/Examples"
|
||||
}
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(Globe)
|
||||
openspace.addSceneGraphNode(Node)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeSceneGraphNode(Node)
|
||||
openspace.removeSceneGraphNode(Globe)
|
||||
end)
|
||||
@@ -0,0 +1,58 @@
|
||||
-- Adaptive Height
|
||||
-- This asset creates a translation that places coordinate axes on the surface of a
|
||||
-- planetary body while adjusting to the existing height map on the globe. Note that this
|
||||
-- examples only the position of the coordinate axes, but leaves the orientation
|
||||
-- unchanged, causing their rotation to be inherited from the parent node.
|
||||
|
||||
-- The example needs a `RenderableGlobe` with a height map as a parent to function
|
||||
local layer = asset.require("scene/solarsystem/planets/earth/layers/heightlayers/blue_marble_height")
|
||||
local Globe = {
|
||||
Identifier = "GlobeTranslation_Example_AdaptiveHeight_Globe",
|
||||
Renderable = {
|
||||
Type = "RenderableGlobe",
|
||||
Layers = {
|
||||
HeightLayers = { layer.layer }
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "GlobeTranslation - Adaptive Height (Globe)",
|
||||
Path = "/Examples"
|
||||
}
|
||||
}
|
||||
|
||||
local Node = {
|
||||
Identifier = "GlobeTranslation_Example_AdaptiveHeight",
|
||||
Parent = "GlobeTranslation_Example_AdaptiveHeight_Globe",
|
||||
Transform = {
|
||||
Translation = {
|
||||
Type = "GlobeTranslation",
|
||||
Globe = "GlobeTranslation_Example_AdaptiveHeight_Globe",
|
||||
Latitude = 20.0,
|
||||
Longitude = -45.0,
|
||||
UseHeightmap = true
|
||||
}
|
||||
},
|
||||
Renderable = {
|
||||
Type = "RenderableCartesianAxes"
|
||||
},
|
||||
GUI = {
|
||||
Name = "GlobeTranslation - Adaptive Height",
|
||||
Path = "/Examples"
|
||||
}
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(Globe)
|
||||
-- The layer is designed for a globe with Earth scale. So we need to scale it down for
|
||||
-- it to make sense for this example
|
||||
openspace.setPropertyValueSingle("Scene.GlobeTranslation_Example_AdaptiveHeight_Globe.Renderable.Layers.HeightLayers.Earth_Bluemarble_Height.Enabled", true)
|
||||
enspace.setPropertyValueSingle("Scene.GlobeTranslation_Example_AdaptiveHeight_Globe.Renderable.Layers.HeightLayers.Earth_Bluemarble_Height.Settings.Multiplier", 1.9)
|
||||
openspace.setPropertyValueSingle("Scene.GlobeTranslation_Example_AdaptiveHeight_Globe.Renderable.Layers.HeightLayers.Earth_Bluemarble_Height.Settings.Gamma", 0.16)
|
||||
|
||||
openspace.addSceneGraphNode(Node)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeSceneGraphNode(Node)
|
||||
openspace.removeSceneGraphNode(Globe)
|
||||
end)
|
||||
@@ -0,0 +1,48 @@
|
||||
-- Fixed Height
|
||||
-- This asset creates a translation that places coordinate axes on the surface of a
|
||||
-- planetary body with a fixed height to the reference surface of the globe. Note that
|
||||
-- this examples only the position of the coordinate axes, but leaves the orientation
|
||||
-- unchanged, causing their rotation to be inherited from the parent node.
|
||||
|
||||
-- The example needs a `RenderableGlobe` with a height map as a parent to function
|
||||
local Globe = {
|
||||
Identifier = "GlobeTranslation_Example_FixedHeight_Globe",
|
||||
Renderable = {
|
||||
Type = "RenderableGlobe"
|
||||
},
|
||||
GUI = {
|
||||
Name = "GlobeTranslation - Fixed Height (Globe)",
|
||||
Path = "/Examples"
|
||||
}
|
||||
}
|
||||
|
||||
local Node = {
|
||||
Identifier = "GlobeTranslation_Example_FixedHeight",
|
||||
Parent = "GlobeTranslation_Example_FixedHeight_Globe",
|
||||
Transform = {
|
||||
Translation = {
|
||||
Type = "GlobeTranslation",
|
||||
Globe = "GlobeTranslation_Example_FixedHeight_Globe",
|
||||
Latitude = 20.0,
|
||||
Longitude = -45.0,
|
||||
Altitude = 2.0
|
||||
}
|
||||
},
|
||||
Renderable = {
|
||||
Type = "RenderableCartesianAxes"
|
||||
},
|
||||
GUI = {
|
||||
Name = "GlobeTranslation - Fixed Height",
|
||||
Path = "/Examples"
|
||||
}
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(Globe)
|
||||
openspace.addSceneGraphNode(Node)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeSceneGraphNode(Node)
|
||||
openspace.removeSceneGraphNode(Globe)
|
||||
end)
|
||||
@@ -1,29 +0,0 @@
|
||||
local transforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
|
||||
|
||||
|
||||
local ToyVolume = {
|
||||
Identifier = "RenderableToyVolume",
|
||||
Parent = transforms.SolarSystemBarycenter.Identifier,
|
||||
Renderable = {
|
||||
Type = "RenderableToyVolume",
|
||||
Size = { 5, 5, 5 },
|
||||
ScalingExponent = 11,
|
||||
StepSize = 0.01,
|
||||
Color = { 1.0, 0.0, 0.0 }
|
||||
},
|
||||
GUI = {
|
||||
Path = "/Examples"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(ToyVolume)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeSceneGraphNode(ToyVolume)
|
||||
end)
|
||||
|
||||
asset.export(ToyVolume)
|
||||
@@ -1,5 +0,0 @@
|
||||
width 1024
|
||||
lower 0.0
|
||||
upper 1.0
|
||||
mappingkey 0.0 250 250 250 0
|
||||
mappingkey 1.0 200 200 200 255
|
||||
@@ -58,7 +58,10 @@ local AltAzGrid = {
|
||||
Opacity = 0.8,
|
||||
Color = { 0.2, 0.4, 0.2 },
|
||||
LineWidth = 2.0,
|
||||
RenderBinMode = "PostDeferredTransparent"
|
||||
RenderBinMode = "PostDeferredTransparent",
|
||||
LatSegments = 19,
|
||||
LongSegments = 36
|
||||
|
||||
},
|
||||
Tag = { "nightsky_marking" },
|
||||
GUI = {
|
||||
|
||||
@@ -46,10 +46,11 @@ local Mercury = {
|
||||
Tag = { "nightsky_billboard" },
|
||||
GUI = {
|
||||
Name = "Night Sky Mercury",
|
||||
Description = [[A night sky version of the planet Mercury, making it visible as
|
||||
a bright object on the sky (textured representation).]],
|
||||
Path = "/Night Sky/Planets",
|
||||
OrderingNumber = 1
|
||||
Focusable = false,
|
||||
OrderingNumber = 1,
|
||||
Description = [[A night sky version of the planet Mercury, making it visible as
|
||||
a bright object on the sky (textured representation).]]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,10 +79,11 @@ local Venus = {
|
||||
Tag = { "nightsky_billboard" },
|
||||
GUI = {
|
||||
Name = "Night Sky Venus",
|
||||
Description = [[A night sky version of the planet Venus, making it visible as
|
||||
a bright object on the sky (textured representation).]],
|
||||
Path = "/Night Sky/Planets",
|
||||
OrderingNumber = 2
|
||||
Focusable = false,
|
||||
OrderingNumber = 2,
|
||||
Description = [[A night sky version of the planet Venus, making it visible as
|
||||
a bright object on the sky (textured representation).]]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,6 +113,7 @@ local Mars = {
|
||||
GUI = {
|
||||
Name = "Night Sky Mars",
|
||||
Path = "/Night Sky/Planets",
|
||||
Focusable = false,
|
||||
OrderingNumber = 4
|
||||
}
|
||||
}
|
||||
@@ -140,10 +143,11 @@ local Jupiter = {
|
||||
Tag = { "nightsky_billboard" },
|
||||
GUI = {
|
||||
Name = "Night Sky Jupiter",
|
||||
Description = [[A night sky version of the planet Jupiter, making it visible as
|
||||
a bright object on the sky (textured representation).]],
|
||||
Path = "/Night Sky/Planets",
|
||||
OrderingNumber = 5
|
||||
Focusable = false,
|
||||
OrderingNumber = 5,
|
||||
Description = [[A night sky version of the planet Jupiter, making it visible as
|
||||
a bright object on the sky (textured representation).]]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,6 +164,8 @@ local Saturn = {
|
||||
File = textures .. "glare.png"
|
||||
},
|
||||
SizeSettings = {
|
||||
ScaleFactor = 10,
|
||||
ScaleExponent = 15,
|
||||
MaxSize = 0.332,
|
||||
EnableMaxSizeControl = true
|
||||
},
|
||||
@@ -170,10 +176,11 @@ local Saturn = {
|
||||
Tag = { "nightsky_billboard" },
|
||||
GUI = {
|
||||
Name = "Night Sky Saturn",
|
||||
Description = [[A night sky version of the planet Saturn, making it visible as
|
||||
a bright object on the sky (textured representation).]],
|
||||
Path = "/Night Sky/Planets",
|
||||
OrderingNumber = 6
|
||||
Focusable = false,
|
||||
OrderingNumber = 6,
|
||||
Description = [[A night sky version of the planet Saturn, making it visible as
|
||||
a bright object on the sky (textured representation).]]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ local COBE = {
|
||||
GUI = {
|
||||
Name = "COBE",
|
||||
Path = "/Universe/Cosmic Microwave Background",
|
||||
Focusable = false,
|
||||
Description = [[In 1990, COBE, the Cosmic Background Explorer, took the first
|
||||
detailed map of the cosmic microwave background light. The red areas are
|
||||
relatively hotter areas of the CMB, while the blue areas are cooler than the
|
||||
@@ -71,6 +72,7 @@ local WMAP = {
|
||||
GUI = {
|
||||
Name = "WMAP",
|
||||
Path = "/Universe/Cosmic Microwave Background",
|
||||
Focusable = false,
|
||||
Description = [[WMAP, the Wilkinson Microwave Anisotropy Probe, released this all-sky
|
||||
image of the cosmic microwave background light in 2003. The blue colors are slightly
|
||||
cooler than average and red is slightly warmer, with fluctuations of about a
|
||||
@@ -104,6 +106,7 @@ local Planck = {
|
||||
GUI = {
|
||||
Name = "Planck",
|
||||
Path = "/Universe/Cosmic Microwave Background",
|
||||
Focusable = false,
|
||||
Description = [[The Planck mission's 2013 image of the cosmic microwave background
|
||||
light release is the most detailed view of the CMB we have to date. The orange
|
||||
areas represent the slightly hotter areas, and the blue areas show the areas that
|
||||
|
||||
@@ -33,7 +33,8 @@ local PlanckMultiverse1 = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Planck Multiverse 1",
|
||||
Path = "/Universe/Cosmic Microwave Background"
|
||||
Path = "/Universe/Cosmic Microwave Background",
|
||||
Focusable = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +65,8 @@ local PlanckMultiverse2 = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Planck Multiverse 2",
|
||||
Path = "/Universe/Cosmic Microwave Background"
|
||||
Path = "/Universe/Cosmic Microwave Background",
|
||||
Focusable = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +97,8 @@ local PlanckMultiverse3 = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Planck Multiverse 3",
|
||||
Path = "/Universe/Cosmic Microwave Background"
|
||||
Path = "/Universe/Cosmic Microwave Background",
|
||||
Focusable = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +129,8 @@ local PlanckMultiverse4 = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Planck Multiverse 4",
|
||||
Path = "/Universe/Cosmic Microwave Background"
|
||||
Path = "/Universe/Cosmic Microwave Background",
|
||||
Focusable = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ local EquatorialSphere = {
|
||||
Opacity = 1.0,
|
||||
Color = { 0.3, 0.3, 0.15 },
|
||||
LineWidth = 2.0,
|
||||
LatSegments = 36,
|
||||
LatSegments = 19,
|
||||
LongSegments = 24,
|
||||
},
|
||||
Tag = { "du_grid" },
|
||||
@@ -164,7 +164,9 @@ local EclipticSphere = {
|
||||
Enabled = false,
|
||||
Opacity = 1.0,
|
||||
Color = { 0.3, 0.15, 0.15 },
|
||||
LineWidth = 2.0
|
||||
LineWidth = 2.0,
|
||||
LatSegments = 19,
|
||||
LongSegments = 24
|
||||
},
|
||||
Tag = { "du_grid" },
|
||||
GUI = {
|
||||
|
||||
@@ -36,6 +36,7 @@ local OrionClusterStars = {
|
||||
GUI = {
|
||||
Name = "Orion Nebula Star Cluster",
|
||||
Path = "/Milky Way/Orion",
|
||||
Focusable = false,
|
||||
Description = [[In order to have an accurate depiction of the Orion nebula, we need to
|
||||
include the star cluster that was birthed from it. We turned to a study of the
|
||||
cluster's stellar population by Lynne Hillenbrand, who was working at the University
|
||||
|
||||
@@ -80,6 +80,7 @@ local OrionNebulaModel = {
|
||||
GUI = {
|
||||
Name = "Orion Nebula Model",
|
||||
Path = "/Milky Way/Orion",
|
||||
Focusable = false,
|
||||
Description = "Orion Nebula 3D model. See Orion Nebula for description"
|
||||
}
|
||||
}
|
||||
@@ -114,6 +115,7 @@ local OrionNebulaShocksModel = {
|
||||
GUI = {
|
||||
Name = "Orion Nebula Shocks",
|
||||
Path = "/Milky Way/Orion",
|
||||
Focusable = false,
|
||||
Description = "Orion Nebula Shocks 3D model. See Orion Nebula for description"
|
||||
}
|
||||
}
|
||||
@@ -148,6 +150,7 @@ local OrionNebulaProplydsModel = {
|
||||
GUI = {
|
||||
Name = "Orion Nebula Proplyds",
|
||||
Path = "/Milky Way/Orion",
|
||||
Focusable = false,
|
||||
Description = "Orion Nebula Proplyds 3D model. See Orion Nebula for description"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
asset.require("./trail")
|
||||
asset.require("./trail_barycentric")
|
||||
asset.require("./pluto")
|
||||
asset.require("./charon/charon")
|
||||
asset.require("./charon/charon_trail")
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
local transforms = asset.require("./transforms")
|
||||
local coreKernels = asset.require("spice/core")
|
||||
|
||||
|
||||
|
||||
local PlutoTrailBarycentric = {
|
||||
Identifier = "PlutoBarycentricTrail",
|
||||
Parent = transforms.PlutoBarycenter.Identifier,
|
||||
Renderable = {
|
||||
Type = "RenderableTrailOrbit",
|
||||
Translation = {
|
||||
Type = "SpiceTranslation",
|
||||
Target = coreKernels.ID.Pluto,
|
||||
Observer = coreKernels.ID.PlutoBarycenter
|
||||
},
|
||||
Color = { 0.00, 0.62, 1.00 },
|
||||
Period = 6.38723,
|
||||
Resolution = 1000
|
||||
},
|
||||
Tag = { "planetTrail_dwarf" },
|
||||
GUI = {
|
||||
Name = "Pluto Barycentric Trail",
|
||||
Path = "/Solar System/Dwarf Planets/Pluto",
|
||||
Focusable = false,
|
||||
Description = "Orbit of Pluto around its Barycenter"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(PlutoTrailBarycentric)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeSceneGraphNode(PlutoTrailBarycentric)
|
||||
end)
|
||||
|
||||
asset.export(PlutoTrailBarycentric)
|
||||
|
||||
|
||||
|
||||
asset.meta = {
|
||||
Name = "Pluto Barycentric Trail",
|
||||
Description = "Trail of Pluto as observed by its Barycenter",
|
||||
Author = "OpenSpace Team",
|
||||
URL = "http://openspaceproject.com",
|
||||
License = "MIT license"
|
||||
}
|
||||
@@ -34,8 +34,9 @@ local EquatorialCutplane = {
|
||||
Opacity = 0.7
|
||||
},
|
||||
GUI = {
|
||||
Name = "Cutplane Equitorial",
|
||||
Name = "Cutplane Equatorial",
|
||||
Path = "/Solar System/Heliosphere/Bastille Day 2000",
|
||||
Focusable = false,
|
||||
Description = [[Equatorial cutplane sequence for the bastille day CME event. This
|
||||
asset contains data from 2000-07-14 08:38 to 2000-07-14 12:00]]
|
||||
}
|
||||
@@ -65,6 +66,7 @@ local MeridialCutplane = {
|
||||
GUI = {
|
||||
Name = "Cutplane Meridial",
|
||||
Path = "/Solar System/Heliosphere/Bastille Day 2000",
|
||||
Focusable = false,
|
||||
Description = [[Meridial cutplane sequence for the bastille day CME event. This asset
|
||||
contains data from 2000-07-14 08:38 to 2000-07-14 12:00]]
|
||||
}
|
||||
|
||||
@@ -26,8 +26,9 @@ local TravelSpeedIndicator = {
|
||||
FadeLength = 10
|
||||
},
|
||||
GUI = {
|
||||
Name = "Speed Indicator",
|
||||
Path = "/Solar System/Heliosphere",
|
||||
Name = "Speed indicator",
|
||||
Focusable = false,
|
||||
Description = "Speed of light indicator from sun to earth"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ local CarringtonPrimeMeridian = {
|
||||
Color = { 1.0, 0.0, 0.0 },
|
||||
LineWidth = 2.0,
|
||||
LongSegments = 2,
|
||||
LatSegments = 64
|
||||
LatSegments = 19
|
||||
},
|
||||
GUI = {
|
||||
Name = "Carrington Prime Meridian",
|
||||
@@ -63,7 +63,7 @@ local WSA_GridSlice = {
|
||||
Color = { 0.8, 0.8, 0.8 },
|
||||
LineWidth = 2.0,
|
||||
LongSegments = 2,
|
||||
LatSegments = 64
|
||||
LatSegments = 19
|
||||
},
|
||||
GUI = {
|
||||
Name = "Solar Longitude Facing the Earth",
|
||||
@@ -86,8 +86,7 @@ local WSA_Grid10Degrees = {
|
||||
Type = "RenderableSphericalGrid",
|
||||
Size = gridSizeRadius,
|
||||
Color = { 0.035, 0.675, 0.255 },
|
||||
LineWidth = 1.0,
|
||||
Segments = 36
|
||||
LineWidth = 1.0
|
||||
},
|
||||
GUI = {
|
||||
Name = "Grid on Sun",
|
||||
|
||||
@@ -26,7 +26,8 @@ local Station2Boulder1Holder = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Station 2 Boulder 1",
|
||||
Path = "/Solar System/Missions/Apollo/17/Station 2"
|
||||
Path = "/Solar System/Missions/Apollo/17/Station 2",
|
||||
Focusable = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +76,8 @@ local Station2Boulder2Holder = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Station 2 Boulder 2",
|
||||
Path = "/Solar System/Missions/Apollo/17/Station 2"
|
||||
Path = "/Solar System/Missions/Apollo/17/Station 2",
|
||||
Focusable = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +126,8 @@ local Station2Boulder3Holder = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Station 2 Boulder 3",
|
||||
Path = "/Solar System/Missions/Apollo/17/Station 2"
|
||||
Path = "/Solar System/Missions/Apollo/17/Station 2",
|
||||
Focusable = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,8 @@ local Station6Frag1Holder = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Station 6 Fragment 1",
|
||||
Path = "/Solar System/Missions/Apollo/17/Station 6"
|
||||
Path = "/Solar System/Missions/Apollo/17/Station 6",
|
||||
Focusable = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +74,8 @@ local Station6Frag23Holder = {
|
||||
Parent = moon.Moon.Identifier,
|
||||
GUI = {
|
||||
Name = "Station 6 Fragments 2 & 3 Holder",
|
||||
Path = "/Solar System/Missions/Apollo/17/Station 6"
|
||||
Path = "/Solar System/Missions/Apollo/17/Station 6",
|
||||
Focusable = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,8 @@ local Station7BoulderHolder = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Station 7 Boulder",
|
||||
Path = "/Solar System/Missions/Apollo/17/Station 7"
|
||||
Path = "/Solar System/Missions/Apollo/17/Station 7",
|
||||
Focusable = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +78,8 @@ local PolyCam = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "OCAMS POLYCAM",
|
||||
Path = "/Solar System/Missions/OSIRIS REx/Instruments"
|
||||
Path = "/Solar System/Missions/OSIRIS REx/Instruments",
|
||||
Focusable = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +111,8 @@ local Rexis = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "REXIS",
|
||||
Path = "/Solar System/Missions/OSIRIS REx/Instruments"
|
||||
Path = "/Solar System/Missions/OSIRIS REx/Instruments",
|
||||
Focusable = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@ local EarthMarker = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Earth Marker",
|
||||
Path = "/Solar System/Planets/Earth"
|
||||
Path = "/Solar System/Planets/Earth",
|
||||
Focusable = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ for i,v in ipairs(layers_names) do
|
||||
local layer = {
|
||||
Identifier = Identifier .. "-" .. v,
|
||||
Name = Name .. " " .. v,
|
||||
Enabled = asset.enabled,
|
||||
Enabled = false,
|
||||
ZIndex = 100,
|
||||
FilePath = imagesDestination .. "/" .. v .. ".jpg",
|
||||
Description = Description
|
||||
|
||||
@@ -52,6 +52,7 @@ local NeptuneLabel = {
|
||||
GUI = {
|
||||
Name = "Neptune Label",
|
||||
Path = "/Solar System/Planets/Neptune",
|
||||
Focusable = false,
|
||||
Description = "Main planet label for Neptune"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,8 @@ local MirandaTrail = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Miranda Trail",
|
||||
Path = "/Solar System/Planets/Uranus/Major Moons/Miranda"
|
||||
Path = "/Solar System/Planets/Uranus/Major Moons/Miranda",
|
||||
Focusable = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +78,8 @@ local MirandaLabel = {
|
||||
Tag = { "solarsystem_labels", "moon_labels", "major_moon_labels" },
|
||||
GUI = {
|
||||
Name = "Miranda Label",
|
||||
Path = "/Solar System/Planets/Uranus/Major Moons/Miranda"
|
||||
Path = "/Solar System/Planets/Uranus/Major Moons/Miranda",
|
||||
Focusable = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +132,8 @@ local ArielTrail = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Ariel Trail",
|
||||
Path = "/Solar System/Planets/Uranus/Major Moons/Ariel"
|
||||
Path = "/Solar System/Planets/Uranus/Major Moons/Ariel",
|
||||
Focusable = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,7 +157,8 @@ local ArielLabel = {
|
||||
Tag = { "solarsystem_labels", "moon_labels", "major_moon_labels" },
|
||||
GUI = {
|
||||
Name = "Ariel Label",
|
||||
Path = "/Solar System/Planets/Uranus/Major Moons/Ariel"
|
||||
Path = "/Solar System/Planets/Uranus/Major Moons/Ariel",
|
||||
Focusable = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,7 +211,8 @@ local UmbrielTrail = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Umbriel Trail",
|
||||
Path = "/Solar System/Planets/Uranus/Major Moons/Umbriel"
|
||||
Path = "/Solar System/Planets/Uranus/Major Moons/Umbriel",
|
||||
Focusable = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,7 +236,8 @@ local UmbrielLabel = {
|
||||
Tag = { "solarsystem_labels", "moon_labels", "major_moon_labels" },
|
||||
GUI = {
|
||||
Name = "Umbriel Label",
|
||||
Path = "/Solar System/Planets/Uranus/Major Moons/Umbriel"
|
||||
Path = "/Solar System/Planets/Uranus/Major Moons/Umbriel",
|
||||
Focusable = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,7 +290,8 @@ local TitaniaTrail = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Titania Trail",
|
||||
Path = "/Solar System/Planets/Uranus/Major Moons/Titania"
|
||||
Path = "/Solar System/Planets/Uranus/Major Moons/Titania",
|
||||
Focusable = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,7 +315,8 @@ local TitaniaLabel = {
|
||||
Tag = { "solarsystem_labels", "moon_labels", "major_moon_labels" },
|
||||
GUI = {
|
||||
Name = "Titania Label",
|
||||
Path = "/Solar System/Planets/Uranus/Major Moons/Titania"
|
||||
Path = "/Solar System/Planets/Uranus/Major Moons/Titania",
|
||||
Focusable = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,7 +369,8 @@ local OberonTrail = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Oberon Trail",
|
||||
Path = "/Solar System/Planets/Uranus/Major Moons/Oberon"
|
||||
Path = "/Solar System/Planets/Uranus/Major Moons/Oberon",
|
||||
Focusable = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,7 +394,8 @@ local OberonLabel = {
|
||||
Tag = { "solarsystem_labels", "moon_labels", "major_moon_labels" },
|
||||
GUI = {
|
||||
Name = "Oberon Label",
|
||||
Path = "/Solar System/Planets/Uranus/Major Moons/Oberon"
|
||||
Path = "/Solar System/Planets/Uranus/Major Moons/Oberon",
|
||||
Focusable = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,6 +66,7 @@ local HUDFJWSTLine = {
|
||||
GUI = {
|
||||
Name = "JWST to HUDF Line",
|
||||
Path = "/Solar System/Telescopes/JWST/HUDF",
|
||||
Focusable = false,
|
||||
Description = [[
|
||||
Line from the James Webb Space Telescope to the Hubble Ultra Deep Field
|
||||
]]
|
||||
|
||||
+1
-1
Submodule ext/ghoul updated: 4ff211d7aa...b274675f3d
+6
-7
@@ -22,8 +22,8 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_BASE___SCREENSPACEFRAMEBUFFER___H__
|
||||
#define __OPENSPACE_MODULE_BASE___SCREENSPACEFRAMEBUFFER___H__
|
||||
#ifndef __OPENSPACE_CORE___SCREENSPACEFRAMEBUFFER___H__
|
||||
#define __OPENSPACE_CORE___SCREENSPACEFRAMEBUFFER___H__
|
||||
|
||||
#include <openspace/rendering/screenspacerenderable.h>
|
||||
|
||||
@@ -44,19 +44,18 @@ namespace documentation { struct Documentation; }
|
||||
* an attached texture. The texture is then used on a screen space plane that works both
|
||||
* in fisheye and flat screens.
|
||||
*/
|
||||
class ScreenSpaceFramebuffer : public ScreenSpaceRenderable {
|
||||
class ScreenSpaceRenderableFramebuffer : public ScreenSpaceRenderable {
|
||||
public:
|
||||
using RenderFunction = std::function<void()>;
|
||||
|
||||
explicit ScreenSpaceFramebuffer(const ghoul::Dictionary& dictionary);
|
||||
virtual ~ScreenSpaceFramebuffer() override;
|
||||
explicit ScreenSpaceRenderableFramebuffer(const ghoul::Dictionary& dictionary);
|
||||
virtual ~ScreenSpaceRenderableFramebuffer() override;
|
||||
|
||||
void initializeGL() override;
|
||||
void deinitializeGL() override;
|
||||
void render(const RenderData& renderData) override;
|
||||
bool isReady() const override;
|
||||
|
||||
void setSize(glm::vec2 size);
|
||||
void addRenderFunction(RenderFunction renderFunction);
|
||||
void removeAllRenderFunctions();
|
||||
|
||||
@@ -79,4 +78,4 @@ private:
|
||||
|
||||
} //namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_BASE___SCREENSPACEFRAMEBUFFER___H__
|
||||
#endif // __OPENSPACE_CORE___SCREENSPACEFRAMEBUFFER___H__
|
||||
@@ -0,0 +1,77 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2025 *
|
||||
* *
|
||||
* 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_CORE___SCREENSPACERENDERABLETEXT___H__
|
||||
#define __OPENSPACE_CORE___SCREENSPACERENDERABLETEXT___H__
|
||||
|
||||
#include <openspace/rendering/screenspacerenderable.h>
|
||||
|
||||
#include <openspace/properties/misc/stringproperty.h>
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
#include <ghoul/font/fontrenderer.h>
|
||||
|
||||
namespace ghoul { class Dictionary; }
|
||||
namespace ghoul::opengl {
|
||||
class FramebufferObject;
|
||||
class Texture;
|
||||
} // namespace ghoul::opengl
|
||||
namespace ghoul::fontrendering { class Font; }
|
||||
|
||||
namespace openspace {
|
||||
|
||||
namespace documentation { struct Documentation; }
|
||||
|
||||
class ScreenSpaceRenderableText : public ScreenSpaceRenderable {
|
||||
public:
|
||||
explicit ScreenSpaceRenderableText(const ghoul::Dictionary& dictionary);
|
||||
|
||||
void initializeGL() override;
|
||||
void deinitializeGL() override;
|
||||
bool isReady() const override;
|
||||
|
||||
void update() override;
|
||||
void render(const RenderData& renderData) override;
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
protected:
|
||||
std::string _buffer;
|
||||
|
||||
private:
|
||||
void updateFramebuffer();
|
||||
void bindTexture() override;
|
||||
|
||||
properties::StringProperty _fontName;
|
||||
properties::FloatProperty _fontSize;
|
||||
|
||||
std::shared_ptr<ghoul::fontrendering::Font> _font;
|
||||
std::unique_ptr<ghoul::fontrendering::FontRenderer> _fontRenderer;
|
||||
|
||||
std::unique_ptr<ghoul::opengl::FramebufferObject> _framebuffer;
|
||||
std::unique_ptr<ghoul::opengl::Texture> _texture;
|
||||
};
|
||||
|
||||
} //namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_CORE___SCREENSPACERENDERABLETEXT___H__
|
||||
@@ -32,7 +32,8 @@ Keyframe<T>::Keyframe(size_t i, double t, T d)
|
||||
|
||||
template <typename T>
|
||||
void Timeline<T>::addKeyframe(double timestamp, T&& data) {
|
||||
Keyframe<T> keyframe(++_nextKeyframeId, timestamp, std::move(data));
|
||||
_nextKeyframeId++;
|
||||
Keyframe<T> keyframe(_nextKeyframeId, timestamp, std::move(data));
|
||||
const auto iter = std::upper_bound(
|
||||
_keyframes.cbegin(),
|
||||
_keyframes.cend(),
|
||||
@@ -44,7 +45,8 @@ void Timeline<T>::addKeyframe(double timestamp, T&& data) {
|
||||
|
||||
template <typename T>
|
||||
void Timeline<T>::addKeyframe(double timestamp, const T& data) {
|
||||
Keyframe<T> keyframe(++_nextKeyframeId, timestamp, data);
|
||||
_nextKeyframeId++;
|
||||
Keyframe<T> keyframe(_nextKeyframeId, timestamp, data);
|
||||
const auto iter = std::upper_bound(
|
||||
_keyframes.cbegin(),
|
||||
_keyframes.cend(),
|
||||
|
||||
@@ -71,11 +71,12 @@ set(HEADER_FILES
|
||||
rendering/renderabletrailorbit.h
|
||||
rendering/renderabletrailtrajectory.h
|
||||
rendering/screenspacedashboard.h
|
||||
rendering/screenspaceframebuffer.h
|
||||
rendering/screenspacedate.h
|
||||
rendering/screenspaceimagelocal.h
|
||||
rendering/screenspaceimageonline.h
|
||||
rendering/screenspaceinsetblackout.h
|
||||
rendering/screenspacerenderablerenderable.h
|
||||
rendering/screenspacetext.h
|
||||
rendering/screenspacetimevaryingimageonline.h
|
||||
rotation/timelinerotation.h
|
||||
rotation/constantrotation.h
|
||||
@@ -149,11 +150,12 @@ set(SOURCE_FILES
|
||||
rendering/renderabletrailtrajectory.cpp
|
||||
rendering/screenspacedashboard.cpp
|
||||
rendering/screenspacedashboard_lua.inl
|
||||
rendering/screenspaceframebuffer.cpp
|
||||
rendering/screenspacedate.cpp
|
||||
rendering/screenspaceimagelocal.cpp
|
||||
rendering/screenspaceimageonline.cpp
|
||||
rendering/screenspaceinsetblackout.cpp
|
||||
rendering/screenspacerenderablerenderable.cpp
|
||||
rendering/screenspacetext.cpp
|
||||
rendering/screenspacetimevaryingimageonline.cpp
|
||||
rotation/timelinerotation.cpp
|
||||
rotation/constantrotation.cpp
|
||||
|
||||
@@ -67,11 +67,12 @@
|
||||
#include <modules/base/rendering/renderableprism.h>
|
||||
#include <modules/base/rendering/renderabletimevaryingsphere.h>
|
||||
#include <modules/base/rendering/screenspacedashboard.h>
|
||||
#include <modules/base/rendering/screenspaceframebuffer.h>
|
||||
#include <modules/base/rendering/screenspaceimagelocal.h>
|
||||
#include <modules/base/rendering/screenspaceimageonline.h>
|
||||
#include <modules/base/rendering/screenspaceinsetblackout.h>
|
||||
#include <modules/base/rendering/screenspacerenderablerenderable.h>
|
||||
#include <modules/base/rendering/screenspacedate.h>
|
||||
#include <modules/base/rendering/screenspacetext.h>
|
||||
#include <modules/base/rendering/screenspacetimevaryingimageonline.h>
|
||||
#include <modules/base/rotation/constantrotation.h>
|
||||
#include <modules/base/rotation/fixedrotation.h>
|
||||
@@ -115,7 +116,6 @@ void BaseModule::internalInitialize(const ghoul::Dictionary&) {
|
||||
ghoul_assert(fSsRenderable, "ScreenSpaceRenderable factory was not created");
|
||||
|
||||
fSsRenderable->registerClass<ScreenSpaceDashboard>("ScreenSpaceDashboard");
|
||||
fSsRenderable->registerClass<ScreenSpaceFramebuffer>("ScreenSpaceFramebuffer");
|
||||
fSsRenderable->registerClass<ScreenSpaceImageLocal>("ScreenSpaceImageLocal");
|
||||
fSsRenderable->registerClass<ScreenSpaceImageOnline>("ScreenSpaceImageOnline");
|
||||
fSsRenderable->registerClass<ScreenSpaceInsetBlackout>("ScreenSpaceInsetBlackout");
|
||||
@@ -125,6 +125,8 @@ void BaseModule::internalInitialize(const ghoul::Dictionary&) {
|
||||
fSsRenderable->registerClass<ScreenSpaceTimeVaryingImageOnline>(
|
||||
"ScreenSpaceTimeVaryingImageOnline"
|
||||
);
|
||||
fSsRenderable->registerClass<ScreenSpaceDate>("ScreenSpaceDate");
|
||||
fSsRenderable->registerClass<ScreenSpaceText>("ScreenSpaceText");
|
||||
|
||||
|
||||
ghoul::TemplateFactory<DashboardItem>* fDashboard =
|
||||
@@ -308,11 +310,12 @@ std::vector<documentation::Documentation> BaseModule::documentations() const {
|
||||
SizeMappingComponent::Documentation(),
|
||||
|
||||
ScreenSpaceDashboard::Documentation(),
|
||||
ScreenSpaceFramebuffer::Documentation(),
|
||||
ScreenSpaceDate::Documentation(),
|
||||
ScreenSpaceImageLocal::Documentation(),
|
||||
ScreenSpaceImageOnline::Documentation(),
|
||||
ScreenSpaceInsetBlackout::Documentation(),
|
||||
ScreenSpaceRenderableRenderable::Documentation(),
|
||||
ScreenSpaceText::Documentation(),
|
||||
ScreenSpaceTimeVaryingImageOnline::Documentation(),
|
||||
|
||||
ConstantRotation::Documentation(),
|
||||
|
||||
@@ -124,7 +124,7 @@ RenderableSphericalGrid::RenderableSphericalGrid(const ghoul::Dictionary& dictio
|
||||
, _gridProgram(nullptr)
|
||||
, _color(ColorInfo, glm::vec3(0.5f), glm::vec3(0.f), glm::vec3(1.f))
|
||||
, _longSegments(LongSegmentsInfo, 36, 4, 200)
|
||||
, _latSegments(LatSegmentsInfo, 36, 4, 200)
|
||||
, _latSegments(LatSegmentsInfo, 19, 4, 200)
|
||||
, _lineWidth(LineWidthInfo, 0.5f, 1.f, 20.f)
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
@@ -136,9 +136,8 @@ RenderableSphericalGrid::RenderableSphericalGrid(const ghoul::Dictionary& dictio
|
||||
addProperty(_color);
|
||||
|
||||
auto gridDirty = [this]() {
|
||||
if (_longSegments.value() % 2 == 1) {
|
||||
_longSegments = _longSegments - 1;
|
||||
}
|
||||
_longSegments = std::max<int>(_longSegments, 3);
|
||||
_latSegments = std::max<int>(_latSegments, 3);
|
||||
_gridIsDirty = true;
|
||||
};
|
||||
_longSegments = p.segments.value_or(p.longSegments.value_or(_longSegments));
|
||||
@@ -188,11 +187,9 @@ void RenderableSphericalGrid::initializeGL() {
|
||||
|
||||
glGenVertexArrays(1, &_vaoID);
|
||||
glGenBuffers(1, &_vBufferID);
|
||||
glGenBuffers(1, &_iBufferID);
|
||||
|
||||
glBindVertexArray(_vaoID);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vBufferID);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iBufferID);
|
||||
glEnableVertexAttribArray(0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
@@ -204,9 +201,6 @@ void RenderableSphericalGrid::deinitializeGL() {
|
||||
glDeleteBuffers(1, &_vBufferID);
|
||||
_vBufferID = 0;
|
||||
|
||||
glDeleteBuffers(1, &_iBufferID);
|
||||
_iBufferID = 0;
|
||||
|
||||
BaseModule::ProgramObjectManager.release(
|
||||
"GridProgram",
|
||||
[](ghoul::opengl::ProgramObject* p) {
|
||||
@@ -239,8 +233,23 @@ void RenderableSphericalGrid::render(const RenderData& data, RendererTasks&) {
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
|
||||
glBindVertexArray(_vaoID);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iBufferID);
|
||||
glDrawElements(GL_LINES, 6 * _longSegments * _latSegments, GL_UNSIGNED_INT, nullptr);
|
||||
|
||||
// Render latitude rings
|
||||
glMultiDrawArrays(
|
||||
GL_LINE_LOOP,
|
||||
_latitudeRenderInfo.first.data(),
|
||||
_latitudeRenderInfo.count.data(),
|
||||
_latSegments
|
||||
);
|
||||
|
||||
// Render longitude segments
|
||||
glMultiDrawArrays(
|
||||
GL_LINE_STRIP,
|
||||
_longitudeRenderInfo.first.data(),
|
||||
_longitudeRenderInfo.count.data(),
|
||||
_longSegments
|
||||
);
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
_gridProgram->deactivate();
|
||||
@@ -286,71 +295,72 @@ void RenderableSphericalGrid::update(const UpdateData&) {
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int vertSize = (_longSegments + 1) * (_latSegments + 1);
|
||||
std::vector<Vertex> vert = std::vector<Vertex>(vertSize, { 0.f, 0.f, 0.f });
|
||||
unsigned int idxSize = 6 * _longSegments * _latSegments;
|
||||
std::vector<int> idx = std::vector<int>(idxSize, 0);
|
||||
// Instead of using an element buffer which didn't save that much memory and just
|
||||
// caused some indirections, we are creating two sets of vertices in the same vertex
|
||||
// buffer in this function. First all of the vertices for the longitudinal rings, one
|
||||
// ring after another. After that it is all the vertices for the latitudinal arcs, one
|
||||
// arc after another
|
||||
|
||||
int nr = 0;
|
||||
|
||||
for (int lat = 0; lat <= _latSegments; lat++) {
|
||||
// define an extra vertex around the y-axis due to texture mapping
|
||||
for (int lng = 0; lng <= _longSegments; lng++) {
|
||||
// * 2 since we store all vertices twice
|
||||
const unsigned int vertSize = _longSegments * _latSegments * 2;
|
||||
std::vector<Vertex> vert;
|
||||
vert.reserve(vertSize);
|
||||
for (int lat = 0; lat < _latSegments; lat++) {
|
||||
for (int lng = 0; lng < _longSegments; lng++) {
|
||||
// inclination angle (north to south)
|
||||
const float theta = lat * glm::pi<float>() / _latSegments * 2.f; // 0 -> PI
|
||||
const float theta =
|
||||
static_cast<float>(lat) / static_cast<float>(_latSegments - 1) *
|
||||
glm::pi<float>(); // 0 -> PI
|
||||
|
||||
// azimuth angle (east to west)
|
||||
const float phi = lng * 2.f * glm::pi<float>() / _longSegments; // 0 -> 2*PI
|
||||
// Dividing by one segment more as the points for 0 and 2*pi are identical
|
||||
const float phi =
|
||||
static_cast<float>(lng) / static_cast<float>(_longSegments) *
|
||||
2.f * glm::pi<float>(); // 0 -> 2*PI
|
||||
|
||||
const float x = std::sin(phi) * std::sin(theta); //
|
||||
const float y = std::cos(theta); // up
|
||||
const float z = std::cos(phi) * std::sin(theta); //
|
||||
|
||||
glm::vec3 normal = glm::vec3(x, y, z);
|
||||
if (x != 0.f || y != 0.f || z != 0.f) {
|
||||
normal = glm::normalize(normal);
|
||||
}
|
||||
|
||||
glm::vec4 tmp = glm::vec4(x, y, z, 1.f);
|
||||
const glm::mat4 rot = glm::rotate(
|
||||
glm::mat4(1.f),
|
||||
glm::half_pi<float>(),
|
||||
glm::vec3(1.f, 0.f, 0.f)
|
||||
);
|
||||
tmp = glm::vec4(glm::dmat4(rot) * glm::dvec4(tmp));
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
vert[nr].location[i] = tmp[i];
|
||||
}
|
||||
++nr;
|
||||
const float y = std::cos(phi) * std::sin(theta); //
|
||||
const float z = std::cos(theta); // up
|
||||
vert.push_back({ x, y, z });
|
||||
}
|
||||
}
|
||||
|
||||
nr = 0;
|
||||
// define indices for all triangles
|
||||
for (int i = 1; i <= _latSegments; i++) {
|
||||
for (int j = 0; j < _longSegments; j++) {
|
||||
const int t = _longSegments + 1;
|
||||
idx[nr] = t * (i - 1) + j + 0; ++nr;
|
||||
idx[nr] = t * (i + 0) + j + 0; ++nr;
|
||||
idx[nr] = t * (i + 0) + j + 1; ++nr;
|
||||
idx[nr] = t * (i - 1) + j + 1; ++nr;
|
||||
idx[nr] = t * (i - 1) + j + 0; ++nr;
|
||||
// Create the render info struct to be able to render the longitude rings using
|
||||
// glMultiDrawArrays in the render function
|
||||
_latitudeRenderInfo.first.clear();
|
||||
_latitudeRenderInfo.count.clear();
|
||||
for (int i = 0; i < _latSegments; i++) {
|
||||
_latitudeRenderInfo.first.push_back(i * _longSegments);
|
||||
_latitudeRenderInfo.count.push_back(_longSegments);
|
||||
}
|
||||
|
||||
// Create the duplicate vertex entries to efficiently render the latitude arcs. We
|
||||
// take every vertex in a longitude segment and connect it to the same index along all
|
||||
// latitude arcs
|
||||
for (int lng = 0; lng < _longSegments; lng++) {
|
||||
for (int lat = 0; lat < _latSegments; lat++) {
|
||||
Vertex v = vert[lat * _longSegments + lng];
|
||||
vert.push_back(v);
|
||||
}
|
||||
}
|
||||
|
||||
// Create the render info struct to be able to render the latitude arcs using
|
||||
// glMultiDrawArrays in the render function. The `base` is the offset to make this
|
||||
// render call use the vertices that are in the second "block" of the VBO
|
||||
_longitudeRenderInfo.first.clear();
|
||||
_longitudeRenderInfo.count.clear();
|
||||
const int base = _longSegments * _latSegments;
|
||||
for (int i = 0; i < _longSegments; i++) {
|
||||
_longitudeRenderInfo.first.push_back(i * _latSegments + base);
|
||||
_longitudeRenderInfo.count.push_back(_latSegments);
|
||||
}
|
||||
|
||||
|
||||
glBindVertexArray(_vaoID);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vBufferID);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertSize * sizeof(Vertex), vert.data(), GL_STATIC_DRAW);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), nullptr);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iBufferID);
|
||||
glBufferData(
|
||||
GL_ELEMENT_ARRAY_BUFFER,
|
||||
idxSize * sizeof(int),
|
||||
idx.data(), GL_STATIC_DRAW
|
||||
);
|
||||
|
||||
_gridIsDirty = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,14 @@ protected:
|
||||
|
||||
GLuint _vaoID = 0;
|
||||
GLuint _vBufferID = 0;
|
||||
GLuint _iBufferID = 0;
|
||||
struct {
|
||||
std::vector<GLint> first;
|
||||
std::vector<GLsizei> count;
|
||||
} _latitudeRenderInfo;
|
||||
struct {
|
||||
std::vector<GLint> first;
|
||||
std::vector<GLsizei> count;
|
||||
} _longitudeRenderInfo;
|
||||
|
||||
bool _gridIsDirty = true;
|
||||
|
||||
|
||||
@@ -769,7 +769,7 @@ void RenderableModel::render(const RenderData& data, RendererTasks&) {
|
||||
_lightDirectionsViewSpaceBuffer[nLightSources] =
|
||||
lightSource->directionViewSpace(data);
|
||||
|
||||
++nLightSources;
|
||||
nLightSources++;
|
||||
}
|
||||
|
||||
if (_uniformCache.performShading != -1) {
|
||||
|
||||
@@ -408,7 +408,7 @@ RenderableTrailOrbit::UpdateReport RenderableTrailOrbit::updateTrails(
|
||||
else {
|
||||
// Move the current pointer fowards one step to be used as the new
|
||||
// floating
|
||||
++_primaryRenderInformation.first;
|
||||
_primaryRenderInformation.first++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ documentation::Documentation ScreenSpaceDashboard::Documentation() {
|
||||
}
|
||||
|
||||
ScreenSpaceDashboard::ScreenSpaceDashboard(const ghoul::Dictionary& dictionary)
|
||||
: ScreenSpaceFramebuffer(dictionary)
|
||||
: ScreenSpaceRenderableFramebuffer(dictionary)
|
||||
, _useMainDashboard(UseMainInfo, false)
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
@@ -98,7 +98,7 @@ ScreenSpaceDashboard::ScreenSpaceDashboard(const ghoul::Dictionary& dictionary)
|
||||
}
|
||||
|
||||
void ScreenSpaceDashboard::initializeGL() {
|
||||
ScreenSpaceFramebuffer::initializeGL();
|
||||
ScreenSpaceRenderableFramebuffer::initializeGL();
|
||||
|
||||
addRenderFunction([this]() {
|
||||
glm::vec2 penPosition = glm::vec2(0.f, _size.value().x);
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#ifndef __OPENSPACE_MODULE_BASE___SCREENSPACEDASHBOARD___H__
|
||||
#define __OPENSPACE_MODULE_BASE___SCREENSPACEDASHBOARD___H__
|
||||
|
||||
#include <modules/base/rendering/screenspaceframebuffer.h>
|
||||
#include <openspace/rendering/screenspacerenderableframebuffer.h>
|
||||
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
#include <openspace/rendering/dashboard.h>
|
||||
@@ -40,7 +40,7 @@ namespace openspace {
|
||||
namespace documentation { struct Documentation; }
|
||||
namespace scripting { struct LuaLibrary; }
|
||||
|
||||
class ScreenSpaceDashboard : public ScreenSpaceFramebuffer {
|
||||
class ScreenSpaceDashboard : public ScreenSpaceRenderableFramebuffer {
|
||||
public:
|
||||
explicit ScreenSpaceDashboard(const ghoul::Dictionary& dictionary);
|
||||
virtual ~ScreenSpaceDashboard() override = default;
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2025 *
|
||||
* *
|
||||
* 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/screenspacedate.h>
|
||||
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <openspace/util/time.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/opengl/framebufferobject.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
|
||||
namespace {
|
||||
constexpr openspace::properties::Property::PropertyInfo FormatStringInfo = {
|
||||
"FormatString",
|
||||
"Format string",
|
||||
"The format text describing how this dashboard item renders its text. This text "
|
||||
"must contain exactly one {} which is a placeholder that will contain the date "
|
||||
"in the format as specified by `TimeFormat`.",
|
||||
openspace::properties::Property::Visibility::AdvancedUser
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo TimeFormatInfo = {
|
||||
"TimeFormat",
|
||||
"Time format",
|
||||
"The format string used for formatting the date/time before being passed to the "
|
||||
"string in FormatString. See "
|
||||
"https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/timout_c.html for full "
|
||||
"information about how to structure this format.",
|
||||
openspace::properties::Property::Visibility::User
|
||||
};
|
||||
|
||||
// This `ScreenSpaceRenderable` shows the current in-game simulation time. The
|
||||
// `FormatString` and the `TimeFormat` options provide the ability to customize the
|
||||
// output that is printed. See these two parameters for more information on how to
|
||||
// structure the inputs.
|
||||
struct [[codegen::Dictionary(ScreenSpaceTextDate)]] Parameters {
|
||||
// [[codegen::verbatim(FormatStringInfo.description)]]
|
||||
std::optional<std::string> formatString;
|
||||
|
||||
// [[codegen::verbatim(TimeFormatInfo.description)]]
|
||||
std::optional<std::string> timeFormat;
|
||||
};
|
||||
#include "screenspacedate_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation ScreenSpaceDate::Documentation() {
|
||||
return codegen::doc<Parameters>(
|
||||
"base_screenspace_date",
|
||||
ScreenSpaceRenderableText::Documentation()
|
||||
);
|
||||
}
|
||||
|
||||
ScreenSpaceDate::ScreenSpaceDate(const ghoul::Dictionary& dictionary)
|
||||
: ScreenSpaceRenderableText(dictionary)
|
||||
, _formatString(FormatStringInfo, "Date: {}")
|
||||
, _timeFormat(TimeFormatInfo, "YYYY MON DD HR:MN:SC.### UTC ::RND")
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
_formatString = p.formatString.value_or(_formatString);
|
||||
addProperty(_formatString);
|
||||
|
||||
_timeFormat = p.timeFormat.value_or(_timeFormat);
|
||||
addProperty(_timeFormat);
|
||||
}
|
||||
|
||||
void ScreenSpaceDate::update() {
|
||||
std::string time = SpiceManager::ref().dateFromEphemerisTime(
|
||||
global::timeManager->time().j2000Seconds(),
|
||||
_timeFormat.value().c_str()
|
||||
);
|
||||
|
||||
try {
|
||||
// @CPP26(abock): This can be replaced with std::runtime_format
|
||||
_buffer = std::vformat(_formatString.value(), std::make_format_args(time));
|
||||
}
|
||||
catch (const std::format_error&) {
|
||||
LERRORC("ScreenSpaceDate", "Illegal format string");
|
||||
}
|
||||
|
||||
ScreenSpaceRenderableText::update();
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -0,0 +1,49 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2025 *
|
||||
* *
|
||||
* 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___SCREENSPACEDATE___H__
|
||||
#define __OPENSPACE_MODULE_BASE___SCREENSPACEDATE___H__
|
||||
|
||||
#include <openspace/rendering/screenspacerenderabletext.h>
|
||||
|
||||
#include <openspace/properties/misc/stringproperty.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class ScreenSpaceDate : public ScreenSpaceRenderableText {
|
||||
public:
|
||||
explicit ScreenSpaceDate(const ghoul::Dictionary& dictionary);
|
||||
|
||||
void update() override;
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
private:
|
||||
properties::StringProperty _formatString;
|
||||
properties::StringProperty _timeFormat;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_BASE___SCREENSPACEDATE___H__
|
||||
@@ -143,13 +143,13 @@ namespace openspace {
|
||||
documentation::Documentation ScreenSpaceRenderableRenderable::Documentation() {
|
||||
return codegen::doc<Parameters>(
|
||||
"base_screenspace_renderable",
|
||||
ScreenSpaceFramebuffer::Documentation()
|
||||
ScreenSpaceRenderableFramebuffer::Documentation()
|
||||
);
|
||||
}
|
||||
|
||||
ScreenSpaceRenderableRenderable::ScreenSpaceRenderableRenderable(
|
||||
const ghoul::Dictionary& dictionary)
|
||||
: ScreenSpaceFramebuffer(dictionary)
|
||||
: ScreenSpaceRenderableFramebuffer(dictionary)
|
||||
, _time(
|
||||
TimeInfo,
|
||||
0.0,
|
||||
@@ -232,7 +232,7 @@ ScreenSpaceRenderableRenderable::ScreenSpaceRenderableRenderable(
|
||||
ScreenSpaceRenderableRenderable::~ScreenSpaceRenderableRenderable() {}
|
||||
|
||||
void ScreenSpaceRenderableRenderable::initialize() {
|
||||
ScreenSpaceFramebuffer::initialize();
|
||||
ScreenSpaceRenderableFramebuffer::initialize();
|
||||
_transform.translation->initialize();
|
||||
_transform.rotation->initialize();
|
||||
_transform.scale->initialize();
|
||||
@@ -240,7 +240,7 @@ void ScreenSpaceRenderableRenderable::initialize() {
|
||||
}
|
||||
|
||||
void ScreenSpaceRenderableRenderable::initializeGL() {
|
||||
ScreenSpaceFramebuffer::initializeGL();
|
||||
ScreenSpaceRenderableFramebuffer::initializeGL();
|
||||
|
||||
_renderable->initializeGL();
|
||||
|
||||
@@ -288,7 +288,7 @@ void ScreenSpaceRenderableRenderable::deinitializeGL() {
|
||||
_renderable->deinitializeGL();
|
||||
_renderable->deinitialize();
|
||||
|
||||
ScreenSpaceFramebuffer::deinitializeGL();
|
||||
ScreenSpaceRenderableFramebuffer::deinitializeGL();
|
||||
}
|
||||
|
||||
void ScreenSpaceRenderableRenderable::update() {
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#ifndef __OPENSPACE_MODULE_BASE___SCREENSPACERENDERABLERENDERABLE___H__
|
||||
#define __OPENSPACE_MODULE_BASE___SCREENSPACERENDERABLERENDERABLE___H__
|
||||
|
||||
#include <modules/base//rendering/screenspaceframebuffer.h>
|
||||
#include <openspace/rendering/screenspacerenderableframebuffer.h>
|
||||
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
#include <openspace/properties/scalar/doubleproperty.h>
|
||||
@@ -43,7 +43,7 @@ class Translation;
|
||||
|
||||
namespace documentation { struct Documentation; }
|
||||
|
||||
class ScreenSpaceRenderableRenderable : public ScreenSpaceFramebuffer {
|
||||
class ScreenSpaceRenderableRenderable : public ScreenSpaceRenderableFramebuffer {
|
||||
public:
|
||||
using RenderFunction = std::function<void()>;
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2025 *
|
||||
* *
|
||||
* 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/screenspacetext.h>
|
||||
|
||||
#include <ghoul/opengl/framebufferobject.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
|
||||
namespace {
|
||||
constexpr openspace::properties::Property::PropertyInfo TextInfo = {
|
||||
"Text",
|
||||
"Text",
|
||||
"The text to be displayed.",
|
||||
openspace::properties::Property::Visibility::User
|
||||
};
|
||||
|
||||
// This `ScreenSpaceRenderable` shows a static text that can be changed via a
|
||||
// property.
|
||||
struct [[codegen::Dictionary(DashboardItemText)]] Parameters {
|
||||
// [[codegen::verbatim(TextInfo.description)]]
|
||||
std::optional<std::string> text;
|
||||
};
|
||||
#include "screenspacetext_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation ScreenSpaceText::Documentation() {
|
||||
return codegen::doc<Parameters>(
|
||||
"base_screenspace_text",
|
||||
ScreenSpaceRenderableText::Documentation()
|
||||
);
|
||||
}
|
||||
|
||||
ScreenSpaceText::ScreenSpaceText(const ghoul::Dictionary& dictionary)
|
||||
: ScreenSpaceRenderableText(dictionary)
|
||||
, _text(TextInfo, "")
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
_text = p.text.value_or(_text);
|
||||
addProperty(_text);
|
||||
}
|
||||
|
||||
void ScreenSpaceText::update() {
|
||||
_buffer = _text.value();
|
||||
|
||||
ScreenSpaceRenderableText::update();
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -0,0 +1,48 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2025 *
|
||||
* *
|
||||
* 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___SCREENSPACETEXT___H__
|
||||
#define __OPENSPACE_MODULE_BASE___SCREENSPACETEXT___H__
|
||||
|
||||
#include <openspace/rendering/screenspacerenderabletext.h>
|
||||
|
||||
#include <openspace/properties/misc/stringproperty.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class ScreenSpaceText : public ScreenSpaceRenderableText {
|
||||
public:
|
||||
explicit ScreenSpaceText(const ghoul::Dictionary& dictionary);
|
||||
|
||||
void update() override;
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
private:
|
||||
properties::StringProperty _text;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_BASE___SCREENSPACETEXT___H__
|
||||
@@ -21,14 +21,14 @@ openspace.debugging.documentation = {
|
||||
current focus node is used instead.
|
||||
\\param scale An optional parameter that specifies the size of the coordinate axes,
|
||||
in meters. If not specified, the size is set to 2.5 times the
|
||||
interaction sphere of the selected node.
|
||||
bounding sphere of the selected node.
|
||||
]]
|
||||
}
|
||||
}
|
||||
|
||||
openspace.debugging.createCoordinateAxes = function (nodeIdentifier, scale)
|
||||
local node = nodeIdentifier or openspace.navigation.getNavigationState().Anchor
|
||||
local sphere = openspace.propertyValue("Scene." .. node .. ".EvaluatedInteractionSphere")
|
||||
local sphere = openspace.propertyValue("Scene." .. node .. ".EvaluatedBoundingSphere")
|
||||
if sphere == -1 then
|
||||
sphere = 1
|
||||
end
|
||||
|
||||
@@ -130,7 +130,7 @@ std::vector<std::string> hostStarsWithSufficientData() {
|
||||
// Read number of lines
|
||||
int nExoplanets = 0;
|
||||
while (ghoul::getline(lookupTableFile, line)) {
|
||||
++nExoplanets;
|
||||
nExoplanets++;
|
||||
}
|
||||
lookupTableFile.clear();
|
||||
lookupTableFile.seekg(0);
|
||||
|
||||
@@ -148,7 +148,7 @@ void ExoplanetsDataPreparationTask::perform(
|
||||
int total = 0;
|
||||
std::string row;
|
||||
while (ghoul::getline(inputDataFile, row)) {
|
||||
++total;
|
||||
total++;
|
||||
}
|
||||
inputDataFile.clear();
|
||||
inputDataFile.seekg(0);
|
||||
@@ -161,7 +161,7 @@ void ExoplanetsDataPreparationTask::perform(
|
||||
|
||||
int exoplanetCount = 0;
|
||||
while (ghoul::getline(inputDataFile, row)) {
|
||||
++exoplanetCount;
|
||||
exoplanetCount++;
|
||||
progressCallback(static_cast<float>(exoplanetCount) / static_cast<float>(total));
|
||||
|
||||
PlanetData planetData = parseDataRow(
|
||||
|
||||
@@ -193,7 +193,7 @@ void KameleonVolumeToFieldlinesTask::perform(
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
}
|
||||
++fileNumber;
|
||||
fileNumber++;
|
||||
}
|
||||
|
||||
// Ideally, we would want to signal about progress earlier as well, but
|
||||
|
||||
@@ -371,7 +371,7 @@ void FieldlinesState::saveStateToJson(const std::string& absPath) {
|
||||
size_t pointIndex = 0;
|
||||
for (size_t lineIndex = 0; lineIndex < nLines; lineIndex++) {
|
||||
json jData = json::array();
|
||||
for (GLsizei i = 0; i < _lineCount[lineIndex]; i++, ++pointIndex) {
|
||||
for (GLsizei i = 0; i < _lineCount[lineIndex]; i++, pointIndex++) {
|
||||
const glm::vec3 pos = _vertexPositions[pointIndex];
|
||||
json jDataElement = { pos.x, pos.y, pos.z };
|
||||
|
||||
|
||||
@@ -176,7 +176,7 @@ extractSeedPointsFromFiles(std::filesystem::path path, size_t nth)
|
||||
outVec.push_back(std::move(point));
|
||||
}
|
||||
}
|
||||
++linenumber;
|
||||
linenumber++;
|
||||
}
|
||||
|
||||
if (outVec.empty()) {
|
||||
|
||||
@@ -1022,7 +1022,7 @@ bool OctreeManager::insertInNode(OctreeNode& node, const std::vector<float>& sta
|
||||
storeStarData(node, starValues);
|
||||
}
|
||||
|
||||
return insertInNode(*node.children[index], starValues, ++depth);
|
||||
return insertInNode(*node.children[index], starValues, depth + 1);
|
||||
}
|
||||
|
||||
void OctreeManager::sliceNodeLodCache(OctreeNode& node) {
|
||||
|
||||
@@ -118,27 +118,6 @@ GDALDataType toGDALDataType(GLenum glType) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use as a helper function when determining the maximum tile level. This function
|
||||
* returns the negated number of overviews requred to downscale the highest overview
|
||||
* dataset so that it fits within minimumPixelSize pixels in the x-dimension.
|
||||
*/
|
||||
int calculateTileLevelDifference(GDALDataset* dataset, int minimumPixelSize) {
|
||||
GDALRasterBand* firstBand = dataset->GetRasterBand(1);
|
||||
GDALRasterBand* maxOverview = nullptr;
|
||||
const int numOverviews = firstBand->GetOverviewCount();
|
||||
if (numOverviews <= 0) { // No overviews. Use first band.
|
||||
maxOverview = firstBand;
|
||||
}
|
||||
else { // Pick the highest overview.
|
||||
maxOverview = firstBand->GetOverview(numOverviews - 1);
|
||||
}
|
||||
const int sizeLevel0 = maxOverview->GetXSize();
|
||||
const double diff = log2(minimumPixelSize) - log2(sizeLevel0);
|
||||
const double intdiff = diff >= 0 ? ceil(diff) : floor(diff);
|
||||
return static_cast<int>(intdiff);
|
||||
}
|
||||
|
||||
bool isInside(const PixelRegion& lhs, const PixelRegion& rhs) {
|
||||
const glm::ivec2 e = lhs.start + lhs.numPixels;
|
||||
const glm::ivec2 re = rhs.start + rhs.numPixels;
|
||||
@@ -434,17 +413,18 @@ void RawTileDataReader::initialize() {
|
||||
_padfTransform = geoTransform(_rasterXSize, _rasterYSize);
|
||||
}
|
||||
|
||||
const double tileLevelDifference = calculateTileLevelDifference(
|
||||
_dataset,
|
||||
_initData.dimensions.x
|
||||
);
|
||||
|
||||
const int numOverviews = _dataset->GetRasterBand(1)->GetOverviewCount();
|
||||
_maxChunkLevel = static_cast<int>(-tileLevelDifference);
|
||||
if (numOverviews > 0) {
|
||||
_maxChunkLevel += numOverviews;
|
||||
|
||||
const int nOverviews = _dataset->GetRasterBand(1)->GetOverviewCount();
|
||||
if (nOverviews > 0) {
|
||||
_maxChunkLevel = nOverviews;
|
||||
}
|
||||
else {
|
||||
const int sizeLevel0 = _dataset->GetRasterBand(1)->GetXSize();
|
||||
const double diff = log2(sizeLevel0) - log2(_initData.dimensions.x);
|
||||
const double intdiff = diff >= 0 ? ceil(diff) : floor(diff);
|
||||
_maxChunkLevel = intdiff;
|
||||
}
|
||||
_maxChunkLevel = std::max(_maxChunkLevel, 2);
|
||||
}
|
||||
|
||||
void RawTileDataReader::reset() {
|
||||
|
||||
@@ -837,7 +837,7 @@ KameleonWrapper::TraceLine KameleonWrapper::traceCartesianFieldline(
|
||||
|
||||
pos = pos + (step / 6.f) * (k1 + 2.f * k2 + 2.f * k3 + k4);
|
||||
|
||||
++numSteps;
|
||||
numSteps++;
|
||||
if (numSteps > MaxSteps) {
|
||||
LDEBUG(std::format("Max number of steps taken ({})", MaxSteps));
|
||||
break;
|
||||
@@ -951,7 +951,7 @@ KameleonWrapper::TraceLine KameleonWrapper::traceLorentzTrajectory(
|
||||
|
||||
v0 = v0 + step / 6.f * (k1 + 2.f * k2 + 2.f * k3 + k4);
|
||||
|
||||
++numSteps;
|
||||
numSteps++;
|
||||
if (numSteps > MaxSteps) {
|
||||
LDEBUG(std::format("Max number of steps taken ({})", MaxSteps));
|
||||
break;
|
||||
|
||||
@@ -73,7 +73,8 @@ bool ErrorHistogramManager::buildHistograms(int numBins) {
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
pb.print(++processedLeaves);
|
||||
processedLeaves++;
|
||||
pb.print(processedLeaves);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -848,7 +848,7 @@ std::vector<Parameters> readMpcFile(const std::filesystem::path& file) {
|
||||
argPeriapsis,
|
||||
meanAnomaly,
|
||||
epochFromYMDdSubstring(epochDate),
|
||||
std::chrono::seconds(std::chrono::hours(24)).count() / meanMotion
|
||||
(360.0 / meanMotion) * std::chrono::seconds(std::chrono::hours(24)).count()
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@@ -340,7 +340,7 @@ bool RenderableConstellationBounds::loadVertexFile() {
|
||||
static_cast<float>(rectangularValues[1]),
|
||||
static_cast<float>(rectangularValues[2])
|
||||
});
|
||||
++currentLineNumber;
|
||||
currentLineNumber++;
|
||||
}
|
||||
|
||||
// Due to the way we read the file, the first (empty) constellation bounds will not
|
||||
|
||||
@@ -624,7 +624,7 @@ void RenderableFluxNodes::populateStartTimes() {
|
||||
std::string columnName;
|
||||
// loops through the names/columns in first line/header
|
||||
while (s >> columnName) {
|
||||
++nColumns;
|
||||
nColumns++;
|
||||
}
|
||||
while (ghoul::getline(tfs, line)) { // for each line of data
|
||||
std::istringstream iss(line);
|
||||
|
||||
@@ -40,18 +40,24 @@
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <execution>
|
||||
#include <fstream>
|
||||
#include <random>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
// The possible values for the _renderingModes property
|
||||
enum RenderingMode {
|
||||
enum class RenderMode {
|
||||
RenderingModeTrail = 0,
|
||||
RenderingModePoint,
|
||||
RenderingModePointTrail
|
||||
};
|
||||
|
||||
enum class PointRenderingMode {
|
||||
ViewDirection = 0,
|
||||
PositionNormal
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo PathInfo = {
|
||||
"Path",
|
||||
"Path",
|
||||
@@ -59,6 +65,17 @@ namespace {
|
||||
openspace::properties::Property::Visibility::AdvancedUser
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo PointRenderingModeInfo = {
|
||||
"PointRenderingMode",
|
||||
"Point Rendering Mode",
|
||||
"Controls how the points will be oriented. \"Camera View Direction\" rotates the "
|
||||
"points so that they are orthogonal to the viewing direction of the camera "
|
||||
"(useful for planar displays), and \"Camera Position Normal\" rotates the points "
|
||||
"towards the position of the camera (useful for spherical displays, like dome "
|
||||
"theaters).",
|
||||
openspace::properties::Property::Visibility::AdvancedUser
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo SegmentQualityInfo = {
|
||||
"SegmentQuality",
|
||||
"Segment quality",
|
||||
@@ -193,6 +210,13 @@ namespace {
|
||||
// The file format that is contained in the file.
|
||||
Format format;
|
||||
|
||||
enum class [[codegen::map(PointRenderingMode)]] PointRenderingMode {
|
||||
ViewDirection [[codegen::key("Camera View Direction")]],
|
||||
PositionNormal [[codegen::key("Camera Position Normal")]]
|
||||
};
|
||||
// [[codegen::verbatim(PointRenderingModeInfo.description)]]
|
||||
std::optional<PointRenderingMode> pointRenderingMode;
|
||||
|
||||
// [[codegen::verbatim(SegmentQualityInfo.description)]]
|
||||
int segmentQuality;
|
||||
|
||||
@@ -261,22 +285,24 @@ RenderableOrbitalKepler::Appearance::Appearance()
|
||||
, enableMaxSize(EnableMaxSizeInfo, true)
|
||||
, maxSize(MaxSizeInfo, 5.f, 0.f, 45.f)
|
||||
, renderingModes(RenderingModeInfo)
|
||||
, pointRenderOption(PointRenderingModeInfo)
|
||||
, trailFade(TrailFadeInfo, 20.f, 0.f, 30.f)
|
||||
, enableOutline(EnableOutlineInfo, true)
|
||||
, outlineColor(OutlineColorInfo, glm::vec3(0.f), glm::vec3(0.f), glm::vec3(1.f))
|
||||
, outlineWidth(OutlineWidthInfo, 0.2f, 0.f, 1.f)
|
||||
{
|
||||
renderingModes.addOptions({
|
||||
{ RenderingModeTrail, "Trails" },
|
||||
{ RenderingModePoint, "Points" },
|
||||
{ RenderingModePointTrail , "Points and Trails" }
|
||||
{ static_cast<int>(RenderMode::RenderingModeTrail), "Trails" },
|
||||
{ static_cast<int>(RenderMode::RenderingModePoint), "Points"},
|
||||
{ static_cast<int>(RenderMode::RenderingModePointTrail) , "Points and Trails" }
|
||||
});
|
||||
renderingModes.onChange([this]() { isRenderTypeDirty = true; });
|
||||
addProperty(renderingModes);
|
||||
|
||||
color.setViewOption(properties::Property::ViewOptions::Color);
|
||||
addProperty(color);
|
||||
addProperty(trailWidth);
|
||||
addProperty(trailFade);
|
||||
addProperty(pointRenderOption);
|
||||
addProperty(pointSizeExponent);
|
||||
addProperty(enableMaxSize);
|
||||
addProperty(maxSize);
|
||||
@@ -288,6 +314,7 @@ RenderableOrbitalKepler::Appearance::Appearance()
|
||||
|
||||
RenderableOrbitalKepler::RenderableOrbitalKepler(const ghoul::Dictionary& dict)
|
||||
: Renderable(dict)
|
||||
, _nThreads(std::max(1u, std::thread::hardware_concurrency() / 2u))
|
||||
, _segmentQuality(SegmentQualityInfo, 2, 1, 10)
|
||||
, _startRenderIdx(StartRenderIdxInfo, 0, 0, 1)
|
||||
, _sizeRender(RenderSizeInfo, 1, 1, 2)
|
||||
@@ -299,11 +326,12 @@ RenderableOrbitalKepler::RenderableOrbitalKepler(const ghoul::Dictionary& dict)
|
||||
addProperty(Fadeable::_opacity);
|
||||
|
||||
_segmentQuality = static_cast<unsigned int>(p.segmentQuality);
|
||||
_segmentQuality.onChange([this]() { updateBuffers(); });
|
||||
_segmentQuality.onChange([this]() { _updateDataBuffersAtNextRender = true; });
|
||||
addProperty(_segmentQuality);
|
||||
|
||||
_appearance.color = p.color;
|
||||
_appearance.trailFade = p.trailFade.value_or(_appearance.trailFade);
|
||||
_appearance.trailFade.onChange([this]() { _forceUpdate = true; });
|
||||
_appearance.trailWidth = p.trailWidth.value_or(_appearance.trailWidth);
|
||||
_appearance.enableMaxSize = p.enableMaxSize.value_or(_appearance.enableMaxSize);
|
||||
_appearance.maxSize = p.maxSize.value_or(_appearance.maxSize);
|
||||
@@ -313,21 +341,49 @@ RenderableOrbitalKepler::RenderableOrbitalKepler(const ghoul::Dictionary& dict)
|
||||
_appearance.pointSizeExponent =
|
||||
p.pointSizeExponent.value_or(_appearance.pointSizeExponent);
|
||||
|
||||
if (p.renderingMode.has_value()) {
|
||||
switch (*p.renderingMode) {
|
||||
case Parameters::RenderingMode::Trail:
|
||||
_appearance.renderingModes = RenderingModeTrail;
|
||||
_appearance.pointRenderOption.addOption(
|
||||
static_cast<int>(PointRenderingMode::ViewDirection),
|
||||
"Camera View Direction"
|
||||
);
|
||||
_appearance.pointRenderOption.addOption(
|
||||
static_cast<int>(PointRenderingMode::PositionNormal),
|
||||
"Camera Position Normal"
|
||||
);
|
||||
if (p.pointRenderingMode.has_value()) {
|
||||
switch (*p.pointRenderingMode) {
|
||||
case Parameters::PointRenderingMode::ViewDirection:
|
||||
_appearance.pointRenderOption =
|
||||
static_cast<int>(PointRenderingMode::ViewDirection);
|
||||
break;
|
||||
case Parameters::RenderingMode::Point:
|
||||
_appearance.renderingModes = RenderingModePoint;
|
||||
break;
|
||||
case Parameters::RenderingMode::PointsTrails:
|
||||
_appearance.renderingModes = RenderingModePointTrail;
|
||||
case Parameters::PointRenderingMode::PositionNormal:
|
||||
_appearance.pointRenderOption =
|
||||
static_cast<int>(PointRenderingMode::PositionNormal);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
_appearance.renderingModes = RenderingModeTrail;
|
||||
_appearance.pointRenderOption =
|
||||
static_cast<int>(PointRenderingMode::ViewDirection);
|
||||
}
|
||||
|
||||
if (p.renderingMode.has_value()) {
|
||||
switch (*p.renderingMode) {
|
||||
case Parameters::RenderingMode::Trail:
|
||||
_appearance.renderingModes =
|
||||
static_cast<int>(RenderMode::RenderingModeTrail);
|
||||
break;
|
||||
case Parameters::RenderingMode::Point:
|
||||
_appearance.renderingModes =
|
||||
static_cast<int>(RenderMode::RenderingModePoint);
|
||||
break;
|
||||
case Parameters::RenderingMode::PointsTrails:
|
||||
_appearance.renderingModes =
|
||||
static_cast<int>(RenderMode::RenderingModePointTrail);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
_appearance.renderingModes = static_cast<int>(RenderMode::RenderingModeTrail);
|
||||
}
|
||||
addPropertySubOwner(_appearance);
|
||||
|
||||
@@ -336,8 +392,8 @@ RenderableOrbitalKepler::RenderableOrbitalKepler(const ghoul::Dictionary& dict)
|
||||
_startRenderIdx = p.startRenderIdx.value_or(0);
|
||||
_startRenderIdx.onChange([this]() {
|
||||
if (_contiguousMode) {
|
||||
if ((_numObjects - _startRenderIdx) < _sizeRender) {
|
||||
_sizeRender = static_cast<unsigned int>(_numObjects - _startRenderIdx);
|
||||
if ((_nOrbits - _startRenderIdx) < _sizeRender) {
|
||||
_sizeRender = static_cast<unsigned int>(_nOrbits - _startRenderIdx);
|
||||
}
|
||||
_updateDataBuffersAtNextRender = true;
|
||||
}
|
||||
@@ -347,8 +403,8 @@ RenderableOrbitalKepler::RenderableOrbitalKepler(const ghoul::Dictionary& dict)
|
||||
_sizeRender = p.renderSize.value_or(0u);
|
||||
_sizeRender.onChange([this]() {
|
||||
if (_contiguousMode) {
|
||||
if (_sizeRender > (_numObjects - _startRenderIdx)) {
|
||||
_startRenderIdx = static_cast<unsigned int>(_numObjects - _sizeRender);
|
||||
if (_sizeRender > (_nOrbits - _startRenderIdx)) {
|
||||
_startRenderIdx = static_cast<unsigned int>(_nOrbits - _sizeRender);
|
||||
}
|
||||
}
|
||||
_updateDataBuffersAtNextRender = true;
|
||||
@@ -360,7 +416,7 @@ RenderableOrbitalKepler::RenderableOrbitalKepler(const ghoul::Dictionary& dict)
|
||||
addProperty(_contiguousMode);
|
||||
|
||||
_path = p.path.string();
|
||||
_path.onChange([this]() { updateBuffers(); });
|
||||
_path.onChange([this]() { _updateDataBuffersAtNextRender = true; });
|
||||
addProperty(_path);
|
||||
}
|
||||
|
||||
@@ -398,7 +454,7 @@ void RenderableOrbitalKepler::initializeGL() {
|
||||
ghoul::opengl::updateUniformLocations(*_trailProgram, _uniformTrailCache);
|
||||
ghoul::opengl::updateUniformLocations(*_pointProgram, _uniformPointCache);
|
||||
|
||||
updateBuffers();
|
||||
_updateDataBuffersAtNextRender = true;
|
||||
}
|
||||
|
||||
void RenderableOrbitalKepler::deinitializeGL() {
|
||||
@@ -427,11 +483,32 @@ bool RenderableOrbitalKepler::isReady() const {
|
||||
return _pointProgram != nullptr && _trailProgram != nullptr;
|
||||
}
|
||||
|
||||
void RenderableOrbitalKepler::update(const UpdateData&) {
|
||||
void RenderableOrbitalKepler::update(const UpdateData& data) {
|
||||
if (_updateDataBuffersAtNextRender) {
|
||||
_updateDataBuffersAtNextRender = false;
|
||||
updateBuffers();
|
||||
_forceUpdate = true;
|
||||
}
|
||||
|
||||
if (_appearance.isRenderTypeDirty) {
|
||||
_forceUpdate = true;
|
||||
}
|
||||
|
||||
bool isPaused = data.time.j2000Seconds() == data.previousFrameTime.j2000Seconds();
|
||||
if (!isPaused || _forceUpdate) {
|
||||
std::for_each(
|
||||
std::execution::par_unseq,
|
||||
_threadIds.begin(),
|
||||
_threadIds.end(),
|
||||
[&](int threadId) {
|
||||
threadedSegmentCalculations(threadId, data);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
_lineDrawCount = static_cast<GLsizei>(_segmentsPerOrbit.size() * 2);
|
||||
_updateDataBuffersAtNextRender = false;
|
||||
_appearance.isRenderTypeDirty = false;
|
||||
_forceUpdate = false;
|
||||
}
|
||||
|
||||
void RenderableOrbitalKepler::render(const RenderData& data, RendererTasks&) {
|
||||
@@ -439,18 +516,21 @@ void RenderableOrbitalKepler::render(const RenderData& data, RendererTasks&) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int selection = _appearance.renderingModes;
|
||||
const bool renderPoints = (
|
||||
selection == RenderingModePoint ||
|
||||
selection == RenderingModePointTrail
|
||||
);
|
||||
const bool renderTrails = (
|
||||
selection == RenderingModeTrail ||
|
||||
selection == RenderingModePointTrail
|
||||
);
|
||||
|
||||
if (renderPoints) {
|
||||
calculateSegmentsForPoints(data);
|
||||
if (_renderPoints) {
|
||||
glm::vec3 cameraViewDirectionWorld = -data.camera.viewDirectionWorldSpace();
|
||||
glm::vec3 cameraUpDirectionWorld = data.camera.lookUpVectorWorldSpace();
|
||||
glm::vec3 orthoRight = glm::normalize(
|
||||
glm::cross(cameraUpDirectionWorld, cameraViewDirectionWorld)
|
||||
);
|
||||
if (orthoRight == glm::vec3(0.f)) {
|
||||
glm::vec3 otherVector = glm::vec3(
|
||||
cameraUpDirectionWorld.y,
|
||||
cameraUpDirectionWorld.x,
|
||||
cameraUpDirectionWorld.z
|
||||
);
|
||||
orthoRight = glm::normalize(glm::cross(otherVector, cameraViewDirectionWorld));
|
||||
}
|
||||
glm::vec3 orthoUp = glm::normalize(glm::cross(cameraViewDirectionWorld, orthoRight));
|
||||
|
||||
_pointProgram->activate();
|
||||
_pointProgram->setUniform(
|
||||
@@ -465,6 +545,18 @@ void RenderableOrbitalKepler::render(const RenderData& data, RendererTasks&) {
|
||||
_uniformPointCache.projectionTransform,
|
||||
data.camera.projectionMatrix()
|
||||
);
|
||||
_pointProgram->setUniform(
|
||||
_uniformPointCache.renderOption,
|
||||
_appearance.pointRenderOption
|
||||
);
|
||||
_pointProgram->setUniform(
|
||||
_uniformPointCache.cameraViewDirectionUp,
|
||||
orthoUp
|
||||
);
|
||||
_pointProgram->setUniform(
|
||||
_uniformPointCache.cameraViewDirectionRight,
|
||||
orthoRight
|
||||
);
|
||||
_pointProgram->setUniform(
|
||||
_uniformPointCache.cameraPositionWorld,
|
||||
data.camera.positionVec3()
|
||||
@@ -513,9 +605,7 @@ void RenderableOrbitalKepler::render(const RenderData& data, RendererTasks&) {
|
||||
_pointProgram->deactivate();
|
||||
}
|
||||
|
||||
if (renderTrails) {
|
||||
calculateSegmentsForTrails(data);
|
||||
|
||||
if (_renderTrails) {
|
||||
_trailProgram->activate();
|
||||
_trailProgram->setUniform(_uniformTrailCache.opacity, opacity());
|
||||
_trailProgram->setUniform(_uniformTrailCache.color, _appearance.color);
|
||||
@@ -562,32 +652,31 @@ void RenderableOrbitalKepler::render(const RenderData& data, RendererTasks&) {
|
||||
|
||||
void RenderableOrbitalKepler::updateBuffers() {
|
||||
_parameters = kepler::readFile(_path.value(), _format);
|
||||
_nOrbits = static_cast<unsigned int>(_parameters.size());
|
||||
|
||||
_numObjects = _parameters.size();
|
||||
|
||||
if (_startRenderIdx >= _numObjects) {
|
||||
if (_startRenderIdx >= _nOrbits) {
|
||||
throw ghoul::RuntimeError(std::format(
|
||||
"Start index {} out of range [0, {}]", _startRenderIdx.value(), _numObjects
|
||||
"Start index {} out of range [0, {}]", _startRenderIdx.value(), _nOrbits
|
||||
));
|
||||
}
|
||||
|
||||
long long endElement = _startRenderIdx + _sizeRender - 1;
|
||||
endElement = (endElement >= _numObjects) ? _numObjects - 1 : endElement;
|
||||
if (endElement < 0 || endElement >= _numObjects) {
|
||||
endElement = (endElement >= _nOrbits) ? _nOrbits - 1 : endElement;
|
||||
if (endElement < 0 || endElement >= _nOrbits) {
|
||||
throw ghoul::RuntimeError(std::format(
|
||||
"End index {} out of range [0, {}]", endElement, _numObjects
|
||||
"End index {} out of range [0, {}]", endElement, _nOrbits
|
||||
));
|
||||
}
|
||||
|
||||
_startRenderIdx.setMaxValue(static_cast<unsigned int>(_numObjects - 1));
|
||||
_sizeRender.setMaxValue(static_cast<unsigned int>(_numObjects));
|
||||
_startRenderIdx.setMaxValue(static_cast<unsigned int>(_nOrbits - 1));
|
||||
_sizeRender.setMaxValue(static_cast<unsigned int>(_nOrbits));
|
||||
if (_sizeRender == 0u) {
|
||||
_sizeRender = static_cast<unsigned int>(_numObjects);
|
||||
_sizeRender = static_cast<unsigned int>(_nOrbits);
|
||||
}
|
||||
|
||||
if (_contiguousMode) {
|
||||
if (_startRenderIdx >= _parameters.size() ||
|
||||
(_startRenderIdx + _sizeRender) >= _parameters.size())
|
||||
(_startRenderIdx + _sizeRender) > _parameters.size())
|
||||
{
|
||||
throw ghoul::RuntimeError(std::format(
|
||||
"Tried to load {} objects but only {} are available",
|
||||
@@ -613,64 +702,112 @@ void RenderableOrbitalKepler::updateBuffers() {
|
||||
);
|
||||
}
|
||||
|
||||
_threadIds.clear();
|
||||
_orbitsPerThread.clear();
|
||||
_updateHelper.clear();
|
||||
_startIndexPoints.clear();
|
||||
_segmentSizePoints.clear();
|
||||
_vertexBufferOffset.clear();
|
||||
_startIndexTrails.clear();
|
||||
_segmentSizeTrails.clear();
|
||||
_segmentSizeRaw.clear();
|
||||
size_t nVerticesTotal = 0;
|
||||
const int numOrbits = static_cast<int>(_parameters.size());
|
||||
for (int i = 0; i < numOrbits; i++) {
|
||||
_segmentsPerOrbit.clear();
|
||||
|
||||
_updateHelper.resize(_sizeRender);
|
||||
_startIndexPoints.resize(_sizeRender);
|
||||
_segmentSizePoints.resize(_sizeRender);
|
||||
_vertexBufferOffset.resize(_sizeRender);
|
||||
_segmentsPerOrbit.resize(_sizeRender);
|
||||
|
||||
// Trail vectors needs double length as it may use two trails per orbit
|
||||
_startIndexTrails.resize(_sizeRender * 2);
|
||||
_segmentSizeTrails.resize(_sizeRender * 2);
|
||||
|
||||
double maxSemiMajorAxis = 0.0;
|
||||
size_t nVerticesTotal = 0;
|
||||
for (unsigned int i = 0; i < _sizeRender; i++) {
|
||||
// For points rendering as they are always two vertices long
|
||||
_segmentSizePoints.push_back(2);
|
||||
_segmentSizePoints[i] = 2;
|
||||
|
||||
const double scale = static_cast<double>(_segmentQuality) * 10.0;
|
||||
const kepler::Parameters& p = _parameters[i];
|
||||
_segmentSizeRaw.push_back(
|
||||
static_cast<int>(scale + (scale / std::pow(1.0 - p.eccentricity, 1.2)))
|
||||
_segmentsPerOrbit[i] = static_cast<int>(
|
||||
scale + (scale / std::pow(1.0 - p.eccentricity, 1.2))
|
||||
);
|
||||
nVerticesTotal += _segmentSizeRaw[i];
|
||||
_vertexBufferOffset[i] = static_cast<int>(nVerticesTotal);
|
||||
nVerticesTotal += _segmentsPerOrbit[i];
|
||||
|
||||
// Find largest value for bounding sphere
|
||||
if (p.semiMajorAxis > maxSemiMajorAxis) {
|
||||
maxSemiMajorAxis = p.semiMajorAxis;
|
||||
}
|
||||
}
|
||||
_startIndexPoints.resize(numOrbits);
|
||||
_startIndexTrails.resize(numOrbits*2);
|
||||
_segmentSizeTrails.resize(numOrbits*2);
|
||||
setBoundingSphere(maxSemiMajorAxis * 1000);
|
||||
_vertexBufferData.resize(nVerticesTotal);
|
||||
|
||||
size_t vertexBufIdx = 0;
|
||||
for (int orbitIdx = 0; orbitIdx < numOrbits; orbitIdx++) {
|
||||
const kepler::Parameters& orbit = _parameters[orbitIdx];
|
||||
std::vector<int> orbitIdHolder;
|
||||
orbitIdHolder.resize(_sizeRender);
|
||||
std::iota(orbitIdHolder.begin(), orbitIdHolder.end(), 0);
|
||||
|
||||
ghoul::Dictionary d;
|
||||
d.setValue("Type", std::string("KeplerTranslation"));
|
||||
d.setValue("Eccentricity", orbit.eccentricity);
|
||||
d.setValue("SemiMajorAxis", orbit.semiMajorAxis);
|
||||
d.setValue("Inclination", orbit.inclination);
|
||||
d.setValue("AscendingNode", orbit.ascendingNode);
|
||||
d.setValue("ArgumentOfPeriapsis", orbit.argumentOfPeriapsis);
|
||||
d.setValue("MeanAnomaly", orbit.meanAnomaly);
|
||||
d.setValue("Period", orbit.period);
|
||||
d.setValue("Epoch", orbit.epoch);
|
||||
KeplerTranslation keplerTranslator = KeplerTranslation(d);
|
||||
std::for_each(
|
||||
std::execution::par_unseq,
|
||||
orbitIdHolder.begin(),
|
||||
orbitIdHolder.end(),
|
||||
[&](int index) {
|
||||
ZoneScoped;
|
||||
|
||||
const int nSegments = _segmentSizeRaw[orbitIdx];
|
||||
for (GLint j = 0 ; j < nSegments; j++) {
|
||||
const double timeOffset = orbit.period *
|
||||
static_cast<double>(j) / static_cast<double>(nSegments - 1);
|
||||
const kepler::Parameters& orbit = _parameters[index];
|
||||
|
||||
const glm::dvec3 position = keplerTranslator.position({
|
||||
{},
|
||||
Time(timeOffset + orbit.epoch),
|
||||
Time(0.0)
|
||||
});
|
||||
const KeplerCalculator calc = KeplerCalculator(
|
||||
orbit.eccentricity,
|
||||
orbit.semiMajorAxis,
|
||||
orbit.inclination,
|
||||
orbit.ascendingNode,
|
||||
orbit.argumentOfPeriapsis,
|
||||
orbit.meanAnomaly,
|
||||
orbit.period,
|
||||
orbit.epoch
|
||||
);
|
||||
|
||||
_vertexBufferData[vertexBufIdx + j].x = static_cast<float>(position.x);
|
||||
_vertexBufferData[vertexBufIdx + j].y = static_cast<float>(position.y);
|
||||
_vertexBufferData[vertexBufIdx + j].z = static_cast<float>(position.z);
|
||||
_vertexBufferData[vertexBufIdx + j].time = static_cast<float>(timeOffset);
|
||||
_vertexBufferData[vertexBufIdx + j].epoch = orbit.epoch;
|
||||
_vertexBufferData[vertexBufIdx + j].period = orbit.period;
|
||||
const int nVerts = _segmentsPerOrbit[index];
|
||||
const int offset = _vertexBufferOffset[index];
|
||||
const int nSegments = nVerts - 1;
|
||||
for (GLint j = 0; j < nVerts; j++) {
|
||||
const double timeOffset = orbit.period *
|
||||
static_cast<double>(j) / static_cast<double>(nSegments);
|
||||
|
||||
const glm::dvec3 position = calc.position(timeOffset + orbit.epoch);
|
||||
|
||||
_vertexBufferData[offset + j].x = static_cast<float>(position.x);
|
||||
_vertexBufferData[offset + j].y = static_cast<float>(position.y);
|
||||
_vertexBufferData[offset + j].z = static_cast<float>(position.z);
|
||||
_vertexBufferData[offset + j].time = timeOffset;
|
||||
_vertexBufferData[offset + j].epoch = orbit.epoch;
|
||||
_vertexBufferData[offset + j].period = orbit.period;
|
||||
}
|
||||
|
||||
_updateHelper[index].timePerStep = orbit.period / nSegments;
|
||||
}
|
||||
vertexBufIdx += nSegments;
|
||||
);
|
||||
|
||||
// Calculate how many orbits we calculate per thread
|
||||
// 1000 per thread (arbitrary) to not create threads that do little to no work
|
||||
unsigned int orbitsPerThread = std::max(
|
||||
1000,
|
||||
static_cast<int>(std::ceil(static_cast<double>(_sizeRender) / _nThreads))
|
||||
);
|
||||
|
||||
// Vector that maps thread index to number of orbits to render
|
||||
int threadId = 0;
|
||||
unsigned int remainingOrbits = _sizeRender;
|
||||
while (remainingOrbits >= orbitsPerThread) {
|
||||
_threadIds.push_back(threadId);
|
||||
_orbitsPerThread.push_back(orbitsPerThread);
|
||||
remainingOrbits -= orbitsPerThread;
|
||||
threadId++;
|
||||
}
|
||||
if (remainingOrbits > 0) {
|
||||
_threadIds.push_back(threadId);
|
||||
_orbitsPerThread.push_back(remainingOrbits);
|
||||
}
|
||||
|
||||
glBindVertexArray(_vertexArray);
|
||||
@@ -684,120 +821,145 @@ void RenderableOrbitalKepler::updateBuffers() {
|
||||
);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(TrailVBOLayout), nullptr);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(TrailVBOLayout), nullptr);
|
||||
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribLPointer(
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
GL_DOUBLE,
|
||||
sizeof(TrailVBOLayout),
|
||||
reinterpret_cast<GLvoid*>(4 * sizeof(GL_FLOAT))
|
||||
reinterpret_cast<GLvoid*>(offsetof(TrailVBOLayout, time))
|
||||
);
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
double maxSemiMajorAxis = 0.0;
|
||||
for (const kepler::Parameters& kp : _parameters) {
|
||||
if (kp.semiMajorAxis > maxSemiMajorAxis) {
|
||||
maxSemiMajorAxis = kp.semiMajorAxis;
|
||||
}
|
||||
}
|
||||
setBoundingSphere(maxSemiMajorAxis * 1000);
|
||||
}
|
||||
|
||||
void RenderableOrbitalKepler::calculateSegmentsForPoints(const RenderData& data) {
|
||||
int startVertexIndex = 0;
|
||||
for (size_t i = 0; i < _segmentSizeRaw.size(); i++) {
|
||||
// Check how far along the trail we are
|
||||
const kepler::Parameters& orbit = _parameters[i];
|
||||
const double nRevs = (data.time.j2000Seconds() - orbit.epoch) / orbit.period;
|
||||
float frac = static_cast<float>(nRevs - std::trunc(nRevs));
|
||||
frac += (frac < 0.f) ? 1.f: 0.f;
|
||||
void RenderableOrbitalKepler::threadedSegmentCalculations(int threadId,
|
||||
const UpdateData& data)
|
||||
{
|
||||
ZoneScoped;
|
||||
|
||||
// Get the closest vertex before that point
|
||||
const int nSegments = _segmentSizeRaw[i] - 1;
|
||||
const int offset = static_cast<int>(std::floor(frac * nSegments));
|
||||
const int selection = _appearance.renderingModes;
|
||||
_renderPoints = (
|
||||
selection == static_cast<int>(RenderMode::RenderingModePoint) ||
|
||||
selection == static_cast<int>(RenderMode::RenderingModePointTrail)
|
||||
);
|
||||
_renderTrails = (
|
||||
selection == static_cast<int>(RenderMode::RenderingModeTrail) ||
|
||||
selection == static_cast<int>(RenderMode::RenderingModePointTrail)
|
||||
);
|
||||
|
||||
// Set start vertex ID in buffer
|
||||
_startIndexPoints[i] = startVertexIndex + offset;
|
||||
startVertexIndex += _segmentSizeRaw[i];
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableOrbitalKepler::calculateSegmentsForTrails(const RenderData& data) {
|
||||
const float fade = std::pow(
|
||||
_appearance.trailFade.maxValue() - _appearance.trailFade,
|
||||
2.f
|
||||
);
|
||||
const float threshold = 1.f - std::pow(0.05f, 1.f / fade);
|
||||
|
||||
int nTotalTrailParts = 0;
|
||||
int startVertexIndex = 0;
|
||||
for (size_t i = 0; i < _segmentSizeRaw.size(); i++) {
|
||||
// Check how far along the trail we are
|
||||
const kepler::Parameters& orbit = _parameters[i];
|
||||
const double nRevs = (data.time.j2000Seconds() - orbit.epoch) / orbit.period;
|
||||
float frac = static_cast<float>(nRevs - std::trunc(nRevs));
|
||||
frac += (frac < 0.f) ? 1.f : 0.f;
|
||||
int offset = std::accumulate(
|
||||
_orbitsPerThread.begin(),
|
||||
_orbitsPerThread.begin() + threadId,
|
||||
0
|
||||
);
|
||||
const int cutoff = offset + _orbitsPerThread[threadId];
|
||||
|
||||
int p0Start = 0;
|
||||
int p0Length = 0;
|
||||
int p1Start = 0;
|
||||
int p1Length = 0;
|
||||
const double now = data.time.j2000Seconds();
|
||||
int startVertexIndex = _vertexBufferOffset[offset];
|
||||
for (int i = offset; i < cutoff; i++) {
|
||||
UpdateInfo* helper = &_updateHelper[i];
|
||||
double upper = helper->timestamp + (helper->timePerStep);
|
||||
double lower = helper->timestamp - (helper->timePerStep);
|
||||
const bool shouldUpdate = (now >= upper || now <= lower);
|
||||
|
||||
const int nVerts = _segmentSizeRaw[i];
|
||||
const int nSegments = nVerts - 1;
|
||||
const int trailLength = static_cast<int>(std::ceil(threshold * nSegments));
|
||||
if (trailLength == nSegments) {
|
||||
// Whole trail should be visible
|
||||
p0Start = startVertexIndex;
|
||||
p0Length = nVerts;
|
||||
}
|
||||
else {
|
||||
const int headOffset = static_cast<int>(std::ceil(frac * nSegments));
|
||||
const int headVertexIndex = startVertexIndex + headOffset;
|
||||
const int correctTrailLength = trailLength + 2;
|
||||
const int nVerts = _segmentsPerOrbit[i];
|
||||
if (shouldUpdate || _forceUpdate) {
|
||||
// Check how far along the trail we are
|
||||
const kepler::Parameters& orbit = _parameters[i];
|
||||
const double nRevs = (data.time.j2000Seconds() - orbit.epoch) / orbit.period;
|
||||
double frac = static_cast<double>(nRevs - std::trunc(nRevs));
|
||||
frac += (frac < 0.0) ? 1.0 : 0.0;
|
||||
|
||||
int correctVertexIndex = headVertexIndex - correctTrailLength + 1;
|
||||
const int nSegments = nVerts - 1;
|
||||
const int pointHead = static_cast<int>(std::floor(frac * nSegments));
|
||||
|
||||
// If the start of the trail should be at the end of the orbit
|
||||
if (correctVertexIndex < startVertexIndex) {
|
||||
correctVertexIndex += nVerts;
|
||||
// We can always do this since it has no cost
|
||||
_startIndexPoints[i] = startVertexIndex + pointHead;
|
||||
|
||||
// There is a lot of what seems to be "magic numbers" in this section.
|
||||
// They will most likely disappear when we change our method of determining
|
||||
// the trail fade amount is changed.
|
||||
if (_renderTrails) {
|
||||
// When rendering a trail we don't know if the trail will pass over
|
||||
// the starting point of the orbit or not. If the trail passes over the
|
||||
// starting point of the orbit, then we can't draw the entire trail as
|
||||
// line strip. Instead we need to divide the line strip into two parts,
|
||||
// where p0 and p1 denotes the respctive line strips (parts).
|
||||
int p0Start = -1;
|
||||
int p0Length = -1;
|
||||
int p1Start = -1;
|
||||
int p1Length = -1;
|
||||
|
||||
const int trailLength =
|
||||
static_cast<int>(std::ceil(threshold * nSegments));
|
||||
if (trailLength == nSegments) {
|
||||
// Whole trail should be visible
|
||||
p0Start = startVertexIndex;
|
||||
p0Length = nVerts;
|
||||
p1Start = 0;
|
||||
p1Length = 0;
|
||||
}
|
||||
else {
|
||||
const int trailHead = static_cast<int>(std::ceil(frac * nSegments));
|
||||
const int headVertexIndex = startVertexIndex + trailHead + 1;
|
||||
const int correctTrailLength = trailLength + 3;
|
||||
|
||||
// Need to do this due to order of vertex data in the vertex buffer
|
||||
int correctVertexIndex = headVertexIndex - correctTrailLength;
|
||||
|
||||
// If the start of the trail should be at the end of the orbit
|
||||
if (correctVertexIndex < startVertexIndex) {
|
||||
correctVertexIndex += nVerts;
|
||||
}
|
||||
|
||||
// If the trail is length passes over the last point of the orbit
|
||||
const int lastVertexIndex = startVertexIndex + nVerts;
|
||||
if (correctVertexIndex + correctTrailLength > lastVertexIndex) {
|
||||
p0Start = startVertexIndex;
|
||||
p1Start = correctVertexIndex;
|
||||
|
||||
// Special check to make sure we don't end up with segment
|
||||
// sections 1 vertex length. A segment must contain at least 2
|
||||
// vertices or more.
|
||||
if (lastVertexIndex - correctVertexIndex == 1) {
|
||||
p1Length = 0;
|
||||
p0Length = correctTrailLength - 1;
|
||||
}
|
||||
else {
|
||||
p1Length = lastVertexIndex - correctVertexIndex;
|
||||
p0Length = correctTrailLength - p1Length;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// If the entire trail is within the bounds of the orbit
|
||||
p0Start = correctVertexIndex;
|
||||
p0Length = correctTrailLength;
|
||||
p1Start = 0;
|
||||
p1Length = 0;
|
||||
}
|
||||
}
|
||||
_startIndexTrails[i * 2] = p0Start;
|
||||
_segmentSizeTrails[i * 2] = p0Length;
|
||||
_startIndexTrails[i * 2 + 1] = p1Start;
|
||||
_segmentSizeTrails[i * 2 + 1] = p1Length;
|
||||
}
|
||||
|
||||
// If the trail is length passes over the last point of the orbit
|
||||
const int lastVertexIndex = startVertexIndex + nVerts;
|
||||
if (correctVertexIndex + correctTrailLength > lastVertexIndex) {
|
||||
p1Start = correctVertexIndex - 1;
|
||||
p1Length = lastVertexIndex - correctVertexIndex + 1;
|
||||
p0Start = startVertexIndex;
|
||||
p0Length = correctTrailLength - p1Length + 1;
|
||||
}
|
||||
else {
|
||||
// If the entire trail is within the bounds of the orbit
|
||||
p0Start = correctVertexIndex;
|
||||
p0Length = correctTrailLength;
|
||||
}
|
||||
}
|
||||
|
||||
int newTrailParts = 0;
|
||||
if (p0Length > 1) {
|
||||
_startIndexTrails[nTotalTrailParts] = p0Start;
|
||||
_segmentSizeTrails[nTotalTrailParts] = p0Length;
|
||||
newTrailParts += 1;
|
||||
}
|
||||
|
||||
if (p1Length > 1) {
|
||||
_startIndexTrails[nTotalTrailParts + newTrailParts] = p1Start;
|
||||
_segmentSizeTrails[nTotalTrailParts + newTrailParts] = p1Length;
|
||||
newTrailParts += 1;
|
||||
_updateHelper[i].timestamp = orbit.epoch +
|
||||
(std::floor(frac * nSegments) * _updateHelper[i].timePerStep) +
|
||||
(std::floor(nRevs) * orbit.period);
|
||||
}
|
||||
|
||||
startVertexIndex += nVerts;
|
||||
nTotalTrailParts += newTrailParts;
|
||||
}
|
||||
_lineDrawCount = static_cast<GLsizei>(nTotalTrailParts);
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -68,6 +68,8 @@ private:
|
||||
properties::FloatProperty maxSize;
|
||||
/// Max angular size between vector cameraToPoint and edge of the point
|
||||
properties::OptionProperty renderingModes;
|
||||
/// Specifies rendering orientation when rendering points
|
||||
properties::OptionProperty pointRenderOption;
|
||||
/// Specifies a multiplicative factor that fades out the trail line
|
||||
properties::FloatProperty trailFade;
|
||||
/// Specifies if the point outline should be enabled
|
||||
@@ -76,59 +78,73 @@ private:
|
||||
properties::Vec3Property outlineColor;
|
||||
/// Specifies how much if the point should be covered by the outline
|
||||
properties::FloatProperty outlineWidth;
|
||||
|
||||
bool isRenderTypeDirty = false;
|
||||
};
|
||||
|
||||
void updateBuffers();
|
||||
void calculateSegmentsForPoints(const RenderData& data);
|
||||
void calculateSegmentsForTrails(const RenderData& data);
|
||||
void threadedSegmentCalculations(int threadId, const UpdateData& data);
|
||||
|
||||
const int _nThreads = 0;
|
||||
std::vector<int> _threadIds;
|
||||
std::vector<int> _orbitsPerThread;
|
||||
std::vector<int> _vertexBufferOffset;
|
||||
|
||||
bool _renderTrails = false;
|
||||
bool _renderPoints = false;
|
||||
bool _forceUpdate = false;
|
||||
bool _updateDataBuffersAtNextRender = false;
|
||||
long long _numObjects = 0;
|
||||
|
||||
unsigned int _nOrbits = 0;
|
||||
GLsizei _lineDrawCount = 0;
|
||||
properties::UIntProperty _segmentQuality;
|
||||
properties::UIntProperty _startRenderIdx;
|
||||
properties::UIntProperty _sizeRender;
|
||||
std::vector<GLint> _segmentSizeRaw;
|
||||
std::vector<GLint> _segmentsPerOrbit;
|
||||
std::vector<GLint> _startIndexPoints;
|
||||
std::vector<GLint> _segmentSizePoints;
|
||||
std::vector<GLint> _startIndexTrails;
|
||||
std::vector<GLint> _segmentSizeTrails;
|
||||
std::vector<kepler::Parameters> _parameters;
|
||||
|
||||
/// Extra data for more efficient updating of vectors
|
||||
struct UpdateInfo {
|
||||
double timestamp = std::numeric_limits<double>::min();
|
||||
double timePerStep = 0.0;
|
||||
};
|
||||
std::vector<UpdateInfo> _updateHelper;
|
||||
|
||||
/// The layout of the VBOs
|
||||
struct TrailVBOLayout {
|
||||
float x = 0.f;
|
||||
float y = 0.f;
|
||||
float z = 0.f;
|
||||
float time = 0.f;
|
||||
double time = 0.0;
|
||||
double epoch = 0.0;
|
||||
double period = 0.0;
|
||||
};
|
||||
|
||||
/// The backend storage for the vertex buffer object containing all points
|
||||
std::vector<TrailVBOLayout> _vertexBufferData;
|
||||
|
||||
GLuint _vertexArray = 0;
|
||||
GLuint _vertexBuffer = 0;
|
||||
|
||||
ghoul::opengl::ProgramObject* _trailProgram = nullptr;
|
||||
ghoul::opengl::ProgramObject* _pointProgram = nullptr;
|
||||
properties::UIntProperty _segmentQuality;
|
||||
properties::UIntProperty _startRenderIdx;
|
||||
properties::UIntProperty _sizeRender;
|
||||
properties::StringProperty _path;
|
||||
properties::BoolProperty _contiguousMode;
|
||||
kepler::Format _format;
|
||||
RenderableOrbitalKepler::Appearance _appearance;
|
||||
|
||||
GLuint _vertexArray = 0;
|
||||
GLuint _vertexBuffer = 0;
|
||||
|
||||
// Line cache
|
||||
UniformCache(modelViewTransform, projectionTransform, trailFadeExponent,
|
||||
colorFadeCutoffValue, inGameTime, color, opacity)
|
||||
_uniformTrailCache;
|
||||
colorFadeCutoffValue, inGameTime, color, opacity) _uniformTrailCache;
|
||||
|
||||
// Point cache
|
||||
UniformCache(modelTransform, viewTransform, projectionTransform,
|
||||
cameraPositionWorld, cameraUpWorld, inGameTime, color,
|
||||
pointSizeExponent, enableMaxSize, maxSize, enableOutline,
|
||||
outlineColor, outlineWeight, opacity)
|
||||
_uniformPointCache;
|
||||
UniformCache(modelTransform, viewTransform, projectionTransform, renderOption,
|
||||
cameraViewDirectionUp, cameraViewDirectionRight, cameraPositionWorld,
|
||||
cameraUpWorld, inGameTime, color, pointSizeExponent, enableMaxSize, maxSize,
|
||||
enableOutline, outlineColor, outlineWeight, opacity) _uniformPointCache;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -33,17 +33,27 @@ flat in float vertexRevolutionFraction[];
|
||||
uniform dmat4 modelTransform;
|
||||
uniform dmat4 viewTransform;
|
||||
uniform mat4 projectionTransform;
|
||||
uniform dvec3 cameraPositionWorld;
|
||||
uniform vec3 cameraUpWorld;
|
||||
uniform float pointSizeExponent;
|
||||
uniform bool enableMaxSize;
|
||||
uniform float maxSize;
|
||||
uniform int renderOption;
|
||||
|
||||
// Camera View Direction
|
||||
uniform vec3 cameraViewDirectionUp;
|
||||
uniform vec3 cameraViewDirectionRight;
|
||||
|
||||
// Camera Normal
|
||||
uniform dvec3 cameraPositionWorld;
|
||||
uniform vec3 cameraUpWorld;
|
||||
|
||||
layout(triangle_strip, max_vertices = 4) out;
|
||||
out float projectionViewDepth;
|
||||
out vec4 viewSpace;
|
||||
out vec2 texCoord;
|
||||
|
||||
const int RenderOptionCameraViewDirection = 0;
|
||||
const int RenderOptionCameraPositionNormal = 1;
|
||||
|
||||
void main() {
|
||||
// cFrac is how far along the trail orbit the head of the trail is.
|
||||
// v0Frac and v1Frac are how far the two vertices that creates the current line strip
|
||||
@@ -65,12 +75,21 @@ void main() {
|
||||
|
||||
// Calculate current vertex position to world space
|
||||
dvec4 vertPosWorldSpace = modelTransform * pos;
|
||||
|
||||
// Calculate new axis for plane
|
||||
vec3 camPosToVertPos = vec3(cameraPositionWorld - vertPosWorldSpace.xyz);
|
||||
vec3 normal = normalize(camPosToVertPos);
|
||||
vec3 right = normalize(cross(cameraUpWorld, normal));
|
||||
vec3 up = normalize(cross(normal, right));
|
||||
|
||||
vec3 up;
|
||||
vec3 right;
|
||||
// Calculate new axis for plane
|
||||
if (renderOption == RenderOptionCameraViewDirection) {
|
||||
up = cameraViewDirectionUp;
|
||||
right = cameraViewDirectionRight;
|
||||
}
|
||||
else {
|
||||
// Camera Position Normal
|
||||
vec3 normal = normalize(camPosToVertPos);
|
||||
right = normalize(cross(cameraUpWorld, normal));
|
||||
up = normalize(cross(normal, right));
|
||||
}
|
||||
|
||||
// Calculate size of points
|
||||
float initialSize = pow(10.0, pointSizeExponent);
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout (location = 0) in vec4 vertexData; // 1: x, 2: y, 3: z, 4: timeOffset,
|
||||
layout (location = 1) in dvec2 orbitData; // 1: epoch, 2: period
|
||||
layout (location = 0) in vec3 vertexData; // 1: x, 2: y, 3: z
|
||||
layout (location = 1) in dvec3 orbitData; // 1: timeOffset, 2: epoch, 3: period
|
||||
|
||||
uniform double inGameTime;
|
||||
|
||||
@@ -33,8 +33,9 @@ flat out float currentRevolutionFraction;
|
||||
flat out float vertexRevolutionFraction;
|
||||
|
||||
void main() {
|
||||
double epoch = orbitData.x;
|
||||
double period = orbitData.y;
|
||||
double timeOffset = orbitData.x;
|
||||
double epoch = orbitData.y;
|
||||
double period = orbitData.z;
|
||||
|
||||
// calculate nr of periods, get fractional part to know where the vertex closest to the
|
||||
// debris part is right now
|
||||
@@ -45,7 +46,7 @@ void main() {
|
||||
}
|
||||
|
||||
// Same procedure for the current vertex
|
||||
vertexRevolutionFraction = float(vertexData.w / period);
|
||||
vertexRevolutionFraction = float(timeOffset / period);
|
||||
|
||||
gl_Position = vec4(vertexData.xyz, 1.0);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user