Ejemplo n.º 1
0
    public static int BoxOnPlaneSide(ref Vector3 emins, ref Vector3 emaxs, mplane_t p)
    {
        float mindist, maxdist;

        switch (p.type)
        {
        case 0:
            mindist = emins.X;
            maxdist = emaxs.X;
            break;

        case 1:
            mindist = emins.Y;
            maxdist = emaxs.Y;
            break;

        case 2:
            mindist = emins.Z;
            maxdist = emaxs.Z;
            break;

        default:
            return(_BoxOnPlaneSide(ref emins, ref emaxs, p));
        }
        return(p.dist <= mindist ? 1 : (p.dist >= maxdist ? 2 : 3));
    }
Ejemplo n.º 2
0
    public static void SV_Init()
    {
        for (int i = 0; i < _BoxClipNodes.Length; i++)
        {
            _BoxClipNodes[i].children = new short[2];
        }
        for (int i = 0; i < _BoxPlanes.Length; i++)
        {
            _BoxPlanes[i] = new mplane_t();
        }
        for (int i = 0; i < sv_areanodes.Length; i++)
        {
            sv_areanodes[i] = new areanode_t();
        }

        sv_friction        = new cvar_t("sv_friction", "4", false, true);
        edgefriction       = new cvar_t("edgefriction", "2");
        sv_stopspeed       = new cvar_t("sv_stopspeed", "100");
        sv_gravity         = new cvar_t("sv_gravity", "800", false, true);
        sv_maxvelocity     = new cvar_t("sv_maxvelocity", "2000");
        sv_nostep          = new cvar_t("sv_nostep", "0");
        sv_maxspeed        = new cvar_t("sv_maxspeed", "320", false, true);
        sv_accelerate      = new cvar_t("sv_accelerate", "10");
        sv_aim             = new cvar_t("sv_aim", "0.93");
        sv_idealpitchscale = new cvar_t("sv_idealpitchscale", "0.8");

        for (int i = 0; i < q_shared.MAX_MODELS; i++)
        {
            localmodels[i] = "*" + i.ToString();
        }
    }
Ejemplo n.º 3
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);
    }
Ejemplo n.º 4
0
    public static int BoxOnPlaneSide(ref v3f emins, ref v3f emaxs, mplane_t p)
    {
        float mindist, maxdist;

        switch (p.type)
        {
        case 0:
            mindist = emins.x;
            maxdist = emaxs.x;
            break;

        case 1:
            mindist = emins.y;
            maxdist = emaxs.y;
            break;

        case 2:
            mindist = emins.z;
            maxdist = emaxs.z;
            break;

        default:
            Vector3 mins, maxs;
            Copy(ref emins, out mins);
            Copy(ref emaxs, out maxs);
            return(_BoxOnPlaneSide(ref mins, ref maxs, p));
        }
        return(p.dist <= mindist ? 1 : (p.dist >= maxdist ? 2 : 3));
    }
Ejemplo n.º 5
0
    public static void R_Init()
    {
        for (int i = 0; i < frustum.Length; i++)
        {
            frustum[i] = new mplane_t();
        }

        Cmd_AddCommand("timerefresh", R_TimeRefresh_f);
        //Cmd.Add("envmap", Envmap_f);
        //Cmd.Add("pointfile", ReadPointFile_f);

        r_norefresh     = new cvar_t("r_norefresh", "0");
        r_drawentities  = new cvar_t("r_drawentities", "1");
        r_drawviewmodel = new cvar_t("r_drawviewmodel", "1");
        r_speeds        = new cvar_t("r_speeds", "0");
        r_fullbright    = new cvar_t("r_fullbright", "0");
        r_lightmap      = new cvar_t("r_lightmap", "0");
        r_shadows       = new cvar_t("r_shadows", "0");
        r_mirroralpha   = new cvar_t("r_mirroralpha", "1");
        r_wateralpha    = new cvar_t("r_wateralpha", "1");
        r_dynamic       = new cvar_t("r_dynamic", "1");
        r_novis         = new cvar_t("r_novis", "0");

        gl_finish           = new cvar_t("gl_finish", "0");
        gl_clear            = new cvar_t("gl_clear", "0");
        gl_cull             = new cvar_t("gl_cull", "1");
        gl_texsort          = new cvar_t("gl_texsort", "1");
        gl_smoothmodels     = new cvar_t("gl_smoothmodels", "1");
        gl_affinemodels     = new cvar_t("gl_affinemodels", "0");
        gl_polyblend        = new cvar_t("gl_polyblend", "1");
        gl_flashblend       = new cvar_t("gl_flashblend", "1");
        gl_playermip        = new cvar_t("gl_playermip", "0");
        gl_nocolors         = new cvar_t("gl_nocolors", "0");
        gl_keeptjunctions   = new cvar_t("gl_keeptjunctions", "0");
        gl_reporttjunctions = new cvar_t("gl_reporttjunctions", "0");
        gl_doubleeys        = new cvar_t("gl_doubleeys", "1");

        if (gl_mtexable)
        {
            Cvar.Cvar_SetValue("gl_texsort", 0.0f);
        }

        R_InitParticles();
        R_InitParticleTexture();

        // reserve 16 textures
        playertextures = GenerateTextureNumberRange(16);
    }
