From 2bbf374e1c338d963eb529ebf23ac509838f8c1c Mon Sep 17 00:00:00 2001 From: gaozl Date: Mon, 22 May 2023 11:29:28 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=9C=B0=E5=9B=BE=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/static/qm/MainMap_QM.js | 1776 +++++++++++++++++++++----------- public/static/qm/three.js | 96 +- 2 files changed, 1241 insertions(+), 631 deletions(-) diff --git a/public/static/qm/MainMap_QM.js b/public/static/qm/MainMap_QM.js index 9709fbb..7fd9455 100644 --- a/public/static/qm/MainMap_QM.js +++ b/public/static/qm/MainMap_QM.js @@ -1,29 +1,31 @@ -var Map_QM, renderFrame = -1, pathCameraState, stats, isJUZ = false, dir=false, iot = false, shopTime, debug = false; //dir--自定义地图大小适应不同版本的地图大小 +var Map_QM, renderFrame = -1, pathCameraState, stats, stateTime, isJUZ = false, hasLine = false, dir = false, iot = false, shopTime, debug = false; //dir--自定义地图大小适应不同版本的地图大小 //basePath 基础路径 graphPath最佳路径 ftPath 扶梯路径 dtPath 电梯路径 -var typeObj = [{ ft: 0, type: 0, code: 'ft', name: '扶梯' }, { upft: 1, type: 1, code: 'upft', name: '上扶梯' }, { downft: 2, type: 2, code: 'downft', name: '下扶梯' }, { mys: 3, type: 3, code: 'mys', name: '母婴室' }, { xsj: 4, type: 4, code: 'xsj', name: '洗手间' }, { dt: 5, type: 5, code: 'dt', name: '直梯' }, { hxkj: 6, type: 6, code: 'hxkj', name: '焕醒空间' }, -{ fwt: 7, type: 7, code: 'fwt', name: '服务台' }, { tcc: 8, type: 8, code: 'tcc', name: '停车场' }, { hhkj: 9, type: 9, code: 'hhkj', name: '焕活空间' }, { cjr: 10, type: 10, code: 'cjr', name: '无障碍洗手间' }, { xys: 11, type: 11, code: 'xys', name: '吸烟室' }, { upft: 12, type: 12, code: 'upft', name: '上扶梯' }, -{ downft: 13, type: 13, code: 'downft', name: '下扶梯' }, { dkbc: 14, type: 14, code: 'dkbc', name: '代客泊车' }, { tczj: 15, type: 15, code: 'tczj', name: '童车租借' }, { ysc: 16, type: 16, code: 'ysc', name: '饮水处' }, { ztg: 17, type: 17, code: 'ztg', name: 'L1自提柜' }, { thg: 18, type: 18, code: 'thg', name: 'B1自提柜' }, -{ cwysd: 19, type: 19, code: 'cwysd', name: '宠物饮水点' }, { td: 20, type: 20, code: 'td', name: '人行通道' }, { dit: 21, type: 21, code: 'dit', name: '地铁' }, { czc: 22, type: 22, code: 'czc', name: '出租车' }, { atm: 23, type: 23, code: 'atm', name: 'ATM' }, -{ jcfw: 24, type: 24, code: 'jcfw', name: '寄存服务' }, { sjcd: 25, type: 25, code: 'sjcd', name: '手机充电' }, { bc: 26, type: 26, code: 'bc', name: '泊车' }, { cjc: 27, type: 27, code: 'cjc', name: '裁剪处' }, { jtn: 28, type: 28, code: 'jtn', name: '家庭洗手间(男)' }, { jtv: 29, type: 29, code: 'jtv', name: '家庭洗手间(女)' }, -{ ksgj: 30, type: 30, code: 'ksgj', name: '公交' }, { sjxsn: 31, type: 31, code: 'sjxsn', name: '无障碍洗手间男' }, { sjxsv: 32, type: 32, code: 'sjxsv', name: '无障碍洗手间女' }, { tcjf: 33, type: 33, code: 'tcjf', name: '停车缴费' }, { vip: 34, type: 34, code: 'vip', name: 'VIP' }, { xsjn: 35, type: 35, code: 'xsjn', name: '男洗手间' }, -{ xsjv: 36, type: 36, code: 'xsjv', name: '女洗手间' }, { yszj: 37, type: 37, code: 'yszj', name: '雨伞租借' }, { dyj: 38, type: 38, code: 'dyj', name: '打印机' }, { door: 39, type: 39, code: 'door', name: '出入口' }, { pq: 40, type: 40, code: 'pq', name: '喷泉' }, { d1k: 41, type: 41, code: 'd1k', name: '1号出入口' }, +var typeObj = [{ ft: 0, type: 0, code: 'ft', name: '扶梯' }, { upft: 1, type: 1, code: 'upft', name: '上扶梯' }, { downft: 2, type: 2, code: 'downft', name: '下扶梯' }, { mys: 3, type: 3, code: 'mys', name: '母婴室' }, { xsj: 4, type: 4, code: 'xsj', name: '洗手间' }, +{ dt: 5, type: 5, code: 'dt', name: '直梯' }, { hxkj: 6, type: 6, code: 'hxkj', name: '焕醒空间' }, { fwt: 7, type: 7, code: 'fwt', name: '服务台' }, { tcc: 8, type: 8, code: 'tcc', name: '停车场' }, { hhkj: 9, type: 9, code: 'hhkj', name: '焕活空间' }, +{ cjr: 10, type: 10, code: 'cjr', name: '无障碍洗手间' }, { xys: 11, type: 11, code: 'xys', name: '吸烟室' }, { upft: 12, type: 12, code: 'upft', name: '上扶梯' }, { downft: 13, type: 13, code: 'downft', name: '下扶梯' }, { dkbc: 14, type: 14, code: 'dkbc', name: '代客泊车' }, { tczj: 15, type: 15, code: 'tczj', name: '童车租借' }, +{ ysc: 16, type: 16, code: 'ysc', name: '饮水处' }, { ztg: 17, type: 17, code: 'ztg', name: 'L1自提柜' }, { thg: 18, type: 18, code: 'thg', name: 'B1自提柜' }, { cwysd: 19, type: 19, code: 'cwysd', name: '宠物饮水点' }, { td: 20, type: 20, code: 'td', name: '人行通道' }, { dit: 21, type: 21, code: 'dit', name: '地铁' }, +{ czc: 22, type: 22, code: 'czc', name: '出租车' }, { atm: 23, type: 23, code: 'atm', name: 'ATM' }, { jcfw: 24, type: 24, code: 'jcfw', name: '寄存服务' }, { sjcd: 25, type: 25, code: 'sjcd', name: '手机充电' }, { bc: 26, type: 26, code: 'bc', name: '泊车' }, +{ cjc: 27, type: 27, code: 'cjc', name: '裁剪处' }, { jtn: 28, type: 28, code: 'jtn', name: '家庭洗手间(男)' }, { jtv: 29, type: 29, code: 'jtv', name: '家庭洗手间(女)' }, { ksgj: 30, type: 30, code: 'ksgj', name: '公交' }, { sjxsn: 31, type: 31, code: 'sjxsn', name: '无障碍洗手间男' }, +{ sjxsv: 32, type: 32, code: 'sjxsv', name: '无障碍洗手间女' }, { tcjf: 33, type: 33, code: 'tcjf', name: '停车缴费' }, { vip: 34, type: 34, code: 'vip', name: 'VIP' }, { xsjn: 35, type: 35, code: 'xsjn', name: '男洗手间' }, { xsjv: 36, type: 36, code: 'xsjv', name: '女洗手间' }, +{ yszj: 37, type: 37, code: 'yszj', name: '雨伞租借' }, { dyj: 38, type: 38, code: 'dyj', name: '打印机' }, { door: 39, type: 39, code: 'door', name: '出入口' }, { pq: 40, type: 40, code: 'pq', name: '喷泉' }, { d1k: 41, type: 41, code: 'd1k', name: '1号出入口' }, { d2k: 42, type: 42, code: 'd2k', name: '2号出入口' }, { d3k: 43, type: 43, code: 'd3k', name: '3号出入口' }, { d4k: 44, type: 44, code: 'd4k', name: '4号出入口' }, { mjzyf: 45, type: 45, code: 'mjzyf', name: '门急诊药房' }, { cryc: 46, type: 46, code: 'cryc', name: '出入院处' }, { rggh: 47, type: 47, code: 'rggh', name: '人工挂号收费处' }, { zzyl: 48, type: 48, code: 'zzyl', name: '自动饮料贩卖机' }, { gxly: 49, type: 49, code: 'gxly', name: '共享轮椅' }, { ysp: 50, type: 50, code: 'ysp', name: '艺术品' }, { B1up: 51, type: 51, code: 'B1up', name: '' }, { B1down: 52, type: 52, code: 'B1down', name: '' }, { B2up: 53, type: 53, code: 'B2up', name: '' }, { B2down: 54, type: 54, code: 'B2down', name: '' }, { B3up: 55, type: 55, code: 'B3up', name: '' }, { B3down: 56, type: 56, code: 'B3down', name: '' }, { xcgc: 57, type: 57, code: 'xcgc', name: '下沉广场' }, { tthy: 58, type: 58, code: 'tthy', name: '天台花园' }, { ybck: 59, type: 59, code: 'ybck', name: '医保窗口' }, { zzfw: 60, type: 60, code: 'zzfw', name: '自助服务' }, { gjj: 61, type: 61, code: 'gjj', name: '工具间' }, { syt1: 62, type: 62, code: 'syt1', name: 'mall收银台' }, { gwc: 63, type: 63, code: 'gwc', name: '购物车' }, { ht: 64, type: 64, code: 'ht', name: '花坛' }, { jrc: 65, type: 65, code: 'jrc', name: '自助加热' }, { qbc: 66, type: 66, code: 'qbc', name: '自助取冰' }, { zxc: 67, type: 67, code: 'zxc', name: '自行车停放' }, -{ jws: 68, type: 68, code: 'jws', name: '警务室' }, { etxsj: 69, type: 69, code: 'etxsj', name: '儿童洗手间' }, { vip_xxq: 70, type: 70, code: 'vip_xxq', name: 'vip休息区' }, -{ ab: 71, type: 71, code: 'ab', name: '安保' }, { abjks: 72, type: 72, code: 'abjks', name: '安保监控室' }, { bys: 73, type: 73, code: 'bys', name: '播音室' }, { cpgys: 74, type: 74, code: 'cpgys', name: '裁判更衣室' }, { gzyld: 75, type: 75, code: 'gzyld', name: '观众医疗点' }, -{ hqgys: 76, type: 76, code: 'hqgys', name: '后勤更衣室' }, { jjs: 77, type: 77, code: 'jjs', name: '急救室' }, { jw: 78, type: 78, code: 'jw', name: '警卫' }, { ksj: 79, type: 79, code: 'ksj', name: '开水间' }, { kt: 80, type: 80, code: 'kt', name: '看台' }, { qzgysn: 81, type: 81, code: 'qzgysn', name: '亲自更衣(男)' }, -{ rsggys: 82, type: 82, code: 'rsggys', name: '热身馆更衣室' }, { swzl: 83, type: 83, code: 'swzl', name: '失物招领' }, { tsgbs1: 84, type: 84, code: 'tsgbs1', name: '特殊贵宾室1' }, { tsgbs2: 85, type: 85, code: 'tsgbs2', name: '特殊贵宾室2' }, { tsgbs3: 86, type: 86, code: 'tsgbs3', name: '特殊贵宾室3' }, { wxc: 87, type: 87, code: 'wxc', name: '闻讯处' }, +{ jws: 68, type: 68, code: 'jws', name: '警务室' }, { etxsj: 69, type: 69, code: 'etxsj', name: '儿童洗手间' }, { vip_xxq: 70, type: 70, code: 'vip_xxq', name: 'vip休息区' }, { ab: 71, type: 71, code: 'ab', name: '安保' }, { abjks: 72, type: 72, code: 'abjks', name: '安保监控室' }, +{ bys: 73, type: 73, code: 'bys', name: '播音室' }, { cpgys: 74, type: 74, code: 'cpgys', name: '裁判更衣室' }, { gzyld: 75, type: 75, code: 'gzyld', name: '观众医疗点' }, { hqgys: 76, type: 76, code: 'hqgys', name: '后勤更衣室' }, { jjs: 77, type: 77, code: 'jjs', name: '急救室' }, +{ jw: 78, type: 78, code: 'jw', name: '警卫' }, { ksj: 79, type: 79, code: 'ksj', name: '开水间' }, { kt: 80, type: 80, code: 'kt', name: '看台' }, { qzgysn: 81, type: 81, code: 'qzgysn', name: '亲自更衣(男)' }, { rsggys: 82, type: 82, code: 'rsggys', name: '热身馆更衣室' }, +{ swzl: 83, type: 83, code: 'swzl', name: '失物招领' }, { tsgbs1: 84, type: 84, code: 'tsgbs1', name: '特殊贵宾室1' }, { tsgbs2: 85, type: 85, code: 'tsgbs2', name: '特殊贵宾室2' }, { tsgbs3: 86, type: 86, code: 'tsgbs3', name: '特殊贵宾室3' }, { wxc: 87, type: 87, code: 'wxc', name: '闻讯处' }, { lt: 88, type: 88, code: 'lt', name: '楼梯' }, { yhs: 89, type: 89, code: 'yhs', name: '医护室' }, { yls: 90, type: 90, code: 'yls', name: '医疗室' }, { ylz: 91, type: 91, code: 'ylz', name: '医疗站' }, { ydygys: 92, type: 92, code: 'ydygys', name: '运动员更衣室' }, { ydygysn: 93, type: 93, code: 'ydygysn', name: '运动员男更衣室' }, { ydygysv: 94, type: 94, code: 'ydygysv', name: '运动员女更衣室' }, { zls: 95, type: 95, code: 'zls', name: '诊疗室' }, { zys: 96, type: 96, code: 'zys', name: '直饮水' }, { zas: 97, type: 97, code: 'zas', name: '治安室' }, { xxq: 98, type: 98, code: 'xxq', name: '休息区' }, { jtxsj: 99, type: 99, code: 'jtxsj', name: '家庭洗手间' }, { hzs: 100, type: 100, code: 'hzs', name: '化妆室' }, { brs: 101, type: 101, code: 'brs', name: '哺乳室' }, { mtl: 102, type: 102, code: 'mtl', name: '摩天轮' }, { dgnxsj: 103, type: 103, code: 'dgnxsj', name: '多功能洗手间' }, { wxbxsj: 104, type: 104, code: 'wxbxsj', name: '无性别洗手间' }, { sjzx: 105, type: 105, code: 'sjzx', name: '设计中心' }, { dxp: 106, type: 106, code: 'dxp', name: '导向牌' }, { gydh: 107, type: 107, code: 'gydh', name: '公用电话' }, { sgq: 108, type: 108, code: 'sgq', name: '石拱桥' }, { wxw: 109, type: 109, code: 'wxw', name: '无线网' }, { xmb: 110, type: 110, code: 'xmb', name: '小卖部' }, { zyzfwz: 111, type: 111, code: 'zyzfwz', name: '志愿者服务站' }, -{ ykzx: 112, type: 112, code: 'ykzx', name: '服务中心' }, { zjyy: 113, type: 113, code: 'zjyy', name: '专家预约处' }, { yjt: 114, type: 114, code: 'yjt', name: '预检台' }, -{ mzjd: 115, type: 115, code: 'mzjd', name: '门诊综合接待室' }, { hd: 116, type: 116, code: 'hd', name: '活动点' }, { bsl: 117, type: 117, code: 'bsl', name: '白石龙' }]; +{ ykzx: 112, type: 112, code: 'ykzx', name: '服务中心' }, { zjyy: 113, type: 113, code: 'zjyy', name: '专家预约处' }, { yjt: 114, type: 114, code: 'yjt', name: '预检台' }, { mzjd: 115, type: 115, code: 'mzjd', name: '门诊综合接待室' }, { hd: 116, type: 116, code: 'hd', name: '活动点' }, +{ bsl: 117, type: 117, code: 'bsl', name: '白石龙' }, { xzl: 118, type: 118, code: 'xzl', name: '写字楼' }, { axzj: 119, type: 119, code: 'axzj', name: '爱心租借' }, { cdz: 120, type: 120, code: 'cdz', name: '充电桩' }, { hjcq: 121, type: 121, code: 'hjcq', name: '黑金车区' }, +{ yjjj: 122, type: 122, code: 'yjjj', name: '宜家家居' }]; QMUtil = function () { this.shopServerInfo = "static/offline/JSON/QueryShopList.json"; @@ -31,13 +33,13 @@ QMUtil = function () { this.beforPath = "./"; this.options = { playSpeed: 6, //动画播放速度 - collision: true, //是否支持名称的碰撞检测 + collision: false, //是否支持名称的碰撞检测 showStyle: false, //是否4K modelIcon: true, //是否使用模型 true 模型 false 图标 otherPath: [], //人为干预的路线 [{f:"0_5_10",s:"1_5_47",d:500},{f:"1_5_47",s:"0_5_10",d:500}]; - bSpace: 5000, + bSpace: 3000, fSpace: 500, //双叠层状态下楼层的间距 - maxDis: 1000, + maxDis: 500, minDis: 60, shadow: true, //是否显示阴影 navColor: 0xEE6A50, //途径店铺颜色 @@ -45,7 +47,10 @@ QMUtil = function () { overlap: false, //是否叠层 iconName: false, //图标名称是否显示 mapScale: 18, //地图比例尺 - pathColor: 0xb47834, + pathColor: "#6e95fe", // + pathColor2: "#6e7dfe", //'rgb(110,125,254)' + pathBgColor: "#a9b5d3", //'rgb(169,181,211)' + pathBgColor2: "#bdc0cb", //'rgb(189, 192, 203)', pathStyle: "3D", shopStyle: "shopName", //设置box显示名称shopName或编号shopNum inArea: false, //点击后是否聚焦到店铺 @@ -55,11 +60,12 @@ QMUtil = function () { } this.lightOptions = { d_col: "#ffffff", - d_int: 0.2, + d_int: 0.1, s_col: "#fffffa", g_col: "#ffffff", - a_int: 0.85 + a_int: 0.5 }; + this.m_zoom = 1.2; this._clock = new THREE.Clock(); this._indexPathFloor = 0; // 遍历途径数据 this.changeDist = { inner: 350, outner: 900 }; //室内外切换的极限值, 如果 inner小于minDis 则不支持缩放切换 @@ -69,15 +75,15 @@ QMUtil = function () { this.pathStateObj = { isPathState: false, isPathPlay: true, basePath: "", graphPath: "", ftPath: "", dtPath: "", facAllArr: [], forShopArr: {}, elevator: null, straight: null, elevatorDown: null, seldtFacNo: "", seldownftFacNo: "", selupftFacNo: "" }; this.timeObj = { timeS: 0, collTime: -1, pathTime: -1 }; //debug 参数 相机坐标/ 镜头方向 - this.guiOptions = { cameraX: 0, cameraY: 220, cameraZ: 220, targatX: 0, targatY: 0, targatZ: 0 }; //this.button = function() {}; + this.guiOptions = { cameraX: 0, cameraY: 220, cameraZ: 220, targatX: 0, targatY: 0, targatZ: 0 }; //this.button = function() {}; - this.sceneGap = { x: 0, y: 0, z: 0, scale: dir ? 0.15 : 0.09 }; //改变地图位置,大小 + this.sceneGap = { x: 0, y: 0, z: 0, scale: dir ? 0.15 : 0.08 }; //改变地图位置,大小 this.selectBuild = 0; this.selectFloor = 0; this.deviceObj = {}; //angle --- 设备旋转角度 node ---- 设备导航点位 floor --- 设备楼层 this.startObj = {}; // 导航起点; - this.overObj = {}; //导航结束点 + this.overObj = {}; //导航结束点 this.tubeMaterial = new THREE.MeshPhongMaterial({ color: this.options.pathColor, transparent: true, opacity: 0.6 }); //叠层的路径材质 this.buildHeight = 5; this.shopHeight = 30; //店铺高度 控制店铺相关的其它第三方组件高度 @@ -87,45 +93,55 @@ QMUtil = function () { this.logos = []; /** * 外立面 - * Map_QM.util.initModelArr=[{url:"./static/model/jianfa.gltf",type:"out", scale:0.038, rot:{x:0,y:30,z:0}, site:{x:-20,y:-100,z:20}, colorModel:"gama" }]; + * Map_QM.util.initModelArr=[{url:"./static/model/jianfa.gltf",type:"out", scale:0.038, rot:{x:0,y:30,z:0}, site:{x:-20,y:-100,z:20}, colorModel:"gama" }]; */ - this.initModelArr = []; // + this.initModelArr = []; // /** * 一直显示不隐藏, 在楼层内显示 */ this.modelArr = []; this.modelStr = [ //种树 - { 'key': 'tree', 'url': 'static/img/model/tree.gltf', 'colorModel': 'line', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 1, 'y': 1, 'z': 1 } }, - { 'key': 'tree2', 'url': 'static/img/model/tree2.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'huatan1', 'url': 'static/img/model/huatan1.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'huatan2', 'url': 'static/img/model/huatan2.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'penquan2', 'url': 'static/img/model/penquan2.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'qiche1', 'url': 'static/img/model/qiche1.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'qiche2', 'url': 'static/img/model/qiche2.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'qiche3', 'url': 'static/img/model/qiche3.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'qiche4', 'url': 'static/img/model/qiche4.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'qiche5', 'url': 'static/img/model/qiche5.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'qiche6', 'url': 'static/img/model/qiche6.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'qiche7', 'url': 'static/img/model/qiche7.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'qiche8', 'url': 'static/img/model/qiche8.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'qiche9', 'url': 'static/img/model/qiche9.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - - { 'key': 'chongdianzhuang', 'url': 'static/img/model/chongdianzhuang.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'IDS_H', 'url': 'static/img/model/IDS_H.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'IDS_V', 'url': 'static/img/model/IDS_V.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'xiaofangshuan', 'url': 'static/img/model/xiaofangshuan.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'tingchechang', 'url': 'static/img/model/tingchechang.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'chechanglangan', 'url': 'static/img/model/chechanglangan.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'bangongyi', 'url': 'static/img/model/bangongyi.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'lvzhi', 'url': 'static/img/model/lvzhi.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'ren1', 'url': 'static/img/model/ren1.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'ren2', 'url': 'static/img/model/ren2.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'ren3', 'url': 'static/img/model/ren3.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'ren4', 'url': 'static/img/model/ren4.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'ren5', 'url': 'static/img/model/ren5.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'ren6', 'url': 'static/img/model/ren6.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'yizi1', 'url': 'static/img/model/yizi1.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, - { 'key': 'gjz1', 'url': 'static/img/model/gjz1.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } } + { 'key': 'tree', 'url': 'static/img/model/tree.gltf', 'colorModel': 'line', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 1, 'y': 1, 'z': 1 }, 'load':false}, + { 'key': 'tree2', 'url': 'static/img/model/tree2.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'huatan1', 'url': 'static/img/model/huatan1.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'huatan2', 'url': 'static/img/model/huatan2.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'penquan2', 'url': 'static/img/model/penquan2.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'qiche1', 'url': 'static/img/model/qiche1.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'qiche2', 'url': 'static/img/model/qiche2.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'qiche3', 'url': 'static/img/model/qiche3.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'qiche4', 'url': 'static/img/model/qiche4.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'qiche5', 'url': 'static/img/model/qiche5.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'qiche6', 'url': 'static/img/model/qiche6.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'qiche7', 'url': 'static/img/model/qiche7.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'qiche8', 'url': 'static/img/model/qiche8.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'qiche9', 'url': 'static/img/model/qiche9.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + + { 'key': 'jt_up', 'url': 'static/img/model/jt_up.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'jt_left', 'url': 'static/img/model/jt_left.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'jt_left_up', 'url': 'static/img/model/jt_left_up.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'jt_right', 'url': 'static/img/model/jt_right.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'jt_right_up', 'url': 'static/img/model/jt_right_up.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'jt_turn', 'url': 'static/img/model/jt_turn.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'ludeng', 'url': 'static/img/model/ludeng.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'taiyangsan', 'url': 'static/img/model/taiyangsan.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'honglvdeng', 'url': 'static/img/model/honglvdeng.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + + { 'key': 'chongdianzhuang', 'url': 'static/img/model/chongdianzhuang.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'IDS_H', 'url': 'static/img/model/IDS_H.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'IDS_V', 'url': 'static/img/model/IDS_V.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'xiaofangshuan', 'url': 'static/img/model/xiaofangshuan.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'tingchechang', 'url': 'static/img/model/tingchechang.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'chechanglangan', 'url': 'static/img/model/chechanglangan.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'bangongyi', 'url': 'static/img/model/bangongyi.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'lvzhi', 'url': 'static/img/model/lvzhi.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'ren1', 'url': 'static/img/model/ren1.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'ren2', 'url': 'static/img/model/ren2.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'ren3', 'url': 'static/img/model/ren3.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'ren4', 'url': 'static/img/model/ren4.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'ren5', 'url': 'static/img/model/ren5.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'ren6', 'url': 'static/img/model/ren6.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'yizi1', 'url': 'static/img/model/yizi1.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false}, + { 'key': 'gjz1', 'url': 'static/img/model/gjz1.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 }, 'load':false} ]; this.fbxModels = []; //精灵模型 /** @@ -135,7 +151,7 @@ QMUtil = function () { this.tipArr = []; //模型标签 periphery /** * 室内地图标签 - * Map_QM.util.labelIconArr([{floor:0,title:'', click:false, site:{x:0,y:1870,z:10},data:{type:"labelIcon",id:"1",show:"cn"}}]); + * Map_QM.util.labelIconArr([{floor:0,title:'', click:false, site:{x:0,y:1870,z:10},data:{type:"labelIcon",id:"1",show:"cn"}}]); */ this.labelIconArr = []; this.spriteMaterialArr = []; @@ -165,16 +181,16 @@ QMUtil = function () { * @api {方法} changePlaySpeed(speed) 改变导航速度 * @apiGroup 地图交互 * @apiDescription 改变导航播放速度 - * @apiVersion 2.0.0 - * + * @apiVersion 4.0.0 + * * @apiParam {int} speed 播放速度(默认 6) - * + * * @apiSampleRequest off - * + * * @apiParamExample 请求示例 - * + * * Map_QM.util.changePlaySpeed(6) - * + * */ this.changePlaySpeed = function (speed = 6) { Map_QM.util.options.playSpeed = speed; @@ -192,6 +208,21 @@ QMUtil = function () { this.leftPoint; //左侧平行线交点 this.rightPoint; //右侧平行线交点 } + /** + * 调整颜色更亮更暗 color 六位十六禁止颜色 range 正负数决定颜色更改 + */ + this.adjustColor = function (color, range) { + let newColor = '#'; + for (let i = 0; i < 3; i++) { + const hxStr = color.substr(i * 2 + 1, 2); + let val = parseInt(hxStr, 16); + val += range; + if (val < 0) val = 0; + else if (val > 255) val = 255; + newColor += val.toString(16).padStart(2, '0') + } + return newColor; + } /** * 检测点是否在多边形区域内 @@ -203,20 +234,20 @@ QMUtil = function () { for (let i = 0; i < nCount; i++) { let p1 = ptPolygon[i]; //当前节点 let p2 = ptPolygon[(i + 1) % nCount]; //下一个节点 - // 求解 y=p.y 与 p1p2 的交点 - if (p1.y == p2.y) // p1p2 与 y=p0.y平行 + // 求解 y=p.y 与 p1p2 的交点 + if (p1.y == p2.y) // p1p2 与 y=p0.y平行 continue; - if (p.y < Math.min(p1.y, p2.y)) // 交点在p1p2延长线上 + if (p.y < Math.min(p1.y, p2.y)) // 交点在p1p2延长线上 continue; - if (p.y >= Math.max(p1.y, p2.y)) // 交点在p1p2延长线上 + if (p.y >= Math.max(p1.y, p2.y)) // 交点在p1p2延长线上 continue; - // 从P发射一条水平射线 求交点的 X 坐标 ------原理: ((p2.y-p1.y)/(p2.x-p1.x))=((y-p1.y)/(x-p1.x)) + // 从P发射一条水平射线 求交点的 X 坐标 ------原理: ((p2.y-p1.y)/(p2.x-p1.x))=((y-p1.y)/(x-p1.x)) //直线k值相等 交点y=p.y let x = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x; if (x > p.x) - nCross++; // 只统计单边交点 + nCross++; // 只统计单边交点 } - // 单边交点为偶数,点在多边形之外 --- + // 单边交点为偶数,点在多边形之外 --- return (nCross % 2 == 1); } @@ -344,64 +375,14 @@ QMUtil = function () { } return false; } - //绘制3D线 传入起点(3D坐标)、终点(3D坐标)、控制点1、控制点2(如没有则绘制直线) - this.drawDashedLine = function (startPoint, endPoint, dash = 50, color = 0x2269dd, ctrlPoint1 = null, ctrlPoint2 = null) { //THREE.Vector3 - let gopObj = new THREE.Group(); - let curve; - if (!ctrlPoint1 && !ctrlPoint2) { //控制点为空 - ctrlPoint1 = new THREE.Vector3(startPoint.x + (endPoint.x - startPoint.x) / 4, startPoint.y + (endPoint.y - startPoint.y) / 4, startPoint.z + (endPoint.z - startPoint.z) / 4); - ctrlPoint2 = new THREE.Vector3(endPoint.x + (startPoint.x - endPoint.x) / 4, endPoint.y + (startPoint.y - endPoint.y) / 4, endPoint.z + (startPoint.z - endPoint.z) / 4); - } - curve = new THREE.CubicBezierCurve3(startPoint, ctrlPoint1, ctrlPoint2, endPoint); - let points = curve.getPoints(dash); - let array = []; - points.forEach(element => { - array.push(element.x, element.y, element.z); - }); - let geometry = new THREE.LineSegmentsGeometry(); - // 几何体传入顶点坐标 - geometry.setPositions(array); - // 自定义的材质 - let material = new THREE.LineMaterial({ - color: color, - linewidth: 4, - scale: 1, - dashSize: 1, - gapSize: 2, - }); - // 把渲染窗口尺寸分辨率传值给材质LineMaterial的resolution属性 - // resolution属性值会在着色器代码中参与计算 - material.resolution.set(window.innerWidth, window.innerHeight); - let mesh = new THREE.Mesh(geometry, material); - gopObj.add(mesh); - let jtArr = []; - if (Math.abs(endPoint.x - startPoint.x) > Math.abs(endPoint.y - startPoint.y)) { - jtArr.push(endPoint.x - 10, endPoint.y, endPoint.z + 10); - jtArr.push(endPoint.x, endPoint.y, endPoint.z); - jtArr.push(endPoint.x + 10, endPoint.y, endPoint.z + 10); - jtArr.push(endPoint.x, endPoint.y, endPoint.z); - jtArr.push(endPoint.x, endPoint.y, endPoint.z + 10); - } else { - jtArr.push(endPoint.x, endPoint.y - 10, endPoint.z + 10); - jtArr.push(endPoint.x, endPoint.y, endPoint.z); - jtArr.push(endPoint.x, endPoint.y + 10, endPoint.z + 10); - jtArr.push(endPoint.x, endPoint.y, endPoint.z); - jtArr.push(endPoint.x, endPoint.y, endPoint.z + 10); - } - let jtgeom = new THREE.LineGeometry(); - jtgeom.setPositions(jtArr); - let jtmesh = new THREE.Mesh(jtgeom, material); - gopObj.add(jtmesh); - gopObj.userData.type = "toLine"; - return gopObj; - } + /**碰撞检测 * 传入A中心点和A的宽、高 * B的中心点和B的宽、高 */ - this.isCollision = function (A, aW, aH, B, bW, bH) { + this.isCollision = function (A, B) { let noCol = false; - if (Math.abs(A.x - B.x) < (aW + bW) / 2 + 20 && Math.abs(A.y - B.y) < (aH + bH) / 2 + 10) { + if (Math.abs(A.x - B.x) < (A.width + B.width) / 2 + 25 && Math.abs(A.y - B.y) < (A.height + B.height) / 2 + 20) { noCol = true; } return noCol; @@ -442,7 +423,6 @@ QMUtil = function () { return areaArr; } - this.QM_Line_Father = function (sPoint, ePoint, ctrlPoint1, ctrlPoint2, isStrLine) { this.startPoint = sPoint; //起始点 this.endPoint = ePoint; //结束点 @@ -677,7 +657,7 @@ QMUtil = function () { this.getPointArr = function (s1, s3, s4, s2, sp = 0.01) { let pArr = []; let sz = [s1, s3, s4, s2]; - let p = Map_QM.util.P_BEZ(0, sz); + let p; for (let j = 0; j < 1; j += sp) { p = Map_QM.util.P_BEZ(j, sz); pArr.push(p); @@ -780,7 +760,6 @@ QMUtil = function () { //////////////////////////////////////////////////////////////////////////////////////////// this.getWallPoints = function (points, wallWidth) { if (points.length < 2) { - //console.log("getWallPoints", "points size is letter than 2"); return new Array(); } //构建线段列表 @@ -1103,6 +1082,43 @@ QMUtil = function () { } return (S4() + S4() + S4()); } + + // 文本3D + this.getTextCanvas = function (text) { + const canvas = document.createElement("canvas"); + const color = "#333333"; + const fontSize = 18; + const height = fontSize + 5; + const width = text.length * fontSize + 5; + canvas.height = height; + canvas.width = width; + const ctx = canvas.getContext("2d"); + ctx.fillStyle = color; + ctx.strokeStyle = "#ffffff"; + // font + ctx.font = `${fontSize}px Arial`; + ctx.textAlign = "start"; + ctx.textBaseline = "middle"; + ctx.fillText(text, 5, height / 2); + return { height, width, canvas }; + } + + this.getTextMesh = function (text, position) { + const c = this.getTextCanvas(text); + const texture = new THREE.CanvasTexture(c.canvas); + const spriteMaterial = new THREE.SpriteMaterial({ + map: texture, + depthTest: true, + transparent: true + }); + const sprite = new THREE.Sprite(spriteMaterial); + sprite.scale.set(c.width, c.height, 0); + sprite.renderOrder = 70; + sprite.userData = { name: text, x: position.x, y: position.y, width: c.width, height: c.height }; + sprite.position.set(position.x, position.y, position.z + c.height / 2); + return sprite; + } + } //////////////////////////////-------------------------------------------配置 UtilFun /** @@ -1131,7 +1147,8 @@ MainMap_QM = function (callBack, options) { this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, preserveDrawingBuffer: true }); // preserveDrawingBuffer 是否可以截图 //this.renderer.outputEncoding = THREE.sRGBEncoding; this.renderer.setSize(this.w, this.h); - this.renderer.setPixelRatio(window.devicePixelRatio); + let zoom = this.util.options.showStyle ? 1 : 2; + this.renderer.setPixelRatio(window.devicePixelRatio * zoom); this.renderer.shadowMap.enabled = true; // 阴影类型 this.renderer.shadowMap.type = THREE.PCFSoftShadowMap; @@ -1144,10 +1161,13 @@ MainMap_QM = function (callBack, options) { this.labelRenderer.domElement.style.top = 0; ele.appendChild(this.labelRenderer.domElement); - let hemiLight = new THREE.HemisphereLight(this.util.lightOptions.s_col, this.util.lightOptions.g_col, this.util.lightOptions.a_int); - hemiLight.name = "light"; - hemiLight.position.set(0, 1, 1); - this.scene.add(hemiLight); + let light = new THREE.AmbientLight(0xffffff, 0.4); + light.name = 'light'; + this.scene.add(light); + this.hemiLight = new THREE.HemisphereLight(this.util.lightOptions.s_col, this.util.lightOptions.g_col, this.util.lightOptions.a_int); + this.hemiLight.name = "light"; + this.hemiLight.position.set(0, 1, 1); + this.scene.add(this.hemiLight); this.shawLight = new THREE.DirectionalLight(this.util.lightOptions.d_col, this.util.lightOptions.d_int); this.shawLight.name = "light"; @@ -1176,17 +1196,20 @@ MainMap_QM = function (callBack, options) { //设置相机距离原点的最远距离 this.controls.maxDistance = this.util.options.maxDis; this.controls.minPolarAngle = 0; // 0是为了兼容2D模式 - this.controls.maxPolarAngle = Math.PI / 2 - 0.2; // radians + this.controls.maxPolarAngle = Math.PI / 2 - 0.2; // radians if (debug) { stats = new Stats(); stats.setMode(1); // 0: fps, 1: ms - stats.domElement.style.position = 'absolute'; //绝对坐标 - stats.domElement.style.left = '10px'; // (0,0)px,左上角 + stats.domElement.style.position = 'absolute'; //绝对坐标 + stats.domElement.style.left = '10px'; // (0,0)px,左上角 stats.domElement.style.top = '60px'; document.getElementById(options.containerId || "mapContainer").appendChild(stats.domElement); } + document.getElementById(options.containerId || "mapContainer").addEventListener("wheel", this.disPlayEvent, false); + document.getElementById(options.containerId || "mapContainer").addEventListener("touchmove", this.disPlayEvent, false); + document.getElementById(options.containerId || "mapContainer").addEventListener('click', this.onMouseClickBox, false); //地图点击 document.addEventListener('rezise', this.changeDocmentResize, false); //窗口变化 this.mapArr = []; @@ -1241,7 +1264,6 @@ MainMap_QM.prototype = { try { _space.util.allMap = JSON.parse(LZString.decompressFromBase64(res.data.mapData)); console.log("地图数据更新时间: " + res.data.updateTime); - _space.initOptions(options); } catch (e) { _space.backObj.code = 404; _space.backObj.msg = "地图数据JSON格式错误"; @@ -1271,19 +1293,10 @@ MainMap_QM.prototype = { _space.backObj.code = 500; _space.backObj.msg = "店铺数据解析失败"; } - _space.initOutModel(); + _space.initOptions(options); }, fail: () => { - try { - _space.initOutModel(); - } catch (e) { - _space.backObj.code = 404; - _space.backObj.msg = "地图数据解析失败"; - } - if (_space.backObj.code == 404) { - _space.callBackLoadOver(_space.backObj); - _space.callBackLoadOver = null; - } + _space.initOptions(options); } }); } else { @@ -1310,13 +1323,13 @@ MainMap_QM.prototype = { _space.util.allMap = JSON.parse(LZString.decompressFromBase64(options.mapData.mapData)) } console.log("地图数据更新时间: " + options.mapData.updateTime); - _space.initOptions(options); } catch (e) { console.log(e) backObj.code = 404 backObj.msg = '地图数据JSON格式错误' callBack(backObj) callBack = null + return; } _space.util.shopData = options.shopData; let backObj = { "code": 200, msg: "加载成功", "data": [] }; @@ -1326,13 +1339,7 @@ MainMap_QM.prototype = { backObj.code = 500; backObj.msg = "店铺数据错误"; } - try { - _space.initOutModel(); - } catch (e) { - console.log(e); - _space.callBackLoadOver({ "code": 404, "msg": "地图数据解析失败" }) - _space.callBackLoadOver = null; - } + _space.initOptions(options); } else { _space.util.readTextFile(_space.util.beforPath + _space.util.mapServerInfo, function (res) { try { @@ -1342,15 +1349,14 @@ MainMap_QM.prototype = { _space.util.allMap = JSON.parse(LZString.decompressFromBase64(res.data.mapData)); } console.log("地图数据更新时间: " + res.data.updateTime); - _space.initOptions(options); } catch (e) { console.log(e); _space.backObj.code = 404; _space.backObj.msg = "地图数据JSON格式错误"; _space.callBackLoadOver(_space.backObj); _space.callBackLoadOver = null; + return; } - _space.util.readTextFile(_space.util.beforPath + _space.util.shopServerInfo, function (res) { console.log(res) _space.util.shopData = res.data; @@ -1365,23 +1371,18 @@ MainMap_QM.prototype = { _space.callBackLoadOver(backObj) } }); - try { - _space.initOutModel(); - } catch (e) { - _space.callBackLoadOver({ "code": 404, "msg": "地图数据解析失败" }) - _space.callBackLoadOver = null; - } + _space.initOptions(options); }); } } if (debug) { var gui = new dat.GUI() - gui.add(this.util.guiOptions, "cameraX", -500, 500).step(1).listen(); - gui.add(this.util.guiOptions, "cameraY", -500, 500).step(1).listen(); - gui.add(this.util.guiOptions, "cameraZ", -500, 500).step(1).listen(); - gui.add(this.util.guiOptions, "targatX", -500, 500).step(1).listen(); - gui.add(this.util.guiOptions, "targatY", -500, 500).step(1).listen(); - gui.add(this.util.guiOptions, "targatZ", -500, 500).step(1).listen(); + gui.add(this.util.guiOptions, "cameraX", -800, 800).step(1).listen(); + gui.add(this.util.guiOptions, "cameraY", -800, 800).step(1).listen(); + gui.add(this.util.guiOptions, "cameraZ", -800, 800).step(1).listen(); + gui.add(this.util.guiOptions, "targatX", -800, 800).step(1).listen(); + gui.add(this.util.guiOptions, "targatY", -800, 800).step(1).listen(); + gui.add(this.util.guiOptions, "targatZ", -800, 800).step(1).listen(); //gui.add(options, 'button'); } }, @@ -1397,11 +1398,31 @@ MainMap_QM.prototype = { this.util.options.shopStyle = this.util.allMap[this.util.selectBuild].hasOwnProperty("shopStyle") ? this.util.allMap[this.util.selectBuild].shopStyle : "shopName"; this.util.options.modelIcon = this.util.allMap[this.util.selectBuild].hasOwnProperty("modelIcon") ? this.util.allMap[this.util.selectBuild].modelIcon : true; - this.util.lightOptions.d_col = this.util.allMap[this.util.selectBuild].d_col || 0xffffff; - this.util.lightOptions.d_int = this.util.allMap[this.util.selectBuild].d_int || 0.3; - this.util.lightOptions.s_col = this.util.allMap[this.util.selectBuild].s_col || 0xfffff0; - this.util.lightOptions.g_col = this.util.allMap[this.util.selectBuild].g_col || 0xffffff; - this.util.lightOptions.a_int = this.util.allMap[this.util.selectBuild].a_int || 0.6; + this.hemiLight.color = new THREE.Color(this.util.allMap[this.util.selectBuild].s_col || "#fffff0"); + this.hemiLight.groundColor = new THREE.Color(this.util.allMap[this.util.selectBuild].g_col || "#ffffff"); + this.hemiLight.intensity = this.util.allMap[this.util.selectBuild].a_int || 0.5; + this.shawLight.color = new THREE.Color(this.util.allMap[this.util.selectBuild].d_col || "#ffffff"); + this.shawLight.intensity = this.util.allMap[this.util.selectBuild].d_int || 0.1; + + if (this.util.allMap[this.util.selectBuild].c_site && this.util.allMap[this.util.selectBuild].c_site.split(",")) { + this.util.guiOptions.cameraX = parseInt(this.util.allMap[this.util.selectBuild].c_site.split(",")[0]) || this.util.guiOptions.cameraX; + this.util.guiOptions.cameraY = parseInt(this.util.allMap[this.util.selectBuild].c_site.split(",")[1]) || this.util.guiOptions.cameraY; + this.util.guiOptions.cameraZ = parseInt(this.util.allMap[this.util.selectBuild].c_site.split(",")[2]) || this.util.guiOptions.cameraZ; + this.controls.object.position.x = this.util.guiOptions.cameraX; + this.controls.object.position.y = this.util.guiOptions.cameraY; + this.controls.object.position.z = this.util.guiOptions.cameraZ; + } + if (this.util.allMap[this.util.selectBuild].m_site && this.util.allMap[this.util.selectBuild].m_site.split(",")) { + this.util.guiOptions.targatX = parseInt(this.util.allMap[this.util.selectBuild].m_site.split(",")[0]) || this.util.guiOptions.targatX; + this.util.guiOptions.targatY = parseInt(this.util.allMap[this.util.selectBuild].m_site.split(",")[1]) || this.util.guiOptions.targatY; + this.util.guiOptions.targatZ = parseInt(this.util.allMap[this.util.selectBuild].m_site.split(",")[2]) || this.util.guiOptions.targatZ; + this.controls.target.x = this.util.guiOptions.targatX; + this.controls.target.y = this.util.guiOptions.targatY; + this.controls.target.z = this.util.guiOptions.targatZ; + } + if (this.util.allMap[this.util.selectBuild].m_zoom) { + this.util.m_zoom = this.util.allMap[this.util.selectBuild].m_zoom; + } } let { playSpeed = 6, collision = true, showStyle = false, modelIcon = true, shopStyle = "shopName", shadow = true, otherPath = [], navColor = 0xEE6A50, iconUrl = [], overlap = false, iconName = false, camZoom = 3, inArea = false, pathColor = 0xb47834, pathStyle = "3D" } = options; this.util.options.playSpeed = playSpeed != 6 ? playSpeed : this.util.options.playSpeed; @@ -1432,7 +1453,26 @@ MainMap_QM.prototype = { } } } - + // + for(let k=0; k parseInt(this.util.deviceObj.node)) { this.util.deviceObj.xaxis = pathData.nodes[parseInt(this.util.deviceObj.node)].x; @@ -1660,32 +1699,32 @@ MainMap_QM.prototype = { let ftPathObj = JSON.parse(jcStr); let dtPathObj = JSON.parse(jcStr); try { - for (let j = 0; j < Map_QM.util.pathStateObj.facAllArr.length; j++) { - for (let k = 0; k < Map_QM.util.pathStateObj.facAllArr[j].length; k++) { - let facP = Map_QM.util.pathStateObj.facAllArr[j][k].buildOrder + "_" + Map_QM.util.pathStateObj.facAllArr[j][k].floorOrder + "_" + Map_QM.util.pathStateObj.facAllArr[j][k].navCode; - for (let h = 0; h < Map_QM.util.pathStateObj.facAllArr[j].length; h++) { - if (h != k && Map_QM.util.pathStateObj.facAllArr[j][k].buildOrder == Map_QM.util.pathStateObj.facAllArr[j][h].buildOrder) { - let nP = Map_QM.util.pathStateObj.facAllArr[j][h].buildOrder + "_" + Map_QM.util.pathStateObj.facAllArr[j][h].floorOrder + "_" + Map_QM.util.pathStateObj.facAllArr[j][h].navCode; - if (Map_QM.util.pathStateObj.facAllArr[j][h].facCode == "dt") { - ftPathObj[facP][nP] = 1000 + 3000 * Math.abs(parseInt(Map_QM.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(Map_QM.util.pathStateObj.facAllArr[j][k].floorOrder));; - if (Map_QM.util.pathStateObj.facAllArr[j][k].no == Map_QM.util.pathStateObj.seldtFacNo) { - graphPathObj[facP][nP] = 300 + 200 * Math.abs(parseInt(Map_QM.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(Map_QM.util.pathStateObj.facAllArr[j][k].floorOrder)); + for (let j = 0; j < this.util.pathStateObj.facAllArr.length; j++) { + for (let k = 0; k < this.util.pathStateObj.facAllArr[j].length; k++) { + let facP = this.util.pathStateObj.facAllArr[j][k].buildOrder + "_" + this.util.pathStateObj.facAllArr[j][k].floorOrder + "_" + this.util.pathStateObj.facAllArr[j][k].navCode; + for (let h = 0; h < this.util.pathStateObj.facAllArr[j].length; h++) { + if (h != k && this.util.pathStateObj.facAllArr[j][k].buildOrder == this.util.pathStateObj.facAllArr[j][h].buildOrder) { + let nP = this.util.pathStateObj.facAllArr[j][h].buildOrder + "_" + this.util.pathStateObj.facAllArr[j][h].floorOrder + "_" + this.util.pathStateObj.facAllArr[j][h].navCode; + if (this.util.pathStateObj.facAllArr[j][h].facCode == "dt") { + ftPathObj[facP][nP] = 1000 + 3000 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder));; + if (this.util.pathStateObj.facAllArr[j][k].no == this.util.pathStateObj.seldtFacNo) { + graphPathObj[facP][nP] = 300 + 200 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)); } else { - graphPathObj[facP][nP] = 800 + 200 * Math.abs(parseInt(Map_QM.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(Map_QM.util.pathStateObj.facAllArr[j][k].floorOrder)); + graphPathObj[facP][nP] = 800 + 200 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)); } - dtPathObj[facP][nP] = 1000 + 200 * Math.abs(parseInt(Map_QM.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(Map_QM.util.pathStateObj.facAllArr[j][k].floorOrder)); - } else if (Map_QM.util.pathStateObj.facAllArr[j][h].facCode == "td") { - graphPathObj[facP][nP] = 800 + 300 * Math.abs(parseInt(Map_QM.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(Map_QM.util.pathStateObj.facAllArr[j][k].floorOrder)); - ftPathObj[facP][nP] = 800 + 300 * Math.abs(parseInt(Map_QM.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(Map_QM.util.pathStateObj.facAllArr[j][k].floorOrder)); - dtPathObj[facP][nP] = 800 + 300 * Math.abs(parseInt(Map_QM.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(Map_QM.util.pathStateObj.facAllArr[j][k].floorOrder)); + dtPathObj[facP][nP] = 1000 + 200 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)); + } else if (this.util.pathStateObj.facAllArr[j][h].facCode == "td") { + graphPathObj[facP][nP] = 800 + 300 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)); + ftPathObj[facP][nP] = 800 + 300 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)); + dtPathObj[facP][nP] = 800 + 300 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)); } else { - dtPathObj[facP][nP] = 1000 + 3000 * Math.abs(parseInt(Map_QM.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(Map_QM.util.pathStateObj.facAllArr[j][k].floorOrder)); - if (Map_QM.util.pathStateObj.facAllArr[j][k].no == Map_QM.util.pathStateObj.selupftFacNo || Map_QM.util.pathStateObj.facAllArr[j][k].no == Map_QM.util.pathStateObj.seldownftFacNo) { - graphPathObj[facP][nP] = 300 + 200 * Math.abs(parseInt(Map_QM.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(Map_QM.util.pathStateObj.facAllArr[j][k].floorOrder)); + dtPathObj[facP][nP] = 1000 + 3000 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)); + if (this.util.pathStateObj.facAllArr[j][k].no == this.util.pathStateObj.selupftFacNo || this.util.pathStateObj.facAllArr[j][k].no == this.util.pathStateObj.seldownftFacNo) { + graphPathObj[facP][nP] = 300 + 200 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)); } else { - graphPathObj[facP][nP] = 800 + 200 * Math.abs(parseInt(Map_QM.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(Map_QM.util.pathStateObj.facAllArr[j][k].floorOrder)); + graphPathObj[facP][nP] = 800 + 200 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)); } - ftPathObj[facP][nP] = 1000 + 200 * Math.abs(parseInt(Map_QM.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(Map_QM.util.pathStateObj.facAllArr[j][k].floorOrder)); + ftPathObj[facP][nP] = 1000 + 200 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder)); } } } @@ -1695,9 +1734,9 @@ MainMap_QM.prototype = { console.log("交通设施点位问题: " + e); } - Map_QM.util.pathStateObj.graphPath = graphPathObj; - Map_QM.util.pathStateObj.ftPath = ftPathObj; - Map_QM.util.pathStateObj.dtPath = dtPathObj; + this.util.pathStateObj.graphPath = graphPathObj; + this.util.pathStateObj.ftPath = ftPathObj; + this.util.pathStateObj.dtPath = dtPathObj; var fIndex = 0, bIndex = 0; this.mapArr[bIndex] = []; intTimer = setInterval(() => { @@ -1710,7 +1749,7 @@ MainMap_QM.prototype = { floor.floorName = Map_QM.util.allMap[bIndex].buildArr[fIndex].name; floor.initDraw(); floor.allObj.position.set(bIndex * Map_QM.util.options.bSpace, 0, 0); - if(fIndex != parseInt(Map_QM.util.deviceObj.floor)){ + if (fIndex != parseInt(Map_QM.util.deviceObj.floor)) { floor.allObj.visible = false; } this.buildObj.add(floor.allObj); @@ -1719,15 +1758,15 @@ MainMap_QM.prototype = { if (fIndex >= Map_QM.util.allMap[bIndex].buildArr.length) { if (bIndex == Map_QM.util.allMap.length - 1) { clearInterval(intTimer); - this.controls.minPan = new THREE.Vector3(this.w / -10, 0, this.h / -10); - this.controls.maxPan = new THREE.Vector3(this.w / 10, 0, this.h / 10); + this.controls.minPan = new THREE.Vector3(this.w / -5, 0, this.h / -5); + this.controls.maxPan = new THREE.Vector3(this.w / 5, 0, this.h / 5); let pathData = Map_QM.util.allMap[parseInt(Map_QM.util.deviceObj.build)].buildArr[parseInt(Map_QM.util.deviceObj.floor)].mapData.path; if (Map_QM.util.deviceObj.xaxis) { Map_QM.mapArr[parseInt(Map_QM.util.deviceObj.build)][parseInt(Map_QM.util.deviceObj.floor)].setStartSite(Map_QM.util.deviceObj.xaxis, Map_QM.util.deviceObj.yaxis, parseInt(Map_QM.util.shopHeight)); } else { if (parseInt(Map_QM.util.deviceObj.node) != -1) { - pathData.nodes.sort(Map_QM.util.sortNode); + pathData && pathData.nodes.sort(Map_QM.util.sortNode); if (pathData && !Map_QM.util.deviceObj.xaxis && pathData.nodes.length > parseInt(Map_QM.util.deviceObj.node)) { Map_QM.util.deviceObj.xaxis = pathData.nodes[parseInt(Map_QM.util.deviceObj.node)].x; Map_QM.util.deviceObj.yaxis = pathData.nodes[parseInt(Map_QM.util.deviceObj.node)].y; @@ -1747,32 +1786,42 @@ MainMap_QM.prototype = { }, 50); }, initTreeModel: function () { - let url = Map_QM.util.beforPath + Map_QM.util.modelStr[this.index].url; - this.gltfLoad(url); + if(this.index < this.util.modelStr.length - 1 ){ + if(this.util.modelStr[this.index].load){ + this.gltfLoad(this.util.beforPath + this.util.modelStr[this.index].url); + }else{ + this.index++; + this.initTreeModel(); + } + }else{ + if (this.util.allMap && this.util.allMap.length > 0) { + this.loaderOver(); + } + } }, gltfLoad: function (url) { let sopce = this; new THREE.GLTFLoader().load(url, function (object) {//加载路径fbx文件 object.scene.traverse(function (child) { if (child.type === "Mesh") { - child.castShadow = Map_QM.util.options.shadow; - child.receiveShadow = Map_QM.util.options.shadow; + child.castShadow = sopce.util.options.shadow; + child.receiveShadow = sopce.util.options.shadow; if (child.material.map) { child.material.map.encoding = THREE.LinearEncoding; //贴图需要转换成 线性编码 } - if (Map_QM.util.modelStr[sopce.index].colorModel === 'gama') { + if (sopce.util.modelStr[sopce.index].colorModel === 'gama') { child.material.color.convertGammaToLinear(0.6); } } }); - object.scene.children[0].scale.set(Map_QM.util.modelStr[sopce.index].size.x, Map_QM.util.modelStr[sopce.index].size.y, Map_QM.util.modelStr[sopce.index].size.z); - Map_QM.util.fbxModels.push({ 'key': Map_QM.util.modelStr[sopce.index].key, 'obj': object.scene, 'operation': Map_QM.util.modelStr[sopce.index] }); - if (sopce.index < Map_QM.util.modelStr.length - 1) { + object.scene.children[0].scale.set(sopce.util.modelStr[sopce.index].size.x, sopce.util.modelStr[sopce.index].size.y, sopce.util.modelStr[sopce.index].size.z); + sopce.util.fbxModels.push({ 'key': sopce.util.modelStr[sopce.index].key, 'obj': object.scene, 'operation': sopce.util.modelStr[sopce.index] }); + if (sopce.index < sopce.util.modelStr.length - 1) { sopce.index++; sopce.initTreeModel(); } else { - if (Map_QM.util.allMap && Map_QM.util.allMap.length > 0) { - Map_QM.loaderOver(); + if (sopce.util.allMap && sopce.util.allMap.length > 0) { + sopce.loaderOver(); } } }); @@ -1810,20 +1859,39 @@ MainMap_QM.prototype = { }); }, initFloor: function () { - if (Map_QM.util.initModelArr && Map_QM.util.initModelArr.length > 0) { + if (this.util.initModelArr && this.util.initModelArr.length > 0) { this.buildObj.visible = false; } - Map_QM.changeBuild(Map_QM.util.deviceObj.build, Map_QM.util.deviceObj.floor); - Map_QM.controls.target.set(Map_QM.util.guiOptions.targatX, Map_QM.util.guiOptions.targatY, Map_QM.util.guiOptions.targatZ); + this.changeBuild(this.util.deviceObj.build, this.util.deviceObj.floor); + this.controls.target.set(this.util.guiOptions.targatX, this.util.guiOptions.targatY, this.util.guiOptions.targatZ); //初始化方向为第一人称方向 - let angle = Map_QM.util.options.deviceAng ? Map_QM.util.deviceObj.angle : 0; - Map_QM.rotationAngle(angle); - Map_QM.startRender(); + let angle = this.util.options.deviceAng ? this.util.deviceObj.angle : 0; + this.rotationAngle(angle); + if(this.util.guiOptions.cameraY == 220 && this.util.guiOptions.cameraZ == 220){ + let boundBox = new THREE.Box3(); + boundBox.setFromObject(this.sceneGap); + let wd = Math.max(boundBox.max.x-boundBox.min.x, boundBox.max.y-boundBox.min.y); + let cameraDis = Math.sqrt(this.util.guiOptions.cameraY*this.util.guiOptions.cameraY+this.util.guiOptions.cameraZ*this.util.guiOptions.cameraZ); + this.camera.fov = this.calcFov(cameraDis, wd, this.w / this.h); + this.camera.aspect = this.w / this.h; + this.camera.updateProjectionMatrix(); + } + this.startRender(); setTimeout(() => { Map_QM.controls.saveState(); Map_QM.controls.addEventListener('change', this.controlsChock, false); //控制器变化 + console.log("Number of Triangles :", Map_QM.renderer.info.render.triangles); }, 100) }, + calcFov:function (d, w, r) { + let f; + let vertical = w; + if (r < 1) { + vertical = vertical/r; + } + f = Math.atan(vertical/d/2)* 2 * (180 / Math.PI); + return f; + }, /** * 解析路径 */ @@ -1925,15 +1993,15 @@ MainMap_QM.prototype = { * @api {方法} changeMapState("3d") 地图状态切换 * @apiGroup 地图显示 * @apiDescription 地图展示状态切换 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiParam {string} state 地图状态 - * + * * @apiSampleRequest off - * + * * @apiParamExample {String} 请求示例 - * + * * Map_QM.changeMapState("2d"); - * + * */ changeMapState: function (state) { Map_QM.controls.reset(); @@ -1949,8 +2017,9 @@ MainMap_QM.prototype = { Map_QM.camera = Map_QM.cameraOrtho; Map_QM.controls.object = Map_QM.camera; Map_QM.shawLight.castShadow = false; - Map_QM.controls.setZoom(1.5); + Map_QM.controls.setZoom(Map_QM.util.m_zoom); Map_QM.camera.updateProjectionMatrix(); //必须update + Map_QM.camera.position.set(Map_QM.util.guiOptions.cameraX, Map_QM.util.guiOptions.cameraY, Map_QM.util.guiOptions.cameraZ); Map_QM.controls.maxPolarAngle = 0; Map_QM.changeIconState(state); } @@ -1983,16 +2052,16 @@ MainMap_QM.prototype = { * @api {方法} changeBuild(buildOrder,floorOrder) 楼栋切换 * @apiGroup 地图交互 * @apiDescription 楼栋切换 传入楼栋编号,楼层编号 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiParam {int} buildOrder 传入楼栋编号(默认 0) * @apiParam {int} floorOrder 传入楼栋编号(默认 0) - * + * * @apiSampleRequest off - * + * * @apiParamExample {int, int} 请求示例 - * + * * Map_QM.changeBuild(0, 0); - * + * */ changeBuild: function (buildOrder = 0, floorOrder = 0) { Map_QM.resetFloorState(); @@ -2012,6 +2081,7 @@ MainMap_QM.prototype = { }); }, resetFloorState: function () { + TweenMax.killAll(true); Map_QM.util.pathStateObj.isPathState = false; Map_QM.controls.maxDistance = Map_QM.util.options.maxDis; clearTimeout(Map_QM.util.timeObj.collTime); @@ -2027,19 +2097,19 @@ MainMap_QM.prototype = { } }, /** - * @api {方法} showFloor(floorOrder) 通过楼层编号切换楼层 + * @api {方法} showFloor(floorOrder) 通过楼层编号切换楼层 * @apiGroup 地图交互 * @apiDescription 楼层切换,传入楼层编号,编号从下到上排序,最下面是0 - * @apiVersion 2.0.0 - * + * @apiVersion 4.0.0 + * * @apiParam {int} floorOrder 楼层编号 - * + * * @apiSampleRequest off - * + * * @apiParamExample {int} 请求示例 - * + * * Map_QM.showFloor(1); - * + * */ showFloor: function (fIndex = -1, callBack = undefined) { Map_QM.resetFloorState(); @@ -2049,16 +2119,16 @@ MainMap_QM.prototype = { } }, /** - * @api {方法} changeFloorByName(floorOrder) 通过楼层名称切换楼层 + * @api {方法} changeFloorByName(floorOrder) 通过楼层名称切换楼层 * @apiGroup 地图交互 * @apiDescription 楼层切换,传入楼层名称, - * @apiVersion 2.0.0 - * + * @apiVersion 4.0.0 + * * @apiParam {String} floorName 楼层名称 - * + * * @apiSampleRequest off * @apiParamExample {String} 请求示例 - * + * * Map_QM.changeFloorByName("L1"); */ changeFloorByName: function (floorName) { @@ -2147,7 +2217,7 @@ MainMap_QM.prototype = { Map_QM.util.selectBuild = build; Map_QM.util.selectFloor = fIndex; if (Map_QM.util.options.shadow) { - TweenMax.fromTo(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.position, 0.3, { z: Map_QM.util.options.fSpace}, { + TweenMax.fromTo(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.position, 0.3, { z: Map_QM.util.options.fSpace }, { z: 0, ease: Cubic.easeIn, onComplete: function () { Map_QM.timeOutInit(); if (callBack) callBack(); @@ -2155,7 +2225,7 @@ MainMap_QM.prototype = { }); } else { Map_QM.timeOutInit() - if (callBack) callBack() + if (callBack) callBack() } } } @@ -2165,15 +2235,15 @@ MainMap_QM.prototype = { /** * @api {方法} onShowMeDir() 我的方向 * @apiGroup 地图显示 - * @apiDescription 我的方向 - * @apiVersion 2.0.0 - * + * @apiDescription 我的方向 + * @apiVersion 4.0.0 + * * @apiSampleRequest off - * + * * @apiParamExample 请求示例 - * + * * Map_QM.onShowMeDir(); - * + * */ onShowMeDir: function () { if (this.util.selectBuild != this.util.deviceObj.build || this.util.selectFloor != this.util.deviceObj.floor) { @@ -2189,10 +2259,10 @@ MainMap_QM.prototype = { this.dirIcon.visible = false; } if (Map_QM.util.deviceObj.xaxis) { - Map_QM.controls.object.position.set(Map_QM.util.deviceObj.xaxis * Map_QM.util.sceneGap.scale, Map_QM.util.sceneGap.y+100, Map_QM.util.deviceObj.yaxis * Map_QM.util.sceneGap.scale) + Map_QM.controls.object.position.set(Map_QM.util.deviceObj.xaxis * Map_QM.util.sceneGap.scale, Map_QM.util.sceneGap.y + 100, Map_QM.util.deviceObj.yaxis * Map_QM.util.sceneGap.scale) Map_QM.controls.target = new THREE.Vector3(Map_QM.util.deviceObj.xaxis * Map_QM.util.sceneGap.scale, 0, Map_QM.util.deviceObj.yaxis * Map_QM.util.sceneGap.scale) } else { - Map_QM.controls.object.position.set(0, Map_QM.util.sceneGap.y+100, 0) + Map_QM.controls.object.position.set(0, Map_QM.util.sceneGap.y + 100, 0) Map_QM.controls.target = new THREE.Vector3(0, 0, 0) } Map_QM.controls.setZoom(Map_QM.util.options.camZoom) @@ -2202,13 +2272,17 @@ MainMap_QM.prototype = { changeMapModel: function (model) { if (model == "2D") { Map_QM.util.setModelState("2d"); + Map_QM.controls.maxPolarAngle = 0; Map_QM.camera = Map_QM.cameraOrtho; Map_QM.controls.object = Map_QM.camera; + Map_QM.camera.updateProjectionMatrix(); Map_QM.shawLight.castShadow = false; } else { Map_QM.util.setModelState("3d"); Map_QM.camera = Map_QM.cameraPerspective; Map_QM.controls.object = Map_QM.camera; + Map_QM.controls.maxPolarAngle = Math.PI / 2 - 0.02; + Map_QM.camera.updateProjectionMatrix(); Map_QM.shawLight.castShadow = Map_QM.util.options.shadow; Map_QM.controls.reset(); } @@ -2217,17 +2291,17 @@ MainMap_QM.prototype = { /** * @api {方法} onShowLocalSite(0) 局部显示放大 * @apiGroup 地图显示 - * @apiDescription 局部显示放大 point 传入放大目标点,zoom放大级别 1-5 - * @apiVersion 2.0.0 + * @apiDescription 局部显示放大 point 传入放大目标点,zoom放大级别 1-5 + * @apiVersion 4.0.0 * @apiParam {Object} point 放大的地图位置 * @apiParam {int} zoom 放大倍数(默认 1) - * + * * @apiSampleRequest off - * + * * @apiParamExample {Object} 请求示例 - * - * Map_QM.onShowLocalSite({x:0,y:0},1); - * + * + * Map_QM.onShowLocalSite({x:0,y:0},1); + * */ onShowLocalSite: function (centerPoint, zoom = 1) { if (Map_QM.util.initModelArr.length > 0 && Map_QM.util.changeDist.inner > Map_QM.util.options.minDis) { @@ -2261,15 +2335,15 @@ MainMap_QM.prototype = { /** * @api {方法} onShowDeviceSite() 地图方向复位 * @apiGroup 地图显示 - * @apiDescription 地图方向复位 - * @apiVersion 2.0.0 - * + * @apiDescription 地图方向复位 + * @apiVersion 4.0.0 + * * @apiSampleRequest off - * + * * @apiParamExample 请求示例 - * + * * Map_QM.onShowDeviceSite(); - * + * */ onShowDeviceSite: function () { this.showFloor(this.util.deviceObj.floor); @@ -2301,16 +2375,16 @@ MainMap_QM.prototype = { * @api {方法} changePathDir(pathState) 切换导航方向 * @apiGroup 地图交互 * @apiDescription 切换导航方向 - * @apiVersion 2.0.0 - * + * @apiVersion 4.0.0 + * * @apiParam {String} pathState 地图导航方向(默认 3D) - * + * * @apiSampleRequest off - * + * * @apiParamExample 请求示例 - * + * * Map_QM.changePathDir("2D"); - * + * */ changePathDir: function (pathState = "3D") { if (Map_QM.util.pathStateObj.isPathState) { //导航状态 @@ -2326,7 +2400,7 @@ MainMap_QM.prototype = { Map_QM.reSetGuide(); } }, - reSetGuide:function(){ + reSetGuide: function () { if (pathCameraState == "2D") { //2D导航 Map_QM.onShowMeDir(); Map_QM.guide.visible = false; @@ -2352,15 +2426,15 @@ MainMap_QM.prototype = { * @api {方法} queryObject3DByShopNum(ipName) 获取3D对象 * @apiGroup 地图交互 * @apiDescription 获取3D对象 - * @apiVersion 2.0.0 - * @apiParam {string} ipName POI名称 - * + * @apiVersion 4.0.0 + * @apiParam {string} ipName POI名称 + * * @apiSampleRequest off - * + * * @apiParamExample 请求示例 - * + * * Map_QM.queryObject3DByShopNum("L1001"); - * + * */ queryObject3DByShopNum: function (ipName) { for (let b = 0; b < Map_QM.mapArr.length; b++) { @@ -2376,19 +2450,19 @@ MainMap_QM.prototype = { return null; }, /** - * @api {方法} parseSelectShop() 设置选中店铺弹跳 + * @api {方法} parseSelectShop() 设置选中店铺弹跳 * @apiGroup 地图交互 - * @apiDescription 设置选中店铺弹跳 - * @apiVersion 2.0.0 - * + * @apiDescription 设置选中店铺弹跳 + * @apiVersion 4.0.0 + * * @apiParam {object3D} selObject 传入3D对象 - * + * * @apiSampleRequest off - * + * * @apiParamExample 请求示例 - * + * * Map_QM.parseSelectShop(object); - * + * */ parseSelectShop: function (selObject) { if (selObject) { @@ -2407,17 +2481,17 @@ MainMap_QM.prototype = { } }, /** - * @api {方法} cancelSelectShop() 取消店铺弹跳 + * @api {方法} cancelSelectShop() 取消店铺弹跳 * @apiGroup 地图交互 - * @apiDescription 取消店铺弹跳效果 - * @apiVersion 2.0.0 - * + * @apiDescription 取消店铺弹跳效果 + * @apiVersion 4.0.0 + * * @apiSampleRequest off - * + * * @apiParamExample 请求示例 - * + * * Map_QM.cancelSelectShop(); - * + * */ cancelSelectShop: function () { TweenMax.killAll(true); @@ -2429,16 +2503,16 @@ MainMap_QM.prototype = { * @api {方法} changeStateShopPro(isShow) 店铺促销标签 * @apiGroup 地图交互 * @apiDescription 店铺促销标签展示/隐藏 - * @apiVersion 2.0.0 - * + * @apiVersion 4.0.0 + * * @apiParam {boolean} isShow 店铺促销标签是否显示(默认 false) - * + * * @apiSampleRequest off - * + * * @apiParamExample {boolean} 请求示例 - * + * * Map_QM.changeStateShopPro(true); - * + * */ changeStateShopPro: function (isShow = false) { Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].tagObj.traverse((obj) => { @@ -2449,16 +2523,16 @@ MainMap_QM.prototype = { * @api {方法} changeShowTagObjState(isShow) 自定义标签 * @apiGroup 地图交互 * @apiDescription 自定义标签展示/隐藏 - * @apiVersion 2.0.0 - * + * @apiVersion 4.0.0 + * * @apiParam {boolean} isShow 自定义标签是否显示(默认 false) - * + * * @apiSampleRequest off - * + * * @apiParamExample {boolean} 请求示例 - * + * * Map_QM.changeShowTagObjState(true); - * + * */ changeShowTagObjState: function (isShow = false) { Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].showTagObj.traverse((obj) => { @@ -2470,12 +2544,12 @@ MainMap_QM.prototype = { * @api {方法} queryShopList() 获取店铺列表信息 * @apiGroup 地图数据 * @apiDescription 店铺列表 - * @apiVersion 2.0.0 - * + * @apiVersion 4.0.0 + * * @apiSampleRequest off - * + * * @apiParamExample 请求示例 - * + * * Map_QM.queryShopList() * */ @@ -2486,23 +2560,24 @@ MainMap_QM.prototype = { * @api {方法} drawCurveLine(startShop,endShop,color) 绘制引导线 * @apiGroup 地图交互 * @apiDescription 绘制引导线 - * @apiVersion 2.0.0 - * + * @apiVersion 4.0.0 + * * @apiParam {string/Array} startShop 起始店铺编号或编号数组 * @apiParam {string/Array} endShop 终点店铺编号或编号数组 * @apiParam {string} color 绘制颜色 (默认 "#0099ff") - * + * * @apiSampleRequest off - * + * * @apiParamExample 请求示例 * //绘制一到多 * Map_QM.drawCurveLine("L125",["L117","L127","L130"],"#2246d8") * //绘制多到一 - * Map_QM.drawCurveLine(["L117","L127","L130"],"L125","#2246d8") + * Map_QM.drawCurveLine(["L117","L127","L130"],"L125","#66ffff") * */ - drawCurveLine: function (startShop, endShop, color = "#0099ff") { + drawCurveLine: function (startShop, endShop, color = "#3969f7") { let sp, ep, cp1, cp2; + hasLine = true; if (Array.isArray(startShop) && Array.isArray(endShop)) { return { "msg": "只能有一个数组" }; } @@ -2515,20 +2590,20 @@ MainMap_QM.prototype = { let s = Math.sqrt((endShop.xaxis - startShop[i].xaxis) * (endShop.xaxis - startShop[i].xaxis) + (endShop.yaxis - startShop[i].yaxis) * (endShop.yaxis - startShop[i].yaxis)); cp1 = new THREE.Vector3(startShop[i].xaxis + (endShop.xaxis - startShop[i].xaxis) / 3, -1 * startShop[i].yaxis - (endShop.yaxis - startShop[i].yaxis) / 3, Map_QM.util.shopHeight + s / 5); cp2 = new THREE.Vector3(endShop.xaxis, -1 * endShop.yaxis, Map_QM.util.shopHeight + s / 3); - Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].lineObj.add(Map_QM.util.drawDashedLine(sp, ep, s / 10, color, cp1, cp2)); + Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].lineObj.add(Map_QM.drawToLine(sp, ep, s / 10, color, cp1, cp2)); } } else { startShop = Map_QM.shopNumToNavPoint({ shopNum: startShop }, "shop"); if (Array.isArray(endShop)) { //如果是数组 for (let i = 0; i < endShop.length; i++) { endShop[i] = Map_QM.shopNumToNavPoint({ shopNum: endShop[i] }, "shop"); + console.log(endShop[i]); sp = new THREE.Vector3(startShop.xaxis, -1 * startShop.yaxis, Map_QM.util.shopHeight); ep = new THREE.Vector3(endShop[i].xaxis, -1 * endShop[i].yaxis, Map_QM.util.shopHeight); let s = Math.sqrt((endShop[i].xaxis - startShop.xaxis) * (endShop[i].xaxis - startShop.xaxis) + (endShop[i].yaxis - startShop.yaxis) * (endShop[i].yaxis - startShop.yaxis)); cp1 = new THREE.Vector3(startShop.xaxis + (endShop[i].xaxis - startShop.xaxis) / 3, -1 * startShop.yaxis - (endShop[i].yaxis - startShop.yaxis) / 3, Map_QM.util.shopHeight + s / 5); cp2 = new THREE.Vector3(endShop[i].xaxis, -1 * endShop[i].yaxis, Map_QM.util.shopHeight + s / 3); - - Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].lineObj.add(Map_QM.util.drawDashedLine(sp, ep, s / 10, color, cp1, cp2)); + Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].lineObj.add(Map_QM.drawToLine(sp, ep, s / 10, color, cp1, cp2)); } } else { endShop = Map_QM.shopNumToNavPoint({ shopNum: endShop }, "shop"); @@ -2537,21 +2612,29 @@ MainMap_QM.prototype = { let s = Math.sqrt((endShop.xaxis - startShop.xaxis) * (endShop.xaxis - startShop.xaxis) + (endShop.yaxis - startShop.yaxis) * (endShop.yaxis - startShop.yaxis)); cp1 = new THREE.Vector3(startShop.xaxis + (endShop.xaxis - startShop.xaxis) / 3, -1 * startShop.yaxis - (endShop.yaxis - startShop.yaxis) / 3, Map_QM.util.shopHeight + s / 5); cp2 = new THREE.Vector3(endShop.xaxis, -1 * endShop.yaxis, Map_QM.util.shopHeight + s / 3); - Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].lineObj.add(Map_QM.util.drawDashedLine(sp, ep, s / 10, color, cp1, cp2)); + Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].lineObj.add(Map_QM.drawToLine(sp, ep, s / 10, color, cp1, cp2)) } } }, + + drawToLine: function (startPoint, endPoint, dash = 50, color = 0x2269dd, ctrlPoint1 = null, ctrlPoint2 = null) { + let curve = new THREE.CubicBezierCurve3(startPoint, ctrlPoint1, ctrlPoint2, endPoint); + let points = curve.getPoints(dash); + let flyLine = createFlyCurve(points, false); + flyLine.userData.type = "toLine"; + return flyLine; + }, /** * @api {方法} drawColumnar(source,property) 绘制柱状图 * @apiGroup 地图交互 * @apiDescription 绘制柱状图 - * @apiVersion 2.0.0 - * + * @apiVersion 4.0.0 + * * @apiParam source 起始店铺编号或编号数组 * @apiParam property 控制参数对象 - * + * * @apiSampleRequest off - * + * * @apiParamExample 请求示例 * //绘制多个 * Map_QM.drawColumnar(["L117","L127","L130"],{"height":200,"width":20,"color":"#2246d8"}) @@ -2628,18 +2711,21 @@ MainMap_QM.prototype = { * @api {方法} removeDrawEle(type) 删除绘制元素 * @apiGroup 地图交互 * @apiDescription 删除绘制元素 - * @apiVersion 2.0.0 - * + * @apiVersion 4.0.0 + * * @apiParam type 传入删除的类型(默认 all) toLine--引导线 columer--柱状样式 all---所有 - * + * * @apiSampleRequest off - * + * * @apiParamExample 请求示例 - * + * * Map_QM.removeDrawEle("toLine") - * + * */ removeDrawEle: function (type = "all") { + if (type == "all" || type == "toLine") { + hasLine = false; + } for (let i = 0; i < Map_QM.mapArr.length; i++) { for (let k = 0; k < Map_QM.mapArr[i].length; k++) { let lineObj = Map_QM.mapArr[i][k].lineObj; @@ -2655,16 +2741,16 @@ MainMap_QM.prototype = { * @api {方法} rotationAngle(angle) 改变水平角度 * @apiGroup 地图显示 * @apiDescription 改变地图水平角度 angle>-180 && angle<180 - * @apiVersion 2.0.0 - * + * @apiVersion 4.0.0 + * * @apiParam {int} angle 旋转角度 - * + * * @apiSampleRequest off - * + * * @apiParamExample {int} 请求示例 - * + * * Map_QM.rotationAngle(90); - * + * */ rotationAngle: function (angle) { Map_QM.controls.setRotateHorizontal(angle / 180 * Math.PI); @@ -2673,34 +2759,34 @@ MainMap_QM.prototype = { * @api {方法} rotateAngle(angle) 改变垂直角度 * @apiGroup 地图显示 * @apiDescription 改变地图垂直角度 angle>-90 && angle<90 - * @apiVersion 2.0.0 - * + * @apiVersion 4.0.0 + * * @apiParam {int} angle 旋转角度 - * + * * @apiSampleRequest off - * + * * @apiParamExample {int} 请求示例 - * + * * Map_QM.rotateAngle(-45); - * + * */ rotateAngle: function (angle) { Map_QM.controls.rotate(angle / 180 * Math.PI); }, /** - * @api {方法} setCameraDist(cDist) 调整地图大小 + * @api {方法} setCameraDist(cDist) 调整地图大小 * @apiGroup 地图显示 * @apiDescription 调整地图大小(值越小地图越大) Map_QM.util.options.minDis ~ Map_QM.util.options.maxDis - * @apiVersion 2.0.0 - * + * @apiVersion 4.0.0 + * * @apiParam {int} cDist 摄像头距离 - * + * * @apiSampleRequest off - * + * * @apiParamExample {int} 请求示例 - * + * * Map_QM.setCameraDist(150); - * + * */ setCameraDist: function (cDist) { if (Map_QM.util.options.minDis < parseInt(cDist) && parseInt(cDist) < Map_QM.util.options.maxDis) { @@ -2719,21 +2805,21 @@ MainMap_QM.prototype = { * @api {方法} startRender() 启动地图渲染 * @apiGroup 地图显示 * @apiDescription 启动地图渲染 与 cancelRender 配合使用可节约资源 - * @apiVersion 2.0.0 - * + * @apiVersion 4.0.0 + * * @apiSampleRequest off * @apiParamExample 请求示例 - * + * * Map_QM.startRender(); - * + * */ startRender: function () { Map_QM.cancelRender(); renderFrame = requestAnimationFrame(Map_QM.startRender); let T = Map_QM.util._clock.getDelta(); Map_QM.util.timeObj.timeS = Map_QM.util.timeObj.timeS + T; - // requestAnimationFrame默认调用render函数60次,通过时间判断,降低renderer.render执行频率 - if (Map_QM.util.timeObj.timeS > 0.03) { + // requestAnimationFrame默认调用render函数60次,通过时间判断,降低renderer.render执行频率 + if (Map_QM.util.timeObj.timeS > 0.05) { if (Map_QM.qiModel) { Map_QM.qiModel.rotateY(0.05); } @@ -2753,12 +2839,18 @@ MainMap_QM.prototype = { Map_QM.controls.update(); Map_QM.renderer.render(Map_QM.scene, Map_QM.camera); Map_QM.labelRenderer.render(Map_QM.scene, Map_QM.camera); + Map_QM.labelRenderer.renderObject( Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].labelObj, Map_QM.camera ); + Map_QM.labelRenderer.renderObject( Map_QM.CSSObject, Map_QM.camera ); for (let item of Map_QM.mixers) { item.update(T); } if (debug) { stats.update(); } + if (hasLine) { + const elapsed = Map_QM.util._clock.getElapsedTime(); + uniforms.u_time.value = elapsed; + } //timeS置0 Map_QM.util.timeObj.timeS = 0; } @@ -2767,14 +2859,14 @@ MainMap_QM.prototype = { * @api {方法} cancelRender() 取消地图渲染 * @apiGroup 地图显示 * @apiDescription 取消地图渲染 与 startRender 配合使用可节约资源 - * @apiVersion 2.0.0 - * + * @apiVersion 4.0.0 + * * @apiSampleRequest off - * + * * @apiParamExample 请求示例 - * + * * Map_QM.cancelRender(); - * + * */ cancelRender: function () { window.cancelAnimationFrame(renderFrame); @@ -2785,21 +2877,20 @@ MainMap_QM.prototype = { * @api {方法} addElementLabel() 地图html标签 * @apiGroup 地图交互 * @apiDescription 地图显示Html标签,返回3d标签对象 - * @apiVersion 2.0.0 - * + * @apiVersion 4.0.0 + * * @apiParam {Element} divObj div对象 * @apiParam {int} x 显示X坐标 * @apiParam {int} y 显示Y坐标 * @apiParam {int} z 显示高度坐标(默认 50) * @apiParam {String} type docment元素自定义标识(默认 "shopInfo") * @apiSampleRequest off - * + * * @apiParamExample {String} 请求示例 * Map_QM.addElementLabel(divObj,x,y); */ addElementLabel: function (divObj, x, y, z = 50, type = "shopInfo") { divObj.style.opacity = 0; - Map_QM.elementDestroy(type); let shopInfo = new THREE.CSS2DObject(divObj); shopInfo.position.set(x, -1 * y, z); shopInfo.applyMatrix4(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.matrix); @@ -2813,17 +2904,17 @@ MainMap_QM.prototype = { * @api {方法} updateElementPosition() 修改标签位置 * @apiGroup 地图交互 * @apiDescription 修改标签位置 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiParam {Object} obj 对象 * @apiParam {int} x 新的X坐标 * @apiParam {int} y 新的Y坐标 - * + * * @apiSampleRequest off - * + * * @apiParamExample {Object} 请求示例 - * + * * Map_QM.updateElementPosition(obj,x,y); - * + * */ updateElementPosition: function (obj, x, y) { if (obj.hasOwnProperty("position")) { @@ -2836,15 +2927,15 @@ MainMap_QM.prototype = { * @api {方法} elementDestroy(type) 销毁地图标签 * @apiGroup 地图交互 * @apiDescription 销毁地图上的html标签 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiParam {String} type docment元素自定义标识(默认 "shopInfo") - * + * * @apiSampleRequest off - * + * * @apiParamExample {Object} 请求示例 - * + * * Map_QM.elementDestroy(); - * + * */ elementDestroy: function (type = "shopInfo") { for (let i = Map_QM.CSSObject.children.length - 1; i >= 0; i--) { @@ -2857,11 +2948,11 @@ MainMap_QM.prototype = { * @api {方法} changeShowShopName() 修改店铺显示名称 * @apiGroup 地图显示 * @apiDescription 通过店铺编号修改店铺显示名称 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiParam {Array} shopNum 店铺编号 * @apiParam {Array} element html标签字符串 * @apiSampleRequest off - * + * * @apiParamExample {String} 请求示例 * Map_QM.changeShowShopName(["L104"],['

