private static int GetExpectedOffsetY(Sidedef source, Sidedef target, string texturename, int textureheight, double texturescaley, double linescaley, Rectangle partsize, out VisualGeometryType matchingparttype)
        {
            if (target.MiddleTexture == texturename &&
                partsize.IntersectsWith(BuilderModesTools.GetSidedefPartSize(target, VisualGeometryType.WALL_MIDDLE)))
            {
                matchingparttype = VisualGeometryType.WALL_MIDDLE;
                int partheight = (int)Math.Round(((target.Sector.CeilHeight - source.Sector.CeilHeight) / texturescaley) * linescaley);
                return(((int)Tools.GetSidedefMiddleOffsetY(target, target.OffsetY + GetSidedefValue(target, matchingparttype, "offsety", 0f), linescaley, false) + partheight) % textureheight);
            }

            // Only check upper and lower textures if the sidedef as an other side. See https://github.com/jewalky/UltimateDoomBuilder/issues/533
            if (target.Other != null && target.HighTexture == texturename &&
                partsize.IntersectsWith(BuilderModesTools.GetSidedefPartSize(target, VisualGeometryType.WALL_UPPER)))
            {
                matchingparttype = VisualGeometryType.WALL_UPPER;
                int partheight = (int)Math.Round(((target.Sector.CeilHeight - source.Sector.CeilHeight) / texturescaley) * linescaley);
                return(((int)Tools.GetSidedefTopOffsetY(target, target.OffsetY + GetSidedefValue(target, matchingparttype, "offsety", 0f), linescaley, false) + partheight) % textureheight);
            }

            if (target.Other != null && target.LowTexture == texturename &&
                partsize.IntersectsWith(BuilderModesTools.GetSidedefPartSize(target, VisualGeometryType.WALL_LOWER)))
            {
                matchingparttype = VisualGeometryType.WALL_LOWER;
                int partheight = (int)Math.Round(((target.Sector.CeilHeight - source.Sector.CeilHeight) / texturescaley) * linescaley);
                return(((int)Tools.GetSidedefBottomOffsetY(target, target.OffsetY + GetSidedefValue(target, matchingparttype, "offsety", 0f), linescaley, false) + partheight) % textureheight);
            }

            matchingparttype = VisualGeometryType.UNKNOWN;
            return(int.MinValue);
        }
Beispiel #2
0
        private static int GetExpectedOffsetY(Sidedef source, Sidedef target, string texturename, int textureheight, double texturescaley, double linescaley, Rectangle partsize, out VisualGeometryType matchingparttype)
        {
            if (target.MiddleTexture == texturename &&
                partsize.IntersectsWith(BuilderModesTools.GetSidedefPartSize(target, VisualGeometryType.WALL_MIDDLE)))
            {
                matchingparttype = VisualGeometryType.WALL_MIDDLE;
                int partheight = (int)Math.Round(((target.Sector.CeilHeight - source.Sector.CeilHeight) / texturescaley) * linescaley);
                return(((int)Tools.GetSidedefMiddleOffsetY(target, target.OffsetY + GetSidedefValue(target, matchingparttype, "offsety", 0f), linescaley, false) + partheight) % textureheight);
            }

            if (target.HighTexture == texturename &&
                partsize.IntersectsWith(BuilderModesTools.GetSidedefPartSize(target, VisualGeometryType.WALL_UPPER)))
            {
                matchingparttype = VisualGeometryType.WALL_UPPER;
                int partheight = (int)Math.Round(((target.Sector.CeilHeight - source.Sector.CeilHeight) / texturescaley) * linescaley);
                return(((int)Tools.GetSidedefTopOffsetY(target, target.OffsetY + GetSidedefValue(target, matchingparttype, "offsety", 0f), linescaley, false) + partheight) % textureheight);
            }

            if (target.LowTexture == texturename &&
                partsize.IntersectsWith(BuilderModesTools.GetSidedefPartSize(target, VisualGeometryType.WALL_LOWER)))
            {
                matchingparttype = VisualGeometryType.WALL_LOWER;
                int partheight = (int)Math.Round(((target.Sector.CeilHeight - source.Sector.CeilHeight) / texturescaley) * linescaley);
                return(((int)Tools.GetSidedefBottomOffsetY(target, target.OffsetY + GetSidedefValue(target, matchingparttype, "offsety", 0f), linescaley, false) + partheight) % textureheight);
            }

            matchingparttype = VisualGeometryType.UNKNOWN;
            return(int.MinValue);
        }
