首页 文章 精选 留言 我的

精选列表

搜索[腾讯混元生3D],共10000篇文章
优秀的个人博客,低调大师

基于WebGL架构的3D可视化平台—三维设备管理(ThingJS实现楼宇设备管理3D可视化)

国内高层建筑不断兴建,它的特点是高度高、层数多、体量大。面积可达几万平方米到几十万平方米。这些建筑都是一个个庞然大物,高高的耸立在地面上,这是它的外观,而随之带来的内部的建筑设备也是大量的。为了提高设备利用率,合理地使用能源,加强对建筑设备状态的监视等,自然地就提出了楼宇自动化控制系统。下面我们将用ThingJS平台来模拟一个设备管理系统。 第一步,利用CampusBuilder搭建模拟场景。CampusBuilder的模型库有各种各样的模型,使我们搭建出的场景更逼真。使用CampusBuilde创建层级,之后再给层级加外立面就出现了当前的效果。详情移步:CampusBuilder3D场景制作工具 先看结果:演示地址 第二步,创建Equipment类,这里创建。switchControl方法主要一个完成一个计时器的功能来模拟设备警报。 class Equipment extends THING.Thing { constructor(app, name, obj, url) { super(app); this.name = name; this.obj = obj; this.url = url; this.interval = null; this.localPosition = [Math.floor(Math.random() * 7), 2.9, Math.floor(Math.random() * 7)]; } createSelf() { app.create({ type: 'Equipment', name: this.name, url: this.url, parent: this.obj, localPosition: this.localPosition, angle: 0 }); } switchControl(ev) { var flag; var equipment = app.query(this.name)[0]; app.level.change(equipment); if (ev) { this.interval = setInterval(function () { if (flag) { equipment.style.color = '#FF0000'; flag = false; } else { flag = true; equipment.style.color = ''; } }, 500); console.log(this.interval + "查看是否创建了定时器"); } else { console.log(this.interval); clearInterval(this.interval); if (equipment.style.color == '#FF0000') equipment.style.color = ''; } } } THING.factory.registerClass('Equipment', Equipment); 第三步,创建摄像机面板,烟感报警面板以及控制设备的开关,这里简单调整一下面板位置之后会增加两个创建设备的按钮。 //创建主面板 var panel1 = new THING.widget.Panel({ titleText: '摄像机列表', closeIcon: false, // 是否有关闭按钮 dragable: true, retractable: true, opacity: 0.9, hasTitle: true, }); panel1.position = [80, 0]; var panel2 = new THING.widget.Panel({ titleText: '烟感报警列表', closeIcon: false, // 是否有关闭按钮 dragable: true, retractable: true, opacity: 0.9, hasTitle: true, }); panel2.position = [80, 320]; // 创建任意对象 var dataObj1 = { open1: false, open2: false, open3: false, open4: false, } var dataObj2 = { open5: false, open6: false, open7: false, open8: false, }; // 动态绑定物体 var open1 = panel1.addBoolean(dataObj1, 'open1').caption('设备01'); var open2 = panel1.addBoolean(dataObj1, 'open2').caption('设备02'); var open3 = panel1.addBoolean(dataObj1, 'open3').caption('设备03'); var open4 = panel1.addBoolean(dataObj1, 'open4').caption('设备04'); var open5 = panel2.addBoolean(dataObj2, 'open5').caption('设备01'); var open6 = panel2.addBoolean(dataObj2, 'open6').caption('设备02'); var open7 = panel2.addBoolean(dataObj2, 'open7').caption('设备03'); var open8 = panel2.addBoolean(dataObj2, 'open8').caption('设备04'); 第四步,开启场景层级切换,创建摄像机和烟感报警器各四个,创建一个数字标识index和保存equipment对象的数组equipmentGroup。 //创建equipment对象数组,以及数组标识 var equipmentGroup = []; var index = 0; app.on('load', function (ev) { app.level.change(ev.campus); for (var i = 0; i < 8; i++) { var type = null; if (i < 4) { type = 'http://model.3dmomoda.cn/models/62A8A75C75044E6AB3D8463FA0CB67AF/0/gltf/'; } else { type = 'http://model.3dmomoda.cn/models/641A9B800DE5431E8C84DC290F8EFDE6/0/gltf/'; } var equipment = new Equipment(app, 'equipment' + index++, app.query('floor' + (Math.floor(Math.random() * 5) + 1))[0], type); equipment.createSelf(); equipmentGroup.push(equipment); } }); 第五步,为每个设备对应的创建控制开关。 open1.on('change', function (ev) { equipmentGroup[0].switchControl(ev); }); open2.on('change', function (ev) { equipmentGroup[1].switchControl(ev); }); open3.on('change', function (ev) { equipmentGroup[2].switchControl(ev); }); open4.on('change', function (ev) { equipmentGroup[3].switchControl(ev); }); open5.on('change', function (ev) { equipmentGroup[4].switchControl(ev); }); open6.on('change', function (ev) { equipmentGroup[5].switchControl(ev); }); open7.on('change', function (ev) { equipmentGroup[6].switchControl(ev); }); open8.on('change', function (ev) { equipmentGroup[7].switchControl(ev); }); 最后一步,创建两个按钮来控制创建设备。 new THING.widget.Button('创建烟感报警', function () { var type = 'http://model.3dmomoda.cn/models/641A9B800DE5431E8C84DC290F8EFDE6/0/gltf/'; var equipment = new Equipment(app, 'equipment' + index++, app.query('floor' + (Math.floor(Math.random() * 5) + 1))[0], type,); equipment.createSelf(); equipmentGroup.push(equipment); app.level.change(app.query(equipment.name)[0]); }); new THING.widget.Button('创建摄像头', function () { var type = 'http://model.3dmomoda.cn/models/62A8A75C75044E6AB3D8463FA0CB67AF/0/gltf/'; var equipment = new Equipment(app, 'equipment' + index++, app.query('floor' + (Math.floor(Math.random() * 5) + 1))[0], type,); equipment.createSelf(); equipmentGroup.push(equipment); app.level.change(app.query(equipment.name)[0]); }); 在编写过程还是走了不少弯路的,最主要的就是计时器的卸载问题,最初的版本写来写去发现不能控制警报的关闭,后来才 发现计时器没有卸载,警报不但不会关闭而且闪动的频率越来越快。更改之后创建了Equipment这个类来控制所有设备,通过创建这个类的对象给他赋id,父物体,模型地址。这里控制器在开关被触发的时候创建一个新的计时器并赋给的这个对象,再次触发时清除这个计时器,警报的动画就关闭了。演示地址 最后附上完整代码: /** * 说明:创建App,url为场景地址(可选) */ var app = new THING.App({ url: "http://www.thingjs.com/./uploads/wechat/oLX7p05lsWJZUIxnIWsNXAzJ40X8/scene/CampusBuilder20181126134710", // 场景地址 "skyBox": "BlueSky" }); //创建主面板 var panel1 = new THING.widget.Panel({ titleText: '设备列表', closeIcon: false, // 是否有关闭按钮 dragable: true, retractable: true, opacity: 0.9, hasTitle: true, titleImage: 'https://www.thingjs.com/static/images/example/icon.png' }); panel1.position = [80, 0]; var panel2 = new THING.widget.Panel({ titleText: '设备列表', closeIcon: false, // 是否有关闭按钮 dragable: true, retractable: true, opacity: 0.9, hasTitle: true, titleImage: 'https://www.thingjs.com/static/images/example/icon.png' }); panel2.position = [80, 320]; // 创建任意对象 var dataObj1 = { open1: false, open2: false, open3: false, open4: false, } var dataObj2 = { open5: false, open6: false, open7: false, open8: false, }; // 动态绑定物体 var open1 = panel1.addBoolean(dataObj1, 'open1').caption('设备01'); var open2 = panel1.addBoolean(dataObj1, 'open2').caption('设备02'); var open3 = panel1.addBoolean(dataObj1, 'open3').caption('设备03'); var open4 = panel1.addBoolean(dataObj1, 'open4').caption('设备04'); var open5 = panel2.addBoolean(dataObj2, 'open5').caption('设备01'); var open6 = panel2.addBoolean(dataObj2, 'open6').caption('设备02'); var open7 = panel2.addBoolean(dataObj2, 'open7').caption('设备03'); var open8 = panel2.addBoolean(dataObj2, 'open8').caption('设备04'); new THING.widget.Button('创建烟感报警', function () { var type = 'http://model.3dmomoda.cn/models/641A9B800DE5431E8C84DC290F8EFDE6/0/gltf/'; var equipment = new Equipment(app, 'equipment' + index++, app.query('floor' + (Math.floor(Math.random() * 5) + 1))[0], type,); equipment.createSelf(); equipmentGroup.push(equipment); app.level.change(app.query(equipment.name)[0]); }); new THING.widget.Button('创建摄像头', function () { var type = 'http://model.3dmomoda.cn/models/62A8A75C75044E6AB3D8463FA0CB67AF/0/gltf/'; var equipment = new Equipment(app, 'equipment' + index++, app.query('floor' + (Math.floor(Math.random() * 5) + 1))[0], type,); equipment.createSelf(); equipmentGroup.push(equipment); app.level.change(app.query(equipment.name)[0]); }); //创建equipment对象数组,以及数组标识 var equipmentGroup = []; var index = 0; app.on('load', function (ev) { app.level.change(ev.campus); for (var i = 0; i < 8; i++) { var type = null; if (i < 4) { type = 'http://model.3dmomoda.cn/models/62A8A75C75044E6AB3D8463FA0CB67AF/0/gltf/'; } else { type = 'http://model.3dmomoda.cn/models/641A9B800DE5431E8C84DC290F8EFDE6/0/gltf/'; } var equipment = new Equipment(app, 'equipment' + index++, app.query('floor' + (Math.floor(Math.random() * 5) + 1))[0], type); equipment.createSelf(); equipmentGroup.push(equipment); } open1.on('change', function (ev) { equipmentGroup[0].switchControl(ev); }); open2.on('change', function (ev) { equipmentGroup[1].switchControl(ev); }); open3.on('change', function (ev) { equipmentGroup[2].switchControl(ev); }); open4.on('change', function (ev) { equipmentGroup[3].switchControl(ev); }); open5.on('change', function (ev) { equipmentGroup[4].switchControl(ev); }); open6.on('change', function (ev) { equipmentGroup[5].switchControl(ev); }); open7.on('change', function (ev) { equipmentGroup[6].switchControl(ev); }); open8.on('change', function (ev) { equipmentGroup[7].switchControl(ev); }); }); class Equipment extends THING.Thing { constructor(app, name, obj, url) { super(app); this.name = name; this.obj = obj; this.url = url; this.interval = null; } createSelf() { app.create({ type: 'Equipment', name: this.name, url: this.url, parent: this.obj, localPosition: [Math.floor(Math.random() * 7), 2.9, Math.floor(Math.random() * 7)], angle: 0 }); } switchControl(ev) { var flag; var equipment = app.query(this.name)[0]; app.level.change(equipment); if (ev) { this.interval = setInterval(function () { if (flag) { equipment.style.color = '#FF0000'; flag = false; } else { flag = true; equipment.style.color = ''; } }, 500); console.log(this.interval + "查看是否创建了定时器"); } else { console.log(this.interval); clearInterval(this.interval); if (equipment.style.color == '#FF0000') equipment.style.color = ''; } } } THING.factory.registerClass('Equipment', Equipment);

优秀的个人博客,低调大师

《腾讯iOS测试实践》一一导读

Foreword 前 言 为何编写本书随着移动互联网的兴起,移动终端的测试也进入火热的时代。两大主流操作系统Android和iOS占据了移动端的主要市场份额,其中iOS系统只能在苹果系列的移动终端使用,也就是说,在苹果系列的移动终端产品上,操作系统都是清一色的iOS系统,这就形成了硬件和系统同属于一家公司的独特现象。每年苹果公司发布新机型或者新操作系统时,都会引起全球果粉的疯狂。如此火热的平台,如何保证其App的质量就显得尤为重要。长久以来,市面上单独讲解iOS平台测试相关知识的书籍比较少见,对于做iOS测试的同行来说,可参考的国内资源十分匮乏,他们往往需要借助外文网站和博客上的片段资料进行学习和整合。随着iPhone和iPad等移动终端设备的兴起和流行,越来越多的开发者和测试人员投入到iOS平台软件的研发中,而中文参考资料的缺

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册