如何用webgl(three.js)搭建處理3D隧道、3D橋樑、3D物聯網設備、3D高速公路、三維隧道橋樑設備監控-第十一課

開篇廢話:

跟之前的文章一樣,開篇之前,總要寫幾句廢話,大抵也是沒啥人看仔細文字,索性我也想到啥就聊啥吧。

這次聊聊疫情,這次全國多地的疫情挺嚴重的,本人身處深圳,深圳這幾日報導都是幾十幾十的新增病例,整個深圳都按下了暫停鍵。在此也真誠的感謝在一線辛苦抗疫的醫護工作者、自願者以及政府工作人員們。

疫情起起伏伏,着實對經濟的衝擊還是挺大的,大家也都切身感受到了疫情對我們的生活影響了,社會上也出現了一些質疑的聲音,有質疑動態清零的,也有標榜國外放棄抗疫的。國外的國情、政治文化,我們且按下不表。

且說說我個人的觀點吧,首先我也是快十年的老黨員了,深知我黨的宗旨:全心全意為人民服務。一切為了人民,保障人民的生命財產安全。這些年,特別是疫情這兩年,也能看出我黨維護宗旨的堅定與決心。

政府的任何一個決策都是經過深思熟慮,深入研究調查的,比如動態清零政策,無論從經濟、政治、文化角度,我們都有充足的理由需要這樣做,再從死亡率角度講,無論死亡率有多低,發生在任何一個家庭,都是不可接受的。

加上我國人口基數大,如果放棄動態清零,病毒發生變異的可能性會增加,如果往好的方向變異也就罷了,但如果往壞的方向變異,那損失是不可計量的。

這些日子居家辦公中,一時興起,講了些自己的觀點,閑話少敘,我們進入正題

項目背景:

隨着三維可視化技術越來越普及,應用的行業也是越來越多,前面的文章,我們介紹了三維園區三維機房(數據中心)三維消防模擬三維庫房檔案室數字孿生,等等。

鑒於可視化方案的直觀可控,及時反饋,衝擊力強,美觀大氣等特點。對於橋樑,隧道上三維可視化系統也有充分的必要性與實用性。

  一、方案設計:

 針對橋樑隧道方案,初步設計以監控物聯網設備為主,前置設備將數據傳給中間網關,網關再將數據傳給平台,平台端與三維進行數據交互

採用rest方式提供接口協議,websoket方式實時監控告警。

三維端以主動獲取方式去拉去數據。對於實時性要求高的數據,比如告警、應力值等採用websoket方式保持實時性。

1.動態加載

在系統的某些場景中採用了模型動態加載技術,比如在自動巡檢功能,初期方法是在點擊自動巡檢時加載所有設備模型到場景中,這時設備數量稍多便會造成運行卡頓,為了解決這個問題,採取即時加載即時刪除的方法,設置加載閥值和移除閥值,當camera運行到接近裝置設備時達到加載閥值,在這時加載此裝置設備中所有的設備模型,然後裝置設備打開、巡檢此設備,當camera繼續運行遠離此裝置設備,裝置設備關閉後達到移除閥值,移除此裝置設備中的所有設備模型,循環往複直至巡檢結束。這樣,既保證了巡檢的功能性,也使運行更加流暢。

2.用克隆代替加載新模型

當要往場景中加載場景中有存在的模型時,用clone()方法克隆已加載模型代替加載新模型,這樣能夠減少內存佔用率。

3.處理模型文件

 在建模時就應該注意盡量減少不必要的點邊面,將能夠合併的邊和面進行合併操作,將相同的模型材質也進行合併,以減少模型的複雜度,導出模型後再對模型文件進行壓縮。

4.模型製作技術

本系統大量採用代碼模型來製作所需的設備模型,Three.js有專用的模型庫,非常容易使用,在呈現複雜的幾何體或場景時非常有優勢。

 二、效果與代碼實現:

2.1、隧道全景

