mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-03 18:19:38 -06:00
Make more use of temporary string objects in the TimeQuantizer
Add GPU markers to the rendering
This commit is contained in:
Submodule ext/ghoul updated: 26de570dec...d073de9ab1
@@ -33,11 +33,15 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include "SpiceUsr.h"
|
||||
#include "SpiceZpr.h"
|
||||
|
||||
namespace openspace {
|
||||
|
||||
namespace scripting { struct LuaLibrary; }
|
||||
|
||||
void throwSpiceError(const std::string& errorMessage);
|
||||
|
||||
class SpiceManager {
|
||||
public:
|
||||
BooleanType(UseException);
|
||||
@@ -462,6 +466,7 @@ public:
|
||||
* \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/str2et_c.html
|
||||
*/
|
||||
double ephemerisTimeFromDate(const std::string& timeString) const;
|
||||
double ephemerisTimeFromDate(const char* timeString) const;
|
||||
|
||||
/**
|
||||
* Converts the passed \p ephemerisTime into a human-readable date string with a
|
||||
@@ -476,11 +481,33 @@ public:
|
||||
*
|
||||
* \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/timout_c.html
|
||||
*/
|
||||
template <int N = 31>
|
||||
std::string dateFromEphemerisTime(double ephemerisTime,
|
||||
std::string_view format = "YYYY MON DDTHR:MN:SC.### ::RND") const;
|
||||
const char (&format)[N] = "YYYY MON DDTHR:MN:SC.### ::RND") const
|
||||
{
|
||||
static_assert(N != 0, "Format must not be empty");
|
||||
|
||||
std::string res;
|
||||
res.resize(N);
|
||||
dateFromEphemerisTime(ephemerisTime, res.data(), N, format);
|
||||
return res;
|
||||
}
|
||||
|
||||
template <int N>
|
||||
void dateFromEphemerisTime(double ephemerisTime, char* outBuf, int bufferSize,
|
||||
std::string_view format = "YYYY MON DDTHR:MN:SC.### ::RND") const;
|
||||
const char (&format)[N] = "YYYY MON DDTHR:MN:SC.### ::RND") const
|
||||
{
|
||||
static_assert(N != 0, "Format must not be empty");
|
||||
ghoul_assert(N > bufferSize - 1, "Buffer size too small");
|
||||
|
||||
timout_c(ephemerisTime, format, bufferSize - 1, outBuf);
|
||||
if (failed_c()) {
|
||||
throwSpiceError(fmt::format(
|
||||
"Error converting ephemeris time '{}' to date with format '{}'",
|
||||
ephemerisTime, format
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the \p position of a \p target body relative to an \p observer in a
|
||||
|
||||
@@ -64,6 +64,7 @@ public:
|
||||
* \pre \p timeString must not be empty
|
||||
*/
|
||||
static double convertTime(const std::string& time);
|
||||
static double convertTime(const char* time);
|
||||
|
||||
explicit Time(double secondsJ2000 = -1);
|
||||
explicit Time(const std::string& time);
|
||||
@@ -113,13 +114,13 @@ public:
|
||||
* thus also compliant with the Spice library.
|
||||
* \return The current time as a formatted date string
|
||||
*/
|
||||
std::string UTC() const;
|
||||
std::string_view UTC() const;
|
||||
|
||||
/**
|
||||
* Returns the current time as a ISO 8601 formatted, i.e YYYY-MM-DDThh:mm:ssZ
|
||||
* \return The current time as a ISO 8601 formatted string
|
||||
*/
|
||||
std::string ISO8601() const;
|
||||
std::string_view ISO8601() const;
|
||||
|
||||
/**
|
||||
* Advances the simulation time using the deltaTime() and the <code>tickTime</code>.
|
||||
|
||||
@@ -245,7 +245,7 @@ bool FieldlinesState::loadStateFromJson(const std::string& pathToJsonFile,
|
||||
*/
|
||||
void FieldlinesState::saveStateToOsfls(const std::string& absPath) {
|
||||
// ------------------------------- Create the file ------------------------------- //
|
||||
std::string pathSafeTimeString = Time(_triggerTime).ISO8601();
|
||||
std::string pathSafeTimeString = std::string(Time(_triggerTime).ISO8601());
|
||||
pathSafeTimeString.replace(13, 1, "-");
|
||||
pathSafeTimeString.replace(16, 1, "-");
|
||||
pathSafeTimeString.replace(19, 1, "-");
|
||||
@@ -341,7 +341,7 @@ void FieldlinesState::saveStateToJson(const std::string& absPath) {
|
||||
|
||||
json jFile;
|
||||
|
||||
const std::string timeStr = Time(_triggerTime).ISO8601();
|
||||
std::string_view timeStr = Time(_triggerTime).ISO8601();
|
||||
const size_t nLines = _lineStart.size();
|
||||
// const size_t nPoints = _vertexPositions.size();
|
||||
const size_t nExtras = _extraQuantities.size();
|
||||
|
||||
@@ -278,9 +278,9 @@ std::string timeStringify(TemporalTileProvider::TimeFormatType type, const Time&
|
||||
|
||||
switch (type) {
|
||||
case TemporalTileProvider::TimeFormatType::YYYY_MM_DD:
|
||||
return t.ISO8601().substr(0, 10);
|
||||
return std::string(t.ISO8601().substr(0, 10));
|
||||
case TemporalTileProvider::TimeFormatType::YYYYMMDD_hhmmss: {
|
||||
std::string ts = t.ISO8601().substr(0, 19);
|
||||
std::string ts = std::string(t.ISO8601().substr(0, 19));
|
||||
|
||||
// YYYY_MM_DDThh_mm_ss -> YYYYMMDD_hhmmss
|
||||
ts.erase(std::remove(ts.begin(), ts.end(), '-'), ts.end());
|
||||
@@ -289,7 +289,7 @@ std::string timeStringify(TemporalTileProvider::TimeFormatType type, const Time&
|
||||
return ts;
|
||||
}
|
||||
case TemporalTileProvider::TimeFormatType::YYYYMMDD_hhmm: {
|
||||
std::string ts = t.ISO8601().substr(0, 16);
|
||||
std::string ts = std::string(t.ISO8601().substr(0, 16));
|
||||
|
||||
// YYYY_MM_DDThh_mm -> YYYYMMDD_hhmm
|
||||
ts.erase(std::remove(ts.begin(), ts.end(), '-'), ts.end());
|
||||
@@ -298,9 +298,9 @@ std::string timeStringify(TemporalTileProvider::TimeFormatType type, const Time&
|
||||
return ts;
|
||||
}
|
||||
case TemporalTileProvider::TimeFormatType::YYYY_MM_DDThhColonmmColonssZ:
|
||||
return t.ISO8601().substr(0, 19) + "Z";
|
||||
return std::string(t.ISO8601().substr(0, 19)) + "Z";
|
||||
case TemporalTileProvider::TimeFormatType::YYYY_MM_DDThh_mm_ssZ: {
|
||||
std::string timeString = t.ISO8601().substr(0, 19) + "Z";
|
||||
std::string timeString = std::string(t.ISO8601().substr(0, 19)) + "Z";
|
||||
replace(timeString.begin(), timeString.end(), ':', '_');
|
||||
return timeString;
|
||||
}
|
||||
@@ -423,7 +423,10 @@ std::string consumeTemporalMetaData(TemporalTileProvider& t, const std::string&
|
||||
}
|
||||
|
||||
try {
|
||||
t.timeQuantizer.setStartEndRange(start.ISO8601(), end.ISO8601());
|
||||
t.timeQuantizer.setStartEndRange(
|
||||
std::string(start.ISO8601()),
|
||||
std::string(end.ISO8601())
|
||||
);
|
||||
t.timeQuantizer.setResolution(timeResolution);
|
||||
}
|
||||
catch (const ghoul::RuntimeError& e) {
|
||||
|
||||
@@ -137,11 +137,11 @@ std::string RangedTime::clamp(const std::string& checkTime) {
|
||||
}
|
||||
}
|
||||
|
||||
std::string RangedTime::start() const {
|
||||
std::string_view RangedTime::start() const {
|
||||
return _start;
|
||||
}
|
||||
|
||||
std::string RangedTime::end() const {
|
||||
std::string_view RangedTime::end() const {
|
||||
return _end;
|
||||
}
|
||||
|
||||
@@ -174,10 +174,14 @@ std::string DateTime::ISO8601() const {
|
||||
};
|
||||
|
||||
double DateTime::J2000() const {
|
||||
Time t;
|
||||
std::string timeString = ISO8601();
|
||||
t.setTime(timeString);
|
||||
return t.j2000Seconds();
|
||||
char Buffer[20];
|
||||
std::memset(Buffer, 0, 20);
|
||||
fmt::format_to(
|
||||
Buffer,
|
||||
"{:0>4}-{:0>2}-{:0>2}T{:0>2}:{:0>2}:{:0>2}",
|
||||
_year, _month, _day, _hour, _minute, _second
|
||||
);
|
||||
return Time::convertTime(Buffer);
|
||||
}
|
||||
|
||||
void DateTime::operator=(DateTime& src) {
|
||||
@@ -471,7 +475,7 @@ double TimeQuantizer::computeSecondsFromResolution(const int valueIn, const char
|
||||
bool TimeQuantizer::quantize(Time& t, bool clamp) {
|
||||
ZoneScoped
|
||||
|
||||
const std::string unquantizedStr = t.ISO8601();
|
||||
std::string_view unquantizedStr = t.ISO8601();
|
||||
DateTime unquantized(unquantizedStr);
|
||||
// resolutionFraction helps to improve iteration performance
|
||||
constexpr const double ResolutionFraction = 0.7;
|
||||
@@ -514,7 +518,7 @@ bool TimeQuantizer::quantize(Time& t, bool clamp) {
|
||||
return true;
|
||||
}
|
||||
else if (clamp) {
|
||||
const std::string clampedTime = _timerange.clamp(unquantizedStr);
|
||||
const std::string clampedTime = _timerange.clamp(std::string(unquantizedStr));
|
||||
t.setTime(clampedTime);
|
||||
return true;
|
||||
}
|
||||
@@ -612,7 +616,7 @@ std::vector<std::string> TimeQuantizer::quantized(Time& start, Time& end) {
|
||||
|
||||
std::vector<std::string> result;
|
||||
DateTime itr = s;
|
||||
RangedTime range(start.ISO8601(), end.ISO8601());
|
||||
RangedTime range(std::string(start.ISO8601()), std::string(end.ISO8601()));
|
||||
while (range.includes(Time(itr.ISO8601()))) {
|
||||
itr.incrementOnce(static_cast<int>(_resolutionValue), _resolutionUnit);
|
||||
result.push_back(itr.ISO8601());
|
||||
|
||||
@@ -76,14 +76,14 @@ public:
|
||||
*
|
||||
* \returns The ISO8601 date/time string that defines the start of the range
|
||||
*/
|
||||
std::string start() const;
|
||||
std::string_view start() const;
|
||||
|
||||
/*
|
||||
* Get the end date/time of the time range
|
||||
*
|
||||
* \returns The ISO8601 date/time string that defines the end of the range
|
||||
*/
|
||||
std::string end() const;
|
||||
std::string_view end() const;
|
||||
|
||||
/*
|
||||
* Set the start date/time of the time range
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace {
|
||||
|
||||
openspace::gui::CaptionText("Mission Progress");
|
||||
|
||||
ImGui::Text("%s", startTime.UTC().c_str());
|
||||
ImGui::Text("%s", std::string(startTime.UTC()).c_str());
|
||||
ImGui::SameLine();
|
||||
float v = static_cast<float>(currentTime);
|
||||
const float s = static_cast<float>(startTime.j2000Seconds());
|
||||
@@ -74,10 +74,10 @@ namespace {
|
||||
&v,
|
||||
s,
|
||||
e,
|
||||
openspace::global::timeManager.time().UTC().c_str()
|
||||
std::string(openspace::global::timeManager.time().UTC()).c_str()
|
||||
);
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%s", endTime.UTC().c_str());
|
||||
ImGui::Text("%s", std::string(endTime.UTC()).c_str());
|
||||
|
||||
openspace::gui::CaptionText("Phases");
|
||||
|
||||
|
||||
@@ -211,7 +211,10 @@ void GuiSpaceTimeComponent::render() {
|
||||
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 10.f);
|
||||
|
||||
ImGui::Text("Current Date: %s", global::timeManager.time().UTC().c_str());
|
||||
ImGui::Text(
|
||||
"Current Date: %s",
|
||||
std::string(global::timeManager.time().UTC()).c_str()
|
||||
);
|
||||
|
||||
constexpr int BufferSize = 256;
|
||||
static char Buffer[BufferSize];
|
||||
@@ -296,7 +299,7 @@ void GuiSpaceTimeComponent::render() {
|
||||
|
||||
const bool nowDay = ImGui::Button("Now");
|
||||
if (nowDay) {
|
||||
std::string nowTime = Time::now().UTC();
|
||||
std::string nowTime = std::string(Time::now().UTC());
|
||||
// UTC returns a string of the type YYYY MMM DDTHH:mm:ss.xxx
|
||||
// setTime doesn't like the T in it and wants a space instead
|
||||
nowTime[11] = ' ';
|
||||
|
||||
@@ -269,8 +269,9 @@ std::string IswaManager::iswaUrl(int id, double timestamp, const std::string& ty
|
||||
}
|
||||
|
||||
//std::string t = Time::ref().currentTimeUTC();
|
||||
std::string t = SpiceManager::ref().dateFromEphemerisTime(timestamp);
|
||||
std::stringstream ss(t);
|
||||
std::string_view t = SpiceManager::ref().dateFromEphemerisTime(timestamp);
|
||||
std::stringstream ss;
|
||||
ss << t;
|
||||
std::string token;
|
||||
|
||||
std::getline(ss, token, ' ');
|
||||
|
||||
@@ -109,7 +109,7 @@ void TimeTopic::sendCurrentTime() {
|
||||
}
|
||||
|
||||
void TimeTopic::sendFullTimeData() {
|
||||
const std::string currentTime = global::timeManager.time().ISO8601();
|
||||
std::string_view currentTime = global::timeManager.time().ISO8601();
|
||||
const double deltaTime = global::timeManager.deltaTime();
|
||||
const double targetDeltaTime = global::timeManager.targetDeltaTime();
|
||||
const bool isPaused = global::timeManager.isPaused();
|
||||
|
||||
@@ -230,7 +230,7 @@ void DashboardItemInstruments::render(glm::vec2& penPosition) {
|
||||
ghoul::fontrendering::CrDirection::Down
|
||||
);
|
||||
|
||||
std::string str = SpiceManager::ref().dateFromEphemerisTime(
|
||||
std::string_view str = SpiceManager::ref().dateFromEphemerisTime(
|
||||
sequencer.nextCaptureTime(global::timeManager.time().j2000Seconds()),
|
||||
"YYYY MON DD HR:MN:SC"
|
||||
);
|
||||
|
||||
@@ -112,12 +112,12 @@ ghoul::Dictionary RawVolumeMetadata::dictionary() {
|
||||
}
|
||||
|
||||
if (hasTime) {
|
||||
std::string timeString = Time(time).ISO8601();
|
||||
std::string_view timeString = Time(time).ISO8601();
|
||||
// Do not include time offset in time string
|
||||
if (timeString.back() == 'Z') {
|
||||
timeString.pop_back();
|
||||
timeString = timeString.substr(0, timeString.size() - 1);
|
||||
}
|
||||
dict.setValue<std::string>(KeyTime, timeString);
|
||||
dict.setValue<std::string>(KeyTime, std::string(timeString));
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
|
||||
@@ -1057,6 +1057,8 @@ void OpenSpaceEngine::writeSceneDocumentation() {
|
||||
|
||||
void OpenSpaceEngine::preSynchronization() {
|
||||
ZoneScoped
|
||||
TracyGpuZone("preSynchronization")
|
||||
|
||||
LTRACE("OpenSpaceEngine::preSynchronization(begin)");
|
||||
|
||||
FileSys.triggerFilesystemEvents();
|
||||
@@ -1125,6 +1127,7 @@ void OpenSpaceEngine::preSynchronization() {
|
||||
|
||||
void OpenSpaceEngine::postSynchronizationPreDraw() {
|
||||
ZoneScoped
|
||||
TracyGpuZone("postSynchronizationPreDraw")
|
||||
LTRACE("OpenSpaceEngine::postSynchronizationPreDraw(begin)");
|
||||
|
||||
bool master = global::windowDelegate.isMaster();
|
||||
@@ -1196,6 +1199,7 @@ void OpenSpaceEngine::render(const glm::mat4& sceneMatrix, const glm::mat4& view
|
||||
const glm::mat4& projectionMatrix)
|
||||
{
|
||||
ZoneScoped
|
||||
TracyGpuZone("Render")
|
||||
LTRACE("OpenSpaceEngine::render(begin)");
|
||||
|
||||
const bool isGuiWindow =
|
||||
@@ -1220,6 +1224,7 @@ void OpenSpaceEngine::render(const glm::mat4& sceneMatrix, const glm::mat4& view
|
||||
|
||||
void OpenSpaceEngine::drawOverlays() {
|
||||
ZoneScoped
|
||||
TracyGpuZone("Draw2D")
|
||||
LTRACE("OpenSpaceEngine::drawOverlays(begin)");
|
||||
|
||||
const bool isGuiWindow =
|
||||
@@ -1244,6 +1249,7 @@ void OpenSpaceEngine::drawOverlays() {
|
||||
|
||||
void OpenSpaceEngine::postDraw() {
|
||||
ZoneScoped
|
||||
TracyGpuZone("postDraw")
|
||||
LTRACE("OpenSpaceEngine::postDraw(begin)");
|
||||
|
||||
global::renderEngine.postDraw();
|
||||
|
||||
@@ -1132,6 +1132,7 @@ void FramebufferRenderer::updateDownscaledVolume() {
|
||||
|
||||
void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFactor) {
|
||||
ZoneScoped
|
||||
TracyGpuZone("FramebufferRenderer")
|
||||
|
||||
GLint viewport[4];
|
||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
@@ -1177,25 +1178,31 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac
|
||||
RendererTasks tasks;
|
||||
|
||||
{
|
||||
TracyGpuZone("Background")
|
||||
GLDebugGroup group("Background");
|
||||
data.renderBinMask = static_cast<int>(Renderable::RenderBin::Background);
|
||||
scene->render(data, tasks);
|
||||
}
|
||||
|
||||
{
|
||||
TracyGpuZone("Opaque")
|
||||
GLDebugGroup group("Opaque");
|
||||
data.renderBinMask = static_cast<int>(Renderable::RenderBin::Opaque);
|
||||
scene->render(data, tasks);
|
||||
}
|
||||
|
||||
{
|
||||
TracyGpuZone("PreDeferredTransparent")
|
||||
GLDebugGroup group("PreDeferredTransparent");
|
||||
data.renderBinMask = static_cast<int>(Renderable::RenderBin::PreDeferredTransparent);
|
||||
data.renderBinMask = static_cast<int>(
|
||||
Renderable::RenderBin::PreDeferredTransparent
|
||||
);
|
||||
scene->render(data, tasks);
|
||||
}
|
||||
|
||||
// Run Volume Tasks
|
||||
{
|
||||
TracyGpuZone("Raycaster Tasks")
|
||||
GLDebugGroup group("Raycaster Tasks");
|
||||
performRaycasterTasks(tasks.raycasterTasks);
|
||||
|
||||
@@ -1205,6 +1212,7 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac
|
||||
}
|
||||
|
||||
if (!tasks.deferredcasterTasks.empty()) {
|
||||
TracyGpuZone("Deferred Caster Tasks")
|
||||
GLDebugGroup group("Deferred Caster Tasks");
|
||||
|
||||
// We use ping pong rendering in order to be able to
|
||||
@@ -1220,12 +1228,16 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac
|
||||
glEnablei(GL_BLEND, 0);
|
||||
|
||||
{
|
||||
TracyGpuZone("PostDeferredTransparent")
|
||||
GLDebugGroup group("PostDeferredTransparent");
|
||||
data.renderBinMask = static_cast<int>(Renderable::RenderBin::PostDeferredTransparent);
|
||||
data.renderBinMask = static_cast<int>(
|
||||
Renderable::RenderBin::PostDeferredTransparent
|
||||
);
|
||||
scene->render(data, tasks);
|
||||
}
|
||||
|
||||
{
|
||||
TracyGpuZone("Overlay")
|
||||
GLDebugGroup group("Overlay");
|
||||
data.renderBinMask = static_cast<int>(Renderable::RenderBin::Overlay);
|
||||
scene->render(data, tasks);
|
||||
@@ -1252,12 +1264,14 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac
|
||||
|
||||
{
|
||||
// Apply the selected TMO on the results and resolve the result to the default FBO
|
||||
TracyGpuZone("Apply TMO")
|
||||
GLDebugGroup group("Apply TMO");
|
||||
|
||||
applyTMO(blackoutFactor);
|
||||
}
|
||||
|
||||
if (_enableFXAA) {
|
||||
TracyGpuZone("Apply FXAA")
|
||||
GLDebugGroup group("Apply FXAA");
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO);
|
||||
applyFXAA();
|
||||
@@ -1268,6 +1282,8 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector<RaycasterTask>
|
||||
ZoneScoped
|
||||
|
||||
for (const RaycasterTask& raycasterTask : tasks) {
|
||||
TracyGpuZone("Raycaster")
|
||||
|
||||
VolumeRaycaster* raycaster = raycasterTask.raycaster;
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _exitFramebuffer);
|
||||
@@ -1399,6 +1415,8 @@ void FramebufferRenderer::performDeferredTasks(
|
||||
ZoneScoped
|
||||
|
||||
for (const DeferredcasterTask& deferredcasterTask : tasks) {
|
||||
TracyGpuZone("Deferredcaster")
|
||||
|
||||
Deferredcaster* deferredcaster = deferredcasterTask.deferredcaster;
|
||||
|
||||
ghoul::opengl::ProgramObject* deferredcastProgram = nullptr;
|
||||
|
||||
@@ -80,7 +80,7 @@ int saveSettingsToProfile(lua_State* L) {
|
||||
}
|
||||
|
||||
const properties::PropertyOwner& root = global::rootPropertyOwner;
|
||||
std::string currentTime = global::timeManager.time().ISO8601();
|
||||
std::string currentTime = std::string(global::timeManager.time().ISO8601());
|
||||
interaction::NavigationHandler::NavigationState navState =
|
||||
global::navigationHandler.navigationState();
|
||||
global::profile.saveCurrentSettingsToProfile(root, currentTime, navState);
|
||||
|
||||
@@ -43,18 +43,6 @@ namespace {
|
||||
// as the maximum message length
|
||||
constexpr const unsigned SpiceErrorBufferSize = 1841;
|
||||
|
||||
// This method checks if one of the previous SPICE methods has failed. If it has, an
|
||||
// exception with the SPICE error message is thrown
|
||||
// If an error occurred, true is returned, otherwise, false
|
||||
void throwSpiceError(const std::string& errorMessage) {
|
||||
if (openspace::SpiceManager::ref().exceptionHandling()) {
|
||||
char buffer[SpiceErrorBufferSize];
|
||||
getmsg_c("LONG", SpiceErrorBufferSize, buffer);
|
||||
reset_c();
|
||||
throw openspace::SpiceManager::SpiceException(errorMessage + ": " + buffer);
|
||||
}
|
||||
}
|
||||
|
||||
const char* toString(openspace::SpiceManager::FieldOfViewMethod m) {
|
||||
using SM = openspace::SpiceManager;
|
||||
switch (m) {
|
||||
@@ -196,6 +184,18 @@ SpiceManager& SpiceManager::ref() {
|
||||
return *_instance;
|
||||
}
|
||||
|
||||
// This method checks if one of the previous SPICE methods has failed. If it has, an
|
||||
// exception with the SPICE error message is thrown
|
||||
// If an error occurred, true is returned, otherwise, false
|
||||
void throwSpiceError(const std::string& errorMessage) {
|
||||
if (openspace::SpiceManager::ref().exceptionHandling()) {
|
||||
char buffer[SpiceErrorBufferSize];
|
||||
getmsg_c("LONG", SpiceErrorBufferSize, buffer);
|
||||
reset_c();
|
||||
throw openspace::SpiceManager::SpiceException(errorMessage + ": " + buffer);
|
||||
}
|
||||
}
|
||||
|
||||
SpiceManager::KernelHandle SpiceManager::loadKernel(std::string filePath) {
|
||||
ghoul_assert(!filePath.empty(), "Empty file path");
|
||||
ghoul_assert(
|
||||
@@ -474,58 +474,20 @@ double SpiceManager::spacecraftClockToET(const std::string& craft, double craftT
|
||||
double SpiceManager::ephemerisTimeFromDate(const std::string& timeString) const {
|
||||
ghoul_assert(!timeString.empty(), "Empty timeString");
|
||||
|
||||
return ephemerisTimeFromDate(timeString.c_str());
|
||||
}
|
||||
|
||||
double SpiceManager::ephemerisTimeFromDate(const char* timeString) const {
|
||||
ghoul_assert(!timeString.empty(), "Empty timeString");
|
||||
|
||||
double et;
|
||||
str2et_c(timeString.c_str(), &et);
|
||||
str2et_c(timeString, &et);
|
||||
if (failed_c()) {
|
||||
throwSpiceError(fmt::format("Error converting date '{}'", timeString));
|
||||
}
|
||||
return et;
|
||||
}
|
||||
|
||||
std::string SpiceManager::dateFromEphemerisTime(double ephemerisTime,
|
||||
std::string_view format) const
|
||||
{
|
||||
ghoul_assert(!formatString.empty(), "Format is empty");
|
||||
ghoul_assert(formatString.back() == '\0', "Format string must be null-terminated");
|
||||
|
||||
if (format.size() < 32) {
|
||||
constexpr const int BufferSize = 32;
|
||||
SpiceChar buffer[BufferSize];
|
||||
dateFromEphemerisTime(ephemerisTime, buffer, BufferSize, format);
|
||||
return std::string(buffer);
|
||||
}
|
||||
else if (format.size() < 256) {
|
||||
constexpr const int BufferSize = 256;
|
||||
SpiceChar buffer[BufferSize];
|
||||
dateFromEphemerisTime(ephemerisTime, buffer, BufferSize, format);
|
||||
return std::string(buffer);
|
||||
}
|
||||
else {
|
||||
std::string res;
|
||||
res.resize(format.size() + 1);
|
||||
dateFromEphemerisTime(ephemerisTime, res.data(), format.size(), format);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
void SpiceManager::dateFromEphemerisTime(double ephemerisTime, char* outBuf,
|
||||
int bufferSize,
|
||||
std::string_view formatString) const
|
||||
{
|
||||
ghoul_assert(!formatString.empty(), "Format is empty");
|
||||
ghoul_assert(formatString.back() == '\0', "Format string must be null-terminated");
|
||||
ghoul_assert(formatString.size() > bufferSize - 1, "Buffer size too small");
|
||||
|
||||
timout_c(ephemerisTime, formatString.data(), bufferSize - 1, outBuf);
|
||||
if (failed_c()) {
|
||||
throwSpiceError(
|
||||
fmt::format("Error converting ephemeris time '{}' to date with format '{}'",
|
||||
ephemerisTime, formatString
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
glm::dvec3 SpiceManager::targetPosition(const std::string& target,
|
||||
const std::string& observer,
|
||||
const std::string& referenceFrame,
|
||||
|
||||
@@ -24,7 +24,9 @@
|
||||
|
||||
#include <openspace/util/time.h>
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <openspace/util/memorymanager.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <openspace/util/syncbuffer.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
@@ -43,6 +45,10 @@ double Time::convertTime(const std::string& time) {
|
||||
return SpiceManager::ref().ephemerisTimeFromDate(time);
|
||||
}
|
||||
|
||||
double Time::convertTime(const char* time) {
|
||||
return SpiceManager::ref().ephemerisTimeFromDate(time);
|
||||
}
|
||||
|
||||
Time::Time(double secondsJ2000) : _time(secondsJ2000) {}
|
||||
|
||||
Time::Time(const std::string& time) :
|
||||
@@ -79,17 +85,26 @@ void Time::setTime(const std::string& time) {
|
||||
_time = SpiceManager::ref().ephemerisTimeFromDate(time);
|
||||
}
|
||||
|
||||
std::string Time::UTC() const {
|
||||
return SpiceManager::ref().dateFromEphemerisTime(_time);
|
||||
std::string_view Time::UTC() const {
|
||||
constexpr const char Format[] = "YYYY MON DDTHR:MN:SC.### ::RND";
|
||||
char* b = reinterpret_cast<char*>(global::memoryManager.TemporaryMemory.allocate(32));
|
||||
std::memset(b, 0, 32);
|
||||
|
||||
SpiceManager::ref().dateFromEphemerisTime(_time, b, 32, Format);
|
||||
|
||||
return std::string_view(b, 32);
|
||||
}
|
||||
|
||||
std::string Time::ISO8601() const {
|
||||
std::string_view Time::ISO8601() const {
|
||||
ZoneScoped
|
||||
|
||||
return SpiceManager::ref().dateFromEphemerisTime(
|
||||
_time,
|
||||
"YYYY-MM-DDTHR:MN:SC.###"
|
||||
);
|
||||
constexpr const char Format[] = "YYYY-MM-DDTHR:MN:SC.###";
|
||||
char* b = reinterpret_cast<char*>(global::memoryManager.TemporaryMemory.allocate(24));
|
||||
std::memset(b, 0, 24);
|
||||
|
||||
SpiceManager::ref().dateFromEphemerisTime(_time, b, 24, Format);
|
||||
|
||||
return std::string_view(b, 24);
|
||||
}
|
||||
|
||||
scripting::LuaLibrary Time::luaLibrary() {
|
||||
|
||||
@@ -506,7 +506,7 @@ int time_interpolateTimeRelative(lua_State* L) {
|
||||
* It is returned by calling the Time::currentTime method.
|
||||
*/
|
||||
int time_currentTime(lua_State* L) {
|
||||
lua_pushnumber(L, global::timeManager.time().j2000Seconds());
|
||||
ghoul::lua::push(L, global::timeManager.time().j2000Seconds());
|
||||
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
|
||||
return 1;
|
||||
}
|
||||
@@ -518,7 +518,7 @@ int time_currentTime(lua_State* L) {
|
||||
* timezone by calling the Time::UTC method
|
||||
*/
|
||||
int time_currentTimeUTC(lua_State* L) {
|
||||
lua_pushstring(L, global::timeManager.time().UTC().c_str());
|
||||
ghoul::lua::push(L, global::timeManager.time().UTC());
|
||||
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user