123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578 |
- import { Injectable } from '@nestjs/common';
- import { CacheService } from 'src/cache/cache.service';
- import { RotateService } from 'src/rotate/rotate.service';
- // import { SceneService } from 'src/scene/scene.service';
- @Injectable()
- export class MoveService {
- constructor(
- private cacheService: CacheService,
- private rotateService: RotateService,
- ) {}
- private Actions = {
- Clicking: 1,
- Rotation: 1014,
- Joystick: 15,
- };
- public users = this.rotateService.users;
- private reply = {
- traceIds: [],
- vehicle: null,
- mediaSrc: null,
- newUserStates: [
- {
- userId: 'dcff36ae4fc1d',
- playerState: {
- roomTypeId: '',
- person: 0,
- avatarId: '',
- skinId: '',
- roomId: '',
- isHost: false,
- isFollowHost: false,
- skinDataVersion: '',
- avatarComponents: '',
- nickName: '',
- movingMode: 0,
- attitude: '',
- areaName: '',
- pathName: '',
- pathId: '',
- avatarSize: 1,
- extra: '',
- prioritySync: false,
- player: {
- position: { x: -700, y: 0, z: 0 },
- angle: {
- pitch: 0,
- yaw: 0,
- roll: 0,
- },
- },
- camera: {
- position: { x: -1145, y: 0, z: 160 },
- angle: {
- pitch: 0,
- yaw: 0,
- roll: 0,
- },
- },
- cameraCenter: { x: -700, y: 0, z: 0 },
- },
- renderInfo: {
- renderType: 0,
- videoFrame: null,
- cameraStateType: 3,
- isMoving: 1,
- needIfr: 0,
- isVideo: 0,
- stillFrame: 0,
- isRotating: 0,
- isFollowing: 0,
- clientPanoTitlesBitmap: [],
- clientPanoTreceId: '',
- prefetchVideoId: '',
- noMedia: false,
- },
- event: null,
- relation: 1,
- },
- ],
- actionResponses: [
- {
- actionType: 1,
- pointType: 100,
- extra: '',
- traceId: '',
- packetId: '',
- nps: [],
- peopleNum: 0,
- zoneId: '',
- echoMsg: '',
- reserveDetail: null,
- userWithAvatarList: [],
- newUserStates: [],
- code: 0,
- msg: '',
- },
- ],
- getStateType: 0,
- code: 0,
- msg: 'OK',
- };
- init(app_id, userId) {
- const user = {
- appId: null,
- userId: null,
- breakPointId: null,
- roomId: null,
- player: {
- position: { x: -700, y: 0, z: 0 },
- angle: {
- pitch: 0,
- yaw: 0,
- roll: 0,
- },
- },
- camera: {
- position: { x: -1145, y: 0, z: 160 },
- angle: {
- pitch: 0,
- yaw: 0,
- roll: 0,
- },
- },
- rotateInfo: {
- frameIndex: 0,
- horizontal_move: 0,
- mediaSrc: null,
- },
- moveInfo: {},
- // traceIds: [],
- // actionResponses:[]
- };
- user.appId = app_id;
- user.userId = userId;
- user.breakPointId = 100;
- this.users[userId] = user;
- }
- async move(pathArray, actionRequest) {
- try {
- const userId = actionRequest['user_id'];
- const traceId = actionRequest['trace_id'];
- const actionType = actionRequest['action_type'];
- const user = this.users[userId];
- const appId = user.appId;
- const path = pathArray || [100, 101, 102]; //需要计算路径
- const angle = user.camera.angle.yaw % 44; //纠正需要
- console.log('矫正前-相机:' + user.camera.angle.yaw);
- const replys = {};
- const traceIds = [];
- traceIds.push(traceId);
- //纠正,旋转传到缓存里
- const checkReplys = [];
- // console.log('矫正: ' + angle + ' 度');
- for (let i = 0; i < angle; ++i) {
- // console.warn('矫正一次:' + i);
- const reply = await this.rotateService.rotateForAngle(userId, 1);
- // console.warn(
- // '矫正:' + reply.newUserStates[0].playerState.camera.angle.yaw,
- // );
- reply.traceIds = [];
- reply.traceIds.push(traceId);
- const actionResponse = this.rotateService.createActionResponse(
- actionType,
- traceId,
- );
- reply.actionResponses = [];
- reply.actionResponses.push(actionResponse);
- checkReplys.push(reply);
- }
- replys['P' + user.breakPointId + 'T' + user.breakPointId] = checkReplys;
- //replys.push(checkReplys);
- //过渡传到缓存里
- this.reply.traceIds = traceIds;
- this.reply['newUserStates'][0].userId = userId;
- this.reply['actionResponses'][0].traceId = traceId;
- console.log('矫正后-相机:' + user.camera.angle.yaw);
- const index = Math.round(user.camera.angle.yaw / 44); //过渡需要
- for (let i = 0; i < path.length - 1; ++i) {
- let pathReplys = [];
- const start_break_point_id = path[i];
- const end_break_point_id = path[i + 1];
- //读redis里的数据,按照frame_index的大小排序
- const key =
- 'moveframe:app_id:' +
- appId +
- ':start_break_point_id:' +
- start_break_point_id +
- ':end_break_point_id:' +
- end_break_point_id +
- ':angle:' +
- index;
- const moveFramesRes = await this.cacheService.get(key);
- if (moveFramesRes == null) {
- return replys;
- }
- const moveFrames = JSON.parse(moveFramesRes);
- //读redis里的数据
- const startBreakPointRes = await this.cacheService.get(
- 'breakpoints:app_id:' +
- appId +
- ':break_point_id:' +
- start_break_point_id,
- );
- const startBreakPoint = JSON.parse(startBreakPointRes);
- const endBreakPointRes = await this.cacheService.get(
- 'breakpoints:app_id:' +
- appId +
- ':break_point_id:' +
- end_break_point_id,
- );
- const endBreakPoint = JSON.parse(endBreakPointRes);
- pathReplys = this.createCacheReplys(
- moveFrames,
- traceId,
- userId,
- start_break_point_id,
- startBreakPoint.position,
- endBreakPoint.position,
- );
- if (i == path.length - 2) {
- pathReplys[pathReplys.length - 1][
- 'newUserStates'
- ][0].renderInfo.isMoving = 0;
- }
- //replys.push(pathReplys);
- replys['P' + start_break_point_id + 'T' + end_break_point_id] =
- pathReplys;
- }
- return replys;
- } catch (error) {
- console.log('MoveService', error);
- }
- }
- createCacheReplys(
- moveFrames,
- traceId,
- userId,
- breakPointId,
- startPosition,
- endPosition,
- ) {
- const replys = [];
- const angle =
- -1 *
- this.getAngle(
- startPosition,
- {
- x: startPosition.x + 1,
- y: startPosition.y,
- },
- endPosition,
- );
- for (let i = 1; i < moveFrames.length; i += 5) {
- const moveFrame = moveFrames[i];
- const reply = JSON.parse(JSON.stringify(this.reply));
- reply.traceIds.push(traceId);
- reply['newUserStates'][0].userId = userId;
- reply['newUserStates'][0].playerState.player.position = {
- x:
- startPosition.x +
- ((endPosition.x - startPosition.x) / moveFrames.length) * i,
- y:
- startPosition.y +
- ((endPosition.y - startPosition.y) / moveFrames.length) * i,
- z:
- startPosition.z +
- ((endPosition.z - startPosition.z) / moveFrames.length) * i,
- };
- reply['newUserStates'][0].playerState.player.angle.yaw = angle;
- reply['newUserStates'][0].playerState.camera.position =
- moveFrame.camera_position;
- reply['newUserStates'][0].playerState.camera.angle =
- moveFrame.camera_angle;
- reply['newUserStates'][0].playerState.cameraCenter =
- reply['newUserStates'][0].playerState.player.position;
- reply['actionResponses'][0].traceId = traceId;
- reply.mediaSrc =
- '/' +
- '0000000001' +
- '/' +
- breakPointId +
- '/' +
- moveFrame.file_name.substring(0, moveFrame.file_name.indexOf('.')) +
- '/' +
- moveFrame.file_name +
- '?m=' +
- new Date().getTime();
- replys.push(reply);
- }
- return replys;
- }
- //需要通知user,人物和相机走到哪一个呼吸点位了
- updateUser(userId, breakPointId, lastReply) {
- const user = this.users[userId];
- user.breakPointId = breakPointId;
- // debugger;
- user.player.position =
- lastReply['newUserStates'][0].playerState.player.position;
- user.player.angle = lastReply['newUserStates'][0].playerState.player.angle;
- user.camera.position =
- lastReply['newUserStates'][0].playerState.camera.position;
- user.camera.angle = lastReply['newUserStates'][0].playerState.camera.angle;
- }
- async getBreakPoints(actionRequest) {
- const userId = actionRequest['user_id'];
- const traceId = actionRequest['trace_id'];
- const actionType = actionRequest['action_type'];
- const user = this.users[userId];
- const appId = user.appId;
- const breakPointId = user.breakPointId;
- const reply = {
- actionType: actionType,
- pointType: 100,
- extra: '',
- traceId: traceId,
- packetId: '',
- nps: [],
- peopleNum: 0,
- zoneId: '',
- echoMsg: '',
- reserveDetail: null,
- userWithAvatarList: [],
- newUserStates: [],
- code: 0,
- msg: '',
- };
- //const breakPoints = await this.cacheService.get('breakpoints:app_id:'+appId+':break_point_id:'+breakPointId);
- //获取redis表全部元素,'breakpoints:app_id:'+appId+':break_point_id:'开头的
- const keys = await this.cacheService.keys(`breakpoints:app_id:${appId}*`);
- for (let i = 0; i < keys.length; ++i) {
- const breakPointRes = await this.cacheService.get(keys[i]);
- const breakPoint = JSON.parse(breakPointRes);
- const position = breakPoint.position;
- reply['nps'].push({
- position: position,
- breakPointId: breakPoint.breakPointId,
- });
- }
- return reply;
- }
- getAngle(point, point1, point2) {
- const x1 = point1.x - point.x;
- const y1 = point1.y - point.y;
- const x2 = point2.x - point.x;
- const y2 = point2.y - point.y;
- const dot = x1 * x2 + y1 * y2;
- const det = x1 * y2 - y1 * x2;
- const angle = (Math.atan2(det, dot) / Math.PI) * 180;
- return (angle + 360) % 360;
- }
- async stop(traceId, userId, movePointIds, cameraAngle, playerAngle) {
- const breakPointId = movePointIds.substring(movePointIds.indexOf('-') + 1);
- const user = this.users[userId];
- user.breakPointId = breakPointId;
- const appId = user.appId;
- const breakPointRes = await this.cacheService.get(
- 'breakpoints:app_id:' + appId + ':break_point_id:' + breakPointId,
- );
- const breakPoint = JSON.parse(breakPointRes);
- user.player.position = breakPoint.position;
- user.player.angle = playerAngle;
- const rotateKey =
- 'rotateframe:app_id:' +
- appId +
- ':frame_index:' +
- cameraAngle.yaw +
- ':break_point_id:' +
- breakPointId;
- const rotateDataRes = await this.cacheService.get(rotateKey);
- const rotateData = JSON.parse(rotateDataRes);
- user.camera.position = rotateData.cameraPosition;
- user.camera.angle = rotateData.cameraAngle;
- const reply = JSON.parse(JSON.stringify(this.reply));
- reply.traceIds.push(traceId);
- reply['newUserStates'][0].userId = userId;
- reply['newUserStates'][0].playerState.player.position = breakPoint.position;
- reply['newUserStates'][0].playerState.player.angle = playerAngle;
- reply['newUserStates'][0].playerState.camera.position =
- rotateData.cameraPosition;
- reply['newUserStates'][0].playerState.camera.angle = rotateData.cameraAngle;
- reply['newUserStates'][0].playerState.cameraCenter = breakPoint.position;
- reply['actionResponses'][0].traceId = traceId;
- reply.mediaSrc =
- '/' +
- '0000000001' +
- '/' +
- breakPointId +
- '/' +
- rotateData.directory +
- '/' +
- rotateData.fileName +
- '?m=' +
- new Date().getTime();
- reply['newUserStates'][0].renderInfo.isMoving = 0;
- return reply;
- }
- async joystick(actionRequest) {
- try {
- const userId = actionRequest['user_id'];
- const traceId = actionRequest['trace_id'];
- const dir_action = actionRequest['dir_action'];
- const actionType = actionRequest['action_type'];
- const user = this.users[userId];
- const appId = user.appId;
- //只是移动人物
- if (dir_action.speed_level < 7) {
- user.player.angle.yaw = dir_action.move_angle;
- this.reply['newUserStates'][0]['userId'] = userId;
- this.reply['newUserStates'][0].playerState.player.position =
- user.player.position;
- this.reply['newUserStates'][0].playerState.player.angle.yaw =
- dir_action.move_angle;
- this.reply['newUserStates'][0].playerState.camera.position =
- user.camera.position;
- this.reply['newUserStates'][0].playerState.camera.angle =
- user.camera.angle;
- this.reply['newUserStates'][0].playerState.cameraCenter =
- user.camera.position;
- this.reply['actionResponses'][0].traceId = traceId;
- return this.reply;
- }
- //选择过渡
- else {
- const breakPointId = user.breakPointId;
- //先矫正
- const breakPointRes = await this.cacheService.get(
- 'breakpoints:app_id:' + appId + ':break_point_id:' + breakPointId,
- );
- if (breakPointRes == null) {
- return null;
- }
- const breakPoint = JSON.parse(breakPointRes);
- const contact = breakPoint.contact;
- let chooseBreakPointId = null;
- let minOffsetAngle = null;
- let neighPoint = null;
- let angle = 0;
- for (let i = 0; i < contact.length; ++i) {
- neighPoint = await this.cacheService.get(
- 'breakpoints:app_id:' + appId + ':break_point_id:' + contact[i],
- ); //通过contact[i],去redis里找
- //通过user.player.position;neighPoint.position获得角度
- neighPoint = JSON.parse(neighPoint);
- angle = this.getAngle(
- user.player.position,
- { x: user.player.position.x + 1, y: user.player.position.y },
- neighPoint.position,
- );
- if (
- Math.abs(angle - dir_action.move_angle) < 45 &&
- (minOffsetAngle == null ||
- Math.abs(angle - dir_action.move_angle) < minOffsetAngle)
- ) {
- chooseBreakPointId = contact[i];
- minOffsetAngle = Math.abs(angle - dir_action.move_angle);
- }
- }
- if (chooseBreakPointId == null) {
- return null;
- } else {
- //人物矫正
- user.player.angle.yaw = angle;
- //相机纠正
- const replys = [];
- const traceIds = [];
- traceIds.push(traceId);
- const checkReplys = [];
- angle = user.camera.angle.yaw % 44; //纠正需要
- for (let i = 0; i < angle; ++i) {
- const reply = await this.rotateService.rotateForAngle(userId, 1);
- reply.traceIds = [];
- reply.traceIds.push(traceId);
- const actionResponse = this.rotateService.createActionResponse(
- actionType,
- traceId,
- );
- reply.actionResponses = [];
- reply.actionResponses.push(actionResponse);
- checkReplys.push(reply);
- }
- replys.push(checkReplys);
- //过渡
- //读redis里的数据,按照frame_index的大小排序
- const key =
- 'moveframe:app_id:' +
- appId +
- ':start_break_point_id:' +
- breakPointId +
- ':end_break_point_id:' +
- chooseBreakPointId +
- ':angle:' +
- (user.camera.angle.yaw % 44);
- const moveFramesRes = await this.cacheService.get(key);
- if (moveFramesRes == null) {
- return replys;
- }
- const moveFrames = JSON.parse(moveFramesRes);
- //读redis里的数据
- const startBreakPointRes = await this.cacheService.get(
- 'breakpoints:app_id:' + appId + ':break_point_id:' + breakPointId,
- );
- const startBreakPoint = JSON.parse(startBreakPointRes);
- const endBreakPointRes = await this.cacheService.get(
- 'breakpoints:app_id:' +
- appId +
- ':break_point_id:' +
- chooseBreakPointId,
- );
- const endBreakPoint = JSON.parse(endBreakPointRes);
- const pathReplys = this.createCacheReplys(
- moveFrames,
- traceId,
- userId,
- breakPointId,
- startBreakPoint.position,
- endBreakPoint.position,
- );
- replys.push(pathReplys);
- return replys;
- }
- }
- } catch (error) {
- console.log('MoveService', error);
- }
- }
- }
|