index.html 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>四维全真漫游</title>
  8. <!-- <link rel="stylesheet" href="./index.css" /> -->
  9. <link rel="stylesheet" href="./css/toastify.min.css" />
  10. <style>
  11. .loading {
  12. position: absolute;
  13. width: 100%;
  14. height: 100%;
  15. background: #fff url("./assets/loading.gif") center;
  16. background-repeat: no-repeat;
  17. background-size: 600px 600px;
  18. }
  19. .tip {
  20. position: absolute;
  21. top: 2rem;
  22. left: 50%;
  23. transform: translateX(-50%);
  24. padding: 1rem 1.6rem;
  25. background-color: #5bc1d1;
  26. color: white;
  27. z-index: 9999;
  28. border-radius: 0.2rem;
  29. opacity: 1;
  30. transition: opacity .2s;
  31. }
  32. </style>
  33. </head>
  34. <body>
  35. <!-- Babylon.js -->
  36. <script src="./libs/jquery-1.10.2.min.js"></script>
  37. <script src="./libs/dat.gui.min.js"></script>
  38. <script src="./libs/ammo.js"></script>
  39. <script src="./libs/cannon.js"></script>
  40. <script src="./libs/Oimo.js"></script>
  41. <script src="./libs/earcut.min.js"></script>
  42. <script src="./libs/recast.js"></script>
  43. <script src="./libs/babylon.js"></script>
  44. <script src="./libs/babylonjs.materials.min.js"></script>
  45. <script src="./libs/babylonjs.proceduralTextures.min.js"></script>
  46. <script src="./libs/babylonjs.postProcess.min.js"></script>
  47. <script src="./libs/babylonjs.loaders.js"></script>
  48. <script src="./libs/babylonjs.serializers.min.js"></script>
  49. <script src="./libs/babylon.gui.min.js"></script>
  50. <script src="./libs/babylon.inspector.bundle.js"></script>
  51. <script src="./libs/socket.2.3.js"></script>
  52. <script src="./libs/events.js"></script>
  53. <script src="./libs/axios.min.js"></script>
  54. <script src="./libs/VisibilityChangeHandler.js"></script>
  55. <script src="./libs/decoder.js"></script>
  56. <script src="./libs/nipplejs.min.js"></script>
  57. <script src="./shader.js"></script>
  58. <script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
  59. <!-- <script src="./webrtc//adapter-7.4.0.min.js"></script>
  60. <script src="./webrtc/srs.sdk.js"></script> -->
  61. <link rel="stylesheet" href="./css/index.cb1a6e05.css" />
  62. <script>
  63. // var vConsole = new window.VConsole();
  64. const SERVER_URLS = {
  65. DEV: "wss://sit-eks.xverse.cn/ws",
  66. PROD: "wss://eks.xverse.cn/ws"
  67. }
  68. , REPORT_URL = {
  69. DEV: "https://xa.xverse.cn:6680/collect1",
  70. PROD: "https://xa.xverse.cn/collect1"
  71. }
  72. , MAX_RECONNECT_COUNT = 3
  73. , DEFAULT_JOINROOM_TIMEOUT = 5e4
  74. , DEFAULT_MAIN_CAMERA_FOV = 50
  75. , DEFAULT_AVATAR_SCALE = 1
  76. , REPORT_NUM_PER_REQUEST = 20
  77. , DEFAULT_OPEN_TIMEOUT_MS = 6e3
  78. , WS_CLOSE_NORMAL = 1e3
  79. , WS_CLOSE_RECONNECT = 3008
  80. , PING_INTERVAL_MS = 1e3
  81. , TEXTURE_URL = "https://static.xverse.cn/qqktv/texture.png"
  82. , REPORT_MODULE_TYPE = "xverse-js"
  83. , authenticationErrorCodes = [3001, 3002, 3003, 3005]
  84. , RTT_MAX_VALUE = 200
  85. , HB_MAX_VALUE = 500
  86. , DURATION = 10
  87. , NET_INTERVAL = 1;
  88. const VERSION$1 = "1.0.75"
  89. , ENV = "production";
  90. const COMPONENT_LIST_PREFIX = "/component_list.json";
  91. const debugMode = location.href.indexOf("debug") > -1 // true
  92. if(debugMode){
  93. var vConsole = new window.VConsole();
  94. }
  95. // 角色相关设置
  96. const avatarSetting = {
  97. fileType: ".glb",
  98. lodType: "_lod",
  99. lod: [{
  100. level: "lod0",
  101. fileName: ".glb",
  102. quota: 5,
  103. dist: 1e3
  104. }, {
  105. level: "lod1",
  106. fileName: "_lod2.glb",
  107. quota: 5,
  108. dist: 2e3
  109. }, {
  110. level: "lod2",
  111. fileName: "_lod4.glb",
  112. quota: 0,
  113. dist: 7500
  114. }],
  115. isRayCastEnable: !0,
  116. maxAvatarNum: 40, // 角色数量上限
  117. maxBillBoardDist: 7500,
  118. body: "body",
  119. head: "head",
  120. hair: "hair",
  121. suit: "suit",
  122. pants: "pants",
  123. shoes: "shoes",
  124. clothes: "clothes",
  125. animations: "animations",
  126. defaultIdle: "Idle",
  127. cullingDistance: 200,
  128. defaultMove: "Walking"
  129. }
  130. , avatarResources = {
  131. ygb: {
  132. name: "ygb",
  133. mat: "NM_ygb",
  134. mesh: "ygb"
  135. }
  136. }
  137. , action = {
  138. GiftClap: {
  139. animName: "GiftClap",
  140. keyTime: 1760
  141. },
  142. Cheering: {
  143. animName: "Cheering",
  144. attachPair: [{
  145. bone: "mixamorig_MiddleFinger2_R",
  146. obj: "ygb",
  147. offset: {
  148. x: 0,
  149. y: 0,
  150. z: 0
  151. },
  152. rotate: {
  153. x: 0,
  154. y: 3.84,
  155. z: 0
  156. },
  157. scale: {
  158. x: 1,
  159. y: 1,
  160. z: 1
  161. }
  162. }, {
  163. bone: "mixamorig_MiddleFinger2_L",
  164. obj: "ygb",
  165. offset: {
  166. x: 0,
  167. y: 0,
  168. z: 0
  169. },
  170. rotate: {
  171. x: 0,
  172. y: 3.49,
  173. z: 0
  174. },
  175. scale: {
  176. x: 1,
  177. y: 1,
  178. z: 1
  179. }
  180. }]
  181. }
  182. }
  183. const WASM_Version = "h264"
  184. , DECODER_VERSION = "v0.9.3"
  185. , WASM_URLS = {
  186. h264: "https://metaverse.4dage.com/wasm/lib_ff264dec_no_idb_with_wasm_tbundle.js",
  187. xv265: "https://metaverse.4dage.com/wasm/libxv265dec.js",
  188. h265: ""
  189. }
  190. , STUCK_STAGE_GOOD = 45
  191. , STUCK_STAGE_WELL = 85
  192. , STUCK_STAGE_FAIR = 125
  193. , STUCK_STAGE_BAD = 165
  194. , DECODER_PASSIVE_JITTER = 0;
  195. /**
  196. * 公共方法
  197. **/
  198. const isFunction = i=>typeof i == "function";
  199. const isSuit = i=>i === "suit"
  200. // 随机获取数组内某一元素,或字符串内某一字符
  201. const getRandomItem = (i) =>i.length === 0 ? null : i[Math.floor(Math.random() * i.length)]
  202. const getAnimationKey = (i,e)=>e + "_" + i
  203. const blobToDataURI = async i=>new Promise((e,t)=>{
  204. const r = new FileReader;
  205. r.readAsDataURL(i),
  206. r.onload = function(n) {
  207. var o;
  208. e((o = n.target) == null ? void 0 : o.result)
  209. }
  210. ,
  211. r.onerror = function(n) {
  212. t(n)
  213. }
  214. });
  215. // 系统检测
  216. const checkOS = ()=>{
  217. const i = navigator.userAgent
  218. , e = /(?:Windows Phone)/.test(i)
  219. , t = /(?:SymbianOS)/.test(i) || e
  220. , r = /(?:Android)/.test(i)
  221. , n = /(?:Firefox)/.test(i);
  222. /(?:Chrome|CriOS)/.test(i);
  223. const o = /(?:iPad|PlayBook)/.test(i) || r && !/(?:Mobile)/.test(i) || n && /(?:Tablet)/.test(i)
  224. , a = /(?:iPhone|ipad|ipod)/.test(i) && !o
  225. , s = !a && !r && !t;
  226. return {
  227. isTablet: o,
  228. isPhone: a,
  229. isIOS: /iPhone|iPod|iPad/.test(navigator.userAgent),
  230. isAndroid: r,
  231. isPc: s
  232. }
  233. }
  234. var De = Object.defineProperty
  235. , Ne = Object.defineProperties;
  236. var we = Object.getOwnPropertyDescriptors;
  237. var be = Object.getOwnPropertySymbols;
  238. var Me = Object.prototype.hasOwnProperty
  239. , Ie = Object.prototype.propertyIsEnumerable;
  240. var Se = (obj, key, value) =>
  241. key in obj ? Object.defineProperty(obj, key, {
  242. enumerable: true,
  243. configurable: true,
  244. writable: true,
  245. value: value
  246. }) : obj[key] = value
  247. , oe = (obj, propsObj)=>{
  248. for (var t in propsObj || (propsObj = {}))
  249. Me.call(propsObj, t) && Se(obj, t, propsObj[t]);
  250. if (Object.getOwnPropertySymbols) {
  251. for (var t of Object.getOwnPropertySymbols(propsObj))
  252. Ie.call(propsObj, t) && Se(obj, t, propsObj[t]);
  253. }
  254. return obj
  255. }
  256. // 将propsObj的所有属性拷贝到obj
  257. , le = (obj, propsObj) => Object.defineProperties(obj, Object.getOwnPropertyDescriptors(propsObj));
  258. var Oe = (i,e)=>{
  259. var t = {};
  260. for (var r in i)
  261. Me.call(i, r) && e.indexOf(r) < 0 && (t[r] = i[r]);
  262. if (i != null && be)
  263. for (var r of be(i))
  264. e.indexOf(r) < 0 && Ie.call(i, r) && (t[r] = i[r]);
  265. return t
  266. };
  267. var E = (i,e,t)=>(Se(i, typeof e != "symbol" ? e + "" : e, t),t);
  268. // 自定义Promise超时
  269. Promise.prototype._timeout = function(timeLimit, e) {
  270. let handle;
  271. return new Promise((resolve, reject) => (
  272. handle = window.setTimeout(()=>{
  273. reject(e)
  274. }, timeLimit),
  275. this.then(
  276. o=>{
  277. clearTimeout(handle),
  278. resolve(o)
  279. },
  280. o=>{
  281. clearTimeout(handle),
  282. reject(o)
  283. }
  284. )
  285. ))
  286. };
  287. function toast(i, e) {
  288. const {onClick: t, duration: r} = e || {};
  289. // return window.Toastify({
  290. return (new Toastify({
  291. text: i,
  292. duration: r || 3e3,
  293. position: "center",
  294. onClick: function() {
  295. t && t()
  296. }
  297. })).showToast()
  298. // }).showToast()
  299. }
  300. class Toastify {
  301. constructor(options) {
  302. this.text = options.text
  303. this.duration = options.duration
  304. this.onClick = options.onClick
  305. }
  306. showToast() {
  307. setTimeout(() => {
  308. let res = confirm(this.text)
  309. if(res) {
  310. this.onClick()
  311. }
  312. }, this.duration)
  313. return this
  314. }
  315. hideToast() {
  316. return this
  317. }
  318. }
  319. // 将原json里的值全部转成float,并返回一个新json
  320. const objectParseFloat = (i) => {
  321. const e = {};
  322. i && Object.keys(i).forEach((t) => {
  323. e[t] = parseFloat(i[t]);
  324. })
  325. return e;
  326. }
  327. const safelyJsonParse = i=> {
  328. let e = {};
  329. try {
  330. e = JSON.parse(i)
  331. } catch {}
  332. return e
  333. }
  334. const safeParseComponents = i=>{
  335. let e = [];
  336. try {
  337. e = JSON.parse(i || "[]")
  338. } catch {
  339. e = [],
  340. log$2.error(`avatarComponents parse error: ${i}`)
  341. }
  342. return e
  343. }
  344. const safeDecodeURIComponent = i=>{
  345. let e = "";
  346. try {
  347. e = decodeURIComponent(i)
  348. } catch {
  349. e = i
  350. }
  351. return e
  352. }
  353. // 坐标和旋转数值保护,保留2位小数
  354. const positionPrecisionProtect = i=>{
  355. const {x: e, y: t, z: r} = i;
  356. return {
  357. x: +e.toFixed(2),
  358. y: +t.toFixed(2),
  359. z: +r.toFixed(2)
  360. }
  361. }
  362. const rotationPrecisionProtect = i=>{
  363. const {pitch: e, yaw: t, roll: r} = i;
  364. return {
  365. pitch: +e.toFixed(2),
  366. yaw: +t.toFixed(2),
  367. roll: +r.toFixed(2)
  368. }
  369. }
  370. const avatarComponentsModify = (i,e)=>new Promise((t,r)=>{
  371. var l;
  372. let n = [];
  373. const o = []
  374. , a = [];
  375. let s = e.some(u=>isSuit(u.type));
  376. if ((l = i == null ? void 0 : i.components) == null || l.forEach(u=>{
  377. var f;
  378. const c = e.find(d=>d.type === u.type)
  379. , h = c && ((f = i == null ? void 0 : i.components) == null ? void 0 : f.find(d=>d.type === c.type && d.units.some(_=>_.id === c.id))) !== void 0;
  380. if (c)
  381. if (h)
  382. n.push(c);
  383. else {
  384. const d = u.units.find(_=>_.isDefault) || u.units[0];
  385. d ? n.push({
  386. type: u.type,
  387. id: d.id
  388. }) : o.push(`component with type: ${u.type} without default and available unit`)
  389. }
  390. else if (isSuit(u.type)) {
  391. const d = u.units.find(_=>_.isDefault);
  392. d && n.push({
  393. type: u.type,
  394. id: d.id
  395. })
  396. } else {
  397. const d = u.units.find(_=>_.isDefault) || u.units[0];
  398. d ? n.push({
  399. type: u.type,
  400. id: d.id
  401. }) : o.push(`component with type: ${u.type} without default and available unit`)
  402. }
  403. }
  404. ),
  405. s = n.some(u=>isSuit(u.type)),
  406. s) {
  407. const u = i == null ? void 0 : i.components.find(c=>isSuit(c.type));
  408. n = n.filter(c=>(u == null ? void 0 : u.suitComb.indexOf(c.type)) === -1)
  409. }
  410. o.length > 0 && (log$2.error(o.join(", ")),
  411. r(o.join(", "))),
  412. a.length > 0 && log$2.warn(a.join(", ")),
  413. t(n)
  414. })
  415. const avatarComponentsParser = async(i=null,e,t=[])=>new Promise(async(r,n)=>{
  416. var u, c;
  417. if (e.find(h=>isSuit(h.type))) {
  418. const h = (c = (u = i == null ? void 0 : i.components) == null ? void 0 : u.find(f=>isSuit(f.type))) == null ? void 0 : c.suitComb;
  419. e = e.filter(f=>(h == null ? void 0 : h.indexOf(f.type)) === -1)
  420. }
  421. const a = e.filter(h=>!t.some(f=>f.id === h.id));
  422. a.length === 0 && r([]);
  423. const s = [];
  424. a.forEach(async h=>{
  425. var _;
  426. let f = (_ = i == null ? void 0 : i.components) == null ? void 0 : _.find(g=>g.type === h.type);
  427. if (!f) {
  428. const g = `changeComponents, no such component with type: ${h.type}`;
  429. log$2.error(g),
  430. n(g)
  431. }
  432. f = JSON.parse(JSON.stringify(f));
  433. let d = f == null ? void 0 : f.units.find(g=>g.id === h.id);
  434. d || (log$2.warn(`changeComponents, no unit with type: ${h.type}, id: ${h.id}`),
  435. d = f == null ? void 0 : f.units.find(g=>g.isDefault),
  436. !d && log$2.warn(`changeComponents, no default unit with type: ${h.type}`)),
  437. d && s.push({
  438. id: d.id,
  439. url: d.url,
  440. suitComb: (f == null ? void 0 : f.suitComb) || [],
  441. type: h.type
  442. })
  443. });
  444. const l = [];
  445. Promise.all(l).then(h=>{
  446. s.forEach((f,d)=>{
  447. var _, g;
  448. if (!isSuit(f.type)) {
  449. const m = ((g = (_ = i == null ? void 0 : i.components) == null ? void 0 : _.find(v=>isSuit(v.type))) == null ? void 0 : g.suitComb) || [];
  450. m.length > 0 && (m == null ? void 0 : m.indexOf(f.type)) !== -1 && (f.suitComb = ["suit"])
  451. }
  452. f.url = h[d]
  453. }
  454. ),
  455. r(s)
  456. }).catch(h=>{
  457. n(h)
  458. })
  459. })
  460. /**
  461. * 坐标转换相关
  462. **/
  463. // UE4 to Xverse
  464. const ue4Rotation2Xverse = i=>isRotationCorrect() ? (
  465. i.pitch >= 89.5 ? i.pitch = 89.5 : i.pitch <= -89.5 && (i.pitch = -89.5),
  466. new BABYLON.Vector3(-1 * Math.PI * i.pitch / 180,Math.PI * i.yaw / 180 - Math.PI * 27 / 18,Math.PI * i.roll / 180 < .001 ? 0 : Math.PI * i.roll / 180)
  467. ) : null
  468. const ue4Rotation2Xverse_mesh = i=>isRotationCorrect() ? new BABYLON.Vector3(Math.PI * i.pitch / 180,Math.PI * i.yaw / 180,Math.abs(Math.PI * i.roll) / 180 < .001 ? 0 : -1 * (Math.PI * i.roll) / 180) : null
  469. const scaleFromUE4toXverse = 100;
  470. const ue4Scaling2Xverse = i=>isScalingCorrect() ? new BABYLON.Vector3(i.x,i.z,-1 * i.y) : null
  471. const ue4Position2Xverse = i=>isPositionCorrect() ? new BABYLON.Vector3(i.x * .01,i.z * .01,-1 * i.y * .01) : null
  472. // Xverse to Ue4
  473. const xversePosition2Ue4 = i=>isPositionCorrect() ? {
  474. x: i.x * 100,
  475. y: -1 * i.z * 100,
  476. z: i.y * 100
  477. } : null
  478. const xverseRotation2Ue4 = i=>{
  479. if (isPositionCorrect()) {
  480. let e = 0;
  481. return i.z == 0 ? e = 0 : e = 180 * i.z / Math.PI,
  482. {
  483. pitch: 180 * i.x * -1 / Math.PI,
  484. yaw: (i.y + Math.PI * 27 / 18) * 180 / Math.PI,
  485. roll: e
  486. }
  487. } else
  488. return null
  489. }
  490. // 计算两个向量间的距离或角度
  491. const calcDistance3D = (i,e)=>Math.sqrt((i.x - e.x) * (i.x - e.x) + (i.y - e.y) * (i.y - e.y) + (i.z - e.z) * (i.z - e.z))
  492. const calcDistance3DVector = (i,e)=>Math.sqrt((i.x - e.x) * (i.x - e.x) + (i.y - e.y) * (i.y - e.y) + (i.z - e.z) * (i.z - e.z))
  493. const calcDistance3DAngle = (i,e)=>Math.sqrt((i.roll - e.roll) * (i.roll - e.roll) + (i.pitch - e.pitch) * (i.pitch - e.pitch) + (i.yaw - e.yaw) * (i.yaw - e.yaw))
  494. const isPositionCorrect = i=>!0
  495. const isScalingCorrect = i=>!0
  496. const isRotationCorrect = i=>!0
  497. const getStringBoundaries = (i,e,t=new Map)=>{
  498. let r = 0
  499. , n = ""
  500. , o = -1
  501. , a = 0;
  502. const s = [0];
  503. for (let l = 0; l < i.length; l++) {
  504. const u = i.codePointAt(l);
  505. let c = t.get(u);
  506. if (c)
  507. r += c,
  508. n += i[l],
  509. u > 64 && u < 91 || u > 96 && u < 123 ? (o == -1 && (o = l),
  510. a += c) : (o = -1,
  511. a = 0);
  512. else if (u < 975 || u > 1024 && u < 1920)
  513. c = 1,
  514. r++,
  515. n += i[l],
  516. u > 64 && u < 91 || u > 96 && u < 123 ? (o == -1 && (o = l),
  517. a += c) : (o = -1,
  518. a = 0);
  519. else if (u > 4499 && u < 4600 || u > 8207 && u < 8232 || u > 8238 && u < 8287 || u > 8238 && u < 8287 || u > 8304 && u < 8384 || u > 8447 && u < 9211 || u > 11263 && u < 11624 || u > 11646 && u < 11671 || u > 11679 && u < 11845 || u > 11903 && u < 12020 || u > 12031 && u < 12246 || u > 12287 && u < 12544 || u > 12548 && u < 12728 || u > 12735 && u < 12772 || u > 12783 && u < 19894 || u > 19967 && u < 40918 || u > 42191 && u < 42240 || u > 44031 && u < 55204 || u > 59276 && u < 59287 || u > 59412 && u < 59493 || u > 63743 && u < 64207 || u > 65039 && u < 65050 || u > 65071 && u < 65510)
  520. c = 2,
  521. r += 2,
  522. o = -1,
  523. a = 0,
  524. n += i[l];
  525. else if (u > 9311 && u < 11158) {
  526. c = 2,
  527. r += 2,
  528. o = -1,
  529. a = 0,
  530. n += i[l];
  531. const h = i.codePointAt(l + 1);
  532. h > 65023 && h < 65040 && (n += i[l + 1],
  533. l++)
  534. } else
  535. u > 126979 && u < 129783 && (c = 2,
  536. r += 2,
  537. o = -1,
  538. a = 0,
  539. l++,
  540. n += String.fromCodePoint(u));
  541. if (l == s[s.length - 1] + 1 && o > 0 ? (s[s.length - 1] = o,
  542. r = 0 + a) : r > e && (s.push(l),
  543. a >= r && (a = 0 + c,
  544. o = 0),
  545. r = 0 + c),
  546. l >= i.length - 1)
  547. break
  548. }
  549. return s[s.length - 1] != i.length && s.push(i.length),
  550. [n, s]
  551. }
  552. var Observer = function() {
  553. function i(e, t, r) {
  554. r === void 0 && (r = null),
  555. this.callback = e,
  556. this.mask = t,
  557. this.scope = r,
  558. this._willBeUnregistered = !1,
  559. this.unregisterOnNextCall = !1
  560. }
  561. return i
  562. }()
  563. var Observable = function() {
  564. function i(e) {
  565. this._observers = new Array,
  566. this._eventState = new BABYLON.EventState(0),
  567. e && (this._onObserverAdded = e)
  568. }
  569. i.FromPromise = function(e, t) {
  570. var r = new i;
  571. return e.then(function(n) {
  572. r.notifyObservers(n)
  573. }).catch(function(n) {
  574. if (t)
  575. t.notifyObservers(n);
  576. else
  577. throw n
  578. }),
  579. r
  580. }
  581. ,
  582. Object.defineProperty(i.prototype, "observers", {
  583. get: function() {
  584. return this._observers
  585. },
  586. enumerable: !1,
  587. configurable: !0
  588. }),
  589. i.prototype.add = function(e, t, r, n, o) {
  590. if (t === void 0 && (t = -1),
  591. r === void 0 && (r = !1),
  592. n === void 0 && (n = null),
  593. o === void 0 && (o = !1),
  594. !e)
  595. return null;
  596. var a = new Observer(e,t,n);
  597. return a.unregisterOnNextCall = o,
  598. r ? this._observers.unshift(a) : this._observers.push(a),
  599. this._onObserverAdded && this._onObserverAdded(a),
  600. a
  601. }
  602. ,
  603. i.prototype.addOnce = function(e) {
  604. return this.add(e, void 0, void 0, void 0, !0)
  605. }
  606. ,
  607. i.prototype.remove = function(e) {
  608. if (!e)
  609. return !1;
  610. var t = this._observers.indexOf(e);
  611. return t !== -1 ? (this._deferUnregister(e),
  612. !0) : !1
  613. }
  614. ,
  615. i.prototype.removeCallback = function(e, t) {
  616. for (var r = 0; r < this._observers.length; r++) {
  617. var n = this._observers[r];
  618. if (!n._willBeUnregistered && n.callback === e && (!t || t === n.scope))
  619. return this._deferUnregister(n),
  620. !0
  621. }
  622. return !1
  623. }
  624. ,
  625. i.prototype._deferUnregister = function(e) {
  626. var t = this;
  627. e.unregisterOnNextCall = !1,
  628. e._willBeUnregistered = !0,
  629. setTimeout(function() {
  630. t._remove(e)
  631. }, 0)
  632. }
  633. ,
  634. i.prototype._remove = function(e) {
  635. if (!e)
  636. return !1;
  637. var t = this._observers.indexOf(e);
  638. return t !== -1 ? (this._observers.splice(t, 1),
  639. !0) : !1
  640. }
  641. ,
  642. i.prototype.makeObserverTopPriority = function(e) {
  643. this._remove(e),
  644. this._observers.unshift(e)
  645. }
  646. ,
  647. i.prototype.makeObserverBottomPriority = function(e) {
  648. this._remove(e),
  649. this._observers.push(e)
  650. }
  651. ,
  652. i.prototype.notifyObservers = function(e, t, r, n, o) {
  653. if (t === void 0 && (t = -1),
  654. !this._observers.length)
  655. return !0;
  656. var a = this._eventState;
  657. a.mask = t,
  658. a.target = r,
  659. a.currentTarget = n,
  660. a.skipNextObservers = !1,
  661. a.lastReturnValue = e,
  662. a.userInfo = o;
  663. for (var s = 0, l = this._observers; s < l.length; s++) {
  664. var u = l[s];
  665. if (!u._willBeUnregistered && (u.mask & t && (u.scope ? a.lastReturnValue = u.callback.apply(u.scope, [e, a]) : a.lastReturnValue = u.callback(e, a),
  666. u.unregisterOnNextCall && this._deferUnregister(u)),
  667. a.skipNextObservers))
  668. return !1
  669. }
  670. return !0
  671. }
  672. ,
  673. i.prototype.notifyObserversWithPromise = function(e, t, r, n, o) {
  674. var a = this;
  675. t === void 0 && (t = -1);
  676. var s = Promise.resolve(e);
  677. if (!this._observers.length)
  678. return s;
  679. var l = this._eventState;
  680. return l.mask = t,
  681. l.target = r,
  682. l.currentTarget = n,
  683. l.skipNextObservers = !1,
  684. l.userInfo = o,
  685. this._observers.forEach(function(u) {
  686. l.skipNextObservers || u._willBeUnregistered || u.mask & t && (u.scope ? s = s.then(function(c) {
  687. return l.lastReturnValue = c,
  688. u.callback.apply(u.scope, [e, l])
  689. }) : s = s.then(function(c) {
  690. return l.lastReturnValue = c,
  691. u.callback(e, l)
  692. }),
  693. u.unregisterOnNextCall && a._deferUnregister(u))
  694. }),
  695. s.then(function() {
  696. return e
  697. })
  698. }
  699. ,
  700. i.prototype.notifyObserver = function(e, t, r) {
  701. if (r === void 0 && (r = -1),
  702. !e._willBeUnregistered) {
  703. var n = this._eventState;
  704. n.mask = r,
  705. n.skipNextObservers = !1,
  706. e.callback(t, n),
  707. e.unregisterOnNextCall && this._deferUnregister(e)
  708. }
  709. }
  710. ,
  711. i.prototype.hasObservers = function() {
  712. return this._observers.length > 0
  713. }
  714. ,
  715. i.prototype.clear = function() {
  716. this._observers = new Array,
  717. this._onObserverAdded = null
  718. }
  719. ,
  720. i.prototype.clone = function() {
  721. var e = new i;
  722. return e._observers = this._observers.slice(0),
  723. e
  724. }
  725. ,
  726. i.prototype.hasSpecificMask = function(e) {
  727. e === void 0 && (e = -1);
  728. for (var t = 0, r = this._observers; t < r.length; t++) {
  729. var n = r[t];
  730. if (n.mask & e || n.mask === e)
  731. return !0
  732. }
  733. return !1
  734. }
  735. return i
  736. }();
  737. </script>
  738. <div id="root">
  739. <div class="loading" style="z-index: 9999"></div>
  740. <div class = "App">
  741. <canvas id = "canvas" class = "stream unselect">
  742. </canvas>
  743. </div>
  744. <div class="debug_control_btns">
  745. <button class="debugger1">Toggle Stats</button>
  746. <button class="debugger2">取消低模着色</button>
  747. <button class="debugger3">画质:高</button>
  748. <button class="font-size-small debugger4" onclick="room.debug.toggleNearbyBreathPoint">Toggle周边呼吸点</button>
  749. <button class="font-size-small debugger5" onclick="room.debug.toggleTapBreathPoint">Toggle点击呼吸点</button>
  750. <!-- <button class="font-size-small debugger6" >录制码流(10s)</button> -->
  751. <button class="font-size-small debugger7" >开始录制</button>
  752. <button class="font-size-small debugger8" style="display: none; background-color: brown;" >结束录制</button>
  753. </div>
  754. </div>
  755. <script type="module">
  756. document.querySelector('.debugger1').onclick = ()=>{
  757. var y, b;
  758. (y = window.room.stats) != null && y.isShow
  759. ? window.room.stats.hide()
  760. : (b = window.room.stats) == null || b.show();
  761. }
  762. document.querySelector('.debugger2').onclick = ()=>{
  763. window.room.debug.toggleSceneshading() //, r(room.debug.isSceneShading);
  764. }
  765. document.querySelector('.debugger3').onclick = ()=>{
  766. let y = "average";
  767. n === "high"
  768. ? (y = "average")
  769. : n === "average"
  770. ? (y = "low")
  771. : n === "low"
  772. ? (y = "high")
  773. : (y = "average"),
  774. o(y),
  775. window.room.setPictureQualityLevel(y);
  776. }
  777. document.querySelector('.debugger4').onclick = ()=>{
  778. window.room.debug.toggleNearbyBreathPoint();
  779. }
  780. document.querySelector('.debugger5').onclick = ()=>{
  781. window.room.debug.toggleTapBreathPoint();
  782. }
  783. // document.querySelector('.debugger6').onclick = ()=>{
  784. // window.room.debug.dumpStream(() => {
  785. // // toast("\u5F55\u5236\u5B8C\u6210");
  786. // });
  787. // // toast("\u5F00\u59CB\u5F55\u5236");
  788. // }
  789. document.querySelector('.debugger7').onclick = ()=>{
  790. window.startRecord();
  791. document.querySelector('.debugger7').style.display = "none"
  792. document.querySelector('.debugger8').style.display = "block"
  793. }
  794. document.querySelector('.debugger8').onclick = ()=>{
  795. window.stopRecord();
  796. document.querySelector('.debugger7').style.display = "block"
  797. document.querySelector('.debugger8').style.display = "none"
  798. }
  799. // 只在调试时显示control面板
  800. debugMode || (document.querySelector(".debug_control_btns").style.display = "none")
  801. </script>
  802. <script src="js/index.js"></script>
  803. </body>
  804. </html>