Finish change of structure of screenspaceskybrowser

This commit is contained in:
sylvass
2021-11-17 11:15:21 -05:00
parent 80e4e26b43
commit d5cdf4b3f8
10 changed files with 46 additions and 459 deletions

View File

@@ -27,13 +27,15 @@ include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake)
set(HEADER_FILES
skybrowsermodule.h
include/screenspaceskybrowser.h
include/screenspaceskytarget.h
include/wwtdatahandler.h
include/utility.h
include/renderableskybrowser.h
include/pair.h
tinyxml2/tinyxml2.h
include/pair.h
include/wwtcommunicator.h
include/browser.h
include/screenspaceskybrowser.h
ext/tinyxml2/tinyxml2.h
)
source_group("Header Files" FILES ${HEADER_FILES})
@@ -42,13 +44,15 @@ set(SOURCE_FILES
skybrowsermodule.cpp
skybrowsermodule_lua.inl
src/screenspaceskybrowser.cpp
src/screenspaceskytarget.cpp
src/wwtdatahandler.cpp
src/utility.cpp
src/renderableskybrowser.cpp
src/pair.cpp
tinyxml2/tinyxml2.cpp
src/pair.cpp
src/wwtcommunicator.cpp
src/browser.cpp
src/screenspaceskybrowser.cpp
ext/tinyxml2/tinyxml2.cpp
)
source_group("Source Files" FILES ${SOURCE_FILES})

View File

@@ -74,6 +74,7 @@ public:
void loadImages(std::string collection);
void setImageOpacity(const int i, float opacity);
void sendIdToBrowser();
void updateBrowserSize();
ScreenSpaceSkyTarget* getTarget();
ScreenSpaceSkyBrowser* getBrowser();

View File

@@ -1,89 +0,0 @@
#ifndef __OPENSPACE_MODULE_SKYBROWSER___SCREENSPACESKYBROWSER2___H__
#define __OPENSPACE_MODULE_SKYBROWSER___SCREENSPACESKYBROWSER2___H__
#include <modules/skybrowser/include/wwtcommunicator.h>
#include <openspace/rendering/screenspacerenderable.h>
#include <openspace/documentation/documentation.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/scalar/floatproperty.h>
#include <openspace/properties/vector/ivec3property.h>
#include <deque>
namespace openspace {
class ScreenSpaceSkyTarget;
class ScreenSpaceSkyBrowser2 : public ScreenSpaceRenderable, public WwtCommunicator
{
public:
// Constructor and destructor
ScreenSpaceSkyBrowser2(const ghoul::Dictionary& dictionary);
virtual ~ScreenSpaceSkyBrowser2();
// Inherited functions
bool initializeGL() override;
bool deinitializeGL() override;
glm::mat4 scaleMatrix() override;
void render() override;
void update() override;
// Target - browser connection
bool connectToSkyTarget();
bool isAnimated();
void startFovAnimation(float fov);
void incrementallyAnimateToFov(float deltaTime);
glm::dvec2 fineTuneVector(glm::dvec2 drag);
// Getters returning references
ScreenSpaceSkyTarget* getSkyTarget();
properties::FloatProperty& getOpacity();
// Setters
void setVerticalFovWithScroll(float scroll);
void setScale(glm::vec2 scalingFactor);
void setScale(float scalingFactor);
// Communication with WorldWide Telescope
void startSyncingWithWwt();
// Mouse interaction with the browser. Returns 1 or -1 at the coordinate in
// image if the mouse is on a side of the browser
// __1__
// y| -1 |_____|1
// |__x -1
glm::ivec2 isOnResizeArea(glm::vec2 screenSpaceCoord);
private:
void syncWwtView();
void bindTexture() override;
// Resize functions
void saveResizeStartSize();
void updateBrowserSize();
// Properties
properties::StringProperty _skyTargetId;
// Flags
bool _isSyncedWithWwt{ false };
bool _isFovAnimated{ false };
float _endVfov{ 0.f };
float _fovDiff{ 0.01f };
// Resizing of browser
glm::vec2 _originalDimensions;
float _originalScale;
float _resizeAreaPercentage{ 0.1f };
// Target & images
ScreenSpaceSkyTarget* _skyTarget{ nullptr };
std::thread _wwtMessages;
// Time variables
// For capping the calls to change the zoom from scrolling
constexpr static const std::chrono::milliseconds _timeUpdateInterval{ 10 };
std::chrono::system_clock::time_point _lastUpdateTime;
};
}
#endif // __OPENSPACE_MODULE_SKYBROWSER___SCREENSPACESKYBROWSER2___H__

