昨天弄Camera,本来还以为不难,谁知道却被这个问题困扰了一个晚上。不知怎么地,早上突然一个猜想,然后测试,通过!因此写下本文,供大家一起学习交流。本文所用图片都是本人亲手PS的,所以转载文章、图片请注明出处。谢谢!
想自定义jMonkeyEngine中的Camera一般需要做2件事:
1、 设置摄像机视锥(ViewFrustum)的大小
2、 设置摄像机的位置和朝向
设置视锥(ViewFrustum)一般有以下2个方法:
setFrustum(float near, float far, float left, float right, float top, float bottom)
float near : 最近那个面(屏幕)离摄像机位置(你眼睛)的距离。
float far : 相当于摄像机最远那个面和你眼睛的距离。
float left : 最近那个面向左偏离你眼睛的值。
float right : 最近那个面向右偏离你眼睛的值。
float top : 最近那个面向上偏离你眼睛的值。
float bottom : 最近那个面向下偏离你眼睛的值。
该方法比较直观,也就是当你设置了一个锥体的2个截面和你距离,以及第一个截面的大小。那么你就能确定这个锥体(如下图,省略了right和bottom,原理和top、left一样)。
另一种设置视锥的方法是下面这种:
setFrustumPerspective(float fovY, float aspect, float near, float far)
float fovY : 如果一个摄像机固定,一个物体从被正视到往上移动直到看不到的角度。
float aspect : 屏幕的宽高比。
float near : 最近那个面(屏幕)离摄像机位置(你眼睛)的距离。
float far : 相当于摄像机最远那个面和你眼睛的距离。
这个方法也比较容易理解,看下面的图:
一般float fovY如果你不知道设置什么好,就设置45f,该值应该在0-90之间。你想想,如果你设置了91,那么表示摄像机上下的角度加起来将超过182,也就是你能看到自己后面的东西?而如果设置太小将形成隧道效应。
总体来说,设置视锥还是比较容易。接下来是设置位置和朝向。这很重要,决定了你能不能看到东西,就看这一步了。
设置帧(setFrame)
1、 通过setLocation(Vector3f loc)和lookAt(Vector3f pos, Vector3f worldUp)组合设置
2、 通过setFrame(Vector3f loc, Quaternion axes)
3、 通过setFrame(Vector3f loc, Vector3f left, Vector3f up, Vector3f dir)
第一种方法比较简单。大家可以试一下,就是设置Camera的位置和它看向的方向。这个我就不说了。
第二种方法我还没试过。当应该和第三种方法原理一样。
我现在就讲讲第三种,正是这种方法困扰了我一天。
先看下面这个图:
setFrame(Vector3f loc, Vector3f left, Vector3f up, Vector3f dir)
其中 loc为摄像机的位置,即视锥的顶点的在世界中的位置。而left和up则定义了camera自己的坐标系。dir为camera指向的方向。
//想在图中位置正视box,如下代码
Vector3f loc = new Vector3f(0,0,100);
Vector3f left = new Vector3f(-1,0,0);
Vector3f up = new Vector3f(0,1,0);
Vector3f dir = new Vector3f(0,0,-1);
cam.setFrame(loc, left, up, dir);
up定义了camera的上轴,由于现在该轴和世界坐标系的Y轴一样,因此为(0,1,0),由于我们想让camera在Z轴正向往Z轴负向看。因此dir应该为(0,0,-1),而由于jME中使用右手坐标系统,因此X轴此时就只能是往左。即(-1,0,0)。Z轴可以看成是视锥顶点到各个截面中心的连线所指的方向,这个很重要记住!。
注意:很多人(包括我)一开始可能会想到将Camera移动到X轴正向,然后设置dir来从右边观察位于原点的Box。如下代码:
Vector3f loc = new Vector3f(100,0,0);
Vector3f left = new Vector3f(-1,0,0);
Vector3f up = new Vector3f(0,1,0);
Vector3f dir = new Vector3f(-1,0,0);
cam.setFrame(loc, left, up, dir);
你会发现这样根本看不到box。
因为camera的坐标轴并没有改变,改变的只是dir。在坐标轴不变的情况下改变dir相当于将camera进行变形操作。而当dir和x轴或y轴为同一方向时,整个视锥相当于被压扁。它此时近似已经没有可视范围了,因此不管怎样都看不到东西了。
你还可以试试:
//想从Y轴往下看,也看不到Camera
Vector3f loc = new Vector3f(0, 100,0);
Vector3f left = new Vector3f(-1,0,0);
Vector3f up = new Vector3f(0,1,0);
Vector3f dir = new Vector3f(0, -1,0);
cam.setFrame(loc, left, up, dir);
那么怎样才能在Vector3f loc = new Vector3f(100,0,0);的情况下从右侧观察box能。很简单。确定Y轴,确定dir,让它指向世界坐标X轴负向,最后确定Camera的X轴(由右手坐标规则)。
试试:
Vector3f loc = new Vector3f(100,0, 0);
Vector3f left = new Vector3f(0,0,1);
Vector3f up = new Vector3f(0,1,0);
Vector3f dir = new Vector3f(-1,0, 0);
cam.setFrame(loc, left, up, dir);
OK了吧。
不知道怎样会不会让你更好理解一点:想要确定摄像机的朝向,那么先确定它的dir,然后确定up(因为一般都是(0,1,0)),然后把dir看成是Z轴,UP则是Y轴,这样就可以确定X轴,就是left。
注意:上面的(0,0,1)和(0,0,4)指向的是同一个方向,但是使用(0,0,4)你会发现box变形了。在这里,left、up、dir的数值除了用于计算方向,还代表单位向量的长度。因此,需要计算好。
分享到:
相关推荐
jmonkeyengine是一个面向冒险的java开发人员的三维游戏引擎。它是开源的、跨平台的、尖端的。3.2.4是jmonkeyengine 3 sdk的最新稳定版本,是一个完整的游戏开发套件。我们将发布3.2.x更新,直到主要的3.3版本到来。
Jmonkeyengine 3.0 Beginners Guide
jMonkeyEngine(jME)是一个开源的Java 3D引擎,它的效果非常好,速度也不错
NULL 博文链接:https://hjk685.iteye.com/blog/1912303
jMonkeyEngine 3.0 Beginner's Guide
sdk, 在netbeans上,基于 jMonkeyEngine3 SDK jMonkeyEngine软件开发工具包( SDK ) 欢迎使用jMonkeyEngine软件开发工具包( SDK )的知识库。 这个SDK使用jMonkeyEngine简化了 3D 个应用程序的开发。 它包含开发完整...
NULL 博文链接:https://snake.iteye.com/blog/578982
jmonkeyengine, 在Java中,一个完整的3D 游戏开发 jMonkeyEngine jMonkeyEngine是一款用于冒险Java开发人员的3D 游戏引擎。 它是开放的,跨平台的,和cutting的。 3.2.0是 jMonkeyEngine 3 SDK的最新稳定版本,一个...
共12章JME中文教程,演示代码经测试无错
jmonkeyengine:纯Java编写的一个完整的3D游戏开发套件
jMonkeyEngine软件开发套件(SDK) 欢迎使用jMonkeyEngine软件开发套件(SDK)的存储库。 该SDK简化了使用jMonkeyEngine开发3D应用程序的过程。 它包含开发完整应用程序所需的一切。 我们的SDK(或jmonkeyplatform...
JME学习文档 中文版 jMonkeyEngine 入门学习
jMonkeyEngine是一个众所周知且广泛使用的免费开放源代码游戏引擎。 该演示应用程序展示了最新的jME版本jME 3的功能和某些功能。jMonkeyEngine使用OpenGL作为其图形库。 该软件包含的一些功能包括:粒子效果,水渲染...
赛车游戏 使用 JMonkeyEngine 创建的赛车游戏。 汽车的转向非常僵硬。 按住 F 将车轮摩擦设置为 0 并改为漂移。
Voider 该游戏正在创作中。 这样做的基本思想是创建一个刺客信条Unity副本,但差别很小。 它是用Java编写并在Blender中设计的。 目前,登录,加载屏幕,游戏gui和游戏开始部分完成。 主要类别尚未连接,因此您必须...
《jmonkeyengine 3.0 初学者指南》一书的 Java 示例代码: : 包括多媒体资产、Ant 脚本和NetBeans IDE 属性。
jMonkeyEngine 3 SDK 插件向导 插件向导的实现 - 通过自动化减少创建 jmonkey 插件所需的步骤。 用法:文件 pluginWizardIterator.java 中的 instantiate() 方法是按下完成按钮时的逻辑所在。 ...