[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [56195] trunk/blender: rigidbody: Add function to perform convex sweep test

Sergej Reich sergej.reich at googlemail.com
Sun Apr 21 21:53:41 CEST 2013


Revision: 56195
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=56195
Author:   sergof
Date:     2013-04-21 19:53:40 +0000 (Sun, 21 Apr 2013)
Log Message:
-----------
rigidbody: Add function to perform convex sweep test

This is a experimental collision detection function, so the API might
change in the future.

Note: The simulation needs to be stepped before this function can be
used, otherwise the rigid body world might not be valid.

Patch [#34989]  Bullet Convex sweep test API
by Vilem Novak (pildanovak), thanks!

Modified Paths:
--------------
    trunk/blender/intern/rigidbody/RBI_api.h
    trunk/blender/intern/rigidbody/rb_bullet_api.cpp
    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-04-21 19:04:04 UTC (rev 56194)
+++ trunk/blender/intern/rigidbody/RBI_api.h	2013-04-21 19:53:40 UTC (rev 56195)
@@ -110,6 +110,12 @@
 /* Remove RigidBody from dynamics world */
 extern void RB_dworld_remove_body(rbDynamicsWorld *world, rbRigidBody *body);
 
+/* Collision detection */
+
+void RB_world_convex_sweep_test(rbDynamicsWorld *world, rbRigidBody *object,
+								const float loc_start[3], const float loc_end[3],
+	                            float v_location[3],  float v_hitpoint[3],  float v_normal[3], int *r_hit);
+
 /* ............ */
 
 /* Create new RigidBody instance */

Modified: trunk/blender/intern/rigidbody/rb_bullet_api.cpp
===================================================================
--- trunk/blender/intern/rigidbody/rb_bullet_api.cpp	2013-04-21 19:04:04 UTC (rev 56194)
+++ trunk/blender/intern/rigidbody/rb_bullet_api.cpp	2013-04-21 19:53:40 UTC (rev 56195)
@@ -242,6 +242,56 @@
 	world->dynamicsWorld->removeRigidBody(body);
 }
 
+/* Collision detection */
+
+void RB_world_convex_sweep_test(rbDynamicsWorld *world, rbRigidBody *object, const float loc_start[3], const float loc_end[3], float v_location[3],  float v_hitpoint[3],  float v_normal[3], int *r_hit)
+{
+	btRigidBody *body = object->body;
+	btCollisionShape *collisionShape = body->getCollisionShape();
+	/* only convex shapes are supported, but user can specify a non convex shape */
+	if (collisionShape->isConvex()) {
+		btCollisionWorld::ClosestConvexResultCallback result(btVector3(loc_start[0], loc_start[1], loc_start[2]), btVector3(loc_end[0], loc_end[1], loc_end[2]));
+
+		btQuaternion obRot = body->getWorldTransform().getRotation();
+		
+		btTransform rayFromTrans;
+		rayFromTrans.setIdentity();
+		rayFromTrans.setRotation(obRot);
+		rayFromTrans.setOrigin(btVector3(loc_start[0], loc_start[1], loc_start[2]));
+
+		btTransform rayToTrans;
+		rayToTrans.setIdentity();
+		rayToTrans.setRotation(obRot);
+		rayToTrans.setOrigin(btVector3(loc_end[0], loc_end[1], loc_end[2]));
+		
+		world->dynamicsWorld->convexSweepTest((btConvexShape*) collisionShape, rayFromTrans, rayToTrans, result, 0);
+		
+		if (result.hasHit()) {
+			*r_hit = 1;
+			
+			v_location[0] = result.m_convexFromWorld[0]+(result.m_convexToWorld[0]-result.m_convexFromWorld[0])*result.m_closestHitFraction;
+			v_location[1] = result.m_convexFromWorld[1]+(result.m_convexToWorld[1]-result.m_convexFromWorld[1])*result.m_closestHitFraction;
+			v_location[2] = result.m_convexFromWorld[2]+(result.m_convexToWorld[2]-result.m_convexFromWorld[2])*result.m_closestHitFraction;
+			
+			v_hitpoint[0] = result.m_hitPointWorld[0];
+			v_hitpoint[1] = result.m_hitPointWorld[1];
+			v_hitpoint[2] = result.m_hitPointWorld[2];
+			
+			v_normal[0] = result.m_hitNormalWorld[0];
+			v_normal[1] = result.m_hitNormalWorld[1];
+			v_normal[2] = result.m_hitNormalWorld[2];
+			
+		}
+		else {
+			*r_hit = 0;
+		}
+	}
+	else{
+		/* we need to return a value if user passes non convex body, to report */
+		*r_hit = -2;
+	}
+}
+
 /* ............ */
 
 rbRigidBody *RB_body_new(rbCollisionShape *shape, const float loc[3], const float rot[4])

Modified: trunk/blender/source/blender/makesrna/intern/rna_rigidbody.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/rna_rigidbody.c	2013-04-21 19:04:04 UTC (rev 56194)
+++ trunk/blender/source/blender/makesrna/intern/rna_rigidbody.c	2013-04-21 19:53:40 UTC (rev 56195)
@@ -594,14 +594,33 @@
 #endif
 }
 
