Clean up in interaction mode abd push camera to the surface of the heightmap.

This commit is contained in:
Kalle Bladin
2016-06-22 17:48:59 -04:00
parent cb4b6dbdf3
commit e8fc2250d5
3 changed files with 40 additions and 26 deletions
@@ -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();
+25 -17
View File
@@ -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);
}
}