Fix T55958: allow the user to select between spring and spring2.
authorAlexander Gavrilov <angavrilov@gmail.com>
Sat, 14 Jul 2018 14:01:02 +0000 (17:01 +0300)
committerAlexander Gavrilov <angavrilov@gmail.com>
Tue, 24 Jul 2018 07:10:48 +0000 (10:10 +0300)
The old springs with damping 1.0 operate in a special way that
is more similar to plastic deformation than a spring. Some users
rely on that, so let the user choose which implementation to use.
This also restores full backward compatibility with 2.79.

Reviewers: sergof

Differential Revision: https://developer.blender.org/D3544

intern/rigidbody/RBI_api.h
intern/rigidbody/rb_bullet_api.cpp
release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py
source/blender/blenkernel/intern/rigidbody.c
source/blender/makesdna/DNA_rigidbody_types.h
source/blender/makesrna/intern/rna_rigidbody.c

index 556ca95..eec94bc 100644 (file)
@@ -268,6 +268,7 @@ rbConstraint *RB_constraint_new_slider(float pivot[3], float orn[4], rbRigidBody
 rbConstraint *RB_constraint_new_piston(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
 rbConstraint *RB_constraint_new_6dof(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
 rbConstraint *RB_constraint_new_6dof_spring(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
+rbConstraint *RB_constraint_new_6dof_spring2(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
 rbConstraint *RB_constraint_new_motor(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
 
 /* ............ */
@@ -299,12 +300,18 @@ void RB_constraint_set_limits_piston(rbConstraint *con, float lin_lower, float l
 void RB_constraint_set_limits_6dof(rbConstraint *con, int axis, float lower, float upper);
 
 /* 6dof spring specific */
-void RB_constraint_set_limits_6dof_spring(rbConstraint *con, int axis, float lower, float upper);
 void RB_constraint_set_stiffness_6dof_spring(rbConstraint *con, int axis, float stiffness);
 void RB_constraint_set_damping_6dof_spring(rbConstraint *con, int axis, float damping);
 void RB_constraint_set_spring_6dof_spring(rbConstraint *con, int axis, int enable);
 void RB_constraint_set_equilibrium_6dof_spring(rbConstraint *con);
 
+/* 6dof spring 2 specific */
+void RB_constraint_set_limits_6dof_spring2(rbConstraint *con, int axis, float lower, float upper);
+void RB_constraint_set_stiffness_6dof_spring2(rbConstraint *con, int axis, float stiffness);
+void RB_constraint_set_damping_6dof_spring2(rbConstraint *con, int axis, float damping);
+void RB_constraint_set_spring_6dof_spring2(rbConstraint *con, int axis, int enable);
+void RB_constraint_set_equilibrium_6dof_spring2(rbConstraint *con);
+
 /* motors */
 void RB_constraint_set_enable_motor(rbConstraint *con, int enable_lin, int enable_ang);
 void RB_constraint_set_max_impulse_motor(rbConstraint *con, float max_impulse_lin, float max_impulse_ang);
index a9fbcb2..6a50c5c 100644 (file)
@@ -954,11 +954,25 @@ rbConstraint *RB_constraint_new_6dof_spring(float pivot[3], float orn[4], rbRigi
        
        make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
        
-       btTypedConstraint *con = new btGeneric6DofSpring2Constraint(*body1, *body2, transform1, transform2);
+       btTypedConstraint *con = new btGeneric6DofSpringConstraint(*body1, *body2, transform1, transform2, true);
        
        return (rbConstraint *)con;
 }
 
+rbConstraint *RB_constraint_new_6dof_spring2(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
+{
+       btRigidBody *body1 = rb1->body;
+       btRigidBody *body2 = rb2->body;
+       btTransform transform1;
+       btTransform transform2;
+
+       make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
+
+       btTypedConstraint *con = new btGeneric6DofSpring2Constraint(*body1, *body2, transform1, transform2);
+
+       return (rbConstraint *)con;
+}
+
 rbConstraint *RB_constraint_new_motor(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
 {
        btRigidBody *body1 = rb1->body;
@@ -1034,7 +1048,7 @@ void RB_constraint_set_limits_6dof(rbConstraint *con, int axis, float lower, flo
        constraint->setLimit(axis, lower, upper);
 }
 
-void RB_constraint_set_limits_6dof_spring(rbConstraint *con, int axis, float lower, float upper)
+void RB_constraint_set_limits_6dof_spring2(rbConstraint *con, int axis, float lower, float upper)
 {
        btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
 
@@ -1043,26 +1057,57 @@ void RB_constraint_set_limits_6dof_spring(rbConstraint *con, int axis, float low
 
 void RB_constraint_set_stiffness_6dof_spring(rbConstraint *con, int axis, float stiffness)
 {
-       btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
+       btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
 
        constraint->setStiffness(axis, stiffness);
 }
 
 void RB_constraint_set_damping_6dof_spring(rbConstraint *con, int axis, float damping)
 {
-       btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
+       btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
+
+       // invert damping range so that 0 = no damping
+       damping = (damping > 1.0f) ? 0.0f : 1.0f - damping;
 
        constraint->setDamping(axis, damping);
 }
 
 void RB_constraint_set_spring_6dof_spring(rbConstraint *con, int axis, int enable)
 {
-       btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
+       btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
 
        constraint->enableSpring(axis, enable);
 }
 
 void RB_constraint_set_equilibrium_6dof_spring(rbConstraint *con)
+{
+       btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
+
+       constraint->setEquilibriumPoint();
+}
+
+void RB_constraint_set_stiffness_6dof_spring2(rbConstraint *con, int axis, float stiffness)
+{
+       btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
+
+       constraint->setStiffness(axis, stiffness);
+}
+
+void RB_constraint_set_damping_6dof_spring2(rbConstraint *con, int axis, float damping)
+{
+       btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
+
+       constraint->setDamping(axis, damping);
+}
+
+void RB_constraint_set_spring_6dof_spring2(rbConstraint *con, int axis, int enable)
+{
+       btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
+
+       constraint->enableSpring(axis, enable);
+}
+
+void RB_constraint_set_equilibrium_6dof_spring2(rbConstraint *con)
 {
        btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
 
index 84a4cbb..8f6b5b5 100644 (file)
@@ -140,6 +140,11 @@ class PHYSICS_PT_rigid_body_constraint(PHYSICS_PT_rigidbody_constraint_panel, Pa
             sub.prop(rbc, "motor_ang_max_impulse", text="Max Impulse")
 
         elif rbc.type in {'GENERIC', 'GENERIC_SPRING'}:
+            if rbc.type == 'GENERIC_SPRING':
+                row = layout.row()
+                row.label("Spring Type:")
+                row.prop(rbc, "spring_type", text="")
+
             col = layout.column(align=True)
             col.label("Limits:")
 
index 502b6a8..5d6695e 100644 (file)
@@ -700,6 +700,35 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool
 
 /* --------------------- */
 
+static void rigidbody_constraint_init_spring(
+       RigidBodyCon *rbc, void (*set_spring)(rbConstraint*,int,int),
+       void (*set_stiffness)(rbConstraint*,int,float), void (*set_damping)(rbConstraint*,int,float)
+) {
+       set_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->flag & RBC_FLAG_USE_SPRING_X);
+       set_stiffness(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_stiffness_x);
+       set_damping(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_damping_x);
+
+       set_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->flag & RBC_FLAG_USE_SPRING_Y);
+       set_stiffness(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->spring_stiffness_y);
+       set_damping(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->spring_damping_y);
+
+       set_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->flag & RBC_FLAG_USE_SPRING_Z);
+       set_stiffness(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_stiffness_z);
+       set_damping(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_damping_z);
+
+       set_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->flag & RBC_FLAG_USE_SPRING_ANG_X);
+       set_stiffness(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_stiffness_ang_x);
+       set_damping(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_damping_ang_x);
+
+       set_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->flag & RBC_FLAG_USE_SPRING_ANG_Y);
+       set_stiffness(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_stiffness_ang_y);
+       set_damping(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_damping_ang_y);
+
+       set_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->flag & RBC_FLAG_USE_SPRING_ANG_Z);
+       set_stiffness(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_stiffness_ang_z);
+       set_damping(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_damping_ang_z);
+}
+
 static void rigidbody_constraint_set_limits(RigidBodyCon *rbc, void (*set_limits)(rbConstraint*,int,float,float))
 {
        if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_X)
@@ -824,35 +853,24 @@ static void rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, b
                                        RB_constraint_set_limits_piston(rbc->physics_constraint, lin_lower, lin_upper, ang_lower, ang_upper);
                                        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);
+                                       if (rbc->spring_type == RBC_SPRING_TYPE2) {
+                                               rbc->physics_constraint = RB_constraint_new_6dof_spring2(loc, rot, rb1, rb2);
 
-                                       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);
+                                               rigidbody_constraint_init_spring(rbc, RB_constraint_set_spring_6dof_spring2, RB_constraint_set_stiffness_6dof_spring2, RB_constraint_set_damping_6dof_spring2);
 
-                                       RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->flag & RBC_FLAG_USE_SPRING_ANG_X);
-                                       RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_stiffness_ang_x);
-                                       RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_damping_ang_x);
+                                               RB_constraint_set_equilibrium_6dof_spring2(rbc->physics_constraint);
 
-                                       RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->flag & RBC_FLAG_USE_SPRING_ANG_Y);
-                                       RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_stiffness_ang_y);
-                                       RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_damping_ang_y);
+                                               rigidbody_constraint_set_limits(rbc, RB_constraint_set_limits_6dof_spring2);
+                                       }
+                                       else {
+                                               rbc->physics_constraint = RB_constraint_new_6dof_spring(loc, rot, rb1, rb2);
 
-                                       RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->flag & RBC_FLAG_USE_SPRING_ANG_Z);
-                                       RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_stiffness_ang_z);
-                                       RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_damping_ang_z);
+                                               rigidbody_constraint_init_spring(rbc, RB_constraint_set_spring_6dof_spring, RB_constraint_set_stiffness_6dof_spring, RB_constraint_set_damping_6dof_spring);
 
