1010import  gov .nasa .worldwind .WorldWindow ;
1111import  gov .nasa .worldwind .geom .Camera ;
1212import  gov .nasa .worldwind .geom .Location ;
13+ import  gov .nasa .worldwind .geom .Position ;
1314import  gov .nasa .worldwind .gesture .GestureRecognizer ;
1415import  gov .nasa .worldwind .gesture .PinchRecognizer ;
1516import  gov .nasa .worldwind .gesture .RotationRecognizer ;
1617import  gov .nasa .worldwind .util .WWMath ;
1718
1819public  class  CameraControlFragment  extends  BasicGlobeFragment  {
1920
21+     private  static  final  double  COLLISION_THRESHOLD  = 20.0 ; // 20m above surface 
22+ 
2023    /** 
2124     * Creates a new WorldWindow object with a custom WorldWindowController. 
2225     */ 
@@ -42,7 +45,7 @@ public WorldWindow createWorldWindow() {
4245     * A custom WorldWindController that uses gestures to control the camera directly via the setAsCamera interface 
4346     * instead of the default setAsLookAt interface. 
4447     */ 
45-     private  class  CameraController  extends  BasicWorldWindowController  {
48+     private  static   class  CameraController  extends  BasicWorldWindowController  {
4649
4750        protected  double  beginHeading ;
4851
@@ -189,15 +192,22 @@ protected void gestureDidBegin() {
189192        }
190193
191194        protected  void  applyLimits (Camera  camera ) {
192-             double   distanceToExtents  = this . wwd . distanceToViewGlobeExtents () ;
195+             Position   position  = camera . position ;
193196
194197            double  minAltitude  = 100 ;
195-             double  maxAltitude  = distanceToExtents ;
196-             camera .position .altitude  = WWMath .clamp (camera .position .altitude , minAltitude , maxAltitude );
198+             double  maxAltitude  = this .wwd .distanceToViewGlobeExtents ();
199+             position .altitude  = WWMath .clamp (position .altitude , minAltitude , maxAltitude );
200+ 
201+             // Check if camera altitude is not under the surface 
202+             double  elevation  = this .wwd .getGlobe ().getElevationAtLocation (position .latitude , position .longitude )
203+                     * wwd .getVerticalExaggeration () + COLLISION_THRESHOLD ;
204+             if  (elevation  > position .altitude ) {
205+                 position .altitude  = elevation ;
206+             }
197207
198208            // Limit the tilt to between nadir and the horizon (roughly) 
199-             double  r  = wwd .getGlobe ().getRadiusAt (camera . position .latitude , camera . position .latitude );
200-             double  maxTilt  = Math .toDegrees (Math .asin (r  / (r  + camera . position .altitude )));
209+             double  r  = wwd .getGlobe ().getRadiusAt (position .latitude , position .latitude );
210+             double  maxTilt  = Math .toDegrees (Math .asin (r  / (r  + position .altitude )));
201211            double  minTilt  = 0 ;
202212            camera .tilt  = WWMath .clamp (camera .tilt , minTilt , maxTilt );
203213        }
0 commit comments