예제 #1
0
 public virtual void Mod_SetParent(mnode_t node, mnode_t parent)
 {
     node.parent = parent;
     if (node.contents != -1)
     {
         return;
     }
     Mod_SetParent(node.children[0], node);
     Mod_SetParent(node.children[1], node);
 }
예제 #2
0
        /*
         * =============================================================================
         *
         * DYNAMIC LIGHTS
         *
         * =============================================================================
         */

        /*
         * ============= R_MarkLights =============
         */
        protected void R_MarkLights(dlight_t light, int bit, mnode_t node)
        {
            cplane_t   splitplane;
            float      dist;
            msurface_t surf;
            int        i;
            int        sidebit;

            if (node.contents != -1)
            {
                return;
            }

            splitplane = node.plane;
            dist       = Math3D.DotProduct(light.origin, splitplane.normal) - splitplane.dist;

            if (dist > light.intensity - OpenGLRenderApi.DLIGHT_CUTOFF)
            {
                this.R_MarkLights(light, bit, node.children[0]);

                return;
            }

            if (dist < -light.intensity + OpenGLRenderApi.DLIGHT_CUTOFF)
            {
                this.R_MarkLights(light, bit, node.children[1]);

                return;
            }

            // mark the polygons
            for (i = 0; i < node.numsurfaces; i++)
            {
                surf = this.r_worldmodel.surfaces[node.firstsurface + i];

                dist    = Math3D.DotProduct(light.origin, surf.plane.normal) - surf.plane.dist;
                sidebit = dist >= 0 ? 0 : Defines.SURF_PLANEBACK;

                if ((surf.flags & Defines.SURF_PLANEBACK) != sidebit)
                {
                    continue;
                }

                if (surf.dlightframe != this.r_dlightframecount)
                {
                    surf.dlightbits  = 0;
                    surf.dlightframe = this.r_dlightframecount;
                }

                surf.dlightbits |= bit;
            }

            this.R_MarkLights(light, bit, node.children[0]);
            this.R_MarkLights(light, bit, node.children[1]);
        }
예제 #3
0
        public virtual void Mod_LoadNodes(lump_t l)
        {
            Int32 i, j, count, p;

            qfiles.dnode_t in_renamed;
            mnode_t[]      out_renamed;
            if ((l.filelen % qfiles.dnode_t.SIZE) != 0)
            {
                Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name);
            }
            count              = l.filelen / qfiles.dnode_t.SIZE;
            out_renamed        = new mnode_t[count];
            loadmodel.nodes    = out_renamed;
            loadmodel.numnodes = count;
            ByteBuffer bb = ByteBuffer.Wrap(mod_base, l.fileofs, l.filelen);

            bb.Order = ByteOrder.LittleEndian;
            for (i = 0; i < count; i++)
            {
                out_renamed[i] = new mnode_t();
            }
            for (i = 0; i < count; i++)
            {
                in_renamed = new dnode_t(bb);
                for (j = 0; j < 3; j++)
                {
                    out_renamed[i].mins[j] = in_renamed.mins[j];
                    out_renamed[i].maxs[j] = in_renamed.maxs[j];
                }

                p = in_renamed.planenum;
                out_renamed[i].plane        = loadmodel.planes[p];
                out_renamed[i].firstsurface = in_renamed.firstface;
                out_renamed[i].numsurfaces  = in_renamed.numfaces;
                out_renamed[i].contents     = -1;
                for (j = 0; j < 2; j++)
                {
                    p = in_renamed.children[j];
                    if (p >= 0)
                    {
                        out_renamed[i].children[j] = loadmodel.nodes[p];
                    }
                    else
                    {
                        out_renamed[i].children[j] = loadmodel.leafs[-1 - p];
                    }
                }
            }

            Mod_SetParent(loadmodel.nodes[0], null);
        }
