我正在尝试在使用 JavaFX 8 + 3D 构建的应用程序中实现一种简单直观的方法来控制相机方向。在 OpenGL 中,有一个简单的函数,名为
gluLookAt()
,可以轻松定义从哪个点查看以及查看到哪个目标点。
JavaFX-3D 中有等效的东西吗?
OpenJDK 邮件列表中的这个答案可能对您有帮助。 看
在这里找到此代码片段:https://community.oracle.com/thread/3868043
我将代码复制到此处以确保它将来可用。没有测试过,需要确保它运行良好:
public void lookAt(Point3D cameraPosition, Point3D lookAtPos) {
//Create direction vector
Point3D camDirection = lookAtPos.subtract(cameraPosition.getX(), cameraPosition.getY(), cameraPosition.getZ());
camDirection = camDirection.normalize();
double xRotation = Math.toDegrees(Math.asin(-camDirection.getY()));
double yRotation = Math.toDegrees(Math.atan2( camDirection.getX(), camDirection.getZ()));
Rotate rx = new Rotate(xRotation, cameraPosition.getX(), cameraPosition.getY(), cameraPosition.getZ(), Rotate.X_AXIS);
Rotate ry = new Rotate(yRotation, cameraPosition.getX(), cameraPosition.getY(), cameraPosition.getZ(), Rotate.Y_AXIS);
cam.getTransforms().addAll( ry, rx,
new Translate(
cameraPosition.getX(),
cameraPosition.getY(),
cameraPosition.getZ()));
}
这是我用来旋转 3D 子场景中任意节点的实用程序。它通过为您提供布尔参数以将“内部”组转换应用于生成的仿射变换来说明对象是否位于组内部。 它考虑了代数边缘情况,其中旋转角度几乎完美 90 度(导致正切接近 0.0)
您可以在这里找到一个简单的测试应用程序来演示这一点: https://github.com/Birdasaur/Trinity/blob/main/src/test/java/edu/jhuapl/trinity/javafx/javafx3D/LookAtTest.java
代码如下:
public static Affine lookAt(Node node, Point3D from, Point3D to, boolean applyTranslate) {
//zVec is "forward"
Point3D zVec = to.subtract(from).normalize();
//ydir is "up"
Point3D ydir = Rotate.Y_AXIS;
Point3D tangent0 = zVec.crossProduct(ydir);
//handle edge case where to location is precisely the "up" direction
if (tangent0.magnitude() < 0.001) {
//pick a different axis to use
ydir = Rotate.X_AXIS;
tangent0 = zVec.crossProduct(ydir);
}
tangent0.normalize();
ydir = zVec.crossProduct(tangent0);
Point3D xVec = ydir.normalize().crossProduct(zVec).normalize();
Point3D yVec = zVec.crossProduct(xVec).normalize();
Affine affine = new Affine(
xVec.getX(), yVec.getX(), zVec.getX(), 0,
xVec.getY(), yVec.getY(), zVec.getY(), 0,
xVec.getZ(), yVec.getZ(), zVec.getZ(), 0);
if (applyTranslate) {
affine.setTx(from.getX());
affine.setTy(from.getY());
affine.setTz(from.getZ());
}
node.getTransforms().setAll(affine);
return affine;
}