Address comments on PR

This commit is contained in:
Ylva Selling
2023-04-14 16:29:42 -04:00
parent f77a028153
commit 5789d86dab
28 changed files with 167 additions and 567 deletions

View File

@@ -1,26 +1,26 @@
# #########################################################################################
# #
##########################################################################################
# #
# OpenSpace #
# #
# #
# Copyright (c) 2014-2023 #
# #
# #
# 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(${PROJECT_SOURCE_DIR}/support/cmake/module_definition.cmake)
@@ -149,16 +149,16 @@ target_precompile_headers(${globebrowsing_module} PRIVATE
# Gdal
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/gdal_data DESTINATION modules/globebrowsing)
if(WIN32)
if (WIN32)
add_library(gdal SHARED IMPORTED)
target_include_directories(gdal SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/ext/gdal/include)
set_target_properties(gdal PROPERTIES IMPORTED_IMPLIB ${CMAKE_CURRENT_SOURCE_DIR}/ext/gdal/lib/gdal_i.lib)
set_target_properties(gdal PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/ext/gdal/lib/gdal241.dll)
target_link_libraries(openspace-module-globebrowsing PRIVATE gdal)
else(WIN32)
else (WIN32)
find_package(GDAL REQUIRED)
target_include_directories(openspace-module-globebrowsing SYSTEM PRIVATE ${GDAL_INCLUDE_DIR})
target_link_libraries(openspace-module-globebrowsing PRIVATE ${GDAL_LIBRARY})
mark_as_advanced(GDAL_CONFIG GDAL_INCLUDE_DIR GDAL_LIBRARY)
endif() # WIN32
endif () # WIN32

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2022 *
* Copyright (c) 2014-2023 *
* *
* 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 *
@@ -88,7 +88,7 @@ std::unique_ptr<TileProvider> TileProvider::createFromDictionary(
void TileProvider::initializeDefaultTile() {
ZoneScoped;
ghoul_assert(!DefaultTile.texture, "Default tile should not have been created");
ghoul_assert(!DefaultTile.texture, "Default tile should not have been created");
using namespace ghoul::opengl;
// Create pixel data
@@ -118,8 +118,8 @@ void TileProvider::deinitializeDefaultTile() {
DefaultTileTexture = nullptr;
}
TileProvider::TileProvider() :
properties::PropertyOwner({ "TileProvider", "Tile Provider" })
TileProvider::TileProvider()
: properties::PropertyOwner({ "TileProvider", "Tile Provider" })
{}
void TileProvider::initialize() {
@@ -153,7 +153,9 @@ void TileProvider::deinitialize() {
}
ChunkTile TileProvider::traverseTree(TileIndex tileIndex, int parents, int maxParents,
std::function<void(TileIndex&, TileUvTransform&)>& ascendToParent, TileUvTransform& uvTransform) {
std::function<void(TileIndex&, TileUvTransform&)>& ascendToParent,
TileUvTransform& uvTransform)
{
// Step 1. Traverse 0 or more parents up the chunkTree as requested by the caller
for (int i = 0; i < parents && tileIndex.level > 1; i++) {
ascendToParent(tileIndex, uvTransform);
@@ -198,16 +200,17 @@ ChunkTile TileProvider::chunkTile(TileIndex tileIndex, int parents, int maxParen
ghoul_assert(isInitialized, "TileProvider was not initialized");
lambda ascendToParent = [](TileIndex& ti, TileUvTransform& uv) {
uv.uvOffset *= 0.5;
uv.uvScale *= 0.5;
std::function<void(TileIndex&, TileUvTransform&)> ascendToParent = []
(TileIndex& ti, TileUvTransform& uv) {
uv.uvOffset *= 0.5;
uv.uvScale *= 0.5;
uv.uvOffset += ti.positionRelativeParent();
uv.uvOffset += ti.positionRelativeParent();
ti.x /= 2;
ti.y /= 2;
ti.level--;
};
ti.x /= 2;
ti.y /= 2;
ti.level--;
};
TileUvTransform uvTransform = {
.uvOffset = glm::vec2(0.f, 0.f),

View File

@@ -71,8 +71,6 @@ enum class Type {
FfmpegTileProvider
};
using lambda = std::function<void(TileIndex&, TileUvTransform&)>;
struct TileProvider : public properties::PropertyOwner {
static unsigned int NumTileProviders;
@@ -134,7 +132,8 @@ struct TileProvider : public properties::PropertyOwner {
virtual float noDataValueAsFloat() = 0;
virtual ChunkTile chunkTile(TileIndex tileIndex, int parents = 0, int maxParents = 1337);
virtual ChunkTile chunkTile(TileIndex tileIndex, int parents = 0,
int maxParents = 1337);
ChunkTilePile chunkTilePile(TileIndex tileIndex, int pileSize);
@@ -144,7 +143,8 @@ struct TileProvider : public properties::PropertyOwner {
bool isInitialized = false;
protected:
ChunkTile traverseTree(TileIndex tileIndex, int parents, int maxParents,
lambda& ascendToParent, TileUvTransform& uvTransform);
std::function<void(TileIndex&, TileUvTransform&)>& ascendToParent,
TileUvTransform& uvTransform);
private:
virtual void internalInitialize();

View File

@@ -1,26 +1,27 @@
# #########################################################################################
# #
##########################################################################################
# #
# OpenSpace #
# #
# #
# Copyright (c) 2014-2023 #
# #
# #
# 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(${PROJECT_SOURCE_DIR}/support/cmake/module_definition.cmake)
@@ -97,7 +98,7 @@ else (WIN32)
target_include_directories(openspace-module-globebrowsing SYSTEM PRIVATE ${LIBMPV_INCLUDE_DIR})
target_link_libraries(openspace-module-globebrowsing PRIVATE ${LIBMPV_LIBRARY})
mark_as_advanced(LIBMPV_CONFIG LIBMPV_INCLUDE_DIR LIBMPV_LIBRARY)
endif() # WIN32
endif () # WIN32
create_new_module(
"Video"

View File

@@ -45,8 +45,6 @@ public:
void render(const RenderData& data, RendererTasks& rendererTask) override;
void update(const UpdateData& data) override;
static documentation::Documentation Documentation();
protected:
virtual void bindTexture() override;

View File

@@ -89,7 +89,6 @@ private:
bool _sphereIsDirty = false;
};
} // namespace openspace
#endif // __OPENSPACE_MODULE_BASE___RENDERABLEVIDEOSPHERE___H__

View File

@@ -22,8 +22,8 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_MODULE_BASE___SCREENSPACEVIDEO___H__
#define __OPENSPACE_MODULE_BASE___SCREENSPACEVIDEO___H__
#ifndef __OPENSPACE_MODULE_VIDEO___SCREENSPACEVIDEO___H__
#define __OPENSPACE_MODULE_VIDEO___SCREENSPACEVIDEO___H__
#include <openspace/rendering/screenspacerenderable.h>
@@ -55,4 +55,4 @@ private:
} // namespace openspace
#endif // __OPENSPACE_MODULE_BASE___SCREENSPACEVIDEO___H__
#endif // __OPENSPACE_MODULE_VIDEO___SCREENSPACEVIDEO___H__

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2022 *
* Copyright (c) 2014-2023 *
* *
* 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 *
@@ -22,8 +22,8 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__VIDEOPLAYER___H__
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__VIDEOPLAYER___H__
#ifndef __OPENSPACE_MODULE_VIDEO___VIDEOPLAYER___H__
#define __OPENSPACE_MODULE_VIDEO___VIDEOPLAYER___H__
#include <openspace/properties/propertyowner.h>
#include <openspace/util/syncable.h>
@@ -32,6 +32,7 @@
#include <openspace/properties/triggerproperty.h>
#include <openspace/properties/scalar/boolproperty.h>
#include <ghoul/glm.h>
#include <ghoul/misc/boolean.h>
#include <ghoul/opengl/texture.h>
#include <map>
@@ -46,7 +47,9 @@ enum class PlaybackMode {
RealTimeLoop
};
class VideoPlayer : public properties::PropertyOwner, Syncable {
class VideoPlayer : public properties::PropertyOwner, public Syncable {
BooleanType(PauseAfterSeek);
public:
VideoPlayer(const ghoul::Dictionary& dictionary);
~VideoPlayer();
@@ -58,7 +61,7 @@ public:
void play();
void goToStart();
void seekToTime(double time, bool pauseAfter = true);
void seekToTime(double time, PauseAfterSeek pauseAfter = PauseAfterSeek::Yes);
void toggleMute();
const std::unique_ptr<ghoul::opengl::Texture>& frameTexture() const;
@@ -77,7 +80,7 @@ public:
private:
// Libmpv keys
enum class MpvKey : uint64_t {
Duration = 1,
Duration = 1, // 0 is the default key in libmpv so avoid that
Height,
Width,
Meta,
@@ -95,7 +98,7 @@ private:
void resizeFBO(int width, int height);
// Libmpv
static void on_mpv_render_update(void*); // Has to be static because of C api
static void onMpvRenderUpdate(void*); // Has to be static because of C api
void initializeMpv(); // Called first time in update
void renderMpv(); // Called in update
void commandAsyncMpv(const char* cmd[], MpvKey key = MpvKey::Command);
@@ -149,7 +152,7 @@ private:
// Libmpv
mpv_handle* _mpvHandle = nullptr;
mpv_render_context* _mpvRenderContext = nullptr;
std::unique_ptr<ghoul::opengl::Texture> _frameTexture = nullptr;
std::unique_ptr<ghoul::opengl::Texture> _frameTexture;
GLuint _fbo = 0; // Our opengl framebuffer where mpv renders to
int _wakeup = 0; // Signals when libmpv has a new frame ready
bool _isInitialized = false; // If libmpv has been inititalized
@@ -159,4 +162,4 @@ private:
};
} // namespace video::globebrowsing
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__VIDEOPLAYER___H__
#endif // __OPENSPACE_MODULE_VIDEO___VIDEOPLAYER___H__

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2022 *
* Copyright (c) 2014-2023 *
* *
* 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 *
@@ -22,12 +22,12 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__VIDEOTILEPROVIDER___H__
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__VIDEOTILEPROVIDER___H__
#ifndef __OPENSPACE_MODULE_VIDEO___VIDEOTILEPROVIDER___H__
#define __OPENSPACE_MODULE_VIDEO___VIDEOTILEPROVIDER___H__
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
#include <modules/video/include/videoplayer.h>
#include <modules/video/include/videoplayer.h>
#include <openspace/properties/triggerproperty.h>
#include <openspace/properties/scalar/doubleproperty.h>
#include <openspace/properties/vector/ivec2property.h>
@@ -40,9 +40,8 @@
namespace openspace { struct Documentation; }
namespace openspace {
using namespace globebrowsing;
class VideoTileProvider : public TileProvider {
class VideoTileProvider : public globebrowsing::TileProvider {
public:
VideoTileProvider(const ghoul::Dictionary& dictionary);
~VideoTileProvider();
@@ -52,10 +51,12 @@ public:
int minLevel() override final;
int maxLevel() override final;
float noDataValueAsFloat() override final;
ChunkTile chunkTile(TileIndex tileIndex, int parents, int maxParents = 1337) override;
Tile tile(const TileIndex& tileIndex) override final;
Tile::Status tileStatus(const TileIndex& tileIndex) override final;
TileDepthTransform depthTransform() override final;
globebrowsing::ChunkTile chunkTile(globebrowsing::TileIndex tileIndex, int parents,
int maxParents = 1337) override;
globebrowsing::Tile tile(const globebrowsing::TileIndex& tileIndex) override final;
globebrowsing::Tile::Status tileStatus(
const globebrowsing::TileIndex& tileIndex) override final;
globebrowsing::TileDepthTransform depthTransform() override final;
static documentation::Documentation Documentation();
@@ -64,12 +65,13 @@ private:
void internalDeinitialize() override final;
// Tile handling
std::map<TileIndex::TileHashKey, Tile> _tileCache; // Cache for rendering 1 frame
// Cache for rendering 1 frame
std::map<globebrowsing::TileIndex::TileHashKey, globebrowsing::Tile> _tileCache;
bool _tileIsReady = false;
VideoPlayer _videoPlayer;
};
} // namespace video::globebrowsing
} // namespace openspace
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__VIDEOTILEPROVIDER___H__
#endif // __OPENSPACE_MODULE_VIDEO___VIDEOTILEPROVIDER___H__

View File

@@ -1,16 +0,0 @@
local spec = {
Type = "ScreenSpaceVideo",
Identifier = "ScreenSpaceVideoExample",
Name = "Screen Space Browser Example",
Video = "C:/Users/ylvaselling/Documents/Work/Testmovies/chlorophyll_model_2048.mp4",
};
asset.onInitialize(function()
openspace.addScreenSpaceRenderable(spec)
end)
asset.onDeinitialize(function()
openspace.removeScreenSpaceRenderable(spec)
end)
asset.export(spec)

View File

@@ -27,25 +27,12 @@
#include <openspace/documentation/documentation.h>
#include <openspace/documentation/verifier.h>
namespace {
struct [[codegen::Dictionary(RenderableVideoPlane)]] Parameters {
};
#include "renderablevideoplane_codegen.cpp"
} // namespace
namespace openspace {
documentation::Documentation RenderableVideoPlane::Documentation() {
return codegen::doc<Parameters>("renderable_video_plane");
}
RenderableVideoPlane::RenderableVideoPlane(const ghoul::Dictionary& dictionary)
: RenderablePlane(dictionary)
, _videoPlayer(dictionary)
{
const Parameters p = codegen::bake<Parameters>(dictionary);
addPropertySubOwner(_videoPlayer);
}
@@ -64,11 +51,9 @@ bool RenderableVideoPlane::isReady() const {
}
void RenderableVideoPlane::render(const RenderData& data, RendererTasks& rendererTask) {
if (!_videoPlayer.isInitialized()) {
return;
if (_videoPlayer.isInitialized()) {
RenderablePlane::render(data, rendererTask);
}
RenderablePlane::render(data, rendererTask);
}
void RenderableVideoPlane::update(const UpdateData& data) {

View File

@@ -157,7 +157,7 @@ RenderableVideoSphere::RenderableVideoSphere(const ghoul::Dictionary& dictionary
{ static_cast<int>(Orientation::Outside), "Outside" },
{ static_cast<int>(Orientation::Inside), "Inside" },
{ static_cast<int>(Orientation::Both), "Both" }
});
});
if (p.orientation.has_value()) {
_orientation = static_cast<int>(codegen::map<Orientation>(*p.orientation));
@@ -171,7 +171,7 @@ RenderableVideoSphere::RenderableVideoSphere(const ghoul::Dictionary& dictionary
_size.onChange([this]() {
setBoundingSphere(_size);
_sphereIsDirty = true;
});
});
addProperty(_size);
addProperty(_segments);

View File

@@ -35,25 +35,12 @@
#include <filesystem>
#include <optional>
namespace {
struct [[codegen::Dictionary(ScreenSpaceVideo)]] Parameters {
};
#include "screenspacevideo_codegen.cpp"
} // namespace
namespace openspace {
documentation::Documentation ScreenSpaceVideo::Documentation() {
return codegen::doc<Parameters>("screenspace_video");
}
ScreenSpaceVideo::ScreenSpaceVideo(const ghoul::Dictionary& dictionary)
: ScreenSpaceRenderable(dictionary)
, _videoPlayer(dictionary)
{
const Parameters p = codegen::bake<Parameters>(dictionary);
// @TODO (abock, 2021-02-02) Should this be the name variable? The identifier wasn't
// declared in the documentation
std::string identifier;
@@ -82,10 +69,9 @@ void ScreenSpaceVideo::update() {
}
void ScreenSpaceVideo::render() {
if (!_videoPlayer.isInitialized()) {
return;
if (_videoPlayer.isInitialized()) {
ScreenSpaceRenderable::render();
}
ScreenSpaceRenderable::render();
}
bool ScreenSpaceVideo::initializeGL() {

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2022 *
* Copyright (c) 2014-2023 *
* *
* 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 *
@@ -42,8 +42,7 @@ namespace {
constexpr openspace::properties::Property::PropertyInfo VideoInfo = {
"Video",
"Video",
"This should point to the video that should be played. It can "
"be either a file path or a url to a youtube video."
"This should point to the video file that should be played."
};
constexpr openspace::properties::Property::PropertyInfo PlayInfo = {
@@ -124,6 +123,8 @@ namespace {
namespace openspace {
namespace {
bool checkMpvError(int status) {
if (status < 0) {
LERROR(fmt::format("Libmpv API error: {}", mpv_error_string(status)));
@@ -137,8 +138,9 @@ void* getOpenGLProcAddress(void*, const char* name) {
global::windowDelegate->openGLProcedureAddress(name)
);
}
} // namespace
void VideoPlayer::on_mpv_render_update(void* ctx) {
void VideoPlayer::onMpvRenderUpdate(void* ctx) {
// The wakeup flag is set here to enable the mpv_render_context_render
// path in the main loop.
// The pattern here with a static function and a void pointer to the the class
@@ -155,8 +157,7 @@ void VideoPlayer::observePropertyMpv(MpvKey key) {
);
}
void VideoPlayer::setPropertyStringMpv(const char* name, const char* value)
{
void VideoPlayer::setPropertyStringMpv(const char* name, const char* value) {
int result = mpv_set_property_string(_mpvHandle, name, value);
if (!checkMpvError(result)) {
LWARNING(fmt::format("Error setting property {}", name));
@@ -271,22 +272,23 @@ VideoPlayer::VideoPlayer(const ghoul::Dictionary& dictionary)
if (p.playbackMode.has_value()) {
switch (*p.playbackMode) {
case Parameters::PlaybackMode::RealTimeLoop:
_playbackMode = PlaybackMode::RealTimeLoop;
break;
case Parameters::PlaybackMode::MapToSimulationTime:
_playbackMode = PlaybackMode::MapToSimulationTime;
break;
default:
LERROR("Missing playback mode in VideoTileProvider");
throw ghoul::MissingCaseException();
case Parameters::PlaybackMode::RealTimeLoop:
_playbackMode = PlaybackMode::RealTimeLoop;
break;
case Parameters::PlaybackMode::MapToSimulationTime:
_playbackMode = PlaybackMode::MapToSimulationTime;
break;
default:
LERROR("Missing playback mode in VideoTileProvider");
throw ghoul::MissingCaseException();
}
}
if (_playbackMode == PlaybackMode::MapToSimulationTime) {
if (!p.startTime.has_value() || !p.endTime.has_value()) {
LERROR("Video tile layer tried to map to simulation time but lacked start or"
" end time");
" end time"
);
return;
}
_startJ200Time = Time::convertTime(*p.startTime);
@@ -297,34 +299,35 @@ VideoPlayer::VideoPlayer(const ghoul::Dictionary& dictionary)
global::syncEngine->addSyncable(this);
keys = {
{MpvKey::Pause, "pause"},
{MpvKey::Params, "video-params"},
{MpvKey::Time, "time-pos"},
{MpvKey::Duration, "duration"},
{MpvKey::Height, "height"},
{MpvKey::Width, "width"},
{MpvKey::Meta, "metadata"},
{MpvKey::Fps, "container-fps"},
{MpvKey::IsSeeking, "seeking"},
{MpvKey::Mute, "mute"},
{MpvKey::Seek, "seek"}
{ MpvKey::Pause, "pause" },
{ MpvKey::Params, "video-params" },
{ MpvKey::Time, "time-pos" },
{ MpvKey::Duration, "duration" },
{ MpvKey::Height, "height" },
{ MpvKey::Width, "width" },
{ MpvKey::Meta, "metadata" },
{ MpvKey::Fps, "container-fps" },
{ MpvKey::IsSeeking, "seeking" },
{ MpvKey::Mute, "mute" },
{ MpvKey::Seek, "seek" }
};
formats = {
{MpvKey::Pause, MPV_FORMAT_FLAG},
{MpvKey::Params, MPV_FORMAT_NODE},
{MpvKey::Time, MPV_FORMAT_DOUBLE},
{MpvKey::Duration, MPV_FORMAT_DOUBLE},
{MpvKey::Height, MPV_FORMAT_INT64},
{MpvKey::Width, MPV_FORMAT_INT64},
{MpvKey::Meta, MPV_FORMAT_NODE},
{MpvKey::Fps, MPV_FORMAT_DOUBLE},
{MpvKey::IsSeeking, MPV_FORMAT_FLAG},
{MpvKey::Mute, MPV_FORMAT_STRING}
{ MpvKey::Pause, MPV_FORMAT_FLAG },
{ MpvKey::Params, MPV_FORMAT_NODE },
{ MpvKey::Time, MPV_FORMAT_DOUBLE },
{ MpvKey::Duration, MPV_FORMAT_DOUBLE },
{ MpvKey::Height, MPV_FORMAT_INT64 },
{ MpvKey::Width, MPV_FORMAT_INT64 },
{ MpvKey::Meta, MPV_FORMAT_NODE },
{ MpvKey::Fps, MPV_FORMAT_DOUBLE },
{ MpvKey::IsSeeking, MPV_FORMAT_FLAG },
{ MpvKey::Mute, MPV_FORMAT_STRING }
};
}
VideoPlayer::~VideoPlayer() {}
void VideoPlayer::pause() {
int isPaused = 1;
setPropertyAsyncMpv(isPaused, MpvKey::Pause);
@@ -400,13 +403,9 @@ void VideoPlayer::initializeMpv() {
// Starting MPV in a paused state seems to reduce problems with initialization
setPropertyStringMpv("pause", "");
//setPropertyStringMpv("load-stats-overlay", "");
//mpv_set_property_string(_mpvHandle, "script-opts", "autoload-disabled=yes");
// Verbose mode
mpv_set_property_string(_mpvHandle, "msg-level", "all=v");
//mpv_request_log_messages(_mpvHandle, "debug");
// Verbose mode for debug purposes
// setPropertyStringMpv("msg-level", "all=v");
// mpv_request_log_messages(_mpvHandle, "debug");
if (mpv_initialize(_mpvHandle) < 0) {
LINFO("mpv init failed");
@@ -419,16 +418,17 @@ void VideoPlayer::initializeMpv() {
int blockTime = 0;
mpv_render_param params[]{
{MPV_RENDER_PARAM_API_TYPE, const_cast<char*>(MPV_RENDER_API_TYPE_OPENGL)},
{MPV_RENDER_PARAM_OPENGL_INIT_PARAMS, &gl_init_params},
{MPV_RENDER_PARAM_ADVANCED_CONTROL, &adv},
{MPV_RENDER_PARAM_BLOCK_FOR_TARGET_TIME, &blockTime},
{MPV_RENDER_PARAM_INVALID, nullptr}
{ MPV_RENDER_PARAM_API_TYPE, const_cast<char*>(MPV_RENDER_API_TYPE_OPENGL) },
{ MPV_RENDER_PARAM_OPENGL_INIT_PARAMS, &gl_init_params },
{ MPV_RENDER_PARAM_ADVANCED_CONTROL, &adv },
{ MPV_RENDER_PARAM_BLOCK_FOR_TARGET_TIME, &blockTime },
{ MPV_RENDER_PARAM_INVALID, nullptr }
};
// This makes mpv use the currently set GL context. It will use the callback
// (passed via params) to resolve GL builtin functions, as well as extensions.
if (mpv_render_context_create(&_mpvRenderContext, _mpvHandle, params) < 0) {
int result = mpv_render_context_create(&_mpvRenderContext, _mpvHandle, params);
if (result < 0) {
LINFO("Failed to initialize libmpv OpenGL context");
}
@@ -438,7 +438,7 @@ void VideoPlayer::initializeMpv() {
// users which run OpenGL on a different thread.)
mpv_render_context_set_update_callback(
_mpvRenderContext,
on_mpv_render_update,
onMpvRenderUpdate,
this
);
@@ -468,7 +468,7 @@ void VideoPlayer::initializeMpv() {
_isInitialized = true;
}
void VideoPlayer::seekToTime(double time, bool pauseAfter) {
void VideoPlayer::seekToTime(double time, PauseAfterSeek pauseAfter) {
if (_isSeeking || abs(_currentVideoTime - time) < glm::epsilon<double>()) {
return;
}
@@ -500,7 +500,8 @@ void VideoPlayer::renderMpv() {
handleMpvEvents();
if (_wakeup) {
if ((mpv_render_context_update(_mpvRenderContext) & MPV_RENDER_UPDATE_FRAME)) {
uint64_t result = mpv_render_context_update(_mpvRenderContext);
if ((result & MPV_RENDER_UPDATE_FRAME)) {
// Save the currently bound fbo
GLint defaultFBO = ghoul::opengl::FramebufferObject::getActiveObject();
@@ -514,12 +515,12 @@ void VideoPlayer::renderMpv() {
_videoResolution.y,
0
};
int flip_y{ 1 };
int flipY{ 1 };
mpv_render_param params[] = {
{MPV_RENDER_PARAM_OPENGL_FBO, &mpfbo},
{MPV_RENDER_PARAM_FLIP_Y, &flip_y},
{MPV_RENDER_PARAM_INVALID, nullptr}
{ MPV_RENDER_PARAM_OPENGL_FBO, &mpfbo },
{ MPV_RENDER_PARAM_FLIP_Y, &flipY },
{ MPV_RENDER_PARAM_INVALID, nullptr }
};
// This "renders" to the video_framebuffer "linked by ID" in the
// params_fbo
@@ -584,25 +585,7 @@ void VideoPlayer::handleMpvEvents() {
mpv_event_log_message* msg =
reinterpret_cast<mpv_event_log_message*>(event->data);
std::stringstream ss;
ss << "[" << msg->prefix << "] " << msg->level << ": " << msg->text;
LINFO(ss.str());
break;
}
case MPV_EVENT_COMMAND_REPLY: {
MpvKey key = static_cast<MpvKey>(event->reply_userdata);
switch (key) {
case MpvKey::Command: {
break;
}
case MpvKey::Seek: {
break;
}
default: {
break;
}
}
LINFO(fmt::format("[{}] {}: {}", msg->prefix, msg->level, msg->text));
break;
}
default: {
@@ -730,7 +713,7 @@ void VideoPlayer::handleMpvProperties(mpv_event* event) {
}
case MpvKey::Pause: {
int* videoIsPaused = reinterpret_cast<int*>(prop->data);
_isPaused = *videoIsPaused == 1;
_isPaused = (* videoIsPaused == 1);
LINFO(fmt::format("Is Paused: {}", _isPaused));
break;
}
@@ -795,10 +778,8 @@ void VideoPlayer::handleMpvProperties(mpv_event* event) {
}
break;
}
default: {
throw ghoul::MissingCaseException();
break;
}
}
}
@@ -815,12 +796,7 @@ void VideoPlayer::destroy() {
}
void VideoPlayer::preSync(bool isMaster) {
if (isMaster) {
_correctPlaybackTime = _currentVideoTime;
}
else {
_correctPlaybackTime = -1.0;
}
_correctPlaybackTime = isMaster ? _currentVideoTime : -1.0;
}
void VideoPlayer::encode(SyncBuffer* syncBuffer) {
@@ -944,6 +920,4 @@ void VideoPlayer::resizeFBO(int width, int height) {
createFBO(width, height);
}
VideoPlayer::~VideoPlayer() {}
} // namespace openspace::video

View File

@@ -2,7 +2,7 @@
* *
* OpenSpace *
* *
* Copyright (c) 2014-2022 *
* Copyright (c) 2014-2023 *
* *
* 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 *
@@ -38,37 +38,33 @@
namespace {
constexpr std::string_view _loggerCat = "VideoTileProvider";
struct [[codegen::Dictionary(VideoTileProvider)]] Parameters {
};
#include "videotileprovider_codegen.cpp"
} // namespace
namespace openspace {
documentation::Documentation VideoTileProvider::Documentation() {
return codegen::doc<Parameters>("video_videotileprovider");
namespace {
constexpr bool isDifferent(double first, double second) {
return abs(first - second) > glm::epsilon<double>();
}
bool isDifferent(double first, double second) {
return abs(first - second) > glm::epsilon<double>();
}
VideoTileProvider::VideoTileProvider(const ghoul::Dictionary& dictionary)
: _videoPlayer(dictionary)
{
ZoneScoped
const Parameters p = codegen::bake<Parameters>(dictionary);
addPropertySubOwner(_videoPlayer);
}
Tile VideoTileProvider::tile(const TileIndex& tileIndex) {
VideoTileProvider::~VideoTileProvider() {}
globebrowsing::Tile VideoTileProvider::tile(const globebrowsing::TileIndex& tileIndex) {
ZoneScoped
if (!_videoPlayer.isInitialized()) {
return Tile();
return globebrowsing::Tile();
}
// Always check that our framebuffer is ok
@@ -83,28 +79,28 @@ Tile VideoTileProvider::tile(const TileIndex& tileIndex) {
foundTile->second.texture != _videoPlayer.frameTexture().get();
if (foundTile == _tileCache.end() || textureChanged) {
_tileCache[hash] = Tile{
_tileCache[hash] = globebrowsing::Tile{
_videoPlayer.frameTexture().get(),
std::nullopt,
Tile::Status::OK
globebrowsing::Tile::Status::OK
};
}
return _tileCache[hash];
}
Tile::Status VideoTileProvider::tileStatus(const TileIndex& tileIndex) {
globebrowsing::Tile::Status VideoTileProvider::tileStatus(const globebrowsing::TileIndex& tileIndex) {
if (tileIndex.level > maxLevel()) {
return Tile::Status::OutOfRange;
return globebrowsing::Tile::Status::OutOfRange;
}
else if (_tileIsReady) {
return Tile::Status::OK;
return globebrowsing::Tile::Status::OK;
}
else {
return Tile::Status::Unavailable;
return globebrowsing::Tile::Status::Unavailable;
}
}
TileDepthTransform VideoTileProvider::depthTransform() {
globebrowsing::TileDepthTransform VideoTileProvider::depthTransform() {
return { 0.f, 1.f };
}
@@ -116,13 +112,18 @@ void VideoTileProvider::reset() {
_videoPlayer.reset();
}
ChunkTile VideoTileProvider::chunkTile(TileIndex tileIndex, int parents, int maxParents) {
globebrowsing::ChunkTile VideoTileProvider::chunkTile(globebrowsing::TileIndex tileIndex,
int parents, int maxParents) {
using namespace globebrowsing;
std::function<void(TileIndex&, TileUvTransform&)> ascendToParent = []
(TileIndex& ti, TileUvTransform& uv) {
ti.level--;
};
lambda ascendToParent = [](TileIndex& ti, TileUvTransform& uv) {
ti.level--;
glm::vec2 noOfTiles = {
std::pow(2, tileIndex.level),
std::pow(2, tileIndex.level - 1)
};
glm::vec2 noOfTiles = { pow(2, tileIndex.level), pow(2, tileIndex.level - 1) };
glm::vec2 ratios = { 1.f / noOfTiles.x, 1.f / noOfTiles.y };
float offsetX = ratios.x * static_cast<float>(tileIndex.x);
// The tiles on the y-axis should be traversed backwards
@@ -151,10 +152,8 @@ void VideoTileProvider::internalInitialize() {
_videoPlayer.initialize();
}
VideoTileProvider::~VideoTileProvider() {}
void VideoTileProvider::internalDeinitialize() {
_videoPlayer.destroy();
}
} // namespace openspace::video
} // namespace openspace

View File

@@ -1,30 +0,0 @@
local layer = {
Identifier = "TestVideo",
Video = "C:/Users/ylvaselling/Documents/Work/Testmovies/result.mp4",
StartTime = '2023 01 29 20:00:00',
EndTime = '2023 01 29 21:00:00',
Name = "Test Video",
PlaybackMode = "MapToSimulationTime",
Enabled = asset.enabled,
Type = "VideoTileLayer",
Description = [[Testing video]]
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer("Earth", "ColorLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer("Earth", "ColorLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "Aqua Modis (Temporal)",
Version = "1.1",
Description = "GIBS hosted layer",
Author = "NASA EOSDIS Global Imagery Browse Services",
URL = "https://earthdata.nasa.gov/eosdis/science-system-description/eosdis-components/gibs",
License = "NASA"
}

View File

@@ -1,27 +0,0 @@
local layer = {
Identifier = "TestVideoLoop",
Video = "C:/Users/ylvaselling/Documents/Work/Testmovies/black_carbon_sulfate.mp4",
Name = "Test Video Loop",
Enabled = asset.enabled,
Type = "VideoTileLayer",
Description = [[Testing video]]
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer("Earth", "ColorLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer("Earth", "ColorLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "Aqua Modis (Temporal)",
Version = "1.1",
Description = "GIBS hosted layer",
Author = "NASA EOSDIS Global Imagery Browse Services",
URL = "https://earthdata.nasa.gov/eosdis/science-system-description/eosdis-components/gibs",
License = "NASA"
}

View File

@@ -1,27 +0,0 @@
local layer = {
Identifier = "SosLoopTest",
Video = "C:/Users/ylvaselling/Documents/Work/Testmovies/chlorophyll_model_2048.mp4",
Name = "Science On A Sphere Loop Video",
Enabled = asset.enabled,
Type = "VideoTileLayer",
Description = [[Testing video]]
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer("Earth", "ColorLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer("Earth", "ColorLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "Aqua Modis (Temporal)",
Version = "1.1",
Description = "GIBS hosted layer",
Author = "NASA EOSDIS Global Imagery Browse Services",
URL = "https://earthdata.nasa.gov/eosdis/science-system-description/eosdis-components/gibs",
License = "NASA"
}

View File

@@ -1,27 +0,0 @@
local layer = {
Identifier = "SosLoop3",
Video = "C:/Users/ylvaselling/Documents/Work/Testmovies/air_traffic_2048.mp4",
Name = "Science On A Sphere Loop Video",
Enabled = asset.enabled,
Type = "VideoTileLayer",
Description = [[Testing video]]
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer("Earth", "ColorLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer("Earth", "ColorLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "Aqua Modis (Temporal)",
Version = "1.1",
Description = "GIBS hosted layer",
Author = "NASA EOSDIS Global Imagery Browse Services",
URL = "https://earthdata.nasa.gov/eosdis/science-system-description/eosdis-components/gibs",
License = "NASA"
}

View File

@@ -1,27 +0,0 @@
local layer = {
Identifier = "SosLoop2",
Video = "C:/Users/ylvaselling/Documents/Work/Testmovies/2048_jpg-2048x1024.mp4",
Name = "Science On A Sphere Loop Video",
Enabled = asset.enabled,
Type = "VideoTileLayer",
Description = [[Testing video]]
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer("Earth", "ColorLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer("Earth", "ColorLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "Aqua Modis (Temporal)",
Version = "1.1",
Description = "GIBS hosted layer",
Author = "NASA EOSDIS Global Imagery Browse Services",
URL = "https://earthdata.nasa.gov/eosdis/science-system-description/eosdis-components/gibs",
License = "NASA"
}

View File

@@ -1,30 +0,0 @@
local layer = {
Identifier = "ScienceOnASphere",
Video = "C:/Users/ylvaselling/Documents/Work/Testmovies/4096-4.mp4",
StartTime = '2004 01 01 00:00:00',
EndTime = '2004 06 05 20:00:00',
Name = "Science On A Sphere Video",
PlaybackMode = "MapToSimulationTime",
Enabled = asset.enabled,
Type = "VideoTileLayer",
Description = [[Testing video]]
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer("Earth", "ColorLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer("Earth", "ColorLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "Aqua Modis (Temporal)",
Version = "1.1",
Description = "GIBS hosted layer",
Author = "NASA EOSDIS Global Imagery Browse Services",
URL = "https://earthdata.nasa.gov/eosdis/science-system-description/eosdis-components/gibs",
License = "NASA"
}

View File

@@ -1,26 +0,0 @@
local layer = {
Identifier = "Capitals",
Video = "C:/Users/ylvaselling/Documents/Work/Testmovies/capitals/4096.png",
Name = "Capitals",
Enabled = asset.enabled,
Description = [[Testing video]]
}
asset.onInitialize(function()
openspace.globebrowsing.addLayer("Earth", "ColorLayers", layer)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteLayer("Earth", "ColorLayers", layer)
end)
asset.export("layer", layer)
asset.meta = {
Name = "Aqua Modis (Temporal)",
Version = "1.1",
Description = "GIBS hosted layer",
Author = "NASA EOSDIS Global Imagery Browse Services",
URL = "https://earthdata.nasa.gov/eosdis/science-system-description/eosdis-components/gibs",
License = "NASA"
}

View File

@@ -23,6 +23,7 @@
****************************************************************************************/
#include <modules/video/videomodule.h>
#include <modules/video/include/videotileprovider.h>
#include <modules/video/include/screenspacevideo.h>
#include <modules/video/include/renderablevideosphere.h>
@@ -60,12 +61,11 @@ VideoModule::VideoModule()
void VideoModule::internalInitialize(const ghoul::Dictionary& dict) {
const Parameters p = codegen::bake<Parameters>(dict);
using namespace globebrowsing;
_enabled = p.enabled.value_or(_enabled);
ghoul::TemplateFactory<TileProvider>* fTileProvider =
FactoryManager::ref().factory<TileProvider>();
ghoul::TemplateFactory<globebrowsing::TileProvider>* fTileProvider =
FactoryManager::ref().factory<globebrowsing::TileProvider>();
ghoul_assert(fTileProvider, "TileProvider factory was not created");
fTileProvider->registerClass<VideoTileProvider>("VideoTileLayer");
@@ -89,13 +89,4 @@ std::vector<documentation::Documentation> VideoModule::documentations() const {
return std::vector<documentation::Documentation>();
}
scripting::LuaLibrary VideoModule::luaLibrary() const {
return {
"video",
{
}
};
}
} // namespace openspace

View File

@@ -37,7 +37,6 @@ public:
VideoModule();
scripting::LuaLibrary luaLibrary() const override;
std::vector<documentation::Documentation> documentations() const override;
protected:

View File

@@ -1,32 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2023 *
* *
* 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 <modules/video/videomodule.h>
#include <openspace/engine/moduleengine.h>
namespace {
constexpr std::string_view _loggerCat = "VideoModule";
//#include "videomodule_lua_codegen.cpp"
} // namespace

View File

@@ -1,33 +0,0 @@
local transforms = asset.require("scene/solarsystem/planets/earth/transforms")
local plane = {
Identifier = "VideoPlaneVeryCool",
Parent = transforms.EarthCenter.Identifier,
Transform = {
Translation = {
Type = "StaticTranslation",
Position = { 0.0, -11E7, 0.0 }
}
},
Renderable = {
Type = "RenderableVideoPlane",
MirrorBackside = true,
Size = 3E7,
Video = "C:/Users/malej60/Videos/test/4096-4.mp4",
PlaybackMode = "RealTimeLoop"
},
GUI = {
Name = "Test Plane Cool",
Path = "/Other/Planes"
}
}
asset.onInitialize(function()
openspace.addSceneGraphNode(plane)
end)
asset.onDeinitialize(function()
openspace.removeSceneGraphNode(plane)
end)
asset.export(plane)

View File

@@ -1,32 +0,0 @@
local sphere = {
Identifier = "Aurora",
Transform = {
Translation = {
Type = "StaticTranslation",
Position = { 0, 0, 0 }
}
},
Renderable = {
Type = "RenderableVideoSphere",
Enabled = true,
Size = 100.0,
Segments = 80,
Opacity = 1,
Video = "C:/Users/ylvaselling/Documents/Work/Testmovies/aurora.mp4",
Orientation = "Both",
},
GUI = {
Name = "Aurora Sphere",
Path = "/Other/Spheres"
}
}
asset.onInitialize(function()
openspace.addSceneGraphNode(sphere)
end)
asset.onDeinitialize(function()
openspace.removeSceneGraphNode(sphere)
end)
asset.export(sphere)

View File

@@ -1,33 +0,0 @@
local sphere = {
Identifier = "VideoSphereVeryCool",
Transform = {
Translation = {
Type = "StaticTranslation",
Position = { 0, 0, 0 }
}
},
Renderable = {
Type = "RenderableVideoSphere",
Enabled = true,
Size = 100.0,
Segments = 80,
Opacity = 1,
Texture = openspace.absPath("${DATA}/test2.jpg"),
File = "C:/Users/ylvaselling/Documents/Work/Testmovies/2048_jpg-2048x1024.mp4",
Orientation = "Both",
},
GUI = {
Name = "Test Sphere Cool",
Path = "/Other/Spheres"
}
}
asset.onInitialize(function()
openspace.addSceneGraphNode(sphere)
end)
asset.onDeinitialize(function()
openspace.removeSceneGraphNode(sphere)
end)
asset.export(sphere)