Пример #1
0
 /*!
    \param   r   Rectangle to remove overlaps with.
 */
 void Atlas::Prune( const rect_t& r )
 {
    for (auto it = unused.begin(); it!=unused.end(); it++ )
    {
       if (rect_overlap(r, *it))
       {
          it = unused.erase(it);
          it--;
       }
    }
    for (auto i = unused.begin(); i!=unused.end(); ++i )
       for (auto j = i; j != unused.end(); ++j)
       {
          if ( i == j ) continue;
          if (rect_iscontained(*i, *j))
          {
             i = unused.erase(i);
             i--;
             break;
          }
          if (rect_iscontained(*j, *i))
          {
             j = unused.erase(j);
             j--;
          }
       }
 }
Пример #2
0
static struct PendNode *
find_pending(struct PendNode *cptr)
{
    struct PendNode *ptr;

    for (ptr = pendups.First; ptr != NULL; ptr = ptr->nextnode) {
        if (rect_overlap(ptr, cptr) == 0)
            continue;
        return (ptr);
    }
    return (NULL);
}
Пример #3
0
   /*
      Splits the atlas by removing the rectangle given from free space.

      \param   r   a rectangle to use as a splitting surface.
   */
   void Atlas::Split( const rect_t& r )
   {
      rect_t temp;

      for( auto r2 : unused )
      {
         if (rect_overlap( r, r2 ))
         {
            if (r.x < r2.x + r2.w && r.x + r.w > r2.x)
            {
               if (r.y > r2.y && r.y < r2.y + r2.h)
               {
                  temp = r2;
                  temp.h = r.y - r2.y;
                  if (temp.h > minsize)
                     unused.push_front(temp);
               }
               if (r.y + r.h < r2.y + r2.h)
               {
                  temp = r2;
                  temp.y = r.y + r.h;
                  temp.h = r2.y + r2.h - (r.y + r.h);
                  if (temp.h > minsize)
                     unused.push_front(temp);
               }
            }
            if (r.y < r2.y + r2.h && r.y + r.h > r2.y)
            {
               if (r.x > r2.x && r.x < r2.x + r2.w)
               {
                  temp = r2;
                  temp.w = r.x - r2.x;
                  if (temp.w > minsize)
                     unused.push_front(temp);
               }
               if (r.x + r.w < r2.x + r2.w)
               {
                  temp = r2;
                  temp.x = r.x + r.w;
                  temp.w = r2.x + r2.w - (r.x + r.w);
                  if (temp.w > minsize)
                     unused.push_front(temp);
               }
            }
         }
      }
   }
