From 843d22f7eb8b9bfbe13750a1b7d0a2c7b77accf5 Mon Sep 17 00:00:00 2001 From: Eugene Maksymenko Date: Sun, 20 Feb 2022 21:07:59 +0200 Subject: [PATCH] Fix PointPlacemark orientation transformations: Prevent tilted PointPlacemark clipping (https://github.com/NASAWorldWind/WorldWindJava/issues/151). Make rotation and tilting around specified offset point instead of image center. --- .../nasa/worldwind/render/PointPlacemark.java | 69 +++++++++---------- .../nasa/worldwindx/examples/Placemarks.java | 1 + 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/gov/nasa/worldwind/render/PointPlacemark.java b/src/gov/nasa/worldwind/render/PointPlacemark.java index 93c6e2d5c8..08719e26d2 100644 --- a/src/gov/nasa/worldwind/render/PointPlacemark.java +++ b/src/gov/nasa/worldwind/render/PointPlacemark.java @@ -999,9 +999,26 @@ protected void doDrawOrderedRenderable(DrawContext dc, PickSupport pickCandidate (byte) color.getAlpha()); } + // Compute the scale + double xscale; + Double scale = this.getActiveAttributes().getScale(); + if (scale != null) + xscale = scale * this.activeTexture.getWidth(dc); + else + xscale = this.activeTexture.getWidth(dc); + + double yscale; + if (scale != null) + yscale = scale * this.activeTexture.getHeight(dc); + else + yscale = this.activeTexture.getHeight(dc); + + // Calculate maximum possible depth value in case of rectangle is tilted on 90 degree and rotated on 45 + double maxDepth = Math.max(xscale, yscale) * 1.42; + // The image is drawn using a parallel projection. osh.pushProjectionIdentity(gl); - gl.glOrtho(0d, dc.getView().getViewport().width, 0d, dc.getView().getViewport().height, -1d, 1d); + gl.glOrtho(0d, dc.getView().getViewport().width, 0d, dc.getView().getViewport().height, -maxDepth, maxDepth); // Apply the depth buffer but don't change it (for screen-space shapes). if ((!dc.isDeepPickingEnabled())) @@ -1014,52 +1031,34 @@ protected void doDrawOrderedRenderable(DrawContext dc, PickSupport pickCandidate // Adjust depth of image to bring it slightly forward double depth = opm.screenPoint.z - (8d * 0.00048875809d); - depth = depth < 0d ? 0d : (depth > 1d ? 1d : depth); + depth = depth < 0d ? 0d : Math.min(depth, 1d); gl.glDepthFunc(GL.GL_LESS); gl.glDepthRange(depth, depth); // The image is drawn using a translated and scaled unit quad. - // Translate to screen point and adjust to align hot spot. osh.pushModelviewIdentity(gl); - gl.glTranslated(opm.screenPoint.x + this.dx, opm.screenPoint.y + this.dy, 0); - // Compute the scale - double xscale; - Double scale = this.getActiveAttributes().getScale(); - if (scale != null) - xscale = scale * this.activeTexture.getWidth(dc); - else - xscale = this.activeTexture.getWidth(dc); - - double yscale; - if (scale != null) - yscale = scale * this.activeTexture.getHeight(dc); - else - yscale = this.activeTexture.getHeight(dc); + // Translate to screen point. + gl.glTranslated(opm.screenPoint.x, opm.screenPoint.y, 0); - Double heading = getActiveAttributes().getHeading(); + // Apply the pitch if specified. Double pitch = getActiveAttributes().getPitch(); - - // Adjust heading to be relative to globe or screen - if (heading != null) - { - if (AVKey.RELATIVE_TO_GLOBE.equals(this.getActiveAttributes().getHeadingReference())) - heading = dc.getView().getHeading().degrees - heading; - else - heading = -heading; + if (pitch != null) { + gl.glRotated(pitch, 1, 0, 0); } - // Apply the heading and pitch if specified. - if (heading != null || pitch != null) - { - gl.glTranslated(xscale / 2, yscale / 2, 0); - if (pitch != null) - gl.glRotated(pitch, 1, 0, 0); - if (heading != null) - gl.glRotated(heading, 0, 0, 1); - gl.glTranslated(-xscale / 2, -yscale / 2, 0); + // Apply the heading if specified. + Double heading = getActiveAttributes().getHeading(); + if (heading != null) { + // Adjust heading to be relative to globe or screen + heading = AVKey.RELATIVE_TO_GLOBE.equals(this.getActiveAttributes().getHeadingReference()) + ? dc.getView().getHeading().degrees - heading : -heading; + gl.glRotated(heading, 0, 0, 1); } + // Adjust to align hot spot. + gl.glTranslated(this.dx, this.dy, 0); + // Scale the unit quad gl.glScaled(xscale, yscale, 1); diff --git a/src/gov/nasa/worldwindx/examples/Placemarks.java b/src/gov/nasa/worldwindx/examples/Placemarks.java index 4564da9dfa..7bf15befe5 100644 --- a/src/gov/nasa/worldwindx/examples/Placemarks.java +++ b/src/gov/nasa/worldwindx/examples/Placemarks.java @@ -273,6 +273,7 @@ public void run() // Create and assign the placemark attributes. PointPlacemarkAttributes attrs = new PointPlacemarkAttributes(); attrs.setImage(symbolImage); + attrs.setImageOffset(new Offset(0.5, 0.5, AVKey.FRACTION, AVKey.FRACTION)); attrs.setImageColor(new Color(1f, 1f, 1f, 1f)); attrs.setLabelOffset(new Offset(0.9d, 0.6d, AVKey.FRACTION, AVKey.FRACTION)); attrs.setScale(0.5);