按照等比例,將隧道建模,採用透明透視方式為隧道頂部建模,方便看清內部設備與結構

 模型還是採用數據代碼形式實現,例如添加標記模型

ModelBussiness.prototype.addMark = function (name,position,scale) {
    var markjson = [{ "name": name, "objType": "picIdentification", "size": scale, "position": position, "imgurl": "../img/3dImg/qp4.png", "showSortNub": 327, "show": true, "customType1": "", "customType2": "", "animation": null, "dbclickEvents": null, "BindDevId": null, "BindDevName": null, "devInfo": null, "BindMeteId": null, "BindMeteName": null }];
}

2.2、服務機房

前置設備通過有線(穩定)方式,傳輸數據到服務機房的中間網關上,網關再傳給本地中轉平台,平台再上雲台數據。

 

 2.3、設備監控

隧道內支持多種設備類型監控,通過參數化方案,載入模型。

  DevTypes: {
        "FXD": "風向袋",
        "QXG": "氣象儀",
        "GDSXJ": "固定攝像機",
        "YKSXJ": "遙控攝像機",
        "ZPSXJ": "抓拍攝像機",
        "WBJCY": "微波車輛檢測器",
        "MJSQBB": "門架式情報板",
        "XBSQBB": "懸臂式情報板",
        "QYKZQ": "區域控制器",
        "SKBXHD": "四可變信號燈",
        "CDZSD": "車道指示燈",
        "XBGZ": "懸臂杆子",
        "GZ1": "杆子1",
        "GZ2": "杆子2",
        "FJ": "風機",
        "IPGB": "IP廣播",
        "JJDH": "緊急電話",
        "KBXHD1": "單個變信號燈",
        "KBXHD2": "二可變信號燈",
        "KBXHD3": "三可變信號燈",
        "DD": "燈帶",
        "HZBJQ": "火災報警",
        "QBB": "情報板",
        "QBB2": "情報板2",
        "XSQBB": "限速情報板",
        "COVI": "covi檢測器",
        "QGJCQ": "光強檢測器",
        "FSY": "風速儀",
        "JTSJJCQ": "交通事件檢測器",
    }

主要參數如下:

  {
            show: true,
            dataId:"f101",//數據id
            type: "FJ",//類型 風機
            name: "fj1",//唯一性
            position: { x: -950, y: 55, z: -70 },//位置
            scale: { x: 0.05, y: 0.05, z: 0.05 },//縮放
            rotation: { x: 0, y: Math.PI/2, z: 0 }//旋轉
        }

 

 

設備模型支持動態調整

/*
type:類型(見TypeConfig.json文件)
name:名稱(命名規則)名稱+樁號 ,所有特殊符號用下劃線替換
position:在三維中的位置,可通過任意添加一個位置,然後調整到合適位置,格式{x:0,y:0,z:0}
scale:模型的縮放,格式{x:1,y:1,z:1} x y z的值大於0
rotation:模型旋轉,格式{x:0,y:0,z:0} x y z的值取值範圍是0到Math.PI*2
show:是否顯示
dataId:關聯的數據id
callBack:添加成功後回調
*/
ModelBussiness.prototype.addOrUpdataModel = function (type, name, position, scale, rotation, show, dataId, callBack) {
    var _this = this;
    $.each(Config.DevModels, function (_index, _obj) {
        if (_obj.type == type && _obj.name == name) {
            _obj.position = position;
            _obj.scale = scale;
            _obj.rotation = rotation;
            _obj.show = show;
            _obj.dataid = dataid;
        }
    });
    var obj = WT3DObj.commonFunc.findObject("dev_" + type + "_" + name);
    if (obj) {
        if (position) {
            obj.position.x = position.x;
            obj.position.y = position.y;
            obj.position.z = position.z;
        }
        if (scale) {
            obj.scale.x = scale.x;
            obj.scale.y = scale.y;
            obj.scale.z = scale.z;
        }
        if (rotation) {
            obj.rotation.x = rotation.x;
            obj.rotation.y = rotation.y;
            obj.rotation.z = rotation.z;
        }
        obj.visible = show;

    } else {
        Config.DevModels.push({
            show: show,
            dataId: dataId,//數據id
            type: type,//類型 
            name: name,//唯一性
            position: position,//位置
            scale: scale,//縮放
            rotation: rotation//旋轉
        });
        var json = _this.createModel(type, name, position, scale, rotation, show);
        WT3DObj.commonFunc.loadModelsByJsons([json], { x: 0, y: 0, z: 0 }, { x: 0, y: 0, z: 0 }, true, true, function () {
            if (callBack) {
                callBack();
            }
        });
    }
  
}