肯德基

']) */ @@ -2879,14 +2970,14 @@ MainMap_QM.prototype = { } }, /** - * @api {方法} unionShop() 店铺合并 + * @api {方法} unionShop() 店铺合并 * @apiGroup 地图显示 * @apiDescription 通过店铺编号合并店铺 合铺 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiParam {Array} shops 店铺编号数组 * @apiParam {Object} data 新的店铺数据(默认 空数据) * @apiSampleRequest off - * + * * @apiParamExample {String} 请求示例 * Map_QM.unionShop(["L105","L106","L107","L108"],{name:"新店",shopNum:"L104-L108",color:"#F4A460"}) */ @@ -2997,12 +3088,12 @@ MainMap_QM.prototype = { let facCode = intersects[i].object.userData.facCode || intersects[i].object.parent.userData.facCode || intersects[i].object.parent.parent.userData.facCode let title = intersects[i].object.userData.title || intersects[i].object.parent.userData.title || intersects[i].object.parent.parent.userData.title /** - * @api {事件} icon 点击设施图标 + * @api {事件} icon 点击设施图标 * @apiGroup 地图事件 * @apiDescription 用户点击设施图标后触发自定义事件 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiSampleRequest off - * + * * @apiParamExample 请求示例 * Map_QM.addEventListener("icon",onClickIcon,false); */ @@ -3031,29 +3122,29 @@ MainMap_QM.prototype = { } } /** - * @api {事件} shop 点击已绑定品牌的店铺 + * @api {事件} shop 点击已绑定品牌的店铺 * @apiGroup 地图事件 * @apiDescription 用户点击店铺后触发自定义事件 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiSampleRequest off - * + * * @apiParamExample 请求示例 * Map_QM.addEventListener("shop",onClickShop,false); */ if (clickShop && Map_QM.selectShop && Map_QM.selectShop.userData) { - if ((iot && Map_QM.selectShop.userData.shopData.hasOwnProperty("shopName")) || (!iot && Map_QM.selectShop.userData.shopData.hasOwnProperty("name"))) { + if (Map_QM.selectShop.userData.shopData.hasOwnProperty("shopName")) { Map_QM.dispatchEvent({ type: "shop", data: Map_QM.selectShop.userData }) } else { /** - * @api {事件} onlyShop 点击未绑定品牌的店铺 + * @api {事件} onlyShop 点击未绑定品牌的店铺 * @apiGroup 地图事件 * @apiDescription 用户点击空店铺后触发自定义事件 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiSampleRequest off - * + * * @apiParamExample 请求示例 * Map_QM.addEventListener("onlyShop",onClickShop,false); */ @@ -3073,15 +3164,15 @@ MainMap_QM.prototype = { * @api {方法} setSelectShopMatByName(shopNum) 设置box 选中 * @apiGroup 地图交互 * @apiDescription 地图box 选中 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiParam {String} shopNum POI编号 - * + * * @apiSampleRequest off - * + * * @apiParamExample {String} 请求示例 - * + * * Map_QM.setSelectShopMatByName("L101"); - * + * */ setSelectShopMatByName: function (ipName) { for (let i = 0; i < Map_QM.mapArr[Map_QM.util.selectBuild].length; i++) { @@ -3109,6 +3200,8 @@ MainMap_QM.prototype = { Map_QM.controls.update(); Map_QM.renderer.render(Map_QM.scene, Map_QM.camera); Map_QM.labelRenderer.render(Map_QM.scene, Map_QM.camera); + Map_QM.labelRenderer.renderObject( Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].labelObj, Map_QM.camera ); + Map_QM.labelRenderer.zOrder( Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].labelObj ); if (Map_QM.callBackLoadOver) { let floorData = []; for (let i = 0; i < Map_QM.util.allMap.length; i++) { @@ -3168,19 +3261,40 @@ MainMap_QM.prototype = { } } }, + disPlayEvent: function (e) { + clearTimeout(stateTime); + stateTime = setTimeout(() => { + clearTimeout(stateTime); + if (!Map_QM.util.pathStateObj.isPathState) { + let distance = Map_QM.controls.getDistance(); + if (distance <= Map_QM.util.changeDist.inner) { //切换到室内 + Map_QM.dispatchEvent({ + type: 'mapShowChange', + data: 'mall' + }) + } else { + Map_QM.dispatchEvent({ + type: 'mapShowChange', + data: 'out' + }) + } + } + }, 300); + }, /** * 碰撞检测 - * @param {Object} 传入检测楼层下标 + * @param {Object} 传入检测楼层下标 */ controlsChock: function () { Map_QM.autoChangeEleAngle(); + Map_QM.collLabel(); /** - * @api {事件} MapAngleChange 地图的方向改变 + * @api {事件} MapAngleChange 地图的方向改变 * @apiGroup 地图事件 * @apiDescription 用户操作地图时触发 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiSampleRequest off - * + * * @apiParamExample 请求示例 * Map_QM.addEventListener("MapAngleChange",onMapAngleChange,false); */ @@ -3271,7 +3385,6 @@ MainMap_QM.prototype = { Map_QM.hideObjecrGap(Map_QM.outModelGap, true); } } - Map_QM.collLabel(); }, hideObjecrGap: function (gap, isShow) { @@ -3289,12 +3402,17 @@ MainMap_QM.prototype = { //内部碰撞检测 collLabel: function () { - if (!Map_QM || !Map_QM.util.options.collision) { + if (!Map_QM) { return; } - + clearTimeout(Map_QM.util.timeObj.collTime); Map_QM.util.timeObj.collTime = setTimeout(() => { clearTimeout(Map_QM.util.timeObj.collTime); + Map_QM.labelRenderer.zOrder( Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].labelObj ); + if (!Map_QM.util.options.collision) { + return; + } + let checkList = []; if (Map_QM.util.options.overlap) { for (let i = 0; i < Map_QM.mapArr[Map_QM.util.selectBuild].length; i++) { @@ -3305,36 +3423,30 @@ MainMap_QM.prototype = { }); } } - if (Map_QM.mapArr[Map_QM.util.selectBuild]) { + if (Map_QM.mapArr[Map_QM.util.selectBuild] && Map_QM.buildObj.visible) { for (let m = 0; m < Map_QM.mapArr[Map_QM.util.selectBuild].length; m++) { if (Map_QM.mapArr[Map_QM.util.selectBuild][m].allObj.visible && (!Map_QM.buildObj.userData.hasOwnProperty("visible") || Map_QM.buildObj.userData.visible)) { let childs = Map_QM.mapArr[Map_QM.util.selectBuild][m].labelObj.children; let len = childs.length; for (let i = 0; i < len; i++) { let obj = childs[i].element - if(childs[i].userData.mapShow){ + if (childs[i].userData.mapShow) { obj.style.visibility = "visible"; - }else{ + } else { obj.style.visibility = "hidden"; } if (obj.style.transform) { obj.style.visibility = "visible" - let labP = obj.style.transform.split('translate')[2].split(', ') + let labP = obj.getBoundingClientRect(); for (let j = 0; j < i; j++) { if (childs[j].element.style.visibility == "visible") { - let pb = childs[j].element.style.transform.split('translate')[2].split(', ') - let isCol = Map_QM.util.isCollision( - new Map_QM.util.Point(labP[0].substring(1, labP[0].length - 2), labP[1].substring(0, labP[1].length - 3)), - obj.clientWidth, - obj.clientHeight, - new Map_QM.util.Point(pb[0].substring(1, pb[0].length - 2), pb[1].substring(0, pb[1].length - 3)), - childs[j].element.clientWidth, - childs[j].element.clientHeight - ) + let pb = childs[j].element.getBoundingClientRect(); + let isCol = Map_QM.util.isCollision(labP, pb); if (isCol) { - if(!childs[i].userData.mapShow){ + if (!childs[i].userData.mapShow) { obj.style.visibility = "hidden" - }else if(!childs[j].userData.mapShow){ + break; + } else if (!childs[j].userData.mapShow) { childs[j].element.style.visibility = "hidden" } } @@ -3382,15 +3494,15 @@ MainMap_QM.prototype = { * @api {方法} bounceIcon({type:"xsj"}) 图标弹跳 * @apiGroup 地图导航 * @apiDescription 地图图标弹跳效果 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiParam {String} iconType 设施缩写 - * + * * @apiSampleRequest off - * + * * @apiParamExample {String} 请求示例 - * + * * Map_QM.bounceIcon({type:"xsj"}); - * + * */ bounceIcon: function (iconType) { let toFloor = parseInt(Map_QM.util.selectFloor); @@ -3404,29 +3516,366 @@ MainMap_QM.prototype = { } } }, + /** + * @api {方法} countPath() 方向算法 + * @apiGroup 地图导航 + * @apiDescription 计算设施、店铺的导航方向, toObj,pathType 不能同时为空 + * @apiVersion 4.0.0 + * @param {Object} toObj {build,floor,node} //终点 设施寻路可以为空 + * @param {String} pathType 公共设施名称或编号(点位寻路此参数为空字符串) + * @param {String} countType 8--八方向(默认) 12--十二方向 + * + * @apiSampleRequest off + * + * @apiParamExample {String} 请求示例 + * + * Map_QM.countPath({build:0,floor:0,node:0},"xsj","8"); + * + */ + countPath: function (toObj, pathType = "", _countType = "8") { + direction = { "code": 500, "dir": '', "cost": 0, "gap": 0 }; + countType = _countType; + Map_QM.util.overObj = null; + if (pathType == "") { //传入终点导航点 + Map_QM.util.overObj = toObj; + if (Map_QM.util.startObj.node != "" && Map_QM.util.startObj.node != "-1" && Map_QM.util.overObj.node != "") { + this.forShopArr.length = 0; + return this.forDirPath(); + } else { + direction.code = "404"; + return direction + } + } else { // + let iconPath = this.pathIcon({ type: pathType }); + Map_QM.util.overObj = iconPath; + if (Map_QM.util.startObj.node != "" && Map_QM.util.startObj.node != "-1" && Map_QM.util.overObj.node != "") { + this.forShopArr.length = 0; + return this.forDirPath(); + } + } + return direction = { "code": 404, "dir": '', "cost": 0, "gap": 0 }; + }, + forDirPath: function () { + let startNade = Map_QM.util.startObj.build + "_" + Map_QM.util.startObj.floor + "_" + Map_QM.util.startObj.node; + let toNade = Map_QM.util.overObj.build + "_" + Map_QM.util.overObj.floor + "_" + Map_QM.util.overObj.node; + let PathPoint; + direction = { "code": 500, "dir": '', "cost": 0, "gap": 0 }; + try { + let obj = dijkstra.find_path(Map_QM.util.pathStateObj.graphPath, startNade, toNade); + PathPoint = obj.nodes; + direction.cost = Math.floor(obj.cost / Map_QM.util.options.mapScale * 0.9); + direction.gap = parseInt(obj.cost / Map_QM.util.options.mapScale); + } catch (e) { + console.log(e); + direction.code = 404; + return direction; + } + let index = 0; + this.forShopArr = []; + if (PathPoint.length > 1) { + this.forShopArr.push({ build: Map_QM.util.startObj.build, floor: Map_QM.util.startObj.floor, PathPoint: [] }); + let pathData; + for (let j = 0; j < PathPoint.length; j++) { + let array = PathPoint[j].split("_"); + pathData = Map_QM.util.allMap[parseInt(array[0])].buildArr[parseInt(array[1])].mapData.path; + pathData.nodes.sort(Map_QM.util.sortNumber); + if (parseInt(array[1]) == this.forShopArr[index].floor) { //同层 + this.forShopArr[index].PathPoint.push(pathData.nodes[parseInt(array[2])]); + } else { + this.forShopArr.push({ build: parseInt(array[0]), floor: parseInt(array[1]), PathPoint: [] }); + index++; + this.forShopArr[index].PathPoint.push(pathData.nodes[parseInt(array[2])]); + } + } + } else { + this.forShopArr.length = 0; + } + if (this.forShopArr.length > 0) { //--------------------------计算方向 + direction.code = 200; + if (countType == "12") { //16方向 + Map_QM.countSixteenArrow(); + } else { + Map_QM.countStartAndEndDire(); + } + + } + console.log(this.forShopArr) + if (this.forShopArr.length > 1) { + let facType; + if (this.forShopArr[0].floor > this.forShopArr[1].floor) { //下 + if (Math.abs(parseInt(this.forShopArr[0].floor) - parseInt(this.forShopArr[1].floor)) < 3) { //扶梯 + facType = Map_QM.util.getFacType("downft"); + } else { + facType = Map_QM.util.getFacType("dt"); + } + } else { + if (Math.abs(parseInt(this.forShopArr[0].floor) - parseInt(this.forShopArr[1].floor)) < 3) { //扶梯 + facType = Map_QM.util.getFacType("upft"); + } else { + facType = Map_QM.util.getFacType("dt"); + } + } + facType = facType + ""; + if (facType.length === 1) { + direction.dir = "600" + facType; + } else if (facType.length === 2) { + direction.dir = "60" + facType; + } else if (facType.length === 3) { + direction.dir = "6" + facType; + } + } + return direction; + }, + /** + * 计算十六方向箭头 + */ + countSixteenArrow: function () { + if (this.forShopArr[0].PathPoint.length > 1) { + let keyPoints = [], ishas = false, allCount = 0; + for (let i = 1; i < this.forShopArr[0].PathPoint.length; i++) { + let s = Math.sqrt(Math.pow((this.forShopArr[0].PathPoint[i].x - this.forShopArr[0].PathPoint[i - 1].x), 2) + Math.pow((this.forShopArr[0].PathPoint[i].y - this.forShopArr[0].PathPoint[i - 1].y), 2)); + if (s < 20) { + continue; + } + ishas = false; + let dirObj = { angleName: Map_QM.getPathAngle(this.forShopArr[0].PathPoint[i - 1], this.forShopArr[0].PathPoint[i]), count: s }; + allCount += s; + if (keyPoints.length > 0 && keyPoints[keyPoints.length - 1].angleName == dirObj.angleName) { + keyPoints[keyPoints.length - 1].count += s; + ishas = true; + } + if (!ishas) { + keyPoints.push(dirObj); + } + } + if (allCount < 150) { //总长度< 150 按8方向 + Map_QM.countStartAndEndDire(); + return; + } + if (keyPoints.length == 1) { + direction.dir = Map_QM.getDirByName(keyPoints[0].angleName); + return; + } + if (keyPoints.length == 0) { //没有路径,按方向计算 + direction.code = 404; + return; + } + let upCount = 0, rightFrontCount = 0, rightCount = 0, leftFrontCount = 0; + for (let item of keyPoints) { + if (item.angleName == "up") { + upCount += item.count; + } else if (item.angleName == "down") { + upCount -= item.count; + } else if (item.angleName == "right") { + rightCount += item.count; + } else if (item.angleName == "left") { + rightCount -= item.count; + } else if (item.angleName == "rightFront") { + rightFrontCount += item.count; + } else if (item.angleName == "rightRear") { + leftFrontCount -= item.count; + } else if (item.angleName == "leftFront") { + leftFrontCount += item.count; + } else if (item.angleName == "leftRear") { + rightFrontCount -= item.count; + } + } + console.log(keyPoints) + //斜方向忽略 + let dir1 = ""; + let bjCount = Math.max(150, allCount / 10); + let onlyDir = ""; + for (let item of keyPoints) { + if (item.angleName != "rightFront" && item.angleName != "leftFront" && item.angleName != "rightRear" && item.angleName != "leftRear") { + onlyDir = dir1.length > 0 ? dir1.substring(dir1.length - 1, dir1.length) : dir1; + if (item.angleName == "down" && (item.count > bjCount || upCount < -1 * bjCount)) { + if (onlyDir != "D") { + dir1 += "D"; + } + } else if (item.angleName == "up" && (item.count > bjCount || upCount > bjCount)) { + if (onlyDir != "T") { + dir1 += "T"; + } + } else if (item.angleName == "right" && (item.count > bjCount || rightCount > bjCount)) { + if (onlyDir != "R") { + dir1 += "R"; + } + } else if (item.angleName == "left" && (item.count > bjCount || rightCount < -1 * bjCount)) { + if (onlyDir != "L") { + dir1 += "L"; + } + } + } + } + //console.log(dir1) + if (dir1.length > 2) dir1 = dir1.substring(0, 2) //两个以上方向 + direction.dir = Map_QM.getDirByName(dir1); + if (!direction.dir) Map_QM.countStartAndEndDire(); + + } else { //没有路径,按方向计算 + direction.code = 404; + } + }, + + getDirByName: function (dir) { + switch (dir) { + default: + return ""; + case "T": + return "1201"; + case "R": + return "1202"; + case "D": + return "1203"; + case "L": + return "1204"; + case "TL": + return "1205"; + case "TR": + return "1206"; + case "RT": + return "1207"; + case "RD": + return "1208"; + case "DL": + return "1209"; + case "DR": + return "1210"; + case "LT": + return "1211"; + case "LD": + return "1212"; + case "up": + return "1201"; + case "rightFront": + return "8002"; + case "right": + return "1202"; + case "rightRear": + return "8004"; + case "down": + return "1203"; + case "leftRear": + return "8006"; + case "left": + return "1204"; + case "leftFront": + return "8008"; + } + }, + + /** + * 计算八方向坐标 + */ + countStartAndEndDire: function () { + let sPoint = new Map_QM.util.Point(this.forShopArr[0].PathPoint[0].x, this.forShopArr[0].PathPoint[0].y); //本层起始点坐标 + let ePoint = new Map_QM.util.Point(this.forShopArr[0].PathPoint[this.forShopArr[0].PathPoint.length - 1].x, this.forShopArr[0].PathPoint[this.forShopArr[0].PathPoint.length - 1].y); //本层结束点坐标 + switch (Map_QM.getPathAngle(sPoint, ePoint)) { + default: + direction.dir = "8001"; + case "up": + direction.dir = "8001"; + break; + case "rightFront": + direction.dir = "8002"; + break; + case "right": + direction.dir = "8003"; + break; + case "rightRear": + direction.dir = "8004"; + break; + case "down": + direction.dir = "8005"; + break; + case "leftRear": + direction.dir = "8006"; + break; + case "left": + direction.dir = "8007"; + break; + case "leftFront": + direction.dir = "8008"; + break; + } + }, + + getPathAngle: function (sPoint, ePoint) { + let x = Math.abs(sPoint.x - ePoint.x); + let y = Math.abs(sPoint.y - ePoint.y); + let tan = x / y; + let radina = Math.atan(tan);//用反三角函数求弧度 + let angle = Math.floor(180 / (Math.PI / radina)) || 0;//将弧度转换成角度 + + if (ePoint.x > sPoint.x && ePoint.y > sPoint.y) {// 右下方 + angle = 180 - angle; + } + if (ePoint.x == sPoint.x && ePoint.y > sPoint.y) {// 正下方 + angle = 180; + } + if (ePoint.x < sPoint.x && ePoint.y > sPoint.y) {//左下方 + angle = angle - 180; + } + if (ePoint.x < sPoint.x && ePoint.y == sPoint.y) {//左方 + angle = -90; + } + if (ePoint.x < sPoint.x && ePoint.y < sPoint.y) {// 左上方 + angle = (-1) * angle; + } + if (ePoint.x == sPoint.x && ePoint.y < sPoint.y) {//上方 + angle = 0; + } + if (ePoint.x > sPoint.x && ePoint.y < sPoint.y) {//右上方 + angle = angle; + } + if (ePoint.x > sPoint.x && ePoint.y == sPoint.y) {//point在x轴正方向上 + angle = 90; + } + angle -= Map_QM.util.deviceObj.angle; + angle = angle > 180 ? angle - 360 : angle; + angle = angle < -180 ? angle + 360 : angle; + + if (angle > -22 && angle <= 22) { //前 + return "up"; + } else if (angle > 22 && angle <= 67) { //右前 + return "rightFront"; + } else if (angle > 67 && angle <= 112) { //右 + return "right"; + } else if (angle > 112 && angle <= 158) { //右后 + return "rightRear"; + } else if (angle > 158 || angle <= -158) { //后 + return "down"; + } else if (angle > -158 && angle <= -112) { //左后 + return "leftRear"; + } else if (angle > -112 && angle <= -67) { //左 + return "left"; + } else { //左前 + return "leftFront"; + } + + }, /** * @api {方法} pathIcon({type:"xsj"}) 获取最近设施 * @apiGroup 地图导航 * @apiDescription 获取离当前楼层最近的设施 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiParam {JSON} type 设施缩写 - * + * * @apiSampleRequest off - * - * @apiParamExample {String} 请求示例 - * + * + * @apiParamExample {String} 请求示例 + * * Map_QM.pathIcon({type:"xsj"}); - * + * * @apiSuccessExample 返回示例 * { * "floor": 楼层编号, "node": 设施导航点,"typeCode":设施编号 * } - * + * */ pathIcon: function (iconType) { let selIcon; // let minS = -1; - toIcon = iconType.type; if (!Map_QM.util.startObj.build && parseInt(Map_QM.util.startObj.build) != 0) { Map_QM.util.startObj.build = parseInt(Map_QM.util.deviceObj.build); } @@ -3455,7 +3904,7 @@ MainMap_QM.prototype = { } if (selIcon) { - return { "build": parseInt(Map_QM.util.deviceObj.build), "floor": selIcon.floor, site: { x: selIcon.position.x, y: selIcon.position.y }, "node": selIcon.navCode, "no": selIcon.no, "typeCode": Map_QM.util.getFacType(iconType.type) }; + return { "build": parseInt(Map_QM.util.deviceObj.build), "floor": selIcon.floor, "site": { x: selIcon.position.x, y: selIcon.position.y }, "node": selIcon.navCode, "no": selIcon.no, "typeCode": Map_QM.util.getFacType(iconType.type) }; } else { // 当前楼栋没有 for (let b = 0; b < Map_QM.mapArr.length; b++) { if (b != parseInt(Map_QM.util.deviceObj.build)) { @@ -3463,17 +3912,19 @@ MainMap_QM.prototype = { let sers = Map_QM.mapArr[b][i].serObj.children; //服务图标 for (let n = 0; n < sers.length; n++) { if (sers[n].facCode == iconType.type) { - let toNade = parseInt(Map_QM.util.deviceObj.build) + "_" + sers[n].floor + "_" + sers[n].navCode; + let toNade = b + "_" + sers[n].floor + "_" + sers[n].navCode; if (!selIcon) { minS = costAll[toNade]; if (minS) { selIcon = sers[n]; + selIcon.build = b; } } else { let s1 = costAll[toNade]; if (s1 && s1 < minS) { minS = s1; selIcon = sers[n]; + selIcon.build = b; } } } @@ -3481,9 +3932,9 @@ MainMap_QM.prototype = { } } } - } - if (selIcon) { - return { "build": parseInt(Map_QM.util.deviceObj.build), "floor": selIcon.floor, "node": selIcon.navCode, site: { x: selIcon.position.x, y: selIcon.position.y }, "no": selIcon.no, "typeCode": Map_QM.util.getFacType(iconType.type) }; + if (selIcon) { + return { "build": selIcon.build, "floor": selIcon.floor, "node": selIcon.navCode, "site": { x: selIcon.position.x, y: selIcon.position.y }, "no": selIcon.no, "typeCode": Map_QM.util.getFacType(iconType.type) }; + } } } }, @@ -3491,21 +3942,21 @@ MainMap_QM.prototype = { * @api {方法} pathByStartAndOver(startObj,toObj,callBackFun) 地图路径规划 * @apiGroup 地图导航 * @apiDescription 根据传入的起、终点;直接导航 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiParam {String} startObj.shopNum 店铺编号/车位编号 * @apiParam {String} startObj.type "shop"/"park" - * + * * @apiParam {String} toObj.shopNum 店铺编号/车位编号 * @apiParam {String} toObj.type "shop"/"park" - * + * * @apiParam {Function} callBackFun 回调函数 - * + * * @apiSampleRequest off - * + * * @apiParamExample {String} 请求示例 - * + * * Map_QM.pathByStartAndOver({"shopNum":"L102","type":"shop"},{"shopNum":"L204","type":"shop"}); - * + * */ pathByStartAndOver: function (startObj, toObj, callBackFun) { try { @@ -3521,18 +3972,18 @@ MainMap_QM.prototype = { * @api {方法} changeStartPoint() 设置起始点位 * @apiGroup 地图导航 * @apiDescription 设置起始点位 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiParam {int} build 起点楼栋编号 * @apiParam {int} floor 起点楼层编号 * @apiParam {String} node 起点编号 * @apiParam {int} angle 起点角度 - * + * * @apiSampleRequest off - * + * * @apiParamExample {String} 请求示例 - * + * * Map_QM.changeStartPoint({"build":0, "floor":3, "node":"20", "angle":0}); - * + * */ changeStartPoint: function (toObj) { this.clearFloor(); @@ -3570,16 +4021,16 @@ MainMap_QM.prototype = { * @api {方法} changeMapIPState(ipName,color) 改变POI颜色 * @apiGroup 地图交互 * @apiDescription 改变POI 颜色 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiParam {string} ipName POI名称 - * @apiParam {string} color 颜色字符串 - * + * @apiParam {string} color 颜色字符串 + * * @apiSampleRequest off - * + * * @apiParamExample 请求示例 - * + * * Map_QM.changeMapIPState("L1001","#ffff00"); - * + * */ changeMapIPState: function (ipName, color) { // #775544 #AD8164 for (let i = 0; i < this.mapArr[this.util.selectBuild].length; i++) { @@ -3593,18 +4044,18 @@ MainMap_QM.prototype = { } }, /** - * @api {方法} getMapIPData(ipName) 获取POI 基础数据 + * @api {方法} getMapIPData(ipName) 获取POI 基础数据 * @apiGroup 地图交互 * @apiDescription 获取POI 基础数据 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiParam {string} ipName POI名称 - * + * * @apiSampleRequest off - * + * * @apiParamExample 请求示例 - * + * * Map_QM.getMapIPData("L1001"); - * + * * @apiSuccessExample 返回示例 * { * shopNum:店铺编号, shopName:店铺名 node:导航点, floor:楼层编号, xaxis:中心点X坐标, yaxis:中心点Y坐标, borderColor:边框色, entColor:填充色 @@ -3625,17 +4076,17 @@ MainMap_QM.prototype = { * @api {方法} pathNode() 地图模拟导航 * @apiGroup 地图导航 * @apiDescription 地图路径模拟导航 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiParam {int} floor 楼层编号 * @apiParam {string} node 路径点位编号 * @apiParam {function} callBackFun 回调方法 - * + * * @apiSampleRequest off - * + * * @apiParamExample 请求示例 - * + * * Map_QM.pathNode({build:0, floor:2,node:"53"},callBackFun); - * + * */ pathNode: function (toObj, callBackFun) { if (!toObj) { @@ -3654,7 +4105,7 @@ MainMap_QM.prototype = { Map_QM.changeStartPoint(null); } Map_QM.util.overObj = null; - Map_QM.util.overObj = { build: toObj.build || 0, floor: toObj.floor, node: toObj.node, shopNum: toObj.shopNum,comeIn: toObj.comeIn || "" }; + Map_QM.util.overObj = { build: toObj.build || 0, floor: toObj.floor, node: toObj.node, shopNum: toObj.shopNum, comeIn: toObj.comeIn || "" }; if (Map_QM.util.overObj.node != "") { Map_QM.cancelRender(); this.onFindPathModel(); @@ -3680,14 +4131,14 @@ MainMap_QM.prototype = { } if (item.hasOwnProperty("wayShop") && item.wayShop) { for (let i = 0; i < item.wayShop.length; i++) { - let enTlite = item.wayShop[i].shop.nameEn == "" ? item.wayShop[i].shop.name : item.wayShop[i].shop.nameEn; - Map_QM.util.pathStateObj.forShopArr.wayList.push({ isAddPrefix: false, name: "经过 " + item.wayShop[i].shop.name, nameEn: "PASS " + enTlite, logoPath: item.wayShop[i].shop.logoPath, code: item.wayShop[i].shop.code, shopNum: iot ? item.wayShop[i].shop.houseNumber : item.wayShop[i].shop.houseNum }); + let enTlite = item.wayShop[i].shop.shopNameEn == "" ? item.wayShop[i].shop.shopName : item.wayShop[i].shop.shopNameEn; + Map_QM.util.pathStateObj.forShopArr.wayList.push({ isAddPrefix: false, shopName: "经过 " + item.wayShop[i].shop.shopName || item.wayShop[i].shop.name, shopNameEn: "PASS " + enTlite, logoPath: item.wayShop[i].shop.logoPath, code: item.wayShop[i].shop.code, shopNum: iot ? item.wayShop[i].shop.houseNumber : item.wayShop[i].shop.houseNum }); } } if (item.hasOwnProperty("Facilities") && item.Facilities) { //设施 Map_QM.util.pathStateObj.forShopArr.wayList.push({ - isAddPrefix: true, name: "乘坐 " + item.Facilities.userData.title + "到 " + Map_QM.mapArr[Map_QM.util.selectBuild][parseInt(Map_QM.forShopArr[index + 1].floor)].floorName, - nameEn: "BY " + item.Facilities.userData.title + "TO " + Map_QM.mapArr[Map_QM.util.selectBuild][parseInt(Map_QM.forShopArr[index + 1].floor)].floorName, logoPath: item.Facilities.imgUrl, code: (((Math.random()) * 0x1234567) | 0).toString(16).substring(0), shopNum: item.Facilities.userData.facCode + item.Facilities.userData.no + isAddPrefix: true, shopName: "乘坐 " + item.Facilities.userData.title + "到 " + Map_QM.mapArr[Map_QM.util.selectBuild][parseInt(Map_QM.forShopArr[index + 1].floor)].floorName, + shopNameEn: "BY " + item.Facilities.userData.title + "TO " + Map_QM.mapArr[Map_QM.util.selectBuild][parseInt(Map_QM.forShopArr[index + 1].floor)].floorName, logoPath: item.Facilities.imgUrl, code: (((Math.random()) * 0x1234567) | 0).toString(16).substring(0), shopNum: item.Facilities.userData.facCode + item.Facilities.userData.no }); } }); @@ -3696,16 +4147,16 @@ MainMap_QM.prototype = { * @api {方法} getGapByPathNode() 获取实际距离 * @apiGroup 地图导航 * @apiDescription 通过点位获取距离 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiParam {int} floor 楼层编号 * @apiParam {string} node 路径点位编号 - * + * * @apiSampleRequest off - * + * * @apiParamExample 请求示例 - * + * * Map_QM.getGapByPathNode({floor:2,node:"53"}); - * + * * @apiSuccessExample {Object} dist 距离米数 time 步行时间 * { * dis:200,time:4 @@ -3718,7 +4169,7 @@ MainMap_QM.prototype = { try { path = dijkstra.find_path(Map_QM.util.pathStateObj.graphPath, startNade, toNade); minTime = parseInt(path.cost / Map_QM.util.options.mapScale / 50) < 0.5 ? 0.5 : parseInt(path.cost / Map_QM.util.options.mapScale / 50); - console.log(`距离目的地 ${parseInt(path.cost / Map_QM.util.options.mapScale)} 米,预计${mint} 分钟`); // 21 是比例尺 + console.log(`距离目的地 ${parseInt(path.cost / Map_QM.util.options.mapScale)} 米,预计${minTime} 分钟`); // 21 是比例尺 } catch (e) { console.log(e) } @@ -3728,11 +4179,11 @@ MainMap_QM.prototype = { * @api {方法} getAllIcon() 获取所有Icon * @apiGroup 地图数据 * @apiDescription 获取所有Icon - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiParam {int} floorOrder 楼层编号(默认 所有) - * + * * @apiSampleRequest off - * + * */ getAllIcon: function (floorOrder = -1, buildOrder = -1) { let icons = []; @@ -3790,15 +4241,15 @@ MainMap_QM.prototype = { * @api {方法} pathPark() 获取车位点位 * @apiGroup 地图数据 * @apiDescription 获取车位导航点 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiParam {String} shopNum 车位编号 - * + * * @apiSampleRequest off - * + * * @apiParamExample 请求示例 - * + * * Map_QM.pathPark({shopNum:"B1002"}); - * + * * @apiSuccessExample 返回示例 * { * shopNum: 车位编号, node: 导航点, floor: 楼层编号, xaxis: 中心点X坐标, yaxis: 中心点Y坐标 @@ -3812,15 +4263,15 @@ MainMap_QM.prototype = { * @api {方法} pathShopByName() 获取店铺点位 * @apiGroup 地图数据 * @apiDescription 通过店铺名称获取点位 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiParam {String} shopName 店铺名称 - * + * * @apiSampleRequest off - * + * * @apiParamExample 请求示例 - * + * * Map_QM.pathShopByName("金拱门"); - * + * * @apiSuccessExample 返回示例 * { * shopNum: 店铺编号, node: 导航点, floor: 楼层编号, xaxis: 中心点X坐标, yaxis: 中心点Y坐标, comeIn:店铺多门点 @@ -3857,12 +4308,12 @@ MainMap_QM.prototype = { * @api {方法} shopNumToNavPoint() 获取导航点位 * @apiGroup 地图导航 * @apiDescription 通过店铺编号或车位获取导航点位 - * @apiVersion 2.0.0 - * @apiParam {Object} object build,floor,shopNum 楼栋编号,楼层编号,店铺或车位编号 + * @apiVersion 4.0.0 + * @apiParam {Object} object build,floor,shopNum 楼栋编号,楼层编号,店铺或车位编号 * @apiParam {String} type 店铺或车位标识 "shop" "park" - * + * * @apiSampleRequest off - * + * * @apiSuccessExample 返回示例 * { * shopNum: 店铺编号, node: 导航点, floor: 楼层编号, xaxis: 中心点X坐标, yaxis: 中心点Y坐标, comeIn:店铺多门点 @@ -3915,11 +4366,11 @@ MainMap_QM.prototype = { if (!usePath) { usePath = Map_QM.util.pathStateObj.graphPath; } - if(Map_QM.util.overObj.comeIn){ + if (Map_QM.util.overObj.comeIn) { const costall = dijkstra.single_source_shortest_paths(Map_QM.util.pathStateObj.graphPath, startNade, startNade).costs; - if(costall){ + if (costall) { let inArray = Map_QM.util.overObj.comeIn.split(","); - Map_QM.util.overObj.node = Map_QM.getMinCostByArray(Map_QM.util.overObj.floor,inArray, costall); + Map_QM.util.overObj.node = Map_QM.getMinCostByArray(Map_QM.util.overObj.floor, inArray, costall); } } Map_QM.forShopPath(usePath); @@ -4014,9 +4465,9 @@ MainMap_QM.prototype = { * @api {事件} InitPathOver 地图导航状态完成 * @apiGroup 地图事件 * @apiDescription 地图开始导航时触发 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiSampleRequest off - * + * * @apiParamExample 请求示例 * Map_QM.addEventListener("InitPathOver",onInitPathOver,false); */ @@ -4031,22 +4482,22 @@ MainMap_QM.prototype = { this.onFindPathToObj(); } }, - getMinCostByArray:function(floor,array,costall){ - if(!Map_QM.util.startObj){ + getMinCostByArray: function (floor, array, costall) { + if (!Map_QM.util.startObj) { Map_QM.changeStartPoint(); } - if(!Map_QM.util.numBuild){ + if (!Map_QM.util.numBuild) { Map_QM.util.numBuild = 0; } - let mis=-1,nodeP; - for(let i=0; i PathPoint){ + } else { + if (mis > PathPoint) { mis = PathPoint; nodeP = array[i]; } @@ -4211,9 +4662,9 @@ MainMap_QM.prototype = { * @api {事件} PathPlaying 地图导航的实时状态 * @apiGroup 地图事件 * @apiDescription 地图导航过程中实时触发 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiSampleRequest off - * + * * @apiParamExample 请求示例 * Map_QM.addEventListener("PathPlaying",onPathPlaying,false); */ @@ -4342,9 +4793,9 @@ MainMap_QM.prototype = { * @api {事件} PathPlayOver 地图导航完成 * @apiGroup 地图事件 * @apiDescription 地图导航到达目标点时触发 - * @apiVersion 2.0.0 + * @apiVersion 4.0.0 * @apiSampleRequest off - * + * * @apiParamExample 请求示例 * Map_QM.addEventListener("PathPlayOver",onPathPlayOver,false); */ @@ -4377,10 +4828,6 @@ MainMap_QM.prototype = { if (reSet) { //叠层不处理 if (Map_QM.mapArr[Map_QM.util.selectBuild] && Map_QM.mapArr[Map_QM.util.selectBuild].length > 0) { for (let i = 0; i < Map_QM.mapArr[Map_QM.util.selectBuild].length; i++) { - let lines = Map_QM.mapArr[Map_QM.util.selectBuild][i].lineObj; - for (let j = lines.children.length - 1; j >= 0; j--) { - Map_QM.mapArr[Map_QM.util.selectBuild][i].lineObj.remove(lines.children[j]); - } let child = Map_QM.mapArr[Map_QM.util.selectBuild][i].allObj; for (let k = child.children.length - 1; k >= 0; k--) { if (child.children[k].name == "lineDash") { @@ -4441,10 +4888,10 @@ MainMap_QM.prototype = { * @api {方法} pathStop() 导航暂停/播放 * @apiGroup 地图导航 * @apiDescription 导航动画暂停/播放 - * @apiVersion 2.0.0 - * + * @apiVersion 4.0.0 + * * @apiSampleRequest off - * + * */ pathStop: function (isPlaying) { Map_QM.util.pathStateObj.isPathPlay = isPlaying === undefined ? !Map_QM.util.pathStateObj.isPathPlay : isPlaying; @@ -4454,10 +4901,10 @@ MainMap_QM.prototype = { * @api {方法} pathRePlay() 导航动画重播 * @apiGroup 地图导航 * @apiDescription 导航动画重播 - * @apiVersion 2.0.0 - * + * @apiVersion 4.0.0 + * * @apiSampleRequest off - * + * */ pathRePlay: function () { clearTimeout(Map_QM.util.timeObj.pathTime); @@ -4476,16 +4923,16 @@ MainMap_QM.prototype = { * @api {方法} ChangePathByFt() 切换扶梯模式 * @apiGroup 地图导航 * @apiDescription 导航切换扶梯模式 - * @apiVersion 2.0.0 - * + * @apiVersion 4.0.0 + * * @apiParam {function} callBack 回调函数 - * + * * @apiSampleRequest off - * + * * @apiParamExample 请求示例 - * + * * Map_QM.ChangePathByFt(function); - * + * */ ChangePathByFt: function (callBack) { clearTimeout(Map_QM.util.timeObj.pathTime); @@ -4507,16 +4954,16 @@ MainMap_QM.prototype = { * @api {方法} ChangePathByDt() 切换电梯模式 * @apiGroup 地图导航 * @apiDescription 导航切换电梯模式 - * @apiVersion 2.0.0 - * + * @apiVersion 4.0.0 + * * @apiParam {function} callBack 回调函数 - * + * * @apiSampleRequest off - * + * * @apiParamExample 请求示例 - * + * * Map_QM.ChangePathByDt(function); - * + * */ ChangePathByDt: function (callBack) { clearTimeout(Map_QM.util.timeObj.pathTime); @@ -4538,16 +4985,16 @@ MainMap_QM.prototype = { * @api {方法} ChangePathByGood() 切换最佳模式 * @apiGroup 地图导航 * @apiDescription 导航切换最佳模式 - * @apiVersion 2.0.0 - * + * @apiVersion 4.0.0 + * * @apiParam {function} callBack 回调函数 - * + * * @apiSampleRequest off - * + * * @apiParamExample 请求示例 - * + * * Map_QM.ChangePathByGood(function); - * + * */ ChangePathByGood: function (callBack) { clearTimeout(Map_QM.util.timeObj.pathTime); @@ -4577,15 +5024,15 @@ MainMap_QM.prototype = { * @api {方法} changeWindowResize() 窗口变化 * @apiGroup 地图交互 * @apiDescription 窗口变化 - * @apiVersion 2.0.0 - * + * @apiVersion 4.0.0 + * * @apiParam {int} width 窗口宽 * @apiParam {int} height 窗口高 - * + * * @apiSampleRequest off - * + * * @apiParamExample 请求示例 - * + * * Map_QM.changeWindowResize(1280,1080); */ changeWindowResize: function (width, height) { @@ -4598,6 +5045,8 @@ MainMap_QM.prototype = { Map_QM.cameraOrtho.bottom = 340 / -2; Map_QM.cameraOrtho.updateProjectionMatrix(); Map_QM.renderer.setSize(width, height); + let zoom = Map_QM.util.options.showStyle ? 1 : 2; + Map_QM.renderer.setPixelRatio(window.devicePixelRatio * zoom); Map_QM.labelRenderer.setSize(width, height); Map_QM.w = width; Map_QM.h = height; @@ -4607,8 +5056,8 @@ MainMap_QM.prototype = { * @api {方法} init(callBack,options) 地图初始化 * @apiGroup 地图数据 * @apiDescription 初始化地图赋值 Map_QM - * @apiVersion 2.0.0 - * + * @apiVersion 4.0.0 + * * @apiParam {function} callBack 初始化成功后的回调函数 * @apiParam {object} options 初始化对象 * @apiParam {int} options.build 设备所在楼栋编号 默认值6 @@ -4638,7 +5087,7 @@ MainMap_QM.prototype = { * * @apiSampleRequest off * @apiParamExample {String} 请求示例 - * + * * MainMap_QM.init(callBackLoadOver,{build : 0, floor : 3, navPoint : 7, angle : 0, perc_H : "-50%",containerId : "mapContainer"}); */ MainMap_QM.init = function (callBack, options) { @@ -4842,7 +5291,7 @@ FloorMap_QM.prototype = { borderColor = parseInt(mapData.buildArea[i].borderColor.replace("#", "0x"), 16); Map_QM.util.buildHeight = Math.max(parseInt(mapData.buildArea[i].toHeight), Map_QM.util.buildHeight); buildH = parseInt(mapData.buildArea[i].toHeight); - let mash = this.Model_QM.MyModelShape(build, hows, mapData.buildArea[i], entColor, borderColor, 30); + let mash = this.Model_QM.MyPlaneShape(build, hows, mapData.buildArea[i], entColor, borderColor, 30); mash.receiveShadow = true; mash.castShadow = false; mash.userData = { @@ -4868,16 +5317,16 @@ FloorMap_QM.prototype = { logo = ""; showLeb = ""; navRecommend = false; - mapShow=false; + mapShow = false; shopD = {}; if (shopData) { for (let h = 0; h < shopData.length; h++) { let houseNum = iot ? shopData[h].houseNumber : shopData[h].houseNum; if (shopData[h].buildingOrder == this.buildOrder && shopData[h].floorOrder == this.floorOrder) { if (houseNum == mapData.shopArea[i].name) { - show = iot ? shopData[h].shopName : shopData[h].name; + show = shopData[h].shopName || shopData[h].name; showLeb = houseNum; - showE = iot ? shopData[h].shopNameEn : shopData[h].nameEn; + showE = shopData[h].shopNameEn || shopData[h].nameEn; logo = shopData[h].logoPath; mapShow = shopData[h].mapShow ?? false; if (shopData[h].navRecommend) { @@ -4896,13 +5345,9 @@ FloorMap_QM.prototype = { } if (shopData[h].formatColor) { entColor = parseInt(shopData[h].formatColor.replace("#", "0x"), 16); - } else { - entColor = "#eab16e"; } if (shopData[h].borderColor) { borderColor = parseInt(shopData[h].borderColor.replace("#", "0x"), 16); - } else { - borderColor = "#eab16e"; } break; } @@ -4941,8 +5386,8 @@ FloorMap_QM.prototype = { if (mapData.shopArea[i].logoUrl && mapData.shopArea[i].isLabel == 0) { //添加logo this.logoUtil.renderIcon(mapData.shopArea[i], mahc, parseInt(mapData.shopArea[i].toHeight) + parseInt(mapData.shopArea[i].site || 0) + 1); } else { //添加文字 - let some =false; - if(Map_QM.util.options.boxShop.length && Map_QM.util.options.boxShop[0] !== ""){ + let some = false; + if (Map_QM.util.options.boxShop.length && Map_QM.util.options.boxShop[0] !== "") { some = Map_QM.util.options.boxShop.some((item) => { return mapData.shopArea[i].name.includes(item); }); @@ -4950,7 +5395,7 @@ FloorMap_QM.prototype = { if (showLeb != "" || some) { showLeb = mapData.shopArea[i].name; let shopDiv = document.createElement('div'); - shopDiv.className = "map_label" + shopDiv.className = "map_label"; shopDiv.innerHTML = Map_QM.util.options.shopStyle == "shopName" ? show : mapData.shopArea[i].name; shopDiv.dataset.name = show; shopDiv.dataset.nameEn = showE; @@ -4960,6 +5405,7 @@ FloorMap_QM.prototype = { shopLabel.name = mapData.shopArea[i].name; shopLabel.userData.mapShow = mapShow; this.labelObj.add(shopLabel); + //this.labelObj.add(Map_QM.util.getTextMesh(show,new THREE.Vector3(mapData.shopArea[i].xaxis >> 0, -1 * mapData.shopArea[i].yaxis >> 0, parseInt(mapData.shopArea[i].toHeight) + parseInt(mapData.shopArea[i].site || 0)))); } } } @@ -5161,7 +5607,12 @@ FloorMap_QM.prototype = { hollShop.push(Map_QM.util.changeAreaToString(mapData.decos[i].hollArea[k])); } } - let mahc = this.Model_QM.MyModelShape(arr, hollShop, mapData.decos[i], entColor, borderColor, 240); + let mahc; + if(mapData.decos[i].toHeight<3){ + mahc = this.Model_QM.MyPlaneShape(arr, hollShop, mapData.decos[i], entColor, borderColor, 240); + }else{ + mahc = this.Model_QM.MyModelShape(arr, hollShop, mapData.decos[i], entColor, borderColor, 240); + } mahc.xaxis = mapData.decos[i].xaxis >> 0; mahc.yaxis = mapData.decos[i].yaxis >> 0; mahc.node = mapData.decos[i].shopNav; @@ -5531,13 +5982,13 @@ MyModel_QM.prototype.MyModelShape = function (areaArr, howllowArr, opObj, entity let scanGeometry, meshMaterial, options = { depth: parseInt(opObj.toHeight), bevelEnabled: false, - curveSegments: 24 + curveSegments: 12 }; scanGeometry = new THREE.ExtrudeGeometry(shape, options); + let meshColor = new THREE.Color(entityColor); for (let e = 0; e < Map_QM.util.meshMaterialArr.length; e++) { - let color2 = new THREE.Color(entityColor); - if (Map_QM.util.meshMaterialArr[e].color.equals(color2) && Map_QM.util.meshMaterialArr[e].opacity == alphaModle) { + if (Map_QM.util.meshMaterialArr[e].color.equals(meshColor) && Map_QM.util.meshMaterialArr[e].opacity == alphaModle) { meshMaterial = Map_QM.util.meshMaterialArr[e]; } } @@ -5549,7 +6000,6 @@ MyModel_QM.prototype.MyModelShape = function (areaArr, howllowArr, opObj, entity side: THREE.DoubleSide, depthTest: true }); - //meshMaterial.color.convertLinearToGamma(0.4); Map_QM.util.meshMaterialArr.push(meshMaterial); } if (opObj.angleY || opObj.angleZ) { @@ -5557,6 +6007,7 @@ MyModel_QM.prototype.MyModelShape = function (areaArr, howllowArr, opObj, entity } // 创建模型 let mesh = new THREE.Mesh(scanGeometry, meshMaterial); + if (!Map_QM.util.toMapModel && opObj.type != "wall") { let cubeEdges = new THREE.EdgesGeometry(scanGeometry, 60); let cubeLine = new THREE.LineSegments(cubeEdges, material); @@ -5574,6 +6025,88 @@ MyModel_QM.prototype.MyModelShape = function (areaArr, howllowArr, opObj, entity return mesh; } +//绘制平面 +MyModel_QM.prototype.MyPlaneShape = function (areaArr, howllowArr, opObj, entityColor = "#dadada", lineColor = "#eeeeee", indexOrder = 1) { + let len = areaArr.length; + if (len == 0) { + return; + } + let alphaModle = opObj.alphaModle / 100 || 0; + // 实例化shape对象 + let shape = new THREE.Shape(); + // 设置开始点的位置 + shape.moveTo(areaArr[0][0], -1 * areaArr[0][1]); + for (let i = 0; i < areaArr.length; i++) { + if (areaArr[i].length == 4) { + shape.lineTo(areaArr[i][2], -1 * areaArr[i][3]); + } else { + shape.bezierCurveTo(areaArr[i][2], -1 * areaArr[i][3], areaArr[i][4], -1 * areaArr[i][5], areaArr[i][6], -1 * areaArr[i][7]); + } + } + let material; + for (let k = 0; k < Map_QM.util.lineBasicMaterialArr.length; k++) { + let color2 = new THREE.Color(lineColor) + if (Map_QM.util.lineBasicMaterialArr[k].color.equals(color2)) { + material = Map_QM.util.lineBasicMaterialArr[k]; + } + } + if (!material) { + material = new THREE.LineBasicMaterial({ + color: lineColor + }); //材质对象lineColor + Map_QM.util.lineBasicMaterialArr.push(material); + } + if (howllowArr && howllowArr.length > 0) { + for (let n = 0; n < howllowArr.length; n++) { + let hole = new THREE.Path(); // 添加孔洞 + hole.moveTo(howllowArr[n][0][0], -1 * howllowArr[n][0][1]); + for (let k = 0; k < howllowArr[n].length; k++) { + if (howllowArr[n][k].length == 4) { + hole.lineTo(howllowArr[n][k][2], -1 * howllowArr[n][k][3]); + } else { + hole.bezierCurveTo(howllowArr[n][k][2], -1 * howllowArr[n][k][3], howllowArr[n][k][4], -1 * howllowArr[n][k][5], howllowArr[n][k][6], -1 * howllowArr[n][k][7]); + } + } + shape.holes.push(hole); + } + } + let scanGeometry, meshMaterial; + scanGeometry = new THREE.ShapeGeometry(shape, 8); + for (let e = 0; e < Map_QM.util.meshMaterialArr.length; e++) { + let color2 = new THREE.Color(entityColor); + if (Map_QM.util.meshMaterialArr[e].color.equals(color2) && Map_QM.util.meshMaterialArr[e].opacity == alphaModle) { + meshMaterial = Map_QM.util.meshMaterialArr[e]; + } + } + if (!meshMaterial) { + meshMaterial = new THREE.MeshPhongMaterial({ + color: entityColor, + transparent: true, + opacity: alphaModle, + + depthTest: true + }); + Map_QM.util.meshMaterialArr.push(meshMaterial); + } + if (opObj.angleY || opObj.angleZ) { + Map_QM.util.rotateYZ(scanGeometry, opObj.angleY * Math.PI / 180, opObj.angleZ * Math.PI / 180); + } + // 创建模型 + let mesh = new THREE.Mesh(scanGeometry, meshMaterial); + + let cubeEdges = new THREE.EdgesGeometry(scanGeometry, 60); + let cubeLine = new THREE.LineSegments(cubeEdges, material); + cubeLine.renderOrder = indexOrder - 5; + mesh.add(cubeLine); + + mesh.position.z = parseInt(opObj.toHeight)+parseInt(opObj.site); + + mesh.castShadow = true; + mesh.renderOrder = indexOrder; + mesh.name = opObj.name || ""; + return mesh; +} + MyModel_QM.prototype.MyModelText = function (svgArea) { let text = svgArea.data; @@ -5607,19 +6140,12 @@ MyModel_QM.prototype.MyModelText = function (svgArea) { for (let i = 0; i < paths.length; i++) { const path = paths[i]; let shapes = path.toShapes(true); - for (let j = 0; j < shapes.length; j++) { - const shape = shapes[j]; - const geometry = new THREE.ExtrudeBufferGeometry(shape, { - depth: svgArea.toHeight, - bevelEnabled: false, - curveSegments: 24 - }); - const mesh = new THREE.Mesh(geometry, meshMaterial); - mesh.renderOrder = 50; - mesh.name = svgArea.name || ""; - mesh.position.set(-svgArea.width / 2, -svgArea.height / 2, 0); - group.add(mesh); - } + const geometry = new THREE.ShapeGeometry(shapes, 4); + const mesh = new THREE.Mesh(geometry, meshMaterial); + mesh.renderOrder = 50; + mesh.name = svgArea.name || ""; + mesh.position.set(-svgArea.width / 2, -svgArea.height / 2, parseInt(svgArea.toHeight)); + group.add(mesh); } return group; } @@ -5662,57 +6188,58 @@ MySprite_QM.prototype.constructor = MySprite_QM; /** * 渲染公共设施 */ -Facilities_QM = function () { } - -Facilities_QM.prototype.renderIcon = function (obj, _this, isShow = true, ele = null) { - if (obj) { - let spriteMaterial; - let url = Map_QM.util.beforPath + "static/img/" + obj.facCode + ".png"; - if (Map_QM.util.iconUrl.length > 0) { //使用设施库 - for (let i = 0; i < Map_QM.util.iconUrl.length; i++) { - if (Map_QM.util.iconUrl[i].abbreviation == obj.facCode) { - url = Map_QM.util.beforPath + "static/offline" + Map_QM.util.iconUrl[i].filePath +Facilities_QM = function () { + this.renderIcon = function (obj, _this, isShow = true, ele = null) { + if (obj) { + let spriteMaterial; + let url = Map_QM.util.beforPath + "static/img/" + obj.facCode + ".png"; + if (Map_QM.util.iconUrl.length > 0) { //使用设施库 + for (let i = 0; i < Map_QM.util.iconUrl.length; i++) { + if (Map_QM.util.iconUrl[i].abbreviation == obj.facCode) { + url = Map_QM.util.beforPath + "static/offline" + Map_QM.util.iconUrl[i].filePath + } } } - } - for (let m = 0; m < Map_QM.util.spriteMaterialArr.length; m++) { - if (Map_QM.util.spriteMaterialArr[m].name == obj.facCode) { - spriteMaterial = Map_QM.util.spriteMaterialArr[m]; + for (let m = 0; m < Map_QM.util.spriteMaterialArr.length; m++) { + if (Map_QM.util.spriteMaterialArr[m].name == obj.facCode) { + spriteMaterial = Map_QM.util.spriteMaterialArr[m]; + } + } + if (!spriteMaterial) { + let spriteMap = new THREE.TextureLoader().load(url); + spriteMaterial = new THREE.SpriteMaterial({ //sizeAttenuation: false 禁止跟随鼠标缩放 + map: spriteMap, + depthTest: true, + transparent: true, + alphaTest: 0.8 + }); + spriteMaterial.name = obj.facCode; + Map_QM.util.spriteMaterialArr.push(spriteMaterial); + } + + let sprite = new MySprite_QM(spriteMaterial, obj); + sprite.scale.set(64, 64, 1); + sprite.imgUrl = url; + sprite.center = new THREE.Vector2(0.5, 0); + sprite.userData = obj; + sprite.userData.type = "icon"; + sprite.userData.use = ele ? "2d" : "all"; + sprite.userData.model = ele; + sprite.userData.src = url; + sprite.position.set(obj.x, -1 * obj.y, Math.max(55, parseInt(obj.site) || 0)); + sprite.renderOrder = 300; + sprite.visible = isShow; + _this.serObj.add(sprite); + if (Map_QM.util.options.iconName) { + let shopDiv = document.createElement('div'); + shopDiv.className = "map_label" + shopDiv.innerText = obj.title; + shopDiv.dataset.name = obj.title; + shopDiv.dataset.nameEn = Map_QM.util.iconEn[obj.title]; + let shopLabel = new THREE.CSS2DObject(shopDiv); + shopLabel.position.set(obj.x, -1 * obj.y, 30); + _this.iconLabel.add(shopLabel); } - } - if (!spriteMaterial) { - let spriteMap = new THREE.TextureLoader().load(url); - spriteMaterial = new THREE.SpriteMaterial({ //sizeAttenuation: false 禁止跟随鼠标缩放 - map: spriteMap, - depthTest: true, - transparent: true, - }); - spriteMaterial.name = obj.facCode; - Map_QM.util.spriteMaterialArr.push(spriteMaterial); - } - - let sprite = new MySprite_QM(spriteMaterial, obj); - sprite.scale.set(64, 64, 1); - sprite.imgUrl = url; - sprite.center = new THREE.Vector2(0.5, 0); - sprite.userData = obj; - sprite.userData.type = "icon"; - sprite.userData.use = ele ? "2d" : "all"; - sprite.userData.model = ele; - sprite.userData.src = url; - sprite.position.set(obj.x, -1 * obj.y, Math.max(55, parseInt(obj.site) || 0)); - sprite.renderOrder = 300; - sprite.visible = isShow; - _this.serObj.add(sprite); - if (Map_QM.util.options.iconName) { - let shopDiv = document.createElement('div'); - shopDiv.className = "map_label" - shopDiv.innerText = obj.title; - shopDiv.dataset.name = obj.title; - shopDiv.dataset.nameEn = Map_QM.util.iconEn[obj.title]; - let shopLabel = new THREE.CSS2DObject(shopDiv); - shopLabel.position.set(obj.x, -1 * obj.y, 30); - _this.iconLabel.add(shopLabel); } } } @@ -5745,7 +6272,6 @@ ShopLogo_QM = function () { } } } -MySprite_QM.prototype.constructor = MySprite_QM; var _selfFindPath; FindPath_QM = function () { @@ -5834,7 +6360,7 @@ FindPath_QM.prototype.drawPath = function (floorOrder) { } } //this.lineDashed.name = 'lineDash' - this.lineDashed_old = new PathLine(12, linePath, parseInt(Map_QM.util.buildHeight) + 1, 'rgb(169,181,211)', 'rgb(189, 192, 203)', true) + this.lineDashed_old = new PathLine(12, linePath, parseInt(Map_QM.util.buildHeight) + 1, Map_QM.util.options.pathBgColor, Map_QM.util.options.pathBgColor2, true) this.lineDashed_old.renderOrder = 128 Map_QM.mapArr[Map_QM.util.selectBuild][floorOrder].allObj.add(this.lineDashed_old) @@ -5858,7 +6384,7 @@ FindPath_QM.prototype.updateDrawPath = function () { linePath.push([this.pathArr[i].x, -1 * this.pathArr[i].y]) } } - this.lineDashed = new PathLine(12, linePath, parseInt(Map_QM.util.buildHeight) + 2, 'rgb(110, 149, 254)', 'rgb(110,125,254)', false) + this.lineDashed = new PathLine(12, linePath, parseInt(Map_QM.util.buildHeight) + 2, Map_QM.util.options.pathColor, Map_QM.util.options.pathColor2, false) this.lineDashed.renderOrder = 130 Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.add(this.lineDashed); } diff --git a/public/static/qm/three.js b/public/static/qm/three.js index 943d427..f7cecb2 100644 --- a/public/static/qm/three.js +++ b/public/static/qm/three.js @@ -31629,7 +31629,7 @@ THREE.CSS2DRenderer = function () { domElement.style.width = width + 'px'; domElement.style.height = height + 'px'; }; - var renderObject = function ( object, camera ) { + this.renderObject = function ( object, camera ) { if ( object instanceof THREE.CSS2DObject) { vector.setFromMatrixPosition( object.matrixWorld ); vector.applyMatrix4( viewProjectionMatrix ); @@ -31649,7 +31649,7 @@ THREE.CSS2DRenderer = function () { } } for ( var i = 0, l = object.children.length; i < l; i ++ ) { - renderObject( object.children[ i ], camera ); + this.renderObject( object.children[ i ], camera ); } }; var getDistanceToSquared = function () { @@ -31668,7 +31668,7 @@ THREE.CSS2DRenderer = function () { } ); return result; }; - var zOrder = function ( scene ) { + this.zOrder = function ( scene ) { var sorted = filterAndFlatten( scene ).sort( function ( a, b ) { var distanceA = cache.objects.get( a ).distanceToCameraSquared; var distanceB = cache.objects.get( b ).distanceToCameraSquared; @@ -31684,8 +31684,6 @@ THREE.CSS2DRenderer = function () { if ( camera.parent === null ) camera.updateMatrixWorld(); viewMatrix.copy( camera.matrixWorldInverse ); viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, viewMatrix ); - renderObject( scene, camera ); - zOrder( scene ); }; }; THREE.GLTFLoader = ( function () { @@ -39014,4 +39012,90 @@ THREE.LineGeometry.prototype = Object.assign( Object.create( THREE.LineSegmentsG })(); }).call(this); /////////////////////////////////////--------------------------------- dat.gui ---------------------------------------// -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(e.dat={})}(this,function(e){"use strict";function t(e,t){var n=e.__state.conversionName.toString(),o=Math.round(e.r),i=Math.round(e.g),r=Math.round(e.b),s=e.a,a=Math.round(e.h),l=e.s.toFixed(1),d=e.v.toFixed(1);if(t||"THREE_CHAR_HEX"===n||"SIX_CHAR_HEX"===n){for(var c=e.hex.toString(16);c.length<6;)c="0"+c;return"#"+c}return"CSS_RGB"===n?"rgb("+o+","+i+","+r+")":"CSS_RGBA"===n?"rgba("+o+","+i+","+r+","+s+")":"HEX"===n?"0x"+e.hex.toString(16):"RGB_ARRAY"===n?"["+o+","+i+","+r+"]":"RGBA_ARRAY"===n?"["+o+","+i+","+r+","+s+"]":"RGB_OBJ"===n?"{r:"+o+",g:"+i+",b:"+r+"}":"RGBA_OBJ"===n?"{r:"+o+",g:"+i+",b:"+r+",a:"+s+"}":"HSV_OBJ"===n?"{h:"+a+",s:"+l+",v:"+d+"}":"HSVA_OBJ"===n?"{h:"+a+",s:"+l+",v:"+d+",a:"+s+"}":"unknown format"}function n(e,t,n){Object.defineProperty(e,t,{get:function(){return"RGB"===this.__state.space?this.__state[t]:(I.recalculateRGB(this,t,n),this.__state[t])},set:function(e){"RGB"!==this.__state.space&&(I.recalculateRGB(this,t,n),this.__state.space="RGB"),this.__state[t]=e}})}function o(e,t){Object.defineProperty(e,t,{get:function(){return"HSV"===this.__state.space?this.__state[t]:(I.recalculateHSV(this),this.__state[t])},set:function(e){"HSV"!==this.__state.space&&(I.recalculateHSV(this),this.__state.space="HSV"),this.__state[t]=e}})}function i(e){if("0"===e||S.isUndefined(e))return 0;var t=e.match(U);return S.isNull(t)?0:parseFloat(t[1])}function r(e){var t=e.toString();return t.indexOf(".")>-1?t.length-t.indexOf(".")-1:0}function s(e,t){var n=Math.pow(10,t);return Math.round(e*n)/n}function a(e,t,n,o,i){return o+(e-t)/(n-t)*(i-o)}function l(e,t,n,o){e.style.background="",S.each(ee,function(i){e.style.cssText+="background: "+i+"linear-gradient("+t+", "+n+" 0%, "+o+" 100%); "})}function d(e){e.style.background="",e.style.cssText+="background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);",e.style.cssText+="background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",e.style.cssText+="background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",e.style.cssText+="background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",e.style.cssText+="background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"}function c(e,t,n){var o=document.createElement("li");return t&&o.appendChild(t),n?e.__ul.insertBefore(o,n):e.__ul.appendChild(o),e.onResize(),o}function u(e){X.unbind(window,"resize",e.__resizeHandler),e.saveToLocalStorageIfPossible&&X.unbind(window,"unload",e.saveToLocalStorageIfPossible)}function _(e,t){var n=e.__preset_select[e.__preset_select.selectedIndex];n.innerHTML=t?n.value+"*":n.value}function h(e,t,n){if(n.__li=t,n.__gui=e,S.extend(n,{options:function(t){if(arguments.length>1){var o=n.__li.nextElementSibling;return n.remove(),f(e,n.object,n.property,{before:o,factoryArgs:[S.toArray(arguments)]})}if(S.isArray(t)||S.isObject(t)){var i=n.__li.nextElementSibling;return n.remove(),f(e,n.object,n.property,{before:i,factoryArgs:[t]})}},name:function(e){return n.__li.firstElementChild.firstElementChild.innerHTML=e,n},listen:function(){return n.__gui.listen(n),n},remove:function(){return n.__gui.remove(n),n}}),n instanceof q){var o=new Q(n.object,n.property,{min:n.__min,max:n.__max,step:n.__step});S.each(["updateDisplay","onChange","onFinishChange","step","min","max"],function(e){var t=n[e],i=o[e];n[e]=o[e]=function(){var e=Array.prototype.slice.call(arguments);return i.apply(o,e),t.apply(n,e)}}),X.addClass(t,"has-slider"),n.domElement.insertBefore(o.domElement,n.domElement.firstElementChild)}else if(n instanceof Q){var i=function(t){if(S.isNumber(n.__min)&&S.isNumber(n.__max)){var o=n.__li.firstElementChild.firstElementChild.innerHTML,i=n.__gui.__listening.indexOf(n)>-1;n.remove();var r=f(e,n.object,n.property,{before:n.__li.nextElementSibling,factoryArgs:[n.__min,n.__max,n.__step]});return r.name(o),i&&r.listen(),r}return t};n.min=S.compose(i,n.min),n.max=S.compose(i,n.max)}else n instanceof K?(X.bind(t,"click",function(){X.fakeEvent(n.__checkbox,"click")}),X.bind(n.__checkbox,"click",function(e){e.stopPropagation()})):n instanceof Z?(X.bind(t,"click",function(){X.fakeEvent(n.__button,"click")}),X.bind(t,"mouseover",function(){X.addClass(n.__button,"hover")}),X.bind(t,"mouseout",function(){X.removeClass(n.__button,"hover")})):n instanceof $&&(X.addClass(t,"color"),n.updateDisplay=S.compose(function(e){return t.style.borderLeftColor=n.__color.toString(),e},n.updateDisplay),n.updateDisplay());n.setValue=S.compose(function(t){return e.getRoot().__preset_select&&n.isModified()&&_(e.getRoot(),!0),t},n.setValue)}function p(e,t){var n=e.getRoot(),o=n.__rememberedObjects.indexOf(t.object);if(-1!==o){var i=n.__rememberedObjectIndecesToControllers[o];if(void 0===i&&(i={},n.__rememberedObjectIndecesToControllers[o]=i),i[t.property]=t,n.load&&n.load.remembered){var r=n.load.remembered,s=void 0;if(r[e.preset])s=r[e.preset];else{if(!r[se])return;s=r[se]}if(s[o]&&void 0!==s[o][t.property]){var a=s[o][t.property];t.initialValue=a,t.setValue(a)}}}}function f(e,t,n,o){if(void 0===t[n])throw new Error('Object "'+t+'" has no property "'+n+'"');var i=void 0;if(o.color)i=new $(t,n);else{var r=[t,n].concat(o.factoryArgs);i=ne.apply(e,r)}o.before instanceof z&&(o.before=o.before.__li),p(e,i),X.addClass(i.domElement,"c");var s=document.createElement("span");X.addClass(s,"property-name"),s.innerHTML=i.property;var a=document.createElement("div");a.appendChild(s),a.appendChild(i.domElement);var l=c(e,a,o.before);return X.addClass(l,he.CLASS_CONTROLLER_ROW),i instanceof $?X.addClass(l,"color"):X.addClass(l,H(i.getValue())),h(e,l,i),e.__controllers.push(i),i}function m(e,t){return document.location.href+"."+t}function g(e,t,n){var o=document.createElement("option");o.innerHTML=t,o.value=t,e.__preset_select.appendChild(o),n&&(e.__preset_select.selectedIndex=e.__preset_select.length-1)}function b(e,t){t.style.display=e.useLocalStorage?"block":"none"}function v(e){var t=e.__save_row=document.createElement("li");X.addClass(e.domElement,"has-save"),e.__ul.insertBefore(t,e.__ul.firstChild),X.addClass(t,"save-row");var n=document.createElement("span");n.innerHTML=" ",X.addClass(n,"button gears");var o=document.createElement("span");o.innerHTML="Save",X.addClass(o,"button"),X.addClass(o,"save");var i=document.createElement("span");i.innerHTML="New",X.addClass(i,"button"),X.addClass(i,"save-as");var r=document.createElement("span");r.innerHTML="Revert",X.addClass(r,"button"),X.addClass(r,"revert");var s=e.__preset_select=document.createElement("select");if(e.load&&e.load.remembered?S.each(e.load.remembered,function(t,n){g(e,n,n===e.preset)}):g(e,se,!1),X.bind(s,"change",function(){for(var t=0;t=0;n--)t=[e[n].apply(this,t)];return t[0]}},each:function(e,t,n){if(e)if(A&&e.forEach&&e.forEach===A)e.forEach(t,n);else if(e.length===e.length+0){var o=void 0,i=void 0;for(o=0,i=e.length;o1?S.toArray(arguments):arguments[0];return S.each(O,function(t){if(t.litmus(e))return S.each(t.conversions,function(t,n){if(T=t.read(e),!1===L&&!1!==T)return L=T,T.conversionName=n,T.conversion=t,S.BREAK}),S.BREAK}),L},B=void 0,N={hsv_to_rgb:function(e,t,n){var o=Math.floor(e/60)%6,i=e/60-Math.floor(e/60),r=n*(1-t),s=n*(1-i*t),a=n*(1-(1-i)*t),l=[[n,a,r],[s,n,r],[r,n,a],[r,s,n],[a,r,n],[n,r,s]][o];return{r:255*l[0],g:255*l[1],b:255*l[2]}},rgb_to_hsv:function(e,t,n){var o=Math.min(e,t,n),i=Math.max(e,t,n),r=i-o,s=void 0,a=void 0;return 0===i?{h:NaN,s:0,v:0}:(a=r/i,s=e===i?(t-n)/r:t===i?2+(n-e)/r:4+(e-t)/r,(s/=6)<0&&(s+=1),{h:360*s,s:a,v:i/255})},rgb_to_hex:function(e,t,n){var o=this.hex_with_component(0,2,e);return o=this.hex_with_component(o,1,t),o=this.hex_with_component(o,0,n)},component_from_hex:function(e,t){return e>>8*t&255},hex_with_component:function(e,t,n){return n<<(B=8*t)|e&~(255<this.__max&&(n=this.__max),void 0!==this.__step&&n%this.__step!=0&&(n=Math.round(n/this.__step)*this.__step),D(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"setValue",this).call(this,n)}},{key:"min",value:function(e){return this.__min=e,this}},{key:"max",value:function(e){return this.__max=e,this}},{key:"step",value:function(e){return this.__step=e,this.__impliedStep=e,this.__precision=r(e),this}}]),t}(),Q=function(e){function t(e,n,o){function i(){l.__onFinishChange&&l.__onFinishChange.call(l,l.getValue())}function r(e){var t=d-e.clientY;l.setValue(l.getValue()+t*l.__impliedStep),d=e.clientY}function s(){X.unbind(window,"mousemove",r),X.unbind(window,"mouseup",s),i()}F(this,t);var a=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n,o));a.__truncationSuspended=!1;var l=a,d=void 0;return a.__input=document.createElement("input"),a.__input.setAttribute("type","text"),X.bind(a.__input,"change",function(){var e=parseFloat(l.__input.value);S.isNaN(e)||l.setValue(e)}),X.bind(a.__input,"blur",function(){i()}),X.bind(a.__input,"mousedown",function(e){X.bind(window,"mousemove",r),X.bind(window,"mouseup",s),d=e.clientY}),X.bind(a.__input,"keydown",function(e){13===e.keyCode&&(l.__truncationSuspended=!0,this.blur(),l.__truncationSuspended=!1,i())}),a.updateDisplay(),a.domElement.appendChild(a.__input),a}return j(t,W),P(t,[{key:"updateDisplay",value:function(){return this.__input.value=this.__truncationSuspended?this.getValue():s(this.getValue(),this.__precision),D(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"updateDisplay",this).call(this)}}]),t}(),q=function(e){function t(e,n,o,i,r){function s(e){e.preventDefault();var t=_.__background.getBoundingClientRect();return _.setValue(a(e.clientX,t.left,t.right,_.__min,_.__max)),!1}function l(){X.unbind(window,"mousemove",s),X.unbind(window,"mouseup",l),_.__onFinishChange&&_.__onFinishChange.call(_,_.getValue())}function d(e){var t=e.touches[0].clientX,n=_.__background.getBoundingClientRect();_.setValue(a(t,n.left,n.right,_.__min,_.__max))}function c(){X.unbind(window,"touchmove",d),X.unbind(window,"touchend",c),_.__onFinishChange&&_.__onFinishChange.call(_,_.getValue())}F(this,t);var u=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n,{min:o,max:i,step:r})),_=u;return u.__background=document.createElement("div"),u.__foreground=document.createElement("div"),X.bind(u.__background,"mousedown",function(e){document.activeElement.blur(),X.bind(window,"mousemove",s),X.bind(window,"mouseup",l),s(e)}),X.bind(u.__background,"touchstart",function(e){1===e.touches.length&&(X.bind(window,"touchmove",d),X.bind(window,"touchend",c),d(e))}),X.addClass(u.__background,"slider"),X.addClass(u.__foreground,"slider-fg"),u.updateDisplay(),u.__background.appendChild(u.__foreground),u.domElement.appendChild(u.__background),u}return j(t,W),P(t,[{key:"updateDisplay",value:function(){var e=(this.getValue()-this.__min)/(this.__max-this.__min);return this.__foreground.style.width=100*e+"%",D(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"updateDisplay",this).call(this)}}]),t}(),Z=function(e){function t(e,n,o){F(this,t);var i=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n)),r=i;return i.__button=document.createElement("div"),i.__button.innerHTML=void 0===o?"Fire":o,X.bind(i.__button,"click",function(e){return e.preventDefault(),r.fire(),!1}),X.addClass(i.__button,"button"),i.domElement.appendChild(i.__button),i}return j(t,z),P(t,[{key:"fire",value:function(){this.__onChange&&this.__onChange.call(this),this.getValue().call(this.object),this.__onFinishChange&&this.__onFinishChange.call(this,this.getValue())}}]),t}(),$=function(e){function t(e,n){function o(e){u(e),X.bind(window,"mousemove",u),X.bind(window,"touchmove",u),X.bind(window,"mouseup",r),X.bind(window,"touchend",r)}function i(e){_(e),X.bind(window,"mousemove",_),X.bind(window,"touchmove",_),X.bind(window,"mouseup",s),X.bind(window,"touchend",s)}function r(){X.unbind(window,"mousemove",u),X.unbind(window,"touchmove",u),X.unbind(window,"mouseup",r),X.unbind(window,"touchend",r),c()}function s(){X.unbind(window,"mousemove",_),X.unbind(window,"touchmove",_),X.unbind(window,"mouseup",s),X.unbind(window,"touchend",s),c()}function a(){var e=R(this.value);!1!==e?(p.__color.__state=e,p.setValue(p.__color.toOriginal())):this.value=p.__color.toString()}function c(){p.__onFinishChange&&p.__onFinishChange.call(p,p.__color.toOriginal())}function u(e){-1===e.type.indexOf("touch")&&e.preventDefault();var t=p.__saturation_field.getBoundingClientRect(),n=e.touches&&e.touches[0]||e,o=n.clientX,i=n.clientY,r=(o-t.left)/(t.right-t.left),s=1-(i-t.top)/(t.bottom-t.top);return s>1?s=1:s<0&&(s=0),r>1?r=1:r<0&&(r=0),p.__color.v=s,p.__color.s=r,p.setValue(p.__color.toOriginal()),!1}function _(e){-1===e.type.indexOf("touch")&&e.preventDefault();var t=p.__hue_field.getBoundingClientRect(),n=1-((e.touches&&e.touches[0]||e).clientY-t.top)/(t.bottom-t.top);return n>1?n=1:n<0&&(n=0),p.__color.h=360*n,p.setValue(p.__color.toOriginal()),!1}F(this,t);var h=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n));h.__color=new I(h.getValue()),h.__temp=new I(0);var p=h;h.domElement=document.createElement("div"),X.makeSelectable(h.domElement,!1),h.__selector=document.createElement("div"),h.__selector.className="selector",h.__saturation_field=document.createElement("div"),h.__saturation_field.className="saturation-field",h.__field_knob=document.createElement("div"),h.__field_knob.className="field-knob",h.__field_knob_border="2px solid ",h.__hue_knob=document.createElement("div"),h.__hue_knob.className="hue-knob",h.__hue_field=document.createElement("div"),h.__hue_field.className="hue-field",h.__input=document.createElement("input"),h.__input.type="text",h.__input_textShadow="0 1px 1px ",X.bind(h.__input,"keydown",function(e){13===e.keyCode&&a.call(this)}),X.bind(h.__input,"blur",a),X.bind(h.__selector,"mousedown",function(){X.addClass(this,"drag").bind(window,"mouseup",function(){X.removeClass(p.__selector,"drag")})}),X.bind(h.__selector,"touchstart",function(){X.addClass(this,"drag").bind(window,"touchend",function(){X.removeClass(p.__selector,"drag")})});var f=document.createElement("div");return S.extend(h.__selector.style,{width:"122px",height:"102px",padding:"3px",backgroundColor:"#222",boxShadow:"0px 1px 3px rgba(0,0,0,0.3)"}),S.extend(h.__field_knob.style,{position:"absolute",width:"12px",height:"12px",border:h.__field_knob_border+(h.__color.v<.5?"#fff":"#000"),boxShadow:"0px 1px 3px rgba(0,0,0,0.5)",borderRadius:"12px",zIndex:1}),S.extend(h.__hue_knob.style,{position:"absolute",width:"15px",height:"2px",borderRight:"4px solid #fff",zIndex:1}),S.extend(h.__saturation_field.style,{width:"100px",height:"100px",border:"1px solid #555",marginRight:"3px",display:"inline-block",cursor:"pointer"}),S.extend(f.style,{width:"100%",height:"100%",background:"none"}),l(f,"top","rgba(0,0,0,0)","#000"),S.extend(h.__hue_field.style,{width:"15px",height:"100px",border:"1px solid #555",cursor:"ns-resize",position:"absolute",top:"3px",right:"3px"}),d(h.__hue_field),S.extend(h.__input.style,{outline:"none",textAlign:"center",color:"#fff",border:0,fontWeight:"bold",textShadow:h.__input_textShadow+"rgba(0,0,0,0.7)"}),X.bind(h.__saturation_field,"mousedown",o),X.bind(h.__saturation_field,"touchstart",o),X.bind(h.__field_knob,"mousedown",o),X.bind(h.__field_knob,"touchstart",o),X.bind(h.__hue_field,"mousedown",i),X.bind(h.__hue_field,"touchstart",i),h.__saturation_field.appendChild(f),h.__selector.appendChild(h.__field_knob),h.__selector.appendChild(h.__saturation_field),h.__selector.appendChild(h.__hue_field),h.__hue_field.appendChild(h.__hue_knob),h.domElement.appendChild(h.__input),h.domElement.appendChild(h.__selector),h.updateDisplay(),h}return j(t,z),P(t,[{key:"updateDisplay",value:function(){var e=R(this.getValue());if(!1!==e){var t=!1;S.each(I.COMPONENTS,function(n){if(!S.isUndefined(e[n])&&!S.isUndefined(this.__color.__state[n])&&e[n]!==this.__color.__state[n])return t=!0,{}},this),t&&S.extend(this.__color.__state,e)}S.extend(this.__temp.__state,this.__color.__state),this.__temp.a=1;var n=this.__color.v<.5||this.__color.s>.5?255:0,o=255-n;S.extend(this.__field_knob.style,{marginLeft:100*this.__color.s-7+"px",marginTop:100*(1-this.__color.v)-7+"px",backgroundColor:this.__temp.toHexString(),border:this.__field_knob_border+"rgb("+n+","+n+","+n+")"}),this.__hue_knob.style.marginTop=100*(1-this.__color.h/360)+"px",this.__temp.s=1,this.__temp.v=1,l(this.__saturation_field,"left","#fff",this.__temp.toHexString()),this.__input.value=this.__color.toString(),S.extend(this.__input.style,{backgroundColor:this.__color.toHexString(),color:"rgb("+n+","+n+","+n+")",textShadow:this.__input_textShadow+"rgba("+o+","+o+","+o+",.7)"})}}]),t}(),ee=["-moz-","-o-","-webkit-","-ms-",""],te={load:function(e,t){var n=t||document,o=n.createElement("link");o.type="text/css",o.rel="stylesheet",o.href=e,n.getElementsByTagName("head")[0].appendChild(o)},inject:function(e,t){var n=t||document,o=document.createElement("style");o.type="text/css",o.innerHTML=e;var i=n.getElementsByTagName("head")[0];try{i.appendChild(o)}catch(e){}}},ne=function(e,t){var n=e[t];return S.isArray(arguments[2])||S.isObject(arguments[2])?new Y(e,t,arguments[2]):S.isNumber(n)?S.isNumber(arguments[2])&&S.isNumber(arguments[3])?S.isNumber(arguments[4])?new q(e,t,arguments[2],arguments[3],arguments[4]):new q(e,t,arguments[2],arguments[3]):S.isNumber(arguments[4])?new Q(e,t,{min:arguments[2],max:arguments[3],step:arguments[4]}):new Q(e,t,{min:arguments[2],max:arguments[3]}):S.isString(n)?new J(e,t):S.isFunction(n)?new Z(e,t,""):S.isBoolean(n)?new K(e,t):null},oe=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(e){setTimeout(e,1e3/60)},ie=function(){function e(){F(this,e),this.backgroundElement=document.createElement("div"),S.extend(this.backgroundElement.style,{backgroundColor:"rgba(0,0,0,0.8)",top:0,left:0,display:"none",zIndex:"1000",opacity:0,WebkitTransition:"opacity 0.2s linear",transition:"opacity 0.2s linear"}),X.makeFullscreen(this.backgroundElement),this.backgroundElement.style.position="fixed",this.domElement=document.createElement("div"),S.extend(this.domElement.style,{position:"fixed",display:"none",zIndex:"1001",opacity:0,WebkitTransition:"-webkit-transform 0.2s ease-out, opacity 0.2s linear",transition:"transform 0.2s ease-out, opacity 0.2s linear"}),document.body.appendChild(this.backgroundElement),document.body.appendChild(this.domElement);var t=this;X.bind(this.backgroundElement,"click",function(){t.hide()})}return P(e,[{key:"show",value:function(){var e=this;this.backgroundElement.style.display="block",this.domElement.style.display="block",this.domElement.style.opacity=0,this.domElement.style.webkitTransform="scale(1.1)",this.layout(),S.defer(function(){e.backgroundElement.style.opacity=1,e.domElement.style.opacity=1,e.domElement.style.webkitTransform="scale(1)"})}},{key:"hide",value:function(){var e=this,t=function t(){e.domElement.style.display="none",e.backgroundElement.style.display="none",X.unbind(e.domElement,"webkitTransitionEnd",t),X.unbind(e.domElement,"transitionend",t),X.unbind(e.domElement,"oTransitionEnd",t)};X.bind(this.domElement,"webkitTransitionEnd",t),X.bind(this.domElement,"transitionend",t),X.bind(this.domElement,"oTransitionEnd",t),this.backgroundElement.style.opacity=0,this.domElement.style.opacity=0,this.domElement.style.webkitTransform="scale(1.1)"}},{key:"layout",value:function(){this.domElement.style.left=window.innerWidth/2-X.getWidth(this.domElement)/2+"px",this.domElement.style.top=window.innerHeight/2-X.getHeight(this.domElement)/2+"px"}}]),e}(),re=function(e){if(e&&"undefined"!=typeof window){var t=document.createElement("style");return t.setAttribute("type","text/css"),t.innerHTML=e,document.head.appendChild(t),e}}(".dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear;border:0;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button.close-top{position:relative}.dg.main .close-button.close-bottom{position:absolute}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-y:visible}.dg.a.has-save>ul.close-top{margin-top:0}.dg.a.has-save>ul.close-bottom{margin-top:27px}.dg.a.has-save>ul.closed{margin-top:0}.dg.a .save-row{top:0;z-index:1002}.dg.a .save-row.close-top{position:relative}.dg.a .save-row.close-bottom{position:fixed}.dg li{-webkit-transition:height .1s ease-out;-o-transition:height .1s ease-out;-moz-transition:height .1s ease-out;transition:height .1s ease-out;-webkit-transition:overflow .1s linear;-o-transition:overflow .1s linear;-moz-transition:overflow .1s linear;transition:overflow .1s linear}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li>*{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px;overflow:hidden}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .cr.function .property-name{width:100%}.dg .c{float:left;width:60%;position:relative}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:7px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .cr.color{overflow:visible}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.color{border-left:3px solid}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2FA1D6}.dg .cr.number input[type=text]{color:#2FA1D6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2FA1D6;max-width:100%}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\n");te.inject(re);var se="Default",ae=function(){try{return!!window.localStorage}catch(e){return!1}}(),le=void 0,de=!0,ce=void 0,ue=!1,_e=[],he=function e(t){var n=this,o=t||{};this.domElement=document.createElement("div"),this.__ul=document.createElement("ul"),this.domElement.appendChild(this.__ul),X.addClass(this.domElement,"dg"),this.__folders={},this.__controllers=[],this.__rememberedObjects=[],this.__rememberedObjectIndecesToControllers=[],this.__listening=[],o=S.defaults(o,{closeOnTop:!1,autoPlace:!0,width:e.DEFAULT_WIDTH}),o=S.defaults(o,{resizable:o.autoPlace,hideable:o.autoPlace}),S.isUndefined(o.load)?o.load={preset:se}:o.preset&&(o.load.preset=o.preset),S.isUndefined(o.parent)&&o.hideable&&_e.push(this),o.resizable=S.isUndefined(o.parent)&&o.resizable,o.autoPlace&&S.isUndefined(o.scrollable)&&(o.scrollable=!0);var i=ae&&"true"===localStorage.getItem(m(this,"isLocal")),r=void 0,s=void 0;if(Object.defineProperties(this,{parent:{get:function(){return o.parent}},scrollable:{get:function(){return o.scrollable}},autoPlace:{get:function(){return o.autoPlace}},closeOnTop:{get:function(){return o.closeOnTop}},preset:{get:function(){return n.parent?n.getRoot().preset:o.load.preset},set:function(e){n.parent?n.getRoot().preset=e:o.load.preset=e,E(this),n.revert()}},width:{get:function(){return o.width},set:function(e){o.width=e,w(n,e)}},name:{get:function(){return o.name},set:function(e){o.name=e,s&&(s.innerHTML=o.name)}},closed:{get:function(){return o.closed},set:function(t){o.closed=t,o.closed?X.addClass(n.__ul,e.CLASS_CLOSED):X.removeClass(n.__ul,e.CLASS_CLOSED),this.onResize(),n.__closeButton&&(n.__closeButton.innerHTML=t?e.TEXT_OPEN:e.TEXT_CLOSED)}},load:{get:function(){return o.load}},useLocalStorage:{get:function(){return i},set:function(e){ae&&(i=e,e?X.bind(window,"unload",r):X.unbind(window,"unload",r),localStorage.setItem(m(n,"isLocal"),e))}}}),S.isUndefined(o.parent)){if(this.closed=o.closed||!1,X.addClass(this.domElement,e.CLASS_MAIN),X.makeSelectable(this.domElement,!1),ae&&i){n.useLocalStorage=!0;var a=localStorage.getItem(m(this,"gui"));a&&(o.load=JSON.parse(a))}this.__closeButton=document.createElement("div"),this.__closeButton.innerHTML=e.TEXT_CLOSED,X.addClass(this.__closeButton,e.CLASS_CLOSE_BUTTON),o.closeOnTop?(X.addClass(this.__closeButton,e.CLASS_CLOSE_TOP),this.domElement.insertBefore(this.__closeButton,this.domElement.childNodes[0])):(X.addClass(this.__closeButton,e.CLASS_CLOSE_BOTTOM),this.domElement.appendChild(this.__closeButton)),X.bind(this.__closeButton,"click",function(){n.closed=!n.closed})}else{void 0===o.closed&&(o.closed=!0);var l=document.createTextNode(o.name);X.addClass(l,"controller-name"),s=c(n,l);X.addClass(this.__ul,e.CLASS_CLOSED),X.addClass(s,"title"),X.bind(s,"click",function(e){return e.preventDefault(),n.closed=!n.closed,!1}),o.closed||(this.closed=!1)}o.autoPlace&&(S.isUndefined(o.parent)&&(de&&(ce=document.createElement("div"),X.addClass(ce,"dg"),X.addClass(ce,e.CLASS_AUTO_PLACE_CONTAINER),document.body.appendChild(ce),de=!1),ce.appendChild(this.domElement),X.addClass(this.domElement,e.CLASS_AUTO_PLACE)),this.parent||w(n,o.width)),this.__resizeHandler=function(){n.onResizeDebounced()},X.bind(window,"resize",this.__resizeHandler),X.bind(this.__ul,"webkitTransitionEnd",this.__resizeHandler),X.bind(this.__ul,"transitionend",this.__resizeHandler),X.bind(this.__ul,"oTransitionEnd",this.__resizeHandler),this.onResize(),o.resizable&&y(this),r=function(){ae&&"true"===localStorage.getItem(m(n,"isLocal"))&&localStorage.setItem(m(n,"gui"),JSON.stringify(n.getSaveObject()))},this.saveToLocalStorageIfPossible=r,o.parent||function(){var e=n.getRoot();e.width+=1,S.defer(function(){e.width-=1})}()};he.toggleHide=function(){ue=!ue,S.each(_e,function(e){e.domElement.style.display=ue?"none":""})},he.CLASS_AUTO_PLACE="a",he.CLASS_AUTO_PLACE_CONTAINER="ac",he.CLASS_MAIN="main",he.CLASS_CONTROLLER_ROW="cr",he.CLASS_TOO_TALL="taller-than-window",he.CLASS_CLOSED="closed",he.CLASS_CLOSE_BUTTON="close-button",he.CLASS_CLOSE_TOP="close-top",he.CLASS_CLOSE_BOTTOM="close-bottom",he.CLASS_DRAG="drag",he.DEFAULT_WIDTH=245,he.TEXT_CLOSED="Close Controls",he.TEXT_OPEN="Open Controls",he._keydownHandler=function(e){"text"===document.activeElement.type||72!==e.which&&72!==e.keyCode||he.toggleHide()},X.bind(window,"keydown",he._keydownHandler,!1),S.extend(he.prototype,{add:function(e,t){return f(this,e,t,{factoryArgs:Array.prototype.slice.call(arguments,2)})},addColor:function(e,t){return f(this,e,t,{color:!0})},remove:function(e){this.__ul.removeChild(e.__li),this.__controllers.splice(this.__controllers.indexOf(e),1);var t=this;S.defer(function(){t.onResize()})},destroy:function(){if(this.parent)throw new Error("Only the root GUI should be removed with .destroy(). For subfolders, use gui.removeFolder(folder) instead.");this.autoPlace&&ce.removeChild(this.domElement);var e=this;S.each(this.__folders,function(t){e.removeFolder(t)}),X.unbind(window,"keydown",he._keydownHandler,!1),u(this)},addFolder:function(e){if(void 0!==this.__folders[e])throw new Error('You already have a folder in this GUI by the name "'+e+'"');var t={name:e,parent:this};t.autoPlace=this.autoPlace,this.load&&this.load.folders&&this.load.folders[e]&&(t.closed=this.load.folders[e].closed,t.load=this.load.folders[e]);var n=new he(t);this.__folders[e]=n;var o=c(this,n.domElement);return X.addClass(o,"folder"),n},removeFolder:function(e){this.__ul.removeChild(e.domElement.parentElement),delete this.__folders[e.name],this.load&&this.load.folders&&this.load.folders[e.name]&&delete this.load.folders[e.name],u(e);var t=this;S.each(e.__folders,function(t){e.removeFolder(t)}),S.defer(function(){t.onResize()})},open:function(){this.closed=!1},close:function(){this.closed=!0},hide:function(){this.domElement.style.display="none"},show:function(){this.domElement.style.display=""},onResize:function(){var e=this.getRoot();if(e.scrollable){var t=X.getOffset(e.__ul).top,n=0;S.each(e.__ul.childNodes,function(t){e.autoPlace&&t===e.__save_row||(n+=X.getHeight(t))}),window.innerHeight-t-20GUI\'s constructor:\n\n \n\n
\n\n Automatically save\n values to localStorage on exit.\n\n
The values saved to localStorage will\n override those passed to dat.GUI\'s constructor. This makes it\n easier to work incrementally, but localStorage is fragile,\n and your friends may not see the same values you do.\n\n
\n\n
\n\n'),this.parent)throw new Error("You can only call remember on a top level GUI.");var e=this;S.each(Array.prototype.slice.call(arguments),function(t){0===e.__rememberedObjects.length&&v(e),-1===e.__rememberedObjects.indexOf(t)&&e.__rememberedObjects.push(t)}),this.autoPlace&&w(this,this.width)},getRoot:function(){for(var e=this;e.parent;)e=e.parent;return e},getSaveObject:function(){var e=this.load;return e.closed=this.closed,this.__rememberedObjects.length>0&&(e.preset=this.preset,e.remembered||(e.remembered={}),e.remembered[this.preset]=x(this)),e.folders={},S.each(this.__folders,function(t,n){e.folders[n]=t.getSaveObject()}),e},save:function(){this.load.remembered||(this.load.remembered={}),this.load.remembered[this.preset]=x(this),_(this,!1),this.saveToLocalStorageIfPossible()},saveAs:function(e){this.load.remembered||(this.load.remembered={},this.load.remembered[se]=x(this,!0)),this.load.remembered[e]=x(this),this.preset=e,g(this,e,!0),this.saveToLocalStorageIfPossible()},revert:function(e){S.each(this.__controllers,function(t){this.getRoot().load.remembered?p(e||this.getRoot(),t):t.setValue(t.initialValue),t.__onFinishChange&&t.__onFinishChange.call(t,t.getValue())},this),S.each(this.__folders,function(e){e.revert(e)}),e||_(this.getRoot(),!1)},listen:function(e){var t=0===this.__listening.length;this.__listening.push(e),t&&C(this.__listening)},updateDisplay:function(){S.each(this.__controllers,function(e){e.updateDisplay()}),S.each(this.__folders,function(e){e.updateDisplay()})}});var pe={Color:I,math:N,interpret:R},fe={Controller:z,BooleanController:K,OptionController:Y,StringController:J,NumberController:W,NumberControllerBox:Q,NumberControllerSlider:q,FunctionController:Z,ColorController:$},me={dom:X},ge={GUI:he},be=he,ve={color:pe,controllers:fe,dom:me,gui:ge,GUI:be};e.color=pe,e.controllers=fe,e.dom=me,e.gui=ge,e.GUI=be,e.default=ve,Object.defineProperty(e,"__esModule",{value:!0})}); \ No newline at end of file +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(e.dat={})}(this,function(e){"use strict";function t(e,t){var n=e.__state.conversionName.toString(),o=Math.round(e.r),i=Math.round(e.g),r=Math.round(e.b),s=e.a,a=Math.round(e.h),l=e.s.toFixed(1),d=e.v.toFixed(1);if(t||"THREE_CHAR_HEX"===n||"SIX_CHAR_HEX"===n){for(var c=e.hex.toString(16);c.length<6;)c="0"+c;return"#"+c}return"CSS_RGB"===n?"rgb("+o+","+i+","+r+")":"CSS_RGBA"===n?"rgba("+o+","+i+","+r+","+s+")":"HEX"===n?"0x"+e.hex.toString(16):"RGB_ARRAY"===n?"["+o+","+i+","+r+"]":"RGBA_ARRAY"===n?"["+o+","+i+","+r+","+s+"]":"RGB_OBJ"===n?"{r:"+o+",g:"+i+",b:"+r+"}":"RGBA_OBJ"===n?"{r:"+o+",g:"+i+",b:"+r+",a:"+s+"}":"HSV_OBJ"===n?"{h:"+a+",s:"+l+",v:"+d+"}":"HSVA_OBJ"===n?"{h:"+a+",s:"+l+",v:"+d+",a:"+s+"}":"unknown format"}function n(e,t,n){Object.defineProperty(e,t,{get:function(){return"RGB"===this.__state.space?this.__state[t]:(I.recalculateRGB(this,t,n),this.__state[t])},set:function(e){"RGB"!==this.__state.space&&(I.recalculateRGB(this,t,n),this.__state.space="RGB"),this.__state[t]=e}})}function o(e,t){Object.defineProperty(e,t,{get:function(){return"HSV"===this.__state.space?this.__state[t]:(I.recalculateHSV(this),this.__state[t])},set:function(e){"HSV"!==this.__state.space&&(I.recalculateHSV(this),this.__state.space="HSV"),this.__state[t]=e}})}function i(e){if("0"===e||S.isUndefined(e))return 0;var t=e.match(U);return S.isNull(t)?0:parseFloat(t[1])}function r(e){var t=e.toString();return t.indexOf(".")>-1?t.length-t.indexOf(".")-1:0}function s(e,t){var n=Math.pow(10,t);return Math.round(e*n)/n}function a(e,t,n,o,i){return o+(e-t)/(n-t)*(i-o)}function l(e,t,n,o){e.style.background="",S.each(ee,function(i){e.style.cssText+="background: "+i+"linear-gradient("+t+", "+n+" 0%, "+o+" 100%); "})}function d(e){e.style.background="",e.style.cssText+="background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);",e.style.cssText+="background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",e.style.cssText+="background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",e.style.cssText+="background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",e.style.cssText+="background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"}function c(e,t,n){var o=document.createElement("li");return t&&o.appendChild(t),n?e.__ul.insertBefore(o,n):e.__ul.appendChild(o),e.onResize(),o}function u(e){X.unbind(window,"resize",e.__resizeHandler),e.saveToLocalStorageIfPossible&&X.unbind(window,"unload",e.saveToLocalStorageIfPossible)}function _(e,t){var n=e.__preset_select[e.__preset_select.selectedIndex];n.innerHTML=t?n.value+"*":n.value}function h(e,t,n){if(n.__li=t,n.__gui=e,S.extend(n,{options:function(t){if(arguments.length>1){var o=n.__li.nextElementSibling;return n.remove(),f(e,n.object,n.property,{before:o,factoryArgs:[S.toArray(arguments)]})}if(S.isArray(t)||S.isObject(t)){var i=n.__li.nextElementSibling;return n.remove(),f(e,n.object,n.property,{before:i,factoryArgs:[t]})}},name:function(e){return n.__li.firstElementChild.firstElementChild.innerHTML=e,n},listen:function(){return n.__gui.listen(n),n},remove:function(){return n.__gui.remove(n),n}}),n instanceof q){var o=new Q(n.object,n.property,{min:n.__min,max:n.__max,step:n.__step});S.each(["updateDisplay","onChange","onFinishChange","step","min","max"],function(e){var t=n[e],i=o[e];n[e]=o[e]=function(){var e=Array.prototype.slice.call(arguments);return i.apply(o,e),t.apply(n,e)}}),X.addClass(t,"has-slider"),n.domElement.insertBefore(o.domElement,n.domElement.firstElementChild)}else if(n instanceof Q){var i=function(t){if(S.isNumber(n.__min)&&S.isNumber(n.__max)){var o=n.__li.firstElementChild.firstElementChild.innerHTML,i=n.__gui.__listening.indexOf(n)>-1;n.remove();var r=f(e,n.object,n.property,{before:n.__li.nextElementSibling,factoryArgs:[n.__min,n.__max,n.__step]});return r.name(o),i&&r.listen(),r}return t};n.min=S.compose(i,n.min),n.max=S.compose(i,n.max)}else n instanceof K?(X.bind(t,"click",function(){X.fakeEvent(n.__checkbox,"click")}),X.bind(n.__checkbox,"click",function(e){e.stopPropagation()})):n instanceof Z?(X.bind(t,"click",function(){X.fakeEvent(n.__button,"click")}),X.bind(t,"mouseover",function(){X.addClass(n.__button,"hover")}),X.bind(t,"mouseout",function(){X.removeClass(n.__button,"hover")})):n instanceof $&&(X.addClass(t,"color"),n.updateDisplay=S.compose(function(e){return t.style.borderLeftColor=n.__color.toString(),e},n.updateDisplay),n.updateDisplay());n.setValue=S.compose(function(t){return e.getRoot().__preset_select&&n.isModified()&&_(e.getRoot(),!0),t},n.setValue)}function p(e,t){var n=e.getRoot(),o=n.__rememberedObjects.indexOf(t.object);if(-1!==o){var i=n.__rememberedObjectIndecesToControllers[o];if(void 0===i&&(i={},n.__rememberedObjectIndecesToControllers[o]=i),i[t.property]=t,n.load&&n.load.remembered){var r=n.load.remembered,s=void 0;if(r[e.preset])s=r[e.preset];else{if(!r[se])return;s=r[se]}if(s[o]&&void 0!==s[o][t.property]){var a=s[o][t.property];t.initialValue=a,t.setValue(a)}}}}function f(e,t,n,o){if(void 0===t[n])throw new Error('Object "'+t+'" has no property "'+n+'"');var i=void 0;if(o.color)i=new $(t,n);else{var r=[t,n].concat(o.factoryArgs);i=ne.apply(e,r)}o.before instanceof z&&(o.before=o.before.__li),p(e,i),X.addClass(i.domElement,"c");var s=document.createElement("span");X.addClass(s,"property-name"),s.innerHTML=i.property;var a=document.createElement("div");a.appendChild(s),a.appendChild(i.domElement);var l=c(e,a,o.before);return X.addClass(l,he.CLASS_CONTROLLER_ROW),i instanceof $?X.addClass(l,"color"):X.addClass(l,H(i.getValue())),h(e,l,i),e.__controllers.push(i),i}function m(e,t){return document.location.href+"."+t}function g(e,t,n){var o=document.createElement("option");o.innerHTML=t,o.value=t,e.__preset_select.appendChild(o),n&&(e.__preset_select.selectedIndex=e.__preset_select.length-1)}function b(e,t){t.style.display=e.useLocalStorage?"block":"none"}function v(e){var t=e.__save_row=document.createElement("li");X.addClass(e.domElement,"has-save"),e.__ul.insertBefore(t,e.__ul.firstChild),X.addClass(t,"save-row");var n=document.createElement("span");n.innerHTML=" ",X.addClass(n,"button gears");var o=document.createElement("span");o.innerHTML="Save",X.addClass(o,"button"),X.addClass(o,"save");var i=document.createElement("span");i.innerHTML="New",X.addClass(i,"button"),X.addClass(i,"save-as");var r=document.createElement("span");r.innerHTML="Revert",X.addClass(r,"button"),X.addClass(r,"revert");var s=e.__preset_select=document.createElement("select");if(e.load&&e.load.remembered?S.each(e.load.remembered,function(t,n){g(e,n,n===e.preset)}):g(e,se,!1),X.bind(s,"change",function(){for(var t=0;t=0;n--)t=[e[n].apply(this,t)];return t[0]}},each:function(e,t,n){if(e)if(A&&e.forEach&&e.forEach===A)e.forEach(t,n);else if(e.length===e.length+0){var o=void 0,i=void 0;for(o=0,i=e.length;o1?S.toArray(arguments):arguments[0];return S.each(O,function(t){if(t.litmus(e))return S.each(t.conversions,function(t,n){if(T=t.read(e),!1===L&&!1!==T)return L=T,T.conversionName=n,T.conversion=t,S.BREAK}),S.BREAK}),L},B=void 0,N={hsv_to_rgb:function(e,t,n){var o=Math.floor(e/60)%6,i=e/60-Math.floor(e/60),r=n*(1-t),s=n*(1-i*t),a=n*(1-(1-i)*t),l=[[n,a,r],[s,n,r],[r,n,a],[r,s,n],[a,r,n],[n,r,s]][o];return{r:255*l[0],g:255*l[1],b:255*l[2]}},rgb_to_hsv:function(e,t,n){var o=Math.min(e,t,n),i=Math.max(e,t,n),r=i-o,s=void 0,a=void 0;return 0===i?{h:NaN,s:0,v:0}:(a=r/i,s=e===i?(t-n)/r:t===i?2+(n-e)/r:4+(e-t)/r,(s/=6)<0&&(s+=1),{h:360*s,s:a,v:i/255})},rgb_to_hex:function(e,t,n){var o=this.hex_with_component(0,2,e);return o=this.hex_with_component(o,1,t),o=this.hex_with_component(o,0,n)},component_from_hex:function(e,t){return e>>8*t&255},hex_with_component:function(e,t,n){return n<<(B=8*t)|e&~(255<this.__max&&(n=this.__max),void 0!==this.__step&&n%this.__step!=0&&(n=Math.round(n/this.__step)*this.__step),D(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"setValue",this).call(this,n)}},{key:"min",value:function(e){return this.__min=e,this}},{key:"max",value:function(e){return this.__max=e,this}},{key:"step",value:function(e){return this.__step=e,this.__impliedStep=e,this.__precision=r(e),this}}]),t}(),Q=function(e){function t(e,n,o){function i(){l.__onFinishChange&&l.__onFinishChange.call(l,l.getValue())}function r(e){var t=d-e.clientY;l.setValue(l.getValue()+t*l.__impliedStep),d=e.clientY}function s(){X.unbind(window,"mousemove",r),X.unbind(window,"mouseup",s),i()}F(this,t);var a=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n,o));a.__truncationSuspended=!1;var l=a,d=void 0;return a.__input=document.createElement("input"),a.__input.setAttribute("type","text"),X.bind(a.__input,"change",function(){var e=parseFloat(l.__input.value);S.isNaN(e)||l.setValue(e)}),X.bind(a.__input,"blur",function(){i()}),X.bind(a.__input,"mousedown",function(e){X.bind(window,"mousemove",r),X.bind(window,"mouseup",s),d=e.clientY}),X.bind(a.__input,"keydown",function(e){13===e.keyCode&&(l.__truncationSuspended=!0,this.blur(),l.__truncationSuspended=!1,i())}),a.updateDisplay(),a.domElement.appendChild(a.__input),a}return j(t,W),P(t,[{key:"updateDisplay",value:function(){return this.__input.value=this.__truncationSuspended?this.getValue():s(this.getValue(),this.__precision),D(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"updateDisplay",this).call(this)}}]),t}(),q=function(e){function t(e,n,o,i,r){function s(e){e.preventDefault();var t=_.__background.getBoundingClientRect();return _.setValue(a(e.clientX,t.left,t.right,_.__min,_.__max)),!1}function l(){X.unbind(window,"mousemove",s),X.unbind(window,"mouseup",l),_.__onFinishChange&&_.__onFinishChange.call(_,_.getValue())}function d(e){var t=e.touches[0].clientX,n=_.__background.getBoundingClientRect();_.setValue(a(t,n.left,n.right,_.__min,_.__max))}function c(){X.unbind(window,"touchmove",d),X.unbind(window,"touchend",c),_.__onFinishChange&&_.__onFinishChange.call(_,_.getValue())}F(this,t);var u=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n,{min:o,max:i,step:r})),_=u;return u.__background=document.createElement("div"),u.__foreground=document.createElement("div"),X.bind(u.__background,"mousedown",function(e){document.activeElement.blur(),X.bind(window,"mousemove",s),X.bind(window,"mouseup",l),s(e)}),X.bind(u.__background,"touchstart",function(e){1===e.touches.length&&(X.bind(window,"touchmove",d),X.bind(window,"touchend",c),d(e))}),X.addClass(u.__background,"slider"),X.addClass(u.__foreground,"slider-fg"),u.updateDisplay(),u.__background.appendChild(u.__foreground),u.domElement.appendChild(u.__background),u}return j(t,W),P(t,[{key:"updateDisplay",value:function(){var e=(this.getValue()-this.__min)/(this.__max-this.__min);return this.__foreground.style.width=100*e+"%",D(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"updateDisplay",this).call(this)}}]),t}(),Z=function(e){function t(e,n,o){F(this,t);var i=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n)),r=i;return i.__button=document.createElement("div"),i.__button.innerHTML=void 0===o?"Fire":o,X.bind(i.__button,"click",function(e){return e.preventDefault(),r.fire(),!1}),X.addClass(i.__button,"button"),i.domElement.appendChild(i.__button),i}return j(t,z),P(t,[{key:"fire",value:function(){this.__onChange&&this.__onChange.call(this),this.getValue().call(this.object),this.__onFinishChange&&this.__onFinishChange.call(this,this.getValue())}}]),t}(),$=function(e){function t(e,n){function o(e){u(e),X.bind(window,"mousemove",u),X.bind(window,"touchmove",u),X.bind(window,"mouseup",r),X.bind(window,"touchend",r)}function i(e){_(e),X.bind(window,"mousemove",_),X.bind(window,"touchmove",_),X.bind(window,"mouseup",s),X.bind(window,"touchend",s)}function r(){X.unbind(window,"mousemove",u),X.unbind(window,"touchmove",u),X.unbind(window,"mouseup",r),X.unbind(window,"touchend",r),c()}function s(){X.unbind(window,"mousemove",_),X.unbind(window,"touchmove",_),X.unbind(window,"mouseup",s),X.unbind(window,"touchend",s),c()}function a(){var e=R(this.value);!1!==e?(p.__color.__state=e,p.setValue(p.__color.toOriginal())):this.value=p.__color.toString()}function c(){p.__onFinishChange&&p.__onFinishChange.call(p,p.__color.toOriginal())}function u(e){-1===e.type.indexOf("touch")&&e.preventDefault();var t=p.__saturation_field.getBoundingClientRect(),n=e.touches&&e.touches[0]||e,o=n.clientX,i=n.clientY,r=(o-t.left)/(t.right-t.left),s=1-(i-t.top)/(t.bottom-t.top);return s>1?s=1:s<0&&(s=0),r>1?r=1:r<0&&(r=0),p.__color.v=s,p.__color.s=r,p.setValue(p.__color.toOriginal()),!1}function _(e){-1===e.type.indexOf("touch")&&e.preventDefault();var t=p.__hue_field.getBoundingClientRect(),n=1-((e.touches&&e.touches[0]||e).clientY-t.top)/(t.bottom-t.top);return n>1?n=1:n<0&&(n=0),p.__color.h=360*n,p.setValue(p.__color.toOriginal()),!1}F(this,t);var h=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n));h.__color=new I(h.getValue()),h.__temp=new I(0);var p=h;h.domElement=document.createElement("div"),X.makeSelectable(h.domElement,!1),h.__selector=document.createElement("div"),h.__selector.className="selector",h.__saturation_field=document.createElement("div"),h.__saturation_field.className="saturation-field",h.__field_knob=document.createElement("div"),h.__field_knob.className="field-knob",h.__field_knob_border="2px solid ",h.__hue_knob=document.createElement("div"),h.__hue_knob.className="hue-knob",h.__hue_field=document.createElement("div"),h.__hue_field.className="hue-field",h.__input=document.createElement("input"),h.__input.type="text",h.__input_textShadow="0 1px 1px ",X.bind(h.__input,"keydown",function(e){13===e.keyCode&&a.call(this)}),X.bind(h.__input,"blur",a),X.bind(h.__selector,"mousedown",function(){X.addClass(this,"drag").bind(window,"mouseup",function(){X.removeClass(p.__selector,"drag")})}),X.bind(h.__selector,"touchstart",function(){X.addClass(this,"drag").bind(window,"touchend",function(){X.removeClass(p.__selector,"drag")})});var f=document.createElement("div");return S.extend(h.__selector.style,{width:"122px",height:"102px",padding:"3px",backgroundColor:"#222",boxShadow:"0px 1px 3px rgba(0,0,0,0.3)"}),S.extend(h.__field_knob.style,{position:"absolute",width:"12px",height:"12px",border:h.__field_knob_border+(h.__color.v<.5?"#fff":"#000"),boxShadow:"0px 1px 3px rgba(0,0,0,0.5)",borderRadius:"12px",zIndex:1}),S.extend(h.__hue_knob.style,{position:"absolute",width:"15px",height:"2px",borderRight:"4px solid #fff",zIndex:1}),S.extend(h.__saturation_field.style,{width:"100px",height:"100px",border:"1px solid #555",marginRight:"3px",display:"inline-block",cursor:"pointer"}),S.extend(f.style,{width:"100%",height:"100%",background:"none"}),l(f,"top","rgba(0,0,0,0)","#000"),S.extend(h.__hue_field.style,{width:"15px",height:"100px",border:"1px solid #555",cursor:"ns-resize",position:"absolute",top:"3px",right:"3px"}),d(h.__hue_field),S.extend(h.__input.style,{outline:"none",textAlign:"center",color:"#fff",border:0,fontWeight:"bold",textShadow:h.__input_textShadow+"rgba(0,0,0,0.7)"}),X.bind(h.__saturation_field,"mousedown",o),X.bind(h.__saturation_field,"touchstart",o),X.bind(h.__field_knob,"mousedown",o),X.bind(h.__field_knob,"touchstart",o),X.bind(h.__hue_field,"mousedown",i),X.bind(h.__hue_field,"touchstart",i),h.__saturation_field.appendChild(f),h.__selector.appendChild(h.__field_knob),h.__selector.appendChild(h.__saturation_field),h.__selector.appendChild(h.__hue_field),h.__hue_field.appendChild(h.__hue_knob),h.domElement.appendChild(h.__input),h.domElement.appendChild(h.__selector),h.updateDisplay(),h}return j(t,z),P(t,[{key:"updateDisplay",value:function(){var e=R(this.getValue());if(!1!==e){var t=!1;S.each(I.COMPONENTS,function(n){if(!S.isUndefined(e[n])&&!S.isUndefined(this.__color.__state[n])&&e[n]!==this.__color.__state[n])return t=!0,{}},this),t&&S.extend(this.__color.__state,e)}S.extend(this.__temp.__state,this.__color.__state),this.__temp.a=1;var n=this.__color.v<.5||this.__color.s>.5?255:0,o=255-n;S.extend(this.__field_knob.style,{marginLeft:100*this.__color.s-7+"px",marginTop:100*(1-this.__color.v)-7+"px",backgroundColor:this.__temp.toHexString(),border:this.__field_knob_border+"rgb("+n+","+n+","+n+")"}),this.__hue_knob.style.marginTop=100*(1-this.__color.h/360)+"px",this.__temp.s=1,this.__temp.v=1,l(this.__saturation_field,"left","#fff",this.__temp.toHexString()),this.__input.value=this.__color.toString(),S.extend(this.__input.style,{backgroundColor:this.__color.toHexString(),color:"rgb("+n+","+n+","+n+")",textShadow:this.__input_textShadow+"rgba("+o+","+o+","+o+",.7)"})}}]),t}(),ee=["-moz-","-o-","-webkit-","-ms-",""],te={load:function(e,t){var n=t||document,o=n.createElement("link");o.type="text/css",o.rel="stylesheet",o.href=e,n.getElementsByTagName("head")[0].appendChild(o)},inject:function(e,t){var n=t||document,o=document.createElement("style");o.type="text/css",o.innerHTML=e;var i=n.getElementsByTagName("head")[0];try{i.appendChild(o)}catch(e){}}},ne=function(e,t){var n=e[t];return S.isArray(arguments[2])||S.isObject(arguments[2])?new Y(e,t,arguments[2]):S.isNumber(n)?S.isNumber(arguments[2])&&S.isNumber(arguments[3])?S.isNumber(arguments[4])?new q(e,t,arguments[2],arguments[3],arguments[4]):new q(e,t,arguments[2],arguments[3]):S.isNumber(arguments[4])?new Q(e,t,{min:arguments[2],max:arguments[3],step:arguments[4]}):new Q(e,t,{min:arguments[2],max:arguments[3]}):S.isString(n)?new J(e,t):S.isFunction(n)?new Z(e,t,""):S.isBoolean(n)?new K(e,t):null},oe=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(e){setTimeout(e,1e3/60)},ie=function(){function e(){F(this,e),this.backgroundElement=document.createElement("div"),S.extend(this.backgroundElement.style,{backgroundColor:"rgba(0,0,0,0.8)",top:0,left:0,display:"none",zIndex:"1000",opacity:0,WebkitTransition:"opacity 0.2s linear",transition:"opacity 0.2s linear"}),X.makeFullscreen(this.backgroundElement),this.backgroundElement.style.position="fixed",this.domElement=document.createElement("div"),S.extend(this.domElement.style,{position:"fixed",display:"none",zIndex:"1001",opacity:0,WebkitTransition:"-webkit-transform 0.2s ease-out, opacity 0.2s linear",transition:"transform 0.2s ease-out, opacity 0.2s linear"}),document.body.appendChild(this.backgroundElement),document.body.appendChild(this.domElement);var t=this;X.bind(this.backgroundElement,"click",function(){t.hide()})}return P(e,[{key:"show",value:function(){var e=this;this.backgroundElement.style.display="block",this.domElement.style.display="block",this.domElement.style.opacity=0,this.domElement.style.webkitTransform="scale(1.1)",this.layout(),S.defer(function(){e.backgroundElement.style.opacity=1,e.domElement.style.opacity=1,e.domElement.style.webkitTransform="scale(1)"})}},{key:"hide",value:function(){var e=this,t=function t(){e.domElement.style.display="none",e.backgroundElement.style.display="none",X.unbind(e.domElement,"webkitTransitionEnd",t),X.unbind(e.domElement,"transitionend",t),X.unbind(e.domElement,"oTransitionEnd",t)};X.bind(this.domElement,"webkitTransitionEnd",t),X.bind(this.domElement,"transitionend",t),X.bind(this.domElement,"oTransitionEnd",t),this.backgroundElement.style.opacity=0,this.domElement.style.opacity=0,this.domElement.style.webkitTransform="scale(1.1)"}},{key:"layout",value:function(){this.domElement.style.left=window.innerWidth/2-X.getWidth(this.domElement)/2+"px",this.domElement.style.top=window.innerHeight/2-X.getHeight(this.domElement)/2+"px"}}]),e}(),re=function(e){if(e&&"undefined"!=typeof window){var t=document.createElement("style");return t.setAttribute("type","text/css"),t.innerHTML=e,document.head.appendChild(t),e}}(".dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear;border:0;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button.close-top{position:relative}.dg.main .close-button.close-bottom{position:absolute}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-y:visible}.dg.a.has-save>ul.close-top{margin-top:0}.dg.a.has-save>ul.close-bottom{margin-top:27px}.dg.a.has-save>ul.closed{margin-top:0}.dg.a .save-row{top:0;z-index:1002}.dg.a .save-row.close-top{position:relative}.dg.a .save-row.close-bottom{position:fixed}.dg li{-webkit-transition:height .1s ease-out;-o-transition:height .1s ease-out;-moz-transition:height .1s ease-out;transition:height .1s ease-out;-webkit-transition:overflow .1s linear;-o-transition:overflow .1s linear;-moz-transition:overflow .1s linear;transition:overflow .1s linear}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li>*{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px;overflow:hidden}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .cr.function .property-name{width:100%}.dg .c{float:left;width:60%;position:relative}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:7px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .cr.color{overflow:visible}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.color{border-left:3px solid}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2FA1D6}.dg .cr.number input[type=text]{color:#2FA1D6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2FA1D6;max-width:100%}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\n");te.inject(re);var se="Default",ae=function(){try{return!!window.localStorage}catch(e){return!1}}(),le=void 0,de=!0,ce=void 0,ue=!1,_e=[],he=function e(t){var n=this,o=t||{};this.domElement=document.createElement("div"),this.__ul=document.createElement("ul"),this.domElement.appendChild(this.__ul),X.addClass(this.domElement,"dg"),this.__folders={},this.__controllers=[],this.__rememberedObjects=[],this.__rememberedObjectIndecesToControllers=[],this.__listening=[],o=S.defaults(o,{closeOnTop:!1,autoPlace:!0,width:e.DEFAULT_WIDTH}),o=S.defaults(o,{resizable:o.autoPlace,hideable:o.autoPlace}),S.isUndefined(o.load)?o.load={preset:se}:o.preset&&(o.load.preset=o.preset),S.isUndefined(o.parent)&&o.hideable&&_e.push(this),o.resizable=S.isUndefined(o.parent)&&o.resizable,o.autoPlace&&S.isUndefined(o.scrollable)&&(o.scrollable=!0);var i=ae&&"true"===localStorage.getItem(m(this,"isLocal")),r=void 0,s=void 0;if(Object.defineProperties(this,{parent:{get:function(){return o.parent}},scrollable:{get:function(){return o.scrollable}},autoPlace:{get:function(){return o.autoPlace}},closeOnTop:{get:function(){return o.closeOnTop}},preset:{get:function(){return n.parent?n.getRoot().preset:o.load.preset},set:function(e){n.parent?n.getRoot().preset=e:o.load.preset=e,E(this),n.revert()}},width:{get:function(){return o.width},set:function(e){o.width=e,w(n,e)}},name:{get:function(){return o.name},set:function(e){o.name=e,s&&(s.innerHTML=o.name)}},closed:{get:function(){return o.closed},set:function(t){o.closed=t,o.closed?X.addClass(n.__ul,e.CLASS_CLOSED):X.removeClass(n.__ul,e.CLASS_CLOSED),this.onResize(),n.__closeButton&&(n.__closeButton.innerHTML=t?e.TEXT_OPEN:e.TEXT_CLOSED)}},load:{get:function(){return o.load}},useLocalStorage:{get:function(){return i},set:function(e){ae&&(i=e,e?X.bind(window,"unload",r):X.unbind(window,"unload",r),localStorage.setItem(m(n,"isLocal"),e))}}}),S.isUndefined(o.parent)){if(this.closed=o.closed||!1,X.addClass(this.domElement,e.CLASS_MAIN),X.makeSelectable(this.domElement,!1),ae&&i){n.useLocalStorage=!0;var a=localStorage.getItem(m(this,"gui"));a&&(o.load=JSON.parse(a))}this.__closeButton=document.createElement("div"),this.__closeButton.innerHTML=e.TEXT_CLOSED,X.addClass(this.__closeButton,e.CLASS_CLOSE_BUTTON),o.closeOnTop?(X.addClass(this.__closeButton,e.CLASS_CLOSE_TOP),this.domElement.insertBefore(this.__closeButton,this.domElement.childNodes[0])):(X.addClass(this.__closeButton,e.CLASS_CLOSE_BOTTOM),this.domElement.appendChild(this.__closeButton)),X.bind(this.__closeButton,"click",function(){n.closed=!n.closed})}else{void 0===o.closed&&(o.closed=!0);var l=document.createTextNode(o.name);X.addClass(l,"controller-name"),s=c(n,l);X.addClass(this.__ul,e.CLASS_CLOSED),X.addClass(s,"title"),X.bind(s,"click",function(e){return e.preventDefault(),n.closed=!n.closed,!1}),o.closed||(this.closed=!1)}o.autoPlace&&(S.isUndefined(o.parent)&&(de&&(ce=document.createElement("div"),X.addClass(ce,"dg"),X.addClass(ce,e.CLASS_AUTO_PLACE_CONTAINER),document.body.appendChild(ce),de=!1),ce.appendChild(this.domElement),X.addClass(this.domElement,e.CLASS_AUTO_PLACE)),this.parent||w(n,o.width)),this.__resizeHandler=function(){n.onResizeDebounced()},X.bind(window,"resize",this.__resizeHandler),X.bind(this.__ul,"webkitTransitionEnd",this.__resizeHandler),X.bind(this.__ul,"transitionend",this.__resizeHandler),X.bind(this.__ul,"oTransitionEnd",this.__resizeHandler),this.onResize(),o.resizable&&y(this),r=function(){ae&&"true"===localStorage.getItem(m(n,"isLocal"))&&localStorage.setItem(m(n,"gui"),JSON.stringify(n.getSaveObject()))},this.saveToLocalStorageIfPossible=r,o.parent||function(){var e=n.getRoot();e.width+=1,S.defer(function(){e.width-=1})}()};he.toggleHide=function(){ue=!ue,S.each(_e,function(e){e.domElement.style.display=ue?"none":""})},he.CLASS_AUTO_PLACE="a",he.CLASS_AUTO_PLACE_CONTAINER="ac",he.CLASS_MAIN="main",he.CLASS_CONTROLLER_ROW="cr",he.CLASS_TOO_TALL="taller-than-window",he.CLASS_CLOSED="closed",he.CLASS_CLOSE_BUTTON="close-button",he.CLASS_CLOSE_TOP="close-top",he.CLASS_CLOSE_BOTTOM="close-bottom",he.CLASS_DRAG="drag",he.DEFAULT_WIDTH=245,he.TEXT_CLOSED="Close Controls",he.TEXT_OPEN="Open Controls",he._keydownHandler=function(e){"text"===document.activeElement.type||72!==e.which&&72!==e.keyCode||he.toggleHide()},X.bind(window,"keydown",he._keydownHandler,!1),S.extend(he.prototype,{add:function(e,t){return f(this,e,t,{factoryArgs:Array.prototype.slice.call(arguments,2)})},addColor:function(e,t){return f(this,e,t,{color:!0})},remove:function(e){this.__ul.removeChild(e.__li),this.__controllers.splice(this.__controllers.indexOf(e),1);var t=this;S.defer(function(){t.onResize()})},destroy:function(){if(this.parent)throw new Error("Only the root GUI should be removed with .destroy(). For subfolders, use gui.removeFolder(folder) instead.");this.autoPlace&&ce.removeChild(this.domElement);var e=this;S.each(this.__folders,function(t){e.removeFolder(t)}),X.unbind(window,"keydown",he._keydownHandler,!1),u(this)},addFolder:function(e){if(void 0!==this.__folders[e])throw new Error('You already have a folder in this GUI by the name "'+e+'"');var t={name:e,parent:this};t.autoPlace=this.autoPlace,this.load&&this.load.folders&&this.load.folders[e]&&(t.closed=this.load.folders[e].closed,t.load=this.load.folders[e]);var n=new he(t);this.__folders[e]=n;var o=c(this,n.domElement);return X.addClass(o,"folder"),n},removeFolder:function(e){this.__ul.removeChild(e.domElement.parentElement),delete this.__folders[e.name],this.load&&this.load.folders&&this.load.folders[e.name]&&delete this.load.folders[e.name],u(e);var t=this;S.each(e.__folders,function(t){e.removeFolder(t)}),S.defer(function(){t.onResize()})},open:function(){this.closed=!1},close:function(){this.closed=!0},hide:function(){this.domElement.style.display="none"},show:function(){this.domElement.style.display=""},onResize:function(){var e=this.getRoot();if(e.scrollable){var t=X.getOffset(e.__ul).top,n=0;S.each(e.__ul.childNodes,function(t){e.autoPlace&&t===e.__save_row||(n+=X.getHeight(t))}),window.innerHeight-t-20GUI\'s constructor:\n\n \n\n
\n\n Automatically save\n values to localStorage on exit.\n\n
The values saved to localStorage will\n override those passed to dat.GUI\'s constructor. This makes it\n easier to work incrementally, but localStorage is fragile,\n and your friends may not see the same values you do.\n\n
\n\n
\n\n'),this.parent)throw new Error("You can only call remember on a top level GUI.");var e=this;S.each(Array.prototype.slice.call(arguments),function(t){0===e.__rememberedObjects.length&&v(e),-1===e.__rememberedObjects.indexOf(t)&&e.__rememberedObjects.push(t)}),this.autoPlace&&w(this,this.width)},getRoot:function(){for(var e=this;e.parent;)e=e.parent;return e},getSaveObject:function(){var e=this.load;return e.closed=this.closed,this.__rememberedObjects.length>0&&(e.preset=this.preset,e.remembered||(e.remembered={}),e.remembered[this.preset]=x(this)),e.folders={},S.each(this.__folders,function(t,n){e.folders[n]=t.getSaveObject()}),e},save:function(){this.load.remembered||(this.load.remembered={}),this.load.remembered[this.preset]=x(this),_(this,!1),this.saveToLocalStorageIfPossible()},saveAs:function(e){this.load.remembered||(this.load.remembered={},this.load.remembered[se]=x(this,!0)),this.load.remembered[e]=x(this),this.preset=e,g(this,e,!0),this.saveToLocalStorageIfPossible()},revert:function(e){S.each(this.__controllers,function(t){this.getRoot().load.remembered?p(e||this.getRoot(),t):t.setValue(t.initialValue),t.__onFinishChange&&t.__onFinishChange.call(t,t.getValue())},this),S.each(this.__folders,function(e){e.revert(e)}),e||_(this.getRoot(),!1)},listen:function(e){var t=0===this.__listening.length;this.__listening.push(e),t&&C(this.__listening)},updateDisplay:function(){S.each(this.__controllers,function(e){e.updateDisplay()}),S.each(this.__folders,function(e){e.updateDisplay()})}});var pe={Color:I,math:N,interpret:R},fe={Controller:z,BooleanController:K,OptionController:Y,StringController:J,NumberController:W,NumberControllerBox:Q,NumberControllerSlider:q,FunctionController:Z,ColorController:$},me={dom:X},ge={GUI:he},be=he,ve={color:pe,controllers:fe,dom:me,gui:ge,GUI:be};e.color=pe,e.controllers=fe,e.dom=me,e.gui=ge,e.GUI=be,e.default=ve,Object.defineProperty(e,"__esModule",{value:!0})}); +/////////////////////----------------- 流光线 ------------------ +var uniforms = { + u_time: { value: 0.0 } + }; +// 着色器设置 +const vertexShader = ` + varying vec2 vUv; + attribute float percent; + uniform float u_time; + uniform float number; + uniform float speed; + uniform float length; + varying float opacity; + uniform float size; + void main() + { + vUv = uv; + vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); + float l = clamp(1.0-length,0.0,1.0); + gl_PointSize = clamp(fract(percent*number + l - u_time*number*speed)-l ,0.0,1.) * size * (1./length); + opacity = gl_PointSize/size; + gl_Position = projectionMatrix * mvPosition; + } + ` +const fragmentShader = ` + #ifdef GL_ES + precision mediump float; + #endif + varying float opacity; + uniform vec3 color; + void main(){ + if(opacity <=0.2){ + discard; + } + gl_FragColor = vec4(color,1); + } + ` +function createFlyCurve(points, closed) { + var curve = new THREE.CatmullRomCurve3(points, closed); + // 流光的颜色,三个数字分别代表rgb的值,不过注意,需要除以255 + var color = new THREE.Vector3( 0.2235, 0.412, 1 ); + var flyLine = initFlyLine( curve, { + speed: 0.5, + color: color, + number: 5, //同时跑动的流光数量 + length: 0.3, //流光线条长度 + size: 8 //粗细 + }, 3000 ); + return flyLine; +} +function initFlyLine( curve, matSetting, pointsNumber ) { + var points = curve.getPoints( pointsNumber ); + var geometry = new THREE.BufferGeometry().setFromPoints( points ); + const length = points.length; + var percents = new Float32Array( length ); + for (let i = 0; i < points.length; i += 1) { + percents[i] = ( i / length ); + } + geometry.setAttribute( 'percent', new THREE.BufferAttribute( percents, 1 ) ); + const lineMaterial = initLineMaterial( matSetting ); + var flyLine = new THREE.Points( geometry, lineMaterial ); + return flyLine; + } + + function initLineMaterial( setting ) { + const number = setting ? ( Number( setting.number ) || 1.0 ) : 1.0; + const speed = setting ? ( Number( setting.speed ) || 1.0 ) : 1.0; + const length = setting ? ( Number( setting.length ) || 0.5 ) : 0.5; + const size = setting ? ( Number( setting.size ) || 3.0 ) : 3.0; + const color = setting ? setting.color || new THREE.Vector3( 0, 1, 1 ) : new THREE.Vector3( 0, 1, 1 ); + const singleUniforms = { + u_time: uniforms.u_time, + number: { type: 'f', value: number }, + speed: { type: 'f', value: speed }, + length: { type: 'f', value: length }, + size: { type: 'f', value: size }, + color: { type: 'v3', value: color } + }; + const lineMaterial = new THREE.ShaderMaterial( { + uniforms: singleUniforms, + vertexShader: vertexShader, + fragmentShader: fragmentShader, + transparent: true + } ); + return lineMaterial; + }