[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [54798] trunk/blender: rigidbody: Add motor constraint

Sergej Reich sergej.reich at googlemail.com
Sun Feb 24 00:04:07 CET 2013


Revision: 54798
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=54798
Author:   sergof
Date:     2013-02-23 23:04:07 +0000 (Sat, 23 Feb 2013)
Log Message:
-----------
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.

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

Modified: trunk/blender/intern/rigidbody/RBI_api.h
===================================================================
--- trunk/blender/intern/rigidbody/RBI_api.h	2013-02-23 23:04:03 UTC (rev 54797)
+++ trunk/blender/intern/rigidbody/RBI_api.h	2013-02-23 23:04:07 UTC (rev 54798)
@@ -257,6 +257,7 @@
 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_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);

Modified: trunk/blender/intern/rigidbody/rb_bullet_api.cpp
===================================================================
--- trunk/blender/intern/rigidbody/rb_bullet_api.cpp	2013-02-23 23:04:03 UTC (rev 54797)
+++ trunk/blender/intern/rigidbody/rb_bullet_api.cpp	2013-02-23 23:04:07 UTC (rev 54798)
@@ -850,6 +850,27 @@
 	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 @@
 	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;
+}
+
 /* ********************************** */

Modified: trunk/blender/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py
===================================================================
--- trunk/blender/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py	2013-02-23 23:04:03 UTC (rev 54797)
+++ trunk/blender/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py	2013-02-23 23:04:07 UTC (rev 54798)
@@ -51,11 +51,12 @@
         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 @@
             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:")

Modified: trunk/blender/source/blender/blenkernel/intern/rigidbody.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/rigidbody.c	2013-02-23 23:04:03 UTC (rev 54797)
+++ trunk/blender/source/blender/blenkernel/intern/rigidbody.c	2013-02-23 23:04:07 UTC (rev 54798)
@@ -633,6 +633,13 @@
 					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 @@
 	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);
 

Modified: trunk/blender/source/blender/makesdna/DNA_rigidbody_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_rigidbody_types.h	2013-02-23 23:04:03 UTC (rev 54797)
+++ trunk/blender/source/blender/makesdna/DNA_rigidbody_types.h	2013-02-23 23:04:07 UTC (rev 54798)
@@ -221,6 +221,12 @@
 	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 @@
 	/* 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 @@
 	/* 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;
 
 /* ******************************** */

Modified: trunk/blender/source/blender/makesrna/intern/rna_rigidbody.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/rna_rigidbody.c	2013-02-23 23:04:03 UTC (rev 54797)
+++ trunk/blender/source/blender/makesrna/intern/rna_rigidbody.c	2013-02-23 23:04:07 UTC (rev 54798)
@@ -72,6 +72,7 @@
 	{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 @@
 #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)
+{

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list