Slower bone rotation?
Moderators: Víctor Paredes, Belgarath, slowtiger
Slower bone rotation?
For my liking, the bone rotation-tool reacts too much to the mouse-movements. I had a look at the lm_rotate_bone.lua script and didn't understand much of it.
Would it be possible to make the bone-rotation-tool slower and if so, could someone give me a hint as to how that would have to be done?
			
			
									
									
						Would it be possible to make the bone-rotation-tool slower and if so, could someone give me a hint as to how that would have to be done?
This buggered me too a while ago (you can't get very subltle bone rotations with the rotation tool) so I started to modify the rotation tool to rotate 1/10 of it's normal movement (and some other bling-bling as well). there are a lot of work still to be done to it, it behaves somewhat irratical and I probably won't have the time to make a full workable version anytime soon but if you would like to give it a try I could put together a version and mail you so  you could develop it  further.
			
			
									
									
						So did you get the 1/10th movement to work? The rest is probably of lesser interest to me.rylleman wrote:This buggered me too a while ago (you can't get very subltle bone rotations with the rotation tool) so I started to modify the rotation tool to rotate 1/10 of it's normal movement (and some other bling-bling as well). there are a lot of work still to be done to it, it behaves somewhat irratical and I probably won't have the time to make a full workable version anytime soon but if you would like to give it a try I could put together a version and mail you so you could develop it further.
If only I could figure out where in the script the mouse-movement is put into the bone-tip movement, but my little bit of experience with BASIC isn't much of a help here.
Yippeeee
Just like yourself, I tried all sort of stuff, but always got those jumps. But I think I cracked it now. At the moment it halfs the speed at which the bones react. These are the lines where it happens:
It's the division by 2 that does it, but you can of course change it to another value.
The other one is the reaction-speed of the scrollwheel in the numerical field:
In the original script it reads 5 between the brackets.
			
			
									
									
						Code: Select all
if (moho.frame == 0) then
				local angle = bone.fAnimAngle:GetValue(0) + math.atan2(v2.y, v2.x)/2 -- Slowed down
				bone.fAnimAngle:SetValue(0, angle)
			else
				bone.fAngle = bone.fAngle + math.atan2(v2.y, v2.x)/2 -- Slowed Down
			endThe other one is the reaction-speed of the scrollwheel in the numerical field:
Code: Select all
self.angle:SetWheelInc(1)--Slowed Down...and here is the whole script:
			
			
									
									
						Code: Select all
-- **************************************************
-- Provide Moho with the name of this script object
-- **************************************************
ScriptName = "LM_RotateBone"
-- **************************************************
-- General information about this script
-- **************************************************
LM_RotateBone = {}
function LM_RotateBone:Name()
	return "Rotate Bone"
end
function LM_RotateBone:Version()
	return "5.0"
end
function LM_RotateBone:Description()
	return "Rotate bone (hold <shift> to constrain)"
end
function LM_RotateBone:Creator()
	return "Lost Marble"
end
function LM_RotateBone:UILabel()
	return("Rotate Bone")
end
-- **************************************************
-- Recurring values
-- **************************************************
LM_RotateBone.selID = -1
LM_RotateBone.lastVec = LM.Vector2:new_local()
-- **************************************************
-- The guts of this script
-- **************************************************
function LM_RotateBone:IsEnabled(moho)
	if (moho:CountBones() < 1) then
		return false
	end
	return true
end
function LM_RotateBone:OnMouseDown(moho, mouseEvent)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return
	end
	moho.document:PrepUndo(moho.layer)
	moho.document:SetDirty()
	if (moho:CountSelectedBones() < 2) then
		for i = 0, skel:CountBones() - 1 do
			skel:Bone(i).fSelected = false
		end
		local id = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, false)
		skel:Bone(id).fSelected = true
	end
	local selCount = 0
	for i = 0, skel:CountBones() - 1 do
		local bone = skel:Bone(i)
		if (bone.fSelected) then
			self.selID = i
			selCount = selCount + 1
			if (moho.frame == 0) then
				bone.fTempPos:Set(bone.fAnimPos:GetValue(0))
				bone.fTempLength = bone.fLength
				bone.fTempAngle = bone.fAnimAngle:GetValue(0)
			else
				bone.fTempAngle = bone.fAngle
			end
		end
	end
	if (selCount > 1) then
		self.selID = -1
	end
	moho:UpdateBonePointSelection()
	mouseEvent.view:DrawMe()
	moho:UpdateSelectedChannels()
	self.lastVec:Set(mouseEvent.vec)
end
function LM_RotateBone:OnMouseMoved(moho, mouseEvent)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return
	end
	for i = 0, skel:CountBones() - 1 do
		local bone = skel:Bone(i)
		if (bone.fSelected) then
			if (moho.frame == 0) then
				bone.fAnimPos:SetValue(0, bone.fTempPos)
				bone.fLength = bone.fTempLength
				bone.fAnimAngle:SetValue(0, bone.fTempAngle)
			else
				bone.fAngle = bone.fTempAngle
			end
		end
	end
	skel:UpdateBoneMatrix()
	for i = 0, skel:CountBones() - 1 do
		local bone = skel:Bone(i)
		if (bone.fSelected) then
			local origin = LM.Vector2:new_local()
			if (moho:CountSelectedBones() < 2) then
				origin:Set(0, 0)
				if (moho.frame == 0) then
					bone.fRestMatrix:Transform(origin)
				else
					bone.fMovedMatrix:Transform(origin)
				end
			else
				origin = moho.layer:Origin()
			end
			local v1 = self.lastVec - origin
			local v2 = mouseEvent.vec - origin
			v2:Rotate(-math.atan2(v1.y, v1.x))
			if (moho.frame == 0) then
				local angle = bone.fAnimAngle:GetValue(0) + math.atan2(v2.y, v2.x)/2 -- Slowed down
				bone.fAnimAngle:SetValue(0, angle)
			else
				bone.fAngle = bone.fAngle + math.atan2(v2.y, v2.x)/2 -- Slowed Down
			end
			if (moho.frame == 0) then
				local angle = bone.fAnimAngle:GetValue(0)
				while angle > 2 * math.pi do
					angle = angle - 2 * math.pi
				end
				while angle < 0 do
					angle = angle + 2 * math.pi
				end
				bone.fTempAngle = angle
				if (mouseEvent.shiftKey) then
					angle = angle / (math.pi / 4)
					angle = (math.pi / 4) * LM.Round(angle)
				end
				bone.fAnimAngle:SetValue(0, angle)
			else
				if (bone.fConstraints) then
					local min = bone.fAnimAngle:GetValue(0)
					local max = min + bone.fMaxConstraint
					min = min + bone.fMinConstraint
					bone.fAngle = LM.Clamp(bone.fAngle, min, max)
				end
				bone.fTempAngle = bone.fAngle
				if (mouseEvent.shiftKey) then
					bone.fAngle = bone.fAngle / (math.pi / 4)
					bone.fAngle = (math.pi / 4) * LM.Round(bone.fAngle)
				end
				bone.fAnimAngle:SetValue(moho.frame, bone.fAngle)
				moho.layer:UpdateCurFrame()
			end
			bone.fAngle = bone.fAnimAngle.value
		end
	end
	mouseEvent.view:DrawMe()
	self.lastVec:Set(mouseEvent.vec)
end
function LM_RotateBone:OnMouseUp(moho, mouseEvent)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return
	end
	if ((moho.frame > 0) and (moho:CountSelectedBones() > 0)) then
		for i = 0, skel:CountBones() - 1 do
			local bone = skel:Bone(i)
			if (bone.fSelected) then
				bone.fAnimAngle:SetValue(moho.frame, bone.fAngle)
			end
		end
		moho.layer:UpdateCurFrame()
		moho:NewKeyframe(CHANNEL_BONE)
	end
	self.selID = -1
	mouseEvent.view:DrawMe()
end
function LM_RotateBone:OnKeyDown(moho, keyEvent)
	LM_SelectBone:OnKeyDown(moho, keyEvent)
end
-- **************************************************
-- Tool options - create and respond to tool's UI
-- **************************************************
LM_RotateBone.CHANGE = MOHO.MSG_BASE
LM_RotateBone.RESET = MOHO.MSG_BASE + 1
LM_RotateBone.DUMMY = MOHO.MSG_BASE + 2
LM_RotateBone.SELECTITEM = MOHO.MSG_BASE + 3
function LM_RotateBone:DoLayout(moho, layout)
	self.menu = LM.GUI.Menu("Select Bone")
	self.popup = LM.GUI.PopupMenu(128, false)
	self.popup:SetMenu(self.menu)
	layout:AddChild(self.popup)
	layout:AddChild(LM.GUI.StaticText("Angle:"))
	self.angle = LM.GUI.TextControl(0, "000.0000", self.CHANGE, LM.GUI.FIELD_FLOAT)
	self.angle:SetWheelInc(1)--Slowed Down
	layout:AddChild(self.angle)
	self.reset = LM.GUI.Button("Reset", self.RESET)
	layout:AddChild(self.reset)
end
function LM_RotateBone:UpdateWidgets(moho)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return
	end
	MOHO.BuildBoneMenu(self.menu, skel, self.SELECTITEM, self.DUMMY)
	if (moho:CountSelectedBones() > 0) then
		local selCount = 0
		local angle = 0
		for i = 0, skel:CountBones() - 1 do
			local bone = skel:Bone(i)
			if (bone.fSelected) then
				selCount = selCount + 1
				angle = angle + bone.fAngle
			end
		end
		self.angle:SetValue(math.deg(angle) / selCount)
	else
		self.angle:SetValue("")
	end
	if (moho.frame == 0) then
		self.reset:Enable(false)
	else
		self.reset:Enable(true)
	end
end
function LM_RotateBone:HandleMessage(moho, view, msg)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return
	end
	if (msg == self.RESET) then
		if (moho:CountSelectedBones() > 0) then
			moho.document:PrepUndo(moho.layer)
			moho.document:SetDirty()
			for i = 0, skel:CountBones() - 1 do
				local bone = skel:Bone(i)
				if (bone.fSelected) then
					bone.fAnimAngle:SetValue(moho.frame, bone.fAnimAngle:GetValue(0))
				end
			end
			moho.layer:UpdateCurFrame()
			moho:NewKeyframe(CHANNEL_BONE)
			self:UpdateWidgets(moho)
		end
	elseif (msg == self.CHANGE) then
		if (moho:CountSelectedBones() > 0) then
			moho.document:PrepUndo(moho.layer)
			moho.document:SetDirty()
			for i = 0, skel:CountBones() - 1 do
				local bone = skel:Bone(i)
				if (bone.fSelected) then
					bone.fAngle = math.rad(self.angle:FloatValue())
					bone.fAnimAngle:SetValue(moho.frame, bone.fAngle)
				end
			end
			moho.layer:UpdateCurFrame()
			moho:NewKeyframe(CHANNEL_BONE)
		end
	elseif (msg >= self.SELECTITEM) then
		for i = 0, skel:CountBones() - 1 do
			skel:Bone(i).fSelected = (i == msg - self.SELECTITEM)
		end
		moho:UpdateUI()
	end
end