// This finds and adds visible sectors private void ProcessSidedefCulling(Sidedef sd) { VisualSector vs; // Find the visualsector and make it if needed if (allsectors.ContainsKey(sd.Sector)) { // Take existing visualsector vs = allsectors[sd.Sector]; } else { // Make new visualsector vs = CreateVisualSector(sd.Sector); if (vs != null) { allsectors.Add(sd.Sector, vs); } } if (vs != null) { // Add to visible sectors if not added yet if (!visiblesectors.ContainsKey(sd.Sector)) { visiblesectors.Add(sd.Sector, vs); visiblegeometry.AddRange(vs.FixedGeometry); } // Add sidedef geometry visiblegeometry.AddRange(vs.GetSidedefGeometry(sd)); } }
// This reads a single sidedef and connects it to the given linedef private void ReadSidedef(MapSet map, UniversalCollection sc, Linedef ld, bool front, Dictionary <int, Sector> sectorlink, int index) { // Read fields string where = "linedef " + ld.Index + (front ? " front sidedef " : " back sidedef ") + index; int offsetx = GetCollectionEntry <int>(sc, "offsetx", false, 0, where); int offsety = GetCollectionEntry <int>(sc, "offsety", false, 0, where); string thigh = GetCollectionEntry <string>(sc, "texturetop", false, "-", where); string tlow = GetCollectionEntry <string>(sc, "texturebottom", false, "-", where); string tmid = GetCollectionEntry <string>(sc, "texturemiddle", false, "-", where); int sector = GetCollectionEntry <int>(sc, "sector", true, 0, where); // Create sidedef if (sectorlink.ContainsKey(sector)) { Sidedef s = map.CreateSidedef(ld, front, sectorlink[sector]); if (s != null) { s.Update(offsetx, offsety, thigh, tmid, tlow); // Custom fields ReadCustomFields(sc, s, "sidedef"); } } else { General.ErrorLogger.Add(ErrorType.Warning, "Sidedef references invalid sector " + sector + ". Sidedef has been removed."); } }
// Disposer internal void Dispose() { reflexlink = null; eartiplink = null; vertslink = null; sidedef = null; }
// This sets the Lower Unpegged flag public virtual void ApplyBottomAlignment(bool set) { if (!set) { // Remove flag mode.CreateUndo("Remove bottom-aligned setting"); mode.SetActionResult("Removed bottom-aligned setting."); Sidedef.SetFlag(General.Map.FormatInterface.WallFlags.AlignImageToBottom, false); } else { // Add flag mode.CreateUndo("Set bottom-aligned setting"); mode.SetActionResult("Set bottom-aligned setting."); Sidedef.SetFlag(General.Map.FormatInterface.WallFlags.AlignImageToBottom, true); } // Update sidedef geometry VisualWallParts parts = Sector.GetSidedefParts(Sidedef); parts.SetupAllParts(); // Update other sidedef geometry /*if(Sidedef.Other != null) * { * BaseVisualSector othersector = (BaseVisualSector)mode.GetVisualSector(Sidedef.Other.Sector); * parts = othersector.GetSidedefParts(Sidedef.Other); * parts.SetupAllParts(); * }*/ }
// Insert middle texture public virtual void OnInsert() { // No middle texture yet? if (!Sidedef.MiddleRequired() && (string.IsNullOrEmpty(Sidedef.MiddleTexture) || (Sidedef.MiddleTexture[0] == '-'))) { // Make it now mode.CreateUndo("Create middle texture"); mode.SetActionResult("Created middle texture."); General.Settings.FindDefaultDrawSettings(); Sidedef.SetTextureMid(General.Settings.DefaultTexture); // Update Sector.Changed = true; // Other side as well if (string.IsNullOrEmpty(Sidedef.Other.MiddleTexture) || (Sidedef.Other.MiddleTexture[0] == '-')) { Sidedef.Other.SetTextureMid(General.Settings.DefaultTexture); // Update VisualSector othersector = mode.GetVisualSector(Sidedef.Other.Sector); if (othersector is BaseVisualSector) { (othersector as BaseVisualSector).Changed = true; } } } }
// This adds the matching, unmarked sidedefs from a vertex for texture alignment private static void AddSidedefsForFloodfill(BaseVisualMode mode, Stack <Tools.SidedefFillJob> stack, Vertex v, bool forward, HashSet <long> texturelongnames) { foreach (Linedef ld in v.Linedefs) { Sidedef side1 = (forward ? ld.Front : ld.Back); Sidedef side2 = (forward ? ld.Back : ld.Front); // [ZZ] don't iterate the same linedef twice. // if ((side1 != null && side1.Marked) || (side2 != null && side2.Marked)) { continue; } if ((ld.Start == v) && (side1 != null) && !side1.Marked) { if (SidedefTextureMatch(mode, side1, texturelongnames)) { stack.Push(new Tools.SidedefFillJob { forward = forward, sidedef = side1 }); } } else if ((ld.End == v) && (side2 != null) && !side2.Marked) { if (SidedefTextureMatch(mode, side2, texturelongnames)) { stack.Push(new Tools.SidedefFillJob { forward = forward, sidedef = side2 }); } } } }
public BuildWall(Sidedef src) { Flags = new Dictionary <string, bool>(src.Flags); var v = (src.IsFront ? src.Line.Start : src.Line.End); StartX = (int)v.Position.x; StartY = (int)v.Position.y; // These must be set separately... NextWallIndex = -1; OtherWallIndex = -1; OtherSectorIndex = -1; OffsetX = src.OffsetX; OffsetY = src.OffsetY; RepeatX = src.RepeatX; RepeatY = src.RepeatY; TileIndex = src.TileIndex; MaskedTileIndex = src.MaskedTileIndex; Shade = src.Shade; PaletteIndex = src.PaletteIndex; HiTag = src.HiTag; LoTag = src.LoTag; Extra = src.Extra; }
//mxd. This calculates wall brightness level with doom-style shading public int CalculateBrightness(int level, Sidedef sd) { if (level < 253 && sd != null) { bool evenlighting = General.Map.Data.MapInfo.EvenLighting; bool smoothlighting = General.Map.Data.MapInfo.SmoothLighting; //check for possiburu UDMF overrides if (General.Map.UDMF) { if (sd.IsFlagSet("lightabsolute") && sd.Fields.ContainsKey("light")) { evenlighting = true; } else { if (sd.IsFlagSet("nofakecontrast")) { evenlighting = true; } if (sd.IsFlagSet("smoothlighting")) { smoothlighting = true; } } } if (!evenlighting) { //all walls are shaded by their angle if (smoothlighting) { float ammount = Math.Abs((float)Math.Sin(sd.Angle)); int hAmmount = (int)((1.0f - ammount) * General.Map.Data.MapInfo.HorizWallShade); int vAmmount = (int)(ammount * General.Map.Data.MapInfo.VertWallShade); level = General.Clamp(level - hAmmount - vAmmount, 0, 255); } else //only horizontal/verticel walls are shaded { switch ((int)Angle2D.RadToDeg(sd.Angle)) { // Horizontal wall case 90: case 270: level = General.Clamp(level + General.Map.Data.MapInfo.HorizWallShade, 0, 255); break; // Vertical wall case 180: case 0: level = General.Clamp(level + General.Map.Data.MapInfo.VertWallShade, 0, 255); break; } } } } return(CalculateBrightness(level)); }
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); }
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); }
//mxd private static void SetUDMFLight(Sidedef sd, Label label, Label value, bool highlight) { if (sd.Fields.ContainsKey("light")) { int light = (int)sd.Fields["light"].Value; if (sd.Fields.GetValue("lightabsolute", false)) { value.Text = light + " (abs.)"; } else { value.Text = light + " (" + Math.Min(255, Math.Max(0, (light + sd.Sector.Brightness))) + ")"; } value.Enabled = true; label.Enabled = true; } else { value.Text = "-- (" + sd.Sector.Brightness + ")"; label.Enabled = highlight; value.Enabled = highlight; } label.ForeColor = (highlight ? SystemColors.HotTrack : SystemColors.WindowText); value.ForeColor = label.ForeColor; }
// Fix a single side public override bool Button1Click(bool batchMode) { // On which side can we fix? if(copysidedeffront != null) { // Front if(!batchMode) General.Map.UndoRedo.CreateUndo("Create front sidedef"); Sidedef newside = General.Map.Map.CreateSidedef(line, true, copysidedeffront.Sector); if(newside == null) return false; copysidedeffront.CopyPropertiesTo(newside); } else if(copysidedefback != null) { // Back // Because the line is single-sided, we make the sidedef on the front. // We will then flip it to make sure to ends up in the right position. if(!batchMode) General.Map.UndoRedo.CreateUndo("Create front sidedef"); Sidedef newside = General.Map.Map.CreateSidedef(line, true, copysidedefback.Sector); if(newside == null) return false; copysidedefback.CopyPropertiesTo(newside); line.FlipVertices(); } line.ApplySidedFlags(); General.Map.Map.Update(); return true; }
// This returns all selected sidedefs, no doubles public List <Sidedef> GetSelectedSidedefs() { Dictionary <Sidedef, int> added = new Dictionary <Sidedef, int>(); List <Sidedef> sidedefs = new List <Sidedef>(); foreach (IVisualEventReceiver i in selectedobjects) { if (i is BaseVisualGeometrySidedef) { Sidedef sd = (i as BaseVisualGeometrySidedef).Sidedef; if (!added.ContainsKey(sd)) { sidedefs.Add(sd); added.Add(sd, 0); } } } // Add highlight? if ((selectedobjects.Count == 0) && (target.picked is BaseVisualGeometrySidedef)) { Sidedef sd = (target.picked as BaseVisualGeometrySidedef).Sidedef; if (!added.ContainsKey(sd)) { sidedefs.Add(sd); } } return(sidedefs); }
// This adds the matching, unmarked sidedefs from a vertex for texture alignment private static void AddSidedefsForAlignment(Stack <SidedefAlignJob> stack, Vertex v, bool forward, float offsetx, long texturelongname) { foreach (Linedef ld in v.Linedefs) { Sidedef side1 = forward ? ld.Front : ld.Back; Sidedef side2 = forward ? ld.Back : ld.Front; if ((ld.Start == v) && (side1 != null) && !side1.Marked) { if (SidedefTextureMatch(side1, texturelongname)) { SidedefAlignJob nj = new SidedefAlignJob(); nj.forward = forward; nj.offsetx = offsetx; nj.sidedef = side1; stack.Push(nj); } } else if ((ld.End == v) && (side2 != null) && !side2.Marked) { if (SidedefTextureMatch(side2, texturelongname)) { SidedefAlignJob nj = new SidedefAlignJob(); nj.forward = forward; nj.offsetx = offsetx; nj.sidedef = side2; stack.Push(nj); } } } }
//mxd. Useful when debugging... public override string ToString() { Sidedef side = (front ? line.Front : line.Back); Sector sector = (side != null ? side.Sector : null); return(line + " (" + (front ? "front" : "back") + ")" + (sector != null ? ", Sector " + sector.Index : ", no sector")); }
// Fix both sides public override bool Button2Click(bool batchMode) { if (!batchMode) { General.Map.UndoRedo.CreateUndo("Create sidedefs"); } // Front Sidedef newside = General.Map.Map.CreateSidedef(line, true, copysidedeffront.Sector); if (newside == null) { return(false); } copysidedeffront.CopyPropertiesTo(newside); // Back newside = General.Map.Map.CreateSidedef(line, false, copysidedefback.Sector); if (newside == null) { return(false); } copysidedefback.CopyPropertiesTo(newside); line.ApplySidedFlags(); General.Map.Map.Update(); return(true); }
// Constructor public ResultUnknownTexture(Sidedef sd, SidedefPart part) { // Initialize this.side = sd; this.part = part; this.viewobjects.Add(sd); this.description = "This sidedef uses an unknown texture. This could be the result of missing resources, or a mistyped texture name. Click the Remove Texture button to remove the texture or click on Add Default Texture to use a known texture instead."; }
// This gets the geometry list for the specified sidedef public List <VisualGeometry> GetSidedefGeometry(Sidedef sd) { if (sidedefgeometry.ContainsKey(sd)) { return(sidedefgeometry[sd]); } return(new List <VisualGeometry>()); }
// Constructor public ResultMissingTexture(Sidedef sd, SidedefPart part) { // Initialize this.side = sd; this.part = part; this.viewobjects.Add(sd); this.description = "This sidedef is missing a texture where it is required and could cause a 'Hall Of Mirrors' visual problem in the map. Click the Add Default Texture button to add a texture to the line."; }
// Constructor public VisualMiddleDouble(BaseVisualMode mode, VisualSector vs, Sidedef s) : base(mode, vs, s) { // Set render pass this.RenderPass = RenderPass.Mask; // We have no destructor GC.SuppressFinalize(this); }
void Start() { map = WADReader.LoadMap("E1M1"); vertices = new List <Vector3>(); List <CombineInstance> floorCIs = new List <CombineInstance>(); foreach (SubSector ssector in map.subsectors) { List <Vector3> floorVerts = new List <Vector3>(); //SubSector ssector = map.subsectors[0]; for (int i = 0; i < ssector.num; i++) { Seg seg = map.segs[ssector.start + i]; Vertex vertS = map.vertexes[seg.start]; Vertex vertE = map.vertexes[seg.end]; Linedef line = map.linedefs[seg.linedef]; Sidedef sideR = map.sidedefs[line.right]; Sector sectorR = map.sectors[sideR.sector]; if (line.left >= 0) { Sidedef sideL = map.sidedefs[line.left]; Sector sectorL = map.sectors[sideL.sector]; } Vector3 vStart = new Vector3(vertS.x, 0, vertS.y) * scale; Vector3 vEnd = new Vector3(vertE.x, 0, vertE.y) * scale; /*if (!floorVerts.Contains(vStart))*/ floorVerts.Add(vStart); /*if (!floorVerts.Contains(vEnd))*/ floorVerts.Add(vEnd); } List <int> floorTris = new List <int>(); int p0 = 0; int pHelper = 1; for (int i = 2; i < floorVerts.Count; i++) { int pTemp = i; floorTris.AddRange(new int[] { p0, pHelper, pTemp }); pHelper = pTemp; } CombineInstance ci = new CombineInstance(); Mesh mesh = new Mesh(); mesh.vertices = floorVerts.ToArray(); mesh.triangles = floorTris.ToArray(); mesh.RecalculateNormals(); ci.mesh = mesh; ci.transform = transform.localToWorldMatrix; floorCIs.Add(ci); } Mesh combinedFloor = new Mesh(); combinedFloor.CombineMeshes(floorCIs.ToArray()); meshFilter.sharedMesh = combinedFloor; inited = true; }
public SidedefProperties(Sidedef s) { hightexture = s.HighTexture; middletexture = s.MiddleTexture; lowtexture = s.LowTexture; offsetx = s.OffsetX; offsety = s.OffsetY; fields = new UniFields(s.Fields); }
public static LuaSidedef NearestSidedef(LuaVector2D pos) { Sidedef side = MapSet.NearestSidedef(General.Map.Map.Sidedefs, pos.vec); if (side == null) { return null; } return new LuaSidedef(side); }
// Copy constructor internal EarClipVertex(EarClipVertex v) { // Initialize this.pos = v.pos; this.sidedef = v.sidedef; // We have no destructor GC.SuppressFinalize(this); }
// Constructor public VisualMiddle3D(BaseVisualMode mode, VisualSector vs, Sidedef s) : base(mode, vs, s) { //mxd geometrytype = VisualGeometryType.WALL_MIDDLE_3D; partname = "mid"; // We have no destructor GC.SuppressFinalize(this); }
// Constructor internal EarClipVertex(Vector2 v, Sidedef sidedef) { // Initialize this.pos = v; this.sidedef = sidedef; // We have no destructor GC.SuppressFinalize(this); }
// Constructor public ResultUnusedTexture(Sidedef sd, SidedefPart part) { // Initialize this.side = sd; this.part = part; this.viewobjects.Add(sd); this.hidden = sd.IgnoredErrorChecks.Contains(this.GetType()); //mxd this.description = "This sidedef uses an upper or lower texture, which is not required (it will never be visible ingame). Click the Remove Texture button to remove the texture (this will also reset texture offsets and scale in UDMF map format)."; }
// Constructor public VisualUpper(BaseVisualMode mode, VisualSector vs, Sidedef s) : base(mode, vs, s) { //mxd geometrytype = VisualGeometryType.WALL_UPPER; partname = "top"; // We have no destructor GC.SuppressFinalize(this); }
private readonly Dictionary <string, bool> flags; //mxd public SidedefProperties(Sidedef s) : base(s.Fields, MapElementType.SIDEDEF) { hightexture = s.HighTexture; middletexture = s.MiddleTexture; lowtexture = s.LowTexture; offsetx = s.OffsetX; offsety = s.OffsetY; flags = s.GetFlags(); //mxd }
// This performs an accurate test for object picking public override bool PickAccurate(Vector3D from, Vector3D to, Vector3D dir, ref float u_ray) { u_ray = pickrayu; // Check on which side of the nearest sidedef we are Sidedef sd = MapSet.NearestSidedef(Sector.Sector.Sidedefs, pickintersect); float side = sd.Line.SideOfLine(pickintersect); //mxd. Alpha based picking. Used only on extrafloors with transparent or masked textures if ((side <= 0.0f && sd.IsFront) || (side > 0.0f && !sd.IsFront)) { if (!BuilderPlug.Me.AlphaBasedTextureHighlighting || !Texture.IsImageLoaded || extrafloor == null || RenderPass == RenderPass.Solid || (!Texture.IsTranslucent && !Texture.IsMasked)) { return(true); } // Some textures (e.g. HiResImage) may lie about their size, so use bitmap size instead Bitmap image = Texture.GetBitmap(); lock (image) { // Fetch ZDoom fields float rotate = Angle2D.DegToRad(level.sector.Fields.GetValue("rotationfloor", 0.0f)); Vector2D offset = new Vector2D(level.sector.Fields.GetValue("xpanningfloor", 0.0f), level.sector.Fields.GetValue("ypanningfloor", 0.0f)); Vector2D scale = new Vector2D(level.sector.Fields.GetValue("xscalefloor", 1.0f), level.sector.Fields.GetValue("yscalefloor", 1.0f)); Vector2D texscale = new Vector2D(1.0f / Texture.ScaledWidth, 1.0f / Texture.ScaledHeight); // Texture coordinates Vector2D o = pickintersect; o = o.GetRotated(rotate); o.y = -o.y; o = (o + offset) * scale * texscale; o.x = (o.x * image.Width) % image.Width; o.y = (o.y * image.Height) % image.Height; // Make sure coordinates are inside of texture dimensions... if (o.x < 0) { o.x += image.Width; } if (o.y < 0) { o.y += image.Height; } // Make final texture coordinates... int ox = General.Clamp((int)Math.Floor(o.x), 0, image.Width - 1); int oy = General.Clamp((int)Math.Floor(o.y), 0, image.Height - 1); // Check pixel alpha return(image.GetPixel(ox, oy).A > 0); } } return(false); }