rigidbody: Add generic spring constraint

Behaves like the generic constraint but has optional spring on each axis.

TODO: Add option to set rest length.

Patch by Markus Kasten (markus111), thanks!
This commit is contained in:
Sergej Reich 2013-01-23 05:57:01 +00:00
parent 47c96081d0
commit c48238fac6
4 changed files with 167 additions and 1 deletions

@ -206,6 +206,7 @@ class ConnectRigidBodies(Operator):
('SLIDER', "Slider", "Restricts rigid boddy translation to one axis"), ('SLIDER', "Slider", "Restricts rigid boddy translation to one axis"),
('PISTON', "Piston", "Restricts rigid boddy translation and rotation to one axis"), ('PISTON', "Piston", "Restricts rigid boddy translation and rotation to one axis"),
('GENERIC', "Generic", "Restricts translation and rotation to specified axes"), ('GENERIC', "Generic", "Restricts translation and rotation to specified axes"),
('GENERIC_SPRING', "Generic Spring", "Restricts translation and rotation to specified axes with springs")),
default='FIXED',) default='FIXED',)
pivot_type = EnumProperty( pivot_type = EnumProperty(

@ -569,7 +569,25 @@ void BKE_rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, shor
} }
RB_constraint_set_limits_piston(rbc->physics_constraint, lin_lower, lin_upper, ang_lower, ang_upper); RB_constraint_set_limits_piston(rbc->physics_constraint, lin_lower, lin_upper, ang_lower, ang_upper);
break; break;
case RBC_TYPE_6DOF_SPRING:
rbc->physics_constraint = RB_constraint_new_6dof_spring(loc, rot, rb1, rb2);
RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->flag & RBC_FLAG_USE_SPRING_X);
RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_stiffness_x);
RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_damping_x);
RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->flag & RBC_FLAG_USE_SPRING_Y);
RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->spring_stiffness_y);
RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->spring_damping_y);
RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->flag & RBC_FLAG_USE_SPRING_Z);
RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_stiffness_z);
RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_damping_z);
RB_constraint_set_equilibrium_6dof_spring(rbc->physics_constraint);
/* fall through */
case RBC_TYPE_6DOF: case RBC_TYPE_6DOF:
if (rbc->type == RBC_TYPE_6DOF) /* a litte awkward but avoids duplicate code for limits */
rbc->physics_constraint = RB_constraint_new_6dof(loc, rot, rb1, rb2); rbc->physics_constraint = RB_constraint_new_6dof(loc, rot, rb1, rb2);
if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_X) if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_X)
@ -775,6 +793,13 @@ RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short ty
rbc->limit_ang_z_lower = -M_PI_4; rbc->limit_ang_z_lower = -M_PI_4;
rbc->limit_ang_z_upper = M_PI_4; rbc->limit_ang_z_upper = M_PI_4;
rbc->spring_damping_x = 0.5f;
rbc->spring_damping_y = 0.5f;
rbc->spring_damping_z = 0.5f;
rbc->spring_stiffness_x = 10.0f;
rbc->spring_stiffness_y = 10.0f;
rbc->spring_stiffness_z = 10.0f;
/* flag cache as outdated */ /* flag cache as outdated */
BKE_rigidbody_cache_reset(rbw); BKE_rigidbody_cache_reset(rbw);

