首页 > 其他分享 >如何使用webgl(three.js)实现3D消防、3D建筑消防大楼、消防数字孪生、消防可视化解决方案——第十八课(一)

如何使用webgl(three.js)实现3D消防、3D建筑消防大楼、消防数字孪生、消防可视化解决方案——第十八课(一)

时间:2023-03-11 16:56:02浏览次数:60  
标签:function obj 消防 webgl action 2000 var 3D

序:

  又是很久没出随笔文章了,一篇文章有时候整理一天,实在是抽不出来时间。

  最近在回顾几年前的项目时,发现这个智慧三维消防可视化项目很有回顾价值,索性就拿出来讲讲。

  首先,我们要知道消防里的知识,不是简简单单的几个灭火器,烟感报警器这么简单的,消防是自有一套完整体系的,光是消防相关的产业年产值就有几千个亿。而我们普通非专业人士常见的消防设备只是消防产业中的皮毛。

  单是消防系统就可以分为很多类,常见的有消防给水系统、消火栓系统、自动喷水灭火系统、气体灭火系统、防烟排烟系统、火灾自动报警系统等等。这些系统内部的组成结构又各有不同。每个系统里就有几十个甚至上百个不同的消防设备。比如我们常见的消防喷头就有好几种,各自用于不同的建筑场景。

  还是闲话少序,切入正题。

前言:

  前面的课程里,有一篇文章《使用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 + '"  class="boxbg ' + _obj.defaultState + '" onclick="if(indexPage.clickme){return false;};indexPage.clickme=true;setTimeout(function(){indexPage.clickme=false},500);' + _obj.actionStr + ';">\
               <img src= "../img/' + (_obj.defaultState == "noselect" ? "dot_unselect.png" : "dot_selected.png") + '" class="s1icontime" />\
                   <p class="timeP">' + _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机房管线问题(机房升级版)-第九课(一)

 

标签:function,obj,消防,webgl,action,2000,var,3D
From: https://www.cnblogs.com/yeyunfei/p/17205445.html

相关文章

  • 搭建良好编写体验的webgl编程环境 vscode+vit
    因为webgl代码是以字符串的形式嵌入在javascript代码中,这对于我们编写webgl代码的体验不友好,本文介绍如何搭建友好webgl编程环境:需要安装的vscode插件WebGLGLSLEdito......
  • 利用ai生成深度图后实现图片跟随鼠标实现3D效果
    实现原理利用three.js根据深度图来控制不同深度位置像素位移距离不同,营造3D效果。 前期准备深度图生成网站 LeiaPixConverter注册登录完成后第一步点击upload上传......
  • webgl 系列 —— 变换矩阵和动画
    其他章节请看:webgl系列变换矩阵和动画动画就是不停地将某个东西变换(transform)。例如将三角形不停地旋转就是一个动画和CSStransform类似,变换有三种形式:平移、缩......
  • 2023 最新 WebGL 快速入门教程 All In One
    2023最新WebGL快速入门教程AllInOneOpenGLES:OpenGLforWebhttps://www.khronos.org/webgl/WebGL1.0SpecificationEditor'sDraftWedNov206:33:45......
  • 3Dmax和C4D有什么区别
    3Dmax和C4D有什么区别老杨爱说2022-11-2113:02吉林关注 3Dmax和C4D的区别有:  一、性质不同  1、3Dmax:3Dmax作为一个非常经典的三维软件,......
  • d3dcompiler_47.dll缺失怎么修复【缺失修复方法】
    d3dcompiler_47.dll文件是Windows系统重要的组件,电脑一出现缺失或者损坏的情况下,电脑很多游戏跟软件都无法打开运行。小编今天就把修复教程分享给大家;​首先是打开电脑浏览......
  • Block3Dv1.0发布!多年以后会开启多少人的编程之路?
    Block3Dv1.0发布!多年以后会开启多少人的编程之路?原创2023-02-1013:19·宅家呗自从2022年6月2日发布第一个测试版,已经过去了整整8个月。软件的开发过程很顺利,没有遇到特......
  • 日本国土交通部在Unity商店发布“全日本城市3D模型”,全部免费用!
    日本国土交通部在Unity商店发布“全日本城市3D模型”,全部免费用!投递人 itwriter 发布于 2023-03-0312:20 评论(0) 有2076人阅读 原文链接 [收藏] « »......
  • QT Linux下编译qwt3d
    原文链接 1、从下面网址下载bugfix版本的qwtplot3dhttps://sourceforge.net/p/qwtplot3d/code/HEAD/tree/branches/multiple_curves_0_2_x/  2、解压刚刚下载的......
  • #创作者激励#OpenHarmony 3D显示支持
    【本文正在参加2023年第一期优质创作者激励计划】前言OpenHarmony系统是一个非常先进,现代化设计理念的新系统其系统架构图如下:一.图形子系统架构图图形子系统是最复杂......