Ejemplo n.º 6
0
    public static int SignbitsForPlane(mplane_t p)
    {
        // for fast box on planeside test
        int bits = 0;

        if (p.normal.X < 0)
        {
            bits |= 1 << 0;
        }
        if (p.normal.Y < 0)
        {
            bits |= 1 << 1;
        }
        if (p.normal.Z < 0)
        {
            bits |= 1 << 2;
        }
        return(bits);
    }
Ejemplo n.º 7
0
    public static void SV_FindTouchedLeafs(edict_t ent, mnodebase_t node)
    {
        if (node.contents == q_shared.CONTENTS_SOLID)
        {
            return;
        }

        // add an efrag if the node is a leaf

        if (node.contents < 0)
        {
            if (ent.num_leafs == q_shared.MAX_ENT_LEAFS)
            {
                return;
            }

            mleaf_t leaf    = (mleaf_t)node;
            int     leafnum = Array.IndexOf(sv.worldmodel.leafs, leaf) - 1;

            ent.leafnums[ent.num_leafs] = (short)leafnum;
            ent.num_leafs++;
            return;
        }

        // NODE_MIXED
        mnode_t  n          = (mnode_t)node;
        mplane_t splitplane = n.plane;
        int      sides      = Mathlib.BoxOnPlaneSide(ref ent.v.absmin, ref ent.v.absmax, splitplane);

        // recurse down the contacted sides
        if ((sides & 1) != 0)
        {
            SV_FindTouchedLeafs(ent, n.children[0]);
        }

        if ((sides & 2) != 0)
        {
            SV_FindTouchedLeafs(ent, n.children[1]);
        }
    }
Ejemplo n.º 8
0
    public static void R_MarkLights(dlight_t light, int bit, mnodebase_t node)
    {
        if (node.contents < 0)
        {
            return;
        }

        mnode_t  n          = (mnode_t)node;
        mplane_t splitplane = n.plane;
        float    dist       = Vector3.Dot(light.origin, splitplane.normal) - splitplane.dist;

        if (dist > light.radius)
        {
            R_MarkLights(light, bit, n.children[0]);
            return;
        }
        if (dist < -light.radius)
        {
            R_MarkLights(light, bit, n.children[1]);
            return;
        }

        // mark the polygons
        for (int i = 0; i < n.numsurfaces; i++)
        {
            msurface_t surf = cl.worldmodel.surfaces[n.firstsurface + i];
            if (surf.dlightframe != r_dlightframecount)
            {
                surf.dlightbits  = 0;
                surf.dlightframe = r_dlightframecount;
            }
            surf.dlightbits |= bit;
        }

        R_MarkLights(light, bit, n.children[0]);
        R_MarkLights(light, bit, n.children[1]);
    }
