Merge branch 'master' into feature/jwst-trail-update

This commit is contained in:
Malin E
2022-08-31 14:30:58 +02:00
80 changed files with 1130 additions and 924 deletions
+1 -1
View File
@@ -9,7 +9,7 @@
url = https://github.com/OpenSpace/Spice.git
[submodule "modules/touch/ext/libTUIO11"]
path = modules/touch/ext/libTUIO11
url = https://github.com/mkalten/TUIO11_CPP
url = https://github.com/OpenSpace/TUIO11_CPP.git
[submodule "apps/OpenSpace-MinVR/ext/minvr"]
path = apps/OpenSpace-MinVR/ext/minvr
url = https://github.com/OpenSpace/minvr
+1 -1
View File
@@ -38,7 +38,7 @@ This repository contains the source code and example profiles for OpenSpace, but
Requirements for compiling are:
- CMake version 3.10 or above
- C++ compiler supporting C++17 (MSVC 16.10, GCC9, Clang10)
- C++ compiler supporting C++20 (MSVC 19.31, GCC11, Clang14, AppleClang 13.1.6)
- [Boost](http://www.boost.org/)
- [Qt](http://www.qt.io/download)
+18 -5
View File
@@ -127,11 +127,24 @@ target_link_libraries(
Qt${QT_VERSION_MAJOR}::Network
)
if (MSVC)
set(MSVC_WARNINGS
"/wd4619" # #pragma warning: there is no warning number (raised by Qt headers)
"/wd4946" # reinterpret_cast used between related classes:
target_precompile_headers(openspace-ui-launcher PRIVATE
<openspace/scene/profile.h>
<ghoul/glm.h>
<QAbstractItemDelegate>
<QAbstractItemModel>
<QDialog>
<QLineEdit>
<QObject>
<QStyleOption>
<QTextCursor>
<QWidget>
<filesystem>
)
target_compile_options(openspace-ui-launcher INTERFACE ${MSVC_WARNINGS})
if (MSVC)
set(MSVC_WARNINGS
"/wd4619" # #pragma warning: there is no warning number (raised by Qt headers)
"/wd4946" # reinterpret_cast used between related classes:
)
target_compile_options(openspace-ui-launcher INTERFACE ${MSVC_WARNINGS})
endif ()
+7 -21
View File
@@ -28,21 +28,15 @@
#include <openspace/engine/openspaceengine.h>
#include <openspace/engine/windowdelegate.h>
#include <openspace/interaction/joystickinputstate.h>
#include <openspace/scripting/scriptengine.h>
#include <openspace/util/keys.h>
#include <openspace/openspace.h>
#include <ghoul/ghoul.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/fmt.h>
#include <ghoul/glm.h>
#include <ghoul/cmdparser/commandlineparser.h>
#include <ghoul/cmdparser/singlecommand.h>
#include <ghoul/filesystem/file.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/logging/consolelog.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/logging/visualstudiooutputlog.h>
#include <ghoul/lua/ghoul_lua.h>
#include <ghoul/misc/assert.h>
#include <ghoul/misc/boolean.h>
#include <ghoul/opengl/ghoul_gl.h>
#include <ghoul/misc/stacktrace.h>
#ifdef WIN32
#define GLFW_EXPOSE_NATIVE_WIN32
#endif
@@ -54,25 +48,17 @@
#include <sgct/log.h>
#include <sgct/projection/fisheye.h>
#include <sgct/projection/nonlinearprojection.h>
#include <sgct/screencapture.h>
#include <sgct/settings.h>
#include <sgct/user.h>
#include <sgct/viewport.h>
#include <sgct/window.h>
#include <stb_image.h>
#include <Tracy.hpp>
#include <chrono>
#include <ctime>
#include <filesystem>
#include <memory>
#include <iostream>
#include <string_view>
#ifdef WIN32
#include <openspace/openspace.h>
#include <ghoul/misc/stacktrace.h>
#include <ghoul/fmt.h>
#include <Windows.h>
#include <dbghelp.h>
#include <shellapi.h>
#include <shlobj.h>
#endif // WIN32
#ifdef OPENVR_SUPPORT
+169 -24
View File
@@ -1,30 +1,175 @@
local orbit_right = {
Identifier = "ipac.orbit_right",
Name = "Orbit right",
Command = [[ openspace.navigation.addGlobalRotation(-5.0, 0.0) ]],
Documentation = "Orbits the camera to the right around the current focus",
GuiPath = "/Ipac",
IsLocal = false
}
asset.export("IpacOrbitRight", orbit_right)
local orbit_left = {
Identifier = "ipac.orbit_left",
Name = "Orbit left",
Command = [[ openspace.navigation.addGlobalRotation(5.0, 0.0) ]],
Documentation = "Orbits the camera to the left around the current focus",
GuiPath = "/Ipac",
IsLocal = false
}
asset.export("IpacOrbitLeft", orbit_left)
local orbit_up = {
Identifier = "ipac.orbit_up",
Name = "Orbit up",
Command = [[ openspace.navigation.addGlobalRotation(0.0, 5.0) ]],
Documentation = "Orbits the camera up around the current focus",
GuiPath = "/Ipac",
IsLocal = false
}
asset.export("IpacOrbitUp", orbit_up)
local orbit_down = {
Identifier = "ipac.orbit_down",
Name = "Orbit down",
Command = [[ openspace.navigation.addGlobalRotation(0.0, -5.0) ]],
Documentation = "Orbits the camera down around the current focus",
GuiPath = "/Ipac",
IsLocal = false
}
asset.export("IpacOrbitDown", orbit_down)
local pan_right = {
Identifier = "ipac.pan_right",
Name = "Pan right",
Command = [[ openspace.navigation.addLocalRotation(-5.0, 0.0) ]],
Documentation = "Pans the camera to the right",
GuiPath = "/Ipac",
IsLocal = false
}
asset.export("IpacPanRight", pan_right)
local pan_left = {
Identifier = "ipac.pan_left",
Name = "Pan left",
Command = [[ openspace.navigation.addLocalRotation(5.0, 0.0) ]],
Documentation = "Pans the camera to the left",
GuiPath = "/Ipac",
IsLocal = false
}
asset.export("IpacPanLeft", pan_left)
local pan_up = {
Identifier = "ipac.pan_up",
Name = "Pan up",
Command = [[ openspace.navigation.addLocalRotation(0.0, 5.0) ]],
Documentation = "Pans the camera up",
GuiPath = "/Ipac",
IsLocal = false
}
asset.export("IpacPanUp", pan_up)
local pan_down = {
Identifier = "ipac.pan_down",
Name = "Pan down",
Command = [[ openspace.navigation.addLocalRotation(0.0, -5.0) ]],
Documentation = "Pans the camera down",
GuiPath = "/Ipac",
IsLocal = false
}
asset.export("IpacPanDown", pan_down)
local zoom_in = {
Identifier = "ipac.zoom_in",
Name = "Zoom in",
Command = [[ openspace.navigation.addTruckMovement(0.0, 5.0) ]],
Documentation = "Zooms the camera in, towards the current focus",
GuiPath = "/Ipac",
IsLocal = false
}
asset.export("IpacZoomIn", zoom_in)
local zoom_out = {
Identifier = "ipac.zoom_out",
Name = "Zoom out",
Command = [[ openspace.navigation.addTruckMovement(0.0, -5.0) ]],
Documentation = "Zooms the camera out, away form the current focus",
GuiPath = "/Ipac",
IsLocal = false
}
asset.export("IpacZoomOut", zoom_out)
local focus_moon = {
Identifier = "ipac.focus_moon",
Name = "Focus on the Moon",
Command = [[
openspace.setPropertyValueSingle("NavigationHandler.OrbitalNavigator.Aim", "");
openspace.setPropertyValueSingle("NavigationHandler.OrbitalNavigator.Anchor", "Moon");
openspace.setPropertyValueSingle("NavigationHandler.OrbitalNavigator.RetargetAnchor", nil);
]],
Documentation = "Focuses the camera on the Moon",
GuiPath = "/Ipac",
IsLocal = false
}
asset.export("IpacFocusMoon", focus_moon)
local focus_earth = {
Identifier = "ipac.focus_earth",
Name = "Focus on the Earth",
Command = [[
openspace.setPropertyValueSingle("NavigationHandler.OrbitalNavigator.Aim", "");
openspace.setPropertyValueSingle("NavigationHandler.OrbitalNavigator.Anchor", "Earth");
openspace.setPropertyValueSingle("NavigationHandler.OrbitalNavigator.RetargetAnchor", nil)
]],
Documentation = "Focuses the camera on Earth",
GuiPath = "/Ipac",
IsLocal = false
}
asset.export("IpacFocusEarth", focus_earth)
local actions = {
orbit_right,
orbit_left,
orbit_up,
orbit_down,
pan_right,
pan_left,
pan_up,
pan_down,
zoom_in,
zoom_out,
focus_moon,
focus_earth
}
asset.onInitialize(function()
for _, a in ipairs(actions) do
openspace.action.registerAction(a)
end
openspace.clearKeys()
openspace.bindKey("RIGHT", "openspace.navigation.addGlobalRotation(-5.0, 0.0)");
openspace.bindKey("LEFT", "openspace.navigation.addGlobalRotation(5.0, 0.0)");
openspace.bindKey("UP", "openspace.navigation.addGlobalRotation(0.0, 5.0)");
openspace.bindKey("DOWN", "openspace.navigation.addGlobalRotation(0.0, -5.0)");
openspace.bindKey("RIGHT", orbit_right.Identifier)
openspace.bindKey("LEFT", orbit_left.Identifier)
openspace.bindKey("UP", orbit_up.Identifier)
openspace.bindKey("DOWN", orbit_down.Identifier)
openspace.bindKey("CTRL+RIGHT", "openspace.navigation.addLocalRotation(-5.0, 0.0)");
openspace.bindKey("CTRL+LEFT", "openspace.navigation.addLocalRotation(5.0, 0.0)");
openspace.bindKey("CTRL+UP", "openspace.navigation.addLocalRotation(0.0, 5.0)");
openspace.bindKey("CTRL+DOWN", "openspace.navigation.addLocalRotation(0.0, -5.0)");
openspace.bindKey("CTRL+RIGHT", pan_right.Identifier)
openspace.bindKey("CTRL+LEFT", pan_left.Identifier)
openspace.bindKey("CTRL+UP", pan_up.Identifier)
openspace.bindKey("CTRL+DOWN", pan_down.Identifier)
openspace.bindKey("ALT+UP", "openspace.navigation.addTruckMovement(0.0, 5.0)");
openspace.bindKey("ALT+DOWN", "openspace.navigation.addTruckMovement(0.0, -5.0)");
openspace.bindKey("ALT+UP", zoom_in.Identifier)
openspace.bindKey("ALT+DOWN", zoom_out.Identifier)
openspace.bindKey(
"SPACE",
[[
openspace.setPropertyValueSingle("NavigationHandler.OrbitalNavigator.Aim", "");
openspace.setPropertyValueSingle("NavigationHandler.OrbitalNavigator.Anchor", "Moon");
openspace.setPropertyValueSingle("NavigationHandler.OrbitalNavigator.RetargetAnchor", nil)
]])
openspace.bindKey(
"Z",
[[
openspace.setPropertyValueSingle("NavigationHandler.OrbitalNavigator.Aim", "");
openspace.setPropertyValueSingle("NavigationHandler.OrbitalNavigator.Anchor", "Earth");
openspace.setPropertyValueSingle("NavigationHandler.OrbitalNavigator.RetargetAnchor", nil)
]])
openspace.bindKey("SPACE", focus_moon.Identifier)
openspace.bindKey("Z", focus_earth.Identifier)
end)
asset.onDeinitialize(function ()
for i = #actions, 1, -1 do
openspace.action.removeAction(actions[i])
end
end)
+1
View File
@@ -56,6 +56,7 @@ set_folder_location(GhoulTest "Unit Tests")
begin_dependency("Spice")
set(SPICE_BUILD_SHARED_LIBRARY OFF CACHE BOOL "" FORCE)
add_subdirectory(spice)
target_compile_features(spice PUBLIC cxx_std_20)
set_folder_location(spice "External")
end_dependency()
+2
View File
@@ -96,6 +96,8 @@ public:
void setRenderBin(RenderBin bin);
bool matchesRenderBinMask(int binMask);
void setFade(float fade);
bool isVisible() const;
void onEnabledChange(std::function<void(bool)> callback);
+2 -2
View File
@@ -98,8 +98,8 @@ public:
void addScreenSpaceRenderable(std::unique_ptr<ScreenSpaceRenderable> s);
void removeScreenSpaceRenderable(ScreenSpaceRenderable* s);
void removeScreenSpaceRenderable(const std::string& identifier);
ScreenSpaceRenderable* screenSpaceRenderable(const std::string& identifier);
void removeScreenSpaceRenderable(std::string_view identifier);
ScreenSpaceRenderable* screenSpaceRenderable(std::string_view identifier);
std::vector<ScreenSpaceRenderable*> screenSpaceRenderables() const;
std::unique_ptr<ghoul::opengl::ProgramObject> buildRenderProgram(
-2
View File
@@ -80,11 +80,9 @@ private:
float _minValue = 0.f;
float _maxValue = 0.f;
float* _data = nullptr;
std::vector<float> _equalizer;
int _numValues = 0;
};
} // namespace openspace
@@ -30,6 +30,7 @@
#include <openspace/documentation/verifier.h>
#include <openspace/engine/globals.h>
#include <openspace/navigation/navigationhandler.h>
#include <ghoul/misc/profiling.h>
#include <openspace/properties/property.h>
#include <openspace/rendering/deferredcastermanager.h>
#include <math.h>
+11
View File
@@ -165,3 +165,14 @@ create_new_module(
STATIC
${HEADER_FILES} ${SOURCE_FILES} ${SHADER_FILES}
)
target_precompile_headers(${base_module} PRIVATE
<openspace/documentation/documentation.h>
<openspace/documentation/verifier.h>
<openspace/properties/numericalproperty.h>
<openspace/rendering/renderable.h>
<ghoul/opengl/programobject.h>
<ghoul/opengl/shaderobject.h>
<ghoul/opengl/uniformcache.h>
<future>
<map>
)
+14
View File
@@ -48,4 +48,18 @@ create_new_module(
${OPENSPACE_HEADER_FILES} ${OPENSPACE_SOURCE_FILES}
)
target_precompile_headers(${cefwebgui_module} PRIVATE
[["include/capi/cef_base_capi.h"]]
[["include/cef_render_handler.h"]]
<string>
<sstream>
<istream>
<ostream>
)
if (WIN32)
target_precompile_headers(${cefwebgui_module} PRIVATE
<Windows.h>
)
endif ()
set_modules_dependency_on_cef_libraries(${cefwebgui_module})
@@ -40,9 +40,9 @@
#include <optional>
namespace {
constexpr std::array<const char*, 6> UniformNames = {
constexpr std::array<const char*, 7> UniformNames = {
"modelViewProjectionTransform", "offset", "opacity",
"discTexture", "eccentricity", "semiMajorAxis"
"discTexture", "eccentricity", "semiMajorAxis", "multiplyColor"
};
constexpr openspace::properties::Property::PropertyInfo TextureInfo = {
@@ -74,6 +74,13 @@ namespace {
"from the semi-major axis and 1 is a whole semi-major axis's worth of deviation"
};
constexpr openspace::properties::Property::PropertyInfo MultiplyColorInfo = {
"MultiplyColor",
"Multiply Color",
"If set, the disc's texture is multiplied with this color. "
"Useful for applying a color grayscale images"
};
struct [[codegen::Dictionary(RenderableOrbitDisc)]] Parameters {
// [[codegen::verbatim(TextureInfo.description)]]
std::filesystem::path texture;
@@ -86,6 +93,9 @@ namespace {
// [[codegen::verbatim(OffsetInfo.description)]]
std::optional<glm::vec2> offset;
// [[codegen::verbatim(MultiplyColorInfo.description)]]
std::optional<glm::vec3> multiplyColor [[codegen::color()]];
};
#include "renderableorbitdisc_codegen.cpp"
} // namespace
@@ -102,6 +112,7 @@ RenderableOrbitDisc::RenderableOrbitDisc(const ghoul::Dictionary& dictionary)
, _size(SizeInfo, 1.f, 0.f, 3.0e12f)
, _eccentricity(EccentricityInfo, 0.f, 0.f, 1.f)
, _offset(OffsetInfo, glm::vec2(0.f), glm::vec2(0.f), glm::vec2(1.f))
, _multiplyColor(MultiplyColorInfo, glm::vec3(1.f), glm::vec3(0.f), glm::vec3(1.f))
{
const Parameters p = codegen::bake<Parameters>(dictionary);
@@ -119,6 +130,10 @@ RenderableOrbitDisc::RenderableOrbitDisc(const ghoul::Dictionary& dictionary)
_texturePath.onChange([&]() { _texture->loadFromFile(_texturePath.value()); });
addProperty(_texturePath);
_multiplyColor = p.multiplyColor.value_or(_multiplyColor);
_multiplyColor.setViewOption(properties::Property::ViewOptions::Color);
addProperty(_multiplyColor);
_eccentricity = p.eccentricity;
_eccentricity.onChange([&]() { _planeIsDirty = true; });
addProperty(_eccentricity);
@@ -179,6 +194,7 @@ void RenderableOrbitDisc::render(const RenderData& data, RendererTasks&) {
_shader->setUniform(_uniformCache.opacity, opacity());
_shader->setUniform(_uniformCache.eccentricity, _eccentricity);
_shader->setUniform(_uniformCache.semiMajorAxis, _size);
_shader->setUniform(_uniformCache.multiplyColor, _multiplyColor);
ghoul::opengl::TextureUnit unit;
unit.activate();
@@ -28,6 +28,7 @@
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/scalar/floatproperty.h>
#include <openspace/properties/vector/vec2property.h>
#include <openspace/properties/vector/vec3property.h>
#include <openspace/rendering/renderable.h>
#include <openspace/rendering/texturecomponent.h>
#include <openspace/util/planegeometry.h>
@@ -64,10 +65,11 @@ private:
properties::FloatProperty _size;
properties::FloatProperty _eccentricity;
properties::Vec2Property _offset;
properties::Vec3Property _multiplyColor;
std::unique_ptr<ghoul::opengl::ProgramObject> _shader = nullptr;
UniformCache(modelViewProjection, offset, opacity, texture,
eccentricity, semiMajorAxis) _uniformCache;
eccentricity, semiMajorAxis, multiplyColor) _uniformCache;
std::unique_ptr<PlaneGeometry> _plane;
std::unique_ptr<TextureComponent> _texture;
@@ -32,6 +32,7 @@ uniform vec2 offset; // relative to semi major axis
uniform float opacity;
uniform float eccentricity;
uniform float semiMajorAxis;
uniform vec3 multiplyColor = vec3(1.0);
const float Epsilon = 0.0000001;
@@ -122,6 +123,7 @@ Fragment getFragment() {
vec4 diffuse = texture(discTexture, textureCoord);
diffuse.a *= opacity;
diffuse.rgb *= multiplyColor;
Fragment frag;
frag.color = diffuse;
@@ -41,6 +41,7 @@
#include <ccmc/Kameleon.h>
#include <ccmc/KameleonInterpolator.h>
#include <ccmc/Tracer.h>
#include <modules/kameleon/include/kameleonhelper.h>
#ifdef _MSC_VER
+5
View File
@@ -64,3 +64,8 @@ disable_external_warnings(CCfits)
target_include_directories(openspace-module-fitsfilereader SYSTEM PRIVATE ${INCLUDES_FOR_TARGET})
target_link_libraries(openspace-module-fitsfilereader PRIVATE cfitsio CCfits)
target_precompile_headers(CCfits PRIVATE
<istream>
<ostream>
)
+6
View File
@@ -139,6 +139,12 @@ create_new_module(
STATIC
${HEADER_FILES} ${SOURCE_FILES} ${SHADER_FILES}
)
target_precompile_headers(${globebrowsing_module} PRIVATE
<modules/globebrowsing/src/tileprovider/tileprovider.h>
<modules/globebrowsing/globebrowsingmodule.h>
<future>
<map>
)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/gdal_data DESTINATION modules/globebrowsing)
@@ -512,7 +512,7 @@ void ShadowComponent::saveDepthBuffer() {
<< std::endl;
ppmFile << "255" << std::endl;
std::cout << "\n\nSaving depth texture to file depthBufferShadowMapping.ppm\n\n";
LDEBUG("Saving depth texture to file depthBufferShadowMapping.ppm");
int k = 0;
for (int i = 0; i < _shadowDepthTextureWidth; i++) {
for (int j = 0; j < _shadowDepthTextureHeight; j++, k++) {
@@ -523,8 +523,7 @@ void ShadowComponent::saveDepthBuffer() {
}
ppmFile.close();
std::cout << "Texture saved to file depthBufferShadowMapping.ppm\n\n";
LDEBUG("Texture saved to file depthBufferShadowMapping.ppm");
}
buffer.clear();
@@ -552,7 +551,7 @@ void ShadowComponent::saveDepthBuffer() {
<< std::endl;
ppmFile << "255" << std::endl;
std::cout << "\n\nSaving texture position to positionBufferShadowMapping.ppm\n\n";
LDEBUG("Saving texture position to positionBufferShadowMapping.ppm");
float biggestValue = 0.f;
@@ -580,7 +579,7 @@ void ShadowComponent::saveDepthBuffer() {
ppmFile.close();
LINFO("Texture saved to file positionBufferShadowMapping.ppm");
LDEBUG("Texture saved to file positionBufferShadowMapping.ppm");
}
}
+4
View File
@@ -80,3 +80,7 @@ create_new_module(
STATIC
${HEADER_FILES} ${SOURCE_FILES} ${SHADER_FILES}
)
target_precompile_headers(${iswa_module} PRIVATE
<openspace/json.h>
<future>
)
+2
View File
@@ -93,6 +93,7 @@ protected:
* \return \c true if update was successful
*/
virtual bool updateTexture() = 0;
/**
* Is called before updateTexture. For IswaCygnets getting data from a HTTP request,
* this function should get the dataFile from the future object.
@@ -100,6 +101,7 @@ protected:
* \return \c true if update was successful
*/
virtual bool updateTextureResource() = 0;
/**
* Should send a HTTP request to get the resource it needs to create a texture. For
* Texture cygnets, this should be an image. For DataCygnets, this should be the data
+26 -29
View File
@@ -64,27 +64,25 @@
#endif // OPENSPACE_MODULE_KAMELEON_ENABLED
constexpr std::string_view monthNumber(std::string_view month) {
if (month == "JAN") return "01";
else if (month == "FEB") return "02";
else if (month == "MAR") return "03";
else if (month == "APR") return "04";
else if (month == "MAY") return "05";
else if (month == "JUN") return "06";
else if (month == "JUL") return "07";
else if (month == "AUG") return "08";
else if (month == "SEP") return "09";
else if (month == "OCT") return "10";
else if (month == "NOV") return "11";
else if (month == "DEC") return "12";
else return "";
}
namespace {
using json = nlohmann::json;
constexpr std::string_view _loggerCat = "IswaManager";
constexpr std::string_view monthNumber(std::string_view month) {
if (month == "JAN") return "01";
else if (month == "FEB") return "02";
else if (month == "MAR") return "03";
else if (month == "APR") return "04";
else if (month == "MAY") return "05";
else if (month == "JUN") return "06";
else if (month == "JUL") return "07";
else if (month == "AUG") return "08";
else if (month == "SEP") return "09";
else if (month == "OCT") return "10";
else if (month == "NOV") return "11";
else if (month == "DEC") return "12";
else return "";
}
void createScreenSpace(int id) {
std::string idStr = std::to_string(id);
openspace::global::scriptEngine->queueScript(
@@ -92,7 +90,6 @@ namespace {
openspace::scripting::ScriptEngine::RemoteScripting::Yes
);
}
} // namespace
namespace openspace {
@@ -178,7 +175,7 @@ void IswaManager::addIswaCygnet(int id, const std::string& type, std::string gro
metaFuture.json = res;
//convert to json
json j = json::parse(res);
nlohmann::json j = nlohmann::json::parse(res);
// Check what kind of geometry here
if (j["Coordinate Type"].is_null()) {
@@ -357,7 +354,7 @@ std::string IswaManager::jsonPlaneToLuaTable(MetadataFuture& data) {
if (data.json.empty()) {
return "";
}
json j = json::parse(data.json);
nlohmann::json j = nlohmann::json::parse(data.json);
std::string parent = j["Central Body"];
std::string frame = j["Coordinates"];
@@ -473,7 +470,7 @@ std::string IswaManager::jsonSphereToLuaTable(MetadataFuture& data) {
return "";
}
json j = json::parse(data.json);
nlohmann::json j = nlohmann::json::parse(data.json);
j = j["metadata"];
std::string parent = j["central_body"];
parent[0] = static_cast<char>(toupper(static_cast<int>(parent[0])));
@@ -667,16 +664,16 @@ void IswaManager::createFieldline(std::string name, std::string cdfPath,
void IswaManager::fillCygnetInfo(std::string jsonString) {
if (jsonString != "") {
json j = json::parse(jsonString);
nlohmann::json j = nlohmann::json::parse(jsonString);
std::set<std::string> lists = {"listOfPriorityCygnets", "listOfOKCygnets"
// ,"listOfStaleCygnets", "listOfInactiveCygnets",
};
for (const std::string& list : lists) {
json jsonList = j[list];
nlohmann::json jsonList = j[list];
for (size_t i = 0; i < jsonList.size(); ++i) {
json jCygnet = jsonList.at(i);
nlohmann::json jCygnet = jsonList.at(i);
std::string name = jCygnet["cygnetDisplayTitle"];
std::replace(name.begin(), name.end(),'.', ',');
@@ -706,9 +703,9 @@ void IswaManager::addCdfFiles(std::string cdfpath) {
std::ifstream jsonFile(cdfFile);
if (jsonFile.is_open()) {
json cdfGroups = json::parse(jsonFile);
nlohmann::json cdfGroups = nlohmann::json::parse(jsonFile);
for(size_t i = 0; i < cdfGroups.size(); ++i) {
json cdfGroup = cdfGroups.at(i);
nlohmann::json cdfGroup = cdfGroups.at(i);
std::string groupName = cdfGroup["group"];
std::string fieldlineSeedsIndexFile = cdfGroup["fieldlinefile"];
@@ -720,9 +717,9 @@ void IswaManager::addCdfFiles(std::string cdfpath) {
_cdfInformation[groupName] = std::vector<CdfInfo>();
json cdfs = cdfGroup["cdfs"];
nlohmann::json cdfs = cdfGroup["cdfs"];
for (size_t j = 0; j < cdfs.size(); j++) {
json cdf = cdfs.at(j);
nlohmann::json cdf = cdfs.at(j);
std::string name = cdf["name"];
std::string path = cdf["path"];
+14
View File
@@ -71,6 +71,20 @@ if (TARGET cdf)
set_folder_location(cdf "External")
endif ()
target_precompile_headers(cdf PRIVATE
[["stdio.h"]]
[["stdlib.h"]]
[["string.h"]]
)
target_precompile_headers(ccmc PRIVATE
"$<$<COMPILE_LANGUAGE:CXX>:iostream>"
"$<$<COMPILE_LANGUAGE:CXX>:map>"
"$<$<COMPILE_LANGUAGE:CXX>:unordered_map>"
"$<$<COMPILE_LANGUAGE:CXX>:vector>"
"$<$<COMPILE_LANGUAGE:CXX>:boost/unordered_map.hpp>"
)
if (WIN32)
target_compile_options(ccmc PRIVATE /MP)
if (TARGET cdf)
+1
View File
@@ -35,6 +35,7 @@
#endif // _MSC_VER
#include <ccmc/Kameleon.h>
#include <ccmc/FileReader.h>
#ifdef _MSC_VER
#pragma warning (pop)
+2
View File
@@ -39,6 +39,8 @@
#endif // WIN32
#include <ccmc/Kameleon.h>
#include <ccmc/Constants.h>
#include <ccmc/FileReader.h>
#include <ccmc/Model.h>
#include <ccmc/Interpolator.h>
#include <ccmc/BATSRUS.h>
@@ -42,6 +42,7 @@
#include <ccmc/Kameleon.h>
#include <ccmc/Model.h>
#include <ccmc/FileReader.h>
#include <ccmc/BATSRUS.h>
#include <ccmc/ENLIL.h>
#include <ccmc/CCMCTime.h>
@@ -27,7 +27,6 @@
#include <openspace/util/histogram.h>
#include <filesystem>
#include <string>
namespace openspace {
+7
View File
@@ -82,3 +82,10 @@ create_new_module(
server_module
${HEADER_FILES} ${SOURCE_FILES}
)
target_precompile_headers(${server_module} PRIVATE
<modules/server/include/connection.h>
<modules/server/include/topics/topic.h>
<openspace/json.h>
<ghoul/misc/templatefactory.h>
)
@@ -101,7 +101,7 @@ void SkyBrowserTopic::sendBrowserData() {
// Pass data for all the browsers and the corresponding targets
if (module->isCameraInSolarSystem()) {
const std::vector<std::unique_ptr<TargetBrowserPair>>& pairs = module->getPairs();
const std::vector<std::unique_ptr<TargetBrowserPair>>& pairs = module->pairs();
ghoul::Dictionary targets;
for (const std::unique_ptr<TargetBrowserPair>& pair : pairs) {
std::string id = pair->browserId();
+4
View File
@@ -63,3 +63,7 @@ create_new_module(
STATIC
${HEADER_FILES} ${SOURCE_FILES} ${SHADER_FILES}
)
target_precompile_headers(${skybrowser_module} PRIVATE
[["include/cef_accessibility_handler.h"]]
[["include/cef_render_handler.h"]]
)
+3 -3
View File
@@ -28,8 +28,8 @@
#include <modules/webbrowser/include/webrenderhandler.h>
#include <openspace/documentation/documentation.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/vector/vec2property.h>
#include <openspace/properties/triggerproperty.h>
#include <openspace/properties/vector/vec2property.h>
#ifdef _MSC_VER
#pragma warning (push)
@@ -64,7 +64,7 @@ public:
explicit Browser(const ghoul::Dictionary& dictionary);
virtual ~Browser();
bool initializeGL();
void initializeGL();
void deinitializeGL();
bool isReady() const;
@@ -78,7 +78,7 @@ public:
void setCallbackDimensions(const std::function<void(const glm::dvec2&)>& function);
protected:
properties::Vec2Property _browserPixeldimensions;
properties::Vec2Property _browserDimensions;
properties::StringProperty _url;
properties::TriggerProperty _reload;
@@ -29,7 +29,6 @@
#include <openspace/documentation/documentation.h>
#include <openspace/properties/scalar/floatproperty.h>
#include <openspace/properties/scalar/doubleproperty.h>
namespace openspace::documentation { struct Documentation; }
@@ -29,9 +29,9 @@
#include <modules/skybrowser/include/wwtcommunicator.h>
#include <openspace/documentation/documentation.h>
#include <openspace/properties/scalar/doubleproperty.h>
#include <openspace/properties/scalar/boolproperty.h>
#include <openspace/properties/scalar/floatproperty.h>
#include <openspace/properties/vector/vec2property.h>
#include <openspace/properties/vector/vec3property.h>
namespace openspace {
@@ -26,8 +26,6 @@
#define __OPENSPACE_MODULE_SKYBROWSER___TARGETBROWSERPAIR___H__
#include <modules/skybrowser/include/utility.h>
#include <openspace/documentation/documentation.h>
#include <deque>
namespace ghoul { class Dictionary; }
@@ -42,7 +40,6 @@ class ScreenSpaceRenderable;
class TargetBrowserPair {
public:
TargetBrowserPair(SceneGraphNode* target, ScreenSpaceSkyBrowser* browser);
TargetBrowserPair& operator=(TargetBrowserPair other);
// Target & Browser
void initialize();
@@ -60,9 +57,7 @@ public:
// Browser
void sendIdToBrowser() const;
void updateBrowserSize();
std::vector<std::pair<std::string, glm::dvec3>> displayCopies() const;
bool isImageCollectionLoaded();
// Target
void centerTargetOnScreen();
@@ -73,7 +68,6 @@ public:
bool isEnabled() const;
void setEnabled(bool enable);
void setOpacity(float opacity);
void setVerticalFov(double vfov);
void setEquatorialAim(const glm::dvec2& aim);
void setBorderColor(const glm::ivec3& color);
@@ -89,9 +83,7 @@ public:
std::string browserId() const;
std::string targetRenderableId() const;
std::string targetNodeId() const;
float browserRatio() const;
SceneGraphNode* targetNode() const;
ScreenSpaceSkyBrowser* browser() const;
std::vector<int> selectedImages() const;
@@ -106,12 +98,7 @@ public:
void setImageOpacity(int i, float opacity);
void hideChromeInterface();
friend bool operator==(const TargetBrowserPair& lhs, const TargetBrowserPair& rhs);
friend bool operator!=(const TargetBrowserPair& lhs, const TargetBrowserPair& rhs);
private:
void aimTargetGalactic(glm::dvec3 direction);
// Target and browser
RenderableSkyTarget* _targetRenderable = nullptr;
ScreenSpaceSkyBrowser* _browser = nullptr;
+6 -20
View File
@@ -33,20 +33,7 @@ namespace openspace::skybrowser {
// Constants
constexpr double ScreenSpaceZ = -2.1;
constexpr glm::dvec3 NorthPole = { 0.0, 0.0, 1.0 };
constexpr double CelestialSphereRadius = 4 * distanceconstants::Parsec;
// Conversion matrix - J2000 equatorial <-> galactic
// https://arxiv.org/abs/1010.3773v1
const glm::dmat3 conversionMatrix = glm::dmat3(
-0.054875539390, 0.494109453633, -0.867666135681, // col 0
-0.873437104725, -0.444829594298, -0.198076389622, // col 1
-0.483834991775, 0.746982248696, 0.455983794523 // col 2
);
// Galactic coordinates are projected onto the celestial sphere
// Equatorial coordinates are unit length
// Conversion spherical <-> Cartesian
constexpr double CelestialSphereRadius = 4.0 * distanceconstants::Parsec;
/**
* Converts from Cartesian coordinates to spherical coordinates with unit length.
@@ -205,9 +192,8 @@ public:
Animation(T start, T goal, double time)
: _goal(std::move(goal))
, _start(std::move(start))
{
_animationTime = std::chrono::milliseconds(static_cast<int>(time * 1000));
}
, _animationTime(std::chrono::milliseconds(static_cast<int>(time * 1000)))
{}
void start() {
_isStarted = true;
@@ -219,12 +205,12 @@ public:
}
bool isAnimating() const {
bool timeLeft = timeSpent().count() < _animationTime.count() ? true : false;
bool timeLeft = timeSpent().count() < _animationTime.count();
return timeLeft && _isStarted;
}
T getNewValue();
glm::dmat4 getRotationMatrix();
T newValue() const;
glm::dmat4 rotationMatrix();
private:
std::chrono::duration<double, std::milli> timeSpent() const {
+1 -19
View File
@@ -27,10 +27,6 @@
#include <modules/skybrowser/include/browser.h>
#include <openspace/documentation/documentation.h>
#include <openspace/properties/vector/dvec2property.h>
#include <openspace/properties/scalar/floatproperty.h>
#include <openspace/properties/vector/ivec3property.h>
#include <deque>
namespace openspace {
@@ -38,8 +34,7 @@ namespace openspace {
class WwtCommunicator : public Browser {
public:
explicit WwtCommunicator(const ghoul::Dictionary& dictionary);
WwtCommunicator(const WwtCommunicator&) = default;
~WwtCommunicator() override;
~WwtCommunicator() override = default;
void update();
@@ -82,23 +77,10 @@ protected:
std::deque<std::pair<int, double>> _selectedImages;
private:
void setWebpageBorderColor(glm::ivec3 color) const;
void sendMessageToWwt(const ghoul::Dictionary& msg) const;
// WorldWide Telescope messages
ghoul::Dictionary moveCameraMessage(const glm::dvec2& celestCoords, double fov,
double roll, bool shouldMoveInstantly = true) const;
ghoul::Dictionary loadCollectionMessage(const std::string& url) const;
ghoul::Dictionary setForegroundMessage(const std::string& name) const;
ghoul::Dictionary addImageMessage(const std::string& id,
const std::string& url) const;
ghoul::Dictionary removeImageMessage(const std::string& id) const;
ghoul::Dictionary setImageOpacityMessage(const std::string& id, double opacity) const;
ghoul::Dictionary setLayerOrderMessage(const std::string& id, int version);
bool _borderColorIsDirty = false;
bool _equatorialAimIsDirty = false;
int messageCounter = 0;
// Time variables
// For capping the message passing to WWT
+13 -47
View File
@@ -25,51 +25,22 @@
#ifndef __OPENSPACE_MODULE_SKYBROWSER___WWTDATAHANDLER___H__
#define __OPENSPACE_MODULE_SKYBROWSER___WWTDATAHANDLER___H__
#include <modules/space/speckloader.h>
#include <openspace/documentation/documentation.h>
#include <unordered_map>
#include <filesystem>
#include <memory>
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsuggest-override"
#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
#endif
#include <modules/skybrowser/ext/tinyxml2/tinyxml2.h>
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
#endif
namespace openspace::documentation { struct Documentation; }
namespace openspace::wwt {
const std::string Thumbnail = "Thumbnail";
const std::string Name = "Name";
const std::string ImageSet = "ImageSet";
const std::string Dec = "Dec";
const std::string RA = "RA";
const std::string Undefined = "";
const std::string Folder = "Folder";
const std::string Place = "Place";
const std::string ThumbnailUrl = "ThumbnailUrl";
const std::string Url = "Url";
const std::string Credits = "Credits";
const std::string CreditsUrl = "CreditsUrl";
const std::string ZoomLevel = "ZoomLevel";
const std::string DataSetType = "DataSetType";
const std::string Sky = "Sky";
} // namespace openspace::wwt
namespace tinyxml2 { class XMLElement; }
namespace openspace {
namespace documentation { struct Documentation; }
struct ImageData {
std::string name = wwt::Undefined;
std::string thumbnailUrl = wwt::Undefined;
std::string imageUrl = wwt::Undefined;
std::string credits = wwt::Undefined;
std::string creditsUrl = wwt::Undefined;
std::string collection = wwt::Undefined;
std::string name;
std::string thumbnailUrl;
std::string imageUrl;
std::string credits;
std::string creditsUrl;
std::string collection;
bool hasCelestialCoords = false;
float fov = 0.f;
glm::dvec2 equatorialSpherical = glm::dvec2(0.0);
@@ -78,20 +49,15 @@ struct ImageData {
class WwtDataHandler {
public:
WwtDataHandler() = default;
~WwtDataHandler();
void loadImages(const std::string& root, const std::filesystem::path& directory);
int nLoadedImages() const;
const ImageData& getImage(int i) const;
const ImageData& image(int i) const;
private:
void saveImageFromNode(tinyxml2::XMLElement* node, std::string collection);
void saveImagesFromXml(tinyxml2::XMLElement* root, std::string collection);
void saveImagesFromXml(const tinyxml2::XMLElement* root, std::string collection);
// Images
std::vector<ImageData> _images;
std::vector<tinyxml2::XMLDocument*> _xmls;
};
} // namespace openspace
+49 -48
View File
@@ -150,8 +150,10 @@ SkyBrowserModule::SkyBrowserModule()
, _hideTargetsBrowsersWithGui(HideWithGuiInfo, false)
, _inverseZoomDirection(InverseZoomInfo, false)
, _spaceCraftAnimationTime(SpaceCraftTimeInfo, 2.0, 0.0, 10.0)
, _wwtImageCollectionUrl(ImageCollectionInfo,
"https://data.openspaceproject.com/wwt/1/imagecollection.wtml")
, _wwtImageCollectionUrl(
ImageCollectionInfo,
"https://data.openspaceproject.com/wwt/1/imagecollection.wtml"
)
{
addProperty(_enabled);
addProperty(_showTitleInGuiBrowser);
@@ -189,7 +191,8 @@ SkyBrowserModule::SkyBrowserModule()
if (vizModeChanged) {
constexpr float FadeDuration = 2.f;
if (camWasInSolarSystem) { // Camera moved out of the solar system => fade out
if (camWasInSolarSystem) {
// Camera moved out of the solar system => fade out
for (const std::unique_ptr<TargetBrowserPair>& pair : _targetsBrowsers) {
pair->startFading(0.f, FadeDuration);
}
@@ -197,7 +200,8 @@ SkyBrowserModule::SkyBrowserModule()
// Also hide the hover circle
disableHoverCircle();
}
else { // Camera moved into the solar system => fade in
else {
// Camera moved into the solar system => fade in
for (const std::unique_ptr<TargetBrowserPair>& pair : _targetsBrowsers) {
pair->startFading(1.f, FadeDuration);
}
@@ -246,10 +250,6 @@ void SkyBrowserModule::internalInitialize(const ghoul::Dictionary& dict) {
// Register ScreenSpaceSkyTarget
fRenderable->registerClass<RenderableSkyTarget>("RenderableSkyTarget");
// Create data handler dynamically to avoid the linking error that
// came up when including the include file in the module header file
_dataHandler = std::make_unique<WwtDataHandler>();
}
void SkyBrowserModule::addTargetBrowserPair(const std::string& targetId,
@@ -281,8 +281,6 @@ void SkyBrowserModule::removeTargetBrowserPair(const std::string& id) {
_targetsBrowsers.begin(),
_targetsBrowsers.end(),
[&](const std::unique_ptr<TargetBrowserPair>& pair) {
// should this be?
// found == pair.get()
return found == pair.get();
}
);
@@ -298,6 +296,7 @@ void SkyBrowserModule::lookAtTarget(const std::string& id) {
}
void SkyBrowserModule::setHoverCircle(SceneGraphNode* circle) {
ghoul_assert(circle, "No circle specified");
_hoverCircle = circle;
// Always disable it per default. It should only be visible on interaction
@@ -305,46 +304,48 @@ void SkyBrowserModule::setHoverCircle(SceneGraphNode* circle) {
}
void SkyBrowserModule::moveHoverCircle(int i, bool useScript) {
const ImageData& image = _dataHandler->getImage(i);
const ImageData& image = _dataHandler.image(i);
// Only move and show circle if the image has coordinates
if (_hoverCircle && image.hasCelestialCoords && _isCameraInSolarSystem) {
const std::string id = _hoverCircle->identifier();
if (!(_hoverCircle && image.hasCelestialCoords && _isCameraInSolarSystem)) {
return;
}
// Show the circle
if (useScript) {
const std::string script = fmt::format(
"openspace.setPropertyValueSingle('Scene.{}.Renderable.Fade', 1.0);",
id
);
global::scriptEngine->queueScript(
script,
scripting::ScriptEngine::RemoteScripting::Yes
);
}
else {
Renderable* renderable = _hoverCircle->renderable();
if (renderable) {
renderable->property("Fade")->set(1.f);
}
}
const std::string id = _hoverCircle->identifier();
// Set the exact target position
// Move it slightly outside of the celestial sphere so it doesn't overlap with
// the target
glm::dvec3 pos = skybrowser::equatorialToGalactic(image.equatorialCartesian);
pos *= skybrowser::CelestialSphereRadius * 1.1;
// Note that the position can only be set through the script engine
// Show the circle
if (useScript) {
const std::string script = fmt::format(
"openspace.setPropertyValueSingle('Scene.{}.Translation.Position', {});",
id, ghoul::to_string(pos)
"openspace.setPropertyValueSingle('Scene.{}.Renderable.Fade', 1.0);",
id
);
global::scriptEngine->queueScript(
script,
scripting::ScriptEngine::RemoteScripting::Yes
);
}
else {
Renderable* renderable = _hoverCircle->renderable();
if (renderable) {
renderable->setFade(1.f);
}
}
// Set the exact target position
// Move it slightly outside of the celestial sphere so it doesn't overlap with
// the target
glm::dvec3 pos = skybrowser::equatorialToGalactic(image.equatorialCartesian);
pos *= skybrowser::CelestialSphereRadius * 1.1;
// Note that the position can only be set through the script engine
const std::string script = fmt::format(
"openspace.setPropertyValueSingle('Scene.{}.Translation.Position', {});",
id, ghoul::to_string(pos)
);
global::scriptEngine->queueScript(
script,
scripting::ScriptEngine::RemoteScripting::Yes
);
}
void SkyBrowserModule::disableHoverCircle(bool useScript) {
@@ -368,18 +369,18 @@ void SkyBrowserModule::disableHoverCircle(bool useScript) {
void SkyBrowserModule::loadImages(const std::string& root,
const std::filesystem::path& directory)
{
_dataHandler->loadImages(root, directory);
_dataHandler.loadImages(root, directory);
}
int SkyBrowserModule::nLoadedImages() const {
return _dataHandler->nLoadedImages();
return _dataHandler.nLoadedImages();
}
const std::unique_ptr<WwtDataHandler>& SkyBrowserModule::getWwtDataHandler() const {
const WwtDataHandler& SkyBrowserModule::wwtDataHandler() const {
return _dataHandler;
}
std::vector<std::unique_ptr<TargetBrowserPair>>& SkyBrowserModule::getPairs() {
std::vector<std::unique_ptr<TargetBrowserPair>>& SkyBrowserModule::pairs() {
return _targetsBrowsers;
}
@@ -387,7 +388,7 @@ int SkyBrowserModule::nPairs() const {
return static_cast<int>(_targetsBrowsers.size());
}
TargetBrowserPair* SkyBrowserModule::pair(const std::string& id) const {
TargetBrowserPair* SkyBrowserModule::pair(std::string_view id) const {
auto it = std::find_if(
_targetsBrowsers.begin(),
_targetsBrowsers.end(),
@@ -416,7 +417,7 @@ void SkyBrowserModule::startRotatingCamera(glm::dvec3 endAnimation) {
void SkyBrowserModule::incrementallyRotateCamera() {
if (_cameraRotation.isAnimating()) {
glm::dmat4 rotMat = _cameraRotation.getRotationMatrix();
glm::dmat4 rotMat = _cameraRotation.rotationMatrix();
global::navigationHandler->camera()->rotate(glm::quat_cast(rotMat));
}
}
@@ -445,9 +446,9 @@ std::string SkyBrowserModule::wwtImageCollectionUrl() const {
return _wwtImageCollectionUrl;
}
void SkyBrowserModule::setSelectedBrowser(const std::string& id) {
TargetBrowserPair* found = pair(id);
if (found) {
void SkyBrowserModule::setSelectedBrowser(std::string_view id) {
TargetBrowserPair* p = pair(id);
if (p) {
_selectedBrowser = id;
}
}
+17 -18
View File
@@ -25,24 +25,21 @@
#ifndef __OPENSPACE_MODULE_SKYBROWSER___SKYBROWSERMODULE___H__
#define __OPENSPACE_MODULE_SKYBROWSER___SKYBROWSERMODULE___H__
#include <modules/skybrowser/include/utility.h>
#include <openspace/util/openspacemodule.h>
#include <openspace/documentation/documentation.h>
#include <openspace/util/distanceconstants.h>
#include <openspace/util/mouse.h>
#include <modules/skybrowser/include/utility.h>
#include <modules/skybrowser/include/wwtdatahandler.h>
#include <openspace/properties/scalar/boolproperty.h>
#include <openspace/properties/scalar/doubleproperty.h>
#include <openspace/properties/stringproperty.h>
#include <fstream>
#include <filesystem>
namespace openspace {
class ScreenSpaceImageLocal;
class WwtDataHandler;
class TargetBrowserPair;
class SceneGraphNode;
struct ImageData;
class SceneGraphNode;
class ScreenSpaceImageLocal;
class TargetBrowserPair;
class SkyBrowserModule : public OpenSpaceModule {
public:
@@ -50,25 +47,24 @@ public:
SkyBrowserModule();
std::vector<std::unique_ptr<TargetBrowserPair>>& getPairs();
std::vector<std::unique_ptr<TargetBrowserPair>>& pairs();
int nPairs() const;
TargetBrowserPair* pair(const std::string& id) const;
const std::unique_ptr<WwtDataHandler>& getWwtDataHandler() const;
TargetBrowserPair* pair(std::string_view id) const;
const WwtDataHandler& wwtDataHandler() const;
std::string selectedBrowserId() const;
std::string selectedTargetId() const;
int uniqueIdentifierCounter() const;
void setSelectedBrowser(const std::string& id);
void setSelectedBrowser(std::string_view id);
void setHoverCircle(SceneGraphNode* circle);
// Rotation, animation, placement
void lookAtTarget(const std::string& id);
void startRotatingCamera(glm::dvec3 endAnimation); // Pass in galactic coordinate
void incrementallyRotateCamera();
void incrementallyAnimateTargets();
double targetAnimationSpeed() const;
double browserAnimationSpeed() const;
double spaceCraftAnimationTime() const;
std::string wwtImageCollectionUrl() const;
bool isCameraInSolarSystem() const;
@@ -94,6 +90,9 @@ protected:
void internalInitialize(const ghoul::Dictionary& dict) override;
private:
void incrementallyRotateCamera();
void incrementallyAnimateTargets();
properties::BoolProperty _enabled;
properties::BoolProperty _showTitleInGuiBrowser;
properties::BoolProperty _allowCameraRotation;
@@ -108,7 +107,7 @@ private:
// The browsers and targets
std::vector<std::unique_ptr<TargetBrowserPair>> _targetsBrowsers;
SceneGraphNode* _hoverCircle = nullptr;
std::string _selectedBrowser = ""; // Currently selected browser
std::string _selectedBrowser; // Currently selected browser
int _uniqueIdentifierCounter = 0;
// Flags
@@ -119,7 +118,7 @@ private:
skybrowser::Animation(glm::dvec3(0.0), glm::dvec3(0.0), 0.0);
// Data handler for the image collections
std::unique_ptr<WwtDataHandler> _dataHandler;
WwtDataHandler _dataHandler;
};
} // namespace openspace
+11 -11
View File
@@ -52,7 +52,7 @@ namespace {
if (module->isCameraInSolarSystem()) {
TargetBrowserPair* selected = module->pair(module->selectedBrowserId());
if (selected) {
const ImageData& image = module->getWwtDataHandler()->getImage(imageIndex);
const ImageData& image = module->wwtDataHandler().image(imageIndex);
// Load image into browser
std::string str = image.name;
// Check if character is ASCII - if it isn't, remove
@@ -147,7 +147,7 @@ namespace {
TargetBrowserPair* pair = module->pair(identifier);
if (pair) {
pair->hideChromeInterface();
pair->loadImageCollection(module->wwtImageCollectionUrl());
pair->browser()->loadImageCollection(module->wwtImageCollectionUrl());
}
}
@@ -162,7 +162,7 @@ namespace {
// Set all border colors to the border color in the master node
if (global::windowDelegate->isMaster()) {
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
const std::vector<std::unique_ptr<TargetBrowserPair>>& pairs = module->getPairs();
const std::vector<std::unique_ptr<TargetBrowserPair>>& pairs = module->pairs();
for (const std::unique_ptr<TargetBrowserPair>& pair : pairs) {
std::string id = pair->browserId();
glm::ivec3 color = pair->borderColor();
@@ -194,7 +194,7 @@ namespace {
// This is called when the sky_browser website is connected to OpenSpace
// Send out identifiers to the browsers
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
const std::vector<std::unique_ptr<TargetBrowserPair>>& pairs = module->getPairs();
const std::vector<std::unique_ptr<TargetBrowserPair>>& pairs = module->pairs();
for (const std::unique_ptr<TargetBrowserPair>& pair : pairs) {
pair->sendIdToBrowser();
}
@@ -257,9 +257,9 @@ namespace {
// Send image list to GUI
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
std::string url = module->wwtImageCollectionUrl();
// If no data has been loaded yet, download the data from the web!
// If no data has been loaded yet, download the data from the web
if (module->nLoadedImages() == 0) {
std::filesystem::path directory = absPath("${MODULE_SKYBROWSER}/wwtimagedata/");
std::filesystem::path directory = absPath("${SYNC}/wwtimagedata/");
module->loadImages(url, directory);
}
@@ -267,7 +267,7 @@ namespace {
ghoul::Dictionary list;
for (int i = 0; i < module->nLoadedImages(); i++) {
const ImageData& img = module->getWwtDataHandler()->getImage(i);
const ImageData& img = module->wwtDataHandler().image(i);
// Push ("Key", value)
ghoul::Dictionary image;
@@ -327,7 +327,7 @@ namespace {
// Pass data for all the browsers and the corresponding targets
if (module->isCameraInSolarSystem()) {
const std::vector<std::unique_ptr<TargetBrowserPair>>& pairs = module->getPairs();
const std::vector<std::unique_ptr<TargetBrowserPair>>& pairs = module->pairs();
for (const std::unique_ptr<TargetBrowserPair>& pair : pairs) {
std::string id = pair->browserId();
@@ -561,7 +561,7 @@ namespace {
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
TargetBrowserPair* pair = module->pair(identifier);
if (pair) {
pair->removeSelectedImage(imageIndex);
pair->browser()->removeSelectedImage(imageIndex);
}
}
@@ -725,7 +725,7 @@ namespace {
std::for_each(
images.rbegin(), images.rend(),
[&](int index) {
const ImageData& image = module->getWwtDataHandler()->getImage(index);
const ImageData& image = module->wwtDataHandler().image(index);
// Index of image is used as layer ID as it is unique in the image data set
pair->browser()->addImageLayerToWwt(image.imageUrl, index);
}
@@ -740,7 +740,7 @@ namespace {
[[codegen::luawrap]] void showAllTargetsAndBrowsers(bool show) {
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
const std::vector<std::unique_ptr<TargetBrowserPair>>& pairs = module->getPairs();
const std::vector<std::unique_ptr<TargetBrowserPair>>& pairs = module->pairs();
for (const std::unique_ptr<TargetBrowserPair>& pair : pairs) {
pair->setEnabled(show);
}
+19 -36
View File
@@ -55,9 +55,6 @@ namespace {
};
struct [[codegen::Dictionary(Browser)]] Parameters {
// [[codegen::verbatim(DimensionsInfo.description)]]
std::optional<glm::vec2> dimensions;
// [[codegen::verbatim(UrlInfo.description)]]
std::optional<std::string> url;
@@ -66,7 +63,6 @@ namespace {
};
#include "browser_codegen.cpp"
} // namespace
namespace openspace {
@@ -80,29 +76,21 @@ void Browser::RenderHandler::setTexture(GLuint t) {
}
Browser::Browser(const ghoul::Dictionary& dictionary)
: _browserPixeldimensions(
: _browserDimensions(
DimensionsInfo,
glm::vec2(500.f),
global::windowDelegate->currentSubwindowSize(),
glm::vec2(10.f),
glm::vec2(3000.f)
)
, _url(UrlInfo)
, _reload(ReloadInfo)
{
if (dictionary.hasValue<std::string>(UrlInfo.identifier)) {
_url = dictionary.value<std::string>(UrlInfo.identifier);
}
// Handle target dimension property
const Parameters p = codegen::bake<Parameters>(dictionary);
_url = p.url.value_or(_url);
_browserPixeldimensions = p.dimensions.value_or(_browserPixeldimensions);
glm::vec2 windowDimensions = global::windowDelegate->currentSubwindowSize();
_browserPixeldimensions = windowDimensions;
_url.onChange([this]() { _isUrlDirty = true; });
_browserPixeldimensions.onChange([this]() { _isDimensionsDirty = true; });
_browserDimensions.onChange([this]() { _isDimensionsDirty = true; });
_reload.onChange([this]() { _shouldReload = true; });
// Create browser and render handler
@@ -121,9 +109,9 @@ Browser::Browser(const ghoul::Dictionary& dictionary)
Browser::~Browser() {}
bool Browser::initializeGL() {
void Browser::initializeGL() {
_texture = std::make_unique<ghoul::opengl::Texture>(
glm::uvec3(glm::ivec2(_browserPixeldimensions.value()), 1),
glm::uvec3(glm::ivec2(_browserDimensions.value()), 1),
GL_TEXTURE_2D
);
@@ -131,7 +119,6 @@ bool Browser::initializeGL() {
_browserInstance->initialize();
_browserInstance->loadUrl(_url);
return isReady();
}
void Browser::deinitializeGL() {
@@ -164,11 +151,11 @@ void Browser::update() {
_browserInstance->loadUrl(_url);
_isUrlDirty = false;
}
if (_isDimensionsDirty) {
if (_browserPixeldimensions.value().x > 0 &&
_browserPixeldimensions.value().y > 0)
{
_browserInstance->reshape(_browserPixeldimensions.value());
glm::vec2 dim = _browserDimensions;
if (dim.x > 0 && dim.y > 0) {
_browserInstance->reshape(dim);
_isDimensionsDirty = false;
}
}
@@ -184,12 +171,12 @@ bool Browser::isReady() const {
}
glm::vec2 Browser::browserPixelDimensions() const {
return _browserPixeldimensions;
return _browserDimensions;
}
// Updates the browser size to match the size of the texture
void Browser::updateBrowserSize() {
_browserPixeldimensions = _texture->dimensions();
_browserDimensions = _texture->dimensions();
}
float Browser::browserRatio() const {
@@ -198,23 +185,19 @@ float Browser::browserRatio() const {
}
void Browser::setCallbackDimensions(const std::function<void(const glm::dvec2&)>& func) {
_browserPixeldimensions.onChange([&]() {
func(_browserPixeldimensions.value());
_browserDimensions.onChange([&]() {
func(_browserDimensions.value());
});
}
void Browser::executeJavascript(const std::string& script) const {
// Make sure that the browser has a main frame
const bool browserExists = _browserInstance && _browserInstance->getBrowser();
const bool frameIsLoaded = browserExists &&
_browserInstance->getBrowser()->GetMainFrame();
bool browserExists = _browserInstance && _browserInstance->getBrowser();
bool frameIsLoaded = browserExists && _browserInstance->getBrowser()->GetMainFrame();
if (frameIsLoaded) {
_browserInstance->getBrowser()->GetMainFrame()->ExecuteJavaScript(
script,
_browserInstance->getBrowser()->GetMainFrame()->GetURL(),
0
);
CefRefPtr<CefFrame> frame = _browserInstance->getBrowser()->GetMainFrame();
frame->ExecuteJavaScript(script, frame->GetURL(), 0);
}
}
@@ -116,7 +116,7 @@ ScreenSpaceSkyBrowser::ScreenSpaceSkyBrowser(const ghoul::Dictionary& dictionary
addProperty(_isHidden);
addProperty(_url);
addProperty(_browserPixeldimensions);
addProperty(_browserDimensions);
addProperty(_reload);
addProperty(_textureQuality);
@@ -198,7 +198,7 @@ void ScreenSpaceSkyBrowser::updateTextureResolution() {
float newResX = newResY * _ratio;
glm::vec2 newSize = glm::vec2(newResX , newResY) * _textureQuality.value();
_browserPixeldimensions = glm::ivec2(newSize);
_browserDimensions = glm::ivec2(newSize);
_texture->setDimensions(glm::ivec3(newSize, 1));
_objectSize = glm::ivec3(_texture->dimensions());
}
+22 -56
View File
@@ -40,6 +40,22 @@
#include <functional>
#include <chrono>
namespace {
void aimTargetGalactic(std::string id, glm::dvec3 direction) {
glm::dvec3 positionCelestial = glm::normalize(direction) *
openspace::skybrowser::CelestialSphereRadius;
std::string script = fmt::format(
"openspace.setPropertyValueSingle('Scene.{}.Translation.Position', {});",
id, ghoul::to_string(positionCelestial)
);
openspace::global::scriptEngine->queueScript(
script,
openspace::scripting::ScriptEngine::RemoteScripting::Yes
);
}
} // namespace
namespace openspace {
TargetBrowserPair::TargetBrowserPair(SceneGraphNode* targetNode,
@@ -53,31 +69,10 @@ TargetBrowserPair::TargetBrowserPair(SceneGraphNode* targetNode,
_targetRenderable = dynamic_cast<RenderableSkyTarget*>(_targetNode->renderable());
}
TargetBrowserPair& TargetBrowserPair::operator=(TargetBrowserPair other) {
std::swap(_targetNode, other._targetNode);
std::swap(_browser, other._browser);
return *this;
}
void TargetBrowserPair::setImageOrder(int i, int order) {
_browser->setImageOrder(i, order);
}
void TargetBrowserPair::aimTargetGalactic(glm::dvec3 direction) {
std::string id = _targetNode->identifier();
glm::dvec3 positionCelestial = glm::normalize(direction) *
skybrowser::CelestialSphereRadius;
std::string script = fmt::format(
"openspace.setPropertyValueSingle('Scene.{}.Translation.Position', {});",
id, ghoul::to_string(positionCelestial)
);
openspace::global::scriptEngine->queueScript(
script,
scripting::ScriptEngine::RemoteScripting::Yes
);
}
void TargetBrowserPair::startFinetuningTarget() {
_startTargetPosition = _targetNode->worldPosition();
}
@@ -100,7 +95,7 @@ void TargetBrowserPair::fineTuneTarget(const glm::vec2& startMouse,
);
glm::dvec3 translationWorld = endWorld - startWorld;
aimTargetGalactic(_startTargetPosition + translationWorld);
aimTargetGalactic(_targetNode->identifier(), _startTargetPosition + translationWorld);
}
void TargetBrowserPair::synchronizeAim() {
@@ -116,11 +111,6 @@ void TargetBrowserPair::setEnabled(bool enable) {
_targetRenderable->property("Enabled")->set(enable);
}
void TargetBrowserPair::setOpacity(float opacity) {
_browser->property("Opacity")->set(opacity);
_targetRenderable->property("Opacity")->set(opacity);
}
bool TargetBrowserPair::isEnabled() const {
return _targetRenderable->isEnabled() || _browser->isEnabled();
}
@@ -165,10 +155,6 @@ std::string TargetBrowserPair::targetNodeId() const {
return _targetNode->identifier();
}
float TargetBrowserPair::browserRatio() const {
return _browser->browserRatio();
}
double TargetBrowserPair::verticalFov() const {
return _browser->verticalFov();
}
@@ -190,7 +176,7 @@ ghoul::Dictionary TargetBrowserPair::dataAsDictionary() const {
res.setValue("roll", targetRoll());
res.setValue("color", borderColor());
res.setValue("cartesianDirection", cartesian);
res.setValue("ratio", static_cast<double>(browserRatio()));
res.setValue("ratio", static_cast<double>(_browser->browserRatio()));
res.setValue("isFacingCamera", isFacingCamera());
res.setValue("isUsingRae", isUsingRadiusAzimuthElevation());
res.setValue("selectedImages", selectedImages());
@@ -248,19 +234,10 @@ void TargetBrowserPair::hideChromeInterface() {
void TargetBrowserPair::sendIdToBrowser() const {
_browser->setIdInBrowser();
}
void TargetBrowserPair::updateBrowserSize() {
_browser->updateBrowserSize();
}
std::vector<std::pair<std::string, glm::dvec3>> TargetBrowserPair::displayCopies() const {
return _browser->displayCopies();
}
bool TargetBrowserPair::isImageCollectionLoaded() {
return _browser->isImageCollectionLoaded();
}
void TargetBrowserPair::setVerticalFov(double vfov) {
_browser->setVerticalFov(vfov);
_targetRenderable->setVerticalFov(vfov);
@@ -268,6 +245,7 @@ void TargetBrowserPair::setVerticalFov(double vfov) {
void TargetBrowserPair::setEquatorialAim(const glm::dvec2& aim) {
aimTargetGalactic(
_targetNode->identifier(),
skybrowser::equatorialToGalactic(skybrowser::sphericalToCartesian(aim))
);
_browser->setEquatorialAim(aim);
@@ -294,16 +272,16 @@ void TargetBrowserPair::setImageCollectionIsLoaded(bool isLoaded) {
void TargetBrowserPair::incrementallyAnimateToCoordinate() {
// Animate the target before the field of view starts to animate
if (_targetAnimation.isAnimating()) {
aimTargetGalactic(_targetAnimation.getNewValue());
aimTargetGalactic(_targetNode->identifier(), _targetAnimation.newValue());
}
else if (!_targetAnimation.isAnimating() && _targetIsAnimating) {
// Set the finished position
aimTargetGalactic(_targetAnimation.getNewValue());
aimTargetGalactic(_targetNode->identifier(), _targetAnimation.newValue());
_fovAnimation.start();
_targetIsAnimating = false;
}
if (_fovAnimation.isAnimating()) {
_browser->setVerticalFov(_fovAnimation.getNewValue());
_browser->setVerticalFov(_fovAnimation.newValue());
_targetRenderable->setVerticalFov(_browser->verticalFov());
}
}
@@ -377,20 +355,8 @@ bool TargetBrowserPair::isUsingRadiusAzimuthElevation() const {
return _browser->isUsingRaeCoords();
}
SceneGraphNode* TargetBrowserPair::targetNode() const {
return _targetNode;
}
ScreenSpaceSkyBrowser* TargetBrowserPair::browser() const {
return _browser;
}
bool operator==(const TargetBrowserPair& lhs, const TargetBrowserPair& rhs) {
return lhs._targetNode == rhs._targetNode && lhs._browser == rhs._browser;
}
bool operator!=(const TargetBrowserPair& lhs, const TargetBrowserPair& rhs) {
return !(lhs == rhs);
}
} // namespace openspace
+35 -32
View File
@@ -32,6 +32,20 @@
#include <glm/gtx/vector_angle.hpp>
#include <cmath>
namespace {
// Galactic coordinates are projected onto the celestial sphere
// Equatorial coordinates are unit length
// Conversion spherical <-> Cartesian
// Conversion matrix - J2000 equatorial <-> galactic
// https://arxiv.org/abs/1010.3773v1
constexpr glm::dmat3 ConversionMatrix = glm::dmat3(
-0.054875539390, 0.494109453633, -0.867666135681, // col 0
-0.873437104725, -0.444829594298, -0.198076389622, // col 1
-0.483834991775, 0.746982248696, 0.455983794523 // col 2
);
} // namespace
namespace openspace::skybrowser {
// Converts from spherical coordinates in the unit of degrees to cartesian coordianates
@@ -53,26 +67,26 @@ glm::dvec2 cartesianToSpherical(const glm::dvec3& coord) {
double ra = atan2(coord.y, coord.x);
double dec = atan2(coord.z, glm::sqrt((coord.x * coord.x) + (coord.y * coord.y)));
ra = ra > 0 ? ra : ra + glm::two_pi<double>();
ra = ra > 0.0 ? ra : ra + glm::two_pi<double>();
glm::dvec2 celestialCoords = glm::dvec2(ra, dec);
return glm::degrees(celestialCoords);
}
glm::dvec3 galacticToEquatorial(const glm::dvec3& coords) {
return glm::transpose(conversionMatrix) * glm::normalize(coords);
return glm::transpose(ConversionMatrix) * glm::normalize(coords);
}
glm::dvec3 equatorialToGalactic(const glm::dvec3& coords) {
// On the unit sphere
glm::dvec3 rGalactic = conversionMatrix * glm::normalize(coords);
glm::dvec3 rGalactic = ConversionMatrix * glm::normalize(coords);
return rGalactic;
}
glm::dvec3 localCameraToScreenSpace3d(const glm::dvec3& coords) {
// Ensure that if the coord is behind the camera,
// the converted coordinate will be there too
double zCoord = coords.z > 0 ? -ScreenSpaceZ : ScreenSpaceZ;
double zCoord = coords.z > 0.0 ? -ScreenSpaceZ : ScreenSpaceZ;
// Calculate screen space coords x and y
double tanX = coords.x / coords.z;
@@ -91,15 +105,15 @@ glm::dvec3 localCameraToGalactic(const glm::dvec3& coords) {
// Subtract camera position to get the view direction
glm::dvec3 galactic = glm::dvec3(camMat * coordsVec4) - camPos;
return glm::normalize(galactic) * skybrowser::CelestialSphereRadius;
return glm::normalize(galactic) * CelestialSphereRadius;
}
glm::dvec3 localCameraToEquatorial(const glm::dvec3& coords) {
// Calculate the galactic coordinate of the target direction
// projected onto the celestial sphere
glm::dvec3 camPos = global::navigationHandler->camera()->positionVec3();
glm::dvec3 galactic = camPos + skybrowser::localCameraToGalactic(coords);
return skybrowser::galacticToEquatorial(galactic);
glm::dvec3 galactic = camPos + localCameraToGalactic(coords);
return galacticToEquatorial(galactic);
}
glm::dvec3 equatorialToLocalCamera(const glm::dvec3& coords) {
@@ -117,8 +131,10 @@ glm::dvec3 galacticToLocalCamera(const glm::dvec3& coords) {
}
double targetRoll(const glm::dvec3& up, const glm::dvec3& forward) {
glm::dvec3 upJ2000 = skybrowser::galacticToEquatorial(up);
glm::dvec3 forwardJ2000 = skybrowser::galacticToEquatorial(forward);
constexpr glm::dvec3 NorthPole = glm::dvec3(0.0, 0.0, 1.0);
glm::dvec3 upJ2000 = galacticToEquatorial(up);
glm::dvec3 forwardJ2000 = galacticToEquatorial(forward);
glm::dvec3 crossUpNorth = glm::cross(upJ2000, NorthPole);
double dotNorthUp = glm::dot(NorthPole, upJ2000);
@@ -129,14 +145,15 @@ double targetRoll(const glm::dvec3& up, const glm::dvec3& forward) {
glm::dvec3 cameraDirectionEquatorial() {
// Get the view direction of the screen in cartesian J2000 coordinates
return galacticToEquatorial(cameraDirectionGalactic());
glm::dvec3 camDirGalactic = cameraDirectionGalactic();
return galacticToEquatorial(camDirGalactic);
}
glm::dvec3 cameraDirectionGalactic() {
// Get the view direction of the screen in galactic coordinates
glm::dvec3 camPos = global::navigationHandler->camera()->positionVec3();
glm::dvec3 view = global::navigationHandler->camera()->viewDirectionWorldSpace();
glm::dvec3 galCoord = camPos + (skybrowser::CelestialSphereRadius * view);
glm::dvec3 galCoord = camPos + CelestialSphereRadius * view;
return galCoord;
}
@@ -150,11 +167,10 @@ bool isCoordinateInView(const glm::dvec3& equatorial) {
// Check if image coordinate is within current FOV
glm::dvec3 localCamera = equatorialToLocalCamera(equatorial);
glm::dvec3 coordsScreen = localCameraToScreenSpace3d(localCamera);
double r = static_cast<float>(windowRatio());
bool isCoordInView = abs(coordsScreen.x) < r && abs(coordsScreen.y) < 1.f &&
coordsScreen.z < 0;
double r = windowRatio();
bool isCoordInView =
abs(coordsScreen.x) < r && abs(coordsScreen.y) < 1.f && coordsScreen.z < 0.f;
return isCoordInView;
}
@@ -200,31 +216,18 @@ glm::dmat4 incrementalAnimationMatrix(const glm::dvec3& start, const glm::dvec3&
}
double sizeFromFov(double fov, glm::dvec3 worldPosition) {
// Calculate the size with trigonometry
// /|
// /_| Adjacent is the horizontal line, opposite the vertical
// \ | Calculate for half the triangle first, then multiply with 2
// \|
double adjacent = glm::length(worldPosition);
double opposite = 2 * adjacent * glm::tan(glm::radians(fov * 0.5));
double opposite = 2.0 * adjacent * glm::tan(glm::radians(fov * 0.5));
return opposite;
}
template <>
float Animation<float>::getNewValue() {
if (!isAnimating()) {
return _goal;
}
else {
float percentage = static_cast<float>(percentageSpent());
float diff = static_cast<float>((_goal - _start) * ghoul::exponentialEaseOut(percentage));
return _start + diff;
}
}
template <>
double Animation<double>::getNewValue() {
double Animation<double>::newValue() const {
if (!isAnimating()) {
return _goal;
}
@@ -236,7 +239,7 @@ double Animation<double>::getNewValue() {
}
template <>
glm::dmat4 Animation<glm::dvec3>::getRotationMatrix() {
glm::dmat4 Animation<glm::dvec3>::rotationMatrix() {
if (!isAnimating()) {
return glm::dmat4(1.0);
}
@@ -254,7 +257,7 @@ glm::dmat4 Animation<glm::dvec3>::getRotationMatrix() {
}
template <>
glm::dvec3 Animation<glm::dvec3>::getNewValue() {
glm::dvec3 Animation<glm::dvec3>::newValue() const {
if (!isAnimating()) {
return _goal;
}
+136 -135
View File
@@ -32,6 +32,90 @@
namespace {
constexpr std::string_view _loggerCat = "WwtCommunicator";
// WWT messages
ghoul::Dictionary moveCameraMessage(const glm::dvec2& celestCoords, double fov,
double roll)
{
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "center_on_coordinates"s);
msg.setValue("ra", celestCoords.x);
msg.setValue("dec", celestCoords.y);
msg.setValue("fov", fov);
msg.setValue("roll", roll);
msg.setValue("instant", true);
return msg;
}
ghoul::Dictionary loadCollectionMessage(const std::string& url) {
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "load_image_collection"s);
msg.setValue("url", url);
msg.setValue("loadChildFolders", true);
return msg;
}
ghoul::Dictionary setForegroundMessage(const std::string& name) {
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "set_foreground_by_name"s);
msg.setValue("name", name);
return msg;
}
ghoul::Dictionary addImageMessage(const std::string& id, const std::string& url) {
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "image_layer_create"s);
msg.setValue("id", id);
msg.setValue("url", url);
msg.setValue("mode", "preloaded"s);
msg.setValue("goto", false);
return msg;
}
ghoul::Dictionary removeImageMessage(const std::string& imageId) {
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "image_layer_remove"s);
msg.setValue("id", imageId);
return msg;
}
ghoul::Dictionary setImageOpacityMessage(const std::string& imageId, double opacity) {
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "image_layer_set"s);
msg.setValue("id", imageId);
msg.setValue("setting", "opacity"s);
msg.setValue("value", opacity);
return msg;
}
ghoul::Dictionary setLayerOrderMessage(const std::string& id, int order) {
static int MessageCounter = 0;
// The lower the layer order, the more towards the back the image is placed
// 0 is the background
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "image_layer_order"s);
msg.setValue("id", id);
msg.setValue("order", order);
msg.setValue("version", MessageCounter);
MessageCounter++;
return msg;
}
} // namespace
namespace openspace {
@@ -40,7 +124,27 @@ WwtCommunicator::WwtCommunicator(const ghoul::Dictionary& dictionary)
: Browser(dictionary)
{}
WwtCommunicator::~WwtCommunicator() {}
void WwtCommunicator::update() {
// Cap how messages are passed
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
std::chrono::system_clock::duration timeSinceLastUpdate = now - _lastUpdateTime;
if (timeSinceLastUpdate > TimeUpdateInterval) {
if (_equatorialAimIsDirty) {
updateAim();
_equatorialAimIsDirty = false;
}
if (_borderColorIsDirty) {
updateBorderColor();
_borderColorIsDirty = false;
}
_lastUpdateTime = std::chrono::system_clock::now();
}
if (_shouldReload) {
_isImageCollectionLoaded = false;
}
Browser::update();
}
void WwtCommunicator::selectImage(const std::string& url, int i) {
// Ensure there are no duplicates
@@ -66,7 +170,6 @@ void WwtCommunicator::addImageLayerToWwt(const std::string& url, int i) {
void WwtCommunicator::removeSelectedImage(int i) {
// Remove from selected list
auto it = findSelectedImage(i);
if (it != _selectedImages.end()) {
_selectedImages.erase(it);
sendMessageToWwt(removeImageMessage(std::to_string(i)));
@@ -74,23 +177,31 @@ void WwtCommunicator::removeSelectedImage(int i) {
}
void WwtCommunicator::sendMessageToWwt(const ghoul::Dictionary& msg) const {
std::string script = "sendMessageToWWT(" + ghoul::formatJson(msg) + ");";
executeJavascript(script);
std::string m = ghoul::formatJson(msg);
executeJavascript(fmt::format("sendMessageToWWT({});", m));
}
std::vector<int> WwtCommunicator::selectedImages() const {
std::vector<int> selectedImagesVector;
for (const std::pair<int, double>& image : _selectedImages) {
selectedImagesVector.push_back(image.first);
}
selectedImagesVector.resize(_selectedImages.size());
std::transform(
_selectedImages.cbegin(),
_selectedImages.cend(),
selectedImagesVector.begin(),
[](const std::pair<int, double>& image) { return image.first; }
);
return selectedImagesVector;
}
std::vector<double> WwtCommunicator::opacities() const {
std::vector<double> opacities;
for (const std::pair<int, double>& image : _selectedImages) {
opacities.push_back(image.second);
}
opacities.resize(_selectedImages.size());
std::transform(
_selectedImages.cbegin(),
_selectedImages.cend(),
opacities.begin(),
[](const std::pair<int, double>& image) { return image.second; }
);
return opacities;
}
@@ -103,12 +214,6 @@ void WwtCommunicator::setVerticalFov(double vfov) {
_equatorialAimIsDirty = true;
}
void WwtCommunicator::setWebpageBorderColor(glm::ivec3 color) const {
std::string stringColor = fmt::format("{},{},{}", color.x, color.y, color.z);
std::string scr = "document.body.style.backgroundColor = 'rgb(" + stringColor + ")';";
executeJavascript(scr);
}
void WwtCommunicator::setEquatorialAim(glm::dvec2 equatorial) {
_equatorialAim = std::move(equatorial);
_equatorialAimIsDirty = true;
@@ -120,7 +225,11 @@ void WwtCommunicator::setBorderColor(glm::ivec3 color) {
}
void WwtCommunicator::updateBorderColor() const {
setWebpageBorderColor(_borderColor);
std::string script = fmt::format(
"document.body.style.backgroundColor = 'rgb({},{},{})';",
_borderColor.x, _borderColor.y, _borderColor.z
);
executeJavascript(script);
}
void WwtCommunicator::updateAim() const {
@@ -130,8 +239,9 @@ void WwtCommunicator::updateAim() const {
}
glm::dvec2 WwtCommunicator::fieldsOfView() const {
glm::dvec2 browserFov = glm::dvec2(verticalFov() * browserRatio(), verticalFov());
return browserFov;
const double vFov = verticalFov();
const double hFov = vFov * browserRatio();
return glm::dvec2(hFov, vFov);
}
bool WwtCommunicator::isImageCollectionLoaded() const {
@@ -139,10 +249,11 @@ bool WwtCommunicator::isImageCollectionLoaded() const {
}
std::deque<std::pair<int, double>>::iterator WwtCommunicator::findSelectedImage(int i) {
auto it = std::find_if(_selectedImages.begin(), _selectedImages.end(),
[i](std::pair<int, double>& pair) {
return (pair.first == i);
});
auto it = std::find_if(
_selectedImages.begin(),
_selectedImages.end(),
[i](const std::pair<int, double>& pair) { return pair.first == i; }
);
return it;
}
@@ -186,35 +297,13 @@ void WwtCommunicator::hideChromeInterface() const {
executeJavascript(script);
}
void WwtCommunicator::update() {
// Cap how messages are passed
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
std::chrono::system_clock::duration timeSinceLastUpdate = now - _lastUpdateTime;
if (timeSinceLastUpdate > TimeUpdateInterval) {
if (_equatorialAimIsDirty) {
updateAim();
_equatorialAimIsDirty = false;
}
if (_borderColorIsDirty) {
updateBorderColor();
_borderColorIsDirty = false;
}
_lastUpdateTime = std::chrono::system_clock::now();
}
if (_shouldReload) {
_isImageCollectionLoaded = false;
}
Browser::update();
}
void WwtCommunicator::setImageCollectionIsLoaded(bool isLoaded) {
_isImageCollectionLoaded = isLoaded;
}
void WwtCommunicator::setIdInBrowser(const std::string& id) const {
// Send ID to it's browser
executeJavascript("setId('" + id + "')");
// Send ID to its browser
executeJavascript(fmt::format("setId('{}')", id));
}
glm::ivec3 WwtCommunicator::borderColor() const {
@@ -225,92 +314,4 @@ double WwtCommunicator::verticalFov() const {
return _verticalFov;
}
// WWT messages
ghoul::Dictionary WwtCommunicator::moveCameraMessage(const glm::dvec2& celestCoords,
double fov, double roll,
bool shouldMoveInstantly) const
{
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "center_on_coordinates"s);
msg.setValue("ra", celestCoords.x);
msg.setValue("dec", celestCoords.y);
msg.setValue("fov", fov);
msg.setValue("roll", roll);
msg.setValue("instant", shouldMoveInstantly);
return msg;
}
ghoul::Dictionary WwtCommunicator::loadCollectionMessage(const std::string& url) const {
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "load_image_collection"s);
msg.setValue("url", url);
msg.setValue("loadChildFolders", true);
return msg;
}
ghoul::Dictionary WwtCommunicator::setForegroundMessage(const std::string& name) const {
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "set_foreground_by_name"s);
msg.setValue("name", name);
return msg;
}
ghoul::Dictionary WwtCommunicator::addImageMessage(const std::string& id,
const std::string& url) const
{
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "image_layer_create"s);
msg.setValue("id", id);
msg.setValue("url", url);
msg.setValue("mode", "preloaded"s);
msg.setValue("goto", false);
return msg;
}
ghoul::Dictionary WwtCommunicator::removeImageMessage(const std::string& imageId) const {
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "image_layer_remove"s);
msg.setValue("id", imageId);
return msg;
}
ghoul::Dictionary WwtCommunicator::setImageOpacityMessage(const std::string& imageId,
double opacity) const
{
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "image_layer_set"s);
msg.setValue("id", imageId);
msg.setValue("setting", "opacity"s);
msg.setValue("value", opacity);
return msg;
}
ghoul::Dictionary WwtCommunicator::setLayerOrderMessage(const std::string& id, int order)
{
// The lower the layer order, the more towards the back the image is placed
// 0 is the background
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "image_layer_order"s);
msg.setValue("id", id);
msg.setValue("order", order);
msg.setValue("version", messageCounter);
messageCounter++;
return msg;
}
} // namespace openspace
+303 -293
View File
@@ -25,239 +25,316 @@
#include <modules/skybrowser/include/wwtdatahandler.h>
#include <modules/skybrowser/include/utility.h>
#include <modules/space/speckloader.h>
#include <openspace/util/httprequest.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/logging/logmanager.h>
#include <algorithm>
#include <filesystem>
#include <sys/types.h>
#include <sys/stat.h>
#include <string_view>
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsuggest-override"
#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
#endif
#include <modules/skybrowser/ext/tinyxml2/tinyxml2.h>
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
#endif
namespace {
constexpr std::string_view _loggerCat = "WwtDataHandler";
constexpr std::string_view Thumbnail = "Thumbnail";
constexpr std::string_view Name = "Name";
constexpr std::string_view ImageSet = "ImageSet";
constexpr std::string_view Dec = "Dec";
constexpr std::string_view RA = "RA";
constexpr std::string_view Undefined = "";
constexpr std::string_view Folder = "Folder";
constexpr std::string_view Place = "Place";
constexpr std::string_view ThumbnailUrl = "ThumbnailUrl";
constexpr std::string_view Url = "Url";
constexpr std::string_view Credits = "Credits";
constexpr std::string_view CreditsUrl = "CreditsUrl";
constexpr std::string_view ZoomLevel = "ZoomLevel";
constexpr std::string_view DataSetType = "DataSetType";
constexpr std::string_view Sky = "Sky";
bool hasAttribute(const tinyxml2::XMLElement* element, std::string_view name) {
std::string n = std::string(name);
return element->FindAttribute(n.c_str());
}
std::string attribute(const tinyxml2::XMLElement* element, std::string_view name) {
if (hasAttribute(element, name)) {
std::string n = std::string(name);
return element->FindAttribute(n.c_str())->Value();
}
return std::string(Undefined);
}
// Parsing and downloading of wtml files
bool downloadFile(const std::string& url, const std::filesystem::path& destination) {
using namespace openspace;
HttpFileDownload wtmlRoot(url, destination, HttpFileDownload::Overwrite::Yes);
wtmlRoot.start(std::chrono::milliseconds(10000));
return wtmlRoot.wait();
}
bool directoryExists(const std::filesystem::path& path) {
return std::filesystem::exists(path) && std::filesystem::is_directory(path);
}
const tinyxml2::XMLElement* directChildNode(const tinyxml2::XMLElement* node,
std::string_view name)
{
while (node && node->Name() != name) {
node = node->FirstChildElement();
}
return node;
}
const tinyxml2::XMLElement* childNode(const tinyxml2::XMLElement* node,
std::string_view name)
{
const tinyxml2::XMLElement* child = node->FirstChildElement();
// Traverse the children and look at all their first child to find ImageSet
while (child) {
const tinyxml2::XMLElement* imageSet = directChildNode(child, name);
if (imageSet) {
return imageSet;
}
child = child->NextSiblingElement();
}
return nullptr;
}
std::string childNodeContentFromImageSet(const tinyxml2::XMLElement* imageSet,
std::string_view elementName)
{
// Find the thumbnail image url
// The thumbnail is the last node so traverse backwards for speed
std::string n = std::string(elementName);
const tinyxml2::XMLElement* child = imageSet->FirstChildElement(n.c_str());
return child && child->GetText() ? child->GetText() : std::string(Undefined);
}
std::string urlFromPlace(const tinyxml2::XMLElement* place) {
// If the place has a thumbnail url, return it
if (hasAttribute(place, Thumbnail)) {
return attribute(place, Thumbnail);
}
// If the place doesn't have a thumbnail url data attribute,
// Load the image set it stores instead
const tinyxml2::XMLElement* imageSet = childNode(place, ImageSet);
// If there is an imageSet, collect thumbnail url, if it doesn't contain an
// ImageSet, it doesn't have an url
return imageSet ?
childNodeContentFromImageSet(imageSet, ThumbnailUrl) :
std::string(Undefined);
}
bool downloadWtmlFiles(const std::filesystem::path& directory, const std::string& url,
const std::string& fileName)
{
using namespace openspace;
// Download file from url
std::filesystem::path file = directory.string() + fileName + ".aspx";
const bool success = downloadFile(url, file);
if (!success) {
LINFO(fmt::format(
"Could not download file '{}' to directory {}", url, directory
));
return false;
}
// Parse file to XML
auto document = std::make_unique<tinyxml2::XMLDocument>();
document->LoadFile(file.string().c_str());
// Search XML file for folders with urls
const tinyxml2::XMLElement* root = document->RootElement();
const tinyxml2::XMLElement* element = root->FirstChildElement(Folder.data());
const bool folderExists = element != nullptr;
const bool folderContainNoUrls = folderExists && !hasAttribute(element, Url);
// If the file contains no folders, or there are folders but without urls,
// stop recursion
if (!folderExists || folderContainNoUrls) {
LINFO(fmt::format("Saving {}", url));
return true;
}
// Iterate through all the folders in the XML file
while (element && std::string(element->Value()) == Folder) {
// If folder contains urls, download and parse those urls
if (hasAttribute(element, Url) && hasAttribute(element, Name)) {
std::string urlAttr = attribute(element, Url);
std::string fileNameAttr = attribute(element, Name);
downloadWtmlFiles(directory, urlAttr, fileNameAttr);
}
element = element->NextSiblingElement();
}
return true;
}
std::optional<openspace::ImageData> loadImageFromNode(
const tinyxml2::XMLElement* node,
std::string collection)
{
using namespace openspace;
// Collect the image set of the node. The structure is different depending on if
// it is a Place or an ImageSet
std::string thumbnailUrl = std::string(Undefined);
const tinyxml2::XMLElement* imageSet = nullptr;
std::string type = node->Name();
if (type == ImageSet) {
thumbnailUrl = childNodeContentFromImageSet(node, ThumbnailUrl);
imageSet = node;
}
else if (type == Place) {
thumbnailUrl = urlFromPlace(node);
imageSet = childNode(node, ImageSet);
}
// Only collect the images that have a thumbnail image, that are sky images and
// that have an image
const bool hasThumbnailUrl = thumbnailUrl != Undefined;
const bool isSkyImage = attribute(node, DataSetType) == Sky;
const bool hasImageUrl = imageSet ? hasAttribute(imageSet, Url) : false;
if (!(hasThumbnailUrl && isSkyImage && hasImageUrl)) {
return std::nullopt;
}
// Collect name, image url and credits
std::string name = attribute(node, Name);
if (std::islower(name[0])) {
// convert string to upper case
name[0] = static_cast<char>(std::toupper(name[0]));
}
std::string imageUrl = attribute(imageSet, Url);
std::string credits = childNodeContentFromImageSet(imageSet, Credits);
std::string creditsUrl = childNodeContentFromImageSet(imageSet, CreditsUrl);
// Collect equatorial coordinates. All-sky surveys do not have these coordinates
bool hasCelestialCoords = hasAttribute(node, RA) && hasAttribute(node, Dec);
glm::dvec2 equatorialSpherical = glm::dvec2(0.0);
glm::dvec3 equatorialCartesian = glm::dvec3(0.0);
if (hasCelestialCoords) {
// The RA from WWT is in the unit hours:
// to convert to degrees, multiply with 360 (deg) /24 (h) = 15
double ra = 15.0 * std::stod(attribute(node, RA));
double dec = std::stod(attribute(node, Dec));
equatorialSpherical = glm::dvec2(ra, dec);
equatorialCartesian = skybrowser::sphericalToCartesian(equatorialSpherical);
}
// Collect field of view. The WWT definition of ZoomLevel is: VFOV = ZoomLevel / 6
float fov = 0.f;
if (hasAttribute(node, ZoomLevel)) {
fov = std::stof(attribute(node, ZoomLevel)) / 6.f;
}
return ImageData{
name,
thumbnailUrl,
imageUrl,
credits,
creditsUrl,
collection,
hasCelestialCoords,
fov,
equatorialSpherical,
equatorialCartesian
};
}
} //namespace
namespace openspace {
bool hasAttribute(const tinyxml2::XMLElement* element, const std::string_view& name) {
return element->FindAttribute(std::string(name).c_str());
}
std::string attribute(const tinyxml2::XMLElement* element, const std::string& name) {
if (hasAttribute(element, name)) {
return element->FindAttribute(name.c_str())->Value();
}
return wwt::Undefined;
}
// Parsing and downloading of wtml files
bool downloadFile(const std::string& url, const std::filesystem::path& fileDestination) {
// Get the web page and save to file
HttpFileDownload wtmlRoot(
url,
fileDestination,
HttpFileDownload::Overwrite::Yes
);
wtmlRoot.start(std::chrono::milliseconds(10000));
return wtmlRoot.wait();
}
bool directoryExists(const std::filesystem::path& path) {
return std::filesystem::exists(path) && std::filesystem::is_directory(path);
}
std::string createSearchableString(std::string str) {
// Remove white spaces and all special characters
str.erase(
std::remove_if(
str.begin(), str.end(),
[](char c) {
const bool isNumberOrLetter = std::isdigit(c) || std::isalpha(c);
return !isNumberOrLetter;
}
),
str.end()
);
// Make the word lower case
std::transform(
str.begin(), str.end(),
str.begin(),
[](char c) { return static_cast<char>(std::tolower(c)); }
);
return str;
}
tinyxml2::XMLElement* getDirectChildNode(tinyxml2::XMLElement* node,
const std::string& name)
{
while (node && node->Name() != name) {
node = node->FirstChildElement();
}
return node;
}
tinyxml2::XMLElement* getChildNode(tinyxml2::XMLElement* node,
const std::string& name)
{
tinyxml2::XMLElement* child = node->FirstChildElement();
// Traverse the children and look at all their first child to find ImageSet
while (child) {
tinyxml2::XMLElement* imageSet = getDirectChildNode(child, name);
// Found
if (imageSet) {
return imageSet;
}
child = child->NextSiblingElement();
}
return nullptr;
}
std::string getChildNodeContentFromImageSet(tinyxml2::XMLElement* imageSet,
const std::string& elementName)
{
// Find the thumbnail image url
// The thumbnail is the last node so traverse backwards for speed
tinyxml2::XMLElement* imageSetChild =
imageSet->FirstChildElement(elementName.c_str());
if (imageSetChild && imageSetChild->GetText()) {
return imageSetChild->GetText();
}
else {
return wwt::Undefined;
}
}
std::string getUrlFromPlace(tinyxml2::XMLElement* place) {
// If the place has a thumbnail url, return it
if (hasAttribute(place, wwt::Thumbnail)) {
return attribute(place, wwt::Thumbnail);
}
// If the place doesn't have a thumbnail url data attribute,
// Load the image set it stores instead
tinyxml2::XMLElement* imageSet = getChildNode(place, wwt::ImageSet);
// If there is an imageSet, collect thumbnail url
if (imageSet) {
return getChildNodeContentFromImageSet(imageSet, wwt::ThumbnailUrl);
}
else {
// If it doesn't contain an ImageSet, it doesn't have an url
return wwt::Undefined;
}
}
void parseWtmlsFromDisc(std::vector<tinyxml2::XMLDocument*>& xmls,
const std::filesystem::path& directory)
{
for (const auto& entry : std::filesystem::directory_iterator(directory)) {
tinyxml2::XMLDocument* document = new tinyxml2::XMLDocument();
std::string path = entry.path().string();
tinyxml2::XMLError successCode = document->LoadFile(path.c_str());
if (successCode == tinyxml2::XMLError::XML_SUCCESS) {
xmls.push_back(document);
}
}
}
bool downloadAndParseWtmlFilesFromUrl(std::vector<tinyxml2::XMLDocument*>& xmls,
const std::filesystem::path& directory,
const std::string& url, const std::string& fileName)
{
// Look for WWT image data folder, create folder if it doesn't exist
if (!directoryExists(directory)) {
std::string newDir = directory.string();
// Remove the '/' at the end
newDir.pop_back();
LINFO("Creating directory" + newDir);
std::filesystem::create_directory(newDir);
}
// Download file from url
std::filesystem::path file = directory.string() + fileName + ".aspx";
if (!downloadFile(url, file)) {
LINFO(
fmt::format("Couldn't download file '{}' to directory '{}'", url, directory)
);
return false;
}
// Parse file to XML
using namespace tinyxml2;
tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument();
doc->LoadFile(file.string().c_str());
// Search XML file for folders with urls
XMLElement* root = doc->RootElement();
XMLElement* element = root->FirstChildElement(wwt::Folder.c_str());
const bool folderExists = element;
const bool folderContainNoUrls = folderExists && !hasAttribute(element, wwt::Url);
// If the file contains no folders, or there are folders but without urls,
// stop recursion
if (!folderExists || folderContainNoUrls) {
xmls.push_back(doc);
LINFO("Saving " + url);
return true;
}
// Iterate through all the folders in the XML file
while (element && std::string(element->Value()) == wwt::Folder) {
// If folder contains urls, download and parse those urls
if (hasAttribute(element, wwt::Url) && hasAttribute(element, wwt::Name)) {
std::string urlAttr = attribute(element, wwt::Url);
std::string fileNameAttr = attribute(element, wwt::Name);
downloadAndParseWtmlFilesFromUrl(xmls, directory, urlAttr, fileNameAttr);
}
element = element->NextSiblingElement();
}
return true;
}
WwtDataHandler::~WwtDataHandler() {
// Call destructor of all allocated xmls
_xmls.clear();
}
void WwtDataHandler::loadImages(const std::string& root,
const std::filesystem::path& directory)
{
// Collect the wtml files, either by reading from disc or from a url
if (directoryExists(directory) && !std::filesystem::is_empty(directory)) {
parseWtmlsFromDisc(_xmls, directory);
LINFO("Loading images from directory");
}
else {
downloadAndParseWtmlFilesFromUrl(_xmls, directory, root, "root");
LINFO("Loading images from url");
// Steps to download new images
// 1. Create the target directory if it doesn't already exist
// 2. If the 'root' has an associated hash file, download and compare it with the
// local file. If the hash has changed, nuke the folder
// 3. If the folder is empty, download files
// 1.
if (!directoryExists(directory)) {
LINFO(fmt::format("Creating directory {}", directory));
std::filesystem::create_directory(directory);
}
// Traverse through the collected wtml documents and collect the images
for (tinyxml2::XMLDocument* doc : _xmls) {
tinyxml2::XMLElement* rootNode = doc->FirstChildElement();
std::string collectionName = attribute(rootNode, wwt::Name);
saveImagesFromXml(rootNode, collectionName);
// Get the hash from the remote. If no such hash exists, the remoteHash will be empty
std::string remoteHash;
{
std::string remoteHashFile = root.substr(0, root.find_last_of('/')) + "/hash.md5";
bool success = downloadFile(remoteHashFile, directory / "hash.tmp");
// The hash download might fail if the provided 'root' does not have a hash
// in which case we assume that the underlying data has not changed
if (success) {
std::ifstream(directory / "hash.tmp") >> remoteHash;
std::filesystem::remove(directory / "hash.tmp");
}
}
// Load the local hash. If no such hash exists, the localHash will be empty
std::string localHash;
std::filesystem::path localHashFile = directory / "hash.md5";
if (std::filesystem::exists(localHashFile)) {
std::ifstream(localHashFile) >> localHash;
}
// Check if the hash has changed. This will be ignored if either the local of remote
// hash does not exist
if (!localHash.empty() && !remoteHash.empty() && localHash != remoteHash) {
LINFO(fmt::format(
"Local hash '{}' differs from remote hash '{}'. Cleaning directory",
localHash, remoteHash
));
std::filesystem::remove_all(directory);
std::filesystem::create_directory(directory);
}
// If there is no directory (either because it is the first start, or the previous
// contents were deleted because of a change in hash) we have to download the files
if (std::filesystem::is_empty(directory)) {
LINFO("Loading images from url");
downloadWtmlFiles(directory, root, "root");
std::ofstream(localHashFile) << remoteHash;
}
// Finally, we can load the files that are now on disk
LINFO("Loading images from directory");
for (const auto& entry : std::filesystem::directory_iterator(directory)) {
tinyxml2::XMLDocument document;
std::string path = entry.path().string();
tinyxml2::XMLError successCode = document.LoadFile(path.c_str());
if (successCode == tinyxml2::XMLError::XML_SUCCESS) {
tinyxml2::XMLElement* rootNode = document.FirstChildElement();
std::string collectionName = attribute(rootNode, Name);
saveImagesFromXml(rootNode, collectionName);
}
}
// Sort images in alphabetical order
std::sort(
_images.begin(),
_images.end(),
[](ImageData& a, ImageData& b) {
// If the first character in the names are lowercase, make it upper case
if (std::islower(a.name[0])) {
// convert string to upper case
a.name[0] = static_cast<char>(::toupper(a.name[0]));
}
if (std::islower(b.name[0])) {
b.name[0] = static_cast<char>(::toupper(b.name[0]));
}
return a.name < b.name;
}
[](ImageData& a, ImageData& b) { return a.name < b.name; }
);
LINFO(fmt::format("Loaded {} WorldWide Telescope images", _images.size()));
@@ -267,100 +344,33 @@ int WwtDataHandler::nLoadedImages() const {
return static_cast<int>(_images.size());
}
const ImageData& WwtDataHandler::getImage(int i) const {
const ImageData& WwtDataHandler::image(int i) const {
ghoul_assert(i < static_cast<int>(_images.size()), "Index outside of vector size");
return _images[i];
}
void WwtDataHandler::saveImageFromNode(tinyxml2::XMLElement* node, std::string collection)
{
// Collect the image set of the node. The structure is different depending on if
// it is a Place or an ImageSet
std::string thumbnailUrl = wwt::Undefined;
tinyxml2::XMLElement* imageSet = nullptr;
std::string type = std::string(node->Name());
if (type == wwt::ImageSet) {
thumbnailUrl = getChildNodeContentFromImageSet(node, wwt::ThumbnailUrl);
imageSet = node;
}
else if (type == wwt::Place) {
thumbnailUrl = getUrlFromPlace(node);
imageSet = getChildNode(node, wwt::ImageSet);
}
// Only collect the images that have a thumbnail image, that are sky images and
// that have an image
const bool hasThumbnailUrl = thumbnailUrl != wwt::Undefined;
const bool isSkyImage = attribute(node, wwt::DataSetType) == wwt::Sky;
const bool hasImageUrl = imageSet ? hasAttribute(imageSet, wwt::Url) : false;
if (!(hasThumbnailUrl && isSkyImage && hasImageUrl)) {
return;
}
// Collect name, image url and credits
std::string name = attribute(node, wwt::Name);
std::string imageUrl = attribute(imageSet, wwt::Url);
std::string credits = getChildNodeContentFromImageSet(imageSet, wwt::Credits);
std::string creditsUrl = getChildNodeContentFromImageSet(imageSet, wwt::CreditsUrl);
// Collect equatorial coordinates. All-sky surveys do not have this kind of
// coordinate
bool hasCelestialCoords = hasAttribute(node, wwt::RA) && hasAttribute(node, wwt::Dec);
glm::dvec2 equatorialSpherical = glm::dvec2(0.0);
glm::dvec3 equatorialCartesian = glm::vec3(0.0);
if (hasCelestialCoords) {
// The RA from WWT is in the unit hours:
// to convert to degrees, multiply with 360 (deg) /24 (h) = 15
double ra = 15.0 * std::stod(attribute(node, wwt::RA));
double dec = std::stod(attribute(node, wwt::Dec));
equatorialSpherical = glm::dvec2(ra, dec);
equatorialCartesian = skybrowser::sphericalToCartesian(equatorialSpherical);
}
// Collect field of view. The WWT definition of ZoomLevel is: VFOV = ZoomLevel / 6
float fov = 0.f;
if (hasAttribute(node, wwt::ZoomLevel)) {
fov = std::stof(attribute(node, wwt::ZoomLevel)) / 6.0f;
}
ImageData image = {
name,
thumbnailUrl,
imageUrl,
credits,
creditsUrl,
collection,
hasCelestialCoords,
fov,
equatorialSpherical,
equatorialCartesian
};
_images.push_back(image);
}
void WwtDataHandler::saveImagesFromXml(tinyxml2::XMLElement* root, std::string collection)
void WwtDataHandler::saveImagesFromXml(const tinyxml2::XMLElement* root,
std::string collection)
{
// Get direct child of node called Place
using namespace tinyxml2;
XMLElement* node = root->FirstChildElement();
const tinyxml2::XMLElement* node = root->FirstChildElement();
// Iterate through all siblings of node. If sibling is folder, open recursively.
// If sibling is image, save it.
while (node) {
const std::string name = node->Name();
// If node is an image or place, load it
if (name == wwt::ImageSet || name == wwt::Place) {
saveImageFromNode(node, collection);
if (name == ImageSet || name == Place) {
std::optional<ImageData> image = loadImageFromNode(node, collection);
if (image.has_value()) {
_images.push_back(std::move(*image));
}
}
// If node is another folder, open recursively
else if (name == wwt::Folder) {
std::string newCollectionName = collection + "/";
newCollectionName += attribute(node, wwt::Name);
else if (name == Folder) {
std::string nodeName = attribute(node, Name);
std::string newCollectionName = fmt::format("{}/{}", collection, nodeName);
saveImagesFromXml(node, newCollectionName);
}
node = node->NextSiblingElement();
+9
View File
@@ -88,3 +88,12 @@ create_new_module(
STATIC
${HEADER_FILES} ${SOURCE_FILES} ${SHADER_FILES}
)
target_precompile_headers(${space_module} PRIVATE
<openspace/documentation/documentation.h>
<openspace/documentation/verifier.h>
<openspace/properties/numericalproperty.h>
<openspace/rendering/renderable.h>
<ghoul/opengl/programobject.h>
<ghoul/opengl/shaderobject.h>
<ghoul/opengl/uniformcache.h>
)
@@ -91,3 +91,6 @@ create_new_module(
STATIC
${HEADER_FILES} ${SOURCE_FILES} ${SHADER_FILES}
)
target_precompile_headers(${spacecraftinstruments_module} PRIVATE
)
+18 -11
View File
@@ -25,23 +25,30 @@
include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake)
set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/include/state.h
${CMAKE_CURRENT_SOURCE_DIR}/include/transition.h
${CMAKE_CURRENT_SOURCE_DIR}/include/statemachine.h
${CMAKE_CURRENT_SOURCE_DIR}/include/state.h
${CMAKE_CURRENT_SOURCE_DIR}/include/transition.h
${CMAKE_CURRENT_SOURCE_DIR}/include/statemachine.h
)
source_group("Header Files" FILES ${HEADER_FILES})
set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/statemachinemodule_lua.inl
${CMAKE_CURRENT_SOURCE_DIR}/src/state.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/transition.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/statemachine.cpp
${CMAKE_CURRENT_SOURCE_DIR}/statemachinemodule_lua.inl
${CMAKE_CURRENT_SOURCE_DIR}/src/state.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/transition.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/statemachine.cpp
)
source_group("Source Files" FILES ${SOURCE_FILES})
create_new_module(
"StateMachine"
statemachine_module
STATIC
${HEADER_FILES} ${SOURCE_FILES}
"StateMachine"
statemachine_module
STATIC
${HEADER_FILES} ${SOURCE_FILES}
)
target_precompile_headers(${statemachine_module} PRIVATE
<ghoul/glm.h>
<ghoul/lua/ghoul_lua.h>
<chrono>
<filesystem>
<string>
)
@@ -25,6 +25,7 @@
#include <modules/statemachine/include/statemachine.h>
#include <openspace/documentation/documentation.h>
#include <ghoul/fmt.h>
#include <ghoul/logging/logmanager.h>
#include <fstream>
#include <optional>
+17
View File
@@ -76,6 +76,23 @@ target_include_directories(libTUIO11 SYSTEM
"${PROJECT_SOURCE_DIR}/libTUIO11/"
"${PROJECT_SOURCE_DIR}/libTUIO11/oscpack"
)
target_precompile_headers(libTUIO11 PRIVATE
<iostream>
<istream>
<ostream>
<stdexcept>
)
# # [["tuiopoint.h"]]
# # [["tuiocontainer.h"]]
# # [["tuiotime.h"]]
# # [["tuioobject.h"]]
# # [["tuiodispatcher.h"]]
# # [["tuiolistener.h"]]
# # [["tuioclient.h"]]
# # [["oscreceiver.h"]]
# <stdexcept>
# <math.h>
# )
if (WIN32)
# Tuio dependencies
-7
View File
@@ -28,16 +28,9 @@
#include <modules/touch/include/win32_touch.h>
#include <openspace/engine/globals.h>
#include <openspace/engine/globalscallbacks.h>
#include <openspace/engine/moduleengine.h>
#include <openspace/engine/windowdelegate.h>
#include <openspace/interaction/interactionmonitor.h>
#include <openspace/navigation/navigationhandler.h>
#include <openspace/navigation/orbitalnavigator.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/rendering/screenspacerenderable.h>
#include <ghoul/logging/logmanager.h>
#include <sstream>
#include <string>
using namespace TUIO;
+25 -1
View File
@@ -99,6 +99,25 @@ if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
target_compile_options(libcef_dll_wrapper PRIVATE "-w")
endif ()
target_precompile_headers(libcef_dll_wrapper PRIVATE
[["include/cef_client.h"]]
[["include/capi/cef_browser_capi.h"]]
[["include/capi/cef_client_capi.h"]]
[["include/cef_client.h"]]
[["include/capi/cef_base_capi.h"]]
[["include/cef_render_handler.h"]]
<string>
<sstream>
<istream>
<ostream>
)
if (WIN32)
target_precompile_headers(libcef_dll_wrapper PRIVATE
<Windows.h>
)
endif ()
##########################################################################################
# Add CEF client files
@@ -241,10 +260,15 @@ create_new_module(
${HEADER_FILES} ${SOURCE_FILES}
)
target_precompile_headers(${webbrowser_module} PRIVATE
<include/cef_browser.h>
<include/cef_client.h>
<include/wrapper/cef_helpers.h>
)
set_folder_location(libcef_dll_wrapper "Helper")
set_folder_location(openspace_web_helper "Helper")
# Display CEF configuration settings.
# PRINT_CEF_CONFIG()
+9
View File
@@ -446,6 +446,8 @@ target_include_directories(openspace-core
)
target_precompile_headers(openspace-core PRIVATE
<openspace/json.h>
<openspace/properties/numericalproperty.h>
[["ghoul/fmt.h"]]
[["ghoul/glm.h"]]
[["ghoul/misc/assert.h"]]
@@ -453,12 +455,19 @@ target_precompile_headers(openspace-core PRIVATE
[["ghoul/misc/exception.h"]]
[["ghoul/misc/invariants.h"]]
[["ghoul/misc/profiling.h"]]
[["ghoul/opengl/ghoul_gl.h"]]
<algorithm>
<any>
<array>
<deque>
<filesystem>
<fstream>
<future>
<map>
<memory>
<string>
<utility>
<variant>
<vector>
)
+1
View File
@@ -33,6 +33,7 @@
#include <curl/curl.h>
#include <chrono>
#include <filesystem>
#include <sstream>
#include <thread>
namespace {
+34 -34
View File
@@ -66,140 +66,140 @@ void create() {
#endif // WIN32
#ifdef WIN32
initialize = new (currentPos) std::vector<std::function<void()>>;
initialize = new (currentPos) std::vector<std::function<void()>>();
ghoul_assert(initialize, "No initialize");
currentPos += sizeof(std::vector<std::function<void()>>);
#else // ^^^ WIN32 / !WIN32 vvv
initialize = new std::vector<std::function<void()>>;
initialize = new std::vector<std::function<void()>>();
#endif // WIN32
#ifdef WIN32
deinitialize = new (currentPos) std::vector<std::function<void()>>;
deinitialize = new (currentPos) std::vector<std::function<void()>>();
ghoul_assert(deinitialize, "No deinitialize");
currentPos += sizeof(std::vector<std::function<void()>>);
#else // ^^^ WIN32 / !WIN32 vvv
deinitialize = new std::vector<std::function<void()>>;
deinitialize = new std::vector<std::function<void()>>();
#endif // WIN32
#ifdef WIN32
initializeGL = new (currentPos) std::vector<std::function<void()>>;
initializeGL = new (currentPos) std::vector<std::function<void()>>();
ghoul_assert(initializeGL, "No initializeGL");
currentPos += sizeof(std::vector<std::function<void()>>);
#else // ^^^ WIN32 / !WIN32 vvv
initializeGL = new std::vector<std::function<void()>>;
initializeGL = new std::vector<std::function<void()>>();
#endif // WIN32
#ifdef WIN32
deinitializeGL = new (currentPos) std::vector<std::function<void()>>;
deinitializeGL = new (currentPos) std::vector<std::function<void()>>();
ghoul_assert(deinitializeGL, "No deinitializeGL");
currentPos += sizeof(std::vector<std::function<void()>>);
#else // ^^^ WIN32 / !WIN32 vvv
deinitializeGL = new std::vector<std::function<void()>>;
deinitializeGL = new std::vector<std::function<void()>>();
#endif // WIN32
#ifdef WIN32
preSync = new (currentPos) std::vector<std::function<void()>>;
preSync = new (currentPos) std::vector<std::function<void()>>();
ghoul_assert(preSync, "No preSync");
currentPos += sizeof(std::vector<std::function<void()>>);
#else // ^^^ WIN32 / !WIN32 vvv
preSync = new std::vector<std::function<void()>>;
preSync = new std::vector<std::function<void()>>();
#endif // WIN32
#ifdef WIN32
postSyncPreDraw = new (currentPos) std::vector<std::function<void()>>;
postSyncPreDraw = new (currentPos) std::vector<std::function<void()>>();
ghoul_assert(postSyncPreDraw, "No postSyncPreDraw");
currentPos += sizeof(std::vector<std::function<void()>>);
#else // ^^^ WIN32 / !WIN32 vvv
postSyncPreDraw = new std::vector<std::function<void()>>;
postSyncPreDraw = new std::vector<std::function<void()>>();
#endif // WIN32
#ifdef WIN32
render = new (currentPos) std::vector<std::function<void()>>;
render = new (currentPos) std::vector<std::function<void()>>();
ghoul_assert(render, "No render");
currentPos += sizeof(std::vector<std::function<void()>>);
#else // ^^^ WIN32 / !WIN32 vvv
render = new std::vector<std::function<void()>>;
render = new std::vector<std::function<void()>>();
#endif // WIN32
#ifdef WIN32
draw2D = new (currentPos) std::vector<std::function<void()>>;
draw2D = new (currentPos) std::vector<std::function<void()>>();
ghoul_assert(draw2D, "No draw2D");
currentPos += sizeof(std::vector<std::function<void()>>);
#else // ^^^ WIN32 / !WIN32 vvv
draw2D = new std::vector<std::function<void()>>;
draw2D = new std::vector<std::function<void()>>();
#endif // WIN32
#ifdef WIN32
postDraw = new (currentPos) std::vector<std::function<void()>>;
postDraw = new (currentPos) std::vector<std::function<void()>>();
ghoul_assert(postDraw, "No postDraw");
currentPos += sizeof(std::vector<std::function<void()>>);
#else // ^^^ WIN32 / !WIN32 vvv
postDraw = new std::vector<std::function<void()>>;
postDraw = new std::vector<std::function<void()>>();
#endif // WIN32
#ifdef WIN32
keyboard = new (currentPos) std::vector<KeyboardCallback>
keyboard = new (currentPos) std::vector<KeyboardCallback>();
ghoul_assert(keyboard, "No keyboard");
currentPos += sizeof(std::vector<KeyboardCallback>);
#else // ^^^ WIN32 / !WIN32 vvv
keyboard = new std::vector<KeyboardCallback>;
keyboard = new std::vector<KeyboardCallback>();
#endif // WIN32
#ifdef WIN32
character = new (currentPos) std::vector<CharacterCallback>;
character = new (currentPos) std::vector<CharacterCallback>();
ghoul_assert(character, "No character");
currentPos += sizeof(std::vector<CharacterCallback>);
#else // ^^^ WIN32 / !WIN32 vvv
character = new std::vector<CharacterCallback>;
character = new std::vector<CharacterCallback>();
#endif // WIN32
#ifdef WIN32
mouseButton = new (currentPos) std::vector<MouseButtonCallback>;
mouseButton = new (currentPos) std::vector<MouseButtonCallback>();
ghoul_assert(mouseButton, "No mouseButton");
currentPos += sizeof(std::vector<MouseButtonCallback>);
#else // ^^^ WIN32 / !WIN32 vvv
mouseButton = new std::vector<MouseButtonCallback>;
mouseButton = new std::vector<MouseButtonCallback>();
#endif // WIN32
#ifdef WIN32
mousePosition =
new (currentPos) std::vector<MousePositionCallback>;
new (currentPos) std::vector<MousePositionCallback>();
ghoul_assert(mousePosition, "No mousePosition");
currentPos += sizeof(std::vector<MousePositionCallback>);
#else // ^^^ WIN32 / !WIN32 vvv
mousePosition = new std::vector<MousePositionCallback>;
mousePosition = new std::vector<MousePositionCallback>();
#endif // WIN32
#ifdef WIN32
mouseScrollWheel = new (currentPos) std::vector<MouseScrollWheelCallback>;
mouseScrollWheel = new (currentPos) std::vector<MouseScrollWheelCallback>();
ghoul_assert(mouseScrollWheel, "No mouseScrollWheel");
currentPos += sizeof(std::vector<MouseScrollWheelCallback>);
#else // ^^^ WIN32 / !WIN32 vvv
mouseScrollWheel = new std::vector<MouseScrollWheelCallback>;
mouseScrollWheel = new std::vector<MouseScrollWheelCallback>();
#endif // WIN32
#ifdef WIN32
touchDetected = new (currentPos) std::vector<std::function<bool(TouchInput)>>;
touchDetected = new (currentPos) std::vector<std::function<bool(TouchInput)>>();
ghoul_assert(touchDetected, "No touchDetected");
currentPos += sizeof(std::vector<std::function<bool(TouchInput)>>);
#else // ^^^ WIN32 / !WIN32 vvv
touchDetected = new std::vector<std::function<bool(TouchInput)>>;
touchDetected = new std::vector<std::function<bool(TouchInput)>>();
#endif // WIN32
#ifdef WIN32
touchUpdated = new (currentPos) std::vector<std::function<bool(TouchInput)>>;
touchUpdated = new (currentPos) std::vector<std::function<bool(TouchInput)>>();
ghoul_assert(touchUpdated, "No touchUpdated");
currentPos += sizeof(std::vector<std::function<bool(TouchInput)>>);
#else // ^^^ WIN32 / !WIN32 vvv
touchUpdated = new std::vector<std::function<bool(TouchInput)>>;
touchUpdated = new std::vector<std::function<bool(TouchInput)>>();
#endif // WIN32
#ifdef WIN32
touchExit = new (currentPos) std::vector<std::function<void(TouchInput)>>;
touchExit = new (currentPos) std::vector<std::function<void(TouchInput)>>();
ghoul_assert(touchExit, "No touchExit");
//currentPos += sizeof(std::vector<std::function<void(TouchInput)>>);
#else // ^^^ WIN32 / !WIN32 vvv
touchExit = new std::vector<std::function<void(TouchInput)>>;
touchExit = new std::vector<std::function<void(TouchInput)>>();
#endif // WIN32
}
+5
View File
@@ -82,6 +82,7 @@
#include <ghoul/misc/profiling.h>
#include <ghoul/misc/stacktrace.h>
#include <ghoul/misc/stringconversion.h>
#include <ghoul/opengl/ghoul_gl.h>
#include <ghoul/opengl/debugcontext.h>
#include <ghoul/opengl/shaderpreprocessor.h>
#include <ghoul/opengl/texture.h>
@@ -94,6 +95,10 @@
#include <numeric>
#include <sstream>
#ifdef WIN32
#include <Windows.h>
#endif // WIN32
#ifdef __APPLE__
#include <openspace/interaction/touchbar.h>
#endif // __APPLE__
+1 -1
View File
@@ -55,7 +55,7 @@
#include <iomanip>
#ifdef WIN32
#include <windows.h>
#include <Windows.h>
#endif // WIN32
#include "sessionrecording_lua.inl"
+12 -7
View File
@@ -316,6 +316,7 @@ glm::dquat Path::linearPathRotation(double t) const {
}
glm::dquat Path::lookAtTargetsRotation(double t) const {
t = glm::clamp(t, 0.0, 1.0);
const double t1 = 0.2;
const double t2 = 0.8;
@@ -331,13 +332,15 @@ glm::dquat Path::lookAtTargetsRotation(double t) const {
const glm::dvec3 viewDir = ghoul::viewDirection(_start.rotation());
const glm::dvec3 inFrontOfStart = startPos + inFrontDistance * viewDir;
const double tScaled = ghoul::cubicEaseInOut(t / t1);
const double tScaled = glm::clamp(t / t1, 0.0, 1.0);
const double tEased = ghoul::cubicEaseInOut(tScaled);
lookAtPos =
ghoul::interpolateLinear(tScaled, inFrontOfStart, startNodePos);
ghoul::interpolateLinear(tEased, inFrontOfStart, startNodePos);
}
else if (t <= t2) {
const double tScaled = ghoul::cubicEaseInOut((t - t1) / (t2 - t1));
lookAtPos = ghoul::interpolateLinear(tScaled, startNodePos, endNodePos);
const double tScaled = glm::clamp((t - t1) / (t2 - t1), 0.0, 1.0);
const double tEased = ghoul::cubicEaseInOut(tScaled);
lookAtPos = ghoul::interpolateLinear(tEased, startNodePos, endNodePos);
}
else {
// (t > t2)
@@ -346,8 +349,9 @@ glm::dquat Path::lookAtTargetsRotation(double t) const {
const glm::dvec3 viewDir = ghoul::viewDirection(_end.rotation());
const glm::dvec3 inFrontOfEnd = endPos + inFrontDistance * viewDir;
const double tScaled = ghoul::cubicEaseInOut((t - t2) / (1.0 - t2));
lookAtPos = ghoul::interpolateLinear(tScaled, endNodePos, inFrontOfEnd);
const double tScaled = glm::clamp((t - t2) / (1.0 - t2), 0.0, 1.0);
const double tEased = ghoul::cubicEaseInOut(tScaled);
lookAtPos = ghoul::interpolateLinear(tEased, endNodePos, inFrontOfEnd);
}
// Handle up vector separately
@@ -416,6 +420,7 @@ double Path::speedAlongPath(double traveledDistance) const {
const double remainingDistance = pathLength() - traveledDistance;
dampeningFactor = remainingDistance / closeUpDistance;
}
dampeningFactor = glm::clamp(dampeningFactor, 0.0, 1.0);
dampeningFactor = ghoul::sineEaseOut(dampeningFactor);
// Prevent multiplying with 0 (and hence a speed of 0.0 => no movement)
@@ -706,7 +711,7 @@ Path createPathFromDictionary(const ghoul::Dictionary& dictionary,
try {
return Path(startPoint, waypointToAdd, type, duration);
}
catch (const PathCurve::TooShortPathError& e) {
catch (const PathCurve::TooShortPathError&) {
LINFO("Already at the requested target");
// Rethrow e, so the pathnavigator can handle it as well
throw;
+1
View File
@@ -29,6 +29,7 @@
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/misc/assert.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/ghoul_gl.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
#include <algorithm>
+1
View File
@@ -36,6 +36,7 @@
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/misc/stringconversion.h>
#include <ghoul/opengl/ghoul_gl.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
+1
View File
@@ -37,6 +37,7 @@
#include <ghoul/misc/clipboard.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/opengl/ghoul_gl.h>
#include <ghoul/opengl/programobject.h>
#include <filesystem>
#include <fstream>
+4
View File
@@ -267,6 +267,10 @@ bool Renderable::matchesRenderBinMask(int binMask) {
return binMask & static_cast<int>(renderBin());
}
void Renderable::setFade(float fade) {
_fade = fade;
}
bool Renderable::isVisible() const {
return _enabled && _opacity > 0.f && _fade > 0.f;
}
+3 -3
View File
@@ -63,6 +63,7 @@
#include <ghoul/misc/easing.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/misc/stringconversion.h>
#include <ghoul/opengl/ghoul_gl.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/openglstatecache.h>
#include <ghoul/systemcapabilities/openglcapabilitiescomponent.h>
@@ -1099,15 +1100,14 @@ void RenderEngine::removeScreenSpaceRenderable(ScreenSpaceRenderable* s) {
}
}
void RenderEngine::removeScreenSpaceRenderable(const std::string& identifier) {
void RenderEngine::removeScreenSpaceRenderable(std::string_view identifier) {
ScreenSpaceRenderable* s = screenSpaceRenderable(identifier);
if (s) {
removeScreenSpaceRenderable(s);
}
}
ScreenSpaceRenderable* RenderEngine::screenSpaceRenderable(const std::string& identifier)
{
ScreenSpaceRenderable* RenderEngine::screenSpaceRenderable(std::string_view identifier) {
const auto it = std::find_if(
global::screenSpaceRenderables->begin(),
global::screenSpaceRenderables->end(),
+1
View File
@@ -36,6 +36,7 @@
#include <openspace/util/factorymanager.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/ghoul_gl.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/textureunit.h>
#include <optional>
+1
View File
@@ -33,6 +33,7 @@
#include <iterator>
#include <filesystem>
#include <fstream>
#include <sstream>
#include <string>
namespace {
+1
View File
@@ -51,6 +51,7 @@
#include <ghoul/misc/easing.h>
#include <ghoul/misc/misc.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/ghoul_gl.h>
#include <string>
#include <stack>
@@ -25,6 +25,7 @@
#include <openspace/util/blockplaneintersectiongeometry.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/opengl/ghoul_gl.h>
#include <algorithm>
namespace {
+1
View File
@@ -25,6 +25,7 @@
#include <openspace/util/boxgeometry.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/opengl/ghoul_gl.h>
#include <string>
namespace {
+1
View File
@@ -25,6 +25,7 @@
#include <openspace/util/planegeometry.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/opengl/ghoul_gl.h>
#include <string>
namespace openspace {
+1
View File
@@ -25,6 +25,7 @@
#include <openspace/util/sphere.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/opengl/ghoul_gl.h>
#include <cstring>
namespace {
+18 -16
View File
@@ -31,22 +31,24 @@ function (create_new_application application_name)
# We currently can't reuse the precompiled header because that one has the Kameleon
# definition stuck into it
#target_precompile_headers(${library_name} REUSE_FROM openspace-core)
target_precompile_headers(${application_name} PRIVATE
[["ghoul/fmt.h"]]
[["ghoul/glm.h"]]
[["ghoul/misc/assert.h"]]
[["ghoul/misc/boolean.h"]]
[["ghoul/misc/exception.h"]]
[["ghoul/misc/invariants.h"]]
[["ghoul/misc/profiling.h"]]
<algorithm>
<array>
<map>
<memory>
<string>
<utility>
<vector>
)
#target_precompile_headers(${application_name} PRIVATE
# [["ghoul/fmt.h"]]
# [["ghoul/glm.h"]]
# [["ghoul/misc/assert.h"]]
# [["ghoul/misc/boolean.h"]]
# [["ghoul/misc/exception.h"]]
# [["ghoul/misc/invariants.h"]]
# [["ghoul/misc/profiling.h"]]
# <algorithm>
# <array>
# <chrono>
# <filesystem>
# <map>
# <memory>
# <string>
# <utility>
# <vector>
#)
if (WIN32)
get_external_library_dependencies(ext_lib)
+4 -6
View File
@@ -108,9 +108,6 @@ endfunction ()
function (handle_module_dependencies target_name module_name)
# We always want to link against Ghoul and the core library
target_link_libraries(${library_name} PRIVATE Ghoul openspace-core)
# We currently can't reuse the precompiled header because that one has the Kameleon
# definition stuck into it
#target_precompile_headers(${library_name} REUSE_FROM openspace-core)
target_precompile_headers(${library_name} PRIVATE
[["ghoul/fmt.h"]]
[["ghoul/glm.h"]]
@@ -119,12 +116,13 @@ function (handle_module_dependencies target_name module_name)
[["ghoul/misc/exception.h"]]
[["ghoul/misc/invariants.h"]]
[["ghoul/misc/profiling.h"]]
<algorithm>
[["ghoul/opengl/ghoul_gl.h"]]
<array>
<map>
<filesystem>
<memory>
<string>
<utility>
<string_view>
<variant>
<vector>
)
@@ -23,7 +23,7 @@
##########################################################################################
function (set_openspace_compile_settings target)
target_compile_features(${target} PRIVATE cxx_std_20)
target_compile_features(${target} PUBLIC cxx_std_20)
set(MSVC_WARNINGS
"/MP" # Multi-threading support
@@ -195,6 +195,8 @@ function (set_openspace_compile_settings target)
# Boost as of 1.64 still uses unary_function unless we define this
target_compile_definitions(${target} PRIVATE "_HAS_AUTO_PTR_ETC")
target_compile_definitions(${target} PRIVATE "NOMINMAX")
target_compile_definitions(${target} PRIVATE "WIN32_LEAN_AND_MEAN")
target_compile_definitions(${target} PRIVATE "VC_EXTRALEAN")
elseif (NOT LINUX AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if (OPENSPACE_WARNINGS_AS_ERRORS)
target_compile_options(${target} PRIVATE "-Werror")