Image
-- **************************************************
-- Provide Moho with the name of this script object
-- **************************************************

ScriptName = "AM_Create_Limb"

-- **************************************************
-- General information about this script
-- **************************************************

AM_Create_Limb = {}

function AM_Create_Limb:Name()
	return 'Create Limb'
end

function AM_Create_Limb:Version()
	return '1.0'
end

function AM_Create_Limb:UILabel()
	return 'Create Limb'
end

function AM_Create_Limb:Creator()
	return 'Aleksei Maletin'
end

function AM_Create_Limb:Description()
	return 'Hold <Alt> and drag side to side to adjust radius of joints'
end


-- **************************************************
-- Is Relevant / Is Enabled
-- **************************************************

function AM_Create_Limb:IsRelevant(moho)
	if moho:Skeleton() then
		return true
	else
		return false
	end
end

function AM_Create_Limb:IsEnabled(moho)
	if moho:Skeleton() then
		return true
	else
		return false
	end
end

-- **************************************************
-- Recurring Values
-- **************************************************

AM_Create_Limb.radius = 0.05
AM_Create_Limb.enableArrows = true
AM_Create_Limb.savedVal = 0
AM_Create_Limb.createDeformer = false
AM_Create_Limb.bodyPartName = 'Forearm L'
AM_Create_Limb.stroke = false
AM_Create_Limb.fill = false
AM_Create_Limb.selRect = LM.Rect:new_local()
AM_Create_Limb.startJoint = true
AM_Create_Limb.endJoint = true
AM_Create_Limb.startJointTest = true

-- **************************************************
-- Prefs
-- **************************************************

function AM_Create_Limb:LoadPrefs(prefs)
	self.radius = prefs:GetFloat("AM_Create_Limb.radius", 0)
	self.bodypartName = prefs:GetString("AM_Create_Limb.bodypartName", 'Forearm L')
	self.stroke = prefs:GetBool("AM_Create_Limb.stroke", false)
    self.fill = prefs:GetBool("AM_Create_Limb.fill", false)
	self.startJoint = prefs:GetBool("AM_Create_Limb.startJoint", true)
    self.endJoint = prefs:GetBool("AM_Create_Limb.endJoint", true)
end

function AM_Create_Limb:SavePrefs(prefs)
	prefs:SetFloat("AM_Create_Limb.radius", self.radius)
	prefs:SetString("AM_Create_Limb.bodypartName", self.bodypartName)
	prefs:SetBool("AM_Create_Limb.stroke", self.stroke)
    prefs:SetBool("AM_Create_Limb.fill", self.fill)
	prefs:SetBool("AM_Create_Limb.startJoint", self.startJoint)
    prefs:SetBool("AM_Create_Limb.endJoint", self.endJoint)
end

function AM_Create_Limb:ResetPrefs()
	self.radius = 0
	self.bodypartName = 'Forearm L'
	self.stroke = false
    self.fill = false
	self.startJoint = true
    self.endJoint = true
end

-- **************************************************
-- Keyboard/Mouse Control
-- **************************************************



function AM_Create_Limb:Select(moho, mousePt, mouseVec, mouseView, shiftSelect, ctrlSelect, altSelect)
	self.selBoneID = -1

	local parentSkeleton = false
	local skel = moho:Skeleton()
	if (skel == nil) then
		if (self:ShouldUseParentSkeleton(moho)) then
			skel = moho:ParentSkeleton()
			parentSkeleton = true
		end
		if (skel == nil) then
			return
		end
	end

	local id = -1
	if (parentSkeleton) then
		id = mouseView:PickBone(mousePt, mouseVec, moho.layer:ControllingBoneLayer(), true)
	else
		id = mouseView:PickBone(mousePt, mouseVec, moho.layer, true)
	end
	self.selBoneID = id

	if (shiftSelect) then
		if (id >= 0) then
			skel:Bone(id).fSelected = true
		end
	elseif (ctrlSelect) then
		if (id >= 0) then
			skel:Bone(id).fSelected = not skel:Bone(id).fSelected
		end
	elseif (altSelect) then

	else
		for i = 0, skel:CountBones() - 1 do
			skel:Bone(i).fSelected = (i == id)
		end
	end

	moho:UpdateBonePointSelection()
	mouseView:DrawMe()
	moho:UpdateSelectedChannels()
end


