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

ScriptName = "AM_Create_Limb_V2"

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

AM_Create_Limb_V2 = {}

function AM_Create_Limb_V2:Name()
	return 'Create Limb 2'
end

function AM_Create_Limb_V2:Version()
	return '1.0'
end

function AM_Create_Limb_V2:UILabel()
	return 'Create Limb 2'
end

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

function AM_Create_Limb_V2:Description()
	return 'Hold <Alt> and drag side to side to adjust radius of both joints. Hold <Shift> and drag side to side to adjust radius of end joint'
end


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

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

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

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

AM_Create_Limb_V2.baseBodypart = true
AM_Create_Limb_V2.endOfForearmShin = false
AM_Create_Limb_V2.startRadius = 0
AM_Create_Limb_V2.endRadius = 0
AM_Create_Limb_V2.bodyPartName = 'Forearm L'
AM_Create_Limb_V2.stroke = false
AM_Create_Limb_V2.fill = false
AM_Create_Limb_V2.startJoint = true
AM_Create_Limb_V2.startJoint2 = true
AM_Create_Limb_V2.startJointTest = true
AM_Create_Limb_V2.endJoint = true
AM_Create_Limb_V2.endJoint2 = true
AM_Create_Limb_V2.makeTangentForm = true
AM_Create_Limb_V2.makeTangentForm2 = true
AM_Create_Limb_V2.groupAndSeparate = false
AM_Create_Limb_V2.createDeformer = false
AM_Create_Limb_V2.magnitude = 0
AM_Create_Limb_V2.selRect = LM.Rect:new_local()
AM_Create_Limb_V2.currentShapeSettings = 1 -- 1 for Base bodypart, 2 for end of forearm/shin
AM_Create_Limb_V2.sleeveLength = 1.00
AM_Create_Limb_V2.startRadius2 = 0
AM_Create_Limb_V2.endRadius2 = 0
AM_Create_Limb_V2.magnitude2 = 0
AM_Create_Limb_V2.sleeveDefault = 1
AM_Create_Limb_V2.sleeve = 1

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


function AM_Create_Limb_V2:LoadPrefs(prefs)
	self.baseBodypart = prefs:GetBool("AM_Create_Limb_V2.baseBodypart", true)
	self.endOfForearmShin = prefs:GetBool("AM_Create_Limb_V2.endOfForearmShin", false)
	self.startRadius = prefs:GetFloat("AM_Create_Limb_V2.startRadius", 0)
	self.endRadius = prefs:GetFloat("AM_Create_Limb_V2.endRadius", 0)
	self.bodyPartName = prefs:GetString("AM_Create_Limb_V2.bodyPartName", 'Forearm L')
	self.stroke = prefs:GetBool("AM_Create_Limb_V2.stroke", false)
	self.fill = prefs:GetBool("AM_Create_Limb_V2.fill", false)
	self.startJoint = prefs:GetBool("AM_Create_Limb_V2.startJoint", true)
	self.endJoint = prefs:GetBool("AM_Create_Limb_V2.endJoint", true)
	self.startJoint2 = prefs:GetBool("AM_Create_Limb_V2.startJoint2", true)
	self.endJoint2 = prefs:GetBool("AM_Create_Limb_V2.endJoint2", true)
	self.makeTangentForm = prefs:GetBool("AM_Create_Limb_V2.makeTangentForm", true)
	self.makeTangentForm2 = prefs:GetBool("AM_Create_Limb_V2.makeTangentForm2", true)
	self.groupAndSeparate = prefs:GetBool("AM_Create_Limb_V2.groupAndSeparate", false)
	self.createDeformer = prefs:GetBool("AM_Create_Limb_V2.createDeformer", false)
	self.currentShapeSettings = prefs:GetFloat("AM_Create_Limb_V2.currentShapeSettings", 1)
	self.sleeveLength = prefs:GetFloat("AM_Create_Limb_V2.sleeveLength", 1.00)
	self.startRadius2 = prefs:GetFloat("AM_Create_Limb_V2.startRadius2", 0)
	self.endRadius2 = prefs:GetFloat("AM_Create_Limb_V2.endRadius2", 0)
	self.magnitude = prefs:GetFloat("AM_Create_Limb_V2.magnitude", 0)
    self.magnitude2 = prefs:GetFloat("AM_Create_Limb_V2.magnitude2", 0)

end

function AM_Create_Limb_V2:SavePrefs(prefs)
	prefs:SetBool("AM_Create_Limb_V2.baseBodypart", self.baseBodypart)
	prefs:SetBool("AM_Create_Limb_V2.endOfForearmShin", self.endOfForearmShin)
	prefs:SetFloat("AM_Create_Limb_V2.startRadius", self.startRadius)
	prefs:SetFloat("AM_Create_Limb_V2.endRadius", self.endRadius)
	prefs:SetString("AM_Create_Limb_V2.bodyPartName", self.bodyPartName)
	prefs:SetBool("AM_Create_Limb_V2.stroke", self.stroke)
	prefs:SetBool("AM_Create_Limb_V2.fill", self.fill)
	prefs:SetBool("AM_Create_Limb_V2.startJoint", self.startJoint)
	prefs:SetBool("AM_Create_Limb_V2.endJoint", self.endJoint)
	prefs:SetBool("AM_Create_Limb_V2.startJoint2", self.startJoint2)
	prefs:SetBool("AM_Create_Limb_V2.endJoint2", self.endJoint2)
	prefs:SetBool("AM_Create_Limb_V2.makeTangentForm", self.makeTangentForm)
	prefs:SetBool("AM_Create_Limb_V2.makeTangentForm2", self.makeTangentForm2)
	prefs:SetBool("AM_Create_Limb_V2.groupAndSeparate", self.groupAndSeparate)
	prefs:SetBool("AM_Create_Limb_V2.createDeformer", self.createDeformer)
	prefs:SetFloat("AM_Create_Limb_V2.currentShapeSettings", self.currentShapeSettings)
	prefs:SetFloat("AM_Create_Limb_V2.sleeveLength", self.sleeveLength)
	prefs:SetFloat("AM_Create_Limb_V2.startRadius2", self.startRadius2)
	prefs:SetFloat("AM_Create_Limb_V2.endRadius2", self.endRadius2)
	prefs:SetFloat("AM_Create_Limb_V2.magnitude", self.magnitude)
    prefs:SetFloat("AM_Create_Limb_V2.magnitude2", self.magnitude2)
