Babylon.js阅读笔记一

Babylon.js101

  • 创建一个基本的Demo
    <style>
            html, body {
                overflow: hidden;
                width   : 100%;
                height  : 100%;
                margin  : 0;
                padding : 0;
            }
        
            #renderCanvas {
                width   : 100%;
                height  : 100%;
                touch-action: none;
            }
        </style>
    </head>
    <body>
        <canvas id="renderCanvas"></canvas>
    </body>
    <script>
        window.addEventListener('DOMContentLoaded', function() {
            // All the following code is entered here.
            var canvas = document.getElementById('renderCanvas');
            var engine = new BABYLON.Engine(canvas,true);
            var createScene = function(){
                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,false);  // 将相机绑定到canvas
                var light = new BABYLON.HemisphericLight('light1',new BABYLON.Vector3(0,1,0),scene); // 创建灯光
                var sphere = BABYLON.MeshBuilder.CreateSphere('sphere',{segments:16,diameter:2},scene); // 创建立方体
                sphere.position.y = 1; // 设置立方体位置
                var ground = BABYLON.MeshBuilder.CreateGround('ground1',{height:6,width:6,subdivisions:2},scene); // 创建地板
                var myPoints = [];
                var po
                return scene;
            }
            var scene = createScene();
            // 必要步骤。循环渲染
            engine.runRenderLoop(function(){
                scene.render();
            })
        });
    </script>
    

网格

  • 创建一个固定形状网格的一般形式:
    var shape = BABYLON.MeshBuilder.CreateShape(name,potions,scene);
    option参数允许你设置形状的大小以及是否可以更新它。
  • 立方体模型
    var box = BABYLON.MeshBuilder.CreateBox("box", {}, scene); // default box
    var myBox = BABYLON.MeshBuilder.CreateBox("myBox", {height: 5, width: 2, depth: 0.5}, scene);
    
    optionvalue默认值
    size每个盒子的尺寸(数字)1
    height盒子高度(数字)(设置的话会覆盖size属性)size
    width宽度(数字)(设置会覆盖size属性)size
    depth深度(数字)(设置会覆盖size属性)size
    faceColors有六个Color4类型值的数组,每个值对应立方体的一面含6个Color4(1,1,1,1)值的数组
    faceUV有六个Vector4类型值的数组,每个值对应立方体的一面含6个Color4(1,1,1,1)值的数组
    updatable网格可更新则为truefalse
    sideOrientation(数字类型) 排列方向DEFAULTSIDE

sideOrientation和Threejs的side类似,为0的时候正面隐藏只能看到形状的反面,为1时看到的是正面,为2时为双面显示

  • 球型网格

    var sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {}, scene); //default sphere
    var mySphere = BABYLON.MeshBuilder.CreateSphere("mySphere", {diameter: 2, diameterX: 3}, scene);
    
    optionvalue默认值
    segments(数字) 水平分段的数值32
    diameter球直径(数字)1
    diameterXX轴上的直径(数字),如果设置会覆盖diameterdiameter
    diameterYY轴上的直径(数字),如果设置会覆盖diameterdiameter
    diameterZZ轴上的直径(数字),如果设置会覆盖diameterdiameter
    arc(数字) 周长(纬度)在0和1之间的比率1
    slice(数字) 高度(经度)在0和1之间的比率1
    updatable网格可更新则为truefalse
    sideOrientation(数字)排列方向DEFAULTSIDE
  • 平面网格

    var plane = BABYLON.MeshBuilder.CreatePlane("plane", {}, scene); // default plane
    var myPlane = BABYLON.MeshBuilder.CreatePlane("myPlane", {width: 5, height: 2}, scene);
    
    optionvalue默认值
    size平面的尺寸1
    height高(长)度size
    width宽度size
    updatable网格可更新则为truefalse
    sideOrientation(数字类型) side orientationDEFAULTSIDE
    faceUV含一个Vector4类型值的数组,ONLY WHEN sideOrientation:BABYLON.Mesh.DOUBLESIDE setVector4(0,0,1,1)
    backUVs含一个Vector4类型值的数组,ONLY WHEN sideOrientation:BABYLON.Mesh.DOUBLESIDE setVector4(0,0,1,1)
    sourcePlane(Plane) source plane (maths) the mesh will be transformed tonull

    sourcePlane 对平面来说是一个唯一的选项,它提供一种排列摆放位置的方法,目前它的排列定向为向量vector(0,0,1)。如果你希望方向是向量vector(0,-1,1),那么你就创建一个源平面。

    var sourcePlane = new BABYLON.Plane(0, -1, 1, 0);
    sourcePlane.normalize();
    

    这就创建了一个数学平面,作为方向源。第四个参数是在方向向量方向移动的距离。

  • 地面

    var ground = BABYLON.MeshBuilder.CreateGround("ground", {}, scene); //default ground
    var myGround = BABYLON.MeshBuilder.CreateGround("myGround", {width: 6, height: 4, subdivisions: 4}, scene);
    
    optionvalue默认值
    height高(长)度size
    width宽度size
    updatable网格可更新则为truefalse
    subdivisions(数字类型) 平方细分数1

    可以通过heightMap使用CreateGroundFromHeightMap创造一个形成起伏的地面而不是一个平坦的地面。

