源战役客户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

187 lines
3.8 KiB

  1. local rawget = rawget
  2. local setmetatable = setmetatable
  3. local type = type
  4. local Vector3 = Vector3
  5. local zero = Vector3.zero
  6. local Bounds = {}
  7. local get = tolua.initget(Bounds)
  8. Bounds.__index = function(t,k)
  9. local var = rawget(Bounds, k)
  10. if var == nil then
  11. var = rawget(get, k)
  12. if var ~= nil then
  13. return var(t)
  14. end
  15. end
  16. return var
  17. end
  18. Bounds.__call = function(t, center, size)
  19. return Bounds.New(center, size)
  20. end
  21. function Bounds.New(center, size)
  22. local bd = {}
  23. bd.center = center
  24. bd.extents = size * 0.5
  25. setmetatable(bd, Bounds)
  26. return bd
  27. end
  28. function Bounds:Get()
  29. local size = self:GetSize()
  30. return self.center, size
  31. end
  32. function Bounds:GetSize()
  33. return self.extents * 2
  34. end
  35. function Bounds:SetSize(value)
  36. self.extents = value * 0.5
  37. end
  38. function Bounds:GetMin()
  39. return self.center - self.extents
  40. end
  41. function Bounds:SetMin(value)
  42. self:SetMinMax(value, self:GetMax())
  43. end
  44. function Bounds:GetMax()
  45. return self.center + self.extents
  46. end
  47. function Bounds:SetMax(value)
  48. self:SetMinMax(self:GetMin(), value)
  49. end
  50. function Bounds:SetMinMax(min, max)
  51. self.extents = (max - min) * 0.5
  52. self.center = min + self.extents
  53. end
  54. function Bounds:Encapsulate(point)
  55. self:SetMinMax(Vector3.Min(self:GetMin(), point), Vector3.Max(self:GetMax(), point))
  56. end
  57. function Bounds:Expand(amount)
  58. local t = type(amount)
  59. if t == "number" then
  60. amount = amount * 0.5
  61. self.extents:Add(Vector3.New(amount, amount, amount))
  62. else
  63. self.extents:Add(amount * 0.5)
  64. end
  65. end
  66. function Bounds:Intersects(bounds)
  67. local min = self:GetMin()
  68. local max = self:GetMax()
  69. local min2 = bounds:GetMin()
  70. local max2 = bounds:GetMax()
  71. return min.x <= max2.x and max.x >= min2.x and min.y <= max2.y and max.y >= min2.y and min.z <= max2.z and max.z >= min2.z
  72. end
  73. function Bounds:Contains(p)
  74. local min = self:GetMin()
  75. local max = self:GetMax()
  76. if p.x < min.x or p.y < min.y or p.z < min.z or p.x > max.x or p.y > max.y or p.z > max.z then
  77. return false
  78. end
  79. return true
  80. end
  81. function Bounds:IntersectRay(ray)
  82. local tmin = -Mathf.Infinity
  83. local tmax = Mathf.Infinity
  84. local t0, t1, f
  85. local t = self:GetCenter () - ray:GetOrigin()
  86. local p = {t.x, t.y, t.z}
  87. t = self.extents
  88. local extent = {t.x, t.y, t.z}
  89. t = ray:GetDirection()
  90. local dir = {t.x, t.y, t.z}
  91. for i = 1, 3 do
  92. f = 1 / dir[i]
  93. t0 = (p[i] + extent[i]) * f
  94. t1 = (p[i] - extent[i]) * f
  95. if t0 < t1 then
  96. if t0 > tmin then tmin = t0 end
  97. if t1 < tmax then tmax = t1 end
  98. if tmin > tmax then return false end
  99. if tmax < 0 then return false end
  100. else
  101. if t1 > tmin then tmin = t1 end
  102. if t0 < tmax then tmax = t0 end
  103. if tmin > tmax then return false end
  104. if tmax < 0 then return false end
  105. end
  106. end
  107. return true, tmin
  108. end
  109. function Bounds:ClosestPoint(point)
  110. local t = point - self:GetCenter()
  111. local closest = {t.x, t.y, t.z}
  112. local et = self.extents
  113. local extent = {et.x, et.y, et.z}
  114. local distance = 0
  115. local delta
  116. for i = 1, 3 do
  117. if closest[i] < - extent[i] then
  118. delta = closest[i] + extent[i]
  119. distance = distance + delta * delta
  120. closest[i] = -extent[i]
  121. elseif closest[i] > extent[i] then
  122. fDelta = closest[i] - extent[i]
  123. distance = distance + delta * delta
  124. closest[i] = extent[i]
  125. end
  126. end
  127. if distance == 0 then
  128. return rkPoint, 0
  129. else
  130. outPoint = closest + self:GetCenter()
  131. return outPoint, distance
  132. end
  133. end
  134. function Bounds:Destroy()
  135. self.center = nil
  136. self.size = nil
  137. end
  138. Bounds.__tostring = function(self)
  139. return string.format("Center: %s, Extents %s", tostring(self.center), tostring(self.extents))
  140. end
  141. Bounds.__eq = function(a, b)
  142. return a.center == b.center and a.extents == b.extents
  143. end
  144. get.size = Bounds.GetSize
  145. get.min = Bounds.GetMin
  146. get.max = Bounds.GetMax
  147. UnityEngine.Bounds = Bounds
  148. setmetatable(Bounds, Bounds)
  149. return Bounds