end

function AM_Create_Limb_V2:ResetPrefs()
	self.baseBodypart = true
	self.endOfForearmShin = false
	self.startRadius = 0
	self.endRadius = 0
	self.bodyPartName = 'Forearm L'
	self.stroke = false
	self.fill = false
	self.startJoint = true
	self.endJoint = true
	self.startJoint2 = true
	self.endJoint2 = true
	self.makeTangentForm = true
	self.makeTangentForm2 = true
	self.groupAndSeparate = false
	self.createDeformer = false
	self.currentShapeSettings = 1
	self.sleeveLength = 1.00
	self.startRadius2 = 0
	self.endRadius2 = 0
	self.magnitude = 0
    self.magnitude2 = 0
end

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

function AM_Create_Limb_V2:OnMouseDown(moho, mouseEvent)
	if not (mouseEvent.altKey) or not (mouseEvent.shiftKey) 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_V2: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
				if self.baseBodypart then
					self.startRadius = self.startRadius - self.savedVal + newVal
					self.endRadius = self.startRadius + self.magnitude
					if (self.startRadius < 0) then
						self.startRadius = 0
					end
					if (self.magnitude < 0 - self.startRadius) then
						self.magnitude = 0 - self.startRadius
					end
				elseif self.endOfForearmShin then
					self.startRadius2 = self.startRadius2 - self.savedVal + newVal
					self.endRadius2 = self.startRadius2 + self.magnitude2
					if (self.startRadius2 < 0) then
						self.startRadius2 = 0
					end
					if (self.magnitude2 < 0 - self.startRadius2) then
						self.magnitude2 = 0 - self.startRadius2
					end
				end
			end
		end
		self.savedVal = newVal
	elseif (mouseEvent.shiftKey) 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
				if self.baseBodypart then
					self.magnitude = self.magnitude - self.savedVal + newVal
				
					self.endRadius = self.startRadius + self.magnitude
					if (self.magnitude < 0 - self.startRadius) then
						self.magnitude = 0 - self.startRadius
					end
				elseif self.endOfForearmShin then
					self.magnitude2 = self.magnitude2 - self.savedVal + newVal
				
					self.endRadius2 = self.startRadius2 + self.magnitude2
					if (self.magnitude2 < 0 - self.startRadius2) then
						self.magnitude2 = 0 - self.startRadius2
					end
				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_V2: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_V2:OnKeyDown(moho, keyEvent)
	
end

function AM_Create_Limb_V2:OnKeyUp(moho, keyEvent)
	
end

function AM_Create_Limb_V2: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()
		local bonePt3 = LM.Vector2:new_local()

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

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

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

				if self.startJoint then
					g:SetColor(50, 255, 50, 50)
					g:FillCircle(bonePt2, self.startRadius)
					if self.endOfForearmShin then
						g:SetColor(255, 255, 50, 50)
						g:FillCircle(bonePt2, self.startRadius2)
					end
				end
				if self.endJoint and self.makeTangentForm then
					if not self.endOfForearmShin then
						g:SetColor(50, 255, 50, 50)
						g:FillCircle(bonePt, self.endRadius)
					end
				elseif self.endJoint then
					if not self.endOfForearmShin then
						g:SetColor(50, 255, 50, 50)
						g:FillCircle(bonePt, self.startRadius)
					end
				end
				

				local boneLength = bone.fLength
				local centerA = LM.Vector2:new_local()
				centerA:Set(bone)
				bone.fMovedMatrix:Transform(centerA)
				local centerB = LM.Vector2:new_local()
				centerB:Set(bone.fLength)
				bone.fMovedMatrix:Transform(centerB)

				-- draw wrist rectangle
				
				if self.endOfForearmShin then
					
					if self.makeTangentForm2 then
						if self.startRadius2 ~= 0 or self.endRadius2 ~= 0 then
							self.sleeveEndRadius = self.startRadius + (self.endRadius - self.startRadius)*self.sleeveLength
							local pt1Coord, pt2Coord, pt3Coord, pt4Coord = self:BodyPartPointsCoords(centerA, centerB, self.startRadius2, self.endRadius2)
							g:SetColor(255, 255, 50, 50)
							g:BeginShape()
							g:AddLine(pt1Coord, pt2Coord)
							g:AddLine(pt2Coord, pt3Coord)
							g:AddLine(pt3Coord, pt4Coord)
							g:AddLine(pt4Coord, pt1Coord)
							g:EndShape()
							if self.endJoint2 then
								g:SetColor(255, 255, 50, 50)
								g:FillCircle(bonePt3, self.endRadius2)
							end
						end
					else
						if self.startRadius2 ~= 0 then
							local pt1Coord, pt2Coord, pt3Coord, pt4Coord = self:BodyPartPointsCoords(centerA, centerB, self.startRadius2, self.startRadius2)
							g:SetColor(255, 255, 50, 50)
							g:BeginShape()
							g:AddLine(pt1Coord, pt2Coord)
							g:AddLine(pt2Coord, pt3Coord)
							g:AddLine(pt3Coord, pt4Coord)
							g:AddLine(pt4Coord, pt1Coord)
							g:EndShape()
							if self.endJoint2 then
								g:SetColor(255, 255, 50, 50)
								g:FillCircle(bonePt3, self.startRadius2)
							end
						end
					end
				end

				

				if self.makeTangentForm then
					
					local pt1Coord, pt2Coord, pt3Coord, pt4Coord = self:BodyPartPointsCoords(centerA, bonePt, self.startRadius, self.sleeveEndRadius)
					g:SetColor(50, 255, 50, 50)
					g:BeginShape()
					g:AddLine(pt1Coord, pt2Coord)
					g:AddLine(pt2Coord, pt3Coord)
					g:AddLine(pt3Coord, pt4Coord)
					g:AddLine(pt4Coord, pt1Coord)
					g:EndShape()

				else
					local pt1Coord, pt2Coord, pt3Coord, pt4Coord = self:BodyPartPointsCoords(centerA, bonePt, self.startRadius, self.startRadius)
					g:SetColor(50, 255, 50, 50)
					g:BeginShape()
					g:AddLine(pt1Coord, pt2Coord)
					g:AddLine(pt2Coord, pt3Coord)
					g:AddLine(pt3Coord, pt4Coord)
					g:AddLine(pt4Coord, pt1Coord)
					g:EndShape()

				
				end

			end
		end

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

		g:Pop()
	end
