Slower bone rotation?

Moho allows users to write new tools and plugins. Discuss scripting ideas and problems here.

Moderators: Víctor Paredes, Belgarath, slowtiger

Post Reply
User avatar
Manu
Posts: 327
Joined: Tue Aug 03, 2004 10:11 pm
Contact:

Slower bone rotation?

Post by Manu »

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?
User avatar
Rasheed
Posts: 2008
Joined: Tue May 17, 2005 8:30 am
Location: The Netherlands

Post by Rasheed »

I don't understand what you mean. The tip of the bone follows the mouse vector. If you want the bone to rotate slower, you simply move your move vector slower. If your mouse vector moves too fast, you need to adjust your mouse system settings.
User avatar
Hiddicop
Posts: 250
Joined: Sun Nov 07, 2004 4:18 pm
Location: Sweden

Post by Hiddicop »

I'm not sure I understand what you mean...

The further away from the bones orgin (where the two inner lines cross eachother), the "slower" the bone is rotated. If you click at the very cross it's almost impossible to control the bone, but the further away you click, the more precise it gets.
User avatar
rylleman
Posts: 750
Joined: Tue Feb 15, 2005 5:22 pm
Location: sweden
Contact:

Post by rylleman »

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.
User avatar
Manu
Posts: 327
Joined: Tue Aug 03, 2004 10:11 pm
Contact:

Post by Manu »

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.
So did you get the 1/10th movement to work? The rest is probably of lesser interest to me.
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.
User avatar
Rai López
Posts: 2259
Joined: Sun Aug 08, 2004 1:41 pm
Location: Spain
Contact:

Post by Rai López »

Hiddicop wrote:The further away from the bones orgin (where the two inner lines cross eachother), the "slower" the bone is rotated.
Not always... have you tried to rotate several bones at a time in this way?
User avatar
rylleman
Posts: 750
Joined: Tue Feb 15, 2005 5:22 pm
Location: sweden
Contact:

Post by rylleman »

Manu wrote:So did you get the 1/10th movement to work?
Well, it rotates 1/10 but the problem is that when you grab the bone it makes a jump with a few degrees so it's not usable yet. I'll see if I can get it to work tomorrow.
User avatar
Manu
Posts: 327
Joined: Tue Aug 03, 2004 10:11 pm
Contact:

Yippeeee

Post by Manu »

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:

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
			end
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:

Code: Select all

self.angle:SetWheelInc(1)--Slowed Down
In the original script it reads 5 between the brackets.
User avatar
Manu
Posts: 327
Joined: Tue Aug 03, 2004 10:11 pm
Contact:

Post by Manu »

...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
Post Reply