diff --git a/public/offline/getMapInfo.json b/public/offline/getMapInfo.json
new file mode 100644
index 0000000..efdf9e0
--- /dev/null
+++ b/public/offline/getMapInfo.json
@@ -0,0 +1,10 @@
+{
+ "code": 200,
+ "msg": "操作成功",
+ "data": {
+ "mapData": "[{\"name\":\"A\",\"scale\":18,\"collision\":true,\"m_shadow\":false,\"playSpeed\":6,\"aRadius\":0,\"navColor\":\"#EE6A50\",\"boxShop\":\"\",\"shopStyle\":\"shopName\",\"modelIcon\":true,\"d_col\":\"#ffffff\",\"d_int\":0.1,\"s_col\":\"#fffffa\",\"g_col\":\"#ffffff\",\"a_int\":0.5,\"c_site\":\"0,220,220\",\"m_site\":\"0,0,0\",\"m_zoom\":1.2,\"m_scale\":0.09,\"mapW\":3000,\"mapH\":3000,\"buildArr\":[{\"name\":\"L1\",\"mapData\":{\"groupArea\":[],\"floorArea\":{\"id\":\"2d5f86b1ca9e\",\"name\":\"floor\",\"hasLines\":[{\"startPoint\":{\"x\":-596,\"y\":-392},\"endPoint\":{\"x\":-593,\"y\":-825},\"name\":3320206,\"isStrLine\":true},{\"startPoint\":{\"x\":-593,\"y\":-825},\"endPoint\":{\"x\":-251,\"y\":-945},\"name\":3320207,\"isStrLine\":true},{\"startPoint\":{\"x\":-251,\"y\":-945},\"endPoint\":{\"x\":-88,\"y\":-459},\"name\":3320208,\"isStrLine\":true},{\"startPoint\":{\"x\":-88,\"y\":-459},\"endPoint\":{\"x\":1321,\"y\":-466},\"name\":3320209,\"isStrLine\":true},{\"startPoint\":{\"x\":1321,\"y\":-466},\"endPoint\":{\"x\":1323.083538083538,\"y\":-307},\"name\":3320210,\"isStrLine\":true},{\"startPoint\":{\"x\":1323.083538083538,\"y\":-307},\"endPoint\":{\"x\":1424,\"y\":-195},\"name\":3320211,\"isStrLine\":true},{\"startPoint\":{\"x\":1424,\"y\":-195},\"endPoint\":{\"x\":1418,\"y\":161},\"name\":3320212,\"isStrLine\":true},{\"startPoint\":{\"x\":1418,\"y\":161},\"endPoint\":{\"x\":858,\"y\":735},\"name\":3320213,\"isStrLine\":true},{\"startPoint\":{\"x\":858,\"y\":735},\"endPoint\":{\"x\":152,\"y\":730},\"name\":3320214,\"isStrLine\":false,\"ctrlPoint1\":{\"x\":644,\"y\":998},\"ctrlPoint2\":{\"x\":327,\"y\":990}},{\"startPoint\":{\"x\":152,\"y\":730},\"endPoint\":{\"x\":103,\"y\":730},\"name\":3320215,\"isStrLine\":true},{\"startPoint\":{\"x\":103,\"y\":730},\"endPoint\":{\"x\":103,\"y\":693},\"name\":3320216,\"isStrLine\":true},{\"startPoint\":{\"x\":103,\"y\":693},\"endPoint\":{\"x\":8,\"y\":693},\"name\":3320217,\"isStrLine\":true},{\"startPoint\":{\"x\":8,\"y\":693},\"endPoint\":{\"x\":8,\"y\":607},\"name\":3320218,\"isStrLine\":true},{\"startPoint\":{\"x\":8,\"y\":607},\"endPoint\":{\"x\":-157,\"y\":607},\"name\":3320219,\"isStrLine\":true},{\"startPoint\":{\"x\":-157,\"y\":607},\"endPoint\":{\"x\":-157,\"y\":529},\"name\":3320220,\"isStrLine\":true},{\"startPoint\":{\"x\":-157,\"y\":529},\"endPoint\":{\"x\":-1192,\"y\":529},\"name\":3320221,\"isStrLine\":true},{\"startPoint\":{\"x\":-1192,\"y\":529},\"endPoint\":{\"x\":-1325,\"y\":230},\"name\":3320222,\"isStrLine\":true},{\"startPoint\":{\"x\":-1325,\"y\":230},\"endPoint\":{\"x\":-1350,\"y\":242},\"name\":3320223,\"isStrLine\":true},{\"startPoint\":{\"x\":-1350,\"y\":242},\"endPoint\":{\"x\":-1441,\"y\":47},\"name\":3320224,\"isStrLine\":true},{\"startPoint\":{\"x\":-1441,\"y\":47},\"endPoint\":{\"x\":-1413,\"y\":33},\"name\":3320225,\"isStrLine\":true},{\"startPoint\":{\"x\":-1413,\"y\":33},\"endPoint\":{\"x\":-1454,\"y\":-52},\"name\":3320226,\"isStrLine\":true},{\"startPoint\":{\"x\":-1454,\"y\":-52},\"endPoint\":{\"x\":-1375,\"y\":-92},\"name\":3320227,\"isStrLine\":true},{\"startPoint\":{\"x\":-1375,\"y\":-92},\"endPoint\":{\"x\":-1395,\"y\":-126},\"name\":3320228,\"isStrLine\":true},{\"startPoint\":{\"x\":-1395,\"y\":-126},\"endPoint\":{\"x\":-836,\"y\":-393},\"name\":3320229,\"isStrLine\":true},{\"startPoint\":{\"x\":-836,\"y\":-393},\"endPoint\":{\"x\":-596,\"y\":-392},\"name\":3320230,\"isStrLine\":true}],\"entColor\":\"#cccccc\",\"borderColor\":\"#ffffff\",\"toHeight\":10,\"alphaModle\":90,\"site\":0,\"xaxis\":-1,\"yaxis\":1.5,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":-1,\"style\":1,\"isLabel\":1,\"comeIn\":\"\",\"area\":30192,\"map\":\"\"},\"buildArea\":[],\"hollowArea\":[],\"shopArea\":[{\"id\":\"0ce7bf8d98b3\",\"name\":\"C152\",\"hasLines\":[{\"startPoint\":{\"x\":-1224,\"y\":-170},\"endPoint\":{\"x\":-1080,\"y\":-240},\"name\":3320231,\"isStrLine\":true},{\"startPoint\":{\"x\":-1080,\"y\":-240},\"endPoint\":{\"x\":-1080,\"y\":32},\"name\":3320232,\"isStrLine\":true},{\"startPoint\":{\"x\":-1080,\"y\":32},\"endPoint\":{\"x\":-1224,\"y\":32},\"name\":3320233,\"isStrLine\":true},{\"startPoint\":{\"x\":-1224,\"y\":32},\"endPoint\":{\"x\":-1224,\"y\":-170},\"name\":3320234,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":-1170,\"yaxis\":-35,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"46\",\"style\":1,\"isLabel\":1,\"comeIn\":\"\",\"area\":341,\"map\":\"\"},{\"id\":\"bc1bd60f8919\",\"name\":\"C166\",\"hasLines\":[{\"startPoint\":{\"x\":-1080,\"y\":-240},\"endPoint\":{\"x\":-983,\"y\":-290},\"name\":3320235,\"isStrLine\":true},{\"startPoint\":{\"x\":-983,\"y\":-290},\"endPoint\":{\"x\":-983,\"y\":-140},\"name\":3320236,\"isStrLine\":true},{\"startPoint\":{\"x\":-983,\"y\":-140},\"endPoint\":{\"x\":-932,\"y\":-140},\"name\":3320237,\"isStrLine\":true},{\"startPoint\":{\"x\":-932,\"y\":-140},\"endPoint\":{\"x\":-932,\"y\":32},\"name\":3320238,\"isStrLine\":true},{\"startPoint\":{\"x\":-932,\"y\":32},\"endPoint\":{\"x\":-1080,\"y\":32},\"name\":3320239,\"isStrLine\":true},{\"startPoint\":{\"x\":-1080,\"y\":32},\"endPoint\":{\"x\":-1080,\"y\":-240},\"name\":3320240,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":-1008,\"yaxis\":-76,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"43\",\"style\":0,\"isLabel\":1,\"comeIn\":\"\",\"area\":376,\"map\":\"\"},{\"id\":\"85f6a3350834\",\"name\":\"F102\",\"hasLines\":[{\"startPoint\":{\"x\":-932,\"y\":-140},\"endPoint\":{\"x\":-766,\"y\":-140},\"name\":3320241,\"isStrLine\":true},{\"startPoint\":{\"x\":-766,\"y\":-140},\"endPoint\":{\"x\":-766,\"y\":32},\"name\":3320242,\"isStrLine\":true},{\"startPoint\":{\"x\":-766,\"y\":32},\"endPoint\":{\"x\":-932,\"y\":32},\"name\":3320243,\"isStrLine\":true},{\"startPoint\":{\"x\":-932,\"y\":32},\"endPoint\":{\"x\":-932,\"y\":-140},\"name\":3320244,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":-854,\"yaxis\":-56,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"40\",\"style\":0,\"isLabel\":1,\"comeIn\":\"\",\"area\":286,\"map\":\"\"},{\"id\":\"bd0a23a58583\",\"name\":\"\",\"hasLines\":[{\"startPoint\":{\"x\":-1356,\"y\":-112},\"endPoint\":{\"x\":-1224,\"y\":-170},\"name\":3320245,\"isStrLine\":true},{\"startPoint\":{\"x\":-1224,\"y\":-170},\"endPoint\":{\"x\":-1224,\"y\":32},\"name\":3320246,\"isStrLine\":true},{\"startPoint\":{\"x\":-1224,\"y\":32},\"endPoint\":{\"x\":-1294,\"y\":32},\"name\":3320247,\"isStrLine\":true},{\"startPoint\":{\"x\":-1294,\"y\":32},\"endPoint\":{\"x\":-1356,\"y\":-112},\"name\":3320248,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":-1279,\"yaxis\":-64,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"48\",\"style\":0,\"isLabel\":1,\"comeIn\":\"\",\"area\":184,\"map\":\"\"},{\"id\":\"96e7a966ef66\",\"name\":\"B127\",\"hasLines\":[{\"startPoint\":{\"x\":-766,\"y\":-319},\"endPoint\":{\"x\":-618,\"y\":-319},\"name\":3320249,\"isStrLine\":true},{\"startPoint\":{\"x\":-618,\"y\":-319},\"endPoint\":{\"x\":-618,\"y\":32},\"name\":3320250,\"isStrLine\":true},{\"startPoint\":{\"x\":-618,\"y\":32},\"endPoint\":{\"x\":-766,\"y\":32},\"name\":3320251,\"isStrLine\":true},{\"startPoint\":{\"x\":-766,\"y\":32},\"endPoint\":{\"x\":-766,\"y\":-140},\"name\":3320252,\"isStrLine\":true},{\"startPoint\":{\"x\":-766,\"y\":-140},\"endPoint\":{\"x\":-766,\"y\":-319},\"name\":3320253,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":-687,\"yaxis\":-205,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"37\",\"style\":0,\"isLabel\":1,\"comeIn\":\"\",\"area\":519,\"map\":\"\"},{\"id\":\"77e954a94ec0\",\"name\":\"F119\",\"hasLines\":[{\"startPoint\":{\"x\":-618,\"y\":-319},\"endPoint\":{\"x\":-557,\"y\":-319},\"name\":3320254,\"isStrLine\":true},{\"startPoint\":{\"x\":-557,\"y\":-319},\"endPoint\":{\"x\":-476,\"y\":-319},\"name\":3320255,\"isStrLine\":true},{\"startPoint\":{\"x\":-476,\"y\":-319},\"endPoint\":{\"x\":-476,\"y\":-122},\"name\":3320256,\"isStrLine\":true},{\"startPoint\":{\"x\":-476,\"y\":-122},\"endPoint\":{\"x\":-476,\"y\":32},\"name\":3320257,\"isStrLine\":true},{\"startPoint\":{\"x\":-476,\"y\":32},\"endPoint\":{\"x\":-618,\"y\":32},\"name\":3320258,\"isStrLine\":true},{\"startPoint\":{\"x\":-618,\"y\":32},\"endPoint\":{\"x\":-618,\"y\":-319},\"name\":3320259,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":-547,\"yaxis\":-115,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"34\",\"style\":0,\"isLabel\":1,\"comeIn\":\"\",\"area\":498,\"map\":\"\"},{\"id\":\"a86ab003b5ab\",\"name\":\"B119-B158\",\"hasLines\":[{\"startPoint\":{\"x\":-557,\"y\":-534},\"endPoint\":{\"x\":-247,\"y\":-534},\"name\":3320260,\"isStrLine\":true},{\"startPoint\":{\"x\":-247,\"y\":-534},\"endPoint\":{\"x\":-247,\"y\":-122},\"name\":3320261,\"isStrLine\":true},{\"startPoint\":{\"x\":-247,\"y\":-122},\"endPoint\":{\"x\":-476,\"y\":-122},\"name\":3320262,\"isStrLine\":true},{\"startPoint\":{\"x\":-476,\"y\":-122},\"endPoint\":{\"x\":-476,\"y\":-319},\"name\":3320263,\"isStrLine\":true},{\"startPoint\":{\"x\":-476,\"y\":-319},\"endPoint\":{\"x\":-557,\"y\":-319},\"name\":3320264,\"isStrLine\":true},{\"startPoint\":{\"x\":-557,\"y\":-319},\"endPoint\":{\"x\":-557,\"y\":-534},\"name\":3320265,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":-350,\"yaxis\":-328,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"24\",\"style\":0,\"isLabel\":1,\"comeIn\":\"\",\"area\":1118,\"map\":\"\"},{\"id\":\"b089da41f459\",\"name\":\"F305\",\"hasLines\":[{\"startPoint\":{\"x\":-247,\"y\":-534},\"endPoint\":{\"x\":-161,\"y\":-534},\"name\":3320266,\"isStrLine\":true},{\"startPoint\":{\"x\":-161,\"y\":-534},\"endPoint\":{\"x\":-127,\"y\":-435},\"name\":3320267,\"isStrLine\":true},{\"startPoint\":{\"x\":-127,\"y\":-435},\"endPoint\":{\"x\":-99,\"y\":-435},\"name\":3320268,\"isStrLine\":true},{\"startPoint\":{\"x\":-99,\"y\":-435},\"endPoint\":{\"x\":-99,\"y\":-288},\"name\":3320269,\"isStrLine\":true},{\"startPoint\":{\"x\":-99,\"y\":-288},\"endPoint\":{\"x\":8,\"y\":-287},\"name\":3320270,\"isStrLine\":true},{\"startPoint\":{\"x\":8,\"y\":-287},\"endPoint\":{\"x\":8,\"y\":-122},\"name\":3320271,\"isStrLine\":true},{\"startPoint\":{\"x\":8,\"y\":-122},\"endPoint\":{\"x\":-247,\"y\":-122},\"name\":3320272,\"isStrLine\":true},{\"startPoint\":{\"x\":-247,\"y\":-122},\"endPoint\":{\"x\":-247,\"y\":-534},\"name\":3320273,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":-133,\"yaxis\":-217,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"25\",\"style\":0,\"isLabel\":1,\"comeIn\":\"\",\"area\":742,\"map\":\"\"},{\"id\":\"96cffbc3fb47\",\"name\":\"F705\",\"hasLines\":[{\"startPoint\":{\"x\":96,\"y\":-287},\"endPoint\":{\"x\":96,\"y\":-431},\"name\":3320274,\"isStrLine\":true},{\"startPoint\":{\"x\":96,\"y\":-431},\"endPoint\":{\"x\":198,\"y\":-431},\"name\":3320275,\"isStrLine\":true},{\"startPoint\":{\"x\":198,\"y\":-431},\"endPoint\":{\"x\":198,\"y\":-122},\"name\":3320276,\"isStrLine\":true},{\"startPoint\":{\"x\":198,\"y\":-122},\"endPoint\":{\"x\":8,\"y\":-122},\"name\":3320277,\"isStrLine\":true},{\"startPoint\":{\"x\":8,\"y\":-122},\"endPoint\":{\"x\":8,\"y\":-287},\"name\":3320278,\"isStrLine\":true},{\"startPoint\":{\"x\":8,\"y\":-287},\"endPoint\":{\"x\":96,\"y\":-287},\"name\":3320279,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":105,\"yaxis\":-193,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"26\",\"style\":0,\"isLabel\":1,\"comeIn\":\"\",\"area\":460,\"map\":\"\"},{\"id\":\"7c7b082bf2b6\",\"name\":\"L108\",\"hasLines\":[{\"startPoint\":{\"x\":198,\"y\":-431},\"endPoint\":{\"x\":512,\"y\":-431},\"name\":3320280,\"isStrLine\":true},{\"startPoint\":{\"x\":512,\"y\":-431},\"endPoint\":{\"x\":512,\"y\":-122},\"name\":3320281,\"isStrLine\":true},{\"startPoint\":{\"x\":512,\"y\":-122},\"endPoint\":{\"x\":198,\"y\":-122},\"name\":3320282,\"isStrLine\":true},{\"startPoint\":{\"x\":198,\"y\":-122},\"endPoint\":{\"x\":198,\"y\":-431},\"name\":3320283,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":355,\"yaxis\":-272,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"19\",\"style\":0,\"isLabel\":1,\"comeIn\":\"\",\"area\":970,\"map\":\"\"},{\"id\":\"e9dae9ad0876\",\"name\":\"L106-L206\",\"hasLines\":[{\"startPoint\":{\"x\":512,\"y\":-431},\"endPoint\":{\"x\":646,\"y\":-431},\"name\":3320284,\"isStrLine\":true},{\"startPoint\":{\"x\":646,\"y\":-431},\"endPoint\":{\"x\":646,\"y\":-299},\"name\":3320285,\"isStrLine\":true},{\"startPoint\":{\"x\":646,\"y\":-299},\"endPoint\":{\"x\":837,\"y\":-299},\"name\":3320286,\"isStrLine\":true},{\"startPoint\":{\"x\":837,\"y\":-299},\"endPoint\":{\"x\":837,\"y\":-122},\"name\":3320287,\"isStrLine\":true},{\"startPoint\":{\"x\":837,\"y\":-122},\"endPoint\":{\"x\":512,\"y\":-122},\"name\":3320288,\"isStrLine\":true},{\"startPoint\":{\"x\":512,\"y\":-122},\"endPoint\":{\"x\":512,\"y\":-431},\"name\":3320289,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":676,\"yaxis\":-210,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"17\",\"style\":0,\"isLabel\":1,\"comeIn\":\"\",\"area\":752,\"map\":\"\"},{\"id\":\"af23710dcba6\",\"name\":\"L118-L208\",\"hasLines\":[{\"startPoint\":{\"x\":837,\"y\":-431},\"endPoint\":{\"x\":978,\"y\":-431},\"name\":3320290,\"isStrLine\":true},{\"startPoint\":{\"x\":978,\"y\":-431},\"endPoint\":{\"x\":978,\"y\":-300},\"name\":3320291,\"isStrLine\":true},{\"startPoint\":{\"x\":978,\"y\":-300},\"endPoint\":{\"x\":978,\"y\":-122},\"name\":3320292,\"isStrLine\":true},{\"startPoint\":{\"x\":978,\"y\":-122},\"endPoint\":{\"x\":837,\"y\":-122},\"name\":3320293,\"isStrLine\":true},{\"startPoint\":{\"x\":837,\"y\":-122},\"endPoint\":{\"x\":837,\"y\":-299},\"name\":3320294,\"isStrLine\":true},{\"startPoint\":{\"x\":837,\"y\":-299},\"endPoint\":{\"x\":837,\"y\":-431},\"name\":3320295,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":906,\"yaxis\":-273,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"14\",\"style\":0,\"isLabel\":1,\"comeIn\":\"\",\"area\":436,\"map\":\"\"},{\"id\":\"86df1131de89\",\"name\":\"B115\",\"hasLines\":[{\"startPoint\":{\"x\":1050,\"y\":-300},\"endPoint\":{\"x\":1050,\"y\":-431},\"name\":3320296,\"isStrLine\":true},{\"startPoint\":{\"x\":1050,\"y\":-431},\"endPoint\":{\"x\":1118,\"y\":-431},\"name\":3320297,\"isStrLine\":true},{\"startPoint\":{\"x\":1118,\"y\":-431},\"endPoint\":{\"x\":1118,\"y\":-122},\"name\":3320298,\"isStrLine\":true},{\"startPoint\":{\"x\":1118,\"y\":-122},\"endPoint\":{\"x\":978,\"y\":-122},\"name\":3320299,\"isStrLine\":true},{\"startPoint\":{\"x\":978,\"y\":-122},\"endPoint\":{\"x\":978,\"y\":-300},\"name\":3320300,\"isStrLine\":true},{\"startPoint\":{\"x\":978,\"y\":-300},\"endPoint\":{\"x\":1050,\"y\":-300},\"name\":3320301,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":1046,\"yaxis\":-225,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"11\",\"style\":0,\"isLabel\":1,\"comeIn\":\"\",\"area\":338,\"map\":\"\"},{\"id\":\"d0b55ebea895\",\"name\":\"L133-L230\",\"hasLines\":[{\"startPoint\":{\"x\":1118,\"y\":-431},\"endPoint\":{\"x\":1225,\"y\":-431},\"name\":3320302,\"isStrLine\":true},{\"startPoint\":{\"x\":1225,\"y\":-431},\"endPoint\":{\"x\":1225,\"y\":-230},\"name\":3320303,\"isStrLine\":true},{\"startPoint\":{\"x\":1225,\"y\":-230},\"endPoint\":{\"x\":1314,\"y\":-165},\"name\":3320304,\"isStrLine\":true},{\"startPoint\":{\"x\":1314,\"y\":-165},\"endPoint\":{\"x\":1314,\"y\":-122},\"name\":3320305,\"isStrLine\":true},{\"startPoint\":{\"x\":1314,\"y\":-122},\"endPoint\":{\"x\":1118,\"y\":-122},\"name\":3320306,\"isStrLine\":true},{\"startPoint\":{\"x\":1118,\"y\":-122},\"endPoint\":{\"x\":1118,\"y\":-431},\"name\":3320307,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":1172,\"yaxis\":-272,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"8\",\"style\":0,\"isLabel\":1,\"comeIn\":\"\",\"area\":398,\"map\":\"\"},{\"id\":\"7c874d145c77\",\"name\":\"L530\",\"hasLines\":[{\"startPoint\":{\"x\":-1310,\"y\":173},\"endPoint\":{\"x\":-1083,\"y\":173},\"name\":3320308,\"isStrLine\":true},{\"startPoint\":{\"x\":-1083,\"y\":173},\"endPoint\":{\"x\":-1083,\"y\":493},\"name\":3320309,\"isStrLine\":true},{\"startPoint\":{\"x\":-1083,\"y\":493},\"endPoint\":{\"x\":-1168,\"y\":493},\"name\":3320310,\"isStrLine\":true},{\"startPoint\":{\"x\":-1168,\"y\":493},\"endPoint\":{\"x\":-1310,\"y\":173},\"name\":3320311,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":-1162,\"yaxis\":288,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"49\",\"style\":1,\"isLabel\":1,\"comeIn\":\"\",\"area\":499,\"map\":\"\"},{\"id\":\"08aba9038cb2\",\"name\":\"C169\",\"hasLines\":[{\"startPoint\":{\"x\":-1083,\"y\":173},\"endPoint\":{\"x\":-931,\"y\":173},\"name\":3320312,\"isStrLine\":true},{\"startPoint\":{\"x\":-931,\"y\":173},\"endPoint\":{\"x\":-931,\"y\":493},\"name\":3320313,\"isStrLine\":true},{\"startPoint\":{\"x\":-931,\"y\":493},\"endPoint\":{\"x\":-1083,\"y\":493},\"name\":3320314,\"isStrLine\":true},{\"startPoint\":{\"x\":-1083,\"y\":493},\"endPoint\":{\"x\":-1083,\"y\":173},\"name\":3320315,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":-1008,\"yaxis\":360,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"44\",\"style\":0,\"isLabel\":1,\"comeIn\":\"\",\"area\":486,\"map\":\"\"},{\"id\":\"8ef484f252ba\",\"name\":\"F716\",\"hasLines\":[{\"startPoint\":{\"x\":-931,\"y\":173},\"endPoint\":{\"x\":-770,\"y\":173},\"name\":3320316,\"isStrLine\":true},{\"startPoint\":{\"x\":-770,\"y\":173},\"endPoint\":{\"x\":-770,\"y\":493},\"name\":3320317,\"isStrLine\":true},{\"startPoint\":{\"x\":-770,\"y\":493},\"endPoint\":{\"x\":-931,\"y\":493},\"name\":3320318,\"isStrLine\":true},{\"startPoint\":{\"x\":-931,\"y\":493},\"endPoint\":{\"x\":-931,\"y\":173},\"name\":3320319,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":-849,\"yaxis\":293,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"41\",\"style\":0,\"isLabel\":1,\"comeIn\":\"\",\"area\":515,\"map\":\"\"},{\"id\":\"0ba690c6ac85\",\"name\":\"F718\",\"hasLines\":[{\"startPoint\":{\"x\":-770,\"y\":173},\"endPoint\":{\"x\":-617,\"y\":173},\"name\":3320320,\"isStrLine\":true},{\"startPoint\":{\"x\":-617,\"y\":173},\"endPoint\":{\"x\":-617,\"y\":493},\"name\":3320321,\"isStrLine\":true},{\"startPoint\":{\"x\":-617,\"y\":493},\"endPoint\":{\"x\":-770,\"y\":493},\"name\":3320322,\"isStrLine\":true},{\"startPoint\":{\"x\":-770,\"y\":493},\"endPoint\":{\"x\":-770,\"y\":173},\"name\":3320323,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":-693,\"yaxis\":367,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"38\",\"style\":0,\"isLabel\":1,\"comeIn\":\"\",\"area\":490,\"map\":\"\"},{\"id\":\"9574a7257ec0\",\"name\":\"F703\",\"hasLines\":[{\"startPoint\":{\"x\":-617,\"y\":173},\"endPoint\":{\"x\":-462,\"y\":173},\"name\":3320324,\"isStrLine\":true},{\"startPoint\":{\"x\":-462,\"y\":173},\"endPoint\":{\"x\":-462,\"y\":493},\"name\":3320325,\"isStrLine\":true},{\"startPoint\":{\"x\":-462,\"y\":493},\"endPoint\":{\"x\":-617,\"y\":493},\"name\":3320326,\"isStrLine\":true},{\"startPoint\":{\"x\":-617,\"y\":493},\"endPoint\":{\"x\":-617,\"y\":173},\"name\":3320327,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":-543,\"yaxis\":286,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"35\",\"style\":0,\"isLabel\":1,\"comeIn\":\"\",\"area\":496,\"map\":\"\"},{\"id\":\"d51d7b910937\",\"name\":\"F710-1\",\"hasLines\":[{\"startPoint\":{\"x\":-462,\"y\":173},\"endPoint\":{\"x\":-311,\"y\":173},\"name\":3320328,\"isStrLine\":true},{\"startPoint\":{\"x\":-311,\"y\":173},\"endPoint\":{\"x\":-311,\"y\":493},\"name\":3320329,\"isStrLine\":true},{\"startPoint\":{\"x\":-311,\"y\":493},\"endPoint\":{\"x\":-462,\"y\":493},\"name\":3320330,\"isStrLine\":true},{\"startPoint\":{\"x\":-462,\"y\":493},\"endPoint\":{\"x\":-462,\"y\":173},\"name\":3320331,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":-387,\"yaxis\":359,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"33\",\"style\":0,\"isLabel\":1,\"comeIn\":\"\",\"area\":483,\"map\":\"\"},{\"id\":\"eb55b023d7b8\",\"name\":\"F712\",\"hasLines\":[{\"startPoint\":{\"x\":-311,\"y\":173},\"endPoint\":{\"x\":-124,\"y\":173},\"name\":3320332,\"isStrLine\":true},{\"startPoint\":{\"x\":-124,\"y\":173},\"endPoint\":{\"x\":-124,\"y\":493},\"name\":3320333,\"isStrLine\":true},{\"startPoint\":{\"x\":-124,\"y\":493},\"endPoint\":{\"x\":-311,\"y\":493},\"name\":3320334,\"isStrLine\":true},{\"startPoint\":{\"x\":-311,\"y\":493},\"endPoint\":{\"x\":-311,\"y\":173},\"name\":3320335,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":-222,\"yaxis\":292,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"32\",\"style\":0,\"isLabel\":1,\"comeIn\":\"\",\"area\":598,\"map\":\"\"},{\"id\":\"dae84185ae27\",\"name\":\"L610\",\"hasLines\":[{\"startPoint\":{\"x\":-124,\"y\":173},\"endPoint\":{\"x\":30,\"y\":173},\"name\":3320336,\"isStrLine\":true},{\"startPoint\":{\"x\":30,\"y\":173},\"endPoint\":{\"x\":30,\"y\":434},\"name\":3320337,\"isStrLine\":true},{\"startPoint\":{\"x\":30,\"y\":434},\"endPoint\":{\"x\":30,\"y\":570},\"name\":3320338,\"isStrLine\":true},{\"startPoint\":{\"x\":30,\"y\":570},\"endPoint\":{\"x\":-124,\"y\":570},\"name\":3320339,\"isStrLine\":true},{\"startPoint\":{\"x\":-124,\"y\":570},\"endPoint\":{\"x\":-124,\"y\":493},\"name\":3320340,\"isStrLine\":true},{\"startPoint\":{\"x\":-124,\"y\":493},\"endPoint\":{\"x\":-124,\"y\":173},\"name\":3320341,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":-49,\"yaxis\":369,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"30\",\"style\":0,\"isLabel\":1,\"comeIn\":\"\",\"area\":611,\"map\":\"\"},{\"id\":\"b72c1cd49f81\",\"name\":\"L607\",\"hasLines\":[{\"startPoint\":{\"x\":30,\"y\":173},\"endPoint\":{\"x\":185,\"y\":173},\"name\":3320342,\"isStrLine\":true},{\"startPoint\":{\"x\":185,\"y\":173},\"endPoint\":{\"x\":185,\"y\":434},\"name\":3320343,\"isStrLine\":true},{\"startPoint\":{\"x\":185,\"y\":434},\"endPoint\":{\"x\":30,\"y\":434},\"name\":3320344,\"isStrLine\":true},{\"startPoint\":{\"x\":30,\"y\":434},\"endPoint\":{\"x\":30,\"y\":173},\"name\":3320345,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":103,\"yaxis\":284,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"28\",\"style\":0,\"isLabel\":1,\"comeIn\":\"\",\"area\":405,\"map\":\"\"},{\"id\":\"b020d08b654f\",\"name\":\"L101-L102-L201-L202\",\"hasLines\":[{\"startPoint\":{\"x\":672,\"y\":36},\"endPoint\":{\"x\":1315,\"y\":36},\"name\":3320346,\"isStrLine\":true},{\"startPoint\":{\"x\":1315,\"y\":36},\"endPoint\":{\"x\":1315,\"y\":122},\"name\":3320347,\"isStrLine\":true},{\"startPoint\":{\"x\":1315,\"y\":122},\"endPoint\":{\"x\":1088,\"y\":351},\"name\":3320348,\"isStrLine\":true},{\"startPoint\":{\"x\":1088,\"y\":351},\"endPoint\":{\"x\":1012,\"y\":351},\"name\":3320349,\"isStrLine\":true},{\"startPoint\":{\"x\":1012,\"y\":351},\"endPoint\":{\"x\":1012,\"y\":194},\"name\":3320350,\"isStrLine\":true},{\"startPoint\":{\"x\":1012,\"y\":194},\"endPoint\":{\"x\":907,\"y\":194},\"name\":3320351,\"isStrLine\":true},{\"startPoint\":{\"x\":907,\"y\":194},\"endPoint\":{\"x\":672,\"y\":194},\"name\":3320352,\"isStrLine\":true},{\"startPoint\":{\"x\":672,\"y\":194},\"endPoint\":{\"x\":672,\"y\":36},\"name\":3320353,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":991.5,\"yaxis\":115,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"15\",\"style\":1,\"isLabel\":1,\"comeIn\":\"\",\"area\":1232,\"map\":\"\"},{\"id\":\"95cef2fd7e29\",\"name\":\"L303\",\"hasLines\":[{\"startPoint\":{\"x\":907,\"y\":194},\"endPoint\":{\"x\":1012,\"y\":194},\"name\":3320354,\"isStrLine\":true},{\"startPoint\":{\"x\":1012,\"y\":194},\"endPoint\":{\"x\":1012,\"y\":351},\"name\":3320355,\"isStrLine\":true},{\"startPoint\":{\"x\":1012,\"y\":351},\"endPoint\":{\"x\":1088,\"y\":351},\"name\":3320356,\"isStrLine\":true},{\"startPoint\":{\"x\":1088,\"y\":351},\"endPoint\":{\"x\":895,\"y\":549},\"name\":3320357,\"isStrLine\":true},{\"startPoint\":{\"x\":895,\"y\":549},\"endPoint\":{\"x\":782,\"y\":549},\"name\":3320358,\"isStrLine\":true},{\"startPoint\":{\"x\":782,\"y\":549},\"endPoint\":{\"x\":782,\"y\":369},\"name\":3320359,\"isStrLine\":true},{\"startPoint\":{\"x\":782,\"y\":369},\"endPoint\":{\"x\":905,\"y\":369},\"name\":3320360,\"isStrLine\":true},{\"startPoint\":{\"x\":905,\"y\":369},\"endPoint\":{\"x\":907,\"y\":194},\"name\":3320361,\"isStrLine\":true}],\"entColor\":\"#ddb184\",\"borderColor\":\"#ffffff\",\"toHeight\":50,\"alphaModle\":100,\"site\":0,\"xaxis\":947.5,\"yaxis\":379.5,\"angle\":0,\"angleY\":0,\"angleZ\":0,\"scale\":1,\"gid\":\"\",\"hollArea\":[],\"shopNav\":\"54\",\"style\":0,\"isLabel\":1,\"comeIn\":\"\",\"area\":559,\"map\":\"\"}],\"path\":{\"nodes\":[{\"id\":0,\"x\":-1386,\"y\":-26,\"Proy\":\"graph\",\"list\":[{\"cost\":123,\"id\":1}]},{\"id\":1,\"x\":-1345,\"y\":90,\"Proy\":\"graph\",\"list\":[{\"cost\":123,\"id\":0},{\"cost\":77,\"id\":47}]},{\"id\":2,\"x\":-551,\"y\":94,\"Proy\":\"graph\",\"list\":[{\"cost\":159,\"id\":3},{\"cost\":37,\"id\":34},{\"cost\":57,\"id\":35},{\"cost\":150,\"id\":36}]},{\"id\":3,\"x\":-392,\"y\":95,\"Proy\":\"graph\",\"list\":[{\"cost\":159,\"id\":2},{\"cost\":126,\"id\":22},{\"cost\":165,\"id\":31},{\"cost\":58,\"id\":33}]},{\"id\":4,\"x\":-134,\"y\":-33,\"Proy\":\"graph\",\"list\":[{\"cost\":245,\"id\":5},{\"cost\":253,\"id\":22},{\"cost\":66,\"id\":25}]},{\"id\":5,\"x\":111,\"y\":-35,\"Proy\":\"graph\",\"list\":[{\"cost\":245,\"id\":4},{\"cost\":238,\"id\":18},{\"cost\":65,\"id\":26},{\"cost\":133,\"id\":27}]},{\"id\":6,\"x\":1369,\"y\":-45,\"Proy\":\"graph\",\"list\":[{\"cost\":137,\"id\":7}]},{\"id\":7,\"x\":1232,\"y\":-44,\"Proy\":\"graph\",\"list\":[{\"cost\":137,\"id\":6},{\"cost\":53,\"id\":8},{\"cost\":53,\"id\":9},{\"cost\":173,\"id\":10}]},{\"id\":8,\"x\":1226,\"y\":-97,\"Proy\":\"graph\",\"list\":[{\"cost\":53,\"id\":7}]},{\"id\":9,\"x\":1233,\"y\":9,\"Proy\":\"graph\",\"list\":[{\"cost\":53,\"id\":7}]},{\"id\":10,\"x\":1059,\"y\":-43,\"Proy\":\"graph\",\"list\":[{\"cost\":173,\"id\":7},{\"cost\":58,\"id\":11},{\"cost\":50,\"id\":12},{\"cost\":141,\"id\":13}]},{\"id\":11,\"x\":1057,\"y\":-101,\"Proy\":\"graph\",\"list\":[{\"cost\":58,\"id\":10}]},{\"id\":12,\"x\":1061,\"y\":7,\"Proy\":\"graph\",\"list\":[{\"cost\":50,\"id\":10}]},{\"id\":13,\"x\":918,\"y\":-42,\"Proy\":\"graph\",\"list\":[{\"cost\":141,\"id\":10},{\"cost\":60,\"id\":14},{\"cost\":59,\"id\":15},{\"cost\":229,\"id\":16}]},{\"id\":14,\"x\":912,\"y\":-102,\"Proy\":\"graph\",\"list\":[{\"cost\":60,\"id\":13}]},{\"id\":15,\"x\":919,\"y\":17,\"Proy\":\"graph\",\"list\":[{\"cost\":59,\"id\":13}]},{\"id\":16,\"x\":689,\"y\":-40,\"Proy\":\"graph\",\"list\":[{\"cost\":229,\"id\":13},{\"cost\":61,\"id\":17},{\"cost\":197,\"id\":20}]},{\"id\":17,\"x\":685,\"y\":-101,\"Proy\":\"graph\",\"list\":[{\"cost\":61,\"id\":16}]},{\"id\":18,\"x\":349,\"y\":-37,\"Proy\":\"graph\",\"list\":[{\"cost\":238,\"id\":5},{\"cost\":65,\"id\":19},{\"cost\":143,\"id\":20},{\"cost\":273,\"id\":27},{\"cost\":137,\"id\":50}]},{\"id\":19,\"x\":349,\"y\":-102,\"Proy\":\"graph\",\"list\":[{\"cost\":65,\"id\":18}]},{\"id\":20,\"x\":492,\"y\":-39,\"Proy\":\"graph\",\"list\":[{\"cost\":197,\"id\":16},{\"cost\":143,\"id\":18},{\"cost\":50,\"id\":21}]},{\"id\":21,\"x\":493,\"y\":11,\"Proy\":\"graph\",\"list\":[{\"cost\":50,\"id\":20}]},{\"id\":22,\"x\":-387,\"y\":-31,\"Proy\":\"graph\",\"list\":[{\"cost\":126,\"id\":3},{\"cost\":253,\"id\":4},{\"cost\":62,\"id\":23},{\"cost\":66,\"id\":24}]},{\"id\":23,\"x\":-339,\"y\":9,\"Proy\":\"graph\",\"list\":[{\"cost\":62,\"id\":22}]},{\"id\":24,\"x\":-386,\"y\":-97,\"Proy\":\"graph\",\"list\":[{\"cost\":66,\"id\":22}]},{\"id\":25,\"x\":-132,\"y\":-99,\"Proy\":\"graph\",\"list\":[{\"cost\":66,\"id\":4}]},{\"id\":26,\"x\":111,\"y\":-100,\"Proy\":\"graph\",\"list\":[{\"cost\":65,\"id\":5}]},{\"id\":27,\"x\":111,\"y\":98,\"Proy\":\"graph\",\"list\":[{\"cost\":133,\"id\":5},{\"cost\":273,\"id\":18},{\"cost\":57,\"id\":28},{\"cost\":155,\"id\":29},{\"cost\":238,\"id\":50}]},{\"id\":28,\"x\":111,\"y\":155,\"Proy\":\"graph\",\"list\":[{\"cost\":57,\"id\":27}]},{\"id\":29,\"x\":-44,\"y\":97,\"Proy\":\"graph\",\"list\":[{\"cost\":155,\"id\":27},{\"cost\":60,\"id\":30},{\"cost\":183,\"id\":31}]},{\"id\":30,\"x\":-42,\"y\":157,\"Proy\":\"graph\",\"list\":[{\"cost\":60,\"id\":29}]},{\"id\":31,\"x\":-227,\"y\":96,\"Proy\":\"graph\",\"list\":[{\"cost\":165,\"id\":3},{\"cost\":183,\"id\":29},{\"cost\":56,\"id\":32}]},{\"id\":32,\"x\":-229,\"y\":152,\"Proy\":\"graph\",\"list\":[{\"cost\":56,\"id\":31}]},{\"id\":33,\"x\":-393,\"y\":153,\"Proy\":\"graph\",\"list\":[{\"cost\":58,\"id\":3}]},{\"id\":34,\"x\":-550,\"y\":57,\"Proy\":\"graph\",\"list\":[{\"cost\":37,\"id\":2}]},{\"id\":35,\"x\":-553,\"y\":151,\"Proy\":\"graph\",\"list\":[{\"cost\":57,\"id\":2}]},{\"id\":36,\"x\":-701,\"y\":93,\"Proy\":\"graph\",\"list\":[{\"cost\":150,\"id\":2},{\"cost\":41,\"id\":37},{\"cost\":62,\"id\":38},{\"cost\":162,\"id\":39}]},{\"id\":37,\"x\":-699,\"y\":52,\"Proy\":\"graph\",\"list\":[{\"cost\":41,\"id\":36}]},{\"id\":38,\"x\":-702,\"y\":155,\"Proy\":\"graph\",\"list\":[{\"cost\":62,\"id\":36}]},{\"id\":39,\"x\":-863,\"y\":92,\"Proy\":\"graph\",\"list\":[{\"cost\":162,\"id\":36},{\"cost\":46,\"id\":40},{\"cost\":61,\"id\":41},{\"cost\":156,\"id\":42}]},{\"id\":40,\"x\":-862,\"y\":46,\"Proy\":\"graph\",\"list\":[{\"cost\":46,\"id\":39}]},{\"id\":41,\"x\":-865,\"y\":153,\"Proy\":\"graph\",\"list\":[{\"cost\":61,\"id\":39}]},{\"id\":42,\"x\":-1019,\"y\":91,\"Proy\":\"graph\",\"list\":[{\"cost\":156,\"id\":39},{\"cost\":47,\"id\":43},{\"cost\":59,\"id\":44},{\"cost\":153,\"id\":45}]},{\"id\":43,\"x\":-1016,\"y\":44,\"Proy\":\"graph\",\"list\":[{\"cost\":47,\"id\":42}]},{\"id\":44,\"x\":-1021,\"y\":150,\"Proy\":\"graph\",\"list\":[{\"cost\":59,\"id\":42}]},{\"id\":45,\"x\":-1172,\"y\":91,\"Proy\":\"graph\",\"list\":[{\"cost\":153,\"id\":42},{\"cost\":45,\"id\":46},{\"cost\":96,\"id\":47},{\"cost\":56,\"id\":49}]},{\"id\":46,\"x\":-1169,\"y\":46,\"Proy\":\"graph\",\"list\":[{\"cost\":45,\"id\":45}]},{\"id\":47,\"x\":-1268,\"y\":90,\"Proy\":\"graph\",\"list\":[{\"cost\":77,\"id\":1},{\"cost\":96,\"id\":45},{\"cost\":40,\"id\":48}]},{\"id\":48,\"x\":-1266,\"y\":50,\"Proy\":\"graph\",\"list\":[{\"cost\":40,\"id\":47}]},{\"id\":49,\"x\":-1175,\"y\":147,\"Proy\":\"graph\",\"list\":[{\"cost\":56,\"id\":45}]},{\"id\":50,\"x\":349,\"y\":100,\"Proy\":\"graph\",\"list\":[{\"cost\":137,\"id\":18},{\"cost\":238,\"id\":27},{\"cost\":375,\"id\":51},{\"cost\":349,\"id\":60}]},{\"id\":51,\"x\":678,\"y\":282,\"Proy\":\"graph\",\"list\":[{\"cost\":375,\"id\":50},{\"cost\":132,\"id\":52},{\"cost\":164,\"id\":53}]},{\"id\":52,\"x\":810,\"y\":280,\"Proy\":\"graph\",\"list\":[{\"cost\":132,\"id\":51}]},{\"id\":53,\"x\":679,\"y\":446,\"Proy\":\"graph\",\"list\":[{\"cost\":164,\"id\":51},{\"cost\":81,\"id\":54},{\"cost\":318,\"id\":60}]},{\"id\":54,\"x\":760,\"y\":446,\"Proy\":\"graph\",\"list\":[{\"cost\":81,\"id\":53}]},{\"id\":55,\"x\":258,\"y\":453,\"Proy\":\"graph\",\"list\":[{\"cost\":127,\"id\":56},{\"cost\":103,\"id\":60}]},{\"id\":56,\"x\":258,\"y\":580,\"Proy\":\"graph\",\"list\":[{\"cost\":127,\"id\":55},{\"cost\":137,\"id\":57}]},{\"id\":57,\"x\":121,\"y\":581,\"Proy\":\"graph\",\"list\":[{\"cost\":137,\"id\":56},{\"cost\":42,\"id\":58},{\"cost\":47,\"id\":59}]},{\"id\":58,\"x\":120,\"y\":539,\"Proy\":\"graph\",\"list\":[{\"cost\":42,\"id\":57}]},{\"id\":59,\"x\":122,\"y\":628,\"Proy\":\"graph\",\"list\":[{\"cost\":47,\"id\":57}]},{\"id\":60,\"x\":361,\"y\":449,\"Proy\":\"graph\",\"list\":[{\"cost\":318,\"id\":53},{\"cost\":103,\"id\":55},{\"cost\":349,\"id\":50}]}]},\"decos\":[],\"icons\":[{\"no\":\"\",\"x\":114,\"y\":536,\"navCode\":58,\"facCode\":\"xsj\",\"title\":\"洗手间\",\"titleEn\":\"\",\"site\":0,\"angle\":0,\"state\":true,\"iShow\":true,\"downState\":false,\"upState\":false,\"toState\":true},{\"no\":\"\",\"x\":355,\"y\":103,\"navCode\":50,\"facCode\":\"fwt\",\"title\":\"服务台\",\"titleEn\":\"\",\"site\":0,\"angle\":0,\"state\":true,\"iShow\":true,\"downState\":false,\"upState\":false,\"toState\":true},{\"no\":\"\",\"x\":122,\"y\":628,\"navCode\":59,\"facCode\":\"mys\",\"title\":\"母婴室\",\"titleEn\":\"\",\"site\":0,\"angle\":0,\"state\":true,\"iShow\":true,\"downState\":false,\"upState\":false,\"toState\":true}],\"stairs\":[{\"no\":\"\",\"x\":811,\"y\":277,\"navCode\":52,\"facCode\":\"dt\",\"title\":\"直梯\",\"titleEn\":\"\",\"site\":0,\"angle\":0,\"state\":true,\"iShow\":true,\"downState\":false,\"upState\":false,\"toState\":true},{\"no\":\"\",\"x\":-335,\"y\":7,\"navCode\":23,\"facCode\":\"ft\",\"title\":\"扶梯\",\"titleEn\":\"\",\"site\":0,\"angle\":90,\"state\":true,\"iShow\":true,\"downState\":true,\"upState\":false,\"toState\":true}],\"parkArea\":[],\"wallArea\":[{\"id\":\"bc1bd60f8919\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":-1080,\"y\":-240},{\"x\":-1080,\"y\":32}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"bd0a23a58583\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":-1224,\"y\":-170},{\"x\":-1224,\"y\":32}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"85f6a3350834\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":-932,\"y\":-140},{\"x\":-932,\"y\":32}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"96e7a966ef66\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":-766,\"y\":-140},{\"x\":-766,\"y\":32}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"77e954a94ec0\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":-618,\"y\":-319},{\"x\":-618,\"y\":32}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"a86ab003b5ab\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":-557,\"y\":-319},{\"x\":-476,\"y\":-319}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"a86ab003b5ab\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":-476,\"y\":-319},{\"x\":-476,\"y\":-122}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"b089da41f459\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":-247,\"y\":-534},{\"x\":-247,\"y\":-122}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"96cffbc3fb47\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":8,\"y\":-287},{\"x\":8,\"y\":-122}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"7c7b082bf2b6\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":198,\"y\":-431},{\"x\":198,\"y\":-122}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"e9dae9ad0876\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":512,\"y\":-431},{\"x\":512,\"y\":-122}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"af23710dcba6\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":837,\"y\":-299},{\"x\":837,\"y\":-122}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"86df1131de89\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":978,\"y\":-300},{\"x\":978,\"y\":-122}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"d0b55ebea895\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":1118,\"y\":-431},{\"x\":1118,\"y\":-122}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"08aba9038cb2\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":-1083,\"y\":173},{\"x\":-1083,\"y\":493}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"8ef484f252ba\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":-931,\"y\":173},{\"x\":-931,\"y\":493}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"0ba690c6ac85\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":-770,\"y\":173},{\"x\":-770,\"y\":493}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"9574a7257ec0\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":-617,\"y\":173},{\"x\":-617,\"y\":493}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"d51d7b910937\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":-462,\"y\":173},{\"x\":-462,\"y\":493}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"eb55b023d7b8\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":-311,\"y\":173},{\"x\":-311,\"y\":493}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"dae84185ae27\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":-124,\"y\":173},{\"x\":-124,\"y\":493}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"b72c1cd49f81\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":30,\"y\":173},{\"x\":30,\"y\":434}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"95cef2fd7e29\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":1088,\"y\":351},{\"x\":1012,\"y\":351}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"95cef2fd7e29\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":1012,\"y\":351},{\"x\":1012,\"y\":194}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0},{\"id\":\"95cef2fd7e29\",\"name\":\"shopWall\",\"pathPoints\":[{\"x\":1012,\"y\":194},{\"x\":907,\"y\":194}],\"thick\":4,\"isWall\":true,\"entColor\":\"#FFFFFF\",\"borderColor\":\"#FFFFFF\",\"toHeight\":51,\"alphaModle\":100,\"site\":0}],\"svgArea\":[],\"models\":[],\"animations\":[],\"axisTo\":{\"gps\":[],\"local\":[],\"oTom\":[],\"mToo\":[]}},\"code\":\"NVHbokkrXi7-P1pOIaHCx\"}],\"code\":\"dZJSO_9LbEwjrgpcfVRpK\",\"facSize\":40}]",
+ "createTime": "2024-01-05 10:22:42",
+ "updateTime": "2025-06-06 17:15:27"
+ },
+ "traceId": "cb579d10581d47c28afdaf4ec0bbe20a.74.17492013367886377"
+}
\ No newline at end of file
diff --git a/public/offline/queryShopList.json b/public/offline/queryShopList.json
new file mode 100644
index 0000000..abf53bf
--- /dev/null
+++ b/public/offline/queryShopList.json
@@ -0,0 +1,778 @@
+{
+ "code": 200,
+ "msg": "操作成功",
+ "data": {
+ "listObject": [
+ {
+ "id": 32112,
+ "shopCode": "TDJVS2AScHnkLqFyMokwm",
+ "name": "南京大排档",
+ "nameEn": "南京大牌档",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "餐饮",
+ "logoCode": "cK1NVm5w9JKsBbNhb47HF",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250606/cK1NVm5w9JKsBbNhb47HF.jpg",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "7l9kcAfHriFK93MEU8r95",
+ "building": "一期",
+ "floorCode": "j4wxPFAWbs3lgTtg00I_q",
+ "floor": "L7",
+ "houseNumber": "F705",
+ "contact": "",
+ "businessHours": "",
+ "introOl": "南京大牌档始创于1994年,是南京人展示独特金陵菜系的古典饭店品牌,在秉承原新街口南京大排档之浓郁民俗风格基础之上,又有创新和升华,数百种民厨小食,田园时蔬,家常烹煮,口味地道。南京大牌档有20余间各款江南小阁、随处可见的楹联灯幌、穿梭于桌台间的古装堂倌,充溢着中华传统民俗风情,气韵古雅,再现清末民初茶楼酒肆之旧貌。",
+ "status": 0,
+ "industryFatherCode": "IMfcJ4ayFhf_4JMUZq8Fv",
+ "industryCode": "",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ },
+ {
+ "id": 32109,
+ "shopCode": "gxo3s3Nb5K0hSbrj9VKnK",
+ "name": "德合禧狮",
+ "nameEn": "",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "餐饮",
+ "logoCode": "lu8siYE599eWf0swP59A-",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250526/lu8siYE599eWf0swP59A-.jpg",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "yUu64OIyH49L7Pso2dM9L",
+ "building": "二期",
+ "floorCode": "OWGxb3HIq7Wod0w5poE_-",
+ "floor": "L7",
+ "houseNumber": "F712",
+ "contact": "",
+ "businessHours": "",
+ "intro": "德合禧狮,全国首店落座南京德基广场二期7楼。其氛围设计源于新加坡司令的“鸡尾酒杯”,置身双层挑高空间,尽显经典高级。这里主打正宗新加坡菜,招牌黑白胡椒蟹、莱记海南鸡不容错过,还有特色甜品车。来德合禧狮,为欢禧干杯 。 ",
+ "introOl": "",
+ "status": 0,
+ "industryFatherCode": "IMfcJ4ayFhf_4JMUZq8Fv",
+ "industryCode": "vtV8YqwcB2OmLkxgfWn-F",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ },
+ {
+ "id": 32108,
+ "shopCode": "yq9cH1yhK9TulYZn3L0PZ",
+ "name": "NEEDCREATE",
+ "nameEn": "NEEDCREATE",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "餐饮",
+ "logoCode": "2WYTza6AB1aC_bPFoL6-O",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250526/2WYTza6AB1aC_bPFoL6-O.png",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "yUu64OIyH49L7Pso2dM9L",
+ "building": "二期",
+ "floorCode": "OWGxb3HIq7Wod0w5poE_-",
+ "floor": "L7",
+ "houseNumber": "F710-1",
+ "contact": "",
+ "businessHours": "",
+ "intro": "NEED是个极具创意的品牌,在不同领域展现独特魅力。NEED市集创立于2021年,瞄准潮流青年,以音乐、艺术、摄影为特色,设“need!flea”等区域。NEED韩国料理坚持手作,用现代技法重新演绎传统韩餐。NEEDT则专注时尚定制,打造多元潮牌。 ",
+ "introOl": "",
+ "status": 0,
+ "industryFatherCode": "IMfcJ4ayFhf_4JMUZq8Fv",
+ "industryCode": "vtV8YqwcB2OmLkxgfWn-F",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ },
+ {
+ "id": 32107,
+ "shopCode": "LbeLfk4vbOCkEOB_P0QZi",
+ "name": "黑牛の店",
+ "nameEn": "",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "餐饮",
+ "logoCode": "6wqO70R9YmRXyLnL2QHsW",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250526/6wqO70R9YmRXyLnL2QHsW.jpg",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "yUu64OIyH49L7Pso2dM9L",
+ "building": "二期",
+ "floorCode": "OWGxb3HIq7Wod0w5poE_-",
+ "floor": "L7",
+ "houseNumber": "F703",
+ "contact": "",
+ "businessHours": "",
+ "intro": "黑牛の店,传承30年烧肉经验,火遍上海、深圳等十余城,还多次上榜必吃榜。店内甄选顶尖5%的澳洲金凤凰和牛,品质非凡。装修潮酷,黑红色调搭配绿植,宽敞明亮。更有专人帮烤,把控火候。招牌烧肉的女王不容错过,快来享受舌尖盛宴 。 ",
+ "introOl": "",
+ "status": 0,
+ "industryFatherCode": "IMfcJ4ayFhf_4JMUZq8Fv",
+ "industryCode": "vtV8YqwcB2OmLkxgfWn-F",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ },
+ {
+ "id": 32106,
+ "shopCode": "z4r8nlbJfYCMK7UtBDQoz",
+ "name": "蟹道力二多食",
+ "nameEn": "",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "餐饮",
+ "logoCode": "0Ik3ys_nC6xwdB-gbIbNl",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250526/0Ik3ys_nC6xwdB-gbIbNl.png",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "yUu64OIyH49L7Pso2dM9L",
+ "building": "二期",
+ "floorCode": "OWGxb3HIq7Wod0w5poE_-",
+ "floor": "L7",
+ "houseNumber": "F718",
+ "contact": "",
+ "businessHours": "",
+ "intro": "蟹道力二多食,专注打造一蟹多吃的艺术美学餐厅。在这里,一只活雪蟹便能演绎出六重美味,刺身的鲜嫩、炭烤的焦香、蒸笼的原味、火锅的鲜美、泡饭的醇厚,还有茶碗蒸的细腻,搭配色拉和卷物双拼,带来丰富的味觉享受,就餐体验也十分出色。 ",
+ "introOl": "",
+ "status": 0,
+ "industryFatherCode": "IMfcJ4ayFhf_4JMUZq8Fv",
+ "industryCode": "vtV8YqwcB2OmLkxgfWn-F",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ },
+ {
+ "id": 32105,
+ "shopCode": "kPQIXENTvQe5nDsSyoG__",
+ "name": "富贵椰",
+ "nameEn": "",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "餐饮",
+ "logoCode": "31Tyl23FBgHvnY93zdXda",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250526/31Tyl23FBgHvnY93zdXda.png",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "yUu64OIyH49L7Pso2dM9L",
+ "building": "二期",
+ "floorCode": "OWGxb3HIq7Wod0w5poE_-",
+ "floor": "L7",
+ "houseNumber": "F716",
+ "contact": "",
+ "businessHours": "",
+ "intro": "富贵椰是一家充满特色的泰式餐厅,创立于 2022 年,以 “take a thai break” 为口号。店内绿植环绕,充满东南亚风情,仿佛曼谷后花园。行政总厨来自曼谷,菜品融合传统与现代风味,还有丰富酒单,是享受泰餐与休闲小酌的好去处。",
+ "introOl": "",
+ "status": 0,
+ "industryFatherCode": "IMfcJ4ayFhf_4JMUZq8Fv",
+ "industryCode": "vtV8YqwcB2OmLkxgfWn-F",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ },
+ {
+ "id": 32104,
+ "shopCode": "Ouv8qMRT4sxyxhj41SSl0",
+ "name": "PENHALIGON'S",
+ "nameEn": "PENHALIGON'S",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "零售",
+ "logoCode": "pN8hWvFGCDuT_DLiya1Xw",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250526/pN8hWvFGCDuT_DLiya1Xw.png",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "yUu64OIyH49L7Pso2dM9L",
+ "building": "二期",
+ "floorCode": "9G0HmClDfTdp5lvCCHQB9",
+ "floor": "C1",
+ "houseNumber": "C169",
+ "contact": "",
+ "businessHours": "",
+ "intro": "PENHALIGON'S 是创立于 1870 年的英国香水品牌。它以精湛工艺和英伦风格著称,融合经典传承与创新理念。产品多样,包装优雅,其香氛富有特色。品牌定位中高端,致力于为消费者打造独特迷人的香氛世界。",
+ "introOl": "",
+ "status": 0,
+ "industryFatherCode": "r4Uo7CNqF50UGiPmqJ2hq",
+ "industryCode": "RzUD84ZIxro1y-s5LRv00",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ },
+ {
+ "id": 32103,
+ "shopCode": "R4jlJoHMfdfxPxcLZ-301",
+ "name": "ROLEX",
+ "nameEn": "ROLEX",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "零售",
+ "logoCode": "tzmaktU2PE6LKb2yp1r48",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250526/tzmaktU2PE6LKb2yp1r48.png",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "yUu64OIyH49L7Pso2dM9L",
+ "building": "二期",
+ "floorCode": "xoWQJPuk-5XBSZ6US0Qz_",
+ "floor": "L1",
+ "houseNumber": "F119",
+ "contact": "",
+ "businessHours": "",
+ "intro": "劳力士(Rolex)是 1905 年由汉斯・威斯多夫与戴维斯在伦敦创立的瑞士著名手表制造商。1908 年正式更名,总部位于日内瓦。它以精准、耐用和创新闻名,推出蚝式腕表、恒动摆陀等,是高端奢华品牌,深受成功人士喜爱。",
+ "introOl": "",
+ "status": 0,
+ "industryFatherCode": "r4Uo7CNqF50UGiPmqJ2hq",
+ "industryCode": "pvGCVdplz5taKcDQnTrpm",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ },
+ {
+ "id": 32102,
+ "shopCode": "dgIJFNAS2dPPdXWWTBgxP",
+ "name": "老铺黄金",
+ "nameEn": "",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "零售",
+ "logoCode": "iucT2rzvfoXR7-UhD6d0L",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250526/iucT2rzvfoXR7-UhD6d0L.png",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "yUu64OIyH49L7Pso2dM9L",
+ "building": "二期",
+ "floorCode": "It2h-cl0AMXZqdsYKYNw_",
+ "floor": "L3",
+ "houseNumber": "F305",
+ "contact": "",
+ "businessHours": "",
+ "intro": "老铺黄金创立于 2009 年,专营中国古法手工金器,是古法黄金高端品牌。它传承中国宫廷古法制金工艺,产品线涵盖古法黄金饰品、古法黄金(足金)钻石饰品、古法黄金金器三大类。其产品设计精美,兼具经典与时尚,尽显极致品质,致力于打造可传世的金器。",
+ "introOl": "",
+ "status": 0,
+ "industryFatherCode": "r4Uo7CNqF50UGiPmqJ2hq",
+ "industryCode": "8pP3SzereNDbiRmR9i9nU",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ },
+ {
+ "id": 32101,
+ "shopCode": "-npkYHZNl79q-4dqCvnue",
+ "name": "GUCCI(Watch and Jewelry)",
+ "nameEn": "",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "零售",
+ "logoCode": "_X42VHniE90kKCTw2Z6SA",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250526/_X42VHniE90kKCTw2Z6SA.png",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "yUu64OIyH49L7Pso2dM9L",
+ "building": "二期",
+ "floorCode": "9G0HmClDfTdp5lvCCHQB9",
+ "floor": "C1",
+ "houseNumber": "C152",
+ "contact": "",
+ "businessHours": "",
+ "intro": "GUCCI(Watch and Jewelry)系列展现意式奢华魅力。1921 年品牌创立,70 年代涉足制表业,90 年代推出银饰与珍贵珠宝。腕表于瑞士制表工坊打造,珠宝由意大利工匠雕琢,融入经典元素,将高品质材料与独特美学结合,尽显优雅迷人风范 。",
+ "introOl": "",
+ "status": 0,
+ "industryFatherCode": "r4Uo7CNqF50UGiPmqJ2hq",
+ "industryCode": "8pP3SzereNDbiRmR9i9nU",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ },
+ {
+ "id": 32100,
+ "shopCode": "NEaGPsSm770DoptgykLsK",
+ "name": "GUCCI香水",
+ "nameEn": "",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "零售",
+ "logoCode": "uZ1gz-TQ069oVqTyNuGNJ",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250526/uZ1gz-TQ069oVqTyNuGNJ.png",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "yUu64OIyH49L7Pso2dM9L",
+ "building": "二期",
+ "floorCode": "9G0HmClDfTdp5lvCCHQB9",
+ "floor": "C1",
+ "houseNumber": "C166",
+ "contact": "",
+ "businessHours": "",
+ "intro": "GUCCI香水于1921年创立,风格独特。其花悦系列以粉色陶瓷瓶身和繁花设计吸睛,花香调以茉莉为基底,留香久。罪爱系列经典,酒瓶形瓶身搭配双色设计,产品线丰富。绮梦栀子香型香水,粉色瓶身,主调是栀子花与茉莉,香甜迷人 。 ",
+ "introOl": "",
+ "status": 0,
+ "industryFatherCode": "r4Uo7CNqF50UGiPmqJ2hq",
+ "industryCode": "RzUD84ZIxro1y-s5LRv00",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ },
+ {
+ "id": 32099,
+ "shopCode": "F2FJXVrXhdSHqQdLoUf2-",
+ "name": "HARRY WINSTON",
+ "nameEn": "",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "零售",
+ "logoCode": "Hm4HUw5WvcY8nR3BwTstR",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250526/Hm4HUw5WvcY8nR3BwTstR.png",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "yUu64OIyH49L7Pso2dM9L",
+ "building": "二期",
+ "floorCode": "xoWQJPuk-5XBSZ6US0Qz_",
+ "floor": "L1",
+ "houseNumber": "F102",
+ "contact": "",
+ "businessHours": "",
+ "intro": "HARRY WINSTON 是 1932 年由海瑞・温斯顿在纽约创立的美国珠宝与腕表品牌,属斯沃琪集团。它以 “钻石之王” 美誉闻名,设计理念独特,产品有高级珠宝、婚嫁珠宝和腕表等,在全球多地设有门店,是高净值人群青睐的奢侈品牌。",
+ "introOl": "",
+ "status": 0,
+ "industryFatherCode": "r4Uo7CNqF50UGiPmqJ2hq",
+ "industryCode": "8pP3SzereNDbiRmR9i9nU",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ },
+ {
+ "id": 32098,
+ "shopCode": "HDY18nwoloIjffHwFC_0a",
+ "name": "PRADA",
+ "nameEn": "PRADA",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "零售",
+ "logoCode": "Khehp_E4NxmKxCAg7y5vu",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250526/Khehp_E4NxmKxCAg7y5vu.png",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "7l9kcAfHriFK93MEU8r95",
+ "building": "一期",
+ "floorCode": "E0StNaAVKleCUEnte9_xb",
+ "floor": "B1",
+ "houseNumber": "B127",
+ "contact": "",
+ "businessHours": "",
+ "intro": "PRADA是1913年于意大利米兰创立的奢侈品牌。由马里奥·普拉达始创,现任掌门人缪西娅·普拉达赋予品牌灵魂。其产品涵盖手提袋、成衣、香水等多个品类。品牌在经典与创新间平衡,如Moon手袋展现独特魅力。通过多样宣传,在时尚界地位斐然 。 ",
+ "introOl": "",
+ "status": 0,
+ "industryFatherCode": "r4Uo7CNqF50UGiPmqJ2hq",
+ "industryCode": "RzUD84ZIxro1y-s5LRv00",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ },
+ {
+ "id": 32097,
+ "shopCode": "ApeoiFxFASSi4KFks7Io4",
+ "name": "阿嬷手作",
+ "nameEn": "",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "餐饮",
+ "logoCode": "q1zOVbGGfN95Z9Ivav9z9",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250526/q1zOVbGGfN95Z9Ivav9z9.png",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "7l9kcAfHriFK93MEU8r95",
+ "building": "一期",
+ "floorCode": "E0StNaAVKleCUEnte9_xb",
+ "floor": "B1",
+ "houseNumber": "B119-B158",
+ "contact": "",
+ "businessHours": "",
+ "intro": "阿嬷手作2018年创立于广西,是主打手作健康饮品的热门奶茶品牌。坚持以广西本土真材实料,现熬煮制、现场制作。每款饮品底料古法熬制,不添加调味料。将特色水果与茶饮结合,在广东、上海等地开有多家门店,传递家的温暖与质朴风味 。 ",
+ "introOl": "",
+ "status": 0,
+ "industryFatherCode": "IMfcJ4ayFhf_4JMUZq8Fv",
+ "industryCode": "_J24ggjWBfyhFPR7lfk-P",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ },
+ {
+ "id": 32096,
+ "shopCode": "S2cMBGLwVtVTrDpWJVBRj",
+ "name": "gaga",
+ "nameEn": "gaga",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "餐饮",
+ "logoCode": "S4yrK8WLqiP83aK65UAFG",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250526/S4yrK8WLqiP83aK65UAFG.png",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "7l9kcAfHriFK93MEU8r95",
+ "building": "一期",
+ "floorCode": "E0StNaAVKleCUEnte9_xb",
+ "floor": "B1",
+ "houseNumber": "B115",
+ "contact": "",
+ "businessHours": "",
+ "intro": "gaga创立于2010年,是知名的全时段茶饮轻食连锁品牌。门店分布于北京、上海等城市,旗下有多个不同风格的餐饮品牌。它以茶饮为特色,提供新鲜水果茶、咖啡、沙拉、意面等产品,秉持“连锁不简单复制”理念,为都市人打造休闲社交空间 。 ",
+ "introOl": "",
+ "status": 0,
+ "industryFatherCode": "IMfcJ4ayFhf_4JMUZq8Fv",
+ "industryCode": "_J24ggjWBfyhFPR7lfk-P",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ },
+ {
+ "id": 32095,
+ "shopCode": "g4dtCSWN89A_uLJ1sFnE4",
+ "name": "威尔胜",
+ "nameEn": "",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "零售",
+ "logoCode": "YXJrU4unedgOu30shUqvt",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250526/YXJrU4unedgOu30shUqvt.png",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "7l9kcAfHriFK93MEU8r95",
+ "building": "一期",
+ "floorCode": "bMAFNeXfipzfUPufcKAZ8",
+ "floor": "L6",
+ "houseNumber": "L610",
+ "contact": "",
+ "businessHours": "",
+ "intro": "威尔胜1914年创立于美国芝加哥,是知名运动品牌。它专注于高性能运动装备、服饰等制造,业务覆盖篮球、网球等多个领域。凭借创新科技,如篮球吸湿专利等,产品专业品质过硬,是众多职业赛事指定品牌,深受运动员与爱好者喜爱 。 ",
+ "introOl": "",
+ "status": 0,
+ "industryFatherCode": "r4Uo7CNqF50UGiPmqJ2hq",
+ "industryCode": "W1aFyk-eqsnbgKI3RYc6t",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ },
+ {
+ "id": 32094,
+ "shopCode": "buXqtL658TaHDPF59FN93",
+ "name": "萨洛蒙",
+ "nameEn": "SALOMON",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "零售",
+ "logoCode": "OEvRmip-q6pAlYHQN_KFm",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250526/OEvRmip-q6pAlYHQN_KFm.png",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "7l9kcAfHriFK93MEU8r95",
+ "building": "一期",
+ "floorCode": "bMAFNeXfipzfUPufcKAZ8",
+ "floor": "L6",
+ "houseNumber": "L607",
+ "contact": "",
+ "businessHours": "",
+ "intro": "萨洛蒙1947年创立于法国阿尔卑斯山,是专业户外运动品牌。品牌初期专注滑雪装备,如今产品线涵盖滑雪、越野、徒步等领域的鞋服及器材。它秉持创新精神,以先进科技打造产品,为户外运动爱好者提供专业装备,深受全球消费者青睐 。 ",
+ "introOl": "",
+ "status": 0,
+ "industryFatherCode": "r4Uo7CNqF50UGiPmqJ2hq",
+ "industryCode": "W1aFyk-eqsnbgKI3RYc6t",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ },
+ {
+ "id": 32093,
+ "shopCode": "YQR68FEGQHibTfoOF0J2t",
+ "name": "NIKE",
+ "nameEn": "NIKE",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "零售",
+ "logoCode": "yYq1_7fEobYErimT7H_eq",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250526/yYq1_7fEobYErimT7H_eq.png",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "7l9kcAfHriFK93MEU8r95",
+ "building": "一期",
+ "floorCode": "tMmsTU--liKcv2Vq1-8gD",
+ "floor": "L5",
+ "houseNumber": "L530",
+ "contact": "",
+ "businessHours": "",
+ "intro": "Nike(耐克)于 1962 年由田径教练比尔・鲍尔曼和运动员菲尔・奈特在美国创立,名字源于希腊胜利女神。其产品涵盖男女及儿童的鞋类、服装、配件等。首创的气垫技术革新了运动鞋。凭借 “轻资产” 运营、明星代言及创意广告,品牌影响力持续扩大,多年蝉联全球最具价值服装品牌榜首 。",
+ "introOl": "",
+ "status": 0,
+ "industryFatherCode": "r4Uo7CNqF50UGiPmqJ2hq",
+ "industryCode": "W1aFyk-eqsnbgKI3RYc6t",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ },
+ {
+ "id": 32092,
+ "shopCode": "oBBwRC-o_tbsA5fZq3dim",
+ "name": "老铺黄金",
+ "nameEn": "",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "零售",
+ "logoCode": "y_651an8-zKcnjxh0CkR5",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250526/y_651an8-zKcnjxh0CkR5.png",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "7l9kcAfHriFK93MEU8r95",
+ "building": "一期",
+ "floorCode": "872Ph9GCIF4QWWJl23wgt",
+ "floor": "L3",
+ "houseNumber": "L303",
+ "contact": "",
+ "businessHours": "",
+ "intro": "老铺黄金创立于 2009 年,是中国古法黄金高端品牌。专营中国古法手工金器,产品涵盖古法黄金饰品、钻石饰品、金器三大产品线。它传承中国宫廷古法制金工艺,坚持原创设计,产品经典、极致、可传世,2024 年在港交所上市,发展势头强劲。",
+ "introOl": "",
+ "status": 0,
+ "industryFatherCode": "r4Uo7CNqF50UGiPmqJ2hq",
+ "industryCode": "8pP3SzereNDbiRmR9i9nU",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ },
+ {
+ "id": 32091,
+ "shopCode": "-kmdZ1imK14GPZ3boXYcT",
+ "name": "路易威登",
+ "nameEn": "LV",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "零售",
+ "logoCode": "zaqIzaEba_HpDynCWv0XC",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250526/zaqIzaEba_HpDynCWv0XC.png",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "7l9kcAfHriFK93MEU8r95",
+ "building": "一期",
+ "floorCode": "EAoHuHvnswYDjbW_3-8jb",
+ "floor": "L1",
+ "houseNumber": "L101-L102-L201-L202",
+ "contact": "",
+ "businessHours": "",
+ "intro": "路易威登是 1854 年创立于法国的奢侈品牌。由路易・威登创立,起初以制作行李箱闻名,后发展为涵盖手提包、鞋履、成衣、珠宝等多品类的时尚品牌。其品牌标识醒目,设计风格融合时尚与经典,以高品质和精湛工艺著称,在全球奢侈品行业中占据重要地位。",
+ "introOl": "",
+ "status": 0,
+ "industryFatherCode": "r4Uo7CNqF50UGiPmqJ2hq",
+ "industryCode": "nQcL2qFWxCIg5EnZhMDLl",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ },
+ {
+ "id": 32090,
+ "shopCode": "X8SSEhnCPws9CwJslKYJX",
+ "name": "巴黎世家",
+ "nameEn": "BALENCIAGA",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "零售",
+ "logoCode": "n_14MgGXO4L70zMo4Trb9",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250526/n_14MgGXO4L70zMo4Trb9.png",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "7l9kcAfHriFK93MEU8r95",
+ "building": "一期",
+ "floorCode": "EAoHuHvnswYDjbW_3-8jb",
+ "floor": "L1",
+ "houseNumber": "L133-L230",
+ "contact": "",
+ "businessHours": "",
+ "intro": "巴黎世家是 1917 年由西班牙设计师克里斯托瓦尔・巴伦西亚加创立的奢侈品牌,1937 年迁至法国巴黎。其设计风格独特,融合古典与现代,以精湛剪裁、创新理念和高品质面料著称,产品涵盖成衣、皮具、鞋履等,在时尚界具有重要影响力。",
+ "introOl": "",
+ "status": 0,
+ "industryFatherCode": "r4Uo7CNqF50UGiPmqJ2hq",
+ "industryCode": "nQcL2qFWxCIg5EnZhMDLl",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ },
+ {
+ "id": 32089,
+ "shopCode": "guI1KgAGJz4PPQqHKbUVC",
+ "name": "GUCCI",
+ "nameEn": "GUCCI",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "零售",
+ "logoCode": "Qk8Gnz0wM5yYSw7qGr7k1",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250526/Qk8Gnz0wM5yYSw7qGr7k1.png",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "7l9kcAfHriFK93MEU8r95",
+ "building": "一期",
+ "floorCode": "EAoHuHvnswYDjbW_3-8jb",
+ "floor": "L1",
+ "houseNumber": "L118-L208",
+ "contact": "",
+ "businessHours": "",
+ "intro": "GUCCI 于 1921 年在意大利佛罗伦萨创立,是极具影响力的奢侈品牌。它起初以手工皮具起家,专为欧洲贵族服务。历经百年,业务拓展至成衣、皮具、鞋履等多领域。品牌风格大胆创新,融合复古与现代,双 G 标识更是深入人心,彰显尊贵。",
+ "introOl": "",
+ "status": 0,
+ "industryFatherCode": "r4Uo7CNqF50UGiPmqJ2hq",
+ "industryCode": "nQcL2qFWxCIg5EnZhMDLl",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ },
+ {
+ "id": 32088,
+ "shopCode": "2qgI_N3gIFRDSbWVHVcxO",
+ "name": "宝诗龙",
+ "nameEn": "BOUCHERON",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "零售",
+ "logoCode": "f6jrmt43cbTmavQpAVPBV",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250526/f6jrmt43cbTmavQpAVPBV.png",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "7l9kcAfHriFK93MEU8r95",
+ "building": "一期",
+ "floorCode": "EAoHuHvnswYDjbW_3-8jb",
+ "floor": "L1",
+ "houseNumber": "L108",
+ "contact": "",
+ "businessHours": "",
+ "intro": "宝诗龙,这个于 1858 年由费德列克・宝诗龙创立的法国珠宝品牌,宛如一颗璀璨的星辰在时尚与珠宝的天空闪耀了近两个世纪。其创立之初,便在巴黎高级时尚中心 “皇宫区大街” 开设精品店,打破传统,运用垂直立体的胸像展示珠宝,开启了珠宝展示的新方式。",
+ "introOl": "",
+ "status": 0,
+ "industryFatherCode": "r4Uo7CNqF50UGiPmqJ2hq",
+ "industryCode": "8pP3SzereNDbiRmR9i9nU",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ },
+ {
+ "id": 32087,
+ "shopCode": "ZOY91G5p1GKXmEvZ8rYaQ",
+ "name": "HERMES",
+ "nameEn": "HERMES",
+ "nameOl": "",
+ "alias": "",
+ "industryFatherName": "零售",
+ "logoCode": "b506agcQ7d1F32ENfTqsG",
+ "logoUrl": "/iotFile/Moderation/iotFile/project-artfg6tetwlnbcyxnlqzra/20250526/b506agcQ7d1F32ENfTqsG.png",
+ "source": 0,
+ "regionCode": "",
+ "buildingCode": "7l9kcAfHriFK93MEU8r95",
+ "building": "一期",
+ "floorCode": "EAoHuHvnswYDjbW_3-8jb",
+ "floor": "L1",
+ "houseNumber": "L106-L206",
+ "contact": "",
+ "businessHours": "",
+ "intro": "爱马仕(HERMES)1837 年创立于法国巴黎,由蒂埃利・爱马仕开启品牌传奇。它从高级马具制造起步,坚守传统手工艺,不断创新。产品覆盖箱包、丝巾、领带、时装等十七类,经典如 Kelly 包、Birkin 包。门店遍布 45 国,以精湛工艺与独特设计闻名全球 。",
+ "introOl": "",
+ "status": 0,
+ "industryFatherCode": "r4Uo7CNqF50UGiPmqJ2hq",
+ "industryCode": "nQcL2qFWxCIg5EnZhMDLl",
+ "xaxis": "",
+ "yaxis": "",
+ "navXaxis": "",
+ "navYaxis": "",
+ "aliasNum": 0,
+ "aliasNames": [],
+ "isPointPosition": 0
+ }
+ ],
+ "itemCount": 23,
+ "pageCount": 1
+ },
+ "traceId": "ad623fd715a542168ee7290a5706dd77.311.17491004697120399"
+}
\ No newline at end of file
diff --git a/public/qm/MainMap_QM_label.js b/public/qm/MainMap_QM_label.js
new file mode 100644
index 0000000..8182ade
--- /dev/null
+++ b/public/qm/MainMap_QM_label.js
@@ -0,0 +1,8149 @@
+var Map_QM,
+ renderFrame = -1,
+ renderCount = 0,
+ pathCameraState,
+ mapState = "mall",
+ iconState = "3d",
+ heatmapInstance,
+ isShowElement = true,
+ isJUZ = false,
+ allJU = true,
+ hasLine = false,
+ intTimer,
+ shopTime,
+ pathNodes,
+ actionTime=-1,
+ allTime,
+ language = "zh";
+//basePath 基础路径 graphPath最佳路径 ftPath 扶梯路径 dtPath 电梯路径
+
+var QMUtil = function () {
+ this.shopServerInfo = "./offline/queryShopList.json";
+ this.mapServerInfo = "./offline/getMapInfo.json";
+ this.beforPath = "./"; //https://qianmu-iot.1000my.com/QMAPSDK/
+ this.tomUrl = "https://qianmu-iot.1000my.com";
+ this.options = {
+ playSpeed: 8, //动画播放速度
+ speedMult: 1, //动画播放倍数
+ collision: true, //是否支持名称的碰撞检测
+ 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}];
+ fSpace: 500, //双叠层状态下楼层的间距
+ maxDis: 700,
+ minDis: 80,
+ shadow: true, //是否显示阴影
+ navColor: 0xee6a50, //途径店铺颜色
+ aRadius: 2, //圆角半径 大于2 则店铺box显示圆角
+ iconName: false, //图标名称是否显示
+ pathColor: "#6e95fe", //
+ pathColor2: "#6e7dfe", //'rgb(110,125,254)'
+ pathBgColor: "#a9b5d3", //'rgb(169,181,211)'
+ pathBgColor2: "#bdc0cb", //'rgb(189, 192, 203)',
+ pathStyle: "2D",
+ shopStyle: "shopName", //设置box显示名称shopName或编号shopNum
+ inArea: false, //点击后是否聚焦到店铺
+ boxShop: [], //设置box上显示的文字(过滤指),可点击触发onlyShop
+ deviceAng: false, //地图初始化方向是否使用设备角度
+ northShow: false, //指南针显示
+ facSize: 20, //设施大小
+ };
+ this.lightOptions = {
+ d_col: "#ffffff",
+ d_int: 0.15,
+ s_col: "#fffffa",
+ g_col: "#ffffff",
+ a_int: 0.2,
+ };
+ this.m_zoom = 1.2; //2D地图缩放大小
+ this._clock = new THREE.Clock();
+ this._indexPathFloor = 0; // 遍历途径数据
+ this.changeDist = { inner: 300, outner: 900 };
+ /**
+ * isPathState 寻路状态
+ */
+ this.pathStateObj = {
+ isPathState: false,
+ isPathPlay: true,
+ basePath: "",
+ graphPath: "",
+ ftPath: "",
+ dtPath: "",
+ facAllArr: [],
+ forShopArr: {},
+ elevator: null,
+ straight: null,
+ elevatorDown: null,
+ seldtFacNo: { type: "", no: "" },
+ };
+ this.timeObj = { collTime: -1, pathTime: -1 };
+ this.sceneGap = { cameraX: 0, cameraY: 170, cameraZ: 170, x: 0, y: 0, z: 0, scale: 0.08 }; //改变地图位置,大小
+ this.isMorePath = false; //多节点寻路模式
+ this.selectBuild = 0;
+ this.selectFloor = 0;
+ this.deviceObj = {}; //angle --- 设备旋转角度 node ---- 设备导航点位 floor --- 设备楼层
+ this.startObj = {}; // 导航起点;
+ this.overObj = {}; //导航结束点
+ this.buildHeight = 5;
+ this.shopHeight = 30; //店铺高度 控制店铺相关的其它第三方组件高度
+ //添加平铺logo {floor:5, logoUrl:"./static/img/ss.png", imgW:395, imgH:376, xaxis:1550, yaxis:-860, site:30}
+ this.logos = [];
+ /**
+ * 外立面
+ * Map_QM.util.initModelArr=[{url:"./static/img/out/yong.glb",type:"out", scale:1, rot:{x:0,y:0,z:0}, site:{x:0,y:0,z:0}, colorModel:"gama" }];
+ */
+ this.initModelArr = []; //
+ /**
+ * 一直显示不隐藏, 在楼层内显示
+ * {build:15, floor:0, url:"static/img/out/floor.glb", list:[{size:{x:4.35,y:4.35,z:4.35}, rot:{x:90,y:0,z:0}, site:{x:-35,y:70,z:0}}]}
+ */
+ 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 }, 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: "tree3", url: "static/img/model/tree3.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
+ {key: "grass", url: "static/img/model/grass.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 }, load: false },
+ {key: "flower1", url: "static/img/model/flower1.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 20, y: 20, z: 20 },load: false},
+ {key: "flower2", url: "static/img/model/flower2.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: "park_paly", url: "static/img/model/park_paly.glb", colorModel: "gama", rot: { x: 1.5708, y: 0, z: 0 }, size: { x: 80, y: 80, z: 80 }, 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: "officeTV", url: "static/img/model/officeTV.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: "subway", url: "static/img/model/subway.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: "table", url: "static/img/model/table.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 = []; //精灵模型
+ /**
+ * 模型弹窗
+ */
+ 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"}}]);
+ */
+ this.labelIconArr = [];
+ this.spriteMaterialArr = [];
+ this.lineBasicMaterialArr = [];
+ this.meshMaterialArr = [];
+ this.parkMaterialArr = [];
+ this.shopData = []; //店铺数据
+ this.iconUrl = [];
+ this.allMap = [];
+ /*** ------------------------------------------------ 参数 API START ------------------------------------------------- */
+ this.exportImg = function () {
+ let tempSrc = Map_QM.renderer.domElement.toDataURL("image/png");
+ let a = document.createElement("a");
+ a.href = tempSrc;
+ a.setAttribute("download", "floor.png");
+ a.click();
+ };
+ /**
+ * @api {方法} changePlaySpeed(speedMult) 改变导航速度倍数
+ * @apiGroup 地图导航
+ * @apiDescription 改变导航播放速度倍数
+ * @apiVersion 4.0.0
+ *
+ * @apiParam {int} speedMult 播放速度倍数(默认 1)
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ *
+ * Map_QM.util.changePlaySpeed()
+ *
+ */
+ this.changePlaySpeed = function (speedMult = 1) {
+ Map_QM.util.options.speedMult = speedMult;
+ };
+ /*** ----------------------------------------------- 参数 API END ----------------------------------------------- **** */
+ this.Point = function (x = 0, y = 0) {
+ this.x = x;
+ this.y = y;
+ };
+ this.WallLine = function (start, end) {
+ this.start = start; //起始点位
+ this.end = end; //结束点位
+ this.leftParLine; //左侧平行线段
+ this.rightParLine; //右侧平行线段
+ this.leftPoint; //左侧平行线交点
+ this.rightPoint; //右侧平行线交点
+ };
+
+ this.assignUVs = function (geometry) {
+ geometry.computeBoundingBox();
+ let max = geometry.boundingBox.max,
+ min = geometry.boundingBox.min;
+ let offset = new THREE.Vector2(0 - min.x, 0 - min.y);
+ let range = new THREE.Vector2(max.x - min.x, max.y - min.y);
+ let addX = 1, addY = 1;
+ range.x / range.y < 1 ? (addX = range.x / range.y) : (addY = range.y / range.x);
+ geometry.faceVertexUvs[0] = [];
+ for (let face of geometry.faces) {
+ let v1 = geometry.vertices[face.a], v2 = geometry.vertices[face.b], v3 = geometry.vertices[face.c];
+ if (face.normal.z == 0) {
+ //侧面
+ if (range.x / range.y >= 1) {
+ let repY = range.y / 256 >= 2 ? 256 : range.y;
+ face.materialIndex = Math.abs(face.normal.x) < 0.7 ? 2 : 1;
+ geometry.faceVertexUvs[0].push(
+ face.materialIndex == 1
+ ? [
+ new THREE.Vector2((v1.y + offset.y) / repY, v1.z / 512),
+ new THREE.Vector2((v2.y + offset.y) / repY, v2.z / 512),
+ new THREE.Vector2((v3.y + offset.y) / repY, v3.z / 512),
+ ]
+ : [
+ new THREE.Vector2((v1.x + offset.x) / range.x, v1.z / 64),
+ new THREE.Vector2((v2.x + offset.x) / range.x, v2.z / 64),
+ new THREE.Vector2((v3.x + offset.x) / range.x, v3.z / 64),
+ ]
+ );
+ } else {
+ face.materialIndex = Math.abs(face.normal.x) < 0.7 ? 1 : 2;
+ geometry.faceVertexUvs[0].push(
+ face.materialIndex == 1
+ ? [
+ new THREE.Vector2((v1.x + offset.x) / range.x, v1.z / 512),
+ new THREE.Vector2((v2.x + offset.x) / range.x, v2.z / 512),
+ new THREE.Vector2((v3.x + offset.x) / range.x, v3.z / 512),
+ ]
+ : [
+ new THREE.Vector2((v1.y + offset.y) / range.y, v1.z / 64),
+ new THREE.Vector2((v2.y + offset.y) / range.y, v2.z / 64),
+ new THREE.Vector2((v3.y + offset.y) / range.y, v3.z / 64),
+ ]
+ );
+ }
+ } else {
+ //顶面和底面
+ face.materialIndex = 0;
+ geometry.faceVertexUvs[0].push([
+ new THREE.Vector2(
+ ((v1.x + offset.x) / range.x) * addX,
+ ((v1.y + offset.y) / range.y) * addY
+ ),
+ new THREE.Vector2(
+ ((v2.x + offset.x) / range.x) * addX,
+ ((v2.y + offset.y) / range.y) * addY
+ ),
+ new THREE.Vector2(
+ ((v3.x + offset.x) / range.x) * addX,
+ ((v3.y + offset.y) / range.y) * addY
+ ),
+ ]);
+ }
+ }
+ geometry.uvsNeedUpdate = true;
+ };
+ this.packUv = function (geometry) {
+ geometry.computeBoundingBox();
+ let max = geometry.boundingBox.max,
+ min = geometry.boundingBox.min;
+ let offset = new THREE.Vector2(0 - min.x, 0 - min.y);
+ let range = new THREE.Vector2(max.x - min.x, max.y - min.y);
+ geometry.faceVertexUvs[0] = [];
+ let allReag = 0;
+ for (let i = 0; i < geometry.faces.length; i += 2) {
+ let v1 = geometry.vertices[geometry.faces[i].a],
+ v2 = geometry.vertices[geometry.faces[i].b];
+ if (geometry.faces[i].normal.z == 0) {
+ //侧面
+ if (Math.abs(geometry.faces[i].normal.x) < 0.7) {
+ //左右
+ allReag += Math.abs(v2.x - v1.x);
+ } else {
+ allReag += Math.abs(v2.y - v1.y);
+ }
+ }
+ }
+ for (let face of geometry.faces) {
+ let v1 = geometry.vertices[face.a],
+ v2 = geometry.vertices[face.b],
+ v3 = geometry.vertices[face.c];
+ if (face.normal.z == 0) {
+ //侧面
+ face.materialIndex = 1;
+ if (Math.abs(face.normal.x) < 0.7) {
+ //前后
+ geometry.faceVertexUvs[0].push([
+ new THREE.Vector2((v1.x + offset.x) / allReag, v1.z / 512),
+ new THREE.Vector2((v2.x + offset.x) / allReag, v2.z / 512),
+ new THREE.Vector2((v3.x + offset.x) / allReag, v3.z / 512),
+ ]);
+ } else {
+ geometry.faceVertexUvs[0].push([
+ new THREE.Vector2((v1.y + offset.y) / allReag, v1.z / 512),
+ new THREE.Vector2((v2.y + offset.y) / allReag, v2.z / 512),
+ new THREE.Vector2((v3.y + offset.y) / allReag, v3.z / 512),
+ ]);
+ }
+ } else {
+ //顶面和底面
+ face.materialIndex = 0;
+ geometry.faceVertexUvs[0].push([
+ new THREE.Vector2(
+ (v1.x + offset.x) / range.x,
+ (v1.y + offset.y) / range.y
+ ),
+ new THREE.Vector2(
+ (v2.x + offset.x) / range.x,
+ (v2.y + offset.y) / range.y
+ ),
+ new THREE.Vector2(
+ (v3.x + offset.x) / range.x,
+ (v3.y + offset.y) / range.y
+ ),
+ ]);
+ }
+ }
+ };
+ /**
+ * 检测点是否在多边形区域内
+ */
+ this.checkBoundary = function (p, ptPolygon) {
+ // 判断边界方法
+ let nCount = ptPolygon.length;
+ let nCross = 0;
+ 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平行
+ continue;
+ if (p.y < Math.min(p1.y, p2.y))
+ // 交点在p1p2延长线上
+ continue;
+ 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))
+ //直线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++; // 只统计单边交点
+ }
+ // 单边交点为偶数,点在多边形之外 ---
+ return nCross % 2 == 1;
+ };
+ this.requestNoJM = function (params) {
+ params.method = params.method || "GET";
+ let xmlhttp = new XMLHttpRequest();
+ xmlhttp.onreadystatechange = function () {
+ if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
+ let jsonObject;
+ try {
+ jsonObject = JSON.parse(xmlhttp.responseText);
+ } catch (e) {
+ window.captureException && window.captureException(e);
+ params.fail();
+ return;
+ }
+ params.success(jsonObject);
+ }
+ if (
+ xmlhttp.readyState === 4 &&
+ (xmlhttp.status === 404 || xmlhttp.status === 405)
+ ) {
+ params.fail();
+ }
+ };
+ xmlhttp.onerror = function () {
+ params.fail();
+ };
+ xmlhttp.open(params.method, params.url, true);
+ //xmlhttp.setRequestHeader("Access-Control-Allow-Origin", "*");
+ xmlhttp.setRequestHeader("Content-type", "application/json");
+ xmlhttp.send(params.data);
+ };
+ //解密
+ this.decrypt = function (word, keyStr) {
+ keyStr = keyStr ? keyStr : "cqmyg#hdhxt!saas";
+ var key = CryptoJS.enc.Utf8.parse(keyStr); //Latin1 w8m31+Yy/Nw6thPsMpO5fg==
+ var decrypt = CryptoJS.AES.decrypt(word, key, {
+ mode: CryptoJS.mode.ECB,
+ padding: CryptoJS.pad.Pkcs7,
+ });
+ return CryptoJS.enc.Utf8.stringify(decrypt).toString();
+ };
+ this.timeStamp = function () {
+ return parseInt(new Date().getTime() / 1000);
+ };
+
+ this.readTextFile = function (file, callback) {
+ let rawFile = new XMLHttpRequest();
+ rawFile.overrideMimeType("application/json");
+ rawFile.open("GET", file, true);
+ rawFile.onreadystatechange = function () {
+ if (rawFile.readyState === 4 && rawFile.status == 200) {
+ try {
+ let jsonObject = JSON.parse(rawFile.response);
+ callback(jsonObject);
+ } catch (e) {
+ window.captureException && window.captureException(e);
+ }
+ }
+ };
+ rawFile.onerror = function () {
+ callback(null);
+ };
+ rawFile.send(null);
+ };
+ /**碰撞检测
+ * 传入A中心点和A的宽、高
+ * B的中心点和B的宽、高
+ */
+ this.isCollision = function (A, B) {
+ return (
+ A.x < B.x + B.width &&
+ A.x + A.width > B.x &&
+ A.y < B.y + B.height &&
+ A.y + A.height > B.y
+ );
+ };
+ this.changeParkToString = function (area) {
+ let areaArr = [];
+ for (let i = 0; i < area.hasLines.length; i++) {
+ let line = area.hasLines[i];
+ let array = [];
+ array.push( line.startPoint.x, line.startPoint.y, line.endPoint.x, line.endPoint.y);
+ areaArr.push(array);
+ }
+ return areaArr;
+ };
+ this.changeAreaToString = function (area) {
+ let areaArr = [];
+ for (let i = 0; i < area.hasLines.length; i++) {
+ let line = area.hasLines[i];
+ let array = [];
+ if (line.isStrLine) {
+ array.push(
+ line.startPoint.x,
+ line.startPoint.y,
+ line.endPoint.x,
+ line.endPoint.y
+ );
+ } else {
+ array.push(
+ line.startPoint.x,
+ line.startPoint.y,
+ line.ctrlPoint1.x,
+ line.ctrlPoint1.y,
+ line.ctrlPoint2.x,
+ line.ctrlPoint2.y,
+ line.endPoint.x,
+ line.endPoint.y
+ );
+ }
+ areaArr.push(array);
+ }
+ return areaArr;
+ };
+ this.changeWallToString = function (area) {
+ let areaArr = [];
+ let points = Map_QM.util.getWallPoints(area.pathPoints, area.thick);
+ for (let i = 0; i < points.length; i++) {
+ let array = [];
+ let pend = i == points.length - 1 ? points[0] : points[i + 1];
+ array.push(points[i].x, points[i].y, pend.x, pend.y);
+ areaArr.push(array);
+ }
+ return areaArr;
+ };
+
+ this.QM_Line_Father = function ( sPoint, ePoint, ctrlPoint1, ctrlPoint2, isStrLine ) {
+ this.startPoint = sPoint; //起始点
+ this.endPoint = ePoint; //结束点
+ this.ctrlPoint1 = ctrlPoint1;
+ this.ctrlPoint2 = ctrlPoint2;
+ this.isStrLine = isStrLine; //是否是直线
+ };
+ //根据配置参数转换店铺圆角
+ this.changeShopLinesToString = function (area) {
+ let areaStr = [];
+ let lines = [];
+ for (let m = 0; m < area.hasLines.length; m++) {
+ let sPoint, ePoint, cPoint1, cPoint2;
+ sPoint = new Map_QM.util.Point(
+ area.hasLines[m].startPoint.x,
+ area.hasLines[m].startPoint.y
+ );
+ ePoint = new Map_QM.util.Point(
+ area.hasLines[m].endPoint.x,
+ area.hasLines[m].endPoint.y
+ );
+ if (area.hasLines[m].isStrLine) {
+ cPoint1 = null;
+ cPoint2 = null;
+ } else {
+ cPoint1 = new Map_QM.util.Point(
+ area.hasLines[m].ctrlPoint1.x,
+ area.hasLines[m].ctrlPoint1.y
+ );
+ cPoint2 = new Map_QM.util.Point(
+ area.hasLines[m].ctrlPoint2.x,
+ area.hasLines[m].ctrlPoint2.y
+ );
+ }
+ let line = new Map_QM.util.QM_Line_Father(
+ sPoint,
+ ePoint,
+ cPoint1,
+ cPoint2,
+ area.hasLines[m].isStrLine
+ );
+ lines.push(line);
+ }
+
+ for (let i = 0; i < lines.length; i++) {
+ let line0 = lines[i];
+ let line1 = i < lines.length - 1 ? lines[i + 1] : lines[0];
+ if (Map_QM.util.options.aRadius > 2) {
+ if (line0.isStrLine &&line1.isStrLine &&Math.abs(line0.endPoint.x - line0.startPoint.x) + Math.abs(line0.endPoint.y - line0.startPoint.y) > parseInt(Map_QM.util.options.aRadius) * 2) {
+ let x1 = line0.endPoint.x;
+ let y1 = line0.endPoint.y;
+ let x2 = line0.startPoint.x;
+ let y2 = line0.startPoint.y;
+ let x3 = line1.endPoint.x;
+ let y3 = line1.endPoint.y;
+ if (Math.abs((x3 - x1) / (x2 - x1) - (y3 - y1) / (y2 - y1)) < 0.1) {
+ let yArr = [];
+ yArr.push(line0.startPoint.x,line0.startPoint.y, line0.endPoint.x, line0.endPoint.y);
+ areaStr.push(yArr);
+ continue;
+ }
+ let result = Map_QM.util.getIncircleByLines(x1,y1,x2,y2,x3,y3,Map_QM.util.options.aRadius);
+ let bezierResult = Map_QM.util.getBezier(result.center.x,result.center.y, result.tangencyPoints[0].x, result.tangencyPoints[0].y, result.tangencyPoints[1].x, result.tangencyPoints[1].y, x1, y1, Map_QM.util.options.aRadius);
+ if (i > 0) {
+ let ctrlPoint1,
+ ctrlPoint2,
+ array = [];
+ ctrlPoint1 = ctrlPoint2 = new Map_QM.util.Point(((bezierResult[0].x - line0.startPoint.x) / 2 + line0.startPoint.x) >>0, ((bezierResult[0].y - line0.startPoint.y) / 2 +line0.startPoint.y) >> 0); //控制点
+ array.push(line0.startPoint.x, line0.startPoint.y, ctrlPoint1.x, ctrlPoint1.y, ctrlPoint2.x, ctrlPoint2.y, bezierResult[0].x, bezierResult[0].y);
+ areaStr.push(array);
+ } else {
+ lines[0].endPoint.x = bezierResult[0].x;
+ lines[0].endPoint.y = bezierResult[0].y;
+ }
+ let arr = [];
+ arr.push(bezierResult[0].x, bezierResult[0].y, bezierResult[1].x, bezierResult[1].y, bezierResult[2].x, bezierResult[2].y, bezierResult[3].x, bezierResult[3].y);
+ areaStr.push(arr);
+ line1.startPoint.x = bezierResult[3].x;
+ line1.startPoint.y = bezierResult[3].y;
+ } else {
+ /////////////////////////////
+ if (i != 0) {
+ let pArr = [];
+ if (line0.isStrLine) {
+ pArr.push( line0.startPoint.x, line0.startPoint.y, line0.endPoint.x, line0.endPoint.y);
+ } else {
+ pArr.push( line0.startPoint.x, line0.startPoint.y, line0.ctrlPoint1.x, line0.ctrlPoint1.y, line0.ctrlPoint2.x, line0.ctrlPoint2.y, line0.endPoint.x, line0.endPoint.y);
+ }
+ areaStr.push(pArr);
+ }
+ }
+ if (i == lines.length - 1) {
+ let ocPoint1, ocPoint2, oArr = [];
+ if (line1.isStrLine) {
+ oArr.push( line1.startPoint.x, line1.startPoint.y, line1.endPoint.x, line1.endPoint.y);
+ } else {
+ ocPoint1 = new Map_QM.util.Point(line1.ctrlPoint1.x,line1.ctrlPoint1.y);
+ ocPoint2 = new Map_QM.util.Point(line1.ctrlPoint2.x,line1.ctrlPoint2.y);
+ oArr.push( line1.startPoint.x, line1.startPoint.y, ocPoint1.x, ocPoint1.y, ocPoint2.x, ocPoint2.y, line1.endPoint.x, line1.endPoint.y );
+ }
+ areaStr.push(oArr);
+ }
+ } else {
+ let yArr = [];
+ if (line0.isStrLine) {
+ yArr.push(line0.startPoint.x, line0.startPoint.y, line0.endPoint.x,line0.endPoint.y);
+ } else {
+ yArr.push(
+ line0.startPoint.x,line0.startPoint.y,
+ line0.ctrlPoint1.x,line0.ctrlPoint1.y,
+ line0.ctrlPoint2.x, line0.ctrlPoint2.y,
+ line0.endPoint.x, line0.endPoint.y
+ );
+ }
+ areaStr.push(yArr);
+ }
+ }
+ return areaStr;
+ };
+
+ //根据圆心、两个切点、切点相交线顶点和半径 计算三次贝塞尔曲线的控制点
+ this.getBezier = function (x1, y1, x2, y2, x3, y3, x4, y4, radius) {
+ //切线向量A
+ var vectorAx = x2 - x1;
+ var vectorAy = y2 - y1;
+ //切线向量B
+ var vectorBx = x3 - x1;
+ var vectorBy = y3 - y1;
+
+ //计算切点和圆形组成相交线的夹角
+ var angle = Math.acos(
+ (vectorAx * vectorBx + vectorAy * vectorBy) /
+ (Math.sqrt(vectorAx * vectorAx + vectorAy * vectorAy) *
+ Math.sqrt(vectorBx * vectorBx + vectorBy * vectorBy))
+ );
+ //计算切点到控制点的距离
+ var tempDistence = (4 / 3) * radius * Math.tan(angle / 4);
+ return [
+ {
+ x: x2,
+ y: y2,
+ },
+ Map_QM.util.getPointFromLine(x2, y2, x4, y4, tempDistence),
+ Map_QM.util.getPointFromLine(x3, y3, x4, y4, tempDistence),
+ {
+ x: x3,
+ y: y3,
+ },
+ ];
+ };
+ //根据半径计算两条线段相切圆的圆心和切点坐标
+ this.getIncircleByLines = function (x1, y1, x2, y2, x3, y3, radius) {
+ //向量夹角
+ let angle = Map_QM.util.getVectorAngle(x2 - x1, y2 - y1, x3 - x1, y3 - y1);
+ angle = (angle > 180 ? 360 - angle : angle) / 2;
+ //根据夹角计算侧边切点相对于顶点距离
+ let distance = radius / Math.tan((Math.PI * angle) / 180);
+ //计算侧边相切点具体坐标
+ let tangencyPoints = [
+ Map_QM.util.getPointFromLine(x1, y1, x2, y2, distance),
+ Map_QM.util.getPointFromLine(x1, y1, x3, y3, distance),
+ ];
+
+ let centerX, centerY;
+ let areaSize = (x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1);
+ //计算圆心坐标
+ if (areaSize < 0) {
+ centerX =
+ (tangencyPoints[0].x * (1 / Math.tan((Math.PI * angle) / 180)) +
+ tangencyPoints[0].y -y1) /(1 / Math.tan((Math.PI * angle) / 180));
+ centerY = (tangencyPoints[0].y * (1 / Math.tan((Math.PI * angle) / 180)) + x1 - tangencyPoints[0].x) /(1 / Math.tan((Math.PI * angle) / 180));
+ } else {
+ centerX = (tangencyPoints[1].x * (1 / Math.tan((Math.PI * angle) / 180)) +tangencyPoints[1].y -y1) / (1 / Math.tan((Math.PI * angle) / 180));
+ centerY = (tangencyPoints[1].y * (1 / Math.tan((Math.PI * angle) / 180)) + x1 -tangencyPoints[1].x) /(1 / Math.tan((Math.PI * angle) / 180));
+ }
+ return {
+ center: {
+ x: centerX,
+ y: centerY,
+ },
+ tangencyPoints: tangencyPoints,
+ angle: (Math.PI * angle) / 90,
+ };
+ };
+
+ //根据距离计算线段上某一点的具体坐标
+ this.getPointFromLine = function (startX, startY, endX, endY, distance) {
+ if (startX == endX)
+ return {
+ x: startX,
+ y: startY < endY ? startY + distance : startY - distance,
+ };
+
+ let k = ((startY - endY) * 1.0) / (startX - endX);
+ let b = startY - k * startX;
+ let A = Math.pow(k, 2) + 1;
+ let B = 2 * ((b - startY) * k - startX);
+ let C =
+ Math.pow(b - startY, 2) + Math.pow(startX, 2) - Math.pow(distance, 2);
+ let x1 = (-B + Math.sqrt(Math.pow(B, 2) - 4 * A * C)) / (2 * A);
+ let x2 = (-B - Math.sqrt(Math.pow(B, 2) - 4 * A * C)) / (2 * A);
+ let x = 0;
+
+ if (x1 == x2) x = x1;
+ else if ((startX <= x1 && x1 <= endX) || (endX <= x1 && x1 <= startX))
+ x = x1;
+ else if ((startX <= x2 && x2 <= endX) || (endX <= x2 && x2 <= startX))
+ x = x2;
+
+ let y = k * x + b;
+ return {
+ x: x,
+ y: y,
+ };
+ };
+
+ //计算两个向量之间的夹角
+ this.getVectorAngle = function (x1, y1, x2, y2) {
+ let epsilon = 1.0e-6;
+ let dist, dot, degree, angle;
+ dist = Math.sqrt(x1 * x1 + y1 * y1);
+ x1 /= dist;
+ y1 /= dist;
+ dist = Math.sqrt(x2 * x2 + y2 * y2);
+ x2 /= dist;
+ y2 /= dist;
+ dot = x1 * x2 + y1 * y2;
+ if (Math.abs(dot - 1.0) <= epsilon) angle = 0;
+ else if (Math.abs(dot + 1.0) <= epsilon) angle = Math.PI;
+ else {
+ angle = Math.acos(dot);
+ let cross = x1 * y2 - x2 * y1;
+ if (cross < 0) angle = 2 * Math.PI - angle;
+ }
+ degree = (angle * 180) / Math.PI;
+ return degree;
+ };
+ //检测区域是否在区域内 true (area2包含area)
+ this.checkAreaInArea = function (area, area2) {
+ if (!area2.hasLines || !area.hasLines) {
+ return false;
+ }
+ let ptPolygon = [];
+ for (let i = 0; i < area2.hasLines.length; i++) {
+ let line = area2.hasLines[i];
+ let pArr;
+ if (line.isStrLine) {
+ pArr = Map_QM.util.getPointArrOnLine(line.startPoint, line.endPoint);
+ } else {
+ pArr = Map_QM.util.getPointArr(line.startPoint, line.ctrlPoint1,line.ctrlPoint2,line.endPoint,0.1);
+ }
+ ptPolygon.push(...pArr);
+ }
+ for (let f = 0; f < area.hasLines.length; f++) {
+ let line2 = area.hasLines[f];
+ let sPoint = Map_QM.util.checkBoundary(new Map_QM.util.Point(line2.startPoint.x, line2.startPoint.y),ptPolygon);
+ let ePoint = Map_QM.util.checkBoundary(new Map_QM.util.Point(line2.endPoint.x, line2.endPoint.y),ptPolygon);
+ if (!sPoint || !ePoint) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ /**
+ * 返回取得点的数组
+ * s1--起点 s2 --终点 s3,s4 --控制点
+ */
+ this.getPointArr = function (s1, s3, s4, s2, sp = 0.01) {
+ let pArr = [];
+ let sz = [s1, s3, s4, s2];
+ let p;
+ for (let j = 0; j < 1; j += sp) {
+ p = Map_QM.util.P_BEZ(j, sz);
+ pArr.push(p);
+ }
+ return pArr;
+ };
+
+ this.P_BEZ = function (t, sz) {
+ //n次
+ let x_p = 0;
+ let y_p = 0;
+ let n = sz.length;
+ for (let i = 0; i < sz.length; i++) {
+ let son = Map_QM.util.jie_cheng(n - 1);
+ let mother = Map_QM.util.jie_cheng(i) * Map_QM.util.jie_cheng(n - 1 - i);
+ let b = (son / mother) * Math.pow(t, i) * Math.pow(1 - t, n - 1 - i);
+ x_p += sz[i].x * b;
+ y_p += sz[i].y * b;
+ }
+
+ x_p = Number(x_p * 1000) / 1000;
+ y_p = Number(y_p * 1000) / 1000;
+ return new Map_QM.util.Point(x_p, y_p);
+ };
+
+ this.jie_cheng = function (i) {
+ //阶乘
+ let n = 1;
+ for (let j = 1; j <= i; j++) {
+ n *= j;
+ }
+ return n;
+ };
+
+ /**
+ * 获取线段上的所有点
+ */
+ this.getPointArrOnLine = function (s1, s2) {
+ let points = [];
+ if (s1.x == s2.x) {
+ let vy = s1.y < s2.y ? 1 : -1;
+ for (let m = 1; m < Math.abs(s1.y - s2.y); m++) {
+ let y0 = s1.y + m * vy;
+ let x0 = s1.x;
+ points.push(new Map_QM.util.Point(x0, y0));
+ }
+ return points;
+ }
+ let k = (s1.y - s2.y) / (s1.x - s2.x); // 坐标直线斜率k
+ let b = s1.y - k * s1.x; // 坐标直线b
+ if (Math.abs(s1.x - s2.x) > Math.abs(s1.y - s2.y)) {
+ let vx = s1.x < s2.x ? 1 : -1;
+ for (let i = 1; i < Math.abs(s1.x - s2.x); i++) {
+ let x0 = s1.x + i * vx;
+ let y0 = k * x0 + b;
+ points.push(new Map_QM.util.Point(x0, y0));
+ }
+ } else {
+ let vy = s1.y < s2.y ? 1 : -1;
+ for (let n = 1; n < Math.abs(s1.y - s2.y); n++) {
+ let y0 = s1.y + n * vy;
+ let x0 = (y0 - b) / k;
+ points.push(new Map_QM.util.Point(x0, y0));
+ }
+ }
+ return points;
+ };
+ //店铺排序
+ this.sortShopByFloor = function (a, b) {
+ return a.floorOrder < b.floorOrder ? -1 : 1;
+ };
+ this.sortNode = function (a, b) {
+ return a.id - b.id;
+ };
+ ////////////////////////////////////////////////////////////////////////////////////////////
+ this.getWallPoints = function (points, wallWidth) {
+ if (points.length < 2) {
+ return new Array();
+ }
+ //构建线段列表
+ let lines = new Array();
+ for (let index = 0; index < points.length - 1; index++) {
+ let startPoint = points[index];
+ let endPoint = points[index + 1];
+ let line = Map_QM.util.getParallelLine(startPoint, endPoint, wallWidth);
+ lines.push(line);
+ }
+ //生成线段对应的左右两侧平行线
+ for (let index = 0; index < lines.length - 1; index++) {
+ let start = lines[index];
+ let end = lines[index + 1];
+ if (
+ start.leftParLine != null &&
+ start.rightParLine != null &&
+ end.leftParLine != null &&
+ end.rightParLine != null
+ ) {
+ start.leftPoint = Map_QM.util.getIntersectionByLines(
+ start.leftParLine,
+ end.leftParLine
+ );
+ start.rightPoint = Map_QM.util.getIntersectionByLines(
+ start.rightParLine,
+ end.rightParLine
+ );
+ }
+ }
+ //循环线段列表 获取墙体所有点位 顺序为 左侧起始点->左侧所有交点->左侧结束点->右侧结束点->右侧所有交点->右侧起始点
+ let leftPointList = new Array();
+ let rightPointList = new Array();
+ for (let index = 0; index < lines.length; index++) {
+ //第一条线段 记录左右两侧平行线的起点坐标
+ if (index == 0) {
+ leftPointList.push(lines[index].leftParLine.start);
+ rightPointList.push(lines[index].rightParLine.start);
+ }
+ //最后一条线段 记录左右两侧平行线的终点坐标
+ if (index == lines.length - 1) {
+ leftPointList.push(lines[index].leftParLine.end);
+ rightPointList.push(lines[index].rightParLine.end);
+ } else {
+ //记录线段左右平行线交点坐标
+ if (
+ !isNaN(lines[index].leftPoint.x) ||
+ !isNaN(lines[index].leftPoint.y) ||
+ !isNaN(lines[index].rightPoint.x) ||
+ !isNaN(lines[index].rightPoint.y)
+ ) {
+ leftPointList.push(lines[index].leftPoint);
+ rightPointList.push(lines[index].rightPoint);
+ }
+ }
+ }
+ rightPointList.reverse();
+ return leftPointList.concat(rightPointList);
+ };
+ //生成线段左右两侧的平行线
+ this.getParallelLine = function (start, end, wallWidth) {
+ let line = new Map_QM.util.WallLine(start, end);
+ //计算当前线段的斜率
+ let gradient = (start.y - end.y) / (start.x - end.x);
+ //计算垂直线的斜率
+ let perGradient = -1 / gradient;
+ //获取垂直线上左右两侧 与当前点位相距一定距离的两个定点
+ let startResult = Map_QM.util.getParallelPoints( perGradient, start, wallWidth);
+ let endResult = Map_QM.util.getParallelPoints(perGradient, end, wallWidth);
+ let x1 = startResult[0].x;
+ let y1 = startResult[0].y;
+ let x2 = endResult[0].x;
+ let y2 = endResult[0].y;
+ let x3 = end.x;
+ let y3 = end.y;
+ let x4 = startResult[1].x;
+ let y4 = startResult[1].y;
+ let x5 = endResult[1].x;
+ let y5 = endResult[1].y;
+ let s = (x1 - x3) * (y2 - y3) - (y1 - y3) * (x2 - x3);
+ //判断点位位于线段的左侧还是右侧
+ if (s >= 0) {
+ line.leftParLine = new Map_QM.util.WallLine(new Map_QM.util.Point(x1, y1), new Map_QM.util.Point(x2, y2));
+ line.rightParLine = new Map_QM.util.WallLine(new Map_QM.util.Point(x4, y4), new Map_QM.util.Point(x5, y5));
+ } else {
+ line.leftParLine = new Map_QM.util.WallLine(new Map_QM.util.Point(x4, y4), new Map_QM.util.Point(x5, y5));
+ line.rightParLine = new Map_QM.util.WallLine(new Map_QM.util.Point(x1, y1), new Map_QM.util.Point(x2, y2));
+ }
+ return line;
+ };
+ // 生成线段起始 和 结束 点位 对应的 两条 与线段垂直的直线 并记录坐标
+ this.getParallelPoints = function (gradient, point, wallWidth) {
+ let x, y;
+ //斜率为无穷大时 计算不了垂直线 指定点位
+ if (gradient == Number.NEGATIVE_INFINITY || gradient == Number.POSITIVE_INFINITY) {
+ x = point.x;
+ y = point.y + 5;
+ } else {
+ //不是横线时 根据斜率计算点位
+ x = point.x + 5;
+ y = gradient * (x - point.x) + point.y;
+ }
+
+ return Map_QM.util.pointXY(
+ point,
+ new Map_QM.util.Point(x, y),
+ wallWidth / 2
+ );
+ };
+ // 获取点位在直线上的坐标
+ this.pointXY = function (curPoint, nextPoint, length) {
+ let result = new Array();
+ //x值相等 说明是竖线 只需增减y轴坐标
+ if (curPoint.x == nextPoint.x) {
+ result.push(new Map_QM.util.Point(curPoint.x, curPoint.y + length));
+ result.push(new Map_QM.util.Point(curPoint.x, curPoint.y - length));
+ return result;
+ }
+ //根据 斜率 和 距离 计算出对应的两个点位
+ let k = (curPoint.y - nextPoint.y) / (curPoint.x - nextPoint.x);
+ let b = curPoint.y - k * curPoint.x;
+ let A = Math.pow(k, 2) + 1;
+ let B = 2 * ((b - curPoint.y) * k - curPoint.x);
+ let C = Math.pow(b - curPoint.y, 2) + Math.pow(curPoint.x, 2) - Math.pow(length, 2);
+ let x1 = (-B + Math.sqrt(Math.pow(B, 2) - 4 * A * C)) / (2 * A);
+ let x2 = (-B - Math.sqrt(Math.pow(B, 2) - 4 * A * C)) / (2 * A);
+
+ result.push(new Map_QM.util.Point(x1, k * x1 + b));
+ result.push(new Map_QM.util.Point(x2, k * x2 + b));
+ return result;
+ };
+ //计算两条直线的相交点
+ this.getIntersectionByLines = function (line1, line2) {
+ //直线斜率
+ let gradient1 =
+ (line1.end.y - line1.start.y) / (line1.end.x - line1.start.x);
+ let gradient2 =
+ (line2.end.y - line2.start.y) / (line2.end.x - line2.start.x);
+ //斜率差值小于一定范围 表示两条线近似平行 因为交点太远 可能超出屏幕 直接取线段中点为交点
+ if (Math.abs(gradient1 - gradient2) < 0.1)
+ return new Map_QM.util.Point(line1.end.x, line1.end.y);
+ let x1 = line1.start.x;
+ let y1 = line1.start.y;
+ let x2 = line1.end.x;
+ let y2 = line1.end.y;
+ let x3 = line2.start.x;
+ let y3 = line2.start.y;
+ let x4 = line2.end.x;
+ let y4 = line2.end.y;
+
+ //计算交点坐标
+ let x =
+ ((x1 - x2) * (x3 * y4 - x4 * y3) - (x3 - x4) * (x1 * y2 - x2 * y1)) /
+ ((x3 - x4) * (y1 - y2) - (x1 - x2) * (y3 - y4));
+ let y =
+ ((y1 - y2) * (x3 * y4 - x4 * y3) - (x1 * y2 - x2 * y1) * (y3 - y4)) /
+ ((y1 - y2) * (x3 - x4) - (x1 - x2) * (y3 - y4));
+ return new Map_QM.util.Point(x, y);
+ };
+ /**
+ * 根据色值获取材质
+ */
+ this.getMeshMaterial = function (color, alphaModle = 0.9) {
+ let meshMaterial;
+ for (let k = 0; k < Map_QM.util.meshMaterialArr.length; k++) {
+ let color2 = new THREE.Color(color);
+ if (
+ Map_QM.util.meshMaterialArr[k].color &&
+ Map_QM.util.meshMaterialArr[k].color.equals(color2) &&
+ Map_QM.util.meshMaterialArr[k].opacity == alphaModle
+ ) {
+ meshMaterial = Map_QM.util.meshMaterialArr[k];
+ }
+ }
+ if (!meshMaterial) {
+ meshMaterial = new THREE.MeshStandardMaterial({
+ color: color,
+ emissive: 0x000000,
+ specular: 0x000000,
+ transparent: true,
+ side: THREE.DoubleSide,
+ opacity: alphaModle,
+ emissive : 0x000000,
+ roughness:0.8
+ });
+ Map_QM.util.meshMaterialArr.push(meshMaterial);
+ }
+ return meshMaterial;
+ };
+ this.rotateYZ = function (geometry, ry, rz) {
+ let center = new THREE.Vector3();
+ geometry.computeBoundingBox();
+ geometry.boundingBox.getCenter(center);
+ let x = center.x;
+ let y = center.y;
+ let z = center.z;
+ geometry.center();
+ geometry.rotateY(ry);
+ geometry.rotateX(rz);
+ geometry.translate(x, y, z);
+ };
+ //用于生成uuid
+ this.guid = function () {
+ function S4() {
+ return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
+ }
+ return S4() + S4() + S4();
+ };
+
+ this.getTextMesh = function (text, position) {
+ spriteScale = window.innerWidth>2000 ? 0.16 : 0.2;
+ const sprite = new SpriteText(text, 32, "#000000");
+ sprite.renderOrder = 800;
+ sprite.material.transparent = true;
+ sprite.material.alphaTest = 0.5;
+ sprite.material.sizeAttenuation = false;
+ sprite.userData.scaleX = sprite.scale.x;
+ sprite.userData.scaleY = sprite.scale.y;
+ sprite.position.set(position.x, position.y, position.z + 24);
+ return sprite;
+ };
+};
+//////////////////////////////-------------------------------------------配置 UtilFun
+/**
+ * 地图主类,入口 初始化设备点位
+ */
+var MainMap_QM = function (callBack, options) {
+ this.util = new QMUtil();
+ this.callBackLoadOver = callBack;
+ this.ele = document.getElementById(options.containerId || "mapContainer");
+ this.w = parseInt(this.ele.clientWidth) || parseInt(window.getComputedStyle(this.ele, null).getPropertyValue("width"));
+ this.h = parseInt(this.ele.clientHeight) ||parseInt(window.getComputedStyle(this.ele, null).getPropertyValue("height"));
+ this.backObj = { code: 200, msg: "加载成功", data: [] };
+ this.scene = new THREE.Scene();
+ this.scene.name = "scene";
+ //this.scene.fog = new THREE.Fog(0xe5e5e5,this.util.options.maxDis,this.util.options.maxDis + 500);
+ this.aspect = this.w / this.h;
+ this.cameraPerspective = new THREE.PerspectiveCamera(45,this.aspect,10,10000);
+ this.cameraPerspective.position.set(this.util.sceneGap.cameraX,this.util.sceneGap.cameraY,this.util.sceneGap.cameraZ); //x 水平 y 垂直旋转 z 展示大小
+ this.cameraPerspective.lookAt(new THREE.Vector3(0, 0, 0));
+ this.cameraOrtho = new THREE.OrthographicCamera(-150 * this.aspect, 150 * this.aspect, 150, -150, 10, 10000)
+ this.cameraOrtho.position.set(this.util.sceneGap.cameraX, this.util.sceneGap.cameraY, this.util.sceneGap.cameraZ)
+ this.cameraOrtho.lookAt(new THREE.Vector3(0, 0, 0));
+ this.camera = this.cameraPerspective;
+ //
+ this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); // preserveDrawingBuffer 是否可以截图
+ //this.renderer.outputEncoding = THREE.sRGBEncoding;
+ //this.renderer.physicallyCorrectLights = true;
+ this.renderer.setSize(this.w, this.h);
+ this.renderer.setPixelRatio(window.devicePixelRatio);
+ this.renderer.shadowMap.enabled = this.util.options.shadow;
+ // 阴影类型
+ this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
+ this.ele.appendChild(this.renderer.domElement);
+
+ this.labelRenderer = new THREE.CSS2DRenderer();
+ //弹窗的偏移百分比 或者像素
+ this.labelRenderer.setSize(this.w, this.h, options.perc_H || "-50%");
+ this.labelRenderer.domElement.style.position = "absolute";
+ this.labelRenderer.domElement.style.top = 0;
+ this.ele.appendChild(this.labelRenderer.domElement);
+
+ let light = new THREE.AmbientLight(0xffffff, 0.65);
+ light.name = "light";
+ this.scene.add(light);
+
+ let dLight = new THREE.DirectionalLight(0xffffff, 0.35); //
+ dLight.name = "light";
+ dLight.position.set(-280, 400, 300);
+ this.scene.add(dLight);
+
+ this.hemiLight = new THREE.DirectionalLight(this.util.lightOptions.s_col, this.util.lightOptions.a_int); //
+ this.hemiLight.name = "light";
+ this.hemiLight.position.set(280, -400, 300);
+ this.scene.add(this.hemiLight);
+
+ this.shawLight = new THREE.DirectionalLight(this.util.lightOptions.d_col, this.util.lightOptions.d_int);
+ this.shawLight.name = "light";
+ this.shawLight.position.set(280, 400, -200);
+ this.shawLight.castShadow = this.util.options.shadow; //阴影
+ this.shawLight.shadow.camera.top = 200;
+ this.shawLight.shadow.camera.bottom = -200;
+ this.shawLight.shadow.camera.right = 200;
+ this.shawLight.shadow.camera.left = -200;
+ this.shawLight.shadow.camera.far = 800;
+ this.shawLight.shadow.camera.near = 100;
+ this.shawLight.shadow.bias = -0.001;
+ this.shawLight.shadow.darkness = 0.3;
+ this.shawLight.shadow.mapSize.set(2048, 2048);
+ this.scene.add(this.shawLight);
+ this.cost = -1;
+ this.controls = new THREE.OrbitControls(this.camera, this.ele);
+ this.controls.minZoom = 0.5;
+ this.controls.maxZoom = 2.8;
+ //设置相机距离原点的最远距离
+ this.controls.minDistance = this.util.options.minDis;
+ //设置相机距离原点的最远距离
+ this.controls.maxDistance = this.util.options.maxDis;
+ this.controls.minPolarAngle = 0; // 0是为了兼容2D模式
+ this.controls.maxPolarAngle = Math.PI / 2 - 0.2; // radians
+
+ document.addEventListener("resize", this.changeDocmentResize); //窗口变化
+ this.mapArr = [];
+ this.selectShop;
+ this.selectEle = null; //当前使用的电梯
+ this.overShop; //终点店铺
+
+ if (document.getElementById("moveFloorBG")) {
+ document.getElementById("moveFloorBG").style.zIndex = 500;
+ this.moveFloorbg = new THREE.CSS2DObject(document.getElementById("moveFloorBG"));
+ this.moveFloorbg.userData.isShow = false;
+ }
+
+ this.mixers = [];
+ this.man_3d = null;
+ this.man_2d = null;
+ this.guide = null;
+ this.devModel = null;
+ this.sceneGap = new THREE.Group();
+ this.outModelGap = new THREE.Group(); //全局外立面模型
+ this.scene.add(this.outModelGap);
+ this.peripheryGap = new THREE.Group(); //周边模型
+ this.scene.add(this.peripheryGap);
+ this.outObject = new THREE.Object3D();
+ this.outObject.userData.type = "moveFloor";
+ this.perObject = new THREE.Object3D();
+ this.perObject.userData.type = "moveFloor";
+ this.buildObj = new THREE.Group();
+ this.qiModel = null; //起点
+ this.qiIcon = null; //起点Icon
+ this.endIcon = null; //终点Icon
+ this.endModel = null;
+ this.forShopArr = []; //途径数据
+ this.getInstance(options);
+ if (this.util.options.northShow) {
+ this.util.img = document.createElement("img");
+ this.util.img.src = "./static/img/noth.png";
+ this.util.img.classList.add("north");
+ this.ele.appendChild(this.util.img);
+ }
+};
+MainMap_QM.prototype = {
+ resetModel: function () {
+ if (mapState == "mall") {
+ Map_QM.buildObj.visible = true;
+ Map_QM.controls.reset();
+ Map_QM.controls.autoRotate = false;
+ Map_QM.controls.setDistance(Map_QM.util.changeDist.inner - 25);
+ } else if (mapState == "out") {
+ Map_QM.controls.reset();
+ Map_QM.controls.setDistance(Map_QM.util.changeDist.inner + 30);
+ Map_QM.controls.autoRotate = true;
+ } else {
+ Map_QM.controls.reset();
+ Map_QM.controls.setDistance(Map_QM.util.changeDist.outner + 25);
+ Map_QM.controls.autoRotate = false;
+ }
+ Map_QM.controls.update();
+ },
+ //隐藏活动标签(万象定制)
+ mouseMove: function () {
+ Map_QM.CSSObject && Map_QM.CSSObject.traverse((obj) => {
+ if (obj.userData.type == "tip") {
+ obj.element.style.visibility = "hidden";
+ }
+ });
+ },
+ //显示活动标签(万象定制)
+ mouseUp: function () {
+ Map_QM.CSSObject && Map_QM.CSSObject.traverse((obj) => {
+ if (obj.userData.type == "tip") {
+ obj.element.style.visibility = parseInt(obj.userData.floor) == Map_QM.util.selectFloor ? "visible": "hidden";
+ }
+ });
+ },
+
+ /**
+ * @api {方法} getPointByNode() 获取导航点位的坐标
+ * @apiGroup 地图交互
+ * @apiDescription 获取导航点位的坐标
+ * @apiVersion 4.0.0
+ * @apiParam {String} str 导航点位
+ *
+ * @apiSampleRequest off
+ * @apiParamExample {String} 请求示例
+ *
+ * Map_QM.getPointByNode("0_0_1");
+ */
+ getPointByNode: function (str) {
+ let nodes = str.split("_");
+ if (nodes.length > 2 && !isNaN(parseInt(nodes[2])) && parseInt(nodes[2])>=0) {
+ Map_QM.util.allMap[parseInt(nodes[0])].buildArr[parseInt(nodes[1])].mapData.path.nodes.sort(Map_QM.util.sortNode);
+ return Map_QM.util.allMap[parseInt(nodes[0])].buildArr[parseInt(nodes[1])].mapData.path.nodes[nodes[2]];
+ }else{
+ return {x:-5000,y:-5000,msg:"未打点"};
+ }
+ },
+ getInstance: function (options) {
+ this.util.startObj.build = this.util.deviceObj.build = parseInt(options.build) || 0;
+ this.util.startObj.node = this.util.deviceObj.node = parseInt(options.navPoint) || 1;
+ this.util.deviceObj.angle = parseInt(options.angle) || 0;
+ this.util.selectBuild = this.util.deviceObj.build;
+ let _space = this;
+ if (options.mallCode) {
+ let tim = this.util.timeStamp();
+ this.util.requestNoJM({
+ method: "GET",
+ url: options.url + "/api/info/v1/web/getUploadUrl",
+ success: (res) => {
+ let resText = res.data;
+ if (typeof resText === "string" &&resText.search("https://") === -1) {
+ resText = JSON.parse(_space.util.decrypt(res.data));
+ }
+ _space.tomUrl = resText;
+ this.util.requestNoJM({
+ method: "GET",
+ url: _space.tomUrl + "/ar/" + options.mallCode +"/config.json?a=" +tim,
+ success: (res) => {
+ _space.util.shopServerInfo = res.shopUrl;
+ _space.util.mapServerInfo = res.mapUrl;
+ _space.initLoadMapFile(options);
+ },
+ fail: () => {
+ _space.backObj.code = 404;
+ _space.backObj.msg = "地图数据获取失败";
+ _space.callBackLoadOver(_space.backObj);
+ _space.callBackLoadOver = null;
+ },
+ });
+ },
+ fail: () => {
+ this.util.requestNoJM({
+ method: "GET",
+ url: _space.tomUrl +"/ar/" +options.mallCode +"/config.json?a=" +tim,
+ success: (res) => {
+ _space.util.shopServerInfo = res.shopUrl;
+ _space.util.mapServerInfo = res.mapUrl;
+ _space.initLoadMapFile(options);
+ },
+ fail: () => {
+ _space.backObj.code = 404;
+ _space.backObj.msg = "地图数据获取失败";
+ _space.callBackLoadOver(_space.backObj);
+ _space.callBackLoadOver = null;
+ },
+ });
+ },
+ });
+ } else {
+ if (options.mapData) {
+ try {
+ _space.util.allMap = JSON.parse(options.mapData.mapData);
+ console.log("地图数据更新时间: " + options.mapData.updateTime);
+ } catch (e) {
+ window.captureException && window.captureException(e);
+ console.log(e);
+ _space.backObj.code = 404;
+ _space.backObj.msg = "地图数据JSON格式错误";
+ _space.callBackLoadOver(_space.backObj);
+ return;
+ }
+ _space.util.shopData = options.shopData || [];
+ _space.initOptions(options);
+ } else {
+ _space.initLoadMapFile(options);
+ }
+ }
+ },
+
+ initLoadMapFile: function (options) {
+ let _space = this;
+ _space.util.readTextFile(_space.util.mapServerInfo, function (res) {
+ if (res) {
+ try {
+ if (Array.isArray(res.data)) {
+ for (let map of res.data) {
+ _space.util.allMap = JSON.parse(map.mapData);
+ }
+ } else {
+ _space.util.allMap = JSON.parse(res.data.mapData);
+ console.log("地图数据更新时间: " + res.data.updateTime);
+ }
+ } catch (e) {
+ window.captureException && window.captureException(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.shopServerInfo, function (res) {
+ _space.util.shopData = [];
+ if (res) {
+ res.data.listObject.forEach((item) => {
+ _space.util.shopData.push(item);
+ });
+ }
+ _space.initOptions(options);
+ });
+ } else {
+ _space.backObj.code = 404;
+ _space.backObj.msg = "地图数据JSON格式错误";
+ _space.callBackLoadOver(_space.backObj);
+ _space.callBackLoadOver = null;
+ return;
+ }
+ });
+ },
+
+ initOptions: function (options) {
+ //初始化参数
+ if (this.util.allMap[this.util.selectBuild].playSpeed) {
+ this.util.allMap[this.util.selectBuild].hasOwnProperty("playSpeed") && (this.util.options.playSpeed = parseInt( this.util.allMap[this.util.selectBuild].playSpeed));
+ this.util.allMap[this.util.selectBuild].hasOwnProperty("collision") && (this.util.options.collision = this.util.allMap[this.util.selectBuild].collision);
+ this.util.allMap[this.util.selectBuild].hasOwnProperty("navColor") && (this.util.options.navColor = this.util.allMap[this.util.selectBuild].navColor);
+ this.util.allMap[this.util.selectBuild].hasOwnProperty("aRadius") && (this.util.options.aRadius = parseInt( this.util.allMap[this.util.selectBuild].aRadius));
+ this.util.allMap[this.util.selectBuild].hasOwnProperty("boxShop") && (this.util.options.boxShop = this.util.allMap[this.util.selectBuild].boxShop.split(","));
+ this.util.allMap[this.util.selectBuild].hasOwnProperty("shopStyle") && (this.util.options.shopStyle = this.util.allMap[this.util.selectBuild].shopStyle);
+ this.util.allMap[this.util.selectBuild].hasOwnProperty("modelIcon") && (this.util.options.modelIcon = this.util.allMap[this.util.selectBuild].modelIcon);
+ this.util.allMap[this.util.selectBuild].hasOwnProperty("facSize") && (this.util.options.facSize = this.util.allMap[this.util.selectBuild].facSize);
+ this.util.allMap[this.util.selectBuild].hasOwnProperty("m_scale") && (this.util.sceneGap.scale = this.util.allMap[this.util.selectBuild].m_scale);
+
+ if (this.util.allMap[this.util.selectBuild].hasOwnProperty("m_shadow")) {
+ this.util.options.shadow = this.util.allMap[this.util.selectBuild].m_shadow;
+ }
+
+ this.hemiLight.color = new THREE.Color(this.util.allMap[this.util.selectBuild].s_col || "#ffffff");
+ this.hemiLight.intensity = this.util.allMap[this.util.selectBuild].a_int || 0.2;
+ 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.15;
+
+ if (this.util.allMap[this.util.selectBuild].c_site && this.util.allMap[this.util.selectBuild].c_site.split(",")) {
+ this.util.sceneGap.cameraX = parseInt(this.util.allMap[this.util.selectBuild].c_site.split(",")[0]) || this.util.sceneGap.cameraX;
+ this.util.sceneGap.cameraY = parseInt(this.util.allMap[this.util.selectBuild].c_site.split(",")[1]) || this.util.sceneGap.cameraY;
+ this.util.sceneGap.cameraZ = parseInt(this.util.allMap[this.util.selectBuild].c_site.split(",")[2]) || this.util.sceneGap.cameraZ;
+ }
+ if (this.util.allMap[this.util.selectBuild].m_site && this.util.allMap[this.util.selectBuild].m_site.split(",")) {
+ this.util.sceneGap.x = parseInt(this.util.allMap[this.util.selectBuild].m_site.split(",")[0]) || this.util.sceneGap.x;
+ this.util.sceneGap.y = parseInt(this.util.allMap[this.util.selectBuild].m_site.split(",")[1]) || this.util.sceneGap.y;
+ this.util.sceneGap.z = parseInt(this.util.allMap[this.util.selectBuild].m_site.split(",")[2]) || this.util.sceneGap.z;
+ }
+ if (this.util.allMap[this.util.selectBuild].m_zoom) {
+ this.util.m_zoom = this.util.allMap[this.util.selectBuild].m_zoom;
+ }
+ }
+ let { playSpeed, collision, modelIcon, shopStyle, shadow, otherPath, navColor, iconUrl, iconName, inArea, pathColor, pathStyle} = options;
+
+ this.util.options.playSpeed = playSpeed != undefined ? playSpeed : this.util.options.playSpeed;
+ this.util.options.collision = collision != undefined ? collision : this.util.options.collision;
+ this.util.options.modelIcon = modelIcon != undefined ? modelIcon : this.util.options.modelIcon;
+ this.util.options.shadow = shadow != undefined ? shadow : this.util.options.shadow;
+ this.util.options.shopStyle = shopStyle != undefined ? shopStyle : this.util.options.shopStyle;
+ this.util.options.otherPath = otherPath != undefined ? otherPath : this.util.options.otherPath;
+ this.util.options.navColor = navColor != undefined ? navColor : this.util.options.navColor;
+ this.util.options.iconName = iconName != undefined ? iconName : this.util.options.iconName;
+ this.util.options.inArea = inArea != undefined ? inArea : this.util.options.inArea;
+ this.util.options.pathColor = pathColor != undefined ? pathColor : this.util.options.pathColor;
+ this.util.options.pathStyle = pathStyle != undefined ? pathStyle : this.util.options.pathStyle;
+ this.util.iconUrl = iconUrl != undefined ? iconUrl : [];
+ this.renderer.shadowMap.enabled = this.util.options.shadow;
+ this.shawLight.castShadow = this.util.options.shadow; //阴影
+
+ if (!isNaN(Number(options.floor))) {
+ this.util.startObj.floor = this.util.deviceObj.floor = parseInt(options.floor) || 0;
+ } else {
+ if (Array.isArray(this.util.allMap)) {
+ for (var iii = 0; iii < this.util.allMap[this.util.startObj.build].buildArr.length; iii++) {
+ if (this.util.allMap[this.util.startObj.build].buildArr[iii].name == options.floor) {
+ this.util.startObj.floor = this.util.deviceObj.floor = this.util.allMap[this.util.startObj.build].buildArr[iii].order;
+ break;
+ }
+ }
+ }
+ }
+ //
+ for (let k = 0; k < this.util.allMap.length; k++) {
+ for (let kk = 0; kk < this.util.allMap[k].buildArr.length; kk++) {
+ let floor = this.util.allMap[k].buildArr[kk].mapData;
+ if (floor.models) {
+ for (let t = 0; t < floor.models.length; t++) {
+ for (let i = 0; i < this.util.modelStr.length; i++) {
+ if (floor.models[t].type == this.util.modelStr[i].key) {
+ this.util.modelStr[i].load = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ try {
+ this.initOutModel();
+ } catch (e) {
+ window.captureException && window.captureException(e);
+ this.callBackLoadOver({ code: 404, msg: "地图数据解析失败" });
+ this.callBackLoadOver = null;
+ }
+ },
+ //加载全局模型
+ initOutModel: function () {
+ let _this = this;
+ if (this.util.initModelArr && this.util.initModelArr.length > 0) {
+ for (let i = 0; i < _this.util.initModelArr.length; i++) {
+ let loader = new THREE.GLTFLoader();
+ loader.load( _this.util.beforPath + _this.util.initModelArr[i].url,
+ function (collada) {
+ collada.scene.scale.x = collada.scene.scale.y =collada.scene.scale.z = _this.util.initModelArr[i].scale;
+ collada.scene.position.set( _this.util.initModelArr[i].site.x, _this.util.initModelArr[i].site.y,_this.util.initModelArr[i].site.z);
+ collada.scene.rotation.set((_this.util.initModelArr[i].rot.x * Math.PI) / 180, (_this.util.initModelArr[i].rot.y * Math.PI) / 180,(_this.util.initModelArr[i].rot.z * Math.PI) / 180);
+ collada.scene.userData.type = _this.util.initModelArr[i].type;
+ for (let k = 0; k < collada.animations.length; k++) {
+ let mixer = new THREE.AnimationMixer(collada.scene);
+ mixer.clipAction(collada.animations[k]).play();
+ _this.mixers.push(mixer);
+ }
+ //////////////////////////////////////////////
+ collada.scene.traverse(function (child) {
+ if (child.type === "Mesh") {
+ child.castShadow = _this.util.options.shadow;
+ child.receiveShadow = _this.util.options.shadow;
+ child.userData.opacity = child.material.opacity;
+ if (child.material.map) {
+ child.material.map.encoding = THREE.LinearEncoding; //贴图需要转换成 线性编码
+ }
+ }
+ });
+ collada.scene.name = "model"; //删除其它元素时过滤
+ if (_this.util.initModelArr[i].type == "out") {
+ _this.outModelGap.add(collada.scene);
+ } else if (_this.util.initModelArr[i].type == "periphery") {
+ _this.peripheryGap.add(collada.scene);
+ }
+ }
+ );
+ if (i == _this.util.initModelArr.length - 1) {
+ for (let u = 0; u < _this.util.tipArr.length; u++) {
+ let prite = document.createElement("div");
+ prite.style.zIndex = _this.util.tipArr[u].zIndex || 20;
+ prite.innerHTML = _this.util.tipArr[u].htmlUrl;
+ if (!_this.util.tipArr[u].click) {
+ prite.style.pointerEvents = "none";
+ }
+ let pointLabel2 = new THREE.CSS2DObject(prite);
+ pointLabel2.position.set(_this.util.tipArr[u].x, _this.util.tipArr[u].z, _this.util.tipArr[u].y);
+ pointLabel2.userData.type = "2d_IP";
+ pointLabel2.userData.show = _this.util.tipArr[u].show;
+ pointLabel2.userData.name = _this.util.tipArr[u].name || "";
+ if (pointLabel2.userData.show == "all" ||pointLabel2.userData.show == language) {
+ pointLabel2.element.style.visibility = "visible";
+ } else {
+ pointLabel2.element.style.visibility = "hidden";
+ }
+ if (_this.util.tipArr[u].type == "out") {
+ _this.outObject.add(pointLabel2);
+ } else if (_this.util.tipArr[u].type == "periphery") {
+ _this.perObject.add(pointLabel2);
+ }
+ }
+ _this.initBuild();
+ }
+ }
+ } else {
+ _this.util.changeDist.inner = _this.util.options.maxDis;
+ _this.initBuild();
+ }
+ },
+ changePerTag: function (str) {
+ if (mapState == "periphery") {
+ Map_QM.perObject.traverse(function (child) {
+ if (child.userData && child.userData.show) {
+ if (child.userData.show.includes(str)) {
+ child.element.style.visibility = "visible";
+ } else {
+ child.element.style.visibility = "hidden";
+ }
+ }
+ });
+ }
+ },
+ initBuild: function () {
+ this.util.pathStateObj.elevator = null;
+ this.util.pathStateObj.straight = null;
+ this.util.pathStateObj.elevatorDown = null;
+ let loader2 = new THREE.GLTFLoader();
+ let _this = this;
+ loader2.load(this.util.beforPath + "static/img/zhong.glb",
+ function (collada2) {
+ collada2.scene.scale.x = collada2.scene.scale.y = collada2.scene.scale.z = 80;
+ collada2.scene.applyMatrix4(_this.sceneGap.matrix);
+ collada2.scene.renderOrder = 200;
+ collada2.scene.traverse(function (child) {
+ if (child.type === "Mesh") {
+ child.castShadow = _this.util.options.shadow;
+ child.receiveShadow = _this.util.options.shadow;
+ child.userData.opacity = child.material.opacity;
+ if (child.material.map) {
+ child.material.map.encoding = THREE.LinearEncoding; //贴图需要转换成 线性编码
+ }
+ if(child.material.roughness && child.material.roughness<0.8){
+ child.material.roughness=0.8;
+ }
+ }
+ });
+ collada2.scene.name = "Z-model";
+ for (let k = 0; k < collada2.animations.length; k++) {
+ let mixer = new THREE.AnimationMixer(collada2.scene);
+ mixer.clipAction(collada2.animations[k]).play();
+ _this.mixers.push(mixer);
+ }
+ _this.endModel = collada2.scene;
+ _this.scene.add(collada2.scene);
+ _this.endModel.visible = false;
+ }
+ );
+
+ let spriteMap = new THREE.TextureLoader().load(
+ _this.util.beforPath + "static/img/Z.png"
+ );
+ let spriteMaterial = new THREE.SpriteMaterial({
+ //sizeAttenuation: false 禁止跟随鼠标缩放
+ map: spriteMap,
+ depthTest: true,
+ transparent: true,
+ alphaTest: 0.5,
+ });
+ _this.endIcon = new MySprite_QM(spriteMaterial);
+ _this.endIcon.scale.set(100, 120, 1);
+ _this.endIcon.center = new THREE.Vector2(0.5, 0);
+ _this.endIcon.position.set(0, 55, 0);
+ _this.endIcon.applyMatrix4(_this.sceneGap.matrix);
+ _this.endIcon.renderOrder = 300;
+ _this.endIcon.visible = false;
+ _this.endIcon.name = "Z-model";
+ _this.scene.add(_this.endIcon);
+ if (_this.util.options.modelIcon) {
+ let loader = new THREE.GLTFLoader();
+ loader.load(_this.util.beforPath + "static/img/elevator.glb",
+ function (collada) {
+ collada.scene.scale.x = collada.scene.scale.y = collada.scene.scale.z = _this.util.options.facSize || 20;
+ collada.scene.rotation.x = (-90 * Math.PI) / -180;
+ collada.scene.renderOrder = 300;
+ _this.util.pathStateObj.elevator = collada.scene;
+ collada.scene.traverse(function (child) {
+ if (child.type === "Mesh") {
+ child.castShadow = _this.util.options.shadow;
+ child.receiveShadow = _this.util.options.shadow;
+ child.userData.opacity = child.material.opacity;
+ if (child.material.map) {
+ child.material.map.encoding = THREE.LinearEncoding; //贴图需要转换成 线性编码
+ }
+ if(child.material.roughness && child.material.roughness<0.8){
+ child.material.roughness=0.8;
+ }
+ }
+ });
+
+ new THREE.GLTFLoader().load(_this.util.beforPath + "static/img/elevatorDown.glb",
+ function (collada) {
+ collada.scene.scale.x = collada.scene.scale.y = collada.scene.scale.z = _this.util.options.facSize || 20;
+ collada.scene.rotation.x = (-90 * Math.PI) / -180;
+ collada.scene.renderOrder = 300;
+ _this.util.pathStateObj.elevatorDown = collada.scene;
+ collada.scene.traverse(function (child) {
+ if (child.type === "Mesh") {
+ child.castShadow = _this.util.options.shadow;
+ child.receiveShadow = _this.util.options.shadow;
+ child.userData.opacity = child.material.opacity;
+ if (child.material.map) {
+ child.material.map.encoding = THREE.LinearEncoding; //贴图需要转换成 线性编码
+ }
+ if(child.material.roughness && child.material.roughness<0.8){
+ child.material.roughness=0.8;
+ }
+ }
+ });
+
+ new THREE.GLTFLoader().load(_this.util.beforPath + "static/img/dt.glb",
+ function (collada) {
+ collada.scene.scale.x = collada.scene.scale.y = collada.scene.scale.z = _this.util.options.facSize || 20;
+ collada.scene.rotation.x = (-90 * Math.PI) / -180;
+ collada.scene.renderOrder = 300;
+ _this.util.pathStateObj.straight = collada.scene;
+ collada.scene.traverse(function (child) {
+ if (child.type === "Mesh") {
+ child.castShadow = _this.util.options.shadow;
+ child.receiveShadow = _this.util.options.shadow;
+ child.userData.opacity = child.material.opacity;
+ if (child.material.map) {
+ child.material.map.encoding = THREE.LinearEncoding; //贴图需要转换成 线性编码
+ }
+ if(child.material.roughness && child.material.roughness<0.8){
+ child.material.roughness=0.8;
+ }
+ }
+ });
+ _this.index = 0;
+ _this.initTreeModel();
+ }
+ );
+ }
+ );
+ }
+ );
+ } else {
+ _this.index = 0;
+ _this.initTreeModel();
+ }
+ },
+ loaderOver: function () {
+ this.sceneGap = new THREE.Group();
+ this.sceneGap.scale.set(this.util.sceneGap.scale, this.util.sceneGap.scale, this.util.sceneGap.scale);
+ this.scene.add(this.sceneGap);
+ this.buildObj = new THREE.Group();
+ this.sceneGap.add(this.buildObj);
+ this.CSSObject = new THREE.Object3D();
+ if (this.moveFloorbg) {
+ this.moveFloorbg.userData.type = "moveFloor";
+ this.CSSObject.add(this.moveFloorbg);
+ }
+ this.CSSObject.add(this.outObject);
+ this.CSSObject.add(this.perObject);
+ this.buildObj.add(this.CSSObject);
+ this.initGuide();
+ if (!this.util.options.deviceAng) {
+ this.cameraPerspective.position.set(this.util.sceneGap.cameraX, this.util.sceneGap.cameraY, this.util.sceneGap.cameraZ );
+ this.cameraPerspective.updateProjectionMatrix(); //必须update
+ this.cameraOrtho.position.set(this.util.sceneGap.cameraX, this.util.sceneGap.cameraY, this.util.sceneGap.cameraZ);
+ this.cameraOrtho.updateProjectionMatrix();
+ this.controls.target.set(this.util.sceneGap.x, this.util.sceneGap.y, this.util.sceneGap.z);
+ }
+ this.controls.saveState();
+ let pathData = this.util.allMap[parseInt(this.util.deviceObj.build)].buildArr[parseInt(this.util.deviceObj.floor)].mapData.path;
+ pathData && pathData.nodes.sort(this.util.sortNode);
+ if (parseInt(this.util.deviceObj.node) != -1) {
+ if (pathData &&pathData.nodes.length > parseInt(this.util.deviceObj.node)) {
+ this.util.deviceObj.xaxis = pathData.nodes[parseInt(this.util.deviceObj.node)].x;
+ this.util.deviceObj.yaxis = pathData.nodes[parseInt(this.util.deviceObj.node)].y;
+ }
+ }
+ this.util.pathStateObj.facAllArr = [];
+ this.mapArr.length = 0;
+ this.util.pathStateObj.basePath = "{";
+ for (let bd = 0; bd < this.util.allMap.length; bd++) {
+ for (let i = 0; i < this.util.allMap[bd].buildArr.length; i++) {
+ this.convertPath(bd, i);
+ }
+ }
+ if (this.util.pathStateObj.basePath.length > 1) {
+ this.util.pathStateObj.basePath = this.util.pathStateObj.basePath.substr(0,this.util.pathStateObj.basePath.length - 1);
+ }
+ this.util.pathStateObj.basePath += "}";
+ let bjP = JSON.parse(this.util.pathStateObj.basePath);
+ if (this.util.options.otherPath) {
+ //如果多楼栋需要配置楼栋之间通行路径
+ for (let item of this.util.options.otherPath) {
+ bjP[item.f][item.s] = item.d;
+ bjP[item.s][item.f] = item.d;
+ }
+ }
+ //初始化基础路径;
+ let jcStr = JSON.stringify(bjP);
+ let graphPathObj = JSON.parse(jcStr);
+ let ftPathObj = JSON.parse(jcStr);
+ let dtPathObj = JSON.parse(jcStr);
+ let basePathObj = JSON.parse(jcStr);
+ try {
+ for (let j = 0; j < this.util.pathStateObj.facAllArr.length; j++) {
+ for (let k = 0; k < this.util.pathStateObj.facAllArr[j].length; k++) {
+ if(!this.util.pathStateObj.facAllArr[j][k].hasOwnProperty("toState") || this.util.pathStateObj.facAllArr[j][k].toState){ //增加扶梯停靠状态
+ 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] = 20000 +200 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder)-parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder));
+ graphPathObj[facP][nP] = 500 +100 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) -parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder));
+ dtPathObj[facP][nP] = 300 +80 *Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder)-parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder));
+ basePathObj[facP][nP] = 35;
+ } else if (this.util.pathStateObj.facAllArr[j][h].facCode == "td") {
+ graphPathObj[facP][nP] = 400 +80 * Math.abs( parseInt( this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder));
+ ftPathObj[facP][nP] = 400 +80 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) -parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder ));
+ dtPathObj[facP][nP] = 400 + 80 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder));
+ basePathObj[facP][nP] = 30 *Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) -parseInt( this.util.pathStateObj.facAllArr[j][k].floorOrder ));
+ } else {
+ dtPathObj[facP][nP] = 20000 +200 * Math.abs(parseInt( this.util.pathStateObj.facAllArr[j][h].floorOrder) - parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder) );
+ graphPathObj[facP][nP] = 200 + 300 * Math.abs( parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) -parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder) );
+ ftPathObj[facP][nP] = 300 + 80 * Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder) -parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder));
+ basePathObj[facP][nP] = 20 *Math.abs(parseInt(this.util.pathStateObj.facAllArr[j][h].floorOrder)-parseInt(this.util.pathStateObj.facAllArr[j][k].floorOrder));
+ }
+ }
+ }
+ }
+ }
+ }
+ } catch (e) {
+ window.captureException && window.captureException(e);
+ console.log("交通设施点位问题: " + e);
+ }
+
+ this.util.pathStateObj.graphPath = graphPathObj;
+ this.util.pathStateObj.ftPath = ftPathObj;
+ this.util.pathStateObj.dtPath = dtPathObj;
+ this.util.pathStateObj.basePath = basePathObj;
+ let fIndex = 0, bIndex = 0;
+ this.mapArr[bIndex] = new Array();
+ let _this = this;
+ intTimer = setInterval(() => {
+ if (!_this.util.allMap[bIndex].buildArr[fIndex]) {
+ clearInterval(intTimer);
+ _this.initFloor();
+ return;
+ }
+ let floor = new FloorMap_QM(bIndex, fIndex, _this.util.allMap[bIndex].buildArr[fIndex].name );
+ floor.floorName = _this.util.allMap[bIndex].buildArr[fIndex].name;
+ floor.initDraw();
+ floor.allObj.position.set(0, 0, 0);
+ if (bIndex != parseInt(_this.util.deviceObj.build) || fIndex != parseInt(_this.util.deviceObj.floor)) {
+ floor.allObj.visible = false;
+ }
+ _this.buildObj.add(floor.allObj);
+ _this.mapArr[bIndex].push(floor);
+ fIndex++;
+ if (fIndex >= _this.util.allMap[bIndex].buildArr.length) {
+ if (bIndex == _this.util.allMap.length - 1) {
+ clearInterval(intTimer);
+ let pathData = _this.util.allMap[parseInt(_this.util.deviceObj.build)].buildArr[parseInt(_this.util.deviceObj.floor)].mapData.path;
+ if (_this.util.deviceObj.xaxis) {
+ _this.mapArr[parseInt(_this.util.deviceObj.build)][parseInt(_this.util.deviceObj.floor)].setStartSite(_this.util.deviceObj.xaxis,_this.util.deviceObj.yaxis, parseInt(_this.util.shopHeight) + 20);
+ } else {
+ if (parseInt(_this.util.deviceObj.node) != -1) {
+ pathData && pathData.nodes.sort(_this.util.sortNode);
+ if (pathData &&!_this.util.deviceObj.xaxis && pathData.nodes.length > parseInt(_this.util.deviceObj.node) && parseInt(_this.util.deviceObj.node) >= 0) {
+ _this.util.deviceObj.xaxis = pathData.nodes[parseInt(_this.util.deviceObj.node)].x;
+ _this.util.deviceObj.yaxis = pathData.nodes[parseInt(_this.util.deviceObj.node)].y;
+ } else {
+ console.warn("初始化点位失败");
+ }
+ _this.mapArr[parseInt(_this.util.deviceObj.build)][parseInt(_this.util.deviceObj.floor)].setStartSite(_this.util.deviceObj.xaxis,_this.util.deviceObj.yaxis,parseInt(_this.util.shopHeight) + 20);
+ }
+ }
+ _this.initFloor();
+ } else {
+ bIndex++;
+ fIndex = 0;
+ _this.mapArr[bIndex] = [];
+ }
+ }
+ }, 0);
+ },
+ beforeDestroy: function () {
+ if (this.scene) {
+ this.controls && this.controls.dispose();
+ this.renderer.renderLists && this.renderer.renderLists.dispose();
+ this.renderer.dispose && this.renderer.dispose();
+ this.renderer.forceContextLoss();
+ let gl = this.renderer.domElement.getContext('webgl');
+ gl && gl.getExtension('WEBGL_lose_context').loseContext();
+ this.util.pathStateObj.basePath = null;
+ this.ele.removeEventListener("touchmove", this.mouseMove);
+ this.ele.removeEventListener("click", this.onMouseClickBox); //地图点击
+ this.ele.removeEventListener("touchend", this.mouseUp);
+ this.controls.removeEventListener("change", this.controlsChock);
+ document.removeEventListener("resize", this.changeDocmentResize); //窗口变化
+ this.remove_child(this.sceneGap);
+ this.scene.remove(this.sceneGap);
+ while (this.ele.firstChild) {
+ this.ele.firstChild.remove();
+ }
+ this.renderer.domElement = null;
+ this.renderer.content = null;
+ this.renderer = null;
+ this.scene.clear();
+ this.scene = null;
+ this.camera = null;
+ this.controls = null;
+ this.util.spriteMaterialArr = [];
+ this.util.lineBasicMaterialArr = [];
+ this.util.meshMaterialArr = [];
+ this.util.parkMaterialArr = [];
+ this.util.shopData = []; //店铺数据
+ this.util.iconUrl = [];
+ this.util.allMap = [];
+ this.util = null;
+ Map_QM = null;
+ }
+ },
+ /**
+ * @api {方法} changeLanguage() 切换中英文
+ * @apiGroup 地图交互
+ * @apiDescription 切换中英文 zh en
+ * @apiVersion 1.0.0
+ * @apiParam {String} str 显示语言
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample {String} 请求示例
+ *
+ * Map_QM.changeLanguage("en");
+ *
+ */
+ changeLanguage: function (lang = "zh") {
+ language = lang;
+ for (let t = 0; t < Map_QM.mapArr.length; t++) {
+ for (let i = 0; i < Map_QM.mapArr[t].length; i++) {
+ Map_QM.mapArr[t][i].labelObj.traverse((obj) => {
+ if (obj.element) {
+ obj.element.innerText = lang == "en"? (obj.element.dataset.nameEn || obj.element.dataset.name) : obj.element.dataset.name;
+ }
+ });
+ Map_QM.mapArr[t][i].showTagObj.traverse((obj) => {
+ if (obj.element) {
+ obj.element.style.opacity = obj.userData.show != lang ? 0 : 1;
+ }
+ });
+ }
+ }
+ Map_QM.outObject.traverse((obj) => {
+ if (obj.element && mapState == "out") {
+ if(obj.userData.show == "all"){
+ obj.element.style.visibility = "visible";
+ }else{
+ obj.element.style.visibility = obj.userData.show == lang ? "visible" : "hidden";
+ }
+ }
+ });
+ Map_QM.perObject.traverse((obj) => {
+ if (obj.element && mapState == "periphery") {
+ obj.element.style.visibility = obj.userData.show == lang ? "visible" : "hidden";
+ }
+ });
+ //出发方向英文
+ Map_QM.CSSObject.traverse((obj) => {
+ if (obj.element && obj.userData.type == "dirLabel") {
+ obj.element.children[0].children[1].innerText = lang == "en" ? obj.element.dataset.nameEn : obj.element.dataset.name;
+ }
+ });
+ Map_QM.controlsChock();
+ },
+ initTreeModel: function () {
+ 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 = sopce.util.options.shadow;
+ child.receiveShadow = sopce.util.options.shadow;
+ if (child.material.map) {
+ child.material.map.encoding = THREE.LinearEncoding; //贴图需要转换成 线性编码
+ }
+ if (sopce.util.modelStr[sopce.index].colorModel === "gama") {
+ child.material.color.convertGammaToLinear(0.6);
+ }
+ if(child.material.roughness && child.material.roughness<0.8){
+ child.material.roughness=0.8;
+ }
+ }
+ });
+ 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, operation: sopce.util.modelStr[sopce.index],});
+ if (sopce.index < sopce.util.modelStr.length - 1) {
+ sopce.index++;
+ sopce.initTreeModel();
+ } else {
+ if (sopce.util.allMap && sopce.util.allMap.length > 0) {
+ sopce.loaderOver();
+ }
+ }
+ });
+ },
+ initGuide: function () {
+ let _this = this;
+ new THREE.GLTFLoader().load(
+ this.util.beforPath + "static/img/runman.gltf",
+ function (obj) {
+ obj.scene.scale.x = obj.scene.scale.y =obj.scene.scale.z = 20;
+ obj.scene.children[0].children[1].children[0].material.color = new THREE.Color(0xfe9219);
+ _this.sceneGap.add(obj.scene);
+ obj.scene.traverse(function (child) {
+ if (child.type === "SkinnedMesh") {
+ child.material.map && (child.material.map.encoding = THREE.LinearEncoding); //贴图需要转换成 线性编码
+ }
+ });
+ obj.scene.visible = false;
+ obj.scene.children[0].rotation.x = Math.PI / 2;
+ obj.scene.children[0].rotation.y = Math.PI;
+ // obj作为参数创建一个混合器,解析播放obj及其子对象包含的动画数据
+ let mixer = new THREE.AnimationMixer(obj.scene);
+ let AnimationAction = mixer.clipAction(obj.animations[0]);
+ AnimationAction.play();
+ _this.mixers.push(mixer);
+ _this.man_3d = obj.scene;
+ _this.guide = _this.man_3d;
+ }
+ );
+
+ new THREE.GLTFLoader().load(
+ this.util.beforPath + "static/img/guide.glb",
+ function (obj) {
+ obj.scene.scale.x =obj.scene.scale.y = obj.scene.scale.z = 90;
+ obj.scene.visible = false;
+ obj.scene.children[0].rotation.x = Math.PI / 2;
+ obj.scene.traverse(function (child) {
+ if (child.type === "Mesh") {
+ child.castShadow = _this.util.options.shadow;
+ child.receiveShadow = _this.util.options.shadow;
+ child.userData.opacity = child.material.opacity;
+ if (child.material.map) {
+ child.material.map.encoding = THREE.LinearEncoding; //贴图需要转换成 线性编码
+ }
+ if(child.material.roughness && child.material.roughness<0.8){
+ child.material.roughness = 0.8;
+ }
+ }
+ });
+ for (let k = 0; k < obj.animations.length; k++) {
+ let mixer = new THREE.AnimationMixer(obj.scene);
+ mixer.clipAction(obj.animations[k]).play();
+ _this.mixers.push(mixer);
+ }
+ _this.man_2d = obj.scene;
+ _this.man_2d.renderOrder = 160;
+ _this.sceneGap.add(_this.man_2d);
+ }
+ );
+ },
+ initFloor: function () {
+ this.changeBuild(this.util.deviceObj.build, this.util.deviceObj.floor);
+ //初始化方向为第一人称方向
+ this.util.options.deviceAng && this.rotationAngle(this.util.deviceObj.angle);
+ this.startRender();
+
+ setTimeout(() => {
+ Map_QM.ele.addEventListener("touchmove", Map_QM.mouseMove);
+ Map_QM.ele.addEventListener("touchend", Map_QM.mouseUp);
+ Map_QM.ele.addEventListener("click", Map_QM.onMouseClickBox); //地图点击
+ Map_QM.controls.addEventListener("change", Map_QM.controlsChock); //控制器变化
+ Map_QM.util.fbxModels = [];
+ let boundBox = new THREE.Box3();
+ boundBox.setFromObject(Map_QM.sceneGap);
+ if (isNaN(boundBox.min.x) || isNaN(boundBox.min.y)) {
+ Map_QM.controls.minPan = new THREE.Vector3(Map_QM.w / -8,0,Map_QM.h / -8);
+ Map_QM.controls.maxPan = new THREE.Vector3(Map_QM.w / 8, 0,Map_QM.h / 8);
+ } else {
+ boundBox.min.x < -400 && (boundBox.min.x = boundBox.min.z);
+ boundBox.max.x > 400 && (boundBox.max.x = boundBox.max.z);
+ boundBox.min.z < -400 && (boundBox.min.z = boundBox.min.x);
+ boundBox.max.z > 400 && (boundBox.max.z = boundBox.max.x);
+ Map_QM.controls.minPan = boundBox.min;
+ Map_QM.controls.maxPan = boundBox.max;
+ }
+ console.log("Number of Triangles :", Map_QM.renderer.info.render.triangles);
+ if (Map_QM.util.initModelArr.length > 0) {
+ Map_QM.toOutModel();
+ setTimeout(() => {
+ Map_QM.toOutModelInner();
+ }, 1000);
+ }
+ }, 200);
+ },
+ 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;
+ },
+ /**
+ * 解析路径
+ */
+ convertPath: function (buildOrder, floorOrder) {
+ let mapDataA = this.util.allMap[buildOrder].buildArr[floorOrder].mapData;
+ let blc = this.util.allMap[buildOrder].scale || 10; //每米多少像素
+ let pathData = mapDataA.path;
+ if (!pathData) {
+ return;
+ }
+ if (pathData.nodes.length > 0) {
+ pathData.nodes.sort(this.util.sortNode);
+ for (let i = 0; i < pathData.nodes.length; i++) {
+ let a = pathData.nodes[i].id;
+ this.util.pathStateObj.basePath += '"' + buildOrder + "_" + floorOrder + "_" + a + '":{';
+ for (let n = 0; n < pathData.nodes[i]["list"].length; n++) {
+ let b;
+ if (pathData.nodes[i]["list"][n].id ||pathData.nodes[i]["list"][n].id == "0") {
+ b = pathData.nodes[i]["list"][n].id;
+ } else {
+ b = a == pathData.nodes[i]["list"][n].selfNode.id ? pathData.nodes[i]["list"][n].nextNode.id : pathData.nodes[i]["list"][n].selfNode.id;
+ }
+ this.util.pathStateObj.basePath +='"'+buildOrder+"_" +floorOrder +"_" +b +'":'+parseFloat(pathData.nodes[i]["list"][n].cost/blc).toFixed(2) +",";
+ }
+ if (pathData.nodes[i]["list"].length > 0) {
+ this.util.pathStateObj.basePath = this.util.pathStateObj.basePath.substr(0,this.util.pathStateObj.basePath.length - 1);
+ }
+ this.util.pathStateObj.basePath += "},";
+ }
+ }
+ let noHas;
+ for (let j = 0; j < mapDataA.stairs.length; j++) {
+ if ( parseInt(mapDataA.stairs[j].navCode) > 0 && mapDataA.stairs[j].state) {
+ //排除禁用的设施
+ noHas = true;
+ for (let k = 0; k < this.util.pathStateObj.facAllArr.length; k++) {
+ //Map_QM.util.pathStateObj.facAllArr 记录遍历结果
+ if (this.util.pathStateObj.facAllArr[k][0].no != "" && this.util.pathStateObj.facAllArr[k][0].navCode != "" &&
+ parseInt(this.util.pathStateObj.facAllArr[k][0].navCode) > 0 && this.util.pathStateObj.facAllArr[k][0].no == mapDataA.stairs[j].no ) {
+ if (this.util.pathStateObj.facAllArr[k][0].facCode == mapDataA.stairs[j].facCode || (this.util.pathStateObj.facAllArr[k][0].facCode.search("ft") != -1 && mapDataA.stairs[j].facCode.search("ft") != -1)) {
+ noHas = false;
+ mapDataA.stairs[j].floorOrder = floorOrder;
+ mapDataA.stairs[j].buildOrder = buildOrder;
+ this.util.pathStateObj.facAllArr[k].push(mapDataA.stairs[j]);
+ }
+ }
+ }
+ if (noHas) {
+ mapDataA.stairs[j].buildOrder = buildOrder;
+ mapDataA.stairs[j].floorOrder = floorOrder;
+ let array = [mapDataA.stairs[j]];
+ this.util.pathStateObj.facAllArr.push(array);
+ }
+ }
+ }
+ },
+ /**
+ * @api {方法} changeMapState("3d") 地图状态切换
+ * @apiGroup 地图显示
+ * @apiDescription 地图展示状态切换
+ * @apiVersion 4.0.0
+ * @apiParam {string} state 地图状态
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample {String} 请求示例
+ *
+ * Map_QM.changeMapState("2d");
+ *
+ */
+ changeMapState: function (state) {
+ Map_QM.controls.reset();
+ Map_QM.util.options.deviceAng && Map_QM.rotationAngle(Map_QM.util.deviceObj.angle);
+ if (state === "3d") {
+ Map_QM.camera = Map_QM.cameraPerspective;
+ Map_QM.controls.object = Map_QM.camera;
+ Map_QM.shawLight.castShadow = Map_QM.util.options.shadow;
+ Map_QM.controls.maxPolarAngle = Math.PI / 2 - 0.2;
+ Map_QM.controls.setZoom(1);
+ Map_QM.changeIconState(state);
+ } else {
+ Map_QM.camera = Map_QM.cameraOrtho;
+ Map_QM.controls.object = Map_QM.camera;
+ Map_QM.shawLight.castShadow = false;
+ Map_QM.controls.maxPolarAngle = 0;
+ Map_QM.changeIconState(state);
+ }
+ },
+
+ changeIconState: function (state, fIndex = -1) {
+ iconState = state;
+ fIndex = fIndex === -1 ? Map_QM.util.selectFloor : fIndex;
+ if(!Map_QM.mapArr || !Map_QM.mapArr[Map_QM.util.selectBuild]){
+ return;
+ }
+ try{
+ for (let i = 0; i < Map_QM.mapArr[Map_QM.util.selectBuild].length; i++) {
+ if (i == fIndex && Map_QM.buildObj.visible) {
+ Map_QM.mapArr[Map_QM.util.selectBuild][i].serObj.traverse((obj) => {
+ if (obj.userData && obj.userData.use) {
+ if (obj.userData.use != "all" && obj.userData.use != state) {
+ obj.visible = false;
+ obj.element && (obj.element.style.display = "none");
+ } else {
+ obj.visible = true;
+ obj.element && (obj.element.style.display = "block");
+ }
+ }
+ });
+ }
+ }
+ }catch(e){
+ window.captureException && window.captureException(e);
+ console.log(e);
+ }
+ if (Map_QM.qiModel) {
+ Map_QM.qiModel.visible = state == "3d" ? true : false;
+ Map_QM.qiModel.children[0].children[0].visible= Map_QM.util.pathStateObj.isPathState ?true:false;
+ }
+ if (Map_QM.devModel) {
+ Map_QM.devModel.visible = state == "2d" && !Map_QM.util.pathStateObj.isPathState ? true : false;
+ }
+ if (Map_QM.qiIcon) {
+ Map_QM.qiIcon.visible = state == "2d" && Map_QM.util.pathStateObj.isPathState ? true : false;
+ }
+ },
+
+ /**
+ * @api {方法} changeBuild(buildOrder,floorOrder) 楼栋切换
+ * @apiGroup 地图交互
+ * @apiDescription 楼栋切换 传入楼栋编号,楼层编号
+ * @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.changeMapModel("3D");
+ Map_QM.resetFloorState();
+ Map_QM.controls.reset();
+ Map_QM.util.options.deviceAng && Map_QM.rotationAngle(Map_QM.util.deviceObj.angle);
+ buildOrder = buildOrder == -1 ? parseInt(Map_QM.util.selectBuild) : buildOrder;
+ Map_QM.clearFloor(Map_QM.util.selectFloor);
+ this.changeBuildInner(buildOrder, floorOrder);
+ },
+
+ changeBuildInner: function (build = -1, fIndex = -1) {
+ fIndex = fIndex == -1 ? 0 : fIndex;
+ build = build == -1 ? parseInt(Map_QM.util.selectBuild) : build;
+ Map_QM.util.selectBuild = build;
+ Map_QM.changeFloorInner(build, fIndex); //结束后切换楼层
+ },
+
+ 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);
+ Map_QM.controls.enableRotate = true;
+ Map_QM.controls.minAzimuthAngle = -Infinity;
+ Map_QM.controls.maxAzimuthAngle = Infinity;
+ Map_QM.util.pathStateObj.forShopArr = { direction: "", wayList: [] };
+ if (Map_QM.guide && Map_QM.guide.visible) {
+ Map_QM.guide.visible = false;
+ }
+ if (Map_QM.endModel && Map_QM.endModel.visible) {
+ Map_QM.endModel.visible = false;
+ }
+ },
+ /**
+ * @api {方法} showFloor(floorOrder) 通过楼层编号切换楼层
+ * @apiGroup 地图交互
+ * @apiDescription 楼层切换,传入楼层编号,编号从下到上排序,最下面是0
+ * @apiVersion 4.0.0
+ *
+ * @apiParam {int} floorOrder 楼层编号
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample {int} 请求示例
+ *
+ * Map_QM.showFloor(1);
+ *
+ */
+ showFloor: function (fIndex = -1, callBack = undefined) {
+ clearTimeout(actionTime); //清理导航
+ if (!Map_QM.buildObj.visible) {
+ return;
+ }
+ Map_QM.util.isMorePath = false;
+ Map_QM.util.pathStateObj.isPathState = false;
+ //Map_QM.changeStartPoint();
+ isShowElement = true;
+ allJU = true;
+ try{
+ Map_QM.changeMapModel("3D");
+ Map_QM.resetFloorState();
+ Map_QM.controls.reset();
+ Map_QM.util.options.deviceAng && Map_QM.rotationAngle(Map_QM.util.deviceObj.angle);
+ Map_QM.clearFloor(fIndex);
+ Map_QM.elementDestroy("all");
+ if (fIndex != -1) {
+ Map_QM.changeFloorInner(-1, fIndex, callBack);
+ }
+ }catch(e){
+
+ }
+ },
+ /**
+ * @api {方法} bindingShop(mesh,shop,isBinding) 绑定或解绑店铺
+ * @apiGroup 地图交互
+ * @apiDescription 给3D对象绑定数据
+ * @apiVersion 4.0.0
+ *
+ * @apiParam {Object3D} mesh 3D对象
+ * @apiParam {Object} shop 要绑定的数据对象(houseNumber是必需属性)。解绑可以不传
+ * @apiParam {Boolean} isBinding 默认true。 true是绑定,false是解绑
+ *
+ * @apiSampleRequest off
+ * @apiParamExample 请求示例
+ *
+ * Map_QM.bindingShop(mesh, {shopName:"shop",houseNumber:"L101",color:"", ...},true);
+ */
+ bindingShop: function (mesh, shop, isBinding = true) {
+ if (!isBinding || (shop && shop.houseNumber)) {
+ for (let i = 0; i < Map_QM.util.allMap.length; i) {
+ for (let j = 0; j < Map_QM.util.allMap[i].buildArr.length; j++) {
+ let shopArea = Map_QM.util.allMap[i].buildArr[j].mapData.shopArea;
+ for (let k = 0; k < shopArea.length; k++) {
+ if (shopArea[k].id === mesh.userData.id) {
+ if (isBinding) {
+ shopArea[k].name = shop.houseNumber; //修改地图原始数据的box名称
+ mesh.userData.shopData = shop;
+ mesh.name = shop.houseNumber;
+ if (shop.color) {
+ // 替换材质
+ mesh.userData.initMaterial = mesh.material;
+ let meshMat = new THREE.MeshStandardMaterial({
+ color: shop.color,
+ transparent: true,
+ opacity: mesh.material.opacity,
+ side: THREE.DoubleSide,
+ depthTest: true,
+ emissive : 0x000000,
+ roughness:0.8
+ });
+ Map_QM.util.meshMaterialArr.push(meshMat);
+ mesh.material = meshMat;
+ }
+ //添加名称标签
+ let shopLabel = Map_QM.util.addMapLabel(shop.shopName, shop.shopName, shop.houseNumber);
+ shopLabel.position.set(mesh.xaxis >> 0, (-1 * mesh.yaxis) >> 0, mesh.zaxis);
+ Map_QM.mapArr[mesh.userData.build][mesh.userData.floor].labelObj.add(shopLabel);
+ Map_QM.updateRender();
+ Map_QM.collLabel();
+ } else {
+ shopArea[k].name = "shop";
+ mesh.userData.shopData = {};
+ if (mesh.userData.initMaterial) {
+ mesh.material = mesh.userData.initMaterial;
+ }
+ //删除文本标签
+ let labObj = Map_QM.mapArr[mesh.userData.build][mesh.userData.floor].labelObj.children;
+ for (let j = 0; j < labObj.length; j++) {
+ if (labObj[j].name == mesh.name) {
+ if (labObj[j].element && labObj[j].element.parentNode) {
+ labObj[j].element.parentNode.removeChild(labObj[j].element);
+ }
+ Map_QM.mapArr[mesh.userData.build][mesh.userData.floor].labelObj.remove(labObj[j]);
+ break;
+ }
+ }
+ }
+ return;
+ }
+ }
+ }
+ }
+ }
+ },
+ /**
+ * @api {方法} getAllIcon() 获取所有Icon
+ * @apiGroup 地图数据
+ * @apiDescription 获取所有Icon
+ * @apiVersion 2.0.0
+ * @apiParam {int} floorOrder 楼层编号(默认 所有楼层)
+ *
+ * @apiSampleRequest off
+ *
+ */
+ getAllIcon: function (floorOrder = -1) {
+ let icons = new Array();
+ if (floorOrder != -1) {
+ let bd = Map_QM.util.selectBuild;
+ let sers = Map_QM.mapArr[bd][floorOrder].serObj.children; //服务图标
+ for (let n = 0; n < sers.length; n++) {
+ if (sers[n].type == 'Object3D') {
+ let title = sers[n].userData.name||sers[n].userData.title;
+ let titleEn = sers[n].userData.nameEn || title;
+ let type = sers[n].userData.facCode;
+ let imgUrl = sers[n].userData.src;
+ if (sers[n].facCode == 'upft' || sers[n].facCode == 'downft' || sers[n].facCode == 'ft') {
+ if (title == '上扶梯' || title == '下扶梯') {
+ title = '扶梯';
+ }
+ type = 'ft';
+ }
+ let icon = { type: type, floor: floorOrder, imgUrl: imgUrl, title: title, titleEn: titleEn };
+ icons.push(icon)
+ }
+ }
+ return icons
+ }
+
+ for (let j = 0; j < Map_QM.mapArr.length; j++) {
+ let iconBuild = []
+ for (let i = 0; i < Map_QM.mapArr[j].length; i++) {
+ let iconArr = []
+ if (Map_QM.mapArr[j][i].serObj) {
+ let sers = Map_QM.mapArr[j][i].serObj.children //服务图标
+ for (let n = 0; n < sers.length; n++) {
+ if (sers[n].type == 'Object3D') {
+ let title = sers[n].userData.name||sers[n].userData.title;
+ let titleEn = sers[n].userData.nameEn || title;
+ let type = sers[n].userData.facCode;
+ let imgUrl = sers[n].userData.src;
+ if (sers[n].facCode == 'upft' || sers[n].facCode == 'downft' || sers[n].facCode == 'ft') {
+ title = '扶梯'
+ type = 'ft'
+ }
+ let icon = { type: type, floor: i, imgUrl: imgUrl, title: title, titleEn: titleEn }
+ iconArr.push(icon)
+ }
+ }
+ }
+ iconBuild.push(iconArr)
+ }
+ icons.push(iconBuild)
+ }
+ return icons
+ },
+ /**
+ * @api {方法} queryAllMapData() 获取地图原始数据
+ * @apiGroup 地图数据
+ * @apiDescription 获取地图接口数据
+ * @apiVersion 4.0.1
+ *
+ * @apiSampleRequest off
+ * @apiParamExample {String} 请求示例
+ *
+ * Map_QM.queryAllMapData();
+ */
+ queryAllMapData: function () {
+ return JSON.stringify({
+ mallCode: Map_QM.util.mallCode,
+ MapInfo: Map_QM.util.allMap,
+ key: "Aeditor",
+ });
+ },
+ /**
+ * @api {方法} changeFloorByName(floorOrder) 通过楼层名称切换楼层
+ * @apiGroup 地图交互
+ * @apiDescription 楼层切换,传入楼层名称,
+ * @apiVersion 4.0.0
+ *
+ * @apiParam {String} floorName 楼层名称
+ *
+ * @apiSampleRequest off
+ * @apiParamExample {String} 请求示例
+ *
+ * Map_QM.changeFloorByName("L1");
+ */
+ changeFloorByName: function (floorName) {
+ let floors = Map_QM.mapArr[Map_QM.util.selectBuild];
+ for (let i = 0; i < floors.length; i++) {
+ if (floors[i].floorName == floorName) {
+ Map_QM.showFloor(floors[i].floorOrder);
+ return;
+ }
+ }
+ },
+ /**
+ * @api {方法} changeFloorByCode(floorCode) 通过楼层code切换楼层
+ * @apiGroup 地图交互
+ * @apiDescription 楼层切换,传入楼层code,
+ * @apiVersion 4.0.0
+ *
+ * @apiParam {String} floorCode 楼层code
+ *
+ * @apiSampleRequest off
+ * @apiParamExample {String} 请求示例
+ *
+ * Map_QM.changeFloorByCode("Ek_MaiuKLPjakB1uB0uQV");
+ */
+ changeFloorByCode: function (floorCode) {
+ for (let kk = 0; kk < Map_QM.util.allMap.length; kk++) {
+ for (var iii = 0; iii < Map_QM.util.allMap[kk].buildArr.length; iii++) {
+ if (Map_QM.util.allMap[kk].buildArr[iii].code == floorCode) {
+ Map_QM.changeBuild(kk, iii);
+ return;
+ }
+ }
+ }
+ },
+ changeFloorInner: function (build = -1,fIndex = -1,callBack = undefined) {
+ Map_QM.elementDestroy("dirLabel",true);
+ if (Map_QM.util.initModelArr.length > 0) {
+ Map_QM.controls.setDistance(Map_QM.util.changeDist.inner - 25);
+ Map_QM.controls.update();
+ }
+ fIndex = fIndex != -1 ? fIndex : Map_QM.util.deviceObj.floor;
+ build = build != -1 ? build : Map_QM.util.selectBuild;
+ for (let t = 0; t < Map_QM.mapArr.length; t++) {
+ for (let i = 0; i < Map_QM.mapArr[t].length; i++) {
+ Map_QM.mapArr[t][i].allObj.visible = t == build ? true : false;
+ Map_QM.mapArr[t][i].CSSObj.traverse((obj) => {
+ obj.element && (obj.element.style.display = "none");
+ });
+ }
+ }
+ if (Map_QM.mapArr[build] && Map_QM.mapArr[build][fIndex]) {
+ Map_QM.mapArr[build][fIndex].allObj.visible = true;
+ } else {
+ return;
+ }
+ for (let i = 0; i < Map_QM.mapArr[build].length; i++) {
+ if (i == fIndex) {
+ Map_QM.mapArr[build][i].allObj.visible = true;
+ Map_QM.mapArr[build][i].CSSObj.traverse((obj) => {
+ obj.element && obj.userData.isShow && obj.userData.type == "icon" && (obj.element.style.display = "block");
+ });
+ Map_QM.changeIconState(iconState, fIndex);
+ } else {
+ Map_QM.mapArr[build][i].allObj.visible = false;
+ }
+ if (i == Map_QM.mapArr[build].length - 1) {
+ if (build == Map_QM.util.selectBuild && fIndex == Map_QM.util.selectFloor ) {
+ if (callBack) callBack();
+ Map_QM.timeOutInit();
+ } else {
+ 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.2,
+ { z: Map_QM.util.options.fSpace },
+ { z: 0, ease: Cubic.easeIn,
+ onComplete: function () {
+ Map_QM.timeOutInit();
+ if (callBack) callBack();
+ },
+ }
+ );
+ } else {
+ Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.position.z = 0;
+ Map_QM.timeOutInit();
+ if (callBack) callBack();
+ }
+ }
+ }
+ }
+ },
+ /**
+ * @api {方法} onShowMeDir() 我的方向
+ * @apiGroup 地图显示
+ * @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) {
+ this.changeFloorInner(this.util.deviceObj.build, this.util.deviceObj.floor);
+ }
+ this.onInnerMeDir();
+ },
+ onInnerMeDir: function () {
+ TweenMax.killAll(true);
+ this.changeMapModel("2D");
+ Map_QM.controls.reset();
+ clearTimeout(shopTime);
+ isJUZ = false;
+ Map_QM.controls.minPolarAngle = 0;
+ if (Map_QM.util.deviceObj.xaxis || Map_QM.util.deviceObj.yaxis) {
+ Map_QM.mapToPoint(Map_QM.util.deviceObj.xaxis, Map_QM.util.deviceObj.yaxis, 0, false );
+ } else {
+ Map_QM.mapToPoint(0, 0, 0, false);
+ }
+ Map_QM.rotationAngle(Map_QM.util.deviceObj.angle);
+ Map_QM.controls.setZoom(2);
+ Map_QM.controls.enableRotate = false;
+ Map_QM.updateRender();
+ Map_QM.collLabel();
+ },
+ changeMapModel: function (model) {
+ if (model == "2D") {
+ Map_QM.changeIconState("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.changeIconState("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.updateRender();
+ },
+ /**
+ * @api {方法} toOutModel() 显示外立面模型
+ * @apiGroup 地图显示
+ * @apiDescription 显示外立面模型
+ * @apiVersion 4.0.0
+ *
+ * @apiSampleRequest off
+ * @apiParamExample {String} 请求示例
+ *
+ * Map_QM.toOutModel();
+ */
+ toOutModel: function () {
+ TweenMax.killAll(true);
+ Map_QM.controls.setDistance(Map_QM.util.changeDist.inner + 25);
+ Map_QM.controls.update();
+ Map_QM.disPlayEvent(true);
+ Map_QM.resetModel();
+ },
+ toOutModelInner: function () {
+ TweenMax.killAll(true);
+ Map_QM.emitChangeMap("out");
+ Map_QM.hideFloor();
+ Map_QM.buildObj.visible = false;
+ TweenMax.to(Map_QM.peripheryGap.scale, 0.3, {
+ y: 0.01,
+ ease: Quad.easeIn,
+ onComplete: function () {
+ Map_QM.hideObjecrGap(Map_QM.peripheryGap, false); //隐藏外立面
+ Map_QM.hideObjecrGap(Map_QM.perObject, false);
+ },
+ });
+ if (!Map_QM.outModelGap.visible) {
+ Map_QM.hideObjecrGap(Map_QM.outModelGap, true);
+ Map_QM.hideObjecrGap(Map_QM.outObject, true);
+ TweenMax.to(Map_QM.outModelGap.scale, 0.6, {y: 1, ease: Quad.easeIn});
+ } else {
+ mapState = "out";
+ }
+ Map_QM.rotateAngle(70);
+ Map_QM.controls.autoRotate = true;
+ },
+ hideFloor: function () {
+ Map_QM.changeMapModel("3D");
+ Map_QM.resetFloorState();
+ Map_QM.clearFloor();
+ Map_QM.hideInnerFloorElement();
+ },
+ /**
+ * @api {方法} toPeriphery() 显示周边模型
+ * @apiGroup 地图显示
+ * @apiDescription 显示周边模型
+ * @apiVersion 4.0.0
+ *
+ * @apiSampleRequest off
+ * @apiParamExample {String} 请求示例
+ *
+ * Map_QM.toPeriphery();
+ */
+ toPeriphery: function () {
+ TweenMax.killAll(true);
+ Map_QM.controls.reset();
+ Map_QM.controls.setDistance(Map_QM.util.changeDist.outner + 25);
+ Map_QM.controls.update();
+ Map_QM.disPlayEvent(true);
+ },
+
+ toPeripheryInner: function () {
+ TweenMax.killAll(true);
+ Map_QM.emitChangeMap("periphery");
+ Map_QM.controls.autoRotate = false;
+ Map_QM.hideFloor();
+ TweenMax.to(Map_QM.outModelGap.scale, 0.3, {
+ y: 0.01,
+ ease: Quad.easeIn,
+ onComplete: function () {
+ Map_QM.buildObj.visible = false;
+ Map_QM.hideObjecrGap(Map_QM.outModelGap, false); //隐藏外立面
+ Map_QM.hideObjecrGap(Map_QM.outObject, false);
+ },
+ });
+ if (!Map_QM.peripheryGap.visible) {
+ Map_QM.hideObjecrGap(Map_QM.peripheryGap, true);
+ TweenMax.to(Map_QM.peripheryGap.scale, 0.6, {
+ y: 1,
+ ease: Quad.easeIn,
+ onComplete: function () {
+ Map_QM.changePerTag("mark");
+ },
+ });
+ } else {
+ mapState = "periphery";
+ }
+ Map_QM.rotateAngle(45);
+ },
+ /**
+ * @api {方法} hideInnerFloorElement() 隐藏室内楼层元素
+ * @apiGroup 地图显示
+ * @apiDescription 隐藏室内楼层元素
+ * @apiVersion 4.0.0
+ *
+ * @apiSampleRequest off
+ * @apiParamExample 请求示例
+ *
+ * Map_QM.hideInnerFloorElement();
+ */
+ hideInnerFloorElement: function () {
+ isShowElement = false;
+ for (let t = 0; t < Map_QM.mapArr.length; t++) {
+ for (let i = 0; i < Map_QM.mapArr[t].length; i++) {
+ Map_QM.mapArr[t][i].CSSObj.traverse((obj) => {
+ obj.element && (obj.element.style.display = "none");
+ if (obj.children && obj.children.length > 0) {
+ obj.traverse((item) => {
+ item.element && (item.element.style.display = "none");
+ });
+ }
+ });
+ }
+ }
+ },
+
+ /**
+ * @api {方法} toMall() 显示室内模型
+ * @apiGroup 地图显示
+ * @apiDescription 显示室内模型
+ * @apiVersion 4.0.0
+ *
+ * @apiSampleRequest off
+ * @apiParamExample {String} 请求示例
+ *
+ * Map_QM.toMall();
+ */
+ toMall: function () {
+ Map_QM.controls.reset();
+ Map_QM.controls.setDistance(Map_QM.util.changeDist.inner - 25);
+ Map_QM.controls.update();
+ Map_QM.disPlayEvent(true);
+ },
+ toMallInner: function () {
+ isShowElement = true;
+ TweenMax.killAll(true);
+ Map_QM.emitChangeMap("mall");
+ Map_QM.controls.autoRotate = false;
+ if (Map_QM.outModelGap.visible) {
+ TweenMax.to(Map_QM.outModelGap.scale, 0.5, {
+ y: 0.01,
+ ease: Quad.easeIn,
+ onComplete: function () {
+ Map_QM.buildObj.visible = true;
+ Map_QM.hideObjecrGap(Map_QM.outModelGap, false); //隐藏外立面
+ Map_QM.hideObjecrGap(Map_QM.outObject, false);
+ Map_QM.onShowDeviceSite();
+ },
+ });
+ } else {
+ if (Map_QM.peripheryGap.visible) {
+ TweenMax.to(Map_QM.peripheryGap.scale, 0.5, {
+ y: 0.01,
+ ease: Quad.easeIn,
+ onComplete: function () {
+ Map_QM.hideObjecrGap(Map_QM.peripheryGap, false); //隐藏外立面
+ Map_QM.hideObjecrGap(Map_QM.perObject, false);
+ Map_QM.buildObj.visible = true;
+ Map_QM.onShowDeviceSite();
+ },
+ });
+ } else {
+ Map_QM.buildObj.visible = true;
+ Map_QM.onShowDeviceSite();
+ }
+ }
+ },
+ //设置地图状态为室内状态
+ setMall: function () {
+ isShowElement = true;
+ TweenMax.killAll(true);
+ Map_QM.emitChangeMap("mall");
+ Map_QM.controls.autoRotate = false;
+ Map_QM.hideObjecrGap(Map_QM.outModelGap, false); //隐藏外立面
+ Map_QM.hideObjecrGap(Map_QM.outObject, false);
+ Map_QM.hideObjecrGap(Map_QM.peripheryGap, false); //隐藏外立面
+ Map_QM.hideObjecrGap(Map_QM.perObject, false);
+ Map_QM.buildObj.visible = true;
+ Map_QM.onShowDeviceSite();
+ },
+
+ emitChangeMap: function (state) {
+ if (mapState != state) {
+ mapState = state;
+ Map_QM.dispatchEvent({
+ type: "mapShowChange",
+ data: mapState,
+ });
+ }
+ },
+ hideObjecrGap: function (gap, isShow) {
+ gap.visible = isShow;
+ gap.traverse((obj) => {
+ if (obj.userData && obj.userData.type == "2d_IP") {
+ if (obj.element) {
+ if (isShow) {
+ if(obj.userData.show == "all"){
+ obj.element.style.visibility = "visible";
+ obj.element.style.display = "block";
+ }else{
+ obj.element.style.visibility = obj.userData.show == lang ? "visible" : "hidden";
+ obj.element.style.display = obj.userData.show == language ? "block" : "none";
+ }
+ } else {
+ obj.element.style.visibility = "hidden";
+ }
+ }
+ }
+ });
+ },
+ /**
+ * @api {方法} onShowLocalSite(0) 局部显示放大
+ * @apiGroup 地图显示
+ * @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);
+ *
+ */
+ onShowLocalSite: function (centerPoint, juZ = true) {
+ if (Map_QM.util.initModelArr.length > 0 && Map_QM.util.changeDist.inner > Map_QM.util.options.minDis) {
+ Map_QM.controls.maxDistance = Map_QM.util.changeDist.inner;
+ }
+ Map_QM.mapToPoint(centerPoint.x, centerPoint.y, 0);
+ if (!juZ) {
+ allJU = false;
+ }
+ isJUZ = juZ;
+ Map_QM.updateRender();
+ Map_QM.collLabel();
+ },
+ /**
+ * @api {方法} mapToPoint() 镜头聚焦特定点
+ * @apiGroup 地图显示
+ * @apiDescription 镜头聚焦特定点
+ * @apiVersion 4.0.0
+ * @apiParam {int} x x坐标
+ * @apiParam {int} y y坐标
+ * @apiParam {int} z z坐标
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample {Object} 请求示例
+ *
+ * Map_QM.mapToPoint(0,0,1);
+ *
+ */
+ mapToPoint: function (mapX, mapY, mapZ, iskill=true, onCompleteFun=null) {
+ let tag0 = Map_QM.controls.target.clone();
+ let pos0 = Map_QM.controls.object.position.clone();
+ let vct = new THREE.Vector3(mapX, -1 * mapY, mapZ);
+ vct.applyMatrix4(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].floorObj.matrix);
+ vct.applyMatrix4(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.matrix);
+ vct.applyMatrix4(Map_QM.buildObj.matrix);
+ vct.applyMatrix4(Map_QM.sceneGap.matrix);
+
+ let oldObj = {x:tag0.x, y:tag0.y, z:tag0.z, cx:pos0.x, cy:pos0.y, cz: pos0.z};
+ if(iskill){
+ TweenMax.killAll(true);
+ TweenMax.to(oldObj, 0.5, {
+ x: vct.x,
+ y: vct.y,
+ z: vct.z,
+ cx: pos0.x + (vct.x - tag0.x),
+ cy: pos0.y + (vct.y - tag0.y),
+ cz: pos0.z + (vct.z - tag0.z),
+ ease: Quad.easeOut,
+ onUpdate: function () {
+ let vt = new THREE.Vector3(oldObj.x, oldObj.y, oldObj.z);
+ Map_QM.controls.target = vt;
+ Map_QM.controls.object.position.set(oldObj.cx, oldObj.cy, oldObj.cz);
+ Map_QM.controls.object.lookAt(vt);
+ Map_QM.controls.update();
+ },
+ onComplete:function(){
+ let vt = new THREE.Vector3(oldObj.x, oldObj.y, oldObj.z);
+ Map_QM.controls.target = vt;
+ Map_QM.controls.object.position.set(oldObj.cx, oldObj.cy, oldObj.cz);
+ Map_QM.controls.object.lookAt(vt);
+ Map_QM.controls.update();
+ onCompleteFun && onCompleteFun();
+ }
+ });
+ }else{ //立即执行
+ Map_QM.controls.target = vct;
+ Map_QM.controls.object.position.set(pos0.x + (vct.x - tag0.x), pos0.y + (vct.y - tag0.y), pos0.z + (vct.z - tag0.z));
+ Map_QM.controls.object.lookAt(vct);
+ Map_QM.controls.update();
+ }
+ return vct;
+ },
+ /**
+ * @api {方法} onShowDeviceSite() 地图方向复位
+ * @apiGroup 地图显示
+ * @apiDescription 地图方向复位
+ * @apiVersion 4.0.0
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ *
+ * Map_QM.onShowDeviceSite();
+ *
+ */
+ onShowDeviceSite: function () {
+ this.changeBuild(this.util.deviceObj.build,this.util.deviceObj.floor);
+ },
+ /**
+ * 在2D 状态下平移镜头
+ */
+ moveCameraBy2D: function (obj) {
+ if (pathCameraState == "2D" && Map_QM.camera == Map_QM.cameraOrtho) {
+ Map_QM.controls.minAzimuthAngle = (Map_QM.util.deviceObj.angle * Math.PI) / -180;
+ Map_QM.controls.maxAzimuthAngle = (Map_QM.util.deviceObj.angle * Math.PI) / -180;
+ Map_QM.mapToPoint(obj.x, obj.y, 0, false);
+ }
+ },
+ // 一个地方调用
+ tweenMoveCameraBy2D:function(obj){
+ if (pathCameraState == "2D" && Map_QM.camera == Map_QM.cameraOrtho) {
+ Map_QM.controls.minAzimuthAngle = (Map_QM.util.deviceObj.angle * Math.PI) / -180;
+ Map_QM.controls.maxAzimuthAngle = (Map_QM.util.deviceObj.angle * Math.PI) / -180;
+ Map_QM.mapToPoint(obj.x, obj.y, 0,true,()=>{
+ if (Map_QM.util.pathStateObj.isPathPlay && _selfFindPath) {
+ _selfFindPath.pathPlay.isPlay = true;
+ }
+ });
+ }else{
+ if (Map_QM.util.pathStateObj.isPathPlay && _selfFindPath) {
+ _selfFindPath.pathPlay.isPlay = true;
+ }
+ }
+ },
+
+ /**
+ * 方向复位
+ */
+ resetMeDir: function () {
+ this.changeMapState("3d");
+ this.controls.minAzimuthAngle = -Infinity;
+ this.controls.maxAzimuthAngle = Infinity;
+ this.shawLight.castShadow = this.util.options.shadow;
+ this.controls.reset();
+ this.util.options.deviceAng && this.rotationAngle(this.util.deviceObj.angle);
+ },
+ /**
+ * @api {方法} changePathDir(pathState) 切换导航方向
+ * @apiGroup 地图交互
+ * @apiDescription 切换导航方向
+ * @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) {
+ //导航状态
+ let initVis = false;
+ if (Map_QM.endModel && Map_QM.endIcon) {
+ initVis = pathCameraState == "2D" ? Map_QM.endIcon.visible : Map_QM.endModel.visible;
+ }
+ pathCameraState = pathState;
+ if (Map_QM.endModel && Map_QM.endIcon) {
+ Map_QM.endModel.visible = pathCameraState == "2D" ? false : initVis;
+ Map_QM.endIcon.visible = pathCameraState == "2D" ? initVis : false;
+ }
+ Map_QM.reSetGuide();
+ Map_QM.pathRePlay();
+ }
+ },
+ reSetGuide: function () {
+ if(Map_QM.guide){
+ if (pathCameraState == "2D") {
+ //2D导航
+ Map_QM.onShowMeDir();
+ Map_QM.guide.visible = false;
+ let pos = Map_QM.guide.position;
+ Map_QM.guide = Map_QM.man_2d;
+ Map_QM.guide.position.x = pos.x;
+ Map_QM.guide.position.y = pos.y;
+ Map_QM.guide.visible = true;
+ Map_QM.controls.enableRotate = false;
+ } else {
+ Map_QM.resetMeDir();
+ Map_QM.controls.enableRotate = true;
+ Map_QM.guide.visible = false;
+ let pos = Map_QM.guide.position;
+ Map_QM.guide = Map_QM.man_3d;
+ Map_QM.guide.position.x = pos.x;
+ Map_QM.guide.position.y = pos.y;
+ Map_QM.guide.visible = true;
+ }
+ }
+ },
+ /**
+ * @api {方法} queryObject3DByShopNum(ipName) 获取3D对象
+ * @apiGroup 地图交互
+ * @apiDescription 获取3D对象
+ * @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++) {
+ for (let i = 0; i < Map_QM.mapArr[b].length; i++) {
+ let shopArr = Map_QM.mapArr[b][i].shopObj.children;
+ for (let k = 0; k < shopArr.length; k++) {
+ if (shopArr[k].name == ipName) {
+ return shopArr[k];
+ }
+ }
+ }
+ }
+ return null;
+ },
+ /**
+ * @api {方法} parseSelectShop() 设置选中店铺弹跳
+ * @apiGroup 地图交互
+ * @apiDescription 设置选中店铺弹跳
+ * @apiVersion 4.0.0
+ *
+ * @apiParam {object3D} selObject 传入3D对象
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ *
+ * Map_QM.parseSelectShop(object);
+ *
+ */
+ parseSelectShop: function (selObject) {
+ if (selObject) {
+ Map_QM.selectShop = selObject;
+ if (Map_QM.util.options.inArea && iconState == "3d") {
+ Map_QM.onShowLocalSite(new Map_QM.util.Point(Map_QM.selectShop.xaxis, Map_QM.selectShop.yaxis));
+ }
+ TweenMax.to(Map_QM.selectShop.scale, 0.5, {
+ z: 3, repeat: 4, yoyo: true, ease: Cubic.easeIn,
+ onComplete: function () {
+ Map_QM.selectShop && TweenMax.to(Map_QM.selectShop.scale, 0.5, { z: 1 });
+ },
+ });
+ }
+ },
+ /**
+ * @api {方法} cancelSelectShop() 取消店铺弹跳
+ * @apiGroup 地图交互
+ * @apiDescription 取消店铺弹跳效果
+ * @apiVersion 4.0.0
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ *
+ * Map_QM.cancelSelectShop();
+ *
+ */
+ cancelSelectShop: function () {
+ TweenMax.killAll(true);
+ if (Map_QM.selectShop) {
+ Map_QM.selectShop.scale.z = 1;
+ }
+ },
+ /**
+ * @api {方法} changeStateShopPro(isShow) 店铺促销标签
+ * @apiGroup 地图交互
+ * @apiDescription 店铺促销标签展示/隐藏
+ * @apiVersion 4.0.0
+ *
+ * @apiParam {boolean} isShow 店铺促销标签是否显示(默认 false)
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample {boolean} 请求示例
+ *
+ * Map_QM.changeStateShopPro(true);
+ *
+ */
+ changeStateShopPro: function (isShow = false) {
+ if (Map_QM.mapArr[Map_QM.util.selectBuild]) {
+ Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].tagObj.traverse((obj) => {
+ obj.element && (obj.element.style.display = isShow ? "block" : "none");
+ });
+ }
+ },
+ /**
+ * @api {方法} changeShowTagObjState(isShow) 自定义标签
+ * @apiGroup 地图交互
+ * @apiDescription 自定义标签展示/隐藏
+ * @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) => {
+ obj.visible = isShow;
+ });
+ },
+
+ /**
+ * @api {方法} queryShopList() 获取店铺列表信息
+ * @apiGroup 地图数据
+ * @apiDescription 店铺列表
+ * @apiVersion 4.0.0
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ *
+ * Map_QM.queryShopList()
+ *
+ */
+ queryShopList: function () {
+ return JSON.parse(JSON.stringify(Map_QM.util.shopData));
+ },
+ /**
+ * @api {方法} drawCurveLine(startShop,endShop,color) 绘制引导线
+ * @apiGroup 地图交互
+ * @apiDescription 绘制引导线
+ * @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","#66ffff")
+ *
+ */
+ drawCurveLine: function (startShop, endShop, color = "#3969f7") {
+ let sp, ep, cp1, cp2;
+ hasLine = true;
+ if (Array.isArray(startShop) && Array.isArray(endShop)) {
+ return { msg: "只能有一个数组" };
+ }
+ if (Array.isArray(startShop)) {
+ //如果是数组
+ endShop = Map_QM.shopNumToNavPoint({ houseNumber: endShop }, "shop");
+ for (let i = 0; i < startShop.length; i++) {
+ startShop[i] = Map_QM.shopNumToNavPoint({houseNumber: startShop[i] }, "shop");
+ sp = new THREE.Vector3(startShop[i].xaxis, -1 * startShop[i].yaxis, Map_QM.util.shopHeight);
+ ep = new THREE.Vector3(endShop.xaxis, -1 * endShop.yaxis, Map_QM.util.shopHeight);
+ 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.drawToLine(sp, ep, s/10, color, cp1, cp2));
+ }
+ } else {
+ startShop = Map_QM.shopNumToNavPoint({ houseNumber: startShop }, "shop");
+ if (Array.isArray(endShop)) {
+ //如果是数组
+ for (let i = 0; i < endShop.length; i++) {
+ endShop[i] = Map_QM.shopNumToNavPoint({ houseNumber: endShop[i] }, "shop");
+ 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.drawToLine(sp, ep, s/10, color, cp1, cp2));
+ }
+ } else {
+ endShop = Map_QM.shopNumToNavPoint({ houseNumber: endShop }, "shop");
+ sp = new THREE.Vector3(startShop.xaxis,-1 * startShop.yaxis, Map_QM.util.shopHeight);
+ ep = new THREE.Vector3( endShop.xaxis, -1 * endShop.yaxis, Map_QM.util.shopHeight);
+ 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.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 colorChange = [];
+ for (let i = 1; i < 7; i += 2) {
+ colorChange.push(parseInt("0x" + color.slice(i, i+2))/255);
+ }
+ let flyLine = createFlyCurve(points, new THREE.Vector3(colorChange[0], colorChange[1], colorChange[2]), false);
+ flyLine.userData.type = "toLine";
+ return flyLine;
+ },
+ /**
+ * @api {方法} drawColumnar(source,property) 绘制柱状图
+ * @apiGroup 地图交互
+ * @apiDescription 绘制柱状图
+ * @apiVersion 4.0.0
+ *
+ * @apiParam source 起始店铺编号或编号数组
+ * @apiParam property 控制参数对象
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ * //绘制多个
+ * Map_QM.drawColumnar(["L117","L127","L130"],{"height":200,"width":20,"color":"#2246d8"})
+ * //绘制单个
+ * Map_QM.drawColumnar("L125",{"height":200,"width":20,"color":"#2246d8"})
+ */
+ drawColumnar: function (source, property) {
+ if (Array.isArray(source)) {
+ if (source.length == 0) {
+ return { msg: "不能解析空数组" };
+ }
+ for (let i = 0; i < source.length; i++) {
+ Map_QM.drawOnlyColumer(source[i], property);
+ }
+ } else {
+ Map_QM.drawOnlyColumer(source, property);
+ }
+ },
+ drawOnlyColumer: function (houseNumber, property) {
+ if (houseNumber.trim() != "" && property) {
+ let endShop = Map_QM.shopNumToNavPoint({ houseNumber: houseNumber }, "shop");
+ let geometry = new THREE.BoxGeometry(property.width * 2, property.width * 2, property.width * 2);
+ let c = new THREE.Color(property.color);
+ let material;
+ let color2 = new THREE.Color(property.color);
+ for (let k = 0; k < Map_QM.util.meshMaterialArr.length; k++) {
+ if (Map_QM.util.meshMaterialArr[k].color && Map_QM.util.meshMaterialArr[k].color.equals(color2) && Map_QM.util.meshMaterialArr[k].isShaderMaterial) {
+ material = Map_QM.util.meshMaterialArr[k];
+ }
+ }
+ if (!material) {
+ material = new THREE.ShaderMaterial({
+ uniforms: {
+ targetColor: { value: new THREE.Vector3(c.r, c.g, c.b) },
+ height: { value: property.height / 5 },
+ },
+ transparent: true,
+ //depthTest:false,
+ vertexShader: [
+ "varying vec3 modelPos;",
+ "void main() {",
+ " modelPos = position;",
+ " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
+ "}",
+ ].join("\n"),
+ fragmentShader: [
+ "uniform vec3 targetColor;",
+ "uniform float height;",
+ "varying vec3 modelPos;",
+ "void main() {",
+ " gl_FragColor = vec4(targetColor.xyz,(0.9 - modelPos.y/height)*(0.9 - modelPos.y/height));",
+ "}",
+ ].join("\n"),
+ });
+ Map_QM.util.meshMaterialArr.push(material);
+ }
+
+ let mesh = new THREE.Mesh(geometry, material);
+ mesh.position.set(endShop.xaxis, -1 * endShop.yaxis, property.height);
+ mesh.rotation.x = Math.PI / -2;
+ mesh.scale.setY(property.height / property.width);
+ let cubeEdges = new THREE.EdgesGeometry(geometry, 60);
+ mesh.add(new THREE.LineSegments(cubeEdges, material));
+ mesh.userData.type = "columer";
+ Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].lineObj.add(mesh);
+ }
+ },
+
+ /**
+ * @api {方法} removeDrawEle(type) 删除绘制元素
+ * @apiGroup 地图交互
+ * @apiDescription 删除绘制元素
+ * @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;
+ for (let j = lineObj.children.length - 1; j >= 0; j--) {
+ if (type == "all" || lineObj.children[j].userData.type == type) {
+ lineObj.remove(lineObj.children[j]);
+ }
+ }
+ }
+ }
+ },
+
+ setHeatMapData: function () {
+ let points = [];
+ let max = 0;
+ let childRen = Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].shopObj.children;
+ for (let i = 0; i < childRen.length; i++) {
+ let val = Math.random() * 100;
+ max = Math.max(max, val);
+ var point = {
+ x: parseInt(childRen[i].xaxis),
+ y: parseInt(childRen[i].yaxis),
+ value: val,
+ };
+ points.push(point);
+ }
+ // 准备 heatmap 的数据
+ const data = {max: max, data: points};
+ Map_QM.heatMap(data);
+ Map_QM.hideInnerFloorElement();
+ },
+ /**
+ * @api {方法} heatMap(data) 热力图
+ * @apiGroup 地图交互
+ * @apiDescription 绘制热力图
+ * @apiVersion 4.0.0
+ *
+ * @apiParam {object} data 热力图的绘制数据
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ *
+ * Map_QM.heatMap({max: 100, data: [{x:0,y:0,value:50},...]})
+ */
+ heatMap: function (data) {
+ let heatMap = document.getElementById("heatmap");
+ Map_QM.removeHeatMap();
+ heatMap.style.pointerEvents = "none";
+ let mapW = Map_QM.util.allMap[Map_QM.util.selectBuild].mapW || 5000;
+ let mapH = Map_QM.util.allMap[Map_QM.util.selectBuild].mapH || 5000;
+ heatMap.style.width = mapW + "px";
+ heatMap.style.height = mapH + "px";
+ if (!heatmapInstance) {
+ heatmapInstance = h337.create({
+ container: heatMap,
+ gradient: {
+ 1.0: "#f00",
+ 0.9: "#e2fa00",
+ 0.6: "#33f900",
+ 0.3: "#0349df",
+ 0.0: "#0f00ff",
+ },
+ radius: 120,
+ maxOpacity: 1,
+ minOpacity: 0,
+ });
+ }
+ if (data.data && data.data.length > 0) {
+ data.data.map((item) => {
+ item.x += mapW / 2;
+ item.y += mapH / 2;
+ });
+ }
+ heatmapInstance.setData(data);
+ // 获取 heatmap
+ let texture = new THREE.Texture(heatmapInstance._renderer.canvas);
+ const material = new THREE.MeshLambertMaterial({
+ map: texture,
+ transparent: true,
+ opacity: 1,
+ });
+
+ let mesh = new THREE.Mesh(new THREE.PlaneGeometry(mapW, mapH, 10),material);
+ Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].otherObj.add(mesh);
+ mesh.renderOrder = 800;
+ mesh.position.set(0, 0, 60);
+ // 更新图片
+ texture && (texture.needsUpdate = true);
+ },
+ /**
+ * @api {方法} removeHeatMap() 清除外加图层
+ * @apiGroup 地图交互
+ * @apiDescription 清除外加图层
+ * @apiVersion 4.0.0
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ *
+ * Map_QM.removeHeatMap()
+ */
+ removeHeatMap: function () {
+ for (let i = 0; i < Map_QM.mapArr.length; i++) {
+ for (let j = 0; j < Map_QM.mapArr[i].length; j++) {
+ Map_QM.remove_child(Map_QM.mapArr[i][j].otherObj);
+ }
+ }
+ },
+
+ /**
+ * @api {方法} rotationAngle(angle) 改变水平角度
+ * @apiGroup 地图显示
+ * @apiDescription 改变地图水平角度 angle>-180 && angle<180 逆时针旋转
+ * @apiVersion 4.0.0
+ *
+ * @apiParam {int} angle 旋转角度
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample {int} 请求示例
+ *
+ * Map_QM.rotationAngle(90);
+ *
+ */
+ rotationAngle: function (angle) {
+ Map_QM.controls.setRotateHorizontal(Map_QM.controls.getRotateHorizontal());
+ Map_QM.controls.setRotateHorizontal((angle / 180) * Math.PI);
+ },
+ /**
+ * @api {方法} rotateAngle(angle) 改变垂直角度
+ * @apiGroup 地图显示
+ * @apiDescription 改变地图垂直角度 angle>-90 && angle<90
+ * @apiVersion 4.0.0
+ *
+ * @apiParam {int} angle 旋转角度
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample {int} 请求示例
+ *
+ * Map_QM.rotateAngle(-45);
+ *
+ */
+ rotateAngle: function (angle) {
+ let r0 = Map_QM.controls.getRotate();
+ Map_QM.controls.rotate(r0);
+ Map_QM.controls.rotate((angle / -180) * Math.PI);
+ },
+ /**
+ * @api {方法} setCameraDist(cDist) 调整地图大小
+ * @apiGroup 地图显示
+ * @apiDescription 调整地图大小(值越小地图越大) Map_QM.util.options.minDis ~ Map_QM.util.options.maxDis
+ * @apiVersion 4.0.0
+ *
+ * @apiParam {int} cDist 摄像头距离
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample {int} 请求示例
+ *
+ * Map_QM.setCameraDist(150);
+ *
+ */
+ setCameraDist: function (cDist, updateFun, callBack) {
+ cDist = Map_QM.util.options.minDis > parseInt(cDist) ? Map_QM.util.options.minDis : parseInt(cDist);
+ cDist = parseInt(cDist) > Map_QM.util.options.maxDis ? Map_QM.util.options.minDis : parseInt(cDist);
+ let oldObj = { dis: Map_QM.controls.getDistance() };
+ TweenMax.killAll(true);
+ TweenMax.to(oldObj, 0.5, {
+ dis: cDist,
+ onUpdate: function () {
+ updateFun && updateFun();
+ Map_QM.controls.setDistance(oldObj.dis);
+ Map_QM.controlsChock();
+ },
+ onComplete:function(){
+ updateFun && updateFun();
+ callBack && callBack();
+ Map_QM.collLabel();
+ }
+ });
+ },
+ //设置相机缩放
+ setCameraZoom: function (cZoom, updateFun, callBack) {
+ cZoom = cZoom < 0 ? 1 : cZoom;
+ let oldObj = { zoom: Map_QM.controls.object.zoom};
+ TweenMax.killAll(true);
+ TweenMax.to(oldObj, 0.5, {
+ zoom: cZoom,
+ onUpdate: function () {
+ updateFun && updateFun();
+ Map_QM.controls.setZoom(oldObj.zoom);
+ Map_QM.controlsChock();
+ },
+ onComplete:function(){
+ updateFun && updateFun();
+ callBack && callBack();
+ Map_QM.collLabel();
+ }
+ });
+ },
+ /**
+ * @api {方法} startRender() 启动地图渲染
+ * @apiGroup 地图显示
+ * @apiDescription 启动地图渲染 与 cancelRender 配合使用可节约资源
+ * @apiVersion 4.0.0
+ *
+ * @apiSampleRequest off
+ * @apiParamExample 请求示例
+ *
+ * Map_QM.startRender();
+ *
+ */
+ startRender: function () {
+ Map_QM.cancelRender();
+ let T = Map_QM.util._clock.getDelta();
+ Map_QM.controls.update();
+ Map_QM.renderer.render(Map_QM.scene, Map_QM.camera);
+ Map_QM.labelRenderer.render(Map_QM.scene, Map_QM.camera);
+ if (renderCount < 3) {
+ if (Map_QM.mapArr[Map_QM.util.selectBuild] && Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor]) {
+ Map_QM.labelRenderer.renderObject(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].CSSObj, Map_QM.scene, Map_QM.camera);
+ }
+ renderCount++;
+ }
+ Map_QM.CSSObject && Map_QM.labelRenderer.renderObject(Map_QM.CSSObject, Map_QM.scene, Map_QM.camera);
+ for (let item of Map_QM.mixers) {
+ item.update(T);
+ }
+ if (hasLine) {
+ const elapsed = Map_QM.util._clock.getElapsedTime();
+ uniforms.u_time.value = elapsed;
+ }
+ if (Map_QM.util.options.northShow) {
+ let a = Map_QM.controls.getRotateHorizontal();
+ if (Map_QM.outModelGap.visible) {
+ Map_QM.util.img.style.transform = "rotate(" +((Math.PI - (Map_QM.outModelGap.rotation.y - a)) * 180) / Math.PI +"deg)";
+ } else {
+ Map_QM.util.img.style.transform = "rotate(" + (a * 180) / Math.PI + "deg)";
+ }
+ }
+ renderFrame = requestAnimationFrame(Map_QM.startRender);
+ },
+ /**
+ * @api {方法} cancelRender() 取消地图渲染
+ * @apiGroup 地图显示
+ * @apiDescription 取消地图渲染 与 startRender 配合使用可节约资源
+ * @apiVersion 4.0.0
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ *
+ * Map_QM.cancelRender();
+ *
+ */
+ cancelRender: function () {
+ window.cancelAnimationFrame(renderFrame);
+ renderFrame = -1;
+ },
+
+ /**
+ * @api {方法} addElementLabel() 地图html标签
+ * @apiGroup 地图交互
+ * @apiDescription 地图显示Html标签,返回3d标签对象
+ * @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") {
+ let shopInfo;
+ Map_QM.CSSObject && Map_QM.CSSObject.traverse((obj) => {
+ if (obj.userData.type == type) {
+ shopInfo = obj;
+ }
+ });
+ if(!shopInfo){
+ divObj.style.opacity = 0;
+ 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].floorObj.matrix);
+ shopInfo.applyMatrix4(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.matrix);
+ shopInfo.userData.type = type;
+ shopInfo.userData.isShow = false;
+ shopInfo.userData.floor = parseInt(Map_QM.util.selectFloor);
+ Map_QM.CSSObject.add(shopInfo);
+ TweenMax.to(divObj.style, 0.2, { opacity: 1, delay: 0.1 });
+ }else{
+ Map_QM.updateElementPosition(shopInfo, x, y, z);
+ }
+ return shopInfo;
+ },
+
+ addDirectionLabel:function(angle){
+ if(Map_QM.qiModel){
+ let divObj = document.createElement("div");
+ divObj.style.position = "absolute";
+ divObj.style.zIndex = 499;
+ divObj.dataset.name = "出发方向";
+ divObj.dataset.nameEn = "Starting direction";
+ let div0 = document.createElement("div");
+ div0.className = "dir_map";
+ divObj.appendChild(div0);
+
+ let divImg = document.createElement("div");
+ divImg.className = "dir-divimg";
+ div0.appendChild(divImg);
+
+ let img = document.createElement("img");
+ img.src="./static/img/jt.png";
+ divImg.appendChild(img);
+
+ img.style.transform=`rotate(${angle}deg)`;
+ let txt = document.createElement("span");
+ txt.innerText = "出发方向";
+ div0.appendChild(txt);
+
+ let toDir = new THREE.CSS2DObject(divObj);
+ toDir.position.set(Map_QM.qiModel.position.x, Map_QM.qiModel.position.y, Map_QM.qiModel.position.z+80);
+ toDir.applyMatrix4(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].floorObj.matrix);
+ toDir.applyMatrix4(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.matrix);
+ toDir.userData.type = "dirLabel";
+ toDir.userData.isShow = false;
+ toDir.userData.floor = parseInt(Map_QM.util.selectFloor);
+ Map_QM.CSSObject.add(toDir);
+ }
+ },
+
+ /**
+ * @api {方法} updateElementPosition() 修改标签位置
+ * @apiGroup 地图交互
+ * @apiDescription 修改标签位置
+ * @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, z) {
+ if (obj.hasOwnProperty("position")) {
+ obj.position.set(x, -1 * y, z);
+ obj.applyMatrix4(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].floorObj.matrix);
+ obj.applyMatrix4(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.matrix);
+ }
+ },
+ /**
+ * @api {方法} elementDestroy(type) 销毁地图标签
+ * @apiGroup 地图交互
+ * @apiDescription 销毁地图上的html标签
+ * @apiVersion 4.0.0
+ * @apiParam {String} type docment元素自定义标识(默认 "shopInfo")
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample {Object} 请求示例
+ *
+ * Map_QM.elementDestroy();
+ *
+ */
+ elementDestroy: function (type = "shopInfo", isRemove = false) {
+ if (!Map_QM.CSSObject) {
+ return;
+ }
+ for (let i = Map_QM.CSSObject.children.length - 1; i >= 0; i--) {
+ if (Map_QM.CSSObject.children[i].userData.type != "moveFloor") {
+ if (type == "all") {
+ Map_QM.CSSObject.children[i].element && (Map_QM.CSSObject.children[i].element.style.visibility = "hidden");
+ } else {
+ if (
+ Map_QM.CSSObject.children[i].userData &&
+ Map_QM.CSSObject.children[i].userData.type == type
+ ) {
+ let node = Map_QM.CSSObject.children[i];
+ if(node.element){
+ node.element.style.visibility = "hidden";
+ if (isRemove && node.element.parentNode) {
+ node.element.parentNode.removeChild(node.element);
+ }
+ }
+ Map_QM.CSSObject.remove(node);
+ }
+ }
+ }
+ }
+ },
+ /**
+ * @api {方法} addElementByNode() 显示地图活动标签
+ * @apiGroup 地图交互
+ * @apiDescription 地图显示活动标签,返回3d标签对象
+ * @apiVersion 4.0.0
+ *
+ * @apiParam {Element} divObj div对象
+ * @apiParam {int} node 显示导航点位
+ * @apiParam {String} type docment元素自定义标识(默认 "tip")
+ * @apiSampleRequest off
+ *
+ * @apiParamExample {String} 请求示例
+ * Map_QM.addElementByNode(divObj,node,type);
+ */
+ addElementByNode: function (divObj, node, type = "tip") {
+ let pathData = Map_QM.util.allMap[Map_QM.util.selectBuild].buildArr[parseInt(Map_QM.util.selectFloor)].mapData.path;
+ if (!pathData || !divObj) {
+ return;
+ }
+ if (pathData.nodes.length > 0) {
+ pathData.nodes.sort(Map_QM.util.sortNode);
+ } else {
+ return;
+ }
+ divObj.style.visibility = "visible";
+ divObj.style.opacity = "0";
+ let shopInfo = new THREE.CSS2DObject(divObj);
+ shopInfo.position.set(pathData.nodes[parseInt(node)].x,-1 * pathData.nodes[parseInt(node)].y,60);
+ shopInfo.applyMatrix4(Map_QM.mapArr[Map_QM.util.selectBuild][parseInt(Map_QM.util.selectFloor)].floorObj.matrix);
+ shopInfo.applyMatrix4(Map_QM.mapArr[Map_QM.util.selectBuild][parseInt(Map_QM.util.selectFloor)].allObj.matrix);
+ shopInfo.userData.type = type;
+ shopInfo.userData.isShow = false;
+ shopInfo.userData.floor = parseInt(Map_QM.util.selectFloor);
+ Map_QM.CSSObject.add(shopInfo);
+ TweenMax.to(divObj.style, 0.2, { opacity: 1, delay: 0.2 });
+ return shopInfo;
+ },
+
+ /**
+ * @api {方法} changeShowShopName() 修改店铺显示名称
+ * @apiGroup 地图显示
+ * @apiDescription 通过店铺编号修改店铺显示名称
+ * @apiVersion 4.0.0
+ * @apiParam {Array} houseNumber 店铺编号
+ * @apiParam {Array} nameStr 字符串
+ * @apiSampleRequest off
+ *
+ * @apiParamExample {String} 请求示例
+ * Map_QM.changeShowShopName(["L104"],['
肯德基
'])
+ */
+ changeShowShopName: function (shopNums, elements) {
+ if (shopNums.length === elements.length) {
+ let labObj = Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].labelObj.children;
+ for (let i = 0; i < shopNums.length; i++) {
+ for (let j = 0; j < labObj.length; j++) {
+ if (labObj[j].name == shopNums[i] && labObj[j].element) {
+ labObj[j].element.innerHTML = elements[i];
+ break;
+ }
+ }
+ }
+ }
+ },
+
+ /**
+ * @api {方法} showAreaAnimate() 区域定位
+ * @apiGroup 地图显示
+ * @apiDescription 通过区域名称凸显区域
+ * @apiVersion 4.0.0
+ * @apiParam {String} aName 区域名称,不传则复位
+ * @apiSampleRequest off
+ *
+ * @apiParamExample {String} 请求示例
+ * Map_QM.showAreaAnimate("A");
+ */
+ showAreaAnimate: function (aName = "") {
+ //在我的方向状态,恢复
+ Map_QM.changeMapModel("3D");
+ Map_QM.resetFloorState();
+ Map_QM.controls.reset();
+ Map_QM.util.options.deviceAng && Map_QM.rotationAngle(Map_QM.util.deviceObj.angle);
+ TweenMax.killAll(true);
+ if (!aName) {
+ isJUZ = false;
+ allJU = true;
+ return;
+ }
+ Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].floorObj.traverse((obj) => {
+ if (obj.userData && obj.userData.type == "build") {
+ if (obj.name == aName) {
+ Map_QM.onShowLocalSite({ x: obj.userData.xaxis, y: obj.userData.yaxis }, false);
+ let dis = Map_QM.controls.getDistance()-100;
+ Map_QM.controls.setDistance(dis);
+ }
+ }
+ });
+ },
+
+ /**
+ * @api {方法} unionShop() 店铺合并
+ * @apiGroup 地图显示
+ * @apiDescription 通过店铺编号合并店铺 合铺
+ * @apiVersion 4.0.0
+ * @apiParam {Array} shops 店铺编号数组
+ * @apiParam {Object} data 新的店铺数据(默认 空数据)
+ * @apiSampleRequest off
+ *
+ * @apiParamExample {String} 请求示例
+ * Map_QM.unionShop(["L105","L106","L107","L108"],{name:"新店",houseNumber:"L104-L108",color:"#F4A460"})
+ */
+ unionShop: function (shops, data = { name: "", houseNumber: "shop", color: "#F4A460" }) {
+ let shopObj = [], xAll = 0, yAll = 0;
+ if (Array.isArray(shops) && shops.length > 1) {
+ //删除店铺box
+ let shopArea = Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].shopObj.children;
+ for (let i = 0; i < shops.length; i++) {
+ for (let k = 0; k < shopArea.length; k++) {
+ if (shopArea[k].name == shops[i]) {
+ xAll += shopArea[k].xaxis;
+ yAll += shopArea[k].yaxis;
+ shopObj.push(shopArea[k]);
+ Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].shopObj.remove(shopArea[k]);
+ break;
+ }
+ }
+ }
+ //删除文本标签
+ let labObj = Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].labelObj.children;
+ for (let i = 0; i < shops.length; i++) {
+ for (let j = 0; j < labObj.length; j++) {
+ if (labObj[j].name == shops[i]) {
+ if (labObj[j].element && labObj[j].element.parentNode) {
+ labObj[j].element.parentNode.removeChild(labObj[j].element);
+ }
+ Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].labelObj.remove(labObj[j]);
+ break;
+ }
+ }
+ }
+ let point = {
+ x: xAll / shopObj.length,
+ y: yAll / shopObj.length,
+ };
+ let baseShop;
+ for (let l = 0; l < shopObj.length; l++) {
+ if (l == 0) {
+ baseShop = new ThreeBSP(shopObj[0]);
+ } else {
+ baseShop = baseShop.union(new ThreeBSP(shopObj[l]));
+ }
+ }
+ //ThreeBSP对象转化为网格模型对象
+ let mesh = baseShop.toMesh();
+ mesh.userData = data;
+ mesh.userData.shopData = { formatColor: data.color };
+ mesh.userData.xaxis = point.x >> 0;
+ mesh.userData.yaxis = point.y >> 0;
+ mesh.userData.houseNumber = data.houseNumber;
+ mesh.userData.entColor = data.color;
+ mesh.userData.type = "shop";
+ if (data.name) {
+ mesh.name = data.name;
+ let shopDiv = document.createElement("div");
+ shopDiv.className = "map_label";
+ if (window.innerWidth > 2000) {
+ shopDiv.style.fontSize = "16px";
+ }
+ shopDiv.innerHTML = data.name;
+ shopDiv.dataset.name = data.name;
+ shopDiv.dataset.nameEn = data.nameEn || data.name;
+ let shopLabel = new THREE.CSS2DObject(shopDiv);
+ shopLabel.position.set(point.x >> 0, (-1 * point.y) >> 0, 30);
+ shopLabel.name = data.houseNumber || "";
+ shopLabel.userData.mapShow = true; //是否永久显示
+ shopLabel.userData.isShow = true;
+ Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].labelObj.add(shopLabel);
+ }
+ mesh.material = new THREE.MeshStandardMaterial({
+ color: data.color || 0xf4a460,
+ transparent: true,
+ opacity: 0.9,
+ side: THREE.DoubleSide,
+ depthTest: true,
+ emissive : 0x000000,
+ roughness:0.8
+ });
+ Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].floorObj.add(mesh);
+ }
+ renderCount = 0;
+ },
+
+ ////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * @param {Object} e
+ * 地图BOX点击
+ */
+ onMouseClickBox: function (event) {
+ Map_QM.controls.autoRotate = false;
+ let mouse = new THREE.Vector2();
+ mouse.x = (event.offsetX / Map_QM.w) * 2 - 1;
+ mouse.y = -(event.offsetY / Map_QM.h) * 2 + 1;
+ Map_QM.onCallTouchORMouse(mouse);
+ },
+ onCallTouchORMouse: function (mouse) {
+ if ((!Map_QM.mapArr[Map_QM.util.selectBuild] &&!Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor]) || !Map_QM.buildObj.visible || Map_QM.util.pathStateObj.isPathState) {
+ return;
+ }
+ let raycaster = new THREE.Raycaster();
+ raycaster.setFromCamera(mouse, Map_QM.camera);
+ let intersects = raycaster.intersectObjects(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].floorObj.children, true);
+ let clickShop = false,
+ clickOnly = false,
+ onlyData = null;
+ for (let i = 0; i < intersects.length; i++) {
+ //店铺BOX点击
+ if (intersects[i].object.userData && intersects[i].object.userData.type == "shop") {
+ if (intersects[i].object.name != "") {
+ if (Map_QM.endModel && Map_QM.endModel.visible) {
+ Map_QM.endModel.visible = false;
+ }
+ clickShop = true;
+ Map_QM.setSelectShopMat(intersects[i].object);
+ break;
+ } else {
+ //空店铺有编号
+ if (intersects[i].object.userData.houseNumber && intersects[i].object.userData.houseNumber != "shop") {
+ clickOnly = true;
+ onlyData = intersects[i].object.userData;
+ }
+ }
+ }
+ }
+
+ /**
+ * @api {事件} shop 点击已绑定品牌的店铺
+ * @apiGroup 地图事件
+ * @apiDescription 用户点击店铺后触发自定义事件
+ * @apiVersion 4.0.0
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ * Map_QM.addEventListener("shop",onClickShop,false);
+ */
+ if (clickShop && Map_QM.selectShop && Map_QM.selectShop.userData) {
+ if (Map_QM.selectShop.userData.shopData.hasOwnProperty("houseNumber")) {
+ Map_QM.dispatchEvent({
+ type: "shop",
+ data: Map_QM.selectShop.userData,
+ });
+ } else {
+ /**
+ * @api {事件} onlyShop 点击未绑定品牌的店铺
+ * @apiGroup 地图事件
+ * @apiDescription 用户点击空店铺后触发自定义事件
+ * @apiVersion 4.0.0
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ * Map_QM.addEventListener("onlyShop",onClickShop,false);
+ */
+ Map_QM.dispatchEvent({
+ type: "onlyShop",
+ data: Map_QM.selectShop.userData,
+ });
+ }
+ } else {
+ if (clickOnly) {
+ Map_QM.dispatchEvent({
+ type: "onlyShop",
+ data: onlyData,
+ });
+ } else {
+ Map_QM.dispatchEvent({
+ type: "shop",
+ data: null,
+ });
+ }
+ }
+ },
+ /**
+ * @api {方法} setSelectShopMatByName(houseNumber) 设置box 选中
+ * @apiGroup 地图交互
+ * @apiDescription 地图box 选中
+ * @apiVersion 4.0.0
+ * @apiParam {String} houseNumber 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++) {
+ let shopArr = Map_QM.mapArr[Map_QM.util.selectBuild][i].shopObj.children;
+ for (let k = 0; k < shopArr.length; k++) {
+ if (shopArr[k].name == ipName) {
+ Map_QM.setSelectShopMat(shopArr[k]);
+ return [shopArr[k].xaxis, shopArr[k].yaxis];
+ }
+ }
+ }
+ },
+ //改变选中店铺box
+ setSelectShopMat: function (selObject) {
+ TweenMax.killAll(true);
+ if (Map_QM.selectShop) {
+ Map_QM.selectShop.scale.z = 1;
+ }
+ Map_QM.parseSelectShop(selObject);
+ },
+ updateRender: function () {
+ Map_QM.controls.update();
+ Map_QM.renderer.render(Map_QM.scene, Map_QM.camera);
+ Map_QM.labelRenderer.render(Map_QM.scene, Map_QM.camera);
+ if(Map_QM.mapArr && Map_QM.mapArr[Map_QM.util.selectBuild] && Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor]){
+ Map_QM.labelRenderer.renderObject(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].CSSObj, Map_QM.scene,Map_QM.camera);
+ Map_QM.labelRenderer.zOrder(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].labelObj);
+ }
+ },
+ /**
+ * 初始化后调用
+ */
+ timeOutInit: function () {
+ Map_QM.updateRender();
+ Map_QM.collLabel();
+ renderCount = 0;
+ if (Map_QM.callBackLoadOver) {
+ let floorData = [];
+ for (let i = 0; i < Map_QM.util.allMap.length; i++) {
+ let build = [];
+ for (let j = 0; j < Map_QM.util.allMap[i].buildArr.length; j++) {
+ if (Map_QM.util.allMap[i].buildArr[j]) {
+ build.push({
+ order: Map_QM.util.allMap[i].buildArr[j].order,
+ name: Map_QM.util.allMap[i].buildArr[j].name,
+ });
+ }
+ }
+ floorData.push(build);
+ }
+ if (Map_QM.backObj) {
+ Map_QM.controls.enableRotate = true;
+ Map_QM.backObj.data = floorData;
+ }
+ Map_QM.callBackLoadOver(Map_QM.backObj); //初始化完成后回调
+ Map_QM.callBackLoadOver = null;
+ Map_QM.backObj = null;
+ }
+ Map_QM.dispatchEvent({
+ type: "changeFloorOver",
+ data: Map_QM.selectFloor,
+ });
+ },
+
+ autoChangeEleAngle: function () {
+ if (Map_QM.mapArr[Map_QM.util.selectBuild]) {
+ 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) {
+ let svgChilds = Map_QM.mapArr[Map_QM.util.selectBuild][m].svgObj.children;
+ let rat = Map_QM.controls.getRotateHorizontal();
+ svgChilds.forEach((item) => {
+ if (Math.abs(item.rotation.x) < 0.5) {
+ if (
+ rat - item.userData.rot > 1.7 ||
+ rat - item.userData.rot < -1.7
+ ) {
+ item.rotation.z =
+ item.userData.rot < 0
+ ? item.userData.rot + 3.1415926
+ : item.userData.rot - 3.1415926;
+ } else {
+ item.rotation.z = item.userData.rot;
+ }
+ }
+ });
+ let logoChilds = Map_QM.mapArr[Map_QM.util.selectBuild][m].shopObj.children;
+ logoChilds.forEach((item) => {
+ if (item.children.length > 0) {
+ item.children.forEach((obj) => {
+ if (obj.userData.type == "logo") {
+ if (
+ rat - obj.userData.rot > 1.7 ||
+ rat - obj.userData.rot < -1.7
+ ) {
+ obj.rotation.z =
+ obj.userData.rot < 0
+ ? obj.userData.rot + 3.1415926
+ : obj.userData.rot - 3.1415926;
+ } else {
+ obj.rotation.z = obj.userData.rot;
+ }
+ }
+ });
+ }
+ });
+ }
+ }
+ }
+ },
+ disPlayEvent: function (isChange=false) { //默认值false 则手动缩放不能切换状态
+ if(isChange){
+ let distance = Map_QM.controls.getDistance();
+ if (distance > Map_QM.util.changeDist.outner + 20 && mapState != "periphery") {
+ Map_QM.toPeripheryInner();
+ } else if (distance > Map_QM.util.changeDist.inner + 20 && distance < Map_QM.util.changeDist.outner - 20 && mapState != "out") {
+ Map_QM.toOutModelInner();
+ } else if (distance < Map_QM.util.changeDist.inner - 20 && mapState != "mall") {
+ Map_QM.toMallInner();
+ }
+ }
+ },
+ /**
+ * 碰撞检测
+ * @param {Object} 传入检测楼层下标
+ */
+ controlsChock: function () {
+ Map_QM.autoChangeEleAngle();
+ renderCount = 0;
+ /**
+ * @api {事件} MapAngleChange 地图的方向改变
+ * @apiGroup 地图事件
+ * @apiDescription 用户操作地图时触发
+ * @apiVersion 4.0.0
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ * Map_QM.addEventListener("MapAngleChange",onMapAngleChange,false);
+ */
+ Map_QM.dispatchEvent({
+ type: "MapAngleChange",
+ data: {
+ hAngle: Map_QM.controls.getRotateHorizontal(),
+ vAngle: Map_QM.controls.getRotate(),
+ },
+ });
+ if (Map_QM.util.options.inArea && isJUZ && allJU) {
+ clearTimeout(shopTime);
+ shopTime = setTimeout(() => {
+ clearTimeout(shopTime);
+ isJUZ = false;
+ Map_QM.controls.reset();
+ Map_QM.util.options.deviceAng && Map_QM.rotationAngle(Map_QM.util.deviceObj.angle);
+ }, 10000);
+ }
+ },
+
+ //内部碰撞检测
+ collLabel: function () {
+ if (!Map_QM || !isShowElement || !Map_QM.util.options.collision) {
+ return;
+ }
+ clearTimeout(allTime);
+ allTime = setTimeout(() => {
+ clearTimeout(allTime);
+ Map_QM.runTaskQueue();
+ }, 400);
+ },
+ //世界坐标转屏幕坐标
+ getlocaleToScreen:function(object,vect){
+ let standardVec;
+ if(vect){
+ standardVec = object.localToWorld(vect).project(Map_QM.camera);
+ }else{
+ standardVec = object.localToWorld(new THREE.Vector3()).project(Map_QM.camera);
+ }
+ const screenX = Math.round(Map_QM.w/2 * standardVec.x + Map_QM.w/2);
+ const screenY = Math.round(Map_QM.h/-2 * standardVec.y + Map_QM.h/2);
+ return {x:screenX, y:screenY};
+ },
+
+ runTaskQueue: function (){
+ if (Map_QM.mapArr[Map_QM.util.selectBuild] && Map_QM.buildObj.visible && Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor]) {
+ if (Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.visible && (!Map_QM.buildObj.userData.hasOwnProperty("visible") || Map_QM.buildObj.userData.visible)) {
+ let childs = Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].labelObj.children;
+ let len = childs.length;
+ for (let i = 0; i < len; i++) {
+ if (!childs[i].userData.isShow) {
+ //是否可见
+ continue;
+ }
+ if (!Map_QM.util.options.collision) {
+ childs[i].element.style.display = "block";
+ continue;
+ }
+ let obj = childs[i].element;
+ obj.style.display = "block";
+ let labP = obj.getBoundingClientRect();
+
+ for (let j=Math.max(i-10, 0); j < i; j++) {
+ if (childs[j].element.style.display == "block") {
+ let pb = childs[j].element.getBoundingClientRect();
+ let isCol = Map_QM.util.isCollision(labP, pb);
+ if (isCol) {
+ if (!childs[i].userData.mapShow) {
+ childs[i].element.style.display = "none";
+ break;
+ } else if (!childs[j].userData.mapShow) {
+ childs[j].element.style.display = "none";
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+
+ /**
+ * 寻路----------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /**
+ * @api {方法} countPath() 方向算法
+ * @apiGroup 地图导航
+ * @apiDescription 计算设施、店铺的导航方向, toObj,pathType 不能同时为空
+ * @apiVersion 4.0.0
+ * @apiParam {Object} toObj {build,floor,node} //终点 设施寻路可以为空
+ * @apiParam {String} pathType 公共设施名称或编号(点位寻路此参数为空字符串)
+ * @apiParam {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.basePath,startNade,toNade);
+ PathPoint = obj.nodes;
+ direction.cost = Math.ceil(obj.cost / 50);
+ direction.gap = Math.floor(obj.cost);
+ } catch (e) {
+ window.captureException && window.captureException(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();
+ }
+ }
+ 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 = 2; //downft
+ } else {
+ facType = 5;
+ }
+ } else {
+ if (Math.abs(parseInt(this.forShopArr[0].floor) - parseInt(this.forShopArr[1].floor)) < 3 ) {
+ //扶梯
+ facType = 1; //upft
+ } else {
+ facType = 5; //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;
+ }
+ }
+ //斜方向忽略
+ 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 {方法} bounceIcon("xsj") 图标弹跳
+ * @apiGroup 地图导航
+ * @apiDescription 地图图标弹跳效果
+ * @apiVersion 4.0.0
+ * @apiParam {String} iconType 设施缩写
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample {String} 请求示例
+ *
+ * Map_QM.bounceIcon("xsj");
+ *
+ */
+ bounceIcon: function (iconType) {
+ TweenMax.killAll(true);
+ let facs = Map_QM.mapArr[Map_QM.util.selectBuild][parseInt(Map_QM.util.selectFloor)].serObj.children; //交通图标
+ for (let i = 0; i < facs.length; i++) {
+ if (facs[i].type == "Object3D") {
+ if (facs[i].userData.facCode == iconType) {
+ facs[i].element.style.zIndex = 200;
+ let oldZ = facs[i].userData.site + 5;
+ TweenMax.fromTo(
+ facs[i].position,
+ 0.5,
+ { z: oldZ },
+ {
+ z: oldZ + 80,
+ repeat: 1,
+ onUpdate: function () {
+ Map_QM.labelRenderer.renderObject(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].CSSObj, Map_QM.scene,Map_QM.camera);
+ },
+ onComplete: function () {
+ TweenMax.to(facs[i].position, 0.2, {
+ z: oldZ,
+ onUpdate: function () {
+ Map_QM.labelRenderer.renderObject(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].CSSObj, Map_QM.scene, Map_QM.camera);
+ },
+ });
+ },
+ }
+ );
+ } else {
+ facs[i].element.style.zIndex = 100;
+ }
+ }
+ }
+ },
+
+//获取目标物角度和距离 deviceObj
+getObjectAngle:function(objArr){
+ if(parseInt(Map_QM.util.startObj.node) || parseInt(Map_QM.util.startObj.node) == 0){
+ let pathData =Map_QM.util.allMap[parseInt(Map_QM.util.startObj.build)].buildArr[parseInt(Map_QM.util.startObj.floor)].mapData.path;
+ pathData.nodes.sort(Map_QM.util.sortNode);
+ Map_QM.util.startObj.xaxis = pathData.nodes[parseInt(Map_QM.util.startObj.node)].x;
+ Map_QM.util.startObj.yaxis = pathData.nodes[parseInt(Map_QM.util.startObj.node)].y;
+
+ let startNade = Map_QM.util.startObj.build +"_" +Map_QM.util.startObj.floor +"_" +Map_QM.util.startObj.node;
+ const costAll = dijkstra.single_source_shortest_paths( Map_QM.util.pathStateObj.basePath,startNade,startNade).costs;
+ for(let i=0;i0) {
+ for (let i = 0;i < this.mapArr[parseInt(this.util.startObj.build)].length;i++) {
+ for (let len =this.mapArr[parseInt(this.util.startObj.build)][i].floorObj.children.length - 1;len >= 0;len--) {
+ let obj =this.mapArr[parseInt(this.util.startObj.build)][i].floorObj.children[len];
+ if (obj.userData.type == "start") {
+ this.mapArr[parseInt(this.util.startObj.build)][i].floorObj.remove(obj);
+ }
+ }
+ }
+ }else{
+ return;
+ }
+ this.util.startObj = {};
+ if (toObj && toObj.node) {
+ let pathData =this.util.allMap[parseInt(toObj.build)].buildArr[parseInt(toObj.floor)].mapData.path;
+ pathData.nodes.sort(this.util.sortNode);
+ this.util.startObj.xaxis = pathData.nodes[parseInt(toObj.node)].x;
+ this.util.startObj.yaxis = pathData.nodes[parseInt(toObj.node)].y;
+ this.util.startObj.build = parseInt(toObj.build);
+ this.util.startObj.floor = parseInt(toObj.floor);
+ this.util.startObj.node = toObj.node;
+ this.util.startObj.angle = toObj.angle || 0;
+ } else {
+ this.util.startObj.xaxis = this.util.deviceObj.xaxis;
+ this.util.startObj.yaxis = this.util.deviceObj.yaxis;
+ this.util.startObj.build = parseInt(this.util.deviceObj.build);
+ this.util.startObj.floor = parseInt(this.util.deviceObj.floor);
+ this.util.startObj.node = this.util.deviceObj.node;
+ this.util.startObj.angle = this.util.deviceObj.angle;
+ this.util.startObj.xaxis = this.util.deviceObj.xaxis;
+ this.util.startObj.yaxis = this.util.deviceObj.yaxis;
+ }
+ this.mapArr[parseInt(this.util.startObj.build)][parseInt(this.util.startObj.floor)].setStartSite(
+ this.util.startObj.xaxis,
+ this.util.startObj.yaxis,
+ parseInt(this.util.shopHeight) + 20
+ );
+ },
+
+ /**
+ * @api {方法} changeMapIPState(ipName,color) 改变POI颜色
+ * @apiGroup 地图交互
+ * @apiDescription 改变POI 颜色
+ * @apiVersion 4.0.0
+ * @apiParam {string} ipName POI名称
+ * @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++) {
+ let shopArr = this.mapArr[this.util.selectBuild][i].shopObj.children;
+ for (let k = 0; k < shopArr.length; k++) {
+ if (shopArr[k].name == ipName ||(shopArr[k].userData && shopArr[k].userData.houseNumber == ipName)) {
+ shopArr[k].userData.initMaterial = shopArr[k].material;
+ shopArr[k].material = this.util.getMeshMaterial(color || 0xeab16e);
+ break;
+ }
+ }
+ }
+ },
+ /**
+ * @api {方法} resetMapIPState(ipName) 恢复POI颜色
+ * @apiGroup 地图交互
+ * @apiDescription 恢复POI初始颜色
+ * @apiVersion 4.0.0
+ * @apiParam {string} ipName POI名称
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ *
+ * Map_QM.resetMapIPState("L101");
+ *
+ */
+ resetMapIPState: function (ipName) {
+ for (let i = 0; i < this.mapArr[this.util.selectBuild].length; i++) {
+ let shopArr = this.mapArr[this.util.selectBuild][i].shopObj.children;
+ for (let k = 0; k < shopArr.length; k++) {
+ if (shopArr[k].name == ipName) {
+ shopArr[k].material = shopArr[k].userData.initMaterial;
+ break;
+ }
+ }
+ }
+ },
+
+ /**
+ * @api {方法} getMapIPData(ipName) 获取POI 基础数据
+ * @apiGroup 地图交互
+ * @apiDescription 获取POI 基础数据
+ * @apiVersion 4.0.0
+ * @apiParam {string} ipName POI名称
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ *
+ * Map_QM.getMapIPData("L1001");
+ *
+ * @apiSuccessExample 返回示例
+ * {
+ * houseNumber:店铺编号, shopName:店铺名 node:导航点, floor:楼层编号, xaxis:中心点X坐标, yaxis:中心点Y坐标, borderColor:边框色, entColor:填充色
+ * }
+ */
+ getMapIPData: function (ipName) {
+ for (let i = 0; i < Map_QM.mapArr[Map_QM.util.selectBuild].length; i++) {
+ let shopArr = Map_QM.mapArr[Map_QM.util.selectBuild][i].shopObj.children;
+ for (let k = 0; k < shopArr.length; k++) {
+ if (shopArr[k].name == ipName ||(shopArr[k].userData && shopArr[k].userData.houseNumber == ipName)) {
+ return shopArr[k].userData;
+ }
+ }
+ }
+ },
+
+ /**
+ * @api {方法} pathNode() 地图模拟导航
+ * @apiGroup 地图导航
+ * @apiDescription 地图路径模拟导航
+ * @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) {
+ Map_QM.util.isMorePath = false;
+ Map_QM.cost=-1;
+ if (!toObj) {
+ return { direction: "", wayList: [] };
+ }
+ pathCameraState = Map_QM.util.options.pathStyle;
+ Map_QM.onShowDeviceSite();
+ Map_QM.selectShop = null;
+ Map_QM.util.pathStateObj.isPathState = true;
+ Map_QM.elementDestroy("all");
+ Map_QM.guide = pathCameraState == "2D" ? Map_QM.man_2d : Map_QM.man_3d;
+ Map_QM.reSetGuide();
+ if (Map_QM.util.initModelArr && Map_QM.util.initModelArr.length > 0 && Map_QM.util.changeDist.inner > Map_QM.util.options.minDis) {
+ Map_QM.controls.maxDistance = Map_QM.util.changeDist.inner;
+ }
+ if (!Map_QM.util.startObj.xaxis && !Map_QM.util.startObj.yaxis) {
+ Map_QM.changeStartPoint(null);
+ }
+ Map_QM.util.overObj = null;
+ Map_QM.util.overObj = {
+ build: toObj.build || 0,
+ floor: toObj.floor,
+ node: toObj.node,
+ houseNumber: toObj.houseNumber,
+ comeIn: toObj.comeIn || "",
+ };
+ if (Map_QM.util.overObj.node != "") {
+ Map_QM.cancelRender();
+ this.onFindPathModel();
+ if (callBackFun) {
+ Map_QM.parseForShopArr();
+ const data = JSON.parse(JSON.stringify(Map_QM.util.pathStateObj.forShopArr));
+ callBackFun(data);
+ }
+ Map_QM.startRender();
+ }
+ },
+
+ /**
+ * @api {方法} pathShopList() 指定路径导航
+ * @apiGroup 地图导航
+ * @apiDescription 根据传入的店铺编号列表绘制导航路径
+ * @apiVersion 4.0.0
+ * @apiParam {Array} shopList 路径的店铺编号数组
+ * @apiParam {Function} callBackFun 回调函数
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ *
+ * Map_QM.pathShopList(["L1-1","L1-5","L1-8","L1-10","LA-13"],()=>{});
+ *
+ */
+ pathShopList: function (shopList, callBackFun) {
+ if (!shopList || shopList.length < 2) {
+ return { direction: "", wayList: [] };
+ }
+ let pathList = shopList.map(Map_QM.getPathNodeByHousenumber);
+ Map_QM.pathList(pathList, callBackFun);
+ },
+ /**
+ * 获取导航点
+ */
+ getPathNodeByHousenumber: function (houseNumber) {
+ for (let h = 0; h < Map_QM.mapArr.length; h++) {
+ for (let i = 0; i < Map_QM.mapArr[h].length; i++) {
+ let shopArr = Map_QM.mapArr[h][i].shopObj.children;
+ for (let k = 0; k < shopArr.length; k++) {
+ if (shopArr[k].name == houseNumber && parseInt(shopArr[k].node) >= 0) {
+ return {build: h, floor: i, path: h + "_" + i + "_" + shopArr[k].node, node: shopArr[k].node};
+ }
+ }
+ }
+ }
+ },
+ getPathNodeByNode: function (nodeObj) {
+ let build = nodeObj.buildOrder || 0;
+ let floor = nodeObj.floorOrder || 0;
+ let node = parseInt(nodeObj.node);
+ if (isNaN(node)) {
+ return null;
+ } else {
+ return {build: build, floor: floor, path: build + "_" + floor + "_" + node, node: node};
+ }
+ },
+ /**
+ * @api {方法} pathShopList() 指定路径导航
+ * @apiGroup 地图导航
+ * @apiDescription 根据传入的店铺编号列表绘制导航路径
+ * @apiVersion 4.0.0
+ * @apiParam {Array} shopList 路径的店铺编号数组
+ * @apiParam {Function} callBackFun 回调函数
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ * [{buildOrder:0,floorOrder:0,node:8},{buildOrder:0,floorOrder:0,node:13},{buildOrder:0,floorOrder:0,node:16},{buildOrder:0,floorOrder:0,node:20}],()=>{}
+ */
+ pathNodeList: function (nodeList, callBackFun, isShowNo = true) {
+ Map_QM.elementDestroy("map_no", true);
+ if (!nodeList || nodeList.length < 2) {
+ return { direction: "", wayList: [] };
+ }
+ Map_QM.selectShop = null;
+ Map_QM.util.pathStateObj.isPathState = true;
+ let pathList = nodeList.map(Map_QM.getPathNodeByNode);
+ Map_QM.pathList(pathList, callBackFun, isShowNo);
+ },
+ pathList: function (pathList, callBackFun, isShowNo = false) {
+ Map_QM.util.isMorePath = true;
+ Map_QM.clearFloor(Map_QM.util.selectFloor || -1);
+ pathCameraState = Map_QM.util.options.pathStyle;
+ Map_QM.selectShop = null;
+ Map_QM.util.pathStateObj.isPathState = true;
+ Map_QM.cancelRender();
+ let startNode,
+ endNode,
+ isFrist = true,
+ PathPoint = [];
+ try {
+ let index = 0,
+ findIndex = 0,
+ pathNodes = [];
+ pathList.forEach((item, inx) => {
+ if (isShowNo) {
+ //显示序号
+ let pathN =Map_QM.util.allMap[parseInt(item.build)].buildArr[parseInt(item.floor)].mapData.path.nodes;
+ pathN.sort(Map_QM.util.sortNode);
+ let labelDiv = document.createElement("div");
+ labelDiv.className = "map_no";
+ labelDiv.innerText = inx + 1;
+ let img = document.createElement("img");
+ img.src = "../static/img/arrowBlack.svg";
+ labelDiv.appendChild(img);
+ let shopLabel = new THREE.CSS2DObject(labelDiv);
+ shopLabel.position.set(pathN[parseInt(item.node)].x,-1 * pathN[parseInt(item.node)].y,30);
+ shopLabel.applyMatrix4(Map_QM.mapArr[parseInt(item.build)][parseInt(item.floor)].floorObj.matrix);
+ shopLabel.applyMatrix4(Map_QM.mapArr[parseInt(item.build)][parseInt(item.floor)].allObj.matrix);
+ shopLabel.userData.type = "map_no";
+ shopLabel.userData.index = inx;
+ shopLabel.userData.mapShow = true;
+ shopLabel.userData.isShow = false; //切换楼层默认不显示,且不参与碰撞检测
+ Map_QM.CSSObject.add(shopLabel);
+ }
+
+ if (startNode && startNode.path) {
+ endNode = item;
+ if (endNode && endNode.path) {
+ let iNodes = Map_QM.util.allMap[parseInt(endNode.build)].buildArr[parseInt(endNode.floor)].mapData.path.nodes;
+ iNodes.sort(Map_QM.util.sortNode);
+ Map_QM.util.overObj.build = endNode.build;
+ Map_QM.util.overObj.floor = endNode.floor;
+ Map_QM.util.overObj.node = endNode.node;
+ Map_QM.util.overObj.xaxis = iNodes[parseInt(endNode.node)].x;
+ Map_QM.util.overObj.yaxis = iNodes[parseInt(endNode.node)].y;
+ Map_QM.util.overObj.angle = 0;
+ let pathNode = dijkstra.find_path(Map_QM.util.pathStateObj.graphPath,startNode.path,endNode.path).nodes;
+ if (pathNode.length > 1) {
+ let pathData;
+ for (let j = 0; j < pathNode.length; j++) {
+ let array = pathNode[j].split("_");
+ if (j == 0 && isFrist) {
+ pathNodes.push({build: parseInt(array[0]),floor: parseInt(array[1]),pathNode: []});
+ }
+ pathData = Map_QM.util.allMap[parseInt(array[0])].buildArr[parseInt(array[1])].mapData.path;
+ pathData.nodes.sort(Map_QM.util.sortNode);
+ if (array[0] == pathNodes[index].build) {
+ if (array[1] == pathNodes[index].floor) {
+ if (!pathNodes[index].pathNode[findIndex]) {
+ pathNodes[index].pathNode[findIndex] = [];
+ }
+ pathNodes[index].pathNode[findIndex].push(pathData.nodes[parseInt(array[2])]);
+ } else {
+ if (j > 0) {
+ pathNodes[index].Facilities = this.getFacilIcon(pathNode[j - 1].split("_"),parseInt(array[0]));
+ } else {
+ pathNodes[index].Facilities = null;
+ }
+ pathNodes.push({build: parseInt(array[0]),floor: parseInt(array[1]),pathNode: [],});
+ index++;
+ findIndex = 0;
+ if (!pathNodes[index].pathNode[findIndex]) {
+ pathNodes[index].pathNode[findIndex] = [];
+ }
+ pathNodes[index].pathNode[findIndex].push(pathData.nodes[parseInt(array[2])]);
+ }
+ } else {
+ pathNodes.push({ build: parseInt(array[0]),floor: parseInt(array[1]),pathNode: []});
+ index++;
+ findIndex = 0;
+ if (!pathNodes[index].pathNode[findIndex]) {
+ pathNodes[index].pathNode[findIndex] = [];
+ }
+ pathNodes[index].pathNode[findIndex].push(
+ pathData.nodes[parseInt(array[2])]
+ );
+ }
+ }
+ }
+ if (isFrist) {
+ isFrist = false;
+ } else {
+ pathNode.shift();
+ }
+ PathPoint.push(...pathNode);
+ startNode = endNode;
+ findIndex++;
+ }
+ } else {
+ startNode = item;
+ Map_QM.changeStartPoint({
+ build: startNode.build,
+ floor: startNode.floor,
+ node: startNode.node,
+ angle: 0,
+ });
+ }
+ });
+ } catch (e) {
+ window.captureException && window.captureException(e);
+ console.log(e);
+ return;
+ }
+ Map_QM.forShopArr.length = 0;
+ Map_QM.util._indexPathFloor = 0;
+ Map_QM.util.pathStateObj.isPathPlay = true;
+ Map_QM.forShopListPath(PathPoint); //传入所有导航点
+ if (callBackFun) {
+ Map_QM.parseForShopArr();
+ const data = JSON.parse(
+ JSON.stringify(Map_QM.util.pathStateObj.forShopArr)
+ );
+ callBackFun(data);
+ }
+ Map_QM.startRender();
+ pathNodeList = null;
+ },
+
+ forShopListPath: function (PathPoint) {
+ let index = 0;
+ this.forShopArr = [];
+ if (PathPoint.length > 1) {
+ let pathData;
+ for (let j = 0; j < PathPoint.length; j++) {
+ let array = PathPoint[j].split("_");
+ if (j == 0) {
+ this.forShopArr.push({
+ build: parseInt(array[0]),
+ floor: parseInt(array[1]),
+ PathPoint: [],
+ });
+ }
+ pathData = Map_QM.util.allMap[parseInt(array[0])].buildArr[parseInt(array[1])].mapData.path;
+ pathData.nodes.sort(Map_QM.util.sortNode);
+ if (array[0] == this.forShopArr[index].build) {
+ if (array[1] == this.forShopArr[index].floor) {
+ this.forShopArr[index].PathPoint.push(pathData.nodes[parseInt(array[2])]);
+ } else {
+ if (j > 0) {
+ this.forShopArr[index].Facilities = this.getFacilIcon(PathPoint[j - 1].split("_"),parseInt(array[0]));
+ } else {
+ this.forShopArr[index].Facilities = null;
+ }
+ 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.push({ build: parseInt(array[0]), floor: parseInt(array[1]), PathPoint: []});
+ index++;
+ this.forShopArr[index].PathPoint.push(pathData.nodes[parseInt(array[2])]);
+ }
+ }
+ if (Map_QM.forShopArr.length > 0) {
+ // "floor" PathPoint Direction (Facilities)
+ for (let m = 0; m < Map_QM.forShopArr.length; m++) {
+ //查找经过店铺
+ Map_QM.forShopArr[m].wayShop = Map_QM.foreignShop(
+ Map_QM.forShopArr[m].PathPoint,
+ Map_QM.forShopArr[m].build,
+ Map_QM.forShopArr[m].floor,
+ m
+ );
+ if (Map_QM.util.overObj.build == Map_QM.forShopArr[m].build &&Map_QM.util.overObj.floor == Map_QM.forShopArr[m].floor) {
+ let len = Map_QM.forShopArr[m].wayShop.length;
+ if (Map_QM.forShopArr[m].wayShop[len - 1] && Map_QM.forShopArr[m].wayShop[len - 1].shop.yaxis == Map_QM.util.overObj.node) {
+ Map_QM.forShopArr[m].wayShop.pop();
+ }
+ }
+ }
+ } else {
+ console.error("无可行路径");
+ return;
+ }
+ this.onFindPathToObj();
+ }
+ pathNodeList = null;
+ },
+
+ parseForShopArr: function () {
+ Map_QM.util.pathStateObj.forShopArr = { direction: "", angle:0, cost:0, wayList: [] };
+ if(Map_QM.cost>0){
+ Map_QM.util.pathStateObj.forShopArr.cost = parseInt(Map_QM.cost);
+ }else{
+ let obj = Map_QM.getGapByPathNode({build: Map_QM.util.overObj.build, floor: Map_QM.util.overObj.floor, node: Map_QM.util.overObj.node});
+ Map_QM.util.pathStateObj.forShopArr.angle = obj.angle;
+ Map_QM.util.pathStateObj.forShopArr.cost = obj.dis;
+ }
+
+ if(Map_QM.forShopArr[0] && Map_QM.forShopArr[0].Facilities){
+ let x0 = Map_QM.forShopArr[0].Facilities.position.x - Map_QM.util.startObj.xaxis;
+ let y0 = Map_QM.forShopArr[0].Facilities.position.y + Map_QM.util.startObj.yaxis;
+ angle = (360+parseInt(Math.atan2(y0, x0)*180/Math.PI))%360;
+ Map_QM.util.pathStateObj.forShopArr.angle = Math.abs(angle - parseInt(Map_QM.util.deviceObj.angle));
+ }
+
+ Map_QM.forShopArr.forEach((item, index) => {
+ if (item.hasOwnProperty("Direction")) {
+ Map_QM.util.pathStateObj.forShopArr.direction = item.Direction;
+ Map_QM.util.pathStateObj.forShopArr.directionEn = item.DirectionEn;
+ }
+ if (item.hasOwnProperty("wayShop") && item.wayShop) {
+ for (let i = 0; i < item.wayShop.length; i++) {
+ 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 || item.wayShop[i].shop.logoUrl,
+ shopCode: item.wayShop[i].shop.shopCode,
+ houseNumber: item.wayShop[i].shop.houseNumber,
+ });
+ }
+ }
+ if (item.hasOwnProperty("Facilities") && item.Facilities) {
+ //设施
+ Map_QM.util.pathStateObj.forShopArr.wayList.push({
+ isAddPrefix: true,
+ shopName: "乘坐 " + item.Facilities.userData.name +"到 " + Map_QM.mapArr[parseInt(Map_QM.forShopArr[index + 1].build)][parseInt(Map_QM.forShopArr[index + 1].floor)].floorName,
+ shopNameEn:"BY " +item.Facilities.userData.nameEn +"TO " + Map_QM.mapArr[parseInt(Map_QM.forShopArr[index + 1].build)][parseInt(Map_QM.forShopArr[index + 1].floor)].floorName,
+ logoPath: item.Facilities.imgUrl,
+ shopCode: ((Math.random() * 0x1234567) | 0).toString(16).substring(0),
+ houseNumber:item.Facilities.userData.facCode + item.Facilities.userData.no,
+ });
+ }
+ });
+ },
+ /**
+ * @api {方法} getGapByPathNode() 获取实际距离
+ * @apiGroup 地图导航
+ * @apiDescription 通过点位获取距离
+ * @apiVersion 4.0.0
+ * @apiParam {int} floor 楼层编号
+ * @apiParam {string} node 路径点位编号
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ *
+ * Map_QM.getGapByPathNode({build:0, floor:2, node:"53"});
+ *
+ * @apiSuccessExample {Object} dist 距离米数 time 步行时间
+ * {
+ * dis:200,time:4
+ * }
+ */
+ getGapByPathNode: function (toObj) {
+ let startNade = Map_QM.util.deviceObj.build +"_" + Map_QM.util.deviceObj.floor + "_" + Map_QM.util.deviceObj.node;
+ let toNade = toObj.build + "_" + toObj.floor + "_" + toObj.node;
+ let pathData0 =Map_QM.util.allMap[parseInt(Map_QM.util.deviceObj.build)].buildArr[parseInt(Map_QM.util.deviceObj.floor)].mapData.path;
+ pathData0.nodes.sort(Map_QM.util.sortNode);
+ let stX = pathData0.nodes[parseInt(Map_QM.util.deviceObj.node)].x;
+ let stY = pathData0.nodes[parseInt(Map_QM.util.deviceObj.node)].y;
+
+ let pathData =Map_QM.util.allMap[parseInt(toObj.build)].buildArr[parseInt(toObj.floor)].mapData.path;
+ pathData.nodes.sort(Map_QM.util.sortNode);
+ let toX = pathData.nodes[parseInt(toObj.node)].x;
+ let toY = pathData.nodes[parseInt(toObj.node)].y;
+
+ let path = { cost: -1 }, angle=0,
+ minTime = 1;
+ try {
+ path = dijkstra.find_path( Map_QM.util.pathStateObj.basePath,startNade,toNade);
+ let x0 = (toX - stX);
+ let y0 = -1*(toY - stY);
+ angle = (360+parseInt(Math.atan2(y0, x0)*180/Math.PI))%360;
+ angle = Math.abs(angle - parseInt(Map_QM.util.deviceObj.angle));
+ minTime = Math.max(1,parseInt(path.cost / 50));
+ console.log(`距离目的地 ${parseInt(path.cost)} 米,预计${minTime} 分钟`); // 21 是比例尺
+ } catch (e) {
+ window.captureException && window.captureException(e);
+ console.log(e);
+ }
+ return {
+ angle: angle,
+ dis: parseInt(path.cost),
+ time: minTime,
+ };
+ },
+ /**
+ * @api {方法} pathPark() 获取车位点位
+ * @apiGroup 地图数据
+ * @apiDescription 获取车位导航点
+ * @apiVersion 4.0.0
+ * @apiParam {String} houseNumber 车位编号
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ *
+ * Map_QM.pathPark({houseNumber:"B1002"});
+ *
+ * @apiSuccessExample 返回示例
+ * {
+ * houseNumber: 车位编号, node: 导航点, floor: 楼层编号, xaxis: 中心点X坐标, yaxis: 中心点Y坐标
+ * }
+ */
+ pathPark: function (toObj) {
+ return this.shopNumToNavPoint(toObj, "park");
+ },
+
+ /**
+ * @api {方法} pathShopByName() 获取店铺点位
+ * @apiGroup 地图数据
+ * @apiDescription 通过店铺名称获取点位
+ * @apiVersion 4.0.0
+ * @apiParam {String} shopName 店铺名称
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ *
+ * Map_QM.pathShopByName("金拱门");
+ *
+ * @apiSuccessExample 返回示例
+ * {
+ * houseNumber: 店铺编号, node: 导航点, floor: 楼层编号, xaxis: 中心点X坐标, yaxis: 中心点Y坐标, comeIn:店铺多门点
+ * }
+ */
+ pathShopByName: function (shopName) {
+ for (let item of Map_QM.util.shopData) {
+ if (item.name === shopName) {
+ let toObj = { houseNumber: item.houseNumber, node: item.yaxis };
+ for (let h = 0; h < Map_QM.util.allMap.length; h++) {
+ let sArr = Map_QM.util.allMap[h].buildArr;
+ for (let i = 0; i < sArr.length; i++) {
+ let shops = Map_QM.util.allMap[h].buildArr[i].mapData.shopArea;
+ for (let k = 0; k < shops.length; k++) {
+ if (shops[k].name == toObj.houseNumber) {
+ toObj.floor = i;
+ toObj.build = h;
+ toObj.node = shops[k].shopNav;
+ toObj.xaxis = shops[k].xaxis;
+ toObj.yaxis = shops[k].yaxis;
+ if (shops[k].comeIn) {
+ toObj.comeIn = shops[k].comeIn;
+ }
+ return toObj;
+ }
+ }
+ }
+ }
+ return toObj;
+ }
+ }
+ },
+ /**
+ * @api {方法} changeBoxStateByFormat() 切换box显示状态
+ * @apiGroup 地图交互
+ * @apiDescription 根据业态切换box显示状态
+ * @apiVersion 4.0.0
+ * @apiParam {String} formatCode 业态Id
+ * @apiParam {Boolean} isShow 是否显示
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample {Object} 请求示例
+ *
+ * Map_QM.changeBoxStateByFormat("X8f1sfGl0gfa_QwVcMy86",false);
+ *
+ */
+ changeBoxStateByFormat: function (formatCode, isShow) {
+ for (let h = 0; h < Map_QM.mapArr.length; h++) {
+ for (let i = 0; i < Map_QM.mapArr[h].length; i++) {
+ let shopArr = Map_QM.mapArr[h][i].shopObj.children;
+ for (let k = 0; k < shopArr.length; k++) {
+ if ( shopArr[k].userData && shopArr[k].userData.formatCode == formatCode ) {
+ shopArr[k].visible = isShow;
+ }
+ }
+ Map_QM.mapArr[h][i].labelObj.traverse((obj) => {
+ if (obj.element && obj.userData.formatCode == formatCode) {
+ obj.element.style.display = isShow ? "block" : "none";
+ obj.userData.isShow = isShow;
+ }
+ });
+ }
+ }
+ Map_QM.updateRender();
+ Map_QM.collLabel();
+ },
+ /**
+ * @api {方法} changeBoxStateByName() 切换box显示状态
+ * @apiGroup 地图交互
+ * @apiDescription 根据名称切换box显示状态
+ * @apiVersion 4.0.0
+ * @apiParam {String} houseNumber box名称
+ * @apiParam {Boolean} isShow 是否显示
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample {Object} 请求示例
+ *
+ * Map_QM.changeBoxStateByName("L101", true);
+ *
+ */
+ changeBoxStateByName: function (houseNumber, isShow) {
+ for (let h = 0; h < Map_QM.mapArr.length; h++) {
+ for (let i = 0; i < Map_QM.mapArr[h].length; i++) {
+ let shopArr = Map_QM.mapArr[h][i].shopObj.children;
+ for (let k = 0; k < shopArr.length; k++) {
+ if (shopArr[k].name == houseNumber) {
+ shopArr[k].visible = isShow;
+ }
+ }
+ Map_QM.mapArr[h][i].labelObj.traverse((obj) => {
+ if (obj.name == houseNumber) {
+ obj.element.style.display = isShow ? "block" : "none";
+ obj.userData.isShow = isShow;
+ }
+ });
+ }
+ }
+ Map_QM.updateRender();
+ Map_QM.collLabel();
+ },
+ /**
+ * @api {方法} shopNumToNavPoint() 获取导航点位
+ * @apiGroup 地图导航
+ * @apiDescription 通过店铺编号或车位获取导航点位
+ * @apiVersion 4.0.0
+ * @apiParam {Object} object build,floor,houseNumber 楼栋编号,楼层编号,店铺或车位编号
+ * @apiParam {String} type 店铺或车位标识 "shop" "park"
+ *
+ * @apiSampleRequest off
+ *
+ * @apiSuccessExample 返回示例
+ * {
+ * houseNumber: 店铺编号, node: 导航点, floor: 楼层编号, xaxis: 中心点X坐标, yaxis: 中心点Y坐标, comeIn:店铺多门点
+ * }
+ */
+ shopNumToNavPoint: function (obj, type) {
+ let shopArr;
+ let reObj = {
+ build: Map_QM.util.selectBuild,
+ node: "",
+ xaxis: "",
+ yaxis: "",
+ floor: "",
+ comeIn: "",
+ };
+ for (let h = 0; h < Map_QM.util.allMap.length; h++) {
+ let sArr = Map_QM.util.allMap[h].buildArr;
+ for (let i = 0; i < sArr.length; i++) {
+ if (type == "shop") {
+ shopArr = sArr[i].mapData.shopArea;
+ } else if (type == "park") {
+ shopArr = sArr[i].mapData.parkArea;
+ }
+ for (let k = 0; k < shopArr.length; k++) {
+ if (shopArr[k].name == obj.houseNumber) {
+ reObj.floor = i;
+ reObj.build = h;
+ reObj.xaxis = shopArr[k].xaxis;
+ reObj.yaxis = shopArr[k].yaxis;
+ reObj.node = shopArr[k].shopNav;
+ reObj.houseNumber = obj.houseNumber;
+ if (shopArr[k].comeIn) {
+ reObj.comeIn = shopArr[k].comeIn;
+ }
+ return reObj;
+ }
+ }
+ }
+ }
+ },
+ /**
+ * 模拟导航获取路线
+ */
+ onFindPathModel: function (usePath = null) {
+ Map_QM.cost = -1;
+ Map_QM.forShopArr.length = 0;
+ Map_QM.util._indexPathFloor = 0;
+ Map_QM.util.pathStateObj.isPathPlay = true;
+ if (isNaN(parseInt(Map_QM.util.startObj.node)) ||parseInt(Map_QM.util.startObj.node) == -1) {
+ return;
+ }
+ try {
+ if (!Map_QM.util.startObj.xaxis) {
+ let pathData = Map_QM.util.allMap[parseInt(Map_QM.util.startObj.build)].buildArr[parseInt(Map_QM.util.startObj.floor)].mapData.path;
+ pathData.nodes.sort(Map_QM.util.sortNode);
+ Map_QM.util.startObj.xaxis = pathData.nodes[parseInt(Map_QM.util.startObj.node)].x;
+ Map_QM.util.startObj.yaxis = pathData.nodes[parseInt(Map_QM.util.startObj.node)].y;
+ }
+ if (!usePath) {
+ usePath = Map_QM.util.pathStateObj.graphPath;
+ }
+ if (Map_QM.util.overObj.comeIn) {
+ const costall = dijkstra.single_source_shortest_paths( Map_QM.util.pathStateObj.graphPath, startNade,startNade).costs;
+ 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);
+ }
+ }
+ 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 path = dijkstra.find_path(usePath, startNade, toNade);
+ if(Math.abs(Map_QM.util.overObj.floor-Map_QM.util.startObj.floor)>1){
+ if(usePath == Map_QM.util.pathStateObj.graphPath){
+ Map_QM.cost -= (1500 +300*Math.abs(Map_QM.util.overObj.floor-Map_QM.util.deviceObj.floor));
+ }else if(usePath == Map_QM.util.pathStateObj.ftPath){
+ Map_QM.cost -= (4500 +800*Math.abs(Map_QM.util.overObj.floor-Map_QM.util.deviceObj.floor));
+ }else{
+ Map_QM.cost -= (4500 +800*Math.abs(Map_QM.util.overObj.floor-Map_QM.util.deviceObj.floor));
+ }
+ }
+ Map_QM.forShopPath(path.nodes);
+ } catch (e) {
+ window.captureException && window.captureException(e);
+ console.log(e);
+ return;
+ }
+ },
+ forShopPath: function (PathPoint) {
+ let Dir = "向前出发",
+ index = 0;
+ let DirEn = "to forward";
+ 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;
+ if (array[0] == this.forShopArr[index].build) {
+ if (array[1] == this.forShopArr[index].floor) {
+ this.forShopArr[index].PathPoint.push(pathData.nodes[parseInt(array[2])]);
+ } else {
+ if (j > 0) {
+ this.forShopArr[index].Facilities = this.getFacilIcon( PathPoint[j - 1].split("_"),parseInt(array[0]));
+ } else {
+ this.forShopArr[index].Facilities = null;
+ }
+ 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.push({
+ build: parseInt(array[0]),
+ floor: parseInt(array[1]),
+ PathPoint: []
+ });
+ index++;
+ this.forShopArr[index].PathPoint.push(pathData.nodes[parseInt(array[2])]);
+ }
+ }
+ let dy = 0,dx = 0, ang = 0;
+ if (this.forShopArr[0].PathPoint.length > 1) {
+ if (this.forShopArr[0].PathPoint.length == 2) {
+ dy = -1*(this.forShopArr[0].PathPoint[1].y - this.forShopArr[0].PathPoint[0].y);
+ dx = this.forShopArr[0].PathPoint[1].x - this.forShopArr[0].PathPoint[0].x;
+ } else {
+ dy = -1*(this.forShopArr[0].PathPoint[2].y - this.forShopArr[0].PathPoint[1].y);
+ dx = this.forShopArr[0].PathPoint[2].x -this.forShopArr[0].PathPoint[1].x;
+ }
+
+ ang = parseInt(Math.atan2(dx,dy)*180/Math.PI);
+ ang = ang - parseInt(Map_QM.util.deviceObj.angle);
+ ang = ang > 180 ? ang - 360 : ang;
+ ang = ang < -180 ? ang + 360 : ang;
+ if (ang > -45 && ang <= 45) {
+ Dir = "向前出发";
+ DirEn = "to forward";
+ } else if (ang >= 45 && ang < 135) {
+ Dir = "向右出发";
+ DirEn = "to right";
+ } else if (ang <= -45 && ang > -135) {
+ Dir = "向左出发";
+ DirEn = "to left";
+ } else {
+ Dir = "向后出发";
+ DirEn = "to back";
+ }
+ }
+ let pLen = Map_QM.forShopArr[Map_QM.forShopArr.length - 1].PathPoint.length;
+ Map_QM.util.overObj.xaxis = Map_QM.forShopArr[Map_QM.forShopArr.length - 1].PathPoint[pLen - 1].x;
+ Map_QM.util.overObj.yaxis = Map_QM.forShopArr[Map_QM.forShopArr.length - 1].PathPoint[pLen - 1].y;
+
+ if (Map_QM.forShopArr.length > 0) {
+ Map_QM.forShopArr[0].angle = ang;
+ Map_QM.forShopArr[0].Direction = Dir;
+ Map_QM.forShopArr[0].DirectionEn = DirEn;
+
+ for (let m = 0; m < Map_QM.forShopArr.length; m++) {
+ //查找经过店铺
+ Map_QM.forShopArr[m].wayShop = Map_QM.foreignShop(
+ Map_QM.forShopArr[m].PathPoint,
+ Map_QM.forShopArr[m].build,
+ Map_QM.forShopArr[m].floor,
+ m
+ );
+ if (Map_QM.util.overObj.build == Map_QM.forShopArr[m].build && Map_QM.util.overObj.floor == Map_QM.forShopArr[m].floor ) {
+ let len = Map_QM.forShopArr[m].wayShop.length;
+ if (Map_QM.forShopArr[m].wayShop[len - 1] &&Map_QM.forShopArr[m].wayShop[len - 1].shop.yaxis == Map_QM.util.overObj.node) {
+ Map_QM.forShopArr[m].wayShop.pop();
+ }
+ }
+ }
+ /**
+ * @api {事件} InitPathOver 地图导航状态完成
+ * @apiGroup 地图事件
+ * @apiDescription 地图开始导航时触发
+ * @apiVersion 4.0.0
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ * Map_QM.addEventListener("InitPathOver",onInitPathOver,false);
+ */
+ Map_QM.dispatchEvent({
+ type: "InitPathOver",
+ data: Map_QM.forShopArr,
+ });
+ } else {
+ console.error("无可行路径,请检查起、终点位");
+ return;
+ }
+ this.onFindPathToObj();
+ }
+ },
+ getMinCostByArray: function (floor, array, costall) {
+ if (!Map_QM.util.startObj) {
+ Map_QM.changeStartPoint();
+ }
+ if (!Map_QM.util.numBuild) {
+ Map_QM.util.numBuild = 0;
+ }
+ let mis = -1,
+ nodeP;
+ for (let i = 0; i < array.length; i++) {
+ let toNade = Map_QM.util.numBuild + "_" + floor + "_" + array[i];
+ let PathPoint = costall[toNade];
+ if (mis == -1) {
+ mis = PathPoint;
+ nodeP = array[i];
+ } else {
+ if (mis > PathPoint) {
+ mis = PathPoint;
+ nodeP = array[i];
+ }
+ }
+ }
+ return nodeP;
+ },
+ isPassed:function(node, list=[]){
+ if(list && list.length>0){
+ for(let i=0;i 0) {
+ if (pathCameraState == "2D") {
+ const postArr = Map_QM.forShopArr[Map_QM.util._indexPathFloor].PathPoint;
+ const len = postArr.length;
+ let leftX = 50000, rightX=-50000, topY=50000, bottomY = -50000;
+ for(let i=0; i vw/Map_QM.w){ //按高度计算
+ Map_QM.setCameraZoom((0.8/(vh/Map_QM.h)), Map_QM.moveMapPosition, Map_QM.drawPathStart);
+ }else{ //按宽度计算
+ Map_QM.setCameraZoom((0.8/(vw/Map_QM.w)), Map_QM.moveMapPosition, Map_QM.drawPathStart);
+ }
+ }else{ //3D 不放大路线
+ Map_QM.drawPathStart();
+ // let disc = Map_QM.controls.getDistance();
+ // if(vh==0 || vw/vh < Map_QM.w/Map_QM.h){ //按高度计算
+ // Map_QM.setCameraDist((disc*vh/Map_QM.h)+30, Map_QM.moveMapPosition, Map_QM.drawPathStart);
+ // }else{ //按宽度计算
+ // Map_QM.setCameraDist((disc*vw/Map_QM.w)+30, Map_QM.moveMapPosition, Map_QM.drawPathStart);
+ // }
+ }
+ }
+ },
+ drawPathStart:function(){
+ document.addEventListener("pathOver", Map_QM.onFindPathFloor, true);
+ if (Map_QM.util.isMorePath) {
+ Map_QM.mapArr[Map_QM.forShopArr[Map_QM.util._indexPathFloor].build][Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor].findPath.onFindPathAnimation(pathNodes[Map_QM.util._indexPathFloor].pathNode, Map_QM.util.isMorePath,pathNodes[Map_QM.util._indexPathFloor].floor); //传入数组
+ } else {
+ Map_QM.mapArr[Map_QM.forShopArr[Map_QM.util._indexPathFloor].build][Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor].findPath.onFindPathAnimation(Map_QM.forShopArr[Map_QM.util._indexPathFloor].PathPoint,false ); //传入数组
+ }
+ clearTimeout(actionTime);
+ actionTime = setTimeout(()=>{
+ clearTimeout(actionTime);
+ Map_QM.mapArr[Map_QM.forShopArr[Map_QM.util._indexPathFloor].build][Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor].findPath.guidePathPlay(Map_QM.forShopArr[Map_QM.util._indexPathFloor]);
+ },800);
+ Map_QM.elementDestroy("dirLabel",true);
+ if(Map_QM.util.selectBuild == Map_QM.util.deviceObj.build && Map_QM.util.selectFloor == Map_QM.util.deviceObj.floor){
+ Map_QM.addDirectionLabel(Map_QM.forShopArr[0].angle);
+ }
+ Map_QM.controlsChock();
+ },
+ //根据屏幕坐标平移地图
+ moveMapPosition:function(){
+ const postArr = Map_QM.forShopArr[Map_QM.util._indexPathFloor].PathPoint;
+ const len = postArr.length;
+ let leftX = 50000, rightX=-50000, topY=50000, bottomY = -50000;
+ for(let i=0; i 3) {
+ floorArr.splice(2, floorArr.length - 3);
+ floorArr[1] = "...";
+ }
+ return floorArr;
+ },
+
+ //导航完成事件
+ onFindPathFloor: function (event) {
+ document.removeEventListener("pathOver", Map_QM.onFindPathFloor);
+ if (Map_QM.forShopArr.length <= Map_QM.util._indexPathFloor) {
+ return;
+ }
+ if (Map_QM.util._indexPathFloor < Map_QM.forShopArr.length - 1) {
+ //楼层切换
+ if (Map_QM.forShopArr[Map_QM.util._indexPathFloor].Facilities) {
+ let pathFloor = Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor;
+ let x0 =Map_QM.forShopArr[Map_QM.util._indexPathFloor].Facilities.position.x+64;
+ let y0 = Map_QM.forShopArr[Map_QM.util._indexPathFloor].Facilities.position.y;
+ let model = Map_QM.forShopArr[Map_QM.util._indexPathFloor].Facilities.userData.model;
+ /**
+ * @api {事件} PathPlaying 地图导航的实时状态
+ * @apiGroup 地图事件
+ * @apiDescription 地图导航过程中实时触发
+ * @apiVersion 4.0.0
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ * Map_QM.addEventListener("PathPlaying",onPathPlaying,false);
+ */
+ Map_QM.dispatchEvent({
+ //寻路中返回小人当前所在点位
+ type: "PathPlaying",
+ data: {
+ houseNumber:Map_QM.forShopArr[Map_QM.util._indexPathFloor].Facilities.userData.facCode + Map_QM.forShopArr[Map_QM.util._indexPathFloor].Facilities.userData.no,
+ },
+ });
+ let box;
+ if (model && model.userData.name == "dt") {
+ model.traverse(function (child) {
+ if (child.isMesh && child.name == "zhitibox") {
+ box = child;
+ }
+ if (child.isMesh && (child.name == "zhitijiegou" || child.name == "zhitiboli")) {
+ child.scale.y = 3;
+ }
+ });
+ }
+
+ let zo = window.innerWidth > 2000 ? 8 : 4,
+ tz = window.innerWidth > 2000 ? 8 : 4,
+ boxT = 0,
+ boxZ = 0;
+ let add = window.innerWidth > 2000 ? 80 : 40;
+ let lft = window.innerWidth > 2000 ? 8 : 4;
+ Map_QM.util._indexPathFloor++;
+ let toFloor = parseInt(
+ Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor
+ );
+ let floorArr = Map_QM.showNavFloor(
+ pathFloor,
+ toFloor,
+ parseInt(Map_QM.forShopArr[Map_QM.util._indexPathFloor].build)
+ ); //电梯旁显示的楼层名称
+ if (pathFloor < toFloor) {
+ tz = (floorArr.length - 1) * add-lft;
+ boxT = 12;
+ } else {
+ zo = (floorArr.length - 1) * add-lft;
+ boxZ = 12;
+ }
+
+ document.getElementById("moveFloor").style.bottom = zo + "px";
+ document.getElementById("moveFloor").style.width = add + "px";
+ document.getElementById("moveFloor").style.height = add + "px";
+ document.getElementById("moveFloor").style.left = window.innerWidth > 2000 ? "4px" : "2px";
+
+ Map_QM.moveFloorbg.element.style.width = add + lft + "px";
+ Map_QM.moveFloorbg.element.style.height = floorArr.length * add + "px";
+ Map_QM.moveFloorbg.position.set(x0, y0, -80);
+ Map_QM.moveFloorbg.applyMatrix4(Map_QM.mapArr[parseInt(Map_QM.forShopArr[Map_QM.util._indexPathFloor].build)][pathFloor].floorObj.matrix);
+ Map_QM.moveFloorbg.applyMatrix4(Map_QM.mapArr[parseInt(Map_QM.forShopArr[Map_QM.util._indexPathFloor].build)][pathFloor].allObj.matrix);
+ let floorBox = document.getElementById("floorBox");
+ while (floorBox.hasChildNodes()) {
+ floorBox.removeChild(floorBox.firstChild);
+ }
+ for (let i = floorArr.length - 1; i >= 0; i--) {
+ let span2 = document.createElement("span");
+ span2.style.cssText = "display: block;color: #FFF; font-weight: 700; text-align: center;";
+ span2.style.fontSize = "16px";
+ if (window.innerWidth > 2000) {
+ span2.style.fontSize = "32px";
+ }
+ span2.style.width = add + lft + "px";
+ span2.style.height = add + "px";
+ span2.style.lineHeight = add + "px";
+ span2.innerText = floorArr[i];
+ floorBox.appendChild(span2);
+ }
+
+ let matches = floorBox.querySelectorAll("span");
+ let length = matches.length-1;
+
+ TweenMax.fromTo("#moveFloor",1.5,{ bottom: zo },
+ {
+ bottom: tz,
+ onUpdate: function () {
+ let bottm = parseInt(document.getElementById("moveFloor").style.bottom);
+ matches.forEach((item,index)=>{
+ if( -0.5 0) {
+ for (let i = 0; i < Map_QM.mapArr[k].length; i++) {
+ Map_QM.mapArr[k][i].findPath.clearPath(k,i);
+ }
+ }
+ }
+
+ Map_QM.controls.setZoom(1);
+ pathNodes = null;
+ Map_QM.removeHeatMap();
+ TweenMax.killAll(true);
+ },
+
+ remove_child: function (remObj) {
+ if (!remObj) {
+ return;
+ }
+ let child_elem = remObj.children;
+ for (let i = child_elem.length - 1; i >= 0; i--) {
+ if (child_elem[i].children.length > 0) {
+ Map_QM.remove_child(child_elem[i]);
+ } else {
+ if (child_elem[i] instanceof THREE.Mesh) {
+ child_elem[i].geometry.dispose(); // 删除几何体
+ if (child_elem[i].material !== undefined)
+ Map_QM.removeMaterial(child_elem.material); // 删除材质
+ }
+ }
+ if (child_elem[i].name != "light" && child_elem[i].name != "dtline") {
+ remObj.remove(child_elem[i]);
+ }
+ }
+ },
+ removeMaterial: function (material) {
+ if (Array.isArray(material)) {
+ for (var i = 0, l = material.length; i < l; i++) {
+ this.removeMaterialFromRefCounter(material[i]);
+ }
+ } else {
+ this.removeMaterialFromRefCounter(material);
+ }
+ },
+ removeMaterialFromRefCounter: function (material) {
+ var materialsRefCounter = this.materialsRefCounter;
+ if (materialsRefCounter) {
+ var count = materialsRefCounter.get(material);
+ count--;
+ if (count === 0) {
+ materialsRefCounter.delete(material);
+ delete this.materials[material.uuid];
+ } else {
+ materialsRefCounter.set(material, count);
+ }
+ }
+ },
+
+ /**
+ * @api {方法} pathStop() 导航暂停/播放
+ * @apiGroup 地图导航
+ * @apiDescription 导航动画暂停/播放
+ * @apiVersion 4.0.0
+ *
+ * @apiSampleRequest off
+ *
+ */
+ pathStop: function (isPlaying) {
+ Map_QM.util.pathStateObj.isPathPlay =isPlaying === undefined? !Map_QM.util.pathStateObj.isPathPlay : isPlaying;
+ Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].findPath.pathPlay.isPlay = Map_QM.util.pathStateObj.isPathPlay;
+ },
+ /**
+ * @api {方法} pathRePlay() 导航动画重播
+ * @apiGroup 地图导航
+ * @apiDescription 导航动画重播
+ * @apiVersion 4.0.0
+ *
+ * @apiSampleRequest off
+ *
+ */
+ pathRePlay: function () {
+ clearTimeout(Map_QM.util.timeObj.pathTime);
+ TweenMax.killAll(true);
+ if (!Map_QM.util.overObj.node) {
+ return;
+ }
+ if (Map_QM.util.pathStateObj.isPathState) {
+ Map_QM.util.timeObj.pathTime = setTimeout(() => {
+ clearTimeout(Map_QM.util.timeObj.pathTime);
+ Map_QM.controls.reset();
+ if (Map_QM.util.overObj && Map_QM.forShopArr[0]) {
+ Map_QM.util.pathStateObj.isPathPlay = true;
+ Map_QM.clearFloor();
+ Map_QM.onFindPathToObj();
+ }
+ }, 100);
+ }
+ },
+
+ /**
+ * @api {方法} ChangePathByFt() 切换扶梯模式
+ * @apiGroup 地图导航
+ * @apiDescription 导航切换扶梯模式
+ * @apiVersion 4.0.0
+ *
+ * @apiParam {function} callBack 回调函数
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ *
+ * Map_QM.ChangePathByFt(function);
+ *
+ */
+ ChangePathByFt: function (callBack) {
+ clearTimeout(Map_QM.util.timeObj.pathTime);
+ TweenMax.killAll(true);
+ if (!Map_QM.util.overObj.node || Map_QM.util.isMorePath) {
+ return;
+ }
+ Map_QM.util.timeObj.pathTime = setTimeout(() => {
+ clearTimeout(Map_QM.util.timeObj.pathTime);
+ Map_QM.controls.reset();
+ if (Map_QM.util.overObj) {
+ Map_QM.clearFloor();
+ Map_QM.onFindPathModel(Map_QM.util.pathStateObj.ftPath);
+ if (callBack) {
+ Map_QM.parseForShopArr();
+ const data = JSON.parse(JSON.stringify(Map_QM.util.pathStateObj.forShopArr));
+ callBack(data);
+ }
+ }
+ }, 100);
+ },
+ /**
+ * @api {方法} ChangePathByDt() 切换电梯模式
+ * @apiGroup 地图导航
+ * @apiDescription 导航切换电梯模式
+ * @apiVersion 4.0.0
+ *
+ * @apiParam {function} callBack 回调函数
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ *
+ * Map_QM.ChangePathByDt(function);
+ *
+ */
+ ChangePathByDt: function (callBack) {
+ clearTimeout(Map_QM.util.timeObj.pathTime);
+ TweenMax.killAll(true);
+ if (!Map_QM.util.overObj.node || Map_QM.util.isMorePath) {
+ return;
+ }
+ Map_QM.util.timeObj.pathTime = setTimeout(() => {
+ clearTimeout(Map_QM.util.timeObj.pathTime);
+ Map_QM.controls.reset();
+ if (Map_QM.util.overObj) {
+ Map_QM.clearFloor();
+ Map_QM.onFindPathModel(Map_QM.util.pathStateObj.dtPath);
+ if (callBack) {
+ Map_QM.parseForShopArr();
+ const data = JSON.parse(JSON.stringify(Map_QM.util.pathStateObj.forShopArr));
+ callBack(data);
+ }
+ }
+ }, 100);
+ },
+ /**
+ * @api {方法} ChangePathByGood() 切换最佳模式
+ * @apiGroup 地图导航
+ * @apiDescription 导航切换最佳模式
+ * @apiVersion 4.0.0
+ *
+ * @apiParam {function} callBack 回调函数
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ *
+ * Map_QM.ChangePathByGood(function);
+ *
+ */
+ ChangePathByGood: function (callBack) {
+ clearTimeout(Map_QM.util.timeObj.pathTime);
+ TweenMax.killAll(true);
+ if (!Map_QM.util.overObj.node || Map_QM.util.isMorePath) {
+ return;
+ }
+ Map_QM.util.timeObj.pathTime = setTimeout(() => {
+ clearTimeout(Map_QM.util.timeObj.pathTime);
+ Map_QM.controls.reset();
+ if (Map_QM.util.overObj) {
+ Map_QM.clearFloor();
+ Map_QM.onFindPathModel(Map_QM.util.pathStateObj.graphPath);
+ if (callBack) {
+ Map_QM.parseForShopArr();
+ const data = JSON.parse(JSON.stringify(Map_QM.util.pathStateObj.forShopArr));
+ callBack(data);
+ }
+ }
+ }, 100);
+ },
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ changeDocmentResize: function (e) {
+ let w = parseInt(Map_QM.ele.clientWidth) || parseInt(window.getComputedStyle(Map_QM.ele, null).getPropertyValue("width"));
+ let h = parseInt(Map_QM.ele.clientHeight) || parseInt( window.getComputedStyle(Map_QM.ele, null).getPropertyValue("height"));
+ Map_QM.changeWindowResize(w, h);
+ },
+ /**
+ * @api {方法} changeWindowResize() 窗口变化
+ * @apiGroup 地图交互
+ * @apiDescription 窗口变化
+ * @apiVersion 4.0.0
+ *
+ * @apiParam {int} width 窗口宽
+ * @apiParam {int} height 窗口高
+ *
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ *
+ * Map_QM.changeWindowResize(1280,1080);
+ */
+ changeWindowResize: function (width, height) {
+ width = width || Map_QM.w;
+ height = height || Map_QM.h;
+ Map_QM.aspect = width / height;
+ Map_QM.cameraPerspective.aspect = Map_QM.aspect;
+ Map_QM.cameraPerspective.updateProjectionMatrix();
+ Map_QM.cameraOrtho.left = -150 * Map_QM.aspect;
+ Map_QM.cameraOrtho.right = 150 * Map_QM.aspect;
+ Map_QM.cameraOrtho.top = 150;
+ Map_QM.cameraOrtho.bottom = -150;
+ Map_QM.cameraOrtho.updateProjectionMatrix();
+ Map_QM.renderer.setSize(width, height);
+ Map_QM.labelRenderer.setSize(width, height);
+ Map_QM.w = width;
+ Map_QM.h = height;
+ Map_QM.updateRender();
+ Map_QM.collLabel();
+ },
+};
+/**
+ * @api {方法} init(callBack,options) 地图初始化
+ * @apiGroup 地图数据
+ * @apiDescription 初始化地图赋值 Map_QM
+ * @apiVersion 4.0.0
+ *
+ * @apiParam {function} callBack 初始化成功后的回调函数
+ * @apiParam {object} options 初始化对象
+ * @apiParam {int} options.build 设备所在楼栋编号 默认值6
+ * @apiParam {int} options.floor 设备所在楼层编号 默认值 true
+ * @apiParam {int} options.navPoint 设备导航点 默认值 -1
+ * @apiParam {int} options.angle 起点设备角度 默认值 0
+ * @apiParam {string} options.perc_H 弹窗的偏移量 默认值 "-50%";
+ * @apiParam {string} options.containerId 地图div容器Id 默认值 "mapContainer"
+ * @apiParam {string} options.playSpeed 动画播放速度 默认值8
+ * @apiParam {boolean} options.collision 是否支持名称的碰撞检测 默认值 true
+ * @apiParam {boolean} options.modelIcon 交通设施是否使用模型 默认值 true
+ * @apiParam {Array} options.otherPath 人为干预的路线 默认值 [];
+ * @apiParam {int} options.fSpace 双叠层状态下楼层的间距 默认值 500
+ * @apiParam {uint} options.navColor 途径店铺颜色 默认值 0xEE6A50
+ * @apiParam {boolean} options.shadow 是否显示阴影 默认值 false
+ * @apiParam {boolean} options.iconName 图标名称是否显示 默认值false
+ * @apiParam {uint} options.pathColor 导航路径颜色 默认值 0xb47834,
+ * @apiParam {string} options.pathStyle 导航第一视角 默认值 "2D",
+ * @apiParam {string} options.shopStyle 店铺显示字段编号(houseNumber)名称(shopName) 默认值 "shopName",
+ * @apiParam {boolean} options.inArea 地图点击后是否聚焦到当前位置 默认值 false
+ * @apiParam {string} options.mapData 地图数据 res.data.mapData
+ * @apiParam {string} options.shopData 店铺数据 res.data
+ * @apiParam {Array} options.iconUrl 设施库图标 默认值 []
+ *
+ * @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) {
+ if (Map_QM) {
+ Map_QM.cancelRender();
+ Map_QM.beforeDestroy();
+ }
+ Map_QM = new MainMap_QM(callBack, options);
+ return Map_QM;
+};
+Object.assign(MainMap_QM.prototype, THREE.EventDispatcher.prototype);
+
+//////////////////////////////////////-------------------------------FloorMap
+var FloorMap_QM = function (bIndex, fIndex, floorName) {
+ this.Model_QM = new MyModel_QM();
+ this.facUtil = new Facilities_QM();
+ this.findPath = new FindPath_QM();
+ this.logoUtil = new ShopLogo_QM();
+ this.allObj = new THREE.Group();
+ this.allObj.name = floorName;
+ this.allObj.rotation.x = Math.PI / -2;
+ this.floorObj = new THREE.Group();
+ this.allObj.add(this.floorObj);
+ this.CSSObj = new THREE.Group();
+ this.labelObj = new THREE.Group();
+ this.labelObj.renderOrder = 100;
+ this.floorOrder = fIndex;
+ this.buildOrder = bIndex;
+ this.floorName = floorName;
+ //存第三方
+ this.otherObj = new THREE.Object3D();
+ this.floorObj.add(this.otherObj);
+ //存放设施图标
+ this.serObj = new THREE.Object3D();
+ //存放车位box
+ this.parkObj = new THREE.Group();
+ //标签
+ this.tagObj = new THREE.Group();
+ this.tagObj.renderOrder = 100;
+ //存放设施图标
+ this.svgObj = new THREE.Group();
+ //店铺
+ this.shopObj = new THREE.Group();
+ this.floorObj.add(this.shopObj);
+ this.floorObj.add(this.svgObj);
+ this.floorObj.add(this.CSSObj);
+
+ this.CSSObj.add(this.serObj);
+ this.CSSObj.add(this.labelObj);
+ this.CSSObj.add(this.tagObj);
+ //标签
+ this.showTagObj = new THREE.Group();
+ this.showTagObj.renderOrder = 100;
+ this.CSSObj.add(this.showTagObj);
+
+ //线条
+ this.lineObj = new THREE.Group();
+ this.lineObj.renderOrder = 100;
+
+ this.floorObj.add(this.lineObj);
+
+ this.startIcon;
+};
+
+FloorMap_QM.prototype = {
+ initDraw: function () {
+ this.initFloor();
+ this.initFacilitie();
+ this.initStairs();
+ this.initTextArea();
+ this.initWall();
+ this.initDecos();
+ this.initPark();
+ this.initModel();
+ this.initTree(); //植树
+ this.initLogos(); //贴图
+ },
+ initLogos: function () {
+ let sopce = this;
+ if (Map_QM.util.logos) {
+ Map_QM.util.logos.map((item) => {
+ if (item.build == sopce.buildOrder && item.floor == sopce.floorOrder) {
+ sopce.logoUtil.renderIcon(item, sopce, item.site || 0);
+ }
+ });
+ }
+ },
+ initModel: function () {
+ let sopce = this;
+ if (Map_QM.util.modelArr) {
+ for (let i = 0; i < Map_QM.util.modelArr.length; i++) {
+ if (Map_QM.util.modelArr[i].build == this.buildOrder && Map_QM.util.modelArr[i].floor == this.floorOrder) {
+ new THREE.GLTFLoader().load(
+ Map_QM.util.beforPath + Map_QM.util.modelArr[i].url,
+ function (object) {
+ //加载路径fbx文件
+ let mod = object.scene;
+ mod.traverse(function (child) {
+ if (child.isMesh) {
+ child.receiveShadow = Map_QM.util.options.shadow;
+ child.castShadow = Map_QM.util.options.shadow;
+ child.userData.opacity = child.material.opacity;
+ if (child.material.map) {
+ child.material.map.encoding = THREE.LinearEncoding; //贴图需要转换成 线性编码
+ }
+ child.material.color.convertGammaToLinear(0.7);
+ }
+ });
+ for (let t = 0; t < Map_QM.util.modelArr[i].list.length; t++) {
+ let obj = mod.clone();
+ obj.position.set(
+ Map_QM.util.modelArr[i].list[t].site.x,
+ -1 * Map_QM.util.modelArr[i].list[t].site.y,
+ Map_QM.util.modelArr[i].list[t].site.z
+ );
+ obj.scale.set(
+ Map_QM.util.modelArr[i].list[t].size.x,
+ Map_QM.util.modelArr[i].list[t].size.y,
+ Map_QM.util.modelArr[i].list[t].size.z
+ );
+ obj.rotateX((Map_QM.util.modelArr[i].list[t].rot.x * Math.PI) / 180);
+ obj.rotateY((Map_QM.util.modelArr[i].list[t].rot.y * Math.PI) / 180);
+ obj.rotateZ((Map_QM.util.modelArr[i].list[t].rot.z * Math.PI) / 180);
+ sopce.floorObj.add(obj);
+ }
+ }
+ );
+ }
+ }
+ }
+ if (Map_QM.util.labelIconArr) {
+ for (let i = 0; i < Map_QM.util.labelIconArr.length; i++) {
+ if (Map_QM.util.labelIconArr[i].build == this.buildOrder && Map_QM.util.labelIconArr[i].floor == this.floorOrder) {
+ let SpriteDiv = document.createElement("div");
+ SpriteDiv.className = Map_QM.util.labelIconArr[i].className;
+ SpriteDiv.innerHTML = Map_QM.util.labelIconArr[i].title;
+ SpriteDiv.dataset.id = Map_QM.util.labelIconArr[i].data.id;
+ SpriteDiv.dataset.x = Map_QM.util.labelIconArr[i].site.x;
+ SpriteDiv.dataset.y = Map_QM.util.labelIconArr[i].site.y;
+ SpriteDiv.dataset.z = Map_QM.util.labelIconArr[i].site.z;
+ let pointLabel = new THREE.CSS2DObject(SpriteDiv);
+ pointLabel.position.set(
+ Map_QM.util.labelIconArr[i].site.x,
+ -1 * Map_QM.util.labelIconArr[i].site.y,
+ Map_QM.util.labelIconArr[i].site.z
+ );
+ pointLabel.name = Map_QM.util.labelIconArr[i].title;
+ pointLabel.userData = Map_QM.util.labelIconArr[i].data;
+ pointLabel.userData.site = Map_QM.util.labelIconArr[i].site;
+ pointLabel.userData.mapShow = true;
+ pointLabel.userData.isShow = true;
+ pointLabel.userData.type = "icon";
+ if (Map_QM.util.labelIconArr[i].click) {
+ //可点击
+ SpriteDiv.addEventListener("click", (event) => {
+ Map_QM.dispatchEvent({
+ type: "labelIcon",
+ data: event.target.dataset,
+ });
+ },
+ false
+ );
+ } else {
+ pointLabel.element.style.pointerEvents = "none";
+ }
+ pointLabel.userData.floor = Map_QM.util.labelIconArr[i].floor;
+ sopce.showTagObj.add(pointLabel);
+ }
+ }
+ }
+ },
+ initTree: function () {
+ let mapData =
+ Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData;
+ if (mapData.models) {
+ for (let t = 0; t < mapData.models.length; t++) {
+ for (let i = 0; i < Map_QM.util.fbxModels.length; i++) {
+ if (mapData.models[t].type == Map_QM.util.fbxModels[i].key) {
+ let obj = Map_QM.util.fbxModels[i].obj.scene.clone();
+ obj.position.set(mapData.models[t].x, -1 * mapData.models[t].y, mapData.models[t].site);
+ obj.scale.set(mapData.models[t].scale,mapData.models[t].scale,mapData.models[t].scale);
+ obj.rotateX(Map_QM.util.fbxModels[i].operation.rot.x);
+ obj.rotateY((-1 * mapData.models[t].angle * Math.PI) / 180);
+ obj.renderOrder = 100;
+ for (let k = 0;k < Map_QM.util.fbxModels[i].obj.animations.length; k++ ) {
+ let mixer = new THREE.AnimationMixer(obj);
+ mixer.clipAction(Map_QM.util.fbxModels[i].obj.animations[k]).play();
+ Map_QM.mixers.push(mixer);
+ }
+ //加载编辑器动画
+ obj.name = mapData.models[t].name;
+ if (mapData.animations) {
+ mapData.animations.forEach((item) => {
+ if (mapData.models[t].name == item.name) {
+ obj.rotateY(mapData.models[t].angle * Math.PI / 180);
+ let posArr = [],
+ rotArr = [],
+ scaleArr = [],
+ keyArr = [],
+ proArr = [],
+ clip;
+ item.frames.forEach((it) => {
+ keyArr.push(it.time);
+ posArr.push(it.pos.x, -1 * it.pos.y, it.pos.z);
+ rotArr.push((it.rot / -180) * Math.PI);
+ scaleArr.push(it.size, it.size, it.size);
+ proArr.push(it.pro);
+ });
+ if (item.isType) {
+ //特殊模型动画
+ let rotTF = new THREE.KeyframeTrack(item.name + ".rotation[y]", keyArr,rotArr);
+ let rotKF = new THREE.KeyframeTrack(item.sonName, keyArr, proArr);
+ clip = new THREE.AnimationClip(item.name, keyArr[keyArr.length - 1], [rotTF,rotKF]);
+ } else {
+ let posKF = new THREE.KeyframeTrack(item.name + ".position",keyArr,posArr);
+ let rotKF = new THREE.KeyframeTrack(item.name + ".rotation[y]", keyArr,rotArr);
+ let scalKF = new THREE.KeyframeTrack(item.name + ".scale",keyArr,scaleArr);
+ clip = new THREE.AnimationClip(item.name,keyArr[keyArr.length - 1],[posKF, rotKF, scalKF]);
+ }
+ if (clip) {
+ let mixer = new THREE.AnimationMixer(obj);
+ mixer.clipAction(clip).play();
+ Map_QM.mixers.push(mixer);
+ }
+ }
+ });
+ }
+ this.floorObj.add(obj);
+ }
+ }
+ }
+ }
+ },
+ //初始化单楼层
+ initFloor: function () {
+ let floor;
+ let mapData = Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData;
+ let entColor, borderColor,floorH=1,buildH=1;
+ if (mapData.floorArea) {
+ floor = Map_QM.util.changeAreaToString(mapData.floorArea);
+ }
+
+ let bLen = mapData.buildArea.length;
+ let hLen = mapData.hollowArea.length;
+ let hows_f = [];
+ for (let m = 0; m < hLen; m++) {
+ let isIn = Map_QM.util.checkAreaInArea(mapData.hollowArea[m],mapData.floorArea);
+ if (isIn) {
+ hows_f.push(Map_QM.util.changeAreaToString(mapData.hollowArea[m]));
+ }
+ }
+ if (floor) {
+ entColor = mapData.floorArea.entColor;
+ borderColor = mapData.floorArea.borderColor;
+ floorH = parseInt(mapData.floorArea.toHeight);
+ let mash = this.Model_QM.MyModelShape(floor,hows_f,mapData.floorArea,entColor,borderColor,10 + 100 * this.floorOrder);
+ mash.receiveShadow = true;
+ mash.castShadow = false;
+ mash.userData = {
+ type: "floor",
+ order: this.floorOrder,
+ };
+ mash.userData.opacity = mapData.floorArea.alphaModle / 100 || 0;
+ mash.name = "floor";
+ this.floorObj.add(mash);
+ }
+ /////////////////////初始化楼栋
+ for (let i = 0; i < bLen; i++) {
+ let build = Map_QM.util.changeAreaToString(mapData.buildArea[i]);
+ let hows = [];
+ for (let t = 0; t < hLen; t++) {
+ let isIn = Map_QM.util.checkAreaInArea(mapData.hollowArea[t],mapData.buildArea[i]);
+ if (isIn) {
+ hows.push(Map_QM.util.changeAreaToString(mapData.hollowArea[t]));
+ }
+ }
+ entColor = mapData.buildArea[i].entColor;
+ borderColor = mapData.buildArea[i].borderColor;
+ buildH = parseInt(mapData.buildArea[i].toHeight);
+ let mash = this.Model_QM.MyPlaneShape(build,hows,mapData.buildArea[i],entColor,borderColor,30 + 100 * this.floorOrder);
+ mash.receiveShadow = true;
+ mash.castShadow = false;
+ mash.userData = {
+ type: "build",
+ order: this.floorOrder,
+ xaxis: mapData.buildArea[i].xaxis,
+ yaxis: mapData.buildArea[i].yaxis,
+ };
+ mash.userData.opacity = mapData.buildArea[i].alphaModle / 100 || 0;
+ mash.name = mapData.buildArea[i].name;
+ this.floorObj.add(mash);
+ }
+ //店铺
+ mapData.shopArea.sort((a,b)=>{
+ return a.xaxis-b.xaxis+a.yaxis-b.yaxis;
+ })
+ let sLen = mapData.shopArea.length;
+ let show = "",
+ showE = "",
+ showLeb = "",
+ formatCode = "",
+ mapShow = false;
+ let logo = "",
+ navRecommend = false,
+ shopD = {};
+ let shopData = Map_QM.util.shopData;
+ for (let i = 0; i < sLen; i++) {
+ if (Map_QM.util.changeAreaToString(mapData.shopArea[i]) != "") {
+ for (let t = 0; t < sLen; t++) {
+ let isIn = Map_QM.util.checkAreaInArea(mapData.shopArea[i], mapData.shopArea[t]);
+ isIn &&(mapData.shopArea[i].site = parseInt(mapData.shopArea[i].site) + 1);
+ }
+ let arr = Map_QM.util.changeShopLinesToString(mapData.shopArea[i]);
+ entColor = mapData.shopArea[i].entColor || "#b79266";
+ borderColor = mapData.shopArea[i].borderColor || "#b79266";
+ show = showE = mapData.shopArea[i].name;
+ logo = "";
+ showLeb = "";
+ formatCode="";
+ navRecommend = false;
+ mapShow = false;
+ shopD = {};
+ if (shopData) {
+ for (let h = 0; h < shopData.length; h++) {
+ if (shopData[h].houseNumber === mapData.shopArea[i].name) {
+ showLeb = shopData[h].houseNumber;
+ show = shopData[h].shopName == undefined ? shopData[h].name : shopData[h].shopName;
+ showE = shopData[h].shopNameEn == undefined ? shopData[h].nameEn : shopData[h].shopNameEn;
+ logo = shopData[h].logoUrl;
+ mapShow = shopData[h].mapShow ?? false; //是否常显示
+ formatCode = shopData[h].industryFatherCode;
+ navRecommend = true;
+ shopD = shopData[h];
+ if (shopData[h].isNewShop) {
+ //新店
+ mapData.shopArea[i].type = "new-shop";
+ this.addTagLabel(mapData.shopArea[i], {node: mapData.shopArea[i].shopNav, floor: this.floorOrder, build: this.buildOrder});
+ } else {
+ if (shopData[h].activityList &&shopData[h].activityList.length > 0) {
+ //促销
+ mapData.shopArea[i].type = "promotion";
+ this.addTagLabel(mapData.shopArea[i], {node: mapData.shopArea[i].shopNav, floor: this.floorOrder, build: this.buildOrder });
+ }
+ }
+ shopData[h].color && (entColor = shopData[h].color);
+ shopData[h].formatColor && (entColor = shopData[h].formatColor);
+ shopData[h].borderColor && (borderColor = shopData[h].borderColor);
+ break;
+ }
+ }
+ }
+ let hollShop = [];
+ if (mapData.shopArea[i].hollArea) {
+ for (let k = 0; k < mapData.shopArea[i].hollArea.length; k++) {
+ hollShop.push(Map_QM.util.changeAreaToString(mapData.shopArea[i].hollArea[k]));
+ }
+ }
+ let mahc = this.Model_QM.MyModelShape(arr,hollShop,mapData.shopArea[i],entColor,borderColor,60 + 100 * this.floorOrder);
+ mahc.node = mapData.shopArea[i].shopNav;
+ mahc.userData = {
+ id: mapData.shopArea[i].id,
+ shopData: shopD,
+ xaxis: mapData.shopArea[i].xaxis >> 0,
+ yaxis: mapData.shopArea[i].yaxis >> 0,
+ node: mahc.node,
+ floor: this.floorOrder,
+ build: this.buildOrder,
+ navRecommend: navRecommend,
+ type: "shop",
+ houseNumber: mapData.shopArea[i].name,
+ shopName: show,
+ formatCode: formatCode,
+ logo: logo,
+ opacity: mapData.shopArea[i].alphaModle / 100 || 0,
+ };
+ mahc.name = showLeb;
+ mahc.xaxis = mapData.shopArea[i].xaxis >> 0;
+ mahc.yaxis = mapData.shopArea[i].yaxis >> 0;
+ this.shopObj.add(mahc);
+ if (mapData.shopArea[i].logoUrl && mapData.shopArea[i].isLabel == 0) {
+ //添加logo
+ this.logoUtil.renderIcon(mapData.shopArea[i],mahc,parseInt(mapData.shopArea[i].toHeight) +1 );
+ } else {
+ //添加文字
+ 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);
+ });
+ }
+ if (showLeb != "" || some) {
+ let shopDiv = document.createElement("div");
+ shopDiv.className = "map_label";
+ if (window.innerWidth > 2000) {
+ shopDiv.style.fontSize = "16px";
+ }
+ shopDiv.innerHTML =Map_QM.util.options.shopStyle == "shopName" ? show : mapData.shopArea[i].name;
+ shopDiv.dataset.name = show;
+ shopDiv.dataset.nameEn = showE;
+ shopDiv.style.display = "none";
+ let shopLabel = new THREE.CSS2DObject(shopDiv);
+ shopLabel.position.set(mapData.shopArea[i].xaxis >> 0, (-1 * mapData.shopArea[i].yaxis) >> 0, parseInt(mapData.shopArea[i].toHeight) + parseInt(mapData.shopArea[i].site || 0));
+ shopLabel.name = mapData.shopArea[i].name;
+ shopLabel.userData.mapShow = mapShow; //是否永久显示
+ shopLabel.userData.formatCode = formatCode;
+ shopLabel.userData.isShow = true;
+ this.labelObj.add(shopLabel);
+ }
+ }
+ }
+ }
+ },
+ addTagLabel: function (obj, userData) {
+ let shopDiv = document.createElement("img");
+ shopDiv.src = Map_QM.util.beforPath + "static/img/" + obj.type + ".png";
+ shopDiv.style.zIndex = 30;
+ shopDiv.style.width = "3.125vw";
+ let shopLabel = new THREE.CSS2DObject(shopDiv);
+ shopLabel.userData = userData;
+ shopLabel.userData.mapShow = true; //是否永久显示
+ shopLabel.userData.isShow = false;
+ shopLabel.userData.type = obj.type;
+ shopLabel.position.set(obj.xaxis >> 0, (-1 * obj.yaxis) >> 0, Map_QM.util.shopHeight + 30);
+ this.tagObj.add(shopLabel);
+ },
+ //初始化服务图标
+ initFacilitie: function () {
+ let serArr = Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData.icons;
+ for (let i = 0; i < serArr.length; i++) {
+ if (serArr[i].hasOwnProperty("iShow")) {
+ if (serArr[i].iShow) {
+ serArr[i].floorOrder = this.floorOrder;
+ serArr[i].buildOrder = this.buildOrder;
+ this.facUtil.renderIcon(serArr[i], this);
+ }
+ } else {
+ serArr[i].floorOrder = this.floorOrder;
+ serArr[i].buildOrder = this.buildOrder;
+ this.facUtil.renderIcon(serArr[i], this);
+ }
+ }
+ },
+ //初始化电梯图标
+ initStairs: function () {
+ let facArr = Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData.stairs;
+ for (let i = 0; i < facArr.length; i++) {
+ if (facArr[i].hasOwnProperty("iShow") && !facArr[i].iShow) {
+ continue;
+ }
+ if (facArr[i].facCode == "ft") {
+ if (Map_QM.util.pathStateObj.elevatorDown && Map_QM.util.pathStateObj.elevator && Map_QM.util.options.modelIcon) {
+ if (facArr[i].downState) {
+ //上扶梯
+ let ex = Map_QM.util.pathStateObj.elevator.clone();
+ ex.position.set(facArr[i].x, -1 * facArr[i].y, facArr[i].site || 0);
+ ex.rotation.y = ((facArr[i].angle || 0) * Math.PI) / -180;
+ ex.userData.type = "icon";
+ ex.userData.use = "3d";
+ ex.userData.name = "upft";
+ ex.userData.buildOrder = facArr[i].buildOrder;
+ ex.userData.floorOrder = facArr[i].floorOrder;
+ ex.userData.navCode = facArr[i].navCode;
+ ex.userData.src = "static/img/ft.png";
+ ex.userData.facCode = facArr[i].facCode;
+ ex.userData.title = facArr[i].title;
+ this.serObj.add(ex);
+ facArr[i].facCode = "ft";
+ this.facUtil.renderIcon(facArr[i], this, false, ex);
+ } else if (facArr[i].upState) {
+ //下扶梯
+ let ex = Map_QM.util.pathStateObj.elevatorDown.clone();
+ ex.position.set(facArr[i].x, -1 * facArr[i].y, facArr[i].site || 0);
+ ex.rotation.y = ((facArr[i].angle || 0) * Math.PI) / -180;
+ ex.userData.type = "icon";
+ ex.userData.use = "3d";
+ ex.userData.name = "downft";
+ ex.userData.buildOrder = facArr[i].buildOrder;
+ ex.userData.floorOrder = facArr[i].floorOrder;
+ ex.userData.navCode = facArr[i].navCode;
+ ex.userData.src = "static/img/ft.png";
+ ex.userData.facCode = facArr[i].facCode;
+ ex.userData.title = facArr[i].title;
+ this.serObj.add(ex);
+ facArr[i].facCode = "ft";
+ this.facUtil.renderIcon(facArr[i], this, false, ex);
+ } else {
+ this.facUtil.renderIcon(facArr[i], this, true);
+ }
+ } else {
+ this.facUtil.renderIcon(facArr[i], this, true);
+ }
+ } else if (facArr[i].facCode == "upft") {
+ if (Map_QM.util.pathStateObj.elevator && Map_QM.util.options.modelIcon) {
+ let ex = Map_QM.util.pathStateObj.elevator.clone();
+ ex.position.set(facArr[i].x, -1 * facArr[i].y, facArr[i].site || 0);
+ ex.rotation.y = ((facArr[i].angle || 0) * Math.PI) / -180;
+ ex.userData.type = "icon";
+ ex.userData.use = "3d";
+ ex.userData.name = "upft";
+ ex.userData.buildOrder = facArr[i].buildOrder;
+ ex.userData.floorOrder = facArr[i].floorOrder;
+ ex.userData.navCode = facArr[i].navCode;
+ ex.userData.src = "static/img/ft.png";
+ ex.userData.facCode = facArr[i].facCode;
+ ex.userData.title = facArr[i].title;
+ this.serObj.add(ex);
+ facArr[i].facCode = "ft";
+ this.facUtil.renderIcon(facArr[i], this, false, ex);
+ } else {
+ facArr[i].facCode = "ft";
+ this.facUtil.renderIcon(facArr[i], this, true);
+ }
+ } else if (facArr[i].facCode == "downft") {
+ if (Map_QM.util.pathStateObj.elevatorDown && Map_QM.util.options.modelIcon) {
+ let ex = Map_QM.util.pathStateObj.elevatorDown.clone();
+ ex.position.set(facArr[i].x, -1 * facArr[i].y, facArr[i].site || 0);
+ ex.rotation.y = ((facArr[i].angle || 0) * Math.PI) / -180;
+ ex.userData.type = "icon";
+ ex.userData.use = "3d";
+ ex.userData.name = "downft";
+ ex.userData.buildOrder = facArr[i].buildOrder;
+ ex.userData.floorOrder = facArr[i].floorOrder;
+ ex.userData.navCode = facArr[i].navCode;
+ ex.userData.src = "static/img/ft.png";
+ ex.userData.facCode = facArr[i].facCode;
+ ex.userData.title = facArr[i].title;
+ this.serObj.add(ex);
+ facArr[i].facCode = "ft";
+ this.facUtil.renderIcon(facArr[i], this, false, ex);
+ } else {
+ facArr[i].facCode = "ft";
+ this.facUtil.renderIcon(facArr[i], this, true);
+ }
+ } else if (facArr[i].facCode == "dt") {
+ if (Map_QM.util.pathStateObj.straight && Map_QM.util.options.modelIcon) {
+ let stra = Map_QM.util.pathStateObj.straight.clone();
+ stra.position.set(facArr[i].x, -1 * facArr[i].y, facArr[i].site || 0);
+ stra.rotation.y = ((facArr[i].angle || 0) * Math.PI) / -180;
+ stra.userData.type = "icon";
+ stra.userData.use = "3d";
+ stra.userData.name = "dt";
+ stra.userData.buildOrder = facArr[i].buildOrder;
+ stra.userData.floorOrder = facArr[i].floorOrder;
+ stra.userData.navCode = facArr[i].navCode;
+ stra.userData.src = "static/img/dt.png";
+ stra.userData.facCode = facArr[i].facCode;
+ stra.userData.title = facArr[i].title;
+ this.serObj.add(stra);
+ this.facUtil.renderIcon(facArr[i], this, false, stra);
+ } else {
+ this.facUtil.renderIcon(facArr[i], this, true);
+ }
+ } else {
+ this.facUtil.renderIcon(facArr[i], this, true);
+ }
+ }
+ },
+ //初始化装饰图标
+ initDecos: function () {
+ let mapData = Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData;
+ let sLen = mapData.decos.length;
+ let entColor, borderColor;
+
+ if (mapData.groupArea) {
+ for (let k = 0; k < mapData.groupArea.length; k++) {
+ var gp = new THREE.Group();
+ gp.rotateX((mapData.groupArea[k].angleX * Math.PI) / 180);
+ gp.rotateY((mapData.groupArea[k].angleY * Math.PI) / 180);
+ gp.rotateZ((mapData.groupArea[k].angleZ * Math.PI) / 180);
+ for (let i = 0; i < sLen; i++) {
+ let arr = Map_QM.util.changeAreaToString(mapData.decos[i]);
+ if (mapData.decos[i].gid && mapData.decos[i].gid == mapData.groupArea[k].name && arr.length > 0) {
+ entColor = mapData.decos[i].entColor;
+ borderColor = mapData.decos[i].borderColor;
+ let show = mapData.decos[i].name == "deco" ? "" : mapData.decos[i].name;
+ let hollShop = [];
+ if (mapData.decos[i].hollArea) {
+ for (let k = 0; k < mapData.decos[i].hollArea.length; k++) {
+ hollShop.push(Map_QM.util.changeAreaToString(mapData.decos[i].hollArea[k]));
+ }
+ }
+ let mahc = this.Model_QM.MyModelShape(arr,hollShop,mapData.decos[i],entColor,borderColor,70 + 100 * this.floorOrder);
+ mahc.xaxis = mapData.decos[i].xaxis >> 0;
+ mahc.yaxis = mapData.decos[i].yaxis >> 0;
+ mahc.node = mapData.decos[i].shopNav;
+ mahc.userData = {
+ type: "deco",
+ name: show,
+ };
+ mahc.userData.opacity = mapData.decos[i].alphaModle / 100 || 0;
+ gp.add(mahc);
+ mahc.position.x = -1 * mapData.groupArea[k].xaxis;
+ mahc.position.y = mapData.groupArea[k].yaxis;
+ }
+ }
+ this.floorObj.add(gp);
+ gp.position.x = mapData.groupArea[k].xaxis;
+ gp.position.y = -1 * mapData.groupArea[k].yaxis;
+ gp.position.z = mapData.groupArea[k].site || 0;
+ gp.scale.set(mapData.groupArea[k].scale,mapData.groupArea[k].scale,mapData.groupArea[k].scale);
+ }
+ }
+
+ for (let i = 0; i < sLen; i++) {
+ let arr = Map_QM.util.changeAreaToString(mapData.decos[i]);
+ if (!mapData.decos[i].gid && arr.length > 0) {
+ entColor = mapData.decos[i].entColor;
+ borderColor = mapData.decos[i].borderColor;
+ let show = mapData.decos[i].name == "deco" ? "" : mapData.decos[i].name;
+ let hollShop = [];
+ if (mapData.decos[i].hollArea) {
+ for (let k = 0; k < mapData.decos[i].hollArea.length; k++) {
+ hollShop.push(Map_QM.util.changeAreaToString(mapData.decos[i].hollArea[k]));
+ }
+ }
+ let mahc;
+ mahc = this.Model_QM.MyModelShape(arr,hollShop,mapData.decos[i],entColor,borderColor,70 + 100 * this.floorOrder );
+ mahc.userData = {
+ type: "deco",
+ node: mapData.decos[i].shopNav,
+ xaxis: mapData.decos[i].xaxis,
+ yaxis: mapData.decos[i].yaxis,
+ houseNumber: mahc.name,
+ name: show,
+ };
+ this.floorObj.add(mahc);
+ }
+ }
+ },
+ /**
+ * 渲染墙体
+ */
+ initWall: function () {
+ let mapData = Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData;
+ //渲染
+ if (mapData.wallArea) {
+ let sLen = mapData.wallArea.length;
+ for (let i = 0; i < sLen; i++) {
+ let arr = Map_QM.util.changeWallToString(mapData.wallArea[i]);
+ let mahc = this.Model_QM.MyModelShape(arr, null, mapData.wallArea[i], mapData.wallArea[i].entColor || "#eaeaea", mapData.wallArea[i].borderColor || "#eaeaea", 300);
+ mahc.userData = {
+ type: "wall",
+ };
+ mahc.userData.opacity = mapData.wallArea[i].alphaModle / 100 || 0;
+ this.floorObj.add(mahc);
+ }
+ }
+ },
+ /**
+ * 渲染文本
+ */
+ initTextArea: function () {
+ let mapData = Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData;
+ //渲染
+ if (mapData.svgArea) {
+ let sLen = mapData.svgArea.length;
+ for (let i = 0; i < sLen; i++) {
+ let mahc = this.Model_QM.MyModelText(mapData.svgArea[i]);
+ mahc.userData = {
+ type: "svg",
+ rot: mahc.rotation.z,
+ houseNumber: mapData.svgArea[i].name,
+ };
+ this.svgObj.add(mahc);
+ }
+ }
+ },
+ /**
+ * 设置终点图标
+ */
+ setOverSite: function (shopX, shopY, shopZ) {
+ if (Map_QM.endModel) {
+ Map_QM.endModel.visible = pathCameraState == "2D" ? false : true;
+ Map_QM.endModel.scale.x = Map_QM.endModel.scale.y = Map_QM.endModel.scale.z = 80;
+ Map_QM.endModel.position.set(shopX, shopZ, shopY); //x,z,y
+ Map_QM.endModel.applyMatrix4(Map_QM.sceneGap.matrix);
+ if (Map_QM.endIcon) {
+ Map_QM.endIcon.visible = pathCameraState == "2D" ? true : false;
+ Map_QM.endIcon.scale.x = 100;
+ Map_QM.endIcon.scale.y = 120;
+ Map_QM.endIcon.position.set(shopX, 100, shopY); //x,z,y
+ Map_QM.endIcon.applyMatrix4(Map_QM.sceneGap.matrix);
+ }
+ } else {
+ try {
+ Map_QM.scene.traverse((item) => {
+ if (item.name == "Z-model") {
+ Map_QM.scene.remove(item);
+ }
+ });
+ } catch (e) {
+ window.captureException && window.captureException(e);
+ console.log("traverse");
+ }
+
+ let loader2 = new THREE.GLTFLoader();
+ loader2.load(
+ Map_QM.util.beforPath + "static/img/zhong.glb",
+ function (collada2) {
+ collada2.scene.scale.x = collada2.scene.scale.y = collada2.scene.scale.z = 80;
+ if (shopX != 0 && shopY != 0) {
+ collada2.scene.position.set(shopX, shopZ, shopY); //x,z,y
+ }
+ collada2.scene.applyMatrix4(Map_QM.sceneGap.matrix);
+ collada2.scene.renderOrder = 200;
+ collada2.scene.traverse(function (child) {
+ if (child.type === "Mesh") {
+ child.castShadow = Map_QM.util.options.shadow;
+ child.receiveShadow = Map_QM.util.options.shadow;
+ if (child.material.map) {
+ child.material.map.encoding = THREE.LinearEncoding; //贴图需要转换成 线性编码
+ }
+ if(child.material.roughness && child.material.roughness<0.8){
+ child.material.roughness=0.8;
+ }
+ }
+ });
+ for (let k = 0; k < collada2.animations.length; k++) {
+ let mixer = new THREE.AnimationMixer(collada2.scene);
+ mixer.clipAction(collada2.animations[k]).play();
+ Map_QM.mixers.push(mixer);
+ }
+ collada2.scene.name = "Z-model";
+ Map_QM.endModel = collada2.scene;
+ Map_QM.scene.add(collada2.scene);
+ Map_QM.endModel.visible = pathCameraState == "2D" ? false : true;
+ }
+ );
+ let spriteMap = new THREE.TextureLoader().load(
+ Map_QM.util.beforPath + "static/img/Z.png"
+ );
+ let spriteMaterial = new THREE.SpriteMaterial({
+ //sizeAttenuation: false 禁止跟随鼠标缩放
+ map: spriteMap,
+ depthTest: true,
+ transparent: true,
+ alphaTest: 0.5,
+ });
+ Map_QM.endIcon = new MySprite_QM(spriteMaterial);
+ Map_QM.endIcon.scale.set(100, 120, 1);
+ Map_QM.endIcon.center = new THREE.Vector2(0.5, 0);
+ Map_QM.endIcon.position.set(shopX, 100, shopY);
+ Map_QM.endIcon.applyMatrix4(Map_QM.sceneGap.matrix);
+ Map_QM.endIcon.renderOrder = 300;
+ Map_QM.endIcon.name = "Z-model";
+ Map_QM.endIcon.visible = pathCameraState == "2D" ? true : false;
+ Map_QM.scene.add(Map_QM.endIcon);
+ }
+ },
+ /**
+ * 设置起点图标
+ */
+ setStartSite: function (shopX, shopY, shopZ) {
+ let _this = this;
+ if (Map_QM.qiModel) {
+ Map_QM.devModel.position.set(shopX, -1 * shopY, 20);
+ _this.floorObj.add(Map_QM.devModel);
+ Map_QM.qiModel.position.set(shopX, -1 * shopY, 10);
+ _this.floorObj.add(Map_QM.qiModel);
+ Map_QM.qiIcon.position.set(shopX, -1 * shopY, shopZ);
+ _this.floorObj.add(Map_QM.qiIcon);
+ } else {
+ new THREE.GLTFLoader().load(
+ Map_QM.util.beforPath + "static/img/guide.glb",
+ function (obj) {
+ obj.scene.scale.x = obj.scene.scale.y = obj.scene.scale.z = 80;
+ obj.scene.rotation.x = Math.PI / 2;
+ obj.scene.rotation.y = (Map_QM.util.deviceObj.angle * Math.PI) / -180;
+ obj.scene.traverse(function (child) {
+ if (child.type === "Mesh") {
+ child.castShadow = Map_QM.util.options.shadow;
+ child.receiveShadow = Map_QM.util.options.shadow;
+ if (child.material.map) {
+ child.material.map.encoding = THREE.LinearEncoding; //贴图需要转换成 线性编码
+ }
+ if(child.material.roughness && child.material.roughness<0.8){
+ child.material.roughness=0.8;
+ }
+ }
+ });
+ if (shopX != 0 && shopY != 0) {
+ obj.scene.position.set(shopX, -1 * shopY, 5); //x,z,y
+ }
+ for (let k = 0; k < obj.animations.length; k++) {
+ let mixer = new THREE.AnimationMixer(obj.scene);
+ mixer.clipAction(obj.animations[k]).play();
+ Map_QM.mixers.push(mixer);
+ }
+ Map_QM.devModel = obj.scene;
+ Map_QM.devModel.visible = false;
+ Map_QM.devModel.renderOrder = 160;
+ _this.floorObj.add(Map_QM.devModel);
+ }
+ );
+ new THREE.GLTFLoader().load(Map_QM.util.beforPath + "static/img/qi.glb",
+ function (collada) {
+ collada.scene.scale.x = collada.scene.scale.y = collada.scene.scale.z = 80;
+ collada.scene.rotateX(Math.PI / 2);
+ collada.scene.traverse(function (child) {
+ if (child.type === "Mesh") {
+ child.castShadow = Map_QM.util.options.shadow;
+ child.receiveShadow = Map_QM.util.options.shadow;
+ if (child.material.map) {
+ child.material.map.encoding = THREE.LinearEncoding; //贴图需要转换成 线性编码
+ }
+ if(child.material.roughness && child.material.roughness<0.8){
+ child.material.roughness=0.8;
+ }
+ }
+ });
+ if (shopX != 0 && shopY != 0) {
+ collada.scene.position.set( shopX, -1 * shopY, parseInt(Map_QM.util.buildHeight) + 5); //x,z,y
+ }
+ for (let k = 0; k < collada.animations.length; k++) {
+ let mixer = new THREE.AnimationMixer(collada.scene);
+ mixer.clipAction(collada.animations[k]).play();
+ Map_QM.mixers.push(mixer);
+ }
+ collada.scene.renderOrder = 200;
+ collada.scene.userData.type = "start";
+ Map_QM.qiModel = collada.scene;
+ Map_QM.qiModel.children[0].children[0].visible = false;
+ _this.floorObj.add(collada.scene);
+ //--------------------------------------------------------------
+ let spriteMap = new THREE.TextureLoader().load(
+ Map_QM.util.beforPath + "static/img/Q.png"
+ );
+ let spriteMaterial = new THREE.SpriteMaterial({
+ //sizeAttenuation: false 禁止跟随鼠标缩放
+ map: spriteMap,
+ depthTest: true,
+ transparent: true,
+ alphaTest: 0.5,
+ });
+ Map_QM.qiIcon = new MySprite_QM(spriteMaterial);
+ Map_QM.qiIcon.scale.set(100, 120, 1);
+ Map_QM.qiIcon.center = new THREE.Vector2(0.5, 0);
+ Map_QM.qiIcon.position.set(shopX, -1 * shopY, shopZ + 50);
+ Map_QM.qiIcon.renderOrder = 500;
+ Map_QM.qiIcon.visible = false;
+ Map_QM.qiIcon.userData.type = "start";
+ _this.floorObj.add(Map_QM.qiIcon);
+ }
+ );
+ }
+ },
+ /**
+ * 查找线
+ * @param {Object} startNode
+ * @param {Object} endNode
+ */
+ isNoFindLine: function (startNode, endNode) {
+ let no = false;
+ for (let i = 0; i < startNode.lineArr.length; i++) {
+ if (startNode.lineArr[i].nextNode.id == endNode.id ||startNode.lineArr[i].selfNode.id == endNode.id) {
+ no = true;
+ break;
+ }
+ }
+ return no;
+ },
+ //初始化停车位
+ initPark: function () {
+ let mapData = Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData;
+ //渲染车位
+ if (mapData.parkArea) {
+ let sLen = mapData.parkArea.length;
+ if (sLen > 0) {
+ this.floorObj.add(this.parkObj);
+ }
+ let shapeArr = [],
+ materials = [],
+ parkHeight = 1,
+ borderColor = 0xaaaaaa;
+ for (let i = 0; i < sLen; i++) {
+ let arr = Map_QM.util.changeParkToString(mapData.parkArea[i]);
+ if (arr != "") {
+ parkHeight = Math.max(parseInt(mapData.parkArea[i].toHeight), parkHeight);
+ borderColor = mapData.parkArea[i].borderColor;
+ if (arr.length > 0) {
+ let shape = new THREE.Shape();
+ shape.moveTo(arr[0][0], -1 * arr[0][1]);
+ for (let k = 1; k < arr.length; k++) {
+ shape.lineTo(arr[k][0], -1 * arr[k][1]);
+ }
+ shapeArr.push(shape);
+ let meshMaterial;
+ let color2 = new THREE.Color(mapData.parkArea[i].entColor);
+ for (let e = 0; e < Map_QM.util.parkMaterialArr.length; e++) {
+ if (Map_QM.util.parkMaterialArr[e].color.equals(color2)) {
+ meshMaterial = Map_QM.util.parkMaterialArr[e];
+ }
+ }
+ if (!meshMaterial) {
+ meshMaterial = new THREE.MeshBasicMaterial({
+ color: mapData.parkArea[i].entColor,
+ });
+ Map_QM.util.parkMaterialArr.push(meshMaterial);
+ }
+ materials.push(meshMaterial);
+ if (mapData.parkArea[i].childArea && mapData.parkArea[i].childArea.length > 0) {
+ for (let m = 0; m < mapData.parkArea[i].childArea.length; m++) {
+ let meshMaterial0;
+ if (mapData.parkArea[i].childArea[m].color && mapData.parkArea[i].childArea[m].color != "#FFffff") {
+ let color2 = new THREE.Color(mapData.parkArea[i].childArea[m].color);
+ for (let e = 0; e < Map_QM.util.parkMaterialArr.length; e++) {
+ if (Map_QM.util.parkMaterialArr[e].color.equals(color2)) {
+ meshMaterial0 = Map_QM.util.parkMaterialArr[e];
+ }
+ }
+ if (!meshMaterial0) {
+ meshMaterial0 = new THREE.MeshBasicMaterial({
+ color: mapData.parkArea[i].childArea[m].color,
+ });
+ Map_QM.util.parkMaterialArr.push(meshMaterial0);
+ }
+ } else {
+ meshMaterial0 = meshMaterial;
+ }
+ let ps = mapData.parkArea[i].childArea[m].points;
+ let shape0 = new THREE.Shape();
+ // 设置开始点的位置
+ shape0.moveTo(ps[0].x, -1 * ps[0].y);
+ for (let t = 0; t < ps.length; t++) {
+ shape0.lineTo(ps[t].x, -1 * ps[t].y);
+ }
+ shapeArr.push(shape0);
+ materials.push(meshMaterial0);
+ }
+ }
+ }
+ //显示车位编号
+ if (mapData.parkArea[i].parkNum != "NaN" && i % 18 == 0) {
+ let shopDiv = document.createElement("div");
+ shopDiv.className = "map_label";
+ shopDiv.style.display = "none";
+ shopDiv.textContent = mapData.parkArea[i].parkNum;
+ let shopLabel = new THREE.CSS2DObject(shopDiv);
+ shopLabel.userData.mapShow = true; //是否永久显示
+ shopLabel.name = mapData.parkArea[i].name;
+ shopLabel.position.set(mapData.parkArea[i].xaxis >> 0,(-1 * mapData.parkArea[i].yaxis) >> 0,parseInt(mapData.parkArea[i].toHeight) + 1);
+ this.labelObj.add(shopLabel);
+ }
+ }
+ }
+ let mahc = this.Model_QM.MyParkShape(shapeArr, materials, parkHeight);
+ this.parkObj.add(mahc);
+ }
+ },
+};
+
+/**
+ * 渲染3D模型类
+ * 传入区域点list
+ * 镂空点 howllowArr
+ * 模型对象 options
+ */
+MyModel_QM = function () {
+ this.xaxis = 0;
+ this.yaxis = 0;
+ this.node = 0;
+};
+MyModel_QM.prototype.MyParkShape = function (shapes, materials, toHeight = 5) {
+ let scanGeometry = new THREE.ShapeBufferGeometry(shapes, 1);
+ let material = new THREE.LineBasicMaterial({
+ color: "#aeaeae",
+ }); //材质对象lineColor
+ Map_QM.util.lineBasicMaterialArr.push(material);
+
+ // 创建模型
+ let mesh = new THREE.Mesh(scanGeometry, materials);
+ mesh.position.z = toHeight;
+ mesh.renderOrder = 300;
+ mesh.userData.type = "park";
+
+ let cubeEdges = new THREE.EdgesGeometry(scanGeometry, 60);
+ let cubeLine = new THREE.LineSegments(cubeEdges, material);
+ mesh.add(cubeLine);
+ return mesh;
+};
+
+MyModel_QM.prototype.MyModelShape = function (areaArr,howllowArr,opObj,entityColor = 0xdadada,lineColor = 0xeeeeee,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;
+ let matcolor = new THREE.Color(lineColor);
+ for (let k = 0; k < Map_QM.util.lineBasicMaterialArr.length; k++) {
+ if (Map_QM.util.lineBasicMaterialArr[k].color.equals(matcolor)) {
+ material = Map_QM.util.lineBasicMaterialArr[k];
+ }
+ }
+ if (!material) {
+ material = new THREE.LineBasicMaterial({
+ color: lineColor,
+ opacity: 0.8,
+ transparent: true,
+ }); //材质对象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,
+ options = {
+ depth: parseInt(opObj.toHeight),
+ bevelEnabled: false,
+ curveSegments: 12,
+ bevelThickness: 4,
+ bevelSize: 2,
+ bevelSegments: 8,
+ };
+
+ scanGeometry = new THREE.ExtrudeGeometry(shape, options);
+ let meshColor = new THREE.Color(entityColor);
+ for (let e = 0; e < Map_QM.util.meshMaterialArr.length; e++) {
+ if (Map_QM.util.meshMaterialArr[e].color &&
+ Map_QM.util.meshMaterialArr[e].color.equals(meshColor) &&
+ Map_QM.util.meshMaterialArr[e].opacity == alphaModle &&
+ !Map_QM.util.meshMaterialArr[e].userData.map
+ ) {
+ meshMaterial = Map_QM.util.meshMaterialArr[e];
+ }
+ }
+ if (!meshMaterial) {
+ meshMaterial = new THREE.MeshStandardMaterial({
+ color: entityColor,
+ transparent: true,
+ opacity: alphaModle,
+ side: THREE.DoubleSide,
+ depthTest: true,
+ emissive : 0x000000,
+ roughness:0.8 // 0镜面反射,1漫反射
+ });
+ 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;
+ if (opObj.map == "home") {
+ Map_QM.util.assignUVs(scanGeometry);
+ let mapMaterial, ceMaterial;
+ for (let e = 0; e < Map_QM.util.meshMaterialArr.length; e++) {
+ if (Map_QM.util.meshMaterialArr[e].userData.map == "front" && Map_QM.util.meshMaterialArr[e].opacity == alphaModle) {
+ mapMaterial = Map_QM.util.meshMaterialArr[e];
+ }
+ if (Map_QM.util.meshMaterialArr[e].userData.map == "c50" && Map_QM.util.meshMaterialArr[e].opacity == alphaModle) {
+ ceMaterial = Map_QM.util.meshMaterialArr[e];
+ }
+ }
+ if (!mapMaterial) {
+ let texture = new THREE.TextureLoader().load(Map_QM.util.beforPath + "static/img/map/front.png");
+ texture.wrapS = THREE.ClampToEdgeWrapping;
+ texture.wrapT = THREE.RepeatWrapping;
+ mapMaterial = new THREE.MeshStandardMaterial({
+ color: entityColor,
+ map: texture,
+ transparent: true,
+ opacity: alphaModle,
+ side: THREE.DoubleSide,
+ depthTest: true,
+ emissive : 0x000000,
+ roughness:0.8
+ });
+ mapMaterial.userData.map = "front";
+ Map_QM.util.meshMaterialArr.push(mapMaterial);
+ }
+ if (!ceMaterial) {
+ let texture2 = new THREE.TextureLoader().load(Map_QM.util.beforPath + "static/img/map/c50.png");
+ texture2.wrapS = THREE.RepeatWrapping;
+ texture2.wrapT = THREE.ClampToEdgeWrapping;
+ ceMaterial = new THREE.MeshStandardMaterial({
+ color: entityColor,
+ map: texture2,
+ transparent: true,
+ opacity: alphaModle,
+ side: THREE.DoubleSide,
+ depthTest: true,
+ emissive : 0x000000,
+ roughness:0.8
+ });
+ ceMaterial.userData.map = "c50";
+ Map_QM.util.meshMaterialArr.push(ceMaterial);
+ }
+ mesh = new THREE.Mesh(scanGeometry, [meshMaterial, ceMaterial, mapMaterial,]);
+ } else if (opObj.map) {
+ Map_QM.util.packUv(scanGeometry);
+ let ceMaterial;
+ for (let e = 0; e < Map_QM.util.meshMaterialArr.length; e++) {
+ if (Map_QM.util.meshMaterialArr[e].userData.map == opObj.map && Map_QM.util.meshMaterialArr[e].opacity == alphaModle) {
+ ceMaterial = Map_QM.util.meshMaterialArr[e];
+ }
+ }
+ if (!ceMaterial) {
+ let texture2 = new THREE.TextureLoader().load(Map_QM.util.beforPath + "static/img/map/" + opObj.map + ".png");
+ texture2.wrapS = THREE.RepeatWrapping;
+ texture2.wrapT = THREE.ClampToEdgeWrapping;
+ ceMaterial = new THREE.MeshStandardMaterial({
+ color: entityColor,
+ map: texture2,
+ transparent: true,
+ opacity: alphaModle,
+ side: THREE.DoubleSide,
+ depthTest: true,
+ emissive : 0x000000,
+ roughness:0.8
+ });
+ ceMaterial.userData.map = opObj.map;
+ Map_QM.util.meshMaterialArr.push(ceMaterial);
+ }
+ mesh = new THREE.Mesh(scanGeometry, [meshMaterial, ceMaterial]);
+ } else {
+ mesh = new THREE.Mesh(scanGeometry, meshMaterial);
+ }
+
+ if (opObj.type != "wall") {
+ let cubeEdges = new THREE.EdgesGeometry(scanGeometry, 60);
+ let cubeLine = new THREE.LineSegments(cubeEdges, material);
+ cubeLine.renderOrder = indexOrder - 5;
+ mesh.add(cubeLine);
+ }
+ if (opObj.name != "floor") {
+ mesh.position.z = opObj.site || 0;
+ } else {
+ mesh.position.z = -1 * parseInt(opObj.toHeight) - 1;
+ }
+ mesh.castShadow = true;
+ mesh.renderOrder = indexOrder;
+ mesh.name = opObj.name || "";
+ 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,
+ opacity: 0.8,
+ transparent: true,
+ }); //材质对象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);
+ Map_QM.util.assignUVs(scanGeometry);
+ if (opObj.map) {
+ let texture = new THREE.TextureLoader().load(
+ Map_QM.util.beforPath + "static/img/map/" + opObj.map + ".png"
+ );
+ meshMaterial = new THREE.MeshStandardMaterial({
+ color: entityColor,
+ map: texture,
+ transparent: true,
+ opacity: alphaModle,
+ side: THREE.DoubleSide,
+ depthTest: true,
+ emissive : 0x000000,
+ roughness:0.8
+ });
+ meshMaterial.userData.map = opObj.map;
+ Map_QM.util.meshMaterialArr.push(meshMaterial);
+ } else {
+ for (let e = 0; e < Map_QM.util.meshMaterialArr.length; e++) {
+ let color2 = new THREE.Color(entityColor);
+ if (
+ Map_QM.util.meshMaterialArr[e].color &&
+ Map_QM.util.meshMaterialArr[e].color.equals(color2) &&
+ Map_QM.util.meshMaterialArr[e].opacity == alphaModle &&
+ !Map_QM.util.meshMaterialArr[e].userData.map
+ ) {
+ meshMaterial = Map_QM.util.meshMaterialArr[e];
+ }
+ }
+ if (!meshMaterial) {
+ meshMaterial = new THREE.MeshStandardMaterial({
+ color: entityColor,
+ transparent: true,
+ opacity: alphaModle,
+ side: THREE.DoubleSide,
+ depthTest: true,
+ emissive : 0x000000,
+ roughness:0.8
+ });
+ 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);
+ if(alphaModle<0.05 || alphaModle>0.1){
+ let cubeEdges = new THREE.EdgesGeometry(scanGeometry, 60);
+ let cubeLine = new THREE.LineSegments(cubeEdges, material);
+ cubeLine.renderOrder = indexOrder - 5;
+ mesh.add(cubeLine);
+ }
+
+ if (opObj.name != "floor") {
+ mesh.position.z = parseInt(opObj.toHeight) || 0;
+ }
+ mesh.castShadow = true;
+ mesh.renderOrder = indexOrder;
+ mesh.name = opObj.name || "";
+ return mesh;
+};
+
+MyModel_QM.prototype.MyModelText = function (svgArea) {
+ let text = svgArea.data;
+ const paths = new THREE.SVGLoader().parse(text).paths;
+ const group = new THREE.Group();
+
+ group.position.x = parseInt(svgArea.xaxis);
+ group.position.y = -1 * parseInt(svgArea.yaxis);
+ group.position.z = parseInt(svgArea.site || 0);
+ group.rotateX((parseInt(svgArea.angleZ) * Math.PI) / 180);
+ group.rotateY((parseInt(svgArea.angleY) * Math.PI) / 180);
+ group.rotateZ((parseInt(svgArea.angle) * Math.PI) / 180);
+ group.scale.multiplyScalar(svgArea.scale);
+ group.scale.y *= -1;
+
+ let meshMaterial;
+ for (let e = 0; e < Map_QM.util.meshMaterialArr.length; e++) {
+ let color2 = new THREE.Color().setHex(svgArea.entColor);
+ if (Map_QM.util.meshMaterialArr[e].color &&
+ Map_QM.util.meshMaterialArr[e].color.equals(color2) &&
+ Map_QM.util.meshMaterialArr[e].opacity == svgArea.alphaModle
+ ) {
+ meshMaterial = Map_QM.util.meshMaterialArr[e];
+ }
+ }
+ if (!meshMaterial) {
+ meshMaterial = new THREE.MeshStandardMaterial({
+ color: svgArea.entColor,
+ opacity: parseInt(svgArea.alphaModle) / 100,
+ emissive : 0x000000,
+ roughness:0.8
+ });
+ Map_QM.util.meshMaterialArr.push(meshMaterial);
+ }
+
+ for (let i = 0; i < paths.length; i++) {
+ const path = paths[i];
+ let shapes = path.toShapes(true);
+ const geometry = new THREE.ShapeGeometry(shapes, 8);
+ 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) + 1);
+ group.add(mesh);
+ }
+ return group;
+};
+
+/**
+ * 公共设施
+ */
+var MySprite_QM = function (spriteMaterial, obj = null) {
+ THREE.Sprite.call(this);
+ if (obj) {
+ this.navCode = obj.navCode;
+ this.no = obj.no;
+ this.facCode = obj.facCode;
+ this.floor = obj.floorOrder;
+ this.build = obj.buildOrder;
+ this.site = parseInt(obj.site) || Map_QM.util.shopHeight + 32;
+ }
+ this.imgUrl;
+ this.material = spriteMaterial !== undefined ? spriteMaterial : new SpriteMaterial();
+ //图标跳动
+ this.jumpIcon = function () {
+ let oldZ = this.site;
+ let self = this;
+ TweenMax.fromTo(self.position, 0.5, { z: oldZ }, {z: oldZ + 20, repeat: 1,
+ onComplete: function () {
+ TweenMax.to(self.position, 0.2, { z: oldZ });
+ },
+ }
+ );
+ };
+ this.reSetSite = function () {
+ //重置位置
+ this.position.z = this.site;
+ };
+};
+
+MySprite_QM.prototype = Object.create(THREE.Sprite.prototype);
+MySprite_QM.prototype.constructor = MySprite_QM;
+
+/**
+ * 渲染公共设施
+ */
+var Facilities_QM = function () {
+ this.renderIcon = function (obj, _this, isShow = true, ele = null) {
+ if (obj) {
+ let url = Map_QM.util.beforPath + "static/img/" + obj.facCode + ".png";
+ let name = obj.title;
+ let nameEn = obj.title;
+ 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.iconUrl[i].navFilePath;
+ name = Map_QM.util.iconUrl[i].customFacilityName || Map_QM.util.iconUrl[i].name;
+ nameEn = Map_QM.util.iconUrl[i].customFacilityNameEn || Map_QM.util.iconUrl[i].nameEn;
+ }
+ }
+ }
+ let shopDiv = document.createElement("img");
+ shopDiv.src = url;
+ shopDiv.style.zIndex = 100;
+ shopDiv.style.width = "36px";
+ shopDiv.style.display = isShow ? "block" : "none";
+ shopDiv.dataset.name = name;
+ shopDiv.dataset.src = url;
+ shopDiv.dataset.nameEn = nameEn;
+ shopDiv.dataset.buildOrder = obj.buildOrder;
+ shopDiv.dataset.floorOrder = obj.floorOrder;
+ shopDiv.dataset.facCode = obj.facCode;
+ shopDiv.dataset.node = obj.navCode;
+
+ shopDiv.addEventListener("click", (event) => {
+ /**
+ * @api {事件} icon 点击设施图标
+ * @apiGroup 地图事件
+ * @apiDescription 用户点击设施图标后触发自定义事件
+ * @apiVersion 4.0.0
+ * @apiSampleRequest off
+ *
+ * @apiParamExample 请求示例
+ * Map_QM.addEventListener("icon",onClickIcon,false);
+ */
+ Map_QM.dispatchEvent({
+ type: "icon",
+ data: {
+ buildOrder: event.target.dataset.buildOrder,
+ floorOrder: event.target.dataset.floorOrder,
+ node: event.target.dataset.node,
+ src: event.target.dataset.src,
+ facCode: event.target.dataset.facCode,
+ title: event.target.dataset.name,
+ },
+ });
+ });
+ let shopLabel = new THREE.CSS2DObject(shopDiv);
+ shopLabel.userData.mapShow = true; //是否永久显示
+ shopLabel.userData = obj;
+ shopLabel.userData.name = name;
+ shopLabel.userData.nameEn = nameEn;
+ shopLabel.userData.type = "icon";
+ shopLabel.userData.use = ele ? "2d" : "all";
+ shopLabel.userData.model = ele;
+ shopLabel.userData.src = url;
+ shopLabel.userData.isShow = true;
+ shopLabel.position.set(obj.x, -1*obj.y, Math.max(30, parseInt(obj.site) || 0));
+ _this.serObj.add(shopLabel);
+
+ if (Map_QM.util.options.iconName) {
+ let titleDiv = document.createElement("div");
+ titleDiv.className = "map_label";
+ if (window.innerWidth > 2000) {
+ titleDiv.style.fontSize = "16px";
+ }
+ titleDiv.innerText = name;
+ titleDiv.dataset.name = name;
+ titleDiv.dataset.nameEn = nameEn;
+ titleDiv.style.zIndex = 480;
+ let shopLabel = new THREE.CSS2DObject(titleDiv);
+ shopLabel.position.set(obj.x, -1 * obj.y, parseInt(obj.site) + 85);
+ shopLabel.userData.mapShow = true;
+ shopLabel.userData.isShow = true;
+ _this.labelObj.add(shopLabel);
+ }
+ }
+ };
+};
+/**
+ * 店铺LOGO地图展示类
+ */
+var ShopLogo_QM = function () {
+ this.renderIcon = function (obj, _this, z) {
+ if (obj) {
+ let x = obj.xaxis >> 0;
+ let y = (-1 * obj.yaxis) >> 0;
+ let imgW = obj.imgW >> 0;
+ let imgH = obj.imgH >> 0;
+
+ new THREE.TextureLoader().load(obj.logoUrl, (textu) => {
+ let planeMaterial = new THREE.MeshStandardMaterial({
+ map: textu,
+ depthTest: true,
+ transparent: true,
+ alphaTest: 0.01,
+ emissive : 0x000000,
+ roughness:0.8,
+ alphaTest: 0.5,
+ });
+ let planeGeometry = new THREE.PlaneGeometry(imgW, imgH);
+ let plane = new THREE.Mesh(planeGeometry, planeMaterial);
+ plane.center = new THREE.Vector2(0, 0);
+ plane.position.set(x, y, obj.site || z);
+ plane.userData.rot = 0;
+ plane.userData.type = "logo";
+ plane.renderOrder = 70;
+ _this.add(plane);
+ });
+ }
+ };
+};
+
+var _selfFindPath;
+var FindPath_QM = function () {
+ this.pathArr = [];
+ this.lineDashed;
+ this.lineDashed_old;
+ //路线指引箭头皮肤
+ this.planeGeometry = new THREE.PlaneGeometry(128, 128);
+ this.morePath = false;
+ this.stop = null;
+ this._index = 0; //寻路用
+ this.pathState = "init";
+ this.pathPlay = {
+ _isPlay: false,
+ get isPlay() {
+ return this._isPlay;
+ },
+ set isPlay(val) {
+ this._isPlay = val;
+ if (_selfFindPath && _selfFindPath.stop) {
+ window.cancelAnimationFrame(_selfFindPath.stop);
+ _selfFindPath.stop = null;
+ }
+ if (_selfFindPath && _selfFindPath.pathState == "isPlay" && _selfFindPath._index < _selfFindPath.pathArr.length) {
+ _selfFindPath.playMoveGuide();
+ }
+ },
+ };
+};
+
+FindPath_QM.prototype.clearPath = function (build,floor) {
+ this.pathArr = [];
+ if (this.lineDashed) {
+ if (Map_QM.mapArr[build][floor]) {
+ Map_QM.mapArr[build][floor].floorObj.remove(this.lineDashed);
+ }
+ this.lineDashed.destroy();
+ this.lineDashed = null;
+ }
+ if (this.lineDashed_old) {
+ if (Map_QM.mapArr[build][floor]) {
+ Map_QM.mapArr[build][floor].floorObj.remove(this.lineDashed_old);
+ }
+ this.lineDashed_old.destroy();
+ this.lineDashed_old = null;
+ }
+ if (Map_QM.guide) {
+ Map_QM.guide.visible = false;
+ if (Map_QM.mapArr[build][floor]) {
+ Map_QM.mapArr[build][floor].floorObj.remove(Map_QM.man_2d);
+ Map_QM.mapArr[build][floor].floorObj.remove(Map_QM.man_3d);
+ }
+ }
+ if (_selfFindPath && _selfFindPath.stop) {
+ window.cancelAnimationFrame(_selfFindPath.stop);
+ }
+ this._index = 0;
+ this.pathState = "init";
+};
+/**
+ * @param {Object} startNade
+ * @param {Object} toNade
+ * @param {Object} callBack 回调函数
+ */
+FindPath_QM.prototype.onFindPathAnimation = function (pathArray,morePath = false,floorOrder = -1) {
+ this.morePath = morePath;
+ if (pathArray && pathArray.length > 0) {
+ this.pathState = "isPlay";
+ this._index = 0;
+ this.pathArr = [];
+ if (floorOrder === -1) {
+ floorOrder = Map_QM.util.selectFloor;
+ }
+ if (morePath) {
+ for (let j = 0; j < pathArray.length; j++) {
+ this.drawPath(floorOrder,pathArray[j], parseInt(Map_QM.util.buildHeight) + j);
+ }
+ } else {
+ for (let j = 0; j < pathArray.length; j++) {
+ this.pathArr.push(pathArray[j]);
+ }
+ this.drawPath(floorOrder);
+ }
+ }
+};
+
+FindPath_QM.prototype.drawPath = function (floorOrder, pathArr = null, height = 1) {
+ let linePath = [];
+ if (!pathArr) {
+ for (let i = 0; i < this.pathArr.length; i++) {
+ if (i < this.pathArr.length) {
+ linePath.push([this.pathArr[i].x, -1 * this.pathArr[i].y]);
+ }
+ }
+ } else {
+ for (let i = 0; i < pathArr.length; i++) {
+ if (i < pathArr.length) {
+ linePath.push([pathArr[i].x, -1 * pathArr[i].y]);
+ }
+ }
+ }
+ if (this.morePath) {
+ this.lineDashed_old = new PathLine(12,linePath,height,Map_QM.util.options.pathColor,Map_QM.util.options.pathColor2,true);
+ } else if (Map_QM.util.options.shadow) {
+ this.lineDashed_old = new PathLine(12,linePath,parseInt(Map_QM.util.buildHeight) + 1,Map_QM.util.options.pathBgColor,Map_QM.util.options.pathBgColor2,true);
+ } else {
+ this.lineDashed_old = new PathLine(12,linePath,parseInt(Map_QM.util.buildHeight) + 1,Map_QM.util.options.pathColor,Map_QM.util.options.pathColor2,true);
+ }
+ this.lineDashed_old.name = "lineDash";
+ this.lineDashed_old.renderOrder = 128;
+ Map_QM.mapArr[Map_QM.util.selectBuild][floorOrder].floorObj.add(this.lineDashed_old);
+};
+FindPath_QM.prototype.updateClearPath = function () {
+ if (this.lineDashed) {
+ if (Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor]) {
+ Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].floorObj.remove(this.lineDashed);
+ }
+ this.lineDashed.destroy();
+ this.lineDashed = null;
+ }
+};
+FindPath_QM.prototype.updateDrawPath = function () {
+ if (Map_QM.util.options.shadow) {
+ this.updateClearPath();
+ let linePath = [];
+ linePath.push([Map_QM.guide.position.x, Map_QM.guide.position.y]);
+ for (let i = this._index; i < this.pathArr.length; i++) {
+ if (i < this.pathArr.length) {
+ linePath.push([this.pathArr[i].x, -1 * this.pathArr[i].y]);
+ }
+ }
+ 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].floorObj.add(this.lineDashed);
+ }
+};
+
+FindPath_QM.prototype.guidePathPlay = function (paths) {
+ _selfFindPath = this;
+ if (Map_QM.guide) {
+ Map_QM.guide.renderOrder = 99;
+ if (paths.PathPoint) {
+ Map_QM.guide.position.x = paths.PathPoint[0].x;
+ Map_QM.guide.position.y = -1 * paths.PathPoint[0].y;
+ Map_QM.tweenMoveCameraBy2D(paths.PathPoint[0]);
+ Map_QM.man_2d.position.z = parseInt(Map_QM.util.buildHeight) + 120;
+ Map_QM.man_3d.position.z = parseInt(Map_QM.util.buildHeight) + 5;
+ Map_QM.guide.visible = true;
+ Map_QM.mapArr[Map_QM.util.selectBuild][paths.floor].floorObj.add(Map_QM.man_2d);
+ Map_QM.mapArr[Map_QM.util.selectBuild][paths.floor].floorObj.add(Map_QM.man_3d);
+ }
+ }
+ this.pathArr = paths.PathPoint;
+};
+/**
+ * 播放图标指引动画
+ */
+FindPath_QM.prototype.playMoveGuide = function () {
+ if (!Map_QM.guide) {
+ return;
+ }
+ let px = Map_QM.guide.position.x;
+ let py = Map_QM.guide.position.y;
+ let targetX = _selfFindPath.pathArr[_selfFindPath._index].x - px;
+ let targetY = -1 * _selfFindPath.pathArr[_selfFindPath._index].y - py;
+ let dist = Math.sqrt(targetX * targetX + targetY * targetY);
+ let df = Math.ceil(dist / (Map_QM.util.options.playSpeed * Map_QM.util.options.speedMult));
+ let dx = (_selfFindPath.pathArr[_selfFindPath._index].x - px) / df;
+ let dy = (-1 * _selfFindPath.pathArr[_selfFindPath._index].y - py) / df;
+ let ang = 0;
+ if (df < 2) {
+ Map_QM.guide.position.x = _selfFindPath.pathArr[_selfFindPath._index].x;
+ Map_QM.guide.position.y = -1 * _selfFindPath.pathArr[_selfFindPath._index].y;
+ Map_QM.moveCameraBy2D({x: _selfFindPath.pathArr[_selfFindPath._index].x, y: _selfFindPath.pathArr[_selfFindPath._index].y });
+ _selfFindPath._index++;
+ if (_selfFindPath._index > 0 && _selfFindPath._index < _selfFindPath.pathArr.length) {
+ Map_QM.man_3d.rotation.z = Map_QM.man_2d.rotation.z = 0; //180;
+ let s = Math.sqrt(
+ (_selfFindPath.pathArr[_selfFindPath._index].x - _selfFindPath.pathArr[_selfFindPath._index - 1].x) *
+ (_selfFindPath.pathArr[_selfFindPath._index].x - _selfFindPath.pathArr[_selfFindPath._index - 1].x) +
+ (_selfFindPath.pathArr[_selfFindPath._index].y - _selfFindPath.pathArr[_selfFindPath._index - 1].y) *
+ (_selfFindPath.pathArr[_selfFindPath._index].y - _selfFindPath.pathArr[_selfFindPath._index - 1].y)
+ );
+ ang = Math.acos((_selfFindPath.pathArr[_selfFindPath._index].y - _selfFindPath.pathArr[_selfFindPath._index - 1].y) /s);
+ if ( _selfFindPath.pathArr[_selfFindPath._index].x < _selfFindPath.pathArr[_selfFindPath._index - 1].x) {
+ Map_QM.man_3d.rotation.z = Map_QM.man_2d.rotation.z = Math.PI - ang;
+ } else {
+ Map_QM.man_3d.rotation.z = Map_QM.man_2d.rotation.z = Math.PI + ang;
+ }
+ }
+ let pathShop = "";
+ for (let t = 0; t < Map_QM.forShopArr[Map_QM.util._indexPathFloor].wayShop.length; t++) {
+ if (Map_QM.forShopArr[Map_QM.util._indexPathFloor].wayShop[t].pathIndex ==_selfFindPath._index) {
+ let shop_ = Map_QM.forShopArr[Map_QM.util._indexPathFloor].wayShop[t].shop;
+ pathShop = shop_.houseNumber;
+ console.log(Map_QM.util.selectBuild, parseInt(Map_QM.forShopArr[Map_QM.util._indexPathFloor].wayShop[t].shop.floorOrder)); //////////////////////////////////////////////////////////////////
+ let shops = Map_QM.mapArr[Map_QM.util.selectBuild][0].shopObj.children;
+ for (let i = 0; i < shops.length; i++) {
+ let _shop = shops[i].userData.shopData;
+ if (_shop && _shop.houseNumber == pathShop) {
+ let shopModel = shops[i];
+ let material = shopModel.material;
+ shopModel.material = new THREE.MeshBasicMaterial({
+ color: Map_QM.util.options.navColor,
+ });
+ TweenMax.to(shopModel.scale, 0.8, { z: 3, yoyo: true, ease: Cubic.easeIn,
+ onComplete: function () {
+ if (shopModel) {
+ TweenMax.to(shopModel.scale, 0.5, { z: 1 });
+ shopModel.material = material;
+ }
+ },
+ });
+ break;
+ }
+ }
+ break;
+ }
+ }
+ Map_QM.dispatchEvent({
+ //寻路中返回小人当前所在点位
+ type: "PathPlaying",
+ data: { houseNumber: pathShop },
+ });
+ } else {
+ px += dx;
+ py += dy;
+ Map_QM.guide.position.x = px;
+ Map_QM.guide.position.y = py;
+ Map_QM.moveCameraBy2D({ x: px, y: -1 * py });
+ if (!_selfFindPath.morePath) {
+ _selfFindPath.updateDrawPath(); //实时绘制有效路径 await 修是 promise
+ }
+ }
+
+ if (_selfFindPath.pathPlay.isPlay && Map_QM.guide) {
+ if (_selfFindPath._index < _selfFindPath.pathArr.length) {
+ _selfFindPath.stop = requestAnimationFrame(_selfFindPath.playMoveGuide);
+ } else {
+ if (_selfFindPath && _selfFindPath.stop) {
+ window.cancelAnimationFrame(_selfFindPath.stop);
+ _selfFindPath.stop = null;
+ }
+ _selfFindPath.updateClearPath();
+ _selfFindPath._index = 0;
+ if (Map_QM.guide) {
+ Map_QM.guide.visible = false;
+ }
+ let myEvent = new CustomEvent("pathOver", {
+ detail: { dx: dx, dy: dy },
+ });
+ document.dispatchEvent(myEvent); //触发导航完成事件
+ _selfFindPath.pathState = "pathOver";
+ }
+ }
+};
diff --git a/public/qm/three.js b/public/qm/three.js
new file mode 100644
index 0000000..ac6ad67
--- /dev/null
+++ b/public/qm/three.js
@@ -0,0 +1,38009 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+ typeof define === 'function' && define.amd ? define(['exports'], factory) :
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.THREE = {}));
+}(this, (function (exports) { 'use strict';
+ if (Number.EPSILON === undefined) {
+ Number.EPSILON = Math.pow(2, -52);
+ }
+ if (Number.isInteger === undefined) {
+ Number.isInteger = function (value) {
+ return typeof value === 'number' && isFinite(value) && Math.floor(value) === value;
+ };
+ }
+ if (Math.sign === undefined) {
+ Math.sign = function (x) {
+ return x < 0 ? -1 : x > 0 ? 1 : +x;
+ };
+ }
+ if ('name' in Function.prototype === false) {
+ Object.defineProperty(Function.prototype, 'name', {
+ get: function get() {
+ return this.toString().match(/^\s*function\s*([^\(\s]*)/)[1];
+ }
+ });
+ }
+ if (Object.assign === undefined) {
+ Object.assign = function (target) {
+ if (target === undefined || target === null) {
+ throw new TypeError('Cannot convert undefined or null to object');
+ }
+ var output = Object(target);
+ for (var index = 1; index < arguments.length; index++) {
+ var source = arguments[index];
+ if (source !== undefined && source !== null) {
+ for (var nextKey in source) {
+ if (Object.prototype.hasOwnProperty.call(source, nextKey)) {
+ output[nextKey] = source[nextKey];
+ }
+ }
+ }
+ }
+ return output;
+ };
+ }
+ var REVISION = '124dev';
+ var MOUSE = {
+ LEFT: 0,
+ MIDDLE: 1,
+ RIGHT: 2,
+ ROTATE: 0,
+ DOLLY: 1,
+ PAN: 2
+ };
+ var TOUCH = {
+ ROTATE: 0,
+ PAN: 1,
+ DOLLY_PAN: 2,
+ DOLLY_ROTATE: 3
+ };
+ var CullFaceNone = 0;
+ var CullFaceBack = 1;
+ var CullFaceFront = 2;
+ var CullFaceFrontBack = 3;
+ var BasicShadowMap = 0;
+ var PCFShadowMap = 1;
+ var PCFSoftShadowMap = 2;
+ var VSMShadowMap = 3;
+ var FrontSide = 0;
+ var BackSide = 1;
+ var DoubleSide = 2;
+ var FlatShading = 1;
+ var SmoothShading = 2;
+ var NoBlending = 0;
+ var NormalBlending = 1;
+ var AdditiveBlending = 2;
+ var SubtractiveBlending = 3;
+ var MultiplyBlending = 4;
+ var CustomBlending = 5;
+ var AddEquation = 100;
+ var SubtractEquation = 101;
+ var ReverseSubtractEquation = 102;
+ var MinEquation = 103;
+ var MaxEquation = 104;
+ var ZeroFactor = 200;
+ var OneFactor = 201;
+ var SrcColorFactor = 202;
+ var OneMinusSrcColorFactor = 203;
+ var SrcAlphaFactor = 204;
+ var OneMinusSrcAlphaFactor = 205;
+ var DstAlphaFactor = 206;
+ var OneMinusDstAlphaFactor = 207;
+ var DstColorFactor = 208;
+ var OneMinusDstColorFactor = 209;
+ var SrcAlphaSaturateFactor = 210;
+ var NeverDepth = 0;
+ var AlwaysDepth = 1;
+ var LessDepth = 2;
+ var LessEqualDepth = 3;
+ var EqualDepth = 4;
+ var GreaterEqualDepth = 5;
+ var GreaterDepth = 6;
+ var NotEqualDepth = 7;
+ var MultiplyOperation = 0;
+ var MixOperation = 1;
+ var AddOperation = 2;
+ var NoToneMapping = 0;
+ var LinearToneMapping = 1;
+ var ReinhardToneMapping = 2;
+ var CineonToneMapping = 3;
+ var ACESFilmicToneMapping = 4;
+ var CustomToneMapping = 5;
+ var UVMapping = 300;
+ var CubeReflectionMapping = 301;
+ var CubeRefractionMapping = 302;
+ var EquirectangularReflectionMapping = 303;
+ var EquirectangularRefractionMapping = 304;
+ var CubeUVReflectionMapping = 306;
+ var CubeUVRefractionMapping = 307;
+ var RepeatWrapping = 1000;
+ var ClampToEdgeWrapping = 1001;
+ var MirroredRepeatWrapping = 1002;
+ var NearestFilter = 1003;
+ var NearestMipmapNearestFilter = 1004;
+ var NearestMipMapNearestFilter = 1004;
+ var NearestMipmapLinearFilter = 1005;
+ var NearestMipMapLinearFilter = 1005;
+ var LinearFilter = 1006;
+ var LinearMipmapNearestFilter = 1007;
+ var LinearMipMapNearestFilter = 1007;
+ var LinearMipmapLinearFilter = 1008;
+ var LinearMipMapLinearFilter = 1008;
+ var UnsignedByteType = 1009;
+ var ByteType = 1010;
+ var ShortType = 1011;
+ var UnsignedShortType = 1012;
+ var IntType = 1013;
+ var UnsignedIntType = 1014;
+ var FloatType = 1015;
+ var HalfFloatType = 1016;
+ var UnsignedShort4444Type = 1017;
+ var UnsignedShort5551Type = 1018;
+ var UnsignedShort565Type = 1019;
+ var UnsignedInt248Type = 1020;
+ var AlphaFormat = 1021;
+ var RGBFormat = 1022;
+ var RGBAFormat = 1023;
+ var LuminanceFormat = 1024;
+ var LuminanceAlphaFormat = 1025;
+ var RGBEFormat = RGBAFormat;
+ var DepthFormat = 1026;
+ var DepthStencilFormat = 1027;
+ var RedFormat = 1028;
+ var RedIntegerFormat = 1029;
+ var RGFormat = 1030;
+ var RGIntegerFormat = 1031;
+ var RGBIntegerFormat = 1032;
+ var RGBAIntegerFormat = 1033;
+ var RGB_S3TC_DXT1_Format = 33776;
+ var RGBA_S3TC_DXT1_Format = 33777;
+ var RGBA_S3TC_DXT3_Format = 33778;
+ var RGBA_S3TC_DXT5_Format = 33779;
+ var RGB_PVRTC_4BPPV1_Format = 35840;
+ var RGB_PVRTC_2BPPV1_Format = 35841;
+ var RGBA_PVRTC_4BPPV1_Format = 35842;
+ var RGBA_PVRTC_2BPPV1_Format = 35843;
+ var RGB_ETC1_Format = 36196;
+ var RGB_ETC2_Format = 37492;
+ var RGBA_ETC2_EAC_Format = 37496;
+ var RGBA_ASTC_4x4_Format = 37808;
+ var RGBA_ASTC_5x4_Format = 37809;
+ var RGBA_ASTC_5x5_Format = 37810;
+ var RGBA_ASTC_6x5_Format = 37811;
+ var RGBA_ASTC_6x6_Format = 37812;
+ var RGBA_ASTC_8x5_Format = 37813;
+ var RGBA_ASTC_8x6_Format = 37814;
+ var RGBA_ASTC_8x8_Format = 37815;
+ var RGBA_ASTC_10x5_Format = 37816;
+ var RGBA_ASTC_10x6_Format = 37817;
+ var RGBA_ASTC_10x8_Format = 37818;
+ var RGBA_ASTC_10x10_Format = 37819;
+ var RGBA_ASTC_12x10_Format = 37820;
+ var RGBA_ASTC_12x12_Format = 37821;
+ var RGBA_BPTC_Format = 36492;
+ var SRGB8_ALPHA8_ASTC_4x4_Format = 37840;
+ var SRGB8_ALPHA8_ASTC_5x4_Format = 37841;
+ var SRGB8_ALPHA8_ASTC_5x5_Format = 37842;
+ var SRGB8_ALPHA8_ASTC_6x5_Format = 37843;
+ var SRGB8_ALPHA8_ASTC_6x6_Format = 37844;
+ var SRGB8_ALPHA8_ASTC_8x5_Format = 37845;
+ var SRGB8_ALPHA8_ASTC_8x6_Format = 37846;
+ var SRGB8_ALPHA8_ASTC_8x8_Format = 37847;
+ var SRGB8_ALPHA8_ASTC_10x5_Format = 37848;
+ var SRGB8_ALPHA8_ASTC_10x6_Format = 37849;
+ var SRGB8_ALPHA8_ASTC_10x8_Format = 37850;
+ var SRGB8_ALPHA8_ASTC_10x10_Format = 37851;
+ var SRGB8_ALPHA8_ASTC_12x10_Format = 37852;
+ var SRGB8_ALPHA8_ASTC_12x12_Format = 37853;
+ var LoopOnce = 2200;
+ var LoopRepeat = 2201;
+ var LoopPingPong = 2202;
+ var InterpolateDiscrete = 2300;
+ var InterpolateLinear = 2301;
+ var InterpolateSmooth = 2302;
+ var ZeroCurvatureEnding = 2400;
+ var ZeroSlopeEnding = 2401;
+ var WrapAroundEnding = 2402;
+ var NormalAnimationBlendMode = 2500;
+ var AdditiveAnimationBlendMode = 2501;
+ var TrianglesDrawMode = 0;
+ var TriangleStripDrawMode = 1;
+ var TriangleFanDrawMode = 2;
+ var LinearEncoding = 3000;
+ var sRGBEncoding = 3001;
+ var GammaEncoding = 3007;
+ var RGBEEncoding = 3002;
+ var LogLuvEncoding = 3003;
+ var RGBM7Encoding = 3004;
+ var RGBM16Encoding = 3005;
+ var RGBDEncoding = 3006;
+ var BasicDepthPacking = 3200;
+ var RGBADepthPacking = 3201;
+ var TangentSpaceNormalMap = 0;
+ var ObjectSpaceNormalMap = 1;
+ var ZeroStencilOp = 0;
+ var KeepStencilOp = 7680;
+ var ReplaceStencilOp = 7681;
+ var IncrementStencilOp = 7682;
+ var DecrementStencilOp = 7683;
+ var IncrementWrapStencilOp = 34055;
+ var DecrementWrapStencilOp = 34056;
+ var InvertStencilOp = 5386;
+ var NeverStencilFunc = 512;
+ var LessStencilFunc = 513;
+ var EqualStencilFunc = 514;
+ var LessEqualStencilFunc = 515;
+ var GreaterStencilFunc = 516;
+ var NotEqualStencilFunc = 517;
+ var GreaterEqualStencilFunc = 518;
+ var AlwaysStencilFunc = 519;
+ var StaticDrawUsage = 35044;
+ var DynamicDrawUsage = 35048;
+ var StreamDrawUsage = 35040;
+ var StaticReadUsage = 35045;
+ var DynamicReadUsage = 35049;
+ var StreamReadUsage = 35041;
+ var StaticCopyUsage = 35046;
+ var DynamicCopyUsage = 35050;
+ var StreamCopyUsage = 35042;
+ var GLSL1 = '100';
+ var GLSL3 = '300 es';
+ function EventDispatcher() {}
+ Object.assign(EventDispatcher.prototype, {
+ addEventListener: function addEventListener(type, listener) {
+ if (this._listeners === undefined) this._listeners = {};
+ var listeners = this._listeners;
+ if (listeners[type] === undefined) {
+ listeners[type] = [];
+ }
+ if (listeners[type].indexOf(listener) === -1) {
+ listeners[type].push(listener);
+ }
+ },
+ hasEventListener: function hasEventListener(type, listener) {
+ if (this._listeners === undefined) return false;
+ var listeners = this._listeners;
+ return listeners[type] !== undefined && listeners[type].indexOf(listener) !== -1;
+ },
+ removeEventListener: function removeEventListener(type, listener) {
+ if (this._listeners === undefined) return;
+ var listeners = this._listeners;
+ var listenerArray = listeners[type];
+ if (listenerArray !== undefined) {
+ var index = listenerArray.indexOf(listener);
+ if (index !== -1) {
+ listenerArray.splice(index, 1);
+ }
+ }
+ },
+ dispatchEvent: function dispatchEvent(event) {
+ if (this._listeners === undefined) return;
+ var listeners = this._listeners;
+ var listenerArray = listeners[event.type];
+ if (listenerArray !== undefined) {
+ event.target = this;
+ var array = listenerArray.slice(0);
+ for (var i = 0, l = array.length; i < l; i++) {
+ array[i].call(this, event);
+ }
+ }
+ }
+ });
+ var _lut = [];
+ for (var i = 0; i < 256; i++) {
+ _lut[i] = (i < 16 ? '0' : '') + i.toString(16);
+ }
+ var _seed = 1234567;
+ var MathUtils = {
+ DEG2RAD: Math.PI / 180,
+ RAD2DEG: 180 / Math.PI,
+ generateUUID: function generateUUID() {
+ var d0 = Math.random() * 0xffffffff | 0;
+ var d1 = Math.random() * 0xffffffff | 0;
+ var d2 = Math.random() * 0xffffffff | 0;
+ var d3 = Math.random() * 0xffffffff | 0;
+ var uuid = _lut[d0 & 0xff] + _lut[d0 >> 8 & 0xff] + _lut[d0 >> 16 & 0xff] + _lut[d0 >> 24 & 0xff] + '-' + _lut[d1 & 0xff] + _lut[d1 >> 8 & 0xff] + '-' + _lut[d1 >> 16 & 0x0f | 0x40] + _lut[d1 >> 24 & 0xff] + '-' + _lut[d2 & 0x3f | 0x80] + _lut[d2 >> 8 & 0xff] + '-' + _lut[d2 >> 16 & 0xff] + _lut[d2 >> 24 & 0xff] + _lut[d3 & 0xff] + _lut[d3 >> 8 & 0xff] + _lut[d3 >> 16 & 0xff] + _lut[d3 >> 24 & 0xff];
+ return uuid.toUpperCase();
+ },
+ clamp: function clamp(value, min, max) {
+ return Math.max(min, Math.min(max, value));
+ },
+ euclideanModulo: function euclideanModulo(n, m) {
+ return (n % m + m) % m;
+ },
+ mapLinear: function mapLinear(x, a1, a2, b1, b2) {
+ return b1 + (x - a1) * (b2 - b1) / (a2 - a1);
+ },
+ lerp: function lerp(x, y, t) {
+ return (1 - t) * x + t * y;
+ },
+ smoothstep: function smoothstep(x, min, max) {
+ if (x <= min) return 0;
+ if (x >= max) return 1;
+ x = (x - min) / (max - min);
+ return x * x * (3 - 2 * x);
+ },
+ smootherstep: function smootherstep(x, min, max) {
+ if (x <= min) return 0;
+ if (x >= max) return 1;
+ x = (x - min) / (max - min);
+ return x * x * x * (x * (x * 6 - 15) + 10);
+ },
+ randInt: function randInt(low, high) {
+ return low + Math.floor(Math.random() * (high - low + 1));
+ },
+ randFloat: function randFloat(low, high) {
+ return low + Math.random() * (high - low);
+ },
+ randFloatSpread: function randFloatSpread(range) {
+ return range * (0.5 - Math.random());
+ },
+ seededRandom: function seededRandom(s) {
+ if (s !== undefined) _seed = s % 2147483647;
+ _seed = _seed * 16807 % 2147483647;
+ return (_seed - 1) / 2147483646;
+ },
+ degToRad: function degToRad(degrees) {
+ return degrees * MathUtils.DEG2RAD;
+ },
+ radToDeg: function radToDeg(radians) {
+ return radians * MathUtils.RAD2DEG;
+ },
+ isPowerOfTwo: function isPowerOfTwo(value) {
+ return (value & value - 1) === 0 && value !== 0;
+ },
+ ceilPowerOfTwo: function ceilPowerOfTwo(value) {
+ return Math.pow(2, Math.ceil(Math.log(value) / Math.LN2));
+ },
+ floorPowerOfTwo: function floorPowerOfTwo(value) {
+ return Math.pow(2, Math.floor(Math.log(value) / Math.LN2));
+ },
+ setQuaternionFromProperEuler: function setQuaternionFromProperEuler(q, a, b, c, order) {
+ var cos = Math.cos;
+ var sin = Math.sin;
+ var c2 = cos(b / 2);
+ var s2 = sin(b / 2);
+ var c13 = cos((a + c) / 2);
+ var s13 = sin((a + c) / 2);
+ var c1_3 = cos((a - c) / 2);
+ var s1_3 = sin((a - c) / 2);
+ var c3_1 = cos((c - a) / 2);
+ var s3_1 = sin((c - a) / 2);
+ switch (order) {
+ case 'XYX':
+ q.set(c2 * s13, s2 * c1_3, s2 * s1_3, c2 * c13);
+ break;
+ case 'YZY':
+ q.set(s2 * s1_3, c2 * s13, s2 * c1_3, c2 * c13);
+ break;
+ case 'ZXZ':
+ q.set(s2 * c1_3, s2 * s1_3, c2 * s13, c2 * c13);
+ break;
+ case 'XZX':
+ q.set(c2 * s13, s2 * s3_1, s2 * c3_1, c2 * c13);
+ break;
+ case 'YXY':
+ q.set(s2 * c3_1, c2 * s13, s2 * s3_1, c2 * c13);
+ break;
+ case 'ZYZ':
+ q.set(s2 * s3_1, s2 * c3_1, c2 * s13, c2 * c13);
+ break;
+ default:
+ console.warn('THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: ' + order);
+ }
+ }
+ };
+ function _defineProperties(target, props) {
+ for (var i = 0; i < props.length; i++) {
+ var descriptor = props[i];
+ descriptor.enumerable = descriptor.enumerable || false;
+ descriptor.configurable = true;
+ if ("value" in descriptor) descriptor.writable = true;
+ Object.defineProperty(target, descriptor.key, descriptor);
+ }
+ }
+ function _createClass(Constructor, protoProps, staticProps) {
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
+ if (staticProps) _defineProperties(Constructor, staticProps);
+ return Constructor;
+ }
+ function _inheritsLoose(subClass, superClass) {
+ subClass.prototype = Object.create(superClass.prototype);
+ subClass.prototype.constructor = subClass;
+ subClass.__proto__ = superClass;
+ }
+ function _assertThisInitialized(self) {
+ if (self === void 0) {
+ throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
+ }
+ return self;
+ }
+ var Vector2 = /*#__PURE__*/function () {
+ function Vector2(x, y) {
+ if (x === void 0) {
+ x = 0;
+ }
+ if (y === void 0) {
+ y = 0;
+ }
+ Object.defineProperty(this, 'isVector2', {
+ value: true
+ });
+ this.x = x;
+ this.y = y;
+ }
+ var _proto = Vector2.prototype;
+ _proto.set = function set(x, y) {
+ this.x = x;
+ this.y = y;
+ return this;
+ };
+ _proto.setScalar = function setScalar(scalar) {
+ this.x = scalar;
+ this.y = scalar;
+ return this;
+ };
+ _proto.setX = function setX(x) {
+ this.x = x;
+ return this;
+ };
+ _proto.setY = function setY(y) {
+ this.y = y;
+ return this;
+ };
+ _proto.setComponent = function setComponent(index, value) {
+ switch (index) {
+ case 0:
+ this.x = value;
+ break;
+ case 1:
+ this.y = value;
+ break;
+ default:
+ throw new Error('index is out of range: ' + index);
+ }
+ return this;
+ };
+ _proto.getComponent = function getComponent(index) {
+ switch (index) {
+ case 0:
+ return this.x;
+ case 1:
+ return this.y;
+ default:
+ throw new Error('index is out of range: ' + index);
+ }
+ };
+ _proto.clone = function clone() {
+ return new this.constructor(this.x, this.y);
+ };
+ _proto.copy = function copy(v) {
+ this.x = v.x;
+ this.y = v.y;
+ return this;
+ };
+ _proto.add = function add(v, w) {
+ if (w !== undefined) {
+ console.warn('THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.');
+ return this.addVectors(v, w);
+ }
+ this.x += v.x;
+ this.y += v.y;
+ return this;
+ };
+ _proto.addScalar = function addScalar(s) {
+ this.x += s;
+ this.y += s;
+ return this;
+ };
+ _proto.addVectors = function addVectors(a, b) {
+ this.x = a.x + b.x;
+ this.y = a.y + b.y;
+ return this;
+ };
+ _proto.addScaledVector = function addScaledVector(v, s) {
+ this.x += v.x * s;
+ this.y += v.y * s;
+ return this;
+ };
+ _proto.sub = function sub(v, w) {
+ if (w !== undefined) {
+ console.warn('THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.');
+ return this.subVectors(v, w);
+ }
+ this.x -= v.x;
+ this.y -= v.y;
+ return this;
+ };
+ _proto.subScalar = function subScalar(s) {
+ this.x -= s;
+ this.y -= s;
+ return this;
+ };
+ _proto.subVectors = function subVectors(a, b) {
+ this.x = a.x - b.x;
+ this.y = a.y - b.y;
+ return this;
+ };
+ _proto.multiply = function multiply(v) {
+ this.x *= v.x;
+ this.y *= v.y;
+ return this;
+ };
+ _proto.multiplyScalar = function multiplyScalar(scalar) {
+ this.x *= scalar;
+ this.y *= scalar;
+ return this;
+ };
+ _proto.divide = function divide(v) {
+ this.x /= v.x;
+ this.y /= v.y;
+ return this;
+ };
+ _proto.divideScalar = function divideScalar(scalar) {
+ return this.multiplyScalar(1 / scalar);
+ };
+ _proto.applyMatrix3 = function applyMatrix3(m) {
+ var x = this.x,
+ y = this.y;
+ var e = m.elements;
+ this.x = e[0] * x + e[3] * y + e[6];
+ this.y = e[1] * x + e[4] * y + e[7];
+ return this;
+ };
+ _proto.min = function min(v) {
+ this.x = Math.min(this.x, v.x);
+ this.y = Math.min(this.y, v.y);
+ return this;
+ };
+ _proto.max = function max(v) {
+ this.x = Math.max(this.x, v.x);
+ this.y = Math.max(this.y, v.y);
+ return this;
+ };
+ _proto.clamp = function clamp(min, max) {
+ this.x = Math.max(min.x, Math.min(max.x, this.x));
+ this.y = Math.max(min.y, Math.min(max.y, this.y));
+ return this;
+ };
+ _proto.clampScalar = function clampScalar(minVal, maxVal) {
+ this.x = Math.max(minVal, Math.min(maxVal, this.x));
+ this.y = Math.max(minVal, Math.min(maxVal, this.y));
+ return this;
+ };
+ _proto.clampLength = function clampLength(min, max) {
+ var length = this.length();
+ return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length)));
+ };
+ _proto.floor = function floor() {
+ this.x = Math.floor(this.x);
+ this.y = Math.floor(this.y);
+ return this;
+ };
+ _proto.ceil = function ceil() {
+ this.x = Math.ceil(this.x);
+ this.y = Math.ceil(this.y);
+ return this;
+ };
+ _proto.round = function round() {
+ this.x = Math.round(this.x);
+ this.y = Math.round(this.y);
+ return this;
+ };
+ _proto.roundToZero = function roundToZero() {
+ this.x = this.x < 0 ? Math.ceil(this.x) : Math.floor(this.x);
+ this.y = this.y < 0 ? Math.ceil(this.y) : Math.floor(this.y);
+ return this;
+ };
+ _proto.negate = function negate() {
+ this.x = -this.x;
+ this.y = -this.y;
+ return this;
+ };
+ _proto.dot = function dot(v) {
+ return this.x * v.x + this.y * v.y;
+ };
+ _proto.cross = function cross(v) {
+ return this.x * v.y - this.y * v.x;
+ };
+ _proto.lengthSq = function lengthSq() {
+ return this.x * this.x + this.y * this.y;
+ };
+ _proto.length = function length() {
+ return Math.sqrt(this.x * this.x + this.y * this.y);
+ };
+ _proto.manhattanLength = function manhattanLength() {
+ return Math.abs(this.x) + Math.abs(this.y);
+ };
+ _proto.normalize = function normalize() {
+ return this.divideScalar(this.length() || 1);
+ };
+ _proto.angle = function angle() {
+ var angle = Math.atan2(-this.y, -this.x) + Math.PI;
+ return angle;
+ };
+ _proto.distanceTo = function distanceTo(v) {
+ return Math.sqrt(this.distanceToSquared(v));
+ };
+ _proto.distanceToSquared = function distanceToSquared(v) {
+ var dx = this.x - v.x,
+ dy = this.y - v.y;
+ return dx * dx + dy * dy;
+ };
+ _proto.manhattanDistanceTo = function manhattanDistanceTo(v) {
+ return Math.abs(this.x - v.x) + Math.abs(this.y - v.y);
+ };
+ _proto.setLength = function setLength(length) {
+ return this.normalize().multiplyScalar(length);
+ };
+ _proto.lerp = function lerp(v, alpha) {
+ this.x += (v.x - this.x) * alpha;
+ this.y += (v.y - this.y) * alpha;
+ return this;
+ };
+ _proto.lerpVectors = function lerpVectors(v1, v2, alpha) {
+ this.x = v1.x + (v2.x - v1.x) * alpha;
+ this.y = v1.y + (v2.y - v1.y) * alpha;
+ return this;
+ };
+ _proto.equals = function equals(v) {
+ return v.x === this.x && v.y === this.y;
+ };
+ _proto.fromArray = function fromArray(array, offset) {
+ if (offset === void 0) {
+ offset = 0;
+ }
+ this.x = array[offset];
+ this.y = array[offset + 1];
+ return this;
+ };
+ _proto.toArray = function toArray(array, offset) {
+ if (array === void 0) {
+ array = [];
+ }
+ if (offset === void 0) {
+ offset = 0;
+ }
+ array[offset] = this.x;
+ array[offset + 1] = this.y;
+ return array;
+ };
+ _proto.fromBufferAttribute = function fromBufferAttribute(attribute, index, offset) {
+ if (offset !== undefined) {
+ console.warn('THREE.Vector2: offset has been removed from .fromBufferAttribute().');
+ }
+ this.x = attribute.getX(index);
+ this.y = attribute.getY(index);
+ return this;
+ };
+ _proto.rotateAround = function rotateAround(center, angle) {
+ var c = Math.cos(angle),
+ s = Math.sin(angle);
+ var x = this.x - center.x;
+ var y = this.y - center.y;
+ this.x = x * c - y * s + center.x;
+ this.y = x * s + y * c + center.y;
+ return this;
+ };
+ _proto.random = function random() {
+ this.x = Math.random();
+ this.y = Math.random();
+ return this;
+ };
+ _createClass(Vector2, [{
+ key: "width",
+ get: function get() {
+ return this.x;
+ },
+ set: function set(value) {
+ this.x = value;
+ }
+ }, {
+ key: "height",
+ get: function get() {
+ return this.y;
+ },
+ set: function set(value) {
+ this.y = value;
+ }
+ }]);
+ return Vector2;
+ }();
+ var Matrix3 = /*#__PURE__*/function () {
+ function Matrix3() {
+ Object.defineProperty(this, 'isMatrix3', {
+ value: true
+ });
+ this.elements = [1, 0, 0, 0, 1, 0, 0, 0, 1];
+ if (arguments.length > 0) {
+ console.error('THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.');
+ }
+ }
+ var _proto = Matrix3.prototype;
+ _proto.set = function set(n11, n12, n13, n21, n22, n23, n31, n32, n33) {
+ var te = this.elements;
+ te[0] = n11;
+ te[1] = n21;
+ te[2] = n31;
+ te[3] = n12;
+ te[4] = n22;
+ te[5] = n32;
+ te[6] = n13;
+ te[7] = n23;
+ te[8] = n33;
+ return this;
+ };
+ _proto.identity = function identity() {
+ this.set(1, 0, 0, 0, 1, 0, 0, 0, 1);
+ return this;
+ };
+ _proto.clone = function clone() {
+ return new this.constructor().fromArray(this.elements);
+ };
+ _proto.copy = function copy(m) {
+ var te = this.elements;
+ var me = m.elements;
+ te[0] = me[0];
+ te[1] = me[1];
+ te[2] = me[2];
+ te[3] = me[3];
+ te[4] = me[4];
+ te[5] = me[5];
+ te[6] = me[6];
+ te[7] = me[7];
+ te[8] = me[8];
+ return this;
+ };
+ _proto.extractBasis = function extractBasis(xAxis, yAxis, zAxis) {
+ xAxis.setFromMatrix3Column(this, 0);
+ yAxis.setFromMatrix3Column(this, 1);
+ zAxis.setFromMatrix3Column(this, 2);
+ return this;
+ };
+ _proto.setFromMatrix4 = function setFromMatrix4(m) {
+ var me = m.elements;
+ this.set(me[0], me[4], me[8], me[1], me[5], me[9], me[2], me[6], me[10]);
+ return this;
+ };
+ _proto.multiply = function multiply(m) {
+ return this.multiplyMatrices(this, m);
+ };
+ _proto.premultiply = function premultiply(m) {
+ return this.multiplyMatrices(m, this);
+ };
+ _proto.multiplyMatrices = function multiplyMatrices(a, b) {
+ var ae = a.elements;
+ var be = b.elements;
+ var te = this.elements;
+ var a11 = ae[0],
+ a12 = ae[3],
+ a13 = ae[6];
+ var a21 = ae[1],
+ a22 = ae[4],
+ a23 = ae[7];
+ var a31 = ae[2],
+ a32 = ae[5],
+ a33 = ae[8];
+ var b11 = be[0],
+ b12 = be[3],
+ b13 = be[6];
+ var b21 = be[1],
+ b22 = be[4],
+ b23 = be[7];
+ var b31 = be[2],
+ b32 = be[5],
+ b33 = be[8];
+ te[0] = a11 * b11 + a12 * b21 + a13 * b31;
+ te[3] = a11 * b12 + a12 * b22 + a13 * b32;
+ te[6] = a11 * b13 + a12 * b23 + a13 * b33;
+ te[1] = a21 * b11 + a22 * b21 + a23 * b31;
+ te[4] = a21 * b12 + a22 * b22 + a23 * b32;
+ te[7] = a21 * b13 + a22 * b23 + a23 * b33;
+ te[2] = a31 * b11 + a32 * b21 + a33 * b31;
+ te[5] = a31 * b12 + a32 * b22 + a33 * b32;
+ te[8] = a31 * b13 + a32 * b23 + a33 * b33;
+ return this;
+ };
+ _proto.multiplyScalar = function multiplyScalar(s) {
+ var te = this.elements;
+ te[0] *= s;
+ te[3] *= s;
+ te[6] *= s;
+ te[1] *= s;
+ te[4] *= s;
+ te[7] *= s;
+ te[2] *= s;
+ te[5] *= s;
+ te[8] *= s;
+ return this;
+ };
+ _proto.determinant = function determinant() {
+ var te = this.elements;
+ var a = te[0],
+ b = te[1],
+ c = te[2],
+ d = te[3],
+ e = te[4],
+ f = te[5],
+ g = te[6],
+ h = te[7],
+ i = te[8];
+ return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;
+ };
+ _proto.invert = function invert() {
+ var te = this.elements,
+ n11 = te[0],
+ n21 = te[1],
+ n31 = te[2],
+ n12 = te[3],
+ n22 = te[4],
+ n32 = te[5],
+ n13 = te[6],
+ n23 = te[7],
+ n33 = te[8],
+ t11 = n33 * n22 - n32 * n23,
+ t12 = n32 * n13 - n33 * n12,
+ t13 = n23 * n12 - n22 * n13,
+ det = n11 * t11 + n21 * t12 + n31 * t13;
+ if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0);
+ var detInv = 1 / det;
+ te[0] = t11 * detInv;
+ te[1] = (n31 * n23 - n33 * n21) * detInv;
+ te[2] = (n32 * n21 - n31 * n22) * detInv;
+ te[3] = t12 * detInv;
+ te[4] = (n33 * n11 - n31 * n13) * detInv;
+ te[5] = (n31 * n12 - n32 * n11) * detInv;
+ te[6] = t13 * detInv;
+ te[7] = (n21 * n13 - n23 * n11) * detInv;
+ te[8] = (n22 * n11 - n21 * n12) * detInv;
+ return this;
+ };
+ _proto.transpose = function transpose() {
+ var tmp;
+ var m = this.elements;
+ tmp = m[1];
+ m[1] = m[3];
+ m[3] = tmp;
+ tmp = m[2];
+ m[2] = m[6];
+ m[6] = tmp;
+ tmp = m[5];
+ m[5] = m[7];
+ m[7] = tmp;
+ return this;
+ };
+ _proto.getNormalMatrix = function getNormalMatrix(matrix4) {
+ return this.setFromMatrix4(matrix4).copy(this).invert().transpose();
+ };
+ _proto.transposeIntoArray = function transposeIntoArray(r) {
+ var m = this.elements;
+ r[0] = m[0];
+ r[1] = m[3];
+ r[2] = m[6];
+ r[3] = m[1];
+ r[4] = m[4];
+ r[5] = m[7];
+ r[6] = m[2];
+ r[7] = m[5];
+ r[8] = m[8];
+ return this;
+ };
+ _proto.setUvTransform = function setUvTransform(tx, ty, sx, sy, rotation, cx, cy) {
+ var c = Math.cos(rotation);
+ var s = Math.sin(rotation);
+ this.set(sx * c, sx * s, -sx * (c * cx + s * cy) + cx + tx, -sy * s, sy * c, -sy * (-s * cx + c * cy) + cy + ty, 0, 0, 1);
+ return this;
+ };
+ _proto.scale = function scale(sx, sy) {
+ var te = this.elements;
+ te[0] *= sx;
+ te[3] *= sx;
+ te[6] *= sx;
+ te[1] *= sy;
+ te[4] *= sy;
+ te[7] *= sy;
+ return this;
+ };
+ _proto.rotate = function rotate(theta) {
+ var c = Math.cos(theta);
+ var s = Math.sin(theta);
+ var te = this.elements;
+ var a11 = te[0],
+ a12 = te[3],
+ a13 = te[6];
+ var a21 = te[1],
+ a22 = te[4],
+ a23 = te[7];
+ te[0] = c * a11 + s * a21;
+ te[3] = c * a12 + s * a22;
+ te[6] = c * a13 + s * a23;
+ te[1] = -s * a11 + c * a21;
+ te[4] = -s * a12 + c * a22;
+ te[7] = -s * a13 + c * a23;
+ return this;
+ };
+ _proto.translate = function translate(tx, ty) {
+ var te = this.elements;
+ te[0] += tx * te[2];
+ te[3] += tx * te[5];
+ te[6] += tx * te[8];
+ te[1] += ty * te[2];
+ te[4] += ty * te[5];
+ te[7] += ty * te[8];
+ return this;
+ };
+ _proto.equals = function equals(matrix) {
+ var te = this.elements;
+ var me = matrix.elements;
+ for (var i = 0; i < 9; i++) {
+ if (te[i] !== me[i]) return false;
+ }
+ return true;
+ };
+ _proto.fromArray = function fromArray(array, offset) {
+ if (offset === void 0) {
+ offset = 0;
+ }
+ for (var i = 0; i < 9; i++) {
+ this.elements[i] = array[i + offset];
+ }
+ return this;
+ };
+ _proto.toArray = function toArray(array, offset) {
+ if (array === void 0) {
+ array = [];
+ }
+ if (offset === void 0) {
+ offset = 0;
+ }
+ var te = this.elements;
+ array[offset] = te[0];
+ array[offset + 1] = te[1];
+ array[offset + 2] = te[2];
+ array[offset + 3] = te[3];
+ array[offset + 4] = te[4];
+ array[offset + 5] = te[5];
+ array[offset + 6] = te[6];
+ array[offset + 7] = te[7];
+ array[offset + 8] = te[8];
+ return array;
+ };
+ return Matrix3;
+ }();
+ var _canvas;
+ var ImageUtils = {
+ getDataURL: function getDataURL(image) {
+ if (/^data:/i.test(image.src)) {
+ return image.src;
+ }
+ if (typeof HTMLCanvasElement == 'undefined') {
+ return image.src;
+ }
+ var canvas;
+ if (image instanceof HTMLCanvasElement) {
+ canvas = image;
+ } else {
+ if (_canvas === undefined) _canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas');
+ _canvas.width = image.width;
+ _canvas.height = image.height;
+ var context = _canvas.getContext('2d');
+ if (image instanceof ImageData) {
+ context.putImageData(image, 0, 0);
+ } else {
+ context.drawImage(image, 0, 0, image.width, image.height);
+ }
+ canvas = _canvas;
+ }
+ if (canvas.width > 2048 || canvas.height > 2048) {
+ return canvas.toDataURL('image/jpeg', 0.6);
+ } else {
+ return canvas.toDataURL('image/png');
+ }
+ }
+ };
+ var textureId = 0;
+ function Texture(image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding) {
+ if (image === void 0) {
+ image = Texture.DEFAULT_IMAGE;
+ }
+ if (mapping === void 0) {
+ mapping = Texture.DEFAULT_MAPPING;
+ }
+ if (wrapS === void 0) {
+ wrapS = ClampToEdgeWrapping;
+ }
+ if (wrapT === void 0) {
+ wrapT = ClampToEdgeWrapping;
+ }
+ if (magFilter === void 0) {
+ magFilter = LinearFilter;
+ }
+ if (minFilter === void 0) {
+ minFilter = LinearMipmapLinearFilter;
+ }
+ if (format === void 0) {
+ format = RGBAFormat;
+ }
+ if (type === void 0) {
+ type = UnsignedByteType;
+ }
+ if (anisotropy === void 0) {
+ anisotropy = 1;
+ }
+ if (encoding === void 0) {
+ encoding = LinearEncoding;
+ }
+ Object.defineProperty(this, 'id', {
+ value: textureId++
+ });
+ this.uuid = MathUtils.generateUUID();
+ this.name = '';
+ this.image = image;
+ this.mipmaps = [];
+ this.mapping = mapping;
+ this.wrapS = wrapS;
+ this.wrapT = wrapT;
+ this.magFilter = magFilter;
+ this.minFilter = minFilter;
+ this.anisotropy = anisotropy;
+ this.format = format;
+ this.internalFormat = null;
+ this.type = type;
+ this.offset = new Vector2(0, 0);
+ this.repeat = new Vector2(1, 1);
+ this.center = new Vector2(0, 0);
+ this.rotation = 0;
+ this.matrixAutoUpdate = true;
+ this.matrix = new Matrix3();
+ this.generateMipmaps = true;
+ this.premultiplyAlpha = false;
+ this.flipY = true;
+ this.unpackAlignment = 4;
+ this.encoding = encoding;
+ this.version = 0;
+ this.onUpdate = null;
+ }
+ Texture.DEFAULT_IMAGE = undefined;
+ Texture.DEFAULT_MAPPING = UVMapping;
+ Texture.prototype = Object.assign(Object.create(EventDispatcher.prototype), {
+ constructor: Texture,
+ isTexture: true,
+ updateMatrix: function updateMatrix() {
+ this.matrix.setUvTransform(this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y);
+ },
+ clone: function clone() {
+ return new this.constructor().copy(this);
+ },
+ copy: function copy(source) {
+ this.name = source.name;
+ this.image = source.image;
+ this.mipmaps = source.mipmaps.slice(0);
+ this.mapping = source.mapping;
+ this.wrapS = source.wrapS;
+ this.wrapT = source.wrapT;
+ this.magFilter = source.magFilter;
+ this.minFilter = source.minFilter;
+ this.anisotropy = source.anisotropy;
+ this.format = source.format;
+ this.internalFormat = source.internalFormat;
+ this.type = source.type;
+ this.offset.copy(source.offset);
+ this.repeat.copy(source.repeat);
+ this.center.copy(source.center);
+ this.rotation = source.rotation;
+ this.matrixAutoUpdate = source.matrixAutoUpdate;
+ this.matrix.copy(source.matrix);
+ this.generateMipmaps = source.generateMipmaps;
+ this.premultiplyAlpha = source.premultiplyAlpha;
+ this.flipY = source.flipY;
+ this.unpackAlignment = source.unpackAlignment;
+ this.encoding = source.encoding;
+ return this;
+ },
+ toJSON: function toJSON(meta) {
+ var isRootObject = meta === undefined || typeof meta === 'string';
+ if (!isRootObject && meta.textures[this.uuid] !== undefined) {
+ return meta.textures[this.uuid];
+ }
+ var output = {
+ metadata: {
+ version: 4.5,
+ type: 'Texture',
+ generator: 'Texture.toJSON'
+ },
+ uuid: this.uuid,
+ name: this.name,
+ mapping: this.mapping,
+ repeat: [this.repeat.x, this.repeat.y],
+ offset: [this.offset.x, this.offset.y],
+ center: [this.center.x, this.center.y],
+ rotation: this.rotation,
+ wrap: [this.wrapS, this.wrapT],
+ format: this.format,
+ type: this.type,
+ encoding: this.encoding,
+ minFilter: this.minFilter,
+ magFilter: this.magFilter,
+ anisotropy: this.anisotropy,
+ flipY: this.flipY,
+ premultiplyAlpha: this.premultiplyAlpha,
+ unpackAlignment: this.unpackAlignment
+ };
+ if (this.image !== undefined) {
+ var image = this.image;
+ if (image.uuid === undefined) {
+ image.uuid = MathUtils.generateUUID();
+ }
+ if (!isRootObject && meta.images[image.uuid] === undefined) {
+ var url;
+ if (Array.isArray(image)) {
+ url = [];
+ for (var i = 0, l = image.length; i < l; i++) {
+ if (image[i].isDataTexture) {
+ url.push(serializeImage(image[i].image));
+ } else {
+ url.push(serializeImage(image[i]));
+ }
+ }
+ } else {
+ url = serializeImage(image);
+ }
+ meta.images[image.uuid] = {
+ uuid: image.uuid,
+ url: url
+ };
+ }
+ output.image = image.uuid;
+ }
+ if (!isRootObject) {
+ meta.textures[this.uuid] = output;
+ }
+ return output;
+ },
+ dispose: function dispose() {
+ this.dispatchEvent({
+ type: 'dispose'
+ });
+ },
+ transformUv: function transformUv(uv) {
+ if (this.mapping !== UVMapping) return uv;
+ uv.applyMatrix3(this.matrix);
+ if (uv.x < 0 || uv.x > 1) {
+ switch (this.wrapS) {
+ case RepeatWrapping:
+ uv.x = uv.x - Math.floor(uv.x);
+ break;
+ case ClampToEdgeWrapping:
+ uv.x = uv.x < 0 ? 0 : 1;
+ break;
+ case MirroredRepeatWrapping:
+ if (Math.abs(Math.floor(uv.x) % 2) === 1) {
+ uv.x = Math.ceil(uv.x) - uv.x;
+ } else {
+ uv.x = uv.x - Math.floor(uv.x);
+ }
+ break;
+ }
+ }
+ if (uv.y < 0 || uv.y > 1) {
+ switch (this.wrapT) {
+ case RepeatWrapping:
+ uv.y = uv.y - Math.floor(uv.y);
+ break;
+ case ClampToEdgeWrapping:
+ uv.y = uv.y < 0 ? 0 : 1;
+ break;
+ case MirroredRepeatWrapping:
+ if (Math.abs(Math.floor(uv.y) % 2) === 1) {
+ uv.y = Math.ceil(uv.y) - uv.y;
+ } else {
+ uv.y = uv.y - Math.floor(uv.y);
+ }
+ break;
+ }
+ }
+ if (this.flipY) {
+ uv.y = 1 - uv.y;
+ }
+ return uv;
+ }
+ });
+ Object.defineProperty(Texture.prototype, 'needsUpdate', {
+ set: function set(value) {
+ if (value === true) this.version++;
+ }
+ });
+ function serializeImage(image) {
+ if (typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap) {
+ return ImageUtils.getDataURL(image);
+ } else {
+ if (image.data) {
+ return {
+ data: Array.prototype.slice.call(image.data),
+ width: image.width,
+ height: image.height,
+ type: image.data.constructor.name
+ };
+ } else {
+ console.warn('THREE.Texture: Unable to serialize Texture.');
+ return {};
+ }
+ }
+ }
+ var Vector4 = /*#__PURE__*/function () {
+ function Vector4(x, y, z, w) {
+ if (x === void 0) {
+ x = 0;
+ }
+ if (y === void 0) {
+ y = 0;
+ }
+ if (z === void 0) {
+ z = 0;
+ }
+ if (w === void 0) {
+ w = 1;
+ }
+ Object.defineProperty(this, 'isVector4', {
+ value: true
+ });
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ this.w = w;
+ }
+ var _proto = Vector4.prototype;
+ _proto.set = function set(x, y, z, w) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ this.w = w;
+ return this;
+ };
+ _proto.setScalar = function setScalar(scalar) {
+ this.x = scalar;
+ this.y = scalar;
+ this.z = scalar;
+ this.w = scalar;
+ return this;
+ };
+ _proto.setX = function setX(x) {
+ this.x = x;
+ return this;
+ };
+ _proto.setY = function setY(y) {
+ this.y = y;
+ return this;
+ };
+ _proto.setZ = function setZ(z) {
+ this.z = z;
+ return this;
+ };
+ _proto.setW = function setW(w) {
+ this.w = w;
+ return this;
+ };
+ _proto.setComponent = function setComponent(index, value) {
+ switch (index) {
+ case 0:
+ this.x = value;
+ break;
+ case 1:
+ this.y = value;
+ break;
+ case 2:
+ this.z = value;
+ break;
+ case 3:
+ this.w = value;
+ break;
+ default:
+ throw new Error('index is out of range: ' + index);
+ }
+ return this;
+ };
+ _proto.getComponent = function getComponent(index) {
+ switch (index) {
+ case 0:
+ return this.x;
+ case 1:
+ return this.y;
+ case 2:
+ return this.z;
+ case 3:
+ return this.w;
+ default:
+ throw new Error('index is out of range: ' + index);
+ }
+ };
+ _proto.clone = function clone() {
+ return new this.constructor(this.x, this.y, this.z, this.w);
+ };
+ _proto.copy = function copy(v) {
+ this.x = v.x;
+ this.y = v.y;
+ this.z = v.z;
+ this.w = v.w !== undefined ? v.w : 1;
+ return this;
+ };
+ _proto.add = function add(v, w) {
+ if (w !== undefined) {
+ console.warn('THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.');
+ return this.addVectors(v, w);
+ }
+ this.x += v.x;
+ this.y += v.y;
+ this.z += v.z;
+ this.w += v.w;
+ return this;
+ };
+ _proto.addScalar = function addScalar(s) {
+ this.x += s;
+ this.y += s;
+ this.z += s;
+ this.w += s;
+ return this;
+ };
+ _proto.addVectors = function addVectors(a, b) {
+ this.x = a.x + b.x;
+ this.y = a.y + b.y;
+ this.z = a.z + b.z;
+ this.w = a.w + b.w;
+ return this;
+ };
+ _proto.addScaledVector = function addScaledVector(v, s) {
+ this.x += v.x * s;
+ this.y += v.y * s;
+ this.z += v.z * s;
+ this.w += v.w * s;
+ return this;
+ };
+ _proto.sub = function sub(v, w) {
+ if (w !== undefined) {
+ console.warn('THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.');
+ return this.subVectors(v, w);
+ }
+ this.x -= v.x;
+ this.y -= v.y;
+ this.z -= v.z;
+ this.w -= v.w;
+ return this;
+ };
+ _proto.subScalar = function subScalar(s) {
+ this.x -= s;
+ this.y -= s;
+ this.z -= s;
+ this.w -= s;
+ return this;
+ };
+ _proto.subVectors = function subVectors(a, b) {
+ this.x = a.x - b.x;
+ this.y = a.y - b.y;
+ this.z = a.z - b.z;
+ this.w = a.w - b.w;
+ return this;
+ };
+ _proto.multiplyScalar = function multiplyScalar(scalar) {
+ this.x *= scalar;
+ this.y *= scalar;
+ this.z *= scalar;
+ this.w *= scalar;
+ return this;
+ };
+ _proto.applyMatrix4 = function applyMatrix4(m) {
+ var x = this.x,
+ y = this.y,
+ z = this.z,
+ w = this.w;
+ var e = m.elements;
+ this.x = e[0] * x + e[4] * y + e[8] * z + e[12] * w;
+ this.y = e[1] * x + e[5] * y + e[9] * z + e[13] * w;
+ this.z = e[2] * x + e[6] * y + e[10] * z + e[14] * w;
+ this.w = e[3] * x + e[7] * y + e[11] * z + e[15] * w;
+ return this;
+ };
+ _proto.divideScalar = function divideScalar(scalar) {
+ return this.multiplyScalar(1 / scalar);
+ };
+ _proto.setAxisAngleFromQuaternion = function setAxisAngleFromQuaternion(q) {
+ this.w = 2 * Math.acos(q.w);
+ var s = Math.sqrt(1 - q.w * q.w);
+ if (s < 0.0001) {
+ this.x = 1;
+ this.y = 0;
+ this.z = 0;
+ } else {
+ this.x = q.x / s;
+ this.y = q.y / s;
+ this.z = q.z / s;
+ }
+ return this;
+ };
+ _proto.setAxisAngleFromRotationMatrix = function setAxisAngleFromRotationMatrix(m) {
+ var angle, x, y, z;
+ var epsilon = 0.01,
+ epsilon2 = 0.1,
+ te = m.elements,
+ m11 = te[0],
+ m12 = te[4],
+ m13 = te[8],
+ m21 = te[1],
+ m22 = te[5],
+ m23 = te[9],
+ m31 = te[2],
+ m32 = te[6],
+ m33 = te[10];
+ if (Math.abs(m12 - m21) < epsilon && Math.abs(m13 - m31) < epsilon && Math.abs(m23 - m32) < epsilon) {
+ if (Math.abs(m12 + m21) < epsilon2 && Math.abs(m13 + m31) < epsilon2 && Math.abs(m23 + m32) < epsilon2 && Math.abs(m11 + m22 + m33 - 3) < epsilon2) {
+ this.set(1, 0, 0, 0);
+ return this;
+ }
+ angle = Math.PI;
+ var xx = (m11 + 1) / 2;
+ var yy = (m22 + 1) / 2;
+ var zz = (m33 + 1) / 2;
+ var xy = (m12 + m21) / 4;
+ var xz = (m13 + m31) / 4;
+ var yz = (m23 + m32) / 4;
+ if (xx > yy && xx > zz) {
+ if (xx < epsilon) {
+ x = 0;
+ y = 0.707106781;
+ z = 0.707106781;
+ } else {
+ x = Math.sqrt(xx);
+ y = xy / x;
+ z = xz / x;
+ }
+ } else if (yy > zz) {
+ if (yy < epsilon) {
+ x = 0.707106781;
+ y = 0;
+ z = 0.707106781;
+ } else {
+ y = Math.sqrt(yy);
+ x = xy / y;
+ z = yz / y;
+ }
+ } else {
+ if (zz < epsilon) {
+ x = 0.707106781;
+ y = 0.707106781;
+ z = 0;
+ } else {
+ z = Math.sqrt(zz);
+ x = xz / z;
+ y = yz / z;
+ }
+ }
+ this.set(x, y, z, angle);
+ return this;
+ }
+ var s = Math.sqrt((m32 - m23) * (m32 - m23) + (m13 - m31) * (m13 - m31) + (m21 - m12) * (m21 - m12));
+ if (Math.abs(s) < 0.001) s = 1;
+ this.x = (m32 - m23) / s;
+ this.y = (m13 - m31) / s;
+ this.z = (m21 - m12) / s;
+ this.w = Math.acos((m11 + m22 + m33 - 1) / 2);
+ return this;
+ };
+ _proto.min = function min(v) {
+ this.x = Math.min(this.x, v.x);
+ this.y = Math.min(this.y, v.y);
+ this.z = Math.min(this.z, v.z);
+ this.w = Math.min(this.w, v.w);
+ return this;
+ };
+ _proto.max = function max(v) {
+ this.x = Math.max(this.x, v.x);
+ this.y = Math.max(this.y, v.y);
+ this.z = Math.max(this.z, v.z);
+ this.w = Math.max(this.w, v.w);
+ return this;
+ };
+ _proto.clamp = function clamp(min, max) {
+ this.x = Math.max(min.x, Math.min(max.x, this.x));
+ this.y = Math.max(min.y, Math.min(max.y, this.y));
+ this.z = Math.max(min.z, Math.min(max.z, this.z));
+ this.w = Math.max(min.w, Math.min(max.w, this.w));
+ return this;
+ };
+ _proto.clampScalar = function clampScalar(minVal, maxVal) {
+ this.x = Math.max(minVal, Math.min(maxVal, this.x));
+ this.y = Math.max(minVal, Math.min(maxVal, this.y));
+ this.z = Math.max(minVal, Math.min(maxVal, this.z));
+ this.w = Math.max(minVal, Math.min(maxVal, this.w));
+ return this;
+ };
+ _proto.clampLength = function clampLength(min, max) {
+ var length = this.length();
+ return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length)));
+ };
+ _proto.floor = function floor() {
+ this.x = Math.floor(this.x);
+ this.y = Math.floor(this.y);
+ this.z = Math.floor(this.z);
+ this.w = Math.floor(this.w);
+ return this;
+ };
+ _proto.ceil = function ceil() {
+ this.x = Math.ceil(this.x);
+ this.y = Math.ceil(this.y);
+ this.z = Math.ceil(this.z);
+ this.w = Math.ceil(this.w);
+ return this;
+ };
+ _proto.round = function round() {
+ this.x = Math.round(this.x);
+ this.y = Math.round(this.y);
+ this.z = Math.round(this.z);
+ this.w = Math.round(this.w);
+ return this;
+ };
+ _proto.roundToZero = function roundToZero() {
+ this.x = this.x < 0 ? Math.ceil(this.x) : Math.floor(this.x);
+ this.y = this.y < 0 ? Math.ceil(this.y) : Math.floor(this.y);
+ this.z = this.z < 0 ? Math.ceil(this.z) : Math.floor(this.z);
+ this.w = this.w < 0 ? Math.ceil(this.w) : Math.floor(this.w);
+ return this;
+ };
+ _proto.negate = function negate() {
+ this.x = -this.x;
+ this.y = -this.y;
+ this.z = -this.z;
+ this.w = -this.w;
+ return this;
+ };
+ _proto.dot = function dot(v) {
+ return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
+ };
+ _proto.lengthSq = function lengthSq() {
+ return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;
+ };
+ _proto.length = function length() {
+ return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w);
+ };
+ _proto.manhattanLength = function manhattanLength() {
+ return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z) + Math.abs(this.w);
+ };
+ _proto.normalize = function normalize() {
+ return this.divideScalar(this.length() || 1);
+ };
+ _proto.setLength = function setLength(length) {
+ return this.normalize().multiplyScalar(length);
+ };
+ _proto.lerp = function lerp(v, alpha) {
+ this.x += (v.x - this.x) * alpha;
+ this.y += (v.y - this.y) * alpha;
+ this.z += (v.z - this.z) * alpha;
+ this.w += (v.w - this.w) * alpha;
+ return this;
+ };
+ _proto.lerpVectors = function lerpVectors(v1, v2, alpha) {
+ this.x = v1.x + (v2.x - v1.x) * alpha;
+ this.y = v1.y + (v2.y - v1.y) * alpha;
+ this.z = v1.z + (v2.z - v1.z) * alpha;
+ this.w = v1.w + (v2.w - v1.w) * alpha;
+ return this;
+ };
+ _proto.equals = function equals(v) {
+ return v.x === this.x && v.y === this.y && v.z === this.z && v.w === this.w;
+ };
+ _proto.fromArray = function fromArray(array, offset) {
+ if (offset === void 0) {
+ offset = 0;
+ }
+ this.x = array[offset];
+ this.y = array[offset + 1];
+ this.z = array[offset + 2];
+ this.w = array[offset + 3];
+ return this;
+ };
+ _proto.toArray = function toArray(array, offset) {
+ if (array === void 0) {
+ array = [];
+ }
+ if (offset === void 0) {
+ offset = 0;
+ }
+ array[offset] = this.x;
+ array[offset + 1] = this.y;
+ array[offset + 2] = this.z;
+ array[offset + 3] = this.w;
+ return array;
+ };
+ _proto.fromBufferAttribute = function fromBufferAttribute(attribute, index, offset) {
+ if (offset !== undefined) {
+ console.warn('THREE.Vector4: offset has been removed from .fromBufferAttribute().');
+ }
+ this.x = attribute.getX(index);
+ this.y = attribute.getY(index);
+ this.z = attribute.getZ(index);
+ this.w = attribute.getW(index);
+ return this;
+ };
+ _proto.random = function random() {
+ this.x = Math.random();
+ this.y = Math.random();
+ this.z = Math.random();
+ this.w = Math.random();
+ return this;
+ };
+ _createClass(Vector4, [{
+ key: "width",
+ get: function get() {
+ return this.z;
+ },
+ set: function set(value) {
+ this.z = value;
+ }
+ }, {
+ key: "height",
+ get: function get() {
+ return this.w;
+ },
+ set: function set(value) {
+ this.w = value;
+ }
+ }]);
+ return Vector4;
+ }();
+ function WebGLRenderTarget(width, height, options) {
+ this.width = width;
+ this.height = height;
+ this.scissor = new Vector4(0, 0, width, height);
+ this.scissorTest = false;
+ this.viewport = new Vector4(0, 0, width, height);
+ options = options || {};
+ this.texture = new Texture(undefined, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding);
+ this.texture.image = {};
+ this.texture.image.width = width;
+ this.texture.image.height = height;
+ this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false;
+ this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter;
+ this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;
+ this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : false;
+ this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;
+ }
+ WebGLRenderTarget.prototype = Object.assign(Object.create(EventDispatcher.prototype), {
+ constructor: WebGLRenderTarget,
+ isWebGLRenderTarget: true,
+ setSize: function setSize(width, height) {
+ if (this.width !== width || this.height !== height) {
+ this.width = width;
+ this.height = height;
+ this.texture.image.width = width;
+ this.texture.image.height = height;
+ this.dispose();
+ }
+ this.viewport.set(0, 0, width, height);
+ this.scissor.set(0, 0, width, height);
+ },
+ clone: function clone() {
+ return new this.constructor().copy(this);
+ },
+ copy: function copy(source) {
+ this.width = source.width;
+ this.height = source.height;
+ this.viewport.copy(source.viewport);
+ this.texture = source.texture.clone();
+ this.depthBuffer = source.depthBuffer;
+ this.stencilBuffer = source.stencilBuffer;
+ this.depthTexture = source.depthTexture;
+ return this;
+ },
+ dispose: function dispose() {
+ this.dispatchEvent({
+ type: 'dispose'
+ });
+ }
+ });
+ function WebGLMultisampleRenderTarget(width, height, options) {
+ WebGLRenderTarget.call(this, width, height, options);
+ this.samples = 4;
+ }
+ WebGLMultisampleRenderTarget.prototype = Object.assign(Object.create(WebGLRenderTarget.prototype), {
+ constructor: WebGLMultisampleRenderTarget,
+ isWebGLMultisampleRenderTarget: true,
+ copy: function copy(source) {
+ WebGLRenderTarget.prototype.copy.call(this, source);
+ this.samples = source.samples;
+ return this;
+ }
+ });
+ var Quaternion = /*#__PURE__*/function () {
+ function Quaternion(x, y, z, w) {
+ if (x === void 0) {
+ x = 0;
+ }
+ if (y === void 0) {
+ y = 0;
+ }
+ if (z === void 0) {
+ z = 0;
+ }
+ if (w === void 0) {
+ w = 1;
+ }
+ Object.defineProperty(this, 'isQuaternion', {
+ value: true
+ });
+ this._x = x;
+ this._y = y;
+ this._z = z;
+ this._w = w;
+ }
+ Quaternion.slerp = function slerp(qa, qb, qm, t) {
+ return qm.copy(qa).slerp(qb, t);
+ };
+ Quaternion.slerpFlat = function slerpFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t) {
+ var x0 = src0[srcOffset0 + 0],
+ y0 = src0[srcOffset0 + 1],
+ z0 = src0[srcOffset0 + 2],
+ w0 = src0[srcOffset0 + 3];
+ var x1 = src1[srcOffset1 + 0],
+ y1 = src1[srcOffset1 + 1],
+ z1 = src1[srcOffset1 + 2],
+ w1 = src1[srcOffset1 + 3];
+ if (w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1) {
+ var s = 1 - t;
+ var cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,
+ dir = cos >= 0 ? 1 : -1,
+ sqrSin = 1 - cos * cos;
+ if (sqrSin > Number.EPSILON) {
+ var sin = Math.sqrt(sqrSin),
+ len = Math.atan2(sin, cos * dir);
+ s = Math.sin(s * len) / sin;
+ t = Math.sin(t * len) / sin;
+ }
+ var tDir = t * dir;
+ x0 = x0 * s + x1 * tDir;
+ y0 = y0 * s + y1 * tDir;
+ z0 = z0 * s + z1 * tDir;
+ w0 = w0 * s + w1 * tDir;
+ if (s === 1 - t) {
+ var f = 1 / Math.sqrt(x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0);
+ x0 *= f;
+ y0 *= f;
+ z0 *= f;
+ w0 *= f;
+ }
+ }
+ dst[dstOffset] = x0;
+ dst[dstOffset + 1] = y0;
+ dst[dstOffset + 2] = z0;
+ dst[dstOffset + 3] = w0;
+ };
+ Quaternion.multiplyQuaternionsFlat = function multiplyQuaternionsFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1) {
+ var x0 = src0[srcOffset0];
+ var y0 = src0[srcOffset0 + 1];
+ var z0 = src0[srcOffset0 + 2];
+ var w0 = src0[srcOffset0 + 3];
+ var x1 = src1[srcOffset1];
+ var y1 = src1[srcOffset1 + 1];
+ var z1 = src1[srcOffset1 + 2];
+ var w1 = src1[srcOffset1 + 3];
+ dst[dstOffset] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1;
+ dst[dstOffset + 1] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1;
+ dst[dstOffset + 2] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1;
+ dst[dstOffset + 3] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1;
+ return dst;
+ };
+ var _proto = Quaternion.prototype;
+ _proto.set = function set(x, y, z, w) {
+ this._x = x;
+ this._y = y;
+ this._z = z;
+ this._w = w;
+ this._onChangeCallback();
+ return this;
+ };
+ _proto.clone = function clone() {
+ return new this.constructor(this._x, this._y, this._z, this._w);
+ };
+ _proto.copy = function copy(quaternion) {
+ this._x = quaternion.x;
+ this._y = quaternion.y;
+ this._z = quaternion.z;
+ this._w = quaternion.w;
+ this._onChangeCallback();
+ return this;
+ };
+ _proto.setFromEuler = function setFromEuler(euler, update) {
+ if (!(euler && euler.isEuler)) {
+ throw new Error('THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.');
+ }
+ var x = euler._x,
+ y = euler._y,
+ z = euler._z,
+ order = euler._order;
+ var cos = Math.cos;
+ var sin = Math.sin;
+ var c1 = cos(x / 2);
+ var c2 = cos(y / 2);
+ var c3 = cos(z / 2);
+ var s1 = sin(x / 2);
+ var s2 = sin(y / 2);
+ var s3 = sin(z / 2);
+ switch (order) {
+ case 'XYZ':
+ this._x = s1 * c2 * c3 + c1 * s2 * s3;
+ this._y = c1 * s2 * c3 - s1 * c2 * s3;
+ this._z = c1 * c2 * s3 + s1 * s2 * c3;
+ this._w = c1 * c2 * c3 - s1 * s2 * s3;
+ break;
+ case 'YXZ':
+ this._x = s1 * c2 * c3 + c1 * s2 * s3;
+ this._y = c1 * s2 * c3 - s1 * c2 * s3;
+ this._z = c1 * c2 * s3 - s1 * s2 * c3;
+ this._w = c1 * c2 * c3 + s1 * s2 * s3;
+ break;
+ case 'ZXY':
+ this._x = s1 * c2 * c3 - c1 * s2 * s3;
+ this._y = c1 * s2 * c3 + s1 * c2 * s3;
+ this._z = c1 * c2 * s3 + s1 * s2 * c3;
+ this._w = c1 * c2 * c3 - s1 * s2 * s3;
+ break;
+ case 'ZYX':
+ this._x = s1 * c2 * c3 - c1 * s2 * s3;
+ this._y = c1 * s2 * c3 + s1 * c2 * s3;
+ this._z = c1 * c2 * s3 - s1 * s2 * c3;
+ this._w = c1 * c2 * c3 + s1 * s2 * s3;
+ break;
+ case 'YZX':
+ this._x = s1 * c2 * c3 + c1 * s2 * s3;
+ this._y = c1 * s2 * c3 + s1 * c2 * s3;
+ this._z = c1 * c2 * s3 - s1 * s2 * c3;
+ this._w = c1 * c2 * c3 - s1 * s2 * s3;
+ break;
+ case 'XZY':
+ this._x = s1 * c2 * c3 - c1 * s2 * s3;
+ this._y = c1 * s2 * c3 - s1 * c2 * s3;
+ this._z = c1 * c2 * s3 + s1 * s2 * c3;
+ this._w = c1 * c2 * c3 + s1 * s2 * s3;
+ break;
+ default:
+ console.warn('THREE.Quaternion: .setFromEuler() encountered an unknown order: ' + order);
+ }
+ if (update !== false) this._onChangeCallback();
+ return this;
+ };
+ _proto.setFromAxisAngle = function setFromAxisAngle(axis, angle) {
+ var halfAngle = angle / 2,
+ s = Math.sin(halfAngle);
+ this._x = axis.x * s;
+ this._y = axis.y * s;
+ this._z = axis.z * s;
+ this._w = Math.cos(halfAngle);
+ this._onChangeCallback();
+ return this;
+ };
+ _proto.setFromRotationMatrix = function setFromRotationMatrix(m) {
+ var te = m.elements,
+ m11 = te[0],
+ m12 = te[4],
+ m13 = te[8],
+ m21 = te[1],
+ m22 = te[5],
+ m23 = te[9],
+ m31 = te[2],
+ m32 = te[6],
+ m33 = te[10],
+ trace = m11 + m22 + m33;
+ if (trace > 0) {
+ var s = 0.5 / Math.sqrt(trace + 1.0);
+ this._w = 0.25 / s;
+ this._x = (m32 - m23) * s;
+ this._y = (m13 - m31) * s;
+ this._z = (m21 - m12) * s;
+ } else if (m11 > m22 && m11 > m33) {
+ var _s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33);
+ this._w = (m32 - m23) / _s;
+ this._x = 0.25 * _s;
+ this._y = (m12 + m21) / _s;
+ this._z = (m13 + m31) / _s;
+ } else if (m22 > m33) {
+ var _s2 = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33);
+ this._w = (m13 - m31) / _s2;
+ this._x = (m12 + m21) / _s2;
+ this._y = 0.25 * _s2;
+ this._z = (m23 + m32) / _s2;
+ } else {
+ var _s3 = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22);
+ this._w = (m21 - m12) / _s3;
+ this._x = (m13 + m31) / _s3;
+ this._y = (m23 + m32) / _s3;
+ this._z = 0.25 * _s3;
+ }
+ this._onChangeCallback();
+ return this;
+ };
+ _proto.setFromUnitVectors = function setFromUnitVectors(vFrom, vTo) {
+ var EPS = 0.000001;
+ var r = vFrom.dot(vTo) + 1;
+ if (r < EPS) {
+ r = 0;
+ if (Math.abs(vFrom.x) > Math.abs(vFrom.z)) {
+ this._x = -vFrom.y;
+ this._y = vFrom.x;
+ this._z = 0;
+ this._w = r;
+ } else {
+ this._x = 0;
+ this._y = -vFrom.z;
+ this._z = vFrom.y;
+ this._w = r;
+ }
+ } else {
+ this._x = vFrom.y * vTo.z - vFrom.z * vTo.y;
+ this._y = vFrom.z * vTo.x - vFrom.x * vTo.z;
+ this._z = vFrom.x * vTo.y - vFrom.y * vTo.x;
+ this._w = r;
+ }
+ return this.normalize();
+ };
+ _proto.angleTo = function angleTo(q) {
+ return 2 * Math.acos(Math.abs(MathUtils.clamp(this.dot(q), -1, 1)));
+ };
+ _proto.rotateTowards = function rotateTowards(q, step) {
+ var angle = this.angleTo(q);
+ if (angle === 0) return this;
+ var t = Math.min(1, step / angle);
+ this.slerp(q, t);
+ return this;
+ };
+ _proto.identity = function identity() {
+ return this.set(0, 0, 0, 1);
+ };
+ _proto.invert = function invert() {
+ return this.conjugate();
+ };
+ _proto.conjugate = function conjugate() {
+ this._x *= -1;
+ this._y *= -1;
+ this._z *= -1;
+ this._onChangeCallback();
+ return this;
+ };
+ _proto.dot = function dot(v) {
+ return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;
+ };
+ _proto.lengthSq = function lengthSq() {
+ return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;
+ };
+ _proto.length = function length() {
+ return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w);
+ };
+ _proto.normalize = function normalize() {
+ var l = this.length();
+ if (l === 0) {
+ this._x = 0;
+ this._y = 0;
+ this._z = 0;
+ this._w = 1;
+ } else {
+ l = 1 / l;
+ this._x = this._x * l;
+ this._y = this._y * l;
+ this._z = this._z * l;
+ this._w = this._w * l;
+ }
+ this._onChangeCallback();
+ return this;
+ };
+ _proto.multiply = function multiply(q, p) {
+ if (p !== undefined) {
+ console.warn('THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.');
+ return this.multiplyQuaternions(q, p);
+ }
+ return this.multiplyQuaternions(this, q);
+ };
+ _proto.premultiply = function premultiply(q) {
+ return this.multiplyQuaternions(q, this);
+ };
+ _proto.multiplyQuaternions = function multiplyQuaternions(a, b) {
+ var qax = a._x,
+ qay = a._y,
+ qaz = a._z,
+ qaw = a._w;
+ var qbx = b._x,
+ qby = b._y,
+ qbz = b._z,
+ qbw = b._w;
+ this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
+ this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
+ this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
+ this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
+ this._onChangeCallback();
+ return this;
+ };
+ _proto.slerp = function slerp(qb, t) {
+ if (t === 0) return this;
+ if (t === 1) return this.copy(qb);
+ var x = this._x,
+ y = this._y,
+ z = this._z,
+ w = this._w;
+ var cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;
+ if (cosHalfTheta < 0) {
+ this._w = -qb._w;
+ this._x = -qb._x;
+ this._y = -qb._y;
+ this._z = -qb._z;
+ cosHalfTheta = -cosHalfTheta;
+ } else {
+ this.copy(qb);
+ }
+ if (cosHalfTheta >= 1.0) {
+ this._w = w;
+ this._x = x;
+ this._y = y;
+ this._z = z;
+ return this;
+ }
+ var sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta;
+ if (sqrSinHalfTheta <= Number.EPSILON) {
+ var s = 1 - t;
+ this._w = s * w + t * this._w;
+ this._x = s * x + t * this._x;
+ this._y = s * y + t * this._y;
+ this._z = s * z + t * this._z;
+ this.normalize();
+ this._onChangeCallback();
+ return this;
+ }
+ var sinHalfTheta = Math.sqrt(sqrSinHalfTheta);
+ var halfTheta = Math.atan2(sinHalfTheta, cosHalfTheta);
+ var ratioA = Math.sin((1 - t) * halfTheta) / sinHalfTheta,
+ ratioB = Math.sin(t * halfTheta) / sinHalfTheta;
+ this._w = w * ratioA + this._w * ratioB;
+ this._x = x * ratioA + this._x * ratioB;
+ this._y = y * ratioA + this._y * ratioB;
+ this._z = z * ratioA + this._z * ratioB;
+ this._onChangeCallback();
+ return this;
+ };
+ _proto.equals = function equals(quaternion) {
+ return quaternion._x === this._x && quaternion._y === this._y && quaternion._z === this._z && quaternion._w === this._w;
+ };
+ _proto.fromArray = function fromArray(array, offset) {
+ if (offset === void 0) {
+ offset = 0;
+ }
+ this._x = array[offset];
+ this._y = array[offset + 1];
+ this._z = array[offset + 2];
+ this._w = array[offset + 3];
+ this._onChangeCallback();
+ return this;
+ };
+ _proto.toArray = function toArray(array, offset) {
+ if (array === void 0) {
+ array = [];
+ }
+ if (offset === void 0) {
+ offset = 0;
+ }
+ array[offset] = this._x;
+ array[offset + 1] = this._y;
+ array[offset + 2] = this._z;
+ array[offset + 3] = this._w;
+ return array;
+ };
+ _proto.fromBufferAttribute = function fromBufferAttribute(attribute, index) {
+ this._x = attribute.getX(index);
+ this._y = attribute.getY(index);
+ this._z = attribute.getZ(index);
+ this._w = attribute.getW(index);
+ return this;
+ };
+ _proto._onChange = function _onChange(callback) {
+ this._onChangeCallback = callback;
+ return this;
+ };
+ _proto._onChangeCallback = function _onChangeCallback() {};
+ _createClass(Quaternion, [{
+ key: "x",
+ get: function get() {
+ return this._x;
+ },
+ set: function set(value) {
+ this._x = value;
+ this._onChangeCallback();
+ }
+ }, {
+ key: "y",
+ get: function get() {
+ return this._y;
+ },
+ set: function set(value) {
+ this._y = value;
+ this._onChangeCallback();
+ }
+ }, {
+ key: "z",
+ get: function get() {
+ return this._z;
+ },
+ set: function set(value) {
+ this._z = value;
+ this._onChangeCallback();
+ }
+ }, {
+ key: "w",
+ get: function get() {
+ return this._w;
+ },
+ set: function set(value) {
+ this._w = value;
+ this._onChangeCallback();
+ }
+ }]);
+ return Quaternion;
+ }();
+ var Vector3 = /*#__PURE__*/function () {
+ function Vector3(x, y, z) {
+ if (x === void 0) {
+ x = 0;
+ }
+ if (y === void 0) {
+ y = 0;
+ }
+ if (z === void 0) {
+ z = 0;
+ }
+ Object.defineProperty(this, 'isVector3', {
+ value: true
+ });
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+ var _proto = Vector3.prototype;
+ _proto.set = function set(x, y, z) {
+ if (z === undefined) z = this.z;
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ return this;
+ };
+ _proto.setScalar = function setScalar(scalar) {
+ this.x = scalar;
+ this.y = scalar;
+ this.z = scalar;
+ return this;
+ };
+ _proto.setX = function setX(x) {
+ this.x = x;
+ return this;
+ };
+ _proto.setY = function setY(y) {
+ this.y = y;
+ return this;
+ };
+ _proto.setZ = function setZ(z) {
+ this.z = z;
+ return this;
+ };
+ _proto.setComponent = function setComponent(index, value) {
+ switch (index) {
+ case 0:
+ this.x = value;
+ break;
+ case 1:
+ this.y = value;
+ break;
+ case 2:
+ this.z = value;
+ break;
+ default:
+ throw new Error('index is out of range: ' + index);
+ }
+ return this;
+ };
+ _proto.getComponent = function getComponent(index) {
+ switch (index) {
+ case 0:
+ return this.x;
+ case 1:
+ return this.y;
+ case 2:
+ return this.z;
+ default:
+ throw new Error('index is out of range: ' + index);
+ }
+ };
+ _proto.clone = function clone() {
+ return new this.constructor(this.x, this.y, this.z);
+ };
+ _proto.copy = function copy(v) {
+ this.x = v.x;
+ this.y = v.y;
+ this.z = v.z;
+ return this;
+ };
+ _proto.add = function add(v, w) {
+ if (w !== undefined) {
+ console.warn('THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.');
+ return this.addVectors(v, w);
+ }
+ this.x += v.x;
+ this.y += v.y;
+ this.z += v.z;
+ return this;
+ };
+ _proto.addScalar = function addScalar(s) {
+ this.x += s;
+ this.y += s;
+ this.z += s;
+ return this;
+ };
+ _proto.addVectors = function addVectors(a, b) {
+ this.x = a.x + b.x;
+ this.y = a.y + b.y;
+ this.z = a.z + b.z;
+ return this;
+ };
+ _proto.addScaledVector = function addScaledVector(v, s) {
+ this.x += v.x * s;
+ this.y += v.y * s;
+ this.z += v.z * s;
+ return this;
+ };
+ _proto.sub = function sub(v, w) {
+ if (w !== undefined) {
+ console.warn('THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.');
+ return this.subVectors(v, w);
+ }
+ this.x -= v.x;
+ this.y -= v.y;
+ this.z -= v.z;
+ return this;
+ };
+ _proto.subScalar = function subScalar(s) {
+ this.x -= s;
+ this.y -= s;
+ this.z -= s;
+ return this;
+ };
+ _proto.subVectors = function subVectors(a, b) {
+ this.x = a.x - b.x;
+ this.y = a.y - b.y;
+ this.z = a.z - b.z;
+ return this;
+ };
+ _proto.multiply = function multiply(v, w) {
+ if (w !== undefined) {
+ console.warn('THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.');
+ return this.multiplyVectors(v, w);
+ }
+ this.x *= v.x;
+ this.y *= v.y;
+ this.z *= v.z;
+ return this;
+ };
+ _proto.multiplyScalar = function multiplyScalar(scalar) {
+ this.x *= scalar;
+ this.y *= scalar;
+ this.z *= scalar;
+ return this;
+ };
+ _proto.multiplyVectors = function multiplyVectors(a, b) {
+ this.x = a.x * b.x;
+ this.y = a.y * b.y;
+ this.z = a.z * b.z;
+ return this;
+ };
+ _proto.applyEuler = function applyEuler(euler) {
+ if (!(euler && euler.isEuler)) {
+ console.error('THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.');
+ }
+ return this.applyQuaternion(_quaternion.setFromEuler(euler));
+ };
+ _proto.applyAxisAngle = function applyAxisAngle(axis, angle) {
+ return this.applyQuaternion(_quaternion.setFromAxisAngle(axis, angle));
+ };
+ _proto.applyMatrix3 = function applyMatrix3(m) {
+ var x = this.x,
+ y = this.y,
+ z = this.z;
+ var e = m.elements;
+ this.x = e[0] * x + e[3] * y + e[6] * z;
+ this.y = e[1] * x + e[4] * y + e[7] * z;
+ this.z = e[2] * x + e[5] * y + e[8] * z;
+ return this;
+ };
+ _proto.applyNormalMatrix = function applyNormalMatrix(m) {
+ return this.applyMatrix3(m).normalize();
+ };
+ _proto.applyMatrix4 = function applyMatrix4(m) {
+ var x = this.x,
+ y = this.y,
+ z = this.z;
+ var e = m.elements;
+ var w = 1 / (e[3] * x + e[7] * y + e[11] * z + e[15]);
+ this.x = (e[0] * x + e[4] * y + e[8] * z + e[12]) * w;
+ this.y = (e[1] * x + e[5] * y + e[9] * z + e[13]) * w;
+ this.z = (e[2] * x + e[6] * y + e[10] * z + e[14]) * w;
+ return this;
+ };
+ _proto.applyQuaternion = function applyQuaternion(q) {
+ var x = this.x,
+ y = this.y,
+ z = this.z;
+ var qx = q.x,
+ qy = q.y,
+ qz = q.z,
+ qw = q.w;
+ var ix = qw * x + qy * z - qz * y;
+ var iy = qw * y + qz * x - qx * z;
+ var iz = qw * z + qx * y - qy * x;
+ var iw = -qx * x - qy * y - qz * z;
+ this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
+ this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
+ this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx;
+ return this;
+ };
+ _proto.project = function project(camera) {
+ return this.applyMatrix4(camera.matrixWorldInverse).applyMatrix4(camera.projectionMatrix);
+ };
+ _proto.unproject = function unproject(camera) {
+ return this.applyMatrix4(camera.projectionMatrixInverse).applyMatrix4(camera.matrixWorld);
+ };
+ _proto.transformDirection = function transformDirection(m) {
+ var x = this.x,
+ y = this.y,
+ z = this.z;
+ var e = m.elements;
+ this.x = e[0] * x + e[4] * y + e[8] * z;
+ this.y = e[1] * x + e[5] * y + e[9] * z;
+ this.z = e[2] * x + e[6] * y + e[10] * z;
+ return this.normalize();
+ };
+ _proto.divide = function divide(v) {
+ this.x /= v.x;
+ this.y /= v.y;
+ this.z /= v.z;
+ return this;
+ };
+ _proto.divideScalar = function divideScalar(scalar) {
+ return this.multiplyScalar(1 / scalar);
+ };
+ _proto.min = function min(v) {
+ this.x = Math.min(this.x, v.x);
+ this.y = Math.min(this.y, v.y);
+ this.z = Math.min(this.z, v.z);
+ return this;
+ };
+ _proto.max = function max(v) {
+ this.x = Math.max(this.x, v.x);
+ this.y = Math.max(this.y, v.y);
+ this.z = Math.max(this.z, v.z);
+ return this;
+ };
+ _proto.clamp = function clamp(min, max) {
+ this.x = Math.max(min.x, Math.min(max.x, this.x));
+ this.y = Math.max(min.y, Math.min(max.y, this.y));
+ this.z = Math.max(min.z, Math.min(max.z, this.z));
+ return this;
+ };
+ _proto.clampScalar = function clampScalar(minVal, maxVal) {
+ this.x = Math.max(minVal, Math.min(maxVal, this.x));
+ this.y = Math.max(minVal, Math.min(maxVal, this.y));
+ this.z = Math.max(minVal, Math.min(maxVal, this.z));
+ return this;
+ };
+ _proto.clampLength = function clampLength(min, max) {
+ var length = this.length();
+ return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length)));
+ };
+ _proto.floor = function floor() {
+ this.x = Math.floor(this.x);
+ this.y = Math.floor(this.y);
+ this.z = Math.floor(this.z);
+ return this;
+ };
+ _proto.ceil = function ceil() {
+ this.x = Math.ceil(this.x);
+ this.y = Math.ceil(this.y);
+ this.z = Math.ceil(this.z);
+ return this;
+ };
+ _proto.round = function round() {
+ this.x = Math.round(this.x);
+ this.y = Math.round(this.y);
+ this.z = Math.round(this.z);
+ return this;
+ };
+ _proto.roundToZero = function roundToZero() {
+ this.x = this.x < 0 ? Math.ceil(this.x) : Math.floor(this.x);
+ this.y = this.y < 0 ? Math.ceil(this.y) : Math.floor(this.y);
+ this.z = this.z < 0 ? Math.ceil(this.z) : Math.floor(this.z);
+ return this;
+ };
+ _proto.negate = function negate() {
+ this.x = -this.x;
+ this.y = -this.y;
+ this.z = -this.z;
+ return this;
+ };
+ _proto.dot = function dot(v) {
+ return this.x * v.x + this.y * v.y + this.z * v.z;
+ };
+ _proto.lengthSq = function lengthSq() {
+ return this.x * this.x + this.y * this.y + this.z * this.z;
+ };
+ _proto.length = function length() {
+ return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
+ };
+ _proto.manhattanLength = function manhattanLength() {
+ return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z);
+ };
+ _proto.normalize = function normalize() {
+ return this.divideScalar(this.length() || 1);
+ };
+ _proto.setLength = function setLength(length) {
+ return this.normalize().multiplyScalar(length);
+ };
+ _proto.lerp = function lerp(v, alpha) {
+ this.x += (v.x - this.x) * alpha;
+ this.y += (v.y - this.y) * alpha;
+ this.z += (v.z - this.z) * alpha;
+ return this;
+ };
+ _proto.lerpVectors = function lerpVectors(v1, v2, alpha) {
+ this.x = v1.x + (v2.x - v1.x) * alpha;
+ this.y = v1.y + (v2.y - v1.y) * alpha;
+ this.z = v1.z + (v2.z - v1.z) * alpha;
+ return this;
+ };
+ _proto.cross = function cross(v, w) {
+ if (w !== undefined) {
+ console.warn('THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.');
+ return this.crossVectors(v, w);
+ }
+ return this.crossVectors(this, v);
+ };
+ _proto.crossVectors = function crossVectors(a, b) {
+ var ax = a.x,
+ ay = a.y,
+ az = a.z;
+ var bx = b.x,
+ by = b.y,
+ bz = b.z;
+ this.x = ay * bz - az * by;
+ this.y = az * bx - ax * bz;
+ this.z = ax * by - ay * bx;
+ return this;
+ };
+ _proto.projectOnVector = function projectOnVector(v) {
+ var denominator = v.lengthSq();
+ if (denominator === 0) return this.set(0, 0, 0);
+ var scalar = v.dot(this) / denominator;
+ return this.copy(v).multiplyScalar(scalar);
+ };
+ _proto.projectOnPlane = function projectOnPlane(planeNormal) {
+ _vector.copy(this).projectOnVector(planeNormal);
+ return this.sub(_vector);
+ };
+ _proto.reflect = function reflect(normal) {
+ return this.sub(_vector.copy(normal).multiplyScalar(2 * this.dot(normal)));
+ };
+ _proto.angleTo = function angleTo(v) {
+ var denominator = Math.sqrt(this.lengthSq() * v.lengthSq());
+ if (denominator === 0) return Math.PI / 2;
+ var theta = this.dot(v) / denominator;
+ return Math.acos(MathUtils.clamp(theta, -1, 1));
+ };
+ _proto.distanceTo = function distanceTo(v) {
+ return Math.sqrt(this.distanceToSquared(v));
+ };
+ _proto.distanceToSquared = function distanceToSquared(v) {
+ var dx = this.x - v.x,
+ dy = this.y - v.y,
+ dz = this.z - v.z;
+ return dx * dx + dy * dy + dz * dz;
+ };
+ _proto.manhattanDistanceTo = function manhattanDistanceTo(v) {
+ return Math.abs(this.x - v.x) + Math.abs(this.y - v.y) + Math.abs(this.z - v.z);
+ };
+ _proto.setFromSpherical = function setFromSpherical(s) {
+ return this.setFromSphericalCoords(s.radius, s.phi, s.theta);
+ };
+ _proto.setFromSphericalCoords = function setFromSphericalCoords(radius, phi, theta) {
+ var sinPhiRadius = Math.sin(phi) * radius;
+ this.x = sinPhiRadius * Math.sin(theta);
+ this.y = Math.cos(phi) * radius;
+ this.z = sinPhiRadius * Math.cos(theta);
+ return this;
+ };
+ _proto.setFromCylindrical = function setFromCylindrical(c) {
+ return this.setFromCylindricalCoords(c.radius, c.theta, c.y);
+ };
+ _proto.setFromCylindricalCoords = function setFromCylindricalCoords(radius, theta, y) {
+ this.x = radius * Math.sin(theta);
+ this.y = y;
+ this.z = radius * Math.cos(theta);
+ return this;
+ };
+ _proto.setFromMatrixPosition = function setFromMatrixPosition(m) {
+ var e = m.elements;
+ this.x = e[12];
+ this.y = e[13];
+ this.z = e[14];
+ return this;
+ };
+ _proto.setFromMatrixScale = function setFromMatrixScale(m) {
+ var sx = this.setFromMatrixColumn(m, 0).length();
+ var sy = this.setFromMatrixColumn(m, 1).length();
+ var sz = this.setFromMatrixColumn(m, 2).length();
+ this.x = sx;
+ this.y = sy;
+ this.z = sz;
+ return this;
+ };
+ _proto.setFromMatrixColumn = function setFromMatrixColumn(m, index) {
+ return this.fromArray(m.elements, index * 4);
+ };
+ _proto.setFromMatrix3Column = function setFromMatrix3Column(m, index) {
+ return this.fromArray(m.elements, index * 3);
+ };
+ _proto.equals = function equals(v) {
+ return v.x === this.x && v.y === this.y && v.z === this.z;
+ };
+ _proto.fromArray = function fromArray(array, offset) {
+ if (offset === void 0) {
+ offset = 0;
+ }
+ this.x = array[offset];
+ this.y = array[offset + 1];
+ this.z = array[offset + 2];
+ return this;
+ };
+ _proto.toArray = function toArray(array, offset) {
+ if (array === void 0) {
+ array = [];
+ }
+ if (offset === void 0) {
+ offset = 0;
+ }
+ array[offset] = this.x;
+ array[offset + 1] = this.y;
+ array[offset + 2] = this.z;
+ return array;
+ };
+ _proto.fromBufferAttribute = function fromBufferAttribute(attribute, index, offset) {
+ if (offset !== undefined) {
+ console.warn('THREE.Vector3: offset has been removed from .fromBufferAttribute().');
+ }
+ this.x = attribute.getX(index);
+ this.y = attribute.getY(index);
+ this.z = attribute.getZ(index);
+ return this;
+ };
+ _proto.random = function random() {
+ this.x = Math.random();
+ this.y = Math.random();
+ this.z = Math.random();
+ return this;
+ };
+ return Vector3;
+ }();
+ var _vector = /*@__PURE__*/new Vector3();
+ var _quaternion = /*@__PURE__*/new Quaternion();
+ var Box3 = /*#__PURE__*/function () {
+ function Box3(min, max) {
+ Object.defineProperty(this, 'isBox3', {
+ value: true
+ });
+ this.min = min !== undefined ? min : new Vector3(+Infinity, +Infinity, +Infinity);
+ this.max = max !== undefined ? max : new Vector3(-Infinity, -Infinity, -Infinity);
+ }
+ var _proto = Box3.prototype;
+ _proto.set = function set(min, max) {
+ this.min.copy(min);
+ this.max.copy(max);
+ return this;
+ };
+ _proto.setFromArray = function setFromArray(array) {
+ var minX = +Infinity;
+ var minY = +Infinity;
+ var minZ = +Infinity;
+ var maxX = -Infinity;
+ var maxY = -Infinity;
+ var maxZ = -Infinity;
+ for (var i = 0, l = array.length; i < l; i += 3) {
+ var x = array[i];
+ var y = array[i + 1];
+ var z = array[i + 2];
+ if (x < minX) minX = x;
+ if (y < minY) minY = y;
+ if (z < minZ) minZ = z;
+ if (x > maxX) maxX = x;
+ if (y > maxY) maxY = y;
+ if (z > maxZ) maxZ = z;
+ }
+ this.min.set(minX, minY, minZ);
+ this.max.set(maxX, maxY, maxZ);
+ return this;
+ };
+ _proto.setFromBufferAttribute = function setFromBufferAttribute(attribute) {
+ var minX = +Infinity;
+ var minY = +Infinity;
+ var minZ = +Infinity;
+ var maxX = -Infinity;
+ var maxY = -Infinity;
+ var maxZ = -Infinity;
+ for (var i = 0, l = attribute.count; i < l; i++) {
+ var x = attribute.getX(i);
+ var y = attribute.getY(i);
+ var z = attribute.getZ(i);
+ if (x < minX) minX = x;
+ if (y < minY) minY = y;
+ if (z < minZ) minZ = z;
+ if (x > maxX) maxX = x;
+ if (y > maxY) maxY = y;
+ if (z > maxZ) maxZ = z;
+ }
+ this.min.set(minX, minY, minZ);
+ this.max.set(maxX, maxY, maxZ);
+ return this;
+ };
+ _proto.setFromPoints = function setFromPoints(points) {
+ this.makeEmpty();
+ for (var i = 0, il = points.length; i < il; i++) {
+ this.expandByPoint(points[i]);
+ }
+ return this;
+ };
+ _proto.setFromCenterAndSize = function setFromCenterAndSize(center, size) {
+ var halfSize = _vector$1.copy(size).multiplyScalar(0.5);
+ this.min.copy(center).sub(halfSize);
+ this.max.copy(center).add(halfSize);
+ return this;
+ };
+ _proto.setFromObject = function setFromObject(object) {
+ this.makeEmpty();
+ return this.expandByObject(object);
+ };
+ _proto.clone = function clone() {
+ return new this.constructor().copy(this);
+ };
+ _proto.copy = function copy(box) {
+ this.min.copy(box.min);
+ this.max.copy(box.max);
+ return this;
+ };
+ _proto.makeEmpty = function makeEmpty() {
+ this.min.x = this.min.y = this.min.z = +Infinity;
+ this.max.x = this.max.y = this.max.z = -Infinity;
+ return this;
+ };
+ _proto.isEmpty = function isEmpty() {
+ return this.max.x < this.min.x || this.max.y < this.min.y || this.max.z < this.min.z;
+ };
+ _proto.getCenter = function getCenter(target) {
+ if (target === undefined) {
+ console.warn('THREE.Box3: .getCenter() target is now required');
+ target = new Vector3();
+ }
+ return this.isEmpty() ? target.set(0, 0, 0) : target.addVectors(this.min, this.max).multiplyScalar(0.5);
+ };
+ _proto.getSize = function getSize(target) {
+ if (target === undefined) {
+ console.warn('THREE.Box3: .getSize() target is now required');
+ target = new Vector3();
+ }
+ return this.isEmpty() ? target.set(0, 0, 0) : target.subVectors(this.max, this.min);
+ };
+ _proto.expandByPoint = function expandByPoint(point) {
+ this.min.min(point);
+ this.max.max(point);
+ return this;
+ };
+ _proto.expandByVector = function expandByVector(vector) {
+ this.min.sub(vector);
+ this.max.add(vector);
+ return this;
+ };
+ _proto.expandByScalar = function expandByScalar(scalar) {
+ this.min.addScalar(-scalar);
+ this.max.addScalar(scalar);
+ return this;
+ };
+ _proto.expandByObject = function expandByObject(object) {
+ object.updateWorldMatrix(false, false);
+ var geometry = object.geometry;
+ if (geometry !== undefined) {
+ if (geometry.boundingBox === null) {
+ geometry.computeBoundingBox();
+ }
+ _box.copy(geometry.boundingBox);
+ _box.applyMatrix4(object.matrixWorld);
+ this.union(_box);
+ }
+ var children = object.children;
+ for (var i = 0, l = children.length; i < l; i++) {
+ this.expandByObject(children[i]);
+ }
+ return this;
+ };
+ _proto.containsPoint = function containsPoint(point) {
+ return point.x < this.min.x || point.x > this.max.x || point.y < this.min.y || point.y > this.max.y || point.z < this.min.z || point.z > this.max.z ? false : true;
+ };
+ _proto.containsBox = function containsBox(box) {
+ return this.min.x <= box.min.x && box.max.x <= this.max.x && this.min.y <= box.min.y && box.max.y <= this.max.y && this.min.z <= box.min.z && box.max.z <= this.max.z;
+ };
+ _proto.getParameter = function getParameter(point, target) {
+ if (target === undefined) {
+ console.warn('THREE.Box3: .getParameter() target is now required');
+ target = new Vector3();
+ }
+ return target.set((point.x - this.min.x) / (this.max.x - this.min.x), (point.y - this.min.y) / (this.max.y - this.min.y), (point.z - this.min.z) / (this.max.z - this.min.z));
+ };
+ _proto.intersectsBox = function intersectsBox(box) {
+ return box.max.x < this.min.x || box.min.x > this.max.x || box.max.y < this.min.y || box.min.y > this.max.y || box.max.z < this.min.z || box.min.z > this.max.z ? false : true;
+ };
+ _proto.intersectsSphere = function intersectsSphere(sphere) {
+ this.clampPoint(sphere.center, _vector$1); // If that point is inside the sphere, the AABB and sphere intersect.
+ return _vector$1.distanceToSquared(sphere.center) <= sphere.radius * sphere.radius;
+ };
+ _proto.intersectsPlane = function intersectsPlane(plane) {
+ var min, max;
+ if (plane.normal.x > 0) {
+ min = plane.normal.x * this.min.x;
+ max = plane.normal.x * this.max.x;
+ } else {
+ min = plane.normal.x * this.max.x;
+ max = plane.normal.x * this.min.x;
+ }
+ if (plane.normal.y > 0) {
+ min += plane.normal.y * this.min.y;
+ max += plane.normal.y * this.max.y;
+ } else {
+ min += plane.normal.y * this.max.y;
+ max += plane.normal.y * this.min.y;
+ }
+ if (plane.normal.z > 0) {
+ min += plane.normal.z * this.min.z;
+ max += plane.normal.z * this.max.z;
+ } else {
+ min += plane.normal.z * this.max.z;
+ max += plane.normal.z * this.min.z;
+ }
+ return min <= -plane.constant && max >= -plane.constant;
+ };
+ _proto.intersectsTriangle = function intersectsTriangle(triangle) {
+ if (this.isEmpty()) {
+ return false;
+ }
+ this.getCenter(_center);
+ _extents.subVectors(this.max, _center);
+ _v0.subVectors(triangle.a, _center);
+ _v1.subVectors(triangle.b, _center);
+ _v2.subVectors(triangle.c, _center);
+ _f0.subVectors(_v1, _v0);
+ _f1.subVectors(_v2, _v1);
+ _f2.subVectors(_v0, _v2);
+ var axes = [0, -_f0.z, _f0.y, 0, -_f1.z, _f1.y, 0, -_f2.z, _f2.y, _f0.z, 0, -_f0.x, _f1.z, 0, -_f1.x, _f2.z, 0, -_f2.x, -_f0.y, _f0.x, 0, -_f1.y, _f1.x, 0, -_f2.y, _f2.x, 0];
+ if (!satForAxes(axes, _v0, _v1, _v2, _extents)) {
+ return false;
+ }
+ axes = [1, 0, 0, 0, 1, 0, 0, 0, 1];
+ if (!satForAxes(axes, _v0, _v1, _v2, _extents)) {
+ return false;
+ }
+ _triangleNormal.crossVectors(_f0, _f1);
+ axes = [_triangleNormal.x, _triangleNormal.y, _triangleNormal.z];
+ return satForAxes(axes, _v0, _v1, _v2, _extents);
+ };
+ _proto.clampPoint = function clampPoint(point, target) {
+ if (target === undefined) {
+ console.warn('THREE.Box3: .clampPoint() target is now required');
+ target = new Vector3();
+ }
+ return target.copy(point).clamp(this.min, this.max);
+ };
+ _proto.distanceToPoint = function distanceToPoint(point) {
+ var clampedPoint = _vector$1.copy(point).clamp(this.min, this.max);
+ return clampedPoint.sub(point).length();
+ };
+ _proto.getBoundingSphere = function getBoundingSphere(target) {
+ if (target === undefined) {
+ console.error('THREE.Box3: .getBoundingSphere() target is now required');
+ }
+ this.getCenter(target.center);
+ target.radius = this.getSize(_vector$1).length() * 0.5;
+ return target;
+ };
+ _proto.intersect = function intersect(box) {
+ this.min.max(box.min);
+ this.max.min(box.max);
+ if (this.isEmpty()) this.makeEmpty();
+ return this;
+ };
+ _proto.union = function union(box) {
+ this.min.min(box.min);
+ this.max.max(box.max);
+ return this;
+ };
+ _proto.applyMatrix4 = function applyMatrix4(matrix) {
+ if (this.isEmpty()) return this;
+ _points[0].set(this.min.x, this.min.y, this.min.z).applyMatrix4(matrix);
+
+ _points[1].set(this.min.x, this.min.y, this.max.z).applyMatrix4(matrix);
+
+ _points[2].set(this.min.x, this.max.y, this.min.z).applyMatrix4(matrix);
+
+ _points[3].set(this.min.x, this.max.y, this.max.z).applyMatrix4(matrix);
+
+ _points[4].set(this.max.x, this.min.y, this.min.z).applyMatrix4(matrix);
+
+ _points[5].set(this.max.x, this.min.y, this.max.z).applyMatrix4(matrix);
+
+ _points[6].set(this.max.x, this.max.y, this.min.z).applyMatrix4(matrix);
+
+ _points[7].set(this.max.x, this.max.y, this.max.z).applyMatrix4(matrix);
+
+ this.setFromPoints(_points);
+ return this;
+ };
+ _proto.translate = function translate(offset) {
+ this.min.add(offset);
+ this.max.add(offset);
+ return this;
+ };
+ _proto.equals = function equals(box) {
+ return box.min.equals(this.min) && box.max.equals(this.max);
+ };
+ return Box3;
+ }();
+ function satForAxes(axes, v0, v1, v2, extents) {
+ for (var i = 0, j = axes.length - 3; i <= j; i += 3) {
+ _testAxis.fromArray(axes, i);
+
+ var r = extents.x * Math.abs(_testAxis.x) + extents.y * Math.abs(_testAxis.y) + extents.z * Math.abs(_testAxis.z);
+ var p0 = v0.dot(_testAxis);
+ var p1 = v1.dot(_testAxis);
+ var p2 = v2.dot(_testAxis);
+ if (Math.max(-Math.max(p0, p1, p2), Math.min(p0, p1, p2)) > r) {
+ return false;
+ }
+ }
+ return true;
+ }
+ var _points = [/*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3()];
+ var _vector$1 = /*@__PURE__*/new Vector3();
+ var _box = /*@__PURE__*/new Box3();
+
+ var _v0 = /*@__PURE__*/new Vector3();
+ var _v1 = /*@__PURE__*/new Vector3();
+ var _v2 = /*@__PURE__*/new Vector3();
+
+ var _f0 = /*@__PURE__*/new Vector3();
+ var _f1 = /*@__PURE__*/new Vector3();
+ var _f2 = /*@__PURE__*/new Vector3();
+ var _center = /*@__PURE__*/new Vector3();
+ var _extents = /*@__PURE__*/new Vector3();
+ var _triangleNormal = /*@__PURE__*/new Vector3();
+ var _testAxis = /*@__PURE__*/new Vector3();
+ var _box$1 = /*@__PURE__*/new Box3();
+ var Sphere = /*#__PURE__*/function () {
+ function Sphere(center, radius) {
+ this.center = center !== undefined ? center : new Vector3();
+ this.radius = radius !== undefined ? radius : -1;
+ }
+ var _proto = Sphere.prototype;
+ _proto.set = function set(center, radius) {
+ this.center.copy(center);
+ this.radius = radius;
+ return this;
+ };
+ _proto.setFromPoints = function setFromPoints(points, optionalCenter) {
+ var center = this.center;
+ if (optionalCenter !== undefined) {
+ center.copy(optionalCenter);
+ } else {
+ _box$1.setFromPoints(points).getCenter(center);
+ }
+ var maxRadiusSq = 0;
+ for (var i = 0, il = points.length; i < il; i++) {
+ maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(points[i]));
+ }
+ this.radius = Math.sqrt(maxRadiusSq);
+ return this;
+ };
+ _proto.clone = function clone() {
+ return new this.constructor().copy(this);
+ };
+ _proto.copy = function copy(sphere) {
+ this.center.copy(sphere.center);
+ this.radius = sphere.radius;
+ return this;
+ };
+ _proto.isEmpty = function isEmpty() {
+ return this.radius < 0;
+ };
+ _proto.makeEmpty = function makeEmpty() {
+ this.center.set(0, 0, 0);
+ this.radius = -1;
+ return this;
+ };
+ _proto.containsPoint = function containsPoint(point) {
+ return point.distanceToSquared(this.center) <= this.radius * this.radius;
+ };
+ _proto.distanceToPoint = function distanceToPoint(point) {
+ return point.distanceTo(this.center) - this.radius;
+ };
+ _proto.intersectsSphere = function intersectsSphere(sphere) {
+ var radiusSum = this.radius + sphere.radius;
+ return sphere.center.distanceToSquared(this.center) <= radiusSum * radiusSum;
+ };
+ _proto.intersectsBox = function intersectsBox(box) {
+ return box.intersectsSphere(this);
+ };
+ _proto.intersectsPlane = function intersectsPlane(plane) {
+ return Math.abs(plane.distanceToPoint(this.center)) <= this.radius;
+ };
+ _proto.clampPoint = function clampPoint(point, target) {
+ var deltaLengthSq = this.center.distanceToSquared(point);
+ if (target === undefined) {
+ console.warn('THREE.Sphere: .clampPoint() target is now required');
+ target = new Vector3();
+ }
+ target.copy(point);
+ if (deltaLengthSq > this.radius * this.radius) {
+ target.sub(this.center).normalize();
+ target.multiplyScalar(this.radius).add(this.center);
+ }
+ return target;
+ };
+ _proto.getBoundingBox = function getBoundingBox(target) {
+ if (target === undefined) {
+ console.warn('THREE.Sphere: .getBoundingBox() target is now required');
+ target = new Box3();
+ }
+ if (this.isEmpty()) {
+ target.makeEmpty();
+ return target;
+ }
+ target.set(this.center, this.center);
+ target.expandByScalar(this.radius);
+ return target;
+ };
+ _proto.applyMatrix4 = function applyMatrix4(matrix) {
+ this.center.applyMatrix4(matrix);
+ this.radius = this.radius * matrix.getMaxScaleOnAxis();
+ return this;
+ };
+ _proto.translate = function translate(offset) {
+ this.center.add(offset);
+ return this;
+ };
+ _proto.equals = function equals(sphere) {
+ return sphere.center.equals(this.center) && sphere.radius === this.radius;
+ };
+ return Sphere;
+ }();
+ var _vector$2 = /*@__PURE__*/new Vector3();
+ var _segCenter = /*@__PURE__*/new Vector3();
+ var _segDir = /*@__PURE__*/new Vector3();
+ var _diff = /*@__PURE__*/new Vector3();
+ var _edge1 = /*@__PURE__*/new Vector3();
+ var _edge2 = /*@__PURE__*/new Vector3();
+ var _normal = /*@__PURE__*/new Vector3();
+ var Ray = /*#__PURE__*/function () {
+ function Ray(origin, direction) {
+ this.origin = origin !== undefined ? origin : new Vector3();
+ this.direction = direction !== undefined ? direction : new Vector3(0, 0, -1);
+ }
+ var _proto = Ray.prototype;
+ _proto.set = function set(origin, direction) {
+ this.origin.copy(origin);
+ this.direction.copy(direction);
+ return this;
+ };
+ _proto.clone = function clone() {
+ return new this.constructor().copy(this);
+ };
+ _proto.copy = function copy(ray) {
+ this.origin.copy(ray.origin);
+ this.direction.copy(ray.direction);
+ return this;
+ };
+ _proto.at = function at(t, target) {
+ if (target === undefined) {
+ console.warn('THREE.Ray: .at() target is now required');
+ target = new Vector3();
+ }
+ return target.copy(this.direction).multiplyScalar(t).add(this.origin);
+ };
+ _proto.lookAt = function lookAt(v) {
+ this.direction.copy(v).sub(this.origin).normalize();
+ return this;
+ };
+ _proto.recast = function recast(t) {
+ this.origin.copy(this.at(t, _vector$2));
+ return this;
+ };
+ _proto.closestPointToPoint = function closestPointToPoint(point, target) {
+ if (target === undefined) {
+ console.warn('THREE.Ray: .closestPointToPoint() target is now required');
+ target = new Vector3();
+ }
+ target.subVectors(point, this.origin);
+ var directionDistance = target.dot(this.direction);
+ if (directionDistance < 0) {
+ return target.copy(this.origin);
+ }
+ return target.copy(this.direction).multiplyScalar(directionDistance).add(this.origin);
+ };
+ _proto.distanceToPoint = function distanceToPoint(point) {
+ return Math.sqrt(this.distanceSqToPoint(point));
+ };
+ _proto.distanceSqToPoint = function distanceSqToPoint(point) {
+ var directionDistance = _vector$2.subVectors(point, this.origin).dot(this.direction); // point behind the ray
+
+ if (directionDistance < 0) {
+ return this.origin.distanceToSquared(point);
+ }
+ _vector$2.copy(this.direction).multiplyScalar(directionDistance).add(this.origin);
+ return _vector$2.distanceToSquared(point);
+ };
+ _proto.distanceSqToSegment = function distanceSqToSegment(v0, v1, optionalPointOnRay, optionalPointOnSegment) {
+ _segCenter.copy(v0).add(v1).multiplyScalar(0.5);
+ _segDir.copy(v1).sub(v0).normalize();
+ _diff.copy(this.origin).sub(_segCenter);
+ var segExtent = v0.distanceTo(v1) * 0.5;
+ var a01 = -this.direction.dot(_segDir);
+ var b0 = _diff.dot(this.direction);
+ var b1 = -_diff.dot(_segDir);
+ var c = _diff.lengthSq();
+ var det = Math.abs(1 - a01 * a01);
+ var s0, s1, sqrDist, extDet;
+ if (det > 0) {
+ s0 = a01 * b1 - b0;
+ s1 = a01 * b0 - b1;
+ extDet = segExtent * det;
+ if (s0 >= 0) {
+ if (s1 >= -extDet) {
+ if (s1 <= extDet) {
+ var invDet = 1 / det;
+ s0 *= invDet;
+ s1 *= invDet;
+ sqrDist = s0 * (s0 + a01 * s1 + 2 * b0) + s1 * (a01 * s0 + s1 + 2 * b1) + c;
+ } else {
+ s1 = segExtent;
+ s0 = Math.max(0, -(a01 * s1 + b0));
+ sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c;
+ }
+ } else {
+ s1 = -segExtent;
+ s0 = Math.max(0, -(a01 * s1 + b0));
+ sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c;
+ }
+ } else {
+ if (s1 <= -extDet) {
+ s0 = Math.max(0, -(-a01 * segExtent + b0));
+ s1 = s0 > 0 ? -segExtent : Math.min(Math.max(-segExtent, -b1), segExtent);
+ sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c;
+ } else if (s1 <= extDet) {
+ s0 = 0;
+ s1 = Math.min(Math.max(-segExtent, -b1), segExtent);
+ sqrDist = s1 * (s1 + 2 * b1) + c;
+ } else {
+ s0 = Math.max(0, -(a01 * segExtent + b0));
+ s1 = s0 > 0 ? segExtent : Math.min(Math.max(-segExtent, -b1), segExtent);
+ sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c;
+ }
+ }
+ } else {
+ s1 = a01 > 0 ? -segExtent : segExtent;
+ s0 = Math.max(0, -(a01 * s1 + b0));
+ sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c;
+ }
+ if (optionalPointOnRay) {
+ optionalPointOnRay.copy(this.direction).multiplyScalar(s0).add(this.origin);
+ }
+ if (optionalPointOnSegment) {
+ optionalPointOnSegment.copy(_segDir).multiplyScalar(s1).add(_segCenter);
+ }
+ return sqrDist;
+ };
+ _proto.intersectSphere = function intersectSphere(sphere, target) {
+ _vector$2.subVectors(sphere.center, this.origin);
+ var tca = _vector$2.dot(this.direction);
+ var d2 = _vector$2.dot(_vector$2) - tca * tca;
+ var radius2 = sphere.radius * sphere.radius;
+ if (d2 > radius2) return null;
+ var thc = Math.sqrt(radius2 - d2);
+ var t0 = tca - thc;
+ var t1 = tca + thc;
+ if (t0 < 0 && t1 < 0) return null;
+ if (t0 < 0) return this.at(t1, target);
+ return this.at(t0, target);
+ };
+ _proto.intersectsSphere = function intersectsSphere(sphere) {
+ return this.distanceSqToPoint(sphere.center) <= sphere.radius * sphere.radius;
+ };
+ _proto.distanceToPlane = function distanceToPlane(plane) {
+ var denominator = plane.normal.dot(this.direction);
+ if (denominator === 0) {
+ if (plane.distanceToPoint(this.origin) === 0) {
+ return 0;
+ }
+ return null;
+ }
+ var t = -(this.origin.dot(plane.normal) + plane.constant) / denominator;
+ return t >= 0 ? t : null;
+ };
+ _proto.intersectPlane = function intersectPlane(plane, target) {
+ var t = this.distanceToPlane(plane);
+ if (t === null) {
+ return null;
+ }
+ return this.at(t, target);
+ };
+ _proto.intersectsPlane = function intersectsPlane(plane) {
+ var distToPoint = plane.distanceToPoint(this.origin);
+ if (distToPoint === 0) {
+ return true;
+ }
+ var denominator = plane.normal.dot(this.direction);
+ if (denominator * distToPoint < 0) {
+ return true;
+ }
+ return false;
+ };
+ _proto.intersectBox = function intersectBox(box, target) {
+ var tmin, tmax, tymin, tymax, tzmin, tzmax;
+ var invdirx = 1 / this.direction.x,
+ invdiry = 1 / this.direction.y,
+ invdirz = 1 / this.direction.z;
+ var origin = this.origin;
+ if (invdirx >= 0) {
+ tmin = (box.min.x - origin.x) * invdirx;
+ tmax = (box.max.x - origin.x) * invdirx;
+ } else {
+ tmin = (box.max.x - origin.x) * invdirx;
+ tmax = (box.min.x - origin.x) * invdirx;
+ }
+ if (invdiry >= 0) {
+ tymin = (box.min.y - origin.y) * invdiry;
+ tymax = (box.max.y - origin.y) * invdiry;
+ } else {
+ tymin = (box.max.y - origin.y) * invdiry;
+ tymax = (box.min.y - origin.y) * invdiry;
+ }
+ if (tmin > tymax || tymin > tmax) return null;
+ if (tymin > tmin || tmin !== tmin) tmin = tymin;
+ if (tymax < tmax || tmax !== tmax) tmax = tymax;
+ if (invdirz >= 0) {
+ tzmin = (box.min.z - origin.z) * invdirz;
+ tzmax = (box.max.z - origin.z) * invdirz;
+ } else {
+ tzmin = (box.max.z - origin.z) * invdirz;
+ tzmax = (box.min.z - origin.z) * invdirz;
+ }
+ if (tmin > tzmax || tzmin > tmax) return null;
+ if (tzmin > tmin || tmin !== tmin) tmin = tzmin;
+ if (tzmax < tmax || tmax !== tmax) tmax = tzmax;
+ if (tmax < 0) return null;
+ return this.at(tmin >= 0 ? tmin : tmax, target);
+ };
+ _proto.intersectsBox = function intersectsBox(box) {
+ return this.intersectBox(box, _vector$2) !== null;
+ };
+ _proto.intersectTriangle = function intersectTriangle(a, b, c, backfaceCulling, target) {
+ _edge1.subVectors(b, a);
+ _edge2.subVectors(c, a);
+ _normal.crossVectors(_edge1, _edge2);
+ var DdN = this.direction.dot(_normal);
+ var sign;
+ if (DdN > 0) {
+ if (backfaceCulling) return null;
+ sign = 1;
+ } else if (DdN < 0) {
+ sign = -1;
+ DdN = -DdN;
+ } else {
+ return null;
+ }
+ _diff.subVectors(this.origin, a);
+ var DdQxE2 = sign * this.direction.dot(_edge2.crossVectors(_diff, _edge2));
+ if (DdQxE2 < 0) {
+ return null;
+ }
+ var DdE1xQ = sign * this.direction.dot(_edge1.cross(_diff));
+ if (DdE1xQ < 0) {
+ return null;
+ }
+ if (DdQxE2 + DdE1xQ > DdN) {
+ return null;
+ }
+ var QdN = -sign * _diff.dot(_normal);
+ if (QdN < 0) {
+ return null;
+ }
+ return this.at(QdN / DdN, target);
+ };
+ _proto.applyMatrix4 = function applyMatrix4(matrix4) {
+ this.origin.applyMatrix4(matrix4);
+ this.direction.transformDirection(matrix4);
+ return this;
+ };
+ _proto.equals = function equals(ray) {
+ return ray.origin.equals(this.origin) && ray.direction.equals(this.direction);
+ };
+ return Ray;
+ }();
+ var Matrix4 = /*#__PURE__*/function () {
+ function Matrix4() {
+ Object.defineProperty(this, 'isMatrix4', {
+ value: true
+ });
+ this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
+ if (arguments.length > 0) {
+ console.error('THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.');
+ }
+ }
+ var _proto = Matrix4.prototype;
+ _proto.set = function set(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44) {
+ var te = this.elements;
+ te[0] = n11;
+ te[4] = n12;
+ te[8] = n13;
+ te[12] = n14;
+ te[1] = n21;
+ te[5] = n22;
+ te[9] = n23;
+ te[13] = n24;
+ te[2] = n31;
+ te[6] = n32;
+ te[10] = n33;
+ te[14] = n34;
+ te[3] = n41;
+ te[7] = n42;
+ te[11] = n43;
+ te[15] = n44;
+ return this;
+ };
+ _proto.identity = function identity() {
+ this.set(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+ return this;
+ };
+ _proto.clone = function clone() {
+ return new Matrix4().fromArray(this.elements);
+ };
+ _proto.copy = function copy(m) {
+ var te = this.elements;
+ var me = m.elements;
+ te[0] = me[0];
+ te[1] = me[1];
+ te[2] = me[2];
+ te[3] = me[3];
+ te[4] = me[4];
+ te[5] = me[5];
+ te[6] = me[6];
+ te[7] = me[7];
+ te[8] = me[8];
+ te[9] = me[9];
+ te[10] = me[10];
+ te[11] = me[11];
+ te[12] = me[12];
+ te[13] = me[13];
+ te[14] = me[14];
+ te[15] = me[15];
+ return this;
+ };
+ _proto.copyPosition = function copyPosition(m) {
+ var te = this.elements,
+ me = m.elements;
+ te[12] = me[12];
+ te[13] = me[13];
+ te[14] = me[14];
+ return this;
+ };
+ _proto.extractBasis = function extractBasis(xAxis, yAxis, zAxis) {
+ xAxis.setFromMatrixColumn(this, 0);
+ yAxis.setFromMatrixColumn(this, 1);
+ zAxis.setFromMatrixColumn(this, 2);
+ return this;
+ };
+ _proto.makeBasis = function makeBasis(xAxis, yAxis, zAxis) {
+ this.set(xAxis.x, yAxis.x, zAxis.x, 0, xAxis.y, yAxis.y, zAxis.y, 0, xAxis.z, yAxis.z, zAxis.z, 0, 0, 0, 0, 1);
+ return this;
+ };
+ _proto.extractRotation = function extractRotation(m) {
+ var te = this.elements;
+ var me = m.elements;
+ var scaleX = 1 / _v1$1.setFromMatrixColumn(m, 0).length();
+ var scaleY = 1 / _v1$1.setFromMatrixColumn(m, 1).length();
+ var scaleZ = 1 / _v1$1.setFromMatrixColumn(m, 2).length();
+ te[0] = me[0] * scaleX;
+ te[1] = me[1] * scaleX;
+ te[2] = me[2] * scaleX;
+ te[3] = 0;
+ te[4] = me[4] * scaleY;
+ te[5] = me[5] * scaleY;
+ te[6] = me[6] * scaleY;
+ te[7] = 0;
+ te[8] = me[8] * scaleZ;
+ te[9] = me[9] * scaleZ;
+ te[10] = me[10] * scaleZ;
+ te[11] = 0;
+ te[12] = 0;
+ te[13] = 0;
+ te[14] = 0;
+ te[15] = 1;
+ return this;
+ };
+ _proto.makeRotationFromEuler = function makeRotationFromEuler(euler) {
+ if (!(euler && euler.isEuler)) {
+ console.error('THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.');
+ }
+ var te = this.elements;
+ var x = euler.x,
+ y = euler.y,
+ z = euler.z;
+ var a = Math.cos(x),
+ b = Math.sin(x);
+ var c = Math.cos(y),
+ d = Math.sin(y);
+ var e = Math.cos(z),
+ f = Math.sin(z);
+ if (euler.order === 'XYZ') {
+ var ae = a * e,
+ af = a * f,
+ be = b * e,
+ bf = b * f;
+ te[0] = c * e;
+ te[4] = -c * f;
+ te[8] = d;
+ te[1] = af + be * d;
+ te[5] = ae - bf * d;
+ te[9] = -b * c;
+ te[2] = bf - ae * d;
+ te[6] = be + af * d;
+ te[10] = a * c;
+ } else if (euler.order === 'YXZ') {
+ var ce = c * e,
+ cf = c * f,
+ de = d * e,
+ df = d * f;
+ te[0] = ce + df * b;
+ te[4] = de * b - cf;
+ te[8] = a * d;
+ te[1] = a * f;
+ te[5] = a * e;
+ te[9] = -b;
+ te[2] = cf * b - de;
+ te[6] = df + ce * b;
+ te[10] = a * c;
+ } else if (euler.order === 'ZXY') {
+ var _ce = c * e,
+ _cf = c * f,
+ _de = d * e,
+ _df = d * f;
+ te[0] = _ce - _df * b;
+ te[4] = -a * f;
+ te[8] = _de + _cf * b;
+ te[1] = _cf + _de * b;
+ te[5] = a * e;
+ te[9] = _df - _ce * b;
+ te[2] = -a * d;
+ te[6] = b;
+ te[10] = a * c;
+ } else if (euler.order === 'ZYX') {
+ var _ae = a * e,
+ _af = a * f,
+ _be = b * e,
+ _bf = b * f;
+ te[0] = c * e;
+ te[4] = _be * d - _af;
+ te[8] = _ae * d + _bf;
+ te[1] = c * f;
+ te[5] = _bf * d + _ae;
+ te[9] = _af * d - _be;
+ te[2] = -d;
+ te[6] = b * c;
+ te[10] = a * c;
+ } else if (euler.order === 'YZX') {
+ var ac = a * c,
+ ad = a * d,
+ bc = b * c,
+ bd = b * d;
+ te[0] = c * e;
+ te[4] = bd - ac * f;
+ te[8] = bc * f + ad;
+ te[1] = f;
+ te[5] = a * e;
+ te[9] = -b * e;
+ te[2] = -d * e;
+ te[6] = ad * f + bc;
+ te[10] = ac - bd * f;
+ } else if (euler.order === 'XZY') {
+ var _ac = a * c,
+ _ad = a * d,
+ _bc = b * c,
+ _bd = b * d;
+ te[0] = c * e;
+ te[4] = -f;
+ te[8] = d * e;
+ te[1] = _ac * f + _bd;
+ te[5] = a * e;
+ te[9] = _ad * f - _bc;
+ te[2] = _bc * f - _ad;
+ te[6] = b * e;
+ te[10] = _bd * f + _ac;
+ }
+ te[3] = 0;
+ te[7] = 0;
+ te[11] = 0;
+ te[12] = 0;
+ te[13] = 0;
+ te[14] = 0;
+ te[15] = 1;
+ return this;
+ };
+ _proto.makeRotationFromQuaternion = function makeRotationFromQuaternion(q) {
+ return this.compose(_zero, q, _one);
+ };
+ _proto.lookAt = function lookAt(eye, target, up) {
+ var te = this.elements;
+ _z.subVectors(eye, target);
+ if (_z.lengthSq() === 0) {
+ _z.z = 1;
+ }
+ _z.normalize();
+ _x.crossVectors(up, _z);
+ if (_x.lengthSq() === 0) {
+ if (Math.abs(up.z) === 1) {
+ _z.x += 0.0001;
+ } else {
+ _z.z += 0.0001;
+ }
+ _z.normalize();
+ _x.crossVectors(up, _z);
+ }
+ _x.normalize();
+ _y.crossVectors(_z, _x);
+ te[0] = _x.x;
+ te[4] = _y.x;
+ te[8] = _z.x;
+ te[1] = _x.y;
+ te[5] = _y.y;
+ te[9] = _z.y;
+ te[2] = _x.z;
+ te[6] = _y.z;
+ te[10] = _z.z;
+ return this;
+ };
+ _proto.multiply = function multiply(m, n) {
+ if (n !== undefined) {
+ console.warn('THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.');
+ return this.multiplyMatrices(m, n);
+ }
+ return this.multiplyMatrices(this, m);
+ };
+ _proto.premultiply = function premultiply(m) {
+ return this.multiplyMatrices(m, this);
+ };
+ _proto.multiplyMatrices = function multiplyMatrices(a, b) {
+ var ae = a.elements;
+ var be = b.elements;
+ var te = this.elements;
+ var a11 = ae[0],
+ a12 = ae[4],
+ a13 = ae[8],
+ a14 = ae[12];
+ var a21 = ae[1],
+ a22 = ae[5],
+ a23 = ae[9],
+ a24 = ae[13];
+ var a31 = ae[2],
+ a32 = ae[6],
+ a33 = ae[10],
+ a34 = ae[14];
+ var a41 = ae[3],
+ a42 = ae[7],
+ a43 = ae[11],
+ a44 = ae[15];
+ var b11 = be[0],
+ b12 = be[4],
+ b13 = be[8],
+ b14 = be[12];
+ var b21 = be[1],
+ b22 = be[5],
+ b23 = be[9],
+ b24 = be[13];
+ var b31 = be[2],
+ b32 = be[6],
+ b33 = be[10],
+ b34 = be[14];
+ var b41 = be[3],
+ b42 = be[7],
+ b43 = be[11],
+ b44 = be[15];
+ te[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
+ te[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
+ te[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
+ te[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
+ te[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
+ te[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
+ te[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
+ te[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
+ te[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
+ te[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
+ te[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
+ te[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
+ te[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
+ te[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
+ te[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
+ te[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
+ return this;
+ };
+ _proto.multiplyScalar = function multiplyScalar(s) {
+ var te = this.elements;
+ te[0] *= s;
+ te[4] *= s;
+ te[8] *= s;
+ te[12] *= s;
+ te[1] *= s;
+ te[5] *= s;
+ te[9] *= s;
+ te[13] *= s;
+ te[2] *= s;
+ te[6] *= s;
+ te[10] *= s;
+ te[14] *= s;
+ te[3] *= s;
+ te[7] *= s;
+ te[11] *= s;
+ te[15] *= s;
+ return this;
+ };
+ _proto.determinant = function determinant() {
+ var te = this.elements;
+ var n11 = te[0],
+ n12 = te[4],
+ n13 = te[8],
+ n14 = te[12];
+ var n21 = te[1],
+ n22 = te[5],
+ n23 = te[9],
+ n24 = te[13];
+ var n31 = te[2],
+ n32 = te[6],
+ n33 = te[10],
+ n34 = te[14];
+ var n41 = te[3],
+ n42 = te[7],
+ n43 = te[11],
+ n44 = te[15];
+ return n41 * (+n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34) + n42 * (+n11 * n23 * n34 - n11 * n24 * n33 + n14 * n21 * n33 - n13 * n21 * n34 + n13 * n24 * n31 - n14 * n23 * n31) + n43 * (+n11 * n24 * n32 - n11 * n22 * n34 - n14 * n21 * n32 + n12 * n21 * n34 + n14 * n22 * n31 - n12 * n24 * n31) + n44 * (-n13 * n22 * n31 - n11 * n23 * n32 + n11 * n22 * n33 + n13 * n21 * n32 - n12 * n21 * n33 + n12 * n23 * n31);
+ };
+ _proto.transpose = function transpose() {
+ var te = this.elements;
+ var tmp;
+ tmp = te[1];
+ te[1] = te[4];
+ te[4] = tmp;
+ tmp = te[2];
+ te[2] = te[8];
+ te[8] = tmp;
+ tmp = te[6];
+ te[6] = te[9];
+ te[9] = tmp;
+ tmp = te[3];
+ te[3] = te[12];
+ te[12] = tmp;
+ tmp = te[7];
+ te[7] = te[13];
+ te[13] = tmp;
+ tmp = te[11];
+ te[11] = te[14];
+ te[14] = tmp;
+ return this;
+ };
+ _proto.setPosition = function setPosition(x, y, z) {
+ var te = this.elements;
+ if (x.isVector3) {
+ te[12] = x.x;
+ te[13] = x.y;
+ te[14] = x.z;
+ } else {
+ te[12] = x;
+ te[13] = y;
+ te[14] = z;
+ }
+ return this;
+ };
+ _proto.invert = function invert() {
+ var te = this.elements,
+ n11 = te[0],
+ n21 = te[1],
+ n31 = te[2],
+ n41 = te[3],
+ n12 = te[4],
+ n22 = te[5],
+ n32 = te[6],
+ n42 = te[7],
+ n13 = te[8],
+ n23 = te[9],
+ n33 = te[10],
+ n43 = te[11],
+ n14 = te[12],
+ n24 = te[13],
+ n34 = te[14],
+ n44 = te[15],
+ t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,
+ t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,
+ t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,
+ t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;
+ var det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;
+ if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ var detInv = 1 / det;
+ te[0] = t11 * detInv;
+ te[1] = (n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44) * detInv;
+ te[2] = (n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44) * detInv;
+ te[3] = (n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43) * detInv;
+ te[4] = t12 * detInv;
+ te[5] = (n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44) * detInv;
+ te[6] = (n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44) * detInv;
+ te[7] = (n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43) * detInv;
+ te[8] = t13 * detInv;
+ te[9] = (n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44) * detInv;
+ te[10] = (n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44) * detInv;
+ te[11] = (n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43) * detInv;
+ te[12] = t14 * detInv;
+ te[13] = (n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34) * detInv;
+ te[14] = (n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34) * detInv;
+ te[15] = (n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33) * detInv;
+ return this;
+ };
+ _proto.scale = function scale(v) {
+ var te = this.elements;
+ var x = v.x,
+ y = v.y,
+ z = v.z;
+ te[0] *= x;
+ te[4] *= y;
+ te[8] *= z;
+ te[1] *= x;
+ te[5] *= y;
+ te[9] *= z;
+ te[2] *= x;
+ te[6] *= y;
+ te[10] *= z;
+ te[3] *= x;
+ te[7] *= y;
+ te[11] *= z;
+ return this;
+ };
+ _proto.getMaxScaleOnAxis = function getMaxScaleOnAxis() {
+ var te = this.elements;
+ var scaleXSq = te[0] * te[0] + te[1] * te[1] + te[2] * te[2];
+ var scaleYSq = te[4] * te[4] + te[5] * te[5] + te[6] * te[6];
+ var scaleZSq = te[8] * te[8] + te[9] * te[9] + te[10] * te[10];
+ return Math.sqrt(Math.max(scaleXSq, scaleYSq, scaleZSq));
+ };
+ _proto.makeTranslation = function makeTranslation(x, y, z) {
+ this.set(1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1);
+ return this;
+ };
+ _proto.makeRotationX = function makeRotationX(theta) {
+ var c = Math.cos(theta),
+ s = Math.sin(theta);
+ this.set(1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1);
+ return this;
+ };
+ _proto.makeRotationY = function makeRotationY(theta) {
+ var c = Math.cos(theta),
+ s = Math.sin(theta);
+ this.set(c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1);
+ return this;
+ };
+ _proto.makeRotationZ = function makeRotationZ(theta) {
+ var c = Math.cos(theta),
+ s = Math.sin(theta);
+ this.set(c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+ return this;
+ };
+ _proto.makeRotationAxis = function makeRotationAxis(axis, angle) {
+ var c = Math.cos(angle);
+ var s = Math.sin(angle);
+ var t = 1 - c;
+ var x = axis.x,
+ y = axis.y,
+ z = axis.z;
+ var tx = t * x,
+ ty = t * y;
+ this.set(tx * x + c, tx * y - s * z, tx * z + s * y, 0, tx * y + s * z, ty * y + c, ty * z - s * x, 0, tx * z - s * y, ty * z + s * x, t * z * z + c, 0, 0, 0, 0, 1);
+ return this;
+ };
+ _proto.makeScale = function makeScale(x, y, z) {
+ this.set(x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1);
+ return this;
+ };
+ _proto.makeShear = function makeShear(x, y, z) {
+ this.set(1, y, z, 0, x, 1, z, 0, x, y, 1, 0, 0, 0, 0, 1);
+ return this;
+ };
+ _proto.compose = function compose(position, quaternion, scale) {
+ var te = this.elements;
+ var x = quaternion._x,
+ y = quaternion._y,
+ z = quaternion._z,
+ w = quaternion._w;
+ var x2 = x + x,
+ y2 = y + y,
+ z2 = z + z;
+ var xx = x * x2,
+ xy = x * y2,
+ xz = x * z2;
+ var yy = y * y2,
+ yz = y * z2,
+ zz = z * z2;
+ var wx = w * x2,
+ wy = w * y2,
+ wz = w * z2;
+ var sx = scale.x,
+ sy = scale.y,
+ sz = scale.z;
+ te[0] = (1 - (yy + zz)) * sx;
+ te[1] = (xy + wz) * sx;
+ te[2] = (xz - wy) * sx;
+ te[3] = 0;
+ te[4] = (xy - wz) * sy;
+ te[5] = (1 - (xx + zz)) * sy;
+ te[6] = (yz + wx) * sy;
+ te[7] = 0;
+ te[8] = (xz + wy) * sz;
+ te[9] = (yz - wx) * sz;
+ te[10] = (1 - (xx + yy)) * sz;
+ te[11] = 0;
+ te[12] = position.x;
+ te[13] = position.y;
+ te[14] = position.z;
+ te[15] = 1;
+ return this;
+ };
+ _proto.decompose = function decompose(position, quaternion, scale) {
+ var te = this.elements;
+ var sx = _v1$1.set(te[0], te[1], te[2]).length();
+ var sy = _v1$1.set(te[4], te[5], te[6]).length();
+ var sz = _v1$1.set(te[8], te[9], te[10]).length();
+ var det = this.determinant();
+ if (det < 0) sx = -sx;
+ position.x = te[12];
+ position.y = te[13];
+ position.z = te[14];
+ _m1.copy(this);
+ var invSX = 1 / sx;
+ var invSY = 1 / sy;
+ var invSZ = 1 / sz;
+ _m1.elements[0] *= invSX;
+ _m1.elements[1] *= invSX;
+ _m1.elements[2] *= invSX;
+ _m1.elements[4] *= invSY;
+ _m1.elements[5] *= invSY;
+ _m1.elements[6] *= invSY;
+ _m1.elements[8] *= invSZ;
+ _m1.elements[9] *= invSZ;
+ _m1.elements[10] *= invSZ;
+ quaternion.setFromRotationMatrix(_m1);
+ scale.x = sx;
+ scale.y = sy;
+ scale.z = sz;
+ return this;
+ };
+ _proto.makePerspective = function makePerspective(left, right, top, bottom, near, far) {
+ if (far === undefined) {
+ console.warn('THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.');
+ }
+ var te = this.elements;
+ var x = 2 * near / (right - left);
+ var y = 2 * near / (top - bottom);
+ var a = (right + left) / (right - left);
+ var b = (top + bottom) / (top - bottom);
+ var c = -(far + near) / (far - near);
+ var d = -2 * far * near / (far - near);
+ te[0] = x;
+ te[4] = 0;
+ te[8] = a;
+ te[12] = 0;
+ te[1] = 0;
+ te[5] = y;
+ te[9] = b;
+ te[13] = 0;
+ te[2] = 0;
+ te[6] = 0;
+ te[10] = c;
+ te[14] = d;
+ te[3] = 0;
+ te[7] = 0;
+ te[11] = -1;
+ te[15] = 0;
+ return this;
+ };
+ _proto.makeOrthographic = function makeOrthographic(left, right, top, bottom, near, far) {
+ var te = this.elements;
+ var w = 1.0 / (right - left);
+ var h = 1.0 / (top - bottom);
+ var p = 1.0 / (far - near);
+ var x = (right + left) * w;
+ var y = (top + bottom) * h;
+ var z = (far + near) * p;
+ te[0] = 2 * w;
+ te[4] = 0;
+ te[8] = 0;
+ te[12] = -x;
+ te[1] = 0;
+ te[5] = 2 * h;
+ te[9] = 0;
+ te[13] = -y;
+ te[2] = 0;
+ te[6] = 0;
+ te[10] = -2 * p;
+ te[14] = -z;
+ te[3] = 0;
+ te[7] = 0;
+ te[11] = 0;
+ te[15] = 1;
+ return this;
+ };
+ _proto.equals = function equals(matrix) {
+ var te = this.elements;
+ var me = matrix.elements;
+ for (var i = 0; i < 16; i++) {
+ if (te[i] !== me[i]) return false;
+ }
+ return true;
+ };
+ _proto.fromArray = function fromArray(array, offset) {
+ if (offset === void 0) {
+ offset = 0;
+ }
+ for (var i = 0; i < 16; i++) {
+ this.elements[i] = array[i + offset];
+ }
+ return this;
+ };
+ _proto.toArray = function toArray(array, offset) {
+ if (array === void 0) {
+ array = [];
+ }
+ if (offset === void 0) {
+ offset = 0;
+ }
+ var te = this.elements;
+ array[offset] = te[0];
+ array[offset + 1] = te[1];
+ array[offset + 2] = te[2];
+ array[offset + 3] = te[3];
+ array[offset + 4] = te[4];
+ array[offset + 5] = te[5];
+ array[offset + 6] = te[6];
+ array[offset + 7] = te[7];
+ array[offset + 8] = te[8];
+ array[offset + 9] = te[9];
+ array[offset + 10] = te[10];
+ array[offset + 11] = te[11];
+ array[offset + 12] = te[12];
+ array[offset + 13] = te[13];
+ array[offset + 14] = te[14];
+ array[offset + 15] = te[15];
+ return array;
+ };
+ return Matrix4;
+ }();
+ var _v1$1 = /*@__PURE__*/new Vector3();
+ var _m1 = /*@__PURE__*/new Matrix4();
+ var _zero = /*@__PURE__*/new Vector3(0, 0, 0);
+ var _one = /*@__PURE__*/new Vector3(1, 1, 1);
+ var _x = /*@__PURE__*/new Vector3();
+ var _y = /*@__PURE__*/new Vector3();
+ var _z = /*@__PURE__*/new Vector3();
+ var Euler = /*#__PURE__*/function () {
+ function Euler(x, y, z, order) {
+ if (x === void 0) {
+ x = 0;
+ }
+ if (y === void 0) {
+ y = 0;
+ }
+ if (z === void 0) {
+ z = 0;
+ }
+ if (order === void 0) {
+ order = Euler.DefaultOrder;
+ }
+ Object.defineProperty(this, 'isEuler', {
+ value: true
+ });
+ this._x = x;
+ this._y = y;
+ this._z = z;
+ this._order = order;
+ }
+ var _proto = Euler.prototype;
+ _proto.set = function set(x, y, z, order) {
+ this._x = x;
+ this._y = y;
+ this._z = z;
+ this._order = order || this._order;
+ this._onChangeCallback();
+ return this;
+ };
+ _proto.clone = function clone() {
+ return new this.constructor(this._x, this._y, this._z, this._order);
+ };
+ _proto.copy = function copy(euler) {
+ this._x = euler._x;
+ this._y = euler._y;
+ this._z = euler._z;
+ this._order = euler._order;
+ this._onChangeCallback();
+ return this;
+ };
+ _proto.setFromRotationMatrix = function setFromRotationMatrix(m, order, update) {
+ var clamp = MathUtils.clamp; // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
+ var te = m.elements;
+ var m11 = te[0],
+ m12 = te[4],
+ m13 = te[8];
+ var m21 = te[1],
+ m22 = te[5],
+ m23 = te[9];
+ var m31 = te[2],
+ m32 = te[6],
+ m33 = te[10];
+ order = order || this._order;
+ switch (order) {
+ case 'XYZ':
+ this._y = Math.asin(clamp(m13, -1, 1));
+ if (Math.abs(m13) < 0.9999999) {
+ this._x = Math.atan2(-m23, m33);
+ this._z = Math.atan2(-m12, m11);
+ } else {
+ this._x = Math.atan2(m32, m22);
+ this._z = 0;
+ }
+ break;
+ case 'YXZ':
+ this._x = Math.asin(-clamp(m23, -1, 1));
+ if (Math.abs(m23) < 0.9999999) {
+ this._y = Math.atan2(m13, m33);
+ this._z = Math.atan2(m21, m22);
+ } else {
+ this._y = Math.atan2(-m31, m11);
+ this._z = 0;
+ }
+ break;
+ case 'ZXY':
+ this._x = Math.asin(clamp(m32, -1, 1));
+ if (Math.abs(m32) < 0.9999999) {
+ this._y = Math.atan2(-m31, m33);
+ this._z = Math.atan2(-m12, m22);
+ } else {
+ this._y = 0;
+ this._z = Math.atan2(m21, m11);
+ }
+ break;
+ case 'ZYX':
+ this._y = Math.asin(-clamp(m31, -1, 1));
+ if (Math.abs(m31) < 0.9999999) {
+ this._x = Math.atan2(m32, m33);
+ this._z = Math.atan2(m21, m11);
+ } else {
+ this._x = 0;
+ this._z = Math.atan2(-m12, m22);
+ }
+ break;
+ case 'YZX':
+ this._z = Math.asin(clamp(m21, -1, 1));
+ if (Math.abs(m21) < 0.9999999) {
+ this._x = Math.atan2(-m23, m22);
+ this._y = Math.atan2(-m31, m11);
+ } else {
+ this._x = 0;
+ this._y = Math.atan2(m13, m33);
+ }
+ break;
+ case 'XZY':
+ this._z = Math.asin(-clamp(m12, -1, 1));
+ if (Math.abs(m12) < 0.9999999) {
+ this._x = Math.atan2(m32, m22);
+ this._y = Math.atan2(m13, m11);
+ } else {
+ this._x = Math.atan2(-m23, m33);
+ this._y = 0;
+ }
+ break;
+ default:
+ console.warn('THREE.Euler: .setFromRotationMatrix() encountered an unknown order: ' + order);
+ }
+ this._order = order;
+ if (update !== false) this._onChangeCallback();
+ return this;
+ };
+ _proto.setFromQuaternion = function setFromQuaternion(q, order, update) {
+ _matrix.makeRotationFromQuaternion(q);
+ return this.setFromRotationMatrix(_matrix, order, update);
+ };
+ _proto.setFromVector3 = function setFromVector3(v, order) {
+ return this.set(v.x, v.y, v.z, order || this._order);
+ };
+ _proto.reorder = function reorder(newOrder) {
+ // WARNING: this discards revolution information -bhouston
+ _quaternion$1.setFromEuler(this);
+ return this.setFromQuaternion(_quaternion$1, newOrder);
+ };
+ _proto.equals = function equals(euler) {
+ return euler._x === this._x && euler._y === this._y && euler._z === this._z && euler._order === this._order;
+ };
+ _proto.fromArray = function fromArray(array) {
+ this._x = array[0];
+ this._y = array[1];
+ this._z = array[2];
+ if (array[3] !== undefined) this._order = array[3];
+ this._onChangeCallback();
+ return this;
+ };
+ _proto.toArray = function toArray(array, offset) {
+ if (array === void 0) {
+ array = [];
+ }
+ if (offset === void 0) {
+ offset = 0;
+ }
+ array[offset] = this._x;
+ array[offset + 1] = this._y;
+ array[offset + 2] = this._z;
+ array[offset + 3] = this._order;
+ return array;
+ };
+ _proto.toVector3 = function toVector3(optionalResult) {
+ if (optionalResult) {
+ return optionalResult.set(this._x, this._y, this._z);
+ } else {
+ return new Vector3(this._x, this._y, this._z);
+ }
+ };
+ _proto._onChange = function _onChange(callback) {
+ this._onChangeCallback = callback;
+ return this;
+ };
+ _proto._onChangeCallback = function _onChangeCallback() {};
+ _createClass(Euler, [{
+ key: "x",
+ get: function get() {
+ return this._x;
+ },
+ set: function set(value) {
+ this._x = value;
+ this._onChangeCallback();
+ }
+ }, {
+ key: "y",
+ get: function get() {
+ return this._y;
+ },
+ set: function set(value) {
+ this._y = value;
+ this._onChangeCallback();
+ }
+ }, {
+ key: "z",
+ get: function get() {
+ return this._z;
+ },
+ set: function set(value) {
+ this._z = value;
+ this._onChangeCallback();
+ }
+ }, {
+ key: "order",
+ get: function get() {
+ return this._order;
+ },
+ set: function set(value) {
+ this._order = value;
+ this._onChangeCallback();
+ }
+ }]);
+ return Euler;
+ }();
+ Euler.DefaultOrder = 'XYZ';
+ Euler.RotationOrders = ['XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX'];
+ var _matrix = /*@__PURE__*/new Matrix4();
+ var _quaternion$1 = /*@__PURE__*/new Quaternion();
+ var Layers = /*#__PURE__*/function () {
+ function Layers() {
+ this.mask = 1 | 0;
+ }
+ var _proto = Layers.prototype;
+ _proto.set = function set(channel) {
+ this.mask = 1 << channel | 0;
+ };
+ _proto.enable = function enable(channel) {
+ this.mask |= 1 << channel | 0;
+ };
+ _proto.enableAll = function enableAll() {
+ this.mask = 0xffffffff | 0;
+ };
+ _proto.toggle = function toggle(channel) {
+ this.mask ^= 1 << channel | 0;
+ };
+ _proto.disable = function disable(channel) {
+ this.mask &= ~(1 << channel | 0);
+ };
+ _proto.disableAll = function disableAll() {
+ this.mask = 0;
+ };
+ _proto.test = function test(layers) {
+ return (this.mask & layers.mask) !== 0;
+ };
+ return Layers;
+ }();
+ var _object3DId = 0;
+ var _v1$2 = new Vector3();
+ var _q1 = new Quaternion();
+ var _m1$1 = new Matrix4();
+ var _target = new Vector3();
+ var _position = new Vector3();
+ var _scale = new Vector3();
+ var _quaternion$2 = new Quaternion();
+ var _xAxis = new Vector3(1, 0, 0);
+ var _yAxis = new Vector3(0, 1, 0);
+ var _zAxis = new Vector3(0, 0, 1);
+ var _addedEvent = {
+ type: 'added'
+ };
+ var _removedEvent = {
+ type: 'removed'
+ };
+ function Object3D() {
+ Object.defineProperty(this, 'id', {
+ value: _object3DId++
+ });
+ this.uuid = MathUtils.generateUUID();
+ this.name = '';
+ this.type = 'Object3D';
+ this.parent = null;
+ this.children = [];
+ this.up = Object3D.DefaultUp.clone();
+ var position = new Vector3();
+ var rotation = new Euler();
+ var quaternion = new Quaternion();
+ var scale = new Vector3(1, 1, 1);
+ function onRotationChange() {
+ quaternion.setFromEuler(rotation, false);
+ }
+ function onQuaternionChange() {
+ rotation.setFromQuaternion(quaternion, undefined, false);
+ }
+ rotation._onChange(onRotationChange);
+ quaternion._onChange(onQuaternionChange);
+ Object.defineProperties(this, {
+ position: {
+ configurable: true,
+ enumerable: true,
+ value: position
+ },
+ rotation: {
+ configurable: true,
+ enumerable: true,
+ value: rotation
+ },
+ quaternion: {
+ configurable: true,
+ enumerable: true,
+ value: quaternion
+ },
+ scale: {
+ configurable: true,
+ enumerable: true,
+ value: scale
+ },
+ modelViewMatrix: {
+ value: new Matrix4()
+ },
+ normalMatrix: {
+ value: new Matrix3()
+ }
+ });
+ this.matrix = new Matrix4();
+ this.matrixWorld = new Matrix4();
+ this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;
+ this.matrixWorldNeedsUpdate = false;
+ this.layers = new Layers();
+ this.visible = true;
+ this.castShadow = false;
+ this.receiveShadow = false;
+ this.frustumCulled = true;
+ this.renderOrder = 0;
+ this.animations = [];
+ this.userData = {};
+ }
+ Object3D.DefaultUp = new Vector3(0, 1, 0);
+ Object3D.DefaultMatrixAutoUpdate = true;
+ Object3D.prototype = Object.assign(Object.create(EventDispatcher.prototype), {
+ constructor: Object3D,
+ isObject3D: true,
+ onBeforeRender: function onBeforeRender() {},
+ onAfterRender: function onAfterRender() {},
+ applyMatrix4: function applyMatrix4(matrix) {
+ if (this.matrixAutoUpdate) this.updateMatrix();
+ this.matrix.premultiply(matrix);
+ this.matrix.decompose(this.position, this.quaternion, this.scale);
+ },
+ applyQuaternion: function applyQuaternion(q) {
+ this.quaternion.premultiply(q);
+ return this;
+ },
+ setRotationFromAxisAngle: function setRotationFromAxisAngle(axis, angle) {
+ // assumes axis is normalized
+ this.quaternion.setFromAxisAngle(axis, angle);
+ },
+ setRotationFromEuler: function setRotationFromEuler(euler) {
+ this.quaternion.setFromEuler(euler, true);
+ },
+ setRotationFromMatrix: function setRotationFromMatrix(m) {
+ // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
+ this.quaternion.setFromRotationMatrix(m);
+ },
+ setRotationFromQuaternion: function setRotationFromQuaternion(q) {
+ // assumes q is normalized
+ this.quaternion.copy(q);
+ },
+ rotateOnAxis: function rotateOnAxis(axis, angle) {
+ // rotate object on axis in object space
+ // axis is assumed to be normalized
+ _q1.setFromAxisAngle(axis, angle);
+ this.quaternion.multiply(_q1);
+ return this;
+ },
+ rotateOnWorldAxis: function rotateOnWorldAxis(axis, angle) {
+ // rotate object on axis in world space
+ // axis is assumed to be normalized
+ // method assumes no rotated parent
+ _q1.setFromAxisAngle(axis, angle);
+ this.quaternion.premultiply(_q1);
+ return this;
+ },
+ rotateX: function rotateX(angle) {
+ return this.rotateOnAxis(_xAxis, angle);
+ },
+ rotateY: function rotateY(angle) {
+ return this.rotateOnAxis(_yAxis, angle);
+ },
+ rotateZ: function rotateZ(angle) {
+ return this.rotateOnAxis(_zAxis, angle);
+ },
+ translateOnAxis: function translateOnAxis(axis, distance) {
+ // translate object by distance along axis in object space
+ // axis is assumed to be normalized
+ _v1$2.copy(axis).applyQuaternion(this.quaternion);
+ this.position.add(_v1$2.multiplyScalar(distance));
+ return this;
+ },
+ translateX: function translateX(distance) {
+ return this.translateOnAxis(_xAxis, distance);
+ },
+ translateY: function translateY(distance) {
+ return this.translateOnAxis(_yAxis, distance);
+ },
+ translateZ: function translateZ(distance) {
+ return this.translateOnAxis(_zAxis, distance);
+ },
+ localToWorld: function localToWorld(vector) {
+ return vector.applyMatrix4(this.matrixWorld);
+ },
+ worldToLocal: function worldToLocal(vector) {
+ return vector.applyMatrix4(_m1$1.copy(this.matrixWorld).invert());
+ },
+ lookAt: function lookAt(x, y, z) {
+ // This method does not support objects having non-uniformly-scaled parent(s)
+ if (x.isVector3) {
+ _target.copy(x);
+ } else {
+ _target.set(x, y, z);
+ }
+ var parent = this.parent;
+ this.updateWorldMatrix(true, false);
+ _position.setFromMatrixPosition(this.matrixWorld);
+ if (this.isCamera || this.isLight) {
+ _m1$1.lookAt(_position, _target, this.up);
+ } else {
+ _m1$1.lookAt(_target, _position, this.up);
+ }
+ this.quaternion.setFromRotationMatrix(_m1$1);
+ if (parent) {
+ _m1$1.extractRotation(parent.matrixWorld);
+ _q1.setFromRotationMatrix(_m1$1);
+ this.quaternion.premultiply(_q1.invert());
+ }
+ },
+ add: function add(object) {
+ if (arguments.length > 1) {
+ for (var i = 0; i < arguments.length; i++) {
+ this.add(arguments[i]);
+ }
+ return this;
+ }
+ if (object === this) {
+ console.error('THREE.Object3D.add: object can\'t be added as a child of itself.', object);
+ return this;
+ }
+ if (object && object.isObject3D) {
+ if (object.parent !== null) {
+ object.parent.remove(object);
+ }
+ object.parent = this;
+ this.children.push(object);
+ object.dispatchEvent(_addedEvent);
+ } else {
+ console.error('THREE.Object3D.add: object not an instance of THREE.Object3D.', object);
+ }
+ return this;
+ },
+ remove: function remove(object) {
+ if (arguments.length > 1) {
+ for (var i = 0; i < arguments.length; i++) {
+ this.remove(arguments[i]);
+ }
+ return this;
+ }
+ var index = this.children.indexOf(object);
+ if (index !== -1) {
+ object.parent = null;
+ this.children.splice(index, 1);
+ object.dispatchEvent(_removedEvent);
+ }
+ return this;
+ },
+ clear: function clear() {
+ for (var i = 0; i < this.children.length; i++) {
+ var object = this.children[i];
+ object.parent = null;
+ object.dispatchEvent(_removedEvent);
+ }
+ this.children.length = 0;
+ return this;
+ },
+ attach: function attach(object) {
+ // adds object as a child of this, while maintaining the object's world transform
+ this.updateWorldMatrix(true, false);
+ _m1$1.copy(this.matrixWorld).invert();
+ if (object.parent !== null) {
+ object.parent.updateWorldMatrix(true, false);
+ _m1$1.multiply(object.parent.matrixWorld);
+ }
+ object.applyMatrix4(_m1$1);
+ object.updateWorldMatrix(false, false);
+ this.add(object);
+ return this;
+ },
+ getObjectById: function getObjectById(id) {
+ return this.getObjectByProperty('id', id);
+ },
+ getObjectByName: function getObjectByName(name) {
+ return this.getObjectByProperty('name', name);
+ },
+ getObjectByProperty: function getObjectByProperty(name, value) {
+ if (this[name] === value) return this;
+ for (var i = 0, l = this.children.length; i < l; i++) {
+ var child = this.children[i];
+ var object = child.getObjectByProperty(name, value);
+ if (object !== undefined) {
+ return object;
+ }
+ }
+ return undefined;
+ },
+ getWorldPosition: function getWorldPosition(target) {
+ if (target === undefined) {
+ console.warn('THREE.Object3D: .getWorldPosition() target is now required');
+ target = new Vector3();
+ }
+ this.updateWorldMatrix(true, false);
+ return target.setFromMatrixPosition(this.matrixWorld);
+ },
+ getWorldQuaternion: function getWorldQuaternion(target) {
+ if (target === undefined) {
+ console.warn('THREE.Object3D: .getWorldQuaternion() target is now required');
+ target = new Quaternion();
+ }
+ this.updateWorldMatrix(true, false);
+ this.matrixWorld.decompose(_position, target, _scale);
+ return target;
+ },
+ getWorldScale: function getWorldScale(target) {
+ if (target === undefined) {
+ console.warn('THREE.Object3D: .getWorldScale() target is now required');
+ target = new Vector3();
+ }
+ this.updateWorldMatrix(true, false);
+ this.matrixWorld.decompose(_position, _quaternion$2, target);
+ return target;
+ },
+ getWorldDirection: function getWorldDirection(target) {
+ if (target === undefined) {
+ console.warn('THREE.Object3D: .getWorldDirection() target is now required');
+ target = new Vector3();
+ }
+ this.updateWorldMatrix(true, false);
+ var e = this.matrixWorld.elements;
+ return target.set(e[8], e[9], e[10]).normalize();
+ },
+ raycast: function raycast() {},
+ traverse: function traverse(callback) {
+ callback(this);
+ var children = this.children;
+ for (var i = 0, l = children.length; i < l; i++) {
+ children[i].traverse(callback);
+ }
+ },
+ traverseVisible: function traverseVisible(callback) {
+ if (this.visible === false) return;
+ callback(this);
+ var children = this.children;
+ for (var i = 0, l = children.length; i < l; i++) {
+ children[i].traverseVisible(callback);
+ }
+ },
+ traverseAncestors: function traverseAncestors(callback) {
+ var parent = this.parent;
+ if (parent !== null) {
+ callback(parent);
+ parent.traverseAncestors(callback);
+ }
+ },
+ updateMatrix: function updateMatrix() {
+ this.matrix.compose(this.position, this.quaternion, this.scale);
+ this.matrixWorldNeedsUpdate = true;
+ },
+ updateMatrixWorld: function updateMatrixWorld(force) {
+ if (this.matrixAutoUpdate) this.updateMatrix();
+ if (this.matrixWorldNeedsUpdate || force) {
+ if (this.parent === null) {
+ this.matrixWorld.copy(this.matrix);
+ } else {
+ this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix);
+ }
+ this.matrixWorldNeedsUpdate = false;
+ force = true;
+ } // update children
+
+ var children = this.children;
+ for (var i = 0, l = children.length; i < l; i++) {
+ children[i].updateMatrixWorld(force);
+ }
+ },
+ updateWorldMatrix: function updateWorldMatrix(updateParents, updateChildren) {
+ var parent = this.parent;
+ if (updateParents === true && parent !== null) {
+ parent.updateWorldMatrix(true, false);
+ }
+ if (this.matrixAutoUpdate) this.updateMatrix();
+ if (this.parent === null) {
+ this.matrixWorld.copy(this.matrix);
+ } else {
+ this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix);
+ } // update children
+
+ if (updateChildren === true) {
+ var children = this.children;
+ for (var i = 0, l = children.length; i < l; i++) {
+ children[i].updateWorldMatrix(false, true);
+ }
+ }
+ },
+ toJSON: function toJSON(meta) {
+ // meta is a string when called from JSON.stringify
+ var isRootObject = meta === undefined || typeof meta === 'string';
+ var output = {}; // meta is a hash used to collect geometries, materials.
+ // not providing it implies that this is the root object
+ // being serialized.
+ if (isRootObject) {
+ // initialize meta obj
+ meta = {
+ geometries: {},
+ materials: {},
+ textures: {},
+ images: {},
+ shapes: {},
+ skeletons: {},
+ animations: {}
+ };
+ output.metadata = {
+ version: 4.5,
+ type: 'Object',
+ generator: 'Object3D.toJSON'
+ };
+ } // standard Object3D serialization
+
+ var object = {};
+ object.uuid = this.uuid;
+ object.type = this.type;
+ if (this.name !== '') object.name = this.name;
+ if (this.castShadow === true) object.castShadow = true;
+ if (this.receiveShadow === true) object.receiveShadow = true;
+ if (this.visible === false) object.visible = false;
+ if (this.frustumCulled === false) object.frustumCulled = false;
+ if (this.renderOrder !== 0) object.renderOrder = this.renderOrder;
+ if (JSON.stringify(this.userData) !== '{}') object.userData = this.userData;
+ object.layers = this.layers.mask;
+ object.matrix = this.matrix.toArray();
+ if (this.matrixAutoUpdate === false) object.matrixAutoUpdate = false; // object specific properties
+ if (this.isInstancedMesh) {
+ object.type = 'InstancedMesh';
+ object.count = this.count;
+ object.instanceMatrix = this.instanceMatrix.toJSON();
+ } //
+
+ function serialize(library, element) {
+ if (library[element.uuid] === undefined) {
+ library[element.uuid] = element.toJSON(meta);
+ }
+ return element.uuid;
+ }
+ if (this.isMesh || this.isLine || this.isPoints) {
+ object.geometry = serialize(meta.geometries, this.geometry);
+ var parameters = this.geometry.parameters;
+ if (parameters !== undefined && parameters.shapes !== undefined) {
+ var shapes = parameters.shapes;
+ if (Array.isArray(shapes)) {
+ for (var i = 0, l = shapes.length; i < l; i++) {
+ var shape = shapes[i];
+ serialize(meta.shapes, shape);
+ }
+ } else {
+ serialize(meta.shapes, shapes);
+ }
+ }
+ }
+ if (this.isSkinnedMesh) {
+ object.bindMode = this.bindMode;
+ object.bindMatrix = this.bindMatrix.toArray();
+ if (this.skeleton !== undefined) {
+ serialize(meta.skeletons, this.skeleton);
+ object.skeleton = this.skeleton.uuid;
+ }
+ }
+ if (this.material !== undefined) {
+ if (Array.isArray(this.material)) {
+ var uuids = [];
+ for (var _i = 0, _l = this.material.length; _i < _l; _i++) {
+ uuids.push(serialize(meta.materials, this.material[_i]));
+ }
+ object.material = uuids;
+ } else {
+ object.material = serialize(meta.materials, this.material);
+ }
+ } //
+
+ if (this.children.length > 0) {
+ object.children = [];
+ for (var _i2 = 0; _i2 < this.children.length; _i2++) {
+ object.children.push(this.children[_i2].toJSON(meta).object);
+ }
+ } //
+
+ if (this.animations.length > 0) {
+ object.animations = [];
+ for (var _i3 = 0; _i3 < this.animations.length; _i3++) {
+ var animation = this.animations[_i3];
+ object.animations.push(serialize(meta.animations, animation));
+ }
+ }
+ if (isRootObject) {
+ var geometries = extractFromCache(meta.geometries);
+ var materials = extractFromCache(meta.materials);
+ var textures = extractFromCache(meta.textures);
+ var images = extractFromCache(meta.images);
+ var _shapes = extractFromCache(meta.shapes);
+ var skeletons = extractFromCache(meta.skeletons);
+ var animations = extractFromCache(meta.animations);
+ if (geometries.length > 0) output.geometries = geometries;
+ if (materials.length > 0) output.materials = materials;
+ if (textures.length > 0) output.textures = textures;
+ if (images.length > 0) output.images = images;
+ if (_shapes.length > 0) output.shapes = _shapes;
+ if (skeletons.length > 0) output.skeletons = skeletons;
+ if (animations.length > 0) output.animations = animations;
+ }
+ output.object = object;
+ return output; // extract data from the cache hash
+ // remove metadata on each item
+ // and return as array
+ function extractFromCache(cache) {
+ var values = [];
+ for (var key in cache) {
+ var data = cache[key];
+ delete data.metadata;
+ values.push(data);
+ }
+ return values;
+ }
+ },
+ clone: function clone(recursive) {
+ return new this.constructor().copy(this, recursive);
+ },
+ copy: function copy(source, recursive) {
+ if (recursive === void 0) {
+ recursive = true;
+ }
+ this.name = source.name;
+ this.up.copy(source.up);
+ this.position.copy(source.position);
+ this.rotation.order = source.rotation.order;
+ this.quaternion.copy(source.quaternion);
+ this.scale.copy(source.scale);
+ this.matrix.copy(source.matrix);
+ this.matrixWorld.copy(source.matrixWorld);
+ this.matrixAutoUpdate = source.matrixAutoUpdate;
+ this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;
+ this.layers.mask = source.layers.mask;
+ this.visible = source.visible;
+ this.castShadow = source.castShadow;
+ this.receiveShadow = source.receiveShadow;
+ this.frustumCulled = source.frustumCulled;
+ this.renderOrder = source.renderOrder;
+ this.userData = JSON.parse(JSON.stringify(source.userData));
+ if (recursive === true) {
+ for (var i = 0; i < source.children.length; i++) {
+ var child = source.children[i];
+ this.add(child.clone());
+ }
+ }
+ return this;
+ }
+ });
+ var _vector1 = /*@__PURE__*/new Vector3();
+ var _vector2 = /*@__PURE__*/new Vector3();
+ var _normalMatrix = /*@__PURE__*/new Matrix3();
+ var Plane = /*#__PURE__*/function () {
+ function Plane(normal, constant) {
+ Object.defineProperty(this, 'isPlane', {
+ value: true
+ }); // normal is assumed to be normalized
+ this.normal = normal !== undefined ? normal : new Vector3(1, 0, 0);
+ this.constant = constant !== undefined ? constant : 0;
+ }
+ var _proto = Plane.prototype;
+ _proto.set = function set(normal, constant) {
+ this.normal.copy(normal);
+ this.constant = constant;
+ return this;
+ };
+ _proto.setComponents = function setComponents(x, y, z, w) {
+ this.normal.set(x, y, z);
+ this.constant = w;
+ return this;
+ };
+ _proto.setFromNormalAndCoplanarPoint = function setFromNormalAndCoplanarPoint(normal, point) {
+ this.normal.copy(normal);
+ this.constant = -point.dot(this.normal);
+ return this;
+ };
+ _proto.setFromCoplanarPoints = function setFromCoplanarPoints(a, b, c) {
+ var normal = _vector1.subVectors(c, b).cross(_vector2.subVectors(a, b)).normalize(); // Q: should an error be thrown if normal is zero (e.g. degenerate plane)?
+
+ this.setFromNormalAndCoplanarPoint(normal, a);
+ return this;
+ };
+ _proto.clone = function clone() {
+ return new this.constructor().copy(this);
+ };
+ _proto.copy = function copy(plane) {
+ this.normal.copy(plane.normal);
+ this.constant = plane.constant;
+ return this;
+ };
+ _proto.normalize = function normalize() {
+ // Note: will lead to a divide by zero if the plane is invalid.
+ var inverseNormalLength = 1.0 / this.normal.length();
+ this.normal.multiplyScalar(inverseNormalLength);
+ this.constant *= inverseNormalLength;
+ return this;
+ };
+ _proto.negate = function negate() {
+ this.constant *= -1;
+ this.normal.negate();
+ return this;
+ };
+ _proto.distanceToPoint = function distanceToPoint(point) {
+ return this.normal.dot(point) + this.constant;
+ };
+ _proto.distanceToSphere = function distanceToSphere(sphere) {
+ return this.distanceToPoint(sphere.center) - sphere.radius;
+ };
+ _proto.projectPoint = function projectPoint(point, target) {
+ if (target === undefined) {
+ console.warn('THREE.Plane: .projectPoint() target is now required');
+ target = new Vector3();
+ }
+ return target.copy(this.normal).multiplyScalar(-this.distanceToPoint(point)).add(point);
+ };
+ _proto.intersectLine = function intersectLine(line, target) {
+ if (target === undefined) {
+ console.warn('THREE.Plane: .intersectLine() target is now required');
+ target = new Vector3();
+ }
+ var direction = line.delta(_vector1);
+ var denominator = this.normal.dot(direction);
+ if (denominator === 0) {
+ // line is coplanar, return origin
+ if (this.distanceToPoint(line.start) === 0) {
+ return target.copy(line.start);
+ } // Unsure if this is the correct method to handle this case.
+
+ return undefined;
+ }
+ var t = -(line.start.dot(this.normal) + this.constant) / denominator;
+ if (t < 0 || t > 1) {
+ return undefined;
+ }
+ return target.copy(direction).multiplyScalar(t).add(line.start);
+ };
+ _proto.intersectsLine = function intersectsLine(line) {
+ // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.
+ var startSign = this.distanceToPoint(line.start);
+ var endSign = this.distanceToPoint(line.end);
+ return startSign < 0 && endSign > 0 || endSign < 0 && startSign > 0;
+ };
+ _proto.intersectsBox = function intersectsBox(box) {
+ return box.intersectsPlane(this);
+ };
+ _proto.intersectsSphere = function intersectsSphere(sphere) {
+ return sphere.intersectsPlane(this);
+ };
+ _proto.coplanarPoint = function coplanarPoint(target) {
+ if (target === undefined) {
+ console.warn('THREE.Plane: .coplanarPoint() target is now required');
+ target = new Vector3();
+ }
+ return target.copy(this.normal).multiplyScalar(-this.constant);
+ };
+ _proto.applyMatrix4 = function applyMatrix4(matrix, optionalNormalMatrix) {
+ var normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix(matrix);
+ var referencePoint = this.coplanarPoint(_vector1).applyMatrix4(matrix);
+ var normal = this.normal.applyMatrix3(normalMatrix).normalize();
+ this.constant = -referencePoint.dot(normal);
+ return this;
+ };
+ _proto.translate = function translate(offset) {
+ this.constant -= offset.dot(this.normal);
+ return this;
+ };
+ _proto.equals = function equals(plane) {
+ return plane.normal.equals(this.normal) && plane.constant === this.constant;
+ };
+ return Plane;
+ }();
+ var _v0$1 = /*@__PURE__*/new Vector3();
+ var _v1$3 = /*@__PURE__*/new Vector3();
+ var _v2$1 = /*@__PURE__*/new Vector3();
+ var _v3 = /*@__PURE__*/new Vector3();
+ var _vab = /*@__PURE__*/new Vector3();
+ var _vac = /*@__PURE__*/new Vector3();
+ var _vbc = /*@__PURE__*/new Vector3();
+ var _vap = /*@__PURE__*/new Vector3();
+ var _vbp = /*@__PURE__*/new Vector3();
+ var _vcp = /*@__PURE__*/new Vector3();
+ var Triangle = /*#__PURE__*/function () {
+ function Triangle(a, b, c) {
+ this.a = a !== undefined ? a : new Vector3();
+ this.b = b !== undefined ? b : new Vector3();
+ this.c = c !== undefined ? c : new Vector3();
+ }
+ Triangle.getNormal = function getNormal(a, b, c, target) {
+ if (target === undefined) {
+ console.warn('THREE.Triangle: .getNormal() target is now required');
+ target = new Vector3();
+ }
+ target.subVectors(c, b);
+ _v0$1.subVectors(a, b);
+ target.cross(_v0$1);
+ var targetLengthSq = target.lengthSq();
+ if (targetLengthSq > 0) {
+ return target.multiplyScalar(1 / Math.sqrt(targetLengthSq));
+ }
+ return target.set(0, 0, 0);
+ } // static/instance method to calculate barycentric coordinates
+ // based on: http://www.blackpawn.com/texts/pointinpoly/default.html
+ ;
+ Triangle.getBarycoord = function getBarycoord(point, a, b, c, target) {
+ _v0$1.subVectors(c, a);
+ _v1$3.subVectors(b, a);
+ _v2$1.subVectors(point, a);
+ var dot00 = _v0$1.dot(_v0$1);
+ var dot01 = _v0$1.dot(_v1$3);
+ var dot02 = _v0$1.dot(_v2$1);
+ var dot11 = _v1$3.dot(_v1$3);
+ var dot12 = _v1$3.dot(_v2$1);
+ var denom = dot00 * dot11 - dot01 * dot01;
+ if (target === undefined) {
+ console.warn('THREE.Triangle: .getBarycoord() target is now required');
+ target = new Vector3();
+ } // collinear or singular triangle
+
+ if (denom === 0) {
+ // arbitrary location outside of triangle?
+ // not sure if this is the best idea, maybe should be returning undefined
+ return target.set(-2, -1, -1);
+ }
+ var invDenom = 1 / denom;
+ var u = (dot11 * dot02 - dot01 * dot12) * invDenom;
+ var v = (dot00 * dot12 - dot01 * dot02) * invDenom; // barycentric coordinates must always sum to 1
+ return target.set(1 - u - v, v, u);
+ };
+ Triangle.containsPoint = function containsPoint(point, a, b, c) {
+ this.getBarycoord(point, a, b, c, _v3);
+ return _v3.x >= 0 && _v3.y >= 0 && _v3.x + _v3.y <= 1;
+ };
+ Triangle.getUV = function getUV(point, p1, p2, p3, uv1, uv2, uv3, target) {
+ this.getBarycoord(point, p1, p2, p3, _v3);
+ target.set(0, 0);
+ target.addScaledVector(uv1, _v3.x);
+ target.addScaledVector(uv2, _v3.y);
+ target.addScaledVector(uv3, _v3.z);
+ return target;
+ };
+ Triangle.isFrontFacing = function isFrontFacing(a, b, c, direction) {
+ _v0$1.subVectors(c, b);
+ _v1$3.subVectors(a, b); // strictly front facing
+
+ return _v0$1.cross(_v1$3).dot(direction) < 0 ? true : false;
+ };
+ var _proto = Triangle.prototype;
+ _proto.set = function set(a, b, c) {
+ this.a.copy(a);
+ this.b.copy(b);
+ this.c.copy(c);
+ return this;
+ };
+ _proto.setFromPointsAndIndices = function setFromPointsAndIndices(points, i0, i1, i2) {
+ this.a.copy(points[i0]);
+ this.b.copy(points[i1]);
+ this.c.copy(points[i2]);
+ return this;
+ };
+ _proto.clone = function clone() {
+ return new this.constructor().copy(this);
+ };
+ _proto.copy = function copy(triangle) {
+ this.a.copy(triangle.a);
+ this.b.copy(triangle.b);
+ this.c.copy(triangle.c);
+ return this;
+ };
+ _proto.getArea = function getArea() {
+ _v0$1.subVectors(this.c, this.b);
+ _v1$3.subVectors(this.a, this.b);
+ return _v0$1.cross(_v1$3).length() * 0.5;
+ };
+ _proto.getMidpoint = function getMidpoint(target) {
+ if (target === undefined) {
+ console.warn('THREE.Triangle: .getMidpoint() target is now required');
+ target = new Vector3();
+ }
+ return target.addVectors(this.a, this.b).add(this.c).multiplyScalar(1 / 3);
+ };
+ _proto.getNormal = function getNormal(target) {
+ return Triangle.getNormal(this.a, this.b, this.c, target);
+ };
+ _proto.getPlane = function getPlane(target) {
+ if (target === undefined) {
+ console.warn('THREE.Triangle: .getPlane() target is now required');
+ target = new Plane();
+ }
+ return target.setFromCoplanarPoints(this.a, this.b, this.c);
+ };
+ _proto.getBarycoord = function getBarycoord(point, target) {
+ return Triangle.getBarycoord(point, this.a, this.b, this.c, target);
+ };
+ _proto.getUV = function getUV(point, uv1, uv2, uv3, target) {
+ return Triangle.getUV(point, this.a, this.b, this.c, uv1, uv2, uv3, target);
+ };
+ _proto.containsPoint = function containsPoint(point) {
+ return Triangle.containsPoint(point, this.a, this.b, this.c);
+ };
+ _proto.isFrontFacing = function isFrontFacing(direction) {
+ return Triangle.isFrontFacing(this.a, this.b, this.c, direction);
+ };
+ _proto.intersectsBox = function intersectsBox(box) {
+ return box.intersectsTriangle(this);
+ };
+ _proto.closestPointToPoint = function closestPointToPoint(p, target) {
+ if (target === undefined) {
+ console.warn('THREE.Triangle: .closestPointToPoint() target is now required');
+ target = new Vector3();
+ }
+ var a = this.a,
+ b = this.b,
+ c = this.c;
+ var v, w; // algorithm thanks to Real-Time Collision Detection by Christer Ericson,
+ // published by Morgan Kaufmann Publishers, (c) 2005 Elsevier Inc.,
+ // under the accompanying license; see chapter 5.1.5 for detailed explanation.
+ // basically, we're distinguishing which of the voronoi regions of the triangle
+ // the point lies in with the minimum amount of redundant computation.
+ _vab.subVectors(b, a);
+ _vac.subVectors(c, a);
+ _vap.subVectors(p, a);
+ var d1 = _vab.dot(_vap);
+ var d2 = _vac.dot(_vap);
+ if (d1 <= 0 && d2 <= 0) {
+ // vertex region of A; barycentric coords (1, 0, 0)
+ return target.copy(a);
+ }
+ _vbp.subVectors(p, b);
+ var d3 = _vab.dot(_vbp);
+ var d4 = _vac.dot(_vbp);
+ if (d3 >= 0 && d4 <= d3) {
+ // vertex region of B; barycentric coords (0, 1, 0)
+ return target.copy(b);
+ }
+ var vc = d1 * d4 - d3 * d2;
+ if (vc <= 0 && d1 >= 0 && d3 <= 0) {
+ v = d1 / (d1 - d3); // edge region of AB; barycentric coords (1-v, v, 0)
+ return target.copy(a).addScaledVector(_vab, v);
+ }
+ _vcp.subVectors(p, c);
+ var d5 = _vab.dot(_vcp);
+ var d6 = _vac.dot(_vcp);
+ if (d6 >= 0 && d5 <= d6) {
+ // vertex region of C; barycentric coords (0, 0, 1)
+ return target.copy(c);
+ }
+ var vb = d5 * d2 - d1 * d6;
+ if (vb <= 0 && d2 >= 0 && d6 <= 0) {
+ w = d2 / (d2 - d6); // edge region of AC; barycentric coords (1-w, 0, w)
+ return target.copy(a).addScaledVector(_vac, w);
+ }
+ var va = d3 * d6 - d5 * d4;
+ if (va <= 0 && d4 - d3 >= 0 && d5 - d6 >= 0) {
+ _vbc.subVectors(c, b);
+ w = (d4 - d3) / (d4 - d3 + (d5 - d6)); // edge region of BC; barycentric coords (0, 1-w, w)
+ return target.copy(b).addScaledVector(_vbc, w); // edge region of BC
+ } // face region
+
+ var denom = 1 / (va + vb + vc); // u = va * denom
+ v = vb * denom;
+ w = vc * denom;
+ return target.copy(a).addScaledVector(_vab, v).addScaledVector(_vac, w);
+ };
+ _proto.equals = function equals(triangle) {
+ return triangle.a.equals(this.a) && triangle.b.equals(this.b) && triangle.c.equals(this.c);
+ };
+ return Triangle;
+ }();
+ var _colorKeywords = {
+ 'aliceblue': 0xF0F8FF,
+ 'antiquewhite': 0xFAEBD7,
+ 'aqua': 0x00FFFF,
+ 'aquamarine': 0x7FFFD4,
+ 'azure': 0xF0FFFF,
+ 'beige': 0xF5F5DC,
+ 'bisque': 0xFFE4C4,
+ 'black': 0x000000,
+ 'blanchedalmond': 0xFFEBCD,
+ 'blue': 0x0000FF,
+ 'blueviolet': 0x8A2BE2,
+ 'brown': 0xA52A2A,
+ 'burlywood': 0xDEB887,
+ 'cadetblue': 0x5F9EA0,
+ 'chartreuse': 0x7FFF00,
+ 'chocolate': 0xD2691E,
+ 'coral': 0xFF7F50,
+ 'cornflowerblue': 0x6495ED,
+ 'cornsilk': 0xFFF8DC,
+ 'crimson': 0xDC143C,
+ 'cyan': 0x00FFFF,
+ 'darkblue': 0x00008B,
+ 'darkcyan': 0x008B8B,
+ 'darkgoldenrod': 0xB8860B,
+ 'darkgray': 0xA9A9A9,
+ 'darkgreen': 0x006400,
+ 'darkgrey': 0xA9A9A9,
+ 'darkkhaki': 0xBDB76B,
+ 'darkmagenta': 0x8B008B,
+ 'darkolivegreen': 0x556B2F,
+ 'darkorange': 0xFF8C00,
+ 'darkorchid': 0x9932CC,
+ 'darkred': 0x8B0000,
+ 'darksalmon': 0xE9967A,
+ 'darkseagreen': 0x8FBC8F,
+ 'darkslateblue': 0x483D8B,
+ 'darkslategray': 0x2F4F4F,
+ 'darkslategrey': 0x2F4F4F,
+ 'darkturquoise': 0x00CED1,
+ 'darkviolet': 0x9400D3,
+ 'deeppink': 0xFF1493,
+ 'deepskyblue': 0x00BFFF,
+ 'dimgray': 0x696969,
+ 'dimgrey': 0x696969,
+ 'dodgerblue': 0x1E90FF,
+ 'firebrick': 0xB22222,
+ 'floralwhite': 0xFFFAF0,
+ 'forestgreen': 0x228B22,
+ 'fuchsia': 0xFF00FF,
+ 'gainsboro': 0xDCDCDC,
+ 'ghostwhite': 0xF8F8FF,
+ 'gold': 0xFFD700,
+ 'goldenrod': 0xDAA520,
+ 'gray': 0x808080,
+ 'green': 0x008000,
+ 'greenyellow': 0xADFF2F,
+ 'grey': 0x808080,
+ 'honeydew': 0xF0FFF0,
+ 'hotpink': 0xFF69B4,
+ 'indianred': 0xCD5C5C,
+ 'indigo': 0x4B0082,
+ 'ivory': 0xFFFFF0,
+ 'khaki': 0xF0E68C,
+ 'lavender': 0xE6E6FA,
+ 'lavenderblush': 0xFFF0F5,
+ 'lawngreen': 0x7CFC00,
+ 'lemonchiffon': 0xFFFACD,
+ 'lightblue': 0xADD8E6,
+ 'lightcoral': 0xF08080,
+ 'lightcyan': 0xE0FFFF,
+ 'lightgoldenrodyellow': 0xFAFAD2,
+ 'lightgray': 0xD3D3D3,
+ 'lightgreen': 0x90EE90,
+ 'lightgrey': 0xD3D3D3,
+ 'lightpink': 0xFFB6C1,
+ 'lightsalmon': 0xFFA07A,
+ 'lightseagreen': 0x20B2AA,
+ 'lightskyblue': 0x87CEFA,
+ 'lightslategray': 0x778899,
+ 'lightslategrey': 0x778899,
+ 'lightsteelblue': 0xB0C4DE,
+ 'lightyellow': 0xFFFFE0,
+ 'lime': 0x00FF00,
+ 'limegreen': 0x32CD32,
+ 'linen': 0xFAF0E6,
+ 'magenta': 0xFF00FF,
+ 'maroon': 0x800000,
+ 'mediumaquamarine': 0x66CDAA,
+ 'mediumblue': 0x0000CD,
+ 'mediumorchid': 0xBA55D3,
+ 'mediumpurple': 0x9370DB,
+ 'mediumseagreen': 0x3CB371,
+ 'mediumslateblue': 0x7B68EE,
+ 'mediumspringgreen': 0x00FA9A,
+ 'mediumturquoise': 0x48D1CC,
+ 'mediumvioletred': 0xC71585,
+ 'midnightblue': 0x191970,
+ 'mintcream': 0xF5FFFA,
+ 'mistyrose': 0xFFE4E1,
+ 'moccasin': 0xFFE4B5,
+ 'navajowhite': 0xFFDEAD,
+ 'navy': 0x000080,
+ 'oldlace': 0xFDF5E6,
+ 'olive': 0x808000,
+ 'olivedrab': 0x6B8E23,
+ 'orange': 0xFFA500,
+ 'orangered': 0xFF4500,
+ 'orchid': 0xDA70D6,
+ 'palegoldenrod': 0xEEE8AA,
+ 'palegreen': 0x98FB98,
+ 'paleturquoise': 0xAFEEEE,
+ 'palevioletred': 0xDB7093,
+ 'papayawhip': 0xFFEFD5,
+ 'peachpuff': 0xFFDAB9,
+ 'peru': 0xCD853F,
+ 'pink': 0xFFC0CB,
+ 'plum': 0xDDA0DD,
+ 'powderblue': 0xB0E0E6,
+ 'purple': 0x800080,
+ 'rebeccapurple': 0x663399,
+ 'red': 0xFF0000,
+ 'rosybrown': 0xBC8F8F,
+ 'royalblue': 0x4169E1,
+ 'saddlebrown': 0x8B4513,
+ 'salmon': 0xFA8072,
+ 'sandybrown': 0xF4A460,
+ 'seagreen': 0x2E8B57,
+ 'seashell': 0xFFF5EE,
+ 'sienna': 0xA0522D,
+ 'silver': 0xC0C0C0,
+ 'skyblue': 0x87CEEB,
+ 'slateblue': 0x6A5ACD,
+ 'slategray': 0x708090,
+ 'slategrey': 0x708090,
+ 'snow': 0xFFFAFA,
+ 'springgreen': 0x00FF7F,
+ 'steelblue': 0x4682B4,
+ 'tan': 0xD2B48C,
+ 'teal': 0x008080,
+ 'thistle': 0xD8BFD8,
+ 'tomato': 0xFF6347,
+ 'turquoise': 0x40E0D0,
+ 'violet': 0xEE82EE,
+ 'wheat': 0xF5DEB3,
+ 'white': 0xFFFFFF,
+ 'whitesmoke': 0xF5F5F5,
+ 'yellow': 0xFFFF00,
+ 'yellowgreen': 0x9ACD32
+ };
+ var _hslA = {
+ h: 0,
+ s: 0,
+ l: 0
+ };
+ var _hslB = {
+ h: 0,
+ s: 0,
+ l: 0
+ };
+ function hue2rgb(p, q, t) {
+ if (t < 0) t += 1;
+ if (t > 1) t -= 1;
+ if (t < 1 / 6) return p + (q - p) * 6 * t;
+ if (t < 1 / 2) return q;
+ if (t < 2 / 3) return p + (q - p) * 6 * (2 / 3 - t);
+ return p;
+ }
+ function SRGBToLinear(c) {
+ return c < 0.04045 ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4);
+ }
+ function LinearToSRGB(c) {
+ return c < 0.0031308 ? c * 12.92 : 1.055 * Math.pow(c, 0.41666) - 0.055;
+ }
+ var Color = /*#__PURE__*/function () {
+ function Color(r, g, b) {
+ Object.defineProperty(this, 'isColor', {
+ value: true
+ });
+ if (g === undefined && b === undefined) {
+ // r is THREE.Color, hex or string
+ return this.set(r);
+ }
+ return this.setRGB(r, g, b);
+ }
+ var _proto = Color.prototype;
+ _proto.set = function set(value) {
+ if (value && value.isColor) {
+ this.copy(value);
+ } else if (typeof value === 'number') {
+ this.setHex(value);
+ } else if (typeof value === 'string') {
+ this.setStyle(value);
+ }
+ return this;
+ };
+ _proto.setScalar = function setScalar(scalar) {
+ this.r = scalar;
+ this.g = scalar;
+ this.b = scalar;
+ return this;
+ };
+ _proto.setHex = function setHex(hex) {
+ hex = Math.floor(hex);
+ this.r = (hex >> 16 & 255) / 255;
+ this.g = (hex >> 8 & 255) / 255;
+ this.b = (hex & 255) / 255;
+ return this;
+ };
+ _proto.setRGB = function setRGB(r, g, b) {
+ this.r = r;
+ this.g = g;
+ this.b = b;
+ return this;
+ };
+ _proto.setHSL = function setHSL(h, s, l) {
+ // h,s,l ranges are in 0.0 - 1.0
+ h = MathUtils.euclideanModulo(h, 1);
+ s = MathUtils.clamp(s, 0, 1);
+ l = MathUtils.clamp(l, 0, 1);
+ if (s === 0) {
+ this.r = this.g = this.b = l;
+ } else {
+ var p = l <= 0.5 ? l * (1 + s) : l + s - l * s;
+ var q = 2 * l - p;
+ this.r = hue2rgb(q, p, h + 1 / 3);
+ this.g = hue2rgb(q, p, h);
+ this.b = hue2rgb(q, p, h - 1 / 3);
+ }
+ return this;
+ };
+ _proto.setStyle = function setStyle(style) {
+ function handleAlpha(string) {
+ if (string === undefined) return;
+ if (parseFloat(string) < 1) {
+ console.warn('THREE.Color: Alpha component of ' + style + ' will be ignored.');
+ }
+ }
+ var m;
+ if (m = /^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec(style)) {
+ // rgb / hsl
+ var color;
+ var name = m[1];
+ var components = m[2];
+ switch (name) {
+ case 'rgb':
+ case 'rgba':
+ if (color = /^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(components)) {
+ // rgb(255,0,0) rgba(255,0,0,0.5)
+ this.r = Math.min(255, parseInt(color[1], 10)) / 255;
+ this.g = Math.min(255, parseInt(color[2], 10)) / 255;
+ this.b = Math.min(255, parseInt(color[3], 10)) / 255;
+ handleAlpha(color[5]);
+ return this;
+ }
+ if (color = /^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(components)) {
+ // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)
+ this.r = Math.min(100, parseInt(color[1], 10)) / 100;
+ this.g = Math.min(100, parseInt(color[2], 10)) / 100;
+ this.b = Math.min(100, parseInt(color[3], 10)) / 100;
+ handleAlpha(color[5]);
+ return this;
+ }
+ break;
+ case 'hsl':
+ case 'hsla':
+ if (color = /^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(components)) {
+ // hsl(120,50%,50%) hsla(120,50%,50%,0.5)
+ var h = parseFloat(color[1]) / 360;
+ var s = parseInt(color[2], 10) / 100;
+ var l = parseInt(color[3], 10) / 100;
+ handleAlpha(color[5]);
+ return this.setHSL(h, s, l);
+ }
+ break;
+ }
+ } else if (m = /^\#([A-Fa-f0-9]+)$/.exec(style)) {
+ // hex color
+ var hex = m[1];
+ var size = hex.length;
+ if (size === 3) {
+ // #ff0
+ this.r = parseInt(hex.charAt(0) + hex.charAt(0), 16) / 255;
+ this.g = parseInt(hex.charAt(1) + hex.charAt(1), 16) / 255;
+ this.b = parseInt(hex.charAt(2) + hex.charAt(2), 16) / 255;
+ return this;
+ } else if (size === 6) {
+ // #ff0000
+ this.r = parseInt(hex.charAt(0) + hex.charAt(1), 16) / 255;
+ this.g = parseInt(hex.charAt(2) + hex.charAt(3), 16) / 255;
+ this.b = parseInt(hex.charAt(4) + hex.charAt(5), 16) / 255;
+ return this;
+ }
+ }
+ if (style && style.length > 0) {
+ return this.setColorName(style);
+ }
+ return this;
+ };
+ _proto.setColorName = function setColorName(style) {
+ // color keywords
+ var hex = _colorKeywords[style];
+ if (hex !== undefined) {
+ // red
+ this.setHex(hex);
+ } else {
+ // unknown color
+ console.warn('THREE.Color: Unknown color ' + style);
+ }
+ return this;
+ };
+ _proto.clone = function clone() {
+ return new this.constructor(this.r, this.g, this.b);
+ };
+ _proto.copy = function copy(color) {
+ this.r = color.r;
+ this.g = color.g;
+ this.b = color.b;
+ return this;
+ };
+ _proto.copyGammaToLinear = function copyGammaToLinear(color, gammaFactor) {
+ if (gammaFactor === void 0) {
+ gammaFactor = 2.0;
+ }
+ this.r = Math.pow(color.r, gammaFactor);
+ this.g = Math.pow(color.g, gammaFactor);
+ this.b = Math.pow(color.b, gammaFactor);
+ return this;
+ };
+ _proto.copyLinearToGamma = function copyLinearToGamma(color, gammaFactor) {
+ if (gammaFactor === void 0) {
+ gammaFactor = 2.0;
+ }
+ var safeInverse = gammaFactor > 0 ? 1.0 / gammaFactor : 1.0;
+ this.r = Math.pow(color.r, safeInverse);
+ this.g = Math.pow(color.g, safeInverse);
+ this.b = Math.pow(color.b, safeInverse);
+ return this;
+ };
+ _proto.convertGammaToLinear = function convertGammaToLinear(gammaFactor) {
+ this.copyGammaToLinear(this, gammaFactor);
+ return this;
+ };
+ _proto.convertLinearToGamma = function convertLinearToGamma(gammaFactor) {
+ this.copyLinearToGamma(this, gammaFactor);
+ return this;
+ };
+ _proto.copySRGBToLinear = function copySRGBToLinear(color) {
+ this.r = SRGBToLinear(color.r);
+ this.g = SRGBToLinear(color.g);
+ this.b = SRGBToLinear(color.b);
+ return this;
+ };
+ _proto.copyLinearToSRGB = function copyLinearToSRGB(color) {
+ this.r = LinearToSRGB(color.r);
+ this.g = LinearToSRGB(color.g);
+ this.b = LinearToSRGB(color.b);
+ return this;
+ };
+ _proto.convertSRGBToLinear = function convertSRGBToLinear() {
+ this.copySRGBToLinear(this);
+ return this;
+ };
+ _proto.convertLinearToSRGB = function convertLinearToSRGB() {
+ this.copyLinearToSRGB(this);
+ return this;
+ };
+ _proto.getHex = function getHex() {
+ return this.r * 255 << 16 ^ this.g * 255 << 8 ^ this.b * 255 << 0;
+ };
+ _proto.getHexString = function getHexString() {
+ return ('000000' + this.getHex().toString(16)).slice(-6);
+ };
+ _proto.getHSL = function getHSL(target) {
+ // h,s,l ranges are in 0.0 - 1.0
+ if (target === undefined) {
+ console.warn('THREE.Color: .getHSL() target is now required');
+ target = {
+ h: 0,
+ s: 0,
+ l: 0
+ };
+ }
+ var r = this.r,
+ g = this.g,
+ b = this.b;
+ var max = Math.max(r, g, b);
+ var min = Math.min(r, g, b);
+ var hue, saturation;
+ var lightness = (min + max) / 2.0;
+ if (min === max) {
+ hue = 0;
+ saturation = 0;
+ } else {
+ var delta = max - min;
+ saturation = lightness <= 0.5 ? delta / (max + min) : delta / (2 - max - min);
+ switch (max) {
+ case r:
+ hue = (g - b) / delta + (g < b ? 6 : 0);
+ break;
+ case g:
+ hue = (b - r) / delta + 2;
+ break;
+ case b:
+ hue = (r - g) / delta + 4;
+ break;
+ }
+ hue /= 6;
+ }
+ target.h = hue;
+ target.s = saturation;
+ target.l = lightness;
+ return target;
+ };
+ _proto.getStyle = function getStyle() {
+ return 'rgb(' + (this.r * 255 | 0) + ',' + (this.g * 255 | 0) + ',' + (this.b * 255 | 0) + ')';
+ };
+ _proto.offsetHSL = function offsetHSL(h, s, l) {
+ this.getHSL(_hslA);
+ _hslA.h += h;
+ _hslA.s += s;
+ _hslA.l += l;
+ this.setHSL(_hslA.h, _hslA.s, _hslA.l);
+ return this;
+ };
+ _proto.add = function add(color) {
+ this.r += color.r;
+ this.g += color.g;
+ this.b += color.b;
+ return this;
+ };
+ _proto.addColors = function addColors(color1, color2) {
+ this.r = color1.r + color2.r;
+ this.g = color1.g + color2.g;
+ this.b = color1.b + color2.b;
+ return this;
+ };
+ _proto.addScalar = function addScalar(s) {
+ this.r += s;
+ this.g += s;
+ this.b += s;
+ return this;
+ };
+ _proto.sub = function sub(color) {
+ this.r = Math.max(0, this.r - color.r);
+ this.g = Math.max(0, this.g - color.g);
+ this.b = Math.max(0, this.b - color.b);
+ return this;
+ };
+ _proto.multiply = function multiply(color) {
+ this.r *= color.r;
+ this.g *= color.g;
+ this.b *= color.b;
+ return this;
+ };
+ _proto.multiplyScalar = function multiplyScalar(s) {
+ this.r *= s;
+ this.g *= s;
+ this.b *= s;
+ return this;
+ };
+ _proto.lerp = function lerp(color, alpha) {
+ this.r += (color.r - this.r) * alpha;
+ this.g += (color.g - this.g) * alpha;
+ this.b += (color.b - this.b) * alpha;
+ return this;
+ };
+ _proto.lerpHSL = function lerpHSL(color, alpha) {
+ this.getHSL(_hslA);
+ color.getHSL(_hslB);
+ var h = MathUtils.lerp(_hslA.h, _hslB.h, alpha);
+ var s = MathUtils.lerp(_hslA.s, _hslB.s, alpha);
+ var l = MathUtils.lerp(_hslA.l, _hslB.l, alpha);
+ this.setHSL(h, s, l);
+ return this;
+ };
+ _proto.equals = function equals(c) {
+ return c.r === this.r && c.g === this.g && c.b === this.b;
+ };
+ _proto.fromArray = function fromArray(array, offset) {
+ if (offset === void 0) {
+ offset = 0;
+ }
+ this.r = array[offset];
+ this.g = array[offset + 1];
+ this.b = array[offset + 2];
+ return this;
+ };
+ _proto.toArray = function toArray(array, offset) {
+ if (array === void 0) {
+ array = [];
+ }
+ if (offset === void 0) {
+ offset = 0;
+ }
+ array[offset] = this.r;
+ array[offset + 1] = this.g;
+ array[offset + 2] = this.b;
+ return array;
+ };
+ _proto.fromBufferAttribute = function fromBufferAttribute(attribute, index) {
+ this.r = attribute.getX(index);
+ this.g = attribute.getY(index);
+ this.b = attribute.getZ(index);
+ if (attribute.normalized === true) {
+ // assuming Uint8Array
+ this.r /= 255;
+ this.g /= 255;
+ this.b /= 255;
+ }
+ return this;
+ };
+ _proto.toJSON = function toJSON() {
+ return this.getHex();
+ };
+ return Color;
+ }();
+ Color.NAMES = _colorKeywords;
+ Color.prototype.r = 1;
+ Color.prototype.g = 1;
+ Color.prototype.b = 1;
+ var Face3 = /*#__PURE__*/function () {
+ function Face3(a, b, c, normal, color, materialIndex) {
+ if (materialIndex === void 0) {
+ materialIndex = 0;
+ }
+ this.a = a;
+ this.b = b;
+ this.c = c;
+ this.normal = normal && normal.isVector3 ? normal : new Vector3();
+ this.vertexNormals = Array.isArray(normal) ? normal : [];
+ this.color = color && color.isColor ? color : new Color();
+ this.vertexColors = Array.isArray(color) ? color : [];
+ this.materialIndex = materialIndex;
+ }
+ var _proto = Face3.prototype;
+ _proto.clone = function clone() {
+ return new this.constructor().copy(this);
+ };
+ _proto.copy = function copy(source) {
+ this.a = source.a;
+ this.b = source.b;
+ this.c = source.c;
+ this.normal.copy(source.normal);
+ this.color.copy(source.color);
+ this.materialIndex = source.materialIndex;
+ for (var i = 0, il = source.vertexNormals.length; i < il; i++) {
+ this.vertexNormals[i] = source.vertexNormals[i].clone();
+ }
+ for (var _i = 0, _il = source.vertexColors.length; _i < _il; _i++) {
+ this.vertexColors[_i] = source.vertexColors[_i].clone();
+ }
+ return this;
+ };
+ return Face3;
+ }();
+ var materialId = 0;
+ function Material() {
+ Object.defineProperty(this, 'id', {
+ value: materialId++
+ });
+ this.uuid = MathUtils.generateUUID();
+ this.name = '';
+ this.type = 'Material';
+ this.fog = true;
+ this.blending = NormalBlending;
+ this.side = FrontSide;
+ this.flatShading = false;
+ this.vertexColors = false;
+ this.opacity = 1;
+ this.transparent = false;
+ this.blendSrc = SrcAlphaFactor;
+ this.blendDst = OneMinusSrcAlphaFactor;
+ this.blendEquation = AddEquation;
+ this.blendSrcAlpha = null;
+ this.blendDstAlpha = null;
+ this.blendEquationAlpha = null;
+ this.depthFunc = LessEqualDepth;
+ this.depthTest = true;
+ this.depthWrite = true;
+ this.stencilWriteMask = 0xff;
+ this.stencilFunc = AlwaysStencilFunc;
+ this.stencilRef = 0;
+ this.stencilFuncMask = 0xff;
+ this.stencilFail = KeepStencilOp;
+ this.stencilZFail = KeepStencilOp;
+ this.stencilZPass = KeepStencilOp;
+ this.stencilWrite = false;
+ this.clippingPlanes = null;
+ this.clipIntersection = false;
+ this.clipShadows = false;
+ this.shadowSide = null;
+ this.colorWrite = true;
+ this.precision = null; // override the renderer's default precision for this material
+ this.polygonOffset = false;
+ this.polygonOffsetFactor = 0;
+ this.polygonOffsetUnits = 0;
+ this.dithering = false;
+ this.alphaTest = 0;
+ this.premultipliedAlpha = false;
+ this.visible = true;
+ this.toneMapped = true;
+ this.userData = {};
+ this.version = 0;
+ }
+ Material.prototype = Object.assign(Object.create(EventDispatcher.prototype), {
+ constructor: Material,
+ isMaterial: true,
+ onBeforeCompile: function onBeforeCompile()
+ /* shaderobject, renderer */
+ {},
+ customProgramCacheKey: function customProgramCacheKey() {
+ return this.onBeforeCompile.toString();
+ },
+ setValues: function setValues(values) {
+ if (values === undefined) return;
+ for (var key in values) {
+ var newValue = values[key];
+ if (newValue === undefined) {
+ console.warn('THREE.Material: \'' + key + '\' parameter is undefined.');
+ continue;
+ } // for backward compatability if shading is set in the constructor
+
+ if (key === 'shading') {
+ console.warn('THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.');
+ this.flatShading = newValue === FlatShading ? true : false;
+ continue;
+ }
+ var currentValue = this[key];
+ if (currentValue === undefined) {
+ console.warn('THREE.' + this.type + ': \'' + key + '\' is not a property of this material.');
+ continue;
+ }
+ if (currentValue && currentValue.isColor) {
+ currentValue.set(newValue);
+ } else if (currentValue && currentValue.isVector3 && newValue && newValue.isVector3) {
+ currentValue.copy(newValue);
+ } else {
+ this[key] = newValue;
+ }
+ }
+ },
+ toJSON: function toJSON(meta) {
+ var isRoot = meta === undefined || typeof meta === 'string';
+ if (isRoot) {
+ meta = {
+ textures: {},
+ images: {}
+ };
+ }
+ var data = {
+ metadata: {
+ version: 4.5,
+ type: 'Material',
+ generator: 'Material.toJSON'
+ }
+ }; // standard Material serialization
+ data.uuid = this.uuid;
+ data.type = this.type;
+ if (this.name !== '') data.name = this.name;
+ if (this.color && this.color.isColor) data.color = this.color.getHex();
+ if (this.roughness !== undefined) data.roughness = this.roughness;
+ if (this.metalness !== undefined) data.metalness = this.metalness;
+ if (this.sheen && this.sheen.isColor) data.sheen = this.sheen.getHex();
+ if (this.emissive && this.emissive.isColor) data.emissive = this.emissive.getHex();
+ if (this.emissiveIntensity && this.emissiveIntensity !== 1) data.emissiveIntensity = this.emissiveIntensity;
+ if (this.specular && this.specular.isColor) data.specular = this.specular.getHex();
+ if (this.shininess !== undefined) data.shininess = this.shininess;
+ if (this.clearcoat !== undefined) data.clearcoat = this.clearcoat;
+ if (this.clearcoatRoughness !== undefined) data.clearcoatRoughness = this.clearcoatRoughness;
+ if (this.clearcoatMap && this.clearcoatMap.isTexture) {
+ data.clearcoatMap = this.clearcoatMap.toJSON(meta).uuid;
+ }
+ if (this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture) {
+ data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON(meta).uuid;
+ }
+ if (this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture) {
+ data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON(meta).uuid;
+ data.clearcoatNormalScale = this.clearcoatNormalScale.toArray();
+ }
+ if (this.map && this.map.isTexture) data.map = this.map.toJSON(meta).uuid;
+ if (this.matcap && this.matcap.isTexture) data.matcap = this.matcap.toJSON(meta).uuid;
+ if (this.alphaMap && this.alphaMap.isTexture) data.alphaMap = this.alphaMap.toJSON(meta).uuid;
+ if (this.lightMap && this.lightMap.isTexture) data.lightMap = this.lightMap.toJSON(meta).uuid;
+ if (this.aoMap && this.aoMap.isTexture) {
+ data.aoMap = this.aoMap.toJSON(meta).uuid;
+ data.aoMapIntensity = this.aoMapIntensity;
+ }
+ if (this.bumpMap && this.bumpMap.isTexture) {
+ data.bumpMap = this.bumpMap.toJSON(meta).uuid;
+ data.bumpScale = this.bumpScale;
+ }
+ if (this.normalMap && this.normalMap.isTexture) {
+ data.normalMap = this.normalMap.toJSON(meta).uuid;
+ data.normalMapType = this.normalMapType;
+ data.normalScale = this.normalScale.toArray();
+ }
+ if (this.displacementMap && this.displacementMap.isTexture) {
+ data.displacementMap = this.displacementMap.toJSON(meta).uuid;
+ data.displacementScale = this.displacementScale;
+ data.displacementBias = this.displacementBias;
+ }
+ if (this.roughnessMap && this.roughnessMap.isTexture) data.roughnessMap = this.roughnessMap.toJSON(meta).uuid;
+ if (this.metalnessMap && this.metalnessMap.isTexture) data.metalnessMap = this.metalnessMap.toJSON(meta).uuid;
+ if (this.emissiveMap && this.emissiveMap.isTexture) data.emissiveMap = this.emissiveMap.toJSON(meta).uuid;
+ if (this.specularMap && this.specularMap.isTexture) data.specularMap = this.specularMap.toJSON(meta).uuid;
+ if (this.envMap && this.envMap.isTexture) {
+ data.envMap = this.envMap.toJSON(meta).uuid;
+ data.reflectivity = this.reflectivity; // Scale behind envMap
+ data.refractionRatio = this.refractionRatio;
+ if (this.combine !== undefined) data.combine = this.combine;
+ if (this.envMapIntensity !== undefined) data.envMapIntensity = this.envMapIntensity;
+ }
+ if (this.gradientMap && this.gradientMap.isTexture) {
+ data.gradientMap = this.gradientMap.toJSON(meta).uuid;
+ }
+ if (this.size !== undefined) data.size = this.size;
+ if (this.sizeAttenuation !== undefined) data.sizeAttenuation = this.sizeAttenuation;
+ if (this.blending !== NormalBlending) data.blending = this.blending;
+ if (this.flatShading === true) data.flatShading = this.flatShading;
+ if (this.side !== FrontSide) data.side = this.side;
+ if (this.vertexColors) data.vertexColors = true;
+ if (this.opacity < 1) data.opacity = this.opacity;
+ if (this.transparent === true) data.transparent = this.transparent;
+ data.depthFunc = this.depthFunc;
+ data.depthTest = this.depthTest;
+ data.depthWrite = this.depthWrite;
+ data.stencilWrite = this.stencilWrite;
+ data.stencilWriteMask = this.stencilWriteMask;
+ data.stencilFunc = this.stencilFunc;
+ data.stencilRef = this.stencilRef;
+ data.stencilFuncMask = this.stencilFuncMask;
+ data.stencilFail = this.stencilFail;
+ data.stencilZFail = this.stencilZFail;
+ data.stencilZPass = this.stencilZPass; // rotation (SpriteMaterial)
+ if (this.rotation && this.rotation !== 0) data.rotation = this.rotation;
+ if (this.polygonOffset === true) data.polygonOffset = true;
+ if (this.polygonOffsetFactor !== 0) data.polygonOffsetFactor = this.polygonOffsetFactor;
+ if (this.polygonOffsetUnits !== 0) data.polygonOffsetUnits = this.polygonOffsetUnits;
+ if (this.linewidth && this.linewidth !== 1) data.linewidth = this.linewidth;
+ if (this.dashSize !== undefined) data.dashSize = this.dashSize;
+ if (this.gapSize !== undefined) data.gapSize = this.gapSize;
+ if (this.scale !== undefined) data.scale = this.scale;
+ if (this.dithering === true) data.dithering = true;
+ if (this.alphaTest > 0) data.alphaTest = this.alphaTest;
+ if (this.premultipliedAlpha === true) data.premultipliedAlpha = this.premultipliedAlpha;
+ if (this.wireframe === true) data.wireframe = this.wireframe;
+ if (this.wireframeLinewidth > 1) data.wireframeLinewidth = this.wireframeLinewidth;
+ if (this.wireframeLinecap !== 'round') data.wireframeLinecap = this.wireframeLinecap;
+ if (this.wireframeLinejoin !== 'round') data.wireframeLinejoin = this.wireframeLinejoin;
+ if (this.morphTargets === true) data.morphTargets = true;
+ if (this.morphNormals === true) data.morphNormals = true;
+ if (this.skinning === true) data.skinning = true;
+ if (this.visible === false) data.visible = false;
+ if (this.toneMapped === false) data.toneMapped = false;
+ if (JSON.stringify(this.userData) !== '{}') data.userData = this.userData; // TODO: Copied from Object3D.toJSON
+ function extractFromCache(cache) {
+ var values = [];
+ for (var key in cache) {
+ var _data = cache[key];
+ delete _data.metadata;
+ values.push(_data);
+ }
+ return values;
+ }
+ if (isRoot) {
+ var textures = extractFromCache(meta.textures);
+ var images = extractFromCache(meta.images);
+ if (textures.length > 0) data.textures = textures;
+ if (images.length > 0) data.images = images;
+ }
+ return data;
+ },
+ clone: function clone() {
+ return new this.constructor().copy(this);
+ },
+ copy: function copy(source) {
+ this.name = source.name;
+ this.fog = source.fog;
+ this.blending = source.blending;
+ this.side = source.side;
+ this.flatShading = source.flatShading;
+ this.vertexColors = source.vertexColors;
+ this.opacity = source.opacity;
+ this.transparent = source.transparent;
+ this.blendSrc = source.blendSrc;
+ this.blendDst = source.blendDst;
+ this.blendEquation = source.blendEquation;
+ this.blendSrcAlpha = source.blendSrcAlpha;
+ this.blendDstAlpha = source.blendDstAlpha;
+ this.blendEquationAlpha = source.blendEquationAlpha;
+ this.depthFunc = source.depthFunc;
+ this.depthTest = source.depthTest;
+ this.depthWrite = source.depthWrite;
+ this.stencilWriteMask = source.stencilWriteMask;
+ this.stencilFunc = source.stencilFunc;
+ this.stencilRef = source.stencilRef;
+ this.stencilFuncMask = source.stencilFuncMask;
+ this.stencilFail = source.stencilFail;
+ this.stencilZFail = source.stencilZFail;
+ this.stencilZPass = source.stencilZPass;
+ this.stencilWrite = source.stencilWrite;
+ var srcPlanes = source.clippingPlanes;
+ var dstPlanes = null;
+ if (srcPlanes !== null) {
+ var n = srcPlanes.length;
+ dstPlanes = new Array(n);
+ for (var i = 0; i !== n; ++i) {
+ dstPlanes[i] = srcPlanes[i].clone();
+ }
+ }
+ this.clippingPlanes = dstPlanes;
+ this.clipIntersection = source.clipIntersection;
+ this.clipShadows = source.clipShadows;
+ this.shadowSide = source.shadowSide;
+ this.colorWrite = source.colorWrite;
+ this.precision = source.precision;
+ this.polygonOffset = source.polygonOffset;
+ this.polygonOffsetFactor = source.polygonOffsetFactor;
+ this.polygonOffsetUnits = source.polygonOffsetUnits;
+ this.dithering = source.dithering;
+ this.alphaTest = source.alphaTest;
+ this.premultipliedAlpha = source.premultipliedAlpha;
+ this.visible = source.visible;
+ this.toneMapped = source.toneMapped;
+ this.userData = JSON.parse(JSON.stringify(source.userData));
+ return this;
+ },
+ dispose: function dispose() {
+ this.dispatchEvent({
+ type: 'dispose'
+ });
+ }
+ });
+ Object.defineProperty(Material.prototype, 'needsUpdate', {
+ set: function set(value) {
+ if (value === true) this.version++;
+ }
+ });
+ /**
+ * parameters = {
+ * color: ,
+ * opacity: ,
+ * map: new THREE.Texture( ),
+ *
+ * lightMap: new THREE.Texture( ),
+ * lightMapIntensity:
+ *
+ * aoMap: new THREE.Texture( ),
+ * aoMapIntensity:
+ *
+ * specularMap: new THREE.Texture( ),
+ *
+ * alphaMap: new THREE.Texture( ),
+ *
+ * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),
+ * combine: THREE.Multiply,
+ * reflectivity: ,
+ * refractionRatio: ,
+ *
+ * depthTest: ,
+ * depthWrite: ,
+ *
+ * wireframe: ,
+ * wireframeLinewidth: ,
+ *
+ * skinning: ,
+ * morphTargets:
+ * }
+ */
+ function MeshBasicMaterial(parameters) {
+ Material.call(this);
+ this.type = 'MeshBasicMaterial';
+ this.color = new Color(0xffffff); // emissive
+ this.map = null;
+ this.lightMap = null;
+ this.lightMapIntensity = 1.0;
+ this.aoMap = null;
+ this.aoMapIntensity = 1.0;
+ this.specularMap = null;
+ this.alphaMap = null;
+ this.envMap = null;
+ this.combine = MultiplyOperation;
+ this.reflectivity = 1;
+ this.refractionRatio = 0.98;
+ this.wireframe = false;
+ this.wireframeLinewidth = 1;
+ this.wireframeLinecap = 'round';
+ this.wireframeLinejoin = 'round';
+ this.skinning = false;
+ this.morphTargets = false;
+ this.setValues(parameters);
+ }
+ MeshBasicMaterial.prototype = Object.create(Material.prototype);
+ MeshBasicMaterial.prototype.constructor = MeshBasicMaterial;
+ MeshBasicMaterial.prototype.isMeshBasicMaterial = true;
+ MeshBasicMaterial.prototype.copy = function (source) {
+ Material.prototype.copy.call(this, source);
+ this.color.copy(source.color);
+ this.map = source.map;
+ this.lightMap = source.lightMap;
+ this.lightMapIntensity = source.lightMapIntensity;
+ this.aoMap = source.aoMap;
+ this.aoMapIntensity = source.aoMapIntensity;
+ this.specularMap = source.specularMap;
+ this.alphaMap = source.alphaMap;
+ this.envMap = source.envMap;
+ this.combine = source.combine;
+ this.reflectivity = source.reflectivity;
+ this.refractionRatio = source.refractionRatio;
+ this.wireframe = source.wireframe;
+ this.wireframeLinewidth = source.wireframeLinewidth;
+ this.wireframeLinecap = source.wireframeLinecap;
+ this.wireframeLinejoin = source.wireframeLinejoin;
+ this.skinning = source.skinning;
+ this.morphTargets = source.morphTargets;
+ return this;
+ };
+ var _vector$3 = new Vector3();
+ var _vector2$1 = new Vector2();
+ function BufferAttribute(array, itemSize, normalized) {
+ if (Array.isArray(array)) {
+ throw new TypeError('THREE.BufferAttribute: array should be a Typed Array.');
+ }
+ this.name = '';
+ this.array = array;
+ this.itemSize = itemSize;
+ this.count = array !== undefined ? array.length / itemSize : 0;
+ this.normalized = normalized === true;
+ this.usage = StaticDrawUsage;
+ this.updateRange = {
+ offset: 0,
+ count: -1
+ };
+ this.version = 0;
+ }
+ Object.defineProperty(BufferAttribute.prototype, 'needsUpdate', {
+ set: function set(value) {
+ if (value === true) this.version++;
+ }
+ });
+ Object.assign(BufferAttribute.prototype, {
+ isBufferAttribute: true,
+ onUploadCallback: function onUploadCallback() {},
+ setUsage: function setUsage(value) {
+ this.usage = value;
+ return this;
+ },
+ copy: function copy(source) {
+ this.name = source.name;
+ this.array = new source.array.constructor(source.array);
+ this.itemSize = source.itemSize;
+ this.count = source.count;
+ this.normalized = source.normalized;
+ this.usage = source.usage;
+ return this;
+ },
+ copyAt: function copyAt(index1, attribute, index2) {
+ index1 *= this.itemSize;
+ index2 *= attribute.itemSize;
+ for (var i = 0, l = this.itemSize; i < l; i++) {
+ this.array[index1 + i] = attribute.array[index2 + i];
+ }
+ return this;
+ },
+ copyArray: function copyArray(array) {
+ this.array.set(array);
+ return this;
+ },
+ copyColorsArray: function copyColorsArray(colors) {
+ var array = this.array;
+ var offset = 0;
+ for (var i = 0, l = colors.length; i < l; i++) {
+ var color = colors[i];
+ if (color === undefined) {
+ console.warn('THREE.BufferAttribute.copyColorsArray(): color is undefined', i);
+ color = new Color();
+ }
+ array[offset++] = color.r;
+ array[offset++] = color.g;
+ array[offset++] = color.b;
+ }
+ return this;
+ },
+ copyVector2sArray: function copyVector2sArray(vectors) {
+ var array = this.array;
+ var offset = 0;
+ for (var i = 0, l = vectors.length; i < l; i++) {
+ var vector = vectors[i];
+ if (vector === undefined) {
+ console.warn('THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i);
+ vector = new Vector2();
+ }
+ array[offset++] = vector.x;
+ array[offset++] = vector.y;
+ }
+ return this;
+ },
+ copyVector3sArray: function copyVector3sArray(vectors) {
+ var array = this.array;
+ var offset = 0;
+ for (var i = 0, l = vectors.length; i < l; i++) {
+ var vector = vectors[i];
+ if (vector === undefined) {
+ console.warn('THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i);
+ vector = new Vector3();
+ }
+ array[offset++] = vector.x;
+ array[offset++] = vector.y;
+ array[offset++] = vector.z;
+ }
+ return this;
+ },
+ copyVector4sArray: function copyVector4sArray(vectors) {
+ var array = this.array;
+ var offset = 0;
+ for (var i = 0, l = vectors.length; i < l; i++) {
+ var vector = vectors[i];
+ if (vector === undefined) {
+ console.warn('THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i);
+ vector = new Vector4();
+ }
+ array[offset++] = vector.x;
+ array[offset++] = vector.y;
+ array[offset++] = vector.z;
+ array[offset++] = vector.w;
+ }
+ return this;
+ },
+ applyMatrix3: function applyMatrix3(m) {
+ if (this.itemSize === 2) {
+ for (var i = 0, l = this.count; i < l; i++) {
+ _vector2$1.fromBufferAttribute(this, i);
+ _vector2$1.applyMatrix3(m);
+ this.setXY(i, _vector2$1.x, _vector2$1.y);
+ }
+ } else if (this.itemSize === 3) {
+ for (var _i = 0, _l = this.count; _i < _l; _i++) {
+ _vector$3.fromBufferAttribute(this, _i);
+ _vector$3.applyMatrix3(m);
+ this.setXYZ(_i, _vector$3.x, _vector$3.y, _vector$3.z);
+ }
+ }
+ return this;
+ },
+ applyMatrix4: function applyMatrix4(m) {
+ for (var i = 0, l = this.count; i < l; i++) {
+ _vector$3.x = this.getX(i);
+ _vector$3.y = this.getY(i);
+ _vector$3.z = this.getZ(i);
+ _vector$3.applyMatrix4(m);
+ this.setXYZ(i, _vector$3.x, _vector$3.y, _vector$3.z);
+ }
+ return this;
+ },
+ applyNormalMatrix: function applyNormalMatrix(m) {
+ for (var i = 0, l = this.count; i < l; i++) {
+ _vector$3.x = this.getX(i);
+ _vector$3.y = this.getY(i);
+ _vector$3.z = this.getZ(i);
+ _vector$3.applyNormalMatrix(m);
+ this.setXYZ(i, _vector$3.x, _vector$3.y, _vector$3.z);
+ }
+ return this;
+ },
+ transformDirection: function transformDirection(m) {
+ for (var i = 0, l = this.count; i < l; i++) {
+ _vector$3.x = this.getX(i);
+ _vector$3.y = this.getY(i);
+ _vector$3.z = this.getZ(i);
+ _vector$3.transformDirection(m);
+ this.setXYZ(i, _vector$3.x, _vector$3.y, _vector$3.z);
+ }
+ return this;
+ },
+ set: function set(value, offset) {
+ if (offset === void 0) {
+ offset = 0;
+ }
+ this.array.set(value, offset);
+ return this;
+ },
+ getX: function getX(index) {
+ return this.array[index * this.itemSize];
+ },
+ setX: function setX(index, x) {
+ this.array[index * this.itemSize] = x;
+ return this;
+ },
+ getY: function getY(index) {
+ return this.array[index * this.itemSize + 1];
+ },
+ setY: function setY(index, y) {
+ this.array[index * this.itemSize + 1] = y;
+ return this;
+ },
+ getZ: function getZ(index) {
+ return this.array[index * this.itemSize + 2];
+ },
+ setZ: function setZ(index, z) {
+ this.array[index * this.itemSize + 2] = z;
+ return this;
+ },
+ getW: function getW(index) {
+ return this.array[index * this.itemSize + 3];
+ },
+ setW: function setW(index, w) {
+ this.array[index * this.itemSize + 3] = w;
+ return this;
+ },
+ setXY: function setXY(index, x, y) {
+ index *= this.itemSize;
+ this.array[index + 0] = x;
+ this.array[index + 1] = y;
+ return this;
+ },
+ setXYZ: function setXYZ(index, x, y, z) {
+ index *= this.itemSize;
+ this.array[index + 0] = x;
+ this.array[index + 1] = y;
+ this.array[index + 2] = z;
+ return this;
+ },
+ setXYZW: function setXYZW(index, x, y, z, w) {
+ index *= this.itemSize;
+ this.array[index + 0] = x;
+ this.array[index + 1] = y;
+ this.array[index + 2] = z;
+ this.array[index + 3] = w;
+ return this;
+ },
+ onUpload: function onUpload(callback) {
+ this.onUploadCallback = callback;
+ return this;
+ },
+ clone: function clone() {
+ return new this.constructor(this.array, this.itemSize).copy(this);
+ },
+ toJSON: function toJSON() {
+ return {
+ itemSize: this.itemSize,
+ type: this.array.constructor.name,
+ array: Array.prototype.slice.call(this.array),
+ normalized: this.normalized
+ };
+ }
+ }); //
+ function Int8BufferAttribute(array, itemSize, normalized) {
+ BufferAttribute.call(this, new Int8Array(array), itemSize, normalized);
+ }
+ Int8BufferAttribute.prototype = Object.create(BufferAttribute.prototype);
+ Int8BufferAttribute.prototype.constructor = Int8BufferAttribute;
+ function Uint8BufferAttribute(array, itemSize, normalized) {
+ BufferAttribute.call(this, new Uint8Array(array), itemSize, normalized);
+ }
+ Uint8BufferAttribute.prototype = Object.create(BufferAttribute.prototype);
+ Uint8BufferAttribute.prototype.constructor = Uint8BufferAttribute;
+ function Uint8ClampedBufferAttribute(array, itemSize, normalized) {
+ BufferAttribute.call(this, new Uint8ClampedArray(array), itemSize, normalized);
+ }
+ Uint8ClampedBufferAttribute.prototype = Object.create(BufferAttribute.prototype);
+ Uint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute;
+ function Int16BufferAttribute(array, itemSize, normalized) {
+ BufferAttribute.call(this, new Int16Array(array), itemSize, normalized);
+ }
+ Int16BufferAttribute.prototype = Object.create(BufferAttribute.prototype);
+ Int16BufferAttribute.prototype.constructor = Int16BufferAttribute;
+ function Uint16BufferAttribute(array, itemSize, normalized) {
+ BufferAttribute.call(this, new Uint16Array(array), itemSize, normalized);
+ }
+ Uint16BufferAttribute.prototype = Object.create(BufferAttribute.prototype);
+ Uint16BufferAttribute.prototype.constructor = Uint16BufferAttribute;
+ function Int32BufferAttribute(array, itemSize, normalized) {
+ BufferAttribute.call(this, new Int32Array(array), itemSize, normalized);
+ }
+ Int32BufferAttribute.prototype = Object.create(BufferAttribute.prototype);
+ Int32BufferAttribute.prototype.constructor = Int32BufferAttribute;
+ function Uint32BufferAttribute(array, itemSize, normalized) {
+ BufferAttribute.call(this, new Uint32Array(array), itemSize, normalized);
+ }
+ Uint32BufferAttribute.prototype = Object.create(BufferAttribute.prototype);
+ Uint32BufferAttribute.prototype.constructor = Uint32BufferAttribute;
+ function Float16BufferAttribute(array, itemSize, normalized) {
+ BufferAttribute.call(this, new Uint16Array(array), itemSize, normalized);
+ }
+ Float16BufferAttribute.prototype = Object.create(BufferAttribute.prototype);
+ Float16BufferAttribute.prototype.constructor = Float16BufferAttribute;
+ Float16BufferAttribute.prototype.isFloat16BufferAttribute = true;
+ function Float32BufferAttribute(array, itemSize, normalized) {
+ BufferAttribute.call(this, new Float32Array(array), itemSize, normalized);
+ }
+ Float32BufferAttribute.prototype = Object.create(BufferAttribute.prototype);
+ Float32BufferAttribute.prototype.constructor = Float32BufferAttribute;
+ function Float64BufferAttribute(array, itemSize, normalized) {
+ BufferAttribute.call(this, new Float64Array(array), itemSize, normalized);
+ }
+ Float64BufferAttribute.prototype = Object.create(BufferAttribute.prototype);
+ Float64BufferAttribute.prototype.constructor = Float64BufferAttribute; //
+ var DirectGeometry = /*#__PURE__*/function () {
+ function DirectGeometry() {
+ this.vertices = [];
+ this.normals = [];
+ this.colors = [];
+ this.uvs = [];
+ this.uvs2 = [];
+ this.groups = [];
+ this.morphTargets = {};
+ this.skinWeights = [];
+ this.skinIndices = []; // this.lineDistances = [];
+ this.boundingBox = null;
+ this.boundingSphere = null; // update flags
+ this.verticesNeedUpdate = false;
+ this.normalsNeedUpdate = false;
+ this.colorsNeedUpdate = false;
+ this.uvsNeedUpdate = false;
+ this.groupsNeedUpdate = false;
+ }
+ var _proto = DirectGeometry.prototype;
+ _proto.computeGroups = function computeGroups(geometry) {
+ var groups = [];
+ var group, i;
+ var materialIndex = undefined;
+ var faces = geometry.faces;
+ for (i = 0; i < faces.length; i++) {
+ var face = faces[i]; // materials
+ if (face.materialIndex !== materialIndex) {
+ materialIndex = face.materialIndex;
+ if (group !== undefined) {
+ group.count = i * 3 - group.start;
+ groups.push(group);
+ }
+ group = {
+ start: i * 3,
+ materialIndex: materialIndex
+ };
+ }
+ }
+ if (group !== undefined) {
+ group.count = i * 3 - group.start;
+ groups.push(group);
+ }
+ this.groups = groups;
+ };
+ _proto.fromGeometry = function fromGeometry(geometry) {
+ var faces = geometry.faces;
+ var vertices = geometry.vertices;
+ var faceVertexUvs = geometry.faceVertexUvs;
+ var hasFaceVertexUv = faceVertexUvs[0] && faceVertexUvs[0].length > 0;
+ var hasFaceVertexUv2 = faceVertexUvs[1] && faceVertexUvs[1].length > 0; // morphs
+ var morphTargets = geometry.morphTargets;
+ var morphTargetsLength = morphTargets.length;
+ var morphTargetsPosition;
+ if (morphTargetsLength > 0) {
+ morphTargetsPosition = [];
+ for (var i = 0; i < morphTargetsLength; i++) {
+ morphTargetsPosition[i] = {
+ name: morphTargets[i].name,
+ data: []
+ };
+ }
+ this.morphTargets.position = morphTargetsPosition;
+ }
+ var morphNormals = geometry.morphNormals;
+ var morphNormalsLength = morphNormals.length;
+ var morphTargetsNormal;
+ if (morphNormalsLength > 0) {
+ morphTargetsNormal = [];
+ for (var _i = 0; _i < morphNormalsLength; _i++) {
+ morphTargetsNormal[_i] = {
+ name: morphNormals[_i].name,
+ data: []
+ };
+ }
+ this.morphTargets.normal = morphTargetsNormal;
+ } // skins
+
+ var skinIndices = geometry.skinIndices;
+ var skinWeights = geometry.skinWeights;
+ var hasSkinIndices = skinIndices.length === vertices.length;
+ var hasSkinWeights = skinWeights.length === vertices.length; //
+ if (vertices.length > 0 && faces.length === 0) {
+ console.error('THREE.DirectGeometry: Faceless geometries are not supported.');
+ }
+ for (var _i2 = 0; _i2 < faces.length; _i2++) {
+ var face = faces[_i2];
+ this.vertices.push(vertices[face.a], vertices[face.b], vertices[face.c]);
+ var vertexNormals = face.vertexNormals;
+ if (vertexNormals.length === 3) {
+ this.normals.push(vertexNormals[0], vertexNormals[1], vertexNormals[2]);
+ } else {
+ var normal = face.normal;
+ this.normals.push(normal, normal, normal);
+ }
+ var vertexColors = face.vertexColors;
+ if (vertexColors.length === 3) {
+ this.colors.push(vertexColors[0], vertexColors[1], vertexColors[2]);
+ } else {
+ var color = face.color;
+ this.colors.push(color, color, color);
+ }
+ if (hasFaceVertexUv === true) {
+ var vertexUvs = faceVertexUvs[0][_i2];
+ if (vertexUvs !== undefined) {
+ this.uvs.push(vertexUvs[0], vertexUvs[1], vertexUvs[2]);
+ } else {
+ console.warn('THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', _i2);
+ this.uvs.push(new Vector2(), new Vector2(), new Vector2());
+ }
+ }
+ if (hasFaceVertexUv2 === true) {
+ var _vertexUvs = faceVertexUvs[1][_i2];
+ if (_vertexUvs !== undefined) {
+ this.uvs2.push(_vertexUvs[0], _vertexUvs[1], _vertexUvs[2]);
+ } else {
+ console.warn('THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', _i2);
+ this.uvs2.push(new Vector2(), new Vector2(), new Vector2());
+ }
+ } // morphs
+
+ for (var j = 0; j < morphTargetsLength; j++) {
+ var morphTarget = morphTargets[j].vertices;
+ morphTargetsPosition[j].data.push(morphTarget[face.a], morphTarget[face.b], morphTarget[face.c]);
+ }
+ for (var _j = 0; _j < morphNormalsLength; _j++) {
+ var morphNormal = morphNormals[_j].vertexNormals[_i2];
+ morphTargetsNormal[_j].data.push(morphNormal.a, morphNormal.b, morphNormal.c);
+ } // skins
+
+ if (hasSkinIndices) {
+ this.skinIndices.push(skinIndices[face.a], skinIndices[face.b], skinIndices[face.c]);
+ }
+ if (hasSkinWeights) {
+ this.skinWeights.push(skinWeights[face.a], skinWeights[face.b], skinWeights[face.c]);
+ }
+ }
+ this.computeGroups(geometry);
+ this.verticesNeedUpdate = geometry.verticesNeedUpdate;
+ this.normalsNeedUpdate = geometry.normalsNeedUpdate;
+ this.colorsNeedUpdate = geometry.colorsNeedUpdate;
+ this.uvsNeedUpdate = geometry.uvsNeedUpdate;
+ this.groupsNeedUpdate = geometry.groupsNeedUpdate;
+ if (geometry.boundingSphere !== null) {
+ this.boundingSphere = geometry.boundingSphere.clone();
+ }
+ if (geometry.boundingBox !== null) {
+ this.boundingBox = geometry.boundingBox.clone();
+ }
+ return this;
+ };
+ return DirectGeometry;
+ }();
+ function arrayMax(array) {
+ if (array.length === 0) return -Infinity;
+ var max = array[0];
+ for (var i = 1, l = array.length; i < l; ++i) {
+ if (array[i] > max) max = array[i];
+ }
+ return max;
+ }
+ var TYPED_ARRAYS = {
+ Int8Array: Int8Array,
+ Uint8Array: Uint8Array,
+ // Workaround for IE11 pre KB2929437. See #11440
+ Uint8ClampedArray: typeof Uint8ClampedArray !== 'undefined' ? Uint8ClampedArray : Uint8Array,
+ Int16Array: Int16Array,
+ Uint16Array: Uint16Array,
+ Int32Array: Int32Array,
+ Uint32Array: Uint32Array,
+ Float32Array: Float32Array,
+ Float64Array: Float64Array
+ };
+ function getTypedArray(type, buffer) {
+ return new TYPED_ARRAYS[type](buffer);
+ }
+ var _bufferGeometryId = 1; // BufferGeometry uses odd numbers as Id
+ var _m1$2 = new Matrix4();
+ var _obj = new Object3D();
+ var _offset = new Vector3();
+ var _box$2 = new Box3();
+ var _boxMorphTargets = new Box3();
+ var _vector$4 = new Vector3();
+ function BufferGeometry() {
+ Object.defineProperty(this, 'id', {
+ value: _bufferGeometryId += 2
+ });
+ this.uuid = MathUtils.generateUUID();
+ this.name = '';
+ this.type = 'BufferGeometry';
+ this.index = null;
+ this.attributes = {};
+ this.morphAttributes = {};
+ this.morphTargetsRelative = false;
+ this.groups = [];
+ this.boundingBox = null;
+ this.boundingSphere = null;
+ this.drawRange = {
+ start: 0,
+ count: Infinity
+ };
+ this.userData = {};
+ }
+ BufferGeometry.prototype = Object.assign(Object.create(EventDispatcher.prototype), {
+ constructor: BufferGeometry,
+ isBufferGeometry: true,
+ getIndex: function getIndex() {
+ return this.index;
+ },
+ setIndex: function setIndex(index) {
+ if (Array.isArray(index)) {
+ this.index = new (arrayMax(index) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute)(index, 1);
+ } else {
+ this.index = index;
+ }
+ return this;
+ },
+ getAttribute: function getAttribute(name) {
+ return this.attributes[name];
+ },
+ setAttribute: function setAttribute(name, attribute) {
+ this.attributes[name] = attribute;
+ return this;
+ },
+ deleteAttribute: function deleteAttribute(name) {
+ delete this.attributes[name];
+ return this;
+ },
+ hasAttribute: function hasAttribute(name) {
+ return this.attributes[name] !== undefined;
+ },
+ addGroup: function addGroup(start, count, materialIndex) {
+ if (materialIndex === void 0) {
+ materialIndex = 0;
+ }
+ this.groups.push({
+ start: start,
+ count: count,
+ materialIndex: materialIndex
+ });
+ },
+ clearGroups: function clearGroups() {
+ this.groups = [];
+ },
+ setDrawRange: function setDrawRange(start, count) {
+ this.drawRange.start = start;
+ this.drawRange.count = count;
+ },
+ applyMatrix4: function applyMatrix4(matrix) {
+ var position = this.attributes.position;
+ if (position !== undefined) {
+ position.applyMatrix4(matrix);
+ position.needsUpdate = true;
+ }
+ var normal = this.attributes.normal;
+ if (normal !== undefined) {
+ var normalMatrix = new Matrix3().getNormalMatrix(matrix);
+ normal.applyNormalMatrix(normalMatrix);
+ normal.needsUpdate = true;
+ }
+ var tangent = this.attributes.tangent;
+ if (tangent !== undefined) {
+ tangent.transformDirection(matrix);
+ tangent.needsUpdate = true;
+ }
+ if (this.boundingBox !== null) {
+ this.computeBoundingBox();
+ }
+ if (this.boundingSphere !== null) {
+ this.computeBoundingSphere();
+ }
+ return this;
+ },
+ rotateX: function rotateX(angle) {
+ // rotate geometry around world x-axis
+ _m1$2.makeRotationX(angle);
+ this.applyMatrix4(_m1$2);
+ return this;
+ },
+ rotateY: function rotateY(angle) {
+ // rotate geometry around world y-axis
+ _m1$2.makeRotationY(angle);
+ this.applyMatrix4(_m1$2);
+ return this;
+ },
+ rotateZ: function rotateZ(angle) {
+ // rotate geometry around world z-axis
+ _m1$2.makeRotationZ(angle);
+ this.applyMatrix4(_m1$2);
+ return this;
+ },
+ translate: function translate(x, y, z) {
+ // translate geometry
+ _m1$2.makeTranslation(x, y, z);
+ this.applyMatrix4(_m1$2);
+ return this;
+ },
+ scale: function scale(x, y, z) {
+ // scale geometry
+ _m1$2.makeScale(x, y, z);
+ this.applyMatrix4(_m1$2);
+ return this;
+ },
+ lookAt: function lookAt(vector) {
+ _obj.lookAt(vector);
+ _obj.updateMatrix();
+ this.applyMatrix4(_obj.matrix);
+ return this;
+ },
+ center: function center() {
+ this.computeBoundingBox();
+ this.boundingBox.getCenter(_offset).negate();
+ this.translate(_offset.x, _offset.y, _offset.z);
+ return this;
+ },
+ setFromObject: function setFromObject(object) {
+ // console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this );
+ var geometry = object.geometry;
+ if (object.isPoints || object.isLine) {
+ var positions = new Float32BufferAttribute(geometry.vertices.length * 3, 3);
+ var colors = new Float32BufferAttribute(geometry.colors.length * 3, 3);
+ this.setAttribute('position', positions.copyVector3sArray(geometry.vertices));
+ this.setAttribute('color', colors.copyColorsArray(geometry.colors));
+ if (geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length) {
+ var lineDistances = new Float32BufferAttribute(geometry.lineDistances.length, 1);
+ this.setAttribute('lineDistance', lineDistances.copyArray(geometry.lineDistances));
+ }
+ if (geometry.boundingSphere !== null) {
+ this.boundingSphere = geometry.boundingSphere.clone();
+ }
+ if (geometry.boundingBox !== null) {
+ this.boundingBox = geometry.boundingBox.clone();
+ }
+ } else if (object.isMesh) {
+ if (geometry && geometry.isGeometry) {
+ this.fromGeometry(geometry);
+ }
+ }
+ return this;
+ },
+ setFromPoints: function setFromPoints(points) {
+ var position = [];
+ for (var i = 0, l = points.length; i < l; i++) {
+ var point = points[i];
+ position.push(point.x, point.y, point.z || 0);
+ }
+ this.setAttribute('position', new Float32BufferAttribute(position, 3));
+ return this;
+ },
+ updateFromObject: function updateFromObject(object) {
+ var geometry = object.geometry;
+ if (object.isMesh) {
+ var direct = geometry.__directGeometry;
+ if (geometry.elementsNeedUpdate === true) {
+ direct = undefined;
+ geometry.elementsNeedUpdate = false;
+ }
+ if (direct === undefined) {
+ return this.fromGeometry(geometry);
+ }
+ direct.verticesNeedUpdate = geometry.verticesNeedUpdate;
+ direct.normalsNeedUpdate = geometry.normalsNeedUpdate;
+ direct.colorsNeedUpdate = geometry.colorsNeedUpdate;
+ direct.uvsNeedUpdate = geometry.uvsNeedUpdate;
+ direct.groupsNeedUpdate = geometry.groupsNeedUpdate;
+ geometry.verticesNeedUpdate = false;
+ geometry.normalsNeedUpdate = false;
+ geometry.colorsNeedUpdate = false;
+ geometry.uvsNeedUpdate = false;
+ geometry.groupsNeedUpdate = false;
+ geometry = direct;
+ }
+ if (geometry.verticesNeedUpdate === true) {
+ var attribute = this.attributes.position;
+ if (attribute !== undefined) {
+ attribute.copyVector3sArray(geometry.vertices);
+ attribute.needsUpdate = true;
+ }
+ geometry.verticesNeedUpdate = false;
+ }
+ if (geometry.normalsNeedUpdate === true) {
+ var _attribute = this.attributes.normal;
+ if (_attribute !== undefined) {
+ _attribute.copyVector3sArray(geometry.normals);
+ _attribute.needsUpdate = true;
+ }
+ geometry.normalsNeedUpdate = false;
+ }
+ if (geometry.colorsNeedUpdate === true) {
+ var _attribute2 = this.attributes.color;
+ if (_attribute2 !== undefined) {
+ _attribute2.copyColorsArray(geometry.colors);
+ _attribute2.needsUpdate = true;
+ }
+ geometry.colorsNeedUpdate = false;
+ }
+ if (geometry.uvsNeedUpdate) {
+ var _attribute3 = this.attributes.uv;
+ if (_attribute3 !== undefined) {
+ _attribute3.copyVector2sArray(geometry.uvs);
+ _attribute3.needsUpdate = true;
+ }
+ geometry.uvsNeedUpdate = false;
+ }
+ if (geometry.lineDistancesNeedUpdate) {
+ var _attribute4 = this.attributes.lineDistance;
+ if (_attribute4 !== undefined) {
+ _attribute4.copyArray(geometry.lineDistances);
+ _attribute4.needsUpdate = true;
+ }
+ geometry.lineDistancesNeedUpdate = false;
+ }
+ if (geometry.groupsNeedUpdate) {
+ geometry.computeGroups(object.geometry);
+ this.groups = geometry.groups;
+ geometry.groupsNeedUpdate = false;
+ }
+ return this;
+ },
+ fromGeometry: function fromGeometry(geometry) {
+ geometry.__directGeometry = new DirectGeometry().fromGeometry(geometry);
+ return this.fromDirectGeometry(geometry.__directGeometry);
+ },
+ fromDirectGeometry: function fromDirectGeometry(geometry) {
+ var positions = new Float32Array(geometry.vertices.length * 3);
+ this.setAttribute('position', new BufferAttribute(positions, 3).copyVector3sArray(geometry.vertices));
+ if (geometry.normals.length > 0) {
+ var normals = new Float32Array(geometry.normals.length * 3);
+ this.setAttribute('normal', new BufferAttribute(normals, 3).copyVector3sArray(geometry.normals));
+ }
+ if (geometry.colors.length > 0) {
+ var colors = new Float32Array(geometry.colors.length * 3);
+ this.setAttribute('color', new BufferAttribute(colors, 3).copyColorsArray(geometry.colors));
+ }
+ if (geometry.uvs.length > 0) {
+ var uvs = new Float32Array(geometry.uvs.length * 2);
+ this.setAttribute('uv', new BufferAttribute(uvs, 2).copyVector2sArray(geometry.uvs));
+ }
+ if (geometry.uvs2.length > 0) {
+ var uvs2 = new Float32Array(geometry.uvs2.length * 2);
+ this.setAttribute('uv2', new BufferAttribute(uvs2, 2).copyVector2sArray(geometry.uvs2));
+ } // groups
+
+ this.groups = geometry.groups; // morphs
+ for (var name in geometry.morphTargets) {
+ var array = [];
+ var morphTargets = geometry.morphTargets[name];
+ for (var i = 0, l = morphTargets.length; i < l; i++) {
+ var morphTarget = morphTargets[i];
+ var attribute = new Float32BufferAttribute(morphTarget.data.length * 3, 3);
+ attribute.name = morphTarget.name;
+ array.push(attribute.copyVector3sArray(morphTarget.data));
+ }
+ this.morphAttributes[name] = array;
+ } // skinning
+
+ if (geometry.skinIndices.length > 0) {
+ var skinIndices = new Float32BufferAttribute(geometry.skinIndices.length * 4, 4);
+ this.setAttribute('skinIndex', skinIndices.copyVector4sArray(geometry.skinIndices));
+ }
+ if (geometry.skinWeights.length > 0) {
+ var skinWeights = new Float32BufferAttribute(geometry.skinWeights.length * 4, 4);
+ this.setAttribute('skinWeight', skinWeights.copyVector4sArray(geometry.skinWeights));
+ } //
+
+ if (geometry.boundingSphere !== null) {
+ this.boundingSphere = geometry.boundingSphere.clone();
+ }
+ if (geometry.boundingBox !== null) {
+ this.boundingBox = geometry.boundingBox.clone();
+ }
+ return this;
+ },
+ computeBoundingBox: function computeBoundingBox() {
+ if (this.boundingBox === null) {
+ this.boundingBox = new Box3();
+ }
+ var position = this.attributes.position;
+ var morphAttributesPosition = this.morphAttributes.position;
+ if (position && position.isGLBufferAttribute) {
+ console.error('THREE.BufferGeometry.computeBoundingBox(): GLBufferAttribute requires a manual bounding box. Alternatively set "mesh.frustumCulled" to "false".', this);
+ this.boundingBox.set(new Vector3(-Infinity, -Infinity, -Infinity), new Vector3(+Infinity, +Infinity, +Infinity));
+ return;
+ }
+ if (position !== undefined) {
+ this.boundingBox.setFromBufferAttribute(position); // process morph attributes if present
+ if (morphAttributesPosition) {
+ for (var i = 0, il = morphAttributesPosition.length; i < il; i++) {
+ var morphAttribute = morphAttributesPosition[i];
+ _box$2.setFromBufferAttribute(morphAttribute);
+ if (this.morphTargetsRelative) {
+ _vector$4.addVectors(this.boundingBox.min, _box$2.min);
+ this.boundingBox.expandByPoint(_vector$4);
+ _vector$4.addVectors(this.boundingBox.max, _box$2.max);
+ this.boundingBox.expandByPoint(_vector$4);
+ } else {
+ this.boundingBox.expandByPoint(_box$2.min);
+ this.boundingBox.expandByPoint(_box$2.max);
+ }
+ }
+ }
+ } else {
+ this.boundingBox.makeEmpty();
+ }
+ if (isNaN(this.boundingBox.min.x) || isNaN(this.boundingBox.min.y) || isNaN(this.boundingBox.min.z)) {
+ console.error('THREE.BufferGeometry.computeBoundingBox(): Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this);
+ }
+ },
+ computeBoundingSphere: function computeBoundingSphere() {
+ if (this.boundingSphere === null) {
+ this.boundingSphere = new Sphere();
+ }
+ var position = this.attributes.position;
+ var morphAttributesPosition = this.morphAttributes.position;
+ if (position && position.isGLBufferAttribute) {
+ console.error('THREE.BufferGeometry.computeBoundingSphere(): GLBufferAttribute requires a manual bounding sphere. Alternatively set "mesh.frustumCulled" to "false".', this);
+ this.boundingSphere.set(new Vector3(), Infinity);
+ return;
+ }
+ if (position) {
+ // first, find the center of the bounding sphere
+ var center = this.boundingSphere.center;
+ _box$2.setFromBufferAttribute(position); // process morph attributes if present
+
+ if (morphAttributesPosition) {
+ for (var i = 0, il = morphAttributesPosition.length; i < il; i++) {
+ var morphAttribute = morphAttributesPosition[i];
+ _boxMorphTargets.setFromBufferAttribute(morphAttribute);
+ if (this.morphTargetsRelative) {
+ _vector$4.addVectors(_box$2.min, _boxMorphTargets.min);
+ _box$2.expandByPoint(_vector$4);
+ _vector$4.addVectors(_box$2.max, _boxMorphTargets.max);
+ _box$2.expandByPoint(_vector$4);
+ } else {
+ _box$2.expandByPoint(_boxMorphTargets.min);
+ _box$2.expandByPoint(_boxMorphTargets.max);
+ }
+ }
+ }
+ _box$2.getCenter(center); // second, try to find a boundingSphere with a radius smaller than the
+ // boundingSphere of the boundingBox: sqrt(3) smaller in the best case
+
+ var maxRadiusSq = 0;
+ for (var _i = 0, _il = position.count; _i < _il; _i++) {
+ _vector$4.fromBufferAttribute(position, _i);
+ maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$4));
+ } // process morph attributes if present
+
+ if (morphAttributesPosition) {
+ for (var _i2 = 0, _il2 = morphAttributesPosition.length; _i2 < _il2; _i2++) {
+ var _morphAttribute = morphAttributesPosition[_i2];
+ var morphTargetsRelative = this.morphTargetsRelative;
+ for (var j = 0, jl = _morphAttribute.count; j < jl; j++) {
+ _vector$4.fromBufferAttribute(_morphAttribute, j);
+ if (morphTargetsRelative) {
+ _offset.fromBufferAttribute(position, j);
+ _vector$4.add(_offset);
+ }
+ maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$4));
+ }
+ }
+ }
+ this.boundingSphere.radius = Math.sqrt(maxRadiusSq);
+ if (isNaN(this.boundingSphere.radius)) {
+ console.error('THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this);
+ }
+ }
+ },
+ computeFaceNormals: function computeFaceNormals() {// backwards compatibility
+ },
+ computeVertexNormals: function computeVertexNormals() {
+ var index = this.index;
+ var positionAttribute = this.getAttribute('position');
+ if (positionAttribute !== undefined) {
+ var normalAttribute = this.getAttribute('normal');
+ if (normalAttribute === undefined) {
+ normalAttribute = new BufferAttribute(new Float32Array(positionAttribute.count * 3), 3);
+ this.setAttribute('normal', normalAttribute);
+ } else {
+ // reset existing normals to zero
+ for (var i = 0, il = normalAttribute.count; i < il; i++) {
+ normalAttribute.setXYZ(i, 0, 0, 0);
+ }
+ }
+ var pA = new Vector3(),
+ pB = new Vector3(),
+ pC = new Vector3();
+ var nA = new Vector3(),
+ nB = new Vector3(),
+ nC = new Vector3();
+ var cb = new Vector3(),
+ ab = new Vector3(); // indexed elements
+ if (index) {
+ for (var _i3 = 0, _il3 = index.count; _i3 < _il3; _i3 += 3) {
+ var vA = index.getX(_i3 + 0);
+ var vB = index.getX(_i3 + 1);
+ var vC = index.getX(_i3 + 2);
+ pA.fromBufferAttribute(positionAttribute, vA);
+ pB.fromBufferAttribute(positionAttribute, vB);
+ pC.fromBufferAttribute(positionAttribute, vC);
+ cb.subVectors(pC, pB);
+ ab.subVectors(pA, pB);
+ cb.cross(ab);
+ nA.fromBufferAttribute(normalAttribute, vA);
+ nB.fromBufferAttribute(normalAttribute, vB);
+ nC.fromBufferAttribute(normalAttribute, vC);
+ nA.add(cb);
+ nB.add(cb);
+ nC.add(cb);
+ normalAttribute.setXYZ(vA, nA.x, nA.y, nA.z);
+ normalAttribute.setXYZ(vB, nB.x, nB.y, nB.z);
+ normalAttribute.setXYZ(vC, nC.x, nC.y, nC.z);
+ }
+ } else {
+ // non-indexed elements (unconnected triangle soup)
+ for (var _i4 = 0, _il4 = positionAttribute.count; _i4 < _il4; _i4 += 3) {
+ pA.fromBufferAttribute(positionAttribute, _i4 + 0);
+ pB.fromBufferAttribute(positionAttribute, _i4 + 1);
+ pC.fromBufferAttribute(positionAttribute, _i4 + 2);
+ cb.subVectors(pC, pB);
+ ab.subVectors(pA, pB);
+ cb.cross(ab);
+ normalAttribute.setXYZ(_i4 + 0, cb.x, cb.y, cb.z);
+ normalAttribute.setXYZ(_i4 + 1, cb.x, cb.y, cb.z);
+ normalAttribute.setXYZ(_i4 + 2, cb.x, cb.y, cb.z);
+ }
+ }
+ this.normalizeNormals();
+ normalAttribute.needsUpdate = true;
+ }
+ },
+ merge: function merge(geometry, offset) {
+ if (!(geometry && geometry.isBufferGeometry)) {
+ console.error('THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry);
+ return;
+ }
+ if (offset === undefined) {
+ offset = 0;
+ console.warn('THREE.BufferGeometry.merge(): Overwriting original geometry, starting at offset=0. ' + 'Use BufferGeometryUtils.mergeBufferGeometries() for lossless merge.');
+ }
+ var attributes = this.attributes;
+ for (var key in attributes) {
+ if (geometry.attributes[key] === undefined) continue;
+ var attribute1 = attributes[key];
+ var attributeArray1 = attribute1.array;
+ var attribute2 = geometry.attributes[key];
+ var attributeArray2 = attribute2.array;
+ var attributeOffset = attribute2.itemSize * offset;
+ var length = Math.min(attributeArray2.length, attributeArray1.length - attributeOffset);
+ for (var i = 0, j = attributeOffset; i < length; i++, j++) {
+ attributeArray1[j] = attributeArray2[i];
+ }
+ }
+ return this;
+ },
+ normalizeNormals: function normalizeNormals() {
+ var normals = this.attributes.normal;
+ for (var i = 0, il = normals.count; i < il; i++) {
+ _vector$4.fromBufferAttribute(normals, i);
+ _vector$4.normalize();
+ normals.setXYZ(i, _vector$4.x, _vector$4.y, _vector$4.z);
+ }
+ },
+ toNonIndexed: function toNonIndexed() {
+ function convertBufferAttribute(attribute, indices) {
+ var array = attribute.array;
+ var itemSize = attribute.itemSize;
+ var normalized = attribute.normalized;
+ var array2 = new array.constructor(indices.length * itemSize);
+ var index = 0,
+ index2 = 0;
+ for (var i = 0, l = indices.length; i < l; i++) {
+ index = indices[i] * itemSize;
+ for (var j = 0; j < itemSize; j++) {
+ array2[index2++] = array[index++];
+ }
+ }
+ return new BufferAttribute(array2, itemSize, normalized);
+ } //
+
+ if (this.index === null) {
+ console.warn('THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.');
+ return this;
+ }
+ var geometry2 = new BufferGeometry();
+ var indices = this.index.array;
+ var attributes = this.attributes; // attributes
+ for (var name in attributes) {
+ var attribute = attributes[name];
+ var newAttribute = convertBufferAttribute(attribute, indices);
+ geometry2.setAttribute(name, newAttribute);
+ } // morph attributes
+
+ var morphAttributes = this.morphAttributes;
+ for (var _name in morphAttributes) {
+ var morphArray = [];
+ var morphAttribute = morphAttributes[_name]; // morphAttribute: array of Float32BufferAttributes
+ for (var i = 0, il = morphAttribute.length; i < il; i++) {
+ var _attribute5 = morphAttribute[i];
+ var _newAttribute = convertBufferAttribute(_attribute5, indices);
+ morphArray.push(_newAttribute);
+ }
+ geometry2.morphAttributes[_name] = morphArray;
+ }
+ geometry2.morphTargetsRelative = this.morphTargetsRelative; // groups
+ var groups = this.groups;
+ for (var _i5 = 0, l = groups.length; _i5 < l; _i5++) {
+ var group = groups[_i5];
+ geometry2.addGroup(group.start, group.count, group.materialIndex);
+ }
+ return geometry2;
+ },
+ toJSON: function toJSON() {
+ var data = {
+ metadata: {
+ version: 4.5,
+ type: 'BufferGeometry',
+ generator: 'BufferGeometry.toJSON'
+ }
+ }; // standard BufferGeometry serialization
+ data.uuid = this.uuid;
+ data.type = this.type;
+ if (this.name !== '') data.name = this.name;
+ if (Object.keys(this.userData).length > 0) data.userData = this.userData;
+ if (this.parameters !== undefined) {
+ var parameters = this.parameters;
+ for (var key in parameters) {
+ if (parameters[key] !== undefined) data[key] = parameters[key];
+ }
+ return data;
+ }
+ data.data = {
+ attributes: {}
+ };
+ var index = this.index;
+ if (index !== null) {
+ data.data.index = {
+ type: index.array.constructor.name,
+ array: Array.prototype.slice.call(index.array)
+ };
+ }
+ var attributes = this.attributes;
+ for (var _key in attributes) {
+ var attribute = attributes[_key];
+ var attributeData = attribute.toJSON(data.data);
+ if (attribute.name !== '') attributeData.name = attribute.name;
+ data.data.attributes[_key] = attributeData;
+ }
+ var morphAttributes = {};
+ var hasMorphAttributes = false;
+ for (var _key2 in this.morphAttributes) {
+ var attributeArray = this.morphAttributes[_key2];
+ var array = [];
+ for (var i = 0, il = attributeArray.length; i < il; i++) {
+ var _attribute6 = attributeArray[i];
+ var _attributeData = _attribute6.toJSON(data.data);
+ if (_attribute6.name !== '') _attributeData.name = _attribute6.name;
+ array.push(_attributeData);
+ }
+ if (array.length > 0) {
+ morphAttributes[_key2] = array;
+ hasMorphAttributes = true;
+ }
+ }
+ if (hasMorphAttributes) {
+ data.data.morphAttributes = morphAttributes;
+ data.data.morphTargetsRelative = this.morphTargetsRelative;
+ }
+ var groups = this.groups;
+ if (groups.length > 0) {
+ data.data.groups = JSON.parse(JSON.stringify(groups));
+ }
+ var boundingSphere = this.boundingSphere;
+ if (boundingSphere !== null) {
+ data.data.boundingSphere = {
+ center: boundingSphere.center.toArray(),
+ radius: boundingSphere.radius
+ };
+ }
+ return data;
+ },
+ clone: function clone() {
+ /*
+ // Handle primitives
+ const parameters = this.parameters;
+ if ( parameters !== undefined ) {
+ const values = [];
+ for ( const key in parameters ) {
+ values.push( parameters[ key ] );
+ }
+ const geometry = Object.create( this.constructor.prototype );
+ this.constructor.apply( geometry, values );
+ return geometry;
+ }
+ return new this.constructor().copy( this );
+ */
+ return new BufferGeometry().copy(this);
+ },
+ copy: function copy(source) {
+ // reset
+ this.index = null;
+ this.attributes = {};
+ this.morphAttributes = {};
+ this.groups = [];
+ this.boundingBox = null;
+ this.boundingSphere = null; // used for storing cloned, shared data
+ var data = {}; // name
+ this.name = source.name; // index
+ var index = source.index;
+ if (index !== null) {
+ this.setIndex(index.clone(data));
+ } // attributes
+
+ var attributes = source.attributes;
+ for (var name in attributes) {
+ var attribute = attributes[name];
+ this.setAttribute(name, attribute.clone(data));
+ } // morph attributes
+
+ var morphAttributes = source.morphAttributes;
+ for (var _name2 in morphAttributes) {
+ var array = [];
+ var morphAttribute = morphAttributes[_name2]; // morphAttribute: array of Float32BufferAttributes
+ for (var i = 0, l = morphAttribute.length; i < l; i++) {
+ array.push(morphAttribute[i].clone(data));
+ }
+ this.morphAttributes[_name2] = array;
+ }
+ this.morphTargetsRelative = source.morphTargetsRelative; // groups
+ var groups = source.groups;
+ for (var _i6 = 0, _l = groups.length; _i6 < _l; _i6++) {
+ var group = groups[_i6];
+ this.addGroup(group.start, group.count, group.materialIndex);
+ } // bounding box
+
+ var boundingBox = source.boundingBox;
+ if (boundingBox !== null) {
+ this.boundingBox = boundingBox.clone();
+ } // bounding sphere
+
+ var boundingSphere = source.boundingSphere;
+ if (boundingSphere !== null) {
+ this.boundingSphere = boundingSphere.clone();
+ } // draw range
+
+ this.drawRange.start = source.drawRange.start;
+ this.drawRange.count = source.drawRange.count; // user data
+ this.userData = source.userData;
+ return this;
+ },
+ dispose: function dispose() {
+ this.dispatchEvent({
+ type: 'dispose'
+ });
+ }
+ });
+ var _inverseMatrix = new Matrix4();
+ var _ray = new Ray();
+ var _sphere = new Sphere();
+ var _vA = new Vector3();
+ var _vB = new Vector3();
+ var _vC = new Vector3();
+ var _tempA = new Vector3();
+ var _tempB = new Vector3();
+ var _tempC = new Vector3();
+ var _morphA = new Vector3();
+ var _morphB = new Vector3();
+ var _morphC = new Vector3();
+ var _uvA = new Vector2();
+ var _uvB = new Vector2();
+ var _uvC = new Vector2();
+ var _intersectionPoint = new Vector3();
+ var _intersectionPointWorld = new Vector3();
+ function Mesh(geometry, material) {
+ Object3D.call(this);
+ this.type = 'Mesh';
+ this.geometry = geometry !== undefined ? geometry : new BufferGeometry();
+ this.material = material !== undefined ? material : new MeshBasicMaterial();
+ this.updateMorphTargets();
+ }
+ Mesh.prototype = Object.assign(Object.create(Object3D.prototype), {
+ constructor: Mesh,
+ isMesh: true,
+ copy: function copy(source) {
+ Object3D.prototype.copy.call(this, source);
+ if (source.morphTargetInfluences !== undefined) {
+ this.morphTargetInfluences = source.morphTargetInfluences.slice();
+ }
+ if (source.morphTargetDictionary !== undefined) {
+ this.morphTargetDictionary = Object.assign({}, source.morphTargetDictionary);
+ }
+ this.material = source.material;
+ this.geometry = source.geometry;
+ return this;
+ },
+ updateMorphTargets: function updateMorphTargets() {
+ var geometry = this.geometry;
+ if (geometry.isBufferGeometry) {
+ var morphAttributes = geometry.morphAttributes;
+ var keys = Object.keys(morphAttributes);
+ if (keys.length > 0) {
+ var morphAttribute = morphAttributes[keys[0]];
+ if (morphAttribute !== undefined) {
+ this.morphTargetInfluences = [];
+ this.morphTargetDictionary = {};
+ for (var m = 0, ml = morphAttribute.length; m < ml; m++) {
+ var name = morphAttribute[m].name || String(m);
+ this.morphTargetInfluences.push(0);
+ this.morphTargetDictionary[name] = m;
+ }
+ }
+ }
+ } else {
+ var morphTargets = geometry.morphTargets;
+ if (morphTargets !== undefined && morphTargets.length > 0) {
+ console.error('THREE.Mesh.updateMorphTargets() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.');
+ }
+ }
+ },
+ raycast: function raycast(raycaster, intersects) {
+ var geometry = this.geometry;
+ var material = this.material;
+ var matrixWorld = this.matrixWorld;
+ if (material === undefined) return; // Checking boundingSphere distance to ray
+ if (geometry.boundingSphere === null) geometry.computeBoundingSphere();
+ _sphere.copy(geometry.boundingSphere);
+ _sphere.applyMatrix4(matrixWorld);
+ if (raycaster.ray.intersectsSphere(_sphere) === false) return; //
+ _inverseMatrix.copy(matrixWorld).invert();
+ _ray.copy(raycaster.ray).applyMatrix4(_inverseMatrix); // Check boundingBox before continuing
+
+ if (geometry.boundingBox !== null) {
+ if (_ray.intersectsBox(geometry.boundingBox) === false) return;
+ }
+ var intersection;
+ if (geometry.isBufferGeometry) {
+ var index = geometry.index;
+ var position = geometry.attributes.position;
+ var morphPosition = geometry.morphAttributes.position;
+ var morphTargetsRelative = geometry.morphTargetsRelative;
+ var uv = geometry.attributes.uv;
+ var uv2 = geometry.attributes.uv2;
+ var groups = geometry.groups;
+ var drawRange = geometry.drawRange;
+ if (index !== null) {
+ // indexed buffer geometry
+ if (Array.isArray(material)) {
+ for (var i = 0, il = groups.length; i < il; i++) {
+ var group = groups[i];
+ var groupMaterial = material[group.materialIndex];
+ var start = Math.max(group.start, drawRange.start);
+ var end = Math.min(group.start + group.count, drawRange.start + drawRange.count);
+ for (var j = start, jl = end; j < jl; j += 3) {
+ var a = index.getX(j);
+ var b = index.getX(j + 1);
+ var c = index.getX(j + 2);
+ intersection = checkBufferGeometryIntersection(this, groupMaterial, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c);
+ if (intersection) {
+ intersection.faceIndex = Math.floor(j / 3); // triangle number in indexed buffer semantics
+ intersection.face.materialIndex = group.materialIndex;
+ intersects.push(intersection);
+ }
+ }
+ }
+ } else {
+ var _start = Math.max(0, drawRange.start);
+ var _end = Math.min(index.count, drawRange.start + drawRange.count);
+ for (var _i = _start, _il = _end; _i < _il; _i += 3) {
+ var _a = index.getX(_i);
+ var _b = index.getX(_i + 1);
+ var _c = index.getX(_i + 2);
+ intersection = checkBufferGeometryIntersection(this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, _a, _b, _c);
+ if (intersection) {
+ intersection.faceIndex = Math.floor(_i / 3); // triangle number in indexed buffer semantics
+ intersects.push(intersection);
+ }
+ }
+ }
+ } else if (position !== undefined) {
+ // non-indexed buffer geometry
+ if (Array.isArray(material)) {
+ for (var _i2 = 0, _il2 = groups.length; _i2 < _il2; _i2++) {
+ var _group = groups[_i2];
+ var _groupMaterial = material[_group.materialIndex];
+ var _start2 = Math.max(_group.start, drawRange.start);
+ var _end2 = Math.min(_group.start + _group.count, drawRange.start + drawRange.count);
+ for (var _j = _start2, _jl = _end2; _j < _jl; _j += 3) {
+ var _a2 = _j;
+ var _b2 = _j + 1;
+ var _c2 = _j + 2;
+ intersection = checkBufferGeometryIntersection(this, _groupMaterial, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, _a2, _b2, _c2);
+ if (intersection) {
+ intersection.faceIndex = Math.floor(_j / 3); // triangle number in non-indexed buffer semantics
+ intersection.face.materialIndex = _group.materialIndex;
+ intersects.push(intersection);
+ }
+ }
+ }
+ } else {
+ var _start3 = Math.max(0, drawRange.start);
+ var _end3 = Math.min(position.count, drawRange.start + drawRange.count);
+ for (var _i3 = _start3, _il3 = _end3; _i3 < _il3; _i3 += 3) {
+ var _a3 = _i3;
+ var _b3 = _i3 + 1;
+ var _c3 = _i3 + 2;
+ intersection = checkBufferGeometryIntersection(this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, _a3, _b3, _c3);
+ if (intersection) {
+ intersection.faceIndex = Math.floor(_i3 / 3); // triangle number in non-indexed buffer semantics
+ intersects.push(intersection);
+ }
+ }
+ }
+ }
+ } else if (geometry.isGeometry) {
+ var isMultiMaterial = Array.isArray(material);
+ var vertices = geometry.vertices;
+ var faces = geometry.faces;
+ var uvs;
+ var faceVertexUvs = geometry.faceVertexUvs[0];
+ if (faceVertexUvs.length > 0) uvs = faceVertexUvs;
+ for (var f = 0, fl = faces.length; f < fl; f++) {
+ var face = faces[f];
+ var faceMaterial = isMultiMaterial ? material[face.materialIndex] : material;
+ if (faceMaterial === undefined) continue;
+ var fvA = vertices[face.a];
+ var fvB = vertices[face.b];
+ var fvC = vertices[face.c];
+ intersection = checkIntersection(this, faceMaterial, raycaster, _ray, fvA, fvB, fvC, _intersectionPoint);
+ if (intersection) {
+ if (uvs && uvs[f]) {
+ var uvs_f = uvs[f];
+ _uvA.copy(uvs_f[0]);
+ _uvB.copy(uvs_f[1]);
+ _uvC.copy(uvs_f[2]);
+ intersection.uv = Triangle.getUV(_intersectionPoint, fvA, fvB, fvC, _uvA, _uvB, _uvC, new Vector2());
+ }
+ intersection.face = face;
+ intersection.faceIndex = f;
+ intersects.push(intersection);
+ }
+ }
+ }
+ }
+ });
+ function checkIntersection(object, material, raycaster, ray, pA, pB, pC, point) {
+ var intersect;
+ if (material.side === BackSide) {
+ intersect = ray.intersectTriangle(pC, pB, pA, true, point);
+ } else {
+ intersect = ray.intersectTriangle(pA, pB, pC, material.side !== DoubleSide, point);
+ }
+ if (intersect === null) return null;
+ _intersectionPointWorld.copy(point);
+ _intersectionPointWorld.applyMatrix4(object.matrixWorld);
+ var distance = raycaster.ray.origin.distanceTo(_intersectionPointWorld);
+ if (distance < raycaster.near || distance > raycaster.far) return null;
+ return {
+ distance: distance,
+ point: _intersectionPointWorld.clone(),
+ object: object
+ };
+ }
+ function checkBufferGeometryIntersection(object, material, raycaster, ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c) {
+ _vA.fromBufferAttribute(position, a);
+ _vB.fromBufferAttribute(position, b);
+ _vC.fromBufferAttribute(position, c);
+ var morphInfluences = object.morphTargetInfluences;
+ if (material.morphTargets && morphPosition && morphInfluences) {
+ _morphA.set(0, 0, 0);
+ _morphB.set(0, 0, 0);
+ _morphC.set(0, 0, 0);
+ for (var i = 0, il = morphPosition.length; i < il; i++) {
+ var influence = morphInfluences[i];
+ var morphAttribute = morphPosition[i];
+ if (influence === 0) continue;
+ _tempA.fromBufferAttribute(morphAttribute, a);
+ _tempB.fromBufferAttribute(morphAttribute, b);
+ _tempC.fromBufferAttribute(morphAttribute, c);
+ if (morphTargetsRelative) {
+ _morphA.addScaledVector(_tempA, influence);
+ _morphB.addScaledVector(_tempB, influence);
+ _morphC.addScaledVector(_tempC, influence);
+ } else {
+ _morphA.addScaledVector(_tempA.sub(_vA), influence);
+ _morphB.addScaledVector(_tempB.sub(_vB), influence);
+ _morphC.addScaledVector(_tempC.sub(_vC), influence);
+ }
+ }
+ _vA.add(_morphA);
+ _vB.add(_morphB);
+ _vC.add(_morphC);
+ }
+ if (object.isSkinnedMesh) {
+ object.boneTransform(a, _vA);
+ object.boneTransform(b, _vB);
+ object.boneTransform(c, _vC);
+ }
+ var intersection = checkIntersection(object, material, raycaster, ray, _vA, _vB, _vC, _intersectionPoint);
+ if (intersection) {
+ if (uv) {
+ _uvA.fromBufferAttribute(uv, a);
+ _uvB.fromBufferAttribute(uv, b);
+ _uvC.fromBufferAttribute(uv, c);
+ intersection.uv = Triangle.getUV(_intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2());
+ }
+ if (uv2) {
+ _uvA.fromBufferAttribute(uv2, a);
+ _uvB.fromBufferAttribute(uv2, b);
+ _uvC.fromBufferAttribute(uv2, c);
+ intersection.uv2 = Triangle.getUV(_intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2());
+ }
+ var face = new Face3(a, b, c);
+ Triangle.getNormal(_vA, _vB, _vC, face.normal);
+ intersection.face = face;
+ }
+ return intersection;
+ }
+ var BoxBufferGeometry = /*#__PURE__*/function (_BufferGeometry) {
+ _inheritsLoose(BoxBufferGeometry, _BufferGeometry);
+ function BoxBufferGeometry(width, height, depth, widthSegments, heightSegments, depthSegments) {
+ var _this;
+ if (width === void 0) {
+ width = 1;
+ }
+ if (height === void 0) {
+ height = 1;
+ }
+ if (depth === void 0) {
+ depth = 1;
+ }
+ if (widthSegments === void 0) {
+ widthSegments = 1;
+ }
+ if (heightSegments === void 0) {
+ heightSegments = 1;
+ }
+ if (depthSegments === void 0) {
+ depthSegments = 1;
+ }
+ _this = _BufferGeometry.call(this) || this;
+ _this.type = 'BoxBufferGeometry';
+ _this.parameters = {
+ width: width,
+ height: height,
+ depth: depth,
+ widthSegments: widthSegments,
+ heightSegments: heightSegments,
+ depthSegments: depthSegments
+ };
+ var scope = _assertThisInitialized(_this); // segments
+
+ widthSegments = Math.floor(widthSegments);
+ heightSegments = Math.floor(heightSegments);
+ depthSegments = Math.floor(depthSegments); // buffers
+ var indices = [];
+ var vertices = [];
+ var normals = [];
+ var uvs = []; // helper variables
+ var numberOfVertices = 0;
+ var groupStart = 0; // build each side of the box geometry
+ buildPlane('z', 'y', 'x', -1, -1, depth, height, width, depthSegments, heightSegments, 0); // px
+ buildPlane('z', 'y', 'x', 1, -1, depth, height, -width, depthSegments, heightSegments, 1); // nx
+ buildPlane('x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2); // py
+ buildPlane('x', 'z', 'y', 1, -1, width, depth, -height, widthSegments, depthSegments, 3); // ny
+ buildPlane('x', 'y', 'z', 1, -1, width, height, depth, widthSegments, heightSegments, 4); // pz
+ buildPlane('x', 'y', 'z', -1, -1, width, height, -depth, widthSegments, heightSegments, 5); // nz
+ // build geometry
+ _this.setIndex(indices);
+ _this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
+ _this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
+ _this.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
+ function buildPlane(u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex) {
+ var segmentWidth = width / gridX;
+ var segmentHeight = height / gridY;
+ var widthHalf = width / 2;
+ var heightHalf = height / 2;
+ var depthHalf = depth / 2;
+ var gridX1 = gridX + 1;
+ var gridY1 = gridY + 1;
+ var vertexCounter = 0;
+ var groupCount = 0;
+ var vector = new Vector3(); // generate vertices, normals and uvs
+ for (var iy = 0; iy < gridY1; iy++) {
+ var y = iy * segmentHeight - heightHalf;
+ for (var ix = 0; ix < gridX1; ix++) {
+ var x = ix * segmentWidth - widthHalf; // set values to correct vector component
+ vector[u] = x * udir;
+ vector[v] = y * vdir;
+ vector[w] = depthHalf; // now apply vector to vertex buffer
+ vertices.push(vector.x, vector.y, vector.z); // set values to correct vector component
+ vector[u] = 0;
+ vector[v] = 0;
+ vector[w] = depth > 0 ? 1 : -1; // now apply vector to normal buffer
+ normals.push(vector.x, vector.y, vector.z); // uvs
+ uvs.push(ix / gridX);
+ uvs.push(1 - iy / gridY); // counters
+ vertexCounter += 1;
+ }
+ } // indices
+ // 1. you need three indices to draw a single face
+ // 2. a single segment consists of two faces
+ // 3. so we need to generate six (2*3) indices per segment
+
+ for (var _iy = 0; _iy < gridY; _iy++) {
+ for (var _ix = 0; _ix < gridX; _ix++) {
+ var a = numberOfVertices + _ix + gridX1 * _iy;
+ var b = numberOfVertices + _ix + gridX1 * (_iy + 1);
+ var c = numberOfVertices + (_ix + 1) + gridX1 * (_iy + 1);
+ var d = numberOfVertices + (_ix + 1) + gridX1 * _iy; // faces
+ indices.push(a, b, d);
+ indices.push(b, c, d); // increase counter
+ groupCount += 6;
+ }
+ } // add a group to the geometry. this will ensure multi material support
+
+ scope.addGroup(groupStart, groupCount, materialIndex); // calculate new start value for groups
+ groupStart += groupCount; // update total number of vertices
+ numberOfVertices += vertexCounter;
+ }
+ return _this;
+ }
+ return BoxBufferGeometry;
+ }(BufferGeometry);
+ /**
+ * Uniform Utilities
+ */
+ function cloneUniforms(src) {
+ var dst = {};
+ for (var u in src) {
+ dst[u] = {};
+ for (var p in src[u]) {
+ var property = src[u][p];
+ if (property && (property.isColor || property.isMatrix3 || property.isMatrix4 || property.isVector2 || property.isVector3 || property.isVector4 || property.isTexture)) {
+ dst[u][p] = property.clone();
+ } else if (Array.isArray(property)) {
+ dst[u][p] = property.slice();
+ } else {
+ dst[u][p] = property;
+ }
+ }
+ }
+ return dst;
+ }
+ function mergeUniforms(uniforms) {
+ var merged = {};
+ for (var u = 0; u < uniforms.length; u++) {
+ var tmp = cloneUniforms(uniforms[u]);
+ for (var p in tmp) {
+ merged[p] = tmp[p];
+ }
+ }
+ return merged;
+ } // Legacy
+ var UniformsUtils = {
+ clone: cloneUniforms,
+ merge: mergeUniforms
+ };
+ var default_vertex = "void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}";
+ var default_fragment = "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}";
+ /**
+ * parameters = {
+ * defines: { "label" : "value" },
+ * uniforms: { "parameter1": { value: 1.0 }, "parameter2": { value2: 2 } },
+ *
+ * fragmentShader: ,
+ * vertexShader: ,
+ *
+ * wireframe: ,
+ * wireframeLinewidth: ,
+ *
+ * lights: ,
+ *
+ * skinning: ,
+ * morphTargets: ,
+ * morphNormals:
+ * }
+ */
+ function ShaderMaterial(parameters) {
+ Material.call(this);
+ this.type = 'ShaderMaterial';
+ this.defines = {};
+ this.uniforms = {};
+ this.vertexShader = default_vertex;
+ this.fragmentShader = default_fragment;
+ this.linewidth = 1;
+ this.wireframe = false;
+ this.wireframeLinewidth = 1;
+ this.fog = false; // set to use scene fog
+ this.lights = false; // set to use scene lights
+ this.clipping = false; // set to use user-defined clipping planes
+ this.skinning = false; // set to use skinning attribute streams
+ this.morphTargets = false; // set to use morph targets
+ this.morphNormals = false; // set to use morph normals
+ this.extensions = {
+ derivatives: false,
+ // set to use derivatives
+ fragDepth: false,
+ // set to use fragment depth values
+ drawBuffers: false,
+ // set to use draw buffers
+ shaderTextureLOD: false // set to use shader texture LOD
+ }; // When rendered geometry doesn't include these attributes but the material does,
+ // use these default values in WebGL. This avoids errors when buffer data is missing.
+ this.defaultAttributeValues = {
+ 'color': [1, 1, 1],
+ 'uv': [0, 0],
+ 'uv2': [0, 0]
+ };
+ this.index0AttributeName = undefined;
+ this.uniformsNeedUpdate = false;
+ this.glslVersion = null;
+ if (parameters !== undefined) {
+ if (parameters.attributes !== undefined) {
+ console.error('THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.');
+ }
+ this.setValues(parameters);
+ }
+ }
+ ShaderMaterial.prototype = Object.create(Material.prototype);
+ ShaderMaterial.prototype.constructor = ShaderMaterial;
+ ShaderMaterial.prototype.isShaderMaterial = true;
+ ShaderMaterial.prototype.copy = function (source) {
+ Material.prototype.copy.call(this, source);
+ this.fragmentShader = source.fragmentShader;
+ this.vertexShader = source.vertexShader;
+ this.uniforms = cloneUniforms(source.uniforms);
+ this.defines = Object.assign({}, source.defines);
+ this.wireframe = source.wireframe;
+ this.wireframeLinewidth = source.wireframeLinewidth;
+ this.lights = source.lights;
+ this.clipping = source.clipping;
+ this.skinning = source.skinning;
+ this.morphTargets = source.morphTargets;
+ this.morphNormals = source.morphNormals;
+ this.extensions = Object.assign({}, source.extensions);
+ this.glslVersion = source.glslVersion;
+ return this;
+ };
+ ShaderMaterial.prototype.toJSON = function (meta) {
+ var data = Material.prototype.toJSON.call(this, meta);
+ data.glslVersion = this.glslVersion;
+ data.uniforms = {};
+ for (var name in this.uniforms) {
+ var uniform = this.uniforms[name];
+ var value = uniform.value;
+ if (value && value.isTexture) {
+ data.uniforms[name] = {
+ type: 't',
+ value: value.toJSON(meta).uuid
+ };
+ } else if (value && value.isColor) {
+ data.uniforms[name] = {
+ type: 'c',
+ value: value.getHex()
+ };
+ } else if (value && value.isVector2) {
+ data.uniforms[name] = {
+ type: 'v2',
+ value: value.toArray()
+ };
+ } else if (value && value.isVector3) {
+ data.uniforms[name] = {
+ type: 'v3',
+ value: value.toArray()
+ };
+ } else if (value && value.isVector4) {
+ data.uniforms[name] = {
+ type: 'v4',
+ value: value.toArray()
+ };
+ } else if (value && value.isMatrix3) {
+ data.uniforms[name] = {
+ type: 'm3',
+ value: value.toArray()
+ };
+ } else if (value && value.isMatrix4) {
+ data.uniforms[name] = {
+ type: 'm4',
+ value: value.toArray()
+ };
+ } else {
+ data.uniforms[name] = {
+ value: value
+ }; // note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far
+ }
+ }
+ if (Object.keys(this.defines).length > 0) data.defines = this.defines;
+ data.vertexShader = this.vertexShader;
+ data.fragmentShader = this.fragmentShader;
+ var extensions = {};
+ for (var key in this.extensions) {
+ if (this.extensions[key] === true) extensions[key] = true;
+ }
+ if (Object.keys(extensions).length > 0) data.extensions = extensions;
+ return data;
+ };
+ function Camera() {
+ Object3D.call(this);
+ this.type = 'Camera';
+ this.matrixWorldInverse = new Matrix4();
+ this.projectionMatrix = new Matrix4();
+ this.projectionMatrixInverse = new Matrix4();
+ }
+ Camera.prototype = Object.assign(Object.create(Object3D.prototype), {
+ constructor: Camera,
+ isCamera: true,
+ copy: function copy(source, recursive) {
+ Object3D.prototype.copy.call(this, source, recursive);
+ this.matrixWorldInverse.copy(source.matrixWorldInverse);
+ this.projectionMatrix.copy(source.projectionMatrix);
+ this.projectionMatrixInverse.copy(source.projectionMatrixInverse);
+ return this;
+ },
+ getWorldDirection: function getWorldDirection(target) {
+ if (target === undefined) {
+ console.warn('THREE.Camera: .getWorldDirection() target is now required');
+ target = new Vector3();
+ }
+ this.updateWorldMatrix(true, false);
+ var e = this.matrixWorld.elements;
+ return target.set(-e[8], -e[9], -e[10]).normalize();
+ },
+ updateMatrixWorld: function updateMatrixWorld(force) {
+ Object3D.prototype.updateMatrixWorld.call(this, force);
+ this.matrixWorldInverse.copy(this.matrixWorld).invert();
+ },
+ updateWorldMatrix: function updateWorldMatrix(updateParents, updateChildren) {
+ Object3D.prototype.updateWorldMatrix.call(this, updateParents, updateChildren);
+ this.matrixWorldInverse.copy(this.matrixWorld).invert();
+ },
+ clone: function clone() {
+ return new this.constructor().copy(this);
+ }
+ });
+ function PerspectiveCamera(fov, aspect, near, far) {
+ if (fov === void 0) {
+ fov = 50;
+ }
+ if (aspect === void 0) {
+ aspect = 1;
+ }
+ if (near === void 0) {
+ near = 0.1;
+ }
+ if (far === void 0) {
+ far = 2000;
+ }
+ Camera.call(this);
+ this.type = 'PerspectiveCamera';
+ this.fov = fov;
+ this.zoom = 1;
+ this.near = near;
+ this.far = far;
+ this.focus = 10;
+ this.aspect = aspect;
+ this.view = null;
+ this.filmGauge = 35; // width of the film (default in millimeters)
+ this.filmOffset = 0; // horizontal film offset (same unit as gauge)
+ this.updateProjectionMatrix();
+ }
+ PerspectiveCamera.prototype = Object.assign(Object.create(Camera.prototype), {
+ constructor: PerspectiveCamera,
+ isPerspectiveCamera: true,
+ copy: function copy(source, recursive) {
+ Camera.prototype.copy.call(this, source, recursive);
+ this.fov = source.fov;
+ this.zoom = source.zoom;
+ this.near = source.near;
+ this.far = source.far;
+ this.focus = source.focus;
+ this.aspect = source.aspect;
+ this.view = source.view === null ? null : Object.assign({}, source.view);
+ this.filmGauge = source.filmGauge;
+ this.filmOffset = source.filmOffset;
+ return this;
+ },
+ /**
+ * Sets the FOV by focal length in respect to the current .filmGauge.
+ *
+ * The default film gauge is 35, so that the focal length can be specified for
+ * a 35mm (full frame) camera.
+ *
+ * Values for focal length and film gauge must have the same unit.
+ */
+ setFocalLength: function setFocalLength(focalLength) {
+ // see http://www.bobatkins.com/photography/technical/field_of_view.html
+ var vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;
+ this.fov = MathUtils.RAD2DEG * 2 * Math.atan(vExtentSlope);
+ this.updateProjectionMatrix();
+ },
+ /**
+ * Calculates the focal length from the current .fov and .filmGauge.
+ */
+ getFocalLength: function getFocalLength() {
+ var vExtentSlope = Math.tan(MathUtils.DEG2RAD * 0.5 * this.fov);
+ return 0.5 * this.getFilmHeight() / vExtentSlope;
+ },
+ getEffectiveFOV: function getEffectiveFOV() {
+ return MathUtils.RAD2DEG * 2 * Math.atan(Math.tan(MathUtils.DEG2RAD * 0.5 * this.fov) / this.zoom);
+ },
+ getFilmWidth: function getFilmWidth() {
+ // film not completely covered in portrait format (aspect < 1)
+ return this.filmGauge * Math.min(this.aspect, 1);
+ },
+ getFilmHeight: function getFilmHeight() {
+ // film not completely covered in landscape format (aspect > 1)
+ return this.filmGauge / Math.max(this.aspect, 1);
+ },
+ /**
+ * Sets an offset in a larger frustum. This is useful for multi-window or
+ * multi-monitor/multi-machine setups.
+ *
+ * For example, if you have 3x2 monitors and each monitor is 1920x1080 and
+ * the monitors are in grid like this
+ *
+ * +---+---+---+
+ * | A | B | C |
+ * +---+---+---+
+ * | D | E | F |
+ * +---+---+---+
+ *
+ * then for each monitor you would call it like this
+ *
+ * const w = 1920;
+ * const h = 1080;
+ * const fullWidth = w * 3;
+ * const fullHeight = h * 2;
+ *
+ * --A--
+ * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
+ * --B--
+ * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
+ * --C--
+ * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
+ * --D--
+ * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
+ * --E--
+ * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
+ * --F--
+ * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
+ *
+ * Note there is no reason monitors have to be the same size or in a grid.
+ */
+ setViewOffset: function setViewOffset(fullWidth, fullHeight, x, y, width, height) {
+ this.aspect = fullWidth / fullHeight;
+ if (this.view === null) {
+ this.view = {
+ enabled: true,
+ fullWidth: 1,
+ fullHeight: 1,
+ offsetX: 0,
+ offsetY: 0,
+ width: 1,
+ height: 1
+ };
+ }
+ this.view.enabled = true;
+ this.view.fullWidth = fullWidth;
+ this.view.fullHeight = fullHeight;
+ this.view.offsetX = x;
+ this.view.offsetY = y;
+ this.view.width = width;
+ this.view.height = height;
+ this.updateProjectionMatrix();
+ },
+ clearViewOffset: function clearViewOffset() {
+ if (this.view !== null) {
+ this.view.enabled = false;
+ }
+ this.updateProjectionMatrix();
+ },
+ updateProjectionMatrix: function updateProjectionMatrix() {
+ var near = this.near;
+ var top = near * Math.tan(MathUtils.DEG2RAD * 0.5 * this.fov) / this.zoom;
+ var height = 2 * top;
+ var width = this.aspect * height;
+ var left = -0.5 * width;
+ var view = this.view;
+ if (this.view !== null && this.view.enabled) {
+ var fullWidth = view.fullWidth,
+ fullHeight = view.fullHeight;
+ left += view.offsetX * width / fullWidth;
+ top -= view.offsetY * height / fullHeight;
+ width *= view.width / fullWidth;
+ height *= view.height / fullHeight;
+ }
+ var skew = this.filmOffset;
+ if (skew !== 0) left += near * skew / this.getFilmWidth();
+ this.projectionMatrix.makePerspective(left, left + width, top, top - height, near, this.far);
+ this.projectionMatrixInverse.copy(this.projectionMatrix).invert();
+ },
+ toJSON: function toJSON(meta) {
+ var data = Object3D.prototype.toJSON.call(this, meta);
+ data.object.fov = this.fov;
+ data.object.zoom = this.zoom;
+ data.object.near = this.near;
+ data.object.far = this.far;
+ data.object.focus = this.focus;
+ data.object.aspect = this.aspect;
+ if (this.view !== null) data.object.view = Object.assign({}, this.view);
+ data.object.filmGauge = this.filmGauge;
+ data.object.filmOffset = this.filmOffset;
+ return data;
+ }
+ });
+ var fov = 90,
+ aspect = 1;
+ function CubeCamera(near, far, renderTarget) {
+ Object3D.call(this);
+ this.type = 'CubeCamera';
+ if (renderTarget.isWebGLCubeRenderTarget !== true) {
+ console.error('THREE.CubeCamera: The constructor now expects an instance of WebGLCubeRenderTarget as third parameter.');
+ return;
+ }
+ this.renderTarget = renderTarget;
+ var cameraPX = new PerspectiveCamera(fov, aspect, near, far);
+ cameraPX.layers = this.layers;
+ cameraPX.up.set(0, -1, 0);
+ cameraPX.lookAt(new Vector3(1, 0, 0));
+ this.add(cameraPX);
+ var cameraNX = new PerspectiveCamera(fov, aspect, near, far);
+ cameraNX.layers = this.layers;
+ cameraNX.up.set(0, -1, 0);
+ cameraNX.lookAt(new Vector3(-1, 0, 0));
+ this.add(cameraNX);
+ var cameraPY = new PerspectiveCamera(fov, aspect, near, far);
+ cameraPY.layers = this.layers;
+ cameraPY.up.set(0, 0, 1);
+ cameraPY.lookAt(new Vector3(0, 1, 0));
+ this.add(cameraPY);
+ var cameraNY = new PerspectiveCamera(fov, aspect, near, far);
+ cameraNY.layers = this.layers;
+ cameraNY.up.set(0, 0, -1);
+ cameraNY.lookAt(new Vector3(0, -1, 0));
+ this.add(cameraNY);
+ var cameraPZ = new PerspectiveCamera(fov, aspect, near, far);
+ cameraPZ.layers = this.layers;
+ cameraPZ.up.set(0, -1, 0);
+ cameraPZ.lookAt(new Vector3(0, 0, 1));
+ this.add(cameraPZ);
+ var cameraNZ = new PerspectiveCamera(fov, aspect, near, far);
+ cameraNZ.layers = this.layers;
+ cameraNZ.up.set(0, -1, 0);
+ cameraNZ.lookAt(new Vector3(0, 0, -1));
+ this.add(cameraNZ);
+ this.update = function (renderer, scene) {
+ if (this.parent === null) this.updateMatrixWorld();
+ var currentXrEnabled = renderer.xr.enabled;
+ var currentRenderTarget = renderer.getRenderTarget();
+ renderer.xr.enabled = false;
+ var generateMipmaps = renderTarget.texture.generateMipmaps;
+ renderTarget.texture.generateMipmaps = false;
+ renderer.setRenderTarget(renderTarget, 0);
+ renderer.render(scene, cameraPX);
+ renderer.setRenderTarget(renderTarget, 1);
+ renderer.render(scene, cameraNX);
+ renderer.setRenderTarget(renderTarget, 2);
+ renderer.render(scene, cameraPY);
+ renderer.setRenderTarget(renderTarget, 3);
+ renderer.render(scene, cameraNY);
+ renderer.setRenderTarget(renderTarget, 4);
+ renderer.render(scene, cameraPZ);
+ renderTarget.texture.generateMipmaps = generateMipmaps;
+ renderer.setRenderTarget(renderTarget, 5);
+ renderer.render(scene, cameraNZ);
+ renderer.setRenderTarget(currentRenderTarget);
+ renderer.xr.enabled = currentXrEnabled;
+ };
+ }
+ CubeCamera.prototype = Object.create(Object3D.prototype);
+ CubeCamera.prototype.constructor = CubeCamera;
+ function CubeTexture(images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding) {
+ images = images !== undefined ? images : [];
+ mapping = mapping !== undefined ? mapping : CubeReflectionMapping;
+ format = format !== undefined ? format : RGBFormat;
+ Texture.call(this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding);
+ this.flipY = false; // Why CubeTexture._needsFlipEnvMap is necessary:
+ //
+ // By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js)
+ // in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words,
+ // in a left-handed coordinate system. By continuing this convention, preexisting cube maps continued to render correctly.
+ // three.js uses a right-handed coordinate system. So environment maps used in three.js appear to have px and nx swapped
+ // and the flag _needsFlipEnvMap controls this conversion. The flip is not required (and thus _needsFlipEnvMap is set to false)
+ // when using WebGLCubeRenderTarget.texture as a cube texture.
+ this._needsFlipEnvMap = true;
+ }
+ CubeTexture.prototype = Object.create(Texture.prototype);
+ CubeTexture.prototype.constructor = CubeTexture;
+ CubeTexture.prototype.isCubeTexture = true;
+ Object.defineProperty(CubeTexture.prototype, 'images', {
+ get: function get() {
+ return this.image;
+ },
+ set: function set(value) {
+ this.image = value;
+ }
+ });
+ function WebGLCubeRenderTarget(size, options, dummy) {
+ if (Number.isInteger(options)) {
+ console.warn('THREE.WebGLCubeRenderTarget: constructor signature is now WebGLCubeRenderTarget( size, options )');
+ options = dummy;
+ }
+ WebGLRenderTarget.call(this, size, size, options);
+ options = options || {};
+ this.texture = new CubeTexture(undefined, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding);
+ this.texture._needsFlipEnvMap = false;
+ }
+ WebGLCubeRenderTarget.prototype = Object.create(WebGLRenderTarget.prototype);
+ WebGLCubeRenderTarget.prototype.constructor = WebGLCubeRenderTarget;
+ WebGLCubeRenderTarget.prototype.isWebGLCubeRenderTarget = true;
+ WebGLCubeRenderTarget.prototype.fromEquirectangularTexture = function (renderer, texture) {
+ this.texture.type = texture.type;
+ this.texture.format = RGBAFormat; // see #18859
+ this.texture.encoding = texture.encoding;
+ this.texture.generateMipmaps = texture.generateMipmaps;
+ this.texture.minFilter = texture.minFilter;
+ this.texture.magFilter = texture.magFilter;
+ var shader = {
+ uniforms: {
+ tEquirect: {
+ value: null
+ }
+ },
+ vertexShader:
+ /* glsl */
+ "\n\n\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\tvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\n\t\t\t\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n\n\t\t\t}\n\n\t\t\tvoid main() {\n\n\t\t\t\tvWorldDirection = transformDirection( position, modelMatrix );\n\n\t\t\t\t#include \n\t\t\t\t#include \n\n\t\t\t}\n\t\t",
+ fragmentShader:
+ /* glsl */
+ "\n\n\t\t\tuniform sampler2D tEquirect;\n\n\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\t#include \n\n\t\t\tvoid main() {\n\n\t\t\t\tvec3 direction = normalize( vWorldDirection );\n\n\t\t\t\tvec2 sampleUV = equirectUv( direction );\n\n\t\t\t\tgl_FragColor = texture2D( tEquirect, sampleUV );\n\n\t\t\t}\n\t\t"
+ };
+ var geometry = new BoxBufferGeometry(5, 5, 5);
+ var material = new ShaderMaterial({
+ name: 'CubemapFromEquirect',
+ uniforms: cloneUniforms(shader.uniforms),
+ vertexShader: shader.vertexShader,
+ fragmentShader: shader.fragmentShader,
+ side: BackSide,
+ blending: NoBlending
+ });
+ material.uniforms.tEquirect.value = texture;
+ var mesh = new Mesh(geometry, material);
+ var currentMinFilter = texture.minFilter; // Avoid blurred poles
+ if (texture.minFilter === LinearMipmapLinearFilter) texture.minFilter = LinearFilter;
+ var camera = new CubeCamera(1, 10, this);
+ camera.update(renderer, mesh);
+ texture.minFilter = currentMinFilter;
+ mesh.geometry.dispose();
+ mesh.material.dispose();
+ return this;
+ };
+ WebGLCubeRenderTarget.prototype.clear = function (renderer, color, depth, stencil) {
+ var currentRenderTarget = renderer.getRenderTarget();
+ for (var i = 0; i < 6; i++) {
+ renderer.setRenderTarget(this, i);
+ renderer.clear(color, depth, stencil);
+ }
+ renderer.setRenderTarget(currentRenderTarget);
+ };
+ function DataTexture(data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding) {
+ Texture.call(this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding);
+ this.image = {
+ data: data || null,
+ width: width || 1,
+ height: height || 1
+ };
+ this.magFilter = magFilter !== undefined ? magFilter : NearestFilter;
+ this.minFilter = minFilter !== undefined ? minFilter : NearestFilter;
+ this.generateMipmaps = false;
+ this.flipY = false;
+ this.unpackAlignment = 1;
+ this.needsUpdate = true;
+ }
+ DataTexture.prototype = Object.create(Texture.prototype);
+ DataTexture.prototype.constructor = DataTexture;
+ DataTexture.prototype.isDataTexture = true;
+ var _sphere$1 = /*@__PURE__*/new Sphere();
+ var _vector$5 = /*@__PURE__*/new Vector3();
+ var Frustum = /*#__PURE__*/function () {
+ function Frustum(p0, p1, p2, p3, p4, p5) {
+ this.planes = [p0 !== undefined ? p0 : new Plane(), p1 !== undefined ? p1 : new Plane(), p2 !== undefined ? p2 : new Plane(), p3 !== undefined ? p3 : new Plane(), p4 !== undefined ? p4 : new Plane(), p5 !== undefined ? p5 : new Plane()];
+ }
+ var _proto = Frustum.prototype;
+ _proto.set = function set(p0, p1, p2, p3, p4, p5) {
+ var planes = this.planes;
+ planes[0].copy(p0);
+ planes[1].copy(p1);
+ planes[2].copy(p2);
+ planes[3].copy(p3);
+ planes[4].copy(p4);
+ planes[5].copy(p5);
+ return this;
+ };
+ _proto.clone = function clone() {
+ return new this.constructor().copy(this);
+ };
+ _proto.copy = function copy(frustum) {
+ var planes = this.planes;
+ for (var i = 0; i < 6; i++) {
+ planes[i].copy(frustum.planes[i]);
+ }
+ return this;
+ };
+ _proto.setFromProjectionMatrix = function setFromProjectionMatrix(m) {
+ var planes = this.planes;
+ var me = m.elements;
+ var me0 = me[0],
+ me1 = me[1],
+ me2 = me[2],
+ me3 = me[3];
+ var me4 = me[4],
+ me5 = me[5],
+ me6 = me[6],
+ me7 = me[7];
+ var me8 = me[8],
+ me9 = me[9],
+ me10 = me[10],
+ me11 = me[11];
+ var me12 = me[12],
+ me13 = me[13],
+ me14 = me[14],
+ me15 = me[15];
+ planes[0].setComponents(me3 - me0, me7 - me4, me11 - me8, me15 - me12).normalize();
+ planes[1].setComponents(me3 + me0, me7 + me4, me11 + me8, me15 + me12).normalize();
+ planes[2].setComponents(me3 + me1, me7 + me5, me11 + me9, me15 + me13).normalize();
+ planes[3].setComponents(me3 - me1, me7 - me5, me11 - me9, me15 - me13).normalize();
+ planes[4].setComponents(me3 - me2, me7 - me6, me11 - me10, me15 - me14).normalize();
+ planes[5].setComponents(me3 + me2, me7 + me6, me11 + me10, me15 + me14).normalize();
+ return this;
+ };
+ _proto.intersectsObject = function intersectsObject(object) {
+ var geometry = object.geometry;
+ if (geometry.boundingSphere === null) geometry.computeBoundingSphere();
+ _sphere$1.copy(geometry.boundingSphere).applyMatrix4(object.matrixWorld);
+ return this.intersectsSphere(_sphere$1);
+ };
+ _proto.intersectsSprite = function intersectsSprite(sprite) {
+ _sphere$1.center.set(0, 0, 0);
+ _sphere$1.radius = 0.7071067811865476;
+ _sphere$1.applyMatrix4(sprite.matrixWorld);
+ return this.intersectsSphere(_sphere$1);
+ };
+ _proto.intersectsSphere = function intersectsSphere(sphere) {
+ var planes = this.planes;
+ var center = sphere.center;
+ var negRadius = -sphere.radius;
+ for (var i = 0; i < 6; i++) {
+ var distance = planes[i].distanceToPoint(center);
+ if (distance < negRadius) {
+ return false;
+ }
+ }
+ return true;
+ };
+ _proto.intersectsBox = function intersectsBox(box) {
+ var planes = this.planes;
+ for (var i = 0; i < 6; i++) {
+ var plane = planes[i]; // corner at max distance
+ _vector$5.x = plane.normal.x > 0 ? box.max.x : box.min.x;
+ _vector$5.y = plane.normal.y > 0 ? box.max.y : box.min.y;
+ _vector$5.z = plane.normal.z > 0 ? box.max.z : box.min.z;
+ if (plane.distanceToPoint(_vector$5) < 0) {
+ return false;
+ }
+ }
+ return true;
+ };
+ _proto.containsPoint = function containsPoint(point) {
+ var planes = this.planes;
+ for (var i = 0; i < 6; i++) {
+ if (planes[i].distanceToPoint(point) < 0) {
+ return false;
+ }
+ }
+ return true;
+ };
+ return Frustum;
+ }();
+ function WebGLAnimation() {
+ var context = null;
+ var isAnimating = false;
+ var animationLoop = null;
+ var requestId = null;
+ function onAnimationFrame(time, frame) {
+ animationLoop(time, frame);
+ requestId = context.requestAnimationFrame(onAnimationFrame);
+ }
+ return {
+ start: function start() {
+ if (isAnimating === true) return;
+ if (animationLoop === null) return;
+ requestId = context.requestAnimationFrame(onAnimationFrame);
+ isAnimating = true;
+ },
+ stop: function stop() {
+ context.cancelAnimationFrame(requestId);
+ isAnimating = false;
+ },
+ setAnimationLoop: function setAnimationLoop(callback) {
+ animationLoop = callback;
+ },
+ setContext: function setContext(value) {
+ context = value;
+ }
+ };
+ }
+ function WebGLAttributes(gl, capabilities) {
+ var isWebGL2 = capabilities.isWebGL2;
+ var buffers = new WeakMap();
+ function createBuffer(attribute, bufferType) {
+ var array = attribute.array;
+ var usage = attribute.usage;
+ var buffer = gl.createBuffer();
+ gl.bindBuffer(bufferType, buffer);
+ gl.bufferData(bufferType, array, usage);
+ attribute.onUploadCallback();
+ var type = 5126;
+ if (array instanceof Float32Array) {
+ type = 5126;
+ } else if (array instanceof Float64Array) {
+ console.warn('THREE.WebGLAttributes: Unsupported data buffer format: Float64Array.');
+ } else if (array instanceof Uint16Array) {
+ if (attribute.isFloat16BufferAttribute) {
+ if (isWebGL2) {
+ type = 5131;
+ } else {
+ console.warn('THREE.WebGLAttributes: Usage of Float16BufferAttribute requires WebGL2.');
+ }
+ } else {
+ type = 5123;
+ }
+ } else if (array instanceof Int16Array) {
+ type = 5122;
+ } else if (array instanceof Uint32Array) {
+ type = 5125;
+ } else if (array instanceof Int32Array) {
+ type = 5124;
+ } else if (array instanceof Int8Array) {
+ type = 5120;
+ } else if (array instanceof Uint8Array) {
+ type = 5121;
+ }
+ return {
+ buffer: buffer,
+ type: type,
+ bytesPerElement: array.BYTES_PER_ELEMENT,
+ version: attribute.version
+ };
+ }
+ function updateBuffer(buffer, attribute, bufferType) {
+ var array = attribute.array;
+ var updateRange = attribute.updateRange;
+ gl.bindBuffer(bufferType, buffer);
+ if (updateRange.count === -1) {
+ // Not using update ranges
+ gl.bufferSubData(bufferType, 0, array);
+ } else {
+ if (isWebGL2) {
+ gl.bufferSubData(bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, array, updateRange.offset, updateRange.count);
+ } else {
+ gl.bufferSubData(bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, array.subarray(updateRange.offset, updateRange.offset + updateRange.count));
+ }
+ updateRange.count = -1; // reset range
+ }
+ } //
+
+ function get(attribute) {
+ if (attribute.isInterleavedBufferAttribute) attribute = attribute.data;
+ return buffers.get(attribute);
+ }
+ function remove(attribute) {
+ if (attribute.isInterleavedBufferAttribute) attribute = attribute.data;
+ var data = buffers.get(attribute);
+ if (data) {
+ gl.deleteBuffer(data.buffer);
+ buffers.delete(attribute);
+ }
+ }
+ function update(attribute, bufferType) {
+ if (attribute.isGLBufferAttribute) {
+ var cached = buffers.get(attribute);
+ if (!cached || cached.version < attribute.version) {
+ buffers.set(attribute, {
+ buffer: attribute.buffer,
+ type: attribute.type,
+ bytesPerElement: attribute.elementSize,
+ version: attribute.version
+ });
+ }
+ return;
+ }
+ if (attribute.isInterleavedBufferAttribute) attribute = attribute.data;
+ var data = buffers.get(attribute);
+ if (data === undefined) {
+ buffers.set(attribute, createBuffer(attribute, bufferType));
+ } else if (data.version < attribute.version) {
+ updateBuffer(data.buffer, attribute, bufferType);
+ data.version = attribute.version;
+ }
+ }
+ return {
+ get: get,
+ remove: remove,
+ update: update
+ };
+ }
+ var PlaneBufferGeometry = /*#__PURE__*/function (_BufferGeometry) {
+ _inheritsLoose(PlaneBufferGeometry, _BufferGeometry);
+ function PlaneBufferGeometry(width, height, widthSegments, heightSegments) {
+ var _this;
+ if (width === void 0) {
+ width = 1;
+ }
+ if (height === void 0) {
+ height = 1;
+ }
+ if (widthSegments === void 0) {
+ widthSegments = 1;
+ }
+ if (heightSegments === void 0) {
+ heightSegments = 1;
+ }
+ _this = _BufferGeometry.call(this) || this;
+ _this.type = 'PlaneBufferGeometry';
+ _this.parameters = {
+ width: width,
+ height: height,
+ widthSegments: widthSegments,
+ heightSegments: heightSegments
+ };
+ var width_half = width / 2;
+ var height_half = height / 2;
+ var gridX = Math.floor(widthSegments);
+ var gridY = Math.floor(heightSegments);
+ var gridX1 = gridX + 1;
+ var gridY1 = gridY + 1;
+ var segment_width = width / gridX;
+ var segment_height = height / gridY; //
+ var indices = [];
+ var vertices = [];
+ var normals = [];
+ var uvs = [];
+ for (var iy = 0; iy < gridY1; iy++) {
+ var y = iy * segment_height - height_half;
+ for (var ix = 0; ix < gridX1; ix++) {
+ var x = ix * segment_width - width_half;
+ vertices.push(x, -y, 0);
+ normals.push(0, 0, 1);
+ uvs.push(ix / gridX);
+ uvs.push(1 - iy / gridY);
+ }
+ }
+ for (var _iy = 0; _iy < gridY; _iy++) {
+ for (var _ix = 0; _ix < gridX; _ix++) {
+ var a = _ix + gridX1 * _iy;
+ var b = _ix + gridX1 * (_iy + 1);
+ var c = _ix + 1 + gridX1 * (_iy + 1);
+ var d = _ix + 1 + gridX1 * _iy;
+ indices.push(a, b, d);
+ indices.push(b, c, d);
+ }
+ }
+ _this.setIndex(indices);
+ _this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
+ _this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
+ _this.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
+ return _this;
+ }
+ return PlaneBufferGeometry;
+ }(BufferGeometry);
+ var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif";
+ var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif";
+ var alphatest_fragment = "#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif";
+ var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( STANDARD )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif";
+ var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif";
+ var begin_vertex = "vec3 transformed = vec3( position );";
+ var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif";
+ var bsdfs = "vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) {\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\treturn vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n#else\n\tif( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t}\n\treturn 1.0;\n#endif\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nvec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV );\n\tvec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0;\n\treturn Fr * fresnel + F0;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + viewDir );\n\tfloat dotNL = saturate( dot( normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\treturn specularColor * brdf.x + brdf.y;\n}\nvoid BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\tvec3 FssEss = F * brdf.x + brdf.y;\n\tfloat Ess = brdf.x + brdf.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie(float roughness, float NoH) {\n\tfloat invAlpha = 1.0 / roughness;\n\tfloat cos2h = NoH * NoH;\n\tfloat sin2h = max(1.0 - cos2h, 0.0078125);\treturn (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * PI);\n}\nfloat V_Neubelt(float NoV, float NoL) {\n\treturn saturate(1.0 / (4.0 * (NoL + NoV - NoL * NoV)));\n}\nvec3 BRDF_Specular_Sheen( const in float roughness, const in vec3 L, const in GeometricContext geometry, vec3 specularColor ) {\n\tvec3 N = geometry.normal;\n\tvec3 V = geometry.viewDir;\n\tvec3 H = normalize( V + L );\n\tfloat dotNH = saturate( dot( N, H ) );\n\treturn specularColor * D_Charlie( roughness, dotNH ) * V_Neubelt( dot(N, V), dot(N, L) );\n}\n#endif";
+ var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tfDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif";
+ var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#pragma unroll_loop_end\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\tif ( clipped ) discard;\n\t#endif\n#endif";
+ var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif";
+ var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n#endif";
+ var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvClipPosition = - mvPosition.xyz;\n#endif";
+ var color_fragment = "#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif";
+ var color_pars_fragment = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif";
+ var color_pars_vertex = "#if defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )\n\tvarying vec3 vColor;\n#endif";
+ var color_vertex = "#if defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )\n\tvColor = vec3( 1.0 );\n#endif\n#ifdef USE_COLOR\n\tvColor.xyz *= color.xyz;\n#endif\n#ifdef USE_INSTANCING_COLOR\n\tvColor.xyz *= instanceColor.xyz;\n#endif";
+ var common = "#define PI 3.141592653589793\n#define PI2 6.283185307179586\n#define PI_HALF 1.5707963267948966\n#define RECIPROCAL_PI 0.3183098861837907\n#define RECIPROCAL_PI2 0.15915494309189535\n#define EPSILON 1e-6\n#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\n#define whiteComplement(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat max3( vec3 v ) { return max( max( v.x, v.y ), v.z ); }\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n#ifdef CLEARCOAT\n\tvec3 clearcoatNormal;\n#endif\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n\treturn m[ 2 ][ 3 ] == - 1.0;\n}\nvec2 equirectUv( in vec3 dir ) {\n\tfloat u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\n\tfloat v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\treturn vec2( u, v );\n}";
+ var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n\t#define cubeUV_maxMipLevel 8.0\n\t#define cubeUV_minMipLevel 4.0\n\t#define cubeUV_maxTileSize 256.0\n\t#define cubeUV_minTileSize 16.0\n\tfloat getFace( vec3 direction ) {\n\t\tvec3 absDirection = abs( direction );\n\t\tfloat face = - 1.0;\n\t\tif ( absDirection.x > absDirection.z ) {\n\t\t\tif ( absDirection.x > absDirection.y )\n\t\t\t\tface = direction.x > 0.0 ? 0.0 : 3.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t} else {\n\t\t\tif ( absDirection.z > absDirection.y )\n\t\t\t\tface = direction.z > 0.0 ? 2.0 : 5.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t}\n\t\treturn face;\n\t}\n\tvec2 getUV( vec3 direction, float face ) {\n\t\tvec2 uv;\n\t\tif ( face == 0.0 ) {\n\t\t\tuv = vec2( direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 1.0 ) {\n\t\t\tuv = vec2( - direction.x, - direction.z ) / abs( direction.y );\n\t\t} else if ( face == 2.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.y ) / abs( direction.z );\n\t\t} else if ( face == 3.0 ) {\n\t\t\tuv = vec2( - direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 4.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.z ) / abs( direction.y );\n\t\t} else {\n\t\t\tuv = vec2( direction.x, direction.y ) / abs( direction.z );\n\t\t}\n\t\treturn 0.5 * ( uv + 1.0 );\n\t}\n\tvec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) {\n\t\tfloat face = getFace( direction );\n\t\tfloat filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 );\n\t\tmipInt = max( mipInt, cubeUV_minMipLevel );\n\t\tfloat faceSize = exp2( mipInt );\n\t\tfloat texelSize = 1.0 / ( 3.0 * cubeUV_maxTileSize );\n\t\tvec2 uv = getUV( direction, face ) * ( faceSize - 1.0 );\n\t\tvec2 f = fract( uv );\n\t\tuv += 0.5 - f;\n\t\tif ( face > 2.0 ) {\n\t\t\tuv.y += faceSize;\n\t\t\tface -= 3.0;\n\t\t}\n\t\tuv.x += face * faceSize;\n\t\tif ( mipInt < cubeUV_maxMipLevel ) {\n\t\t\tuv.y += 2.0 * cubeUV_maxTileSize;\n\t\t}\n\t\tuv.y += filterInt * 2.0 * cubeUV_minTileSize;\n\t\tuv.x += 3.0 * max( 0.0, cubeUV_maxTileSize - 2.0 * faceSize );\n\t\tuv *= texelSize;\n\t\tvec3 tl = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb;\n\t\tuv.x += texelSize;\n\t\tvec3 tr = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb;\n\t\tuv.y += texelSize;\n\t\tvec3 br = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb;\n\t\tuv.x -= texelSize;\n\t\tvec3 bl = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb;\n\t\tvec3 tm = mix( tl, tr, f.x );\n\t\tvec3 bm = mix( bl, br, f.x );\n\t\treturn mix( tm, bm, f.y );\n\t}\n\t#define r0 1.0\n\t#define v0 0.339\n\t#define m0 - 2.0\n\t#define r1 0.8\n\t#define v1 0.276\n\t#define m1 - 1.0\n\t#define r4 0.4\n\t#define v4 0.046\n\t#define m4 2.0\n\t#define r5 0.305\n\t#define v5 0.016\n\t#define m5 3.0\n\t#define r6 0.21\n\t#define v6 0.0038\n\t#define m6 4.0\n\tfloat roughnessToMip( float roughness ) {\n\t\tfloat mip = 0.0;\n\t\tif ( roughness >= r1 ) {\n\t\t\tmip = ( r0 - roughness ) * ( m1 - m0 ) / ( r0 - r1 ) + m0;\n\t\t} else if ( roughness >= r4 ) {\n\t\t\tmip = ( r1 - roughness ) * ( m4 - m1 ) / ( r1 - r4 ) + m1;\n\t\t} else if ( roughness >= r5 ) {\n\t\t\tmip = ( r4 - roughness ) * ( m5 - m4 ) / ( r4 - r5 ) + m4;\n\t\t} else if ( roughness >= r6 ) {\n\t\t\tmip = ( r5 - roughness ) * ( m6 - m5 ) / ( r5 - r6 ) + m5;\n\t\t} else {\n\t\t\tmip = - 2.0 * log2( 1.16 * roughness );\t\t}\n\t\treturn mip;\n\t}\n\tvec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) {\n\t\tfloat mip = clamp( roughnessToMip( roughness ), m0, cubeUV_maxMipLevel );\n\t\tfloat mipF = fract( mip );\n\t\tfloat mipInt = floor( mip );\n\t\tvec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt );\n\t\tif ( mipF == 0.0 ) {\n\t\t\treturn vec4( color0, 1.0 );\n\t\t} else {\n\t\t\tvec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 );\n\t\t\treturn vec4( mix( color0, color1, mipF ), 1.0 );\n\t\t}\n\t}\n#endif";
+ var defaultnormal_vertex = "vec3 transformedNormal = objectNormal;\n#ifdef USE_INSTANCING\n\tmat3 m = mat3( instanceMatrix );\n\ttransformedNormal /= vec3( dot( m[ 0 ], m[ 0 ] ), dot( m[ 1 ], m[ 1 ] ), dot( m[ 2 ], m[ 2 ] ) );\n\ttransformedNormal = m * transformedNormal;\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = ( modelViewMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif";
+ var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif";
+ var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );\n#endif";
+ var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif";
+ var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif";
+ var encodings_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );";
+ var encodings_pars_fragment = "\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * value.a * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = clamp( floor( D ) / 255.0, 0.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value ) {\n\tvec3 Xp_Y_XYZp = cLogLuvM * value.rgb;\n\tXp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract( Le );\n\tvResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;\n\treturn vec4( max( vRGB, 0.0 ), 1.0 );\n}";
+ var envmap_fragment = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToFrag;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToFrag = normalize( vWorldPosition - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToFrag, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec4 envColor = textureCubeUV( envMap, reflectVec, 0.0 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\t#ifndef ENVMAP_TYPE_CUBE_UV\n\t\tenvColor = envMapTexelToLinear( envColor );\n\t#endif\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif";
+ var envmap_common_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\t\n#endif";
+ var envmap_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\tvarying vec3 vWorldPosition;\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif";
+ var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) ||defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\t\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif";
+ var envmap_vertex = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif";
+ var fog_vertex = "#ifdef USE_FOG\n\tfogDepth = - mvPosition.z;\n#endif";
+ var fog_pars_vertex = "#ifdef USE_FOG\n\tvarying float fogDepth;\n#endif";
+ var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * fogDepth * fogDepth );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif";
+ var fog_pars_fragment = "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif";
+ var gradientmap_pars_fragment = "#ifdef USE_GRADIENTMAP\n\tuniform sampler2D gradientMap;\n#endif\nvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\tfloat dotNL = dot( normal, lightDirection );\n\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t#ifdef USE_GRADIENTMAP\n\t\treturn texture2D( gradientMap, coord ).rgb;\n\t#else\n\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t#endif\n}";
+ var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\treflectedLight.indirectDiffuse += PI * lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n#endif";
+ var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif";
+ var lights_lambert_vertex = "vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\nvIndirectFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n\tvIndirectBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\nvIndirectFront += getAmbientLightIrradiance( ambientLightColor );\nvIndirectFront += getLightProbeIrradiance( lightProbe, geometry );\n#ifdef DOUBLE_SIDED\n\tvIndirectBack += getAmbientLightIrradiance( ambientLightColor );\n\tvIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry );\n#endif\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif";
+ var lights_pars_begin = "uniform bool receiveShadow;\nuniform vec3 ambientLightColor;\nuniform vec3 lightProbe[ 9 ];\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in GeometricContext geometry ) {\n\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif";
+ var envmap_physical_pars_fragment = "#if defined( USE_ENVMAP )\n\t#ifdef ENVMAP_MODE_REFRACTION\n\t\tuniform float refractionRatio;\n\t#endif\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, worldNormal, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float roughness, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat sigma = PI * roughness * roughness / ( 1.0 + roughness );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + log2( sigma );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( -viewDir, normal );\n\t\t\treflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( -viewDir, normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( roughness, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness );\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif";
+ var lights_toon_fragment = "ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;";
+ var lights_toon_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct ToonMaterial {\n\tvec3 diffuseColor;\n};\nvoid RE_Direct_Toon( const in IncidentLight directLight, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Toon\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Toon\n#define Material_LightProbeLOD( material )\t(0)";
+ var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;";
+ var lights_phong_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3 diffuseColor;\n\tvec3 specularColor;\n\tfloat specularShininess;\n\tfloat specularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)";
+ var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nvec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );\nfloat geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );\nmaterial.specularRoughness = max( roughnessFactor, 0.0525 );material.specularRoughness += geometryRoughness;\nmaterial.specularRoughness = min( material.specularRoughness, 1.0 );\n#ifdef REFLECTIVITY\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#endif\n#ifdef CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\t#ifdef USE_CLEARCOATMAP\n\t\tmaterial.clearcoat *= texture2D( clearcoatMap, vUv ).x;\n\t#endif\n\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\t\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vUv ).y;\n\t#endif\n\tmaterial.clearcoat = saturate( material.clearcoat );\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n\tmaterial.clearcoatRoughness += geometryRoughness;\n\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheen;\n#endif";
+ var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tfloat specularRoughness;\n\tvec3 specularColor;\n#ifdef CLEARCOAT\n\tfloat clearcoat;\n\tfloat clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tvec3 sheenColor;\n#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearcoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNL = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = ccDotNL * directLight.color;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tccIrradiance *= PI;\n\t\t#endif\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t\treflectedLight.directSpecular += ccIrradiance * material.clearcoat * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_Sheen(\n\t\t\tmaterial.specularRoughness,\n\t\t\tdirectLight.direction,\n\t\t\tgeometry,\n\t\t\tmaterial.sheenColor\n\t\t);\n\t#else\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.normal, material.specularColor, material.specularRoughness);\n\t#endif\n\treflectedLight.directDiffuse += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNV = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * BRDF_Specular_GGX_Environment( geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t\tfloat ccDotNL = ccDotNV;\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\tfloat clearcoatInv = 1.0 - clearcoatDHR;\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\tBRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering );\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\n\treflectedLight.indirectSpecular += clearcoatInv * radiance * singleScattering;\n\treflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;\n\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}";
+ var lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n#ifdef CLEARCOAT\n\tgeometry.clearcoatNormal = clearcoatNormal;\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tspotLightShadow = spotLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 iblIrradiance = vec3( 0.0 );\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\tirradiance += getLightProbeIrradiance( lightProbe, geometry );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif";
+ var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\t\tvec3 lightMapIrradiance = lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.normal, material.specularRoughness, maxMipLevel );\n\t#ifdef CLEARCOAT\n\t\tclearcoatRadiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness, maxMipLevel );\n\t#endif\n#endif";
+ var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight );\n#endif";
+ var logdepthbuf_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif";
+ var logdepthbuf_pars_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif";
+ var logdepthbuf_pars_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t\tvarying float vIsPerspective;\n\t#else\n\t\tuniform float logDepthBufFC;\n\t#endif\n#endif";
+ var logdepthbuf_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t\tvIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\n\t#else\n\t\tif ( isPerspectiveMatrix( projectionMatrix ) ) {\n\t\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\t\tgl_Position.z *= gl_Position.w;\n\t\t}\n\t#endif\n#endif";
+ var map_fragment = "#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif";
+ var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif";
+ var map_particle_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n#endif\n#ifdef USE_MAP\n\tvec4 mapTexel = texture2D( map, uv );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif\n#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, uv ).g;\n#endif";
+ var map_particle_pars_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tuniform mat3 uvTransform;\n#endif\n#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif";
+ var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif";
+ var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif";
+ var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n\tobjectNormal *= morphTargetBaseInfluence;\n\tobjectNormal += morphNormal0 * morphTargetInfluences[ 0 ];\n\tobjectNormal += morphNormal1 * morphTargetInfluences[ 1 ];\n\tobjectNormal += morphNormal2 * morphTargetInfluences[ 2 ];\n\tobjectNormal += morphNormal3 * morphTargetInfluences[ 3 ];\n#endif";
+ var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\tuniform float morphTargetBaseInfluence;\n\t#ifndef USE_MORPHNORMALS\n\t\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\t\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif";
+ var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\ttransformed += morphTarget0 * morphTargetInfluences[ 0 ];\n\ttransformed += morphTarget1 * morphTargetInfluences[ 1 ];\n\ttransformed += morphTarget2 * morphTargetInfluences[ 2 ];\n\ttransformed += morphTarget3 * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\t\ttransformed += morphTarget4 * morphTargetInfluences[ 4 ];\n\t\ttransformed += morphTarget5 * morphTargetInfluences[ 5 ];\n\t\ttransformed += morphTarget6 * morphTargetInfluences[ 6 ];\n\t\ttransformed += morphTarget7 * morphTargetInfluences[ 7 ];\n\t#endif\n#endif";
+ var normal_fragment_begin = "#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\t#ifdef USE_TANGENT\n\t\tvec3 tangent = normalize( vTangent );\n\t\tvec3 bitangent = normalize( vBitangent );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\ttangent = tangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\tbitangent = bitangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\t#if defined( TANGENTSPACE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP )\n\t\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\n\t\t#endif\n\t#endif\n#endif\nvec3 geometryNormal = normal;";
+ var normal_fragment_maps = "#ifdef OBJECTSPACE_NORMALMAP\n\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t#ifdef FLIP_SIDED\n\t\tnormal = - normal;\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\tnormal = normalize( normalMatrix * normal );\n#elif defined( TANGENTSPACE_NORMALMAP )\n\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\tmapN.xy *= normalScale;\n\t#ifdef USE_TANGENT\n\t\tnormal = normalize( vTBN * mapN );\n\t#else\n\t\tnormal = perturbNormal2Arb( -vViewPosition, normal, mapN );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif";
+ var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 mapN ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\tvec3 N = normalize( surf_norm );\n\t\tmat3 tsn = mat3( S, T, N );\n\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif";
+ var clearcoat_normal_fragment_begin = "#ifdef CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif";
+ var clearcoat_normal_fragment_maps = "#ifdef USE_CLEARCOAT_NORMALMAP\n\tvec3 clearcoatMapN = texture2D( clearcoatNormalMap, vUv ).xyz * 2.0 - 1.0;\n\tclearcoatMapN.xy *= clearcoatNormalScale;\n\t#ifdef USE_TANGENT\n\t\tclearcoatNormal = normalize( vTBN * clearcoatMapN );\n\t#else\n\t\tclearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatMapN );\n\t#endif\n#endif";
+ var clearcoat_pars_fragment = "#ifdef USE_CLEARCOATMAP\n\tuniform sampler2D clearcoatMap;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform sampler2D clearcoatRoughnessMap;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearcoatNormalMap;\n\tuniform vec2 clearcoatNormalScale;\n#endif";
+ var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nvec4 pack2HalfToRGBA( vec2 v ) {\n\tvec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ));\n\treturn vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w);\n}\nvec2 unpackRGBATo2Half( vec4 v ) {\n\treturn vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}";
+ var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif";
+ var project_vertex = "vec4 mvPosition = vec4( transformed, 1.0 );\n#ifdef USE_INSTANCING\n\tmvPosition = instanceMatrix * mvPosition;\n#endif\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;";
+ var dithering_fragment = "#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif";
+ var dithering_pars_fragment = "#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif";
+ var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif";
+ var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif";
+ var shadowmap_pars_fragment = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tvec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {\n\t\treturn unpackRGBATo2Half( texture2D( shadow, uv ) );\n\t}\n\tfloat VSMShadow (sampler2D shadow, vec2 uv, float compare ){\n\t\tfloat occlusion = 1.0;\n\t\tvec2 distribution = texture2DDistribution( shadow, uv );\n\t\tfloat hard_shadow = step( compare , distribution.x );\n\t\tif (hard_shadow != 1.0 ) {\n\t\t\tfloat distance = compare - distribution.x ;\n\t\t\tfloat variance = max( 0.00000, distribution.y * distribution.y );\n\t\t\tfloat softness_probability = variance / (variance + distance * distance );\t\t\tsoftness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 );\t\t\tocclusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );\n\t\t}\n\t\treturn occlusion;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx = texelSize.x;\n\t\t\tfloat dy = texelSize.y;\n\t\t\tvec2 uv = shadowCoord.xy;\n\t\t\tvec2 f = fract( uv * shadowMapSize + 0.5 );\n\t\t\tuv -= f * texelSize;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, uv, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ), \n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ), \n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t f.y )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_VSM )\n\t\t\tshadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif";
+ var shadowmap_pars_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n#endif";
+ var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0 || NUM_SPOT_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0\n\t\tvec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\tvec4 shadowWorldPosition;\n\t#endif\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias, 0 );\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n#endif";
+ var shadowmask_pars_fragment = "float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#endif\n\treturn shadow;\n}";
+ var skinbase_vertex = "#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif";
+ var skinning_pars_vertex = "#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform highp sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif";
+ var skinning_vertex = "#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif";
+ var skinnormal_vertex = "#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif";
+ var specularmap_fragment = "float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif";
+ var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif";
+ var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif";
+ var tonemapping_pars_fragment = "#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 RRTAndODTFit( vec3 v ) {\n\tvec3 a = v * ( v + 0.0245786 ) - 0.000090537;\n\tvec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;\n\treturn a / b;\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tconst mat3 ACESInputMat = mat3(\n\t\tvec3( 0.59719, 0.07600, 0.02840 ),\t\tvec3( 0.35458, 0.90834, 0.13383 ),\n\t\tvec3( 0.04823, 0.01566, 0.83777 )\n\t);\n\tconst mat3 ACESOutputMat = mat3(\n\t\tvec3( 1.60475, -0.10208, -0.00327 ),\t\tvec3( -0.53108, 1.10813, -0.07276 ),\n\t\tvec3( -0.07367, -0.00605, 1.07602 )\n\t);\n\tcolor *= toneMappingExposure / 0.6;\n\tcolor = ACESInputMat * color;\n\tcolor = RRTAndODTFit( color );\n\tcolor = ACESOutputMat * color;\n\treturn saturate( color );\n}\nvec3 CustomToneMapping( vec3 color ) { return color; }";
+ var transmissionmap_fragment = "#ifdef USE_TRANSMISSIONMAP\n\ttotalTransmission *= texture2D( transmissionMap, vUv ).r;\n#endif";
+ var transmissionmap_pars_fragment = "#ifdef USE_TRANSMISSIONMAP\n\tuniform sampler2D transmissionMap;\n#endif";
+ var uv_pars_fragment = "#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\n\tvarying vec2 vUv;\n#endif";
+ var uv_pars_vertex = "#ifdef USE_UV\n\t#ifdef UVS_VERTEX_ONLY\n\t\tvec2 vUv;\n\t#else\n\t\tvarying vec2 vUv;\n\t#endif\n\tuniform mat3 uvTransform;\n#endif";
+ var uv_vertex = "#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif";
+ var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif";
+ var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n\tuniform mat3 uv2Transform;\n#endif";
+ var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\n#endif";
+ var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = vec4( transformed, 1.0 );\n\t#ifdef USE_INSTANCING\n\t\tworldPosition = instanceMatrix * worldPosition;\n\t#endif\n\tworldPosition = modelMatrix * worldPosition;\n#endif";
+ var background_frag = "uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}";
+ var background_vert = "varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}";
+ var cube_frag = "#include \nuniform float opacity;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvec3 vReflect = vWorldDirection;\n\t#include \n\tgl_FragColor = envColor;\n\tgl_FragColor.a *= opacity;\n\t#include \n\t#include \n}";
+ var cube_vert = "varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}";
+ var depth_frag = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( fragCoordZ );\n\t#endif\n}";
+ var depth_vert = "#include \n#include \n#include \n#include \n#include \n#include \n#include \nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvHighPrecisionZW = gl_Position.zw;\n}";
+ var distanceRGBA_frag = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main () {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include \n\t#include \n\t#include \n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}";
+ var distanceRGBA_vert = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvWorldPosition = worldPosition.xyz;\n}";
+ var equirect_frag = "uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV = equirectUv( direction );\n\tvec4 texColor = texture2D( tEquirect, sampleUV );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}";
+ var equirect_vert = "varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}";
+ var linedashed_frag = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}";
+ var linedashed_vert = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvLineDistance = scale * lineDistance;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}";
+ var meshbasic_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\n\t\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\t\treflectedLight.indirectDiffuse += lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}";
+ var meshbasic_vert = "#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_ENVMAP\n\t#include \n\t#include \n\t#include \n\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}";
+ var meshlambert_frag = "uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;\n\t#else\n\t\treflectedLight.indirectDiffuse += vIndirectFront;\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}";
+ var meshlambert_vert = "#define LAMBERT\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include