< Summary

Class:GDX.Experimental.DebugDrawBuffer
Assembly:GDX
File(s):./Packages/com.dotbunny.gdx/GDX/Experimental/DebugDrawBuffer.cs
Covered lines:24
Uncovered lines:248
Coverable lines:272
Total lines:726
Line coverage:8.8% (24 of 272)
Covered branches:0
Total branches:0
Covered methods:2
Total methods:33
Method coverage:6% (2 of 33)

Coverage History

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
DebugDrawBuffer()0%110100%
DebugDrawBuffer(...)0%330100%
Converge()0%42600%
DrawDottedLine(...)0%2100%
DrawDottedLines(...)0%2100%
DrawDottedLines(...)0%2100%
DrawLine(...)0%2100%
DrawLines(...)0%2100%
DrawLines(...)0%2100%
DrawLines(...)0%90900%
DrawRenderer(...)0%2100%
DrawMesh(...)0%2100%
Execute()0%6200%
GetBuffer()0%2100%
HasToken(...)0%2100%
Unlock()0%2100%
Invalidate(...)0%6200%
InvalidateAll()0%2100%
NextDottedLineBatch(...)0%2100%
NextLineBatch(...)0%2100%
NextLineBatch(...)0%12300%
Reset()0%2100%
AddLineDrawCommand(...)0%6200%
AddMeshDrawCommand(...)0%2100%
AddMeshDrawCommand(...)0%6200%
GetDottedLineMaterialByColor(...)0%6200%
GetMaterialByHashCode(...)0%12300%
GetSolidLineMaterialByColor(...)0%6200%
ReserveToken()0%2100%
DrawCommand(...)0%2100%
DrawCommand(...)0%2100%

File(s)

./Packages/com.dotbunny.gdx/GDX/Experimental/DebugDrawBuffer.cs

