From 539715f49c3a5a0b47d9864938f3c7847bf2c55d Mon Sep 17 00:00:00 2001 From: Jacob Molin Date: Thu, 23 Jun 2022 12:55:36 -0600 Subject: [PATCH] Adds date recorded to velocity (used as t=0 in renderable) + cleanup --- .../network/messagehandler.cpp | 77 +++++++++++ .../rendering/renderablepointscloud.cpp | 24 +++- .../rendering/renderablepointscloud.h | 5 + modules/softwareintegration/simp/simp.cpp | 122 ++++++++++++++---- modules/softwareintegration/simp/simp.h | 16 +++ .../utils/syncablestorage.cpp | 6 +- 6 files changed, 219 insertions(+), 31 deletions(-) diff --git a/modules/softwareintegration/network/messagehandler.cpp b/modules/softwareintegration/network/messagehandler.cpp index 266c355a11..334a12b441 100644 --- a/modules/softwareintegration/network/messagehandler.cpp +++ b/modules/softwareintegration/network/messagehandler.cpp @@ -380,6 +380,66 @@ bool handleColorValue( return true; } +bool handleDateValue( + const std::string& identifier, + const glm::ivec3& _newDate, + const std::string& propertyName, + std::shared_ptr connection = nullptr, + const std::function< + void( + properties::Property* property, + const std::string& identifier, + std::shared_ptr connection + ) + >& onChangeCallback = nullptr +) { + auto setDateCallback = [identifier, _newDate, propertyName] { + // Get renderable + auto r = renderable(identifier); + if (!r) return; + + // Get date value of renderable + auto property = r->property(propertyName); + if (!property) return; + + auto currentDate = std::any_cast(property->get()); + + // Update new date values + auto newDate = _newDate; + for (glm::ivec3::length_type i = 0; i < glm::ivec3::length(); ++i) { + // Keep the parts of currentDate that won't be updated + if (newDate[i] < 0) { + newDate[i] = currentDate[i]; + } + } + + // Update date of renderable + if (glm::any(glm::notEqual(newDate, currentDate))) { + global::scriptEngine->queueScript( + fmt::format( + "openspace.setPropertyValueSingle('Scene.{}.Renderable.{}', {});", + identifier, propertyName, newDate + ), + scripting::ScriptEngine::RemoteScripting::Yes + ); + } + }; + addCallback( + identifier, + { + setDateCallback, + {}, + fmt::format("Callback on property {}", propertyName), + } + ); + + if (onChangeCallback && connection) { + checkAddOnChangeCallback(identifier, propertyName, connection, onChangeCallback); + } + + return true; +} + bool handleBoolValue( const std::vector& message, size_t& offset, @@ -527,6 +587,8 @@ void handleDataMessage(const std::vector& message, std::shared_ptr& message, std::shared_ptr(message, offset, identifier, dataKey, "VelocityNanMode")) break; } @@ -728,6 +802,9 @@ void handleDataMessage(const std::vector& message, std::shared_ptr& message, std::shared_ptr connection) { diff --git a/modules/softwareintegration/rendering/renderablepointscloud.cpp b/modules/softwareintegration/rendering/renderablepointscloud.cpp index 61dca8422d..0868406e3c 100644 --- a/modules/softwareintegration/rendering/renderablepointscloud.cpp +++ b/modules/softwareintegration/rendering/renderablepointscloud.cpp @@ -137,13 +137,19 @@ namespace { "Velocity Distance Unit", "The distance unit of the velocity data." }; - + constexpr openspace::properties::Property::PropertyInfo VelocityTimeUnitInfo = { "VelocityTimeUnit", "Velocity Time Unit", "The time unit of the velocity data." }; - + + constexpr openspace::properties::Property::PropertyInfo VelocityDateRecordedInfo = { + "VelocityDateRecorded", + "Velocity Date Recorded", + "The date the velocity data was recorded." + }; + constexpr openspace::properties::Property::PropertyInfo VelocityNanModeInfo = { "VelocityNanMode", "Velocity NaN Mode", @@ -205,6 +211,9 @@ namespace { // [[codegen::verbatim(VelocityTimeUnitInfo.description)]] std::optional velocityTimeUnit; + // [[codegen::verbatim(VelocityDateRecordedInfo.description)]] + std::optional velocityDateRecorded; + // [[codegen::verbatim(VelocityNanModeInfo.description)]] std::optional velocityNanMode; @@ -249,6 +258,7 @@ RenderablePointsCloud::RenderablePointsCloud(const ghoul::Dictionary& dictionary , _linearSizeEnabled(LinearSizeEnabledInfo, false) , _velocityDistanceUnit(VelocityDistanceUnitInfo, "") , _velocityTimeUnit(VelocityTimeUnitInfo, "") + , _velocityDateRecorded(VelocityDateRecordedInfo, glm::ivec3{ -1 }) , _velocityNanMode(VelocityNanModeInfo) , _name(NameInfo) , _motionEnabled(MotionEnabledInfo, false) @@ -345,6 +355,11 @@ RenderablePointsCloud::RenderablePointsCloud(const ghoul::Dictionary& dictionary _velocityTimeUnit.onChange([this] { _velocityUnitsAreDirty = true; }); addProperty(_velocityTimeUnit); + _velocityDateRecorded = p.velocityDateRecorded.value_or(_velocityDateRecorded); + _velocityDateRecorded.setVisibility(properties::Property::Visibility::Hidden); + _velocityDateRecorded.onChange([this] { updateVelocityT0(); }); + addProperty(_velocityDateRecorded); + _velocityNanMode = p.velocityNanMode.value_or(_velocityNanMode); _velocityNanMode.setVisibility(properties::Property::Visibility::Hidden); addProperty(_velocityNanMode); @@ -443,7 +458,7 @@ void RenderablePointsCloud::render(const RenderData& data, RendererTasks&) { _shaderProgram->setUniform(_uniformCache.motionEnabled, _motionEnabled); _shaderProgram->setUniform( _uniformCache.time, - static_cast(data.time.j2000Seconds()) + static_cast(data.time.j2000Seconds() - _t0) ); _shaderProgram->setUniform(_uniformCache.color, _color); @@ -952,5 +967,8 @@ bool RenderablePointsCloud::shouldLoadLinearSizeAttrData(SoftwareIntegrationModu return softwareIntegrationModule->isDataDirty(_identifier.value(), storage::Key::LinearSizeAttrData); } +void RenderablePointsCloud::updateVelocityT0() { + _t0 = Time::convertTime(simp::toDateString(_velocityDateRecorded)); +} } // namespace openspace diff --git a/modules/softwareintegration/rendering/renderablepointscloud.h b/modules/softwareintegration/rendering/renderablepointscloud.h index 8a0cdff3db..12c53317aa 100644 --- a/modules/softwareintegration/rendering/renderablepointscloud.h +++ b/modules/softwareintegration/rendering/renderablepointscloud.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -74,6 +75,7 @@ private: void checkColormapMinMax(); void checkIfColormapCanBeEnabled(); void checkIfLinearSizeCanBeEnabled(); + void updateVelocityT0(); void checkIfMotionCanBeEnabled(); bool shouldLoadPointData(SoftwareIntegrationModule* softwareIntegrationModule); @@ -111,6 +113,7 @@ private: properties::BoolProperty _motionEnabled; properties::StringProperty _velocityDistanceUnit; properties::StringProperty _velocityTimeUnit; + properties::IVec3Property _velocityDateRecorded; properties::IntProperty _velocityNanMode; @@ -123,6 +126,8 @@ private: bool _hasLoadedLinearSizeAttributeData = false; + double _t0 = 0.0; + bool _velocityDateIsDirty = false; bool _velocityUnitsAreDirty = false; bool _hasLoadedVelocityData = false; diff --git a/modules/softwareintegration/simp/simp.cpp b/modules/softwareintegration/simp/simp.cpp index e23cfaa74e..709386bbe9 100644 --- a/modules/softwareintegration/simp/simp.cpp +++ b/modules/softwareintegration/simp/simp.cpp @@ -55,6 +55,9 @@ const std::unordered_map _dataTypeFromString{ { "vel.w", DataKey::W }, { "vel.unit.dist", DataKey::VelocityDistanceUnit }, { "vel.unit.time", DataKey::VelocityTimeUnit }, + { "vel.t0.day", DataKey::VelocityDayRecorded }, + { "vel.t0.month", DataKey::VelocityMonthRecorded }, + { "vel.t0.year", DataKey::VelocityYearRecorded }, { "vel.nan.mode", DataKey::VelocityNanMode }, { "vel.enable", DataKey::VelocityEnabled }, { "col.r", DataKey::Red }, @@ -92,31 +95,6 @@ const std::unordered_map _velocityNanRenderM { "Static", VelocityNanRenderMode::Static }, }; -// glm::vec4 readSingleColor(const std::vector& message, size_t& offset) { -// if (message[offset] != '[') { -// throw SimpError( -// tools::ErrorCode::Generic, -// fmt::format("Expected to read '[', got {} in 'readColor'", message[offset]) -// ); -// } -// ++offset; - -// float r = readFloat32Value(message, offset); -// float g = readFloat32Value(message, offset); -// float b = readFloat32Value(message, offset); -// float a = readFloat32Value(message, offset); - -// if (message[offset] != ']') { -// throw SimpError( -// tools::ErrorCode::Generic, -// fmt::format("Expected to read ']', got {} in 'readColor'", message[offset]) -// ); -// } -// ++offset; - -// return { r, g, b, a }; -// } - void checkOffset(const std::vector& message, size_t offset) { if (offset >= message.size()) { throw SimpError( @@ -292,6 +270,78 @@ std::string formatLengthOfSubject(size_t lengthOfSubject) { return os.str(); } +std::string yearIntToString(int32_t yearAsInt) { + // Only positive values for year possible since Time::convertTime + // (used in RenderablePointsCloud::updateVelocityT0) just converts + // negative values to small values + if (yearAsInt < 0) { + LERROR(fmt::format( + "The year can't be negative. The provided year: {}", + yearAsInt + )); + return ""; + } + return std::to_string(yearAsInt); +} + +std::string monthIntToString(int32_t monthAsInt) { + switch (monthAsInt) { + case 1: + return "JAN"; + case 2: + return "FEB"; + case 3: + return "MAR"; + case 4: + return "APR"; + case 5: + return "MAY"; + case 6: + return "JUN"; + case 7: + return "JUL"; + case 8: + return "AUG"; + case 9: + return "SEP"; + case 10: + return "OCT"; + case 11: + return "NOV"; + case 12: + return "DEC"; + default: + LERROR(fmt::format("There's no month {}", monthAsInt)); + return ""; + } +} + +std::string dayIntToString(int32_t dayAsInt) { + if (dayAsInt < 0 || dayAsInt > 31) { + LERROR(fmt::format( + "There was an issue trying to convert the day as int to a string. The provided day as int: {}", + dayAsInt + )); + return ""; + } + + std::string dayAsString{}; + if (dayAsInt < 10) dayAsString = "0"; + dayAsString += std::to_string(dayAsInt); + + return dayAsString; +} + +std::string toDateString(glm::ivec3 dateVec) { + std::string dateString{}; + dateString += simp::yearIntToString(dateVec[0]); // Year + dateString += " " + simp::monthIntToString(dateVec[1]); // Month + dateString += " " + simp::dayIntToString(dateVec[2]); // Day + LWARNING(fmt::format("dateString='{}'", dateString)); + + return dateString; +} + bool readColorChannel( const std::vector& message, size_t& offset, @@ -314,6 +364,28 @@ bool readColorChannel( return true; } +bool readDateValue( + const std::vector& message, + size_t& offset, + const DataKey& dataKey, + glm::ivec3& date, + const glm::ivec3::length_type& timeUnit +) { + int32_t newTimeValue; + try { + simp::readValue(message, offset, newTimeValue); + } + catch (const simp::SimpError& err) { + LERROR(fmt::format( + "Error when parsing int in {} message: {}", + simp::getStringFromDataKey(dataKey), err.message + )); + return false; + } + date[timeUnit] = newTimeValue; + + return true; +} void readValue(const std::vector& message, size_t& offset, float& value) { value = readFloat32Value(message, offset); diff --git a/modules/softwareintegration/simp/simp.h b/modules/softwareintegration/simp/simp.h index 0570062650..b397461cfb 100644 --- a/modules/softwareintegration/simp/simp.h +++ b/modules/softwareintegration/simp/simp.h @@ -61,6 +61,9 @@ enum class DataKey : uint16_t { W, VelocityDistanceUnit, VelocityTimeUnit, + VelocityDayRecorded, + VelocityMonthRecorded, + VelocityYearRecorded, VelocityNanMode, VelocityEnabled, // Color @@ -138,6 +141,11 @@ VelocityNanRenderMode getVelocityNanRenderMode(const std::string& type); std::string formatLengthOfSubject(size_t lengthOfSubject); +std::string yearIntToString(int32_t yearAsInt); +std::string monthIntToString(int32_t monthAsInt); +std::string dayIntToString(int32_t dayAsInt); +std::string toDateString(glm::ivec3 dateVec); + bool readColorChannel( const std::vector& message, size_t& offset, @@ -146,6 +154,14 @@ bool readColorChannel( const glm::vec4::length_type& channel ); +bool readDateValue( + const std::vector& message, + size_t& offset, + const DataKey& dataKey, + glm::ivec3& date, + const glm::ivec3::length_type& timeUnit +); + template T networkToHostEndian(T value); diff --git a/modules/softwareintegration/utils/syncablestorage.cpp b/modules/softwareintegration/utils/syncablestorage.cpp index 8e78b4c214..b93093fde2 100644 --- a/modules/softwareintegration/utils/syncablestorage.cpp +++ b/modules/softwareintegration/utils/syncablestorage.cpp @@ -113,7 +113,7 @@ void SyncableStorage::setLoaded(const Identifier& identifier, const storage::Key for (auto key : simpDataKeys) { if (!count(identifier, key)) { LERROR(fmt::format( - "SceneGraphNode {} has no data with key '{}' in the centralized data storage", + "SceneGraphNode {} has no data with key '{}' in the syncable data storage", identifier, simp::getStringFromDataKey(key) )); @@ -303,7 +303,7 @@ bool SyncableStorage::fetchDimFloatData( if (!count(identifier)) { LERROR(fmt::format( - "SceneGraphNode {} is missing from the centralized data storage", + "SceneGraphNode {} is missing from the syncable data storage", identifier )); return false; @@ -314,7 +314,7 @@ bool SyncableStorage::fetchDimFloatData( for (size_t i = 0; i < nDimensions; i++) { if (!count(identifier, dimDataKeys[i])) { LERROR(fmt::format( - "SceneGraphNode {} is missing {} from the centralized data storage", + "SceneGraphNode {} is missing {} from the syncable data storage", identifier, simp::getStringFromDataKey(dimDataKeys[i]) )); return false;