3DSMax Lipsync Rig – Convert Bones to Morph

LipSyncRig

This example shows a relatively low-poly head rigged with bones for the standard lipsync viseme targets. This was matched to a system called Animeter that has since been bought and sold a bunch of times. Anyway, the standard targets still apply now.

So, the way this guy works is that we have a head model that is rigged and animated to a different morph target every 5 frames. The script creates a button in the head object’s rollout called “Create Morpher Head”. When the artist hits the button, Max snapshots the head along the timeline to create morph targets. It then assigns the targets to a base head with the Morpher modifier. Then you’re ready to roll.

The advantage to this is that since morphs are always topology dependent, we can’t tweak the model very much without ruining the rig. So instead, we make modeling changes to the skinned head and regenerate the morph targets from there. This can save artists a bunch of time.

Below is the source for the script.

?View Code MAXSCRIPT
makeHeadCA = attributes makeHead
(
	parameters main rollout:params
	(
		makeHeadBtn type:#boolean ui:makeHeadBtn
	)
	rollout params "Make Morpher"
	(
		button makeHeadBtn "Create Morpher Head"
		on makeHeadBtn pressed do
		(
			headBasis = $
			nameArray = #("head_player_none_male","Eat","Earth","If","Ox","Oat","Wet","Size","Church","Fave","Though","Told","Bump","New","Roar","Cage","EyebrowRaiseLeft","EyebrowRaiseRight","BlinkLeft","BlinkRight","LookUp","LookDown","LookLeft","LookRight","EyebrowRaiseBoth","BlinkBoth")
 
			sliderTime = 0f
			headPosX = 0.5
			headDone = 1
			global headMorphs = #()
			--snapshot the main head
			for i = 1 to nameArray.count do
			(
				newHead = snapshot headBasis
				headPosX = headPosX + .5
				newHead.name = nameArray[i]
				newHead.pos.x = headPosX
				append headMorphs newHead
				sliderTime = sliderTime + 5f
			)
			sliderTime = 0f
 
			--now add the morpher plus the targets
			mainHead = headMorphs[1]
			addmodifier mainHead (morpher())
			global theMorpher = mainHead.morpher
			select mainHead
 
			for i = 1 to (headMorphs.count - 1) do
			(
				print ("adding " + headmorphs[i+1].name)
				WM3_MC_BuildFromNode mainHead.morpher i headMorphs[i+1]
			)
		)
	)
)
 
CAs = custattributes.getdefs $head_basis.skin
if CAs.count > 0 then
(
	for i = 1 to CAs.count do
	(
		custattributes.delete $head_basis.skin i
	)
)
custAttributes.add $head_basis.skin makeHeadCA

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>