end

-- **************************************************
-- guts of script
-- **************************************************


function AM_Create_Limb_V2: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_V2:BodyPartPointsCoords(centerA, centerB, radiusA, radiusB)
	
	local Yplus = math.atan2(centerB.x - centerA.x, centerB.y - centerA.y) + math.acos((radiusA - radiusB)/math.sqrt((centerB.x - centerA.x)^2+(centerB.y - centerA.y)^2))
	local Yminus = math.atan2(centerB.x - centerA.x, centerB.y - centerA.y) - math.acos((radiusA - radiusB)/math.sqrt((centerB.x - centerA.x)^2+(centerB.y - centerA.y)^2))
	local pt1Coord = LM.Vector2:new_local()
	local pt2Coord = LM.Vector2:new_local()
	local pt3Coord = LM.Vector2:new_local()
	local pt4Coord = LM.Vector2:new_local()

	local YplusCoords = LM.Vector2:new_local()
	local YminusCoords = LM.Vector2:new_local()
	YplusCoords.y = math.cos(Yminus)
	YplusCoords.x = math.sin(Yminus)
	YminusCoords.y = math.cos(Yplus)
	YminusCoords.x = math.sin(Yplus)

	local pt1CoordPlus =  LM.Vector2:new_local()
	pt1CoordPlus.x = radiusA * YminusCoords.x
	pt1CoordPlus.y = radiusA * YminusCoords.y

	pt1Coord:Set(centerA + pt1CoordPlus)

	local pt2CoordPlus = LM.Vector2:new_local()

	pt2CoordPlus.x = radiusA * YplusCoords.x
	pt2CoordPlus.y = radiusA * YplusCoords.y

	pt2Coord:Set(centerA + pt2CoordPlus)

	local pt4CoordPlus = LM.Vector2:new_local()
	pt4CoordPlus.x = radiusB * YminusCoords.x
	pt4CoordPlus.y = radiusB * YminusCoords.y

	pt4Coord:Set(centerB + pt4CoordPlus)

	local pt3CoordPlus = LM.Vector2:new_local()
	pt3CoordPlus.x = radiusB * YplusCoords.x
	pt3CoordPlus.y = radiusB * YplusCoords.y

	pt3Coord:Set(centerB + pt3CoordPlus)

	return pt1Coord, pt2Coord, pt3Coord, pt4Coord

end

function AM_Create_Limb_V2: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_V2:GetGlobalBoneEndPos(moho, bone)

end

function AM_Create_Limb_V2:ShowConstructionCurvesTest(moho, layer)
	if self.stroke then
		layer:ShowConstructionCurves(false)
	elseif self.fill then
		layer:ShowConstructionCurves(false)
	else
		layer:ShowConstructionCurves(true)
	end
end

function AM_Create_Limb_V2:DrawCircle(destMesh, vec, radius, parentBone)
	local n = destMesh:CountPoints()		
	
	vec.x = vec.x - radius
	destMesh:AddLonePoint(vec, 0)
	
	vec.x = vec.x + radius
	vec.y = vec.y - radius
	destMesh:AppendPoint(vec, 0)
	
	vec.x = vec.x + radius
	vec.y = vec.y + radius
	destMesh:AppendPoint(vec, 0)
	
	vec.x = vec.x - radius
	vec.y = vec.y + radius
	destMesh:AppendPoint(vec, 0)
	
	vec.x = vec.x - radius
	vec.y = vec.y - radius
	destMesh:AppendPoint(vec, 0)

	destMesh:WeldPoints(n + 4, n, 0)

	-- set all their curvatures appropriately (0.391379 is the magic number for a circle)
	destMesh:SelectNone()
	destMesh:Point(n):SetCurvature(0.391379, 0)
	destMesh:Point(n).fParent = parentBone
	destMesh:Point(n + 1):SetCurvature(0.391379, 0)
	destMesh:Point(n + 1).fParent = parentBone
	destMesh:Point(n + 2):SetCurvature(0.391379, 0)
	destMesh:Point(n + 2).fParent = parentBone
	destMesh:Point(n + 3):SetCurvature(0.391379, 0)
	destMesh:Point(n + 3).fParent = parentBone

	destMesh:Point(n).fSelected = true

	destMesh:SelectConnected(n + 3)

end

function AM_Create_Limb_V2:GetGlobalAngle(moho, v1, v2)
	v2 = v2 - v1
	newAngle = math.atan2(v2.y, v2.x)
	return newAngle
end

function AM_Create_Limb_V2:BindJointToBone(jointsMesh, pt1, pt2, pt3, pt4, parentBoneID)
	jointsMesh:Point(pt1).fParent = parentBoneID
	jointsMesh:Point(pt2).fParent = parentBoneID
	jointsMesh:Point(pt3).fParent = parentBoneID
	jointsMesh:Point(pt4).fParent = parentBoneID
end

