Questions about calculations involving bones
rames44
Posts: 329
Just starting with Daz scripting, so expect a whole sequence of newbie questions from me.
I'm trying to do some calculations involving bone positions. I've read the documentation on DzBone and its base classes, and I do understand the difference between "local space" and "world space" when it comes to positions, rotations, etc.
Questions (all in the context of DzBone, even though many of the methods are in DzNode):
- I assume that the "location" of a bone refers to its root (for lack of a better term). Given the location and rotation or transform for the bone, how does one calculate the position of the bone's tip? I see the DzNode.getEndpoint() method, but uncertain what space that is in and how it relates to getLocalPos()./ getWSPos()
- How does the return value of DzNode.getOrientation() differ from the return value of DzNode getLocalRot()?
- For items that take a Boolean defaultVal=false argument, if one passes in "true" for that, does this give you the value as if the bone's "positioning controls" were all set to zero? (i.e. as if the bone in the figure is in the default pose's position)?
Thanks in advance!
Comments
You will find mcasual's scripts to be an invaluable source of DAZ script examples: https://sites.google.com/site/mcasualsdazscripts9/home
I think it's in LocalSpace - see e.g. mcasual's usage in https://sites.google.com/site/mcasualsdazscripts7/mcjchainchainchain
As for your questions 2 & 3: I don't know - I'd like clarification too.
Thanks - I’m well aware of mcasual’s awesome body of work. It was what inspired me to dip my toe into this, and I am gradually deciphering how some of his scripts work.
i just wish the Daz docs were a bit more detailed.
when you zero-pose a figure ( maybe also zero-morphs ) the figure is in a T-Pose, which is the way the figure was rigged
the bone.getEndPoint() function gives you the position of the end-Point in World space
but as we'll see below this doest mean it's the position where we expect the hand joint to be
to get the world-space endpoint, you'd probably be better using the world-space joint position and the children-bone joint position
example for Genesis3 zero-posed but not zero-shaped
my genesis3 was zero posed
here you can see that the position of the hand and the position of the endPoint of the foreArm don't match
so the world-space positions of the hand and foreArm are better if you want real positions
-----------
i think the endpoint parameter is more a convenience for rigging, by that i mean it's used when comes time to bend the skin of an elbow for example
------------
since the finger tips dont have a child bone, you could parent and position null nodes at the finger tips
and get your null node using
lIndex4 = lIndex3.getNodeChild( 0 );
===========================================
getOrientation() tells you how the 3 hinges that make a joint are oriented
so here too its mainly a rigging convenience, well actually historically i found this brain-stretching to work with,
but i did fight the good fight when i made a script to rig mirrors on my VW Transporter
https://sites.google.com/site/mcasualsdazscripts3/mcjchangeorientation
getLocalRot() gives you a Quaternion, that describes how that bone was twisted and bent from its initial zero-pose , to be in its current orientation
Local means, imagine the figure was in the zero-pose ( t-pose ) and now the foreArm is bent 90 degrees
getLocalRot() would give you a quaternion that rotates something 90 degrees around the Y Axis
skeleton = Scene.findNode( "Genesis3Female" );
foreArm = skeleton.findBone( "lForearmBend" );
debug( foreArm.getLocalRot() )
the result : [-0.00681274,0.707073,-0.00100848,0.707107]
quaternions, if you dont know are not euler rotations like we see in the parameters tab : rotx roty rotz
instead they are of the form x, y, z, w
where xyz are like a hinge arouns which the rotation will occur and w indirectly tells the angle of the spin around that hinge
so you have to use functions that accept quaternions to manipulate them
say you have 2 vectors you can get the quaternion for the angle between those 2 vectors
by doing rotab = veca.getRotationTo( vecb );
then you can do rotForeArm = foreArm.getWSRot()
then rotForeArm = rotForeArm.multiply( rotab )
foreArm.setWSRot( rotForeArm );
and we rotated the foreArm by the angle between veca and vecb
i do most my rotation tricks using the getWSpos, getRotationTo, multiply, setWSRot functions
you just have to figure if you need to do veca.getRotationTo( vecb ) or vecb.getRotationTo( veca )
the other functions i use a lot for the 3D space gymnastics are thisStick.getWSRot().getYAxis()
which gives you the YUp vector for theStick
Thank you maestro!