Home Technical Talk

Bone Copying Max script

polycounter lvl 18
Offline / Send Message
Rick Stirling polycounter lvl 18
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

  • Ruz
    Options
    Offline / Send Message
    Ruz polycount lvl 666
    I gave this to one of our animtors today. will ask him if it was ok tomorrow.
    I am sure he will be able to suggest improvements as he is well in to max script
  • Rick Stirling
    Options
    Offline / Send Message
    Rick Stirling polycounter lvl 18
    Cheers!

    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.
  • Ruz
    Options
    Offline / Send Message
    Ruz polycount lvl 666
    yeh I will ask him about it tomorrow, think he is rather busy anyhow
Sign In or Register to comment.