摘要:寫在前面的前面現(xiàn)在拍電影搞真人秀都流行拍續(xù)集,哥今天給大家?guī)?lái)的是打造最美機(jī)房的續(xù)集,哥的目標(biāo)是成為機(jī)房界的網(wǎng)紅。機(jī)柜標(biāo)簽機(jī)房中最重要的物理資源機(jī)柜是機(jī)房管理規(guī)劃監(jiān)控人員最關(guān)注的對(duì)象之一。
寫在前面的前面
現(xiàn)在拍電影、搞真人秀都流行拍續(xù)集,哥今天給大家?guī)?lái)的是打造最美3D機(jī)房的續(xù)集,哥的目標(biāo)是成為3D機(jī)房界的網(wǎng)紅。
-------------------------------我是這個(gè)系列已經(jīng)有了第三篇的分割線-------------------------------
前情提要請(qǐng)腦補(bǔ)畫外音 Previously on Monolog……
前陣子寫了一篇打造最美html5 3d機(jī)房,介紹了如何用html5在網(wǎng)頁(yè)上創(chuàng)建無(wú)插件的精美3d機(jī)房場(chǎng)景,收到很多朋友的鼓勵(lì),深表感謝。對(duì)于索要源代碼的朋友,已經(jīng)盡力郵件回復(fù)。由于精力所限,如未能收到的朋友請(qǐng)留言或給我發(fā)送郵件:[email protected]。最近項(xiàng)目第二期又要緊鑼密鼓地開(kāi)始了,所以想抓緊把一些新增的內(nèi)容補(bǔ)充上,進(jìn)一步完善這個(gè)html5 3d機(jī)房的呈現(xiàn)效果。
上一篇中主要介紹的是如何從最基礎(chǔ)的webgl封裝到創(chuàng)建3d物體對(duì)象,再通過(guò)3d物體對(duì)象“搭積木”式的組建整個(gè)3d機(jī)房場(chǎng)景。這一篇主要介紹一些如何在這個(gè)場(chǎng)景上進(jìn)一步豐富更多的功能和呈現(xiàn)效果,以及實(shí)現(xiàn)這些功能在技術(shù)上的思路。
首先我們來(lái)看看第一季已經(jīng)實(shí)現(xiàn)的純天然無(wú)添加無(wú)PS的HTML5 3D機(jī)房效果:
已經(jīng)拿到過(guò)代碼的朋友應(yīng)該知道,這一場(chǎng)景是通過(guò)一個(gè)json文件進(jìn)行組裝和加載,可以很方便地進(jìn)行修改和維護(hù)。在此基礎(chǔ)上,這一次我又增加了機(jī)柜標(biāo)簽、機(jī)柜門、復(fù)雜設(shè)備、機(jī)房走線、人員軌跡等效果,下面我就把第二季的干貨一一為大家奉上。
機(jī)柜標(biāo)簽機(jī)房中最重要的物理資源——機(jī)柜——是機(jī)房管理、規(guī)劃、監(jiān)控人員最關(guān)注的對(duì)象之一。對(duì)于規(guī)模在幾十個(gè)、上百個(gè)甚至上千個(gè)機(jī)柜的機(jī)房,每個(gè)機(jī)柜必然會(huì)進(jìn)行資產(chǎn)編號(hào),方便檢索和管理。這個(gè)在多數(shù)資產(chǎn)管理系統(tǒng)中,都是最基本的。但是在3d場(chǎng)景中,如何顯示這些機(jī)柜編號(hào),才能讓用戶更直觀的看到每個(gè)機(jī)柜的位置呢?
傳統(tǒng)的方式是用標(biāo)簽顯示資產(chǎn)編號(hào),例如可以用“告警冒泡”那樣的方式顯示一個(gè)文字氣泡。不過(guò)當(dāng)機(jī)柜產(chǎn)生告警時(shí),兩個(gè)氣泡會(huì)有所沖突。而且過(guò)多的氣泡會(huì)產(chǎn)生相互遮擋覆蓋,有點(diǎn)混亂,比如像這樣:
因此我嘗試了一種不同的思路:把文字渲染到一個(gè)內(nèi)存圖片,“溶解”到機(jī)柜的上方貼圖中。
想要生成一個(gè)內(nèi)存的圖片文字,可以通過(guò)下面的函數(shù)實(shí)現(xiàn):
generateAssetImage: function(text){ var width=512, height=256; var canvas = document.createElement("canvas"); canvas.width = width; canvas.height = height; var ctx = canvas.getContext("2d"); ctx.fillStyle="white"; ctx.fillRect(0,0,width,height); ctx.font = 150+"px "Microsoft Yahei" bold"; ctx.fillStyle = "black"; ctx.textAlign = "center"; ctx.textBaseline = "middle"; ctx.fillText(text, width/2,height/2); ctx.strokeStyle="black"; ctx.lineWidth=15; ctx.strokeText(text, width/2,height/2); return canvas; }
需要留意的是:
生成的圖片寬高數(shù)值最好是2的冪,例如128、256、512等,這樣在3d中渲染不容易出現(xiàn)閃爍和鋸齒。相關(guān)原理請(qǐng)查閱google。
文字繪制盡量居中、充滿整個(gè)圖,不要太小,否則看上去比較奇怪。
空白處保持透明,不必填充色,方便和機(jī)柜本身貼圖的“溶解”。
直接返回canvas對(duì)象即可,不必生成圖片點(diǎn)陣數(shù)組。
生成canvas后,可以這樣直接貼圖使用:
var labelCanvas=demo.Default.generateAssetImage(label); rack.setStyle("top.m.texture.image", labelCanvas); rack.setStyle("top.m.specularmap.image", labelCanvas);
通過(guò)上面代碼,把貼圖作為機(jī)柜立方體top面的貼圖和反射映射圖。這樣出來(lái)的效果如下:
這樣,既不用增加3d對(duì)象,也不影響機(jī)柜的美觀度,關(guān)鍵是看得非常清晰,在大場(chǎng)景中也不干擾用戶的視線:
上一篇里,由于時(shí)間緊迫,也考慮到呈現(xiàn)效率,機(jī)柜采用了“雙擊機(jī)柜出現(xiàn)設(shè)備”的方案。一個(gè)立方體的機(jī)柜雖然簡(jiǎn)單直接,但是沒(méi)有機(jī)柜門,總覺(jué)得假了一點(diǎn),客戶也提到了這一點(diǎn),因此按照機(jī)房門的思路,增加一個(gè)機(jī)柜門,增加雙擊開(kāi)門的效果,這個(gè)比較簡(jiǎn)單:
var rackDoor = new mono.Cube(width, height, 2); rackDoor.s({ "m.type":"phong", "m.color": "#A5F1B5", "m.ambient": "#A4F4EC", "front.m.texture.image": "images/rack_front_door.png", "back.m.texture.image": "images/rack_door_back.png", "m.envmap.image": demo.Default.getEnvmap("envmap1"), }); rackDoor.setParent(rack); rackDoor.setPosition(0, 0, depth/2+1); rackDoor.setClient("animation","rotate.right.120");
上面代碼創(chuàng)建了一個(gè)薄薄的立方體作為機(jī)柜門。設(shè)置貼圖、顏色等,再設(shè)置其parent是機(jī)柜。這樣,如果拖拽機(jī)柜位置,機(jī)柜也會(huì)跟著移動(dòng),簡(jiǎn)單方便。最后,在設(shè)置一下機(jī)柜門的動(dòng)畫。通過(guò)一個(gè)字符串進(jìn)行定義:rotate.right.120表示動(dòng)畫是“向右側(cè)旋轉(zhuǎn)120度”,在雙擊的時(shí)候觸發(fā)。
第一季里,機(jī)柜內(nèi)的設(shè)備,主要用樂(lè)服務(wù)器來(lái)表現(xiàn),加入了設(shè)備彈出、告警等效果。后期根據(jù)現(xiàn)場(chǎng)和用戶的交流,用戶進(jìn)一步提出要顯示機(jī)架上需要安裝更加復(fù)雜的電信設(shè)備,包括板卡、板卡的插拔動(dòng)作、呈現(xiàn)方法等,也就是在機(jī)柜上顯示一個(gè)有多個(gè)板卡的設(shè)備,雙擊板卡可以彈出。
要做這個(gè),需要把原來(lái)的一個(gè)立方體的服務(wù)器設(shè)備做一個(gè)“挖空”處理,變成一個(gè)空的設(shè)備框的樣子。然后再生成一系列的板卡對(duì)象,插入這個(gè)空框。每個(gè)板卡應(yīng)該由面板+電路板組成,可以用兩個(gè)立方體進(jìn)行拼接,添加適當(dāng)?shù)馁N圖完成。代碼如下:
var parts=[{ //card panel type: "cube", width: width, height: height, depth: 1, translate: [x, y, z+1], rotate: rotate, op: "+", style:{ "m.color": color, "m.ambient": color, "m.texture.image": "images/gray.png", "front.m.texture.image": pic, "back.m.texture.image": pic, } },{ //card body type: "cube", width: 1, height: height*0.95, depth: depth, translate: [x, y, z-depth/2+1], rotate: rotate, op: "+", style:{ "m.color": color, "m.ambient": color, "m.texture.image": "images/gray.png", "left.m.texture.image": "images/card_body.png", "right.m.texture.image": "images/card_body.png", "left.m.texture.flipX": true, "m.transparent": true, } }]; var card=demo.Default.createCombo(parts); card.setClient("animation", "pullOut.z"); box.add(card);
上面代碼可以生成一個(gè)板卡對(duì)象。循環(huán)重復(fù),設(shè)置位置,即可生成整個(gè)設(shè)備。通過(guò)設(shè)置animation屬性,定義板卡動(dòng)畫為“雙擊拉出”,再次雙擊推回。效果如下圖:
當(dāng)然,實(shí)際項(xiàng)目中,各種結(jié)構(gòu)的電信設(shè)備千奇百怪,要通過(guò)代碼定義是不現(xiàn)實(shí)的。所以我們還開(kāi)發(fā)了一個(gè)設(shè)備編輯器,可以通過(guò)拖拽方式快速生成設(shè)備結(jié)構(gòu)圖。
除了機(jī)柜之外,線纜的連接走向和連接關(guān)系是管理員關(guān)注的另外一個(gè)焦點(diǎn)。機(jī)架中的電信設(shè)備或服務(wù)器設(shè)備會(huì)通過(guò)端口和線纜進(jìn)行連接,組成一定結(jié)構(gòu)的網(wǎng)絡(luò)。而線纜的走向在物理上通過(guò)肉眼是很難看清晰的。更多線纜會(huì)從機(jī)柜連出,延伸到屋頂上方或地板下方的隱蔽工程中(例如走線架)固定和布線,用肉眼更無(wú)法觀察。此時(shí),需要3d機(jī)房界面能清晰的顯示電纜從端口到走線架再到端口的“端到端”的物理走線,方便管理員了解網(wǎng)絡(luò)情況和管理。
線纜線纜,可以用一個(gè)空間的path來(lái)定義,并設(shè)置其貼圖:
var path = demo.Default.create3DPath(json.data); var cable=new mono.PathNode(path, 100, 1); cable.s({ "m.type": "phong", "m.specularStrength": 30, "m.color": json.color, "m.ambient": json.color, "m.texture.image": "images/flow.jpg", "m.texture.repeat": new mono.Vec2(200, 1), }); box.add(cable);
通過(guò)json定義的[x, y, z]數(shù)組來(lái)生成一個(gè)path對(duì)象,然后用它來(lái)生成一個(gè)空間的“管子”對(duì)象。流動(dòng)效果可以通過(guò)一個(gè)動(dòng)畫來(lái)修改貼圖紋理的offset,讓眼睛產(chǎn)生貼圖不斷“移動(dòng)”的效果。
走線架走線架可以通過(guò)簡(jiǎn)單的鏤空貼圖來(lái)模擬,不需要建一個(gè)復(fù)雜的框架模型,減少對(duì)GPU的壓力。實(shí)際的走線架有很多種,例如下圖是一種典型的走線架:
我們通過(guò)程序模擬一下:
var rail=demo.Default.createPathObject(railInfo); rail.s({ "m.texture.image": "images/rail.png", "m.type": "phong", "m.transparent": true, "m.color": "#CEECF5", "m.ambient": "#CEECF5", "aside.m.visible": false, "zside.m.visible": false, "m.specularStrength": 50, }); rail.setPositionY(263); box.add(rail);
最終走線架+線纜的效果如下:
在3d場(chǎng)景中,經(jīng)常需要計(jì)算規(guī)劃并顯示一個(gè)最優(yōu)的空間或平面路徑,用來(lái)指示如何最快、最合理的到達(dá)目標(biāo),或通過(guò)路徑顯示一個(gè)移動(dòng)物體的軌跡,方便進(jìn)行監(jiān)控和分析。例如,客戶提出一個(gè)實(shí)際需求:現(xiàn)場(chǎng)檢修人員手持平板進(jìn)入機(jī)房,輸入設(shè)備id后,直接給出前方走動(dòng)路徑,并進(jìn)行實(shí)時(shí)導(dǎo)航引導(dǎo)。
我們可以把這個(gè)需求分解為導(dǎo)航路徑顯示和人員模擬兩步。
導(dǎo)航路徑導(dǎo)航線可以通過(guò)一個(gè)浮在地板上方的path路徑來(lái)定義。做一個(gè)簡(jiǎn)單的顏色渲染和彎角處理,就可以比較清晰的展示底面的走動(dòng)路徑。
var path=new mono.Path(); path.moveTo(object.getPositionX(), object.getPositionZ()); for(var i=0;i拉近后看下細(xì)節(jié):
移動(dòng)軌跡的顯示也有很多變化,形狀、顏色的變化,空間坐標(biāo)的變化,都可以產(chǎn)生一些不同的效果。例如下圖是另外一個(gè)3d車庫(kù)導(dǎo)航系統(tǒng)的場(chǎng)景:
加載人物模型接下來(lái),要加載一個(gè)人的模型進(jìn)來(lái),放在路徑上??梢栽诰W(wǎng)上找一些3d max做的模型,并轉(zhuǎn)成obj格式的文件,這樣就可以方便的導(dǎo)入場(chǎng)景中。Obj通過(guò)對(duì)應(yīng)的mtl文件進(jìn)行定義材質(zhì),需要的貼圖也需要一并涵蓋進(jìn)來(lái)。通過(guò)下面幾行代碼即可完成obj模型的導(dǎo)入:
var obj="images/worker.obj"; var mtl="images/worker.mtl"; var loader = new mono.OBJMTLLoader(); loader.load(obj, mtl, {"worker": "images/worker.png",}, function (object) { box.addByDescendant(object); });效果如下圖:
需要留意的是,人的模型不要太大,能把人物輪廓大概渲染清晰即可。例如上面的模型也就幾百k,加載和顯示幾乎瞬間完成,不會(huì)產(chǎn)生卡頓。如果加載幾十兆上百兆的高清模型,則可能出現(xiàn)卡頓,也會(huì)拖慢場(chǎng)景的渲染速度。畢竟我們的主要場(chǎng)景對(duì)象是3d機(jī)房,對(duì)模型選擇要有所取舍,千萬(wàn)不要喧賓奪主。
讓任務(wù)沿著路徑移動(dòng),可以通過(guò)動(dòng)畫進(jìn)行控制,對(duì)path中每一段路線進(jìn)行平移,連續(xù)、反復(fù)的播放,即可實(shí)現(xiàn)人物的移動(dòng)效果。
當(dāng)然這里有一個(gè)缺點(diǎn),人物的移動(dòng)是僵硬不動(dòng)的,不能像真實(shí)人物一樣邁腿一步一步的走路進(jìn)行移動(dòng)。如果要做,需要用到骨骼動(dòng)畫等技術(shù),相對(duì)復(fù)雜一些,目前項(xiàng)目緊急,就留給以后找時(shí)間研究了。當(dāng)然對(duì)于3d機(jī)房這樣的企業(yè)應(yīng)用來(lái)說(shuō),必要性不一定很大,畢竟不是游戲。
通過(guò)這些技術(shù),大家可以輕松構(gòu)建一個(gè)比較完整的3d機(jī)房系統(tǒng),就跟我們這次的項(xiàng)目一樣:
后記篇幅有限,這一篇就介紹這么多,后續(xù)找時(shí)間會(huì)繼續(xù)給大家介紹如何拖拽移動(dòng)機(jī)柜、顯示機(jī)房中的溫度云圖、風(fēng)向監(jiān)控、攝像頭及視頻監(jiān)控,如何創(chuàng)建一個(gè)大的園區(qū)和樓宇等內(nèi)容。成為一個(gè)網(wǎng)紅的路還很漫長(zhǎng),我會(huì)一步一個(gè)腳印地走,也希望對(duì)大家有所啟發(fā)和幫助。老規(guī)矩,需要相關(guān)代碼的同學(xué)可以發(fā)郵件到[email protected],或留下郵箱,我會(huì)盡力回復(fù)。謝謝!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/49626.html
摘要:寫在前面的前面現(xiàn)在拍電影搞真人秀都流行拍續(xù)集,哥今天給大家?guī)?lái)的是打造最美機(jī)房的續(xù)集,哥的目標(biāo)是成為機(jī)房界的網(wǎng)紅。機(jī)柜標(biāo)簽機(jī)房中最重要的物理資源機(jī)柜是機(jī)房管理規(guī)劃監(jiān)控人員最關(guān)注的對(duì)象之一。 寫在前面的前面 現(xiàn)在拍電影、搞真人秀都流行拍續(xù)集,哥今天給大家?guī)?lái)的是打造最美3D機(jī)房的續(xù)集,哥的目標(biāo)是成為3D機(jī)房界的網(wǎng)紅。 -------------------------------我是這個(gè)...
摘要:受到大家的啟發(fā)和鼓勵(lì),這個(gè)機(jī)房系列已經(jīng)有了長(zhǎng)足的進(jìn)步。做應(yīng)用并不是一件輕松的事。來(lái)張全景圖看看接著,只要把門安上去就行了。 前言 最近項(xiàng)目開(kāi)發(fā)任務(wù)告一段落,剛好有時(shí)間整理這大半年的一些成果。使用html5時(shí)間還不久,對(duì)js的認(rèn)識(shí)還不夠深入。沒(méi)辦法,以前一直搞java,對(duì)js的一些語(yǔ)言特性和概念一時(shí)還轉(zhuǎn)換不過(guò)來(lái)。 上一篇第一彈介紹了項(xiàng)目中做的一個(gè)彩虹爆炸圖,主要用了 html5的canv...
閱讀 2523·2023-04-25 19:24
閱讀 1740·2021-11-11 16:54
閱讀 2861·2021-11-08 13:19
閱讀 3581·2021-10-25 09:45
閱讀 2589·2021-09-13 10:24
閱讀 3316·2021-09-07 10:15
閱讀 4110·2021-09-07 10:14
閱讀 2984·2019-08-30 15:56