+/* Sweep test */
+static void rna_RigidBodyWorld_convex_sweep_test(RigidBodyWorld *rbw, ReportList *reports, Object *object,  float ray_start[3], float ray_end[3], float r_location[3], float r_hitpoint[3], float r_normal[3], int *r_hit)
+{
+#ifdef WITH_BULLET
+	RigidBodyOb *rob = object->rigidbody_object;
 
+	if (rbw->physics_world != NULL && rob->physics_object != NULL) {
+		RB_world_convex_sweep_test(rbw->physics_world, rob->physics_object, ray_start, ray_end, r_location, r_hitpoint, r_normal, r_hit);
+		if (*r_hit == -2) {
+			BKE_report(reports, RPT_ERROR, "A non convex collision shape was passed to the function. Use only convex collision shapes.");
+		}
+	}
+	else {
+		*r_hit=-1;
+		BKE_report(reports, RPT_ERROR, "Rigidbody world was not properly initialized, need to step the simulation first");
+	}
+#endif
+}
+
 #else
 
 static void rna_def_rigidbody_world(BlenderRNA *brna)
 {
 	StructRNA *srna;
 	PropertyRNA *prop;
-	
+	FunctionRNA *func;
+
 	srna = RNA_def_struct(brna, "RigidBodyWorld", NULL);
 	RNA_def_struct_sdna(srna, "RigidBodyWorld");
 	RNA_def_struct_ui_text(srna, "Rigid Body World", "Self-contained rigid body simulation environment and settings");
@@ -678,6 +697,39 @@
 	RNA_def_property_struct_type(prop, "EffectorWeights");
 	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
 	RNA_def_property_ui_text(prop, "Effector Weights", "");
+
+	/* Sweep test */
+	func = RNA_def_function(srna, "convex_sweep_test", "rna_RigidBodyWorld_convex_sweep_test");
+	RNA_def_function_ui_description(func, "Sweep test convex rigidbody against the current rigidbody world");
+	RNA_def_function_flag(func, FUNC_USE_REPORTS);
+
+	prop = RNA_def_pointer(func, "object", "Object", "", "Rigidbody object with a convex collision shape");
+	RNA_def_property_flag(prop, PROP_REQUIRED | PROP_NEVER_NULL);
+	RNA_def_property_clear_flag(prop, PROP_THICK_WRAP);
+
+	/* ray start and end */
+	prop = RNA_def_float_vector(func, "start", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
+	RNA_def_property_flag(prop, PROP_REQUIRED);
+	prop = RNA_def_float_vector(func, "end", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
+	RNA_def_property_flag(prop, PROP_REQUIRED);
+
+	prop = RNA_def_float_vector(func, "object_location", 3, NULL, -FLT_MAX, FLT_MAX, "Location",
+								"The hit location of this sweep test", -1e4, 1e4);
+	RNA_def_property_flag(prop, PROP_THICK_WRAP);
+	RNA_def_function_output(func, prop);
+
+	prop = RNA_def_float_vector(func, "hitpoint", 3, NULL, -FLT_MAX, FLT_MAX, "Hitpoint",
+								"The hit location of this sweep test", -1e4, 1e4);
+	RNA_def_property_flag(prop, PROP_THICK_WRAP);
+	RNA_def_function_output(func, prop);
+
+	prop = RNA_def_float_vector(func, "normal", 3, NULL, -FLT_MAX, FLT_MAX, "Normal",
+								"The face normal at the sweep test hit location", -1e4, 1e4);
+	RNA_def_property_flag(prop, PROP_THICK_WRAP);
+	RNA_def_function_output(func, prop);
+
+	prop = RNA_def_int(func, "has_hit", 0, 0, 0, "", "If the function has found collision point, value is 1, otherwise 0", 0, 0);
+	RNA_def_function_output(func, prop);
 }
 
 static void rna_def_rigidbody_object(BlenderRNA *brna)




More information about the Bf-blender-cvs mailing list