示例#1
0
static Winding* NewWindingFromPlane(const brushhull_t* const hull, const int planenum)
{
    Winding*        winding;
    Winding*        front;
    Winding*        back;
    bface_t*        face;
    plane_t*        plane;

    plane = &g_mapplanes[planenum];
    winding = new Winding(plane->normal, plane->dist);

    for (face = hull->faces; face; face = face->next)
    {
        plane = &g_mapplanes[face->planenum];
        winding->Clip(plane->normal, plane->dist, &front, &back);
        delete winding;

        if (front)
        {
            delete front;
        }
        if (back)
        {
            winding = back;
        }
        else
        {
            Developer(DEVELOPER_LEVEL_ERROR, "NewFaceFromPlane returning NULL");
            return NULL;
        }
    }

    return winding;
}
示例#2
0
// =====================================================================================
//  GetAlternateOrigin
// =====================================================================================
void GetAlternateOrigin (const vec3_t pos, const vec3_t normal, const patch_t *patch, vec3_t &origin)
{
    const dplane_t *faceplane;
    const vec_t *faceplaneoffset;
    const vec_t *facenormal;
    dplane_t clipplane;
    Winding w;

    faceplane = getPlaneFromFaceNumber (patch->faceNumber);
    faceplaneoffset = g_face_offset[patch->faceNumber];
    facenormal = faceplane->normal;
    VectorCopy (normal, clipplane.normal);
    clipplane.dist = DotProduct (pos, clipplane.normal);

    w = *patch->winding;
    if (w.WindingOnPlaneSide (clipplane.normal, clipplane.dist) != SIDE_CROSS)
    {
        VectorCopy (patch->origin, origin);
    }
    else
    {
        w.Clip (clipplane, false);
        if (w.m_NumPoints == 0)
        {
            VectorCopy (patch->origin, origin);
        }
        else
        {
            vec3_t center;
            bool found;
            vec3_t bestpoint;
            vec_t bestdist = -1.0;
            vec3_t point;
            vec_t dist;
            vec3_t v;

            w.getCenter (center);
            found = false;

            VectorMA (center, PATCH_HUNT_OFFSET, facenormal, point);
            if (HuntForWorld (point, faceplaneoffset, faceplane, 2, 1.0, PATCH_HUNT_OFFSET))
            {
                VectorSubtract (point, center, v);
                dist = VectorLength (v);
                if (!found || dist < bestdist)
                {
                    found = true;
                    VectorCopy (point, bestpoint);
                    bestdist = dist;
                }
            }
            if (!found)
            {
                for (int i = 0; i < w.m_NumPoints; i++)
                {
                    const vec_t *p1;
                    const vec_t *p2;
                    p1 = w.m_Points[i];
                    p2 = w.m_Points[(i + 1) % w.m_NumPoints];
                    VectorAdd (p1, p2, point);
                    VectorAdd (point, center, point);
                    VectorScale (point, 1.0/3.0, point);
                    VectorMA (point, PATCH_HUNT_OFFSET, facenormal, point);
                    if (HuntForWorld (point, faceplaneoffset, faceplane, 1, 0.0, PATCH_HUNT_OFFSET))
                    {
                        VectorSubtract (point, center, v);
                        dist = VectorLength (v);
                        if (!found || dist < bestdist)
                        {
                            found = true;
                            VectorCopy (point, bestpoint);
                            bestdist = dist;
                        }
                    }
                }
            }

            if (found)
            {
                VectorCopy (bestpoint, origin);
            }
            else
            {
                VectorCopy (patch->origin, origin);
            }
        }
    }
}
示例#3
0
// =====================================================================================
//  snap_to_winding_noedge
//      first snaps the point into the winding
//      then moves the point towards the inside for at most certain distance until:
//        either 1) the point is not close to any of the edges
//        or     2) the point can not be moved any more
//      returns the maximal distance that the point can be kept away from all the edges
//      in most of the cases, the maximal distance = width; in other cases, the maximal distance < width
// =====================================================================================
vec_t			snap_to_winding_noedge(const Winding& w, const dplane_t& plane, vec_t* const point, vec_t width, vec_t maxmove)
{
    int pass;
    int numplanes;
    dplane_t *planes;
    int x;
    vec3_t v;
    vec_t newwidth;
    vec_t bestwidth;
    vec3_t bestpoint;

    snap_to_winding (w, plane, point);

    planes = (dplane_t *)malloc (w.m_NumPoints * sizeof (dplane_t));
    hlassume (planes != NULL, assume_NoMemory);
    numplanes = 0;
    for (x = 0; x < w.m_NumPoints; x++)
    {
        VectorSubtract (w.m_Points[(x + 1) % w.m_NumPoints], w.m_Points[x], v);
        CrossProduct (v, plane.normal, planes[numplanes].normal);
        if (!VectorNormalize (planes[numplanes].normal))
        {
            continue;
        }
        planes[numplanes].dist = DotProduct (w.m_Points[x], planes[numplanes].normal);
        numplanes++;
    }

    bestwidth = 0;
    VectorCopy (point, bestpoint);
    newwidth = width;

    for (pass = 0; pass < 5; pass++) // apply binary search method for 5 iterations to find the maximal distance that the point can be kept away from all the edges
    {
        bool failed;
        vec3_t newpoint;
        Winding *newwinding;

        failed = true;

        newwinding = new Winding (w);
        for (x = 0; x < numplanes && newwinding->m_NumPoints > 0; x++)
        {
            dplane_t clipplane = planes[x];
            clipplane.dist += newwidth;
            newwinding->Clip (clipplane, false);
        }

        if (newwinding->m_NumPoints > 0)
        {
            VectorCopy (point, newpoint);
            snap_to_winding (*newwinding, plane, newpoint);

            VectorSubtract (newpoint, point, v);
            if (VectorLength (v) <= maxmove + ON_EPSILON)
            {
                failed = false;
            }
        }

        delete newwinding;

        if (!failed)
        {
            bestwidth = newwidth;
            VectorCopy (newpoint, bestpoint);
            if (pass == 0)
            {
                break;
            }
            newwidth += width * pow (0.5, pass + 1);
        }
        else
        {
            newwidth -= width * pow (0.5, pass + 1);
        }
    }

    free (planes);

    VectorCopy (bestpoint, point);
    return bestwidth;
}