Ejemplo n.º 9
0
    public static void SV_AddToFatPVS(ref Vector3 org, mnodebase_t node)
    {
        while (true)
        {
            // if this is a leaf, accumulate the pvs bits
            if (node.contents < 0)
            {
                if (node.contents != q_shared.CONTENTS_SOLID)
                {
                    byte[] pvs = Mod_LeafPVS((mleaf_t)node, sv.worldmodel);
                    for (int i = 0; i < fatbytes; i++)
                    {
                        fatpvs[i] |= pvs[i];
                    }
                }
                return;
            }

            mnode_t  n     = (mnode_t)node;
            mplane_t plane = n.plane;
            float    d     = Vector3.Dot(org, plane.normal) - plane.dist;
            if (d > 8)
            {
                node = n.children[0];
            }
            else if (d < -8)
            {
                node = n.children[1];
            }
            else
            {   // go down both
                SV_AddToFatPVS(ref org, n.children[0]);
                node = n.children[1];
            }
        }
    }
Ejemplo n.º 10
0
    public static int RecursiveLightPoint(mnodebase_t node, ref Vector3 start, ref Vector3 end)
    {
        if (node.contents < 0)
        {
            return(-1);          // didn't hit anything
        }
        mnode_t n = (mnode_t)node;

        // calculate mid point

        // FIXME: optimize for axial
        mplane_t plane = n.plane;
        float    front = Vector3.Dot(start, plane.normal) - plane.dist;
        float    back  = Vector3.Dot(end, plane.normal) - plane.dist;
        int      side  = front < 0 ? 1 : 0;

        if ((back < 0 ? 1 : 0) == side)
        {
            return(RecursiveLightPoint(n.children[side], ref start, ref end));
        }

        float   frac = front / (front - back);
        Vector3 mid  = start + (end - start) * frac;

        // go down front side
        int r = RecursiveLightPoint(n.children[side], ref start, ref mid);

        if (r >= 0)
        {
            return(r);           // hit something
        }
        if ((back < 0 ? 1 : 0) == side)
        {
            return(-1);          // didn't hit anuthing
        }
        // check for impact on this node
        lightspot  = mid;
        lightplane = plane;

        msurface_t[] surf   = cl.worldmodel.surfaces;
        int          offset = n.firstsurface;

        for (int i = 0; i < n.numsurfaces; i++, offset++)
        {
            if ((surf[offset].flags & q_shared.SURF_DRAWTILED) != 0)
            {
                continue;       // no lightmaps
            }
            mtexinfo_t tex = surf[offset].texinfo;

            int s = (int)(Vector3.Dot(mid, tex.vecs[0].Xyz) + tex.vecs[0].W);
            int t = (int)(Vector3.Dot(mid, tex.vecs[1].Xyz) + tex.vecs[1].W);

            if (s < surf[offset].texturemins[0] || t < surf[offset].texturemins[1])
            {
                continue;
            }

            int ds = s - surf[offset].texturemins[0];
            int dt = t - surf[offset].texturemins[1];

            if (ds > surf[offset].extents[0] || dt > surf[offset].extents[1])
            {
                continue;
            }

            if (surf[offset].sample_base == null)
            {
                return(0);
            }

            ds >>= 4;
            dt >>= 4;

            byte[]  lightmap = surf[offset].sample_base;
            int     lmOffset = surf[offset].sampleofs;
            short[] extents  = surf[offset].extents;
            r = 0;
            if (lightmap != null)
            {
                lmOffset += dt * ((extents[0] >> 4) + 1) + ds;

                for (int maps = 0; maps < q_shared.MAXLIGHTMAPS && surf[offset].styles[maps] != 255; maps++)
                {
                    int scale = d_lightstylevalue[surf[offset].styles[maps]];
                    r        += lightmap[lmOffset] * scale;
                    lmOffset += ((extents[0] >> 4) + 1) * ((extents[1] >> 4) + 1);
                }

                r >>= 8;
            }

            return(r);
        }

        // go down back side
        return(RecursiveLightPoint(n.children[side == 0 ? 1 : 0], ref mid, ref end));
    }
