babylon101| 04. Position ,Rotation and Scaling(位置、旋转和缩放)

在babylon101中,只考虑格网的位置、旋转和缩放,有关平移、旋转的更多方法在: https://doc.babylonjs.com/babylon101/position#further-reading

利用 Pilot 作为参考框架,对位置、旋转和缩放信息进行可视化

在官方的例子中,X轴为 红色 、Y轴为 绿色 、Z轴为 蓝色

aa7ea58de4367f84047199aadf8248c1e93.jpg

  • 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;
}

7b1e7b98ac21e3c4c0fdf87b8d51c65705f.jpg

  • Position 位置

Pilot的绝对位置与世界坐标系相关,而局部坐标系随着pilot的移动而移动

移动位置的方法有:

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

或者

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

移动之后的效果如下:

40a8969f0fce1dd38001a6e11d8c4ec2a3b.jpg

  • 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;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以通过在场景中添加一个事件侦听器,然后在事件处理程序中使用raycasting技术来获取鼠标点击位置和角度。具体来说,可以使用以下代码: ``` var canvas = document.getElementById('renderCanvas'); // 获取Canvas对象 var engine = new BABYLON.Engine(canvas, true); // 创建Babylon.js引擎 var scene = createScene(); // 创建场景 // 添加鼠标点击事件 canvas.addEventListener("pointerdown", function (event) { // 计算出鼠标点击位置 var pickResult = scene.pick(scene.pointerX, scene.pointerY); // 判断是否点中物体 if (pickResult.hit) { var selectedObject = pickResult.pickedMesh; // 获取选中的物体 // 计算出鼠标点击位置和相机的角度 var cameraPosition = scene.activeCamera.position; var cameraRotation = scene.activeCamera.rotation; var pickPosition = pickResult.pickedPoint; var pickAngle = BABYLON.Vector3.Normalize(pickPosition.subtract(cameraPosition)); console.log('选中的物体: ' + selectedObject.name); console.log('鼠标点击位置: ' + pickPosition); console.log('相机角度: ' + cameraRotation); console.log('选中物体的角度: ' + pickAngle); } }); // 渲染场景 engine.runRenderLoop(function () { scene.render(); }); // 创建场景的函数 function createScene() { var scene = new BABYLON.Scene(engine); // 添加相机 var camera = new BABYLON.FreeCamera("Camera", new BABYLON.Vector3(0, 5, -10), scene); camera.setTarget(BABYLON.Vector3.Zero()); camera.attachControl(canvas, true); // 添加灯光 var light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene); light.intensity = 0.7; // 添加网格 var sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {diameter: 2}, scene); return scene; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值