設備模型快速定位

/*
type:類型(見TypeConfig.json文件)
name:名稱(命名規則)名稱+樁號 ,所有特殊符號用下劃線替換
callBack:定為完成後回調函數
*/
ModelBussiness.prototype.LocationObj = function (type, name, callBack) {
    var obj = WT3DObj.commonFunc.findObject("dev_" + type + "_" + name);
    if (obj) {
        CloseDistance(obj, function () {
            if (callBack) {
                callBack();
            }
        });
    }
    return obj;
}

 2.3、通用隧道

 增加通用隧道模型,以用來適配不同場景下,匹配大部分隧道場景。既直觀展示,又模擬場景。

 

同時提供通用方法,比如通用數據彈窗回調等:

//////////////////////回調方法/////////////////////////////
/*
單擊回調配置
model:模型對象
dataInfo 包含了關聯的業務數據 比如數據dataId
*/
function clickDevCallBack(model, dataInfo) {
    var showHtml = "<div >此處顯示自定義內容</div>";
    layer.tips(showHtml, '#MarkMessageHelper', {
        closeBtn: 1,
        shade: 0.1,
        shadeClose: true,
        area: ["300px", "300px"],
        maxWidth: 1000,
        maxHeight: 350,
        skin: 'louBox',
        time: 0,//是否定時關閉,0表示不關閉
        cancel: function (index, layero) {
        
        },
        success: function () {

        },
        tips: [1, "rgba(14, 188, 255,1)"] //還可配置顏色
    });
}
/*
雙擊回調配置
model:模型對象
dataInfo 包含了關聯的業務數據 比如數據dataId
*/
function dbClickDevCallBack(model,dataInfo) {
    
    //舉例
    var showHtml = "<div >此處顯示自定義內容</div>";
    layer.open({
        type: 1,
        title: model.name+"自定義彈窗案例【"+dataInfo.dataId+"】",
        shade: [0.1],
        area: ['500px', '500px'],
        anim: 2,
        content: showHtml, //iframe的url,no代表不顯示滾動條
        end: function () { //此處用於演示
        }
    });
}

 

 三、橋隧一體

3.1、橋樑隧道全景

此場景包含兩座大橋,中間夾着一座隧道,比較經典的橋隧場景

由於場景涉及範圍較廣,為提升適配機器性能,在大場景下,我們採用大模,涵蓋主體建築。概況監測。

 

3.2、單獨展示橋樑模型

雙擊單個主體後,進入主體細模,詳細展示模型與模型上所監控的設備單體。

 

//雙擊選中
ModelBussiness.prototype.dbClickSelectCabinet = function (_obj, _face) {
    if (!_obj.visible) {
        return;
    }
   // layer.msg("【雙擊設備接口】設備名稱" + _obj.name);
    //datainfo表示配置的數據 可以根據datainfo.dataId獲取與數據的關聯關係
    var datainfo = getInfoByModelName(_obj.name);
    console.log(datainfo);
    dbClickDevCallBack(_obj, datainfo);
}

 

 3.3、橋樑設備監管

另一座橋樑細模設備監測。

設備模型狀態修改

