diff --git a/Documents/planeslogic.png b/Documents/planeslogic.png new file mode 100644 index 00000000..4df2da44 Binary files /dev/null and b/Documents/planeslogic.png differ diff --git a/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualMode.cs b/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualMode.cs index edcbc425..99d39544 100644 --- a/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualMode.cs +++ b/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualMode.cs @@ -462,7 +462,8 @@ namespace CodeImp.DoomBuilder.GZDoomEditing } } // ========== Sector 3D floor (see http://zdoom.org/wiki/Sector_Set3dFloor) ========== - else if(l.Action == 160) + // ========== Transfer Brightness (see http://zdoom.org/wiki/ExtraFloor_LightOnly) ========= + else if((l.Action == 160) || (l.Action == 50)) { if(sectortags.ContainsKey(l.Args[0])) { @@ -480,7 +481,8 @@ namespace CodeImp.DoomBuilder.GZDoomEditing foreach(Thing t in General.Map.Map.Things) { // ========== Copy floor slope ========== - if(t.Type == 9510) + // ========== Line floor slope ========== + if((t.Type == 9510) || (t.Type == 9500)) { t.DetermineSector(blockmap); if(t.Sector != null) diff --git a/Source/Plugins/GZDoomEditing/VisualModes/SectorData.cs b/Source/Plugins/GZDoomEditing/VisualModes/SectorData.cs index 0df82594..d4329c56 100644 --- a/Source/Plugins/GZDoomEditing/VisualModes/SectorData.cs +++ b/Source/Plugins/GZDoomEditing/VisualModes/SectorData.cs @@ -216,6 +216,25 @@ namespace CodeImp.DoomBuilder.GZDoomEditing levels.Add(c); } } + // ========== Transfer Brightness (see http://zdoom.org/wiki/ExtraFloor_LightOnly) ========= + else if(l.Action == 50) + { + if(l.Front != null) + { + SectorData sd = mode.GetSectorData(l.Front.Sector); + if(!sd.Built) sd.BuildLevels(mode); + + SectorLevel f = new SectorLevel(sd.Floor); + SectorLevel c = new SectorLevel(sd.Ceiling); + c.type = SectorLevelType.Light; + f.type = SectorLevelType.Light; + f.color = 0; + f.brightnessbelow = 0; + f.colorbelow = PixelColor.FromInt(0); + //levels.Add(f); + levels.Add(c); + } + } } foreach(Thing t in things) @@ -241,6 +260,39 @@ namespace CodeImp.DoomBuilder.GZDoomEditing floor.plane = tsd.floor.plane; } } + // ========== Line floor slope ========== + else if(t.Type == 9500) + { + // Find the tagged line + Linedef ld = null; + foreach(Linedef l in General.Map.Map.Linedefs) + { + if(l.Tag == t.Args[0]) + { + ld = l; + break; + } + } + + if(ld != null) + { + // Slope the floor from the linedef to thing + t.DetermineSector(mode.BlockMap); + Vector3D v3 = new Vector3D(t.Position.x, t.Position.y, t.Position.z + t.Sector.FloorHeight); + if(ld.SideOfLine(t.Position) < 0.0f) + { + Vector3D v1 = new Vector3D(ld.Start.Position.x, ld.Start.Position.y, ld.Front.Sector.FloorHeight); + Vector3D v2 = new Vector3D(ld.End.Position.x, ld.End.Position.y, ld.Front.Sector.FloorHeight); + floor.plane = new Plane(v1, v2, v3, true); + } + else + { + Vector3D v1 = new Vector3D(ld.Start.Position.x, ld.Start.Position.y, ld.Back.Sector.FloorHeight); + Vector3D v2 = new Vector3D(ld.End.Position.x, ld.End.Position.y, ld.Back.Sector.FloorHeight); + floor.plane = new Plane(v2, v1, v3, true); + } + } + } } // Sort the levels diff --git a/Source/Plugins/GZDoomEditing/VisualModes/VisualLower.cs b/Source/Plugins/GZDoomEditing/VisualModes/VisualLower.cs index 79bfbb30..f5b5ac42 100644 --- a/Source/Plugins/GZDoomEditing/VisualModes/VisualLower.cs +++ b/Source/Plugins/GZDoomEditing/VisualModes/VisualLower.cs @@ -153,6 +153,8 @@ namespace CodeImp.DoomBuilder.GZDoomEditing // Heights of the floor on the other side float ol = osd.Floor.plane.GetZ(tp.vlt); float or = osd.Floor.plane.GetZ(tp.vrt); + Vector3D vol = new Vector3D(tp.vlt.x, tp.vlt.y, ol); + Vector3D vor = new Vector3D(tp.vrt.x, tp.vrt.y, or); // Go for all levels to build geometry List verts = new List(); @@ -173,55 +175,39 @@ namespace CodeImp.DoomBuilder.GZDoomEditing // When both corners are above the heights of the floor on // the other side, then we can stop building. - if((lbl > ol) && (lbr > or)) + if(((lbl - ol) > 0.001f) && ((lbr - or) > 0.001f)) break; - + // Make coordinates for the corners Vector3D vlb = new Vector3D(tp.vlt.x, tp.vlt.y, lbl); Vector3D vlt = new Vector3D(tp.vlt.x, tp.vlt.y, ltl); Vector3D vrb = new Vector3D(tp.vrb.x, tp.vrb.y, lbr); Vector3D vrt = new Vector3D(tp.vrt.x, tp.vrt.y, ltr); - // Compare corner heights to see if we should split - if((lbl < ltl) && (lbr >= ltr)) + // Check if the plane on the other side crosses our top plane + // Then we must create two vertical parts + float int_u = -1.0f; + if(lt.plane.GetIntersection(vol, vor, ref int_u) && (int_u > 0.0f) && (int_u < 1.0f)) { - // Split vertically with geometry on the left - float u_ray = 1.0f; - lb.plane.GetIntersection(vlt, vrt, ref u_ray); - Vector3D vs = vlt + (vrt - vlt) * u_ray; - Vector2D tlb = tp.GetTextureCoordsAt(vlb); - Vector2D tlt = tp.GetTextureCoordsAt(vlt); - Vector2D ts = tp.GetTextureCoordsAt(vs); - verts.Add(new WorldVertex(vlb.x, vlb.y, vlb.z, c, tlb.x, tlb.y)); - verts.Add(new WorldVertex(vlt.x, vlt.y, vlt.z, c, tlt.x, tlt.y)); - verts.Add(new WorldVertex(vs.x, vs.y, vs.z, c, ts.x, ts.y)); + // Determine top and bottom vertices in the middle (at the split) + Vector3D vmt = vlt + (vrt - vlt) * int_u; + Vector3D vmb = vlb + (vrb - vlb) * int_u; + + // Clip vertices to the heights of the plane on the other side + if(vlt.z > ol) vlt.z = ol; + if(vrt.z > or) vrt.z = or; + + CreateVerticalPart(verts, tp, lb, lt, vmb, vmt, vrb, vrt, c); + CreateVerticalPart(verts, tp, lb, lt, vlb, vlt, vmb, vmt, c); } - else if((lbl >= ltl) && (lbr < ltr)) + else { - // Split vertically with geometry on the right - float u_ray = 0.0f; - lb.plane.GetIntersection(vlt, vrt, ref u_ray); - Vector3D vs = vlt + (vrt - vlt) * u_ray; - Vector2D trb = tp.GetTextureCoordsAt(vrb); - Vector2D trt = tp.GetTextureCoordsAt(vrt); - Vector2D ts = tp.GetTextureCoordsAt(vs); - verts.Add(new WorldVertex(vs.x, vs.y, vs.z, c, ts.x, ts.y)); - verts.Add(new WorldVertex(vrt.x, vrt.y, vrt.z, c, trt.x, trt.y)); - verts.Add(new WorldVertex(vrb.x, vrb.y, vrb.z, c, trb.x, trb.y)); - } - else if((lbl < ltl) && (lbr < ltr)) - { - // Span entire width - Vector2D tlb = tp.GetTextureCoordsAt(vlb); - Vector2D tlt = tp.GetTextureCoordsAt(vlt); - Vector2D trb = tp.GetTextureCoordsAt(vrb); - Vector2D trt = tp.GetTextureCoordsAt(vrt); - verts.Add(new WorldVertex(vlb.x, vlb.y, vlb.z, c, tlb.x, tlb.y)); - verts.Add(new WorldVertex(vlt.x, vlt.y, vlt.z, c, tlt.x, tlt.y)); - verts.Add(new WorldVertex(vrt.x, vrt.y, vrt.z, c, trt.x, trt.y)); - verts.Add(new WorldVertex(vlb.x, vlb.y, vlb.z, c, tlb.x, tlb.y)); - verts.Add(new WorldVertex(vrt.x, vrt.y, vrt.z, c, trt.x, trt.y)); - verts.Add(new WorldVertex(vrb.x, vrb.y, vrb.z, c, trb.x, trb.y)); + // Clip vertices to the heights of the plane on the other side + if(vlt.z > ol) vlt.z = ol; + if(vrt.z > or) vrt.z = or; + + // Create single vertical part + CreateVerticalPart(verts, tp, lb, lt, vlb, vlt, vrb, vrt, c); } } @@ -235,6 +221,53 @@ namespace CodeImp.DoomBuilder.GZDoomEditing return false; } } + + // This creates the geometry for a vertical part of the wall + private void CreateVerticalPart(List verts, TexturePlane tp, SectorLevel lb, SectorLevel lt, + Vector3D vlb, Vector3D vlt, Vector3D vrb, Vector3D vrt, int c) + { + // Compare corner heights to see if we should split + if((vlb.z < vlt.z) && (vrb.z >= vrt.z)) + { + // Split vertically with geometry on the left + float u_ray = 1.0f; + lb.plane.GetIntersection(vlt, vrt, ref u_ray); + Vector3D vs = vlt + (vrt - vlt) * u_ray; + Vector2D tlb = tp.GetTextureCoordsAt(vlb); + Vector2D tlt = tp.GetTextureCoordsAt(vlt); + Vector2D ts = tp.GetTextureCoordsAt(vs); + verts.Add(new WorldVertex(vlb.x, vlb.y, vlb.z, c, tlb.x, tlb.y)); + verts.Add(new WorldVertex(vlt.x, vlt.y, vlt.z, c, tlt.x, tlt.y)); + verts.Add(new WorldVertex(vs.x, vs.y, vs.z, c, ts.x, ts.y)); + } + else if((vlb.z >= vlt.z) && (vrb.z < vrt.z)) + { + // Split vertically with geometry on the right + float u_ray = 0.0f; + lb.plane.GetIntersection(vlt, vrt, ref u_ray); + Vector3D vs = vlt + (vrt - vlt) * u_ray; + Vector2D trb = tp.GetTextureCoordsAt(vrb); + Vector2D trt = tp.GetTextureCoordsAt(vrt); + Vector2D ts = tp.GetTextureCoordsAt(vs); + verts.Add(new WorldVertex(vs.x, vs.y, vs.z, c, ts.x, ts.y)); + verts.Add(new WorldVertex(vrt.x, vrt.y, vrt.z, c, trt.x, trt.y)); + verts.Add(new WorldVertex(vrb.x, vrb.y, vrb.z, c, trb.x, trb.y)); + } + else if((vlb.z < vlt.z) && (vrb.z < vrt.z)) + { + // Span entire width + Vector2D tlb = tp.GetTextureCoordsAt(vlb); + Vector2D tlt = tp.GetTextureCoordsAt(vlt); + Vector2D trb = tp.GetTextureCoordsAt(vrb); + Vector2D trt = tp.GetTextureCoordsAt(vrt); + verts.Add(new WorldVertex(vlb.x, vlb.y, vlb.z, c, tlb.x, tlb.y)); + verts.Add(new WorldVertex(vlt.x, vlt.y, vlt.z, c, tlt.x, tlt.y)); + verts.Add(new WorldVertex(vrt.x, vrt.y, vrt.z, c, trt.x, trt.y)); + verts.Add(new WorldVertex(vlb.x, vlb.y, vlb.z, c, tlb.x, tlb.y)); + verts.Add(new WorldVertex(vrt.x, vrt.y, vrt.z, c, trt.x, trt.y)); + verts.Add(new WorldVertex(vrb.x, vrb.y, vrb.z, c, trb.x, trb.y)); + } + } #endregion