DOC-03-03 镜头(Camera)

本章描述了在JavaFX 3D图形库中的Camera API。

Camera是一个可以被添加到JavaFX的场景图(Scene Graph)中的Node,因此你可以在3D UI布局中四处移动Camera。这与在2D布局中Camera固定在一个位置是不同的。

在JavaFX 的场景坐标空间中,默认的Camera投影面为Z=0,并且Camera的坐标系统如下:

● X坐标轴指向右边

● Y坐标轴指向下面

● Z坐标轴从观察者指向屏幕里面

透视镜头(Perspective Camera)

JavaFX为渲染3D场景提供了一个透视镜头(Perspective Camera)。这个Camera为透视投影定义了一个观察量(Viewing Volume)。Viewing Volumne可以通过修改fieldOfView属性的值来改变。

例3-1展示了创建Perspective Camera的两个构造方法。

例3-1 PerspectiveCamera构造方法

第二个构造方法是在JavaFX8中引入的新构造方法,并且它允许你通过指定fixedEyeAtCameraZero标志来控制Camera的位置,这样它会渲染在3D环境中Camera所看到的内容。

下面的构造方法可以在3D图形编程时用到:

当fixedEyeAtCameraZero选项被设置为true时,构造的PerspectiveCamera会将其观察点位置(Eye Position)固定到其坐标空间的(0,0,0)处,无论投影区域的范围或窗体大小如何改变均是如此。

当fixedEyeAtCameraZero被设置为默认值false时,由Camera所定义的坐标系统会将其初始位置放到面板的左上角。这种模式用于使用PerspectiveCamera来渲染2D UI,但是对大多数3D图形应用程序来说都是无用的。Camera会在窗体改变大小时移动,例如,保持初始位置在面板的左上角。这正是在2D UI 布局时你所需要的,但是在3D布局时却没有用处。因此,记住在你进行3D图形程序设计时为了改变或移动Camare,记住将fixedEyeAtCameraZero属性设置为true是非常重要的。

为了创建一个Camera并且将其添加到Scene中,可以使用下面的代码行:

使用下面的代码来将一个Camera添加到Scene Graph中。

为了旋转Camera并移动cameraGroup,可以使用下面的代码行:

视野范围(Field of View)

Camera的视野范围可以按下面的方法来设置:

视野范围越大,透视失真和大小差异就会越大。

● Fisheye镜头具有180度的视野范围。

● Normal镜头具有40到62度的视野范围。

● Telephot镜头具有1(或更小)到30度的视野范围。

裁剪面(Clipping Planes)

你可以按照下面的方法在本地坐标系统中为Camera设置近裁剪面(Near Clipping Plane):

以及按照下面的方式在本地坐标系统中为Camera设置远裁剪面(Far Clipping Plane):

设置近或远裁剪面决定了视野大小。如果近裁剪面太大,则一般会裁剪到Scene中靠前的部分。如果太小,则会开始裁剪Scene的背面。

小窍门:不要将近裁剪值设置得太小或者将远裁剪值设置得过大,因为可能会开始看见一些奇怪的东西。

裁剪面需要被设置来使得Scene的内容充分可见。但是视觉范围不能设置得过大以避免出现数值错误。如果近裁剪面被设置得过大,则Scene会开始被裁剪掉。但是如果近裁剪面被设置得过小,则由于数值过于接近零会导致出现一些奇怪的东西。如果远裁剪面被设置得过大,则会触发数值错误,尤其是当近裁剪面被设置的过小时。

Y轴向下(Y-down)坐标系 VS Y轴向上(Y-up)坐标系

大多数2D图形坐标系统(包括 UI)中Y轴坐标值会沿着屏幕向下的方向增加。包括PhotoShop、JavaFX和Illustrator中都是这样。一般来说,大多数的2D图形库都是以这种方式工作的。而很多3D图形坐标系统中Y轴坐标值是沿着屏幕向上的方向增加。也有一些3D图形坐标系统沿屏幕向上的方向增加的是Z轴坐标值,但是大多数都是沿着屏幕向上的方向增加的都是Y轴坐标值。

Y-down对比Y-up坐标系来说,在其各自的上下文中都是正确的。在JavaFX中,Camera的坐标系统是Y-down类型的,也就是说X坐标轴指向右,Y坐标轴指向下,Z坐标轴指向远离观察者或指向屏幕里面。

如果你希望3D场景是Y-up类型的,那么你可以在root之下创建一个Xform Node,称之为root3D,如例3-2所示。你可以将其rx.setAngle属性设置为180度,也就是将其翻转。然后将3D元素添加到root3D Node中并且将Camera放到root3D之下。

例3-2 创建名为root3D的Xform Node

你也可以创建名为cameraXform的Xfrom Node并将其放到root之下,如例3-3所示。你可以将其翻转,并将Camera放到cameraXform之下。

3-3 创建一个cameraXform NodeCamera camera = new

另外一个在Camera Node的处理上会有细微不同的更好的方法是为Camera增加一个180度的旋转。为了避免自动中心计算,旋转方法并不是一种常用的方法。在例3-4中,Camera被旋转了180度并且它被添加为cameraXfomr的子节点。这种方法的不同之处在于cameraXform保留了原来的值并且仍在其默认位置上,所有的东西都被归零,包括平移和旋转。

3–4 创建cameraXformRotate

使用PerspectiveCamera的样例代码

在例3-5中展示了Simple3DBoxApp样例,它创建了一个3D盒子并且使用了一个PerspectiveCamera来渲染Scene。这个样例程序是Ensemble8 Samples样例的一部分,你可以从http://www.oracle.com/technetwork/java/javase/downloads/的”JavaFX Demos and Samples”部分下载。

应用程序MSAAApp.java(见附录)也给出了一个关于如何使用Camera API的样例。
例3-5 3D Box 样例程序

打赏一下
支付宝
微信
除非注明,博客文章均为原创,转载请标明文章地址
本文地址: http://www.javafxchina.net/blog/2015/08/graphics_camera/
百度已收录