diff options
author | Benoit Bolsee <benoit.bolsee@online.be> | 2018-10-19 11:08:59 +0300 |
---|---|---|
committer | Benoit Bolsee <benoit.bolsee@online.be> | 2018-10-19 11:08:59 +0300 |
commit | 14fdcbe0009e62d2b748f5de55db5ea1d360705c (patch) | |
tree | 8a368e604124e6e433c5d08bd02e58fabff6e68b | |
parent | ad21793c69429dea4489603a77b95ac733966bcc (diff) |
Setting object position is propagated to the physics simulation even for dynmamic objects.interactive_physics
The velocity is also reset to 0, which makes sense after forcing a dynamic object position.
Known issues:
- in interactive mode, changing an object position by rna causes a simulation step
- setting any part of the object position or orientation causes the full matrix to be applied to physics => missing true rigid body API
-rw-r--r-- | source/blender/blenkernel/intern/rigidbody.c | 18 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_ID.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_object.c | 43 |
3 files changed, 41 insertions, 22 deletions
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index 737359aae93..bd2d3d65244 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -1313,13 +1313,13 @@ static void rigidbody_update_sim_ob(Depsgraph *depsgraph, Scene *scene, RigidBod RB_shape_set_margin(rbo->shared->physics_shape, RBO_GET_MARGIN(rbo) * MIN3(scale[0], scale[1], scale[2])); /* make transformed objects temporarily kinmatic so that they can be moved by the user during simulation */ - if (ob->transflag & OB_PHYS_MOVING) { + if ((ob->transflag & OB_PHYS_MOVING) || (ob->id.recalc & ID_RECALC_PHYS)) { RB_body_set_kinematic_state(rbo->shared->physics_object, true); RB_body_set_mass(rbo->shared->physics_object, 0.0f); } /* update rigid body location and rotation for kinematic bodies */ - if (rbo->flag & RBO_FLAG_KINEMATIC || (ob->transflag & OB_PHYS_MOVING)) { + if (rbo->flag & RBO_FLAG_KINEMATIC || (ob->transflag & OB_PHYS_MOVING) || (ob->id.recalc & ID_RECALC_PHYS)) { RB_body_activate(rbo->shared->physics_object); RB_body_set_loc_rot(rbo->shared->physics_object, loc, rot); } @@ -1484,14 +1484,18 @@ static void rigidbody_update_simulation(Depsgraph *depsgraph, Scene *scene, Rigi static void rigidbody_update_simulation_post_step(Depsgraph *depsgraph, RigidBodyWorld *rbw) { + static float null_vel[3] = {0.f, 0.f, 0.f}; + FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, ob) { RigidBodyOb *rbo = ob->rigidbody_object; /* Reset kinematic state for transformed objects. */ if (rbo) { - if (ob->transflag & OB_PHYS_MOVING) { + if ((ob->transflag & OB_PHYS_MOVING) || (ob->id.recalc & ID_RECALC_PHYS)) { RB_body_set_kinematic_state(rbo->shared->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED); RB_body_set_mass(rbo->shared->physics_object, RBO_GET_MASS(rbo)); + RB_body_set_linear_velocity(rbo->shared->physics_object, null_vel); + RB_body_set_angular_velocity(rbo->shared->physics_object, null_vel); /* Deactivate passive objects so they don't interfere with deactivation of active objects. */ if (rbo->type == RBO_TYPE_PASSIVE) RB_body_deactivate(rbo->shared->physics_object); @@ -1520,7 +1524,7 @@ 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 (BKE_rigidbody_check_sim_running(rbw, ctime) && !(ob->transflag & OB_PHYS_MOVING)) { + if (BKE_rigidbody_check_sim_running(rbw, ctime) && !(ob->transflag & OB_PHYS_MOVING) && !(ob->id.recalc & ID_RECALC_PHYS)) { float mat[4][4], size_mat[4][4], size[3]; normalize_qt(rbo->orn); // RB_TODO investigate why quaternion isn't normalized at this point @@ -1624,6 +1628,12 @@ void BKE_rigidbody_rebuild_world(Depsgraph *depsgraph, Scene *scene, float ctime PTCacheID pid; int startframe, endframe; + if (scene->flag & SCE_INTERACTIVE) { + if (rbw->shared->physics_world == NULL) + rigidbody_update_simulation(depsgraph, scene, rbw, true); + return; + } + BKE_ptcache_id_from_rigidbody(&pid, NULL, rbw); BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL); cache = rbw->shared->pointcache; diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 9e5e822c4d5..2f802eaba2a 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -515,6 +515,8 @@ enum { ID_RECALC_GEOMETRY = 1 << 4, ID_RECALC_TRANSFORM = 1 << 5, ID_RECALC_COPY_ON_WRITE = 1 << 6, + /* copy object matrix to physics simulation */ + ID_RECALC_PHYS = 1 << 7, /* Special flag to check if SOMETHING was changed. */ ID_RECALC_ALL = (~(int)0), }; diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 16fbec0baa5..661138fe523 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -239,6 +239,13 @@ static void rna_Object_internal_update(Main *UNUSED(bmain), Scene *UNUSED(scene) DEG_id_tag_update(ptr->id.data, OB_RECALC_OB); } +static void rna_Object_internal_transform_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + DEG_id_tag_update(ptr->id.data, OB_RECALC_OB); + /* propagate new object position to physics simulation */ + ((ID *)ptr->id.data)->recalc |= ID_RECALC_PHYS; +} + static void rna_Object_internal_update_draw(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { DEG_id_tag_update(ptr->id.data, OB_RECALC_OB); @@ -249,7 +256,7 @@ static void rna_Object_matrix_world_update(Main *bmain, Scene *scene, PointerRNA { /* don't use compat so we get predictable rotation */ BKE_object_apply_mat4(ptr->id.data, ((Object *)ptr->id.data)->obmat, false, true); - rna_Object_internal_update(bmain, scene, ptr); + rna_Object_internal_transform_update(bmain, scene, ptr); } static void rna_Object_hide_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) @@ -2251,7 +2258,7 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC); RNA_def_property_ui_text(prop, "Location", "Location of the object"); RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); - RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update"); + RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_transform_update"); prop = RNA_def_property(srna, "rotation_quaternion", PROP_FLOAT, PROP_QUATERNION); RNA_def_property_float_sdna(prop, NULL, "quat"); @@ -2259,7 +2266,7 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC); RNA_def_property_float_array_default(prop, default_quat); RNA_def_property_ui_text(prop, "Quaternion Rotation", "Rotation in Quaternions"); - RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update"); + RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_transform_update"); /* XXX: for axis-angle, it would have been nice to have 2 separate fields for UI purposes, but * having a single one is better for Keyframing and other property-management situations... @@ -2272,21 +2279,21 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_float_array_default(prop, default_axisAngle); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC); RNA_def_property_ui_text(prop, "Axis-Angle Rotation", "Angle of Rotation for Axis-Angle rotation representation"); - RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update"); + RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_transform_update"); prop = RNA_def_property(srna, "rotation_euler", PROP_FLOAT, PROP_EULER); RNA_def_property_float_sdna(prop, NULL, "rot"); RNA_def_property_editable_array_func(prop, "rna_Object_rotation_euler_editable"); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC); RNA_def_property_ui_text(prop, "Euler Rotation", "Rotation in Eulers"); - RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update"); + RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_transform_update"); prop = RNA_def_property(srna, "rotation_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "rotmode"); RNA_def_property_enum_items(prop, prop_rotmode_items); /* XXX move to using a single define of this someday */ RNA_def_property_enum_funcs(prop, NULL, "rna_Object_rotation_mode_set", NULL); RNA_def_property_ui_text(prop, "Rotation Mode", ""); - RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update"); + RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_transform_update"); prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ); RNA_def_property_float_sdna(prop, NULL, "size"); @@ -2296,7 +2303,7 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 3); RNA_def_property_float_array_default(prop, default_scale); RNA_def_property_ui_text(prop, "Scale", "Scaling of the object"); - RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update"); + RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_transform_update"); prop = RNA_def_property(srna, "dimensions", PROP_FLOAT, PROP_XYZ_LENGTH); RNA_def_property_array(prop, 3); @@ -2305,7 +2312,7 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_float_funcs(prop, "rna_Object_dimensions_get", "rna_Object_dimensions_set", NULL); RNA_def_property_ui_range(prop, 0.0f, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_ui_text(prop, "Dimensions", "Absolute bounding box dimensions of the object"); - RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update"); + RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_transform_update"); /* delta transforms */ @@ -2313,20 +2320,20 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "dloc"); RNA_def_property_ui_text(prop, "Delta Location", "Extra translation added to the location of the object"); RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); - RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update"); + RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_transform_update"); prop = RNA_def_property(srna, "delta_rotation_euler", PROP_FLOAT, PROP_EULER); RNA_def_property_float_sdna(prop, NULL, "drot"); RNA_def_property_ui_text(prop, "Delta Rotation (Euler)", "Extra rotation added to the rotation of the object (when using Euler rotations)"); - RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update"); + RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_transform_update"); prop = RNA_def_property(srna, "delta_rotation_quaternion", PROP_FLOAT, PROP_QUATERNION); RNA_def_property_float_sdna(prop, NULL, "dquat"); RNA_def_property_float_array_default(prop, default_quat); RNA_def_property_ui_text(prop, "Delta Rotation (Quaternion)", "Extra rotation added to the rotation of the object (when using Quaternion rotations)"); - RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update"); + RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_transform_update"); #if 0 /* XXX not supported well yet... */ prop = RNA_def_property(srna, "delta_rotation_axis_angle", PROP_FLOAT, PROP_AXISANGLE); @@ -2335,7 +2342,7 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_float_array_default(prop, default_axisAngle); RNA_def_property_ui_text(prop, "Delta Rotation (Axis Angle)", "Extra rotation added to the rotation of the object (when using Axis-Angle rotations)"); - RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update"); + RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_transform_update"); #endif prop = RNA_def_property(srna, "delta_scale", PROP_FLOAT, PROP_XYZ); @@ -2344,7 +2351,7 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 3); RNA_def_property_float_array_default(prop, default_scale); RNA_def_property_ui_text(prop, "Delta Scale", "Extra scaling added to the scale of the object"); - RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update"); + RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_transform_update"); /* transform locks */ prop = RNA_def_property(srna, "lock_location", PROP_BOOLEAN, PROP_NONE); @@ -2352,14 +2359,14 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Lock Location", "Lock editing of location in the interface"); RNA_def_property_ui_icon(prop, ICON_UNLOCKED, 1); - RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update"); + RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_transform_update"); prop = RNA_def_property(srna, "lock_rotation", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_ROTX); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Lock Rotation", "Lock editing of rotation in the interface"); RNA_def_property_ui_icon(prop, ICON_UNLOCKED, 1); - RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update"); + RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_transform_update"); /* XXX this is sub-optimal - it really should be included above, * but due to technical reasons we can't do this! */ @@ -2379,7 +2386,7 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Lock Scale", "Lock editing of scale in the interface"); RNA_def_property_ui_icon(prop, ICON_UNLOCKED, 1); - RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update"); + RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_transform_update"); /* matrix */ prop = RNA_def_property(srna, "matrix_world", PROP_FLOAT, PROP_MATRIX); @@ -2405,14 +2412,14 @@ static void rna_def_object(BlenderRNA *brna) "Matrix access to location, rotation and scale (including deltas), " "before constraints and parenting are applied"); RNA_def_property_float_funcs(prop, "rna_Object_matrix_basis_get", "rna_Object_matrix_basis_set", NULL); - RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update"); + RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_transform_update"); /*parent_inverse*/ prop = RNA_def_property(srna, "matrix_parent_inverse", PROP_FLOAT, PROP_MATRIX); RNA_def_property_float_sdna(prop, NULL, "parentinv"); RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4); RNA_def_property_ui_text(prop, "Matrix", "Inverse of object's parent matrix at time of parenting"); - RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update"); + RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_transform_update"); /* modifiers */ prop = RNA_def_property(srna, "modifiers", PROP_COLLECTION, PROP_NONE); |