Example #1
0
static seg_t *FindFastSeg(superblock_t *seg_list, const bbox_t *bbox)
{
  seg_t *best_H = NULL;
  seg_t *best_V = NULL;

  int mid_x = (bbox->minx + bbox->maxx) / 2;
  int mid_y = (bbox->miny + bbox->maxy) / 2;

  EvaluateFastWorker(seg_list, &best_H, &best_V, mid_x, mid_y);

  int H_cost = -1;
  int V_cost = -1;

  if (best_H)
    H_cost = EvalPartition(seg_list, best_H, 99999999);

  if (best_V)
    V_cost = EvalPartition(seg_list, best_V, 99999999);

# if DEBUG_PICKNODE
  PrintDebug("FindFastSeg: best_H=%p (cost %d) | best_V=%p (cost %d)\n",
             best_H, H_cost, best_V, V_cost);
# endif

  if (H_cost < 0 && V_cost < 0)
    return NULL;

  if (H_cost < 0) return best_V;
  if (V_cost < 0) return best_H;

  return (V_cost < H_cost) ? best_V : best_H;
}
Example #2
0
/* returns FALSE if cancelled */
static int PickNodeWorker(superblock_t *part_list, 
    superblock_t *seg_list, seg_t ** best, int *best_cost,
    int *progress, int prog_step)
{
  seg_t *part;

  int num;
  int cost;

  /* use each Seg as partition */
  for (part=part_list->segs; part; part = part->next)
  {
    if (cur_comms->cancelled)
      return FALSE;

#   if DEBUG_PICKNODE
    PrintDebug("PickNode:   %sSEG %p  sector=%d  (%1.1f,%1.1f) -> (%1.1f,%1.1f)\n",
      part->linedef ? "" : "MINI", part, 
      part->sector ? part->sector->index : -1,
      part->start->x, part->start->y, part->end->x, part->end->y);
#   endif

    /* something for the user to look at */
    (*progress) += 1;

    if ((*progress % prog_step) == 0)
    {
      cur_comms->build_pos++;
      DisplaySetBar(1, cur_comms->build_pos);
      DisplaySetBar(2, cur_comms->file_pos + cur_comms->build_pos / 100);
    }

    /* ignore minisegs as partition candidates */
    if (! part->linedef)
      continue;
    
    cost = EvalPartition(seg_list, part, *best_cost);

    /* seg unsuitable or too costly ? */
    if (cost < 0 || cost >= *best_cost)
      continue;

    /* we have a new better choice */
    (*best_cost) = cost;

    /* remember which Seg */
    (*best) = part;
  }

  DisplayTicker();

  /* recursively handle sub-blocks */

  for (num=0; num < 2; num++)
  {
    if (part_list->subs[num])
      PickNodeWorker(part_list->subs[num], seg_list, best, best_cost,
        progress, prog_step);
  }

  return TRUE;
}
Example #3
0
//
// PickNode
//
// Find the best seg in the seg_list to use as a partition line.
//
seg_t *PickNode(superblock_t *seg_list, int depth,
    node_t ** stale_nd, int *stale_opposite)
{
  seg_t *best=NULL;

  int best_cost=INT_MAX;

  int progress=0;
  int prog_step=1<<24;
  int build_step=0;

# if DEBUG_PICKNODE
  PrintDebug("PickNode: BEGUN (depth %d)\n", depth);
# endif

  /* compute info for showing progress */
  if (depth <= 6)
  {
    static int depth_counts[7] = { 248, 100, 30, 10, 6, 4, 2 };
    
    int total = seg_list->real_num + seg_list->mini_num;

    build_step = depth_counts[depth];
    prog_step = 1 + ((total - 1) / build_step);

    if (total / prog_step < build_step)
    {
      cur_comms->build_pos += build_step - total / prog_step;
      build_step = total / prog_step;

      DisplaySetBar(1, cur_comms->build_pos);
      DisplaySetBar(2, cur_comms->file_pos + cur_comms->build_pos / 100);
    }
  }

  DisplayTicker();

  /* -AJA- another (optional) optimisation, when building just the GL
   *       nodes.  We assume that the original nodes are reasonably
   *       good choices, and re-use them as much as possible, saving
   *       *heaps* of time on really large levels.
   */
  if (*stale_nd && seg_list->real_num >= SEG_REUSE_THRESHHOLD)
  {
    best = FindSegFromStaleNode(seg_list, *stale_nd, stale_opposite);

#   if DEBUG_PICKNODE
    PrintDebug("PickNode: Trying stale node %p\n", best);
#   endif

    if (best && EvalPartition(seg_list, best, best_cost) < 0)
    {
      best = NULL;
 
#     if DEBUG_PICKNODE
      PrintDebug("PickNode: Stale node unsuitable !\n");
#     endif
    }

    if (best)
    {
      /* update progress */
      cur_comms->build_pos += build_step;
      DisplaySetBar(1, cur_comms->build_pos);
      DisplaySetBar(2, cur_comms->file_pos + cur_comms->build_pos / 100);

#     if DEBUG_PICKNODE
      PrintDebug("PickNode: Using Stale node (%1.1f,%1.1f) -> (%1.1f,%1.1f)\n",
          best->start->x, best->start->y, best->end->x, best->end->y);
#     endif

      return best;
    }
  }

  (*stale_nd) = NULL;

  if (FALSE == PickNodeWorker(seg_list, seg_list, &best, &best_cost, 
      &progress, prog_step))
  {
    /* hack here : BuildNodes will detect the cancellation */
    return NULL;
  }

# if DEBUG_PICKNODE
  if (! best)
  {
    PrintDebug("PickNode: NO BEST FOUND !\n");
  }
  else
  {
    PrintDebug("PickNode: Best has score %d.%02d  (%1.1f,%1.1f) -> (%1.1f,%1.1f)\n", 
      best_cost / 100, best_cost % 100, best->start->x, best->start->y,
      best->end->x, best->end->y);
  }
# endif

  /* all finished, return best Seg */
  return best;
}