Home Website Youtube GitHub

SOLVED: Does anyone have any issues with Softness control

Makes sense Chris, that old XSI article pretty much has the formula posted on it.

I never considered doing it in reverse. But someone smarter then me could probably answer that better.

image

From what i read in the code there is an issue (I think) with the distance2 and distance call

either by removing or changing the calls to distance2 alltogether or just changing

stretch = distance / newlen;

to

stretch = distance2 / newlen;

I really don’t know myself unless I try and mess with the code and compile it.

I’m also not sure if the code is changing the length of the bones themselves or adjusting the effector or both.

1 Like

So my findings did not reveal much. The way the IKFK2Bone solver works with the softness is by changing the length of the bones to adjust for the algorithm. This however does not work if the IK does not have stretch applied to it. Normally how soft IK solvers work is the softness is applied to the IK handle position itself to achieve this effect. I tested this by running the mGear IK handle without stretch and parent constraining it’s IK effector to an node with an expression added.

This works very nicely with mGear. So I know fixing this is possible I am just still a bit new at maya’s API and am unsure how to add new output attributes to the node, and have them access as variables. Unless someone can find something to fix with the math or run the calculation based on a matrix position instead and a quaternion output attribute the node spits out so things can be updated in Shifter.

Just my thoughts.

Nice finding @dew
Thanks for all the research you are doing. All this information will be very useful when we tackle the ticket. :slight_smile:

Ty Miquel. I seemed to have checked the math on the algorithm itself and aside from some small differences I can’t see any issues with the equation in itself.

I’m beginning to suspect it has something to do with the way the elbow position is calculated. As we can see here when the “softness” value is changed in a default position the elbow is moving to compensate for the softness distance.

So that is definitely being added into the final calculation of it’s position. However something is preventing its position to lag behind like you would normally find in a softIK system. When the MaxStretch value is at 1, as in no stretch being applied. We can still see the soft IK calculation being done onto the Length A and B sides of the bones however the elbow snaps into position as if it were a normal IK.

