主頁 > 企業開發 > 如何使用webgl(three.js)實作3D消防、3D建筑消防大樓、消防數字孿生、消防可視化解決方案——第十八課(一)

如何使用webgl(three.js)實作3D消防、3D建筑消防大樓、消防數字孿生、消防可視化解決方案——第十八課(一)

2023-03-12 08:41:08 企業開發

序:

  又是很久沒出隨筆文章了,一篇文章有時候整理一天,實在是抽不出來時間,

  最近在回顧幾年前的專案時,發現這個智慧三維消防可視化專案很有回顧價值,索性就拿出來講講,

  首先,我們要知道消防里的知識,不是簡簡單單的幾個滅火器,煙感報警器這么簡單的,消防是自有一套完整體系的,光是消防相關的產業年產值就有幾千個億,而我們普通非專業人士常見的消防設備只是消防產業中的皮毛,

  單是消防系統就可以分為很多類,常見的有消防給水系統、消火栓系統、自動噴水滅火系統、氣體滅火系統、防煙排煙系統、火災自動報警系統等等,這些系統內部的組成結構又各有不同,每個系統里就有幾十個甚至上百個不同的消防設備,比如我們常見的消防噴頭就有好幾種,各自用于不同的建筑場景,

  還是閑話少序,切入正題,

前言:

  前面的課程里,有一篇文章《使用webgl(three.js)搭建一個3D智慧園區、3D建筑,3D消防模擬,web版3D,bim管理系統——第四課》是介紹實作消防模擬的,本文以及后續的篇幅將系統的介紹消防可視化方案,

  這篇文章由于篇幅原因,我專門這一篇先介紹一下常見的消防系統,以及代碼框架,在后續的篇幅里我們再各個擊破,詳細介紹每個消防系統的3D實作方案,

  我們是技術類文章,這里只能做一個簡單的常見的消防系統定義介紹:

    消防給水系統:以水為滅火劑消防撲救火災的供水系統,由水源、消防給水管網、消防水池、消防水泵及消火栓、自動噴水滅火設施等組成,

    消火栓系統:消火栓系統一般都由主泵和備用泵組成,一般按鈕啟動后,先啟動1#泵,1#泵啟動失靈,自動轉啟2#泵,只有當兩臺泵都不能啟動時,控制盤上才顯示故障,消防水泵的故障,一般是指水泵電機斷電、過載及短路等

    自動噴水滅火系統:自動噴水滅火系統由灑水噴頭、報警閥組、水流報警裝置等組件,以及管道、供水設施組成,并能在發生火災時噴水的自動滅火系統,

    氣體滅火系統:氣體滅火系統主要用在不適于設定水滅火系統等其他滅火系統的環境中

    防煙排煙系統:防排煙系統,都是由送排風管道、管井、防火閥、門開關設備、送、排風機等設備組成

    火災自動報警系統:火災自動報警系統是由觸發裝置、火災報警裝置、聯動輸出裝置以及具有其它輔助功能裝置組成的

  上述系統,在我們實作3D軟體模擬程序中,程式員需要詳細知道各系統的作業原理,作用,才不會出現重大的業務性bug,(這就是程式員為啥會掉頭發,基本在做一個系統體系時,就需要學習了解一遍)

  言歸正傳,我們下面對各系統架構做一些概括性講解,

一、效果展示

 1.1、消防給水系統效果展示

 

 系統涉及各部件展示,邏輯結構展示,通過剖面視角、管網視角,全方位,多視角展示改系統的結構組成,

其功能實作的主要偽代碼如下:

首先創建系統物件,用于各系統之間的切換

$(function () {
    indexPage = new IndexPage();
    indexPage.init();
    for (var i = 1; i <= 6; i++) {
        if (window["System0" + i]) {
            window["system0" + i] = new window["System0" + i]();
            window["system0" + i].init();
        }
    }
});

切換系統事件系結

    $(".res .sys").click(function () {
        $("#sysMainNav").hide();
        $("#sysNav1").show();
        $("#sysNav2").show();
        var systemindex = $(this).attr("data-systemIndex");
        console.log(systemindex);
       
        if (window["system0" + systemindex]) {
            window["system0" + systemindex].show();
        }
    });

主功能切換

