From f01efcde01d44e02bbf726cce514ec697d865cfa Mon Sep 17 00:00:00 2001 From: Colin McMillen Date: Wed, 12 Feb 2020 15:11:09 -0500 Subject: [PATCH] Split LinesOfSight into separate Draw() and Update() functions. Don't make new arrays every frame. Partial solution to bug #41, just need to DrawIndexedPrimitives() now. GitOrigin-RevId: 0e769d3288dce17fe174b2a1d82a99b1d9994213 --- Shared/LinesOfSight.cs | 31 +++++++++++------ Shared/Shared.projitems | 1 + Shared/SneakGame.cs | 77 +++-------------------------------------- 3 files changed, 25 insertions(+), 84 deletions(-) diff --git a/Shared/LinesOfSight.cs b/Shared/LinesOfSight.cs index 29e9bf7..fb42d1c 100644 --- a/Shared/LinesOfSight.cs +++ b/Shared/LinesOfSight.cs @@ -4,14 +4,22 @@ using System; namespace SemiColinGames { class LinesOfSight { - public static void Draw(Player player, AABB[] collisionTargets, GraphicsDevice graphics, - BasicEffect lightingEffect) { + + const int numConePoints = 60; + VertexPositionColor[] conePoints = new VertexPositionColor[numConePoints]; + Color color = Color.FromNonPremultiplied(new Vector4(0, 0, 1, 0.6f)); + VertexPositionColor[] vertices = new VertexPositionColor[numConePoints * 3]; + VertexBuffer vertexBuffer; + + public LinesOfSight(GraphicsDevice graphics) { + vertexBuffer = new VertexBuffer( + graphics, typeof(VertexPositionColor), numConePoints * 3, BufferUsage.WriteOnly); + } + + public void Update(Player player, AABB[] collisionTargets) { // TODO: DrawIndexedPrimitives - Color color = Color.FromNonPremultiplied(new Vector4(0, 0, 1, 0.6f)); Vector2 eyePos = player.EyePosition; - int numConePoints = 60; - // TODO: don't new[] every frame. - VertexPositionColor[] conePoints = new VertexPositionColor[numConePoints]; + float visionRange = 150; float visionRangeSq = visionRange * visionRange; float fov = FMath.DegToRad(120); @@ -55,18 +63,19 @@ namespace SemiColinGames { Color tinted = Color.FromNonPremultiplied(new Vector4(0, 0, 1, tint)); conePoints[i] = new VertexPositionColor(new Vector3(closestHit, 0), tinted); } + } + + public void Draw(Player player, AABB[] collisionTargets, GraphicsDevice graphics, + BasicEffect lightingEffect) { - // TODO: don't new[] every frame. - VertexPositionColor[] vertices = new VertexPositionColor[numConePoints * 3]; - VertexPositionColor eyeVertex = new VertexPositionColor(new Vector3(eyePos, 0), color); + VertexPositionColor eyeVertex = new VertexPositionColor( + new Vector3(player.EyePosition, 0), color); for (int i = 0; i < numConePoints - 1; i++) { vertices[i * 3] = eyeVertex; vertices[i * 3 + 1] = conePoints[i]; vertices[i * 3 + 2] = conePoints[i + 1]; } - VertexBuffer vertexBuffer = new VertexBuffer( - graphics, typeof(VertexPositionColor), vertices.Length, BufferUsage.WriteOnly); vertexBuffer.SetData(vertices); graphics.SetVertexBuffer(vertexBuffer); diff --git a/Shared/Shared.projitems b/Shared/Shared.projitems index 5b7292f..64ba46d 100644 --- a/Shared/Shared.projitems +++ b/Shared/Shared.projitems @@ -19,6 +19,7 @@ + diff --git a/Shared/SneakGame.cs b/Shared/SneakGame.cs index 09e3210..7fad51d 100644 --- a/Shared/SneakGame.cs +++ b/Shared/SneakGame.cs @@ -36,6 +36,7 @@ namespace SemiColinGames { Player player; World world; + LinesOfSight linesOfSight; readonly Camera camera = new Camera(); public SneakGame() { @@ -84,6 +85,7 @@ namespace SemiColinGames { player = new Player(Content.Load("Ninja_Female")); world = new World(Content.Load("grassland"), Levels.ONE_ONE); + linesOfSight = new LinesOfSight(GraphicsDevice); grasslandBg1 = Content.Load("grassland_bg1"); grasslandBg2 = Content.Load("grassland_bg2"); } @@ -121,6 +123,7 @@ namespace SemiColinGames { float modelTime = (float) gameTime.ElapsedGameTime.TotalSeconds; Clock.AddModelTime(modelTime); player.Update(modelTime, input, world.CollisionTargets); + linesOfSight.Update(player, world.CollisionTargets); camera.Update(player.Position, world.Width); } @@ -183,7 +186,7 @@ namespace SemiColinGames { GraphicsDevice.SetRenderTarget(lightingTarget); GraphicsDevice.Clear(new Color(0, 0, 0, 0f)); lightingEffect.Projection = camera.Projection; - DrawFov(); + linesOfSight.Draw(player, world.CollisionTargets, GraphicsDevice, lightingEffect); // Draw sceneTarget to screen. GraphicsDevice.SetRenderTarget(null); @@ -206,77 +209,5 @@ namespace SemiColinGames { base.Draw(gameTime); drawTimer.Stop(); } - - private void DrawFov() { - // TODO: DrawIndexedPrimitives - Color color = Color.FromNonPremultiplied(new Vector4(0, 0, 1, 0.6f)); - Vector2 eyePos = player.EyePosition; - int numConePoints = 60; - // TODO: don't new[] every frame. - VertexPositionColor[] conePoints = new VertexPositionColor[numConePoints]; - float visionRange = 150; - float visionRangeSq = visionRange * visionRange; - float fov = FMath.DegToRad(120); - float fovStep = fov / (numConePoints - 1); - - Vector2 ray = new Vector2(visionRange * player.GetFacing, 0); - if (player.GetPose == Player.Pose.Stretching) { - ray = ray.Rotate(player.GetFacing * FMath.DegToRad(-30)); - } - if (player.GetPose == Player.Pose.Crouching) { - ray = ray.Rotate(player.GetFacing * FMath.DegToRad(30)); - } - - for (int i = 0; i < conePoints.Length; i++) { - float angle = -fov / 2 + fovStep * i; - Vector2 rotated = ray.Rotate(angle); - Vector2 closestHit = Vector2.Add(eyePos, rotated); - float hitTime = 1f; - - Vector2 halfTileSize = new Vector2(World.TileSize / 2.0f, World.TileSize / 2.0f); - for (int j = 0; j < world.CollisionTargets.Length; j++) { - AABB box = world.CollisionTargets[j]; - if (Math.Abs(box.Position.X - player.Position.X) > visionRange + halfTileSize.X) { - continue; - } - Vector2 delta = Vector2.Add(halfTileSize, Vector2.Subtract(box.Position, eyePos)); - if (delta.LengthSquared() > visionRangeSq) { - continue; - } - Hit? maybeHit = box.IntersectSegment(eyePos, rotated); - if (maybeHit != null) { - Hit hit = maybeHit.Value; - if (hit.Time < hitTime) { - hitTime = hit.Time; - closestHit = hit.Position; - } - } - } - - float tint = 0.6f - hitTime / 2; - Color tinted = Color.FromNonPremultiplied(new Vector4(0, 0, 1, tint)); - conePoints[i] = new VertexPositionColor(new Vector3(closestHit, 0), tinted); - } - - // TODO: don't new[] every frame. - VertexPositionColor[] vertices = new VertexPositionColor[numConePoints * 3]; - VertexPositionColor eyeVertex = new VertexPositionColor(new Vector3(eyePos, 0), color); - for (int i = 0; i < numConePoints - 1; i++) { - vertices[i * 3] = eyeVertex; - vertices[i * 3 + 1] = conePoints[i]; - vertices[i * 3 + 2] = conePoints[i + 1]; - } - - VertexBuffer vertexBuffer = new VertexBuffer( - GraphicsDevice, typeof(VertexPositionColor), vertices.Length, BufferUsage.WriteOnly); - vertexBuffer.SetData(vertices); - - GraphicsDevice.SetVertexBuffer(vertexBuffer); - - foreach (EffectPass pass in lightingEffect.CurrentTechnique.Passes) { - pass.Apply(); - GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, vertices.Length / 3); - } - } } }