I am still able to move the elbow freely, however there is something positional not being added up correctly. Since the bones become completely straight then change their lengths instead of forcing a triangular shape and changing the elbows position mostly. I’m pretty sure the end bone (Wrist does not move past it’s max length but eases into it instead.

I checked the code sections of where the elbow position is being calculated and the only thing I can find is some commented out code for scale. I did not uncomment it to check if it removed the bug. But any thoughts from folks as to where I should look in the code would be very welcome.

So I’ve reached the conclusion that there is no possible way to add soft IK to the bone lengths and have the elbow ease into position. I changed the math to absolutely make sure the end and root are following the soft IK distance algorithm correctly. However this means the lengths of each Bone will shorten temporarily to account for the sudden dampening effect. By doing that the elbow now sees the lengths have suddenly shortened and snaps down because it’s calculating it’s new position.

The only solution I see possible to fix this is to run the soft IK calculation independent of everything else. This would mean the If statement would run and output a new matrix attribute controlling the IK handle Null/Ref, which that can be constrained normally to all of the components. It would only change the structure of things slightly. I wanted to see about fixing this and leaving everything else in tact but that does not look possible unless there is a way to calculate the elbow’s position to compensate and that does not seem like a straight forward fix.

Any thoughts would be greatly appreciated.

Never mind I apparently figured it out. I was looking in the wrong place. The law of cosign had to be factored in.

It works, and works VERY well. I just need to get the stretch working back with this and it will be non destructive to everyone’s rig.

easy fix once you know what the issue was. (Isn’t it always, 4 days of doing this says otherwise)

I will upload the source code once I get the stretch and everything working with it.

Thank you! For allowing me to help out and solve some bugs.

1 Like

@Miquel Would it be possible to change this topic name somehow to solved?

@dew thanks to you for all the research and information shared :smiley:

done! :wink:

1 Like

I’ll finish fixing up the stretch with the Softness this weekend. When I have this code fixed how do I send it back to you guys to make sure it gets pushed through with the new release? @Miquel

1 Like

Please use Github PR (pull Request)

are you doing the change on the C++ code?

@Miquel yeah it’s all in C++, it’s not a lot of lines. It just took me a while to figure out the logic issue. It’s a simple fix in hindsight. I kept recompiling the plugin until I figured out what was the issue.

1 Like

Hey @Miquel I finished fixing up the bug and created a pull request. Here is the the stretch working with and without the softness. SoftIkAndStretchFixed

The only change that has to be made in shifter is to change the Max Stretch attribute from Min 1 Max 99 to Min 0 to Max 1. It should work perfectly after that. Previously built rigs will just need to adjust it in Edit Attributes in maya. Should not break anything.

I’ve never used GitHub before so I hope I did this correctly. If not i can attach the source code here directly.

2 Likes

Awesome! @dew Thanks for the PR! :heart:
I will check it ASAP, but I may take a little to integrate it. I want to test it carefully with a few production rigs to ensure no surprises :wink:

NOTE: The PR arrived perfectly :slight_smile:

Ty! @Miquel it should work the same the only caveat is there would need to just be the change in shifter and in current rigs the Min Max of Max Stretch would need to be set to 0 and 1 respectively. Thank you for allowing me to fix this. I feel really good about it and no worries, take all the time you need to integrate it I want to make sure it works for everyone.

2 Likes

Great work! I haven’t compiled to test, but I watched you working through this on Discord, and it looks like it will behave a lot better!

My only concern is that I think you’ve change the meaning of “Max Stretch” from clamp to multiply.

Max Stretch is a way to limit/clamp how far the arm stretches. If you had it set to 2.0, the arm would double in length before reaching the end and then no longer stretch. 1.0 meant it would reach the length of the arm and then stop stretching. (Equivalent to not stretching, but not the same thing as multiplying it off.)

If you’ve set it to 0-1, does that mean it is basically a percentage blender from OFF to ON? Meaning if you have it set to 0.9, the arm will 90% reach the length of the goal.

I personally never used Max Stretch as a clamp. The animators always wanted it cranked to 99 so the arm would just stretch indefinitely. But this does change the meaning, so it is worth double-checking that that was the intention.

It might be better to ADD an attribute “stretch”, or “stretchOffOn” that would turn the stretch on and off from 0 to 1 like you’ve done. And then maintain Max Stretch as a clamping/limit on top of that. This might help prevent any unintended changes to the rig behaviour.

Hey Chris. Yeah that’s exactly what I did since it required the least amount of large changes to the node itself and seemed to be the most non destructive.

Adding a node attribute would require a few changes in everyone’s rig. As an animator I don’t understand the purpose of clamping the stretching distance in that way. Normally I only ever have the stretch on or off or a multiplier making it go from off to fully on. This made the most sense to me mathematically and logistically. However that does change the purpose of max stretch to just stretch. Which is what I think the majority of stretchy arm rigs use is just an on/off function.

If absolutely necessary I can go back in and tinker with adding another attribute to turn the stretch feature off and on and a multiplier. I feel this may borderline on redundancy but I’m pretty utilitarian with my rigging. My first impression with max stretch function was confusion as 1 meant no stretch and up to 99 was infinite stretching.

Just let me know what you think. I’m not sure how to ask the general community what they would like me to do to make this as least destructive as possible and the most accommodating.

I think you are right. And personally, I think clamping the result is pretty useless too. But do keep in mind that these components don’t need to be used for just organic biped characters. You can’t imagine all the ways people could use them.

Adding an attribute wouldn’t change any existing animation. Since stretch is on by default, have “stretch” set to 1.0 would mean the result was the same.

Changing the meaning of the math could potentially change existing animation, especially if you’re baking it into the solver, where it could even potentially change the animated results of a rig that wasn’t rebuilt. (As far as I can imagine.)

That said, maybe the solver would also need to ignore the new “stretch” attribute if it didn’t exist, on a rig that hadn’t been rebuilt. Otherwise old rigs might break. (Sorry for complicating this! I hope some other people chime in, or there is an easy answer I’m not thinking of.)

Yeah I would def want to get some feedback and input from folks so I can gather a general idea of what people want me to do. The bug itself is fixed so it would just mostly be me adding a new attribute, which is a lot of new lines of code to do. And I would need to make a few adjustments to each shifter component to make sure it properly hooks everything up. The distance clamp would need to be a separate function. To return a max value, just guessing off the top of my head rather then using that as a ratio for the stretch itself, which is how it functioned before.

Would I need to make a new topic? What would be the best way to ask and notify everyone of this suggestion. I’m willing to do it since I now have a very good understanding of how the solver itself works and the math involved.

That does sound like a lot of work. :frowning:

Maybe there is a way to tweak the formula, so it doesn’t ultimately care what the Max Stretch is?

The distance could just be relative to the restLength of the bones. Then no matter what your formula is, the softness range is just relative to the restLength. If it extends to 99, then after the extra softness distance, (say 1.1x for example) it just stays straight. 1.1 to 99.0 would just be straight. The softness only needs to operate on that small range, ever.

So I’m proposing (if this is possible) to put Max Stretch back to how it was (1 to 99). Change the formula so it doesn’t care about Max Stretch. And then avoid adding any new attributes.

I do understand that some stretch needs to be there, in order for the softness to reach a straight result. But if Max Stretch was set to 1.0, then it just wouldn’t be possible to reach completely straight. But that’s fine. That’s just a limitation of the softness extension formula.

(I’ll try to stop replying now, and leave room for other opinions! :face_with_hand_over_mouth:)

I do understand that some stretch needs to be there, in order for the softness to reach a straight result. But if Max Stretch was set to 1.0, then it just wouldn’t be possible to reach completely straight. But that’s fine. That’s just a limitation of the softness extension formula

This is actually a misnomer, no stretch needs to be there for soft IK to function. The way soft IK works is by lagging the distance behind the controller, there is actually no stretch involved whatsoever. This was why there was a bug in the first place since the logic dictated the stretch was dependent on the softness, which is not true.

I can make the max stretch behave like a clamp but I think for most animation purposes a traditional stretch being on and off from 0 to 1 needs to be there. It’s confusing for an animator to see 1 as no stretch and 99 as infinite and in a rig it’s always good to ask if what we’re doing is redundant. I can make them both work but it does beg the question if the max stretch is 1 no stretch will happen, and if the stretch is 0 no stretch will happen, so an animator has to know to have the max stretch above 1 and the stretch value itself at 1 for the function to take full effect. The only other logic would be to have a Boolean instead for the stretch to say on or off so it’s more logistical to function in tandem with the max stretch.

Again this is why I wanted to see if I could ask the community what would best suit them or make the most sense.