Bugfix #21384: Bone Driven Shapekeys Child Evaluation Problem
Transform channel drivers for bones in 'localspace' was using the wrong matrix when getting the transforms. I had been assuming that pchan->chan_mat always contained only the matrix-ised transform values stored in the pchan (which is true while constraints are being evaluated, but not afterwards). Changes: - Added a new function to calculate this matrix instead of directly writing it on the pchan->chan_matrix field. - Also, made the normalisation of the quaternion values during this process be done on a temp var instead of on the stored value. This was a constant source of confusion in the past, so let's see if we can do without it now :) Unrelated to this commit, I've also fixed a compiler warning with previous commit that I missed (missing include).
This commit is contained in:
@@ -106,6 +106,7 @@ void armature_loc_pose_to_bone(struct bPoseChannel *pchan, float *inloc, float *
|
||||
void armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float arm_mat[][4]);
|
||||
|
||||
void pchan_apply_mat4(struct bPoseChannel *pchan, float mat[][4]);
|
||||
void pchan_to_mat4(struct bPoseChannel *pchan, float chan_mat[4][4]);
|
||||
|
||||
/* Rotation Mode Conversions - Used for PoseChannels + Objects... */
|
||||
void BKE_rotMode_change_values(float quat[4], float eul[3], float axis[3], float *angle, short oldMode, short newMode);
|
||||
|
||||
@@ -2130,44 +2130,59 @@ static void splineik_execute_tree(Scene *scene, Object *ob, bPoseChannel *pchan_
|
||||
|
||||
/* ********************** THE POSE SOLVER ******************* */
|
||||
|
||||
|
||||
/* loc/rot/size to mat4 */
|
||||
/* used in constraint.c too */
|
||||
void chan_calc_mat(bPoseChannel *chan)
|
||||
/* loc/rot/size to given mat4 */
|
||||
void pchan_to_mat4(bPoseChannel *pchan, float chan_mat[4][4])
|
||||
{
|
||||
float smat[3][3];
|
||||
float rmat[3][3];
|
||||
float tmat[3][3];
|
||||
|
||||
/* get scaling matrix */
|
||||
size_to_mat3( smat,chan->size);
|
||||
size_to_mat3(smat, pchan->size);
|
||||
|
||||
/* rotations may either be quats, eulers (with various rotation orders), or axis-angle */
|
||||
if (chan->rotmode > 0) {
|
||||
if (pchan->rotmode > 0) {
|
||||
/* euler rotations (will cause gimble lock, but this can be alleviated a bit with rotation orders) */
|
||||
eulO_to_mat3( rmat,chan->eul, chan->rotmode);
|
||||
eulO_to_mat3(rmat, pchan->eul, pchan->rotmode);
|
||||
}
|
||||
else if (chan->rotmode == ROT_MODE_AXISANGLE) {
|
||||
else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
|
||||
/* axis-angle - not really that great for 3D-changing orientations */
|
||||
axis_angle_to_mat3( rmat,chan->rotAxis, chan->rotAngle);
|
||||
axis_angle_to_mat3(rmat, pchan->rotAxis, pchan->rotAngle);
|
||||
}
|
||||
else {
|
||||
/* quats are normalised before use to eliminate scaling issues */
|
||||
normalize_qt(chan->quat); // TODO: do this with local vars only!
|
||||
quat_to_mat3( rmat,chan->quat);
|
||||
float quat[4];
|
||||
|
||||
/* NOTE: we now don't normalise the stored values anymore, since this was kindof evil in some cases
|
||||
* but if this proves to be too problematic, switch back to the old system of operating directly on
|
||||
* the stored copy
|
||||
*/
|
||||
QUATCOPY(quat, pchan->quat);
|
||||
normalize_qt(quat);
|
||||
quat_to_mat3(rmat, quat);
|
||||
}
|
||||
|
||||
/* calculate matrix of bone (as 3x3 matrix, but then copy the 4x4) */
|
||||
mul_m3_m3m3(tmat, rmat, smat);
|
||||
copy_m4_m3(chan->chan_mat, tmat);
|
||||
copy_m4_m3(chan_mat, tmat);
|
||||
|
||||
/* prevent action channels breaking chains */
|
||||
/* need to check for bone here, CONSTRAINT_TYPE_ACTION uses this call */
|
||||
if ((chan->bone==NULL) || !(chan->bone->flag & BONE_CONNECTED)) {
|
||||
VECCOPY(chan->chan_mat[3], chan->loc);
|
||||
if ((pchan->bone==NULL) || !(pchan->bone->flag & BONE_CONNECTED)) {
|
||||
VECCOPY(chan_mat[3], pchan->loc);
|
||||
}
|
||||
}
|
||||
|
||||
/* loc/rot/size to mat4 */
|
||||
/* used in constraint.c too */
|
||||
void chan_calc_mat(bPoseChannel *pchan)
|
||||
{
|
||||
/* this is just a wrapper around the copy of this function which calculates the matrix
|
||||
* and stores the result in any given channel
|
||||
*/
|
||||
pchan_to_mat4(pchan, pchan->chan_mat);
|
||||
}
|
||||
|
||||
/* NLA strip modifiers */
|
||||
static void do_strip_modifiers(Scene *scene, Object *armob, Bone *bone, bPoseChannel *pchan)
|
||||
{
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
#include "BKE_fcurve.h"
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_action.h"
|
||||
|
||||
#include "BKE_armature.h"
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_idprop.h"
|
||||
@@ -1041,8 +1041,12 @@ static float dvar_eval_transChan (ChannelDriver *driver, DriverVar *dvar)
|
||||
useEulers = 1;
|
||||
}
|
||||
|
||||
if (dtar->flag & DTAR_FLAG_LOCALSPACE)
|
||||
copy_m4_m4(mat, pchan->chan_mat);
|
||||
if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
|
||||
/* specially calculate local matrix, since chan_mat is not valid
|
||||
* since it stores delta transform of pose_mat so that deforms work
|
||||
*/
|
||||
pchan_to_mat4(pchan, mat);
|
||||
}
|
||||
else
|
||||
mul_m4_m4m4(mat, pchan->pose_mat, ob->obmat);
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_sequence_types.h"
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_sequencer.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
Reference in New Issue
Block a user