Bugfix:
authorJoshua Leung <aligorith@gmail.com>
Thu, 24 Mar 2011 23:34:43 +0000 (23:34 +0000)
committerJoshua Leung <aligorith@gmail.com>
Thu, 24 Mar 2011 23:34:43 +0000 (23:34 +0000)
[#25725] Transform bone constraint & 'local with parent' as owners
space
[#26014] ChildOf Bone Constrain (influence) works in wrong workspace

Moved the influence calculation stuff outside of the space conversions
(i.e. so that it is done in worldspace only) fixes these problems,
which seem to arise when a constraint doesn't work in worldspace AND
doesn't need to apply inverse correct for this space conversion when
it's done, hence resulting in mismatch between spaces for old and new
matrices resulting in all the weird behaviour.

Patch to fix this from Jahka. Cheers!

source/blender/blenkernel/intern/constraint.c

index ba5b7e3ae4ad292c1f4d073d69aa896785b2d9d0..9f646a93b6aa7ecab9f71732006aa9761bbe98ff 100644 (file)
@@ -4465,9 +4465,11 @@ void solve_constraints (ListBase *conlist, bConstraintOb *cob, float ctime)
                 */
                enf = con->enforce;
                
+               /* make copy of worldspace matrix pre-constraint for use with blending later */
+               copy_m4_m4(oldmat, cob->matrix);
+               
                /* move owner matrix into right space */
                constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, CONSTRAINT_SPACE_WORLD, con->ownspace);
-               copy_m4_m4(oldmat, cob->matrix);
                
                /* prepare targets for constraint solving */
                if (cti->get_constraint_targets) {
@@ -4503,16 +4505,20 @@ void solve_constraints (ListBase *conlist, bConstraintOb *cob, float ctime)
                        cti->flush_constraint_targets(con, &targets, 1);
                }
                
-               /* Interpolate the enforcement, to blend result of constraint into final owner transform */
+               /* move owner back into worldspace for next constraint/other business */
+               if ((con->flag & CONSTRAINT_SPACEONCE) == 0) 
+                       constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, con->ownspace, CONSTRAINT_SPACE_WORLD);
+                       
+               /* Interpolate the enforcement, to blend result of constraint into final owner transform 
+                *      - all this happens in worldspace to prevent any weirdness creeping in ([#26014] and [#25725]),
+                *        since some constraints may not convert the solution back to the input space before blending
+                *        but all are guaranteed to end up in good "worldspace" result
+                */
                /* Note: all kind of stuff here before (caused trouble), much easier to just interpolate, or did I miss something? -jahka */
                if (enf < 1.0) {
                        float solution[4][4];
                        copy_m4_m4(solution, cob->matrix);
                        blend_m4_m4m4(cob->matrix, oldmat, solution, enf);
                }
-               
-               /* move owner back into worldspace for next constraint/other business */
-               if ((con->flag & CONSTRAINT_SPACEONCE) == 0) 
-                       constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, con->ownspace, CONSTRAINT_SPACE_WORLD);
        }
 }