-                                       RB_constraint_set_equilibrium_6dof_spring(rbc->physics_constraint);
+                                               RB_constraint_set_equilibrium_6dof_spring(rbc->physics_constraint);
 
-                                       rigidbody_constraint_set_limits(rbc, RB_constraint_set_limits_6dof_spring);
+                                               rigidbody_constraint_set_limits(rbc, RB_constraint_set_limits_6dof);
+                                       }
                                        break;
                                case RBC_TYPE_6DOF:
                                        rbc->physics_constraint = RB_constraint_new_6dof(loc, rot, rb1, rb2);
@@ -1071,6 +1089,8 @@ RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short ty
        rbc->flag |= RBC_FLAG_ENABLED;
        rbc->flag |= RBC_FLAG_DISABLE_COLLISIONS;
 
+       rbc->spring_type = RBC_SPRING_TYPE2;
+
        rbc->breaking_threshold = 10.0f; /* no good default here, just use 10 for now */
        rbc->num_solver_iterations = 10; /* 10 is Bullet default */
 
index 1cd3a22..19e4964 100644 (file)
@@ -203,7 +203,8 @@ typedef struct RigidBodyCon {
        int flag;                                       /* (eRigidBodyCon_Flag) */
 
        float breaking_threshold;       /* breaking impulse threshold */
-       float pad;
+       char spring_type;               /* spring implementation to use */
+       char pad[3];
 
        /* limits */
        /* translation limits */
@@ -273,9 +274,15 @@ typedef enum eRigidBodyCon_Type {
        /* Simplified spring constraint with only once axis that's automatically placed between the connected bodies */
        RBC_TYPE_SPRING,
        /* dirves bodies by applying linear and angular forces */
-       RBC_TYPE_MOTOR
+       RBC_TYPE_MOTOR,
 } eRigidBodyCon_Type;
 
+/* Spring implementation type for RigidBodyOb */
+typedef enum eRigidBodyCon_SpringType {
+       RBC_SPRING_TYPE1 = 0,   /* btGeneric6DofSpringConstraint */
+       RBC_SPRING_TYPE2,       /* btGeneric6DofSpring2Constraint */
+} eRigidBodyCon_SpringType;
+
 /* Flags for RigidBodyCon */
 typedef enum eRigidBodyCon_Flag {
        /* constraint influences rigid body motion */
index e1e9bb3..853b1d9 100644 (file)
@@ -76,6 +76,12 @@ const EnumPropertyItem rna_enum_rigidbody_constraint_type_items[] = {
        {RBC_TYPE_MOTOR, "MOTOR", ICON_NONE, "Motor", "Drive rigid body around or along an axis"},
        {0, NULL, 0, NULL, NULL}};
 
+/* bullet spring type */
+const EnumPropertyItem rna_enum_rigidbody_constraint_spring_type_items[] = {
+       {RBC_SPRING_TYPE1, "SPRING1", ICON_NONE, "Blender 2.7", "Spring implementation used in blender 2.7. Damping is capped at 1.0"},
+       {RBC_SPRING_TYPE2, "SPRING2", ICON_NONE, "Blender 2.8", "New implementation available since 2.8"},
+       {0, NULL, 0, NULL, NULL}};
+
 #ifndef RNA_RUNTIME
 /* mesh source for collision shape creation */
 static const EnumPropertyItem rigidbody_mesh_source_items[] = {
@@ -376,6 +382,14 @@ static void rna_RigidBodyCon_type_set(PointerRNA *ptr, int value)
        rbc->flag |= RBC_FLAG_NEEDS_VALIDATE;
 }
 
+static void rna_RigidBodyCon_spring_type_set(PointerRNA *ptr, int value)
+{
+       RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+       rbc->spring_type = value;
+       rbc->flag |= RBC_FLAG_NEEDS_VALIDATE;
+}
+
 static void rna_RigidBodyCon_enabled_set(PointerRNA *ptr, bool value)
 {
        RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
@@ -468,6 +482,22 @@ static void rna_RigidBodyCon_num_solver_iterations_set(PointerRNA *ptr, int valu
 #endif
 }
 
+#ifdef WITH_BULLET
+static void rna_RigidBodyCon_do_set_spring_stiffness(RigidBodyCon *rbc, float value, int flag, int axis)
+{
+       if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & flag)) {
+               switch (rbc->spring_type) {
+                       case RBC_SPRING_TYPE1:
+                               RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, axis, value);
+                               break;
+                       case RBC_SPRING_TYPE2:
+                               RB_constraint_set_stiffness_6dof_spring2(rbc->physics_constraint, axis, value);
+                               break;
+               }
+       }
+}
+#endif
+
 static void rna_RigidBodyCon_spring_stiffness_x_set(PointerRNA *ptr, float value)
 {
        RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
@@ -475,9 +505,7 @@ static void rna_RigidBodyCon_spring_stiffness_x_set(PointerRNA *ptr, float value
        rbc->spring_stiffness_x = value;
 
 #ifdef WITH_BULLET
-       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);
-       }
+       rna_RigidBodyCon_do_set_spring_stiffness(rbc, value, RBC_FLAG_USE_SPRING_X, RB_LIMIT_LIN_X);
 #endif
 }
 