#LineLine coverage
 1// Copyright (c) 2020-2023 dotBunny Inc.
 2// dotBunny licenses this file to you under the BSL-1.0 license.
 3// See the LICENSE file in the project root for more information.
 4
 5using GDX.Collections.Generic;
 6using UnityEngine;
 7using UnityEngine.Rendering;
 8
 9namespace GDX.Experimental
 10{
 11    // TODO: Add Lifetime? - puts them in volatile?
 12
 13    /// <summary>
 14    /// An optimized method for drawing static procedural content.
 15    /// </summary>
 16    /// <remarks>
 17    ///     This still suffers from multiple SetPass calls associated with the <see cref="CommandBuffer"/>.
 18    ///     It should be possible in the future to using GraphicsBuffers/BatchRenderGroup once that API stabilizes.
 19    /// </remarks>
 20    public class DebugDrawBuffer
 21    {
 22        /// <summary>
 23        ///     The default maximum number of vertices per meshReference when dynamically creating meshes.
 24        /// </summary>
 25        public const int DefaultMaximumVerticesPerMesh = 512;
 26
 27        /// <summary>
 28        ///     The base instance of the default dotted line material.
 29        /// </summary>
 30        /// <remarks>
 31        ///     This will be cloned when a new color value is provided and not found by
 32        ///     <see cref="GetDottedLineMaterialByColor"/>.
 33        /// </remarks>
 34        static Material s_DottedLineMaterial;
 35
 36        /// <summary>
 37        ///     The base instance of the default line material.
 38        /// </summary>
 39        /// <remarks>
 40        ///     This will be cloned when a new color value is provided and not found by
 41        ///     <see cref="GetSolidLineMaterialByColor" />.
 42        /// </remarks>
 43        static Material s_LineMaterial;
 44
 45        /// <summary>
 46        ///     The ordered segment index pairs used to describe a line.
 47        /// </summary>
 148        static int[] s_LineSegmentIndices =
 49        {
 50            0, 1
 51        };
 52
 53        /// <summary>
 54        /// The associated <see cref="int"/> key with the <see cref="DebugDrawBuffer"/>.
 55        /// </summary>
 56        /// <remarks>
 57        ///     <para>
 58        ///         This is useful for identifying the <see cref="DebugDrawBuffer" /> in different contexts; its
 59        ///         specific use is meant for being able to recall a <see cref="DebugDrawBuffer" /> from the
 60        ///         <see cref="DebugDraw" />.
 61        ///     </para>
 62        ///     <para>
 63        ///         A common pattern is to use the the <see cref="GameObject"/>'s InstanceID or an Entity Number to
 64        ///         create a unique indexer. Collisions can occur if you are not careful about how you index your
 65        ///         <see cref="DebugDrawBuffer"/>.
 66        ///     </para>
 67        /// </remarks>
 68        public readonly int Key;
 69
 70        /// <summary>
 71        ///     The actual allocated <see cref="CommandBuffer"/> used by the <see cref="DebugDrawBuffer"/>.
 72        /// </summary>
 73        readonly CommandBuffer m_CommandBuffer;
 74
 75        /// <summary>
 76        ///     The established maximum number of vertices per meshReference for this particular <see cref="DebugDrawBuf
 77        /// </summary>
 78        /// <remarks>
 79        ///     Once this is set in the constructor it cannot be changed. Arbitrary meshReference adds are not effected 
 80        /// </remarks>
 81        readonly int m_MaximumVerticesPerMesh;
 82
 83        /// <summary>
 84        ///     The current incremental token used when associating draw commands.
 85        /// </summary>
 86        /// <remarks>
 87        ///     This is used to provide a stable index in an extremely simple form. While it will eventually roll over,
 88        ///     at that threshold you should be considering if multiple <see cref="DebugDrawBuffer"/> may be more
 89        ///     optimal.
 90        /// </remarks>
 91        int m_CurrentToken;
 92
 93        /// <summary>
 94        ///     An indexed dictionary of all dotted line materials, referenced by the hashcode of the color.
 95        /// </summary>
 96        IntKeyDictionary<int> m_DottedLineMaterials;
 97
 98        /// <summary>
 99        ///     An indexed dictionary of all of the draw commands to use with the buffer.
 100        /// </summary>
 101        /// <remarks>
 102        ///     This includes the meshReference and an index of the material to use with that meshReference when drawing
 103        ///     added, the <see cref="m_CurrentToken"/> is incremented to simulate a stable ID.
 104        /// </remarks>
 105        IntKeyDictionary<DrawCommand> m_DrawCommands;
 106
 107        /// <summary>
 108        ///     An indexed dictionary of all line materials, referenced by the hashcode of the color.
 109        /// </summary>
 110        IntKeyDictionary<int> m_LineMaterials;
 111
 112        /// <summary>
 113        ///     An ever expanding list of materials used with the <see cref="DebugDrawBuffer"/>.
 114        /// </summary>
 115        /// <remarks>
 116        ///     Both <see cref="m_DottedLineMaterials"/> and <see cref="m_LineMaterials"/> store indexes of
 117        ///     <see cref="Material"/>s inside of this list.
 118        /// </remarks>
 119        SimpleList<Material> m_Materials;
 120
 121        /// <summary>
 122        ///     A storage of working vertices information indexed based on the hashcode of the material it is meant to
 123        ///     be drawn with.
 124        /// </summary>
 125        IntKeyDictionary<SimpleList<Vector3>> m_WorkingPoints;
 126
 127        /// <summary>
 128        ///     A storage of working segment indices pairs indexed based on the hashcode of the material it is meant to
 129        ///     be drawn with.
 130        /// </summary>
 131        IntKeyDictionary<SimpleList<int>> m_WorkingSegments;
 132
 133        /// <summary>
 134        ///     A storage of working expected tokens of meshes to be created in the future.
 135        /// </summary>
 136        IntKeyDictionary<int> m_WorkingTokens;
 137
 138        /// <summary>
 139        ///     Create a <see cref="DebugDrawBuffer"/>.
 140        /// </summary>
 141        /// <param name="key">The internally cached key associated with this buffer.</param>
 142        /// <param name="initialMaterialCount">
 143        ///     An initial allocation of the expected number of materials that will be used.
 144        /// </param>
 145        /// <param name="verticesPerMesh">The number of vertices to ingest before a meshReference is split.</param>
 4146        public DebugDrawBuffer(int key, int initialMaterialCount = 5,
 147            int verticesPerMesh = DefaultMaximumVerticesPerMesh)
 4148        {
 4149            Key = key;
 150
 4151            m_MaximumVerticesPerMesh = verticesPerMesh;
 152
 4153            m_Materials = new SimpleList<Material>(initialMaterialCount);
 4154            m_LineMaterials = new IntKeyDictionary<int>(initialMaterialCount);
 4155            m_DottedLineMaterials = new IntKeyDictionary<int>(initialMaterialCount);
 156
 4157            m_WorkingPoints = new IntKeyDictionary<SimpleList<Vector3>>(initialMaterialCount);
 4158            m_WorkingSegments = new IntKeyDictionary<SimpleList<int>>(initialMaterialCount);
 4159            m_WorkingTokens = new IntKeyDictionary<int>(initialMaterialCount);
 160
 4161            m_DrawCommands = new IntKeyDictionary<DrawCommand>(2);
 4162            m_CurrentToken = 0;
 163
 4164            m_CommandBuffer = new CommandBuffer();
 4165            m_CommandBuffer.name = $"GDX_DebugDrawBuffer_{Key}";
 166
 167            // Make sure our statics have their desired default materials atm
 4168            if (s_LineMaterial == null)
 1169            {
 1170                s_LineMaterial = new Material(Rendering.ShaderProvider.UnlitColor);
 1171            }
 172
 4173            if (s_DottedLineMaterial == null)
 1174            {
 1175                s_DottedLineMaterial = new Material(Rendering.ShaderProvider.DottedLine);
 1176            }
 4177        }
 178
 179        /// <summary>
 180        ///     Has the <see cref="DebugDrawBuffer"/> been converged?
 181        /// </summary>
 182        /// <remarks>
 183        ///     A finalized <see cref="DebugDrawBuffer"/> has had its command buffer filled with the fixed draw calls
 184        ///     based on the meshes/materials outlined. If a meshReference is invalidated by <see cref="Invalidate"/>, t
 185        ///     <see cref="DebugDrawBuffer"/> will become not finalized and will re-converge itself next
 186        ///     <see cref="Execute"/>.
 187        /// </remarks>
 188        public bool Finalized
 189        {
 0190            get;
 0191            private set;
 192        }
 193
 194        /// <summary>
 195        ///     Converges all working vertices/material additions into finalized meshReference forms and fills the comma
 196        ///     buffer with the appropriate data.
 197        /// </summary>
 198        public void Converge()
 0199        {
 0200            if (Finalized) return;
 201
 202            //  Finalize each material we have something in process for
 0203            int materialCount = m_Materials.Count;
 0204            for (int i = 0; i < materialCount; i++)
 0205            {
 0206                int materialHashCode = m_Materials.Array[i].GetHashCode();
 207
 208                // We've finalized and have just invalidated, dont want to go through this
 0209                if (!m_WorkingPoints.ContainsKey(materialHashCode))
 0210                {
 0211                    continue;
 212                }
 213
 0214                SimpleList<Vector3> pointList = m_WorkingPoints[materialHashCode];
 0215                SimpleList<int> segmentList = m_WorkingSegments[materialHashCode];
 0216                int token = m_WorkingTokens[materialHashCode];
 0217                if (pointList.Count > 0)
 0218                {
 0219                    AddLineDrawCommand(GetMaterialByHashCode(materialHashCode), ref pointList.Array, ref segmentList.Arr
 0220                }
 0221            }
 222
 223            // Clear our working memory
 0224            m_WorkingPoints.Clear();
 0225            m_WorkingSegments.Clear();
 0226            m_CommandBuffer.Clear();
 227
 228            // Record our command buffer
 0229            int currentIndex = 0;
 0230            while (m_DrawCommands.MoveNext(ref currentIndex))
 0231            {
 0232                DrawCommand command = m_DrawCommands.Entries[currentIndex - 1].Value;
 233
 0234                m_CommandBuffer.DrawMesh(command.MeshReference, command.Matrix,
 235                    command.MaterialReference,0, 0);
 0236            }
 0237            Finalized = true;
 0238        }
 239
 240
 241        /// <summary>
 242        ///     Draw a dotted line of a specific color as defined to the buffer.
 243        /// </summary>
 244        /// <remarks>
 245        ///     If multiple lines are being drawn it is much more performant to use
 246        ///     <see cref="DrawDottedLines(UnityEngine.Color,ref UnityEngine.Vector3[],ref int[])"/>.
 247        /// </remarks>
 248        /// <param name="color">The color which to draw the dotted line with.</param>
 249        /// <param name="startPoint">The start of the line in world space.</param>
 250        /// <param name="endPoint">The end of the line in world space.</param>
 251        /// <returns>The dotted line's invalidation token.</returns>
 252        public int DrawDottedLine(Color color, Vector3 startPoint, Vector3 endPoint)
 0253        {
 0254            Vector3[] points = new Vector3[] { startPoint, endPoint };
 0255            return DrawDottedLines(color, ref points, 0, 2,
 256                ref s_LineSegmentIndices, 0, 2);
 0257        }
 258
 259        /// <summary>
 260        ///     Draw dotted lines of a specific color as defined to the buffer.
 261        /// </summary>
 262        /// <param name="color">The color which to draw the dotted lines with.</param>
 263        /// <param name="vertices">The vertices of the dotted lines.</param>
 264        /// <param name="segments">The segment pairs based on <paramref name="vertices"/>.</param>
 265        /// <returns>The dotted lines' invalidation token.</returns>
 266        public int DrawDottedLines(Color color, ref Vector3[] vertices, ref int[] segments)
 0267        {
 0268            return DrawDottedLines(color,
 269                ref vertices, 0, vertices.Length,
 270                ref segments, 0, segments.Length);
 0271        }
 272
 273        /// <summary>
 274        ///     Draw dotted lines of a specific color as defined to the buffer.
 275        /// </summary>
 276        /// <param name="color">The color which to draw the dotted lines with.</param>
 277        /// <param name="vertices">The vertices of the dotted lines.</param>
 278        /// <param name="verticesStartIndex">The index to start at in the <paramref name="vertices"/> array.</param>
 279        /// <param name="verticesLength">The number of elements in the <paramref name="vertices"/> array to use.</param>
 280        /// <param name="segments">The segment pairs based on <paramref name="vertices"/>.</param>
 281        /// <param name="segmentsStartIndex">The index to start at in the <paramref name="segments"/> array.</param>
 282        /// <param name="segmentsLength">The number of elements in the <paramref name="segments"/> array to use.</param>
 283        /// <returns>The dotted lines' invalidation token.</returns>
 284        public int DrawDottedLines(Color color,
 285            ref Vector3[] vertices, int verticesStartIndex, int verticesLength,
 286            ref int[] segments, int segmentsStartIndex, int segmentsLength)
 0287        {
 0288            return DrawLines(GetDottedLineMaterialByColor(color), ref vertices, verticesStartIndex, verticesLength,
 289                ref segments, segmentsStartIndex, segmentsLength);
 0290        }
 291
 292        /// <summary>
 293        ///     Draw a line of a specific color as defined to the buffer.
 294        /// </summary>
 295        /// <remarks>
 296        ///     If multiple lines are being drawn it is much more performant to use
 297        ///     <see cref="DrawLines(UnityEngine.Color,ref UnityEngine.Vector3[],ref int[])"/>.
 298        /// </remarks>
 299        /// <param name="color">The color which to draw the line with.</param>
 300        /// <param name="startPoint">The start of the line in world space.</param>
 301        /// <param name="endPoint">The end of the line in world space.</param>
 302        /// <returns>The line's invalidation token.</returns>
 303        public int DrawLine(Color color, Vector3 startPoint, Vector3 endPoint)
 0304        {
 0305            Vector3[] points = new Vector3[] { startPoint, endPoint };
 0306            return DrawLines(color, ref points, 0, 2,
 307                ref s_LineSegmentIndices, 0, 2);
 0308        }
 309
 310        /// <summary>
 311        ///     Draw lines of a specific color as defined to the buffer.
 312        /// </summary>
 313        /// <param name="color">The color which to draw the lines with.</param>
 314        /// <param name="vertices">The vertices of the lines.</param>
 315        /// <param name="segments">The segment pairs based on <paramref name="vertices"/>.</param>
 316        /// <returns>The lines' invalidation token.</returns>
 317        public int DrawLines(Color color, ref Vector3[] vertices, ref int[] segments)
 0318        {
 0319            return DrawLines(color,
 320                ref vertices, 0, vertices.Length,
 321                ref segments, 0, segments.Length);
 0322        }
 323
 324        /// <summary>
 325        ///     Draw lines of a specific color as defined to the buffer.
 326        /// </summary>
 327        /// <param name="color">The color which to draw the lines with.</param>
 328        /// <param name="vertices">The vertices of the lines.</param>
 329        /// <param name="verticesStartIndex">The index to start at in the <paramref name="vertices"/> array.</param>
 330        /// <param name="verticesLength">The number of elements in the <paramref name="vertices"/> array to use.</param>
 331        /// <param name="segments">The segment pairs based on <paramref name="vertices"/>.</param>
 332        /// <param name="segmentsStartIndex">The index to start at in the <paramref name="segments"/> array.</param>
 333        /// <param name="segmentsLength">The number of elements in the <paramref name="segments"/> array to use.</param>
 334        /// <returns>The lines' invalidation token.</returns>
 335        public int DrawLines(Color color,
 336            ref Vector3[] vertices, int verticesStartIndex, int verticesLength,
 337            ref int[] segments, int segmentsStartIndex, int segmentsLength)
 0338        {
 0339            return DrawLines(GetSolidLineMaterialByColor(color), ref vertices, verticesStartIndex, verticesLength,
 340                ref segments, segmentsStartIndex, segmentsLength);
 0341        }
 342
 343        /// <summary>
 344        ///     Draw lines with a specific material to the buffer.
 345        /// </summary>
 346        /// <param name="material">A <em>potentially</em> unlit material to draw the lines with. This will only be drawi
 347        /// <param name="vertices">The vertices of the lines.</param>
 348        /// <param name="verticesStartIndex">The index to start at in the <paramref name="vertices"/> array.</param>
 349        /// <param name="verticesLength">The number of elements in the <paramref name="vertices"/> array to use.</param>
 350        /// <param name="segments">The segment pairs based on <paramref name="vertices"/>.</param>
 351        /// <param name="segmentsStartIndex">The index to start at in the <paramref name="segments"/> array.</param>
 352        /// <param name="segmentsLength">The number of elements in the <paramref name="segments"/> array to use.</param>
 353        /// <returns>The lines' invalidation token.</returns>
 354        public int DrawLines(Material material,
 355            ref Vector3[] vertices, int verticesStartIndex, int verticesLength,
 356            ref int[] segments, int segmentsStartIndex, int segmentsLength)
 0357        {
 0358            if (Finalized)
 0359            {
 360#if UNITY_EDITOR
 0361                Debug.LogWarning("Finalized. You must invalidate the batch before adding anything.");
 362#endif // UNITY_EDITOR
 0363                return -1;
 364            }
 365
 366            // Figure out our identifier for the material we will be drawing against
 0367            int materialHashCode = material.GetHashCode();
 0368            if (!m_Materials.ContainsItem(material))
 0369            {
 0370                m_Materials.AddWithExpandCheck(material);
 0371            }
 372
 0373            if (!m_WorkingPoints.ContainsKey(materialHashCode))
 0374            {
 0375                m_WorkingPoints.AddWithExpandCheck(materialHashCode, new SimpleList<Vector3>(verticesLength));
 0376                m_WorkingSegments.AddWithExpandCheck(materialHashCode, new SimpleList<int>(segmentsLength));
 0377                m_WorkingTokens.AddWithExpandCheck(materialHashCode, ReserveToken());
 0378            }
 379
 380            // Get data storage
 0381            SimpleList<Vector3> pointList = m_WorkingPoints[materialHashCode];
 0382            int token = m_WorkingTokens[materialHashCode];
 383
 384            // Check for meshReference conversion
 0385            if (pointList.Array.Length + verticesLength >= m_MaximumVerticesPerMesh)
 0386            {
 387                // Create meshReference!
 0388                SimpleList<int> segmentList = m_WorkingSegments[materialHashCode];
 0389                AddLineDrawCommand(material, ref pointList.Array, ref segmentList.Array, token);
 390
 391                // Reset storage
 0392                pointList.Clear();
 0393                m_WorkingSegments[materialHashCode] = new SimpleList<int>(segmentList.Array.Length);
 394
 395                // increment token
 0396                token = ReserveToken();
 0397                m_WorkingTokens[materialHashCode] = token;
 0398            }
 399
 0400            int verticesBaseIndex = pointList.Count;
 0401            if (verticesLength > 0)
 0402            {
 0403                pointList.Reserve(verticesLength);
 0404                int verticesStopIndex = verticesStartIndex + verticesLength;
 0405                for (int i = verticesStartIndex; i < verticesStopIndex; i++)
 0406                {
 0407                    pointList.AddUnchecked(vertices[i]);
 0408                }
 409
 0410                m_WorkingPoints[materialHashCode] = pointList;
 0411            }
 412
 0413            if (segmentsLength > 0)
 0414            {
 0415                SimpleList<int> segmentList = m_WorkingSegments[materialHashCode];
 0416                segmentList.Reserve(segmentsLength);
 0417                int segmentsStopIndex = segmentsStartIndex + segmentsLength;
 0418                for (int i = segmentsStartIndex; i < segmentsStopIndex; i++)
 0419                {
 0420                    segmentList.AddUnchecked(verticesBaseIndex + segments[i]);
 0421                }
 422
 0423                m_WorkingSegments[materialHashCode] = segmentList;
 0424            }
 425
 0426            return token;
 0427        }
 428
 429        public int DrawRenderer(MeshRenderer renderer, MeshFilter filter)
 0430        {
 431
 0432            Matrix4x4 matrix = renderer.localToWorldMatrix;
 0433            return DrawMesh(renderer.sharedMaterial, filter.sharedMesh, ref matrix);
 0434        }
 435
 436        public int DrawMesh(Material material, Mesh mesh, ref Matrix4x4 matrix)
 0437        {
 0438            Vector3[] vertices = mesh.vertices;
 0439            int[] triangles = mesh.GetTriangles(0);
 0440            Vector2[] uv0 = mesh.uv;
 441
 0442            return AddMeshDrawCommand(material, ref vertices, ref triangles, ref uv0, ref matrix);
 0443        }
 444
 445        /// <summary>
 446        ///     Execute the <see cref="DebugDrawBuffer"/>, rendering its outputs to the screen.
 447        /// </summary>
 448        /// <remarks>
 449        ///     This will finalize the command buffer, converging all data into meshes, etc. In order to change the
 450        ///     buffer, you will need to
 451        /// </remarks>
 452        public void Execute()
 0453        {
 0454            if (!Finalized)
 0455            {
 0456                Converge();
 0457            }
 458
 0459            Graphics.ExecuteCommandBuffer(m_CommandBuffer);
 0460        }
 461
 462        /// <summary>
 463        ///     Get the internal command buffer being used by this <see cref="DebugDrawBuffer"/>.
 464        /// </summary>
 465        /// <returns>A <see cref="CommandBuffer"/>.</returns>
 466        public CommandBuffer GetBuffer()
 0467        {
 0468            return m_CommandBuffer;
 0469        }
 470
 471        /// <summary>
 472        /// Is the given <paramref name="token"/> present in the draw commands buffer.
 473        /// </summary>
 474        /// <param name="token">The token of the draw commands to check for.</param>
 475        /// <returns>Returns true if the token is found in the existing draw commands.</returns>
 476        public bool HasToken(int token)
 0477        {
 0478            return m_DrawCommands.ContainsKey(token);
 0479        }
 480
 481        public void Unlock()
 0482        {
 0483            Finalized = false;
 0484        }
 485
 486        /// <summary>
 487        ///     Invalidates a <see cref="DrawCommand"/> based on the provided token, forcing the buffer to be refilled.
 488        /// </summary>
 489        /// <param name="token">The token of the draw commands to invalidate.</param>
 490        public void Invalidate(int token)
 0491        {
 0492            if (m_DrawCommands.TryRemove(token))
 0493            {
 0494                Finalized = false;
 0495            }
 0496        }
 497
 498        /// <summary>
 499        ///     Invalidates the entire <see cref="DebugDrawBuffer"/>.
 500        /// </summary>
 501        public void InvalidateAll()
 0502        {
 0503            m_DrawCommands.Clear();
 0504            Finalized = false;
 0505        }
 506
 507        /// <summary>
 508        ///     Move to the next batch for a given dotted line color.
 509        /// </summary>
 510        /// <param name="color">The color which the dotted line is drawn as.</param>
 511        public void NextDottedLineBatch(Color color)
 0512        {
 0513            NextLineBatch(GetDottedLineMaterialByColor(color));
 0514        }
 515
 516        /// <summary>
 517        ///     Move to the next batch for a given line color.
 518        /// </summary>
 519        /// <param name="color">The color which the line is drawn as.</param>
 520        public void NextLineBatch(Color color)
 0521        {
 0522            NextLineBatch((GetSolidLineMaterialByColor(color)));
 0523        }
 524
 525        /// <summary>
 526        ///     Move to the next batch for a given material.
 527        /// </summary>
 528        /// <param name="material">The material used by a batch.</param>
 529        public void NextLineBatch(Material material)
 0530        {
 0531            int materialHashCode = material.GetHashCode();
 532
 0533            if (!m_WorkingPoints.ContainsKey(materialHashCode))
 0534            {
 0535                return;
 536            }
 537
 538            // Get data storage
 0539            SimpleList<Vector3> pointList = m_WorkingPoints[materialHashCode];
 0540            int token = m_WorkingTokens[materialHashCode];
 541
 0542            if(pointList.Array.Length > 0)
 0543            {
 544                // Create meshReference!
 0545                SimpleList<int> segmentList = m_WorkingSegments[materialHashCode];
 0546                AddLineDrawCommand(material, ref pointList.Array, ref segmentList.Array, token);
 547
 548                // Reset storage
 0549                m_WorkingSegments[materialHashCode] = new SimpleList<int>(segmentList.Array.Length);
 0550                m_WorkingPoints[materialHashCode] = new SimpleList<Vector3>(pointList.Array.Length);
 0551                m_WorkingTokens[materialHashCode] = ReserveToken();
 0552            }
 0553        }
 554
 555        /// <summary>
 556        ///     Resets the <see cref="DebugDrawBuffer"/>, as if it were newly created. However all fields are already
 557        ///     allocating their previous sizes.
 558        /// </summary>
 559        public void Reset()
 0560        {
 0561            m_WorkingPoints.Clear();
 0562            m_WorkingSegments.Clear();
 0563            m_WorkingTokens.Clear();
 564
 0565            m_CurrentToken = 0;
 0566            m_DrawCommands.Clear();
 567
 0568            m_Materials.Clear();
 0569            m_LineMaterials.Clear();
 0570            m_DottedLineMaterials.Clear();
 571
 0572            m_CommandBuffer.Clear();
 573
 0574            Finalized = false;
 0575        }
 576
 577        /// <summary>
 578        ///     Builds a line based meshReference from the given <paramref name="vertices"/> and adds it to the draw buf
 579        /// </summary>
 580        /// <param name="material">The material to use when drawing the created meshReference.</param>
 581        /// <param name="vertices">The vertices of the created meshReference.</param>
 582        /// <param name="segments">The segment pairs based on <paramref name="vertices"/>.</param>
 583        /// <param name="token">Force a specific token for the meshReference. Don't use this.</param>
 584        /// <returns>The created meshReference's invalidation token.</returns>
 585        int AddLineDrawCommand(Material material, ref Vector3[] vertices, ref int[] segments, int token = -1)
 0586        {
 0587            Mesh batchMesh = new Mesh { indexFormat = IndexFormat.UInt32 };
 0588            batchMesh.SetVertices(vertices);
 0589            batchMesh.SetIndices(segments, MeshTopology.Lines, 0);
 590
 0591            if (token == -1)
 0592            {
 0593                token = ReserveToken();
 0594            }
 595
 596#if UNITY_EDITOR
 0597            batchMesh.name = $"P_Line_Mesh_{material.name}_{token}";
 598#endif // UNITY_EDITOR
 0599            m_DrawCommands.AddWithExpandCheck(token, new DrawCommand(batchMesh, material));
 0600            return token;
 0601        }
 602
 603        int AddMeshDrawCommand(Material material, ref Vector3[] vertices, ref int[] triangles, ref Vector2[] uv0, ref Ma
 0604        {
 0605            Mesh batchMesh = new Mesh { indexFormat = IndexFormat.UInt32 };
 606
 0607            batchMesh.SetVertices(vertices);
 0608            batchMesh.SetTriangles(triangles, 0);
 0609            batchMesh.SetUVs(0, uv0);
 0610            batchMesh.RecalculateNormals();
 0611            batchMesh.RecalculateTangents();
 612
 0613            return AddMeshDrawCommand(material, batchMesh, ref matrix, token);
 0614        }
 615
 616        int AddMeshDrawCommand(Material material, Mesh mesh, ref Matrix4x4 matrix, int token = -1)
 0617        {
 0618            if (token == -1)
 0619            {
 0620                token = ReserveToken();
 0621            }
 622
 623#if UNITY_EDITOR
 0624            mesh.name = $"P_Mesh_{material.name}_{token}";
 625#endif // UNITY_EDITOR
 626
 0627            m_DrawCommands.AddWithExpandCheck(token, new DrawCommand(mesh, material, ref matrix));
 0628            return token;
 0629        }
 630
 631
 632        /// <summary>
 633        ///     Gets the cached dotted line material, or creates one for the given <paramref name="color"/>.
 634        /// </summary>
 635        /// <param name="color">A defined draw color.</param>
 636        /// <returns>The qualified dotted line material of the color.</returns>
 637        Material GetDottedLineMaterialByColor(Color color)
 0638        {
 0639            int requestedHashCode = color.GetHashCode();
 0640            if (m_DottedLineMaterials.ContainsKey(requestedHashCode))
 0641            {
 0642                return m_Materials.Array[m_DottedLineMaterials[requestedHashCode]];
 643            }
 644
 0645            Material newMaterial = new Material(s_DottedLineMaterial);
 0646            newMaterial.SetColor(Rendering.ShaderProvider.ColorPropertyID, color);
 647
 0648            m_Materials.AddWithExpandCheck(newMaterial);
 0649            m_DottedLineMaterials.AddWithExpandCheck(requestedHashCode, m_Materials.Count - 1);
 0650            return newMaterial;
 0651        }
 652
 653        /// <summary>
 654        ///     Gets a material from the internal cache based on its <see cref="Material.GetHashCode"/>.
 655        /// </summary>
 656        /// <remarks>A warning will be thrown in the editor if the material is not found.</remarks>
 657        /// <param name="hashCode">The integer based hash code of the material.</param>
 658        /// <returns>The material if found, otherwise a default material will be returned.</returns>
 659        Material GetMaterialByHashCode(int hashCode)
 0660        {
 0661            int count = m_Materials.Count;
 0662            for (int i = 0; i < count; i++)
 0663            {
 0664                if (m_Materials.Array[i].GetHashCode() == hashCode) return m_Materials.Array[i];
 0665            }
 666#if UNITY_EDITOR
 0667            Debug.LogWarning(
 668                "A set of lines have been added to the MergedDraw where the Material hash code that was provided has not
 669#endif // UNITY_EDITOR
 670            // Ensure default material
 0671            m_Materials.AddWithExpandCheck(s_LineMaterial);
 0672            return s_LineMaterial;
 0673        }
 674
 675        /// <summary>
 676        ///     Gets the cached solid line material, or creates one for the given <paramref name="color"/>.
 677        /// </summary>
 678        /// <param name="color">A defined draw color.</param>
 679        /// <returns>The qualified line material of the color.</returns>
 680        Material GetSolidLineMaterialByColor(Color color)
 0681        {
 0682            int requestedHashCode = color.GetHashCode();
 0683            if (m_LineMaterials.ContainsKey(requestedHashCode))
 0684            {
 0685                return m_Materials.Array[m_LineMaterials[requestedHashCode]];
 686            }
 687
 0688            Material newMaterial = new Material(s_LineMaterial);
 0689            newMaterial.SetColor(Rendering.ShaderProvider.ColorPropertyID, color);
 690
 0691            m_Materials.AddWithExpandCheck(newMaterial);
 0692            m_LineMaterials.AddWithExpandCheck(requestedHashCode, m_Materials.Count - 1);
 0693            return newMaterial;
 0694        }
 695
 696        int ReserveToken()
 0697        {
 0698            int returnValue = m_CurrentToken;
 0699            m_CurrentToken++;
 0700            return returnValue;
 0701        }
 702
 703        /// <summary>
 704        ///     A structure describing a finalized meshReference/material and its draw operation.
 705        /// </summary>
 706        struct DrawCommand
 707        {
 708            public readonly Mesh MeshReference;
 709            public readonly Matrix4x4 Matrix;
 710            public readonly Material MaterialReference;
 711
 712            public DrawCommand(Mesh meshReference, Material materialReference)
 0713            {
 0714                Matrix = Matrix4x4.identity;
 0715                MaterialReference = materialReference;
 0716                MeshReference = meshReference;
 0717            }
 718            public DrawCommand(Mesh meshReference, Material materialReference, ref Matrix4x4 matrix)
 0719            {
 0720                Matrix = matrix;
 0721                MaterialReference = materialReference;
 0722                MeshReference = meshReference;
 0723            }
 724        }
 725    }
 726}

Coverage by test methods





Methods/Properties

DebugDrawBuffer()
DebugDrawBuffer(System.Int32, System.Int32, System.Int32)
Finalized()
Finalized(System.Boolean)
Converge()
DrawDottedLine(UnityEngine.Color, UnityEngine.Vector3, UnityEngine.Vector3)
DrawDottedLines(UnityEngine.Color, UnityEngine.Vector3[]&, System.Int32[]&)
DrawDottedLines(UnityEngine.Color, UnityEngine.Vector3[]&, System.Int32, System.Int32, System.Int32[]&, System.Int32, System.Int32)
DrawLine(UnityEngine.Color, UnityEngine.Vector3, UnityEngine.Vector3)
DrawLines(UnityEngine.Color, UnityEngine.Vector3[]&, System.Int32[]&)
DrawLines(UnityEngine.Color, UnityEngine.Vector3[]&, System.Int32, System.Int32, System.Int32[]&, System.Int32, System.Int32)
DrawLines(UnityEngine.Material, UnityEngine.Vector3[]&, System.Int32, System.Int32, System.Int32[]&, System.Int32, System.Int32)
DrawRenderer(UnityEngine.MeshRenderer, UnityEngine.MeshFilter)
DrawMesh(UnityEngine.Material, UnityEngine.Mesh, UnityEngine.Matrix4x4&)
Execute()
GetBuffer()
HasToken(System.Int32)
Unlock()
Invalidate(System.Int32)
InvalidateAll()
NextDottedLineBatch(UnityEngine.Color)
NextLineBatch(UnityEngine.Color)
NextLineBatch(UnityEngine.Material)
Reset()
AddLineDrawCommand(UnityEngine.Material, UnityEngine.Vector3[]&, System.Int32[]&, System.Int32)
AddMeshDrawCommand(UnityEngine.Material, UnityEngine.Vector3[]&, System.Int32[]&, UnityEngine.Vector2[]&, UnityEngine.Matrix4x4&, System.Int32)
AddMeshDrawCommand(UnityEngine.Material, UnityEngine.Mesh, UnityEngine.Matrix4x4&, System.Int32)
GetDottedLineMaterialByColor(UnityEngine.Color)
GetMaterialByHashCode(System.Int32)
GetSolidLineMaterialByColor(UnityEngine.Color)
ReserveToken()
DrawCommand(UnityEngine.Mesh, UnityEngine.Material)
DrawCommand(UnityEngine.Mesh, UnityEngine.Material, UnityEngine.Matrix4x4&)