[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [54038] trunk/blender/source/blender: rigidbody: Make rigid bodies kinematic during transformation

Sergej Reich sergej.reich at googlemail.com
Wed Jan 23 13:06:21 CET 2013


Revision: 54038
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=54038
Author:   sergof
Date:     2013-01-23 12:06:18 +0000 (Wed, 23 Jan 2013)
Log Message:
-----------
rigidbody: Make rigid bodies kinematic during transformation

This allows moving rigid bodies on frame > startframe.
Also rigid bodies can now be picked up and trown around while the
simulation is running.

Note: There is a small glitch with cancelling tansform during simulation
but it's tricky to get rid of.

TODO: Avoid static-static collision warnings

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_rigidbody.h
    trunk/blender/source/blender/blenkernel/intern/rigidbody.c
    trunk/blender/source/blender/editors/transform/transform.h
    trunk/blender/source/blender/editors/transform/transform_conversions.c

Modified: trunk/blender/source/blender/blenkernel/BKE_rigidbody.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_rigidbody.h	2013-01-23 11:40:35 UTC (rev 54037)
+++ trunk/blender/source/blender/blenkernel/BKE_rigidbody.h	2013-01-23 12:06:18 UTC (rev 54038)
@@ -87,6 +87,7 @@
 /* -------------- */
 /* Simulation */
 
+void BKE_rigidbody_aftertrans_update(struct Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle);
 void BKE_rigidbody_sync_transforms(struct Scene *scene, struct Object *ob, float ctime);
 void BKE_rigidbody_cache_reset(struct RigidBodyWorld *rbw);
 void BKE_rigidbody_do_simulation(struct Scene *scene, float ctime);

Modified: trunk/blender/source/blender/blenkernel/intern/rigidbody.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/rigidbody.c	2013-01-23 11:40:35 UTC (rev 54037)
+++ trunk/blender/source/blender/blenkernel/intern/rigidbody.c	2013-01-23 12:06:18 UTC (rev 54038)
@@ -953,8 +953,14 @@
 	if (!(rbo->flag & RBO_FLAG_USE_MARGIN) && rbo->shape == RB_SHAPE_CONVEXH)
 		RB_shape_set_margin(rbo->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) || rbo->type == RBO_TYPE_PASSIVE) {
+		RB_body_set_kinematic_state(rbo->physics_object, TRUE);
+		RB_body_set_mass(rbo->physics_object, 0.0f);
+	}
+
 	/* update rigid body location and rotation for kinematic bodies */
-	if (rbo->flag & RBO_FLAG_KINEMATIC) {
+	if (rbo->flag & RBO_FLAG_KINEMATIC || (ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ)) {
 		RB_body_activate(rbo->physics_object);
 		RB_body_set_loc_rot(rbo->physics_object, loc, rot);
 	}
@@ -1095,6 +1101,24 @@
 	}
 }
 