function AM_Create_Limb:OnMouseDown(moho, mouseEvent)
	if not (mouseEvent.altKey) then
		self.isMouseDragging = true
	end
	
	self.selRect.left = mouseEvent.startPt.x
	self.selRect.top = mouseEvent.startPt.y
	self.selRect.right = mouseEvent.pt.x
	self.selRect.bottom = mouseEvent.pt.y
	mouseEvent.view:Graphics():SelectionRect(self.selRect)
	mouseEvent.view:DrawMe()
	self.savedVal = 0
	self:Select(moho, mouseEvent.pt, mouseEvent.vec, mouseEvent.view, mouseEvent.shiftKey, mouseEvent.ctrlKey, mouseEvent.altKey)
end

function AM_Create_Limb:OnMouseMoved(moho, mouseEvent)
	local skel = moho:Skeleton()
	if (mouseEvent.altKey) then
		
		if (skel == nil) then
			return
		end

		local newVal = 1 * (mouseEvent.pt.x - mouseEvent.startPt.x) / mouseEvent.view:Graphics():Width()

		for i = 0, skel:CountBones() - 1 do
			local bone = skel:Bone(i)
			if (bone.fSelected) then
				self.radius = self.radius - self.savedVal + newVal
				if (self.radius < 0) then
					self.radius = 0
				end
			end
		end
		self.savedVal = newVal
	else
		mouseEvent.view:Graphics():SelectionRect(self.selRect)
		self.selRect.right = mouseEvent.pt.x
		self.selRect.bottom = mouseEvent.pt.y
		mouseEvent.view:Graphics():SelectionRect(self.selRect)
		mouseEvent.view:RefreshView()
	end

	mouseEvent.view:DrawMe()
end

function AM_Create_Limb:OnMouseUp(moho, mouseEvent)
	local skel = moho:Skeleton()
	
	local mouseDist = math.abs(mouseEvent.pt.x - mouseEvent.startPt.x) + math.abs(mouseEvent.pt.y - mouseEvent.startPt.y)

	self.isMouseDragging = false

	local v = LM.Vector2:new_local()
	local screenPt = LM.Point:new_local()
	local m = LM.Matrix:new_local()

	self.selRect:Normalize()
	moho.drawingLayer:GetFullTransform(moho.frame, m, moho.document)

	if skel then
		
		for i = 0, skel:CountBones() - 1 do
			local bone = skel:Bone(i)
			local boneMatrix = bone.fMovedMatrix
			for j = 0, 10 do
				v:Set(bone.fLength * j / 10.0, 0)
				boneMatrix:Transform(v)
				m:Transform(v)
				mouseEvent.view:Graphics():WorldToScreen(v, screenPt)
				if (self.selRect:Contains(screenPt)) then
						if mouseEvent.ctrlKey then
							bone.fSelected = not bone.fSelected
						else
							bone.fSelected = true
						end
						
					break
				end
			end
		end
	end

	moho:UpdateSelectedChannels()
end

function AM_Create_Limb:GetGlobalBonePos(moho, bone)
	local skel = moho:Skeleton()
	local selBonePos = LM.Vector2:new_local()
	selBonePos:Set(bone.fAnimPos:GetValue(0))
	if bone.fParent >-1 then
	  local selBoneParentMatrix = LM.Matrix:new_local()
	  selBoneParentMatrix:Set(skel:Bone(bone.fParent).fRestMatrix)
	  selBoneParentMatrix:Transform(selBonePos)
	end
	return selBonePos
end
  
function AM_Create_Limb:GetGlobalAngle(moho, v1, v2)
	v2 = v2 - v1
	newAngle = math.atan2(v2.y, v2.x)
	return newAngle
end


