Page 1 of 1

Skeletons and bounding boxes--any interest in a patch?

Posted: Tue Nov 05, 2013 2:52 am
by lunkhound
So I've been having culling problems with my skeleton-based objects because of the way Ogre computes bounding boxes. Basically Ogre ignores what the skeleton bones are doing, so the bounding box is only accurate when the object is in the bind pose.

http://www.ogre3d.org/forums/viewtopic.php?f=2&t=79312

So I've got a fix for this that only affects the Entity class (the only files I modified were OgreEntity.h and cpp). Is there any interest in having this change in the main repo??

I wrote the change with compatibility in mind, so by default the feature is turned off. You have to opt-in on a per-entity basis. The Entity class gets a new bool member variable called mUpdateBoundingBoxFromSkeleton, as well as a public getter and setter function.
When the feature is enabled, the bounding box is formed around only the bones used for skinning. The resulting box is then inflated by the mesh's getBoundingSphereRadius value. This usually makes a bounding box that is larger than necessary. But a tighter fit can be achieved by reducing the bounding sphere radius on the mesh.

At first I was planning to add a "bone bounding radius" to the Mesh class for the expansion amount, and have it automatically calculated when the mesh is loaded, but I had trouble finding a good place in the code where the mesh's vertex positions were available along with the skeleton.

Re: Skeletons and bounding boxes--any interest in a patch?

Posted: Wed Nov 06, 2013 11:33 am
by bstone
Wouldn't it make sense to use a bounding box that is a merge of bounding boxes for all frames of the animation? Slightly excessive, yes, but stable as you can tell (it's really hard to tell when getBoundingSphereRadius() adjustment will bite you, and impossible to test that out).

Re: Skeletons and bounding boxes--any interest in a patch?

Posted: Wed Nov 06, 2013 5:50 pm
by lunkhound
bstone wrote:Wouldn't it make sense to use a bounding box that is a merge of bounding boxes for all frames of the animation? Slightly excessive, yes, but stable as you can tell (it's really hard to tell when getBoundingSphereRadius() adjustment will bite you, and impossible to test that out).
That would work fine as long as you aren't doing any procedural translations on the bones. In my case, I'm doing ragdoll--so my bones are controlled by physics, and they can travel arbitrarily far from the scene node. I would have to set the bounding box to be hugely oversized--and basically turn off culling--not just for the one guy doing ragdoll, but for everyone sharing the same mesh!

Also, it is possible to pick an inflation amount that will always work no matter what the bones do. For each bone, find the bounding radius of a sphere centered on the bone origin that encloses all vertices weighted to that bone. If you use the largest of these radii to inflate the bounding box around the bone origins it will always work. Even in the case of procedural animations.

Although scaling needs some special consideration which my current patch doesn't handle. I just need to take the max scaling factor across all the bones, and apply that scale to the inflation amount.

I kind of hijacked the value of getBoundingSphereRadius() because I was loathe to add a dedicated value to the Mesh class, but I'm rethinking that--I think its too confusing. I think it should be called something like getBoneBoundingRadius() or maybe getBoneBoundingBoxInflation().

Re: Skeletons and bounding boxes--any interest in a patch?

Posted: Wed Nov 06, 2013 7:17 pm
by bstone
Yeah, the simplistic approach won't work for procedural and blended animation. I like the auto-bounding idea.

Re: Skeletons and bounding boxes--any interest in a patch?

Posted: Wed Nov 06, 2013 7:21 pm
by holocronweaver
This could be useful to me. If it is well implemented and documented I don't see why we couldn't add it.

Re: Skeletons and bounding boxes--any interest in a patch?

Posted: Wed Nov 06, 2013 9:37 pm
by lunkhound
I've made some revisions to the original change:

- added getBoneBoundingRadius() to the Mesh class (added 4 bytes to the size of Mesh) (so I'm no longer hijacking the getBoundingSphereRadius() value)
- when a mesh first loads, if it has a skeleton, a value for the bone bounding radius is automatically computed. Should be pretty quick, just a single pass over the vertices of the mesh.

Here is a comparison of the kinds of bounding boxes I'm getting for the driver of this vehicle I've been working with:
Comparison of bounding box methods
Comparison of bounding box methods
bbox-comparison.jpg (199.78 KiB) Viewed 4637 times
On the left is the normal Ogre way of doing it, with a static bounding box around the mesh in bind pose position. His binding pose is the usual rigging T-pose, so it doesn't suit him particularly well when he is animated to be sitting in the vehicle.
On the right is the dynamic bounding box. Just based on his bone positions (with a bit of inflation).

These changes are up on my repo here https://bitbucket.org/cc8192/ogre-pull-requests

The last change fixes the scaling:
The driver's head bone is scaled by 5x
The driver's head bone is scaled by 5x
bbox-big-head.jpg (75.4 KiB) Viewed 4618 times
You can see that the bounding box properly handles the oversized head.

Re: Skeletons and bounding boxes--any interest in a patch?

Posted: Thu Nov 07, 2013 12:21 am
by scrawl
I haven't tried this out yet but I am also facing the same problem so your work is appreciated! Thumbs up :)

Re: Skeletons and bounding boxes--any interest in a patch?

Posted: Sun Nov 10, 2013 2:19 pm
by mkultra333
This does look neat. I've had to deal with this kind of thing myself, in almost exactly the same situation (ragdolls breaking up). I've already done a culling hack for my own project but if this had been around at the time it would have been handy.

Re: Skeletons and bounding boxes--any interest in a patch?

Posted: Sun Nov 10, 2013 7:14 pm
by lunkhound
Screenshot of broken-up ragdolls, and associated bounding boxes:
Ragdolls with detached legs strewn about.
Ragdolls with detached legs strewn about.
bug-bboxes.jpg (146.57 KiB) Viewed 4517 times
Sometimes a detached ragdoll part tunnels under my ground and falls out of the level, which makes the bounding box grow quite large. When this happens, I shut off the physics for that part and scale the bone to zero. The dynamic bounding box won't include any bones that are scaled to zero, so this keeps my bounding boxes to a reasonable size. And if all the bones are scaled to zero, it results in a "null" bounding box, which is always culled.

This sort of thing could be useful for reducing batch counts--aggregate a group of loosely related objects into a single object with bones using hardware skinning.

@scrawl: Thanks for approving the pull!