Merged in GZDB r2469.

This commit is contained in:
MascaraSnake 2016-01-23 02:50:13 +01:00
parent 2cb8570eec
commit b524dd8277
10 changed files with 257 additions and 120 deletions

View file

@ -711,6 +711,7 @@
<None Include="Resources\ZoneBuilder.bmp" /> <None Include="Resources\ZoneBuilder.bmp" />
<None Include="app.manifest" /> <None Include="app.manifest" />
<None Include="Resources\ScriptSnippet.xpm" /> <None Include="Resources\ScriptSnippet.xpm" />
<EmbeddedResource Include="Resources\SkySphere.md3" />
<None Include="Resources\ThingStatistics.png" /> <None Include="Resources\ThingStatistics.png" />
<None Include="Resources\Copy.png" /> <None Include="Resources\Copy.png" />
<None Include="Resources\Cut.png" /> <None Include="Resources\Cut.png" />

View file

@ -28,12 +28,15 @@ using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.GZBuilder.Data; using CodeImp.DoomBuilder.GZBuilder.Data;
using CodeImp.DoomBuilder.GZBuilder.GZDoom; using CodeImp.DoomBuilder.GZBuilder.GZDoom;
using CodeImp.DoomBuilder.GZBuilder.MD3; using CodeImp.DoomBuilder.GZBuilder.MD3;
using CodeImp.DoomBuilder.Geometry;
using CodeImp.DoomBuilder.IO; using CodeImp.DoomBuilder.IO;
using CodeImp.DoomBuilder.Map; using CodeImp.DoomBuilder.Map;
using CodeImp.DoomBuilder.Rendering;
using CodeImp.DoomBuilder.Windows; using CodeImp.DoomBuilder.Windows;
using CodeImp.DoomBuilder.ZDoom; using CodeImp.DoomBuilder.ZDoom;
using SlimDX; using SlimDX;
using SlimDX.Direct3D9; using SlimDX.Direct3D9;
using Matrix = SlimDX.Matrix;
#endregion #endregion
@ -496,9 +499,6 @@ namespace CodeImp.DoomBuilder.Data
alltextures.AddFlat(img.Value); alltextures.AddFlat(img.Value);
} }
//mxd. Create skybox texture(s)
SetupSkybox();
// Start background loading // Start background loading
StartBackgroundLoader(); StartBackgroundLoader();
@ -1853,9 +1853,6 @@ namespace CodeImp.DoomBuilder.Data
foreach(Thing t in General.Map.Map.Things) t.UpdateCache(); foreach(Thing t in General.Map.Map.Things) t.UpdateCache();
// Rebuild skybox texture
SetupSkybox();
// Rebuild geometry if in Visual mode // Rebuild geometry if in Visual mode
if (General.Editing.Mode != null && General.Editing.Mode.GetType().Name == "BaseVisualMode") if (General.Editing.Mode != null && General.Editing.Mode.GetType().Name == "BaseVisualMode")
{ {
@ -1884,8 +1881,12 @@ namespace CodeImp.DoomBuilder.Data
return; return;
} }
//rebuild geometry if in Visual mode // Reset skybox texture
if(General.Editing.Mode != null && General.Editing.Mode.GetType().Name == "BaseVisualMode") skybox.Dispose();
skybox = null;
// Rebuild geometry if in Visual mode
if (General.Editing.Mode != null && General.Editing.Mode.GetType().Name == "BaseVisualMode")
{ {
General.Editing.Mode.OnReloadResources(); General.Editing.Mode.OnReloadResources();
} }
@ -2361,6 +2362,10 @@ namespace CodeImp.DoomBuilder.Data
#endregion #endregion
#region ================== mxd. Skybox Making #region ================== mxd. Skybox Making
internal void UpdateSkybox()
{
if (skybox == null) SetupSkybox();
}
private void SetupSkybox() private void SetupSkybox()
{ {
@ -2396,7 +2401,7 @@ namespace CodeImp.DoomBuilder.Data
Bitmap img = GetTextureBitmap(skytex); Bitmap img = GetTextureBitmap(skytex);
if (img != null) if (img != null)
{ {
skybox = MakeClassicSkyBox(img, true); skybox = MakeClassicSkyBox(img);
} }
} }
} }
@ -2406,137 +2411,186 @@ namespace CodeImp.DoomBuilder.Data
{ {
ImageData tex = LoadInternalTexture("MissingSky3D.png"); ImageData tex = LoadInternalTexture("MissingSky3D.png");
tex.CreateTexture(); tex.CreateTexture();
skybox = MakeClassicSkyBox(new Bitmap(tex.GetBitmap()), false); skybox = MakeClassicSkyBox(new Bitmap(tex.GetBitmap()));
tex.Dispose(); tex.Dispose();
} }
} }
private static CubeTexture MakeClassicSkyBox(Bitmap img, bool dogradients) //INFO: 1. Looks like GZDoom tries to tile a sky texture into a 1024 pixel width texture.
//INFO: 2. If sky texture width <= height, it will be tiled to fit into 512 pixel height texture vertically.
private static CubeTexture MakeClassicSkyBox(Bitmap img)
{ {
// CubeTexture must be square with power of 2 sides // Get averaged top and bottom colors from the original image
int targetwidth = General.NextPowerOf2(img.Width); int tr = 0, tg = 0, tb = 0, br = 0, bg = 0, bb = 0;
int targetheight = General.NextPowerOf2(img.Height); const int colorsampleheight = 28; // TODO: is this value calculated from the image's height?
for (int w = 0; w < img.Width; w++)
// Get averaged top and bottom colors
Color topcolor, bottomcolor;
if (dogradients)
{ {
int tr = 0, tg = 0, tb = 0, br = 0, bg = 0, bb = 0; for (int h = 0; h < colorsampleheight; h++)
for (int i = 0; i < img.Width; i++)
{ {
Color c = img.GetPixel(i, 0); Color c = img.GetPixel(w, h);
tr += c.R; tr += c.R;
tg += c.G; tg += c.G;
tb += c.B; tb += c.B;
c = img.GetPixel(i, img.Height - 1); c = img.GetPixel(w, img.Height - 1 - h);
br += c.R; br += c.R;
bg += c.G; bg += c.G;
bb += c.B; bb += c.B;
} }
topcolor = Color.FromArgb(255, tr / img.Width, tg / img.Width, tb / img.Width);
bottomcolor = Color.FromArgb(255, br / img.Width, bg / img.Width, bb / img.Width);
}
else
{
// This should be built-in sky texture
Color c = img.GetPixel(img.Width / 2, 0);
topcolor = Color.FromArgb(255, c);
c = img.GetPixel(img.Width / 2, img.Height - 1);
bottomcolor = Color.FromArgb(255, c);
} }
// Make it Po2 int pixelscount = img.Width * colorsampleheight;
if (img.Width != targetwidth || img.Height != targetheight) img = ResizeImage(img, targetwidth, targetheight); Color topcolor = Color.FromArgb(255, tr / pixelscount, tg / pixelscount, tb / pixelscount);
Color bottomcolor = Color.FromArgb(255, br / pixelscount, bg / pixelscount, bb / pixelscount);
// Make it square // Make tiling image
if (targetwidth > targetheight) int horiztiles = (int)Math.Ceiling(1024.0f / img.Width);
int verttiles = img.Height > 256 ? 1 : 2;
Bitmap skyimage = new Bitmap(1024, img.Height * verttiles, img.PixelFormat);
// Draw original image
using (Graphics g = Graphics.FromImage(skyimage))
{ {
int c = targetwidth / targetheight; for (int w = 0; w < horiztiles; w++)
Bitmap result = new Bitmap(targetwidth, targetwidth, img.PixelFormat);
// Tile vertically
using (Graphics g = Graphics.FromImage(result))
{ {
for (int i = 0; i < c; i++) g.DrawImage(img, 0, targetheight * i); for (int h = 0; h < verttiles; h++)
{
g.DrawImage(img, img.Width * w, img.Height * h);
}
} }
img = result;
}
else if (targetwidth < targetheight)
{
int c = targetheight / targetwidth;
Bitmap result = new Bitmap(targetheight, targetheight);
// Tile horizontally
using (Graphics g = Graphics.FromImage(result))
{
for (int i = 0; i < c; i++) g.DrawImage(img, targetwidth * i, 0);
}
img = result;
} }
// Make top and bottom images // Make top and bottom images
Bitmap top = new Bitmap(img.Width, img.Height); const int capsimgsize = 16;
using (Graphics g = Graphics.FromImage(top)) Bitmap topimg = new Bitmap(capsimgsize, capsimgsize);
using (Graphics g = Graphics.FromImage(topimg))
{ {
using (SolidBrush b = new SolidBrush(topcolor)) using (SolidBrush b = new SolidBrush(topcolor))
{ g.FillRectangle(b, 0, 0, capsimgsize, capsimgsize);
g.FillRectangle(b, 0, 0, img.Width, img.Height);
}
} }
Bitmap bottom = new Bitmap(img.Width, img.Height); Bitmap bottomimg = new Bitmap(capsimgsize, capsimgsize);
using (Graphics g = Graphics.FromImage(bottom)) using (Graphics g = Graphics.FromImage(bottomimg))
{ {
using (SolidBrush b = new SolidBrush(bottomcolor)) using (SolidBrush b = new SolidBrush(bottomcolor))
{ g.FillRectangle(b, 0, 0, capsimgsize, capsimgsize);
g.FillRectangle(b, 0, 0, img.Width, img.Height);
}
} }
// Apply top/bottom gradients // Apply top/bottom gradients
if (dogradients) using (Graphics g = Graphics.FromImage(skyimage))
{ {
using (Graphics g = Graphics.FromImage(img)) Rectangle area = new Rectangle(0, 0, skyimage.Width, colorsampleheight);
using (LinearGradientBrush b = new LinearGradientBrush(area, topcolor, Color.FromArgb(0, topcolor), 90f))
{ {
int gradientheight = img.Height / 6; g.FillRectangle(b, area);
Rectangle area = new Rectangle(0, 0, img.Width, gradientheight); }
using (LinearGradientBrush b = new LinearGradientBrush(area, topcolor, Color.FromArgb(0, topcolor), 90f))
{
g.FillRectangle(b, area);
}
area = new Rectangle(0, img.Height - gradientheight, img.Width, gradientheight); area = new Rectangle(0, skyimage.Height - colorsampleheight, skyimage.Width, colorsampleheight);
using (LinearGradientBrush b = new LinearGradientBrush(area, Color.FromArgb(0, bottomcolor), bottomcolor, 90f)) using (LinearGradientBrush b = new LinearGradientBrush(area, Color.FromArgb(0, bottomcolor), bottomcolor, 90f))
{ {
area.Y += 1; area.Y += 1;
g.FillRectangle(b, area); g.FillRectangle(b, area);
}
} }
} }
// Load the skysphere model...
Device device = General.Map.Graphics.Device;
World3DShader effect = General.Map.Graphics.Shaders.World3D;
BoundingBoxSizes bbs = new BoundingBoxSizes();
Stream modeldata = General.ThisAssembly.GetManifestResourceStream("CodeImp.DoomBuilder.Resources.SkySphere.md3");
ModelReader.MD3LoadResult result = ModelReader.ReadMD3Model(ref bbs, true, modeldata, device, 0);
if (result.Meshes.Count != 3) throw new Exception("Skybox creation failed: " + result.Errors);
// Make skysphere textures...
Texture texside = TextureFromBitmap(device, skyimage);
Texture textop = TextureFromBitmap(device, topimg);
Texture texbottom = TextureFromBitmap(device, bottomimg);
// Calculate model scaling (gl.skydone.cpp:RenderDome() in GZDoom)
float yscale;
if (img.Height < 128) yscale = 128 / 230.0f;
else if (img.Height < 200) yscale = img.Height / 230.0f;
else if (img.Height < 241) yscale = 1.0f + ((img.Height - 200.0f) / 200.0f) * 1.17f;
else yscale = 1.2f * 1.17f;
// Make cubemap texture // Make cubemap texture
CubeTexture cubemap = new CubeTexture(General.Map.Graphics.Device, img.Width, 1, Usage.None, Format.A8R8G8B8, Pool.Managed); const int cubemaptexsize = 1024;
CubeTexture cubemap = new CubeTexture(device, cubemaptexsize, 1, Usage.RenderTarget, Format.A8R8G8B8, Pool.Default);
// Draw faces // Set render settings...
img.RotateFlip(RotateFlipType.Rotate180FlipX); device.SetRenderState(RenderState.ZEnable, false);
DrawCubemapFace(cubemap, CubeMapFace.NegativeX, img); device.SetRenderState(RenderState.CullMode, Cull.None);
img.RotateFlip(RotateFlipType.Rotate90FlipNone); // Make custom rendertarget
DrawCubemapFace(cubemap, CubeMapFace.NegativeY, img); Surface rendertarget = Surface.CreateRenderTarget(device, cubemaptexsize, cubemaptexsize, Format.A8R8G8B8, MultisampleType.None, 0, false);
img.RotateFlip(RotateFlipType.Rotate90FlipNone); // Setup matrices
DrawCubemapFace(cubemap, CubeMapFace.PositiveX, img); Vector3 offset = new Vector3(0f, 0f, -1.8f); // Sphere size is 10 mu
Matrix mworld = Matrix.Multiply(Matrix.Identity, Matrix.Translation(offset) * Matrix.Scaling(1.0f, 1.0f, yscale));
Matrix mprojection = Matrix.PerspectiveFovLH(Angle2D.PIHALF, 1.0f, 0.5f, 100.0f);
img.RotateFlip(RotateFlipType.Rotate90FlipNone); // Place camera at origin
DrawCubemapFace(cubemap, CubeMapFace.PositiveY, img); effect.CameraPosition = new Vector4();
DrawCubemapFace(cubemap, CubeMapFace.PositiveZ, top); // Set the rendertarget to our own RT surface
DrawCubemapFace(cubemap, CubeMapFace.NegativeZ, bottom); device.SetRenderTarget(0, rendertarget);
// Set custom depth stencil
device.DepthStencilSurface = Surface.CreateDepthStencil(device, cubemaptexsize, cubemaptexsize, General.Map.Graphics.DepthBuffer.Description.Format, MultisampleType.None, 0, false);
// Begin rendering
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.DarkRed, 1.0f, 0);
device.BeginScene();
effect.Begin();
effect.BeginPass(1); // Fullbright pass
// Render to the six faces of the cube map
for (int i = 0; i < 6; i++)
{
Matrix faceview = GetCubeMapViewMatrix((CubeMapFace)i);
effect.WorldViewProj = mworld * faceview * mprojection;
// Render the skysphere meshes
for (int j = 0; j < result.Meshes.Count; j++)
{
// Set appropriate texture
switch (result.Skins[j])
{
case "top.png": effect.Texture1 = textop; break;
case "bottom.png": effect.Texture1 = texbottom; break;
case "side.png": effect.Texture1 = texside; break;
default: throw new Exception("Unexpected skin!");
}
// Commit changes
effect.ApplySettings();
// Render mesh
result.Meshes[j].DrawSubset(0);
}
// Copy the rendered image from our RT surface to the texture face
Surface cubeface = cubemap.GetCubeMapSurface((CubeMapFace)i, 0);
device.StretchRectangle(rendertarget, cubeface, TextureFilter.None);
cubeface.Dispose();
}
// End rendering
effect.EndPass();
effect.End();
device.EndScene();
// Dispose unneeded stuff
rendertarget.Dispose();
textop.Dispose();
texside.Dispose();
texbottom.Dispose();
// Dispose skybox meshes
foreach (Mesh m in result.Meshes) m.Dispose();
// All done... // All done...
return cubemap; return cubemap;
@ -2757,6 +2811,62 @@ namespace CodeImp.DoomBuilder.Data
return destimage; return destimage;
} }
private static Matrix GetCubeMapViewMatrix(CubeMapFace face)
{
Vector3 lookdir, updir;
switch (face)
{
case CubeMapFace.PositiveX:
lookdir = new Vector3(1.0f, 0.0f, 0.0f);
updir = new Vector3(0.0f, 1.0f, 0.0f);
break;
case CubeMapFace.NegativeX:
lookdir = new Vector3(-1.0f, 0.0f, 0.0f);
updir = new Vector3(0.0f, 1.0f, 0.0f);
break;
case CubeMapFace.PositiveY:
lookdir = new Vector3(0.0f, 1.0f, 0.0f);
updir = new Vector3(0.0f, 0.0f, -1.0f);
break;
case CubeMapFace.NegativeY:
lookdir = new Vector3(0.0f, -1.0f, 0.0f);
updir = new Vector3(0.0f, 0.0f, 1.0f);
break;
case CubeMapFace.PositiveZ:
lookdir = new Vector3(0.0f, 0.0f, 1.0f);
updir = new Vector3(0.0f, 1.0f, 0.0f);
break;
case CubeMapFace.NegativeZ:
lookdir = new Vector3(0.0f, 0.0f, -1.0f);
updir = new Vector3(0.0f, 1.0f, 0.0f);
break;
default:
throw new Exception("Unknown CubeMapFace!");
}
Vector3 eye = new Vector3();
return Matrix.LookAtLH(eye, lookdir, updir);
}
private static Texture TextureFromBitmap(Device device, Image image)
{
MemoryStream ms = new MemoryStream();
image.Save(ms, ImageFormat.Png);
ms.Seek(0, SeekOrigin.Begin);
Texture result = Texture.FromStream(device, ms);
ms.Close();
ms.Dispose();
return result;
}
#endregion #endregion
} }
} }

