自TWaver 3D產品發布以來,TWaver 3D的定位一直在于為企業提供3D應用的快速開發工具,方便企業開發適合自己的高效、實時的監控系統。
基于這樣的產品定位,我們在過去的一年多時間里,一直將重心放在提升引擎效率,增加可視化工具上。對于我們的優勢應用行業——電信行業,我們在3D機房應用上做了比較多的優化和定制。近期,有不少客戶向我們提出,總覺用TWaver 3D開發出來的界面,不像主流的3D效果那么精美。首先,我們想說,效果圖終歸是效果圖,和實際的系統一般來說還是有一些差異。其次,3D Max這些專業3D建模工具,和TWaver并不是對立的,而是相輔相成的工具。我們已經支持將3D max的文件導入TWaver進行展示,也正在研究使得TWaver能對接更多的模型類型。大家可以一起討論,如何讓TWaver的3D模型做得更好。最后,我們始終相信,作為開發工具的我們,是前途無限的,因此我們決定挑戰一下效果圖,看看TWaver的3D效果,到底有多強。
首先我們先找來一張效果圖,真的是效果圖哦~~

這張效果圖和TWaver 3D以往的demo風格都大不相同,我們就來按圖索個機房吧~
地板
第一個要做,也是應該比較簡單的,就是地板。這個地板應該是一個有點厚度、有格子貼圖的薄薄立方體平面。還好經過封裝,就寫一段json對象就能定義了:
name: '地板',
type: 'cube',
width: 1600,
height: 10,
depth: 1300,
style: {
'm.color': '#BEC9BE',
'm.ambient': '#BEC9BE',
}
}
通過定義,創建了一個13米*16米的地板塊:
調整到合適的角度看,效果還不錯,但顏色欠缺了些,需要找一個材質紋理圖。紋理圖的尺寸都需要是寬和高都是2的冪,例如128×128、256*256等,這樣出來效果才會好。這也是3D軟件一般所要求的。另外紋理要能連續拼接不露破綻,這樣才好。例如下面我google出來的圖:
在style里面添加:
'top.m.texture.repeat': new mono.Vec2(10,10),
效果如下:
雖然不是很華麗,但作為機房的地板,也綽綽有余了。好像有點so easy,決定加大難度,給地板加一個方便運送設備的斜坡!
這里就給大家普及下TWaver的好處了。Twaver里面的對象可以支持運算,這個斜坡,可以定義一個斜的立方體,讓地板剪掉立方體,應該可以做到。于是繼續定義json:
name: '地板切坡',
type: 'cube',
width: 200,
height: 20,
depth: 260,
translate: [-348,0,530],
rotate: [Math.PI/180*3, 0, 0],
op: '-',
style: {
…,
}
}
這里定義的一個傾斜的立方體,通過translate定義位置,通過rotate定義旋轉角度,然后再通過op定義運算符,這里是“減去”,就用“-”。被剪掉的立方體也可以設置材質、紋理、貼圖、顏色….等等。看看效果:
走廊桌
效果圖的房間有點狹窄,決定加一條寬敞的走廊,并在走廊上放一個接待桌。對于桌子這種沒有業務屬性的對象,為了簡單就偷懶做一個立方體表示吧!這個簡單,繼續使用上述辦法:
name: '走廊板凳',
type: 'cube',
width: 300,
height: 50,
depth: 100,
translate: [350, 0, -500],
}

有點簡單,再加點陰影效果:
簡簡單單一個接待桌就做好啦!下面繼續造房子,蓋墻體。
墻體
墻體是一個不規則的路徑,不過放心,TWaver的引擎不光支持不規則路徑,連曲線路徑都可以噢。所以看上去挺麻煩實際還是比較簡單的。在json里面定義一組數字的坐標,讓這些數字依次連接,組成一個墻體,最后生成3D對象放入場景中。
Json定義大致如下:
name: '主墻體',
type: 'path',
width: 20,
height: 200,
translate: [-500, 0, -500],
data:[
[0, 0],
[1000, 0],
[1000, 500],
[500, 500],
[500, 1000],
[0, 1000],
[0,0],
],
}
注意這里的類型變成了path,data中定義了一個二維坐標數組來描述墻體。由于墻都是從底面開始的,所以只定義它的平面的x、y坐標就行了。吸取剛才的經驗教訓,啟用陰影并咨詢設計師美眉幾個顏色值加上,看看效果:
再瞅瞅細節,好像缺點啥,沒門!
門如果直接放上去,會被墻蓋住;如果比墻厚,又難看不符合實際。還是應該先定義一個門洞立方體,把門所在的位置挖掉:
name: '門洞',
type: 'cube',
width: 195,
height: 170,
depth: 30,
op: '-',
translate:[-350,2,500],
}
剛好挖在斜坡的位置,這樣設備進屋就方便了:
不過這門沒有一個門框,感覺不太生動。多一個門框會感覺立體感強一些。門框可以是一個比門洞略大的立方體,在挖門洞之前添加:
name: '門框',
type: 'cube',
width: 205,
height: 180,
depth: 26,
translate: [-350, 0, 500],
op: '+',
}
加上陰影和光線等綜合效果,還不錯,挺有檔次的。
還少點東西,對,門還沒裝上去。作為機房,應該來個清爽透亮的玻璃門。門體較大,就來個雙開門吧。門的定義比較簡單,就是一個薄的立方體。不過為了做到玻璃效果,要設置透明度,讓他看上去更像一個玻璃,再讓設計師美眉弄一張好看一點的門的圖,貼上去。先做左邊的門:
name: '左門',
type: 'cube',
width: 93,
height: 165,
depth: 2,
translate:[-397,4,500],
style:{
'm.transparent': true,
'm.texture.image': 'images/door_left.png',
}
上面增加的style主要是透明和貼圖兩項。看看效果:
再把右邊的也加上,位置對稱而已,json就不貼了。為了增加體驗,門上再設置動畫:雙擊可以自動打開,再雙擊可以直接關閉。TWaver的動畫功能引擎做好了封裝,在json中直接指定動畫類型就行了。不過要注意左右門的動畫旋轉方向要相反,要不然一個向里開一個向外開感覺比較怪異。
窗
有門就要有窗。有窗才有“窗明幾凈”的清爽干凈的趕腳。就在門的旁邊開一扇大窗戶吧!誰不喜歡大窗戶呢?方法和門類似,先放窗框后挖窗體。不過為了有點變化,這里不做窗框了,做一個窗臺,方法和道理與門相同。
name: ‘主窗戶洞’,
type: ‘cube’,
width: 420,
height: 150,
depth: 50,
translate: [200, 30, 500],
op: ‘-‘,
},{
name: ‘主窗戶臺’,
type: ‘cube’,
width: 420,
height: 10,
depth: 40,
translate: [200, 30, 510],
op: ‘+’,
}