function AM_Create_Limb:DrawBothJoints(moho, srcVec1, srcVec2, srcMesh)

  
	local circleVec = LM.Vector2:new_local()
  
	circleVec.x = srcVec1.x - self.radius
	circleVec.y = srcVec1.y
	srcMesh:AddLonePoint(circleVec, 0)
	
	circleVec.x = srcVec1.x
	circleVec.y = srcVec1.y - self.radius
	srcMesh:AppendPoint(circleVec, 0)
  
	circleVec.x = srcVec1.x + self.radius
	circleVec.y = srcVec1.y
	srcMesh:AppendPoint(circleVec, 0)
  
	circleVec.x = srcVec1.x
	circleVec.y = srcVec1.y + self.radius
	srcMesh:AppendPoint(circleVec, 0)
  
	circleVec.x = srcVec1.x - self.radius
	circleVec.y = srcVec1.y
	srcMesh:AppendPoint(circleVec, 0)
  
	srcMesh:WeldPoints(4, 0, 0)
	
	
	circleVec.x = srcVec2.x - self.radius
	circleVec.y = srcVec2.y
	srcMesh:AddLonePoint(circleVec, 0)
	
	circleVec.x = srcVec2.x
	circleVec.y = srcVec2.y - self.radius
	srcMesh:AppendPoint(circleVec, 0)
  
	circleVec.x = srcVec2.x + self.radius
	circleVec.y = srcVec2.y
	srcMesh:AppendPoint(circleVec, 0)
  
	circleVec.x = srcVec2.x
	circleVec.y = srcVec2.y + self.radius
	srcMesh:AppendPoint(circleVec, 0)
  
	circleVec.x = srcVec2.x - self.radius
	circleVec.y = srcVec2.y
	srcMesh:AppendPoint(circleVec, 0)
  
	srcMesh:WeldPoints(8, 4, 0)
	
	for i = 0, srcMesh:CountPoints()-1 do
	  srcMesh:Point(i):SetCurvature(0.391379, 0)
	end
	
	srcMesh:DeselectPoints()
end


function AM_Create_Limb:DrawStartJoint(moho, srcVec1, srcMesh)

  
	local circleVec = LM.Vector2:new_local()
  
	circleVec.x = srcVec1.x - self.radius
	circleVec.y = srcVec1.y
	srcMesh:AddLonePoint(circleVec, 0)
	
	circleVec.x = srcVec1.x
	circleVec.y = srcVec1.y - self.radius
	srcMesh:AppendPoint(circleVec, 0)
  
	circleVec.x = srcVec1.x + self.radius
	circleVec.y = srcVec1.y
	srcMesh:AppendPoint(circleVec, 0)
  
	circleVec.x = srcVec1.x
	circleVec.y = srcVec1.y + self.radius
	srcMesh:AppendPoint(circleVec, 0)
  
	circleVec.x = srcVec1.x - self.radius
	circleVec.y = srcVec1.y
	srcMesh:AppendPoint(circleVec, 0)
  
	srcMesh:WeldPoints(4, 0, 0)
	
	
	for i = 0, srcMesh:CountPoints()-1 do
	  srcMesh:Point(i):SetCurvature(0.391379, 0)
	end
	
	srcMesh:DeselectPoints()
end


function AM_Create_Limb:DrawEndJoint(moho, srcVec2, srcMesh)

  
	local circleVec = LM.Vector2:new_local()
  	circleVec.x = srcVec2.x - self.radius
	circleVec.y = srcVec2.y
	srcMesh:AddLonePoint(circleVec, 0)
	
	circleVec.x = srcVec2.x
	circleVec.y = srcVec2.y - self.radius
	srcMesh:AppendPoint(circleVec, 0)
  
	circleVec.x = srcVec2.x + self.radius
	circleVec.y = srcVec2.y
	srcMesh:AppendPoint(circleVec, 0)
  
	circleVec.x = srcVec2.x
	circleVec.y = srcVec2.y + self.radius
	srcMesh:AppendPoint(circleVec, 0)
  
	circleVec.x = srcVec2.x - self.radius
	circleVec.y = srcVec2.y
	srcMesh:AppendPoint(circleVec, 0)

  
	srcMesh:WeldPoints(4, 0, 0)

	for i = 0, srcMesh:CountPoints()-1 do
	  srcMesh:Point(i):SetCurvature(0.391379, 0)
	end
	
	srcMesh:DeselectPoints()
end


function AM_Create_Limb:DrawMe(moho, view)

	local skel = moho:Skeleton()
	if skel then
		local g = view:Graphics()
		local matrix = LM.Matrix:new_local()
		local bonePt = LM.Vector2:new_local()
		local bonePt2 = LM.Vector2:new_local()

		moho.layer:GetFullTransform(moho.frame, matrix, moho.document)
		g:Push()
		g:ApplyMatrix(matrix)
		g:SetColor(50, 255, 50, 50)
		g:SetSmoothing(true)
		for i = 0, skel:CountBones() - 1 do
			local bone = skel:Bone(i)
			if bone.fSelected then
				local parentBone = skel:Bone(bone.fAngleControlParent)

				bonePt:Set(bone.fLength, 0)
				bone.fMovedMatrix:Transform(bonePt)

				bonePt2:Set(0, 0)
				bone.fMovedMatrix:Transform(bonePt2)

				g:FrameCircle(bonePt, self.radius)
				g:FrameCircle(bonePt2, self.radius)
				g:FillCircle(bonePt, self.radius)
				g:FillCircle(bonePt2, self.radius)

			end
		end

		if self.isMouseDragging then
			local g = view:Graphics()
			g:SelectionRect(self.selRect)
		end

		g:Pop()
	end
	

