基於 HTML5 WebGL 的樓宇智慧化整合系統(三)
阿新 • • 發佈:2020-04-16
前言
2018年7月,資訊化部印發了《工業網際網路平臺建設及推廣指南》和《工業網際網路平臺評價方法》,掀起了 工業網際網路 的浪潮,併成為熱詞寫入了報告中。同為資訊發展下的產物 建築智慧化整合系統 也是兼具著資訊與管理的重要體現,資料化資訊通過視覺化的管理系統展示出一套網際網路智慧優化的解決方案,而本系列文章便結合了 HT 的 2D/3D 視覺化工具的運用,結合面板的資料展示和大樓建模場景的視覺化管理,前面的內容已經講解了 3D 模型和 2D 面板的融合體現,本次的內容將帶您探討 智慧樓宇管理系統、電梯監控系統 以及 停車場管理系統 的實現方式和整體系統的聯合優化體現。
介面簡介及效果預覽
智慧樓宇管理系統優化效果
主要包括冷站、熱站和中央末端智慧群控的聯合作用,以及樓層智慧照明,通過清晰的動畫體現出整棟大樓智慧節能運作的流程,可以通過面板詳情的演示細緻地介紹每個場景的作用以及串聯的用處。 電梯以及樓層監控效果
視覺化地實時監控電梯在樓層間的工作執行狀態,並且能夠準確地瀏覽每個電梯內的實時監控畫面。 停車場管理系統監控效果
停車場作為現在樓宇監控不可缺失的一環,這裡主要可以體現出實時的車位監控,通過簡單的動畫演示來表現出整個停車場車輛的執行狀態,方便管理。 程式碼實現 一、 智慧樓宇管理系統優化效果的實現 在點選智慧樓宇管理系統的按鈕後,場景視角會根據 moveCamera 轉移到大樓正視的視角後,大樓整體呈現漸變虛化後透明展示大樓內部資訊,這個動畫是封裝了一個 tweenColor 顏色變化的過渡效果,從一種顏色 rgba 狀態上改變色值和透明度來體現視覺上的變化。在效果展示上有一種視覺化浸入式檢視大樓內部資訊的體驗,具體的 3D 模型屬性的變化可參考 <HT 的 3D 手冊>。
顏色變化函式的實現是傳入引數來改變節點的顏色屬性變化值:
主要包括冷站、熱站和中央末端智慧群控的聯合作用,以及樓層智慧照明,通過清晰的動畫體現出整棟大樓智慧節能運作的流程,可以通過面板詳情的演示細緻地介紹每個場景的作用以及串聯的用處。 電梯以及樓層監控效果
視覺化地實時監控電梯在樓層間的工作執行狀態,並且能夠準確地瀏覽每個電梯內的實時監控畫面。 停車場管理系統監控效果
停車場作為現在樓宇監控不可缺失的一環,這裡主要可以體現出實時的車位監控,通過簡單的動畫演示來表現出整個停車場車輛的執行狀態,方便管理。 程式碼實現 一、 智慧樓宇管理系統優化效果的實現 在點選智慧樓宇管理系統的按鈕後,場景視角會根據 moveCamera 轉移到大樓正視的視角後,大樓整體呈現漸變虛化後透明展示大樓內部資訊,這個動畫是封裝了一個 tweenColor 顏色變化的過渡效果,從一種顏色 rgba 狀態上改變色值和透明度來體現視覺上的變化。在效果展示上有一種視覺化浸入式檢視大樓內部資訊的體驗,具體的 3D 模型屬性的變化可參考 <HT 的 3D 手冊>。
// 通過 moveCamera 改變 eye 和 center 來移動場景視角為大樓的正視面 moveCamera(g3d, [134, 399, 1617], [7, 40, 144], { duration: 2000, easing: t => t * t, finishFunc: () => { // 開啟場景大樓模型的可透明為 true this.building.eachChild(c => { c.s({ 'shape3d.transparent': true, }); }); // 大樓模型線框的顏色變化 tweenColor(this.building, 'wf.color', 'rgba(72,149,232,1)', 'rgba(56,156,255,0.03)', { duration: 2000, easing: t => t }); // 大樓模型整體染色的顏色變化 tweenColor(this.building, 'shape3d.blend', 'rgba(120,180,255,1)', 'rgba(120,180,255,0)', { duration: 2000, easing: t => t, finishFunc: () => { // 樓層設定為可見 this.floor.eachChild(c => { setNodeVisible(c, true); }); this.floorLighting = 1; // 顯示大樓建築資訊的動畫 this.showBuilding(); } }); } });
- node:改變顏色的圖元節點;
- startColor:起始顏色的 rgba 值;
- endColor:變化後顏色的 rgba 值;
- animParams:過渡動畫引數;
tweenColor(node, property, startColor, endColor, animParams) { animParams = animParams || {}; if (!animParams.frames && !animParams.duration) animParams.duration = 5000; if (!animParams.easing) animParams.easing = t => t; startColor = ht.Default.toColorData(startColor); endColor = ht.Default.toColorData(endColor); const dx = endColor[0] - startColor[0]; const dy = endColor[1] - startColor[1]; const dz = endColor[2] - startColor[2]; const da = endColor[3] - startColor[3]; const postAction = animParams.postAction; animParams.action = (v, t) => { const x = startColor[0] + v * dx; const y = startColor[1] + v * dy; const z = startColor[2] + v * dz; const a = (startColor[3] + v * da) / 255; node.s(property, ('rgba(' + ([x, y, z, a]).join(', ')) + ')'); if (postAction) postAction(('rgba(' + ([x, y, z, a]).join(', ')) + ')'); } return ht.Default.startAnim(animParams); }
大樓透明化後展示內部資訊,此時我們可以看到樓層的照明系統從底樓逐一向上亮起也是通過這種方法實現的。而後大樓兩側的系統介紹面板是通過改變面板的縮放屬性來實現延展的效果:
// 面板顯示 showPanel(data) { ht.Default.startAnim({ duration: 1000, easing: t => t, action: (v,t) => { data.setScaleX(data.getScaleX() + (1 - data.getScaleX()) * v); } }); } // 面板隱藏 hidePanel(data) { ht.Default.startAnim({ duration: 1000, easing: t => t, action: (v,t) => { data.setScaleX(data.getScaleX() + (0 - data.getScaleX()) * v); } }); }
二、電梯以及樓層監控效果的實現 電梯是大樓日常管理必不可少的一環,而通過視覺化場景便可實時對接電梯執行的情況。電梯動畫效果的實現原理是判斷當前電梯所處樓層的位置和下一層隨機樓層的位置,來實現樓梯執行動畫,本棟大樓劃分設定為每層樓層高50,所以只需要得到電梯所處的高度就很容易可以判斷出所處的樓層,而電梯面板也是通過這個判斷來實時展示樓層的資訊。 具體實現的虛擬碼如下:
elevatorAnimation(data) { const g3d = this.g3d; const tag = data.getTag(); const e = data.getElevation(); const label = data.getChildAt(0); // 判斷現在所處樓層 let now = Math.ceil(e / 50); // 下一層樓層取1~7隨機數 let next = randomNumber(1, 7); // 根據現在的樓層和下一個樓層,判斷電梯執行的範圍 let range = numBetween(now, next); this.animationElevatorMap[tag] = ht.Default.startAnim({ duration: range * 800, easing: t => t, action: (v, t) => { // 電梯執行位置設定 data.setElevation(now < next ? (e + (range * 50) * v) : (e - (range * 50) * v)); // 設定電梯樓層面板顯示並根據電梯位置設定 if (!label) return; const floor = Math.ceil(data.getElevation() / 50); if (floor === label.a('text')) return; label.a('text', floor); // 手動重新整理電梯面板資訊 g3d.invalidateShape3dCachedImage(label); }, finishFunc: () => { // 銷燬電梯間隔動畫 delete this.timeoutElevatorMap[tag]; // 執行電梯間隔動畫後回撥電梯執行動畫 this.timeoutElevatorMap[tag] = setTimeout(() => { this.elevatorAnimation1(data); }, Math.floor(Math.random() * 5000) + 2000); } }); }
三、停車場管理系統監控效果的實現 停車場的車位資訊可以直觀地在 3D 場景中去實現管理,而車輛進出的視覺化控制也可以用簡單的管道動畫去實現,實時監控車輛進出去呼叫這個動畫就能很直觀地反應停車場的實時情況。而停車場的具體實現方案是通過車輛節點的前進管道和倒退管道去呼叫封裝的管道動畫來實現車輛行駛和倒車入庫的動畫效果: 每個車輛的停車動畫都包含著 forwardPath 和 backwardPath 兩條路線,分別對應著車輛的前進路線和倒車路線,具體的行駛虛擬碼如下:
park(car, key = 'Path', finishFunc) { const dm = car.dm(); const tag = car.getTag(); const forwardPath = dm.getDataByTag(tag + '_forward' + key); const backwardPath = dm.getDataByTag(tag + '_backward' + key); this.animationMap[tag] = move(car, forwardPath, 'forward', undefined, 24, { pathEndFunc: () => { this.animationMap[tag].stop(); this.animationMap[tag] = move(car, backwardPath, 'backward', undefined, undefined, { pathEndFunc: () => { this.animationMap[tag].stop(); delete this.animationMap[tag]; if (finishFunc) finishFunc(); return true; } }); return true; } }); }
move 是節點沿著路徑平滑移動的封裝函式,主要引數為:
- node:動畫節點;
- path:執行路徑;
- direction:節點朝向 forward | backward;
- animParams:動畫引數;
通過繪製一條執行路線的管道,ht.Default.getLineCacheInfo() 得到這條管道的點位和分割資訊 cache,然後管道資訊通過 ht.Default.getLineLength() 得到管道的長度,並且通過 ht.Default.getLineOffset() 來獲取連線或者管道指定比例的偏移資訊,從而達到移動的效果,注意的是,這裡還設定了 direction 來規定動畫節點的朝向,主要是為了通過 node.lookAtX() 來獲取節點下一個面對的朝向的位置資訊,並設定節點此時的位置,從而達到節點沿著路徑平滑移動的效果。
move(node, path, direction, step = 6, interval = 75, animParams) { let cache = path.__cache__; if (!cache) cache = path.__cache__ = ht.Default.getLineCacheInfo(path.getPoints(), path.getSegments()); const len = ht.Default.getLineLength(cache); animParams = animParams || {}; const face = direction === 'forward' ? 'front' : direction === 'backward' ? 'back' : direction; let currentLen = 0; const pathEndFunc = animParams.pathEndFunc; const action = animParams.action; animParams.action = (v, t) => { if (currentLen >= len) { // 檔 pathEndFunc 返回 true 是,認為是要結束動畫, 不執行後面檔 action if (pathEndFunc && pathEndFunc()) return; } currentLen = currentLen % len; const offset = ht.Default.getLineOffset(cache, currentLen); const point = offset.point; node.lookAtX([point.x, node.getElevation(), point.z], face); node.p3(point.x, node.getElevation(), point.z); currentLen = currentLen + step; if (action) action(); }; return loop(animParams.action, interval); }
與此同時,我們還可以看到車輛行駛到車位或者離開時,車位上方的紅綠燈則表示著這個車位的停放資訊,是根據車輛的情況實時設定車位的狀況,通過改變其訊號燈 image 的 json 圖示並手動重新整理快取來實現的。而快取機制對於整體場景的流暢度是至關重要的,對於一些不必要實時重新整理的面板資訊,我們可以採取快取的方式,並且在下一次更新的時候呼叫 Graph3dView.invalidateShape3dCachedImage(node)來手動重新整理這個節點,從而大大提高了場景的效能,有關 3D 面板的屬性可以參考 <HT 的 3D 手冊 billboard 公告板>。
updateLight(view, light, color) { light.s('shape3d.image', 'symbols/parking/' + color + 'Light.json'); view.invalidateShape3dCachedImage(light); }
總結 IBMS 智慧化整合系統管理結合資料資訊、大樓模型以及每個系統的場景模型,完整地體現出一套系統之間的功能串聯。在一棟大樓的功能上,每個子系統負責著各自資訊資料的管理和操作,但是通過智慧化整合管理系統的管理,便可將每部分子系統的資料資訊彙總到一起去視覺化 3D/2D 工具上完整地體現。在未來科技的進步下,也許不再需要親臨現場管理著整棟的日常執行,一套視覺化的智慧化整合管理系統就可以輕鬆解決日常維護的繁瑣,充分的資料也可以實時地反映裝置與大樓的關聯資訊。 2019 我們也更新了數百個工業網際網路 2D/3D 視覺化案例集,在這裡你能發現許多新奇的例項,也能發掘出不一樣的工業網際網路:https://mp.weixin.qq.com/s/ZbhB6LO2kBRPrRIfHlKGQA 同時,你也可以檢視更多案例及效果:https://www.hightopo.com/demos/index.ht