Exemplo n.º 1
0
static void _apply_kernel (cairo_surface_t *surface,
                           const int *kernel,
                           int kernel_size)
{
  ol_assert (kernel_size > 0 && kernel_size % 2 == 1);
  ol_assert (kernel != NULL);
  static const int DIR[2][2] = {{0, 1}, {1, 0}};
  guint32 *pixels = (guint32*) cairo_image_surface_get_data (surface);
  int width = cairo_image_surface_get_width (surface);
  int height = cairo_image_surface_get_height (surface);
  if (pixels == NULL || width <= 0 || height <= 0)
  {
    ol_errorf ("Invalid image surface");
    return;
  }
  int kernel_orig = kernel_size / 2;
  int d, i, x, y;
  for (d = 0; d < 2; d++)
  {
    guint32 *old_pixels = g_new (guint32, width * height);
    memcpy (old_pixels, pixels, sizeof (guint32) * width * height);
    for (x = 0; x < width; x++)
      for (y = 0; y < height; y++)
      {
        struct _pixel final_value = {0};
        int sum = 0;
        for (i = 0; i < kernel_size; i++)
        {
          int x1 = x + (i - kernel_orig) * DIR[d][0];
          int y1 = y + (i - kernel_orig) * DIR[d][1];
          int index1 = _pos_to_index (x1, y1, width, height);
          if (index1 > 0)
          {
            sum += kernel[i];
            struct _pixel value = _num_to_pixel_with_factor (old_pixels[index1],
                                                             kernel[i]);
            _pixel_plus (&final_value, &value);
          }
        }
        int index = _pos_to_index (x, y, width, height);
        pixels[index] = _pixel_to_num_with_divisor (&final_value, sum);
      }
    g_free (old_pixels);
  }
}
Exemplo n.º 2
0
void GPathFinder::_alg_astarmod_3d(const g_ivec3 &st_pos, const g_ivec3 &end_pos)
{
  g_double ticks = GetTicks();

  priority_queue <G_WP*, vector<G_WP*>, G_WP> WPQueue;
  G_WP_TREE WPTree;
  
  WPQueue.push(WPTree.add_wp(st_pos, 0, 0, NULL));

  g_ivec3 min = st_pos - _init_params.search_radius;
  g_ivec3 max = st_pos + _init_params.search_radius;
  
  g_float end_dist = g_float((end_pos - st_pos).Length());
  g_float max_dist = end_dist*1.3f;
  if (max_dist < 25) max_dist += 10.0f;

  memset(_cached_cells, 0, _cache_buff_size*sizeof(G_CELL_INFO));

  G_WP *curr_wp;

  _last_path.state = psNotFound;

  while (WPQueue.size() > 0)
  {
	curr_wp = WPQueue.top();
	WPQueue.pop();
	//Проверяем является ли точка конечной
	g_ivec3 curr_pos = curr_wp->pos;
	if (curr_pos == end_pos)
	{
	  _last_path.state = psFound;
	  break;
	}
	//Проверяем максимальную длинну пути
	/*if (curr_wp->total_length > g_max_length)
	{
      _last_path.state = psTooLong;
	  break;
	}*/
	//Проверяем возможность прыжка
	g_int32 curr_jump = -2;
	for (g_uint32 i = 0; i < _init_params.jump_power + 2; i++)
	{
      g_ivec3 new_pos = curr_pos + g_ivec3(0,i,0);
	  if (!_pos_in_range(min,max,new_pos)) break;
	  g_int32 index = _pos_to_index(new_pos - min, _cache_area_size);
	  _get_info_at_pos(new_pos, _cached_cells[index]);
	  _cached_cells[index].state = csDenyMove;
      if (_cached_cells[index].move_resist == 255) break;
	  curr_jump++;
	}
	//Проверяем точки по осям
	for (g_int32 curr_dir = 0; curr_dir < 8; curr_dir++)
	{
	  g_int32 diag = curr_dir%2;
	  g_ivec3 targ_pos = curr_pos + move_dir[curr_dir];
	  if (!_pos_in_range(min,max,targ_pos)) continue;

	  G_CELL_INFO *up_cell_info[3], *down_cell_info[3];
	  
	  //Получаем инфу о соседних ячейках (сверху и снизу)
	  for (g_int32 i = 0; i < 3; i++)
	  {
		g_ivec3 new_pos = targ_pos + g_ivec3(0,i-1,0);
		g_int32 index = _pos_to_index(new_pos - min, _cache_area_size);
		_get_info_at_pos(new_pos, _cached_cells[index]);
		up_cell_info[i] = down_cell_info[i] = &_cached_cells[index];	
	  }
	  g_bool check_way_down = true;
	  // Проверяем перемещение вверх
	  for (g_int32 i = 0; i < curr_jump + 1; i++)
	  {
		if (up_cell_info[0]->move_resist == 255)
		{
		  g_bool no_wall = true;
		  if (i < 3) check_way_down = false;
		  if (diag == 1)
		  {
		    g_ivec3 new_pos[2] = {curr_pos + g_ivec3(0,i,0), curr_pos + g_ivec3(0,i,0)}; 
		    new_pos[0].x += move_dir[curr_dir].x;
		    new_pos[1].z += move_dir[curr_dir].z;
		  
            for (g_int32 j = 0; j < 4; j++)
		    {
		      g_int32 index = _pos_to_index(new_pos[j%2] - min, _cache_area_size);
			  _get_info_at_pos(new_pos[j%2], _cached_cells[index]);
			  if (_cached_cells[index].move_resist == 255)
			  {
			    no_wall = false; 
			    break;
			  }
			  new_pos[j%2].y++;
		    }
		  }
		  if (no_wall)
		    if ((up_cell_info[1]->state != csDenyMove) && (up_cell_info[2]->state != csDenyMove) &&
		  	    (up_cell_info[1]->move_resist < 255) && (up_cell_info[2]->move_resist < 255))
		    {
		      g_ivec3 new_pos = targ_pos + g_ivec3(0,i,0);
			  if (i < 2) up_cell_info[1]->state = csDenyMove;
			  g_float dist = g_float((end_pos - new_pos).Length());
			  if (dist < max_dist)
			  {
				G_WP *temp_wp = curr_wp;
				if (i > 0) //Если движемся вверх
				  temp_wp = WPTree.add_wp(curr_pos + g_ivec3(0,i,0), move_weight[2]*i, dist, curr_wp);
				WPQueue.push(WPTree.add_wp(new_pos, move_weight[diag], dist, temp_wp));
			  }
		    }
		}
		up_cell_info[0] = up_cell_info[1];
		up_cell_info[1] = up_cell_info[2];
		g_ivec3 new_pos = targ_pos + g_ivec3(0,2+i,0);
		g_int32 index = _pos_to_index(new_pos - min, _cache_area_size);
		_get_info_at_pos(new_pos, _cached_cells[index]);
		up_cell_info[2] = &_cached_cells[index];
	  }
	  // Проверяем перемещение вниз
	  if (check_way_down)
	    for (g_int32 i = 0; i <= g_int32(_init_params.jump_power); i++)
	    {
		  if ((down_cell_info[0]->move_resist == 255) ||
		  	  (down_cell_info[1]->move_resist == 255) ||
			  (down_cell_info[2]->move_resist == 255))
		  {
            if ((down_cell_info[1]->state != csDenyMove) && (down_cell_info[2]->state != csDenyMove) &&
			    (down_cell_info[1]->move_resist < 255) && (down_cell_info[2]->move_resist < 255))
		    {
              g_ivec3 new_pos = targ_pos + g_ivec3(0,-i,0);
			  if (i < 2) down_cell_info[1]->state = csDenyMove;
			  g_float dist = g_float((end_pos - new_pos).Length());
			  if (dist < max_dist)
			  {
				if (i > 0) //Если движемся вниз
				{
				  G_WP *temp_wp = WPTree.add_wp(targ_pos, move_weight[diag], dist, curr_wp);
			      WPQueue.push(WPTree.add_wp(new_pos, move_weight[3]*i, dist, temp_wp));
				}
				else
				  WPQueue.push(WPTree.add_wp(new_pos, move_weight[diag], dist, curr_wp));
			  }
		    }
		    break;
		  }
		  down_cell_info[2] = down_cell_info[1];
	      down_cell_info[1] = down_cell_info[0];
		  g_ivec3 new_pos = targ_pos + g_ivec3(0,-2-i,0);
		  g_int32 index = _pos_to_index(new_pos - min, _cache_area_size);
		  _get_info_at_pos(new_pos, _cached_cells[index]);
		  down_cell_info[0] = &_cached_cells[index];
	    }
	}
  }

  if (_last_path.state == psFound)
  {
    _last_path.path.total_length = 0;
	G_WAYPOINT new_wp;
	while (curr_wp->prev_wp != NULL)
	{  
	  new_wp.move_pos = curr_wp->pos;
	  new_wp.length = curr_wp->total_length - curr_wp->prev_wp->total_length;
	  _last_path.path.add_front_wp(new_wp);
	  curr_wp = curr_wp->prev_wp;
	}
	new_wp.move_pos = curr_wp->pos;
	new_wp.length = 0;
	_last_path.path.add_front_wp(new_wp);
  }
  WPTree.clear();

  g_char res_str[100];
  sprintf_s(res_str,100,"wp: %d st: %d dist: %.3f", WPTree.way_points.size(), _last_path.state, max_dist);
  CheckTimeAndWriteToFile(ticks, res_str);
}