Consequences of a 0 margin
-
- Posts: 22
- Joined: Sat Jun 14, 2008 3:38 pm
- Location: Doha, Qatar.
Consequences of a 0 margin
What are the consequences of using a 0 margin on a convex hull? This is only for very simple convex hulls (almost as simple as a box).
-
- Posts: 133
- Joined: Wed Jul 27, 2005 1:05 pm
- Location: Berkeley, CA
Re: Consequences of a 0 margin
Hi,
Using the collision shape margin Bullet can avoid performing expensive penetration depth checks when the penetration is smaller than the margins. So, one of the consequences would be decreased performance. I would suggest always using the default margin.
Thanks,
John
Using the collision shape margin Bullet can avoid performing expensive penetration depth checks when the penetration is smaller than the margins. So, one of the consequences would be decreased performance. I would suggest always using the default margin.
Thanks,
John
-
- Posts: 133
- Joined: Wed Jul 27, 2005 1:05 pm
- Location: Berkeley, CA
Re: Consequences of a 0 margin
Hey,
Another (more important) reason to not use a collision margin of zero comes from how Bullet (GJK) determines the collision normal. GJK is used to determine the closest points on each object to each other. The normal is computed by subtracting closest(A) - closest(B) without a collision margin, the chances that closest(A) == closest(B) are higher. When closest(A) == closest(B) the collision normal will be the zero vector and invalid. Again, you should always use a collision margin.
Thanks,
John
Another (more important) reason to not use a collision margin of zero comes from how Bullet (GJK) determines the collision normal. GJK is used to determine the closest points on each object to each other. The normal is computed by subtracting closest(A) - closest(B) without a collision margin, the chances that closest(A) == closest(B) are higher. When closest(A) == closest(B) the collision normal will be the zero vector and invalid. Again, you should always use a collision margin.
Thanks,
John
-
- Posts: 66
- Joined: Fri Oct 12, 2007 6:28 pm
- Location: San Diego
Re: Consequences of a 0 margin
One problem with using a collision margin is that you always have gaps between objects that should be touching.
Like a characters feet not touching the ground, or a box stack with gaps between them.
Of course, this depends a lot on your units, since the hard coded default margin is 0.4. This would be fine if your units are centimeters perhaps, but not when it's meters.
I think the default margin should be some configurable thing at runtime/startup instead of being a define at compile time.
Like a characters feet not touching the ground, or a box stack with gaps between them.
Of course, this depends a lot on your units, since the hard coded default margin is 0.4. This would be fine if your units are centimeters perhaps, but not when it's meters.
I think the default margin should be some configurable thing at runtime/startup instead of being a define at compile time.
-
- Posts: 133
- Joined: Wed Jul 27, 2005 1:05 pm
- Location: Berkeley, CA
Re: Consequences of a 0 margin
Hi reltham,
This isn't really a problem. Just adjust your rendering geometry so that hides the margin.
Thanks,
John
This isn't really a problem. Just adjust your rendering geometry so that hides the margin.
Thanks,
John
-
- Site Admin
- Posts: 4221
- Joined: Sun Jun 26, 2005 6:43 pm
- Location: California, USA
Re: Consequences of a 0 margin
The default margin is 0.04 units, which is 4 centimeter assuming meter units.
For spheres and capsule, the margin is already 'embedded' so there will be no gap. For other shapes, such as boxes you can subtract the margin from the half extents. For convex hull of vertices there is a utility to shrink the shape to encapsulate the margin.
At least one of the collision shapes should have a margin, so as a rule you can safely set the margin for static collision hapes (for example non-moving triangle meshes) to zero.
Hope this helps,
Erwin
For spheres and capsule, the margin is already 'embedded' so there will be no gap. For other shapes, such as boxes you can subtract the margin from the half extents. For convex hull of vertices there is a utility to shrink the shape to encapsulate the margin.
At least one of the collision shapes should have a margin, so as a rule you can safely set the margin for static collision hapes (for example non-moving triangle meshes) to zero.
Hope this helps,
Erwin
-
- Posts: 508
- Joined: Fri May 30, 2008 2:51 am
- Location: Ossining, New York
Re: Consequences of a 0 margin
Now, that could come in very handy indeed...Erwin Coumans wrote: At least one of the collision shapes should have a margin, so as a rule you can safely set the margin for static collision hapes (for example non-moving triangle meshes) to zero.
An unrelated question: suppose I'm not using metre units, is there a problem with making the collision margin too large? Should it scale with the maximum velocity of the penetrating object?
-
- Posts: 508
- Joined: Fri May 30, 2008 2:51 am
- Location: Ossining, New York
Re: Consequences of a 0 margin
Could anyone help me find this utilty?Erwin Coumans wrote: For convex hull of vertices there is a utility to shrink the shape to encapsulate the margin.
btConvexHullShape does not modify its vertices, HullLibrary and HullResult don't seem to mention margins, and although btShapeHull::buildHull has a "margin" parameter, this is not used in the code.
I tried to do it myself using two methods - firstly subtracting the margin from the vector (0,0,0)->p for all points p in the hull and secondly subracting the margin from each axis of each point p. Neither produced convex meshes that stacked neatly.
thanks
-
- Site Admin
- Posts: 4221
- Joined: Sun Jun 26, 2005 6:43 pm
- Location: California, USA
Re: Consequences of a 0 margin
You can try to use btGeometryUtil to convert vertices into plane equations, move the plane equations inwards and create vertices from the intersection of the shifted plane equations. See this code snippet from ConvexDecompositionDemo:
Hope this helps,
Erwin
Code: Select all
//Input is a set of vertices (point cloud)
#define SHRINK_OBJECT_INWARDS 1
#ifdef SHRINK_OBJECT_INWARDS
std::vector<btVector3> planeEquations;
btGeometryUtil::getPlaneEquationsFromVertices(vertices,planeEquations);
std::vector<btVector3> shiftedPlaneEquations;
for (int p=0;p<planeEquations.size();p++)
{
btVector3 plane = planeEquations[p];
plane[3] += collisionMargin;
shiftedPlaneEquations.push_back(plane);
}
std::vector<btVector3> shiftedVertices;
btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations,shiftedVertices);
btCollisionShape* convexShape = new btConvexHullShape(&(shiftedVertices[0].getX()),shiftedVertices.size());
Erwin
-
- Posts: 508
- Joined: Fri May 30, 2008 2:51 am
- Location: Ossining, New York
Re: Consequences of a 0 margin
That function works nicely, thanks.
I changed the code slightly because I already had a btConvexHull object I wanted to populate and std::vector didn't work.
For the benefit of anyone else in this situation:
I changed the code slightly because I already had a btConvexHull object I wanted to populate and std::vector didn't work.
For the benefit of anyone else in this situation:
Code: Select all
#include <LinearMath/btGeometryUtil.h>
...
btAlignedObjectArray<btVector3> vertexes = ...; // put all the hull vertexes in here
btAlignedObjectArray<btVector3> planes;
btGeometryUtil::getPlaneEquationsFromVertices(vertexes, planes);
int sz = planes.size();
for (int i=0 ; i<sz ; ++i) {
planes[i][3] += s->getMargin();
}
vertexes.clear();
btGeometryUtil::getVerticesFromPlaneEquations(planes, vertexes);
sz = vertexes.size();
for (int i=0 ; i<sz ; ++i) {
s->addPoint(vertexes[i]);
}
-
- Posts: 237
- Joined: Tue Jun 29, 2010 10:27 pm
Re: Consequences of a 0 margin
Sparkprime, thanks for posting your code (and thanks to Erwin for the original version). It's very helpful when people post their solutions for those who may have the same problem. It indeed helped me as I had the same issue.
One additional problem I have though... the convex hulls I am dealing with are ones that are generated automatically by convex decomposition of a mesh. If I set the level of decomposition high enough, I was sometimes getting strange memory access errors during collisions. I traced this down to an issue with a margin, and I believe what is happening is that some of the generated convex hulls were so small that the shrinking of their vertices (via the code you/Erwin posted) was causing their shapes to shrink to nothing (all vertices shrunk to the same centre point?) or perhaps even turned inside out.
So I'm wondering how I would go about ensuring that the convex hull is not too small to be shrunk by. Perhaps if the value of planes[3] is less than or greater than some value?
One additional problem I have though... the convex hulls I am dealing with are ones that are generated automatically by convex decomposition of a mesh. If I set the level of decomposition high enough, I was sometimes getting strange memory access errors during collisions. I traced this down to an issue with a margin, and I believe what is happening is that some of the generated convex hulls were so small that the shrinking of their vertices (via the code you/Erwin posted) was causing their shapes to shrink to nothing (all vertices shrunk to the same centre point?) or perhaps even turned inside out.
So I'm wondering how I would go about ensuring that the convex hull is not too small to be shrunk by. Perhaps if the value of planes[3] is less than or greater than some value?
-
- Posts: 237
- Joined: Tue Jun 29, 2010 10:27 pm
Re: Consequences of a 0 margin
Ok, I think I figured it out. plane[3] values should be negative, and problems occur when they pass 0 and become positive (indicating that the shape is essentially flipping inside out, or something like that). So I modified sparkprime's code to ensure shrinking only occurs if the shape is large enough to avoid errors when shrinking objects smaller than the margin.
This is probably not necessary for most people, but is a good safety check anyway, particularly when dealing with convex hulls of unknown, potentially small size (like I am).
Code: Select all
btAlignedObjectArray<btVector3> vertices = ...;
btConvexHullShape convexShape = new btConvexHullShape();
convexShape->setMargin(someValue);
btAlignedObjectArray<btVector3> planes;
btGeometryUtil::getPlaneEquationsFromVertices(vertices, planes);
int sz = planes.size();
bool tooSmall = false;
for (int i=0 ; i<sz ; ++i) {
if ((planes[i][3] += convexShape->getMargin()) >= 0) {
tooSmall = true;
break;
}
}
if (!tooSmall) {
vertices.clear();
btGeometryUtil::getVerticesFromPlaneEquations(planes, vertices);
}
sz = vertices.size();
for (int i=0 ; i<sz ; ++i) {
convexShape->addPoint(vertices[i]);
}
-
- Posts: 508
- Joined: Fri May 30, 2008 2:51 am
- Location: Ossining, New York
Re: Consequences of a 0 margin
Interesting, I'll add that to my code too.
-
- Posts: 508
- Joined: Fri May 30, 2008 2:51 am
- Location: Ossining, New York
Re: Consequences of a 0 margin
Does this mean it only works when the convex hull is defined such that (0,0,0) in object space is within the bounds of the hull? I have several where this is not true, because they form part of a compound.
-
- Posts: 237
- Joined: Tue Jun 29, 2010 10:27 pm
Re: Consequences of a 0 margin
I have some hulls in the same situation (not enclosing {0,0,0} in object space), but it doesn't seem to be an issue. The code has stood up to several preliminary tests I've done. If some erroneous case comes up, I'll post it.