Exemple #1
0
        // This builds the geometry. Returns false when no geometry created.
        public override bool Setup()
        {
            //mxd. Middle part exists only when either masked or maskedsolid flag is set
            bool masked      = this.Sidedef.Masked;        // wal->cstat & 16
            bool maskedsolid = this.Sidedef.MaskedSolid;   // wal->cstat & 32

            if (masked || maskedsolid)
            {
                Vector2D vl, vr;

                // Left and right vertices for this sidedef
                if (Sidedef.IsFront)
                {
                    vl = new Vector2D(Sidedef.Line.Start.Position);
                    vr = new Vector2D(Sidedef.Line.End.Position);
                }
                else
                {
                    vl = new Vector2D(Sidedef.Line.End.Position);
                    vr = new Vector2D(Sidedef.Line.Start.Position);
                }

                // Keep top and bottom planes for intersection testing
                Sector s  = Sidedef.Sector;
                Sector os = Sidedef.Other.Sector;
                top    = ((s.CeilingPlane.GetZ(vl) < os.CeilingPlane.GetZ(vl) && s.CeilingPlane.GetZ(vr) < os.CeilingPlane.GetZ(vr)) ? s.CeilingPlane : os.CeilingPlane);
                bottom = ((os.FloorPlane.GetZ(vl) > s.FloorPlane.GetZ(vl) && os.FloorPlane.GetZ(vr) > s.FloorPlane.GetZ(vr)) ? os.FloorPlane : s.FloorPlane);

                // Get ceiling and floor heights
                float cl = top.GetZ(vl);
                float cr = top.GetZ(vr);
                float fl = bottom.GetZ(vl);
                float fr = bottom.GetZ(vr);

                // Anything to see?
                if (cl > fl || cr > fr)
                {
                    // Mostly the same as upper wall part
                    if (masked && maskedsolid)
                    {
                        // Transparency and brightness
                        int brightness;
                        if (Sidedef.SemiTransparent)
                        {
                            brightness      = MapElement.CalculateBrightness(Sidedef.Shade, (byte)(Sidedef.Transparent ? 85 : 170));
                            this.RenderPass = RenderPass.Alpha;
                        }
                        else
                        {
                            brightness      = MapElement.CalculateBrightness(Sidedef.Shade);
                            this.RenderPass = RenderPass.Mask;
                        }

                        // Texture given?
                        Texture = General.Map.Data.GetImageData(Sidedef.MaskedTileIndex);
                        if (Texture is UnknownImage)
                        {
                            // Use missing texture
                            //Texture = General.Map.Data.MissingTexture3D;
                            setuponloadedimage = -1;
                        }
                        else if (!Texture.IsImageLoaded)
                        {
                            setuponloadedimage = Sidedef.MaskedTileIndex;
                        }

                        // Create initial polygon, which is just a quad between floor and ceiling
                        var poly = new List <WorldVertex>
                        {
                            new WorldVertex(vl.x, vl.y, fl, brightness, 0, 0),
                            new WorldVertex(vl.x, vl.y, cl, brightness, 0, 0),
                            new WorldVertex(vr.x, vr.y, cr, brightness, 0, 0),
                            new WorldVertex(vr.x, vr.y, fr, brightness, 0, 0)
                        };

                        //mxd. Set UV coords the Build way...
                        int xref    = (!Sidedef.ImageFlipX ? 1 : 0);
                        int xrefinv = 1 - xref;

                        int yref = (Sidedef.AlignImageToBottom ?
                                    Math.Min(Sidedef.Sector.FloorHeight, Sidedef.Other.Sector.FloorHeight) :
                                    Math.Max(Sidedef.Sector.CeilingHeight, Sidedef.Other.Sector.CeilingHeight));

                        float ypancoef         = CalculateOffsetV(Sidedef.OffsetY, Texture, false);
                        float scaledtexrepeaty = ((Texture.Height * 128f) / Sidedef.RepeatY);

                        for (int i = 0; i < poly.Count; i++)
                        {
                            var   p    = poly[i];
                            float dist = ((i == 2 || i == 3) ? xref : xrefinv);

                            p.u = ((dist * 8.0f * Sidedef.RepeatX) + Sidedef.OffsetX) / Texture.Width;
                            p.v = ((yref + (-p.z)) / scaledtexrepeaty) - ypancoef;
                            if (Sidedef.ImageFlipY)
                            {
                                p.v *= -1;
                            }

                            poly[i] = p;
                        }

                        // Now we create triangles from the polygon. The polygon is convex and clockwise, so this is a piece of cake.
                        List <WorldVertex> verts = new List <WorldVertex>(3);
                        for (int k = 1; k < (poly.Count - 1); k++)
                        {
                            verts.Add(poly[0]);
                            verts.Add(poly[k]);
                            verts.Add(poly[k + 1]);
                        }

                        // Apply vertices
                        SetVertices(verts);
                        return(true);
                    }
                    // Mostly the same as lower wall part
                    else                     // masked || maskedsolid
                    {
                        //INFO: used refwall props: picnum, palette, shade, xpanning, ypanning
                        var refwall    = (Sidedef.SwapBottomImage ? GetNextWall() : Sidedef);
                        int brightness = MapElement.CalculateBrightness(refwall.Shade);

                        // Texture given?
                        Texture = General.Map.Data.GetImageData(refwall.TileIndex);
                        if (Texture is UnknownImage)
                        {
                            // Use missing texture
                            //Texture = General.Map.Data.MissingTexture3D;
                            setuponloadedimage = -1;
                        }
                        else if (!Texture.IsImageLoaded)
                        {
                            setuponloadedimage = Sidedef.TileIndex;
                        }

                        // Create initial polygon, which is just a quad between floor and ceiling
                        var poly = new List <WorldVertex>
                        {
                            new WorldVertex(vl.x, vl.y, fl, brightness, 0, 0),
                            new WorldVertex(vl.x, vl.y, cl, brightness, 0, 0),
                            new WorldVertex(vr.x, vr.y, cr, brightness, 0, 0),
                            new WorldVertex(vr.x, vr.y, fr, brightness, 0, 0)
                        };

                        //mxd. Set UV coords the Build way...
                        int   xref             = (!Sidedef.ImageFlipX ? 1 : 0);
                        int   xrefinv          = 1 - xref;
                        int   yref             = (!refwall.AlignImageToBottom ? refwall.Other.Sector.FloorHeight : refwall.Sector.CeilingHeight);
                        float ypancoef         = CalculateOffsetV(refwall.OffsetY, Texture, !refwall.AlignImageToBottom);
                        float scaledtexrepeaty = ((Texture.Height * 128f) / Sidedef.RepeatY);

                        // (!(wal->cstat & 2) && (wal->cstat & 256)) || ((wal->cstat & 2) && (wall[nwallnum].cstat & 256))
                        bool flipy = (!Sidedef.SwapBottomImage && Sidedef.ImageFlipY) || (Sidedef.SwapBottomImage && refwall.ImageFlipY);

                        for (int i = 0; i < poly.Count; i++)
                        {
                            var   p    = poly[i];
                            float dist = ((i == 2 || i == 3) ? xref : xrefinv);

                            p.u = ((dist * 8.0f * Sidedef.RepeatX) + refwall.OffsetX) / Texture.Width;
                            p.v = ((yref + (-p.z)) / scaledtexrepeaty) - ypancoef;
                            if (flipy)
                            {
                                p.v *= -1;
                            }

                            poly[i] = p;
                        }

                        // Now we create triangles from the polygon. The polygon is convex and clockwise, so this is a piece of cake.
                        List <WorldVertex> verts = new List <WorldVertex>(3);
                        for (int k = 1; k < (poly.Count - 1); k++)
                        {
                            verts.Add(poly[0]);
                            verts.Add(poly[k]);
                            verts.Add(poly[k + 1]);
                        }

                        // Apply vertices
                        base.SetVertices(verts);
                        return(true);
                    }
                }
            }

            // No geometry for invisible wall
            top    = Sidedef.Sector.CeilingPlane;
            bottom = Sidedef.Sector.CeilingPlane;               // bottom same as top so that it has a height of 0 (otherwise it will still be picked up by object picking)
            SetVertices(new WorldVertex[0]);
            return(false);
        }
