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