Some rework for renderableTrailTrajectory (#3742)

Removed feature sweepChunk.
The feature was implemented for version 0.19.0 as an iterative way to calculate renderableTrailTrajectory.
However, due to the function not being active by default, and due multithreading being on the horizon for SPICE2, this code is now removed.

- Removed SweepChunk feature
- Added toggle for Accurate Trail Points (in asset: AccurateTrail)
- Changed min number of accurate points from 0 to 2
- Removed max vertices ceiling
- Fixed issue where number of vertices were not calculated properly
- Fixed point size rendering issue for RenderableTrail
- Changed start/end time for voyager 1 & 2
- Updated description for SampleInterval and TimeStampSubsampleFactor to be more clear
- Moved full sweep pass from update function to new updateBuffer function
- Fixed trail rendering issue when time is exact same as start time of a trail
This commit is contained in:
Adam Rohdin
2025-08-15 09:59:08 +02:00
committed by GitHub
parent 204a929fe7
commit 559190d7d7
8 changed files with 187 additions and 259 deletions
@@ -45,7 +45,8 @@ local Pioneer10Trail = {
Color = { 0.70, 0.50, 0.20 },
StartTime = "1972 MAR 03 02:04:00",
EndTime = "1990 JAN 02 00:00:00",
EnableFade = false
EnableFade = false,
SampleInterval = 1800
},
GUI = {
Name = "Pioneer 10 Trail (SPICE)",
@@ -50,7 +50,8 @@ local Pioneer11Trail = {
Color = { 0.70, 0.50, 0.20 },
StartTime = "1973 APR 06 02:25:00.000",
EndTime = "1990 JAN 02 00:00:00.000",
EnableFade = false
EnableFade = false,
SampleInterval = 1800
},
GUI = {
Name = "Pioneer 11 Trail (SPICE)",
@@ -117,8 +117,7 @@ local VoyagerTrailEncounterJupiter = {
},
Color = { 0.70, 0.50, 0.20 },
EnableFade = false,
-- @TODO: Probably an off-by-one bug in RenderableTrailTrajectory?
StartTime = "1979 MAR 03 23:24:00",
StartTime = "1979 MAR 04",
EndTime = "1979 MAR 09",
SampleInterval = 100
},
@@ -167,8 +166,7 @@ local VoyagerTrailEncounterSaturn = {
},
EnableFade = false,
Color = { 0.70, 0.50, 0.20 },
-- @TODO: Probably an off-by-one bug in RenderableTrailTrajectory?
StartTime = "1980 NOV 10 23:08:30",
StartTime = "1980 NOV 11",
EndTime = "1980 NOV 16",
SampleInterval = 100
},
@@ -120,8 +120,7 @@ local VoyagerTrailEncounterJupiter = {
},
Color = { 0.70, 0.50, 0.20 },
EnableFade = false,
-- @TODO: Probably an off-by-one bug in RenderableTrailTrajectory?
StartTime = "1979 JUL 05 23:24:00",
StartTime = "1979 JUL 06",
EndTime = "1979 JUL 15",
SampleInterval = 100
},
@@ -170,8 +169,7 @@ local VoyagerTrailEncounterSaturn = {
},
EnableFade = false,
Color = { 0.70, 0.50, 0.20 },
-- @TODO: Probably an off-by-one bug in RenderableTrailTrajectory?
StartTime = "1981 AUG 22 23:08:30",
StartTime = "1981 AUG 23",
EndTime = "1981 AUG 30",
SampleInterval = 100
},
@@ -220,8 +218,7 @@ local VoyagerTrailEncounterUranus = {
},
EnableFade = false,
Color = { 0.70, 0.50, 0.20 },
-- @TODO: Probably an off-by-one bug in RenderableTrailTrajectory?
StartTime = "1986 JAN 21 23:30:00",
StartTime = "1986 JAN 22",
EndTime = "1986 JAN 27",
SampleInterval = 100
},
@@ -270,8 +267,7 @@ local VoyagerTrailEncounterNeptune = {
},
EnableFade = false,
Color = { 0.70, 0.50, 0.20 },
-- @TODO: Probably an off-by-one bug in RenderableTrailTrajectory?
StartTime = "1989 AUG 23 22:30:00",
StartTime = "1989 AUG 24",
EndTime = "1989 AUG 26",
SampleInterval = 100
},
+1 -1
View File
@@ -101,7 +101,7 @@ namespace {
"Line Fade Amount",
"The amount of the trail that should be faded. If the value is 0 then the "
"trail will have no fading applied. A value of 0.6 will result in a trail "
"where 60% of the extent of the trail will have fading applied to it. In other"
"where 60% of the extent of the trail will have fading applied to it. In other "
"words, the 40% closest to the head of the trail will be solid and the rest "
"will fade until completely transparent at the end of the trail. A value of 1 "
"will result in a trail that starts fading immediately, becoming fully "
@@ -65,9 +65,8 @@ namespace {
"SampleInterval",
"Sample Interval",
"The interval between samples of the trajectory. This value (together with "
"'TimeStampSubsampleFactor') determines how far apart (in time) the samples are "
"spaced along the trajectory. The time interval between 'StartTime' and "
"'EndTime' is split into 'SampleInterval' * 'TimeStampSubsampleFactor' segments.",
"'TimeStampSubsampleFactor') determines how far apart (in seconds) the samples "
"are spaced along the trajectory.",
openspace::properties::Property::Visibility::AdvancedUser
};
@@ -75,9 +74,10 @@ namespace {
"TimeStampSubsampleFactor",
"Time Stamp Subsampling Factor",
"The factor that is used to create subsamples along the trajectory. This value "
"(together with 'SampleInterval') determines how far apart (in time) the samples "
"are spaced along the trajectory. The time interval between 'StartTime' and "
"'EndTime' is split into 'SampleInterval' * 'TimeStampSubsampleFactor' segments.",
"(together with 'SampleInterval') determines how far apart (in seconds) the "
"samples are spaced along the trajectory. Subsamples are rendered as smaller "
"points compared to normal samples (from 'SampleInterval') when rendering the "
"trail as points.",
openspace::properties::Property::Visibility::AdvancedUser
};
@@ -89,23 +89,11 @@ namespace {
openspace::properties::Property::Visibility::NoviceUser
};
constexpr openspace::properties::Property::PropertyInfo SweepChunkSizeInfo = {
"SweepChunkSize",
"Sweep Chunk Size",
"The number of vertices that will be calculated each frame whenever the trail "
"needs to be recalculated. A greater value will result in more calculations per "
"frame.",
openspace::properties::Property::Visibility::AdvancedUser
};
constexpr openspace::properties::Property::PropertyInfo EnableSweepChunkingInfo = {
"EnableSweepChunking",
"Use Sweep Chunking",
"Enable or Disable the use of iterative calculations (chunking) during full "
"sweep vertex calculations. When enabled, small part of the trail will be "
"calculated each frame instead of calculating the entire trail in one go. "
"The size of each 'chunk' can be altered by changing the sweep chunk size "
"property.",
constexpr openspace::properties::Property::PropertyInfo AccurateTrailInfo = {
"AccurateTrail",
"Use Accurate Trail",
"If true, the trail around the spacecraft will be recalculated to present a "
"smoother trail. If false, the original trail will be used.",
openspace::properties::Property::Visibility::AdvancedUser
};
@@ -125,25 +113,21 @@ namespace {
// [[codegen::verbatim(EndTimeInfo.description)]]
std::string endTime [[codegen::annotation("A valid date in ISO 8601 format")]];
// The interval between samples of the trajectory. This value (together with
// 'TimeStampSubsampleFactor') determines how far apart (in time) the samples are
// spaced along the trajectory. The time interval between 'StartTime' and
// 'EndTime' is split into 'SampleInterval' * 'TimeStampSubsampleFactor' segments.
// If this value is not specified, it will be automatically calculated to produce
// one sample every two day between the 'StartTime' and 'EndTime'.
// [[codegen::verbatim(SampleIntervalInfo.description)]]
// The final interval is calculated as SampleInterval/TimeStampSubsampleFactor.
// If SampleInterval is not specified, it will be automatically calculated to produce
// two samples per day between the 'StartTime' and 'EndTime'.
std::optional<double> sampleInterval;
// [[codegen::verbatim(TimeSubSampleInfo.description)]]
// The final interval is calculated as SampleInterval/TimeStampSubsampleFactor.
std::optional<int> timeStampSubsampleFactor;
// [[codegen::verbatim(RenderFullPathInfo.description)]]
std::optional<bool> showFullTrail;
// [[codegen::verbatim(SweepChunkSizeInfo.description)]]
std::optional<int> sweepChunkSize;
// [[codegen::verbatim(SweepChunkSizeInfo.description)]]
std::optional<bool> enableSweepChunking;
// [[codegen::verbatim(AccurateTrailInfo.description)]]
std::optional<bool> useAccurateTrail;
// [[codegen::verbatim(AccurateTrailPositionsInfo.description)]]
std::optional<int> accurateTrailPositions;
@@ -162,14 +146,18 @@ documentation::Documentation RenderableTrailTrajectory::Documentation() {
RenderableTrailTrajectory::RenderableTrailTrajectory(const ghoul::Dictionary& dictionary)
: RenderableTrail(dictionary)
, _sweepChunkSize(SweepChunkSizeInfo, 200, 50, 5000)
, _enableSweepChunking(EnableSweepChunkingInfo, false)
, _startTime(StartTimeInfo)
, _endTime(EndTimeInfo)
, _sampleInterval(SampleIntervalInfo, 2.0, 2.0, 1e6)
, _timeStampSubsamplingFactor(TimeSubSampleInfo, 1, 1, 1000000000)
, _sampleInterval(
SampleIntervalInfo,
openspace::timeconstants::SecondsPerDay / 2.0,
1.0,
1e6
)
, _timeStampSubsamplingFactor(TimeSubSampleInfo, 1, 1, 100)
, _renderFullTrail(RenderFullPathInfo, false)
, _nReplacementPoints(AccurateTrailPositionsInfo, 100, 0, 1000)
, _useAccurateTrail(AccurateTrailInfo, true)
, _nReplacementPoints(AccurateTrailPositionsInfo, 100, 2, 1000)
, _maxVertex(glm::vec3(-std::numeric_limits<float>::max()))
, _minVertex(glm::vec3(std::numeric_limits<float>::max()))
{
@@ -180,6 +168,15 @@ RenderableTrailTrajectory::RenderableTrailTrajectory(const ghoul::Dictionary& di
_renderFullTrail = p.showFullTrail.value_or(_renderFullTrail);
addProperty(_renderFullTrail);
_useAccurateTrail = p.useAccurateTrail.value_or(_useAccurateTrail);
addProperty(_useAccurateTrail);
_nReplacementPoints = p.accurateTrailPositions.value_or(_nReplacementPoints);
_nReplacementPoints.onChange([this]() {
_nReplacementPoints = std::max<int>(2, _nReplacementPoints);
});
addProperty(_nReplacementPoints);
_startTime = p.startTime;
_startTime.onChange([this] { reset(); });
addProperty(_startTime);
@@ -188,30 +185,16 @@ RenderableTrailTrajectory::RenderableTrailTrajectory(const ghoul::Dictionary& di
_endTime.onChange([this] { reset(); });
addProperty(_endTime);
if (p.sampleInterval.has_value()) {
_sampleInterval = *p.sampleInterval;
}
else {
const double delta = Time::convertTime(_endTime) - Time::convertTime(_startTime);
_sampleInterval = delta / (openspace::timeconstants::SecondsPerYear * 2);
}
_sampleInterval.onChange([this] { reset(); });
_sampleInterval = p.sampleInterval.value_or(_sampleInterval);
_sampleInterval.onChange([this]() { reset(); });
addProperty(_sampleInterval);
_timeStampSubsamplingFactor =
p.timeStampSubsampleFactor.value_or(_timeStampSubsamplingFactor);
_timeStampSubsamplingFactor.onChange([this] { _subsamplingIsDirty = true; });
_timeStampSubsamplingFactor.onChange([this]() { reset(); });
addProperty(_timeStampSubsamplingFactor);
_nReplacementPoints = p.accurateTrailPositions.value_or(_nReplacementPoints);
addProperty(_nReplacementPoints);
_enableSweepChunking = p.enableSweepChunking.value_or(_enableSweepChunking);
addProperty(_enableSweepChunking);
_sweepChunkSize = p.sweepChunkSize.value_or(_sweepChunkSize);
addProperty(_sweepChunkSize);
// We store the vertices with ascending temporal order
_primaryRenderInformation.sorting = RenderInformation::VertexSorting::OldestFirst;
_secondaryRenderInformation.sorting = RenderInformation::VertexSorting::OldestFirst;
@@ -249,109 +232,79 @@ void RenderableTrailTrajectory::deinitializeGL() {
void RenderableTrailTrajectory::reset() {
_needsFullSweep = true;
_sweepIteration = 0;
_maxVertex = glm::vec3(-std::numeric_limits<float>::max());
_minVertex = glm::vec3(std::numeric_limits<float>::max());
}
void RenderableTrailTrajectory::updateBuffer() {
// Convert the start and end time from string representations to J2000 seconds
_start = SpiceManager::ref().ephemerisTimeFromDate(_startTime);
_end = SpiceManager::ref().ephemerisTimeFromDate(_endTime);
const double timespan = _end - _start;
_totalSampleInterval = _sampleInterval / _timeStampSubsamplingFactor;
_nVertices = static_cast<unsigned int>(std::ceil(timespan / _totalSampleInterval));
// Make space for the vertices
_vertexArray.clear();
_dVertexArray.clear();
_timeVector.clear();
_vertexArray.resize(_nVertices + 1);
_dVertexArray.resize(_nVertices + 1);
_timeVector.resize(_nVertices + 1);
// Calculate all vertex positions
for (unsigned int i = 0; i < _nVertices; i++) {
const glm::dvec3 dp = translationPosition(
Time(_start + i * _totalSampleInterval)
);
const glm::vec3 p = dp;
_vertexArray[i] = { p.x, p.y, p.z };
_timeVector[i] = Time(_start + i * _totalSampleInterval).j2000Seconds();
_dVertexArray[i] = { dp.x, dp.y, dp.z };
// Set max and min vertex for bounding sphere calculations
_maxVertex = glm::max(_maxVertex, dp);
_minVertex = glm::min(_minVertex, dp);
}
// Full sweep is complete here.
// Adds the last point in time to the _vertexArray so that we
// ensure that points for _start and _end always exists
const glm::dvec3 dp = translationPosition(Time(_end));
const glm::vec3 p = dp;
_vertexArray[_nVertices] = { p.x, p.y, p.z };
_timeVector[_nVertices] = Time(_end).j2000Seconds();
_dVertexArray[_nVertices] = { dp.x, dp.y, dp.z };
setBoundingSphere(glm::distance(_maxVertex, _minVertex) / 2.0);
// Upload vertices to the GPU
glBindVertexArray(_primaryRenderInformation._vaoID);
glBindBuffer(GL_ARRAY_BUFFER, _primaryRenderInformation._vBufferID);
glBufferData(
GL_ARRAY_BUFFER,
_vertexArray.size() * sizeof(TrailVBOLayout<float>),
_vertexArray.data(),
GL_STATIC_DRAW
);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
// We clear the indexArray just in case. The base class will take care not to use
// it if it is empty
_indexArray.clear();
_primaryRenderInformation.stride = _timeStampSubsamplingFactor;
_secondaryRenderInformation.stride = _timeStampSubsamplingFactor;
_floatingRenderInformation.stride = _timeStampSubsamplingFactor;
_needsFullSweep = false;
}
void RenderableTrailTrajectory::update(const UpdateData& data) {
if (_needsFullSweep) {
if (_sweepIteration == 0) {
constexpr unsigned int MaxVertices = 1000000;
// Convert the start and end time from string representations to J2000 seconds
_start = SpiceManager::ref().ephemerisTimeFromDate(_startTime);
_end = SpiceManager::ref().ephemerisTimeFromDate(_endTime);
const double timespan = _end - _start;
_totalSampleInterval = _sampleInterval / _timeStampSubsamplingFactor;
// Cap _nVertices in order to prevent overflow and extreme performance
// degredation/RAM usage
_nVertices = std::min(
static_cast<unsigned int>(std::ceil(timespan / _totalSampleInterval)),
MaxVertices
);
// We need to recalcuate the _totalSampleInterval if _nVertices equals
// MaxVertices. If we don't do this the position for each vertex
// will not be correct for the number of vertices we are doing along the trail
_totalSampleInterval = (_nVertices == MaxVertices) ?
(timespan / _nVertices) : _totalSampleInterval;
// Make space for the vertices
_vertexArray.clear();
_dVertexArray.clear();
_timeVector.clear();
_vertexArray.resize(_nVertices + 1);
_dVertexArray.resize(_nVertices + 1);
_timeVector.resize(_nVertices + 1);
}
// Calculate sweeping range for this iteration
const unsigned int startIndex = _sweepIteration * _sweepChunkSize;
const unsigned int nextIndex = (_sweepIteration + 1) * _sweepChunkSize;
unsigned int stopIndex = std::min(nextIndex, _nVertices);
// If iterative calculations are disabled
if (!_enableSweepChunking) {
stopIndex = _nVertices;
}
// Calculate all vertex positions
for (unsigned int i = startIndex; i < stopIndex; i++) {
const glm::dvec3 dp = translationPosition(
Time(_start + i * _totalSampleInterval)
);
const glm::vec3 p(dp.x, dp.y, dp.z);
_vertexArray[i] = { p.x, p.y, p.z };
_timeVector[i] = Time(_start + i * _totalSampleInterval).j2000Seconds();
_dVertexArray[i] = {dp.x, dp.y, dp.z};
// Set max and min vertex for bounding sphere calculations
_maxVertex = glm::max(_maxVertex, dp);
_minVertex = glm::min(_minVertex, dp);
}
++_sweepIteration;
// Full sweep is complete here.
// Adds the last point in time to the _vertexArray so that we
// ensure that points for _start and _end always exists
if (stopIndex == _nVertices) {
const glm::dvec3 dp = translationPosition(Time(_end));
const glm::vec3 p(dp.x, dp.y, dp.z);
_vertexArray[stopIndex] = { p.x, p.y, p.z };
_timeVector[stopIndex] = Time(_end).j2000Seconds();
_dVertexArray[stopIndex] = { dp.x, dp.y, dp.z };
_sweepIteration = 0;
setBoundingSphere(glm::distance(_maxVertex, _minVertex) / 2.0);
}
else {
// Early return as we don't need to render if we are still
// doing full sweep calculations
return;
}
// Upload vertices to the GPU
glBindVertexArray(_primaryRenderInformation._vaoID);
glBindBuffer(GL_ARRAY_BUFFER, _primaryRenderInformation._vBufferID);
glBufferData(
GL_ARRAY_BUFFER,
_vertexArray.size() * sizeof(TrailVBOLayout<float>),
_vertexArray.data(),
GL_STATIC_DRAW
);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
// We clear the indexArray just in case. The base class will take care not to use
// it if it is empty
_indexArray.clear();
_subsamplingIsDirty = true;
_needsFullSweep = false;
updateBuffer();
}
// This has to be done every update step;
@@ -372,7 +325,7 @@ void RenderableTrailTrajectory::update(const UpdateData& data) {
// Calculates number of vertices for the second segment (object to end point)
_secondaryRenderInformation.first = _primaryRenderInformation.count;
_secondaryRenderInformation.count = static_cast<GLsizei>(
_vertexArray.size() - (_primaryRenderInformation.count)
_vertexArray.size() - _primaryRenderInformation.count
);
// Calculate number of vertices in the trail
@@ -389,32 +342,28 @@ void RenderableTrailTrajectory::update(const UpdateData& data) {
_nUniqueVertices = _primaryRenderInformation.count;
}
// Determine the number of points to be recalculated
int prePaddingDelta = 0;
if (!_renderFullTrail && _nReplacementPoints == 0) {
// Enables trail from last point to current position
// if we don't do any replacement points
prePaddingDelta = 1;
}
else {
prePaddingDelta = std::min(
static_cast<int>(_primaryRenderInformation.count),
static_cast<int>(_nReplacementPoints)
);
}
int postPaddingDelta = std::min(
static_cast<int>(_secondaryRenderInformation.count),
static_cast<int>(_nReplacementPoints)
);
// Get current position of the object
const glm::dvec3 p = translationPosition(data.time);
// Calculates all replacement points before the object
// Determine the number of points before the object to be recalculated
int prePaddingDelta = 0;
if (_useAccurateTrail) {
prePaddingDelta = std::min<int>(
_primaryRenderInformation.count,
_nReplacementPoints
);
}
else if (_renderFullTrail) {
_primaryRenderInformation.count += 1;
}
else {
prePaddingDelta = std::min(_primaryRenderInformation.count, 2);
}
glm::dvec3 v = p;
for (int i = 0; i < prePaddingDelta; ++i) {
for (int i = 0; i < prePaddingDelta; i++) {
const int floatPointIndex =
_primaryRenderInformation.count - prePaddingDelta + i;
(_primaryRenderInformation.count - prePaddingDelta) + i;
glm::dvec3 fp = glm::dvec3(
_vertexArray[floatPointIndex].x,
@@ -431,17 +380,11 @@ void RenderableTrailTrajectory::update(const UpdateData& data) {
glm::dvec3 dv = fp - dp;
glm::dvec3 newPoint = dp - v;
// Scales position offset for smooth transition from '
// original points to accurate points
double mult = 0.0;
if (i == prePaddingDelta - 1) {
mult = (i == 0) ? 1.0 : 0.0;
}
else {
mult = (prePaddingDelta - i) / static_cast<double>(prePaddingDelta);
}
// Scales offset for smooth transition from original to accurate points
const double mult = (i == prePaddingDelta - 1 && i > 0) ?
0.0 : (prePaddingDelta - i) / static_cast<double>(prePaddingDelta);
newPoint = newPoint + dv * mult;
newPoint += dv * pow(mult, 2.0);
_replacementPoints.push_back({
static_cast<float>(newPoint.x),
static_cast<float>(newPoint.y),
@@ -450,13 +393,21 @@ void RenderableTrailTrajectory::update(const UpdateData& data) {
}
// Mid-point (model-space position for the object)
if (_nReplacementPoints > 0 || !_renderFullTrail) {
if (_useAccurateTrail || !_renderFullTrail) {
_replacementPoints.push_back({ 0.f, 0.f, 0.f });
}
// Calculates all replacement points after the object
v = glm::dvec3(p.x, p.y, p.z);
for (int i = 0; i < postPaddingDelta; ++i) {
int postPaddingDelta = _secondaryRenderInformation.count;
if (_useAccurateTrail) {
postPaddingDelta = std::min<int>(
_secondaryRenderInformation.count,
_nReplacementPoints
);
}
v = p;
for (int i = 0; i < postPaddingDelta; i++) {
const int floatPointIndex = _secondaryRenderInformation.first + i;
glm::dvec3 fp = glm::dvec3(
@@ -474,13 +425,13 @@ void RenderableTrailTrajectory::update(const UpdateData& data) {
glm::dvec3 dv = fp - dp;
glm::dvec3 newPoint = dp - v;
// Scales position offset for smooth transition from '
// original points to accurate points
double mult = (i == postPaddingDelta - 1) ?
1.0 :
1.0 - (postPaddingDelta - i) / static_cast<double>(postPaddingDelta);
// Scales offset for smooth transition from original to accurate points
double mult = 1.0;
if (_useAccurateTrail && i != postPaddingDelta - 1) {
mult -= (postPaddingDelta - i) / static_cast<double>(postPaddingDelta);
}
newPoint = newPoint + dv * mult;
newPoint += dv * pow(mult, 2.0);
_replacementPoints.push_back({
static_cast<float>(newPoint.x),
static_cast<float>(newPoint.y),
@@ -497,7 +448,7 @@ void RenderableTrailTrajectory::update(const UpdateData& data) {
// Adjusts number of unique vertices if we have inserted a new mid point
if (_floatingRenderInformation.count > 0 && _renderFullTrail) {
_nUniqueVertices++;
_nUniqueVertices += 1;
}
// Recalculate .count and .first based on the recalculated (floating) vertices
@@ -522,16 +473,6 @@ void RenderableTrailTrajectory::update(const UpdateData& data) {
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
}
else if (j2k >= _end || (j2k < _start && _renderFullTrail)) {
// Renders the whole trail if time has passed the end time
_primaryRenderInformation.first = 0;
_primaryRenderInformation.count = static_cast<GLsizei>(_vertexArray.size());
_nUniqueVertices = _primaryRenderInformation.count;
_secondaryRenderInformation.first = 0;
_secondaryRenderInformation.count = 0;
_floatingRenderInformation.first = 0;
_floatingRenderInformation.count = 0;
}
else {
_primaryRenderInformation.first = 0;
_primaryRenderInformation.count = 0;
@@ -539,17 +480,11 @@ void RenderableTrailTrajectory::update(const UpdateData& data) {
_secondaryRenderInformation.count = 0;
_floatingRenderInformation.first = 0;
_floatingRenderInformation.count = 0;
}
if (_subsamplingIsDirty) {
// If the subsampling information has changed (either by a property change or by
// a request of a full sweep) we update it here
_primaryRenderInformation.stride = _timeStampSubsamplingFactor;
_secondaryRenderInformation.stride = _timeStampSubsamplingFactor;
_floatingRenderInformation.stride = _timeStampSubsamplingFactor;
_subsamplingIsDirty = false;
if (_renderFullTrail || j2k >= _end) {
// Renders the whole trail if time has passed the end time
_primaryRenderInformation.count = static_cast<GLsizei>(_vertexArray.size());
_nUniqueVertices = _primaryRenderInformation.count;
}
}
glBindVertexArray(0);
@@ -61,16 +61,16 @@ public:
private:
/**
* Update vertex buffer when a full sweep is needed.
*/
void updateBuffer();
/**
* Reset some variables to default state.
*/
void reset();
/// The number of vertices that we calculate during each frame of the full sweep pass
properties::IntProperty _sweepChunkSize;
/// Enables or disables iterative vertex calculations during a full sweep
properties::BoolProperty _enableSweepChunking;
/// The start time of the trail
properties::StringProperty _startTime;
/// The end time of the trail
@@ -82,6 +82,8 @@ private:
properties::IntProperty _timeStampSubsamplingFactor;
/// Determines whether the full trail should be rendered or the future trail removed
properties::BoolProperty _renderFullTrail;
/// Determines whether accurate trail points are being calculated or not
properties::BoolProperty _useAccurateTrail;
/// Determines how many vertices around the object that will be
/// replaced during full trail rendering
properties::IntProperty _nReplacementPoints;
@@ -89,17 +91,11 @@ private:
/// Dirty flag that determines whether the full vertex buffer needs to be resampled
bool _needsFullSweep = true;
/// Dirty flag to determine whether the stride information needs to be changed
bool _subsamplingIsDirty = true;
/// The conversion of the _startTime into the internal time format
double _start = 0.0;
/// The conversion of the _endTime into the internal time format
double _end = 0.0;
/// Tracks sweep iteration, is used to calculate which vertices to work on per frame
int _sweepIteration = 0;
/// How many points do we need to compute given the distance between the
/// start and end date and the desired sample interval
unsigned int _nVertices = 0;
+17 -16
View File
@@ -55,23 +55,24 @@ Fragment getFragment() {
//float circleClipping = 1.0 - smoothstep(1.0 - Delta, 1.0, dot(circCoord, circCoord));
float circleClipping = smoothstep(1.0, 1.0 - Delta, dot(circCoord, circCoord));
frag.color.a *= circleClipping;
}
// We can't expect a viewport of the form (0, 0, res.x, res.y) used to convert the
// window coordinates from gl_FragCoord into [0, 1] coordinates, so we need to use
// this more complicated method that is also used in the FXAA and HDR rendering steps
vec2 xy = vec2(gl_FragCoord.xy);
xy -= viewport.xy;
double distanceCenter = length(mathLine - xy);
double dLW = double(lineWidth);
const float blendFactor = 20.0;
if (distanceCenter > dLW) {
frag.color.a = 0.0;
}
}
else {
frag.color.a *= pow(float((dLW - distanceCenter) / dLW), blendFactor);
// We can't expect a viewport of the form (0, 0, res.x, res.y) used to convert the
// window coordinates from gl_FragCoord into [0, 1] coordinates, so we need to use
// this more complicated method that is also used in the FXAA and HDR rendering steps
vec2 xy = vec2(gl_FragCoord.xy);
xy -= viewport.xy;
double distanceCenter = length(mathLine - xy);
double dLW = double(lineWidth);
const float blendFactor = 20.0;
if (distanceCenter > dLW) {
frag.color.a = 0.0;
}
else {
frag.color.a *= pow(float((dLW - distanceCenter) / dLW), blendFactor);
}
}
frag.gPosition = vs_gPosition;