[Bf-blender-cvs] [48668d8] temp_bullet_ghosts: Support for btGhostObjects in the Bullet API.

Lukas Tönne noreply at git.blender.org
Wed Apr 29 09:08:02 CEST 2015


Commit: 48668d821c3bae4638edac2b2072f190016923d1
Author: Lukas Tönne
Date:   Tue Dec 30 11:35:35 2014 +0100
Branches: temp_bullet_ghosts
https://developer.blender.org/rB48668d821c3bae4638edac2b2072f190016923d1

Support for btGhostObjects in the Bullet API.

Ghost objects are pure collision objects that have no effect on rigid
bodies, but can be used to hook into the collision detection of Bullet.

This way Blender can utilize the optimized collision detection in Bullet
as well as its contact caching, which is necessary for stable collision
response in many softbody-type algorithms that implement Coulomb
friction cones.

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

M	intern/rigidbody/RBI_api.h
M	intern/rigidbody/rb_bullet_api.cpp

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

diff --git a/intern/rigidbody/RBI_api.h b/intern/rigidbody/RBI_api.h
index d464154..607617c 100644
--- a/intern/rigidbody/RBI_api.h
+++ b/intern/rigidbody/RBI_api.h
@@ -57,6 +57,9 @@ typedef struct rbDynamicsWorld rbDynamicsWorld;
 /* Rigid Body */
 typedef struct rbRigidBody rbRigidBody;
 
+/* Ghost Collision Object */
+typedef struct rbGhostObject rbGhostObject;
+
 /* Collision Shape */
 typedef struct rbCollisionShape rbCollisionShape;
 
@@ -190,7 +193,6 @@ void RB_body_set_activation_state(rbRigidBody *body, int use_deactivation);
 void RB_body_activate(rbRigidBody *body);
 void RB_body_deactivate(rbRigidBody *body);
 
-
 /* Simulation ----------------------- */
 
 /* Get current transform matrix of RigidBody to use in Blender (OpenGL format) */
@@ -213,6 +215,27 @@ void RB_body_get_orientation(rbRigidBody *body, float v_out[4]);
 void RB_body_apply_central_force(rbRigidBody *body, const float v_in[3]);
 
 /* ********************************** */
+/* Ghost Collision Object Methods */
+
+/* Add ghost to dynamics world */
+void RB_dworld_add_ghost(rbDynamicsWorld *world, rbGhostObject *ghost, int col_groups);
+/* Remove ghost from dynamics world */
+void RB_dworld_remove_ghost(rbDynamicsWorld *world, rbGhostObject *ghost);
+
+/* Create new ghost instance */
+rbGhostObject *RB_ghost_new(rbCollisionShape *shape, const float loc[3], const float rot[4]);
+/* Delete the given ghost instance */
+void RB_ghost_delete(rbGhostObject *ghost);
+
+/* Collision Shape */
+void RB_ghost_set_collision_shape(rbGhostObject *body, rbCollisionShape *shape);
+
+/* Transform */
+void RB_ghost_get_transform_matrix(rbGhostObject *object, float m_out[4][4]);
+void RB_ghost_set_loc_rot(rbGhostObject *object, const float loc[3], const float rot[4]);
+void RB_ghost_set_scale(rbGhostObject *object, const float scale[3]);
+
+/* ********************************** */
 /* Collision Shape Methods */
 
 /* Setup (Standard Shapes) ----------- */
diff --git a/intern/rigidbody/rb_bullet_api.cpp b/intern/rigidbody/rb_bullet_api.cpp
index 3cc39e6..fc264f6 100644
--- a/intern/rigidbody/rb_bullet_api.cpp
+++ b/intern/rigidbody/rb_bullet_api.cpp
@@ -69,6 +69,7 @@ subject to the following restrictions:
 #include "LinearMath/btTransform.h"
 #include "LinearMath/btConvexHullComputer.h"
 
+#include "BulletCollision/CollisionDispatch/btGhostObject.h"
 #include "BulletCollision/Gimpact/btGImpactShape.h"
 #include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h"
 #include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h"
@@ -81,9 +82,20 @@ struct rbDynamicsWorld {
 	btConstraintSolver *constraintSolver;
 	btOverlapFilterCallback *filterCallback;
 };
