[Bf-blender-cvs] [d4396ea] hair_system: Simple hair contact point debugging using a ghost object per hair point.

Lukas Tönne noreply at git.blender.org
Mon Aug 4 16:18:56 CEST 2014


Commit: d4396ea29d5d97724a9b1d4ec3f41bd35c7ed18c
Author: Lukas Tönne
Date:   Mon Aug 4 14:38:25 2014 +0200
Branches: hair_system
https://developer.blender.org/rBd4396ea29d5d97724a9b1d4ec3f41bd35c7ed18c

Simple hair contact point debugging using a ghost object per hair point.

The rbDynamicsWorld is now also exposed in the types header for the RBI
API, because currently we need direct access to some Bullet properties.

User pointers for collision objects now point to a generic
rbCollisionObject base class, so we don't run into trouble when
explicitly casting to rbRigidBody.

Points can not be copied explicitly any more, because it makes internal
point variables invalid that are hard to track. Bullet itself also does
not like direct copies of btRigidBody ...

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

M	intern/rigidbody/rb_bullet_api.cpp
M	intern/rigidbody/rb_internal_types.h
M	source/blender/blenloader/intern/readfile.c
M	source/blender/hair/HAIR_capi.cpp
M	source/blender/hair/intern/HAIR_curve.cpp
M	source/blender/hair/intern/HAIR_curve.h
M	source/blender/hair/intern/HAIR_scene.cpp
M	source/blender/hair/intern/HAIR_solver.cpp
M	source/blender/hair/intern/HAIR_solver.h

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

diff --git a/intern/rigidbody/rb_bullet_api.cpp b/intern/rigidbody/rb_bullet_api.cpp
index 2fdb0e8..2b79d4d 100644
--- a/intern/rigidbody/rb_bullet_api.cpp
+++ b/intern/rigidbody/rb_bullet_api.cpp
@@ -79,15 +79,6 @@ subject to the following restrictions:
 const size_t rbRigidBodySize = sizeof(rbRigidBody);
 const size_t rbGhostObjectSize = sizeof(rbGhostObject);
 
-struct rbDynamicsWorld {
-	btDiscreteDynamicsWorld *dynamicsWorld;
-	btDefaultCollisionConfiguration *collisionConfiguration;
-	btDispatcher *dispatcher;
-	btBroadphaseInterface *pairCache;
-	btConstraintSolver *constraintSolver;
-	btOverlapFilterCallback *filterCallback;
-};
-
 struct rbVert {
 	float x, y, z;
 };
@@ -112,13 +103,13 @@ 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 *ob0 = (rbCollisionObject *)((btCollisionObject *)proxy0->m_clientObject)->getUserPointer();
+		rbCollisionObject *ob1 = (rbCollisionObject *)((btCollisionObject *)proxy1->m_clientObject)->getUserPointer();
 		
 		bool collides;
 		collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
 		collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
-		collides = collides && (rb0->col_groups & rb1->col_groups);
+		collides = collides && (ob0->col_groups & ob1->col_groups);
 		
 		return collides;
 	}
@@ -157,6 +148,8 @@ rbDynamicsWorld *RB_dworld_new(const float gravity[3])
 	
 	world->filterCallback = new rbFilterCallback();
 	world->pairCache->getOverlappingPairCache()->setOverlapFilterCallback(world->filterCallback);
+	world->ghostPairCallback = new btGhostPairCallback();
+	world->pairCache->getOverlappingPairCache()->setInternalGhostPairCallback(world->ghostPairCallback);
 
 	/* constraint solving */
 	world->constraintSolver = new btSequentialImpulseConstraintSolver();
@@ -181,6 +174,7 @@ void RB_dworld_delete(rbDynamicsWorld *world)
 	delete world->dispatcher;
 	delete world->collisionConfiguration;
 	delete world->filterCallback;
+	delete world->ghostPairCallback;
 	delete world;
 }
 
@@ -295,7 +289,7 @@ void RB_dworld_add_ghost(rbDynamicsWorld *world, rbGhostObject *object, int col_
 	btGhostObject *ghost = &object->ghost;
 	object->col_groups = col_groups;
 	
-	world->dynamicsWorld->addCollisionObject(ghost);
+	world->dynamicsWorld->addCollisionObject(ghost, btBroadphaseProxy::AllFilter, btBroadphaseProxy::AllFilter);
 }
 
 void RB_dworld_remove_ghost(rbDynamicsWorld *world, rbGhostObject *object)
