示例#1
0
        public int RecursiveLightPoint(int idx_node, Vector3 start, Vector3 end)
        {
            float front;
            float back;
            float frac;
            int   side;

            CShared.SCPlane plane;
            Vector3         mid;
            int             surf;
            int             s, t;
            int             ds, dt;

            CModel.SMTexInfo tex;
            int lightmap;
            int r;

            CModel.SMNode node;

            node = CQ2BSP.SWorldData.nodes[idx_node];

            if (node.contents != -1)
            {
                return(-1); // didn't hit anything
            }
            // calculate mid point
            // FIXME: optimize for axial
            plane = CQ2BSP.SWorldData.planes[node.plane];
            front = Vector3.Dot(start, plane.normal) - plane.dist;
            back  = Vector3.Dot(end, plane.normal) - plane.dist;
            side  = Convert.ToInt32(front < 0);

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

            frac  = front / (front - back);
            mid.X = start.X + (end.X - start.X) * frac;
            mid.Y = start.Y + (end.Y - start.Y) * frac;
            mid.Z = start.Z + (end.Z - start.Z) * frac;


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

            if (r >= 0)
            {
                return(r); // hit something
            }
            if (Convert.ToInt32(back < 0) == side)
            {
                return(-1); // didn't hit anything
            }
            // check for impact on this node
            lightspot.X = mid.X;
            lightspot.Y = mid.Y;
            lightspot.Z = mid.Z;
            lightplane  = plane;

            surf = node.firstsurface;
            for (int i = 0; i < node.numsurfaces; i++, surf++)
            {
                Vector3 vecs;

                if ((CQ2BSP.SWorldData.surfaces[surf].flags & CModel.EMSurface.SURF_DRAWTURB) == CModel.EMSurface.SURF_DRAWTURB)
                {
                    continue; // no lightmaps
                }
                if ((CQ2BSP.SWorldData.surfaces[surf].flags & CModel.EMSurface.SURF_DRAWSKY) == CModel.EMSurface.SURF_DRAWSKY)
                {
                    continue; // no lightmaps
                }
                tex = CQ2BSP.SWorldData.texinfo[CQ2BSP.SWorldData.surfaces[surf].texinfo];

                vecs.X = tex.vecs[0].X;
                vecs.Y = tex.vecs[0].Y;
                vecs.Z = tex.vecs[0].Z;
                s      = (int)(Vector3.Dot(mid, vecs) + tex.vecs[0].W);

                vecs.X = tex.vecs[1].X;
                vecs.Y = tex.vecs[1].Y;
                vecs.Z = tex.vecs[1].Z;
                t      = (int)(Vector3.Dot(mid, vecs) + tex.vecs[1].W);


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

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

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

                if (CQ2BSP.SWorldData.surfaces[surf].samples == -1)
                {
                    return(0);
                }

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

                lightmap     = CQ2BSP.SWorldData.surfaces[surf].samples;
                pointcolor.X = CShared.vec3_origin.X;
                pointcolor.Y = CShared.vec3_origin.Y;
                pointcolor.Z = CShared.vec3_origin.Z;

                if (lightmap != -1)
                {
                    Vector3 scale;

                    lightmap += 3 * (dt * ((CQ2BSP.SWorldData.surfaces[surf].extents[0] >> 4) + 1) + ds);

                    for (int maps = 0; maps < CQ2BSP.MAXLIGHTMAPS && CQ2BSP.SWorldData.surfaces[surf].styles[maps] != 255; maps++)
                    {
                        scale = Vector3.Zero;

                        for (i = 0; i < 3; i++)
                        {
                            // jkrige ??
                            //scale.X = CLocal.gl_modulate * CClient.cl.RefDef.lightstyles[CQ2BSP.SWorldData.surfaces[surf].styles[maps]].rgb[0];
                            //scale.Y = CLocal.gl_modulate * CClient.cl.RefDef.lightstyles[CQ2BSP.SWorldData.surfaces[surf].styles[maps]].rgb[1];
                            //scale.Z = CLocal.gl_modulate * CClient.cl.RefDef.lightstyles[CQ2BSP.SWorldData.surfaces[surf].styles[maps]].rgb[2];
                            scale.X = 1.0f;
                            scale.Y = 1.0f;
                            scale.Z = 1.0f;
                            // jkrige ??
                        }

                        pointcolor.X += CQ2BSP.SWorldData.lightdata[lightmap + 0] * scale.X * (1.0f / 255);
                        pointcolor.Y += CQ2BSP.SWorldData.lightdata[lightmap + 1] * scale.Y * (1.0f / 255);
                        pointcolor.Z += CQ2BSP.SWorldData.lightdata[lightmap + 2] * scale.Z * (1.0f / 255);

                        lightmap += 3 * ((CQ2BSP.SWorldData.surfaces[surf].extents[0] >> 4) + 1) * ((CQ2BSP.SWorldData.surfaces[surf].extents[1] >> 4) + 1);
                    }
                }

                return(1);
            }

            // go down back side
            return(RecursiveLightPoint(node.children[Convert.ToInt32(side == 0)], mid, end));
        }
