----------------------------------------------------------------------------------------------------------------


local SmoothDamp = {}
SmoothDamp.__index = SmoothDamp

function SmoothDamp.new()
	return setmetatable({
		MaxSpeed = math.huge;
		_update = tick();
		_velocity = Vector3_new();
	}, SmoothDamp)
end

function SmoothDamp:Update(current, target, smoothTime)
	local currentVelocity = self._velocity
	local now = tick()
	local deltaTime = (now - self._update)
	smoothTime = math_max(0.0001, smoothTime)
	local num = (2 / smoothTime)
	local num2 = (num * deltaTime)
	local d = (1 / (1 + num2 + 0.48 * num2 * num2 + 0.235 * num2 * num2 * num2))
	local vector = (current - target)
	local vector2 = target
	local maxLength = (self.MaxSpeed * smoothTime)
	vector = vector.Magnitude > maxLength and (vector.Unit * maxLength) or vector -- Clamp magnitude.
	target = (current - vector)
	local vector3 = ((currentVelocity + num * vector) * deltaTime)
	currentVelocity = ((currentVelocity - num * vector3) * d)
	local vector4 = (target + (vector + vector3) * d)
	if ((vector2 - current):Dot(vector4 - vector2) > 0) then
		vector4 = vector2
		currentVelocity = ((vector4 - vector2) / deltaTime)
	end
	self._velocity = currentVelocity
	self._update = now
	return vector4
end

function SmoothDamp:UpdateAngle(current, target, smoothTime)
	return self:Update(current, (current + DeltaAngleV3(current, target)), smoothTime)
end

return SmoothDamp