@ -207,6 +207,15 @@ typedef struct RigidBodyCon {
float limit_ang_z_lower; /* lower limit for z axis rotation */ float limit_ang_z_lower; /* lower limit for z axis rotation */
float limit_ang_z_upper; /* upper limit for z axis rotation */ float limit_ang_z_upper; /* upper limit for z axis rotation */
/* spring settings */
/* RB_TODO document spring properties */
float spring_stiffness_x;
float spring_stiffness_y;
float spring_stiffness_z;
float spring_damping_x;
float spring_damping_y;
float spring_damping_z;
/* References to Physics Sim object. Exist at runtime only */ /* References to Physics Sim object. Exist at runtime only */
void *physics_constraint; /* Physics object representation (i.e. btTypedConstraint) */ void *physics_constraint; /* Physics object representation (i.e. btTypedConstraint) */
} RigidBodyCon; } RigidBodyCon;
@ -257,6 +266,10 @@ typedef enum eRigidBodyCon_Flag {
RBC_FLAG_USE_LIMIT_ANG_X = (1<<8), RBC_FLAG_USE_LIMIT_ANG_X = (1<<8),
RBC_FLAG_USE_LIMIT_ANG_Y = (1<<9), RBC_FLAG_USE_LIMIT_ANG_Y = (1<<9),
RBC_FLAG_USE_LIMIT_ANG_Z = (1<<10), RBC_FLAG_USE_LIMIT_ANG_Z = (1<<10),
/* springs */
RBC_FLAG_USE_SPRING_X = (1<<11),
RBC_FLAG_USE_SPRING_Y = (1<<12),
RBC_FLAG_USE_SPRING_Z = (1<<13)
} eRigidBodyCon_Flag; } eRigidBodyCon_Flag;
/* ******************************** */ /* ******************************** */

