JavaFX 3D PerspectiveCamera坐标转换及轨道导航实现问题
问题修复方案
1. 坐标转换逻辑修正
你原有moveLocal*方法的坐标转换逻辑颠倒,沿相机本地轴向移动的正确逻辑是:获取本地轴向的单位向量,转换为父坐标系下的方向,再叠加到当前父坐标位移上。替换原移动相关方法:
private void moveLocalX(double amount) { Point3D direction = localToParent(Point3D.X_AXIS.multiply(amount)).subtract(localToParent(Point3D.ZERO)); setTranslateX(getTranslateX() + direction.getX()); setTranslateY(getTranslateY() + direction.getY()); setTranslateZ(getTranslateZ() + direction.getZ()); } private void moveLocalY(double amount) { Point3D direction = localToParent(Point3D.Y_AXIS.multiply(amount)).subtract(localToParent(Point3D.ZERO)); setTranslateX(getTranslateX() + direction.getX()); setTranslateY(getTranslateY() + direction.getY()); setTranslateZ(getTranslateZ() + direction.getZ()); } private void moveLocalZ(double amount) { Point3D direction = localToParent(Point3D.Z_AXIS.multiply(amount)).subtract(localToParent(Point3D.ZERO)); setTranslateX(getTranslateX() + direction.getX()); setTranslateY(getTranslateY() + direction.getY()); setTranslateZ(getTranslateZ() + direction.getZ()); }
2. 俯视原点配置不生效修复
问题出在额外添加的旋转变换和原有旋转变换冲突,且初始位移/角度配置不对。不需要新增pointDown变换,直接修改构造方法初始配置即可实现俯视效果:
public NavigableCamera(Scene scene) { camera = new PerspectiveCamera(true); camera.setFarClip(6000); camera.setNearClip(0.01); getChildren().add(camera); // 俯视原点配置 setTranslateY(-500); xRotate.setAngle(-90); getTransforms().addAll(xRotate, yRotate, zRotate); initKeyboardControl(scene); initMouseControl(scene); initTouchControls(scene); scene.setCamera(camera); }
3. 触摸缩放逻辑修复
你原有修改scaleZ的逻辑完全错误,缩放不会改变相机位置,直接调用修正后的moveLocalZ方法即可实现沿视角前后移动:
private void initTouchControls(Scene scene) { scene.setOnZoomStarted(event -> { z = getTranslateZ(); }); scene.setOnZoom(event -> { double delta = (event.getZoomFactor() - 1) * 100; moveLocalZ(delta); }); }
其他已知问题修复
你原有键盘事件处理代码存在语法错误,删掉多余的无效行即可:
private void initKeyboardControl(Scene scene) { scene.setOnKeyPressed(event -> { KeyCode code = event.getCode(); switch (code) { case SPACE: moveLocalZ(+10); break; case BACK_SPACE: moveLocalZ(-10); break; case RIGHT: moveLocalX(+10); break; case LEFT: moveLocalX(-10); break; case UP: moveLocalY(-10); break; case DOWN: moveLocalY(+10); break; } }); }
内容的提问来源于stack exchange,提问作者Joshua Chambers
相关产品推荐
相关产品推荐