Ejemplo n.º 11
0
    public static void R_RecursiveWorldNode(mnodebase_t node)
    {
        if (node.contents == q_shared.CONTENTS_SOLID)
        {
            return;             // solid
        }
        if (node.visframe != r_visframecount)
        {
            return;
        }
        if (R_CullBox(ref node.mins, ref node.maxs))
        {
            return;
        }

        int c;

        // if a leaf node, draw stuff
        if (node.contents < 0)
        {
            mleaf_t      pleaf = (mleaf_t)node;
            msurface_t[] marks = pleaf.marksurfaces;
            int          mark  = pleaf.firstmarksurface;
            c = pleaf.nummarksurfaces;

            if (c != 0)
            {
                do
                {
                    marks[mark].visframe = r_framecount;
                    mark++;
                } while (--c != 0);
            }

            // deal with model fragments in this leaf
            if (pleaf.efrags != null)
            {
                R_StoreEfrags(pleaf.efrags);
            }

            return;
        }

        // node is just a decision point, so go down the apropriate sides

        mnode_t n = (mnode_t)node;

        // find which side of the node we are on
        mplane_t plane = n.plane;
        double   dot;

        switch (plane.type)
        {
        case q_shared.PLANE_X:
            dot = modelorg.X - plane.dist;
            break;

        case q_shared.PLANE_Y:
            dot = modelorg.Y - plane.dist;
            break;

        case q_shared.PLANE_Z:
            dot = modelorg.Z - plane.dist;
            break;

        default:
            dot = Vector3.Dot(modelorg, plane.normal) - plane.dist;
            break;
        }

        int side = (dot >= 0 ? 0 : 1);

        // recurse down the children, front side first
        R_RecursiveWorldNode(n.children[side]);

        // draw stuff
        c = n.numsurfaces;

        if (c != 0)
        {
            msurface_t[] surf   = cl.worldmodel.surfaces;
            int          offset = n.firstsurface;

            if (dot < 0 - q_shared.BACKFACE_EPSILON)
            {
                side = q_shared.SURF_PLANEBACK;
            }
            else if (dot > q_shared.BACKFACE_EPSILON)
            {
                side = 0;
            }

            for (; c != 0; c--, offset++)
            {
                if (surf[offset].visframe != r_framecount)
                {
                    continue;
                }

                // don't backface underwater surfaces, because they warp
                if ((surf[offset].flags & q_shared.SURF_UNDERWATER) == 0 && ((dot < 0) ^ ((surf[offset].flags & q_shared.SURF_PLANEBACK) != 0)))
                {
                    continue;           // wrong side
                }
                // if sorting by texture, just store it out
                if (gl_texsort.value != 0)
                {
                    if (!mirror || surf[offset].texinfo.texture != cl.worldmodel.textures[mirrortexturenum])
                    {
                        surf[offset].texturechain = surf[offset].texinfo.texture.texturechain;
                        surf[offset].texinfo.texture.texturechain = surf[offset];
                    }
                }
                else if ((surf[offset].flags & q_shared.SURF_DRAWSKY) != 0)
                {
                    surf[offset].texturechain = skychain;
                    skychain = surf[offset];
                }
                else if ((surf[offset].flags & q_shared.SURF_DRAWTURB) != 0)
                {
                    surf[offset].texturechain = waterchain;
                    waterchain = surf[offset];
                }
                else
                {
                    R_DrawSequentialPoly(surf[offset]);
                }
            }
        }

        // recurse down the back side
        R_RecursiveWorldNode(n.children[side == 0 ? 1 : 0]);
    }