//功能ui
IndexPage.prototype.showSystemMainNav1 = function (nav1) {
    layer.closeAll();
    $("#backToMainNav").nextAll().remove();
    if (nav1 && nav1.length > 0) {
        var sysNav1_detailhtml = "";
        $.each(nav1, function (_index, _obj) {
            sysNav1_detailhtml += '<div id="' + _obj.id + '"   onclick="if(indexPage.clickme){return false;};indexPage.clickme=true;setTimeout(function(){indexPage.clickme=false},500);' + _obj.actionStr + ';">\
               <img src= "https://www.cnblogs.com/yeyunfei/img/' + (_obj.defaultState == "noselect" ? "dot_unselect.png" : "dot_selected.png") + '"  />\
                   <p >' + _obj.name + '</p>\
        </div >';
        });
        $("#backToMainNav").after(sysNav1_detailhtml);
    }
}

 

 1.2、消火栓系統

 消火栓系統與消防給水系統功能類似,只是其組成部件的側重點不一樣

例如消火栓注重分室外、室內、干式、濕式、水鶴等等

這里我們是展示模型的視角不一樣

   modelBussiness.hideAllPLSystemDevs(200, function () {
                layer.msg("loading...", { time: 1000 });
                if (param.greatePosition) {
                    var greatePosition = param.greatePosition[_this.nav1State];
                    var camera = { x: 0, y: 0, z: 0 };
                    var target = { x: 0, y: 0, z: 0 };
                    var abloutModelNames = null;
                    var abloutModelObjs = null;
                    if (greatePosition) {
                        camera = greatePosition.camera;
                        target = greatePosition.target;
                        abloutModelNames = greatePosition.abloutModelNames;
                    }
                    if (abloutModelNames == "All") {
                        modelBussiness.showAllDevModels(1);
                    }
                    else if (abloutModelNames && abloutModelNames.length > 0) {
                        abloutModelObjs = WT3DObj.commonFunc.findObjectsByNames(abloutModelNames);
                        if (abloutModelObjs && abloutModelObjs.length > 0) {
                            $.each(abloutModelObjs, function (_index, _obj) {
                                _obj.visible = true;
                            });
                        }
                    }
                    WT3DObj.commonFunc.changeCameraPosition(camera, target, 1000, function () {
                        if (id == "s02_03_ssshs" || id == "s02_03_gsshs") {
                            if (_objs) {
                                $.each(_objs, function (_index, _obj) {
                                    if (_obj.name == "pldev_t10_1_7") {
                                        WT3DObj.commonFunc.changeObjsOpacity([_obj], 1, 0.2, 50, function () {
                                        });
                                    }
                                    if (_obj.name == "pldev_t10_1_7_inner" && id == "s02_03_gsshs") {
                                        _obj.visible = false;

                                    }

                                    if (_obj.name == "pldev_t10_1_7_inner" && id == "s02_03_ssshs") {
                                        _obj.visible = true;
                                    }
                                });
                            }

                        }
                    });
                } else {
                    console.log("資料初始化例外!沒有設定最佳位置");
                    return;
                }
            });

 

 1.3、自動噴水滅火系統

該系統注重整體運作原理,在部件中特意加了原理影片講解

 【系統部件原理影片舉例

 影片實作偽代碼:

//執行影片 遞回呼叫
System02.prototype.doAnimation = function () {
    modelBussiness.showAllPLSystemDevs(50, function () {
    modelBussiness.hideAllBuildModels();
    modelBussiness.opcityDevs(function () {
        modelBussiness.changeDevsToSSMaterial();
        WT3DObj.commonFunc.changeCameraPosition({ x: -34, y: -331, z: -546 }, { x: -412, y: -260, z: 135 }, 1000, function () {
        });
        var actions = system02.nav2[2].children;
        if (actions && actions.length > 0) {
            function doaction(action_nub) {
                $("#" + actions[action_nub].id).attr("class", "nav2res navsys");
                if (action_nub > 0) {
                    $("#" + actions[action_nub - 1].id).attr("class", "nav2res navsys noseleced");
                }
                actions[action_nub].action(function () {
                    if (actions[action_nub + 1] && actions[action_nub + 1].action) {
                        doaction(action_nub + 1);
                    }
                });
            }
            doaction(0);
        }
    });
    });
}
 var animationChildren=[

                {
                    name: "發生火情",
                    id: "s01_step01",
                    greatePosition: {
                        camera: { x: -1388, y: -781, z: -309 },
                        target: { x: -2119, y: -1106, z: 873 }
                    },
                    actionStr: "",
                    action: function (callBack) {
                        modelBussiness.addFire(function () {
                            setTimeout(function () {
                                callBack();
                            }, 2000);
                        });
                    }
                },
                {
                    name: "噴淋動作",
                    id: "s01_step02",
                    greatePosition: {
                        camera: { x: -1388, y: -781, z: -309 },
                        target: { x: -2119, y: -1106, z: 873 }
                    },
                    actionStr: "",
                    action: function (callBack) {
                        console.log("執行2");
                        //找到噴淋
                        var pls = WT3DObj.commonFunc.findObjectsByNames(["pldev_penling_1_1_28", "pldev_penling_1_1_28_sp_1", "pldev_penling_1_1_28_sp_2", "pldev_penling_1_1_28_sp_3"]);
                        WT3DObj.commonFunc.flashObjs(pls, "flashPL", 0xff0000, 10, 200, 0);
                        setTimeout(function () {
                            var pl = pls[0];
                            pl.children[1].visible = false;
                            pl.children[3].visible = false;
                            //噴淋裂開
                            var pls1 = pls[1];
                            var p1x = pls1.position.x;
                            var p1z = pls1.position.z;
                            var pls2 = pls[2];
                            var pls3 = pls[3];
                            pls1.oldpostion = { x: pls1.position.x, y: pls1.position.y, z: pls1.position.z };
                            new TWEEN.Tween(pls1.position).to({
                                x: p1x + 100 * (Math.random() < 0.5 ? -5 * Math.random() : 3 * Math.random()),
                                y: -2000,
                                z: p1z + 100 * (Math.random() < 0.5 ? -5 * Math.random() : 3 * Math.random())
                            }, 8000).start();
                            new TWEEN.Tween(pls2.position).to({
                                x: p1x + 100 * (Math.random() < 0.5 ? -5 * Math.random() : 3 * Math.random()),
                                y: -2000,
                                z: p1z + 100 * (Math.random() < 0.5 ? -5 * Math.random() : 3 * Math.random())
                            }, 8000).start();
                            new TWEEN.Tween(pls3.position).to({
                                x: p1x + 100 * (Math.random() < 0.5 ? -5 * Math.random() : 3 * Math.random()),
                                y: -2000,
                                z: p1z + 100 * (Math.random() < 0.5 ? -5 * Math.random() : 3 * Math.random())
                            }, 8000).start();
                            //開始噴水
                            modelBussiness.addWater(
                                function () {
                                    setTimeout(function () {
                                        callBack();
                                    }, 1000);
                                }
                            );

                        }, 2000);
                    }
                },
                ......]

 1.4、氣體滅火系統

 在氣體系統中,實作方式又有點不一樣,前面幾個系統都是代碼模型,該系統使用了大量的載入模型,如座椅板凳等

該系統也是主要展現系統部件跟作業影片原理

影片中采用了大量的定時器,閉包,回呼,遞回等等,這里特別注意記憶體有效回收,否者瀏覽器可能會隨時崩潰

