在babylon101中,只考虑格网的位置、旋转和缩放,有关平移、旋转的更多方法在: https://doc.babylonjs.com/babylon101/position#further-reading
利用 Pilot 作为参考框架,对位置、旋转和缩放信息进行可视化
在官方的例子中,X轴为 红色 、Y轴为 绿色 、Z轴为 蓝色
- Frame of Reference 参考框架
在babylonjs中存在两个坐标系, World axes 世界坐标系和 Local axes 局部坐标系
World axes 世界坐标系是固定不变的,当格网被创建时,它的中心被默认放置在世界坐标系的原点,并且坐标总是与世界坐标系有关
Local axes 局部坐标系跟随格网的移动而移动,无论格网的中心位置(世界坐标)在何处,局部坐标系位于格网中心,网格的旋转中心和放大中心都在局部轴的原点,通过TransformNode() 或者 矩阵设置 pivot point (枢轴点)可以移动局部坐标系的位置
- Vectors 矢量
所有的位置、旋转和缩放信息都由三维向量控制,利用 new BABYLON.Vector3(x,y,z) 进行设置
- The Pilot
在它创建之后,它的位置为原点,旋转度为零,缩放比例为1,世界轴和Pilot的局部轴重合
创建代码如下:
var createScene = function () {
var scene = new BABYLON.Scene(engine);
scene.clearColor = new BABYLON.Color3(.5, .5, .5);
// camera
var camera = new BABYLON.ArcRotateCamera("camera1", 0, 0, 0, new BABYLON.Vector3(2, 3, 4), scene);
camera.setPosition(new BABYLON.Vector3(10, 3, -10));
camera.attachControl(canvas, true);
// lights
var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(1, 0.5, 0), scene);
light.intensity = 0.8;
/************Start Pilot*********************************/
/************构建一个Pilot*********************************/
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);//将两个mesh合为一个
var localOrigin = localAxes(2);//创建局部坐标示意线,参数代表其轴的长度
localOrigin.parent = pilot;//将局部坐标示意线与Pilot绑定
/*************End Pilot****************************************/
//#############################################################
/*********************************Start World Axes 世界坐标系显示********************/
var showAxis = function (size) {
var makeTextPlane = function (text, color, size) {
var dynamicTexture = new BABYLON.DynamicTexture("DynamicTexture", 50, scene, true);
dynamicTexture.hasAlpha = true;
dynamicTexture.drawText(text, 5, 40, "bold 36px Arial", color, "transparent", true);
var plane = new BABYLON.Mesh.CreatePlane("TextPlane", size, scene, true);
plane.material = new BABYLON.StandardMaterial("TextPlaneMaterial", scene);
plane.material.backFaceCulling = false;
plane.material.specularColor = new BABYLON.Color3(0, 0, 0);
plane.material.diffuseTexture = dynamicTexture;
return plane;
};
var axisX = BABYLON.Mesh.CreateLines("axisX", [
new BABYLON.Vector3.Zero(), new BABYLON.Vector3(size, 0, 0), new BABYLON.Vector3(size * 0.95, 0.05 * size, 0),
new BABYLON.Vector3(size, 0, 0), new BABYLON.Vector3(size * 0.95, -0.05 * size, 0)
], scene);
axisX.color = new BABYLON.Color3(1, 0, 0);
var xChar = makeTextPlane("X", "red", size / 10);
xChar.position = new BABYLON.Vector3(0.9 * size, -0.05 * size, 0);
var axisY = BABYLON.Mesh.CreateLines("axisY", [
new BABYLON.Vector3.Zero(), new BABYLON.Vector3(0, size, 0), new BABYLON.Vector3(-0.05 * size, size * 0.95, 0),
new BABYLON.Vector3(0, size, 0), new BABYLON.Vector3(0.05 * size, size * 0.95, 0)
], scene);
axisY.color = new BABYLON.Color3(0, 1, 0);
var yChar = makeTextPlane("Y", "green", size / 10);
yChar.position = new BABYLON.Vector3(0, 0.9 * size, -0.05 * size);
var axisZ = BABYLON.Mesh.CreateLines("axisZ", [
new BABYLON.Vector3.Zero(), new BABYLON.Vector3(0, 0, size), new BABYLON.Vector3(0, -0.05 * size, size * 0.95),
new BABYLON.Vector3(0, 0, size), new BABYLON.Vector3(0, 0.05 * size, size * 0.95)
], scene);
axisZ.color = new BABYLON.Color3(0, 0, 1);
var zChar = makeTextPlane("Z", "blue", size / 10);
zChar.position = new BABYLON.Vector3(0, 0.05 * size, 0.9 * size);
};
/***************************End World Axes***************************/
showAxis(8);//显示世界坐标系 参数代表轴的长度
/*******************************Local Axes 局部坐标系显示****************************/
function localAxes(size) {
var pilot_local_axisX = BABYLON.Mesh.CreateLines("pilot_local_axisX", [
new BABYLON.Vector3.Zero(), new BABYLON.Vector3(size, 0, 0), new BABYLON.Vector3(size * 0.95, 0.05 * size, 0),
new BABYLON.Vector3(size, 0, 0), new BABYLON.Vector3(size * 0.95, -0.05 * size, 0)
], scene);
pilot_local_axisX.color = new BABYLON.Color3(1, 0, 0);
pilot_local_axisY = BABYLON.Mesh.CreateLines("pilot_local_axisY", [
new BABYLON.Vector3.Zero(), new BABYLON.Vector3(0, size, 0), new BABYLON.Vector3(-0.05 * size, size * 0.95, 0),
new BABYLON.Vector3(0, size, 0), new BABYLON.Vector3(0.05 * size, size * 0.95, 0)
], scene);
pilot_local_axisY.color = new BABYLON.Color3(0, 1, 0);
var pilot_local_axisZ = BABYLON.Mesh.CreateLines("pilot_local_axisZ", [
new BABYLON.Vector3.Zero(), new BABYLON.Vector3(0, 0, size), new BABYLON.Vector3(0, -0.05 * size, size * 0.95),
new BABYLON.Vector3(0, 0, size), new BABYLON.Vector3(0, 0.05 * size, size * 0.95)
], scene);
pilot_local_axisZ.color = new BABYLON.Color3(0, 0, 1);
var local_origin = BABYLON.MeshBuilder.CreateBox("local_origin", { size: 1 }, scene);
local_origin.isVisible = false;
pilot_local_axisX.parent = local_origin;
pilot_local_axisY.parent = local_origin;
pilot_local_axisZ.parent = local_origin;
return local_origin;
}
/*******************************End Local Axes****************************/
return scene;
}
- Position 位置
Pilot的绝对位置与世界坐标系相关,而局部坐标系随着pilot的移动而移动
移动位置的方法有:
pilot.position = new BABYLON.Vector3(2, 3, 4);
或者
pilot.position.x = 2;
pilot.position.y = 3;
pilot.position.z = 4;
移动之后的效果如下:
- Rotation 旋转
在3D空间中旋转总是很棘手,将旋转应用于形状的顺序会改变形状的最终方向,并且需要知道正在使用哪个参考框架,在三维建模中应用旋转有许多不同的约定。有babylon.js中这些约定的更多细节,请参见 Applying Rotations Convention BJS
babylon.js 中的旋转可以通过以下方法:
pilot.rotation = new BABYLON.Vector3(alpha, beta, gamma);
//or
pilot.rotation.x = alpha; //rotation around x axis 绕X轴旋转
pilot.rotation.y = beta; //rotation around y axis 绕y轴旋转
pilot.rotation.z = gamma; //rotation around z axis 绕z轴旋转
注意:旋转的角度为 弧度制 无论以何种顺序进行旋转,最终的旋转结果都是一致的
-
Sequencing Rotations 顺序旋转
对于世界坐标系 有旋转的方法
对于局部坐标系 可以利用addRotation()方法进行旋转
-
RotationQuaternions 旋转四元数
旋转的另一种选择是旋转四元数,虽然使用它们可能比较棘手,但可以克服一些常平架锁定问题。在网格上同时使用这两种方法是不可能的,请参阅 warning
-
Scaling 缩放
可以利用参数进行指定方向上的缩放,例子如下
mesh.scaling = new BABYLON.Vector3(scale_x, scale_y, scale_z);
//or
mesh.scaling.y = 5;