@@ -374,7 +368,6 @@ void RB_body_init(rbRigidBody *object, rbCollisionShape *shape, const float loc[
 	
 	/* make rigidbody, using placement new to initialize given memory buffer */
 	new (object) rbRigidBody(rbInfo);
-	object->body.setUserPointer(object);
 }
 
 void RB_body_free(rbRigidBody *object)
@@ -412,7 +405,6 @@ void RB_ghost_init(rbGhostObject *object, rbCollisionShape *shape, const float l
 	
 	/* make rigidbody, using placement new to initialize given memory buffer */
 	new (object) rbGhostObject();
-	object->ghost.setUserPointer(object);
 	
 	object->ghost.setWorldTransform(trans);
 }
diff --git a/intern/rigidbody/rb_internal_types.h b/intern/rigidbody/rb_internal_types.h
index 8acf9f1..6375be7 100644
--- a/intern/rigidbody/rb_internal_types.h
+++ b/intern/rigidbody/rb_internal_types.h
@@ -36,32 +36,60 @@
 #include "btBulletDynamicsCommon.h"
 #include "BulletCollision/CollisionDispatch/btGhostObject.h"
 
-struct rbRigidBody {
+struct rbDynamicsWorld {
+	btDiscreteDynamicsWorld *dynamicsWorld;
+	btDefaultCollisionConfiguration *collisionConfiguration;
+	btDispatcher *dispatcher;
+	btBroadphaseInterface *pairCache;
+	btConstraintSolver *constraintSolver;
+	btOverlapFilterCallback *filterCallback;
+	btGhostPairCallback *ghostPairCallback;
+};
+
+/* Common extra group info for collision objects */
+struct rbCollisionObject {
+	rbCollisionObject(int col_groups = 0) :
+	    col_groups(col_groups)
+	{}
+	
+	int col_groups;
+};
+
+struct rbRigidBody : rbCollisionObject {
 	rbRigidBody(const btRigidBody::btRigidBodyConstructionInfo& constructionInfo) :
+	    rbCollisionObject(0),
 	    body(constructionInfo),
-	    col_groups(0),
 	    flag(0)
-	{}
+	{
+		body.setUserPointer(this);
+	}
+	
 	~rbRigidBody()
 	{}
 	
 	btRigidBody body;
-	int col_groups;
 	int flag;
 };
 
-struct rbGhostObject {
+struct rbGhostObject : rbCollisionObject {
 	rbGhostObject() :
+	    rbCollisionObject(0),
 	    ghost(),
-	    col_groups(0),
 	    flag(0)
-	{}
+	{
+		ghost.setUserPointer(this);
+	}
+	
 	~rbGhostObject()
 	{}
 	
-	btGhostObject ghost;
-	int col_groups;
+	btPairCachingGhostObject ghost;
 	int flag;
+	
+private:
+	/* non-copyable */
+	rbGhostObject(const rbGhostObject &) {}
+	rbGhostObject& operator = (const rbGhostObject &) { return *this; }
 };
 
 #endif /* __RB_TYPES_H__ */
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 71fc2ae..2e8a348 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -4864,6 +4864,9 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
 				direct_link_hair_system(fd, hmd->hairsys);
 
 			hmd->solver = NULL;
+
+			hmd->debug_contacts = NULL;
+			hmd->debug_totcontacts = 0;
 		}
 	}
 }
diff --git a/source/blender/hair/HAIR_capi.cpp b/source/blender/hair/HAIR_capi.cpp
index 08141de..a703131 100644
--- a/source/blender/hair/HAIR_capi.cpp
+++ b/source/blender/hair/HAIR_capi.cpp
@@ -80,7 +80,7 @@ void HAIR_solver_build_data(struct HAIR_Solver *csolver, Scene *scene, Object *o
 	
 	if (world) {
 		// XXX col_groups ?
-		data->add_to_world(world, 0);
+		data->add_to_world(world, 0xFFFFFFFF);
 	}
 }
 
diff --git a/source/blender/hair/intern/HAIR_curve.cpp b/source/blender/hair/intern/HAIR_curve.cpp
index 75e547f..39f44ad 100644
--- a/source/blender/hair/intern/HAIR_curve.cpp
+++ b/source/blender/hair/intern/HAIR_curve.cpp
@@ -48,28 +48,6 @@ Point::Point(const float3 &rest_co) :
 	rb_ghost.ghost.setCollisionShape(&bt_shape);
 }
 
-Point::Point(const Point &other) :
-    bt_shape(1.0f)
-{
-	*this = other;
-}
-
-Point &Point::operator = (const Point &other)
-{
-	rest_co = other.rest_co;
-	rest_bend = other.rest_bend;
-	
-	cur = other.cur;
-	next = other.next;
-	
-	rb_ghost = other.rb_ghost;
-	bt_shape = other.bt_shape;
-	/* assign new collision shape */
-	rb_ghost.ghost.setCollisionShape(&bt_shape);
-	
-	return *this;
-}
-
 Curve::Curve(int totpoints, Point *points) :
     points(points),
     totpoints(totpoints)
