-- ************************************************** -- Provide Moho with the name of this script object -- ************************************************** ScriptName = "LK_SetOrigin" -- ************************************************** -- The original tool LM_Set_Origin can't be disabled (because it doesn't have an IsRelevant function perhaps?) -- "LK_Set_Origin's filename must be "LM_SetOrigin.lua" -- ************************************************** -- ************************************************** -- General information about this script -- ************************************************** LK_SetOrigin = {} LK_SetOrigin.BASE_STR = 2325 function LK_SetOrigin:Name() return "Set Origin" end function LK_SetOrigin:Version() return "1.0" end function LK_SetOrigin:Description() return (MOHO.Localize("/Scripts/Tool/SetOrigin/Description=Click to set the origin of this layer (the point the layer rotates around)").." (also works with layerscripts LK_Origin_Switch.lua and LK_Origin_Bone.lua) (<,/.> to go to previous/next FBF-frame)") end function LK_SetOrigin:Creator() return "Smith Micro Software, Inc. - Modified by Lukas Krepel, Frame Order" end function LK_SetOrigin:UILabel() return(MOHO.Localize("/Scripts/Tool/SetOrigin/SetOrigin=Set Origin")) end function LK_SetOrigin:IsRelevant(moho) if MohoMode ~= nil then if MohoMode.vanilla then return false end end return true end function LK_SetOrigin:ColorizeIcon() return true end -- ************************************************** -- Disable original tool -- ************************************************** function LM_SetOrigin:IsRelevant(moho) if LK_SetOrigin:IsRelevant(moho) then return false end -- * Copy of original IsRelevant function: return true end -- ************************************************** -- Recurring values -- ************************************************** LK_SetOrigin.matrix = LM.Matrix:new_local() LK_SetOrigin.layerSettingsWnd = nil -- ************************************************** -- The guts of this script -- ************************************************** function LK_SetOrigin:OnInputDeviceEvent(moho, deviceEvent) return LM_TransformLayer:OnInputDeviceEvent(moho, deviceEvent) end function LK_SetOrigin:OnMouseDown(moho, mouseEvent) moho.document:PrepUndo(moho.layer, true) moho.document:SetDirty() self:SetOrigin(moho, mouseEvent) mouseEvent.view:DrawMe() end function LK_SetOrigin:OnMouseMoved(moho, mouseEvent) self:SetOrigin(moho, mouseEvent) mouseEvent.view:DrawMe() end function LK_SetOrigin:SetOrigin(moho, mouseEvent, newVal) local matrix = LM.Matrix:new_local() local beforeVec = LM.Vector3:new_local() local afterVec = LM.Vector3:new_local() -- * local layer = moho.layer local embeddedscript = string.gsub(tostring(layer:LayerScript()), '\\', '/') if embeddedscript ~= "" then local lastslashpos = (embeddedscript:reverse()):find("%/") -- find last slash embeddedscript = (embeddedscript:sub(-lastslashpos+1)) -- filename only if embeddedscript == "LK_Origin_Switch.lua" then -- * Script is embedded, set origin of active child: if moho.layer:LayerType() == MOHO.LT_SWITCH then local switchLayer = moho:LayerAsSwitch(moho.layer) local activeChildName = switchLayer:GetValue(moho.frame) for i = switchLayer:CountLayers()-1, 0, -1 do local childLayer = switchLayer:Layer(i) if childLayer:Name() == activeChildName then layer = childLayer end end end elseif embeddedscript == "LK_Origin_Bone.lua" then local skel = moho:Skeleton() local OriginTag = "origin" -- * Find Origin Bone: for i=0, skel:CountBones()-1 do local bone = skel:Bone(i) local boneName = string.lower(bone:Name()) if string.match (boneName, OriginTag) then OriginBone = bone layer:GetFullTransform(moho.frame, matrix, moho.document) if mouseEvent ~= nil then OriginBone.fAnimPos:SetValue (moho.frame, mouseEvent.view:Point2Vec(mouseEvent.pt, matrix)) else OriginBone.fAnimPos:SetValue (moho.frame, newVal) end moho.layer:UpdateCurFrame() -- * Updates position in viewport. moho:UpdateUI() -- * Updates timeline. return end end end end -- * layer:GetFullTransform(moho.frame, matrix, nil) matrix:Transform(beforeVec) if mouseEvent ~= nil then layer:GetFullTransform(moho.frame, matrix, moho.document) layer:SetOrigin(mouseEvent.view:Point2Vec(mouseEvent.pt, matrix)) else layer:SetOrigin(newVal) end layer:GetFullTransform(moho.frame, matrix, nil) matrix:Transform(afterVec) local newLayerPos = layer.fTranslation.value + beforeVec - afterVec local v = newLayerPos - layer.fTranslation.value if (v:Mag() > 0.000001) then layer.fTranslation:SetValue(moho.layerFrame, newLayerPos) moho:NewKeyframe(CHANNEL_LAYER_T) end moho.document:DepthSort() end -- ************************************************** -- Tool options - create and respond to tool's UI -- ************************************************** LK_SetOrigin.CHANGE = MOHO.MSG_BASE LK_SetOrigin.RESET = MOHO.MSG_BASE + 1 LK_SetOrigin.FLIP_H = MOHO.MSG_BASE + 2 LK_SetOrigin.FLIP_V = MOHO.MSG_BASE + 3 LK_SetOrigin.RESET_ORIGIN_X = MOHO.MSG_BASE + 4 LK_SetOrigin.RESET_ORIGIN_Y = MOHO.MSG_BASE + 5 LK_SetOrigin.BONE_LAYERSCRIPT = MOHO.MSG_BASE + 6 LK_SetOrigin.SWITCH_LAYERSCRIPT = MOHO.MSG_BASE + 7 LK_SetOrigin.layerscript_bone = "LK_Origin_Bone.lua" LK_SetOrigin.layerscript_switch = "LK_Origin_Switch.lua" function LK_SetOrigin:DoLayout(moho, layout) FO_Utilities.tinyUI = false -- ******************* -- *** Origin X/Y: *** -- ******************* FO_Utilities:Divider(layout, "Origin", true) self.xButton = LM.GUI.ImageButton("ScriptResources/FO_icons/channels_X", "Reset Origin's Horizontal Position", false, self.RESET_ORIGIN_X, true) layout:AddChild(self.xButton) layout:AddPadding(-15) self.textX = LM.GUI.TextControl(0, "00.0000", self.CHANGE, LM.GUI.FIELD_FLOAT) layout:AddChild(self.textX) layout:AddPadding(-15) self.yButton = LM.GUI.ImageButton("ScriptResources/FO_icons/channels_Y", "Reset Origin's Vertical Position", false, self.RESET_ORIGIN_Y, true) layout:AddChild(self.yButton) -- ************** -- *** Reset: *** -- ************** layout:AddPadding(-15) self.textY = LM.GUI.TextControl(0, "00.0000", self.CHANGE, LM.GUI.FIELD_FLOAT) layout:AddChild(self.textY) layout:AddChild(LM.GUI.Button(MOHO.Localize("/Scripts/Tool/SetOrigin/Reset=Reset"), self.RESET)) -- ******************* -- *** Flip Layer: *** -- ******************* FO_Utilities:Divider(layout, "Flip Layer") self.flipLayerXButton = (LM.GUI.ImageButton("ScriptResources/flip_layer_h", MOHO.Localize("/Scripts/Tool/SetOrigin/FlipH=Flip Layer Horizontally"), true, self.FLIP_H, true)) layout:AddChild(self.flipLayerXButton) self.flipLayerYButton = (LM.GUI.ImageButton("ScriptResources/flip_layer_v", MOHO.Localize("/Scripts/Tool/SetOrigin/FlipV=Flip Layer Vertically"), true, self.FLIP_V, true)) layout:AddChild(self.flipLayerYButton) -- *********************** -- *** Animate Origin: *** -- *********************** FO_Utilities:Divider(layout, "Embed Animate Origin Layerscripts") self.boneButton = (LM.GUI.ImageButton("ScriptResources/FO_icons/channels_bone_channels", "Embed layerscript: '"..self.layerscript_bone.."'", true, self.BONE_LAYERSCRIPT, true)) layout:AddChild(self.boneButton) self.switchButton = (LM.GUI.ImageButton("ScriptResources/FO_icons/channels_switch_channels", "Embed layerscript: '"..self.layerscript_switch.."'", true, self.SWITCH_LAYERSCRIPT, true)) layout:AddChild(self.switchButton) end function LK_SetOrigin:UpdateWidgets(moho) local origin = moho.layer:Origin() self.textX:SetValue(origin.x) self.textY:SetValue(origin.y) if (self.layerSettingsWnd) then self.layerSettingsWnd:Update(moho) end self.boneButton:Enable(moho.layer:IsBoneType()) self.switchButton:Enable(moho.layer:LayerType() == MOHO.LT_SWITCH) local layerscript = moho.layer:LayerScript() self.boneButton:SetValue(string.match(layerscript, self.layerscript_bone)) self.switchButton:SetValue(string.match(layerscript, self.layerscript_switch)) self.flipLayerXButton:SetValue(moho.layer.fFlipH.value) self.flipLayerYButton:SetValue(moho.layer.fFlipV.value) end function LK_SetOrigin:HandleMessage(moho, view, msg) local newVal = LM.Vector2:new_local() local selCount = moho.document:CountSelectedLayers() if (msg == self.BONE_LAYERSCRIPT) then moho.document:PrepUndo(moho.layer, true) moho.document:SetDirty() if not self.boneButton:Value() then -- * Value is false, because we just clicked the button! -- * Remove layerscript: moho.layer:SetLayerScript() local skel = moho:Skeleton() for i=0, skel:CountBones()-1 do local bone = skel:Bone(i) local boneName = string.lower(bone:Name()) if string.match (boneName, FO_Utilities.originTag) then if FO_Utilities:YesNoQuestion("Delete 'Origin' bone?") then skel:DeleteBone(i) end end end else -- * Embed bone script: FO_Utilities:EmbedLayerScript(moho, moho.layer, self.layerscript_bone) end elseif (msg == self.SWITCH_LAYERSCRIPT) then moho.document:PrepUndo(moho.layer, true) moho.document:SetDirty() if not self.switchButton:Value() then -- * Value is false, because we just clicked the button! -- * Remove layerscript: moho.layer:SetLayerScript() else -- * Embed switch script: FO_Utilities:EmbedLayerScript(moho, moho.layer, self.layerscript_switch) end elseif (msg == self.RESET) then -- moho.document:PrepMultiUndo(true) -- * Ditched multi layer support? moho.document:PrepUndo(moho.layer, true) moho.document:SetDirty() newVal:Set(0, 0) --[[ -- * Ditched multi layer support? for i = 0, selCount - 1 do local layer = moho.document:GetSelectedLayer(i) self:SetOrigin(moho, nil, newVal) end --]] -- * Ditched multi layer support? self:SetOrigin(moho, nil, newVal) elseif (msg == self.RESET_ORIGIN_X) then moho.document:PrepUndo(moho.layer, true) moho.document:SetDirty() newVal:Set(0, moho.layer:Origin().y) self:SetOrigin(moho, nil, newVal) elseif (msg == self.RESET_ORIGIN_Y) then moho.document:PrepUndo(moho.layer, true) moho.document:SetDirty() newVal:Set(moho.layer:Origin().x, 0) self:SetOrigin(moho, nil, newVal) elseif (msg == self.CHANGE) then moho.document:PrepUndo(moho.layer, true) moho.document:SetDirty() newVal.x = self.textX:FloatValue() newVal.y = self.textY:FloatValue() self:SetOrigin(moho, nil, newVal) elseif (msg == self.FLIP_H) then moho.document:PrepMultiUndo(true) moho.document:SetDirty() for i = 0, selCount - 1 do local layer = moho.document:GetSelectedLayer(i) layer.fFlipH:SetValue(moho.frame + layer:TotalTimingOffset(), not layer.fFlipH.value) moho:NewKeyframe(CHANNEL_LAYER_FLIP_H) end elseif (msg == self.FLIP_V) then moho.document:PrepMultiUndo(true) moho.document:SetDirty() for i = 0, selCount - 1 do local layer = moho.document:GetSelectedLayer(i) layer.fFlipV:SetValue(moho.frame + layer:TotalTimingOffset(), not layer.fFlipV.value) moho:NewKeyframe(CHANNEL_LAYER_FLIP_V) end end self:UpdateWidgets(moho) end function LK_SetOrigin:OnKeyDown(moho, keyEvent) if keyEvent.key == "." then FO_Utilities:GoToNextSwitchKey(moho, false) return elseif keyEvent.key == "," then FO_Utilities:GoToNextSwitchKey(moho, true) return end if LK_SelectPoints ~= nil then LK_SelectPoints:OnKeyDown(moho, keyEvent) -- * Contains "," "." "/" FBF shortcuts! end end
Set Origin
Listed
Author: Lukas
View Script
Script type: Tool
Uploaded: Jun 24 2022, 05:25
Last modified: May 26 2023, 07:11
Script Version: 1.0
Allows the Origin to be animated.
Allows the Origin to be animated.
On a bone layer, it is controlled by a pinbone called 'Origin'. Which can be animated like any other bone or simply with this tool.
On a switch or FBF layer the Origin is set per child layer, set the child layers' Origins from the switch level with this tool. This way you can scale and rotate on the Switch/FBF level, while each instance having their own Origin.
Put these files:
- LK_Origin_Bone.lua
- LK_Origin_Switch.lua
in this folder:
/YourCustomContentFolder/Shared Resources/Layerscripts/
For FBF purposes, the LK_SelectPoints shortcuts will also work in this tool if you've got that one installed.
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: 1523
Set Origin
Listed
Author: Lukas
View Script
Script type: Tool
Uploaded: Jun 24 2022, 05:25
Last modified: May 26 2023, 07:11
Script Version: 1.0
Allows the Origin to be animated.
Allows the Origin to be animated.
On a bone layer, it is controlled by a pinbone called 'Origin'. Which can be animated like any other bone or simply with this tool.
On a switch or FBF layer the Origin is set per child layer, set the child layers' Origins from the switch level with this tool. This way you can scale and rotate on the Switch/FBF level, while each instance having their own Origin.
Put these files:
- LK_Origin_Bone.lua
- LK_Origin_Switch.lua
in this folder:
/YourCustomContentFolder/Shared Resources/Layerscripts/
For FBF purposes, the LK_SelectPoints shortcuts will also work in this tool if you've got that one installed.
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: 1523