Add possibility to switch geographic position

This commit is contained in:
kalbl
2016-11-29 13:29:02 +01:00
parent 328f57fb20
commit 0df09d23ad
11 changed files with 182 additions and 5 deletions
+34
View File
@@ -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<GlobeBrowsingInteractionMode> gbim =
std::dynamic_pointer_cast<GlobeBrowsingInteractionMode> (_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<GlobeBrowsingInteractionMode> gbim =
std::dynamic_pointer_cast<GlobeBrowsingInteractionMode> (_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"
},
}
};
}
@@ -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";
+88
View File
@@ -38,6 +38,7 @@
#ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED
#include <modules/globebrowsing/globes/renderableglobe.h>
#include <modules/globebrowsing/globes/chunkedlodglobe.h>
#include <modules/globebrowsing/geometry/geodetic2.h>
#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