@ -67,6 +67,7 @@ EnumPropertyItem rigidbody_con_type_items[] = {
{RBC_TYPE_SLIDER, "SLIDER", ICON_FORCE_FORCE, "Slider", "Restricts rigid boddy translation to one axis"}, {RBC_TYPE_SLIDER, "SLIDER", ICON_FORCE_FORCE, "Slider", "Restricts rigid boddy translation to one axis"},
{RBC_TYPE_PISTON, "PISTON", ICON_FORCE_FORCE, "Piston", "Restricts rigid boddy translation and rotation to one axis"}, {RBC_TYPE_PISTON, "PISTON", ICON_FORCE_FORCE, "Piston", "Restricts rigid boddy translation and rotation to one axis"},
{RBC_TYPE_6DOF, "GENERIC", ICON_FORCE_FORCE, "Generic", "Restricts translation and rotation to specified axes"}, {RBC_TYPE_6DOF, "GENERIC", ICON_FORCE_FORCE, "Generic", "Restricts translation and rotation to specified axes"},
{RBC_TYPE_6DOF_SPRING, "GENERIC_SPRING", ICON_FORCE_FORCE, "Generic Spring", "Restricts translation and rotation to specified axes with springs"},
{0, NULL, 0, NULL, NULL}}; {0, NULL, 0, NULL, NULL}};
@ -381,6 +382,66 @@ static void rna_RigidBodyCon_num_solver_iterations_set(PointerRNA *ptr, int valu
RB_constraint_set_solver_iterations(rbc->physics_constraint, value); RB_constraint_set_solver_iterations(rbc->physics_constraint, value);
} }
static void rna_RigidBodyCon_spring_stiffness_x_set(PointerRNA *ptr, float value)
{
RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
rbc->spring_stiffness_x = value;
if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_X))
RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, value);
}
static void rna_RigidBodyCon_spring_stiffness_y_set(PointerRNA *ptr, float value)
{
RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
rbc->spring_stiffness_y = value;
if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_Y))
RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, value);
}
static void rna_RigidBodyCon_spring_stiffness_z_set(PointerRNA *ptr, float value)
{
RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
rbc->spring_stiffness_z = value;
if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_Z))
RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, value);
}
static void rna_RigidBodyCon_spring_damping_x_set(PointerRNA *ptr, float value)
{
RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
rbc->spring_damping_x = value;
if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_X))
RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, value);
}
static void rna_RigidBodyCon_spring_damping_y_set(PointerRNA *ptr, float value)
{
RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
rbc->spring_damping_y = value;
if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_Y))
RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, value);
}
static void rna_RigidBodyCon_spring_damping_z_set(PointerRNA *ptr, float value)
{
RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
rbc->spring_damping_z = value;
if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_Z))
RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, value);
}
#else #else
static void rna_def_rigidbody_world(BlenderRNA *brna) static void rna_def_rigidbody_world(BlenderRNA *brna)
@ -710,6 +771,21 @@ static void rna_def_rigidbody_constraint(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Z Angle", "Limits rotation around z axis"); RNA_def_property_ui_text(prop, "Z Angle", "Limits rotation around z axis");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset"); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
prop = RNA_def_property(srna, "use_spring_x", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_SPRING_X);
RNA_def_property_ui_text(prop, "X Spring", "Enables spring on X axis");
RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
prop = RNA_def_property(srna, "use_spring_y", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_SPRING_Y);
RNA_def_property_ui_text(prop, "Y Spring", "Enables spring on Y axis");
RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
prop = RNA_def_property(srna, "use_spring_z", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_SPRING_Z);
RNA_def_property_ui_text(prop, "Z Spring", "Enables spring on Z axis");
RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
prop = RNA_def_property(srna, "limit_lin_x_lower", PROP_FLOAT, PROP_UNIT_LENGTH); prop = RNA_def_property(srna, "limit_lin_x_lower", PROP_FLOAT, PROP_UNIT_LENGTH);
RNA_def_property_float_sdna(prop, NULL, "limit_lin_x_lower"); RNA_def_property_float_sdna(prop, NULL, "limit_lin_x_lower");
RNA_def_property_float_default(prop, -1.0f); RNA_def_property_float_default(prop, -1.0f);
@ -787,6 +863,57 @@ static void rna_def_rigidbody_constraint(BlenderRNA *brna)
RNA_def_property_float_default(prop, M_PI_4); RNA_def_property_float_default(prop, M_PI_4);
RNA_def_property_ui_text(prop, "Upper Z Angle Limit", "Upper limit of z axis rotation"); RNA_def_property_ui_text(prop, "Upper Z Angle Limit", "Upper limit of z axis rotation");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset"); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_RigidBodyOb_reset");
prop = RNA_def_property(srna, "spring_stiffness_x", PROP_FLOAT, PROP_UNIT_LENGTH);
RNA_def_property_float_sdna(prop, NULL, "spring_stiffness_x");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, 3);
RNA_def_property_float_default(prop, 10.0f);
RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_stiffness_x_set", NULL);
RNA_def_property_ui_text(prop, "X Axis Stiffness", "Stiffness on the X axis");
RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
prop = RNA_def_property(srna, "spring_stiffness_y", PROP_FLOAT, PROP_UNIT_LENGTH);
RNA_def_property_float_sdna(prop, NULL, "spring_stiffness_y");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, 3);
RNA_def_property_float_default(prop, 10.0f);
RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_stiffness_y_set", NULL);
RNA_def_property_ui_text(prop, "Y Axis Stiffness", "Stiffness on the Y axis");
RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
prop = RNA_def_property(srna, "spring_stiffness_z", PROP_FLOAT, PROP_UNIT_LENGTH);
RNA_def_property_float_sdna(prop, NULL, "spring_stiffness_z");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, 3);
RNA_def_property_float_default(prop, 10.0f);
RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_stiffness_z_set", NULL);
RNA_def_property_ui_text(prop, "Z Axis Stiffness", "Stiffness on the Z axis");
RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
prop = RNA_def_property(srna, "spring_damping_x", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "spring_damping_x");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_float_default(prop, 0.5f);
RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_damping_x_set", NULL);
RNA_def_property_ui_text(prop, "Damping X", "Damping on the X axis");
RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
prop = RNA_def_property(srna, "spring_damping_y", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "spring_damping_y");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_float_default(prop, 0.5f);
RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_damping_y_set", NULL);
RNA_def_property_ui_text(prop, "Damping Y", "Damping on the Y axis");
RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
prop = RNA_def_property(srna, "spring_damping_z", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "spring_damping_z");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_float_default(prop, 0.5f);
RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_damping_z_set", NULL);
RNA_def_property_ui_text(prop, "Damping Z", "Damping on the Z axis");
RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
} }
void RNA_def_rigidbody(BlenderRNA *brna) void RNA_def_rigidbody(BlenderRNA *brna)