javafx - 相对于javafx中的视图移动相机?
问题描述
我的场景中有一个摄像机,我目前正在使用 WASD 在 xy 和 z 轴上移动。但是,我希望它根据它所面临的方向移动。为了更好地说明我的意思,我使用程序搅拌器中的片段来演示这个想法。
在图 1 中,这很容易。向前移动只会在 x(红色)轴上移动,向两侧移动将在 y(绿色)轴上移动。当相机旋转时会出现问题,从而改变它相对于轴的位置,如顶视图中的图像 2 所示:
如果我现在尝试向前移动(红色箭头的方向),我需要移动以适应旋转,并调整 x 和 y 坐标,以便相机从其视角向前移动。
有没有办法做到这一点?我已经尝试了许多涉及正弦和余弦的计算,以及很多谷歌搜索,但它没有导致任何结果。谷歌大多使用 OpenGL 显示未解决的问题或解决方案,而我的数学方程式只是吐出不正确的结果。
我希望我清楚地解释了这个问题,如果没有,我很乐意提供更多信息。感谢您的时间!
解决方案
我知道我迟到了 3 个月,但我想我知道你的意思。
在 JavaFX 中,您有一个名为 world 的组(除了相机之外的所有 3d)。如果要将相机向左旋转(例如围绕 y 轴),则不要触摸相机而是触摸世界并围绕 y 轴旋转它。
老实说,我不是 100% 理解它为什么有效,但它对我有用(我正在开发一款游戏,所以我必须经历它)。
我希望这能回答你的问题:D
编辑 1:示例代码
package FXTesting;
import javafx.application.Application;
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.input.KeyEvent;
import javafx.scene.shape.Box;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;
public class Main extends Application {
public static int SIZEFACTOR = 100;
@Override
public void start(Stage primaryStage) throws Exception {
Group world = createEnvironment();
Scene scene = new Scene(world);
primaryStage.setScene(scene);
primaryStage.setWidth(16 * SIZEFACTOR);
primaryStage.setHeight(9 * SIZEFACTOR);
Camera camera = new PerspectiveCamera();
camera.setFarClip(2000);
camera.setNearClip(1);
scene.setCamera(camera);
Rotate worldRotX = new Rotate(0, Rotate.X_AXIS);
Rotate worldRotY = new Rotate(0, Rotate.Y_AXIS);
Translate worldTransX = new Translate();
world.getTransforms().addAll(worldRotY, worldRotX);
primaryStage.addEventHandler(KeyEvent.KEY_PRESSED, event -> {
switch(event.getCode()){
case LEFT:
worldRotY.setAngle(worldRotY.getAngle() + 10);
break;
case RIGHT:
worldRotY.setAngle(worldRotY.getAngle() - 10);
break;
case UP:
worldRotX.setAngle(worldRotX.getAngle() + 10);
break;
case DOWN:
worldRotX.setAngle(worldRotX.getAngle() - 10);
case W: //w/s is for z
world.setTranslateZ(world.getTranslateZ() + 10);
break;
case S:
world.setTranslateZ(world.getTranslateZ() - 10);
break;
case A:// a/d is x axis
world.setTranslateX(world.getTranslateX() + 10);
break;
case D:
world.setTranslateX(world.getTranslateX() - 10);
break;
case SHIFT:// shift/contr is for y axis
world.setTranslateY(world.getTranslateY() + 10);
break;
case CONTROL:
world.setTranslateY(world.getTranslateY() - 10);
break;
}
});
primaryStage.show();
}
private Group createEnvironment(){
Group group = new Group();
Box ground = new Box();
ground.setHeight(10);
ground.setWidth(1000);
ground.setDepth(1000);
ground.setTranslateX(-500);
ground.setTranslateZ(-500);
Box box = new Box(100,100,100);
box.setTranslateY(10);
group.getChildren().addAll(ground, box);
return group;
}
public static void main(String... args){
launch(args);
}
}
推荐阅读
- xamarin - 如何在 Xamarin Forms Android 的屏幕上显示通知弹出窗口?
- android - 在 Android 9 中键入时,文本不会出现在 EditText 字段中
- javascript - 内联进度条动画,将触发器更改为从加载滚动?
- plugins - 如何从我的简单 .dart 文件创建插件以在 Flutter 中使用?
- ios - “TWTRInvalidInitializationException” Twitter 登录崩溃应用程序 Ionic 4
- c# - How to group a list so that a single record for a day on a DateTime field is retrived using Linq?
- android - 错误:不兼容的类型:NonExistentClass 无法转换为注解 @error.NonExistentClass()
- python - Tensorflow model.fit() 返回所有浮点输入的 NaN
- ruby-on-rails - 唯一索引和标准索引是分开做的吗?
- java - 如何从二维对象数组中获取数据?