end

-- **************************************************
-- Tool Panel Layout
-- **************************************************

AM_Create_Limb.CREATE_LIMB = MOHO.MSG_BASE
AM_Create_Limb.RADIUS = MOHO.MSG_BASE + 1
AM_Create_Limb.BODYPART_NAME = MOHO.MSG_BASE + 2
AM_Create_Limb.STROKE = MOHO.MSG_BASE + 3
AM_Create_Limb.FILL = MOHO.MSG_BASE + 4
AM_Create_Limb.READ_RADIUS_FROM_BONE = MOHO.MSG_BASE + 5
AM_Create_Limb.START_JOINT = MOHO.MSG_BASE + 6
AM_Create_Limb.END_JOINT = MOHO.MSG_BASE + 7

function AM_Create_Limb:DoLayout(moho, layout)

	self.createLimbButton = LM.GUI.Button('Create Limb', self.CREATE_LIMB)
	layout:AddChild(self.createLimbButton, LM.GUI.ALIGN_LEFT, 0)

	self.radiusInput = LM.GUI.TextControl(0, '           ', self.RADIUS, LM.GUI.FIELD_FLOAT, 'Radius')
	self.radiusInput:SetWheelInc(0.001)
	layout:AddChild(self.radiusInput, LM.GUI.ALIGN_LEFT, 0)

	self.bodyPartNameInput = LM.GUI.TextControl(0, 'Forearm L', self.BODYPART_NAME, LM.GUI.FIELD_TEXT, 'Bodypart Name:')
    layout:AddChild(self.bodyPartNameInput, LM.GUI.ALIGN_LEFT, 0)

	self.strokeCheckbox = LM.GUI.CheckBox('Stroke', self.STROKE)
    layout:AddChild(self.strokeCheckbox, LM.GUI.ALIGN_LEFT, 0)

    self.fillCheckbox = LM.GUI.CheckBox('Fill', self.FILL)
    layout:AddChild(self.fillCheckbox, LM.GUI.ALIGN_LEFT, 0)

	self.readRadiusFromBoneButton = LM.GUI.Button('Read radius', self.READ_RADIUS_FROM_BONE)
	layout:AddChild(self.readRadiusFromBoneButton, LM.GUI.ALIGN_LEFT, 0)
	self.readRadiusFromBoneButton:SetToolTip('Radius = Length of selected bone')

	self.startJointCheckbox = LM.GUI.CheckBox('Start joint', self.START_JOINT)
	layout:AddChild(self.startJointCheckbox, LM.GUI.ALIGN_LEFT, 0)

	self.endJointCheckbox = LM.GUI.CheckBox('End joint', self.END_JOINT)
	layout:AddChild(self.endJointCheckbox, LM.GUI.ALIGN_LEFT, 0)
end

function AM_Create_Limb:UpdateWidgets(moho)
	AM_Create_Limb.radiusInput:SetValue(self.radius)
	AM_Create_Limb.bodyPartNameInput:SetValue(self.bodyPartName)
	AM_Create_Limb.strokeCheckbox:SetValue(self.stroke)
    AM_Create_Limb.fillCheckbox:SetValue(self.fill)
    AM_Create_Limb.startJointCheckbox:SetValue(self.startJoint)
    AM_Create_Limb.endJointCheckbox:SetValue(self.endJoint)
end

