RayCastingSupport.intersectRayWithTerrain始终返回null

时间:2015-07-03 16:14:26

标签: java javafx-8 worldwind mercator

我使用自己的交互方法,因为我将NASA WorldWind嵌入JavaFX而不是Swing。视图在FXML中定义如下:

<?xml version="1.0" encoding="UTF-8"?>
...
<Pane xmlns:fx="http://javafx.com/fxml" fx:id="_mainPane"
   fx:controller="view.MainCtrl" prefWidth="1600" prefHeight="900">
   <stylesheets><URL value="@NavDb.css" /></stylesheets>
   <BorderPane><SwingNode fx:id="_worldWindFxContainer" /></BorderPane>
   ...

控制器属性:

   @FXML private SwingNode           _worldWindFxContainer;

   private final WorldWindowGLJPanel _worldWind   = new WorldWindowGLJPanel();
   private final RenderableLayer     _routeLayer  = new RenderableLayer();
   private final RenderableLayer     _alertLayer  = new RenderableLayer();
   private final Preferences         _preferences = new Preferences();

WW初始化代码:

   private void initWorldWind() {
      WorldWind.setOfflineMode( _preferences.get( "WorldWind/offline", false ));
      final OrbitView orbitVw = new FlatOrbitView();
      final EarthFlat globe   = new EarthFlat();
      final Model     model   = new BasicModel();
      globe.setProjection( FlatGlobe.PROJECTION_MERCATOR );
      model.setGlobe( globe );
      orbitVw.getOrbitViewLimits().setZoomLimits( 1.2E+04, 2.2E+07 );
      _worldWind.setModelAndView( model, orbitVw );
      _worldWind.getSceneController().setDeepPickEnabled( true );
      _routeLayer.setName( "Route-Layer" );
      _routeLayer.setPickEnabled( false );
      _alertLayer.setName( "Alert-Layer" );
      _alertLayer.setPickEnabled( true );
      _alertLayer.setEnabled( true );
      final LayerList layers = model.getLayers();
      layers.add( _routeLayer );
      layers.add( _alertLayer );
      layers.removeIf( l -> l instanceof CompassLayer  );
      layers.removeIf( l -> l instanceof WorldMapLayer );
      for(int i = 0; i < layers.size(); i++) {
         final Layer l = layers.get( i );
         if( l instanceof SkyGradientLayer ) {
            layers.set( i, new SkyColorLayer());
          }
      }
      final double lat        = _preferences.get( "Startup/initial-location-lat", 0.0 );
      final double lon        = _preferences.get( "Startup/initial-location-lon", 0.0 );
      final double zoomFactor = _preferences.get( "Startup/initial-zoom", 1.0 );
      orbitVw.setEyePosition( Position.fromDegrees( lat, lon ));
      orbitVw.setZoom( zoomFactor );
      Platform.runLater(() -> {
         final Interactions handler = new Interactions( _worldWind );
         handler.setPicker( this );
         _worldWindFxContainer.addEventHandler( InputEvent .ANY, handler );
         _worldWindFxContainer.addEventFilter ( MouseEvent .ANY, event -> {
            handler.handle( event );
            event.consume();
         });
         _worldWindFxContainer.addEventFilter ( ScrollEvent.ANY, event -> {
            handler.handle( event );
            event.consume();
         });
      });
      _worldWind.redrawNow();
   }

来自JavaFx初始化代码:

   SwingUtilities.invokeLater( this::initWorldWind );

互动课程:

public final class Interactions implements EventHandler<InputEvent> {

   private final WorldWindowGLJPanel _wwPanel;
   private final SceneController     _sceneController;
   private final OrbitView           _view;

   public Interactions( WorldWindowGLJPanel wwPanel ) {
      _wwPanel         = wwPanel;
      _sceneController = _wwPanel.getSceneController();
      _view            = (OrbitView)_sceneController.getView();
   }

   private Position getPositionFromScreenPoint( double x, double y ) {
      final View vw  = _sceneController.getView();
      final Line ray = vw.computeRayFromScreenPoint( x, y );
      if( ray != null ) {
         final Globe globe = _sceneController.getModel().getGlobe();
         final Vec4 origin = ray.getOrigin();
         final Vec4 direction = ray.getDirection().normalize3();
         final Position pos =
            RayCastingSupport.intersectRayWithTerrain( globe, origin, direction );
         return pos;
      }
      return null;
   }
从FX鼠标处理程序调用

Interactions.getPositionFromScreenPoint

问题是:我从世界的球形表示切换到平面表示后,RayCastingSupport.intersectRayWithTerrain()始终返回null。

1 个答案:

答案 0 :(得分:1)

我还没有找到真正的答案,但写了一个简化的方法来处理鼠标点击以移动平面地图:

   private Position getPositionFromScreenPoint( double x, double y ) {
      final View           vw        = _sceneController.getView();
      final Line           ray       = vw.computeRayFromScreenPoint( x, y );
      final Vec4           origin    = ray.getOrigin();
      final Vec4           direction = ray.getDirection().normalize3();
      final Globe          globe     = _sceneController.getModel().getGlobe();
      final double         gme       = globe.getMaxElevation();
      final Intersection[] inters    = globe.intersect( new Line( origin, direction ), gme );
      if( inters != null ) {
         final Vec4     pt  = inters[0].getIntersectionPoint();
         final Position pos = globe.computePositionFromPoint( pt );
         return pos;
      }
      return null;
   }

我不明白为什么我必须为inters检查null,但有时候,它是空的......