Home Website Youtube GitHub

Tweaks Rotations break Uniform Scaling rigs

This means any limbs that need tweaking to achieve crazy noddly poses, who need Rotations and Translations, not just Translations for Tweaks to achieve smooth deformations, are not exportable via FBX to game engines or anything. Example [the broken deformations become a lot worse when more ctrls are involved, this is a really gentle example, but things can look completely exploded into the stratosphere]:


What I do for the export atm is I duplicate the skeleton and create parent and scale constraints for every joint. It worked very well and cleanly so far. I will try to export in other ways. Meanwhile here’s an error I had after trying to export some exploded skinned mesh:

Non-orthogonal matrix support. One or more objects in the scene has local axes that are not perpendicular to each other (non-orthogonal). The FBX plug-in only supports orthogonal (or perpendicular) axes and will not correctly import or export any transformations that involve non-perpendicular local axes. This can create an inaccurate appearance with the affected objects [etc, all joints Below in hierarchy, so under the arm, so fingers and so on].

And yes, btw, I am forcing uniform scaling. It works fine for everything else, it doesn’t seem to work the same for Tweaks.
image

You are having the same issue as me i think the manipulation you’re doing is Shearing the joints and the FBX export does not support joint shearing. The only work around for it i found was to manually break the “Shear” connection on the joints. so it stops doing it. i JUST made a post about this issue. (well at least i think its the same issue : How To Prevent Shear On Joints)

1 Like

Shear didn’t seem to fix it [maybe I didn’t do it correctly] but… merging all skinned meshes as 1 and then changing the way I’m exporting, did. Instead of duplicating the skeleton, I’m exporting the mesh and skeleton as is, and then auto/batch fixing the exported fbx/s. Maybe there’s a better way to export, but so far I wasn’t able to figure it out. Problemo 1 being that the rig is referenced, so I can’t export cleanly, directly, I need to unparent and remove references. Removing refs in a referenced anim file… I believe is only possible via de Ref Editor, so not something I can batch script. Anyway, all seems to be fine. It’s hard to export mGear to game engines, was clearly not designed for that, but after jumping thru a few hoops and dying a few times, it worked. I hope. Until the next surprise… O o

Hi! mGear is perfectly exportable to game engines and you don’t need to do anything special to use it. We use mGear in production in my current studio and I have also been using it for my personal projects for over 5 years now. Unity or Unreal game engines only required a single joint hierarchy, blendshapes and skinning (normally 4 influences ber bone, up to 8) Unreal 5.1 supports even dual quaternion skinning. I captured this little example of how you can export and import from Maya to Unreal. No scripts or complicated workflow needed:

Dragon’s Lair, Dirk the Daring, mGear Maya rig - #7 by Milio

3 Likes

Yes but I bet you’re building all your rigs with “Force Uniform Scale” that way nothing is getting sheared. the second you have a shear value in any of your joints the FBX exporter will not export that. Or it will export it but kill the value and then you’ll have a discrepancy of how things look like in maya Vs your exported FBX file

And if you have characters that are somewhat cartoony and your animators what to squash and stretch things none uniformly that’s when things get interesting especially if you have mGear Foot and Arm controllers involved.

Thanks, I know that video Milio. That solution doesn’t work for referenced rigs. There is nothing referenced in that scene as far as I can see. We cannot unparent referenced nodes and, as mentioned above, I don’t believe it’s possible to un-reference either, in code, only with the Reference Editor. 2 essential problems when working with references and especially if you want to batch export.

That aside, there are multiple ways to export an Fbx. Maybe via the game exporter it’s cleaner, but it’s manual and slow. Via regular export or from code it works just as fine, as long as the settings are correct I guess. I do have to open the exported files anyway, to unparent and remove references, and with that occasion I can fix anything else I need to. It’s not trivial but it’s automatable.

You mean import from reference? Sure you can.

# "ref" would be some refNode.
refFile = cmds.referenceQuery(ref, f=True)
cmds.file(refFile, importReference=True)

This example is overly complex, because it checks for invalid references, and also supports importing nested references:

import maya.cmds as cmds

