国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

基于Three.js的拾取方法的研究

2020-06-30 10:13余莉
計(jì)算機(jī)時(shí)代 2020年6期

余莉

摘? 要: Three.js是一個(gè)由JavaScript編寫的WebGL框架,可以調(diào)用API直接在瀏覽器中創(chuàng)建和渲染三維場(chǎng)景。與虛擬場(chǎng)景進(jìn)行交互的最常見方式就是鼠標(biāo)拾取,點(diǎn)擊對(duì)象可顯示所點(diǎn)擊物體信息,或修改物體屬性,或激活動(dòng)畫。文章先介紹了拾取的基本原理,再分析和實(shí)現(xiàn)了組合模型的拾取、外部導(dǎo)入模型的拾取以及拾取多個(gè)對(duì)象等三個(gè)方面的特殊應(yīng)用,對(duì)THREE.Raycaster對(duì)象的用法進(jìn)行了詳盡的介紹,能較全面地滿足拾取在教學(xué)和虛擬現(xiàn)實(shí)中的應(yīng)用。

關(guān)鍵詞: Three.js; 拾取; THREE.Raycaster對(duì)象

中圖分類號(hào):TP37? ? ? ? ? 文獻(xiàn)標(biāo)識(shí)碼:A? ? ?文章編號(hào):1006-8228(2020)06-61-04

Abstract: Three.js is a WebGL framework written with JavaScript, which can call APIs to create and render 3D scene directly in browser. The most common way to interact with the virtual scene is to pick up by the mouse. Click on object can display the information of the selected object, modify the object attributes, or activate animation. The basic principle of pick-up is introduced in this paper, and three special applications are analyzed and realized, i.e. the pick-up of group model, pick-up of external imported model and pick-up multiple objects, the usage of THREE.Raycaster object is also introduced in detail, which can meet the application of pick-up in teaching and virtual reality more comprehensively.

Key words: Three.js; pick-up; THREE.Raycaster object

0 引言

隨著前端展示技術(shù)的發(fā)展,HTML5和WebGL技術(shù)在虛擬現(xiàn)實(shí)領(lǐng)域的應(yīng)用正逐漸增多。由于瀏覽器原生支持WebGL,所以不需要安裝任何插件,即可觀看3D效果,且具有很好的跨平臺(tái)性。電腦、平板、手機(jī)等終端,只要安裝有支持HTML5的瀏覽器,即可使用。但是直接使用WebGL編程是十分復(fù)雜的,需要扎實(shí)的計(jì)算機(jī)圖形學(xué)基礎(chǔ),學(xué)習(xí)復(fù)雜的著色器語法[1]。Three.js庫(kù)是一個(gè)由JavaScript編寫的WebGL框架,實(shí)現(xiàn)了WebGL的封裝與擴(kuò)展[2],降低了初學(xué)者開發(fā)的難度。Three.js庫(kù)及其加載器可以很方便地把JSON、OBJ等格式的三維模型加載到網(wǎng)頁(yè)中來展示,并進(jìn)行光照、材質(zhì)、紋理計(jì)算后的實(shí)時(shí)渲染,用戶可使用鼠標(biāo)旋轉(zhuǎn)、平移和縮放,與虛擬場(chǎng)景進(jìn)行簡(jiǎn)單交互[3]。

1 拾取的基本原理

瀏覽器上最常見的交互就是通過鼠標(biāo)點(diǎn)擊三維物體,檢測(cè)實(shí)物圖形是否位于鼠標(biāo)指針的下方[4],即物體的拾取操作。選中的對(duì)象會(huì)改變顏色、可見性等屬性,如圖1所示,選中的立方體被改為紅色,或者激活對(duì)象的動(dòng)畫。

拾取的過程恰好與實(shí)物圖形繪制的過程相反。由于鼠標(biāo)點(diǎn)擊對(duì)應(yīng)的是瀏覽器的屏幕坐標(biāo)(X,Y),而three.js畫布是三維場(chǎng)景,所以需要將屏幕點(diǎn)擊的二維坐標(biāo)轉(zhuǎn)換為Three.js的三維坐標(biāo)(X',Y'),以確定點(diǎn)擊的對(duì)象模型,如圖2所示,實(shí)線坐標(biāo)系為二維屏幕坐標(biāo)系,左上角為原點(diǎn);虛線坐標(biāo)系為三維世界坐標(biāo)系,中心點(diǎn)為原點(diǎn)。屏幕坐標(biāo)轉(zhuǎn)換成三維場(chǎng)景坐標(biāo)代碼如下:

