move.service.ts 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596
  1. import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
  2. import { ConfigService } from '@nestjs/config';
  3. import { readFileSync } from 'fs';
  4. import { join } from 'path';
  5. import { CacheService } from 'src/cache/cache.service';
  6. import { RotateService } from 'src/rotate/rotate.service';
  7. // import * as BreakPointIds from '../../ws/points-BreakPointId.json';
  8. // import { SceneService } from 'src/scene/scene.service';
  9. const seqExeAsyncFn = (asyncFn) => {
  10. let runPromise = null;
  11. return function seq(...args) {
  12. if (!runPromise) {
  13. //debugger;
  14. runPromise = asyncFn.apply(this, args);
  15. runPromise.then((data) => {
  16. //debugger;
  17. // console.log('seq result', data);
  18. });
  19. runPromise.then(() => (runPromise = null));
  20. return runPromise;
  21. } else {
  22. return runPromise.then(() => seq.apply(this, args));
  23. }
  24. };
  25. };
  26. @Injectable()
  27. export class MoveService implements OnModuleInit {
  28. constructor(
  29. private cacheService: CacheService,
  30. private rotateService: RotateService,
  31. private configService: ConfigService,
  32. ) {}
  33. private logger: Logger = new Logger('MoveService');
  34. private Actions = {
  35. Clicking: 1,
  36. Rotation: 1014,
  37. Joystick: 15,
  38. };
  39. public users = this.rotateService.users;
  40. private reply = {
  41. traceIds: [],
  42. vehicle: null,
  43. mediaSrc: null,
  44. moveOver: false,
  45. moveStart: false,
  46. newUserStates: [
  47. {
  48. userId: 'dcff36ae4fc1d',
  49. playerState: {
  50. roomTypeId: '',
  51. person: 0,
  52. avatarId: '',
  53. skinId: '',
  54. roomId: '',
  55. isHost: false,
  56. isFollowHost: false,
  57. skinDataVersion: '',
  58. avatarComponents: '',
  59. nickName: '',
  60. movingMode: 0,
  61. attitude: '',
  62. areaName: '',
  63. pathName: '',
  64. pathId: '',
  65. avatarSize: 1,
  66. extra: '',
  67. prioritySync: false,
  68. player: {
  69. position: { x: -700, y: 0, z: 0 },
  70. angle: {
  71. pitch: 0,
  72. yaw: 0,
  73. roll: 0,
  74. },
  75. },
  76. camera: {
  77. position: { x: -1145, y: 0, z: 160 },
  78. angle: {
  79. pitch: 0,
  80. yaw: 0,
  81. roll: 0,
  82. },
  83. },
  84. cameraCenter: { x: -700, y: 0, z: 0 },
  85. },
  86. renderInfo: {
  87. renderType: 0,
  88. videoFrame: null,
  89. cameraStateType: 3,
  90. isMoving: 1,
  91. needIfr: 0,
  92. isVideo: 0,
  93. stillFrame: 0,
  94. isRotating: 0,
  95. isFollowing: 0,
  96. clientPanoTitlesBitmap: [],
  97. clientPanoTreceId: '',
  98. prefetchVideoId: '',
  99. noMedia: false,
  100. },
  101. event: null,
  102. relation: 1,
  103. },
  104. ],
  105. actionResponses: [
  106. {
  107. actionType: 1,
  108. pointType: 100,
  109. extra: '',
  110. traceId: '',
  111. packetId: '',
  112. nps: [],
  113. peopleNum: 0,
  114. zoneId: '',
  115. echoMsg: '',
  116. reserveDetail: null,
  117. userWithAvatarList: [],
  118. newUserStates: [],
  119. code: 0,
  120. msg: '',
  121. },
  122. ],
  123. getStateType: 0,
  124. code: 0,
  125. msg: 'OK',
  126. };
  127. private breakPointInfo: any;
  128. private cameraInfos = [];
  129. public sendingFrameForJoystick = false;
  130. // eslint-disable-next-line @typescript-eslint/no-empty-function
  131. async onModuleInit() {
  132. const app_id = '0000000003';
  133. const prefix = '/mnt/metaverse/scene';
  134. let path;
  135. // let path: string;
  136. if (process.env.NODE_ENV === 'development') {
  137. path = join(__dirname, `../ws/${app_id}/points-${app_id}.json`);
  138. console.log('测试服JSON', path);
  139. }
  140. if (process.env.NODE_ENV === 'production') {
  141. path = join(`${prefix}/${app_id}/points-${app_id}.json`);
  142. console.log('正式服JSON', path);
  143. }
  144. this.loadJSON(path);
  145. }
  146. async loadJSON(path) {
  147. try {
  148. const data = await readFileSync(path);
  149. const BreakPointInfo = JSON.parse(Buffer.from(data).toString('utf-8'));
  150. this.breakPointInfo = BreakPointInfo;
  151. // console.log('BreakPointInfo', BreakPointInfo);
  152. } catch (error) {
  153. this.logger.error('load-json-error', error);
  154. }
  155. }
  156. init(app_id, userId) {
  157. const user = {
  158. appId: null,
  159. userId: null,
  160. breakPointId: null,
  161. roomId: null,
  162. player: {
  163. position: { x: -700, y: 0, z: 0 },
  164. angle: {
  165. pitch: 0,
  166. yaw: 0,
  167. roll: 0,
  168. },
  169. },
  170. camera: {
  171. position: { x: -1145, y: 0, z: 160 },
  172. angle: {
  173. pitch: 0,
  174. yaw: 0,
  175. roll: 0,
  176. },
  177. },
  178. rotateInfo: {
  179. frameIndex: 0,
  180. horizontal_move: 0,
  181. },
  182. moveInfo: {},
  183. // traceIds: [],
  184. // actionResponses:[]
  185. };
  186. user.appId = app_id;
  187. user.userId = userId;
  188. user.breakPointId = Number(this.configService.get('app.startPoint')) || 0;
  189. console.log('user-init', user);
  190. this.users[userId] = user;
  191. }
  192. async getMoveFrames(appId,start_break_point_id,end_break_point_id,angleIndex){
  193. let moveFramesRes,moveFrames;
  194. let key = 'moveframe:app_id:' + appId + ':start_break_point_id:' + start_break_point_id + ':end_break_point_id:' + end_break_point_id +':angle:' + angleIndex;
  195. //倒叙
  196. if(start_break_point_id>end_break_point_id){
  197. key = 'moveframe:app_id:' + appId + ':start_break_point_id:' + end_break_point_id + ':end_break_point_id:' + start_break_point_id +':angle:' + angleIndex;
  198. console.log('getMoveFrames:'+key);
  199. moveFramesRes = await this.cacheService.get(key);
  200. moveFrames = JSON.parse(moveFramesRes);
  201. moveFrames = moveFrames.reverse();
  202. }
  203. else{
  204. console.log('getMoveFrames:'+key);
  205. moveFramesRes = await this.cacheService.get(key);
  206. moveFrames = JSON.parse(moveFramesRes);
  207. }
  208. return moveFrames
  209. }
  210. async move(pathArray, actionRequest) {
  211. try {
  212. const userId = actionRequest['user_id'];
  213. const traceId = actionRequest['trace_id'];
  214. const actionType = actionRequest['action_type'];
  215. const user = this.users[userId];
  216. const appId = user.appId;
  217. const path = pathArray || [100, 101, 102]; //需要计算路径
  218. const angle = user.camera.angle.yaw % 45; //纠正需要
  219. const replys = [];
  220. const traceIds = [];
  221. traceIds.push(traceId);
  222. const checkReplys = await this.modeifyCameraAngle(
  223. angle,
  224. userId,
  225. traceId,
  226. actionType,
  227. );
  228. for (let i = 0; i < checkReplys.length; ++i) {
  229. checkReplys[i].actionResponses[0].actionType = actionType;
  230. }
  231. //replys['P' + user.breakPointId + 'T' + user.breakPointId] = checkReplys;
  232. replys.push(checkReplys);
  233. console.log('路径:' + path);
  234. //过渡传到缓存里
  235. this.reply.traceIds = traceIds;
  236. this.reply['newUserStates'][0].userId = userId;
  237. this.reply['actionResponses'][0].traceId = traceId;
  238. const index = Math.floor((user.camera.angle.yaw + 1) / 45)%8; //过渡需要
  239. for (let i = 0; i < path.length - 1; ++i) {
  240. let pathReplys = [];
  241. const start_break_point_id = path[i];
  242. const end_break_point_id = path[i + 1];
  243. /*
  244. //读redis里的数据,按照frame_index的大小排序
  245. const key =
  246. 'moveframe:app_id:' +
  247. appId +
  248. ':start_break_point_id:' +
  249. start_break_point_id +
  250. ':end_break_point_id:' +
  251. end_break_point_id +
  252. ':angle:' +
  253. index;
  254. const moveFramesRes = await this.cacheService.get(key);
  255. if (moveFramesRes == null) {
  256. return replys;
  257. }
  258. const moveFrames = JSON.parse(moveFramesRes);
  259. */
  260. const moveFrames = await this.getMoveFrames(appId,start_break_point_id,end_break_point_id,index);
  261. if (!moveFrames) {
  262. return replys;
  263. }
  264. pathReplys = this.createCacheReplys(
  265. appId,
  266. moveFrames,
  267. traceId,
  268. userId,
  269. start_break_point_id,
  270. end_break_point_id,
  271. false,
  272. );
  273. if (i == path.length - 2) {
  274. pathReplys[pathReplys.length - 1][
  275. 'newUserStates'
  276. ][0].renderInfo.isMoving = 0;
  277. }
  278. for (let j = 0; j < pathReplys.length; ++j) {
  279. pathReplys[j].actionResponses[0].actionType = actionType;
  280. }
  281. replys.push(pathReplys);
  282. //replys['P' + start_break_point_id + 'T' + end_break_point_id] =pathReplys;
  283. }
  284. return replys;
  285. } catch (error) {
  286. console.log('MoveService', error);
  287. }
  288. }
  289. createCacheReplys(
  290. appId,
  291. moveFrames,
  292. traceId,
  293. userId,
  294. startBreakPointId,
  295. endBreakPointId,
  296. isFromUser,
  297. ) {
  298. const replys = [];
  299. const startPosition = this.breakPointInfo[startBreakPointId].position;
  300. const endPosition = this.breakPointInfo[endBreakPointId].position;
  301. const angle = this.getAngle(
  302. startPosition,
  303. {
  304. x: startPosition.x + 1,
  305. y: startPosition.y,
  306. },
  307. endPosition,
  308. );
  309. const user = this.users[userId];
  310. let i;
  311. for (i = 1; i < moveFrames.length; i += 3) {
  312. const moveFrame = moveFrames[i];
  313. const reply = JSON.parse(JSON.stringify(this.reply));
  314. if (reply.traceIds.indexOf(traceId) == -1) {
  315. reply.traceIds.push(traceId);
  316. }
  317. reply['newUserStates'][0].userId = userId;
  318. if (!isFromUser) {
  319. reply['newUserStates'][0].playerState.player.position = {
  320. x:
  321. startPosition.x +
  322. ((endPosition.x - startPosition.x) / moveFrames.length) * i,
  323. y:
  324. startPosition.y +
  325. ((endPosition.y - startPosition.y) / moveFrames.length) * i,
  326. z:
  327. startPosition.z +
  328. ((endPosition.z - startPosition.z) / moveFrames.length) * i,
  329. };
  330. reply['newUserStates'][0].playerState.player.angle.yaw = angle;
  331. reply['newUserStates'][0].playerState.cameraCenter =
  332. reply['newUserStates'][0].playerState.player.position;
  333. } else {
  334. reply['newUserStates'][0].playerState.player.position = JSON.parse(
  335. JSON.stringify(user.player.position),
  336. );
  337. reply['newUserStates'][0].playerState.player.angle.yaw =
  338. user.player.angle.yaw;
  339. reply['newUserStates'][0].playerState.cameraCenter = JSON.parse(
  340. JSON.stringify(user.player.position),
  341. );
  342. }
  343. reply['newUserStates'][0].playerState.camera.position = JSON.parse(
  344. JSON.stringify(moveFrame.camera_position),
  345. );
  346. if (i == 1) {
  347. console.log('move-2' + moveFrame.camera_angle.yaw);
  348. }
  349. if (moveFrame.camera_angle.yaw < 0) {
  350. moveFrame.camera_angle.yaw += 360;
  351. } else if (moveFrame.camera_angle.yaw > 359) {
  352. moveFrame.camera_angle.yaw -= 360;
  353. }
  354. reply['newUserStates'][0].playerState.camera.angle =
  355. moveFrame.camera_angle;
  356. reply['newUserStates'][0].renderInfo.isMoving = 1;
  357. reply['actionResponses'][0].traceId = traceId;
  358. reply.mediaSrc =
  359. '/' +
  360. appId +
  361. '/' +
  362. startBreakPointId +
  363. '/' +
  364. moveFrame.file_name.substring(0, moveFrame.file_name.indexOf('.')) +
  365. '/' +
  366. moveFrame.file_name +
  367. '?m=' +
  368. new Date().getTime();
  369. if(startBreakPointId>endBreakPointId){
  370. reply.mediaSrc =
  371. '/' +
  372. appId +
  373. '/' +
  374. endBreakPointId +
  375. '/' +
  376. moveFrame.file_name.substring(0, moveFrame.file_name.indexOf('.')) +
  377. '/' +
  378. moveFrame.file_name +
  379. '?m=' +
  380. new Date().getTime();
  381. }
  382. reply.startBreakPointId = startBreakPointId;
  383. reply.endBreakPointId = endBreakPointId;
  384. replys.push(reply);
  385. }
  386. if (i != moveFrames.length - 1) {
  387. i = moveFrames.length - 1;
  388. const moveFrame = moveFrames[i];
  389. const reply = JSON.parse(JSON.stringify(this.reply));
  390. reply.traceIds.push(traceId);
  391. reply['newUserStates'][0].userId = userId;
  392. if (!isFromUser) {
  393. reply['newUserStates'][0].playerState.player.position = {
  394. x:
  395. startPosition.x +
  396. ((endPosition.x - startPosition.x) / moveFrames.length) * i,
  397. y:
  398. startPosition.y +
  399. ((endPosition.y - startPosition.y) / moveFrames.length) * i,
  400. z:
  401. startPosition.z +
  402. ((endPosition.z - startPosition.z) / moveFrames.length) * i,
  403. };
  404. reply['newUserStates'][0].playerState.player.angle.yaw = angle;
  405. reply['newUserStates'][0].playerState.cameraCenter =
  406. reply['newUserStates'][0].playerState.player.position;
  407. } else {
  408. reply['newUserStates'][0].playerState.player.position = JSON.parse(
  409. JSON.stringify(user.player.position),
  410. );
  411. reply['newUserStates'][0].playerState.player.angle.yaw =
  412. user.player.angle.yaw;
  413. reply['newUserStates'][0].playerState.cameraCenter = JSON.parse(
  414. JSON.stringify(user.player.position),
  415. );
  416. }
  417. reply['newUserStates'][0].playerState.camera.position =
  418. moveFrame.camera_position;
  419. if (moveFrame.camera_angle.yaw < 0) {
  420. moveFrame.camera_angle.yaw += 360;
  421. } else if (moveFrame.camera_angle.yaw > 359) {
  422. moveFrame.camera_angle.yaw -= 360;
  423. }
  424. reply['newUserStates'][0].playerState.camera.angle =
  425. moveFrame.camera_angle;
  426. reply['actionResponses'][0].traceId = traceId;
  427. reply.mediaSrc =
  428. '/' +
  429. appId +
  430. '/' +
  431. startBreakPointId +
  432. '/' +
  433. moveFrame.file_name.substring(0, moveFrame.file_name.indexOf('.')) +
  434. '/' +
  435. moveFrame.file_name +
  436. '?m=' +
  437. new Date().getTime();
  438. if(startBreakPointId>endBreakPointId){
  439. reply.mediaSrc =
  440. '/' +
  441. appId +
  442. '/' +
  443. endBreakPointId +
  444. '/' +
  445. moveFrame.file_name.substring(0, moveFrame.file_name.indexOf('.')) +
  446. '/' +
  447. moveFrame.file_name +
  448. '?m=' +
  449. new Date().getTime();
  450. }
  451. reply.startBreakPointId = startBreakPointId;
  452. reply.endBreakPointId = endBreakPointId;
  453. replys.push(reply);
  454. }
  455. return replys;
  456. }
  457. //需要通知user,人物和相机走到哪一个呼吸点位了
  458. updateUser(userId, breakPointId, lastReply) {
  459. const user = this.users[userId];
  460. user.breakPointId = breakPointId;
  461. console.log('handlejoystick:updateUser');
  462. if (lastReply.actionResponses[0].actionType != 15) {
  463. user.player.position =
  464. lastReply['newUserStates'][0].playerState.player.position;
  465. }
  466. user.player.angle = lastReply['newUserStates'][0].playerState.player.angle;
  467. user.camera.position =
  468. lastReply['newUserStates'][0].playerState.camera.position;
  469. user.camera.angle = lastReply['newUserStates'][0].playerState.camera.angle;
  470. }
  471. getBreakPoints(actionRequest) {
  472. const userId = actionRequest['user_id'];
  473. const traceId = actionRequest['trace_id'];
  474. const actionType = actionRequest['action_type'];
  475. const user = this.users[userId];
  476. const appId = user.appId;
  477. const breakPointId = user.breakPointId;
  478. const reply = {
  479. actionType: actionType,
  480. pointType: 100,
  481. extra: '',
  482. traceId: traceId,
  483. packetId: '',
  484. nps: [],
  485. peopleNum: 0,
  486. zoneId: '',
  487. echoMsg: '',
  488. reserveDetail: null,
  489. userWithAvatarList: [],
  490. newUserStates: [],
  491. code: 0,
  492. msg: '',
  493. };
  494. //const breakPoints = await this.cacheService.get('breakpoints:app_id:'+appId+':break_point_id:'+breakPointId);
  495. //获取redis表全部元素,'breakpoints:app_id:'+appId+':break_point_id:'开头的
  496. //const keys = await this.cacheService.keys(`breakpoints:app_id:${appId}*`);
  497. for (const key in this.breakPointInfo) {
  498. const breakPoint = this.breakPointInfo[key];
  499. //const breakPoint = JSON.parse(breakPointRes);
  500. //const position = breakPoint.position;
  501. reply['nps'].push({
  502. position: breakPoint.position,
  503. breakPointId: Number(key),
  504. });
  505. }
  506. // for (let i = 0; i < keys.length; ++i) {
  507. // const breakPointRes = await this.cacheService.get(keys[i]);
  508. // const breakPoint = JSON.parse(breakPointRes);
  509. // const position = breakPoint.position;
  510. // reply['nps'].push({
  511. // position: position,
  512. // breakPointId: breakPoint.breakPointId,
  513. // });
  514. // }
  515. return reply;
  516. }
  517. getAngle(point, point1, point2) {
  518. const x1 = point1.x - point.x;
  519. const y1 = point1.y - point.y;
  520. const x2 = point2.x - point.x;
  521. const y2 = point2.y - point.y;
  522. const dot = x1 * x2 + y1 * y2;
  523. const det = x1 * y2 - y1 * x2;
  524. const angle = (Math.atan2(det, dot) / Math.PI) * 180;
  525. return (angle + 360) % 360;
  526. }
  527. async stop(traceId, userId, breakPointId, cameraAngle, playerAngle) {
  528. //const breakPointId = movePointIds.substring(movePointIds.indexOf('-') + 1);
  529. const user = this.users[userId];
  530. const startBreakPointId = user.breakPointId;
  531. user.breakPointId = breakPointId;
  532. const appId = user.appId;
  533. const breakPoint = this.breakPointInfo[breakPointId];
  534. user.player.position = breakPoint.position;
  535. user.player.angle = playerAngle;
  536. const rotateKey =
  537. 'rotateframe:app_id:' +
  538. appId +
  539. ':frame_index:' +
  540. cameraAngle.yaw +
  541. ':break_point_id:' +
  542. breakPointId;
  543. const rotateDataRes = await this.cacheService.get(rotateKey);
  544. const rotateData = JSON.parse(rotateDataRes);
  545. user.camera.position = rotateData.cameraPosition;
  546. user.camera.angle = rotateData.cameraAngle;
  547. const reply = JSON.parse(JSON.stringify(this.reply));
  548. reply.traceIds.push(traceId);
  549. reply['newUserStates'][0].userId = userId;
  550. reply['newUserStates'][0].playerState.player.position = breakPoint.position;
  551. reply['newUserStates'][0].playerState.player.angle = playerAngle;
  552. reply['newUserStates'][0].playerState.camera.position =
  553. rotateData.cameraPosition;
  554. reply['newUserStates'][0].playerState.camera.angle = rotateData.cameraAngle;
  555. reply['newUserStates'][0].playerState.cameraCenter = breakPoint.position;
  556. reply['actionResponses'][0].traceId = traceId;
  557. reply.mediaSrc =
  558. '/' +
  559. appId +
  560. '/' +
  561. breakPointId +
  562. '/' +
  563. rotateData.directory +
  564. '/' +
  565. rotateData.fileName +
  566. '?m=' +
  567. new Date().getTime();
  568. reply.startBreakPointId = startBreakPointId;
  569. reply.endBreakPointId = breakPointId;
  570. reply['newUserStates'][0].renderInfo.isMoving = 0;
  571. return reply;
  572. }
  573. // 顺序旋转请求
  574. seqExeJoystick = seqExeAsyncFn(this.joystick);
  575. // async joystick(actionRequest) {
  576. // try {
  577. // const userId = actionRequest['user_id'];
  578. // const traceId = actionRequest['trace_id'];
  579. // const dir_action = actionRequest['dir_action'];
  580. // const actionType = actionRequest['action_type'];
  581. // const user = this.users[userId];
  582. // const breakPointId = user.breakPointId;
  583. // const appId = user.appId;
  584. // const replys = [];
  585. // const step = 0.3;
  586. // const closestDis = 85; //小于这个距离就跳到邻居呼吸点
  587. // const distance = step * dir_action.speed_level;
  588. // let angle = null;
  589. // let move_angle = dir_action.move_angle + user.camera.angle.yaw;
  590. // move_angle = move_angle % 360;
  591. // //TODO 临时增加断言
  592. // const playerPosition: Point = { x: 0, y: 0, z: 0 };
  593. // playerPosition.x =
  594. // user.player.position.x +
  595. // distance * Math.cos((move_angle / 360) * 2 * Math.PI);
  596. // playerPosition.y =
  597. // user.player.position.y +
  598. // distance * Math.sin((move_angle / 360) * 2 * Math.PI);
  599. // //找到邻居点,判断user.player.position与邻居点的距离,如果距离小于closestDis,就要更新camera的position
  600. // let chooseBreakPointId = null;
  601. // const breakPoint = this.breakPointInfo[breakPointId];
  602. // const surroundPointIds = breakPoint.contact;
  603. // //const neighAngles = [];
  604. // const traceIds = [];
  605. // user.player.angle.yaw = move_angle;
  606. // traceIds.push(traceId);
  607. // this.reply.traceIds = traceIds;
  608. // this.reply['newUserStates'][0].userId = userId;
  609. // this.reply['actionResponses'][0].traceId = traceId;
  610. // this.reply['newUserStates'][0].playerState.player.angle.yaw = move_angle;
  611. // this.reply['newUserStates'][0].playerState.camera.angle = JSON.parse(
  612. // JSON.stringify(user.camera.angle),
  613. // );
  614. // this.reply['newUserStates'][0].playerState.camera.position = JSON.parse(
  615. // JSON.stringify(user.camera.position),
  616. // );
  617. // this.reply['newUserStates'][0].playerState.cameraCenter = JSON.parse(
  618. // JSON.stringify(breakPoint.position),
  619. // );
  620. // this.reply['newUserStates'][0].renderInfo.isMoving = 1;
  621. // this.reply['actionResponses'][0].traceId = traceId;
  622. // this.reply.mediaSrc = null;
  623. // if (surroundPointIds.length == 1) {
  624. // return await this.moveDirect(
  625. // playerPosition,
  626. // closestDis,
  627. // breakPointId,
  628. // surroundPointIds[0],
  629. // appId,
  630. // userId,
  631. // traceId,
  632. // actionType,
  633. // );
  634. // }
  635. // let count = 0;
  636. // const neighPoints = [];
  637. // //人在哪个角度
  638. // let _angle = this.getAngle(
  639. // breakPoint.position,
  640. // { x: breakPoint.position.x + 1, y: breakPoint.position.y },
  641. // playerPosition,
  642. // );
  643. // if (_angle < 0) {
  644. // _angle += 360;
  645. // }
  646. // let singleInfo = null;
  647. // for (let i = 0; i < surroundPointIds.length; ++i) {
  648. // const neighPoint = this.breakPointInfo[surroundPointIds[i]];
  649. // neighPoint.breakPointId = surroundPointIds[i];
  650. // angle = this.getAngle(
  651. // breakPoint.position,
  652. // { x: breakPoint.position.x + 1, y: breakPoint.position.y },
  653. // neighPoint.position,
  654. // );
  655. // if (angle < 0) {
  656. // angle += 360;
  657. // }
  658. // //if(angle<45&&angle!=0){
  659. // if (
  660. // // Math.abs(angle - move_angle) < 45 &&
  661. // // Math.abs(angle - move_angle) != 0
  662. // Math.abs(angle - _angle) < 45 &&
  663. // Math.abs(angle - _angle) != 0
  664. // ) {
  665. // neighPoint.angle = angle;
  666. // neighPoints.push(neighPoint);
  667. // ++count;
  668. // } else if (Math.abs(angle - move_angle) == 0) {
  669. // return await this.moveDirect(
  670. // playerPosition,
  671. // closestDis,
  672. // breakPointId,
  673. // surroundPointIds[i],
  674. // appId,
  675. // userId,
  676. // traceId,
  677. // actionType,
  678. // );
  679. // }
  680. // //if (angle == 0 && Math.abs(360 - move_angle) < 45) {
  681. // if (angle == 0 && Math.abs(360 - _angle) < 45) {
  682. // neighPoint.angle = angle;
  683. // neighPoints.push(neighPoint);
  684. // ++count;
  685. // }
  686. // if(Math.abs(angle - move_angle)<45||Math.abs(angle+360 - move_angle)<45){
  687. // if(singleInfo == null){
  688. // singleInfo = {
  689. // angle:angle,
  690. // breakPointId:surroundPointIds[i]
  691. // }
  692. // }
  693. // }
  694. // }
  695. // if (count == 2) {
  696. // //人物移动
  697. // user.player.position = JSON.parse(JSON.stringify(playerPosition));
  698. // this.reply['newUserStates'][0].playerState.player.position = JSON.parse(
  699. // JSON.stringify(playerPosition),
  700. // );
  701. // }
  702. // else{
  703. // if(singleInfo != null){
  704. // return await this.moveDirect(
  705. // playerPosition,
  706. // closestDis,
  707. // breakPointId,
  708. // singleInfo.breakPointId,
  709. // appId,
  710. // userId,
  711. // traceId,
  712. // actionType,
  713. // );
  714. // }
  715. // else if (count == 1) {
  716. // return await this.moveDirect(
  717. // playerPosition,
  718. // closestDis,
  719. // breakPointId,
  720. // neighPoints[0].breakPointId,
  721. // appId,
  722. // userId,
  723. // traceId,
  724. // actionType,
  725. // );
  726. // }
  727. // else if (count == 0) {
  728. // this.reply['newUserStates'][0].playerState.player.position = JSON.parse(
  729. // JSON.stringify(user.player.position),
  730. // );
  731. // this.reply.actionResponses[0].actionType = actionType;
  732. // return this.reply;
  733. // }
  734. // }
  735. // //count == 2
  736. // //超出范围了
  737. // if (this.getDistance(playerPosition, breakPoint.position) > closestDis) {
  738. // let offsetAngle1 = Math.abs(_angle - neighPoints[0].angle);
  739. // if (neighPoints[0].angle == 0) {
  740. // offsetAngle1 = Math.min(offsetAngle1, Math.abs(_angle - 360));
  741. // }
  742. // let offsetAngle2 = Math.abs(_angle - neighPoints[1].angle);
  743. // if (neighPoints[1].angle == 0) {
  744. // offsetAngle2 = Math.min(offsetAngle2, Math.abs(_angle - 360));
  745. // }
  746. // if (offsetAngle1 > offsetAngle2) {
  747. // chooseBreakPointId = neighPoints[1].breakPointId;
  748. // } else {
  749. // chooseBreakPointId = neighPoints[0].breakPointId;
  750. // }
  751. // return await this.moveCamera(
  752. // breakPointId,
  753. // chooseBreakPointId,
  754. // appId,
  755. // userId,
  756. // traceId,
  757. // actionType,
  758. // );
  759. // } else {
  760. // user.player.position = JSON.parse(JSON.stringify(playerPosition));
  761. // this.reply['newUserStates'][0].playerState.player.position = JSON.parse(
  762. // JSON.stringify(user.player.position),
  763. // );
  764. // this.reply.actionResponses[0].actionType = actionType;
  765. // return this.reply;
  766. // }
  767. // } catch (error) {
  768. // console.log('MoveService', error);
  769. // debugger;
  770. // return null;
  771. // }
  772. // }
  773. async joystick(actionRequest) {
  774. //try {
  775. if (this.sendingFrameForJoystick) {
  776. return null;
  777. }
  778. const userId = actionRequest['user_id'];
  779. const traceId = actionRequest['trace_id'];
  780. const dir_action = actionRequest['dir_action'];
  781. const actionType = actionRequest['action_type'];
  782. const user = this.users[userId];
  783. const breakPointId = user.breakPointId;
  784. const appId = user.appId;
  785. const step = 0.3;
  786. const closestDis = 85; //小于这个距离就跳到邻居呼吸点
  787. const distance = step * dir_action.speed_level;
  788. let angle = null;
  789. let move_angle = dir_action.move_angle + user.camera.angle.yaw;
  790. move_angle = move_angle % 360;
  791. //TODO 临时增加断言
  792. const playerPosition: Point = { x: 0, y: 0, z: 0 };
  793. playerPosition.x =
  794. user.player.position.x +
  795. distance * Math.cos((move_angle / 360) * 2 * Math.PI);
  796. playerPosition.y =
  797. user.player.position.y +
  798. distance * Math.sin((move_angle / 360) * 2 * Math.PI);
  799. //找到邻居点,判断user.player.position与邻居点的距离,如果距离小于closestDis,就要更新camera的position
  800. let chooseBreakPointId = null;
  801. const breakPoint = this.breakPointInfo[breakPointId];
  802. const surroundPointIds = breakPoint.contact;
  803. const traceIds = [];
  804. user.player.angle.yaw = move_angle;
  805. traceIds.push(traceId);
  806. this.reply.traceIds = traceIds;
  807. this.reply['newUserStates'][0].userId = userId;
  808. this.reply['actionResponses'][0].traceId = traceId;
  809. this.reply['newUserStates'][0].playerState.player.angle.yaw = move_angle;
  810. this.reply['newUserStates'][0].playerState.camera.angle = JSON.parse(
  811. JSON.stringify(user.camera.angle),
  812. );
  813. this.reply['newUserStates'][0].playerState.camera.position = JSON.parse(
  814. JSON.stringify(user.camera.position),
  815. );
  816. this.reply['newUserStates'][0].playerState.cameraCenter = JSON.parse(
  817. JSON.stringify(breakPoint.position),
  818. );
  819. this.reply['newUserStates'][0].renderInfo.isMoving = 1;
  820. this.reply['actionResponses'][0].traceId = traceId;
  821. this.reply.mediaSrc = null;
  822. console.log('joystickjoystick:' + this.cameraInfos.length);
  823. if (surroundPointIds.length == 1) {
  824. console.log(
  825. 'joystick校验--->' + breakPointId + '-' + surroundPointIds[0],
  826. );
  827. return await this.moveDirect(
  828. playerPosition,
  829. closestDis,
  830. breakPointId,
  831. surroundPointIds[0],
  832. appId,
  833. userId,
  834. traceId,
  835. actionType,
  836. );
  837. }
  838. let count = 0;
  839. const neighPoints = [];
  840. //人在哪个角度
  841. let _angle = this.getAngle(
  842. breakPoint.position,
  843. { x: breakPoint.position.x + 1, y: breakPoint.position.y },
  844. playerPosition,
  845. );
  846. let singleInfo = null;
  847. for (let i = 0; i < surroundPointIds.length; ++i) {
  848. const neighPoint = this.breakPointInfo[surroundPointIds[i]];
  849. neighPoint.breakPointId = surroundPointIds[i];
  850. angle = this.getAngle(
  851. breakPoint.position,
  852. { x: breakPoint.position.x + 1, y: breakPoint.position.y },
  853. neighPoint.position,
  854. );
  855. //if(angle<45&&angle!=0){
  856. if (
  857. // Math.abs(angle - move_angle) < 45 &&
  858. // Math.abs(angle - move_angle) != 0
  859. Math.abs(angle - _angle) < 45 &&
  860. Math.abs(angle - _angle) != 0
  861. ) {
  862. neighPoint.angle = angle;
  863. neighPoints.push(neighPoint);
  864. ++count;
  865. } else if (Math.abs(angle - move_angle) == 0) {
  866. count = 2
  867. //console.log('handlejoysticktesttest:刚好45°的倍数')
  868. //debugger;
  869. break;
  870. // console.log(
  871. // 'joystick直走--->' + breakPointId + '-' + surroundPointIds[i],
  872. // );
  873. // return await this.moveDirect(
  874. // playerPosition,
  875. // closestDis,
  876. // breakPointId,
  877. // surroundPointIds[i],
  878. // appId,
  879. // userId,
  880. // traceId,
  881. // actionType,
  882. // );
  883. }
  884. //if (angle == 0 && Math.abs(360 - move_angle) < 45) {
  885. if (angle == 0 && Math.abs(360 - _angle) < 45) {
  886. neighPoint.angle = angle;
  887. neighPoints.push(neighPoint);
  888. ++count;
  889. }
  890. if (
  891. Math.abs(angle - move_angle) < 45 ||
  892. Math.abs(angle + 360 - move_angle) < 45
  893. ) {
  894. if (singleInfo == null) {
  895. singleInfo = {
  896. angle: angle,
  897. breakPointId: surroundPointIds[i],
  898. };
  899. }
  900. }
  901. }
  902. if (count == 2) {
  903. //人物移动
  904. user.player.position = JSON.parse(JSON.stringify(playerPosition));
  905. this.reply['newUserStates'][0].playerState.player.position = JSON.parse(
  906. JSON.stringify(playerPosition),
  907. );
  908. } else {
  909. if (singleInfo != null) {
  910. // console.log(
  911. // 'joystick校验--->' + breakPointId + '-' + singleInfo.breakPointId,
  912. // );
  913. //console.log('handlejoysticktesttest校验0角度:'+_angle+','+move_angle) //这个没办法,得换方案
  914. return await this.moveDirect(
  915. playerPosition,
  916. closestDis,
  917. breakPointId,
  918. singleInfo.breakPointId,
  919. appId,
  920. userId,
  921. traceId,
  922. actionType,
  923. );
  924. } else if (count == 1) {
  925. console.log(
  926. 'joystick校验--->' + breakPointId + '-' + neighPoints[0].breakPointId,
  927. );
  928. return await this.moveDirect(
  929. playerPosition,
  930. closestDis,
  931. breakPointId,
  932. neighPoints[0].breakPointId,
  933. appId,
  934. userId,
  935. traceId,
  936. actionType,
  937. );
  938. } else if (count == 0) {
  939. this.reply['newUserStates'][0].playerState.player.position = JSON.parse(
  940. JSON.stringify(user.player.position),
  941. );
  942. this.reply.actionResponses[0].actionType = actionType;
  943. return this.reply;
  944. }
  945. }
  946. //count == 2
  947. //超出范围了
  948. if (this.getDistance(playerPosition, breakPoint.position) > closestDis) {
  949. let offsetAngle1 = Math.abs(_angle - neighPoints[0].angle);
  950. if (neighPoints[0].angle == 0) {
  951. offsetAngle1 = Math.min(offsetAngle1, Math.abs(_angle - 360));
  952. }
  953. let offsetAngle2 = Math.abs(_angle - neighPoints[1].angle);
  954. if (neighPoints[1].angle == 0) {
  955. offsetAngle2 = Math.min(offsetAngle2, Math.abs(_angle - 360));
  956. }
  957. if (offsetAngle1 > offsetAngle2) {
  958. chooseBreakPointId = neighPoints[1].breakPointId;
  959. } else {
  960. chooseBreakPointId = neighPoints[0].breakPointId;
  961. }
  962. console.log(
  963. 'joystick镜头过渡--->' + breakPointId + '-' + chooseBreakPointId,
  964. );
  965. //this.reply.moveOver = true;
  966. return await this.moveCamera(
  967. breakPointId,
  968. chooseBreakPointId,
  969. appId,
  970. userId,
  971. traceId,
  972. actionType,
  973. );
  974. } else {
  975. user.player.position = JSON.parse(JSON.stringify(playerPosition));
  976. this.reply['newUserStates'][0].playerState.player.position = JSON.parse(
  977. JSON.stringify(user.player.position),
  978. );
  979. this.reply.actionResponses[0].actionType = actionType;
  980. const cameraInfo = this.getCameraInfo();
  981. if (cameraInfo != null) {
  982. console.log('joystick自由--->合并');
  983. this.reply['newUserStates'][0].playerState.camera.position =
  984. cameraInfo.camera_position;
  985. this.reply['newUserStates'][0].playerState.camera.angle =
  986. cameraInfo.camera_angle;
  987. if (cameraInfo.mediaSrc) {
  988. this.reply.mediaSrc = cameraInfo.mediaSrc;
  989. }
  990. // if (this.cameraInfos.length == 0) {
  991. // this.reply.moveOver = true;
  992. // }
  993. user.camera.position = JSON.parse(
  994. JSON.stringify(cameraInfo.camera_position),
  995. );
  996. user.camera.angle.yaw = cameraInfo.camera_angle.yaw;
  997. this.sendingFrameForJoystick = true;
  998. } else {
  999. console.log('joystick自由--->不合并');
  1000. }
  1001. return this.reply;
  1002. }
  1003. // }
  1004. // catch (error) {
  1005. // console.log('MoveService', error);
  1006. // debugger;
  1007. // return null;
  1008. // }
  1009. }
  1010. //沿着最合适的neighBreakPointId走
  1011. async moveDirect(
  1012. playerPosition,
  1013. closestDis,
  1014. breakPointId,
  1015. neighBreakPointId,
  1016. appId,
  1017. userId,
  1018. traceId,
  1019. actionType,
  1020. ) {
  1021. const breakPoint = this.breakPointInfo[breakPointId];
  1022. const user = this.users[userId];
  1023. const player_Position = this.getTarget(
  1024. playerPosition,
  1025. breakPoint.position,
  1026. this.breakPointInfo[neighBreakPointId].position,
  1027. );
  1028. // console.log('handlejoysticktesttest校验1线段:'+breakPointId+','+neighBreakPointId)
  1029. // console.log('handlejoysticktesttest校验2计算后的:'+JSON.stringify(player_Position))
  1030. // console.log('handlejoysticktesttest校验3人物变化前:'+JSON.stringify(user.player.position))
  1031. // console.log('handlejoysticktesttest校验4人物本应该的坐标:'+JSON.stringify(playerPosition))
  1032. if (player_Position != null) {
  1033. playerPosition.x = player_Position.x;
  1034. playerPosition.y = player_Position.y;
  1035. user.player.position = JSON.parse(JSON.stringify(playerPosition));
  1036. }
  1037. if (this.getDistance(playerPosition, breakPoint.position) > closestDis) {
  1038. //this.reply.moveOver = true;
  1039. return await this.moveCamera(
  1040. breakPointId,
  1041. neighBreakPointId,
  1042. appId,
  1043. userId,
  1044. traceId,
  1045. actionType,
  1046. );
  1047. } else {
  1048. this.reply['newUserStates'][0].playerState.player.position = JSON.parse(
  1049. JSON.stringify(user.player.position),
  1050. );
  1051. this.reply.actionResponses[0].actionType = actionType;
  1052. const cameraInfo = this.getCameraInfo();
  1053. if (cameraInfo != null) {
  1054. this.reply['newUserStates'][0].playerState.camera.position =
  1055. cameraInfo.camera_position;
  1056. this.reply['newUserStates'][0].playerState.camera.angle =
  1057. cameraInfo.camera_angle;
  1058. if (cameraInfo.mediaSrc) {
  1059. this.reply.mediaSrc = cameraInfo.mediaSrc;
  1060. }
  1061. // if (this.cameraInfos.length == 0) {
  1062. // this.reply.moveOver = true;
  1063. // }
  1064. user.camera.position = JSON.parse(
  1065. JSON.stringify(cameraInfo.camera_position),
  1066. );
  1067. user.camera.angle.yaw = cameraInfo.camera_angle.yaw;
  1068. this.sendingFrameForJoystick = true;
  1069. }
  1070. return this.reply;
  1071. }
  1072. }
  1073. async moveCamera(
  1074. breakPointId,
  1075. chooseBreakPointId,
  1076. appId,
  1077. userId,
  1078. traceId,
  1079. actionType,
  1080. ) {
  1081. const user = this.users[userId];
  1082. if (chooseBreakPointId == null) {
  1083. this.reply['newUserStates'][0].playerState.player.position = JSON.parse(
  1084. JSON.stringify(user.player.position),
  1085. );
  1086. this.reply.actionResponses[0].actionType = actionType;
  1087. return this.reply;
  1088. }
  1089. //判断人物离该邻接点的距离是否在最小路径内,如果是,跳到这个邻接点里
  1090. //相机纠正加过渡
  1091. else {
  1092. if (chooseBreakPointId == user.breakPointId) {
  1093. this.reply['newUserStates'][0].playerState.player.position = JSON.parse(
  1094. JSON.stringify(user.player.position),
  1095. );
  1096. return this.reply;
  1097. }
  1098. const angle = user.camera.angle.yaw % 45; //纠正需要
  1099. //通过user.camera.angle矫正相机的angle
  1100. const checkReplys = await this.modeifyCameraAngle(
  1101. angle,
  1102. userId,
  1103. traceId,
  1104. actionType,
  1105. );
  1106. for (let i = 0; i < checkReplys.length; ++i) {
  1107. //checkReplys[i].actionResponses[0].actionType = actionType;
  1108. this.addCameraInfo(
  1109. checkReplys[i]['newUserStates'][0].playerState.camera.position,
  1110. checkReplys[i]['newUserStates'][0].playerState.camera.angle,
  1111. checkReplys[i].mediaSrc,
  1112. );
  1113. }
  1114. //replys.push(checkReplys);
  1115. //读redis里的数据,按照frame_index的大小排序
  1116. /*
  1117. const key =
  1118. 'moveframe:app_id:' +
  1119. appId +
  1120. ':start_break_point_id:' +
  1121. breakPointId +
  1122. ':end_break_point_id:' +
  1123. chooseBreakPointId +
  1124. ':angle:' +
  1125. Math.floor(user.camera.angle.yaw / 45);
  1126. const moveFramesRes = await this.cacheService.get(key);
  1127. const moveFrames = JSON.parse(moveFramesRes);
  1128. */
  1129. const moveFrames = await this.getMoveFrames(appId,breakPointId,chooseBreakPointId,Math.floor(user.camera.angle.yaw / 45))
  1130. this.setCameraInfo(appId,moveFrames,breakPointId,chooseBreakPointId);
  1131. user.breakPointId = chooseBreakPointId;
  1132. const cameraInfo = this.getCameraInfo();
  1133. if (cameraInfo != null) {
  1134. this.reply['newUserStates'][0].playerState.camera.position =
  1135. cameraInfo.camera_position;
  1136. this.reply['newUserStates'][0].playerState.camera.angle =
  1137. cameraInfo.camera_angle;
  1138. user.camera.position = JSON.parse(
  1139. JSON.stringify(cameraInfo.camera_position),
  1140. );
  1141. user.camera.angle.yaw = cameraInfo.camera_angle.yaw;
  1142. if (cameraInfo.mediaSrc) {
  1143. this.reply.mediaSrc = cameraInfo.mediaSrc;
  1144. }
  1145. this.reply.moveStart = true;
  1146. this.sendingFrameForJoystick = true;
  1147. }
  1148. return this.reply;
  1149. }
  1150. }
  1151. setCameraInfo(appId, moveFrames, startBreakPointId, endBreakPointId) {
  1152. for (let i = 0; i < moveFrames.length; i += 5) {
  1153. moveFrames[i].endBreakPointId = endBreakPointId;
  1154. moveFrames[i].mediaSrc =
  1155. '/' +
  1156. appId +
  1157. '/' +
  1158. startBreakPointId +
  1159. '/' +
  1160. moveFrames[i].file_name.substring(
  1161. 0,
  1162. moveFrames[i].file_name.indexOf('.'),
  1163. ) +
  1164. '/' +
  1165. moveFrames[i].file_name +
  1166. '?m=' +
  1167. new Date().getTime();
  1168. if(startBreakPointId>endBreakPointId){
  1169. moveFrames[i].mediaSrc =
  1170. '/' +
  1171. appId +
  1172. '/' +
  1173. endBreakPointId +
  1174. '/' +
  1175. moveFrames[i].file_name.substring(
  1176. 0,
  1177. moveFrames[i].file_name.indexOf('.'),
  1178. ) +
  1179. '/' +
  1180. moveFrames[i].file_name +
  1181. '?m=' +
  1182. new Date().getTime();
  1183. }
  1184. this.cameraInfos.push(moveFrames[i]);
  1185. }
  1186. }
  1187. addCameraInfo(cameraPosition, cameraAngle, mediaSrc) {
  1188. this.cameraInfos.push({
  1189. camera_position: cameraPosition,
  1190. camera_angle: cameraAngle,
  1191. mediaSrc: mediaSrc,
  1192. });
  1193. }
  1194. getCameraInfo() {
  1195. if (this.cameraInfos.length > 0) {
  1196. const item = this.cameraInfos.shift();
  1197. return item;
  1198. } else {
  1199. return null;
  1200. }
  1201. }
  1202. complementFrame(userId) {
  1203. if (this.cameraInfos.length > 0) {
  1204. const user = this.users[userId];
  1205. const cameraInfo = this.cameraInfos.shift();
  1206. this.reply.traceIds = [];
  1207. this.reply['newUserStates'][0].userId = userId;
  1208. this.reply['actionResponses'][0].traceId = null;
  1209. this.reply['newUserStates'][0].playerState.player.angle.yaw =
  1210. user.player.angle.yaw;
  1211. this.reply['newUserStates'][0].playerState.player.position = JSON.parse(
  1212. JSON.stringify(user.player.position),
  1213. );
  1214. this.reply['newUserStates'][0].playerState.camera.angle = JSON.parse(
  1215. JSON.stringify(cameraInfo.camera_angle),
  1216. );
  1217. this.reply['newUserStates'][0].playerState.camera.position = JSON.parse(
  1218. JSON.stringify(cameraInfo.camera_position),
  1219. );
  1220. this.reply['newUserStates'][0].playerState.cameraCenter = JSON.parse(
  1221. JSON.stringify(user.player.position),
  1222. );
  1223. this.reply['newUserStates'][0].renderInfo.isMoving = 0;
  1224. this.reply['actionResponses'][0].traceId = null;
  1225. if (cameraInfo.mediaSrc) {
  1226. this.reply.mediaSrc = cameraInfo.mediaSrc;
  1227. }
  1228. // if(this.cameraInfos.length == 0){
  1229. // this.reply.moveOver = true;
  1230. // }
  1231. this.sendingFrameForJoystick = true;
  1232. return this.reply;
  1233. } else {
  1234. return null;
  1235. }
  1236. }
  1237. async modeifyCameraAngle(angle, userId, traceId, actionType) {
  1238. const checkReplys = [];
  1239. if (angle > 22) {
  1240. angle = 45 - angle;
  1241. for (let i = 0; i < angle; ++i) {
  1242. // console.warn('矫正一次:' + i);
  1243. const reply = await this.rotateService.rotateForAngle(userId, 1);
  1244. // console.warn(
  1245. // '矫正:' + reply.newUserStates[0].playerState.camera.angle.yaw,
  1246. // );
  1247. reply.traceIds = [];
  1248. reply.traceIds.push(traceId);
  1249. const actionResponse = this.rotateService.createActionResponse(
  1250. actionType,
  1251. traceId,
  1252. );
  1253. reply.actionResponses = [];
  1254. reply.actionResponses.push(actionResponse);
  1255. checkReplys.push(reply);
  1256. }
  1257. } else if (angle != 0) {
  1258. for (let i = angle; i > -1; --i) {
  1259. // console.warn('矫正一次:' + i);
  1260. const reply = await this.rotateService.rotateForAngle(userId, -1);
  1261. // console.warn(
  1262. // '矫正:' + reply.newUserStates[0].playerState.camera.angle.yaw,
  1263. // );
  1264. reply.traceIds = [];
  1265. reply.traceIds.push(traceId);
  1266. const actionResponse = this.rotateService.createActionResponse(
  1267. actionType,
  1268. traceId,
  1269. );
  1270. reply.actionResponses = [];
  1271. reply.actionResponses.push(actionResponse);
  1272. checkReplys.push(reply);
  1273. }
  1274. }
  1275. return checkReplys;
  1276. }
  1277. getTarget(position, position1, position2) {
  1278. const line = this.createLine1(position1, position2);
  1279. const join = this.getJoinLinePoint(position, line);
  1280. // if (this.isContainForSegment(join, position1, position2)) {
  1281. // return join;
  1282. // } else {
  1283. // return null;
  1284. // }
  1285. return join;
  1286. }
  1287. getDistance(position1, position2) {
  1288. return Math.sqrt(
  1289. (position1.x - position2.x) * (position1.x - position2.x) +
  1290. (position1.y - position2.y) * (position1.y - position2.y),
  1291. );
  1292. }
  1293. isContainForSegment(point, startPoint, endPoint) {
  1294. const minDis = 0.1;
  1295. const dis1 =
  1296. this.getDistance(startPoint, point) + this.getDistance(endPoint, point);
  1297. const dis2 = this.getDistance(startPoint, endPoint);
  1298. if (Math.abs(dis1 - dis2) < minDis) {
  1299. return true;
  1300. } else {
  1301. return false;
  1302. }
  1303. }
  1304. //两条线的交点
  1305. getIntersectionPoint(parameter1, parameter2) {
  1306. if (this.isParallel(parameter1, parameter2)) {
  1307. return null;
  1308. }
  1309. if (
  1310. typeof parameter1.a == 'undefined' &&
  1311. typeof parameter2.a != 'undefined'
  1312. ) {
  1313. if (parameter1.x) {
  1314. return {
  1315. x: parameter1.x,
  1316. y: parameter2.a * parameter1.x + parameter2.b,
  1317. };
  1318. } else if (parameter1.y) {
  1319. return {
  1320. x: (parameter1.y - parameter2.b) / parameter2.a,
  1321. y: parameter1.y,
  1322. };
  1323. }
  1324. } else if (
  1325. typeof parameter2.a == 'undefined' &&
  1326. typeof parameter1.a != 'undefined'
  1327. ) {
  1328. if (parameter2.x) {
  1329. return {
  1330. x: parameter2.x,
  1331. y: parameter1.a * parameter2.x + parameter1.b,
  1332. };
  1333. } else if (parameter2.y) {
  1334. return {
  1335. x: (parameter2.y - parameter1.b) / parameter1.a,
  1336. y: parameter2.y,
  1337. };
  1338. }
  1339. } else if (
  1340. typeof parameter2.a == 'undefined' &&
  1341. typeof parameter1.a == 'undefined'
  1342. ) {
  1343. if (parameter1.hasOwnProperty('x') && parameter2.hasOwnProperty('y')) {
  1344. return { x: parameter1.x, y: parameter2.y };
  1345. } else if (
  1346. parameter1.hasOwnProperty('y') &&
  1347. parameter2.hasOwnProperty('x')
  1348. ) {
  1349. return { x: parameter2.x, y: parameter1.y };
  1350. } else {
  1351. return null;
  1352. }
  1353. }
  1354. if (parameter1.a == parameter2.a) {
  1355. return null;
  1356. }
  1357. const joinpointx =
  1358. (parameter2.b - parameter1.b) / (parameter1.a - parameter2.a);
  1359. const joinpointy =
  1360. (parameter1.a * parameter2.b - parameter2.a * parameter1.b) /
  1361. (parameter1.a - parameter2.a);
  1362. const point = { x: joinpointx, y: joinpointy };
  1363. return point;
  1364. }
  1365. // 垂直线
  1366. getVerticalLine(line, point) {
  1367. if (typeof line.a === 'undefined') {
  1368. if (line.hasOwnProperty('x')) {
  1369. return { y: point.y };
  1370. } else if (line.hasOwnProperty('y')) {
  1371. return { x: point.x };
  1372. } else {
  1373. return null;
  1374. }
  1375. } else if (line.a == 0) {
  1376. return { x: point.x };
  1377. } else {
  1378. const tl = {} as any as VerticalLineType;
  1379. tl.a = -1 / line.a;
  1380. const result = this.createLine2(tl, point);
  1381. return result;
  1382. }
  1383. }
  1384. // 经过point且与line垂直的直线,该直线与line的交点
  1385. getJoinLinePoint(point, line) {
  1386. const verticalLine = this.getVerticalLine(line, point);
  1387. const join = this.getIntersectionPoint(line, verticalLine);
  1388. return join;
  1389. }
  1390. // 与lineA平行并且point在线上
  1391. createLine2(lineA, point) {
  1392. const parameter = {} as any as {
  1393. x: number;
  1394. y: number;
  1395. a: number;
  1396. b: number;
  1397. };
  1398. if (typeof lineA.a === 'undefined') {
  1399. if (typeof lineA.x !== 'undefined') {
  1400. parameter.x = point.x;
  1401. } else if (typeof lineA.y !== 'undefined') {
  1402. parameter.y = point.y;
  1403. }
  1404. } else {
  1405. parameter.a = lineA.a;
  1406. parameter.b = point.y - point.x * lineA.a;
  1407. }
  1408. return parameter;
  1409. }
  1410. createLine1(point1, point2) {
  1411. if (point1.x == point2.x && point1.y == point2.y) {
  1412. return null;
  1413. } else if (this.getFixed(Math.abs(point1.x - point2.x)) == 0) {
  1414. return { x: point1.x };
  1415. } else if (this.getFixed(Math.abs(point1.y - point2.y)) == 0) {
  1416. return { y: point1.y };
  1417. }
  1418. const parametera = (point1.y - point2.y) / (point1.x - point2.x);
  1419. const parameterb =
  1420. (point1.x * point2.y - point2.x * point1.y) / (point1.x - point2.x);
  1421. if (this.getFixed(parametera) == 0) {
  1422. return { y: this.getFixed(parameterb) };
  1423. }
  1424. const parameter = {
  1425. a: this.getFixed(parametera),
  1426. b: this.getFixed(parameterb),
  1427. };
  1428. return parameter;
  1429. }
  1430. //返回true表示平行
  1431. isParallel(line1, line2) {
  1432. if (typeof line1.a == 'undefined' && typeof line2.a == 'undefined') {
  1433. if (line1.hasOwnProperty('x') && line2.hasOwnProperty('x')) {
  1434. return true;
  1435. } else if (line1.hasOwnProperty('y') && line2.hasOwnProperty('y')) {
  1436. return true;
  1437. } else {
  1438. return false;
  1439. }
  1440. } else if (typeof line1.a == 'undefined' || typeof line2.a == 'undefined') {
  1441. return false;
  1442. } else if (this.getFixed(line1.a) == this.getFixed(line2.a)) {
  1443. return true;
  1444. } else {
  1445. return false;
  1446. }
  1447. }
  1448. getFixed(num) {
  1449. const decimal = 2;
  1450. return parseFloat(num.toFixed(decimal));
  1451. }
  1452. isPointInPoly(position, breakPointIds) {
  1453. const x = position.x;
  1454. const y = position.y;
  1455. let inside = false;
  1456. for (
  1457. let i = 0, j = breakPointIds.length - 1;
  1458. i < breakPointIds.length;
  1459. j = i++
  1460. ) {
  1461. const pt1 = this.breakPointInfo[breakPointIds[i]];
  1462. const pt2 = this.breakPointInfo[breakPointIds[j]];
  1463. const xi = pt1.x;
  1464. const yi = pt1.y;
  1465. const xj = pt2.x;
  1466. const yj = pt2.y;
  1467. const intersect =
  1468. yi > y != yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;
  1469. if (intersect) inside = !inside;
  1470. }
  1471. return inside;
  1472. }
  1473. }