mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-07 04:00:37 -06:00
Merge branch 'thesis/2021/skybrowser' of https://github.com/OpenSpace/OpenSpace into thesis/2021/skybrowser
This commit is contained in:
Submodule apps/OpenSpace/ext/sgct updated: c5288e6f1d...4964fd4109
@@ -1,4 +1,4 @@
|
||||
local sunTransforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
local transforms = asset.require("scene/solarsystem/planets/earth/transforms")
|
||||
|
||||
local model = asset.syncedResource({
|
||||
@@ -27,12 +27,7 @@ local animationLoop = {
|
||||
AnimationStartTime = StartTime,
|
||||
ModelScale = 3E7,
|
||||
LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
}
|
||||
sun.LightSource
|
||||
},
|
||||
PerformShading = true,
|
||||
DisableFaceCulling = true
|
||||
@@ -61,12 +56,7 @@ local animationLoopInf = {
|
||||
AnimationStartTime = StartTime,
|
||||
ModelScale = 3E7,
|
||||
LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
}
|
||||
sun.LightSource
|
||||
},
|
||||
PerformShading = true,
|
||||
DisableFaceCulling = true
|
||||
@@ -95,12 +85,7 @@ local animationOnce = {
|
||||
AnimationStartTime = StartTime,
|
||||
ModelScale = 3E7,
|
||||
LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
}
|
||||
sun.LightSource
|
||||
},
|
||||
PerformShading = true,
|
||||
DisableFaceCulling = true
|
||||
@@ -129,12 +114,7 @@ local animationBounceInf = {
|
||||
AnimationStartTime = StartTime,
|
||||
ModelScale = 3E7,
|
||||
LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
}
|
||||
sun.LightSource
|
||||
},
|
||||
PerformShading = true,
|
||||
DisableFaceCulling = true
|
||||
@@ -163,12 +143,7 @@ local animationBounce = {
|
||||
AnimationStartTime = StartTime,
|
||||
ModelScale = 3E7,
|
||||
LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
}
|
||||
sun.LightSource
|
||||
},
|
||||
PerformShading = true,
|
||||
DisableFaceCulling = true
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
local sunTransforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
local transforms = asset.require("scene/solarsystem/planets/earth/transforms")
|
||||
|
||||
local generic_action = {
|
||||
@@ -34,12 +34,7 @@ local obj = {
|
||||
GeometryFile = model .. "BoxAnimated.glb",
|
||||
ModelScale = 1.0,
|
||||
LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
}
|
||||
sun.LightSource
|
||||
},
|
||||
PerformShading = true,
|
||||
DisableFaceCulling = true
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
local sunTransforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
local transforms = asset.require("scene/solarsystem/planets/earth/transforms")
|
||||
|
||||
local model = asset.syncedResource({
|
||||
@@ -22,12 +22,7 @@ local model = {
|
||||
GeometryFile = model .. "BoxAnimated.glb",
|
||||
ModelScale = 3E7,
|
||||
LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
}
|
||||
sun.LightSource
|
||||
},
|
||||
PerformShading = true,
|
||||
DisableFaceCulling = true,
|
||||
|
||||
@@ -1,20 +1,6 @@
|
||||
local sunTransforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
local transforms = asset.require("./transforms")
|
||||
|
||||
local LIGHTS = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
},
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
|
||||
local sync = asset.syncedResource({
|
||||
Name = "Orion Nebula Model",
|
||||
Type = "HttpSynchronization",
|
||||
@@ -77,7 +63,14 @@ local OrionNebulaModel = {
|
||||
DiffuseIntensity = 1.0,
|
||||
--PerformShading = false,
|
||||
RotationVector = { 0.000000, 22.300000, 0.000000 },
|
||||
LightSources = LIGHTS;
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Orion Nebula Model",
|
||||
@@ -105,7 +98,14 @@ local OrionNebulaShocksModel = {
|
||||
DiffuseIntensity = 1.0,
|
||||
--PerformShading = false,
|
||||
RotationVector = { 0.000000, 22.300000, 0.000000 },
|
||||
LightSources = LIGHTS;
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Orion Nebula Shocks",
|
||||
@@ -134,7 +134,14 @@ local OrionNebulaProplydsModel = {
|
||||
DiffuseIntensity = 1.0,
|
||||
--PerformShading = false,
|
||||
RotationVector = { 0.000000, 22.300000, 0.000000 },
|
||||
LightSources = LIGHTS;
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Orion Nebula Proplyds",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
local sun_transforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
local moon_transforms = asset.require("scene/solarsystem/planets/earth/moon/moon")
|
||||
|
||||
local descentKeyframes = asset.require("./lem_descent.asset")
|
||||
@@ -68,12 +68,7 @@ local Apollo11Model = {
|
||||
Type = "RenderableModel",
|
||||
GeometryFile = models .. "Apollo_CSM_shrunk_rotated_xy_double_size.obj",
|
||||
LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sun_transforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
},
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
@@ -197,12 +192,7 @@ local Apollo11LemDescentModel = {
|
||||
SpecularIntensity = 0.0,
|
||||
RotationVector = { 273.750,28.0,309.85 },
|
||||
LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sun_transforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
},
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
@@ -235,12 +225,7 @@ local Apollo11LemLandedModel = {
|
||||
SpecularIntensity = 0.0,
|
||||
RotationVector = { 273.750,28.0,309.85 },
|
||||
LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sun_transforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
},
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
-- a11_lem.asset
|
||||
local sun_transforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
local moon_asset = asset.require("scene/solarsystem/planets/earth/moon/moon")
|
||||
|
||||
|
||||
@@ -43,12 +42,7 @@ local Apollo11LemModel = {
|
||||
GeometryFile = lem_model .. "LM-2_ver2clean.obj",
|
||||
RotationVector = { 91.044090, 171.229706, 111.666664 },
|
||||
LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sun_transforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
},
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
local moon_transforms = asset.require("scene/solarsystem/planets/earth/moon/moon")
|
||||
local sun_transforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
asset.require("spice/base")
|
||||
|
||||
local models = asset.syncedResource({
|
||||
@@ -19,22 +19,6 @@ local kernels = asset.require("scene/solarsystem/missions/apollo/15/kernels").ke
|
||||
-- Version = 1
|
||||
-- })
|
||||
|
||||
local LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sun_transforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
},
|
||||
-- {
|
||||
-- Identifier = "Camera",
|
||||
-- Type = "CameraLightSource",
|
||||
-- Intensity = 0.5,
|
||||
-- Enabled = false
|
||||
-- }
|
||||
}
|
||||
|
||||
|
||||
local Apollo15 = {
|
||||
Identifier = "Apollo15",
|
||||
Parent = moon_transforms.Moon.Identifier,
|
||||
@@ -57,12 +41,7 @@ local Apollo15 = {
|
||||
GeometryFile = models .. "ApolloCSM.osmodel",
|
||||
ModelScale = 0.0001,
|
||||
LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sun_transforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
}
|
||||
sun.LightSource
|
||||
},
|
||||
PerformShading = true,
|
||||
DisableFaceCulling = true
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
local sun_transforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
local moon_asset = asset.require("scene/solarsystem/planets/earth/moon/moon")
|
||||
|
||||
local models = asset.syncedResource({
|
||||
@@ -8,20 +8,6 @@ local models = asset.syncedResource({
|
||||
Version = 2
|
||||
})
|
||||
|
||||
local LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sun_transforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
},
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
|
||||
local Station2Boulder1Holder = {
|
||||
Identifier = "Station_2_Boulder1",
|
||||
Parent = moon_asset.Moon.Identifier,
|
||||
@@ -54,7 +40,14 @@ local Station2Boulder1Model = {
|
||||
Type = "RenderableModel",
|
||||
GeometryFile = models .. "b1-v2.obj",
|
||||
RotationVector = { 243.243256 ,206.270264, 309.677429 },
|
||||
LightSources = LightSources,
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
},
|
||||
PerformShading = false,
|
||||
DisableFaceCulling = true
|
||||
},
|
||||
@@ -96,7 +89,14 @@ local Station2Boulder2Model = {
|
||||
Type = "RenderableModel",
|
||||
GeometryFile = models .. "b2model.obj",
|
||||
RotationVector = { 66.162155, 7.783780, 114.193550 },
|
||||
LightSources = LightSources,
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
},
|
||||
PerformShading = false,
|
||||
DisableFaceCulling = true
|
||||
},
|
||||
@@ -138,7 +138,14 @@ local Station2Boulder3Model = {
|
||||
Type = "RenderableModel",
|
||||
GeometryFile = models .. "b3model.obj",
|
||||
RotationVector = { 161.513519 ,243.243256, 65.806450 },
|
||||
LightSources = LightSources,
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
},
|
||||
PerformShading = false,
|
||||
DisableFaceCulling = true
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
local sun_transforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
local moon_asset = asset.require("scene/solarsystem/planets/earth/moon/moon")
|
||||
|
||||
local models = asset.syncedResource({
|
||||
@@ -8,20 +8,6 @@ local models = asset.syncedResource({
|
||||
Version = 2
|
||||
})
|
||||
|
||||
local LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sun_transforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
},
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
local Station6Frag1Holder = {
|
||||
Identifier = "Station_6_Fragment1",
|
||||
@@ -65,7 +51,14 @@ local Station6Frag1Model = {
|
||||
Type = "RenderableModel",
|
||||
GeometryFile = models .. "A17-S6-frag1.obj",
|
||||
RotationVector = { 235.909088,165.000000,286.299194 },
|
||||
LightSources = LightSources,
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
},
|
||||
PerformShading = false,
|
||||
DisableFaceCulling = true
|
||||
},
|
||||
@@ -108,7 +101,14 @@ local Station6Frag2Model = {
|
||||
Type = "RenderableModel",
|
||||
GeometryFile = models .. "station6_boulder_frag2.obj",
|
||||
RotationVector = { 336.959991,210.239990,325.984253 },
|
||||
LightSources = LightSources,
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
},
|
||||
PerformShading = false,
|
||||
DisableFaceCulling = true,
|
||||
},
|
||||
@@ -139,7 +139,14 @@ local Station6Frag3Model = {
|
||||
Type = "RenderableModel",
|
||||
GeometryFile = models .. "station6_boulder_frag3.obj",
|
||||
RotationVector = { 293.181824,255.000000,4.090910 },
|
||||
LightSources = LightSources,
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
},
|
||||
PerformShading = false,
|
||||
DisableFaceCulling = true
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
local sun_transforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
local moon_asset = asset.require("scene/solarsystem/planets/earth/moon/moon")
|
||||
|
||||
local models = asset.syncedResource({
|
||||
@@ -8,20 +8,6 @@ local models = asset.syncedResource({
|
||||
Version = 2
|
||||
})
|
||||
|
||||
local LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sun_transforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
},
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
|
||||
local Station7BoulderHolder = {
|
||||
Identifier = "Station_7_Boulder",
|
||||
Parent = moon_asset.Moon.Identifier,
|
||||
@@ -54,7 +40,14 @@ local Station7BoulderModel = {
|
||||
Type = "RenderableModel",
|
||||
GeometryFile = models .. "b7model.obj",
|
||||
RotationVector = { 1.945950,274.378387,212.903214 },
|
||||
LightSources = LightSources,
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
},
|
||||
PerformShading = false,
|
||||
DisableFaceCulling = true
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
local sun_transforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
local moon_asset = asset.require("scene/solarsystem/planets/earth/moon/moon")
|
||||
|
||||
local model = asset.syncedResource({
|
||||
@@ -42,12 +42,7 @@ local Apollo17LemModel = {
|
||||
SpecularIntensity = 0.0,
|
||||
RotationVector = { 110.255219,171.229706,126.666664 },
|
||||
LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sun_transforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
},
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
local earth_transforms = asset.require("scene/solarsystem/planets/earth/transforms")
|
||||
local sun_transforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
local kernels = asset.require("./kernels").kernels
|
||||
|
||||
local models = asset.syncedResource({
|
||||
@@ -53,12 +53,7 @@ local Apollo8LaunchModel = {
|
||||
GeometryFile = models .. "ApolloCSM.osmodel",
|
||||
ModelScale = 0.0001,
|
||||
LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sun_transforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
}
|
||||
sun.LightSource
|
||||
},
|
||||
PerformShading = true,
|
||||
DisableFaceCulling = true
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
local earth_transforms = asset.require("scene/solarsystem/planets/earth/transforms")
|
||||
local sun_transforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
local kernels = asset.require("./kernels").kernels
|
||||
|
||||
local models = asset.syncedResource({
|
||||
@@ -65,12 +65,7 @@ local Apollo8Model = {
|
||||
GeometryFile = models .. "ApolloCSM.osmodel",
|
||||
ModelScale = 0.0001,
|
||||
LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sun_transforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
}
|
||||
sun.LightSource
|
||||
},
|
||||
PerformShading = true,
|
||||
DisableFaceCulling = true
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
local transforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sunTransforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
|
||||
|
||||
local kernels = asset.syncedResource({
|
||||
@@ -622,12 +622,7 @@ local KernelFiles = {
|
||||
}
|
||||
|
||||
local LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
},
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
local transforms = asset.require("./transforms")
|
||||
local sunTransforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
|
||||
local model = asset.syncedResource({
|
||||
Name = "Gaia Model",
|
||||
@@ -32,12 +32,7 @@ local Gaia = {
|
||||
Body = "GAIA",
|
||||
GeometryFile = model .. "gaia.obj",
|
||||
LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 0.3
|
||||
},
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
asset.require("spice/base")
|
||||
local sunTransforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
local mars = asset.require("scene/solarsystem/planets/mars/mars")
|
||||
|
||||
local models = asset.syncedResource({
|
||||
@@ -31,12 +31,7 @@ local RotationMatrix = {
|
||||
}
|
||||
|
||||
local LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
},
|
||||
sun.LightSource,
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Mars",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
local transforms = asset.require("scene/solarsystem/planets/jupiter/transforms")
|
||||
local sunTransforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
|
||||
|
||||
local model = asset.syncedResource({
|
||||
@@ -152,12 +152,7 @@ local Juno = {
|
||||
GeometryFile = model .. "Juno.obj",
|
||||
ModelTransform = RotationMatrix,
|
||||
LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
},
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
local sunTransforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local transforms = asset.require("./transforms")
|
||||
asset.require("spice/base")
|
||||
@@ -71,12 +72,7 @@ local JWSTModel = {
|
||||
AnimationTimeScale = "Millisecond",
|
||||
AnimationMode = "Once",
|
||||
LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
}
|
||||
sun.LightSource
|
||||
},
|
||||
PerformShading = true,
|
||||
DisableFaceCulling = true
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
local sunTransforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local mercuryTransforms = asset.require("scene/solarsystem/planets/mercury/transforms")
|
||||
|
||||
@@ -56,21 +57,6 @@ local RotationMatrix = {
|
||||
0, 1, 0
|
||||
}
|
||||
|
||||
|
||||
local LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
},
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
|
||||
local Messenger = {
|
||||
Identifier = "Messenger",
|
||||
Parent = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
@@ -105,7 +91,14 @@ local MessengerProbeBlack = {
|
||||
Type = "RenderableModel",
|
||||
GeometryFile = models .. "MessengerProbe_black.obj",
|
||||
ModelTransform = RotationMatrix,
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "MessengerProbe Black",
|
||||
@@ -120,7 +113,14 @@ local MessengerProbeFoil = {
|
||||
Type = "RenderableModel",
|
||||
GeometryFile = models .. "MessengerProbe_foil.obj",
|
||||
ModelTransform = RotationMatrix,
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "MessengerProbe foil",
|
||||
@@ -135,7 +135,14 @@ local MessengerProbeHeatShield = {
|
||||
Type = "RenderableModel",
|
||||
GeometryFile = models .. "MessengerProbe_heatShield.obj",
|
||||
ModelTransform = RotationMatrix,
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "MessengerProbe Heat Sheild",
|
||||
@@ -150,7 +157,14 @@ local MessengerProbeMetal = {
|
||||
Type = "RenderableModel",
|
||||
GeometryFile = models .. "MessengerProbe_metal.obj",
|
||||
ModelTransform = RotationMatrix,
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "MessengerProbe Metal",
|
||||
@@ -165,7 +179,14 @@ local MessengerProbePanels = {
|
||||
Type = "RenderableModel",
|
||||
GeometryFile = models .. "MessengerProbe_panels.obj",
|
||||
ModelTransform = RotationMatrix,
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "MessengerProbe Panels",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
local transforms = asset.require("./transforms")
|
||||
local sunTransforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
|
||||
local models = asset.syncedResource({
|
||||
Name = "New Horizons Model",
|
||||
@@ -19,12 +19,7 @@ local NewHorizons = {
|
||||
DiffuseIntensity = 1.0,
|
||||
SpecularIntensity = 1.0,
|
||||
LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
}
|
||||
sun.LightSource
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
local transforms = asset.require("./transforms")
|
||||
local sunTransforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
|
||||
local models = asset.syncedResource({
|
||||
Name = "Bennu Models",
|
||||
@@ -10,15 +10,6 @@ local models = asset.syncedResource({
|
||||
|
||||
local BENNU_BODY = "2101955"
|
||||
|
||||
local LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
},
|
||||
}
|
||||
|
||||
local Bennu = {
|
||||
Identifier = "Bennu",
|
||||
Parent = transforms.BennuBarycenter.Identifier,
|
||||
@@ -34,7 +25,9 @@ local Bennu = {
|
||||
Type = "RenderableModel",
|
||||
Body = BENNU_BODY,
|
||||
GeometryFile = models .. "Bennu_v20_200k_an.obj",
|
||||
LightSources = LightSources,
|
||||
LightSources = {
|
||||
sun.LightSource
|
||||
},
|
||||
SpecularIntensity = 0.0
|
||||
},
|
||||
GUI = {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
local transforms = asset.require("./transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
local sunTransforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local earthTransforms = asset.require("scene/solarsystem/planets/earth/transforms")
|
||||
|
||||
@@ -13,21 +14,6 @@ local models = asset.syncedResource({
|
||||
|
||||
local BENNU_BODY = "2101955"
|
||||
|
||||
|
||||
local LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
},
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
|
||||
local OsirisRex = {
|
||||
Identifier = "OsirisRex",
|
||||
Parent = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
@@ -48,7 +34,14 @@ local OsirisRex = {
|
||||
Type = "RenderableModel",
|
||||
Body = "OSIRIS-REX",
|
||||
GeometryFile = models .. "orx_base_resized_12_sep_2016.obj",
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "OSIRIS REx",
|
||||
@@ -74,7 +67,14 @@ local PolyCam = {
|
||||
Type = "RenderableModel",
|
||||
Body = "OSIRIS-REX",
|
||||
GeometryFile = models .. "orx_polycam_resized_12_sep_2016.obj",
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "OCAMS POLYCAM",
|
||||
@@ -89,7 +89,14 @@ local Rexis = {
|
||||
Type = "RenderableModel",
|
||||
Body = "OSIRIS-REX",
|
||||
GeometryFile = models .. "orx_rexis_resized_12_sep_2016.obj",
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
Transform = {
|
||||
Translation = {
|
||||
|
||||
@@ -1,22 +1,8 @@
|
||||
local trail = asset.require("./trail")
|
||||
local marsTransforms = asset.require("scene/solarsystem/planets/mars/transforms")
|
||||
local sunTransforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
-- asset.require("./fov")
|
||||
|
||||
local LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
},
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
|
||||
local models = asset.syncedResource({
|
||||
Name = "Mars 2020 Kernels",
|
||||
Type = "HttpSynchronization",
|
||||
@@ -53,7 +39,14 @@ local Body = {
|
||||
Type = "RenderableModel",
|
||||
Body = "MARS SCIENCE LABORATORY",
|
||||
GeometryFile = models .. "Perseverance.obj",
|
||||
LightSources = LightSources,
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
},
|
||||
PerformShading = false,
|
||||
RotationVector = {65.940000,201.389999,263.980011}
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
local sunTransforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
|
||||
local modelFolder = asset.syncedResource({
|
||||
Name = "Pioneer 10/11 Models",
|
||||
@@ -11,12 +11,7 @@ local ModelRenderable = {
|
||||
Type = "RenderableModel",
|
||||
GeometryFile = modelFolder .. "pioneer.fbx",
|
||||
LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
},
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
@@ -35,4 +30,4 @@ asset.meta = {
|
||||
Author = "NASA",
|
||||
URL = "https://nasa3d.arc.nasa.gov/detail/eoss-pioneer",
|
||||
License = "NASA"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
local sunTransforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local transforms = asset.require("./67p")
|
||||
|
||||
@@ -65,20 +66,6 @@ local RosettaKernels = {
|
||||
kernels .. "ROS_CGS_RSOC_V03.TPC"
|
||||
}
|
||||
|
||||
local LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
},
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
|
||||
local RotationMatrix = {
|
||||
0, 1, 0,
|
||||
0, 0, 1,
|
||||
@@ -130,7 +117,14 @@ local RosettaBlackFoil = {
|
||||
Body = "ROSETTA",
|
||||
GeometryFile = models .. "black_foil.obj",
|
||||
ModelTransform = RotationMatrix,
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Rosetta Model Part Black Foil",
|
||||
@@ -146,7 +140,14 @@ local RosettaBlackParts = {
|
||||
Body = "ROSETTA",
|
||||
GeometryFile = models .. "black_parts.obj",
|
||||
ModelTransform = RotationMatrix,
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Rosetta Model Part Black Parts",
|
||||
@@ -162,7 +163,14 @@ local RosettaDish = {
|
||||
Body = "ROSETTA",
|
||||
GeometryFile = models .. "dish.obj",
|
||||
ModelTransform = RotationMatrix,
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Rosetta Model Part Dish",
|
||||
@@ -178,7 +186,14 @@ local RosettaParts = {
|
||||
Body = "ROSETTA",
|
||||
GeometryFile = models .. "parts.obj",
|
||||
ModelTransform = RotationMatrix,
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Rosetta Model Part Parts",
|
||||
@@ -194,7 +209,14 @@ local RosettaSilverFoil = {
|
||||
Body = "ROSETTA",
|
||||
GeometryFile = models .. "silver_foil.obj",
|
||||
ModelTransform = RotationMatrix,
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Rosetta Model Part Silver Foil",
|
||||
@@ -210,7 +232,14 @@ local RosettaVents = {
|
||||
Body = "ROSETTA",
|
||||
GeometryFile = models .. "vents.obj",
|
||||
ModelTransform = RotationMatrix,
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Rosetta Model Part Vents",
|
||||
@@ -226,7 +255,14 @@ local RosettaWingA = {
|
||||
Body = "ROSETTA",
|
||||
GeometryFile = models .."wingA.obj",
|
||||
ModelTransform = RotationMatrix,
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Rosetta Model Part Wing A",
|
||||
@@ -242,7 +278,14 @@ local RosettaWingB = {
|
||||
Body = "ROSETTA",
|
||||
GeometryFile = models .. "wingB.obj",
|
||||
ModelTransform = RotationMatrix,
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Rosetta Model Part Wing B",
|
||||
@@ -258,7 +301,14 @@ local RosettaYellowFoil = {
|
||||
Body = "ROSETTA",
|
||||
GeometryFile = models .. "yellow_foil.obj",
|
||||
ModelTransform = RotationMatrix,
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Rosetta Model Part Yellow Foil",
|
||||
@@ -303,7 +353,14 @@ local PhilaeFoil = {
|
||||
Body = "ROSETTA",
|
||||
GeometryFile = models .. "lander_foil.obj",
|
||||
ModelTransform = RotationMatrix,
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Philae Model Part Foil",
|
||||
@@ -319,7 +376,14 @@ local PhilaeLids = {
|
||||
Body = "ROSETTA",
|
||||
GeometryFile = models .. "lander_lids.obj",
|
||||
ModelTransform = RotationMatrix,
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Philae Model Part Lids",
|
||||
@@ -335,7 +399,14 @@ local PhilaeParts = {
|
||||
Body = "ROSETTA",
|
||||
GeometryFile = models .. "lander_parts.obj",
|
||||
ModelTransform = RotationMatrix,
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Philae Model Part Parts",
|
||||
@@ -351,7 +422,14 @@ local PhilaeSolarPanels = {
|
||||
Body = "ROSETTA",
|
||||
GeometryFile = models .. "lander_solarp.obj",
|
||||
ModelTransform = RotationMatrix,
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Philae Model Parts Solar Panels",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
local sunTransforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
|
||||
local models = asset.syncedResource({
|
||||
@@ -31,20 +32,6 @@ local RotationMatrix = {
|
||||
0, -1, 0
|
||||
}
|
||||
|
||||
local LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
},
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
|
||||
local Voyager1 = {
|
||||
Identifier = "Voyager_1",
|
||||
Parent = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
@@ -79,7 +66,14 @@ local Voyager1Main = {
|
||||
Type = "RenderableModel",
|
||||
GeometryFile = models .. "voyager-main.obj",
|
||||
ModelTransform = RotationMatrix,
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Voyager 1 Main",
|
||||
@@ -94,7 +88,14 @@ local Voyager1Antenna = {
|
||||
Type = "RenderableModel",
|
||||
GeometryFile = models .. "voyager-antenna.obj",
|
||||
ModelTransform = RotationMatrix,
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Voyager 1 Antenna",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
local sunTransforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
|
||||
|
||||
@@ -35,20 +36,6 @@ local RotationMatrix = {
|
||||
}
|
||||
|
||||
|
||||
local LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
},
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
|
||||
local Voyager2 = {
|
||||
Identifier = "Voyager_2",
|
||||
Parent = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
@@ -83,7 +70,14 @@ local Voyager2Main = {
|
||||
Type = "RenderableModel",
|
||||
GeometryFile = models .. "voyager-main.obj",
|
||||
ModelTransform = RotationMatrix,
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Voyager 2 Main",
|
||||
@@ -98,7 +92,14 @@ local Voyager2Antenna = {
|
||||
Type = "RenderableModel",
|
||||
GeometryFile = models .. "voyager-antenna.obj",
|
||||
ModelTransform = RotationMatrix,
|
||||
LightSources = LightSources
|
||||
LightSources = {
|
||||
sun.LightSource,
|
||||
{
|
||||
Identifier = "Camera",
|
||||
Type = "CameraLightSource",
|
||||
Intensity = 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Voyager 2 Antenna",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
local satelliteHelper = asset.require("util/tle_helper")
|
||||
local transforms = asset.require("scene/solarsystem/planets/earth/transforms")
|
||||
local sunTransforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sun = asset.require("scene/solarsystem/sun/sun")
|
||||
|
||||
local url = "http://celestrak.com/satcat/tle.php?CATNR=25544"
|
||||
local identifier = "ISS"
|
||||
@@ -62,12 +62,7 @@ local initializeAndAddNodes = function()
|
||||
GeometryFile = models .. "ISS.fbx",
|
||||
ModelScale = "Centimeter",
|
||||
LightSources = {
|
||||
{
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
}
|
||||
sun.LightSource
|
||||
},
|
||||
PerformShading = true,
|
||||
DisableFaceCulling = true
|
||||
|
||||
@@ -44,6 +44,13 @@ local SunLabel = {
|
||||
}
|
||||
}
|
||||
|
||||
local LightSource = {
|
||||
Type = "SceneGraphLightSource",
|
||||
Identifier = "Sun",
|
||||
Node = transforms.SolarSystemBarycenter.Identifier,
|
||||
Intensity = 1.0
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(Sun)
|
||||
openspace.addSceneGraphNode(SunLabel)
|
||||
@@ -56,6 +63,7 @@ end)
|
||||
|
||||
asset.export(Sun)
|
||||
asset.export(SunLabel)
|
||||
asset.export("LightSource", LightSource)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ asset.require("./static_server")
|
||||
local guiCustomization = asset.require("customization/gui")
|
||||
|
||||
-- Select which commit hashes to use for the frontend and backend
|
||||
local frontendHash = "234ddc8975ff03fd45708f9668c92bd31f7e79e8"
|
||||
local frontendHash = "1823d1b030e3e8ecc768f936e78496ad43adcf62"
|
||||
local dataProvider = "data.openspaceproject.com/files/webgui"
|
||||
|
||||
local frontend = asset.syncedResource({
|
||||
|
||||
@@ -12,17 +12,28 @@
|
||||
<div class="col-lg-12">
|
||||
<p>
|
||||
<a href="#{{urlify name}}" name="{{urlify name}}">
|
||||
|
||||
<span class="documentation-key">{{name}}(</span>
|
||||
<span class="documentation-type">{{arguments}}</span>
|
||||
<span class="documentation-function-arguments">
|
||||
{{#each arguments}}
|
||||
<span class="arguments-name">{{name}}</span>
|
||||
<span class="arguments-type">({{type}})</span>
|
||||
{{#unless @last}},{{/unless}}
|
||||
{{/each}}
|
||||
</span>
|
||||
<span class="documentation-key">)</span>
|
||||
{{#if returnType}}
|
||||
<span class="documentation-function-return">
|
||||
<span class="return-arrow"> -></span>
|
||||
<span class="return-type"> {{returnType}}</span>
|
||||
</span>
|
||||
{{/if}}
|
||||
</a>
|
||||
</p>
|
||||
<p class="documentation-description">{{help}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
|
||||
@@ -63,6 +63,23 @@
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.documentation-function-arguments,
|
||||
.documentation-function-return
|
||||
{
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.documentation-function-arguments > .arguments-name {
|
||||
color: #777;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.documentation-function-arguments > .arguments-type,
|
||||
.documentation-function-return
|
||||
{
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.documentation-key {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
|
||||
Submodule ext/ghoul updated: 35995e3e78...8d85f42fc3
@@ -213,11 +213,6 @@ void setAdditionalScriptsFromProfile(const Profile& p);
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
// Lua functions - exposed for testing
|
||||
namespace openspace::luascriptfunctions {
|
||||
|
||||
int createSingleColorImage(lua_State* L);
|
||||
|
||||
} // openspace::luascriptfunctions
|
||||
std::filesystem::path createSingleColorImage(std::string name, glm::dvec3 color);
|
||||
|
||||
#endif // __OPENSPACE_CORE___OPENSPACEENGINE___H__
|
||||
|
||||
@@ -237,9 +237,7 @@ public:
|
||||
|
||||
/**
|
||||
* Returns the Lua library that contains all Lua functions available to change the
|
||||
* scene graph. The functions contained are
|
||||
* - openspace::luascriptfunctions::property_setValue
|
||||
* - openspace::luascriptfunctions::property_getValue
|
||||
* scene graph.
|
||||
* \return The Lua library that contains all Lua functions available to change the
|
||||
* scene graph
|
||||
*/
|
||||
|
||||
@@ -47,8 +47,18 @@ struct LuaLibrary {
|
||||
std::string name;
|
||||
/// The function pointer that is executed if the function is called
|
||||
lua_CFunction function;
|
||||
/// A text describing the arguments to this function
|
||||
std::string argumentText;
|
||||
struct Argument {
|
||||
/// The name of the arguments
|
||||
std::string name;
|
||||
/// The type of the argument
|
||||
std::string type;
|
||||
/// The default value if it exists
|
||||
std::optional<std::string> defaultValue = std::nullopt;
|
||||
};
|
||||
/// The ordered arguments that this function takes
|
||||
std::vector<Argument> arguments;
|
||||
/// Information about the type that this function returns
|
||||
std::string returnType;
|
||||
/// A help text describing what the function does/
|
||||
std::string helpText;
|
||||
};
|
||||
@@ -61,19 +71,9 @@ struct LuaLibrary {
|
||||
/// A list of all libraries that are children for this library
|
||||
std::vector<LuaLibrary> subLibraries = std::vector<LuaLibrary>();
|
||||
|
||||
/// This struct contains information about a function or constant that is defined in
|
||||
/// a Lua script
|
||||
struct Documentation {
|
||||
/// The name of the function/variable
|
||||
std::string name;
|
||||
/// The description of the parameters for a function
|
||||
std::string parameter;
|
||||
/// The description of the function/variable
|
||||
std::string description;
|
||||
};
|
||||
/// The list of documentations will be populated automatically by parsing the Lua
|
||||
/// scripts
|
||||
std::vector<Documentation> documentations = std::vector<Documentation>();
|
||||
std::vector<Function> documentations = std::vector<Function>();
|
||||
|
||||
/// Comparison function that compares two LuaLibrary%s name
|
||||
bool operator<(const LuaLibrary& rhs) const;
|
||||
|
||||
@@ -143,8 +143,6 @@ public:
|
||||
|
||||
/**
|
||||
* Sets a relative time from profile.
|
||||
* \param setTime a string containing time adjustment as described in documentation
|
||||
* for luascriptfunctions::time_advancedTime
|
||||
*/
|
||||
void setTimeRelativeFromProfile(const std::string& setTime);
|
||||
|
||||
|
||||
@@ -350,7 +350,7 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& data, const Deferred
|
||||
|
||||
// Shadow calculations..
|
||||
_shadowDataArrayCache.clear();
|
||||
for (const ShadowConfiguration& shadowConf : _shadowConfArray) {
|
||||
for (ShadowConfiguration& shadowConf : _shadowConfArray) {
|
||||
// TO REMEMBER: all distances and lengths in world coordinates are in
|
||||
// meters!!! We need to move this to view space...
|
||||
double lt;
|
||||
@@ -374,10 +374,19 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& data, const Deferred
|
||||
casterPos *= KM_TO_M; // converting to meters
|
||||
|
||||
SceneGraphNode* sourceNode = sceneGraphNode(shadowConf.source.first);
|
||||
if (!sourceNode) {
|
||||
if (!shadowConf.printedSourceError) {
|
||||
LERROR("Invalid scenegraph node for the shadow's receiver");
|
||||
shadowConf.printedSourceError = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
SceneGraphNode* casterNode = sceneGraphNode(shadowConf.caster.first);
|
||||
|
||||
if (!sourceNode || !casterNode) {
|
||||
LERROR("Invalid scenegraph node for the shadow's caster or receiver");
|
||||
if (!casterNode) {
|
||||
if (!shadowConf.printedCasterError) {
|
||||
LERROR("Invalid scenegraph node for the shadow's caster");
|
||||
shadowConf.printedCasterError = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,10 @@ struct TransformData;
|
||||
struct ShadowConfiguration {
|
||||
std::pair<std::string, double> source;
|
||||
std::pair<std::string, double> caster;
|
||||
// Set to 'true' if we printed an error because we couldn't find the source or caster.
|
||||
// We only want to print a message once
|
||||
bool printedSourceError = false;
|
||||
bool printedCasterError = false;
|
||||
};
|
||||
|
||||
namespace documentation { struct Documentation; }
|
||||
|
||||
@@ -136,18 +136,8 @@ scripting::LuaLibrary ScreenSpaceDashboard::luaLibrary() {
|
||||
return {
|
||||
"dashboard",
|
||||
{
|
||||
{
|
||||
"addDashboardItemToScreenSpace",
|
||||
&luascriptfunctions::addDashboardItemToScreenSpace,
|
||||
"string, table",
|
||||
"Adds a new dashboard item to an existing SceenSpaceDashboard."
|
||||
},
|
||||
{
|
||||
"removeDashboardItemsFromScreenSpace",
|
||||
&luascriptfunctions::removeDashboardItemsFromScreenSpace,
|
||||
"string",
|
||||
"Removes all dashboard items from an existing ScreenSpaceDashboard."
|
||||
}
|
||||
codegen::lua::AddDashboardItemToScreenSpace,
|
||||
codegen::lua::RemoveDashboardItemsFromScreenSpace
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,56 +22,48 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
namespace openspace::luascriptfunctions {
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* addDashboardItemToScreenSpace(string, table):
|
||||
*/
|
||||
int addDashboardItemToScreenSpace(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::addDashboardItemToScreenSpace");
|
||||
auto [name, d] = ghoul::lua::values<std::string, ghoul::Dictionary>(L);
|
||||
//Adds a new dashboard item to an existing SceenSpaceDashboard.
|
||||
[[codegen::luawrap]] void addDashboardItemToScreenSpace(std::string identifier,
|
||||
ghoul::Dictionary dashboard)
|
||||
{
|
||||
using namespace openspace;
|
||||
|
||||
ScreenSpaceRenderable* ssr = global::renderEngine->screenSpaceRenderable(name);
|
||||
ScreenSpaceRenderable* ssr = global::renderEngine->screenSpaceRenderable(identifier);
|
||||
if (!ssr) {
|
||||
return ghoul::lua::luaError(L, "Provided name is not a ScreenSpace item");
|
||||
throw ghoul::lua::LuaError("Provided name is not a ScreenSpace item");
|
||||
}
|
||||
|
||||
ScreenSpaceDashboard* dash = dynamic_cast<ScreenSpaceDashboard*>(ssr);
|
||||
if (!dash) {
|
||||
return ghoul::lua::luaError(
|
||||
L,
|
||||
throw ghoul::lua::LuaError(
|
||||
"Provided name is a ScreenSpace item but not a dashboard"
|
||||
);
|
||||
}
|
||||
|
||||
dash->dashboard().addDashboardItem(DashboardItem::createFromDictionary(d));
|
||||
return 0;
|
||||
dash->dashboard().addDashboardItem(DashboardItem::createFromDictionary(dashboard));
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* removeDashboardItemsFromScreenSpace(string):
|
||||
*/
|
||||
int removeDashboardItemsFromScreenSpace(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::removeDashboardItemsFromScreenSpace");
|
||||
const std::string name = ghoul::lua::value<std::string>(L);
|
||||
// Removes all dashboard items from an existing ScreenSpaceDashboard.
|
||||
[[codegen::luawrap]] void removeDashboardItemsFromScreenSpace(std::string identifier) {
|
||||
using namespace openspace;
|
||||
|
||||
ScreenSpaceRenderable* ssr = global::renderEngine->screenSpaceRenderable(name);
|
||||
ScreenSpaceRenderable* ssr = global::renderEngine->screenSpaceRenderable(identifier);
|
||||
if (!ssr) {
|
||||
return ghoul::lua::luaError(L, "Provided name is not a ScreenSpace item");
|
||||
throw ghoul::lua::LuaError("Provided identifier is not a ScreenSpace item");
|
||||
}
|
||||
|
||||
ScreenSpaceDashboard* dash = dynamic_cast<ScreenSpaceDashboard*>(ssr);
|
||||
if (!dash) {
|
||||
return ghoul::lua::luaError(
|
||||
L,
|
||||
"Provided name is a ScreenSpace item but not a dashboard"
|
||||
throw ghoul::lua::LuaError(
|
||||
"Provided identifier is a ScreenSpace item but not a dashboard"
|
||||
);
|
||||
}
|
||||
|
||||
dash->dashboard().clearDashboardItems();
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace openspace::luascriptfunctions
|
||||
#include "screenspacedashboard_lua_codegen.cpp"
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -26,9 +26,18 @@
|
||||
|
||||
#include <modules/debugging/rendering/renderabledebugplane.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/path.h>
|
||||
#include <openspace/navigation/pathnavigator.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/assert.h>
|
||||
#include <ghoul/misc/templatefactory.h>
|
||||
|
||||
@@ -53,51 +62,16 @@ std::vector<documentation::Documentation> DebuggingModule::documentations() cons
|
||||
}
|
||||
|
||||
scripting::LuaLibrary DebuggingModule::luaLibrary() const {
|
||||
scripting::LuaLibrary res;
|
||||
res.name = "debugging";
|
||||
res.functions = {
|
||||
return {
|
||||
"debugging",
|
||||
{
|
||||
"renderCameraPath",
|
||||
&luascriptfunctions::renderCameraPath,
|
||||
"[number, bool, number]",
|
||||
"Render the current camera path from the path navigation system. The "
|
||||
"first optional argument is the number of samples to take along the path "
|
||||
"(defaults to 100). If a second optional argument is included and set to "
|
||||
"true, a line indicating the camera view direction along the path will "
|
||||
"also be rendered. This can be useful when debugging camera orientations. "
|
||||
"Finally, the third optional argument can be used to set the length "
|
||||
"(in meter) of the view direction lines"
|
||||
},
|
||||
{
|
||||
"removeRenderedCameraPath",
|
||||
&luascriptfunctions::removeRenderedCameraPath,
|
||||
"",
|
||||
"Removes the rendered camera path, if there is one"
|
||||
},
|
||||
{
|
||||
"renderPathControlPoints",
|
||||
&luascriptfunctions::renderPathControlPoints,
|
||||
"[number]",
|
||||
"Render the control points for the camera path spline as spheres. The "
|
||||
"optional argument can be used to set the radius of the created spheres. "
|
||||
},
|
||||
{
|
||||
"removePathControlPoints",
|
||||
&luascriptfunctions::removePathControlPoints,
|
||||
"",
|
||||
"Removes the rendered control points"
|
||||
},
|
||||
{
|
||||
"addCartesianAxes",
|
||||
&luascriptfunctions::addCartesianAxes,
|
||||
"string, [number]",
|
||||
"Adds a set of Cartesian axes to the scene graph node identified by the "
|
||||
"first string, to illustrate its local coordinate system. The second "
|
||||
"(optional) argument is a scale value, in meters."
|
||||
codegen::lua::RenderCameraPath,
|
||||
codegen::lua::RemoveRenderedCameraPath,
|
||||
codegen::lua::RenderPathControlPoints,
|
||||
codegen::lua::RemovePathControlPoints,
|
||||
codegen::lua::AddCartesianAxes
|
||||
}
|
||||
};
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -22,46 +22,39 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/path.h>
|
||||
#include <openspace/navigation/pathnavigator.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char _loggerCat[] = "Debugging";
|
||||
|
||||
constexpr const char RenderedPathIdentifier[] = "CurrentCameraPath";
|
||||
constexpr const char RenderedPointsIdentifier[] = "CurrentPathControlPoints";
|
||||
constexpr const char DebuggingGuiPath[] = "/Debugging";
|
||||
constexpr const char RenderedPathIdentifier[] = "CurrentCameraPath";
|
||||
constexpr const char RenderedPointsIdentifier[] = "CurrentPathControlPoints";
|
||||
constexpr const char DebuggingGuiPath[] = "/Debugging";
|
||||
|
||||
constexpr const glm::vec3 PathColor = { 1.0, 1.0, 0.0 };
|
||||
constexpr const glm::vec3 OrientationLineColor = { 0.0, 1.0, 1.0 };
|
||||
constexpr const glm::vec3 PathColor = { 1.0, 1.0, 0.0 };
|
||||
constexpr const glm::vec3 OrientationLineColor = { 0.0, 1.0, 1.0 };
|
||||
|
||||
// Conver the input string to a format that is valid as an identifier
|
||||
std::string makeIdentifier(std::string s) {
|
||||
std::replace(s.begin(), s.end(), ' ', '_');
|
||||
std::replace(s.begin(), s.end(), '.', '-');
|
||||
// Remove quotes and apostrophe, since they cause problems
|
||||
// when a string is translated to a script call
|
||||
s.erase(remove(s.begin(), s.end(), '\"'), s.end());
|
||||
s.erase(remove(s.begin(), s.end(), '\''), s.end());
|
||||
return s;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace openspace::luascriptfunctions {
|
||||
// Conver the input string to a format that is valid as an identifier
|
||||
std::string makeIdentifier(std::string s) {
|
||||
std::replace(s.begin(), s.end(), ' ', '_');
|
||||
std::replace(s.begin(), s.end(), '.', '-');
|
||||
// Remove quotes and apostrophe, since they cause problems
|
||||
// when a string is translated to a script call
|
||||
s.erase(remove(s.begin(), s.end(), '\"'), s.end());
|
||||
s.erase(remove(s.begin(), s.end(), '\''), s.end());
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* PathNavigation
|
||||
* Renders the current camera path
|
||||
* Render the current camera path from the path navigation system. The first optional
|
||||
* argument is the number of samples to take along the path (defaults to 100). If a second
|
||||
* optional argument is included and set to true, a line indicating the camera view
|
||||
* direction along the path will also be rendered. This can be useful when debugging
|
||||
* camera orientations. Finally, the third optional argument can be used to set the length
|
||||
* (in meter) of the view direction lines.
|
||||
*/
|
||||
int renderCameraPath(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 0, 3 }, "lua::renderCameraPath");
|
||||
[[codegen::luawrap]] void renderCameraPath(int nSteps = 100,
|
||||
bool renderDirections = false,
|
||||
double directionLineLength = 6e7)
|
||||
{
|
||||
using namespace openspace;
|
||||
|
||||
if (!global::navigationHandler->pathNavigator().hasCurrentPath()) {
|
||||
LWARNINGC("Debugging: PathNavigation", "There is no current path to render");
|
||||
@@ -70,15 +63,7 @@ int renderCameraPath(lua_State* L) {
|
||||
const interaction::Path* currentPath =
|
||||
global::navigationHandler->pathNavigator().currentPath();
|
||||
|
||||
auto [nSteps, renderDirections, directionLineLength] = ghoul::lua::values<
|
||||
std::optional<int>, std::optional<bool>, std::optional<double>
|
||||
>(L);
|
||||
|
||||
nSteps = nSteps.value_or(100);
|
||||
renderDirections = renderDirections.value_or(false);
|
||||
directionLineLength = directionLineLength.value_or(6e7);
|
||||
|
||||
// Parent node. Note that we only render one path at a time, so remove the previously
|
||||
// Parent node. Note that we only render one path at a time, so remove the previously
|
||||
// rendered one, if any
|
||||
std::string addParentScript = fmt::format(
|
||||
"if openspace.hasSceneGraphNode('{0}') then "
|
||||
@@ -88,14 +73,14 @@ int renderCameraPath(lua_State* L) {
|
||||
RenderedPathIdentifier
|
||||
);
|
||||
|
||||
openspace::global::scriptEngine->queueScript(
|
||||
global::scriptEngine->queueScript(
|
||||
addParentScript,
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
|
||||
// Get the poses along the path
|
||||
std::vector<CameraPose> poses;
|
||||
const double du = 1.0 / (*nSteps);
|
||||
const double du = 1.0 / nSteps;
|
||||
const double length = currentPath->pathLength();
|
||||
for (double u = 0.0; u < 1.0; u += du) {
|
||||
const CameraPose p = currentPath->interpolatedPose(u * length);
|
||||
@@ -120,7 +105,7 @@ int renderCameraPath(lua_State* L) {
|
||||
"}"
|
||||
"}";
|
||||
|
||||
openspace::global::scriptEngine->queueScript(
|
||||
global::scriptEngine->queueScript(
|
||||
fmt::format("openspace.addSceneGraphNode({})", pointNode),
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
@@ -142,7 +127,7 @@ int renderCameraPath(lua_State* L) {
|
||||
"}"
|
||||
"}";
|
||||
|
||||
openspace::global::scriptEngine->queueScript(
|
||||
global::scriptEngine->queueScript(
|
||||
fmt::format("openspace.addSceneGraphNode({})", lineNode),
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
@@ -162,43 +147,35 @@ int renderCameraPath(lua_State* L) {
|
||||
|
||||
// Add first point separately so that we can create first line in for loop
|
||||
addPoint(pointIdentifier(0), poses.front().position);
|
||||
if (*renderDirections) {
|
||||
addDirectionLine(pointIdentifier(0), poses.front(), *directionLineLength);
|
||||
if (renderDirections) {
|
||||
addDirectionLine(pointIdentifier(0), poses.front(), directionLineLength);
|
||||
}
|
||||
|
||||
for (int i = 1; i < static_cast<int>(poses.size()); i++) {
|
||||
addPoint(pointIdentifier(i), poses[i].position);
|
||||
addLineBetweenPoints(pointIdentifier(i), pointIdentifier(i - 1), PathColor, 4.f);
|
||||
|
||||
if (*renderDirections) {
|
||||
addDirectionLine(pointIdentifier(i), poses[i], *directionLineLength);
|
||||
if (renderDirections) {
|
||||
addDirectionLine(pointIdentifier(i), poses[i], directionLineLength);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* PathNavigation
|
||||
* Removes the currently rendered camera path if there is one
|
||||
*/
|
||||
int removeRenderedCameraPath(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::removeRenderedCameraPath");
|
||||
|
||||
openspace::global::scriptEngine->queueScript(
|
||||
fmt::format("openspace.removeSceneGraphNode('{}') ", RenderedPathIdentifier),
|
||||
// Removes the currently rendered camera path if there is one.
|
||||
[[codegen::luawrap]] void removeRenderedCameraPath() {
|
||||
using namespace openspace;
|
||||
global::scriptEngine->queueScript(
|
||||
fmt::format("openspace.removeSceneGraphNode('{}');", RenderedPathIdentifier),
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* PathNavigation
|
||||
* Renders the control points of the current camera path
|
||||
* Render the control points for the camera path spline as spheres. The optional argument
|
||||
* can be used to set the radius of the created spheres.
|
||||
*/
|
||||
int renderPathControlPoints(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 0, 1 }, "lua::renderPathControlPoints");
|
||||
[[codegen::luawrap]] void renderPathControlPoints(double radius = 2000000.0) {
|
||||
using namespace openspace;
|
||||
|
||||
if (!global::navigationHandler->pathNavigator().hasCurrentPath()) {
|
||||
LWARNINGC(
|
||||
@@ -209,20 +186,17 @@ int renderPathControlPoints(lua_State* L) {
|
||||
const interaction::Path* currentPath =
|
||||
global::navigationHandler->pathNavigator().currentPath();
|
||||
|
||||
auto [radius] = ghoul::lua::values<std::optional<double>>(L);
|
||||
radius = radius.value_or(2000000.0);
|
||||
|
||||
// Parent node. Note that we only render one set of points at a time,
|
||||
// so remove any previously rendered ones
|
||||
// Parent node. Note that we only render one set of points at a time, so remove any
|
||||
// previously rendered ones
|
||||
std::string addParentScript = fmt::format(
|
||||
"if openspace.hasSceneGraphNode('{0}') then "
|
||||
"openspace.removeSceneGraphNode('{0}') "
|
||||
"openspace.removeSceneGraphNode('{0}') "
|
||||
"end "
|
||||
"openspace.addSceneGraphNode( {{ Identifier = '{0}' }} )",
|
||||
RenderedPointsIdentifier
|
||||
);
|
||||
|
||||
openspace::global::scriptEngine->queueScript(
|
||||
global::scriptEngine->queueScript(
|
||||
addParentScript,
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
@@ -234,74 +208,69 @@ int renderPathControlPoints(lua_State* L) {
|
||||
|
||||
const char* colorTexturePath = "openspace.absPath("
|
||||
"openspace.createSingleColorImage('point_color', { 0.0, 1.0, 0.0 })"
|
||||
")";
|
||||
")";
|
||||
|
||||
for (size_t i = 0; i < points.size(); i++) {
|
||||
const std::string& node = "{"
|
||||
"Identifier = 'ControlPoint_" + std::to_string(i) + "',"
|
||||
"Parent = '" + RenderedPointsIdentifier + "',"
|
||||
"Transform = { "
|
||||
"Translation = {"
|
||||
"Type = 'StaticTranslation',"
|
||||
"Position = " + ghoul::to_string(points[i]) + ""
|
||||
"},"
|
||||
"Translation = {"
|
||||
"Type = 'StaticTranslation',"
|
||||
"Position = " + ghoul::to_string(points[i]) + ""
|
||||
"},"
|
||||
"},"
|
||||
"Renderable = {"
|
||||
"Type = 'RenderableSphere',"
|
||||
"Enabled = true,"
|
||||
"Segments = 30,"
|
||||
"Size = " + std::to_string(*radius) + ","
|
||||
"Texture = " + colorTexturePath + ""
|
||||
"Type = 'RenderableSphere',"
|
||||
"Enabled = true,"
|
||||
"Segments = 30,"
|
||||
"Size = " + std::to_string(radius) + ","
|
||||
"Texture = " + colorTexturePath + ""
|
||||
"},"
|
||||
"GUI = {"
|
||||
"Name = 'Control Point " + std::to_string(i) + "',"
|
||||
"Path = '" + guiPath + "'"
|
||||
"Name = 'Control Point " + std::to_string(i) + "',"
|
||||
"Path = '" + guiPath + "'"
|
||||
"}"
|
||||
"}";
|
||||
"}";
|
||||
|
||||
openspace::global::scriptEngine->queueScript(
|
||||
global::scriptEngine->queueScript(
|
||||
fmt::format("openspace.addSceneGraphNode({})", node),
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* PathNavigation
|
||||
* Removes the rendered control points
|
||||
*/
|
||||
int removePathControlPoints(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::removePathControlPoints");
|
||||
|
||||
openspace::global::scriptEngine->queueScript(
|
||||
fmt::format("openspace.removeSceneGraphNode('{}') ", RenderedPointsIdentifier),
|
||||
// Removes the rendered control points.
|
||||
[[codegen::luawrap]] void removePathControlPoints() {
|
||||
using namespace openspace;
|
||||
global::scriptEngine->queueScript(
|
||||
fmt::format("openspace.removeSceneGraphNode('{}');", RenderedPointsIdentifier),
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a set of cartesian axes to the specified scene graph node
|
||||
* Adds a set of Cartesian axes to the scene graph node identified by the first string, to
|
||||
* illustrate its local coordinate system. The second (optional) argument is a scale
|
||||
* value, in meters.
|
||||
*/
|
||||
int addCartesianAxes(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 1, 2 }, "lua::addCartesianAxes");
|
||||
|
||||
auto [nodeIdentifier, scale] =
|
||||
ghoul::lua::values<std::string, std::optional<double>>(L);
|
||||
|
||||
[[codegen::luawrap]] void addCartesianAxes(std::string nodeIdentifier,
|
||||
std::optional<double> scale)
|
||||
{
|
||||
using namespace openspace;
|
||||
SceneGraphNode* n = global::renderEngine->scene()->sceneGraphNode(nodeIdentifier);
|
||||
if (!n) {
|
||||
return ghoul::lua::luaError(L, "Unknown scene graph node: " + nodeIdentifier);
|
||||
throw ghoul::lua::LuaError("Unknown scene graph node: " + nodeIdentifier);
|
||||
}
|
||||
|
||||
if (!scale.has_value()) {
|
||||
scale = 2.0 * n->boundingSphere();
|
||||
if (n->boundingSphere() < 1E-3) {
|
||||
LWARNING("Using zero bounding sphere for scale of created axes. You might "
|
||||
"have to set the scale manually for them to be visible");
|
||||
if (n->boundingSphere() <= 0.0) {
|
||||
LWARNINGC(
|
||||
"Debugging: Cartesian Axes",
|
||||
"Using zero bounding sphere for scale of created axes. You need to set "
|
||||
"the scale manually for them to be visible"
|
||||
);
|
||||
scale = 1.0;
|
||||
}
|
||||
}
|
||||
@@ -311,31 +280,30 @@ int addCartesianAxes(lua_State* L) {
|
||||
"Identifier = '" + identifier + "',"
|
||||
"Parent = '" + nodeIdentifier + "',"
|
||||
"Transform = { "
|
||||
"Scale = {"
|
||||
"Type = 'StaticScale',"
|
||||
"Scale = " + std::to_string(*scale) + ""
|
||||
"}"
|
||||
"Scale = {"
|
||||
"Type = 'StaticScale',"
|
||||
"Scale = " + std::to_string(*scale) + ""
|
||||
"}"
|
||||
"},"
|
||||
"Renderable = {"
|
||||
"Type = 'RenderableCartesianAxes',"
|
||||
"Enabled = true,"
|
||||
"XColor = { 1.0, 0.0, 0.0 },"
|
||||
"YColor = { 0.0, 1.0, 0.0 },"
|
||||
"ZColor = { 0.0, 0.0, 1.0 }"
|
||||
"Type = 'RenderableCartesianAxes',"
|
||||
"Enabled = true,"
|
||||
"XColor = { 1.0, 0.0, 0.0 },"
|
||||
"YColor = { 0.0, 1.0, 0.0 },"
|
||||
"ZColor = { 0.0, 0.0, 1.0 }"
|
||||
"},"
|
||||
"GUI = {"
|
||||
"Name = '" + identifier + "',"
|
||||
"Path = '" + DebuggingGuiPath + "/Coordiante Systems'"
|
||||
"Name = '" + identifier + "',"
|
||||
"Path = '" + DebuggingGuiPath + "/Coordiante Systems'"
|
||||
"}"
|
||||
"}";
|
||||
|
||||
openspace::global::scriptEngine->queueScript(
|
||||
fmt::format("openspace.addSceneGraphNode({})", axes),
|
||||
global::scriptEngine->queueScript(
|
||||
fmt::format("openspace.addSceneGraphNode({});", axes),
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace openspace::luascriptfunctions
|
||||
#include "debuggingmodule_lua_codegen.cpp"
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -24,15 +24,29 @@
|
||||
|
||||
#include <modules/exoplanets/exoplanetsmodule.h>
|
||||
|
||||
#include <modules/exoplanets/exoplanetshelper.h>
|
||||
#include <modules/exoplanets/rendering/renderableorbitdisc.h>
|
||||
#include <modules/exoplanets/tasks/exoplanetsdatapreparationtask.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/globalscallbacks.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <openspace/util/distanceconstants.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <openspace/util/timeconversion.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/fmt.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/assert.h>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include "exoplanetsmodule_lua.inl"
|
||||
|
||||
@@ -256,41 +270,6 @@ float ExoplanetsModule::habitableZoneOpacity() const {
|
||||
return _habitableZoneOpacity;
|
||||
}
|
||||
|
||||
scripting::LuaLibrary ExoplanetsModule::luaLibrary() const {
|
||||
scripting::LuaLibrary res;
|
||||
res.name = "exoplanets";
|
||||
res.functions = {
|
||||
{
|
||||
"addExoplanetSystem",
|
||||
&exoplanets::luascriptfunctions::addExoplanetSystem,
|
||||
"string or list of strings",
|
||||
"Add one or multiple exoplanet systems to the scene, as specified by the "
|
||||
"input. An input string should be the name of the system host star"
|
||||
},
|
||||
{
|
||||
"removeExoplanetSystem",
|
||||
&exoplanets::luascriptfunctions::removeExoplanetSystem,
|
||||
"string",
|
||||
"Removes the nodes of the specified exoplanet system from the scene graph"
|
||||
},
|
||||
{
|
||||
"listAvailableExoplanetSystems",
|
||||
&exoplanets::luascriptfunctions::listAvailableExoplanetSystems,
|
||||
"",
|
||||
"Prints a list with the names of all exoplanet systems that can be added to "
|
||||
"the scene graph to the OpenSpace Log"
|
||||
},
|
||||
{
|
||||
"getListOfExoplanets",
|
||||
&exoplanets::luascriptfunctions::getListOfExoplanets,
|
||||
"",
|
||||
"Gets a list with the names of all exoplanet systems"
|
||||
}
|
||||
};
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void ExoplanetsModule::internalInitialize(const ghoul::Dictionary& dict) {
|
||||
const Parameters p = codegen::bake<Parameters>(dict);
|
||||
|
||||
@@ -343,4 +322,16 @@ std::vector<documentation::Documentation> ExoplanetsModule::documentations() con
|
||||
};
|
||||
}
|
||||
|
||||
scripting::LuaLibrary ExoplanetsModule::luaLibrary() const {
|
||||
return {
|
||||
"exoplanets",
|
||||
{
|
||||
codegen::lua::AddExoplanetSystem,
|
||||
codegen::lua::RemoveExoplanetSystem,
|
||||
codegen::lua::GetListOfExoplanets,
|
||||
codegen::lua::ListAvailableExoplanetSystems
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -22,44 +22,25 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/exoplanets/exoplanetshelper.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <openspace/util/distanceconstants.h>
|
||||
#include <openspace/util/timeconversion.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/fmt.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/assert.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
namespace {
|
||||
constexpr const char _loggerCat[] = "ExoplanetsModule";
|
||||
|
||||
constexpr const char ExoplanetsGuiPath[] = "/Milky Way/Exoplanets/Exoplanet Systems/";
|
||||
constexpr const char _loggerCat[] = "ExoplanetsModule";
|
||||
|
||||
// Lua cannot handle backslashes, so replace these with forward slashes
|
||||
std::string formatPathToLua(const std::string& path) {
|
||||
std::string resPath = path;
|
||||
std::replace(resPath.begin(), resPath.end(), '\\', '/');
|
||||
return resPath;
|
||||
}
|
||||
} // namespace
|
||||
constexpr const char ExoplanetsGuiPath[] = "/Milky Way/Exoplanets/Exoplanet Systems/";
|
||||
|
||||
namespace openspace::exoplanets::luascriptfunctions {
|
||||
// Lua cannot handle backslashes, so replace these with forward slashes
|
||||
std::string formatPathToLua(const std::string& path) {
|
||||
std::string resPath = path;
|
||||
std::replace(resPath.begin(), resPath.end(), '\\', '/');
|
||||
return resPath;
|
||||
}
|
||||
|
||||
constexpr const float AU = static_cast<float>(distanceconstants::AstronomicalUnit);
|
||||
constexpr const float SolarRadius = static_cast<float>(distanceconstants::SolarRadius);
|
||||
constexpr const float JupiterRadius =
|
||||
static_cast<float>(distanceconstants::JupiterRadius);
|
||||
openspace::exoplanets::ExoplanetSystem findExoplanetSystemInData(
|
||||
std::string_view starName)
|
||||
{
|
||||
using namespace openspace;
|
||||
using namespace exoplanets;
|
||||
|
||||
ExoplanetSystem findExoplanetSystemInData(std::string_view starName) {
|
||||
const ExoplanetsModule* module = global::moduleEngine->module<ExoplanetsModule>();
|
||||
|
||||
const std::string binPath = module->exoplanetsDataPath();
|
||||
@@ -135,6 +116,9 @@ ExoplanetSystem findExoplanetSystemInData(std::string_view starName) {
|
||||
}
|
||||
|
||||
void createExoplanetSystem(const std::string& starName) {
|
||||
using namespace openspace;
|
||||
using namespace exoplanets;
|
||||
|
||||
const std::string starIdentifier = createIdentifier(starName);
|
||||
|
||||
std::string sanitizedStarName = starName;
|
||||
@@ -173,7 +157,7 @@ void createExoplanetSystem(const std::string& starName) {
|
||||
const glm::dmat3 exoplanetSystemRotation = computeSystemRotation(starPos);
|
||||
|
||||
// Star
|
||||
float radiusInMeter = SolarRadius;
|
||||
double radiusInMeter = distanceconstants::SolarRadius;
|
||||
if (!std::isnan(system.starData.radius)) {
|
||||
radiusInMeter *= system.starData.radius;
|
||||
}
|
||||
@@ -242,7 +226,7 @@ void createExoplanetSystem(const std::string& starName) {
|
||||
"}"
|
||||
"}";
|
||||
|
||||
openspace::global::scriptEngine->queueScript(
|
||||
global::scriptEngine->queueScript(
|
||||
"openspace.addSceneGraphNode(" + starParent + ");",
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
@@ -278,25 +262,25 @@ void createExoplanetSystem(const std::string& starName) {
|
||||
sEpoch = "2009-05-19T07:11:34.080";
|
||||
}
|
||||
|
||||
float planetRadius;
|
||||
double planetRadius;
|
||||
std::string enabled;
|
||||
if (std::isnan(planet.r)) {
|
||||
if (std::isnan(planet.rStar)) {
|
||||
planetRadius = planet.a * 0.001f * AU;
|
||||
planetRadius = planet.a * 0.001 * distanceconstants::AstronomicalUnit;
|
||||
}
|
||||
else {
|
||||
planetRadius = planet.rStar * 0.1f * SolarRadius;
|
||||
planetRadius = planet.rStar * 0.1 * distanceconstants::SolarRadius;
|
||||
}
|
||||
enabled = "false";
|
||||
}
|
||||
else {
|
||||
planetRadius = static_cast<float>(planet.r) * JupiterRadius;
|
||||
planetRadius = planet.r * distanceconstants::JupiterRadius;
|
||||
enabled = "true";
|
||||
}
|
||||
|
||||
const float periodInSeconds = static_cast<float>(planet.per * SecondsPerDay);
|
||||
const float semiMajorAxisInMeter = planet.a * AU;
|
||||
const float semiMajorAxisInKm = semiMajorAxisInMeter * 0.001f;
|
||||
float periodInSeconds = static_cast<float>(planet.per * SecondsPerDay);
|
||||
double semiMajorAxisInMeter = planet.a * distanceconstants::AstronomicalUnit;
|
||||
double semiMajorAxisInKm = semiMajorAxisInMeter * 0.001;
|
||||
|
||||
const std::string planetIdentifier = createIdentifier(planetName);
|
||||
|
||||
@@ -356,7 +340,7 @@ void createExoplanetSystem(const std::string& starName) {
|
||||
"}"
|
||||
"}";
|
||||
|
||||
openspace::global::scriptEngine->queueScript(
|
||||
global::scriptEngine->queueScript(
|
||||
"openspace.addSceneGraphNode(" + planetTrailNode + ");"
|
||||
"openspace.addSceneGraphNode(" + planetNode + ");",
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
@@ -406,7 +390,7 @@ void createExoplanetSystem(const std::string& starName) {
|
||||
"}"
|
||||
"}";
|
||||
|
||||
openspace::global::scriptEngine->queueScript(
|
||||
global::scriptEngine->queueScript(
|
||||
"openspace.addSceneGraphNode(" + discNode + ");",
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
@@ -442,7 +426,7 @@ void createExoplanetSystem(const std::string& starName) {
|
||||
"},"
|
||||
"Scale = {"
|
||||
"Type = 'StaticScale',"
|
||||
"Scale = " + std::to_string(AU) + ""
|
||||
"Scale = " + std::to_string(distanceconstants::AstronomicalUnit) + ""
|
||||
"}"
|
||||
"},"
|
||||
"GUI = {"
|
||||
@@ -451,7 +435,7 @@ void createExoplanetSystem(const std::string& starName) {
|
||||
"}"
|
||||
"}";
|
||||
|
||||
openspace::global::scriptEngine->queueScript(
|
||||
global::scriptEngine->queueScript(
|
||||
"openspace.addSceneGraphNode(" + circle + ");",
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
@@ -506,7 +490,7 @@ void createExoplanetSystem(const std::string& starName) {
|
||||
"}"
|
||||
"}";
|
||||
|
||||
openspace::global::scriptEngine->queueScript(
|
||||
global::scriptEngine->queueScript(
|
||||
"openspace.addSceneGraphNode(" + zoneDiscNode + ");",
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
@@ -547,7 +531,7 @@ void createExoplanetSystem(const std::string& starName) {
|
||||
"}"
|
||||
"}";
|
||||
|
||||
openspace::global::scriptEngine->queueScript(
|
||||
global::scriptEngine->queueScript(
|
||||
"openspace.addSceneGraphNode(" + starGlare + ");",
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
@@ -555,46 +539,9 @@ void createExoplanetSystem(const std::string& starName) {
|
||||
}
|
||||
}
|
||||
|
||||
int addExoplanetSystem(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::addExoplanetSystem");
|
||||
std::variant<std::string, ghoul::Dictionary> v =
|
||||
ghoul::lua::value<std::variant<std::string, ghoul::Dictionary>>(L);
|
||||
|
||||
if (std::holds_alternative<std::string>(v)) {
|
||||
// The user provided a single name
|
||||
std::string starName = std::get<std::string>(v);
|
||||
createExoplanetSystem(starName);
|
||||
}
|
||||
else {
|
||||
// A list of names was provided
|
||||
ghoul::Dictionary starNames = ghoul::lua::value<ghoul::Dictionary>(L);
|
||||
for (size_t i = 1; i <= starNames.size(); ++i) {
|
||||
if (!starNames.hasValue<std::string>(std::to_string(i))) {
|
||||
return ghoul::lua::luaError(
|
||||
L,
|
||||
fmt::format("List item {} is of invalid type", i)
|
||||
);
|
||||
}
|
||||
const std::string& starName = starNames.value<std::string>(std::to_string(i));
|
||||
createExoplanetSystem(starName);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int removeExoplanetSystem(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::removeExoplanetSystem");
|
||||
std::string starName = ghoul::lua::value<std::string>(L);
|
||||
|
||||
const std::string starIdentifier = createIdentifier(std::move(starName));
|
||||
openspace::global::scriptEngine->queueScript(
|
||||
"openspace.removeSceneGraphNode('" + starIdentifier + "');",
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<std::string> hostStarsWithSufficientData() {
|
||||
using namespace openspace;
|
||||
using namespace exoplanets;
|
||||
const ExoplanetsModule* module = global::moduleEngine->module<ExoplanetsModule>();
|
||||
|
||||
if (!module->hasDataFiles()) {
|
||||
@@ -657,23 +604,42 @@ std::vector<std::string> hostStarsWithSufficientData() {
|
||||
return names;
|
||||
}
|
||||
|
||||
int getListOfExoplanets(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::getListOfExoplanets");
|
||||
|
||||
std::vector<std::string> names = hostStarsWithSufficientData();
|
||||
lua_newtable(L);
|
||||
int number = 1;
|
||||
for (const std::string& s : names) {
|
||||
ghoul::lua::push(L, s);
|
||||
lua_rawseti(L, -2, number);
|
||||
++number;
|
||||
/**
|
||||
* Add one or multiple exoplanet systems to the scene, as specified by the input. An input
|
||||
* string should be the name of the system host star.
|
||||
*/
|
||||
[[codegen::luawrap]] void addExoplanetSystem(
|
||||
std::variant<std::string, std::vector<std::string>> starNames)
|
||||
{
|
||||
if (std::holds_alternative<std::string>(starNames)) {
|
||||
// The user provided a single name
|
||||
std::string starName = std::get<std::string>(starNames);
|
||||
createExoplanetSystem(starName);
|
||||
}
|
||||
else {
|
||||
std::vector<std::string> sns = std::get<std::vector<std::string>>(starNames);
|
||||
for (const std::string& starName : sns) {
|
||||
createExoplanetSystem(starName);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int listAvailableExoplanetSystems(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::listAvailableExoplanetSystems");
|
||||
[[codegen::luawrap]] void removeExoplanetSystem(std::string starName) {
|
||||
using namespace openspace;
|
||||
using namespace exoplanets;
|
||||
const std::string starIdentifier = createIdentifier(std::move(starName));
|
||||
global::scriptEngine->queueScript(
|
||||
"openspace.removeSceneGraphNode('" + starIdentifier + "');",
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
}
|
||||
|
||||
[[codegen::luawrap]] std::vector<std::string> getListOfExoplanets() {
|
||||
std::vector<std::string> names = hostStarsWithSufficientData();
|
||||
return names;
|
||||
}
|
||||
|
||||
[[codegen::luawrap]] void listAvailableExoplanetSystems() {
|
||||
std::vector<std::string> names = hostStarsWithSufficientData();
|
||||
|
||||
std::string output;
|
||||
@@ -687,7 +653,8 @@ int listAvailableExoplanetSystems(lua_State* L) {
|
||||
"There is data available for the following {} exoplanet systems: {}",
|
||||
names.size(), output
|
||||
));
|
||||
return 0;
|
||||
}
|
||||
|
||||
} //namespace openspace::exoplanets::luascriptfunctions
|
||||
#include "exoplanetsmodule_lua_codegen.cpp"
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
openspace.gaia.documentation = {
|
||||
{
|
||||
Name = "addClippingBox",
|
||||
Arguments = "string, vec3, vec3",
|
||||
Arguments = { name = "String", size = "vec3", position = "vec3" },
|
||||
Documentation = "Creates a clipping box for the Gaia renderable in the first argument"
|
||||
},
|
||||
{
|
||||
Name = "removeClippingBox",
|
||||
Arguments = "",
|
||||
Arguments = {},
|
||||
Documentation = ""
|
||||
},
|
||||
{
|
||||
Name = "addClippingSphere",
|
||||
Arguments = "string, float",
|
||||
Arguments = { name = "String", radius = "Number" },
|
||||
Documentation = "Creates a clipping sphere for the Gaia renderable in the first argument"
|
||||
},
|
||||
{
|
||||
Name = "removeClippingBox",
|
||||
Arguments = "",
|
||||
Arguments = {},
|
||||
Documentation = ""
|
||||
}
|
||||
}
|
||||
@@ -104,4 +104,4 @@ openspace.gaia.removeClippingSphere = function()
|
||||
if openspace.hasSceneGraphNode(grid_identifier) then
|
||||
openspace.removeSceneGraphNode(grid_identifier)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -33,8 +33,10 @@
|
||||
#include <modules/globebrowsing/src/globerotation.h>
|
||||
#include <modules/globebrowsing/src/layer.h>
|
||||
#include <modules/globebrowsing/src/layeradjustment.h>
|
||||
#include <modules/globebrowsing/src/layergroup.h>
|
||||
#include <modules/globebrowsing/src/layermanager.h>
|
||||
#include <modules/globebrowsing/src/memoryawaretilecache.h>
|
||||
#include <modules/globebrowsing/src/renderableglobe.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/defaulttileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/imagesequencetileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/singleimagetileprovider.h>
|
||||
@@ -45,13 +47,22 @@
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/tileproviderbyindex.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/tileproviderbylevel.h>
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/globalscallbacks.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/navigationstate.h>
|
||||
#include <openspace/navigation/orbitalnavigator.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/fmt.h>
|
||||
@@ -338,141 +349,6 @@ globebrowsing::cache::MemoryAwareTileCache* GlobeBrowsingModule::tileCache() {
|
||||
return _tileCache.get();
|
||||
}
|
||||
|
||||
scripting::LuaLibrary GlobeBrowsingModule::luaLibrary() const {
|
||||
std::string listLayerGroups = layerGroupNamesList();
|
||||
|
||||
scripting::LuaLibrary res;
|
||||
res.name = "globebrowsing";
|
||||
res.functions = {
|
||||
{
|
||||
"addLayer",
|
||||
&globebrowsing::luascriptfunctions::addLayer,
|
||||
"string, string, table",
|
||||
"Adds a layer to the specified globe. The first argument specifies the "
|
||||
"name of the scene graph node of which to add the layer. The renderable "
|
||||
"of the specified scene graph node needs to be a renderable globe. "
|
||||
"The second argument is the layer group which can be any of "
|
||||
+ listLayerGroups + ". The third argument is the dictionary defining the "
|
||||
"layer."
|
||||
},
|
||||
{
|
||||
"deleteLayer",
|
||||
&globebrowsing::luascriptfunctions::deleteLayer,
|
||||
"string, string, (string, table)",
|
||||
"Removes a layer from the specified globe. The first argument specifies "
|
||||
"the name of the scene graph node of which to remove the layer. "
|
||||
"The renderable of the specified scene graph node needs to be a "
|
||||
"renderable globe. The second argument is the layer group which can be "
|
||||
"any of " + listLayerGroups + ". The third argument is either the identifier "
|
||||
"for the layer or a dictionary with the 'Identifier' key that is used instead"
|
||||
},
|
||||
{
|
||||
"getLayers",
|
||||
&globebrowsing::luascriptfunctions::getLayers,
|
||||
"string, string",
|
||||
"Returns the list of layers for the scene graph node specified in the first "
|
||||
"parameter. The second parameter specifies which layer type should be "
|
||||
"queried."
|
||||
},
|
||||
{
|
||||
"moveLayer",
|
||||
&globebrowsing::luascriptfunctions::moveLayer,
|
||||
"string, string, number, number",
|
||||
"Rearranges the order of a single layer on a globe. The first parameter"
|
||||
"is the identifier of the globe, the second parameter specifies "
|
||||
"the name of the layer group, the third parameter is the original position "
|
||||
"of the layer that should be moved and the last parameter is the new "
|
||||
"position in the list. The first position in the list has index 0, and the "
|
||||
"last position is given by the number of layers minus one. The new position "
|
||||
"may be -1 to place the layer at the top or any number bigger than the "
|
||||
"number of layers to place it at the bottom."
|
||||
},
|
||||
{
|
||||
"goToChunk",
|
||||
&globebrowsing::luascriptfunctions::goToChunk,
|
||||
"void",
|
||||
"Go to chunk with given index x, y, level"
|
||||
},
|
||||
{
|
||||
"goToGeo",
|
||||
&globebrowsing::luascriptfunctions::goToGeo,
|
||||
"[string], number, number, [number]",
|
||||
"Go to geographic coordinates of a globe. The first (optional) argument is "
|
||||
"the identifier of a scene graph node that has a RenderableGlobe attached. "
|
||||
"If no globe is passed in, the current anchor will be used. "
|
||||
"The second argument is latitude and the third is longitude (degrees). "
|
||||
"North and East are expressed as positive angles, while South and West are "
|
||||
"negative. The optional fourh argument is the altitude in meters. If no "
|
||||
"altitude is provided, the altitude will be kept as the current distance to "
|
||||
"the surface of the specified globe."
|
||||
},
|
||||
{
|
||||
// @TODO (2021-06-23, emmbr) Combine with the above function when the camera
|
||||
// paths work really well close to surfaces
|
||||
"flyToGeo",
|
||||
&globebrowsing::luascriptfunctions::flyToGeo,
|
||||
"[string], number, number, number [, bool, number]",
|
||||
"Fly the camera to geographic coordinates of a globe, using the path "
|
||||
"navigation system. The first (optional) argument is the identifier of a "
|
||||
"scene graph node with a RenderableGlobe. If no globe is passed in, the "
|
||||
"current anchor will be used. The second and third argument is latitude and "
|
||||
"longitude (degrees). The fourth argument is the altitude, in meters. The "
|
||||
"last two optional arguments are: a bool specifying whether the up vector "
|
||||
"at the target position should be set to the globe's North vector, and a "
|
||||
"duration for the motion, in seconds. Either of the two can be left out."
|
||||
},
|
||||
{
|
||||
"getLocalPositionFromGeo",
|
||||
&globebrowsing::luascriptfunctions::getLocalPositionFromGeo,
|
||||
"string, number, number, number",
|
||||
"Returns a position in the local Cartesian coordinate system of the globe "
|
||||
"identified by the first argument, that corresponds to the given geographic "
|
||||
"coordinates: latitude, longitude and altitude (in degrees and meters). In "
|
||||
"the local coordinate system, the position (0,0,0) corresponds to the "
|
||||
"globe's center."
|
||||
},
|
||||
{
|
||||
"getGeoPositionForCamera",
|
||||
&globebrowsing::luascriptfunctions::getGeoPositionForCamera,
|
||||
"void",
|
||||
"Get geographic coordinates of the camera position in latitude, "
|
||||
"longitude, and altitude (degrees and meters)."
|
||||
},
|
||||
{
|
||||
"loadWMSCapabilities",
|
||||
&globebrowsing::luascriptfunctions::loadWMSCapabilities,
|
||||
"string, string, string",
|
||||
"Loads and parses the WMS capabilities xml file from a remote server. "
|
||||
"The first argument is the name of the capabilities that can be used to "
|
||||
"later refer to the set of capabilities. The second argument is the "
|
||||
"globe for which this server is applicable. The third argument is the "
|
||||
"URL at which the capabilities file can be found."
|
||||
},
|
||||
{
|
||||
"removeWMSServer",
|
||||
&globebrowsing::luascriptfunctions::removeWMSServer,
|
||||
"string",
|
||||
"Removes the WMS server identified by the first argument from the list "
|
||||
"of available servers. The parameter corrsponds to the first argument in "
|
||||
"the loadWMSCapabilities call that was used to load the WMS server."
|
||||
},
|
||||
{
|
||||
"capabilitiesWMS",
|
||||
&globebrowsing::luascriptfunctions::capabilities,
|
||||
"string",
|
||||
"Returns an array of tables that describe the available layers that are "
|
||||
"supported by the WMS server identified by the provided name. The 'URL'"
|
||||
"component of the returned table can be used in the 'FilePath' argument "
|
||||
"for a call to the 'addLayer' function to add the value to a globe."
|
||||
}
|
||||
};
|
||||
res.scripts = {
|
||||
absPath("${MODULE_GLOBEBROWSING}/scripts/layer_support.lua")
|
||||
};
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<documentation::Documentation> GlobeBrowsingModule::documentations() const {
|
||||
return {
|
||||
globebrowsing::Layer::Documentation(),
|
||||
@@ -821,4 +697,32 @@ uint64_t GlobeBrowsingModule::wmsCacheSize() const {
|
||||
return size * 1024 * 1024;
|
||||
}
|
||||
|
||||
scripting::LuaLibrary GlobeBrowsingModule::luaLibrary() const {
|
||||
std::string listLayerGroups = layerGroupNamesList();
|
||||
|
||||
scripting::LuaLibrary res;
|
||||
res.name = "globebrowsing";
|
||||
res.functions = {
|
||||
codegen::lua::AddLayer,
|
||||
codegen::lua::DeleteLayer,
|
||||
codegen::lua::GetLayers,
|
||||
codegen::lua::MoveLayer,
|
||||
codegen::lua::GoToChunk,
|
||||
codegen::lua::GoToGeo,
|
||||
// @TODO (2021-06-23, emmbr) Combine with the above function when the camera
|
||||
// paths work really well close to surfaces
|
||||
codegen::lua::FlyToGeo,
|
||||
codegen::lua::GetLocalPositionFromGeo,
|
||||
codegen::lua::GetGeoPositionForCamera,
|
||||
codegen::lua::LoadWMSCapabilities,
|
||||
codegen::lua::RemoveWMSServer,
|
||||
codegen::lua::Capabilities
|
||||
};
|
||||
res.scripts = {
|
||||
absPath("${MODULE_GLOBEBROWSING}/scripts/layer_support.lua")
|
||||
};
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -22,89 +22,78 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/src/renderableglobe.h>
|
||||
|
||||
#include <modules/globebrowsing/src/layer.h>
|
||||
#include <modules/globebrowsing/src/layergroup.h>
|
||||
#include <modules/globebrowsing/src/layermanager.h>
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
|
||||
namespace openspace::globebrowsing::luascriptfunctions {
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* Adds a layer to the specified globe.
|
||||
* Adds a layer to the specified globe. The first argument specifies the name of the scene
|
||||
* graph node of which to add the layer. The renderable of the specified scene graph node
|
||||
* needs to be a renderable globe. The second argument is the layer group which can be any
|
||||
* of the supported layer groups. The third argument is the dictionary defining the layer.
|
||||
*/
|
||||
int addLayer(lua_State* L) {
|
||||
ZoneScoped
|
||||
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::addLayer");
|
||||
auto [globeName, layerGroupName, layerDict] =
|
||||
ghoul::lua::values<std::string, std::string, ghoul::Dictionary>(L);
|
||||
[[codegen::luawrap]] void addLayer(std::string globeName, std::string layerGroupName,
|
||||
ghoul::Dictionary layer)
|
||||
{
|
||||
using namespace openspace;
|
||||
using namespace globebrowsing;
|
||||
|
||||
// Get the node and make sure it exists
|
||||
SceneGraphNode* n = global::renderEngine->scene()->sceneGraphNode(globeName);
|
||||
if (!n) {
|
||||
return ghoul::lua::luaError(L, "Unknown globe name: " + globeName);
|
||||
throw ghoul::lua::LuaError("Unknown globe name: " + globeName);
|
||||
}
|
||||
|
||||
// Get the renderable globe
|
||||
RenderableGlobe* globe = dynamic_cast<RenderableGlobe*>(n->renderable());
|
||||
if (!globe) {
|
||||
return ghoul::lua::luaError(L, "Renderable is not a globe: " + globeName);
|
||||
throw ghoul::lua::LuaError("Renderable is not a globe: " + globeName);
|
||||
}
|
||||
|
||||
// Get the layer group
|
||||
layergroupid::GroupID groupID = ghoul::from_string<layergroupid::GroupID>(
|
||||
layerGroupName
|
||||
);
|
||||
);
|
||||
if (groupID == layergroupid::GroupID::Unknown) {
|
||||
return ghoul::lua::luaError(L, "Unknown layer group: " + layerGroupName);
|
||||
throw ghoul::lua::LuaError("Unknown layer group: " + layerGroupName);
|
||||
}
|
||||
|
||||
// Get the dictionary defining the layer
|
||||
Layer* layer = globe->layerManager().addLayer(groupID, layerDict);
|
||||
if (layer) {
|
||||
layer->initialize();
|
||||
Layer* l = globe->layerManager().addLayer(groupID, layer);
|
||||
if (l) {
|
||||
l->initialize();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a layer from the specified globe.
|
||||
* Removes a layer from the specified globe. The first argument specifies the name of the
|
||||
* scene graph node of which to remove the layer. The renderable of the specified scene
|
||||
* graph node needs to be a renderable globe. The second argument is the layer group which
|
||||
* can be any of the supported layer groups. The third argument is either the identifier
|
||||
* for the layer or a dictionary with the 'Identifier' key that is used instead.
|
||||
*/
|
||||
int deleteLayer(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::deleteLayer");
|
||||
auto [globeName, layerGroupName, layerOrName] = ghoul::lua::values<
|
||||
std::string, std::string, std::variant<std::string, ghoul::Dictionary>
|
||||
>(L);
|
||||
[[codegen::luawrap]] void deleteLayer(std::string globeName, std::string layerGroupName,
|
||||
std::variant<std::string, ghoul::Dictionary> layerOrName)
|
||||
{
|
||||
using namespace openspace;
|
||||
using namespace globebrowsing;
|
||||
|
||||
// Get the node and make sure it exists
|
||||
SceneGraphNode* n = global::renderEngine->scene()->sceneGraphNode(globeName);
|
||||
if (!n) {
|
||||
return ghoul::lua::luaError(L, "Unknown globe name: " + globeName);
|
||||
throw ghoul::lua::LuaError("Unknown globe name: " + globeName);
|
||||
}
|
||||
|
||||
// Get the renderable globe
|
||||
RenderableGlobe* globe = dynamic_cast<RenderableGlobe*>(n->renderable());
|
||||
if (!globe) {
|
||||
return ghoul::lua::luaError(L, "Renderable is not a globe: " + globeName);
|
||||
throw ghoul::lua::LuaError("Renderable is not a globe: " + globeName);
|
||||
}
|
||||
|
||||
// Get the layer group
|
||||
layergroupid::GroupID groupID = ghoul::from_string<layergroupid::GroupID>(
|
||||
layerGroupName
|
||||
);
|
||||
);
|
||||
if (groupID == layergroupid::GroupID::Unknown) {
|
||||
return ghoul::lua::luaError(L, "Unknown layer group: " + layerGroupName);
|
||||
throw ghoul::lua::LuaError("Unknown layer group: " + layerGroupName);
|
||||
}
|
||||
|
||||
std::string layerName;
|
||||
@@ -112,15 +101,9 @@ int deleteLayer(lua_State* L) {
|
||||
layerName = std::get<std::string>(layerOrName);
|
||||
}
|
||||
else {
|
||||
ghoul_assert(
|
||||
std::holds_alternative<ghoul::Dictionary>(layerOrName),
|
||||
"Missing case"
|
||||
);
|
||||
|
||||
ghoul::Dictionary d = std::get<ghoul::Dictionary>(layerOrName);
|
||||
if (!d.hasValue<std::string>("Identifier")) {
|
||||
return ghoul::lua::luaError(
|
||||
L,
|
||||
throw ghoul::lua::LuaError(
|
||||
"Table passed to deleteLayer does not contain an Identifier"
|
||||
);
|
||||
}
|
||||
@@ -128,131 +111,144 @@ int deleteLayer(lua_State* L) {
|
||||
}
|
||||
|
||||
globe->layerManager().deleteLayer(groupID, layerName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getLayers(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::getLayers");
|
||||
auto [globeIdentifier, layer] = ghoul::lua::values<std::string, std::string>(L);
|
||||
/**
|
||||
* Returns the list of layers for the scene graph node specified in the first parameter.
|
||||
* The second parameter specifies which layer type should be queried.
|
||||
*/
|
||||
[[codegen::luawrap]] std::vector<std::string> getLayers(std::string globeIdentifier,
|
||||
std::string layer)
|
||||
{
|
||||
using namespace openspace;
|
||||
using namespace globebrowsing;
|
||||
|
||||
SceneGraphNode* n = sceneGraphNode(globeIdentifier);
|
||||
if (!n) {
|
||||
return ghoul::lua::luaError(L, "Unknown globe name: " + globeIdentifier);
|
||||
throw ghoul::lua::LuaError("Unknown globe name: " + globeIdentifier);
|
||||
}
|
||||
|
||||
const RenderableGlobe* globe = dynamic_cast<const RenderableGlobe*>(n->renderable());
|
||||
if (!globe) {
|
||||
return ghoul::lua::luaError(L, "Identifier must be a RenderableGlobe");
|
||||
throw ghoul::lua::LuaError("Identifier must be a RenderableGlobe");
|
||||
}
|
||||
|
||||
globebrowsing::layergroupid::GroupID group =
|
||||
ghoul::from_string<globebrowsing::layergroupid::GroupID>(layer);
|
||||
if (group == globebrowsing::layergroupid::GroupID::Unknown) {
|
||||
return ghoul::lua::luaError(L, "Unknown layer groupd: " + layer);
|
||||
throw ghoul::lua::LuaError("Unknown layer groupd: " + layer);
|
||||
}
|
||||
|
||||
const globebrowsing::LayerGroup& lg = globe->layerManager().layerGroup(group);
|
||||
std::vector<globebrowsing::Layer*> layers = lg.layers();
|
||||
|
||||
lua_newtable(L);
|
||||
int key = 1;
|
||||
std::vector<std::string> res;
|
||||
res.reserve(layers.size());
|
||||
for (globebrowsing::Layer* l : layers) {
|
||||
ghoul::lua::push(L, key, l->identifier());
|
||||
lua_settable(L, -3);
|
||||
key++;
|
||||
res.push_back(l->identifier());
|
||||
}
|
||||
return 1;
|
||||
return res;
|
||||
}
|
||||
|
||||
int moveLayer(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 4, "lua::moveLayer");
|
||||
auto [globeIdentifier, layer, oldPosition, newPosition] =
|
||||
ghoul::lua::values<std::string, std::string, int, int>(L);
|
||||
/**
|
||||
* Rearranges the order of a single layer on a globe. The first parameter is the
|
||||
* identifier of the globe, the second parameter specifies the name of the layer group,
|
||||
* the third parameter is the original position of the layer that should be moved and the
|
||||
* last parameter is the new position in the list. The first position in the list has
|
||||
* index 0, and the last position is given by the number of layers minus one. The new
|
||||
* position may be -1 to place the layer at the top or any number bigger than the number
|
||||
* of layers to place it at the bottom.
|
||||
*/
|
||||
[[codegen::luawrap]] void moveLayer(std::string globeIdentifier, std::string layer,
|
||||
int oldPosition, int newPosition)
|
||||
{
|
||||
using namespace openspace;
|
||||
using namespace globebrowsing;
|
||||
|
||||
if (oldPosition == newPosition) {
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
SceneGraphNode* n = sceneGraphNode(globeIdentifier);
|
||||
if (!n) {
|
||||
return ghoul::lua::luaError(L, "Unknown globe name: " + globeIdentifier);
|
||||
throw ghoul::lua::LuaError("Unknown globe name: " + globeIdentifier);
|
||||
}
|
||||
|
||||
RenderableGlobe* globe = dynamic_cast<RenderableGlobe*>(n->renderable());
|
||||
if (!globe) {
|
||||
return ghoul::lua::luaError(L, "Identifier must be a RenderableGlobe");
|
||||
throw ghoul::lua::LuaError("Identifier must be a RenderableGlobe");
|
||||
}
|
||||
|
||||
globebrowsing::layergroupid::GroupID group =
|
||||
ghoul::from_string<globebrowsing::layergroupid::GroupID>(layer);
|
||||
if (group == globebrowsing::layergroupid::GroupID::Unknown) {
|
||||
return ghoul::lua::luaError(L, "Unknown layer groupd: " + layer);
|
||||
throw ghoul::lua::LuaError("Unknown layer groupd: " + layer);
|
||||
}
|
||||
|
||||
globebrowsing::LayerGroup& lg = globe->layerManager().layerGroup(group);
|
||||
lg.moveLayer(oldPosition, newPosition);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int goToChunk(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 4, "lua::goToChunk");
|
||||
auto [identifier, x, y, level] = ghoul::lua::values<std::string, int, int, int>(L);
|
||||
/**
|
||||
* Go to the chunk on a globe with given index x, y, level.
|
||||
*/
|
||||
[[codegen::luawrap]] void goToChunk(std::string identifier, int x, int y, int level) {
|
||||
using namespace openspace;
|
||||
using namespace globebrowsing;
|
||||
|
||||
SceneGraphNode* n = sceneGraphNode(identifier);
|
||||
if (!n) {
|
||||
return ghoul::lua::luaError(L, "Unknown globe name: " + identifier);
|
||||
throw ghoul::lua::LuaError("Unknown globe name: " + identifier);
|
||||
}
|
||||
|
||||
const RenderableGlobe* globe = dynamic_cast<const RenderableGlobe*>(n->renderable());
|
||||
if (!globe) {
|
||||
return ghoul::lua::luaError(L, "Identifier must be a RenderableGlobe");
|
||||
throw ghoul::lua::LuaError("Identifier must be a RenderableGlobe");
|
||||
}
|
||||
|
||||
global::moduleEngine->module<GlobeBrowsingModule>()->goToChunk(*globe, x, y, level);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int goToGeo(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 2, 4 }, "lua::goToGeo");
|
||||
/**
|
||||
* Go to geographic coordinates of a globe. The first (optional) argument is the
|
||||
* identifier of a scene graph node that has a RenderableGlobe attached. If no globe is
|
||||
* passed in, the current anchor will be used. The second argument is latitude and the
|
||||
* third is longitude (degrees). North and East are expressed as positive angles, while
|
||||
* South and West are negative. The optional fourh argument is the altitude in meters. If
|
||||
* no altitude is provided, the altitude will be kept as the current distance to the
|
||||
* surface of the specified globe.
|
||||
*/
|
||||
[[codegen::luawrap]] void goToGeo(std::optional<std::string> globe, double latitude,
|
||||
double longitude, std::optional<double> altitude)
|
||||
{
|
||||
using namespace openspace;
|
||||
using namespace globebrowsing;
|
||||
|
||||
// Check if the user provided a Scene graph node identifier as the first argument.
|
||||
// lua_isstring returns true for both numbers and strings, so better use !lua_isnumber
|
||||
const bool providedGlobeIdentifier = !lua_isnumber(L, 1);
|
||||
const SceneGraphNode* n;
|
||||
if (providedGlobeIdentifier) {
|
||||
const std::string& globeIdentifier = ghoul::lua::value<std::string>(L);
|
||||
n = sceneGraphNode(globeIdentifier);
|
||||
if (globe.has_value()) {
|
||||
n = sceneGraphNode(*globe);
|
||||
if (!n) {
|
||||
return ghoul::lua::luaError(L, "Unknown globe name: " + globeIdentifier);
|
||||
throw ghoul::lua::LuaError("Unknown globe name: " + *globe);
|
||||
}
|
||||
}
|
||||
else {
|
||||
n = global::navigationHandler->orbitalNavigator().anchorNode();
|
||||
if (!n) {
|
||||
return ghoul::lua::luaError(L, "No anchor node is set.");
|
||||
throw ghoul::lua::LuaError("No anchor node is set.");
|
||||
}
|
||||
}
|
||||
|
||||
auto [latitude, longitude, altitude] =
|
||||
ghoul::lua::values<double, double, std::optional<double>>(L);
|
||||
|
||||
const RenderableGlobe* globe = dynamic_cast<const RenderableGlobe*>(n->renderable());
|
||||
if (!globe) {
|
||||
if (providedGlobeIdentifier) {
|
||||
return ghoul::lua::luaError(L, "Identifier must be a RenderableGlobe");
|
||||
}
|
||||
else {
|
||||
return ghoul::lua::luaError(
|
||||
L,
|
||||
"Current anchor node is not a RenderableGlobe. Either change the anchor "
|
||||
"to a globe, or specify a globe identifier as the first argument"
|
||||
);
|
||||
}
|
||||
const RenderableGlobe* gl = dynamic_cast<const RenderableGlobe*>(n->renderable());
|
||||
if (!gl) {
|
||||
throw ghoul::lua::LuaError(
|
||||
"Current anchor node is not a RenderableGlobe. Either change the anchor "
|
||||
"to a globe, or specify a globe identifier as the first argument"
|
||||
);
|
||||
}
|
||||
|
||||
if (altitude.has_value()) {
|
||||
global::moduleEngine->module<GlobeBrowsingModule>()->goToGeo(
|
||||
*globe,
|
||||
*gl,
|
||||
latitude,
|
||||
longitude,
|
||||
*altitude
|
||||
@@ -260,63 +256,52 @@ int goToGeo(lua_State* L) {
|
||||
}
|
||||
else {
|
||||
global::moduleEngine->module<GlobeBrowsingModule>()->goToGeo(
|
||||
*globe,
|
||||
*gl,
|
||||
latitude,
|
||||
longitude
|
||||
);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flyToGeo(lua_State* L) {
|
||||
int nArguments = ghoul::lua::checkArgumentsAndThrow(L, { 3, 6 }, "lua::flyToGeo");
|
||||
|
||||
// Check if the user provided a Scene graph node identifier as the first argument.
|
||||
// lua_isstring returns true for both numbers and strings, so better use !lua_isnumber
|
||||
const bool providedGlobeIdentifier = !lua_isnumber(L, 1);
|
||||
const int parameterOffset = providedGlobeIdentifier ? 1 : 0;
|
||||
/**
|
||||
* Fly the camera to geographic coordinates of a globe, using the path navigation system.
|
||||
* The first (optional) argument is the identifier of a scene graph node with a
|
||||
* RenderableGlobe. If no globe is passed in, the current anchor will be used. The second
|
||||
* and third argument is latitude and longitude (degrees). The fourth argument is the
|
||||
* altitude, in meters. The last two optional arguments are: a bool specifying whether the
|
||||
* up vector at the target position should be set to the globe's North vector, and a
|
||||
* duration for the motion, in seconds. Either of the two can be left out.
|
||||
*/
|
||||
[[codegen::luawrap]] void flyToGeo(std::optional<std::string> globe, double latitude,
|
||||
double longitude, double altitude,
|
||||
std::optional<double> duration,
|
||||
std::optional<bool> shouldUseUpVector)
|
||||
{
|
||||
using namespace openspace;
|
||||
using namespace globebrowsing;
|
||||
|
||||
const SceneGraphNode* n;
|
||||
if (providedGlobeIdentifier) {
|
||||
const std::string& globeIdentifier =
|
||||
ghoul::lua::value<std::string>(L, 1, ghoul::lua::PopValue::No);
|
||||
n = sceneGraphNode(globeIdentifier);
|
||||
if (globe.has_value()) {
|
||||
n = sceneGraphNode(*globe);
|
||||
if (!n) {
|
||||
return ghoul::lua::luaError(L, "Unknown globe name: " + globeIdentifier);
|
||||
throw ghoul::lua::LuaError("Unknown globe name: " + *globe);
|
||||
}
|
||||
}
|
||||
else {
|
||||
n = global::navigationHandler->orbitalNavigator().anchorNode();
|
||||
if (!n) {
|
||||
return ghoul::lua::luaError(L, "No anchor node is set.");
|
||||
throw ghoul::lua::LuaError("No anchor node is set.");
|
||||
}
|
||||
}
|
||||
|
||||
const RenderableGlobe* globe = dynamic_cast<const RenderableGlobe*>(n->renderable());
|
||||
if (!globe) {
|
||||
if (providedGlobeIdentifier) {
|
||||
return ghoul::lua::luaError(L, "Identifier must be a RenderableGlobe");
|
||||
}
|
||||
else {
|
||||
return ghoul::lua::luaError(L,
|
||||
"Current anchor node is not a RenderableGlobe. "
|
||||
"Either change the anchor to a globe, or specify a globe identifier "
|
||||
"as the first argument"
|
||||
);
|
||||
}
|
||||
const RenderableGlobe* gl = dynamic_cast<const RenderableGlobe*>(n->renderable());
|
||||
if (!gl) {
|
||||
throw ghoul::lua::LuaError("Current anchor node is not a RenderableGlobe");
|
||||
}
|
||||
|
||||
const double latitude =
|
||||
ghoul::lua::value<double>(L, parameterOffset + 1, ghoul::lua::PopValue::No);
|
||||
const double longitude =
|
||||
ghoul::lua::value<double>(L, parameterOffset + 2, ghoul::lua::PopValue::No);
|
||||
const double altitude =
|
||||
ghoul::lua::value<double>(L, parameterOffset + 3, ghoul::lua::PopValue::No);
|
||||
|
||||
// Compute the relative position based on the input values
|
||||
auto module = global::moduleEngine->module<GlobeBrowsingModule>();
|
||||
const glm::dvec3 positionModelCoords = module->cartesianCoordinatesFromGeo(
|
||||
*globe,
|
||||
*gl,
|
||||
latitude,
|
||||
longitude,
|
||||
altitude
|
||||
@@ -324,12 +309,12 @@ int flyToGeo(lua_State* L) {
|
||||
|
||||
const glm::dvec3 currentPosW = global::navigationHandler->camera()->positionVec3();
|
||||
const glm::dvec3 currentPosModelCoords =
|
||||
glm::inverse(globe->modelTransform()) * glm::dvec4(currentPosW, 1.0);
|
||||
glm::inverse(gl->modelTransform()) * glm::dvec4(currentPosW, 1.0);
|
||||
|
||||
constexpr const double LengthEpsilon = 10.0; // meters
|
||||
if (glm::distance(currentPosModelCoords, positionModelCoords) < LengthEpsilon) {
|
||||
LINFOC("GlobeBrowsing", "flyToGeo: Already at the requested position");
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
ghoul::Dictionary instruction;
|
||||
@@ -338,83 +323,63 @@ int flyToGeo(lua_State* L) {
|
||||
instruction.setValue("Position", positionModelCoords);
|
||||
instruction.setValue("PathType", std::string("ZoomOutOverview"));
|
||||
|
||||
// Handle the two optional arguments: duration and use target's up direction argument
|
||||
// The user can either provide both, or one of them
|
||||
if (nArguments >= parameterOffset + 4) {
|
||||
const int firstLocation = parameterOffset + 4;
|
||||
const bool firstIsNumber = (lua_isnumber(L, firstLocation) != 0);
|
||||
const bool firstIsBool = (lua_isboolean(L, firstLocation) != 0);
|
||||
|
||||
if (!(firstIsNumber || firstIsBool)) {
|
||||
const char* msg = lua_pushfstring(
|
||||
L,
|
||||
"%s or %s expected, got %s",
|
||||
lua_typename(L, LUA_TNUMBER),
|
||||
lua_typename(L, LUA_TBOOLEAN),
|
||||
luaL_typename(L, -1)
|
||||
);
|
||||
return ghoul::lua::luaError(
|
||||
L, fmt::format("bad argument #{} ({})", firstLocation, msg)
|
||||
);
|
||||
if (duration.has_value()) {
|
||||
constexpr const double Epsilon = 1e-5;
|
||||
if (*duration <= Epsilon) {
|
||||
throw ghoul::lua::LuaError("Duration must be larger than zero");
|
||||
}
|
||||
instruction.setValue("Duration", *duration);
|
||||
}
|
||||
|
||||
int location = firstLocation;
|
||||
if (firstIsBool) {
|
||||
const bool useUpFromTarget = (lua_toboolean(L, location) == 1);
|
||||
instruction.setValue("UseTargetUpDirection", useUpFromTarget);
|
||||
if (shouldUseUpVector.has_value()) {
|
||||
instruction.setValue("UseTargetUpDirection", *shouldUseUpVector);
|
||||
|
||||
if (nArguments > location) {
|
||||
location++;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstIsNumber || nArguments > firstLocation) {
|
||||
double duration =
|
||||
ghoul::lua::value<double>(L, location, ghoul::lua::PopValue::No);
|
||||
constexpr const double Epsilon = 1e-5;
|
||||
if (duration <= Epsilon) {
|
||||
return ghoul::lua::luaError(L, "Duration must be larger than zero");
|
||||
}
|
||||
instruction.setValue("Duration", duration);
|
||||
}
|
||||
}
|
||||
|
||||
global::navigationHandler->pathNavigator().createPath(instruction);
|
||||
global::navigationHandler->pathNavigator().startPath();
|
||||
|
||||
lua_settop(L, 0);
|
||||
|
||||
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getLocalPositionFromGeo(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 4, "lua::getLocalPositionFromGeo");
|
||||
auto [globeIdentifier, latitude, longitude, altitude] =
|
||||
ghoul::lua::values<std::string, double, double, double>(L);
|
||||
|
||||
/**
|
||||
* Returns a position in the local Cartesian coordinate system of the globe identified by
|
||||
* the first argument, that corresponds to the given geographic coordinates: latitude,
|
||||
* longitude and altitude (in degrees and meters). In the local coordinate system, the
|
||||
* position (0,0,0) corresponds to the globe's center.
|
||||
*/
|
||||
[[codegen::luawrap]]
|
||||
std::tuple<double, double, double>
|
||||
getLocalPositionFromGeo(std::string globeIdentifier, double latitude, double longitude,
|
||||
double altitude)
|
||||
{
|
||||
using namespace openspace;
|
||||
using namespace globebrowsing;
|
||||
|
||||
SceneGraphNode* n = sceneGraphNode(globeIdentifier);
|
||||
if (!n) {
|
||||
return ghoul::lua::luaError(L, "Unknown globe identifier: " + globeIdentifier);
|
||||
throw ghoul::lua::LuaError("Unknown globe identifier: " + globeIdentifier);
|
||||
}
|
||||
const RenderableGlobe* globe = dynamic_cast<const RenderableGlobe*>(n->renderable());
|
||||
if (!globe) {
|
||||
return ghoul::lua::luaError(L, "Identifier must be a RenderableGlobe");
|
||||
throw ghoul::lua::LuaError("Identifier must be a RenderableGlobe");
|
||||
}
|
||||
|
||||
GlobeBrowsingModule& mod = *(global::moduleEngine->module<GlobeBrowsingModule>());
|
||||
glm::vec3 p = mod.cartesianCoordinatesFromGeo(*globe, latitude, longitude, altitude);
|
||||
ghoul::lua::push(L, p.x, p.y, p.z);
|
||||
return 3;
|
||||
return { p.x, p.y, p.z };
|
||||
}
|
||||
|
||||
int getGeoPositionForCamera(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::getGeoPositionForCamera");
|
||||
/**
|
||||
* Get geographic coordinates of the camera position in latitude, longitude, and altitude
|
||||
* (degrees and meters).
|
||||
*/
|
||||
[[codegen::luawrap]] std::tuple<double, double, double> getGeoPositionForCamera() {
|
||||
using namespace openspace;
|
||||
using namespace globebrowsing;
|
||||
|
||||
GlobeBrowsingModule* module = global::moduleEngine->module<GlobeBrowsingModule>();
|
||||
const RenderableGlobe* globe = module->castFocusNodeRenderableToGlobe();
|
||||
if (!globe) {
|
||||
return ghoul::lua::luaError(L, "Focus node must be a RenderableGlobe");
|
||||
throw ghoul::lua::LuaError("Focus node must be a RenderableGlobe");
|
||||
}
|
||||
|
||||
const glm::dvec3 cameraPosition = global::navigationHandler->camera()->positionVec3();
|
||||
@@ -430,53 +395,66 @@ int getGeoPositionForCamera(lua_State* L) {
|
||||
const Geodetic2 geo2 = globe->ellipsoid().cartesianToGeodetic2(
|
||||
posHandle.centerToReferenceSurface
|
||||
);
|
||||
const double altitude = glm::length(cameraPositionModelSpace -
|
||||
posHandle.centerToReferenceSurface);
|
||||
const double altitude = glm::length(
|
||||
cameraPositionModelSpace - posHandle.centerToReferenceSurface
|
||||
);
|
||||
|
||||
ghoul::lua::push(L, glm::degrees(geo2.lat), glm::degrees(geo2.lon), altitude);
|
||||
return 3;
|
||||
return { glm::degrees(geo2.lat), glm::degrees(geo2.lon), altitude };
|
||||
}
|
||||
|
||||
int loadWMSCapabilities(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::loadWMSCapabilities");
|
||||
auto [name, globe, url] =
|
||||
ghoul::lua::values<std::string, std::string, std::string>(L);
|
||||
|
||||
/**
|
||||
* Loads and parses the WMS capabilities xml file from a remote server. The first argument
|
||||
* is the name of the capabilities that can be used to later refer to the set of
|
||||
* capabilities. The second argument is the globe for which this server is applicable. The
|
||||
* third argument is the URL at which the capabilities file can be found.
|
||||
*/
|
||||
[[codegen::luawrap]] void loadWMSCapabilities(std::string name, std::string globe,
|
||||
std::string url)
|
||||
{
|
||||
using namespace openspace;
|
||||
using namespace globebrowsing;
|
||||
global::moduleEngine->module<GlobeBrowsingModule>()->loadWMSCapabilities(
|
||||
std::move(name),
|
||||
std::move(globe),
|
||||
std::move(url)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int removeWMSServer(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::removeWMSServer");
|
||||
const std::string name = ghoul::lua::value<std::string>(L);
|
||||
|
||||
/**
|
||||
* Removes the WMS server identified by the first argument from the list of available
|
||||
* servers. The parameter corrsponds to the first argument in the loadWMSCapabilities call
|
||||
* that was used to load the WMS server.
|
||||
*/
|
||||
[[codegen::luawrap]] void removeWMSServer(std::string name) {
|
||||
using namespace openspace;
|
||||
using namespace globebrowsing;
|
||||
global::moduleEngine->module<GlobeBrowsingModule>()->removeWMSServer(name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int capabilities(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::capabilities");
|
||||
const std::string name = ghoul::lua::value<std::string>(L);
|
||||
/**
|
||||
* Returns an array of tables that describe the available layers that are supported by the
|
||||
* WMS server identified by the provided name. The 'URL' component of the returned table
|
||||
* can be used in the 'FilePath' argument for a call to the 'addLayer' function to add the
|
||||
* value to a globe.
|
||||
*/
|
||||
[[codegen::luawrap]] std::vector<ghoul::Dictionary> capabilities(std::string name) {
|
||||
using namespace openspace;
|
||||
using namespace globebrowsing;
|
||||
|
||||
GlobeBrowsingModule::Capabilities cap =
|
||||
global::moduleEngine->module<GlobeBrowsingModule>()->capabilities(name);
|
||||
|
||||
lua_newtable(L);
|
||||
std::vector<ghoul::Dictionary> res;
|
||||
res.reserve(cap.size());
|
||||
for (size_t i = 0; i < cap.size(); ++i) {
|
||||
const GlobeBrowsingModule::Layer& l = cap[i];
|
||||
|
||||
lua_newtable(L);
|
||||
ghoul::lua::push(L, "Name", l.name);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "URL", l.url);
|
||||
lua_settable(L, -3);
|
||||
lua_rawseti(L, -2, i + 1);
|
||||
ghoul::Dictionary c;
|
||||
c.setValue("Name", cap[i].name);
|
||||
c.setValue("URL", cap[i].url);
|
||||
res.push_back(c);
|
||||
}
|
||||
return 1;
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing::luascriptfunctions
|
||||
#include "globebrowsingmodule_lua_codegen.cpp"
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
openspace.globebrowsing.documentation = {
|
||||
{
|
||||
Name = "createTemporalGibsGdalXml",
|
||||
Arguments = "string, string, string",
|
||||
Arguments = { layerName = "String", resolution = "String", format = "String" },
|
||||
Documentation = [[
|
||||
Creates an XML configuration for a temporal GIBS dataset to be used in
|
||||
a TemporalTileprovider
|
||||
@@ -9,7 +9,7 @@ openspace.globebrowsing.documentation = {
|
||||
},
|
||||
{
|
||||
Name = "createGibsGdalXml",
|
||||
Arguments = "string, string, string, string",
|
||||
Arguments = { layerName = "String", date = "String", resolution = "String", format = "String" },
|
||||
Documentation =
|
||||
"Creates an XML configuration for a GIBS dataset." ..
|
||||
"Arguments are: layerName, date, resolution, format." ..
|
||||
@@ -32,7 +32,7 @@ openspace.globebrowsing.documentation = {
|
||||
},
|
||||
{
|
||||
Name = "addGibsLayer",
|
||||
Arguments = "string, string, string, string, string",
|
||||
Arguments = { layer = "String", resolution = "String", format = "String", startDate = "String", endDate = "String" },
|
||||
Documentation = "Adds a new layer from NASA GIBS to the Earth globe. Arguments " ..
|
||||
"are: imagery layer name, imagery resolution, start date, end date, format. " ..
|
||||
"For all specifications, see " ..
|
||||
@@ -42,7 +42,7 @@ openspace.globebrowsing.documentation = {
|
||||
},
|
||||
{
|
||||
Name = "parseInfoFile",
|
||||
Arguments = "string",
|
||||
Arguments = { file = "String" },
|
||||
Documentation =
|
||||
"Parses the passed info file and return the table with the information " ..
|
||||
"provided in the info file. The return table contains the optional keys: " ..
|
||||
@@ -53,7 +53,7 @@ openspace.globebrowsing.documentation = {
|
||||
},
|
||||
{
|
||||
Name = "addBlendingLayersFromDirectory",
|
||||
Arguments = "string, string",
|
||||
Arguments = { directory = "String", nodeName = "String" },
|
||||
Documentation =
|
||||
"Retrieves all info files recursively in the directory passed as the first " ..
|
||||
"argument to this function. The color and height tables retrieved from these " ..
|
||||
@@ -63,7 +63,7 @@ openspace.globebrowsing.documentation = {
|
||||
},
|
||||
{
|
||||
Name = "addFocusNodesFromDirectory",
|
||||
Arguments = "string, string",
|
||||
Arguments = { directory = "String", nodeName = "String" },
|
||||
Documentation =
|
||||
"Retrieves all info files recursively in the directory passed as the first " ..
|
||||
"argument to this function. The name and location retrieved from these info " ..
|
||||
@@ -73,7 +73,7 @@ openspace.globebrowsing.documentation = {
|
||||
},
|
||||
{
|
||||
Name = "addFocusNodeFromLatLong",
|
||||
Arguments = "string, string, number, number, number",
|
||||
Arguments = { name = "String", globeIdentifier = "String", latitude = "Number", longitude = "Number", altitude = "Number" },
|
||||
Documentation =
|
||||
"Creates a new SceneGraphNode that can be used as focus node. " ..
|
||||
"Usage: openspace.globebrowsing.addFocusNodeFromLatLong(" ..
|
||||
@@ -81,7 +81,7 @@ openspace.globebrowsing.documentation = {
|
||||
},
|
||||
{
|
||||
Name = "loadWMSServersFromFile",
|
||||
Arguments = "string",
|
||||
Arguments = { filePath = "String" },
|
||||
Documentation =
|
||||
"Loads all WMS servers from the provided file and passes them to the " ..
|
||||
"'openspace.globebrowsing.loadWMSCapabilities' file."
|
||||
|
||||
@@ -186,6 +186,7 @@ TileDepthTransform SpoutImageProvider::depthTransform() {
|
||||
}
|
||||
|
||||
void SpoutImageProvider::update() {
|
||||
#ifdef OPENSPACE_HAS_SPOUT
|
||||
if (!spoutUpdate) {
|
||||
return;
|
||||
}
|
||||
@@ -198,10 +199,13 @@ void SpoutImageProvider::update() {
|
||||
}
|
||||
|
||||
spoutReceiver->updateReceiver();
|
||||
#endif // OPENSPACE_HAS_SPOUT
|
||||
}
|
||||
|
||||
void SpoutImageProvider::reset() {
|
||||
#ifdef OPENSPACE_HAS_SPOUT
|
||||
spoutReceiver->updateReceiver();
|
||||
#endif // OPENSPACE_HAS_SPOUT
|
||||
}
|
||||
|
||||
int SpoutImageProvider::minLevel() {
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#include <modules/kameleon/include/kameleonwrapper.h>
|
||||
#include <openspace/json.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/rendering/screenspacerenderable.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
@@ -753,54 +755,14 @@ scripting::LuaLibrary IswaManager::luaLibrary() {
|
||||
return {
|
||||
"iswa",
|
||||
{
|
||||
{
|
||||
"addCygnet",
|
||||
&luascriptfunctions::iswa_addCygnet,
|
||||
"int, string, string",
|
||||
"Adds a IswaCygnet",
|
||||
},
|
||||
{
|
||||
"addScreenSpaceCygnet",
|
||||
&luascriptfunctions::iswa_addScreenSpaceCygnet,
|
||||
"int, string, string",
|
||||
"Adds a Screen Space Cygnets",
|
||||
},
|
||||
{
|
||||
"addKameleonPlanes",
|
||||
&luascriptfunctions::iswa_addKameleonPlanes,
|
||||
"string, int",
|
||||
"Adds KameleonPlanes from cdf file.",
|
||||
},
|
||||
{
|
||||
"addCdfFiles",
|
||||
&luascriptfunctions::iswa_addCdfFiles,
|
||||
"string",
|
||||
"Adds a cdf files to choose from.",
|
||||
},
|
||||
{
|
||||
"removeCygnet",
|
||||
&luascriptfunctions::iswa_removeCygnet,
|
||||
"string",
|
||||
"Remove a Cygnets",
|
||||
},
|
||||
{
|
||||
"removeScreenSpaceCygnet",
|
||||
&luascriptfunctions::iswa_removeScrenSpaceCygnet,
|
||||
"int",
|
||||
"Remove a Screen Space Cygnets",
|
||||
},
|
||||
{
|
||||
"removeGroup",
|
||||
&luascriptfunctions::iswa_removeGroup,
|
||||
"int",
|
||||
"Remove a group of Cygnets",
|
||||
},
|
||||
{
|
||||
"setBaseUrl",
|
||||
&luascriptfunctions::iswa_setBaseUrl,
|
||||
"string",
|
||||
"sets the base url",
|
||||
}
|
||||
codegen::lua::AddCygnet,
|
||||
codegen::lua::AddScreenSpaceCygnet,
|
||||
codegen::lua::RemoveCygnet,
|
||||
codegen::lua::RemoveScreenSpaceCygnet,
|
||||
codegen::lua::RemoveGroup,
|
||||
codegen::lua::AddCdfFiles,
|
||||
codegen::lua::AddKameleonPlanes,
|
||||
codegen::lua::SetBaseUrl
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,63 +22,26 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/rendering/screenspacerenderable.h>
|
||||
namespace {
|
||||
|
||||
namespace openspace::luascriptfunctions {
|
||||
|
||||
int iswa_addCygnet(lua_State* L) {
|
||||
int nArguments = lua_gettop(L);
|
||||
|
||||
int id = -1;
|
||||
std::string type = "Texture";
|
||||
std::string group = "";
|
||||
|
||||
if (nArguments > 0) {
|
||||
id = static_cast<int>(lua_tonumber(L, 1));
|
||||
}
|
||||
|
||||
if (nArguments > 1) {
|
||||
type = luaL_checkstring(L, 2);
|
||||
}
|
||||
|
||||
if (nArguments > 2) {
|
||||
group = luaL_checkstring(L, 3);
|
||||
}
|
||||
|
||||
IswaManager::ref().addIswaCygnet(id, type, group);
|
||||
|
||||
return 0;
|
||||
// Adds a IswaCygnet.
|
||||
[[codegen::luawrap]] void addCygnet(int id = -1, std::string type = "Texture",
|
||||
std::string group = "")
|
||||
{
|
||||
openspace::IswaManager::ref().addIswaCygnet(id, type, group);
|
||||
}
|
||||
|
||||
int iswa_addScreenSpaceCygnet(lua_State* L) {
|
||||
static const std::string _loggerCat = "addScreenSpaceCygnet";
|
||||
using ghoul::lua::errorLocation;
|
||||
|
||||
int nArguments = lua_gettop(L);
|
||||
if (nArguments != 1) {
|
||||
return ghoul::lua::luaError(L, fmt::format(
|
||||
"Expected {} argumemts, got {}", 1, nArguments
|
||||
));
|
||||
}
|
||||
|
||||
ghoul::Dictionary d;
|
||||
try {
|
||||
ghoul::lua::luaDictionaryFromState(L, d);
|
||||
}
|
||||
catch (const ghoul::lua::LuaFormatException& e) {
|
||||
LERROR(e.what());
|
||||
return 0;
|
||||
}
|
||||
// Adds a Screen Space Cygnets.
|
||||
[[codegen::luawrap]] void addScreenSpaceCygnet(ghoul::Dictionary d) {
|
||||
using namespace openspace;
|
||||
|
||||
int id = static_cast<int>(d.value<double>("CygnetId"));
|
||||
|
||||
std::map<int, std::shared_ptr<CygnetInfo>> cygnetInformation =
|
||||
IswaManager::ref().cygnetInformation();
|
||||
if (cygnetInformation.find(id) == cygnetInformation.end()) {
|
||||
LWARNING("Could not find Cygnet with id = " + std::to_string(id));
|
||||
return 0;
|
||||
throw ghoul::lua::LuaError(
|
||||
"Could not find Cygnet with id = " + std::to_string(id)
|
||||
);
|
||||
}
|
||||
|
||||
std::shared_ptr<CygnetInfo> info = cygnetInformation[id];
|
||||
@@ -87,8 +50,9 @@ int iswa_addScreenSpaceCygnet(lua_State* L) {
|
||||
info->selected = true;
|
||||
|
||||
if (global::renderEngine->screenSpaceRenderable(name)) {
|
||||
LERROR("A cygnet with the name \"" + name +"\" already exist");
|
||||
return 0;
|
||||
throw ghoul::lua::LuaError(fmt::format(
|
||||
"A cygnet with the name \"{}\" already exist", name
|
||||
));
|
||||
}
|
||||
else {
|
||||
d.setValue("Name", name);
|
||||
@@ -100,99 +64,68 @@ int iswa_addScreenSpaceCygnet(lua_State* L) {
|
||||
);
|
||||
global::renderEngine->addScreenSpaceRenderable(std::move(s));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// int iswa_addKameleonPlane(lua_State* L){
|
||||
// int nArguments = lua_gettop(L);
|
||||
|
||||
// std::string kwPath = "";
|
||||
// std::string type = "x";
|
||||
// std::string group = "";
|
||||
|
||||
// if (nArguments > 0) {
|
||||
// kwPath = luaL_checkstring(L, 1);
|
||||
// }
|
||||
|
||||
// if (nArguments > 1) {
|
||||
// type = luaL_checkstring(L, 2);
|
||||
// }
|
||||
|
||||
// if (nArguments > 2) {
|
||||
// group = luaL_checkstring(L, 3);
|
||||
// }
|
||||
|
||||
// IswaManager::ref().createKameleonPlane(kwPath, type, group);
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
int iswa_removeCygnet(lua_State* L) {
|
||||
std::string name = luaL_checkstring(L, -1);
|
||||
// Remove a Cygnets.
|
||||
[[codegen::luawrap]] void removeCygnet(std::string name) {
|
||||
using namespace openspace;
|
||||
global::scriptEngine->queueScript(
|
||||
"openspace.removeSceneGraphNode('" + name + "')",
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
// IswaManager::ref().deleteIswaCygnet(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iswa_removeScrenSpaceCygnet(lua_State* L) {
|
||||
static const std::string _loggerCat = "removeScreenSpaceCygnet";
|
||||
|
||||
int id = static_cast<int>(lua_tonumber(L, 1));
|
||||
|
||||
// Remove a Screen Space Cygnets.
|
||||
[[codegen::luawrap]] void removeScreenSpaceCygnet(int id) {
|
||||
using namespace openspace;
|
||||
|
||||
std::map<int, std::shared_ptr<CygnetInfo>> cygnetInformation =
|
||||
IswaManager::ref().cygnetInformation();
|
||||
if (cygnetInformation.find(id) == cygnetInformation.end()) {
|
||||
LWARNING("Could not find Cygnet with id = " + std::to_string(id));
|
||||
return 0;
|
||||
throw ghoul::lua::LuaError(
|
||||
"Could not find Cygnet with id = " + std::to_string(id)
|
||||
);
|
||||
}
|
||||
|
||||
std::shared_ptr<CygnetInfo> info = cygnetInformation[id];
|
||||
info->selected = false;
|
||||
|
||||
std::string script =
|
||||
"openspace.unregisterScreenSpaceRenderable('" +
|
||||
cygnetInformation[id]->name + "');";
|
||||
std::string script = fmt::format(
|
||||
"openspace.unregisterScreenSpaceRenderable('{}');", cygnetInformation[id]->name
|
||||
);
|
||||
|
||||
global::scriptEngine->queueScript(
|
||||
script,
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iswa_removeGroup(lua_State* L) {
|
||||
std::string name = luaL_checkstring(L, -1);
|
||||
// IswaManager::ref().unregisterGroup(id);
|
||||
|
||||
// Remove a group of Cygnets.
|
||||
[[codegen::luawrap]] void removeGroup(std::string name) {
|
||||
using namespace openspace;
|
||||
|
||||
std::map<std::string, std::shared_ptr<IswaBaseGroup>> groups =
|
||||
IswaManager::ref().groups();
|
||||
if (groups.find(name) != groups.end()) {
|
||||
groups[name]->clearGroup();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iswa_addCdfFiles(lua_State* L) {
|
||||
std::string path = luaL_checkstring(L, 1);
|
||||
IswaManager::ref().addCdfFiles(path);
|
||||
|
||||
return 0;
|
||||
// Adds a cdf files to choose from.
|
||||
[[codegen::luawrap]] void addCdfFiles(std::string path) {
|
||||
openspace::IswaManager::ref().addCdfFiles(path);
|
||||
}
|
||||
|
||||
int iswa_addKameleonPlanes(lua_State* L) {
|
||||
std::string group = luaL_checkstring(L, 1);
|
||||
int pos = static_cast<int>(lua_tonumber(L, 2));
|
||||
IswaManager::ref().addKameleonCdf(group, pos);
|
||||
return 0;
|
||||
// Adds KameleonPlanes from cdf file.
|
||||
[[codegen::luawrap]] void addKameleonPlanes(std::string group, int pos) {
|
||||
openspace::IswaManager::ref().addKameleonCdf(group, pos);
|
||||
}
|
||||
|
||||
int iswa_setBaseUrl(lua_State* L) {
|
||||
std::string url = luaL_checkstring(L, 1);
|
||||
IswaManager::ref().setBaseUrl(url);
|
||||
return 0;
|
||||
// Sets the base url.
|
||||
[[codegen::luawrap]] void setBaseUrl(std::string url) {
|
||||
openspace::IswaManager::ref().setBaseUrl(url);
|
||||
}
|
||||
|
||||
} // namespace openspace::luascriptfunctions
|
||||
#include "iswamanager_lua_codegen.cpp"
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -53,7 +53,6 @@ public:
|
||||
float opacity() const;
|
||||
double animationSpeed() const;
|
||||
double stopAnimationThreshold() const;
|
||||
double smallestFov() const;
|
||||
|
||||
void setDimensions(glm::vec2 dimensions);
|
||||
void setColor(glm::ivec3 color);
|
||||
@@ -69,7 +68,6 @@ private:
|
||||
properties::FloatProperty _crossHairSize;
|
||||
properties::FloatProperty _showRectangleThreshold;
|
||||
properties::FloatProperty _lineWidth;
|
||||
properties::DoubleProperty _smallestFov;
|
||||
properties::DoubleProperty _stopAnimationThreshold;
|
||||
properties::DoubleProperty _animationSpeed;
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@ public:
|
||||
private:
|
||||
properties::DoubleProperty _animationSpeed;
|
||||
properties::FloatProperty _textureQuality;
|
||||
properties::BoolProperty _renderOnlyOnMaster;
|
||||
std::vector<std::unique_ptr<properties::Vec3Property>> _renderCopies;
|
||||
|
||||
void bindTexture() override;
|
||||
|
||||
@@ -67,8 +67,6 @@ public:
|
||||
|
||||
// Target
|
||||
void centerTargetOnScreen();
|
||||
void lock();
|
||||
void unlock();
|
||||
void incrementallyAnimateTarget(float deltaTime);
|
||||
|
||||
bool hasFinishedFading(float goalState) const;
|
||||
@@ -116,9 +114,7 @@ private:
|
||||
bool isTargetFadeFinished(float goalState) const;
|
||||
bool isBrowserFadeFinished(float goalState) const;
|
||||
|
||||
void aimTargetGalactic(glm::dvec3 position);
|
||||
|
||||
void setFovTarget(double fov);
|
||||
void aimTargetGalactic(glm::dvec3 direction);
|
||||
|
||||
// Selection
|
||||
ScreenSpaceSkyBrowser* _selected = nullptr;
|
||||
|
||||
@@ -42,7 +42,7 @@ uniform vec3 multiplyColor;
|
||||
|
||||
// A factor which states how much thicker vertical lines are rendered than horizontal
|
||||
// This compensates for the optical illusion that vertical lines appear thinner
|
||||
const float VerticalThickness = 1.15;
|
||||
const float VerticalThickness = 1.1;
|
||||
|
||||
float createLine(float lineCenter, float lineWidth, float coord) {
|
||||
// Calculate edges of line
|
||||
@@ -52,28 +52,13 @@ float createLine(float lineCenter, float lineWidth, float coord) {
|
||||
return step(startEdge, coord) - step(endEdge, coord);
|
||||
}
|
||||
|
||||
float createFilledRectangle(float width, vec2 coord) {
|
||||
return createLine(0.5, width, coord.x) * createLine(0.5, width, coord.y);
|
||||
}
|
||||
|
||||
float createRectangle(float linewidthY, float ratio, vec2 coord) {
|
||||
// Calculate the widths and centers for the lines
|
||||
float linewidthX = linewidthY * ratio * VerticalThickness;
|
||||
float linecenterX = linewidthX * 0.5;
|
||||
float linecenterY = linewidthY * 0.5;
|
||||
|
||||
// Create the four lines for the rectangle
|
||||
float l = createLine(linecenterX, linewidthX, coord.x);
|
||||
float r = createLine(1.0 - linecenterX, linewidthX, coord.x);
|
||||
float b = createLine(linecenterY, linewidthY, coord.y);
|
||||
float t = createLine(1.0 - linecenterY, linewidthY, coord.y);
|
||||
|
||||
return l + r + b + t;
|
||||
float createFilledRectangle(float width, float height, vec2 coord) {
|
||||
return createLine(0.5, width, coord.x) * createLine(0.5, height, coord.y);
|
||||
}
|
||||
|
||||
float createCrosshair(in float linewidth, in float ratio, in vec2 coord) {
|
||||
const float Center = 0.5;
|
||||
float crosshairVertical = createLine(Center, linewidth * ratio * VerticalThickness, coord.x);
|
||||
float crosshairVertical = createLine(Center, linewidth * VerticalThickness, coord.x);
|
||||
float crosshairHorizontal = createLine(Center, linewidth, coord.y);
|
||||
|
||||
return crosshairHorizontal + crosshairVertical;
|
||||
@@ -84,14 +69,22 @@ float createCrosshair(in float linewidth, in float ratio, in vec2 coord) {
|
||||
Fragment getFragment() {
|
||||
float ratio = dimensions.y / dimensions.x;
|
||||
float rectangle = 0.0;
|
||||
float lineWidthUsed = (lineWidth * 0.01)/max(fov,2);
|
||||
float maxWwtFov = 70;
|
||||
|
||||
float crosshair = createCrosshair(lineWidthUsed, ratio, vs_st);
|
||||
float crossHairBox = createFilledRectangle(crossHairSize/max(fov,2), vs_st);
|
||||
float crosshair = createCrosshair(lineWidth, ratio, vs_st);
|
||||
float crossHairHeight = crossHairSize/maxWwtFov;
|
||||
float crossHairWidth = crossHairHeight * ratio;
|
||||
float crossHairBox = createFilledRectangle(crossHairHeight, crossHairWidth, vs_st);
|
||||
crosshair *= crossHairBox;
|
||||
|
||||
if (showRectangle) {
|
||||
rectangle = createRectangle(lineWidthUsed, ratio, vs_st);
|
||||
float height = fov/maxWwtFov;
|
||||
float width = height * ratio;
|
||||
float outerEdge = createFilledRectangle(height, width, vs_st);
|
||||
float lineWidthX = lineWidth * 2 * VerticalThickness;
|
||||
float lineWidthY = lineWidth * 2;
|
||||
float innerEdge = createFilledRectangle(height-lineWidthX, width-lineWidthY, vs_st);
|
||||
rectangle = outerEdge - innerEdge;
|
||||
}
|
||||
|
||||
float result = clamp(crosshair + rectangle, 0.0, 1.0);
|
||||
|
||||
@@ -24,17 +24,16 @@
|
||||
|
||||
#include <modules/skybrowser/skybrowsermodule.h>
|
||||
|
||||
#include <modules/skybrowser/include/renderableskytarget.h>
|
||||
#include <modules/skybrowser/include/screenspaceskybrowser.h>
|
||||
#include <modules/skybrowser/include/targetbrowserpair.h>
|
||||
#include <modules/skybrowser/include/RenderableSkyTarget.h>
|
||||
#include <modules/skybrowser/include/wwtdatahandler.h>
|
||||
#include <modules/base/rendering/screenspaceimagelocal.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/engine/globalscallbacks.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
|
||||
#include "skybrowsermodule_lua.inl"
|
||||
@@ -76,199 +75,6 @@ namespace {
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
scripting::LuaLibrary SkyBrowserModule::luaLibrary() const {
|
||||
scripting::LuaLibrary res;
|
||||
res.name = "skybrowser";
|
||||
res.functions = {
|
||||
{
|
||||
"getListOfImages",
|
||||
&skybrowser::luascriptfunctions::getListOfImages,
|
||||
"",
|
||||
"Returns a list of all the loaded AAS WorldWide Telescope images that "
|
||||
"have been loaded. Each image has a name, thumbnail url, equatorial "
|
||||
"spherical coordinates RA and Dec, equatorial Cartesian coordinates, "
|
||||
"if the image has celestial coordinates, credits text, credits url "
|
||||
"and the identifier of the image which is a unique number."
|
||||
},
|
||||
{
|
||||
"setHoverCircle",
|
||||
&skybrowser::luascriptfunctions::setHoverCircle,
|
||||
"string",
|
||||
"Takes an identifier to a screen space renderable and adds it to the "
|
||||
"module."
|
||||
},
|
||||
{
|
||||
"moveCircleToHoverImage",
|
||||
&skybrowser::luascriptfunctions::moveCircleToHoverImage,
|
||||
"int",
|
||||
"Moves the hover circle to the coordinate specified by the image index."
|
||||
},
|
||||
{
|
||||
"disableHoverCircle",
|
||||
&skybrowser::luascriptfunctions::disableHoverCircle,
|
||||
"",
|
||||
"Disables the hover circle, if there is one added to the sky browser "
|
||||
"module."
|
||||
},
|
||||
{
|
||||
"loadImagesToWWT",
|
||||
&skybrowser::luascriptfunctions::loadImagesToWWT,
|
||||
"string",
|
||||
"Takes an identifier to a sky browser or target and loads the WWT image "
|
||||
"collection to that browser."
|
||||
},
|
||||
{
|
||||
"selectImage",
|
||||
&skybrowser::luascriptfunctions::selectImage,
|
||||
"int",
|
||||
"Takes an index to an image and selects that image in the currently "
|
||||
"selected sky browser."
|
||||
},
|
||||
{
|
||||
"removeSelectedImageInBrowser",
|
||||
&skybrowser::luascriptfunctions::removeSelectedImageInBrowser,
|
||||
"string, int",
|
||||
"Takes an identifier to a sky browser or target and an index to an "
|
||||
"image. Removes that image from that sky browser."
|
||||
},
|
||||
{
|
||||
"adjustCamera",
|
||||
& skybrowser::luascriptfunctions::adjustCamera,
|
||||
"string",
|
||||
"Takes an identifier to a sky browser or sky target. Rotates the camera "
|
||||
"so that the target is placed in the center of the view."
|
||||
},
|
||||
{
|
||||
"setSelectedBrowser",
|
||||
& skybrowser::luascriptfunctions::setSelectedBrowser,
|
||||
"string",
|
||||
"Takes an identifier to a sky browser or target. Sets that sky browser "
|
||||
"currently selected."
|
||||
},
|
||||
{
|
||||
"getTargetData",
|
||||
&skybrowser::luascriptfunctions::getTargetData,
|
||||
"",
|
||||
"Returns a table of data regarding the current view and the sky browsers "
|
||||
"and targets."
|
||||
},
|
||||
{
|
||||
"createTargetBrowserPair",
|
||||
&skybrowser::luascriptfunctions::createTargetBrowserPair,
|
||||
"",
|
||||
"Creates a sky browser and a target."
|
||||
},
|
||||
{
|
||||
"removeTargetBrowserPair",
|
||||
&skybrowser::luascriptfunctions::removeTargetBrowserPair,
|
||||
"string",
|
||||
"Takes in identifier to a sky browser or target and removes them."
|
||||
},
|
||||
{
|
||||
"setOpacityOfImageLayer",
|
||||
&skybrowser::luascriptfunctions::setOpacityOfImageLayer,
|
||||
"string, int, double",
|
||||
"Takes an identifier to a sky browser or sky target, an index to an image"
|
||||
"and a value for the opacity."
|
||||
},
|
||||
{
|
||||
"sendOutIdsToBrowsers",
|
||||
&skybrowser::luascriptfunctions::sendOutIdsToBrowsers,
|
||||
"",
|
||||
"Sends all sky browsers' identifiers to their respective CEF browser. "
|
||||
},
|
||||
{
|
||||
"initializeBrowser",
|
||||
&skybrowser::luascriptfunctions::initializeBrowser,
|
||||
"string",
|
||||
"Takes an identifier to a sky browser and starts the initialization "
|
||||
"for that browser. That means that the browser starts to try to connect "
|
||||
"to the AAS WorldWide Telescope application by sending it messages. And "
|
||||
"that the target matches its appearance to its corresponding browser."
|
||||
},
|
||||
{
|
||||
"centerTargetOnScreen",
|
||||
&skybrowser::luascriptfunctions::centerTargetOnScreen,
|
||||
"string",
|
||||
"Takes an identifier to a sky browser and animates its corresponding "
|
||||
"target to the center of the current view."
|
||||
},
|
||||
{
|
||||
"setImageLayerOrder",
|
||||
&skybrowser::luascriptfunctions::setImageLayerOrder,
|
||||
"string, int, int",
|
||||
"Takes an identifier to a sky browser or a sky target, an image index "
|
||||
"and the order which it should have in the selected image list. The "
|
||||
"image is then changed to have this order."
|
||||
},
|
||||
{
|
||||
"addPairToSkyBrowserModule",
|
||||
&skybrowser::luascriptfunctions::addPairToSkyBrowserModule,
|
||||
"string, string",
|
||||
"Takes the identifier of the sky target and a sky browser and adds them "
|
||||
"to the sky browser module."
|
||||
},
|
||||
{
|
||||
"setEquatorialAim",
|
||||
&skybrowser::luascriptfunctions::setEquatorialAim,
|
||||
"string, double, double",
|
||||
"Takes the identifier of a sky browser or a sky target and equatorial "
|
||||
"coordinates Right Ascension and Declination. The target will animate to "
|
||||
"this coordinate and the browser will display the coordinate."
|
||||
},
|
||||
{
|
||||
"setVerticalFov",
|
||||
&skybrowser::luascriptfunctions::setVerticalFov,
|
||||
"string, float",
|
||||
"Takes an identifier to a sky browser or a sky target and a vertical "
|
||||
"field of view. Changes the field of view as specified by the input."
|
||||
},
|
||||
{
|
||||
"setBorderColor",
|
||||
&skybrowser::luascriptfunctions::setBorderColor,
|
||||
"string, int, int, int",
|
||||
"Takes an identifier to a sky browser or a sky target and a rgb color "
|
||||
"in the ranges [0, 255]."
|
||||
},
|
||||
{
|
||||
"setScreenSpaceSize",
|
||||
&skybrowser::luascriptfunctions::setScreenSpaceSize,
|
||||
"string, float, float",
|
||||
"Sets the screen space size of the sky browser to the numbers specified "
|
||||
"by the input [x, y]."
|
||||
},
|
||||
{
|
||||
"startSetup",
|
||||
&skybrowser::luascriptfunctions::startSetup,
|
||||
"",
|
||||
"Starts the setup process of the sky browers. This function calls "
|
||||
"the lua function 'sendOutIdsToBrowsers' in all nodes in the cluster."
|
||||
},
|
||||
{
|
||||
"translateScreenSpaceRenderable",
|
||||
&skybrowser::luascriptfunctions::translateScreenSpaceRenderable,
|
||||
"string, float, float, float, float",
|
||||
"Takes an identifier to a sky browser or sky target and the [x, y] "
|
||||
"starting position and the [x, y] translation vector."
|
||||
},
|
||||
{
|
||||
"addRenderCopy",
|
||||
&skybrowser::luascriptfunctions::addRenderCopy,
|
||||
"string",
|
||||
"Takes an identifier to a sky browser and adds a rendered copy to it."
|
||||
},
|
||||
{
|
||||
"removeRenderCopy",
|
||||
&skybrowser::luascriptfunctions::removeRenderCopy,
|
||||
"string",
|
||||
"Takes an identifier to a sky browser and removes the latest added "
|
||||
"rendered copy to it."
|
||||
},
|
||||
};
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
SkyBrowserModule::SkyBrowserModule()
|
||||
: OpenSpaceModule(SkyBrowserModule::Name)
|
||||
, _allowMouseInteraction(AllowInteractionInfo, true)
|
||||
@@ -570,7 +376,7 @@ TargetBrowserPair* SkyBrowserModule::getPair(const std::string& id) {
|
||||
bool foundBrowser = pair->browserId() == id;
|
||||
bool foundTarget = pair->targetRenderableId() == id;
|
||||
bool foundTargetNode = pair->targetNodeId() == id;
|
||||
return foundBrowser || foundTarget;
|
||||
return foundBrowser || foundTarget || foundTargetNode;
|
||||
}
|
||||
);
|
||||
if (it == std::end(_targetsBrowsers)) {
|
||||
@@ -702,4 +508,39 @@ bool SkyBrowserModule::isSelectedPairFacingCamera() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
scripting::LuaLibrary SkyBrowserModule::luaLibrary() const {
|
||||
return {
|
||||
"skybrowser",
|
||||
{
|
||||
codegen::lua::StartSetup,
|
||||
codegen::lua::InitializeBrowser,
|
||||
codegen::lua::SendOutIdsToBrowsers,
|
||||
codegen::lua::GetListOfImages,
|
||||
codegen::lua::SetHoverCircle,
|
||||
codegen::lua::MoveCircleToHoverImage,
|
||||
codegen::lua::DisableHoverCircle,
|
||||
codegen::lua::LoadImagesToWWT,
|
||||
codegen::lua::SelectImage,
|
||||
codegen::lua::RemoveSelectedImageInBrowser,
|
||||
codegen::lua::AdjustCamera,
|
||||
codegen::lua::SetSelectedBrowser,
|
||||
codegen::lua::GetTargetData,
|
||||
codegen::lua::CreateTargetBrowserPair,
|
||||
codegen::lua::RemoveTargetBrowserPair,
|
||||
codegen::lua::SetOpacityOfImageLayer,
|
||||
codegen::lua::CenterTargetOnScreen,
|
||||
codegen::lua::SetImageLayerOrder,
|
||||
codegen::lua::AddPairToSkyBrowserModule,
|
||||
codegen::lua::SetEquatorialAim,
|
||||
codegen::lua::SetVerticalFov,
|
||||
codegen::lua::SetBorderColor,
|
||||
codegen::lua::TranslateScreenSpaceRenderable,
|
||||
codegen::lua::AddRenderCopy,
|
||||
codegen::lua::SetScreenSpaceSize,
|
||||
codegen::lua::RemoveRenderCopy
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -25,8 +25,10 @@
|
||||
#include <modules/skybrowser/skybrowsermodule.h>
|
||||
|
||||
#include <modules/skybrowser/include/utility.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <modules/skybrowser/include/targetbrowserpair.h>
|
||||
#include <modules/skybrowser/include/wwtdatahandler.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
@@ -35,14 +37,16 @@
|
||||
|
||||
namespace {
|
||||
constexpr const char _loggerCat[] = "SkyBrowserModule";
|
||||
} // namespace
|
||||
|
||||
namespace openspace::skybrowser::luascriptfunctions {
|
||||
using namespace openspace;
|
||||
|
||||
int selectImage(lua_State* L) {
|
||||
/**
|
||||
* Takes an index to an image and selects that image in the currently
|
||||
* selected sky browser.
|
||||
* \param i Index of image
|
||||
*/
|
||||
[[codegen::luawrap]] void selectImage(int i) {
|
||||
// Load image
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::selectImage");
|
||||
const int i = ghoul::lua::value<int>(L, 1);
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
|
||||
if (module->isCameraInSolarSystem()) {
|
||||
@@ -53,66 +57,68 @@ int selectImage(lua_State* L) {
|
||||
LINFO("Loading image " + image.name);
|
||||
selected->selectImage(image, i);
|
||||
|
||||
bool isInView = isCoordinateInView(image.equatorialCartesian);
|
||||
bool isInView = skybrowser::isCoordinateInView(image.equatorialCartesian);
|
||||
// If the coordinate is not in view, rotate camera
|
||||
if (image.hasCelestialCoords && !isInView) {
|
||||
module->startRotatingCamera(
|
||||
equatorialToGalactic(
|
||||
skybrowser::equatorialToGalactic(
|
||||
image.equatorialCartesian * skybrowser::CelestialSphereRadius
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int setHoverCircle(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::setHoverCircle");
|
||||
/**
|
||||
* Takes an identifier to a screen space renderable and adds it to the module.
|
||||
* \param id Identifier
|
||||
*/
|
||||
[[codegen::luawrap]] void setHoverCircle(std::string id) {
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
std::string id = ghoul::lua::value<std::string>(L, 1);
|
||||
|
||||
SceneGraphNode* circle = global::renderEngine->scene()->sceneGraphNode(id);
|
||||
module->setHoverCircle(circle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int moveCircleToHoverImage(lua_State* L) {
|
||||
/**
|
||||
* Moves the hover circle to the coordinate specified by the image index.
|
||||
* \param i Index of image
|
||||
*/
|
||||
[[codegen::luawrap]] void moveCircleToHoverImage(int i) {
|
||||
// Load image
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::moveCircleToHoverImage");
|
||||
const int i = ghoul::lua::value<int>(L, 1);
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
module->moveHoverCircle(i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int disableHoverCircle(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::disableHoverCircle");
|
||||
/**
|
||||
* Disables the hover circle, if there is one added to the sky browser
|
||||
* module.
|
||||
*/
|
||||
[[codegen::luawrap]] void disableHoverCircle() {
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
module->disableHoverCircle();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int setImageLayerOrder(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::setImageLayerOrder");
|
||||
auto [id, i, order] = ghoul::lua::values<std::string, int, int>(L);
|
||||
/**
|
||||
* Takes an identifier to a sky browser or a sky target, an image index
|
||||
* and the order which it should have in the selected image list. The
|
||||
* image is then changed to have this order.
|
||||
* \param id Identifier
|
||||
* \param i Image index
|
||||
* \param order Order of image
|
||||
*/
|
||||
[[codegen::luawrap]] void setImageLayerOrder(std::string id, int i, int order) {
|
||||
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
|
||||
if (module->getPair(id)) {
|
||||
module->getPair(id)->setImageOrder(i, order);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int loadImagesToWWT(lua_State* L) {
|
||||
/**
|
||||
* Takes an identifier to a sky browser or target and loads the WWT image
|
||||
* collection to that browser.
|
||||
* \param id Identifier
|
||||
*/
|
||||
[[codegen::luawrap]] void loadImagesToWWT(std::string id) {
|
||||
// Load images from url
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::loadImagesToWWT");
|
||||
const std::string id = ghoul::lua::value<std::string>(L, 1);
|
||||
LINFO("Connection established to WorldWide Telescope application in " + id);
|
||||
LINFO("Loading image collections to " + id);
|
||||
|
||||
@@ -127,14 +133,13 @@ int loadImagesToWWT(lua_State* L) {
|
||||
module->getPair(id)->hideChromeInterface(true);
|
||||
module->getPair(id)->loadImageCollection(root);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int startSetup(lua_State* L) {
|
||||
/**
|
||||
* Starts the setup process of the sky browers. This function calls
|
||||
* the lua function 'sendOutIdsToBrowsers' in all nodes in the cluster.
|
||||
*/
|
||||
[[codegen::luawrap]] void startSetup() {
|
||||
// This is called when the sky_browser website is connected to OpenSpace
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::startSetup");
|
||||
|
||||
// Set all border colors to the border color in the master node
|
||||
if (global::windowDelegate->isMaster()) {
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
@@ -162,29 +167,28 @@ int startSetup(lua_State* L) {
|
||||
"openspace.skybrowser.sendOutIdsToBrowsers();",
|
||||
scripting::ScriptEngine::RemoteScripting::No
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sendOutIdsToBrowsers(lua_State* L) {
|
||||
/**
|
||||
* Sends all sky browsers' identifiers to their respective CEF browser.
|
||||
*/
|
||||
[[codegen::luawrap]] void sendOutIdsToBrowsers() {
|
||||
// This is called when the sky_browser website is connected to OpenSpace
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::sendOutIdsToBrowsers");
|
||||
|
||||
// Send out identifiers to the browsers
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
std::vector<std::unique_ptr<TargetBrowserPair>>& pairs = module->getPairs();
|
||||
for (std::unique_ptr<TargetBrowserPair>& pair : pairs) {
|
||||
pair->sendIdToBrowser();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int initializeBrowser(lua_State* L) {
|
||||
/**
|
||||
* Takes an identifier to a sky browser and starts the initialization
|
||||
* for that browser. That means that the browser starts to try to connect
|
||||
* to the AAS WorldWide Telescope application by sending it messages. And
|
||||
* that the target matches its appearance to its corresponding browser.
|
||||
* \param id Identifier
|
||||
*/
|
||||
[[codegen::luawrap]] void initializeBrowser(std::string id) {
|
||||
// Initialize browser with ID and its corresponding target
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::initializeBrowser");
|
||||
const std::string id = ghoul::lua::value<std::string>(L, 1);
|
||||
|
||||
LINFO("Initializing sky browser " + id);
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
TargetBrowserPair* found = module->getPair(id);
|
||||
@@ -192,30 +196,34 @@ int initializeBrowser(lua_State* L) {
|
||||
found->setIsSyncedWithWwt(true);
|
||||
found->initialize();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int addPairToSkyBrowserModule(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::addPairToSkyBrowserModule");
|
||||
auto [targetId, browserId] = ghoul::lua::values<std::string, std::string>(L);
|
||||
/**
|
||||
* Takes the identifier of the sky target and a sky browser and adds them
|
||||
* to the sky browser module.
|
||||
* \param targetId Identifier of target (either SceneGraphNode or Renderable)
|
||||
* \param browserId Identifier of browser
|
||||
*/
|
||||
[[codegen::luawrap]] void addPairToSkyBrowserModule(std::string targetId, std::string browserId) {
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
|
||||
LINFO("Add browser " + browserId + " to sky browser module");
|
||||
LINFO("Add target " + targetId + " to sky browser module");
|
||||
|
||||
module->addTargetBrowserPair(targetId, browserId);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* Returns a list of all the loaded AAS WorldWide Telescope images that
|
||||
* have been loaded. Each image has a name, thumbnail url, equatorial
|
||||
* spherical coordinates RA and Dec, equatorial Cartesian coordinates,
|
||||
* if the image has celestial coordinates, credits text, credits url
|
||||
* and the identifier of the image which is a unique number.
|
||||
*/
|
||||
|
||||
int getListOfImages(lua_State* L) {
|
||||
[[codegen::luawrap]] ghoul::Dictionary getListOfImages() {
|
||||
// Send image list to GUI
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::getListOfImages");
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
|
||||
// If no data has been loaded yet, download the data from the web!
|
||||
|
||||
if (module->nLoadedImages() == 0) {
|
||||
std::string root = "https://raw.githubusercontent.com/WorldWideTelescope/"
|
||||
"wwt-web-client/master/assets/webclient-explore-root.wtml";
|
||||
@@ -226,79 +234,64 @@ int getListOfImages(lua_State* L) {
|
||||
}
|
||||
|
||||
// Create Lua table to send to the GUI
|
||||
lua_newtable(L);
|
||||
ghoul::Dictionary list;
|
||||
|
||||
for (int i = 0; i < module->nLoadedImages(); i++) {
|
||||
const ImageData& img = module->getWwtDataHandler()->getImage(i);
|
||||
using namespace std::string_literals;
|
||||
|
||||
// Index for current ImageData
|
||||
ghoul::lua::push(L, i + 1);
|
||||
lua_newtable(L);
|
||||
// Push ("Key", value)
|
||||
ghoul::lua::push(L, "name", img.name);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "thumbnail", img.thumbnailUrl);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "ra", img.equatorialSpherical.x);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "dec", img.equatorialSpherical.y);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "cartesianDirection", img.equatorialCartesian);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "hasCelestialCoords", img.hasCelestialCoords);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "credits", img.credits);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "creditsUrl", img.creditsUrl);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "identifier", std::to_string(i));
|
||||
lua_settable(L, -3);
|
||||
ghoul::Dictionary image;
|
||||
image.setValue("name", img.name);
|
||||
image.setValue("thumbnail", img.thumbnailUrl);
|
||||
image.setValue("ra", img.equatorialSpherical.x);
|
||||
image.setValue("dec", img.equatorialSpherical.y);
|
||||
image.setValue("cartesianDirection", img.equatorialCartesian);
|
||||
image.setValue("hasCelestialCoords", img.hasCelestialCoords);
|
||||
image.setValue("credits", img.credits);
|
||||
image.setValue("creditsUrl", img.creditsUrl);
|
||||
image.setValue("identifier", std::to_string(i));
|
||||
|
||||
// Index for current ImageData
|
||||
// Set table for the current ImageData
|
||||
lua_settable(L, -3);
|
||||
list.setValue(std::to_string(i + 1), image);
|
||||
}
|
||||
|
||||
return 1;
|
||||
return list;
|
||||
}
|
||||
|
||||
int getTargetData(lua_State* L) {
|
||||
// Send image list to GUI
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::getTargetData");
|
||||
|
||||
/**
|
||||
* Returns a table of data regarding the current view and the sky browsers
|
||||
* and targets.
|
||||
* \return Dictionary of data regarding the current targets
|
||||
*/
|
||||
[[codegen::luawrap]] ghoul::Dictionary getTargetData() {
|
||||
using namespace std::string_literals;
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
|
||||
lua_newtable(L);
|
||||
ghoul::Dictionary data;
|
||||
|
||||
// Add the window data for OpenSpace
|
||||
ghoul::lua::push(L, "OpenSpace");
|
||||
lua_newtable(L);
|
||||
// The current viewport data for OpenSpace
|
||||
ghoul::Dictionary openSpace;
|
||||
|
||||
// Camera directions
|
||||
glm::dvec3 cartesianCam = skybrowser::cameraDirectionEquatorial();
|
||||
glm::dvec2 sphericalCam = skybrowser::cartesianToSpherical(cartesianCam);
|
||||
|
||||
// Calculate the smallest FOV of vertical and horizontal
|
||||
glm::dvec2 fovs = skybrowser::fovWindow();
|
||||
double FOV = std::min(fovs.x, fovs.y);
|
||||
// Push window data
|
||||
ghoul::lua::push(L, "windowHFOV", FOV);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "cartesianDirection", cartesianCam);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "ra", sphericalCam.x);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "dec", sphericalCam.y);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "selectedBrowserId", module->selectedBrowserId());
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "selectedTargetId", module->selectedTargetId());
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "isFacingCamera", module->isSelectedPairFacingCamera());
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "isUsingRadiusAzimuthElevation", module->isSelectedPairUsingRae());
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "cameraInSolarSystem", module->isCameraInSolarSystem());
|
||||
lua_settable(L, -3);
|
||||
|
||||
// Set window data
|
||||
openSpace.setValue("windowHFOV", FOV);
|
||||
openSpace.setValue("cartesianDirection", cartesianCam);
|
||||
openSpace.setValue("ra", sphericalCam.x);
|
||||
openSpace.setValue("dec", sphericalCam.y);
|
||||
openSpace.setValue("selectedBrowserId", module->selectedBrowserId());
|
||||
openSpace.setValue("selectedTargetId", module->selectedTargetId());
|
||||
openSpace.setValue("isFacingCamera", module->isSelectedPairFacingCamera());
|
||||
openSpace.setValue("isUsingRadiusAzimuthElevation", module->isSelectedPairUsingRae());
|
||||
openSpace.setValue("cameraInSolarSystem", module->isCameraInSolarSystem());
|
||||
// Set table for the current ImageData
|
||||
lua_settable(L, -3);
|
||||
data.setValue("OpenSpace", openSpace);
|
||||
|
||||
// Pass data for all the browsers and the corresponding targets
|
||||
if (module->isCameraInSolarSystem()) {
|
||||
@@ -320,85 +313,76 @@ int getTargetData(lua_State* L) {
|
||||
glm::dvec2 spherical = pair->targetDirectionEquatorial();
|
||||
glm::dvec3 cartesian = skybrowser::sphericalToCartesian(spherical);
|
||||
|
||||
ghoul::lua::push(L, id);
|
||||
lua_newtable(L);
|
||||
// Push ("Key", value)
|
||||
ghoul::lua::push(L, "id", id);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "name", pair->browserGuiName());
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "FOV", pair->verticalFov());
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "selectedImages", selectedImagesVector);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "cartesianDirection", cartesian);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "ra", spherical.x);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "dec", spherical.y);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "color", pair->borderColor());
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "size", pair->size());
|
||||
lua_settable(L, -3);
|
||||
ghoul::Dictionary target;
|
||||
// Set ("Key", value)
|
||||
target.setValue("id", id);
|
||||
target.setValue("name", pair->browserGuiName());
|
||||
target.setValue("FOV", static_cast<double>(pair->verticalFov()));
|
||||
target.setValue("selectedImages", selectedImagesVector);
|
||||
target.setValue("cartesianDirection", cartesian);
|
||||
target.setValue("ra", spherical.x);
|
||||
target.setValue("dec", spherical.y);
|
||||
target.setValue("color", pair->borderColor());
|
||||
target.setValue("size", glm::dvec2(pair->size()));
|
||||
|
||||
// Set table for the current target
|
||||
lua_settable(L, -3);
|
||||
data.setValue(id, target);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
return data;
|
||||
}
|
||||
|
||||
int adjustCamera(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::adjustCamera");
|
||||
const std::string id = ghoul::lua::value<std::string>(L, 1);
|
||||
/**
|
||||
* Takes an identifier to a sky browser or sky target. Rotates the camera
|
||||
* so that the target is placed in the center of the view.
|
||||
* \param id
|
||||
*/
|
||||
[[codegen::luawrap]] void adjustCamera(std::string id) {
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
|
||||
if (module->isCameraInSolarSystem()) {
|
||||
module->lookAtTarget(id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int setOpacityOfImageLayer(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::setOpacityOfImageLayer");
|
||||
auto [id, i, opacity] = ghoul::lua::values<std::string, int, double>(L);
|
||||
/**
|
||||
* Takes an identifier to a sky browser or sky target, an index to an image
|
||||
* and a value for the opacity.
|
||||
* \param id Identifier
|
||||
* \param i Image index
|
||||
* \param opacity
|
||||
*/
|
||||
[[codegen::luawrap]] void setOpacityOfImageLayer(std::string id, int i, double opacity) {
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
|
||||
TargetBrowserPair* found = module->getPair(id);
|
||||
if (found) {
|
||||
found->setImageOpacity(i, opacity);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int centerTargetOnScreen(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::centerTargetOnScreen");
|
||||
const std::string id = ghoul::lua::value<std::string>(L, 1);
|
||||
/**
|
||||
* Takes an identifier to a sky browser and animates its corresponding
|
||||
* target to the center of the current view.
|
||||
* \param id Identifier
|
||||
*/
|
||||
[[codegen::luawrap]] void centerTargetOnScreen(std::string id) {
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
TargetBrowserPair* pair = module->getPair(id);
|
||||
if (pair) {
|
||||
pair->centerTargetOnScreen();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int setSelectedBrowser(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::setSelectedBrowser");
|
||||
const std::string id = ghoul::lua::value<std::string>(L, 1);
|
||||
/**
|
||||
* Takes an identifier to a sky browser or target. Sets that sky browser
|
||||
* currently selected.
|
||||
* \param id
|
||||
*/
|
||||
[[codegen::luawrap]] void setSelectedBrowser(std::string id) {
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
|
||||
module->setSelectedBrowser(id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int createTargetBrowserPair(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::createTargetBrowserPair");
|
||||
/**
|
||||
* Creates a sky browser and a target.
|
||||
*/
|
||||
[[codegen::luawrap]] void createTargetBrowserPair() {
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
|
||||
int noOfPairs = module->nPairs();
|
||||
@@ -412,7 +396,7 @@ int createTargetBrowserPair(lua_State* L) {
|
||||
glm::dvec3 galacticTarget = skybrowser::localCameraToGalactic(positionTarget);
|
||||
std::string guiPath = "/SkyBrowser";
|
||||
std::string url = "https://data.openspaceproject.com/dist/skybrowser/page/";
|
||||
double fov = 5.0;
|
||||
double fov = 70.0;
|
||||
double size = skybrowser::sizeFromFov(fov, galacticTarget);
|
||||
|
||||
const std::string browser = "{"
|
||||
@@ -477,13 +461,12 @@ int createTargetBrowserPair(lua_State* L) {
|
||||
"openspace.skybrowser.setSelectedBrowser('" + idBrowser + "');",
|
||||
scripting::ScriptEngine::RemoteScripting::No
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int removeTargetBrowserPair(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::removeTargetBrowserPair");
|
||||
std::string id = ghoul::lua::value<std::string>(L, 1);
|
||||
/**
|
||||
* Takes in identifier to a sky browser or target and removes them.
|
||||
* \param id Identifier
|
||||
*/
|
||||
[[codegen::luawrap]] void removeTargetBrowserPair(std::string id) {
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
TargetBrowserPair* found = module->getPair(id);
|
||||
if (found) {
|
||||
@@ -503,28 +486,32 @@ int removeTargetBrowserPair(lua_State* L) {
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int translateScreenSpaceRenderable(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 5, "lua::translateScreenSpaceRenderable");
|
||||
auto [id, startX, startY, transX, transY] =
|
||||
ghoul::lua::values<std::string, float, float, float, float>(L);
|
||||
|
||||
/**
|
||||
* Takes an identifier to a sky browser or sky target and the [x, y]
|
||||
* starting position and the [x, y] translation vector.
|
||||
* \param id Identifier
|
||||
* \param startX Starting x-position
|
||||
* \param startY Starting y-position
|
||||
* \param transX Translation x-value
|
||||
* \param transY Translation y-value
|
||||
*/
|
||||
[[codegen::luawrap]] void translateScreenSpaceRenderable(std::string id, float startX,
|
||||
float startY, float transX,
|
||||
float transY) {
|
||||
ScreenSpaceRenderable* renderable = global::renderEngine->screenSpaceRenderable(id);
|
||||
|
||||
if (renderable) {
|
||||
renderable->translate(glm::vec2(transX, transY), glm::vec2(startX, startY));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int removeSelectedImageInBrowser(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::removeSelectedImageInBrowser");
|
||||
auto [id, i] = ghoul::lua::values<std::string, int>(L);
|
||||
|
||||
/**
|
||||
* Takes an identifier to a sky browser or target and an index to an
|
||||
* image. Removes that image from that sky browser.
|
||||
* \param id Identifier
|
||||
* \i Index of image
|
||||
*/
|
||||
[[codegen::luawrap]] void removeSelectedImageInBrowser(std::string id, int i) {
|
||||
// Get browser
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
const ImageData& image = module->getWwtDataHandler()->getImage(i);
|
||||
@@ -533,14 +520,16 @@ int removeSelectedImageInBrowser(lua_State* L) {
|
||||
if (pair) {
|
||||
pair->removeSelectedImage(i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int setEquatorialAim(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::setEquatorialAim");
|
||||
auto [id, ra, dec] = ghoul::lua::values<std::string, double, double>(L);
|
||||
|
||||
/**
|
||||
* Takes the identifier of a sky browser or a sky target and equatorial
|
||||
* coordinates Right Ascension and Declination. The target will animate to
|
||||
* this coordinate and the browser will display the coordinate.
|
||||
* \param id Identifier
|
||||
* \param ra Right Ascension
|
||||
* \param dec Declination
|
||||
*/
|
||||
[[codegen::luawrap]] void setEquatorialAim(std::string id, double ra, double dec) {
|
||||
// Get module
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
|
||||
@@ -548,14 +537,14 @@ int setEquatorialAim(lua_State* L) {
|
||||
if (pair) {
|
||||
pair->setEquatorialAim(glm::dvec2(ra, dec));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int setVerticalFov(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::setVerticalFov");
|
||||
auto [id, vfov] = ghoul::lua::values<std::string, float>(L);
|
||||
|
||||
/**
|
||||
* Takes an identifier to a sky browser or a sky target and a vertical
|
||||
* field of view. Changes the field of view as specified by the input.
|
||||
* \param id Identifier
|
||||
* \param vfov Vertical Field of View
|
||||
*/
|
||||
[[codegen::luawrap]] void setVerticalFov(std::string id, float vfov) {
|
||||
// Get module
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
|
||||
@@ -563,14 +552,16 @@ int setVerticalFov(lua_State* L) {
|
||||
if (pair) {
|
||||
pair->setVerticalFov(vfov);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int setBorderColor(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 4, "lua::setBorderColor");
|
||||
auto [id, r, g, b] = ghoul::lua::values<std::string, int, int, int>(L);
|
||||
|
||||
/**
|
||||
* Takes an identifier to a sky browser or a sky target and a rgb color
|
||||
* in the ranges [0, 255].
|
||||
* \param id Identifier
|
||||
* \param r Red
|
||||
* \param g Green
|
||||
* \param b Blue
|
||||
*/
|
||||
[[codegen::luawrap]] void setBorderColor(std::string id, int r, int g, int b) {
|
||||
glm::ivec3 color{ r, g, b };
|
||||
// Get module
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
@@ -579,14 +570,15 @@ int setBorderColor(lua_State* L) {
|
||||
if (pair) {
|
||||
pair->setBorderColor(color);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int setScreenSpaceSize(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::setScreenSpaceSize");
|
||||
auto [id, sizeX, sizeY] = ghoul::lua::values<std::string, float, float>(L);
|
||||
|
||||
/**
|
||||
* Sets the screen space size of the sky browser to the numbers specified
|
||||
* by the input [x, y].
|
||||
* \param id
|
||||
* \param sizeX Size on the x-axis
|
||||
* \param sizeY Size on the y-axis
|
||||
*/
|
||||
[[codegen::luawrap]] void setScreenSpaceSize(std::string id, float sizeX, float sizeY) {
|
||||
// Get module
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
|
||||
@@ -594,13 +586,12 @@ int setScreenSpaceSize(lua_State* L) {
|
||||
if (pair) {
|
||||
pair->setScreenSpaceSize(glm::vec2(sizeX, sizeY));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int addRenderCopy(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::addRenderCopy");
|
||||
auto [id] = ghoul::lua::values<std::string>(L);
|
||||
|
||||
/**
|
||||
* Takes an identifier to a sky browser and adds a rendered copy to it.
|
||||
* \param id Identifier
|
||||
*/
|
||||
[[codegen::luawrap]] void addRenderCopy(std::string id) {
|
||||
// Get module
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
|
||||
@@ -608,14 +599,13 @@ int addRenderCopy(lua_State* L) {
|
||||
if (pair) {
|
||||
pair->browser()->addRenderCopy();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int removeRenderCopy(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::removeRenderCopy");
|
||||
auto [id] = ghoul::lua::values<std::string>(L);
|
||||
|
||||
/**
|
||||
* Takes an identifier to a sky browser and removes the latest added
|
||||
* rendered copy to it.
|
||||
* \param id Identifier
|
||||
*/
|
||||
[[codegen::luawrap]] void removeRenderCopy(std::string id) {
|
||||
// Get module
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
|
||||
@@ -623,7 +613,8 @@ int removeRenderCopy(lua_State* L) {
|
||||
if (pair) {
|
||||
pair->browser()->removeRenderCopy();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
} // namespace openspace::skybrowser::luafunctions
|
||||
#include "skybrowsermodule_lua_codegen.cpp"
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -103,8 +103,8 @@ Browser::Browser(const ghoul::Dictionary& dictionary)
|
||||
_renderHandler = new RenderHandler();
|
||||
_keyboardHandler = new WebKeyboardHandler();
|
||||
_browserInstance = std::make_unique<BrowserInstance>(
|
||||
_renderHandler,
|
||||
_keyboardHandler
|
||||
_renderHandler.get(),
|
||||
_keyboardHandler.get()
|
||||
);
|
||||
|
||||
WebBrowserModule* webBrowser = global::moduleEngine->module<WebBrowserModule>();
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace {
|
||||
{
|
||||
"CrosshairSize",
|
||||
"Crosshair Size",
|
||||
"Determines the size of the crosshair."
|
||||
"Determines the size of the crosshair. The size is determined in fov (degrees). "
|
||||
};
|
||||
|
||||
constexpr const openspace::properties::Property::PropertyInfo RectangleThresholdInfo =
|
||||
@@ -85,12 +85,6 @@ namespace {
|
||||
"The thickness of the line of the target. The larger number, the thicker line."
|
||||
};
|
||||
|
||||
constexpr const openspace::properties::Property::PropertyInfo SmallestFovInfo = {
|
||||
"SmallestFov",
|
||||
"Smallest Vertical Field Of View",
|
||||
"The smallest field of view that the target will display on screen."
|
||||
};
|
||||
|
||||
struct [[codegen::Dictionary(RenderableSkyTarget)]] Parameters {
|
||||
// [[codegen::verbatim(crossHairSizeInfo.description)]]
|
||||
std::optional<float> crossHairSize;
|
||||
@@ -106,9 +100,6 @@ namespace {
|
||||
|
||||
// [[codegen::verbatim(LineWidthInfo.description)]]
|
||||
std::optional<float> lineWidth;
|
||||
|
||||
// [[codegen::verbatim(SmallestFovInfo.description)]]
|
||||
std::optional<float> smallestFov;
|
||||
};
|
||||
|
||||
#include "renderableskytarget_codegen.cpp"
|
||||
@@ -122,7 +113,6 @@ namespace openspace {
|
||||
, _stopAnimationThreshold(AnimationThresholdInfo, 5.0f, 1.f, 10.f)
|
||||
, _animationSpeed(AnimationSpeedInfo, 5.0, 0.1, 10.0)
|
||||
, _lineWidth(LineWidthInfo, 13.f, 1.f, 100.f)
|
||||
, _smallestFov(SmallestFovInfo, 3.0, 0.5, 20.0)
|
||||
, _borderColor(220, 220, 220)
|
||||
{
|
||||
// Handle target dimension property
|
||||
@@ -131,14 +121,12 @@ namespace openspace {
|
||||
_showRectangleThreshold = p.rectangleThreshold.value_or(_showRectangleThreshold);
|
||||
_stopAnimationThreshold = p.crossHairSize.value_or(_stopAnimationThreshold);
|
||||
_animationSpeed = p.animationSpeed.value_or(_animationSpeed);
|
||||
_smallestFov = p.smallestFov.value_or(_smallestFov);
|
||||
|
||||
addProperty(_crossHairSize);
|
||||
addProperty(_showRectangleThreshold);
|
||||
addProperty(_stopAnimationThreshold);
|
||||
addProperty(_animationSpeed);
|
||||
addProperty(_lineWidth);
|
||||
addProperty(_smallestFov);
|
||||
}
|
||||
|
||||
void RenderableSkyTarget::bindTexture() {}
|
||||
@@ -186,7 +174,7 @@ void RenderableSkyTarget::render(const RenderData& data, RendererTasks&) {
|
||||
|
||||
_shader->setUniform("crossHairSize", _crossHairSize);
|
||||
_shader->setUniform("showRectangle", showRectangle);
|
||||
_shader->setUniform("lineWidth", _lineWidth);
|
||||
_shader->setUniform("lineWidth", _lineWidth * 0.0001f);
|
||||
_shader->setUniform("dimensions", _dimensions);
|
||||
_shader->setUniform("lineColor", color);
|
||||
_shader->setUniform("fov", static_cast<float>(_verticalFov));
|
||||
@@ -279,10 +267,6 @@ double RenderableSkyTarget::stopAnimationThreshold() const {
|
||||
return _stopAnimationThreshold * 0.0001;
|
||||
}
|
||||
|
||||
double RenderableSkyTarget::smallestFov() const {
|
||||
return _smallestFov;
|
||||
}
|
||||
|
||||
void RenderableSkyTarget::setOpacity(float opacity) {
|
||||
_opacity = opacity;
|
||||
}
|
||||
|
||||
@@ -61,12 +61,22 @@ namespace {
|
||||
"be interactive. The position is in RAE (Radius, Azimuth, Elevation) coordinates."
|
||||
};
|
||||
|
||||
constexpr const openspace::properties::Property::PropertyInfo RenderOnMasterInfo = {
|
||||
"RenderOnlyOnMaster",
|
||||
"Render Only On Master",
|
||||
"Render the interactive sky browser only on the master node (this setting won't "
|
||||
"affect the copies). This setting allows mouse interactions in a dome environment."
|
||||
};
|
||||
|
||||
struct [[codegen::Dictionary(ScreenSpaceSkyBrowser)]] Parameters {
|
||||
// [[codegen::verbatim(AnimationSpeedInfo.description)]]
|
||||
std::optional<double> animationSpeed;
|
||||
|
||||
// [[codegen::verbatim(TextureQualityInfo.description)]]
|
||||
std::optional<float> textureQuality;
|
||||
|
||||
// [[codegen::verbatim(RenderOnMasterInfo.description)]]
|
||||
std::optional<bool> renderOnlyOnMaster;
|
||||
};
|
||||
|
||||
#include "screenspaceskybrowser_codegen.cpp"
|
||||
@@ -99,6 +109,7 @@ namespace openspace {
|
||||
, WwtCommunicator(dictionary)
|
||||
, _animationSpeed(AnimationSpeedInfo, 5.0, 0.1, 10.0)
|
||||
, _textureQuality(TextureQualityInfo, 1.f, 0.25f, 1.f)
|
||||
, _renderOnlyOnMaster(RenderOnMasterInfo, false)
|
||||
{
|
||||
_identifier = makeUniqueIdentifier(_identifier);
|
||||
|
||||
@@ -106,11 +117,13 @@ namespace openspace {
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
_textureQuality = p.textureQuality.value_or(_textureQuality);
|
||||
_animationSpeed = p.animationSpeed.value_or(_animationSpeed);
|
||||
_renderOnlyOnMaster = p.renderOnlyOnMaster.value_or(_renderOnlyOnMaster);
|
||||
|
||||
addProperty(_url);
|
||||
addProperty(_browserPixeldimensions);
|
||||
addProperty(_reload);
|
||||
addProperty(_textureQuality);
|
||||
addProperty(_renderOnlyOnMaster);
|
||||
|
||||
_textureQuality.onChange([this]() {
|
||||
_textureDimensionsIsDirty = true;
|
||||
@@ -151,7 +164,7 @@ glm::dvec2 ScreenSpaceSkyBrowser::fineTuneVector(glm::dvec2 drag) {
|
||||
glm::dvec2 resultRelativeOs = angleResult / openSpaceFOV;
|
||||
|
||||
// Convert to screen space coordinate system
|
||||
glm::dvec2 convertToScreenSpace{ (2 * skybrowser::windowRatio()), 2.f };
|
||||
glm::dvec2 convertToScreenSpace{ (2.f * skybrowser::windowRatio()), 2.f };
|
||||
glm::dvec2 result = - convertToScreenSpace * resultRelativeOs;
|
||||
return result;
|
||||
}
|
||||
@@ -228,12 +241,23 @@ void ScreenSpaceSkyBrowser::incrementallyAnimateToFov(float deltaTime) {
|
||||
void ScreenSpaceSkyBrowser::render() {
|
||||
WwtCommunicator::render();
|
||||
|
||||
draw(
|
||||
globalRotationMatrix() *
|
||||
translationMatrix() *
|
||||
localRotationMatrix() *
|
||||
scaleMatrix()
|
||||
);
|
||||
// If the sky browser only should be rendered on master, don't use the
|
||||
// global rotation
|
||||
if (_renderOnlyOnMaster && global::windowDelegate->isMaster()) {
|
||||
draw(
|
||||
translationMatrix() *
|
||||
localRotationMatrix() *
|
||||
scaleMatrix()
|
||||
);
|
||||
}
|
||||
else if(!_renderOnlyOnMaster) {
|
||||
draw(
|
||||
globalRotationMatrix() *
|
||||
translationMatrix() *
|
||||
localRotationMatrix() *
|
||||
scaleMatrix()
|
||||
);
|
||||
}
|
||||
|
||||
// Render a copy that is not interactive
|
||||
for (const std::unique_ptr<properties::Vec3Property>& copy : _renderCopies) {
|
||||
@@ -274,7 +298,7 @@ void ScreenSpaceSkyBrowser::setVerticalFovWithScroll(float scroll) {
|
||||
float x = _verticalFov;
|
||||
float zoomFactor = atan(x / 50.f) + exp(x / 40.f) - 0.999999f;
|
||||
float zoom = scroll > 0.f ? -zoomFactor : zoomFactor;
|
||||
_verticalFov = std::clamp(_verticalFov + zoom, 0.001f, 70.0f);
|
||||
_verticalFov = std::clamp(_verticalFov + zoom, 0.000001f, 70.0f);
|
||||
}
|
||||
|
||||
void ScreenSpaceSkyBrowser::bindTexture() {
|
||||
|
||||
@@ -92,24 +92,6 @@ void TargetBrowserPair::aimTargetGalactic(glm::dvec3 direction) {
|
||||
);
|
||||
}
|
||||
|
||||
void TargetBrowserPair::setFovTarget(double fov) {
|
||||
std::string id = _targetNode->identifier();
|
||||
std::string renderableId = _targetRenderable->identifier();
|
||||
// Uris for properties
|
||||
std::string sizeUri = "Scene." + id + "." + renderableId + ".Size";
|
||||
|
||||
double renderedFov = std::max(fov, _targetRenderable->smallestFov());
|
||||
double size = skybrowser::sizeFromFov(renderedFov, _targetNode->worldPosition());
|
||||
|
||||
std::string setValue = "openspace.setPropertyValueSingle('";
|
||||
|
||||
openspace::global::scriptEngine->queueScript(
|
||||
setValue + sizeUri + "', " + std::to_string(size) + ");",
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
_targetRenderable->setVerticalFov(renderedFov);
|
||||
}
|
||||
|
||||
bool TargetBrowserPair::checkMouseIntersection(const glm::vec2& mousePosition) {
|
||||
_selected = _browser->isIntersecting(mousePosition) ? _browser : nullptr;
|
||||
|
||||
@@ -162,7 +144,7 @@ void TargetBrowserPair::synchronizeAim() {
|
||||
// target, send the locked coordinates to wwt
|
||||
glm::dvec2 aim = targetDirectionEquatorial();
|
||||
_browser->setEquatorialAim(aim);
|
||||
setFovTarget(_browser->verticalFov());
|
||||
_targetRenderable->setVerticalFov(_browser->verticalFov());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,7 +158,7 @@ bool TargetBrowserPair::isEnabled() const {
|
||||
|
||||
void TargetBrowserPair::initialize() {
|
||||
_targetRenderable->setColor(_browser->borderColor());
|
||||
_targetRenderable->setDimensions(_browser->browserPixelDimensions());
|
||||
_targetRenderable->setDimensions(_browser->screenSpaceDimensions());
|
||||
_browser->updateBorderColor();
|
||||
}
|
||||
|
||||
@@ -271,7 +253,7 @@ void TargetBrowserPair::setIsSyncedWithWwt(bool isSynced) {
|
||||
|
||||
void TargetBrowserPair::setVerticalFov(float vfov) {
|
||||
_browser->setVerticalFov(vfov);
|
||||
setFovTarget(vfov);
|
||||
_targetRenderable->setVerticalFov(vfov);
|
||||
}
|
||||
|
||||
void TargetBrowserPair::setEquatorialAim(const glm::dvec2& aim) {
|
||||
@@ -290,6 +272,7 @@ void TargetBrowserPair::setBorderColor(const glm::ivec3& color) {
|
||||
|
||||
void TargetBrowserPair::setScreenSpaceSize(const glm::vec2& dimensions) {
|
||||
_browser->setScreenSpaceSize(dimensions);
|
||||
_targetRenderable->setDimensions(dimensions);
|
||||
}
|
||||
|
||||
void TargetBrowserPair::setVerticalFovWithScroll(float scroll) {
|
||||
@@ -303,7 +286,7 @@ void TargetBrowserPair::incrementallyAnimateToCoordinate(double deltaTime) {
|
||||
}
|
||||
else if (_browser->isAnimated()) {
|
||||
_browser->incrementallyAnimateToFov(static_cast<float>(deltaTime));
|
||||
setFovTarget(_browser->verticalFov());
|
||||
_targetRenderable->setVerticalFov(_browser->verticalFov());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -188,8 +188,9 @@ glm::dvec2 fovWindow() {
|
||||
|
||||
double angleBetweenVectors(const glm::dvec3& start, const glm::dvec3& end) {
|
||||
// Find smallest angle between the two vectors
|
||||
double cos = glm::dot(start, end) / (glm::length(start) * glm::length(end));
|
||||
return std::acos(cos);
|
||||
double cos = glm::dot(glm::normalize(start), glm::normalize(end));
|
||||
// Ensure cos is within defined interval [-1,1]
|
||||
return std::acos(std::clamp(cos, -1.0, 1.0));
|
||||
}
|
||||
|
||||
glm::dmat4 incrementalAnimationMatrix(const glm::dvec3& start, const glm::dvec3& end,
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/rendering/screenspacerenderable.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <openspace/util/coordinateconversion.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <ghoul/misc/assert.h>
|
||||
@@ -140,28 +141,13 @@ std::vector<documentation::Documentation> SpaceModule::documentations() const {
|
||||
}
|
||||
|
||||
scripting::LuaLibrary SpaceModule::luaLibrary() const {
|
||||
scripting::LuaLibrary res;
|
||||
res.name = "space";
|
||||
res.functions = {
|
||||
return {
|
||||
"space",
|
||||
{
|
||||
"convertFromRaDec",
|
||||
&space::luascriptfunctions::convertFromRaDec,
|
||||
"string/double, string/double, double",
|
||||
"Returns the cartesian world position of a ra dec coordinate with distance. "
|
||||
"If the coordinate is given as strings the format should be ra 'XhYmZs' and "
|
||||
"dec 'XdYmZs'. If the coordinate is given as numbers the values should be "
|
||||
"in degrees."
|
||||
},
|
||||
{
|
||||
"convertToRaDec",
|
||||
&space::luascriptfunctions::convertToRaDec,
|
||||
"double, double, double",
|
||||
"Returns the formatted ra, dec strings and distance for a given cartesian "
|
||||
"world coordinate."
|
||||
codegen::lua::ConvertFromRaDec,
|
||||
codegen::lua::ConvertToRaDec
|
||||
}
|
||||
};
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -22,47 +22,61 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/util/coordinateconversion.h>
|
||||
namespace {
|
||||
|
||||
namespace openspace::space::luascriptfunctions {
|
||||
|
||||
int convertFromRaDec(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::convertFromRaDec");
|
||||
/**
|
||||
* Returns the cartesian world position of a ra dec coordinate with distance. If the
|
||||
* coordinate is given as strings the format should be ra 'XhYmZs' and dec 'XdYmZs'. If
|
||||
* the coordinate is given as numbers the values should be in degrees.
|
||||
*/
|
||||
[[codegen::luawrap]] glm::dvec3 convertFromRaDec(
|
||||
std::variant<double, std::string> rightAscension,
|
||||
std::variant<double, std::string> declination,
|
||||
double distance)
|
||||
{
|
||||
using namespace openspace;
|
||||
|
||||
glm::dvec2 degrees = glm::dvec2(0.0);
|
||||
if (ghoul::lua::hasValue<std::string>(L, 1) &&
|
||||
ghoul::lua::hasValue<std::string>(L, 2))
|
||||
if (std::holds_alternative<double>(rightAscension) &&
|
||||
std::holds_alternative<double>(declination))
|
||||
{
|
||||
auto [ra, dec] = ghoul::lua::values<std::string, std::string>(L);
|
||||
degrees = icrsToDecimalDegrees(ra, dec);
|
||||
degrees = glm::dvec2(
|
||||
std::get<double>(rightAscension),
|
||||
std::get<double>(declination)
|
||||
);
|
||||
}
|
||||
else if (ghoul::lua::hasValue<double>(L, 1) && ghoul::lua::hasValue<double>(L, 2)) {
|
||||
auto [x, y] = ghoul::lua::values<double, double>(L);
|
||||
degrees.x = x;
|
||||
degrees.y = y;
|
||||
else if (std::holds_alternative<std::string>(rightAscension) &&
|
||||
std::holds_alternative<std::string>(declination))
|
||||
{
|
||||
degrees = icrsToDecimalDegrees(
|
||||
std::get<std::string>(rightAscension),
|
||||
std::get<std::string>(declination)
|
||||
);
|
||||
}
|
||||
else {
|
||||
throw ghoul::lua::LuaRuntimeException(
|
||||
throw ghoul::lua::LuaError(
|
||||
"Ra and Dec have to be of the same type, either String or Number"
|
||||
);
|
||||
}
|
||||
|
||||
double distance = ghoul::lua::value<double>(L);
|
||||
glm::dvec3 pos = icrsToGalacticCartesian(degrees.x, degrees.y, distance);
|
||||
ghoul::lua::push(L, pos);
|
||||
return 1;
|
||||
return pos;
|
||||
}
|
||||
|
||||
int convertToRaDec(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::convertToRaDec");
|
||||
auto [x, y, z] = ghoul::lua::values<double, double, double>(L);
|
||||
|
||||
/**
|
||||
* Returns the formatted ra, dec strings and distance for a given cartesian world
|
||||
* coordinate.
|
||||
*/
|
||||
[[codegen::luawrap]] std::tuple<std::string, std::string, double> convertToRaDec(double x,
|
||||
double y,
|
||||
double z)
|
||||
{
|
||||
using namespace openspace;
|
||||
glm::dvec3 deg = galacticCartesianToIcrs(x, y, z);
|
||||
std::pair<std::string, std::string> raDecPair = decimalDegreesToIcrs(deg.x, deg.y);
|
||||
|
||||
// Ra, Dec, Distance
|
||||
ghoul::lua::push(L, raDecPair.first, raDecPair.second, deg.z);
|
||||
return 3;
|
||||
return { raDecPair.first, raDecPair.second, deg.z };
|
||||
}
|
||||
|
||||
} // namespace openspace::space::luascriptfunctions
|
||||
#include "spacemodule_lua_codegen.cpp"
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -315,10 +315,27 @@ Dataset loadFile(std::filesystem::path path, SkipAllZeroLines skipAllZeroLines)
|
||||
str >> entry.position.x >> entry.position.y >> entry.position.z;
|
||||
allZero &= (entry.position == glm::vec3(0.0));
|
||||
|
||||
if (!str.good()) {
|
||||
throw ghoul::RuntimeError(fmt::format(
|
||||
"Error loading position information out of data line {} in file {}. "
|
||||
"Value was not a number",
|
||||
res.entries.size(), path
|
||||
));
|
||||
}
|
||||
|
||||
entry.data.resize(nDataValues);
|
||||
for (int i = 0; i < nDataValues; i += 1) {
|
||||
str >> entry.data[i];
|
||||
bool isGood = str.good();
|
||||
allZero &= (entry.data[i] == 0.0);
|
||||
|
||||
if (!str.good()) {
|
||||
throw ghoul::RuntimeError(fmt::format(
|
||||
"Error loading data value {} out of data line {} in file {}. "
|
||||
"Value was not a number",
|
||||
i, res.entries.size(), path
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if (skipAllZeroLines && allZero) {
|
||||
|
||||
@@ -28,10 +28,15 @@
|
||||
#include <modules/statemachine/include/statemachine.h>
|
||||
#include <modules/statemachine/include/transition.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/misc.h>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
|
||||
#include "statemachinemodule_lua.inl"
|
||||
|
||||
@@ -140,78 +145,20 @@ void StateMachineModule::saveToFile(const std::string& filename,
|
||||
}
|
||||
|
||||
scripting::LuaLibrary StateMachineModule::luaLibrary() const {
|
||||
scripting::LuaLibrary res;
|
||||
res.name = "statemachine";
|
||||
res.functions = {
|
||||
{
|
||||
"createStateMachine",
|
||||
&luascriptfunctions::createStateMachine,
|
||||
"table, table, [string]",
|
||||
"Creates a state machine from a list of states and transitions. See State "
|
||||
"and Transition documentation for details. The optional thrid argument is "
|
||||
"the identifier of the desired initial state. If left out, the first state "
|
||||
"in the list will be used."
|
||||
},
|
||||
return {
|
||||
"statemachine",
|
||||
{
|
||||
"destroyStateMachine",
|
||||
&luascriptfunctions::destroyStateMachine,
|
||||
"",
|
||||
"Destroys the current state machine and deletes all the memory."
|
||||
},
|
||||
{
|
||||
"goToState",
|
||||
&luascriptfunctions::goToState,
|
||||
"string",
|
||||
"Triggers a transition from the current state to the state with the given "
|
||||
"identifier. Requires that the specified string corresponds to an existing "
|
||||
"state, and that a transition between the two states exists."
|
||||
},
|
||||
{
|
||||
"setInitialState",
|
||||
&luascriptfunctions::setInitialState,
|
||||
"string",
|
||||
"Immediately sets the current state to the state with the given name, if "
|
||||
"it exists. This is done without doing a transition and completely ignores "
|
||||
"the previous state."
|
||||
},
|
||||
{
|
||||
"currentState",
|
||||
&luascriptfunctions::currentState,
|
||||
"",
|
||||
"Returns the string name of the current state that the statemachine is in."
|
||||
},
|
||||
{
|
||||
"possibleTransitions",
|
||||
&luascriptfunctions::possibleTransitions,
|
||||
"",
|
||||
"Returns a list with the identifiers of all the states that can be "
|
||||
"transitioned to from the current state."
|
||||
},
|
||||
{
|
||||
"canGoToState",
|
||||
&luascriptfunctions::canGoToState,
|
||||
"string",
|
||||
"Returns true if there is a defined transition between the current state and "
|
||||
"the given string name of a state, otherwise false"
|
||||
},
|
||||
{
|
||||
"printCurrentStateInfo",
|
||||
&luascriptfunctions::printCurrentStateInfo,
|
||||
"",
|
||||
"Prints information about the current state and possible transitions to the "
|
||||
"log."
|
||||
},
|
||||
{
|
||||
"saveToDotFile",
|
||||
&luascriptfunctions::saveToDotFile,
|
||||
"string, [string]",
|
||||
"Saves the current state machine to a .dot file as a directed graph. The "
|
||||
"resulting graph can be rendered using external tools such as Graphviz. "
|
||||
"The first parameter is the name of the file, and the second is an optional "
|
||||
"directory. If no directory is given, the file is saved to the temp folder."
|
||||
codegen::lua::CreateStateMachine,
|
||||
codegen::lua::DestroyStateMachine,
|
||||
codegen::lua::GoToState,
|
||||
codegen::lua::SetInitialState,
|
||||
codegen::lua::CurrentState,
|
||||
codegen::lua::PossibleTransitions,
|
||||
codegen::lua::CanGoToState,
|
||||
codegen::lua::PrintCurrentStateInfo,
|
||||
codegen::lua::SaveToDotFile
|
||||
}
|
||||
};
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<documentation::Documentation> StateMachineModule::documentations() const {
|
||||
|
||||
@@ -22,90 +22,91 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/statemachine/statemachinemodule.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/misc.h>
|
||||
#include <optional>
|
||||
|
||||
namespace openspace::luascriptfunctions {
|
||||
|
||||
int createStateMachine(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 2, 3 }, "lua::createStateMachine");
|
||||
auto [states, transitions, startState] = ghoul::lua::values<
|
||||
ghoul::Dictionary, ghoul::Dictionary, std::optional<std::string>
|
||||
>(L);
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* Creates a state machine from a list of states and transitions. See State and Transition
|
||||
* documentation for details. The optional thrid argument is the identifier of the desired
|
||||
* initial state. If left out, the first state in the list will be used.
|
||||
*/
|
||||
[[codegen::luawrap]] void createStateMachine(ghoul::Dictionary states,
|
||||
ghoul::Dictionary transitions,
|
||||
std::optional<std::string> startState)
|
||||
{
|
||||
using namespace openspace;
|
||||
StateMachineModule* module = global::moduleEngine->module<StateMachineModule>();
|
||||
module->initializeStateMachine(
|
||||
std::move(states),
|
||||
std::move(transitions),
|
||||
std::move(startState)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int destroyStateMachine(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::destroyStateMachine");
|
||||
|
||||
// Destroys the current state machine and deletes all the memory.
|
||||
[[codegen::luawrap]] void destroyStateMachine() {
|
||||
using namespace openspace;
|
||||
StateMachineModule* module = global::moduleEngine->module<StateMachineModule>();
|
||||
module->deinitializeStateMachine();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int goToState(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::goToState");
|
||||
std::string newState = ghoul::lua::value<std::string>(L);
|
||||
|
||||
/**
|
||||
* Triggers a transition from the current state to the state with the given identifier.
|
||||
* Requires that the specified string corresponds to an existing state, and that a
|
||||
* transition between the two states exists.
|
||||
*/
|
||||
[[codegen::luawrap]] void goToState(std::string newState) {
|
||||
using namespace openspace;
|
||||
StateMachineModule* module = global::moduleEngine->module<StateMachineModule>();
|
||||
module->transitionTo(newState);
|
||||
LINFOC("StateMachine", "Transitioning to " + newState);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int setInitialState(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::setStartState");
|
||||
std::string startState = ghoul::lua::value<std::string>(L);
|
||||
|
||||
/**
|
||||
* Immediately sets the current state to the state with the given name, if it exists. This
|
||||
* is done without doing a transition and completely ignores the previous state.
|
||||
*/
|
||||
[[codegen::luawrap]] void setInitialState(std::string startState) {
|
||||
using namespace openspace;
|
||||
StateMachineModule* module = global::moduleEngine->module<StateMachineModule>();
|
||||
module->setInitialState(startState);
|
||||
LINFOC("StateMachine", "Initial state set to: " + startState);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int currentState(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::currentState");
|
||||
|
||||
// Returns the string name of the current state that the statemachine is in.
|
||||
[[codegen::luawrap]] std::string currentState() {
|
||||
using namespace openspace;
|
||||
StateMachineModule* module = global::moduleEngine->module<StateMachineModule>();
|
||||
std::string currentState = module->currentState();
|
||||
ghoul::lua::push(L, std::move(currentState));
|
||||
return 1;
|
||||
return currentState;
|
||||
}
|
||||
|
||||
int possibleTransitions(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::possibleTransitions");
|
||||
|
||||
/**
|
||||
* Returns a list with the identifiers of all the states that can be transitioned to from
|
||||
* the current state.
|
||||
*/
|
||||
[[codegen::luawrap]] std::vector<std::string> possibleTransitions() {
|
||||
using namespace openspace;
|
||||
StateMachineModule* module = global::moduleEngine->module<StateMachineModule>();
|
||||
std::vector<std::string> transitions = module->possibleTransitions();
|
||||
ghoul::lua::push(L, transitions);
|
||||
return 1;
|
||||
return transitions;
|
||||
}
|
||||
|
||||
int canGoToState(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::canGoToState");
|
||||
std::string state = ghoul::lua::value<std::string>(L);
|
||||
|
||||
/**
|
||||
* Returns true if there is a defined transition between the current state and the given
|
||||
* string name of a state, otherwise false.
|
||||
*/
|
||||
[[codegen::luawrap]] bool canGoToState(std::string state) {
|
||||
using namespace openspace;
|
||||
StateMachineModule* module = global::moduleEngine->module<StateMachineModule>();
|
||||
ghoul::lua::push(L, module->canGoToState(state));
|
||||
return 1;
|
||||
bool canTransition = module->canGoToState(state);
|
||||
return canTransition;
|
||||
}
|
||||
|
||||
int printCurrentStateInfo(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::printCurrentStateInfo");
|
||||
|
||||
/**
|
||||
* Prints information about the current state and possible transitions to the log.
|
||||
*/
|
||||
[[codegen::luawrap]] void printCurrentStateInfo() {
|
||||
using namespace openspace;
|
||||
StateMachineModule* module = global::moduleEngine->module<StateMachineModule>();
|
||||
if (module->hasStateMachine()) {
|
||||
std::string currentState = module->currentState();
|
||||
@@ -119,24 +120,27 @@ int printCurrentStateInfo(lua_State* L) {
|
||||
else {
|
||||
LINFOC("StateMachine", "No state machine has been created");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int saveToDotFile(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 1, 2 }, "lua::saveToDotFile");
|
||||
auto [filename, directory] =
|
||||
ghoul::lua::values<std::string, std::optional<std::string>>(L);
|
||||
|
||||
/**
|
||||
* Saves the current state machine to a .dot file as a directed graph. The resulting graph
|
||||
* can be rendered using external tools such as Graphviz. The first parameter is the name
|
||||
* of the file, and the second is an optional directory. If no directory is given, the
|
||||
* file is saved to the temp folder.
|
||||
*/
|
||||
[[codegen::luawrap]] void saveToDotFile(std::string filename,
|
||||
std::optional<std::string> directory)
|
||||
{
|
||||
using namespace openspace;
|
||||
StateMachineModule* module = global::moduleEngine->module<StateMachineModule>();
|
||||
|
||||
if (directory.has_value()) {
|
||||
module->saveToFile(filename, *directory);
|
||||
}
|
||||
else {
|
||||
module->saveToFile(filename);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} //namespace openspace::luascriptfunctions
|
||||
#include "statemachinemodule_lua_codegen.cpp"
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -27,7 +27,9 @@
|
||||
#include <modules/sync/syncs/httpsynchronization.h>
|
||||
#include <modules/sync/syncs/urlsynchronization.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/globalscallbacks.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/rendering/screenspacerenderable.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
@@ -119,30 +121,13 @@ std::vector<documentation::Documentation> SyncModule::documentations() const {
|
||||
}
|
||||
|
||||
scripting::LuaLibrary SyncModule::luaLibrary() const {
|
||||
scripting::LuaLibrary res;
|
||||
res.name = "sync";
|
||||
res.functions = {
|
||||
return {
|
||||
"sync",
|
||||
{
|
||||
"syncResource",
|
||||
&luascriptfunctions::syncResource,
|
||||
"string, number",
|
||||
"Synchronizes the http resource identified by the name passed as the "
|
||||
"first parameter and the version provided as the second parameter. The "
|
||||
"application will hang while the data is being downloaded"
|
||||
},
|
||||
{
|
||||
"unsyncResource",
|
||||
&luascriptfunctions::unsyncResource,
|
||||
"string [, number]",
|
||||
"Unsynchronizes the http resources identified by the name passed as the "
|
||||
"first parameter by removing all data that was downloaded as part of the "
|
||||
"original synchronization. If the second parameter is provided, is it "
|
||||
"the version of the resources that is unsynchronized, if the parameter "
|
||||
"is not provided, all versions for the specified http resource are "
|
||||
"removed."
|
||||
codegen::lua::SyncResource,
|
||||
codegen::lua::UnsyncResource
|
||||
}
|
||||
};
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -22,14 +22,15 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
namespace {
|
||||
|
||||
namespace openspace::luascriptfunctions {
|
||||
|
||||
int syncResource(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::syncResource");
|
||||
auto [identifier, version] = ghoul::lua::values<std::string, double>(L);
|
||||
/**
|
||||
* Synchronizes the http resource identified by the name passed as the first parameter and
|
||||
* the version provided as the second parameter. The application will hang while the data
|
||||
* is being downloaded.
|
||||
*/
|
||||
[[codegen::luawrap]] bool syncResource(std::string identifier, int version) {
|
||||
using namespace openspace;
|
||||
|
||||
ghoul::Dictionary dict;
|
||||
dict.setValue("Type", std::string("HttpSynchronization"));
|
||||
@@ -45,14 +46,20 @@ int syncResource(lua_State* L) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||
}
|
||||
|
||||
ghoul::lua::push(L, sync->isResolved());
|
||||
return 1;
|
||||
bool isResolved = sync->isResolved();
|
||||
return isResolved;
|
||||
}
|
||||
|
||||
int unsyncResource(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 1, 2 }, "lua::unsyncResource");
|
||||
auto [identifier, version] = ghoul::lua::values<std::string, std::optional<int>>(L);
|
||||
|
||||
/**
|
||||
* Unsynchronizes the http resources identified by the name passed as the first parameter
|
||||
* by removing all data that was downloaded as part of the original synchronization. If
|
||||
* the second parameter is provided, is it the version of the resources that is
|
||||
* unsynchronized, if the parameter is not provided, all versions for the specified http
|
||||
* resource are removed.
|
||||
*/
|
||||
[[codegen::luawrap]] void unsyncResource(std::string identifier, std::optional<int> version) {
|
||||
using namespace openspace;
|
||||
|
||||
const SyncModule* module = global::moduleEngine->module<SyncModule>();
|
||||
std::filesystem::path sync = absPath(module->synchronizationRoot());
|
||||
std::filesystem::path base = sync / "http" / identifier;
|
||||
@@ -70,8 +77,8 @@ int unsyncResource(lua_State* L) {
|
||||
std::filesystem::remove_all(folder);
|
||||
std::filesystem::remove(base / syncFile);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace openspace::luascriptfunctions
|
||||
#include "syncmodule_lua_codegen.cpp"
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -55,14 +55,15 @@ cmake_policy(SET CMP0074 NEW)
|
||||
|
||||
# Specify the CEF distribution version.
|
||||
|
||||
# Release from 04/24/2019 verified to work on Windows.
|
||||
set(CEF_VERSION "73.1.13+g6e3c989+chromium-73.0.3683.75")
|
||||
# Release from 03/21/2022 verified to work on Windows.
|
||||
set(CEF_VERSION "99.2.12+g2977b3a+chromium-99.0.4844.74")
|
||||
|
||||
# Removing - micahnyc 03/21/2022
|
||||
# 73.1.13 has an issue on MacOS: The GUI freezing upon interaction.
|
||||
# Therefore, we fall back to 3.3578.1867 from 01/29/2019
|
||||
if (APPLE)
|
||||
set(CEF_VERSION "3.3578.1867.g0f6d65a")
|
||||
endif ()
|
||||
#if (APPLE)
|
||||
# set(CEF_VERSION "3.3578.1867.g0f6d65a")
|
||||
#endif ()
|
||||
|
||||
# CEF Sandbox is not working with the latest Visual Studio, so we disable it for now.
|
||||
if (WIN32)
|
||||
|
||||
@@ -456,12 +456,10 @@ if(OS_WINDOWS)
|
||||
# List of CEF binary files.
|
||||
set(CEF_BINARY_FILES
|
||||
chrome_elf.dll
|
||||
d3dcompiler_43.dll
|
||||
d3dcompiler_47.dll
|
||||
libcef.dll
|
||||
libEGL.dll
|
||||
libGLESv2.dll
|
||||
natives_blob.bin
|
||||
snapshot_blob.bin
|
||||
v8_context_snapshot.bin
|
||||
#swiftshader
|
||||
@@ -469,11 +467,9 @@ if(OS_WINDOWS)
|
||||
|
||||
# List of CEF resource files.
|
||||
set(CEF_RESOURCE_FILES
|
||||
cef.pak
|
||||
cef_100_percent.pak
|
||||
cef_200_percent.pak
|
||||
cef_extensions.pak
|
||||
devtools_resources.pak
|
||||
chrome_100_percent.pak
|
||||
chrome_200_percent.pak
|
||||
resources.pak
|
||||
icudtl.dat
|
||||
locales
|
||||
)
|
||||
|
||||
@@ -41,11 +41,17 @@ namespace openspace {
|
||||
|
||||
class DefaultBrowserLauncher : public CefLifeSpanHandler, public CefRequestHandler {
|
||||
public:
|
||||
bool OnBeforePopup(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
|
||||
const CefString& targetUrl, const CefString& targetFrameName,
|
||||
CefLifeSpanHandler::WindowOpenDisposition targetDisposition, bool userGesture,
|
||||
const CefPopupFeatures& popupFeatures, CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client, CefBrowserSettings& settings,
|
||||
bool OnBeforePopup(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
const CefString& targetUrl,
|
||||
const CefString& targetFrameName,
|
||||
CefLifeSpanHandler::WindowOpenDisposition targetDisposition,
|
||||
bool userGesture,
|
||||
const CefPopupFeatures& popupFeatures,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings,
|
||||
CefRefPtr<CefDictionaryValue>& extra_info,
|
||||
bool* noJavascriptAccess) override;
|
||||
|
||||
//bool OnOpenURLFromTab(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
|
||||
|
||||
@@ -48,7 +48,7 @@ BrowserInstance::BrowserInstance(WebRenderHandler* renderer,
|
||||
: _renderHandler(renderer)
|
||||
, _keyboardHandler(keyboardHandler)
|
||||
{
|
||||
_client = new BrowserClient(_renderHandler, _keyboardHandler);
|
||||
_client = new BrowserClient(_renderHandler.get(), _keyboardHandler.get());
|
||||
|
||||
CefWindowInfo windowInfo;
|
||||
windowInfo.SetAsWindowless(nullptr);
|
||||
@@ -62,6 +62,7 @@ BrowserInstance::BrowserInstance(WebRenderHandler* renderer,
|
||||
_client.get(),
|
||||
url,
|
||||
browserSettings,
|
||||
nullptr,
|
||||
nullptr
|
||||
);
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ bool DefaultBrowserLauncher::OnBeforePopup(CefRefPtr<CefBrowser>, CefRefPtr<CefF
|
||||
CefLifeSpanHandler::WindowOpenDisposition,
|
||||
bool, const CefPopupFeatures&, CefWindowInfo&,
|
||||
CefRefPtr<CefClient>&, CefBrowserSettings&,
|
||||
CefRefPtr<CefDictionaryValue>&,
|
||||
bool*)
|
||||
{
|
||||
// never permit CEF popups, always launch in default browser
|
||||
|
||||
@@ -94,8 +94,8 @@ ScreenSpaceBrowser::ScreenSpaceBrowser(const ghoul::Dictionary& dictionary)
|
||||
_renderHandler = new ScreenSpaceRenderHandler;
|
||||
_keyboardHandler = new WebKeyboardHandler();
|
||||
_browserInstance = std::make_unique<BrowserInstance>(
|
||||
_renderHandler,
|
||||
_keyboardHandler
|
||||
_renderHandler.get(),
|
||||
_keyboardHandler.get()
|
||||
);
|
||||
|
||||
_url.onChange([this]() { _isUrlDirty = true; });
|
||||
|
||||
@@ -42,8 +42,10 @@ void WebBrowserApp::OnContextCreated(CefRefPtr<CefBrowser>, CefRefPtr<CefFrame>,
|
||||
void WebBrowserApp::OnBeforeCommandLineProcessing(const CefString&,
|
||||
CefRefPtr<CefCommandLine> commandLine)
|
||||
{
|
||||
commandLine->AppendSwitch("disable-gpu");
|
||||
commandLine->AppendSwitch("disable-gpu-compositing");
|
||||
commandLine->AppendSwitch("use-gl=desktop");
|
||||
commandLine->AppendSwitch("ignore-gpu-blacklist");
|
||||
commandLine->AppendSwitch("log-gpu-control-list-decisions");
|
||||
|
||||
commandLine->AppendSwitch("enable-begin-frame-scheduling");
|
||||
commandLine->AppendSwitchWithValue("autoplay-policy", "no-user-gesture-required");
|
||||
}
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
openspace.documentation = {
|
||||
{
|
||||
Name = "markInterestingNodes",
|
||||
Arguments = "List of nodes",
|
||||
Arguments = { sceneGraphNode = "[ String ]" },
|
||||
Documentation = "This function marks the scene graph nodes identified by name " ..
|
||||
"as interesting, which will provide shortcut access to focus buttons and " ..
|
||||
"featured properties."
|
||||
},
|
||||
{
|
||||
Name = "markInterestingTimes",
|
||||
Arguments = "List of { Name = '...', Time = '...' } or { '<name>', '<time>' }",
|
||||
Arguments = { times = "[ Table ]" },
|
||||
Documentation = "This function marks interesting times for the current scene, " ..
|
||||
"which will create shortcuts for a quick access."
|
||||
},
|
||||
{
|
||||
Name = "removeInterestingNodes",
|
||||
Arguments = "List of nodes",
|
||||
Arguments = { sceneGraphNode = "[ String ]" },
|
||||
Documentation = "This function removes unmarks the scene graph nodes " ..
|
||||
"identified by name as interesting, thus removing the shortcuts from the " ..
|
||||
"features properties list."
|
||||
},
|
||||
{
|
||||
Name = "setDefaultGuiSorting",
|
||||
Arguments = "",
|
||||
Arguments = {},
|
||||
Documentation = "This function sets the default GUI sorting for the space " ..
|
||||
"environment to increasing size, from solar system, through Milky Way, " ..
|
||||
"Universe and finishing with other elements"
|
||||
},
|
||||
{
|
||||
Name = "setDefaultDashboard",
|
||||
Arguments = "",
|
||||
Arguments = {},
|
||||
Documentation = "This function sets the default values for the dashboard " ..
|
||||
"consisting of 'DashboardItemDate', 'DashboardItemSimulationIncrement', " ..
|
||||
"'DashboardItemDistance', 'DashboardItemFramerate', and " ..
|
||||
@@ -36,7 +36,7 @@ openspace.documentation = {
|
||||
},
|
||||
{
|
||||
Name = "rebindKey",
|
||||
Arguments = "string, string",
|
||||
Arguments = { oldKey = "String", newKey = "String" },
|
||||
Documentation = "Rebinds all scripts from the old key (first argument) to the " ..
|
||||
"new key (second argument)."
|
||||
}
|
||||
|
||||
@@ -158,6 +158,7 @@ set(OPENSPACE_SOURCE
|
||||
${OPENSPACE_BASE_DIR}/src/scripting/scriptscheduler.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/scripting/scriptscheduler_lua.inl
|
||||
${OPENSPACE_BASE_DIR}/src/scripting/systemcapabilitiesbinding.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/scripting/systemcapabilitiesbinding_lua.inl
|
||||
${OPENSPACE_BASE_DIR}/src/util/blockplaneintersectiongeometry.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/boxgeometry.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/collisionhelper.cpp
|
||||
|
||||
@@ -243,7 +243,7 @@ std::future<DownloadManager::MemoryFile> DownloadManager::fetchFile(
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); // NOLINT
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); // NOLINT
|
||||
// NOLINTNEXTLINE
|
||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, "OpenSpace"); // NOLINT
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, reinterpret_cast<void*>(&file));
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeMemoryCallback); // NOLINT
|
||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5L); // NOLINT
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/moduleregistration.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
@@ -168,12 +169,7 @@ scripting::LuaLibrary ModuleEngine::luaLibrary() {
|
||||
return {
|
||||
"modules",
|
||||
{
|
||||
{
|
||||
"isLoaded",
|
||||
&luascriptfunctions::isLoaded,
|
||||
"string",
|
||||
"Checks whether a specific module is loaded"
|
||||
}
|
||||
codegen::lua::IsLoaded
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,28 +22,20 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <ghoul/lua/ghoul_lua.h>
|
||||
namespace {
|
||||
|
||||
namespace openspace::luascriptfunctions {
|
||||
// Checks whether the passed OpenSpaceModule is loaded.
|
||||
[[codegen::luawrap]] bool isLoaded(std::string moduleName) {
|
||||
using namespace openspace;
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* isLoaded(string):
|
||||
* Checks whether the passed OpenSpaceModule is loaded or not
|
||||
*/
|
||||
int isLoaded(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::isLoaded");
|
||||
const std::string name = ghoul::lua::value<std::string>(L);
|
||||
|
||||
const std::vector<OpenSpaceModule*>& modules = global::moduleEngine->modules();
|
||||
const auto it = std::find_if(
|
||||
modules.cbegin(), modules.cend(),
|
||||
[name](OpenSpaceModule* module) { return module->identifier() == name; }
|
||||
);
|
||||
|
||||
ghoul::lua::push(L, it != modules.cend());
|
||||
return 1;
|
||||
for (OpenSpaceModule* module : global::moduleEngine->modules()) {
|
||||
if (module->identifier() == moduleName) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace openspace::luascriptfunctions
|
||||
#include "moduleengine_lua_codegen.cpp"
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <openspace/documentation/core_registration.h>
|
||||
#include <openspace/documentation/documentationengine.h>
|
||||
#include <openspace/engine/configuration.h>
|
||||
#include <openspace/engine/downloadmanager.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/globalscallbacks.h>
|
||||
#include <openspace/engine/logfactory.h>
|
||||
@@ -50,6 +51,7 @@
|
||||
#include <openspace/rendering/loadingscreen.h>
|
||||
#include <openspace/rendering/luaconsole.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/asset.h>
|
||||
#include <openspace/scene/assetmanager.h>
|
||||
#include <openspace/scene/profile.h>
|
||||
@@ -71,6 +73,7 @@
|
||||
#include <openspace/util/timemanager.h>
|
||||
#include <openspace/util/transformationmanager.h>
|
||||
#include <ghoul/ghoul.h>
|
||||
#include <ghoul/filesystem/cachemanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/font/fontmanager.h>
|
||||
#include <ghoul/font/fontrenderer.h>
|
||||
@@ -101,7 +104,7 @@
|
||||
namespace {
|
||||
// Helper structs for the visitor pattern of the std::variant
|
||||
template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
|
||||
template <class... Ts> overloaded(Ts...)->overloaded<Ts...>;
|
||||
template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
|
||||
|
||||
constexpr const char* _loggerCat = "OpenSpaceEngine";
|
||||
|
||||
@@ -180,6 +183,10 @@ void OpenSpaceEngine::initialize() {
|
||||
LTRACE("OpenSpaceEngine::initialize(begin)");
|
||||
|
||||
global::initialize();
|
||||
// Initialize the general capabilities component
|
||||
SysCap.addComponent(
|
||||
std::make_unique<ghoul::systemcapabilities::GeneralCapabilitiesComponent>()
|
||||
);
|
||||
|
||||
_printEvents = global::configuration->isPrintingEvents;
|
||||
|
||||
@@ -403,11 +410,8 @@ void OpenSpaceEngine::initializeGL() {
|
||||
glbinding::Binding::initialize(global::windowDelegate->openGLProcedureAddress);
|
||||
//glbinding::Binding::useCurrentContext();
|
||||
|
||||
LDEBUG("Adding system components");
|
||||
LDEBUG("Adding OpenGL capabilities components");
|
||||
// Detect and log OpenCL and OpenGL versions and available devices
|
||||
SysCap.addComponent(
|
||||
std::make_unique<ghoul::systemcapabilities::GeneralCapabilitiesComponent>()
|
||||
);
|
||||
SysCap.addComponent(
|
||||
std::make_unique<ghoul::systemcapabilities::OpenGLCapabilitiesComponent>()
|
||||
);
|
||||
@@ -1797,61 +1801,14 @@ scripting::LuaLibrary OpenSpaceEngine::luaLibrary() {
|
||||
return {
|
||||
"",
|
||||
{
|
||||
{
|
||||
"toggleShutdown",
|
||||
&luascriptfunctions::toggleShutdown,
|
||||
"",
|
||||
"Toggles the shutdown mode that will close the application after the "
|
||||
"count down timer is reached"
|
||||
},
|
||||
{
|
||||
"writeDocumentation",
|
||||
&luascriptfunctions::writeDocumentation,
|
||||
"",
|
||||
"Writes out documentation files"
|
||||
},
|
||||
{
|
||||
"downloadFile",
|
||||
&luascriptfunctions::downloadFile,
|
||||
"",
|
||||
"Downloads a file from Lua scope"
|
||||
},
|
||||
{
|
||||
"setScreenshotFolder",
|
||||
&luascriptfunctions::setScreenshotFolder,
|
||||
"string",
|
||||
"Sets the folder used for storing screenshots or session recording frames"
|
||||
},
|
||||
{
|
||||
"addTag",
|
||||
&luascriptfunctions::addTag,
|
||||
"string, string",
|
||||
"Adds a tag (second argument) to a scene graph node (first argument)"
|
||||
},
|
||||
{
|
||||
"removeTag",
|
||||
&luascriptfunctions::removeTag,
|
||||
"string, string",
|
||||
"Removes a tag (second argument) from a scene graph node (first argument)"
|
||||
},
|
||||
{
|
||||
"createSingleColorImage",
|
||||
&luascriptfunctions::createSingleColorImage,
|
||||
"string, vec3",
|
||||
"Creates a 1 pixel image with a certain color in the cache folder and "
|
||||
"returns the path to the file. If a cached file with the given name "
|
||||
"already exists, the path to that file is returned. The first argument "
|
||||
"is the name of the file, without extension. The second is the RGB "
|
||||
"color, given as {r, g, b} with values between 0 and 1."
|
||||
},
|
||||
{
|
||||
"isMaster",
|
||||
&luascriptfunctions::isMaster,
|
||||
"",
|
||||
"Returns whether the current OpenSpace instance is the master node of a "
|
||||
"cluster configuration. If this instance is not part of a cluster, this "
|
||||
"function also returns 'true'."
|
||||
}
|
||||
codegen::lua::ToggleShutdown,
|
||||
codegen::lua::WriteDocumentation,
|
||||
codegen::lua::SetScreenshotFolder,
|
||||
codegen::lua::AddTag,
|
||||
codegen::lua::RemoveTag,
|
||||
codegen::lua::DownloadFile,
|
||||
codegen::lua::CreateSingleColorImage,
|
||||
codegen::lua::IsMaster
|
||||
},
|
||||
{
|
||||
absPath("${SCRIPTS}/core_scripts.lua")
|
||||
|
||||
@@ -22,48 +22,29 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/downloadmanager.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/properties/triggerproperty.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <ghoul/filesystem/cachemanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <filesystem>
|
||||
|
||||
namespace openspace::luascriptfunctions {
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* toggleShutdown():
|
||||
* Toggles the shutdown mode that will close the application after the countdown timer is
|
||||
* reached
|
||||
* Toggles the shutdown mode that will close the application after the countdown timer
|
||||
* is reached
|
||||
*/
|
||||
int toggleShutdown(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::toggleShutdown");
|
||||
global::openSpaceEngine->toggleShutdownMode();
|
||||
return 0;
|
||||
[[codegen::luawrap]] void toggleShutdown() {
|
||||
openspace::global::openSpaceEngine->toggleShutdownMode();
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* writeDocumentation():
|
||||
* Writes out documentation files
|
||||
*/
|
||||
int writeDocumentation(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::writeDocumentation");
|
||||
global::openSpaceEngine->writeStaticDocumentation();
|
||||
global::openSpaceEngine->writeSceneDocumentation();
|
||||
return 0;
|
||||
[[codegen::luawrap]] void writeDocumentation() {
|
||||
openspace::global::openSpaceEngine->writeStaticDocumentation();
|
||||
openspace::global::openSpaceEngine->writeSceneDocumentation();
|
||||
}
|
||||
|
||||
int setScreenshotFolder(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::setScreenshotFolder");
|
||||
const std::string arg = ghoul::lua::value<std::string>(L);
|
||||
// Sets the folder used for storing screenshots or session recording frames
|
||||
[[codegen::luawrap]] void setScreenshotFolder(std::string newFolder) {
|
||||
using namespace openspace;
|
||||
|
||||
std::filesystem::path folder = absPath(arg);
|
||||
std::filesystem::path folder = absPath(newFolder);
|
||||
if (!std::filesystem::exists(folder)) {
|
||||
std::filesystem::create_directory(folder);
|
||||
}
|
||||
@@ -75,108 +56,90 @@ int setScreenshotFolder(lua_State* L) {
|
||||
);
|
||||
|
||||
global::windowDelegate->setScreenshotFolder(folder.string());
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* addTag()
|
||||
* Adds a Tag to a SceneGraphNode
|
||||
*/
|
||||
int addTag(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::addTag");
|
||||
auto [uri, tag] = ghoul::lua::values<std::string, std::string>(L);
|
||||
// Adds a Tag to a SceneGraphNode identified by the provided uri
|
||||
[[codegen::luawrap]] void addTag(std::string uri, std::string tag) {
|
||||
using namespace openspace;
|
||||
|
||||
SceneGraphNode* node = global::renderEngine->scene()->sceneGraphNode(uri);
|
||||
if (!node) {
|
||||
return ghoul::lua::luaError(L, fmt::format("Unknown scene graph node '{}'", uri));
|
||||
throw ghoul::lua::LuaError(fmt::format("Unknown scene graph node '{}'", uri));
|
||||
}
|
||||
|
||||
node->addTag(std::move(tag));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* removeTag():
|
||||
* Removes a tag from a SceneGraphNode
|
||||
*/
|
||||
int removeTag(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::removeTag");
|
||||
auto [uri, tag] = ghoul::lua::values<std::string, std::string>(L);
|
||||
// Removes a tag (second argument) from a scene graph node (first argument)
|
||||
[[codegen::luawrap]] void removeTag(std::string uri, std::string tag) {
|
||||
using namespace openspace;
|
||||
|
||||
SceneGraphNode* node = global::renderEngine->scene()->sceneGraphNode(uri);
|
||||
if (!node) {
|
||||
return ghoul::lua::luaError(L, fmt::format("Unknown scene graph node '{}'", uri));
|
||||
throw ghoul::lua::LuaError(fmt::format("Unknown scene graph node '{}'", uri));
|
||||
}
|
||||
|
||||
node->removeTag(tag);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* downloadFile():
|
||||
* Downloads a file from Lua interpreter
|
||||
*/
|
||||
int downloadFile(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 2, 3 }, "lua::downloadFile");
|
||||
auto [uri, savePath, waitForComplete] =
|
||||
ghoul::lua::values<std::string, std::string, std::optional<bool>>(L);
|
||||
waitForComplete = waitForComplete.value_or(false);
|
||||
// Downloads a file from Lua interpreter
|
||||
[[codegen::luawrap]] void downloadFile(std::string url, std::string savePath,
|
||||
bool waitForCompletion = false)
|
||||
{
|
||||
using namespace openspace;
|
||||
|
||||
LINFOC("OpenSpaceEngine", fmt::format("Downloading file from {}", uri));
|
||||
LINFOC("OpenSpaceEngine", fmt::format("Downloading file from {}", url));
|
||||
std::shared_ptr<DownloadManager::FileFuture> future =
|
||||
global::downloadManager->downloadFile(
|
||||
uri,
|
||||
url,
|
||||
savePath,
|
||||
DownloadManager::OverrideFile::Yes,
|
||||
DownloadManager::FailOnError::Yes,
|
||||
5
|
||||
);
|
||||
|
||||
if (waitForComplete) {
|
||||
while (!future->isFinished && future->errorMessage.empty() ) {
|
||||
//just wait
|
||||
if (waitForCompletion) {
|
||||
while (!future->isFinished && future->errorMessage.empty()) {
|
||||
// just wait
|
||||
LTRACEC("OpenSpaceEngine", fmt::format("waiting {}", future->errorMessage));
|
||||
}
|
||||
}
|
||||
|
||||
if (!future || !future->isFinished) {
|
||||
return ghoul::lua::luaError(
|
||||
L,
|
||||
throw ghoul::lua::LuaError(
|
||||
future ? "Download failed: " + future->errorMessage : "Download failed"
|
||||
);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Closing the anoynmous namespace here to allow a unit test to access this function
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* createSingleColorImage():
|
||||
* Creates a one pixel image with a given color and returns the path to the cached file
|
||||
* Creates a 1 pixel image with a certain color in the cache folder and returns the path
|
||||
* to the file. If a cached file with the given name already exists, the path to that file
|
||||
* is returned. The first argument is the name of the file, without extension. The second
|
||||
* is the RGB color, given as {r, g, b} with values between 0 and 1.
|
||||
*/
|
||||
int createSingleColorImage(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::createSingleColorImage");
|
||||
auto [name, d] = ghoul::lua::values<std::string, ghoul::Dictionary>(L);
|
||||
[[codegen::luawrap]] std::filesystem::path createSingleColorImage(std::string name,
|
||||
glm::dvec3 color)
|
||||
{
|
||||
using namespace openspace;
|
||||
|
||||
// @TODO (emmbr 2020-12-18) Verify that the input dictionary is a vec3
|
||||
// Would like to clean this up with a more direct use of the Verifier in the future
|
||||
const std::string& key = "color";
|
||||
ghoul::Dictionary colorDict;
|
||||
colorDict.setValue(key, d);
|
||||
colorDict.setValue(key, color);
|
||||
documentation::TestResult res = documentation::Color3Verifier()(colorDict, key);
|
||||
|
||||
if (!res.success) {
|
||||
return ghoul::lua::luaError(
|
||||
L,
|
||||
throw ghoul::lua::LuaError(
|
||||
"Invalid color. Expected three double values {r, g, b} in range 0 to 1"
|
||||
);
|
||||
}
|
||||
|
||||
const glm::dvec3 color = colorDict.value<glm::dvec3>(key);
|
||||
|
||||
std::filesystem::path fileName = FileSys.cacheManager()->cachedFilename(
|
||||
name + ".ppm",
|
||||
""
|
||||
@@ -184,8 +147,7 @@ int createSingleColorImage(lua_State* L) {
|
||||
const bool hasCachedFile = std::filesystem::is_regular_file(fileName);
|
||||
if (hasCachedFile) {
|
||||
LDEBUGC("OpenSpaceEngine", fmt::format("Cached file '{}' used", fileName));
|
||||
ghoul::lua::push(L, fileName);
|
||||
return 1;
|
||||
return fileName;
|
||||
}
|
||||
else {
|
||||
// Write the color to a ppm file
|
||||
@@ -201,25 +163,30 @@ int createSingleColorImage(lua_State* L) {
|
||||
img[1] = static_cast<unsigned char>(255 * color.g);
|
||||
img[2] = static_cast<unsigned char>(255 * color.b);
|
||||
|
||||
if (ppmFile.is_open()) {
|
||||
ppmFile << "P6" << std::endl;
|
||||
ppmFile << width << " " << height << std::endl;
|
||||
ppmFile << 255 << std::endl;
|
||||
ppmFile.write(reinterpret_cast<char*>(&img[0]), size * 3);
|
||||
ppmFile.close();
|
||||
ghoul::lua::push(L, fileName);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return ghoul::lua::luaError(L, "Could not open ppm file for writing.");
|
||||
if (!ppmFile.is_open()) {
|
||||
throw ghoul::lua::LuaError("Could not open ppm file for writing");
|
||||
}
|
||||
|
||||
ppmFile << "P6" << std::endl;
|
||||
ppmFile << width << " " << height << std::endl;
|
||||
ppmFile << 255 << std::endl;
|
||||
ppmFile.write(reinterpret_cast<char*>(img.data()), size * 3);
|
||||
ppmFile.close();
|
||||
return fileName;
|
||||
}
|
||||
}
|
||||
|
||||
int isMaster(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::isMaster");
|
||||
ghoul::lua::push(L, global::windowDelegate->isMaster());
|
||||
return 1;
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* Returns whether the current OpenSpace instance is the master node of a cluster
|
||||
* configuration. If this instance is not part of a cluster, this function also returns
|
||||
* 'true'.
|
||||
*/
|
||||
[[codegen::luawrap]] bool isMaster() {
|
||||
return openspace::global::windowDelegate->isMaster();
|
||||
}
|
||||
|
||||
} // namespace openspace::luascriptfunctions
|
||||
#include "openspaceengine_lua_codegen.cpp"
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -107,25 +107,13 @@ void EventEngine::triggerActions() const {
|
||||
}
|
||||
|
||||
scripting::LuaLibrary EventEngine::luaLibrary() {
|
||||
scripting::LuaLibrary res;
|
||||
res.name = "event";
|
||||
res.functions.push_back({
|
||||
"registerEventAction",
|
||||
&luascriptfunctions::registerEventAction,
|
||||
"string, string [, table]",
|
||||
"Registers an action (second parameter) to be executed whenever an event (first "
|
||||
"parameter) is encountered. If the optional third parameter is provided, it "
|
||||
"describes a filter that the event is being checked against and only if it "
|
||||
"passes the filter, the action is triggered"
|
||||
});
|
||||
res.functions.push_back({
|
||||
"unregisterEventAction",
|
||||
&luascriptfunctions::unregisterEventAction,
|
||||
"string, string [, table]",
|
||||
"Unregisters a specific combination of event (first parameter), action (second "
|
||||
"parameter), and potentially a filter (optional third argument)"
|
||||
});
|
||||
return res;
|
||||
return {
|
||||
"event",
|
||||
{
|
||||
codegen::lua::RegisterEventAction,
|
||||
codegen::lua::UnregisterEventAction
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -22,28 +22,32 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
namespace openspace::luascriptfunctions {
|
||||
|
||||
int registerEventAction(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 2, 3 }, "lua::registerEventAction");
|
||||
auto [event, action, filter] =
|
||||
ghoul::lua::values<std::string, std::string, std::optional<ghoul::Dictionary>>(L);
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* Registers an action to be executed whenever an event is encountered. If the optional
|
||||
* third parameter is provided, it describes a filter that the event is being checked
|
||||
* against and only if it passes the filter, the action is triggered.
|
||||
*/
|
||||
[[codegen::luawrap]] void registerEventAction(std::string event, std::string action,
|
||||
std::optional<ghoul::Dictionary> filter)
|
||||
{
|
||||
using namespace openspace;
|
||||
events::Event::Type type = events::fromString(event);
|
||||
|
||||
global::eventEngine->registerEventAction(type, std::move(action), std::move(filter));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unregisterEventAction(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 2, 3 }, "lua::unregisterEventAction");
|
||||
auto [event, action, filter] =
|
||||
ghoul::lua::values<std::string, std::string, std::optional<ghoul::Dictionary>>(L);
|
||||
|
||||
/**
|
||||
* Unregisters a specific combination of event, action, and potentially a filter.
|
||||
*/
|
||||
[[codegen::luawrap]] void unregisterEventAction(std::string event, std::string action,
|
||||
std::optional<ghoul::Dictionary> filter)
|
||||
{
|
||||
using namespace openspace;
|
||||
events::Event::Type type = events::fromString(event);
|
||||
|
||||
global::eventEngine->unregisterEventAction(type, action, filter);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace openspace::luascriptfunctions
|
||||
#include "eventengine_lua_codegen.cpp"
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <openspace/interaction/actionmanager.h>
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
@@ -110,55 +111,12 @@ scripting::LuaLibrary ActionManager::luaLibrary() {
|
||||
return {
|
||||
"action",
|
||||
{
|
||||
{
|
||||
"hasAction",
|
||||
&luascriptfunctions::hasAction,
|
||||
"string",
|
||||
"Checks if the passed identifier corresponds to an action"
|
||||
},
|
||||
{
|
||||
"removeAction",
|
||||
&luascriptfunctions::removeAction,
|
||||
"(string, table)",
|
||||
"Removes an existing action from the list of possible actions. The "
|
||||
"action is identifies either by the passed name, or if it is a table, "
|
||||
"the value behind the 'Identifier' key is extract and used instead"
|
||||
},
|
||||
{
|
||||
"registerAction",
|
||||
&luascriptfunctions::registerAction,
|
||||
"table",
|
||||
"Registers a new action. The table must at least contain the keys "
|
||||
"'Identifier' and 'Command' represeting the unique identifier and the "
|
||||
"Lua script that belong to this new action. Optional keys are 'Name' for "
|
||||
"a human-readable name, 'Documentation' for a description of what the "
|
||||
"action does, 'GuiPath' for a path used for grouping a user interface. "
|
||||
"All of these parameters must be strings. The last parameter is "
|
||||
"'IsLocal' and represents whether the action should be executed locally "
|
||||
"(= false) or remotely (= true, the default)"
|
||||
},
|
||||
{
|
||||
"action",
|
||||
&luascriptfunctions::action,
|
||||
"string",
|
||||
"Returns information about the action as a table with the keys "
|
||||
"'Identifier', 'Command', 'Name', 'Documentation', 'GuiPath', and "
|
||||
"'Synchronization'"
|
||||
},
|
||||
{
|
||||
"actions",
|
||||
&luascriptfunctions::actions,
|
||||
"",
|
||||
"Returns all registered actions in the system as a table of tables each "
|
||||
"containing the keys 'Identifier', 'Command', 'Name', 'Documentation', "
|
||||
"'GuiPath', and 'Synchronization'"
|
||||
},
|
||||
{
|
||||
"triggerAction",
|
||||
&luascriptfunctions::triggerAction,
|
||||
"string",
|
||||
"Triggers the action given by the specified identifier"
|
||||
}
|
||||
codegen::lua::HasAction,
|
||||
codegen::lua::RemoveAction,
|
||||
codegen::lua::RegisterAction,
|
||||
codegen::lua::Action,
|
||||
codegen::lua::Actions,
|
||||
codegen::lua::TriggerAction
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,47 +22,35 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
|
||||
namespace openspace::luascriptfunctions {
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* hasAction():
|
||||
* Checks if the passed identifier corresponds to an action.
|
||||
*/
|
||||
int hasAction(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::hasAction");
|
||||
const std::string identifier = ghoul::lua::value<std::string>(L);
|
||||
namespace {
|
||||
|
||||
// Checks if the passed identifier corresponds to an action.
|
||||
[[codegen::luawrap]] bool hasAction(std::string identifier) {
|
||||
if (identifier.empty()) {
|
||||
return ghoul::lua::luaError(L, "Identifier must not be empty");
|
||||
throw ghoul::lua::LuaError("Identifier must not be empty");
|
||||
}
|
||||
|
||||
const bool res = global::actionManager->hasAction(identifier);
|
||||
ghoul::lua::push(L, res);
|
||||
return 1;
|
||||
const bool res = openspace::global::actionManager->hasAction(identifier);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* removeAction():
|
||||
* Removes an existing action from the list of possible actions.
|
||||
*/
|
||||
int removeAction(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::removeAction");
|
||||
std::variant v = ghoul::lua::value<std::variant<std::string, ghoul::Dictionary>>(L);
|
||||
* Removes an existing action from the list of possible actions.The action is identifies
|
||||
* either by the passed name, or if it is a table, the value behind the 'Identifier' key
|
||||
* is extract and used instead.
|
||||
*/
|
||||
[[codegen::luawrap]] void removeAction(
|
||||
std::variant<std::string, ghoul::Dictionary> action)
|
||||
{
|
||||
using namespace openspace;
|
||||
|
||||
std::string identifier;
|
||||
if (std::holds_alternative<std::string>(v)) {
|
||||
identifier = std::get<std::string>(v);
|
||||
if (std::holds_alternative<std::string>(action)) {
|
||||
identifier = std::get<std::string>(action);
|
||||
}
|
||||
else {
|
||||
ghoul_assert(std::holds_alternative<ghoul::Dictionary>(v), "Missing case");
|
||||
ghoul::Dictionary d = std::get<ghoul::Dictionary>(v);
|
||||
ghoul::Dictionary d = std::get<ghoul::Dictionary>(action);
|
||||
if (!d.hasValue<std::string>("Identifier")) {
|
||||
return ghoul::lua::luaError(
|
||||
L,
|
||||
throw ghoul::lua::LuaError(
|
||||
"Table passed to removeAction does not contain an Identifier"
|
||||
);
|
||||
}
|
||||
@@ -70,22 +58,18 @@ int removeAction(lua_State* L) {
|
||||
}
|
||||
|
||||
if (identifier.empty()) {
|
||||
return ghoul::lua::luaError(L, "Identifier must not be empty");
|
||||
throw ghoul::lua::LuaError("Identifier must not be empty");
|
||||
}
|
||||
if (!global::actionManager->hasAction(identifier)) {
|
||||
return ghoul::lua::luaError(
|
||||
L,
|
||||
throw ghoul::lua::LuaError(
|
||||
fmt::format("Identifier '{}' for action not found", identifier)
|
||||
);
|
||||
}
|
||||
|
||||
global::actionManager->removeAction(identifier);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* registerAction():
|
||||
* Registers a new action. The first argument is the identifier which cannot have been
|
||||
* used to register a previous action before, the second argument is the Lua command that
|
||||
* is to be executed, and the optional third argument is the name used in a user-interface
|
||||
@@ -94,154 +78,124 @@ int removeAction(lua_State* L) {
|
||||
* whether the action should be executed locally (= false) or remotely (= true, the
|
||||
* default).
|
||||
*/
|
||||
int registerAction(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::registerAction");
|
||||
const ghoul::Dictionary d = ghoul::lua::value<ghoul::Dictionary>(L);
|
||||
[[codegen::luawrap]] void registerAction(ghoul::Dictionary action) {
|
||||
using namespace openspace;
|
||||
|
||||
if (!d.hasValue<std::string>("Identifier")) {
|
||||
return ghoul::lua::luaError(L, "Identifier must to provided to register action");
|
||||
if (!action.hasValue<std::string>("Identifier")) {
|
||||
throw ghoul::lua::LuaError("Identifier must to provided to register action");
|
||||
}
|
||||
std::string identifier = d.value<std::string>("Identifier");
|
||||
std::string identifier = action.value<std::string>("Identifier");
|
||||
if (global::actionManager->hasAction(identifier)) {
|
||||
return ghoul::lua::luaError(
|
||||
L,
|
||||
throw ghoul::lua::LuaError(
|
||||
fmt::format("Action for identifier '{}' already existed", identifier)
|
||||
);
|
||||
}
|
||||
if (global::actionManager->hasAction(identifier)) {
|
||||
return ghoul::lua::luaError(
|
||||
L,
|
||||
throw ghoul::lua::LuaError(
|
||||
fmt::format("Identifier '{}' for action already registered", identifier)
|
||||
);
|
||||
}
|
||||
|
||||
if (!d.hasValue<std::string>("Command")) {
|
||||
return ghoul::lua::luaError(
|
||||
L,
|
||||
if (!action.hasValue<std::string>("Command")) {
|
||||
throw ghoul::lua::LuaError(
|
||||
fmt::format(
|
||||
"Identifier '{}' does not provide a Lua command to execute", identifier
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
interaction::Action action;
|
||||
action.identifier = std::move(identifier);
|
||||
action.command = d.value<std::string>("Command");
|
||||
if (d.hasValue<std::string>("Name")) {
|
||||
action.name = d.value<std::string>("Name");
|
||||
interaction::Action a;
|
||||
a.identifier = std::move(identifier);
|
||||
a.command = action.value<std::string>("Command");
|
||||
if (action.hasValue<std::string>("Name")) {
|
||||
a.name = action.value<std::string>("Name");
|
||||
}
|
||||
if (d.hasValue<std::string>("Documentation")) {
|
||||
action.documentation = d.value<std::string>("Documentation");
|
||||
if (action.hasValue<std::string>("Documentation")) {
|
||||
a.documentation = action.value<std::string>("Documentation");
|
||||
}
|
||||
if (d.hasValue<std::string>("GuiPath")) {
|
||||
action.guiPath = d.value<std::string>("GuiPath");
|
||||
if (action.hasValue<std::string>("GuiPath")) {
|
||||
a.guiPath = action.value<std::string>("GuiPath");
|
||||
}
|
||||
if (d.hasValue<bool>("IsLocal")) {
|
||||
bool value = d.value<bool>("IsLocal");
|
||||
action.synchronization = interaction::Action::IsSynchronized(value);
|
||||
if (action.hasValue<bool>("IsLocal")) {
|
||||
bool value = action.value<bool>("IsLocal");
|
||||
a.synchronization = interaction::Action::IsSynchronized(value);
|
||||
}
|
||||
global::actionManager->registerAction(std::move(action));
|
||||
return 0;
|
||||
global::actionManager->registerAction(std::move(a));
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* action():
|
||||
* Returns information about the action with the identifier equal to the provided
|
||||
* identifier.
|
||||
* Returns information about the action as a table with the keys 'Identifier', 'Command',
|
||||
* 'Name', 'Documentation', 'GuiPath', and 'Synchronization'.
|
||||
*/
|
||||
int action(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::action");
|
||||
const std::string identifier = ghoul::lua::value<std::string>(L);
|
||||
[[codegen::luawrap]] ghoul::Dictionary action(std::string identifier) {
|
||||
using namespace openspace;
|
||||
|
||||
if (identifier.empty()) {
|
||||
return ghoul::lua::luaError(L, "Identifier must not be empty");
|
||||
throw ghoul::lua::LuaError("Identifier must not be empty");
|
||||
}
|
||||
if (!global::actionManager->hasAction(identifier)) {
|
||||
return ghoul::lua::luaError(
|
||||
L,
|
||||
throw ghoul::lua::LuaError(
|
||||
fmt::format("Identifier '{}' for action not found", identifier)
|
||||
);
|
||||
}
|
||||
|
||||
const interaction::Action& action = global::actionManager->action(identifier);
|
||||
lua_newtable(L);
|
||||
ghoul::lua::push(L, "Identifier", action.identifier);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "Command", action.command);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "Name", action.name);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "Documentation", action.documentation);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "GuiPath", action.guiPath);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(
|
||||
L,
|
||||
ghoul::Dictionary res;
|
||||
res.setValue("Identifier", action.identifier);
|
||||
res.setValue("Command", action.command);
|
||||
res.setValue("Name", action.name);
|
||||
res.setValue("Documentation", action.documentation);
|
||||
res.setValue("GuiPath", action.guiPath);
|
||||
res.setValue(
|
||||
"Synchronization",
|
||||
action.synchronization == interaction::Action::IsSynchronized::Yes
|
||||
);
|
||||
lua_settable(L, -3);
|
||||
return 1;
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* actions():
|
||||
* Returns all registered actions in the system.
|
||||
* Returns all registered actions in the system as a table of tables each containing the
|
||||
* keys 'Identifier', 'Command', 'Name', 'Documentation', 'GuiPath', and
|
||||
* 'Synchronization'.
|
||||
*/
|
||||
int actions(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::actions");
|
||||
[[codegen::luawrap]] std::vector<ghoul::Dictionary> actions() {
|
||||
using namespace openspace;
|
||||
|
||||
lua_newtable(L);
|
||||
std::vector<ghoul::Dictionary> res;
|
||||
const std::vector<interaction::Action>& actions = global::actionManager->actions();
|
||||
for (size_t i = 0; i < actions.size(); ++i) {
|
||||
const interaction::Action& action = actions[i];
|
||||
|
||||
ghoul::lua::push(L, i + 1);
|
||||
lua_newtable(L);
|
||||
ghoul::lua::push(L, "Identifier", action.identifier);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "Command", action.command);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "Name", action.name);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "Documentation", action.documentation);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "GuiPath", action.guiPath);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(
|
||||
L,
|
||||
for (const interaction::Action& action : actions) {
|
||||
ghoul::Dictionary d;
|
||||
d.setValue("Identifier", action.identifier);
|
||||
d.setValue("Command", action.command);
|
||||
d.setValue("Name", action.name);
|
||||
d.setValue("Documentation", action.documentation);
|
||||
d.setValue("GuiPath", action.guiPath);
|
||||
d.setValue(
|
||||
"Synchronization",
|
||||
action.synchronization == interaction::Action::IsSynchronized::Yes
|
||||
);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_settable(L, -3);
|
||||
res.push_back(d);
|
||||
}
|
||||
|
||||
return 1;
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* triggerAction():
|
||||
* Triggers the action given by the specified identifier.
|
||||
*/
|
||||
int triggerAction(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 1, 2 }, "lua::triggerAction");
|
||||
auto [id, arg] = ghoul::lua::values<std::string, std::optional<ghoul::Dictionary>>(L);
|
||||
arg = arg.value_or(ghoul::Dictionary());
|
||||
// Triggers the action given by the specified identifier.
|
||||
[[codegen::luawrap]] void triggerAction(std::string id,
|
||||
ghoul::Dictionary arg = ghoul::Dictionary())
|
||||
{
|
||||
using namespace openspace;
|
||||
|
||||
if (id.empty()) {
|
||||
return ghoul::lua::luaError(L, "Identifier must not be empty");
|
||||
throw ghoul::lua::LuaError("Identifier must not be empty");
|
||||
}
|
||||
if (!global::actionManager->hasAction(id)) {
|
||||
return ghoul::lua::luaError(L, fmt::format("Action '{}' not found", id));
|
||||
throw ghoul::lua::LuaError(fmt::format("Action '{}' not found", id));
|
||||
}
|
||||
|
||||
global::actionManager->triggerAction(id, *arg);
|
||||
return 0;
|
||||
global::actionManager->triggerAction(id, arg);
|
||||
}
|
||||
|
||||
} // namespace openspace::luascriptfunctions
|
||||
#include "actionmanager_lua_codegen.cpp"
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <openspace/util/json_helper.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/profiling.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <sstream>
|
||||
@@ -142,32 +143,10 @@ scripting::LuaLibrary KeybindingManager::luaLibrary() {
|
||||
return {
|
||||
"",
|
||||
{
|
||||
{
|
||||
"clearKeys",
|
||||
&luascriptfunctions::clearKeys,
|
||||
"",
|
||||
"Clear all key bindings"
|
||||
},
|
||||
{
|
||||
"clearKey",
|
||||
&luascriptfunctions::clearKey,
|
||||
"string or strings",
|
||||
"Unbinds the key or keys that have been provided. This function can be "
|
||||
"called with a single key or with an array of keys to remove all of the "
|
||||
"provided keys at once"
|
||||
},
|
||||
{
|
||||
"bindKey",
|
||||
&luascriptfunctions::bindKey,
|
||||
"string, string",
|
||||
"Binds a key by name to the action identified by the second argument"
|
||||
},
|
||||
{
|
||||
"getKeyBinding",
|
||||
&luascriptfunctions::getKeyBindings,
|
||||
"string",
|
||||
"Returns a list of information about the keybindings for the provided key"
|
||||
}
|
||||
codegen::lua::BindKey,
|
||||
codegen::lua::KeyBindings,
|
||||
codegen::lua::ClearKey,
|
||||
codegen::lua::ClearKeys
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,48 +22,36 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
namespace openspace::luascriptfunctions {
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* bindKey():
|
||||
* Binds a key to Lua command to both execute locally and broadcast to all clients if this
|
||||
* node is hosting a parallel connection.
|
||||
*/
|
||||
int bindKey(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::bindKey");
|
||||
auto [key, action] = ghoul::lua::values<std::string, std::string>(L);
|
||||
[[codegen::luawrap]] void bindKey(std::string key, std::string action) {
|
||||
using namespace openspace;
|
||||
|
||||
if (action.empty()) {
|
||||
return ghoul::lua::luaError(L, "Action must not be empty");
|
||||
throw ghoul::lua::LuaError("Action must not be empty");
|
||||
}
|
||||
if (!global::actionManager->hasAction(action)) {
|
||||
return ghoul::lua::luaError(L, fmt::format("Action '{}' does not exist", action));
|
||||
throw ghoul::lua::LuaError(fmt::format("Action '{}' does not exist", action));
|
||||
}
|
||||
|
||||
openspace::KeyWithModifier iKey = openspace::stringToKey(key);
|
||||
if (iKey.key == openspace::Key::Unknown) {
|
||||
std::string error = fmt::format("Could not find key '{}'", key);
|
||||
LERRORC("lua.bindKey", error);
|
||||
return ghoul::lua::luaError(L, error);
|
||||
throw ghoul::lua::LuaError(fmt::format("Could not find key '{}'", key));
|
||||
}
|
||||
|
||||
global::keybindingManager->bindKey(iKey.key, iKey.modifier, std::move(action));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* getKeyBindings(string):
|
||||
* Returns the strings of the script that are bound to the passed key and whether they were
|
||||
* local or remote key binds
|
||||
*/
|
||||
int getKeyBindings(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::getKeyBindings");
|
||||
const std::string& key = ghoul::lua::value<std::string>(L);
|
||||
* Returns the strings of the script that are bound to the passed key and whether they
|
||||
* were local or remote key binds.
|
||||
*/
|
||||
[[codegen::luawrap]] std::vector<std::string> keyBindings(std::string key) {
|
||||
using namespace openspace;
|
||||
|
||||
using K = KeyWithModifier;
|
||||
using V = std::string;
|
||||
@@ -71,50 +59,39 @@ int getKeyBindings(lua_State* L) {
|
||||
stringToKey(key)
|
||||
);
|
||||
|
||||
lua_createtable(L, static_cast<int>(info.size()), 0);
|
||||
int i = 1;
|
||||
std::vector<std::string> res;
|
||||
res.reserve(info.size());
|
||||
for (const std::pair<K, V>& it : info) {
|
||||
lua_pushnumber(L, i);
|
||||
ghoul::lua::push(L, it.second);
|
||||
lua_settable(L, -3);
|
||||
++i;
|
||||
res.push_back(it.second);
|
||||
}
|
||||
|
||||
return 1;
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* clearKey(string):
|
||||
* Clears the keybinding of the key named as argument
|
||||
*/
|
||||
int clearKey(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::clearKey");
|
||||
* Unbinds the key or keys that have been provided. This function can be called with a
|
||||
* single key or with an array of keys to remove all of the provided keys at once.
|
||||
*/
|
||||
[[codegen::luawrap]] void clearKey(
|
||||
std::variant<std::string, std::vector<std::string>> key)
|
||||
{
|
||||
using namespace openspace;
|
||||
|
||||
std::variant key = ghoul::lua::value<std::variant<std::string, ghoul::Dictionary>>(L);
|
||||
if (std::holds_alternative<std::string>(key)) {
|
||||
KeyWithModifier k = stringToKey(std::get<std::string>(key));
|
||||
global::keybindingManager->removeKeyBinding(k);
|
||||
}
|
||||
else {
|
||||
ghoul::Dictionary d = std::get<ghoul::Dictionary>(key);
|
||||
for (size_t i = 1; i <= d.size(); ++i) {
|
||||
const std::string& k = d.value<std::string>(std::to_string(i));
|
||||
for (const std::string& k : std::get<std::vector<std::string>>(key)) {
|
||||
global::keybindingManager->removeKeyBinding(stringToKey(k));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* clearKeys():
|
||||
* Clears all key bindings
|
||||
*/
|
||||
int clearKeys(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::clearKeys");
|
||||
global::keybindingManager->resetKeyBindings();
|
||||
return 0;
|
||||
// Clear all key bindings
|
||||
[[codegen::luawrap]] void clearKeys() {
|
||||
openspace::global::keybindingManager->resetKeyBindings();
|
||||
}
|
||||
|
||||
} // namespace openspace::luascriptfunctions
|
||||
#include "keybindingmanager_lua_codegen.cpp"
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -58,6 +58,8 @@
|
||||
#include <windows.h>
|
||||
#endif // WIN32
|
||||
|
||||
#include "sessionrecording_lua.inl"
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "SessionRecording";
|
||||
|
||||
@@ -76,11 +78,8 @@ namespace {
|
||||
};
|
||||
|
||||
constexpr const bool UsingTimeKeyframes = false;
|
||||
|
||||
} // namespace
|
||||
|
||||
#include "sessionrecording_lua.inl"
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
ConversionError::ConversionError(std::string msg)
|
||||
@@ -2546,118 +2545,20 @@ scripting::LuaLibrary SessionRecording::luaLibrary() {
|
||||
return {
|
||||
"sessionRecording",
|
||||
{
|
||||
{
|
||||
"startRecording",
|
||||
&luascriptfunctions::startRecording,
|
||||
"string",
|
||||
"Starts a recording session. The string argument is the filename used "
|
||||
"for the file where the recorded keyframes are saved. "
|
||||
"The file data format is binary."
|
||||
},
|
||||
{
|
||||
"startRecordingAscii",
|
||||
&luascriptfunctions::startRecordingAscii,
|
||||
"string",
|
||||
"Starts a recording session. The string argument is the filename used "
|
||||
"for the file where the recorded keyframes are saved. "
|
||||
"The file data format is ASCII."
|
||||
},
|
||||
{
|
||||
"stopRecording",
|
||||
&luascriptfunctions::stopRecording,
|
||||
"void",
|
||||
"Stops a recording session"
|
||||
},
|
||||
{
|
||||
"startPlayback",
|
||||
&luascriptfunctions::startPlaybackDefault,
|
||||
"string [, bool]",
|
||||
"Starts a playback session with keyframe times that are relative to "
|
||||
"the time since the recording was started (the same relative time "
|
||||
"applies to the playback). When playback starts, the simulation time "
|
||||
"is automatically set to what it was at recording time. The string "
|
||||
"argument is the filename to pull playback keyframes from (the file "
|
||||
"path is relative to the RECORDINGS variable specified in the config "
|
||||
"file). If a second input value of true is given, then playback will "
|
||||
"continually loop until it is manually stopped."
|
||||
},
|
||||
{
|
||||
"startPlaybackApplicationTime",
|
||||
&luascriptfunctions::startPlaybackApplicationTime,
|
||||
"string",
|
||||
"Starts a playback session with keyframe times that are relative to "
|
||||
"application time (seconds since OpenSpace application started). "
|
||||
"The string argument is the filename to pull playback keyframes from "
|
||||
"(the file path is relative to the RECORDINGS variable specified in the "
|
||||
"config file)."
|
||||
},
|
||||
{
|
||||
"startPlaybackRecordedTime",
|
||||
&luascriptfunctions::startPlaybackRecordedTime,
|
||||
"string [, bool]",
|
||||
"Starts a playback session with keyframe times that are relative to "
|
||||
"the time since the recording was started (the same relative time "
|
||||
"applies to the playback). The string argument is the filename to pull "
|
||||
"playback keyframes from (the file path is relative to the RECORDINGS "
|
||||
"variable specified in the config file). If a second input value of "
|
||||
"true is given, then playback will continually loop until it is "
|
||||
"manually stopped."
|
||||
},
|
||||
{
|
||||
"startPlaybackSimulationTime",
|
||||
&luascriptfunctions::startPlaybackSimulationTime,
|
||||
"string",
|
||||
"Starts a playback session with keyframe times that are relative to "
|
||||
"the simulated date & time. The string argument is the filename to pull "
|
||||
"playback keyframes from (the file path is relative to the RECORDINGS "
|
||||
"variable specified in the config file)."
|
||||
},
|
||||
{
|
||||
"stopPlayback",
|
||||
&luascriptfunctions::stopPlayback,
|
||||
"",
|
||||
"Stops a playback session before playback of all keyframes is complete"
|
||||
},
|
||||
{
|
||||
"enableTakeScreenShotDuringPlayback",
|
||||
&luascriptfunctions::enableTakeScreenShotDuringPlayback,
|
||||
"[int]",
|
||||
"Enables that rendered frames should be saved during playback. The "
|
||||
"parameter determines the number of frames that are exported per second "
|
||||
"if this value is not provided, 60 frames per second will be exported."
|
||||
},
|
||||
{
|
||||
"disableTakeScreenShotDuringPlayback",
|
||||
&luascriptfunctions::disableTakeScreenShotDuringPlayback,
|
||||
"",
|
||||
"Used to disable that renderings are saved during playback"
|
||||
},
|
||||
{
|
||||
"fileFormatConversion",
|
||||
&luascriptfunctions::fileFormatConversion,
|
||||
"string",
|
||||
"Performs a conversion of the specified file to the most most recent "
|
||||
"file format, creating a copy of the recording file."
|
||||
},
|
||||
{
|
||||
"setPlaybackPause",
|
||||
&luascriptfunctions::setPlaybackPause,
|
||||
"bool",
|
||||
"Pauses or resumes the playback progression through keyframes"
|
||||
},
|
||||
{
|
||||
"togglePlaybackPause",
|
||||
&luascriptfunctions::togglePlaybackPause,
|
||||
"",
|
||||
"Toggles the pause function, i.e. temporarily setting the delta time to 0"
|
||||
" and restoring it afterwards"
|
||||
},
|
||||
{
|
||||
"isPlayingBack",
|
||||
& luascriptfunctions::isPlayingBack,
|
||||
"",
|
||||
"Returns true if session recording is currently playing back a recording"
|
||||
}
|
||||
codegen::lua::StartRecording,
|
||||
codegen::lua::StartRecordingAscii,
|
||||
codegen::lua::StopRecording,
|
||||
codegen::lua::StartPlaybackDefault,
|
||||
codegen::lua::StartPlaybackApplicationTime,
|
||||
codegen::lua::StartPlaybackRecordedTime,
|
||||
codegen::lua::StartPlaybackSimulationTime,
|
||||
codegen::lua::StopPlayback,
|
||||
codegen::lua::EnableTakeScreenShotDuringPlayback,
|
||||
codegen::lua::DisableTakeScreenShotDuringPlayback,
|
||||
codegen::lua::FileFormatConversion,
|
||||
codegen::lua::SetPlaybackPause,
|
||||
codegen::lua::TogglePlaybackPause,
|
||||
codegen::lua::IsPlayingBack
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,137 +22,179 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
namespace openspace::luascriptfunctions {
|
||||
namespace {
|
||||
|
||||
int startRecording(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::startRecording");
|
||||
const std::string recordFilePath = ghoul::lua::value<std::string>(L);
|
||||
/**
|
||||
* Starts a recording session. The string argument is the filename used for the file where
|
||||
* the recorded keyframes are saved. The file data format is binary.
|
||||
*/
|
||||
[[codegen::luawrap]] void startRecording(std::string recordFilePath) {
|
||||
using namespace openspace;
|
||||
|
||||
if (recordFilePath.empty()) {
|
||||
return luaL_error(L, "filepath string is empty");
|
||||
throw ghoul::lua::LuaError("Filepath string is empty");
|
||||
}
|
||||
global::sessionRecording->setRecordDataFormat(
|
||||
interaction::SessionRecording::DataMode::Binary
|
||||
);
|
||||
global::sessionRecording->startRecording(recordFilePath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int startRecordingAscii(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::startRecordingAscii");
|
||||
const std::string recordFilePath = ghoul::lua::value<std::string>(L);
|
||||
|
||||
/**
|
||||
* Starts a recording session. The string argument is the filename used for the file where
|
||||
* the recorded keyframes are saved. The file data format is ASCII.
|
||||
*/
|
||||
[[codegen::luawrap]] void startRecordingAscii(std::string recordFilePath) {
|
||||
using namespace openspace;
|
||||
|
||||
if (recordFilePath.empty()) {
|
||||
return luaL_error(L, "filepath string is empty");
|
||||
throw ghoul::lua::LuaError("Filepath string is empty");
|
||||
}
|
||||
global::sessionRecording->setRecordDataFormat(
|
||||
interaction::SessionRecording::DataMode::Ascii
|
||||
);
|
||||
global::sessionRecording->startRecording(recordFilePath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int stopRecording(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::stopRecording");
|
||||
global::sessionRecording->stopRecording();
|
||||
return 0;
|
||||
// Stops a recording session.
|
||||
[[codegen::luawrap]] void stopRecording() {
|
||||
openspace::global::sessionRecording->stopRecording();
|
||||
}
|
||||
|
||||
int startPlayback(lua_State* L, interaction::KeyframeTimeRef timeMode,
|
||||
bool forceSimTimeAtStart)
|
||||
{
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 1, 2 }, "lua::startPlayback");
|
||||
auto [file, loop] = ghoul::lua::values<std::string, std::optional<bool>>(L);
|
||||
loop = loop.value_or(false);
|
||||
|
||||
/**
|
||||
* Starts a playback session with keyframe times that are relative to the time since the
|
||||
* recording was started (the same relative time applies to the playback). When playback
|
||||
* starts, the simulation time is automatically set to what it was at recording time. The
|
||||
* string argument is the filename to pull playback keyframes from (the file path is
|
||||
* relative to the RECORDINGS variable specified in the config file). If a second input
|
||||
* value of true is given, then playback will continually loop until it is manually
|
||||
* stopped.
|
||||
*/
|
||||
[[codegen::luawrap]] void startPlaybackDefault(std::string file, bool loop = false) {
|
||||
using namespace openspace;
|
||||
|
||||
if (file.empty()) {
|
||||
return ghoul::lua::luaError(L, "Filepath string is empty");
|
||||
throw ghoul::lua::LuaError("Filepath string is empty");
|
||||
}
|
||||
global::sessionRecording->startPlayback(file, timeMode, forceSimTimeAtStart, *loop);
|
||||
return 0;
|
||||
global::sessionRecording->startPlayback(
|
||||
file,
|
||||
interaction::KeyframeTimeRef::Relative_recordedStart,
|
||||
true,
|
||||
loop
|
||||
);
|
||||
}
|
||||
|
||||
int startPlaybackDefault(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 1, 2 }, "lua::startPlaybackDefault");
|
||||
return startPlayback(L, interaction::KeyframeTimeRef::Relative_recordedStart, true);
|
||||
}
|
||||
|
||||
int startPlaybackApplicationTime(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::startPlaybackApplicationTime");
|
||||
|
||||
return startPlayback(
|
||||
L,
|
||||
/**
|
||||
* Starts a playback session with keyframe times that are relative to application time
|
||||
* (seconds since OpenSpace application started). The string argument is the filename to
|
||||
* pull playback keyframes from (the file path is relative to the RECORDINGS variable
|
||||
* specified in the config file).
|
||||
*/
|
||||
[[codegen::luawrap]] void startPlaybackApplicationTime(std::string file) {
|
||||
using namespace openspace;
|
||||
|
||||
if (file.empty()) {
|
||||
throw ghoul::lua::LuaError("Filepath string is empty");
|
||||
}
|
||||
global::sessionRecording->startPlayback(
|
||||
file,
|
||||
interaction::KeyframeTimeRef::Relative_applicationStart,
|
||||
false,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
int startPlaybackRecordedTime(lua_State* L) {
|
||||
using interaction::KeyframeNavigator;
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 1, 2 }, "lua::startPlaybackRecordedTime");
|
||||
return startPlayback(L, interaction::KeyframeTimeRef::Relative_recordedStart, false);
|
||||
}
|
||||
|
||||
int startPlaybackSimulationTime(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::startPlaybackSimulationTime");
|
||||
return startPlayback(L, interaction::KeyframeTimeRef::Absolute_simTimeJ2000, false);
|
||||
}
|
||||
|
||||
int stopPlayback(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::stopPlayback");
|
||||
global::sessionRecording->stopPlayback();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int enableTakeScreenShotDuringPlayback(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(
|
||||
L,
|
||||
{ 0, 1 },
|
||||
"lua::enableTakeScreenShotDuringPlayback"
|
||||
);
|
||||
std::optional<int> fps = ghoul::lua::value<std::optional<int>>(L);
|
||||
fps = fps.value_or(60);
|
||||
|
||||
global::sessionRecording->enableTakeScreenShotDuringPlayback(*fps);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int disableTakeScreenShotDuringPlayback(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::disableTakeScreenShotDuringPlayback");
|
||||
global::sessionRecording->disableTakeScreenShotDuringPlayback();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fileFormatConversion(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::fileFormatConversion");
|
||||
const std::string convertFilePath = ghoul::lua::value<std::string>(L);
|
||||
|
||||
if (convertFilePath.empty()) {
|
||||
return luaL_error(L, "Filepath string must not be empty");
|
||||
/**
|
||||
* Starts a playback session with keyframe times that are relative to the time since the
|
||||
* recording was started (the same relative time applies to the playback). The string
|
||||
* argument is the filename to pull playback keyframes from (the file path is relative to
|
||||
* the RECORDINGS variable specified in the config file). If a second input value of true
|
||||
* is given, then playback will continually loop until it is manually stopped.
|
||||
*/
|
||||
[[codegen::luawrap]] void startPlaybackRecordedTime(std::string file, bool loop = false) {
|
||||
using namespace openspace;
|
||||
|
||||
if (file.empty()) {
|
||||
throw ghoul::lua::LuaError("Filepath string is empty");
|
||||
}
|
||||
global::sessionRecording->convertFile(convertFilePath);
|
||||
return 0;
|
||||
global::sessionRecording->startPlayback(
|
||||
file,
|
||||
interaction::KeyframeTimeRef::Relative_recordedStart,
|
||||
false,
|
||||
loop
|
||||
);
|
||||
}
|
||||
|
||||
int setPlaybackPause(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::setPlaybackPause");
|
||||
const bool pause = ghoul::lua::value<bool>(L);
|
||||
|
||||
global::sessionRecording->setPlaybackPause(pause);
|
||||
return 0;
|
||||
/**
|
||||
* Starts a playback session with keyframe times that are relative to the simulated date &
|
||||
* time. The string argument is the filename to pull playback keyframes from (the file
|
||||
* path is relative to the RECORDINGS variable specified in the config file).
|
||||
*/
|
||||
[[codegen::luawrap]] void startPlaybackSimulationTime(std::string file) {
|
||||
using namespace openspace;
|
||||
|
||||
if (file.empty()) {
|
||||
throw ghoul::lua::LuaError("Filepath string is empty");
|
||||
}
|
||||
global::sessionRecording->startPlayback(
|
||||
file,
|
||||
interaction::KeyframeTimeRef::Absolute_simTimeJ2000,
|
||||
false,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
int togglePlaybackPause(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::togglePlaybackPause");
|
||||
// Stops a playback session before playback of all keyframes is complete.
|
||||
[[codegen::luawrap]] void stopPlayback() {
|
||||
openspace::global::sessionRecording->stopPlayback();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables that rendered frames should be saved during playback. The parameter determines
|
||||
* the number of frames that are exported per second if this value is not provided, 60
|
||||
* frames per second will be exported.
|
||||
*/
|
||||
[[codegen::luawrap]] void enableTakeScreenShotDuringPlayback(int fps = 60) {
|
||||
openspace::global::sessionRecording->enableTakeScreenShotDuringPlayback(fps);
|
||||
}
|
||||
|
||||
// Used to disable that renderings are saved during playback.
|
||||
[[codegen::luawrap]] void disableTakeScreenShotDuringPlayback() {
|
||||
openspace::global::sessionRecording->disableTakeScreenShotDuringPlayback();
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a conversion of the specified file to the most most recent file format,
|
||||
* creating a copy of the recording file.
|
||||
*/
|
||||
[[codegen::luawrap]] void fileFormatConversion(std::string convertFilePath) {
|
||||
if (convertFilePath.empty()) {
|
||||
throw ghoul::lua::LuaError("Filepath string must not be empty");
|
||||
}
|
||||
openspace::global::sessionRecording->convertFile(convertFilePath);
|
||||
}
|
||||
|
||||
// Pauses or resumes the playback progression through keyframes.
|
||||
[[codegen::luawrap]] void setPlaybackPause(bool pause) {
|
||||
openspace::global::sessionRecording->setPlaybackPause(pause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the pause function, i.e. temporarily setting the delta time to 0 and restoring
|
||||
* it afterwards.
|
||||
*/
|
||||
[[codegen::luawrap]] void togglePlaybackPause() {
|
||||
using namespace openspace;
|
||||
|
||||
bool isPlaybackPaused = global::sessionRecording->isPlaybackPaused();
|
||||
global::sessionRecording->setPlaybackPause(!isPlaybackPaused);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int isPlayingBack(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::isPlayingBack");
|
||||
ghoul::lua::push(L, global::sessionRecording->isPlayingBack());
|
||||
return 1;
|
||||
// Returns true if session recording is currently playing back a recording.
|
||||
[[codegen::luawrap]] bool isPlayingBack() {
|
||||
return openspace::global::sessionRecording->isPlayingBack();
|
||||
}
|
||||
|
||||
} // namespace openspace::luascriptfunctions
|
||||
#include "sessionrecording_lua_codegen.cpp"
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <openspace/mission/missionmanager.h>
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <ghoul/filesystem/file.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
@@ -108,30 +109,10 @@ scripting::LuaLibrary MissionManager::luaLibrary() {
|
||||
return {
|
||||
"",
|
||||
{
|
||||
{
|
||||
"loadMission",
|
||||
&luascriptfunctions::loadMission,
|
||||
"string",
|
||||
"Load mission phases from file"
|
||||
},
|
||||
{
|
||||
"unloadMission",
|
||||
&luascriptfunctions::unloadMission,
|
||||
"string",
|
||||
"Unloads a previously loaded mission"
|
||||
},
|
||||
{
|
||||
"hasMission",
|
||||
&luascriptfunctions::hasMission,
|
||||
"string",
|
||||
"Returns whether a mission with the provided name has been loaded"
|
||||
},
|
||||
{
|
||||
"setCurrentMission",
|
||||
&luascriptfunctions::setCurrentMission,
|
||||
"string",
|
||||
"Set the currnet mission"
|
||||
},
|
||||
codegen::lua::LoadMission,
|
||||
codegen::lua::UnloadMission,
|
||||
codegen::lua::HasMission,
|
||||
codegen::lua::SetCurrentMission
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,61 +22,47 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
|
||||
namespace openspace::luascriptfunctions {
|
||||
|
||||
int loadMission(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::loadMission");
|
||||
const std::string& missionFileName = ghoul::lua::value<std::string>(L);
|
||||
|
||||
// Load mission phases from file.
|
||||
[[codegen::luawrap]] std::string loadMission(std::string missionFileName) {
|
||||
if (missionFileName.empty()) {
|
||||
return ghoul::lua::luaError(L, "Filepath is empty");
|
||||
throw ghoul::lua::LuaError("Filepath is empty");
|
||||
}
|
||||
|
||||
const std::string name = global::missionManager->loadMission(missionFileName);
|
||||
ghoul::lua::push(L, name);
|
||||
return 1;
|
||||
std::string name = openspace::global::missionManager->loadMission(missionFileName);
|
||||
return name;
|
||||
}
|
||||
|
||||
int unloadMission(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::unloadMission");
|
||||
const std::string missionName = ghoul::lua::value<std::string>(L);
|
||||
// Unloads a previously loaded mission.
|
||||
[[codegen::luawrap]] void unloadMission(std::string missionName) {
|
||||
using namespace openspace;
|
||||
|
||||
if (missionName.empty()) {
|
||||
return ghoul::lua::luaError(L, "Mission name is empty");
|
||||
throw ghoul::lua::LuaError("Mission name is empty");
|
||||
}
|
||||
|
||||
if (!global::missionManager->hasMission(missionName)) {
|
||||
return ghoul::lua::luaError(L, "Mission was not previously loaded");
|
||||
throw ghoul::lua::LuaError("Mission was not previously loaded");
|
||||
}
|
||||
|
||||
global::missionManager->unloadMission(missionName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hasMission(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::hasMission");
|
||||
const std::string missionName = ghoul::lua::value<std::string>(L);
|
||||
|
||||
// Returns whether a mission with the provided name has been loaded.
|
||||
[[codegen::luawrap]] bool hasMission(std::string missionName) {
|
||||
if (missionName.empty()) {
|
||||
return ghoul::lua::luaError(L, "Missing name is empty");
|
||||
throw ghoul::lua::LuaError("Missing name is empty");
|
||||
}
|
||||
|
||||
const bool hasMission = global::missionManager->hasMission(missionName);
|
||||
ghoul::lua::push(L, hasMission);
|
||||
return 1;
|
||||
bool hasMission = openspace::global::missionManager->hasMission(missionName);
|
||||
return hasMission;
|
||||
}
|
||||
|
||||
int setCurrentMission(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::setCurrentMission");
|
||||
const std::string missionName = ghoul::lua::value<std::string>(L);
|
||||
|
||||
// Set the currnet mission.
|
||||
[[codegen::luawrap]] void setCurrentMission(std::string missionName) {
|
||||
if (missionName.empty()) {
|
||||
return ghoul::lua::luaError(L, "Mission name is empty");
|
||||
throw ghoul::lua::LuaError("Mission name is empty");
|
||||
}
|
||||
global::missionManager->setCurrentMission(missionName);
|
||||
return 0;
|
||||
openspace::global::missionManager->setCurrentMission(missionName);
|
||||
}
|
||||
|
||||
} // namespace openspace::luascriptfunction
|
||||
#include "missionmanager_lua_codegen.cpp"
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <openspace/events/event.h>
|
||||
#include <openspace/events/eventengine.h>
|
||||
#include <openspace/interaction/actionmanager.h>
|
||||
#include <openspace/interaction/scriptcamerastates.h>
|
||||
#include <openspace/navigation/navigationstate.h>
|
||||
#include <openspace/network/parallelpeer.h>
|
||||
#include <openspace/scene/profile.h>
|
||||
@@ -47,11 +48,14 @@
|
||||
#include <glm/gtx/vector_angle.hpp>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <numeric>
|
||||
|
||||
#include "navigationhandler_lua.inl"
|
||||
|
||||
namespace {
|
||||
// Helper structs for the visitor pattern of the std::variant
|
||||
template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
|
||||
template <class... Ts> overloaded(Ts...)->overloaded<Ts...>;
|
||||
template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
|
||||
|
||||
constexpr const char* _loggerCat = "NavigationHandler";
|
||||
|
||||
@@ -76,8 +80,6 @@ namespace {
|
||||
};
|
||||
} // namespace
|
||||
|
||||
#include "navigationhandler_lua.inl"
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
NavigationHandler::NavigationHandler()
|
||||
@@ -583,168 +585,26 @@ scripting::LuaLibrary NavigationHandler::luaLibrary() {
|
||||
return {
|
||||
"navigation",
|
||||
{
|
||||
{
|
||||
"getNavigationState",
|
||||
&luascriptfunctions::getNavigationState,
|
||||
"[string]",
|
||||
"Return the current navigation state as a lua table. The optional "
|
||||
"argument is the scene graph node to use as reference frame. By default, "
|
||||
"the reference frame will picked based on whether the orbital navigator "
|
||||
"is currently following the anchor node rotation. If it is, the anchor "
|
||||
"will be chosen as reference frame. If not, the reference frame will be "
|
||||
"set to the scene graph root."
|
||||
},
|
||||
{
|
||||
"setNavigationState",
|
||||
&luascriptfunctions::setNavigationState,
|
||||
"table",
|
||||
"Set the navigation state. The argument must be a valid Navigation State."
|
||||
},
|
||||
{
|
||||
"saveNavigationState",
|
||||
&luascriptfunctions::saveNavigationState,
|
||||
"string, [string]",
|
||||
"Save the current navigation state to a file with the path given by the "
|
||||
"first argument. The optoinal second argument is the scene graph node to "
|
||||
"use as reference frame. By default, the reference frame will picked "
|
||||
"based on whether the orbital navigator is currently following the "
|
||||
"anchor node rotation. If it is, the anchor will be chosen as reference "
|
||||
"frame. If not, the reference frame will be set to the scene graph root."
|
||||
},
|
||||
{
|
||||
"loadNavigationState",
|
||||
&luascriptfunctions::loadNavigationState,
|
||||
"string",
|
||||
"Load a navigation state from file. The file should be a lua file "
|
||||
"returning the navigation state as a table formatted as a "
|
||||
"Navigation State, such as the output files of saveNavigationState."
|
||||
},
|
||||
{
|
||||
"retargetAnchor",
|
||||
&luascriptfunctions::retargetAnchor,
|
||||
"void",
|
||||
"Reset the camera direction to point at the anchor node"
|
||||
},
|
||||
{
|
||||
"retargetAim",
|
||||
&luascriptfunctions::retargetAim,
|
||||
"void",
|
||||
"Reset the camera direction to point at the aim node"
|
||||
},
|
||||
{
|
||||
"bindJoystickAxis",
|
||||
&luascriptfunctions::bindJoystickAxis,
|
||||
"name, axis, axisType [, isInverted, joystickType, isSticky, sensitivity]",
|
||||
"Finds the input joystick with the given 'name' and binds the axis "
|
||||
"identified by the second argument to be used as the type identified by "
|
||||
"the third argument. If 'isInverted' is 'true', the axis value is "
|
||||
"inverted. 'joystickType' is if the joystick behaves more like a "
|
||||
"joystick or a trigger, where the first is the default. If 'isSticky' is "
|
||||
"'true', the value is calculated relative to the previous value. If "
|
||||
"'sensitivity' is given then that value will affect the sensitivity of "
|
||||
"the axis together with the global sensitivity."
|
||||
},
|
||||
{
|
||||
"bindJoystickAxisProperty",
|
||||
&luascriptfunctions::bindJoystickAxisProperty,
|
||||
"name, axis, propertyUri [, min, max, isInverted, isSticky, sensitivity, "
|
||||
"isRemote]",
|
||||
"Finds the input joystick with the given 'name' and binds the axis "
|
||||
"identified by the second argument to be bound to the property "
|
||||
"identified by the third argument. 'min' and 'max' is the minimum and "
|
||||
"the maximum allowed value for the given property and the axis value is "
|
||||
"rescaled from [-1, 1] to [min, max], default is [0, 1]. If 'isInverted' "
|
||||
"is 'true', the axis value is inverted. The last argument determines "
|
||||
"whether the property change is going to be executed locally or "
|
||||
"remotely, where the latter is the default."
|
||||
},
|
||||
{
|
||||
"joystickAxis",
|
||||
&luascriptfunctions::joystickAxis,
|
||||
"name, axis",
|
||||
"Finds the input joystick with the given 'name' and returns the joystick "
|
||||
"axis information for the passed axis. The information that is returned "
|
||||
"is the current axis binding as a string, whether the values are "
|
||||
"inverted as bool, the joystick type as a string, whether the axis is "
|
||||
"sticky as bool, the sensitivity as number, the property uri bound to "
|
||||
"the axis as string (empty is type is not Property), the min and max "
|
||||
"values for the property as numbers and whether the property change will "
|
||||
"be executed remotly as bool."
|
||||
},
|
||||
{
|
||||
"setAxisDeadZone",
|
||||
&luascriptfunctions::setJoystickAxisDeadzone,
|
||||
"name, axis, float",
|
||||
"Finds the input joystick with the given 'name' and sets the deadzone "
|
||||
"for a particular joystick axis, which means that any input less than "
|
||||
"this value is completely ignored."
|
||||
},
|
||||
{
|
||||
"bindJoystickButton",
|
||||
&luascriptfunctions::bindJoystickButton,
|
||||
"name, button, string [, string, string, bool]",
|
||||
"Finds the input joystick with the given 'name' and binds a Lua script "
|
||||
"given by the third argument to be executed when the joystick button "
|
||||
"identified by the second argument is triggered. The fifth argument "
|
||||
"determines when the script should be executed, this defaults to "
|
||||
"'Press', which means that the script is run when the user presses the "
|
||||
"button. The fourth arguemnt is the documentation of the script in the "
|
||||
"third argument. The sixth argument determines whether the command is "
|
||||
"going to be executable locally or remotely, where the latter is the "
|
||||
"default."
|
||||
},
|
||||
{
|
||||
"clearJoystickButton",
|
||||
&luascriptfunctions::clearJoystickButton,
|
||||
"name, button",
|
||||
"Finds the input joystick with the given 'name' and removes all commands "
|
||||
"that are currently bound to the button identified by the second argument."
|
||||
},
|
||||
{
|
||||
"joystickButton",
|
||||
&luascriptfunctions::joystickButton,
|
||||
"name, button",
|
||||
"Finds the input joystick with the given 'name' and returns the script "
|
||||
"that is currently bound to be executed when the provided button is "
|
||||
"pressed."
|
||||
},
|
||||
{
|
||||
"addGlobalRotation",
|
||||
&luascriptfunctions::addGlobalRotation,
|
||||
"double, double",
|
||||
"Directly adds to the global rotation of the camera"
|
||||
},
|
||||
{
|
||||
"addLocalRotation",
|
||||
&luascriptfunctions::addLocalRotation,
|
||||
"double, double",
|
||||
"Directly adds to the local rotation of the camera"
|
||||
},
|
||||
{
|
||||
"addTruckMovement",
|
||||
&luascriptfunctions::addTruckMovement,
|
||||
"double, double",
|
||||
"Directly adds to the truck movement of the camera"
|
||||
},
|
||||
{
|
||||
"addLocalRoll",
|
||||
&luascriptfunctions::addLocalRoll,
|
||||
"double, double",
|
||||
"Directly adds to the local roll of the camera"
|
||||
},
|
||||
{
|
||||
"addGlobalRoll",
|
||||
&luascriptfunctions::addGlobalRoll,
|
||||
"double, double",
|
||||
"Directly adds to the global roll of the camera"
|
||||
},
|
||||
{
|
||||
"triggerIdleBehavior",
|
||||
&luascriptfunctions::triggerIdleBehavior,
|
||||
"[string]",
|
||||
"Immediately start applying the chosen IdleBehavior. If none is "
|
||||
"specified, use the one set to default in the OrbitalNavigator."
|
||||
}
|
||||
codegen::lua::LoadNavigationState,
|
||||
codegen::lua::GetNavigationState,
|
||||
codegen::lua::SetNavigationState,
|
||||
codegen::lua::SaveNavigationState,
|
||||
codegen::lua::RetargetAnchor,
|
||||
codegen::lua::RetargetAim,
|
||||
codegen::lua::BindJoystickAxis,
|
||||
codegen::lua::BindJoystickAxisProperty,
|
||||
codegen::lua::JoystickAxis,
|
||||
codegen::lua::SetJoystickAxisDeadZone,
|
||||
codegen::lua::JoystickAxisDeadzone,
|
||||
codegen::lua::BindJoystickButton,
|
||||
codegen::lua::ClearJoystickButton,
|
||||
codegen::lua::JoystickButton,
|
||||
codegen::lua::AddGlobalRotation,
|
||||
codegen::lua::AddLocalRotation,
|
||||
codegen::lua::AddTruckMovement,
|
||||
codegen::lua::AddLocalRoll,
|
||||
codegen::lua::AddGlobalRoll,
|
||||
codegen::lua::TriggerIdleBehavior
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,34 +22,38 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/interaction/scriptcamerastates.h>
|
||||
#include <openspace/navigation/navigationstate.h>
|
||||
#include <numeric>
|
||||
|
||||
namespace openspace::luascriptfunctions {
|
||||
|
||||
int loadNavigationState(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::loadNavigationState");
|
||||
const std::string cameraStateFilePath = ghoul::lua::value<std::string>(L);
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* Load a navigation state from file. The file should be a lua file returning the
|
||||
* navigation state as a table formatted as a Navigation State, such as the output files
|
||||
* of saveNavigationState.
|
||||
*/
|
||||
[[codegen::luawrap]] void loadNavigationState(std::string cameraStateFilePath) {
|
||||
if (cameraStateFilePath.empty()) {
|
||||
return ghoul::lua::luaError(L, "filepath string is empty");
|
||||
throw ghoul::lua::LuaError("Filepath string is empty");
|
||||
}
|
||||
|
||||
global::navigationHandler->loadNavigationState(cameraStateFilePath);
|
||||
return 0;
|
||||
openspace::global::navigationHandler->loadNavigationState(cameraStateFilePath);
|
||||
}
|
||||
|
||||
int getNavigationState(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 0, 1 }, "lua::getNavigationState");
|
||||
std::optional<std::string> frame = ghoul::lua::value<std::optional<std::string>>(L);
|
||||
/**
|
||||
* Return the current navigation state as a lua table. The optional argument is the scene
|
||||
* graph node to use as reference frame. By default, the reference frame will picked based
|
||||
* on whether the orbital navigator is currently following the anchor node rotation. If it
|
||||
* is, the anchor will be chosen as reference frame. If not, the reference frame will be
|
||||
* set to the scene graph root.
|
||||
*/
|
||||
[[codegen::luawrap]] ghoul::Dictionary getNavigationState(
|
||||
std::optional<std::string> frame)
|
||||
{
|
||||
using namespace openspace;
|
||||
|
||||
interaction::NavigationState state;
|
||||
if (frame.has_value()) {
|
||||
const SceneGraphNode* referenceFrame = sceneGraphNode(*frame);
|
||||
if (!referenceFrame) {
|
||||
return ghoul::lua::luaError(
|
||||
L,
|
||||
throw ghoul::lua::LuaError(
|
||||
fmt::format("Could not find node '{}' as reference frame", *frame)
|
||||
);
|
||||
}
|
||||
@@ -59,157 +63,147 @@ int getNavigationState(lua_State* L) {
|
||||
state = global::navigationHandler->navigationState();
|
||||
}
|
||||
|
||||
|
||||
const auto pushVector = [](lua_State* s, const glm::dvec3& v) {
|
||||
lua_newtable(s);
|
||||
ghoul::lua::push(s, 1, v.x);
|
||||
lua_rawset(s, -3);
|
||||
ghoul::lua::push(s, 2, v.y);
|
||||
lua_rawset(s, -3);
|
||||
ghoul::lua::push(s, 3, v.z);
|
||||
lua_rawset(s, -3);
|
||||
};
|
||||
|
||||
lua_newtable(L);
|
||||
ghoul::lua::push(L, "Anchor", state.anchor);
|
||||
lua_rawset(L, -3);
|
||||
|
||||
ghoul::Dictionary res;
|
||||
res.setValue("Anchor", state.anchor);
|
||||
if (!state.aim.empty()) {
|
||||
ghoul::lua::push(L, "Aim", state.aim);
|
||||
lua_rawset(L, -3);
|
||||
res.setValue("Aim", state.aim);
|
||||
}
|
||||
if (!state.referenceFrame.empty()) {
|
||||
ghoul::lua::push(L, "ReferenceFrame", state.referenceFrame);
|
||||
lua_rawset(L, -3);
|
||||
res.setValue("ReferenceFrame", state.referenceFrame);
|
||||
}
|
||||
ghoul::lua::push(L, "Position");
|
||||
pushVector(L, state.position);
|
||||
lua_rawset(L, -3);
|
||||
|
||||
res.setValue("ReferenceFrame", state.position);
|
||||
if (state.up.has_value()) {
|
||||
ghoul::lua::push(L, "Up");
|
||||
pushVector(L, *state.up);
|
||||
lua_rawset(L, -3);
|
||||
res.setValue("Up", *state.up);
|
||||
}
|
||||
if (state.yaw != 0) {
|
||||
ghoul::lua::push(L, "Yaw", state.yaw);
|
||||
lua_rawset(L, -3);
|
||||
res.setValue("Up", state.yaw);
|
||||
}
|
||||
if (state.pitch != 0) {
|
||||
ghoul::lua::push(L, "Pitch", state.pitch);
|
||||
lua_rawset(L, -3);
|
||||
res.setValue("Pitch", state.pitch);
|
||||
}
|
||||
|
||||
return 1;
|
||||
return res;
|
||||
}
|
||||
|
||||
int setNavigationState(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::setNavigationState");
|
||||
ghoul::Dictionary navigationStateDictionary = ghoul::lua::value<ghoul::Dictionary>(L);
|
||||
// Set the navigation state. The argument must be a valid Navigation State.
|
||||
[[codegen::luawrap]] void setNavigationState(ghoul::Dictionary navigationState) {
|
||||
using namespace openspace;
|
||||
|
||||
openspace::documentation::TestResult r = openspace::documentation::testSpecification(
|
||||
documentation::TestResult r = documentation::testSpecification(
|
||||
interaction::NavigationState::Documentation(),
|
||||
navigationStateDictionary
|
||||
navigationState
|
||||
);
|
||||
|
||||
if (!r.success) {
|
||||
return ghoul::lua::luaError(
|
||||
L,
|
||||
throw ghoul::lua::LuaError(
|
||||
fmt::format("Could not set camera state: {}", ghoul::to_string(r))
|
||||
);
|
||||
}
|
||||
|
||||
global::navigationHandler->setNavigationStateNextFrame(
|
||||
interaction::NavigationState(navigationStateDictionary)
|
||||
interaction::NavigationState(navigationState)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int saveNavigationState(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 1, 2 }, "lua::saveNavigationState");
|
||||
auto [path, frame] = ghoul::lua::values<std::string, std::optional<std::string>>(L);
|
||||
frame = frame.value_or("");
|
||||
|
||||
/**
|
||||
* Save the current navigation state to a file with the path given by the first argument.
|
||||
* The optional second argument is the scene graph node to use as reference frame. By
|
||||
* default, the reference frame will picked based on whether the orbital navigator is
|
||||
* currently following the anchor node rotation. If it is, the anchor will be chosen as
|
||||
* reference frame. If not, the reference frame will be set to the scene graph root.
|
||||
*/
|
||||
[[codegen::luawrap]] void saveNavigationState(std::string path, std::string frame = "") {
|
||||
if (path.empty()) {
|
||||
return ghoul::lua::luaError(L, "Filepath string is empty");
|
||||
throw ghoul::lua::LuaError("Filepath string is empty");
|
||||
}
|
||||
|
||||
global::navigationHandler->saveNavigationState(path, *frame);
|
||||
return 0;
|
||||
openspace::global::navigationHandler->saveNavigationState(path, frame);
|
||||
}
|
||||
|
||||
int retargetAnchor(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::retargetAnchor");
|
||||
global::navigationHandler->orbitalNavigator().startRetargetAnchor();
|
||||
return 0;
|
||||
// Reset the camera direction to point at the anchor node.
|
||||
[[codegen::luawrap]] void retargetAnchor() {
|
||||
openspace::global::navigationHandler->orbitalNavigator().startRetargetAnchor();
|
||||
}
|
||||
|
||||
int retargetAim(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::retargetAim");
|
||||
global::navigationHandler->orbitalNavigator().startRetargetAim();
|
||||
return 0;
|
||||
// Reset the camera direction to point at the aim node.
|
||||
[[codegen::luawrap]] void retargetAim() {
|
||||
openspace::global::navigationHandler->orbitalNavigator().startRetargetAim();
|
||||
}
|
||||
|
||||
int bindJoystickAxis(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 3, 7 }, "lua::bindJoystickAxis");
|
||||
auto [joystickName, axis, axisType, shouldInvert, joystickType, isSticky,
|
||||
sensitivity] =
|
||||
ghoul::lua::values<
|
||||
std::string, int, std::string, std::optional<bool>,
|
||||
std::optional<std::string>, std::optional<bool>, std::optional<double>
|
||||
>(L);
|
||||
shouldInvert = shouldInvert.value_or(false);
|
||||
isSticky = isSticky.value_or(false);
|
||||
sensitivity = sensitivity.value_or(0.0);
|
||||
joystickType = joystickType.value_or("JoystickLike");
|
||||
|
||||
/**
|
||||
* Finds the input joystick with the given 'name' and binds the axis identified by the
|
||||
* second argument to be used as the type identified by the third argument. If
|
||||
* 'isInverted' is 'true', the axis value is inverted. 'joystickType' is if the joystick
|
||||
* behaves more like a joystick or a trigger, where the first is the default. If
|
||||
* 'isSticky' is 'true', the value is calculated relative to the previous value. If
|
||||
* 'sensitivity' is given then that value will affect the sensitivity of the axis together
|
||||
* with the global sensitivity.
|
||||
*/
|
||||
[[codegen::luawrap]] void bindJoystickAxis(std::string joystickName, int axis,
|
||||
std::string axisType,
|
||||
bool shouldInvert = false,
|
||||
std::string joystickType = "JoystickLike",
|
||||
bool isSticky = false,
|
||||
double sensitivity = 0.0)
|
||||
{
|
||||
using namespace openspace;
|
||||
using JoystickCameraStates = interaction::JoystickCameraStates;
|
||||
global::navigationHandler->setJoystickAxisMapping(
|
||||
std::move(joystickName),
|
||||
axis,
|
||||
ghoul::from_string<interaction::JoystickCameraStates::AxisType>(axisType),
|
||||
interaction::JoystickCameraStates::AxisInvert(*shouldInvert),
|
||||
ghoul::from_string<interaction::JoystickCameraStates::JoystickType>(*joystickType),
|
||||
*isSticky,
|
||||
*sensitivity
|
||||
ghoul::from_string<JoystickCameraStates::AxisType>(axisType),
|
||||
JoystickCameraStates::AxisInvert(shouldInvert),
|
||||
ghoul::from_string<JoystickCameraStates::JoystickType>(joystickType),
|
||||
isSticky,
|
||||
sensitivity
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bindJoystickAxisProperty(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 3, 7 }, "lua::bindJoystickAxisProperty");
|
||||
auto [joystickName, axis, propertyUri, min, max, shouldInvert, isRemote] =
|
||||
ghoul::lua::values<
|
||||
std::string, int, std::string, std::optional<float>, std::optional<float>,
|
||||
std::optional<bool>, std::optional<bool>
|
||||
>(L);
|
||||
min = min.value_or(0.f);
|
||||
max = max.value_or(1.f);
|
||||
shouldInvert = shouldInvert.value_or(false);
|
||||
isRemote = isRemote.value_or(true);
|
||||
|
||||
/**
|
||||
* Finds the input joystick with the given 'name' and binds the axis identified by the
|
||||
* second argument to be bound to the property identified by the third argument. 'min' and
|
||||
* 'max' is the minimum and the maximum allowed value for the given property and the axis
|
||||
* value is rescaled from [-1, 1] to [min, max], default is [0, 1]. If 'isInverted' is
|
||||
* 'true', the axis value is inverted. The last argument determines whether the property
|
||||
* change is going to be executed locally or remotely, where the latter is the default.
|
||||
*/
|
||||
[[codegen::luawrap]] void bindJoystickAxisProperty(std::string joystickName, int axis,
|
||||
std::string propertyUri,
|
||||
float min = 0.f, float max = 1.f,
|
||||
bool shouldInvert = false,
|
||||
bool isRemote = true)
|
||||
{
|
||||
using namespace openspace;
|
||||
global::navigationHandler->setJoystickAxisMappingProperty(
|
||||
std::move(joystickName),
|
||||
axis,
|
||||
std::move(propertyUri),
|
||||
*min,
|
||||
*max,
|
||||
interaction::JoystickCameraStates::AxisInvert(*shouldInvert),
|
||||
*isRemote
|
||||
min,
|
||||
max,
|
||||
interaction::JoystickCameraStates::AxisInvert(shouldInvert),
|
||||
isRemote
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int joystickAxis(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::joystickAxis");
|
||||
auto [joystickName, axis] = ghoul::lua::values<std::string, int>(L);
|
||||
/**
|
||||
* Finds the input joystick with the given 'name' and returns the joystick axis
|
||||
* information for the passed axis. The information that is returned is the current axis
|
||||
* binding as a string, whether the values are inverted as bool, the joystick type as a
|
||||
* string, whether the axis is sticky as bool, the sensitivity as number, the property uri
|
||||
* bound to the axis as string (empty is type is not Property), the min and max values for
|
||||
* the property as numbers and whether the property change will be executed remotly as
|
||||
* bool.
|
||||
*/
|
||||
[[codegen::luawrap]]
|
||||
std::tuple<std::string, bool, std::string, bool, double, std::string, float, float, bool>
|
||||
joystickAxis(std::string joystickName, int axis)
|
||||
{
|
||||
using namespace openspace;
|
||||
|
||||
using AI = interaction::JoystickCameraStates::AxisInformation;
|
||||
AI info = global::navigationHandler->joystickAxisMapping(joystickName, axis);
|
||||
interaction::JoystickCameraStates::AxisInformation info =
|
||||
global::navigationHandler->joystickAxisMapping(joystickName, axis);
|
||||
|
||||
ghoul::lua::push(
|
||||
L,
|
||||
return {
|
||||
ghoul::to_string(info.type),
|
||||
static_cast<bool>(info.invert),
|
||||
info.invert,
|
||||
ghoul::to_string(info.joystickType),
|
||||
info.isSticky,
|
||||
info.sensitivity,
|
||||
@@ -217,67 +211,74 @@ int joystickAxis(lua_State* L) {
|
||||
info.minValue,
|
||||
info.maxValue,
|
||||
info.isRemote
|
||||
);
|
||||
return 9;
|
||||
};
|
||||
}
|
||||
|
||||
int setJoystickAxisDeadzone(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::setJoystickAxisDeadzone");
|
||||
auto [joystickName, axis, deadzone] = ghoul::lua::values<std::string, int, float>(L);
|
||||
|
||||
/**
|
||||
* Finds the input joystick with the given 'name' and sets the deadzone for a particular
|
||||
* joystick axis, which means that any input less than this value is completely ignored.
|
||||
*/
|
||||
[[codegen::luawrap]] void setJoystickAxisDeadZone(std::string joystickName, int axis,
|
||||
float deadzone)
|
||||
{
|
||||
using namespace openspace;
|
||||
global::navigationHandler->setJoystickAxisDeadzone(joystickName, axis, deadzone);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int joystickAxisDeadzone(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::joystickAxisDeadzone");
|
||||
auto [joystickName, axis] = ghoul::lua::values<std::string, int>(L);
|
||||
|
||||
const float deadzone = global::navigationHandler->joystickAxisDeadzone(joystickName, axis);
|
||||
ghoul::lua::push(L, deadzone);
|
||||
return 1;
|
||||
/**
|
||||
* Returns the deadzone for the desired axis of the provided joystick.
|
||||
*/
|
||||
[[codegen::luawrap]] float joystickAxisDeadzone(std::string joystickName, int axis) {
|
||||
float deadzone = openspace::global::navigationHandler->joystickAxisDeadzone(
|
||||
joystickName,
|
||||
axis
|
||||
);
|
||||
return deadzone;
|
||||
}
|
||||
|
||||
int bindJoystickButton(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 4, 6 }, "lua::bindJoystickButton");
|
||||
auto [joystickName, button, command, documentation, actionStr, isRemote] =
|
||||
ghoul::lua::values<
|
||||
std::string,
|
||||
int,
|
||||
std::string,
|
||||
std::string,
|
||||
std::optional<std::string>,
|
||||
std::optional<bool>
|
||||
>(L);
|
||||
actionStr = actionStr.value_or("Press");
|
||||
isRemote = isRemote.value_or(true);
|
||||
|
||||
interaction::JoystickAction action =
|
||||
ghoul::from_string<interaction::JoystickAction>(*actionStr);
|
||||
/**
|
||||
* Finds the input joystick with the given 'name' and binds a Lua script given by the
|
||||
* third argument to be executed when the joystick button identified by the second
|
||||
* argument is triggered. The fifth argument determines when the script should be
|
||||
* executed, this defaults to 'Press', which means that the script is run when the user
|
||||
* presses the button. The fourth arguemnt is the documentation of the script in the third
|
||||
* argument. The sixth argument determines whether the command is going to be executable
|
||||
* locally or remotely, where the latter is the default.
|
||||
*/
|
||||
[[codegen::luawrap]] void bindJoystickButton(std::string joystickName, int button,
|
||||
std::string command,
|
||||
std::string documentation,
|
||||
std::string action = "Press",
|
||||
bool isRemote = true)
|
||||
{
|
||||
using namespace openspace;
|
||||
interaction::JoystickAction act =
|
||||
ghoul::from_string<interaction::JoystickAction>(action);
|
||||
|
||||
global::navigationHandler->bindJoystickButtonCommand(
|
||||
joystickName,
|
||||
button,
|
||||
command,
|
||||
action,
|
||||
interaction::JoystickCameraStates::ButtonCommandRemote(*isRemote),
|
||||
act,
|
||||
interaction::JoystickCameraStates::ButtonCommandRemote(isRemote),
|
||||
documentation
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int clearJoystickButton(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::clearJoystickButton");
|
||||
auto [joystickName, button] = ghoul::lua::values<std::string, int>(L);
|
||||
|
||||
global::navigationHandler->clearJoystickButtonCommand(joystickName, button);
|
||||
return 0;
|
||||
/**
|
||||
* Finds the input joystick with the given 'name' and removes all commands that are
|
||||
* currently bound to the button identified by the second argument.
|
||||
*/
|
||||
[[codegen::luawrap]] void clearJoystickButton(std::string joystickName, int button) {
|
||||
openspace::global::navigationHandler->clearJoystickButtonCommand(joystickName, button);
|
||||
}
|
||||
|
||||
int joystickButton(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::joystickButton");
|
||||
auto [joystickName, button] = ghoul::lua::values<std::string, int>(L);
|
||||
|
||||
/**
|
||||
* Finds the input joystick with the given 'name' and returns the script that is currently
|
||||
* bound to be executed when the provided button is pressed.
|
||||
*/
|
||||
[[codegen::luawrap]] std::string joystickButton(std::string joystickName, int button) {
|
||||
using namespace openspace;
|
||||
const std::vector<std::string>& cmds =
|
||||
global::navigationHandler->joystickButtonCommand(joystickName, button);
|
||||
|
||||
@@ -289,74 +290,63 @@ int joystickButton(lua_State* L) {
|
||||
return lhs + ";" + rhs;
|
||||
}
|
||||
);
|
||||
ghoul::lua::push(L, cmd);
|
||||
return 1;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
int addGlobalRotation(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::addGlobalRotation");
|
||||
auto [v1, v2] = ghoul::lua::values<double, double>(L);
|
||||
|
||||
// Directly adds to the global rotation of the camera.
|
||||
[[codegen::luawrap]] void addGlobalRotation(double v1, double v2) {
|
||||
using namespace openspace;
|
||||
global::navigationHandler->orbitalNavigator().scriptStates().addGlobalRotation(
|
||||
glm::dvec2(v1, v2)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int addLocalRotation(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::addLocalRotation");
|
||||
auto [v1, v2] = ghoul::lua::values<double, double>(L);
|
||||
|
||||
// Directly adds to the local rotation of the camera.
|
||||
[[codegen::luawrap]] void addLocalRotation(double v1, double v2) {
|
||||
using namespace openspace;
|
||||
global::navigationHandler->orbitalNavigator().scriptStates().addLocalRotation(
|
||||
glm::dvec2(v1, v2)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int addTruckMovement(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::addTruckMovement");
|
||||
auto [v1, v2] = ghoul::lua::values<double, double>(L);
|
||||
|
||||
// Directly adds to the truck movement of the camera.
|
||||
[[codegen::luawrap]] void addTruckMovement(double v1, double v2) {
|
||||
using namespace openspace;
|
||||
global::navigationHandler->orbitalNavigator().scriptStates().addTruckMovement(
|
||||
glm::dvec2(v1, v2)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int addLocalRoll(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::addLocalRoll");
|
||||
auto [v1, v2] = ghoul::lua::values<double, double>(L);
|
||||
|
||||
// Directly adds to the local roll of the camera.
|
||||
[[codegen::luawrap]] void addLocalRoll(double v1, double v2) {
|
||||
using namespace openspace;
|
||||
global::navigationHandler->orbitalNavigator().scriptStates().addLocalRoll(
|
||||
glm::dvec2(v1, v2)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int addGlobalRoll(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::addGlobalRoll");
|
||||
auto [v1, v2] = ghoul::lua::values<double, double>(L);
|
||||
|
||||
// Directly adds to the global roll of the camera.
|
||||
[[codegen::luawrap]] void addGlobalRoll(double v1, double v2) {
|
||||
using namespace openspace;
|
||||
global::navigationHandler->orbitalNavigator().scriptStates().addGlobalRoll(
|
||||
glm::dvec2(v1, v2)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int triggerIdleBehavior(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, {0, 1}, "lua::triggerIdleBehavior");
|
||||
std::optional<std::string> choice = ghoul::lua::value<std::optional<std::string>>(L);
|
||||
|
||||
/**
|
||||
* Immediately start applying the chosen IdleBehavior. If none is specified, use the one
|
||||
* set to default in the OrbitalNavigator.
|
||||
*/
|
||||
[[codegen::luawrap]] void triggerIdleBehavior(std::string choice = "") {
|
||||
using namespace openspace;
|
||||
try {
|
||||
global::navigationHandler->orbitalNavigator().triggerIdleBehavior(
|
||||
choice.value_or("")
|
||||
);
|
||||
global::navigationHandler->orbitalNavigator().triggerIdleBehavior(choice);
|
||||
}
|
||||
catch (ghoul::RuntimeError& e) {
|
||||
return ghoul::lua::luaError(L, e.message);
|
||||
throw ghoul::lua::LuaError(e.message);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace openspace::luascriptfunctions
|
||||
#include "navigationhandler_lua_codegen.cpp"
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -27,18 +27,28 @@
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/camera/camerapose.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/navigationstate.h>
|
||||
#include <openspace/navigation/pathnavigator.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <ghoul/filesystem/file.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
#include <glm/gtx/vector_angle.hpp>
|
||||
#include <vector>
|
||||
|
||||
#include "pathnavigator_lua.inl"
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "PathNavigator";
|
||||
|
||||
@@ -97,8 +107,6 @@ namespace {
|
||||
};
|
||||
} // namespace
|
||||
|
||||
#include "pathnavigator_lua.inl"
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
PathNavigator::PathNavigator()
|
||||
@@ -467,95 +475,17 @@ scripting::LuaLibrary PathNavigator::luaLibrary() {
|
||||
return {
|
||||
"pathnavigation",
|
||||
{
|
||||
{
|
||||
"isFlying",
|
||||
&luascriptfunctions::isFlying,
|
||||
"",
|
||||
"Returns true if a camera path is currently running, and false otherwise"
|
||||
},
|
||||
{
|
||||
"continuePath",
|
||||
&luascriptfunctions::continuePath,
|
||||
"",
|
||||
"Continue playing a paused camera path"
|
||||
},
|
||||
{
|
||||
"pausePath",
|
||||
&luascriptfunctions::pausePath,
|
||||
"",
|
||||
"Pause a playing camera path"
|
||||
},
|
||||
{
|
||||
"stopPath",
|
||||
&luascriptfunctions::stopPath,
|
||||
"",
|
||||
"Stops a path, if one is being played"
|
||||
},
|
||||
{
|
||||
"flyTo",
|
||||
&luascriptfunctions::flyTo,
|
||||
"string [, bool, double]",
|
||||
"Move the camera to the node with the specified identifier. The optional "
|
||||
"double specifies the duration of the motion, in seconds. If the optional "
|
||||
"bool is set to true the target up vector for camera is set based on the "
|
||||
"target node. Either of the optional parameters can be left out."
|
||||
},
|
||||
{
|
||||
"flyToHeight",
|
||||
&luascriptfunctions::flyToHeight,
|
||||
"string, double [, bool, double]",
|
||||
"Move the camera to the node with the specified identifier. The second "
|
||||
"argument is the desired target height above the target node's bounding "
|
||||
"sphere, in meters. The optional double specifies the duration of the "
|
||||
"motion, in seconds. If the optional bool is set to true, the target "
|
||||
"up vector for camera is set based on the target node. Either of the "
|
||||
"optional parameters can be left out."
|
||||
},
|
||||
{
|
||||
"flyToNavigationState",
|
||||
&luascriptfunctions::flyToNavigationState,
|
||||
"table, [double]",
|
||||
"Create a path to the navigation state described by the input table. "
|
||||
"The optional double specifies the target duration of the motion, "
|
||||
"in seconds. Note that roll must be included for the target up "
|
||||
"direction to be taken into account."
|
||||
},
|
||||
{
|
||||
"zoomToFocus",
|
||||
&luascriptfunctions::zoomToFocus,
|
||||
"[duration]",
|
||||
"Zoom linearly to the current focus node, using the default distance."
|
||||
"The optional input parameter specifies the duration for the motion, "
|
||||
"in seconds."
|
||||
},
|
||||
{
|
||||
"zoomToDistance",
|
||||
&luascriptfunctions::zoomToDistance,
|
||||
"distance, [duration]",
|
||||
"Fly linearly to a specific distance in relation to the focus node. "
|
||||
"The distance is given in meters above the bounding sphere of the "
|
||||
"current focus node."
|
||||
"The optional input parameter specifies the duration for the motion, "
|
||||
"in seconds."
|
||||
},
|
||||
{
|
||||
"zoomToDistanceRelative",
|
||||
&luascriptfunctions::zoomToDistanceRelative,
|
||||
"distance, [duration]",
|
||||
"Fly linearly to a specific distance in relation to the focus node. "
|
||||
"The distance is given as a multiple of the bounding sphere of the "
|
||||
"current focus node. That is, a value of 1 will result in a position "
|
||||
"at a distance of one times the size of the bounding sphere away from "
|
||||
"the object."
|
||||
"The optional input parameter specifies the duration for the motion, "
|
||||
"in seconds."
|
||||
},
|
||||
{
|
||||
"createPath",
|
||||
&luascriptfunctions::createPath,
|
||||
"table",
|
||||
"Create a camera path as described by the lua table input argument"
|
||||
},
|
||||
codegen::lua::IsFlying,
|
||||
codegen::lua::ContinuePath,
|
||||
codegen::lua::PausePath,
|
||||
codegen::lua::StopPath,
|
||||
codegen::lua::FlyTo,
|
||||
codegen::lua::FlyToHeight,
|
||||
codegen::lua::FlyToNavigationState,
|
||||
codegen::lua::ZoomToFocus,
|
||||
codegen::lua::ZoomToDistance,
|
||||
codegen::lua::ZoomToDistanceRelative,
|
||||
codegen::lua::CreatePath
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,63 +22,50 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/navigationstate.h>
|
||||
#include <openspace/navigation/pathnavigator.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <ghoul/filesystem/file.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <glm/gtx/vector_angle.hpp>
|
||||
|
||||
namespace openspace::luascriptfunctions {
|
||||
|
||||
int isFlying(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::isFlying");
|
||||
namespace {
|
||||
|
||||
// Returns true if a camera path is currently running, and false otherwise.
|
||||
[[codegen::luawrap]] bool isFlying() {
|
||||
using namespace openspace;
|
||||
bool hasFinished = global::navigationHandler->pathNavigator().hasFinished();
|
||||
ghoul::lua::push(L, !hasFinished);
|
||||
return 1;
|
||||
return hasFinished;
|
||||
}
|
||||
|
||||
int continuePath(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::continuePath");
|
||||
global::navigationHandler->pathNavigator().continuePath();
|
||||
return 0;
|
||||
// Continue playing a paused camera path.
|
||||
[[codegen::luawrap]] void continuePath() {
|
||||
openspace::global::navigationHandler->pathNavigator().continuePath();
|
||||
}
|
||||
|
||||
int pausePath(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::pausePath");
|
||||
global::navigationHandler->pathNavigator().pausePath();
|
||||
return 0;
|
||||
// Pause a playing camera path.
|
||||
[[codegen::luawrap]] void pausePath() {
|
||||
openspace::global::navigationHandler->pathNavigator().pausePath();
|
||||
}
|
||||
|
||||
int stopPath(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::stopPath");
|
||||
global::navigationHandler->pathNavigator().abortPath();
|
||||
return 0;
|
||||
// Stops a path, if one is being played.
|
||||
[[codegen::luawrap]] void stopPath() {
|
||||
openspace::global::navigationHandler->pathNavigator().abortPath();
|
||||
}
|
||||
|
||||
int flyTo(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 1, 3 }, "lua::flyTo");
|
||||
auto [nodeIdentifier, useUpFromTargetOrDuration, duration] = ghoul::lua::values<
|
||||
std::string, std::optional<std::variant<bool, double>>, std::optional<double>
|
||||
>(L);
|
||||
|
||||
/**
|
||||
* Move the camera to the node with the specified identifier. The optional double
|
||||
* specifies the duration of the motion, in seconds. If the optional bool is set to true
|
||||
* the target up vector for camera is set based on the target node. Either of the optional
|
||||
* parameters can be left out.
|
||||
*/
|
||||
[[codegen::luawrap]] void flyTo(std::string nodeIdentifier,
|
||||
std::optional<std::variant<bool, double>> useUpFromTargetOrDuration,
|
||||
std::optional<double> duration)
|
||||
{
|
||||
using namespace openspace;
|
||||
if (useUpFromTargetOrDuration.has_value() &&
|
||||
std::holds_alternative<double>(*useUpFromTargetOrDuration)
|
||||
&& duration.has_value())
|
||||
std::holds_alternative<double>(*useUpFromTargetOrDuration) &&
|
||||
duration.has_value())
|
||||
{
|
||||
return ghoul::lua::luaError(L, "Duration cannot be specified twice");
|
||||
throw ghoul::lua::LuaError("Duration cannot be specified twice");
|
||||
}
|
||||
|
||||
if (!sceneGraphNode(nodeIdentifier)) {
|
||||
return ghoul::lua::luaError(L, "Unknown node name: " + nodeIdentifier);
|
||||
throw ghoul::lua::LuaError("Unknown node name: " + nodeIdentifier);
|
||||
}
|
||||
|
||||
ghoul::Dictionary insDict;
|
||||
@@ -94,7 +81,7 @@ int flyTo(lua_State* L) {
|
||||
else {
|
||||
double d = std::get<double>(*useUpFromTargetOrDuration);
|
||||
if (d <= 0.0) {
|
||||
return ghoul::lua::luaError(L, "Duration must be larger than zero");
|
||||
throw ghoul::lua::LuaError("Duration must be larger than zero");
|
||||
}
|
||||
insDict.setValue("Duration", d);
|
||||
}
|
||||
@@ -102,7 +89,7 @@ int flyTo(lua_State* L) {
|
||||
if (duration.has_value()) {
|
||||
double d = *duration;
|
||||
if (d <= 0.0) {
|
||||
return ghoul::lua::luaError(L, "Duration must be larger than zero");
|
||||
throw ghoul::lua::LuaError("Duration must be larger than zero");
|
||||
}
|
||||
insDict.setValue("Duration", d);
|
||||
}
|
||||
@@ -112,20 +99,22 @@ int flyTo(lua_State* L) {
|
||||
if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
|
||||
global::navigationHandler->pathNavigator().startPath();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flyToHeight(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 2, 4 }, "lua::flyToHeight");
|
||||
auto [nodeIdentifier, height, useUpFromTargetOrDuration, duration] =
|
||||
ghoul::lua::values<
|
||||
std::string, double, std::optional<std::variant<bool, double>>,
|
||||
std::optional<double>
|
||||
>(L);
|
||||
|
||||
|
||||
/**
|
||||
* Move the camera to the node with the specified identifier. The second argument is the
|
||||
* desired target height above the target node's bounding sphere, in meters. The optional
|
||||
* double specifies the duration of the motion, in seconds. If the optional bool is set to
|
||||
* true, the target up vector for camera is set based on the target node. Either of the
|
||||
* optional parameters can be left out.
|
||||
*/
|
||||
[[codegen::luawrap]] void flyToHeight(std::string nodeIdentifier, double height,
|
||||
std::optional<std::variant<bool, double>> useUpFromTargetOrDuration,
|
||||
std::optional<double> duration)
|
||||
{
|
||||
using namespace openspace;
|
||||
if (!sceneGraphNode(nodeIdentifier)) {
|
||||
return ghoul::lua::luaError(L, "Unknown node name: " + nodeIdentifier);
|
||||
throw ghoul::lua::LuaError("Unknown node name: " + nodeIdentifier);
|
||||
}
|
||||
|
||||
ghoul::Dictionary insDict;
|
||||
@@ -142,7 +131,7 @@ int flyToHeight(lua_State* L) {
|
||||
else {
|
||||
double d = std::get<double>(*useUpFromTargetOrDuration);
|
||||
if (d <= 0.0) {
|
||||
return ghoul::lua::luaError(L, "Duration must be larger than zero");
|
||||
throw ghoul::lua::LuaError("Duration must be larger than zero");
|
||||
}
|
||||
insDict.setValue("Duration", d);
|
||||
}
|
||||
@@ -150,7 +139,7 @@ int flyToHeight(lua_State* L) {
|
||||
if (duration.has_value()) {
|
||||
double d = *duration;
|
||||
if (d <= 0.0) {
|
||||
return ghoul::lua::luaError(L, "Duration must be larger than zero");
|
||||
throw ghoul::lua::LuaError("Duration must be larger than zero");
|
||||
}
|
||||
insDict.setValue("Duration", d);
|
||||
}
|
||||
@@ -160,27 +149,27 @@ int flyToHeight(lua_State* L) {
|
||||
if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
|
||||
global::navigationHandler->pathNavigator().startPath();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flyToNavigationState(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 1, 2 }, "lua::flyToNavigationState");
|
||||
auto [navigationState, duration] =
|
||||
ghoul::lua::values<ghoul::Dictionary, std::optional<double>>(L);
|
||||
|
||||
/**
|
||||
* Create a path to the navigation state described by the input table. The optional
|
||||
* double specifies the target duration of the motion, in seconds. Note that roll must be
|
||||
* included for the target up direction to be taken into account.
|
||||
*/
|
||||
[[codegen::luawrap]] void flyToNavigationState(ghoul::Dictionary navigationState,
|
||||
std::optional<double> duration)
|
||||
{
|
||||
using namespace openspace;
|
||||
try {
|
||||
openspace::documentation::testSpecificationAndThrow(
|
||||
documentation::testSpecificationAndThrow(
|
||||
interaction::NavigationState::Documentation(),
|
||||
navigationState,
|
||||
"NavigationState"
|
||||
);
|
||||
}
|
||||
catch (documentation::SpecificationError& e) {
|
||||
catch (const documentation::SpecificationError& e) {
|
||||
LERRORC("flyToNavigationState", ghoul::to_string(e.result));
|
||||
return ghoul::lua::luaError(
|
||||
L, fmt::format("Unable to create a path: {}", e.what())
|
||||
);
|
||||
throw ghoul::lua::LuaError(fmt::format("Unable to create a path: {}", e.what()));
|
||||
}
|
||||
|
||||
ghoul::Dictionary instruction;
|
||||
@@ -190,7 +179,7 @@ int flyToNavigationState(lua_State* L) {
|
||||
if (duration.has_value()) {
|
||||
double d = *duration;
|
||||
if (d <= 0.0) {
|
||||
return ghoul::lua::luaError(L, "Duration must be larger than zero");
|
||||
throw ghoul::lua::LuaError("Duration must be larger than zero");
|
||||
}
|
||||
instruction.setValue("Duration", d);
|
||||
}
|
||||
@@ -200,16 +189,17 @@ int flyToNavigationState(lua_State* L) {
|
||||
if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
|
||||
global::navigationHandler->pathNavigator().startPath();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int zoomToFocus(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 0, 1 }, "lua::zoomToFocus");
|
||||
std::optional<double> duration = ghoul::lua::value<std::optional<double>>(L);
|
||||
|
||||
/**
|
||||
* Zoom linearly to the current focus node, using the default distance. The optional input
|
||||
* parameter specifies the duration for the motion, in seconds.
|
||||
*/
|
||||
[[codegen::luawrap]] void zoomToFocus(std::optional<double> duration) {
|
||||
using namespace openspace;
|
||||
const SceneGraphNode* node = global::navigationHandler->anchorNode();
|
||||
if (!node) {
|
||||
return ghoul::lua::luaError(L, "Could not determine current focus node");
|
||||
throw ghoul::lua::LuaError("Could not determine current focus node");
|
||||
}
|
||||
|
||||
ghoul::Dictionary insDict;
|
||||
@@ -220,7 +210,7 @@ int zoomToFocus(lua_State* L) {
|
||||
if (duration.has_value()) {
|
||||
double d = *duration;
|
||||
if (d <= 0.0) {
|
||||
return ghoul::lua::luaError(L, "Duration must be larger than zero");
|
||||
throw ghoul::lua::LuaError("Duration must be larger than zero");
|
||||
}
|
||||
insDict.setValue("Duration", d);
|
||||
}
|
||||
@@ -230,22 +220,23 @@ int zoomToFocus(lua_State* L) {
|
||||
if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
|
||||
global::navigationHandler->pathNavigator().startPath();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int zoomToDistance(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 1, 2 }, "lua::zoomToDistance");
|
||||
auto [distance, duration] =
|
||||
ghoul::lua::values<double, std::optional<double>>(L);
|
||||
|
||||
/**
|
||||
* Fly linearly to a specific distance in relation to the focus node. The distance is
|
||||
* given in meters above the bounding sphere of the current focus node. The optional input
|
||||
* parameter specifies the duration for the motion, in seconds.
|
||||
*/
|
||||
[[codegen::luawrap]] void zoomToDistance(double distance, std::optional<double> duration)
|
||||
{
|
||||
using namespace openspace;
|
||||
if (distance <= 0.0) {
|
||||
return ghoul::lua::luaError(L, "The distance must be larger than zero");
|
||||
throw ghoul::lua::LuaError("The distance must be larger than zero");
|
||||
}
|
||||
|
||||
const SceneGraphNode* node = global::navigationHandler->anchorNode();
|
||||
if (!node) {
|
||||
return ghoul::lua::luaError(L, "Could not determine current focus node");
|
||||
throw ghoul::lua::LuaError("Could not determine current focus node");
|
||||
}
|
||||
|
||||
ghoul::Dictionary insDict;
|
||||
@@ -257,7 +248,7 @@ int zoomToDistance(lua_State* L) {
|
||||
if (duration.has_value()) {
|
||||
double d = *duration;
|
||||
if (d <= 0.0) {
|
||||
return ghoul::lua::luaError(L, "Duration must be larger than zero");
|
||||
throw ghoul::lua::LuaError("Duration must be larger than zero");
|
||||
}
|
||||
insDict.setValue("Duration", d);
|
||||
}
|
||||
@@ -267,22 +258,26 @@ int zoomToDistance(lua_State* L) {
|
||||
if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
|
||||
global::navigationHandler->pathNavigator().startPath();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int zoomToDistanceRelative(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 1, 2 }, "lua::zoomToDistanceRelative");
|
||||
auto [distance, duration] =
|
||||
ghoul::lua::values<double, std::optional<double>>(L);
|
||||
|
||||
/**
|
||||
* Fly linearly to a specific distance in relation to the focus node. The distance is
|
||||
* given as a multiple of the bounding sphere of the current focus node. That is, a value
|
||||
* of 1 will result in a position at a distance of one times the size of the bounding
|
||||
* sphere away from the object. The optional input parameter specifies the duration for
|
||||
* the motion, in seconds.
|
||||
*/
|
||||
[[codegen::luawrap]] void zoomToDistanceRelative(double distance,
|
||||
std::optional<double> duration)
|
||||
{
|
||||
using namespace openspace;
|
||||
if (distance <= 0.0) {
|
||||
return ghoul::lua::luaError(L, "The distance must be larger than zero");
|
||||
throw ghoul::lua::LuaError("The distance must be larger than zero");
|
||||
}
|
||||
|
||||
const SceneGraphNode* node = global::navigationHandler->anchorNode();
|
||||
if (!node) {
|
||||
return ghoul::lua::luaError(L, "Could not determine current focus node");
|
||||
throw ghoul::lua::LuaError("Could not determine current focus node");
|
||||
}
|
||||
|
||||
distance *= node->boundingSphere();
|
||||
@@ -296,7 +291,7 @@ int zoomToDistanceRelative(lua_State* L) {
|
||||
if (duration.has_value()) {
|
||||
double d = *duration;
|
||||
if (d <= 0.0) {
|
||||
return ghoul::lua::luaError(L, "Duration must be larger than zero");
|
||||
throw ghoul::lua::LuaError("Duration must be larger than zero");
|
||||
}
|
||||
insDict.setValue("Duration", d);
|
||||
}
|
||||
@@ -306,19 +301,17 @@ int zoomToDistanceRelative(lua_State* L) {
|
||||
if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
|
||||
global::navigationHandler->pathNavigator().startPath();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int createPath(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::createPath");
|
||||
ghoul::Dictionary dictionary = ghoul::lua::value<ghoul::Dictionary>(L);
|
||||
|
||||
global::navigationHandler->pathNavigator().createPath(dictionary);
|
||||
// Create a camera path as described by the lua table input argument.
|
||||
[[codegen::luawrap]] void createPath(ghoul::Dictionary path) {
|
||||
using namespace openspace;
|
||||
global::navigationHandler->pathNavigator().createPath(path);
|
||||
if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
|
||||
global::navigationHandler->pathNavigator().startPath();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace openspace::luascriptfunctions
|
||||
#include "pathnavigator_lua_codegen.cpp"
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -733,30 +733,10 @@ scripting::LuaLibrary ParallelPeer::luaLibrary() {
|
||||
return {
|
||||
"parallel",
|
||||
{
|
||||
{
|
||||
"connect",
|
||||
&luascriptfunctions::connect,
|
||||
"",
|
||||
"Connect to parallel"
|
||||
},
|
||||
{
|
||||
"disconnect",
|
||||
&luascriptfunctions::disconnect,
|
||||
"",
|
||||
"Disconnect from parallel"
|
||||
},
|
||||
{
|
||||
"requestHostship",
|
||||
&luascriptfunctions::requestHostship,
|
||||
"",
|
||||
"Request to be the host for this session"
|
||||
},
|
||||
{
|
||||
"resignHostship",
|
||||
&luascriptfunctions::resignHostship,
|
||||
"",
|
||||
"Resign hostship"
|
||||
},
|
||||
codegen::lua::Connect,
|
||||
codegen::lua::Disconnect,
|
||||
codegen::lua::RequestHostship,
|
||||
codegen::lua::ResignHostship
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user