例如如下代碼:

  var a_messagePanel_1126 = WT3DObj.commonFunc.findObject("a_messagePanel_1126");
    a_messagePanel_1126.position.x=1499.804;
    a_messagePanel_1126.position.y = 474.389;
    a_messagePanel_1126.position.z = -74.822;
    moveXH(a_messagePanel_1126, { x: 2008.767, y: 474.389, z: -74.822, t: 0 }, 2000);
    setTimeout(function () {
        moveXH(a_messagePanel_1126, { x: 2007.926, y: 478.648, z: -451.129, t: 2000 }, 2000);
        setTimeout(function () {
            moveXH(a_messagePanel_1126, { x: -657.755, y: 478.648, z: -451.129, t: 2000 }, 2000);
            WT3DObj.commonFunc.changeCameraPosition({ x: -295.23352627790484, y: 445.15353495337854, z: -140.38158326269246 }, { x: -798.2079071244784, y: 270.3977749099737, z: -511.7589163393606 }, 10, function () {


            });
            setTimeout(function () {
                moveXH(a_messagePanel_1126, { x: -657.755, y: 478.648, z: -303.566, t: 2000 }, 2000);
                setTimeout(function () {
                    moveXH(a_messagePanel_1126, { x: -657.755, y: 339.858, z: -303.566, t: 2000 }, 2000);
                    setTimeout(function () {
                        a_messagePanel_1126.visible = false;
                        moveXH(a_messagePanel_1126, { x: -662.270, y: 315.038, z: -339.977, t: 2000 }, 2000);
                        setTimeout(function () {
                            a_messagePanel_1126.visible = true;
                            moveXH(a_messagePanel_1126, { x: -662.270, y: 465.038, z: -339.977, t: 2000 }, 2000);
                            setTimeout(function () {
                                moveXH(a_messagePanel_1126, { x: -662.270, y: 465.038, z: -719.977, t: 2000 }, 2000);

                                setTimeout(function () {
                                    WT3DObj.commonFunc.changeCameraPosition({ x: 1672.1492964146757, y: 437.22502365828495, z: -946.6467804045902 }, { x: 1393.4110369255911, y: 391.9499762093484, z: -843.1414359356829 }, 1000, function () {

                                    });
                                    moveXH(a_messagePanel_1126, { x: 1433, y: 465.038, z: -719.847, t: 2000 }, 2000);
                                    setTimeout(function () {
                                        moveXH(a_messagePanel_1126, { x: 1433, y: 465.038, z: -739.847, t: 2000 }, 2000);

                                    setTimeout(function () {
                                        moveXH(a_messagePanel_1126, { x: 1429.452, y: 382.109, z: -739.847, t: 2000 }, 2000);
                                        setTimeout(function () {
                                            sgbjq2(callBack);
                                        }, 2000);
                                    }, 2000);
                                    }, 2000);
                                }, 2000);
                            }, 2000);

                        }, 2000);

                    }, 2000);

                }, 2000);

            }, 2000);

        }, 2000);

    }, 2000);
/*
關閉送(排)風機及送(排)風閥門
停止通風和空調系統及關閉該防護區的電動防火閥
關閉防護區的門窗

*/

/*
向驅動氣瓶電磁閥發送開啟信號,可設≤30s 的延遲噴射

*/
function djsdz(callBack) {
    
    var dev = WT3DObj.commonFunc.findObjectsByNames([
                   "dev_ledFont_1",
    ])[0];
    for (var i = 30; i >=0; i--) {
        (function (a) {
            setTimeout(function () {
                if (a <10) {
                    a = "0"+a;
                }
                dev.freshData(a);
            },1000 * (30 - a));
        })(i);
       
    }
    setTimeout(function () {
        callBack();
    },31 * 1000);
}

 

 1.5、防煙排煙系統

 防排煙系統也是加了影片的形式,充分展現了其作業原理與組成部件

 action: function (callBack) {
                        //剖面圖
                        $.each(system07.allModels, function (_index, _obj) {
                            if (_obj.hasoldPosition) {
                                _obj.position.y = _obj.hasoldPosition.y ;
                            }
                            _obj.visible = true;
                        });
                        $.each(system07.foreModels, function (_index, _obj) {
                            if (_obj.hasoldPosition) {
                                _obj.position.y = _obj.hasoldPosition.y + 10000;
                            } else {
                                _obj.hasoldPosition = { y: _obj.position.y };
                                _obj.position.y = _obj.hasoldPosition.y + 10000;
                            }
                            _obj.visible = false;
                        });
                        //發生火情
                        system07.stepName = "發生火情!";
                        layer.msg("</br><font style='color:#ffffff;font-size:20px;'>發生火情!</font></br>");
                        WT3DObj.commonFunc.changeCameraPosition({ x: 6120.260855819656, y: 1344.6126089802272, z: 10903.874792293966 },  { x: 6292.0698848787415, y: 106.7257770257646, z: 4388.448120618271 }, 1000, function () {
                            addLines();
                            addFire();
                            addFYSFK();
                            setTimeout(function () {
                                WT3DObj.commonFunc.changeCameraPosition({ x: 5416.2974093433795, y: 1500.4126878089987, z: 7749.928368473556 }, { x: 5474.770344242846, y: 899.4381166888209, z: 4216.286318511336 }, 2000, function () {
                                    callBack();
                                });
                            }, 2000);
                        });
                    }
                },
