Example #1
0
 protected override void Execute(List <CommandEntity> entities)
 {
     foreach (var e in entities)
     {
         var playerEntities = m_contexts.game.GetEntitiesWithPlayerId(e.commandOwner.value);
         if (playerEntities.Count == 0)
         {
             continue;
         }
         var playerEntity = playerEntities.SingleEntity();
         if (e.moveCommand.value.LengthSquared() > 0.1f)
         {
             float   angularSpeed = playerEntity.angularSpeed.value;
             Vector3 dir          = playerEntity.direction.value;
             Vector3 targetDir    = e.moveCommand.value;
             // dot(dir, rot90CCW(targetDir))
             float angle = 0f;
             float dot   = dir.X * -targetDir.Y + dir.Y * targetDir.X;
             // parallel/antiparallel
             if (Math.Abs(dot) <= ANGLE_TOLERANCE)
             {
                 Services.Get <ILogService>().LogInfo("parallel/antiparallel");
                 if (Vector3.Dot(dir, targetDir) < 0f)
                 {
                     angle = angularSpeed * m_timeService.FrameInterval;
                 }
             }
             // targetDir is in right of dir,
             else if (dot > float.Epsilon)
             {
                 Services.Get <ILogService>().LogInfo("targetDir is in right of dir " + dot.ToString());
                 angle = -angularSpeed * m_timeService.FrameInterval;
                 float d = MathHelper.ToDegrees((float)Math.Acos(dot)) - 90f;
                 // over rotation
                 if (Math.Abs(angle) > Math.Abs(d))
                 {
                     angle = d;
                 }
             }
             // targetDir is in left of dir
             else
             {
                 Services.Get <ILogService>().LogInfo("targetDir is in left of dir" + dot.ToString());
                 angle = angularSpeed * m_timeService.FrameInterval;
                 float d = MathHelper.ToDegrees((float)Math.Acos(dot)) - 90f;
                 // over rotate
                 if (Math.Abs(angle) > Math.Abs(d))
                 {
                     angle = d;
                 }
             }
             var quat       = Quaternion.CreateFromAxisAngle(Vector3.Backward, MathHelper.ToRadians(angle));
             var targetQuat = Quaternion.Multiply(playerEntity.rotation.value, quat);
             playerEntity.ReplaceRotation(targetQuat);
             playerEntity.ReplaceDirection(Vector3.Normalize(Vector3.Transform(Vector3.Right, targetQuat)));
             playerEntity.ReplaceSpeed(playerEntity.speed.maxValue, playerEntity.speed.maxValue);
         }
         else
         {
             playerEntity.ReplaceSpeed(0f, playerEntity.speed.maxValue);
         }
     }
 }