textures now properly aligned in visual mode

This commit is contained in:
codeimp 2008-11-30 20:46:39 +00:00
parent a2407ebc3b
commit 9513eabd58
9 changed files with 493 additions and 233 deletions

View file

@ -109,7 +109,7 @@
<Compile Include="VisualModes\VisualCeiling.cs" /> <Compile Include="VisualModes\VisualCeiling.cs" />
<Compile Include="VisualModes\VisualFloor.cs" /> <Compile Include="VisualModes\VisualFloor.cs" />
<Compile Include="VisualModes\VisualLower.cs" /> <Compile Include="VisualModes\VisualLower.cs" />
<Compile Include="VisualModes\VisualMiddle.cs" /> <Compile Include="VisualModes\VisualMiddleSingle.cs" />
<Compile Include="Testing\WAuthorMode.cs" /> <Compile Include="Testing\WAuthorMode.cs" />
<Compile Include="Testing\WAuthorTools.cs"> <Compile Include="Testing\WAuthorTools.cs">
<SubType>Form</SubType> <SubType>Form</SubType>
@ -121,6 +121,7 @@
<Compile Include="ClassicModes\SectorsMode.cs" /> <Compile Include="ClassicModes\SectorsMode.cs" />
<Compile Include="ClassicModes\ThingsMode.cs" /> <Compile Include="ClassicModes\ThingsMode.cs" />
<Compile Include="ClassicModes\VerticesMode.cs" /> <Compile Include="ClassicModes\VerticesMode.cs" />
<Compile Include="VisualModes\VisualMiddleDouble.cs" />
<Compile Include="VisualModes\VisualUpper.cs" /> <Compile Include="VisualModes\VisualUpper.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View file

@ -85,22 +85,37 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Forget old geometry // Forget old geometry
base.ClearGeometry(); base.ClearGeometry();
// Make the floor and ceiling // Create floor
base.AddGeometry(new VisualFloor(base.Sector)); VisualFloor vf = new VisualFloor();
base.AddGeometry(new VisualCeiling(base.Sector)); if(vf.Setup(base.Sector)) base.AddGeometry(vf);
// Create ceiling
VisualCeiling vc = new VisualCeiling();
if(vc.Setup(base.Sector)) base.AddGeometry(vc);
// Go for all sidedefs // Go for all sidedefs
foreach(Sidedef sd in base.Sector.Sidedefs) foreach(Sidedef sd in base.Sector.Sidedefs)
{ {
// Make middle wall // Doublesided or singlesided?
base.AddGeometry(new VisualMiddle(sd));
// Check if upper and lower parts are possible at all
if(sd.Other != null) if(sd.Other != null)
{ {
// Make upper and lower walls // Create upper part
base.AddGeometry(new VisualLower(sd)); VisualUpper vu = new VisualUpper(sd);
base.AddGeometry(new VisualUpper(sd)); if(vu.Setup()) base.AddGeometry(vu);
// Create lower part
VisualLower vl = new VisualLower(sd);
if(vl.Setup()) base.AddGeometry(vl);
// Create middle part
VisualMiddleDouble vm = new VisualMiddleDouble(sd);
if(vm.Setup()) base.AddGeometry(vm);
}
else
{
// Create middle part
VisualMiddleSingle vm = new VisualMiddleSingle(sd);
if(vm.Setup()) base.AddGeometry(vm);
} }
} }
} }

View file