Beispiel #3
0
        internal SortedVisualSide(BaseVisualGeometrySidedef side)
        {
            Side   = side;
            Bounds = BuilderModesTools.GetSidedefPartSize(side);
            Index  = index++;

            if (side.Sidedef.Line.Front == side.Sidedef)
            {
                Start = side.Sidedef.Line.Start.Position;
                End   = side.Sidedef.Line.End.Position;
            }
            else
            {
                Start = side.Sidedef.Line.End.Position;
                End   = side.Sidedef.Line.Start.Position;
            }

            switch (side.GeometryType)
            {
            case VisualGeometryType.WALL_UPPER:
                OffsetX = UniFields.GetFloat(side.Sidedef.Fields, "offsetx_top");
                OffsetY = UniFields.GetFloat(side.Sidedef.Fields, "offsety_top");
                ScaleX  = UniFields.GetFloat(side.Sidedef.Fields, "scalex_top", 1.0f);
                ScaleY  = UniFields.GetFloat(side.Sidedef.Fields, "scaley_top", 1.0f);
                break;

            case VisualGeometryType.WALL_MIDDLE:
                OffsetX = UniFields.GetFloat(side.Sidedef.Fields, "offsetx_mid");
                OffsetY = UniFields.GetFloat(side.Sidedef.Fields, "offsety_mid");
                ScaleX  = UniFields.GetFloat(side.Sidedef.Fields, "scalex_mid", 1.0f);
                ScaleY  = UniFields.GetFloat(side.Sidedef.Fields, "scaley_mid", 1.0f);
                break;

            case VisualGeometryType.WALL_MIDDLE_3D:
                Sidedef cs = side.GetControlLinedef().Front;
                ControlSideOffsetX = cs.OffsetX + UniFields.GetFloat(cs.Fields, "offsetx_mid");
                OffsetX            = UniFields.GetFloat(side.Sidedef.Fields, "offsetx_mid");
                ControlSideOffsetY = cs.OffsetY + UniFields.GetFloat(cs.Fields, "offsety_mid");
                OffsetY            = UniFields.GetFloat(side.Sidedef.Fields, "offsety_mid");
                ScaleX             = UniFields.GetFloat(cs.Fields, "scalex_mid", 1.0f);
                ScaleY             = UniFields.GetFloat(cs.Fields, "scaley_mid", 1.0f);
                break;

            case VisualGeometryType.WALL_LOWER:
                OffsetX = UniFields.GetFloat(side.Sidedef.Fields, "offsetx_bottom");
                OffsetY = UniFields.GetFloat(side.Sidedef.Fields, "offsety_bottom");
                ScaleX  = UniFields.GetFloat(side.Sidedef.Fields, "scalex_bottom", 1.0f);
                ScaleY  = UniFields.GetFloat(side.Sidedef.Fields, "scaley_bottom", 1.0f);
                break;
            }

            NextSides     = new Dictionary <SortedVisualSide, bool>();
            PreviousSides = new Dictionary <SortedVisualSide, bool>();
        }
