mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-04 10:40:09 -06:00
Feature/timeline translation (#931)
* Work on timeline translations * Add Apollo 11 Descent data * Ability to display negative altitudes * Expose globe translation properties * Added timeline rotation, and some scene updates. * Cleaning up apollo_sites scene; fixing boulder 1 in place to adress heightmap issue * Use quaternion slerp instaet of linear interpolation + Cleanup * Change to old lem model while waiting for new version to be pushed to data repo * Small fixes
This commit is contained in:
committed by
Alexander Bock
parent
87df4a11a9
commit
c97d5126ec
@@ -2,12 +2,10 @@ asset.require('./base')
|
||||
|
||||
--moonrocks.scene
|
||||
local sceneHelper = asset.require('util/scene_helper')
|
||||
|
||||
-- local station2 = asset.require('scene/solarsystem/missions/apollo/bouldersstation2')
|
||||
-- local station6 = asset.require('scene/solarsystem/missions/apollo/bouldersstation6')
|
||||
-- local station7 = asset.require('scene/solarsystem/missions/apollo/bouldersstation7')
|
||||
asset.require('scene/solarsystem/missions/apollo/apollo11')
|
||||
asset.require('scene/solarsystem/missions/apollo/a11_lem')
|
||||
asset.require('scene/solarsystem/missions/apollo/a17_lem')
|
||||
asset.require('scene/solarsystem/missions/apollo/apollo_globebrowsing')
|
||||
asset.require('scene/solarsystem/missions/apollo/apollo_11_lem_flipbook')
|
||||
@@ -37,11 +35,11 @@ local Keybindings = {
|
||||
},
|
||||
{
|
||||
Key = "F11",
|
||||
Command = "openspace.time.setTime('1969 JUL 20 20:17:40');" ..
|
||||
Command = "openspace.time.setTime('1969 JUL 20 20:17:40');" ..
|
||||
"openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.HeightLayers.LRO_NAC_Apollo_11.Enabled', true);" ..
|
||||
"openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.ColorLayers.A11_M177481212_p_longlat.Enabled', true);" ..
|
||||
"openspace.setPropertyValueSingle('Scene.Moon.Renderable.LodScaleFactor', 20.11);" ..
|
||||
"openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'Apollo11LemModel');" ..
|
||||
"openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'Apollo11LemPosition');" ..
|
||||
"openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil);" ..
|
||||
"openspace.setPropertyValueSingle('Scene.Apollo11MoonTrail.Renderable.Enabled', true);" ..
|
||||
"openspace.setPropertyValueSingle('Scene.Apollo11LemTrail.Renderable.Enabled', true);",
|
||||
@@ -82,8 +80,11 @@ asset.onInitialize(function ()
|
||||
|
||||
sceneHelper.bindKeys(Keybindings)
|
||||
|
||||
openspace.markInterestingNodes({ "Moon", "Apollo11LemModel", "Apollo17LemModel", "Apollo11", "Apollo11LunarLander" })
|
||||
|
||||
openspace.markInterestingNodes({
|
||||
"Moon", "Apollo11LemModel", "Apollo17LemModel",
|
||||
"Apollo11", "Apollo11LunarLander",
|
||||
-- "Station_2_Boulder2", "Station_6_Fragment1"
|
||||
})
|
||||
-- To enable both sites by default, uncomment these lines
|
||||
-- openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.ColorLayers.A17_travmap.BlendMode', 0.000000);
|
||||
-- openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.ColorLayers.A17_travmap.Enabled', true);
|
||||
@@ -95,12 +96,19 @@ asset.onInitialize(function ()
|
||||
-- openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.ColorLayers.A17_station7.BlendMode', 0.000000);
|
||||
-- openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.HeightLayers.LRO_NAC_Apollo_11.Enabled', true);
|
||||
-- openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.ColorLayers.A11_M177481212_p_longlat.Enabled', true);
|
||||
|
||||
|
||||
openspace.setPropertyValueSingle('Scene.Apollo11LemDescentModel.Renderable.RotationVector', { 273.205475,6.904110,308.712311 });
|
||||
openspace.setPropertyValueSingle('Scene.Apollo11LemLandedModel.Renderable.RotationVector', { 273.205475,6.904110,308.712311 });
|
||||
|
||||
openspace.globebrowsing.goToGeo(moonAsset.Moon.Identifier, 20, -60, 15000000)
|
||||
|
||||
openspace.setPropertyValueSingle("Scene.Moon.Renderable.PerformShading", false)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function ()
|
||||
openspace.removeInterestingNodes({ "Moon", "Apollo11Lem", "Apollo17Lem", "Apollo11", "Apollo11LunarLander" })
|
||||
openspace.removeInterestingNodes({
|
||||
"Moon", "Apollo11Lem", "Apollo17Lem",
|
||||
"Apollo11", "Apollo11LemPosition",
|
||||
-- "Station_6_Fragment1", "Station_6_Fragments_2_3"
|
||||
})
|
||||
end)
|
||||
|
||||
@@ -15,8 +15,8 @@ local Apollo11Lem = {
|
||||
Globe = moonAsset.Moon.Identifier,
|
||||
Longitude = -360+23.47306,
|
||||
Latitude = 0.67402,
|
||||
FixedAltitude = -1927.65,
|
||||
UseFixedAltitude = true
|
||||
Altitude = -1927.65,
|
||||
UseHeightMap = false
|
||||
},
|
||||
},
|
||||
GUI = {
|
||||
|
||||
@@ -14,6 +14,7 @@ local Apollo17Lem = {
|
||||
Globe = moonAsset.Moon.Identifier,
|
||||
Longitude = -329.22833,
|
||||
Latitude = 20.19092,
|
||||
UseHeightmap = true
|
||||
},
|
||||
},
|
||||
GUI = {
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
local assetHelper = asset.require('util/asset_helper')
|
||||
local sunTransforms = asset.require('scene/solarsystem/sun/transforms')
|
||||
local descentKeyframes = asset.require('./apollo11_lem_descent.asset')
|
||||
local descentRotationKeyframes = asset.require('./apollo11_lem_descent_rotation.asset')
|
||||
local model = asset.require('scene/solarsystem/missions/apollo/lem_model')
|
||||
|
||||
asset.require('spice/base')
|
||||
|
||||
@@ -24,7 +27,7 @@ local kernels = {
|
||||
kernelsFolder .. '/apollo11_orbits_full9km.bsp',
|
||||
kernelsFolder .. '/apollo11_orbits_lm9km.bsp',
|
||||
}
|
||||
|
||||
--landing - 1969-07-20T20:17:40
|
||||
local apolloSpiceId = "-911"
|
||||
local apolloLemSpiceId = "-911500"
|
||||
|
||||
@@ -107,81 +110,44 @@ local Apollo11MoonTrail = {
|
||||
}
|
||||
}
|
||||
|
||||
-- Uncomment if you want to follow the mock decent
|
||||
-- local Apollo11LemPosition = {
|
||||
-- Identifier = "Apollo11LemPosition",
|
||||
-- Parent = "Moon",
|
||||
-- TimeFrame = {
|
||||
-- Type = "TimeFrameInterval",
|
||||
-- Start = "1969 JUL 20 19:10:25.183",
|
||||
-- End = "1969 JUL 20 20:17:46.183"
|
||||
-- },
|
||||
-- Transform = {
|
||||
-- Translation = {
|
||||
-- Type = "SpiceTranslation",
|
||||
-- Target = apolloLemSpiceId,
|
||||
-- Observer = "MOON",
|
||||
-- Frame = "MOON_ME",
|
||||
-- Kernels = kernels
|
||||
-- },
|
||||
-- },
|
||||
-- GUI = {
|
||||
-- Hidden = true,
|
||||
-- Name = "Apollo 11 Lunar Lander Position",
|
||||
-- Path = "/Solar System/Missions/Apollo/11"
|
||||
-- }
|
||||
-- }
|
||||
|
||||
-- local Apollo11LunarLanderModel = {
|
||||
-- Identifier = "Apollo11LunarLander",
|
||||
-- Parent = Apollo11LemPosition.Identifier,
|
||||
-- Transform = {
|
||||
-- Rotation = {
|
||||
-- Type = "StaticRotation",
|
||||
-- Rotation = {0.0, 0.0, -3.1415/2}
|
||||
-- },
|
||||
-- Scale = {
|
||||
-- Type = "StaticScale",
|
||||
-- Scale = 100.0
|
||||
-- }
|
||||
-- },
|
||||
-- TimeFrame = {
|
||||
-- Type = "TimeFrameInterval",
|
||||
-- Start = "1969 JUL 20 19:10:25.183",
|
||||
-- End = "1969 JUL 20 20:17:46.183"
|
||||
-- },
|
||||
-- Renderable = {
|
||||
-- Type = "RenderableModel",
|
||||
-- Geometry = {
|
||||
-- Type = "MultiModelGeometry",
|
||||
-- GeometryFile = modelFolder .. "/lem_nasa.obj"
|
||||
-- },
|
||||
-- ColorTexture = modelFolder .. "/gray.png",
|
||||
-- LightSources = assetHelper.getDefaultLightSources(sunTransforms.SolarSystemBarycenter.Identifier)
|
||||
-- },
|
||||
-- GUI = {
|
||||
-- Hidden = false,
|
||||
-- Name = "Apollo 11 Lunar Lander",
|
||||
-- Path = "/Solar System/Missions/Apollo/11"
|
||||
-- }
|
||||
-- }
|
||||
|
||||
local Apollo11LemTrail = {
|
||||
Identifier = "Apollo11LemTrail",
|
||||
Parent = "Moon",
|
||||
Renderable = {
|
||||
Type = "RenderableTrailTrajectory",
|
||||
Translation = {
|
||||
local lemTranslation = {
|
||||
Type = "TimelineTranslation",
|
||||
Keyframes = {
|
||||
-- 20:14:30 is an arbitrary cutoff, but last 4 minutes data in descentKeyframes
|
||||
-- begins at 20.14.40. Due to linear interpolation, we will get
|
||||
-- a 10s linear transition to the location where the descentKeyframes start.
|
||||
['1969 JUL 20 20:14:30'] = {
|
||||
Type = "SpiceTranslation",
|
||||
Target = apolloLemSpiceId,
|
||||
Observer = "MOON",
|
||||
Frame = "IAU_MOON",
|
||||
Kernels = kernels
|
||||
},
|
||||
Color = {0.780000,0.940000,0.340000 },
|
||||
['1969 JUL 20 20:14:40'] = {
|
||||
Type = "TimelineTranslation",
|
||||
Keyframes = descentKeyframes.keyframes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
local lemRotation = {
|
||||
Type = "TimelineRotation",
|
||||
Keyframes = descentRotationKeyframes.keyframes
|
||||
}
|
||||
|
||||
|
||||
|
||||
local Apollo11LemTrail = {
|
||||
Identifier = "Apollo11LemTrail",
|
||||
Parent = "Moon",
|
||||
Renderable = {
|
||||
Type = "RenderableTrailTrajectory",
|
||||
Translation = lemTranslation,
|
||||
Color = { 0.780000,0.940000,0.340000 },
|
||||
StartTime = "1969 JUL 20 19:10:25.183",
|
||||
EndTime = "1969 JUL 20 20:17:46.183",
|
||||
SampleInterval = 60,
|
||||
SampleInterval = 2,
|
||||
EnableFade = false,
|
||||
Enabled = false,
|
||||
},
|
||||
@@ -191,11 +157,91 @@ local Apollo11LemTrail = {
|
||||
}
|
||||
}
|
||||
|
||||
local Apollo11LemPosition = {
|
||||
Identifier = "Apollo11LemPosition",
|
||||
Parent = "Moon",
|
||||
TimeFrame = {
|
||||
Type = "TimeFrameInterval",
|
||||
Start = "1969 JUL 20 19:10:25.183"
|
||||
},
|
||||
Transform = {
|
||||
Translation = lemTranslation,
|
||||
Rotation = lemRotation
|
||||
},
|
||||
GUI = {
|
||||
Hidden = false,
|
||||
Name = "Apollo 11 Lunar Lander Position",
|
||||
Path = "/Solar System/Missions/Apollo/11"
|
||||
}
|
||||
}
|
||||
--landing - 1969-07-20T20:17:40
|
||||
|
||||
local Apollo11LemDescentModel = {
|
||||
Identifier = "Apollo11LemDescentModel",
|
||||
Parent = Apollo11LemPosition.Identifier,
|
||||
TimeFrame = {
|
||||
Type = "TimeFrameInterval",
|
||||
Start = "1969 JUL 19 19:38:29.183",
|
||||
End = "1969 JUL 20 20:17:40.0"
|
||||
},
|
||||
Transform = {
|
||||
Scale = {
|
||||
Type = "StaticScale",
|
||||
Scale = 0.24
|
||||
}
|
||||
},
|
||||
Renderable = {
|
||||
Type = "RenderableModel",
|
||||
Geometry = {
|
||||
Type = "MultiModelGeometry",
|
||||
GeometryFile = model.modelFolder .. "/LM-2_ver2clean.obj"
|
||||
},
|
||||
ColorTexture = model.modelFolder .. "/LM-2_ver2clean_u1_v1.jpeg",
|
||||
LightSources = assetHelper.getDefaultLightSources(sunTransforms.SolarSystemBarycenter.Identifier)
|
||||
},
|
||||
GUI = {
|
||||
Hidden = false,
|
||||
Name = "Apollo 11 Descent Lem",
|
||||
Path = "/Solar System/Missions/Apollo/11"
|
||||
}
|
||||
}
|
||||
|
||||
local Apollo11LemLandedModel = {
|
||||
Identifier = "Apollo11LemLandedModel",
|
||||
Parent = Apollo11LemPosition.Identifier,
|
||||
TimeFrame = {
|
||||
Type = "TimeFrameInterval",
|
||||
Start = "1969 JUL 20 20:17:40.0"
|
||||
},
|
||||
Transform = {
|
||||
Scale = {
|
||||
Type = "StaticScale",
|
||||
Scale = 0.24
|
||||
}
|
||||
},
|
||||
Renderable = {
|
||||
Type = "RenderableModel",
|
||||
Geometry = {
|
||||
Type = "MultiModelGeometry",
|
||||
GeometryFile = model.modelFolder .. "/LM-2_ver2clean.obj"
|
||||
},
|
||||
ColorTexture = model.modelFolder .. "/LM-2_ver2clean_u1_v1.jpeg",
|
||||
LightSources = assetHelper.getDefaultLightSources(sunTransforms.SolarSystemBarycenter.Identifier)
|
||||
},
|
||||
GUI = {
|
||||
Hidden = false,
|
||||
Name = "Apollo 11 Landed Lem",
|
||||
Path = "/Solar System/Missions/Apollo/11"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
local exportList = {
|
||||
Apollo11Position,
|
||||
-- Apollo11LemPosition,
|
||||
Apollo11Position,
|
||||
Apollo11LemPosition,
|
||||
Apollo11Model,
|
||||
-- Apollo11LunarLanderModel,
|
||||
Apollo11LemDescentModel,
|
||||
Apollo11LemLandedModel,
|
||||
Apollo11MoonTrail,
|
||||
Apollo11LemTrail,
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,74 @@
|
||||
local assetHelper = asset.require('util/asset_helper')
|
||||
local sunTransforms = asset.require('scene/solarsystem/sun/transforms')
|
||||
local kernelsFolder = asset.syncedResource({
|
||||
Name = "Apollo Kernels",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "apollo_spice",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local kernels = {
|
||||
kernelsFolder .. "/moon_080317.tf",
|
||||
kernelsFolder .. "/apollo8.tf",
|
||||
kernelsFolder .. "/moon_pa_de421_1900-2050.bpc",
|
||||
kernelsFolder .. '/apollo8.tsc',
|
||||
kernelsFolder .. '/apollo8.bsp',
|
||||
kernelsFolder .. '/apollo8_earthrise.bc',
|
||||
}
|
||||
|
||||
local apolloSpiceId = "-908"
|
||||
|
||||
|
||||
local Apollo8LaunchTrail = {
|
||||
Identifier = "Apollo8LaunchTrail",
|
||||
Parent = "Earth",
|
||||
Renderable = {
|
||||
Type = "RenderableTrailTrajectory",
|
||||
Translation = {
|
||||
Type = "SpiceTranslation",
|
||||
Target = apolloSpiceId,
|
||||
Observer = "EARTH",
|
||||
Frame = "IAU_EARTH",
|
||||
Kernels = kernels
|
||||
},
|
||||
Color = { 0.70, 0.50, 0.20 },
|
||||
StartTime = "1968 DEC 21 12:51:00",
|
||||
EndTime = "1968 DEC 21 23:23:22",
|
||||
SampleInterval = 30
|
||||
},
|
||||
GUI = {
|
||||
Name = "Apollo 8 Launch Trail",
|
||||
Path = "/Solar System/Missions/Apollo"
|
||||
}
|
||||
}
|
||||
|
||||
local Apollo8EarthBarycenterTrail = {
|
||||
Identifier = "Apollo8EarthBarycenterTrail",
|
||||
Parent = "EarthBarycenter",
|
||||
Renderable = {
|
||||
Type = "RenderableTrailTrajectory",
|
||||
Translation = {
|
||||
Type = "SpiceTranslation",
|
||||
Target = apolloSpiceId,
|
||||
Observer = "EARTH BARYCENTER",
|
||||
Frame = "GALACTIC",
|
||||
Kernels = kernels
|
||||
},
|
||||
Color = { 1, 0.0, 0.0 },
|
||||
StartTime = "1968 DEC 21",
|
||||
EndTime = "1968 DEC 28",
|
||||
SampleInterval = 30,
|
||||
Enabled = false,
|
||||
},
|
||||
GUI = {
|
||||
Name = "Apollo 8 Earth Barycenter Trail",
|
||||
Path = "/Solar System/Missions/Apollo"
|
||||
}
|
||||
}
|
||||
|
||||
local exportList = {
|
||||
Apollo8LaunchTrail,
|
||||
Apollo8EarthBarycenterTrail,
|
||||
}
|
||||
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, exportList)
|
||||
@@ -33,8 +33,8 @@ local Station2Boulder1Holder = {
|
||||
Globe = moonAsset.Moon.Identifier,
|
||||
Longitude = -360+30.5294692,
|
||||
Latitude = 20.098824,
|
||||
FixedAltitude = -2442.8,
|
||||
UseFixedAltitude = true
|
||||
Altitude = -2442.8,
|
||||
UseHeightMap = false
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
@@ -78,8 +78,8 @@ local Station2Boulder2Holder = {
|
||||
Globe = moonAsset.Moon.Identifier,
|
||||
Longitude = -360+30.5287892,
|
||||
Latitude = 20.098240,
|
||||
FixedAltitude = -2434.6,
|
||||
UseFixedAltitude = true
|
||||
Altitude = -2434.6,
|
||||
UseHeightMap = false
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
@@ -123,8 +123,8 @@ local Station2Boulder3Holder = {
|
||||
Globe = moonAsset.Moon.Identifier,
|
||||
Longitude = -360+30.5294692,
|
||||
Latitude = 20.098610,
|
||||
FixedAltitude = -2441.55,
|
||||
UseFixedAltitude = true
|
||||
Altitude = -2441.55,
|
||||
UseHeightMap = false
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
|
||||
@@ -37,6 +37,8 @@ local Station6Frag1Holder = {
|
||||
Globe = moonAsset.Moon.Identifier,
|
||||
Longitude = -360+30.80068,
|
||||
Latitude = 20.2903,
|
||||
Altitude = -2562.6,
|
||||
UseHeightmap = false
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
@@ -54,6 +56,8 @@ local Station6Frag1Model = {
|
||||
Globe = moonAsset.Moon.Identifier,
|
||||
Longitude = -360+30.8007,
|
||||
Latitude = 20.2903,
|
||||
Altitude = -2562.6,
|
||||
UseHeightmap = false
|
||||
}
|
||||
},
|
||||
Transform = {
|
||||
@@ -104,8 +108,8 @@ local Station6Frag2Model = {
|
||||
Globe = moonAsset.Moon.Identifier,
|
||||
Longitude = -360+30.80055,
|
||||
Latitude = 20.289808,
|
||||
FixedAltitude = -2566.5,
|
||||
UseFixedAltitude = true
|
||||
Altitude = -2566.5,
|
||||
UseHeightmap = false
|
||||
}
|
||||
},
|
||||
Renderable = {
|
||||
@@ -140,8 +144,8 @@ local Station6Frag3Model = {
|
||||
Globe = moonAsset.Moon.Identifier,
|
||||
Longitude = -360+30.80053,
|
||||
Latitude = 20.29030,
|
||||
FixedAltitude = -2563.0,
|
||||
UseFixedAltitude = true
|
||||
Altitude = -2563.0,
|
||||
UseHeightMap = false
|
||||
}
|
||||
},
|
||||
Renderable = {
|
||||
|
||||
@@ -34,8 +34,8 @@ local Station7BoulderHolder = {
|
||||
Globe = moonAsset.Moon.Identifier,
|
||||
Longitude = -360+30.8165882,
|
||||
Latitude = 20.2908556,
|
||||
FixedAltitude = -2593.5,
|
||||
UseFixedAltitude = true
|
||||
Altitude = -2593.5,
|
||||
UseHeightMap = true
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
|
||||
@@ -44,7 +44,12 @@ struct KeyframeBase {
|
||||
*/
|
||||
template <typename T>
|
||||
struct Keyframe : public KeyframeBase {
|
||||
Keyframe(size_t i, double t, T p);
|
||||
Keyframe(size_t i, double t, T d);
|
||||
|
||||
Keyframe(Keyframe const&) = default;
|
||||
Keyframe(Keyframe&&) = default;
|
||||
Keyframe& operator=(Keyframe&&) = default;
|
||||
Keyframe& operator=(Keyframe const&) = default;
|
||||
T data;
|
||||
};
|
||||
|
||||
@@ -56,7 +61,8 @@ class Timeline {
|
||||
public:
|
||||
virtual ~Timeline() = default;
|
||||
|
||||
void addKeyframe(double time, T data);
|
||||
void addKeyframe(double time, const T& data);
|
||||
void addKeyframe(double time, T&& data);
|
||||
void clearKeyframes();
|
||||
void removeKeyframe(size_t id);
|
||||
void removeKeyframesBefore(double timestamp, bool inclusive = false);
|
||||
@@ -66,6 +72,7 @@ public:
|
||||
size_t nKeyframes() const;
|
||||
const Keyframe<T>* firstKeyframeAfter(double timestamp, bool inclusive = false) const;
|
||||
const Keyframe<T>* lastKeyframeBefore(double timestamp, bool inclusive = false) const;
|
||||
|
||||
const std::deque<Keyframe<T>>& keyframes() const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -25,13 +25,25 @@
|
||||
namespace openspace {
|
||||
|
||||
template <typename T>
|
||||
Keyframe<T>::Keyframe(size_t i, double t, T p)
|
||||
Keyframe<T>::Keyframe(size_t i, double t, T d)
|
||||
: KeyframeBase{ i, t }
|
||||
, data(p)
|
||||
, data(std::move(d))
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
void Timeline<T>::addKeyframe(double timestamp, T data) {
|
||||
void Timeline<T>::addKeyframe(double timestamp, T&& data) {
|
||||
Keyframe<T> keyframe(++_nextKeyframeId, timestamp, std::move(data));
|
||||
const auto iter = std::upper_bound(
|
||||
_keyframes.cbegin(),
|
||||
_keyframes.cend(),
|
||||
keyframe,
|
||||
&compareKeyframeTimes
|
||||
);
|
||||
_keyframes.insert(iter, std::move(keyframe));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Timeline<T>::addKeyframe(double timestamp, const T& data) {
|
||||
Keyframe<T> keyframe(++_nextKeyframeId, timestamp, data);
|
||||
const auto iter = std::upper_bound(
|
||||
_keyframes.cbegin(),
|
||||
@@ -39,7 +51,7 @@ void Timeline<T>::addKeyframe(double timestamp, T data) {
|
||||
keyframe,
|
||||
&compareKeyframeTimes
|
||||
);
|
||||
_keyframes.insert(iter, keyframe);
|
||||
_keyframes.insert(iter, std::move(keyframe));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@@ -143,7 +155,7 @@ void Timeline<T>::removeKeyframe(size_t id) {
|
||||
std::remove_if(
|
||||
_keyframes.begin(),
|
||||
_keyframes.end(),
|
||||
[id] (Keyframe<T> keyframe) { return keyframe.id == id; }
|
||||
[id] (const Keyframe<T>& keyframe) { return keyframe.id == id; }
|
||||
),
|
||||
_keyframes.end()
|
||||
);
|
||||
@@ -209,7 +221,7 @@ const Keyframe<T>* Timeline<T>::lastKeyframeBefore(double timestamp, bool inclus
|
||||
return &(*it);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
const std::deque<Keyframe<T>>& Timeline<T>::keyframes() const {
|
||||
return _keyframes;
|
||||
}
|
||||
|
||||
@@ -54,8 +54,7 @@ set(HEADER_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceframebuffer.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceimagelocal.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceimageonline.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/translation/luatranslation.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/translation/statictranslation.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rotation/timelinerotation.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rotation/constantrotation.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rotation/fixedrotation.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rotation/luarotation.h
|
||||
@@ -65,6 +64,10 @@ set(HEADER_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/scale/timedependentscale.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/timeframe/timeframeinterval.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/timeframe/timeframeunion.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/translation/luatranslation.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/translation/statictranslation.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/translation/timelinetranslation.h
|
||||
|
||||
)
|
||||
source_group("Header Files" FILES ${HEADER_FILES})
|
||||
|
||||
@@ -98,8 +101,7 @@ set(SOURCE_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceframebuffer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceimagelocal.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceimageonline.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/translation/luatranslation.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/translation/statictranslation.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rotation/timelinerotation.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rotation/constantrotation.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rotation/fixedrotation.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rotation/luarotation.cpp
|
||||
@@ -109,6 +111,9 @@ set(SOURCE_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/scale/timedependentscale.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/timeframe/timeframeinterval.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/timeframe/timeframeunion.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/translation/luatranslation.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/translation/statictranslation.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/translation/timelinetranslation.cpp
|
||||
)
|
||||
source_group("Source Files" FILES ${SOURCE_FILES})
|
||||
|
||||
|
||||
@@ -55,9 +55,11 @@
|
||||
#include <modules/base/rotation/fixedrotation.h>
|
||||
#include <modules/base/rotation/luarotation.h>
|
||||
#include <modules/base/rotation/staticrotation.h>
|
||||
#include <modules/base/rotation/timelinerotation.h>
|
||||
#include <modules/base/scale/luascale.h>
|
||||
#include <modules/base/scale/staticscale.h>
|
||||
#include <modules/base/scale/timedependentscale.h>
|
||||
#include <modules/base/translation/timelinetranslation.h>
|
||||
#include <modules/base/translation/luatranslation.h>
|
||||
#include <modules/base/translation/statictranslation.h>
|
||||
#include <modules/base/timeframe/timeframeinterval.h>
|
||||
@@ -131,6 +133,7 @@ void BaseModule::internalInitialize(const ghoul::Dictionary&) {
|
||||
auto fTranslation = FactoryManager::ref().factory<Translation>();
|
||||
ghoul_assert(fTranslation, "Ephemeris factory was not created");
|
||||
|
||||
fTranslation->registerClass<TimelineTranslation>("TimelineTranslation");
|
||||
fTranslation->registerClass<LuaTranslation>("LuaTranslation");
|
||||
fTranslation->registerClass<StaticTranslation>("StaticTranslation");
|
||||
|
||||
@@ -141,6 +144,8 @@ void BaseModule::internalInitialize(const ghoul::Dictionary&) {
|
||||
fRotation->registerClass<FixedRotation>("FixedRotation");
|
||||
fRotation->registerClass<LuaRotation>("LuaRotation");
|
||||
fRotation->registerClass<StaticRotation>("StaticRotation");
|
||||
fRotation->registerClass<TimelineRotation>("TimelineRotation");
|
||||
|
||||
|
||||
auto fScale = FactoryManager::ref().factory<Scale>();
|
||||
ghoul_assert(fScale, "Scale factory was not created");
|
||||
@@ -198,6 +203,7 @@ std::vector<documentation::Documentation> BaseModule::documentations() const {
|
||||
FixedRotation::Documentation(),
|
||||
LuaRotation::Documentation(),
|
||||
StaticRotation::Documentation(),
|
||||
TimelineRotation::Documentation(),
|
||||
|
||||
LuaScale::Documentation(),
|
||||
StaticScale::Documentation(),
|
||||
@@ -205,6 +211,7 @@ std::vector<documentation::Documentation> BaseModule::documentations() const {
|
||||
|
||||
LuaTranslation::Documentation(),
|
||||
StaticTranslation::Documentation(),
|
||||
TimelineTranslation::Documentation(),
|
||||
|
||||
TimeFrameInterval::Documentation(),
|
||||
TimeFrameUnion::Documentation(),
|
||||
|
||||
118
modules/base/rotation/timelinerotation.cpp
Normal file
118
modules/base/rotation/timelinerotation.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2019 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/base/rotation/timelinerotation.h>
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <openspace/util/time.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyType = "Type";
|
||||
constexpr const char* KeyKeyframes = "Keyframes";
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation TimelineRotation::Documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"Timeline Rotation",
|
||||
"base_transform_rotation_keyframe",
|
||||
{
|
||||
{
|
||||
KeyType,
|
||||
new StringEqualVerifier("TimelineRotation"),
|
||||
Optional::No
|
||||
},
|
||||
{
|
||||
KeyKeyframes,
|
||||
new TableVerifier({
|
||||
{ "*", new TableVerifier(), Optional::No, "Any translation object" }
|
||||
}),
|
||||
Optional::No,
|
||||
"A table of keyframes, with keys formatted as YYYY-MM-DDTHH:MM:SS"
|
||||
"and values that are valid Rotation objects."
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TimelineRotation::TimelineRotation(const ghoul::Dictionary& dictionary) {
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
dictionary,
|
||||
"TimelineTranslation"
|
||||
);
|
||||
|
||||
const ghoul::Dictionary& keyframes =
|
||||
dictionary.value<ghoul::Dictionary>(KeyKeyframes);
|
||||
|
||||
std::vector<std::string> timeStrings = keyframes.keys();
|
||||
for (const std::string& timeString : timeStrings) {
|
||||
const double t = Time::convertTime(timeString);
|
||||
|
||||
std::unique_ptr<Rotation> rotation =
|
||||
Rotation::createFromDictionary(
|
||||
keyframes.value<ghoul::Dictionary>(timeString)
|
||||
);
|
||||
|
||||
if (rotation) {
|
||||
_timeline.addKeyframe(t, std::move(rotation));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glm::dmat3 TimelineRotation::matrix(const UpdateData& data) const {
|
||||
const double now = data.time.j2000Seconds();
|
||||
using KeyframePointer = const Keyframe<std::unique_ptr<Rotation>>*;
|
||||
|
||||
KeyframePointer prev = _timeline.lastKeyframeBefore(now, true);
|
||||
KeyframePointer next = _timeline.firstKeyframeAfter(now, true);
|
||||
|
||||
if (!prev && !next) {
|
||||
return glm::dmat3(0.0);
|
||||
}
|
||||
if (!prev) {
|
||||
prev = next;
|
||||
}
|
||||
if (!next) {
|
||||
next = prev;
|
||||
}
|
||||
const double prevTime = prev->timestamp;
|
||||
const double nextTime = next->timestamp;
|
||||
|
||||
double t = 0.0;
|
||||
if (nextTime - prevTime > 0.0) {
|
||||
t = (now - prevTime) / (nextTime - prevTime);
|
||||
}
|
||||
|
||||
const glm::dquat nextRot = glm::quat_cast(next->data->matrix(data));
|
||||
const glm::dquat prevRot = glm::quat_cast(prev->data->matrix(data));
|
||||
|
||||
return glm::dmat3(glm::slerp(prevRot, nextRot, t));
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
49
modules/base/rotation/timelinerotation.h
Normal file
49
modules/base/rotation/timelinerotation.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2019 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_BASE___TIMELINEROTATION___H__
|
||||
#define __OPENSPACE_MODULE_BASE___TIMELINEROTATION___H__
|
||||
|
||||
#include <openspace/scene/rotation.h>
|
||||
#include <openspace/util/timeline.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
struct UpdateData;
|
||||
|
||||
namespace documentation { struct Documentation; }
|
||||
|
||||
class TimelineRotation : public Rotation {
|
||||
public:
|
||||
TimelineRotation(const ghoul::Dictionary& dictionary);
|
||||
glm::dmat3 matrix(const UpdateData& data) const override;
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
private:
|
||||
Timeline<std::unique_ptr<Rotation>> _timeline;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_BASE___TIMELINEROTATION___H__
|
||||
114
modules/base/translation/timelinetranslation.cpp
Normal file
114
modules/base/translation/timelinetranslation.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2019 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/base/translation/timelinetranslation.h>
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <openspace/util/time.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyType = "Type";
|
||||
constexpr const char* KeyKeyframes = "Keyframes";
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation TimelineTranslation::Documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"Timeline Translation",
|
||||
"base_transform_translation_keyframe",
|
||||
{
|
||||
{
|
||||
KeyType,
|
||||
new StringEqualVerifier("TimelineTranslation"),
|
||||
Optional::No
|
||||
},
|
||||
{
|
||||
KeyKeyframes,
|
||||
new TableVerifier({
|
||||
{ "*", new TableVerifier(), Optional::No, "Any translation object" }
|
||||
}),
|
||||
Optional::No,
|
||||
"A table of keyframes, with keys formatted as YYYY-MM-DDTHH:MM:SS"
|
||||
"and values that are valid Translation objects."
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TimelineTranslation::TimelineTranslation(const ghoul::Dictionary& dictionary) {
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
dictionary,
|
||||
"TimelineTranslation"
|
||||
);
|
||||
|
||||
const ghoul::Dictionary& keyframes =
|
||||
dictionary.value<ghoul::Dictionary>(KeyKeyframes);
|
||||
|
||||
std::vector<std::string> timeStrings = keyframes.keys();
|
||||
for (const std::string& timeString : timeStrings) {
|
||||
const double t = Time::convertTime(timeString);
|
||||
|
||||
std::unique_ptr<Translation> translation =
|
||||
Translation::createFromDictionary(
|
||||
keyframes.value<ghoul::Dictionary>(timeString)
|
||||
);
|
||||
|
||||
if (translation) {
|
||||
_timeline.addKeyframe(t, std::move(translation));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glm::dvec3 TimelineTranslation::position(const UpdateData& data) const {
|
||||
const double now = data.time.j2000Seconds();
|
||||
using KeyframePointer = const Keyframe<std::unique_ptr<Translation>>*;
|
||||
|
||||
KeyframePointer prev = _timeline.lastKeyframeBefore(now, true);
|
||||
KeyframePointer next = _timeline.firstKeyframeAfter(now, true);
|
||||
|
||||
if (!prev && !next) {
|
||||
return glm::dvec3(0.0);
|
||||
}
|
||||
if (!prev) {
|
||||
prev = next;
|
||||
}
|
||||
if (!next) {
|
||||
next = prev;
|
||||
}
|
||||
const double prevTime = prev->timestamp;
|
||||
const double nextTime = next->timestamp;
|
||||
|
||||
double t = 0.0;
|
||||
if (nextTime - prevTime > 0.0) {
|
||||
t = (now - prevTime) / (nextTime - prevTime);
|
||||
}
|
||||
return t * next->data->position(data) + (1.0 - t) * prev->data->position(data);
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
50
modules/base/translation/timelinetranslation.h
Normal file
50
modules/base/translation/timelinetranslation.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2019 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_BASE___TIMELINETRANSLATION___H__
|
||||
#define __OPENSPACE_MODULE_BASE___TIMELINETRANSLATION___H__
|
||||
|
||||
#include <openspace/scene/translation.h>
|
||||
#include <openspace/util/timeline.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
struct UpdateData;
|
||||
|
||||
namespace documentation { struct Documentation; }
|
||||
|
||||
class TimelineTranslation : public Translation {
|
||||
public:
|
||||
TimelineTranslation(const ghoul::Dictionary& dictionary);
|
||||
|
||||
glm::dvec3 position(const UpdateData& data) const override;
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
private:
|
||||
Timeline<std::unique_ptr<Translation>> _timeline;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_BASE___TIMELINETRANSLATION___H__
|
||||
@@ -173,9 +173,16 @@ void DashboardItemGlobeLocation::render(glm::vec2& penPosition) {
|
||||
bool isEast = lon > 0.0;
|
||||
lon = std::abs(lon);
|
||||
|
||||
const double altitude = glm::length(
|
||||
double altitude = glm::length(
|
||||
cameraPositionModelSpace - posHandle.centerToReferenceSurface
|
||||
);
|
||||
|
||||
if (glm::length(cameraPositionModelSpace) <
|
||||
glm::length(posHandle.centerToReferenceSurface))
|
||||
{
|
||||
altitude = -altitude;
|
||||
}
|
||||
|
||||
std::pair<double, std::string> dist = simplifyDistance(altitude);
|
||||
|
||||
penPosition.y -= _font->height();
|
||||
|
||||
@@ -58,20 +58,21 @@ namespace {
|
||||
"globe. The default value is 0.0"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo FixedAltitudeInfo = {
|
||||
"FixedAltitude",
|
||||
"Fixed Altitude",
|
||||
"The altitude in meters of the location on the globe's surface. This value is "
|
||||
"used if the 'UseFixedAltitude' property is 'true'. The default value is 10000km."
|
||||
constexpr openspace::properties::Property::PropertyInfo AltitudeInfo = {
|
||||
"Altitude",
|
||||
"Altitude",
|
||||
"The altitude in meters. "
|
||||
"If the 'UseHeightmap' property is 'true', this is an offset from the actual "
|
||||
"surface of the globe. If not, this is an offset from the reference ellipsoid."
|
||||
"The default value is 0.0"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo UseFixedAltitudeInfo = {
|
||||
"UseFixedAltitude",
|
||||
"Use Fixed Altitude",
|
||||
"If this value is 'true', the altitude specified in 'FixedAltitude' is used for "
|
||||
"this translation. If it is 'false', the altitude will be computed based on the "
|
||||
"height information that is available about the globe to which this translation "
|
||||
"is attached. The default value is 'true'."
|
||||
constexpr openspace::properties::Property::PropertyInfo UseHeightmapInfo = {
|
||||
"UseHeightmap",
|
||||
"Use Heightmap",
|
||||
"If this value is 'true', the altitude specified in 'Altitude' will be treated "
|
||||
"as an offset from the heightmap. Otherwise, it will be an offset from the "
|
||||
"globe's reference ellipsoid. The default value is 'false'."
|
||||
};
|
||||
} // namespace
|
||||
|
||||
@@ -81,8 +82,8 @@ documentation::Documentation GlobeTranslation::Documentation() {
|
||||
using namespace openspace::documentation;
|
||||
|
||||
return {
|
||||
"Spice Translation",
|
||||
"space_translation_spicetranslation",
|
||||
"Globe Translation",
|
||||
"space_translation_globetranslation",
|
||||
{
|
||||
{
|
||||
"Type",
|
||||
@@ -110,16 +111,16 @@ documentation::Documentation GlobeTranslation::Documentation() {
|
||||
LatitudeInfo.description,
|
||||
},
|
||||
{
|
||||
FixedAltitudeInfo.identifier,
|
||||
AltitudeInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
FixedAltitudeInfo.description
|
||||
AltitudeInfo.description
|
||||
},
|
||||
{
|
||||
UseFixedAltitudeInfo.identifier,
|
||||
UseHeightmapInfo.identifier,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
UseFixedAltitudeInfo.description
|
||||
UseHeightmapInfo.description
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -129,8 +130,8 @@ GlobeTranslation::GlobeTranslation(const ghoul::Dictionary& dictionary)
|
||||
: _globe(GlobeInfo)
|
||||
, _longitude(LongitudeInfo, 0.0, -180.0, 180.0)
|
||||
, _latitude(LatitudeInfo, 0.0, -90.0, 90.0)
|
||||
, _fixedAltitude(FixedAltitudeInfo, 1e8, 0.0, 1e12)
|
||||
, _useFixedAltitude(UseFixedAltitudeInfo, false)
|
||||
, _altitude(AltitudeInfo, 0.0, 0.0, 1e12)
|
||||
, _useHeightmap(UseHeightmapInfo, false)
|
||||
{
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
@@ -145,11 +146,11 @@ GlobeTranslation::GlobeTranslation(const ghoul::Dictionary& dictionary)
|
||||
if (dictionary.hasKey(LatitudeInfo.identifier)) {
|
||||
_latitude = dictionary.value<double>(LatitudeInfo.identifier);
|
||||
}
|
||||
if (dictionary.hasKey(FixedAltitudeInfo.identifier)) {
|
||||
_fixedAltitude = dictionary.value<double>(FixedAltitudeInfo.identifier);
|
||||
if (dictionary.hasKey(AltitudeInfo.identifier)) {
|
||||
_altitude = dictionary.value<double>(AltitudeInfo.identifier);
|
||||
}
|
||||
if (dictionary.hasKey(UseFixedAltitudeInfo.identifier)) {
|
||||
_useFixedAltitude = dictionary.value<bool>(UseFixedAltitudeInfo.identifier);
|
||||
if (dictionary.hasKey(UseHeightmapInfo.identifier)) {
|
||||
_useHeightmap = dictionary.value<bool>(UseHeightmapInfo.identifier);
|
||||
}
|
||||
|
||||
_globe.onChange([this]() {
|
||||
@@ -159,13 +160,13 @@ GlobeTranslation::GlobeTranslation(const ghoul::Dictionary& dictionary)
|
||||
|
||||
_longitude.onChange([this]() { _positionIsDirty = true; });
|
||||
_latitude.onChange([this]() { _positionIsDirty = true; });
|
||||
_fixedAltitude.onChange([this]() { _positionIsDirty = true; });
|
||||
_useFixedAltitude.onChange([this]() { _positionIsDirty = true; });
|
||||
_altitude.onChange([this]() { _positionIsDirty = true; });
|
||||
_useHeightmap.onChange([this]() { _positionIsDirty = true; });
|
||||
|
||||
addProperty(_longitude);
|
||||
addProperty(_latitude);
|
||||
addProperty(_fixedAltitude);
|
||||
addProperty(_useFixedAltitude);
|
||||
addProperty(_altitude);
|
||||
addProperty(_useHeightmap);
|
||||
}
|
||||
|
||||
void GlobeTranslation::fillAttachedNode() {
|
||||
@@ -195,8 +196,8 @@ glm::dvec3 GlobeTranslation::position(const UpdateData&) const {
|
||||
_positionIsDirty = true;
|
||||
}
|
||||
|
||||
if (!_useFixedAltitude) {
|
||||
// If we don't use the fixed altitude, we have to compute the height every frame
|
||||
if (_useHeightmap) {
|
||||
// If we use the heightmap, we have to compute the height every frame
|
||||
_positionIsDirty = true;
|
||||
}
|
||||
|
||||
@@ -204,33 +205,35 @@ glm::dvec3 GlobeTranslation::position(const UpdateData&) const {
|
||||
return _position;
|
||||
}
|
||||
|
||||
|
||||
GlobeBrowsingModule& mod = *(global::moduleEngine.module<GlobeBrowsingModule>());
|
||||
|
||||
glm::vec3 pos = mod.cartesianCoordinatesFromGeo(
|
||||
*_attachedNode,
|
||||
_latitude,
|
||||
_longitude,
|
||||
_fixedAltitude
|
||||
);
|
||||
|
||||
if (_useFixedAltitude) {
|
||||
_position = glm::dvec3(pos);
|
||||
_positionIsDirty = true;
|
||||
|
||||
return _position;
|
||||
}
|
||||
else {
|
||||
SurfacePositionHandle h = _attachedNode->calculateSurfacePositionHandle(pos);
|
||||
|
||||
pos = mod.cartesianCoordinatesFromGeo(
|
||||
if (_useHeightmap) {
|
||||
glm::vec3 groundPos = mod.cartesianCoordinatesFromGeo(
|
||||
*_attachedNode,
|
||||
_latitude,
|
||||
_longitude,
|
||||
h.heightToSurface
|
||||
0.0
|
||||
);
|
||||
|
||||
_position = glm::dvec3(pos);
|
||||
SurfacePositionHandle h =
|
||||
_attachedNode->calculateSurfacePositionHandle(groundPos);
|
||||
|
||||
_position = mod.cartesianCoordinatesFromGeo(
|
||||
*_attachedNode,
|
||||
_latitude,
|
||||
_longitude,
|
||||
h.heightToSurface + _altitude
|
||||
);
|
||||
return _position;
|
||||
}
|
||||
else {
|
||||
_position = mod.cartesianCoordinatesFromGeo(
|
||||
*_attachedNode,
|
||||
_latitude,
|
||||
_longitude,
|
||||
_altitude
|
||||
);
|
||||
_positionIsDirty = false;
|
||||
return _position;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,8 +49,8 @@ private:
|
||||
properties::StringProperty _globe;
|
||||
properties::DoubleProperty _longitude;
|
||||
properties::DoubleProperty _latitude;
|
||||
properties::DoubleProperty _fixedAltitude;
|
||||
properties::BoolProperty _useFixedAltitude;
|
||||
properties::DoubleProperty _altitude;
|
||||
properties::BoolProperty _useHeightmap;
|
||||
|
||||
RenderableGlobe* _attachedNode = nullptr;
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ void HorizonsTranslation::readHorizonsTextFile(const std::string& horizonsTextFi
|
||||
);
|
||||
|
||||
// Add position to stored timeline.
|
||||
_timeline.addKeyframe(timeInJ2000, gPos);
|
||||
_timeline.addKeyframe(timeInJ2000, std::move(gPos));
|
||||
|
||||
std::getline(fileStream, line);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user