function AM_Create_Limb_V2:DrawBodyPart(destMesh, centerA, centerB, radiusA, radiusB, parentStart, parentEnd)

	centerA.x = centerA.x + radiusA
	centerB.x = centerB.x + radiusB

	local n = destMesh:CountPoints()

	local Yplus = math.atan2(centerB.x - centerA.x, centerB.y - centerA.y) + math.acos((radiusA - radiusB)/math.sqrt((centerB.x - centerA.x)^2+(centerB.y - centerA.y)^2))
	local Yminus = math.atan2(centerB.x - centerA.x, centerB.y - centerA.y) - math.acos((radiusA - radiusB)/math.sqrt((centerB.x - centerA.x)^2+(centerB.y - centerA.y)^2))
	local pt1Coord = LM.Vector2:new_local()
	local pt2Coord = LM.Vector2:new_local()
	local pt3Coord = LM.Vector2:new_local()
	local pt4Coord = LM.Vector2:new_local()

	local YplusCoords = LM.Vector2:new_local()
	local YminusCoords = LM.Vector2:new_local()
	YplusCoords.y = math.cos(Yminus)
	YplusCoords.x = math.sin(Yminus)
	YminusCoords.y = math.cos(Yplus)
	YminusCoords.x = math.sin(Yplus)

	pt1CoordPlus =  LM.Vector2:new_local()
	pt1CoordPlus.x = radiusA * YminusCoords.x
	pt1CoordPlus.y = radiusA * YminusCoords.y

	pt1Coord = centerA + pt1CoordPlus

	pt2CoordPlus = LM.Vector2:new_local()

	pt2CoordPlus.x = radiusA * YplusCoords.x
	pt2CoordPlus.y = radiusA * YplusCoords.y

	pt2Coord = centerA + pt2CoordPlus

	local pt4CoordPlus = LM.Vector2:new_local()
	pt4CoordPlus.x = radiusB * YminusCoords.x
	pt4CoordPlus.y = radiusB * YminusCoords.y

	pt4Coord = centerB + pt4CoordPlus

	local pt3CoordPlus = LM.Vector2:new_local()
	pt3CoordPlus.x = radiusB * YplusCoords.x
	pt3CoordPlus.y = radiusB * YplusCoords.y

	pt3Coord = centerB + pt3CoordPlus

	
	destMesh:AddLonePoint(pt1Coord, 0)
	
	destMesh:AppendPoint(pt2Coord, 0)
	
	destMesh:AppendPoint(pt3Coord, 0)
	
	destMesh:AppendPoint(pt4Coord, 0)

	destMesh:AppendPoint(pt1Coord, 0)
	
	destMesh:WeldPoints(n + 4, n, 0)
	destMesh:SelectNone()

	destMesh:Point(n):SetCurvature(0, 0)
	destMesh:Point(n).fParent = parentStart
	destMesh:Point(n + 1):SetCurvature(0, 0)
	destMesh:Point(n + 1).fParent = parentStart
	destMesh:Point(n + 2):SetCurvature(0, 0)
	destMesh:Point(n + 2).fParent = parentEnd
	destMesh:Point(n + 3):SetCurvature(0, 0)
	destMesh:Point(n + 3).fParent = parentEnd

	destMesh:Point(n).fSelected = true

	destMesh:SelectConnected()

end

function AM_Create_Limb_V2:CreateBodypartShape(moho, bodypartMesh)
	if self.stroke or self.fill then
		local jointsShapeID = moho:CreateShape(true)
		local jointsShape = bodypartMesh:Shape(jointsShapeID)
		jointsShape.fHasFill = self.fill
		jointsShape.fHasOutline = self.stroke
	end
end

function AM_Create_Limb_V2:ConstructionBoneSettings(moho, bone, iBone, angle, length, name)
	bone.fParent = iBone
	bone.fAnimParent:SetValue(0, iBone)
	bone.fAnimAngle:SetValue(0, math.rad(angle))
	bone.fIgnoredByIK = true
	bone.fScalingMode = 1
	bone:SetName(self.bodyPartName .. name)
	bone.fShy = true
	bone.fLength = length
	bone.fStrength = 0
end
-- **************************************************
-- Tool Panel Layout
-- **************************************************

AM_Create_Limb_V2.CREATE_LIMB = MOHO.MSG_BASE
AM_Create_Limb_V2.START_RADIUS = MOHO.MSG_BASE + 1
AM_Create_Limb_V2.END_RADIUS = MOHO.MSG_BASE + 2
AM_Create_Limb_V2.BODYPART_NAME = MOHO.MSG_BASE + 3
AM_Create_Limb_V2.STROKE = MOHO.MSG_BASE + 4
AM_Create_Limb_V2.FILL = MOHO.MSG_BASE + 5
AM_Create_Limb_V2.READ_RADIUS = MOHO.MSG_BASE + 6
AM_Create_Limb_V2.START_JOINT = MOHO.MSG_BASE + 7
AM_Create_Limb_V2.END_JOINT = MOHO.MSG_BASE + 8
AM_Create_Limb_V2.MAKE_TANGENT_FORM = MOHO.MSG_BASE + 9
AM_Create_Limb_V2.GROUP_AND_SEPARATE = MOHO.MSG_BASE + 10
AM_Create_Limb_V2.CREATE_DEFORMER = MOHO.MSG_BASE + 11
AM_Create_Limb_V2.SLEEVE_LENGTH = MOHO.MSG_BASE + 12

AM_Create_Limb_V2.BASE_BODYPART = MOHO.MSG_BASE + 100
AM_Create_Limb_V2.END_OF_FOREARMSHIN = MOHO.MSG_BASE + 101
AM_Create_Limb_V2.settingsForBaseBodypart = AM_Create_Limb_V2.BASE_BODYPART
AM_Create_Limb_V2.settingsForForearmShin = AM_Create_Limb_V2.END_OF_FOREARMSHIN