+static void rigidbody_update_simulation_post_step(RigidBodyWorld *rbw)
+{
+	GroupObject *go;
+
+	for (go = rbw->group->gobject.first; go; go = go->next) {
+		Object *ob = go->ob;
+
+		if (ob) {
+			RigidBodyOb *rbo = ob->rigidbody_object;
+			/* reset kinematic state for transformed objects */
+			if (ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ) {
+				RB_body_set_kinematic_state(rbo->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
+				RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo));
+			}
+		}
+	}
+}
+
 /* Sync rigid body and object transformations */
 void BKE_rigidbody_sync_transforms(Scene *scene, Object *ob, float ctime)
 {
@@ -1105,8 +1129,8 @@
 	if (ELEM(NULL, rbw, rbo) || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE)
 		return;
 
-	/* use rigid body transform after cache start frame */
-	if (ctime > rbw->pointcache->startframe) {
+	/* use rigid body transform after cache start frame if objects is not being transformed */
+	if (ctime > rbw->pointcache->startframe && !(ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ)) {
 		float mat[4][4], size_mat[4][4], size[3];
 
 		/* keep original transform when the simulation is muted */
@@ -1129,6 +1153,31 @@
 	}
 }
 
+void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle)
+{
+	RigidBodyOb *rbo = ob->rigidbody_object;
+
+	/* return rigid body and objext to their initial states */
+	copy_v3_v3(rbo->pos, ob->loc);
+	copy_v3_v3(ob->loc, loc);
+
+	if (ob->rotmode > 0) {
+		eulO_to_quat(rbo->orn, ob->rot, ob->rotmode);
+		copy_v3_v3(ob->rot, rot);
+	}
+	else if (ob->rotmode == ROT_MODE_AXISANGLE) {
+		axis_angle_to_quat(rbo->orn, ob->rotAxis, ob->rotAngle);
+		copy_v3_v3(ob->rotAxis, rotAxis);
+		ob->rotAngle = rotAngle;
+	}
+	else {
+		copy_qt_qt(rbo->orn, ob->quat);
+		copy_qt_qt(ob->quat, quat);
+	}
+	RB_body_set_loc_rot(rbo->physics_object, rbo->pos, rbo->orn);
+	// RB_TODO update rigid body physics object's loc/rot for dynamic objects here as well (needs to be done outside bullet's update loop)
+}
+
 void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw)
 {
 	if (rbw)
@@ -1206,6 +1255,8 @@
 		/* step simulation by the requested timestep, steps per second are adjusted to take time scale into account */
 		RB_dworld_step_simulation(rbw->physics_world, timestep, INT_MAX, 1.0f / (float)rbw->steps_per_second * min_ff(rbw->time_scale, 1.0f));
 
+		rigidbody_update_simulation_post_step(rbw);
+
 		/* write cache for current frame */
 		BKE_ptcache_validate(cache, (int)ctime);
 		BKE_ptcache_write(&pid, (unsigned int)ctime);

Modified: trunk/blender/source/blender/editors/transform/transform.h
===================================================================
--- trunk/blender/source/blender/editors/transform/transform.h	2013-01-23 11:40:35 UTC (rev 54037)
+++ trunk/blender/source/blender/editors/transform/transform.h	2013-01-23 12:06:18 UTC (rev 54038)
@@ -137,6 +137,7 @@
 	                      * namely when a bone is in "NoLocal" or "Hinge" mode)... */
 	float  r_smtx[3][3]; /* Invers of previous one. */
 	int    rotOrder;	/* rotation mode,  as defined in eRotationModes (DNA_action_types.h) */
+	float oloc[3], orot[3], oquat[4], orotAxis[3], orotAngle; /* Original object transformation used for rigid bodies */
 } TransDataExtension;
 
 typedef struct TransData2D {

Modified: trunk/blender/source/blender/editors/transform/transform_conversions.c
===================================================================
--- trunk/blender/source/blender/editors/transform/transform_conversions.c	2013-01-23 11:40:35 UTC (rev 54037)
+++ trunk/blender/source/blender/editors/transform/transform_conversions.c	2013-01-23 12:06:18 UTC (rev 54038)
@@ -85,6 +85,7 @@
 #include "BKE_particle.h"
 #include "BKE_pointcache.h"
 #include "BKE_report.h"
+#include "BKE_rigidbody.h"
 #include "BKE_scene.h"
 #include "BKE_sequencer.h"
 #include "BKE_tessmesh.h"
@@ -4541,6 +4542,27 @@
 	short constinv;
 	short skip_invert = 0;
 
+	if (ob->rigidbody_object) {
+		float rot[3][3], scale[3];
+
+		/* save original object transform */
+		copy_v3_v3(td->ext->oloc, ob->loc);
+
+		if (ob->rotmode > 0) {
+			copy_v3_v3(td->ext->orot, ob->rot);
+		}
+		else if (ob->rotmode == ROT_MODE_AXISANGLE) {
+			td->ext->orotAngle = ob->rotAngle;
+			copy_v3_v3(td->ext->orotAxis, ob->rotAxis);
+		}
+		else {
+			copy_qt_qt(td->ext->oquat, ob->quat);
+		}
+		/* update object's loc/rot to get current rigid body transform */
+		mat4_to_loc_rot_size(ob->loc, rot, scale, ob->obmat);
+		BKE_object_mat3_to_rot(ob, rot, FALSE);
+	}
+
 	/* axismtx has the real orientation */
 	copy_m3_m4(td->axismtx, ob->obmat);
 	normalize_m3(td->axismtx);
@@ -5494,6 +5516,9 @@
 				if (ob->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS)
 					recalcObPaths = 1;
 			}
+			/* restore rigid body transform */
+			if (ob->rigidbody_object && canceled)
+				BKE_rigidbody_aftertrans_update(ob, td->ext->oloc, td->ext->orot, td->ext->oquat, td->ext->orotAxis, td->ext->orotAngle);
 		}
 		
 		/* recalculate motion paths for objects (if necessary) 




More information about the Bf-blender-cvs mailing list