mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-04-25 21:48:57 -05:00
Clean up in interaction mode abd push camera to the surface of the heightmap.
This commit is contained in:
@@ -184,22 +184,27 @@ namespace openspace {
|
||||
return _ellipsoid.geodeticSurfaceProjection(position);
|
||||
}
|
||||
|
||||
float RenderableGlobe::getHeight(glm::dvec3 position) {
|
||||
// Get the uv coordinates to sample from
|
||||
Geodetic2 geodeticPosition = _ellipsoid.cartesianToGeodetic2(position);
|
||||
int chunkLevel = 20;
|
||||
ChunkIndex chunkIdx = ChunkIndex(geodeticPosition, chunkLevel);
|
||||
GeodeticPatch patch = GeodeticPatch(chunkIdx);
|
||||
Geodetic2 geoDiffPatch = patch.getCorner(Quad::NORTH_EAST) - patch.getCorner(Quad::SOUTH_WEST);
|
||||
Geodetic2 geoDiffPoint = geodeticPosition - patch.getCorner(Quad::SOUTH_WEST);
|
||||
glm::vec2 patchUV = glm::vec2(geoDiffPoint.lon / geoDiffPatch.lon, geoDiffPoint.lat / geoDiffPatch.lat);
|
||||
const Ellipsoid& RenderableGlobe::ellipsoid() {
|
||||
return _ellipsoid;
|
||||
}
|
||||
|
||||
float RenderableGlobe::getHeight(glm::dvec3 position) {
|
||||
// Get the tile provider for the height map
|
||||
const auto& heightMapProviders = _tileProviderManager->getActivatedLayerCategory(LayeredTextures::HeightMaps);
|
||||
if (heightMapProviders.size() == 0)
|
||||
return 0;
|
||||
const auto& tileProvider = heightMapProviders[0];
|
||||
|
||||
// Get the uv coordinates to sample from
|
||||
Geodetic2 geodeticPosition = _ellipsoid.cartesianToGeodetic2(position);
|
||||
int chunkLevel =
|
||||
tileProvider->getAsyncTileReader()->getTextureDataProvider()->getMaximumLevel();
|
||||
ChunkIndex chunkIdx = ChunkIndex(geodeticPosition, chunkLevel);
|
||||
GeodeticPatch patch = GeodeticPatch(chunkIdx);
|
||||
Geodetic2 geoDiffPatch = patch.getCorner(Quad::NORTH_EAST) - patch.getCorner(Quad::SOUTH_WEST);
|
||||
Geodetic2 geoDiffPoint = geodeticPosition - patch.getCorner(Quad::SOUTH_WEST);
|
||||
glm::vec2 patchUV = glm::vec2(geoDiffPoint.lon / geoDiffPatch.lon, geoDiffPoint.lat / geoDiffPatch.lat);
|
||||
|
||||
// Transform the uv coordinates to the current tile texture
|
||||
TileAndTransform tileAndTransform = TileSelector::getHighestResolutionTile(tileProvider.get(), chunkIdx);
|
||||
const auto& tile = tileAndTransform.tile;
|
||||
|
||||
@@ -111,6 +111,7 @@ public:
|
||||
void update(const UpdateData& data) override;
|
||||
|
||||
glm::dvec3 projectOnEllipsoid(glm::dvec3 position);
|
||||
const Ellipsoid& ellipsoid();
|
||||
float getHeight(glm::dvec3 position);
|
||||
std::shared_ptr<ChunkedLodGlobe> chunkedLodGlobe();
|
||||
|
||||
|
||||
@@ -915,14 +915,20 @@ void GlobeBrowsingInteractionMode::setFocusNode(SceneGraphNode* focusNode) {
|
||||
void GlobeBrowsingInteractionMode::updateCameraStateFromMouseStates() {
|
||||
if (_focusNode && _globe) {
|
||||
// Declare variables to use in interaction calculations
|
||||
// Shrink interaction ellipsoid to enable interaction below height = 0
|
||||
double ellipsoidShrinkTerm = 10000.0;
|
||||
double minHeightAboveGround = 100.0;
|
||||
|
||||
glm::dvec3 centerPos = _focusNode->worldPosition().dvec3();
|
||||
glm::dvec3 camPos = _camera->positionVec3();
|
||||
glm::dvec3 posDiff = camPos - centerPos;
|
||||
glm::dvec3 newPosition = camPos;
|
||||
|
||||
glm::dvec3 centerToEllipsoidSurface = _globe->projectOnEllipsoid(camPos);
|
||||
glm::dvec3 directionFromSurfaceToCamera =
|
||||
_globe->ellipsoid().geodeticSurfaceNormal(
|
||||
_globe->ellipsoid().cartesianToGeodetic2(camPos));
|
||||
glm::dvec3 centerToEllipsoidSurface = _globe->projectOnEllipsoid(camPos) -
|
||||
directionFromSurfaceToCamera * ellipsoidShrinkTerm;
|
||||
glm::dvec3 ellipsoidSurfaceToCamera = camPos - (centerPos + centerToEllipsoidSurface);
|
||||
glm::dvec3 directionFromSurfaceToCamera = glm::normalize(ellipsoidSurfaceToCamera);
|
||||
|
||||
double distFromCenterToSurface =
|
||||
glm::length(centerToEllipsoidSurface);
|
||||
@@ -942,7 +948,6 @@ void GlobeBrowsingInteractionMode::updateCameraStateFromMouseStates() {
|
||||
0) * glm::clamp(distFromEllipsoidSurfaceToCamera / distFromCenterToSurface, 0.0, 1.0);
|
||||
glm::dquat rotationDiffCamSpace = glm::dquat(eulerAngles);
|
||||
|
||||
|
||||
glm::dquat rotationDiffWorldSpace =
|
||||
_globalCameraRotation *
|
||||
rotationDiffCamSpace *
|
||||
@@ -953,11 +958,14 @@ void GlobeBrowsingInteractionMode::updateCameraStateFromMouseStates() {
|
||||
* rotationDiffWorldSpace
|
||||
- (distFromCenterToCamera * directionFromSurfaceToCamera);
|
||||
|
||||
newPosition = camPos + rotationDiffVec3;
|
||||
camPos = camPos + rotationDiffVec3;
|
||||
|
||||
centerToEllipsoidSurface = _globe->projectOnEllipsoid(newPosition);
|
||||
ellipsoidSurfaceToCamera = newPosition - (centerPos + centerToEllipsoidSurface);
|
||||
directionFromSurfaceToCamera = glm::normalize(ellipsoidSurfaceToCamera);
|
||||
directionFromSurfaceToCamera =
|
||||
_globe->ellipsoid().geodeticSurfaceNormal(
|
||||
_globe->ellipsoid().cartesianToGeodetic2(camPos));
|
||||
centerToEllipsoidSurface = _globe->projectOnEllipsoid(camPos) -
|
||||
directionFromSurfaceToCamera * ellipsoidShrinkTerm;
|
||||
ellipsoidSurfaceToCamera = camPos - (centerPos + centerToEllipsoidSurface);
|
||||
|
||||
glm::dvec3 lookUpWhenFacingSurface =
|
||||
_globalCameraRotation * glm::dvec3(_camera->lookUpVectorCameraSpace());
|
||||
@@ -969,7 +977,8 @@ void GlobeBrowsingInteractionMode::updateCameraStateFromMouseStates() {
|
||||
glm::normalize(glm::quat_cast(glm::inverse(lookAtMat)));
|
||||
}
|
||||
{ // Move position towards or away from focus node
|
||||
newPosition += -(posDiff - centerToEllipsoidSurface) *
|
||||
distFromEllipsoidSurfaceToCamera = glm::length(ellipsoidSurfaceToCamera);
|
||||
camPos += -directionFromSurfaceToCamera * distFromEllipsoidSurfaceToCamera *
|
||||
_truckMovementMouseState.velocity.get().y;
|
||||
}
|
||||
{ // Do roll
|
||||
@@ -978,18 +987,17 @@ void GlobeBrowsingInteractionMode::updateCameraStateFromMouseStates() {
|
||||
_globalCameraRotation = cameraRollRotation * _globalCameraRotation;
|
||||
}
|
||||
{ // Push up to surface
|
||||
centerToEllipsoidSurface = _globe->projectOnEllipsoid(newPosition);
|
||||
ellipsoidSurfaceToCamera = newPosition - (centerPos + centerToEllipsoidSurface);
|
||||
directionFromSurfaceToCamera = glm::normalize(newPosition - (centerPos + centerToEllipsoidSurface));
|
||||
ellipsoidSurfaceToCamera = camPos - (centerPos + centerToEllipsoidSurface);
|
||||
|
||||
double heightToCam = glm::length(ellipsoidSurfaceToCamera);
|
||||
double heightToSurface = _globe->getHeight(newPosition);
|
||||
double heightAboveGround = 1000;
|
||||
newPosition = _globe->projectOnEllipsoid(newPosition) + directionFromSurfaceToCamera * glm::max(heightToCam, heightToSurface + heightAboveGround);
|
||||
distFromEllipsoidSurfaceToCamera = glm::length(ellipsoidSurfaceToCamera);
|
||||
double heightToSurface = _globe->getHeight(camPos) + ellipsoidShrinkTerm;
|
||||
double heightToSurfaceAndPadding = heightToSurface + minHeightAboveGround;
|
||||
camPos += directionFromSurfaceToCamera *
|
||||
glm::max(heightToSurfaceAndPadding - distFromEllipsoidSurfaceToCamera, 0.0);
|
||||
}
|
||||
// Update the camera state
|
||||
_camera->setRotation(_globalCameraRotation * _localCameraRotation);
|
||||
_camera->setPositionVec3(newPosition);
|
||||
_camera->setPositionVec3(camPos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user