mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-07 03:49:43 -05:00
Added possibility to go to now, without program freezing, and improved lifecycle with already downloaded field lines
This commit is contained in:
+38
-15
@@ -6,11 +6,11 @@ local renderableHelper = asset.require('util/renderable_helper')
|
||||
-- Specifying which other assets should be loaded in this scene
|
||||
asset.require('spice/base')
|
||||
assetHelper.requestAll(asset, 'scene/solarsystem/sun')
|
||||
-- asset.require('scene/solarsystem/planets')
|
||||
asset.require('scene/solarsystem/planets')
|
||||
-- asset.require('scene/solarsystem/planets/mars/moons/phobos')
|
||||
-- asset.require('scene/solarsystem/planets/mars/moons/deimos')
|
||||
-- asset.require('scene/solarsystem/dwarf_planets/pluto/system')
|
||||
-- assetHelper.requestAll(asset, 'scene/digitaluniverse')
|
||||
assetHelper.requestAll(asset, 'scene/digitaluniverse')
|
||||
|
||||
-- Load default key bindings applicable to most scenes
|
||||
asset.require('util/default_keybindings')
|
||||
@@ -18,7 +18,7 @@ asset.require('util/default_dashboard')
|
||||
-- asset.require('util/default_joystick')
|
||||
|
||||
-- DEBUG
|
||||
asset.require('./testwsa/debugcoordaxes');
|
||||
-- asset.require('./testwsa/debugcoordaxes');
|
||||
|
||||
asset.require('util/webgui')
|
||||
|
||||
@@ -38,14 +38,14 @@ asset.require('./testwsa/pfss_io')
|
||||
|
||||
-- Parker Solar Probe asset package
|
||||
asset.require('scene/solarsystem/missions/parkersolarprobe/parker_solar_probe_trail')
|
||||
--asset.require('./testwsa/psp_pfss_io')
|
||||
--asset.require('./testwsa/psp_pfss_oi')
|
||||
--asset.require('./testwsa/psp_scs_oi')
|
||||
-- asset.require('./testwsa/psp_pfss_io')
|
||||
-- asset.require('./testwsa/psp_pfss_oi')
|
||||
-- asset.require('./testwsa/psp_scs_oi')
|
||||
-- asset.require('./testwsa/psp_sub_satellite')
|
||||
|
||||
|
||||
-- Sub-Earth track
|
||||
asset.require('./testwsa/sub_earth')
|
||||
-- asset.require('./testwsa/sub_earth')
|
||||
|
||||
local Keybindings = {
|
||||
{
|
||||
@@ -104,15 +104,15 @@ local Keybindings = {
|
||||
},
|
||||
{
|
||||
Key = "x",
|
||||
Command = "openspace.time.setTime('2021 APR 28 00:00:00.000')",
|
||||
Documentation = "Jump to 1 September 2017",
|
||||
Name = "Jump to 2017",
|
||||
Command = "openspace.time.setTime('2018 NOV 1 00:00:00.000')",
|
||||
Documentation = "Jump to 1 November 2018",
|
||||
Name = "Jump to 1 November 2018",
|
||||
GuiPath = "/Parker Solar Probe",
|
||||
Local = false
|
||||
},
|
||||
{
|
||||
Key = "b",
|
||||
Command = renderableHelper.toggle('Scene.WSA_Fieldlines_Sun_Earth_Connection'),
|
||||
Command = renderableHelper.toggle('Scene.WSA_Fieldlines_Sub_Earth_Track'),
|
||||
Documentation = "Toggle ballerina skirt",
|
||||
Name = "Toggle Sub Earth connection",
|
||||
GuiPath = "/Parker Solar Probe",
|
||||
@@ -144,13 +144,36 @@ local Keybindings = {
|
||||
},
|
||||
{
|
||||
Key = "l",
|
||||
Command = "openspace.setPropertyValue('Scene.WSA_Fieldlines_SCS_OI.Renderable.Masking.maskingQuantity', 1);" ..
|
||||
"openspace.setPropertyValue('Scene.WSA_Fieldlines_SCS_OI.Renderable.maskingEnabled', not openspace.getPropertyValue('Scene.WSA_Fieldlines_SCS_OI.Renderable.maskingEnabled'))",
|
||||
Documentation = "Toggle SCS out to in model",
|
||||
Name = "Toggle SCS out to in model",
|
||||
Command = "openspace.setPropertyValue('Scene.WSA_Fieldlines_SCS_OI.Renderable.Masking.maskingQuantity', 1)" ..
|
||||
"openspace.setPropertyValue('Scene.WSA_Fieldlines_SCS_OI.Renderable.maskingEnabled', not openspace.getPropertyValue('Scene.WSA_Fieldlines_SCS_OI.Renderable.maskingEnabled'))" ..
|
||||
"openspace.setPropertyValue('Scene.WSA_Fieldlines_PFSS_OI.Renderable.Masking.maskingQuantity', 1)" ..
|
||||
"openspace.setPropertyValue('Scene.WSA_Fieldlines_PFSS_OI.Renderable.maskingEnabled', not openspace.getPropertyValue('Scene.WSA_Fieldlines_PFSS_OI.Renderable.maskingEnabled'));" ..
|
||||
"openspace.setPropertyValue('Scene.PSP_WSA_Fieldlines_SCS_OI.Renderable.Masking.maskingQuantity', 1)" ..
|
||||
"openspace.setPropertyValue('Scene.PSP_WSA_Fieldlines_SCS_OI.Renderable.maskingEnabled', not openspace.getPropertyValue('Scene.PSP_WSA_Fieldlines_SCS_OI.Renderable.maskingEnabled'))" ..
|
||||
"openspace.setPropertyValue('Scene.PSP_WSA_Fieldlines_PFSS_OI.Renderable.Masking.maskingQuantity', 1)" ..
|
||||
"openspace.setPropertyValue('Scene.PSP_WSA_Fieldlines_PFSS_OI.Renderable.maskingEnabled', not openspace.getPropertyValue('Scene.PSP_WSA_Fieldlines_PFSS_OI.Renderable.maskingEnabled'));",
|
||||
Documentation = "Toggle current sheet in all out to in models",
|
||||
Name = "Toggle current sheet in all out to in models",
|
||||
GuiPath = "/Parker Solar Probe",
|
||||
Local = false
|
||||
},
|
||||
{
|
||||
Key = "h",
|
||||
Command = "openspace.setPropertyValue('Scene.WSA_Fieldlines_Sub_Earth_Track.Renderable.Masking.maskingQuantity', 1)" ..
|
||||
"openspace.setPropertyValue('Scene.WSA_Fieldlines_Sub_Earth_Track.Renderable.maskingEnabled', true);",
|
||||
Documentation = "Show only one layer of sub earth track",
|
||||
Name = "Toggle sub satellite layers",
|
||||
GuiPath = "/Parker Solar Probe",
|
||||
Local = false
|
||||
},
|
||||
{
|
||||
Key = "Shift+g",
|
||||
Command = "openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'Earth');" ..
|
||||
"openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil)" ..
|
||||
"openspace.globebrowsing.goToGeo(38.995412,-76.857665)",
|
||||
Documentation = "Sets the focus of the camera on 'Goddard'",
|
||||
Local = false
|
||||
},
|
||||
}
|
||||
|
||||
asset.onInitialize(function ()
|
||||
|
||||
@@ -7,7 +7,6 @@ local opennessColorTable = transferFunctions .. "/openness_spec.txt"
|
||||
|
||||
local sunRadius = 695508000
|
||||
|
||||
-- Fieldlies from json
|
||||
local fieldlines = {
|
||||
Identifier = "WSA_Fieldlines_PFSS_IO",
|
||||
Parent = transforms.TransformGONG.Identifier, -- Use this for regular GONG (Main fieldline endpoints)
|
||||
|
||||
@@ -8,7 +8,6 @@ local currentSheetColorTable = transferFunctions .. "/currentsheet_spec.txt"
|
||||
|
||||
local sunRadius = 695508000
|
||||
|
||||
-- Fieldlies from json
|
||||
local fieldlines = {
|
||||
Identifier = "WSA_Fieldlines_SCS_OI",
|
||||
Parent = transforms.TransformGONG.Identifier, -- Use this for regular GONG (Main fieldline endpoints)
|
||||
|
||||
@@ -330,9 +330,9 @@ void RenderableSphere::initializeGL() {
|
||||
|
||||
loadTexture();
|
||||
|
||||
if(_texturePath.fullyQualifiedIdentifier() == "Scene.Sun.Renderable.Texture"){
|
||||
/*if(_texturePath.fullyQualifiedIdentifier() == "Scene.Sun.Renderable.Texture"){
|
||||
_sunTexMgr.loadWSATexture(_texture);
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
||||
void RenderableSphere::deinitializeGL() {
|
||||
|
||||
@@ -625,7 +625,7 @@ namespace openspace {
|
||||
extractTriggerTimesFromFileNames();
|
||||
FieldlinesState newState;
|
||||
if (!newState.loadStateFromOsfls(_sourceFiles[0])) {
|
||||
LERROR("The provided .osfls files seem to be corrupt!");
|
||||
LERROR("The provided .osfls files seem to be corrupt: " + _sourceFiles[0]);
|
||||
return false;
|
||||
}
|
||||
_states.push_back(newState);
|
||||
|
||||
@@ -156,21 +156,19 @@ namespace openspace{
|
||||
|
||||
// First it checks the time against the "bigger window" aka the long list of
|
||||
// timesteps we know are available online. If it's outside that we're gonna need a new one
|
||||
if (_webFieldlinesWindow.timeIsInTriggerTimesWebList(openspaceTime) && !_webFieldlinesWindow.expectedWindowIsOutOfBounds(openspaceTime)) {
|
||||
if (_webFieldlinesWindow.timeIsInTriggerTimesWebList(openspaceTime) && !_webFieldlinesWindow.expectedWindowIsOutOfBounds(openspaceTime) || _webFieldlinesWindow.checkWorkerEdgeMode()){
|
||||
|
||||
// Check if in window
|
||||
if (_webFieldlinesWindow.timeIsInWindow(openspaceTime)) {
|
||||
if (_webFieldlinesWindow.edgeWindowReady() || _webFieldlinesWindow.timeIsInWindow(openspaceTime)) {
|
||||
|
||||
// Check if in the edge of the window, so we can start downloading a new one
|
||||
if (_webFieldlinesWindow.timeIsInWindowMargin(openspaceTime, deltaTime)) {
|
||||
if (!_webFieldlinesWindow.edgeWindowReady() && _webFieldlinesWindow.timeIsInWindowMargin(openspaceTime, deltaTime)) {
|
||||
// get new window
|
||||
_webFieldlinesWindow.newWindow(openspaceTime);
|
||||
hasUpdated = false;
|
||||
}
|
||||
else {
|
||||
|
||||
// If it's in the middle of the window, we can just sit back and relax
|
||||
// And let the worker work
|
||||
// If it's in the middle of the window, we can just sit back and relax and let the worker work
|
||||
_webFieldlinesWindow.executeDownloadWorker();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,6 @@ namespace openspace{
|
||||
if (direction > 0){ // If time is moving forward
|
||||
if(time >= _window.triggerTimes[_window.nTriggerTimes - threshold].first){
|
||||
if(time > windowEnd()){
|
||||
LERROR("Time is outside of window in margin-check-function. This shouldn't happen.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -90,7 +89,6 @@ namespace openspace{
|
||||
else{ // If time is moving backwards
|
||||
if(time <= _window.triggerTimes[threshold].first){
|
||||
if(time < windowStart()){
|
||||
LERROR("Time is outside of window in margin-check-function. This shouldn't happen.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -106,6 +104,7 @@ namespace openspace{
|
||||
void WebFieldlinesWindow::executeDownloadWorker(){
|
||||
_worker.downloadWindow(_window.triggerTimes);
|
||||
_worker.updateRFSSourceFiles(*rfs_sourceFiles);
|
||||
_edgeWindowReady = false;
|
||||
}
|
||||
|
||||
void WebFieldlinesWindow::newWindow(double time){
|
||||
@@ -115,23 +114,27 @@ namespace openspace{
|
||||
});
|
||||
|
||||
const int index = static_cast<int>(std::distance(it, _triggerTimesWeb.rend())) - 1;
|
||||
|
||||
_window.triggerTimes.clear();
|
||||
_window.nTriggerTimes = 0;
|
||||
|
||||
// This should be safe, because in the manager, it is checked wether the current position is within
|
||||
// the boundaries with respect to back & forward width
|
||||
for(int i = index - _window.backWidth; i <= index + _window.forwardWidth; i++){
|
||||
if(i < 0) i = 0;
|
||||
for(int i = std::max(index - _window.backWidth,0); i <= std::min(index + _window.forwardWidth, static_cast<int>(_triggerTimesWeb.size() -1)); i++){
|
||||
_window.triggerTimes.push_back(std::make_pair(_triggerTimesWeb[i].first, _triggerTimesWeb[i].second));
|
||||
_window.nTriggerTimes++;
|
||||
}
|
||||
|
||||
if (_worker.edgeMode())
|
||||
_edgeWindowReady = true;
|
||||
|
||||
_worker.newWindowToDownload();
|
||||
}
|
||||
|
||||
bool WebFieldlinesWindow::timeIsInTriggerTimesWebList(double time){
|
||||
// There are no files to compare with, just going to be false.
|
||||
if(_nAvailableWeb == 0) return false;
|
||||
|
||||
// Most cases, we are currently in the middle of a bunch of datasets, if we are not, lets get some new ones.
|
||||
if(time >= (_triggerTimesWeb.front().first) && time <= (_triggerTimesWeb.back().first))
|
||||
return true;
|
||||
else
|
||||
@@ -139,7 +142,6 @@ namespace openspace{
|
||||
}
|
||||
|
||||
void WebFieldlinesWindow::getNewTriggerTimesWebList(double time){
|
||||
|
||||
_worker.getRangeOfAvailableTriggerTimes(time, time, _triggerTimesWeb);
|
||||
_nAvailableWeb = static_cast<int>(_triggerTimesWeb.size());
|
||||
}
|
||||
@@ -165,6 +167,14 @@ namespace openspace{
|
||||
void WebFieldlinesWindow::rfsHasUpdated() {
|
||||
_worker.flagUpdated();
|
||||
}
|
||||
|
||||
bool WebFieldlinesWindow::checkWorkerEdgeMode(){
|
||||
return _worker.edgeMode();
|
||||
}
|
||||
|
||||
bool WebFieldlinesWindow::edgeWindowReady(){
|
||||
return _edgeWindowReady;
|
||||
}
|
||||
|
||||
// -------------------------- PRIVATE FUNCTIONS -----------------------------------//
|
||||
// Returns first trigger of window
|
||||
|
||||
@@ -106,6 +106,13 @@ public:
|
||||
// Calling the functioh in worker that renderable fieldlinessequence has updated.
|
||||
void rfsHasUpdated();
|
||||
|
||||
// Returns true if big window is fetching files from the end or beginning of a data segment
|
||||
// Returns false if not.
|
||||
bool checkWorkerEdgeMode();
|
||||
|
||||
// Returns true if edge-window is ready
|
||||
bool edgeWindowReady();
|
||||
|
||||
private:
|
||||
|
||||
// PRIVATE MEMBER VARIABLES
|
||||
@@ -115,6 +122,7 @@ private:
|
||||
|
||||
// The worker that handles downloads
|
||||
WebFieldlinesWorker _worker;
|
||||
bool _edgeWindowReady = false;
|
||||
|
||||
// This is a long list of everything available online,
|
||||
// they are tuples of 3; double is timetrigger, string is donwload key, int is index to where it is on disk
|
||||
|
||||
@@ -64,12 +64,8 @@ namespace openspace{
|
||||
// PUBLIC FUNCTIONS
|
||||
void WebFieldlinesWorker::getRangeOfAvailableTriggerTimes(double startTime, double endTime, std::vector<std::pair<double, std::string>> &_triggerTimesWeb){
|
||||
|
||||
if (global::timeManager.time().j2000Seconds() < acceptableToStartRequestingAgain.first || global::timeManager.time().j2000Seconds() > acceptableToStartRequestingAgain.second) {
|
||||
_noEmptyResponses = true;
|
||||
}
|
||||
|
||||
// We don't want to keep sending request, if we just get empty responses.
|
||||
if (_noEmptyResponses) {
|
||||
if (!_noMoreRequests) {
|
||||
auto time = global::timeManager.time().ISO8601();
|
||||
Time maxTime;
|
||||
Time minTime;
|
||||
@@ -97,14 +93,14 @@ namespace openspace{
|
||||
});
|
||||
|
||||
auto res = json::parse(stringResult);
|
||||
auto temp = std::move(_triggerTimesWeb);
|
||||
_triggerTimesWeb.clear(); // Clear old big window
|
||||
|
||||
for (auto& elem : res[files]) {
|
||||
timeList.push_back(elem["timestamp"]);
|
||||
urlList.push_back(elem["url"]);
|
||||
}
|
||||
|
||||
_triggerTimesWeb.clear(); // Clear old big window
|
||||
|
||||
// Just want to make sure there is no error in the parsing, so taking the smallest dimension, but should be the same
|
||||
for (int i = 0; i < std::min(timeList.size(), urlList.size()); i++) {
|
||||
_triggerTimesWeb.push_back(std::make_pair(triggerTimeString2Double(timeList[i]), urlList[i]));
|
||||
@@ -112,11 +108,12 @@ namespace openspace{
|
||||
|
||||
std::sort(_triggerTimesWeb.begin(), _triggerTimesWeb.end()); // If by any chance it would not sort in properly
|
||||
|
||||
if (_triggerTimesWeb.size() == 0) // We got an empty response
|
||||
if (_triggerTimesWeb.size() == 0 || std::equal(temp.begin(),temp.end(),_triggerTimesWeb.begin(), _triggerTimesWeb.end())) // We got an empty response or the same response twice, stahp it
|
||||
_strikes++;
|
||||
|
||||
if (_strikes % 2 == 0){ // We have got 2 strikes, no more requests for you, Mr.Sir.
|
||||
_noEmptyResponses = false;
|
||||
_bigWindowHasData = (_triggerTimesWeb.size() > 0);
|
||||
_noMoreRequests = true;
|
||||
acceptableToStartRequestingAgain = std::make_pair(minTime.j2000Seconds(), maxTime.j2000Seconds());
|
||||
}
|
||||
}
|
||||
@@ -134,22 +131,9 @@ namespace openspace{
|
||||
bool oneUpdate = false;
|
||||
bool fastDownload = global::timeManager.deltaTime() > 1800.0;
|
||||
|
||||
// May be interesting to keep something like this, if it will be possible to use a list of
|
||||
// AsyncHttpFileDownloads
|
||||
|
||||
/*if (auto index = std::find_if(_downloadList.begin(), _downloadList.end(), [](auto element) {
|
||||
return element.first->hasSucceeded();
|
||||
}); index != _downloadList.end()) {
|
||||
// There is a successful download
|
||||
index->first->wait();
|
||||
addToDownloadedList(index->second);
|
||||
_downloadList.erase(index);
|
||||
}
|
||||
else { */
|
||||
|
||||
if (fastDownload) startingPoint = triggerTimes.size() - 1;
|
||||
|
||||
|
||||
// Is there a download thread to be joined and added to the list?
|
||||
if (_downloading && _downloading->hasSucceeded() && _newWindow) {
|
||||
_downloading->wait();
|
||||
addToDownloadedList(_latestDownload);
|
||||
@@ -172,7 +156,6 @@ namespace openspace{
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Backwards
|
||||
if (!downloaded) {
|
||||
std::for_each(triggerTimes.rbegin(), triggerTimes.rend(), [this, &downloaded](auto it) {
|
||||
@@ -185,7 +168,7 @@ namespace openspace{
|
||||
}
|
||||
}
|
||||
|
||||
if ((!downloaded && !_doneUpdating && _newWindow && _readyToDownload) || oneUpdate) {
|
||||
if ((!downloaded && !_doneUpdating && _newWindow && _readyToDownload && _downloadedSomething) || oneUpdate && _downloadedSomething) {
|
||||
// If reach this point, we now know that we have downloaded all the sets
|
||||
_readyToUpdateSourceFiles = true;
|
||||
if(!oneUpdate)
|
||||
@@ -240,10 +223,19 @@ namespace openspace{
|
||||
|
||||
void WebFieldlinesWorker::newWindowToDownload(){
|
||||
_newWindow = true;
|
||||
_downloadedSomething = false;
|
||||
}
|
||||
|
||||
bool WebFieldlinesWorker::edgeMode(){
|
||||
if (global::timeManager.time().j2000Seconds() < acceptableToStartRequestingAgain.first || global::timeManager.time().j2000Seconds() > acceptableToStartRequestingAgain.second) {
|
||||
_noMoreRequests = false;
|
||||
_bigWindowHasData = false;
|
||||
}
|
||||
return _noMoreRequests && _bigWindowHasData;
|
||||
}
|
||||
|
||||
std::string WebFieldlinesWorker::downloadOsfls(std::pair<double,std::string> downloadKey){
|
||||
|
||||
_downloadedSomething = true;
|
||||
_latestDownload = downloadKey;
|
||||
// YYYY-MM-DDTHH-MM-SS.sss.osfls - Might change
|
||||
const int fileNameLength = 29;
|
||||
|
||||
@@ -64,12 +64,16 @@ public:
|
||||
// Notifies the worker that a new window is ready
|
||||
void newWindowToDownload();
|
||||
|
||||
// If the current window is on the edge of a datasets, but if there are some file in that window, it is still desired to download it.
|
||||
bool edgeMode();
|
||||
|
||||
private:
|
||||
|
||||
// This list is the keep all the started downloads alive between frames, the second argument is a pair, used for identifying which download it is
|
||||
std::vector<AsyncHttpFileDownload> _downloadList;
|
||||
std::vector<std::pair<double,std::string>> _downloadListIdentifier;
|
||||
|
||||
// Asynchttpdownloader worker.
|
||||
std::unique_ptr<AsyncHttpFileDownload> _downloading;
|
||||
|
||||
// Might need this l8r
|
||||
@@ -91,10 +95,10 @@ private:
|
||||
bool _readyToUpdateSourceFiles = false;
|
||||
bool _doneUpdating = false;
|
||||
bool _newWindow = false;
|
||||
|
||||
|
||||
bool _readyToDownload = true;
|
||||
bool _noEmptyResponses = true;
|
||||
bool _noMoreRequests = false;
|
||||
bool _bigWindowHasData = false;
|
||||
bool _downloadedSomething = false;
|
||||
unsigned int _strikes = 0;
|
||||
std::pair<double, double> acceptableToStartRequestingAgain = std::make_pair(0.0, 0.0);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user