From dcf899a3c46c311c9a6338bf14c8ef2ca6a85eb4 Mon Sep 17 00:00:00 2001 From: MaxED Date: Mon, 23 Apr 2012 21:35:48 +0000 Subject: [PATCH] GZDoomBuilder 1.03: Increased dynamic lights rendering performance (currently I'm getting around 25 FPS in Spawn's MAP01 with 32 dynamic lights and rendering distance set to 3000, was getting 4-6 FPS in GZDoomBuilder 1.02). Several fixes in animated lights rendering (secondary light radius can now be smaller than primary light radius, Pulse Light's maximum radius was rendered twise bigger than in GZDoom). --- Source/Core/Builder.csproj | 5 +- Source/Core/Config/ProgramConfiguration.cs | 2 +- Source/Core/GZBuilder/Data/BoundingBox.cs | 97 +++++++++++ Source/Core/GZBuilder/GZGeneral.cs | 2 +- .../Core/GZBuilder/md3/MD3FormatException.cs | 14 -- Source/Core/GZBuilder/md3/ModelReader.cs | 20 +-- Source/Core/Geometry/ProjectedFrustum2D.cs | 9 ++ Source/Core/Rendering/Renderer3D.cs | 151 +++++++++++------- Source/Core/Resources/Splash3_trans.png | Bin 177330 -> 177332 bytes Source/Core/VisualModes/VisualGeometry.cs | 17 +- Source/Core/VisualModes/VisualThing.cs | 39 +++-- 11 files changed, 243 insertions(+), 113 deletions(-) create mode 100644 Source/Core/GZBuilder/Data/BoundingBox.cs delete mode 100644 Source/Core/GZBuilder/md3/MD3FormatException.cs diff --git a/Source/Core/Builder.csproj b/Source/Core/Builder.csproj index 4dd309df..21271f52 100644 --- a/Source/Core/Builder.csproj +++ b/Source/Core/Builder.csproj @@ -507,9 +507,11 @@ 3.5 + + False @@ -703,15 +705,14 @@ + - - Form diff --git a/Source/Core/Config/ProgramConfiguration.cs b/Source/Core/Config/ProgramConfiguration.cs index cb32e1c6..e7504669 100644 --- a/Source/Core/Config/ProgramConfiguration.cs +++ b/Source/Core/Config/ProgramConfiguration.cs @@ -137,7 +137,7 @@ namespace CodeImp.DoomBuilder.Config public bool VisualBilinear { get { return visualbilinear; } internal set { visualbilinear = value; } } public int MouseSpeed { get { return mousespeed; } internal set { mousespeed = value; } } public int MoveSpeed { get { return movespeed; } internal set { movespeed = value; } } - public float ViewDistance { get { return viewdistance; } internal set { viewdistance = value; } } + public float ViewDistance { get { return viewdistance; } internal set { viewdistance = value; } } public bool InvertYAxis { get { return invertyaxis; } internal set { invertyaxis = value; } } public string ScriptFontName { get { return scriptfontname; } internal set { scriptfontname = value; } } public int ScriptFontSize { get { return scriptfontsize; } internal set { scriptfontsize = value; } } diff --git a/Source/Core/GZBuilder/Data/BoundingBox.cs b/Source/Core/GZBuilder/Data/BoundingBox.cs new file mode 100644 index 00000000..ff3af870 --- /dev/null +++ b/Source/Core/GZBuilder/Data/BoundingBox.cs @@ -0,0 +1,97 @@ +using CodeImp.DoomBuilder.Rendering; +using SlimDX; + +namespace CodeImp.DoomBuilder.GZBuilder.Data +{ + public struct BoundingBoxSizes + { + public short MinX; + public short MaxX; + public short MinY; + public short MaxY; + public short MinZ; + public short MaxZ; + + //we need some reference here + public BoundingBoxSizes(WorldVertex v) { + MinX = MaxX = (short)v.x; + MinY = MaxY = (short)v.y; + MinZ = MaxZ = (short)v.z; + } + } + + public class BoundingBoxTools + { + //this creates array of vectors resembling bounding box + public static Vector3[] CalculateBoundingBox(BoundingBoxSizes bbs) { + //center + Vector3 v0 = new Vector3(bbs.MinX + (bbs.MaxX - bbs.MinX) / 2, bbs.MinY + (bbs.MaxY - bbs.MinY) / 2, bbs.MinZ + (bbs.MaxZ - bbs.MinZ) / 2); + + //corners + Vector3 v1 = new Vector3(bbs.MinX, bbs.MinY, bbs.MinZ); + Vector3 v2 = new Vector3(bbs.MaxX, bbs.MinY, bbs.MinZ); + Vector3 v3 = new Vector3(bbs.MinX, bbs.MaxY, bbs.MinZ); + Vector3 v4 = new Vector3(bbs.MaxX, bbs.MaxY, bbs.MinZ); + Vector3 v5 = new Vector3(bbs.MinX, bbs.MinY, bbs.MaxZ); + Vector3 v6 = new Vector3(bbs.MaxX, bbs.MinY, bbs.MaxZ); + Vector3 v7 = new Vector3(bbs.MinX, bbs.MaxY, bbs.MaxZ); + Vector3 v8 = new Vector3(bbs.MaxX, bbs.MaxY, bbs.MaxZ); + + return new Vector3[] { v0, v1, v2, v3, v4, v5, v6, v7, v8 }; + } + + public static Vector3[] CalculateBoundingPlane(BoundingBoxSizes bbs) { + //mxd. looks like I need only these 2 points, so... + //center + Vector3 v0 = new Vector3(bbs.MinX + (bbs.MaxX - bbs.MinX) / 2, bbs.MinY + (bbs.MaxY - bbs.MinY) / 2, bbs.MinZ + (bbs.MaxZ - bbs.MinZ) / 2); + Vector3 v1 = new Vector3(bbs.MinX, bbs.MinY, bbs.MinZ); + return new Vector3[] { v0, v1 }; + } + + /*public static Vector3[] CalculateBoundingPlane(BoundingBoxSizes bbs) { + if(bbs.MinX != bbs.MaxX && bbs.MinY != bbs.MaxY && bbs.MinZ != bbs.MaxZ) + return CalculateBoundingBox(bbs); + + //center + Vector3 v0 = new Vector3(bbs.MinX + (bbs.MaxX - bbs.MinX) / 2, bbs.MinY + (bbs.MaxY - bbs.MinY) / 2, bbs.MinZ + (bbs.MaxZ - bbs.MinZ) / 2); + Vector3 v1, v2, v3, v4; + + //corners + if (bbs.MinX == bbs.MaxX) { + v1 = new Vector3(bbs.MinX, bbs.MinY, bbs.MinZ); + v2 = new Vector3(bbs.MinX, bbs.MaxY, bbs.MinZ); + v3 = new Vector3(bbs.MinX, bbs.MinY, bbs.MaxZ); + v4 = new Vector3(bbs.MinX, bbs.MaxY, bbs.MaxZ); + } else if (bbs.MinY == bbs.MaxY) { + v1 = new Vector3(bbs.MinX, bbs.MinY, bbs.MinZ); + v2 = new Vector3(bbs.MaxX, bbs.MinY, bbs.MinZ); + v3 = new Vector3(bbs.MinX, bbs.MinY, bbs.MaxZ); + v4 = new Vector3(bbs.MaxX, bbs.MinY, bbs.MaxZ); + } else { + v1 = new Vector3(bbs.MinX, bbs.MinY, bbs.MinZ); + v2 = new Vector3(bbs.MaxX, bbs.MinY, bbs.MinZ); + v3 = new Vector3(bbs.MinX, bbs.MaxY, bbs.MinZ); + v4 = new Vector3(bbs.MaxX, bbs.MaxY, bbs.MinZ); + } + + return new Vector3[] { v0, v1, v2, v3, v4 }; + }*/ + + public static void UpdateBoundingBoxSizes(ref BoundingBoxSizes bbs, WorldVertex v) { + if (v.x < bbs.MinX) + bbs.MinX = (short)v.x; + else if (v.x > bbs.MaxX) + bbs.MaxX = (short)v.x; + + if (v.z < bbs.MinZ) + bbs.MinZ = (short)v.z; + else if (v.z > bbs.MaxZ) + bbs.MaxZ = (short)v.z; + + if (v.y < bbs.MinY) + bbs.MinY = (short)v.y; + else if (v.y > bbs.MaxY) + bbs.MaxY = (short)v.y; + } + } +} diff --git a/Source/Core/GZBuilder/GZGeneral.cs b/Source/Core/GZBuilder/GZGeneral.cs index c94b4db4..3a7ab838 100644 --- a/Source/Core/GZBuilder/GZGeneral.cs +++ b/Source/Core/GZBuilder/GZGeneral.cs @@ -30,7 +30,7 @@ namespace CodeImp.DoomBuilder.GZBuilder public static int[] GZ_LIGHT_TYPES { get { return gz_lightTypes; } } //version - public const string Version = "1.02"; + public const string Version = "1.03"; //debug form #if DEBUG diff --git a/Source/Core/GZBuilder/md3/MD3FormatException.cs b/Source/Core/GZBuilder/md3/MD3FormatException.cs deleted file mode 100644 index 3cf998c6..00000000 --- a/Source/Core/GZBuilder/md3/MD3FormatException.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; - -namespace ColladaDotNet.Pipeline.MD3 { - public class MD3FormatException : ApplicationException { - public MD3FormatException(string message) - : base(message) { - - } - public MD3FormatException(string message, Exception ex) - : base(message, ex) { - - } - } -} \ No newline at end of file diff --git a/Source/Core/GZBuilder/md3/ModelReader.cs b/Source/Core/GZBuilder/md3/ModelReader.cs index f9521a74..ef87e062 100644 --- a/Source/Core/GZBuilder/md3/ModelReader.cs +++ b/Source/Core/GZBuilder/md3/ModelReader.cs @@ -63,7 +63,7 @@ namespace ColladaDotNet.Pipeline.MD3 { if (model.NUM_MESHES <= 0) return null; - model.BoundingBox = CalculateBoundingBox(bbs); + model.BoundingBox = BoundingBoxTools.CalculateBoundingBox(bbs); return model; } @@ -173,7 +173,7 @@ namespace ColladaDotNet.Pipeline.MD3 { v.z = (float)br.ReadInt16() / 64 * mde.Scale.Z + mde.zOffset; //bounding box - UpdateBoundingBoxSizes(ref bbs, v); + BoundingBoxTools.UpdateBoundingBoxSizes(ref bbs, v); var lat = br.ReadByte() * (2 * Math.PI) / 255.0; var lng = br.ReadByte() * (2 * Math.PI) / 255.0; @@ -278,7 +278,7 @@ namespace ColladaDotNet.Pipeline.MD3 { WorldVertex v = vertList[polyIndecesList[i]]; //bounding box - UpdateBoundingBoxSizes(ref bbs, v); + BoundingBoxTools.UpdateBoundingBoxSizes(ref bbs, v); //uv v.u = uvCoordsList[uvIndecesList[i]].X; @@ -337,7 +337,7 @@ namespace ColladaDotNet.Pipeline.MD3 { } //this creates array of vectors resembling bounding box - private static Vector3[] CalculateBoundingBox(BoundingBoxSizes bbs) { + /*private static Vector3[] CalculateBoundingBox(BoundingBoxSizes bbs) { //center Vector3 v0 = new Vector3(bbs.MinX + (bbs.MaxX - bbs.MinX) / 2, bbs.MinY + (bbs.MaxY - bbs.MinY) / 2, bbs.MinZ + (bbs.MaxZ - bbs.MinZ) / 2); @@ -369,7 +369,7 @@ namespace ColladaDotNet.Pipeline.MD3 { bbs.MinY = (short)v.y; else if (v.y > bbs.MaxY) bbs.MaxY = (short)v.y; - } + }*/ private static string ReadString(BinaryReader br, int len) { var NAME = string.Empty; @@ -388,14 +388,4 @@ namespace ColladaDotNet.Pipeline.MD3 { return NAME; } } -} - -struct BoundingBoxSizes -{ - public short MinX; - public short MaxX; - public short MinY; - public short MaxY; - public short MinZ; - public short MaxZ; } \ No newline at end of file diff --git a/Source/Core/Geometry/ProjectedFrustum2D.cs b/Source/Core/Geometry/ProjectedFrustum2D.cs index 15def71b..3b3662d9 100644 --- a/Source/Core/Geometry/ProjectedFrustum2D.cs +++ b/Source/Core/Geometry/ProjectedFrustum2D.cs @@ -151,6 +151,15 @@ namespace CodeImp.DoomBuilder.Geometry return true; } + //mxd + public bool IntersectPoint(Vector2D point) { + for (int i = 0; i < lines.Length; i++) { + if (lines[i].GetSideOfLine(point) < 0) + return false; + } + return true; + } + #endregion } } diff --git a/Source/Core/Rendering/Renderer3D.cs b/Source/Core/Rendering/Renderer3D.cs index 04f85440..d06abc12 100644 --- a/Source/Core/Rendering/Renderer3D.cs +++ b/Source/Core/Rendering/Renderer3D.cs @@ -83,7 +83,9 @@ namespace CodeImp.DoomBuilder.Rendering private Dictionary> litGeometry; private Dictionary> thingsWithModel; //dbg - int geoSkipped = 0; + //int geoSkipped = 0; + //int totalGeo = 0; + //int totalThings = 0; // Crosshair private FlatVertex[] crosshairverts; @@ -498,6 +500,7 @@ namespace CodeImp.DoomBuilder.Rendering thingsbydistance = new BinaryHeap(); //mxd thingsWithModel = new Dictionary>(); + litGeometry = new Dictionary>(); for(int i = 0; i < RENDER_PASSES; i++) { @@ -512,6 +515,8 @@ namespace CodeImp.DoomBuilder.Rendering //dbg //GZBuilder.GZGeneral.ClearTrace(); //geoSkipped = 0; + //totalGeo = 0; + //totalThings = 0; } } @@ -531,9 +536,6 @@ namespace CodeImp.DoomBuilder.Rendering graphics.Device.SetRenderState(RenderState.TextureFactor, -1); graphics.Shaders.World3D.Begin(); - //mxd - litGeometry = new Dictionary>(); - // SOLID PASS world = Matrix.Identity; ApplyMatrices3D(); @@ -579,7 +581,7 @@ namespace CodeImp.DoomBuilder.Rendering geometry = null; //dbg - //GZBuilder.GZGeneral.TraceLine("Skipped "+geoSkipped+" geometries"); + //GZBuilder.GZGeneral.TraceLine("Affected by lights: "+totalGeo+"; skipped: "+geoSkipped+"; total things:"+totalThings); //GZBuilder.GZGeneral.TraceInHeader("FPS:" + calculateFrameRate()); } @@ -885,9 +887,6 @@ namespace CodeImp.DoomBuilder.Rendering int i, count; Vector4 lpr; - //dbg - //int gcount = 0; - graphics.Device.SetRenderState(RenderState.SourceBlend, Blend.One); graphics.Device.SetRenderState(RenderState.DestinationBlend, Blend.BlendFactor); @@ -898,9 +897,6 @@ namespace CodeImp.DoomBuilder.Rendering i = 0; count = 0; - //dbg - //gcount++; - graphics.Device.SetStreamSource(0, g.Sector.GeometryBuffer, 0, WorldVertex.Stride); //normal lights @@ -909,13 +905,18 @@ namespace CodeImp.DoomBuilder.Rendering graphics.Device.SetRenderState(RenderState.BlendOperation, BlendOperation.Add); for (i = 0; i < count; i++) { - lpr = lights[i].LightPositionAndRadius; - if (lpr.W == 0) - continue; - graphics.Shaders.World3D.LightColor = lights[i].LightColor; - graphics.Shaders.World3D.LightPositionAndRadius = lights[i].LightPositionAndRadius; - graphics.Shaders.World3D.ApplySettings(); - graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles); + if (checkBBoxIntersection(g.BoundingBox, lights[i].BoundingBox)) { + //dbg + //totalGeo++; + + lpr = lights[i].LightPositionAndRadius; + if (lpr.W == 0) + continue; + graphics.Shaders.World3D.LightColor = lights[i].LightColor; + graphics.Shaders.World3D.LightPositionAndRadius = lights[i].LightPositionAndRadius; + graphics.Shaders.World3D.ApplySettings(); + graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles); + } } } @@ -925,13 +926,18 @@ namespace CodeImp.DoomBuilder.Rendering graphics.Device.SetRenderState(RenderState.BlendOperation, BlendOperation.Add); for (i = lightOffsets[0]; i < count; i++) { - lpr = lights[i].LightPositionAndRadius; - if (lpr.W == 0) - continue; - graphics.Shaders.World3D.LightColor = lights[i].LightColor; - graphics.Shaders.World3D.LightPositionAndRadius = lights[i].LightPositionAndRadius; - graphics.Shaders.World3D.ApplySettings(); - graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles); + if (checkBBoxIntersection(g.BoundingBox, lights[i].BoundingBox)) { + //dbg + //totalGeo++; + + lpr = lights[i].LightPositionAndRadius; + if (lpr.W == 0) + continue; + graphics.Shaders.World3D.LightColor = lights[i].LightColor; + graphics.Shaders.World3D.LightPositionAndRadius = lights[i].LightPositionAndRadius; + graphics.Shaders.World3D.ApplySettings(); + graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles); + } } } @@ -941,14 +947,19 @@ namespace CodeImp.DoomBuilder.Rendering graphics.Device.SetRenderState(RenderState.BlendOperation, BlendOperation.ReverseSubtract); for (i = lightOffsets[0] + lightOffsets[1]; i < count; i++) { - lpr = lights[i].LightPositionAndRadius; - if (lpr.W == 0) - continue; - Color4 lc = lights[i].LightColor; - graphics.Shaders.World3D.LightColor = new Color4(1.0f, (lc.Green + lc.Blue) / 2, (lc.Red + lc.Blue) / 2, (lc.Green + lc.Red) / 2); - graphics.Shaders.World3D.LightPositionAndRadius = lights[i].LightPositionAndRadius; - graphics.Shaders.World3D.ApplySettings(); - graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles); + if (checkBBoxIntersection(g.BoundingBox, lights[i].BoundingBox)) { + //dbg + //totalGeo++; + + lpr = lights[i].LightPositionAndRadius; + if (lpr.W == 0) + continue; + Color4 lc = lights[i].LightColor; + graphics.Shaders.World3D.LightColor = new Color4(1.0f, (lc.Green + lc.Blue) / 2, (lc.Red + lc.Blue) / 2, (lc.Green + lc.Red) / 2); + graphics.Shaders.World3D.LightPositionAndRadius = lights[i].LightPositionAndRadius; + graphics.Shaders.World3D.ApplySettings(); + graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles); + } } } } @@ -957,8 +968,6 @@ namespace CodeImp.DoomBuilder.Rendering graphics.Shaders.World3D.EndPass(); graphics.Device.SetRenderState(RenderState.BlendOperation, BlendOperation.Add); - //graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, alphaBlendEnabled); //disable AlphaBlending which is turned on in shader - //dbg //GZBuilder.GZGeneral.TraceLine("Lit " + gcount + " geometries; Lights: [" + lightOffsets[0] + ";" + lightOffsets[1] + ";" + lightOffsets[2] + "]" + Environment.NewLine + "Models count: " + thingsWithModel.Count); } @@ -987,8 +996,6 @@ namespace CodeImp.DoomBuilder.Rendering // Determine the shader pass we want to use for this object int wantedshaderpass = ((((t == highlighted) && showhighlight) || (t.Selected && showselection)) ? highshaderpass : shaderpass); - //dbg - //GZBuilder.GZGeneral.Trace("Rendering mesh with "+wantedshaderpass+" pass."+Environment.NewLine); // Switch shader pass? if (currentshaderpass != wantedshaderpass) { @@ -1075,8 +1082,6 @@ namespace CodeImp.DoomBuilder.Rendering { highlighted = obj; } - - // This collects a visual sector's geometry for rendering public void AddSectorGeometry(VisualGeometry g) @@ -1084,14 +1089,6 @@ namespace CodeImp.DoomBuilder.Rendering // Must have a texture and vertices if((g.Texture != null) && (g.Triangles > 0)) { - //mxd - /*double angle = Math.Acos(Vector3D.DotProduct(g.Normal, Vector3D.FromAngleXYZ(General.Map.VisualCamera.AngleXY, General.Map.VisualCamera.AngleZ).GetNormal())); - //GZBuilder.GZGeneral.TraceLine("angle=" + angle); - if (angle < 0.78f) { //if angle between geometry normal and camera normal is greater than 135 deg. - geoSkipped++; - return; - }*/ - // Texture group not yet collected? if(!geometry[g.RenderPassInt].ContainsKey(g.Texture)) { @@ -1110,14 +1107,13 @@ namespace CodeImp.DoomBuilder.Rendering //mxd. gater lights if (General.Settings.GZDrawLights && !fullbrightness && t.LightType != -1) { t.UpdateLightRadius(); - //dbg - //GZBuilder.GZGeneral.TraceLine("LightRadius = "+t.LightRadius); + if (t.LightRadius > 0) { t.CalculateCameraDistance3D(D3DDevice.V3(cameraposition)); //t.CameraDistance3D is actually squared distance, hence (t.LightRadius * t.LightRadius) if (t.CameraDistance3D < (t.LightRadius * t.LightRadius) || isThingOnScreen(t.BoundingBox)) { //always render light if camera is within it's radius - //dbg - //GZBuilder.GZGeneral.Trace("Light is on screen."); + if (t.LightType == (int)GZDoomLightType.FLICKER || t.LightType == (int)GZDoomLightType.PULSE || t.LightType == (int)GZDoomLightType.RANDOM) + t.UpdateBoundingBox(t.LightRadius, t.LightRadius * 2); thingsWithLight.Add(t); } } @@ -1125,13 +1121,8 @@ namespace CodeImp.DoomBuilder.Rendering } else if (General.Settings.GZDrawModels && (!General.Settings.GZDrawSelectedModelsOnly || t.Selected) && t.Thing.IsModel) { ModelDefEntry mde = GZBuilder.GZGeneral.ModelDefEntries[t.Thing.Type]; - if (!isThingOnScreen(t.BoundingBox)) { - //dbg - //GZBuilder.GZGeneral.Trace("Model is not on screen"); + if (!isThingOnScreen(t.BoundingBox)) return; - } - //dbg - //GZBuilder.GZGeneral.Trace("Model is on screen"); if (!thingsWithModel.ContainsKey(mde)) thingsWithModel.Add(mde, new List()); @@ -1164,17 +1155,53 @@ namespace CodeImp.DoomBuilder.Rendering Vector3D camNormal = Vector3D.FromAngleXYZ(General.Map.VisualCamera.AngleXY, General.Map.VisualCamera.AngleZ); Vector3D thingNormal = D3DDevice.V3D(bbox[0]) - cameraposition; //bbox[0] is always thing center - if (Vector3D.DotProduct(camNormal, thingNormal) < 0) - return false; + if (Vector3D.DotProduct(camNormal, thingNormal) < 0) { //behind camera plane + //GZBuilder.GZGeneral.TraceLine("Skipped geo. Vector3D.DotProduct(camNormal, thingNormal) < 0"); + return false; + } int len = bbox.Length; Vector3 screenPos; + int behingCount = 0; + int leftCount = 0; + int rightCount = 0; + int topCount = 0; + int bottomCount = 0; + for (int i = 0; i < len; i++) { //check visibility screenPos = Vector3.Project(bbox[i], 0, 0, 1, 1, PROJ_NEAR_PLANE, General.Settings.ViewDistance, worldviewproj); + if (screenPos.X > 0 && screenPos.X < 1 && screenPos.Y > 0 && screenPos.Y < 1) return true; + + if (screenPos.Z < 0) + behingCount++; + + if (screenPos.X < 0) + leftCount++; + else if (screenPos.X > 1) + rightCount++; + if (screenPos.Y < 0) + topCount++; + else if (screenPos.Y > 1) + bottomCount++; } + + if (behingCount == len || leftCount == len || rightCount == len || topCount == len || bottomCount == len) + return false; //Not on screen + return true; + } + + //mxd + private static bool checkBBoxIntersection(Vector3[] bbox1, Vector3[] bbox2) { + Vector3 dist = bbox1[0] - bbox2[0]; + + Vector3 halfSize1 = bbox1[0] - bbox1[1]; + Vector3 halfSize2 = bbox2[0] - bbox2[1]; + + if (halfSize1.X + halfSize2.X >= Math.Abs(dist.X) && halfSize1.Y + halfSize2.Y >= Math.Abs(dist.Y) && halfSize1.Z + halfSize2.Z >= Math.Abs(dist.Z)) + return true; return false; } @@ -1229,9 +1256,9 @@ namespace CodeImp.DoomBuilder.Rendering } //dbg - private int lastTick, lastFrameRate, frameRate; + //private int lastTick, lastFrameRate, frameRate; - private int calculateFrameRate() { + /*private int calculateFrameRate() { if (System.Environment.TickCount - lastTick >= 1000) { lastFrameRate = frameRate; frameRate = 0; @@ -1239,7 +1266,7 @@ namespace CodeImp.DoomBuilder.Rendering } frameRate++; return lastFrameRate; - } + }*/ #endregion } diff --git a/Source/Core/Resources/Splash3_trans.png b/Source/Core/Resources/Splash3_trans.png index d94cc711f10a6cb60caed380ce814367752b1f96..4e2ca777deb1bd95650ce518cefa7c1eaa3840a8 100644 GIT binary patch delta 9186 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 diff --git a/Source/Core/VisualModes/VisualGeometry.cs b/Source/Core/VisualModes/VisualGeometry.cs index 90c2c351..cdb24f17 100644 --- a/Source/Core/VisualModes/VisualGeometry.cs +++ b/Source/Core/VisualModes/VisualGeometry.cs @@ -36,6 +36,9 @@ using CodeImp.DoomBuilder.Editing; using CodeImp.DoomBuilder.IO; using CodeImp.DoomBuilder.Rendering; +//mxd +using CodeImp.DoomBuilder.GZBuilder.Data; + #endregion namespace CodeImp.DoomBuilder.VisualModes @@ -80,6 +83,7 @@ namespace CodeImp.DoomBuilder.VisualModes private int vertexoffset; //mxd + private Vector3[] boundingBox; //private Vector3D normal; #endregion @@ -94,6 +98,7 @@ namespace CodeImp.DoomBuilder.VisualModes internal Color4 ModColor4 { get { return modcolor4; } } //mxd + internal Vector3[] BoundingBox { get { return boundingBox; } } //internal Vector3D Normal { get { return normal; } } /// @@ -161,8 +166,10 @@ namespace CodeImp.DoomBuilder.VisualModes vertices = new WorldVertex[verts.Count]; verts.CopyTo(vertices, 0); triangles = vertices.Length / 3; + //mxd CalculateNormalsAndShading(); + if(sector != null) sector.NeedsUpdateGeo = true; } @@ -170,6 +177,9 @@ namespace CodeImp.DoomBuilder.VisualModes protected void CalculateNormalsAndShading() { int startIndex; Vector3 U, V; + + BoundingBoxSizes bbs = new BoundingBoxSizes(vertices[0]); + for (int i = 0; i < triangles; i++) { startIndex = i * 3; WorldVertex p1 = vertices[startIndex]; @@ -200,8 +210,13 @@ namespace CodeImp.DoomBuilder.VisualModes vertices[startIndex] = p1; vertices[startIndex + 1] = p2; vertices[startIndex + 2] = p3; + + BoundingBoxTools.UpdateBoundingBoxSizes(ref bbs, p1); + BoundingBoxTools.UpdateBoundingBoxSizes(ref bbs, p2); + BoundingBoxTools.UpdateBoundingBoxSizes(ref bbs, p3); } - // normal = new Vector3D(vertices[0].nx, vertices[0].ny, vertices[0].nz).GetNormal(); + if (triangles > 0) + boundingBox = BoundingBoxTools.CalculateBoundingPlane(bbs); } // This compares for sorting by sector diff --git a/Source/Core/VisualModes/VisualThing.cs b/Source/Core/VisualModes/VisualThing.cs index 665e7846..eb643936 100644 --- a/Source/Core/VisualModes/VisualThing.cs +++ b/Source/Core/VisualModes/VisualThing.cs @@ -266,9 +266,9 @@ namespace CodeImp.DoomBuilder.VisualModes if (thing.IsModel) { updateBoundingBoxForModel(); } else if (lightType != -1 && lightRadius > thing.Size) { - updateBoundingBox(lightRadius, lightRadius); + UpdateBoundingBox(lightRadius, lightRadius * 2); } else { - updateBoundingBox((int)thing.Size, thingHeight); + UpdateBoundingBox((int)thing.Size, thingHeight); } } @@ -332,12 +332,12 @@ namespace CodeImp.DoomBuilder.VisualModes int light_id = Array.IndexOf(GZBuilder.GZGeneral.GZ_LIGHTS, thing.Type); if (light_id != -1) { updateLight(light_id); - updateBoundingBox(lightRadius, lightRadius); + UpdateBoundingBox(lightRadius, lightRadius * 2); } else { if (thing.IsModel) { updateBoundingBoxForModel(); } else { - updateBoundingBox((int)thing.Size, thingHeight); + UpdateBoundingBox((int)thing.Size, thingHeight); } lightType = -1; lightRadius = -1; @@ -358,7 +358,7 @@ namespace CodeImp.DoomBuilder.VisualModes if (light_id < GZBuilder.GZGeneral.GZ_LIGHT_TYPES[0]) { n = 0; lightRenderStyle = (int)GZDoomLightRenderStyle.NORMAL; - //lightColor.Alpha used in shader to perform some cations based on light type + //lightColor.Alpha used in shader to perform some calculations based on light type lightColor = new Color4(1.0f, (float)thing.Args[0] / 255, (float)thing.Args[1] / 255, (float)thing.Args[2] / 255); } else if (light_id < GZBuilder.GZGeneral.GZ_LIGHT_TYPES[1]) { n = 10; @@ -377,6 +377,12 @@ namespace CodeImp.DoomBuilder.VisualModes lightRadiusMin = thing.Args[3] * 2; //works... that.. way in GZDoom if (lightType > 0) lightRadiusMax = thing.Args[4] * 2; + + if (lightRadiusMin > lightRadiusMax) { //swap them + int lrm = lightRadiusMin; + lightRadiusMin = lightRadiusMax; + lightRadiusMax = lrm; + } } } else { //it's one of vavoom lights lightRenderStyle = (int)GZDoomLightRenderStyle.NORMAL; @@ -412,7 +418,7 @@ namespace CodeImp.DoomBuilder.VisualModes //pulse if (lightType == (int)GZDoomLightType.PULSE) { lightDelta = (float)Math.Sin(time / (100.0f * thing.Angle * 2.3f)); //just playing by the eye here... - lightRadius = Math.Abs((int)(lightRadiusMin + diff + diff * lightDelta)); + lightRadius = Math.Abs((int)(lightRadiusMin + diff/2 + diff/2 * lightDelta)); //flicker } else if (lightType == (int)GZDoomLightType.FLICKER) { @@ -433,24 +439,23 @@ namespace CodeImp.DoomBuilder.VisualModes lightRadius = lightRadiusMin + new Random().Next(0, diff); lightDelta = delta; } - - //return lightRadius; } //mxd. update bounding box - private void updateBoundingBox(int width, int height) { + public void UpdateBoundingBox(int width, int height) { boundingBox = new Vector3[9]; boundingBox[0] = Center; + int h2 = height / 2; - boundingBox[1] = new Vector3(position_v3.X - width, position_v3.Y - width, position_v3.Z); - boundingBox[2] = new Vector3(position_v3.X + width, position_v3.Y - width, position_v3.Z); - boundingBox[3] = new Vector3(position_v3.X - width, position_v3.Y + width, position_v3.Z); - boundingBox[4] = new Vector3(position_v3.X + width, position_v3.Y + width, position_v3.Z); + boundingBox[1] = new Vector3(position_v3.X - width, position_v3.Y - width, Center.Z - h2); + boundingBox[2] = new Vector3(position_v3.X + width, position_v3.Y - width, Center.Z - h2); + boundingBox[3] = new Vector3(position_v3.X - width, position_v3.Y + width, Center.Z - h2); + boundingBox[4] = new Vector3(position_v3.X + width, position_v3.Y + width, Center.Z - h2); - boundingBox[5] = new Vector3(position_v3.X - width, position_v3.Y - width, position_v3.Z + height); - boundingBox[6] = new Vector3(position_v3.X + width, position_v3.Y - width, position_v3.Z + height); - boundingBox[7] = new Vector3(position_v3.X - width, position_v3.Y + width, position_v3.Z + height); - boundingBox[8] = new Vector3(position_v3.X + width, position_v3.Y + width, position_v3.Z + height); + boundingBox[5] = new Vector3(position_v3.X - width, position_v3.Y - width, Center.Z + h2); + boundingBox[6] = new Vector3(position_v3.X + width, position_v3.Y - width, Center.Z + h2); + boundingBox[7] = new Vector3(position_v3.X - width, position_v3.Y + width, Center.Z + h2); + boundingBox[8] = new Vector3(position_v3.X + width, position_v3.Y + width, Center.Z + h2); } //mxd. update bounding box from model bounding box