Making sure I'm doing this right.

Discuss any questions about BEPUphysics or problems encountered.
snoozbuster
Posts: 172
Joined: Sat Sep 24, 2011 7:31 am

Re: Making sure I'm doing this right.

Post by snoozbuster »

Norbo wrote:
Are there any conditions when TriangleMesh.GetVerticiesAndIndicesFromModel won't work as expected, such as when vertices are offset in the modeler or other similar conditions?
I wouldn't be surprised if there were, but I haven't encountered or heard of any. It's a pretty simple convenience method which has alternatives- using another equivalent approach, like a content pipeline processor to extract the vertices, would be a good test.
Alright. I'll see if I can't figure it out, and if I ever do I'll tell you about it.
snoozbuster
Posts: 172
Joined: Sat Sep 24, 2011 7:31 am

Re: Making sure I'm doing this right.

Post by snoozbuster »

Okay. I've been fiddling with this for a little over an hour now, and I learned this: The World matrix of the affected models is entity.CollisionInformation.WorldTransform.Matrix multiplied by two sets of Identity matrixes. I'm 99.834% positive the Projection and View aren't the problem, because everything else renders just fine. I even tried changing the models' vertices to be offset in the modeler (which didn't work at all) and I'm currently manually setting the LocalPosition. Either way, the graphics aren't aligned with the entities even when the only Matrix acting on the drawing of the model is entity.CollisionInformation.WorldTranform.Matrix, which is understandably frustrating. They're drawn through a shader, but the shader works for everything else...

When you said "The world transform points to the center of the collision shape. If the graphic is not consistently aligned but is positioned using the transform, it will be offset," what did you mean by "consistently aligned?" Is that something code-based or model-based?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Making sure I'm doing this right.

Post by Norbo »

When you said "The world transform points to the center of the collision shape. If the graphic is not consistently aligned but is positioned using the transform, it will be offset," what did you mean by "consistently aligned?" Is that something code-based or model-based?
Everything must agree. If the graphic is positioned in code according to the center of mass, it must be centered in model-space accordingly. If the model was placed in model space such that the origin was the bottom left corner, but the game transformed it with the expectation that the origin was the center of mass, it won't end up in the right spot.

There's no great helpful secret hiding in there, I'm afraid- it's a slightly longer form of 'something, somewhere, is wrong somehow.' :)
snoozbuster
Posts: 172
Joined: Sat Sep 24, 2011 7:31 am

Re: Making sure I'm doing this right.

Post by snoozbuster »

Norbo wrote: Everything must agree. If the graphic is positioned in code according to the center of mass, it must be centered in model-space accordingly. If the model was placed in model space such that the origin was the bottom left corner, but the game transformed it with the expectation that the origin was the center of mass, it won't end up in the right spot.
Would an equivilent statement be that I should have my offset in my model file as well as in my code? Because right now I have the model file perfectly centered at the origin, even if it's offset in the code.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Making sure I'm doing this right.

Post by Norbo »

Would an equivilent statement be that I should have my offset in my model file as well as in my code?
That sounds like it would involve doubling the offset.

Here's the key information on the BEPUphysics side of things:
-The entity.Position points to the entity's center of mass. By default (when LocalPosition is the zero vector), this coincides with the center of the collision shape's volume.
-The LocalPosition offsets the center of the collision shape from the entity.Position. Its new position is entity.Position + Vector3.Transform(LocalPosition, entity.Orientation). This is the position stored in the entity.CollisionInformation.WorldTransform.

Everything else is external choices about how to use that information.

The rest of the work is just ensuring that everything else is consistent. Isolate every possible transform. If they're scattered, make an effort to cut them out or combine them into one spot for easier testing. Rigorously examine each individual transform in sequence, visualizing it (mentally or, more helpfully, with extra debug code). In the end, there should be relatively few individual transforms being layered together to get the final result (localGraphicTransform * physicsWorldTransform). So, if everything is in one conceptual spot, focused debugging should catch the issue quickly. If there doesn't appear to be a bug in the isolated section, cut and isolate more.
snoozbuster
Posts: 172
Joined: Sat Sep 24, 2011 7:31 am

Re: Making sure I'm doing this right.

Post by snoozbuster »

Norbo wrote:In the end, there should be relatively few individual transforms being layered together to get the final result (localGraphicTransform * physicsWorldTransform)
That's just it, though. There is no localGraphicTransform. World is exactly equal to physicsWorldTransform. I was able to get the bucket to line up, more or less, by giving it a localGraphicTransform in the model file, but the necessary transform appears to have no relation to anything I can find. The glass is a hopeless case, on the other hand. I add a little, and it's too much. Subtract a little, and it's too little. I sanity-checked physicsWorldTransform, but it's the exact value I expect it to be -- the point I want the graphic to be rendered at. It doesn't make sense. What makes less sense is there's seemingly nothing in common between the two pieces. Think about it: the original position of the bucket had collision data with slightly too much x and slightly too much z. The original glass had way too little x and I believe the other axes were slightly off, but yet both rendered in the correct graphical position using a matrix that should have rendered them at the exact same position as the collision data. There's nothing in common that I can see, and no relationship between anything, but at the same time, there has to be. The things that might be it work fine for other, practically identical, things. It's like there's something that offsets the collision data by some arbitrary amount, except for when the graphic is drawn. I'm not using multithreading, either.

I guess the point is there's no apperent discrepency between the matrix the physics creates and the matrix the graphic draws at, but yet they don't line up. I tried making the center of mass in my model match the center of mass in my code, but that didn't quite work (wait, wouldn't that work if I changed it to render at entity.WorldTransform instead?). Then I tried the opposite. Worked less.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Making sure I'm doing this right.

Post by Norbo »

I guess the point is there's no apperent discrepency between the matrix the physics creates and the matrix the graphic draws at, but yet they don't line up.
If two meshes are transformed by the same matrix and do not end up in exactly the same spot, then the two meshes are not identical.

Any collision shape which can be created with off-local-center data (convex hulls, mobile meshes, compounds, etc.) will process incoming data to be in the shape's local space. Unless the model's origin is already perfectly aligned with the local center of mass such that the recentering process does not change the position of any vertices, the data in the collision shape will be offset from the original data used to create the collision shape.

If you haven't already seen it, the Shape Recentering article explains the process more: http://bepuphysics.codeplex.com/wikipag ... ecentering
snoozbuster
Posts: 172
Joined: Sat Sep 24, 2011 7:31 am

Re: Making sure I'm doing this right.

Post by snoozbuster »

Huzzah, it has been fixed. What I did was instead of using new Entity(new MobileMeshShape()), I instead used new MobileMesh(), saved a local transform using the outputted entity.Position, and then added my desired position to the position instead of just setting it. Thanks for all your help. I still don't quite understand what was causing it in the first place, but at least it works now, and I don't think I have to set all my models to the origin when exporting them anymore. =p Thanks again!
Post Reply