@@ -488,9 +516,7 @@ static void rna_RigidBodyCon_spring_stiffness_y_set(PointerRNA *ptr, float value
        rbc->spring_stiffness_y = value;
 
 #ifdef WITH_BULLET
-       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);
-       }
+       rna_RigidBodyCon_do_set_spring_stiffness(rbc, value, RBC_FLAG_USE_SPRING_Y, RB_LIMIT_LIN_Y);
 #endif
 }
 
@@ -501,9 +527,7 @@ static void rna_RigidBodyCon_spring_stiffness_z_set(PointerRNA *ptr, float value
        rbc->spring_stiffness_z = value;
 
 #ifdef WITH_BULLET
-       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);
-       }
+       rna_RigidBodyCon_do_set_spring_stiffness(rbc, value, RBC_FLAG_USE_SPRING_Z, RB_LIMIT_LIN_Z);
 #endif
 }
 
@@ -514,9 +538,7 @@ static void rna_RigidBodyCon_spring_stiffness_ang_x_set(PointerRNA *ptr, float v
        rbc->spring_stiffness_ang_x = value;
 
 #ifdef WITH_BULLET
-       if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_X)) {
-               RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, value);
-       }
+       rna_RigidBodyCon_do_set_spring_stiffness(rbc, value, RBC_FLAG_USE_SPRING_ANG_X, RB_LIMIT_ANG_X);
 #endif
 }
 
