A basic movement test scene was added. As a result the spatial system has been reworked.
The player does not have to be the root of the scene, it can, but it probably shouldn't be in most cases
Tracked spaces now get their local spaces updated instead of world. World is then calculated based on hierarchy flattening.
Tracked spaces now must explicitly be parented to something (likely the player, although it is kind of neat when you parent the hands to a distant object).
The PlayerTrackedSpace no longer exists, but an entity marked with "name=Player" will be used for to determine which entity the player is.
The renderer does not ask the spatial system for world coordinates, but instead calculates a player relative transform (just a regular math::Transform, but it gets calculated with respect to the player). For example, if there is a box at world position (0,0,0) and the player is at world position (5, 0, 0), then the player relative position will be (-5, 0, 0) for that box. The player itself may have a local and a world that are not zero, but the player relative transform of the player should work out to be identity (assuming you even want to render the player at all, which you probably don't).
*^^ In other words, local and world now actually make sense. Specifically, world is the hierarchy flattened transform with respect to the origin. The origin (denoted by eid=0), can either be the player (odd but possible), or just some arbitrary point (more useful).
Because of this simplification, UpdateWorld() no longer needs to do any special checks for whether or not something is a tracked space, instead, it just works.
Because less checks are involved we don't need to traverse up the hierarchy tree, instead we just do an UpdateWorld() on the root. If you want, we can go back to having it flatten up the tree, but for now it's simpler going down. Whether we flatten up or down, we still might eventually want to have a "dirty" flag.
A basic movement test scene was added. As a result the spatial system has been reworked.