diff --git a/Source/Core/GZBuilder/Data/BoundingBox.cs b/Source/Core/GZBuilder/Data/BoundingBox.cs index b9629393..9e579b54 100644 --- a/Source/Core/GZBuilder/Data/BoundingBox.cs +++ b/Source/Core/GZBuilder/Data/BoundingBox.cs @@ -5,43 +5,24 @@ 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; + public int MinX; + public int MaxX; + public int MinY; + public int MaxY; + public int MinZ; + public int 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; + MinX = MaxX = (int)v.x; + MinY = MaxY = (int)v.y; + MinZ = MaxZ = (int)v.z; } } public static 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[] { 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... @@ -53,14 +34,14 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data 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.x < bbs.MinX) bbs.MinX = (int)v.x; + else if(v.x > bbs.MaxX) bbs.MaxX = (int)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.z < bbs.MinZ) bbs.MinZ = (int)v.z; + else if(v.z > bbs.MaxZ) bbs.MaxZ = (int)v.z; - if (v.y < bbs.MinY) bbs.MinY = (short)v.y; - else if (v.y > bbs.MaxY) bbs.MaxY = (short)v.y; + if(v.y < bbs.MinY) bbs.MinY = (int)v.y; + else if(v.y > bbs.MaxY) bbs.MaxY = (int)v.y; } } } diff --git a/Source/Core/GZBuilder/md3/GZModel.cs b/Source/Core/GZBuilder/md3/GZModel.cs index 966a6f78..b1889a9e 100644 --- a/Source/Core/GZBuilder/md3/GZModel.cs +++ b/Source/Core/GZBuilder/md3/GZModel.cs @@ -1,14 +1,13 @@ using System.Collections.Generic; -using SlimDX; using SlimDX.Direct3D9; namespace CodeImp.DoomBuilder.GZBuilder.MD3 { internal class GZModel { - internal List Meshes; - internal List Textures; - internal Vector3[] BoundingBox; + internal readonly List Meshes; + internal readonly List Textures; + internal float Radius; internal GZModel() { diff --git a/Source/Core/GZBuilder/md3/ModelReader.cs b/Source/Core/GZBuilder/md3/ModelReader.cs index aef6e413..6be9895b 100644 --- a/Source/Core/GZBuilder/md3/ModelReader.cs +++ b/Source/Core/GZBuilder/md3/ModelReader.cs @@ -219,7 +219,14 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 return; } - mde.Model.BoundingBox = BoundingBoxTools.CalculateBoundingBox(bbs); + //scale bbs + bbs.MaxX = (int)(bbs.MaxX * mde.Scale.X); + bbs.MinX = (int)(bbs.MinX * mde.Scale.X); + bbs.MaxY = (int)(bbs.MaxY * mde.Scale.Y); + bbs.MinY = (int)(bbs.MinY * mde.Scale.Y); + + //calculate model radius + 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 @@ -720,16 +727,14 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 } } - //create bounding box - BoundingBoxSizes bbs = new BoundingBoxSizes(); - bbs.MinX = (short)((xsize / 2f - pivot.x) * mde.Scale.X); - bbs.MaxX = (short)((xsize / 2f + pivot.x) * mde.Scale.X); - bbs.MinZ = (short)((zsize / 2f - pivot.z) * mde.Scale.Z); - bbs.MaxZ = (short)((zsize / 2f + pivot.z) * mde.Scale.Z); - bbs.MinY = (short)((ysize / 2f - pivot.y) * mde.Scale.Y); - bbs.MaxY = (short)((ysize / 2f + pivot.y) * mde.Scale.Y); - - mde.Model.BoundingBox = BoundingBoxTools.CalculateBoundingBox(bbs); + // get model extents + int minX = (int)((xsize / 2f - pivot.x) * mde.Scale.X); + int maxX = (int)((xsize / 2f + pivot.x) * mde.Scale.X); + int minY = (int)((ysize / 2f - pivot.y) * mde.Scale.Y); + int maxY = (int)((ysize / 2f + pivot.y) * mde.Scale.Y); + + // calculate model radius + mde.Model.Radius = Math.Max(Math.Max(Math.Abs(minY), Math.Abs(maxY)), Math.Max(Math.Abs(minX), Math.Abs(maxX))); //create texture MemoryStream memstream = new MemoryStream((4096 * 4) + 4096); diff --git a/Source/Core/Rendering/Renderer2D.cs b/Source/Core/Rendering/Renderer2D.cs index 420224da..5e5cbe0a 100644 --- a/Source/Core/Rendering/Renderer2D.cs +++ b/Source/Core/Rendering/Renderer2D.cs @@ -1332,9 +1332,6 @@ namespace CodeImp.DoomBuilder.Rendering foreach(KeyValuePair> group in modelsByType) { mde = General.Map.Data.ModeldefEntries[group.Key]; - float maxX = Math.Max(Math.Abs(mde.Model.BoundingBox[4].X), Math.Abs(mde.Model.BoundingBox[1].X)); - float maxY = Math.Max(Math.Abs(mde.Model.BoundingBox[4].Y), Math.Abs(mde.Model.BoundingBox[1].Y)); - float maxSize = Math.Max(maxX, maxY); foreach(Thing t in group.Value) { @@ -1343,8 +1340,8 @@ namespace CodeImp.DoomBuilder.Rendering float modelScale = scale * t.ActorScale.Width * t.ScaleX; //should we render this model? - if(((screenpos.x + maxSize * modelScale) <= 0.0f) || ((screenpos.x - maxSize * modelScale) >= windowsize.Width) || - ((screenpos.y + maxSize * modelScale) <= 0.0f) || ((screenpos.y - maxSize * modelScale) >= windowsize.Height)) + if(((screenpos.x + mde.Model.Radius * modelScale) <= 0.0f) || ((screenpos.x - mde.Model.Radius * modelScale) >= windowsize.Width) || + ((screenpos.y + mde.Model.Radius * modelScale) <= 0.0f) || ((screenpos.y - mde.Model.Radius * modelScale) >= windowsize.Height)) continue; graphics.Shaders.Things2D.FillColor = t.Selected ? cHighlight : cWire; diff --git a/Source/Core/Rendering/Renderer3D.cs b/Source/Core/Rendering/Renderer3D.cs index ddcd4069..10089d11 100644 --- a/Source/Core/Rendering/Renderer3D.cs +++ b/Source/Core/Rendering/Renderer3D.cs @@ -1241,25 +1241,19 @@ namespace CodeImp.DoomBuilder.Rendering public void AddThingGeometry(VisualThing t) { //mxd. gater lights - if (General.Settings.GZDrawLightsMode != LightRenderMode.NONE && !fullbrightness && t.LightType != DynamicLightType.NONE) + if(General.Settings.GZDrawLightsMode != LightRenderMode.NONE && !fullbrightness && t.LightType != DynamicLightType.NONE) { t.UpdateLightRadius(); - if (t.LightRadius > 0) + 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 - { - if (Array.IndexOf(GZBuilder.GZGeneral.GZ_ANIMATED_LIGHT_TYPES, t.LightType) != -1) - t.UpdateBoundingBox(); - thingsWithLight.Add(t); - } + if (Array.IndexOf(GZBuilder.GZGeneral.GZ_ANIMATED_LIGHT_TYPES, t.LightType) != -1) + t.UpdateBoundingBox(); + thingsWithLight.Add(t); } } - if (!IsThingOnScreen(t.BoundingBox)) return; - //mxd. gather models if(t.Thing.IsModel && General.Settings.GZDrawModelsMode != ModelRenderMode.NONE && (General.Settings.GZDrawModelsMode == ModelRenderMode.ALL || t.Selected)) { @@ -1295,46 +1289,6 @@ namespace CodeImp.DoomBuilder.Rendering visualvertices = verts; } - //mxd - private bool IsThingOnScreen(Vector3[] bbox) - { - 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; //behind camera plane - - int len = bbox.Length; - Vector3 screenPos; - int behindCount = 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) behindCount++; - - if (screenPos.X < 0) - leftCount++; - else if (screenPos.X > 1) - rightCount++; - if (screenPos.Y < 0) - topCount++; - else if (screenPos.Y > 1) - bottomCount++; - } - - bool notOnScreen = (behindCount == len || leftCount == len || rightCount == len || topCount == len || bottomCount == len); - return !notOnScreen; - } - //mxd private static bool BoundingBoxesIntersect(Vector3[] bbox1, Vector3[] bbox2) { diff --git a/Source/Core/VisualModes/VisualMode.cs b/Source/Core/VisualModes/VisualMode.cs index 3127e455..8c88613f 100644 --- a/Source/Core/VisualModes/VisualMode.cs +++ b/Source/Core/VisualModes/VisualMode.cs @@ -494,7 +494,7 @@ namespace CodeImp.DoomBuilder.VisualModes if (target.picked is VisualThing) { VisualThing vt = target.picked as VisualThing; - return GetIntersection(start, start + delta, new Vector3D(vt.BoundingBox[0].X, vt.BoundingBox[0].Y, vt.BoundingBox[0].Z), D3DDevice.V3D(vt.Center - vt.PositionV3)); + return GetIntersection(start, start + delta, vt.CenterV3D, D3DDevice.V3D(vt.Center - vt.PositionV3)); } return new Vector2D(float.NaN, float.NaN); diff --git a/Source/Core/VisualModes/VisualThing.cs b/Source/Core/VisualModes/VisualThing.cs index eaabb5f4..10b17331 100644 --- a/Source/Core/VisualModes/VisualThing.cs +++ b/Source/Core/VisualModes/VisualThing.cs @@ -248,19 +248,11 @@ namespace CodeImp.DoomBuilder.VisualModes position_v3 = D3DDevice.V3(pos); //mxd position = Matrix.Translation(position_v3); - //mxd. update bounding box - if (thing.IsModel) - { - UpdateBoundingBoxForModel(); - } - else if (lightType != DynamicLightType.NONE && lightRadius > thing.Size) + //mxd. update bounding box? + if(lightType != DynamicLightType.NONE && lightRadius > thing.Size) { UpdateBoundingBox(lightRadius, lightRadius * 2); } - else - { - UpdateBoundingBox((int)thing.Size, thingHeight); - } } // This sets the vertices for the thing sprite @@ -326,10 +318,7 @@ namespace CodeImp.DoomBuilder.VisualModes } else { - if (thing.IsModel) - UpdateBoundingBoxForModel(); - else - UpdateBoundingBox((int)thing.Size, thingHeight); + UpdateBoundingBox((int)thing.Size, thingHeight); lightType = DynamicLightType.NONE; lightRadius = -1; @@ -494,12 +483,8 @@ namespace CodeImp.DoomBuilder.VisualModes //mxd. update bounding box public void UpdateBoundingBox() { - if (thing.IsModel) - UpdateBoundingBoxForModel(); - else if (lightType != DynamicLightType.NONE && lightRadius > thing.Size) + if(lightType != DynamicLightType.NONE && lightRadius > thing.Size) UpdateBoundingBox(lightRadius, lightRadius * 2); - else - UpdateBoundingBox((int)thing.Size, thingHeight); } private void UpdateBoundingBox(float width, float height) @@ -518,19 +503,6 @@ namespace CodeImp.DoomBuilder.VisualModes 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 - private void UpdateBoundingBoxForModel() - { - ModelData mde = General.Map.Data.ModeldefEntries[thing.Type]; - int len = mde.Model.BoundingBox.Length; - boundingBox = new Vector3[len]; - for (int i = 0; i < len; i++) - { - Vector3 v = mde.Model.BoundingBox[i]; - boundingBox[i] = new Vector3(v.X + position_v3.X, v.Y + position_v3.Y, v.Z + position_v3.Z); - } - } /// /// This is called when the thing must be tested for line intersection. This should reject