@ -53,10 +53,17 @@ namespace CodeImp.DoomBuilder.BuilderModes
#endregion #endregion
#region ================== Constructor / Disposer #region ================== Constructor / Setup
// Constructor // Constructor
public VisualCeiling(Sector s) public VisualCeiling()
{
// We have no destructor
GC.SuppressFinalize(this);
}
// This builds the geometry. Returns false when no geometry created.
public bool Setup(Sector s)
{ {
WorldVertex[] verts; WorldVertex[] verts;
WorldVertex v; WorldVertex v;
@ -70,7 +77,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
for(int i = 0; i < s.Triangles.Vertices.Count; i++) for(int i = 0; i < s.Triangles.Vertices.Count; i++)
{ {
// Use sector brightness for color shading // Use sector brightness for color shading
PixelColor pc = new PixelColor(255, unchecked((byte)s.Brightness), unchecked((byte)s.Brightness), unchecked((byte)s.Brightness)); PixelColor pc = new PixelColor(255, unchecked((byte)s.Brightness),
unchecked((byte)s.Brightness),
unchecked((byte)s.Brightness));
verts[i].c = pc.ToInt(); verts[i].c = pc.ToInt();
//verts[i].c = -1; //verts[i].c = -1;
@ -106,11 +115,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Apply vertices // Apply vertices
base.SetVertices(verts); base.SetVertices(verts);
return (verts.Length > 0);
// We have no destructor
GC.SuppressFinalize(this);
} }
#endregion #endregion
#region ================== Methods #region ================== Methods

View file

@ -53,23 +53,32 @@ namespace CodeImp.DoomBuilder.BuilderModes
#endregion #endregion
#region ================== Constructor / Disposer #region ================== Constructor / Setup
// Constructor // Constructor
public VisualFloor(Sector s) public VisualFloor()
{
// We have no destructor
GC.SuppressFinalize(this);
}
// This builds the geometry. Returns false when no geometry created.
public bool Setup(Sector s)
{ {
WorldVertex[] verts; WorldVertex[] verts;
// Load floor texture // Load floor texture
base.Texture = General.Map.Data.GetFlatImage(s.LongFloorTexture); base.Texture = General.Map.Data.GetFlatImage(s.LongFloorTexture);
if(base.Texture == null) base.Texture = General.Map.Data.MissingTexture3D; if(base.Texture == null) base.Texture = General.Map.Data.MissingTexture3D;
// Make vertices // Make vertices
verts = new WorldVertex[s.Triangles.Vertices.Count]; verts = new WorldVertex[s.Triangles.Vertices.Count];
for(int i = 0; i < s.Triangles.Vertices.Count; i++) for(int i = 0; i < s.Triangles.Vertices.Count; i++)
{ {
// Use sector brightness for color shading // Use sector brightness for color shading
PixelColor pc = new PixelColor(255, unchecked((byte)s.Brightness), unchecked((byte)s.Brightness), unchecked((byte)s.Brightness)); PixelColor pc = new PixelColor(255, unchecked((byte)s.Brightness),
unchecked((byte)s.Brightness),
unchecked((byte)s.Brightness));
verts[i].c = pc.ToInt(); verts[i].c = pc.ToInt();
//verts[i].c = -1; //verts[i].c = -1;
@ -84,7 +93,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
verts[i].u = s.Triangles.Vertices[i].x / 64; verts[i].u = s.Triangles.Vertices[i].x / 64;
verts[i].v = s.Triangles.Vertices[i].y / 64; verts[i].v = s.Triangles.Vertices[i].y / 64;
} }
// Vertex coordinates // Vertex coordinates
verts[i].x = s.Triangles.Vertices[i].x; verts[i].x = s.Triangles.Vertices[i].x;
verts[i].y = s.Triangles.Vertices[i].y; verts[i].y = s.Triangles.Vertices[i].y;
@ -93,11 +102,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Apply vertices // Apply vertices
base.SetVertices(verts); base.SetVertices(verts);
return (verts.Length > 0);
// We have no destructor
GC.SuppressFinalize(this);
} }
#endregion #endregion
#region ================== Methods #region ================== Methods

View file

@ -53,28 +53,32 @@ namespace CodeImp.DoomBuilder.BuilderModes
#endregion #endregion
#region ================== Constructor / Disposer #region ================== Constructor / Setup
// Constructor // Constructor
public VisualLower(Sidedef s) : base(s) public VisualLower(Sidedef s) : base(s)
{ {
WorldVertex[] verts; // We have no destructor
float geotop; GC.SuppressFinalize(this);
float geobottom; }
float geoheight;
Vector2D v1, v2;
// This builds the geometry. Returns false when no geometry created.
public bool Setup()
{
// Calculate size of this wall part // Calculate size of this wall part
geotop = (float)s.Other.Sector.FloorHeight; float geotop = (float)Sidedef.Other.Sector.FloorHeight;
geobottom = (float)s.Sector.FloorHeight; float geobottom = (float)Sidedef.Sector.FloorHeight;
geoheight = geotop - geobottom; float geoheight = geotop - geobottom;
if(geoheight > 0.001f) if(geoheight > 0.001f)
{ {
Vector2D t1 = new Vector2D();
Vector2D t2 = new Vector2D();
// Texture given? // Texture given?
if((s.LowTexture.Length > 0) && (s.LowTexture[0] != '-')) if((Sidedef.LowTexture.Length > 0) && (Sidedef.LowTexture[0] != '-'))
{ {
// Load texture // Load texture
base.Texture = General.Map.Data.GetTextureImage(s.LongLowTexture); base.Texture = General.Map.Data.GetTextureImage(Sidedef.LongLowTexture);
if(base.Texture == null) base.Texture = General.Map.Data.MissingTexture3D; if(base.Texture == null) base.Texture = General.Map.Data.MissingTexture3D;
} }
else else
@ -83,43 +87,66 @@ namespace CodeImp.DoomBuilder.BuilderModes
base.Texture = General.Map.Data.MissingTexture3D; base.Texture = General.Map.Data.MissingTexture3D;
} }
// Get coordinates // Get texture scaled size
if(s.IsFront) Vector2D tsz = new Vector2D(base.Texture.ScaledWidth, base.Texture.ScaledHeight);
// Determine texture coordinates
// See http://doom.wikia.com/wiki/Texture_alignment
// We just use pixels for coordinates for now
if(Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag))
{ {
v1 = s.Line.Start.Position; // When lower unpegged is set, the lower texture is bound to the bottom
v2 = s.Line.End.Position; t1.y = (float)Sidedef.Sector.CeilHeight - geotop;
}
t2.x = t1.x + Sidedef.Line.Length;
t2.y = t1.y + geoheight;
// Apply texture offset
t1 += new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY);
t2 += new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY);
// Transform pixel coordinates to texture coordinates
t1 /= tsz;
t2 /= tsz;
// Get world coordinates for geometry
Vector2D v1, v2;
if(Sidedef.IsFront)
{
v1 = Sidedef.Line.Start.Position;
v2 = Sidedef.Line.End.Position;
} }
else else
{ {
v1 = s.Line.End.Position; v1 = Sidedef.Line.End.Position;
v2 = s.Line.Start.Position; v2 = Sidedef.Line.Start.Position;
} }
// Use sector brightness for color shading // Use sector brightness for color shading
PixelColor pc = new PixelColor(255, unchecked((byte)s.Sector.Brightness), unchecked((byte)s.Sector.Brightness), unchecked((byte)s.Sector.Brightness)); PixelColor pc = new PixelColor(255, unchecked((byte)Sidedef.Sector.Brightness),
unchecked((byte)Sidedef.Sector.Brightness),
unchecked((byte)Sidedef.Sector.Brightness));
// Make vertices // Make vertices
verts = new WorldVertex[6]; WorldVertex[] verts = new WorldVertex[6];
verts[0] = new WorldVertex(v1.x, v1.y, geobottom, pc.ToInt(), 0.0f, 1.0f); verts[0] = new WorldVertex(v1.x, v1.y, geobottom, pc.ToInt(), t1.x, t2.y);
verts[1] = new WorldVertex(v1.x, v1.y, geotop, pc.ToInt(), 0.0f, 0.0f); verts[1] = new WorldVertex(v1.x, v1.y, geotop, pc.ToInt(), t1.x, t1.y);
verts[2] = new WorldVertex(v2.x, v2.y, geotop, pc.ToInt(), 1.0f, 0.0f); verts[2] = new WorldVertex(v2.x, v2.y, geotop, pc.ToInt(), t2.x, t1.y);
verts[3] = verts[0]; verts[3] = verts[0];
verts[4] = verts[2]; verts[4] = verts[2];
verts[5] = new WorldVertex(v2.x, v2.y, geobottom, pc.ToInt(), 1.0f, 1.0f); verts[5] = new WorldVertex(v2.x, v2.y, geobottom, pc.ToInt(), t2.x, t2.y);
// Apply vertices
base.SetVertices(verts);
return true;
} }
else else
{ {
// No geometry for invisible wall // No geometry for invisible wall
verts = new WorldVertex[0]; return false;
} }
// Apply vertices
base.SetVertices(verts);
// We have no destructor
GC.SuppressFinalize(this);
} }
#endregion #endregion
#region ================== Methods #region ================== Methods

