Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode.
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
Is the version of Python used within Cinema 4D R21 "built-in" to Cinema 4D, or can it be updated to a new version?
If it can, how is it done, and is there backwards compatibility risks with exiting plugins, scripts, etc?
@m_magalhaes
Hi Manuel,
Sorry for not making my last post clear, I wasn't requesting you to test my code as is it seems to work from my tests. I just wanted to see if I was combining the matrixes together correctly. Thanks for the help, consider this issue "Solved".
It looks like the code does what I need, though I'm still working to understand why it works. Below is a code snip of how I combined all of the joints three rotation values from the source joint and transferred it to the target joint as well as obtaining the new target rotation vector to set animation keyframes. Does this look correct?
# Rotation values from source joint (for code testing only). sourceYValue = 90 sourceXValue = -90 sourceZValue = 0 # Define a matrix rotation around the axis of the source joint rotation values mX = c4d.utils.MatrixRotX(c4d.utils.DegToRad(sourceXValue)) mY = c4d.utils.MatrixRotY(c4d.utils.DegToRad(sourceYValue)) mZ = c4d.utils.MatrixRotZ(c4d.utils.DegToRad(sourceZValue)) # Combine all source joint rotation maxtrixs into one. mTotalTargetRelitiveTransforms = mX * mY * mZ # We just want the rotation so we can reset the offset mTotalTargetRelitiveTransforms.off = c4d.Vector(0, 0, 0) # Get the target joint orginal matrix rotations. mTargetOrginalTransforms = targetJoint.GetMg() # Combine target joint orginal matrix with new relitive rotation matrix. newTargetMatrix = mTotalTargetRelitiveTransforms * mTargetOrginalTransforms # As we just want to keep the rotation, we "reset" the position with the # previous one. newTargetMatrix.off = mTargetOrginalTransforms.off # To be sure the scale remain to 1 we normalize the matrix newTargetMatrix.Normalize() # Set the target joint new rotations. doc.AddUndo(c4d.UNDOTYPE_CHANGE, targetJoint) targetJoint.SetMg(newTargetMatrix) # Use this vector to set animation keyframes. vNewAnimationValues = targetJoint.GetRelRot()
@m_magalhaes Hi Manuel,
Thanks for the same code, I try it this weekend.
I've spent the last couple of days studying Matrixes and playing with code. During my tests, I noticed the GetMg() function returned the rotation created by the parent shoulder joint being changed to 45 deg, where I can see why the order of operation is important. I found a bunch of sample code rotating objects with points, but noting on a joint that has no points.
Thanks again. Bruce.
Attached is two characters, a source character rigged in a T-Pose and target character rigged in a A-Pose. I animated the joints to show the challenge. I first rotate the shoulder of the target character shoulder so it's in the T-Pose like the source character. Then I rotate both characters forearm 66 deg in the H axis. You can see the poses don't match due to target orientation of the axis when rigged being different.
As far as my code, I'm doing pretty much the same as the Retarget tag except I'm reading the animation tracks of the source character and reading the vector values, and creating new animation track for the target character, which works fine if the both characters were originally rig using the same pose. But in this case, I'm adding 45 degs to the target character shoulder values which makes all child joints orientation of the axis different. So using the vector values are no longer correct.
T-Pose_A-Pose.c4d
I’ve run into a math challenge working on an animation re-targeting script. This Python script copies the bone rotational properties from one character rig to another (like the retarget tag) but also performs additional modifications and clean-up.
I'm using Cinema 4D R21.
Up to now, both characters were always rigged based on an “A-Pose”, but now the source characters can be based on a “T-Pose”. Simply adding 45 deg to the shoulder works fine, but every bone to the fingers center of rotation is now off by 45 deg. I’m struggling to find the math or hopefully a Cinema 4D Python functions that will enables me to calculate from the single axis rotation from the source rig, to the “multiple axis” rotations required for the target. This would be similar math used by Cinema 4D when rotation an object in “World Space”.
Example, if I have the source character in the T-Pose position and rotate the forearm “forward” 45 deg in the “H” axis only, the target character I first add 45 deg to the shoulder to the “B” axis making it in the T-Pose, then I need to apply multiple axis values close to (H = 35.264, P = -30, B = 9.736) to get the same orientation of the source character.
Source Character
Target Character
Any ideas? Bruce Kingsley
Does anyone know of Python code to both remove keyframe noise and also perform keyframe reduction somewhat like the timeline keyframe reduce function? I'm importing face capture FBX files produced by the Apple ARKit which contains multiple morphs with keyframes on every frame. Some keys have very small changes that produces a "vibration" look, or sudden changes "spikes" that I manually delete. Then I perform the keyframe reduce function on each morph not only to remove keys, but to create a nice smooth curve giving the animation a more fluid, natural look.
Another option is if anyone knows how (and if) the Cinema 4D keyframe reduce function can be called from Python.