voxelarea.lua 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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. return {
  18. x = self.MaxEdge.x - self.MinEdge.x + 1,
  19. y = self.MaxEdge.y - self.MinEdge.y + 1,
  20. z = self.MaxEdge.z - self.MinEdge.z + 1,
  21. }
  22. end
  23. function VoxelArea:getVolume()
  24. local e = self:getExtent()
  25. return e.x * e.y * e.z
  26. end
  27. function VoxelArea:index(x, y, z)
  28. local i = (z - self.MinEdge.z) * self.zstride +
  29. (y - self.MinEdge.y) * self.ystride +
  30. (x - self.MinEdge.x) + 1
  31. return math.floor(i)
  32. end
  33. function VoxelArea:indexp(p)
  34. local i = (p.z - self.MinEdge.z) * self.zstride +
  35. (p.y - self.MinEdge.y) * self.ystride +
  36. (p.x - self.MinEdge.x) + 1
  37. return math.floor(i)
  38. end
  39. function VoxelArea:position(i)
  40. local p = {}
  41. i = i - 1
  42. p.z = math.floor(i / self.zstride) + self.MinEdge.z
  43. i = i % self.zstride
  44. p.y = math.floor(i / self.ystride) + self.MinEdge.y
  45. i = i % self.ystride
  46. p.x = math.floor(i) + self.MinEdge.x
  47. return p
  48. end
  49. function VoxelArea:contains(x, y, z)
  50. return (x >= self.MinEdge.x) and (x <= self.MaxEdge.x) and
  51. (y >= self.MinEdge.y) and (y <= self.MaxEdge.y) and
  52. (z >= self.MinEdge.z) and (z <= self.MaxEdge.z)
  53. end
  54. function VoxelArea:containsp(p)
  55. return (p.x >= self.MinEdge.x) and (p.x <= self.MaxEdge.x) and
  56. (p.y >= self.MinEdge.y) and (p.y <= self.MaxEdge.y) and
  57. (p.z >= self.MinEdge.z) and (p.z <= self.MaxEdge.z)
  58. end
  59. function VoxelArea:containsi(i)
  60. return (i >= 1) and (i <= self:getVolume())
  61. end
  62. function VoxelArea:iter(minx, miny, minz, maxx, maxy, maxz)
  63. local i = self:index(minx, miny, minz) - 1
  64. local last = self:index(maxx, maxy, maxz)
  65. local ystride = self.ystride
  66. local zstride = self.zstride
  67. local yoff = (last+1) % ystride
  68. local zoff = (last+1) % zstride
  69. local ystridediff = (i - last) % ystride
  70. local zstridediff = (i - last) % zstride
  71. return function()
  72. i = i + 1
  73. if i % zstride == zoff then
  74. i = i + zstridediff
  75. elseif i % ystride == yoff then
  76. i = i + ystridediff
  77. end
  78. if i <= last then
  79. return i
  80. end
  81. end
  82. end
  83. function VoxelArea:iterp(minp, maxp)
  84. return self:iter(minp.x, minp.y, minp.z, maxp.x, maxp.y, maxp.z)
  85. end