예제 #1
0
        private 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   = client.cl.worldmodel.surfaces;
            int          offset = n.firstsurface;

            for (int i = 0; i < n.numsurfaces; i++, offset++)
            {
                if ((surf[offset].flags & Surf.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 < bsp_file.MAXLIGHTMAPS && surf[offset].styles[maps] != 255; maps++)
                    {
                        int scale = _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));
        }
예제 #2
0
        /// <summary>
        /// R_AddDynamicLights
        /// </summary>
        private static void AddDynamicLights(msurface_t surf)
        {
            int        smax = (surf.extents[0] >> 4) + 1;
            int        tmax = (surf.extents[1] >> 4) + 1;
            mtexinfo_t tex  = surf.texinfo;

            dlight_t[] dlights = client.DLights;

            for (int lnum = 0; lnum < client.MAX_DLIGHTS; lnum++)
            {
                if ((surf.dlightbits & (1 << lnum)) == 0)
                {
                    continue;           // not lit by this light
                }
                float rad  = dlights[lnum].radius;
                float dist = Vector3.Dot(dlights[lnum].origin, surf.plane.normal) - surf.plane.dist;
                rad -= Math.Abs(dist);
                float minlight = dlights[lnum].minlight;
                if (rad < minlight)
                {
                    continue;
                }
                minlight = rad - minlight;

                Vector3 impact = dlights[lnum].origin - surf.plane.normal * dist;

                float local0 = Vector3.Dot(impact, tex.vecs[0].Xyz) + tex.vecs[0].W;
                float local1 = Vector3.Dot(impact, tex.vecs[1].Xyz) + tex.vecs[1].W;

                local0 -= surf.texturemins[0];
                local1 -= surf.texturemins[1];

                for (int t = 0; t < tmax; t++)
                {
                    int td = (int)(local1 - t * 16);
                    if (td < 0)
                    {
                        td = -td;
                    }
                    for (int s = 0; s < smax; s++)
                    {
                        int sd = (int)(local0 - s * 16);
                        if (sd < 0)
                        {
                            sd = -sd;
                        }
                        if (sd > td)
                        {
                            dist = sd + (td >> 1);
                        }
                        else
                        {
                            dist = td + (sd >> 1);
                        }
                        if (dist < minlight)
                        {
                            _BlockLights[t * smax + s] += (uint)((rad - dist) * 256);
                        }
                    }
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Mod_LoadTexinfo
        /// </summary>
        static void LoadTexInfo(ref lump_t l)
        {
            //in = (void *)(mod_base + l->fileofs);
            if ((l.filelen % texinfo_t.SizeInBytes) != 0)
                Sys.Error("MOD_LoadBmodel: funny lump size in {0}", _LoadModel.name);

            int count = l.filelen / texinfo_t.SizeInBytes;
            mtexinfo_t[] infos = new mtexinfo_t[count]; // out = Hunk_AllocName ( count*sizeof(*out), loadname);

            for (int i = 0; i < infos.Length; i++)
                infos[i] = new mtexinfo_t();

            _LoadModel.texinfo = infos;
            _LoadModel.numtexinfo = count;

            for (int i = 0; i < count; i++)//, in++, out++)
            {
                texinfo_t src = Sys.BytesToStructure<texinfo_t>(_ModBase, l.fileofs + i * texinfo_t.SizeInBytes);

                for (int j = 0; j < 2; j++)
                    infos[i].vecs[j] = Common.LittleVector4(src.vecs, j * 4);

                float len1 = infos[i].vecs[0].Length;
                float len2 = infos[i].vecs[1].Length;
                len1 = (len1 + len2) / 2;
                if (len1 < 0.32)
                    infos[i].mipadjust = 4;
                else if (len1 < 0.49)
                    infos[i].mipadjust = 3;
                else if (len1 < 0.99)
                    infos[i].mipadjust = 2;
                else
                    infos[i].mipadjust = 1;

                int miptex = Common.LittleLong(src.miptex);
                infos[i].flags = Common.LittleLong(src.flags);

                if (_LoadModel.textures == null)
                {
                    infos[i].texture = Render.NoTextureMip;	// checkerboard texture
                    infos[i].flags = 0;
                }
                else
                {
                    if (miptex >= _LoadModel.numtextures)
                        Sys.Error("miptex >= loadmodel->numtextures");
                    infos[i].texture = _LoadModel.textures[miptex];
                    if (infos[i].texture == null)
                    {
                        infos[i].texture = Render.NoTextureMip; // texture not found
                        infos[i].flags = 0;
                    }
                }
            }
        }