mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-03 09:20:26 -05:00
Merge branch 'develop' into feature/NewAtmosphere
This commit is contained in:
@@ -31,8 +31,9 @@
|
||||
#include <ghoul/ghoul.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/filesystem/file.h>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/lua/ghoul_lua.h>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCheckBox>
|
||||
|
||||
@@ -5,9 +5,9 @@ return {
|
||||
Parent = "Root",
|
||||
Renderable = {
|
||||
Type = "RenderableStars",
|
||||
File = "${OPENSPACE_DATA}/scene/stars/speck/stars.speck",
|
||||
Texture = "${OPENSPACE_DATA}/scene/stars/textures/halo.png",
|
||||
ColorMap = "${OPENSPACE_DATA}/scene/stars/colorbv.cmap"
|
||||
File = "speck/stars.speck",
|
||||
Texture = "textures/halo.png",
|
||||
ColorMap = "colorbv.cmap"
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
Submodule ext/ghoul updated: c5edba4f70...1ee083f486
@@ -22,12 +22,9 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
// temporary includes (will fix as soon as I figure out how class hierarchy should work,
|
||||
// ie after I see model on screen)
|
||||
|
||||
// open space includes
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <modules/base/rendering/renderablemodel.h>
|
||||
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <modules/base/rendering/modelgeometry.h>
|
||||
#include <openspace/engine/configurationmanager.h>
|
||||
|
||||
@@ -37,7 +34,6 @@
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
|
||||
#include <openspace/util/time.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
|
||||
@@ -177,18 +173,6 @@ void RenderableModel::render(const RenderData& data) {
|
||||
|
||||
double lt;
|
||||
|
||||
// Fade away if it does not have spice coverage
|
||||
double time = openspace::Time::ref().j2000Seconds();
|
||||
bool targetPositionCoverage = openspace::SpiceManager::ref().hasSpkCoverage(_target, time);
|
||||
if (!targetPositionCoverage) {
|
||||
int frame = _frameCount % 180;
|
||||
|
||||
float fadingFactor = static_cast<float>(sin((frame * M_PI) / 180));
|
||||
_alpha = 0.5f + fadingFactor * 0.5f;
|
||||
}
|
||||
else
|
||||
_alpha = 1.0f;
|
||||
|
||||
// Fading
|
||||
if (_performFade && _fading > 0.f) {
|
||||
_fading = _fading - 0.01f;
|
||||
@@ -261,7 +245,7 @@ void RenderableModel::update(const UpdateData& data) {
|
||||
//}
|
||||
|
||||
double lt;
|
||||
_sunPos = openspace::SpiceManager::ref().targetPosition("SUN", "SUN", "GALACTIC", {}, _time, lt);
|
||||
_sunPos = OsEng.renderEngine().scene()->sceneGraphNode("Sun")->worldPosition();
|
||||
}
|
||||
|
||||
void RenderableModel::loadTexture() {
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <modules/base/rendering/renderablestars.h>
|
||||
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
@@ -31,6 +32,8 @@
|
||||
#include <ghoul/filesystem/filesystem>
|
||||
#include <ghoul/misc/templatefactory.h>
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
|
||||
#include <array>
|
||||
@@ -44,9 +47,6 @@ namespace {
|
||||
const std::string KeyTexture = "Texture";
|
||||
const std::string KeyColorMap = "ColorMap";
|
||||
|
||||
ghoul::filesystem::File* _psfTextureFile;
|
||||
ghoul::filesystem::File* _colorTextureFile;
|
||||
|
||||
const int8_t CurrentCacheVersion = 1;
|
||||
|
||||
struct ColorVBOLayout {
|
||||
@@ -82,6 +82,46 @@ namespace {
|
||||
|
||||
namespace openspace {
|
||||
|
||||
openspace::Documentation RenderableStars::Documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"RenderableStars",
|
||||
"base_renderablestars",
|
||||
{
|
||||
{
|
||||
"Type",
|
||||
new StringEqualVerifier("RenderableStars"),
|
||||
"",
|
||||
Optional::No
|
||||
},
|
||||
{
|
||||
KeyFile,
|
||||
new StringVerifier,
|
||||
"The path to the SPECK file that contains information about the stars "
|
||||
"being rendered.",
|
||||
Optional::No
|
||||
},
|
||||
{
|
||||
KeyTexture,
|
||||
new StringVerifier,
|
||||
"The path to the texture that should be used as a point spread function "
|
||||
"for the stars. The path is relative to the location of the .mod file "
|
||||
"and can contain file system token.",
|
||||
Optional::No
|
||||
},
|
||||
{
|
||||
KeyColorMap,
|
||||
new StringVerifier,
|
||||
"The path to the texture that is used to convert from the B-V value of "
|
||||
"the star to its color. The texture is used as a one dimensional lookup "
|
||||
"function.",
|
||||
Optional::No
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
, _pointSpreadFunctionTexturePath("psfTexture", "Point Spread Function Texture")
|
||||
@@ -101,47 +141,54 @@ RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary)
|
||||
, _vao(0)
|
||||
, _vbo(0)
|
||||
{
|
||||
using ghoul::filesystem::File;
|
||||
using File = ghoul::filesystem::File;
|
||||
|
||||
std::string texturePath = "";
|
||||
dictionary.getValue(KeyTexture, texturePath);
|
||||
_pointSpreadFunctionTexturePath = absPath(texturePath);
|
||||
_psfTextureFile = new File(_pointSpreadFunctionTexturePath);
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
dictionary,
|
||||
"RenderableStars"
|
||||
);
|
||||
|
||||
dictionary.getValue(KeyColorMap, texturePath);
|
||||
_colorTexturePath = absPath(texturePath);
|
||||
_colorTextureFile = new File(_colorTexturePath);
|
||||
_pointSpreadFunctionTexturePath = absPath(dictionary.value<std::string>(KeyTexture));
|
||||
_pointSpreadFunctionFile = std::make_unique<File>(_pointSpreadFunctionTexturePath);
|
||||
|
||||
bool success = dictionary.getValue(KeyFile, _speckFile);
|
||||
if (!success) {
|
||||
LERROR("SpeckDataSource did not contain key '" << KeyFile << "'");
|
||||
return;
|
||||
}
|
||||
_speckFile = absPath(_speckFile);
|
||||
_colorTexturePath = absPath(dictionary.value<std::string>(KeyColorMap));
|
||||
_colorTextureFile = std::make_unique<File>(_colorTexturePath);
|
||||
|
||||
_speckFile = absPath(dictionary.value<std::string>(KeyFile));
|
||||
|
||||
//_colorOption.addOptions({
|
||||
// { ColorOption::Color, "Color" },
|
||||
// { ColorOption::Velocity, "Velocity" },
|
||||
// { ColorOption::Speed, "Speed" }
|
||||
//});
|
||||
_colorOption.addOption(ColorOption::Color, "Color");
|
||||
_colorOption.addOption(ColorOption::Velocity, "Velocity");
|
||||
_colorOption.addOption(ColorOption::Speed, "Speed");
|
||||
addProperty(_colorOption);
|
||||
|
||||
_colorOption.onChange([&]{ _dataIsDirty = true;});
|
||||
|
||||
addProperty(_pointSpreadFunctionTexturePath);
|
||||
_pointSpreadFunctionTexturePath.onChange([&]{ _pointSpreadFunctionTextureIsDirty = true; });
|
||||
_psfTextureFile->setCallback([&](const File&) { _pointSpreadFunctionTextureIsDirty = true; });
|
||||
_pointSpreadFunctionTexturePath.onChange(
|
||||
[&]{ _pointSpreadFunctionTextureIsDirty = true; }
|
||||
);
|
||||
_pointSpreadFunctionFile->setCallback(
|
||||
[&](const File&) { _pointSpreadFunctionTextureIsDirty = true; }
|
||||
);
|
||||
|
||||
addProperty(_colorTexturePath);
|
||||
_colorTexturePath.onChange([&]{ _colorTextureIsDirty = true; });
|
||||
_colorTextureFile->setCallback([&](const File&) { _colorTextureIsDirty = true; });
|
||||
_colorTextureFile->setCallback(
|
||||
[&](const File&) { _colorTextureIsDirty = true; }
|
||||
);
|
||||
|
||||
addProperty(_alphaValue);
|
||||
addProperty(_scaleFactor);
|
||||
addProperty(_minBillboardSize);
|
||||
}
|
||||
|
||||
RenderableStars::~RenderableStars() {
|
||||
delete _psfTextureFile;
|
||||
delete _colorTextureFile;
|
||||
}
|
||||
RenderableStars::~RenderableStars() {}
|
||||
|
||||
bool RenderableStars::isReady() const {
|
||||
return (_program != nullptr) && (!_fullData.empty());
|
||||
@@ -156,8 +203,9 @@ bool RenderableStars::initialize() {
|
||||
"${MODULE_BASE}/shaders/star_fs.glsl",
|
||||
"${MODULE_BASE}/shaders/star_ge.glsl");
|
||||
|
||||
if (!_program)
|
||||
if (!_program) {
|
||||
return false;
|
||||
}
|
||||
completeSuccess &= loadData();
|
||||
completeSuccess &= (_pointSpreadFunctionTexture != nullptr);
|
||||
|
||||
@@ -212,14 +260,12 @@ void RenderableStars::render(const RenderData& data) {
|
||||
|
||||
ghoul::opengl::TextureUnit psfUnit;
|
||||
psfUnit.activate();
|
||||
if (_pointSpreadFunctionTexture)
|
||||
_pointSpreadFunctionTexture->bind();
|
||||
_pointSpreadFunctionTexture->bind();
|
||||
_program->setUniform("psfTexture", psfUnit);
|
||||
|
||||
ghoul::opengl::TextureUnit colorUnit;
|
||||
colorUnit.activate();
|
||||
if (_colorTexture)
|
||||
_colorTexture->bind();
|
||||
_colorTexture->bind();
|
||||
_program->setUniform("colorTexture", colorUnit);
|
||||
|
||||
glBindVertexArray(_vao);
|
||||
@@ -253,10 +299,12 @@ void RenderableStars::update(const UpdateData& data) {
|
||||
}
|
||||
glBindVertexArray(_vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
size*sizeof(GLfloat),
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
size * sizeof(GLfloat),
|
||||
&_slicedData[0],
|
||||
GL_STATIC_DRAW);
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
|
||||
GLint positionAttrib = _program->attributeLocation("in_position");
|
||||
GLint brightnessDataAttrib = _program->attributeLocation("in_brightness");
|
||||
@@ -316,17 +364,27 @@ void RenderableStars::update(const UpdateData& data) {
|
||||
LDEBUG("Reloading Point Spread Function texture");
|
||||
_pointSpreadFunctionTexture = nullptr;
|
||||
if (_pointSpreadFunctionTexturePath.value() != "") {
|
||||
_pointSpreadFunctionTexture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_pointSpreadFunctionTexturePath)));
|
||||
_pointSpreadFunctionTexture = std::move(
|
||||
ghoul::io::TextureReader::ref().loadTexture(
|
||||
absPath(_pointSpreadFunctionTexturePath)
|
||||
)
|
||||
);
|
||||
|
||||
if (_pointSpreadFunctionTexture) {
|
||||
LDEBUG("Loaded texture from '" << absPath(_pointSpreadFunctionTexturePath) << "'");
|
||||
LDEBUG("Loaded texture from '" <<
|
||||
absPath(_pointSpreadFunctionTexturePath) << "'");
|
||||
_pointSpreadFunctionTexture->uploadTexture();
|
||||
}
|
||||
_pointSpreadFunctionTexture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
|
||||
|
||||
delete _psfTextureFile;
|
||||
_psfTextureFile = new ghoul::filesystem::File(_pointSpreadFunctionTexturePath);
|
||||
_psfTextureFile->setCallback([&](const ghoul::filesystem::File&) { _pointSpreadFunctionTextureIsDirty = true; });
|
||||
_pointSpreadFunctionFile = std::make_unique<ghoul::filesystem::File>(
|
||||
_pointSpreadFunctionTexturePath
|
||||
);
|
||||
_pointSpreadFunctionFile->setCallback(
|
||||
[&](const ghoul::filesystem::File&) {
|
||||
_pointSpreadFunctionTextureIsDirty = true;
|
||||
}
|
||||
);
|
||||
}
|
||||
_pointSpreadFunctionTextureIsDirty = false;
|
||||
}
|
||||
@@ -341,9 +399,12 @@ void RenderableStars::update(const UpdateData& data) {
|
||||
_colorTexture->uploadTexture();
|
||||
}
|
||||
|
||||
delete _colorTextureFile;
|
||||
_colorTextureFile = new ghoul::filesystem::File(_colorTexturePath);
|
||||
_colorTextureFile->setCallback([&](const ghoul::filesystem::File&) { _colorTextureIsDirty = true; });
|
||||
_colorTextureFile = std::make_unique<ghoul::filesystem::File>(
|
||||
_colorTexturePath
|
||||
);
|
||||
_colorTextureFile->setCallback(
|
||||
[&](const ghoul::filesystem::File&) { _colorTextureIsDirty = true; }
|
||||
);
|
||||
}
|
||||
_colorTextureIsDirty = false;
|
||||
}
|
||||
@@ -361,12 +422,14 @@ bool RenderableStars::loadData() {
|
||||
LINFO("Cached file '" << cachedFile << "' used for Speck file '" << _file << "'");
|
||||
|
||||
bool success = loadCachedFile(cachedFile);
|
||||
if (success)
|
||||
if (success) {
|
||||
return true;
|
||||
else
|
||||
}
|
||||
else {
|
||||
FileSys.cacheManager()->removeCacheFile(_file);
|
||||
// Intentional fall-through to the 'else' computation to generate the cache
|
||||
// file for the next run
|
||||
}
|
||||
}
|
||||
else {
|
||||
LINFO("Cache for Speck file '" << _file << "' not found");
|
||||
@@ -374,8 +437,9 @@ bool RenderableStars::loadData() {
|
||||
LINFO("Loading Speck file '" << _file << "'");
|
||||
|
||||
bool success = readSpeckFile();
|
||||
if (!success)
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LINFO("Saving cache");
|
||||
success = saveCachedFile(cachedFile);
|
||||
@@ -401,8 +465,9 @@ bool RenderableStars::readSpeckFile() {
|
||||
std::ifstream::streampos position = file.tellg();
|
||||
std::getline(file, line);
|
||||
|
||||
if (line[0] == '#' || line.empty())
|
||||
if (line[0] == '#' || line.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line.substr(0, 7) != "datavar" &&
|
||||
line.substr(0, 10) != "texturevar" &&
|
||||
@@ -437,8 +502,9 @@ bool RenderableStars::readSpeckFile() {
|
||||
std::getline(file, line);
|
||||
std::stringstream str(line);
|
||||
|
||||
for (int i = 0; i < _nValuesPerStar; ++i)
|
||||
for (int i = 0; i < _nValuesPerStar; ++i) {
|
||||
str >> values[i];
|
||||
}
|
||||
|
||||
_fullData.insert(_fullData.end(), values.begin(), values.end());
|
||||
} while (!file.eof());
|
||||
|
||||
@@ -26,15 +26,25 @@
|
||||
#define __RENDERABLESTARS_H__
|
||||
|
||||
#include <openspace/rendering/renderable.h>
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/optionproperty.h>
|
||||
#include <openspace/properties/vectorproperty.h>
|
||||
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
namespace ghoul {
|
||||
namespace filesystem {
|
||||
class File;
|
||||
}
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
namespace opengl {
|
||||
class ProgramObject;
|
||||
class Texture;
|
||||
}
|
||||
|
||||
class RenderableStars : public Renderable {
|
||||
public:
|
||||
explicit RenderableStars(const ghoul::Dictionary& dictionary);
|
||||
@@ -48,6 +58,8 @@ public:
|
||||
void render(const RenderData& data) override;
|
||||
void update(const UpdateData& data) override;
|
||||
|
||||
static openspace::Documentation Documentation();
|
||||
|
||||
private:
|
||||
enum ColorOption {
|
||||
Color = 0,
|
||||
@@ -64,10 +76,12 @@ private:
|
||||
|
||||
properties::StringProperty _pointSpreadFunctionTexturePath;
|
||||
std::unique_ptr<ghoul::opengl::Texture> _pointSpreadFunctionTexture;
|
||||
std::unique_ptr<ghoul::filesystem::File> _pointSpreadFunctionFile;
|
||||
bool _pointSpreadFunctionTextureIsDirty;
|
||||
|
||||
properties::StringProperty _colorTexturePath;
|
||||
std::unique_ptr<ghoul::opengl::Texture> _colorTexture;
|
||||
std::unique_ptr<ghoul::filesystem::File> _colorTextureFile;
|
||||
bool _colorTextureIsDirty;
|
||||
|
||||
properties::OptionProperty _colorOption;
|
||||
|
||||
@@ -462,7 +462,7 @@ bool RenderablePlanetProjection::loadTextures() {
|
||||
if (_colorTexturePath.value() != "") {
|
||||
_baseTexture = ghoul::io::TextureReader::ref().loadTexture(_colorTexturePath);
|
||||
if (_baseTexture) {
|
||||
ghoul::opengl::convertTextureFormat(Texture::Format::RGB, *_baseTexture);
|
||||
ghoul::opengl::convertTextureFormat(*_baseTexture, Texture::Format::RGB);
|
||||
_baseTexture->uploadTexture();
|
||||
_baseTexture->setFilter(Texture::FilterMode::Linear);
|
||||
}
|
||||
@@ -472,7 +472,7 @@ bool RenderablePlanetProjection::loadTextures() {
|
||||
if (_heightMapTexturePath.value() != "") {
|
||||
_heightMapTexture = ghoul::io::TextureReader::ref().loadTexture(_heightMapTexturePath);
|
||||
if (_heightMapTexture) {
|
||||
ghoul::opengl::convertTextureFormat(Texture::Format::RGB, *_heightMapTexture);
|
||||
ghoul::opengl::convertTextureFormat(*_heightMapTexture, Texture::Format::RGB);
|
||||
_heightMapTexture->uploadTexture();
|
||||
_heightMapTexture->setFilter(Texture::FilterMode::Linear);
|
||||
}
|
||||
|
||||
@@ -875,7 +875,7 @@ std::shared_ptr<ghoul::opengl::Texture> ProjectionComponent::loadProjectionTextu
|
||||
unique_ptr<Texture> texture = TextureReader::ref().loadTexture(absPath(texturePath));
|
||||
if (texture) {
|
||||
if (texture->format() == Texture::Format::Red)
|
||||
ghoul::opengl::convertTextureFormat(ghoul::opengl::Texture::Format::RGB, *texture);
|
||||
ghoul::opengl::convertTextureFormat(*texture, Texture::Format::RGB);
|
||||
texture->uploadTexture();
|
||||
// TODO: AnisotropicMipMap crashes on ATI cards ---abock
|
||||
//_textureProj->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
|
||||
|
||||
@@ -35,8 +35,6 @@ class GUI;
|
||||
*/
|
||||
class GuiComponent {
|
||||
public:
|
||||
friend class GUI;
|
||||
|
||||
/**
|
||||
* Returns if this component is enabled, that is, if it is currently active and
|
||||
* visible on the screen.
|
||||
|
||||
@@ -206,8 +206,12 @@ void addScreenSpaceRenderable(std::string texturePath) {
|
||||
LWARNING("Could not find image '" << texturePath << "'");
|
||||
return;
|
||||
}
|
||||
|
||||
texturePath = absPath(texturePath);
|
||||
texturePath = FileSys.convertPathSeparator(texturePath, '/');
|
||||
|
||||
std::string luaTable =
|
||||
"{Type = 'ScreenSpaceImage', TexturePath = '" + absPath(texturePath) + "' }";
|
||||
"{Type = 'ScreenSpaceImage', TexturePath = '" + texturePath + "' }";
|
||||
std::string script = "openspace.registerScreenSpaceRenderable(" + luaTable + ");";
|
||||
OsEng.scriptEngine().queueScript(script, openspace::scripting::ScriptEngine::RemoteScripting::Yes);
|
||||
}
|
||||
@@ -324,8 +328,9 @@ void GUI::initializeGL() {
|
||||
"${MODULE_ONSCREENGUI}/shaders/gui_vs.glsl",
|
||||
"${MODULE_ONSCREENGUI}/shaders/gui_fs.glsl"
|
||||
);
|
||||
if (!_program)
|
||||
if (!_program) {
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char* pngData;
|
||||
glm::ivec2 textureSize;
|
||||
@@ -406,8 +411,7 @@ void GUI::deinitializeGL() {
|
||||
}
|
||||
|
||||
void GUI::startFrame(float deltaTime, const glm::vec2& windowSize,
|
||||
const glm::vec2& dpiScaling,
|
||||
const glm::vec2& mousePos,
|
||||
const glm::vec2& dpiScaling, const glm::vec2& mousePos,
|
||||
uint32_t mouseButtonsPressed)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
@@ -430,18 +434,26 @@ void GUI::endFrame() {
|
||||
|
||||
render();
|
||||
|
||||
if (_globalProperty.isEnabled())
|
||||
if (_globalProperty.isEnabled()) {
|
||||
_globalProperty.render();
|
||||
if (_property.isEnabled())
|
||||
}
|
||||
if (_property.isEnabled()) {
|
||||
_property.render();
|
||||
if (_screenSpaceProperty.isEnabled())
|
||||
}
|
||||
if (_screenSpaceProperty.isEnabled()) {
|
||||
_screenSpaceProperty.render();
|
||||
if (_performance.isEnabled())
|
||||
}
|
||||
|
||||
if (OsEng.renderEngine().doesPerformanceMeasurements()) {
|
||||
_performance.render();
|
||||
if (_help.isEnabled())
|
||||
}
|
||||
|
||||
if (_help.isEnabled()) {
|
||||
_help.render();
|
||||
if (_iswa.isEnabled())
|
||||
}
|
||||
if (_iswa.isEnabled()) {
|
||||
_iswa.render();
|
||||
}
|
||||
|
||||
ImGui::Render();
|
||||
}
|
||||
@@ -467,8 +479,9 @@ bool GUI::keyCallback(Key key, KeyModifier modifier, KeyAction action) {
|
||||
bool consumeEvent = io.WantCaptureKeyboard;
|
||||
if (consumeEvent) {
|
||||
int keyIndex = static_cast<int>(key);
|
||||
if (keyIndex < 0)
|
||||
if (keyIndex < 0) {
|
||||
LERROR("Pressed key of index '" << keyIndex << "' was negative");
|
||||
}
|
||||
else {
|
||||
if (action == KeyAction::Press)
|
||||
io.KeysDown[keyIndex] = true;
|
||||
@@ -487,8 +500,9 @@ bool GUI::charCallback(unsigned int character, KeyModifier modifier) {
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
bool consumeEvent = io.WantCaptureKeyboard;
|
||||
|
||||
if (consumeEvent)
|
||||
io.AddInputCharacter((unsigned short)character);
|
||||
if (consumeEvent) {
|
||||
io.AddInputCharacter(static_cast<unsigned short>(character));
|
||||
}
|
||||
|
||||
return consumeEvent;
|
||||
}
|
||||
@@ -496,54 +510,41 @@ bool GUI::charCallback(unsigned int character, KeyModifier modifier) {
|
||||
void GUI::render() {
|
||||
ImGui::Begin("OpenSpace GUI", nullptr);
|
||||
|
||||
ImGui::Checkbox("Scene Graph Properties", &_property._isEnabled);
|
||||
ImGui::Checkbox("ScreenSpace Properties", &_screenSpaceProperty._isEnabled);
|
||||
ImGui::Checkbox("Global Properties", &_globalProperty._isEnabled);
|
||||
bool property = _property.isEnabled();
|
||||
ImGui::Checkbox("Scene Graph Properties", &property);
|
||||
_property.setEnabled(property);
|
||||
|
||||
bool screenSpaceProperty = _screenSpaceProperty.isEnabled();
|
||||
ImGui::Checkbox("ScreenSpace Properties", &screenSpaceProperty);
|
||||
_screenSpaceProperty.setEnabled(screenSpaceProperty);
|
||||
|
||||
bool globalProperty = _globalProperty.isEnabled();
|
||||
ImGui::Checkbox("Global Properties", &globalProperty);
|
||||
_globalProperty.setEnabled(globalProperty);
|
||||
|
||||
#ifdef OPENSPACE_MODULE_ISWA_ENABLED
|
||||
ImGui::Checkbox("iSWA", &_iswa._isEnabled);
|
||||
bool iswa = _iswa.isEnabled();
|
||||
ImGui::Checkbox("iSWA", &iswa);
|
||||
_iswa.setEnabled(iswa);
|
||||
#endif
|
||||
ImGui::Checkbox("Performance", &_performance._isEnabled);
|
||||
|
||||
_origin.render();
|
||||
_time.render();
|
||||
|
||||
// These are temporary until the scalegraph is in effect ---abock
|
||||
bool toSun = ImGui::Button("Coordinate System to Sun");
|
||||
bool toPluto = ImGui::Button("Coordinate System to Pluto");
|
||||
bool toJupiter = ImGui::Button("Coordinate System to Jupiter");
|
||||
bool to67P = ImGui::Button("Coordinate System to 67P");
|
||||
|
||||
if (toSun) {
|
||||
OsEng.scriptEngine().queueScript(
|
||||
"openspace.setPropertyValue('Interaction.coordinateSystem', 'Sun');",
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
}
|
||||
if (toPluto) {
|
||||
OsEng.scriptEngine().queueScript(
|
||||
"openspace.setPropertyValue('Interaction.coordinateSystem', 'Pluto');",
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
}
|
||||
if (toJupiter) {
|
||||
OsEng.scriptEngine().queueScript(
|
||||
"openspace.setPropertyValue('Interaction.coordinateSystem', 'Jupiter');",
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
}
|
||||
if (to67P) {
|
||||
OsEng.scriptEngine().queueScript(
|
||||
"openspace.setPropertyValue('Interaction.coordinateSystem', '67P');",
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Help", &_help._isEnabled);
|
||||
bool help = _help.isEnabled();
|
||||
ImGui::Checkbox("Help", &help);
|
||||
_help.setEnabled(help);
|
||||
|
||||
static const int addImageBufferSize = 256;
|
||||
static char addImageBuffer[addImageBufferSize];
|
||||
ImGui::InputText("addImage", addImageBuffer, addImageBufferSize);
|
||||
|
||||
if (ImGui::SmallButton("Add Image")) {
|
||||
bool addImage = ImGui::InputText(
|
||||
"addImage",
|
||||
addImageBuffer,
|
||||
addImageBufferSize,
|
||||
ImGuiInputTextFlags_EnterReturnsTrue
|
||||
);
|
||||
if (addImage) {
|
||||
addScreenSpaceRenderable(std::string(addImageBuffer));
|
||||
}
|
||||
|
||||
|
||||
@@ -35,8 +35,9 @@ namespace gui {
|
||||
*/
|
||||
int show(lua_State* L) {
|
||||
int nArguments = lua_gettop(L);
|
||||
if (nArguments != 0)
|
||||
if (nArguments != 0) {
|
||||
return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments);
|
||||
}
|
||||
|
||||
OsEng.gui().setEnabled(true);
|
||||
return 0;
|
||||
@@ -49,8 +50,9 @@ int show(lua_State* L) {
|
||||
*/
|
||||
int hide(lua_State* L) {
|
||||
int nArguments = lua_gettop(L);
|
||||
if (nArguments != 0)
|
||||
if (nArguments != 0) {
|
||||
return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments);
|
||||
}
|
||||
|
||||
OsEng.gui().setEnabled(false);
|
||||
return 0;
|
||||
@@ -63,8 +65,9 @@ int hide(lua_State* L) {
|
||||
*/
|
||||
int toggle(lua_State* L) {
|
||||
int nArguments = lua_gettop(L);
|
||||
if (nArguments != 0)
|
||||
if (nArguments != 0) {
|
||||
return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments);
|
||||
}
|
||||
|
||||
OsEng.gui().setEnabled(!OsEng.gui().isEnabled());
|
||||
return 0;
|
||||
|
||||
@@ -33,10 +33,6 @@
|
||||
|
||||
#include "imgui.h"
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "GuiOriginComponent";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
namespace gui {
|
||||
|
||||
@@ -54,8 +50,9 @@ void GuiOriginComponent::render() {
|
||||
}
|
||||
);
|
||||
std::string nodeNames = "";
|
||||
for (SceneGraphNode* n : nodes)
|
||||
for (SceneGraphNode* n : nodes) {
|
||||
nodeNames += n->name() + '\0';
|
||||
}
|
||||
|
||||
auto iCurrentFocus = std::find(nodes.begin(), nodes.end(), currentFocus);
|
||||
ghoul_assert(iCurrentFocus != nodes.end(), "Focus node not found");
|
||||
|
||||
@@ -59,365 +59,363 @@ void GuiPerformanceComponent::render() {
|
||||
using namespace performance;
|
||||
|
||||
ImGui::Begin("Performance", &_isEnabled);
|
||||
if (OsEng.renderEngine().doesPerformanceMeasurements()) {
|
||||
PerformanceLayout* layout = OsEng.renderEngine().performanceManager()->performanceData();
|
||||
|
||||
ImGui::Checkbox("SceneGraph", &_sceneGraphIsEnabled);
|
||||
ImGui::Checkbox("Functions", &_functionsIsEnabled);
|
||||
ImGui::Checkbox("SceneGraph", &_sceneGraphIsEnabled);
|
||||
ImGui::Checkbox("Functions", &_functionsIsEnabled);
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::Spacing();
|
||||
|
||||
if (ImGui::Button("Reset measurements")) {
|
||||
OsEng.renderEngine().performanceManager()->resetPerformanceMeasurements();
|
||||
}
|
||||
if (ImGui::Button("Reset measurements")) {
|
||||
OsEng.renderEngine().performanceManager()->resetPerformanceMeasurements();
|
||||
}
|
||||
|
||||
if (_sceneGraphIsEnabled) {
|
||||
ImGui::Begin("SceneGraph", &_sceneGraphIsEnabled);
|
||||
if (_sceneGraphIsEnabled) {
|
||||
ImGui::Begin("SceneGraph", &_sceneGraphIsEnabled);
|
||||
|
||||
// The indices correspond to the index into the average array further below
|
||||
ImGui::Text("Sorting");
|
||||
ImGui::RadioButton(
|
||||
"No Sorting",
|
||||
&_sortingSelection,
|
||||
static_cast<int>(Sorting::NoSorting)
|
||||
);
|
||||
ImGui::RadioButton(
|
||||
"UpdateTranslation",
|
||||
&_sortingSelection,
|
||||
static_cast<int>(Sorting::UpdateTranslation)
|
||||
);
|
||||
ImGui::RadioButton(
|
||||
"UpdateRotation",
|
||||
&_sortingSelection,
|
||||
static_cast<int>(Sorting::UpdateRotation)
|
||||
);
|
||||
ImGui::RadioButton(
|
||||
"UpdateScaling",
|
||||
&_sortingSelection,
|
||||
static_cast<int>(Sorting::UpdateScaling)
|
||||
);
|
||||
ImGui::RadioButton(
|
||||
"UpdateRender",
|
||||
&_sortingSelection,
|
||||
static_cast<int>(Sorting::UpdateRender)
|
||||
);
|
||||
ImGui::RadioButton(
|
||||
"RenderTime",
|
||||
&_sortingSelection,
|
||||
static_cast<int>(Sorting::Render)
|
||||
);
|
||||
ImGui::RadioButton(
|
||||
"TotalTime",
|
||||
&_sortingSelection,
|
||||
static_cast<int>(Sorting::Total)
|
||||
);
|
||||
// The indices correspond to the index into the average array further below
|
||||
ImGui::Text("Sorting");
|
||||
ImGui::RadioButton(
|
||||
"No Sorting",
|
||||
&_sortingSelection,
|
||||
static_cast<int>(Sorting::NoSorting)
|
||||
);
|
||||
ImGui::RadioButton(
|
||||
"UpdateTranslation",
|
||||
&_sortingSelection,
|
||||
static_cast<int>(Sorting::UpdateTranslation)
|
||||
);
|
||||
ImGui::RadioButton(
|
||||
"UpdateRotation",
|
||||
&_sortingSelection,
|
||||
static_cast<int>(Sorting::UpdateRotation)
|
||||
);
|
||||
ImGui::RadioButton(
|
||||
"UpdateScaling",
|
||||
&_sortingSelection,
|
||||
static_cast<int>(Sorting::UpdateScaling)
|
||||
);
|
||||
ImGui::RadioButton(
|
||||
"UpdateRender",
|
||||
&_sortingSelection,
|
||||
static_cast<int>(Sorting::UpdateRender)
|
||||
);
|
||||
ImGui::RadioButton(
|
||||
"RenderTime",
|
||||
&_sortingSelection,
|
||||
static_cast<int>(Sorting::Render)
|
||||
);
|
||||
ImGui::RadioButton(
|
||||
"TotalTime",
|
||||
&_sortingSelection,
|
||||
static_cast<int>(Sorting::Total)
|
||||
);
|
||||
|
||||
// Later, we will sort this indices list instead of the real values for
|
||||
// performance reasons
|
||||
std::vector<size_t> indices(layout->nScaleGraphEntries);
|
||||
std::iota(indices.begin(), indices.end(), 0);
|
||||
// Later, we will sort this indices list instead of the real values for
|
||||
// performance reasons
|
||||
std::vector<size_t> indices(layout->nScaleGraphEntries);
|
||||
std::iota(indices.begin(), indices.end(), 0);
|
||||
|
||||
// Ordering:
|
||||
// updateTranslation
|
||||
// updateRotation
|
||||
// updateScaling
|
||||
// UpdateRender
|
||||
// RenderTime
|
||||
std::vector<std::array<float, 5>> averages(
|
||||
layout->nScaleGraphEntries,
|
||||
{ 0.f, 0.f, 0.f, 0.f, 0.f }
|
||||
);
|
||||
// Ordering:
|
||||
// updateTranslation
|
||||
// updateRotation
|
||||
// updateScaling
|
||||
// UpdateRender
|
||||
// RenderTime
|
||||
std::vector<std::array<float, 5>> averages(
|
||||
layout->nScaleGraphEntries,
|
||||
{ 0.f, 0.f, 0.f, 0.f, 0.f }
|
||||
);
|
||||
|
||||
std::vector<std::array<std::pair<float, float>, 5>> minMax(
|
||||
layout->nScaleGraphEntries
|
||||
);
|
||||
std::vector<std::array<std::pair<float, float>, 5>> minMax(
|
||||
layout->nScaleGraphEntries
|
||||
);
|
||||
|
||||
for (int i = 0; i < layout->nScaleGraphEntries; ++i) {
|
||||
const PerformanceLayout::SceneGraphPerformanceLayout& entry =
|
||||
layout->sceneGraphEntries[i];
|
||||
for (int i = 0; i < layout->nScaleGraphEntries; ++i) {
|
||||
const PerformanceLayout::SceneGraphPerformanceLayout& entry =
|
||||
layout->sceneGraphEntries[i];
|
||||
|
||||
int nValues[5] = { 0, 0, 0, 0, 0 };
|
||||
int nValues[5] = { 0, 0, 0, 0, 0 };
|
||||
|
||||
// Compute the averages and count the number of values so we don't divide
|
||||
// by 0 later
|
||||
for (int j = 0; j < PerformanceLayout::NumberValues; ++j) {
|
||||
averages[i][0] += entry.updateTranslation[j];
|
||||
if (entry.updateTranslation[j] != 0.f)
|
||||
++(nValues[0]);
|
||||
averages[i][1] += entry.updateRotation[j];
|
||||
if (entry.updateRotation[j] != 0.f)
|
||||
++(nValues[1]);
|
||||
averages[i][2] += entry.updateScaling[j];
|
||||
if (entry.updateScaling[j] != 0.f)
|
||||
++(nValues[2]);
|
||||
averages[i][3] += entry.updateRenderable[j];
|
||||
if (entry.updateRenderable[j] != 0.f)
|
||||
++(nValues[3]);
|
||||
averages[i][4] += entry.renderTime[j];
|
||||
if (entry.renderTime[j] != 0.f)
|
||||
++(nValues[4]);
|
||||
}
|
||||
|
||||
if (nValues[0] != 0)
|
||||
averages[i][0] /= static_cast<float>(nValues[0]);
|
||||
if (nValues[1] != 0)
|
||||
averages[i][1] /= static_cast<float>(nValues[1]);
|
||||
if (nValues[2] != 0)
|
||||
averages[i][2] /= static_cast<float>(nValues[2]);
|
||||
if (nValues[3] != 0)
|
||||
averages[i][3] /= static_cast<float>(nValues[3]);
|
||||
if (nValues[4] != 0)
|
||||
averages[i][4] /= static_cast<float>(nValues[4]);
|
||||
|
||||
// Get the minimum/maximum values for each of the components so that we
|
||||
// can scale the plot by these numbers
|
||||
auto minmaxTranslation = std::minmax_element(
|
||||
std::begin(entry.updateTranslation),
|
||||
std::end(entry.updateTranslation)
|
||||
);
|
||||
minMax[i][0] = std::make_pair(
|
||||
*(minmaxTranslation.first),
|
||||
*(minmaxTranslation.second)
|
||||
);
|
||||
|
||||
auto minmaxRotation = std::minmax_element(
|
||||
std::begin(entry.updateRotation),
|
||||
std::end(entry.updateRotation)
|
||||
);
|
||||
minMax[i][1] = std::make_pair(
|
||||
*(minmaxRotation.first),
|
||||
*(minmaxRotation.second)
|
||||
);
|
||||
|
||||
auto minmaxScaling = std::minmax_element(
|
||||
std::begin(entry.updateScaling),
|
||||
std::end(entry.updateScaling)
|
||||
);
|
||||
minMax[i][2] = std::make_pair(
|
||||
*(minmaxScaling.first),
|
||||
*(minmaxScaling.second)
|
||||
);
|
||||
|
||||
auto minmaxUpdateRenderable = std::minmax_element(
|
||||
std::begin(entry.updateRenderable),
|
||||
std::end(entry.updateRenderable)
|
||||
);
|
||||
minMax[i][3] = std::make_pair(
|
||||
*(minmaxUpdateRenderable.first),
|
||||
*(minmaxUpdateRenderable.second)
|
||||
);
|
||||
|
||||
auto minmaxRendering = std::minmax_element(
|
||||
std::begin(entry.renderTime),
|
||||
std::end(entry.renderTime)
|
||||
);
|
||||
minMax[i][4] = std::make_pair(
|
||||
*(minmaxRendering.first),
|
||||
*(minmaxRendering.second)
|
||||
);
|
||||
|
||||
|
||||
// Compute the averages and count the number of values so we don't divide
|
||||
// by 0 later
|
||||
for (int j = 0; j < PerformanceLayout::NumberValues; ++j) {
|
||||
averages[i][0] += entry.updateTranslation[j];
|
||||
if (entry.updateTranslation[j] != 0.f)
|
||||
++(nValues[0]);
|
||||
averages[i][1] += entry.updateRotation[j];
|
||||
if (entry.updateRotation[j] != 0.f)
|
||||
++(nValues[1]);
|
||||
averages[i][2] += entry.updateScaling[j];
|
||||
if (entry.updateScaling[j] != 0.f)
|
||||
++(nValues[2]);
|
||||
averages[i][3] += entry.updateRenderable[j];
|
||||
if (entry.updateRenderable[j] != 0.f)
|
||||
++(nValues[3]);
|
||||
averages[i][4] += entry.renderTime[j];
|
||||
if (entry.renderTime[j] != 0.f)
|
||||
++(nValues[4]);
|
||||
}
|
||||
|
||||
if (nValues[0] != 0) {
|
||||
averages[i][0] /= static_cast<float>(nValues[0]);
|
||||
}
|
||||
if (nValues[1] != 0) {
|
||||
averages[i][1] /= static_cast<float>(nValues[1]);
|
||||
}
|
||||
if (nValues[2] != 0) {
|
||||
averages[i][2] /= static_cast<float>(nValues[2]);
|
||||
}
|
||||
if (nValues[3] != 0) {
|
||||
averages[i][3] /= static_cast<float>(nValues[3]);
|
||||
}
|
||||
if (nValues[4] != 0) {
|
||||
averages[i][4] /= static_cast<float>(nValues[4]);
|
||||
}
|
||||
|
||||
// Get the minimum/maximum values for each of the components so that we
|
||||
// can scale the plot by these numbers
|
||||
auto minmaxTranslation = std::minmax_element(
|
||||
std::begin(entry.updateTranslation),
|
||||
std::end(entry.updateTranslation)
|
||||
);
|
||||
minMax[i][0] = std::make_pair(
|
||||
*(minmaxTranslation.first),
|
||||
*(minmaxTranslation.second)
|
||||
);
|
||||
|
||||
auto minmaxRotation = std::minmax_element(
|
||||
std::begin(entry.updateRotation),
|
||||
std::end(entry.updateRotation)
|
||||
);
|
||||
minMax[i][1] = std::make_pair(
|
||||
*(minmaxRotation.first),
|
||||
*(minmaxRotation.second)
|
||||
);
|
||||
|
||||
auto minmaxScaling = std::minmax_element(
|
||||
std::begin(entry.updateScaling),
|
||||
std::end(entry.updateScaling)
|
||||
);
|
||||
minMax[i][2] = std::make_pair(
|
||||
*(minmaxScaling.first),
|
||||
*(minmaxScaling.second)
|
||||
);
|
||||
|
||||
auto minmaxUpdateRenderable = std::minmax_element(
|
||||
std::begin(entry.updateRenderable),
|
||||
std::end(entry.updateRenderable)
|
||||
);
|
||||
minMax[i][3] = std::make_pair(
|
||||
*(minmaxUpdateRenderable.first),
|
||||
*(minmaxUpdateRenderable.second)
|
||||
);
|
||||
|
||||
auto minmaxRendering = std::minmax_element(
|
||||
std::begin(entry.renderTime),
|
||||
std::end(entry.renderTime)
|
||||
);
|
||||
minMax[i][4] = std::make_pair(
|
||||
*(minmaxRendering.first),
|
||||
*(minmaxRendering.second)
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
// If we don't want to sort, we will leave the indices list alone, thus
|
||||
// leaving them in the regular ordering
|
||||
Sorting selection = Sorting(_sortingSelection);
|
||||
if (selection != Sorting::NoSorting) {
|
||||
std::function<bool(size_t, size_t)> sortFunc;
|
||||
// If we don't want to sort, we will leave the indices list alone, thus
|
||||
// leaving them in the regular ordering
|
||||
Sorting selection = Sorting(_sortingSelection);
|
||||
if (selection != Sorting::NoSorting) {
|
||||
std::function<bool(size_t, size_t)> sortFunc;
|
||||
|
||||
if (selection == Sorting::Total) {
|
||||
// If we do want to sort totally, we need to sum all the averages and
|
||||
// use that as the criterion
|
||||
sortFunc = [&averages](size_t a, size_t b) {
|
||||
float sumA = std::accumulate(
|
||||
std::begin(averages[a]),
|
||||
std::end(averages[a]),
|
||||
0.f
|
||||
);
|
||||
if (selection == Sorting::Total) {
|
||||
// If we do want to sort totally, we need to sum all the averages and
|
||||
// use that as the criterion
|
||||
sortFunc = [&averages](size_t a, size_t b) {
|
||||
float sumA = std::accumulate(
|
||||
std::begin(averages[a]),
|
||||
std::end(averages[a]),
|
||||
0.f
|
||||
);
|
||||
|
||||
float sumB = std::accumulate(
|
||||
std::begin(averages[b]),
|
||||
std::end(averages[b]),
|
||||
0.f
|
||||
);
|
||||
float sumB = std::accumulate(
|
||||
std::begin(averages[b]),
|
||||
std::end(averages[b]),
|
||||
0.f
|
||||
);
|
||||
|
||||
return sumA > sumB;
|
||||
};
|
||||
}
|
||||
else {
|
||||
// otherwise we use the sorting index
|
||||
int sel = _sortingSelection;
|
||||
sortFunc = [sel, &averages](size_t a, size_t b) {
|
||||
return averages[a][sel] > averages[b][sel];
|
||||
};
|
||||
}
|
||||
|
||||
std::sort(
|
||||
indices.begin(),
|
||||
indices.end(),
|
||||
sortFunc
|
||||
);
|
||||
return sumA > sumB;
|
||||
};
|
||||
}
|
||||
else {
|
||||
// NoSorting -> So we sort by names instead
|
||||
std::sort(
|
||||
indices.begin(),
|
||||
indices.end(),
|
||||
[layout](size_t a, size_t b) {
|
||||
return std::string(layout->sceneGraphEntries[a].name) < std::string(layout->sceneGraphEntries[b].name);
|
||||
}
|
||||
);
|
||||
// otherwise we use the sorting index
|
||||
int sel = _sortingSelection;
|
||||
sortFunc = [sel, &averages](size_t a, size_t b) {
|
||||
return averages[a][sel] > averages[b][sel];
|
||||
};
|
||||
}
|
||||
|
||||
for (int i = 0; i < layout->nScaleGraphEntries; ++i) {
|
||||
// We are using the indices list as an additional level of indirection
|
||||
// into the respective values so that the list will be sorted by whatever
|
||||
// criterion we selected previously
|
||||
|
||||
const PerformanceLayout::SceneGraphPerformanceLayout& entry =
|
||||
layout->sceneGraphEntries[indices[i]];
|
||||
|
||||
if (ImGui::CollapsingHeader(entry.name)) {
|
||||
|
||||
std::string updateTranslationTime = std::to_string(
|
||||
entry.updateTranslation[PerformanceLayout::NumberValues - 1]
|
||||
) + "us";
|
||||
|
||||
ImGui::PlotLines(
|
||||
fmt::format(
|
||||
"UpdateTranslation\nAverage: {}us",
|
||||
averages[indices[i]][0]
|
||||
).c_str(),
|
||||
&entry.updateTranslation[0],
|
||||
PerformanceLayout::NumberValues,
|
||||
0,
|
||||
updateTranslationTime.c_str(),
|
||||
minMax[indices[i]][0].first,
|
||||
minMax[indices[i]][0].second,
|
||||
ImVec2(0, 40)
|
||||
);
|
||||
|
||||
std::string updateRotationTime = std::to_string(
|
||||
entry.updateRotation[PerformanceLayout::NumberValues - 1]
|
||||
) + "us";
|
||||
|
||||
ImGui::PlotLines(
|
||||
fmt::format(
|
||||
"UpdateRotation\nAverage: {}us",
|
||||
averages[indices[i]][1]
|
||||
).c_str(),
|
||||
&entry.updateRotation[0],
|
||||
PerformanceLayout::NumberValues,
|
||||
0,
|
||||
updateRotationTime.c_str(),
|
||||
minMax[indices[i]][1].first,
|
||||
minMax[indices[i]][1].second,
|
||||
ImVec2(0, 40)
|
||||
);
|
||||
|
||||
std::string updateScalingTime = std::to_string(
|
||||
entry.updateScaling[PerformanceLayout::NumberValues - 1]
|
||||
) + "us";
|
||||
|
||||
ImGui::PlotLines(
|
||||
fmt::format(
|
||||
"UpdateScaling\nAverage: {}us",
|
||||
averages[indices[i]][2]
|
||||
).c_str(),
|
||||
&entry.updateScaling[0],
|
||||
PerformanceLayout::NumberValues,
|
||||
0,
|
||||
updateScalingTime.c_str(),
|
||||
minMax[indices[i]][2].first,
|
||||
minMax[indices[i]][2].second,
|
||||
ImVec2(0, 40)
|
||||
);
|
||||
|
||||
std::string updateRenderableTime = std::to_string(
|
||||
entry.updateRenderable[PerformanceLayout::NumberValues - 1]
|
||||
) + "us";
|
||||
|
||||
ImGui::PlotLines(
|
||||
fmt::format(
|
||||
"UpdateRender\nAverage: {}us",
|
||||
averages[indices[i]][3]
|
||||
).c_str(),
|
||||
&entry.updateRenderable[0],
|
||||
PerformanceLayout::NumberValues,
|
||||
0,
|
||||
updateRenderableTime.c_str(),
|
||||
minMax[indices[i]][3].first,
|
||||
minMax[indices[i]][3].second,
|
||||
ImVec2(0, 40)
|
||||
);
|
||||
|
||||
std::string renderTime = std::to_string(
|
||||
entry.renderTime[PerformanceLayout::NumberValues - 1]
|
||||
) + "us";
|
||||
|
||||
ImGui::PlotLines(
|
||||
fmt::format(
|
||||
"RenderTime\nAverage: {}us",
|
||||
averages[indices[i]][4]
|
||||
).c_str(),
|
||||
&entry.renderTime[0],
|
||||
PerformanceLayout::NumberValues,
|
||||
0,
|
||||
renderTime.c_str(),
|
||||
minMax[indices[i]][4].first,
|
||||
minMax[indices[i]][4].second,
|
||||
ImVec2(0, 40)
|
||||
);
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
std::sort(
|
||||
indices.begin(),
|
||||
indices.end(),
|
||||
sortFunc
|
||||
);
|
||||
}
|
||||
|
||||
if (_functionsIsEnabled) {
|
||||
ImGui::Begin("Functions", &_functionsIsEnabled);
|
||||
using namespace performance;
|
||||
|
||||
for (int i = 0; i < layout->nFunctionEntries; ++i) {
|
||||
const PerformanceLayout::FunctionPerformanceLayout& entry =
|
||||
layout->functionEntries[i];
|
||||
|
||||
float avg = 0.f;
|
||||
int count = 0;
|
||||
for (int j = 0; j < PerformanceLayout::NumberValues; ++j) {
|
||||
avg += layout->functionEntries[i].time[j];
|
||||
if (layout->functionEntries[i].time[j] != 0.f)
|
||||
++count;
|
||||
else {
|
||||
// NoSorting -> So we sort by names instead
|
||||
std::sort(
|
||||
indices.begin(),
|
||||
indices.end(),
|
||||
[layout](size_t a, size_t b) {
|
||||
return std::string(layout->sceneGraphEntries[a].name) < std::string(layout->sceneGraphEntries[b].name);
|
||||
}
|
||||
avg /= count;
|
||||
|
||||
auto minmax = std::minmax_element(
|
||||
std::begin(layout->functionEntries[i].time),
|
||||
std::end(layout->functionEntries[i].time)
|
||||
);
|
||||
|
||||
const PerformanceLayout::FunctionPerformanceLayout& f =
|
||||
layout->functionEntries[i];
|
||||
|
||||
std::string renderTime = std::to_string(
|
||||
entry.time[PerformanceLayout::NumberValues - 1]
|
||||
);
|
||||
}
|
||||
|
||||
for (int i = 0; i < layout->nScaleGraphEntries; ++i) {
|
||||
// We are using the indices list as an additional level of indirection
|
||||
// into the respective values so that the list will be sorted by whatever
|
||||
// criterion we selected previously
|
||||
|
||||
const PerformanceLayout::SceneGraphPerformanceLayout& entry =
|
||||
layout->sceneGraphEntries[indices[i]];
|
||||
|
||||
if (ImGui::CollapsingHeader(entry.name)) {
|
||||
std::string updateTranslationTime = std::to_string(
|
||||
entry.updateTranslation[PerformanceLayout::NumberValues - 1]
|
||||
) + "us";
|
||||
|
||||
ImGui::PlotLines(
|
||||
fmt::format("{}\nAverage: {}us", entry.name, avg).c_str(),
|
||||
&entry.time[0],
|
||||
fmt::format(
|
||||
"UpdateTranslation\nAverage: {}us",
|
||||
averages[indices[i]][0]
|
||||
).c_str(),
|
||||
&entry.updateTranslation[0],
|
||||
PerformanceLayout::NumberValues,
|
||||
0,
|
||||
updateTranslationTime.c_str(),
|
||||
minMax[indices[i]][0].first,
|
||||
minMax[indices[i]][0].second,
|
||||
ImVec2(0, 40)
|
||||
);
|
||||
|
||||
std::string updateRotationTime = std::to_string(
|
||||
entry.updateRotation[PerformanceLayout::NumberValues - 1]
|
||||
) + "us";
|
||||
|
||||
ImGui::PlotLines(
|
||||
fmt::format(
|
||||
"UpdateRotation\nAverage: {}us",
|
||||
averages[indices[i]][1]
|
||||
).c_str(),
|
||||
&entry.updateRotation[0],
|
||||
PerformanceLayout::NumberValues,
|
||||
0,
|
||||
updateRotationTime.c_str(),
|
||||
minMax[indices[i]][1].first,
|
||||
minMax[indices[i]][1].second,
|
||||
ImVec2(0, 40)
|
||||
);
|
||||
|
||||
std::string updateScalingTime = std::to_string(
|
||||
entry.updateScaling[PerformanceLayout::NumberValues - 1]
|
||||
) + "us";
|
||||
|
||||
ImGui::PlotLines(
|
||||
fmt::format(
|
||||
"UpdateScaling\nAverage: {}us",
|
||||
averages[indices[i]][2]
|
||||
).c_str(),
|
||||
&entry.updateScaling[0],
|
||||
PerformanceLayout::NumberValues,
|
||||
0,
|
||||
updateScalingTime.c_str(),
|
||||
minMax[indices[i]][2].first,
|
||||
minMax[indices[i]][2].second,
|
||||
ImVec2(0, 40)
|
||||
);
|
||||
|
||||
std::string updateRenderableTime = std::to_string(
|
||||
entry.updateRenderable[PerformanceLayout::NumberValues - 1]
|
||||
) + "us";
|
||||
|
||||
ImGui::PlotLines(
|
||||
fmt::format(
|
||||
"UpdateRender\nAverage: {}us",
|
||||
averages[indices[i]][3]
|
||||
).c_str(),
|
||||
&entry.updateRenderable[0],
|
||||
PerformanceLayout::NumberValues,
|
||||
0,
|
||||
updateRenderableTime.c_str(),
|
||||
minMax[indices[i]][3].first,
|
||||
minMax[indices[i]][3].second,
|
||||
ImVec2(0, 40)
|
||||
);
|
||||
|
||||
std::string renderTime = std::to_string(
|
||||
entry.renderTime[PerformanceLayout::NumberValues - 1]
|
||||
) + "us";
|
||||
|
||||
ImGui::PlotLines(
|
||||
fmt::format(
|
||||
"RenderTime\nAverage: {}us",
|
||||
averages[indices[i]][4]
|
||||
).c_str(),
|
||||
&entry.renderTime[0],
|
||||
PerformanceLayout::NumberValues,
|
||||
0,
|
||||
renderTime.c_str(),
|
||||
*(minmax.first),
|
||||
*(minmax.second),
|
||||
minMax[indices[i]][4].first,
|
||||
minMax[indices[i]][4].second,
|
||||
ImVec2(0, 40)
|
||||
);
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
else {
|
||||
ImGui::TextWrapped("Performance monitoring is disabled. Enable with "
|
||||
"'openspace.setPerformanceMeasurement(true)'");
|
||||
|
||||
if (_functionsIsEnabled) {
|
||||
ImGui::Begin("Functions", &_functionsIsEnabled);
|
||||
using namespace performance;
|
||||
|
||||
for (int i = 0; i < layout->nFunctionEntries; ++i) {
|
||||
const PerformanceLayout::FunctionPerformanceLayout& entry =
|
||||
layout->functionEntries[i];
|
||||
|
||||
float avg = 0.f;
|
||||
int count = 0;
|
||||
for (int j = 0; j < PerformanceLayout::NumberValues; ++j) {
|
||||
avg += layout->functionEntries[i].time[j];
|
||||
if (layout->functionEntries[i].time[j] != 0.f)
|
||||
++count;
|
||||
}
|
||||
avg /= count;
|
||||
|
||||
auto minmax = std::minmax_element(
|
||||
std::begin(layout->functionEntries[i].time),
|
||||
std::end(layout->functionEntries[i].time)
|
||||
);
|
||||
|
||||
const PerformanceLayout::FunctionPerformanceLayout& f =
|
||||
layout->functionEntries[i];
|
||||
|
||||
std::string renderTime = std::to_string(
|
||||
entry.time[PerformanceLayout::NumberValues - 1]
|
||||
) + "us";
|
||||
ImGui::PlotLines(
|
||||
fmt::format("{}\nAverage: {}us", entry.name, avg).c_str(),
|
||||
&entry.time[0],
|
||||
PerformanceLayout::NumberValues,
|
||||
0,
|
||||
renderTime.c_str(),
|
||||
*(minmax.first),
|
||||
*(minmax.second),
|
||||
ImVec2(0, 40)
|
||||
);
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
|
||||
@@ -47,6 +47,10 @@ void GuiPropertyComponent::setSource(SourceFunction function) {
|
||||
}
|
||||
|
||||
void GuiPropertyComponent::renderPropertyOwner(properties::PropertyOwner* owner) {
|
||||
if (owner->propertiesRecursive().empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::PushID(owner->name().c_str());
|
||||
const auto& subOwners = owner->propertySubOwners();
|
||||
for (properties::PropertyOwner* subOwner : subOwners) {
|
||||
|
||||
@@ -59,8 +59,9 @@ void renderBoolProperty(Property* prop, const std::string& ownerName) {
|
||||
ImGui::Checkbox(name.c_str(), &value);
|
||||
renderTooltip(prop);
|
||||
|
||||
if (value != p->value())
|
||||
if (value != p->value()) {
|
||||
executeScript(p->fullyQualifiedIdentifier(), value ? "true" : "false");
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
@@ -90,8 +91,9 @@ void renderOptionProperty(Property* prop, const std::string& ownerName) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (value != p->value())
|
||||
if (value != p->value()) {
|
||||
executeScript(p->fullyQualifiedIdentifier(), std::to_string(value));
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
@@ -115,14 +117,16 @@ void renderSelectionProperty(Property* prop, const std::string& ownerName) {
|
||||
ImGui::Checkbox(description.c_str(), &selected);
|
||||
renderTooltip(prop);
|
||||
|
||||
if (selected)
|
||||
if (selected) {
|
||||
newSelectedIndices.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (newSelectedIndices != p->value()) {
|
||||
std::string parameters = "{";
|
||||
for (int i : newSelectedIndices)
|
||||
for (int i : newSelectedIndices) {
|
||||
parameters += std::to_string(i) + ",";
|
||||
}
|
||||
parameters += "}";
|
||||
executeScript(p->fullyQualifiedIdentifier(), parameters);
|
||||
}
|
||||
@@ -148,8 +152,9 @@ void renderStringProperty(Property* prop, const std::string& ownerName) {
|
||||
|
||||
std::string newValue(buffer);
|
||||
|
||||
if (newValue != p->value())
|
||||
if (newValue != p->value()) {
|
||||
executeScript(p->fullyQualifiedIdentifier(), "'" + newValue + "'");
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
@@ -166,8 +171,9 @@ void renderIntProperty(Property* prop, const std::string& ownerName) {
|
||||
ImGui::SliderInt(name.c_str(), &value, min, max);
|
||||
renderTooltip(prop);
|
||||
|
||||
if (value != p->value())
|
||||
if (value != p->value()) {
|
||||
executeScript(p->fullyQualifiedIdentifier(), std::to_string(value));
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
@@ -181,17 +187,18 @@ void renderIVec2Property(Property* prop, const std::string& ownerName) {
|
||||
float min = std::min(p->minValue().x, p->minValue().y);
|
||||
float max = std::max(p->maxValue().x, p->maxValue().y);
|
||||
ImGui::SliderInt2(
|
||||
name.c_str(),
|
||||
&value.x,
|
||||
min,
|
||||
max
|
||||
);
|
||||
name.c_str(),
|
||||
&value.x,
|
||||
min,
|
||||
max
|
||||
);
|
||||
renderTooltip(prop);
|
||||
|
||||
if (value != p->value()) {
|
||||
executeScript(p->fullyQualifiedIdentifier(),
|
||||
"{" + std::to_string(value.x) + "," + std::to_string(value.y) + "}"
|
||||
);
|
||||
executeScript(
|
||||
p->fullyQualifiedIdentifier(),
|
||||
"{" + std::to_string(value.x) + "," + std::to_string(value.y) + "}"
|
||||
);
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
@@ -207,19 +214,20 @@ void renderIVec3Property(Property* prop, const std::string& ownerName) {
|
||||
float max = std::max(std::max(p->maxValue().x, p->maxValue().y), p->maxValue().z);
|
||||
|
||||
ImGui::SliderInt3(
|
||||
name.c_str(),
|
||||
&value.x,
|
||||
min,
|
||||
max
|
||||
);
|
||||
name.c_str(),
|
||||
&value.x,
|
||||
min,
|
||||
max
|
||||
);
|
||||
renderTooltip(prop);
|
||||
|
||||
if (value != p->value())
|
||||
executeScript(p->fullyQualifiedIdentifier(),
|
||||
"{" + std::to_string(value.x) + "," +
|
||||
std::to_string(value.y) + "," +
|
||||
std::to_string(value.z) + "}");
|
||||
|
||||
if (value != p->value()) {
|
||||
executeScript(
|
||||
p->fullyQualifiedIdentifier(),
|
||||
"{" + std::to_string(value.x) + "," + std::to_string(value.y) + "," +
|
||||
std::to_string(value.z) + "}"
|
||||
);
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
@@ -230,29 +238,32 @@ void renderIVec4Property(Property* prop, const std::string& ownerName) {
|
||||
|
||||
IVec4Property::ValueType value = *p;
|
||||
float min = std::min(std::min(std::min(
|
||||
p->minValue().x, p->minValue().y), p->minValue().z), p->minValue().w);
|
||||
p->minValue().x, p->minValue().y), p->minValue().z), p->minValue().w
|
||||
);
|
||||
float max = std::max(std::max(std::max(
|
||||
p->maxValue().x, p->maxValue().y), p->maxValue().z), p->maxValue().w);
|
||||
p->maxValue().x, p->maxValue().y), p->maxValue().z), p->maxValue().w
|
||||
);
|
||||
|
||||
ImGui::SliderInt4(
|
||||
name.c_str(),
|
||||
&value.x,
|
||||
min,
|
||||
max
|
||||
);
|
||||
name.c_str(),
|
||||
&value.x,
|
||||
min,
|
||||
max
|
||||
);
|
||||
renderTooltip(prop);
|
||||
|
||||
if (value != p->value())
|
||||
executeScript(p->fullyQualifiedIdentifier(),
|
||||
"{" + std::to_string(value.x) + "," +
|
||||
std::to_string(value.y) + "," +
|
||||
std::to_string(value.z) + "," +
|
||||
std::to_string(value.w) + "}");
|
||||
|
||||
if (value != p->value()) {
|
||||
executeScript(
|
||||
p->fullyQualifiedIdentifier(),
|
||||
"{" + std::to_string(value.x) + "," +
|
||||
std::to_string(value.y) + "," +
|
||||
std::to_string(value.z) + "," +
|
||||
std::to_string(value.w) + "}"
|
||||
);
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void renderFloatProperty(Property* prop, const std::string& ownerName) {
|
||||
FloatProperty* p = static_cast<FloatProperty*>(prop);
|
||||
std::string name = p->guiName();
|
||||
@@ -264,8 +275,9 @@ void renderFloatProperty(Property* prop, const std::string& ownerName) {
|
||||
ImGui::SliderFloat(name.c_str(), &value, min, max);
|
||||
renderTooltip(prop);
|
||||
|
||||
if (value != p->value())
|
||||
if (value != p->value()) {
|
||||
executeScript(p->fullyQualifiedIdentifier(), std::to_string(value));
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
@@ -287,8 +299,9 @@ void renderVec2Property(Property* prop, const std::string& ownerName) {
|
||||
renderTooltip(prop);
|
||||
|
||||
if (value != p->value()) {
|
||||
executeScript(p->fullyQualifiedIdentifier(),
|
||||
"{" + std::to_string(value.x) + "," + std::to_string(value.y) + "}"
|
||||
executeScript(
|
||||
p->fullyQualifiedIdentifier(),
|
||||
"{" + std::to_string(value.x) + "," + std::to_string(value.y) + "}"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -312,11 +325,14 @@ void renderVec3Property(Property* prop, const std::string& ownerName) {
|
||||
);
|
||||
renderTooltip(prop);
|
||||
|
||||
if (value != p->value())
|
||||
executeScript(p->fullyQualifiedIdentifier(),
|
||||
"{" + std::to_string(value.x) + "," +
|
||||
std::to_string(value.y) + "," +
|
||||
std::to_string(value.z) + "}");
|
||||
if (value != p->value()) {
|
||||
executeScript(
|
||||
p->fullyQualifiedIdentifier(),
|
||||
"{" + std::to_string(value.x) + "," +
|
||||
std::to_string(value.y) + "," +
|
||||
std::to_string(value.z) + "}"
|
||||
);
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
@@ -340,12 +356,15 @@ void renderVec4Property(Property* prop, const std::string& ownerName) {
|
||||
);
|
||||
renderTooltip(prop);
|
||||
|
||||
if (value != p->value())
|
||||
executeScript(p->fullyQualifiedIdentifier(),
|
||||
"{" + std::to_string(value.x) + "," +
|
||||
std::to_string(value.y) + "," +
|
||||
std::to_string(value.z) + "," +
|
||||
std::to_string(value.w) + "}");
|
||||
if (value != p->value()) {
|
||||
executeScript(
|
||||
p->fullyQualifiedIdentifier(),
|
||||
"{" + std::to_string(value.x) + "," +
|
||||
std::to_string(value.y) + "," +
|
||||
std::to_string(value.z) + "," +
|
||||
std::to_string(value.w) + "}"
|
||||
);
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
@@ -355,8 +374,9 @@ void renderTriggerProperty(Property* prop, const std::string& ownerName) {
|
||||
ImGui::PushID((ownerName + "." + name).c_str());
|
||||
|
||||
bool pressed = ImGui::Button(name.c_str());
|
||||
if (pressed)
|
||||
if (pressed) {
|
||||
executeScript(prop->fullyQualifiedIdentifier(), "nil");
|
||||
}
|
||||
renderTooltip(prop);
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <ghoul/lua/lua_helper.h>
|
||||
#include <ghoul/misc/exception.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
#include <list>
|
||||
|
||||
|
||||
@@ -211,8 +211,8 @@ Documentation ConfigurationManager::Documentation() {
|
||||
}
|
||||
}),
|
||||
"Contains a log of all Lua scripts that were executed in the last "
|
||||
"session.",
|
||||
Optional::Yes
|
||||
"session.",
|
||||
Optional::Yes
|
||||
},
|
||||
{
|
||||
ConfigurationManager::KeyKeyboardShortcuts,
|
||||
@@ -282,7 +282,8 @@ Documentation ConfigurationManager::Documentation() {
|
||||
}),
|
||||
"This defines the location and type of the factory documentation file, which "
|
||||
"shows the different types of objects that can be created in the current "
|
||||
"application configuration."
|
||||
"application configuration.",
|
||||
Optional::Yes
|
||||
},
|
||||
{
|
||||
ConfigurationManager::KeyShutdownCountdown,
|
||||
|
||||
@@ -173,7 +173,6 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName,
|
||||
);
|
||||
SpiceManager::initialize();
|
||||
Time::initialize();
|
||||
ghoul::systemcapabilities::SystemCapabilities::initialize();
|
||||
TransformationManager::initialize();
|
||||
}
|
||||
|
||||
@@ -385,11 +384,12 @@ void OpenSpaceEngine::destroy() {
|
||||
|
||||
_engine->_scriptEngine->deinitialize();
|
||||
delete _engine;
|
||||
ghoul::systemcapabilities::SystemCapabilities::deinitialize();
|
||||
FactoryManager::deinitialize();
|
||||
Time::deinitialize();
|
||||
SpiceManager::deinitialize();
|
||||
|
||||
ghoul::fontrendering::FontRenderer::deinitialize();
|
||||
|
||||
LogManager::deinitialize();
|
||||
|
||||
ghoul::deinitialize();
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/engine/wrapper/windowwrapper.h>
|
||||
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
#include <ghoul/systemcapabilities/openglcapabilitiescomponent.h>
|
||||
#include <ghoul/font/fontrenderer.h>
|
||||
#include <ghoul/font/fontmanager.h>
|
||||
#include <ghoul/font/font.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <openspace/engine/wrapper/windowwrapper.h>
|
||||
#include <openspace/rendering/screenspacerenderable.h>
|
||||
|
||||
+12
-7
@@ -47,11 +47,12 @@
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <numeric>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
|
||||
#ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED
|
||||
#include <modules/onscreengui/include/gui.h>
|
||||
@@ -549,12 +550,16 @@ void Scene::writePropertyDocumentation(const std::string& filename, const std::s
|
||||
|
||||
std::stringstream json;
|
||||
json << "[";
|
||||
auto nodes = _graph.nodes();
|
||||
for (SceneGraphNode* node : nodes) {
|
||||
json << createJson(node);
|
||||
if (node != nodes.back()) {
|
||||
json << ",";
|
||||
}
|
||||
std::vector<SceneGraphNode*> nodes = _graph.nodes();
|
||||
if (!nodes.empty()) {
|
||||
json << std::accumulate(
|
||||
std::next(nodes.begin()),
|
||||
nodes.end(),
|
||||
createJson(*nodes.begin()),
|
||||
[createJson](std::string a, SceneGraphNode* n) {
|
||||
return a + "," + createJson(n);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
json << "]";
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* GHOUL *
|
||||
* General Helpful Open Utility Library *
|
||||
* *
|
||||
* Copyright (c) 2012-2015 *
|
||||
* Copyright (c) 2012-2016 *
|
||||
* *
|
||||
* 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 *
|
||||
|
||||
Reference in New Issue
Block a user