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

Mil-std-2525 tactical graphics requires lookAt.range in rendering context #87

Open ComBatVision opened 7 years ago

ComBatVision commented 7 years ago

Hello.

Mil-std-2525 tactical graphics rendering library requres map scale to render tactical symbols with proper level of details.

Map scale in worldwind can be approximately calculated using the range from camera to the surface in central point of screen. Camera altitude and horison distance are not suitable in this case.

After moving cameraToLookAt from Globe to Navigator there is a problem to calculate lookAt range in the custom Renderables based on rendering context.

Please, add lookAt momentary value in the rendering context itself, or give any possibility to calculate it from renderingContext.

Thanks.

pdavidc commented 7 years ago

@Sufaev Thanks for outlining your use case in this issue. We'll be sure to consider this use case and make the necessary adjustments to the SDK.

ComBatVision commented 7 years ago

When do you approximately plan to do this improvement?

I need to use custom WorldWind build with this modification for now, because I can not compile my project code after update to the latest develop commit and have no possibility to fix it without custom WorldWind.

pdavidc commented 7 years ago

I'd recommend that you develop an extended WorldWind Globe, rather than a custom build of the SDK itself. We're reviewing priorities with our sponsors this month, and we want to support use cases like yours. That said, we don't have the time to address this immediately.

ComBatVision commented 7 years ago

Making custom Globe will not help, because Globe has no path to call Navigator.getAsLookAt.

Could you, please, add only three lines in RenderContext and WorldWondow (because I am stuck in development without passing custom RenderContext through the whole library):

1) Add lookAt definition into RenderContext after Camera definition: public LookAt lookAt = new LookAt(); 2) Reset lookAt in RenderContext: public void reset() { ... this.lookAt.set(0.0D, 0.0D, 0.0D, 0, 0.0D, 0.0D, 0.0D, 0.0D); ... }

2) Fill lookAt after camera in WorldWindow.renderFrame:

protected void renderFrame(Frame frame) {
...
this.rc.camera = this.navigator.getAsCamera(this.globe, this.rc.camera);
this.rc.lookAt = this.navigator.getAsLookAt(this.globe, this.rc.lookAt);
...
}

I think this addition will not influence performance much, but it will be possible to use lookAt in any necessary calculation during rendering via RenderContext.lookAt.

Thanks.

pdavidc commented 7 years ago

Thanks for the clarification. I'd like to avoid workarounds like this, and target something more specific to this use case instead. The LookAt data structure is designed as an application level navigation mechanism, not a mechanism for informing the application of the map scale.

Would you please try computing the range directly in your rendering code using the information already in the RenderContext. Here's a pseudocode start:

double computeRange(rc) {
    Line ray = rc.modelview.extractForwardVector(new Line());
    Vec3 eyePoint = rc.modelview.extractEyePoint(new Vec3());
    Vec3 globePoint = new Vec3();
    if (globe.intersect(ray, point)) {
        return eyePoint.distanceTo(globePoint);
    } else {
        // viewer is not looking at the globe; compute the scale another way
    }
}
ComBatVision commented 7 years ago

Ok. I undestand now.

Then, it will be necessary to add some conceptual thing like "map scale" in the system architecture later. Am I right?

P.S.: I think this feature will be also useful to display usual paper map scale e.g. "1:50 000" on the screen and draw map scale ruler.

ComBatVision commented 7 years ago

Idea! I will copy cameraAsLookAt code from Navigator to my custom Renderable and will calculate it from rc.camera. But it will require half of navigator private methods to copy :(

pdavidc commented 7 years ago

Implementing code in your custom Renderable would be perfect at the moment. In the long term we intend to add a conceptual map scale that developers such as yourself can rely on. Both your current use case and use cases around paper map scale are exactly what we have in mind.

ComBatVision commented 6 years ago

Hello! Any news about map scale determination from inside the rendering context?

I have copied part of code which determines lookAt.range from Navigator. Is this approach OK?:

    private double computeRange(RenderContext rc) {
        modelview.set(rc.modelview);
        modelview.extractEyePoint(forwardRay.origin);
        modelview.extractForwardVector(forwardRay.direction);

        if (!rc.globe.intersect(forwardRay, originPoint)) {
            forwardRay.pointAt(rc.globe.horizonDistance(rc.camera.altitude), originPoint);
        }

        rc.globe.cartesianToLocalTransform(originPoint.x, originPoint.y, originPoint.z, origin);
        modelview.multiplyByMatrix(origin);

        return -modelview.m[11];
    }

Then I determine scale like this: scale = rc.pixelSizeAtDistance(computeRange(rc)) * rc.resources.getDisplayMetrics().density;