示例#2
0
        public int RecursiveLightPoint(int idx_node, Vector3 start, Vector3 end)
        {
            float front;
            float back;
            float frac;
            int side;
            CShared.SCPlane plane;
            Vector3 mid;
            int surf;
            int s, t;
            int ds, dt;
            CModel.SMTexInfo tex;
            int lightmap;
            int r;
            CModel.SMNode node;

            node = CQ2BSP.SWorldData.nodes[idx_node];

            if (node.contents != -1)
                return -1; // didn't hit anything

            // calculate mid point
            // FIXME: optimize for axial
            plane = CQ2BSP.SWorldData.planes[node.plane];
            front = Vector3.Dot(start, plane.normal) - plane.dist;
            back = Vector3.Dot(end, plane.normal) - plane.dist;
            side = Convert.ToInt32(front < 0);

            if (Convert.ToInt32(back < 0) == side)
                return RecursiveLightPoint(node.children[side], start, end);

            frac = front / (front - back);
            mid.X = start.X + (end.X - start.X) * frac;
            mid.Y = start.Y + (end.Y - start.Y) * frac;
            mid.Z = start.Z + (end.Z - start.Z) * frac;

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

            if (r >= 0)
                return r; // hit something

            if (Convert.ToInt32(back < 0) == side)
                return -1; // didn't hit anything

            // check for impact on this node
            lightspot.X = mid.X;
            lightspot.Y = mid.Y;
            lightspot.Z = mid.Z;
            lightplane = plane;

            surf = node.firstsurface;
            for (int i = 0; i < node.numsurfaces; i++, surf++)
            {
                Vector3 vecs;

                if ((CQ2BSP.SWorldData.surfaces[surf].flags & CModel.EMSurface.SURF_DRAWTURB) == CModel.EMSurface.SURF_DRAWTURB)
                    continue; // no lightmaps

                if ((CQ2BSP.SWorldData.surfaces[surf].flags & CModel.EMSurface.SURF_DRAWSKY) == CModel.EMSurface.SURF_DRAWSKY)
                    continue; // no lightmaps

                tex = CQ2BSP.SWorldData.texinfo[CQ2BSP.SWorldData.surfaces[surf].texinfo];

                vecs.X = tex.vecs[0].X;
                vecs.Y = tex.vecs[0].Y;
                vecs.Z = tex.vecs[0].Z;
                s = (int)(Vector3.Dot(mid, vecs) + tex.vecs[0].W);

                vecs.X = tex.vecs[1].X;
                vecs.Y = tex.vecs[1].Y;
                vecs.Z = tex.vecs[1].Z;
                t = (int)(Vector3.Dot(mid, vecs) + tex.vecs[1].W);

                if (s < CQ2BSP.SWorldData.surfaces[surf].texturemins[0] || t < CQ2BSP.SWorldData.surfaces[surf].texturemins[1])
                    continue;

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

                if (ds > CQ2BSP.SWorldData.surfaces[surf].extents[0] || dt > CQ2BSP.SWorldData.surfaces[surf].extents[1])
                    continue;

                if (CQ2BSP.SWorldData.surfaces[surf].samples == -1)
                    return 0;

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

                lightmap = CQ2BSP.SWorldData.surfaces[surf].samples;
                pointcolor.X = CShared.vec3_origin.X;
                pointcolor.Y = CShared.vec3_origin.Y;
                pointcolor.Z = CShared.vec3_origin.Z;

                if (lightmap != -1)
                {
                    Vector3 scale;

                    lightmap += 3 * (dt * ((CQ2BSP.SWorldData.surfaces[surf].extents[0] >> 4) + 1) + ds);

                    for (int maps = 0; maps < CQ2BSP.MAXLIGHTMAPS && CQ2BSP.SWorldData.surfaces[surf].styles[maps] != 255; maps++)
                    {
                        scale = Vector3.Zero;

                        for (i = 0; i < 3; i++)
                        {
                            // jkrige ??
                            //scale.X = CLocal.gl_modulate * CClient.cl.RefDef.lightstyles[CQ2BSP.SWorldData.surfaces[surf].styles[maps]].rgb[0];
                            //scale.Y = CLocal.gl_modulate * CClient.cl.RefDef.lightstyles[CQ2BSP.SWorldData.surfaces[surf].styles[maps]].rgb[1];
                            //scale.Z = CLocal.gl_modulate * CClient.cl.RefDef.lightstyles[CQ2BSP.SWorldData.surfaces[surf].styles[maps]].rgb[2];
                            scale.X = 1.0f;
                            scale.Y = 1.0f;
                            scale.Z = 1.0f;
                            // jkrige ??
                        }

                        pointcolor.X += CQ2BSP.SWorldData.lightdata[lightmap + 0] * scale.X * (1.0f / 255);
                        pointcolor.Y += CQ2BSP.SWorldData.lightdata[lightmap + 1] * scale.Y * (1.0f / 255);
                        pointcolor.Z += CQ2BSP.SWorldData.lightdata[lightmap + 2] * scale.Z * (1.0f / 255);

                        lightmap += 3 * ((CQ2BSP.SWorldData.surfaces[surf].extents[0] >> 4) + 1) * ((CQ2BSP.SWorldData.surfaces[surf].extents[1] >> 4) + 1);
                    }
                }

                return 1;
            }

            // go down back side
            return RecursiveLightPoint(node.children[Convert.ToInt32(side == 0)], mid, end);
        }