diff options
author | Sergej Reich <sergej.reich@googlemail.com> | 2013-04-07 18:09:29 +0400 |
---|---|---|
committer | Sergej Reich <sergej.reich@googlemail.com> | 2013-04-07 18:09:29 +0400 |
commit | 42e8f3e88971a320c4204d5386f740b23b4ecf16 (patch) | |
tree | 6d169ddb87c435b5989bbc38daf2d91d11d084b4 /source | |
parent | fd6a96216819f14763e4b6c8ab33ec58fead5bd2 (diff) |
rigidbody: Fix/workaround for transforming rigid bodies with parents
Since we use the rigid body transform when transforming rigid bodies
things like parents and constraints add an offset because rigid body
transforms are in global space.
Now we just don't take rigid body transform into account on simulation
start frame so there are no problems when doing the initial setup.
The problem still exists when simulation is running of course.
To properly fix this we'd have to solve parenting and constratins while
taking rigid bodies into account before and after transform.
We'll have to see if it's really needed, would like to avoid it though.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_rigidbody.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/rigidbody.c | 13 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_conversions.c | 40 |
3 files changed, 33 insertions, 21 deletions
diff --git a/source/blender/blenkernel/BKE_rigidbody.h b/source/blender/blenkernel/BKE_rigidbody.h index bab961bcbd2..75647876419 100644 --- a/source/blender/blenkernel/BKE_rigidbody.h +++ b/source/blender/blenkernel/BKE_rigidbody.h @@ -90,6 +90,7 @@ void BKE_rigidbody_remove_constraint(struct Scene *scene, struct Object *ob); void BKE_rigidbody_aftertrans_update(struct Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle); void BKE_rigidbody_sync_transforms(struct RigidBodyWorld *rbw, struct Object *ob, float ctime); +bool BKE_rigidbody_check_sim_running(struct RigidBodyWorld *rbw, float ctime); void BKE_rigidbody_cache_reset(struct RigidBodyWorld *rbw); void BKE_rigidbody_rebuild_world(struct Scene *scene, float ctime); void BKE_rigidbody_do_simulation(struct Scene *scene, float ctime); diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index eaf385fbfcf..ca7bb542598 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -1148,6 +1148,12 @@ static void rigidbody_update_simulation_post_step(RigidBodyWorld *rbw) } } } + +bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime) +{ + return (rbw && (rbw->flag & RBW_FLAG_MUTED) == 0 && ctime > rbw->pointcache->startframe); +} + /* Sync rigid body and object transformations */ void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) { @@ -1158,13 +1164,9 @@ void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) return; /* use rigid body transform after cache start frame if objects is not being transformed */ - if (ctime > rbw->pointcache->startframe && !(ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ)) { + if (BKE_rigidbody_check_sim_running(rbw, ctime) && !(ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ)) { float mat[4][4], size_mat[4][4], size[3]; - /* keep original transform when the simulation is muted */ - if (rbw->flag & RBW_FLAG_MUTED) - return; - normalize_qt(rbo->orn); // RB_TODO investigate why quaternion isn't normalized at this point quat_to_mat4(mat, rbo->orn); copy_v3_v3(mat[3], rbo->pos); @@ -1337,6 +1339,7 @@ void BKE_rigidbody_remove_object(Scene *scene, Object *ob) {} void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob) {} void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) {} void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle) {} +bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime) { return false; } void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw) {} void BKE_rigidbody_rebuild_world(Scene *scene, float ctime) {} void BKE_rigidbody_do_simulation(Scene *scene, float ctime) {} diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 820a343497c..f711dd1d438 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -4596,23 +4596,28 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) if (t->mode != TFM_DUMMY && ob->rigidbody_object) { float rot[3][3], scale[3]; + float ctime = BKE_scene_frame_get(scene); - /* save original object transform */ - copy_v3_v3(td->ext->oloc, ob->loc); + /* only use rigid body transform if simulation is running, avoids problems with initial setup of rigid bodies */ + if (BKE_rigidbody_check_sim_running(scene->rigidbody_world, ctime)) { - if (ob->rotmode > 0) { - copy_v3_v3(td->ext->orot, ob->rot); - } - else if (ob->rotmode == ROT_MODE_AXISANGLE) { - td->ext->orotAngle = ob->rotAngle; - copy_v3_v3(td->ext->orotAxis, ob->rotAxis); - } - else { - copy_qt_qt(td->ext->oquat, ob->quat); + /* save original object transform */ + copy_v3_v3(td->ext->oloc, ob->loc); + + if (ob->rotmode > 0) { + copy_v3_v3(td->ext->orot, ob->rot); + } + else if (ob->rotmode == ROT_MODE_AXISANGLE) { + td->ext->orotAngle = ob->rotAngle; + copy_v3_v3(td->ext->orotAxis, ob->rotAxis); + } + else { + copy_qt_qt(td->ext->oquat, ob->quat); + } + /* update object's loc/rot to get current rigid body transform */ + mat4_to_loc_rot_size(ob->loc, rot, scale, ob->obmat); + BKE_object_mat3_to_rot(ob, rot, FALSE); } - /* update object's loc/rot to get current rigid body transform */ - mat4_to_loc_rot_size(ob->loc, rot, scale, ob->obmat); - BKE_object_mat3_to_rot(ob, rot, FALSE); } /* axismtx has the real orientation */ @@ -5571,8 +5576,11 @@ void special_aftertrans_update(bContext *C, TransInfo *t) recalcObPaths = 1; } /* restore rigid body transform */ - if (ob->rigidbody_object && canceled) - BKE_rigidbody_aftertrans_update(ob, td->ext->oloc, td->ext->orot, td->ext->oquat, td->ext->orotAxis, td->ext->orotAngle); + if (ob->rigidbody_object && canceled) { + float ctime = BKE_scene_frame_get(t->scene); + if (BKE_rigidbody_check_sim_running(t->scene->rigidbody_world, ctime)) + BKE_rigidbody_aftertrans_update(ob, td->ext->oloc, td->ext->orot, td->ext->oquat, td->ext->orotAxis, td->ext->orotAngle); + } } /* recalculate motion paths for objects (if necessary) |