NASAWorldWind / WorldWindAndroid

The NASA WorldWind Java SDK for Android (WWA) includes the library, examples and tutorials for building 3D virtual globe applications for phones and tablets.
Other
265 stars 125 forks source link

Camera+LookAt altitude mode #138

Open pdavidc opened 6 years ago

pdavidc commented 6 years ago

Enhance the Navigator component in WorldWind Android by adding altitude mode support. The Camera and LookAt primitives contain an altitudeMode property indicating the viewer's vertical datum. This property is designed to be consumed by the Navigator and used to configure the viewer accordingly.

Navigator's first iteration provides support only for the absolute altitude mode, and handles the clamp-to-ground and relative-to-ground modes as though they were absolute.

pdavidc commented 6 years ago

Three methods in Navigator must be updated to handle altitude mode:

https://github.com/NASAWorldWind/WorldWindAndroid/blob/98a363d2c55de7a5dfbe083ea7ca0c8bb351a108/worldwind/src/main/java/gov/nasa/worldwind/Navigator.java#L122-L141

https://github.com/NASAWorldWind/WorldWindAndroid/blob/98a363d2c55de7a5dfbe083ea7ca0c8bb351a108/worldwind/src/main/java/gov/nasa/worldwind/Navigator.java#L219-L233

https://github.com/NASAWorldWind/WorldWindAndroid/blob/98a363d2c55de7a5dfbe083ea7ca0c8bb351a108/worldwind/src/main/java/gov/nasa/worldwind/Navigator.java#L253-L270

ComBatVision commented 6 years ago

Will this improvement add the ability to get lookAt coordinates of the point on the real surface including altitude instead of coordinates of intersection of viewing vector with zero altitude under surface?

When you plan to implement this feature?

I have developed my application based on lookAt functionality and now I receive wrong coordinates of visible terrain in central screen point. Current functionality returns not the coordinates of surface in screen center, but coordinates of 0 level altitude which is located farther then required point on surface.

pdavidc commented 6 years ago

@Sufaev Yes, the improvement works as you're describing. LookAt coordinates could be retrieved or set relative to the terrain surface, rather than mean sea level. The feature isn't in our immediate schedule, but we can update you here when that changes.

ComBatVision commented 6 years ago

@pdavidc Is there any other way for now to get lookAt object of terrain point in screen center with absolute altitude equals to terrain level in this point?

Will Navigator take absolute altitude into account when i will change lookAt tilt trying to leave the same terrain point on the screen center?

pdavidc commented 6 years ago

@Sufaev That's a good question. By the way, it's unfortunate you're having to work around this limitation, and we have no intention of leaving things this way.

It's possible to determine the terrain position (lat, lon, altitude) at the screen center by picking:

PickedObjectList pickedObjects = worldWindow.pick(screenCenterX, screenCenterY);
PickedObject terrain = pickedObjects.terrainPickedObject();
if (terrain != null) {
    Position terrainPosAtScreenCenter = terrain.getTerrainPosition();
} else {
    // there's no terrain at the screen center
}
ComBatVision commented 6 years ago

I have already tried this solution, but it looks like not suitable in my situation.

I am trying to show current screen center coordinates on the screen layout like in your tutorials using wwd.addNavigatorListener(new NavigatorListener()...). Before terrain support appears I have used lookAt determination here wwd.getNavigator().getAsLookAt(wwd.getGlobe(), lookAt) and then I have used this lookAt coordinates for all other base operations with center point like distance measuring by ruler tool etc.

If I use wwd.pick() in NavigatorListener, then renderer will force WorldWind to redraw frame during current redraw process and it makes my application lag.

ComBatVision commented 6 years ago

@pdavidc How can we talk with you in some text messenger about closer cooperation between our projects?

pdavidc commented 6 years ago

Certainly. The best way to have a conversation about closer cooperation is to contact WorldWind's project management:

https://worldwind.arc.nasa.gov/contact/

I've let project management know to expect a message. Note that today and tomorrow is a holiday in the U.S., so you'll likely hear back next week.

ComBatVision commented 5 years ago

Hello @pdavidc.

Method wwd.pick() at any screen position returns hard-coded 0 altitude with strange comment. Here is the part of original source code:

        // If the pick ray intersects the terrain, enqueue a picked object that associates the terrain drawable with its
        // picked object ID and the intersection position.
        if (rc.pickRay != null && rc.terrain.intersect(rc.pickRay, this.pickPoint)) {
            rc.globe.cartesianToGeographic(this.pickPoint.x, this.pickPoint.y, this.pickPoint.z, this.pickPos);
            this.pickPos.altitude = 0; // report the actual altitude, which may not lie on the terrain's surface
            rc.offerPickedObject(PickedObject.fromTerrain(pickedObjectId, this.pickPos));
        }

When I debug this functionality - it has a big negative number in altitude attribute before it becomes 0.

I also tried to make extension to FrameController and calculate intersection point for current forward viewing vector, but I get the same big negative altitude value after transforming from cartesian to geographic:

    private void renderCameraLookAtPosition(RenderContext rc) {
        if (rc.terrain.getSector().isEmpty()) {
            return; // no terrain to pick
        }

        rc.modelview.extractEyePoint(this.forwardRay.origin);
        rc.modelview.extractForwardVector(this.forwardRay.direction);

        if (rc.terrain.intersect(this.forwardRay, this.forwardPoint)) {
            rc.globe.cartesianToGeographic(this.forwardPoint.x, this.forwardPoint.y, this.forwardPoint.z, this.forwardPos);
            rc.putUserProperty("lookAtPos", forwardPos);
        }
    }

Why altitude has that strange values in both cases and why you reset altitude to 0?