今天跟大家分享的是 3D 系列之 3D 預定義模型。
HT for Web 提供了多種基礎類型供用戶建模使用,不同於傳統的3D 建模方式,HT 的建模核心都是基於API 的介面方式,透過HT 預先定義的圖元類型和參數接口,進行設定達到三維模型的建構。接下來我們就來談談預先定義的 3D 模型及參數設定。
HT 預先定義的3D 模型有:box、sphere、cone、torus、cylinder、star、rect、roundRect、triangle、tightTriangle、parallelogram 和trapezoid 這十二種,那麼這十二種類型又是怎麼設定的呢?
在網路拓樸圖GraphView 的2D 圖形上,呈現各種圖形是透過style 中的shape 屬性決定的,HT 在3D 上提供了shape3d 屬性預定義多種3D 形體。 shape3d 屬性的預設值為 undefined,圖元顯示為六面立方圖形,當 shape3d 指定值時,則顯示為 shape3d 指定的形體,接下來我們來一一介紹 3D 模型的各個形體。
1. box:立方體,不同於預設的六面體,立方體類型的六個面顏色和貼圖只能相同,繪製表現比預設六面體高;
就如上圖所示,左邊是shape3d 設定為box,右邊是預設的六面體,兩個節點都對上表面設定了貼圖,但是從效果上看shape3d 設定為box 的節點直接無視了上表面的貼圖設置,這也應證了上面描述的,box 類型六個面的顏色和貼圖只能相同,只對shape3d.image 和shape3d.color 起效,以下是具體的設定碼:
#node = new ht.Node();
node.s3(80, 80, 80);
node.s({
'shape3d': 'box',
'shape3d.image': 'img11',
'shape3d.top.image': 'img10'});
dm.add(node);
node = new ht.Node();
node.s3(80, 80, 80);
node.p3(100, 0, 0);
node.s({
'all.image': 'img11',
'top.image': 'img10'});
dm.add(node);
##就如上圖所示,球被裁切掉了一部分,被裁切的兩個面可以單獨控制,透過shape3d.from.* 和shape3d.to.* 兩組參數就可以單獨控制兩面的顯示效果,在上圖中,我透過shape3d.to.visible 將to 的面隱藏了,將from 面透過shape3d.from.image 設定了新的貼圖,具體程式碼如下:
node.s({
'shape3d': 'sphere',
'shape3d.image': 'img11',
'shape3d.side': 100,
'shape3d.side.from': 0,
'shape3d.side.to': 65,
'shape3d.from.image': 'img10',
'shape3d.to.visible': false});
##從上圖可以看到,side 值越大,椎體就越圓滑,完全可以比擬圓錐。具體如何設定的,我們來看看代碼:
[3, 4, 5, 6, 10, 20, 40, 80, 100].forEach(function(side, index) { var x = ((index / 3) >> 0) * 100 - 100, y = index % 3 * 100 - 100; node = new ht.Node(); node.p3(x, 40, y); node.s3(80, 80, 80); node.s({ 'shape3d': 'cone', 'shape3d.image': 'img11', 'shape3d.side': side, 'note': 'side: ' + side, 'note.autorotate': true, 'note.position': 17, 'note.face': 'top', 'note.background': '#979EAF' }); dm.add(node); });
當然,椎體也可以和球體一樣,可以設定shape3d.side.from 和shape3d.side.to參數來控制裁切;也可以透過shape3d.from.* 和shape3d.to.* 參數來控制兩個面的表現效果;也可以透過shape3d.bottom.* 樣式來控制椎體地面的表現效果。
在上面的程式碼中,可以看到note 相關的設置,在這邊也順帶介紹下,note.autorotate 樣式是用來控制note 的朝向,如果設定為true ,那麼這個note 永遠是朝向眼睛的方向,不管場景如何旋轉。
4. torus:圓環,可透過shape3d.side 分成多片,結合shape3d.side.from 和shape3d.side.to 可形成半圓環等
#在上圖可以看出,圓環其實和圓錐是一樣的,也是可以設定邊數,構成三角環,四角環等形狀,當邊數達到一定的程度,邊數越多,圓環就越平滑。 ##########
在上图中可以看到 note 中多加了一个 radius 值的打印,这个值对应的是样式中的 shape3d.torus.radius,那么这个值的作用是什么呢,我想从上图也可以看得出来,radius 值是用来控制圆环的半径,但是为什么 radius 为 0.25 的时候圆环中间就被填上了,没有像其他的圆环中间都漏空呢?我们可以这样理解,一个圆环的切面有两个圆环直径,那就有四个圆环半径,那按百分比去计算的话,一个半径就是占整个图元宽的 1/4,也就是 0.25,所以这个 shape3d.torus.radius 样式的取值范围为 0~0.25。
[3, 4, 5, 6, 10, 20, 40, 80, 100].forEach(function(side, index) { var x = ((index / 3) >> 0) * 100 - 100, y = index % 3 * 100 - 100; radius = (Math.random() * 0.25).toFixed(2); node = new ht.Node(); node.p3(x, 40, y); node.s3(80, 80, 80); node.s({ 'shape3d': 'torus', 'shape3d.image': 'img11', 'shape3d.side': side, 'shape3d.torus.radius': radius, 'note': 'side: ' + side + ', radius: ' + radius, 'note.autorotate': true, 'note.position': 17, 'note.face': 'top', 'note.background': '#979EAF' }); dm.add(node); });
5. cylinder:圆柱,可通过 shape3d.top.* 和 shape3d.bottom.* 可控制顶面和底面的参数
圆柱的参数除了 shape3d.top.* 之外,其他的都和前面提到的圆锥的参数一样,因为圆柱体其实就是比圆锥体多了一个面。
[3, 4, 5, 6, 10, 20, 40, 80, 100].forEach(function(side, index) { var x = ((index / 3) >> 0) * 100 - 100, y = index % 3 * 100 - 100; node = new ht.Node(); node.p3(x, 40, y); node.s3(80, 80, 80); node.s({ 'shape3d': 'cylinder', 'shape3d.image': 'img11', 'shape3d.side': side, 'note': 'side: ' + side, 'note.autorotate': true, 'note.position': 17, 'note.face': 'top', 'note.background': '#979EAF' }); dm.add(node); });
到这里所有的可裁切的基本模型都介绍完了,下面要介绍的几个基本模型就没有 side 的相关属性了,也就意味着,它们将没有 from 和 to 的相关参数,没有裁切的功能。
如果想让不能裁切的基本图元达到裁切的效果,还是有其他方案和方法的,这些,我们就在后续的章节中介绍,还望耐心等待。
6. star:星形体,可通过 shape3d.top.* 和 shape3d.bottom.* 可控制顶面和底面的参数
7. rect:矩形体,可通过 shape3d.top.* 和 shape3d.bottom.* 可控制顶面和底面的参数
8. roundRect:圆矩形体,可通过 shape3d.top.* 和 shape3d.bottom.* 可控制顶面和底面的参数
9. triangle:三角形体,可通过 shape3d.top.* 和 shape3d.bottom.* 可控制顶面和底面的参数
10. rightTriangle:直角三角形体,可通过 shape3d.top.* 和 shape3d.bottom.* 可控制顶面和底面的参数
11. parallelogram:平行四边形体,可通过 shape3d.top.* 和 shape3d.bottom.* 可控制顶面和底面的参数
12. trapezoid:梯形体,可通过 shape3d.top.* 和 shape3d.bottom.* 可控制顶面和底面的参数
上图就是几个还未介绍的基本模型。
[ 'star', 'rect', 'roundRect', 'triangle', 'rightTriangle', 'parallelogram', 'trapezoid'].forEach(function(shape, index) { var x = index * 100 - 300; node = new ht.Node(); node.p3(x, 40, 0); node.s3(80, 80, 80); node.s({ 'shape3d': shape, 'shape3d.image': 'img11' }); dm.add(node); });
仔细观察上图,你会发现,从左算起,第二个和第四个好像在前面的例子中有见过。没错,在形状上是一样的,但是在表现上却是有些差异,到底存在什么差异呢,我们通过图来瞧瞧。
左边是基本模型 rect 和 triangle,右边是通过基本模型 cylinder 模拟出来的 rect 和 triangle,四个图元设置的大小都是一样的,边长都是 80,可以发现基本模型 rect 和 triangle 在表现上会比通过 cylinder 模拟出来的 rect 和 triangle 来的大些,原因很简单,通过 cylinder 模拟出来的 rect 和 triangle 因为其本质还是圆柱体,side 参数是是让图形能够更接近圆形而已,所以绘制出来的图形将会是在一个圆柱体内,也就是 rect 基本模型上表面的内切圆范围内,也就是说通过 cylinder 模拟出来的 rect 上表面的对角线才是图元的变成 80。
以下是相关代码,大家可以尝试下,通过不同角度的观察,可能会更好理解一些。
node = new ht.Node(); node.s3(80, 80, 80); node.p3(-50, 40, 50); node.s({ 'shape3d': 'cylinder', 'shape3d.side': 4, 'shape3d.image': 'img11'}); dm.add(node); node = new ht.Node(); node.s3(80, 80, 80); node.p3(50, 40, 50); node.s({ 'shape3d': 'cylinder', 'shape3d.side': 3, 'shape3d.image': 'img11'}); dm.add(node); node = new ht.Node(); node.s3(80, 80, 80); node.p3(-50, 40, -50); node.s({ 'shape3d': 'rect', 'shape3d.image': 'img11'}); dm.add(node); node = new ht.Node(); node.s3(80, 80, 80); node.p3(50, 40, -50); node.s({ 'shape3d': 'triangle', 'shape3d.image': 'img11'}); dm.add(node);
以上是詳細介紹基於HTML5 的WebGL技術建構3D場景的圖文程式碼(一)的詳細內容。更多資訊請關注PHP中文網其他相關文章!