//修改模型狀態
/*
type:類型(見TypeConfig.json文件)
name:名稱(命名規則)"dev_"+類型+"_"+名稱+樁號 ,所有特殊符號用下劃線替換
state:字符串  在線:1 離線:0 故障:-1
            風向袋的狀態值:1_度數 度數的取值範圍0到Math.PI*2
            四可變信號燈:10000 第一位表示在線 離線 故障
                                後面四位分別表示每個燈的亮和滅 
*/
ModelBussiness.prototype.changeDevCtrlState = function (type,name, state) {
    var _this = this;
    var modelJson = "";
    var obj = WT3DObj.commonFunc.findObject("dev_" + type + "_" + name);
    if (!obj&&obj.name.indexOf("dev_")!=0) {
        return;
    }
    
    switch (type) {
        case "XSQBB"://可變限速標誌 狀態:30、40、50、60、80、100、120、異常、故障 130、140、150、160、180、1100、1120 、 0 -1
            state = parseInt(state);
            if (state > 0) {
                if (state > 100) {
                    obj.children[0].freshData(state);
                    obj.children[0].position.z = -5;
                    obj.children[0].matrixAutoUpdate = true;
                } else {
                    obj.children[0].freshData(state);
                    obj.children[0].position.z = -30;
                    obj.children[0].matrixAutoUpdate = true;
                }
            } else {
                obj.children[0].freshData("")
            }
            break;
        case "CDZSD"://車道指示燈 正綠背頭  正紅背綠  正紅背紅 1 2 3
            {
                if (parseInt(state) == 1) {
                    WT3DObj.commonFunc.setObjSkinImg(obj, 0, "../img/3dImg/go.png");
                    WT3DObj.commonFunc.setObjSkinImg(obj, 1, "../img/3dImg/stop.png");
                } else if (parseInt(state) == 2) {
                    WT3DObj.commonFunc.setObjSkinImg(obj, 0, "../img/3dImg/stop.png");
                    WT3DObj.commonFunc.setObjSkinImg(obj, 1, "../img/3dImg/go.png");
                } else if (parseInt(state) == 3) {
                    WT3DObj.commonFunc.setObjSkinImg(obj, 0, "../img/3dImg/stop.png");
                    WT3DObj.commonFunc.setObjSkinImg(obj, 1, "../img/3dImg/stop.png");
                }
            }
            break;
        case "KBXHD1"://單個變信號燈 紅、黃、綠 黑 左 右1 2 3 4 5 6
            { 
                if (parseInt(state) == 1) {
                    WT3DObj.commonFunc.setObjSkinImg(obj, 0, "../img/3dImg/redlight.png");
                } else if (parseInt(state) == 2) {
                    WT3DObj.commonFunc.setObjSkinImg(obj, 0, "../img/3dImg/yellowlight.png");
                } else if (parseInt(state) == 3) {
                    WT3DObj.commonFunc.setObjSkinImg(obj, 0, "../img/3dImg/golight.png");
                } else if (parseInt(state) == 4) {
                    WT3DObj.commonFunc.setObjSkinImg(obj, 0, "../img/3dImg/nolight.png");
                } else if (parseInt(state) ==5) {
                    WT3DObj.commonFunc.setObjSkinImg(obj, 0, "../img/3dImg/left.png");
                } else if (parseInt(state) ==6) {
                    WT3DObj.commonFunc.setObjSkinImg(obj, 0, "../img/3dImg/right.png");
                }
            }
            break;
        case "KBXHD2":
            {
                var stateArray = (state + "").split("");

                if (stateArray[0] == "1") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[4], 1, "../img/3dImg/redlight.png");
                } else if (stateArray[0] == "2") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[4], 1, "../img/3dImg/yellowlight.png");
                } else if (stateArray[0] == "3") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[4], 1, "../img/3dImg/golight.png");
                } else if (stateArray[0] == "4"){
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[4], 1, "../img/3dImg/nolight.png");
                } else if (stateArray[0] == "5") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[4], 1, "../img/3dImg/left.png");
                } else if (stateArray[0] == "6") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[4], 1, "../img/3dImg/right.png");
                }

                if (stateArray[1] == "1") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[3], 1, "../img/3dImg/redlight.png");
                } else if (stateArray[1] == "2") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[3], 1, "../img/3dImg/yellowlight.png");
                } else if (stateArray[1] == "3") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[3], 1, "../img/3dImg/golight.png");
                } else if (stateArray[1] == "4") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[3], 1, "../img/3dImg/nolight.png");
                } else if (stateArray[1] == "5") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[3], 1, "../img/3dImg/left.png");
                } else if (stateArray[1] == "6") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[3], 1, "../img/3dImg/right.png");
                }
            }
            break;
        case "KBXHD3":
            {
                var stateArray = (state + "").split("");

                if (stateArray[0] == "1") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[2], 1, "../img/3dImg/redlight.png");
                } else if (stateArray[0] == "2") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[2], 1, "../img/3dImg/yellowlight.png");
                } else if (stateArray[0] == "3") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[2], 1, "../img/3dImg/golight.png");
                } else if (stateArray[0] == "4"){
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[2], 1, "../img/3dImg/nolight.png");
                } else if (stateArray[0] == "5") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[2], 1, "../img/3dImg/left.png");
                } else if (stateArray[0] == "6") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[2], 1, "../img/3dImg/right.png");
                }


                if (stateArray[1] == "1") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[5], 1, "../img/3dImg/redlight.png");
                } else if (stateArray[1] == "2") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[5], 1, "../img/3dImg/yellowlight.png");
                } else if (stateArray[1] == "3") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[5], 1, "../img/3dImg/golight.png");
                } else if (stateArray[1] == "4"){
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[5], 1, "../img/3dImg/nolight.png");
                } else if (stateArray[1] == "5") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[5], 1, "../img/3dImg/left.png");
                } else if (stateArray[1] == "6") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[5], 1, "../img/3dImg/right.png");
                }
                if (stateArray[2] == "1") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[4], 1, "../img/3dImg/redlight.png");
                } else if (stateArray[2] == "2") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[4], 1, "../img/3dImg/yellowlight.png");
                } else if (stateArray[2] == "3") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[4], 1, "../img/3dImg/golight.png");
                } else if (stateArray[2] == "4"){
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[4], 1, "../img/3dImg/nolight.png");
                } else if (stateArray[2] == "5") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[4],1, "../img/3dImg/left.png");
                } else if (stateArray[2] == "6") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[4], 1, "../img/3dImg/right.png");
                }
            }
            break;

        case "SKBXHD"://四可變信號燈 在線 離線 故障  4種信號燈單獨顯示(滅/亮) 1 0 -1 10000(後面四位表示每個信號燈狀態)
            {
                var stateArray = (state + "").split("");

                if (stateArray[0] == "1") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[2], 1, "../img/3dImg/redlight.png");
                } else if (stateArray[0] == "2") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[2], 1, "../img/3dImg/yellowlight.png");
                } else if (stateArray[0] == "3") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[2], 1, "../img/3dImg/golight.png");
                } else if (stateArray[0] == "4") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[2], 1, "../img/3dImg/nolight.png");
                } else if (stateArray[0] == "5") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[2], 1, "../img/3dImg/left.png");
                } else if (stateArray[0] == "6") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[2], 1, "../img/3dImg/right.png");
                }

                if (stateArray[1] == "1") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[0], 1, "../img/3dImg/redlight.png");
                } else if (stateArray[1] == "2") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[0], 1, "../img/3dImg/yellowlight.png");
                } else if (stateArray[1] == "3") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[0], 1, "../img/3dImg/golight.png");
                } else if (stateArray[1] == "4") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[0], 1, "../img/3dImg/nolight.png");
                } else if (stateArray[1] == "5") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[0], 1, "../img/3dImg/left.png");
                } else if (stateArray[1] == "6") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[0], 1, "../img/3dImg/right.png");
                }
                if (stateArray[2] == "1") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[3], 1, "../img/3dImg/redlight.png");
                } else if (stateArray[2] == "2") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[3], 1, "../img/3dImg/yellowlight.png");
                } else if (stateArray[2] == "3") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[3], 1, "../img/3dImg/golight.png");
                } else if (stateArray[2] == "4") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[3], 1, "../img/3dImg/nolight.png");
                } else if (stateArray[2] == "5") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[3], 1, "../img/3dImg/left.png");
                } else if (stateArray[2] == "6") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[3], 1, "../img/3dImg/right.png");
                }
                if (stateArray[3] == "1") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[4], 1, "../img/3dImg/redlight.png");
                } else if (stateArray[3] == "2") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[4], 1, "../img/3dImg/yellowlight.png");
                } else if (stateArray[3] == "3") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[4], 1, "../img/3dImg/golight.png");
                } else if (stateArray[3] == "4") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[4], 1, "../img/3dImg/nolight.png");
                } else if (stateArray[3] == "5") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[4], 1, "../img/3dImg/left.png");
                } else if (stateArray[3] == "6") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[4], 1, "../img/3dImg/right.png");
                }
            }
            break;
        case "DD"://照明燈帶(1亮、2正常、3暗)
            {
                obj.children[2].visible = true;
                if ((state) == 1) {
                    obj.children[2].material.opacity = 0.6;
                   // obj.children[2]
                } else if ((state) == 2) {
                    obj.children[2].material.opacity = 0.3;
                } else if ((state) == 3) {
                    obj.children[2].material.opacity = 0.1;
                }
            }
            break;
        case "HZBJQ"://火災報警 有聲音、無聲音)
            {
                if ((state) == 1) {
                    obj.children[1].visible = true;
                } else if ((state) == 2) {
                    obj.children[1].visible = false;
                }
            }
            break;
        case "IPGB"://廣播 (有聲音 1、無聲音 2)
            {
                if ((state) == 1) {
                    obj.children[0].visible = true;
                } else if ((state) == 2) {
                    obj.children[0].visible = false;
                }
            }
            break;
        case "JJDH"://緊急電話 (有聲音 1、無聲音 2)
            {
                if ((state) == 1) {
                    obj.children[1].visible = true;
                } else if ((state) == 2) {
                    obj.children[1].visible = false;
                }
            }
            break;

        case "FJ"://風機 停止、正轉、反轉 1 2 3
            {
                if (obj.runInterval) {
                    clearInterval(obj.runInterval);
                }
                if ((state) == 1) {
                    obj.children[0].rotation.z = 0;
                    obj.children[1].rotation.z = 0;
                    obj.children[0].matrixAutoUpdate = true;
                    obj.children[1].matrixAutoUpdate = true;
                    setTimeout(function () {
                        obj.children[0].matrixAutoUpdate = false;
                        obj.children[1].matrixAutoUpdate = false;
                    }, 100);
                } else if ((state) == 2) {
                    obj.children[0].matrixAutoUpdate = true;
                    obj.children[1].matrixAutoUpdate = true;
                    obj.runInterval = setInterval(function () {
                        obj.children[0].rotation.z += 0.5;
                        obj.children[1].rotation.z += 0.5;
                    }, 50);
                } else if ((state) ==3) {
                    obj.children[0].matrixAutoUpdate = true;
                    obj.children[1].matrixAutoUpdate = true;
                    obj.runInterval = setInterval(function () {
                        obj.children[0].rotation.z -= 0.5;
                        obj.children[1].rotation.z -= 0.5;
                    }, 50);
                }
              
            }
            break;

        case "FXD"://風向袋 參照實際,三維圖上示意處理 1_度數
            {
                var stateArray = state.split("_");
                var degree = parseFloat(stateArray[1]);//y軸旋轉度數
                obj.rotation.y = degree;
            }
            break;
        case "QBB"://情報板 state:文字圖片地址
        case "QBB2":
            {
                if (state!="") {
                    WT3DObj.commonFunc.setObjSkinImg(obj.children[1], 5, state);
                } 
            }
            break;
       
    }
}

 3.5、隧道分離展示

 

 3.6、隧道內設備展示

 

 

