diff --git a/include/openspace/rendering/model/renderablemodel.h b/include/openspace/rendering/model/renderablemodel.h index 929da28809..4dd721cc16 100644 --- a/include/openspace/rendering/model/renderablemodel.h +++ b/include/openspace/rendering/model/renderablemodel.h @@ -25,13 +25,11 @@ #ifndef __RENDERABLEMODEL_H__ #define __RENDERABLEMODEL_H__ -// open space includes #include #include #include -// ghoul includes #include #include @@ -44,7 +42,6 @@ class ModelGeometry; class RenderableModel : public Renderable { public: RenderableModel(const ghoul::Dictionary& dictionary); - ~RenderableModel(); bool initialize() override; bool deinitialize() override; @@ -70,7 +67,8 @@ private: std::string _source; std::string _destination; - double _time; + + psc _sunPosition; properties::BoolProperty _performShading; }; diff --git a/include/openspace/rendering/model/wavefrontgeometry.h b/include/openspace/rendering/model/wavefrontgeometry.h index 9d961bec79..be9e467205 100644 --- a/include/openspace/rendering/model/wavefrontgeometry.h +++ b/include/openspace/rendering/model/wavefrontgeometry.h @@ -26,7 +26,6 @@ #define __WAVEFRONTOBJECT_H__ #include -#include namespace openspace { @@ -37,40 +36,29 @@ namespace modelgeometry { class WavefrontGeometry : public ModelGeometry { public: WavefrontGeometry(const ghoul::Dictionary& dictionary); - ~WavefrontGeometry(); bool initialize(RenderableModel* parent) override; void deinitialize() override; void render() override; - typedef struct - { - GLfloat location[4]; - GLfloat tex[2]; - GLfloat normal[3]; - GLfloat padding[7]; - //GLubyte padding[4]; // Pads the struct out to 64 bytes for performance increase - } Vertex; - - std::vector shapes; - std::vector materials; -protected: - void loadObj(const char *filename); private: - void createSphere(); - + struct Vertex { + GLfloat location[4]; + GLfloat tex[2]; + GLfloat normal[3]; + }; + + bool loadObj(const std::string& filename); + bool loadCachedFile(const std::string& filename); + bool saveCachedFile(const std::string& filename); + bool loadModel(const std::string& filename); + GLuint _vaoID; - GLuint _vBufferID; - GLuint _iBufferID; + GLuint _vbo; + GLuint _ibo; - GLuint _tBufferID; - unsigned int _tsize; - float* _tarray; - - unsigned int _isize; - unsigned int _vsize; - Vertex* _varray; - int* _iarray; + std::vector _vertices; + std::vector _indices; }; } // namespace modelgeometry diff --git a/include/openspace/rendering/renderablefov.h b/include/openspace/rendering/renderablefov.h index 409b4e0bcc..effadbfe6a 100644 --- a/include/openspace/rendering/renderablefov.h +++ b/include/openspace/rendering/renderablefov.h @@ -50,8 +50,9 @@ public: void render(const RenderData& data) override; void update(const UpdateData& data) override; + private: - properties::StringProperty _colorTexturePath; + properties::FloatProperty _lineWidth; ghoul::opengl::ProgramObject* _programObject; ghoul::opengl::Texture* _texture; openspace::SceneGraphNode* _targetNode; diff --git a/include/openspace/rendering/renderableplane.h b/include/openspace/rendering/renderableplane.h index 1e09c4aa1e..2c296da5f7 100644 --- a/include/openspace/rendering/renderableplane.h +++ b/include/openspace/rendering/renderableplane.h @@ -25,14 +25,21 @@ #ifndef RENDERABLEPLANE_H_ #define RENDERABLEPLANE_H_ -// open space includes #include + +#include +#include #include -// ghoul includes -#include -#include -#include +namespace ghoul { + namespace filesystem { + class File; + } + namespace opengl { + class ProgramObject; + class Texture; + } +} namespace openspace { struct LinePoint; @@ -57,16 +64,21 @@ public: private: void loadTexture(); + void createPlane(); properties::StringProperty _texturePath; properties::BoolProperty _billboard; + properties::Vec2Property _size; - glm::vec2 _size; Origin _origin; + bool _planeIsDirty; + ghoul::opengl::ProgramObject* _shader; bool _programIsDirty; + bool _textureIsDirty; ghoul::opengl::Texture* _texture; + ghoul::filesystem::File* _textureFile; GLuint _quad; GLuint _vertexPositionBuffer; }; diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index efe5611cf5..4127731039 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -74,8 +74,8 @@ public: void serialize(SyncBuffer* syncBuffer); void deserialize(SyncBuffer* syncBuffer); - float globalOpacity(); - void setGlobalOpacity(float opacity); + float globalBlackOutFactor(); + void setGlobalBlackOutFactor(float factor); void setSGCTRenderStatistics(bool visible); @@ -114,7 +114,7 @@ private: void generateGlslConfig(); - float _globalOpactity; + float _globalBlackOutFactor; float _fadeDuration; float _currentFadeTime; int _fadeDirection; diff --git a/include/openspace/scripting/scriptengine.h b/include/openspace/scripting/scriptengine.h index 725f6e14a2..f1f2e79754 100644 --- a/include/openspace/scripting/scriptengine.h +++ b/include/openspace/scripting/scriptengine.h @@ -85,7 +85,7 @@ private: bool registerLuaLibrary(lua_State* state, const LuaLibrary& library); void addLibraryFunctions(lua_State* state, const LuaLibrary& library, bool replace); - bool isLibraryNameAllowed(const std::string& name); + bool isLibraryNameAllowed(lua_State* state, const std::string& name); void addBaseLibrary(); void remapPrintFunction(); diff --git a/include/openspace/util/constants.h b/include/openspace/util/constants.h index c82272d426..d82d62fb76 100644 --- a/include/openspace/util/constants.h +++ b/include/openspace/util/constants.h @@ -88,11 +88,6 @@ namespace renderablemodel { const std::string keyGeometry = "Geometry"; } // namespace renderablemodel -namespace modelgeometry { - const std::string keyType = "Type"; - const std::string keyObjFile = "ObjFile"; -} // namespace modelgeometry - namespace renderablestars { const std::string keyFile = "File"; const std::string keyTexture = "Texture"; diff --git a/include/openspace/util/time.h b/include/openspace/util/time.h index 67a5d49cbc..b02763709d 100644 --- a/include/openspace/util/time.h +++ b/include/openspace/util/time.h @@ -126,6 +126,24 @@ public: */ double deltaTime() const; + /** + * Sets the pause function, i.e. setting the deltaTime to 0 (pause = + * true) and restoring it when the function is called with a parameter of + * false. + * \param If true, the simulation time stops; if false, the + * simulation time continues at the previous rate + */ + void setPause(bool pause); + + /** + * Toggles the pause function, i.e. setting the deltaTime to 0 and restoring it when + * the function is called a second time. It returns the pause state (true + * if the time is now paused, false otherwise) + * \return The new pause state (true if the time is now paused, + * false otherwise) + */ + bool togglePause(); + /** * Advances the simulation time using the deltaTime() and the tickTime. * The deltaTime() is the number of simulation seconds that pass for each real-time @@ -138,18 +156,6 @@ public: */ double advanceTime(double tickTime); - /** - * Retreats the simulation time using the deltaTime() and the tickTime. - * The deltaTime() is the number of simulation seconds that pass for each real-time - * second. tickTime is the number of real-time seconds that passed since - * the last call to this method. If this method is called in the render loop, the - * tickTime should be equivalent to the frame time. - * \param tickTime The number of real-time seconds that passed since the last call - * to this method - * \return The new time value after retreating the time - */ - double retreatTime(double tickTime); - void serialize(SyncBuffer* syncBuffer); void deserialize(SyncBuffer* syncBuffer); @@ -192,6 +198,7 @@ private: double _time; ///< The time stored as the number of seconds past the J2000 epoch double _dt; bool _timeJumped; + bool _timePaused; bool _jockeHasToFixThisLater; //shared copies diff --git a/scripts/bind_keys.lua b/scripts/bind_keys.lua index 4f795a7618..320207ace1 100644 --- a/scripts/bind_keys.lua +++ b/scripts/bind_keys.lua @@ -1,24 +1,29 @@ +--[[ OpenSpace keybinding script ]]-- +-- This script sets the default keybindings and is executed at startup + openspace.clearKeys() +openspace.bindKey("F1", "openspace.gui.toggle()") +openspace.bindKey("F2", "openspace.setPerformanceMeasurement(true)") +openspace.bindKey("F3", "openspace.setPerformanceMeasurement(false)") +openspace.bindKey("F5", "openspace.changeCoordinateSystem('Sun'); openspace.printInfo('Changing Viewpoint to Sun-in-center');"); +openspace.bindKey("F6", "openspace.changeCoordinateSystem('Jupiter'); openspace.printInfo('Changing Viewpoint to Jupiter-in-center');"); +openspace.bindKey("F7", "openspace.changeCoordinateSystem('Pluto'); openspace.printInfo('Changing Viewpoint to Pluto-in-center');"); +openspace.bindKey("F11", "openspace.fadeOut(2)") +openspace.bindKey("F12", "openspace.fadeIn(2)") +openspace.bindKey("PRINT_SCREEN", "openspace.takeScreenshot()") -interaction_speed = 2.75 +openspace.bindKey("SPACE", "openspace.time.togglePause()") --- Key Bindings -openspace.bindKey("f1", "openspace.gui.toggle()") -openspace.bindKey("f2", "openspace.setPerformanceMeasurement(true)") -openspace.bindKey("f3", "openspace.setPerformanceMeasurement(false)") -openspace.bindKey("f4", "openspace.takeScreenshot()") -openspace.bindKey("f5", "loadKeyBindings()") +-- Bookmarks for the New Horizons encounter +openspace.bindKey("1", "openspace.time.setTime('2007-02-27T16:40:00.00'); openspace.time.setDeltaTime(10)") +openspace.bindKey("2", "openspace.time.setTime('2015-07-14T10:50:00.00'); openspace.time.setDeltaTime(10)") +openspace.bindKey("3", "openspace.time.setTime('2015-07-14T11:22:00.00'); openspace.time.setDeltaTime(1)") +openspace.bindKey("4", "openspace.time.setTime('2015-07-14T11:36:40.00'); openspace.time.setDeltaTime(1)") +openspace.bindKey("5", "openspace.time.setTime('2015-07-14T11:48:43.00'); openspace.time.setDeltaTime(1)") +openspace.bindKey("6", "openspace.time.setTime('2015-07-14T12:04:35.00'); openspace.time.setDeltaTime(1)") +openspace.bindKey("7", "openspace.time.setTime('2015-07-14T15:02:46.00'); openspace.time.setDeltaTime(100)") -openspace.bindKey("f9", "openspace.changeCoordinateSystem('Pluto'); openspace.printInfo('Changing Viewpoint to Pluto-in-center');"); -openspace.bindKey("f10", "openspace.changeCoordinateSystem('Sun'); openspace.printInfo('Changing Viewpoint to Sun-in-center');"); -openspace.bindKey("f11", "openspace.fadeOut(2);") -openspace.bindKey("f12", "openspace.fadeIn(2);") +openspace.bindKey("q", "local b = openspace.getPropertyValue('SunMarker.renderable.enabled'); openspace.setPropertyValue('SunMarker.renderable.enabled', not b)") +openspace.bindKey("e", "local b = openspace.getPropertyValue('EarthMarker.renderable.enabled'); openspace.setPropertyValue('EarthMarker.renderable.enabled', not b)") -openspace.bindKey("T", "openspace.distance(-interaction_speed * openspace.dt(), 6.0)") -openspace.bindKey("G", "openspace.distance(interaction_speed * openspace.dt(), 6.0)") -openspace.bindKey("Y", "openspace.distance(-interaction_speed * openspace.dt(), 10.0)") -openspace.bindKey("H", "openspace.distance(interaction_speed * openspace.dt(), 10.0)") -openspace.bindKey("U", "openspace.distance(-interaction_speed * openspace.dt(), 10.0)") -openspace.bindKey("J", "openspace.distance(interaction_speed * openspace.dt(), 10.0)") - -openspace.bindKey("PRINT_SCREEN", "openspace.takeScreenshot()") \ No newline at end of file +openspace.bindKey("PAUSE", "openspace.printInfo('F5: Toogle to Sun, F6: Toggle to Jupiter, F7: Toggle to Pluto'); openspace.printInfo('Bookmarks: 1: Jupter, 2-7: Pluto');") diff --git a/scripts/default_settings.lua b/scripts/default_settings.lua index 376feeb652..534a6507bb 100644 --- a/scripts/default_settings.lua +++ b/scripts/default_settings.lua @@ -1,7 +1,14 @@ -openspace.printInfo("Setting default values"); -openspace.setPropertyValue("Constellation Bounds.renderable.enabled", false); +--[[ OpenSpace settings script ]]-- +-- This Lua script get executed once at the start of the application and is used to +-- set settings in the loaded scene graph -openspace.setPropertyValue("MilkyWay.renderable.transparency", 0.75); -openspace.setPropertyValue("MilkyWay.renderable.segments", 50); +openspace.printInfo("Setting default values") +openspace.setPropertyValue("Sun.renderable.enabled", false) +openspace.setPropertyValue("SunMarker.renderable.enabled", false) +openspace.setPropertyValue("EarthMarker.renderable.enabled", false) +openspace.setPropertyValue("Constellation Bounds.renderable.enabled", false) -openspace.printInfo("Done setting default values"); \ No newline at end of file +openspace.setPropertyValue("MilkyWay.renderable.transparency", 0.75) +openspace.setPropertyValue("MilkyWay.renderable.segments", 50) + +openspace.printInfo("Done setting default values") diff --git a/scripts/default_startup.lua b/scripts/default_startup.lua index ee98add4b1..26a6c800db 100644 --- a/scripts/default_startup.lua +++ b/scripts/default_startup.lua @@ -1,6 +1,17 @@ -openspace.setInvertRoll(true); +--[[ OpenSpace startup script ]]-- +-- This Lua script get executed once at the start of the application + +--openspace.setInvertRotation(true) -- Uncomment this if you want to invert the rotation +openspace.setInvertRoll(true); +--openspace.setInteractionSensitivity(10) -- This is the default value for the sensitivity (the higher, the more sensitive) + +openspace.time.setTime("2007 FEB 27 16:40:00") -- This is the start time for a Jupiter run of New Horizons + + +openspace.time.setDeltaTime(10) -- How many seconds pass per second of realtime, changeable in the GUI + +dofile(openspace.absPath('${SCRIPTS}/bind_keys.lua')) -- Load the default keybindings -openspace.time.setTime("2007 FEB 27 16:41:00") -- openspace.time.setDeltaTime(50); --openspace.time.setTime("2015-07-14T10:50:00.00") -- PLUTO @@ -29,13 +40,4 @@ openspace.time.setTime("2007 FEB 27 16:41:00") -- until audience tires (enough to fill 10-15 mins if run at dt = 100) -openspace.time.setDeltaTime(10) -- print(openspace.time.currentTimeUTC()) - - - -function loadKeyBindings() - p = openspace.absPath('${SCRIPTS}/bind_keys.lua') - dofile(p) -end -loadKeyBindings() \ No newline at end of file diff --git a/src/engine/logfactory.cpp b/src/engine/logfactory.cpp index 61a8be3490..4f493a3363 100644 --- a/src/engine/logfactory.cpp +++ b/src/engine/logfactory.cpp @@ -75,11 +75,11 @@ ghoul::logging::Log* LogFactory::createLog(const ghoul::Dictionary& dictionary) if (type == valueHtmlLog) { return new ghoul::logging::HTMLLog( - filename, timeStamp, dateStamp, categoryStamp, logLevelStamp); + filename, append, timeStamp, dateStamp, categoryStamp, logLevelStamp); } else if (type == valueTextLog) { return new ghoul::logging::TextLog( - filename, timeStamp, dateStamp, categoryStamp, logLevelStamp); + filename, append, timeStamp, dateStamp, categoryStamp, logLevelStamp); } else { LERROR("Log with type '" << type << "' did not name a valid log"); diff --git a/src/gui/guipropertycomponent.cpp b/src/gui/guipropertycomponent.cpp index 8593089110..633a079544 100644 --- a/src/gui/guipropertycomponent.cpp +++ b/src/gui/guipropertycomponent.cpp @@ -148,7 +148,7 @@ namespace { Vec2Property::ValueType value = *p; - ImGui::SliderFloat2((ownerName + "." + name).c_str(), &value.x, p->minValue().x, p->maxValue().x); + ImGui::SliderFloat2((ownerName + "." + name).c_str(), &value.x, std::min(p->minValue().x, p->minValue().y), std::max(p->maxValue().x, p->maxValue().y)); if (value != p->value()) executeScript(p->fullyQualifiedIdentifier(), diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index 00c209deb4..9ac16253d6 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -905,7 +905,7 @@ void InteractionHandler::keyboardCallback(int key, int action) { Time::ref().advanceTime(sgct::Engine::instance()->getDt()); } if (key == SGCT_KEY_X) { - Time::ref().retreatTime(sgct::Engine::instance()->getDt()); + Time::ref().advanceTime(-sgct::Engine::instance()->getDt()); } if (key == 262) { glm::vec3 euler(0.0, speed * dt*0.4, 0.0); diff --git a/src/main.cpp b/src/main.cpp index 5906ce5dd0..d82e715002 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -239,12 +239,10 @@ void mainLogCallback(const char* msg){ void postFXPass(){ glUniform1i(_postFXTexLoc, 0); - if (OsEng.isMaster()){ - glUniform1f(_postFXOpacityLoc, 1.f); - } - else{ - glUniform1f(_postFXOpacityLoc, OsEng.ref().renderEngine()->globalOpacity()); - } + if (OsEng.isMaster()) + glUniform1f(_postFXOpacityLoc, 1.f); + else + glUniform1f(_postFXOpacityLoc, OsEng.ref().renderEngine()->globalBlackOutFactor()); } void setupPostFX(){ @@ -258,4 +256,4 @@ void setupPostFX(){ _postFXOpacityLoc = shader->getUniformLocation("Opacity"); shader->unbind(); _sgctEngine->addPostFX(fx[0]); -} \ No newline at end of file +} diff --git a/src/rendering/model/modelgeometry.cpp b/src/rendering/model/modelgeometry.cpp index 860c783517..6fb7946ec1 100644 --- a/src/rendering/model/modelgeometry.cpp +++ b/src/rendering/model/modelgeometry.cpp @@ -28,7 +28,9 @@ #include namespace { -const std::string _loggerCat = "ModelGeometry"; + const std::string _loggerCat = "ModelGeometry"; + + const std::string keyType = "Type"; } namespace openspace { @@ -38,10 +40,10 @@ ModelGeometry* ModelGeometry::createFromDictionary(const ghoul::Dictionary& dict { std::string geometryType; const bool success = dictionary.getValue( - constants::modelgeometry::keyType, geometryType); + keyType, geometryType); if (!success) { LERROR("ModelGeometry did not contain a correct value of the key '" - << constants::modelgeometry::keyType << "'"); + << keyType << "'"); return nullptr; } ghoul::TemplateFactory* factory diff --git a/src/rendering/model/renderablemodel.cpp b/src/rendering/model/renderablemodel.cpp index 665da118bd..fa1b7dabba 100644 --- a/src/rendering/model/renderablemodel.cpp +++ b/src/rendering/model/renderablemodel.cpp @@ -58,12 +58,14 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) , _performShading("performShading", "Perform Shading", true) { std::string name; + bool success = dictionary.getValue(constants::scenegraphnode::keyName, name); + ghoul_assert(success, "Name was not passed to RenderableModel"); std::string path; - dictionary.getValue(constants::scenegraphnode::keyName, name); - dictionary.getValue(constants::scenegraph::keyPathModule, path); + success = dictionary.getValue(constants::scenegraph::keyPathModule, path); + ghoul_assert(success, "Module path was not passed to RenderableModel"); ghoul::Dictionary geometryDictionary; - bool success = dictionary.getValue( + success = dictionary.getValue( constants::renderablemodel::keyGeometry, geometryDictionary); if (success) { geometryDictionary.setValue(constants::scenegraphnode::keyName, name); @@ -83,10 +85,8 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) dictionary.getValue(keySource, _source); dictionary.getValue(keyDestination, _destination); -} - -RenderableModel::~RenderableModel(){ + setBoundingSphere(pss(1.f, 9.f)); } bool RenderableModel::isReady() const { @@ -96,7 +96,7 @@ bool RenderableModel::isReady() const { return ready; } -bool RenderableModel::initialize(){ +bool RenderableModel::initialize() { bool completeSuccess = true; if (_programObject == nullptr) completeSuccess @@ -112,7 +112,7 @@ bool RenderableModel::initialize(){ return completeSuccess; } -bool RenderableModel::deinitialize(){ +bool RenderableModel::deinitialize() { if (_geometry) { _geometry->deinitialize(); delete _geometry; @@ -125,12 +125,9 @@ bool RenderableModel::deinitialize(){ return true; } -void RenderableModel::render(const RenderData& data) -{ - // activate shader +void RenderableModel::render(const RenderData& data) { _programObject->activate(); - // scale the planet to appropriate size since the planet is a unit sphere glm::mat4 transform = glm::mat4(1); glm::mat4 tmp = glm::mat4(1); @@ -142,16 +139,7 @@ void RenderableModel::render(const RenderData& data) transform *= tmp; - //glm::mat4 modelview = data.camera.viewMatrix()*data.camera.modelMatrix(); - //glm::vec3 camSpaceEye = (-(modelview*data.position.vec4())).xyz; - // setup the data to the shader -// _programObject->setUniform("camdir", camSpaceEye); - - psc sun_pos; - double lt; - openspace::SpiceManager::ref().getTargetPosition("SUN", _source, "GALACTIC", "NONE", _time, sun_pos, lt); - - _programObject->setUniform("sun_pos", sun_pos.vec3()); + _programObject->setUniform("sun_pos", _sunPosition.vec3()); _programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); _programObject->setUniform("ModelTransform", transform); setPscUniforms(_programObject, &data.camera, data.position); @@ -170,21 +158,16 @@ void RenderableModel::render(const RenderData& data) _programObject->deactivate(); } -void RenderableModel::update(const UpdateData& data){ -#ifndef NDEBUG - if (_source.empty() || _destination.empty()) - return; -#endif +void RenderableModel::update(const UpdateData& data) { // set spice-orientation in accordance to timestamp if (!_source.empty()) openspace::SpiceManager::ref().getPositionTransformMatrix(_source, _destination, data.time, _stateMatrix); - _time = data.time; - + double lt; + openspace::SpiceManager::ref().getTargetPosition("SUN", _source, "GALACTIC", "NONE", data.time, _sunPosition, lt); } -void RenderableModel::loadTexture() -{ +void RenderableModel::loadTexture() { delete _texture; _texture = nullptr; if (_colorTexturePath.value() != "") { diff --git a/src/rendering/model/wavefrontgeometry.cpp b/src/rendering/model/wavefrontgeometry.cpp index 51cef8261b..0ff1605507 100644 --- a/src/rendering/model/wavefrontgeometry.cpp +++ b/src/rendering/model/wavefrontgeometry.cpp @@ -25,13 +25,20 @@ #include #include +#include #include +#include "ghoul/logging/logmanager.h" #include - +#include +#include namespace { const std::string _loggerCat = "WavefrontGeometry"; + + const std::string keyObjFile = "ObjFile"; + + const int8_t CurrentCacheVersion = 3; } namespace openspace { @@ -39,170 +46,71 @@ namespace modelgeometry { WavefrontGeometry::WavefrontGeometry(const ghoul::Dictionary& dictionary) : ModelGeometry() - , _isize(0) - , _vsize(0) - , _varray(nullptr) - , _iarray(nullptr) - , _tarray(nullptr) { using constants::scenegraphnode::keyName; - // The name is passed down from the SceneGraphNode std::string name; bool success = dictionary.getValue(keyName, name); ghoul_assert(success, "Name tag was not present"); std::string file; - success = dictionary.getValue(constants::modelgeometry::keyObjFile, file); + success = dictionary.getValue(keyObjFile, file); if (!success) { - LERROR("SimpleSphereGeometry of '" << name << "' did not provide a key '" - << constants::modelgeometry::keyObjFile << "'"); + LERROR("WaveFrontGeometry of '" << name << "' did not provide a key '" + << keyObjFile << "'"); } - const std::string filename = FileSys.absolutePath(file); + file = FileSys.absolutePath(file); - if (FileSys.fileExists(filename)) - loadObj(filename.c_str()); + if (FileSys.fileExists(file, true)) + loadObj(file); else - LERROR("Could not load OBJ file '" << filename << "': File not found"); + LERROR("Could not load OBJ file '" << file << "': File not found"); } -void WavefrontGeometry::loadObj(const char *filename){ - // temporary - const char *mtl_basepat = filename; +bool WavefrontGeometry::loadObj(const std::string& filename){ + std::string cachedFile = ""; + FileSys.cacheManager()->getCachedFile(filename, cachedFile, true); + bool hasCachedFile = FileSys.fileExists(cachedFile); + if (hasCachedFile) { + LINFO("Cached file '" << cachedFile << "' used for Model file '" << filename << "'"); + + bool success = loadCachedFile(cachedFile); + if (success) + return true; + else + FileSys.cacheManager()->removeCacheFile(filename); + // Intentional fall-through to the 'else' computation to generate the cache + // file for the next run + } + else { + LINFO("Cache for Model'" << filename << "' not found"); + } LINFO("Loading OBJ file '" << filename << "'"); - std::string err = tinyobj::LoadObj(shapes, materials, filename, mtl_basepat); + bool success = loadModel(filename); + if (!success) + return false; - if (!err.empty()) { - LERROR(err); - return; - } + LINFO("Saving cache"); + success = saveCachedFile(cachedFile); - LINFO("Loaded Mesh"); - LINFO("Number of Shapes: " << shapes.size()); - LINFO("Number of Materials: " << materials.size()); - for (int i = 0; i < shapes.size(); ++i) { - LINFO("Shape #" << i << ": " << - "Indices (" << shapes[i].mesh.indices.size() << ") " << - "Positions (" << shapes[i].mesh.positions.size() << ") " << - "Texture (" << shapes[i].mesh.texcoords.size() << ") " << - "Normals (" << shapes[i].mesh.normals.size() << ")"); - } - - _isize = shapes[0].mesh.indices.size(); - _vsize = shapes[0].mesh.indices.size(); // shapes[0].mesh.positions.size() + shapes[0].mesh.positions.size() / 3; - _tsize = shapes[0].mesh.texcoords.size(); - - _varray = new Vertex[_vsize]; - _iarray = new int[_isize]; - - //copy indices - for (int f = 0; f < shapes[0].mesh.indices.size(); f++) { - _iarray[f] = f;// shapes[0].mesh.indices[f]; - } - - //shapes[0].mesh.texcoords.resize(2 * _isize); - int p = 0; - for (auto v : shapes[0].mesh.indices) { - _varray[p].location[0] = shapes[0].mesh.positions[3 * v + 0]; - _varray[p].location[1] = shapes[0].mesh.positions[3 * v + 1]; - _varray[p].location[2] = shapes[0].mesh.positions[3 * v + 2]; - _varray[p].location[3] = 5; - - _varray[p].normal[0] = shapes[0].mesh.normals[3 * v + 0]; - _varray[p].normal[1] = shapes[0].mesh.normals[3 * v + 1]; - _varray[p].normal[2] = shapes[0].mesh.normals[3 * v + 2]; - - // Only set the texture coordinates if they don't fall out of the value range - _varray[p].tex[0] = (2 * v + 0) < shapes[0].mesh.texcoords.size() ? shapes[0].mesh.texcoords[2 * v + 0] : 0.f; - _varray[p].tex[1] = (2 * v + 1) < shapes[0].mesh.texcoords.size() ? shapes[0].mesh.texcoords[2 * v + 1] : 0.f; - - p++; - } - p = 0; - - //if (shapes[0].mesh.texcoords.size() > 0) { - // for (int k = 0; k < shapes[0].mesh.texcoords.size(); ++k) { - - // } - //} - // - //if (shapes[0].mesh.texcoords.size() > 0) { - // for (size_t k = 0; k < shapes[0].mesh.indices.size() / 3; k++) { - // for (int j = 0; j < 3; j++) { - // int idx = shapes[0].mesh.indices[3 * k + j]; - - // _varray[p].tex[0] = shapes[0].mesh.texcoords[2 * idx + 0]; - // _varray[p].tex[1] = shapes[0].mesh.texcoords[2 * idx + 1]; - // p++; - // } - // } - //} - - - //testing with one triangle - works. - /* - _varray[0].location[0] = 0; - _varray[0].location[1] = 0; - _varray[0].location[2] = 0; - _varray[0].location[3] = 5; - - _varray[0].normal[0] = 1; - _varray[0].normal[1] = 1; - _varray[0].normal[2] = 1; - - _varray[0].tex[0] = 0; - _varray[0].tex[1] = 0; - - _varray[1].location[0] = 1; - _varray[1].location[1] = 0; - _varray[1].location[2] = 0; - _varray[1].location[3] = 5; - - _varray[1].normal[0] = 1; - _varray[1].normal[1] = 1; - _varray[1].normal[2] = 1; - - _varray[1].tex[0] = 1; - _varray[1].tex[1] = 0; - - _varray[2].location[0] = 0; - _varray[2].location[1] = 1; - _varray[2].location[2] = 0; - _varray[2].location[3] = 5; - - _varray[2].normal[0] = 1; - _varray[2].normal[1] = 1; - _varray[2].normal[2] = 1; - - _varray[2].tex[0] = 0; - _varray[2].tex[1] = 1; - - _vsize = 3; - _isize = 3; - - _iarray[0] = 0; - _iarray[1] = 1; - _iarray[2] = 2; - */ + return success; } - -WavefrontGeometry::~WavefrontGeometry(){ -} - -bool WavefrontGeometry::initialize(RenderableModel* parent){ +bool WavefrontGeometry::initialize(RenderableModel* parent) { bool success = ModelGeometry::initialize(parent); - createSphere(); + PowerScaledScalar ps = PowerScaledScalar(1.0, 0.0); // will set proper bounding soon. + _parent->setBoundingSphere(ps); - if (_isize == 0) return false; + if (_vertices.empty()) + return false; glGenVertexArrays(1, &_vaoID); - glGenBuffers(1, &_vBufferID); - glGenBuffers(1, &_iBufferID); + glGenBuffers(1, &_vbo); + glGenBuffers(1, &_ibo); glBindVertexArray(_vaoID); - glBindBuffer(GL_ARRAY_BUFFER, _vBufferID); - glBufferData(GL_ARRAY_BUFFER, _vsize * sizeof(Vertex), _varray, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, _vbo); + glBufferData(GL_ARRAY_BUFFER, _vertices.size() * sizeof(Vertex), _vertices.data(), GL_STATIC_DRAW); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); @@ -214,42 +122,144 @@ bool WavefrontGeometry::initialize(RenderableModel* parent){ glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast(offsetof(Vertex, normal))); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iBufferID); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, _isize * sizeof(int), _iarray, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, _indices.size() * sizeof(int), _indices.data(), GL_STATIC_DRAW); + glBindVertexArray(0); - GLint errorID = glGetError(); - if (errorID != GL_NO_ERROR) { - LERROR("OpenGL error: " << glewGetErrorString(errorID)); - return false; - } return success; } -void WavefrontGeometry::deinitialize(){ - if (_varray) - delete[] _varray; - if (_iarray) - delete[] _iarray; - - glDeleteBuffers(1, &_vBufferID); - glDeleteBuffers(1, &_iBufferID); +void WavefrontGeometry::deinitialize() { + glDeleteBuffers(1, &_vbo); glDeleteVertexArrays(1, &_vaoID); - + glDeleteBuffers(1, &_ibo); } -void WavefrontGeometry::render(){ - // render - glBindVertexArray(_vaoID); // select first VAO - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iBufferID); - glDrawElements(GL_TRIANGLES, _isize, GL_UNSIGNED_INT, 0); +void WavefrontGeometry::render() { + glBindVertexArray(_vaoID); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo); + glDrawElements(GL_TRIANGLES, _indices.size(), GL_UNSIGNED_INT, 0); glBindVertexArray(0); } -void WavefrontGeometry::createSphere(){ - // create the power scaled scalar - PowerScaledScalar ps = PowerScaledScalar(1.0, 0.0); // will set proper bounding soon. - _parent->setBoundingSphere(ps); +bool WavefrontGeometry::loadModel(const std::string& filename) { + std::vector shapes; + std::vector materials; + std::string err = tinyobj::LoadObj(shapes, materials, filename.c_str(), filename.c_str()); + + if (!err.empty()) { + LERROR(err); + return false; + } + + if (shapes.size() > 1) { + LWARNING("Loading models with more than one shape is currently untested"); + } + + int totalSizeIndex = 0; + int totalSizeVertex = 0; + for (int i = 0; i < shapes.size(); ++i) { + totalSizeIndex += shapes[i].mesh.indices.size(); + totalSizeVertex += shapes[i].mesh.positions.size(); + + if (shapes[i].mesh.positions.size() != shapes[i].mesh.normals.size()) + LERROR( + "#positions (" << shapes[i].mesh.positions.size() << ")" + " != #normals (" << shapes[i].mesh.normals.size() + ); + } + + _vertices.resize(totalSizeVertex); + std::memset(_vertices.data(), 0, _vertices.size() * sizeof(Vertex)); + _indices.resize(totalSizeIndex); + std::memset(_indices.data(), 0, _indices.size() * sizeof(int)); + + // We add all shapes of the model into the same vertex array, one after the other + // The _shapeCounts array stores for each shape, how many vertices that shape has + int currentPosition = 0; + int currentIndices = 0; + int p = 0; + for (int i = 0; i < shapes.size(); ++i) { + for (int j = 0; j < shapes[i].mesh.positions.size() / 3; ++j) { + _vertices[j + currentPosition].location[0] = shapes[i].mesh.positions[3 * j + 0]; + _vertices[j + currentPosition].location[1] = shapes[i].mesh.positions[3 * j + 1]; + _vertices[j + currentPosition].location[2] = shapes[i].mesh.positions[3 * j + 2]; + _vertices[j + currentPosition].location[3] = 5; + + _vertices[j + currentPosition].normal[0] = shapes[i].mesh.normals[3 * j + 0]; + _vertices[j + currentPosition].normal[1] = shapes[i].mesh.normals[3 * j + 1]; + _vertices[j + currentPosition].normal[2] = shapes[i].mesh.normals[3 * j + 2]; + + if (2 * j + 1 < shapes[i].mesh.texcoords.size()) { + _vertices[j + currentPosition].tex[0] = shapes[0].mesh.texcoords[2 * j + 0]; + _vertices[j + currentPosition].tex[1] = shapes[0].mesh.texcoords[2 * j + 1]; + } + + } + currentPosition += shapes[i].mesh.positions.size() / 3; + + std::copy( + shapes[i].mesh.indices.begin(), + shapes[i].mesh.indices.end(), + _indices.begin() + p + ); + p += shapes[i].mesh.indices.size(); + } + + return true; +} + +bool WavefrontGeometry::saveCachedFile(const std::string& filename) { + std::ofstream fileStream(filename, std::ofstream::binary); + if (fileStream.good()) { + fileStream.write(reinterpret_cast(&CurrentCacheVersion), + sizeof(int8_t)); + + int64_t vSize = _vertices.size(); + fileStream.write(reinterpret_cast(&vSize), sizeof(int64_t)); + int64_t iSize = _indices.size(); + fileStream.write(reinterpret_cast(&iSize), sizeof(int64_t)); + + fileStream.write(reinterpret_cast(_vertices.data()), sizeof(Vertex) * vSize); + fileStream.write(reinterpret_cast(_indices.data()), sizeof(int) * iSize); + + return fileStream.good(); + } + else { + LERROR("Error opening file '" << filename << "' for save cache file"); + return false; + } +} + +bool WavefrontGeometry::loadCachedFile(const std::string& filename) { + std::ifstream fileStream(filename, std::ifstream::binary); + if (fileStream.good()) { + int8_t version = 0; + fileStream.read(reinterpret_cast(&version), sizeof(int8_t)); + if (version != CurrentCacheVersion) { + LINFO("The format of the cached file has changed, deleting old cache"); + fileStream.close(); + FileSys.deleteFile(filename); + return false; + } + + int64_t vSize, iSize; + fileStream.read(reinterpret_cast(&vSize), sizeof(int64_t)); + fileStream.read(reinterpret_cast(&iSize), sizeof(int64_t)); + + _vertices.resize(vSize); + _indices.resize(iSize); + + fileStream.read(reinterpret_cast(_vertices.data()), sizeof(Vertex) * vSize); + fileStream.read(reinterpret_cast(_indices.data()), sizeof(int) * iSize); + + return fileStream.good(); + } + else { + LERROR("Error opening file '" << filename << "' for loading cache file"); + return false; + } } } // namespace modelgeometry diff --git a/src/rendering/renderablefov.cpp b/src/rendering/renderablefov.cpp index 3a828f1136..4950d13854 100644 --- a/src/rendering/renderablefov.cpp +++ b/src/rendering/renderablefov.cpp @@ -64,26 +64,26 @@ namespace openspace{ glm::vec4 col_gray; glm::vec4 col_start; - RenderableFov::RenderableFov(const ghoul::Dictionary& dictionary) - : Renderable(dictionary) - , _colorTexturePath("colorTexture", "Color Texture") - , _programObject(nullptr) - , _texture(nullptr) - , _mode(GL_LINES){ + RenderableFov::RenderableFov(const ghoul::Dictionary& dictionary) + : Renderable(dictionary) + , _lineWidth("lineWidth", "Line Width", 1.f, 1.f, 20.f) + , _programObject(nullptr) + , _texture(nullptr) + , _mode(GL_LINES){ - bool success = dictionary.getValue(keyBody , _spacecraft); + bool success = dictionary.getValue(keyBody, _spacecraft); ghoul_assert(success, ""); - success = dictionary.getValue(keyFrame , _frame); + success = dictionary.getValue(keyFrame, _frame); ghoul_assert(success, ""); - success = dictionary.getValue(keyInstrument , _instrumentID); + success = dictionary.getValue(keyInstrument, _instrumentID); ghoul_assert(success, ""); - success = dictionary.getValue(keyInstrumentMethod , _method); + success = dictionary.getValue(keyInstrumentMethod, _method); ghoul_assert(success, ""); - success = dictionary.getValue(keyInstrumentAberration , _aberrationCorrection); + success = dictionary.getValue(keyInstrumentAberration, _aberrationCorrection); ghoul_assert(success, ""); ghoul::Dictionary potentialTargets; @@ -96,6 +96,8 @@ namespace openspace{ potentialTargets.getValue(std::to_string(i + 1), target); _potentialTargets[i] = target; } + + addProperty(_lineWidth); } void RenderableFov::allocateData(){ @@ -148,8 +150,6 @@ bool RenderableFov::initialize(){ } bool RenderableFov::deinitialize(){ - delete _texture; - _texture = nullptr; return true; } @@ -529,7 +529,7 @@ void RenderableFov::render(const RenderData& data){ } _oldTime = _time; - glLineWidth(1.f); + glLineWidth(_lineWidth); glBindVertexArray(_vaoID[0]); glDrawArrays(_mode, 0, _vtotal[0]); glBindVertexArray(0); @@ -547,6 +547,7 @@ void RenderableFov::render(const RenderData& data){ glDrawArrays(GL_LINE_LOOP, 0, _vtotal[1]); glBindVertexArray(0); } + glLineWidth(1.f); /*glPointSize(5.f); glBindVertexArray(_vaoID2); @@ -563,17 +564,4 @@ void RenderableFov::update(const UpdateData& data){ openspace::SpiceManager::ref().getPositionTransformMatrix(_instrumentID, _frame, data.time, _stateMatrix); } -void RenderableFov::loadTexture() -{ - delete _texture; - _texture = nullptr; - if (_colorTexturePath.value() != "") { - _texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath)); - if (_texture) { - LDEBUG("Loaded texture from '" << absPath(_colorTexturePath) << "'"); - _texture->uploadTexture(); - } - } -} - } \ No newline at end of file diff --git a/src/rendering/renderableplane.cpp b/src/rendering/renderableplane.cpp index 356fec4200..d57d83f915 100644 --- a/src/rendering/renderableplane.cpp +++ b/src/rendering/renderableplane.cpp @@ -29,6 +29,8 @@ #include #include +#include +#include #include namespace { @@ -48,16 +50,18 @@ RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _texturePath("texture", "Texture") , _billboard("billboard", "Billboard", false) - , _size(glm::vec2(1,1)) + , _size("size", "Size", glm::vec2(1,1), glm::vec2(0.f), glm::vec2(1.f, 25.f)) , _origin(Origin::Center) , _shader(nullptr) , _programIsDirty(false) , _texture(nullptr) + , _textureIsDirty(false) , _quad(0) , _vertexPositionBuffer(0) { - - dictionary.getValue("Size", _size); + glm::vec2 size; + dictionary.getValue("Size", size); + _size = size; std::string origin; if (dictionary.getValue("Origin", origin)) { @@ -86,16 +90,25 @@ RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary) std::string texturePath = ""; bool success = dictionary.getValue("Texture", texturePath); - if (success) + if (success) { _texturePath = findPath(texturePath); + _textureFile = new ghoul::filesystem::File(_texturePath); + } + addProperty(_billboard); addProperty(_texturePath); - _texturePath.onChange(std::bind(&RenderablePlane::loadTexture, this)); + _texturePath.onChange(std::bind(&RenderablePlane::loadTexture, this)); + _textureFile->setCallback([&](const ghoul::filesystem::File&) { _textureIsDirty = true; }); - setBoundingSphere(_size); + addProperty(_size); + //_size.onChange(std::bind(&RenderablePlane::createPlane, this)); + _size.onChange([this](){ _planeIsDirty = true; }); + + setBoundingSphere(_size.value()); } RenderablePlane::~RenderablePlane() { + delete _textureFile; } bool RenderablePlane::isReady() const { @@ -108,31 +121,9 @@ bool RenderablePlane::isReady() const { } bool RenderablePlane::initialize() { - - // ============================ - // GEOMETRY (quad) - // ============================ - const GLfloat size = _size[0]; - const GLfloat w = _size[1]; - const GLfloat vertex_data[] = { // square of two triangles (sigh) - // x y z w s t - -size, -size, 0.0f, w, 0,1, - size, size, 0.0f, w, 1, 0, - -size, size, 0.0f, w, 0, 0, - -size, -size, 0.0f, w, 0, 1, - size, -size, 0.0f, w, 1, 1, - size, size, 0.0f, w, 1, 0, - }; - - glGenVertexArrays(1, &_quad); // generate array - glBindVertexArray(_quad); // bind array - glGenBuffers(1, &_vertexPositionBuffer); // generate buffer - glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer); // bind buffer - glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast(0)); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast(sizeof(GLfloat) * 4)); + glGenVertexArrays(1, &_quad); // generate array + glGenBuffers(1, &_vertexPositionBuffer); // generate buffer + createPlane(); // Plane program _shader = ghoul::opengl::ProgramObject::Build("Plane", @@ -152,8 +143,7 @@ bool RenderablePlane::deinitialize() { _quad = 0; glDeleteBuffers(1, &_vertexPositionBuffer); _vertexPositionBuffer = 0; - if(_texture) - delete _texture; + delete _texture; delete _shader; return true; } @@ -186,6 +176,14 @@ void RenderablePlane::update(const UpdateData& data) { _shader->rebuildFromFile(); _programIsDirty = false; } + + if (_planeIsDirty) + createPlane(); + + if (_textureIsDirty) { + loadTexture(); + _textureIsDirty = false; + } } void RenderablePlane::loadTexture() { @@ -203,8 +201,37 @@ void RenderablePlane::loadTexture() { if (_texture) delete _texture; _texture = texture; + + delete _textureFile; + _textureFile = new ghoul::filesystem::File(_texturePath); + _textureFile->setCallback([&](const ghoul::filesystem::File&) { _textureIsDirty = true; }); } } } +void RenderablePlane::createPlane() { + // ============================ + // GEOMETRY (quad) + // ============================ + const GLfloat size = _size.value()[0]; + const GLfloat w = _size.value()[1]; + const GLfloat vertex_data[] = { // square of two triangles (sigh) + // x y z w s t + -size, -size, 0.0f, w, 0, 1, + size, size, 0.0f, w, 1, 0, + -size, size, 0.0f, w, 0, 0, + -size, -size, 0.0f, w, 0, 1, + size, -size, 0.0f, w, 1, 1, + size, size, 0.0f, w, 1, 0, + }; + + glBindVertexArray(_quad); // bind array + glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer); // bind buffer + glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast(0)); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast(sizeof(GLfloat) * 4)); +} + } // namespace openspace diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 2fb9a1c8ed..f2dce43f09 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -222,7 +222,7 @@ namespace openspace { , _performanceMemory(nullptr) , _visualizeABuffer(false) , _visualizer(nullptr) - , _globalOpactity(1.f) + , _globalBlackOutFactor(0.f) , _fadeDuration(2.f) , _currentFadeTime(0.f) , _fadeDirection(0) @@ -384,15 +384,15 @@ namespace openspace { if (_fadeDirection != 0){ if (_currentFadeTime > _fadeDuration){ _fadeDirection = 0; - _globalOpactity = fminf(1.f, fmaxf(0.f, _globalOpactity)); + _globalBlackOutFactor = fminf(1.f, fmaxf(0.f, _globalBlackOutFactor)); } else{ if (_fadeDirection < 0){ - _globalOpactity = glm::smoothstep(1.f, 0.f, _currentFadeTime / _fadeDuration); + _globalBlackOutFactor = glm::smoothstep(1.f, 0.f, _currentFadeTime / _fadeDuration); } else{ - _globalOpactity = glm::smoothstep(0.f, 1.f, _currentFadeTime / _fadeDuration); + _globalBlackOutFactor = glm::smoothstep(0.f, 1.f, _currentFadeTime / _fadeDuration); } _currentFadeTime += static_cast(sgct::Engine::instance()->getAvgDt()); } @@ -690,12 +690,12 @@ namespace openspace { return _abuffer; } - float RenderEngine::globalOpacity(){ - return _globalOpactity; + float RenderEngine::globalBlackOutFactor(){ + return _globalBlackOutFactor; } - void RenderEngine::setGlobalOpacity(float opacity){ - _globalOpactity = opacity; + void RenderEngine::setGlobalBlackOutFactor(float opacity){ + _globalBlackOutFactor = opacity; } void RenderEngine::startFading(int direction, float fadeDuration){ @@ -888,7 +888,7 @@ void RenderEngine::changeViewPoint(std::string origin) { SceneGraphNode* newHorizonsNode = sceneGraph()->sceneGraphNode("NewHorizons"); SceneGraphNode* jupiterBarycenterNode = sceneGraph()->sceneGraphNode("JupiterBarycenter"); - if (solarSystemBarycenterNode == nullptr || plutoBarycenterNode == nullptr || newHorizonsNode == nullptr) { + if (solarSystemBarycenterNode == nullptr || plutoBarycenterNode == nullptr || newHorizonsNode == nullptr || jupiterBarycenterNode == nullptr) { LERROR("WTF"); return; } @@ -991,6 +991,7 @@ void RenderEngine::changeViewPoint(std::string origin) { { std::string("Kernels"), ghoul::Dictionary() } }; newHorizonsNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary)); + return; } ghoul_assert(false, "This function is being misused"); diff --git a/src/rendering/stars/renderablestars.cpp b/src/rendering/stars/renderablestars.cpp index 119bff6852..d607724816 100644 --- a/src/rendering/stars/renderablestars.cpp +++ b/src/rendering/stars/renderablestars.cpp @@ -441,7 +441,7 @@ bool RenderableStars::loadCachedFile(const std::string& file) { int8_t version = 0; fileStream.read(reinterpret_cast(&version), sizeof(int8_t)); if (version != CurrentCacheVersion) { - LINFO("The format of the cached file has changed, deleted old cache"); + LINFO("The format of the cached file has changed, deleting old cache"); fileStream.close(); FileSys.deleteFile(file); return false; diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index 12ec56f69b..dbf903e2ca 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -436,7 +436,7 @@ bool SceneGraph::loadSceneInternal(const std::string& sceneDescriptionFilePath) cameraPosition += psc(glm::vec4(0.f, 0.f, boundf)); //why this line? (JK) - cameraPosition = psc(glm::vec4(0.f, 0.f, 1.f, 0.f)); + //cameraPosition = psc(glm::vec4(0.f, 0.f, 1.f, 0.f)); //c->setPosition(cameraPosition); // c->setCameraDirection(glm::vec3(0, 0, -1)); diff --git a/src/scripting/scriptengine.cpp b/src/scripting/scriptengine.cpp index 5ba590cfd4..771b00670a 100644 --- a/src/scripting/scriptengine.cpp +++ b/src/scripting/scriptengine.cpp @@ -324,17 +324,16 @@ bool ScriptEngine::hasLibrary(const std::string& name) //return false; } -bool ScriptEngine::isLibraryNameAllowed(const std::string& name) -{ +bool ScriptEngine::isLibraryNameAllowed(lua_State* state, const std::string& name) { bool result = false; - lua_getglobal(_state, _openspaceLibraryName.c_str()); - const bool hasOpenSpaceLibrary = lua_istable(_state, -1); + lua_getglobal(state, _openspaceLibraryName.c_str()); + const bool hasOpenSpaceLibrary = lua_istable(state, -1); if (!hasOpenSpaceLibrary) { LFATAL("OpenSpace library was not created in initialize method"); return false; } - lua_getfield(_state, -1, name.c_str()); - const int type = lua_type(_state, -1); + lua_getfield(state, -1, name.c_str()); + const int type = lua_type(state, -1); switch (type) { case LUA_TNONE: case LUA_TNIL: @@ -370,7 +369,7 @@ bool ScriptEngine::isLibraryNameAllowed(const std::string& name) break; } - lua_pop(_state, 2); + lua_pop(state, 2); return result; } @@ -496,7 +495,7 @@ bool ScriptEngine::registerLuaLibrary(lua_State* state, const LuaLibrary& librar //ghoul::lua::logStack(_state); } else { - const bool allowed = isLibraryNameAllowed(library.name); + const bool allowed = isLibraryNameAllowed(state, library.name); if (!allowed) return false; diff --git a/src/util/time.cpp b/src/util/time.cpp index f568680c6c..3a002a308e 100644 --- a/src/util/time.cpp +++ b/src/util/time.cpp @@ -80,6 +80,32 @@ int time_deltaTime(lua_State* L) { return 1; } +/** + * \ingroup LuaScripts + * togglePause(): + * Toggles a pause functionm i.e. setting the delta time to 0 and restoring it afterwards + */ +int time_togglePause(lua_State* L) { + openspace::Time::ref().togglePause(); + return 0; +} + +/** + * \ingroup LuaScripts + * togglePause(): + * Toggles a pause functionm i.e. setting the delta time to 0 and restoring it afterwards + */ +int time_setPause(lua_State* L) { + int nArguments = lua_gettop(L); + if (nArguments != 1) + return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); + + bool pause = lua_toboolean(L, -1); + openspace::Time::ref().setPause(pause); + return 0; +} + + /** * \ingroup LuaScripts * setTime({number, string}): @@ -149,6 +175,7 @@ Time::Time() : _time(-1.0) , _dt(1.0) , _timeJumped(false) + , _timePaused(false) , _syncedTime(-1.0) , _syncedDt(1.0) , _syncedTimeJumped(false) @@ -192,11 +219,10 @@ double Time::currentTime() const { } double Time::advanceTime(double tickTime) { - return _time += _dt * tickTime; -} - -double Time::retreatTime(double tickTime) { - return _time -= _dt * tickTime; + if (_timePaused) + return _time; + else + return _time += _dt * tickTime; } void Time::setDeltaTime(double deltaT) { @@ -208,11 +234,18 @@ double Time::deltaTime() const { return _syncedDt; } +void Time::setPause(bool pause) { + _timePaused = pause; +} + +bool Time::togglePause() { + _timePaused = !_timePaused; + return _timePaused; +} + void Time::setTime(std::string time) { SpiceManager::ref().getETfromDate(std::move(time), _time); _timeJumped = true; - // Add callback to OpenSpaceEngine that signals that the next update phase - // needs total invalidation ---abock } std::string Time::currentTimeUTC() const { @@ -298,6 +331,19 @@ scripting::ScriptEngine::LuaLibrary Time::luaLibrary() { "Returns the amount of simulated time that passes in one " "second of real time" }, + { + "setPause", + &luascriptfunctions::time_setPause, + "bool", + "Pauses the simulation time or restores the delta time" + }, + { + "togglePause", + &luascriptfunctions::time_togglePause, + "", + "Toggles the pause function, i.e. temporarily setting the delta time to 0" + " and restoring it afterwards" + }, { "setTime", &luascriptfunctions::time_setTime,