예제 #4
0
        public override void R_MarkLights(dlight_t light, Int32 bit, mnode_t node)
        {
            cplane_t   splitplane;
            Single     dist;
            msurface_t surf;
            Int32      i;
            Int32      sidebit;

            if (node.contents != -1)
            {
                return;
            }
            splitplane = node.plane;
            dist       = Math3D.DotProduct(light.origin, splitplane.normal) - splitplane.dist;
            if (dist > light.intensity - DLIGHT_CUTOFF)
            {
                R_MarkLights(light, bit, node.children[0]);
                return;
            }

            if (dist < -light.intensity + DLIGHT_CUTOFF)
            {
                R_MarkLights(light, bit, node.children[1]);
                return;
            }

            for (i = 0; i < node.numsurfaces; i++)
            {
                surf    = r_worldmodel.surfaces[node.firstsurface + i];
                dist    = Math3D.DotProduct(light.origin, surf.plane.normal) - surf.plane.dist;
                sidebit = (dist >= 0) ? 0 : Defines.SURF_PLANEBACK;
                if ((surf.flags & Defines.SURF_PLANEBACK) != sidebit)
                {
                    continue;
                }
                if (surf.dlightframe != r_dlightframecount)
                {
                    surf.dlightbits  = 0;
                    surf.dlightframe = r_dlightframecount;
                }

                surf.dlightbits |= bit;
            }

            R_MarkLights(light, bit, node.children[0]);
            R_MarkLights(light, bit, node.children[1]);
        }
예제 #5
0
    public static void R_AddEfrags(entity_t ent)
    {
        if (ent.model == null)
        {
            return;
        }

        r_addent        = ent;
        _LastObj        = ent; //  lastlink = &ent->efrag;
        r_pefragtopnode = null;

        model_t entmodel = ent.model;

        r_emins = ent.origin + entmodel.mins;
        r_emaxs = ent.origin + entmodel.maxs;

        R_SplitEntityOnNode(cl.worldmodel.nodes[0]);
        ent.topnode = r_pefragtopnode;
    }
예제 #6
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]);
        }
    }
예제 #7
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]);
    }
예제 #8
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];
            }
        }
    }
예제 #9
0
        protected float[] lightspot = { 0, 0, 0 };         // vec3_t

        private int RecursiveLightPoint(mnode_t node, float[] start, float[] end)
        {
            if (node.contents != -1)
            {
                return(-1);                // didn't hit anything
            }
            msurface_t surf;
            int        s, t, ds, dt;
            int        i;
            mtexinfo_t tex;
            int        maps;

            float[] mid = { 0, 0, 0 };

            // calculate mid point

            // FIXME: optimize for axial
            var plane     = node.plane;
            var front     = Math3D.DotProduct(start, plane.normal) - plane.dist;
            var back      = Math3D.DotProduct(end, plane.normal) - plane.dist;
            var side      = front < 0;
            var sideIndex = side ? 1 : 0;

            if (back < 0 == side)
            {
                return(this.RecursiveLightPoint(node.children[sideIndex], start, end));
            }

            var frac = front / (front - back);

            mid[0] = start[0] + (end[0] - start[0]) * frac;
            mid[1] = start[1] + (end[1] - start[1]) * frac;
            mid[2] = start[2] + (end[2] - start[2]) * frac;

            // go down front side
            var r = this.RecursiveLightPoint(node.children[sideIndex], start, mid);

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

            var surfIndex = node.firstsurface;

            float[] scale = { 0, 0, 0 };

            for (i = 0; i < node.numsurfaces; i++, surfIndex++)
            {
                surf = this.r_worldmodel.surfaces[surfIndex];

                if ((surf.flags & (Defines.SURF_DRAWTURB | Defines.SURF_DRAWSKY)) != 0)
                {
                    continue;                     // no lightmaps
                }
                tex = surf.texinfo;

                s = (int)(Math3D.DotProduct(mid, tex.vecs[0]) + tex.vecs[0][3]);
                t = (int)(Math3D.DotProduct(mid, tex.vecs[1]) + tex.vecs[1][3]);

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

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

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

                if (surf.samples == null)
                {
                    return(0);
                }

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

                var lightmapIndex = 0;

                Math3D.VectorCopy(Globals.vec3_origin, this.pointcolor);

                if (surf.samples != null)
                {
                    //float[] scale = {0, 0, 0};
                    float[] rgb;
                    lightmapIndex += 3 * (dt * ((surf.extents[0] >> 4) + 1) + ds);

                    for (maps = 0; maps < Defines.MAXLIGHTMAPS && surf.styles[maps] != (byte)255; maps++)
                    {
                        rgb      = this.r_newrefdef.lightstyles[surf.styles[maps] & 0xFF].rgb;
                        scale[0] = this.gl_modulate.value * rgb[0];
                        scale[1] = this.gl_modulate.value * rgb[1];
                        scale[2] = this.gl_modulate.value * rgb[2];

                        this.pointcolor[0] += surf.samples[surf.samplesOffset + lightmapIndex + 0] * scale[0] * (1.0f / 255);
                        this.pointcolor[1] += surf.samples[surf.samplesOffset + lightmapIndex + 1] * scale[1] * (1.0f / 255);
                        this.pointcolor[2] += surf.samples[surf.samplesOffset + lightmapIndex + 2] * scale[2] * (1.0f / 255);
                        lightmapIndex      += 3 * ((surf.extents[0] >> 4) + 1) * ((surf.extents[1] >> 4) + 1);
                    }
                }

                return(1);
            }

            // go down back side
            return(this.RecursiveLightPoint(node.children[1 - sideIndex], mid, end));
        }
