viewportFrame rotation

Soo i’ve got this library:

local WEDGE = {0, 1, 3, 4, 5, 7}
local CORNER_WEDGE = {0, 1, 4, 5, 6}
-- Class
local ViewportModelClass = {}
ViewportModelClass.__index = ViewportModelClass
ViewportModelClass.ClassName = "ViewportModel"
-- Private
local function getIndices(part)
   if part:IsA("WedgePart") then
   	return WEDGE
   elseif part:IsA("CornerWedgePart") then
   	return CORNER_WEDGE
   end
   return BLOCK
end
local function getCorners(cf, size2, indices)
   local corners = {}
   for j, i in pairs(indices) do
   	corners[j] = cf * (size2 * Vector3.new(
   		2 * (math.floor(i / 4) % 2) - 1,
   		2 * (math.floor(i / 2) % 2) - 1,
   		2 * (i % 2) - 1
   		))
   end
   return corners
end
local function getModelPointCloud(model)
   local points = {}
   for _, part in pairs(model:GetDescendants()) do
   	if part:IsA("BasePart") then
   		local indices = getIndices(part)
   		local corners = getCorners(part.CFrame, part.Size / 2, indices)
   		for _, wp in pairs(corners) do
   			table.insert(points, wp)
   		end
   	end
   end
   return points
end
local function viewProjectionEdgeHits(cloud, axis, depth, tanFov2)
   local max, min = -math.huge, math.huge

   for _, lp in pairs(cloud) do
   	local distance = depth - lp.Z
   	local halfSpan = tanFov2 * distance

   	local a = lp[axis] + halfSpan
   	local b = lp[axis] - halfSpan

   	max = math.max(max, a, b)
   	min = math.min(min, a, b)
   end
   return max, min
end
-- Public
function ViewportModelClass.GenerateViewport(viewportFrame: ViewportFrame, model: Model, orientation: CFrame?)
   orientation = orientation or CFrame.Angles(0, 0, 0)
   local camera = viewportFrame:FindFirstChildOfClass("Camera")
   if not camera then
   	camera = Instance.new("Camera")
   	camera.FieldOfView = 70
   	camera.Parent = viewportFrame

   	viewportFrame.CurrentCamera = camera
   end

   model.Parent = viewportFrame

   local vpmClass = ViewportModelClass.new(viewportFrame, camera)
   vpmClass:SetModel(model)
   camera.CFrame = vpmClass:GetMinimumFitCFrame(orientation)
end
function ViewportModelClass.CleanViewport(viewportFrame: ViewportFrame)
   local model = viewportFrame:FindFirstChildOfClass("Model")
   if model then
   	model:Destroy()
   end
end
-- Public Constructors
function ViewportModelClass.new(vpf, camera)
   local self = setmetatable({}, ViewportModelClass)

   self.Model = nil
   self.ViewportFrame = vpf
   self.Camera = camera

   self._points = {}
   self._modelCFrame = CFrame.new()
   self._modelSize = Vector3.new()
   self._modelRadius = 0

   self._viewport = {}

   self:Calibrate()

   return self
end
-- Public Methods
-- Used to set the model that is being focused on
-- should be used for new models and/or a change in the current model
-- e.g. parts added/removed from the model or the model cframe changed
function ViewportModelClass:SetModel(model)
   self.Model = model

   local cf, size = model:GetBoundingBox()

   self._points = getModelPointCloud(model)
   self._modelCFrame = cf
   self._modelSize = size
   self._modelRadius = size.Magnitude / 2
end
-- Should be called when something about the viewport frame / camera changes
-- e.g. the frame size or the camera field of view
function ViewportModelClass:Calibrate()
   local viewport = {}
   local size = self.ViewportFrame.AbsoluteSize

   viewport.aspect = size.X / size.Y

   viewport.yFov2 = math.rad(self.Camera.FieldOfView / 2)
   viewport.tanyFov2 = math.tan(viewport.yFov2)

   viewport.xFov2 = math.atan(viewport.tanyFov2 * viewport.aspect)
   viewport.tanxFov2 = math.tan(viewport.xFov2)

   viewport.cFov2 = math.atan(viewport.tanyFov2 * math.min(1, viewport.aspect))
   viewport.sincFov2 = math.sin(viewport.cFov2)

   self._viewport = viewport
end
-- returns a fixed distance that is guarnteed to encapsulate the full model
-- this is useful for when you want to rotate freely around an object w/o expensive calculations
-- focus position can be used to set the origin of where the camera's looking
-- otherwise the model's center is assumed
function ViewportModelClass:GetFitDistance(focusPosition)
   local displacement = focusPosition and  (focusPosition - self._modelCFrame.Position).Magnitude or 0
   local radius = self._modelRadius + displacement

   return radius / self._viewport.sincFov2
end
-- returns the optimal camera cframe that would be needed to best fit
-- the model in the viewport frame at the given orientation.
-- keep in mind this functions best when the model's point-cloud is correct
-- as such models that rely heavily on meshesh, csg, etc will only return an accurate
-- result as their point cloud
function ViewportModelClass:GetMinimumFitCFrame(orientation)
   if not self.Model then
   	return CFrame.new()
   end

   local rotation = orientation - orientation.Position
   local rInverse = rotation:Inverse()

   local wcloud = self._points
   local cloud = {rInverse * wcloud[1]}
   local furthest = cloud[1].Z

   for i = 2, #wcloud do
   	local lp = rInverse * wcloud[i]
   	furthest = math.min(furthest, lp.Z)
   	cloud[i] = lp
   end

   local hMax, hMin = viewProjectionEdgeHits(cloud, "X", furthest, self._viewport.tanxFov2)
   local vMax, vMin = viewProjectionEdgeHits(cloud, "Y", furthest, self._viewport.tanyFov2)

   local distance = math.max(
   	((hMax - hMin) / 2) / self._viewport.tanxFov2,
   	((vMax - vMin) / 2) / self._viewport.tanyFov2
   )

   return orientation * CFrame.new(
   	(hMax + hMin) / 2,
   	(vMax + vMin) / 2,
   	furthest + distance
   )
end

--

return ViewportModelClass```

And i need to put some most efficient loop to rotate it, i tried while loop with camera but it didn't work well, as it moved as it should only with Z axis but i need X one which started going off screen
Sample: 
```function ViewportModelClass:AutoRotate(viewportFrame,camera)
   coroutine.wrap(function()
   	while viewportFrame:FindFirstChildOfClass("Model") do
   		task.wait()
   		camera.CFrame *= CFrame.Angles(math.rad(1),0,0) -- when used X axis it goes off the selected area
   	end
   end)()
end```

For those not noticing what i need help with: And i need to put some most efficient loop to rotate it, i tried while loop with camera but it didn’t work well, as it moved as it should only with Z axis but i need X one which started going off screen
Sample:

   coroutine.wrap(function()
   	while viewportFrame:FindFirstChildOfClass("Model") do
   		task.wait()
   		camera.CFrame *= CFrame.Angles(math.rad(1),0,0) -- when used X axis it goes off the selected area
   	end
   end)()
end```