|  |  | 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 System; | 
|  |  | 6 |  | using System.Runtime.CompilerServices; | 
|  |  | 7 |  | using Unity.Mathematics; | 
|  |  | 8 |  |  | 
|  |  | 9 |  | namespace GDX.Collections.Generic | 
|  |  | 10 |  | { | 
|  |  | 11 |  |     /// <summary> | 
|  |  | 12 |  |     ///     A uniform three-dimensional array. | 
|  |  | 13 |  |     /// </summary> | 
|  |  | 14 |  |     /// <typeparam name="T">Type of objects.</typeparam> | 
|  |  | 15 |  |     public struct UniformArray3D<T> : IDisposable | 
|  |  | 16 |  |     { | 
|  |  | 17 |  |         /// <summary> | 
|  |  | 18 |  |         ///     The backing <see cref="Array" />. | 
|  |  | 19 |  |         /// </summary> | 
|  |  | 20 |  |         public T[] Array; | 
|  |  | 21 |  |  | 
|  |  | 22 |  |         /// <summary> | 
|  |  | 23 |  |         ///     The length of <see cref="Array" />. | 
|  |  | 24 |  |         /// </summary> | 
|  |  | 25 |  |         public readonly int Length; | 
|  |  | 26 |  |  | 
|  |  | 27 |  |         /// <summary> | 
|  |  | 28 |  |         ///     The stride of each dimensional segment in <see cref="Array" />. | 
|  |  | 29 |  |         /// </summary> | 
|  |  | 30 |  |         public readonly int Stride; | 
|  |  | 31 |  |  | 
|  |  | 32 |  |         /// <summary> | 
|  |  | 33 |  |         ///     Stores a cached copy of the stride squared. | 
|  |  | 34 |  |         /// </summary> | 
|  |  | 35 |  |         public readonly int StrideSquared; | 
|  |  | 36 |  |  | 
|  |  | 37 |  |         /// <summary> | 
|  |  | 38 |  |         ///     Create a <see cref="UniformArray3D{T}" /> with a uniform dimensional length. | 
|  |  | 39 |  |         /// </summary> | 
|  |  | 40 |  |         /// <remarks></remarks> | 
|  |  | 41 |  |         /// <param name="stride">X length, Y length and Z length will all be set to this value.</param> | 
|  |  | 42 |  |         public UniformArray3D(int stride) | 
|  | 2 | 43 |  |         { | 
|  | 2 | 44 |  |             Stride = stride; | 
|  | 2 | 45 |  |             StrideSquared = stride * stride; | 
|  | 2 | 46 |  |             Length = StrideSquared * stride; | 
|  |  | 47 |  |  | 
|  | 2 | 48 |  |             Array = new T[Length]; | 
|  | 2 | 49 |  |         } | 
|  |  | 50 |  |  | 
|  |  | 51 |  |         /// <summary> | 
|  |  | 52 |  |         ///     Access a specific location in the voxel. | 
|  |  | 53 |  |         /// </summary> | 
|  |  | 54 |  |         /// <remarks>x + WIDTH * (y + DEPTH * z)</remarks> | 
|  |  | 55 |  |         /// <param name="x">X location index.</param> | 
|  |  | 56 |  |         /// <param name="y">Y location index.</param> | 
|  |  | 57 |  |         /// <param name="z">Z location index.</param> | 
|  |  | 58 |  |         public T this[int x, int y, int z] | 
|  |  | 59 |  |         { | 
|  |  | 60 |  |             [MethodImpl(MethodImplOptions.AggressiveInlining)] | 
|  | 1 | 61 |  |             get => Array[z * StrideSquared + y * Stride + x]; | 
|  |  | 62 |  |  | 
|  |  | 63 |  |             [MethodImpl(MethodImplOptions.AggressiveInlining)] | 
|  | 0 | 64 |  |             set => Array[z * StrideSquared + y * Stride + x] = value; | 
|  |  | 65 |  |         } | 
|  |  | 66 |  |  | 
|  |  | 67 |  |  | 
|  |  | 68 |  |         /// <summary> | 
|  |  | 69 |  |         ///     Access a specific location in the voxel. | 
|  |  | 70 |  |         /// </summary> | 
|  |  | 71 |  |         /// <param name="index">A three-dimensional index.</param> | 
|  |  | 72 |  |         public T this[int3 index] | 
|  |  | 73 |  |         { | 
|  |  | 74 |  |             [MethodImpl(MethodImplOptions.AggressiveInlining)] | 
|  | 0 | 75 |  |             get => Array[index.z * StrideSquared + index.y * Stride + index.x]; | 
|  |  | 76 |  |  | 
|  |  | 77 |  |             [MethodImpl(MethodImplOptions.AggressiveInlining)] | 
|  | 0 | 78 |  |             set => Array[index.z * StrideSquared + index.y * Stride + index.x] = value; | 
|  |  | 79 |  |         } | 
|  |  | 80 |  |  | 
|  |  | 81 |  |         /// <summary> | 
|  |  | 82 |  |         ///     Properly dispose of the <see cref="UniformArray3D{T}" />. | 
|  |  | 83 |  |         /// </summary> | 
|  |  | 84 |  |         public void Dispose() | 
|  | 0 | 85 |  |         { | 
|  | 0 | 86 |  |             Array = default; | 
|  | 0 | 87 |  |         } | 
|  |  | 88 |  |  | 
|  |  | 89 |  |         /// <summary> | 
|  |  | 90 |  |         ///     Get the three-dimensional index of a flat array index. | 
|  |  | 91 |  |         /// </summary> | 
|  |  | 92 |  |         /// <param name="index">A flat array index.</param> | 
|  |  | 93 |  |         /// <returns>A three-dimensional voxel index.</returns> | 
|  |  | 94 |  |         public int3 GetFromIndex(int index) | 
|  | 0 | 95 |  |         { | 
|  | 0 | 96 |  |             int x = index % Stride; | 
|  | 0 | 97 |  |             int y = (index - x) / Stride % Stride; | 
|  | 0 | 98 |  |             int z = (index - x - Stride * y) / StrideSquared; | 
|  | 0 | 99 |  |             return new int3(x, y, z); | 
|  | 0 | 100 |  |         } | 
|  |  | 101 |  |  | 
|  |  | 102 |  |         /// <summary> | 
|  |  | 103 |  |         ///     Get the three-dimensional index of a flat array index. | 
|  |  | 104 |  |         /// </summary> | 
|  |  | 105 |  |         /// <param name="index">A flat array index.</param> | 
|  |  | 106 |  |         /// <param name="stride">The predetermined length of an axis.</param> | 
|  |  | 107 |  |         /// <param name="strideSquared">The squared value of <paramref name="stride" />.</param> | 
|  |  | 108 |  |         /// <returns>A three-dimensional voxel index.</returns> | 
|  |  | 109 |  |         public static int3 GetFromIndex(int index, int stride, int strideSquared) | 
|  | 0 | 110 |  |         { | 
|  | 0 | 111 |  |             int x = index % stride; | 
|  | 0 | 112 |  |             int y = (index - x) / stride % stride; | 
|  | 0 | 113 |  |             int z = (index - x - stride * y) / strideSquared; | 
|  | 0 | 114 |  |             return new int3(x, y, z); | 
|  | 0 | 115 |  |         } | 
|  |  | 116 |  |     } | 
|  |  | 117 |  | } |