什么是HTML5中WebG的3D網(wǎng)絡(luò)拓撲結(jié)構(gòu)圖

這篇文章將為大家詳細講解有關(guān)什么是HTML5中WebG 的3D網(wǎng)絡(luò)拓撲結(jié)構(gòu)圖,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。

為達州等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計制作服務(wù),及達州網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、達州網(wǎng)站設(shè)計,以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!

現(xiàn)在,3D 模型已經(jīng)用于各種不同的領(lǐng)域。在醫(yī)療行業(yè)使用它們制作器官的精確模型;電影行業(yè)將它們用于活動的人物、物體以及現(xiàn)實電影;視頻游戲產(chǎn)業(yè)將它們作為計算機與視頻游戲中的資源;在科學(xué)領(lǐng)域?qū)⑺鼈冏鳛榛衔锏木_模型;建筑業(yè)將它們用來展示提議的建筑物或者風景表現(xiàn);工程界將它們用于設(shè)計新設(shè)備、交通工具、結(jié)構(gòu)以及其它應(yīng)用領(lǐng)域;在最近幾十年,地球科學(xué)領(lǐng)域開始構(gòu)建三維地質(zhì)模型,而且 3D 模型經(jīng)常做成動畫,例如,在故事片電影以及計算機與視頻游戲中大量地應(yīng)用三維模型。它們可以在三維建模工具中使用或者單獨使用。為了容易形成動畫,通常在模型中加入一些額外的數(shù)據(jù),例如,一些人類或者動物的三維模型中有完整的骨骼系統(tǒng),這樣運動時看起來會更加真實,并且可以通過關(guān)節(jié)與骨骼控制運動。

這些種種都讓我們前端開發(fā)者覺得如果我們可以不用學(xué)習 unity3d 或者其他游戲開發(fā)工具就能實現(xiàn) 3D 效果,而且能夠精準的靠代碼來控制移動或者方向就好了。。。于是我利用 HT For Web 中的 3D組件 來實現(xiàn)了一個小例子,用了 HT 中 3D組件 的大部分功能,做這個例子就是想把 3D 組件好好的掌握,盡量放進一個例子中,到時候別人有需要就可以參考了。

先來看看整體實現(xiàn)的效果圖:

什么是HTML5中WebG 的3D網(wǎng)絡(luò)拓撲結(jié)構(gòu)圖

用 HT for Web,現(xiàn)有的 3d 模板創(chuàng)建三層底板不是問題,問題是要如何將圖中第一層的“電腦”和“機柜組件”放上去?我是在網(wǎng)上 down 下來的 obj 格式的文件,然后我利用 HT 中的 ht.Default.loadObj(objUrl, mtlUrl, params) 函數(shù)將模型加載進去,其中的 params 部分可以參考 http://www.hightopo.com/guide...,代碼如下:

ht.Default.loadObj('obj/機柜組件1.obj', 'obj/機柜組件1.mtl', {  //加載 obj 文件
    cube: true,  //是否將模型縮放到單位1的尺寸范圍內(nèi),默認為false
    center: true,  //模型是否居中,默認為false,設(shè)置為true則會移動模型位置使其內(nèi)容居中
    shape3d: 'box',  //如果指定了shape3d名稱,則HT將自動將加載解析后的所有材質(zhì)模型構(gòu)建成數(shù)組的方式,以該名稱進行注冊
    finishFunc: function(modelMap, array, rawS3){  //用于加載后的回調(diào)處理 
      if(modelMap){  
        device2 = createNode('box', floor1);  //創(chuàng)建一個節(jié)點,在第一層“地板”上
    device2.p3([x1-120, y1+13, z1+60]);  //設(shè)置這個節(jié)點坐標
    device2.s3(rawS3);  //設(shè)置這個節(jié)點大小
    createEdge(device1, device2);  //創(chuàng)建連線
    device3 = createNode('box', floor1);  
    device3.s3(rawS3);  
    device3.p3([x1+120, y1+13, z1+60]);  
    createEdge(device1, device3);  
      }  
    }  
});

其中 finishiFunc 函數(shù)中的三個參數(shù)定義如下:

  • modelMap:調(diào)用 ht.Default.parseObj 解析后的返回值,若加載或解析失敗則返回值為空

  • array:所有材質(zhì)模型組成的數(shù)組

  • rawS3:包含所有模型的原始尺寸

一般在實際應(yīng)用中我們都會將圖元的大小設(shè)置為模型的原始尺寸。

