mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-19 15:01:11 +00:00
Merge branch 'texture-skewing' into 'master'
Implement proper texture skewing in Visual Mode See merge request STJr/UltimateZoneBuilder!5
This commit is contained in:
commit
10e2e3f4cb
7 changed files with 435 additions and 136 deletions
|
@ -625,6 +625,8 @@ speciallinedefs
|
|||
impassableflag = 1;
|
||||
upperunpeggedflag = 8;
|
||||
lowerunpeggedflag = 16;
|
||||
slopeskewflag = 32;
|
||||
nomidtextureskewflag = 128;
|
||||
repeatmidtextureflag = 1024;
|
||||
pegmidtextureflag = 256;
|
||||
}
|
||||
|
@ -639,6 +641,8 @@ speciallinedefs_udmf
|
|||
lowerunpeggedflag = "dontpegbottom";
|
||||
repeatmidtextureflag = "wrapmidtex";
|
||||
pegmidtextureflag = "midpeg";
|
||||
slopeskewflag = "skewtd";
|
||||
nomidtextureskewflag = "noskew";
|
||||
}
|
||||
|
||||
scriptlumpnames
|
||||
|
|
|
@ -77,6 +77,8 @@ namespace CodeImp.DoomBuilder.Config
|
|||
private readonly string upperunpeggedflag;
|
||||
private readonly string lowerunpeggedflag;
|
||||
private readonly string pegmidtextureflag;
|
||||
private readonly string slopeskewflag;
|
||||
private readonly string nomidtextureskewflag;
|
||||
private readonly bool mixtexturesflats;
|
||||
private readonly bool generalizedactions;
|
||||
private readonly bool generalizedeffects;
|
||||
|
@ -245,6 +247,8 @@ namespace CodeImp.DoomBuilder.Config
|
|||
public string UpperUnpeggedFlag { get { return upperunpeggedflag; } }
|
||||
public string LowerUnpeggedFlag { get { return lowerunpeggedflag; } }
|
||||
public string PegMidtextureFlag { get { return pegmidtextureflag; } }
|
||||
public string SlopeSkewFlag { get { return slopeskewflag; } }
|
||||
public string NoMidtextureSkewFlag { get { return nomidtextureskewflag; } }
|
||||
public bool MixTexturesFlats { get { return mixtexturesflats; } }
|
||||
public bool GeneralizedActions { get { return generalizedactions; } }
|
||||
public bool GeneralizedEffects { get { return generalizedeffects; } }
|
||||
|
@ -531,6 +535,10 @@ namespace CodeImp.DoomBuilder.Config
|
|||
pegmidtextureflag = ((int)obj == 0) ? lowerunpeggedflag : ((int)obj).ToString(CultureInfo.InvariantCulture);
|
||||
else
|
||||
pegmidtextureflag = obj.ToString();
|
||||
obj = cfg.ReadSettingObject("slopeskewflag", 0);
|
||||
if (obj is int) slopeskewflag = ((int)obj).ToString(CultureInfo.InvariantCulture); else slopeskewflag = obj.ToString();
|
||||
obj = cfg.ReadSettingObject("nomidtextureskewflag", 0);
|
||||
if (obj is int) nomidtextureskewflag = ((int)obj).ToString(CultureInfo.InvariantCulture); else nomidtextureskewflag = obj.ToString();
|
||||
|
||||
// Get texture and flat sources
|
||||
textureranges = cfg.ReadSetting("textures", new Hashtable());
|
||||
|
|
|
@ -156,40 +156,89 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
// the values are stored in a TexturePlane)
|
||||
// NOTE: I use a small bias for the floor height, because if the difference in
|
||||
// height is 0 then the TexturePlane doesn't work!
|
||||
TexturePlane tp = new TexturePlane();
|
||||
Vector3D vlt, vlb, vrt, vrb;
|
||||
Vector2D tlt, tlb, trt, trb;
|
||||
|
||||
double floorbias = (Sidedef.Other.Sector.FloorHeight == Sidedef.Sector.FloorHeight) ? 1.0 : 0.0;
|
||||
if(Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag))
|
||||
double planefloorbias = Math.Abs(osd.Floor.plane.GetZ(vr) - sd.Floor.plane.GetZ(vr)) < 0.5 ? 1.0 : 0.0;
|
||||
double texturevpeg = 0;
|
||||
|
||||
bool lowerunpegged = Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag);
|
||||
bool slopeskew = Sidedef.Line.IsFlagSet(General.Map.Config.SlopeSkewFlag);
|
||||
|
||||
if (lowerunpegged)
|
||||
{
|
||||
if(Sidedef.Sector.HasSkyCeiling && Sidedef.Other.Sector.HasSkyCeiling)
|
||||
if (slopeskew)
|
||||
{
|
||||
// mxd. Replicate Doom texture offset glitch when front and back sector's ceilings are sky
|
||||
tp.tlt.y = (double)Sidedef.Other.Sector.CeilHeight - Sidedef.Other.Sector.FloorHeight;
|
||||
}
|
||||
texturevpeg = sd.Ceiling.plane.GetZ(vl) - osd.Floor.plane.GetZ(vl);
|
||||
}
|
||||
//if(Sidedef.Sector.HasSkyCeiling && Sidedef.Other.Sector.HasSkyCeiling)
|
||||
//{
|
||||
// // mxd. Replicate Doom texture offset glitch when front and back sector's ceilings are sky
|
||||
// texturevpeg = (double)Sidedef.Other.Sector.CeilHeight - Sidedef.Other.Sector.FloorHeight;
|
||||
//}
|
||||
else
|
||||
{
|
||||
// When lower unpegged is set, the lower texture is bound to the bottom
|
||||
tp.tlt.y = (double) Sidedef.Sector.CeilHeight - Sidedef.Other.Sector.FloorHeight;
|
||||
texturevpeg = (double) Sidedef.Sector.CeilHeight - Sidedef.Other.Sector.FloorHeight;
|
||||
}
|
||||
}
|
||||
tp.trb.x = tp.tlt.x + Math.Round(Sidedef.Line.Length); //mxd. (G)ZDoom snaps texture coordinates to integral linedef length
|
||||
tp.trb.y = tp.tlt.y + (Sidedef.Other.Sector.FloorHeight - (Sidedef.Sector.FloorHeight + floorbias));
|
||||
|
||||
tlt.x = tlb.x = 0;
|
||||
trt.x = trb.x = Math.Round(Sidedef.Line.Length); //mxd. (G)ZDoom snaps texture coordinates to integral linedef length
|
||||
tlt.y = trt.y = texturevpeg;
|
||||
tlb.y = trb.y = texturevpeg + (Sidedef.Other.Sector.FloorHeight - (Sidedef.Sector.FloorHeight + floorbias));
|
||||
|
||||
if (!slopeskew)
|
||||
{
|
||||
// Unskewed
|
||||
tlb.y -= sd.Floor.plane.GetZ(vl) - Sidedef.Sector.FloorHeight;
|
||||
trb.y -= sd.Floor.plane.GetZ(vr) - Sidedef.Sector.FloorHeight;
|
||||
tlt.y -= osd.Floor.plane.GetZ(vl) - Sidedef.Other.Sector.FloorHeight;
|
||||
trt.y -= osd.Floor.plane.GetZ(vr) - Sidedef.Other.Sector.FloorHeight;
|
||||
}
|
||||
else if (lowerunpegged)
|
||||
{
|
||||
// Skewed by bottom
|
||||
tlb.y = texturevpeg + osd.Floor.plane.GetZ(vl) - sd.Floor.plane.GetZ(vl);
|
||||
trb.y = tlb.y;
|
||||
tlt.y = tlb.y - (osd.Floor.plane.GetZ(vl) - sd.Floor.plane.GetZ(vl));
|
||||
trt.y = trb.y - (osd.Floor.plane.GetZ(vr) - sd.Floor.plane.GetZ(vr));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skewed by top
|
||||
tlb.y = texturevpeg + osd.Floor.plane.GetZ(vl) - sd.Floor.plane.GetZ(vl);
|
||||
trb.y = texturevpeg + osd.Floor.plane.GetZ(vr) - sd.Floor.plane.GetZ(vr);
|
||||
}
|
||||
|
||||
if (Math.Abs(trb.y - trt.y) < 0.5f) trb.y = trt.y - 1.0f;
|
||||
|
||||
// Apply texture offset
|
||||
tp.tlt += tof;
|
||||
tp.trb += tof;
|
||||
|
||||
tlt += tof;
|
||||
tlb += tof;
|
||||
trb += tof;
|
||||
trt += tof;
|
||||
|
||||
// Transform pixel coordinates to texture coordinates
|
||||
tp.tlt /= tsz;
|
||||
tp.trb /= tsz;
|
||||
|
||||
// Left top and right bottom of the geometry that
|
||||
tp.vlt = new Vector3D(vl.x, vl.y, Sidedef.Other.Sector.FloorHeight);
|
||||
tp.vrb = new Vector3D(vr.x, vr.y, Sidedef.Sector.FloorHeight + floorbias);
|
||||
|
||||
// Make the right-top coordinates
|
||||
tp.trt = new Vector2D(tp.trb.x, tp.tlt.y);
|
||||
tp.vrt = new Vector3D(tp.vrb.x, tp.vrb.y, tp.vlt.z);
|
||||
|
||||
tlt /= tsz;
|
||||
tlb /= tsz;
|
||||
trb /= tsz;
|
||||
trt /= tsz;
|
||||
|
||||
// Geometry coordinates
|
||||
vlt = new Vector3D(vl.x, vl.y, osd.Floor.plane.GetZ(vl));
|
||||
vlb = new Vector3D(vl.x, vl.y, sd.Floor.plane.GetZ(vl));
|
||||
vrb = new Vector3D(vr.x, vr.y, sd.Floor.plane.GetZ(vr) + planefloorbias);
|
||||
vrt = new Vector3D(vr.x, vr.y, osd.Floor.plane.GetZ(vr));
|
||||
|
||||
TexturePlane tp = new TexturePlane();
|
||||
tp.tlt = lowerunpegged ? tlb : tlt;
|
||||
tp.trb = trb;
|
||||
tp.trt = trt;
|
||||
tp.vlt = lowerunpegged ? vlb : vlt;
|
||||
tp.vrb = vrb;
|
||||
tp.vrt = vrt;
|
||||
|
||||
// Create initial polygon, which is just a quad between floor and ceiling
|
||||
WallPolygon poly = new WallPolygon();
|
||||
poly.Add(new Vector3D(vl.x, vl.y, vlzf));
|
||||
|
|
|
@ -162,7 +162,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
Vector2D tsz = new Vector2D(Math.Ceiling(base.Texture.ScaledWidth / tscale.x), Math.Ceiling(base.Texture.ScaledHeight / tscale.y));
|
||||
|
||||
// Get texture offsets
|
||||
Vector2D tof = new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY) + new Vector2D(sourceside.OffsetX, sourceside.OffsetY);
|
||||
//Vector2D tof = new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY) + new Vector2D(sourceside.OffsetX, sourceside.OffsetY);
|
||||
Vector2D tof = new Vector2D(Sidedef.OffsetX, 0.0f) + new Vector2D(0.0f, sourceside.OffsetY);
|
||||
|
||||
tof = tof + toffset1 + toffset2;
|
||||
|
||||
|
@ -184,35 +185,59 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
// We choose here.
|
||||
double sourcetopheight = extrafloor.VavoomType ? sourceside.Sector.FloorHeight : sourceside.Sector.CeilHeight;
|
||||
double sourcebottomheight = extrafloor.VavoomType ? sourceside.Sector.CeilHeight : sourceside.Sector.FloorHeight;
|
||||
|
||||
|
||||
// Determine texture coordinates plane as they would be in normal circumstances.
|
||||
// We can then use this plane to find any texture coordinate we need.
|
||||
// The logic here is the same as in the original VisualMiddleSingle (except that
|
||||
// the values are stored in a TexturePlane)
|
||||
// NOTE: I use a small bias for the floor height, because if the difference in
|
||||
// height is 0 then the TexturePlane doesn't work!
|
||||
TexturePlane tp = new TexturePlane();
|
||||
double floorbias = (sourcetopheight == sourcebottomheight) ? 1.0f : 0.0f;
|
||||
Vector3D vlt, vlb, vrt, vrb;
|
||||
Vector2D tlt, tlb, trt, trb;
|
||||
bool lowerunpegged = sourceside.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag);
|
||||
bool slopeskew = sourceside.Line.IsFlagSet(General.Map.Config.SlopeSkewFlag);
|
||||
|
||||
double topheight = slopeskew ? extrafloor.Ceiling.plane.GetZ(vl) : sourcetopheight;
|
||||
double bottomheight = slopeskew ? extrafloor.Floor.plane.GetZ(vl) : sourcebottomheight;
|
||||
double topheight2 = slopeskew ? extrafloor.Ceiling.plane.GetZ(vr) : sourcetopheight;
|
||||
double bottomheight2 = slopeskew ? extrafloor.Floor.plane.GetZ(vr) : sourcebottomheight;
|
||||
//float floorbias = (topheight == bottomheight) ? 1.0f : 0.0f;
|
||||
//float floorbias2 = (topheight2 == bottomheight2) ? 1.0f : 0.0f;
|
||||
|
||||
tlt.x = tlb.x = 0;
|
||||
trt.x = trb.x = Sidedef.Line.Length;
|
||||
// For SRB2, invert Lower Unpegged behavior for non-skewed 3D floors
|
||||
tlt.y = !(lowerunpegged ^ slopeskew) ? 0 : -(topheight - bottomheight);
|
||||
trt.y = !(lowerunpegged ^ slopeskew) ? 0 : -(topheight2 - bottomheight2);
|
||||
tlb.y = !(!lowerunpegged ^ slopeskew) ? 0 : (topheight - bottomheight);
|
||||
trb.y = !(!lowerunpegged ^ slopeskew) ? 0 : (topheight2 - bottomheight2);
|
||||
|
||||
tp.trb.x = tp.tlt.x + Math.Round(Sidedef.Line.Length); //mxd. (G)ZDoom snaps texture coordinates to integral linedef length
|
||||
tp.trb.y = tp.tlt.y + (sourcetopheight - sourcebottomheight) + floorbias;
|
||||
|
||||
// Apply texture offset
|
||||
tp.tlt += tof;
|
||||
tp.trb += tof;
|
||||
|
||||
tlt += tof;
|
||||
tlb += tof;
|
||||
trb += tof;
|
||||
trt += tof;
|
||||
|
||||
// Transform pixel coordinates to texture coordinates
|
||||
tp.tlt /= tsz;
|
||||
tp.trb /= tsz;
|
||||
|
||||
// Left top and right bottom of the geometry that
|
||||
tp.vlt = new Vector3D(vl.x, vl.y, sourcetopheight);
|
||||
tp.vrb = new Vector3D(vr.x, vr.y, sourcebottomheight + floorbias);
|
||||
|
||||
// Make the right-top coordinates
|
||||
tp.trt = new Vector2D(tp.trb.x, tp.tlt.y);
|
||||
tp.vrt = new Vector3D(tp.vrb.x, tp.vrb.y, tp.vlt.z);
|
||||
|
||||
tlt /= tsz;
|
||||
tlb /= tsz;
|
||||
trb /= tsz;
|
||||
trt /= tsz;
|
||||
|
||||
// Geometry coordinates
|
||||
vlt = new Vector3D(vl.x, vl.y, topheight);
|
||||
vlb = new Vector3D(vl.x, vl.y, bottomheight);
|
||||
vrb = new Vector3D(vr.x, vr.y, bottomheight2);
|
||||
vrt = new Vector3D(vr.x, vr.y, topheight2);
|
||||
|
||||
TexturePlane tp = new TexturePlane();
|
||||
tp.tlt = lowerunpegged ? tlb : tlt;
|
||||
tp.trb = trb;
|
||||
tp.trt = trt;
|
||||
tp.vlt = lowerunpegged ? vlb : vlt;
|
||||
tp.vrb = vrb;
|
||||
tp.vrt = vrt;
|
||||
|
||||
//mxd. Get ceiling and floor heights. Use our and neighbour sector's data
|
||||
SectorData sdo = mode.GetSectorData(Sidedef.Other.Sector);
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
#region ================== Variables
|
||||
|
||||
private bool repeatmidtex;
|
||||
private int repetitions;
|
||||
private Plane topclipplane;
|
||||
private Plane bottomclipplane;
|
||||
|
||||
|
@ -46,6 +47,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
|
||||
#region ================== Properties
|
||||
|
||||
private bool RepeatIndefinitely { get { return repeatmidtex && repetitions == 1; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Setup
|
||||
|
@ -153,35 +156,139 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
// the values are stored in a TexturePlane)
|
||||
// NOTE: I use a small bias for the floor height, because if the difference in
|
||||
// height is 0 then the TexturePlane doesn't work!
|
||||
TexturePlane tp = new TexturePlane();
|
||||
Vector3D vlt, vlb, vrt, vrb;
|
||||
Vector2D tlt, tlb, trt, trb;
|
||||
double floorbias = (Sidedef.Sector.CeilHeight == Sidedef.Sector.FloorHeight) ? 1.0 : 0.0;
|
||||
double geotop = Math.Min(Sidedef.Sector.CeilHeight, Sidedef.Other.Sector.CeilHeight);
|
||||
double geobottom = Math.Max(Sidedef.Sector.FloorHeight, Sidedef.Other.Sector.FloorHeight);
|
||||
double zoffset = Sidedef.Sector.CeilHeight - Sidedef.Other.Sector.CeilHeight; //mxd
|
||||
double geoplanetop = Math.Min(sd.Ceiling.plane.GetZ(vl), osd.Ceiling.plane.GetZ(vl));
|
||||
double geoplanebottom = Math.Max(sd.Floor.plane.GetZ(vl), osd.Floor.plane.GetZ(vl));
|
||||
|
||||
// When peg midtexture is set, the middle texture is bound to the bottom
|
||||
if(Sidedef.Line.IsFlagSet(General.Map.Config.PegMidtextureFlag))
|
||||
tp.tlt.y = tsz.y - (geotop - geobottom);
|
||||
bool lowerunpegged = Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag);
|
||||
bool pegmidtexture = Sidedef.Line.IsFlagSet(General.Map.Config.PegMidtextureFlag);
|
||||
bool nomidtextureskew = Sidedef.Line.IsFlagSet(General.Map.Config.NoMidtextureSkewFlag);
|
||||
|
||||
double textop = nomidtextureskew ? geotop : geoplanetop;
|
||||
double texbottom = nomidtextureskew ? geobottom : geoplanebottom;
|
||||
|
||||
if (General.Map.UDMF)
|
||||
{
|
||||
repeatmidtex = Sidedef.IsFlagSet("wrapmidtex") || Sidedef.Line.IsFlagSet("wrapmidtex"); //mxd
|
||||
repetitions = repeatmidtex ? Sidedef.Fields.GetValue("repeatcnt", 0) + 1 : 1;
|
||||
}
|
||||
else if (General.Map.HEXEN)
|
||||
{
|
||||
repeatmidtex = Sidedef.Line.Action == 121 && (Sidedef.Line.Args[1] & 16) == 16;
|
||||
repetitions = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
repeatmidtex = false;
|
||||
repetitions = 1;
|
||||
}
|
||||
|
||||
// First determine the visible portion of the texture
|
||||
if (!RepeatIndefinitely)
|
||||
{
|
||||
// Determine top portion height
|
||||
if (Sidedef.Line.IsFlagSet(General.Map.Config.PegMidtextureFlag))
|
||||
textop = texbottom + tof.y + repetitions * Math.Abs(tsz.y);
|
||||
else
|
||||
textop += tof.y;
|
||||
|
||||
// Calculate bottom portion height
|
||||
texbottom = textop - repetitions * Math.Abs(tsz.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Sidedef.Line.IsFlagSet(General.Map.Config.PegMidtextureFlag))
|
||||
{
|
||||
//textop = topheight;
|
||||
texbottom += tof.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
textop += tof.y;
|
||||
//texbottom = bottomheight;
|
||||
}
|
||||
}
|
||||
|
||||
double h = Math.Min(textop, geoplanetop);
|
||||
double l = Math.Max(texbottom, geoplanebottom);
|
||||
double texturevpeg;
|
||||
|
||||
// When lower unpegged is set, the middle texture is bound to the bottom
|
||||
if (pegmidtexture)
|
||||
texturevpeg = repetitions * Math.Abs(tsz.y) - h + texbottom;
|
||||
else
|
||||
texturevpeg = textop - h;
|
||||
|
||||
tlt.x = tlb.x = tof.x;
|
||||
trt.x = trb.x = tof.x + Sidedef.Line.Length;
|
||||
tlt.y = trt.y = texturevpeg;
|
||||
tlb.y = trb.y = texturevpeg + h - (l + floorbias);
|
||||
|
||||
double rh = h;
|
||||
double rl = l;
|
||||
|
||||
// Correct to account for slopes
|
||||
double midtextureslant;
|
||||
|
||||
if (nomidtextureskew)
|
||||
midtextureslant = 0;
|
||||
else if (pegmidtexture)
|
||||
midtextureslant = osd.Floor.plane.GetZ(vl) < sd.Floor.plane.GetZ(vl)
|
||||
? sd.Floor.plane.GetZ(vr) - sd.Floor.plane.GetZ(vl)
|
||||
: osd.Floor.plane.GetZ(vr) - osd.Floor.plane.GetZ(vl);
|
||||
else
|
||||
midtextureslant = sd.Ceiling.plane.GetZ(vl) < osd.Ceiling.plane.GetZ(vl)
|
||||
? sd.Ceiling.plane.GetZ(vr) - sd.Ceiling.plane.GetZ(vl)
|
||||
: osd.Ceiling.plane.GetZ(vr) - osd.Ceiling.plane.GetZ(vl);
|
||||
|
||||
double newtextop = textop + midtextureslant;
|
||||
double newtexbottom = texbottom + midtextureslant;
|
||||
|
||||
double highcut = geotop + (sd.Ceiling.plane.GetZ(vl) < osd.Ceiling.plane.GetZ(vl)
|
||||
? sd.Ceiling.plane.GetZ(vr) - sd.Ceiling.plane.GetZ(vl)
|
||||
: osd.Ceiling.plane.GetZ(vr) - osd.Ceiling.plane.GetZ(vl));
|
||||
double lowcut = geobottom + (osd.Floor.plane.GetZ(vl) < sd.Floor.plane.GetZ(vl)
|
||||
? sd.Floor.plane.GetZ(vr) - sd.Floor.plane.GetZ(vl)
|
||||
: osd.Floor.plane.GetZ(vr) - osd.Floor.plane.GetZ(vl));
|
||||
|
||||
// Texture stuff
|
||||
rh = Math.Min(highcut, newtextop);
|
||||
rl = Math.Max(newtexbottom, lowcut);
|
||||
|
||||
double newtexturevpeg;
|
||||
|
||||
// When lower unpegged is set, the middle texture is bound to the bottom
|
||||
if (pegmidtexture)
|
||||
newtexturevpeg = repetitions * Math.Abs(tsz.y) - rh + newtexbottom;
|
||||
else
|
||||
newtexturevpeg = newtextop - rh;
|
||||
|
||||
trt.y = newtexturevpeg;
|
||||
trb.y = newtexturevpeg + rh - (rl + floorbias);
|
||||
|
||||
if(zoffset > 0) tp.tlt.y -= zoffset; //mxd
|
||||
tp.trb.x = tp.tlt.x + Math.Round(Sidedef.Line.Length); //mxd. (G)ZDoom snaps texture coordinates to integral linedef length
|
||||
tp.trb.y = tp.tlt.y + (Sidedef.Sector.CeilHeight - (Sidedef.Sector.FloorHeight + floorbias));
|
||||
|
||||
// Apply texture offset
|
||||
tp.tlt += tof;
|
||||
tp.trb += tof;
|
||||
|
||||
// Transform pixel coordinates to texture coordinates
|
||||
tp.tlt /= tsz;
|
||||
tp.trb /= tsz;
|
||||
tlt /= tsz;
|
||||
tlb /= tsz;
|
||||
trb /= tsz;
|
||||
trt /= tsz;
|
||||
|
||||
// Left top and right bottom of the geometry that
|
||||
tp.vlt = new Vector3D(vl.x, vl.y, Sidedef.Sector.CeilHeight);
|
||||
tp.vrb = new Vector3D(vr.x, vr.y, Sidedef.Sector.FloorHeight + floorbias);
|
||||
// Geometry coordinates
|
||||
vlt = new Vector3D(vl.x, vl.y, h);
|
||||
vlb = new Vector3D(vl.x, vl.y, l);
|
||||
vrb = new Vector3D(vr.x, vr.y, rl);
|
||||
vrt = new Vector3D(vr.x, vr.y, rh);
|
||||
|
||||
// Make the right-top coordinates
|
||||
tp.trt = new Vector2D(tp.trb.x, tp.tlt.y);
|
||||
tp.vrt = new Vector3D(tp.vrb.x, tp.vrb.y, tp.vlt.z);
|
||||
TexturePlane tp = new TexturePlane();
|
||||
tp.tlt = pegmidtexture ? tlb : tlt;
|
||||
tp.trb = trb;
|
||||
tp.trt = trt;
|
||||
tp.vlt = pegmidtexture ? vlb : vlt;
|
||||
tp.vrb = vrb;
|
||||
tp.vrt = vrt;
|
||||
|
||||
// Keep top and bottom planes for intersection testing
|
||||
top = sd.Ceiling.plane;
|
||||
|
@ -209,36 +316,44 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
|
||||
// Determine if we should repeat the middle texture. In UDMF this is done with a flag, in Hexen with
|
||||
// a argument to the 121:Line_SetIdentification. See https://www.zdoom.org/w/index.php?title=Line_SetIdentification
|
||||
if (General.Map.UDMF)
|
||||
repeatmidtex = Sidedef.IsFlagSet("wrapmidtex") || Sidedef.Line.IsFlagSet("wrapmidtex"); //mxd
|
||||
else if (General.Map.HEXEN)
|
||||
repeatmidtex = Sidedef.Line.Action == 121 && (Sidedef.Line.Args[1] & 16) == 16;
|
||||
else
|
||||
repeatmidtex = false;
|
||||
|
||||
if(!repeatmidtex)
|
||||
// First determine the visible portion of the texture
|
||||
// NOTE: this is done earlier for SRB2 since it's needed earlier
|
||||
|
||||
// Create crop planes (we also need these for intersection testing)
|
||||
if (!nomidtextureskew)
|
||||
{
|
||||
// First determine the visible portion of the texture
|
||||
double textop;
|
||||
if (pegmidtexture)
|
||||
{
|
||||
bottomclipplane = sd.Floor.plane.GetZ(vl) > osd.Floor.plane.GetZ(vl) ? sd.Floor.plane : osd.Floor.plane;
|
||||
Vector3D up = new Vector3D(0f, 0f, texbottom - bottomclipplane.GetZ(vl));
|
||||
bottomclipplane.Offset -= Vector3D.DotProduct(up, bottomclipplane.Normal);
|
||||
|
||||
// Determine top portion height
|
||||
if(Sidedef.Line.IsFlagSet(General.Map.Config.PegMidtextureFlag))
|
||||
textop = geobottom + tof.y + Math.Abs(tsz.y);
|
||||
else
|
||||
textop = geotop + tof.y;
|
||||
topclipplane = bottomclipplane.GetInverted();
|
||||
Vector3D up2 = new Vector3D(0f, 0f, textop - texbottom);
|
||||
topclipplane.Offset -= Vector3D.DotProduct(up2, topclipplane.Normal);
|
||||
}
|
||||
else //Skew according to ceiling
|
||||
{
|
||||
topclipplane = sd.Ceiling.plane.GetZ(vl) < osd.Ceiling.plane.GetZ(vl) ? sd.Ceiling.plane : osd.Ceiling.plane;
|
||||
Vector3D up = new Vector3D(0f, 0f, textop - topclipplane.GetZ(vl));
|
||||
topclipplane.Offset -= Vector3D.DotProduct(up, topclipplane.Normal);
|
||||
|
||||
// Calculate bottom portion height
|
||||
double texbottom = textop - Math.Abs(tsz.y);
|
||||
|
||||
// Create crop planes (we also need these for intersection testing)
|
||||
bottomclipplane = topclipplane.GetInverted();
|
||||
Vector3D down = new Vector3D(0f, 0f, texbottom - textop);
|
||||
bottomclipplane.Offset -= Vector3D.DotProduct(down, bottomclipplane.Normal);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
topclipplane = new Plane(new Vector3D(0, 0, -1), textop);
|
||||
bottomclipplane = new Plane(new Vector3D(0, 0, 1), -texbottom);
|
||||
|
||||
// Crop polygon by these heights
|
||||
CropPoly(ref poly, topclipplane, true);
|
||||
CropPoly(ref poly, bottomclipplane, true);
|
||||
}
|
||||
|
||||
// Crop polygon by these heights
|
||||
CropPoly(ref poly, topclipplane, true);
|
||||
CropPoly(ref poly, bottomclipplane, true);
|
||||
|
||||
//mxd. In(G)ZDoom, middle sidedef parts are not clipped by extrafloors of any type...
|
||||
List<WallPolygon> polygons = new List<WallPolygon> { poly };
|
||||
//ClipExtraFloors(polygons, sd.ExtraFloors, true); //mxd
|
||||
|
@ -282,13 +397,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
// This performs a fast test in object picking
|
||||
public override bool PickFastReject(Vector3D from, Vector3D to, Vector3D dir)
|
||||
{
|
||||
if(!repeatmidtex)
|
||||
{
|
||||
// When the texture is not repeated, leave when outside crop planes
|
||||
//if(!RepeatIndefinitely)
|
||||
//{
|
||||
// When the texture is not repeated indefinitely, leave when outside crop planes
|
||||
if((pickintersect.z < bottomclipplane.GetZ(pickintersect)) ||
|
||||
(pickintersect.z > topclipplane.GetZ(pickintersect)))
|
||||
return false;
|
||||
}
|
||||
//}
|
||||
|
||||
return base.PickFastReject(from, to, dir);
|
||||
}
|
||||
|
@ -316,7 +431,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
% imageWidth);
|
||||
|
||||
int oy;
|
||||
if (repeatmidtex)
|
||||
/*if (RepeatIndefinitely)
|
||||
{
|
||||
bool pegbottom = Sidedef.Line.IsFlagSet(General.Map.Config.PegMidtextureFlag);
|
||||
double zoffset = (pegbottom ? Sidedef.Sector.FloorHeight : Sidedef.Sector.CeilHeight);
|
||||
|
@ -325,10 +440,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
% imageHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
{*/
|
||||
double zoffset = bottomclipplane.GetZ(pickintersect);
|
||||
oy = (int)Math.Ceiling(((pickintersect.z - zoffset) * UniFields.GetFloat(Sidedef.Fields, "scaley_mid", 1.0f) / texscale.y) % imageHeight);
|
||||
}
|
||||
//}
|
||||
|
||||
// Make sure offsets are inside of texture dimensions...
|
||||
if (ox < 0) ox += imageWidth;
|
||||
|
|
|
@ -139,31 +139,76 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
// the values are stored in a TexturePlane)
|
||||
// NOTE: I use a small bias for the floor height, because if the difference in
|
||||
// height is 0 then the TexturePlane doesn't work!
|
||||
TexturePlane tp = new TexturePlane();
|
||||
double floorbias = (Sidedef.Sector.CeilHeight == Sidedef.Sector.FloorHeight) ? 1.0 : 0.0;
|
||||
if(Sidedef.Line.IsFlagSet(General.Map.Config.PegMidtextureFlag))
|
||||
Vector3D vlt, vlb, vrt, vrb;
|
||||
Vector2D tlt, tlb, trt, trb;
|
||||
double texturevpeg = 0;
|
||||
double floorbias = (Sidedef.Sector.CeilHeight == Sidedef.Sector.FloorHeight) ? 1.0f : 0.0f;
|
||||
|
||||
bool lowerunpegged = Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag);
|
||||
bool nomidtextureskew = Sidedef.Line.IsFlagSet(General.Map.Config.NoMidtextureSkewFlag);
|
||||
|
||||
if (lowerunpegged)
|
||||
{
|
||||
// When peg midtexture is set, the middle texture is bound to the bottom
|
||||
tp.tlt.y = tsz.y - (Sidedef.Sector.CeilHeight - Sidedef.Sector.FloorHeight);
|
||||
// When lower unpegged is set, the middle texture is bound to the bottom
|
||||
if (!nomidtextureskew)
|
||||
{
|
||||
texturevpeg = tsz.y - (sd.Ceiling.plane.GetZ(vl) - sd.Floor.plane.GetZ(vl));
|
||||
}
|
||||
else
|
||||
{
|
||||
texturevpeg = tsz.y - (Sidedef.Sector.CeilHeight - Sidedef.Sector.FloorHeight);
|
||||
}
|
||||
}
|
||||
tp.trb.x = tp.tlt.x + Math.Round(Sidedef.Line.Length); //mxd. (G)ZDoom snaps texture coordinates to integral linedef length
|
||||
tp.trb.y = tp.tlt.y + (Sidedef.Sector.CeilHeight - (Sidedef.Sector.FloorHeight + floorbias));
|
||||
|
||||
|
||||
tlt.x = tlb.x = 0;
|
||||
trt.x = trb.x = Sidedef.Line.Length;
|
||||
tlt.y = trt.y = texturevpeg;
|
||||
tlb.y = trb.y = texturevpeg + (Sidedef.Sector.CeilHeight - (Sidedef.Sector.FloorHeight + floorbias));
|
||||
|
||||
// Texture correction for slopes
|
||||
if (nomidtextureskew)
|
||||
{
|
||||
tlt.y += Sidedef.Sector.CeilHeight - sd.Ceiling.plane.GetZ(vl);
|
||||
trt.y += Sidedef.Sector.CeilHeight - sd.Ceiling.plane.GetZ(vr);
|
||||
tlb.y += Sidedef.Sector.FloorHeight - sd.Floor.plane.GetZ(vl);
|
||||
trb.y += Sidedef.Sector.FloorHeight - sd.Floor.plane.GetZ(vr);
|
||||
}
|
||||
else if (lowerunpegged)
|
||||
{
|
||||
tlt.y = tlb.y + sd.Floor.plane.GetZ(vl) - sd.Ceiling.plane.GetZ(vl);
|
||||
trt.y = trb.y + sd.Floor.plane.GetZ(vr) - sd.Ceiling.plane.GetZ(vr);
|
||||
}
|
||||
else
|
||||
{
|
||||
tlb.y = tlt.y - (sd.Floor.plane.GetZ(vl) - sd.Ceiling.plane.GetZ(vl));
|
||||
trb.y = trt.y - (sd.Floor.plane.GetZ(vr) - sd.Ceiling.plane.GetZ(vr));
|
||||
}
|
||||
|
||||
// Apply texture offset
|
||||
tp.tlt += tof;
|
||||
tp.trb += tof;
|
||||
|
||||
tlt += tof;
|
||||
tlb += tof;
|
||||
trb += tof;
|
||||
trt += tof;
|
||||
|
||||
// Transform pixel coordinates to texture coordinates
|
||||
tp.tlt /= tsz;
|
||||
tp.trb /= tsz;
|
||||
|
||||
// Left top and right bottom of the geometry that
|
||||
tp.vlt = new Vector3D(vl.x, vl.y, Sidedef.Sector.CeilHeight);
|
||||
tp.vrb = new Vector3D(vr.x, vr.y, Sidedef.Sector.FloorHeight + floorbias);
|
||||
|
||||
// Make the right-top coordinates
|
||||
tp.trt = new Vector2D(tp.trb.x, tp.tlt.y);
|
||||
tp.vrt = new Vector3D(tp.vrb.x, tp.vrb.y, tp.vlt.z);
|
||||
tlt /= tsz;
|
||||
tlb /= tsz;
|
||||
trb /= tsz;
|
||||
trt /= tsz;
|
||||
|
||||
// Geometry coordinates
|
||||
vlt = new Vector3D(vl.x, vl.y, sd.Ceiling.plane.GetZ(vl));
|
||||
vlb = new Vector3D(vl.x, vl.y, sd.Floor.plane.GetZ(vl) + floorbias);
|
||||
vrb = new Vector3D(vr.x, vr.y, sd.Floor.plane.GetZ(vr));
|
||||
vrt = new Vector3D(vr.x, vr.y, sd.Ceiling.plane.GetZ(vr));
|
||||
|
||||
TexturePlane tp = new TexturePlane();
|
||||
tp.tlt = lowerunpegged ? tlb : tlt;
|
||||
tp.trb = trb;
|
||||
tp.trt = trt;
|
||||
tp.vlt = lowerunpegged ? vlb : vlt;
|
||||
tp.vrb = vrb;
|
||||
tp.vrt = vrt;
|
||||
|
||||
// Get ceiling and floor heights
|
||||
double fl = sd.Floor.plane.GetZ(vl);
|
||||
|
|
|
@ -154,32 +154,85 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
// the values are stored in a TexturePlane)
|
||||
// NOTE: I use a small bias for the floor height, because if the difference in
|
||||
// height is 0 then the TexturePlane doesn't work!
|
||||
TexturePlane tp = new TexturePlane();
|
||||
Vector3D vlt, vlb, vrt, vrb;
|
||||
Vector2D tlt, tlb, trt, trb;
|
||||
double ceilbias = (Sidedef.Other.Sector.CeilHeight == Sidedef.Sector.CeilHeight) ? 1.0 : 0.0;
|
||||
if(!Sidedef.Line.IsFlagSet(General.Map.Config.UpperUnpeggedFlag))
|
||||
double planeceilbias = (Math.Abs(osd.Ceiling.plane.GetZ(vr) - sd.Ceiling.plane.GetZ(vr)) < 0.5) ? 1.0 : 0.0;
|
||||
double texturevpeg = 0;
|
||||
|
||||
bool upperunpegged = Sidedef.Line.IsFlagSet(General.Map.Config.UpperUnpeggedFlag);
|
||||
bool slopeskew = Sidedef.Line.IsFlagSet(General.Map.Config.SlopeSkewFlag);
|
||||
|
||||
if (!upperunpegged)
|
||||
{
|
||||
// When lower unpegged is set, the lower texture is bound to the bottom
|
||||
tp.tlt.y = tsz.y - (Sidedef.Sector.CeilHeight - Sidedef.Other.Sector.CeilHeight);
|
||||
if (slopeskew)
|
||||
{
|
||||
texturevpeg = osd.Ceiling.plane.GetZ(vl) + tsz.y - sd.Ceiling.plane.GetZ(vl);
|
||||
}
|
||||
else
|
||||
{
|
||||
texturevpeg = tsz.y - ((float)Sidedef.Sector.CeilHeight - Sidedef.Other.Sector.CeilHeight);
|
||||
}
|
||||
}
|
||||
tp.trb.x = tp.tlt.x + Math.Round(Sidedef.Line.Length); //mxd. (G)ZDoom snaps texture coordinates to integral linedef length
|
||||
tp.trb.y = tp.tlt.y + (Sidedef.Sector.CeilHeight - (Sidedef.Other.Sector.CeilHeight + ceilbias));
|
||||
|
||||
tlt.x = tlb.x = 0;
|
||||
trt.x = trb.x = Sidedef.Line.Length;
|
||||
tlt.y = trt.y = texturevpeg;
|
||||
tlb.y = trb.y = texturevpeg + (Sidedef.Sector.CeilHeight - (Sidedef.Other.Sector.CeilHeight + ceilbias));
|
||||
|
||||
// Adjust texture y value for sloped walls
|
||||
if (!slopeskew)
|
||||
{
|
||||
// Unskewed
|
||||
tlt.y -= sd.Ceiling.plane.GetZ(vl) - Sidedef.Sector.CeilHeight;
|
||||
trt.y -= sd.Ceiling.plane.GetZ(vr) - Sidedef.Sector.CeilHeight;
|
||||
tlb.y -= osd.Ceiling.plane.GetZ(vl) - Sidedef.Other.Sector.CeilHeight;
|
||||
trb.y -= osd.Ceiling.plane.GetZ(vr) - Sidedef.Other.Sector.CeilHeight;
|
||||
}
|
||||
else if (upperunpegged)
|
||||
{
|
||||
// Skewed by top
|
||||
tlb.y = texturevpeg + sd.Ceiling.plane.GetZ(vl) - osd.Ceiling.plane.GetZ(vl);
|
||||
trb.y = texturevpeg + sd.Ceiling.plane.GetZ(vr) - osd.Ceiling.plane.GetZ(vr);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skewed by bottom
|
||||
tlb.y = texturevpeg + sd.Ceiling.plane.GetZ(vl) - osd.Ceiling.plane.GetZ(vl);
|
||||
trb.y = tlb.y;
|
||||
tlt.y = tlb.y - (sd.Ceiling.plane.GetZ(vl) - osd.Ceiling.plane.GetZ(vl));
|
||||
trt.y = trb.y - (sd.Ceiling.plane.GetZ(vr) - osd.Ceiling.plane.GetZ(vr));
|
||||
}
|
||||
|
||||
|
||||
if (Math.Abs(trb.y - trt.y) < 0.5f) trb.y = trt.y - 1.0f;
|
||||
|
||||
// Apply texture offset
|
||||
tp.tlt += tof;
|
||||
tp.trb += tof;
|
||||
|
||||
tlt += tof;
|
||||
tlb += tof;
|
||||
trb += tof;
|
||||
trt += tof;
|
||||
|
||||
// Transform pixel coordinates to texture coordinates
|
||||
tp.tlt /= tsz;
|
||||
tp.trb /= tsz;
|
||||
|
||||
// Left top and right bottom of the geometry that
|
||||
tp.vlt = new Vector3D(vl.x, vl.y, Sidedef.Sector.CeilHeight);
|
||||
tp.vrb = new Vector3D(vr.x, vr.y, Sidedef.Other.Sector.CeilHeight + ceilbias);
|
||||
|
||||
// Make the right-top coordinates
|
||||
tp.trt = new Vector2D(tp.trb.x, tp.tlt.y);
|
||||
tp.vrt = new Vector3D(tp.vrb.x, tp.vrb.y, tp.vlt.z);
|
||||
|
||||
tlt /= tsz;
|
||||
tlb /= tsz;
|
||||
trb /= tsz;
|
||||
trt /= tsz;
|
||||
|
||||
// Geometry coordinates
|
||||
vlt = new Vector3D(vl.x, vl.y, sd.Ceiling.plane.GetZ(vl));
|
||||
vlb = new Vector3D(vl.x, vl.y, osd.Ceiling.plane.GetZ(vl));
|
||||
vrb = new Vector3D(vr.x, vr.y, osd.Ceiling.plane.GetZ(vr) + planeceilbias);
|
||||
vrt = new Vector3D(vr.x, vr.y, sd.Ceiling.plane.GetZ(vr));
|
||||
|
||||
TexturePlane tp = new TexturePlane();
|
||||
tp.tlt = Sidedef.Line.IsFlagSet(General.Map.Config.UpperUnpeggedFlag) ? tlt : tlb;
|
||||
tp.trb = trb;
|
||||
tp.trt = trt;
|
||||
tp.vlt = Sidedef.Line.IsFlagSet(General.Map.Config.UpperUnpeggedFlag) ? vlt : vlb;
|
||||
tp.vrb = vrb;
|
||||
tp.vrt = vrt;
|
||||
|
||||
// Create initial polygon, which is just a quad between floor and ceiling
|
||||
WallPolygon poly = new WallPolygon();
|
||||
poly.Add(new Vector3D(vl.x, vl.y, sd.Floor.plane.GetZ(vl)));
|
||||
|
|
Loading…
Reference in a new issue