[Bf-blender-cvs] [25dfd03] hair_system: Caching for bullet contacts with the hair system.

Lukas Tönne noreply at git.blender.org
Thu Aug 7 22:59:58 CEST 2014


Commit: 25dfd031c76aed0435608d212bf00cc0c3a53f93
Author: Lukas Tönne
Date:   Thu Aug 7 19:37:43 2014 +0200
Branches: hair_system
https://developer.blender.org/rB25dfd031c76aed0435608d212bf00cc0c3a53f93

Caching for bullet contacts with the hair system.

This makes the hair code a bit more independent from Bullet details when
handling contact information later on. Also we can then quickly loop
over contacts for repeated iterator steps without having to filter the
persistent manifold points cache again and again.

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

M	source/blender/hair/intern/HAIR_collision.cpp
M	source/blender/hair/intern/HAIR_solver.h
M	source/blender/hair/intern/HAIR_types.h

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

diff --git a/source/blender/hair/intern/HAIR_collision.cpp b/source/blender/hair/intern/HAIR_collision.cpp
index a1c0eaf..6962cf0 100644
--- a/source/blender/hair/intern/HAIR_collision.cpp
+++ b/source/blender/hair/intern/HAIR_collision.cpp
@@ -36,34 +36,34 @@ extern "C" {
 
 HAIR_NAMESPACE_BEGIN
 
-#if 0
 PointContactInfo::PointContactInfo(const btManifoldPoint &bt_point) :
+    local_point_body(bt_point.m_localPointB.m_floats),
     local_point_hair(bt_point.m_localPointA),
-    local_point_body(bt_point.m_localPointB),
-    world_point_hair(bt_point.m_positionWorldOnA),
     world_point_body(bt_point.m_positionWorldOnB),
+    world_point_hair(bt_point.m_positionWorldOnA),
     world_normal_body(bt_point.m_normalWorldOnB),
     distance(bt_point.m_distance1),
     friction(bt_point.m_combinedFriction),
     restitution(bt_point.m_combinedRestitution)
 {
 }
-#endif
 
 struct HairContactResultCallback : btCollisionWorld::ContactResultCallback {
+	HairContactResultCallback(PointContactCache &cache) :
+	    m_cache(&cache)
+	{
+	}
+
 	btScalar addSingleResult(btManifoldPoint &cp,
 	                         const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0,
 	                         const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1)
 	{
 		if (cp.getDistance() < 0.f) {
+			m_cache->push_back(PointContactInfo(cp));
 			
-			
-			
-//			const btVector3 &ptA = cp.getPositionWorldOnA();
-//			const btVector3 &ptB = cp.getPositionWorldOnB();
-//			const btVector3 &normalOnB = cp.m_normalWorldOnB;
-			
-//			Debug::collision_contact(float3(ptA.x(), ptA.y(), ptA.z()), float3(ptB.x(), ptB.y(), ptB.z()));
+			const btVector3 &ptA = cp.getPositionWorldOnA();
+			const btVector3 &ptB = cp.getPositionWorldOnB();
+			Debug::collision_contact(float3(ptA.x(), ptA.y(), ptA.z()), float3(ptB.x(), ptB.y(), ptB.z()));
 		}
 		
 		/* note: return value is unused
@@ -71,6 +71,8 @@ struct HairContactResultCallback : btCollisionWorld::ContactResultCallback {
 		 */
 		return 0.0f;
 	}
+	
+	PointContactCache *m_cache;
 };
 
 #if 0
@@ -184,4 +186,40 @@ void SolverData::debug_contacts(rbDynamicsWorld *world)
 }
 #endif
 