def get_reference_depth(ref):
    currentRef = cmds.referenceQuery(ref, referenceNode=True)
    parentRef = cmds.referenceQuery(ref, referenceNode=True, parent=True)
    topRef = cmds.referenceQuery(ref, referenceNode=True, topReference=True)
    safeCounter = 0
    while safeCounter < 20 and currentRef != topRef:
        safeCounter +=1
        currentRef = parentRef
        parentRef = cmds.referenceQuery(currentRef, referenceNode=True, parent=True)
        topRef = cmds.referenceQuery(currentRef, referenceNode=True, topReference=True)
    # return +1 because 0 will be the root space for non-references
    return safeCounter + 1

def import_all_references():
    validRefs = [
            each for each in cmds.ls(type='reference')
            if not each == 'sharedReferenceNode'
            if not 'sharedReferenceNode' in each
            if not '_UNKNOWN_REF_NODE_' in each
            if is_valid_ref(each) == True
            ] or []

    allLoadedReferences = [
            each for each in validRefs
            if not each == 'sharedReferenceNode'
            if not 'sharedReferenceNode' in each
            if cmds.referenceQuery(each, isLoaded=True) == True
            ] or []

    allUnloadedReferences = [
            each for each in validRefs
            if not each == 'sharedReferenceNode'
            if not 'sharedReferenceNode' in each
            if cmds.referenceQuery(each, isLoaded=True) == False
            ] or []

    # We need to get a bit fancy here.
    # Support using nested references. So get_reference_depth() counts how many parent references there are.
    # Start by importing the lowest levels. Parents first, then their children.
    # If you try to import a child reference first, you get an error.
    sortedRefs = sorted([[ref, get_reference_depth(ref)] for ref in allLoadedReferences], key = lambda x: int(x[1]))
    # Example result of sortedRefs: [[u'Main_Character_RigRN', 0], [u'Character_Prop_RigRN', 1]]
    for ref, refDepth in sortedRefs:
        refFile = cmds.referenceQuery(ref, f=True)
        cmds.file(refFile, importReference=True)

1 Like

I did notice some odd joint behaviours when importing into unreal, a strange kind of gimbal lock affecting really odd joints, extra head ones or arms twisters. Found out later that was due to the shear issue. Since then, I remove shear from joints and keep a non-uniform scale for squash and stretch when necessary. Unreal cope with scale exactly as Maya.

2 Likes

The video just showed the “manual and pedestrian” way to do it not involving any scripting. And to be able to export animations using reference you just need to parent the hierarchy at the root of Maya scene. Game exporter is a great way for exporting consistent data in fbx. WIt will keep name conventions, paths and options.

However, It is very simple, without not much python knowledge, creating a script that deals with all the export process, something like this will do the job:

1.Find out the location of mGear joint hierarchy, usually under the jnt_org groups.
2.Copy the hierarchy with input connections. This will simply duplicate a local version of the joints.
3.Move the new hierarchy to the root of the scene. (when duplicating, root joint name might change, rename it back to keep same joint names)
4.mGear set all joints to non key-able by default. Set them back to keyable.
5.Bake all hierarchy.
6.Export the hierarchy as fbx.

if you generate a rig with “Force Non Uniform scale turned off” and delete all the shear connections your IK limbs will look really off if you stretch them out from side to side (up and down looks ok)

What I found as a work around is this :

I generate a rig with “force none uniform scale” turned off, then i break all the shear connections that all the joints have this in turn makes my IK limbs look wonky so on those i reconnect them back into the mGear Matrix node the same way that they would be connected if the rig was generated with “Force Uniform Scaling” turned on.

This way at least some of the rig can me squashed and stretched none unformaly and it gives “ok” results.

I still say all the Epic components should just NOT have any shear connections to begin with since they were geared towards gaming. my 2 cents.

Still love all the work you guys do though <3

An example of what i’m talking about because a picture is worth 1000 words :slight_smile:

Here’s a Leg thats set up with the Epic_Leg nohting fancy no twist joints nada.
The rig was generated with “Force Uniform Scaling” Turned OFF

Look at what happens when break the Shear on the “legFront_ball_l” and “legFront_foot_l”!

The skinning totally goes totally off on the toes. they get this sward screw in them.

2 Likes

No, I mean un-reference. All animation files reference the rig. Let’s say the rig is called George, and contains a rig and a geo group. It [normally] becomes namespace after referencing. So any animation file ends up having George:rig and George:geo. Inside the geo group I have my mesh called George:Mesh. Inside the rig group, you know, the usual suspects, and under the jnt_org/root_C0_jnt_org groups I have my George:root_C0_0_jnt.