Пример #4
0
void do_physics_to_it(body_t *body, rect_list_t *terr_rects, rect_list_t *plat_rects){
	rect_t *start = rect_create();
	rect_match_to(start, body->rect);
	
	rect_node_t *iter;
	
	body->flags &= ~BLOCKED_MASK;
	
	body->rect->x += body->vx;
	iter = terr_rects->head;
	while(iter != NULL){
		if(rect_overlap(body->rect, iter->data)){
			if(body->vx > 0 && rect_get_r_edge(body->rect) >= rect_get_l_edge(iter->data)){
				body->vx = 0;
				rect_set_r_edge(body->rect, rect_get_l_edge(iter->data));
				body->flags |= BLOCKED_R;
			}else if(body->vx < 0 && rect_get_l_edge(body->rect) <= rect_get_r_edge(iter->data)){
				body->vx = 0;
				rect_set_l_edge(body->rect, rect_get_r_edge(iter->data));
				body->flags |= BLOCKED_L;
			}
			break;
		}
		iter = iter->next;
	}

	body->rect->y += body->vy;
	iter = terr_rects->head;
	while(iter != NULL){
		if(rect_overlap(body->rect, iter->data)){
			if(body->vy > 0 && rect_get_b_edge(body->rect) >= rect_get_t_edge(iter->data)){
				body->vy = 0;
				rect_set_b_edge(body->rect, rect_get_t_edge(iter->data));
				body->flags |= BLOCKED_D;
			}else if(body->vy < 0 && rect_get_t_edge(body->rect) <= rect_get_b_edge(iter->data)){
				body->vy = 0;
				rect_set_t_edge(body->rect, rect_get_b_edge(iter->data));
				body->flags |= BLOCKED_U;
			}
			break;
		}
		iter = iter->next;
	}
	
	if(body->vy > 0 && !(body->flags & PLAT_DROP)){
		iter = plat_rects->head;
		while(iter != NULL){
			if(rect_overlap(body->rect, iter->data)){
				if(rect_get_b_edge(start) <= rect_get_t_edge(iter->data)){
					body->vy = 0;
					rect_set_b_edge(body->rect, rect_get_t_edge(iter->data));
					body->flags |= BLOCKED_D;
					break;
				}

			}
			iter = iter->next;
		}
	}
	
	rect_delete(start);
}
Пример #5
0
// chain function - this function does the actual processing
static GstFlowReturn
gst_bgfg_acmmm2003_chain(GstPad *pad, GstBuffer *buf)
{
    GstBgFgACMMM2003 *filter;

    // sanity checks
    g_return_val_if_fail(pad != NULL, GST_FLOW_ERROR);
    g_return_val_if_fail(buf != NULL, GST_FLOW_ERROR);

    filter = GST_BGFG_ACMMM2003(GST_OBJECT_PARENT(pad));

    filter->image->imageData = (gchar*) GST_BUFFER_DATA(buf);

    // the bg model must be initialized with a valid image; thus we delay its
    // creation until the chain function
    if (filter->model == NULL) {
        filter->model = cvCreateFGDStatModel(filter->image, NULL);

        ((CvFGDStatModel*)filter->model)->params.minArea           = filter->min_area;
        ((CvFGDStatModel*)filter->model)->params.erode_iterations  = filter->n_erode_iterations;
        ((CvFGDStatModel*)filter->model)->params.dilate_iterations = filter->n_dilate_iterations;

        return gst_pad_push(filter->srcpad, buf);
    }

    cvUpdateBGStatModel(filter->image, filter->model, -1);

    // send mask event, if requested
    if (filter->send_mask_events) {
        GstStructure *structure;
        GstEvent     *event;
        GArray       *data_array;
        IplImage     *mask;

        // prepare and send custom event with the mask surface
        mask = filter->model->foreground;
        data_array = g_array_sized_new(FALSE, FALSE, sizeof(mask->imageData[0]), mask->imageSize);
        g_array_append_vals(data_array, mask->imageData, mask->imageSize);

        structure = gst_structure_new("bgfg-mask",
                                      "data",      G_TYPE_POINTER, data_array,
                                      "width",     G_TYPE_UINT,    mask->width,
                                      "height",    G_TYPE_UINT,    mask->height,
                                      "depth",     G_TYPE_UINT,    mask->depth,
                                      "channels",  G_TYPE_UINT,    mask->nChannels,
                                      "timestamp", G_TYPE_UINT64,  GST_BUFFER_TIMESTAMP(buf),
                                      NULL);

        event = gst_event_new_custom(GST_EVENT_CUSTOM_DOWNSTREAM, structure);
        gst_pad_push_event(filter->srcpad, event);
        g_array_unref(data_array);

        if (filter->display) {
            // shade the regions not selected by the acmmm2003 algorithm
            cvXorS(mask,          CV_RGB(255, 255, 255), mask,          NULL);
            cvSubS(filter->image, CV_RGB(191, 191, 191), filter->image, mask);
            cvXorS(mask,          CV_RGB(255, 255, 255), mask,          NULL);
        }
    }

    if (filter->send_roi_events) {
        CvSeq        *contour;
        CvRect       *bounding_rects;
        guint         i, j, n_rects;

        // count # of contours, allocate array to store the bounding rectangles
        for (contour = filter->model->foreground_regions, n_rects = 0;
             contour != NULL;
             contour = contour->h_next, ++n_rects);

        bounding_rects = g_new(CvRect, n_rects);

        for (contour = filter->model->foreground_regions, i = 0; contour != NULL; contour = contour->h_next, ++i)
            bounding_rects[i] = cvBoundingRect(contour, 0);

        for (i = 0; i < n_rects; ++i) {
            // skip collapsed rectangles
            if ((bounding_rects[i].width == 0) || (bounding_rects[i].height == 0)) continue;

            for (j = (i + 1); j < n_rects; ++j) {
                // skip collapsed rectangles
                if ((bounding_rects[j].width == 0) || (bounding_rects[j].height == 0)) continue;

                if (rect_overlap(bounding_rects[i], bounding_rects[j])) {
                    bounding_rects[i] = rect_collapse(bounding_rects[i], bounding_rects[j]);
                    bounding_rects[j] = NULL_RECT;
                }
            }
        }

        for (i = 0; i < n_rects; ++i) {
            GstEvent     *event;
            GstStructure *structure;
            CvRect        r;

            // skip collapsed rectangles
            r = bounding_rects[i];
            if ((r.width == 0) || (r.height == 0)) continue;

            structure = gst_structure_new("bgfg-roi",
                                          "x",         G_TYPE_UINT,   r.x,
                                          "y",         G_TYPE_UINT,   r.y,
                                          "width",     G_TYPE_UINT,   r.width,
                                          "height",    G_TYPE_UINT,   r.height,
                                          "timestamp", G_TYPE_UINT64, GST_BUFFER_TIMESTAMP(buf),
                                          NULL);

            event = gst_event_new_custom(GST_EVENT_CUSTOM_DOWNSTREAM, structure);
            gst_pad_send_event(filter->sinkpad, event);

            if (filter->verbose)
                GST_INFO("[roi] x: %d, y: %d, width: %d, height: %d\n",
                         r.x, r.y, r.width, r.height);

            if (filter->display)
                cvRectangle(filter->image, cvPoint(r.x, r.y), cvPoint(r.x + r.width, r.y + r.height),
                            CV_RGB(0, 0, 255), 1, 0, 0);
        }

        g_free(bounding_rects);
    }

    if (filter->display)
        gst_buffer_set_data(buf, (guchar*) filter->image->imageData, filter->image->imageSize);

    return gst_pad_push(filter->srcpad, buf);
}
Пример #6
0
/* Can probably be made more efficient - like only checking one area */
static level_mask_t check_bg_collision(game_t *p_game, sprite_t *p_sprite, dir_t dir, point_t new_pt, point_t *p_overlap)
{
  rect_t rect;
  int16_t x,y;

  rect = rect_add_pt(p_sprite->p_bounds[p_sprite->frame], new_pt);

  switch (dir)
    {
    case LEFT:
      rect.bottom_right.x = rect.top_left.x + TILE_W;
      rect.bottom_right.y-=TILE_H;
      break;
    case RIGHT:
      rect.top_left.x = rect.bottom_right.x - TILE_W;
      rect.bottom_right.y-=TILE_H; /* FIXME! Better with allow left/right */
      break;
    case UP:
      rect.bottom_right.y = rect.top_left.y + TILE_W;
      break;
    case DOWN:
      rect.top_left.y = rect.bottom_right.y - TILE_W;
      break;
    }

#ifndef NDEBUG
  {
    rect_t rect2 = rect_add_pt(p_sprite->p_bounds[p_sprite->frame], p_sprite->pt);

    draw_rect(p_game, rect2, vRGB(255,255,255));
  }
#endif
  draw_rect(p_game, rect, vRGB(255,0,0));

  for (y = rect.top_left.y/TILE_H; y <= rect.bottom_right.y/TILE_H; y++)
    {
      for (x = rect.top_left.x/TILE_W; x <= rect.bottom_right.x/TILE_W; x++)
	{
	  level_mask_t tile = tile_at(p_game, pt(x,y));

	  if (tile > 1)
	    {
	      rect_t tile_rect = rect_add_pt(tile_bounds[tile-1], pt_to_sprite(pt(x,y)));

	      draw_rect(p_game, tile_rect, vRGB(0,255,0));
	      if (rect_overlap(tile_rect, rect, p_overlap))
		{
		  assert(tile != 0);

#ifndef NDEBUG
		  DbgPrintf("  %d:%d Tile %d rect %d:%d -> %d:%d (overlap %d,%d)\n\n", dir, p_sprite->state, tile,
			    tile_rect.top_left.x,tile_rect.top_left.y,
			    tile_rect.bottom_right.x, tile_rect.bottom_right.y,
			    p_overlap->x, p_overlap->y
			    );
		  vFlipScreen(0);
#endif
		  return tile;
		}
	    }
	}
    }
  /* TMP! */
  DbgPrintf("\n");

#ifndef NDEBUG
  vFlipScreen(0);
#endif

  return 0;
}