move.service.ts 52 KB

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