最简单的通过鼠标旋转相机不起作用
Most simple rotate camera via mouse not working
好吧,这让我发疯。文档很薄弱,Oracle的示例应用程序很奇怪,有一个巨大的复杂帮助程序class,甚至这里的问题都没有答案!
我基本上遵循并简化了 this tutorial,但我尝试旋转相机而不是旋转对象,因此当您拖动鼠标时,它应该绕相机旋转。
然而,尽管我已经通过控制台日志和调试确认正在调用事件处理程序,并且一切似乎都具有正确的值,但我的轮换从未发生过!我错过了什么?
此外,我根本无法移动相机,甚至(已注释掉)translateX
之类的也不起作用,所以我很困惑,但无法获得轴看起来像左上角以外的任何地方!
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.transform.Rotate;
public class RotateCameraExample extends Group {
private double anchorX, anchorY;
private double anchorAngleX = 0;
private double anchorAngleY = 0;
private DoubleProperty angleX = new SimpleDoubleProperty(0);
private DoubleProperty angleY = new SimpleDoubleProperty(0);
Camera camera;
Group axes;
public RotateCameraExample() {
axes = buildAxes();
getChildren().add(axes);
camera = new PerspectiveCamera(true);
camera.setFarClip(6000);
camera.setNearClip(0.01);
//camera.translateYProperty().set(300); // this doesn't do anything! why?
getChildren().add(camera);
initMouseControl();
}
private void initMouseControl() {
Rotate xRotate = new Rotate(0, Rotate.X_AXIS);
Rotate yRotate = new Rotate(0, Rotate.Y_AXIS);
camera.getTransforms().addAll(xRotate, yRotate);
xRotate.angleProperty().bind(angleX);
yRotate.angleProperty().bind(angleY);
setOnMousePressed(event -> {
anchorX = event.getSceneX();
anchorY = event.getSceneY();
anchorAngleX = angleX.get();
anchorAngleY = angleY.get();
});
setOnMouseDragged(event -> {
angleX.set(anchorAngleX - (anchorY - event.getSceneY()));
angleY.set(anchorAngleY + anchorX - event.getSceneX());
});
}
private Group buildAxes() {
final Box xAxis = new Box(1200, 10, 10);
final Box yAxis = new Box(10, 1200, 10);
final Box zAxis = new Box(10, 10, 1200);
xAxis.setMaterial(new PhongMaterial(Color.RED));
yAxis.setMaterial(new PhongMaterial(Color.GREEN));
zAxis.setMaterial(new PhongMaterial(Color.BLUE));
Group axisGroup = new Group();
axisGroup.getChildren().addAll(xAxis, yAxis, zAxis);
return axisGroup;
}
}
这里可以看到轴在左上角可见,我希望它在围绕它移动相机时保持在 (0, 0, 0)。
这是 Application
启动代码,这显然不是问题所在:
public class TestApp extends Application {
@Override
public void start(Stage stage) throws IOException {
RotateCameraExample g = new RotateCameraExample();
Scene scene = new Scene(g, 800, 800, Color.BLACK);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
而不是添加相机到Group
的children,
getChildren().add(camera);
你应该设置场景的相机。
scene.setCamera(g.camera);
您会立即在屏幕中央看到轴。同样,应该将鼠标处理程序应用于场景。然后,您可以在场景的处理程序中更新组的变换。
例如,下面的变体改变了相机的旋转以响应鼠标滚动事件。请注意垂直鼠标滚动如何影响绕 X 轴的旋转,而水平鼠标滚动如何影响绕 Y 轴的旋转。同样的手势也将整个团队转化为整体。一系列键盘命令使人们能够围绕 Z 轴旋转相机,沿 Z 轴推拉,并重置场景。
您可以围绕圆上的点平移和旋转,如图所示here; in contrast, this related 动画 object 围绕轴心旋转。
import javafx.application.Application;
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
/**
* @see
*/
public class RotateCameraExample extends Application {
private static class RotateCamera extends Group {
private final Camera camera;
private final Rotate xRotate = new Rotate(0, Rotate.X_AXIS);
private final Rotate yRotate = new Rotate(0, Rotate.Y_AXIS);
private final Rotate zRotate = new Rotate(0, Rotate.Z_AXIS);
public RotateCamera() {
buildAxes();
camera = new PerspectiveCamera(true);
camera.setFarClip(6000);
camera.setNearClip(0.01);
camera.setTranslateZ(-2000);
camera.getTransforms().addAll(xRotate, yRotate, zRotate);
}
private void buildAxes() {
final Box xAxis = new Box(1200, 10, 10);
final Box yAxis = new Box(10, 1200, 10);
final Box zAxis = new Box(10, 10, 1200);
xAxis.setMaterial(new PhongMaterial(Color.RED));
yAxis.setMaterial(new PhongMaterial(Color.GREEN));
zAxis.setMaterial(new PhongMaterial(Color.BLUE));
Group axisGroup = new Group();
axisGroup.getChildren().addAll(xAxis, yAxis, zAxis);
this.getChildren().add(axisGroup);
}
}
@Override
public void start(Stage stage) {
RotateCamera g = new RotateCamera();
Scene scene = new Scene(g, 800, 800, Color.BLACK);
scene.setCamera(g.camera);
stage.setScene(scene);
stage.show();
scene.setOnScroll((final ScrollEvent e) -> {
g.xRotate.setAngle(g.xRotate.getAngle() + e.getDeltaY() / 10);
g.yRotate.setAngle(g.yRotate.getAngle() - e.getDeltaX() / 10);
g.setTranslateX(g.getTranslateX() + e.getDeltaX());
g.setTranslateY(g.getTranslateY() + e.getDeltaY());
});
scene.setOnKeyPressed((KeyEvent e) -> {
KeyCode code = e.getCode();
switch (code) {
case LEFT:
g.zRotate.setAngle(g.zRotate.getAngle() + 10);
break;
case RIGHT:
g.zRotate.setAngle(g.zRotate.getAngle() - 10);
break;
case UP:
g.setTranslateZ(g.getTranslateZ() - 100);
break;
case DOWN:
g.setTranslateZ(g.getTranslateZ() + 100);
break;
case HOME:
g.xRotate.setAngle(0);
g.yRotate.setAngle(0);
g.zRotate.setAngle(0);
g.setTranslateX(0);
g.setTranslateY(0);
g.setTranslateZ(0);
break;
default:
break;
}
});
}
public static void main(String[] args) {
launch();
}
}
好吧,这让我发疯。文档很薄弱,Oracle的示例应用程序很奇怪,有一个巨大的复杂帮助程序class,甚至这里的问题都没有答案!
我基本上遵循并简化了 this tutorial,但我尝试旋转相机而不是旋转对象,因此当您拖动鼠标时,它应该绕相机旋转。
然而,尽管我已经通过控制台日志和调试确认正在调用事件处理程序,并且一切似乎都具有正确的值,但我的轮换从未发生过!我错过了什么?
此外,我根本无法移动相机,甚至(已注释掉)translateX
之类的也不起作用,所以我很困惑,但无法获得轴看起来像左上角以外的任何地方!
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.transform.Rotate;
public class RotateCameraExample extends Group {
private double anchorX, anchorY;
private double anchorAngleX = 0;
private double anchorAngleY = 0;
private DoubleProperty angleX = new SimpleDoubleProperty(0);
private DoubleProperty angleY = new SimpleDoubleProperty(0);
Camera camera;
Group axes;
public RotateCameraExample() {
axes = buildAxes();
getChildren().add(axes);
camera = new PerspectiveCamera(true);
camera.setFarClip(6000);
camera.setNearClip(0.01);
//camera.translateYProperty().set(300); // this doesn't do anything! why?
getChildren().add(camera);
initMouseControl();
}
private void initMouseControl() {
Rotate xRotate = new Rotate(0, Rotate.X_AXIS);
Rotate yRotate = new Rotate(0, Rotate.Y_AXIS);
camera.getTransforms().addAll(xRotate, yRotate);
xRotate.angleProperty().bind(angleX);
yRotate.angleProperty().bind(angleY);
setOnMousePressed(event -> {
anchorX = event.getSceneX();
anchorY = event.getSceneY();
anchorAngleX = angleX.get();
anchorAngleY = angleY.get();
});
setOnMouseDragged(event -> {
angleX.set(anchorAngleX - (anchorY - event.getSceneY()));
angleY.set(anchorAngleY + anchorX - event.getSceneX());
});
}
private Group buildAxes() {
final Box xAxis = new Box(1200, 10, 10);
final Box yAxis = new Box(10, 1200, 10);
final Box zAxis = new Box(10, 10, 1200);
xAxis.setMaterial(new PhongMaterial(Color.RED));
yAxis.setMaterial(new PhongMaterial(Color.GREEN));
zAxis.setMaterial(new PhongMaterial(Color.BLUE));
Group axisGroup = new Group();
axisGroup.getChildren().addAll(xAxis, yAxis, zAxis);
return axisGroup;
}
}
这里可以看到轴在左上角可见,我希望它在围绕它移动相机时保持在 (0, 0, 0)。
这是 Application
启动代码,这显然不是问题所在:
public class TestApp extends Application {
@Override
public void start(Stage stage) throws IOException {
RotateCameraExample g = new RotateCameraExample();
Scene scene = new Scene(g, 800, 800, Color.BLACK);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
而不是添加相机到Group
的children,
getChildren().add(camera);
你应该设置场景的相机。
scene.setCamera(g.camera);
您会立即在屏幕中央看到轴。同样,应该将鼠标处理程序应用于场景。然后,您可以在场景的处理程序中更新组的变换。
例如,下面的变体改变了相机的旋转以响应鼠标滚动事件。请注意垂直鼠标滚动如何影响绕 X 轴的旋转,而水平鼠标滚动如何影响绕 Y 轴的旋转。同样的手势也将整个团队转化为整体。一系列键盘命令使人们能够围绕 Z 轴旋转相机,沿 Z 轴推拉,并重置场景。
您可以围绕圆上的点平移和旋转,如图所示here; in contrast, this related
import javafx.application.Application;
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
/**
* @see
*/
public class RotateCameraExample extends Application {
private static class RotateCamera extends Group {
private final Camera camera;
private final Rotate xRotate = new Rotate(0, Rotate.X_AXIS);
private final Rotate yRotate = new Rotate(0, Rotate.Y_AXIS);
private final Rotate zRotate = new Rotate(0, Rotate.Z_AXIS);
public RotateCamera() {
buildAxes();
camera = new PerspectiveCamera(true);
camera.setFarClip(6000);
camera.setNearClip(0.01);
camera.setTranslateZ(-2000);
camera.getTransforms().addAll(xRotate, yRotate, zRotate);
}
private void buildAxes() {
final Box xAxis = new Box(1200, 10, 10);
final Box yAxis = new Box(10, 1200, 10);
final Box zAxis = new Box(10, 10, 1200);
xAxis.setMaterial(new PhongMaterial(Color.RED));
yAxis.setMaterial(new PhongMaterial(Color.GREEN));
zAxis.setMaterial(new PhongMaterial(Color.BLUE));
Group axisGroup = new Group();
axisGroup.getChildren().addAll(xAxis, yAxis, zAxis);
this.getChildren().add(axisGroup);
}
}
@Override
public void start(Stage stage) {
RotateCamera g = new RotateCamera();
Scene scene = new Scene(g, 800, 800, Color.BLACK);
scene.setCamera(g.camera);
stage.setScene(scene);
stage.show();
scene.setOnScroll((final ScrollEvent e) -> {
g.xRotate.setAngle(g.xRotate.getAngle() + e.getDeltaY() / 10);
g.yRotate.setAngle(g.yRotate.getAngle() - e.getDeltaX() / 10);
g.setTranslateX(g.getTranslateX() + e.getDeltaX());
g.setTranslateY(g.getTranslateY() + e.getDeltaY());
});
scene.setOnKeyPressed((KeyEvent e) -> {
KeyCode code = e.getCode();
switch (code) {
case LEFT:
g.zRotate.setAngle(g.zRotate.getAngle() + 10);
break;
case RIGHT:
g.zRotate.setAngle(g.zRotate.getAngle() - 10);
break;
case UP:
g.setTranslateZ(g.getTranslateZ() - 100);
break;
case DOWN:
g.setTranslateZ(g.getTranslateZ() + 100);
break;
case HOME:
g.xRotate.setAngle(0);
g.yRotate.setAngle(0);
g.zRotate.setAngle(0);
g.setTranslateX(0);
g.setTranslateY(0);
g.setTranslateZ(0);
break;
default:
break;
}
});
}
public static void main(String[] args) {
launch();
}
}