function AM_Create_Limb_V2:DoLayout(moho, layout)
	
	--CREATE LIMB BUTTON
	self.createLimbButton = LM.GUI.Button('Create Limb', self.CREATE_LIMB)
	layout:AddChild(self.createLimbButton, LM.GUI.ALIGN_LEFT, 0)


	-- Settings selection menu
	self.settingsForMenu = LM.GUI.Menu("Settings for:      ")
	self.settingsForMenu_popup = LM.GUI.PopupMenu(110, true)
	self.settingsForMenu_popup:SetMenu(self.settingsForMenu)
	self.settingsForMenu:AddItem("Settings for base bodypart", 0, self.BASE_BODYPART)
	self.settingsForMenu:AddItem("Settings for end of forearm/shin", 0, self.END_OF_FOREARMSHIN)
	layout:AddChild(self.settingsForMenu_popup)

	-- Start radius
	self.startRadiusInput = LM.GUI.TextControl(0, '0.0000', self.START_RADIUS, LM.GUI.FIELD_UFLOAT, 'Start radius')
	self.startRadiusInput:SetWheelInc(0.001)
	layout:AddChild(self.startRadiusInput, LM.GUI.ALIGN_LEFT, 0)

	-- End radius
	self.endRadiusInput = LM.GUI.TextControl(0, '0.0000', self.END_RADIUS, LM.GUI.FIELD_UFLOAT, 'End radius')
	self.endRadiusInput:SetWheelInc(0.001)
	layout:AddChild(self.endRadiusInput, LM.GUI.ALIGN_LEFT, 0)

	-- Bodypart name
	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)

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

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

	-- Read radius from selected bone
	self.readRadius = LM.GUI.ImageButton('ScriptResources/am_create_limb/readradius', 'Radius = selected bone\'s length', false, self.READ_RADIUS, false)
	layout:AddChild(self.readRadius, LM.GUI.ALIGN_LEFT, 0)

	-- Start Joint
	self.startJointCheckbox = LM.GUI.ImageButton('ScriptResources/am_create_limb/startjoint', 'Start joint', true, self.START_JOINT, false)
	layout:AddChild(self.startJointCheckbox, LM.GUI.ALIGN_LEFT, 0)

	-- End Joint
	self.endJointCheckbox = LM.GUI.ImageButton('ScriptResources/am_create_limb/endjoint', 'End joint', true, self.END_JOINT, false)
	layout:AddChild(self.endJointCheckbox, LM.GUI.ALIGN_LEFT, 0)

	-- Make tangent form
	self.makeTangentFormCheckbox = LM.GUI.ImageButton('ScriptResources/am_create_limb/maketangentform', 'Make tangent form', true, self.MAKE_TANGENT_FORM, false)
	layout:AddChild(self.makeTangentFormCheckbox, LM.GUI.ALIGN_LEFT, 0)

	-- Group and separate bodypart and joints layers
	self.groupAndSeparateCheckbox = LM.GUI.ImageButton('ScriptResources/am_create_limb/group', 'Create deformer', true, self.GROUP_AND_SEPARATE, true)
	layout:AddChild(self.groupAndSeparateCheckbox, LM.GUI.ALIGN_LEFT, 0)

	-- Sleeve Length settings
	self.sleeveLengthInput = LM.GUI.TextControl(0, '1.00    x', self.SLEEVE_LENGTH, LM.GUI.FIELD_UFLOAT, 'Sleeve Length:')
	self.sleeveLengthInput:SetWheelInc(0.001)
    layout:AddChild(self.sleeveLengthInput, LM.GUI.ALIGN_LEFT, 0)
end

function AM_Create_Limb_V2:UpdateWidgets(moho)
	if self.baseBodypart then
		if self.makeTangentForm then
			

			AM_Create_Limb_V2.startRadiusInput:SetValue(self.startRadius)
			AM_Create_Limb_V2.endRadiusInput:SetValue(self.endRadius)
			AM_Create_Limb_V2.settingsForMenu:SetChecked(self.settingsForBaseBodypart, true)
		else
			AM_Create_Limb_V2.startRadiusInput:SetValue(self.startRadius)
			AM_Create_Limb_V2.endRadiusInput:SetValue(self.startRadius)
			AM_Create_Limb_V2.settingsForMenu:SetChecked(self.settingsForBaseBodypart, true)
		end


	elseif self.endOfForearmShin then
		if self.makeTangentForm2 then
			AM_Create_Limb_V2.startRadiusInput:SetValue(self.startRadius2)
			AM_Create_Limb_V2.endRadiusInput:SetValue(self.endRadius2)
			AM_Create_Limb_V2.settingsForMenu:SetChecked(self.settingsForForearmShin, true)			
		else
			AM_Create_Limb_V2.startRadiusInput:SetValue(self.startRadius2)
			AM_Create_Limb_V2.endRadiusInput:SetValue(self.startRadius2)
			AM_Create_Limb_V2.settingsForMenu:SetChecked(self.settingsForForearmShin, true)
		end
	end
	
	AM_Create_Limb_V2.bodyPartNameInput:SetValue(self.bodyPartName)
	AM_Create_Limb_V2.strokeCheckbox:SetValue(self.stroke)
	AM_Create_Limb_V2.fillCheckbox:SetValue(self.fill)
	AM_Create_Limb_V2.startJointCheckbox:SetValue(self.startJoint)
	AM_Create_Limb_V2.endJointCheckbox:SetValue(self.endJoint)
	if self.endOfForearmShin then
		self.endJointCheckbox:Enable(false)
	else 
		self.endJointCheckbox:Enable(true)
	end

	if self.baseBodypart and not self.groupAndSeparate then
		AM_Create_Limb_V2.makeTangentFormCheckbox:SetValue(self.makeTangentForm)
	elseif self.endOfForearmShin then
		AM_Create_Limb_V2.makeTangentFormCheckbox:SetValue(self.makeTangentForm2)
	end
	if self.groupAndSeparate then
		self.makeTangentFormCheckbox:Enable(false)
		self.makeTangentForm = false
		self.makeTangentForm2 = false
	else
		self.makeTangentFormCheckbox:Enable(true)
	end
	
	AM_Create_Limb_V2.groupAndSeparateCheckbox:SetValue(self.groupAndSeparate)
	AM_Create_Limb_V2.sleeveLengthInput:SetValue(self.sleeveLength)
	if self.endOfForearmShin then
		self.sleeveLengthInput:Enable(true)
	else 
		self.sleeveLengthInput:Enable(false)
	end
	