Ejemplo n.º 12
0
    public static void R_DrawBrushModel(entity_t e)
    {
        currententity  = e;
        currenttexture = -1;

        model_t clmodel = e.model;
        bool    rotated = false;
        Vector3 mins, maxs;

        if (e.angles.X != 0 || e.angles.Y != 0 || e.angles.Z != 0)
        {
            rotated = true;
            mins    = e.origin;
            mins.X -= clmodel.radius;
            mins.Y -= clmodel.radius;
            mins.Z -= clmodel.radius;
            maxs    = e.origin;
            maxs.X += clmodel.radius;
            maxs.Y += clmodel.radius;
            maxs.Z += clmodel.radius;
        }
        else
        {
            mins = e.origin + clmodel.mins;
            maxs = e.origin + clmodel.maxs;
        }

        if (R_CullBox(ref mins, ref maxs))
        {
            return;
        }

        GL.Color3(1f, 1, 1);
        Array.Clear(lightmap_polys, 0, lightmap_polys.Length);
        modelorg = r_refdef.vieworg - e.origin;
        if (rotated)
        {
            Vector3 temp = modelorg;
            Vector3 forward, right, up;
            Mathlib.AngleVectors(ref e.angles, out forward, out right, out up);
            modelorg.X = Vector3.Dot(temp, forward);
            modelorg.Y = -Vector3.Dot(temp, right);
            modelorg.Z = Vector3.Dot(temp, up);
        }

        // calculate dynamic lighting for bmodel if it's not an
        // instanced model
        if (clmodel.firstmodelsurface != 0 && gl_flashblend.value == 0)
        {
            for (int k = 0; k < q_shared.MAX_DLIGHTS; k++)
            {
                if ((cl_dlights[k].die < cl.time) || (cl_dlights[k].radius == 0))
                {
                    continue;
                }

                R_MarkLights(cl_dlights[k], 1 << k, clmodel.nodes[clmodel.hulls[0].firstclipnode]);
            }
        }

        GL.PushMatrix();
        e.angles.X = -e.angles.X;       // stupid quake bug
        R_RotateForEntity(e);
        e.angles.X = -e.angles.X;       // stupid quake bug

        int surfOffset = clmodel.firstmodelsurface;

        msurface_t[] psurf = clmodel.surfaces; //[clmodel.firstmodelsurface];

        //
        // draw texture
        //
        for (int i = 0; i < clmodel.nummodelsurfaces; i++, surfOffset++)
        {
            // find which side of the node we are on
            mplane_t pplane = psurf[surfOffset].plane;

            float dot = Vector3.Dot(modelorg, pplane.normal) - pplane.dist;

            // draw the polygon
            bool planeBack = (psurf[surfOffset].flags & q_shared.SURF_PLANEBACK) != 0;
            if ((planeBack && (dot < -q_shared.BACKFACE_EPSILON)) || (!planeBack && (dot > q_shared.BACKFACE_EPSILON)))
            {
                if (gl_texsort.value != 0)
                {
                    R_RenderBrushPoly(psurf[surfOffset]);
                }
                else
                {
                    R_DrawSequentialPoly(psurf[surfOffset]);
                }
            }
        }

        R_BlendLightmaps();

        GL.PopMatrix();
    }
Ejemplo n.º 13
0
        /*
        =================
        Mod_LoadPlanes
        =================
        */
        static void Mod_LoadPlanes(bspfile.lump_t l)
        {
            int			        i, j;
            mplane_t[]	        @out;
            bspfile.dplane_t[]  @in;
            int			        count;
            int			        bits;

            if ((l.filelen % bspfile.sizeof_dplane_t) != 0)
                sys_linux.Sys_Error ("MOD_LoadBmodel: funny lump size in " + loadmodel.name);
            count = l.filelen / bspfile.sizeof_dplane_t;
            bspfile.ByteBuffer buf = new bspfile.ByteBuffer(mod_base, l.fileofs);
            @in = new bspfile.dplane_t[count];
            @out = new mplane_t[count];
            for (int kk = 0; kk < count; kk++)
            {
                @in[kk] = (bspfile.dplane_t)buf;
                buf.ofs += bspfile.sizeof_dplane_t;
                @out[kk] = new mplane_t();
            }

            loadmodel.planes = @out;
            loadmodel.numplanes = count;

            for ( i=0 ; i<count ; i++)
            {
                bits = 0;
                for (j=0 ; j<3 ; j++)
                {
                    @out[i].normal[j] = @in[i].normal[j];
                    if (@out[i].normal[j] < 0)
                        bits |= 1<<j;
                }

                @out[i].dist = @in[i].dist;
                @out[i].type = (byte)@in[i].type;
                @out[i].signbits = (byte)bits;
            }
        }
Ejemplo n.º 14
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);
    }
