Babylon.js怎么移动位置和旋转

当你用babylonjs绘制出简单的元素后,是不是想让它动起来,本课教大家怎么移动物体的位置,缩放大小等。

在移动位置前,我们需要有一个坐标系,这样才能知道我们移动到哪里了。上节课,简单的说了一下,坐标系,不过不完整,这里我们在补充一下,千万不要觉得老师啰嗦哦。


Babylonjs中的坐标系

在3D世界中,有坐标系的概念,我们前面的课程已经说了Babylon.js是左手坐标系。如下图:

Babylon.js左手坐标系

上面左边那幅图是左手坐标系,右边那幅图大家自动忽略。

左手坐标系:大拇指向右是x轴,y轴向上,z轴向屏幕里面。

知道了坐标系的概念,我们来看看Babylon.js中有哪些坐标系呢?首先要学习的世界坐标系和局部坐标系。这和左手坐标系是不同的概念,不要混淆了。


坐标系之一:世界坐标系

世界坐标系是一个永远不变的坐标系,相机、场景中的物体都是在世界坐标系中的。

你可以把他理解为一个世界的中心,他的xyz坐标轴是符合左手坐标系的规则的。

例如我们可以把北京当做世界的中心,上海就位于北京的东南边。

世界坐标系.jpg

当我们说把物体放到某个位置时,一定是让他处于世界坐标系的某个位置哦。


坐标系之一:局部坐标系

局部坐标系的原点始终位于物体的创建中心,所以说局部坐标系永远和物体绑定在一起,物体的旋转和放大中心都位于局部坐标系的原点。

例如先下面的一个美女,建模的时候,她的局部坐标系的中心位置头部中心,那么这个模型围绕局部坐标系的旋转,变大缩小,就是围绕这个中心的。

babylon局部坐标系

如果上面一个美女,我们把他放到上海,那么是说,将她的放在世界坐标系的上海,而局部坐标系永远是和她自己绑定的。只有她一个人用她自己的局部坐标系,她自己的局部坐标系对别人来说没有意义。


babylonjs设置物体的位置

先看看效果,点击这里查看效果

位置是用向量来表示,如下代码

pilot.position = new BABYLON.Vector3(2, 3, 4);

这是把pilot这个物体放到世界坐标系的(2, 3, 4)这个位置。停下来30s,仔细想一下,它在哪里。

上面的代码等价于:

pilot.position.x  =  2;
pilot.position.y  =  3;
pilot.position.z  =  4;

只不过这是单独设置每个轴的位置而已。

移动

上图中,记住红色表示x轴,绿色表示y 轴,蓝色表示z轴。上图中既有局部坐标系,又有世界坐标系。pilot.position位置的设置是相对于世界坐标系的。

现在物体是不是在(2, 3, 4)的位置呢?

肯定是吧,学习过高中空间几何的同学都应该承认是吧,哈哈。

好了,废话不多说,翠花,来一份代码,不要注释的。


补充知识:绘制组合物体

上面那个有点像飞机的物体是怎么绘制的呢?这里我们补充学习一下哈:

var body = BABYLON.MeshBuilder.CreateCylinder("body", { height: 0.75, diameterTop: 0.2, diameterBottom: 0.5, tessellation: 6, subdivisions: 1 }, scene);

var arm = BABYLON.MeshBuilder.CreateBox("arm", { height: 0.75, width: 0.3, depth: 0.1875 }, scene);

arm.position.x = 0.125;

var pilot = BABYLON.Mesh.MergeMeshes([body, arm], true);

好了,废话不多说,翠花,来一份代码,看看效果,大家也可以从源码包9.html中找到这份代码。

  • 第1行代码,通过 BABYLON.MeshBuilder.CreateCylinder创建了一个圆柱体,如果不知道其参数是什么意思,你可以在这里看到,不过需要一点点英文基础。
  • 第3行:通过BABYLON.MeshBuilder.CreateBox创建一个长方体
  • 第5行,将长方体的向世界坐标的x轴移动0.125个单位。
  • 第7行, BABYLON.Mesh.MergeMeshes将2个物体合并成一个物体,这样以后操作pilot就等于操作body和arm两个物体了。BABYLON.Mesh.MergeMeshes函数人如其名,就是合并的意思。

关于合并,我们后面有时间给大家将一下,大家可以加老师的微信,不断了解最新信息哦。


babylonjs旋转物体

在3D空间中的旋转总是很复杂的,比追女孩子要容易一些。你需要知道物体旋转的顺序以及它是如何被应用于的物体旋转,同时你也需要知道该次旋转是对应哪个坐标系而产生改变的。

在BabylonJs中,物体的旋转的使用方式如下:

pilot.rotation = new BABYLON.Vector3(alpha, beta, gamma);

或者

pilot.rotation.x  =  alpha; // 围绕x轴旋转
pilot.rotation.y  =  beta;  // 围绕y轴旋转
pilot.rotation.z  =  gamma; // 围绕z轴旋转

其中α,β和γ是表示弧度的角度。3.14弧度表示180度。

在这里三个旋转给出了三个不同的轴,你可能会有疑问——“它适用于哪一个参照系?它是以什么样的顺序来描述的?以及它在哪个方向?”。


以局部坐标轴为基准旋转

物体最终的姿态,和旋转的顺序有关,例如先围绕y轴旋转,再围绕x轴旋转,和先围绕x轴旋转,再围绕y轴旋转是不一样的。

下图第一幅图是原始状态,第二幅图图显示的是按局部坐标轴的Y轴(绿色)正方向旋转π/ 2。

babylonjs旋转.jpg

ok,现在问题来了,围绕y轴旋转90度,看上面的第二幅图,为什么红色坐标是朝左边,而不是朝右边的呢?方法马上来了:

在左手坐标系中,确定旋转轴后,左手握成拳头,拇指指向旋转轴的正方向,其余手指的弯曲方向即为旋转的正方向,跟手指弯曲方向一致的旋转记为正向,相反则为负向。看一下下图的左边这幅图,你就知道为什么红色坐标是朝左边,而不是朝右边了。

babylonjs旋转.jpg

第三幅图,在第二幅图的基础上按局部坐标轴的X轴(红色)正方形旋转π/ 2。第四幅图,在第三幅图的基础上,按局部坐标轴的Z轴(蓝色)旋转π/ 2。

babylonjs旋转.jpg

你 可能会迷惑,其中有的图有2个蓝色,2个绿色坐标,以最长的为准就可以了。短的表示前一个状态的位置。