diff --git a/Subsurface/Source/Map/Lights/ConvexHull.cs b/Subsurface/Source/Map/Lights/ConvexHull.cs index c48285988..d0e3fb589 100644 --- a/Subsurface/Source/Map/Lights/ConvexHull.cs +++ b/Subsurface/Source/Map/Lights/ConvexHull.cs @@ -397,6 +397,59 @@ namespace Barotrauma.Lights } } + public static List GetHullsInRange(Vector2 position, float range, Submarine ParentSub) + { + List list = new List(); + + foreach (ConvexHullList chList in ConvexHull.HullLists) + { + Vector2 lightPos = position; + if (ParentSub == null) + { + //light and the convexhull are both outside + if (chList.Submarine == null) + { + list.AddRange(chList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox))); + + } + //light is outside, convexhull inside a sub + else + { + if (!MathUtils.CircleIntersectsRectangle(lightPos - chList.Submarine.WorldPosition, range, chList.Submarine.Borders)) continue; + + lightPos -= (chList.Submarine.WorldPosition - chList.Submarine.HiddenSubPosition); + + list.AddRange(chList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox))); + } + } + else + { + //light is inside, convexhull outside + if (chList.Submarine == null) continue; + + //light and convexhull are both inside the same sub + if (chList.Submarine == ParentSub) + { + list.AddRange(chList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox))); + } + //light and convexhull are inside different subs + else + { + lightPos -= (chList.Submarine.Position - ParentSub.Position); + + Rectangle subBorders = chList.Submarine.Borders; + subBorders.Location += chList.Submarine.HiddenSubPosition.ToPoint() - new Point(0, chList.Submarine.Borders.Height); + + if (!MathUtils.CircleIntersectsRectangle(lightPos, range, subBorders)) continue; + + list.AddRange(chList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox))); + } + } + } + + return list; + } + public void DrawShadows(GraphicsDevice graphicsDevice, Camera cam, LightSource light, Matrix transform, bool los = true) { if (!Enabled) return; diff --git a/Subsurface/Source/Map/Lights/LightManager.cs b/Subsurface/Source/Map/Lights/LightManager.cs index b3d4c8382..4040be2ab 100644 --- a/Subsurface/Source/Map/Lights/LightManager.cs +++ b/Subsurface/Source/Map/Lights/LightManager.cs @@ -133,45 +133,19 @@ namespace Barotrauma.Lights //clear to some small ambient light graphics.Clear(AmbientLight); + spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, null, null, null, null, cam.Transform); + foreach (LightSource light in lights) { if (light.Color.A < 1 || light.Range < 1.0f || !light.CastShadows) continue; if (!MathUtils.CircleIntersectsRectangle(light.WorldPosition, light.Range, viewRect)) continue; - - //clear alpha to 1 - ClearAlphaToOne(graphics, spriteBatch); - - //draw all shadows - //write only to the alpha channel, which sets alpha to 0 - graphics.RasterizerState = RasterizerState.CullNone; - graphics.BlendState = CustomBlendStates.WriteToAlpha; - light.DrawShadows(graphics, cam, shadowTransform); - - //draw the light shape - //where Alpha is 0, nothing will be written - spriteBatch.Begin(SpriteSortMode.Deferred, CustomBlendStates.MultiplyWithAlpha, null, null, null, null, cam.Transform); light.Draw(spriteBatch); - spriteBatch.End(); } - - ClearAlphaToOne(graphics, spriteBatch); - - spriteBatch.Begin(SpriteSortMode.Deferred, CustomBlendStates.MultiplyWithAlpha, null, null, null, null, cam.Transform); - GameMain.ParticleManager.Draw(spriteBatch, false, Particles.ParticleBlendState.Additive); - - foreach (LightSource light in lights) - { - if (light.Color.A < 1 || light.Range < 1.0f || light.CastShadows) continue; - //if (!MathUtils.CircleIntersectsRectangle(light.WorldPosition, light.Range, viewRect)) continue; - - light.Draw(spriteBatch); - } - if (Character.Controlled != null) { if (Character.Controlled.ClosestItem != null) @@ -185,10 +159,6 @@ namespace Barotrauma.Lights Character.Controlled.ClosestCharacter.Draw(spriteBatch); } } - spriteBatch.End(); - - - spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, null, null, null, null, cam.Transform); foreach (Hull hull in smoothedHullAmbientLights.Keys) { @@ -207,7 +177,6 @@ namespace Barotrauma.Lights spriteBatch.End(); - //clear alpha, to avoid messing stuff up later ClearAlphaToOne(graphics, spriteBatch); @@ -253,7 +222,7 @@ namespace Barotrauma.Lights Matrix shadowTransform = cam.ShaderTransform * Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f; - var convexHulls = LightSource.GetHullsInRange(viewTarget.Position, cam.WorldView.Width*0.75f, viewTarget.Submarine); + var convexHulls = ConvexHull.GetHullsInRange(viewTarget.Position, cam.WorldView.Width*0.75f, viewTarget.Submarine); if (convexHulls != null) { diff --git a/Subsurface/Source/Map/Lights/LightSource.cs b/Subsurface/Source/Map/Lights/LightSource.cs index f6d21525d..0b64f0206 100644 --- a/Subsurface/Source/Map/Lights/LightSource.cs +++ b/Subsurface/Source/Map/Lights/LightSource.cs @@ -136,7 +136,7 @@ namespace Barotrauma.Lights GameMain.LightManager.AddLight(this); } - public void DrawShadows(GraphicsDevice graphics, Camera cam, Matrix shadowTransform) + /*public void DrawShadows(GraphicsDevice graphics, Camera cam, Matrix shadowTransform) { if (!CastShadows) return; if (range < 1.0f || color.A < 0.01f) return; @@ -161,9 +161,9 @@ namespace Barotrauma.Lights foreach (ConvexHull ch in outsideHulls) { ch.DrawShadows(graphics, cam, this, shadowTransform, false); - } - } - + } + } + private List GetHullsInRange(Submarine sub) { //find the current list of hulls in range @@ -237,62 +237,20 @@ namespace Barotrauma.Lights } return chList.List; - } + }*/ - public static List GetHullsInRange(Vector2 position, float range, Submarine ParentSub) + private void CalculateFanVertices() { - List list = new List(); + if (!CastShadows) return; + if (range < 1.0f || color.A < 0.01f) return; - foreach (ConvexHullList chList in ConvexHull.HullLists) - { - Vector2 lightPos = position; - if (ParentSub == null) - { - //light and the convexhull are both outside - if (chList.Submarine == null) - { - list.AddRange(chList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox))); - - } - //light is outside, convexhull inside a sub - else - { - if (!MathUtils.CircleIntersectsRectangle(lightPos - chList.Submarine.WorldPosition, range, chList.Submarine.Borders)) continue; - - lightPos -= (chList.Submarine.WorldPosition - chList.Submarine.HiddenSubPosition); - - list.AddRange(chList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox))); - } - } - else - { - //light is inside, convexhull outside - if (chList.Submarine == null) continue; - - //light and convexhull are both inside the same sub - if (chList.Submarine == ParentSub) - { - list.AddRange(chList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox))); - } - //light and convexhull are inside different subs - else - { - lightPos -= (chList.Submarine.Position - ParentSub.Position); - - Rectangle subBorders = chList.Submarine.Borders; - subBorders.Location += chList.Submarine.HiddenSubPosition.ToPoint() - new Point(0, chList.Submarine.Borders.Height); - - if (!MathUtils.CircleIntersectsRectangle(lightPos, range, subBorders)) continue; - - list.AddRange(chList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox))); - } - } - } - - - return list; + var hulls = ConvexHull.GetHullsInRange(position, range, ParentSub); + + //TODO: calculate fan based on hulls + + //http://www.redblobgames.com/articles/visibility/ + //http://roy-t.nl/index.php/2014/02/27/2d-lighting-and-shadows-preview/ } - public void Draw(SpriteBatch spriteBatch) { @@ -323,7 +281,6 @@ namespace Barotrauma.Lights if (LightSprite != null) { LightSprite.Draw(spriteBatch, drawPos, Color, LightSprite.Origin, -Rotation, 1, SpriteEffect); - } }