I’ve been looking into porting assets to Maya, MotionBuilder, Softimage via FBX. One problematic area I ran into early on was that of the ‘Morpher’ modifier…

To maintain quads, be sure to do the following:

  1. All mesh objects should be of class ‘Editable_Poly’
  2. In the exporter options, “Preserve Triangle Orientation” should not be checked.

Morpher compatibility…

  1. It seems that only the top most MORPHER modifier is exported with FBX. The others are ignored.Furthermore,it seems that morpher modifiers are limited to 100 channels. While you can set channels above this in mxs, the results are not as intended and I’ve only seen one channel above 100 work and it seems to be any index over 100.
  2. All morph targets need to exist in the scene as objects and targeted via the MORPHER ui. Failing to do this will result in the channel names being truncated to the first letter of their name. IE “Jaw_open” and “Jaw_back” both become “J” and “J” respectively. A script below helps address this by extracting and re-targeting morph target objects embedded in the MORPHER modifier.


fn morpher_ExtractTargets obj morph_mod mChannels:(#{1..100}) reTargetFromScene:true offsetPos:[0,0,0] hideTargets:true = (
   suspendEditing()
   targetObjs = #()
   --need to figure out which channels are used within the mChannel range and what their current value is
   -- will zero them out and reset them at the end
   valid_mChannels = #{}
   value_mChannels = #()
   for mc in mChannels do (
      if (wm3_mc_hasData morph_mod mc) then (
         append valid_mChannels mc
         value_mChannels[mc] = (wm3_mc_getValue morph_mod mc)
      )
   )
   --zero out values
   for mc in valid_mChannels do (
      wm3_mc_setValue morph_mod mc 0.0
   )
   --extract targets, if necessary
   for mc in valid_mChannels do (
      if wm3_mc_hasTarget morph_mod mc == false  then (
         wm3_mc_setValue morph_mod mc 100.0
         targetObj = copy obj
         targetObj.name = wm3_mc_getName morph_mod mc
         collapseStack targetObj
         append targetObjs targetObj
         wm3_mc_setValue morph_mod mc 0.0
         targetObj.isHidden = hideTargets  -- supplied function agrument "hideTargets"
         if reTargetFromScene then wm3_mc_buildFromNode morph_mod mc targetObj --supplied function argument "reTargetFromScene"
      ) else (
         append targetObjs (wm3_mc_getTarget morph_mod mc)
      )
      --reposition target, using supplied function argument "offsetPos"
      targetObjs[targetObjs.count].pos = obj.pos + (offsetPos * (findItem (valid_mChannels as array) mc))
   )

   --restore values
   for mc in valid_mChannels do (
      wm3_mc_setValue morph_mod mc value_mChannels[mc]
   )

   if hideTargets then hide targetObjs
   resumeEditing()
   return targetObjs
)

morpher_ExtractTargets $ $.modifiers[1] --hideTargets:false offsetPos:[8,0,0]