Make it possible to add many browsers and targets by moving functionality to ScreenSpaceRenderable

This commit is contained in:
Ylva Selling
2021-03-23 09:44:14 +01:00
parent ac275140c5
commit fbc05244e1
8 changed files with 158 additions and 156 deletions

View File

@@ -71,6 +71,18 @@ public:
bool isEnabled() const;
float depth();
// Added by skybrowser team
// Screen space functionality in these coords: [-1,1][-ratio,ratio]
glm::vec2 getScreenSpacePosition();
glm::vec2 getScreenSpaceDimensions();
glm::vec2 getUpperRightCornerScreenSpace();
glm::vec2 getLowerLeftCornerScreenSpace();
bool coordIsInsideCornersScreenSpace(glm::vec2 coord);
void translate(glm::vec2 translation, glm::vec2 position);
friend bool operator<(const ScreenSpaceRenderable& lhs, const ScreenSpaceRenderable& rhs);
// End of addition by skybrowser team
static documentation::Documentation Documentation();
protected:

View File

@@ -30,17 +30,12 @@ namespace openspace {
void scrollZoom(float scroll);
// Translation
void translate(glm::vec2 translation);
void translate(glm::vec2 translation, glm::vec2 position);
//void translate(glm::vec2 translation);
// Position and dimension and corners
glm::vec2 getScreenSpacePosition();
glm::vec2 getScreenSpaceDimensions();
glm::vec2 getUpperRightCornerScreenSpace();
glm::vec2 getLowerLeftCornerScreenSpace();
glm::vec2 getScreenSpaceBrowserDimension();
// Mouse interaction
bool coordIsInsideCornersScreenSpace(glm::vec2 coord);
glm::vec2 coordIsOnResizeArea(glm::vec2 coord);
// Scaling
void scale(glm::vec2 scalingFactor);
@@ -54,7 +49,7 @@ namespace openspace {
properties::FloatProperty _fieldOfView;
properties::StringProperty _skyTargetID;
private:
glm::vec2 _startSize;
glm::vec2 _startDimensionsSize;
float _startScale;
properties::Vec2Property _browserDimensions;
bool _camIsSyncedWWT;

View File

@@ -32,6 +32,7 @@ namespace openspace {
void createShaders();
void setBrowser(ScreenSpaceSkyBrowser* browser);
ScreenSpaceSkyBrowser* getSkyBrowser();
void setDimensions(glm::vec2 currentBrowserDimensions);
void updateFOV(float fov);

View File

@@ -31,14 +31,13 @@
#include <openspace/engine/moduleengine.h>
#include <openspace/engine/globals.h>
#include <openspace/engine/globalscallbacks.h>
#include <openspace/interaction/navigationhandler.h>
#include <openspace/engine/windowdelegate.h>
#include <openspace/engine/windowdelegate.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/interaction/navigationhandler.h>
#include <openspace/scene/scene.h>
#include <openspace/util/factorymanager.h>
#include "skybrowsermodule_lua.inl"
#include <openspace/engine/windowdelegate.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/opengl/texture.h>
#include <cmath> // For atan2
@@ -46,26 +45,18 @@
#include <ghoul/filesystem/filesystem.h>
namespace {
constexpr const openspace::properties::Property::PropertyInfo ShowSkyBrowserInfo =
{
"Show Sky Browser",
"Show Sky Browser",
"Show sky browser and target for WorldWide Telescope imagery."
};
struct [[codegen::Dictionary(ScreenSpaceSkyBrowser)]] Parameters {
struct [[codegen::Dictionary(SkyBrowserModule)]] Parameters {
// [[codegen::verbatim(ShowSkyBrowserInfo.description)]]
std::optional<bool> show;
};
#include "skybrowsermodule_codegen.cpp"
} // namespace
namespace openspace {
scripting::LuaLibrary SkyBrowserModule::luaLibrary() const {
scripting::LuaLibrary res;
@@ -111,74 +102,66 @@ namespace openspace {
SkyBrowserModule::SkyBrowserModule()
: OpenSpaceModule(SkyBrowserModule::Name)
, _showBrowserAndTarget(ShowSkyBrowserInfo)
, _skyBrowser(nullptr)
, _skyTarget(nullptr)
, currentlyDraggingBrowser(false)
, currentlyDraggingTarget(false)
, _mouseOnObject(nullptr)
, currentlyResizingBrowser(false)
, mouseIsOnBrowser(false)
, mouseIsOnTarget(false)
, currentlyDraggingObject(false)
, resizeVector(0.f, 0.f)
, shouldInitialize(true)
{
addProperty(_showBrowserAndTarget);
_showBrowserAndTarget.onChange([&]() {
if (_showBrowserAndTarget) {
_skyBrowser->setConnectedTarget();
_skyTarget->setConnectedBrowser();
}
});
global::callback::mousePosition->emplace_back(
[&](double x, double y) {
[&](double x, double y) {
// Quick fix to make all renderables find its corresponding partner
if (shouldInitialize) {
std::for_each(renderables.begin(), renderables.end(), [&](ScreenSpaceRenderable* obj) {
if (to_target(obj)) {
to_target(obj)->setConnectedBrowser();
}
else if (to_browser(obj)) {
to_browser(obj)->setConnectedTarget();
}
});
shouldInitialize = false;
}
glm::vec2 pos = glm::vec2(static_cast<float>(x), static_cast<float>(y));
_mousePosition = getMousePositionInScreenSpaceCoords(pos);
if (_skyTarget) {
mouseIsOnTarget = _skyTarget->coordIsInsideCornersScreenSpace(_mousePosition);
if (currentlyDraggingObject) {
_mouseOnObject->translate(_mousePosition - startDragMousePos, startDragObjectPos);
}
else {
mouseIsOnTarget = false;
}
if (_skyBrowser) {
mouseIsOnBrowser = _skyBrowser->coordIsInsideCornersScreenSpace(_mousePosition);
}
else {
mouseIsOnBrowser = false;
}
if (currentlyDraggingBrowser) {
_skyBrowser->translate(_mousePosition - startDragMousePosBrowser, startDragObjectPosBrowser);
}
if (currentlyDraggingTarget) {
_skyTarget->translate(_mousePosition - startDragMousePosTarget, startDragObjectPosTarget);
}
if (currentlyResizingBrowser) {
else if (currentlyResizingBrowser) {
// Calculate scaling factor
glm::vec2 mouseDragVector = (_mousePosition - startDragMousePosBrowser);
glm::vec2 mouseDragVector = (_mousePosition - startDragMousePos);
glm::vec2 scalingVector = mouseDragVector * resizeVector;
glm::vec2 newSizeRelToOld = (startResizeBrowserSize + (scalingVector)) / startResizeBrowserSize;
_skyBrowser->scale(newSizeRelToOld);
// Scale the browser
to_browser(_mouseOnObject)->scale(newSizeRelToOld);
// For dragging functionality, translate so it looks like the browser isn't moving
// Make sure the browser doesn't move in directions it's not supposed to
_skyBrowser->translate(mouseDragVector * abs(resizeVector) / 2.f, startDragObjectPosBrowser);
// _skyTarget->setDimensions(_skyBrowser->getScreenSpaceBrowserDimension());
_mouseOnObject->translate(mouseDragVector * abs(resizeVector) / 2.f, startDragObjectPos);
}
// If there is no dragging or resizing, look for new objects
else {
auto currentlyOnObject = std::find_if(renderables.begin(), renderables.end(), [&](ScreenSpaceRenderable* obj) {
return obj->coordIsInsideCornersScreenSpace(_mousePosition);
});
_mouseOnObject = currentlyOnObject != renderables.end() ? *currentlyOnObject : nullptr;
}
}
);
global::callback::mouseScrollWheel->emplace_back(
[&](double, double scroll) -> bool {
if (mouseIsOnBrowser) {
_skyBrowser->scrollZoom(scroll);
// If mouse is on browser, apply zoom
if (to_browser(_mouseOnObject)) {
to_browser(_mouseOnObject)->scrollZoom(scroll);
return true;
}
else if (to_target(_mouseOnObject) && to_target(_mouseOnObject)->getSkyBrowser()) {
to_target(_mouseOnObject)->getSkyBrowser()->scrollZoom(scroll);
}
return false;
}
);
@@ -187,52 +170,42 @@ SkyBrowserModule::SkyBrowserModule()
[&](MouseButton button, MouseAction action, KeyModifier modifier) -> bool {
if (action == MouseAction::Press) {
if (mouseIsOnBrowser && button == MouseButton::Left) {
startDragMousePosBrowser = _mousePosition;
startDragObjectPosBrowser = _skyBrowser->getScreenSpacePosition();
// Resize browser if mouse is over resize button
resizeVector = _skyBrowser->coordIsOnResizeArea(_mousePosition);
if (resizeVector != glm::vec2{0}) {
_skyBrowser->saveResizeStartSize();
startResizeBrowserSize = _skyBrowser->getScreenSpaceDimensions();
currentlyResizingBrowser = true;
if (_mouseOnObject && button == MouseButton::Left) {
startDragMousePos = _mousePosition;
startDragObjectPos = _mouseOnObject->getScreenSpacePosition();
// If current object is browser, check for resizing
if (to_browser(_mouseOnObject)) {
// Resize browser if mouse is over resize button
resizeVector = to_browser(_mouseOnObject)->coordIsOnResizeArea(_mousePosition);
if (resizeVector != glm::vec2{ 0 }) {
to_browser(_mouseOnObject)->saveResizeStartSize();
startResizeBrowserSize = to_browser(_mouseOnObject)->getScreenSpaceDimensions();
currentlyResizingBrowser = true;
return true;
}
}
else {
currentlyDraggingBrowser = true;
}
currentlyDraggingObject = true;
return true;
}
else if (mouseIsOnTarget && button == MouseButton::Left) {
startDragMousePosTarget = _mousePosition;
startDragObjectPosTarget = _skyTarget->getScreenSpacePosition();
currentlyDraggingTarget = true;
return true;
}
else if (mouseIsOnBrowser && button == MouseButton::Right) {
else if (to_browser(_mouseOnObject) && button == MouseButton::Right) {
startDragMousePosTarget = _mousePosition;
startDragObjectPosTarget = _skyTarget->getScreenSpacePosition();
currentlyDraggingTarget = true;
//startDragMousePos = _mousePosition;
//startDragObjectPos = dynamic_cast<ScreenSpaceSkyBrowser*>(_mouseOnObject)->->getScreenSpacePosition();
//currentlyDraggingObject = true;
return true;
}
}
else if (action == MouseAction::Release) {
if (currentlyDraggingBrowser) {
currentlyDraggingBrowser = false;
return true;
}
if (currentlyDraggingTarget) {
currentlyDraggingTarget = false;
if (currentlyDraggingObject) {
currentlyDraggingObject = false;
return true;
}
if (currentlyResizingBrowser) {
currentlyResizingBrowser = false;
_skyBrowser->updateBrowserSize();
to_browser(_mouseOnObject)->updateBrowserSize();
return true;
}
}
@@ -250,7 +223,6 @@ void SkyBrowserModule::internalDeinitialize() {
void SkyBrowserModule::internalInitialize(const ghoul::Dictionary& dict) {
const Parameters p = codegen::bake<Parameters>(dict);
_showBrowserAndTarget = p.show.value_or(_showBrowserAndTarget);
// register ScreenSpaceBrowser
auto fScreenSpaceRenderable = FactoryManager::ref().factory<ScreenSpaceRenderable>();
@@ -274,13 +246,17 @@ glm::vec2 SkyBrowserModule::getMousePositionInScreenSpaceCoords(glm::vec2& mouse
return screenSpacePos;
}
void SkyBrowserModule::addSkyBrowser(ScreenSpaceSkyBrowser* browser) {
_skyBrowser = browser;
void SkyBrowserModule::addRenderable(ScreenSpaceRenderable* object) {
renderables.push_back(object);
// Sort on z coordinate, objects closer to camera are in beginning of list
std::sort(renderables.begin(), renderables.end());
}
void SkyBrowserModule::addSkyTarget(ScreenSpaceSkyTarget* target) {
_skyTarget = target;
ScreenSpaceSkyBrowser* SkyBrowserModule::to_browser(ScreenSpaceRenderable* ptr) {
return dynamic_cast<ScreenSpaceSkyBrowser*>(ptr);
}
ScreenSpaceSkyTarget* SkyBrowserModule::to_target(ScreenSpaceRenderable* ptr) {
return dynamic_cast<ScreenSpaceSkyTarget*>(ptr);
}

View File

@@ -38,6 +38,7 @@ namespace openspace {
class ScreenSpaceSkyBrowser;
class ScreenSpaceSkyTarget;
class ScreenSpaceRenderable;
class SkyBrowserModule : public OpenSpaceModule {
public:
@@ -46,30 +47,34 @@ public:
SkyBrowserModule();
virtual ~SkyBrowserModule() = default;
glm::vec2 getMousePositionInScreenSpaceCoords(glm::vec2& mousePos);
void addRenderable(ScreenSpaceRenderable* object);
void addSkyBrowser(ScreenSpaceSkyBrowser* browser);
void addSkyTarget(ScreenSpaceSkyTarget* target);
scripting::LuaLibrary luaLibrary() const override;
//std::vector<documentation::Documentation> documentations() const override;
protected:
void internalInitialize(const ghoul::Dictionary& dict) override;
void internalDeinitialize() override;
properties::BoolProperty _showBrowserAndTarget;
ScreenSpaceSkyBrowser* _skyBrowser;
ScreenSpaceSkyTarget* _skyTarget;
glm::vec2 startDragMousePosBrowser;
glm::vec2 startDragObjectPosBrowser;
glm::vec2 startDragMousePosTarget;
glm::vec2 startDragObjectPosTarget;
// Using snake case on these casting functions to make them similar to eg std::to_string
ScreenSpaceSkyBrowser* to_browser(ScreenSpaceRenderable* ptr);
ScreenSpaceSkyTarget* to_target(ScreenSpaceRenderable* ptr);
bool shouldInitialize;
// Renderable vector and ptr to where mouse is
std::vector<ScreenSpaceRenderable*> renderables;
ScreenSpaceRenderable* _mouseOnObject;
// Dragging
glm::vec2 startDragMousePos;
glm::vec2 startDragObjectPos;
// Resizing
glm::vec2 startResizeBrowserSize;
glm::vec2 resizeVector;
bool currentlyDraggingBrowser;
bool currentlyResizingBrowser;
bool currentlyDraggingTarget;
// The current mouse position in screenspace coordinates
glm::vec2 _mousePosition;
bool mouseIsOnBrowser;
bool mouseIsOnTarget;
// Current interaction status
bool currentlyResizingBrowser;
bool currentlyDraggingObject;
};
} // namespace openspace

View File

@@ -61,6 +61,7 @@ namespace {
} // namespace
namespace openspace {
ScreenSpaceSkyBrowser::ScreenSpaceSkyBrowser(const ghoul::Dictionary& dictionary)
: ScreenSpaceBrowser(dictionary)
, _browserDimensions(BrowserDimensionInfo, _dimensions, glm::ivec2(0.f), glm::ivec2(300.f))
@@ -115,7 +116,7 @@ namespace openspace {
}
bool ScreenSpaceSkyBrowser::initializeGL() {
global::moduleEngine->module<SkyBrowserModule>()->addSkyBrowser(this);
global::moduleEngine->module<SkyBrowserModule>()->addRenderable(this);
setConnectedTarget();
if (_skyTarget) {
_skyTarget->setDimensions(getScreenSpaceBrowserDimension());
@@ -229,13 +230,13 @@ namespace openspace {
// Sleep so we don't bombard WWT with too many messages
std::this_thread::sleep_for(std::chrono::milliseconds(50));
sendMessageToWWT(message);
}
});
}
glm::dvec2 ScreenSpaceSkyBrowser::convertGalacticToCelestial(glm::dvec3 rGal) const {
glm::dvec2 ScreenSpaceSkyBrowser::convertGalacticToCelestial(glm::dvec3 rGal) const {
// Used the math from this website: https://gea.esac.esa.int/archive/documentation/GD -->
// R2/Data_processing/chap_cu3ast/sec_cu3ast_intro/ssec_cu3ast_intro_tansforms.html#SSS1
const glm::dmat3 conversionMatrix = glm::dmat3({
@@ -252,37 +253,14 @@ namespace openspace {
return glm::dvec2(glm::degrees(ra), glm::degrees(dec));
}
/*
void ScreenSpaceSkyBrowser::translate(glm::vec2 translation) {
glm::vec3 position = _cartesianPosition;
_cartesianPosition = glm::translate(glm::mat4(1.f), glm::vec3(translation, 0.0f)) * glm::vec4(position, 1.0f);
}
}*/
void ScreenSpaceSkyBrowser::translate(glm::vec2 translation, glm::vec2 position) {
_cartesianPosition = glm::translate(glm::mat4(1.f), glm::vec3(translation, 0.0f)) * glm::vec4(position, _cartesianPosition.value().z, 1.0f);
}
glm::vec2 ScreenSpaceSkyBrowser::getScreenSpacePosition() {
return glm::vec2(_cartesianPosition.value().x, _cartesianPosition.value().y);
}
glm::vec2 ScreenSpaceSkyBrowser::getScreenSpaceDimensions() {
return glm::vec2(2.f*_scale* static_cast<float>(_objectSize.x) / static_cast<float>(_objectSize.y), 2.f*_scale);
}
glm::vec2 ScreenSpaceSkyBrowser::getUpperRightCornerScreenSpace() {
return getScreenSpacePosition() + (getScreenSpaceDimensions()/2.0f);
}
glm::vec2 ScreenSpaceSkyBrowser::getLowerLeftCornerScreenSpace() {
return getScreenSpacePosition() - (getScreenSpaceDimensions()/2.0f);
}
bool ScreenSpaceSkyBrowser::coordIsInsideCornersScreenSpace(glm::vec2 coord) {
bool lessThanUpperRight = coord.x < getUpperRightCornerScreenSpace().x && coord.y < getUpperRightCornerScreenSpace().y;
bool moreThanLowerLeft = coord.x > getLowerLeftCornerScreenSpace().x && coord.y > getLowerLeftCornerScreenSpace().y;
return lessThanUpperRight && moreThanLowerLeft;
}
glm::vec2 ScreenSpaceSkyBrowser::coordIsOnResizeArea(glm::vec2 coord) {
glm::vec2 resizePosition = glm::vec2{ 0 };
@@ -308,7 +286,7 @@ namespace openspace {
// equal to the height of the window
scale(abs(scalingFactor.y));
// Resize the dimensions of the texture on the x axis
glm::vec2 newSize = abs(scalingFactor) * _startSize;
glm::vec2 newSize = abs(scalingFactor) * _startDimensionsSize;
_texture->setDimensions(glm::ivec3(newSize, 1));
_objectSize = _texture->dimensions();
_browserDimensions = newSize;
@@ -330,9 +308,10 @@ namespace openspace {
}
void ScreenSpaceSkyBrowser::saveResizeStartSize() {
_startSize = glm::vec2(_dimensions.value().x, _dimensions.value().y);
_startDimensionsSize = glm::vec2(_dimensions.value().x, _dimensions.value().y);
_startScale = _scale.value();
}
// Updates the browser size to match the size of the texture
void ScreenSpaceSkyBrowser::updateBrowserSize() {
_dimensions = _texture->dimensions();

View File

@@ -92,7 +92,7 @@ namespace openspace {
identifier = makeUniqueIdentifier(identifier);
setIdentifier(identifier);
_cartesianPosition.setValue(glm::vec3(_cartesianPosition.value().x, _cartesianPosition.value().y, -2.1f));
_cartesianPosition.setValue(glm::vec3(_cartesianPosition.value().x, _cartesianPosition.value().y, -2.11f));
}
@@ -115,7 +115,7 @@ namespace openspace {
}
bool ScreenSpaceSkyTarget::initializeGL() {
global::moduleEngine->module<SkyBrowserModule>()->addSkyTarget(this);
global::moduleEngine->module<SkyBrowserModule>()->addRenderable(this);
setConnectedBrowser();
@@ -175,6 +175,10 @@ namespace openspace {
_skyBrowser = browser;
}
ScreenSpaceSkyBrowser* ScreenSpaceSkyTarget::getSkyBrowser() {
return _skyBrowser;
}
void ScreenSpaceSkyTarget::render() {
glDisable(GL_CULL_FACE);

View File

@@ -558,6 +558,36 @@ glm::mat4 ScreenSpaceRenderable::scaleMatrix() {
return scale;
}
glm::vec2 ScreenSpaceRenderable::getScreenSpacePosition() {
return glm::vec2(_cartesianPosition.value().x, _cartesianPosition.value().y);
}
glm::vec2 ScreenSpaceRenderable::getScreenSpaceDimensions() {
return glm::vec2(2.f * _scale * static_cast<float>(_objectSize.x) / static_cast<float>(_objectSize.y), 2.f * _scale);
}
glm::vec2 ScreenSpaceRenderable::getUpperRightCornerScreenSpace() {
return getScreenSpacePosition() + (getScreenSpaceDimensions() / 2.0f);
}
glm::vec2 ScreenSpaceRenderable::getLowerLeftCornerScreenSpace() {
return getScreenSpacePosition() - (getScreenSpaceDimensions() / 2.0f);
}
bool ScreenSpaceRenderable::coordIsInsideCornersScreenSpace(glm::vec2 coord) {
bool lessThanUpperRight = coord.x < getUpperRightCornerScreenSpace().x && coord.y < getUpperRightCornerScreenSpace().y;
bool moreThanLowerLeft = coord.x > getLowerLeftCornerScreenSpace().x && coord.y > getLowerLeftCornerScreenSpace().y;
return lessThanUpperRight && moreThanLowerLeft;
}
void ScreenSpaceRenderable::translate(glm::vec2 translation, glm::vec2 position) {
_cartesianPosition = glm::translate(glm::mat4(1.f), glm::vec3(translation, 0.0f)) * glm::vec4(position, _cartesianPosition.value().z, 1.0f);
}
bool operator<(const ScreenSpaceRenderable& lhs, const ScreenSpaceRenderable& rhs) {
// Sort on depth coordinate, larger values are closer to camera
return lhs._cartesianPosition.value().z > rhs._cartesianPosition.value().z;
}
glm::mat4 ScreenSpaceRenderable::globalRotationMatrix() {
// We do not want the screen space planes to be affected by