From 0df09d23ad01d4aaa5a34482b6734c2957f68b43 Mon Sep 17 00:00:00 2001 From: kalbl Date: Tue, 29 Nov 2016 13:29:02 +0100 Subject: [PATCH] Add possibility to switch geographic position --- .../interaction/interactionhandler.h | 5 +- .../openspace/interaction/interactionmode.h | 14 ++- modules/globebrowsing/geometry/geodetic2.cpp | 5 ++ modules/globebrowsing/geometry/geodetic2.h | 1 + .../globebrowsing/globes/renderableglobe.cpp | 4 +- .../globebrowsing/globes/renderableglobe.h | 1 + .../globebrowsing/rendering/chunkrenderer.cpp | 2 +- .../shaders/globalchunkedlodpatch_fs.glsl | 2 +- src/interaction/interactionhandler.cpp | 34 +++++++ src/interaction/interactionhandler_lua.inl | 31 +++++++ src/interaction/interactionmode.cpp | 88 +++++++++++++++++++ 11 files changed, 182 insertions(+), 5 deletions(-) diff --git a/include/openspace/interaction/interactionhandler.h b/include/openspace/interaction/interactionhandler.h index 1018f37068..d81e85bde5 100644 --- a/include/openspace/interaction/interactionhandler.h +++ b/include/openspace/interaction/interactionhandler.h @@ -65,7 +65,10 @@ public: // Interaction mode setters void setCameraStateFromDictionary(const ghoul::Dictionary& cameraDict); void setInteractionMode(const std::string& interactionModeKey); - + + void goToChunk(int x, int y, int level); + void goToGeo(double latitude, double longitude); + void resetKeyBindings(); void addKeyframe(const datamessagestructures::CameraKeyframe &kf); diff --git a/include/openspace/interaction/interactionmode.h b/include/openspace/interaction/interactionmode.h index 4a5f418db9..25688a2e77 100644 --- a/include/openspace/interaction/interactionmode.h +++ b/include/openspace/interaction/interactionmode.h @@ -31,6 +31,10 @@ #include #include +#ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED +#include +#include +#endif #include @@ -258,7 +262,15 @@ public: virtual void setFocusNode(SceneGraphNode* focusNode); //virtual void update(Camera& camera, const InputState& inputState, double deltaTime); virtual void updateCameraStateFromMouseStates(Camera& camera, double deltaTime); - +#ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED + void goToChunk(Camera& camera, globebrowsing::TileIndex ti, glm::vec2 uv, + bool resetCameraDirection); + void goToGeodetic2(Camera& camera, globebrowsing::Geodetic2 geo2, + bool resetCameraDirection); + + void goToGeodetic3(Camera& camera, globebrowsing::Geodetic3 geo3); + void resetCameraDirection(Camera& camera, globebrowsing::Geodetic2 geo2); +#endif private: //void updateCameraStateFromMouseStates(Camera& camera, double deltaTime); #ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED diff --git a/modules/globebrowsing/geometry/geodetic2.cpp b/modules/globebrowsing/geometry/geodetic2.cpp index 1e22cca34a..5e7fd44b56 100644 --- a/modules/globebrowsing/geometry/geodetic2.cpp +++ b/modules/globebrowsing/geometry/geodetic2.cpp @@ -149,6 +149,11 @@ namespace globebrowsing { } } + Geodetic2 GeodeticPatch::getSize() const { + return _halfSize * 2; + } + + Scalar GeodeticPatch::minLat() const { return _center.lat - _halfSize.lat; } diff --git a/modules/globebrowsing/geometry/geodetic2.h b/modules/globebrowsing/geometry/geodetic2.h index 5a344c05a7..40481ddf23 100644 --- a/modules/globebrowsing/geometry/geodetic2.h +++ b/modules/globebrowsing/geometry/geodetic2.h @@ -108,6 +108,7 @@ public: Scalar isNorthern() const; Geodetic2 getCorner(Quad q) const; + Geodetic2 getSize() const; Scalar minLat() const; Scalar maxLat() const; diff --git a/modules/globebrowsing/globes/renderableglobe.cpp b/modules/globebrowsing/globes/renderableglobe.cpp index 6336818f2e..422ef41431 100644 --- a/modules/globebrowsing/globes/renderableglobe.cpp +++ b/modules/globebrowsing/globes/renderableglobe.cpp @@ -80,7 +80,8 @@ namespace globebrowsing { properties::BoolProperty("levelByProjectedAreaElseDistance", "level by projected area (else distance)",false), properties::BoolProperty("resetTileProviders", "reset tile providers", false), properties::BoolProperty("toggleEnabledEveryFrame", "toggle enabled every frame", false), - properties::BoolProperty("collectStats", "collect stats", false) + properties::BoolProperty("collectStats", "collect stats", false), + properties::BoolProperty("onlyModelSpaceRendering", "Only Model Space Rendering", false) }) { @@ -144,6 +145,7 @@ namespace globebrowsing { _debugPropertyOwner.addProperty(_debugProperties.resetTileProviders); _debugPropertyOwner.addProperty(_debugProperties.toggleEnabledEveryFrame); _debugPropertyOwner.addProperty(_debugProperties.collectStats); + _debugPropertyOwner.addProperty(_debugProperties.onlyModelSpaceRendering); addPropertySubOwner(_debugPropertyOwner); addPropertySubOwner(_layerManager.get()); diff --git a/modules/globebrowsing/globes/renderableglobe.h b/modules/globebrowsing/globes/renderableglobe.h index ed66466d1b..afa3042f2c 100644 --- a/modules/globebrowsing/globes/renderableglobe.h +++ b/modules/globebrowsing/globes/renderableglobe.h @@ -73,6 +73,7 @@ public: properties::BoolProperty resetTileProviders; properties::BoolProperty toggleEnabledEveryFrame; properties::BoolProperty collectStats; + properties::BoolProperty onlyModelSpaceRendering; }; struct GeneralProperties { diff --git a/modules/globebrowsing/rendering/chunkrenderer.cpp b/modules/globebrowsing/rendering/chunkrenderer.cpp index 98b084bd1d..53b0aedede 100644 --- a/modules/globebrowsing/rendering/chunkrenderer.cpp +++ b/modules/globebrowsing/rendering/chunkrenderer.cpp @@ -80,7 +80,7 @@ namespace globebrowsing { void ChunkRenderer::renderChunk(const Chunk& chunk, const RenderData& data) { // A little arbitrary with 10 but it works - if (chunk.tileIndex().level < 10) { + if (chunk.owner().debugProperties().onlyModelSpaceRendering || chunk.tileIndex().level < 10) { renderChunkGlobally(chunk, data); } else { diff --git a/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl b/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl index 9a90381e25..9b1764e690 100644 --- a/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl +++ b/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl @@ -30,7 +30,7 @@ Fragment getFragment() { frag.color = getTileFragColor(); #if SHOW_CHUNK_EDGES - frag.color += patchBorderOverlay(fs_uv, vec3(0,1,0), 0.005); + frag.color += patchBorderOverlay(fs_uv, vec3(0,1,0), 0.02); #endif // SHOW_CHUNK_EDGES frag.depth = fs_position.w; diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index e9af75dead..63cf497c4e 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -203,6 +203,28 @@ void InteractionHandler::setInteractionMode(const std::string& interactionModeKe "' is not a valid interaction mode. Candidates are " << listInteractionModes); } } + +void InteractionHandler::goToChunk(int x, int y, int level) { + std::shared_ptr gbim = + std::dynamic_pointer_cast (_currentInteractionMode); + + if (gbim) { + gbim->goToChunk(*_camera, globebrowsing::TileIndex(x,y,level), glm::vec2(0.5,0.5), true); + } else { + LWARNING("Interaction mode must be set to 'GlobeBrowsing'"); + } +} + +void InteractionHandler::goToGeo(double latitude, double longitude) { + std::shared_ptr gbim = + std::dynamic_pointer_cast (_currentInteractionMode); + + if (gbim) { + gbim->goToGeodetic2(*_camera, globebrowsing::Geodetic2(latitude, longitude) / 180 * M_PI, true); + } else { + LWARNING("Interaction mode must be set to 'GlobeBrowsing'"); + } +} void InteractionHandler::lockControls() { @@ -568,6 +590,18 @@ scripting::LuaLibrary InteractionHandler::luaLibrary() { "void", "Reset the camera direction to point at the focus node" }, + { + "goToChunk", + &luascriptfunctions::goToChunk, + "void", + "Go to chunk with given index x, y, level" + }, + { + "goToGeo", + &luascriptfunctions::goToGeo, + "void", + "Go to geographic coordinates latitude and longitude" + }, } }; } diff --git a/src/interaction/interactionhandler_lua.inl b/src/interaction/interactionhandler_lua.inl index 21ad7fc862..b810761ecb 100644 --- a/src/interaction/interactionhandler_lua.inl +++ b/src/interaction/interactionhandler_lua.inl @@ -191,6 +191,37 @@ int setInteractionMode(lua_State* L) { return 0; } +int goToChunk(lua_State* L) { + using ghoul::lua::luaTypeToString; + + int nArguments = lua_gettop(L); + if (nArguments != 3) + return luaL_error(L, "Expected %i arguments, got %i", 3, nArguments); + + int x = lua_tonumber(L, 1); + int y = lua_tonumber(L, 2); + int level = lua_tonumber(L, 3); + + OsEng.interactionHandler().goToChunk(x, y, level); + + return 0; +} + +int goToGeo(lua_State* L) { + using ghoul::lua::luaTypeToString; + + int nArguments = lua_gettop(L); + if (nArguments != 2) + return luaL_error(L, "Expected %i arguments, got %i", 2, nArguments); + + double latitude = lua_tonumber(L, 1); + double longitude = lua_tonumber(L, 2); + + OsEng.interactionHandler().goToGeo(latitude, longitude); + + return 0; +} + int restoreCameraStateFromFile(lua_State* L) { using ghoul::lua::luaTypeToString; const std::string _loggerCat = "lua.restoreCameraStateFromFile"; diff --git a/src/interaction/interactionmode.cpp b/src/interaction/interactionmode.cpp index 466382579f..70274c1876 100644 --- a/src/interaction/interactionmode.cpp +++ b/src/interaction/interactionmode.cpp @@ -38,6 +38,7 @@ #ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED #include #include +#include #endif @@ -685,5 +686,92 @@ void GlobeBrowsingInteractionMode::updateCameraStateFromMouseStates(Camera& came #endif // OPENSPACE_MODULE_GLOBEBROWSING_ENABLED } +#ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED +void GlobeBrowsingInteractionMode::goToChunk(Camera& camera, + globebrowsing::TileIndex ti, glm::vec2 uv, bool resetCameraDirection) { + using namespace globebrowsing; + + // Camera position in model space + glm::dvec3 camPos = camera.positionVec3(); + glm::dmat4 inverseModelTransform = _globe->inverseModelTransform(); + glm::dvec3 cameraPositionModelSpace = + glm::dvec3(inverseModelTransform * glm::dvec4(camPos, 1)); + + GeodeticPatch patch(ti); + Geodetic2 corner = patch.getCorner(SOUTH_WEST); + Geodetic2 positionOnPatch = patch.getSize(); + positionOnPatch.lat *= uv.y; + positionOnPatch.lon *= uv.x; + Geodetic2 pointPosition = corner + positionOnPatch; + + glm::dvec3 positionOnEllipsoid = + _globe->ellipsoid().geodeticSurfaceProjection(cameraPositionModelSpace); + double altitude = glm::length(cameraPositionModelSpace - positionOnEllipsoid); + + goToGeodetic3(camera, {pointPosition, altitude}); + + if (resetCameraDirection) { + this->resetCameraDirection(camera, pointPosition); + } +} + +void GlobeBrowsingInteractionMode::goToGeodetic2(Camera& camera, + globebrowsing::Geodetic2 geo2, bool resetCameraDirection) { + using namespace globebrowsing; + + // Camera position in model space + glm::dvec3 camPos = camera.positionVec3(); + glm::dmat4 inverseModelTransform = _globe->inverseModelTransform(); + glm::dvec3 cameraPositionModelSpace = + glm::dvec3(inverseModelTransform * glm::dvec4(camPos, 1)); + + glm::dvec3 positionOnEllipsoid = + _globe->ellipsoid().geodeticSurfaceProjection(cameraPositionModelSpace); + double altitude = glm::length(cameraPositionModelSpace - positionOnEllipsoid); + + goToGeodetic3(camera, {geo2, altitude}); + + if (resetCameraDirection) { + this->resetCameraDirection(camera, geo2); + } +} + +void GlobeBrowsingInteractionMode::goToGeodetic3(Camera& camera, globebrowsing::Geodetic3 geo3) { + glm::dvec3 positionModelSpace = _globe->ellipsoid().cartesianPosition(geo3); + glm::dmat4 modelTransform = _globe->modelTransform(); + glm::dvec3 positionWorldSpace = modelTransform * glm::dvec4(positionModelSpace, 1.0); + camera.setPositionVec3(positionWorldSpace); +} + + void GlobeBrowsingInteractionMode::resetCameraDirection(Camera& camera, globebrowsing::Geodetic2 geo2) { + using namespace globebrowsing; + + // Camera is described in world space + glm::dmat4 modelTransform = _globe->modelTransform(); + + // Lookup vector + glm::dvec3 positionModelSpace = _globe->ellipsoid().cartesianSurfacePosition(geo2); + glm::dvec3 slightlyNorth = _globe->ellipsoid().cartesianSurfacePosition( + Geodetic2(geo2.lat + 0.001, geo2.lon)); + glm::dvec3 lookUpModelSpace = glm::normalize(slightlyNorth - positionModelSpace); + glm::dvec3 lookUpWorldSpace = glm::dmat3(modelTransform) * lookUpModelSpace; + + // Lookat vector + glm::dvec3 lookAtWorldSpace = modelTransform * glm::dvec4(positionModelSpace, 1.0); + + // Eye position + glm::dvec3 eye = camera.positionVec3(); + + // Matrix + glm::dmat4 lookAtMatrix = glm::lookAt( + eye, lookAtWorldSpace, lookUpWorldSpace); + + // Set rotation + glm::dquat rotation = glm::quat_cast(inverse(lookAtMatrix)); + camera.setRotation(rotation); + } + +#endif // OPENSPACE_MODULE_GLOBEBROWSING_ENABLED + } // namespace interaction } // namespace openspace