Cone offset different from Cylinder

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
Crushinator
Posts: 11
Joined: Sun Mar 24, 2013 10:27 pm

Cone offset different from Cylinder

Post by Crushinator »

I've added support in my engine for cone primitives, but upon hooking up physics for it I noticed that the physics mesh for the cone did not line up with the render mesh. The cone, given the same height and width as a cylinder, is offset by about 25% of the height, upward. To make sure it wasn't something I was doing wrong I tested a cone and cylinder in the bepu demo framework and ended up with the same problem. Here's the code I used to repro the issue (this was in the Character Playground demo):

Code: Select all

Cone cone = new Cone(new Vector3(4.0f, 1.5f, 0), 1.5f, .7f, 5);
cone.IsAffectedByGravity = false;
Space.Add(cone);

Cylinder cyl = new Cylinder(new Vector3(7.0f, 1.5f, 0), 1.5f, .7f, 5);
cyl.IsAffectedByGravity = false;
Space.Add(cyl);
If this is the desired behavior for BEPU, what would be the best way to go about getting the cone to have the same min and max Y values as a cylinder?

Thanks in advance.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Cone offset different from Cylinder

Post by Norbo »

The position of an entity corresponds to its center of mass. Because the cone's mass is distributed mostly towards the bottom, the center of mass is closer to the bottom (in fact, it is exactly 1/4 the length of the cone away from the base). So, giving a cylinder and a cone the same center of mass position will result in the cone having a higher uppermost point.

To force the cone to have nonphysical rotation behavior, you could set the entity.CollisionInformation.LocalPosition. This offsets the collision shape from the center of mass.

If you want to maintain correct rotation behavior, then you'll need to compensate for the different centers of mass when you position them. In this case, it's easy enough to do manually by just subtracting 1/4 of the length of the cone from the Y value.

For more general cases, you could come up with automated methods. Here's one option:
1) Pick a Y value, here 'lowestY', where you want the lowest point of the entity to be.
2) Compute the extreme point of the collision shape in the downward direction. For a cone entity: cone.CollisionInformation.Shape.GetLocalExtremePoint[WithoutMargin](Vector3.Down, out localExtremePoint). Optionally use the "WithoutMargin" version if you only want to consider the core shape and not the margin expanded version. (For more information about what margins are, check out this video made for bullet physics. Margins work the same way in BEPU.)
3) To figure out the Y value of the position, use lowestY - localExtremePoint.Y.
Crushinator
Posts: 11
Joined: Sun Mar 24, 2013 10:27 pm

Re: Cone offset different from Cylinder

Post by Crushinator »

I'm curious how I could compensate by moving the cone without affecting the position of the render mesh, while also maintaining a proper center of gravity? The render and physics meshes must share the same position, altering one would alter the other. From my understanding of your answer I'd either have to alter how my render meshes are made, so that they match the physics behavior (which would make it difficult to position the render mesh in something like a level editor), or I'd have to alter the center of gravity, which makes the physics representation less realistic. Neither solution is ideal, but I'm leaning toward the less accurate physics since the use of a cone shape for physics is not as common in games as the other shapes.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Cone offset different from Cylinder

Post by Norbo »

The 'proper' way to deal with graphics using a different origin than the physics is to apply a local transform to the graphic before applying the entity's world transform. This can take the form of baking the change into the content, but it's often more convenient to just do it on the fly with something like this:

Code: Select all

graphicalWorldTransform = localTransform * entity.WorldTransform;
The local transform should bring the graphical model into alignment with the entity shape's local space. So, for a cone, it would probably be a translation by 1/4 of the height of the cone.

This works well for other more complex common shapes like convex hulls, too. The center of mass computation for convex hulls will almost certainly not match the original model origin, but the convex hull shape constructor outputs the center of mass and uses it to recenter the vertices. That center of mass can then be used in the 'localTransform' above to keep the graphic aligned. More about this can be found in the Shape Recentering documentation and associated demo.
Crushinator
Posts: 11
Joined: Sun Mar 24, 2013 10:27 pm

Re: Cone offset different from Cylinder

Post by Crushinator »

That's a possible solution, I'm just worried about the inconsistencies between positioning a cone that does have physics and one that doesn't have physics, they would end up in two different positions. But I guess the most accurate solution for the physics. It's a minor problem for now, but this is good information to have, especially since I haven't had to deal with convex hulls yet, so this problem was bound to come up then.

Thanks!
Post Reply