local X=(require(script.Parent.loader)).load(script)local I=game:GetService("\082\117\110\083\101\114\118\105\099\101")local d=game:GetService("\086\082\083\101\114\118\105\099\101")local T=game:GetService("\087\111\114\107\115\112\097\099\101")local Q=game:GetService("\067\111\110\116\101\120\116\065\099\116\105\111\110\083\101\114\118\105\099\101")local v=game:GetService("\072\116\116\112\083\101\114\118\105\099\101")local D=X("\066\097\115\101\079\098\106\101\099\116")local M=X("\073\075\083\101\114\118\105\099\101\067\108\105\101\110\116")local J=setmetatable({},D)J.ClassName="\086\082\072\097\110\100\067\111\110\116\114\111\108\115"J.__index=J function J.new(X,I)local d=setmetatable(D.new(),J)d._serviceBag=assert(X,"\078\111 \115\101\114\118\105\099\101\066\097\103")d._ikServiceClient=d._serviceBag:GetService(M)d._key="\086\082\072\097\110\100\067\111\110\116\114\111\108\115\095"..v:GenerateGUID(false)d._vrEnabledHumanoidClient=assert(I,"\078\111 \118\114\069\110\097\098\108\101\100\072\117\109\097\110\111\105\100\067\108\105\101\110\116")d:_setupGripLoop("\076\101\102\116",Enum.UserCFrame.LeftHand)d:_setupGripLoop("\082\105\103\104\116",Enum.UserCFrame.RightHand)d:_bindInput()return d end function J._setupGripLoop(Q,X,T)if not d:GetUserCFrameEnabled(T)then return end local v=Instance.new("\072\105\103\104\108\105\103\104\116")v.FillTransparency=1 v.Name=("\071\114\105\112\037\115\072\105\103\104\108\105\103\104\116"):format(X)Q._maid:GiveTask(v)Q._maid:GiveTask(I.Stepped:Connect(function()Q:_updateGripStepped(X,T,v)end))end function J._updateGripStepped(v,X,I,Q)local D=d:GetUserCFrame(I)local M=T.CurrentCamera D=D.Rotation+D.Position*M.HeadScale D=D*CFrame.Angles(math.pi/2,0,0)local J=M.CFrame:toWorldSpace(D)v._vrEnabledHumanoidClient:SetGripCFrame(X,J)if X=="\082\105\103\104\116"then if v._vrEnabledHumanoidClient:GetHoldingAdornee(X)then Q.Parent=nil else local I=v._vrEnabledHumanoidClient:FindHoldable(X)if I then Q.Parent=I else Q.Parent=nil end end end end function J._bindInput(X)Q:BindAction(X._key.."\072\111\108\100",function(I,d,T)if d==Enum.UserInputState.Begin then if X._vrEnabledHumanoidClient:GetHoldingAdornee("\082\105\103\104\116")then X._vrEnabledHumanoidClient:RequestDrop("\082\105\103\104\116")else X._vrEnabledHumanoidClient:RequestHold("\082\105\103\104\116")end end end,false,Enum.KeyCode.ButtonA,Enum.KeyCode.ButtonB,Enum.KeyCode.E)X._maid:GiveTask(function()Q:UnbindAction(X._key.."\072\111\108\100")end)end return J
--[=[
	@class VRHandControls
]=]

local require = require(script.Parent.loader).load(script)

local RunService = game:GetService("RunService")
local VRService = game:GetService("VRService")
local Workspace = game:GetService("Workspace")
local ContextActionService = game:GetService("ContextActionService")
local HttpService = game:GetService("HttpService")

local BaseObject = require("BaseObject")
local IKServiceClient = require("IKServiceClient")

local VRHandControls = setmetatable({}, BaseObject)
VRHandControls.ClassName = "VRHandControls"
VRHandControls.__index = VRHandControls

function VRHandControls.new(serviceBag, vrEnabledHumanoidClient)
	local self = setmetatable(BaseObject.new(), VRHandControls)

	self._serviceBag = assert(serviceBag, "No serviceBag")
	self._ikServiceClient = self._serviceBag:GetService(IKServiceClient)

	self._key = "VRHandControls_" .. HttpService:GenerateGUID(false)
	self._vrEnabledHumanoidClient = assert(vrEnabledHumanoidClient, "No vrEnabledHumanoidClient")

	self:_setupGripLoop("Left", Enum.UserCFrame.LeftHand)
	self:_setupGripLoop("Right", Enum.UserCFrame.RightHand)

	self:_bindInput()

	return self
end

function VRHandControls:_setupGripLoop(sideName, sideUserCFrame)
	if not VRService:GetUserCFrameEnabled(sideUserCFrame) then
		return
	end

	local highlight = Instance.new("Highlight")
	highlight.FillTransparency = 1
	highlight.Name = ("Grip%sHighlight"):format(sideName)
	self._maid:GiveTask(highlight)

	self._maid:GiveTask(RunService.Stepped:Connect(function()
		self:_updateGripStepped(sideName, sideUserCFrame, highlight)
	end))
end

function VRHandControls:_updateGripStepped(sideName, sideUserCFrame, highlight)
	local handCFrame = VRService:GetUserCFrame(sideUserCFrame)
	local camera = Workspace.CurrentCamera

	-- Need to compute relative to head scale and position
	handCFrame = handCFrame.Rotation + handCFrame.Position*camera.HeadScale
	handCFrame = handCFrame * CFrame.Angles(math.pi/2, 0, 0) -- Y axis back

	local cframe = camera.CFrame:toWorldSpace(handCFrame)

	self._vrEnabledHumanoidClient:SetGripCFrame(sideName, cframe)

	-- self._maid[sideName .. "debug"] = Draw.cframe(cframe)

	if sideName == "Right" then
		if self._vrEnabledHumanoidClient:GetHoldingAdornee(sideName) then
			highlight.Parent = nil
		else
			local holdable = self._vrEnabledHumanoidClient:FindHoldable(sideName)
			if holdable then
				highlight.Parent = holdable
			else
				highlight.Parent = nil
			end
		end
	end
end

function VRHandControls:_bindInput()
	ContextActionService:BindAction(self._key .. "Hold", function(_, userInputState, _inputObject)
		if userInputState == Enum.UserInputState.Begin then
			if self._vrEnabledHumanoidClient:GetHoldingAdornee("Right") then
				self._vrEnabledHumanoidClient:RequestDrop("Right")
			else
				self._vrEnabledHumanoidClient:RequestHold("Right")
			end
		end
	end, false, Enum.KeyCode.ButtonA, Enum.KeyCode.ButtonB, Enum.KeyCode.E)

	self._maid:GiveTask(function()
		ContextActionService:UnbindAction(self._key .. "Hold")
	end)
end

return VRHandControls