-
Notifications
You must be signed in to change notification settings - Fork 128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Joint Group Indices don't correspond to joint indices #41
Comments
Hello!
what you describe here as control is not actually the control index. The above used API, Other than that, the joint indices that are returned by the for jointGroupIndex in range(dnaReader.getJointGroupCount()):
jointIndices = dnaReader.getJointGroupJointIndices(jointGroupIndex):
for jointIndex in jointIndices:
jointName = dnaReader.getJointName(jointIndex) This above shown snippet will gather joint names within each joint group. Now, finding which exact joints are affected by which exact controls is a more complicated process :) |
this is correct, it contains only expression indices, where expressions are:
output indices are joint attribute indices. Each joint has 9 attributes (translation.x, translation.y, translation.z, rotation.x, rotation.y, rotation.z, scale.x, scale.y, scale.z), so given any output index, when divided by 9, will result in the joint index (and this is how you can find / match which joint is affected by which row from the joint group values matrix). The joint group values matrix is in row major order, with the rows being joint deltas per each joint attribute and the columns being the expressions that turn them on. So:
Using this information you should be able to pinpoint which exact raw controls are affecting which exact joint attributes.
the equation is indeex y=k*x+n, but n = 0 always for the joint behavior data, so we remain with k*x only. Neutral values are not considered in this equation, since rotations cannot be naively added onto the delta values. |
Hi @n0phx ! Thanks for the replies you've been providing in the GitHub issues. May I ask how is it possible that this affirmation is correct? "so given any output index, when divided by 9, will result in the joint index" Since output indices are consecutive integer numbers in sets of 6 (since scale values are ignored), how is it possible that any given set of consecutive integers divided by 9 results in the same number (the joint index)? By aproximation of the possible resulting float results to an integer value? Thanks! |
this is not a correct assumption, you may only assume that output indices will appear in ascending order, but it is a sparse storage, so rows will be frequently skipped entirely where all deltas would be zeros in the matrix (this is part of the pruning strategy described in the paper). output index 17 output index 112 and scale values (while might not be frequent) but they certainly appear somewhere in the behavior data, they are not entirely absent, just not that frequently used. |
Thanks so much for all of this clarification n0phx. I read it as soon as you posted, but needed a few days to really explore and try things out. I ended up rewriting code with this more detailed understanding, which makes for a much faster and more efficient tool. I think I have some values updated correctly, by taking the entire joint group values and updating a few indices with new values. setJointGroupValues(jointGroupIndex, values, count) For saving out I am using something like this to keep previous dna data with setfrom and add an updated values list:
With this way, I wasn't sure how I might use count in setJointGroupValues. Would that be if I created a partial list of new values such as: [0.003, 0.2012, 0.02342] and somehow insert just that at the right spot, telling it how many values in the count? Also, since it is for a specific group, if I am updating several groups, I need to save to dna file each time, which can slow down the process. Any advice for efficient use here? Thank you. |
Glad this helps, sadly the API documentation / general usage guidelines for these lower level portions of the library are lacking in depth.
The count parameter is only present / visible in the C++ API, it is not available in the Python API. With the C++ API, you give a pointer and a size (which is the count parameter), telling the DNA library how many floating point values are in the matrix.
you don't need to save the DNA for each single joint group update, you can do a bulk update, call |
Thanks again for the clarifications n0phx. I've been working on organizing the dna file data and generating the correct transform deltas and the corresponding indices to place them into the joint values list. I've been able to write out data, but it is not correct. The basic idea was to subtract neutral transform values from control expression triggered transforms to get the delta values that would go into the joint group values. The joint group indices to place those values is figured out by cycling through output indices to find the correct control expression and input indices to find the correct joints moving row by row to figure out the correct index value. See code below.
step 2 get the delta. I have scale commented out as I am not sure if this is used. I'm not sure if the above is the correct way to get the delta. step 3 get the value list index for each of these transforms. This way with a list of transform deltas and value indices, I should be able to write out the data correclty.
unfortunately this does not yield the correct results. I'm not quite sure how to fix this. Any thoughts? |
def return_joint_value_indices(self, joint_group, control_name, joint_name):
joint_output_indices = self.dnaReader.getJointGroupOutputIndices(joint_group) # joint
joint_input_indices = self.dnaReader.getJointGroupInputIndices(joint_group) # raw ctrl
# within group get values related to the ctrl expression
# from output indices /9 get joint
update_value_list = []
row_count = len(joint_output_indices)
col_count = len(joint_input_indices)
for row in range(row_count):
output_index = joint_output_indices[row]
joint_index = output_index // 9
# from input indices get ctrl expression
for col in range(col_count):
input_index = joint_input_indices[col]
if self.dnaReader.getRawControlName(input_index) == control_name and joint_index == self.joint_name_list.index(joint_name):
update_value_list.append(row * col_count + col) this would collect the indices of the exact delta values from the joint group values matrix that are related to the given control and joint names (I think this is what you intended to implement with the above code).. the rest seems ok from a quick glance |
thank you! This was a huge help. The information you provided in this entire thread has really helped increase the understanding of how to work with the dna data in addition to the deep dive video. Much appreciated. |
I'm glad it helped! |
Hi,
I'm working with the dna calibration tools (thank you for these amazing additions to Metahumans).
Question:
I can get joint names using dnaReader.getJointName(num)
face control names using dnaReader.getGUIControlName(num)
I can get Group Indices connected to a control using dnaReader.getJointGroupJointIndices(index)
The joint indices returned by that command don't correspond to the index numbers from dnaReader.getJointName(num).
How can I get the joints names that go with the GroupJointIndices?
Thank you
The text was updated successfully, but these errors were encountered: