1
1

Compare commits

...

3 Commits

Author SHA1 Message Date
14fdcbe000 Setting object position is propagated to the physics simulation even for dynmamic objects.
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
2018-10-19 10:08:59 +02:00
ad21793c69 Interactive mode: new scene.flag SCE_INTERACTIVE to update the depsgraph without frame change but running physics.
Interactive button added on time line.
2018-10-11 14:06:34 +02:00
b389f1e957 Fix bug with transformed object interfering with rigid body simulation.
Note: bug was caused by use of legacy ob->flag & SELECT. New OB_PHYS_MOVING
      flag to mark that an active object is being transformed.

Make active object position update independent of cache write in preparation
of interactive physics.
2018-10-10 18:13:34 +02:00
13 changed files with 97 additions and 36 deletions

View File

@@ -38,6 +38,8 @@ class TIME_HT_editor_buttons(Header):
layout.separator_spacer()
layout.prop(scene, "use_interactive_mode", text="", icon='GAME', toggle=True)
layout.prop(toolsettings, "use_keyframe_insert_auto", text="", toggle=True)
row = layout.row(align=True)

View File

@@ -1295,8 +1295,11 @@ static int ptcache_rigidbody_write(int index, void *rb_v, void **data, int UNUS
if (rbo->type == RBO_TYPE_ACTIVE) {
#ifdef WITH_BULLET
RB_body_get_position(rbo->shared->physics_object, rbo->pos);
RB_body_get_orientation(rbo->shared->physics_object, rbo->orn);
/* retrieving physics sim position should not be dependent on caching,
* moved to rigidbody_update_simulation_post_step()
*/
/*RB_body_get_position(rbo->shared->physics_object, rbo->pos);*/
/*RB_body_get_orientation(rbo->shared->physics_object, rbo->orn);*/
#endif
PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, rbo->pos);
PTCACHE_DATA_FROM(data, BPHYS_DATA_ROTATION, rbo->orn);

View File

@@ -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->flag & SELECT && G.moving & G_TRANSFORM_OBJ) {
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->flag & SELECT && G.moving & G_TRANSFORM_OBJ)) {
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,19 +1484,26 @@ static void rigidbody_update_simulation(Depsgraph *depsgraph, Scene *scene, Rigi
static void rigidbody_update_simulation_post_step(Depsgraph *depsgraph, RigidBodyWorld *rbw)
{
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
static float null_vel[3] = {0.f, 0.f, 0.f};
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, ob)
{
Base *base = BKE_view_layer_base_find(view_layer, ob);
RigidBodyOb *rbo = ob->rigidbody_object;
/* Reset kinematic state for transformed objects. */
if (rbo && base && (base->flag & BASE_SELECTED) && (G.moving & G_TRANSFORM_OBJ)) {
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));
/* 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);
if (rbo) {
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);
}
else if (rbo->type == RBO_TYPE_ACTIVE) {
RB_body_get_position(rbo->shared->physics_object, rbo->pos);
RB_body_get_orientation(rbo->shared->physics_object, rbo->orn);
}
}
}
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
@@ -1517,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->flag & SELECT && G.moving & G_TRANSFORM_OBJ)) {
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
@@ -1621,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;
@@ -1658,6 +1671,24 @@ void BKE_rigidbody_do_simulation(Depsgraph *depsgraph, Scene *scene, float ctime
PTCacheID pid;
int startframe, endframe;
if (scene->flag & SCE_INTERACTIVE) {
/* No caching when in interactive mode */
if (rbw->shared->physics_world == NULL)
return;
else if (rbw->objects == NULL)
rigidbody_update_ob_array(rbw);
rigidbody_update_simulation(depsgraph, scene, rbw, false);
/* TODO: get the actual time difference from previous step so that the physics simulation is real time */
timestep = 1.0f / (float)FPS * rbw->time_scale;
/* step simulation by the requested timestep, steps per second are adjusted to take time scale into account */
RB_dworld_step_simulation(rbw->shared->physics_world, timestep, INT_MAX, 1.0f / (float)rbw->steps_per_second * min_ff(rbw->time_scale, 1.0f));
rigidbody_update_simulation_post_step(depsgraph, rbw);
return;
}
BKE_ptcache_id_from_rigidbody(&pid, NULL, rbw);
BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL);
cache = rbw->shared->pointcache;

View File

@@ -3882,6 +3882,7 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
ScrArea *sa;
int sync;
float time;
int pfra = scene->r.cfra;
/* sync, don't sync, or follow scene setting */
if (sad->flag & ANIMPLAY_FLAG_SYNC) sync = 1;
@@ -3939,7 +3940,10 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
/* reset 'jumped' flag before checking if we need to jump... */
sad->flag &= ~ANIMPLAY_FLAG_JUMPED;
if (sad->flag & ANIMPLAY_FLAG_REVERSE) {
if (scene->flag & SCE_INTERACTIVE) {
/* TODO: remember what was the frame increment so that it can be used in physics simulation to stick to real time */
scene->r.cfra = pfra;
} else if (sad->flag & ANIMPLAY_FLAG_REVERSE) {
/* jump back to end? */
if (PRVRANGEON) {
if (scene->r.cfra < scene->r.psfra) {

View File

@@ -5650,7 +5650,8 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
/* 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)) {
/* remember that this object is moving to make it static in simulation */
ob->transflag |= OB_PHYS_MOVING;
/* save original object transform */
copy_v3_v3(td->ext->oloc, ob->loc);
@@ -6784,6 +6785,8 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
ListBase pidlist;
PTCacheID *pid;
ob = td->ob;
/* reset this temp flag when the transformation ends */
ob->transflag &= ~OB_PHYS_MOVING;
if (td->flag & TD_NOACTION)
break;

View File

@@ -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),
};

View File

@@ -419,6 +419,7 @@ enum {
OB_RENDER_DUPLI = 1 << 12,
OB_NO_CONSTRAINTS = 1 << 13, /* runtime constraints disable */
OB_NO_PSYS_UPDATE = 1 << 14, /* hack to work around particle issue */
OB_PHYS_MOVING = 1 << 15, /* hack to set object static when moving by transform */
OB_DUPLI = OB_DUPLIFRAMES | OB_DUPLIVERTS | OB_DUPLICOLLECTION | OB_DUPLIFACES | OB_DUPLIPARTS,
};

View File

@@ -1936,6 +1936,7 @@ typedef enum eVGroupSelect {
#define SCE_NLA_EDIT_ON (1<<2)
#define SCE_FRAME_DROP (1<<3)
#define SCE_KEYS_NO_SELONLY (1<<4)
#define SCE_INTERACTIVE (1<<5)
/* return flag BKE_scene_base_iter_next functions */
/* #define F_ERROR -1 */ /* UNUSED */

View File

@@ -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);

View File

@@ -6194,6 +6194,13 @@ void RNA_def_scene(BlenderRNA *brna)
"(in timeline and when jumping between keyframes)");
RNA_def_property_update(prop, NC_SCENE | ND_FRAME, NULL);
/* Timeline / Interactive mode */
prop = RNA_def_property(srna, "use_interactive_mode", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_INTERACTIVE);
RNA_def_property_ui_text(prop, "Run interactive mode for physics",
"The scene frame is no longer incrementing (and thus animation is stopped) but the physics engine still executes");
RNA_def_property_update(prop, NC_SCENE | ND_FRAME, NULL);
/* Stamp */
prop = RNA_def_property(srna, "use_stamp_note", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "r.stamp_udata");