Use Pair class to communicate with the target and browser

This commit is contained in:
sylvass
2021-11-05 10:07:30 -04:00
parent b64fc94599
commit 2b1de9eebb
11 changed files with 288 additions and 328 deletions

View File

@@ -26,10 +26,9 @@ local target = {
asset.onInitialize(function ()
openspace.addScreenSpaceRenderable(browser)
openspace.addScreenSpaceRenderable(target)
openspace.skybrowser.connectBrowserTarget(browserId)
openspace.skybrowser.connectBrowserTarget(targetId)
openspace.skybrowser.addPairToSkyBrowserModule(targetId,browserId)
openspace.skybrowser.setSelectedBrowser(browserId)
openspace.skybrowser.connectBrowserTarget(browserId)
openspace.skybrowser.setSelectedBrowser(browserId)
end)
asset.onDeinitialize(function ()

View File

@@ -25,8 +25,12 @@ namespace openspace {
// Target - browser connection
bool connectToSkyTarget();
void initializeBrowser();
glm::dvec2 fineTuneTarget(glm::dvec2 drag);
bool isAnimated();
void startFovAnimation(float fov);
void incrementallyAnimateToFov(float deltaTime);
void startSyncingWithWwt();
glm::dvec2 fineTuneVector(glm::dvec2 drag);
// Getters returning values
bool hasLoadedImages() const;
@@ -37,7 +41,7 @@ namespace openspace {
// Getters returning references
ScreenSpaceSkyTarget* getSkyTarget();
std::deque<int>& getSelectedImages();
const std::deque<int>& getSelectedImages();
properties::FloatProperty& getOpacity();
// Setters
@@ -58,7 +62,7 @@ namespace openspace {
// Communication with WorldWide Telescope
void addSelectedImage(const ImageData& image, int i);
void removeSelectedImage(const ImageData& image, int i);
void removeSelectedImage(int i);
void setImageOrder(int i, int order);
void sendMessageToWwt(const ghoul::Dictionary& msg);
void syncWwtView();
@@ -87,6 +91,9 @@ namespace openspace {
// Flags
bool _hasLoadedImages{ false };
bool _syncViewWithWwt{ false };
bool _fovIsAnimated{ false };
float _endVfov{ 0.f };
float _fovDiff{ 0.01f };
// Resizing of browser
glm::vec2 _originalDimensions;

View File

@@ -26,6 +26,7 @@ namespace openspace {
// ScreenSpaceRenderable inherited functions
bool initializeGL() override;
bool deinitializeGL() override;
bool isReady() const override;
void render() override;
glm::mat4 scaleMatrix() override;
@@ -48,19 +49,18 @@ namespace openspace {
void setOpacity(float opacity);
// Target directions
glm::dvec3 targetDirectionGalactic() const;
glm::dvec3 targetDirectionEquatorial() const;
glm::dvec3 directionGalactic() const;
glm::dvec3 directionEquatorial() const;
// Locking functionality
void lock();
void unlock();
bool isLocked();
// Animations
void startAnimation(glm::dvec3 coordsEnd, float FOVEnd, bool lockAfter = true);
void animateToCoordinate(double deltaTime);
bool animateToFov(float endFOV, float deltaTime);
// Animation
bool isAnimated();
void startAnimation(glm::dvec3 end, bool lockAfter);
void animateToCoordinate(float deltaTime);
// Display
void highlight(glm::ivec3 addition);
void removeHighlight(glm::ivec3 removal);
@@ -74,9 +74,9 @@ namespace openspace {
properties::DoubleProperty _animationSpeed;
// Flags
bool _isLocked{ false };
bool _isAnimated{ false };
bool _lockAfterAnimation{ false };
bool _isLocked{ false };
// Shader
UniformCache(modelTransform, viewProj, showCrosshair, showRectangle, lineWidth, dimensions, lineColor) _uniformCache;
@@ -91,11 +91,8 @@ namespace openspace {
glm::dvec3 _lockedCoordinates; // Spherical celestial coordinates
std::thread _lockTarget;
// Animation of target
glm::dvec3 _animationEnd; // Cartesian celestial coordinates
glm::dvec3 _animationStart; // Cartesian celestial coordinates
double _animationTime = 1.0;
float _vfovEndAnimation;
};
}

View File

@@ -42,7 +42,7 @@ namespace openspace {
// Camera roll and direction
// Camera roll is with respect to the equatorial North Pole
bool coordinateIsOutsideView(glm::dvec3 equatorial);
bool coordinateIsInView(glm::dvec3 equatorial);
float windowRatio();
double cameraRoll();
glm::vec2 pixelToScreenSpace(glm::vec2& mouseCoordinate);
@@ -50,7 +50,7 @@ namespace openspace {
glm::dvec3 cameraDirectionGalactic();
glm::dvec3 cameraDirectionEquatorial();
double angleVector(glm::dvec3 start, glm::dvec3 end);
void incrementalAnimationMatrix(glm::dmat4& rotation, glm::dvec3 start,
glm::dmat4 incrementalAnimationMatrix(glm::dvec3 start,
glm::dvec3 end, double deltaTime,
double speedFactor = 1.0);
}

View File

@@ -39,6 +39,8 @@
#include <modules/skybrowser/include/wwtdatahandler.h>
#include <modules/skybrowser/include/pair.h>
#include <modules/skybrowser/skybrowsermodule.h>
#include <modules/skybrowser/include/screenspaceskybrowser.h>
#include <modules/skybrowser/include/screenspaceskytarget.h>
#include "skybrowsermodule_lua.inl"
#include <glm/gtx/vector_angle.hpp>
#include <glm/gtx/string_cast.hpp> // For printing glm data
@@ -288,7 +290,7 @@ SkyBrowserModule::SkyBrowserModule()
}
// If you start dragging around the target, it should unlock
else {
_mouseOnPair->getTarget()->unlock();
_mouseOnPair->unlock();
}
_isDragging = true;
@@ -296,7 +298,7 @@ SkyBrowserModule::SkyBrowserModule()
}
else if (_isBrowser && button == MouseButton::Right) {
// If you start dragging around on the browser, the target should unlock
_mouseOnPair->getTarget()->unlock();
_mouseOnPair->unlock();
// Change view (by moving target) within browser if right mouse click on browser
_startMousePosition = _mousePosition;
_startDragPosition = _mouseOnPair->getTarget()->screenSpacePosition();
@@ -338,8 +340,8 @@ SkyBrowserModule::SkyBrowserModule()
if (_isResizing) {
// Calculate scaling factor
glm::vec2 mouseDragVector = (_mousePosition - _startMousePosition);
glm::vec2 scalingVector = mouseDragVector * _resizeDirection;
glm::vec2 newSizeRelToOld = (_startBrowserSize + (scalingVector)) / _startBrowserSize;
glm::vec2 scaling = mouseDragVector * _resizeDirection;
glm::vec2 newSizeRelToOld = (_startBrowserSize + (scaling)) / _startBrowserSize;
// Scale the browser
_mouseOnPair->getBrowser()->setScale(newSizeRelToOld);
@@ -358,7 +360,7 @@ SkyBrowserModule::SkyBrowserModule()
}
}
else if (_fineTuneMode) {
glm::vec2 fineTune = _mouseOnPair->getBrowser()->fineTuneTarget(translation);
glm::vec2 fineTune = _mouseOnPair->getBrowser()->fineTuneVector(translation);
_mouseOnPair->getTarget()->translate(fineTune, _startDragPosition);
}
// If there is no dragging or resizing, look for new objects
@@ -385,41 +387,41 @@ SkyBrowserModule::SkyBrowserModule()
global::callback::preSync->emplace_back([this]() {
// Disable browser and targets when camera is outside of solar system
double cameraSSBDistance = glm::length(
global::navigationHandler->camera()->positionVec3());
_cameraInSolarSystem = cameraSSBDistance < _solarSystemRadius;
glm::dvec3 cameraPos = global::navigationHandler->camera()->positionVec3();
double deltaTime = global::windowDelegate->deltaTime();
bool camWasInSolarSystem = _cameraInSolarSystem;
_cameraInSolarSystem = glm::length(cameraPos) < _solarSystemRadius;
// Fade out or in browser & target
for (Pair pair : _targetsBrowsers) {
ScreenSpaceSkyBrowser* browser = pair.getBrowser();
// If outside solar system and browser is visible
if (!_cameraInSolarSystem && browser->isEnabled()) {
bool fadingIsFinished = fadeBrowserAndTarget(true, _fadingTime, deltaTime);
// Fading flags
bool fadeIsFinished{ false };
if (_cameraInSolarSystem != camWasInSolarSystem) {
_isTransitioningVizMode = true;
if (fadingIsFinished) {
pair.getBrowser()->property("Enabled")->set(false);
// Select the 3D browser when moving out of the solar system
if (_browser3d != nullptr) {
_selectedBrowser = _browser3d->renderable()->identifier();
}
}
// Select the 3D browser when moving out of the solar system
if (!_cameraInSolarSystem && _browser3d != nullptr) {
_selectedBrowser = _browser3d->renderable()->identifier();
}
// If within solar system and browser is not visible
else if (_cameraInSolarSystem && !browser->isEnabled()) {
pair.getBrowser()->property("Enabled")->set(true);
// Select the first 2D browser when moving into the solar system
if (_targetsBrowsers.size() != 0) {
_selectedBrowser = std::begin(_targetsBrowsers)->getBrowser()->identifier();
}
}
// If within solar system and browser is visible
if (_cameraInSolarSystem && browser->isEnabled()) {
fadeBrowserAndTarget(false, _fadingTime, deltaTime);
}
pair.getTarget()->animateToCoordinate(deltaTime);
// Fade pairs if the camera moved in or out the solar system
if (_isTransitioningVizMode) {
if (_cameraInSolarSystem) {
fadeIsFinished = fadeBrowserTargetsToOpaque(deltaTime);
}
else {
fadeIsFinished = fadeBrowserTargetsToTransparent(deltaTime);
}
// The transition is over when the fade is finished
if (fadeIsFinished) {
_isTransitioningVizMode = false;
}
}
if (_cameraInSolarSystem) {
animateTargets(deltaTime);
}
if (_cameraIsRotating) {
rotateCamera(deltaTime);
@@ -431,7 +433,6 @@ SkyBrowserModule::SkyBrowserModule()
}
SkyBrowserModule::~SkyBrowserModule() {
delete _dataHandler;
}
void SkyBrowserModule::internalDeinitialize() {
@@ -455,7 +456,7 @@ void SkyBrowserModule::internalInitialize(const ghoul::Dictionary& dict) {
fRenderable->registerClass<RenderableSkyBrowser>("RenderableSkyBrowser");
// Create data handler dynamically to avoid the linking error that
// came up when including the include file in the module header file
_dataHandler = new WwtDataHandler();
_dataHandler = std::make_unique<WwtDataHandler>();
}
void SkyBrowserModule::setSelectedObject()
@@ -464,46 +465,52 @@ void SkyBrowserModule::setSelectedObject()
Pair* lastObj = _mouseOnPair;
// Find and save what mouse is currently hovering on
auto it = std::find_if(std::begin(_targetsBrowsers), std::end(_targetsBrowsers),[&](Pair &pair) {
auto it = std::find_if(std::begin(_targetsBrowsers), std::end(_targetsBrowsers),
[&] (Pair &pair) {
bool onBrowser = pair.getBrowser()->coordIsInsideCornersScreenSpace(_mousePosition);
bool onTarget = pair.getTarget()->coordIsInsideCornersScreenSpace(_mousePosition);
if (onBrowser || onTarget) {
_mouseOnPair = &pair;
_isBrowser = onBrowser;
return true;
if (onBrowser) {
_selectedBrowser = pair.getBrowser()->identifier();
}
return false;
_isBrowser = onBrowser;
return onBrowser || onTarget;
});
if (it == std::end(_targetsBrowsers)) {
_mouseOnPair = nullptr;
}
else {
_mouseOnPair = &(*it);
}
// Selection has changed
if (lastObj != _mouseOnPair) {
// Remove highlight
if (lastObj) {
lastObj->getBrowser()->removeHighlight(_highlightAddition);
lastObj->getTarget()->removeHighlight(_highlightAddition);
lastObj->removeHighlight(_highlightAddition);
}
// Add highlight to new selection
if (_mouseOnPair) {
_mouseOnPair->getBrowser()->highlight(_highlightAddition);
_mouseOnPair->getTarget()->highlight(_highlightAddition);
std::string id = _mouseOnPair->getBrowser()->identifier();
std::string info = "Currently selected browser is " + id;
LINFO(info + id);
_mouseOnPair->highlight(_highlightAddition);
}
}
}
void SkyBrowserModule::addTargetBrowserPair(ScreenSpaceSkyTarget* newTarget, ScreenSpaceSkyBrowser* newBrowser) {
void SkyBrowserModule::addTargetBrowserPair(std::string targetId, std::string browserId) {
ScreenSpaceSkyTarget* target = dynamic_cast<ScreenSpaceSkyTarget*>(
global::renderEngine->screenSpaceRenderable(targetId)
);
ScreenSpaceSkyBrowser* browser = dynamic_cast<ScreenSpaceSkyBrowser*>(
global::renderEngine->screenSpaceRenderable(browserId)
);
// Assert pair to have both target and browser
if (newBrowser && newTarget) {
Pair newPair(newBrowser, newTarget);
if (browser && target) {
Pair newPair(browser, target);
_targetsBrowsers.push_back(newPair);
}
}
@@ -546,21 +553,17 @@ void SkyBrowserModule::createTargetBrowserPair() {
scripting::ScriptEngine::RemoteScripting::Yes
);
openspace::global::scriptEngine->queueScript(
"openspace.skybrowser.addPairToSkyBrowserModule('" + idTarget + "','"
+ idBrowser + "');",
scripting::ScriptEngine::RemoteScripting::Yes
);
openspace::global::scriptEngine->queueScript(
"openspace.skybrowser.connectBrowserTarget('" + idBrowser + "');",
scripting::ScriptEngine::RemoteScripting::Yes
);
openspace::global::scriptEngine->queueScript(
"openspace.skybrowser.connectBrowserTarget('" + idTarget + "');",
scripting::ScriptEngine::RemoteScripting::Yes
);
openspace::global::scriptEngine->queueScript(
"openspace.skybrowser.addPairToSkyBrowserModule('" + idTarget + "','" + idBrowser + "');",
scripting::ScriptEngine::RemoteScripting::Yes
);
openspace::global::scriptEngine->queueScript(
"openspace.skybrowser.setSelectedBrowser('" + idBrowser + "');",
scripting::ScriptEngine::RemoteScripting::Yes
@@ -576,11 +579,10 @@ void SkyBrowserModule::removeTargetBrowserPair(std::string& id) {
auto it = std::remove(std::begin(_targetsBrowsers), std::end(_targetsBrowsers),
*found);
std::string browserId = found->getBrowser()->identifier();
std::string targetId = found->getTarget()->identifier();
// Remove from engine
openspace::global::scriptEngine->queueScript(
"openspace.removeScreenSpaceRenderable('" + browserId + "');",
"openspace.removeScreenSpaceRenderable('" + found->browserId() + "');",
scripting::ScriptEngine::RemoteScripting::Yes
);
@@ -606,37 +608,40 @@ void SkyBrowserModule::selectImage2dBrowser(int i)
const ImageData& image = _dataHandler->getImage(i);
// Load image into browser
LINFO("Loading image " + image.name);
selected->getBrowser()->addSelectedImage(image, i);
// If the image has coordinates, move the target
selected->selectImage(image, i);
bool isInView = skybrowser::coordinateIsInView(image.equatorialCartesian);
// If the coordinate is not in view, rotate camera
if (image.hasCelestialCoords) {
// Animate the target to the image coordinate position
selected->getTarget()->unlock();
selected->getTarget()->startAnimation(image.equatorialCartesian, image.fov);
// If the coordinate is not in view, rotate camera
if (skybrowser::coordinateIsOutsideView(image.equatorialCartesian)) {
glm::dvec3 galactic = skybrowser::equatorialToGalactic(image.equatorialCartesian);
startRotation(galactic);
if(!isInView) {
rotateCamera(skybrowser::equatorialToGalactic(image.equatorialCartesian));
}
}
}
}
void SkyBrowserModule::selectImage3dBrowser(int i)
{
const ImageData& image = _dataHandler->getImage(i);
if (_browser3d) {
RenderableSkyBrowser* browser3d = dynamic_cast<RenderableSkyBrowser*>(
_browser3d->renderable());
if (browser3d) {
browser3d->displayImage(image, i);
}
if (!_browser3d) {
return;
}
RenderableSkyBrowser* renderable = dynamic_cast<RenderableSkyBrowser*>(
_browser3d->renderable());
if (renderable) {
const ImageData& image = _dataHandler->getImage(i);
renderable->displayImage(image, i);
}
}
void SkyBrowserModule::lookAtTarget(std::string id)
{
Pair* pair = getPair(id);
if (pair) {
rotateCamera(pair->targetDirectionGalactic());
}
}
void SkyBrowserModule::moveHoverCircle(int i)
{
const ImageData& image = _dataHandler->getImage(i);
@@ -665,7 +670,7 @@ int SkyBrowserModule::nLoadedImages()
return _dataHandler->nLoadedImages();
}
const WwtDataHandler* SkyBrowserModule::getWWTDataHandler() {
const std::unique_ptr<WwtDataHandler>& SkyBrowserModule::getWWTDataHandler() {
return _dataHandler;
}
@@ -678,8 +683,8 @@ Pair* SkyBrowserModule::getPair(std::string id)
{
auto it = std::find_if(std::begin(_targetsBrowsers), std::end(_targetsBrowsers),
[&](Pair& pair) {
bool foundBrowser = pair.getBrowser()->identifier() == id;
bool foundTarget = pair.getTarget()->identifier() == id;
bool foundBrowser = pair.browserId() == id;
bool foundTarget = pair.targetId() == id;
return foundBrowser || foundTarget;
});
return &(*it);
@@ -690,6 +695,9 @@ SceneGraphNode* SkyBrowserModule::get3dBrowser() {
}
void SkyBrowserModule::lookAt3dBrowser() {
if (!_browser3d) {
return;
}
std::string id = _browser3d->identifier();
// Target camera on the 3D sky browser
openspace::global::scriptEngine->queueScript(
@@ -709,7 +717,7 @@ void SkyBrowserModule::lookAt3dBrowser() {
);
}
void SkyBrowserModule::startRotation(glm::dvec3 endAnimation) {
void SkyBrowserModule::rotateCamera(glm::dvec3 endAnimation) {
// Save coordinates to rotate to in galactic world coordinates
_endAnimation = endAnimation;
_startAnimation = skybrowser::cameraDirectionGalactic();
@@ -721,11 +729,9 @@ void SkyBrowserModule::rotateCamera(double deltaTime) {
// Find smallest angle between the two vectors
double smallestAngle = skybrowser::angleVector(_startAnimation, _endAnimation);
if(smallestAngle > _threshold) {
if(smallestAngle > _stopAnimationThreshold) {
glm::dmat4 rotMat;
skybrowser::incrementalAnimationMatrix(
rotMat,
glm::dmat4 rotMat = skybrowser::incrementalAnimationMatrix(
_startAnimation,
_endAnimation,
deltaTime,
@@ -743,61 +749,39 @@ void SkyBrowserModule::rotateCamera(double deltaTime) {
}
}
bool SkyBrowserModule::fadeBrowserAndTarget(bool makeTransparent, double fadeTime,
double deltaTime) {
float opacityDelta = static_cast<float>(deltaTime / fadeTime);
float highTreshold = 0.99f;
float lowThreshold = 0.01f;
float transparent = 0.0;
float opaque = 1.0;
if (makeTransparent) {
opacityDelta *= -1.f;
}
bool finished = true;
bool SkyBrowserModule::fadeBrowserTargetsToTransparent(double deltaTime)
{
bool fadeIsFinished{ false };
for (Pair pair : _targetsBrowsers) {
ScreenSpaceSkyBrowser* browser = pair.getBrowser();
ScreenSpaceSkyTarget* target = pair.getTarget();
bool targetFinished = true;
bool browserFinished = true;
if (target) {
target->setOpacity(target->opacity() + opacityDelta);
float opacityTarget = abs(target->opacity());
if (makeTransparent) {
targetFinished = opacityTarget < lowThreshold;
}
else {
targetFinished = opacityTarget > highTreshold;
}
if (targetFinished) {
float newOpacity = makeTransparent ? transparent : opaque;
target->setOpacity(newOpacity);
if (pair.isEnabled()) {
bool finished = pair.fadeToTransparent(_fadingTime, deltaTime);
if (finished) {
pair.disable();
}
fadeIsFinished &= finished;
}
}
return fadeIsFinished;
}
bool SkyBrowserModule::fadeBrowserTargetsToOpaque(double deltaTime)
{
bool fadeIsFinished{ false };
for (Pair pair : _targetsBrowsers) {
if (pair.isEnabled()) {
fadeIsFinished &= pair.fadeToOpaque(_fadingTime, deltaTime);
}
}
return fadeIsFinished;
}
void SkyBrowserModule::animateTargets(double deltaTime)
{
for (Pair pair : _targetsBrowsers) {
if (pair.isEnabled()) {
pair.animateToCoordinate(deltaTime);
}
// Keep fading the browsers until all are finished
browser->getOpacity() = browser->getOpacity().value() + opacityDelta;
float opacityBrowser = abs(browser->getOpacity().value());
if (makeTransparent) {
browserFinished = opacityBrowser < lowThreshold;
}
else {
browserFinished = opacityBrowser > highTreshold;
}
if (browserFinished && targetFinished) {
browser->getOpacity() = makeTransparent ? transparent : opaque;
}
else {
finished = false;
}
}
return finished;
}
void SkyBrowserModule::setSelectedBrowser(ScreenSpaceSkyBrowser* browser) {

View File

@@ -63,7 +63,7 @@ public:
std::vector<Pair>& getPairs();
Pair* getPair(std::string id);
SceneGraphNode* get3dBrowser();
const WwtDataHandler* getWWTDataHandler();
const std::unique_ptr<WwtDataHandler>& getWWTDataHandler();
std::string selectedBrowserId();
// Setters
@@ -74,9 +74,12 @@ public:
void selectImage3dBrowser(int i);
// Rotation and animation
void startRotation(glm::dvec3 endAnimation); // Pass in galactic coordinate
void lookAtTarget(std::string id);
void rotateCamera(double deltaTime);
bool fadeBrowserAndTarget(bool makeTransparent, double fadeTime, double deltaTime);
bool fadeBrowserTargetsToTransparent(double deltaTime);
bool fadeBrowserTargetsToOpaque(double deltaTime);
void animateTargets(double deltaTime);
void lookAt3dBrowser();
// Boolean functions
@@ -85,7 +88,7 @@ public:
// Managing the browsers
void createTargetBrowserPair();
void removeTargetBrowserPair(std::string& browserId);
void addTargetBrowserPair(ScreenSpaceSkyTarget* target, ScreenSpaceSkyBrowser* browser);
void addTargetBrowserPair(std::string targetId, std::string browserId);
void moveHoverCircle(int i);
// Image collection handling
@@ -105,6 +108,8 @@ protected:
void internalDeinitialize() override;
private:
void rotateCamera(glm::dvec3 endAnimation); // Pass in galactic coordinate
// The browsers and targets
std::vector<Pair> _targetsBrowsers;
Pair* _mouseOnPair{ nullptr };
@@ -124,6 +129,7 @@ private:
bool _isDragging{ false };
bool _cameraInSolarSystem{ true };
bool _cameraIsRotating = false;
bool _isTransitioningVizMode{ false };
// Mouse interaction - dragging and resizing
glm::ivec3 _highlightAddition{ 35 }; // Highlight object when mouse hovers
@@ -136,11 +142,11 @@ private:
// Animation of rotation of camera to look at coordinate galactic coordinates
glm::dvec3 _startAnimation;
glm::dvec3 _endAnimation;
double _threshold{ 0.0005 };
double _stopAnimationThreshold{ 0.0005 };
double _speed{ 1.0 };
// Data handler for the image collections
WwtDataHandler* _dataHandler;
std::unique_ptr<WwtDataHandler> _dataHandler;
};
} // namespace openspace

View File

@@ -8,8 +8,6 @@
#include <modules/base/rendering/screenspaceimagelocal.h>
#include <modules/base/rendering/renderableplaneimagelocal.h>
#include <modules/skybrowser/include/wwtdatahandler.h>
#include <modules/skybrowser/include/screenspaceskybrowser.h>
#include <modules/skybrowser/include/screenspaceskytarget.h>
#include <modules/skybrowser/include/renderableskybrowser.h>
#include <modules/skybrowser/include/pair.h>
#include <modules/skybrowser/skybrowsermodule.h>
@@ -120,12 +118,11 @@ namespace openspace::skybrowser::luascriptfunctions {
// Load the collections here because here we know that the browser can execute javascript
std::string root = "https://raw.githubusercontent.com/WorldWideTelescope/wwt-web-client/master/assets/webclient-explore-root.wtml";
ScreenSpaceSkyBrowser* browser = dynamic_cast<ScreenSpaceSkyBrowser*>(
global::renderEngine->screenSpaceRenderable(id));
if (browser && !browser->hasLoadedImages()) {
browser->sendMessageToWwt(wwtmessage::loadCollection(root));
browser->setHasLoadedImages(true);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
if (module->getPair(id)) {
module->getPair(id)->loadImages(root);
}
else {
SceneGraphNode* node = global::renderEngine->scene()->sceneGraphNode(id);
@@ -153,7 +150,7 @@ namespace openspace::skybrowser::luascriptfunctions {
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
std::vector<Pair> pairs = module->getPairs();
for (Pair pair : pairs) {
pair.getBrowser()->sendIdToBrowser();
pair.sendIdToBrowser();
}
SceneGraphNode* node = module->get3dBrowser();
if(node) {
@@ -169,20 +166,12 @@ namespace openspace::skybrowser::luascriptfunctions {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::connectBrowserTarget");
const std::string id = ghoul::lua::value<std::string>(L, 1);
// Find the ScreenSpaceRenderable that has the id
ScreenSpaceRenderable* found = global::renderEngine->screenSpaceRenderable(id);
ScreenSpaceSkyBrowser* browser = dynamic_cast<ScreenSpaceSkyBrowser*>(found);
ScreenSpaceSkyTarget* target = dynamic_cast<ScreenSpaceSkyTarget*>(found);
// Connect the target and browser to each other
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
if (module->getPair(id)) {
module->getPair(id)->connectPair();
}
// Connect it to its corresponding target / browser
if (browser) {
browser->connectToSkyTarget();
}
else if (target) {
target->findSkyBrowser();
}
return 0;
}
@@ -190,15 +179,11 @@ namespace openspace::skybrowser::luascriptfunctions {
// Initialize browser with ID and its corresponding target
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::initializeBrowser");
const std::string id = ghoul::lua::value<std::string>(L, 1);
ScreenSpaceSkyBrowser* browser = dynamic_cast<ScreenSpaceSkyBrowser*>(
global::renderEngine->screenSpaceRenderable(id));
LINFO("Initializing sky browser " + id);
if (browser) {
browser->initializeBrowser();
ScreenSpaceSkyTarget* target = browser->getSkyTarget();
if (target) {
target->findSkyBrowser();
}
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
if (module->getPair(id)) {
module->getPair(id)->synchronizeWithWwt();
}
else {
SceneGraphNode* node = global::renderEngine->scene()->sceneGraphNode(id);
@@ -240,15 +225,7 @@ namespace openspace::skybrowser::luascriptfunctions {
LINFO("Add browser " + browserId + " to sky browser module.");
LINFO("Add target " + targetId + " to sky browser module.");
ScreenSpaceSkyTarget* target = dynamic_cast<ScreenSpaceSkyTarget*>(
global::renderEngine->screenSpaceRenderable(targetId)
);
ScreenSpaceSkyBrowser* browser = dynamic_cast<ScreenSpaceSkyBrowser*>(
global::renderEngine->screenSpaceRenderable(browserId)
);
module->addTargetBrowserPair(target, browser);
module->addTargetBrowserPair(targetId, browserId);
return 0;
}
@@ -363,22 +340,20 @@ namespace openspace::skybrowser::luascriptfunctions {
std::vector<Pair> pairs = module->getPairs();
for (Pair pair : pairs) {
ScreenSpaceSkyBrowser* browser = pair.getBrowser();
ScreenSpaceSkyTarget* target = pair.getTarget();
std::string id = browser->identifier();
std::string id = pair.browserId();
// Convert deque to vector so ghoul can read it
std::vector<int> selectedImagesVector;
std::deque<int> selectedImages = browser->getSelectedImages();
const std::deque<int> selectedImages = pair.getSelectedImages();
std::for_each(selectedImages.begin(), selectedImages.end(), [&](int i) {
selectedImagesVector.push_back(i);
});
glm::dvec3 celestialCart = target->targetDirectionEquatorial();
glm::dvec3 celestialCart = pair.targetDirectionEquatorial();
glm::dvec2 celestialSpherical = skybrowser::cartesianToSpherical(celestialCart);
std::vector<double> celestialCartVec = { celestialCart.x, celestialCart.y, celestialCart.z };
// Convert color to vector so ghoul can read it
glm::ivec3 color = browser->borderColor();
glm::ivec3 color = pair.borderColor();
std::vector<int> colorVec = { color.r, color.g, color.b };
ghoul::lua::push(L, id);
@@ -386,9 +361,9 @@ namespace openspace::skybrowser::luascriptfunctions {
// Push ("Key", value)
ghoul::lua::push(L, "id", id);
lua_settable(L, -3);
ghoul::lua::push(L, "name", browser->guiName());
ghoul::lua::push(L, "name", pair.browserGuiName());
lua_settable(L, -3);
ghoul::lua::push(L, "FOV", browser->verticalFov());
ghoul::lua::push(L, "FOV", pair.verticalFov());
lua_settable(L, -3);
ghoul::lua::push(L, "selectedImages", selectedImagesVector);
lua_settable(L, -3);
@@ -400,7 +375,7 @@ namespace openspace::skybrowser::luascriptfunctions {
lua_settable(L, -3);
ghoul::lua::push(L, "color", colorVec);
lua_settable(L, -3);
ghoul::lua::push(L, "isLocked", target->isLocked());
ghoul::lua::push(L, "isLocked", pair.isLocked());
lua_settable(L, -3);
// Set table for the current target
@@ -408,7 +383,7 @@ namespace openspace::skybrowser::luascriptfunctions {
}
}
else {
else if(module->get3dBrowser()){
SceneGraphNode* node = module->get3dBrowser();
RenderableSkyBrowser* browser3d = dynamic_cast<RenderableSkyBrowser*>(
node->renderable());
@@ -458,11 +433,10 @@ namespace openspace::skybrowser::luascriptfunctions {
const std::string id = ghoul::lua::value<std::string>(L, 1);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
if(module->cameraInSolarSystem() && module->getPair(id)) {
Pair* pair = module->getPair(id);
module->startRotation(pair->getTarget()->targetDirectionGalactic());
if(module->cameraInSolarSystem()) {
module->lookAtTarget(id);
}
else if (!module->cameraInSolarSystem() && module->get3dBrowser()) {
else {
module->lookAt3dBrowser();
}
@@ -481,8 +455,8 @@ namespace openspace::skybrowser::luascriptfunctions {
// Empty 3D browser selection
browser3d->getSelectedImages().clear();
// Copy 2D selection of images to 3D browser
std::deque images = pair->getBrowser()->getSelectedImages();
std::for_each(std::begin(images), std::end(images), [&](int i) {
const std::deque<int> images = pair->getSelectedImages();
std::for_each(std::begin(images), std::end(images), [&](const int i) {
const ImageData& image = module->getWWTDataHandler()->getImage(i);
browser3d->displayImage(image, i);
});
@@ -494,14 +468,14 @@ namespace openspace::skybrowser::luascriptfunctions {
int setOpacityOfImageLayer(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::setOpacityOfImageLayer");
const std::string id = ghoul::lua::value<std::string>(L, 1);
const std::string i = std::to_string(ghoul::lua::value<int>(L, 2));
const int i = ghoul::lua::value<int>(L, 2);
double opacity = ghoul::lua::value<double>(L, 3);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
ghoul::Dictionary message = wwtmessage::setImageOpacity(i, opacity);
ghoul::Dictionary message = wwtmessage::setImageOpacity(std::to_string(i), opacity);
if (module->getPair(id)) {
Pair* pair = module->getPair(id);
pair->getBrowser()->sendMessageToWwt(message);
module->getPair(id)->setImageOpacity(i, opacity);
}
else if (module->get3dBrowser() != nullptr) {
RenderableSkyBrowser* browser3d = dynamic_cast<RenderableSkyBrowser*>(
@@ -518,13 +492,7 @@ namespace openspace::skybrowser::luascriptfunctions {
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
Pair* pair = module->getPair(id);
if (pair) {
// Animate the target to the center of the screen
pair->getTarget()->unlock();
// Get camera direction in celestial spherical coordinates
glm::dvec3 viewDirection = skybrowser::cameraDirectionEquatorial();
// Keep the current fov
float currentFov = pair->getBrowser()->verticalFov();
pair->getTarget()->startAnimation(viewDirection, currentFov, false);
pair->centerTargetOnScreen();
}
return 0;
@@ -587,11 +555,9 @@ namespace openspace::skybrowser::luascriptfunctions {
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
const ImageData& image = module->getWWTDataHandler()->getImage(i);
if (module->getPair(id)) {
Pair* pair = module->getPair(id);
// Remove image
pair->getBrowser()->removeSelectedImage(image, i);
Pair* pair = module->getPair(id);
if (pair) {
pair->removeSelectedImage(i);
}
else if (module->get3dBrowser() != nullptr) {
RenderableSkyBrowser* browser3d = dynamic_cast<RenderableSkyBrowser*>(

View File

@@ -190,7 +190,7 @@ namespace openspace {
return true;
}
void RenderableSkyBrowser::displayImage(const ImageData& image, int i) {
void RenderableSkyBrowser::displayImage(const ImageData& image, const int i) {
sendMessageToWwt(wwtmessage::moveCamera(image.equatorialSpherical, image.fov, 0.0));
_verticalFov = image.fov;
// Add to selected images if there are no duplicates

View File

@@ -174,22 +174,18 @@ namespace openspace {
setWebpageBorderColor( color - removal );
}
void ScreenSpaceSkyBrowser::initializeBrowser() {
// If the camera is already synced, the browser is already initialized
void ScreenSpaceSkyBrowser::startSyncingWithWwt() {
// If the camera is already synced, the browser is already syncing
if (!_syncViewWithWwt) {
_syncViewWithWwt = true;
// Set border color
setWebpageBorderColor(_borderColor.value());
// Connect to target if they haven't been connected
if (!_skyTarget) {
connectToSkyTarget();
}
// Track target
syncWwtView();
}
}
glm::dvec2 ScreenSpaceSkyBrowser::fineTuneTarget(glm::dvec2 drag) {
glm::dvec2 ScreenSpaceSkyBrowser::fineTuneVector(glm::dvec2 drag) {
// Fine tuning of target
glm::dvec2 wwtFov = fieldsOfView();
glm::dvec2 openSpaceFOV = skybrowser::fovWindow();
@@ -220,6 +216,29 @@ namespace openspace {
return _skyTarget;
}
bool ScreenSpaceSkyBrowser::isAnimated()
{
return _fovIsAnimated;
}
void ScreenSpaceSkyBrowser::startAnimation(float fov)
{
_fovIsAnimated = true;
_endVfov = fov;
}
void ScreenSpaceSkyBrowser::animateToFov(float deltaTime)
{
// If distance is small enough, stop animating
float diff = verticalFov() - _endVfov;
if (abs(diff) > _fovDiff) {
setVerticalFovWithScroll(diff);
}
else {
_fovIsAnimated = false;
}
}
ScreenSpaceSkyTarget* ScreenSpaceSkyBrowser::getSkyTarget() {
return _skyTarget;
}
@@ -299,7 +318,7 @@ namespace openspace {
while (_syncViewWithWwt) {
if (_skyTarget) {
// Message WorldWide Telescope current view
glm::dvec3 cartesian = _skyTarget->targetDirectionEquatorial();
glm::dvec3 cartesian = _skyTarget->directionEquatorial();
ghoul::Dictionary message = wwtmessage::moveCamera(
skybrowser::cartesianToSpherical(cartesian),
@@ -391,7 +410,7 @@ namespace openspace {
return _opacity;
}
std::deque<int>& ScreenSpaceSkyBrowser::getSelectedImages() {
const std::deque<int>& ScreenSpaceSkyBrowser::getSelectedImages() {
return _selectedImages;
}
@@ -408,7 +427,7 @@ namespace openspace {
}
}
void ScreenSpaceSkyBrowser::removeSelectedImage(const ImageData& image, int i) {
void ScreenSpaceSkyBrowser::removeSelectedImage(int i) {
// Remove from selected list
auto it = std::find(std::begin(_selectedImages), std::end(_selectedImages), i);
bool found = it != std::end(_selectedImages);

View File

@@ -188,6 +188,14 @@ namespace openspace {
return isReady();
}
bool ScreenSpaceSkyTarget::deinitializeGL()
{
if (isLocked()) {
unlock();
}
return ScreenSpaceRenderable::deinitializeGL();
}
glm::mat4 ScreenSpaceSkyTarget::scaleMatrix() {
// To ensure the plane has the right ratio
// The _scale us how much of the windows height the browser covers: e.g. a browser
@@ -268,7 +276,7 @@ namespace openspace {
_objectSize = dimensions;
}
glm::dvec3 ScreenSpaceSkyTarget::targetDirectionGalactic() const {
glm::dvec3 ScreenSpaceSkyTarget::directionGalactic() const {
glm::dmat4 rotation = glm::inverse(
global::navigationHandler->camera()->viewRotationMatrix());
glm::dvec4 position = glm::dvec4(_cartesianPosition.value(), 1.0);
@@ -301,7 +309,7 @@ namespace openspace {
unlock();
}
_isLocked = true;
_lockedCoordinates = targetDirectionEquatorial();
_lockedCoordinates = directionEquatorial();
// Start a thread to enable user interactions while locking target
_lockTarget = std::thread([&] {
@@ -315,71 +323,56 @@ namespace openspace {
return _isLocked;
}
glm::dvec3 ScreenSpaceSkyTarget::targetDirectionEquatorial() const {
bool ScreenSpaceSkyTarget::isAnimated()
{
return _isAnimated;
}
void ScreenSpaceSkyTarget::startAnimation(glm::dvec3 end, bool lockAfter)
{
_animationStart = glm::normalize(directionEquatorial());
_animationEnd = glm::normalize(end);
_lockAfterAnimation = lockAfter;
_isAnimated = true;
}
void ScreenSpaceSkyTarget::animateToCoordinate(float deltaTime)
{
// Find smallest angle between the two vectors
double smallestAngle = skybrowser::angleVector(_animationStart, _animationEnd);
// Only keep animating when target is not at final position
if (smallestAngle <= _stopAnimationThreshold) {
// Set the exact target position
_cartesianPosition = skybrowser::equatorialToScreenSpace(_animationEnd);
_isAnimated = false;
// Lock target when it first arrives to the position
if (!isLocked() && _lockAfterAnimation) {
lock();
}
return;
}
glm::dmat4 rotMat = skybrowser::incrementalAnimationMatrix(
_animationStart,
_animationEnd,
deltaTime,
_animationSpeed
);
// Rotate target direction
glm::dvec3 newDir = rotMat * glm::dvec4(_animationStart, 1.0);
// Convert to screen space
_cartesianPosition = skybrowser::equatorialToScreenSpace(newDir);
// Update position
_animationStart = glm::normalize(newDir);
}
glm::dvec3 ScreenSpaceSkyTarget::directionEquatorial() const {
// Calculate the galactic coordinate of the target direction
// projected onto the celestial sphere
return skybrowser::localCameraToEquatorial(_cartesianPosition.value());
}
void ScreenSpaceSkyTarget::animateToCoordinate(double deltaTime) {
if (_isAnimated) {
// Find smallest angle between the two vectors
double smallestAngle = skybrowser::angleVector(_animationStart, _animationEnd);
// Only keep animating when target is not at final position
if (smallestAngle > _stopAnimationThreshold) {
glm::dmat4 rotMat;
skybrowser::incrementalAnimationMatrix(
rotMat,
_animationStart,
_animationEnd,
deltaTime,
_animationSpeed
);
// Rotate target direction
glm::dvec3 newDir = rotMat * glm::dvec4(_animationStart, 1.0);
// Convert to screen space
_cartesianPosition = skybrowser::equatorialToScreenSpace(newDir);
// Update position
_animationStart = glm::normalize(newDir);
}
else {
// Set the exact target position
_cartesianPosition = skybrowser::equatorialToScreenSpace(_animationEnd);
// Lock target when it first arrives to the position
if (!_isLocked && _lockAfterAnimation) {
lock();
}
// When target is in position, animate the FOV until it has finished
if(animateToFov(_vfovEndAnimation, deltaTime)) {
_isAnimated = false;
}
}
}
}
bool ScreenSpaceSkyTarget::animateToFov(float endFOV, float deltaTime) {
if (!_skyBrowser) {
findSkyBrowser();
}
if (_skyBrowser) {
double distance = static_cast<double>(_skyBrowser->verticalFov()) - endFOV;
// If distance is too large, keep animating
if (abs(distance) > 0.01) {
_skyBrowser->setVerticalFovWithScroll(distance);
return false;
}
// Animation is finished
return true;
}
else {
LINFO("Target can't connect to browser!");
}
return true;
}
void ScreenSpaceSkyTarget::highlight(glm::ivec3 addition)
{
@@ -391,17 +384,6 @@ namespace openspace {
_color -= removal;
}
void ScreenSpaceSkyTarget::startAnimation(glm::dvec3 coordsEnd, float FOVEnd,
bool lockAfterwards) {
// Save the Cartesian celestial coordinates for animation
// The coordinates are Cartesian to avoid wrap-around issues
_animationEnd = glm::normalize(coordsEnd);
_animationStart = glm::normalize(targetDirectionEquatorial());
_vfovEndAnimation = FOVEnd;
_isAnimated = true;
_lockAfterAnimation = lockAfterwards;
}
float ScreenSpaceSkyTarget::opacity() const {
return _opacity.value();
}

View File

@@ -131,7 +131,7 @@ namespace openspace::skybrowser {
return windowRatio.x / windowRatio.y;
}
bool coordinateIsOutsideView(glm::dvec3 equatorial) {
bool coordinateIsInView(glm::dvec3 equatorial) {
// Check if image coordinate is within current FOV
glm::dvec3 coordsScreen = equatorialToScreenSpace(equatorial);
double r = static_cast<float>(windowRatio());
@@ -140,7 +140,7 @@ namespace openspace::skybrowser {
abs(coordsScreen.y) < 1.f && coordsScreen.z < 0);
bool coordIsBehindCamera = coordsScreen.z > 0;
// If the coordinate is not in view, rotate camera
return !coordIsWithinView || coordIsBehindCamera;
return coordIsWithinView;
}
// Transforms a pixel coordinate to a screen space coordinate
@@ -172,7 +172,7 @@ namespace openspace::skybrowser {
return std::acos(cos);
}
void incrementalAnimationMatrix(glm::dmat4& rotation, glm::dvec3 start,
glm::dmat4 incrementalAnimationMatrix(glm::dvec3 start,
glm::dvec3 end, double deltaTime,
double speedFactor) {
@@ -182,7 +182,7 @@ namespace openspace::skybrowser {
// Create the rotation matrix for local camera space
glm::dvec3 rotationAxis = glm::normalize(glm::cross(start, end));
rotation = glm::rotate(rotationAngle, rotationAxis);
return glm::rotate(rotationAngle, rotationAxis);
}
}