Ejemplo n.º 1
0
        /*
         * =================
         * =
         * = P_LoadSegs
         * =
         * =================
         */

        public static void P_LoadSegs(int lump)
        {
            w_wad.CacheInfo data;
            int             i, j;

            DoomData.mapseg_t ml;
            r_local.seg_t     li, lj;
            r_local.line_t    ldef;
            int linedef, side;

            numsegs = w_wad.W_LumpLength(lump) / 12;
            segs    = new r_local.seg_t[numsegs];
            data    = w_wad.W_CacheLumpNum(lump, DoomDef.PU_STATIC);
            BinaryReader br = new BinaryReader(new MemoryStream(data.data));

            for (i = 0; i < numsegs; i++)
            {
                ml         = new DoomData.mapseg_t();
                ml.v1      = br.ReadInt16();
                ml.v2      = br.ReadInt16();
                ml.angle   = br.ReadInt16();
                ml.linedef = br.ReadInt16();
                ml.side    = br.ReadInt16();
                ml.offset  = br.ReadInt16();

                li    = new r_local.seg_t();
                li.v1 = vertexes[ml.v1];
                li.v2 = vertexes[ml.v2];

                li.angle       = (uint)ml.angle << 16;
                li.offset      = ml.offset << 16;
                linedef        = ml.linedef;
                ldef           = lines[linedef];
                li.linedef     = ldef;
                side           = ml.side;
                li.sidedef     = sides[ldef.sidenum[side]];
                li.frontsector = sides[ldef.sidenum[side]].sector;
                if ((ldef.flags & DoomData.ML_TWOSIDED) != 0)
                {
                    li.backsector = sides[ldef.sidenum[side ^ 1]].sector;
                }
                else
                {
                    li.backsector = null;
                }
                Vector2 dir =
                    new Vector2(li.v2.x >> DoomDef.FRACBITS, li.v2.y >> DoomDef.FRACBITS) -
                    new Vector2(li.v1.x >> DoomDef.FRACBITS, li.v1.y >> DoomDef.FRACBITS);
                dir.Normalize();
                li.normal.X = dir.Y;
                li.normal.Y = -dir.X;
                li.dir      = dir;
                segs[i]     = li;
            }

            // [dsl] Search for segment neighbors. We do this for the ambient occlusion parts
            for (i = 0; i < numsegs; i++)
            {
                li = segs[i];
                if (li.frontsector == li.backsector)
                {
                    continue;
                }
                for (j = 0; j < numsegs; j++)
                {
                    if (i == j)
                    {
                        continue;
                    }
                    lj = segs[j];
                    if (lj.frontsector == lj.backsector)
                    {
                        continue;
                    }
                    if (Vector2.Dot(li.normal, lj.normal) < 0)
                    {
                        continue;
                    }
                    if (lj.v2.x == li.v1.x &&
                        lj.v2.y == li.v1.y)
                    {
                        if (Vector2.Dot(lj.normal, li.dir) > 0)
                        {
                            li.left.Add(lj);
                        }
                    }
                    if (lj.v1.x == li.v2.x &&
                        lj.v1.y == li.v2.y)
                    {
                        if (Vector2.Dot(li.normal, lj.dir) > 0)
                        {
                            li.right.Add(lj);
                        }
                    }
                }
            }
        }
Ejemplo n.º 2
0
        //=============================================================================

        /*
         * ======================
         * =
         * = R_AddLine
         * =
         * = Clips the given segment and adds any visible pieces to the line list
         * =
         * ======================
         */

        public static void R_AddLine(r_local.seg_t line)
        {
            int  x1, x2;
            uint angle1, angle2, span, tspan;

            curline = line;

            // OPTIMIZE: quickly reject orthogonal back sides

            angle1 = r_main.R_PointToAngle(line.v1.x, line.v1.y);
            angle2 = r_main.R_PointToAngle(line.v2.x, line.v2.y);

            //
            // clip to view edges
            // OPTIMIZE: make constant out of 2*clipangle (FIELDOFVIEW)
            span = angle1 - angle2;
            if (span >= DoomDef.ANG180)
            {
                return;                         // back side
            }
            r_segs.rw_angle1 = (int)angle1;     // global angle needed by segcalc
            angle1          -= r_main.viewangle;
            angle2          -= r_main.viewangle;

            tspan = angle1 + r_main.clipangle;
            if (tspan > 2 * r_main.clipangle)
            {
                tspan -= 2 * r_main.clipangle;
                if (tspan >= span)
                {
                    return;                     // totally off the left edge
                }
                angle1 = r_main.clipangle;
            }
            tspan = r_main.clipangle - angle2;
            if (tspan > 2 * r_main.clipangle)
            {
                tspan -= 2 * r_main.clipangle;
                if (tspan >= span)
                {
                    return;                     // totally off the left edge
                }
                angle2 = (uint)(-r_main.clipangle);
            }

            //
            // the seg is in the view range, but not necessarily visible
            //
            angle1 = (uint)((int)(angle1 + DoomDef.ANG90) >> (int)DoomDef.ANGLETOFINESHIFT);
            angle2 = (uint)((int)(angle2 + DoomDef.ANG90) >> (int)DoomDef.ANGLETOFINESHIFT);
            x1     = r_main.viewangletox[angle1];
            x2     = r_main.viewangletox[angle2];
            if (x1 == x2)
            {
                return;                                         // does not cross a pixel
            }
            backsector = line.backsector;

            // [dsl] There were gotos here. Yup
            if (backsector == null)
            {
                R_ClipSolidWallSegment(x1, x2 - 1);                             // single sided line
                return;
            }

            if (backsector.ceilingheight <= frontsector.floorheight ||
                backsector.floorheight >= frontsector.ceilingheight)
            {
                R_ClipSolidWallSegment(x1, x2 - 1);                             // closed door
                return;
            }

            if (backsector.ceilingheight != frontsector.ceilingheight ||
                backsector.floorheight != frontsector.floorheight)
            {
                R_ClipPassWallSegment(x1, x2 - 1);                              // window
                return;
            }

            // reject empty lines used for triggers and special events
            if (backsector.ceilingpic == frontsector.ceilingpic &&
                backsector.floorpic == frontsector.floorpic &&
                backsector.lightlevel == frontsector.lightlevel &&
                curline.sidedef.
                midtexture == 0)
            {
                return;
            }

            R_ClipPassWallSegment(x1, x2 - 1);
        }
