FlagTable.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. using System;
  2. using UnityEngine;
  3. using UnityEngine.Assertions;
  4. namespace VoxelImporter
  5. {
  6. public class FlagTable3
  7. {
  8. public FlagTable3(int reserveX = 0, int reserveY = 0, int reserveZ = 0)
  9. {
  10. reserve = new IntVector3(reserveX, reserveY, reserveZ);
  11. }
  12. public void Set(int x, int y, int z, bool flag)
  13. {
  14. Assert.IsTrue(x >= 0 && y >= 0 && z >= 0);
  15. int bIndex = Mathf.FloorToInt(z / 64f);
  16. var cIndex = z % 64;
  17. if(!flag)
  18. {
  19. if (table == null || x >= table.Length) return;
  20. if (table[x] == null || y >= table[x].Length) return;
  21. if (table[x][y] == null || bIndex >= table[x][y].Length) return;
  22. }
  23. #region Alloc
  24. reserve = IntVector3.Max(reserve, new IntVector3(x + 1, y + 1, z + 1));
  25. if (table == null)
  26. {
  27. table = new UInt64[reserve.x][][];
  28. }
  29. if (x >= table.Length)
  30. {
  31. var newTmp = new UInt64[x + 1][][];
  32. table.CopyTo(newTmp, 0);
  33. table = newTmp;
  34. }
  35. if(table[x] == null)
  36. {
  37. table[x] = new UInt64[reserve.y][];
  38. }
  39. if (y >= table[x].Length)
  40. {
  41. var newTmp = new UInt64[y + 1][];
  42. table[x].CopyTo(newTmp, 0);
  43. table[x] = newTmp;
  44. }
  45. if (table[x][y] == null)
  46. {
  47. table[x][y] = new UInt64[reserve.z];
  48. }
  49. if (bIndex >= table[x][y].Length)
  50. {
  51. var newTmp = new UInt64[bufferSize];
  52. table[x][y].CopyTo(newTmp, 0);
  53. table[x][y] = newTmp;
  54. }
  55. #endregion
  56. if (flag)
  57. table[x][y][bIndex] |= ((UInt64)1 << cIndex);
  58. else
  59. table[x][y][bIndex] &= ~((UInt64)1 << cIndex);
  60. }
  61. public void Set(IntVector3 pos, bool flag)
  62. {
  63. Set(pos.x, pos.y, pos.z, flag);
  64. }
  65. public bool Get(int x, int y, int z)
  66. {
  67. var bIndex = Mathf.FloorToInt(z / 64f);
  68. var cIndex = z % 64;
  69. if (table == null || x < 0 || x >= table.Length) return false;
  70. if (table[x] == null || y < 0 || y >= table[x].Length) return false;
  71. if (table[x][y] == null || bIndex < 0 || bIndex >= table[x][y].Length) return false;
  72. return (table[x][y][bIndex] & ((UInt64)1 << cIndex)) != 0;
  73. }
  74. public bool Get(IntVector3 pos)
  75. {
  76. return Get(pos.x, pos.y, pos.z);
  77. }
  78. public void Clear()
  79. {
  80. table = null;
  81. }
  82. public void AllAction(Action<int, int, int> action)
  83. {
  84. if (table == null) return;
  85. for (int x = 0; x < table.Length; x++)
  86. {
  87. if (table[x] == null) continue;
  88. for (int y = 0; y < table[x].Length; y++)
  89. {
  90. if (table[x][y] == null) continue;
  91. for (int bz = 0; bz < table[x][y].Length; bz++)
  92. {
  93. for (int i = 0; i < 64; i++)
  94. {
  95. var z = bz * 64 + i;
  96. if (Get(x, y, z))
  97. {
  98. action(x, y, z);
  99. }
  100. }
  101. }
  102. }
  103. }
  104. }
  105. private int bufferSize { get { return Mathf.CeilToInt(reserve.z / 64f); } }
  106. private IntVector3 reserve;
  107. private UInt64[][][] table;
  108. }
  109. }