[Bf-blender-cvs] [4abbd80] hair_system: New memory management system for Bullet rigid bodies and some code reorganization.

Lukas Tönne noreply at git.blender.org
Fri Aug 1 16:42:11 CEST 2014


Commit: 4abbd806d312760eff6d5c00430dbe3f196ebe1e
Author: Lukas Tönne
Date:   Fri Aug 1 12:53:23 2014 +0200
Branches: hair_system
https://developer.blender.org/rB4abbd806d312760eff6d5c00430dbe3f196ebe1e

New memory management system for Bullet rigid bodies and some code
reorganization.

Bullet leaves the allocation and setup of rigid bodies up to the caller
code. Our current system allocates btRigidBody structs (respectively
the extended rbRigidBody wrapper struct) one-by-one. Deleting this
data and other lifetime data management is the domain of Objects and
their rigid body components.

This behavior is fine as long as only persistent objects in the DNA data
populate the RigidBodyWorld. However, for utilizing Bullet for other
collision types (hair, particles) and more on-the-fly rigid body changes
this model does not work well. Updating the rigid body world,
registering/unregistering rigid bodies, keeping track of constraint
references etc. becomes really difficult.

The patch implements a memory pool for rigid bodies, which allows
preallocating rigid body data for massive simulations. The lifetime of
rigid bodies is also disconnected from Object data, so that simulations
can use rigid bodies for data that is dynamically created and destroyed
without having to worry about dangling pointers so much.

The same principles should be applied to constraint data and collision
shapes eventually, but rigid bodies are the most critical.

Separation of concerns: Moved functions for building object rigid bodies
and applying Bullet results to them into a dedicated file. The same
should happen for hair, particles, and any other Bullet users later.
Purpose is to keep the main Bullet world API limited to dealing with
Bullet primarily and avoid fixating it on Object DNA data.

Cleanup: Renamed a number of internal rigidbody functions to clarify
the procedure:

  world_build:  create rbRigidBody instances for stuff in Scene
  validate_*:   ensure a rbRigidBody exists for an Object/particle/etc.
  sync_*:       define Bullet settings for an Object/particle/etc. based
                on Blender Scene data
  world_apply:  copy back data from Bullet after a step to the Blender
                Scene data

===================================================================

M	intern/rigidbody/RBI_api.h
M	intern/rigidbody/rb_bullet_api.cpp
M	source/blender/blenkernel/BKE_rigidbody.h
M	source/blender/blenkernel/CMakeLists.txt
M	source/blender/blenkernel/intern/object.c
M	source/blender/blenkernel/intern/rigidbody.c
A	source/blender/blenkernel/intern/rigidbody_objects.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/writefile.c
M	source/blender/editors/transform/transform_conversions.c
M	source/blender/makesdna/DNA_rigidbody_types.h
M	source/blender/makesrna/intern/rna_rigidbody.c

===================================================================