option解释
  • Face Colors or UV
    只在数量有限的拥有不同的面的形状可用,比如一个立方体,而不是一个球体。这允许你给这些网格的每个面添加独立的颜色或图像。详情:https://doc.babylonjs.com/how_to/createbox_per_face_textures_and_colors
  • Updatable
    当网格的可更新参数设置为true时,意味着可以更改与网格的每个顶点关联的数据,从而更改网格的形状。详情:https://doc.babylonjs.com/how_to/updating_vertices
  • Side Orientation(排列顺序)
    这个选项被用来描述图形的每一个面如何被观察。
    这个选项有四个可能的值:
    BABYLON.Mesh.FRONTSIDE,//前面
    BABYLON.Mesh.BACKSIDE,// 后面
    BABYLON.Mesh.DOUBLESIDE,// 双面
    BABYLON.Mesh.DEFAULT 默认值,当前等于FRONTSIDE,
  • Front and Back UV
    当一个网格有一个Side Orientation选项并被设为DOUBLESIDE ,那么它的前面和后面才可以显示不同的图像。更多内容详见https://doc.babylonjs.com/babylon101/LINK

位移和旋转

本文仅考虑设置一个网格的位置,旋转和缩放,如果想要了解多个网格的变换和旋转参考https://doc.babylonjs.com/babylon101/position#further-reading
BabylonJs的3D场景中通过特定的方法传入数值来调整物体的位置、旋转与尺寸缩放。

  • 坐标系:对网格进行变换必须有一个参考系:用于描述位置,旋转,缩放,并有助于可视化应用这些方法效果。可视化可以帮助使用者建立一个不对称的形状。(Babylon.js使用左手坐标系)
    坐标系有两种,世界坐标系和局部坐标系。世界坐标系的位置永远不变,局部坐标系会随网格变换而变化,无论网格的位置如何,局部坐标系原点总是位于网格创建时的中心点处。不过局部坐标系原点可以通过TransformNode或利用矩阵设置pivot point来更改。
    网格进行旋转和缩放的中心点位于局部坐标系的原点处。
    在所有坐标系中,x轴为红色,y轴为绿色,z轴为蓝色。当物体网格(meshes)被创建时,它们的中心点被放置在世界坐标的原点,它们的位置总是相对于世界坐标的。
  • Vectors:所有的位移,旋转,和缩放的值都通过Vector(矢量)来设置。
  • The Pilot(这里应该翻译为网格或模型吧):网格创建之后,其中心点在世界原点处,所有轴旋转值为0,缩放值为1,世界坐标系与网格的局部坐标系重合
  • Position:使用Vector(x,y,z)使模型在世界坐标系中移动,局部坐标系随模型一起移动。
    pilot.position = new BABYLON.Vector3(2,3,4);
    
    或者分别设置:(此时局部坐标系坐标轴和世界坐标系坐标轴保持相同的方向)
    pilot.position.x  =  2;
    pilot.position.y  =  3;
    pilot.position.z  =  4;
    
  • 旋转
    注意:在3D空间中旋转很棘手,模型多次旋转时,旋转的发生顺序不同,模型的最终方向将不同,你还需要注意旋转使用的是哪个坐标系。三维建模中应用旋转有很多不同的约定,Babylon中约定的相关细节详见https://doc.babylonjs.com/resources/rotation_conventions
    babylon中旋转:
     pilot.rotation = new BABYLON.Vector3(alpha, beta, gamma);
    
    或者:(注意:旋转角度运用弧度制而非角度制)
    pilot.rotation.x  =  alpha; //绕X轴旋转
    pilot.rotation.y  =  beta;  //绕Y轴旋转
    pilot.rotation.z  =  gamma; //绕Z轴旋转
    
    在这里三个旋转给出了三个不同的轴,你可能会有疑问——“它适用于哪一个参照系?它是以什么样的顺序来描述的?以及它在哪个方向?”
    以下两种约定都是Babylon使用的,因为这两种约定都会导致相同的结果。
    公约一(以局部坐标系来描述旋转): 对于使用局部坐标轴旋转物体时,是先以Y、X、Z轴的顺序旋转网格物体的,旋转的顺序是逆时针。
    以下图像序列依次显示了图形的初始位置,然后围绕局部坐标系的Y轴旋转(顺时针还是逆时针…)90度,然后绕局部坐标系的X轴旋转90度,然后围绕局部Z轴旋转90度。 (小轴代表世界坐标轴方向)小轴代表世界坐标轴方向
    公约二(以世界坐标系来描述旋转, 与公约1相比,旋转中心及旋转轴都没有改变。):对于使用世界坐标轴旋转物体时,是先以Z、X、Y轴的顺序旋转网格物体的,旋转的顺序是逆时针。
    以下图像序列依次显示了图形的初始位置,然后绕世界坐标轴的Z轴旋转90度,然后绕世界坐标轴的X轴旋转90度,然后绕世界坐标轴的Y轴旋转90度。
    在这里插入图片描述
    当以世界坐标系来描述旋转时,以网格与世界坐标轴平行的轴,以局部坐标系原点为旋转中心来旋转,沿着坐标轴正方向看所有的旋转都是逆时针的

