Exemplo n.º 1
0
// AJM: MVD
// =====================================================================================
//  ClipWindingsToBounds
//      clips all the windings with all the planes (including original face) and outputs 
//      what's left int "out"
// =====================================================================================
static void			ClipWindingsToBounds(winding_t *windings, int numwindings, plane_t *bounds, int numbounds, plane_t &original_plane, winding_t **out, int &num_out)
{
	hlassert(windings);
	hlassert(bounds);

	winding_t out_windings[MAX_PORTALS_ON_LEAF];
	num_out = 0;

	int h, i;

	*out = NULL;

	Winding wind;

	for(h = 0; h < numwindings; h++)
	{					
		// For each winding...
		// Create a winding with CWinding

		wind.initFromPoints(windings[h].points, windings[h].numpoints);

		// Clip winding to original plane
		wind.Chop(original_plane.normal, original_plane.dist);

		for(i = 0; i < numbounds, wind.Valid(); i++)
		{
			// For each bound...
			// Chop the winding to the bounds
			wind.Chop(bounds[i].normal, bounds[i].dist);
		}
		
		if(wind.Valid())
		{
			// We have a valid winding, copy to array
			wind.CopyPoints(&out_windings[num_out].points[0], out_windings[num_out].numpoints);

			num_out++;
		}
	}

	if(!num_out)		// Everything was clipped away
		return;

	// Otherwise, create out
	*out = new winding_t[num_out];

	memcpy(*out, out_windings, num_out * sizeof(winding_t));
}
Exemplo n.º 2
0
// AJM: MVD
// =====================================================================================
//  GetPortalBounds
//      This function take a portal and finds its bounds
//      parallel to the normal of the portal.  They will face inwards
// =====================================================================================
static void			GetPortalBounds(portal_t *p, plane_t **bounds)
{
	int i;
	vec3_t vec1, vec2;

	hlassert(p->winding->numpoints >= 3);

	if(*bounds)
		delete [] *bounds;

	*bounds = new plane_t[p->winding->numpoints];

	// Loop through each set of points and create a plane boundary for each
	for(i = 0; i < p->winding->numpoints; i++)
	{
		VectorSubtract(p->winding->points[(i + 1) % p->winding->numpoints],p->winding->points[i],vec1);

		// Create inward normal for this boundary
		CrossProduct(p->plane.normal, vec1, vec2);
		VectorNormalize(vec2);

		VectorCopy(vec2, (*bounds)[i].normal);
		(*bounds)[i].dist = DotProduct(p->winding->points[i], vec2);
	}
}
Exemplo n.º 3
0
// =====================================================================================
//  CheckFatal 
// =====================================================================================
void            CheckFatal()
{
    if (fatal)
    {
        hlassert(false);
        exit(1);
    }
}
Exemplo n.º 4
0
Winding::Winding(UINT32 numpoints)
{
    hlassert(numpoints >= 3);
    m_NumPoints = numpoints;
    m_MaxPoints = (m_NumPoints + 3) & ~3;   // groups of 4

    m_Points = new vec3_t[m_MaxPoints];
    memset(m_Points, 0, sizeof(vec3_t) * m_NumPoints);
}
Exemplo n.º 5
0
// AJM: MVD
// =====================================================================================
//  MakeSplitPortalList
//      This function returns a portal on leaf1 that sucessfully seperates leaf1
//      and leaf2
// =====================================================================================
static void		MakeSplitPortalList(leaf_t *leaf1, leaf_t *leaf2, portal_t **portals, int *num_portals)
{
	int i, k, l;

	portal_t	*p1;
	portal_t	*t;

	*num_portals = 0;

	float check_dist;

	portal_t p_list[MAX_PORTALS_ON_LEAF];
	int c_portal = 0;

	if(*portals)
		delete [] *portals;

	for(i = 0, p1 = leaf1->portals[0]; i < leaf1->numportals; i++, p1++)
	{
		hlassert(p1->winding->numpoints >= 3);
		
		// Check to make sure all the points on the other leaf are in front of the portal plane
		for(k = 0, t = leaf2->portals[0]; k < leaf2->numportals; k++, t++)
		{
			for(l = 0; l < t->winding->numpoints; l++)
			{
				check_dist = DotProduct(t->winding->points[l], p1->plane.normal) - p1->plane.dist;
				
				// We make the assumption that all portals face away from their parent leaf
				if(check_dist < -ON_EPSILON)
					goto PostLoop;
			}
		}

PostLoop:
		// If we didn't check all the leaf2 portals, then this leaf1 portal doesn't work		
		if(k < leaf2->numportals)
			continue;

		// If we reach this point, we found a good portal
		memcpy(&p_list[c_portal++], p1, sizeof(portal_t));

		if(c_portal >= MAX_PORTALS_ON_LEAF)
			Error("c_portal > MAX_PORTALS_ON_LEAF");
	}

	if(!c_portal)
		return;

	*num_portals = c_portal;

	*portals = new portal_t[c_portal];
	memcpy(*portals, p_list, c_portal * sizeof(portal_t));
}
Exemplo n.º 6
0
static void     AddFaceToList(bface_t** head, bface_t* newface)
{
    hlassert(newface);
    hlassert(newface->w);
    if (!*head)
    {
        *head = newface;
        return;
    }
    else
    {
        bface_t*        node = *head;

        while (node->next)
        {
            node = node->next;
        }
        node->next = newface;
        newface->next = NULL;
    }
}
Exemplo n.º 7
0
void			Winding::initFromPoints(vec3_t *points, UINT32 numpoints)
{
    hlassert(numpoints >= 3);

    Reset();

    m_NumPoints = numpoints;
    m_MaxPoints = (m_NumPoints + 3) & ~3;	// groups of 4

    m_Points = new vec3_t[m_MaxPoints];
    memcpy(m_Points, points, sizeof(vec3_t) * m_NumPoints);
}
Exemplo n.º 8
0
// AJM: MVD
// =====================================================================================
//  GetSplitPortal
//      This function returns a portal on leaf1 that sucessfully seperates leaf1
//      and leaf2
// =====================================================================================
static portal_t	*GetSplitPortal(leaf_t *leaf1, leaf_t *leaf2)
{
	int i, k, l;

	portal_t	*p1;
	portal_t	*t;

	float check_dist;

	for(i = 0, p1 = leaf1->portals[0]; i < leaf1->numportals; i++, p1++)
	{
		hlassert(p1->winding->numpoints >= 3);
		
		// Check to make sure all the points on the other leaf are in front of the portal plane
		for(k = 0, t = leaf2->portals[0]; k < leaf2->numportals; k++, t++)
		{
			for(l = 0; l < t->winding->numpoints; l++)
			{
				check_dist = DotProduct(t->winding->points[l], p1->plane.normal) - p1->plane.dist;
				
				// We make the assumption that all portals face away from their parent leaf
				if(check_dist < -ON_EPSILON)
					goto PostLoop;
			}
		}

PostLoop:
		// If we didn't check all the leaf2 portals, then this leaf1 portal doesn't work		
		if(k < leaf2->numportals)
			continue;

		// If we reach this point, we found a good portal
		return p1;
	}

	// Didn't find any
	return NULL;
}
Exemplo n.º 9
0
// =====================================================================================
//  GetEdge
//      Don't allow four way edges
// =====================================================================================
int             GetEdge(const vec3_t p1, const vec3_t p2, face_t* f)
{
    int             v1;
    int             v2;
    dedge_t*        edge;
    int             i;

    hlassert(f->contents);

    v1 = GetVertex(p1, f->planenum);
    v2 = GetVertex(p2, f->planenum);
    for (i = firstmodeledge; i < g_numedges; i++)
    {
        edge = &g_dedges[i];
        if (v1 == edge->v[1] && v2 == edge->v[0] && !edgefaces[i][1] && edgefaces[i][0]->contents == f->contents
#ifdef HLBSP_EDGESHARE_SAMESIDE
			&& edgefaces[i][0]->planenum != (f->planenum ^ 1)
			&& edgefaces[i][0]->contents == f->contents
#endif
			)
        {
            edgefaces[i][1] = f;
            return -i;
        }
    }

    // emit an edge
    hlassume(g_numedges < MAX_MAP_EDGES, assume_MAX_MAP_EDGES);
    edge = &g_dedges[g_numedges];
    g_numedges++;
    edge->v[0] = v1;
    edge->v[1] = v2;
    edgefaces[i][0] = f;

    return i;
}
Exemplo n.º 10
0
// Returns false if union of brushes is obviously zero
static void     AddPlaneToUnion(brushhull_t* hull, const int planenum)
{
    bool            need_new_face = false;

    bface_t*        new_face_list;

    bface_t*        face;
    bface_t*        next;

    plane_t*        split;
    Winding*        front;
    Winding*        back;

    new_face_list = NULL;

    next = NULL;

    hlassert(hull);

    if (!hull->faces)
    {
        return;
    }
    hlassert(hull->faces->w);

    for (face = hull->faces; face; face = next)
    {
        hlassert(face->w);
        next = face->next;

        // Duplicate plane, ignore
        if (face->planenum == planenum)
        {
            AddFaceToList(&new_face_list, CopyFace(face));
            continue;
        }

        split = &g_mapplanes[planenum];
        face->w->Clip(split->normal, split->dist, &front, &back);

        if (front)
        {
            delete front;
            need_new_face = true;

            if (back)
            {                                              // Intersected the face
                delete face->w;
                face->w = back;
                AddFaceToList(&new_face_list, CopyFace(face));
            }
        }
        else
        {
            // Completely missed it, back is identical to face->w so it is destroyed
            if (back)
            {
                delete back;
                AddFaceToList(&new_face_list, CopyFace(face));
            }
        }
        hlassert(face->w);
    }

    FreeFaceList(hull->faces);
    hull->faces = new_face_list;

    if (need_new_face && (NumberOfHullFaces(hull) > 2))
    {
        Winding*        new_winding = NewWindingFromPlane(hull, planenum);

        if (new_winding)
        {
            bface_t*        new_face = (bface_t*)Alloc(sizeof(bface_t));

            new_face->planenum = planenum;
            new_face->w = new_winding;

            new_face->next = hull->faces;
            hull->faces = new_face;
        }
    }
}