再添加一個略帶顏色的透明玻璃。玻璃設置點高光和反射,增加“玻璃”感覺:
name: '主窗戶玻璃',
type: 'cube',
width: 420,
height: 150,
depth: 2,
translate: [200, 30, 500],
op: '+',
style: {
'm.transparent': true,
'm.opacity':0.4,
'm.color':'#58ACFA',
},
}
Json中玻璃設置了透明度和顏色。這樣一個半透明的茶色玻璃就好了:
到這里突然在想:蓋房子如果像寫程序一樣簡單就好了,所有的程序猿就不會是無房一族單身狗了。當然寫程序和蓋房子一樣:該封裝好的要封裝好,最后就是搭積木組裝就行了。如果蓋房子都是從挖土活泥巴開始,那就杯具了。寫程序也是一樣,如果從webgl的main開始寫….這3D機房的系統要幾個月甚至幾年才能做出來呢?
外側墻
房間外側的兩道走廊隔墻,由于是直線墻,沒有復雜走向,直接用立方體定義便可:
name: '左外墻',
type: 'cube',
width: 20,
height: 200,
depth: 1300,
translate: [-790, 0, 0],
op: '+',
}

name: '左外墻洞',
type: 'cube',
width: 30,
height: 110,
depth: 1300,
translate: [-790, 60, 0],
op: '-',
}
[/javacsript]
添加玻璃:
{
name: '左外墻玻璃',
type: 'cube',
width: 4,
height: 110,
depth: 1300,
translate: [-790, 60, 0],
op: '+',
style: {
'm.transparent': true,
'm.opacity':0.6,
},
}
機柜
最后再來點重點的內容:機柜,以及其中的服務器設備。這才是3D機房里面最終要管理的內容。在我們的實際項目中,這些資產都是在數據庫中存儲,并通過json接口加載到瀏覽器中顯示。這里為了演示方便,直接寫幾個機柜的片段,看一下顯示效果。
機柜對象在項目中是這樣封裝的:用一個立方體來表示機柜,并加上貼圖。項目中,為了提高顯示速度,機柜一開始并不加載內部服務器內容,而是只顯示自身一個立方體。當用戶雙擊后,會觸發一個延遲加載器,從服務器端加載機柜內部服務器,并加載到對應的位置上。此時,機柜會被挖空成一個空心的立方體,以便視覺上更像一個機柜。
定義機柜的json如下:
name: '機柜',
type: 'rack',
lazy: true,
width: 70,
depth: 100,
height: 220,
translate: [-370, 0, -250],
severity: CRITICAL,
}
上面的機柜定義中,有一個lazy標記,標記它是否延遲加載其內容。如果延遲加載,則雙擊觸發,否則程序顯示時直接加載其內容。Severity是定義了機柜的告警信息,它是否有業務告警。如果有告警,會用一個氣泡顯示在機柜的上方,同時機柜也會被染色成告警對應的顏色。
繼續添加更多的機柜:
簡單起見,這里管理的設備假設都是機架設備,尺寸規格比較規整,因此比較容易在機柜中組織。一個設備的外觀確定后,在數據庫中定義好模板,加載時根據其所在機柜的位置放置即可。這里只是隨機生成了幾個服務器設備,并按位置擺放。在實際應用中,可以通過手工錄入或者智能機架報送的信息來確定服務器的類型和位置。

如果需要監控到端口級別,還可以在服務器彈出后,再進一步延遲加載設備商的板卡、端口對象,并點擊后進一步進行配置、監控等操作。當然加載的數據越細,對3D引擎和瀏覽器的壓力會越大。可以通過動態延遲加載/卸載策略,獲取一些平衡折中。
到這里,機房就基本搭建完成了,看下效果,比起效果圖,是不是有過之而無不及呢?
從顯示效果來看,基本不輸前面看到的廣告公司的效果圖,但和它和一張死圖片太不一樣了,我們這是一個能操作、能漫游、能縮放、有動畫、顯示流暢、瀏覽器無需插件就能直接打開的3D機房小程序,就一個json文件和一百多行代碼和一天的時間就搞定了,還是讓人有點驚訝的。不用插件、不用3Dmax,不用模型庫,我喜歡這樣干干凈凈純粹的小程序。小而美、干凈而純粹。手機和平板也能用哦,而且還很流暢!經過優化,場景加載已經控制在600毫秒以內,縮放漫游也很流暢。當然技術和美化永無止境,用戶的需求也千變萬化綿綿不絕。但只要我們選擇好了技術和工具,就能事半功倍。Html5就是極佳的一個選擇。