/*
//顯示設備狀態
type:   設備類型 見Config.DevTypes
name:   設備名稱 
state: 1:停用(灰色)
       2:故障(紅色)
       3:正常(自身顏色)
*/
ModelBussiness.prototype.setDevState = function (type, name, state) {
    var _this = this;
    var obj = WT3DObj.commonFunc.findObject("dev_" + type + "_" + name);
    if (obj) {
        var box = new THREE.Box3();
        box.setFromObject(obj);
        var positionY = obj.position.y+30;
        if (box&&box.max) {
            positionY = box.max.y + 18;
        }
        var objStateMarkModelName = "dev_" + type + "_" + name + "_stateMark";
        var objStateMark = WT3DObj.commonFunc.findObject(objStateMarkModelName);
        if (objStateMark) {
            WT3DObj.destoryObj(objStateMarkModelName);
        }
        if (state == 1 || state == 2) {
            var mark = {
                "name": objStateMarkModelName,
                "objType": "picIdentification",
                "size": { "x": 30, "y": 30 },
                "position": { "x": obj.position.x, "y": positionY, "z": obj.position.z },
                "imgurl": "../img/3dImg/" + (state == 1 ? "qp3.png" : "qp4.png"),
                "showSortNub": 1
            };
            var temObj = WT3DObj.createObjByJson(mark);
            temObj.material.depthTest = false;
            temObj.visible = obj.visible;
            WT3DObj.addObject(temObj);
        }
        WT3DObj.commonFunc.flashObjs([obj], obj.name + "_flashanimation_", 0x000000, -1, 200, 0);
        if (state == 1) {
            setTimeout(function () {
                WT3DObj.commonFunc.flashObjs([obj], obj.name + "_flashanimation_", 0x333333, 0, 200, 0);
                _this.flashObjsNames.push(obj.name);
            }, 500);
        } else if (state == 2) {
            setTimeout(function () {
                WT3DObj.commonFunc.flashObjs([obj], obj.name + "_flashanimation_", 0xff0000, 0, 200, 0);
                _this.flashObjsNames.push(obj.name);
            }, 500);
        } else if (state==3) {
            var _index = _this.flashObjsNames.indexOf(obj.name);
            if (_index >= 0) {
                _this.flashObjsNames.splice(_index, 1);
                WT3DObj.commonFunc.flashObjs([obj], obj.name + "_flashanimation_", 0x000000, -1, 200, 0);
            }
        }

    }
}

 

技術交流 [email protected]

交流微信:

    

如果你有什麼要交流的心得 可郵件我

 

其它相關文章:

如何用three.js實現數字孿生、3D工廠、3D工業園區、智慧製造、智慧工業、智慧工廠-第十課

使用webgl(three.js)創建3D機房,3D機房微模塊詳細介紹(升級版二)

如何用webgl(three.js)搭建一個3D庫房-第一課

如何用webgl(three.js)搭建一個3D庫房,3D密集架,3D檔案室,-第二課

使用webgl(three.js)搭建一個3D建築,3D消防模擬——第三課

使用webgl(three.js)搭建一個3D智慧園區、3D建築,3D消防模擬,web版3D,bim管理系統——第四課

如何用webgl(three.js)搭建不規則建築模型,客流量熱力圖模擬

 使用webgl(three.js)搭建一個3D智慧園區、3D建築,3D消防模擬,web版3D,bim管理系統——第四課(炫酷版一)

使用webgl(three.js)搭建3D智慧園區、3D大屏,3D樓宇,智慧燈桿三維展示,3D燈桿,web版3D,bim管理系統——第六課

如何用webgl(three.js)搭建處理3D園區、3D樓層、3D機房管線問題(機房升級版)-第九課(一)