Miss convert transform driven value for facial bones

Issue #432 resolved
engetudouiti created an issue

I did not notice this problem (then do not remember how old morph version worked). but today I could confir, when I import bone pose controller which trasform pose bone, it not move drv facial bone as same way in daz

most simple case is, you may use mouth side to side r or l pose controller. then lips deform wrong.

like this

you may check L or R lower lip outer (drv) bone transform value, then compare it in daz L / R lower lip outer. it clear show different postion, when you use mouth side to side.

I suppose the reason is, blender pose bone transform X, Y, Z along with each bone zero pose local axis. But Daz transform axis x, y, z along with parent bone local axis. so without add on auto convert it, we can not use driver expression for each blender X Y Z component.

The difference may clear when driver drive pose bone transform along with Y (twist) axis. (those lip bone not along with world plane then in blender, if we change Y transform value, it transform along with the bone local Y axis direction. in daz it not move so.

Though I do not know detail but at least I do not think current pose bone driver correctly convert daz bone transform driven value for blender drv-bone. I can confirm some lip bone not driven to conrrect position as daz. I still not confrim if it is circulation way or axis problem.

Comments (16)

  1. engetudouiti reporter

    Yes it seems new issue (somehow important) to generate pose controller driver.

    I made test pose controller which move pectoral along with daz Z axis 3.0 unit (3.0cm in daz unit) (Z transform value of the bone). then import to blender.

    In daz it move bone like this.

    the blue line (Z axis) is axis the bone drive. x, y, z transform value move bone along with current transform tool axis (red, green blue), you remember it.

    In blender, we know how to convert edit bone axis for each bone local. when we generate bone. (or add on use template to acjust it correctly) But about pose transform axis, it may need to change. in pic I suppose add on try to convert it as world matrix transform, then convert for blender axis Y component. it drive bone along Y axis from daz X axis 3cm to blender Y axis 2.7656 , but it not drive X and Z transform value. (not convert perfectly ) so bone only transform along with blender bone local Y axis. it is not same axis direction as daz bone transform. (we need to add X and Z delta transform I suppose)

    The issue seems, after convert daz Z transform delta of the bone, as Matrix, then separate for each component transform,, it only pick one transform axis (convert for blender) vector. but it need to move another 2 axis too.

    I suppose if the import morph file describe delta for all component (x, y, z), add on may convert correctly. but we may not make ERC so. (and vendor not), they may only remain delta data, which actually transformed in daz studio.. (so not describe 0.0 transform for non used axis)

  2. Thomas Larsson repo owner

    You are right that all axes except the major one is ignored. I thought that daz drivers only drive a single component, so when we changed the bone orientation to be the same as in DS the other components would always be zero. Indeed, in all cases that I checked that turned out to be correct, but here we evidently have a counterexample.

  3. engetudouiti reporter

    I still do not know how you convert daz axis transform bone to blender bone axis clear.

    but from value with test hand-made controlelr, I clear see importer change transform value, then I can suspect, you convert daz one axis vector transform as blender pose bone transform…

    I just confirm, when we do not pose (keep rest pose) then only move one bone, the bone translate along with object local axis in daz studio = world x, y, z axis. Then ERC simply translate bone along with the world axis. Actually if we do not rotate other bone all bone transform axis is same (but it only for translate, rotate use current bone rest pose local axis)

    In blender,, the rotation axis is same as daz. but translate axis is different, it along with each bone rest pose local axis, (which we set orientation and roll when generate rig as same as daz,,. Can you find solution ? I think you may need to convert daz matrix to blender one, then get each component delta add value, untill generate driver…

    I think, it may not (I hope) so difficult, when property drive pose bone, to convert daz erc as blender Driver expression for each component,

    (all delta add need to convert as 3 axis translate delta value, I suppose)

    But if there is case,, daz bone translate value of each component (x, y, z) drive other prop,, (Like jcm ,), I do not know how we can correctly convert them as blender driver, Though at least I still do not find such morphs, which driven by bone translate value…

    (I check some daz bone x, y, z parameter ERC then they have no child component,, though if there is some morph which will be driven by bone translate,, at current I do not have such morph and product,,)

  4. engetudouiti reporter

    Then basically all daz body bone not translate. so it only matter for facial bone. (and pectoral bone, if there is morph which translate like my test morph ^^;)

    I actually find some 8.1 pose bone are driven by expression morphs. If we hope it work perfect same as daz,, Those translate delta value of one axis , need to convert as 3 axis translate I suppose..

    ( you may need convert function,,, untill generte driver,.. In daz prop translate bone along with one axis,, everytime we need to convert the translate value of one axis for all 3 component axis delta, first I suppose.)

    Though I do not know it must need or not.. i if you convert all delta translate of pose bone drive value for one axis as 3 axis translate it may cause peformance issue when import moprh and generate driver, I afraid it.

  5. engetudouiti reporter

    I suppose if we generate bone_loc which along with rig object cordinate axis (X, Y, Z) with keep parent relation same as bone_drv (same hieralchy) then drive bone_loc (x, y, z) as same as daz translate value for each axis, and use constrain (copy translate) for drv-bone which copy location of bone_loc may work.

    But do not know you may test it or not. it means, devide property which will be driven for rotation and location(translate)

    for rotation use drv_bone x, y, z, and for locaiton(translate), use loc_bone x, y, z

    drv_bone simply copy location by constrain.

    Of course it may show some peformance issue when generate those bone and constrain…. (though I do not know how it make pose slow)

    but as idea it may work ^^;

    I attach blend file, which rename each bone as drv_bone, loc_bone. (I do not include new fin-bone which used to circulate mix rotation value, I do not think, new bone_loc effect it)

    To it work, all bone_loc axis need to have same axis cordinate as object local axis. and all bone_loc need to be generated in same hieralchy as drv_bone.

  6. engetudouiti reporter

    Then I understand G8 user may not find this issue, most of case. because G8 face bone is basically along with object local axis cordinate.

    G3 is not…

    I think some of facial bone driver (typically lip bones , eyelids bones) for G3 which translate facial bones have not shown same translate (location) as daz.

    To avoid it, if we generate G3 all facial bone along with object local axis, we may see issue for bone rotation driver. because it use each bone local axis in daz studio.

    So as general case, to import daz bone pose driver, , (drive each component X, Y, Z in blender), we need to use different cordiante for translate and rotation. I can not imagine other way

    1. generate bone_loc then use object cordinate axis to translate only)

    2 need matrix function and convert to bone cordinate axis for translate (<< I can not imagine it work for driver… >>)

  7. engetudouiti reporter

    The good thing is,,, (though do not know how difficult to change current code) , bones which location will be driven can be limitted

    So if we only think about Genesis family driver, we only need to generate those loc bone when generate rig. (pectoral and facial bones which can translate) . even though we do not use add facial bone, (user pose bones), , those loc bone need to be generated as same hieralchy as bone which will be driven for rotation. (then when parent bone rotate, it can show same translate axis as daz for each bone)

  8. engetudouiti reporter

    I think, we can make it as advance option. that means, when user click the button with perfect rest pose and after all bones posable (add facial bone already = drv_bone generated)

    1_ generate those loc_bone (along with object local axis direction) only for facial bones (or you only generate bone_loc for some facial bones as test) then set hieralchy as same as drv_bone . if it work well I hope you make it for pectoral too ^^; )

    2 _ Only when drv_bone has loc_bone, copy driver of each drv_bone x, y, z transform to loc_bone x, y, z transform. usually it should be same…. then remove driver from those drv_bone.

    3 _ add constrain “copy location” for drv_bone which generate loc_bone only..

    So you can test it as new option, without break current functions. (without user click it it never change current way)

    Could you ^^; ?

    I might try to make test add on, if you can not take time it.. for many reasons. (and simply because it seems neat request ,, most of user have not noticed it I suppose,, or thesitate to report it to bother you with new issue..)

    ===

    No. the procedure work you need to change current conversion way (which change transform value to convert matrix, I suppose) first.. so I can not use current driver expression directly. ^^; I may test later. with manuall set driver expression, and how it work for some bones and controller.

  9. engetudouiti reporter

    Yes basically it work. Then if you generate bone_loc, (all bone_loc have same roll and axis direction along world axis) but, which axis you use may differ.

    as my taste,, I prefer this bone axis cordinate for all bone_loc . like this pic.

    daz X = bone_loc X, daz Y = bone_loc (-Z) ), daz Z = bone_loc(Y)

    then we can directly use daz ERC delta “translate” for each axis, as driver expression of loc(X), loc(Y), loc(Z) , it make conversion more simple. I suppose (about translate) . And it may not effect current bone hieralchy . (though new intermediate bone props driver expression may change for transform. if it have been converted as each bone axis,, but it may not break other things.(eg rotation driver etc).

    then drv bone location only copy the loc bone location (but drv_bone rotation prop are driven as same as before),,

    all driver expression need to describe for each component about translate and rotation, when they are driven.. so even though we use bone_loc for translate delta add driver, it may not cause heavy issue about driver circulation.

  10. Thomas Larsson repo owner

    Should work now. Althouth I only tested with G3F mouth side-side, but at least that does not open the lips. Fortunately it turned out to be a very simple fix.

  11. engetudouiti reporter

    Thanks. I suppose it should work i, you convert and add driver for all 3 component. I may test with individual pose controller.

    I actually made script, to add new loc bone and constrain for drv bone which have loc driver. but after all to make it work, I needed to ask you not to convert axis for each bone anymore but convert daz X = bone_loc X, daz Y = bone_loc (-Z) ), daz Z = bone_loc(Y).

    Now you convert axis and generate driver for x, y, z, It is good enough for me. (I suppose your conversion right)

  12. engetudouiti reporter

    Yes it worked!! 😋 I feel, I had seen wrong facial pose without intention… for my G3 characters ^^;

    Could you tell me where in your code, you convert daz translate values for object local, as blender pose bone translate local cordinate in your code?

    I may get same problem when I make driver which need to trans along with object local axis?

    anyway I close this topic as solved thanks!

  13. Thomas Larsson repo owner

    The actual transformation between Daz and Blender matrices is done in getBoneMatrix (node.py 795).

    This function is called in addPoseboneDriver (load_morph.py 349).

    The change compared to the previous version is in setFcurves (load_morph.py 385). It now loops over all components (getFactors) instead of just picking the largest one (getMaxFactor).

    The code for getting the full Blender transform matrix is very old. With the legacy bone orientation, when the bone tail was the end_point, there was no relation betweeen Daz and Blender orientation and all three components were always driven.

  14. engetudouiti reporter

    Thanks^^ It help me much, when I make custom driver which drive along with ob local. (? I do not know good word how represent daz bone translate cordinate.. do not know other aprication usually use daz way or blender way… )

  15. Log in to comment