Steps to build a custom entity shape

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
mcmonkey
Posts: 92
Joined: Fri Apr 17, 2015 11:42 pm

Steps to build a custom entity shape

Post by mcmonkey »

As I dig myself further into this neat little hole...

I want to build a custom entity shape - one that is non-convex and generally a giant mess of weird-shaped-ness.

What are the proper steps to go about doing this?

I have made an initial series of attempts of course...:

- I have the shape object.
- I have the collidable object.
- I have all the same types of pair handles as one would find in static shape, registered to the narrowphase and all.

And ... it works nice... When the mass is 0, and the object isn't moving. Things bounce off it as they should.
The problem is, it doesn't recognize anything in its way when mass is set above 0 and it needs to actually move in itself. It just casually flies through everything.
My debug output shows it is recognizing that there are solid objects in the way and detecting collision as normal... it's just not reacting.

So what step am I missing? What is required here to make the entity recognize things that block its path, and impact against them instead of fly through them?

(Note: Ray/convex tracing hasn't been coded yet, but that shouldn't be a problem here, I don't think? The velocities are relatively low, and the objects involved are all thick and solid.)
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Steps to build a custom entity shape

Post by Norbo »

Things passing through each other sounds like relevant contacts aren't being generated. Are you sure it's really detecting the collisions properly? If valid contacts exist and the entity's collision rules are set to permit collision solving, it should react. The hard part about a custom shape is computing those valid contacts- once you're done with that, it's the same as anything else.

Is it possible that the bounding box calculation (either in EntityShape.GetBoundingBox, or maybe in your custom Collidable's UpdateBoundingBoxInternal) is not computing the correct box after it moves? A bad bounding box would explain the phasing-through-each-other stuff, though it would mean that contacts aren't being generated.
mcmonkey
Posts: 92
Joined: Fri Apr 17, 2015 11:42 pm

Re: Steps to build a custom entity shape

Post by mcmonkey »

So I have no idea what I actually did wrong in my code, but I realized the general concept was wrong.

I rewrote my custom entity shape to use GroupPairHandler instead of StandardPairHandler. It simplified the code a fair bit, after optimizing for limitations of the physics engine.

As a quick aside:

Code: Select all


        public CollisionShape Shape
        {
            get
            {
                return shape;
            }
            protected set
            {
                if (shape != null)
                    shape.ShapeChanged -= shapeChangedDelegate;
                shape = value;
                if (shape != null)
                    shape.ShapeChanged += shapeChangedDelegate;
                OnShapeChanged(shape);

                //TODO: Watch out for unwanted references in the delegate lists.
            }
        }
^ From Collidable.cs
That set, if fired rapidly, will lag a massive amount from the delegate edits, as I learned the hard way. I worked around that by inputting only null to that, and using the "shape" field directly.

Anyway:

I have some test stuff all functioning now for the most part... except a new issue has arisen: My perfectly cube shaped entity is rolling around like a sphere.
It's still colliding with the shape of a cube.
It's collision setup is literally defined as an off-center cube alone.
It's ... literally a group pair handler, that gives back a BoxShape of scale (1,1,1) as the only subpair.

And it's rolling around on one of its corners like a sphere.

I'm not sure, but it might be related to the fact that the box is off-center, and the corner it's rolling on might be the real origin of the entity (the 0,0,0 of the entity, whereas the Box is centered on 0.5,0.5,0.5)
EDIT: Definitely the 0,0,0 corner it's rolling on

I doubt this is quite a situation you've encountered, but perhaps it makes just enough sense that you might know what is causing it and how to correct it?
Perhaps it needs to be centered, but that doesn't sound like it'd properly account for all possible shapes... IE ones that are difficult to center, as they are too spread out/random...

Also, primarily for entertainment value, I've added a clip of the issue in action - meet "Sphery the Cube": http://i.imgur.com/tcujNWC.gifv

If I can post any relevant code to assist in understanding, just tell me what's needed.

EDIT2: Probably something to do with volume distribution actually. Not quite sure what to set the Matrix3x3 value to for that. Identity = rolling, unset = no rotation, ...
EDIT3: Borrowing Matrix3x3 volumedistribution code from CompoundShape yields more rolling

EDIT4: Fixed all that by offsetting the LocalPosition of the collidable! It now seems to work perfectly for the case of a singular cube!

EDIT5: Since I have this post... the biggest current source of lag in my new system is:
Image

Can we maybe get a constructor that doesn't include that Events and also doesn't set the shape? That should be a noticeable speed boost for me.
EDIT6: Tested that theory... it errors because it expects the events elsewhere, which means that needs to be fixed too...
EDIT7: After much fiddling... it works, and produces a slight boost in efficiency. If me just screwing around and deleting unnecessary code can produce noticeable change, I can't even imagine how much improvement will come with your skilled development of BEPUPhysics 2.0!
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Steps to build a custom entity shape

Post by Norbo »

As you've encountered, weird rotational behavior is usually either a bad inertia tensor(/volume distribution) or a bad offset. All default shapes recenter themselves on their center of mass so no LocalPosition modification is required. If your shape doesn't recenter itself, then a LocalPosition is indeed required as you've found.

The 'volume distribution' matrix is the shape's inertia local inertia tensor, unscaled by mass. Approximating a complex object's inertia tensor with a simpler version can work okay sometimes, though most of the default shapes try to compute accurate tensors.
Can we maybe get a constructor that doesn't include that Events and also doesn't set the shape? That should be a noticeable speed boost for me.
I'm not clear on the details here, but it sounds like collidables are getting recreated over and over and over again. That's going to be very inefficient no matter what; it's generating garbage which the GC is going to have to collect later.

If the frequency of construction is caused by streaming new parts of a large object in over time (as opposed to, say, just creating collidables every single frame for every collision or something), it's generally wise to use a custom collidable that doesn't have any subcollidables. For example, the Terrain doesn't have a collidable or shape for every triangle, there's just a single Terrain collidable.
Post Reply