Ejemplo n.º 15
0
    public static void R_SplitEntityOnNode(mnodebase_t node)
    {
        if (node.contents == q_shared.CONTENTS_SOLID)
        {
            return;
        }

        // add an efrag if the node is a leaf
        if (node.contents < 0)
        {
            if (r_pefragtopnode == null)
            {
                r_pefragtopnode = node as mnode_t;
            }

            mleaf_t leaf = (mleaf_t)(object)node;

            // grab an efrag off the free list
            efrag_t ef = cl.free_efrags;
            if (ef == null)
            {
                Con_Printf("Too many efrags!\n");
                return; // no free fragments...
            }
            cl.free_efrags = cl.free_efrags.entnext;

            ef.entity = r_addent;

            // add the entity link
            // *lastlink = ef;
            if (_LastObj is entity_t)
            {
                ((entity_t)_LastObj).efrag = ef;
            }
            else
            {
                ((efrag_t)_LastObj).entnext = ef;
            }
            _LastObj   = ef; // lastlink = &ef->entnext;
            ef.entnext = null;

            // set the leaf links
            ef.leaf     = leaf;
            ef.leafnext = leaf.efrags;
            leaf.efrags = ef;

            return;
        }

        // NODE_MIXED
        mnode_t n = node as mnode_t;

        if (n == null)
        {
            return;
        }

        mplane_t splitplane = n.plane;
        int      sides      = Mathlib.BoxOnPlaneSide(ref r_emins, ref r_emaxs, splitplane);

        if (sides == 3)
        {
            // split on this plane
            // if this is the first splitter of this bmodel, remember it
            if (r_pefragtopnode == null)
            {
                r_pefragtopnode = n;
            }
        }

        // recurse down the contacted sides
        if ((sides & 1) != 0)
        {
            R_SplitEntityOnNode(n.children[0]);
        }

        if ((sides & 2) != 0)
        {
            R_SplitEntityOnNode(n.children[1]);
        }
    }
Ejemplo n.º 16
0
    public static int _BoxOnPlaneSide(ref Vector3 emins, ref Vector3 emaxs, mplane_t p)
    {
        // general case
        float dist1, dist2;

        switch (p.signbits)
        {
        case 0:
            dist1 = p.normal.X * emaxs.X + p.normal.Y * emaxs.Y + p.normal.Z * emaxs.Z;
            dist2 = p.normal.X * emins.X + p.normal.Y * emins.Y + p.normal.Z * emins.Z;
            break;

        case 1:
            dist1 = p.normal.X * emins.X + p.normal.Y * emaxs.Y + p.normal.Z * emaxs.Z;
            dist2 = p.normal.X * emaxs.X + p.normal.Y * emins.Y + p.normal.Z * emins.Z;
            break;

        case 2:
            dist1 = p.normal.X * emaxs.X + p.normal.Y * emins.Y + p.normal.Z * emaxs.Z;
            dist2 = p.normal.X * emins.X + p.normal.Y * emaxs.Y + p.normal.Z * emins.Z;
            break;

        case 3:
            dist1 = p.normal.X * emins.X + p.normal.Y * emins.Y + p.normal.Z * emaxs.Z;
            dist2 = p.normal.X * emaxs.X + p.normal.Y * emaxs.Y + p.normal.Z * emins.Z;
            break;

        case 4:
            dist1 = p.normal.X * emaxs.X + p.normal.Y * emaxs.Y + p.normal.Z * emins.Z;
            dist2 = p.normal.X * emins.X + p.normal.Y * emins.Y + p.normal.Z * emaxs.Z;
            break;

        case 5:
            dist1 = p.normal.X * emins.X + p.normal.Y * emaxs.Y + p.normal.Z * emins.Z;
            dist2 = p.normal.X * emaxs.X + p.normal.Y * emins.Y + p.normal.Z * emaxs.Z;
            break;

        case 6:
            dist1 = p.normal.X * emaxs.X + p.normal.Y * emins.Y + p.normal.Z * emins.Z;
            dist2 = p.normal.X * emins.X + p.normal.Y * emaxs.Y + p.normal.Z * emaxs.Z;
            break;

        case 7:
            dist1 = p.normal.X * emins.X + p.normal.Y * emins.Y + p.normal.Z * emins.Z;
            dist2 = p.normal.X * emaxs.X + p.normal.Y * emaxs.Y + p.normal.Z * emaxs.Z;
            break;

        default:
            dist1 = dist2 = 0;                  // shut up compiler
            game_engine.Sys_Error("BoxOnPlaneSide:  Bad signbits");
            break;
        }

        int sides = 0;

        if (dist1 >= p.dist)
        {
            sides = 1;
        }
        if (dist2 < p.dist)
        {
            sides |= 2;
        }

#if PARANOID
        if (sides == 0)
        {
            Sys.Error("BoxOnPlaneSide: sides==0");
        }
#endif

        return(sides);
    }