local m={}m.__index=m local D=Vector3.new local j=math.pi local G=j*2 local b=tick local function p(m,D)return m==m and m or D end local function e(m,D)local b=(D-m)%G return b>j and b-G or b end local function I(m,j)return D(e(m.X,j.X),e(m.Y,j.Y),e(m.Z,j.Z))end function m.new()local j=setmetatable({P=5;D=.1,Position=D();Velocity=D(),Goal=D();Last=b()},m)return j end function m.CheckNAN(m)m.Velocity=D(p(m.Velocity.X,0),p(m.Velocity.Y,0),p(m.Velocity.Z,0))m.Position=D(p(m.Position.X,m.Goal.X),p(m.Position.Y,m.Goal.Y),p(m.Position.Z,m.Goal.Z))end function m.Update(m)local D=b()local j=D-m.Last m.Last=D m.Velocity=m.Velocity+m.P*((m.Goal-m.Position)+-m.Velocity*m.D)m.Position=m.Position+m.Velocity*j m:CheckNAN()return m.Position end function m.UpdateAngle(m)m.Goal=m.Position+I(m.Position,m.Goal)return m:Update()end return m
--[[
	
	local Damping = require(this)
	
	local damping = Damping.new()
	
	damping.P = NUMBER
	damping.D = NUMBER
	damping.Position = Vector3
	damping.Goal = Vector3
	
	damping:Update()      [Returns Vector3 position]
	damping:UpdateAngle() [Returns Vector3 position, but each XYZ value is wrapped properly for pi*2 motion]
	
	
	
	EXAMPLE USE:
	
	-- Set D and P values:
	damping.P = 5
	damping.D = 0.1
	
	-- Set starting position:
	damping.Position = part.Position
	
	while (true) do
	
		wait()
		
		-- Update the goal:
		damping.Goal = mouse.Hit.p
		
		-- Calculate new position:
		local newPosition = damping:Update()
		part.Position = newPosition
		
	end
	
	
	
	ALGORITHM:
		
		velocity += P * ( (target - current) + D * -velocity );
		current += velocity * dt;
		
		Credit: http://www.gamedev.net/topic/561981-smooth-value-damping/
	
	
--]]

local Damping = {}
Damping.__index = Damping

local V3 = Vector3.new
local PI = math.pi
local TAU = PI * 2
local tick = tick

local function CheckNAN(value, returnIfNan)
	return (value == value and value or returnIfNan)
end

local function DeltaAngle(current, target)
	local num = (target - current) % TAU
	return (num > PI and (num - TAU) or num)
end

local function DeltaAngleV3(pos1, pos2)
	return V3(DeltaAngle(pos1.X, pos2.X), DeltaAngle(pos1.Y, pos2.Y), DeltaAngle(pos1.Z, pos2.Z))
end

function Damping.new()
	local damping = setmetatable({
		P = 5,
		D = 0.1,
		Position = V3(),
		Velocity = V3(),
		Goal = V3(),
		Last = tick(),
	}, Damping)

	return damping
end

function Damping:CheckNAN()
	self.Velocity = V3(CheckNAN(self.Velocity.X, 0), CheckNAN(self.Velocity.Y, 0), CheckNAN(self.Velocity.Z, 0))
	self.Position = V3(
		CheckNAN(self.Position.X, self.Goal.X),
		CheckNAN(self.Position.Y, self.Goal.Y),
		CheckNAN(self.Position.Z, self.Goal.Z)
	)
end

function Damping:Update()
	local t = tick()
	local dt = (t - self.Last)
	self.Last = t
	self.Velocity = (self.Velocity + (self.P * ((self.Goal - self.Position) + (-self.Velocity * self.D))))
	self.Position = (self.Position + (self.Velocity * dt))
	self:CheckNAN()
	return self.Position
end

function Damping:UpdateAngle()
	self.Goal = (self.Position + DeltaAngleV3(self.Position, self.Goal))
	return self:Update()
end

return Damping
