Пример #1
0
    public static int SV_HullPointContents(hull_t hull, int num, ref Vector3 p)
    {
        while (num >= 0)
        {
            if (num < hull.firstclipnode || num > hull.lastclipnode)
            {
                Sys_Error("SV_HullPointContents: bad node number");
            }

            short[]  node_children = hull.clipnodes[num].children;
            mplane_t plane         = hull.planes[hull.clipnodes[num].planenum];
            float    d;
            if (plane.type < 3)
            {
                d = Mathlib.Comp(ref p, plane.type) - plane.dist;
            }
            else
            {
                d = Vector3.Dot(plane.normal, p) - plane.dist;
            }
            if (d < 0)
            {
                num = node_children[1];
            }
            else
            {
                num = node_children[0];
            }
        }

        return(num);
    }
Пример #2
0
    public static trace_t SV_ClipMoveToEntity(edict_t ent, ref Vector3 start, ref Vector3 mins, ref Vector3 maxs, ref Vector3 end)
    {
        trace_t trace = new trace_t();

        // fill in a default trace
        trace.fraction = 1;
        trace.allsolid = true;
        trace.endpos   = end;

        // get the clipping hull
        Vector3 offset;
        hull_t  hull = SV_HullForEntity(ent, ref mins, ref maxs, out offset);

        Vector3 start_l = start - offset;
        Vector3 end_l   = end - offset;

        // trace a line through the apropriate clipping hull
        SV_RecursiveHullCheck(hull, hull.firstclipnode, 0, 1, ref start_l, ref end_l, trace);

        // fix trace up by the offset
        if (trace.fraction != 1)
        {
            trace.endpos += offset;
        }

        // did we clip the move?
        if (trace.fraction < 1 || trace.startsolid)
        {
            trace.ent = ent;
        }

        return(trace);
    }
Пример #3
0
    public static hull_t SV_HullForEntity(edict_t ent, ref Vector3 mins, ref Vector3 maxs, out Vector3 offset)
    {
        hull_t hull = null;

        // decide which clipping hull to use, based on the size
        if (ent.v.solid == q_shared.SOLID_BSP)
        {       // explicit hulls in the BSP model
            if (ent.v.movetype != q_shared.MOVETYPE_PUSH)
            {
                Sys_Error("SOLID_BSP without MOVETYPE_PUSH");
            }

            model_t model = sv.models[(int)ent.v.modelindex];

            if (model == null || model.type != modtype_t.mod_brush)
            {
                Sys_Error("MOVETYPE_PUSH with a non bsp model");
            }

            Vector3 size = maxs - mins;
            if (size.X < 3)
            {
                hull = model.hulls[0];
            }
            else if (size.X <= 32)
            {
                hull = model.hulls[1];
            }
            else
            {
                hull = model.hulls[2];
            }

            // calculate an offset value to center the origin
            offset  = hull.clip_mins - mins;
            offset += ToVector(ref ent.v.origin);
        }
        else
        {
            // create a temp hull from bounding box sizes
            Vector3 hullmins = ToVector(ref ent.v.mins) - maxs;
            Vector3 hullmaxs = ToVector(ref ent.v.maxs) - mins;
            hull = SV_HullForBox(ref hullmins, ref hullmaxs);

            offset = ToVector(ref ent.v.origin);
        }

        return(hull);
    }
Пример #4
0
 public model_t()
 {
     for (int kk = 0; kk < bspfile.MAX_MAP_HULLS; kk++)
         hulls[kk] = new hull_t();
 }
Пример #5
0
    public static bool SV_RecursiveHullCheck(hull_t hull, int num, float p1f, float p2f, ref Vector3 p1, ref Vector3 p2, trace_t trace)
    {
        // check for empty
        if (num < 0)
        {
            if (num != q_shared.CONTENTS_SOLID)
            {
                trace.allsolid = false;
                if (num == q_shared.CONTENTS_EMPTY)
                {
                    trace.inopen = true;
                }
                else
                {
                    trace.inwater = true;
                }
            }
            else
            {
                trace.startsolid = true;
            }
            return(true);                // empty
        }

        if (num < hull.firstclipnode || num > hull.lastclipnode)
        {
            Sys_Error("SV_RecursiveHullCheck: bad node number");
        }

        //
        // find the point distances
        //
        short[]  node_children = hull.clipnodes[num].children;
        mplane_t plane = hull.planes[hull.clipnodes[num].planenum];
        float    t1, t2;

        if (plane.type < 3)
        {
            t1 = Mathlib.Comp(ref p1, plane.type) - plane.dist;
            t2 = Mathlib.Comp(ref p2, plane.type) - plane.dist;
        }
        else
        {
            t1 = Vector3.Dot(plane.normal, p1) - plane.dist;
            t2 = Vector3.Dot(plane.normal, p2) - plane.dist;
        }

        if (t1 >= 0 && t2 >= 0)
        {
            return(SV_RecursiveHullCheck(hull, node_children[0], p1f, p2f, ref p1, ref p2, trace));
        }
        if (t1 < 0 && t2 < 0)
        {
            return(SV_RecursiveHullCheck(hull, node_children[1], p1f, p2f, ref p1, ref p2, trace));
        }

        // put the crosspoint DIST_EPSILON pixels on the near side
        float frac;

        if (t1 < 0)
        {
            frac = (t1 + q_shared.DIST_EPSILON) / (t1 - t2);
        }
        else
        {
            frac = (t1 - q_shared.DIST_EPSILON) / (t1 - t2);
        }
        if (frac < 0)
        {
            frac = 0;
        }
        if (frac > 1)
        {
            frac = 1;
        }

        float   midf = p1f + (p2f - p1f) * frac;
        Vector3 mid  = p1 + (p2 - p1) * frac;

        int side = (t1 < 0) ? 1 : 0;

        // move up to the node
        if (!SV_RecursiveHullCheck(hull, node_children[side], p1f, midf, ref p1, ref mid, trace))
        {
            return(false);
        }

        if (SV_HullPointContents(hull, node_children[side ^ 1], ref mid) != q_shared.CONTENTS_SOLID)
        {
            // go past the node
            return(SV_RecursiveHullCheck(hull, node_children[side ^ 1], midf, p2f, ref mid, ref p2, trace));
        }

        if (trace.allsolid)
        {
            return(false);               // never got out of the solid area
        }
        //==================
        // the other side of the node is solid, this is the impact point
        //==================
        if (side == 0)
        {
            trace.plane.normal = plane.normal;
            trace.plane.dist   = plane.dist;
        }
        else
        {
            trace.plane.normal = -plane.normal;
            trace.plane.dist   = -plane.dist;
        }

        while (SV_HullPointContents(hull, hull.firstclipnode, ref mid) == q_shared.CONTENTS_SOLID)
        {
            // shouldn't really happen, but does occasionally
            frac -= 0.1f;
            if (frac < 0)
            {
                trace.fraction = midf;
                trace.endpos   = mid;
                Con_DPrintf("backup past 0\n");
                return(false);
            }
            midf = p1f + (p2f - p1f) * frac;
            mid  = p1 + (p2 - p1) * frac;
        }

        trace.fraction = midf;
        trace.endpos   = mid;

        return(false);
    }