From fc09082f1b049b05799aa36ac768f622ec78d20d Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Sun, 6 Dec 2020 19:27:46 -0800 Subject: [PATCH] frustum cull meshsprites --- Geometry/MeshSprite.cs | 28 +++++++++++++++++++++++----- Renderer.cs | 19 ++++++++++++++++++- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/Geometry/MeshSprite.cs b/Geometry/MeshSprite.cs index 87dac1c..a7cca6c 100644 --- a/Geometry/MeshSprite.cs +++ b/Geometry/MeshSprite.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; @@ -16,13 +17,14 @@ namespace Kav 2 }; - public IndexBuffer IndexBuffer { get; } - public VertexBuffer VertexBuffer { get; } - public Texture2D Texture { get; } public Texture2D Normal { get; } public SpriteBillboardConstraint BillboardConstraint { get; } + public IndexBuffer IndexBuffer { get; } + public VertexBuffer VertexBuffer { get; } + public BoundingBox BoundingBox { get; } + public MeshSprite( GraphicsDevice graphicsDevice, Texture2D texture, @@ -40,13 +42,17 @@ namespace Kav ); IndexBuffer.SetData(Indices); + var vertexArray = GenerateVertexArray(Texture); + VertexBuffer = new VertexBuffer( graphicsDevice, typeof(VertexPositionNormalTexture), 4, BufferUsage.WriteOnly ); - VertexBuffer.SetData(GenerateVertexArray(Texture)); + VertexBuffer.SetData(vertexArray); + + BoundingBox = BoundingBox.CreateFromPoints(Positions(vertexArray)); } public MeshSprite( @@ -67,13 +73,17 @@ namespace Kav ); IndexBuffer.SetData(Indices); + var vertexArray = GenerateVertexArray(Texture); + VertexBuffer = new VertexBuffer( graphicsDevice, typeof(VertexPositionNormalTexture), 4, BufferUsage.WriteOnly ); - VertexBuffer.SetData(GenerateVertexArray(Texture)); + VertexBuffer.SetData(vertexArray); + + BoundingBox = BoundingBox.CreateFromPoints(Positions(vertexArray)); } private static VertexPositionNormalTexture[] GenerateVertexArray(Texture2D texture) @@ -98,5 +108,13 @@ namespace Kav return result; } + + private static IEnumerable Positions(IEnumerable vertices) + { + foreach (var vertex in vertices) + { + yield return vertex.Position; + } + } } } diff --git a/Renderer.cs b/Renderer.cs index 28d510c..b45ac9a 100644 --- a/Renderer.cs +++ b/Renderer.cs @@ -297,7 +297,9 @@ namespace Kav i += 1; } - foreach (var (sprite, transform) in meshSpriteTransforms) + var boundingFrustum = new BoundingFrustum(camera.View * camera.Projection); + + foreach (var (sprite, transform) in FrustumCull(boundingFrustum, meshSpriteTransforms)) { DiffuseLitSpriteEffect.NormalMapEnabled = sprite.Normal != null; @@ -849,6 +851,21 @@ namespace Kav } } + private static IEnumerable<(MeshSprite, Matrix)> FrustumCull( + BoundingFrustum boundingFrustum, + IEnumerable<(MeshSprite, Matrix)> meshSpriteTransforms + ) { + foreach (var (meshSprite, transform) in meshSpriteTransforms) + { + var boundingBox = TransformedBoundingBox(meshSprite.BoundingBox, transform); + var containment = boundingFrustum.Contains(boundingBox); + if (containment != ContainmentType.Disjoint) + { + yield return (meshSprite, transform); + } + } + } + private static BoundingBox TransformedBoundingBox(BoundingBox boundingBox, Matrix matrix) { var center = (boundingBox.Min + boundingBox.Max) / 2f;