Beispiel #4
0
        public bool Setup(IEnumerable <BaseVisualGeometrySidedef> sides)
        {
            // Get shapes
            strips = BuilderModesTools.SortVisualSides(sides);

            // No dice...
            if (strips.Count == 0)
            {
                General.Interface.DisplayStatus(StatusType.Warning, "Failed to setup sidedef chains...");
                this.DialogResult = DialogResult.Cancel;
                this.Close();
                return(false);
            }

            // Restore settings
            blockupdate = true;

            // Make sure we start with sensible values for horizontal and vertical repeat
            if (horizontalrepeat == 0.0)
            {
                horizontalrepeat = 1.0;
            }

            if (verticalrepeat == 0.0)
            {
                verticalrepeat = 1.0;
            }

            horizrepeat.Text       = horizontalrepeat.ToString();
            vertrepeat.Text        = verticalrepeat.ToString();
            prevhorizrepeat        = horizontalrepeat;
            prevvertrepeat         = verticalrepeat;
            cbfitconnected.Checked = fitacrosssurfaces;
            cbfitconnected.Enabled = (strips.Count > 1);
            cbfitwidth.Checked     = fitwidth;
            cbfitheight.Checked    = fitheight;
            UpdateRepeatGroup();

            blockupdate = false;

            //trigger update
            UpdateChanges();

            return(true);
        }
        public bool Setup(IEnumerable <BaseVisualGeometrySidedef> sides)
        {
            // Get shapes
            strips = BuilderModesTools.SortVisualSides(sides);

            // No dice...
            if (strips.Count == 0)
            {
                General.Interface.DisplayStatus(StatusType.Warning, "Failed to setup sidedef chains...");
                this.DialogResult = DialogResult.Cancel;
                this.Close();
                return(false);
            }

#if DEBUG
            //debug
            DrawDebugUV();
#endif

            // Restore settings
            blockupdate = true;

            horizrepeat.Value      = horizontalrepeat;
            vertrepeat.Value       = verticalrepeat;
            prevhorizrepeat        = horizontalrepeat;
            prevvertrepeat         = verticalrepeat;
            cbfitconnected.Checked = fitacrosssurfaces;
            cbfitconnected.Enabled = (strips.Count > 1);
            cbfitwidth.Checked     = fitwidth;
            cbfitheight.Checked    = fitheight;
            UpdateRepeatGroup();

            blockupdate = false;

            //trigger update
            UpdateChanges();

            return(true);
        }
        private void CheckAlignment(Sidedef sidedef, int offsetx, int offsety, double linescalex, double linescaley, VisualGeometryType parttype, string texturename)
        {
            ImageData texture = General.Map.Data.GetTextureImage(texturename);

            if (!texture.IsImageLoaded)
            {
                return;
            }
            Rectangle partsize = BuilderModesTools.GetSidedefPartSize(sidedef, parttype);

            double scalex = ((General.Map.Config.ScaledTextureOffsets && !texture.WorldPanning) ? texture.Scale.x : 1.0f);
            double scaley = ((General.Map.Config.ScaledTextureOffsets && !texture.WorldPanning) ? texture.Scale.y : 1.0f);

            // Move offsets to proper range
            offsetx %= texture.Width;
            if (offsetx < 0)
            {
                offsetx += texture.Width;
            }
            offsety %= texture.Height;
            if (offsety < 0)
            {
                offsety += texture.Height;
            }

            // Check if current line is aligned to other sides
            ICollection <Linedef> lines = (sidedef.IsFront ? sidedef.Line.Start.Linedefs : sidedef.Line.End.Linedefs);
            Vertex v = sidedef.IsFront ? sidedef.Line.Start : sidedef.Line.End;

            foreach (Linedef line in lines)
            {
                if (line.Index == sidedef.Line.Index)
                {
                    continue;
                }

                Sidedef target = null;
                if (line.Front != null && line.End == v)
                {
                    target = line.Front;
                }
                else if (line.Back != null && line.Start == v)
                {
                    target = line.Back;
                }

                // No target?
                if (target == null)
                {
                    continue;
                }

                // Get expected texture offsets
                VisualGeometryType targetparttype;
                int alignedY = GetExpectedOffsetY(sidedef, target, texturename, texture.Height, scaley, linescaley, partsize, out targetparttype);
                if (targetparttype == VisualGeometryType.UNKNOWN)
                {
                    continue;
                }

                // Already added?
                if (donesides[parttype].ContainsKey(sidedef.Index) && donesides[parttype][sidedef.Index][targetparttype].ContainsKey(target.Index))
                {
                    continue;
                }

                // Not aligned if scaley is not equal
                double targetscaley = GetSidedefValue(target, targetparttype, "scaley", 1.0);
                if (targetscaley != linescaley)
                {
                    SubmitResult(new ResultTexturesMisaligned(sidedef, target, texturename));
                }

                double targetscalex = GetSidedefValue(target, targetparttype, "scalex", 1.0);

                alignedY %= texture.Height;
                if (alignedY < 0)
                {
                    alignedY += texture.Height;
                }

                int alignedX = (target.OffsetX + (int)GetSidedefValue(target, targetparttype, "offsetx", 0f) + (int)Math.Round(target.Line.Length / scalex * targetscalex)) % texture.Width;
                if (alignedX < 0)
                {
                    alignedX += texture.Width;
                }

                // Submit result if target offsets don't match expected ones
                if (offsetx != alignedX || offsety != alignedY)
                {
                    SubmitResult(new ResultTexturesMisaligned(sidedef, target, texturename));
                }

                // Add to collection
                AddProcessedSides(sidedef, parttype, target, targetparttype);
            }

            // Check if other sides are aligned to current side
            lines = (sidedef.IsFront ? sidedef.Line.End.Linedefs : sidedef.Line.Start.Linedefs);
            v     = (sidedef.IsFront ? sidedef.Line.End : sidedef.Line.Start);

            foreach (Linedef line in lines)
            {
                if (line.Index == sidedef.Line.Index)
                {
                    continue;
                }

                Sidedef target = null;
                if (line.Front != null && line.Start == v)
                {
                    target = line.Front;
                }
                else if (line.Back != null && line.End == v)
                {
                    target = line.Back;
                }

                // No target or laready processed?
                if (target == null)
                {
                    continue;
                }

                // Get expected texture offsets
                VisualGeometryType targetparttype;
                int alignedY = GetExpectedOffsetY(sidedef, target, texturename, texture.Height, scaley, linescaley, partsize, out targetparttype);
                if (targetparttype == VisualGeometryType.UNKNOWN)
                {
                    continue;
                }

                // Already added?
                if (donesides[parttype].ContainsKey(sidedef.Index) && donesides[parttype][sidedef.Index][targetparttype].ContainsKey(target.Index))
                {
                    continue;
                }

                // Not aligned if scaley is not equal
                double targetscaley = GetSidedefValue(target, targetparttype, "scaley", 1.0);
                if (targetscaley != linescaley)
                {
                    SubmitResult(new ResultTexturesMisaligned(sidedef, target, texturename));
                }

                alignedY %= texture.Height;
                if (alignedY < 0)
                {
                    alignedY += texture.Height;
                }

                int alignedX = (target.OffsetX + (int)GetSidedefValue(target, targetparttype, "offsetx", 0.0) - (int)Math.Round(sidedef.Line.Length / scalex * linescalex)) % texture.Width;
                if (alignedX < 0)
                {
                    alignedX += texture.Width;
                }

                // Submit result if target offsets don't match expected ones
                if (offsetx != alignedX || offsety != alignedY)
                {
                    SubmitResult(new ResultTexturesMisaligned(sidedef, target, texturename));
                }

                // Add to collection
                AddProcessedSides(sidedef, parttype, target, targetparttype);
            }
        }