1. 程式人生 > >基於 HTML5 + WebGL 的宇宙(太陽系) 3D 視覺化系統

基於 HTML5 + WebGL 的宇宙(太陽系) 3D 視覺化系統

前言

近年來隨著引力波的發現、黑洞照片的拍攝、火星上存在水的證據發現等科學上的突破,以及文學影視作品中諸如《三體》、《流浪地球》、《星際穿越》等的傳播普及,宇宙空間中那些原本遙不可及的事物離我們越來越近,人們對未知文明的關注和對宇宙空間的好奇達到了前所未有的高度。站在更高的立足點上,作為人類這個物種中的一員,我們理所應當對我們生活的星球、所在的太陽系有一定的認識,對 8 大行星各自的執行軌道、質量、資源儲存量甚至是地形有一定的瞭解。

本系統採用 Hightopo 的 HT for Web 產品來構造輕量化的 3D 視覺化場景。

Solar System 這套系統主要用於兩種場景:

  1.作為科研成果、新發現的載體,做 3D 太空資料視覺化呈現,用於向普通民眾科普太陽系的構成、各行星組織結構等知識,可置於博物館大屏、學校大屏,也可用於網際網路產品,作為航空航天類網站的門戶頁、展示頁。

  2.作為宇航局、航空航天相關研究機構的駕駛艙,在 3D 視覺化介面中對行星相對位置、星體狀態、星體氣象、星體地形有一個直觀快速的瞭解,在宇宙空間探索越來越成功的當下,在資料傳輸技術得到速度和質量上的突破後,甚至可以通過該系統對行星狀態做實時監控呈現,對宇航員的作業點、作業情況做線上監控。在配置上人造衛星軌道、監控區域的資料後,本系統可用作衛星系統,描述覆蓋範圍和呈現觀測資料。

預覽地址: https://www.hightopo.com/demo/solar-system/

介面簡介及效果預覽 

主題一:太陽系檢測系統

 本系統主要展示8大行星繞太陽公轉軌道、相對位置、星體質量、資源含量等資訊。

右上角行星按鈕會觸發視角切換,切換至相對應的行星觀測點

this.g3d.flyTo(data, {
    animation: {
        duration: 1000,
        easing: function (t) {
            return (2-t) * t;
        }
    },
    distance: 2000
});

效果:

該主題提供兩種視角,鳥瞰和斜視,其它視角可以通過滑鼠自行旋轉

兩種視角的切換由右上角第二、三個圓形按鈕觸發。

呼叫 moveCamera 方法重新設定相機位置:

/**
 * 切換鏡頭
 * @param {Number} num - 主題編號
 */
triggerThemeCamera(num) {
    //...
    this.g3d.moveCamera(
        [ 6742.5, 4625.6, -836.7],
        [0, 0, 0],
        {
            duration: 500,
            easing: function (t) {
                return (2-t) * t;
            }
        }
    );
}

 效果:

資訊框預設採用跟隨星體一起旋轉,這可以達到俯視視角不出現資訊框,看起來更清爽。

如果需要檢視星體詳情,可以通過點選右上角播放按鈕,該按鈕會觸發所有資訊框朝向螢幕方向。

通過改變訊息面板 style.autorotate 來實現:

setBillboardToCamera(flag) {
    const list = this.dm3d.getDatas();
    list.each( item => {
        if (item instanceof ht.Node) {
            if (/_board$/.test(item.getTag())) {
                if (flag) {
                    item.s('shape3d.autorotate', true);
                }
                else {
                    item.s('shape3d.autorotate', false);
                }
            }
        }
    });
}

效果:

主題二:戴森球星體 3D 拓撲結構

本系統主要展示使用者所點選的行星與其它星際物質的相互作用,也可用於展示行星周圍衛星的分佈情況,以及展示星體間引力、輻射範圍等的拓撲結構。

滑鼠懸停在一個星體上會觸發選中狀態,右側會監控該星體的相關資料。