@@ -527,9 +549,7 @@ static void rna_RigidBodyCon_spring_stiffness_ang_y_set(PointerRNA *ptr, float v
        rbc->spring_stiffness_ang_y = value;
 
 #ifdef WITH_BULLET
-       if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_Y)) {
-               RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, value);
-       }
+       rna_RigidBodyCon_do_set_spring_stiffness(rbc, value, RBC_FLAG_USE_SPRING_ANG_Y, RB_LIMIT_ANG_Y);
 #endif
 }
 
@@ -540,12 +560,26 @@ static void rna_RigidBodyCon_spring_stiffness_ang_z_set(PointerRNA *ptr, float v
        rbc->spring_stiffness_ang_z = value;
 
 #ifdef WITH_BULLET
-       if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_Z)) {
-               RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, value);
-       }
+       rna_RigidBodyCon_do_set_spring_stiffness(rbc, value, RBC_FLAG_USE_SPRING_ANG_Z, RB_LIMIT_ANG_Z);
 #endif
 }
 
+#ifdef WITH_BULLET
+static void rna_RigidBodyCon_do_set_spring_damping(RigidBodyCon *rbc, float value, int flag, int axis)
+{
+       if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & flag)) {
+               switch (rbc->spring_type) {
+                       case RBC_SPRING_TYPE1:
+                               RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, axis, value);
+                               break;
+                       case RBC_SPRING_TYPE2:
+                               RB_constraint_set_damping_6dof_spring2(rbc->physics_constraint, axis, value);
+                               break;
+               }
+       }
+}
+#endif
+
 static void rna_RigidBodyCon_spring_damping_x_set(PointerRNA *ptr, float value)
 {
        RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
@@ -553,9 +587,7 @@ static void rna_RigidBodyCon_spring_damping_x_set(PointerRNA *ptr, float value)
        rbc->spring_damping_x = value;
 
 #ifdef WITH_BULLET
-       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);
-       }
+       rna_RigidBodyCon_do_set_spring_damping(rbc, value, RBC_FLAG_USE_SPRING_X, RB_LIMIT_LIN_X);
 #endif
 }
 