end

function AM_Create_Limb_V2:HandleMessage(moho, view, msg)
	if msg == self.CREATE_LIMB then -- CREATE LIMB BUTTON

		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

				-- CREATE START BONE
				local boneStart = skel:AddBone(0)
				self:ConstructionBoneSettings(moho, boneStart, iBone, 0, self.startRadius, ' start')
				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

				-- CREATE END BONE FOR MAIN SHAPE
				local boneEnd = skel:AddBone(0)
				local boneEndPos = LM.Vector2:new_local()
				if self.endOfForearmShin and not self.groupAndSeparate then
					
					boneEndPos:Set(boneLength*self.sleeve, 0)

					
				else
					boneEndPos:Set(boneLength)
				end

				self:ConstructionBoneSettings(moho, boneEnd, iBone, 180, self.sleeveEndRadius, ' end')
				if not self.makeTangentForm then
					boneEnd.fLength = self.startRadius
				end

				if self.endOfForearmShin and not self.groupAndSeparate then
					boneEnd.fAnimAngle:SetValue(0, math.rad(90))
					boneEnd.fAnimPos:SetValue(0, boneEndPos)
					boneEnd.fShy = false
					-- *****************  ТУТ ПОПРАВИТЬ РУКАВ!!!! *************************
				else
					boneEnd.fAnimPos:SetValue(0, boneEndPos)
				end
				boneEnd.fAnimPos:SetValue(0, boneEndPos)
				local boneEndGlobalPose = self:GetGlobalBonePos(moho, boneEnd)
				local boneEndParentID = skel:BoneID(boneEnd)

				-- CREATE WRIST BONE
				if self.endOfForearmShin and not self.groupAndSeparate then
					boneWrist = skel:AddBone(0)
					boneWristPos = LM.Vector2:new_local()
					boneWristPos:Set(boneLength, 0)
					self:ConstructionBoneSettings(moho, boneWrist, iBone, 180, self.endRadius2, ' wrist')
					boneWrist.fAnimPos:SetValue(0, boneWristPos)

					AM_Create_Limb_V2.boneWristGlobalPose = self:GetGlobalBonePos(moho, boneWrist)
					AM_Create_Limb_V2.boneWristParentID = skel:BoneID(boneWrist)
				end

				local boneGlobalAngle = self:GetGlobalAngle(moho, boneStartGlobalPose, boneEndGlobalPose)
				
				local startBoneVec = LM.Vector2:new_local()
				local startBoneVec2 = LM.Vector2:new_local()

				startBoneVec:Set(0, 0)
				bone.fMovedMatrix:Transform(startBoneVec)
				startBoneVec.x = startBoneVec.x - self.startRadius
				
				startBoneVec2:Set(0, 0)
				bone.fMovedMatrix:Transform(startBoneVec2)
				startBoneVec2.x = startBoneVec2.x - self.startRadius2

				if self.groupAndSeparate then
					local midBone = skel:AddBone(0)
					AM_Create_Limb_V2.boneMidParentID = skel:BoneID(midBone)

					local midBonePos = LM.Vector2:new_local()
					midBonePos.x = boneLength/2
					midBone.fParent = iBone
					midBone.fAnimParent:SetValue(0, iBone)
					midBone.fAnimPos:SetValue(0, midBonePos)

					local startGroupedJointPose = LM.Vector2:new_local()
					startGroupedJointPose.x = startGroupedJointPose.x - self.startRadius
					local startGroupedJointPose2 = LM.Vector2:new_local()
					local endGroupedJointPose = LM.Vector2:new_local()
					local endGroupedJointPose2 = LM.Vector2:new_local()
					endGroupedJointPose2.x = endGroupedJointPose2.x + boneLength - self.startRadius2

					if self.endOfForearmShin then
						endGroupedJointPose.x = endGroupedJointPose.x + boneLength*self.sleeveLength - self.startRadius
					else
						endGroupedJointPose.x = endGroupedJointPose.x + boneLength - self.startRadius
					end

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

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

					local bodypartMesh = restBodypartLayer:Mesh()
					if self.endOfForearmShin then

						self:DrawBodyPart(bodypartMesh, startGroupedJointPose2, endGroupedJointPose2, self.startRadius2, self.startRadius2, -1, -1)

						local curveNumber2 = bodypartMesh:CountCurves() - 1
						local bodypartCurve2 = bodypartMesh:Curve(curveNumber2)
						self:CreateBodypartShape(moho, bodypartMesh)
						bodypartCurve2:SetSegmentOn(0, false)
						bodypartCurve2:SetSegmentOn(2, false)
					end

					local rectStart = LM.Vector2:new_local()
					rectStart.x = rectStart.x - boneLength
					local rectEnd = LM.Vector2:new_local()
					
					self:DrawBodyPart(bodypartMesh, rectStart, rectEnd, boneLength, boneLength, -1, -1)
					self:DrawBodyPart(bodypartMesh, startGroupedJointPose, endGroupedJointPose, self.startRadius, self.startRadius, -1, -1)

					local curveNumber2 = bodypartMesh:CountCurves() - 1
					local bodypartCurve2 = bodypartMesh:Curve(curveNumber2)
					self:CreateBodypartShape(moho, bodypartMesh)
					bodypartCurve2:SetSegmentOn(0, false)
					if self.baseBodypart then
						bodypartCurve2:SetSegmentOn(2, false)
					end

					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, false, false)
					local jointsMesh = jointsLayer:Mesh()

					if self.startJoint and self.startJointTest then
						self:DrawCircle(jointsMesh, startGroupedJointPose, self.startRadius, boneStartParentID)
						self:CreateBodypartShape(moho, jointsMesh)
					end

					if self.endOfForearmShin then
						self:DrawCircle(jointsMesh, endGroupedJointPose2, self.startRadius2, boneEndParentID)
						self:CreateBodypartShape(moho, jointsMesh)

					else
						if self.endJoint then
							self:DrawCircle(jointsMesh, endGroupedJointPose, self.startRadius, boneEndParentID)
							self:CreateBodypartShape(moho, jointsMesh)
						end
					end
					
					local deformerLayer = moho:LayerAsVector(moho:CreateNewLayer(MOHO.LT_VECTOR, false))
					deformerLayer:SetEditOnly(true)
					moho:PlaceLayerInGroup(bodypartGroup, deformerLayer, true, false)
					local deformerMesh = deformerLayer:Mesh()
					deformerLayer:SetName(self.bodyPartName .. " deformer")

					local startPointPos = LM.Vector2:new_local()
					local endPointPos = LM.Vector2:new_local()
					endPointPos.x = boneLength

					deformerMesh:AddLonePoint(startPointPos, 0)
					deformerMesh:AppendPoint(endPointPos, 0)

					local deformerCurve = deformerMesh:Curve() 
					deformerMesh:Point(0):SetCurvature(0, 0)
					deformerMesh:Point(1):SetCurvature(0, 0)
					deformerCurve:SetWeight(1, 0, 0, true)
					deformerCurve:SetWeight(0, 0, 0, true)
					deformerCurve:SetWeight(1, 0, 0, false)
					deformerCurve:SetWeight(0, 0, 0, false)

					deformerMesh:SelectAll()
					MOHO:SplitSelectedSegments(deformerMesh, 1, 0)
					deformerMesh:Point(2):SetCurvature(0.5, 0)
					deformerMesh:Point(2).fParent = AM_Create_Limb_V2.boneMidParentID
					deformerMesh:Point(0).fParent = boneStartParentID
					deformerMesh:Point(1).fParent = boneEndParentID

					restBodypartLayer:SetFollowingCurve(deformerLayer, deformerCurve, 0, true)
				
				else
						
					local bodypartLayer = moho:LayerAsVector(moho:CreateNewLayer(MOHO.LT_VECTOR, false))
					self:ShowConstructionCurvesTest(moho, bodypartLayer)
					moho:PlaceLayerInGroup(bodypartLayer, boneLayer, true, false)
					bodypartLayer:SetName(self.bodyPartName)
					local bodypartMesh = bodypartLayer:Mesh()
					if self.endOfForearmShin then
						-- DRAW WRIST PART --

						if self.startJoint and self.startJointTest then
							self:DrawCircle(bodypartMesh, boneStartGlobalPose, self.startRadius2, boneStartParentID)
							self:CreateBodypartShape(moho, bodypartMesh)
						end
						if self.makeTangentForm2 then
							self:DrawCircle(bodypartMesh, AM_Create_Limb_V2.boneWristGlobalPose, self.endRadius2, AM_Create_Limb_V2.boneWristParentID)
						else
							self:DrawCircle(bodypartMesh, AM_Create_Limb_V2.boneWristGlobalPose, self.startRadius2, AM_Create_Limb_V2.boneWristParentID)
						end

						self:CreateBodypartShape(moho, bodypartMesh)

						if self.makeTangentForm2 then
							self:DrawBodyPart(bodypartMesh, startBoneVec2, AM_Create_Limb_V2.boneWristGlobalPose, self.startRadius2, self.endRadius2, boneStartParentID, AM_Create_Limb_V2.boneWristParentID)
						else
							self:DrawBodyPart(bodypartMesh, startBoneVec2, AM_Create_Limb_V2.boneWristGlobalPose, self.startRadius2, self.startRadius2, boneStartParentID, AM_Create_Limb_V2.boneWristParentID)
						end
						local curveNumber2 = bodypartMesh:CountCurves() - 1
						local bodypartCurve2 = bodypartMesh:Curve(curveNumber2)
						self:CreateBodypartShape(moho, bodypartMesh)
						bodypartCurve2:SetSegmentOn(0, false)
						bodypartCurve2:SetSegmentOn(2, false)

						-- DRAW REST PART --
						if self.startJoint and self.startJointTest then
							boneStartGlobalPose.x = boneStartGlobalPose.x + self.startRadius2
							self:DrawCircle(bodypartMesh, boneStartGlobalPose, self.startRadius, boneStartParentID)
							self:CreateBodypartShape(moho, bodypartMesh)
						end
					
						if self.makeTangentForm then
							boneEndGlobalPose.x = boneEndGlobalPose.x - self.sleeveEndRadius
						else
							boneEndGlobalPose.x = boneEndGlobalPose.x - self.startRadius
						end

						if self.makeTangentForm then
							self:DrawBodyPart(bodypartMesh, startBoneVec, boneEndGlobalPose, self.startRadius, self.sleeveEndRadius, boneStartParentID, boneEndParentID)
						else
							self:DrawBodyPart(bodypartMesh, startBoneVec, boneEndGlobalPose, self.startRadius, self.startRadius, boneStartParentID, boneEndParentID)
						end
						self:CreateBodypartShape(moho, bodypartMesh)

						local curveNumber = bodypartMesh:CountCurves() - 1
						local bodypartcurve = bodypartMesh:Curve(curveNumber)
						bodypartcurve:SetSegmentOn(0, false)

					elseif self.baseBodypart then
						if self.startJoint and self.startJointTest then
							
							self:DrawCircle(bodypartMesh, boneStartGlobalPose, self.startRadius, boneStartParentID)
							self:CreateBodypartShape(moho, bodypartMesh)
						end
						if self.endJoint then
							if self.makeTangentForm then
								self:DrawCircle(bodypartMesh, boneEndGlobalPose, self.sleeveEndRadius, boneEndParentID)
								self:CreateBodypartShape(moho, bodypartMesh)
								boneEndGlobalPose.x = boneEndGlobalPose.x + self.sleeveEndRadius
							else
								self:DrawCircle(bodypartMesh, boneEndGlobalPose, self.startRadius, boneEndParentID)
								self:CreateBodypartShape(moho, bodypartMesh)
								boneEndGlobalPose.x = boneEndGlobalPose.x + self.startRadius
							end
						end

						if self.makeTangentForm then
							boneEndGlobalPose.x = boneEndGlobalPose.x - self.sleeveEndRadius
						else
							boneEndGlobalPose.x = boneEndGlobalPose.x - self.startRadius
						end

						if self.makeTangentForm then

							self:DrawBodyPart(bodypartMesh, startBoneVec, boneEndGlobalPose, self.startRadius, self.sleeveEndRadius, boneStartParentID, boneEndParentID)
						else

							self:DrawBodyPart(bodypartMesh, startBoneVec, boneEndGlobalPose, self.startRadius, self.startRadius, boneStartParentID, boneEndParentID)
						end
						self:CreateBodypartShape(moho, bodypartMesh)

						local curveNumber = bodypartMesh:CountCurves() - 1
						local bodypartcurve = bodypartMesh:Curve(curveNumber)
						bodypartcurve:SetSegmentOn(0, false)
						if self.endJoint then
							bodypartcurve:SetSegmentOn(2, false)
						end
					end
				end
			end
			moho:SetSelLayer(boneLayer, false, true)
			moho:UpdateUI()
			moho.layer:UpdateCurFrame()
		end
	
	elseif msg == self.BASE_BODYPART then
		self.baseBodypart = true
		self.endOfForearmShin = false
		self.sleeve = self.sleeveDefault
		self:UpdateWidgets(moho)
	elseif msg == self.END_OF_FOREARMSHIN then
		self.baseBodypart = false
		self.endOfForearmShin = true
		self.sleeve = self.sleeveLength
		self:UpdateWidgets(moho)
	elseif msg == self.START_RADIUS then
		if self.baseBodypart then
			self.startRadius = self.startRadiusInput:Value()
			if self.magnitude < 0 - self.startRadiusInput:Value() then
				self.magnitude = 0 - self.startRadiusInput:Value()
			end
			self.endRadius = self.startRadius + self.magnitude
		elseif self.endOfForearmShin then
			self.startRadius2 = self.startRadiusInput:Value()
			if self.magnitude2 < 0 - self.startRadiusInput:Value() then
				self.magnitude2 = 0 - self.startRadiusInput:Value()
			end
			self.endRadius2 = self.startRadius2 + self.magnitude2
		end
		self:UpdateWidgets(moho)
	elseif msg == self.END_RADIUS then -- END RADIUS
		if self.makeTangentForm then
		
			if self.baseBodypart then
				self.endRadius = self.endRadiusInput:Value()
				self.magnitude = self.endRadiusInput:Value()-self.startRadius
			elseif self.endOfForearmShin then
				self.endRadius2 = self.endRadiusInput:Value()
				self.magnitude2 = self.endRadiusInput:Value()-self.startRadius2
			end
		else
			if self.baseBodypart then
				self.endRadius = self.endRadiusInput:Value()
				self.magnitude = 0
				self.startRadius = self.endRadiusInput:Value()			
			elseif self.endOfForearmShin then
				self.endRadius2 = self.endRadiusInput:Value()
				self.magnitude2 = 0
				self.startRadius2 = self.endRadiusInput:Value()
			end			
		end
		self:UpdateWidgets(moho)
	elseif msg == self.BODYPART_NAME then -- BODYPART NAME
		self.bodyPartName = self.bodyPartNameInput:Value()
	elseif msg == self.STROKE then -- STROKE
		self.stroke = self.strokeCheckbox:Value()
	elseif msg == self.FILL then -- FILL
		self.fill = self.fillCheckbox:Value()
	elseif msg == self.READ_RADIUS then -- READ RADIUS
		local skel = moho:Skeleton()
		for i = 0, skel:CountBones() - 1 do
			local bone = skel:Bone(i)
			if bone.fSelected then
				self.startRadius = bone.fLength
				self.magnitude = 0
				self.endRadius = bone.fLength
				break
			end
		end
		
	elseif msg == self.START_JOINT then -- START JOINT
		self.startJoint = self.startJointCheckbox:Value()
	elseif msg == self.END_JOINT then -- END JOINT
		self.endJoint = self.endJointCheckbox:Value()
	elseif msg == self.MAKE_TANGENT_FORM then -- MAKE TANGENT FORM
		if self.baseBodypart then
			self.makeTangentForm = self.makeTangentFormCheckbox:Value()
		elseif self.endOfForearmShin then
			self.makeTangentForm2 = self.makeTangentFormCheckbox:Value()
			self.magnitude2 = 0
		end
		self:UpdateWidgets(moho)

	elseif msg == self.GROUP_AND_SEPARATE then -- GROUP AND SEPARATE LAYERS
		self.groupAndSeparate = self.groupAndSeparateCheckbox:Value()
		self:UpdateWidgets(moho)
	elseif msg == self.SLEEVE_LENGTH then -- SLEEVE LENGTH
        self.sleeveLength = self.sleeveLengthInput:Value()
		self.sleeve = self.sleeveLength
	else
		
	end
	
end

Icon
Create Limb 2
Listed

Script type: Tool

Uploaded: Nov 08 2022, 08:08

Last modified: Aug 29 2023, 11:11

Like Create Limb, but better!
Video instruction is coming soon

The previous version is here.
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: 1575