What I need to export to Unreal is a clean Mesh and root_C0_0_jnt with the rest of the bones below, baked animation on relevant range. Nothing else, no namespaces.

To do this I initially duplicated the skeleton, constrained new to old skeleton… and ended up with problems because of Tweak Rotations. Now I’m exporting the mGear skeleton itself, seems to work fine, it’s a more complicated process, but all scripted.

The last bug I’m fighting is that I’m force-opening Fbx files, instead of force-importing them. And Maya sometimes fails to open Animation. No keys imported! Sometimes it works, no idea why. And that ruins the entire batch. I open the Fbx with the normal open function because I need the range that I exported. Any idea if I could somehow Import Fbx and detect the native range of that Fbx file? More exactly meaning: playbackOptions min and max. I need this range so I can trim and move animation accurately, so all files start at 0 and do not contain any extra keys.

Cheers!

I told you a command that actually exists in Maya. “Import objects from reference”.

What is “un-reference”? Can you share the actual command you’re running manually?

Oh yes you’re probably right, by unreference I mean removing a reference BUT… I actually mean remove its namespace! It doesn’t really remove the reference, just its namespace, which is all I need.

I’m using the namespace command with move namespace and remove namespace flags. Like so:

namespace -f -mv $George “:”;
namespace -rm $George;

This doesn’t work in an animation file with a referenced rig, so I select the Mesh first and export selected with:

FBXExportBakeComplexAnimation -v true;
[dunno if necessary or if even correctly used here…? I added this because of bugs where the baking flag was for some reason, by default, after restarting Maya, set to false]
FBXExport -f $customFileExportPath -s;

And then in a second step I open the exported Fbx, remove the rig’s namespace, and do anything else I need. FBXExport works pretty messy by default tho, I probably need to understand what other commands to add to get it to export cleanly only the relevant range.

Sorry for the confusion! Hope this explains better.

Yeah that explains better. You’re conflating references and namespaces. They aren’t the same thing. You can put anything in a namespace.

I don’t know off-hand how to remove the namespace from a reference. But if you import the reference first, you are more free to edit or remove the namespace.

You’re sort of doing the same thing anyway, by bake/exporting and then importing again. You can just import it from reference directly, like the code I originally shared.

wow! I never noticed such misbehaviour! But I just tested right now and indeed the IK becomes wobbly!
I wonder if keeping it as it is and deleting the shear at exporting time will be enough to keep Maya>Unreal working the same. Totally agree with Epic components shouldn’t have this at all to be 100% real-time friendly. Cheers!

P.S tried it out… duplicated the joint hierarchy, deleted all shear, set it to 0 and the skinning visible differed from the original… not good.

Sadly no, That’s how we noticed the issue. One of our animators was like : “hey man, if you look in maya my feet are planted perfectly, but when i look at my exported file they seam to be wobbling all over the place” witch in turn led to a few hours of “WTF IS ACTUALLY GOING ON HERE” until we figured it out.

Like i mentioned earlier the only work around I’ve found to this is is to generate my rigs with none uniform scaled turned off. Witch allows the animators to scale most of the joints they need scale and then to go over what ever joint is included in an IK chain and plug the scale back into the mGear Matrix node the way it would be plugged as if they rig was generated with “Force Uniform Scale” On.

I guess you can do it the other way around but i found this easier. :stuck_out_tongue:

1 Like

Still don’t quite get the shear transformation at all… is such a strange concept! i guess no real-time rigs might benefit from it somehow… maybe @Miquel can shed some light about this, coming up with a real solution for in-game rigs. Cheers!

1 Like

Hello!
I am not good at explaining math, but I will try my best :stuck_out_tongue:
In mGear we calculate all the matrix transforms in a raw way. The typical 4x4 transform matrix.
To calculate it as a part of the rotation, scale, and translation values we need the shear values to calculate the transform when the parent has not uniform scale.
So we don’t use the segment scale compensation in Maya and ensure that there are no transform operations happening behind curtains.

Unreal support Non uniform scaling but will behave funky if you have child objects. The solution is to use leaf joints and only scale non-uniform on lef joints.
The other is to avoid non uniform scaling to avoid it.
Does it make sense?

I have developed components for clients with this kind of solution with leaf joints. But the classic and the EPIC components don’t have leaf joints.

1 Like