jcms strange behaviour

Issue #412 resolved
Alessandro Padovani created an issue

commit c68c9d5

I see a strange behavior with jcms. It seems they are either 0% off or 100% on, I mean without the usual blending. Below an example with the G8F forearm jcms, they are 0% at 57 degrees then 100% at 58 degrees. I use the default options in global settings.

steps:

  1. import G8F
  2. import jcms

Comments (8)

  1. engetudouiti

    I can find which expression cause issue, but at current Thomas avoid to use custom function for driver, expression so it make difficult to read if condition from expression. you may see issue without set rotation at all.

    the pJCMForeArmFwdL(fin) driver expression is like that

    A = lForearmBend.rotation[x]

    expression

    1 if A> 2.356 else 0.955A+2.945 if A> -0.556 else -0A if A> 0 else 0

    so when input 0 for A, it already add value as 2.945 >> limit by range, then the shape key will be added as full. I hope to use elif , easy to read, but blender expression seems not forgive elif. but I suppose Thomas can fix it soon. I can not read this expression untill learn Blender default expression (no python) if and else usage at all.

    https://blender.stackexchange.com/questions/109345/is-there-any-driver-expression-for-elif-statement

  2. engetudouiti

    maybe -0.556 should be 0.556?

    ((1 if A> 2.356 else -0.955A+2.945) if A> 0.556 else 0

    I understand, the difficulity, it is key-type animation ERC, and it need to work with pJCMForeArmFwd_75_R with use X rotation range. Thomas try to make it work for G8.1

    and 0.955A may need to change as -0.955A too.

    I suppose the morph work only when A>0.556 then when 2.3566 it need to stop as 1.0 so it should be

    ((1 if A> 2.356 else -0.955A+2.945) if A> 0.556 else 0

    The main difficulity is, daz bone rotation axis change in blender, plus and minus, then script may miss. (in daz bend value set as minus direction, in blender rotation X need to set as plus direction.

    At same time, it may need to check pJCMForeArmFwd_75_R expression too. (if it somehow corrupted, it may cause issue for same rotation)

  3. engetudouiti

    No it is wrong ^^; . I may try check with real ERC key of daz. All related R and L forarms ERC.

    Thomas tried to change curve constant, (to simplify) then some value seems not correctly set, I feel.

  4. Alessandro Padovani reporter

    update. As for commit 268159b this is not fixed. Tried with and without “custom drivers” with and without “combine drivers” in global options, it’s the same.

    Then tried back 1.5.1 5e4815b and it’s fine.

  5. engetudouiti

    Thomas I could find where is wrong for your expression.

    I understand, you convert TCB as y = ax + b , it not problem but the a and b value not correclty converted.

    I correct it for L forarm first. (because it keep 1.0 even though I do not set any rotation)

    To check it, you may better to open daz hieralchy propearty first.

    In daz studio,, key -135, value = 1, key -75 value = 0, key 0, 0

    about Larms, you can change minus as plus for blender L forarm X rotation. (bone bend axis),then I convert it as y = f(x) graph first to check easy.

    because, you convert it as Y = aX + b, linea. it is not problem. But your currently set expression is

    if A> 2.356 else 0.955A+2.945 if A> -0.556 else -0A if A> 0 else 0

    the problem is, you use -0.556 to represent key > 75 (invert minus) .

    75 degree = pi*75/180 = 1.3083,,, so you need to set this value to make range (A > 75)

    at same time you add 2.945, but if you make it so, the f(x) > 2.945 when x>0 always.

    My convert expression is

    1 if A> 2.356 else 0.955*A-75/60 if A> 1.308 else -0A if A> 0 else 0

    75/60 is I simply use ratio of graph,, . with see graph. to represent the f(x) line. I simply keep to use 0.955, (believe your conversion and now confrimed it is right) for step value. 1/ (pi*60/180) = 0.955 then now it work correclty.

    When I input 135 degree (x rotation), it show as 1.0 , when I input 75degree, it perfectly set vallue as 0. then gradually change value to 1.0 untill 135 degree.

    I suppose you can simply use same expression for R forarm too. because, in blender, both L and R use plus value to bend direction. (daz use opositte direciton)

    I may check later about pJCMForeArmFwd_75_R and L. it should be more easy to circulate Y= ax + b, with range. Yes I confirmed, the expression is right aobut 75 jcm.

    Though I do not know why script miss convert about this morph, , the range, and Y intercept value (b of Y = ax + b)

  6. engetudouiti

    Thomas I made test script, to input 2 point key and value, then generate range, step value, and X interception for the f(X) line.

    I think there should be some miss conversion, when you convert daz key and value from dsf, then generate expresison. because I do not think this problem only happen about pJCMforArmbend (135)

    it may happen, when the expression need middle range, like a<x<b . I suppose you pick 2 points of (key, value) then generate f(x)=Ax + B , when you conversion. like (75, 0) and (135,1) ,then current conversion seems miss circulate B and range.. When the f(x) = Ax, , it can circulate correctly.

    You may confirm, actually your conversion function for TCB curve from key, is same as this?

    At first I supposed, add on only miss input minus and plus, for blender arm bone, but even though I input minus value, it not show such step value and interception (x=0) like add on converted.

    If it simply miss input one of them or happend to not convert radians correctly, it not matter. But to see the problem morph range conversion, I think there seems miss convert about range too.

    step value seems no problem, so it is only matter, about range and interception (B of Y=AX +B)

    I know I can generate as Y=a(X-b) first, but it may make mistake when return as expression easy so I do not do so.

    import bpy
    from math import radians
    
    def getTCBexp(ak,av,bk,bv): #key0 = ak,  value(key0) =av, key1 = bk, value(key1) = bv
        ak=radians(ak)
        bk=radians(bk)
        print(bk)
        step = (bv-av)/(bk-ak)
        icpt = bv - (step*bk)
        print ("step = ",step)
        print ("icpt = ",icpt)
        print ("range: " + str(ak) + " < " + str(bk))
        li = [step, icpt, ak, bk]
        print (li)  
        return li  #f(x)=Ax+B  step =A icpt=B for x=0 , range: ak<X<bk
    
    getTCBexp(75, 0, 135, 1) #test input for RforArm case
    

    the console output (forArmFwd135) for those 2 point

    step = 0.9549296585513721
    icpt = -1.25
    range: 1.3089969389957472 < 2.356194490192345
    [0.9549296585513721, -1.25, 1.3089969389957472, 2.356194490192345]

    Then I think there seems miss conversion for middle range. and interception circulateion. so it may cause same issue for another bone, it may have same type middle key and value.(TBC convert)

  7. Log in to comment