Exemple #2
0
        // This builds the geometry. Returns false when no geometry created.
        public override bool Setup()
        {
            Vector2D vl, vr;

            // Left and right vertices for this sidedef
            if (Sidedef.IsFront)
            {
                vl = new Vector2D(Sidedef.Line.Start.Position);
                vr = new Vector2D(Sidedef.Line.End.Position);
            }
            else
            {
                vl = new Vector2D(Sidedef.Line.End.Position);
                vr = new Vector2D(Sidedef.Line.Start.Position);
            }

            // Keep top and bottom planes for intersection testing
            //mxd. Our sector's ceiling can be lower than the other sector's floor!
            Sector s  = Sidedef.Sector;
            Sector os = Sidedef.Other.Sector;

            top    = ((s.CeilingPlane.GetZ(vl) < os.FloorPlane.GetZ(vl) && s.CeilingPlane.GetZ(vr) < os.FloorPlane.GetZ(vr)) ? s.CeilingPlane : os.FloorPlane);
            bottom = Sidedef.Sector.FloorPlane;

            // Get ceiling and floor heights
            float cl = top.GetZ(vl);
            float cr = top.GetZ(vr);
            float fl = bottom.GetZ(vl);
            float fr = bottom.GetZ(vr);

            // Anything to see?
            if (cl > fl || cr > fr)
            {
                //INFO: used refwall props: picnum, palette, shade, xpanning, ypanning
                var refwall    = (Sidedef.SwapBottomImage ? GetNextWall() : Sidedef);
                int brightness = MapElement.CalculateBrightness(refwall.Shade);

                // Texture given?
                Texture = General.Map.Data.GetImageData(refwall.TileIndex);
                if (Texture is UnknownImage)
                {
                    // Use missing texture
                    //Texture = General.Map.Data.MissingTexture3D;
                    setuponloadedimage = -1;
                }
                else if (!Texture.IsImageLoaded)
                {
                    setuponloadedimage = Sidedef.TileIndex;
                }

                // Create initial polygon, which is just a quad between floor and ceiling
                var poly = new List <WorldVertex>
                {
                    new WorldVertex(vl.x, vl.y, fl, brightness, 0, 0),
                    new WorldVertex(vl.x, vl.y, cl, brightness, 0, 0),
                    new WorldVertex(vr.x, vr.y, cr, brightness, 0, 0),
                    new WorldVertex(vr.x, vr.y, fr, brightness, 0, 0)
                };

                //mxd. Set UV coords the Build way...
                int   xref             = (!Sidedef.ImageFlipX ? 1 : 0);
                int   xrefinv          = 1 - xref;
                int   yref             = (!refwall.AlignImageToBottom ? Sidedef.Other.Sector.FloorHeight : Sidedef.Sector.CeilingHeight);
                float ypancoef         = CalculateOffsetV(refwall.OffsetY, Texture, !refwall.AlignImageToBottom);
                float scaledtexrepeaty = ((Texture.Height * 128f) / Sidedef.RepeatY);

                // (!(wal->cstat & 2) && (wal->cstat & 256)) || ((wal->cstat & 2) && (wall[nwallnum].cstat & 256))
                bool flipy = (!Sidedef.SwapBottomImage && Sidedef.ImageFlipY) || (Sidedef.SwapBottomImage && refwall.ImageFlipY);

                for (int i = 0; i < poly.Count; i++)
                {
                    var   p    = poly[i];
                    float dist = ((i == 2 || i == 3) ? xref : xrefinv);

                    p.u = ((dist * 8.0f * Sidedef.RepeatX) + refwall.OffsetX) / Texture.Width;
                    p.v = ((yref + (-p.z)) / scaledtexrepeaty) - ypancoef;
                    if (flipy)
                    {
                        p.v *= -1;
                    }

                    poly[i] = p;
                }

                // Cut off the part above the other floor
                CropPoly(ref poly, top, false);

                if (poly.Count > 2)
                {
                    // Now we create triangles from the polygon. The polygon is convex and clockwise, so this is a piece of cake.
                    List <WorldVertex> verts = new List <WorldVertex>(3);
                    for (int k = 1; k < (poly.Count - 1); k++)
                    {
                        verts.Add(poly[0]);
                        verts.Add(poly[k]);
                        verts.Add(poly[k + 1]);
                    }

#if DEBUG
                    //mxd. We should have either 3 or 6 verts, right?
                    if (verts.Count != 3 && verts.Count != 6)
                    {
                        throw new NotImplementedException("Unexpected number of vertices!");
                    }
#endif

                    // Apply vertices
                    base.SetVertices(verts);
                    return(true);
                }
            }

            // No geometry for invisible wall
            base.SetVertices(new WorldVertex[0]);
            return(false);
        }
