index.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. <style src="../../styles/main.css"></style>
  2. <template>
  3. <div>
  4. <div v-if="!isLoaded" ref="loading_a1" id="loading_a1"></div>
  5. <div v-if="!isLoaded" ref="loading" id="loading">正在进入系统中...</div>
  6. <div v-if="reconnect" class="reconnect">网络连接中断,正在进行重连...</div>
  7. <div v-if="loadProgressValue>0 && loadProgressValue<100" class="reconnect">
  8. <div class="loadText">模型加载中...</div>
  9. <div class="loadProgress" :style="{width:loadProgressValue+'%'}"></div>
  10. </div>
  11. <video ref="EngineContent" autoplay muted style="width: 1920px;height:1080px;">浏览器不支持</video>
  12. <Fac v-if="currentTargetType=='FAC'" user-role="index" :fac-model-load-state="facModelLoadState" @markerLClick="facMarkerLClick" @OpenIframeWin="OpenIframeWin"></Fac>
  13. <In02 ref="In02Ele" v-if="currentTargetType=='IN02'" user-role="index" :click-event="In02ClickEvent" :in02-model-load-state="in02modelloadstate" :user-timeout="AutoPlayer" @OpenIframeWin="OpenIframeWin"></In02>
  14. <In03 ref="In03Ele" v-if="currentTargetType=='IN03'" user-role="index" :click-event="In03ClickEvent" :in03-model-load-state="in03modelloadstate" :user-timeout="AutoPlayer" @OpenIframeWin="OpenIframeWin"></In03>
  15. <!--
  16. <In04 v-if="currentTargetType=='IN04'" :click-event="In04ClickEvent" :in04-model-load-state="in04modelloadstate" :user-timeout="AutoPlayer"></In04>
  17. <In05 v-if="currentTargetType=='IN05'" :click-event="In05ClickEvent" :in05-model-load-state="in05modelloadstate" :user-timeout="AutoPlayer"></In05>
  18. -->
  19. <Bottom @loadNavModel="loadNavModel" user-role="index" :fac-model-load-state="isLoaded"/>
  20. </div>
  21. <div id="iframeWin" v-if="isShowIframeWin" :class="iframeWinData.class">
  22. <div class="title"><span class="text" v-html="iframeWinData.title"></span><img src="../../assets/image/Close.png" style="margin: 7px 17px;float: right;cursor: pointer;" @click="CloseIframeWin"></div>
  23. <div class="content"><iframe id="ifrm" :src="iframeWinData.src" class=""></iframe></div>
  24. </div>
  25. </template>
  26. <script>
  27. import { ref, onMounted, onBeforeUnmount } from "vue";
  28. import { useRouter } from "vue-router";
  29. import { ElMessage, ElLoading } from "element-plus";
  30. import lottie from 'lottie-web';
  31. import api from "@/api/system";
  32. import Bottom from '../components/Bottom.vue';
  33. import Fac from '../components/Fac.vue';
  34. import In02 from '../components/In02.vue';
  35. import In03 from '../components/In03.vue';
  36. //import In04 from '../components/In04.vue';
  37. //import In05 from '../components/In05.vue';
  38. export default {
  39. components:{
  40. Bottom,
  41. Fac,
  42. In02,
  43. In03,
  44. //In04,
  45. //In05,
  46. },
  47. setup() {
  48. const loading_a1=ref(null);
  49. const loadProgressValue=ref(0);//模型加载初始进度
  50. const EngineContent=ref(null);
  51. const reconnect=ref(false);
  52. const isShowIframeWin = ref(false);
  53. const iframeWinData = ref({});
  54. const autoplayer_btn =ref(null);
  55. let In02ClickEvent = ref(null);
  56. let In04ClickEvent = ref(null);
  57. let In03ClickEvent = ref(null);
  58. let In05ClickEvent = ref(null);
  59. const In03Ele = ref(null);
  60. let isLoaded = ref(false);
  61. let isClearEle = ref(false);
  62. window.player = null;
  63. let playerNative = ref(null);
  64. let playerConnState=false;
  65. window.modelLoadState = {};
  66. const facModelLoadState=ref(false);
  67. const in02modelloadstate=ref(false);
  68. const in03modelloadstate=ref(false);
  69. const in04modelloadstate=ref(false);
  70. const in05modelloadstate=ref(false);
  71. let currentTargetType = ref('');
  72. let reconntimer=null;
  73. let MarkerMapFac={};
  74. let AutoPlayer=ref(false);
  75. let markerLClickObj=null;
  76. let inPoints={
  77. "IN02":{"Text001_002":1,"x1":-28.07801,"y1":37.95126,"x2":-23.32394,"y2":31.16921},
  78. "IN03":{"Text001_006":1,"x1":46.86921,"y1":24.87041,"x2":51.91054,"y2":17.87417},
  79. //"IN04":{"Text001_004":1,"x1":-38.46275,"y1":35.65208,"x2":-44.94122,"y2":28.22142},
  80. //"IN05":{"Text001_005":1,"x1":102.43050,"y1":38.96248,"x2":108.99212,"y2":30.86295}
  81. };
  82. function CloseIframeWin(){
  83. isShowIframeWin.value=false;
  84. iframeWinData.value={};
  85. }
  86. function OpenIframeWin(info){
  87. iframeWinData.value = {
  88. class:info.class==null? 'newwin bpbWin':info.class,
  89. src:info.src,
  90. title:info.title
  91. };
  92. isShowIframeWin.value=true;
  93. }
  94. function ShowLoading(){
  95. lottie.loadAnimation({
  96. // 选取一个容器,用于渲染动画
  97. container: loading_a1.value,
  98. // 定义JSON文件路径
  99. animationData: lottiedata,
  100. // 是否循环播放
  101. loop: true,
  102. // 渲染的格式svg/canvas/html,svg性能更优,兼容性更好
  103. renderer: "svg",
  104. });
  105. }
  106. function loadNavModel(item){
  107. //console.log(item)
  108. switch(item.code){
  109. case "FAC":
  110. loadFacModel(playerNative.value);
  111. break;
  112. case "IN02":
  113. loadIn02Model(playerNative.value);
  114. break;
  115. case "IN03":
  116. loadIn03Model(playerNative.value);
  117. break;
  118. }
  119. }
  120. function facMarkerLClick(obj){
  121. //接收Fac组件中点击标记时的数据
  122. markerLClickObj = obj;
  123. }
  124. function handleBodyClick(){
  125. isClearEle.value=true;
  126. }
  127. async function moveFacAnything(name,event){
  128. console.log(name, event)
  129. if(event.object==null) return;
  130. var se = event.object;
  131. player.Native.ModelTree.setSelectItem(event.object.item);
  132. var calcInfo = await PlayerUtils.call(player.Native.ModelTree.calcItemAabb, se.item);
  133. console.log(calcInfo)
  134. player.Native.Camera.moveToAabbWithDistance([calcInfo.localAabb.min, calcInfo.localAabb.max], 0.5, 0, 0.9);
  135. }
  136. function senceInit(){
  137. player = new RemotePlayer({
  138. video: EngineContent.value, //绑定视频标签或图片标签
  139. signalServer: process.env.VUE_APP_3D, //云渲染服务器,发布时需要改为实际地址
  140. engineId: "" + Date.now(), // 引擎会话id,如果已存在则连接,没有则创建,会话在断开连接后超时自动关闭
  141. rtcIni: 'rtc.ini', // 可指定webrtc配置文件,默认为rtc.ini,相对目录为集群节点的enginePath目录
  142. autoResize: true, // 引擎是否跟跟随标签尺寸
  143. limtMoveCPS: 10, // 限制每秒鼠标移动的消息个数
  144. userTimeout: 1000 * 60 * 5, // 用户操作超时设置,毫秒
  145. exitTimeout: 1000 * 60 * 60 * 999999, // 用户超时后多久断开会话
  146. maxTimeout: 10000, // 会话超时时间,允许掉线后引擎保存多久,在该时间内可重新连接到会话,否则会创建新的会话
  147. debug: false // 是否启用调试,开启后调用Native接口时会使用console.log进行记录
  148. });
  149. //2.[可选]监听连接成功消息
  150. player.on("Connected", () => {
  151. console.log("Has connected to engine")
  152. playerConnState = true
  153. reconnect.value = false;
  154. isLoaded.value = true;
  155. if (reconntimer != null) clearTimeout(reconntimer);
  156. });
  157. //3.[可选]监听连接失败消息
  158. player.on("Disconnected", (e) => {
  159. console.log("Disconnected from engine", e);
  160. reconnect.value = true;
  161. isClearEle.value=true;
  162. playerConnState = false
  163. facModelLoadState.value=false;
  164. in02modelloadstate.value=false;
  165. in03modelloadstate.value=false;
  166. window.IN03Markers=null;
  167. AutoPlayer.value=false;
  168. EngineContent.value.pause();
  169. if(e=='signal websocket error'){
  170. //服务器网络不通
  171. }
  172. modelLoadState={};
  173. //currentTargetType.value='';
  174. //4.[推荐]尝试重新连接
  175. reconntimer = setTimeout(function () {
  176. console.log('尝试自动重连:', playerConnState)
  177. if (playerConnState) return
  178. if(player==null ){
  179. window.location.reload();
  180. return;
  181. }
  182. player.reconnect();
  183. }, 4000);
  184. //启动自动连接状态检测
  185. setTimeout(() => {
  186. //5秒还未连接成功时直接刷新页面
  187. if(!playerConnState){
  188. console.log('自动连接超时,自动页面刷新')
  189. window.location.reload();
  190. }
  191. }, 9000);
  192. });
  193. //5. [推荐] 响应UserTimeOut消息,引擎接收用户鼠标触屏事件超时发出通知
  194. player.on("UserTimeOut", () => {
  195. console.info('用户长时间没有操作三维视图,可调用player.resetTimer()取消退出');
  196. //AutoPlayer.value = true; //暂时取消自动漫游功能
  197. });
  198. player.on('TimeOutExit',()=>{
  199. console.info('长时间没有操作,已断开连接');
  200. });
  201. player.on('ConnectedFailed',(evt)=>{
  202. console.info('服务器连接失败');
  203. })
  204. //6.监听远程过程调用加载完成消息
  205. player.on("NativeLoad", async (Native) => {
  206. modelLoadState={};
  207. EngineContent.value.play();
  208. playerNative.value =Native;
  209. //模型加载完成监听处理
  210. Native.Model.EventProgressEnd.connect(function(step,id,name){
  211. modelLoadState[name]=true;
  212. if(window.CurrentTargetType!=name){
  213. return
  214. }
  215. //当前模型加载完成,添加进度动画效果,否则会是一闪而过的效果
  216. loadProgressValue.value=99;
  217. setTimeout(() => {
  218. //动画效果为固定的0.5s,多0.5s才让进度消失
  219. loadProgressValue.value=100;
  220. }, 1000);
  221. if("FAC"==name){
  222. facModelLoadState.value=true;//全厂模型加载完成
  223. player.Native.Model.setModelVisible('IN02',false);
  224. player.Native.Model.setModelVisible('IN03',false);
  225. player.Native.Model.setModelVisible(name,window.CurrentTargetType==name?true:false);
  226. player.Native.CameraAnimation.clearKeyFrame();
  227. }else if("IN02"==name){
  228. in02modelloadstate.value=true;
  229. player.Native.Model.setModelVisible('FAC',false);
  230. player.Native.Model.setModelVisible('IN03',false);
  231. player.Native.Model.setModelVisible(name,window.CurrentTargetType==name?true:false);
  232. }else if("IN03"==name){
  233. in03modelloadstate.value=true;
  234. player.Native.Model.setModelVisible('FAC',false);
  235. player.Native.Model.setModelVisible('IN02',false);
  236. player.Native.Model.setModelVisible(name,window.CurrentTargetType==name?true:false);
  237. }
  238. });
  239. //模型加载中监听处理
  240. Native.Model.EventProgress.connect(function(v,hander,name){
  241. //当进度大于0.99时,交由EventProgressEnd监听处理
  242. if(window.CurrentTargetType!=name || v>0.99 ||v<1) return;
  243. loadProgressValue.value = (v*100).toFixed(0);
  244. });
  245. // // 选择Pickup工具
  246. player.Native.Tools.setCurrentTool("system.Pickup");
  247. player.Native.Settings.set('skybox',"string","null");
  248. player.Native.Settings.set('bg.image.file',"string",'data/sky/bg.png');
  249. //不显示提示框
  250. player.Native.Settings.set("tips.enabled", "bool", false);
  251. // //点选高亮显示
  252. player.Native.Settings.set("pickUp.highlight", "bool", false);
  253. //点选包围盒
  254. player.Native.Settings.set("show.select.box", "bool", false);
  255. player.Native.Settings.set("skybox.select", "string", "blue");
  256. //点选背景虚化
  257. player.Native.Settings.set("color.pickup.bkAlpha", "float", 0.8);
  258. // 选中展示节点
  259. // sam0023 = await player.Native.ModelTree.findItemByName("CYLINDER 3 of EQUIPMENT /C1101", 0, true, 3);
  260. player.Native.Settings.set('ambientIndenty', 'float', 0.39);//初始化环境光补偿
  261. player.Native.Settings.set('diffuseIntensity', 'float', 0.8);//初始化光线强度
  262. player.Native.Settings.set('specularIntensity', 'float', 0.64);//初始化高光强度
  263. player.Native.Settings.set('searchLightIntensity', 'float', 0.5);//初始化探照灯强度
  264. // 点击事件一般仅用于浏览工具,在点选工具下无效
  265. Native.Tools.setCurrentTool("system.Browse");
  266. console.log('window.CurrentTargetType:',window.CurrentTargetType)
  267. switch(window.CurrentTargetType){
  268. case "IN02":
  269. loadIn02Model(Native);
  270. break;
  271. case "IN03":
  272. loadIn03Model(Native);
  273. break;
  274. default:
  275. loadFacModel(Native);
  276. break;
  277. }
  278. Native.ModelTree.EventBrowseLClick.connect((event) => {
  279. if(event.object==null) return;
  280. if(currentTargetType.value=="FAC"){
  281. //必须延迟处理模型的点击事件,以判断是否是点击的标记,暂时没有找到更好的方法处理标记点击
  282. setTimeout(function(event){
  283. if(markerLClickObj!=null){
  284. //标记被点击时,不执行模型点击逻辑
  285. markerLClickObj = null;
  286. return;
  287. }
  288. markerLClickObj = null;
  289. var inTxt = "";
  290. if(inPoints[event.object.name]!=null){
  291. //进入楼层内部
  292. inTxt = txt;
  293. }else {
  294. for (var txt in inPoints) {
  295. var item = inPoints[txt];
  296. if(event.pos[1]>= item["x1"] && event.pos[2]<= item["y1"] &&event.pos[1]<= item["x2"] && event.pos[2]>= item["y2"]){
  297. inTxt = txt;
  298. break;
  299. }
  300. }
  301. }
  302. if(inTxt!=""){
  303. switch(inTxt){
  304. case "IN02":
  305. loadIn02Model(Native);
  306. break;
  307. case "IN03":
  308. loadIn03Model(Native);
  309. break;
  310. default:
  311. break;
  312. }
  313. currentTargetType.value=inTxt;
  314. }else{
  315. // moveFacAnything("LClick", event);
  316. }
  317. },200,event);
  318. return;
  319. }
  320. if(currentTargetType.value=="IN02"){
  321. In02ClickEvent.value = event;
  322. //In02Ele.updateInfo("LClick", event);
  323. }
  324. if(currentTargetType.value=="IN03") {
  325. //move03Anything("LClick", event);
  326. In03ClickEvent.value = event;
  327. }
  328. });
  329. Native.ModelTree.EventBrowseRClick.connect((event) => {
  330. if(markerLClickObj!=null) return;
  331. //updateInfo("RClick", event)
  332. });
  333. })
  334. }
  335. function getBottomBtnImg(imgname, type){
  336. if(currentTargetType.value==type) return require('@/assets/image/'+imgname+'_active.png');
  337. else return require('@/assets/image/'+imgname+'.png');
  338. }
  339. async function loadFacModel(Native){
  340. if(currentTargetType.value=="FAC") return;
  341. currentTargetType.value="FAC";
  342. await player.Native.Settings.set('ambientIndenty', 'float', 0.39);//初始化环境光补偿
  343. await player.Native.Settings.set('diffuseIntensity', 'float', 1.2);//初始化光线强度
  344. await player.Native.Settings.set('specularIntensity', 'float', 0.64);//初始化高光强度
  345. if(modelLoadState[currentTargetType.value]==null){
  346. loadProgressValue.value = 1;
  347. modelLoadState['FAC']=false;
  348. var cf = "data://models/T_ALL.pr";
  349. //var errStr = await PlayerUtils.call(Native.Model.loadModel, currentTargetType.value, cf);
  350. //异步加载模型,加载进度通过EventProgress及EventProgressEnd进行监听
  351. PlayerUtils.call(Native.Model.loadModelWithParam, currentTargetType.value, cf, {
  352. "loadThreshold": 10000,
  353. "unloadThreshold": 100000,
  354. "dynamicLoadEnabled ": true
  355. });
  356. if(modelLoadState['IN02']==null){
  357. modelLoadState['IN02']=false;
  358. var cf = "data://models/T_02.pr";
  359. PlayerUtils.call(Native.Model.loadModelWithParam, 'IN02', cf, {
  360. "loadThreshold": 10000,
  361. "unloadThreshold": 100000,
  362. "dynamicLoadEnabled ": true
  363. });
  364. }
  365. if(modelLoadState['IN03']==null){
  366. modelLoadState['IN03']=false;
  367. var cf = "data://models/T_03.pr";
  368. PlayerUtils.call(Native.Model.loadModelWithParam, 'IN03', cf, {
  369. "loadThreshold": 10000,
  370. "unloadThreshold": 100000,
  371. "dynamicLoadEnabled ": true
  372. });
  373. }
  374. return;
  375. }
  376. await player.Native.Model.setModelVisible("IN02",false);
  377. await player.Native.Model.setModelVisible("IN03",false);
  378. await player.Native.Model.setModelVisible(currentTargetType.value,true);
  379. if(modelLoadState[currentTargetType.value]==true) facModelLoadState.value=true;
  380. }
  381. //印花
  382. async function loadIn03Model(Native){
  383. player.Native.Settings.set('ambientIndenty', 'float', 1);//初始化环境光补偿
  384. player.Native.Settings.set('diffuseIntensity', 'float', 2.5);//初始化光线强度
  385. player.Native.Settings.set('specularIntensity', 'float', 0.6);//初始化高光强度
  386. if(currentTargetType.value=="IN03") return;
  387. currentTargetType.value="IN03";
  388. if(modelLoadState[currentTargetType.value]==null){
  389. loadProgressValue.value = 1;
  390. modelLoadState[currentTargetType.value]=false;
  391. var cf = "data://models/T_03.pr";
  392. //异步加载模型,加载进度通过EventProgress及EventProgressEnd进行监听
  393. PlayerUtils.call(Native.Model.loadModelWithParam, currentTargetType.value, cf, {
  394. "loadThreshold": 10000,
  395. "unloadThreshold": 100000,
  396. "dynamicLoadEnabled ": true
  397. });
  398. return;
  399. }
  400. await player.Native.Model.setModelVisible("FAC",false);
  401. await player.Native.Model.setModelVisible("IN02",false);
  402. await player.Native.Model.setModelVisible(currentTargetType.value,true);
  403. if(modelLoadState[currentTargetType.value]==true) in03modelloadstate.value=true;
  404. }
  405. //经编
  406. async function loadIn02Model(Native){
  407. player.Native.Settings.set('ambientIndenty', 'float', 0.39);//初始化环境光补偿
  408. player.Native.Settings.set('diffuseIntensity', 'float', 0.8);//初始化光线强度
  409. player.Native.Settings.set('specularIntensity', 'float', 0.64);//初始化高光强度
  410. if(currentTargetType.value=="IN02") return;
  411. currentTargetType.value="IN02";
  412. if(modelLoadState[currentTargetType.value]==null){
  413. loadProgressValue.value = 1;
  414. modelLoadState[currentTargetType.value]=false;
  415. var cf = "data://models/T_02.pr";
  416. //异步加载模型,加载进度通过EventProgress及EventProgressEnd进行监听
  417. PlayerUtils.call(Native.Model.loadModelWithParam, 'IN02', cf, {
  418. "loadThreshold": 10000,
  419. "unloadThreshold": 100000,
  420. "dynamicLoadEnabled ": true
  421. });
  422. return;
  423. }
  424. await player.Native.Model.setModelVisible("FAC",false);
  425. await player.Native.Model.setModelVisible("IN03",false);
  426. await player.Native.Model.setModelVisible(currentTargetType.value,true);
  427. if(modelLoadState[currentTargetType.value]==true) in02modelloadstate.value=true;
  428. }
  429. onMounted(()=>{
  430. window.addEventListener("click", handleBodyClick);
  431. ShowLoading();
  432. senceInit();
  433. });
  434. onBeforeUnmount(()=>{
  435. EngineContent.value.pause();
  436. player.Native.Model.unloadModel('FAC');
  437. player.Native.Model.unloadModel('IN02');
  438. player.Native.Model.unloadModel('IN03');
  439. })
  440. return {
  441. player,
  442. isShowIframeWin,
  443. iframeWinData,
  444. facMarkerLClick,
  445. CloseIframeWin,
  446. OpenIframeWin,
  447. isLoaded,
  448. currentTargetType,
  449. loading_a1,
  450. loadProgressValue,
  451. reconnect,
  452. EngineContent,
  453. AutoPlayer,
  454. In02ClickEvent,
  455. In03ClickEvent,
  456. In04ClickEvent,
  457. In05ClickEvent,
  458. facModelLoadState,
  459. in02modelloadstate,
  460. in03modelloadstate,
  461. in04modelloadstate,
  462. in05modelloadstate,
  463. ShowLoading,
  464. handleBodyClick,
  465. senceInit,
  466. getBottomBtnImg,
  467. markerLClickObj,
  468. loadNavModel,
  469. }
  470. },
  471. }
  472. </script>
  473. <style scoped>
  474. </style>