diff --git a/source/blender/hair/intern/HAIR_curve.h b/source/blender/hair/intern/HAIR_curve.h
index 082c0c0..95d0b68 100644
--- a/source/blender/hair/intern/HAIR_curve.h
+++ b/source/blender/hair/intern/HAIR_curve.h
@@ -49,9 +49,6 @@ struct Point {
 	
 	Point();
 	Point(const float3 &rest_co);
-	Point(const Point &other);
-	
-	Point &operator = (const Point &other);
 	
 	State cur;
 	State next;
diff --git a/source/blender/hair/intern/HAIR_scene.cpp b/source/blender/hair/intern/HAIR_scene.cpp
index 7b1ba55..3171ff2 100644
--- a/source/blender/hair/intern/HAIR_scene.cpp
+++ b/source/blender/hair/intern/HAIR_scene.cpp
@@ -93,7 +93,7 @@ SolverData *SceneConverter::build_solver_data(Scene *scene, Object *ob, DerivedM
 		for (int k = 0; k < hair->totpoints; ++k, ++point) {
 			HairPoint *hair_pt = hair->points + k;
 			
-			*point = Point(transform_point(mat, hair_pt->rest_co));
+			point->rest_co = transform_point(mat, hair_pt->rest_co);
 			point->cur.co = transform_point(mat, hair_pt->co);
 			point->cur.vel = transform_direction(mat, hair_pt->vel);
 		}
diff --git a/source/blender/hair/intern/HAIR_solver.cpp b/source/blender/hair/intern/HAIR_solver.cpp
index bc82278..2168a22 100644
--- a/source/blender/hair/intern/HAIR_solver.cpp
+++ b/source/blender/hair/intern/HAIR_solver.cpp
@@ -126,6 +126,56 @@ void SolverData::precompute_rest_bend()
 	}
 }
 
+static void debug_point_contacts(btDynamicsWorld *dworld, Point *point)
+{
+	btPairCachingGhostObject *ghost = &point->rb_ghost.ghost;
+	
+	btManifoldArray manifold_array;
+	const btBroadphasePairArray& pairs = ghost->getOverlappingPairCache()->getOverlappingPairArray();
+	int num_pairs = pairs.size();
+	
+	for (int i = 0; i < num_pairs; i++) {
+		manifold_array.clear();
+		
+		const btBroadphasePair& pair = pairs[i];
+		
+		/* unless we manually perform collision detection on this pair, the contacts are in the dynamics world paircache */
+		btBroadphasePair* collision_pair = dworld->getPairCache()->findPair(pair.m_pProxy0,pair.m_pProxy1);
+		if (!collision_pair)
+			continue;
+	
+		if (collision_pair->m_algorithm)
+			collision_pair->m_algorithm->getAllContactManifolds(manifold_array);
+	
+		for (int j = 0; j < manifold_array.size(); j++) {
+			btPersistentManifold* manifold = manifold_array[j];
+			btScalar direction_sign = manifold->getBody0() == ghost ? btScalar(-1.0) : btScalar(1.0);
+			for (int p = 0; p < manifold->getNumContacts(); p++) {
+				const btManifoldPoint &pt = manifold->getContactPoint(p);
+				if (pt.getDistance() < 0.f) {
+					const btVector3 &ptA = pt.getPositionWorldOnA();
+					const btVector3 &ptB = pt.getPositionWorldOnB();
+					const btVector3 &normalOnB = pt.m_normalWorldOnB;
+					
+					Debug::collision_contact(float3(ptB.x(), ptB.y(), ptB.z()));
+				}
+			}
+		}
+	}
+}
+
+void SolverData::debug_contacts(rbDynamicsWorld *world)
+{
+	btDynamicsWorld *dworld = world->dynamicsWorld;
+	
+	Curve *curve = curves;
+	for (int i = 0; i < totcurves; ++i, ++curve) {
+		Point *pt = curve->points;
+		for (int k = 0; k < curve->totpoints; ++k, ++pt)
+			debug_point_contacts(dworld, pt);
+	}
+}
+
 
 SolverForces::SolverForces()
 {
@@ -140,8 +190,12 @@ Solver::Solver() :
 
 Solver::~Solver()
 {
-	if (m_data)
+	if (m_data) {
+		if (m_forces.dynamics_world)
+			m_data->remove_from_world(m_forces.dynamics_world);
+		
 		delete m_data;
+	}
 }
 
 void Solver::set_data(SolverData *data)
@@ -304,6 +358,9 @@ static void step_threade

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list