diff --git a/CMakeLists.txt b/CMakeLists.txt index 81d0833e7c..b4b73947d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,8 +28,8 @@ project(OpenSpace) set(OPENSPACE_VERSION_MAJOR 0) set(OPENSPACE_VERSION_MINOR 17) -set(OPENSPACE_VERSION_PATCH -1) -set(OPENSPACE_VERSION_STRING "Beta-10 [RC1]") +set(OPENSPACE_VERSION_PATCH 0) +set(OPENSPACE_VERSION_STRING "Beta-10") set(OPENSPACE_BASE_DIR "${PROJECT_SOURCE_DIR}") set(OPENSPACE_CMAKE_EXT_DIR "${OPENSPACE_BASE_DIR}/support/cmake") diff --git a/config/fullscreen1080.xml b/config/fullscreen1080.xml index 3b7f94c4cc..52d703f435 100644 --- a/config/fullscreen1080.xml +++ b/config/fullscreen1080.xml @@ -4,7 +4,7 @@ - + diff --git a/config/single_sbs_stereo.xml b/config/single_sbs_stereo.xml index 595d92cafb..e0707559c1 100644 --- a/config/single_sbs_stereo.xml +++ b/config/single_sbs_stereo.xml @@ -1,22 +1,16 @@ - + + + + - - - - - - + + + + + - - - - - - - - - + @@ -24,7 +18,7 @@ - + diff --git a/config/spout_output.xml b/config/spout_output.xml index bac296112f..da4efdc48f 100644 --- a/config/spout_output.xml +++ b/config/spout_output.xml @@ -7,7 +7,7 @@ - + diff --git a/data/assets/scene/solarsystem/missions/osirisrex/bennu_projection.asset b/data/assets/scene/solarsystem/missions/osirisrex/bennu_projection.asset index afcfb529a7..c78fbef4b2 100644 --- a/data/assets/scene/solarsystem/missions/osirisrex/bennu_projection.asset +++ b/data/assets/scene/solarsystem/missions/osirisrex/bennu_projection.asset @@ -34,7 +34,7 @@ local BennuProjection = { Enabled = true, Type = "RenderableModelProjection", Body = BENNU_BODY, - GeometryFile = models .. "/BennuTextured.obj", + GeometryFile = models .. "/Bennu_v20_200k_an.obj", Projection = { Sequence = { images, imagesA }, SequenceType = "image-sequence", diff --git a/data/assets/util/webgui.asset b/data/assets/util/webgui.asset index 15195ee953..e03c216905 100644 --- a/data/assets/util/webgui.asset +++ b/data/assets/util/webgui.asset @@ -3,7 +3,7 @@ asset.require('./static_server') local guiCustomization = asset.require('customization/gui') -- Select which commit hashes to use for the frontend and backend -local frontendHash = "96b88e6c760e59d143bd29da6f06011eaafce4b1" +local frontendHash = "829260614bb95e236d23cb500f6ec0fb2e3bdf51" local dataProvider = "data.openspaceproject.com/files/webgui" local frontend = asset.syncedResource({ diff --git a/ext/CMakeLists.txt b/ext/CMakeLists.txt index 0010d35d22..797f419d56 100644 --- a/ext/CMakeLists.txt +++ b/ext/CMakeLists.txt @@ -54,6 +54,7 @@ set_folder_location(GhoulTest "Unit Tests") # Spice begin_dependency("Spice") +set(SPICE_BUILD_SHARED_LIBRARY OFF CACHE BOOL "" FORCE) add_subdirectory(spice) set_folder_location(spice "External") end_dependency() diff --git a/ext/ghoul b/ext/ghoul index c3c9b88e52..2ffa7b7f7a 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit c3c9b88e524228fb8613c310605cc2126ed9c5bd +Subproject commit 2ffa7b7f7a9582f191e51d4f7b030ea764f86a4c diff --git a/ext/spice b/ext/spice index ba40ad2c25..e8a1cbeacc 160000 --- a/ext/spice +++ b/ext/spice @@ -1 +1 @@ -Subproject commit ba40ad2c25fe81e152a733b4a6afe53868388206 +Subproject commit e8a1cbeacc25a60fbed2f0958951a012ef6ba8e3 diff --git a/include/openspace/interaction/sessionrecording.h b/include/openspace/interaction/sessionrecording.h index 6e776b4ce8..69e7026102 100644 --- a/include/openspace/interaction/sessionrecording.h +++ b/include/openspace/interaction/sessionrecording.h @@ -575,6 +575,7 @@ public: protected: properties::BoolProperty _renderPlaybackInformation; + properties::BoolProperty _ignoreRecordedScale; enum class RecordedType { Camera = 0, diff --git a/include/openspace/properties/numericalproperty.inl b/include/openspace/properties/numericalproperty.inl index 3f5696f17a..23adef27f5 100644 --- a/include/openspace/properties/numericalproperty.inl +++ b/include/openspace/properties/numericalproperty.inl @@ -23,9 +23,11 @@ ****************************************************************************************/ #include +#include #include #include #include +#include namespace openspace::properties { @@ -90,6 +92,35 @@ float NumericalProperty::exponent() const { template void NumericalProperty::setExponent(float exponent) { ghoul_assert(std::abs(exponent) > 0.f, "Exponent for property input cannot be zero"); + + auto isValidRange = [](const T& minValue, const T& maxValue) { + if constexpr (ghoul::isGlmVector() || ghoul::isGlmMatrix()) { + return glm::all(glm::greaterThanEqual(minValue, T(0))) && + glm::all(glm::greaterThanEqual(maxValue, T(0))); + } + else { + return (minValue >= T(0) && maxValue >= T(0)); + } + }; + + // While the exponential slider does not support ranges with negative values, + // prevent setting the exponent for such ranges + // @ TODO (2021-06-30, emmbr), remove this check when no longer needed + if (!std::is_unsigned::value) { + if (!isValidRange(_minimumValue, _maximumValue)) { + LWARNINGC( + "NumericalProperty: setExponent", + fmt::format( + "Setting exponent for properties with negative values in " + "[min, max] range is not yet supported. Property: {}", + this->fullyQualifiedIdentifier() + ) + ); + _exponent = 1.f; + return; + } + } + _exponent = exponent; } diff --git a/include/openspace/scripting/scriptengine.h b/include/openspace/scripting/scriptengine.h index 94a187e1ca..e6c0c23607 100644 --- a/include/openspace/scripting/scriptengine.h +++ b/include/openspace/scripting/scriptengine.h @@ -31,9 +31,10 @@ #include #include #include +#include #include -#include #include +#include #include namespace openspace { class SyncBuffer; } @@ -82,7 +83,7 @@ public: bool hasLibrary(const std::string& name); bool runScript(const std::string& script, ScriptCallback callback = ScriptCallback()); - bool runScriptFile(const std::string& filename); + bool runScriptFile(const std::filesystem::path& filename); bool writeLog(const std::string& script); diff --git a/include/openspace/util/coordinateconversion.h b/include/openspace/util/coordinateconversion.h index b6ba2ec7d5..798f45e6e2 100644 --- a/include/openspace/util/coordinateconversion.h +++ b/include/openspace/util/coordinateconversion.h @@ -26,18 +26,45 @@ #define __OPENSPACE_CORE___COORDINATECONVERSION___H__ #include +#include namespace openspace { /** - * Converts from ICRS coordinates to galactic cartesian coordinates. + * Converts from ICRS decimal degrees coordinates to galactic cartesian coordinates. * \param ra Right ascension, given in decimal degrees * \param dec Declination, given in decimal degrees * \param distance The distance, or radius, to the position given in any unit. * \return A position in galactic cartesian coordinates, given in the same unit as the * distance parameter. */ -glm::dvec3 icrsToGalacticCartesian(float ra, float dec, double distance); +glm::dvec3 icrsToGalacticCartesian(double ra, double dec, double distance); + +/** + * Converts from ICRS (hms and dms) coordinates to decimal degrees. + * \param ra Right ascension, given as a string in format 'XhYmZs' + * \param dec Declination, given as a string in format 'XdYmZs' + * \return The decimal degrees coordinate in degrees + */ +glm::dvec2 icrsToDecimalDegrees(const std::string& ra, const std::string& dec); + +/** + * Converts from galactic cartesian coordinates to ICRS decimal degrees coordinates + * and distance. + * \param x X coordinate + * \param y Y coordinate + * \param z Z coordinate + * \return A vector with the ra and dec decimal degrees in degrees and distance. + */ +glm::dvec3 galacticCartesianToIcrs(double x, double y, double z); + +/** + * Converts from ICRS decimal degrees coordinates to ICRS hms and dms coordinates. + * \param ra Right ascension, given in decimal degrees + * \param dec Declination, given in decimal degrees + * \return A pair with the ra and dec strings in hms and dms format. + */ +std::pair decimalDegreesToIcrs(double ra, double dec); } // namespace openspace diff --git a/modules/atmosphere/rendering/atmospheredeferredcaster.cpp b/modules/atmosphere/rendering/atmospheredeferredcaster.cpp index 33bb35fab1..1cf0fc71ce 100644 --- a/modules/atmosphere/rendering/atmospheredeferredcaster.cpp +++ b/modules/atmosphere/rendering/atmospheredeferredcaster.cpp @@ -74,8 +74,8 @@ namespace { "cullAtmosphere", "Rg", "Rt", "groundRadianceEmission", "HR", "betaRayleigh", "HM", "betaMieExtinction", "mieG", "sunRadiance", "ozoneLayerEnabled", "HO", "betaOzoneExtinction", "SAMPLES_R", "SAMPLES_MU", "SAMPLES_MU_S", "SAMPLES_NU", - "dInverseModelTransformMatrix", "dModelTransformMatrix", - "dSgctProjectionToModelTransformMatrix", "dSGCTViewToWorldMatrix", "dCamPosObj", + "inverseModelTransformMatrix", "modelTransformMatrix", + "projectionToModelTransformMatrix", "viewToWorldMatrix", "camPosObj", "sunDirectionObj", "hardShadows", "transmittanceTexture", "irradianceTexture", "inscatterTexture" }; @@ -309,53 +309,38 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& renderData, // Object Space glm::dmat4 inverseModelMatrix = glm::inverse(_modelTransform); program.setUniform( - _uniformCache.dInverseModelTransformMatrix, - inverseModelMatrix + _uniformCache.inverseModelTransformMatrix, inverseModelMatrix ); - program.setUniform(_uniformCache.dModelTransformMatrix, _modelTransform); + program.setUniform(_uniformCache.modelTransformMatrix, _modelTransform); - // Eye Space in SGCT to Eye Space in OS (SGCT View to OS Camera Rig) -// glm::dmat4 dSgctEye2OSEye = glm::inverse( -// glm::dmat4(renderData.camera.viewMatrix())); - - glm::dmat4 dSGCTViewToWorldMatrix = glm::inverse( + glm::dmat4 viewToWorldMatrix = glm::inverse( renderData.camera.combinedViewMatrix() ); - // Eye Space in SGCT to OS World Space - program.setUniform( - _uniformCache.dSGCTViewToWorldMatrix, - dSGCTViewToWorldMatrix - ); + // Eye Space to World Space + program.setUniform(_uniformCache.viewToWorldMatrix, viewToWorldMatrix); - // SGCT Projection to SGCT Eye Space + // Projection to Eye Space glm::dmat4 dInverseProjection = glm::inverse( glm::dmat4(renderData.camera.projectionMatrix()) ); glm::dmat4 inverseWholeMatrixPipeline = - inverseModelMatrix * dSGCTViewToWorldMatrix * dInverseProjection; + inverseModelMatrix * viewToWorldMatrix * dInverseProjection; program.setUniform( - _uniformCache.dSgctProjectionToModelTransformMatrix, + _uniformCache.projectionToModelTransformMatrix, inverseWholeMatrixPipeline ); glm::dvec4 camPosObjCoords = inverseModelMatrix * glm::dvec4(renderData.camera.eyePositionVec3(), 1.0); - program.setUniform(_uniformCache.dCamPosObj, camPosObjCoords); + program.setUniform(_uniformCache.camPosObj, glm::dvec3(camPosObjCoords)); + + SceneGraphNode* node = sceneGraph()->sceneGraphNode("Sun"); + glm::dvec3 sunPosWorld = node ? node->worldPosition() : glm::dvec3(0.0); - double lt; - glm::dvec3 sunPosWorld = SpiceManager::ref().targetPosition( - "SUN", - "SSB", - "GALACTIC", - {}, - _time, - lt - ); glm::dvec4 sunPosObj; - // Sun following camera position if (_sunFollowingCameraEnabled) { sunPosObj = inverseModelMatrix * glm::dvec4( @@ -365,7 +350,10 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& renderData, } else { sunPosObj = inverseModelMatrix * - glm::dvec4(sunPosWorld - renderData.modelTransform.translation, 1.0); + glm::dvec4( + (sunPosWorld - renderData.modelTransform.translation) * 1000.0, + 1.0 + ); } // Sun Position in Object Space @@ -374,6 +362,8 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& renderData, glm::normalize(glm::dvec3(sunPosObj)) ); + ghoul::opengl::updateUniformLocations(program, _uniformCache, UniformNames); + // Shadow calculations.. if (!_shadowConfArray.empty()) { ZoneScopedN("Shadow Configuration") @@ -384,6 +374,7 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& renderData, // TO REMEMBER: all distances and lengths in world coordinates are in // meters!!! We need to move this to view space... // Getting source and caster: + double lt; glm::dvec3 sourcePos = SpiceManager::ref().targetPosition( shadowConf.source.first, "SSB", diff --git a/modules/atmosphere/rendering/atmospheredeferredcaster.h b/modules/atmosphere/rendering/atmospheredeferredcaster.h index dd8ce176a9..589d2479c7 100644 --- a/modules/atmosphere/rendering/atmospheredeferredcaster.h +++ b/modules/atmosphere/rendering/atmospheredeferredcaster.h @@ -126,9 +126,9 @@ private: UniformCache(cullAtmosphere, Rg, Rt, groundRadianceEmission, HR, betaRayleigh, HM, betaMieExtinction, mieG, sunRadiance, ozoneLayerEnabled, HO, betaOzoneExtinction, - SAMPLES_R, SAMPLES_MU, SAMPLES_MU_S, SAMPLES_NU, dInverseModelTransformMatrix, - dModelTransformMatrix, dSgctProjectionToModelTransformMatrix, - dSGCTViewToWorldMatrix, dCamPosObj, sunDirectionObj, hardShadows, + SAMPLES_R, SAMPLES_MU, SAMPLES_MU_S, SAMPLES_NU, inverseModelTransformMatrix, + modelTransformMatrix, projectionToModelTransformMatrix, + viewToWorldMatrix, camPosObj, sunDirectionObj, hardShadows, transmittanceTexture, irradianceTexture, inscatterTexture) _uniformCache; GLuint _transmittanceTableTexture = 0; diff --git a/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl b/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl index 9be329d940..f0f97c8de1 100644 --- a/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl +++ b/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl @@ -62,7 +62,6 @@ in vec2 texCoord; out vec4 renderTarget; -uniform int nAaSamples; uniform int cullAtmosphere; uniform sampler2D irradianceTexture; @@ -71,17 +70,21 @@ uniform sampler2D mainPositionTexture; uniform sampler2D mainNormalTexture; uniform sampler2D mainColorTexture; -uniform dmat4 dInverseModelTransformMatrix; -uniform dmat4 dModelTransformMatrix; -uniform dmat4 dSGCTViewToWorldMatrix; -uniform dmat4 dSgctProjectionToModelTransformMatrix; +uniform dmat4 inverseModelTransformMatrix; +uniform dmat4 modelTransformMatrix; +uniform dmat4 viewToWorldMatrix; +uniform dmat4 projectionToModelTransformMatrix; uniform vec4 viewport; uniform vec2 resolution; -uniform dvec4 dCamPosObj; +uniform dvec3 camPosObj; uniform dvec3 sunDirectionObj; +uniform dvec3 sunWorld; +uniform dvec3 viewDirWorld; +uniform dvec3 sunModel; + /******************************************************************************* ***** ALL CALCULATIONS FOR ECLIPSE ARE IN METERS AND IN WORLD SPACE SYSTEM **** *******************************************************************************/ @@ -215,13 +218,13 @@ Ray calculateRayRenderableGlobe(vec2 st) { dvec4 clipCoords = dvec4(interpolatedNDCPos, 1.0, 1.0); // Clip to Object Coords - dvec4 objectCoords = dSgctProjectionToModelTransformMatrix * clipCoords; - objectCoords /= objectCoords.w; + dvec4 objectCoords = projectionToModelTransformMatrix * clipCoords; + objectCoords.xyz /= objectCoords.w; // Building Ray // Ray in object space (in KM) Ray ray; - ray.origin = dvec3(dCamPosObj * dvec4(0.001, 0.001, 0.001, 1.0)); + ray.origin = camPosObj * 0.001; ray.direction = normalize(objectCoords.xyz * dvec3(0.001) - ray.origin); return ray; } @@ -244,16 +247,15 @@ Ray calculateRayRenderableGlobe(vec2 st) { * attenuation := out of transmittance T(x,x0). This will be used later when calculating * the reflectance R[L] */ -vec3 inscatterRadiance(vec3 x, inout float t, out float irradianceFactor, vec3 v, vec3 s, - out float r, out float mu, out vec3 attenuation, vec3 fragPosObj, +vec3 inscatterRadiance(vec3 x, inout float t, inout float irradianceFactor, vec3 v, vec3 s, + float r, out float mu, out vec3 attenuation, vec3 fragPosObj, out bool groundHit, double maxLength, double pixelDepth, - vec4 spaceColor, float sunIntensity) + vec3 spaceColor, float sunIntensity) { const float INTERPOLATION_EPS = 0.004; // precision const from Brunetton vec3 radiance; - r = length(x); mu = dot(x, v) / r; float r2 = r * r; @@ -303,16 +305,15 @@ vec3 inscatterRadiance(vec3 x, inout float t, out float irradianceFactor, vec3 v } // cos(PI-thetaH) = dist/r - // cos(thetaH) = - dist/r + // cos(thetaH) = -dist/r // muHorizon = -sqrt(r^2-Rg^2)/r = -sqrt(1-(Rg/r)^2) float muHorizon = -sqrt(1.0 - Rg2 / r2); - // In order to avoid imprecision problems near horizon, we interpolate between two + // In order to avoid precision problems near horizon, we interpolate between two // points: above and below horizon if (abs(mu - muHorizon) < INTERPOLATION_EPS) { // We want an interpolation value close to 1/2, so the contribution of each radiance - // value is almost the same or it has a heavy weight if from above or - // below horizon + // value is almost the same or it has a heavy weight if from above or below horizon float interpolationValue = (mu - muHorizon + INTERPOLATION_EPS) / (2.0 * INTERPOLATION_EPS); // Above Horizon @@ -321,9 +322,9 @@ vec3 inscatterRadiance(vec3 x, inout float t, out float irradianceFactor, vec3 v // From cosine law where t = distance between x and x0 // r0^2 = r^2 + t^2 - 2 * r * t * cos(PI-theta) // r0 = sqrt(r2 + t2 + 2.0f * r * t * mu); - float halfCossineLaw1 = r2 + (t * t); - float halfCossineLaw2 = 2.0 * r * t; - r0 = sqrt(halfCossineLaw1 + halfCossineLaw2 * mu); + float halfCosineLaw1 = r2 + (t * t); + float halfCosineLaw2 = 2.0 * r * t; + r0 = sqrt(halfCosineLaw1 + halfCosineLaw2 * mu); // From the dot product: cos(theta0) = (x0 dot v)/(||ro||*||v||) // mu0 = ((x + t) dot v) / r0 @@ -339,7 +340,7 @@ vec3 inscatterRadiance(vec3 x, inout float t, out float irradianceFactor, vec3 v // Below Horizon mu = muHorizon + INTERPOLATION_EPS; //r0 = sqrt(r2 + t2 + 2.0f * r * t * mu); - r0 = sqrt(halfCossineLaw1 + halfCossineLaw2 * mu); + r0 = sqrt(halfCosineLaw1 + halfCosineLaw2 * mu); mu0 = (r * mu + t) * (1.0 / r0); @@ -374,7 +375,7 @@ vec3 inscatterRadiance(vec3 x, inout float t, out float irradianceFactor, vec3 v return finalScatteringRadiance; } else { - return spaceColor.rgb + finalScatteringRadiance; + return spaceColor + finalScatteringRadiance; } } @@ -457,16 +458,23 @@ vec3 groundColor(vec3 x, float t, vec3 v, vec3 s, vec3 attenuationXtoX0, vec3 gr * attenuation := transmittance T(x,x0) */ vec3 sunColor(vec3 v, vec3 s, float r, float mu, float irradianceFactor) { - vec3 tm = vec3(1.0); - if (r <= Rt) { - tm = mu < -sqrt(1.0 - Rg2 / (r * r)) ? vec3(0.0) : transmittance(r, mu); - } - // JCC: Change this function to a impostor texture with gaussian decay color weighted - // by the sunRadiance, transmittance and irradianceColor (11/03/2017) - float sunFinalColor = smoothstep(cos(M_PI / 500.0), cos(M_PI / 900.0), dot(v, s)) * - sunRadiance * (1.0 - irradianceFactor); + // v = normalize(vec3(inverseModelTransformMatrix * dvec4(sunWorld, 1.0))); + float angle = dot(v, s); - return tm * sunFinalColor; + // JCC: Change this function to a impostor texture with gaussian decay color weighted + // by the sunRadiance, transmittance and irradianceColor (11/03/2017) + + // @TODO (abock, 2021-07-01) This value is hard-coded to our sun right now + // Convert 0.3 degrees -> radians + const float SunAngularSize = (0.3 * M_PI / 180.0); + const float FuzzyFactor = 0.5; // How fuzzy should the edges be + + const float p1 = cos(SunAngularSize); + const float p2 = cos(SunAngularSize * FuzzyFactor); + + float t = (angle - p1) / (p2 - p1); + float scale = clamp(t, 0.0, 1.0); + return scale * transmittance(r, mu) * sunRadiance * (1.0 - irradianceFactor); } void main() { @@ -481,17 +489,13 @@ void main() { st.x = st.x / (resolution.x / viewport[2]) + (viewport[0] / resolution.x); st.y = st.y / (resolution.y / viewport[3]) + (viewport[1] / resolution.y); + // Color from G-Buffer + vec3 color = texture(mainColorTexture, st).rgb; if (cullAtmosphere == 1) { - renderTarget = texture(mainColorTexture, st); + renderTarget.rgb = color; return; } - vec4 atmosphereFinalColor = vec4(0.0); - int nSamples = 1; - - // Color from G-Buffer - vec4 color = texture(mainColorTexture, st); - // Get the ray from camera to atm in object space Ray ray = calculateRayRenderableGlobe(texCoord); @@ -499,7 +503,7 @@ void main() { double maxLength = 0.0; // in KM bool intersect = atmosphereIntersection(ray, Rt - (ATM_EPSILON * 0.001), offset, maxLength); if (!intersect) { - renderTarget = color; + renderTarget.rgb = color; return; } @@ -509,14 +513,11 @@ void main() { // Space (View plus Camera Rig Coords) when using their positions later, one must // convert them to the planet's coords - // - // Get data from G-Buffer - - // Normal is stored in SGCT View Space and transformed to the current object space + // Normal is stored in view space and transformed to the current object space vec4 normalViewSpaceAndWaterReflectance = texture(mainNormalTexture, st); dvec4 normalViewSpace = vec4(normalViewSpaceAndWaterReflectance.xyz, 0.0); - dvec4 normalWorldSpace = dSGCTViewToWorldMatrix * normalViewSpace; - vec4 normal = vec4(dInverseModelTransformMatrix * normalWorldSpace); + dvec4 normalWorldSpace = viewToWorldMatrix * normalViewSpace; + vec4 normal = vec4(inverseModelTransformMatrix * normalWorldSpace); normal.xyz = normalize(normal.xyz); normal.w = normalViewSpaceAndWaterReflectance.w; @@ -524,19 +525,20 @@ void main() { vec4 position = texture(mainPositionTexture, st); // OS Eye to World coords - dvec4 positionWorldCoords = dSGCTViewToWorldMatrix * position; + dvec4 positionWorldCoords = viewToWorldMatrix * position; // World to Object (Normal and Position in meters) - dvec4 positionObjectsCoords = dInverseModelTransformMatrix * positionWorldCoords; + dvec3 positionObjectsCoords = (inverseModelTransformMatrix * positionWorldCoords).xyz; // Distance of the pixel in the gBuffer to the observer // JCC (12/12/2017): AMD distance function is buggy. //double pixelDepth = distance(cameraPositionInObject.xyz, positionObjectsCoords.xyz); - double pixelDepth = length(dCamPosObj.xyz - positionObjectsCoords.xyz); + double pixelDepth = length(camPosObj - positionObjectsCoords); // JCC (12/13/2017): Trick to remove floating error in texture. // We see a squared noise on planet's surface when seeing the planet from far away - float dC = float(length(dCamPosObj.xyz)); + // @TODO (abock, 2021-07-01) I don't think this does anything. Remove? + float dC = float(length(camPosObj)); const float x1 = 1e8; if (dC > x1) { pixelDepth += 1000.0; @@ -552,22 +554,21 @@ void main() { // All calculations are done in KM: pixelDepth *= 0.001; - positionObjectsCoords.xyz *= 0.001; + positionObjectsCoords *= 0.001; if (pixelDepth < offset) { // ATM Occluded - Something in front of ATM - renderTarget = color; + renderTarget.rgb = color; return; } // Following paper nomenclature double t = offset; - vec3 attenuation; // Moving observer from camera location to top atmosphere. If the observer is already // inside the atm, offset = 0.0 and no changes at all vec3 x = vec3(ray.origin + t * ray.direction); - float r = 0.0; // length(x); + float r = length(x); vec3 v = vec3(ray.direction); float mu = 0.0; // dot(x, v) / r; vec3 s = vec3(sunDirectionObj); @@ -578,27 +579,30 @@ void main() { // comparison with the planet's ground make sense: pixelDepth -= offset; - dvec3 onATMPos = (dModelTransformMatrix * dvec4(x * 1000.0, 1.0)).xyz; + dvec3 onATMPos = (modelTransformMatrix * dvec4(x * 1000.0, 1.0)).xyz; float eclipseShadowATM = calcShadow(shadowDataArray, onATMPos, false); float sunIntensityInscatter = sunRadiance * eclipseShadowATM; float irradianceFactor = 0.0; bool groundHit = false; + vec3 attenuation; + vec3 inscatterColor = inscatterRadiance(x, tF, irradianceFactor, v, s, r, mu, - attenuation, vec3(positionObjectsCoords.xyz), groundHit, maxLength, pixelDepth, - color, sunIntensityInscatter); + attenuation, vec3(positionObjectsCoords), groundHit, maxLength, pixelDepth, + color, sunIntensityInscatter); vec3 atmColor = vec3(0.0); if (groundHit) { float eclipseShadowPlanet = calcShadow(shadowDataArray, positionWorldCoords.xyz, true); float sunIntensityGround = sunRadiance * eclipseShadowPlanet; - atmColor = groundColor(x, tF, v, s, attenuation, color.rgb, normal.xyz, + atmColor = groundColor(x, tF, v, s, attenuation, color, normal.xyz, irradianceFactor, normal.w, sunIntensityGround); } else { // In order to get better performance, we are not tracing multiple rays per pixel // when the ray doesn't intersect the ground - atmColor = sunColor(v, s, r, mu, irradianceFactor); + + atmColor = sunColor(v, s, r, mu, irradianceFactor); } // Final Color of ATM plus terrain: diff --git a/modules/base/basemodule.cpp b/modules/base/basemodule.cpp index 67f2332629..048bbc0d45 100644 --- a/modules/base/basemodule.cpp +++ b/modules/base/basemodule.cpp @@ -213,6 +213,7 @@ std::vector BaseModule::documentations() const { ScreenSpaceImageLocal::Documentation(), ScreenSpaceImageOnline::Documentation(), + ConstantRotation::Documentation(), FixedRotation::Documentation(), LuaRotation::Documentation(), StaticRotation::Documentation(), diff --git a/modules/base/rendering/renderableplaneimagelocal.cpp b/modules/base/rendering/renderableplaneimagelocal.cpp index 7b48b72bb5..6f6d88cacd 100644 --- a/modules/base/rendering/renderableplaneimagelocal.cpp +++ b/modules/base/rendering/renderableplaneimagelocal.cpp @@ -196,7 +196,7 @@ void RenderablePlaneImageLocal::loadTexture() { LDEBUGC( "RenderablePlaneImageLocal", - fmt::format("Loaded texture from '{}'", absPath(path)) + fmt::format("Loaded texture from {}", absPath(path)) ); texture->uploadTexture(); texture->setFilter(ghoul::opengl::Texture::FilterMode::LinearMipMap); diff --git a/modules/base/rendering/renderableplaneimageonline.cpp b/modules/base/rendering/renderableplaneimageonline.cpp index 8ce7be472e..998790b581 100644 --- a/modules/base/rendering/renderableplaneimageonline.cpp +++ b/modules/base/rendering/renderableplaneimageonline.cpp @@ -96,53 +96,55 @@ void RenderablePlaneImageOnline::bindTexture() { } void RenderablePlaneImageOnline::update(const UpdateData&) { - if (_textureIsDirty) { - if (!_imageFuture.valid()) { - std::future future = downloadImageToMemory( - _texturePath + if (!_textureIsDirty) { + return; + } + + if (!_imageFuture.valid()) { + std::future future = downloadImageToMemory( + _texturePath + ); + if (future.valid()) { + _imageFuture = std::move(future); + } + } + + if (_imageFuture.valid() && DownloadManager::futureReady(_imageFuture)) { + DownloadManager::MemoryFile imageFile = _imageFuture.get(); + + if (imageFile.corrupted) { + LERRORC( + "ScreenSpaceImageOnline", + fmt::format("Error loading image from URL '{}'", _texturePath) ); - if (future.valid()) { - _imageFuture = std::move(future); - } + return; } - if (_imageFuture.valid() && DownloadManager::futureReady(_imageFuture)) { - DownloadManager::MemoryFile imageFile = _imageFuture.get(); - - if (imageFile.corrupted) { - LERRORC( - "ScreenSpaceImageOnline", - fmt::format("Error loading image from URL '{}'", _texturePath) + try { + std::unique_ptr texture = + ghoul::io::TextureReader::ref().loadTexture( + reinterpret_cast(imageFile.buffer), + imageFile.size, + imageFile.format ); - return; - } - try { - std::unique_ptr texture = - ghoul::io::TextureReader::ref().loadTexture( - reinterpret_cast(imageFile.buffer), - imageFile.size, - imageFile.format - ); + if (texture) { + // Images don't need to start on 4-byte boundaries, for example if the + // image is only RGB + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - if (texture) { - // Images don't need to start on 4-byte boundaries, for example if the - // image is only RGB - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + texture->uploadTexture(); + texture->setFilter(ghoul::opengl::Texture::FilterMode::LinearMipMap); + texture->purgeFromRAM(); - texture->uploadTexture(); - texture->setFilter(ghoul::opengl::Texture::FilterMode::LinearMipMap); - texture->purgeFromRAM(); - - _texture = std::move(texture); - _textureIsDirty = false; - } - } - catch (const ghoul::io::TextureReader::InvalidLoadException& e) { + _texture = std::move(texture); _textureIsDirty = false; - LERRORC(e.component, e.message); } } + catch (const ghoul::io::TextureReader::InvalidLoadException& e) { + _textureIsDirty = false; + LERRORC(e.component, e.message); + } } } diff --git a/modules/base/rendering/renderableprism.cpp b/modules/base/rendering/renderableprism.cpp index 7c96247b21..20f610d3c8 100644 --- a/modules/base/rendering/renderableprism.cpp +++ b/modules/base/rendering/renderableprism.cpp @@ -268,8 +268,8 @@ void RenderablePrism::updateVertexData() { _indexArray.push_back(255); // Indices for Top shape - for (uint8_t i = _nShapeSegments; i < 2 * _nShapeSegments; ++i) { - _indexArray.push_back(i); + for (int i = _nShapeSegments; i < 2 * _nShapeSegments; ++i) { + _indexArray.push_back(static_cast(i)); } // Indices for connecting lines @@ -277,8 +277,8 @@ void RenderablePrism::updateVertexData() { // Reset _indexArray.push_back(255); - _indexArray.push_back(2 * _nShapeSegments + k); - _indexArray.push_back(2 * _nShapeSegments + k + 1); + _indexArray.push_back(static_cast(2 * _nShapeSegments + k)); + _indexArray.push_back(static_cast(2 * _nShapeSegments + k + 1)); } } diff --git a/modules/base/rendering/renderablesphere.cpp b/modules/base/rendering/renderablesphere.cpp index e6b32389be..4d05f81f3d 100644 --- a/modules/base/rendering/renderablesphere.cpp +++ b/modules/base/rendering/renderablesphere.cpp @@ -452,7 +452,7 @@ void RenderableSphere::loadTexture() { if (texture) { LDEBUGC( "RenderableSphere", - fmt::format("Loaded texture from '{}'", absPath(_texturePath)) + fmt::format("Loaded texture from {}", absPath(_texturePath)) ); texture->uploadTexture(); texture->setFilter(ghoul::opengl::Texture::FilterMode::LinearMipMap); diff --git a/modules/base/rendering/renderabletrailorbit.cpp b/modules/base/rendering/renderabletrailorbit.cpp index a80152e3eb..fffd3effd8 100644 --- a/modules/base/rendering/renderabletrailorbit.cpp +++ b/modules/base/rendering/renderabletrailorbit.cpp @@ -158,10 +158,12 @@ RenderableTrailOrbit::RenderableTrailOrbit(const ghoul::Dictionary& dictionary) using namespace std::chrono; _period = p.period * duration_cast(hours(24)).count(); _period.onChange([&] { _needsFullSweep = true; _indexBufferDirty = true; }); + _period.setExponent(5.f); addProperty(_period); _resolution = p.resolution; _resolution.onChange([&] { _needsFullSweep = true; _indexBufferDirty = true; }); + _resolution.setExponent(3.5f); addProperty(_resolution); // We store the vertices with (excluding the wrapping) decending temporal order diff --git a/modules/base/rotation/luarotation.cpp b/modules/base/rotation/luarotation.cpp index 86d9e8d619..b2d019e305 100644 --- a/modules/base/rotation/luarotation.cpp +++ b/modules/base/rotation/luarotation.cpp @@ -79,7 +79,7 @@ LuaRotation::LuaRotation(const ghoul::Dictionary& dictionary) : LuaRotation() { } glm::dmat3 LuaRotation::matrix(const UpdateData& data) const { - ghoul::lua::runScriptFile(_state, _luaScriptFile); + ghoul::lua::runScriptFile(_state, _luaScriptFile.value()); // Get the scaling function lua_getglobal(_state, "rotation"); @@ -87,7 +87,9 @@ glm::dmat3 LuaRotation::matrix(const UpdateData& data) const { if (!isFunction) { LERRORC( "LuaRotation", - fmt::format("Script '{}' does nto have a function 'rotation'", _luaScriptFile) + fmt::format( + "Script '{}' does not have a function 'rotation'", _luaScriptFile.value() + ) ); return glm::dmat3(1.0); } diff --git a/modules/base/scale/luascale.cpp b/modules/base/scale/luascale.cpp index f99600595e..8eb44f4b47 100644 --- a/modules/base/scale/luascale.cpp +++ b/modules/base/scale/luascale.cpp @@ -77,7 +77,7 @@ LuaScale::LuaScale(const ghoul::Dictionary& dictionary) : LuaScale() { } glm::dvec3 LuaScale::scaleValue(const UpdateData& data) const { - ghoul::lua::runScriptFile(_state, _luaScriptFile); + ghoul::lua::runScriptFile(_state, _luaScriptFile.value()); // Get the scaling function lua_getglobal(_state, "scale"); @@ -85,7 +85,9 @@ glm::dvec3 LuaScale::scaleValue(const UpdateData& data) const { if (!isFunction) { LERRORC( "LuaScale", - fmt::format("Script '{}' does not have a function 'scale'", _luaScriptFile) + fmt::format( + "Script '{}' does not have a function 'scale'", _luaScriptFile.value() + ) ); return glm::dvec3(1.0); } diff --git a/modules/base/translation/luatranslation.cpp b/modules/base/translation/luatranslation.cpp index 2f853e8394..d0873b550a 100644 --- a/modules/base/translation/luatranslation.cpp +++ b/modules/base/translation/luatranslation.cpp @@ -81,7 +81,7 @@ LuaTranslation::LuaTranslation(const ghoul::Dictionary& dictionary) : LuaTransla } glm::dvec3 LuaTranslation::position(const UpdateData& data) const { - ghoul::lua::runScriptFile(_state, _luaScriptFile); + ghoul::lua::runScriptFile(_state, _luaScriptFile.value()); // Get the scaling function lua_getglobal(_state, "translation"); @@ -91,7 +91,7 @@ glm::dvec3 LuaTranslation::position(const UpdateData& data) const { "LuaScale", fmt::format( "Script '{}' does not have a function 'translation'", - _luaScriptFile + _luaScriptFile.value() ) ); return glm::dvec3(0.0); @@ -119,7 +119,7 @@ glm::dvec3 LuaTranslation::position(const UpdateData& data) const { double values[3]; for (int i = 1; i <= 3; ++i) { - values[i] = ghoul::lua::value(_state, i); + values[i - 1] = ghoul::lua::value(_state, i); } return glm::make_vec3(values); diff --git a/modules/base/translation/statictranslation.cpp b/modules/base/translation/statictranslation.cpp index 228d6a7d62..ad72c2ae49 100644 --- a/modules/base/translation/statictranslation.cpp +++ b/modules/base/translation/statictranslation.cpp @@ -49,14 +49,11 @@ documentation::Documentation StaticTranslation::Documentation() { } StaticTranslation::StaticTranslation() - : _position( - PositionInfo, - glm::dvec3(0.0), - glm::dvec3(-std::numeric_limits::max()), - glm::dvec3(std::numeric_limits::max()) - ) + : _position(PositionInfo, glm::dvec3(0.0), glm::dvec3(-1e35), glm::dvec3(1e35)) { - _position.setExponent(20.f); + // @TODO (2021-06-24, emmbr) The exponential sliders do not handle ranges with + // negative values very well. When they do, this line can be uncommented + //_position.setExponent(20.f); addProperty(_position); _position.onChange([this]() { diff --git a/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp b/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp index 4113d606ff..8b334a02e6 100644 --- a/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp +++ b/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp @@ -970,7 +970,7 @@ void RenderableBillboardsCloud::update(const UpdateData&) { _spriteTexture = DigitalUniverseModule::TextureManager.request( std::to_string(hash), [path = _spriteTexturePath]() -> std::unique_ptr { - LINFO(fmt::format("Loaded texture from '{}'", absPath(path))); + LINFO(fmt::format("Loaded texture from {}", absPath(path))); std::unique_ptr t = ghoul::io::TextureReader::ref().loadTexture(absPath(path).string()); t->uploadTexture(); diff --git a/modules/digitaluniverse/rendering/renderabledumeshes.cpp b/modules/digitaluniverse/rendering/renderabledumeshes.cpp index b7e0a708df..9fc7d78962 100644 --- a/modules/digitaluniverse/rendering/renderabledumeshes.cpp +++ b/modules/digitaluniverse/rendering/renderabledumeshes.cpp @@ -484,7 +484,7 @@ void RenderableDUMeshes::update(const UpdateData&) { bool RenderableDUMeshes::loadData() { bool success = false; if (_hasSpeckFile) { - LINFO(fmt::format("Loading Speck file '{}'", _speckFile)); + LINFO(fmt::format("Loading Speck file {}", std::filesystem::path(_speckFile))); success = readSpeckFile(); if (!success) { return false; @@ -502,7 +502,9 @@ bool RenderableDUMeshes::loadData() { bool RenderableDUMeshes::readSpeckFile() { std::ifstream file(_speckFile); if (!file.good()) { - LERROR(fmt::format("Failed to open Speck file '{}'", _speckFile)); + LERROR(fmt::format( + "Failed to open Speck file {}", std::filesystem::path(_speckFile) + )); return false; } diff --git a/modules/digitaluniverse/rendering/renderableplanescloud.cpp b/modules/digitaluniverse/rendering/renderableplanescloud.cpp index 1e54b6a7c7..18d0117607 100644 --- a/modules/digitaluniverse/rendering/renderableplanescloud.cpp +++ b/modules/digitaluniverse/rendering/renderableplanescloud.cpp @@ -272,7 +272,7 @@ RenderablePlanesCloud::RenderablePlanesCloud(const ghoul::Dictionary& dictionary addProperty(_opacity); if (p.file.has_value()) { - _speckFile = absPath(*p.file).string(); + _speckFile = absPath(*p.file); _hasSpeckFile = true; _drawElements.onChange([&]() { _hasSpeckFile = !_hasSpeckFile; }); addProperty(_drawElements); @@ -320,7 +320,7 @@ RenderablePlanesCloud::RenderablePlanesCloud(const ghoul::Dictionary& dictionary _scaleFactor.onChange([&]() { _dataIsDirty = true; }); if (p.labelFile.has_value()) { - _labelFile = absPath(*p.labelFile).string(); + _labelFile = absPath(*p.labelFile); _hasLabel = true; _textColor = p.textColor.value_or(_textColor); @@ -368,7 +368,7 @@ RenderablePlanesCloud::RenderablePlanesCloud(const ghoul::Dictionary& dictionary } } - _texturesPath = absPath(p.texturePath).string(); + _texturesPath = absPath(p.texturePath); _luminosityVar = p.luminosity.value_or(_luminosityVar); _sluminosity = p.scaleLuminosity.value_or(_sluminosity); @@ -403,7 +403,7 @@ void RenderablePlanesCloud::initialize() { } if (!_labelFile.empty()) { - LINFO(fmt::format("Loading Label file '{}'", _labelFile)); + LINFO(fmt::format("Loading Label file {}", _labelFile)); _labelset = speck::label::loadFileWithCache(_labelFile); for (speck::Labelset::Entry& e : _labelset.entries) { e.position = glm::vec3(_transformationMatrix * glm::dvec4(e.position, 1.0)); @@ -612,7 +612,7 @@ void RenderablePlanesCloud::update(const UpdateData&) { void RenderablePlanesCloud::loadTextures() { for (const speck::Dataset::Texture& tex : _dataset.textures) { - std::filesystem::path fullPath = absPath(_texturesPath + '/' + tex.file); + std::filesystem::path fullPath = absPath(_texturesPath.string() + '/' + tex.file); std::filesystem::path pngPath = fullPath; pngPath.replace_extension(".png"); @@ -634,7 +634,7 @@ void RenderablePlanesCloud::loadTextures() { ghoul::io::TextureReader::ref().loadTexture(path.string()); if (t) { - LINFOC("RenderablePlanesCloud", fmt::format("Loaded texture '{}'", path)); + LINFOC("RenderablePlanesCloud", fmt::format("Loaded texture {}", path)); t->uploadTexture(); t->setFilter(ghoul::opengl::Texture::FilterMode::LinearMipMap); t->purgeFromRAM(); diff --git a/modules/digitaluniverse/rendering/renderableplanescloud.h b/modules/digitaluniverse/rendering/renderableplanescloud.h index de2d2386cd..b669e1e168 100644 --- a/modules/digitaluniverse/rendering/renderableplanescloud.h +++ b/modules/digitaluniverse/rendering/renderableplanescloud.h @@ -34,10 +34,9 @@ #include #include #include - #include #include - +#include #include #include @@ -129,9 +128,9 @@ private: std::unordered_map _textureFileMap; std::unordered_map _planesMap; - std::string _speckFile; - std::string _labelFile; - std::string _texturesPath; + std::filesystem::path _speckFile; + std::filesystem::path _labelFile; + std::filesystem::path _texturesPath; std::string _luminosityVar; Unit _unit = Parsec; diff --git a/modules/digitaluniverse/rendering/renderablepoints.cpp b/modules/digitaluniverse/rendering/renderablepoints.cpp index 286e247d96..e3449d0095 100644 --- a/modules/digitaluniverse/rendering/renderablepoints.cpp +++ b/modules/digitaluniverse/rendering/renderablepoints.cpp @@ -135,7 +135,7 @@ RenderablePoints::RenderablePoints(const ghoul::Dictionary& dictionary) addProperty(_opacity); registerUpdateRenderBinFromOpacity(); - _speckFile = absPath(p.file).string(); + _speckFile = absPath(p.file); if (p.unit.has_value()) { switch (*p.unit) { @@ -185,7 +185,7 @@ RenderablePoints::RenderablePoints(const ghoul::Dictionary& dictionary) } if (p.colorMap.has_value()) { - _colorMapFile = absPath(*p.colorMap).string(); + _colorMapFile = absPath(*p.colorMap); _hasColorMapFile = true; } @@ -347,9 +347,9 @@ void RenderablePoints::update(const UpdateData&) { absPath(_spriteTexturePath).string() ); if (_spriteTexture) { - LDEBUG(fmt::format( - "Loaded texture from '{}'",absPath(_spriteTexturePath) - )); + LDEBUG( + fmt::format("Loaded texture from {}", absPath(_spriteTexturePath)) + ); _spriteTexture->uploadTexture(); } _spriteTexture->setFilter( @@ -369,7 +369,7 @@ void RenderablePoints::readColorMapFile() { std::ifstream file(_colorMapFile); if (!file.good()) { throw ghoul::RuntimeError(fmt::format( - "Failed to open Color Map file '{}'", _colorMapFile + "Failed to open Color Map file {}", _colorMapFile )); } @@ -396,7 +396,7 @@ void RenderablePoints::readColorMapFile() { } else if (file.eof()) { throw ghoul::RuntimeError(fmt::format( - "Failed to load colors from Color Map file '{}'", _colorMapFile + "Failed to load colors from Color Map file {}", _colorMapFile )); } } diff --git a/modules/digitaluniverse/rendering/renderablepoints.h b/modules/digitaluniverse/rendering/renderablepoints.h index 0f7c4f1361..2f8d3047b0 100644 --- a/modules/digitaluniverse/rendering/renderablepoints.h +++ b/modules/digitaluniverse/rendering/renderablepoints.h @@ -35,6 +35,7 @@ #include #include #include +#include namespace ghoul::filesystem { class File; } @@ -95,8 +96,8 @@ private: spriteTexture, hasColorMap ) _uniformCache; - std::string _speckFile; - std::string _colorMapFile; + std::filesystem::path _speckFile; + std::filesystem::path _colorMapFile; Unit _unit = Parsec; diff --git a/modules/exoplanets/exoplanetshelper.cpp b/modules/exoplanets/exoplanetshelper.cpp index f538f73f6f..6ec7f2866c 100644 --- a/modules/exoplanets/exoplanetshelper.cpp +++ b/modules/exoplanets/exoplanetshelper.cpp @@ -65,8 +65,7 @@ glm::vec3 computeStarColor(float bv) { if (!colorMap.good()) { LERROR(fmt::format( - "Failed to open colormap data file: '{}'", - absPath(bvColormapPath) + "Failed to open colormap data file: {}", absPath(bvColormapPath) )); return glm::vec3(0.f); } diff --git a/modules/exoplanets/exoplanetsmodule_lua.inl b/modules/exoplanets/exoplanetsmodule_lua.inl index 6ee47f1d7a..f5359e9dbe 100644 --- a/modules/exoplanets/exoplanetsmodule_lua.inl +++ b/modules/exoplanets/exoplanetsmodule_lua.inl @@ -158,8 +158,8 @@ void createExoplanetSystem(const std::string& starName) { const glm::vec3 starPosInParsec = system.starData.position; if (!isValidPosition(starPosInParsec)) { LERROR(fmt::format( - "Insufficient data available for exoplanet system: '{}'. " - "Could not determine star position", starName + "Insufficient data available for exoplanet system: '{}'. Could not determine " + "star position", starName )); return; } diff --git a/modules/fieldlinessequence/util/kameleonfieldlinehelper.cpp b/modules/fieldlinessequence/util/kameleonfieldlinehelper.cpp index 7b18d0579d..6646797433 100644 --- a/modules/fieldlinessequence/util/kameleonfieldlinehelper.cpp +++ b/modules/fieldlinessequence/util/kameleonfieldlinehelper.cpp @@ -303,8 +303,10 @@ void prepareStateAndKameleonForExtras(ccmc::Kameleon* kameleon, if (!success && (model == fls::Model::Batsrus && (str == TAsPOverRho || str == "T"))) { - LDEBUG("BATSRUS doesn't contain variable T for temperature. Trying to " - "calculate it using the ideal gas law: T = pressure/density"); + LDEBUG( + "BATSRUS doesn't contain variable T for temperature. Trying to calculate " + "it using the ideal gas law: T = pressure/density" + ); constexpr const char* p = "p"; constexpr const char* r = "rho"; success = kameleon->doesVariableExist(p) && kameleon->loadVariable(p) && @@ -312,9 +314,7 @@ void prepareStateAndKameleonForExtras(ccmc::Kameleon* kameleon, str = TAsPOverRho; } if (!success) { - LWARNING(fmt::format( - "Failed to load extra variable: '{}'. Ignoring", str - )); + LWARNING(fmt::format("Failed to load extra variable: '{}'. Ignoring", str)); extraScalarVars.erase(extraScalarVars.begin() + i); --i; } diff --git a/modules/fitsfilereader/include/fitsfilereader.h b/modules/fitsfilereader/include/fitsfilereader.h index 9418fc42fb..e3909d5f93 100644 --- a/modules/fitsfilereader/include/fitsfilereader.h +++ b/modules/fitsfilereader/include/fitsfilereader.h @@ -25,6 +25,7 @@ #ifndef __OPENSPACE_MODULE_FITSFILEREADER___FITSFILEREADER___H__ #define __OPENSPACE_MODULE_FITSFILEREADER___FITSFILEREADER___H__ +#include #include #include #include @@ -63,7 +64,7 @@ public: ~FitsFileReader(); template - std::shared_ptr> readImage(const std::string& path); + std::shared_ptr> readImage(const std::filesystem::path& path); template std::shared_ptr> readHeader( @@ -78,7 +79,7 @@ public: * If no HDU index is given the current Extension HDU will be read from. */ template - std::shared_ptr> readTable(std::string& path, + std::shared_ptr> readTable(const std::filesystem::path& path, const std::vector& columnNames, int startRow = 1, int endRow = 10, int hduIdx = 1, bool readAll = false); @@ -88,7 +89,7 @@ public: * If additional columns are given by filterColumnNames, they will be * read but it will slow doen the reading tremendously. */ - std::vector readFitsFile(std::string filePath, int& nValuesPerStar, + std::vector readFitsFile(std::filesystem::path filePath, int& nValuesPerStar, int firstRow, int lastRow, std::vector filterColumnNames, int multiplier = 1); @@ -96,7 +97,8 @@ public: * Reads a single SPECK file and returns a vector with nRenderValues * per star. Reads data in pre-defined order based on AMNH's star data files. */ - std::vector readSpeckFile(const std::string& filePath, int& nRenderValues); + std::vector readSpeckFile(const std::filesystem::path& filePath, + int& nRenderValues); private: std::unique_ptr _infile; diff --git a/modules/fitsfilereader/src/fitsfilereader.cpp b/modules/fitsfilereader/src/fitsfilereader.cpp index 26e945fad3..f273326e82 100644 --- a/modules/fitsfilereader/src/fitsfilereader.cpp +++ b/modules/fitsfilereader/src/fitsfilereader.cpp @@ -69,7 +69,8 @@ bool FitsFileReader::isPrimaryHDU() { } template -std::shared_ptr> FitsFileReader::readImage(const std::string& path) { +std::shared_ptr> FitsFileReader::readImage(const std::filesystem::path& path) +{ try { _infile = std::make_unique(path, Read, true); // Primary HDU Object @@ -136,7 +137,7 @@ std::shared_ptr FitsFileReader::readHeaderValue(const std::string key) { } template -std::shared_ptr> FitsFileReader::readTable(std::string& path, +std::shared_ptr> FitsFileReader::readTable(const std::filesystem::path& path, const std::vector& columnNames, int startRow, int endRow, @@ -148,7 +149,7 @@ std::shared_ptr> FitsFileReader::readTable(std::string& path, std::lock_guard g(_mutex); try { - _infile = std::make_unique(path, Read, readAll); + _infile = std::make_unique(path.string(), Read, readAll); // Make sure FITS file is not a Primary HDU Object (aka an image). if (!isPrimaryHDU()) { @@ -191,8 +192,9 @@ std::shared_ptr> FitsFileReader::readTable(std::string& path, return nullptr; } -std::vector FitsFileReader::readFitsFile(std::string filePath, int& nValuesPerStar, - int firstRow, int lastRow, +std::vector FitsFileReader::readFitsFile(std::filesystem::path filePath, + int& nValuesPerStar, int firstRow, + int lastRow, std::vector filterColumnNames, int multiplier) { @@ -245,7 +247,7 @@ std::vector FitsFileReader::readFitsFile(std::string filePath, int& nValu ); if (!table) { - throw ghoul::RuntimeError(fmt::format("Failed to open Fits file '{}'", filePath)); + throw ghoul::RuntimeError(fmt::format("Failed to open Fits file {}", filePath)); } int nStars = table->readRows - firstRow + 1; @@ -520,7 +522,7 @@ std::vector FitsFileReader::readFitsFile(std::string filePath, int& nValu return fullData; } -std::vector FitsFileReader::readSpeckFile(const std::string& filePath, +std::vector FitsFileReader::readSpeckFile(const std::filesystem::path& filePath, int& nRenderValues) { std::vector fullData; @@ -528,7 +530,7 @@ std::vector FitsFileReader::readSpeckFile(const std::string& filePath, std::ifstream fileStream(filePath); if (!fileStream.good()) { - LERROR(fmt::format("Failed to open Speck file '{}'", filePath)); + LERROR(fmt::format("Failed to open Speck file {}", filePath)); return fullData; } diff --git a/modules/gaia/rendering/renderablegaiastars.cpp b/modules/gaia/rendering/renderablegaiastars.cpp index 2971318b53..44e8d3f579 100644 --- a/modules/gaia/rendering/renderablegaiastars.cpp +++ b/modules/gaia/rendering/renderablegaiastars.cpp @@ -2131,9 +2131,7 @@ void RenderableGaiaStars::update(const UpdateData&) { absPath(_colorTexturePath).string() ); if (_colorTexture) { - LDEBUG(fmt::format( - "Loaded texture from '{}'", absPath(_colorTexturePath) - )); + LDEBUG(fmt::format("Loaded texture from {}", absPath(_colorTexturePath))); _colorTexture->uploadTexture(); } @@ -2188,28 +2186,29 @@ bool RenderableGaiaStars::readDataFile() { _octreeManager.initOctree(_cpuRamBudgetInBytes); - LINFO("Loading data file: " + _filePath.value()); + std::filesystem::path file = absPath(_filePath.value()); + LINFO(fmt::format("Loading data file: {}", file)); switch (fileReaderOption) { case gaia::FileReaderOption::Fits: // Read raw fits file and construct Octree. - nReadStars = readFitsFile(_filePath); + nReadStars = readFitsFile(file); break; case gaia::FileReaderOption::Speck: // Read raw speck file and construct Octree. - nReadStars = readSpeckFile(_filePath); + nReadStars = readSpeckFile(file); break; case gaia::FileReaderOption::BinaryRaw: // Stars are stored in an ordered binary file. - nReadStars = readBinaryRawFile(_filePath); + nReadStars = readBinaryRawFile(file); break; case gaia::FileReaderOption::BinaryOctree: // Octree already constructed and stored as a binary file. - nReadStars = readBinaryOctreeFile(_filePath); + nReadStars = readBinaryOctreeFile(file); break; case gaia::FileReaderOption::StreamOctree: // Read Octree structure from file, without data. - nReadStars = readBinaryOctreeStructureFile(_filePath); + nReadStars = readBinaryOctreeStructureFile(file.string()); break; default: LERROR("Wrong FileReaderOption - no data file loaded!"); @@ -2218,13 +2217,13 @@ bool RenderableGaiaStars::readDataFile() { //_octreeManager->printStarsPerNode(); _nRenderedStars.setMaxValue(nReadStars); - LINFO("Dataset contains a total of " + std::to_string(nReadStars) + " stars."); + LINFO(fmt::format("Dataset contains a total of {} stars", nReadStars)); _totalDatasetSizeInBytes = nReadStars * (PositionSize + ColorSize + VelocitySize) * 4; return nReadStars > 0; } -int RenderableGaiaStars::readFitsFile(const std::string& filePath) { +int RenderableGaiaStars::readFitsFile(const std::filesystem::path& filePath) { int nReadValuesPerStar = 0; FitsFileReader fitsFileReader(false); @@ -2248,7 +2247,7 @@ int RenderableGaiaStars::readFitsFile(const std::string& filePath) { return static_cast(fullData.size() / nReadValuesPerStar); } -int RenderableGaiaStars::readSpeckFile(const std::string& filePath) { +int RenderableGaiaStars::readSpeckFile(const std::filesystem::path& filePath) { int nReadValuesPerStar = 0; FitsFileReader fileReader(false); @@ -2266,7 +2265,7 @@ int RenderableGaiaStars::readSpeckFile(const std::string& filePath) { return static_cast(fullData.size() / nReadValuesPerStar); } -int RenderableGaiaStars::readBinaryRawFile(const std::string& filePath) { +int RenderableGaiaStars::readBinaryRawFile(const std::filesystem::path& filePath) { std::vector fullData; int nReadStars = 0; @@ -2299,14 +2298,14 @@ int RenderableGaiaStars::readBinaryRawFile(const std::string& filePath) { } else { LERROR(fmt::format( - "Error opening file '{}' for loading raw binary file!", filePath + "Error opening file '{}' for loading raw binary file", filePath )); return nReadStars; } return nReadStars; } -int RenderableGaiaStars::readBinaryOctreeFile(const std::string& filePath) { +int RenderableGaiaStars::readBinaryOctreeFile(const std::filesystem::path& filePath) { int nReadStars = 0; std::ifstream fileStream(filePath, std::ifstream::binary); @@ -2317,26 +2316,28 @@ int RenderableGaiaStars::readBinaryOctreeFile(const std::string& filePath) { } else { LERROR(fmt::format( - "Error opening file '{}' for loading binary Octree file!", filePath + "Error opening file '{}' for loading binary Octree file", filePath )); return nReadStars; } return nReadStars; } -int RenderableGaiaStars::readBinaryOctreeStructureFile(const std::string& folderPath) { +int RenderableGaiaStars::readBinaryOctreeStructureFile( + const std::filesystem::path& folderPath) +{ int nReadStars = 0; - std::string indexFile = folderPath + "index.bin"; + std::string indexFile = folderPath.string() + "index.bin"; std::ifstream fileStream(indexFile, std::ifstream::binary); if (fileStream.good()) { - nReadStars = _octreeManager.readFromFile(fileStream, false, folderPath); + nReadStars = _octreeManager.readFromFile(fileStream, false, folderPath.string()); fileStream.close(); } else { LERROR(fmt::format( - "Error opening file '{}' for loading binary Octree file!", indexFile + "Error opening file '{}' for loading binary Octree file", indexFile )); return nReadStars; } diff --git a/modules/gaia/rendering/renderablegaiastars.h b/modules/gaia/rendering/renderablegaiastars.h index 09508f0e94..cda54a9772 100644 --- a/modules/gaia/rendering/renderablegaiastars.h +++ b/modules/gaia/rendering/renderablegaiastars.h @@ -78,28 +78,28 @@ private: * * \return the number of stars read. */ - int readFitsFile(const std::string& filePath); + int readFitsFile(const std::filesystem::path& filePath); /** * Read a SPECK file by using FitsFileReader.readSpeckFile() and constructs an octree. * * \return the number of stars read. */ - int readSpeckFile(const std::string& filePath); + int readSpeckFile(const std::filesystem::path& filePath); /** * Reads a preprocessed binary file and constructs an octree. * * \return the number of stars read. */ - int readBinaryRawFile(const std::string& filePath); + int readBinaryRawFile(const std::filesystem::path& filePath); /** * Reads a pre-constructed octree, with all data, from a binary file. * * \return the number of stars read. */ - int readBinaryOctreeFile(const std::string& filePath); + int readBinaryOctreeFile(const std::filesystem::path& filePath); /** * Reads the structure of a pre-constructed octree from a binary file, without any @@ -107,7 +107,7 @@ private: * * \return the number of stars read. */ - int readBinaryOctreeStructureFile(const std::string& folderPath); + int readBinaryOctreeStructureFile(const std::filesystem::path& folderPath); /** * Checks for any OpenGL errors and reports these to the log if _reportGlErrors is diff --git a/modules/gaia/tasks/readfilejob.cpp b/modules/gaia/tasks/readfilejob.cpp index 12e0ea1b08..b2cb6030fa 100644 --- a/modules/gaia/tasks/readfilejob.cpp +++ b/modules/gaia/tasks/readfilejob.cpp @@ -68,8 +68,10 @@ void ReadFileJob::execute() { int nNullArr = 0; size_t nColumnsRead = _allColumns.size(); if (nColumnsRead != _nDefaultCols) { - LINFO("Additional columns will be read! Consider add column in code for " - "significant speedup!"); + LINFO( + "Additional columns will be read! Consider add column in code for " + "significant speedup" + ); } // Copy columns to local variables. diff --git a/modules/galaxy/rendering/renderablegalaxy.cpp b/modules/galaxy/rendering/renderablegalaxy.cpp index 6cb9da54ee..062cab243d 100644 --- a/modules/galaxy/rendering/renderablegalaxy.cpp +++ b/modules/galaxy/rendering/renderablegalaxy.cpp @@ -182,14 +182,15 @@ namespace { #include "renderablegalaxy_codegen.cpp" - void saveCachedFile(const std::string& file, const std::vector& positions, + void saveCachedFile(const std::filesystem::path& file, + const std::vector& positions, const std::vector& colors, int64_t nPoints, float pointsRatio) { std::ofstream fileStream(file, std::ofstream::binary); if (!fileStream.good()) { - LERROR(fmt::format("Error opening file '{}' for save cache file", file)); + LERROR(fmt::format("Error opening file {} for save cache file", file)); return; } @@ -321,13 +322,13 @@ void RenderableGalaxy::initialize() { ); _volume = reader.read(); - std::string cachedPointsFile = FileSys.cacheManager()->cachedFilename( + std::filesystem::path cachedPointsFile = FileSys.cacheManager()->cachedFilename( _pointsFilename ); const bool hasCachedFile = std::filesystem::is_regular_file(cachedPointsFile); if (hasCachedFile) { - LINFO(fmt::format("Cached file '{}' used for galaxy point file '{}'", - cachedPointsFile, _pointsFilename + LINFO(fmt::format("Cached file {} used for galaxy point file {}", + cachedPointsFile, std::filesystem::path(_pointsFilename) )); Result res = loadCachedFile(cachedPointsFile); @@ -730,17 +731,19 @@ RenderableGalaxy::Result RenderableGalaxy::loadPointFile() { return res; } -RenderableGalaxy::Result RenderableGalaxy::loadCachedFile(const std::string& file) { +RenderableGalaxy::Result RenderableGalaxy::loadCachedFile( + const std::filesystem::path& file) +{ std::ifstream fileStream(file, std::ifstream::binary); if (!fileStream.good()) { - LERROR(fmt::format("Error opening file '{}' for loading cache file", file)); + LERROR(fmt::format("Error opening file {} for loading cache file", file)); return { false, {}, {} }; } int8_t cacheVersion; fileStream.read(reinterpret_cast(&cacheVersion), sizeof(int8_t)); if (cacheVersion != CurrentCacheVersion) { - LINFO(fmt::format("Removing cache file '{}' as the version changed")); + LINFO(fmt::format("Removing cache file {} as the version changed", file)); return { false, {}, {} }; } diff --git a/modules/galaxy/rendering/renderablegalaxy.h b/modules/galaxy/rendering/renderablegalaxy.h index 45dbcd1df7..55c3b4cbba 100644 --- a/modules/galaxy/rendering/renderablegalaxy.h +++ b/modules/galaxy/rendering/renderablegalaxy.h @@ -64,7 +64,7 @@ private: std::vector color; }; Result loadPointFile(); - Result loadCachedFile(const std::string& file); + Result loadCachedFile(const std::filesystem::path& file); glm::vec3 _volumeSize = glm::vec3(0.f); glm::vec3 _pointScaling = glm::vec3(0.f); diff --git a/modules/globebrowsing/globebrowsingmodule.cpp b/modules/globebrowsing/globebrowsingmodule.cpp index 04ea8b7693..1b74145d82 100644 --- a/modules/globebrowsing/globebrowsingmodule.cpp +++ b/modules/globebrowsing/globebrowsingmodule.cpp @@ -413,20 +413,22 @@ scripting::LuaLibrary GlobeBrowsingModule::luaLibrary() const { "The last (optional) parameter is a duration for the motion" }, { - "getGeoPosition", - &globebrowsing::luascriptfunctions::getGeoPosition, + "getLocalPositionFromGeo", + &globebrowsing::luascriptfunctions::getLocalPositionFromGeo, {}, "string, number, number, number", - "Returns the specified surface position on the globe identified by the first " - "argument, as three floating point values - latitude, longitude and altitude " - "(degrees and meters)." + "Returns a position in the local Cartesian coordinate system of the globe " + "identified by the first argument, that corresponds to the given geographic " + "coordinates: latitude, longitude and altitude (in degrees and meters). In " + "the local coordinate system, the position (0,0,0) corresponds to the " + "globe's center." }, { "getGeoPositionForCamera", &globebrowsing::luascriptfunctions::getGeoPositionForCamera, {}, "void", - "Get geographic coordinates of the camera poosition in latitude, " + "Get geographic coordinates of the camera position in latitude, " "longitude, and altitude (degrees and meters)." }, { diff --git a/modules/globebrowsing/globebrowsingmodule_lua.inl b/modules/globebrowsing/globebrowsingmodule_lua.inl index eed4aad9b4..7ec89704df 100644 --- a/modules/globebrowsing/globebrowsingmodule_lua.inl +++ b/modules/globebrowsing/globebrowsingmodule_lua.inl @@ -363,8 +363,8 @@ int flyToGeo(lua_State* L) { return 0; } -int getGeoPosition(lua_State* L) { - ghoul::lua::checkArgumentsAndThrow(L, 4, "lua::getGeoPosition"); +int getLocalPositionFromGeo(lua_State* L) { + ghoul::lua::checkArgumentsAndThrow(L, 4, "lua::getLocalPositionFromGeo"); const std::string& globeIdentifier = ghoul::lua::value(L, 1); const double latitude = ghoul::lua::value(L, 2); diff --git a/modules/globebrowsing/scripts/layer_support.lua b/modules/globebrowsing/scripts/layer_support.lua index 82678d901c..0d3b94cc85 100644 --- a/modules/globebrowsing/scripts/layer_support.lua +++ b/modules/globebrowsing/scripts/layer_support.lua @@ -315,24 +315,25 @@ openspace.globebrowsing.addFocusNodesFromDirectory = function (dir, node_name) if file and file:find('.info') then local t = openspace.globebrowsing.parseInfoFile(file) - if t.Node and t.Location then - openspace.printInfo("Creating focus node for '" .. n .. "'") + if node_name and t.Location then + openspace.printInfo("Creating focus node for '" .. node_name .. "'") - local lat = t.Location.Center[2] - local long = t.Location.Center[1] - local a, b, c = openspace.globebrowsing.getGeoPosition(node_name, lat, long, 0.0) - local p = { a, b, c } + local lat = t.Location.Center[1] + local long = t.Location.Center[2] local identifier = node_name .. " - " .. t.Identifier - local name = node_name .. " - " .. t.Node + local name = node_name .. " - " .. t.Name openspace.addSceneGraphNode({ Identifier = identifier, Parent = node_name, Transform = { Translation = { - Type = "StaticTranslation", - Position = { p[1], p[2], p[3] } + Type = "GlobeTranslation", + Globe = node_name, + Latitude = lat, + Longitude = long, + UseHeightmap = true } }, GUI = { @@ -348,8 +349,6 @@ end openspace.globebrowsing.addFocusNodeFromLatLong = function (name, globe_identifier, lat, long, altitude) altitude = altitude or 0; - local a, b, c = openspace.globebrowsing.getGeoPosition(globe_identifier, lat, long, altitude) - local p = { a, b, c } local identifier = globe_identifier .. "-" .. name openspace.addSceneGraphNode({ diff --git a/modules/globebrowsing/src/globelabelscomponent.cpp b/modules/globebrowsing/src/globelabelscomponent.cpp index 5a8da230fd..ed3548ba9d 100644 --- a/modules/globebrowsing/src/globelabelscomponent.cpp +++ b/modules/globebrowsing/src/globelabelscomponent.cpp @@ -306,15 +306,15 @@ void GlobeLabelsComponent::initializeFonts() { ); } -bool GlobeLabelsComponent::loadLabelsData(const std::string& file) { - std::string cachedFile = FileSys.cacheManager()->cachedFilename( +bool GlobeLabelsComponent::loadLabelsData(const std::filesystem::path& file) { + std::filesystem::path cachedFile = FileSys.cacheManager()->cachedFilename( file, "GlobeLabelsComponent|" + identifier() ); bool hasCachedFile = std::filesystem::is_regular_file(cachedFile); if (hasCachedFile) { - LINFO(fmt::format("Cached file '{}' used for labels file: {}", cachedFile, file)); + LINFO(fmt::format("Cached file {} used for labels file {}", cachedFile, file)); const bool hasCache = loadCachedFile(cachedFile); if (hasCache) { @@ -327,9 +327,9 @@ bool GlobeLabelsComponent::loadLabelsData(const std::string& file) { } } else { - LINFO(fmt::format("Cache for labels file '{}' not found", file)); + LINFO(fmt::format("Cache for labels file {} not found", file)); } - LINFO(fmt::format("Loading labels file '{}'", file)); + LINFO(fmt::format("Loading labels file {}", file)); bool success = readLabelsFile(file); if (success) { @@ -338,11 +338,11 @@ bool GlobeLabelsComponent::loadLabelsData(const std::string& file) { return success; } -bool GlobeLabelsComponent::readLabelsFile(const std::string& file) { +bool GlobeLabelsComponent::readLabelsFile(const std::filesystem::path& file) { try { std::fstream csvLabelFile(file); if (!csvLabelFile.good()) { - LERROR(fmt::format("Failed to open labels file '{}'", file)); + LERROR(fmt::format("Failed to open labels file {}", file)); return false; } if (!csvLabelFile.is_open()) { @@ -427,16 +427,16 @@ bool GlobeLabelsComponent::readLabelsFile(const std::string& file) { return true; } catch (const std::fstream::failure& e) { - LERROR(fmt::format("Failed reading labels file '{}'", file)); + LERROR(fmt::format("Failed reading labels file {}", file)); LERROR(e.what()); return false; } } -bool GlobeLabelsComponent::loadCachedFile(const std::string& file) { +bool GlobeLabelsComponent::loadCachedFile(const std::filesystem::path& file) { std::ifstream fileStream(file, std::ifstream::binary); if (!fileStream.good()) { - LERROR(fmt::format("Error opening file '{}' for loading cache file", file)); + LERROR(fmt::format("Error opening file {} for loading cache file", file)); return false; } @@ -463,10 +463,10 @@ bool GlobeLabelsComponent::loadCachedFile(const std::string& file) { return fileStream.good(); } -bool GlobeLabelsComponent::saveCachedFile(const std::string& file) const { +bool GlobeLabelsComponent::saveCachedFile(const std::filesystem::path& file) const { std::ofstream fileStream(file, std::ofstream::binary); if (!fileStream.good()) { - LERROR(fmt::format("Error opening file '{}' for save cache file", file)); + LERROR(fmt::format("Error opening file {} for save cache file", file)); return false; } fileStream.write(reinterpret_cast(&CurrentCacheVersion), sizeof(int8_t)); diff --git a/modules/globebrowsing/src/globelabelscomponent.h b/modules/globebrowsing/src/globelabelscomponent.h index a14ede7078..0cfa277558 100644 --- a/modules/globebrowsing/src/globelabelscomponent.h +++ b/modules/globebrowsing/src/globelabelscomponent.h @@ -62,10 +62,10 @@ public: void draw(const RenderData& data); private: - bool loadLabelsData(const std::string& file); - bool readLabelsFile(const std::string& file); - bool loadCachedFile(const std::string& file); - bool saveCachedFile(const std::string& file) const; + bool loadLabelsData(const std::filesystem::path& file); + bool readLabelsFile(const std::filesystem::path& file); + bool loadCachedFile(const std::filesystem::path& file); + bool saveCachedFile(const std::filesystem::path& file) const; void renderLabels(const RenderData& data, const glm::dmat4& modelViewProjectionMatrix, float distToCamera, float fadeInVariable); bool isLabelInFrustum(const glm::dmat4& MVMatrix, const glm::dvec3& position) const; diff --git a/modules/globebrowsing/src/globetranslation.cpp b/modules/globebrowsing/src/globetranslation.cpp index d1097c35de..ff902b8f67 100644 --- a/modules/globebrowsing/src/globetranslation.cpp +++ b/modules/globebrowsing/src/globetranslation.cpp @@ -125,6 +125,7 @@ GlobeTranslation::GlobeTranslation(const ghoul::Dictionary& dictionary) addProperty(_latitude); _altitude = p.altitude.value_or(_altitude); + _altitude.setExponent(8.f); _altitude.onChange([this]() { _positionIsDirty = true; }); addProperty(_altitude); diff --git a/modules/globebrowsing/src/renderableglobe.cpp b/modules/globebrowsing/src/renderableglobe.cpp index fdfef77894..b36fab95eb 100644 --- a/modules/globebrowsing/src/renderableglobe.cpp +++ b/modules/globebrowsing/src/renderableglobe.cpp @@ -179,6 +179,14 @@ namespace { "Enables shadow mapping algorithm. Used by renderable rings too." }; + constexpr openspace::properties::Property::PropertyInfo RenderAtDistanceInfo = { + "RenderAtDistance", + "Render at Distance", + "Tells the rendering engine not to perform distance based performance culling " + "for this globe. Turning this property on will let the globe to be seen at far " + "away distances when normally it would be hidden." + }; + constexpr openspace::properties::Property::PropertyInfo ZFightingPercentageInfo = { "ZFightingPercentage", "Z-Fighting Percentage", @@ -230,6 +238,9 @@ namespace { // not. If it is disabled, all parts of the planet are illuminated std::optional performShading; + // Specifies if distance culling should be disabled. + std::optional renderAtDistance; + // A list of all the layers that should be added std::map layers [[codegen::reference("globebrowsing_layermanager")]]; @@ -508,6 +519,7 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) BoolProperty(EclipseInfo, false), BoolProperty(EclipseHardShadowsInfo, false), BoolProperty(ShadowMappingInfo, false), + BoolProperty(RenderAtDistanceInfo, false), FloatProperty(ZFightingPercentageInfo, 0.995f, 0.000001f, 1.f), IntProperty(NumberShadowSamplesInfo, 5, 1, 7), FloatProperty(TargetLodScaleFactorInfo, 15.f, 1.f, 50.f), @@ -549,6 +561,8 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) _generalProperties.performShading = p.performShading.value_or(_generalProperties.performShading); + _generalProperties.renderAtDistance = + p.renderAtDistance.value_or(_generalProperties.renderAtDistance); // Init layer manager // @TODO (abock, 2021-03-25) The layermanager should be changed to take a @@ -560,6 +574,7 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) addProperty(_opacity); addProperty(_generalProperties.performShading); addProperty(_generalProperties.useAccurateNormals); + addProperty(_generalProperties.renderAtDistance); if (p.shadowGroup.has_value()) { std::vector shadowConfArray; @@ -711,7 +726,7 @@ void RenderableGlobe::render(const RenderData& data, RendererTasks& rendererTask constexpr int res = 2880; const double distance = res * boundingSphere() / tfov; - if (distanceToCamera < distance) { + if ((distanceToCamera < distance) || (_generalProperties.renderAtDistance)) { try { // Before Shadows _globeLabelsComponent.draw(data); diff --git a/modules/globebrowsing/src/renderableglobe.h b/modules/globebrowsing/src/renderableglobe.h index 35247cefe7..0c0e16a63a 100644 --- a/modules/globebrowsing/src/renderableglobe.h +++ b/modules/globebrowsing/src/renderableglobe.h @@ -135,6 +135,7 @@ private: properties::BoolProperty eclipseShadowsEnabled; properties::BoolProperty eclipseHardShadows; properties::BoolProperty shadowMapping; + properties::BoolProperty renderAtDistance; properties::FloatProperty zFightingPercentage; properties::IntProperty nShadowSamples; properties::FloatProperty targetLodScaleFactor; diff --git a/modules/globebrowsing/src/ringscomponent.cpp b/modules/globebrowsing/src/ringscomponent.cpp index 129fd9bf76..b04cf026ca 100644 --- a/modules/globebrowsing/src/ringscomponent.cpp +++ b/modules/globebrowsing/src/ringscomponent.cpp @@ -620,7 +620,7 @@ void RingsComponent::loadTexture() { if (texture) { LDEBUGC( "RingsComponent", - fmt::format("Loaded texture from '{}'", absPath(_texturePath)) + fmt::format("Loaded texture from {}", absPath(_texturePath)) ); _texture = std::move(texture); @@ -643,7 +643,7 @@ void RingsComponent::loadTexture() { LDEBUGC( "RingsComponent", fmt::format( - "Loaded forwards scattering texture from '{}'", + "Loaded forwards scattering texture from {}", absPath(_textureFwrdPath) ) ); @@ -669,7 +669,7 @@ void RingsComponent::loadTexture() { LDEBUGC( "RingsComponent", fmt::format( - "Loaded backwards scattering texture from '{}'", + "Loaded backwards scattering texture from {}", absPath(_textureBckwrdPath) ) ); @@ -694,10 +694,7 @@ void RingsComponent::loadTexture() { if (textureUnlit) { LDEBUGC( "RingsComponent", - fmt::format( - "Loaded unlit texture from '{}'", - absPath(_textureUnlitPath) - ) + fmt::format("Loaded unlit texture from {}", absPath(_textureUnlitPath)) ); _textureUnlit = std::move(textureUnlit); @@ -719,10 +716,7 @@ void RingsComponent::loadTexture() { if (textureColor) { LDEBUGC( "RingsComponent", - fmt::format( - "Loaded color texture from '{}'", - absPath(_textureColorPath) - ) + fmt::format("Loaded color texture from {}", absPath(_textureColorPath)) ); _textureColor = std::move(textureColor); @@ -744,10 +738,7 @@ void RingsComponent::loadTexture() { if (textureTransparency) { LDEBUGC( "RingsComponent", - fmt::format( - "Loaded unlit texture from '{}'", - absPath(_textureUnlitPath) - ) + fmt::format("Loaded unlit texture from {}", absPath(_textureUnlitPath)) ); _textureTransparency = std::move(textureTransparency); diff --git a/modules/imgui/src/gui.cpp b/modules/imgui/src/gui.cpp index 1329d52063..ff6e488acc 100644 --- a/modules/imgui/src/gui.cpp +++ b/modules/imgui/src/gui.cpp @@ -204,17 +204,17 @@ void GUI::deinitialize() { } void GUI::initializeGL() { - std::string cachedFile = FileSys.cacheManager()->cachedFilename( + std::filesystem::path cachedFile = FileSys.cacheManager()->cachedFilename( configurationFile, "" ); LDEBUG(fmt::format("Using {} as ImGUI cache location", cachedFile)); - iniFileBuffer = new char[cachedFile.size() + 1]; + iniFileBuffer = new char[cachedFile.string().size() + 1]; #ifdef WIN32 - strcpy_s(iniFileBuffer, cachedFile.size() + 1, cachedFile.c_str()); + strcpy_s(iniFileBuffer, cachedFile.string().size() + 1, cachedFile.string().c_str()); #else strcpy(iniFileBuffer, cachedFile.c_str()); #endif diff --git a/modules/kameleonvolume/rendering/renderablekameleonvolume.cpp b/modules/kameleonvolume/rendering/renderablekameleonvolume.cpp index 2e8ad45922..dde78c643c 100644 --- a/modules/kameleonvolume/rendering/renderablekameleonvolume.cpp +++ b/modules/kameleonvolume/rendering/renderablekameleonvolume.cpp @@ -332,7 +332,7 @@ void RenderableKameleonVolume::load() { loadFromPath(_sourcePath); return; } - std::string cachePath = FileSys.cacheManager()->cachedFilename( + std::filesystem::path cachePath = FileSys.cacheManager()->cachedFilename( std::filesystem::path(_sourcePath.value()).stem(), cacheSuffix() ); @@ -360,7 +360,7 @@ void RenderableKameleonVolume::loadFromPath(const std::string& path) { } } -void RenderableKameleonVolume::loadRaw(const std::string& path) { +void RenderableKameleonVolume::loadRaw(const std::filesystem::path& path) { volume::RawVolumeReader reader(path, _dimensions); _rawVolume = reader.read(); updateTextureFromVolume(); @@ -433,7 +433,7 @@ void RenderableKameleonVolume::updateTextureFromVolume() { _volumeTexture->setPixelData(data, ghoul::opengl::Texture::TakeOwnership::No); } -void RenderableKameleonVolume::storeRaw(const std::string& path) { +void RenderableKameleonVolume::storeRaw(const std::filesystem::path& path) { volume::RawVolumeWriter writer(path); writer.write(*_rawVolume); } diff --git a/modules/kameleonvolume/rendering/renderablekameleonvolume.h b/modules/kameleonvolume/rendering/renderablekameleonvolume.h index e4eacd4647..700559c688 100644 --- a/modules/kameleonvolume/rendering/renderablekameleonvolume.h +++ b/modules/kameleonvolume/rendering/renderablekameleonvolume.h @@ -62,9 +62,9 @@ public: private: void load(); void loadFromPath(const std::string& path); - void loadRaw(const std::string& path); + void loadRaw(const std::filesystem::path& path); void loadCdf(const std::string& path); - void storeRaw(const std::string& path); + void storeRaw(const std::filesystem::path& path); std::string cacheSuffix() const; void updateTextureFromVolume(); diff --git a/modules/multiresvolume/rendering/errorhistogrammanager.cpp b/modules/multiresvolume/rendering/errorhistogrammanager.cpp index 3f4824ba65..d7517e797c 100644 --- a/modules/multiresvolume/rendering/errorhistogrammanager.cpp +++ b/modules/multiresvolume/rendering/errorhistogrammanager.cpp @@ -179,7 +179,7 @@ bool ErrorHistogramManager::buildFromLeaf(unsigned int bstOffset, return true; } -bool ErrorHistogramManager::loadFromFile(const std::string& filename) { +bool ErrorHistogramManager::loadFromFile(const std::filesystem::path& filename) { std::ifstream file(filename, std::ios::in | std::ios::binary); if (!file.is_open()) { return false; @@ -210,7 +210,7 @@ bool ErrorHistogramManager::loadFromFile(const std::string& filename) { } -bool ErrorHistogramManager::saveToFile(const std::string& filename) { +bool ErrorHistogramManager::saveToFile(const std::filesystem::path& filename) { std::ofstream file(filename, std::ios::out | std::ios::binary); if (!file.is_open()) { return false; diff --git a/modules/multiresvolume/rendering/errorhistogrammanager.h b/modules/multiresvolume/rendering/errorhistogrammanager.h index 31dc829bf5..00ec8af043 100644 --- a/modules/multiresvolume/rendering/errorhistogrammanager.h +++ b/modules/multiresvolume/rendering/errorhistogrammanager.h @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -42,8 +43,8 @@ public: bool buildHistograms(int numBins); const Histogram* histogram(unsigned int brickIndex) const; - bool loadFromFile(const std::string& filename); - bool saveToFile(const std::string& filename); + bool loadFromFile(const std::filesystem::path& filename); + bool saveToFile(const std::filesystem::path& filename); private: TSP* _tsp; diff --git a/modules/multiresvolume/rendering/histogrammanager.cpp b/modules/multiresvolume/rendering/histogrammanager.cpp index cc3293e253..e32383669e 100644 --- a/modules/multiresvolume/rendering/histogrammanager.cpp +++ b/modules/multiresvolume/rendering/histogrammanager.cpp @@ -121,7 +121,7 @@ std::vector HistogramManager::readValues(TSP* tsp, unsigned int brickInde return voxelValues; } -bool HistogramManager::loadFromFile(const std::string& filename) { +bool HistogramManager::loadFromFile(const std::filesystem::path& filename) { std::ifstream file(filename, std::ios::in | std::ios::binary); if (!file.is_open()) { return false; @@ -151,7 +151,7 @@ bool HistogramManager::loadFromFile(const std::string& filename) { return true; } -bool HistogramManager::saveToFile(const std::string& filename) { +bool HistogramManager::saveToFile(const std::filesystem::path& filename) { std::ofstream file(filename, std::ios::out | std::ios::binary); if (!file.is_open()) { return false; diff --git a/modules/multiresvolume/rendering/histogrammanager.h b/modules/multiresvolume/rendering/histogrammanager.h index 2cda97e5e7..ab7aefbee7 100644 --- a/modules/multiresvolume/rendering/histogrammanager.h +++ b/modules/multiresvolume/rendering/histogrammanager.h @@ -26,6 +26,7 @@ #define __OPENSPACE_MODULE_MULTIRESVOLUME___HISTOGRAMMANAGER___H__ #include +#include #include namespace openspace { @@ -36,8 +37,8 @@ class HistogramManager { public: bool buildHistograms(TSP* tsp, int numBins); Histogram* histogram(unsigned int brickIndex); - bool loadFromFile(const std::string& filename); - bool saveToFile(const std::string& filename); + bool loadFromFile(const std::filesystem::path& filename); + bool saveToFile(const std::filesystem::path& filename); private: bool buildHistogram(TSP* tsp, unsigned int brickIndex); diff --git a/modules/multiresvolume/rendering/localerrorhistogrammanager.cpp b/modules/multiresvolume/rendering/localerrorhistogrammanager.cpp index c13500c7fd..461fd4f983 100644 --- a/modules/multiresvolume/rendering/localerrorhistogrammanager.cpp +++ b/modules/multiresvolume/rendering/localerrorhistogrammanager.cpp @@ -305,7 +305,7 @@ bool LocalErrorHistogramManager::buildFromBstChild(unsigned int bstOffset, return true; } -bool LocalErrorHistogramManager::loadFromFile(const std::string& filename) { +bool LocalErrorHistogramManager::loadFromFile(const std::filesystem::path& filename) { std::ifstream file(filename, std::ios::in | std::ios::binary); if (!file.is_open()) { return false; @@ -344,7 +344,7 @@ bool LocalErrorHistogramManager::loadFromFile(const std::string& filename) { } -bool LocalErrorHistogramManager::saveToFile(const std::string& filename) { +bool LocalErrorHistogramManager::saveToFile(const std::filesystem::path& filename) { std::ofstream file(filename, std::ios::out | std::ios::binary); if (!file.is_open()) { return false; diff --git a/modules/multiresvolume/rendering/localerrorhistogrammanager.h b/modules/multiresvolume/rendering/localerrorhistogrammanager.h index b6f54177c4..da4dd0833b 100644 --- a/modules/multiresvolume/rendering/localerrorhistogrammanager.h +++ b/modules/multiresvolume/rendering/localerrorhistogrammanager.h @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -42,8 +43,8 @@ public: const Histogram* spatialHistogram(unsigned int brickIndex) const; const Histogram* temporalHistogram(unsigned int brickIndex) const; - bool loadFromFile(const std::string& filename); - bool saveToFile(const std::string& filename); + bool loadFromFile(const std::filesystem::path& filename); + bool saveToFile(const std::filesystem::path& filename); private: TSP* _tsp = nullptr; diff --git a/modules/multiresvolume/rendering/renderablemultiresvolume.cpp b/modules/multiresvolume/rendering/renderablemultiresvolume.cpp index 97d542348a..6ddb02345f 100644 --- a/modules/multiresvolume/rendering/renderablemultiresvolume.cpp +++ b/modules/multiresvolume/rendering/renderablemultiresvolume.cpp @@ -455,21 +455,21 @@ bool RenderableMultiresVolume::initializeSelector() { switch (_selector) { case Selector::TF: if (_errorHistogramManager) { - std::string cacheFilename = FileSys.cacheManager()->cachedFilename( + std::filesystem::path cached = FileSys.cacheManager()->cachedFilename( fmt::format( "{}_{}_errorHistograms", std::filesystem::path(_filename).stem().string(), nHistograms ), "" ); - std::ifstream cacheFile(cacheFilename, std::ios::in | std::ios::binary); + std::ifstream cacheFile(cached, std::ios::in | std::ios::binary); if (cacheFile.is_open()) { // Read histograms from cache. cacheFile.close(); LINFO( - fmt::format("Loading histograms from cache: {}", cacheFilename) + fmt::format("Loading histograms from cache: {}", cached) ); - success &= _errorHistogramManager->loadFromFile(cacheFilename); + success &= _errorHistogramManager->loadFromFile(cached); } else if (!_errorHistogramsPath.empty()) { // Read histograms from scene data. @@ -482,11 +482,11 @@ bool RenderableMultiresVolume::initializeSelector() { } else { // Build histograms from tsp file. - LWARNING(fmt::format("Failed to open {}", cacheFilename)); + LWARNING(fmt::format("Failed to open {}", cached)); success &= _errorHistogramManager->buildHistograms(nHistograms); if (success) { - LINFO(fmt::format("Writing cache to {}", cacheFilename)); - _errorHistogramManager->saveToFile(cacheFilename); + LINFO(fmt::format("Writing cache to {}", cached)); + _errorHistogramManager->saveToFile(cached); } } success &= _tfBrickSelector && _tfBrickSelector->initialize(); @@ -495,29 +495,29 @@ bool RenderableMultiresVolume::initializeSelector() { case Selector::SIMPLE: if (_histogramManager) { - std::string cacheFilename = FileSys.cacheManager()->cachedFilename( + std::filesystem::path cached = FileSys.cacheManager()->cachedFilename( fmt::format("{}_{}_histogram", std::filesystem::path(_filename).stem().string(), nHistograms ), "" ); - std::ifstream cacheFile(cacheFilename, std::ios::in | std::ios::binary); + std::ifstream cacheFile(cached, std::ios::in | std::ios::binary); if (cacheFile.is_open()) { // Read histograms from cache. cacheFile.close(); - LINFO(fmt::format("Loading histograms from {}", cacheFilename)); - success &= _histogramManager->loadFromFile(cacheFilename); + LINFO(fmt::format("Loading histograms from {}", cached)); + success &= _histogramManager->loadFromFile(cached); } else { // Build histograms from tsp file. - LWARNING(fmt::format("Failed to open '{}'", cacheFilename)); + LWARNING(fmt::format("Failed to open {}", cached)); success &= _histogramManager->buildHistograms( _tsp.get(), nHistograms ); if (success) { - LINFO(fmt::format("Writing cache to {}", cacheFilename)); - _histogramManager->saveToFile(cacheFilename); + LINFO(fmt::format("Writing cache to {}", cached)); + _histogramManager->saveToFile(cached); } } success &= _simpleTfBrickSelector && _simpleTfBrickSelector->initialize(); @@ -526,27 +526,27 @@ bool RenderableMultiresVolume::initializeSelector() { case Selector::LOCAL: if (_localErrorHistogramManager) { - std::string cacheFilename = FileSys.cacheManager()->cachedFilename( + std::filesystem::path cached = FileSys.cacheManager()->cachedFilename( fmt::format( "{}_{}_localErrorHistograms", std::filesystem::path(_filename).stem().string(), nHistograms ), "" ); - std::ifstream cacheFile(cacheFilename, std::ios::in | std::ios::binary); + std::ifstream cacheFile(cached, std::ios::in | std::ios::binary); if (cacheFile.is_open()) { // Read histograms from cache. cacheFile.close(); - LINFO(fmt::format("Loading histograms from {}", cacheFilename)); - success &= _localErrorHistogramManager->loadFromFile(cacheFilename); + LINFO(fmt::format("Loading histograms from {}", cached)); + success &= _localErrorHistogramManager->loadFromFile(cached); } else { // Build histograms from tsp file. - LWARNING(fmt::format("Failed to open {}", cacheFilename)); + LWARNING(fmt::format("Failed to open {}", cached)); success &= _localErrorHistogramManager->buildHistograms(nHistograms); if (success) { - LINFO(fmt::format("Writing cache to {}", cacheFilename)); - _localErrorHistogramManager->saveToFile(cacheFilename); + LINFO(fmt::format("Writing cache to {}", cached)); + _localErrorHistogramManager->saveToFile(cached); } } success &= _localTfBrickSelector && _localTfBrickSelector->initialize(); diff --git a/modules/multiresvolume/rendering/tsp.cpp b/modules/multiresvolume/rendering/tsp.cpp index 124d1cea24..8ad76a06d3 100644 --- a/modules/multiresvolume/rendering/tsp.cpp +++ b/modules/multiresvolume/rendering/tsp.cpp @@ -507,7 +507,7 @@ bool TSP::readCache() { if (!FileSys.cacheManager()) return false; - std::string cacheFilename = FileSys.cacheManager()->cachedFilename( + std::filesystem::path cacheFilename = FileSys.cacheManager()->cachedFilename( std::filesystem::path(_filename).stem(), "" ); @@ -545,7 +545,7 @@ bool TSP::writeCache() { return false; } - std::string cacheFilename = FileSys.cacheManager()->cachedFilename( + std::filesystem::path cacheFilename = FileSys.cacheManager()->cachedFilename( std::filesystem::path(_filename).stem(), "" ); diff --git a/modules/space/CMakeLists.txt b/modules/space/CMakeLists.txt index 09e56ed641..a6ce4f383c 100644 --- a/modules/space/CMakeLists.txt +++ b/modules/space/CMakeLists.txt @@ -44,6 +44,7 @@ set(HEADER_FILES source_group("Header Files" FILES ${HEADER_FILES}) set(SOURCE_FILES + spacemodule_lua.inl speckloader.cpp rendering/planetgeometry.cpp rendering/renderableconstellationbounds.cpp diff --git a/modules/space/rendering/renderablestars.cpp b/modules/space/rendering/renderablestars.cpp index 89b4fdf9a5..3b42e10193 100644 --- a/modules/space/rendering/renderablestars.cpp +++ b/modules/space/rendering/renderablestars.cpp @@ -865,7 +865,7 @@ void RenderableStars::loadPSFTexture() { if (_pointSpreadFunctionTexture) { LDEBUG(fmt::format( - "Loaded texture from '{}'", absPath(_pointSpreadFunctionTexturePath) + "Loaded texture from {}", absPath(_pointSpreadFunctionTexturePath) )); _pointSpreadFunctionTexture->uploadTexture(); } @@ -1267,10 +1267,7 @@ void RenderableStars::update(const UpdateData&) { absPath(_colorTexturePath).string() ); if (_colorTexture) { - LDEBUG(fmt::format( - "Loaded texture from '{}'", - absPath(_colorTexturePath) - )); + LDEBUG(fmt::format("Loaded texture from {}", absPath(_colorTexturePath))); _colorTexture->uploadTexture(); } @@ -1293,7 +1290,7 @@ void RenderableStars::update(const UpdateData&) { ); if (_otherDataColorMapTexture) { LDEBUG(fmt::format( - "Loaded texture from '{}'", + "Loaded texture from {}", absPath(_otherDataColorMapPath) )); _otherDataColorMapTexture->uploadTexture(); diff --git a/modules/space/spacemodule.cpp b/modules/space/spacemodule.cpp index 0ebba746cd..bac8d687b9 100644 --- a/modules/space/spacemodule.cpp +++ b/modules/space/spacemodule.cpp @@ -39,11 +39,14 @@ #include #include #include +#include #include #include #include #include +#include "spacemodule_lua.inl" + namespace { constexpr openspace::properties::Property::PropertyInfo SpiceExceptionInfo = { "ShowExceptions", @@ -133,4 +136,31 @@ std::vector SpaceModule::documentations() const { }; } +scripting::LuaLibrary SpaceModule::luaLibrary() const { + scripting::LuaLibrary res; + res.name = "space"; + res.functions = { + { + "convertFromRaDec", + &space::luascriptfunctions::convertFromRaDec, + {}, + "string/double, string/double, double", + "Returns the cartesian world position of a ra dec coordinate with distance. " + "If the coordinate is given as strings the format should be ra 'XhYmZs' and " + "dec 'XdYmZs'. If the coordinate is given as numbers the values should be " + "in degrees." + }, + { + "convertToRaDec", + &space::luascriptfunctions::convertToRaDec, + {}, + "double, double, double", + "Returns the formatted ra, dec strings and distance for a given cartesian " + "world coordinate." + } + }; + + return res; +} + } // namespace openspace diff --git a/modules/space/spacemodule.h b/modules/space/spacemodule.h index b2630b6277..bfa65f22b4 100644 --- a/modules/space/spacemodule.h +++ b/modules/space/spacemodule.h @@ -42,6 +42,8 @@ public: static ghoul::opengl::ProgramObjectManager ProgramObjectManager; + scripting::LuaLibrary luaLibrary() const override; + private: void internalInitialize(const ghoul::Dictionary&) override; void internalDeinitializeGL() override; diff --git a/modules/space/spacemodule_lua.inl b/modules/space/spacemodule_lua.inl new file mode 100644 index 0000000000..881a191afe --- /dev/null +++ b/modules/space/spacemodule_lua.inl @@ -0,0 +1,78 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2021 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +namespace openspace::space::luascriptfunctions { + +int convertFromRaDec(lua_State* L) { + ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::convertFromRaDec"); + + glm::dvec2 degrees = glm::dvec2(0.0); + if (lua_type(L, 1) == LUA_TSTRING && lua_type(L, 2) == LUA_TSTRING) { + std::string ra = ghoul::lua::value(L, 1); + std::string dec = ghoul::lua::value(L, 2); + degrees = icrsToDecimalDegrees(ra, dec); + } + else if (lua_type(L, 1) == LUA_TNUMBER && lua_type(L, 2) == LUA_TNUMBER) { + degrees.x = ghoul::lua::value(L, 1); + degrees.y = ghoul::lua::value(L, 2); + } + else { + throw ghoul::lua::LuaRuntimeException("lua::convertFromRaDec: Ra and Dec have to " + "be of the same type, either String or Number" + ); + } + + double distance = ghoul::lua::value(L, 3); + lua_settop(L, 0); + + glm::dvec3 pos = icrsToGalacticCartesian(degrees.x, degrees.y, distance); + ghoul::lua::push(L, pos); + + ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack"); + return 1; +} + +int convertToRaDec(lua_State* L) { + ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::convertToRaDec"); + + double x = ghoul::lua::value(L, 1); + double y = ghoul::lua::value(L, 2); + double z = ghoul::lua::value(L, 3); + lua_settop(L, 0); + + glm::dvec3 degrees = galacticCartesianToIcrs(x, y, z); + std::pair raDecPair + = decimalDegreesToIcrs(degrees.x, degrees.y); + + ghoul::lua::push(L, raDecPair.first); // Ra + ghoul::lua::push(L, raDecPair.second); // Dec + ghoul::lua::push(L, degrees.z); // Distance + + ghoul_assert(lua_gettop(L) == 3, "Incorrect number of items left on stack"); + return 3; +} + +} // namespace openspace::space::luascriptfunctions diff --git a/modules/space/speckloader.cpp b/modules/space/speckloader.cpp index 996ba3ab73..649e3f9aff 100644 --- a/modules/space/speckloader.cpp +++ b/modules/space/speckloader.cpp @@ -99,23 +99,21 @@ namespace { std::is_same_v ); - std::string cachePath = FileSys.cacheManager()->cachedFilename(speckPath); + std::filesystem::path cached = FileSys.cacheManager()->cachedFilename(speckPath); - if (std::filesystem::exists(cachePath)) { + if (std::filesystem::exists(cached)) { LINFOC( "SpeckLoader", - fmt::format( - "Cached file '{}' used for file {}", cachePath, speckPath - ) + fmt::format("Cached file {} used for file {}", cached, speckPath) ); - std::optional dataset = loadCacheFunction(cachePath); + std::optional dataset = loadCacheFunction(cached); if (dataset.has_value()) { // We could load the cache file and we are now done with this return *dataset; } else { - FileSys.cacheManager()->removeCacheFile(cachePath); + FileSys.cacheManager()->removeCacheFile(cached); } } LINFOC("SpeckLoader", fmt::format("Loading file {}", speckPath)); @@ -123,7 +121,7 @@ namespace { if (!dataset.entries.empty()) { LINFOC("SpeckLoader", "Saving cache"); - saveCacheFunction(dataset, cachePath); + saveCacheFunction(dataset, cached); } return dataset; } @@ -547,7 +545,7 @@ Labelset loadFile(std::filesystem::path path, SkipAllZeroLines) { std::ifstream file(path); if (!file.good()) { - throw ghoul::RuntimeError(fmt::format("Failed to open speck file '{}'", path)); + throw ghoul::RuntimeError(fmt::format("Failed to open speck file {}", path)); } Labelset res; @@ -582,7 +580,7 @@ Labelset loadFile(std::filesystem::path path, SkipAllZeroLines) { // included in the speck file) if (res.textColorIndex != -1) { throw ghoul::RuntimeError(fmt::format( - "Error loading label file '{}': Textcolor defined twice", path + "Error loading label file {}: Textcolor defined twice", path )); } @@ -621,7 +619,7 @@ Labelset loadFile(std::filesystem::path path, SkipAllZeroLines) { // data section of the file if (!std::isdigit(line[0]) && line[0] != '-') { throw ghoul::RuntimeError(fmt::format( - "Error loading label file '{}': Header information and datasegment " + "Error loading label file {}: Header information and datasegment " "intermixed", path )); } @@ -640,7 +638,7 @@ Labelset loadFile(std::filesystem::path path, SkipAllZeroLines) { if (!startsWith(rest, "text")) { throw ghoul::RuntimeError(fmt::format( - "Error loading label file '{}': File contains some value between " + "Error loading label file {}: File contains some value between " "positions and text label, which is unsupported", path )); } @@ -755,7 +753,7 @@ ColorMap loadFile(std::filesystem::path path, SkipAllZeroLines) { std::ifstream file(path); if (!file.good()) { - throw ghoul::RuntimeError(fmt::format("Failed to open speck file '{}'", path)); + throw ghoul::RuntimeError(fmt::format("Failed to open speck file {}", path)); } ColorMap res; diff --git a/modules/space/translation/horizonstranslation.cpp b/modules/space/translation/horizonstranslation.cpp index 1f13bdf6cc..47fc033f1a 100644 --- a/modules/space/translation/horizonstranslation.cpp +++ b/modules/space/translation/horizonstranslation.cpp @@ -113,17 +113,15 @@ glm::dvec3 HorizonsTranslation::position(const UpdateData& data) const { } void HorizonsTranslation::loadData() { - std::string file = _horizonsTextFile; - if (!std::filesystem::is_regular_file(absPath(file))) { + std::filesystem::path file = absPath(_horizonsTextFile.value()); + if (!std::filesystem::is_regular_file(file)) { return; } - std::string cachedFile = FileSys.cacheManager()->cachedFilename(file); + std::filesystem::path cachedFile = FileSys.cacheManager()->cachedFilename(file); bool hasCachedFile = std::filesystem::is_regular_file(cachedFile); if (hasCachedFile) { - LINFO(fmt::format( - "Cached file '{}' used for Horizon file '{}'", cachedFile, file - )); + LINFO(fmt::format("Cached file {} used for Horizon file {}", cachedFile, file)); bool success = loadCachedFile(cachedFile); if (success) { @@ -136,9 +134,9 @@ void HorizonsTranslation::loadData() { } } else { - LINFO(fmt::format("Cache for Horizon file '{}' not found", file)); + LINFO(fmt::format("Cache for Horizon file {} not found", file)); } - LINFO(fmt::format("Loading Horizon file '{}'", file)); + LINFO(fmt::format("Loading Horizon file {}", file)); readHorizonsTextFile(); @@ -147,12 +145,11 @@ void HorizonsTranslation::loadData() { } void HorizonsTranslation::readHorizonsTextFile() { - std::ifstream fileStream(_horizonsTextFile); + std::filesystem::path f = absPath(_horizonsTextFile); + std::ifstream fileStream(f); if (!fileStream.good()) { - LERROR(fmt::format( - "Failed to open Horizons text file '{}'", _horizonsTextFile - )); + LERROR(fmt::format("Failed to open Horizons text file {}", f)); return; } @@ -202,11 +199,11 @@ void HorizonsTranslation::readHorizonsTextFile() { fileStream.close(); } -bool HorizonsTranslation::loadCachedFile(const std::string& file) { +bool HorizonsTranslation::loadCachedFile(const std::filesystem::path& file) { std::ifstream fileStream(file, std::ifstream::binary); if (!fileStream.good()) { - LERROR(fmt::format("Error opening file '{}' for loading cache file", file)); + LERROR(fmt::format("Error opening file {} for loading cache file", file)); return false; } @@ -241,10 +238,10 @@ bool HorizonsTranslation::loadCachedFile(const std::string& file) { return fileStream.good(); } -void HorizonsTranslation::saveCachedFile(const std::string& file) const { +void HorizonsTranslation::saveCachedFile(const std::filesystem::path& file) const { std::ofstream fileStream(file, std::ofstream::binary); if (!fileStream.good()) { - LERROR(fmt::format("Error opening file '{}' for save cache file", file)); + LERROR(fmt::format("Error opening file {} for save cache file", file)); return; } diff --git a/modules/space/translation/horizonstranslation.h b/modules/space/translation/horizonstranslation.h index e002c3f8ed..625faa29d9 100644 --- a/modules/space/translation/horizonstranslation.h +++ b/modules/space/translation/horizonstranslation.h @@ -61,8 +61,8 @@ public: private: void loadData(); void readHorizonsTextFile(); - bool loadCachedFile(const std::string& file); - void saveCachedFile(const std::string& file) const; + bool loadCachedFile(const std::filesystem::path& file); + void saveCachedFile(const std::filesystem::path& file) const; properties::StringProperty _horizonsTextFile; std::unique_ptr _fileHandle; diff --git a/modules/spacecraftinstruments/rendering/renderablemodelprojection.cpp b/modules/spacecraftinstruments/rendering/renderablemodelprojection.cpp index aa54052e7c..d165d8da9e 100644 --- a/modules/spacecraftinstruments/rendering/renderablemodelprojection.cpp +++ b/modules/spacecraftinstruments/rendering/renderablemodelprojection.cpp @@ -344,7 +344,7 @@ void RenderableModelProjection::imageProjectGPU( _transform ); - _geometry->render(*_fboProgramObject, false); + _geometry->render(*_fboProgramObject, false, true); _depthFboProgramObject->deactivate(); _projectionComponent.depthMapRenderEnd(); @@ -374,7 +374,7 @@ void RenderableModelProjection::imageProjectGPU( _fboProgramObject->setUniform(_fboUniformCache.ModelTransform, _transform); _fboProgramObject->setUniform(_fboUniformCache.boresight, _boresight); - _geometry->render(*_fboProgramObject, false); + _geometry->render(*_fboProgramObject, false, true); _fboProgramObject->deactivate(); _projectionComponent.imageProjectEnd(); diff --git a/modules/spacecraftinstruments/shaders/renderableModel_fs.glsl b/modules/spacecraftinstruments/shaders/renderableModel_fs.glsl index 7e8b2e1f55..04684b086b 100644 --- a/modules/spacecraftinstruments/shaders/renderableModel_fs.glsl +++ b/modules/spacecraftinstruments/shaders/renderableModel_fs.glsl @@ -30,7 +30,9 @@ in vec3 vs_normalViewSpace; in float vs_depth; in vec4 vs_positionCameraSpace; +uniform bool has_texture_diffuse; uniform sampler2D baseTexture; +uniform vec3 baseColor; uniform sampler2D projectionTexture; uniform bool performShading; uniform float projectionFading; @@ -44,7 +46,13 @@ const float specularIntensity = 0.0; const float specularPower = 100.0; Fragment getFragment() { - vec4 textureColor = texture(baseTexture, vs_st); + vec4 textureColor; + if (has_texture_diffuse) { + textureColor = texture(baseTexture, vs_st); + } + else { + textureColor = vec4(baseColor, 1.0); + } vec4 projectionColor = texture(projectionTexture, vs_st); if (projectionColor.a > 0.0) { textureColor.rgb = mix( diff --git a/modules/spacecraftinstruments/util/labelparser.cpp b/modules/spacecraftinstruments/util/labelparser.cpp index e9469306c1..4baf2c41df 100644 --- a/modules/spacecraftinstruments/util/labelparser.cpp +++ b/modules/spacecraftinstruments/util/labelparser.cpp @@ -166,7 +166,9 @@ bool LabelParser::create() { std::ifstream file(path); if (!file.good()) { - LERROR(fmt::format("Failed to open label file '{}'", path)); + LERROR(fmt::format( + "Failed to open label file {}", std::filesystem::path(path) + )); return false; } diff --git a/modules/volume/rawvolumereader.h b/modules/volume/rawvolumereader.h index 1d2833cf32..519411a68f 100644 --- a/modules/volume/rawvolumereader.h +++ b/modules/volume/rawvolumereader.h @@ -26,6 +26,7 @@ #define __OPENSPACE_MODULE_VOLUME___RAWVOLUMEREADER___H__ #include +#include #include namespace openspace::volume { @@ -37,11 +38,11 @@ class RawVolumeReader { public: using VoxelType = Type; - RawVolumeReader(const std::string& path, const glm::uvec3& dimensions); + RawVolumeReader(const std::filesystem::path& path, const glm::uvec3& dimensions); glm::uvec3 dimensions() const; - std::string path() const; - void setPath(const std::string& path); + std::filesystem::path path() const; + void setPath(std::filesystem::path path); void setDimensions(const glm::uvec3& dimensions); //VoxelType get(const glm::ivec3& coordinates) const; // TODO: Implement this //VoxelType get(const size_t index) const; // TODO: Implement this @@ -51,7 +52,7 @@ private: size_t coordsToIndex(const glm::uvec3& cartesian) const; glm::uvec3 indexToCoords(size_t linear) const; glm::uvec3 _dimensions; - std::string _path; + std::filesystem::path _path; }; } // namespace openspace::volume diff --git a/modules/volume/rawvolumereader.inl b/modules/volume/rawvolumereader.inl index b54f643c0b..642ffbbe6e 100644 --- a/modules/volume/rawvolumereader.inl +++ b/modules/volume/rawvolumereader.inl @@ -28,10 +28,10 @@ namespace openspace::volume { template -RawVolumeReader::RawVolumeReader(const std::string& path, +RawVolumeReader::RawVolumeReader(const std::filesystem::path& path, const glm::uvec3& dimensions) : _dimensions(dimensions) - , _path(path) + , _path(std::move(path)) {} template @@ -45,16 +45,15 @@ void RawVolumeReader::setDimensions(const glm::uvec3& dimensions) { } template -std::string RawVolumeReader::path() const { +std::filesystem::path RawVolumeReader::path() const { return _path; } template -void RawVolumeReader::setPath(const std::string& path) { - _path = path; +void RawVolumeReader::setPath(std::filesystem::path path) { + _path = std::move(path); } - /* TODO: Implement these methods for random access in raw volume file template diff --git a/modules/volume/rawvolumewriter.h b/modules/volume/rawvolumewriter.h index bfae4a9bc4..38918b2e77 100644 --- a/modules/volume/rawvolumewriter.h +++ b/modules/volume/rawvolumewriter.h @@ -25,6 +25,7 @@ #ifndef __OPENSPACE_MODULE_VOLUME___RAWVOLUMEWRITER___H__ #define __OPENSPACE_MODULE_VOLUME___RAWVOLUMEWRITER___H__ +#include #include #include @@ -35,9 +36,9 @@ template class RawVolume; template class RawVolumeWriter { public: - RawVolumeWriter(std::string path, size_t bufferSize = 1024); + RawVolumeWriter(std::filesystem::path path, size_t bufferSize = 1024); - void setPath(const std::string& path); + void setPath(std::filesystem::path path); glm::uvec3 dimensions() const; void setDimensions(glm::uvec3 dimensions); void write(const std::function& fn, @@ -49,7 +50,7 @@ public: private: glm::ivec3 _dimensions = glm::ivec3(0); - std::string _path; + std::filesystem::path _path; size_t _bufferSize = 0; }; diff --git a/modules/volume/rawvolumewriter.inl b/modules/volume/rawvolumewriter.inl index d9318f9b15..7a96b1ce1b 100644 --- a/modules/volume/rawvolumewriter.inl +++ b/modules/volume/rawvolumewriter.inl @@ -25,12 +25,13 @@ #include #include #include +#include #include namespace openspace::volume { template -RawVolumeWriter::RawVolumeWriter(std::string path, size_t bufferSize) +RawVolumeWriter::RawVolumeWriter(std::filesystem::path path, size_t bufferSize) : _path(std::move(path)) , _bufferSize(bufferSize) {} @@ -99,7 +100,7 @@ void RawVolumeWriter::write(const RawVolume& volume) { std::ofstream file(_path, std::ios::binary); if (!file.good()) { - throw ghoul::RuntimeError("Could not create file '" + _path + "'"); + throw ghoul::RuntimeError(fmt::format("Could not create file {}", _path)); } file.write(buffer, length); diff --git a/openspace.cfg b/openspace.cfg index 3e4332c32a..3a5e56d9e0 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -190,7 +190,7 @@ Fonts = { } FontSize = { FrameInfo = 32.0, - Shutdown = 30.0, + Shutdown = 14.0, Log = 8.0, CameraInfo = 12.0, VersionInfo = 12.0 diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 4cb66304ab..d04319b36e 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -1092,7 +1092,7 @@ void OpenSpaceEngine::preSynchronization() { global::memoryManager->TemporaryMemory.reset(); if (_hasScheduledAssetLoading) { - LINFO(fmt::format("Loading asset: {}", _scheduledAssetPathToLoad)); + LINFO(fmt::format("Loading asset: {}", absPath(_scheduledAssetPathToLoad))); global::profile->setIgnoreUpdates(true); loadSingleAsset(_scheduledAssetPathToLoad); global::profile->setIgnoreUpdates(false); @@ -1270,7 +1270,6 @@ void OpenSpaceEngine::drawOverlays() { for (const std::function& func : *global::callback::draw2D) { ZoneScopedN("[Module] draw2D") - func(); } diff --git a/src/engine/openspaceengine_lua.inl b/src/engine/openspaceengine_lua.inl index 7b86f41e8d..275300606a 100644 --- a/src/engine/openspaceengine_lua.inl +++ b/src/engine/openspaceengine_lua.inl @@ -332,7 +332,10 @@ int createSingleColorImage(lua_State* L) { const glm::dvec3 color = colorDict.value(key); - std::string fileName = FileSys.cacheManager()->cachedFilename(name + ".ppm", ""); + std::filesystem::path fileName = FileSys.cacheManager()->cachedFilename( + name + ".ppm", + "" + ); const bool hasCachedFile = std::filesystem::is_regular_file(fileName); if (hasCachedFile) { LDEBUGC("OpenSpaceEngine", fmt::format("Cached file '{}' used", fileName)); diff --git a/src/interaction/sessionrecording.cpp b/src/interaction/sessionrecording.cpp index 351ab09c40..9beb1aac7b 100644 --- a/src/interaction/sessionrecording.cpp +++ b/src/interaction/sessionrecording.cpp @@ -65,6 +65,13 @@ namespace { "recording is rendering to screen" }; + constexpr openspace::properties::Property::PropertyInfo IgnoreRecordedScaleInfo = { + "IgnoreRecordedScale", + "Ignore Recorded Scale", + "If this value is enabled, the scale value from a recording is ignored and the " + "computed values are used instead" + }; + constexpr const bool UsingTimeKeyframes = false; } // namespace @@ -80,11 +87,13 @@ ConversionError::ConversionError(std::string msg) SessionRecording::SessionRecording() : properties::PropertyOwner({ "SessionRecording", "Session Recording" }) , _renderPlaybackInformation(RenderPlaybackInfo, false) + , _ignoreRecordedScale(IgnoreRecordedScaleInfo, false) {} SessionRecording::SessionRecording(bool isGlobal) : properties::PropertyOwner({ "SessionRecording", "Session Recording" }) , _renderPlaybackInformation(RenderPlaybackInfo, false) + , _ignoreRecordedScale(IgnoreRecordedScaleInfo, false) { if (isGlobal) { auto fTask = FactoryManager::ref().factory(); @@ -92,6 +101,7 @@ SessionRecording::SessionRecording(bool isGlobal) fTask->registerClass("ConvertRecFormatTask"); fTask->registerClass("ConvertRecFileVersionTask"); addProperty(_renderPlaybackInformation); + addProperty(_ignoreRecordedScale); } } @@ -980,8 +990,18 @@ void SessionRecording::render() { res.x / 2 - 150.f, res.y / 4 ); - std::string text = std::to_string(currentTime()); - ghoul::fontrendering::RenderFont(*font, penPosition, text, glm::vec4(1.f)); + std::string text1 = std::to_string(currentTime()); + ghoul::fontrendering::RenderFont( + *font, + penPosition, + text1, + glm::vec4(1.f), + ghoul::fontrendering::CrDirection::Down + ); + std::string text2 = fmt::format( + "Scale: {}", global::navigationHandler->camera()->scaling() + ); + ghoul::fontrendering::RenderFont(*font, penPosition, text2, glm::vec4(1.f)); } bool SessionRecording::isRecording() const { @@ -1751,7 +1771,8 @@ void SessionRecording::moveAheadInTime() { using namespace std::chrono; bool paused = global::timeManager->isPaused(); - if (_state == SessionState::PlaybackPaused) { + bool playbackPaused = (_state == SessionState::PlaybackPaused); + if (playbackPaused) { _playbackPauseOffset += global::windowDelegate->applicationTime() - _previousTime; } @@ -1773,10 +1794,10 @@ void SessionRecording::moveAheadInTime() { global::navigationHandler->orbitalNavigator().anchorNode(); const Renderable* focusRenderable = focusNode->renderable(); if (!focusRenderable || focusRenderable->renderedWithDesiredData()) { - if (!paused) { + if (!playbackPaused) { _saveRenderingCurrentRecordedTime_interpolation += _saveRenderingDeltaTime_interpolation_usec; - _saveRenderingCurrentRecordedTime += _saveRenderingDeltaTime; + _saveRenderingCurrentRecordedTime += _saveRenderingDeltaTime; global::renderEngine->takeScreenshot(); } } @@ -1968,7 +1989,7 @@ bool SessionRecording::processCameraKeyframe(double now) { prevPose, nextPose, t, - false + _ignoreRecordedScale ); } diff --git a/src/navigation/orbitalnavigator.cpp b/src/navigation/orbitalnavigator.cpp index 751c20bb40..ba2c1b9a09 100644 --- a/src/navigation/orbitalnavigator.cpp +++ b/src/navigation/orbitalnavigator.cpp @@ -258,7 +258,7 @@ OrbitalNavigator::OrbitalNavigator() , _useAdaptiveStereoscopicDepth(UseAdaptiveStereoscopicDepthInfo, true) , _stereoscopicDepthOfFocusSurface( StereoscopicDepthOfFocusSurfaceInfo, - 200000, + 21500, 0.25, 500000 ) @@ -391,7 +391,7 @@ OrbitalNavigator::OrbitalNavigator() addProperty(_useAdaptiveStereoscopicDepth); addProperty(_staticViewScaleExponent); - _stereoscopicDepthOfFocusSurface.setExponent(10.f); + _stereoscopicDepthOfFocusSurface.setExponent(3.f); addProperty(_stereoscopicDepthOfFocusSurface); addProperty(_retargetInterpolationTime); diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 0f1da9efc6..f22c52d2a0 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -738,6 +738,8 @@ void FramebufferRenderer::updateResolution() { GL_FLOAT, nullptr ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (HasGLDebugInfo) { @@ -756,6 +758,8 @@ void FramebufferRenderer::updateResolution() { GL_FLOAT, nullptr ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (HasGLDebugInfo) { @@ -774,6 +778,8 @@ void FramebufferRenderer::updateResolution() { GL_FLOAT, nullptr ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (HasGLDebugInfo) { @@ -792,6 +798,8 @@ void FramebufferRenderer::updateResolution() { GL_FLOAT, nullptr ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (HasGLDebugInfo) { @@ -810,6 +818,8 @@ void FramebufferRenderer::updateResolution() { GL_FLOAT, nullptr ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (glbinding::Binding::ObjectLabel.isResolved()) { @@ -834,6 +844,8 @@ void FramebufferRenderer::updateResolution() { GL_FLOAT, nullptr ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (glbinding::Binding::ObjectLabel.isResolved()) { @@ -853,6 +865,8 @@ void FramebufferRenderer::updateResolution() { GL_UNSIGNED_BYTE, nullptr ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (glbinding::Binding::ObjectLabel.isResolved()) { @@ -876,9 +890,12 @@ void FramebufferRenderer::updateResolution() { GL_FLOAT, nullptr ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - float volumeBorderColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; + + float volumeBorderColor[] = { 0.f, 0.f, 0.f, 1.f }; glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, volumeBorderColor); if (glbinding::Binding::ObjectLabel.isResolved()) { glObjectLabel( @@ -905,6 +922,8 @@ void FramebufferRenderer::updateResolution() { GL_FLOAT, nullptr ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (glbinding::Binding::ObjectLabel.isResolved()) { @@ -929,6 +948,8 @@ void FramebufferRenderer::updateResolution() { GL_UNSIGNED_SHORT, nullptr ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (glbinding::Binding::ObjectLabel.isResolved()) { @@ -947,6 +968,8 @@ void FramebufferRenderer::updateResolution() { GL_FLOAT, nullptr ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (glbinding::Binding::ObjectLabel.isResolved()) { diff --git a/src/rendering/luaconsole.cpp b/src/rendering/luaconsole.cpp index 2d953ac33b..4cd4c49f48 100644 --- a/src/rendering/luaconsole.cpp +++ b/src/rendering/luaconsole.cpp @@ -170,7 +170,10 @@ LuaConsole::~LuaConsole() {} // NOLINT void LuaConsole::initialize() { ZoneScoped - const std::string filename = FileSys.cacheManager()->cachedFilename(HistoryFile, ""); + const std::filesystem::path filename = FileSys.cacheManager()->cachedFilename( + HistoryFile, + "" + ); if (std::filesystem::is_regular_file(filename)) { std::ifstream file(filename, std::ios::binary | std::ios::in); @@ -230,7 +233,10 @@ void LuaConsole::initialize() { void LuaConsole::deinitialize() { ZoneScoped - const std::string filename = FileSys.cacheManager()->cachedFilename(HistoryFile, ""); + const std::filesystem::path filename = FileSys.cacheManager()->cachedFilename( + HistoryFile, + "" + ); // We want to limit the command history to a realistic value, so that it doesn't // grow without bounds diff --git a/src/rendering/renderable.cpp b/src/rendering/renderable.cpp index c9704ec821..53cb1b2f45 100644 --- a/src/rendering/renderable.cpp +++ b/src/rendering/renderable.cpp @@ -92,9 +92,6 @@ ghoul::mm_unique_ptr Renderable::createFromDictionary( documentation::testSpecificationAndThrow(Documentation(), dictionary, "Renderable"); std::string renderableType = dictionary.value(KeyType); - // Now we no longer need the type variable - dictionary.removeValue(KeyType); - auto factory = FactoryManager::ref().factory(); ghoul_assert(factory, "Renderable factory did not exist"); Renderable* result = factory->create( diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 7620c1dc4d..33728bf312 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -65,7 +66,7 @@ #ifdef GHOUL_USE_DEVIL #include -#endif //GHOUL_USE_DEVIL +#endif // GHOUL_USE_DEVIL #ifdef GHOUL_USE_FREEIMAGE #include #endif // GHOUL_USE_FREEIMAGE @@ -74,7 +75,7 @@ #include #include #include -#endif //GHOUL_USE_SOIL +#endif // GHOUL_USE_SOIL #ifdef GHOUL_USE_STB_IMAGE #include @@ -863,14 +864,9 @@ void RenderEngine::renderOverlays(const ShutdownInformation& shutdownInfo) { renderScreenLog(); renderVersionInformation(); renderDashboard(); + renderCameraInformation(); - if (!shutdownInfo.inShutdown) { - // We render the camera information in the same location as the shutdown info - // and we won't need this if we are shutting down - renderCameraInformation(); - } - else { - // If we are in shutdown mode, we can display the remaining time + if (shutdownInfo.inShutdown) { renderShutdownInformation(shutdownInfo.timer, shutdownInfo.waitTime); } } @@ -890,12 +886,13 @@ void RenderEngine::renderEndscreen() { glm::vec2(global::windowDelegate->currentSubwindowSize()) / dpiScaling; glViewport(0, 0, res.x, res.y); - const glm::vec2 size = _fontShutdown->boundingBox("Shutting down"); + constexpr const std::string_view Text = "Shutting down"; + const glm::vec2 size = _fontShutdown->boundingBox(Text); glm::vec2 penPosition = glm::vec2( fontResolution().x / 2 - size.x / 2, fontResolution().y / 2 - size.y / 2 ); - RenderFont(*_fontShutdown, penPosition, "Shutting down"); + RenderFont(*_fontShutdown, penPosition, Text); } void RenderEngine::renderShutdownInformation(float timer, float fullTime) { @@ -903,30 +900,42 @@ void RenderEngine::renderShutdownInformation(float timer, float fullTime) { timer = std::max(timer, 0.f); - const glm::vec2 size = _fontShutdown->boundingBox( - fmt::format("Shutdown in: {:.2f}s/{:.2f}s", timer, fullTime) + // Render progressive overlay + glEnable(GL_BLEND); + + // t = 1.f -> start of shutdown counter t = 0.f -> timer has reached shutdown + float t = 1.f - (timer / fullTime); + + rendering::helper::renderBox( + glm::vec2(0.f), + glm::vec2(1.f), + glm::vec4(0.f, 0.f, 0.f, ghoul::circularEaseOut(t)) + ); + + // No need to print the text if we are just about to finish since otherwise we'll be + // overplotting the actual "shutdown in progress" text + if (timer == 0.f) { + return; + } + + constexpr const std::string_view FirstLine = "Shutdown in: {:.2f}s/{:.2f}s"; + const glm::vec2 size1 = _fontShutdown->boundingBox( + fmt::format(FirstLine, timer, fullTime) ); glm::vec2 penPosition = glm::vec2( - fontResolution().x - size.x - 10, - fontResolution().y - size.y + fontResolution().x / 2 - size1.x / 2, + fontResolution().y / 2 - size1.y / 2 ); RenderFont( *_fontShutdown, penPosition, - fmt::format("Shutdown in: {:.2f}s/{:.2f}s", timer, fullTime), - ghoul::fontrendering::CrDirection::Down - ); - - RenderFont( - *_fontShutdown, - penPosition, - // Important: length of this string is the same as the shutdown time text - // to make them align - "Press ESC again to abort", + fmt::format(FirstLine, timer, fullTime), ghoul::fontrendering::CrDirection::Down ); + // Important: Length of this string is the same as the first line to make them align + RenderFont(*_fontShutdown, penPosition, "Press ESC again to abort"); } void RenderEngine::renderDashboard() { diff --git a/src/rendering/texturecomponent.cpp b/src/rendering/texturecomponent.cpp index a49200073a..1b06a99ea0 100644 --- a/src/rendering/texturecomponent.cpp +++ b/src/rendering/texturecomponent.cpp @@ -86,7 +86,7 @@ void TextureComponent::loadFromFile(const std::filesystem::path& path) { ); if (texture) { - LDEBUG(fmt::format("Loaded texture from '{}'", absPath(path.string()))); + LDEBUG(fmt::format("Loaded texture from {}", absPath(path.string()))); _texture = std::move(texture); _textureFile = std::make_unique(path); diff --git a/src/scene/asset.cpp b/src/scene/asset.cpp index dc03a46118..6e1737bd7e 100644 --- a/src/scene/asset.cpp +++ b/src/scene/asset.cpp @@ -502,7 +502,7 @@ bool Asset::initialize() { LERROR(fmt::format("Cannot initialize unsynchronized asset {}", id())); return false; } - LDEBUG(fmt::format("Initializing asset {}", id())); + LDEBUG(fmt::format("Initializing asset '{}'", id())); // 1. Initialize requirements for (const std::shared_ptr& child : _requiredAssets) { @@ -593,7 +593,7 @@ void Asset::deinitialize() { if (!isInitialized()) { return; } - LDEBUG(fmt::format("Deintializing asset {}", id())); + LDEBUG(fmt::format("Deintializing asset '{}'", id())); // Perform inverse actions as in initialize, in reverse order (7 - 1) diff --git a/src/scene/scenegraphnode.cpp b/src/scene/scenegraphnode.cpp index 0611b4cdd1..6ce162c4fa 100644 --- a/src/scene/scenegraphnode.cpp +++ b/src/scene/scenegraphnode.cpp @@ -229,7 +229,7 @@ namespace { // A user-facing description about this scene graph node std::optional description; - // If this value is specified, GUI applications are incouraged to ignore this + // If this value is specified, GUI applications are incouraged to ignore this // scenegraph node. This is most useful to trim collective lists of nodes and // not display, for example, barycenters std::optional hidden; @@ -447,7 +447,9 @@ SceneGraphNode::SceneGraphNode() _overrideBoundingSphere = std::nullopt; } }); - _boundingSphere.setExponent(10.f); + // @TODO (2021-06-30, emmbr) Uncomment this when exponential sliders support + // negative values + //_boundingSphere.setExponent(10.f); addProperty(_boundingSphere); _interactionSphere.onChange([this]() { if (_interactionSphere >= 0.0) { @@ -456,8 +458,10 @@ SceneGraphNode::SceneGraphNode() else { _overrideInteractionSphere = std::nullopt; } - }); - _interactionSphere.setExponent(10.f); + }); + // @TODO (2021-06-30, emmbr) Uncomment this when exponential sliders support + // negative values + //_interactionSphere.setExponent(10.f); addProperty(_interactionSphere); addProperty(_showDebugSphere); } diff --git a/src/scripting/scriptengine.cpp b/src/scripting/scriptengine.cpp index 0c7a16a7ae..3e6941c354 100644 --- a/src/scripting/scriptengine.cpp +++ b/src/scripting/scriptengine.cpp @@ -214,15 +214,11 @@ bool ScriptEngine::runScript(const std::string& script, ScriptCallback callback) return true; } -bool ScriptEngine::runScriptFile(const std::string& filename) { +bool ScriptEngine::runScriptFile(const std::filesystem::path& filename) { ZoneScoped - if (filename.empty()) { - LWARNING("Filename was empty"); - return false; - } if (!std::filesystem::is_regular_file(filename)) { - LERROR(fmt::format("Script with name '{}' did not exist", filename)); + LERROR(fmt::format("Script with name {} did not exist", filename)); return false; } @@ -649,14 +645,17 @@ bool ScriptEngine::writeLog(const std::string& script) { _logFilename = absPath(global::configuration->scriptLog).string(); _logFileExists = true; - LDEBUG(fmt::format("Using script log file '{}'", _logFilename)); + LDEBUG(fmt::format( + "Using script log file {}", std::filesystem::path(_logFilename) + )); // Test file and clear previous input std::ofstream file(_logFilename, std::ofstream::out | std::ofstream::trunc); if (!file.good()) { LERROR(fmt::format( - "Could not open file '{}' for logging scripts", _logFilename + "Could not open file {} for logging scripts", + std::filesystem::path(_logFilename) )); return false; diff --git a/src/util/coordinateconversion.cpp b/src/util/coordinateconversion.cpp index 65cba42a33..cc5e28aae4 100644 --- a/src/util/coordinateconversion.cpp +++ b/src/util/coordinateconversion.cpp @@ -24,26 +24,296 @@ #include +#include +#include +#include + +namespace { + constexpr const char* _loggerCat = "Coordinateconversion"; + + // J2000 Galactic reference frame + constexpr double A0 = glm::radians(192.8595); // Equatorial coordinates of the Galactic north pole + constexpr double D0 = glm::radians(27.1284); + constexpr double L0 = glm::radians(122.9320); // Galactic longitude of the equatorial north pole + + void parseString(const std::string& str, int& hoursOrDegrees, int& minutes, + double& seconds) + { + // Find hms or dms indicies + size_t hOrDIndex = + (str.find('h') != std::string::npos) ? str.find('h') : str.find('d'); + size_t mIndex = str.find('m'); + size_t sIndex = str.find('s'); + if (hOrDIndex == std::string::npos || mIndex == std::string::npos || + sIndex == std::string::npos) + { + throw ghoul::lua::LuaRuntimeException(fmt::format( + "Ra or Dec '{}' format is incorrect. Correct format is: Ra 'XhYmZs', " + "and Dec 'XdYmZs'", str)); + } + + // Construct the number strings + std::string sHoursOrDegrees = str.substr(0, hOrDIndex); + std::string sMinutes = str.substr(hOrDIndex + 1, mIndex - hOrDIndex - 1); + std::string sSeconds = str.substr(mIndex + 1, sIndex - mIndex - 1); + + // Convert the strings to numbers + try { + // Hours or degrees must be an integer + double temp = std::stod(sHoursOrDegrees); + if (std::floor(temp) != temp) { + throw ghoul::lua::LuaRuntimeException(fmt::format( + "Ra or Dec '{}' format is incorrect. Correct format is: Ra 'XhYmZs', " + "and Dec 'XdYmZs', where X must be an integer", str)); + } + hoursOrDegrees = std::stoi(sHoursOrDegrees); + + // Minutes must be an integer + temp = std::stod(sMinutes); + if (std::floor(temp) != temp) { + throw ghoul::lua::LuaRuntimeException(fmt::format( + "Ra or Dec '{}' format is incorrect. Correct format is: Ra 'XhYmZs', " + "and Dec 'XdYmZs', where Y must be an integer", str)); + } + minutes = std::stoi(sMinutes); + + // Seconds is a double + seconds = std::stod(sSeconds); + } catch (const std::invalid_argument& ia) { + throw ghoul::lua::LuaRuntimeException(fmt::format( + "Ra or Dec '{}' format is incorrect. Correct format is: Ra 'XhYmZs', " + "and Dec 'XdYmZs'", str)); + } + } + + void parseRa(const std::string& ra, int& hours, int& minutes, double& seconds) { + if (ra.find('d') != std::string::npos) { + throw ghoul::lua::LuaRuntimeException(fmt::format( + "Ra '{}' format is incorrect. Correct format is: 'XhYmZs'", ra)); + } + parseString(ra, hours, minutes, seconds); + } + + void parseDec(const std::string& dec, int& degrees, int& minutes, + double& seconds) + { + if (dec.find('h') != std::string::npos) { + throw ghoul::lua::LuaRuntimeException(fmt::format( + "Dec '{}' format is incorrect. Correct format is: 'XdYmZs'", dec)); + } + parseString(dec, degrees, minutes, seconds); + } + + bool isRaDecValid(int raH, int raM, double raS, int decD, + int decM, double decS) + { + // Ra + if (raH < 0.0 || raH >= 24.0) { + LWARNING(fmt::format("Right ascension hours '{}' is outside the allowed " + "range of 0 to 24 hours (exclusive)", raH) + ); + return false; + } + if (raM < 0.0 || raM >= 60.0) { + LWARNING(fmt::format("Right ascension minutes '{}' is outside the allowed " + "range of 0 to 60 minutes (exclusive)", raM) + ); + return false; + } + if (raS < 0.0 || raS >= 60.0) { + LWARNING(fmt::format("Right ascension seconds '{}' is outside the allowed " + "range of 0 to 60 seconds (exclusive)", raS) + ); + return false; + } + + // Dec + if (decD < -90.0 || decD > 90.0) { + LWARNING(fmt::format("Declination degrees '{}' is outside the allowed range " + "of -90 to 90 degrees (inclusive)", decD) + ); + return false; + } + else if ((decD == -90.0 || decD == 90.0) && (decM != 0 || decS != 0)) { + LWARNING("Total declination is outside the allowed range of -90 to 90 " + "degrees (inclusive)" + ); + return false; + } + if (decM < 0.0 || decM >= 60.0) { + LWARNING(fmt::format("Declination minutes '{}' is outside the allowed range " + "of 0 to 60 minutes (exclusive)", decM) + ); + return false; + } + if (decS < 0.0 || decS >= 60.0) { + LWARNING(fmt::format("Declination seconds '{}' is outside the allowed range " + "of 0 to 60 seconds (exclusive)", decS) + ); + return false; + } + + return true; + } +} // namespace + namespace openspace { -glm::dvec3 icrsToGalacticCartesian(float ra, float dec, double distance) { - // Convert to Galactic Coordinates from ICRS right ascension and declination - // https://gea.esac.esa.int/archive/documentation/GDR2/Data_processing/ - // chap_cu3ast/sec_cu3ast_intro/ssec_cu3ast_intro_tansforms.html#SSS1 - const glm::dmat3 conversionMatrix = glm::dmat3({ - -0.0548755604162154, 0.4941094278755837, -0.8676661490190047, // col 0 - -0.8734370902348850, -0.4448296299600112, -0.1980763734312015, // col 1 - -0.4838350155487132, 0.7469822444972189, 0.4559837761750669 // col 2 - }); +// Convert Equatorial coordinates ICRS right ascension and declination (a, d) +// into Galactic coordinates (l, b) +// Reference: +// https://www.atnf.csiro.au/people/Tobias.Westmeier/tools_coords.php +glm::dvec3 icrsToGalacticCartesian(double ra, double dec, double distance) { + // (Ra, Dec) -> (a, d) + double a = glm::radians(ra); + double d = glm::radians(dec); - glm::dvec3 rICRS = glm::dvec3( - cos(glm::radians(ra)) * cos(glm::radians(dec)), - sin(glm::radians(ra)) * cos(glm::radians(dec)), - sin(glm::radians(dec)) + // Convert to galactic reference frame + double l = L0 - atan2( + cos(d) * sin(a - A0), + sin(d) * cos(D0) - cos(d) * sin(D0) * cos(a - A0) + ); + double b = asin(sin(d) * sin(D0) + cos(d) * cos(D0) * cos(a - A0)); + + // Convert to cartesian + glm::dvec3 rGalactic = glm::dvec3( + cos(b) * cos(l), + cos(b) * sin(l), + sin(b) ); - glm::dvec3 rGalactic = conversionMatrix * rICRS; // on the unit sphere return distance * rGalactic; } +// Ra format 'XhYmZs', where X and Y are positive integers and Z is a positive double +// Dec format 'XdYmZs', where X is a signed integer, Y is a positive integer and Z is a +// positive double +// Reference: +// https://math.stackexchange.com/questions/15323/how-do-i-calculate-the-cartesian-coordinates-of-stars +glm::dvec2 icrsToDecimalDegrees(const std::string& ra, const std::string& dec) { + if (ra.size() < 6 || dec.size() < 6) { + throw ghoul::lua::LuaRuntimeException(fmt::format( + "Ra '{}' or Dec '{}' format is incorrect. Correct format is: Ra 'XhYmZs', " + "and Dec 'XdYmZs'", ra, dec)); + } + + // Parse right ascension + int raHours, raMinutes; + double raSeconds; + parseRa(ra, raHours, raMinutes, raSeconds); + + // Parse declination + int decDegrees, decMinutes; + double decSeconds; + parseDec(dec, decDegrees, decMinutes, decSeconds); + + const bool isValid = isRaDecValid(raHours, + raMinutes, + raSeconds, + decDegrees, + decMinutes, + decSeconds + ); + + if (!isValid) { + LWARNING(fmt::format("Ra '{}' or Dec '{}' is outside the allowed range, " + "result may be incorrect", ra, dec) + ); + } + + // Convert from hours/degrees, minutes, seconds to decimal degrees + double sign = std::signbit(static_cast(decDegrees)) ? -1.0 : 1.0; + double raDeg = (raHours * 15.0) + + (raMinutes * 15.0 / 60.0) + + (raSeconds * 15.0 / 3600.0); + + double decDeg = (abs(decDegrees) + + (decMinutes / 60.0) + + (decSeconds / 3600.0)) * sign; + + return glm::dvec2(raDeg, decDeg); +} + +// Convert Galactic coordinates (x, y, z) or (l, b) into Equatorial coordinates ICRS +// right ascension and declination in decimal degrees (a, d) plus distance +// References: +// https://www.atnf.csiro.au/people/Tobias.Westmeier/tools_coords.php, +// https://en.wikipedia.org/wiki/Celestial_coordinate_system +glm::dvec3 galacticCartesianToIcrs(double x, double y, double z) { + // Normalize + double distance = sqrt(x*x + y*y + z*z); + double nX = x / distance; + double nY = y / distance; + double nZ = z / distance; + + // Convert from cartesian + // (x, y, z) -> (l, b) + double l = atan2(nY, nX); + double b = asin(nZ); + + // Convert to equatorial reference frame + double a = atan2( + cos(b) * sin(L0 - l), + sin(b) * cos(D0) - cos(b) * sin(D0) * cos(L0 - l) + ) + A0; + double d = asin(sin(b) * sin(D0) + cos(b) * cos(D0) * cos(L0 - l)); + + return glm::dvec3(glm::degrees(a), glm::degrees(d), distance); +} + +// Return a pair with two formatted strings from the decimal degrees ra and dec +// References: +// https://www.rapidtables.com/convert/number/degrees-to-degrees-minutes-seconds.html, +// https://math.stackexchange.com/questions/15323/how-do-i-calculate-the-cartesian-coordinates-of-stars +std::pair decimalDegreesToIcrs(double ra, double dec) { + // Radians to degrees + double raDeg = ra; + double decDeg = dec; + + // Check input + if (raDeg < 0 || raDeg > 360 || decDeg < -90 || decDeg > 90) { + LWARNING(fmt::format("Given Ra '{}' or Dec '{}' is outside the allowed range, " + "result may be incorrect", ra, dec) + ); + } + + // Calculate Ra + int raHours = std::trunc(raDeg) / 15.0; + double raMinutesFull = (raDeg - raHours * 15.0) * 60.0 / 15.0; + int raMinutes = std::trunc(raMinutesFull); + double raSeconds = (raMinutesFull - raMinutes) * 60.0; + + // Calculate Dec + int decDegrees = std::trunc(decDeg); + double decMinutesFull = (abs(decDeg) - abs(decDegrees)) * 60.0; + int decMinutes = std::trunc(decMinutesFull); + double decSeconds = (decMinutesFull - decMinutes) * 60.0; + + // Construct strings + std::pair result; + result.first = std::to_string(raHours) + 'h' + + std::to_string(raMinutes) + 'm' + + std::to_string(raSeconds) + 's'; + + result.second = std::to_string(decDegrees) + 'd' + + std::to_string(decMinutes) + 'm' + + std::to_string(decSeconds) + 's'; + + // Check results + const bool isValid = isRaDecValid(raHours, + raMinutes, + raSeconds, + decDegrees, + decMinutes, + decSeconds + ); + + if (!isValid) { + LWARNING(fmt::format("Resulting Ra '{}' or Dec '{}' is outside the allowed range, " + "result may be incorrect", result.first, result.second) + ); + } + return result; +} + } // namespace openspace diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index a2a69b9eb1..0f4897ac31 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -204,13 +204,13 @@ SpiceManager::KernelHandle SpiceManager::loadKernel(std::string filePath) { ghoul_assert(!filePath.empty(), "Empty file path"); ghoul_assert( std::filesystem::is_regular_file(filePath), - fmt::format("File '{}' ('{}') does not exist", filePath, absPath(filePath)) + fmt::format("File '{}' ({}) does not exist", filePath, absPath(filePath)) ); ghoul_assert( std::filesystem::is_directory(std::filesystem::path(filePath).parent_path()), fmt::format( - "File '{}' exists, but directory '{}' doesn't", - absPath(filePath), std::filesystem::path(filePath).parent_path().string() + "File {} exists, but directory {} does not", + absPath(filePath), std::filesystem::path(filePath).parent_path() ) ); @@ -234,7 +234,7 @@ SpiceManager::KernelHandle SpiceManager::loadKernel(std::string filePath) { std::filesystem::path p = std::filesystem::path(path).parent_path(); std::filesystem::current_path(p); - LINFO(fmt::format("Loading SPICE kernel '{}'", path)); + LINFO(fmt::format("Loading SPICE kernel {}", path)); // Load the kernel furnsh_c(path.string().c_str()); @@ -273,7 +273,7 @@ void SpiceManager::unloadKernel(KernelHandle kernelId) { // If there was only one part interested in the kernel, we can unload it if (it->refCount == 1) { // No need to check for errors as we do not allow empty path names - LINFO(fmt::format("Unloading SPICE kernel '{}'", it->path)); + LINFO(fmt::format("Unloading SPICE kernel {}", it->path)); unload_c(it->path.c_str()); _loadedKernels.erase(it); } @@ -299,7 +299,7 @@ void SpiceManager::unloadKernel(std::string filePath) { if (it == _loadedKernels.end()) { if (_useExceptions) { throw SpiceException( - fmt::format("'{}' did not correspond to a loaded kernel", path) + fmt::format("{} did not correspond to a loaded kernel", path) ); } else { @@ -309,7 +309,7 @@ void SpiceManager::unloadKernel(std::string filePath) { else { // If there was only one part interested in the kernel, we can unload it if (it->refCount == 1) { - LINFO(fmt::format("Unloading SPICE kernel '{}'", path)); + LINFO(fmt::format("Unloading SPICE kernel {}", path)); unload_c(path.string().c_str()); _loadedKernels.erase(it); } @@ -1011,8 +1011,8 @@ void SpiceManager::findCkCoverage(const std::string& path) { fmt::format("File '{}' does not exist", path) ); - constexpr unsigned int MaxObj = 256; - constexpr unsigned int WinSiz = 10000; + constexpr unsigned int MaxObj = 1024; + constexpr unsigned int WinSiz = 16384; #if defined __clang__ #pragma clang diagnostic push @@ -1070,8 +1070,8 @@ void SpiceManager::findSpkCoverage(const std::string& path) { fmt::format("File '{}' does not exist", path) ); - constexpr unsigned int MaxObj = 256; - constexpr unsigned int WinSiz = 10000; + constexpr unsigned int MaxObj = 1024; + constexpr unsigned int WinSiz = 16384; #if defined __clang__ #pragma clang diagnostic push