Skip to content

Commit 6c4342c

Browse files
committed
Fix Placemark rotation and tilt (WorldWindEarth#31):
1) Change order of unitSquareTransform matrix operations to fix image stretching on rotation and apply correct pivot point. 2) Normalize unitSquareTransform matrix Z-range to prevent texture clipping on tilting.
1 parent 0dacfec commit 6c4342c

1 file changed

Lines changed: 29 additions & 21 deletions

File tree

worldwind/src/main/java/gov/nasa/worldwind/shape/Placemark.java

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -808,48 +808,56 @@ protected void determineActiveTexture(RenderContext rc) {
808808
// offset is defined with its origin at the image's bottom-left corner and axes that extend up and to the right
809809
// from the origin point. When the placemark has no active texture the image scale defines the image size and no
810810
// other scaling is applied.
811+
double offsetX, offsetY, scaleX, scaleY;
811812
if (this.activeTexture != null) {
812813
int w = this.activeTexture.getWidth();
813814
int h = this.activeTexture.getHeight();
814815
double s = this.activeAttributes.imageScale * visibilityScale;
815816
this.activeAttributes.imageOffset.offsetForSize(w, h, offset);
816-
817-
unitSquareTransform.multiplyByTranslation(
818-
screenPlacePoint.x - offset.x * s,
819-
screenPlacePoint.y - offset.y * s,
820-
screenPlacePoint.z);
821-
822-
unitSquareTransform.multiplyByScale(w * s, h * s, 1);
817+
offsetX = offset.x * s;
818+
offsetY = offset.y * s;
819+
scaleX = w * s;
820+
scaleY = h * s;
823821
} else {
824822
// This branch serves both non-textured attributes and also textures that haven't been loaded yet.
825823
// We set the size for non-loaded textures to the typical size of a contemporary "small" icon (24px)
826824
double size = this.activeAttributes.imageSource != null ? 24 : this.activeAttributes.imageScale;
827825
size *= visibilityScale;
828826
this.activeAttributes.imageOffset.offsetForSize(size, size, offset);
827+
offsetX = offset.x;
828+
offsetY = offset.y;
829+
scaleX = scaleY = size;
830+
}
829831

830-
unitSquareTransform.multiplyByTranslation(
831-
screenPlacePoint.x - offset.x,
832-
screenPlacePoint.y - offset.y,
832+
// Position image on screen
833+
unitSquareTransform.multiplyByTranslation(
834+
screenPlacePoint.x,
835+
screenPlacePoint.y,
833836
screenPlacePoint.z);
834837

835-
unitSquareTransform.multiplyByScale(size, size, 1);
838+
// Divide Z by 2^24 to prevent texture clipping when tilting (where 24 is depth buffer bit size).
839+
// Doing so will limit depth range to (diagonal length)/2^24 and make its value within 0..1 range.
840+
unitSquareTransform.multiplyByScale(1, 1, 1d / (1 << 24) );
841+
842+
// Perform the tilt so that the image tilts back from its base into the view volume
843+
if (this.imageTilt != 0) {
844+
double tilt = this.imageTiltReference == WorldWind.RELATIVE_TO_GLOBE ?
845+
rc.camera.tilt + this.imageTilt : this.imageTilt;
846+
unitSquareTransform.multiplyByRotation(-1, 0, 0, tilt);
836847
}
837848

838-
// ... perform image rotation
849+
// Perform image rotation
839850
if (this.imageRotation != 0) {
840851
double rotation = this.imageRotationReference == WorldWind.RELATIVE_TO_GLOBE ?
841-
rc.camera.heading - this.imageRotation : -this.imageRotation;
842-
unitSquareTransform.multiplyByTranslation(0.5, 0.5, 0);
852+
rc.camera.heading - this.imageRotation : -this.imageRotation;
843853
unitSquareTransform.multiplyByRotation(0, 0, 1, rotation);
844-
unitSquareTransform.multiplyByTranslation(-0.5, -0.5, 0);
845854
}
846855

847-
// ... and perform the tilt so that the image tilts back from its base into the view volume.
848-
if (this.imageTilt != 0) {
849-
double tilt = this.imageTiltReference == WorldWind.RELATIVE_TO_GLOBE ?
850-
rc.camera.tilt + this.imageTilt : this.imageTilt;
851-
unitSquareTransform.multiplyByRotation(-1, 0, 0, tilt);
852-
}
856+
// Apply pivot translation
857+
unitSquareTransform.multiplyByTranslation(-offsetX, -offsetY, 0);
858+
859+
// Apply scale
860+
unitSquareTransform.multiplyByScale(scaleX, scaleY, 1);
853861
}
854862

855863
/**

0 commit comments

Comments
 (0)