Collision and updating position of Mobile Mesh

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
cincoutprabu
Posts: 15
Joined: Mon Jan 12, 2015 11:59 pm

Collision and updating position of Mobile Mesh

Post by cincoutprabu »

Hi, I'm able to add a mobile mesh from an FBX model, but not able to scale it or move it and even the collision is not working with the mobile mesh. For testing, I added a prefab sphere with a simple sphere FBX model. I'm able to move the sphere by applying linear-velocity and even collision events are working when the sphere hits other static meshes and cubes in the environment. But all of these are NOT working with mobile mesh. My objective is very simple: to add a model into the scene and move it based on user inputs. And the model is like a tennis racket with two cylinders (one for net and other for handle).

Is MobileMesh the best class to add a movable physics model into the scene? If yes, why moving and colliding with other objects are not working? If no, what is the best alternative to add a simple model and make it obey movements and collisions? Please note the positioning, scaling and collisions are all working with static meshes, cubes and spheres, but not with mobile meshes.

I'm trying to update the mobile mesh position like this: mobileMesh1.Position = new Vector3(x, y, z);

I have searched thru the forums and browsed the demos code, and spent too much time trying many things, but still the mobile-mesh is simply not working the way it should. I think I'm missing something very basic, but I'm getting nowhere after trying this for nearly 3 days. Any help would be much appreciated!
cincoutprabu
Posts: 15
Joined: Mon Jan 12, 2015 11:59 pm

Re: Collision and updating position of Mobile Mesh

Post by cincoutprabu »

After digging more into the demos code, looks like the problem with collision detection is with center-of-gravity and drawing of the mobile mesh in correct position in the scene. To solve the scaling problem, I have adjusted the scale of the model in modeling program (Blender) to match rest of the objects in the scene. While testing with a bigger model, found out that collision too is working but the model is not getting drawn in desired location of the scene which results in a perception of collision not working.

So, if I am correct, this brings down the problem to setting correct center-of-gravity and applying correct world transforms. But the question is how to find perfect center-of-gravity for an object that is in tennis racket shape and how to set this in mobile-mesh object. For now, I'm using EntityModel.cs class from GettingStartedDemo for drawing the mobile meshes (by replacing Entity property of this class with MobileMesh object), but something is wrong in this which draws the object in a wrong position in scene.

Btw at this, wondering why BEPUphysics doesn't work out of the box w.r.t scaling and center-of-gravity with mobile meshes!
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Collision and updating position of Mobile Mesh

Post by Norbo »

Is MobileMesh the best class to add a movable physics model into the scene?
When it is absolutely required that the dynamic physics representation be a true triangulated mesh, yes, the MobileMesh is the best option. The only other possibility would be a CompoundShape of TriangleShapes, but that would lack some of the MobileMeshShape's specialized features like boundary smoothing.

For performance reasons, however, it is virtually always a better idea to use simpler shapes when possible. For example, if the shape of the model is basically two cylinders, create a CompoundShape from two CylinderShapes. This would easily be an order of magnitude faster than a fully triangulated racket.
Please note the positioning, scaling and collisions are all working with static meshes, cubes and spheres, but not with mobile meshes.
If you are using Entity.WorldTransform to apply scaling, note that entities are rigid, meaning their state is only able to represent position and orientation, not scale or shear. If Entity.WorldTransform is set to some matrix with scale in it, the scale component will be ignored and the orientation will probably end up wrong because of it. (That property is mainly there for convenience when reading data for graphics purposes; when setting values, using the Position or Orientation properties directly is usually more convenient.)

Scaling mobile meshes is done at the shape level on creation. When creating a MobileMesh(Shape), the constructor takes an AffineTransform. That 'local' transform is applied to the triangle vertices before applying the entity's position and orientation. This can be seen in action in the MobileMeshDemo inside the BEPUphysicsDemos. Fiddle with the scale parameter in the AffineTransform constructor to see the effect.
While testing with a bigger model, found out that collision too is working but the model is not getting drawn in desired location of the scene which results in a perception of collision not working.

So, if I am correct, this brings down the problem to setting correct center-of-gravity and applying correct world transforms. But the question is how to find perfect center-of-gravity for an object that is in tennis racket shape and how to set this in mobile-mesh object.
This is related to shape recentering. All entity collision shapes are centered on their center of mass. For simple primitives like spheres and boxes, this is enforced directly through the dimensions growing outward from the center. For more complicated shapes like the ConvexHullShape and MobileMeshShape, the shape constructor takes raw data, computes the center of mass for it, and stores a processed version of the data local to that center. These shapes have a constructor which outputs the center of mass that was computed by the constructor.