Exemple #3
0
        // This builds the thing geometry. Returns false when nothing was created.
        public virtual bool Setup()
        {
            // Must have a width and height!
            float radius, height;

            // Find the sector in which the thing resides
            Thing.DetermineSector(mode.BlockMap);

            if (sprite != null)
            {
                //mxd. Transparency and brightness
                int brightness;
                if (Thing.SemiTransparent)
                {
                    brightness      = MapElement.CalculateBrightness(Thing.Shade, (byte)(Thing.Transparent ? 85 : 170));
                    this.RenderPass = RenderPass.Alpha;
                }
                else
                {
                    brightness      = MapElement.CalculateBrightness(Thing.Shade);
                    this.RenderPass = RenderPass.Mask;
                }

                // Check if the texture is loaded
                sprite.LoadImage();
                isloaded = sprite.IsImageLoaded;

                if (isloaded)
                {
                    base.Texture = sprite;

                    // Determine sprite size and offsets
                    bool flooraligned = Thing.FlatAligned;
                    bool wallaligned  = Thing.WallAligned;
                    bool truecentered = Thing.TrueCentered;

                    float xratio = Thing.RepeatX * ((flooraligned && truecentered) ? 0.2f : 0.25f);
                    float yratio = Thing.RepeatY * 0.25f;

                    int xsize = (int)(sprite.Width * xratio);
                    int ysize = (int)(sprite.Height * yratio);

                    int tilexoff = Thing.OffsetX + sprite.OffsetX;
                    int tileyoff = Thing.OffsetY + sprite.OffsetY;

                    int xoff = (int)(tilexoff * xratio);
                    int yoff = (int)(tileyoff * yratio);

                    if (truecentered && !flooraligned)
                    {
                        yoff -= ysize / 2;                                                   // Seems that centeryoff shenanigans in polymer_updatesprite.cpp do exactly the same thing...
                    }
                    bool xflip = Thing.FlipX;
                    bool yflip = Thing.FlipY;

                    // Initially set flipu and flipv.
                    bool flipu = (xflip ^ flooraligned);
                    bool flipv = (yflip && !flooraligned);

                    if (flipu)
                    {
                        xoff = -xoff;
                    }
                    if (yflip && (flooraligned || wallaligned))
                    {
                        yoff = -yoff;
                    }

                    radius = xsize * 0.5f;
                    height = ysize;

                    // Make vertices
                    WorldVertex[] verts = new WorldVertex[6];
                    verts[0] = new WorldVertex(-radius + xoff, 0.0f, yoff, brightness, 0.0f, 1.0f);
                    verts[1] = new WorldVertex(-radius + xoff, 0.0f, height + yoff, brightness, 0.0f, 0.0f);
                    verts[2] = new WorldVertex(radius + xoff, 0.0f, height + yoff, brightness, 1.0f, 0.0f);
                    verts[3] = verts[0];
                    verts[4] = verts[2];
                    verts[5] = new WorldVertex(radius + xoff, 0.0f, yoff, brightness, 1.0f, 1.0f);

                    // Update UVs if needed
                    if (flipu || flipv)
                    {
                        for (int i = 0; i < 6; i++)
                        {
                            if (flipu)
                            {
                                verts[i].u = (verts[i].u - 1.0f) * -1.0f;
                            }
                            if (flipv)
                            {
                                verts[i].v = (verts[i].v - 1.0f) * -1.0f;
                            }
                        }
                    }

                    SetVertices(verts);
                }
                else
                {
                    base.Texture = General.Map.Data.Hourglass3D;

                    // Determine sprite size
                    radius = Math.Min(Texture.Width / 2f, Texture.Height / 2f);
                    height = Math.Min(Texture.Width, Texture.Height);

                    // Make vertices
                    WorldVertex[] verts = new WorldVertex[6];
                    verts[0] = new WorldVertex(-radius, 0.0f, 0.0f, brightness, 0.0f, 1.0f);
                    verts[1] = new WorldVertex(-radius, 0.0f, height, brightness, 0.0f, 0.0f);
                    verts[2] = new WorldVertex(+radius, 0.0f, height, brightness, 1.0f, 0.0f);
                    verts[3] = verts[0];
                    verts[4] = verts[2];
                    verts[5] = new WorldVertex(+radius, 0.0f, 0.0f, brightness, 1.0f, 1.0f);
                    SetVertices(verts);
                }
            }
            else
            {
                // Use some default values...
                radius = MINIMUM_RADIUS;
                height = MINIMUM_HEIGHT;

                SetVertices(new WorldVertex[0]);
            }

            // Determine position
            Vector3D pos = Thing.Position;

            if (Thing.Sector != null)
            {
                pos.z = Thing.Sector.FloorPlane.GetZ(Thing.Position.x, Thing.Position.y);
            }
            if (Thing.Position.z > 0)
            {
                pos.z += Thing.Position.z;
            }

            // Check if above ceiling
            if ((Thing.Sector != null) && ((pos.z + height) > Thing.Sector.CeilingHeight))
            {
                // Put thing against ceiling
                pos.z = Thing.Sector.CeilingHeight - height;
            }

            // Apply settings
            SetPosition(pos);
            SetCageSize(Math.Max(radius, MINIMUM_RADIUS), Math.Max(height, MINIMUM_HEIGHT));
            SetCageColor(Thing.Color);

            // Keep info for object picking
            cageradius2 = radius * Angle2D.SQRT2;
            cageradius2 = cageradius2 * cageradius2;
            pos2d       = pos;
            boxp1       = new Vector3D(pos.x - radius, pos.y - radius, pos.z);
            boxp2       = new Vector3D(pos.x + radius, pos.y + radius, pos.z + height);

            // Done
            changed = false;
            return(true);
        }
