local y=game:GetService("\087\111\114\107\115\112\097\099\101")local g=game:GetService("\082\117\110\083\101\114\118\105\099\101")local H={}H._defaultColor=Color3.new(1,0,0)function H.SetColor(y)H._defaultColor=y end function H.SetRandomColor()H.SetColor(Color3.fromHSV(math.random(),.5+.5*math.random(),1))end function H.Ray(y,g,k,o,T)g=g or H._defaultColor k=k or H._getDefaultParent()o=o or.2 T=T or.2 local w=y.Origin+y.Direction/2 local d=Instance.new("\080\097\114\116")d.Anchored=true d.Archivable=false d.BottomSurface=Enum.SurfaceType.Smooth d.CanCollide=false d.CFrame=CFrame.new(w,y.Origin+y.Direction)*CFrame.Angles(math.pi/2,0,0)d.Color=g d.Name="\068\101\098\117\103\082\097\121"d.Shape=Enum.PartType.Cylinder d.Size=Vector3.new(1*T,y.Direction.Magnitude,1*T)d.TopSurface=Enum.SurfaceType.Smooth d.Transparency=.5 local z=Instance.new("\083\112\101\099\105\097\108\077\101\115\104")z.Scale=Vector3.new(0,1,0)+Vector3.new(o,0,o)/T z.Parent=d d.Parent=k return d end function H.Point(y,g,k,o)assert(y)g=g or H._defaultColor k=k or H._getDefaultParent()o=o or 1 local T=Instance.new("\080\097\114\116")T.Anchored=true T.Archivable=false T.BottomSurface=Enum.SurfaceType.Smooth T.CanCollide=false T.CFrame=CFrame.new(y)T.Color=g T.Name="\068\101\098\117\103\080\111\105\110\116"T.Shape=Enum.PartType.Ball T.Size=Vector3.new(o,o,o)T.TopSurface=Enum.SurfaceType.Smooth T.Transparency=.5 local w=Instance.new("\083\112\104\101\114\101\072\097\110\100\108\101\065\100\111\114\110\109\101\110\116")w.Archivable=false w.Radius=o/4 w.Color3=g w.AlwaysOnTop=true w.Adornee=T w.ZIndex=1 w.Parent=T T.Parent=k return T end function H.Box(y,g,k)k=k or H._defaultColor y=typeof(y)=="\086\101\099\116\111\114\051"and CFrame.new(y)or y local o=Instance.new("\080\097\114\116")o.Color=k o.Name="\068\101\098\117\103\080\097\114\116"o.Anchored=true o.CanCollide=false o.Archivable=false o.BottomSurface=Enum.SurfaceType.Smooth o.TopSurface=Enum.SurfaceType.Smooth o.Transparency=.5 o.Size=g o.CFrame=y o.Parent=H._getDefaultParent()return o end function H._getDefaultParent()return g:IsServer()and y or y.CurrentCamera end return H
--- Debug drawing library useful for debugging 3D abstractions
-- @module Draw

local Workspace = game:GetService("Workspace")
local RunService = game:GetService("RunService")

local lib = {}
lib._defaultColor = Color3.new(1, 0, 0)

--- Sets the lib's drawing color
-- @tparam {Color3} color The color to set
function lib.SetColor(color)
	lib._defaultColor = color
end

--- Sets the draw library to use a random color
function lib.SetRandomColor()
	lib.SetColor(Color3.fromHSV(math.random(), 0.5+0.5*math.random(), 1))
end

--- Draws a ray for debugging
-- @param ray The ray to draw
-- @tparam[opt] {color3} color The color to draw in
-- @tparam[opt] {Instance} parent
-- @tparam[opt] {number} diameter
-- @tparam[opt] {number} meshDiameter
function lib.Ray(ray, color, parent, meshDiameter, diameter)
	color = color or lib._defaultColor
	parent = parent or lib._getDefaultParent()
	meshDiameter = meshDiameter or 0.2
	diameter = diameter or 0.2

	local rayCenter = ray.Origin + ray.Direction/2

	local part = Instance.new("Part")
	part.Anchored = true
	part.Archivable = false
	part.BottomSurface = Enum.SurfaceType.Smooth
	part.CanCollide = false
	part.CFrame = CFrame.new(rayCenter, ray.Origin + ray.Direction) * CFrame.Angles(math.pi/2, 0, 0)
	part.Color = color
	part.Name = "DebugRay"
	part.Shape = Enum.PartType.Cylinder
	part.Size = Vector3.new(1 * diameter, ray.Direction.Magnitude, 1 * diameter)
	part.TopSurface = Enum.SurfaceType.Smooth
	part.Transparency = 0.5

	local mesh = Instance.new("SpecialMesh")
	mesh.Scale = Vector3.new(0, 1, 0) + Vector3.new(meshDiameter, 0, meshDiameter) / diameter
	mesh.Parent = part

	part.Parent = parent

	return part
end

--- Draws a point for debugging
-- @tparam {Vector3} vector3 Point to draw
-- @tparam[opt] {color3} color The color to draw in
-- @tparam[opt] {Instance} parent
-- @tparam[opt] {number} diameter
function lib.Point(vector3, color, parent, diameter)
	assert(vector3)
	color = color or lib._defaultColor
	parent = parent or lib._getDefaultParent()
	diameter = diameter or 1

	local part = Instance.new("Part")
	part.Anchored = true
	part.Archivable = false
	part.BottomSurface = Enum.SurfaceType.Smooth
	part.CanCollide = false
	part.CFrame = CFrame.new(vector3)
	part.Color = color
	part.Name = "DebugPoint"
	part.Shape = Enum.PartType.Ball
	part.Size = Vector3.new(diameter, diameter, diameter)
	part.TopSurface = Enum.SurfaceType.Smooth
	part.Transparency = 0.5

	local sphereHandle = Instance.new("SphereHandleAdornment")
	sphereHandle.Archivable = false
	sphereHandle.Radius = diameter/4
	sphereHandle.Color3 = color
	sphereHandle.AlwaysOnTop = true
	sphereHandle.Adornee = part
	sphereHandle.ZIndex = 1
	sphereHandle.Parent = part

	part.Parent = parent

	return part
end

function lib.Box(cframe, size, color)
	color = color or lib._defaultColor
	cframe = typeof(cframe) == "Vector3" and CFrame.new(cframe) or cframe

	local part = Instance.new("Part")
	part.Color = color
	part.Name = "DebugPart"
	part.Anchored = true
	part.CanCollide = false
	part.Archivable = false
	part.BottomSurface = Enum.SurfaceType.Smooth
	part.TopSurface = Enum.SurfaceType.Smooth
	part.Transparency = 0.5
	part.Size = size
	part.CFrame = cframe
	part.Parent = lib._getDefaultParent()

	return part
end

function lib._getDefaultParent()
	return RunService:IsServer() and Workspace or Workspace.CurrentCamera
end

return lib