System07.prototype.doAnimationFlag = false;
System07.prototype.showNav2Action = function (index, id) {
    var _this = this;
    modelBussiness.removeSingleShowDevs();
    console.log(id);
    if ((_this.nav1State == "s07_05" || _this.nav1State == "s07_06") && _this.doAnimationFlag) {
        layer.log("正在執行影片");
        return;
    }
    $("#" + _this.nav2State).attr("class", "nav2res navsys noseleced");
    $("#" + id).attr("class", "nav2res navsys");
    _this.nav2State = id;
    var param = _this.getNav2Param(index, id);
    if (!param) {
        console.log("資料初始化例外!");
        return;
    }
    layer.closeAll();
    this.playVoice(index, id);
    if (param.dataId && id != "s04_02_gsgd") {
        modelBussiness.showDevList(param.dataId);
    }
    function flashFunc() {

        if (param && param.flashNames && param.flashNames.length > 0) {
            var fnames = [];
            $.each(param.flashNames, function (_findex, _fobj) {
                var _n = _fobj;
                if (_fobj.indexOf("_children_") > 0) {
                    _n = _fobj.split("_children_")[0];
                }
                fnames.push(_n);
            });
            _objs = WT3DObj.commonFunc.findObjectsByNames(fnames);
            if (param.flashNames[0] == "All") {
                _objs = modelBussiness.getAllPLSystemDevs();
            }
            setTimeout(function () {
                WT3DObj.commonFunc.flashObjs(_objs, "flashPL", 0x00ff00, 8, 150, 0);
            }, 1000);
        }
    }
    flashFunc();
    switch (_this.nav1State) {
        //全景
        case "s07_01":
        //剖面
        case "s07_02":
        //管網
        case "s07_04":
        case "s07_03":
            if (param.greatePosition) {
                var greatePosition = param.greatePosition[_this.nav1State];
                var camera = { x: 0, y: 0, z: 0 };
                var target = { x: 0, y: 0, z: 0 };
                if (greatePosition) {
                    camera = greatePosition.camera;
                    target = greatePosition.target;
                }
                WT3DObj.commonFunc.changeCameraPosition(camera, target, 1000, function () { });
            } else {
                console.log("資料初始化例外!沒有設定最佳位置");
                return;
            }
            break;
        //影片
        case "s07_06":
        case "s07_05":
            {
                //param.action(function () {
                //    system07.stepName = null;
                //});
            }
            break;
    }

 

 1.6、火災自動報警系統

1.6.1、地上部分排煙影片演練 部分錄屏

 

 1.6.2、地下部分自動報警影片演練 部分錄屏

 部分代碼如下:

  function move(id) {
        var dv = document.getElementById(id);
        var x = 0;
        var y = 0;
        var l = 0;
        var t = 0;
        var isDown = false;
        //滑鼠按下事件
        dv.onmousedown = function (e) {
            //獲取x坐標和y坐標
            x = e.clientX;
            y = e.clientY;

            //獲取左部和頂部的偏移量
            l = dv.offsetLeft;
            t = dv.offsetTop;
            //開關打開
            isDown = true;
            //設定樣式  
            dv.style.cursor = 'move';
        }
        //滑鼠移動
        window.onmousemove = function (e) {
            if (isDown == false) {
                return;
            }
            //獲取x和y
            var nx = e.clientX;
            var ny = e.clientY;
            //計算移動后的左偏移量和頂部的偏移量
            var nl = nx - (x - l);
            var nt = ny - (y - t);

            dv.style.left = nl + 'px';
            dv.style.top = nt + 'px';
            layer.closeAll();
        }
        //滑鼠抬起事件
        dv.onmouseup = function () {
            //開關關閉
            isDown = false;
            dv.style.cursor = 'default';
        }
    }
    move("ccAnimationgif");

 

二、實作邏輯

 2.1、模型創建

  模型創建講究的是充分理解業務需求,以及把控性能跟網路的資源情況,采用代碼模型與載入模型靈活配合,

  代碼模型,更好的節約了帶寬與記憶體資源,提升了用戶體驗,載入模型,降低了開發門檻,提升了效率,但其沒有代碼模型靈活可控

  各自案例如下:

  代碼模型:

[{"show":true,"uuid":"","name":"cube2_6","objType":"cube2","length":200,"width":200,"height":200,"x":0,"y":200,"z":0,"style":{"skinColor":16777215,"skin":{"skin_up":{"skinColor":16777215,"imgurl":"../../img/3dImg/rack_inside.jpg","materialType":"basic","side":1,"opacity":1},"skin_down":{"skinColor":16777215},"skin_fore":{"skinColor":16777215},"skin_behind":{"skinColor":16777215},"skin_left":{"skinColor":16777215},"skin_right":{"skinColor":16777215}}},"showSortNub":6}]
View Code

  載入模型:

{"name":"twaver_idc_jiazi_7","objType":"objmodel","position":{"x":0,"y":0,"z":0},"scale":{"x":1,"y":1,"z":1},"visible":true,"rotation":[{"direction":"x","degree":0}],"filePath":"../../js/msj3D/sourse/models/jiazi/","mtlFileName":"jiazi.mtl","objFileName":"jiazi.obj","mtlIsPublic":false,"showSortNub":7}
View Code

 

2.2、場景創建  

  場景搭建通過把各個模型組合而成業務所需要的場景

  搭建場景時需要考慮業務的邏輯關系,什么時候要用,什么時候需要釋放,哪些模型屬于一個場景,哪些模型屬于邏輯打開的場景

  例如在邏輯控制中,如何有效的隱藏顯示模型:

//隱藏所有設備
ModelBussiness.prototype.hideAllDevModels = function (timelong, callBackFunc) {
    var _this = this;
    var devModels = _this.getAllDevModels();
    if (devModels && devModels.length > 0) {
        WT3DObj.commonFunc.changeObjsOpacity(devModels, 1, 0.01, timelong ? timelong : 1000, function () {
            $.each(devModels, function (_index, _obj) {
                _obj.visible = false;
            });
            WT3DObj.commonFunc.changeObjsOpacity(devModels, 0.9, 1, 1, function () {
                if (callBackFunc) {
                    callBackFunc();
                }
            });
        });
    }
}
ModelBussiness.prototype.showAllDevModels = function (timelong, callBackFunc) {
    var _this = this;
    var devModels = _this.getAllDevModels();
    if (devModels && devModels.length > 0) {
        $.each(devModels, function (_index, _obj) {
            _obj.visible = true;
        });
        WT3DObj.commonFunc.changeObjsOpacity(devModels, 0.5,1, timelong ? timelong : 1000, function () {
            if (callBackFunc) {
                callBackFunc();
            }
        });
    }
}

 

2.3、場景切換

  場景切換,除了在場景內部通過事件切換的方式,還有就是大場景切換

  對于大場景切換,通常采用兩種方式,一種時改變路由的方式,一種是釋放當前資源,加載新資源

  這里我們采用物件化加載的方式

  初始化物件:

$(function () {
indexPage = new IndexPage();
indexPage.init();
for (var i = 1; i <= 6; i++) {
if (window["System0" + i]) {
window["system0" + i] = new window["System0" + i]();
window["system0" + i].init();
}
}
});
//系統1:室內外消防給水系統
function System01() {
}
//初始化
System01.prototype.init = function () {
    
}
//顯示
System01.prototype.show = function () {
    console.log("顯示室內外消防給水系統");
    this.loadVoice();
    this.initUI();
    modelBussiness.loadDevModels(1, function () {
        modelBussiness.hideAllInsideBoxs();
    });
}
System01.prototype.initUI = function () {
    //主功能
    this.nav1 = [
        {
            defaultState: "",
            name: "全景視角",
            id: "s01_01",
            actionStr: "system01.showNavSystem('s01_01')"
        },
        {
            defaultState: "noselect",
            name: "剖面視角",
            id: "s01_02",
            actionStr: "system01.showNavSystem('s01_02')"
        },
        {
            defaultState: "noselect",
            name: "管網視角",
            id: "s01_03",
            actionStr: "system01.showNavSystem('s01_03')"
        },
        {
            defaultState: "noselect",
            name: "系統部件",
            id: "s01_04",
            actionStr: "system01.showNavSystem('s01_04')"

        }
    ]
    //子功能
    ....
    /*
    消防水泵
    消防供水管道
    */
    indexPage.showSystemMainNav1(this.nav1);
    this.nav1State = "s01_01";
    indexPage.showSystemMainNav2(this.nav2[0]);
    this.nav2State = "";

}

 

2.4、影片模擬

   影片模擬,這里采用了配置加載的方式,不用每一個影片去寫邏輯代碼,因為涉及到影片比較多,但影片都是基于時間線的,所以我們把需要執行的步驟放到配置里面,再通過統一的方法去呼叫

  例如影片串列配置如下:

  {
            name: "排煙影片",
            children: [
                
                {
                    name: "發生火情",
                    id: "s07_step01",
                    greatePosition: {
                        camera: { x: 6120.260855819656, y: 1344.6126089802272, z: 10903.874792293966 },
                        target: { x: 743.2076296596372, y: 901.5537889282617, z: -467.5814262976444 }
                    },
                    actionStr: "system07.showNav2Action(2,'s07_step01')",
                    action: function (callBack) {
                        //剖面圖
                        $.each(system07.allModels, function (_index, _obj) {
                            if (_obj.hasoldPosition) {
                                _obj.position.y = _obj.hasoldPosition.y ;
                            }
                            _obj.visible = true;
                        });
                        $.each(system07.foreModels, function (_index, _obj) {
                            if (_obj.hasoldPosition) {
                                _obj.position.y = _obj.hasoldPosition.y + 10000;
                            } else {
                                _obj.hasoldPosition = { y: _obj.position.y };
                                _obj.position.y = _obj.hasoldPosition.y + 10000;
                            }
                            _obj.visible = false;
                        });
                        //發生火情
                       //do something...
                    }
                },
                {

                    name: "感煙探測器",
                    id: "s07_step02_1",
                    greatePosition: {
                        camera: { x: -1388, y: -781, z: -309 },
                        target: { x: -2119, y: -1106, z: 873 }
                    },
                    actionStr: "system07.showNav2Action(2,'s07_step02_1')",
                    action: function (callBack) {
                //do something...
                    }
                },
                {

                    name: "煙感信號發送",
                    id: "s07_step02_2",
                    greatePosition: {
                        camera: { x: -1388, y: -781, z: -309 },
                        target: { x: -2119, y: -1106, z: 873 }
                    },
                    actionStr: "system07.showNav2Action(2,'s07_step02_2')",
                    action: function (callBack) {
                       //do something...
                         
                    }
                },
              ....
                {
                    name: "影片結束",
                    id: "s07_step11",
                    greatePosition: {
                        camera: { x: 1737.3999068753242, y: 2415.4782632988126, z: -333.6159257900231 },
                        target: { x: 1239.420815260611, y: 1011.0884298164777, z: 2597.9725494779173 }
                    },
                    actionStr: "system07.showNav2Action(2,'s07_step11')",
                    action: function (callBack) {
                        
                        
                        //洗掉船船

                        //洗掉所有ani開頭的模型

                        //停止旋轉

                        //縮小擋煙垂壁

                    }
                }
            ]
        },

執行影片如下:

 

//執行影片
System07.prototype.doAnimation = function (index) {
    var _this = this;
    this.doAnimationFlag = true;
    var actions = system07.nav2[index].children;
    if (actions && actions.length > 0) {
        function doaction(action_nub) {
            $("#" + actions[action_nub].id).attr("class", "nav2res navsys");
            if (action_nub > 0) {
                $("#" + actions[action_nub - 1].id).attr("class", "nav2res navsys noseleced");
            }
            actions[action_nub].action(function () {
                if (actions[action_nub + 1] && actions[action_nub + 1].action) {
                    doaction(action_nub + 1);
                } else {
                    _this.doAnimationFlag = false;
                }
            });
        }
        doaction(0);
    }
}

 

 

 

由于篇幅原因,我們本節課先到這里,

 

下節課主要介紹3D實作配電站、變電所

 

 

 

技術交流 [email protected]

 

交流微信:

 

    

 

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

 

 

 

其它相關文章:

 

webgl(three.js)3D光伏,3D太陽能能源,3D智慧光伏、光伏發電、清潔能源三維可視化解決方案——第十六課

 

如何用webgl(three.js)搭建一個3D庫房,3D倉庫3D碼頭,3D集裝箱,車輛定位,叉車定位可視化孿生系統——第十五課

 

webgl(three.js)實作室內三維定位,3D定位,3D樓宇bim、實時定位三維可視化解決方案——第十四課(定位升級版)

 

使用three.js(webgl)搭建智慧樓宇、設備檢測、數字孿生——第十三課

 

如何用three.js(webgl)搭建3D糧倉、3D倉庫、3D物聯網設備監控-第十二課

 

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

 

如何用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機房管線問題(機房升級版)-第九課(一)

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/546570.html

標籤:JavaScript

上一篇:前端設計模式——策略模式

下一篇:第128篇:瀏覽器存盤(cookie、webStorage、 IndexedDB)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more