mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-04 09:59:44 -05:00
Merge branch 'master' into feature/FastVolume
This commit is contained in:
@@ -44,6 +44,7 @@ set(OPENSPACE_SOURCE
|
||||
${OPENSPACE_BASE_DIR}/src/engine/syncengine.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/engine/virtualpropertymanager.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/camerainteractionstates.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/interactionmonitor.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/inputstate.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/joystickinputstate.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/joystickcamerastates.cpp
|
||||
@@ -228,6 +229,7 @@ set(OPENSPACE_HEADER
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/delayedvariable.inl
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/camerainteractionstates.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/inputstate.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/interactionmonitor.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/interpolator.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/interpolator.inl
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/joystickinputstate.h
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <openspace/engine/syncengine.h>
|
||||
#include <openspace/engine/virtualpropertymanager.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/interaction/interactionmonitor.h>
|
||||
#include <openspace/interaction/keybindingmanager.h>
|
||||
#include <openspace/interaction/joystickinputstate.h>
|
||||
#include <openspace/interaction/websocketinputstate.h>
|
||||
@@ -150,6 +151,11 @@ configuration::Configuration& gConfiguration() {
|
||||
return g;
|
||||
}
|
||||
|
||||
interaction::InteractionMonitor& gInteractionMonitor() {
|
||||
static interaction::InteractionMonitor g;
|
||||
return g;
|
||||
}
|
||||
|
||||
interaction::JoystickInputStates& gJoystickInputStates() {
|
||||
static interaction::JoystickInputStates g;
|
||||
return g;
|
||||
@@ -214,6 +220,7 @@ void initialize() {
|
||||
global::navigationHandler.setPropertyOwner(&global::rootPropertyOwner);
|
||||
// New property subowners also have to be added to the ImGuiModule callback!
|
||||
global::rootPropertyOwner.addPropertySubOwner(global::navigationHandler);
|
||||
global::rootPropertyOwner.addPropertySubOwner(global::interactionMonitor);
|
||||
global::rootPropertyOwner.addPropertySubOwner(global::sessionRecording);
|
||||
global::rootPropertyOwner.addPropertySubOwner(global::timeManager);
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <openspace/engine/syncengine.h>
|
||||
#include <openspace/engine/virtualpropertymanager.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/interaction/interactionmonitor.h>
|
||||
#include <openspace/interaction/keybindingmanager.h>
|
||||
#include <openspace/interaction/sessionrecording.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
@@ -1030,6 +1031,7 @@ void OpenSpaceEngine::preSynchronization() {
|
||||
}
|
||||
global::sessionRecording.preSynchronization();
|
||||
global::parallelPeer.preSynchronization();
|
||||
global::interactionMonitor.updateActivityState();
|
||||
}
|
||||
|
||||
for (const std::function<void()>& func : global::callback::preSync) {
|
||||
@@ -1218,6 +1220,7 @@ void OpenSpaceEngine::keyboardCallback(Key key, KeyModifier mod, KeyAction actio
|
||||
|
||||
global::navigationHandler.keyboardCallback(key, mod, action);
|
||||
global::keybindingManager.keyboardCallback(key, mod, action);
|
||||
global::interactionMonitor.markInteraction();
|
||||
}
|
||||
|
||||
void OpenSpaceEngine::charCallback(unsigned int codepoint, KeyModifier modifier) {
|
||||
@@ -1230,6 +1233,7 @@ void OpenSpaceEngine::charCallback(unsigned int codepoint, KeyModifier modifier)
|
||||
}
|
||||
|
||||
global::luaConsole.charCallback(codepoint, modifier);
|
||||
global::interactionMonitor.markInteraction();
|
||||
}
|
||||
|
||||
void OpenSpaceEngine::mouseButtonCallback(MouseButton button,
|
||||
@@ -1265,6 +1269,7 @@ void OpenSpaceEngine::mouseButtonCallback(MouseButton button,
|
||||
}
|
||||
|
||||
global::navigationHandler.mouseButtonCallback(button, action);
|
||||
global::interactionMonitor.markInteraction();
|
||||
}
|
||||
|
||||
void OpenSpaceEngine::mousePositionCallback(double x, double y) {
|
||||
@@ -1274,6 +1279,7 @@ void OpenSpaceEngine::mousePositionCallback(double x, double y) {
|
||||
}
|
||||
|
||||
global::navigationHandler.mousePositionCallback(x, y);
|
||||
global::interactionMonitor.markInteraction();
|
||||
}
|
||||
|
||||
void OpenSpaceEngine::mouseScrollWheelCallback(double posX, double posY) {
|
||||
@@ -1286,6 +1292,7 @@ void OpenSpaceEngine::mouseScrollWheelCallback(double posX, double posY) {
|
||||
}
|
||||
|
||||
global::navigationHandler.mouseScrollWheelCallback(posY);
|
||||
global::interactionMonitor.markInteraction();
|
||||
}
|
||||
|
||||
std::vector<char> OpenSpaceEngine::encode() {
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2019 *
|
||||
* *
|
||||
* 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 *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/interaction/interactionmonitor.h>
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "InteractionMonitor";
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo IdleTimeInfo = {
|
||||
"IdleTime",
|
||||
"Idle Time",
|
||||
"Time in seconds that has passed from latest registered interaction until the "
|
||||
"application goes idle."
|
||||
};
|
||||
constexpr openspace::properties::Property::PropertyInfo IsInActiveStateInfo = {
|
||||
"IsInActiveState",
|
||||
"Is State Active",
|
||||
"Keeps track whether the interaction session is in active state or not. False if "
|
||||
"application is in idle state, true if it is in active state."
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
InteractionMonitor::InteractionMonitor()
|
||||
: properties::PropertyOwner({ "InteractionMonitor" })
|
||||
, _isInActiveState(IsInActiveStateInfo, false)
|
||||
, _idleTime(IdleTimeInfo, 120.f)
|
||||
{
|
||||
addProperty(_isInActiveState);
|
||||
addProperty(_idleTime);
|
||||
}
|
||||
|
||||
void InteractionMonitor::setActivityState(bool isActive) {
|
||||
_isInActiveState = isActive;
|
||||
}
|
||||
|
||||
void InteractionMonitor::setIdleTime(float time) {
|
||||
_idleTime = time;
|
||||
}
|
||||
|
||||
void InteractionMonitor::updateActivityState() {
|
||||
const double currentApplicationTime = global::windowDelegate.applicationTime();
|
||||
const double timeDiff = currentApplicationTime - _lastInteractionTime;
|
||||
|
||||
if (timeDiff >= _idleTime && _isInActiveState) {
|
||||
_isInActiveState = false;
|
||||
}
|
||||
}
|
||||
|
||||
void InteractionMonitor::markInteraction() {
|
||||
_lastInteractionTime = global::windowDelegate.applicationTime();
|
||||
_isInActiveState = true;
|
||||
}
|
||||
|
||||
} // namespace openspace::interaction
|
||||
@@ -337,6 +337,18 @@ void NavigationHandler::keyboardCallback(Key key, KeyModifier modifier, KeyActio
|
||||
_inputState.keyboardCallback(key, modifier, action);
|
||||
}
|
||||
|
||||
NavigationHandler::NavigationState NavigationHandler::navigationState() const {
|
||||
const SceneGraphNode* referenceFrame = _orbitalNavigator.followingAnchorRotation() ?
|
||||
_orbitalNavigator.anchorNode() :
|
||||
sceneGraph()->root();
|
||||
ghoul_assert(
|
||||
referenceFrame,
|
||||
"The root will always exist and the anchor node ought to be reset when removed"
|
||||
);
|
||||
|
||||
return navigationState(*referenceFrame);
|
||||
}
|
||||
|
||||
NavigationHandler::NavigationState NavigationHandler::navigationState(
|
||||
const SceneGraphNode& referenceFrame) const
|
||||
{
|
||||
@@ -383,12 +395,9 @@ NavigationHandler::NavigationState NavigationHandler::navigationState(
|
||||
void NavigationHandler::saveNavigationState(const std::string& filepath,
|
||||
const std::string& referenceFrameIdentifier)
|
||||
{
|
||||
const SceneGraphNode* referenceFrame = _orbitalNavigator.followingAnchorRotation() ?
|
||||
_orbitalNavigator.anchorNode() :
|
||||
sceneGraph()->root();
|
||||
|
||||
NavigationHandler::NavigationState state;
|
||||
if (!referenceFrameIdentifier.empty()) {
|
||||
referenceFrame = sceneGraphNode(referenceFrameIdentifier);
|
||||
const SceneGraphNode* referenceFrame = sceneGraphNode(referenceFrameIdentifier);
|
||||
if (!referenceFrame) {
|
||||
LERROR(fmt::format(
|
||||
"Could not find node '{}' to use as reference frame",
|
||||
@@ -396,17 +405,18 @@ void NavigationHandler::saveNavigationState(const std::string& filepath,
|
||||
));
|
||||
return;
|
||||
}
|
||||
state = navigationState(*referenceFrame).dictionary();
|
||||
} else {
|
||||
state = navigationState().dictionary();
|
||||
}
|
||||
|
||||
if (!filepath.empty()) {
|
||||
std::string absolutePath = absPath(filepath);
|
||||
LINFO(fmt::format("Saving camera position: {}", absolutePath));
|
||||
|
||||
ghoul::Dictionary cameraDict = navigationState(*referenceFrame).dictionary();
|
||||
ghoul::DictionaryLuaFormatter formatter;
|
||||
|
||||
std::ofstream ofs(absolutePath.c_str());
|
||||
ofs << "return " << formatter.format(cameraDict);
|
||||
ofs << "return " << formatter.format(state.dictionary());
|
||||
ofs.close();
|
||||
}
|
||||
}
|
||||
@@ -558,13 +568,24 @@ scripting::LuaLibrary NavigationHandler::luaLibrary() {
|
||||
return {
|
||||
"navigation",
|
||||
{
|
||||
{
|
||||
"getNavigationState",
|
||||
&luascriptfunctions::getNavigationState,
|
||||
{},
|
||||
"[string]",
|
||||
"Return the current navigation state as a lua table. The optional "
|
||||
"argument is the scene graph node to use as reference frame. By default, "
|
||||
"the reference frame will picked based on whether the orbital navigator "
|
||||
"is currently following the anchor node rotation. If it is, the anchor "
|
||||
"will be chosen as reference frame. If not, the reference frame will be "
|
||||
"set to the scene graph root."
|
||||
},
|
||||
{
|
||||
"setNavigationState",
|
||||
&luascriptfunctions::setNavigationState,
|
||||
{},
|
||||
"table",
|
||||
"Set the navigation state. "
|
||||
"The argument must be a valid Navigation State."
|
||||
"Set the navigation state. The argument must be a valid Navigation State."
|
||||
},
|
||||
{
|
||||
"saveNavigationState",
|
||||
@@ -642,7 +663,7 @@ scripting::LuaLibrary NavigationHandler::luaLibrary() {
|
||||
"locally or remotely. The latter being the default."
|
||||
},
|
||||
{
|
||||
"clearJoystickButotn",
|
||||
"clearJoystickButton",
|
||||
&luascriptfunctions::clearJoystickButton,
|
||||
{},
|
||||
"int",
|
||||
|
||||
@@ -46,6 +46,77 @@ int loadNavigationState(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getNavigationState(lua_State* L) {
|
||||
const int n = ghoul::lua::checkArgumentsAndThrow(
|
||||
L,
|
||||
{ 0, 1 },
|
||||
"lua::getNavigationState"
|
||||
);
|
||||
|
||||
interaction::NavigationHandler::NavigationState state;
|
||||
if (n == 1) {
|
||||
const std::string referenceFrameIdentifier = ghoul::lua::value<std::string>(L, 1);
|
||||
const SceneGraphNode* referenceFrame = sceneGraphNode(referenceFrameIdentifier);
|
||||
if (!referenceFrame) {
|
||||
LERROR(fmt::format(
|
||||
"Could not find node '{}' to use as reference frame",
|
||||
referenceFrameIdentifier
|
||||
));
|
||||
lua_settop(L, 0);
|
||||
return 0;
|
||||
}
|
||||
state = global::navigationHandler.navigationState(*referenceFrame);
|
||||
}
|
||||
else {
|
||||
state = global::navigationHandler.navigationState();
|
||||
}
|
||||
|
||||
lua_settop(L, 0);
|
||||
|
||||
const auto pushVector = [](lua_State* L, const glm::dvec3& v) {
|
||||
lua_newtable(L);
|
||||
ghoul::lua::push(L, 1, v.x);
|
||||
lua_rawset(L, -3);
|
||||
ghoul::lua::push(L, 2, v.y);
|
||||
lua_rawset(L, -3);
|
||||
ghoul::lua::push(L, 3, v.z);
|
||||
lua_rawset(L, -3);
|
||||
};
|
||||
|
||||
lua_newtable(L);
|
||||
ghoul::lua::push(L, "Anchor", state.anchor);
|
||||
lua_rawset(L, -3);
|
||||
|
||||
if (!state.aim.empty()) {
|
||||
ghoul::lua::push(L, "Aim", state.aim);
|
||||
lua_rawset(L, -3);
|
||||
}
|
||||
if (!state.referenceFrame.empty()) {
|
||||
ghoul::lua::push(L, "ReferenceFrame", state.referenceFrame);
|
||||
lua_rawset(L, -3);
|
||||
}
|
||||
ghoul::lua::push(L, "Position");
|
||||
pushVector(L, state.position);
|
||||
lua_rawset(L, -3);
|
||||
|
||||
if (state.up.has_value()) {
|
||||
ghoul::lua::push(L, "Up");
|
||||
pushVector(L, state.up.value());
|
||||
lua_rawset(L, -3);
|
||||
}
|
||||
if (state.yaw != 0) {
|
||||
ghoul::lua::push(L, "Yaw", state.yaw);
|
||||
lua_rawset(L, -3);
|
||||
}
|
||||
if (state.pitch != 0) {
|
||||
ghoul::lua::push(L, "Pitch", state.pitch);
|
||||
lua_rawset(L, -3);
|
||||
}
|
||||
|
||||
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int setNavigationState(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::setNavigationState");
|
||||
|
||||
|
||||
@@ -1033,7 +1033,7 @@ void SessionRecording::moveAheadInTime() {
|
||||
const Renderable* focusRenderable = focusNode->renderable();
|
||||
if (!focusRenderable || focusRenderable->renderedWithDesiredData()) {
|
||||
_saveRenderingCurrentRecordedTime += _saveRenderingDeltaTime;
|
||||
global::renderEngine.takeScreenShot();
|
||||
global::renderEngine.takeScreenshot();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -439,10 +439,16 @@ void FramebufferRenderer::applyTMO(float blackoutFactor) {
|
||||
_hdrFilteringProgram->setUniform(_hdrUniformCache.Saturation, _saturation);
|
||||
_hdrFilteringProgram->setUniform(_hdrUniformCache.Value, _value);
|
||||
|
||||
glDepthMask(false);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glBindVertexArray(_screenQuad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glBindVertexArray(0);
|
||||
|
||||
glDepthMask(true);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
_hdrFilteringProgram->deactivate();
|
||||
}
|
||||
|
||||
@@ -473,10 +479,16 @@ void FramebufferRenderer::applyFXAA() {
|
||||
glm::vec2 inverseScreenSize(1.f/_resolution.x, 1.f/_resolution.y);
|
||||
_fxaaProgram->setUniform(_fxaaUniformCache.inverseScreenSize, inverseScreenSize);
|
||||
|
||||
glDepthMask(false);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glBindVertexArray(_screenQuad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glBindVertexArray(0);
|
||||
|
||||
glDepthMask(true);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
_fxaaProgram->deactivate();
|
||||
}
|
||||
|
||||
@@ -760,7 +772,7 @@ void FramebufferRenderer::updateResolution() {
|
||||
_resolution.y,
|
||||
0,
|
||||
GL_RGBA,
|
||||
GL_BYTE,
|
||||
GL_UNSIGNED_BYTE,
|
||||
nullptr
|
||||
);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
@@ -1049,7 +1061,7 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac
|
||||
if (doPerformanceMeasurements) {
|
||||
perfInternal = std::make_unique<performance::PerformanceMeasurement>(
|
||||
"FramebufferRenderer::render::deferredTasks"
|
||||
);
|
||||
);
|
||||
}
|
||||
performDeferredTasks(tasks.deferredcasterTasks);
|
||||
}
|
||||
@@ -1067,6 +1079,8 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac
|
||||
|
||||
if (_enableFXAA) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _fxaaBuffers.fxaaFramebuffer);
|
||||
glDrawBuffers(1, ColorAttachment0Array);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
else {
|
||||
// When applying the TMO, the result is saved to the default FBO to be displayed
|
||||
|
||||
@@ -124,16 +124,6 @@ namespace {
|
||||
"shown on the screen"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo TakeScreenshotInfo = {
|
||||
"TakeScreenshot",
|
||||
"Take Screenshot",
|
||||
"If this property is triggered, a screenshot is taken and stored in the current "
|
||||
"working directory (which is the same directory where the OpenSpace.exe) is "
|
||||
"located in most cases. The images are prefixed with 'SGCT' and postfixed with "
|
||||
"the number of frames. This function will silently overwrite images that are "
|
||||
"already present in the folder."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo ApplyWarpingInfo = {
|
||||
"ApplyWarpingScreenshot",
|
||||
"Apply Warping to Screenshots",
|
||||
@@ -264,7 +254,6 @@ RenderEngine::RenderEngine()
|
||||
, _showLog(ShowLogInfo, true)
|
||||
, _showVersionInfo(ShowVersionInfo, true)
|
||||
, _showCameraInfo(ShowCameraInfo, true)
|
||||
, _takeScreenshot(TakeScreenshotInfo)
|
||||
, _applyWarping(ApplyWarpingInfo, false)
|
||||
, _showFrameInformation(ShowFrameNumberInfo, false)
|
||||
#ifdef OPENSPACE_WITH_INSTRUMENTATION
|
||||
@@ -379,9 +368,6 @@ RenderEngine::RenderEngine()
|
||||
});
|
||||
addProperty(_horizFieldOfView);
|
||||
|
||||
_takeScreenshot.onChange([this](){ _shouldTakeScreenshot = true; });
|
||||
addProperty(_takeScreenshot);
|
||||
|
||||
addProperty(_showFrameInformation);
|
||||
#ifdef OPENSPACE_WITH_INSTRUMENTATION
|
||||
_saveFrameInformation.onChange([&]() {
|
||||
@@ -864,21 +850,6 @@ void RenderEngine::renderDashboard() {
|
||||
void RenderEngine::postDraw() {
|
||||
++_frameNumber;
|
||||
|
||||
if (_shouldTakeScreenshot) {
|
||||
// We only create the directory here, as we don't want to spam the users
|
||||
// screenshot folder everytime we start OpenSpace even when we are not taking any
|
||||
// screenshots. So the first time we actually take one, we create the folder:
|
||||
if (!FileSys.directoryExists(absPath("${SCREENSHOTS}"))) {
|
||||
FileSys.createDirectory(
|
||||
absPath("${SCREENSHOTS}"),
|
||||
ghoul::filesystem::FileSystem::Recursive::Yes
|
||||
);
|
||||
}
|
||||
|
||||
global::windowDelegate.takeScreenshot(_applyWarping);
|
||||
_shouldTakeScreenshot = false;
|
||||
}
|
||||
|
||||
if (global::performanceManager.isEnabled()) {
|
||||
global::performanceManager.storeScenePerformanceMeasurements(
|
||||
scene()->allSceneGraphNodes()
|
||||
@@ -1061,10 +1032,28 @@ void RenderEngine::setResolveData(ghoul::Dictionary resolveData) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark that one screenshot should be taken
|
||||
*/
|
||||
void RenderEngine::takeScreenShot() {
|
||||
_shouldTakeScreenshot = true;
|
||||
* Take a screenshot and store it in the ${SCREENSHOTS} directory
|
||||
*/
|
||||
void RenderEngine::takeScreenshot() {
|
||||
// We only create the directory here, as we don't want to spam the users
|
||||
// screenshot folder everytime we start OpenSpace even when we are not taking any
|
||||
// screenshots. So the first time we actually take one, we create the folder:
|
||||
|
||||
if (!FileSys.directoryExists(absPath("${SCREENSHOTS}"))) {
|
||||
FileSys.createDirectory(
|
||||
absPath("${SCREENSHOTS}"),
|
||||
ghoul::filesystem::FileSystem::Recursive::Yes
|
||||
);
|
||||
}
|
||||
|
||||
_latestScreenshotNumber = global::windowDelegate.takeScreenshot(_applyWarping);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the latest screenshot filename
|
||||
*/
|
||||
unsigned int RenderEngine::latestScreenshotNumber() const {
|
||||
return _latestScreenshotNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1123,6 +1112,14 @@ scripting::LuaLibrary RenderEngine::luaLibrary() {
|
||||
"Given a ScreenSpaceRenderable name this script will remove it from the "
|
||||
"renderengine"
|
||||
},
|
||||
{
|
||||
"takeScreenshot",
|
||||
&luascriptfunctions::takeScreenshot,
|
||||
{},
|
||||
"",
|
||||
"Take a screenshot and return the screenshot number. The screenshot will "
|
||||
"be stored in the ${SCREENSHOTS} folder. "
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -89,4 +89,14 @@ int removeScreenSpaceRenderable(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int takeScreenshot(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::takeScreenshot");
|
||||
|
||||
global::renderEngine.takeScreenshot();
|
||||
const unsigned int screenshotNumber = global::renderEngine.latestScreenshotNumber();
|
||||
|
||||
lua_pushinteger(L, screenshotNumber);
|
||||
return 1;
|
||||
}
|
||||
|
||||
}// namespace openspace::luascriptfunctions
|
||||
|
||||
Reference in New Issue
Block a user