I cannot simply use the WorldTransform of my entity, because it does not have scale applied (any possibility it will, someday?)
Nope; the WorldTransform is the combined Position and Orientation of the entity. The scaling is a property of the shape, not the Entity itself, so the WorldTransform is oblivious to it. The world transform just pushes the collidable from its local space into world space. If the world transform included scaling, it would essentially be applying the scaling twice.
so I have to build my world matrix from scratch (I think). The problem with that, is that I do not know how to get a world matrix that includes the entity's rotation/orientation, mainly because all I have been doing is Matrix.CreateTranslation, Matrix.CreateScale etc.
Let's say you start with a mesh, and you create some entity that matches the mesh when it's unscaled. A transform is created which offsets the graphical mesh to match the physical mesh so that the graphic and collision shape match properly (more information can be found here:
viewtopic.php?f=4&t=1511). For a ConvexHullShape whose center is not trivial to compute, the computed center is output for you to use. That center is the offset applied to the vertices to recenter the shape on the origin. Other shapes like BoxShape or SphereShape are created already centered on the origin- if your model is being approximated by one of those, you'll need to find some decent approximate offset to get the model to match.
At this point, if you told your entity go to some position and orientation, the already locally offset graphic should be transformed by the entity's WorldTransform. So the combined graphic world transform would look something like:
Code: Select all
effect.World = localOffsetTransform * entity.WorldTransform;
Recall that we had the graphic matching the collision shape in local space. Now that the same entity.WorldTransform has been applied to both the collision shape and the graphic (they are now in 'world space' instead of local space), they are still aligned.
So let's take a step back and try to implement scaling. As I mentioned earlier, scaling is a property of a collision shape as opposed to a Entity, so we need to change the shape. Whatever convex collision shape we were using before can be tossed into a TransformableShape.
It's important to note that the TransformableShape will not output an offset to apply to your graphic. Any ConvexShape that is given to the TransformableShape has already been centered on the local origin, so the TransformableShape doesn't have to bother. So, the graphic's local offset must be computed using the first shape.
The linear transform of the TransformableShape can then be set to the desired scale. Keep that transform handy; you'll apply it after the local offset. It is applied
after the offset because the offset pulls the graphic onto the collision shape's local origin. If the scaling were applied first, the vertices would be scaled but in the wrong location.
After the offset and scale are applied, the graphic once again matches the collision shape's local space representation. From there, all you have to do is pull it into world space by multiplying by the world transform:
Code: Select all
effect.World = localOffsetTransform * scaleTransform * entity.WorldTransform;