Ejemplo n.º 1
0
        int R_LightVec(Vector3 start, Vector3 end, bool useLightStyles, ref Vector3 c)
        {
            c.X = c.Y = c.Z = 0;
            int skysurf = -1;
            LightVecState state = new LightVecState();
            state.skySurf = -1;
            state.start = start;
            state.end = end;
            state.hitFrac = 1.0f;
            int retSurfId = RecursiveLightPoint(0, 0f, 1f, ref c, state);

            if (retSurfId == -1 && skysurf != -1)
                return skysurf;

            return retSurfId;
        }
Ejemplo n.º 2
0
        int RecursiveLightPoint(int n, float start, float end, ref Vector3 c, LightVecState state)
        {
            while (n >= 0)
            {
                dnode_t node = world.nodes[n];
                cplane_t plane = node.plane;

                float startDotn = Vector3.Dot(state.start, plane.normal);
                float deltaDotn = Vector3.Dot(state.end - state.start, plane.normal);

                float front = startDotn + start * deltaDotn - plane.dist;
                float back = deltaDotn + end * deltaDotn - plane.dist;
                bool side = front < 0;

                // If they're both on the same side of the plane, don't bother to split
                // just check the appropriate child
                int surfid = 0;
                if ((back < 0) == side)
                {
                    n = node.children[side ? 1 : 0];
                    continue;
                    //surfid = RecursiveLightPoint(node.children[side ? 1 : 0], start, end, ref c, state);
                    //return surfid;
                }

                // calculate mid point
                float frac = front / (front - back);
                float mid = start * (1.0f - frac) + end * frac;

                // go down front side
                surfid = RecursiveLightPoint(node.children[side ? 1 : 0], start, mid, ref c, state);
                if (surfid != -1)
                    return surfid;  // hit something

                // check for impact on this node
                surfid = FindIntersectionSurfaceAtNode(n, mid, ref c, state);
                if (surfid != -1)
                    return surfid;

                // go down back side
                surfid = RecursiveLightPoint(node.children[!side ? 1 : 0], mid, end, ref c, state);
                return surfid;

                break;
            }

            // didn't hit anything
            if (n < 0)
            {
                // FIXME: Should we always do this? It could get expensive...
                // Check all the faces at the leaves
                return FindIntersectionSurfaceAtLeaf(world.leafs[-1 - n], start, end, ref c, state);
            }

            return -1;
        }
Ejemplo n.º 3
0
        int FindIntersectionSurfaceAtLeaf(dleaf_t leaf, float start, float end, ref Vector3 c, LightVecState state)
        {
            int clostestSurf = -1;
            for (int i = 0; i < leaf.numleaffaces; i++)
            {
                int surfid = world.leafFaces[leaf.firstleafface + i];
                face_t face = world.faces_t[surfid];

                // Don't add surfaces that have displacement; they are handled above
                // In fact, don't even set the vis frame; we need it unset for translucent
                // displacement code
                if (face.dispinfo != -1)
                    continue;

                if ((face.face.texinfo.flags & SurfFlags.SURF_NODRAW) == SurfFlags.SURF_NODRAW)
                    continue;

                cplane_t plane = face.face.plane_t;

                // Backface cull...
                if (Vector3.Dot(plane.normal, (state.end - state.start)) > 0.0f)
                    continue;

                float startdotn = Vector3.Dot(state.start, plane.normal);
                float deltadotn = Vector3.Dot((state.end - state.start), plane.normal);

                float front = startdotn + start * deltadotn - plane.dist;
                float back = startdotn + end * deltadotn - plane.dist;

                bool side = front < 0.0f;

                // Blow it off if it doesn't split the plane...
                if ((back < 0.0f) == side)
                    continue;

                // Don't test a surface that is farther away from the closest found intersection
                float frac = front / (front - back);
                if (frac >= state.hitFrac)
                    continue;

                float mid = start * (1.0f - frac) + end * frac;

                // Check this surface to see if there's an intersection
                if (FindIntersectionAtSurface(surfid, mid, ref c, state))
                {
                    clostestSurf = surfid;
                }
            }

            // Return the closest surface hit
            return clostestSurf;
        }
Ejemplo n.º 4
0
        int FindIntersectionSurfaceAtNode(int n, float t, ref Vector3 c, LightVecState state)
        {
            dnode_t node = world.nodes[n];
            int surfid = node.firstface;
            for (int i = 0; i < node.numfaces; i++, surfid++)
            {
                // Don't immediately return when we hit sky;
                // we may actually hit another surface
                SurfFlags flags = world.faces[world.leafFaces[surfid]].texinfo.flags;
                if ((flags & SurfFlags.SURF_SKY) == SurfFlags.SURF_SKY)
                {
                    state.skySurf = surfid;
                    continue;
                }

                // Don't let water surfaces affect us
                if ((flags & SurfFlags.SURF_WARP) == SurfFlags.SURF_WARP)
                    continue;

                if(FindIntersectionAtSurface(surfid, t, ref c, state))
                    return surfid;
            }
            return -1;
        }
Ejemplo n.º 5
0
        //-----------------------------------------------------------------------------
        // Tests a particular surface
        //-----------------------------------------------------------------------------
        bool FindIntersectionAtSurface(int surfid, float f, ref Vector3 c, LightVecState state)
        {
            // no lightmaps on this surface? punt...
            // FIXME: should be water surface?
            SurfFlags flags = world.faces[world.leafFaces[surfid]].texinfo.flags;
            if ((flags & SurfFlags.SURF_NOLIGHT) == SurfFlags.SURF_NOLIGHT) // SURFDRAW_NOLIGHT
                return false;

            // Compute the actual point
            Vector3 pt = ViewParams.VectorMA(state.start, f, state.end - state.start);
            texinfo_t tex = world.faces[world.leafFaces[surfid]].texinfo;

            // See where in lightmap space our intersection point is

            float s = Vector3.Dot(pt, tex.lightmapVecs[0]) +
                tex.lightmapVecs2[0];
            float t = Vector3.Dot(pt, tex.lightmapVecs[1]) +
                tex.lightmapVecs2[1];

            // Not in the bounds of our lightmap? punt...
            int[] luxMins = world.faces[world.leafFaces[surfid]].face_t.LightmapTextureMinsInLuxels;
            if (s < luxMins[0] ||
                t < luxMins[1])
                return false;

            // assuming a square lightmap (FIXME: which ain't always the case),
            // lets see if it lies in that rectangle. If not, punt...
            float ds = s - luxMins[0];
            float dt = t - luxMins[1];
            int[] luxExtends = world.faces[world.leafFaces[surfid]].face_t.LightmapTextureSizeInLuxels;
            if (ds > luxExtends[0] ||
                dt > luxExtends[1])
                return false;

            // Store off the hit distance...
            state.hitFrac = f;

            // You heard the man!
            // TODO

            ComputeLightmapColorFromAverage(world.faces[world.leafFaces[surfid]].face_t, state.useLightstyles, ref c);

            return true;
        }