function AM_Create_Limb:HandleMessage(moho, view, msg)
	if msg == self.RADIUS then
	
		self.radius = self.radiusInput:Value()
		
	elseif msg == self.CREATE_LIMB then

		if (curFrame ~= frame0) then moho:SetCurFrame(frame0) end

		moho.document:SetDirty()
		moho.document:PrepUndo(nil)



		local boneLayer = moho:LayerAsBone(moho.layer)
		local skel = moho:Skeleton()

		for iBone = 0, skel:CountBones()-1  do

			local bone = skel:Bone(iBone)
			

			if (bone.fSelected) then
				local boneparent = skel:Bone(bone.fAnimParent:GetValue())
				
				if boneparent and boneparent.fSelected then
					self.startJointTest = false
				else
					self.startJointTest = true
				end

				local boneLength = bone.fLength
				bone.fStrength = 0

				local boneStart = skel:AddBone(0)
				boneStart.fParent = iBone
				boneStart.fAnimParent:SetValue(0, iBone)
				boneStart.fAnimAngle:SetValue(0, math.rad(0))
				boneStart.fIgnoredByIK = true
				boneStart:SetName(self.bodyPartName .. " start")
				boneStart.fShy = true
				boneStart.fLength = self.radius
				boneStart.fStrength = 0
				local boneStartGlobalPose = self:GetGlobalBonePos(moho, boneStart)
				local boneLengthPos = LM.Vector2:new_local()
				local boneStartParentID = skel:BoneID(boneStart)
				boneLengthPos.x = boneStartGlobalPose.x + boneLength
				boneLengthPos.y = boneStartGlobalPose.y

				local boneEnd = skel:AddBone(0)
				local boneEndPos = LM.Vector2:new_local()
				boneEndPos:Set(boneLength, 0)
				boneEnd.fParent = iBone
				boneEnd.fAnimParent:SetValue(0, iBone)
				boneEnd.fAnimAngle:SetValue(0, math.rad(180))
				boneEnd.fIgnoredByIK = true
				boneEnd:SetName(self.bodyPartName .. " end")
				boneEnd.fShy = true
				boneEnd.fAnimPos:SetValue(0, boneEndPos)
				boneEnd.fLength = self.radius
				boneEnd.fStrength = 0
				local boneEndGlobalPose = self:GetGlobalBonePos(moho, boneEnd)
				local boneEndParentID = skel:BoneID(boneEnd)

				local boneGlobalAngle = self:GetGlobalAngle(moho, boneStartGlobalPose, boneEndGlobalPose)

				local bodypartGroup = moho:CreateNewLayer(MOHO.LT_GROUP, false)
				bodypartGroup:SetName(self.bodyPartName)			
				bodypartGroup.fRotationZ:SetValue(0, boneGlobalAngle)  
				bodypartGroup:SetOrigin(boneStartGlobalPose)
				moho:PlaceLayerInGroup(bodypartGroup, boneLayer, true, false)

				local jointsLayer = moho:LayerAsVector(moho:CreateNewLayer(MOHO.LT_VECTOR, false))
				if self.stroke then
					jointsLayer:ShowConstructionCurves(false)
				elseif self.fill then
					jointsLayer:ShowConstructionCurves(false)
				else
					jointsLayer:ShowConstructionCurves(true)
				end

				jointsLayer:SetName(self.bodyPartName .. " joints")
				moho:PlaceLayerInGroup(jointsLayer, bodypartGroup, true, false)
				local jointsMesh = jointsLayer:Mesh()

				if self.startJoint and self.endJoint and self.startJointTest then
					self:DrawBothJoints(moho, boneStartGlobalPose, boneLengthPos, jointsMesh)

					jointsMesh:Point(0).fParent = boneStartParentID
					jointsMesh:Point(1).fParent = boneStartParentID
					jointsMesh:Point(2).fParent = boneStartParentID
					jointsMesh:Point(3).fParent = boneStartParentID
	
					jointsMesh:Point(4).fParent = boneEndParentID
					jointsMesh:Point(5).fParent = boneEndParentID
					jointsMesh:Point(6).fParent = boneEndParentID
					jointsMesh:Point(7).fParent = boneEndParentID
	
				elseif self.startJointTest and self.startJoint then
					self:DrawStartJoint(moho, boneStartGlobalPose, jointsMesh)

					jointsMesh:Point(0).fParent = boneStartParentID
					jointsMesh:Point(1).fParent = boneStartParentID
					jointsMesh:Point(2).fParent = boneStartParentID
					jointsMesh:Point(3).fParent = boneStartParentID
				elseif self.endJoint then
					self:DrawEndJoint(moho, boneLengthPos, jointsMesh)
					jointsMesh:Point(0).fParent = boneEndParentID
					jointsMesh:Point(1).fParent = boneEndParentID
					jointsMesh:Point(2).fParent = boneEndParentID
					jointsMesh:Point(3).fParent = boneEndParentID
				elseif self.startJoint and self.endJoint and not self.startJointTest then
					self:DrawEndJoint(moho, boneLengthPos, jointsMesh)
					jointsMesh:Point(0).fParent = boneEndParentID
					jointsMesh:Point(1).fParent = boneEndParentID
					jointsMesh:Point(2).fParent = boneEndParentID
					jointsMesh:Point(3).fParent = boneEndParentID
				else
				end
				if self.startJoint and not self.endJoint and not self.startJointTest then
				else

					jointsMesh:SelectAll()
					if moho:CountSelectedPoints() > 0 then
						local jointsShapeID = moho:CreateShape(true)
						local jointsShape = jointsMesh:Shape(jointsShapeID)
						
						jointsShape.fHasFill = self.fill
						jointsShape.fHasOutline = self.stroke
					end
				end


				moho:SetSelLayer(boneLayer, false, true)

				local bodypartLayer = moho:LayerAsVector(moho:CreateNewLayer(MOHO.LT_VECTOR, false))
				if self.stroke then
					bodypartLayer:ShowConstructionCurves(false)
				elseif self.fill then
					bodypartLayer:ShowConstructionCurves(false)
				else
					bodypartLayer:ShowConstructionCurves(true)
				end
			
				bodypartLayer:SetName(self.bodyPartName)
				moho:PlaceLayerInGroup(bodypartLayer, bodypartGroup, true, false)
				local bodypartMesh = bodypartLayer:Mesh()

				local rectStart = LM.Vector2:new_local()
				rectStart.x = boneStartGlobalPose.x
				rectStart.y = boneStartGlobalPose.y + self.radius
				bodypartMesh:AddLonePoint(rectStart, 0)

				rectStart.x = boneStartGlobalPose.x + boneLength
				bodypartMesh:AppendPoint(rectStart, 0)

				rectStart.y = boneStartGlobalPose.y - self.radius
				bodypartMesh:AppendPoint(rectStart, 0)

				rectStart.x = boneStartGlobalPose.x
				bodypartMesh:AppendPoint(rectStart, 0)

				rectStart.y = boneStartGlobalPose.y + self.radius
				bodypartMesh:AppendPoint(rectStart, 0)

				bodypartMesh:WeldPoints(4, 0, 0)

				bodypartMesh:Point(0).fParent = boneStartParentID
				bodypartMesh:Point(3).fParent = boneStartParentID

				bodypartMesh:Point(1).fParent = boneEndParentID
				bodypartMesh:Point(2).fParent = boneEndParentID
				for i = 0, bodypartMesh:CountPoints()-1 do
					bodypartMesh:Point(i):SetCurvature(0, 0)
				end

				bodypartMesh:SelectNone()
				bodypartMesh:Point(0).fSelected = true
				bodypartMesh:Point(1).fSelected = true
				bodypartMesh:Point(2).fSelected = true
				bodypartMesh:Point(3).fSelected = true

				local bodypartCurve = bodypartMesh:Curve()
				if self.endJoint then
					bodypartCurve:SetSegmentOn(1, false)
				end
		
				bodypartCurve:SetSegmentOn(3, false)


				local limbShapeID = moho:CreateShape(true)
				local limbShape = bodypartMesh:Shape(limbShapeID)
				limbShape.fHasFill = self.fill
				limbShape.fHasOutline = self.stroke


				moho:SetSelLayer(boneLayer, false, true)

			end
			moho:UpdateUI()
			moho.layer:UpdateCurFrame()
		end 
		

	elseif msg == self.BODYPART_NAME then


		self.bodyPartName = self.bodyPartNameInput:Value()
	
	elseif msg == self.STROKE then
		self.stroke = self.strokeCheckbox:Value()
    elseif msg == self.FILL then
		self.fill = self.fillCheckbox:Value()
	elseif msg == self.READ_RADIUS_FROM_BONE then
		local skel = moho:Skeleton()
		for i = 0, skel:CountBones() - 1 do
			local bone = skel:Bone(i)
			if bone.fSelected then
				self.radius = bone.fLength
				break
			end
		end
		self:UpdateWidgets(moho)
    elseif msg == self.START_JOINT then
        self.startJoint = self.startJointCheckbox:Value()
    elseif msg == self.END_JOINT then
        self.endJoint = self.endJointCheckbox:Value()
	else
		
	end
end

Icon
Create Limb
Listed

Script type: Tool

Uploaded: Jan 24 2022, 11:14

Simple tool for rigging arms/legs
Note: The newer, better version is available here


Hold Alt  and drag side to side to adjust radius of joints
This script, and all other scripts on this site are distributed as free software under the GNU General Public License 3.0 or later.
Downloads count: 1849