move.service.ts 53 KB

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