local function U(U,N,u)local M=U.Size local G=U:GetMass()local t=(U.Position-u):Cross(N)local L=t:Dot(t)local z=G*L local y=M*M local E=(U.CFrame-U.Position):inverse()*N local b=((Vector3.new(y.y+y.z,y.z+y.x,y.x+y.y)):Dot(E*E)*G)/12 return z+b end local function N(N,u,M)local G=0 for N,t in pairs(N)do G=G+U(t,u,M)end return G end local function u(U)local N,u,M,G,t,L,z,y,E,b,m,f=U:components()return Vector3.new(L,E,f)end local function M(U,N,u)local M=N:Cross(u)return CFrame.new(U.x,U.y,U.z,M.x,N.x,u.x,M.y,N.y,u.y,M.z,N.z,u.z)end local function G(U)local N=u(U)return M(U.p,Vector3.new(0,1,0),(Vector3.new(N.x,0,N.z)).unit)end local function t(U)if U==0 then return 0 elseif U>0 then return 1 else return-1 end end local L=require(WaitForChild(script,"\069\097\115\121\067\111\110\102\105\103\117\114\097\116\105\111\110"))


local function MomentOfInertia(Part, Axis, Origin)
	--- Calculates the moment of inertia of a cuboid.

	-- Part is part
	-- Axis is the axis
	-- Origin is the origin of the axis

	local PartSize = Part.Size

	local Mass  = Part:GetMass()
	local Radius  = (Part.Position - Origin):Cross(Axis)
	local r2 = Radius:Dot(Radius)
	local ip = Mass * r2--Inertia based on Position
	local s2 = PartSize*PartSize
	local sa = (Part.CFrame-Part.Position):inverse()*Axis
	local id = (Vector3.new(s2.y+s2.z, s2.z+s2.x, s2.x+s2.y)):Dot(sa*sa)*Mass/12 -- Inertia based on Direction
	return ip+id
end

local function BodyMomentOfInertia(Parts, Axis, Origin)
	--- Given a connected body of parts, returns the moment of inertia of these parts
	-- @param Parts The parts to use
	-- @param Axis the axis to use (Should be torque, or offset cross force)
	-- @param Origin The origin of the axis (should be center of mass of the parts)
	
	local TotalBodyInertia = 0

	for _, Part in pairs(Parts) do
		TotalBodyInertia = TotalBodyInertia + MomentOfInertia(Part, Axis, Origin)
	end

	return TotalBodyInertia
end

local function GetBackVector(CFrameValue)
	--- Get's the back vector of a CFrame Value
	-- @param CFrameValue A CFrame, of which the vector will be retrieved
	-- @return The back vector of the CFrame

	local _,_,_,_,_,r6,_,_,r9,_,_,r12 = CFrameValue:components()
	return Vector3.new(r6,r9,r12)
end

local function GetCFrameFromTopBack(CFrameAt, Top, Back)
	--- Get's the CFrame fromt he "top back" vector. or something

	local Right = Top:Cross(Back) -- Get's the "right" cframe lookvector.
	return CFrame.new(CFrameAt.x, CFrameAt.y, CFrameAt.z,
		Right.x, Top.x, Back.x,
		Right.y, Top.y, Back.y,
		Right.z, Top.z, Back.z
	)
end

local function GetRotationInXZPlane(CFrameValue)
	--- Get's the rotation in the XZ plane (global).

	local Back = GetBackVector(CFrameValue)
	return GetCFrameFromTopBack(CFrameValue.p, 
		Vector3.new(0,1,0), -- Top lookVector (straight up)
		Vector3.new(Back.x, 0, Back.z).unit -- Right facing direction (removed Y axis.)
	)
end

local function Sign(Number)
	-- Return's the mathetmatical sign of an object
	if Number == 0 then
		return 0
	elseif Number > 0 then
		return 1
	else
		return -1
	end
end

local EasyConfiguration = require(WaitForChild(script, "EasyConfiguration"))
