local function w(w,z,y)local o=w.Size local c=w:GetMass()local D=(w.Position-y):Cross(z)local N=D:Dot(D)local t=c*N local L=o*o local H=(w.CFrame-w.Position):inverse()*z local F=((Vector3.new(L.y+L.z,L.z+L.x,L.x+L.y)):Dot(H*H)*c)/12 return t+F end local function z(z,y,o)local c=0 for z,D in pairs(z)do c=c+w(D,y,o)end return c end local function y(w)local z,y,o,c,D,N,t,L,H,F,G,J=w:components()return Vector3.new(N,H,J)end local function o(w,z,y)local o=z:Cross(y)return CFrame.new(w.x,w.y,w.z,o.x,z.x,y.x,o.y,z.y,y.y,o.z,z.z,y.z)end local function c(w)local z=y(w)return o(w.p,Vector3.new(0,1,0),(Vector3.new(z.x,0,z.z)).unit)end local function D(w)if w==0 then return 0 elseif w>0 then return 1 else return-1 end end local N=require(WaitForChild(script,"\069\097\115\121\067\111\110\102\105\103\117\114\097\116\105\111\110"))
-- Moment of Inertia of any rectangular prism.
-- 1/12 * m * sum(deminsionlengths^2)

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"))
