mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-01 00:09:58 -05:00
Add camera view direction to camera topic (#3741)
* Add camera view direction to camera topic * Add subsolar coordinates to topic --------- Co-authored-by: Alexander Bock <alexander.bock@liu.se> Co-authored-by: Ylva Selling <ylva.selling@gmail.com>
This commit is contained in:
@@ -28,6 +28,14 @@ local showcomposer = asset.resource({
|
||||
})
|
||||
|
||||
|
||||
local maps = asset.resource({
|
||||
Identifier = "userinterface_maps",
|
||||
Name = "Userinterface Maps",
|
||||
Type = "HttpSynchronization",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
|
||||
asset.onInitialize(function()
|
||||
-- Unzip the frontend bundle
|
||||
local destFrontend = frontend .. "frontend"
|
||||
@@ -66,6 +74,10 @@ asset.onInitialize(function()
|
||||
directories[#directories + 1] = "showcomposer/projects"
|
||||
directories[#directories + 1] = openspace.absPath("${USER_SHOWCOMPOSER_PROJECTS}")
|
||||
|
||||
-- Add asset folders
|
||||
directories[#directories + 1] = "assets/maps"
|
||||
directories[#directories + 1] = maps
|
||||
|
||||
openspace.setPropertyValueSingle("Modules.WebGui.Directories", directories)
|
||||
openspace.setPropertyValueSingle("Modules.WebGui.DefaultEndpoint", "gui")
|
||||
openspace.setPropertyValueSingle("Modules.WebGui.ServerProcessEnabled", enabled)
|
||||
|
||||
@@ -71,6 +71,19 @@ glm::vec3 cartesianCoordinatesFromGeo(const SceneGraphNode& sgn, double latitude
|
||||
*/
|
||||
glm::dvec3 geoPositionFromCamera();
|
||||
|
||||
/**
|
||||
* Returns the camera view direction relative to the current anchor node as geodetic
|
||||
* coordinates. The returned value contains the latitude and longitude in degrees in the
|
||||
* x, and y-coordinate respectively.
|
||||
*/
|
||||
glm::dvec3 geoViewFromCamera();
|
||||
|
||||
/**
|
||||
* Return the coordinates where the sun is at its zenith at the current anchor at the
|
||||
* current time. The returned value contains the latitude and longitude in degrees.
|
||||
*/
|
||||
glm::dvec2 subSolarCoordinates();
|
||||
|
||||
/**
|
||||
* Returns the height of the camera relative to the provided SceneGraphNode \p sgn in
|
||||
* meters. If \p useHeightMap is provided as `true` and \p sgn is a globe with an existing
|
||||
|
||||
@@ -84,13 +84,28 @@ void CameraTopic::handleJson(const nlohmann::json& json) {
|
||||
void CameraTopic::sendCameraData() {
|
||||
#ifdef OPENSPACE_MODULE_SPACE_ENABLED
|
||||
glm::dvec3 position = geoPositionFromCamera();
|
||||
glm::dvec3 direction = geoViewFromCamera();
|
||||
const double viewLength = direction.z;
|
||||
std::pair<double, std::string_view> altSimplified = simplifyDistance(position.z);
|
||||
glm::dvec2 subSolar = subSolarCoordinates();
|
||||
|
||||
const nlohmann::json jsonData = {
|
||||
glm::dvec2 dir = glm::dvec2(direction) - glm::dvec2(position);
|
||||
if (glm::length(dir) > 1e-6) {
|
||||
// Avoid sending NaNs/null from bad normalization
|
||||
dir = glm::normalize(dir);
|
||||
}
|
||||
|
||||
nlohmann::json jsonData = {
|
||||
{ "latitude", position.x },
|
||||
{ "longitude", position.y },
|
||||
{ "altitude", altSimplified.first },
|
||||
{ "altitudeUnit", altSimplified.second }
|
||||
{ "altitudeUnit", altSimplified.second },
|
||||
{ "altitudeMeters", position.z },
|
||||
{ "viewLatitude", dir.x },
|
||||
{ "viewLongitude", dir.y },
|
||||
{ "viewLength", viewLength },
|
||||
{ "subSolarLatitude", subSolar.x },
|
||||
{ "subSolarLongitude", subSolar.y },
|
||||
};
|
||||
|
||||
_connection->sendJson(wrappedPayload(jsonData));
|
||||
|
||||
+73
-3
@@ -83,12 +83,12 @@ glm::dvec3 geoPositionFromCamera() {
|
||||
cameraPositionModelSpace
|
||||
);
|
||||
|
||||
const Geodetic2 geo2 = renderable->ellipsoid().cartesianToGeodetic2(
|
||||
const Geodetic2 geo = renderable->ellipsoid().cartesianToGeodetic2(
|
||||
posHandle.centerToReferenceSurface
|
||||
);
|
||||
|
||||
const double lat = glm::degrees(geo2.lat);
|
||||
const double lon = glm::degrees(geo2.lon);
|
||||
const double lat = glm::degrees(geo.lat);
|
||||
const double lon = glm::degrees(geo.lon);
|
||||
|
||||
double altitude = glm::length(
|
||||
cameraPositionModelSpace - posHandle.centerToReferenceSurface
|
||||
@@ -103,6 +103,76 @@ glm::dvec3 geoPositionFromCamera() {
|
||||
return glm::dvec3(lat, lon, altitude);
|
||||
}
|
||||
|
||||
glm::dvec3 geoViewFromCamera() {
|
||||
const SceneGraphNode* n = global::navigationHandler->orbitalNavigator().anchorNode();
|
||||
if (!n) {
|
||||
return glm::dvec3(0.0);
|
||||
}
|
||||
|
||||
const glm::dmat4 inverseModelTransform = glm::inverse(n->modelTransform());
|
||||
|
||||
// Get the position of the camera in model space
|
||||
const glm::dvec3 cameraPosition = global::navigationHandler->camera()->positionVec3();
|
||||
const glm::dvec3 cameraPositionModelSpace =
|
||||
glm::dvec3(inverseModelTransform * glm::dvec4(cameraPosition, 1.0));
|
||||
|
||||
// Get the direction of the camera in model space
|
||||
const glm::dvec3 cameraViewDirection =
|
||||
global::navigationHandler->camera()->viewDirectionWorldSpace();
|
||||
// Scaling the cameraViewDirection to move the precision up a few decimals
|
||||
const glm::dvec3 cameraViewPoint = cameraPosition + 10000.0 * cameraViewDirection;
|
||||
glm::dvec3 cameraViewDirectionModelSpace =
|
||||
glm::dvec3(inverseModelTransform * glm::dvec4(cameraViewPoint, 1.0));
|
||||
|
||||
|
||||
// `d` represents how much we are looking towards the center of the scene graph node
|
||||
// The closer `d` is to -1 or 1, the more we are looking either towards the center or
|
||||
// away from it
|
||||
const glm::dmat3 rotationOnly = glm::mat3_cast(glm::quat_cast(n->modelTransform()));
|
||||
const double d = glm::dot(
|
||||
glm::normalize(cameraPositionModelSpace),
|
||||
glm::normalize(glm::transpose(rotationOnly) * cameraViewDirection)
|
||||
);
|
||||
|
||||
const SurfacePositionHandle posHandle = n->calculateSurfacePositionHandle(
|
||||
cameraViewDirectionModelSpace
|
||||
);
|
||||
|
||||
const Geodetic2 geo = n->ellipsoid().cartesianToGeodetic2(
|
||||
posHandle.centerToReferenceSurface
|
||||
);
|
||||
|
||||
const double lat = glm::degrees(geo.lat);
|
||||
const double lon = glm::degrees(geo.lon);
|
||||
return glm::dvec3(lat, lon, d);
|
||||
}
|
||||
|
||||
glm::dvec2 subSolarCoordinates() {
|
||||
const SceneGraphNode* n = global::navigationHandler->orbitalNavigator().anchorNode();
|
||||
if (!n) {
|
||||
return glm::dvec3(0.0);
|
||||
}
|
||||
|
||||
const glm::dmat4 inverseModelTransform = glm::inverse(n->modelTransform());
|
||||
// @TODO (2025-07-16, abock): For now we use the position of the SolarSystemBarycenter
|
||||
// to calculate the Sun position. While this is not completely correct and precludes
|
||||
// the calculation of subsolar coordinates on exoplanets, that is a problem left for
|
||||
// later
|
||||
const glm::dvec3 ssbPositionModelSpace =
|
||||
glm::dvec3(inverseModelTransform * glm::dvec4(-n->worldPosition(), 1.0));
|
||||
|
||||
const SurfacePositionHandle sunPosition = n->calculateSurfacePositionHandle(
|
||||
ssbPositionModelSpace
|
||||
);
|
||||
const Geodetic2 subsolarCoordinates = n->ellipsoid().cartesianToGeodetic2(
|
||||
sunPosition.centerToReferenceSurface
|
||||
);
|
||||
|
||||
const double lat = glm::degrees(subsolarCoordinates.lat);
|
||||
const double lon = glm::degrees(subsolarCoordinates.lon);
|
||||
return glm::dvec2(lat, lon);
|
||||
}
|
||||
|
||||
double altitudeFromCamera(const SceneGraphNode& sgn, bool useHeightMap) {
|
||||
const glm::dvec3 cameraPosition = global::navigationHandler->camera()->positionVec3();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user