| | 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 | |
|
| | 5 | | using Unity.Mathematics; |
| | 6 | | using UnityEngine; |
| | 7 | |
|
| | 8 | | namespace GDX.Experimental |
| | 9 | | { |
| | 10 | | public static class DebugDrawShapes |
| | 11 | | { |
| | 12 | | const float PI = 3.1415927f; |
| | 13 | | const float Deg2Rad = 0.017453292f; |
| | 14 | | const int DefaultCircleVertexCount = 32; |
| | 15 | |
|
| | 16 | | /// <summary> |
| | 17 | | /// The ordered segment index pairs used to describe a cube. |
| | 18 | | /// </summary> |
| | 19 | | /// <remarks> |
| | 20 | | /// This effectively wraps the left side, then the right, then connects the two sides. |
| | 21 | | /// </remarks> |
| 0 | 22 | | public static int[] CubeSegmentIndices = |
| | 23 | | { |
| | 24 | | 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 |
| | 25 | | }; |
| | 26 | |
|
| 0 | 27 | | static readonly Quaternion k_RotationPrimaryTopLoop = Quaternion.Euler(0, 90, 0); |
| 0 | 28 | | static readonly Quaternion k_RotationPrimaryBottomLoop = Quaternion.Euler(0, -90, 180); |
| | 29 | |
|
| 0 | 30 | | static readonly Quaternion k_RotationSecondaryTopLoop = Quaternion.Euler(0, 180, 0); |
| 0 | 31 | | static readonly Quaternion k_RotationSecondaryBottomLoop = Quaternion.Euler(0, 0, 180); |
| | 32 | |
|
| | 33 | |
|
| | 34 | | static void GetCircleVertices(ref Vector3[] vertices, int startIndex, Vector3 center, Quaternion rotation, |
| | 35 | | float radius, int circleVertexCount = DefaultCircleVertexCount) |
| 0 | 36 | | { |
| 0 | 37 | | float radiansInterval = PI * 2f / circleVertexCount; |
| | 38 | |
|
| | 39 | | // Loop through and figure out the points |
| 0 | 40 | | for (int i = 0; i < circleVertexCount; i++) |
| 0 | 41 | | { |
| 0 | 42 | | float angle = i * radiansInterval; |
| | 43 | |
|
| | 44 | | // Create base point |
| 0 | 45 | | vertices[i + startIndex] = |
| | 46 | | rotation * new Vector3(0, math.sin(angle) * radius, math.cos(angle) * radius) + center; |
| 0 | 47 | | } |
| 0 | 48 | | } |
| | 49 | |
|
| | 50 | | static int[] GetCubeSegmentOffset(int offset) |
| 0 | 51 | | { |
| 0 | 52 | | int[] newIndices = new int[24] |
| | 53 | | { |
| | 54 | | CubeSegmentIndices[0] + offset, CubeSegmentIndices[1] + offset, CubeSegmentIndices[2] + offset, |
| | 55 | | CubeSegmentIndices[3] + offset, CubeSegmentIndices[4] + offset, CubeSegmentIndices[5] + offset, |
| | 56 | | CubeSegmentIndices[6] + offset, CubeSegmentIndices[7] + offset, CubeSegmentIndices[8] + offset, |
| | 57 | | CubeSegmentIndices[9] + offset, CubeSegmentIndices[10] + offset, CubeSegmentIndices[11] + offset, |
| | 58 | | CubeSegmentIndices[12] + offset, CubeSegmentIndices[13] + offset, CubeSegmentIndices[14] + offset, |
| | 59 | | CubeSegmentIndices[15] + offset, CubeSegmentIndices[16] + offset, CubeSegmentIndices[17] + offset, |
| | 60 | | CubeSegmentIndices[18] + offset, CubeSegmentIndices[19] + offset, CubeSegmentIndices[20] + offset, |
| | 61 | | CubeSegmentIndices[21] + offset, CubeSegmentIndices[22] + offset, CubeSegmentIndices[23] + offset |
| | 62 | | }; |
| 0 | 63 | | return newIndices; |
| 0 | 64 | | } |
| | 65 | |
|
| | 66 | | static void GetCubeSegmentOffsetNonAlloc(int[] indices, int startIndex, int offset) |
| 0 | 67 | | { |
| 0 | 68 | | indices[startIndex] = CubeSegmentIndices[0] + offset; |
| 0 | 69 | | indices[startIndex + 1] = CubeSegmentIndices[1] + offset; |
| 0 | 70 | | indices[startIndex + 2] = CubeSegmentIndices[2] + offset; |
| 0 | 71 | | indices[startIndex + 3] = CubeSegmentIndices[3] + offset; |
| 0 | 72 | | indices[startIndex + 4] = CubeSegmentIndices[4] + offset; |
| 0 | 73 | | indices[startIndex + 5] = CubeSegmentIndices[5] + offset; |
| 0 | 74 | | indices[startIndex + 6] = CubeSegmentIndices[6] + offset; |
| 0 | 75 | | indices[startIndex + 7] = CubeSegmentIndices[7] + offset; |
| 0 | 76 | | indices[startIndex + 8] = CubeSegmentIndices[8] + offset; |
| 0 | 77 | | indices[startIndex + 9] = CubeSegmentIndices[9] + offset; |
| 0 | 78 | | indices[startIndex + 10] = CubeSegmentIndices[10] + offset; |
| 0 | 79 | | indices[startIndex + 11] = CubeSegmentIndices[11] + offset; |
| 0 | 80 | | indices[startIndex + 12] = CubeSegmentIndices[12] + offset; |
| 0 | 81 | | indices[startIndex + 13] = CubeSegmentIndices[13] + offset; |
| 0 | 82 | | indices[startIndex + 14] = CubeSegmentIndices[14] + offset; |
| 0 | 83 | | indices[startIndex + 15] = CubeSegmentIndices[15] + offset; |
| 0 | 84 | | indices[startIndex + 16] = CubeSegmentIndices[16] + offset; |
| 0 | 85 | | indices[startIndex + 17] = CubeSegmentIndices[17] + offset; |
| 0 | 86 | | indices[startIndex + 18] = CubeSegmentIndices[18] + offset; |
| 0 | 87 | | indices[startIndex + 19] = CubeSegmentIndices[19] + offset; |
| 0 | 88 | | indices[startIndex + 20] = CubeSegmentIndices[20] + offset; |
| 0 | 89 | | indices[startIndex + 21] = CubeSegmentIndices[21] + offset; |
| 0 | 90 | | indices[startIndex + 22] = CubeSegmentIndices[22] + offset; |
| 0 | 91 | | indices[startIndex + 23] = CubeSegmentIndices[23] + offset; |
| 0 | 92 | | } |
| | 93 | |
|
| | 94 | | /// <summary> |
| | 95 | | /// Get the vertices that make up a cube. |
| | 96 | | /// </summary> |
| | 97 | | /// <remarks> |
| | 98 | | /// Ordered based on <see cref="CubeSegmentIndices" />. |
| | 99 | | /// </remarks> |
| | 100 | | /// <param name="center">The world space center location of the cube.</param> |
| | 101 | | /// <param name="size">The size of the cube.</param> |
| | 102 | | /// <returns>An array of ordered vertices.</returns> |
| | 103 | | static Vector3[] GetCubeVertices(Vector3 center, Quaternion rotation, Vector3 size) |
| 0 | 104 | | { |
| 0 | 105 | | Vector3 half = size / 2f; |
| | 106 | |
|
| 0 | 107 | | float centerMinusHalfX = center.x - half.x; |
| 0 | 108 | | float centerMinusHalfY = center.y - half.y; |
| 0 | 109 | | float centerMinusHalfZ = center.z - half.z; |
| 0 | 110 | | float centerPlusHalfX = center.x + half.x; |
| 0 | 111 | | float centerPlusHalfY = center.y + half.y; |
| 0 | 112 | | float centerPlusHalfZ = center.z + half.z; |
| | 113 | |
|
| 0 | 114 | | Vector3[] points = |
| | 115 | | { |
| | 116 | | rotation * new Vector3(centerMinusHalfX, centerMinusHalfY, centerMinusHalfZ), // Front Bottom Left (0) |
| | 117 | | rotation * new Vector3(centerMinusHalfX, centerMinusHalfY, centerPlusHalfZ), // Back Bottom Left (1) |
| | 118 | | rotation * new Vector3(centerMinusHalfX, centerPlusHalfY, centerPlusHalfZ), // Back Top Left (2) |
| | 119 | | rotation * new Vector3(centerMinusHalfX, centerPlusHalfY, centerMinusHalfZ), // Front Top Left (3) |
| | 120 | | rotation * new Vector3(centerPlusHalfX, centerMinusHalfY, centerMinusHalfZ), // Front Bottom Right (4) |
| | 121 | | rotation * new Vector3(centerPlusHalfX, centerMinusHalfY, centerPlusHalfZ), // Back Bottom Right (5) |
| | 122 | | rotation * new Vector3(centerPlusHalfX, centerPlusHalfY, centerPlusHalfZ), // Back Top Right (6) |
| | 123 | | rotation * new Vector3(centerPlusHalfX, centerPlusHalfY, centerMinusHalfZ) // Front Top Right (7) |
| | 124 | | }; |
| | 125 | |
|
| 0 | 126 | | return points; |
| 0 | 127 | | } |
| | 128 | |
|
| | 129 | | static void GetCubeVerticesNonAlloc(ref Vector3[] points, int startIndex, Vector3 center, Quaternion rotation, |
| | 130 | | Vector3 size) |
| 0 | 131 | | { |
| 0 | 132 | | Vector3 half = size / 2f; |
| | 133 | |
|
| 0 | 134 | | float centerMinusHalfX = center.x - half.x; |
| 0 | 135 | | float centerMinusHalfY = center.y - half.y; |
| 0 | 136 | | float centerMinusHalfZ = center.z - half.z; |
| 0 | 137 | | float centerPlusHalfX = center.x + half.x; |
| 0 | 138 | | float centerPlusHalfY = center.y + half.y; |
| 0 | 139 | | float centerPlusHalfZ = center.z + half.z; |
| | 140 | |
|
| 0 | 141 | | points[startIndex] = |
| | 142 | | rotation * new Vector3(centerMinusHalfX, centerMinusHalfY, centerMinusHalfZ); // Front Bottom Left (0) |
| 0 | 143 | | points[startIndex + 1] = |
| | 144 | | rotation * new Vector3(centerMinusHalfX, centerMinusHalfY, centerPlusHalfZ); // Back Bottom Left (1) |
| 0 | 145 | | points[startIndex + 2] = |
| | 146 | | rotation * new Vector3(centerMinusHalfX, centerPlusHalfY, centerPlusHalfZ); // Back Top Left (2) |
| 0 | 147 | | points[startIndex + 3] = |
| | 148 | | rotation * new Vector3(centerMinusHalfX, centerPlusHalfY, centerMinusHalfZ); // Front Top Left (3) |
| 0 | 149 | | points[startIndex + 4] = |
| | 150 | | rotation * new Vector3(centerPlusHalfX, centerMinusHalfY, centerMinusHalfZ); // Front Bottom Right (4) |
| 0 | 151 | | points[startIndex + 5] = |
| | 152 | | rotation * new Vector3(centerPlusHalfX, centerMinusHalfY, centerPlusHalfZ); // Back Bottom Right (5) |
| 0 | 153 | | points[startIndex + 6] = |
| | 154 | | rotation * new Vector3(centerPlusHalfX, centerPlusHalfY, centerPlusHalfZ); // Back Top Right (6) |
| 0 | 155 | | points[startIndex + 7] = |
| | 156 | | rotation * new Vector3(centerPlusHalfX, centerPlusHalfY, centerMinusHalfZ); // Front Top Right (7) |
| 0 | 157 | | } |
| | 158 | |
|
| | 159 | | /// <summary> |
| | 160 | | /// Draw a dotted line cube of a specific color to the buffer. |
| | 161 | | /// </summary> |
| | 162 | | /// <param name="color">The color which to draw the dotted line cube with.</param> |
| | 163 | | /// <param name="center">The center world position of the cube.</param> |
| | 164 | | /// <param name="size">The unit size of the cube</param> |
| | 165 | | /// <returns>The created cube's invalidation token.</returns> |
| | 166 | | public static int DrawDottedCube(this DebugDrawBuffer buffer, Color color, Vector3 center, Quaternion rotation, |
| | 167 | | Vector3 size) |
| 0 | 168 | | { |
| 0 | 169 | | Vector3[] vertices = GetCubeVertices(center, rotation, size); |
| 0 | 170 | | return buffer.DrawDottedLines(color, ref vertices, ref CubeSegmentIndices); |
| 0 | 171 | | } |
| | 172 | |
|
| | 173 | |
|
| | 174 | | public static int DrawWireCapsule(this DebugDrawBuffer buffer, Color color, Vector3 bottomSpherePosition, |
| | 175 | | Vector3 topSpherePosition, Quaternion rotation, float radius, |
| | 176 | | int arcVertexCount = DefaultCircleVertexCount / 2) |
| 0 | 177 | | { |
| | 178 | | // Calculate total vertices |
| 0 | 179 | | int totalVertices = arcVertexCount * 4; |
| | 180 | |
|
| | 181 | | // TODO: add circles? |
| 0 | 182 | | Vector3[] vertices = new Vector3[totalVertices]; |
| 0 | 183 | | float baseAngle = 0f; |
| 0 | 184 | | float arcLength = 180f; |
| 0 | 185 | | int lineCount = arcVertexCount - 1; |
| | 186 | |
|
| 0 | 187 | | int bottomPrimaryStartIndex = arcVertexCount; |
| 0 | 188 | | int topSecondaryStartIndex = bottomPrimaryStartIndex * 2; |
| 0 | 189 | | int bottomSecondaryStartIndex = bottomPrimaryStartIndex * 3; |
| | 190 | |
|
| 0 | 191 | | Quaternion primaryTopRotation = rotation * k_RotationPrimaryTopLoop; |
| 0 | 192 | | Quaternion primaryBottomRotation = rotation * k_RotationPrimaryBottomLoop; |
| 0 | 193 | | Quaternion secondaryTopRotation = rotation * k_RotationSecondaryTopLoop; |
| 0 | 194 | | Quaternion secondaryBottomRotation = rotation * k_RotationSecondaryBottomLoop; |
| | 195 | |
|
| 0 | 196 | | for (int i = 0; i < arcVertexCount; i++) |
| 0 | 197 | | { |
| 0 | 198 | | float currentAngle = Deg2Rad * baseAngle; |
| | 199 | |
|
| 0 | 200 | | Vector3 basePosition = |
| | 201 | | new Vector3(0, Mathf.Sin(currentAngle) * radius, Mathf.Cos(currentAngle) * radius); |
| | 202 | |
|
| 0 | 203 | | vertices[i] = primaryTopRotation * basePosition + topSpherePosition; |
| 0 | 204 | | vertices[i + bottomPrimaryStartIndex] = primaryBottomRotation * basePosition + bottomSpherePosition; |
| | 205 | |
|
| 0 | 206 | | vertices[i + topSecondaryStartIndex] = secondaryTopRotation * basePosition + topSpherePosition; |
| 0 | 207 | | vertices[i + bottomSecondaryStartIndex] = secondaryBottomRotation * basePosition + bottomSpherePosition; |
| | 208 | |
|
| 0 | 209 | | baseAngle += arcLength / lineCount; |
| 0 | 210 | | } |
| | 211 | |
|
| | 212 | |
|
| | 213 | | // Create segment connections |
| 0 | 214 | | int blockSize = lineCount * 2 + 2; |
| 0 | 215 | | int[] segments = new int[blockSize * 4]; |
| | 216 | |
|
| 0 | 217 | | int primaryTopBottomConnectionIndex = blockSize - 2; |
| 0 | 218 | | int primaryBottomTopConnectionIndex = blockSize * 2 - 2; |
| 0 | 219 | | int secondaryTopBottomConnectionIndex = blockSize * 3 - 2; |
| 0 | 220 | | int secondaryBottomTopConnectionIndex = blockSize * 4 - 2; |
| | 221 | |
|
| 0 | 222 | | int segmentCount = segments.Length; |
| 0 | 223 | | int baseCount = 0; |
| | 224 | |
|
| 0 | 225 | | for (int i = 0; i < segmentCount; i += 2) |
| 0 | 226 | | { |
| 0 | 227 | | if (i == primaryTopBottomConnectionIndex || i == primaryBottomTopConnectionIndex || |
| | 228 | | i == secondaryTopBottomConnectionIndex || i == secondaryBottomTopConnectionIndex) |
| 0 | 229 | | { |
| 0 | 230 | | baseCount++; |
| 0 | 231 | | continue; |
| | 232 | | } |
| | 233 | |
|
| 0 | 234 | | segments[i] = baseCount; |
| 0 | 235 | | baseCount++; |
| 0 | 236 | | segments[i + 1] = baseCount; |
| 0 | 237 | | } |
| | 238 | |
|
| 0 | 239 | | segments[primaryTopBottomConnectionIndex] = segments[primaryTopBottomConnectionIndex - 1]; |
| 0 | 240 | | segments[primaryTopBottomConnectionIndex + 1] = segments[primaryTopBottomConnectionIndex + 2]; |
| | 241 | |
|
| 0 | 242 | | segments[primaryBottomTopConnectionIndex] = segments[primaryBottomTopConnectionIndex - 1]; |
| 0 | 243 | | segments[primaryBottomTopConnectionIndex + 1] = segments[0]; |
| | 244 | |
|
| 0 | 245 | | segments[secondaryTopBottomConnectionIndex] = segments[secondaryTopBottomConnectionIndex - 1]; |
| 0 | 246 | | segments[secondaryTopBottomConnectionIndex + 1] = segments[secondaryTopBottomConnectionIndex + 2]; |
| | 247 | |
|
| 0 | 248 | | segments[secondaryBottomTopConnectionIndex] = segments[secondaryBottomTopConnectionIndex - 1]; |
| 0 | 249 | | segments[secondaryBottomTopConnectionIndex + 1] = segments[primaryBottomTopConnectionIndex + 2]; |
| | 250 | |
|
| | 251 | | // Link top to bottom |
| 0 | 252 | | return buffer.DrawLines(color, ref vertices, ref segments); |
| 0 | 253 | | } |
| | 254 | |
|
| | 255 | | public static int DrawWireArc(this DebugDrawBuffer buffer, Color color, Vector3 center, Quaternion rotation, |
| | 256 | | float radius, float startAngle = 0f, float endAngle = 180f, |
| | 257 | | int arcVertexCount = DefaultCircleVertexCount / 2) |
| 0 | 258 | | { |
| | 259 | | // We do the plus one to complete the full arc segment, otherwise it would not be every peice |
| 0 | 260 | | Vector3[] vertices = new Vector3[arcVertexCount]; |
| 0 | 261 | | float baseAngle = startAngle; |
| 0 | 262 | | float arcLength = endAngle - startAngle; |
| 0 | 263 | | int lineCount = arcVertexCount - 1; |
| 0 | 264 | | for (int i = 0; i < arcVertexCount; i++) |
| 0 | 265 | | { |
| 0 | 266 | | float currentAngle = Deg2Rad * baseAngle; |
| 0 | 267 | | vertices[i] = |
| | 268 | | rotation * new Vector3(0, Mathf.Sin(currentAngle) * radius, Mathf.Cos(currentAngle) * radius) + |
| | 269 | | center; |
| 0 | 270 | | baseAngle += arcLength / lineCount; |
| 0 | 271 | | } |
| | 272 | |
|
| | 273 | | // Create segment connections |
| 0 | 274 | | int[] segments = new int[lineCount * 2]; |
| 0 | 275 | | int segmentCount = segments.Length; |
| 0 | 276 | | int baseCount = 0; |
| 0 | 277 | | for (int i = 0; i < segmentCount; i += 2) |
| 0 | 278 | | { |
| 0 | 279 | | segments[i] = baseCount; |
| 0 | 280 | | baseCount++; |
| 0 | 281 | | segments[i + 1] = baseCount; |
| 0 | 282 | | } |
| | 283 | |
|
| 0 | 284 | | return buffer.DrawLines(color, ref vertices, ref segments); |
| 0 | 285 | | } |
| | 286 | |
|
| | 287 | | public static int DrawWireCircle(this DebugDrawBuffer buffer, Color color, Vector3 center, Quaternion rotation, |
| | 288 | | float radius, int circleVertexCount = DefaultCircleVertexCount) |
| 0 | 289 | | { |
| 0 | 290 | | Vector3[] vertices = new Vector3[circleVertexCount]; |
| 0 | 291 | | float radiansInterval = PI * 2f / circleVertexCount; |
| | 292 | |
|
| | 293 | | // Loop through and figure out the points |
| 0 | 294 | | for (int i = 0; i < circleVertexCount; i++) |
| 0 | 295 | | { |
| 0 | 296 | | float angle = i * radiansInterval; |
| | 297 | |
|
| | 298 | | // Create base point |
| 0 | 299 | | vertices[i] = rotation * new Vector3(0, math.sin(angle) * radius, math.cos(angle) * radius) + center; |
| 0 | 300 | | } |
| | 301 | |
|
| 0 | 302 | | int[] segments = new int[circleVertexCount * 2]; |
| 0 | 303 | | int segmentCount = segments.Length; |
| 0 | 304 | | int baseCount = 0; |
| | 305 | |
|
| 0 | 306 | | for (int i = 0; i < segmentCount; i += 2) |
| 0 | 307 | | { |
| 0 | 308 | | segments[i] = baseCount; |
| 0 | 309 | | baseCount++; |
| 0 | 310 | | segments[i + 1] = baseCount; |
| 0 | 311 | | } |
| | 312 | |
|
| 0 | 313 | | segments[segmentCount - 1] = 0; |
| | 314 | |
|
| 0 | 315 | | return buffer.DrawLines(color, ref vertices, ref segments); |
| 0 | 316 | | } |
| | 317 | |
|
| | 318 | | /// <summary> |
| | 319 | | /// Draw a wireframe cube of a specific color to the buffer. |
| | 320 | | /// </summary> |
| | 321 | | /// <param name="color">The color which to draw the wire cube with.</param> |
| | 322 | | /// <param name="center">The center world position of the cube.</param> |
| | 323 | | /// <param name="size">The unit size of the cube</param> |
| | 324 | | /// <returns>The created cube's invalidation token.</returns> |
| | 325 | | public static int DrawWireCube(this DebugDrawBuffer buffer, Color color, Vector3 center, Quaternion rotation, |
| | 326 | | Vector3 size) |
| 0 | 327 | | { |
| 0 | 328 | | Vector3[] vertices = GetCubeVertices(center, rotation, size); |
| 0 | 329 | | return buffer.DrawLines(color, ref vertices, ref CubeSegmentIndices); |
| 0 | 330 | | } |
| | 331 | |
|
| | 332 | | public static int DrawWireSphere(this DebugDrawBuffer buffer, Color color, Vector3 center, Quaternion rotation, |
| | 333 | | float radius, int circleVertexCount = DefaultCircleVertexCount) |
| 0 | 334 | | { |
| 0 | 335 | | int pointCount = circleVertexCount * 2; |
| 0 | 336 | | Vector3[] vertices = new Vector3[pointCount]; |
| | 337 | |
|
| 0 | 338 | | float radiansInterval = PI * 2f / circleVertexCount; |
| 0 | 339 | | Quaternion xRotation = Space.Axis.X.ToRotation() * rotation; |
| 0 | 340 | | Quaternion yRotation = Space.Axis.Y.ToRotation() * rotation; |
| | 341 | |
|
| | 342 | | // Loop through and figure out the points |
| 0 | 343 | | for (int i = 0; i < circleVertexCount; i++) |
| 0 | 344 | | { |
| 0 | 345 | | float angle = i * radiansInterval; |
| | 346 | |
|
| | 347 | | // Create base points |
| 0 | 348 | | vertices[i] = xRotation * new Vector3(0, math.sin(angle) * radius, math.cos(angle) * radius) + center; |
| 0 | 349 | | vertices[i + circleVertexCount] = |
| | 350 | | yRotation * new Vector3(0, math.sin(angle) * radius, math.cos(angle) * radius) + center; |
| 0 | 351 | | } |
| | 352 | |
|
| | 353 | | // Create segment connections |
| 0 | 354 | | int[] segments = new int[pointCount * 2]; |
| 0 | 355 | | int segmentCount = segments.Length; |
| 0 | 356 | | int baseCount = 0; |
| 0 | 357 | | for (int i = 0; i < segmentCount; i += 2) |
| 0 | 358 | | { |
| 0 | 359 | | segments[i] = baseCount; |
| 0 | 360 | | baseCount++; |
| 0 | 361 | | segments[i + 1] = baseCount; |
| 0 | 362 | | } |
| | 363 | |
|
| 0 | 364 | | segments[pointCount - 1] = 0; |
| 0 | 365 | | segments[segmentCount - 1] = circleVertexCount; |
| | 366 | |
|
| 0 | 367 | | return buffer.DrawLines(color, ref vertices, ref segments); |
| 0 | 368 | | } |
| | 369 | | } |
| | 370 | | } |