예제 #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));
    }
예제 #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]);
    }
예제 #12
0
 /*
 =================
 Mod_SetParent
 =================
 */
 static void Mod_SetParent(node_or_leaf_t node, mnode_t parent)
 {
     node.parent = parent;
     if (node.contents < 0)
         return;
     mnode_t _node = (mnode_t)node;
     Mod_SetParent((node_or_leaf_t)_node.children[0], _node);
     Mod_SetParent((node_or_leaf_t)_node.children[1], _node);
 }
예제 #13
0
        /*
        =================
        Mod_LoadNodes
        =================
        */
        static void Mod_LoadNodes(bspfile.lump_t l)
        {
            int			        i, j, count, p;
            bspfile.dnode_t[]   @in;
            mnode_t[] 	        @out;

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

            loadmodel.nodes = @out;
            loadmodel.numnodes = count;

            for ( i=0 ; i<count ; i++)
            {
                for (j=0 ; j<3 ; j++)
                {
                    @out[i].minmaxs[j] = @in[i].mins[j];
                    @out[i].minmaxs[3+j] = @in[i].maxs[j];
                }

                p = @in[i].planenum;
                @out[i].plane = loadmodel.planes[p];

                @out[i].firstsurface = @in[i].firstface;
                @out[i].numsurfaces = @in[i].numfaces;

                for (j=0 ; j<2 ; j++)
                {
                    p = @in[i].children[j];
                    if (p >= 0)
                        @out[i].children[j] = loadmodel.nodes[p];
                    else
                        @out[i].children[j] = loadmodel.leafs[-1 - p];
                }
            }

            Mod_SetParent (loadmodel.nodes[0], null);	// sets nodes and leafs
        }
예제 #14
0
        public virtual Int32 RecursiveLightPoint(mnode_t node, Single[] start, Single[] end)
        {
            if (node.contents != -1)
            {
                return(-1);
            }
            cplane_t plane     = node.plane;
            var      front     = Math3D.DotProduct(start, plane.normal) - plane.dist;
            var      back      = Math3D.DotProduct(end, plane.normal) - plane.dist;
            var      side      = (front < 0);
            var      sideIndex = (side) ? 1 : 0;

            if ((back < 0) == side)
            {
                return(RecursiveLightPoint(node.children[sideIndex], start, end));
            }
            var frac = front / (front - back);

            Single[] mid = Vec3Cache.Get();
            mid[0] = start[0] + (end[0] - start[0]) * frac;
            mid[1] = start[1] + (end[1] - start[1]) * frac;
            mid[2] = start[2] + (end[2] - start[2]) * frac;
            var r = RecursiveLightPoint(node.children[sideIndex], start, mid);

            if (r >= 0)
            {
                Vec3Cache.Release();
                return(r);
            }

            if ((back < 0) == side)
            {
                Vec3Cache.Release();
                return(-1);
            }

            Math3D.VectorCopy(mid, lightspot);
            lightplane = plane;
            var        surfIndex = node.firstsurface;
            msurface_t surf;
            Int32      s, t, ds, dt;
            mtexinfo_t tex;
            ByteBuffer lightmap;
            Int32      maps;

            for (var i = 0; i < node.numsurfaces; i++, surfIndex++)
            {
                surf = r_worldmodel.surfaces[surfIndex];
                if ((surf.flags & (Defines.SURF_DRAWTURB | Defines.SURF_DRAWSKY)) != 0)
                {
                    continue;
                }
                tex = surf.texinfo;
                s   = ( Int32 )(Math3D.DotProduct(mid, tex.vecs[0]) + tex.vecs[0][3]);
                t   = ( Int32 )(Math3D.DotProduct(mid, tex.vecs[1]) + tex.vecs[1][3]);
                if (s < surf.texturemins[0] || t < surf.texturemins[1])
                {
                    continue;
                }
                ds = s - surf.texturemins[0];
                dt = t - surf.texturemins[1];
                if (ds > surf.extents[0] || dt > surf.extents[1])
                {
                    continue;
                }
                if (surf.samples == null)
                {
                    return(0);
                }
                ds     >>= 4;
                dt     >>= 4;
                lightmap = surf.samples;
                var lightmapIndex = 0;
                Math3D.VectorCopy(Globals.vec3_origin, pointcolor);
                if (lightmap != null)
                {
                    Single[] rgb;
                    lightmapIndex += 3 * (dt * ((surf.extents[0] >> 4) + 1) + ds);
                    Single scale0, scale1, scale2;
                    for (maps = 0; maps < Defines.MAXLIGHTMAPS && surf.styles[maps] != ( Byte )255; maps++)
                    {
                        rgb            = r_newrefdef.lightstyles[surf.styles[maps] & 0xFF].rgb;
                        scale0         = gl_modulate.value * rgb[0];
                        scale1         = gl_modulate.value * rgb[1];
                        scale2         = gl_modulate.value * rgb[2];
                        pointcolor[0] += (lightmap.Get(lightmapIndex + 0) & 0xFF) * scale0 * (1F / 255);
                        pointcolor[1] += (lightmap.Get(lightmapIndex + 1) & 0xFF) * scale1 * (1F / 255);
                        pointcolor[2] += (lightmap.Get(lightmapIndex + 2) & 0xFF) * scale2 * (1F / 255);
                        lightmapIndex += 3 * ((surf.extents[0] >> 4) + 1) * ((surf.extents[1] >> 4) + 1);
                    }
                }

                Vec3Cache.Release();
                return(1);
            }

            r = RecursiveLightPoint(node.children[1 - sideIndex], mid, end);
            Vec3Cache.Release();
            return(r);
        }
