This s a work in progress, and not fully working.
Its for the animators to mirror face bones - key a left bone, mirror to the right.
It assumes that all bones are prefixed by l, L, r or R
If anyone can add to it, fix it, make it better, that would be great.
I'll likely add the ability to create a key on the mirrored bone.
-- Bone key copy
-- Rick Stirling
global selectedBone
global oppositebone
global SBstartRX
global SBstartRY
global SBstartRZ
global SBstartR
global SBstartPX
global SBstartPY
global SBstartPZ
fn get_selected_bone_name =
(
-- Error checking to make sure it's a bone
theclass = classof $
if (theclass == BoneGeometry) then
(
try
(
-- Get the bone name
SB=$
selectedBone = SB.name
)
catch
(
messagebox "Couldn't get the bone name"
)
)
else
(
messagebox "Whatever you selected doesn't seem to be a bone"
)
)
fn split_bone_name =
(
SB = selectedBone
BNprefix=substring SB 1 1 as string
BNsuffix= substring SB 2 255 as string
-- And now find out what the opposite bone should be
if (BNprefix=="l" or BNprefix=="L") then
(
OpPF="r"
)
else if (BNprefix=="r" or BNprefix=="R") then
(
OpPF="l"
)
else
(
print "Bone name prefix not found (not l/L/r/R)"
)
-- Assemble name of opposite bone
oppositeBone = OpPF + BNsuffix
)
fn get_bone_PR =
(
SBstartPX = $.pos.x
SBstartPY = $.pos.y
SBstartPZ = $.pos.z
SBstartR = $.rotation
SBstartRX = $.rotation.x
SBstartRY = $.rotation.y
SBstartRZ = $.rotation.z
)
fn put_bone_PR =
(
-- Create a dummy at the selected bone
SBdummy=dummy()
select SBDummy
SBDummy.pos.x=SBStartPX
SBDummy.pos.y=SBStartPY
SBDummy.pos.z=SBStartPZ
SBDummy.rotation=SBStartR
-- Flip the dummy
about [0,0,0] scale $ [-1,1,1]
-- This code will select the opposite bone using pattern matching
try
(
local selectionlist=#()
for loop in $geometry do
(
local tmp=matchPattern Loop.name pattern:(oppositeBone)
if tmp==true do append selectionlist Loop
)
deselect $*
select selectionlist
)
catch()
-- Set rotation of opposite bone to the dummy
$.rotation = SBDummy.rotation
-- Position the bone at the same place as the original bone
$.pos.x = SBstartPX
$.pos.y = SBstartPY
$.pos.z = SBstartPZ
about [0,0,0] scale $ [-1,1,1]
delete SBDummy
)
rollout bonething "Bone copying thing"
(
label lbl1 "Label text here, put in the instructions" pos:[9,8] width:197 height:48
button copyBone "Copy bone" pos:[18,85] width:174 height:32
on copyBone pressed do
(
get_selected_bone_name()
split_bone_name()
get_bone_PR()
put_bone_PR()
)
)
-- Create floater
theNewFloater = newRolloutFloater "Rollout title" 220 160
-- Add the rollout section
addRollout bonething theNewFloater
Replies
I am sure he will be able to suggest improvements as he is well in to max script
I've made a few changes - it now reselects the the bone you want mirroed, and it no longer does an exact mirror on the animators request - it stores the original position of the bone and makes shure that although it may rotate its always at the same position in x/y/z space.
Once I get some more feedback and tweaks I think I'll add a "jitter" function for more organic mirroring.