摘要:寫在前面的前面現(xiàn)在拍電影搞真人秀都流行拍續(xù)集,哥今天給大家?guī)淼氖谴蛟熳蠲罊C(jī)房的續(xù)集,哥的目標(biāo)是成為機(jī)房界的網(wǎng)紅。機(jī)柜標(biāo)簽機(jī)房中最重要的物理資源機(jī)柜是機(jī)房管理規(guī)劃監(jiān)控人員最關(guān)注的對象之一。
寫在前面的前面
現(xiàn)在拍電影、搞真人秀都流行拍續(xù)集,哥今天給大家?guī)淼氖谴蛟熳蠲?D機(jī)房的續(xù)集,哥的目標(biāo)是成為3D機(jī)房界的網(wǎng)紅。
-------------------------------我是這個(gè)系列已經(jīng)有了第三篇的分割線-------------------------------
前情提要請腦補(bǔ)畫外音 Previously on Monolog……
前陣子寫了一篇打造最美html5 3d機(jī)房,介紹了如何用html5在網(wǎng)頁上創(chuàng)建無插件的精美3d機(jī)房場景,收到很多朋友的鼓勵(lì),深表感謝。對于索要源代碼的朋友,已經(jīng)盡力郵件回復(fù)。由于精力所限,如未能收到的朋友請留言或給我發(fā)送郵件:tw-service@servasoft.com。最近項(xiàng)目第二期又要緊鑼密鼓地開始了,所以想抓緊把一些新增的內(nèi)容補(bǔ)充上,進(jìn)一步完善這個(gè)html5 3d機(jī)房的呈現(xiàn)效果。
上一篇中主要介紹的是如何從最基礎(chǔ)的webgl封裝到創(chuàng)建3d物體對象,再通過3d物體對象“搭積木”式的組建整個(gè)3d機(jī)房場景。這一篇主要介紹一些如何在這個(gè)場景上進(jìn)一步豐富更多的功能和呈現(xiàn)效果,以及實(shí)現(xiàn)這些功能在技術(shù)上的思路。
首先我們來看看第一季已經(jīng)實(shí)現(xiàn)的純天然無添加無PS的HTML5 3D機(jī)房效果:
已經(jīng)拿到過代碼的朋友應(yīng)該知道,這一場景是通過一個(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)注的對象之一。對于規(guī)模在幾十個(gè)、上百個(gè)甚至上千個(gè)機(jī)柜的機(jī)房,每個(gè)機(jī)柜必然會進(jìn)行資產(chǎn)編號,方便檢索和管理。這個(gè)在多數(shù)資產(chǎn)管理系統(tǒng)中,都是最基本的。但是在3d場景中,如何顯示這些機(jī)柜編號,才能讓用戶更直觀的看到每個(gè)機(jī)柜的位置呢?
傳統(tǒng)的方式是用標(biāo)簽顯示資產(chǎn)編號,例如可以用“告警冒泡”那樣的方式顯示一個(gè)文字氣泡。不過當(dāng)機(jī)柜產(chǎn)生告警時(shí),兩個(gè)氣泡會有所沖突。而且過多的氣泡會產(chǎn)生相互遮擋覆蓋,有點(diǎn)混亂,比如像這樣:
因此我嘗試了一種不同的思路:把文字渲染到一個(gè)內(nèi)存圖片,“溶解”到機(jī)柜的上方貼圖中。
想要生成一個(gè)內(nèi)存的圖片文字,可以通過下面的函數(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)原理請查閱google。
文字繪制盡量居中、充滿整個(gè)圖,不要太小,否則看上去比較奇怪。
空白處保持透明,不必填充色,方便和機(jī)柜本身貼圖的“溶解”。
直接返回canvas對象即可,不必生成圖片點(diǎn)陣數(shù)組。
生成canvas后,可以這樣直接貼圖使用:
var labelCanvas=demo.Default.generateAssetImage(label); rack.setStyle("top.m.texture.image", labelCanvas); rack.setStyle("top.m.specularmap.image", labelCanvas);
通過上面代碼,把貼圖作為機(jī)柜立方體top面的貼圖和反射映射圖。這樣出來的效果如下:
這樣,既不用增加3d對象,也不影響機(jī)柜的美觀度,關(guān)鍵是看得非常清晰,在大場景中也不干擾用戶的視線:
上一篇里,由于時(shí)間緊迫,也考慮到呈現(xiàn)效率,機(jī)柜采用了“雙擊機(jī)柜出現(xiàn)設(shè)備”的方案。一個(gè)立方體的機(jī)柜雖然簡單直接,但是沒有機(jī)柜門,總覺得假了一點(diǎn),客戶也提到了這一點(diǎn),因此按照機(jī)房門的思路,增加一個(gè)機(jī)柜門,增加雙擊開門的效果,這個(gè)比較簡單:
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ī)柜也會跟著移動,簡單方便。最后,在設(shè)置一下機(jī)柜門的動畫。通過一個(gè)字符串進(jìn)行定義:rotate.right.120表示動畫是“向右側(cè)旋轉(zhuǎn)120度”,在雙擊的時(shí)候觸發(fā)。
第一季里,機(jī)柜內(nèi)的設(shè)備,主要用樂服務(wù)器來表現(xiàn),加入了設(shè)備彈出、告警等效果。后期根據(jù)現(xiàn)場和用戶的交流,用戶進(jìn)一步提出要顯示機(jī)架上需要安裝更加復(fù)雜的電信設(shè)備,包括板卡、板卡的插拔動作、呈現(xiàn)方法等,也就是在機(jī)柜上顯示一個(gè)有多個(gè)板卡的設(shè)備,雙擊板卡可以彈出。
要做這個(gè),需要把原來的一個(gè)立方體的服務(wù)器設(shè)備做一個(gè)“挖空”處理,變成一個(gè)空的設(shè)備框的樣子。然后再生成一系列的板卡對象,插入這個(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è)板卡對象。循環(huán)重復(fù),設(shè)置位置,即可生成整個(gè)設(shè)備。通過設(shè)置animation屬性,定義板卡動畫為“雙擊拉出”,再次雙擊推回。效果如下圖:
當(dāng)然,實(shí)際項(xiàng)目中,各種結(jié)構(gòu)的電信設(shè)備千奇百怪,要通過代碼定義是不現(xiàn)實(shí)的。所以我們還開發(fā)了一個(gè)設(shè)備編輯器,可以通過拖拽方式快速生成設(shè)備結(jié)構(gòu)圖。
除了機(jī)柜之外,線纜的連接走向和連接關(guān)系是管理員關(guān)注的另外一個(gè)焦點(diǎn)。機(jī)架中的電信設(shè)備或服務(wù)器設(shè)備會通過端口和線纜進(jìn)行連接,組成一定結(jié)構(gòu)的網(wǎng)絡(luò)。而線纜的走向在物理上通過肉眼是很難看清晰的。更多線纜會從機(jī)柜連出,延伸到屋頂上方或地板下方的隱蔽工程中(例如走線架)固定和布線,用肉眼更無法觀察。此時(shí),需要3d機(jī)房界面能清晰的顯示電纜從端口到走線架再到端口的“端到端”的物理走線,方便管理員了解網(wǎng)絡(luò)情況和管理。
線纜線纜,可以用一個(gè)空間的path來定義,并設(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);
通過json定義的[x, y, z]數(shù)組來生成一個(gè)path對象,然后用它來生成一個(gè)空間的“管子”對象。流動效果可以通過一個(gè)動畫來修改貼圖紋理的offset,讓眼睛產(chǎn)生貼圖不斷“移動”的效果。
走線架走線架可以通過簡單的鏤空貼圖來模擬,不需要建一個(gè)復(fù)雜的框架模型,減少對GPU的壓力。實(shí)際的走線架有很多種,例如下圖是一種典型的走線架:
我們通過程序模擬一下:
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場景中,經(jīng)常需要計(jì)算規(guī)劃并顯示一個(gè)最優(yōu)的空間或平面路徑,用來指示如何最快、最合理的到達(dá)目標(biāo),或通過路徑顯示一個(gè)移動物體的軌跡,方便進(jìn)行監(jiān)控和分析。例如,客戶提出一個(gè)實(shí)際需求:現(xiàn)場檢修人員手持平板進(jìn)入機(jī)房,輸入設(shè)備id后,直接給出前方走動路徑,并進(jìn)行實(shí)時(shí)導(dǎo)航引導(dǎo)。
我們可以把這個(gè)需求分解為導(dǎo)航路徑顯示和人員模擬兩步。
導(dǎo)航路徑導(dǎo)航線可以通過一個(gè)浮在地板上方的path路徑來定義。做一個(gè)簡單的顏色渲染和彎角處理,就可以比較清晰的展示底面的走動路徑。
var path=new mono.Path(); path.moveTo(object.getPositionX(), object.getPositionZ()); for(var i=0;i拉近后看下細(xì)節(jié):
移動軌跡的顯示也有很多變化,形狀、顏色的變化,空間坐標(biāo)的變化,都可以產(chǎn)生一些不同的效果。例如下圖是另外一個(gè)3d車庫導(dǎo)航系統(tǒng)的場景:
加載人物模型接下來,要加載一個(gè)人的模型進(jìn)來,放在路徑上。可以在網(wǎng)上找一些3d max做的模型,并轉(zhuǎn)成obj格式的文件,這樣就可以方便的導(dǎo)入場景中。Obj通過對應(yīng)的mtl文件進(jìn)行定義材質(zhì),需要的貼圖也需要一并涵蓋進(jìn)來。通過下面幾行代碼即可完成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,加載和顯示幾乎瞬間完成,不會產(chǎn)生卡頓。如果加載幾十兆上百兆的高清模型,則可能出現(xiàn)卡頓,也會拖慢場景的渲染速度。畢竟我們的主要場景對象是3d機(jī)房,對模型選擇要有所取舍,千萬不要喧賓奪主。
讓任務(wù)沿著路徑移動,可以通過動畫進(jìn)行控制,對path中每一段路線進(jìn)行平移,連續(xù)、反復(fù)的播放,即可實(shí)現(xiàn)人物的移動效果。
當(dāng)然這里有一個(gè)缺點(diǎn),人物的移動是僵硬不動的,不能像真實(shí)人物一樣邁腿一步一步的走路進(jìn)行移動。如果要做,需要用到骨骼動畫等技術(shù),相對復(fù)雜一些,目前項(xiàng)目緊急,就留給以后找時(shí)間研究了。當(dāng)然對于3d機(jī)房這樣的企業(yè)應(yīng)用來說,必要性不一定很大,畢竟不是游戲。
通過這些技術(shù),大家可以輕松構(gòu)建一個(gè)比較完整的3d機(jī)房系統(tǒng),就跟我們這次的項(xiàng)目一樣:
后記篇幅有限,這一篇就介紹這么多,后續(xù)找時(shí)間會繼續(xù)給大家介紹如何拖拽移動機(jī)柜、顯示機(jī)房中的溫度云圖、風(fēng)向監(jiān)控、攝像頭及視頻監(jiān)控,如何創(chuàng)建一個(gè)大的園區(qū)和樓宇等內(nèi)容。成為一個(gè)網(wǎng)紅的路還很漫長,我會一步一個(gè)腳印地走,也希望對大家有所啟發(fā)和幫助。老規(guī)矩,需要相關(guān)代碼的同學(xué)可以發(fā)郵件到tw-service@servasoft.com,或留下郵箱,我會盡力回復(fù)。謝謝!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/85972.html
摘要:寫在前面的前面現(xiàn)在拍電影搞真人秀都流行拍續(xù)集,哥今天給大家?guī)淼氖谴蛟熳蠲罊C(jī)房的續(xù)集,哥的目標(biāo)是成為機(jī)房界的網(wǎng)紅。機(jī)柜標(biāo)簽機(jī)房中最重要的物理資源機(jī)柜是機(jī)房管理規(guī)劃監(jiān)控人員最關(guān)注的對象之一。 寫在前面的前面 現(xiàn)在拍電影、搞真人秀都流行拍續(xù)集,哥今天給大家?guī)淼氖谴蛟熳蠲?D機(jī)房的續(xù)集,哥的目標(biāo)是成為3D機(jī)房界的網(wǎng)紅。 -------------------------------我是這個(gè)...
摘要:受到大家的啟發(fā)和鼓勵(lì),這個(gè)機(jī)房系列已經(jīng)有了長足的進(jìn)步。做應(yīng)用并不是一件輕松的事。來張全景圖看看接著,只要把門安上去就行了。 前言 最近項(xiàng)目開發(fā)任務(wù)告一段落,剛好有時(shí)間整理這大半年的一些成果。使用html5時(shí)間還不久,對js的認(rèn)識還不夠深入。沒辦法,以前一直搞java,對js的一些語言特性和概念一時(shí)還轉(zhuǎn)換不過來。 上一篇第一彈介紹了項(xiàng)目中做的一個(gè)彩虹爆炸圖,主要用了 html5的canv...
閱讀 533·2023-04-26 01:39
閱讀 4485·2021-11-16 11:45
閱讀 2609·2021-09-27 13:37
閱讀 882·2021-09-01 10:50
閱讀 3579·2021-08-16 10:50
閱讀 2217·2019-08-30 15:55
閱讀 2979·2019-08-30 15:55
閱讀 2259·2019-08-30 14:07