예제 #15
0
        public virtual void R_RecursiveWorldNode(mnode_t node)
        {
            if (node.contents == Defines.CONTENTS_SOLID)
            {
                return;
            }
            if (node.visframe != r_visframecount)
            {
                return;
            }
            if (R_CullBox(node.mins, node.maxs))
            {
                return;
            }
            Int32      c;
            msurface_t mark;

            if (node.contents != -1)
            {
                mleaf_t pleaf = ( mleaf_t )node;
                if (r_newrefdef.areabits != null)
                {
                    if (((r_newrefdef.areabits[pleaf.area >> 3] & 0xFF) & (1 << (pleaf.area & 7))) == 0)
                    {
                        return;
                    }
                }

                var markp = 0;
                mark = pleaf.GetMarkSurface(markp);
                c    = pleaf.nummarksurfaces;
                if (c != 0)
                {
                    do
                    {
                        mark.visframe = r_framecount;
                        mark          = pleaf.GetMarkSurface(++markp);
                    }while (--c != 0);
                }

                return;
            }

            cplane_t plane = node.plane;
            Single   dot;

            switch (plane.type)

            {
            case Defines.PLANE_X:
                dot = modelorg[0] - plane.dist;
                break;

            case Defines.PLANE_Y:
                dot = modelorg[1] - plane.dist;
                break;

            case Defines.PLANE_Z:
                dot = modelorg[2] - plane.dist;
                break;

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

            Int32 side, sidebit;

            if (dot >= 0F)
            {
                side    = 0;
                sidebit = 0;
            }
            else
            {
                side    = 1;
                sidebit = Defines.SURF_PLANEBACK;
            }

            R_RecursiveWorldNode(node.children[side]);
            msurface_t surf;
            image_t    image;

            for (c = 0; c < node.numsurfaces; c++)
            {
                surf = r_worldmodel.surfaces[node.firstsurface + c];
                if (surf.visframe != r_framecount)
                {
                    continue;
                }
                if ((surf.flags & Defines.SURF_PLANEBACK) != sidebit)
                {
                    continue;
                }
                if ((surf.texinfo.flags & Defines.SURF_SKY) != 0)
                {
                    R_AddSkySurface(surf);
                }
                else if ((surf.texinfo.flags & (Defines.SURF_TRANS33 | Defines.SURF_TRANS66)) != 0)
                {
                    surf.texturechain = r_alpha_surfaces;
                    r_alpha_surfaces  = surf;
                }
                else
                {
                    if ((surf.flags & Defines.SURF_DRAWTURB) == 0)
                    {
                        GL_RenderLightmappedPoly(surf);
                    }
                    else
                    {
                        image              = R_TextureAnimation(surf.texinfo);
                        surf.texturechain  = image.texturechain;
                        image.texturechain = surf;
                    }
                }
            }

            R_RecursiveWorldNode(node.children[1 - side]);
        }
예제 #16
0
 public abstract void R_MarkLights(dlight_t light, Int32 bit, mnode_t node);
예제 #17
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]);
        }
    }