diff --git a/intern/rigidbody/RBI_api.h b/intern/rigidbody/RBI_api.h
index 47e12f6..58653c5 100644
--- a/intern/rigidbody/RBI_api.h
+++ b/intern/rigidbody/RBI_api.h
@@ -37,6 +37,8 @@
 extern "C" {
 #endif
 
+#include <string.h>
+
 /* API Notes:
  * Currently, this API is optimised for Bullet RigidBodies, and doesn't
  * take into account other Physics Engines. Some tweaking may be necessary
@@ -56,6 +58,7 @@ typedef struct rbDynamicsWorld rbDynamicsWorld;
 
 /* Rigid Body */
 typedef struct rbRigidBody rbRigidBody;
+extern size_t rbRigidBodySize;
 
 /* Collision Shape */
 typedef struct rbCollisionShape rbCollisionShape;
@@ -124,10 +127,10 @@ void RB_world_convex_sweep_test(
 /* ............ */
 
 /* Create new RigidBody instance */
-rbRigidBody *RB_body_new(rbCollisionShape *shape, const float loc[3], const float rot[4]);
+void RB_body_init(rbRigidBody *object, rbCollisionShape *shape, const float loc[3], const float rot[4]);
 
 /* Delete the given RigidBody instance */
-void RB_body_delete(rbRigidBody *body);
+void RB_body_free(rbRigidBody *object);
 
 /* Settings ------------------------- */
 
@@ -141,6 +144,11 @@ void RB_body_set_collision_shape(rbRigidBody *body, rbCollisionShape *shape);
 
 /* ............ */
 
+/* Generic flagging */
+extern int RB_body_get_flags(rbRigidBody *body);
+extern void RB_body_set_flag(rbRigidBody *body, int flag);
+extern void RB_body_clear_flag(rbRigidBody *body, int flag);
+
 /* Mass */
 float RB_body_get_mass(rbRigidBody *body);
 void RB_body_set_mass(rbRigidBody *body, float value);
diff --git a/intern/rigidbody/rb_bullet_api.cpp b/intern/rigidbody/rb_bullet_api.cpp
index 5d194a7..f1d135b 100644
--- a/intern/rigidbody/rb_bullet_api.cpp
+++ b/intern/rigidbody/rb_bullet_api.cpp
@@ -81,11 +81,23 @@ struct rbDynamicsWorld {
 	btConstraintSolver *constraintSolver;
 	btOverlapFilterCallback *filterCallback;
 };
+
 struct rbRigidBody {
-	btRigidBody *body;
+	rbRigidBody(const btRigidBody::btRigidBodyConstructionInfo& constructionInfo) :
+	    body(constructionInfo),
+	    col_groups(0),
+	    flag(0)
+	{}
+	~rbRigidBody()
+	{}
+	
+	btRigidBody body;
 	int col_groups;
+	int flag;
 };
 
+size_t rbRigidBodySize = sizeof(rbRigidBody);
+
 struct rbVert {
 	float x, y, z;
 };
@@ -275,7 +287,7 @@ void RB_dworld_export(rbDynamicsWorld *world, const char *filename)
 
 void RB_dworld_add_body(rbDynamicsWorld *world, rbRigidBody *object, int col_groups)
 {
-	btRigidBody *body = object->body;
+	btRigidBody *body = &object->body;
 	object->col_groups = col_groups;
 	
 	world->dynamicsWorld->addRigidBody(body);
@@ -283,7 +295,7 @@ void RB_dworld_add_body(rbDynamicsWorld *world, rbRigidBody *object, int col_gro
 
 void RB_dworld_remove_body(rbDynamicsWorld *world, rbRigidBody *object)
 {
-	btRigidBody *body = object->body;
+	btRigidBody *body = &object->body;
 	
 	world->dynamicsWorld->removeRigidBody(body);
 }
@@ -295,7 +307,7 @@ void RB_world_convex_sweep_test(
         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;
+	btRigidBody *body = &object->body;
 	btCollisionShape *collisionShape = body->getCollisionShape();
 	/* only convex shapes are supported, but user can specify a non convex shape */
 	if (collisionShape->isConvex()) {
@@ -343,9 +355,8 @@ void RB_world_convex_sweep_test(
 
 /* ............ */
 
-rbRigidBody *RB_body_new(rbCollisionShape *shape, const float loc[3], const float rot[4])
+void RB_body_init(rbRigidBody *object, rbCollisionShape *shape, const float loc[3], const float rot[4])
 {
-	rbRigidBody *object = new rbRigidBody;
 	/* current transform */
 	btTransform trans;
 	trans.setOrigin(btVector3(loc[0], loc[1], loc[2]));
@@ -354,19 +365,16 @@ rbRigidBody *RB_body_new(rbCollisionShape *shape, const float loc[3], const floa
 	/* create motionstate, which is necessary for interpolation (includes reverse playback) */
 	btDefaultMotionState *motionState = new btDefaultMotionState(trans);
 	
-	/* make rigidbody */
 	btRigidBody::btRigidBodyConstructionInfo rbInfo(1.0f, motionState, shape->cshape);
 	
-	object->body = new btRigidBody(rbInfo);
-	
-	object->body->setUserPointer(object);
-	
-	return object;
+	/* make rigidbody, using placement new to initialize given memory buffer */
+	new (object) rbRigidBody(rbInfo);
+	object->body.setUserPointer(object);
 }
 
-void RB_body_delete(rbRigidBody *object)
+void RB_body_free(rbRigidBody *object)
 {
-	btRigidBody *body = object->body;
+	btRigidBody *body = &object->body;
 	
 	/* motion state */
 	btMotionState *ms = body->getMotionState();
@@ -384,15 +392,15 @@ void RB_body_delete(rbRigidBody *object)
 		body->removeConstraintRef(con);
 	}
 	
-	delete body;
-	delete object;
+	/* only call destructor, memory management happens externally */
+	object->~rbRigidBody();
 }
 
 /* Settings ------------------------- */
 
 void RB_body_set_collision_shape(rbRigidBody *object, rbCollisionShape *shape)
 {
-	btRigidBody *body = object->body;
+	btRigidBody *body = &object->body;
 	
 	/* set new collision shape */
 	body->setCollisionShape(shape->cshape);
@@ -403,9 +411,24 @@ void RB_body_set_collision_shape(rbRigidBody *object, rbCollisionShape *shape)
 
 /* ............ */
 
+int RB_body_get_flags(rbRigidBody *body)
+{
+	return body->flag;
+}
+
+void RB_body_set_flag(rbRigidBody *body, int flag)
+{
+	body->flag |= flag;
+}
+
+void RB_body_clear_flag(rbRigidBody *body, int flag)
+{
+	body->flag &= ~flag;
+}
+
 float RB_body_get_mass(rbRigidBody *object)
 {
-	btRigidBody *body = object->body;
+	btRigidBody *body = &object->body;
 	
 	/* there isn't really a mass setting, but rather 'inverse mass'  
 	 * which we convert back to mass by taking the reciprocal again 
@@ -420,7 +443,7 @@ float RB_body_get_mass(rbRigidBody *object)
 
 void RB_body_set_mass(rbRigidBody *object, float value)
 {
-	btRigidBody *body = object->body;
+	btRigidBody *body = &object->body;
 	btVector3 localInertia(0, 0, 0);
 	
 	/* calculate new inertia if non-zero mass */
@@ -436,33 +459,33 @@ void RB_body_set_mass(rbRigidBody *object, float value)
 
 float RB_body_get_friction(rbRigidBody *object)
 {
-	btRigidBody *body = object->body;
+	btRigidBody *body = &object->body;
 	return body->getFriction();
 }
 
 void RB_body_set_friction(rbRigidBody *object, float value)
 {
-	btRigidBody *body = object->body;
+	btRigidBody *body = &object->body;
 	body->setFriction(value);
 }
 
 
 float RB_body_get_restitution(rbRigidBody *object)
 {
-	btRigidBody *body = object->body;
+	btRigidBody *body = &object->body;
 	return body->getRestitution();
 }
 
 void RB_body_set_restitution(rbRigidBody *object, float value)
 {
-	btRigidBody *body = object->body;
+	btRigidBody *body = &object->body;
 	body->setRestitution(value);
 }
 
 
 float RB_body_get_linear_damping(rbRigidBody *object)
 {
-	btRigidBody *body = object->body;
+	btRigidBody *body = &object->body;
 	return body->getLinearDamping();
 }
 
@@ -473,7 +496,7 @@ void RB_body_set_linear_damping(rbRigidBody *object, float value)
 
 float RB_body_get_angular_damping(rbRigidBody *object)
 {
-	btRigidBody *body = object->body;
+	btRigidBody *body = &object->body;
 	return body->getAngularDamping();
 }
 
@@ -484,14 +507,14 @@ void RB_body_set_angular_damping(rbRigidBody *object, float value)
 
 void RB_body_set_damping(rbRigidBody *object, float linear, float angular)
 {
-	btRigidBody *body = object->body;
+	btRigidBody *body = &object->body;
 	body->setDamping(linear, angular);
 }
 
 
 float RB_body_get_linear_sleep_thresh(rbRigidBody *object)
 {
-	btRigidBody *body = object->body;
+	btRigidBody *body = &object->body;
 	return body->getLinearSleepingThreshold();
 }
 
@@ -502,7 +525,7 @@ void RB_body_set_linear_sleep_thresh(rbRigidBody *object, float value)
 
 float RB_body_get_angular_sleep_thresh(rbRigidBody *object)
 {
-	btRigidBody *body = object->body;
+	btRigidBody *body = &object->body;
 	return body->getAngularSleepingThreshold();
 }
 
@@ -513,7 +536,7 @@ void RB_body_set_angular_sleep_thresh(rbRigidBody *object, float value)
 
 void RB_body_set_sleep_thresh(rbRigidBody *object, float linear, float angular)
 {
-	btRigidBody *body = object->body;
+	btRigidBody *body = &object->body;
 	body->setSleepingThresholds(linear, angular);
 }
 
@@ -521,14 +544,14 @@ void RB_body_set_sleep_thresh(rbRigidBody *object, float linear, float angular)
 
 void RB_body_get_linear_velocity(rbRigidBody *object, float v_out[3])
 {
-	btRigidBody *body = object->body;
+	btRigidBody *body = &object->body;
 	
 	copy_v3_btvec3(v_out, body->getLinearVelocity());
 }
 
 void RB_body_set_linear_velocity(rbRigidBody *object, const float v_in[3])
 {
-	btRigidBody *body = object->body;
+	btRigidBody *body = &object->body;
 	
 	body->setLinearVelocity(btVector3(v_in[0], v_in[1], v_in[2]));
 }
@@ -536,27 +559,27 @@ void RB_body_set_linear_velocity(rbRigidBody *object, const float v_in[3])
 
 void RB_body_get_angular_velocity(rbRigidBody *object, float v_out[3])
 {
-	btRigidBody *body = object->body;
+	btRigidBody *body = &object->body;
 	
 	copy_v3_btvec3(v_out, body->getAngularVelocity());
 }
 
 void RB_body_set_angular_velocity(rbRigidBody *object, const float v_in[3])
 {
-	btRigidBody *body = object->body;
+	btRigidBody *body = &object->body;
 	
 	body->setAngularVelocity(btVector3(v_in[0], v_in[1], v_in[2]));
 }
 
 void RB_body_set_linear_factor(rbRigidBody *object, float x, float y, float z)
 {
-	btRigidBody *body = object->body;
+	btRigidBody *body = &object->body;
 	body->setLinearFactor(btVector3(x, y, z));
 }
 
 void RB_body_set_angular_factor(rbRigidBody *object, float x, float y, float z)
 {
-	btRigidBody *body = object->body;
+	btRigidBody *body = &object->body;
 	body->setAngularFactor(btVector3(x, y, z));
 }
 
@@ -564,7 +587,7 @@ void RB_body_set_angular_factor(rbRigidBody *object, float x, float y, float z)
 
 void RB_body_set_kinematic_state(rbRigidBody *object, int kinematic)
 {
-	btRigidBody *body = object->body;
+	btRigidBody *body = &object->body;
 	if (kinematic)
 		body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
 	else
@@ -575,7 +598,7 @@ void RB_body_set_kinematic_state(rbRigidBody *object, int kinematic)
 
 void RB_bo

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list