Exemple #4
0
        // This builds the geometry. Returns false when no geometry created.
        public override bool Setup()
        {
            // Left and right vertices for this wall
            Vector2D vl, vr;

            if (Sidedef.IsFront)
            {
                vl = new Vector2D(Sidedef.Line.Start.Position);
                vr = new Vector2D(Sidedef.Line.End.Position);
            }
            else
            {
                vl = new Vector2D(Sidedef.Line.End.Position);
                vr = new Vector2D(Sidedef.Line.Start.Position);
            }

            // Keep top and bottom planes for intersection testing
            top    = Sidedef.Sector.CeilingPlane;
            bottom = Sidedef.Sector.FloorPlane;

            // Get ceiling and floor heights
            float cl = top.GetZ(vl);
            float cr = top.GetZ(vr);
            float fl = bottom.GetZ(vl);
            float fr = bottom.GetZ(vr);

            // Anything to see?
            if (cl - fl > 0.01f || cr - fr > 0.01f)
            {
                int brightness = MapElement.CalculateBrightness(Sidedef.Shade);

                // Texture given?
                Texture = General.Map.Data.GetImageData(Sidedef.TileIndex);
                if (Texture is UnknownImage)
                {
                    // Use missing texture
                    //Texture = General.Map.Data.MissingTexture3D;
                    setuponloadedimage = -1;
                }
                else if (!Texture.IsImageLoaded)
                {
                    setuponloadedimage = Sidedef.TileIndex;
                }

                WorldVertex[] verts = new WorldVertex[6];
                verts[0] = new WorldVertex(vl.x, vl.y, fl, brightness, 0, 0);
                verts[1] = new WorldVertex(vl.x, vl.y, cl, brightness, 0, 0);
                verts[2] = new WorldVertex(vr.x, vr.y, cr, brightness, 0, 0);
                verts[3] = verts[0];
                verts[4] = verts[2];
                verts[5] = new WorldVertex(vr.x, vr.y, fr, brightness, 0, 0);

                //mxd. Set UV coords the Build way...
                int   xref             = (!Sidedef.ImageFlipX ? 1 : 0);
                int   xrefinv          = 1 - xref;
                int   yref             = (Sidedef.AlignImageToBottom ? Sidedef.Sector.FloorHeight : Sidedef.Sector.CeilingHeight);
                float ypancoef         = CalculateOffsetV(Sidedef.OffsetY, Texture, !Sidedef.AlignImageToBottom);
                float scaledtexrepeaty = ((Texture.Height * 128f) / Sidedef.RepeatY);

                for (int i = 0; i < 6; i++)
                {
                    float dist = ((i == 2 || i == 4 || i == 5) ? xref : xrefinv);

                    verts[i].u = ((dist * 8.0f * Sidedef.RepeatX) + Sidedef.OffsetX) / Texture.Width;
                    // w->wall.buffer[i].v = (-(float)(yref + (w->wall.buffer[i].y * 16)) / ((tilesiz[curpicnum].y * 2048.0f) / (float)(wal->yrepeat))) + ypancoef;
                    verts[i].v = ((yref + (-verts[i].z)) / scaledtexrepeaty) - ypancoef;
                    if (Sidedef.ImageFlipY)
                    {
                        verts[i].v *= -1;
                    }
                }

                // Apply vertices
                SetVertices(verts);
                return(true);
            }

            // No geometry for invisible wall
            SetVertices(new WorldVertex[0]);
            return(false);
        }