If trace is null or point type, or the hull doesn't have portals, or the
first node is a leaf, MOD_HullContents operates in point mode (exactly the
same way as SV_HullPointContents()). However, in box mode, all leafs
touched by the trace are checked for their contents. The contents field of
trace (a bit field) will indicate the contents type of all touched leafs.
The returned contents value indicates the most important contents:
solid > lava > slime > water > empty
The one's complement value of the contents type is the bit number of the
contents bit field. I'm not sure how useful this will be as getting the
amount of overlap is currently not supported.
The code itself seems to work now. There are still some problems: the box
faces are using unit vectors for the edges, or I should go back to unit
vectors for the portal edges; starting in a solid corner won't always work;
etc. However, that's just mopping up: the main algorithm seems to be
working.
When the portals are too big, floats break down and break the tests. This
might not be much of an issue in real maps, but my tests use "infinite"
planes.
Unfortunately, Pythagorus and binary don't play well together, so rounding
errors are inevetible when testing with a slope. However, 1e-6 seems to be
a good epsilon (printf's %g hides it nicely :).
If the trace hits a portal on the plane that brought us to the leaf, then
we actually are in the leaf (otherwise, we shouldn't be here and thus
should ignore the leaf). At least, that's my thinking.
Many point tests fail (but they're really using box clipping with a zero
sized box) and two box tests fail.
I got rather tired of there being multiple definitions of mostly compatible
plane types (and I need a common type anyway). dplane_t still exists for
now because I want to be careful when messing with the actual bsp format.
This one demonstrates the need for more information in the bsp tree
(surface polygons). When the box collides with a corner where one side is
flat and the other angled, but there's a partition plane cutting the two,
the box can instead collide with the angled side before it hits the corner.
When the trace collides with something on both sides of a plane, the nearer
collision is required. The code now correctly checks both sides and keeps
the nearer collision.
However, there is still a problem with moves where the box is always cut
by the plane: both sides need to be tested (done), but when the first side
checked allows longer motion than the second, but still collides, only the
first side is checked. The shorter motion is required.
I'm not sure the end point needs to be moved at all, but I'll leave it
alone for now. I have a couple of failing test cases that seem to be caused
by not handling moves where the box is always cut by the plane.
The params are eye position, flags and synctype. Provision is made for
reading them from a text block on export, but nothing is done other than
retrieving the text block.
Rather than setting allsolid when the trace fails to leave solid space,
clear it when the trace enters non-solid space. This is necessary because
the trace might visit only one node and thus the failure to leave solid
space will not be detected. This fixes the problem with hipnotic's bobbing
water.