Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2014-01-09 03:37:41 +0400
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2014-01-09 03:38:56 +0400
commita0dbee6e933bfb5d4722d33367fd8290cd301b4c (patch)
tree5add7bf3b75275c4a56ed4a7a5d9b4c7089416f1 /source/blender/blenkernel
parentaad731d51cdb77f81287300e7a81a00ffd05a38e (diff)
Fix T38016: setting Object.matrix_world does not take bone parents into account.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/intern/object.c135
1 files changed, 69 insertions, 66 deletions
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index c0520e5d1a9..4dccffec0e0 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -1921,36 +1921,6 @@ void BKE_object_tfm_protected_restore(Object *ob,
}
}
-/* see BKE_pchan_apply_mat4() for the equivalent 'pchan' function */
-void BKE_object_apply_mat4(Object *ob, float mat[4][4], const bool use_compat, const bool use_parent)
-{
- float rot[3][3];
-
- if (use_parent && ob->parent) {
- float rmat[4][4], diff_mat[4][4], imat[4][4];
- mul_m4_m4m4(diff_mat, ob->parent->obmat, ob->parentinv);
- invert_m4_m4(imat, diff_mat);
- mul_m4_m4m4(rmat, imat, mat); /* get the parent relative matrix */
- BKE_object_apply_mat4(ob, rmat, use_compat, FALSE);
-
- /* same as below, use rmat rather than mat */
- mat4_to_loc_rot_size(ob->loc, rot, ob->size, rmat);
- BKE_object_mat3_to_rot(ob, rot, use_compat);
- }
- else {
- mat4_to_loc_rot_size(ob->loc, rot, ob->size, mat);
- BKE_object_mat3_to_rot(ob, rot, use_compat);
- }
-
- sub_v3_v3(ob->loc, ob->dloc);
-
- if (ob->dscale[0] != 0.0f) ob->size[0] /= ob->dscale[0];
- if (ob->dscale[1] != 0.0f) ob->size[1] /= ob->dscale[1];
- if (ob->dscale[2] != 0.0f) ob->size[2] /= ob->dscale[2];
-
- /* BKE_object_mat3_to_rot handles delta rotations */
-}
-
void BKE_object_to_mat3(Object *ob, float mat[3][3]) /* no parent */
{
float smat[3][3];
@@ -2234,76 +2204,76 @@ static void ob_parvert3(Object *ob, Object *par, float mat[4][4])
}
}
-/**
- * \param r_originmat Optional matrix that stores the space the object is in (without its own matrix applied)
- */
-static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[4][4], float slowmat[4][4],
- float r_originmat[3][3], const bool simul)
+static void ob_get_parent_matrix(Scene *scene, Object *ob, Object *par, float parentmat[4][4])
{
- float totmat[4][4];
float tmat[4][4];
- float locmat[4][4];
float vec[3];
int ok;
-
- BKE_object_to_mat4(ob, locmat);
-
- if (ob->partype & PARSLOW) copy_m4_m4(slowmat, obmat);
switch (ob->partype & PARTYPE) {
case PAROBJECT:
ok = 0;
if (par->type == OB_CURVE) {
- if (((Curve *)par->data)->flag & CU_PATH) {
+ if (scene && ((Curve *)par->data)->flag & CU_PATH) {
ob_parcurve(scene, ob, par, tmat);
ok = 1;
}
}
- if (ok) mul_m4_m4m4(totmat, par->obmat, tmat);
- else copy_m4_m4(totmat, par->obmat);
+ if (ok) mul_m4_m4m4(parentmat, par->obmat, tmat);
+ else copy_m4_m4(parentmat, par->obmat);
break;
case PARBONE:
ob_parbone(ob, par, tmat);
- mul_m4_m4m4(totmat, par->obmat, tmat);
+ mul_m4_m4m4(parentmat, par->obmat, tmat);
break;
case PARVERT1:
- unit_m4(totmat);
- if (simul) {
- copy_v3_v3(totmat[3], par->obmat[3]);
- }
- else {
- give_parvert(par, ob->par1, vec);
- mul_v3_m4v3(totmat[3], par->obmat, vec);
- }
+ unit_m4(parentmat);
+ give_parvert(par, ob->par1, vec);
+ mul_v3_m4v3(parentmat[3], par->obmat, vec);
break;
case PARVERT3:
ob_parvert3(ob, par, tmat);
- mul_m4_m4m4(totmat, par->obmat, tmat);
+ mul_m4_m4m4(parentmat, par->obmat, tmat);
break;
case PARSKEL:
- copy_m4_m4(totmat, par->obmat);
+ copy_m4_m4(parentmat, par->obmat);
break;
}
+
+}
+
+/**
+ * \param r_originmat Optional matrix that stores the space the object is in (without its own matrix applied)
+ */
+static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[4][4], float slowmat[4][4],
+ float r_originmat[3][3], const bool set_origin)
+{
+ float totmat[4][4];
+ float tmat[4][4];
+ float locmat[4][4];
+
+ BKE_object_to_mat4(ob, locmat);
+
+ if (ob->partype & PARSLOW) copy_m4_m4(slowmat, obmat);
+
+ ob_get_parent_matrix(scene, ob, par, totmat);
/* total */
mul_m4_m4m4(tmat, totmat, ob->parentinv);
mul_m4_m4m4(obmat, tmat, locmat);
- if (simul) {
-
+ if (r_originmat) {
+ /* usable originmat */
+ copy_m3_m4(r_originmat, tmat);
}
- else {
- if (r_originmat) {
- /* usable originmat */
- copy_m3_m4(r_originmat, tmat);
- }
-
- /* origin, for help line */
+
+ /* origin, for help line */
+ if (set_origin) {
if ((ob->partype & PARTYPE) == PARSKEL) {
copy_v3_v3(ob->orig, par->obmat[3]);
}
@@ -2347,7 +2317,7 @@ void BKE_object_where_is_calc_time_ex(Scene *scene, Object *ob, float ctime,
float slowmat[4][4] = MAT4_UNITY;
/* calculate parent matrix */
- solve_parenting(scene, ob, par, ob->obmat, slowmat, r_originmat, false);
+ solve_parenting(scene, ob, par, ob->obmat, slowmat, r_originmat, true);
/* "slow parent" is definitely not threadsafe, and may also give bad results jumping around
* An old-fashioned hack which probably doesn't really cut it anymore
@@ -2395,7 +2365,7 @@ void BKE_object_where_is_calc_mat4(Scene *scene, Object *ob, float obmat[4][4])
if (ob->parent) {
Object *par = ob->parent;
- solve_parenting(scene, ob, par, obmat, slowmat, NULL, true);
+ solve_parenting(scene, ob, par, obmat, slowmat, NULL, false);
if (ob->partype & PARSLOW)
where_is_object_parslow(ob, obmat, slowmat);
@@ -2440,6 +2410,39 @@ void BKE_object_workob_calc_parent(Scene *scene, Object *ob, Object *workob)
BKE_object_where_is_calc(scene, workob);
}
+/* see BKE_pchan_apply_mat4() for the equivalent 'pchan' function */
+void BKE_object_apply_mat4(Object *ob, float mat[4][4], const bool use_compat, const bool use_parent)
+{
+ float rot[3][3];
+
+ if (use_parent && ob->parent) {
+ float rmat[4][4], diff_mat[4][4], imat[4][4], parent_mat[4][4];
+
+ ob_get_parent_matrix(NULL, ob, ob->parent, parent_mat);
+
+ mul_m4_m4m4(diff_mat, parent_mat, ob->parentinv);
+ invert_m4_m4(imat, diff_mat);
+ mul_m4_m4m4(rmat, imat, mat); /* get the parent relative matrix */
+ BKE_object_apply_mat4(ob, rmat, use_compat, FALSE);
+
+ /* same as below, use rmat rather than mat */
+ mat4_to_loc_rot_size(ob->loc, rot, ob->size, rmat);
+ BKE_object_mat3_to_rot(ob, rot, use_compat);
+ }
+ else {
+ mat4_to_loc_rot_size(ob->loc, rot, ob->size, mat);
+ BKE_object_mat3_to_rot(ob, rot, use_compat);
+ }
+
+ sub_v3_v3(ob->loc, ob->dloc);
+
+ if (ob->dscale[0] != 0.0f) ob->size[0] /= ob->dscale[0];
+ if (ob->dscale[1] != 0.0f) ob->size[1] /= ob->dscale[1];
+ if (ob->dscale[2] != 0.0f) ob->size[2] /= ob->dscale[2];
+
+ /* BKE_object_mat3_to_rot handles delta rotations */
+}
+
BoundBox *BKE_boundbox_alloc_unit(void)
{
BoundBox *bb;