Best way to align arbitrary bodies?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Let's say I have 2 bodies, and I want to move one body along a specific vector up to the point where it touches the other body. The intent is to place the body at that location, not necessarily the actual "movement" of the body. I've implemented a solution that I'll describe below, but I'm not very happy with it, and was hoping someone might have a suggestion on a better way to approach it.
I know that with joints and contact sets, you can specify a joint and manually move a body so that it touches another. But I couldn't find any way to push the joint to it's endpoint like that using the API, other than using a binary search or similar. e.g. using a slider joint, and modifying joint.jointMotion.slideValue, the modification simply silently fails if you specify a slide value that would cause the body to intersect another body in the contact set. And you can specify a larger value that successfully skips past any bodies in the joint's way. So I guess you could do some sort of binary search to find the largest joint value within some tolerance of touching the other object. But if the first contact point is a very small feature the two bodies, it seems like it would be possible for the binary search to skip past and miss that contact point. i.e. if there were 2 parallel boxes with very thin tabs sticking out.
The approach I ended up implementing is similar, but doesn't actually use joints.
1. call MeasureManager.measureMinimumDistance
2. move the body along the vector by that distance
3. check if the bodies are touching (within some tolerance)
4. using oriented bounding boxes, check if the moving body has moved past the other body without intersecting it
5. loop
The theory is that you can "safely" move the body along the vector by the measure minimum distance, and be certain that you won't have moved it too far so that it intersects with the other body. But if the minimum distance vector isn't parallel to the movement vector, you'll end up getting closer to the body, but not actually touching. So for every iteration you get closer and closer, until you get close enough within some tolerance.
This works reasonably well in most cases, but if you have 2 parallel faces that slide past each other with a very small distance between them, the above algorithm could require many iterations, since the shortest distance, and the resulting movement amount would be very small.
One improvement I'm considering is that you might be able to do a pair-wise "measureMinimumDistance" for each pair of faces on the two bodies, and find the minimum distance, ignoring those distances where the minimum distance vector between the 2 faces is perpendicular to, or is the opposite direction of the movement vector (i.e. if their dot product is <= 0). But that could be potentially expensive for bodies with a large number of faces.
Although, you know that the minimum distance for any pair of faces won't decrease by more than the movement amount for that iteration, so you could eliminate many face pairs just based on their minimum distance from the previous iteration, especially when the movement amount for that iteration is small.
It seems like you might be able to extend the silhouette of the body and somehow use its intersection with the target body? I can't quite come up with a reliable algorithm though - other than as a way to determine beforehand if there is an intersection or not. Maybe as a way to pare down the number of faces to be considered in the above cartesion product.. needs more thought.
Can anyone think of any better approaches for doing this?