// Constructor public BaseVisualThing(BaseVisualMode mode, Thing t) : base(t) { this.mode = mode; // Find thing information info = General.Map.Data.GetThingInfo(Thing.Type); //mxd. When true, the thing can be moved below floor/above ceiling nointeraction = (info.Actor != null && info.Actor.GetFlagValue("nointeraction", false)); //mxd. Find sprite textures sprites = new ImageData[info.SpriteFrame.Length]; for (int i = 0; i < info.SpriteFrame.Length; i++) { sprites[i] = General.Map.Data.GetSpriteImage(info.SpriteFrame[i].Sprite); if (sprites[i] != null) { sprites[i].AddReference(); } } //mxd if (mode.UseSelectionFromClassicMode && t.Selected) { this.selected = true; mode.AddSelectedObject(this); } // We have no destructor GC.SuppressFinalize(this); }
private static float GetAlignedThingZ(BaseVisualMode mode, Thing t, float targtthingheight) { ThingTypeInfo info = General.Map.Data.GetThingInfoEx(t.Type); if (info != null) { if (info.AbsoluteZ && info.Hangs) { return(t.Position.z); // Not sure what to do here... } if (info.AbsoluteZ) { // Transform to floor-aligned position SectorData nsd = mode.GetSectorData(t.Sector); return(t.Position.z - nsd.Floor.plane.GetZ(t.Position) + t.Height); } if (info.Hangs) { // Transform to floor-aligned position. Align top of target thing to the bottom of the hanging thing SectorData nsd = mode.GetSectorData(t.Sector); return((nsd.Ceiling.plane.GetZ(t.Position) - nsd.Floor.plane.GetZ(t.Position)) - t.Position.z - t.Height - targtthingheight); } } return(t.Position.z + t.Height); }
public SlopeArcher(BaseVisualMode mode, List <IVisualEventReceiver> sectors, VisualSidedefSlope handle1, VisualSidedefSlope handle2, double theta, double offsetangle, double scale) { this.mode = mode; this.sectors = sectors; this.handle1 = handle1; this.handle2 = handle2; this.theta = theta; this.offsetangle = offsetangle; this.scale = scale; heightoffset = 0.0; handleline = new Line2D(handle1.GetCenterPoint(), handle2.GetCenterPoint()); length = handleline.GetLength(); if (handle1.Level.type == SectorLevelType.Ceiling) { baseheight = handle1.Level.extrafloor ? handle1.Level.sector.FloorHeight : handle1.Level.sector.CeilHeight; } else { baseheight = handle1.Level.extrafloor ? handle1.Level.sector.CeilHeight : handle1.Level.sector.FloorHeight; } baseheightoffset = 0.0; }
// Constructor public ThingData(BaseVisualMode mode, Thing t) { // Initialize this.mode = mode; this.thing = t; this.updatesectors = new Dictionary <Sector, bool>(2); }
// 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 }); } } } }
// Constructor public VertexData(BaseVisualMode mode, Vertex v) { // Initialize this.mode = mode; this.vertex = v; this.updatesectors = new Dictionary <Sector, bool>(2); }
// 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); }
// Constructor public BaseVisualThing(BaseVisualMode mode, Thing t) : base(t) { this.mode = mode; Rebuild(); // 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 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 bool innerside; //mxd #endregion #region ================== Properties #endregion #region ================== Constructor / Setup // Constructor public VisualFloor(BaseVisualMode mode, VisualSector vs) : base(mode, vs) { //mxd geometrytype = VisualGeometryType.FLOOR; partname = "floor"; performautoselection = mode.UseSelectionFromClassicMode && vs != null && vs.Sector.Selected && (General.Map.ViewMode == ViewMode.FloorTextures || General.Map.ViewMode == ViewMode.Normal); // We have no destructor GC.SuppressFinalize(this); }
// Constructor public BaseVisualSector(BaseVisualMode mode, Sector s) : base(s) { this.mode = mode; // Initialize Rebuild(); // We have no destructor GC.SuppressFinalize(this); }
// Constructor for sidedefs public BaseVisualGeometrySidedef(BaseVisualMode mode, VisualSector vs, Sidedef sd) : base(vs, sd) { this.mode = mode; this.deltaz = new Vector3D(0.0f, 0.0f, 1.0f); this.deltaxy = (sd.Line.End.Position - sd.Line.Start.Position) * sd.Line.LengthInv; if (!sd.IsFront) { this.deltaxy = -this.deltaxy; } }
// Constructor public VisualFogBoundary(BaseVisualMode mode, VisualSector vs, Sidedef s) : base(mode, vs, s) { //mxd geometrytype = VisualGeometryType.FOG_BOUNDARY; // Set render pass this.RenderPass = RenderPass.Additive; // We have no destructor GC.SuppressFinalize(this); }
// Constructor public VisualMiddleDouble(BaseVisualMode mode, VisualSector vs, Sidedef s) : base(mode, vs, s) { //mxd geometrytype = VisualGeometryType.WALL_MIDDLE; partname = "mid"; // Set render pass this.RenderPass = RenderPass.Mask; // We have no destructor GC.SuppressFinalize(this); }
//mxd. This checks if any of the sidedef texture match the given textures public static bool SidedefTextureMatch(BaseVisualMode mode, Sidedef sd, HashSet <long> texturelongnames) { if (!mode.VisualSectorExists(sd.Sector)) { return(false); } VisualSidedefParts parts = ((BaseVisualSector)mode.GetVisualSector(sd.Sector)).GetSidedefParts(sd); return((texturelongnames.Contains(sd.LongHighTexture) && (parts.upper != null && parts.upper.Triangles > 0)) || (texturelongnames.Contains(sd.LongLowTexture) && (parts.lower != null && parts.lower.Triangles > 0)) || (texturelongnames.Contains(sd.LongMiddleTexture) && ((parts.middledouble != null && parts.middledouble.Triangles > 0) || (parts.middlesingle != null && parts.middlesingle.Triangles > 0)))); }
// Constructor public BaseVisualSector(BaseVisualMode mode, Sector s) : base(s) { this.mode = mode; this.extrafloors = new List <VisualFloor>(2); this.extraceilings = new List <VisualCeiling>(2); this.extrabackfloors = new List <VisualFloor>(2); //mxd this.extrabackceilings = new List <VisualCeiling>(2); //mxd // Initialize Rebuild(); // We have no destructor GC.SuppressFinalize(this); }
//mxd. Gets thing z next higher to target thing z private static double GetNextHigherThingZ(BaseVisualMode mode, IEnumerable <Thing> things, double thingz, double thingheight) { double higherthingz = double.MaxValue; foreach (Thing t in things) { double neighbourz = GetAlignedThingZ(mode, t, thingheight); if (neighbourz > thingz && neighbourz < higherthingz) { higherthingz = neighbourz; } } return(higherthingz); }
//mxd. Gets thing z next higher to target thing z private static float GetNextHigherThingZ(BaseVisualMode mode, IEnumerable <Thing> things, float thingz, float thingheight) { float higherthingz = float.MaxValue; foreach (Thing t in things) { float neighbourz = GetAlignedThingZ(mode, t, thingheight); if (neighbourz > thingz && neighbourz < higherthingz) { higherthingz = neighbourz; } } return(higherthingz); }
// Constructor public BaseVisualVertex(BaseVisualMode mode, Vertex v, bool ceilingVertex) : base(v, ceilingVertex) { this.mode = mode; cageradius2 = DEFAULT_SIZE * General.Settings.GZVertexScale3D * Angle2D.SQRT2; cageradius2 = cageradius2 * cageradius2; // Synchronize selection? if (mode.UseSelectionFromClassicMode && v.Selected && (General.Map.ViewMode == ViewMode.Normal || (!ceilingVertex && General.Map.ViewMode == ViewMode.FloorTextures) || (ceilingVertex && General.Map.ViewMode == ViewMode.CeilingTextures))) { this.selected = true; mode.AddSelectedObject(this); } changed = true; Update(); }
// Constructor public BaseVisualThing(BaseVisualMode mode, Thing t) : base(t) { this.mode = mode; // Find thing information info = General.Map.Data.GetThingInfo(Thing.Type); // Find sprite texture if (info.Sprite.Length > 0) { sprite = General.Map.Data.GetSpriteImage(info.Sprite); if (sprite != null) { sprite.AddReference(); } } // We have no destructor GC.SuppressFinalize(this); }
// Constructor public SectorData(BaseVisualMode mode, Sector s) { // Initialize this.mode = mode; this.sector = s; this.updated = false; this.floorchanged = false; this.ceilingchanged = false; this.lightlevels = new List <SectorLevel>(2); this.extrafloors = new List <Effect3DFloor>(1); this.alleffects = new List <SectorEffect>(1); this.updatesectors = new Dictionary <Sector, bool>(2); this.floor = new SectorLevel(sector, SectorLevelType.Floor); this.floorbase = new SectorLevel(sector, SectorLevelType.Floor); //mxd this.ceiling = new SectorLevel(sector, SectorLevelType.Ceiling); this.ceilingbase = new SectorLevel(sector, SectorLevelType.Ceiling); //mxd this.glowingflateffect = new EffectGlowingFlat(this); //mxd // Add ceiling and floor lightlevels.Add(floor); lightlevels.Add(ceiling); BasicSetup(); }
// Constructor protected BaseVisualGeometrySector(BaseVisualMode mode, VisualSector vs) : base(vs) { this.mode = mode; }
public static bool SidedefTextureMatch(BaseVisualMode mode, Sidedef sd, HashSet <long> texturelongnames) { return(SidedefTextureMatch(mode, sd, texturelongnames, false)); }
// This gets sectors which surround given sectors internal static IEnumerable <Sector> GetSectorsAround(BaseVisualMode mode, IEnumerable <Sector> selected) { HashSet <int> processedsectors = new HashSet <int>(); HashSet <Vertex> verts = new HashSet <Vertex>(); List <Sector> result = new List <Sector>(); foreach (Sector s in selected) { processedsectors.Add(s.Index); foreach (Sidedef side in s.Sidedefs) { if (!verts.Contains(side.Line.Start)) { verts.Add(side.Line.Start); } if (!verts.Contains(side.Line.End)) { verts.Add(side.Line.End); } } } foreach (Vertex v in verts) { foreach (Linedef l in v.Linedefs) { if (l.Front != null && l.Front.Sector != null && !processedsectors.Contains(l.Front.Sector.Index)) { result.Add(l.Front.Sector); processedsectors.Add(l.Front.Sector.Index); // Add extrafloors as well SectorData sd = mode.GetSectorDataEx(l.Front.Sector); if (sd != null && sd.ExtraFloors.Count > 0) { foreach (Effect3DFloor effect in sd.ExtraFloors) { if (!processedsectors.Contains(effect.Linedef.Front.Sector.Index)) { result.Add(effect.Linedef.Front.Sector); processedsectors.Add(effect.Linedef.Front.Sector.Index); } } } } if (l.Back != null && l.Back.Sector != null && !processedsectors.Contains(l.Back.Sector.Index)) { result.Add(l.Back.Sector); processedsectors.Add(l.Back.Sector.Index); // Add extrafloors as well SectorData sd = mode.GetSectorDataEx(l.Back.Sector); if (sd != null && sd.ExtraFloors.Count > 0) { foreach (Effect3DFloor effect in sd.ExtraFloors) { if (!processedsectors.Contains(effect.Linedef.Front.Sector.Index)) { result.Add(effect.Linedef.Front.Sector); processedsectors.Add(effect.Linedef.Front.Sector.Index); } } } } } } return(result); }
internal static float GetLowerThingZ(BaseVisualMode mode, SectorData sd, VisualThing thing) { Vector3D pos = thing.Thing.Position; float thingheight = thing.Thing.Height; bool absolute = thing.Info.AbsoluteZ; bool hangs = thing.Info.Hangs; if (absolute && hangs) { General.Interface.DisplayStatus(StatusType.Warning, "Sorry, can't have both 'absolute' and 'hangs' flags..."); return(pos.z); } // Get things, which bounding boxes intersect with target thing IEnumerable <Thing> intersectingthings = GetIntersectingThings(mode, thing.Thing); float fz = (absolute ? 0 : sd.Floor.plane.GetZ(pos)); float cz = sd.Ceiling.plane.GetZ(pos); if (hangs) { // Transform to floor-aligned position Vector3D floorpos = new Vector3D(pos, (cz - fz) - pos.z - thingheight); float lowertingz = GetNextLowerThingZ(mode, intersectingthings, floorpos.z, thingheight); float lowerfloorz = float.MaxValue; // Do it only when there are extrafloors if (sd.LightLevels.Count > 2) { // Unlike sd.ExtraFloors, these are sorted by height for (int i = sd.LightLevels.Count - 1; i > -1; i--) { SectorLevel level = sd.LightLevels[i]; if (level.type == SectorLevelType.Light || level.type == SectorLevelType.Glow) { continue; // Skip lights and glows } float z = level.plane.GetZ(floorpos) - fz; if (level.type == SectorLevelType.Ceiling) { z -= thingheight; } if (z < floorpos.z) { lowerfloorz = z; break; } } } float floorz = cz - fz; // Floor height when counted from ceiling if (lowerfloorz != float.MaxValue && lowertingz != float.MinValue) { // Transform back to ceiling-aligned position return(cz - fz - Math.Min(Math.Max(lowerfloorz, lowertingz), floorz) - thingheight); } if (lowerfloorz != float.MaxValue) { // Transform back to ceiling-aligned position return(cz - fz - Math.Min(lowerfloorz, floorz) - thingheight); } if (lowertingz != float.MinValue) { // Transform back to ceiling-aligned position return(cz - fz - Math.Min(lowertingz, floorz) - thingheight); } return(floorz - thingheight); // Align to real floor } else { float lowertingz = GetNextLowerThingZ(mode, intersectingthings, (absolute ? pos.z - fz : pos.z), thingheight); float lowerfloorz = float.MaxValue; // Do it only when there are extrafloors if (sd.LightLevels.Count > 2) { // Unlike sd.ExtraFloors, these are sorted by height for (int i = sd.LightLevels.Count - 1; i > -1; i--) { SectorLevel level = sd.LightLevels[i]; if (level.type == SectorLevelType.Light || level.type == SectorLevelType.Glow) { continue; // Skip lights and glows } float z = level.plane.GetZ(pos) - fz; if (level.type == SectorLevelType.Ceiling) { z -= thingheight; } if (z < pos.z) { lowerfloorz = z; break; } } } float floorz = sd.Floor.plane.GetZ(pos); // Floor-aligned relative target thing z float floorpos = 0; if (lowerfloorz != float.MaxValue && lowertingz != float.MinValue) { floorpos = Math.Max(Math.Max(lowerfloorz, lowertingz), floorz); } if (lowerfloorz != float.MaxValue) { floorpos = Math.Max(lowerfloorz, floorz); } if (lowertingz != float.MinValue) { floorpos = Math.Max(lowertingz, floorz); } return(absolute ? floorpos + floorz : floorpos); // Convert to absolute position if necessary } }
// Constructor public VisualLower(BaseVisualMode mode, VisualSector vs, Sidedef s) : base(mode, vs, s) { // We have no destructor GC.SuppressFinalize(this); }
// This performs texture floodfill along all walls that match with the same texture // NOTE: This method uses the sidedefs marking to indicate which sides have been filled // When resetsidemarks is set to true, all sidedefs will first be marked false (not aligned). // Setting resetsidemarks to false is usefull to fill only within a specific selection // (set the marked property to true for the sidedefs outside the selection) public static void FloodfillTextures(BaseVisualMode mode, Sidedef start, HashSet <long> originaltextures, string filltexture, bool resetsidemarks) { Stack <Tools.SidedefFillJob> todo = new Stack <Tools.SidedefFillJob>(50); // Mark all sidedefs false (they will be marked true when the texture is aligned) if (resetsidemarks) { General.Map.Map.ClearMarkedSidedefs(false); } // Begin with first sidedef if (SidedefTextureMatch(mode, start, originaltextures)) { todo.Push(new Tools.SidedefFillJob { sidedef = start, forward = true }); } // Continue until nothing more to align while (todo.Count > 0) { // Get the align job to do Tools.SidedefFillJob j = todo.Pop(); //mxd. Get visual parts if (mode.VisualSectorExists(j.sidedef.Sector)) { VisualSidedefParts parts = ((BaseVisualSector)mode.GetVisualSector(j.sidedef.Sector)).GetSidedefParts(j.sidedef); // Apply texturing if ((parts.upper != null && parts.upper.Triangles > 0) && originaltextures.Contains(j.sidedef.LongHighTexture)) { j.sidedef.SetTextureHigh(filltexture); } if (((parts.middledouble != null && parts.middledouble.Triangles > 0) || (parts.middlesingle != null && parts.middlesingle.Triangles > 0)) && originaltextures.Contains(j.sidedef.LongMiddleTexture)) { j.sidedef.SetTextureMid(filltexture); } if ((parts.lower != null && parts.lower.Triangles > 0) && originaltextures.Contains(j.sidedef.LongLowTexture)) { j.sidedef.SetTextureLow(filltexture); } } j.sidedef.Marked = true; if (j.forward) { // Add sidedefs forward (connected to the right vertex) Vertex v = j.sidedef.IsFront ? j.sidedef.Line.End : j.sidedef.Line.Start; AddSidedefsForFloodfill(mode, todo, v, true, originaltextures); // Add sidedefs backward (connected to the left vertex) v = j.sidedef.IsFront ? j.sidedef.Line.Start : j.sidedef.Line.End; AddSidedefsForFloodfill(mode, todo, v, false, originaltextures); } else { // Add sidedefs backward (connected to the left vertex) Vertex v = j.sidedef.IsFront ? j.sidedef.Line.Start : j.sidedef.Line.End; AddSidedefsForFloodfill(mode, todo, v, false, originaltextures); // Add sidedefs forward (connected to the right vertex) v = j.sidedef.IsFront ? j.sidedef.Line.End : j.sidedef.Line.Start; AddSidedefsForFloodfill(mode, todo, v, true, originaltextures); } } }
// Constructor public VisualFloor(BaseVisualMode mode, VisualSector vs) : base(mode, vs) { // We have no destructor GC.SuppressFinalize(this); }
// Constructor public VisualMiddleBack(BaseVisualMode mode, VisualSector vs, Sidedef s) : base(mode, vs, s) { }