天天看點

玩轉 HTML5 下 WebGL 的 3D 模型交并補

玩轉 HTML5 下 WebGL 的 3D 模型交并補

CSG 對象可以用二叉樹表示,其中葉子表示基元,節點表示操作。在這個圖中,節點被标記 ∩ 為交集,∪ 為并集,- 為差集。CSG 提供的模型或表面看起來很複雜,但實際上不過是巧妙組合或分解對象。

先來看下效果圖:

玩轉 HTML5 下 WebGL 的 3D 模型交并補

從上面效果圖可以看到,我們将界面分為三個部分,這三個部分先是右邊部分上下分割,然後将整個界面左右分割,HT 用封裝好的 ht.widget.SplitView 進行界面的分割,然後将分割元件添加進底層 div 中:

是以為了最外層元件加載填充滿視窗的友善性,HT 的所有元件都有 addToDOM 函數,其思想邏輯如下,其中 iv 是 invalidate 的縮寫:

以後我們在代碼中就可以直接調用 addToDOM 函數,而不用寫一大堆代碼了,上面代碼用 addToDOM 取代之後的代碼如下,而且不用描繪 css 樣式: 

界面配置設定好之後我們就要對其添加内容了,界面的左邊部分是 HT 封裝的樹元件,我在之前的文章寫到過,樹元件是一個非常友善的繪制樹形關系的元件,開發人員能夠輕松地從資料模型 DataModel 中擷取資料和節點之間的關系放到樹上,隻需要在樹元件聲明的過程中,将對應的資料模型 DataModel 放進樹元件的參數即可,當然我們還擴充了很多跟樹元件有關的函數,非常友善實用,這裡我們隻用了 expandAll 函數,将所有對象展開:

右邊部分上下分為兩部分,都是 3D 場景,就是設定顯示有點不同,其他完全相同,上面的 3D 場景重載了 getVisibleFunc 函數,如果元素的 showMe 屬性為 true,則可視;如果節點為 ht.CSGNode 類型并且節點的 getHost 函數的參數為空,則不可視;其他情況均可視:

我們先向 3D 場景中添加元素對象,我們先解釋中間的書架,對兩邊的書架有缺的再進行補充。首先我們添加了一個 ht.CSGNode 節點 shelf,作為書架的主節點,其他的節點都是依附于這個節點的,對這個節點設定了位置、大小、名稱以及六個面的顔色,然後添加進資料模型 DataModel: 

接着向這個 shelf 中添加 10 個節點,做書架的格子效果,并設定依附關系和父子關系添加進資料模型中:

為了讓書架變得更美觀一點,我們在書架的上下左右都加上了 ht.CSGNode,最後為了更加具象化,我們還添加了一本書,實作方式也差不多,都非常簡單:

接着左邊的書架也是類似的建構方法,有一點不同的是,這邊有一個 ht.CSGBox 類型,繼承于 ht.CSGNode,其除具備父類 CSGNode 的挖空等功能外,還可對六個面進行旋轉展開關閉的操作,這裡我們的節點隻設定了前面的能夠旋轉展開,并且設定了一系列的樣式:

玩轉 HTML5 下 WebGL 的 3D 模型交并補

可能你們還想知道下面的地球是怎麼做到的?還記得之前的文章寫到過 HT 中設定了 shape3d 屬性,設定這個屬性實際上就是在操作 setShape3dModel(name, model) 和 getShape3dModel(name),可以通過這個屬性設定為 box|sphere|cylinder|cone|torus|star|rect|roundRect|triangle|rightTriangle|parallelogram|trapezoid 等等模型,這些模型也都是 HT 封裝好的,要使用時直接設定 shape3d 為其中的一個值即可,如這個例子中用到 “shape3d: sphere” 就是設定為球體。我們簡單地用一張地圖圖檔包裹在這個球體的外側,當然,這張地圖圖檔是先通過 ht.Default.setImage 注冊過的,然後通過 shape3d.image 将圖檔附到這個節點上:

最後,我們将左側的地球 earth 和右側的照片 photo 旋轉起來:

我們看到,其實雖然 HT 封裝了很多不同的 CSG 節點類型,但是實際應用都差不多,而且内容也沒有差特别多,差别都是在 style 參數上,但是真的在實際開發中,這種區分就會很大程度上加快開發速度,畢竟名稱一目了然,就知道要運用哪些 style 屬性了。

繼續閱讀