以下代码会产生相同的效果

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

pilot.rotation.z  =  gamma;
pilot.rotation.x  =  alpha;
pilot.rotation.y  =  beta;

pilot.rotation.y  =  beta;
pilot.rotation.z  =  gamma;
pilot.rotation.x  =  alpha;
  • 旋转队列
    现在的问题是:如果你想要一系列的旋转,从X轴开始,然后是Y轴,然后Z轴,该怎么做。对世界坐标轴和局部坐标轴而言,BabylonJs都有对应的rotate和addRotation方法 。.你可以使用addRotation将一系列旋转链接起来,如下所示,这个方法提供三次关于某个轴的旋转角度,然后将他们链式链接起来
mesh.addRotation(Math.PI/2, 0, 0).addRotation(0, Math.PI/2, 0).addRotation(0, 0, Math.PI/2);

下边的序列图像显示了上述代码的旋转过程: 从原始位置开始,绕局部坐标系X轴旋转90度,然后绕局部Y轴旋转90度,然后绕局部Z轴旋转90度。(小轴代表世界坐标轴方向)
在这里插入图片描述
在一般的网格里,使用addRotation(alpha, beta, gamma)进行旋转,通常都有其中两个属性为0。,alpha是绕局部X轴旋转,beta是绕局部Y轴旋转,gamma是绕局部Z轴旋转

  • RotationQuaternions(旋转四元数)
    旋转的另一个替代方法是rotationQuaternions,尽管他们使用起来很复杂,但可以克服万向节锁的问题。在一个网格上同时使用rotation和rotationQuaternions是不允许的,如果用了rotationQuaternions,那么rotation就会失效。详情https://doc.babylonjs.com/resources/rotation_conventions#warning
  • 缩放
    沿着局部坐标系的x,y,z轴缩放设置:
    mesh.scaling = new BABYLON.Vector3(scale_x, scale_y, scale_z);
    或者分别设置:
    mesh.scaling.y = 5;
    下图显示了一个单元立方体绕Z轴旋转,并沿局部Y轴缩放
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值