View File

@@ -44,14 +44,12 @@ public:
WwtCommunicator(WwtCommunicator const&) = default;
virtual ~WwtCommunicator();
// Web page communication
void setIdInBrowser(const std::string& id);
// WorldWide Telescope communication
void displayImage(const std::string& url, const int i);
void removeSelectedImage(const int i);
void setImageLayerOrder(int i, int order);
void setImageOrder(int i, int order);
void loadImageCollection(const std::string& collection);
void setImageOpacity(const int i, float opacity);
// Getters
const std::deque<int>& getSelectedImages();
@@ -59,7 +57,6 @@ public:
float verticalFov() const;
glm::dvec2 fieldsOfView();
bool hasLoadedImages() const;
// Setters
void setHasLoadedImages(bool isLoaded);
@@ -72,6 +69,9 @@ public:
protected:
void sendMessageToWwt(const ghoul::Dictionary& msg);
// Web page communication
void setIdInBrowser(const std::string& id);
properties::FloatProperty _verticalFov;
properties::IVec3Property _borderColor;

View File

@@ -255,7 +255,7 @@ SkyBrowserModule::SkyBrowserModule()
if (_mouseOnPair && action == MouseAction::Press) {
// Get the currently selected browser
setSelectedBrowser(_mouseOnPair->getBrowser());
setSelectedBrowser(_mouseOnPair->getBrowser()->identifier());
if (button == MouseButton::Left) {
_isCameraRotating = false;
@@ -315,7 +315,7 @@ SkyBrowserModule::SkyBrowserModule()
}
if (_isResizing) {
_isResizing = false;
_mouseOnPair->getBrowser()->updateBrowserSize();
_mouseOnPair->updateBrowserSize();
return true;
}
}
@@ -447,11 +447,13 @@ void SkyBrowserModule::internalInitialize(const ghoul::Dictionary& dict) {
// register ScreenSpaceBrowser
auto fScreenSpaceRenderable = FactoryManager::ref().factory<ScreenSpaceRenderable>();
ghoul_assert(fScreenSpaceRenderable, "ScreenSpaceRenderable factory was not created");
fScreenSpaceRenderable->registerClass<ScreenSpaceSkyBrowser>("ScreenSpaceSkyBrowser");
// register ScreenSpaceTarget
fScreenSpaceRenderable->registerClass<ScreenSpaceSkyTarget>("ScreenSpaceSkyTarget");
// register ScreenSpaceTarget
fScreenSpaceRenderable->registerClass<ScreenSpaceSkyBrowser>("ScreenSpaceSkyBrowser");
// Register Renderable Skybrowser
auto fRenderable = FactoryManager::ref().factory<Renderable>();
ghoul_assert(fRenderable, "Renderable factory was not created");
@@ -716,7 +718,7 @@ std::vector<Pair>& SkyBrowserModule::getPairs()
return _targetsBrowsers;
}
Pair* SkyBrowserModule::getPair(std::string id)
Pair* SkyBrowserModule::getPair(const std::string& id)
{
auto it = std::find_if(std::begin(_targetsBrowsers), std::end(_targetsBrowsers),
[&](Pair& pair) {
@@ -855,14 +857,8 @@ void SkyBrowserModule::incrementallyAnimateTargets(double deltaTime)
}
}
void SkyBrowserModule::setSelectedBrowser(ScreenSpaceSkyBrowser* browser) {
if (browser) {
_selectedBrowser = browser->identifier();
}
}
void SkyBrowserModule::setSelectedBrowser(const std::string& id) {
if (getPair(id) || _browser3dNode->identifier() == id) {
if (getPair(id) || (_browser3dNode && _browser3dNode->identifier() == id)) {
_selectedBrowser = id;
}
}

View File

@@ -29,7 +29,6 @@
#include <modules/skybrowser/include/pair.h>
#include <modules/skybrowser/include/screenspaceskytarget.h>
#include <modules/skybrowser/include/wwtdatahandler.h>
//#include <modules/skybrowser/include/screenspaceskybrowser.h>
#include <modules/base/rendering/screenspaceimagelocal.h>
#include <openspace/documentation/documentation.h>
#include <openspace/scene/scenegraphnode.h>
@@ -39,7 +38,6 @@
namespace openspace {
class ScreenSpaceSkyBrowser;
class RenderableSkyBrowser;
enum class Transparency {
@@ -59,7 +57,7 @@ public:
// Getters
std::vector<Pair>& getPairs();
Pair* getPair(std::string id);
Pair* getPair(const std::string& id);
SceneGraphNode* get3dBrowserNode();
RenderableSkyBrowser* get3dBrowser();
RenderableSkyBrowser* get3dBrowser(const std::string& id);
@@ -68,7 +66,6 @@ public:
// Setters
void set3dBrowser(const std::string& id);
void setSelectedBrowser(ScreenSpaceSkyBrowser* ptr);
void setSelectedBrowser(const std::string& id);
void selectImage2dBrowser(int i);
void selectImage3dBrowser(int i);

View File

@@ -147,6 +147,7 @@ namespace openspace {
}
void Browser::update() {
if (_isUrlDirty) {
_browserInstance->loadUrl(_url);
_isUrlDirty = false;

View File

@@ -167,7 +167,7 @@ namespace openspace {
void Pair::selectImage(const ImageData& image, int i)
{
// Load image into browser
_browser->addSelectedImage(image.imageUrl, i);
_browser->displayImage(image.imageUrl, i);
// If the image has coordinates, move the target
if (image.hasCelestialCoords) {
@@ -185,21 +185,23 @@ namespace openspace {
void Pair::loadImages(std::string collection)
{
_browser->sendMessageToWwt(wwtmessage::loadCollection(collection));
_browser->setHasLoadedImages(true);
_browser->loadImageCollection(collection);
}
void Pair::setImageOpacity(const int i, float opacity)
{
ghoul::Dictionary msg = wwtmessage::setImageOpacity(std::to_string(i), opacity);
_browser->sendMessageToWwt(msg);
_browser->setImageOpacity(i, opacity);
}
void Pair::sendIdToBrowser()
{
_browser->sendIdToBrowser();
_browser->setIdInBrowser();
}
#pragma optimize("", off)
void Pair::updateBrowserSize() {
_browser->updateBrowserSize();
}
void Pair::incrementallyAnimateToCoordinate(double deltaTime)
{
// Animate the target before the field of view starts to animate

View File

@@ -1,335 +0,0 @@
#include <modules/skybrowser/include/ScreenSpaceSkyBrowser2.h>
#include <modules/skybrowser/include/screenspaceskytarget.h>
#include <modules/skybrowser/include/utility.h>
#include <openspace/engine/globals.h>
#include <openspace/rendering/renderengine.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/dictionaryjsonformatter.h> // formatJson
#include <ghoul/opengl/texture.h>
#include <optional>
namespace {
constexpr const char* _loggerCat = "ScreenSpaceSkyBrowser2";
constexpr const openspace::properties::Property::PropertyInfo BrowserDimensionInfo =
{
"BrowserDimensions",
"Browser Dimensions",
"The pixel dimensions of the sky browser."
};
constexpr const openspace::properties::Property::PropertyInfo TargetIdInfo =
{
"TargetId",
"Target Id",
"The identifier of the target. It is used to synchronize the sky browser and the"
"sky target."
};
constexpr const openspace::properties::Property::PropertyInfo BorderColorInfo =
{
"BorderColor",
"Border Color",
"The color of the border of the sky browser."
};
constexpr const openspace::properties::Property::PropertyInfo VerticalFovInfo =
{
"VerticalFieldOfView",
"Vertical Field Of View",
"The vertical field of view in degrees."
};
struct [[codegen::Dictionary(ScreenSpaceSkyBrowser2)]] Parameters {
// [[codegen::verbatim(BrowserDimensionInfo.description)]]
std::optional<glm::vec2> browserDimensions;
// [[codegen::verbatim(VerticalFovInfo.description)]]
std::optional<float> verticalFov;
// [[codegen::verbatim(TargetIdInfo.description)]]
std::optional<std::string> targetId;
// [[codegen::verbatim(BorderColorInfo.description)]]
std::optional<glm::ivec3> borderColor;
};
#include "ScreenSpaceSkyBrowser2_codegen.cpp"
} // namespace
namespace openspace {
ScreenSpaceSkyBrowser2::ScreenSpaceSkyBrowser2(const ghoul::Dictionary& dictionary)
: ScreenSpaceRenderable(dictionary),
WwtCommunicator(dictionary)
, _skyTargetId(TargetIdInfo)
{
// Make the color property display a color picker in the GUI
_borderColor.setViewOption("Color", true);
// Handle target dimension property
const Parameters p = codegen::bake<Parameters>(dictionary);
_verticalFov = p.verticalFov.value_or(_verticalFov);
_borderColor = p.borderColor.value_or(_borderColor);
_skyTargetId = p.targetId.value_or(_skyTargetId);
addProperty(_dimensions);
addProperty(_verticalFov);
addProperty(_borderColor);
addProperty(_skyTargetId);
_verticalFov.onChange([&]() {
if (_skyTarget) {
_skyTarget->setScale(_verticalFov);
}
});
_borderColor.onChange([&]() {
setWebpageBorderColor(_borderColor.value());
});
_skyTargetId.onChange([&]() {
connectToSkyTarget();
});
// Set a unique identifier
std::string identifier;
if (dictionary.hasValue<std::string>(KeyIdentifier)) {
identifier = dictionary.value<std::string>(KeyIdentifier);
}
else {
identifier = "ScreenSpaceSkyBrowser22";
}
identifier = makeUniqueIdentifier(identifier);
setIdentifier(identifier);
glm::vec2 screenPosition = _cartesianPosition.value();
_cartesianPosition.setValue(glm::vec3(screenPosition, skybrowser::ScreenSpaceZ));
// Always make sure that the target and browser are visible together
_enabled.onChange([&]() {
if (_skyTarget) {
_skyTarget->property("Enabled")->set(_enabled.value());
}
});
// Ensure the color of the border is bright enough.
// Make sure the RGB color at least is 50% brightness
// By making each channel 50% bright in general
// 222 = sqrt(3*(0.5*256)^2)
while (glm::length(glm::vec3(_borderColor.value())) < 222.f) {
_borderColor = glm::vec3(rand() % 256, rand() % 256, rand() % 256);
}
}
ScreenSpaceSkyBrowser2::~ScreenSpaceSkyBrowser2() {
// Set flag to false so the thread can exit
_isSyncedWithWwt = false;
if (_wwtMessages.joinable()) {
_wwtMessages.join();
LINFO("Joined thread");
}
}
bool ScreenSpaceSkyBrowser2::initializeGL() {
return Browser::initializeGL() && ScreenSpaceRenderable::initializeGL();
}
void ScreenSpaceSkyBrowser2::startSyncingWithWwt() {
// If the camera is already synced, the browser is already syncing
if (!_isSyncedWithWwt) {
_isSyncedWithWwt = true;
// Set border color
setWebpageBorderColor(_borderColor.value());
// Track target
syncWwtView();
}
}
glm::dvec2 ScreenSpaceSkyBrowser2::fineTuneVector(glm::dvec2 drag) {
// Fine tuning of target
glm::dvec2 wwtFov = fieldsOfView();
glm::dvec2 openSpaceFOV = skybrowser::fovWindow();
glm::dvec2 browserDim = screenSpaceDimensions();
glm::dvec2 angleResult = wwtFov * (drag / browserDim);
glm::dvec2 resultRelativeOs = angleResult / openSpaceFOV;
// Convert to screen space coordinate system
glm::dvec2 convertToScreenSpace{ (2 * skybrowser::windowRatio()), 2.f };
glm::dvec2 result = - convertToScreenSpace * resultRelativeOs;
return result;
}
/*
void ScreenSpaceBrowser::setXCallback(std::function<void()> callback) {
_originalDimensions.onChange(std::move(callback));
}
*/
bool ScreenSpaceSkyBrowser2::deinitializeGL() {
// Set flag to false so the thread can exit
_isSyncedWithWwt = false;
if (_wwtMessages.joinable()) {
_wwtMessages.join();
LINFO("Joined thread");
}
return Browser::deinitializeGL() && ScreenSpaceRenderable::deinitializeGL();
}
bool ScreenSpaceSkyBrowser2::connectToSkyTarget() {
_skyTarget = dynamic_cast<ScreenSpaceSkyTarget*>(
global::renderEngine->screenSpaceRenderable(_skyTargetId.value()));
return _skyTarget;
}
bool ScreenSpaceSkyBrowser2::isAnimated()
{
return _isFovAnimated;
}
void ScreenSpaceSkyBrowser2::startFovAnimation(float fov)
{
_isFovAnimated = true;
_endVfov = fov;
}
void ScreenSpaceSkyBrowser2::incrementallyAnimateToFov(float deltaTime)
{
// If distance too large, keep animating. Else, stop animation
float diff = verticalFov() - _endVfov;
const bool shouldAnimate = abs(diff) > _fovDiff;
if (shouldAnimate) {
setVerticalFovWithScroll(diff);
}
else {
_isFovAnimated = false;
}
}
void ScreenSpaceSkyBrowser2::render() {
Browser::render();
draw(
globalRotationMatrix() *
translationMatrix() *
localRotationMatrix() *
scaleMatrix()
);
}
void ScreenSpaceSkyBrowser2::update() {
Browser::update();
ScreenSpaceRenderable::update();
}
ScreenSpaceSkyTarget* ScreenSpaceSkyBrowser2::getSkyTarget() {
return _skyTarget;
}
void ScreenSpaceSkyBrowser2::setVerticalFovWithScroll(float scroll) {
// Cap how often the zoom is allowed to update
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
std::chrono::system_clock::duration timeSinceLastUpdate = now - _lastUpdateTime;
if (timeSinceLastUpdate > _timeUpdateInterval) {
// Make scroll more sensitive the smaller the FOV
float x = _verticalFov;
float zoomFactor = atan(x / 50.0) + exp(x / 40) - 0.999999;
float zoom = scroll > 0.0 ? -zoomFactor : zoomFactor;
_verticalFov = std::clamp(_verticalFov + zoom, 0.001f, 70.0f);
_lastUpdateTime = std::chrono::system_clock::now();
}
}
void ScreenSpaceSkyBrowser2::syncWwtView() {
// Start a thread to enable user interaction while sending the calls to WWT
_wwtMessages = std::thread([&] {
while (_isSyncedWithWwt) {
if (_skyTarget) {
// Message WorldWide Telescope current view
glm::dvec3 cartesian = _skyTarget->directionEquatorial();
ghoul::Dictionary message = wwtmessage::moveCamera(
skybrowser::cartesianToSpherical(cartesian),
_verticalFov,
skybrowser::cameraRoll()
);
sendMessageToWwt(message);
}
// Sleep so we don't bombard WWT with too many messages
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
});
}
glm::ivec2 ScreenSpaceSkyBrowser2::isOnResizeArea(glm::vec2 coord) {
glm::ivec2 resizePosition = glm::ivec2{ 0 };
// Make sure coordinate is on browser
if (!coordIsInsideCornersScreenSpace(coord)) return resizePosition;
// TO DO: turn this into a vector and use prettier vector arithmetic
float resizeAreaY = screenSpaceDimensions().y * _resizeAreaPercentage;
float resizeAreaX = screenSpaceDimensions().x * _resizeAreaPercentage;
const bool isOnTop = coord.y > upperRightCornerScreenSpace().y - resizeAreaY;
const bool isOnBottom = coord.y < lowerLeftCornerScreenSpace().y + resizeAreaY;
const bool isOnRight = coord.x > upperRightCornerScreenSpace().x - resizeAreaX;
const bool isOnLeft = coord.x < lowerLeftCornerScreenSpace().x + resizeAreaX;
resizePosition.x = isOnRight ? 1 : isOnLeft ? -1 : 0;
resizePosition.y = isOnTop ? 1 : isOnBottom ? -1 : 0;
return resizePosition;
}
// Scales the ScreenSpaceBrowser to a new ratio
void ScreenSpaceSkyBrowser2::setScale(glm::vec2 scalingFactor) {
// Scale on the y axis, this is to ensure that _scale = 1 is
// equal to the height of the window
setScale(abs(scalingFactor.y));
// Resize the dimensions of the texture on the x axis
glm::vec2 newSize = abs(scalingFactor) * _originalDimensions;
_texture->setDimensions(glm::ivec3(newSize, 1));
_objectSize = _texture->dimensions();
}
glm::mat4 ScreenSpaceSkyBrowser2::scaleMatrix() {
// To ensure the plane has the right ratio
// The _scale tells us how much of the windows height the
// browser covers: e.g. a browser that covers 0.25 of the
// height of the window will have scale = 0.25
float textureRatio = static_cast<float>(_texture->dimensions().x) /
static_cast<float>(_texture->dimensions().y);
glm::mat4 scale = glm::scale(
glm::mat4(1.f),
glm::vec3(textureRatio * _scale, _scale, 1.f)
);
return scale;
}
void ScreenSpaceSkyBrowser2::saveResizeStartSize() {
_originalDimensions = _dimensions.value();
_originalScale = _scale.value();
}
// Updates the browser size to match the size of the texture
void ScreenSpaceSkyBrowser2::updateBrowserSize() {
_dimensions = _texture->dimensions();
}
void ScreenSpaceSkyBrowser2::setScale(float scalingFactor) {
_scale = _originalScale * scalingFactor;
}
properties::FloatProperty& ScreenSpaceSkyBrowser2::getOpacity() {
return _opacity;
}
void ScreenSpaceSkyBrowser2::bindTexture() {
_texture->bind();
}
}

View File

@@ -130,7 +130,7 @@ namespace openspace {
return _hasLoadedImages;
}
void WwtCommunicator::setImageLayerOrder(int i, int order) {
void WwtCommunicator::setImageOrder(int i, int order) {
// Find in selected images list
auto current = std::find(
std::begin(_selectedImages),
@@ -151,6 +151,16 @@ namespace openspace {
sendMessageToWwt(message);
}
void WwtCommunicator::loadImageCollection(const std::string& collection) {
sendMessageToWwt(wwtmessage::loadCollection(collection));
_hasLoadedImages = true;
}
void WwtCommunicator::setImageOpacity(const int i, float opacity) {
ghoul::Dictionary msg = wwtmessage::setImageOpacity(std::to_string(i), opacity);
sendMessageToWwt(msg);
}
void WwtCommunicator::setHasLoadedImages(bool isLoaded) {
_hasLoadedImages = isLoaded;
}