virtual const CSphMatch & GetNextDoc ( DWORD * )
	{
		m_uFields = 0xFFFFFFFFUL;
		if ( ( m_iChunk++ )==0 )
		{
			if ( GetNextHit() )
			{
				m_tMatch.m_iDocID = 1;
				m_iToken--;
			} else
				m_tMatch.m_iDocID = 0;
		} else
			m_tMatch.m_iDocID = 0;
		return m_tMatch;
	}
示例#2
0
文件: inter.c 项目: oleavitt/gem
int FindAllIntersections(Object *first_obj, HitData *hits)
{
  Object *obj;
  int nhits, nobjhits;
  struct BBQ *first_bbox_queued, *last_bbox_queued, *bbq;

  last_bbox_queued = NULL;
  first_bbox_queued = NULL;
  nhits = 0;
  ct.calc_all++;
  obj = first_obj;

  while(obj != NULL)
  {
    if( ! ((ct.ray_flags & RAY_SHADOW) &&
          ((obj->flags & OBJ_FLAG_NO_SHADOW) ||
          ((obj == ct.baseobj) && (obj->flags & OBJ_FLAG_NO_SELF_INTERSECT))))
      )
    {
      nobjhits = (obj->procs->Intersect)(obj, hits);
      if(nobjhits)
      {
        if(obj->procs->type == OBJ_BBOX)
        {
          /*
           * Place bounding boxes in queue to be tested
           * after the non-BBox objects in this list are tested.
           */
          bbq = fetch_bbq();
          bbq->bbox = obj->data.bbox;
          bbq->t = hits->t;
          if(last_bbox_queued == NULL)
            first_bbox_queued = bbq;
          else
            last_bbox_queued->next = bbq;
          last_bbox_queued = bbq;
        }
        else
        {
          nhits += nobjhits;
          while(--nobjhits)
            hits = hits->next;
          hits = GetNextHit(hits);
        }
      }
    }
    obj = obj->next;

    if(obj == NULL)
    {
      /*
       * End of object list was reached. If there are
       * bounding boxes, pull next one from the queue and recycle.
       * "obj" will point to a new list of objects.
       */
      if(first_bbox_queued != NULL)
      {
        /* Pull first bounding box from the queue... */
        bbq = first_bbox_queued;
        first_bbox_queued = first_bbox_queued->next;
        if(first_bbox_queued == NULL)  /* This was the only one... */
          last_bbox_queued = NULL;        /* ...Clear the queue. */
        /* Get new object list to test... */
        obj = bbq->bbox->objects;
        /* Flag this queue element as "free" in the global pool. */
        bbq->bbox = NULL;
        /* Recycle with new object list. */
      }
    }
  }
  ct.calc_all--;

  return nhits;
}
示例#3
0
文件: Blob.c 项目: oleavitt/gem
int IntersectBlob(Object *obj, HitData *hits)
{
	BlobData *bl;
	BlobHit *first_bi;
	double ray_scale;

	ray_blob_tests++;

	bl = obj->data.blob;

	/* Check user-supplied bound object(s), if present... */
	if (bl->bound != NULL)
	{
		Object *o;
		int nhits = 0;

		for (o = bl->bound; o != NULL && nhits == 0; o = o->next)
			if (o->procs->Intersect(o, hits))
				nhits++;
		if (nhits == 0)
			return 0;
	}

	B = ct.B;
	D = ct.D;
	if (obj->T != NULL)
	{
		PointToObject(&B, obj->T);
		DirToObject(&D, obj->T);
		ray_scale = V3Mag(&D);
		if (ray_scale < EPSILON)
			return 0;
		D.x /= ray_scale;
		D.y /= ray_scale;
		D.z /= ray_scale;
	}
	else
		ray_scale = 1.0;

	if (calc_intervals(bl, &first_bi))
	{
		BlobHit *bi;
		double lo, hi;
		double tc[5], t[4];
		int i, nhits, valid_hits, in, ray_entering = 1;

		bi = first_bi;
		in = 0;
		valid_hits = 0;
		lo = bi->t;
		hi = bi->next->t;
		/* Initialize the eq. totals accumulator. */
		for (i = 1; i < 5; i++)
			tc[i] = 0.0;
		/* Start with blob threshold constant. */
		tc[0] = - bl->threshold;

		for (;;)
		{
			if (bi->entering)
			{
				in++;  /* entering an interval */
				calc_substitutions(bi);
				/* Add to sum total of density eqs. */
				for (i = 0; i < 5 ;i++)
					tc[i] += bi->be->c[i];
			}
			else  /* exiting an interval */
			{
				in--;
				/* Subtract this element out of density eq. totals accumulator. */
				if (in)
				{
					for (i = 0; i < 5; i++)
						tc[i] -= bi->be->c[i];
				}
				else   /* Clear the accumulator. */
				{
					for (i = 1; i < 5; i++)
						tc[i] = 0.0;
					tc[0] = - bl->threshold;
				}
			}

			if (in && (lo < hi))
			{
				nhits = SolvePoly(tc, t, 4, lo, hi);
				if (nhits > 0)
				{
					for (i = 0;i < nhits;i++)
					{
						if (valid_hits++)
						{
							hits = GetNextHit(hits);
						}
						else
						{
							ray_entering = ((nhits & 1) == 0) ? 1 : 0;
							if (obj->flags & OBJ_FLAG_INVERSE)
								ray_entering = 1 - ray_entering;
						}
						hits->t = t[i];
						hits->obj = obj;
						hits->entering = ray_entering;
						ray_entering = 1 - ray_entering;
						hits->t /= ray_scale;
					}
					if (!ct.calc_all)
						break;
				}
			}
			bi = bi->next;
			lo = bi->t;
			if (bi->next == NULL)
				break; /* Done. */
			hi = bi->next->t;
		} /* end of while there are intervals */
		if (valid_hits)
			ray_blob_hits++;
		return valid_hits;
	} /* end of if (calc_intervals()) */

	return 0; /* No intervals found. */
}