voxelarea.lua 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. VoxelArea = {
  2. MinEdge = {x=1, y=1, z=1},
  3. MaxEdge = {x=0, y=0, z=0},
  4. ystride = 0,
  5. zstride = 0,
  6. }
  7. function VoxelArea:new(o)
  8. o = o or {}
  9. setmetatable(o, self)
  10. self.__index = self
  11. local e = o:getExtent()
  12. o.ystride = e.x
  13. o.zstride = e.x * e.y
  14. return o
  15. end
  16. function VoxelArea:getExtent()
  17. local MaxEdge, MinEdge = self.MaxEdge, self.MinEdge
  18. return {
  19. x = MaxEdge.x - MinEdge.x + 1,
  20. y = MaxEdge.y - MinEdge.y + 1,
  21. z = MaxEdge.z - MinEdge.z + 1,
  22. }
  23. end
  24. function VoxelArea:getVolume()
  25. local e = self:getExtent()
  26. return e.x * e.y * e.z
  27. end
  28. function VoxelArea:index(x, y, z)
  29. local MinEdge = self.MinEdge
  30. local i = (z - MinEdge.z) * self.zstride +
  31. (y - MinEdge.y) * self.ystride +
  32. (x - MinEdge.x) + 1
  33. return math.floor(i)
  34. end
  35. function VoxelArea:indexp(p)
  36. local MinEdge = self.MinEdge
  37. local i = (p.z - MinEdge.z) * self.zstride +
  38. (p.y - MinEdge.y) * self.ystride +
  39. (p.x - MinEdge.x) + 1
  40. return math.floor(i)
  41. end
  42. function VoxelArea:position(i)
  43. local p = {}
  44. local MinEdge = self.MinEdge
  45. i = i - 1
  46. p.z = math.floor(i / self.zstride) + MinEdge.z
  47. i = i % self.zstride
  48. p.y = math.floor(i / self.ystride) + MinEdge.y
  49. i = i % self.ystride
  50. p.x = math.floor(i) + MinEdge.x
  51. return p
  52. end
  53. function VoxelArea:contains(x, y, z)
  54. local MaxEdge, MinEdge = self.MaxEdge, self.MinEdge
  55. return (x >= MinEdge.x) and (x <= MaxEdge.x) and
  56. (y >= MinEdge.y) and (y <= MaxEdge.y) and
  57. (z >= MinEdge.z) and (z <= MaxEdge.z)
  58. end
  59. function VoxelArea:containsp(p)
  60. local MaxEdge, MinEdge = self.MaxEdge, self.MinEdge
  61. return (p.x >= MinEdge.x) and (p.x <= MaxEdge.x) and
  62. (p.y >= MinEdge.y) and (p.y <= MaxEdge.y) and
  63. (p.z >= MinEdge.z) and (p.z <= MaxEdge.z)
  64. end
  65. function VoxelArea:containsi(i)
  66. return (i >= 1) and (i <= self:getVolume())
  67. end
  68. function VoxelArea:iter(minx, miny, minz, maxx, maxy, maxz)
  69. local i = self:index(minx, miny, minz) - 1
  70. local last = self:index(maxx, maxy, maxz)
  71. local ystride = self.ystride
  72. local zstride = self.zstride
  73. local yoff = (last+1) % ystride
  74. local zoff = (last+1) % zstride
  75. local ystridediff = (i - last) % ystride
  76. local zstridediff = (i - last) % zstride
  77. return function()
  78. i = i + 1
  79. if i % zstride == zoff then
  80. i = i + zstridediff
  81. elseif i % ystride == yoff then
  82. i = i + ystridediff
  83. end
  84. if i <= last then
  85. return i
  86. end
  87. end
  88. end
  89. function VoxelArea:iterp(minp, maxp)
  90. return self:iter(minp.x, minp.y, minp.z, maxp.x, maxp.y, maxp.z)
  91. end