Exemplo n.º 1
0
        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 < BspFile.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));
        }
Exemplo n.º 2
0
        /// <summary>
        /// R_AddDynamicLights
        /// </summary>
        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);
                        }
                    }
                }
            }
        }