Exemplo n.º 1
0
static __regargs UWORD ClipPolygon(Point3D *S, Point3D *O,
                                   UWORD n, UWORD plane)
{
  Point3D *E = S + 1;

  BOOL S_inside = CheckInside(S, plane);
  BOOL needClose = TRUE;
  UWORD m = 0;

  if (S_inside) {
    needClose = FALSE;
    O[m++] = *S;
  }

  while (--n) {
    BOOL E_inside = CheckInside(E, plane);

    if (S_inside && E_inside) {
      O[m++] = *E;
    } else if (S_inside && !E_inside) {
      ClipEdge(&O[m++], S, E, plane);
    } else if (!S_inside && E_inside) {
      ClipEdge(&O[m++], E, S, plane);
      O[m++] = *E;
    }

    S_inside = E_inside;
    S++; E++;
  }

  if (needClose)
    O[m++] = *O;

  return m;
}
Exemplo n.º 2
0
Mth::Vector 		CEmitterObject::GetClosestPoint(const Mth::Vector &object_pos) const
{
	// Return original position if within the object
	if (CheckInside(object_pos))
	{
		return object_pos;
	}

	Mth::Vector intersect_point;

	switch (m_shape_type)
	{
	case vSHAPE_SPHERE:
		{
			// Same for either within or outside sphere
			Mth::Vector direction = object_pos - m_pos;
			direction.Normalize();
			direction *= m_radius;

			intersect_point = m_pos + direction;
		}
		break;

	case vSHAPE_BBOX:
		m_bbox.GetClosestIntersectPoint(object_pos, intersect_point);
		break;

	default:
		Dbg_MsgAssert(0, ("Can't handle EmitterObject type %d", m_shape_type));
		break;
	}

#ifdef	DEBUG_EMITTER
	Gfx::AddDebugStar(intersect_point);
#endif //	DEBUG_EMITTER

	return intersect_point;
}
Exemplo n.º 3
0
/*
==================
CSGFaces

Returns a list of surfaces containing all of the faces
==================
*/
surface_t *
CSGFaces(void)
{
    brush_t *b1, *b2;
    int i;
    bool overwrite;
    face_t *f;
    surface_t *surfhead;
    int iBrushes = 0;

    Message(msgProgress, "CSGFaces");

    if (validfaces == NULL)
	validfaces = AllocMem(OTHER, sizeof(face_t *) * cPlanes, true);
    else
	memset(validfaces, 0, sizeof(face_t *) * cPlanes);
    csgfaces = brushfaces = csgmergefaces = 0;

    // do the solid faces
    for (b1 = pCurEnt->pBrushes; b1; b1 = b1->next) {
	// set outside to a copy of the brush's faces
	CopyFacesToOutside(b1);

	// Why is this necessary?
	overwrite = false;

	for (b2 = pCurEnt->pBrushes; b2; b2 = b2->next) {
	    // check bounding box first
	    for (i = 0; i < 3; i++)
		if (b1->mins[i] > b2->maxs[i] || b1->maxs[i] < b2->mins[i])
		    break;
	    if (i < 3)
		continue;

	    // see if b2 needs to clip a chunk out of b1
	    if (b1 == b2) {
		overwrite = true;
		continue;
	    }
	    // divide faces by the planes of the new brush
	    inside = outside;
	    outside = NULL;

	    CheckInside(b2);
	    for (f = b2->faces; f; f = f->next)
		ClipInside(f->planenum, f->planeside, overwrite);

	    // these faces are continued in another brush, so get rid of them
	    if (b1->contents == CONTENTS_SOLID
		&& b2->contents <= CONTENTS_WATER)
		FreeInside(b2->contents);
	    else
		FreeInside(CONTENTS_SOLID);
	}

	// all of the faces left in outside are real surface faces
	if (b1->contents != CONTENTS_SOLID)
	    SaveOutside(true);	// mirror faces for inside view
	else
	    SaveOutside(false);

	iBrushes++;
	Message(msgPercent, iBrushes, pCurEnt->cBrushes);
    }

    surfhead = BuildSurfaces();

    Message(msgStat, "%5i brushfaces", brushfaces);
    Message(msgStat, "%5i csgfaces", csgfaces);
    Message(msgStat, "%5i mergedfaces", csgmergefaces);

    return surfhead;
}