[Bf-blender-cvs] [7bb8099] hair_system: Avoid adding all the hair point rigid bodies to the CollisionWorld.
Lukas Tönne
noreply at git.blender.org
Tue Aug 5 15:21:33 CEST 2014
Commit: 7bb8099e9cd7718c7a7e696d6081fb6d852c4a5e
Author: Lukas Tönne
Date: Tue Aug 5 15:18:40 2014 +0200
Branches: hair_system
https://developer.blender.org/rB7bb8099e9cd7718c7a7e696d6081fb6d852c4a5e
Avoid adding all the hair point rigid bodies to the CollisionWorld.
Instead we now use a single box-shaped collision object for the whole
hair system, and then do direct contact tests for the point objects
when there is a potential contact. This avoids O(n^2) issues when
inserting lots of collision objects into a DbvtBroadphase.
The points now have a radius property of their own as well.
===================================================================
M intern/rigidbody/rb_bullet_api.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 5adc167..07ffe20 100644
--- a/intern/rigidbody/rb_bullet_api.cpp
+++ b/intern/rigidbody/rb_bullet_api.cpp
@@ -289,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, btBroadphaseProxy::DefaultFilter, 0);
+ world->dynamicsWorld->addCollisionObject(ghost, btBroadphaseProxy::DefaultFilter, btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::DefaultFilter);
}
void RB_dworld_remove_ghost(rbDynamicsWorld *world, rbGhostObject *object)
diff --git a/source/blender/hair/intern/HAIR_curve.cpp b/source/blender/hair/intern/HAIR_curve.cpp
index 39f44ad..4ce0038 100644
--- a/source/blender/hair/intern/HAIR_curve.cpp
+++ b/source/blender/hair/intern/HAIR_curve.cpp
@@ -39,6 +39,7 @@ Point::Point() :
Point::Point(const float3 &rest_co) :
rest_co(rest_co),
+ radius(0.0f),
rb_ghost(),
bt_shape(1.0f)
{
diff --git a/source/blender/hair/intern/HAIR_curve.h b/source/blender/hair/intern/HAIR_curve.h
index 95d0b68..c84d304 100644
--- a/source/blender/hair/intern/HAIR_curve.h
+++ b/source/blender/hair/intern/HAIR_curve.h
@@ -56,6 +56,8 @@ struct Point {
float3 rest_co;
float3 rest_bend;
+ float radius;
+
rbGhostObject rb_ghost;
btSphereShape bt_shape;
diff --git a/source/blender/hair/intern/HAIR_scene.cpp b/source/blender/hair/intern/HAIR_scene.cpp
index 3171ff2..48c543b 100644
--- a/source/blender/hair/intern/HAIR_scene.cpp
+++ b/source/blender/hair/intern/HAIR_scene.cpp
@@ -94,6 +94,8 @@ SolverData *SceneConverter::build_solver_data(Scene *scene, Object *ob, DerivedM
HairPoint *hair_pt = hair->points + k;
point->rest_co = transform_point(mat, hair_pt->rest_co);
+ point->radius = 0.0f;
+
point->cur.co = transform_point(mat, hair_pt->co);
point->cur.vel = transform_direction(mat, hair_pt->vel);
}
@@ -158,16 +160,41 @@ void SceneConverter::sync_rigidbody_data(SolverData *data)
/* sync settings */
Curve *solver_curves = data->curves;
int totcurves = data->totcurves;
+ btTransform trans;
+ btVector3 halfsize;
- for (int i = 0; i < totcurves && i < totcurves; ++i) {
- Curve *curve = solver_curves + i;
+ if (data->totpoints == 0) {
+ trans.setIdentity();
+ halfsize = btVector3(0.5f, 0.5f, 0.5f);
+ }
+ else {
+ float3 co_min(FLT_MAX, FLT_MAX, FLT_MAX);
+ float3 co_max(-FLT_MAX, -FLT_MAX, -FLT_MAX);
- for (int k = 0; k < curve->totpoints; ++k) {
- Point *point = curve->points + k;
+ for (int i = 0; i < totcurves && i < totcurves; ++i) {
+ Curve *curve = solver_curves + i;
- RB_ghost_set_loc_rot(&point->rb_ghost, point->cur.co.data(), unit_qt.data());
+ for (int k = 0; k < curve->totpoints; ++k) {
+ Point *point = curve->points + k;
+
+ co_min[0] = min_ff(co_min[0], point->cur.co.x - point->radius);
+ co_min[1] = min_ff(co_min[1], point->cur.co.y - point->radius);
+ co_min[2] = min_ff(co_min[2], point->cur.co.z - point->radius);
+ co_max[0] = max_ff(co_max[0], point->cur.co.x + point->radius);
+ co_max[1] = max_ff(co_max[1], point->cur.co.y + point->radius);
+ co_max[2] = max_ff(co_max[2], point->cur.co.z + point->radius);
+
+ RB_ghost_set_loc_rot(&point->rb_ghost, point->cur.co.data(), unit_qt.data());
+ }
}
+
+ trans.setIdentity();
+ trans.setOrigin(btVector3(0.5f*(co_min[0] + co_max[0]), 0.5f*(co_min[1] + co_max[1]), 0.5f*(co_min[2] + co_max[2])));
+ halfsize = btVector3(0.5f*(co_max[0] - co_min[0]), 0.5f*(co_max[1] - co_min[1]), 0.5f*(co_max[2] - co_min[2]));
}
+
+ data->rb_ghost.ghost.setWorldTransform(trans);
+ data->bt_shape.setLocalScaling(halfsize);
}
HAIR_NAMESPACE_END
diff --git a/source/blender/hair/intern/HAIR_solver.cpp b/source/blender/hair/intern/HAIR_solver.cpp
index f176a6a..c6dc92f 100644
--- a/source/blender/hair/intern/HAIR_solver.cpp
+++ b/source/blender/hair/intern/HAIR_solver.cpp
@@ -44,24 +44,34 @@ SolverData::SolverData() :
curves(NULL),
points(NULL),
totcurves(0),
- totpoints(0)
+ totpoints(0),
+ rb_ghost(),
+ bt_shape(btVector3(1.0f, 1.0f, 1.0f))
{
+ rb_ghost.ghost.setCollisionShape(&bt_shape);
}
SolverData::SolverData(int totcurves, int totpoints) :
totcurves(totcurves),
- totpoints(totpoints)
+ totpoints(totpoints),
+ rb_ghost(),
+ bt_shape(btVector3(1.0f, 1.0f, 1.0f))
{
curves = new Curve[totcurves];
points = new Point[totpoints];
+
+ rb_ghost.ghost.setCollisionShape(&bt_shape);
}
SolverData::SolverData(const SolverData &other) :
curves(other.curves),
points(other.points),
totcurves(other.totcurves),
- totpoints(other.totpoints)
+ totpoints(other.totpoints),
+ rb_ghost(),
+ bt_shape(btVector3(1.0f, 1.0f, 1.0f))
{
+ rb_ghost.ghost.setCollisionShape(&bt_shape);
}
SolverData::~SolverData()
@@ -77,9 +87,7 @@ void SolverData::add_to_world(rbDynamicsWorld *world, int col_groups)
if (!world)
return;
- for (int k = 0; k < totpoints; ++k) {
- RB_dworld_add_ghost(world, &points[k].rb_ghost, col_groups);
- }
+ RB_dworld_add_ghost(world, &rb_ghost, col_groups);
}
void SolverData::remove_from_world(rbDynamicsWorld *world)
@@ -87,9 +95,7 @@ void SolverData::remove_from_world(rbDynamicsWorld *world)
if (!world)
return;
- for (int k = 0; k < totpoints; ++k) {
- RB_dworld_remove_ghost(world, &points[k].rb_ghost);
- }
+ RB_dworld_remove_ghost(world, &rb_ghost);
}
static float3 calc_bend(const Frame &frame, const float3 &co0, const float3 &co1)
@@ -132,9 +138,29 @@ void SolverData::precompute_rest_bend()
}
}
-static void debug_point_contacts(btDynamicsWorld *dworld, Point *point)
+struct HairContactResultCallback : btCollisionWorld::ContactResultCallback {
+ btScalar addSingleResult(btManifoldPoint &cp,
+ const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0,
+ const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1)
+ {
+ if (cp.getDistance() < 0.f) {
+ 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()));
+ }
+
+ /* note: return value is unused
+ * http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=20990#p20990
+ */
+ return 0.0f;
+ }
+};
+
+static void debug_ghost_contacts(SolverData *data, btDynamicsWorld *dworld, rbGhostObject *object)
{
- btPairCachingGhostObject *ghost = &point->rb_ghost.ghost;
+ btPairCachingGhostObject *ghost = &object->ghost;
btManifoldArray manifold_array;
const btBroadphasePairArray& pairs = ghost->getOverlappingPairCache()->getOverlappingPairArray();
@@ -149,10 +175,25 @@ static void debug_point_contacts(btDynamicsWorld *dworld, Point *point)
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;
+
+ Curve *curve = data->curves;
+ for (int i = 0; i < data->totcurves; ++i, ++curve) {
+ Point *pt = curve->points;
+ for (int k = 0; k < curve->totpoints; ++k, ++pt) {
+ dworld->contactPairTest(&pt->rb_ghost.ghost, other, cb);
+ }
+ }
+
+#if 0
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);
@@ -167,6 +208,7 @@ static void debug_point_contacts(btDynamicsWorld *dworld, Point *point)
}
}
}
+#endif
}
}
@@ -174,11 +216,32 @@ 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);
+ debug_ghost_contacts(this, dworld, &rb_ghost);
+
+ if (rb_ghost.ghost.getBroadphaseHandle()) {
+ float3 c[8];
+ c[0] = float3((float *)rb_ghost.ghost.getBroadphaseHandle()->m_aabbMin.m_floats);
+ c[7] = float3((float *)rb_ghost.ghost.getBroadphaseHandle()->m_aabbMax.m_floats);
+ c[1] = float3(c[7].x, c[0].y, c[0].z);
+ c[2] = float3(c[0].x, c[7].y, c[0].z);
+ c[3] = float3(c[7].x, c[7].y, c[0].z);
+ c[4] = float3(c[0].x, c[0].y, c[7].z);
+ c[5] = float3(c[7].x, c[0].y, c[7].z);
+ c[6] = float3(c[0].x, c[7].y, c[7].z);
+ Debug::collision_contact(c[0], c[1]);
+ Debug::collision_contact(c[1], c[3]);
+ Debug::collision_contact(c[3], c[2]);
+ Debug::collision_contact(c[2], c[0]);
+
+ Debug::collision_contact(c[0], c[4]);
+ Debug::collision_contact(c[1], c[5]);
+ Debug::collision_contact(c[2], c[6]);
+ Debug::collision_contact(c[3], c[7]);
+
+ Debug::collision_contact(c[4], c[5]);
+ Debug::collision_contact(c[5], c[7]);
+ Debug::collision_contact(c[7], c[6]);
+ Debug::collision_contact(c[6], c[4]);
}
}
diff --git a/source/blender/hair/intern/HAIR_solver.h b/source/blender/hair/intern/HAIR_solver.h
index 794c3ff..d11bf63 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 <BulletCollision/CollisionShapes/btBoxShape.h>
+
extern "C" {
#include "DNA_hair_types.h"
}
@@ -52,6 +54,9 @@ struct SolverData {
float t0, t1;
+ rbGhostObject rb_ghost;
+ btBoxShape bt_shape;
+
void precompute_rest_bend();
void add_to_world(rbDynamicsWorld *world, int col_groups);
More information about the Bf-blender-cvs
mailing list