通過監聽 mousemove 後呼叫 resetPinkOutside 方法,將粉色邊框重新設定到懸停的 node 位置:

/**
 * 重新設定邊框
 * @param node
 */
resetPinkOutside(node) {
    const pinkOutside = this.dm3d.getDataByTag('billboard4');
    pinkOutside.setPosition3d(node.getPosition3d()[0],node.getPosition3d()[1],node.getPosition3d()[2]);
}

效果:

主題三:星體氣象、地形檢測系統

該主題主要用於呈現在場景二中點選的星體上具體的檢測點位,點位周邊的等高線在左側自動生成一個 3D 的地形和閃爍的點位示意,並與右側的檢測點位一一對應。

該功能可用於地形的呈現,也可以用於星體大氣層的氣象狀態展示。

左下角實時監控點位的地質熱量、氣象流動資料。

點選右側對應檢測點,會觸發右側點的縮放動畫,同時左側對應的 3D 點位也會同步變化,其它的點則呼叫 setAnimation(null)

setTwinkleToPoints(flag) {
    //...
    if (flag) {
        if (point1_3D && point1) {
            if (this.animationFlags.twinklePointNum === 1) {
                point1_3D.setAnimation({
                    change: {},
                    start: ["change"]
                });
                point1.setAnimation({
                    width: {},
                    height: {},
                    start: ["width", "height"]
                });
            } else {
                SolarSystem.disableTwinkle(point1_3D, point1);
            }
        } else {
            SolarSystem.disableTwinkle(point1_3D, point1);
            //...
        }
    }
}

效果:

關聯:三個主題(系統)的聯動

三個系統是互相關聯的,相互切換的方式有三種。

  1.點選左上角的切換按鈕:

  左上角部分均為導航欄的響應範圍,滑鼠懸停時會改變動畫控制器 animationFlags 的對應值,觸發導航欄落下來,懸停和點選按鈕會通過 setImage 方法設定不同的背景

this.g2d.getView().addEventListener('mousemove', event => {
    const node = this.g2d.getDataAt(event);
    let tag = '';
    if (node) {
        tag = node.getTag();
    }
    if('navigator' === tag){
        if(!this.animationFlags.navigatorRotate && this.animationFlags.navAnimationDone){
            this.animationFlags.navAnimationDone = false;
            this.animationControl(0, true);
        }
        this.resetButtonStyle();
    }
    else if (/^navButton/.test(tag)) {
        this.animationFlags.navButtonOnHover = true; // 防止動畫過快導致無法點選按鈕
        this.resetButtonStyle();
        if (!node.a('buttonOnClick')) {
            node.setImage('buttonOnHover');
        }
    }
    else {
        this.resetButtonStyle();
        this.animationFlags.navButtonOnHover = false;
        if(this.animationFlags.navigatorRotate && this.animationFlags.navAnimationDone){
            setTimeout(() => {
                if(!this.animationFlags.navButtonOnHover){
                    this.animationFlags.navButtonOnHover = true;
                    this.animationFlags.navAnimationDone = false;
                    this.animationControl(0, false);
                }
            }, 500);
        }
    }
}, false);

效果:

  2.點選最下方的標尺欄,分別對應 3 個模組:

   3.點選主題一中的行星跳轉到的主題二的拓撲結構,點選主題二的星體跳轉主題三的地形,主題三無法向前關聯,只能通過前兩種方式進行跳轉:

總結:

該系統使用輕量高效的 ht 庫,向量平面資訊與 3D 物件進行關聯,並採用 3D 拓撲視覺化呈現,相對位置清晰直觀,3D 地形與等高線圖對應,海拔高度和相互遮擋關係都可以準確把握。

該系統滿足了最基本的太空場景和資料呈現的框架,更為詳盡的資料呈現和業務功能有待相關的工作人員根據具體的業務場景提出更詳盡的需求。