View file

@ -1,144 +0,0 @@
#region ================== Copyright (c) 2007 Pascal vd Heiden
/*
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
* This program is released under GNU General Public License
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#endregion
#region ================== Namespaces
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using System.Drawing;
using System.ComponentModel;
using CodeImp.DoomBuilder.Map;
using CodeImp.DoomBuilder.Geometry;
using System.Drawing.Imaging;
using CodeImp.DoomBuilder.Data;
using CodeImp.DoomBuilder.Editing;
using CodeImp.DoomBuilder.IO;
using CodeImp.DoomBuilder.Rendering;
using CodeImp.DoomBuilder.VisualModes;
#endregion
namespace CodeImp.DoomBuilder.BuilderModes
{
internal class VisualMiddle : VisualSidedef
{
#region ================== Constants
#endregion
#region ================== Variables
#endregion
#region ================== Properties
#endregion
#region ================== Constructor / Disposer
// Constructor
public VisualMiddle(Sidedef s) : base(s)
{
WorldVertex[] verts;
float geotop;
float geobottom;
float geoheight;
bool texturegiven;
bool texturerequired;
Vector2D v1, v2;
// Calculate size of this wall part
geotop = (float)s.Sector.CeilHeight;
geobottom = (float)s.Sector.FloorHeight;
geoheight = geotop - geobottom;
if(geoheight > 0.001f)
{
// Check texture status
texturegiven = ((s.MiddleTexture.Length > 0) && (s.MiddleTexture[0] != '-'));
texturerequired = s.MiddleRequired();
// Only create wall when middle texture is set or the wall requires a texture
if(texturegiven || texturerequired)
{
// Texture given?
if(texturegiven)
{
// Load texture
base.Texture = General.Map.Data.GetTextureImage(s.LongMiddleTexture);
if(base.Texture == null) base.Texture = General.Map.Data.MissingTexture3D;
}
else
{
// Use missing texture
base.Texture = General.Map.Data.MissingTexture3D;
}
// Get coordinates
if(s.IsFront)
{
v1 = s.Line.Start.Position;
v2 = s.Line.End.Position;
}
else
{
v1 = s.Line.End.Position;
v2 = s.Line.Start.Position;
}
// Use sector brightness for color shading
PixelColor pc = new PixelColor(255, unchecked((byte)s.Sector.Brightness), unchecked((byte)s.Sector.Brightness), unchecked((byte)s.Sector.Brightness));
// Make vertices
verts = new WorldVertex[6];
verts[0] = new WorldVertex(v1.x, v1.y, geobottom, pc.ToInt(), 0.0f, 1.0f);
verts[1] = new WorldVertex(v1.x, v1.y, geotop, pc.ToInt(), 0.0f, 0.0f);
verts[2] = new WorldVertex(v2.x, v2.y, geotop, pc.ToInt(), 1.0f, 0.0f);
verts[3] = verts[0];
verts[4] = verts[2];
verts[5] = new WorldVertex(v2.x, v2.y, geobottom, pc.ToInt(), 1.0f, 1.0f);
}
else
{
// No geometry for invisible wall
verts = new WorldVertex[0];
}
}
else
{
// No geometry for invisible wall
verts = new WorldVertex[0];
}
// Apply vertices
base.SetVertices(verts);
// We have no destructor
GC.SuppressFinalize(this);
}
#endregion
#region ================== Methods
#endregion
}
}

View file

@ -0,0 +1,164 @@
#region ================== Copyright (c) 2007 Pascal vd Heiden
/*
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
* This program is released under GNU General Public License
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#endregion
#region ================== Namespaces
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using System.Drawing;
using System.ComponentModel;
using CodeImp.DoomBuilder.Map;
using CodeImp.DoomBuilder.Geometry;
using System.Drawing.Imaging;
using CodeImp.DoomBuilder.Data;
using CodeImp.DoomBuilder.Editing;
using CodeImp.DoomBuilder.IO;
using CodeImp.DoomBuilder.Rendering;
using CodeImp.DoomBuilder.VisualModes;
#endregion
namespace CodeImp.DoomBuilder.BuilderModes
{
internal class VisualMiddleDouble : VisualSidedef
{
#region ================== Constants
#endregion
#region ================== Variables
#endregion
#region ================== Properties
#endregion
#region ================== Constructor / Setup
// Constructor
public VisualMiddleDouble(Sidedef s) : base(s)
{
// We have no destructor
GC.SuppressFinalize(this);
}
// This builds the geometry. Returns false when no geometry created.
public bool Setup()
{
// Calculate size of this wall part
float geotop = (float)Math.Min(Sidedef.Sector.CeilHeight, Sidedef.Other.Sector.CeilHeight);
float geobottom = (float)Math.Max(Sidedef.Sector.FloorHeight, Sidedef.Other.Sector.FloorHeight);
float geoheight = geotop - geobottom;
if(geoheight > 0.001f)
{
// Texture given?
if((Sidedef.MiddleTexture.Length > 0) && (Sidedef.MiddleTexture[0] != '-'))
{
Vector2D t1 = new Vector2D();
Vector2D t2 = new Vector2D();
float textop, texbottom;
float cliptop = 0.0f;
float clipbottom = 0.0f;
// Load texture
base.Texture = General.Map.Data.GetTextureImage(Sidedef.LongMiddleTexture);
if(base.Texture == null) base.Texture = General.Map.Data.MissingTexture3D;
// Get texture scaled size
Vector2D tsz = new Vector2D(base.Texture.ScaledWidth, base.Texture.ScaledHeight);
// Because the middle texture on a double sided line does not repeat vertically,
// we first determine the visible portion of the texture
if(Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag))
textop = geobottom + tsz.y;
else
textop = geotop;
// Apply texture offset
textop += Sidedef.OffsetY;
// Calculate texture portion bottom
texbottom = textop - tsz.y;
// Clip texture portion by geometry
if(geotop < textop) { cliptop = textop - geotop; textop = geotop; }
if(geobottom > texbottom) { clipbottom = geobottom - texbottom; texbottom = geobottom; }
// Check if anything is still visible
if((textop - texbottom) > 0.001f)
{
// Determine texture coordinatess
t1.y = cliptop;
t2.y = tsz.y - clipbottom;
t1.x = Sidedef.OffsetX;
t2.x = t1.x + Sidedef.Line.Length;
// Transform pixel coordinates to texture coordinates
t1 /= tsz;
t2 /= tsz;
// Get world coordinates for geometry
Vector2D v1, v2;
if(Sidedef.IsFront)
{
v1 = Sidedef.Line.Start.Position;
v2 = Sidedef.Line.End.Position;
}
else
{
v1 = Sidedef.Line.End.Position;
v2 = Sidedef.Line.Start.Position;
}
// Use sector brightness for color shading
PixelColor pc = new PixelColor(255, unchecked((byte)Sidedef.Sector.Brightness),
unchecked((byte)Sidedef.Sector.Brightness),
unchecked((byte)Sidedef.Sector.Brightness));
// Make vertices
WorldVertex[] verts = new WorldVertex[6];
verts[0] = new WorldVertex(v1.x, v1.y, texbottom, pc.ToInt(), t1.x, t2.y);
verts[1] = new WorldVertex(v1.x, v1.y, textop, pc.ToInt(), t1.x, t1.y);
verts[2] = new WorldVertex(v2.x, v2.y, textop, pc.ToInt(), t2.x, t1.y);
verts[3] = verts[0];
verts[4] = verts[2];
verts[5] = new WorldVertex(v2.x, v2.y, texbottom, pc.ToInt(), t2.x, t2.y);
// Apply vertices
base.SetVertices(verts);
return true;
}
}
}
// No geometry for invisible wall
return false;
}
#endregion
#region ================== Methods
#endregion
}
}

View file

@ -0,0 +1,156 @@
#region ================== Copyright (c) 2007 Pascal vd Heiden
/*
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
* This program is released under GNU General Public License
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#endregion
#region ================== Namespaces
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using System.Drawing;
using System.ComponentModel;
using CodeImp.DoomBuilder.Map;
using CodeImp.DoomBuilder.Geometry;
using System.Drawing.Imaging;
using CodeImp.DoomBuilder.Data;
using CodeImp.DoomBuilder.Editing;
using CodeImp.DoomBuilder.IO;
using CodeImp.DoomBuilder.Rendering;
using CodeImp.DoomBuilder.VisualModes;
#endregion
namespace CodeImp.DoomBuilder.BuilderModes
{
internal class VisualMiddleSingle : VisualSidedef
{
#region ================== Constants
#endregion
#region ================== Variables
#endregion
#region ================== Properties
#endregion
#region ================== Constructor / Setup
// Constructor
public VisualMiddleSingle(Sidedef s) : base(s)
{
// We have no destructor
GC.SuppressFinalize(this);
}
// This builds the geometry. Returns false when no geometry created.
public bool Setup()
{
// Calculate size of this wall part
float geotop = (float)Sidedef.Sector.CeilHeight;
float geobottom = (float)Sidedef.Sector.FloorHeight;
float geoheight = geotop - geobottom;
if(geoheight > 0.001f)
{
Vector2D t1 = new Vector2D();
Vector2D t2 = new Vector2D();
// Texture given?
if((Sidedef.MiddleTexture.Length > 0) && (Sidedef.MiddleTexture[0] != '-'))
{
// Load texture
base.Texture = General.Map.Data.GetTextureImage(Sidedef.LongMiddleTexture);
if(base.Texture == null) base.Texture = General.Map.Data.MissingTexture3D;
}
else
{
// Use missing texture
base.Texture = General.Map.Data.MissingTexture3D;
}
// Get texture scaled size
Vector2D tsz = new Vector2D(base.Texture.ScaledWidth, base.Texture.ScaledHeight);
// Determine texture coordinates
// See http://doom.wikia.com/wiki/Texture_alignment
// We just use pixels for coordinates for now
if(Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag))
{
// When lower unpegged is set, the middle texture is bound to the bottom
t1.y = tsz.y - geoheight;
}
t2.x = t1.x + Sidedef.Line.Length;
t2.y = t1.y + geoheight;
// Apply texture offset
t1 += new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY);
t2 += new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY);
// Transform pixel coordinates to texture coordinates
t1 /= tsz;
t2 /= tsz;
// Get world coordinates for geometry
Vector2D v1, v2;
if(Sidedef.IsFront)
{
v1 = Sidedef.Line.Start.Position;
v2 = Sidedef.Line.End.Position;
}
else
{
v1 = Sidedef.Line.End.Position;
v2 = Sidedef.Line.Start.Position;
}
// Use sector brightness for color shading
PixelColor pc = new PixelColor(255, unchecked((byte)Sidedef.Sector.Brightness),
unchecked((byte)Sidedef.Sector.Brightness),
unchecked((byte)Sidedef.Sector.Brightness));
// Make vertices
WorldVertex[] verts = new WorldVertex[6];
verts[0] = new WorldVertex(v1.x, v1.y, geobottom, pc.ToInt(), t1.x, t2.y);
verts[1] = new WorldVertex(v1.x, v1.y, geotop, pc.ToInt(), t1.x, t1.y);
verts[2] = new WorldVertex(v2.x, v2.y, geotop, pc.ToInt(), t2.x, t1.y);
verts[3] = verts[0];
verts[4] = verts[2];
verts[5] = new WorldVertex(v2.x, v2.y, geobottom, pc.ToInt(), t2.x, t2.y);
// Apply vertices
base.SetVertices(verts);
return true;
}
else
{
// No geometry for invisible wall
return false;
}
}
#endregion
#region ================== Methods
#endregion
}
}

View file

@ -53,28 +53,32 @@ namespace CodeImp.DoomBuilder.BuilderModes
#endregion #endregion
#region ================== Constructor / Disposer #region ================== Constructor / Setup
// Constructor // Constructor
public VisualUpper(Sidedef s) : base(s) public VisualUpper(Sidedef s) : base(s)
{ {
WorldVertex[] verts; // We have no destructor
float geotop; GC.SuppressFinalize(this);
float geobottom; }
float geoheight;
Vector2D v1, v2;
// This builds the geometry. Returns false when no geometry created.
public bool Setup()
{
// Calculate size of this wall part // Calculate size of this wall part
geotop = (float)s.Sector.CeilHeight; float geotop = (float)Sidedef.Sector.CeilHeight;
geobottom = (float)s.Other.Sector.CeilHeight; float geobottom = (float)Sidedef.Other.Sector.CeilHeight;
geoheight = geotop - geobottom; float geoheight = geotop - geobottom;
if(geoheight > 0.001f) if(geoheight > 0.001f)
{ {
Vector2D t1 = new Vector2D();
Vector2D t2 = new Vector2D();
// Texture given? // Texture given?
if((s.HighTexture.Length > 0) && (s.HighTexture[0] != '-')) if((Sidedef.HighTexture.Length > 0) && (Sidedef.HighTexture[0] != '-'))
{ {
// Load texture // Load texture
base.Texture = General.Map.Data.GetTextureImage(s.LongHighTexture); base.Texture = General.Map.Data.GetTextureImage(Sidedef.LongHighTexture);
if(base.Texture == null) base.Texture = General.Map.Data.MissingTexture3D; if(base.Texture == null) base.Texture = General.Map.Data.MissingTexture3D;
} }
else else
@ -83,43 +87,66 @@ namespace CodeImp.DoomBuilder.BuilderModes
base.Texture = General.Map.Data.MissingTexture3D; base.Texture = General.Map.Data.MissingTexture3D;
} }
// Get coordinates // Get texture scaled size
if(s.IsFront) Vector2D tsz = new Vector2D(base.Texture.ScaledWidth, base.Texture.ScaledHeight);
// Determine texture coordinates
// See http://doom.wikia.com/wiki/Texture_alignment
// We just use pixels for coordinates for now
if(!Sidedef.Line.IsFlagSet(General.Map.Config.UpperUnpeggedFlag))
{ {
v1 = s.Line.Start.Position; // When upper unpegged is NOT set, the upper texture is bound to the bottom
v2 = s.Line.End.Position; t1.y = tsz.y - geoheight;
}
t2.x = t1.x + Sidedef.Line.Length;
t2.y = t1.y + geoheight;
// Apply texture offset
t1 += new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY);
t2 += new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY);
// Transform pixel coordinates to texture coordinates
t1 /= tsz;
t2 /= tsz;
// Get world coordinates for geometry
Vector2D v1, v2;
if(Sidedef.IsFront)
{
v1 = Sidedef.Line.Start.Position;
v2 = Sidedef.Line.End.Position;
} }
else else
{ {
v1 = s.Line.End.Position; v1 = Sidedef.Line.End.Position;
v2 = s.Line.Start.Position; v2 = Sidedef.Line.Start.Position;
} }
// Use sector brightness for color shading // Use sector brightness for color shading
PixelColor pc = new PixelColor(255, unchecked((byte)s.Sector.Brightness), unchecked((byte)s.Sector.Brightness), unchecked((byte)s.Sector.Brightness)); PixelColor pc = new PixelColor(255, unchecked((byte)Sidedef.Sector.Brightness),
unchecked((byte)Sidedef.Sector.Brightness),
unchecked((byte)Sidedef.Sector.Brightness));
// Make vertices // Make vertices
verts = new WorldVertex[6]; WorldVertex[] verts = new WorldVertex[6];
verts[0] = new WorldVertex(v1.x, v1.y, geobottom, pc.ToInt(), 0.0f, 1.0f); verts[0] = new WorldVertex(v1.x, v1.y, geobottom, pc.ToInt(), t1.x, t2.y);
verts[1] = new WorldVertex(v1.x, v1.y, geotop, pc.ToInt(), 0.0f, 0.0f); verts[1] = new WorldVertex(v1.x, v1.y, geotop, pc.ToInt(), t1.x, t1.y);
verts[2] = new WorldVertex(v2.x, v2.y, geotop, pc.ToInt(), 1.0f, 0.0f); verts[2] = new WorldVertex(v2.x, v2.y, geotop, pc.ToInt(), t2.x, t1.y);
verts[3] = verts[0]; verts[3] = verts[0];
verts[4] = verts[2]; verts[4] = verts[2];
verts[5] = new WorldVertex(v2.x, v2.y, geobottom, pc.ToInt(), 1.0f, 1.0f); verts[5] = new WorldVertex(v2.x, v2.y, geobottom, pc.ToInt(), t2.x, t2.y);
// Apply vertices
base.SetVertices(verts);
return true;
} }
else else
{ {
// No geometry for invisible wall // No geometry for invisible wall
verts = new WorldVertex[0]; return false;
} }
// Apply vertices
base.SetVertices(verts);
// We have no destructor
GC.SuppressFinalize(this);
} }
#endregion #endregion
#region ================== Methods #region ================== Methods