local v=Vector3.new(0,0,0)local d=Vector3.new(1,0,0)local function q(v,d,q,R)local m=v-q local B=-m:Dot(R)/d:Dot(R)return v+B*d,B end local R={}function R.PointCloud(v,d)local q,R=v[1],v[1]:Dot(d)for m=2,#v,1 do local B=v[m]:Dot(d)if B>R then q=v[m]R=B end end return q end function R.Cylinder(R,m)local B,s=unpack(R)m=B:VectorToObjectSpace(m)local g=math.min(s.y,s.z)local i,W=m:Dot(d),Vector3.new(s.x,0,0)local L,w,k if i==0 then k=m.Unit*g else W=i>0 and W or-W L,w=q(v,m,W,d)k=W+(L-W).Unit*g end return B:PointToWorldSpace(k)end function R.Ellipsoid(v,d)local q,R=unpack(v)return q:PointToWorldSpace(R*(R*q:VectorToObjectSpace(d)).Unit)end return R
local ZERO = Vector3.new(0, 0, 0)
local RIGHT = Vector3.new(1, 0, 0)

--

local function rayPlane(p, v, s, n)
	local r = p - s;
	local t = -r:Dot(n) / v:Dot(n)
	return p + t * v, t
end;

--

local Supports = {}

function Supports.PointCloud(set, direction)
	local max, maxDot = set[1], set[1]:Dot(direction)
	for i = 2, #set do
		local dot = set[i]:Dot(direction)
		if (dot > maxDot) then
			max = set[i]
			maxDot = dot
		end
	end
	return max
end

function Supports.Cylinder(set, direction)
	local cf, size2 = unpack(set)
	direction = cf:VectorToObjectSpace(direction)
	local radius = math.min(size2.y, size2.z)
	local dotT, cPoint = direction:Dot(RIGHT), Vector3.new(size2.x, 0, 0)
	local h, t, final
	
	if (dotT == 0) then
		final = direction.Unit * radius
	else
		cPoint = dotT > 0 and cPoint or -cPoint
		h, t = rayPlane(ZERO, direction, cPoint, RIGHT)
		final = cPoint + (h - cPoint).Unit * radius
	end
	
	return cf:PointToWorldSpace(final)
end

function Supports.Ellipsoid(set, direction)
	local cf, size2 = unpack(set)
	return cf:PointToWorldSpace(size2 * (size2 * cf:VectorToObjectSpace(direction)).Unit)
end

return Supports