mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-06 19:50:03 -06:00
Finalized segments algorithm and added object selection
This commit is contained in:
@@ -4,7 +4,7 @@ local sharedSssb = asset.require('./sssb_shared')
|
||||
local filepath = sharedSssb.downloadSssbDatabaseFile(asset, 'amor_asteroid', 'sssb_data_amor_asteroid')
|
||||
local object = sharedSssb.createSssbGroupObject('sssb_data_amor_asteroid.csv', "Amor Asteroids", filepath, { 0.9, 0.3, 0.1 })
|
||||
object.Renderable.Enabled = false
|
||||
object.Renderable.SegmentQuality = 1
|
||||
object.Renderable.SegmentQuality = 4
|
||||
object.Renderable.TrailFade = 11
|
||||
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, { object })
|
||||
|
||||
@@ -4,7 +4,7 @@ local sharedSssb = asset.require('./sssb_shared')
|
||||
local filepath = sharedSssb.downloadSssbDatabaseFile(asset, 'apollo_asteroid', 'sssb_data_apollo_asteroid')
|
||||
local object = sharedSssb.createSssbGroupObject('sssb_data_apollo_asteroid.csv', "Apollo Asteroids", filepath, { 0.9, 0.3, 0.1 })
|
||||
object.Renderable.Enabled = false
|
||||
object.Renderable.SegmentQuality = 1
|
||||
object.Renderable.SegmentQuality = 6
|
||||
object.Renderable.TrailFade = 10
|
||||
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, { object })
|
||||
|
||||
@@ -4,7 +4,7 @@ local sharedSssb = asset.require('./sssb_shared')
|
||||
local filepath = sharedSssb.downloadSssbDatabaseFile(asset, 'aten_asteroid', 'sssb_data_aten_asteroid')
|
||||
local object = sharedSssb.createSssbGroupObject('sssb_data_aten_asteroid.csv', "Aten Asteroids", filepath, { 0.9, 0.3, 0.1 })
|
||||
object.Renderable.Enabled = false
|
||||
object.Renderable.SegmentQuality = 1
|
||||
object.Renderable.SegmentQuality = 2
|
||||
object.Renderable.TrailFade = 18
|
||||
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, { object })
|
||||
|
||||
@@ -4,7 +4,7 @@ local sharedSssb = asset.require('./sssb_shared')
|
||||
local filepath = sharedSssb.downloadSssbDatabaseFile(asset, 'atira_asteroid', 'sssb_data_atira_asteroid')
|
||||
local object = sharedSssb.createSssbGroupObject('sssb_data_atira_asteroid.csv', "Atira Asteroids", filepath, { 0.9, 0.3, 0.1 })
|
||||
object.Renderable.Enabled = false
|
||||
object.Renderable.SegmentQuality = 1
|
||||
object.Renderable.SegmentQuality = 2
|
||||
object.Renderable.TrailFade = 25
|
||||
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, { object })
|
||||
|
||||
@@ -4,7 +4,7 @@ local sharedSssb = asset.require('./sssb_shared')
|
||||
local filepath = sharedSssb.downloadSssbDatabaseFile(asset, 'centaur_asteroid', 'sssb_data_centaur_asteroid')
|
||||
local object = sharedSssb.createSssbGroupObject('sssb_data_centaur_asteroid.csv', "Centaur Asteroids", filepath, { 0.9, 0.3, 0.1 })
|
||||
object.Renderable.Enabled = false
|
||||
object.Renderable.SegmentQuality = 1
|
||||
object.Renderable.SegmentQuality = 6
|
||||
object.Renderable.TrailFade = 18
|
||||
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, { object })
|
||||
|
||||
@@ -4,7 +4,7 @@ local sharedSssb = asset.require('./sssb_shared')
|
||||
local filepath = sharedSssb.downloadSssbDatabaseFile(asset, 'chiron-type_comet', 'sssb_data_chiron-type_comet')
|
||||
local object = sharedSssb.createSssbGroupObject('sssb_data_chiron-type_comet.csv', "Chiron-type Comets", filepath, { 0.9, 0.3, 0.1 })
|
||||
object.Renderable.Enabled = false
|
||||
object.Renderable.SegmentQuality = 50
|
||||
object.Renderable.SegmentQuality = 10
|
||||
object.Renderable.TrailFade = 25
|
||||
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, { object })
|
||||
|
||||
@@ -4,7 +4,7 @@ local sharedSssb = asset.require('./sssb_shared')
|
||||
local filepath = sharedSssb.downloadSssbDatabaseFile(asset, 'halley-type_comet', 'sssb_data_halley-type_comet')
|
||||
local object = sharedSssb.createSssbGroupObject('sssb_data_halley-type_comet.csv', "Halley-type Comets", filepath, { 0.9, 0.3, 0.1 })
|
||||
object.Renderable.Enabled = false
|
||||
object.Renderable.SegmentQuality = 2
|
||||
object.Renderable.SegmentQuality = 9
|
||||
object.Renderable.TrailFade = 18
|
||||
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, { object })
|
||||
|
||||
@@ -4,7 +4,7 @@ local sharedSssb = asset.require('./sssb_shared')
|
||||
local filepath = sharedSssb.downloadSssbDatabaseFile(asset, 'transneptunian_object_asteroid', 'sssb_data_transneptunian_object_asteroid')
|
||||
local object = sharedSssb.createSssbGroupObject('sssb_data_transneptunian_object_asteroid.csv', "Transneptunian Object Asteroids", filepath, { 0.9, 0.3, 0.1 })
|
||||
object.Renderable.Enabled = false
|
||||
object.Renderable.SegmentQuality = 3
|
||||
object.Renderable.SegmentQuality = 8
|
||||
object.Renderable.TrailFade = 10
|
||||
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, { object })
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace {
|
||||
"SegmentQuality",
|
||||
"Segment Quality",
|
||||
"A segment quality value for the orbital trail. A value from 1 (lowest) to "
|
||||
"100 (highest) that controls the number of line segments in the rendering of the "
|
||||
"10 (highest) that controls the number of line segments in the rendering of the "
|
||||
"orbital trail. This does not control the direct number of segments because "
|
||||
"these automatically increase according to the eccentricity of the orbit."
|
||||
};
|
||||
@@ -84,7 +84,17 @@ namespace {
|
||||
"Upper limit on the number of objects for this renderable, regardless of "
|
||||
"how many objects are contained in the data file"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo StartRenderIdxInfo = {
|
||||
"StartRenderIdx",
|
||||
"Starting Index of Render",
|
||||
"Index of object in renderable group to start rendering (all prior objects will "
|
||||
"be ignored)."
|
||||
};
|
||||
static const openspace::properties::Property::PropertyInfo RenderSizeInfo = {
|
||||
"RenderSizeInfo",
|
||||
"Size of Render Block",
|
||||
"Number of objects to render from StartRenderIdx"
|
||||
};
|
||||
constexpr const char* KeyFile = "Path";
|
||||
constexpr const char* KeyLineNum = "LineNumber";
|
||||
}
|
||||
@@ -349,12 +359,14 @@ int RenderableOrbitalKepler::daysIntoGivenYear(int month, int dayOfMonth) {
|
||||
}
|
||||
return dayCount;
|
||||
}
|
||||
|
||||
|
||||
RenderableOrbitalKepler::RenderableOrbitalKepler(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
, _path(PathInfo)
|
||||
, _segmentQuality(SegmentQualityInfo, 10, 1, 100)
|
||||
, _segmentQuality(SegmentQualityInfo, 2, 1, 10)
|
||||
, _upperLimit(UpperLimitInfo, 1000, 1, 1000000)
|
||||
, _startRenderIdx(StartRenderIdxInfo, 0, 0, 1)
|
||||
, _sizeRender(RenderSizeInfo, 1, 1, 2)
|
||||
{
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
@@ -388,6 +400,24 @@ RenderableOrbitalKepler::RenderableOrbitalKepler(const ghoul::Dictionary& dictio
|
||||
_upperLimit = 0;
|
||||
}
|
||||
|
||||
if (dictionary.hasKeyAndValue<double>(StartRenderIdxInfo.identifier)) {
|
||||
_startRenderIdx = static_cast<unsigned int>(
|
||||
dictionary.value<double>(StartRenderIdxInfo.identifier)
|
||||
);
|
||||
}
|
||||
else {
|
||||
_startRenderIdx = 0;
|
||||
}
|
||||
|
||||
if (dictionary.hasKeyAndValue<double>(RenderSizeInfo.identifier)) {
|
||||
_sizeRender = static_cast<unsigned int>(
|
||||
dictionary.value<double>(RenderSizeInfo.identifier)
|
||||
);
|
||||
}
|
||||
else {
|
||||
_sizeRender = 0;
|
||||
}
|
||||
|
||||
if (dictionary.hasKeyAndValue<double>(LineWidthInfo.identifier)) {
|
||||
_appearance.lineWidth = static_cast<float>(
|
||||
dictionary.value<double>(LineWidthInfo.identifier)
|
||||
@@ -404,6 +434,13 @@ RenderableOrbitalKepler::RenderableOrbitalKepler(const ghoul::Dictionary& dictio
|
||||
addProperty(_path);
|
||||
addProperty(_segmentQuality);
|
||||
addProperty(_opacity);
|
||||
addProperty(_startRenderIdx);
|
||||
addProperty(_sizeRender);
|
||||
|
||||
updateStartRenderIdxSelect = std::function<void()>([this] { initializeGL(); });
|
||||
updateRenderSizeSelect = std::function<void()>([this] { initializeGL(); });
|
||||
_startRenderIdxCallbackHandle = _startRenderIdx.onChange(updateStartRenderIdxSelect);
|
||||
_sizeRenderCallbackHandle = _sizeRender.onChange(updateRenderSizeSelect);
|
||||
|
||||
setRenderBin(Renderable::RenderBin::Overlay);
|
||||
}
|
||||
@@ -498,13 +535,13 @@ void RenderableOrbitalKepler::render(const RenderData& data, RendererTasks&) {
|
||||
void RenderableOrbitalKepler::updateBuffers() {
|
||||
readDataFile(_path);
|
||||
|
||||
size_t nVerticesPerOrbit = 0;
|
||||
size_t nVerticesTotal = 0;
|
||||
|
||||
int numOrbits = _data.size();
|
||||
for (size_t i = 0; i < numOrbits; ++i) {
|
||||
nVerticesPerOrbit += _segmentSize[i] + 1;
|
||||
nVerticesTotal += _segmentSize[i] + 1;
|
||||
}
|
||||
_vertexBufferData.resize(nVerticesPerOrbit);
|
||||
_vertexBufferData.resize(nVerticesTotal);
|
||||
|
||||
size_t vertexBufIdx = 0;
|
||||
for (size_t orbitIdx = 0; orbitIdx < numOrbits; ++orbitIdx) {
|
||||
@@ -521,7 +558,7 @@ void RenderableOrbitalKepler::updateBuffers() {
|
||||
orbit.epoch
|
||||
);
|
||||
|
||||
for (size_t j = 0 ; j < _segmentSize[orbitIdx]; ++j) {
|
||||
for (size_t j = 0 ; j < (_segmentSize[orbitIdx] + 1); ++j) {
|
||||
double timeOffset = orbit.period *
|
||||
static_cast<double>(j)/ static_cast<double>(_segmentSize[orbitIdx]);
|
||||
|
||||
|
||||
@@ -69,6 +69,8 @@ protected:
|
||||
double epochFromYMDdSubstring(const std::string& epochString);
|
||||
int daysIntoGivenYear(int month, int dayOfMonth);
|
||||
std::function<void()> reinitializeTrailBuffers;
|
||||
std::function<void()> updateStartRenderIdxSelect;
|
||||
std::function<void()> updateRenderSizeSelect;
|
||||
|
||||
const std::vector<int> LeapYears = {
|
||||
1956, 1960, 1964, 1968, 1972, 1976, 1980, 1984, 1988, 1992, 1996,
|
||||
@@ -103,6 +105,7 @@ protected:
|
||||
double epoch = 0.0;
|
||||
double period = 0.0;
|
||||
};
|
||||
std::streamoff _numObjects;
|
||||
const double convertAuToKm = 1.496e8;
|
||||
const double convertDaysToSecs = 86400.;
|
||||
std::vector<KeplerParameters> _data;
|
||||
@@ -110,6 +113,10 @@ protected:
|
||||
properties::UIntProperty _upperLimit;
|
||||
properties::UIntProperty _segmentQuality;
|
||||
properties::Property::OnChangeHandle _upperLimitCallbackHandle;
|
||||
properties::UIntProperty _startRenderIdx;
|
||||
properties::UIntProperty _sizeRender;
|
||||
properties::Property::OnChangeHandle _startRenderIdxCallbackHandle;
|
||||
properties::Property::OnChangeHandle _sizeRenderCallbackHandle;
|
||||
|
||||
private:
|
||||
struct Vertex {
|
||||
|
||||
@@ -142,10 +142,10 @@ void RenderableSatellites::readDataFile(const std::string& filename) {
|
||||
file.seekg(std::ios_base::beg); // reset iterator to beginning of file
|
||||
|
||||
// 3 because a TLE has 3 lines per element/ object.
|
||||
std::streamoff numberOfObjects = numberOfLines / 3;
|
||||
_numObjects = numberOfLines / 3;
|
||||
|
||||
std::string line = "-";
|
||||
for (std::streamoff i = 0; i < numberOfObjects; i++) {
|
||||
for (std::streamoff i = 0; i < _numObjects; i++) {
|
||||
std::getline(file, line); // get rid of title
|
||||
|
||||
KeplerParameters keplerElements;
|
||||
@@ -237,7 +237,7 @@ void RenderableSatellites::readDataFile(const std::string& filename) {
|
||||
keplerElements.period = period;
|
||||
|
||||
_data.push_back(keplerElements);
|
||||
_segmentSize.push_back(_segmentQuality * 10);
|
||||
_segmentSize.push_back(_segmentQuality * 100);
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
@@ -154,14 +154,14 @@ void RenderableSmallBody::readDataFile(const std::string& filename) {
|
||||
file.open(filename);
|
||||
|
||||
std::streamoff numberOfLines = std::count(std::istreambuf_iterator<char>(file),
|
||||
std::istreambuf_iterator<char>(), '\n' );
|
||||
std::istreambuf_iterator<char>(), '\n' );
|
||||
file.seekg(std::ios_base::beg); // reset iterator to beginning of file
|
||||
_data.clear();
|
||||
_sbNames.clear();
|
||||
_segmentSize.clear();
|
||||
|
||||
std::string line;
|
||||
std::streamoff csvLine = -1;
|
||||
unsigned int csvLine = 0;
|
||||
int fieldCount = 0;
|
||||
float lineSkipFraction = 1.0;
|
||||
float currLineFraction;
|
||||
@@ -173,18 +173,42 @@ void RenderableSmallBody::readDataFile(const std::string& filename) {
|
||||
try {
|
||||
std::getline(file, line); // get rid of first line (header)
|
||||
numberOfLines -= 1;
|
||||
if (_upperLimit == 0 || _upperLimit > numberOfLines) {
|
||||
if (_numObjects != numberOfLines) {
|
||||
_initialized = false;
|
||||
}
|
||||
_numObjects = numberOfLines;
|
||||
|
||||
if (!_initialized) {
|
||||
_initialized = true;
|
||||
|
||||
_startRenderIdx.removeOnChange(_startRenderIdxCallbackHandle);
|
||||
_sizeRender.removeOnChange(_sizeRenderCallbackHandle);
|
||||
_startRenderIdx.setMaxValue(_numObjects - 1);
|
||||
_sizeRender.setMaxValue(_numObjects);
|
||||
_startRenderIdx = static_cast<unsigned int>(0);
|
||||
_sizeRender = static_cast<unsigned int>(_numObjects);
|
||||
_startRenderIdxCallbackHandle = _startRenderIdx.onChange(
|
||||
updateStartRenderIdxSelect);
|
||||
_sizeRenderCallbackHandle = _sizeRender.onChange(
|
||||
updateRenderSizeSelect);
|
||||
|
||||
//If a limit wasn't specified in dictionary, set it to # lines in file
|
||||
// minus the header line (but temporarily disable callback to avoid 2nd call)
|
||||
_upperLimit.removeOnChange(_upperLimitCallbackHandle);
|
||||
_upperLimit.setMaxValue(numberOfLines);
|
||||
_upperLimit = static_cast<unsigned int>(numberOfLines);
|
||||
_upperLimit.setMaxValue(_numObjects);
|
||||
_upperLimit = static_cast<unsigned int>(_numObjects);
|
||||
_upperLimitCallbackHandle = _upperLimit.onChange(reinitializeTrailBuffers);
|
||||
}
|
||||
else {
|
||||
lineSkipFraction = static_cast<float>(_upperLimit) /
|
||||
static_cast<float>(numberOfLines);
|
||||
if (_sizeRender < _numObjects || _startRenderIdx > 0) {
|
||||
lineSkipFraction = 1.0;
|
||||
}
|
||||
else {
|
||||
lineSkipFraction = static_cast<float>(_upperLimit)
|
||||
/ static_cast<float>(_numObjects);
|
||||
}
|
||||
}
|
||||
|
||||
if (line.compare(expectedHeaderLine) != 0) {
|
||||
LERROR(fmt::format(
|
||||
"File {} does not have the appropriate JPL SBDB header at line 1.",
|
||||
@@ -195,12 +219,23 @@ void RenderableSmallBody::readDataFile(const std::string& filename) {
|
||||
}
|
||||
|
||||
unsigned int sequentialLineErrors = 0;
|
||||
for (csvLine = 1; csvLine <= numberOfLines; csvLine++, sequentialLineErrors++) {
|
||||
unsigned int endElement = _startRenderIdx + _sizeRender - 1;
|
||||
endElement = (endElement >= _numObjects) ? _numObjects - 1 : endElement;
|
||||
//Burn lines if not starting at first element
|
||||
for (unsigned int k = 0; k < _startRenderIdx; ++k) {
|
||||
skipSingleLineInFile(file);
|
||||
}
|
||||
bool firstDataLine = true;
|
||||
for (csvLine = _startRenderIdx + 1;
|
||||
csvLine <= endElement + 1;
|
||||
csvLine++, sequentialLineErrors++)
|
||||
{
|
||||
currLineFraction = static_cast<float>(csvLine - 1) * lineSkipFraction;
|
||||
currLineCount = static_cast<int>(currLineFraction);
|
||||
if (currLineCount > lastLineCount) {
|
||||
try {
|
||||
readOrbitalParamsFromThisLine(fieldCount, csvLine, file);
|
||||
readOrbitalParamsFromThisLine(firstDataLine, fieldCount, csvLine,
|
||||
file);
|
||||
sequentialLineErrors = 0;
|
||||
}
|
||||
catch (std::invalid_argument&) {
|
||||
@@ -233,7 +268,11 @@ void RenderableSmallBody::readDataFile(const std::string& filename) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
skipSingleLineInFile(file);
|
||||
}
|
||||
lastLineCount = currLineCount;
|
||||
firstDataLine = false;
|
||||
}
|
||||
}
|
||||
catch (std::ios_base::failure&) {
|
||||
@@ -248,8 +287,14 @@ void RenderableSmallBody::readDataFile(const std::string& filename) {
|
||||
file.close();
|
||||
}
|
||||
|
||||
void RenderableSmallBody::readOrbitalParamsFromThisLine(int& fieldCount,
|
||||
std::streamoff& csvLine,
|
||||
void RenderableSmallBody::skipSingleLineInFile(std::ifstream& file) {
|
||||
std::string line;
|
||||
std::getline(file, line);
|
||||
}
|
||||
|
||||
void RenderableSmallBody::readOrbitalParamsFromThisLine(bool firstDataLine,
|
||||
int& fieldCount,
|
||||
unsigned int& csvLine,
|
||||
std::ifstream& file)
|
||||
{
|
||||
const int numDataFields = 8;
|
||||
@@ -259,7 +304,7 @@ void RenderableSmallBody::readOrbitalParamsFromThisLine(int& fieldCount,
|
||||
|
||||
//If there was a read/conversion error in the previous line, then read the remainder
|
||||
// of that line and throw it out first before proceeding with the next line.
|
||||
if (fieldCount != (numDataFields + 1) && csvLine != 1) {
|
||||
if (fieldCount != (numDataFields + 1) && !firstDataLine) {
|
||||
std::getline(file, field);
|
||||
}
|
||||
fieldCount = 0;
|
||||
@@ -336,7 +381,8 @@ void RenderableSmallBody::readOrbitalParamsFromThisLine(int& fieldCount,
|
||||
|
||||
_data.push_back(keplerElements);
|
||||
_sbNames.push_back(name);
|
||||
_segmentSize.push_back(_segmentQuality * 10 * (keplerElements.eccentricity / 0.05));
|
||||
double scale = static_cast<double>(_segmentQuality) * 10.0;
|
||||
_segmentSize.push_back(scale + (scale / pow(1 - keplerElements.eccentricity, 1.2)));
|
||||
}
|
||||
|
||||
static double importAngleValue(const std::string& angle) {
|
||||
|
||||
@@ -46,12 +46,15 @@ public:
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
private:
|
||||
void readOrbitalParamsFromThisLine(int& fieldCount, std::streamoff& csvLine,
|
||||
std::ifstream& file);
|
||||
void readOrbitalParamsFromThisLine(bool firstDataLine, int& fieldCount,
|
||||
unsigned int& csvLine, std::ifstream& file);
|
||||
void readDataFile(const std::string& filename);
|
||||
void skipSingleLineInFile(std::ifstream& file);
|
||||
|
||||
std::vector<std::string> _sbNames;
|
||||
|
||||
bool _initialized = false;
|
||||
|
||||
/// The index array that is potentially used in the draw call. If this is empty, no
|
||||
/// element draw call is used.
|
||||
std::vector<unsigned int> _indexBufferData;
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user