Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergej Reich <sergej.reich@googlemail.com>2013-02-24 03:04:07 +0400
committerSergej Reich <sergej.reich@googlemail.com>2013-02-24 03:04:07 +0400
commitc82213359aa8bc2a762dc0a76c813d46c159a291 (patch)
tree312fc8aa5a246025d8d6d519b83c266d3a2b861a
parent47bd908e014412b4339ca4bca0a3556d9bd7fcd2 (diff)
rigidbody: Add motor constraint
It's implemented as a separate constraint instead of adding properties to the existing constraints. Motors only apply linear and angular impulses and don't limit the movement of rigid bodies, so it's best to use them in conjunction with other constraints to limit the degrees of freedom. Thanks to Markus Kasten (markus111) for the initial patch.
-rw-r--r--intern/rigidbody/RBI_api.h6
-rw-r--r--intern/rigidbody/rb_bullet_api.cpp45
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py35
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c12
-rw-r--r--source/blender/makesdna/DNA_rigidbody_types.h15
-rw-r--r--source/blender/makesrna/intern/rna_rigidbody.c128
6 files changed, 234 insertions, 7 deletions
diff --git a/intern/rigidbody/RBI_api.h b/intern/rigidbody/RBI_api.h
index 9dde2cc3049..e7c88d96873 100644
--- a/intern/rigidbody/RBI_api.h
+++ b/intern/rigidbody/RBI_api.h
@@ -257,6 +257,7 @@ extern rbConstraint *RB_constraint_new_slider(float pivot[3], float orn[4], rbRi
extern rbConstraint *RB_constraint_new_piston(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
extern rbConstraint *RB_constraint_new_6dof(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
extern rbConstraint *RB_constraint_new_6dof_spring(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
+extern rbConstraint *RB_constraint_new_motor(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
/* ............ */
@@ -292,6 +293,11 @@ extern void RB_constraint_set_damping_6dof_spring(rbConstraint *con, int axis, f
extern void RB_constraint_set_spring_6dof_spring(rbConstraint *con, int axis, int enable);
extern void RB_constraint_set_equilibrium_6dof_spring(rbConstraint *con);
+/* motors */
+extern void RB_constraint_set_enable_motor(rbConstraint *con, int enable_lin, int enable_ang);
+extern void RB_constraint_set_max_impulse_motor(rbConstraint *con, float max_impulse_lin, float max_impulse_ang);
+extern void RB_constraint_set_target_velocity_motor(rbConstraint *con, float velocity_lin, float velocity_ang);
+
/* Set number of constraint solver iterations made per step, this overrided world setting
* To use default set it to -1 */
extern void RB_constraint_set_solver_iterations(rbConstraint *con, int num_solver_iterations);
diff --git a/intern/rigidbody/rb_bullet_api.cpp b/intern/rigidbody/rb_bullet_api.cpp
index 58345d4e08c..a628c35218c 100644
--- a/intern/rigidbody/rb_bullet_api.cpp
+++ b/intern/rigidbody/rb_bullet_api.cpp
@@ -850,6 +850,27 @@ rbConstraint *RB_constraint_new_6dof_spring(float pivot[3], float orn[4], rbRigi
return (rbConstraint *)con;
}
+rbConstraint *RB_constraint_new_motor(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);
+
+ btGeneric6DofConstraint *con = new btGeneric6DofConstraint(*body1, *body2, transform1, transform2, true);
+
+ /* unlock constraint axes */
+ for (int i = 0; i < 6; i++) {
+ con->setLimit(i, 0.0f, -1.0f);
+ }
+ /* unlock motor axes */
+ con->getTranslationalLimitMotor()->m_upperLimit.setValue(-1.0f, -1.0f, -1.0f);
+
+ return (rbConstraint*)con;
+}
+
/* Cleanup ----------------------------- */
void RB_constraint_delete(rbConstraint *con)
@@ -947,4 +968,28 @@ void RB_constraint_set_breaking_threshold(rbConstraint *con, float threshold)
constraint->setBreakingImpulseThreshold(threshold);
}
+void RB_constraint_set_enable_motor(rbConstraint *con, int enable_lin, int enable_ang)
+{
+ btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint*>(con);
+
+ constraint->getTranslationalLimitMotor()->m_enableMotor[0] = enable_lin;
+ constraint->getRotationalLimitMotor(0)->m_enableMotor = enable_ang;
+}
+
+void RB_constraint_set_max_impulse_motor(rbConstraint *con, float max_impulse_lin, float max_impulse_ang)
+{
+ btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint*>(con);
+
+ constraint->getTranslationalLimitMotor()->m_maxMotorForce.setX(max_impulse_lin);
+ constraint->getRotationalLimitMotor(0)->m_maxMotorForce = max_impulse_ang;
+}
+
+void RB_constraint_set_target_velocity_motor(rbConstraint *con, float velocity_lin, float velocity_ang)
+{
+ btGeneric6DofConstraint *constraint = reinterpret_cast<btGeneric6DofConstraint*>(con);
+
+ constraint->getTranslationalLimitMotor()->m_targetVelocity.setX(velocity_lin);
+ constraint->getRotationalLimitMotor(0)->m_targetVelocity = velocity_ang;
+}
+
/* ********************************** */
diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py
index e4e5b94407d..a49c6d623ca 100644
--- a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py
@@ -51,11 +51,12 @@ class PHYSICS_PT_rigid_body_constraint(PHYSICS_PT_rigidbody_constraint_panel, Pa
layout.prop(rbc, "object1")
layout.prop(rbc, "object2")
- row = layout.row()
- row.prop(rbc, "use_breaking")
- sub = row.row()
- sub.active = rbc.use_breaking
- sub.prop(rbc, "breaking_threshold", text="Threshold")
+ if rbc.type != 'MOTOR':
+ row = layout.row()
+ row.prop(rbc, "use_breaking")
+ sub = row.row()
+ sub.active = rbc.use_breaking
+ sub.prop(rbc, "breaking_threshold", text="Threshold")
row = layout.row()
row.prop(rbc, "override_solver_iterations", text="Override Iterations")
@@ -113,6 +114,30 @@ class PHYSICS_PT_rigid_body_constraint(PHYSICS_PT_rigidbody_constraint_panel, Pa
sub.prop(rbc, "limit_ang_x_lower", text="Lower")
sub.prop(rbc, "limit_ang_x_upper", text="Upper")
+ elif rbc.type == 'MOTOR':
+ col = layout.column(align=True)
+ col.label("Linear motor:")
+
+ row = col.row()
+ sub = row.row()
+ sub.scale_x = 0.5
+ sub.prop(rbc, "use_motor_lin", toggle=True, text="Enable")
+ sub = row.row()
+ sub.active = rbc.use_motor_lin
+ sub.prop(rbc, "motor_lin_target_velocity", text="Target Velocity")
+ sub.prop(rbc, "motor_lin_max_impulse", text="Max Impulse")
+
+ col.label("Angular motor:")
+
+ row = col.row()
+ sub = row.row()
+ sub.scale_x = 0.5
+ sub.prop(rbc, "use_motor_ang", toggle=True, text="Enable")
+ sub = row.row()
+ sub.active = rbc.use_motor_ang
+ sub.prop(rbc, "motor_ang_target_velocity", text="Target Velocity")
+ sub.prop(rbc, "motor_ang_max_impulse", text="Max Impulse")
+
elif rbc.type in {'GENERIC', 'GENERIC_SPRING'}:
col = layout.column(align=True)
col.label("Limits:")
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index c2fd6a9f54a..4c6bae122cd 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -633,6 +633,13 @@ void BKE_rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, shor
else
RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_ANG_Z, 0.0f, -1.0f);
break;
+ case RBC_TYPE_MOTOR:
+ rbc->physics_constraint = RB_constraint_new_motor(loc, rot, rb1, rb2);
+
+ RB_constraint_set_enable_motor(rbc->physics_constraint, rbc->flag & RBC_FLAG_USE_MOTOR_LIN, rbc->flag & RBC_FLAG_USE_MOTOR_ANG);
+ RB_constraint_set_max_impulse_motor(rbc->physics_constraint, rbc->motor_lin_max_impulse, rbc->motor_ang_max_impulse);
+ RB_constraint_set_target_velocity_motor(rbc->physics_constraint, rbc->motor_lin_target_velocity, rbc->motor_ang_target_velocity);
+ break;
}
}
else { /* can't create constraint without both rigid bodies */
@@ -816,6 +823,11 @@ RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short ty
rbc->spring_stiffness_y = 10.0f;
rbc->spring_stiffness_z = 10.0f;
+ rbc->motor_lin_max_impulse = 1.0f;
+ rbc->motor_lin_target_velocity = 1.0f;
+ rbc->motor_ang_max_impulse = 1.0f;
+ rbc->motor_ang_target_velocity = 1.0f;
+
/* flag cache as outdated */
BKE_rigidbody_cache_reset(rbw);
diff --git a/source/blender/makesdna/DNA_rigidbody_types.h b/source/blender/makesdna/DNA_rigidbody_types.h
index 01a680e558a..c144bc4e588 100644
--- a/source/blender/makesdna/DNA_rigidbody_types.h
+++ b/source/blender/makesdna/DNA_rigidbody_types.h
@@ -221,6 +221,12 @@ typedef struct RigidBodyCon {
float spring_damping_y;
float spring_damping_z;
+ /* motor settings */
+ float motor_lin_target_velocity; /* linear velocity the motor tries to hold */
+ float motor_ang_target_velocity; /* angular velocity the motor tries to hold */
+ float motor_lin_max_impulse; /* maximum force used to reach linear target velocity */
+ float motor_ang_max_impulse; /* maximum force used to reach angular target velocity */
+
/* References to Physics Sim object. Exist at runtime only */
void *physics_constraint; /* Physics object representation (i.e. btTypedConstraint) */
} RigidBodyCon;
@@ -249,7 +255,9 @@ typedef enum eRigidBodyCon_Type {
/* similar to slider but also allows rotation around slider axis */
RBC_TYPE_PISTON,
/* Simplified spring constraint with only once axis that's automatically placed between the connected bodies */
- RBC_TYPE_SPRING
+ RBC_TYPE_SPRING,
+ /* dirves bodies by applying linear and angular forces */
+ RBC_TYPE_MOTOR
} eRigidBodyCon_Type;
/* Flags for RigidBodyCon */
@@ -274,7 +282,10 @@ typedef enum eRigidBodyCon_Flag {
/* springs */
RBC_FLAG_USE_SPRING_X = (1 << 11),
RBC_FLAG_USE_SPRING_Y = (1 << 12),
- RBC_FLAG_USE_SPRING_Z = (1 << 13)
+ RBC_FLAG_USE_SPRING_Z = (1 << 13),
+ /* motors */
+ RBC_FLAG_USE_MOTOR_LIN = (1 << 14),
+ RBC_FLAG_USE_MOTOR_ANG = (1 << 15)
} eRigidBodyCon_Flag;
/* ******************************** */
diff --git a/source/blender/makesrna/intern/rna_rigidbody.c b/source/blender/makesrna/intern/rna_rigidbody.c
index 7270ccadb81..f5cf247b5a1 100644
--- a/source/blender/makesrna/intern/rna_rigidbody.c
+++ b/source/blender/makesrna/intern/rna_rigidbody.c
@@ -72,6 +72,7 @@ EnumPropertyItem rigidbody_con_type_items[] = {
{RBC_TYPE_6DOF, "GENERIC", ICON_NONE, "Generic", "Restrict translation and rotation to specified axes"},
{RBC_TYPE_6DOF_SPRING, "GENERIC_SPRING", ICON_NONE, "Generic Spring",
"Restrict translation and rotation to specified axes with springs"},
+ {RBC_TYPE_MOTOR, "MOTOR", ICON_NONE, "Motor", "Drive rigid body around or along an axis"},
{0, NULL, 0, NULL, NULL}};
@@ -501,6 +502,85 @@ static void rna_RigidBodyCon_spring_damping_z_set(PointerRNA *ptr, float value)
#endif
}
+static void rna_RigidBodyCon_motor_lin_max_impulse_set(PointerRNA *ptr, float value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ rbc->motor_lin_max_impulse = value;
+
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint && rbc->type == RBC_TYPE_MOTOR) {
+ RB_constraint_set_max_impulse_motor(rbc->physics_constraint, value, rbc->motor_ang_max_impulse);
+ }
+#endif
+}
+
+static void rna_RigidBodyCon_use_motor_lin_set(PointerRNA *ptr, int value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ RB_FLAG_SET(rbc->flag, value, RBC_FLAG_USE_MOTOR_LIN);
+
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint) {
+ RB_constraint_set_enable_motor(rbc->physics_constraint, rbc->flag & RBC_FLAG_USE_MOTOR_LIN, rbc->flag & RBC_FLAG_USE_MOTOR_ANG);
+ }
+#endif
+}
+
+static void rna_RigidBodyCon_use_motor_ang_set(PointerRNA *ptr, int value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ RB_FLAG_SET(rbc->flag, value, RBC_FLAG_USE_MOTOR_ANG);
+
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint) {
+ RB_constraint_set_enable_motor(rbc->physics_constraint, rbc->flag & RBC_FLAG_USE_MOTOR_LIN, rbc->flag & RBC_FLAG_USE_MOTOR_ANG);
+ }
+#endif
+}
+
+static void rna_RigidBodyCon_motor_lin_target_velocity_set(PointerRNA *ptr, float value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ rbc->motor_lin_target_velocity = value;
+
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint && rbc->type == RBC_TYPE_MOTOR) {
+ RB_constraint_set_target_velocity_motor(rbc->physics_constraint, value, rbc->motor_ang_target_velocity);
+ }
+#endif
+}
+
+static void rna_RigidBodyCon_motor_ang_max_impulse_set(PointerRNA *ptr, float value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ rbc->motor_ang_max_impulse = value;
+
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint && rbc->type == RBC_TYPE_MOTOR) {
+ RB_constraint_set_max_impulse_motor(rbc->physics_constraint, rbc->motor_lin_max_impulse, value);
+ }
+#endif
+}
+
+static void rna_RigidBodyCon_motor_ang_target_velocity_set(PointerRNA *ptr, float value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ rbc->motor_ang_target_velocity = value;
+
+#ifdef WITH_BULLET
+ if (rbc->physics_constraint && rbc->type == RBC_TYPE_MOTOR) {
+ RB_constraint_set_target_velocity_motor(rbc->physics_constraint, rbc->motor_lin_target_velocity, value);
+ }
+#endif
+}
+
+
#else
static void rna_def_rigidbody_world(BlenderRNA *brna)
@@ -866,6 +946,18 @@ static void rna_def_rigidbody_constraint(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Z Spring", "Enable spring on Z axis");
RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
+ prop = RNA_def_property(srna, "use_motor_lin", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_MOTOR_LIN);
+ RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyCon_use_motor_lin_set");
+ RNA_def_property_ui_text(prop, "Linear Motor", "Enables linear motor");
+ RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "use_motor_ang", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_MOTOR_ANG);
+ RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyCon_use_motor_ang_set");
+ RNA_def_property_ui_text(prop, "Angular Motor", "Enables angular motor");
+ RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
+
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_default(prop, -1.0f);
@@ -994,6 +1086,42 @@ static void rna_def_rigidbody_constraint(BlenderRNA *brna)
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");
+
+ prop = RNA_def_property(srna, "motor_lin_target_velocity", PROP_FLOAT, PROP_UNIT_VELOCITY);
+ RNA_def_property_float_sdna(prop, NULL, "motor_lin_target_velocity");
+ RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
+ RNA_def_property_ui_range(prop, -100.0f, 100.0f, 1, 3);
+ RNA_def_property_float_default(prop, 1.0f);
+ RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_motor_lin_target_velocity_set", NULL);
+ RNA_def_property_ui_text(prop, "Target Velocity", "Target linear motor velocity");
+ RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "motor_lin_max_impulse", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "motor_lin_max_impulse");
+ 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, 1.0f);
+ RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_motor_lin_max_impulse_set", NULL);
+ RNA_def_property_ui_text(prop, "Max Impulse", "Maximum linear motor impulse");
+ RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "motor_ang_target_velocity", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "motor_ang_target_velocity");
+ RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
+ RNA_def_property_ui_range(prop, -100.0f, 100.0f, 1, 3);
+ RNA_def_property_float_default(prop, 1.0f);
+ RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_motor_ang_target_velocity_set", NULL);
+ RNA_def_property_ui_text(prop, "Target Velocity", "Target angular motor velocity");
+ RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
+
+ prop = RNA_def_property(srna, "motor_ang_max_impulse", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "motor_ang_max_impulse");
+ 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, 1.0f);
+ RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_motor_ang_max_impulse_set", NULL);
+ RNA_def_property_ui_text(prop, "Max Impulse", "Maximum angular motor impulse");
+ RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset");
}
void RNA_def_rigidbody(BlenderRNA *brna)