gemercheung 3 yıl önce
ebeveyn
işleme
bbf2a37bf9
2 değiştirilmiş dosya ile 181 ekleme ve 60 silme
  1. 98 56
      src/move/move.service.ts
  2. 83 4
      src/scene/scene.service.ts

+ 98 - 56
src/move/move.service.ts

@@ -282,6 +282,7 @@ export class MoveService implements OnModuleInit {
           userId,
           start_break_point_id,
           end_break_point_id,
+          false,
         );
 
         if (i == path.length - 2) {
@@ -305,6 +306,7 @@ export class MoveService implements OnModuleInit {
     userId,
     startBreakPointId,
     endBreakPointId,
+    isFromUser,
   ) {
     const replys = [];
     const startPosition = this.breakPointInfo[startBreakPointId].position;
@@ -317,7 +319,7 @@ export class MoveService implements OnModuleInit {
       },
       endPosition,
     );
-
+    const user = this.users[userId];
     let i;
     for (i = 1; i < moveFrames.length; i += 3) {
       const moveFrame = moveFrames[i];
@@ -325,22 +327,36 @@ export class MoveService implements OnModuleInit {
       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;
+      if (!isFromUser) {
+        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.cameraCenter =
+          reply['newUserStates'][0].playerState.player.position;
+      } else {
+        reply['newUserStates'][0].playerState.player.position = JSON.parse(
+          JSON.stringify(user.player.position),
+        );
+        reply['newUserStates'][0].playerState.player.angle.yaw =
+          user.player.angle.yaw;
+        reply['newUserStates'][0].playerState.cameraCenter = JSON.parse(
+          JSON.stringify(user.player.position),
+        );
+      }
 
-      reply['newUserStates'][0].playerState.camera.position =
-        moveFrame.camera_position;
+      reply['newUserStates'][0].playerState.camera.position = JSON.parse(
+        JSON.stringify(moveFrame.camera_position),
+      );
       if (i == 1) {
         console.log('move-2' + moveFrame.camera_angle.yaw);
       }
@@ -352,8 +368,6 @@ export class MoveService implements OnModuleInit {
 
       reply['newUserStates'][0].playerState.camera.angle =
         moveFrame.camera_angle;
-      reply['newUserStates'][0].playerState.cameraCenter =
-        reply['newUserStates'][0].playerState.player.position;
       reply['newUserStates'][0].renderInfo.isMoving = 1;
       reply['actionResponses'][0].traceId = traceId;
 
@@ -379,19 +393,32 @@ export class MoveService implements OnModuleInit {
       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;
+      if (!isFromUser) {
+        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.cameraCenter =
+          reply['newUserStates'][0].playerState.player.position;
+      } else {
+        reply['newUserStates'][0].playerState.player.position = JSON.parse(
+          JSON.stringify(user.player.position),
+        );
+        reply['newUserStates'][0].playerState.player.angle.yaw =
+          user.player.angle.yaw;
+        reply['newUserStates'][0].playerState.cameraCenter = JSON.parse(
+          JSON.stringify(user.player.position),
+        );
+      }
 
       reply['newUserStates'][0].playerState.camera.position =
         moveFrame.camera_position;
@@ -403,8 +430,6 @@ export class MoveService implements OnModuleInit {
 
       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;
 
@@ -434,7 +459,6 @@ export class MoveService implements OnModuleInit {
     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;
@@ -569,20 +593,20 @@ export class MoveService implements OnModuleInit {
       const appId = user.appId;
 
       const replys = [];
-      const step = 1;
-      const closestDis = 20; //小于这个距离就跳到邻居呼吸点
+      const step = 0.3;
+      const closestDis = 90; //小于这个距离就跳到邻居呼吸点
       const distance = step * dir_action.speed_level;
       let angle = null;
-
-      // debugger;
+      let move_angle = dir_action.move_angle + user.camera.angle.yaw;
+      move_angle = move_angle % 360;
       //TODO 临时增加断言
       const playerPosition: Point = { x: 0, y: 0, z: 0 };
       playerPosition.x =
         user.player.position.x +
-        distance * Math.cos((dir_action.move_angle / 360) * 2 * Math.PI);
+        distance * Math.cos((move_angle / 360) * 2 * Math.PI);
       playerPosition.y =
         user.player.position.y +
-        distance * Math.sin((dir_action.move_angle / 360) * 2 * Math.PI);
+        distance * Math.sin((move_angle / 360) * 2 * Math.PI);
 
       //找到邻居点,判断user.player.position与邻居点的距离,如果距离小于closestDis,就要更新camera的position
       let chooseBreakPointId = null;
@@ -591,13 +615,12 @@ export class MoveService implements OnModuleInit {
       //const neighAngles = [];
       const traceIds = [];
 
-      user.player.angle.yaw = dir_action.move_angle;
+      user.player.angle.yaw = move_angle;
       traceIds.push(traceId);
       this.reply.traceIds = traceIds;
       this.reply['newUserStates'][0].userId = userId;
       this.reply['actionResponses'][0].traceId = traceId;
-      this.reply['newUserStates'][0].playerState.player.angle.yaw =
-        dir_action.move_angle;
+      this.reply['newUserStates'][0].playerState.player.angle.yaw = move_angle;
 
       this.reply['newUserStates'][0].playerState.camera.angle = JSON.parse(
         JSON.stringify(user.camera.angle),
@@ -635,7 +658,7 @@ export class MoveService implements OnModuleInit {
 
       //判断_angle与angle的差在45以内的个数,两个的话表示可以走
       let count = 0;
-      let neighPoints = [];
+      const neighPoints = [];
       _angle = this.getAngle(
         breakPoint.position,
         { x: breakPoint.position.x + 1, y: breakPoint.position.y },
@@ -664,34 +687,43 @@ export class MoveService implements OnModuleInit {
           angle += 360;
         }
         //neighAngles.push(angle);
-        if(Math.abs(angle - _angle)<45){
+        if (Math.abs(angle - _angle) < 45) {
+          neighPoint.angle = angle;
           neighPoints.push(neighPoint);
           ++count;
-        }
-        else if(angle == 0 && _angle>315){
+        } else if (angle == 0 && _angle > 315) {
+          neighPoint.angle = angle;
           neighPoints.push(neighPoint);
           ++count;
+        } else if (Math.abs(angle - _angle) == 0) {
+          neighPoint.angle = angle;
+          neighPoints.push(neighPoint);
         }
       }
-      
-      if(count==2 || _angle%45 ==0){
+
+      if (count == 2 || _angle % 45 == 0) {
         //人物移动
         user.player.position = JSON.parse(JSON.stringify(playerPosition));
         this.reply['newUserStates'][0].playerState.player.position = JSON.parse(
           JSON.stringify(playerPosition),
         );
-      }
-      else{
+      } else {
         return this.reply;
       }
 
       //超出范围了
-      if(this.getDistance(playerPosition,breakPoint.position)>50){
-        //debugger;
-        if(this.getDistance(playerPosition,neighPoints[0].position)>this.getDistance(playerPosition,neighPoints[1].position)){
+      if (this.getDistance(playerPosition, breakPoint.position) > closestDis) {
+        //角度是45的倍数
+        if (_angle % 45 == 0) {
+          chooseBreakPointId = neighPoints[0].breakPointId;
+        } else if (
+          //this.getDistance(playerPosition, neighPoints[0].position) >
+          //this.getDistance(playerPosition, neighPoints[1].position)
+          Math.abs(_angle - neighPoints[0].angle) >
+          Math.abs(_angle - neighPoints[1].angle)
+        ) {
           chooseBreakPointId = neighPoints[1].breakPointId;
-        }
-        else{
+        } else {
           chooseBreakPointId = neighPoints[0].breakPointId;
         }
       }
@@ -702,6 +734,9 @@ export class MoveService implements OnModuleInit {
       //判断人物离该邻接点的距离是否在最小路径内,如果是,跳到这个邻接点里
       //相机纠正加过渡
       else {
+        if (chooseBreakPointId == user.breakPointId) {
+          return this.reply;
+        }
         angle = user.camera.angle.yaw % 45; //纠正需要
         //通过user.camera.angle矫正相机的angle
         const checkReplys = await this.modeifyCameraAngle(
@@ -731,8 +766,15 @@ export class MoveService implements OnModuleInit {
           userId,
           breakPointId,
           chooseBreakPointId,
+          true,
         );
         replys.push(pathReplys);
+        user.breakPointId = chooseBreakPointId;
+        const lastFrame = moveFrames[moveFrames.length - 1];
+        user.camera.position = JSON.parse(
+          JSON.stringify(lastFrame.camera_position),
+        );
+        user.camera.angle.yaw = lastFrame.camera_angle.yaw;
         return replys;
       }
     } catch (error) {

+ 83 - 4
src/scene/scene.service.ts

@@ -79,6 +79,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
   private isHoldingStream = false;
   private lastMovingPointArray: MovingLastUpdateType[] = [];
   private latestWalkingRequest: any; // 最新waking的接收值
+  private latestJoystickRequest: any; // 最新joystick的接收值
 
   private moveSliceLastFrame = new BehaviorSubject<MovingLastUpdateType>(null);
   private moveSliceLastFrameSub: any;
@@ -498,14 +499,25 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
   }
 
   /***
+   * joystick main core
+   */
+  async joystick(request: JoystickRequest) {
+    this.latestJoystickRequest = request;
+    // if (!this.onMoving.getValue()) {
+    this.handlejoystick(request);
+    // }
+  }
+
+  /***
    * joystick
    */
 
-  async joystick(request: JoystickRequest) {
+  async handlejoystick(request: JoystickRequest) {
     try {
       //const joystickRes = await this.moveService.joystick(request);
       const joystickRes = await this.moveService.seqExeJoystick(request);
       // 有数据 [0]是rotate数据,[1-infinity]是walking数据
+      console.log('joystickRes-1', joystickRes);
       if (Array.isArray(joystickRes)) {
         // 处理第一个镜头数据
         const rotateCamData = joystickRes[0];
@@ -522,7 +534,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
         // 二维数组 做move 序列, move类型
         if (joystickRes?.length >= 1) {
           for (let i = 1; i < joystickRes.length; i++) {
-            console.log('joystickRes', joystickRes[i]);
+            console.log('joystickRes-2', joystickRes[i]);
             Array.from(joystickRes[i]).forEach(
               (item: StreamReplyType, index: number) => {
                 const dir = this.isHeaderOrLast(
@@ -530,6 +542,20 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
                   joystickRes[i].length - 1,
                 );
                 item.DIR = dir ? 1 : 3;
+                // 将每段最后一个推入lastMovingPointArray
+                if (index === joystickRes[i].length - 1) {
+                  this.lastMovingPointArray.push({
+                    mediaSrc: item.mediaSrc,
+                    metaData: item,
+                  });
+                }
+                console.log(
+                  'joystick:' +
+                    JSON.stringify(
+                      joystickRes[i][index]['newUserStates'][0].playerState
+                        .camera.position,
+                    ),
+                );
               },
             );
           }
@@ -542,9 +568,60 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
         } else {
           console.warn('joystick-move无数据');
         }
+
+        //TODO joystick中断逻辑
+        // if (!this.moveSliceLastFrameSub) {
+        //   this.moveSliceLastFrameSub = this.moveSliceLastFrame.subscribe(
+        //     async (frame: MovingLastUpdateType) => {
+        //       if (this.latestJoystickRequest && this.onMoving.value) {
+        //         console.log('中断的小段', frame);
+        //         // this.moveQueue.complete();
+        //         // this.moveQueue.of('');
+        //         // TODO 中断move队列 ?优化如何清空
+        //         this.moveQueueSubscription.unsubscribe();
+        //         this.moveQueueSubscription = null;
+        //         //step1 执行stop方法
+        //         const metaData: StreamReplyType = frame.metaData;
+        //         const newUserStates: NewUserStatesType =
+        //           metaData.newUserStates.find(
+        //             (item) => item.userId === this.user_id,
+        //           );
+        //         const trace_id = metaData.traceIds[0];
+        //         const userId = newUserStates.userId;
+        //         const breakPointId = metaData.endBreakPointId;
+        //         const cameraAngle = newUserStates.playerState.camera.angle;
+        //         const playerAngle = newUserStates.playerState.player.angle;
+        //         console.log(
+        //           'stop-data',
+        //           trace_id,
+        //           userId,
+        //           cameraAngle,
+        //           cameraAngle,
+        //         );
+        //         const redisMeta = await this.moveService.stop(
+        //           trace_id,
+        //           userId,
+        //           breakPointId,
+        //           cameraAngle,
+        //           playerAngle,
+        //         );
+        //         console.log('stop-redisMeta', redisMeta);
+        //         // 2. 中断重新joystick
+        //         this.handlejoystick(this.latestWalkingRequest);
+        //       }
+        //     },
+        //   );
+        // }
       } else {
-        console.warn('joystick-接收人物数据', JSON.stringify(joystickRes));
-        this.streamService.pushNormalDataToStream(joystickRes);
+        console.log(
+          'joystick:' +
+            '->' +
+            JSON.stringify(
+              joystickRes['newUserStates'][0].playerState.camera.position,
+            ),
+        );
+        // console.warn('joystick-接收人物数据', JSON.stringify(joystickRes));
+        // this.streamService.pushNormalDataToStream(joystickRes);
       }
     } catch (error) {
       console.error('joystick错误', error);
@@ -578,6 +655,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
         DIR: frame.DIR,
         mType: type,
       };
+      console.log('this.lastMovingPointArray', this.lastMovingPointArray);
       this.moveQueue.next(stream);
     });
   }
@@ -646,6 +724,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
           const lastReply = currentMeta.metaData;
           // console.log('path-update', breakPointId);
           this.moveService.updateUser(userId, breakPointId, lastReply);
+          //debugger
           this.lastMovingPointArray.splice(isLastFrameIndex, 1);
           //TODO 队列每一段最后one frame
           this.moveSliceLastFrame.next(currentMeta);