miduo_client/Assets/ManagedResources/~Lua/UnityEngine/Bounds.lua

191 lines
4.2 KiB
Lua

--------------------------------------------------------------------------------
-- Copyright (c) 2015 - 2016 , 蒙占志(topameng) topameng@gmail.com
-- All rights reserved.
-- Use, modification and distribution are subject to the "MIT License"
--------------------------------------------------------------------------------
local rawget = rawget
local setmetatable = setmetatable
local type = type
local Vector3 = Vector3
local zero = Vector3.zero
local Bounds =
{
center = Vector3.zero,
extents = Vector3.zero,
}
local get = tolua.initget(Bounds)
Bounds.__index = function(t,k)
local var = rawget(Bounds, k)
if var == nil then
var = rawget(get, k)
if var ~= nil then
return var(t)
end
end
return var
end
Bounds.__call = function(t, center, size)
return setmetatable({center = center, extents = size * 0.5}, Bounds)
end
function Bounds.New(center, size)
return setmetatable({center = center, extents = size * 0.5}, Bounds)
end
function Bounds:Get()
local size = self:GetSize()
return self.center, size
end
function Bounds:GetSize()
return self.extents * 2
end
function Bounds:SetSize(value)
self.extents = value * 0.5
end
function Bounds:GetMin()
return self.center - self.extents
end
function Bounds:SetMin(value)
self:SetMinMax(value, self:GetMax())
end
function Bounds:GetMax()
return self.center + self.extents
end
function Bounds:SetMax(value)
self:SetMinMax(self:GetMin(), value)
end
function Bounds:SetMinMax(min, max)
self.extents = (max - min) * 0.5
self.center = min + self.extents
end
function Bounds:Encapsulate(point)
self:SetMinMax(Vector3.Min(self:GetMin(), point), Vector3.Max(self:GetMax(), point))
end
function Bounds:Expand(amount)
if type(amount) == "number" then
amount = amount * 0.5
self.extents:Add(Vector3.New(amount, amount, amount))
else
self.extents:Add(amount * 0.5)
end
end
function Bounds:Intersects(bounds)
local min = self:GetMin()
local max = self:GetMax()
local min2 = bounds:GetMin()
local max2 = bounds:GetMax()
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
end
function Bounds:Contains(p)
local min = self:GetMin()
local max = self:GetMax()
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
return false
end
return true
end
function Bounds:IntersectRay(ray)
local tmin = -Mathf.Infinity
local tmax = Mathf.Infinity
local t0, t1, f
local t = self:GetCenter () - ray:GetOrigin()
local p = {t.x, t.y, t.z}
t = self.extents
local extent = {t.x, t.y, t.z}
t = ray:GetDirection()
local dir = {t.x, t.y, t.z}
for i = 1, 3 do
f = 1 / dir[i]
t0 = (p[i] + extent[i]) * f
t1 = (p[i] - extent[i]) * f
if t0 < t1 then
if t0 > tmin then tmin = t0 end
if t1 < tmax then tmax = t1 end
if tmin > tmax then return false end
if tmax < 0 then return false end
else
if t1 > tmin then tmin = t1 end
if t0 < tmax then tmax = t0 end
if tmin > tmax then return false end
if tmax < 0 then return false end
end
end
return true, tmin
end
function Bounds:ClosestPoint(point)
local t = point - self:GetCenter()
local closest = {t.x, t.y, t.z}
local et = self.extents
local extent = {et.x, et.y, et.z}
local distance = 0
local delta
for i = 1, 3 do
if closest[i] < - extent[i] then
delta = closest[i] + extent[i]
distance = distance + delta * delta
closest[i] = -extent[i]
elseif closest[i] > extent[i] then
delta = closest[i] - extent[i]
distance = distance + delta * delta
closest[i] = extent[i]
end
end
if distance == 0 then
return point, 0
else
outPoint = closest + self:GetCenter()
return outPoint, distance
end
end
function Bounds:Destroy()
self.center = nil
self.size = nil
end
Bounds.__tostring = function(self)
return string.format("Center: %s, Extents %s", tostring(self.center), tostring(self.extents))
end
Bounds.__eq = function(a, b)
return a.center == b.center and a.extents == b.extents
end
get.size = Bounds.GetSize
get.min = Bounds.GetMin
get.max = Bounds.GetMax
UnityEngine.Bounds = Bounds
setmetatable(Bounds, Bounds)
return Bounds