“電腦”上方有個紅色的立體能旋轉(zhuǎn)的“警告”,是依靠 ht.Default.setShape3dModel 函數(shù)(HT for Web 建模手冊 http://www.hightopo.com/guide... 3d 模型,在 ht 中,封裝好的建模函數(shù)有很多,比較基礎(chǔ)的就是球體,圓柱,立方體等等,這邊我用的是構(gòu)造環(huán)形的方法 createRingModel 來生成“警告”最外面的環(huán),感嘆號的上部分就是用的 createSmoothSphereModel 構(gòu)造的球體,感嘆號的下部分就是用 createSmoothCylinderModel 來構(gòu)造的圓柱。我一開始直接使用了 3d 模型中封裝好的函數(shù),導(dǎo)致后來根本不知道函數(shù)中使用的參數(shù)是做什么用的,而且也不明白 3d 模型是怎么構(gòu)成的,然后自己又重新看了前面的“模型基礎(chǔ)”,才知道原來 3d 模型采用的一個面,最基礎(chǔ)的是三角面,之后復(fù)雜的面也是由多個三角面來形成的,然后繞著一根特定的軸旋轉(zhuǎn)之后形成的,當然,這個軸是你來決定的,不同的軸可以生成不同的形狀,對于顏色等風格方面的設(shè)置可以參考 HT for Web 風格手冊(http://www.hightopo.com/guide...。至于如何讓這個 3d 模型旋轉(zhuǎn)起來,ht 中封裝了 addScheduleTask(Task) 方法,我在第三層 Task 中調(diào)用了 ht 封裝的一個旋轉(zhuǎn)函數(shù) setRotation 來設(shè)置旋轉(zhuǎn)的順序和方向,并且指定了旋轉(zhuǎn)的對象。以下是自定義“警告”的 3d 模型的方法(注意:因為本例的模型是自定義組合的,如果要設(shè)置整體模型的顏色要用 “all.blend” style 屬性):

function createAlarm(device, formPane) {
    var ringModel = ht.Default.createRingModel([ 8, 1, 10, 1, 10, -1, 8, -1, 8, 1 ], null, null, false, false, 100);//根據(jù)xy平面的曲線,環(huán)繞一周形成3D模型。
    var sphereModel = ht.Default.createSmoothSphereModel(8, 8, 0, Math.PI*2, 0, Math.PI, 2);//構(gòu)建光滑球體模型 
    var cylinderModel = ht.Default.createSmoothCylinderModel(8, true, true, 1, 2, 0, Math.PI*2, 8);//構(gòu)建光滑圓柱體模型
    
    var alarmArr = [//組合模型 由三個模型ringModel、sphereModel、cylinderModel組合而成
        {
          shape3d: ringModel,//定義模型類型
          r3: [Math.PI/2, 0, 0],//設(shè)置旋轉(zhuǎn)角度
          color: {//設(shè)置模型顏色
            func: 'style@all.blend',//數(shù)據(jù)綁定style樣式中的all.blend屬性,可通過data.s()獲取和設(shè)置這個屬性
          }
        },{
          shape3d: sphereModel,
          t3: [0, 4, 0],
          color: {
            func: 'style@all.blend',
          }
        },{
          shape3d: cylinderModel,
          t3: [0, -3, 0],
          color: {
            func: 'style@all.blend',
          }
        }
    ];
    ht.Default.setShape3dModel('alarm', {//注冊自定義3D模型
      shape3d: alarmArr
    });

    var alarmTip = createNode('alarm', device);//創(chuàng)建shape3d為alarm的節(jié)點
    alarmTip.s3([2, 2, 2]);//設(shè)置節(jié)點大小
    alarmTip.p3(device.p3()[0], device.p3()[1]+60, device.p3()[2]);
    alarmTip.s('all.blend', 'red');//改變此屬性可改變模型的顏色,因為模型創(chuàng)建的時候已經(jīng)數(shù)據(jù)綁定了

    return alarmTip;
}

接下來看看怎么讓這個“告警”節(jié)點“閃爍”,我是直接將這個動畫跟節(jié)點綁定,這樣可以直接通過節(jié)點來控制動畫。所以在上面我們創(chuàng)建 alarm 的模型時就可以直接將動畫綁在節(jié)點上:

if(formPane){
    alarmNode.scaleFunc = function() {//設(shè)置大小變化動畫
        var size = alarmNode.s3();//獲取節(jié)點的大小
        if (size[0] === 2 && size[1] === 2 && size[2] === 2) alarmNode.s3([1, 1, 1]);
        else alarmNode.s3([2, 2, 2]);
        alarmNode.scaleTimer = setTimeout(alarmNode.scaleFunc, formPane.v('scaleInterval'));//設(shè)置動畫
    }
    alarmNode.blinkFunc = function(){//設(shè)置閃爍的動畫
        var color = alarmNode.s('all.blend');//獲取節(jié)點的style樣式
        if (color === 'red') alarmNode.s({'all.blend': 'yellow'});//如果節(jié)點顏色為紅色,那么設(shè)置為黃色
        else alarmNode.s({'all.blend': 'red'});
        alarmNode.blinkTimer = setTimeout(alarmNode.blinkFunc, formPane.v('blinkInterval'));
    }
    alarmNode.rotateFunc = function() {//設(shè)置旋轉(zhuǎn)動畫
        alarmNode.setRotation(alarmNode.getRotation() + Math.PI/20);//獲取節(jié)點當前的旋轉(zhuǎn)角度,在這個旋轉(zhuǎn)角度之上添加 Math.PI/20 個角度
        alarmNode.rotateTimer = setTimeout(alarmNode.rotateFunc, formPane.v('rotInterval'));
    }
}

上面的動畫我設(shè)置了可以通過 form 表單面板上的屬性來控制節(jié)點閃爍的速度,以及閃爍節(jié)點的動畫等等,主要說一下這個功能在 form 表單上的實現(xiàn):

formPane.addRow([//向form表單面板上添加一行元素
    {
        checkBox: {//復(fù)選框
            label: 'Enable Blink',//復(fù)選框?qū)?yīng)的文本內(nèi)容
            selected: true,//設(shè)置選中復(fù)選框
            onValueChanged: function(){//復(fù)選框值變化時回調(diào)的函數(shù)
                var data = dataModel.getDataByTag('colorAlarm');//通過tag標簽獲取節(jié)點
                if (this.getValue()) {//獲取復(fù)選框當前值true/false
                    data.blinkTimer = setTimeout(data.blinkFunc, formPane.v('blinkInterval'));//直接通過設(shè)置節(jié)點的blinkTimer來設(shè)置動畫
                }
                else {
                    clearTimeout(data.blinkTimer);//清除動畫
                }
            }
        }
    },
    {
        id: 'blinkInterval',//form可以通過getValue(簡寫為v)來獲取這個item的值
        slider: {//設(shè)置了該屬性后HT將根據(jù)屬性值自動構(gòu)建ht.widget.Slider對象,并保存在element屬性上
            min: 0,//滑動條最小值
            max: 1000,//滑動條最大值
            step: 50,//滑動條步進
            value: 500,//當前滑動條的值
        }
    }
], [0.1, 0.1]);//設(shè)置這行的兩個item元素的寬度小于1的值為比例

最后來說說 3D 管線上的小球流動的部分,這個功能確實非常實用,而且做出來的效果也確實不錯,跟大家分享~

首先,創(chuàng)建一條連線連接起始節(jié)點和結(jié)束節(jié)點并設(shè)置這個連線的樣式,用 ht.Edge 可以將連線吸附在起始節(jié)點和結(jié)束節(jié)點上,這樣移動這兩個節(jié)點中的任意一個節(jié)點連線都會跟著節(jié)點移動的位置變化,非常方便:

var polyline = new ht.Edge(source, target);//創(chuàng)建連線
dataModel.add(polyline);//將連線添加進數(shù)據(jù)容器中
polyline.s({
    'edge.width': 5,//連線寬度
    'edge.type': 'points',//連線類型 為points時連線走向?qū)⒂蒭dge.points屬性決定,用于繪制折線
    'edge.points': [//可設(shè)置類型為ht.List的{x:100, y:100}格式的點對象數(shù)組,當edge.type為points時起作用
        {x: source.getPosition3d()[0]+200, y: source.getPosition3d()[2], e: source.getPosition3d()[1]},
        {x: target.getPosition3d()[0]+400, y: target.getPosition3d()[2], e: target.getPosition3d()[1]}
    ],
    'edge.segments': [1, 4],//用于描述點連接樣式,數(shù)組元素為整型值
    'shape3d': 'cylinder',//圓柱
    'shape3d.color': 'rgba(242, 200, 40, 0.4)',
    'shape3d.resolution': 30,//微分段數(shù),可以決定曲線的平滑度
    'edge.source.t3': [20, 0, 0],//連線source端偏移,[tx, ty, tz]格式,默認為空
    'edge.target.t3': [20, 0, 0]//連線target端偏移,[tx, ty, tz]格式,默認為空
});

因為我們在創(chuàng)建連線的時候設(shè)置的 points 僅為曲線上的兩個點,所以如果要獲取曲線目前形成的點,是缺少 source 和 target 兩個點的,我們重新設(shè)置一個數(shù)組,將這兩個點添加進去,后面獲取曲線上所有點時會用上:

var list = new ht.List();
list.push({x: source.getPosition3d()[0], y: source.getPosition3d()[2], e: source.getPosition3d()[1]});//向數(shù)組中添加source點
polyline.s('edge.points').each(function(item){//添加style屬性中已設(shè)置的兩個點
    list.push(item);
});
list.push({x: target.getPosition3d()[0], y: target.getPosition3d()[2], e: target.getPosition3d()[1]});//添加target點

然后創(chuàng)建一個在管線上滑動的小球節(jié)點,這是僅是設(shè)置節(jié)點,真正添加進數(shù)據(jù)容器 dataModel 中需要設(shè)置完小球的坐標時再添加,如果沒有給節(jié)點設(shè)置位置就將節(jié)點添加進數(shù)據(jù)容器中,節(jié)點的初始位置就是 3D 場景的正中心 [0, 0, 0] 的位置。小球滑動的動畫代碼如下:

var ball = new ht.Node();//創(chuàng)建小球節(jié)點
ball.s({//設(shè)置小球節(jié)點的樣式
    'shape3d': 'sphere',//設(shè)置小球的3d模型為球形
    'shape3d.color': 'rgba(40, 90, 240, 0.4)'//設(shè)置3d模型的顏色
});

var delta = 10, flag = 0;
setInterval(function(){
    flag++;
    var length = (polyline.a('total') || 0) % polyline.a('length') + delta;//小球當前走過的曲線長度
    var cache = ht.Default.getLineCacheInfo(list, polyline.s('edge.segments'));//獲取曲線上的點的信息
    var lineLength = ht.Default.getLineLength(cache);//獲取曲線的總長度
    polyline.a('length', lineLength - 50);//因為我設(shè)置了edge的t3(相當于2d中的offset),所以線段長度實際沒有那么長
    var offset = ht.Default.getLineOffset(cache, length);//曲線根據(jù)曲線上點的信息的偏移量
    ball.setPosition3d(offset.point.x + 10, offset.point.y, offset.point.z);//設(shè)置節(jié)點的坐標
    polyline.a('total', length);
    if(flag === 1) dataModel.add(ball);//這時候節(jié)點已經(jīng)有了坐標了,可以添加進數(shù)據(jù)容器中了
}, 10);

我們還可以看到第二層上有兩個特殊的多邊形“平行四邊形”和“梯形”,平行四邊形是靠 createParallelogramModel 模型函數(shù),這個函數(shù)比較簡單,createExtrusionModel(array, segments, top, bottom, resolution, repeatUVLength, tall, elevation),array 是你要形成的圖形的坐標點,這邊只是針對于 xz 軸上畫的平面圖形,segments 指的是如何連接這幾個坐標點,可參考 HT for Web 形狀手冊(http://hightopo.com/guide/gui...),top 和 bottom 就是讓你選擇是否有頂部或者底部,resolution 微分段數(shù),我們描繪一段曲線的時候可能只要確認幾個個別的點然后在每兩個點之間的連線上把它分成多個段,這樣這條線段就會變得平滑,ht 為了用戶能夠輕松操作這些線段,就封裝了這一個參數(shù),repeatUVLength 默認為空,設(shè)置值后頂部和底部的貼圖將根據(jù)制定長度值進行重復(fù),tall 模型的高度,默認為 5,elevation 模型中心的 y 軸位置,默認值為 0,設(shè)置這個值可以使 xz 上的平面繞著 y 軸旋轉(zhuǎn)。

底層的一個環(huán)形的效果是通過一個算法來實現(xiàn)的,環(huán)形得確認這個環(huán)形上有多少個元素,然后算每兩個之間的角度,在通過 sin、cos 來計算每一個元素的位置,得出了如下代碼:

names = ['設(shè)備2', '設(shè)備3', '設(shè)備4', '設(shè)備5', '設(shè)備6', '設(shè)備7', '設(shè)備8', '設(shè)備9'];  
names.forEach(function(name, index) {  
    x = 400, y = 200, angle = 45, r = 120;  
    x = x3 + Math.sin((2 * Math.PI / 360) * angle * index) * r;  
    y = z3 + Math.cos((2 * Math.PI / 360) * angle * index) * r;  
    device = createRect([x, y3 + 15, y], [w * 0.1, 15, h * 0.1], '', '', floor3);  
    createEdge(device5, device);  
});

關(guān)于什么是HTML5中WebG 的3D網(wǎng)絡(luò)拓撲結(jié)構(gòu)圖就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

當前文章:什么是HTML5中WebG的3D網(wǎng)絡(luò)拓撲結(jié)構(gòu)圖
分享路徑:http://muchs.cn/article30/gddcpo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序、網(wǎng)站建設(shè)、網(wǎng)站制作、移動網(wǎng)站建設(shè)動態(tài)網(wǎng)站、網(wǎng)站內(nèi)鏈

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化