View file

@ -21,9 +21,9 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
{ {
internal static class ModelReader internal static class ModelReader
{ {
#region ================== Variables #region ================== Variables
private class MD3LoadResult internal class MD3LoadResult
{ {
public List<string> Skins; public List<string> Skins;
public List<Mesh> Meshes; public List<Mesh> Meshes;
@ -228,12 +228,12 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
mde.Model.Radius = Math.Max(Math.Max(Math.Abs(bbs.MinY), Math.Abs(bbs.MaxY)), Math.Max(Math.Abs(bbs.MinX), Math.Abs(bbs.MaxX))); mde.Model.Radius = Math.Max(Math.Max(Math.Abs(bbs.MinY), Math.Abs(bbs.MaxY)), Math.Max(Math.Abs(bbs.MinX), Math.Abs(bbs.MaxX)));
} }
#endregion #endregion
#region ================== MD3 #region ================== MD3
private static MD3LoadResult ReadMD3Model(ref BoundingBoxSizes bbs, bool useSkins, MemoryStream s, Device device, int frame) internal static MD3LoadResult ReadMD3Model(ref BoundingBoxSizes bbs, bool useSkins, Stream s, Device device, int frame)
{ {
long start = s.Position; long start = s.Position;
MD3LoadResult result = new MD3LoadResult(); MD3LoadResult result = new MD3LoadResult();
@ -419,12 +419,12 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
return ""; return "";
} }
#endregion #endregion
#region ================== MD2 #region ================== MD2
private static MD3LoadResult ReadMD2Model(ref BoundingBoxSizes bbs, MemoryStream s, Device device, int frame, string framename) private static MD3LoadResult ReadMD2Model(ref BoundingBoxSizes bbs, Stream s, Device device, int frame, string framename)
{ {
long start = s.Position; long start = s.Position;
MD3LoadResult result = new MD3LoadResult(); MD3LoadResult result = new MD3LoadResult();

View file

@ -551,8 +551,14 @@ namespace CodeImp.DoomBuilder.Geometry
newsector.Brightness = General.Settings.DefaultBrightness; newsector.Brightness = General.Settings.DefaultBrightness;
} }
//mxd. Apply overrides? //mxd. Better any height than none
if(useOverrides) if (newsector.CeilHeight - newsector.FloorHeight <= 0)
{
newsector.CeilHeight = newsector.FloorHeight + (General.Settings.DefaultCeilingHeight - General.Settings.DefaultFloorHeight);
}
//mxd. Apply overrides?
if (useOverrides)
{ {
if(General.Map.Options.OverrideCeilingTexture) newsector.SetCeilTexture(General.Map.Options.DefaultCeilingTexture); if(General.Map.Options.OverrideCeilingTexture) newsector.SetCeilTexture(General.Map.Options.DefaultCeilingTexture);
if(General.Map.Options.OverrideFloorTexture) newsector.SetFloorTexture(General.Map.Options.DefaultFloorTexture); if(General.Map.Options.OverrideFloorTexture) newsector.SetFloorTexture(General.Map.Options.DefaultFloorTexture);

View file

@ -1180,15 +1180,26 @@ namespace CodeImp.DoomBuilder.Properties {
} }
} }
internal static System.Drawing.Bitmap Sky /// <summary>
{ /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
get /// </summary>
{ internal static System.Drawing.Bitmap Sky {
get {
object obj = ResourceManager.GetObject("Sky", resourceCulture); object obj = ResourceManager.GetObject("Sky", resourceCulture);
return ((System.Drawing.Bitmap)(obj)); return ((System.Drawing.Bitmap)(obj));
} }
} }
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
/// </summary>
internal static byte[] SkySphere {
get {
object obj = ResourceManager.GetObject("SkySphere", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary> /// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
/// </summary> /// </summary>

View file

@ -547,6 +547,9 @@
<data name="Sky" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="Sky" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Sky.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <value>..\Resources\Sky.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data> </data>
<data name="SkySphere" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\SkySphere.md3;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="zonebuilder" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="zonebuilder" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\zonebuilder.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <value>..\Resources\zonebuilder.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data> </data>

Binary file not shown.

View file

@ -84,7 +84,7 @@ namespace CodeImp.DoomBuilder.VisualModes
// Internal properties // Internal properties
public WorldVertex[] Vertices { get { return vertices; } } //mxd public WorldVertex[] Vertices { get { return vertices; } } //mxd
internal int VertexOffset { get { return vertexoffset; } set { vertexoffset = value; } } internal int VertexOffset { get { return vertexoffset; } set { vertexoffset = value; } }
internal int Triangles { get { return triangles; } } public int Triangles { get { return triangles; } }
//mxd //mxd
public Vector3D[] BoundingBox { get { return boundingBox; } } public Vector3D[] BoundingBox { get { return boundingBox; } }

View file

@ -158,8 +158,11 @@ namespace CodeImp.DoomBuilder.VisualModes
{ {
base.OnEngage(); base.OnEngage();
// Update projection (mxd) //mxd. Sky texture may need recreating
General.Map.CRenderer3D.CreateProjection(); General.Map.Data.UpdateSkybox();
// Update projection (mxd)
General.Map.CRenderer3D.CreateProjection();
// Update the used textures // Update the used textures
General.Map.Data.UpdateUsedTextures(); General.Map.Data.UpdateUsedTextures();
@ -878,8 +881,11 @@ namespace CodeImp.DoomBuilder.VisualModes
// Make new blockmap // Make new blockmap
FillBlockMap(); FillBlockMap();
// Visibility culling (this re-creates the needed resources) //mxd. Sky texture may need recreating
DoCulling(); General.Map.Data.UpdateSkybox();
// Visibility culling (this re-creates the needed resources)
DoCulling();
} }
/// <summary> /// <summary>

View file

@ -531,9 +531,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd //mxd
protected void SelectNeighbours(long longtexture, bool select, bool withSameTexture, bool withSameHeight) protected void SelectNeighbours(long longtexture, bool select, bool withSameTexture, bool withSameHeight)
{ {
if(Sidedef.Sector == null || (!withSameTexture && !withSameHeight)) return; if (Sidedef.Sector == null || Triangles < 1 || (!withSameTexture && !withSameHeight)) return;
Rectangle rect = BuilderModesTools.GetSidedefPartSize(this); Rectangle rect = BuilderModesTools.GetSidedefPartSize(this);
if(rect.Height == 0) return; if(rect.Height == 0) return;
if(select && !selected) if(select && !selected)