コード例 #1
0
ファイル: trv_raycast.c プロジェクト: acassis/ros2_nuttx
static void trv_ray_ycaster34(FAR struct trv_raycast_s *result)
{
  struct trv_rect_list_s *list; /* Points to the current P plane rectangle */
  struct trv_rect_data_s *rect; /* Points to the rectangle data */
  trv_coord_t rely;             /* Relative position of the Y plane */
  trv_coord_t absx;             /* Absolute X position at rely given yaw */
  trv_coord_t absz;             /* Absolute Z position at rely given pitch */
  trv_coord_t lastrely1 = -1;   /* Last relative Y position processed */
  trv_coord_t lastrely2 = -1;   /* Last relative Y position processed */
  int32_t dxdy;                 /* Rate of change of X wrt Y (double) */
  int32_t dzdy;                 /* Rate of change of Z wrt Y (double) */

  /* At a viewing angle of 180 degrees, no intersections with the line x = bXi
   * are possible!
   */

  if (g_camera.yaw == ANGLE_180)
    {
      return;
    }

  /* Pre-calculate the rate of change of X and Z with respect to Y */
  /* The negative inverted tangent is equal to the rate of change of X with
   * respect to the Y-axis.  The cotangent is stored at double the the
   * "normal" scaling.
   */

  dxdy = -g_cot_table(g_camera.yaw - ANGLE_180);

  /* Determine the rate of change of the Z with respect to Y.  The tangent
   * is "double" precision; the cosecant is "double" precision.  dzdy will
   * be retained as "double" precision.
   */

  dzdy = qTOd(g_adj_tanpitch * ABS(g_csc_table[g_camera.yaw]));

  /* Look at every rectangle lying in a Y plane */
  /* This logic should be improved at some point so that non-visible planes
   * are "pruned" from the list prior to ray casting!
   */

  for (list = g_ray_yplane.tail; list; list = list->blink)
    {
      rect = &list->d;

      /* Search for a rectangle which lies "before" the current camera
       * position
       */

      if (rect->plane < g_camera.y)
        {
          /* get the Y distance to the plane */

          rely = g_camera.y - rect->plane;

          /* g_ray_yplane is an ordered list, if we have already hit something
           * closer, then we can abort the casting now.
           */

          if (rely > result->ydist)
            {
              return;
            }

          /* Calculate the Y position at this relative X position.  We can skip
           * this step if we are processing another rectangle at the same relx
           * distance.
           */

           if (rely != lastrely1)
            {
              int32_t deltax;  /* Scale == "triple" */

              /* The dxdy is stored at double the"normal" scaling -- so deltax
               * is "triple" precision
               */

              deltax    = dxdy * ((int32_t) rely);
              absx      = tTOs(deltax) + g_camera.x; /* back to "single" */
              lastrely1 = rely;
            }

          /* Check if this X position intersects the rectangle */

          if (absx >= rect->hstart && absx <= rect->hend)
            {

              /* The X position lies in the rectangle.  Now, calculate the
               * Z position at this relative X position.  We can skip this
               * step if we are processing another rectangle at the same
               * relx distance.
               */

              if (rely != lastrely2)
                {
                  int32_t deltaz;      /* Scale == TRIPLE */

                  /* The dzdy is stored at double the"normal" scaling -- so
                   * deltaz is "triple" precision
                   */

                  deltaz    = dzdy * ((int32_t) rely);
                  absz      = tTOs(deltaz) + g_camera.z; /* Back to single */
                  lastrely2 = rely;
                }

              /* Check if this Z position intersects the rectangle */

              if (absz >= rect->vstart && absz <= rect->vend)
                {

                  /* We've got a potential hit, let's see what it is */
                  /* Check if we just hit an ordinary opaque wall */

                  if (IS_NORMAL(rect))
                    {
                      /* Yes..Save the parameters associated with the normal
                       * wall hit
                       */

                      result->rect = rect;
                      result->type = MK_HIT_TYPE(BACK_HIT, Y_HIT);
                      result->xpos = absx;
                      result->ypos = absz;

                      result->xdist = ABS(absx - g_camera.x);
                      result->ydist = rely;
                      result->zdist = ABS(absz - g_camera.z);

                      /* Terminate Y casting */

                      return;
                    }
                  else if (IS_DOOR(rect))
                    {
                      /* Check if the door is in motion. */

                      if (!IS_MOVING_DOOR(rect))
                        {
                          /* Save the parameters associated with the normal
                           * door hit
                           */

                          result->rect = rect;
                          result->type = MK_HIT_TYPE(BACK_HIT, Y_HIT);
                          result->xpos = absx;
                          result->ypos = absz;

                          result->xdist = ABS(absx - g_camera.x);
                          result->ydist = rely;
                          result->zdist = ABS(absz - g_camera.z);

                          /* Terminate Y casting */

                          return;
                        }

                      /* The door is in motion, the Z-position to see if we can
                       * see under the door
                       */

                      else if (absz > g_opendoor.zbottom)
                        {
                          /* Save the parameters associated with the moving
                           * door hit
                           */

                          result->rect = rect;
                          result->type = MK_HIT_TYPE(BACK_HIT, Y_HIT);
                          result->xpos = absx;
                          result->ypos = absz - g_opendoor.zdist;

                          result->xdist = ABS(absx - g_camera.x);
                          result->ydist = rely;
                          result->zdist = ABS(absz - g_camera.z);

                          /* Terminate Y casting */

                          return;
                        }
                    }

                  /* Otherwise, it must be a transparent wall.  We'll need to
                   * make our decision based upon the pixel that we hit
                   */

                  /* Check if the pixel at this location is visible */

                  else if (GET_BACK_PIXEL(rect, absx, absz) != INVISIBLE_PIXEL)
                    {
                      /* Its visible, save the parameters associated with the
                       * transparent wall hit
                       */

                      result->rect = rect;
                      result->type = MK_HIT_TYPE(BACK_HIT, Y_HIT);
                      result->xpos = absx;
                      result->ypos = absz;

                      result->xdist = ABS(absx - g_camera.x);
                      result->ydist = rely;
                      result->zdist = ABS(absz - g_camera.z);

                      /* Terminate Y casting */

                      return;
                    }
                }
            }
        }
    }
}
コード例 #2
0
ファイル: logic.c プロジェクト: pa3zo6/costar_keyboard
void key_press(uint8_t k) {
  uint8_t i;

  key[k].pressed = 0x80 | active_layer;
  if(current_dualrole_key != 255) {
    if(!dualrole_modifier_possible && IS_NORMAL(k) && WAS_TAPPABLE_LAYERSHIFT(current_dualrole_key) ) {//TODO do we need dualrole_modifier_possible ?
      for(i = 5; i > 0; i--)
        queue[i] = queue[i-1];
      queue[0] = current_dualrole_key;

      active_layer = DISENGAGE_LAYER(current_dualrole_key);

      send();

      for(i = 0; i < 6; i++)
        if(queue[i]==current_dualrole_key)
          break;
      for(i = i; i < 6; i++)
        queue[i] = queue[i+1];
      send();

      current_dualrole_key = 255;
      dualrole_tap_possible = false;
      dualrole_modifier_possible = false;
      dualrole_modifier_impossible_until_tick = 0;
      dualrole_tap_impossible_after_tick = 0;
    }
  }

  if(IS_TAPPABLE_MODIFIER(k)) {
    dualrole_tap_possible = true;
    dualrole_modifier_possible = false;
    dualrole_tap_impossible_after_tick = tick + LONGEST_TAP_DURATION;
    dualrole_modifier_impossible_until_tick = tick + SHORTEST_MODIFIER_DURATION;
    current_dualrole_key = k;

    mod_keys |= GET_TAPPABLE_MODIFIER(k);
    send();
  }
  else if(IS_TAPPABLE_LAYERSHIFT(k)) {
    dualrole_tap_possible = true;
    dualrole_modifier_possible = false;
    dualrole_tap_impossible_after_tick = tick + LONGEST_TAP_DURATION;
    dualrole_modifier_impossible_until_tick = tick + SHORTEST_MODIFIER_DURATION;
    current_dualrole_key = k;

    active_layer = ENGAGE_LAYER(k);
  }
  else if(IS_LAYERLOCK(k)) {
    dualrole_tap_possible = true;
    dualrole_modifier_possible = false;
    current_dualrole_key = k;

    active_layer = ENGAGE_LAYER(k);
  }
  else if(IS_MODIFIER(k)) {
    mod_keys |= KEY(k);

    if(IS_MODDED(k)) {
      mod_keys |= ~GET_ADDITIONAL_MODIFIERS(k);
    }

    dualrole_tap_possible = false;
    send();
  }
  else {
    dualrole_tap_possible = false;
    for(i = 5; i > 0; i--)
      queue[i] = queue[i-1];
    queue[0] = k;
    send();
  }
}
コード例 #3
0
ファイル: trv_raycast.c プロジェクト: acassis/ros2_nuttx
static void trv_ray_xcaster14(FAR struct trv_raycast_s *result)
{
  struct trv_rect_list_s *list; /* Points to the current X plane rectangle */
  struct trv_rect_data_s *rect; /* Points to the rectangle data */
  trv_coord_t relx;             /* Relative position of the X plane */
  trv_coord_t absy;             /* Absolute Y position at relx given yaw */
  trv_coord_t absz;             /* Absolute Z position at relx given pitch */
  trv_coord_t lastrelx1 = -1;   /* Last relative X position processed */
  trv_coord_t lastrelx2 = -1;   /* Last relative X position processed */
  int32_t dydx;                 /* Rate of change of Y wrt X (double) */
  int32_t dzdx;                 /* Rate of change of Z wrt X (double) */

  /* At a viewing angle of 270 degrees, no intersections with the g_ray_xplanes
   * are possible!
   */

  if (g_camera.yaw == ANGLE_270)
    {
      return;
    }

  /* Pre-calculate the rate of change of Y and Z with respect to X */
  /* The tangent is equal to the rate of change of Y with respect to the
   * X-axis.  The tangent is stored at double the "normal" scaling.
   */

  dydx = TAN(g_camera.yaw);

  /* Determine the rate of change of the Z with respect to X. The tangent is
   * "double" precision; the secant is "double" precision.  dzdx will be
   * retained as "double" precision.
   */

  dzdx = qTOd(g_adj_tanpitch * ABS(g_sec_table[g_camera.yaw]));

  /* Look at every rectangle lying in the X plane */
  /* This logic should be improved at some point so that non-visible planes
   * are "pruned" from the list prior to ray casting!
   */

  for (list = g_ray_xplane.head; list; list = list->flink)
    {
      rect = &list->d;

      /* Search for a rectangle which lies "beyond" the current camera
       * position
       */

      if (rect->plane > g_camera.x)
        {
          /* get the X distance to the plane */

          relx = rect->plane - g_camera.x;

#if 0
          /* g_ray_xplane is an ordered list, if we have already hit something
           * closer, then we can abort the casting now.
           */

          if (relx > result->xdist)
            {
              return;
            }
#endif

          /* Calculate the Y position at this relative X position.  We can skip
           * this step if we are processing another rectangle at the same relx
           * distance.
           */

          if (relx != lastrelx1)
            {
              int32_t deltay;  /* Scale == "triple" */

              /* The dydx is stored at double the"normal" scaling -- so
               * deltay is "triple" precision
               */

              deltay    = dydx * ((int32_t) relx);
              absy      = tTOs(deltay) + g_camera.y; /* back to "single" */
              lastrelx1 = relx;
            }

          /* Check if this Y position intersects the rectangle */

          if (absy >= rect->hstart && absy <= rect->hend)
            {
              /* The Y position lies in the rectangle.  Now, calculate the
               * theZ position at this relative X position.  We can skip
               * this step if we are processing another rectangle at the
               * same relx distance.
               */

              if (relx != lastrelx2)
                {
                  int32_t deltaz;      /* Scale == TRIPLE */

                  /* The dzdx is stored at double the"normal" scaling -- so
                   * deltaz is "triple" precision
                   */

                  deltaz    = dzdx * ((int32_t) relx);
                  absz      = tTOs(deltaz) + g_camera.z; /* Back to single */
                  lastrelx2 = relx;
                }

              /* Check if this Z position intersects the rectangle */

              if (absz >= rect->vstart && absz <= rect->vend)
                {
                  /* We've got a potential hit, let's see what it is */
                  /* Check if we just hit an ordinary opaque wall */

                  if (IS_NORMAL(rect))
                    {
                      /* Yes..Save the parameters associated with the normal
                       * wall hit
                       */

                      result->rect = rect;
                      result->type = MK_HIT_TYPE(FRONT_HIT, X_HIT);
                      result->xpos = absy;
                      result->ypos = absz;

                      result->xdist = relx;
                      result->ydist = ABS(absy - g_camera.y);
                      result->zdist = ABS(absz - g_camera.z);

                      /* Terminate X casting */

                      return;
                    }
                  else if (IS_DOOR(rect))
                    {
                      /* Check if the door is in motion. */

                      if (!IS_MOVING_DOOR(rect))
                        {
                          /* Save the parameters associated with the normal
                           * door hit
                           */

                          result->rect = rect;
                          result->type = MK_HIT_TYPE(FRONT_HIT, X_HIT);
                          result->xpos = absy;
                          result->ypos = absz;

                          result->xdist = relx;
                          result->ydist = ABS(absy - g_camera.y);
                          result->zdist = ABS(absz - g_camera.z);

                          /* Terminate X casting */

                          return;
                        }

                      /* The door is in motion, the Z-position to see if we can
                       * see under the door
                       */

                      else if (absz > g_opendoor.zbottom)
                        {
                          /* Save the parameters associated with the moving
                           * door hit
                           */

                          result->rect = rect;
                          result->type = MK_HIT_TYPE(FRONT_HIT, X_HIT);
                          result->xpos = absy;
                          result->ypos = absz - g_opendoor.zdist;

                          result->xdist = relx;
                          result->ydist = ABS(absy - g_camera.y);
                          result->zdist = ABS(absz - g_camera.z);

                          /* Terminate X casting */

                          return;
                        }
                    }

                  /* Otherwise, it must be a transparent wall.  We'll need to
                   * make our decision based upon the pixel that we hit
                   */

                  /* Check if the pixel at this location is visible */

                  else if (GET_FRONT_PIXEL(rect, absy, absz) != INVISIBLE_PIXEL)
                    {
                      /* Its visible, save the parameters associated with the
                       * transparent wall hit
                       */

                      result->rect = rect;
                      result->type = MK_HIT_TYPE(FRONT_HIT, X_HIT);
                      result->xpos = absy;
                      result->ypos = absz;

                      result->xdist = relx;
                      result->ydist = ABS(absy - g_camera.y);
                      result->zdist = ABS(absz - g_camera.z);

                      /* Terminate X casting */

                      return;
                    }
                }
            }
        }
    }
}