The center of mass output by that constructor can be used to compensate for the 'recentering' that the constructor did. For more information, check out the shape recentering documentation.
Btw at this, wondering why BEPUphysics doesn't work out of the box w.r.t scaling and center-of-gravity with mobile meshes!
With regard to scaling:
-Local scaling of the MobileMeshShape should work fine, as mentioned.
-Scaling and shearing at the Entity level are disallowed because they are not a part of the simulated dynamics. It is a rigid body simulator, hence rigid transformations.

With regard to centers of gravity, there were basically two options:
1) Recenter the data given to the shape to ensure that collision shapes are always positioned on their center of mass (the current approach), or
2) Just use the information as given to the shape without modification, and make it the user's responsibility to pick a reasonable center of mass.

#2 imposes requirements on the artists making the content or on the content pipeline. If the artist chooses a bad center of mass, the shape would fling all over the place relative to the Entity in a very unintuitive way. To avoid burdening the artist with something that could be automated very precisely, this approach would probably end up with some recentering operation applied in the content pipeline outside of the engine.

At that point, #2 becomes equivalent to #1 in end result, but #1 can make use of the fact that the shape already has to do a bunch of relevant processing to compute inertia tensors, and it avoids dirtying up the content pipeline with details of the physics representation. The physics-related work is centralized in the physics engine.

(Note that the collision shape can be offset relative to the entity by using the Entity.CollisionInformation.LocalPosition if you actually want an effective center of mass different from the analytically computed one, so #1 doesn't remove any freedom.)

Some other side notes that might be relevant to mesh collision behavior:
1)
I'm trying to update the mobile mesh position like this: mobileMesh1.Position = new Vector3(x, y, z);
Watch out- setting the Position directly is equivalent to teleportation. The velocity of the object fails to represent the motion of the object. This can lead to 'squishy' or just broken collision response behavior, depending on how badly the velocity and actual motion diverge. Prefer controlling objects at the velocity level by either setting the velocities directly or using constraints.

2) A MobileMesh with a solidity setting of Solid, Counterclockwise, or Clockwise requires that the mesh has consistent triangle winding. If it does not have consistent winding, some triangles will let objects into the mesh, and others will fight in the other direction. This can cause really nasty behavior.

3) A MobileMesh with a solidity of DoubleSided will (as the name might imply) collide on both sides, which can sometimes 'trap' objects. While turning on CCD to stop objects from tunneling inside the mesh can help, it is not free from a performance perspective and it can't stop all interpenetration. For this reason, it's usually best to use a one-sided sidedness if possible.
cincoutprabu
Posts: 15
Joined: Mon Jan 12, 2015 11:59 pm

Re: Collision and updating position of Mobile Mesh

Post by cincoutprabu »

Thanks for taking time in replying, kudos to you! The problem in my case was drawing the MobileMesh model in a wrong location (due to wrong translation matrix) which resulted in a perception like collision was not working. This is because the bounding box (used by collision detection system) and the model itself were rendered in different positions in the scene. This would have been simpler if the GettingStartedDemo included a movable MobileMesh model apart from only cubes!

The following utility functions might be useful for someone who is looking for rendering a MobileMesh model (movable, collidable model). I used FBX models designed and exported from Blender.

Code: Select all

private MobileMesh CreateMobileMesh(Model model, Vector3 scale, Vector3 position, Vector3 rotationAxis, float rotationAngle, float mass)
{
    Vector3[] vertices;
    int[] indices;
    ModelDataExtractor.GetVerticesAndIndicesFromModel(model, out vertices, out indices);
    return new MobileMesh(vertices, indices, new AffineTransform(scale, Quaternion.CreateFromAxisAngle(rotationAxis, MathHelper.ToRadians(rotationAngle)), position), MobileMeshSolidity.Counterclockwise, mass);
}

private void AddMobileMesh(Model model, MobileMesh mesh, float bounciness)
{
    mesh.Material.Bounciness = bounciness;
    space.Add(mesh);
    Components.Add(new EntityModel(mesh, model, Matrix.Identity, this));
}
The classes ModelDataExtractor, MathHelper and EntityModel are from GettingStartedDemo code.

It is important to note that since 'scale' parameter applied in AffineTransform is ignored by the engine, the model has to be created in correct scale in modeling program (Blender) before importing it into the code.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Collision and updating position of Mobile Mesh

Post by Norbo »

It is important to note that since 'scale' parameter applied in AffineTransform is ignored by the engine, the model has to be created in correct scale in modeling program (Blender) before importing it into the code.
The scale of the AffineTransform passed into the MobileMesh(Shape) is not ignored. Check the MobileMeshDemo in the BEPUphysicsDemos for an example of its usage.
Post Reply