2015-07-03 4 views
1

Я использую свой собственный метод взаимодействия, потому что я внедряю NASA WorldWind в JavaFX, а не в Swing. Просмотр определяется в FXML следующим образом:RayCastingSupport.intersectRayWithTerrain всегда возвращает null

<?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; 
    } 

Interactions.getPositionFromScreenPoint вызывается из FX-мышки.

Проблема: RayCastingSupport.intersectRayWithTerrain() всегда возвращает null после того, как я переключаюсь с сферического представления мира на плоский.

ответ

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