function CameraUtils.getLooseBoundingSphere(N)local p=table.create(#N)for N,f in pairs(N)do p[N]=f.Position end local f=p[1]local B=f local P=0 for N,p in ipairs(p)do local y=(p-f).Magnitude if y>P then B=p P=y end end local y=B local M=0 for N,p in ipairs(p)do local f=(p-B).Magnitude if f>M then y=p M=f end end local J=(B+y)*.5 local A=(B-y).Magnitude*.5 for N,p in ipairs(p)do local f=(p-J).Magnitude if f>A then J=J+((f-A)*.5)*(p-J).Unit A=(f+A)*.5 end end return J,A end

function CameraUtils.getLooseBoundingSphere(parts)
	local points = table.create(#parts)
	for idx, part in pairs(parts) do
		points[idx] = part.Position
	end
	
	-- pick an arbitrary starting point
	local x = points[1]

	-- get y, the point furthest from x
	local y = x
	local yDist = 0

	for _, p in ipairs(points) do
		local pDist = (p - x).Magnitude

		if pDist > yDist then
			y = p
			yDist = pDist
		end
	end

	-- get z, the point furthest from y
	local z = y
	local zDist = 0

	for _, p in ipairs(points) do
		local pDist = (p - y).Magnitude

		if pDist > zDist then
			z = p
			zDist = pDist
		end
	end

	-- use (y, z) as the initial bounding sphere
	local sc = (y + z)*0.5
	local sr = (y - z).Magnitude*0.5

	-- expand sphere to fit any outlying points
	for _, p in ipairs(points) do
		local pDist = (p - sc).Magnitude

		if pDist > sr then
			-- shift to midpoint
			sc = sc + (pDist - sr)*0.5*(p - sc).Unit

			-- expand
			sr = (pDist + sr)*0.5
		end
	end

	return sc, sr
end