@@ -565,9 +597,7 @@ static void rna_RigidBodyCon_spring_damping_y_set(PointerRNA *ptr, float value)
 
        rbc->spring_damping_y = value;
 #ifdef WITH_BULLET
-       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);
-       }
+       rna_RigidBodyCon_do_set_spring_damping(rbc, value, RBC_FLAG_USE_SPRING_Y, RB_LIMIT_LIN_Y);
 #endif
 }
 
@@ -577,9 +607,7 @@ static void rna_RigidBodyCon_spring_damping_z_set(PointerRNA *ptr, float value)
 
        rbc->spring_damping_z = value;
 #ifdef WITH_BULLET
-       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);
-       }
+       rna_RigidBodyCon_do_set_spring_damping(rbc, value, RBC_FLAG_USE_SPRING_Z, RB_LIMIT_LIN_Z);
 #endif
 }
 
@@ -590,9 +618,7 @@ static void rna_RigidBodyCon_spring_damping_ang_x_set(PointerRNA *ptr, float val
        rbc->spring_damping_ang_x = value;
 
 #ifdef WITH_BULLET
-       if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_X)) {
-               RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, value);
-       }
+       rna_RigidBodyCon_do_set_spring_damping(rbc, value, RBC_FLAG_USE_SPRING_ANG_X, RB_LIMIT_ANG_X);
 #endif
 }
 
@@ -602,9 +628,7 @@ static void rna_RigidBodyCon_spring_damping_ang_y_set(PointerRNA *ptr, float val
 
        rbc->spring_damping_ang_y = value;
 #ifdef WITH_BULLET
-       if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_Y)) {
-               RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, value);
-       }
+       rna_RigidBodyCon_do_set_spring_damping(rbc, value, RBC_FLAG_USE_SPRING_ANG_Y, RB_LIMIT_ANG_Y);
 #endif
 }
 
@@ -614,9 +638,7 @@ static void rna_RigidBodyCon_spring_damping_ang_z_set(PointerRNA *ptr, float val
 
        rbc->spring_damping_ang_z = value;
 #ifdef WITH_BULLET
-       if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_Z)) {
-               RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, value);
-       }
+       rna_RigidBodyCon_do_set_spring_damping(rbc, value, RBC_FLAG_USE_SPRING_ANG_Z, RB_LIMIT_ANG_Z);
 #endif
 }
 
@@ -1025,6 +1047,14 @@ static void rna_def_rigidbody_constraint(BlenderRNA *brna)
        RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
        RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
 
+       prop = RNA_def_property(srna, "spring_type", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "spring_type");
+       RNA_def_property_enum_items(prop, rna_enum_rigidbody_constraint_spring_type_items);
+       RNA_def_property_enum_funcs(prop, NULL, "rna_RigidBodyCon_spring_type_set", NULL);
+       RNA_def_property_ui_text(prop, "Spring Type", "Which implementation of spring to use");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+
        prop = RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_ENABLED);
        RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyCon_enabled_set");