local V=script.Parent local K=require(V:WaitForChild("\067\111\110\102\105\103"))local s=require(V:WaitForChild("\085\116\105\108\105\116\105\101\115"))local P={}function P.GetCFrames(V,K)do end local s=V.CFrame local P=s.Position local g,o=s.RightVector,s.UpVector local p=K*.5 local I=math.tan(((V.FieldOfView+5)*.5)*.017453)*K local y=I*(V.ViewportSize.X/V.ViewportSize.Y)local e=s*CFrame.new(0,0,-K)local S=e*Vector3.new(y,I,0)local t=e*Vector3.new(-y,-I,0)local f=e*Vector3.new(y,-I,0)local N=(s*CFrame.new(0,0,-p)):Inverse()local W=(o:Cross(f-P)).Unit local R=(o:Cross(t-P)).Unit local m=(g:Cross(P-S)).Unit local F=(g:Cross(P-f)).Unit do end return N,y,I,p,W,R,m,F,s end function P.InViewFrustum(V,K,s,P,g,o,p,I,y,e)do end local S=e.Position local t=K*V if t.X>s or t.X<-s or t.Y>P or t.Y<-P or t.Z>g or t.Z<-g then do end return false end local f=V-S if o:Dot(f)<0 or p:Dot(f)>0 or I:Dot(f)<0 or y:Dot(f)>0 then do end return false end do end return true end function P.ObjectInFrustum(V,g,o,p,I,y,e,S,t,f)local N=V.CFrame local W=V.Size local R=K.FAR_PLANE*.5 local m=f.Position+f.LookVector*R local F=s.ClosestPointOnLine(m,f.LookVector,R,N.Position)local T,z=s.ClosestPointInBox(N,W,F)if T then return true end if P.InViewFrustum(z,g,o,p,I,y,e,S,t,f)then return true end return false end return P
--!native
local Dependencies = script.Parent
local Config = require(Dependencies:WaitForChild("Config"))
local Utilities = require(Dependencies:WaitForChild("Utilities"))

local Class = {}

function Class.GetCFrames(camera, distance)
do end	
local cameraCFrame = camera.CFrame
	local cameraPos = cameraCFrame.Position
	local rightVec, upVec = cameraCFrame.RightVector, cameraCFrame.UpVector

	local distance2 = distance * 0.5
	local farPlaneHeight2 = math.tan(((camera.FieldOfView + 5) * 0.5) * 0.017453) * distance
	local farPlaneWidth2 = farPlaneHeight2 * (camera.ViewportSize.X / camera.ViewportSize.Y)
	local farPlaneCFrame = cameraCFrame * CFrame.new(0, 0, -distance)
	local farPlaneTopRight = farPlaneCFrame * Vector3.new(farPlaneWidth2, farPlaneHeight2, 0)
	local farPlaneBottomLeft = farPlaneCFrame * Vector3.new(-farPlaneWidth2, -farPlaneHeight2, 0)
	local farPlaneBottomRight = farPlaneCFrame * Vector3.new(farPlaneWidth2, -farPlaneHeight2, 0)

	local frustumCFrameInverse = (cameraCFrame * CFrame.new(0, 0, -distance2)):Inverse()

	local rightNormal = upVec:Cross(farPlaneBottomRight - cameraPos).Unit
	local leftNormal = upVec:Cross(farPlaneBottomLeft - cameraPos).Unit
	local topNormal = rightVec:Cross(cameraPos - farPlaneTopRight).Unit
	local bottomNormal = rightVec:Cross(cameraPos - farPlaneBottomRight).Unit
do end	
return frustumCFrameInverse, farPlaneWidth2, farPlaneHeight2, distance2, rightNormal, leftNormal, topNormal, bottomNormal, cameraCFrame
end

function Class.InViewFrustum(
	point,
	frustumCFrameInverse,
	farPlaneWidth2,
	farPlaneHeight2,
	distance2,
	rightNormal,
	leftNormal,
	topNormal,
	bottomNormal,
	cameraCf
)
do end
	
local cameraPos = cameraCf.Position

	-- Check if point lies outside frustum OBB
	local relativeToOBB = frustumCFrameInverse * point
	if
		relativeToOBB.X > farPlaneWidth2
		or relativeToOBB.X < -farPlaneWidth2
		or relativeToOBB.Y > farPlaneHeight2
		or relativeToOBB.Y < -farPlaneHeight2
		or relativeToOBB.Z > distance2
		or relativeToOBB.Z < -distance2
	then
do end		
return false
	end

	-- Check if point lies outside a frustum plane
	local lookToCell = point - cameraPos
	if rightNormal:Dot(lookToCell) < 0 or leftNormal:Dot(lookToCell) > 0 or topNormal:Dot(lookToCell) < 0 or bottomNormal:Dot(lookToCell) > 0 then
do end		
return false
	end
do end	

return true
end

function Class.ObjectInFrustum(
	Object,
	frustumCFrameInverse,
	farPlaneWidth2,
	farPlaneHeight2,
	distance2,
	rightNormal,
	leftNormal,
	topNormal,
	bottomNormal,
	cameraCFrame
)
	local CF = Object.CFrame
	local Size = Object.Size

	-- Allows for really big root parts to still be checked correctly
	local HalfFarPlane = Config.FAR_PLANE * 0.5
	local LinePosition = cameraCFrame.Position + (cameraCFrame.LookVector * HalfFarPlane)

	local Closest = Utilities.ClosestPointOnLine(LinePosition, cameraCFrame.LookVector, HalfFarPlane, CF.Position)
	local Inside, point = Utilities.ClosestPointInBox(CF, Size, Closest)

	if Inside then
		return true
	end

	if
		Class.InViewFrustum(
			point,
			frustumCFrameInverse,
			farPlaneWidth2,
			farPlaneHeight2,
			distance2,
			rightNormal,
			leftNormal,
			topNormal,
			bottomNormal,
			cameraCFrame
		)
	then
		return true
	end

	return false
end

return Class
