< Summary

Class:GDX.Experimental.DebugDrawBuffer
Assembly:GDX
File(s):./Packages/com.dotbunny.gdx/GDX/Experimental/DebugDrawBuffer.cs
Covered lines:24
Uncovered lines:252
Coverable lines:276
Total lines:734
Line coverage:8.6% (24 of 276)
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-2024 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 GDX.RuntimeContent;
 7using UnityEngine;
 8using UnityEngine.Rendering;
 9
 10namespace GDX.Experimental
 11{
 12    // TODO: Add Lifetime? - puts them in volatile?
 13
 14    /// <summary>
 15    ///     An optimized method for drawing static procedural content.
 16    /// </summary>
 17    /// <remarks>
 18    ///     This still suffers from multiple SetPass calls associated with the <see cref="CommandBuffer" />.
 19    ///     It should be possible in the future to using GraphicsBuffers/BatchRenderGroup once that API stabilizes.
 20    /// </remarks>
 21    public class DebugDrawBuffer
 22    {
 23        /// <summary>
 24        ///     The default maximum number of vertices per meshReference when dynamically creating meshes.
 25        /// </summary>
 26        public const int DefaultMaximumVerticesPerMesh = 512;
 27
 28        /// <summary>
 29        ///     The base instance of the default dotted line material.
 30        /// </summary>
 31        /// <remarks>
 32        ///     This will be cloned when a new color value is provided and not found by
 33        ///     <see cref="GetDottedLineMaterialByColor" />.
 34        /// </remarks>
 35        static Material s_DottedLineMaterial;
 36
 37        /// <summary>
 38        ///     The base instance of the default line material.
 39        /// </summary>
 40        /// <remarks>
 41        ///     This will be cloned when a new color value is provided and not found by
 42        ///     <see cref="GetSolidLineMaterialByColor" />.
 43        /// </remarks>
 44        static Material s_LineMaterial;
 45
 46        /// <summary>
 47        ///     The ordered segment index pairs used to describe a line.
 48        /// </summary>
 149        static int[] s_LineSegmentIndices = { 0, 1 };
 50
 51        /// <summary>
 52        ///     The associated <see cref="int" /> key with the <see cref="DebugDrawBuffer" />.
 53        /// </summary>
 54        /// <remarks>
 55        ///     <para>
 56        ///         This is useful for identifying the <see cref="DebugDrawBuffer" /> in different contexts; its
 57        ///         specific use is meant for being able to recall a <see cref="DebugDrawBuffer" /> from the
 58        ///         <see cref="DebugDraw" />.
 59        ///     </para>
 60        ///     <para>
 61        ///         A common pattern is to use the the <see cref="GameObject" />'s InstanceID or an Entity Number to
 62        ///         create a unique indexer. Collisions can occur if you are not careful about how you index your
 63        ///         <see cref="DebugDrawBuffer" />.
 64        ///     </para>
 65        /// </remarks>
 66        public readonly int Key;
 67
 68        /// <summary>
 69        ///     The actual allocated <see cref="CommandBuffer" /> used by the <see cref="DebugDrawBuffer" />.
 70        /// </summary>
 71        readonly CommandBuffer m_CommandBuffer;
 72
 73        /// <summary>
 74        ///     The established maximum number of vertices per meshReference for this particular <see cref="DebugDrawBuf
 75        /// </summary>
 76        /// <remarks>
 77        ///     Once this is set in the constructor it cannot be changed. Arbitrary meshReference adds are not effected 
 78        /// </remarks>
 79        readonly int m_MaximumVerticesPerMesh;
 80
 81        /// <summary>
 82        ///     The current incremental token used when associating draw commands.
 83        /// </summary>
 84        /// <remarks>
 85        ///     This is used to provide a stable index in an extremely simple form. While it will eventually roll over,
 86        ///     at that threshold you should be considering if multiple <see cref="DebugDrawBuffer" /> may be more
 87        ///     optimal.
 88        /// </remarks>
 89        int m_CurrentToken;
 90
 91        /// <summary>
 92        ///     An indexed dictionary of all dotted line materials, referenced by the hashcode of the color.
 93        /// </summary>
 94        IntKeyDictionary<int> m_DottedLineMaterials;
 95
 96        /// <summary>
 97        ///     An indexed dictionary of all of the draw commands to use with the buffer.
 98        /// </summary>
 99        /// <remarks>
 100        ///     This includes the meshReference and an index of the material to use with that meshReference when drawing
 101        ///     are
 102        ///     added, the <see cref="m_CurrentToken" /> is incremented to simulate a stable ID.
 103        /// </remarks>
 104        IntKeyDictionary<DrawCommand> m_DrawCommands;
 105
 106        /// <summary>
 107        ///     An indexed dictionary of all line materials, referenced by the hashcode of the color.
 108        /// </summary>
 109        IntKeyDictionary<int> m_LineMaterials;
 110
 111        /// <summary>
 112        ///     An ever expanding list of materials used with the <see cref="DebugDrawBuffer" />.
 113        /// </summary>
 114        /// <remarks>
 115        ///     Both <see cref="m_DottedLineMaterials" /> and <see cref="m_LineMaterials" /> store indexes of
 116        ///     <see cref="Material" />s inside of this list.
 117        /// </remarks>
 118        SimpleList<Material> m_Materials;
 119
 120        /// <summary>
 121        ///     A storage of working vertices information indexed based on the hashcode of the material it is meant to
 122        ///     be drawn with.
 123        /// </summary>
 124        IntKeyDictionary<SimpleList<Vector3>> m_WorkingPoints;
 125
 126        /// <summary>
 127        ///     A storage of working segment indices pairs indexed based on the hashcode of the material it is meant to
 128        ///     be drawn with.
 129        /// </summary>
 130        IntKeyDictionary<SimpleList<int>> m_WorkingSegments;
 131
 132        /// <summary>
 133        ///     A storage of working expected tokens of meshes to be created in the future.
 134        /// </summary>
 135        IntKeyDictionary<int> m_WorkingTokens;
 136
 137        /// <summary>
 138        ///     Create a <see cref="DebugDrawBuffer" />.
 139        /// </summary>
 140        /// <param name="key">The internally cached key associated with this buffer.</param>
 141        /// <param name="initialMaterialCount">
 142        ///     An initial allocation of the expected number of materials that will be used.
 143        /// </param>
 144        /// <param name="verticesPerMesh">The number of vertices to ingest before a meshReference is split.</param>
 4145        public DebugDrawBuffer(int key, int initialMaterialCount = 5,
 146            int verticesPerMesh = DefaultMaximumVerticesPerMesh)
 4147        {
 4148            Key = key;
 149
 4150            m_MaximumVerticesPerMesh = verticesPerMesh;
 151
 4152            m_Materials = new SimpleList<Material>(initialMaterialCount);
 4153            m_LineMaterials = new IntKeyDictionary<int>(initialMaterialCount);
 4154            m_DottedLineMaterials = new IntKeyDictionary<int>(initialMaterialCount);
 155
 4156            m_WorkingPoints = new IntKeyDictionary<SimpleList<Vector3>>(initialMaterialCount);
 4157            m_WorkingSegments = new IntKeyDictionary<SimpleList<int>>(initialMaterialCount);
 4158            m_WorkingTokens = new IntKeyDictionary<int>(initialMaterialCount);
 159
 4160            m_DrawCommands = new IntKeyDictionary<DrawCommand>(2);
 4161            m_CurrentToken = 0;
 162
 4163            m_CommandBuffer = new CommandBuffer();
 4164            m_CommandBuffer.name = $"GDX_DebugDrawBuffer_{Key}";
 165
 166            // Make sure our statics have their desired default materials atm
 4167            if (s_LineMaterial == null)
 1168            {
 1169                s_LineMaterial = new Material(RuntimeContent.ResourceProvider.GetShaders().UnlitColor);
 1170            }
 171
 4172            if (s_DottedLineMaterial == null)
 1173            {
 1174                s_DottedLineMaterial = new Material(RuntimeContent.ResourceProvider.GetShaders().DottedLine);
 1175            }
 4176        }
 177
 178        /// <summary>
 179        ///     Has the <see cref="DebugDrawBuffer" /> been converged?
 180        /// </summary>
 181        /// <remarks>
 182        ///     A finalized <see cref="DebugDrawBuffer" /> has had its command buffer filled with the fixed draw calls
 183        ///     based on the meshes/materials outlined. If a meshReference is invalidated by <see cref="Invalidate" />, 
 184        ///     <see cref="DebugDrawBuffer" /> will become not finalized and will re-converge itself next
 185        ///     <see cref="Execute" />.
 186        /// </remarks>
 187        public bool Finalized
 188        {
 0189            get;
 0190            private set;
 191        }
 192
 193        /// <summary>
 194        ///     Converges all working vertices/material additions into finalized meshReference forms and fills the comma
 195        ///     buffer with the appropriate data.
 196        /// </summary>
 197        public void Converge()
 0198        {
 0199            if (Finalized)
 0200            {
 0201                return;
 202            }
 203
 204            //  Finalize each material we have something in process for
 0205            int materialCount = m_Materials.Count;
 0206            for (int i = 0; i < materialCount; i++)
 0207            {
 0208                int materialHashCode = m_Materials.Array[i].GetHashCode();
 209
 210                // We've finalized and have just invalidated, dont want to go through this
 0211                if (!m_WorkingPoints.ContainsKey(materialHashCode))
 0212                {
 0213                    continue;
 214                }
 215
 0216                SimpleList<Vector3> pointList = m_WorkingPoints[materialHashCode];
 0217                SimpleList<int> segmentList = m_WorkingSegments[materialHashCode];
 0218                int token = m_WorkingTokens[materialHashCode];
 0219                if (pointList.Count > 0)
 0220                {
 0221                    AddLineDrawCommand(GetMaterialByHashCode(materialHashCode), ref pointList.Array,
 222                        ref segmentList.Array, token);
 0223                }
 0224            }
 225
 226            // Clear our working memory
 0227            m_WorkingPoints.Clear();
 0228            m_WorkingSegments.Clear();
 0229            m_CommandBuffer.Clear();
 230
 231            // Record our command buffer
 0232            int currentIndex = 0;
 0233            while (m_DrawCommands.MoveNext(ref currentIndex))
 0234            {
 0235                DrawCommand command = m_DrawCommands.Entries[currentIndex - 1].Value;
 236
 0237                m_CommandBuffer.DrawMesh(command.MeshReference, command.Matrix,
 238                    command.MaterialReference, 0, 0);
 0239            }
 240
 0241            Finalized = true;
 0242        }
 243
 244
 245        /// <summary>
 246        ///     Draw a dotted line of a specific color as defined to the buffer.
 247        /// </summary>
 248        /// <remarks>
 249        ///     If multiple lines are being drawn it is much more performant to use
 250        ///     <see cref="DrawDottedLines(UnityEngine.Color,ref UnityEngine.Vector3[],ref int[])" />.
 251        /// </remarks>
 252        /// <param name="color">The color which to draw the dotted line with.</param>
 253        /// <param name="startPoint">The start of the line in world space.</param>
 254        /// <param name="endPoint">The end of the line in world space.</param>
 255        /// <returns>The dotted line's invalidation token.</returns>
 256        public int DrawDottedLine(Color color, Vector3 startPoint, Vector3 endPoint)
 0257        {
 0258            Vector3[] points = { startPoint, endPoint };
 0259            return DrawDottedLines(color, ref points, 0, 2,
 260                ref s_LineSegmentIndices, 0, 2);
 0261        }
 262
 263        /// <summary>
 264        ///     Draw dotted lines of a specific color as defined to the buffer.
 265        /// </summary>
 266        /// <param name="color">The color which to draw the dotted lines with.</param>
 267        /// <param name="vertices">The vertices of the dotted lines.</param>
 268        /// <param name="segments">The segment pairs based on <paramref name="vertices" />.</param>
 269        /// <returns>The dotted lines' invalidation token.</returns>
 270        public int DrawDottedLines(Color color, ref Vector3[] vertices, ref int[] segments)
 0271        {
 0272            return DrawDottedLines(color,
 273                ref vertices, 0, vertices.Length,
 274                ref segments, 0, segments.Length);
 0275        }
 276
 277        /// <summary>
 278        ///     Draw dotted lines of a specific color as defined to the buffer.
 279        /// </summary>
 280        /// <param name="color">The color which to draw the dotted lines with.</param>
 281        /// <param name="vertices">The vertices of the dotted lines.</param>
 282        /// <param name="verticesStartIndex">The index to start at in the <paramref name="vertices" /> array.</param>
 283        /// <param name="verticesLength">The number of elements in the <paramref name="vertices" /> array to use.</param
 284        /// <param name="segments">The segment pairs based on <paramref name="vertices" />.</param>
 285        /// <param name="segmentsStartIndex">The index to start at in the <paramref name="segments" /> array.</param>
 286        /// <param name="segmentsLength">The number of elements in the <paramref name="segments" /> array to use.</param
 287        /// <returns>The dotted lines' invalidation token.</returns>
 288        public int DrawDottedLines(Color color,
 289            ref Vector3[] vertices, int verticesStartIndex, int verticesLength,
 290            ref int[] segments, int segmentsStartIndex, int segmentsLength)
 0291        {
 0292            return DrawLines(GetDottedLineMaterialByColor(color), ref vertices, verticesStartIndex, verticesLength,
 293                ref segments, segmentsStartIndex, segmentsLength);
 0294        }
 295
 296        /// <summary>
 297        ///     Draw a line of a specific color as defined to the buffer.
 298        /// </summary>
 299        /// <remarks>
 300        ///     If multiple lines are being drawn it is much more performant to use
 301        ///     <see cref="DrawLines(UnityEngine.Color,ref UnityEngine.Vector3[],ref int[])" />.
 302        /// </remarks>
 303        /// <param name="color">The color which to draw the line with.</param>
 304        /// <param name="startPoint">The start of the line in world space.</param>
 305        /// <param name="endPoint">The end of the line in world space.</param>
 306        /// <returns>The line's invalidation token.</returns>
 307        public int DrawLine(Color color, Vector3 startPoint, Vector3 endPoint)
 0308        {
 0309            Vector3[] points = { startPoint, endPoint };
 0310            return DrawLines(color, ref points, 0, 2,
 311                ref s_LineSegmentIndices, 0, 2);
 0312        }
 313
 314        /// <summary>
 315        ///     Draw lines of a specific color as defined to the buffer.
 316        /// </summary>
 317        /// <param name="color">The color which to draw the lines with.</param>
 318        /// <param name="vertices">The vertices of the lines.</param>
 319        /// <param name="segments">The segment pairs based on <paramref name="vertices" />.</param>
 320        /// <returns>The lines' invalidation token.</returns>
 321        public int DrawLines(Color color, ref Vector3[] vertices, ref int[] segments)
 0322        {
 0323            return DrawLines(color,
 324                ref vertices, 0, vertices.Length,
 325                ref segments, 0, segments.Length);
 0326        }
 327
 328        /// <summary>
 329        ///     Draw lines of a specific color as defined to the buffer.
 330        /// </summary>
 331        /// <param name="color">The color which to draw the lines with.</param>
 332        /// <param name="vertices">The vertices of the lines.</param>
 333        /// <param name="verticesStartIndex">The index to start at in the <paramref name="vertices" /> array.</param>
 334        /// <param name="verticesLength">The number of elements in the <paramref name="vertices" /> array to use.</param
 335        /// <param name="segments">The segment pairs based on <paramref name="vertices" />.</param>
 336        /// <param name="segmentsStartIndex">The index to start at in the <paramref name="segments" /> array.</param>
 337        /// <param name="segmentsLength">The number of elements in the <paramref name="segments" /> array to use.</param
 338        /// <returns>The lines' invalidation token.</returns>
 339        public int DrawLines(Color color,
 340            ref Vector3[] vertices, int verticesStartIndex, int verticesLength,
 341            ref int[] segments, int segmentsStartIndex, int segmentsLength)
 0342        {
 0343            return DrawLines(GetSolidLineMaterialByColor(color), ref vertices, verticesStartIndex, verticesLength,
 344                ref segments, segmentsStartIndex, segmentsLength);
 0345        }
 346
 347        /// <summary>
 348        ///     Draw lines with a specific material to the buffer.
 349        /// </summary>
 350        /// <param name="material">A <em>potentially</em> unlit material to draw the lines with.</param>
 351        /// <param name="vertices">The vertices of the lines.</param>
 352        /// <param name="verticesStartIndex">The index to start at in the <paramref name="vertices" /> array.</param>
 353        /// <param name="verticesLength">The number of elements in the <paramref name="vertices" /> array to use.</param
 354        /// <param name="segments">The segment pairs based on <paramref name="vertices" />.</param>
 355        /// <param name="segmentsStartIndex">The index to start at in the <paramref name="segments" /> array.</param>
 356        /// <param name="segmentsLength">The number of elements in the <paramref name="segments" /> array to use.</param
 357        /// <returns>The lines' invalidation token.</returns>
 358        public int DrawLines(Material material,
 359            ref Vector3[] vertices, int verticesStartIndex, int verticesLength,
 360            ref int[] segments, int segmentsStartIndex, int segmentsLength)
 0361        {
 0362            if (Finalized)
 0363            {
 364#if UNITY_EDITOR
 0365                Debug.LogWarning("Finalized. You must invalidate the batch before adding anything.");
 366#endif // UNITY_EDITOR
 0367                return -1;
 368            }
 369
 370            // Figure out our identifier for the material we will be drawing against
 0371            int materialHashCode = material.GetHashCode();
 0372            if (!m_Materials.ContainsItem(material))
 0373            {
 0374                m_Materials.AddWithExpandCheck(material);
 0375            }
 376
 0377            if (!m_WorkingPoints.ContainsKey(materialHashCode))
 0378            {
 0379                m_WorkingPoints.AddWithExpandCheck(materialHashCode, new SimpleList<Vector3>(verticesLength));
 0380                m_WorkingSegments.AddWithExpandCheck(materialHashCode, new SimpleList<int>(segmentsLength));
 0381                m_WorkingTokens.AddWithExpandCheck(materialHashCode, ReserveToken());
 0382            }
 383
 384            // Get data storage
 0385            SimpleList<Vector3> pointList = m_WorkingPoints[materialHashCode];
 0386            int token = m_WorkingTokens[materialHashCode];
 387
 388            // Check for meshReference conversion
 0389            if (pointList.Array.Length + verticesLength >= m_MaximumVerticesPerMesh)
 0390            {
 391                // Create meshReference!
 0392                SimpleList<int> segmentList = m_WorkingSegments[materialHashCode];
 0393                AddLineDrawCommand(material, ref pointList.Array, ref segmentList.Array, token);
 394
 395                // Reset storage
 0396                pointList.Clear();
 0397                m_WorkingSegments[materialHashCode] = new SimpleList<int>(segmentList.Array.Length);
 398
 399                // increment token
 0400                token = ReserveToken();
 0401                m_WorkingTokens[materialHashCode] = token;
 0402            }
 403
 0404            int verticesBaseIndex = pointList.Count;
 0405            if (verticesLength > 0)
 0406            {
 0407                pointList.Reserve(verticesLength);
 0408                int verticesStopIndex = verticesStartIndex + verticesLength;
 0409                for (int i = verticesStartIndex; i < verticesStopIndex; i++)
 0410                {
 0411                    pointList.AddUnchecked(vertices[i]);
 0412                }
 413
 0414                m_WorkingPoints[materialHashCode] = pointList;
 0415            }
 416
 0417            if (segmentsLength > 0)
 0418            {
 0419                SimpleList<int> segmentList = m_WorkingSegments[materialHashCode];
 0420                segmentList.Reserve(segmentsLength);
 0421                int segmentsStopIndex = segmentsStartIndex + segmentsLength;
 0422                for (int i = segmentsStartIndex; i < segmentsStopIndex; i++)
 0423                {
 0424                    segmentList.AddUnchecked(verticesBaseIndex + segments[i]);
 0425                }
 426
 0427                m_WorkingSegments[materialHashCode] = segmentList;
 0428            }
 429
 0430            return token;
 0431        }
 432
 433        public int DrawRenderer(MeshRenderer renderer, MeshFilter filter)
 0434        {
 0435            Matrix4x4 matrix = renderer.localToWorldMatrix;
 0436            return DrawMesh(renderer.sharedMaterial, filter.sharedMesh, ref matrix);
 0437        }
 438
 439        public int DrawMesh(Material material, Mesh mesh, ref Matrix4x4 matrix)
 0440        {
 0441            Vector3[] vertices = mesh.vertices;
 0442            int[] triangles = mesh.GetTriangles(0);
 0443            Vector2[] uv0 = mesh.uv;
 444
 0445            return AddMeshDrawCommand(material, ref vertices, ref triangles, ref uv0, ref matrix);
 0446        }
 447
 448        /// <summary>
 449        ///     Execute the <see cref="DebugDrawBuffer" />, rendering its outputs to the screen.
 450        /// </summary>
 451        /// <remarks>
 452        ///     This will finalize the command buffer, converging all data into meshes, etc. In order to change the
 453        ///     buffer, you will need to
 454        /// </remarks>
 455        public void Execute()
 0456        {
 0457            if (!Finalized)
 0458            {
 0459                Converge();
 0460            }
 461
 0462            Graphics.ExecuteCommandBuffer(m_CommandBuffer);
 0463        }
 464
 465        /// <summary>
 466        ///     Get the internal command buffer being used by this <see cref="DebugDrawBuffer" />.
 467        /// </summary>
 468        /// <returns>A <see cref="CommandBuffer" />.</returns>
 469        public CommandBuffer GetBuffer()
 0470        {
 0471            return m_CommandBuffer;
 0472        }
 473
 474        /// <summary>
 475        ///     Is the given <paramref name="token" /> present in the draw commands buffer.
 476        /// </summary>
 477        /// <param name="token">The token of the draw commands to check for.</param>
 478        /// <returns>Returns true if the token is found in the existing draw commands.</returns>
 479        public bool HasToken(int token)
 0480        {
 0481            return m_DrawCommands.ContainsKey(token);
 0482        }
 483
 484        public void Unlock()
 0485        {
 0486            Finalized = false;
 0487        }
 488
 489        /// <summary>
 490        ///     Invalidates a <see cref="DrawCommand" /> based on the provided token, forcing the buffer to be refilled.
 491        /// </summary>
 492        /// <param name="token">The token of the draw commands to invalidate.</param>
 493        public void Invalidate(int token)
 0494        {
 0495            if (m_DrawCommands.TryRemove(token))
 0496            {
 0497                Finalized = false;
 0498            }
 0499        }
 500
 501        /// <summary>
 502        ///     Invalidates the entire <see cref="DebugDrawBuffer" />.
 503        /// </summary>
 504        public void InvalidateAll()
 0505        {
 0506            m_DrawCommands.Clear();
 0507            Finalized = false;
 0508        }
 509
 510        /// <summary>
 511        ///     Move to the next batch for a given dotted line color.
 512        /// </summary>
 513        /// <param name="color">The color which the dotted line is drawn as.</param>
 514        public void NextDottedLineBatch(Color color)
 0515        {
 0516            NextLineBatch(GetDottedLineMaterialByColor(color));
 0517        }
 518
 519        /// <summary>
 520        ///     Move to the next batch for a given line color.
 521        /// </summary>
 522        /// <param name="color">The color which the line is drawn as.</param>
 523        public void NextLineBatch(Color color)
 0524        {
 0525            NextLineBatch(GetSolidLineMaterialByColor(color));
 0526        }
 527
 528        /// <summary>
 529        ///     Move to the next batch for a given material.
 530        /// </summary>
 531        /// <param name="material">The material used by a batch.</param>
 532        public void NextLineBatch(Material material)
 0533        {
 0534            int materialHashCode = material.GetHashCode();
 535
 0536            if (!m_WorkingPoints.ContainsKey(materialHashCode))
 0537            {
 0538                return;
 539            }
 540
 541            // Get data storage
 0542            SimpleList<Vector3> pointList = m_WorkingPoints[materialHashCode];
 0543            int token = m_WorkingTokens[materialHashCode];
 544
 0545            if (pointList.Array.Length > 0)
 0546            {
 547                // Create meshReference!
 0548                SimpleList<int> segmentList = m_WorkingSegments[materialHashCode];
 0549                AddLineDrawCommand(material, ref pointList.Array, ref segmentList.Array, token);
 550
 551                // Reset storage
 0552                m_WorkingSegments[materialHashCode] = new SimpleList<int>(segmentList.Array.Length);
 0553                m_WorkingPoints[materialHashCode] = new SimpleList<Vector3>(pointList.Array.Length);
 0554                m_WorkingTokens[materialHashCode] = ReserveToken();
 0555            }
 0556        }
 557
 558        /// <summary>
 559        ///     Resets the <see cref="DebugDrawBuffer" />, as if it were newly created. However all fields are already
 560        ///     allocating their previous sizes.
 561        /// </summary>
 562        public void Reset()
 0563        {
 0564            m_WorkingPoints.Clear();
 0565            m_WorkingSegments.Clear();
 0566            m_WorkingTokens.Clear();
 567
 0568            m_CurrentToken = 0;
 0569            m_DrawCommands.Clear();
 570
 0571            m_Materials.Clear();
 0572            m_LineMaterials.Clear();
 0573            m_DottedLineMaterials.Clear();
 574
 0575            m_CommandBuffer.Clear();
 576
 0577            Finalized = false;
 0578        }
 579
 580        /// <summary>
 581        ///     Builds a line based meshReference from the given <paramref name="vertices" /> and adds it to the draw bu
 582        /// </summary>
 583        /// <param name="material">The material to use when drawing the created meshReference.</param>
 584        /// <param name="vertices">The vertices of the created meshReference.</param>
 585        /// <param name="segments">The segment pairs based on <paramref name="vertices" />.</param>
 586        /// <param name="token">Force a specific token for the meshReference. Don't use this.</param>
 587        /// <returns>The created meshReference's invalidation token.</returns>
 588        int AddLineDrawCommand(Material material, ref Vector3[] vertices, ref int[] segments, int token = -1)
 0589        {
 0590            Mesh batchMesh = new Mesh { indexFormat = IndexFormat.UInt32 };
 0591            batchMesh.SetVertices(vertices);
 0592            batchMesh.SetIndices(segments, MeshTopology.Lines, 0);
 593
 0594            if (token == -1)
 0595            {
 0596                token = ReserveToken();
 0597            }
 598
 599#if UNITY_EDITOR
 0600            batchMesh.name = $"P_Line_Mesh_{material.name}_{token}";
 601#endif // UNITY_EDITOR
 0602            m_DrawCommands.AddWithExpandCheck(token, new DrawCommand(batchMesh, material));
 0603            return token;
 0604        }
 605
 606        int AddMeshDrawCommand(Material material, ref Vector3[] vertices, ref int[] triangles, ref Vector2[] uv0,
 607            ref Matrix4x4 matrix, int token = -1)
 0608        {
 0609            Mesh batchMesh = new Mesh { indexFormat = IndexFormat.UInt32 };
 610
 0611            batchMesh.SetVertices(vertices);
 0612            batchMesh.SetTriangles(triangles, 0);
 0613            batchMesh.SetUVs(0, uv0);
 0614            batchMesh.RecalculateNormals();
 0615            batchMesh.RecalculateTangents();
 616
 0617            return AddMeshDrawCommand(material, batchMesh, ref matrix, token);
 0618        }
 619
 620        int AddMeshDrawCommand(Material material, Mesh mesh, ref Matrix4x4 matrix, int token = -1)
 0621        {
 0622            if (token == -1)
 0623            {
 0624                token = ReserveToken();
 0625            }
 626
 627#if UNITY_EDITOR
 0628            mesh.name = $"P_Mesh_{material.name}_{token}";
 629#endif // UNITY_EDITOR
 630
 0631            m_DrawCommands.AddWithExpandCheck(token, new DrawCommand(mesh, material, ref matrix));
 0632            return token;
 0633        }
 634
 635
 636        /// <summary>
 637        ///     Gets the cached dotted line material, or creates one for the given <paramref name="color" />.
 638        /// </summary>
 639        /// <param name="color">A defined draw color.</param>
 640        /// <returns>The qualified dotted line material of the color.</returns>
 641        Material GetDottedLineMaterialByColor(Color color)
 0642        {
 0643            int requestedHashCode = color.GetHashCode();
 0644            if (m_DottedLineMaterials.ContainsKey(requestedHashCode))
 0645            {
 0646                return m_Materials.Array[m_DottedLineMaterials[requestedHashCode]];
 647            }
 648
 0649            Material newMaterial = new Material(s_DottedLineMaterial);
 0650            newMaterial.SetColor(ShaderContent.ColorPropertyID, color);
 651
 0652            m_Materials.AddWithExpandCheck(newMaterial);
 0653            m_DottedLineMaterials.AddWithExpandCheck(requestedHashCode, m_Materials.Count - 1);
 0654            return newMaterial;
 0655        }
 656
 657        /// <summary>
 658        ///     Gets a material from the internal cache based on its <see cref="Material.GetHashCode" />.
 659        /// </summary>
 660        /// <remarks>A warning will be thrown in the editor if the material is not found.</remarks>
 661        /// <param name="hashCode">The integer based hash code of the material.</param>
 662        /// <returns>The material if found, otherwise a default material will be returned.</returns>
 663        Material GetMaterialByHashCode(int hashCode)
 0664        {
 0665            int count = m_Materials.Count;
 0666            for (int i = 0; i < count; i++)
 0667            {
 0668                if (m_Materials.Array[i].GetHashCode() == hashCode)
 0669                {
 0670                    return m_Materials.Array[i];
 671                }
 0672            }
 673#if UNITY_EDITOR
 0674            Debug.LogWarning(
 675                "A set of lines have been added to the MergedDraw where the Material hash code that was provided has not
 676#endif // UNITY_EDITOR
 677            // Ensure default material
 0678            m_Materials.AddWithExpandCheck(s_LineMaterial);
 0679            return s_LineMaterial;
 0680        }
 681
 682        /// <summary>
 683        ///     Gets the cached solid line material, or creates one for the given <paramref name="color" />.
 684        /// </summary>
 685        /// <param name="color">A defined draw color.</param>
 686        /// <returns>The qualified line material of the color.</returns>
 687        Material GetSolidLineMaterialByColor(Color color)
 0688        {
 0689            int requestedHashCode = color.GetHashCode();
 0690            if (m_LineMaterials.ContainsKey(requestedHashCode))
 0691            {
 0692                return m_Materials.Array[m_LineMaterials[requestedHashCode]];
 693            }
 694
 0695            Material newMaterial = new Material(s_LineMaterial);
 0696            newMaterial.SetColor(ShaderContent.ColorPropertyID, color);
 697
 0698            m_Materials.AddWithExpandCheck(newMaterial);
 0699            m_LineMaterials.AddWithExpandCheck(requestedHashCode, m_Materials.Count - 1);
 0700            return newMaterial;
 0701        }
 702
 703        int ReserveToken()
 0704        {
 0705            int returnValue = m_CurrentToken;
 0706            m_CurrentToken++;
 0707            return returnValue;
 0708        }
 709
 710        /// <summary>
 711        ///     A structure describing a finalized meshReference/material and its draw operation.
 712        /// </summary>
 713        struct DrawCommand
 714        {
 715            public readonly Mesh MeshReference;
 716            public readonly Matrix4x4 Matrix;
 717            public readonly Material MaterialReference;
 718
 719            public DrawCommand(Mesh meshReference, Material materialReference)
 0720            {
 0721                Matrix = Matrix4x4.identity;
 0722                MaterialReference = materialReference;
 0723                MeshReference = meshReference;
 0724            }
 725
 726            public DrawCommand(Mesh meshReference, Material materialReference, ref Matrix4x4 matrix)
 0727            {
 0728                Matrix = matrix;
 0729                MaterialReference = materialReference;
 0730                MeshReference = meshReference;
 0731            }
 732        }
 733    }
 734}

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&)