@@ -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