在three.js,可以利用THREE.Raycaster來達到點擊與交互,即選擇物體的操作。
那麼我們先來認識一下THREE.Raycaster,它的構造函數如下:
new Raycaster( origin, direction, near, far );
參數介紹:
origin — 射線的起點向量。 direction — 射線的方向向量,應該歸一標準化。 near — 投射近點,所有返回的結果應該比 near 遠。Near不能爲負,默認值爲0。 far — 投射遠點,所有返回的結果應該比 far 近。Far 不能小於 near,默認值爲無窮大。
幾個核心函數:
1、setFromCamera ( coords, camera ):
用一個新的原點和方向向量來更新射線(ray),用照相機的原點和點擊的點構成一條直線。
參數:
coords — 鼠標的二維座標,在歸一化的設備座標中,也就是X 和 Y 分量應該介於 -1 和 1 之間。
camera — 射線起點處的相機,即把射線起點設置在該相機位置處。
2、intersectObject ( object, recursive )
檢查射線和物體之間的所有交叉點(包含或不包含後代)。交叉點返回按距離排序,最接近的爲第一個。 返回一個交叉點對象數組。
參數:
object — 用來檢測和射線相交的物體。
recursive — 如果爲true,它還檢查所有後代。否則只檢查該對象本身。缺省值爲false。
3、intersectObjects( objects, recursive ),和上面的函數功能一樣,區別是這個是一個數組。
簡單示例:
var raycaster = new THREE.Raycaster();
raycaster.setFromCamera( mouse, camera );//通過鼠標點的位置和當前相機的矩陣計算出raycaster
var intersects = raycaster.intersectObjects( objects );// 獲取raycaster直線和所有模型相交的數組集合
//選中第一個射線相交的物體
if (intersects.length > 0) { SELECTED = intersects[0].object; var intersected = intersects[0].object; }
返回的intersected是一個數組,[ { distance, point, face, faceIndex, indices, object }, ... ]
distance – 射線的起點到相交點的距離
point – 在世界座標中的交叉點
face – 相交的面
faceIndex – 相交的面的索引
indices – 組成相交面的頂點索引
object – 相交的對象
知識補充:
世界座標系:在webGL中,世界座標系是以屏幕中心爲原點(0, 0, 0),且是始終不變的。你面對屏幕,你的右邊是x正軸,上面是y正軸,屏幕指向你的爲z正軸。長度單位這樣來定:窗口範圍按此單位恰好是(-1,-1)到(1,1),即屏幕左下角座標爲(-1,-1),右上角
座標爲(1,1)。
屏幕座標系:
webGL的重要功能之一就是將三維的世界座標經過變換、投影等計算,最終算出它在顯示設備上對應的位置,這個位置就稱爲設備座標。在屏幕、打印機等設備上的座標是二維座標。
視點座標系:
是以視點(照相機)爲原點,以視線的方向爲Z+軸正方向的座標系中的方向。webGL會將世界座標先變換到視點座標,然後進行裁剪,只有在視線範圍(視見體)之內的場景纔會進入下一階段的計算。