+
+/* common base for safe casting of user pointers in btCollisionObjects */
+struct rbCollisionObject {
+	int col_groups;
+};
+
 struct rbRigidBody {
+	rbCollisionObject base;
 	btRigidBody *body;
-	int col_groups;
+};
+
+struct rbGhostObject {
+	rbCollisionObject base;
+	btGhostObject *ghost;
 };
 
 struct rbVert {
@@ -110,8 +122,8 @@ struct rbFilterCallback : public btOverlapFilterCallback
 {
 	virtual bool needBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const
 	{
-		rbRigidBody *rb0 = (rbRigidBody *)((btRigidBody *)proxy0->m_clientObject)->getUserPointer();
-		rbRigidBody *rb1 = (rbRigidBody *)((btRigidBody *)proxy1->m_clientObject)->getUserPointer();
+		rbCollisionObject *rb0 = (rbCollisionObject *)((btCollisionObject *)proxy0->m_clientObject)->getUserPointer();
+		rbCollisionObject *rb1 = (rbCollisionObject *)((btCollisionObject *)proxy1->m_clientObject)->getUserPointer();
 		
 		bool collides;
 		collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
@@ -258,7 +270,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;
-	object->col_groups = col_groups;
+	object->base.col_groups = col_groups;
 	
 	world->dynamicsWorld->addRigidBody(body);
 }
@@ -576,8 +588,6 @@ void RB_body_deactivate(rbRigidBody *object)
 
 /* ............ */
 
-
-
 /* Simulation ----------------------- */
 
 /* The transform matrices Blender uses are OpenGL-style matrices, 
@@ -651,6 +661,84 @@ void RB_body_apply_central_force(rbRigidBody *object, const float v_in[3])
 }
 
 /* ********************************** */
+/* Ghost Collision Object Methods */
+
+void RB_dworld_add_ghost(rbDynamicsWorld *world, rbGhostObject *object, int col_groups)
+{
+	object->base.col_groups = col_groups;
+	
+	world->dynamicsWorld->addCollisionObject(object->ghost);
+}
+
+void RB_dworld_remove_ghost(rbDynamicsWorld *world, rbGhostObject *object)
+{
+	world->dynamicsWorld->removeCollisionObject(object->ghost);
+}
+
+rbGhostObject *RB_ghost_new(rbCollisionShape *shape, const float loc[3], const float rot[4])
+{
+	rbGhostObject *object = new rbGhostObject;
+	
+	object->ghost = new btGhostObject();
+	object->ghost->setUserPointer(object);
+	
+	object->ghost->setCollisionShape(shape->cshape);
+	
+	btTransform trans;
+	trans.setOrigin(btVector3(loc[0], loc[1], loc[2]));
+	trans.setRotation(btQuaternion(rot[1], rot[2], rot[3], rot[0]));
+	object->ghost->setWorldTransform(trans);
+	
+	return object;
+}
+
+void RB_ghost_delete(rbGhostObject *object)
+{
+	delete object->ghost;
+	delete object;
+}
+
+void RB_ghost_set_collision_shape(rbGhostObject *body, rbCollisionShape *shape)
+{
+	body->ghost->setCollisionShape(shape->cshape);
+}
+
+void RB_ghost_get_transform_matrix(rbGhostObject *object, float m_out[4][4])
+{
+	btGhostObject *ghost = object->ghost;
+	
+	btTransform trans = ghost->getWorldTransform();
+	trans.getOpenGLMatrix((btScalar *)m_out);
+}
+
+void RB_ghost_set_loc_rot(rbGhostObject *object, const float loc[3], const float rot[4])
+{
+	btGhostObject *ghost = object->ghost;
+	
+	/* set transform matrix */
+	btTransform trans;
+	trans.setOrigin(btVector3(loc[0], loc[1], loc[2]));
+	trans.setRotation(btQuaternion(rot[1], rot[2], rot[3], rot[0]));
+	
+	ghost->setWorldTransform(trans);
+}
+
+void RB_ghost_set_scale(rbGhostObject *object, const float scale[3])
+{
+	btGhostObject *ghost = object->ghost;
+	
+	/* apply scaling factor from matrix above to the collision shape */
+	btCollisionShape *cshape = ghost->getCollisionShape();
+	if (cshape) {
+		cshape->setLocalScaling(btVector3(scale[0], scale[1], scale[2]));
+		
+		/* GIimpact shapes have to be updated to take scaling into account */
+		if (cshape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE)
+			((btGImpactMeshShape *)cshape)->updateBound();
+	}
+}
+
+/* ********************************** */
 /* Collision Shape Methods */
 
 /* Setup (Standard Shapes) ----------- */




More information about the Bf-blender-cvs mailing list