+
+void Solver::cache_point_contacts(PointContactCache &cache) const
+{
+	btDynamicsWorld *dworld = m_forces.dynamics_world->dynamicsWorld;
+	btPairCachingGhostObject *ghost = &m_data->rb_ghost.ghost;
+	
+//	btManifoldArray manifold_array;
+	const btBroadphasePairArray& pairs = ghost->getOverlappingPairCache()->getOverlappingPairArray();
+	int num_pairs = pairs.size();
+	
+	cache.reserve(num_pairs);
+	
+	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;
+		
+		btCollisionObject *ob0 = (btCollisionObject *)pair.m_pProxy0->m_clientObject;
+		btCollisionObject *ob1 = (btCollisionObject *)pair.m_pProxy1->m_clientObject;
+		btCollisionObject *other = ob0 == ghost ? ob1 : ob0;
+		
+		HairContactResultCallback cb(cache);
+		
+		Point *point = m_data->points;
+		int totpoints = m_data->totpoints;
+		for (int k = 0; k < totpoints; ++k, ++point) {
+			dworld->contactPairTest(&point->rb_ghost.ghost, other, cb);
+		}
+	}
+}
+
 HAIR_NAMESPACE_END
diff --git a/source/blender/hair/intern/HAIR_solver.h b/source/blender/hair/intern/HAIR_solver.h
index 7b4ff28..cf5e7ce 100644
--- a/source/blender/hair/intern/HAIR_solver.h
+++ b/source/blender/hair/intern/HAIR_solver.h
@@ -27,6 +27,8 @@
 #ifndef __HAIR_SOLVER_H__
 #define __HAIR_SOLVER_H__
 
+#include <vector>
+
 #include <BulletCollision/CollisionShapes/btBoxShape.h>
 
 extern "C" {
@@ -125,7 +127,6 @@ struct SolverForces {
 
 /* Point contact info */
 
-#if 0
 struct PointContactInfo {
 	PointContactInfo() {}
 	PointContactInfo(const btManifoldPoint &bt_point);
@@ -140,7 +141,8 @@ struct PointContactInfo {
 	float friction;
 	float restitution;
 };
-#endif
+
+typedef std::vector<PointContactInfo> PointContactCache;
 
 class Solver
 {
@@ -157,6 +159,8 @@ public:
 	void free_data();
 	SolverData *data() const { return m_data; }
 	
+	void cache_point_contacts(PointContactCache &cache) const;
+	
 	void do_integration(float time, float timestep, const SolverTaskData &data) const;
 	
 	void step_threaded(float time, float timestep);
diff --git a/source/blender/hair/intern/HAIR_types.h b/source/blender/hair/intern/HAIR_types.h
index 1bd7ec4..d15e4c2 100644
--- a/source/blender/hair/intern/HAIR_types.h
+++ b/source/blender/hair/intern/HAIR_types.h
@@ -43,7 +43,7 @@ struct float2 {
 	
 	__forceinline float2() {}
 	__forceinline float2(float x, float y) : x(x), y(y) {}
-	__forceinline float2(float *data) : x(data[0]), y(data[1]) {}
+	__forceinline float2(const float *data) : x(data[0]), y(data[1]) {}
 
 	__forceinline float operator[](int i) const { return *(&x + i); }
 	__forceinline float& operator[](int i) { return *(&x + i); }
@@ -65,7 +65,7 @@ struct float3 {
 
 	__forceinline float3() {}
 	__forceinline float3(float x, float y, float z) : x(x), y(y), z(z) {}
-	__forceinline float3(float *data) : x(data[0]), y(data[1]), z(data[2]) {}
+	__forceinline float3(const float *data) : x(data[0]), y(data[1]), z(data[2]) {}
 #endif
 
 	__forceinline float operator[](int i) const { return *(&x + i); }
@@ -94,7 +94,7 @@ struct float4 {
 	
 	__forceinline float4() {}
 	__forceinline float4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {}
-	__forceinline float4(float *data) : x(data[0]), y(data[1]), z(data[2]), w(data[3]) {}
+	__forceinline float4(const float *data) : x(data[0]), y(data[1]), z(data[2]), w(data[3]) {}
 #endif
 
 	__forceinline float operator[](int i) const { return *(&x + i); }




More information about the Bf-blender-cvs mailing list