RBD wrote:
In Blender I am using HACD along with voronoi fracture, but after the boolean intersections: for convex decomposition of non-convex voronoi shards.
Thanks for the info (I was wondering how you made your videos...).
I've made some extensions to your code to support generic polyhedral convex shapes in Bullet. In case somebody is interested:
These are the modifications I've made to extend the algorithm to generic convex polyhedral shapes (but use them at your own risk

).
Well, first of all I do the whole stuff in "Local Space" (but I think it should be possible and maybe faster to do all in world space: I just needed to simplify the code a bit): so I didn't use:
const btQuaternion& bbq
const btVector3& bbt
as arguments.
I replaced them with a
const btTransform& T
that I only use when the shard is ready: shardTransform = T * shardTransform;
Then I replaced the arguments:
const btVector3& bbmin, const btVector3& bbmax
with:
const btAlignedObjectArray<btVector3>& originalPlanes
that represent the plane equations of the original convex shape to be shattered; more on this later (*).
Now I just needed to shorten the code a bit like this:
Replaced this code:
Code:
btVector3 icp = quatRotate(bbiq, curVoronoiPoint - bbt); // replace this line only if you use local space for points as I did
//=====================================================
rbb = icp - bbmax;
nrbb = bbmin - icp;
planes.resize(6);
planes[0] = bbvx; planes[0][3] = rbb.x();
planes[1] = bbvy; planes[1][3] = rbb.y();
planes[2] = bbvz; planes[2][3] = rbb.z();
planes[3] = -bbvx; planes[3][3] = nrbb.x();
planes[4] = -bbvy; planes[4][3] = nrbb.y();
planes[5] = -bbvz; planes[5][3] = nrbb.z();
maxDistance = rbb.length();
distance = nrbb.length();
if (maxDistance < distance)
maxDistance = distance;
//======================================================
// Note that bbvx,bbvy,bbvz,rbb,nrbb (and bbmin,bbmax) are not used anymore
With:
Code:
// This is because I use both 'points' and 'originalPlanes' in "Local Space" (I apply a transform later)
const btVector3& icp = curVoronoiPoint; // Untransformed
// But probably the "transformed code" works with 'points' in 'Global Space' and 'originalPlanes' still in "Local Space" (like in the original method AFAIK).
//=======================================================
maxDistance = 0; // Needed ???
planes.copyFromArray(originalPlanes);
for (int i=0;i<planes.size();i++) {
btVector3& p(planes[i]);
distance = -p[3] - p.dot(icp);
p[3] = -distance;
if (maxDistance < distance) maxDistance = distance;
}
//=======================================================
(*) OK now we just need to extract the "originalPlanes" from a convex shape.
Luckily for us, in the case of btPolyhedralConvexShapes (that AFAIK include btBoxShape and btConvexHullShape, but don't include btSphereShape,btCylinderShape,etc.), Bullet can calculate these planes for us. Here's how to do it:
1) Call the method btPolyhedralConvexShape::initializePolyhedralFeatures() (although this has probably some side effect on the collision detection behavior of the shape...).
2) Retrieve the btConvexPolyhedron from the shape (see btPolyhedralConvexShape.h and btConvexPolyhedron.h and things will appear clear soon).
3) Retrieve the planes (4 btscalars) of each face and put them in the 'originalPlane' array (btVector3 can contain 4 btScalars: the 4th value can be set like this: originalPlane[i][3] = value).
Now it should work (well, I've only tried it on a box shape and a pyramidal convex hull so far).
The main drawback is that many random points in the shape local aabb will be outside the convex shape, but this can't be avoided (anyway these points will be automatically excluded). And please remember that the points I used are in "Local Space" now.
@ R&D: I'm starting thinking that probably you've deliberately released only the part of the code relative to "cuboids"... if this is the case I feel terribly sorry

(I should have asked you before posting this...).