Ejemplo n.º 3
0
        private static void testLine(r_local.sector_t sector, r_local.seg_t li, ref Vector4 in_prevScreenBB)
        {
#if DEBUG
            ++portalChecked;
#endif

            r_local.sector_t nextSector;
            if (li.frontsector == sector)
            {
                if (li.backsector == null)
                {
                    return;
                }
                nextSector = li.backsector;
            }
            else
            {
                return;
            }

            Vector3 v1, v2, screenSpace;
            v1.X = li.v1.x >> DoomDef.FRACBITS;
            v1.Y = li.v1.y >> DoomDef.FRACBITS;
            v2.X = li.v2.x >> DoomDef.FRACBITS;
            v2.Y = li.v2.y >> DoomDef.FRACBITS;
            v1.Z = Math.Max(li.frontsector.floorheight >> DoomDef.FRACBITS, li.backsector.floorheight >> DoomDef.FRACBITS);
            v2.Z = Math.Min(li.frontsector.ceilingheight >> DoomDef.FRACBITS, li.backsector.ceilingheight >> DoomDef.FRACBITS);
            if (v1.Z >= v2.Z)
            {
                return;
            }

            //	if (frustum.Contains(liBB) == ContainmentType.Disjoint) return;

            Vector4 screenBB;
            Vector2 originalBB;
            screenBB.X = screenSize.X + 10000;
            screenBB.Y = screenSize.Y + 10000;
            screenBB.Z = -10000;
            screenBB.W = -10000;
            bool allBehind = true;

            screenSpace = v1;
            Project(ref screenSpace);
            screenBB.X = screenSpace.X < screenBB.X ? screenSpace.X : screenBB.X;
            screenBB.W = screenSpace.Y > screenBB.W ? screenSpace.Y : screenBB.W;
            if (screenSpace.Z < camLimit)
            {
                allBehind = false;
            }

            screenSpace   = v1;
            screenSpace.Z = v2.Z;
            Project(ref screenSpace);
            screenBB.X = screenSpace.X < screenBB.X ? screenSpace.X : screenBB.X;
            screenBB.Y = screenSpace.Y < screenBB.Y ? screenSpace.Y : screenBB.Y;
            if (screenSpace.Z < camLimit)
            {
                allBehind = false;
            }

            screenSpace   = v2;
            screenSpace.Z = v1.Z;
            Project(ref screenSpace);
            screenBB.Z = screenSpace.X > screenBB.Z ? screenSpace.X : screenBB.Z;
            screenBB.W = screenSpace.Y > screenBB.W ? screenSpace.Y : screenBB.W;
            if (screenSpace.Z < camLimit)
            {
                allBehind = false;
            }

            screenSpace   = v2;
            screenSpace.Z = v2.Z;
            Project(ref screenSpace);
            screenBB.Y = screenSpace.Y < screenBB.Y ? screenSpace.Y : screenBB.Y;
            screenBB.Z = screenSpace.X > screenBB.Z ? screenSpace.X : screenBB.Z;
            if (screenBB.X >= screenBB.Z)
            {
                return;
            }
            if (screenBB.Y >= screenBB.W)
            {
                return;
            }
            if (screenSpace.Z < camLimit)
            {
                allBehind = false;
            }

            if (allBehind)
            {
                return;
            }

            if (screenBB.X < 0)
            {
                screenBB.X = 0;
            }
            if (screenBB.Y < 0)
            {
                screenBB.Y = 0;
            }
            if (screenBB.Z > screenSize.X)
            {
                screenBB.Z = screenSize.X;
            }
            if (screenBB.W > screenSize.Y)
            {
                screenBB.W = screenSize.Y;
            }

            originalBB.X = screenBB.X;
            originalBB.Y = screenBB.Z;

            // Merge with previous bounding
            screenBB.X = screenBB.X > in_prevScreenBB.X ? screenBB.X : in_prevScreenBB.X;
            screenBB.Y = screenBB.Y > in_prevScreenBB.Y ? screenBB.Y : in_prevScreenBB.Y;
            screenBB.Z = screenBB.Z < in_prevScreenBB.Z ? screenBB.Z : in_prevScreenBB.Z;
            screenBB.W = screenBB.W < in_prevScreenBB.W ? screenBB.W : in_prevScreenBB.W;

            if (screenBB.X >= screenBB.Z)
            {
                return;
            }
            if (screenBB.Y >= screenBB.W)
            {
                return;
            }
            if (screenBB.Z < 0 || screenBB.X > screenSize.X)
            {
                return;
            }
            if (screenBB.W < 0 || screenBB.Y > screenSize.Y)
            {
                return;
            }

            if (originalBB.X == screenBB.X &&
                originalBB.Y == screenBB.Z)
            {
                li.culling_alreadyFullyIncluded = checkId;
            }

            debugRects.Add(screenBB);
#if DEBUG
            ++portalTraversed;
#endif

            li.culling_checkId = checkId;
            addSector(nextSector, ref screenBB);
            li.culling_checkId = 0;
        }