1. 程式人生 > >【Babylonjs】位置、旋轉、尺寸縮放

【Babylonjs】位置、旋轉、尺寸縮放

    BabylonJs的3D場景中通過特定的方法傳入數值來調整物體的位置、旋轉與尺寸縮放。

    無論使用什麼方法,它們都需要一個參照系,一種描述位置、旋轉或縮放的方法以及幫助視覺化應用這些效果的東西。視覺化可以幫助使用者建立一個不對稱的形狀。

參考框架

    BabylonJs一般使用世界座標系(World axes)和區域性座標系(Local axes)兩種座標系作為參考框架,其中世界座標的軸心位置不會發生改變。

    在所有圖表和場景裡上,X軸是紅色的,Y軸是綠色的,Z軸是藍色的。

    當物體網格(meshes)被建立時,它們的中心點被放置在世界座標的原點,它們的位置總是相對於世界座標的。

    區域性座標會跟隨物體網格移動。無論物體網格的位置在哪,區域性座標的原點總是在物體網格的建立中心。一個物體網格的旋轉和放大的中心在區域性座標軸原點,然而它們是可以通過TransformNode或通過矩陣來設定一個支點改變它們的中心。

向量(Vectors)

    所有的位置、旋轉和尺寸大小都由三維向量來描述,可以使用 new BABYLON.Vector3(x,y,z) 來分別設定它們。

試驗

    下圖中的試驗物體中心在世界座標的原點,所有軸的旋轉為0,尺寸大小為1,世界座標系和試驗物體的區域性座標系重合了。

Creation of Pilot

位置(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;

    試驗物體的區域性座標儲存原有的方向。

pilot position

嘗試一下

旋轉(Rotation)

    在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軸旋轉

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

    在這裡三個旋轉給出了三個不同的軸,你可能會有疑問——“它適用於哪一個參照系?它是以什麼樣的順序來描述的?以及它在哪個方向?”。

    在BabylonJs中,以下兩個公約被使用時會被認為該旋轉導致了相同的結果。

公約1 - 區域性座標軸(Local Axes)

    對於使用區域性座標軸旋轉物體時,是先以Y、X、Z軸的順序旋轉網格物體的,旋轉的順序是逆時針。
    下面的影象顯示的起始位置的按區域性座標軸的Y軸逆時針旋轉π/ 2,然後按區域性座標軸的X軸逆時針旋轉π/ 2,最後按區域性座標軸的Z軸逆時針旋轉π/ 2。

圖片.png

    較小的軸代表世界軸心的方向。

    (這裡其實乍一看比較難看懂,我自己是這麼理解的首先是看y軸從下往上看即以y軸正方向檢視,然後進行旋轉,可以看出是逆時針旋轉,其它軸也一樣,從原點到箭頭的方向看去再來理解如何旋轉)

公約2 - 世界座標軸(World Axes)

    與公約1相比,旋轉中心及旋轉軸都沒有改變。

    對於使用世界座標軸旋轉物體時,是先以Z、X、Y軸的順序旋轉網格物體的,旋轉的順序是逆時針。

    下面的影象顯示的起始位置的按世界座標軸的Z軸逆時針旋轉π/ 2,然後按世界座標軸的X軸逆時針旋轉π/ 2,最後按世界座標軸的Y軸逆時針旋轉π/ 2。

圖片.png

嘗試一下

總結

    不管你怎麼想旋轉,結果都是一樣的,下面的結果都是一樣的。

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軸逆時針旋轉π/ 2,然後繞區域性座標的Y軸逆時針旋轉π/ 2,最後繞區域性座標的Z軸逆時針旋轉π/ 2。

圖片.png

    較小的軸代表世界軸心的方向。

    在一般的網格里,使用addRotation(alpha, beta, gamma)進行旋轉,通常都有其中兩個屬性為0。

尺寸縮放(Scaling)

    尺寸是物體在沿其區域性座標縮放的時候使用的。

mesh.scaling = new BABYLON.Vector3(scale_x, scale_y, scale_z);
//或者單獨賦值
mesh.scaling.y = 5;

下圖顯示了一個單位立方體,圍繞Z軸旋轉π/2後,沿著區域性座標軸的Y軸縮放。

scaled