var vector=new THREE.Vector3((event.clientX/

window.innerWidth)*2-1,

-(event.clientY/window.innerHeight)*2+1,0.5);

vector=vector.unproject(camera);

坐標(biāo)拾取的方法涉及復(fù)雜的矩陣運(yùn)算[5],好在Three.js類庫(kù)提供了THREE.Raycaster對(duì)象用于鼠標(biāo)拾取,這是一個(gè)傳統(tǒng)的面向?qū)ο罂臻g的拾取方法[6]。其構(gòu)造函數(shù)為new Raycaster(origin,direction,near,far);其中origin是光線投射的起點(diǎn)向量,就是camera的位置;direction是光線投射的方向向量(被歸一化)。常用方法為.intersectObject(object,recursive);其中object是參與相交檢測(cè)的模型集合,返回值為相交模型的集合,該數(shù)組按距離排序,最接近視點(diǎn)的排在第一個(gè)。求交的偽代碼如下:

var raycaster=new THREE.Raycaster(camera.position,

vector.sub(camera.position).normalize());

var intersects=raycaster.intersectObjects

([參與相交檢測(cè)的模型集合]);

if (intersects.length > 0) {

//intersects[0].object為最近的拾取對(duì)象

}

//else沒有對(duì)象被拾取到

2 特殊的拾取

2.1 組合模型的拾取

⑴ 拾取組合模型的成員

可以通過Three.js自帶的功能來組合或合并已有的幾何體,創(chuàng)建出新的幾何體[7]。如圖3(a)所示的小兔子,就是通過基本的cube、sphere組合成的兔子,可以做局部(耳朵、胳膊、腿等)以及整體的動(dòng)畫。例如通過點(diǎn)擊兔子的耳朵,讓耳朵變長(zhǎng),如圖3(b)所示。設(shè)計(jì)代碼如下:

var intersects=raycaster.intersectObjects(rabbit.children);

if (intersects.length>0) {

intersects[0].object.flag=!intersects[0].object.flag;

//單擊一次true,再一次false

}

然后在requestAnimationFrame(render);回調(diào)的render()函數(shù)中添加if(rabbit.ear1.flag)rabbit.ear1.scale.y*=1.01;語句。

⑵ 拾取組合模型組

但是,使用raycaster射線無法獲取組group,只能獲取組中的元素。如果我們希望點(diǎn)擊兔子,就能讓兔子旋轉(zhuǎn),那么必須是點(diǎn)擊兔子的頭、身體或者四肢,即參與相交檢測(cè)的模型集合必須是rabbit.children,rabbit本身并不能被拾取到,如圖3(c)所示。偽代碼為:

var intersects=raycaster.intersectObjects(rabbit.children);

if (intersects.length>0) {

if (intersects[0].object.parent==rabbit)

//如果點(diǎn)擊兔子的children

rabbit.flag=!rabbit.flag; //兔子被選中或者取消選中

else

//如果有其他模型被選中時(shí)的代碼

}

然后在render()函數(shù)中添加if(rabbit.flag==rabbit) rabbit.rotation.y+=0.02;語句。

2.2 外部導(dǎo)入模型的拾取

使用基本幾何體創(chuàng)建模型的工作量較大,通過各種加載器,Three.js可以加載JSON、OBJ、STL等多種格式的模型,降低了模型制作的成本。如圖4(a)中房子的模型是用3DMAX制作的,圖4(b)中火箭是用MAYA制作的。在google chrome瀏覽器的“開發(fā)者工具”里,可以使用console.log(rocket.children);來查看火箭模型的成員,如圖4(c)所示,該火箭是由15個(gè)部分組成的。圖4(a)中的小房子是只有一個(gè)成員的數(shù)組,見圖4(d)。外部導(dǎo)入模型的拾取方式偽代碼為:

var intersects=raycaster.intersectObjects([其他拾取模型]

.concat(rocket.children));

if (intersects.length>0) {

if (intersects[0].object.parent==rocket)

//如果點(diǎn)擊火箭的children

rocketflag=!rocketflag; //rocketflag是個(gè)全局變量

else

//如果有其他模型被選中時(shí)的代碼

}

然后在render()函數(shù)中添加if (rocketflag) rocket.position.y+=0.02;語句,火箭就會(huì)升空。

2.3 拾取多個(gè)對(duì)象

通常情況下,拾取是選中離視點(diǎn)最近的那一個(gè)三維模型。但某些特殊情況下,用戶希望選中raycaster射線上所有的對(duì)象。例如在模擬一個(gè)機(jī)關(guān)槍的掃射效果時(shí),需要選中射程上的所有對(duì)象,如圖5(a)中用鼠標(biāo)表明鼠標(biāo)拾取位置,并用線框標(biāo)識(shí)射程上的兩個(gè)對(duì)象;圖5(b)是這兩個(gè)對(duì)象不可見后的效果。

代碼如下:

var intersects=raycaster.intersectObjects(scene.children,true);

//第二個(gè)參數(shù)true表明對(duì)象的所有后代也參與求交,默認(rèn)值為false

for (var i=0; i

intersects[i].object.visible=false;

//相交集合中所有元素都不可見

}

3 小結(jié)

本文針對(duì)于網(wǎng)頁(yè)中常見的拾取方式進(jìn)行設(shè)計(jì)和實(shí)現(xiàn),闡釋了傳統(tǒng)的基于對(duì)象空間的拾取方法的基本原理,并分別實(shí)現(xiàn)了對(duì)組合模型的拾取、外部導(dǎo)入模型的拾取和拾取多個(gè)對(duì)象等三方面的特殊應(yīng)用,能夠很好地滿足教學(xué)和虛擬現(xiàn)實(shí)中拾取的需求,因此該研究具有一定的應(yīng)用價(jià)值。下一步的工作可考慮虛擬場(chǎng)景漫游中碰撞檢測(cè)的快速實(shí)現(xiàn),以及提高實(shí)時(shí)繪制性能的LOD技術(shù)的應(yīng)用等。

參考文獻(xiàn)(References):

[1] 張文娟,吳瓊,曹欣然.基于WebGL的三維落葉場(chǎng)景仿真[J].計(jì)算機(jī)技術(shù)與發(fā)展,2018.28(6):171-175

[2] 趙海鵬,周楊,卞和方.基于Three.js的三維虛擬校園系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)[J].蘭州交通大學(xué)學(xué)報(bào),2019.3.

[3] 汪浩,田豐,張文俊.基于WebGL的交互平臺(tái)設(shè)計(jì)與實(shí)現(xiàn)[J].電子測(cè)量技術(shù),2015.8:119-122

[4] 寧?kù)o.基于WebGL實(shí)物交互技術(shù)及其實(shí)現(xiàn)的研究[D].華中科技大學(xué),2014.

[5] 施珂奕,鄧春健,鄒昆.基于OpenGL的三維模型點(diǎn)坐標(biāo)拾取方法[J].液晶與顯示,2016.31(7):708-713

[6] 鄒建達(dá),原力,毛力奮.基于Three.js的在仿真中的可視化和拾取研究[J].電腦與信息技術(shù),2019.5.

[7] Jos Dirksen.Three.js開發(fā)指南:WebGL的JavaScript 3D庫(kù)[M].機(jī)械工業(yè)出版社,2017.

孝义市| 岢岚县| 万源市| 林西县| 高淳县| 济源市| 高安市| 厦门市| 合作市| 堆龙德庆县| 玉溪市| 沈阳市| 云浮市| 海宁市| 通渭县| 灯塔市| 青田县| 许昌市| 汤原县| 盐源县| 宝坻区| 巨鹿县| 武宁县| 贵溪市| 辽宁省| 左云县| 砀山县| 玛多县| 田阳县| 漳浦县| 赞皇县| 永宁县| 新龙县| 长汀县| 凤山市| 遂溪县| 姜堰市| 南乐县| 嘉黎县| 连山| 岚皋县|