#include "coduo_x87emu.h" /* defines EMULATE_X87; x87 shim when it is 1 */

#include "cm_patch_private.h"

#include <math.h>

enum {
    CODUO_PATCH_OUTSIDE_SUM = 1,
    CODUO_PATCH_OUTSIDE_EDGE0 = 2,
    CODUO_PATCH_OUTSIDE_EDGE1 = 4,
    CODUO_PATCH_EDGE_COUNT = 3
};

#define CODUO_PATCH_CAPSULE_HIT_EPSILON 0.00001f

#if EMULATE_X87
/* NOT_FROM_ORIGINAL_SOURCE:
 * Every plane distance in the stock function (DLL 0x08055595 pattern) is one
 * 80-bit x87 chain — three products, two adds and the trailing -dist, rounded
 * once at its float slot (fmul;fmul;faddp;fmul;faddp;fsub dist;fstps). This
 * helper reproduces that exact chain so the six
 * identical dot-minus-dist sites below cannot drift by a transcription slip.
 */
static inline float coduo_engine_x87_plane_dist(float x, float y, float z,
                                                 float nx, float ny, float nz,
                                                 float d)
{
    return x87f_store_f32(x87f_sub(
        x87f_add(x87f_add(x87f_mul(x87f_load_f32(x), x87f_load_f32(nx)),
                          x87f_mul(x87f_load_f32(y), x87f_load_f32(ny))),
                 x87f_mul(x87f_load_f32(z), x87f_load_f32(nz))),
        x87f_load_f32(d)));
}
#endif

void CM_TraceCapsuleThroughPatchCollide(
    traceWork_t *traceWork,
    const coduo_patch_collide_t *patchCollide)
{
#if EMULATE_X87
    const float capOffset =
        x87f_store_f32(x87f_sub(x87f_load_f32(traceWork->sphere.halfheight),
                                x87f_load_f32(traceWork->sphere.radius)));
#else
    const float capOffset =
        traceWork->sphere.halfheight - traceWork->sphere.radius;
#endif
    float capDelta;

    if (patchCollide->capsuleOffsetSign == 0) {
#if EMULATE_X87
        capDelta = x87f_store_f32(
            x87f_add(x87f_load_f32(capOffset), x87f_load_f32(capOffset)));
        traceWork->start[2] = x87f_store_f32(
            x87f_sub(x87f_load_f32(traceWork->start[2]),
                     x87f_load_f32(capOffset)));
        traceWork->end[2] = x87f_store_f32(
            x87f_sub(x87f_load_f32(traceWork->end[2]),
                     x87f_load_f32(capOffset)));
#else
        capDelta = capOffset + capOffset;
        traceWork->start[2] -= capOffset;
        traceWork->end[2] -= capOffset;
#endif
    } else {
#if EMULATE_X87
        /* stock multiplies by the .rodata -2.0f (0x80dc924). */
        capDelta = x87f_store_f32(
            x87f_mul(x87f_load_f32(capOffset), x87f_load_f32(-2.0f)));
        traceWork->start[2] = x87f_store_f32(
            x87f_add(x87f_load_f32(traceWork->start[2]),
                     x87f_load_f32(capOffset)));
        traceWork->end[2] = x87f_store_f32(
            x87f_add(x87f_load_f32(traceWork->end[2]),
                     x87f_load_f32(capOffset)));
#else
        capDelta = capOffset * -2.0f;
        traceWork->start[2] += capOffset;
        traceWork->end[2] += capOffset;
#endif
    }

#if EMULATE_X87
    const float radius = x87f_store_f32(
        x87f_add(x87f_load_f32(traceWork->sphere.radius),
                 x87f_load_f32(CODUO_PATCH_POINT_ENTER_EPSILON)));
#else
    const float radius =
        traceWork->sphere.radius + CODUO_PATCH_POINT_ENTER_EPSILON;
#endif
    /* stock flips the sign bit (xor 0x80000000): an exact bitwise negate. */
    const float negativeRadius = -radius;

    for (int32_t facetIndex = 0;
         facetIndex < (int32_t)patchCollide->facetCount; ++facetIndex) {
        const coduo_patch_collision_facet_t *facet =
            &patchCollide->facets[facetIndex];
        const coduo_patch_collision_plane_t *surfacePlane =
            &facet->surfacePlane;

#if EMULATE_X87
        const float endDistance = coduo_engine_x87_plane_dist(
            traceWork->end[0], traceWork->end[1], traceWork->end[2],
            surfacePlane->normal[0], surfacePlane->normal[1],
            surfacePlane->normal[2], surfacePlane->dist);
#else
        const float endDistance =
            ((traceWork->end[0] * surfacePlane->normal[0]) +
             (traceWork->end[1] * surfacePlane->normal[1])) +
            (traceWork->end[2] * surfacePlane->normal[2]) -
            surfacePlane->dist;
#endif

        /* The stock comparisons fall through on unordered operands; the negated
         * forms below preserve that branch behavior. */
        if (!(endDistance >= radius)) {
#if EMULATE_X87
            const float startDistance = coduo_engine_x87_plane_dist(
                traceWork->start[0], traceWork->start[1], traceWork->start[2],
                surfacePlane->normal[0], surfacePlane->normal[1],
                surfacePlane->normal[2], surfacePlane->dist);
            const float surfaceDelta = x87f_store_f32(x87f_sub(
                x87f_load_f32(startDistance), x87f_load_f32(endDistance)));
#else
            const float startDistance =
                ((traceWork->start[0] * surfacePlane->normal[0]) +
                 (traceWork->start[1] * surfacePlane->normal[1])) +
                (traceWork->start[2] * surfacePlane->normal[2]) -
                surfacePlane->dist;
            const float surfaceDelta = startDistance - endDistance;
#endif

            if (!(0.0f >= surfaceDelta)) {
                if (startDistance <= negativeRadius) {
#if EMULATE_X87
                    const float capDistance = x87f_store_f32(x87f_add(
                        x87f_load_f32(startDistance),
                        x87f_mul(x87f_load_f32(capDelta),
                                 x87f_load_f32(surfacePlane->normal[2]))));
#else
                    const float capDistance =
                        startDistance + (capDelta * surfacePlane->normal[2]);
#endif

                    if (negativeRadius < capDistance) {
#if EMULATE_X87
                        float capTraceOffset = x87f_store_f32(x87f_div(
                            x87f_sub(x87f_load_f32(negativeRadius),
                                     x87f_load_f32(startDistance)),
                            x87f_load_f32(surfacePlane->normal[2])));
                        const float edge0StartDistance =
                            coduo_engine_x87_plane_dist(
                            traceWork->start[0], traceWork->start[1],
                            traceWork->start[2], facet->edgePlanes[0].normal[0],
                            facet->edgePlanes[0].normal[1],
                            facet->edgePlanes[0].normal[2],
                            facet->edgePlanes[0].dist);
                        const float edge1StartDistance =
                            coduo_engine_x87_plane_dist(
                            traceWork->start[0], traceWork->start[1],
                            traceWork->start[2], facet->edgePlanes[1].normal[0],
                            facet->edgePlanes[1].normal[1],
                            facet->edgePlanes[1].normal[2],
                            facet->edgePlanes[1].dist);
                        const float edge0EnterDistance = x87f_store_f32(x87f_add(
                            x87f_load_f32(edge0StartDistance),
                            x87f_mul(
                                x87f_load_f32(capTraceOffset),
                                x87f_load_f32(
                                    facet->edgePlanes[0].normal[2]))));
#else
                        float capTraceOffset =
                            (negativeRadius - startDistance) /
                            surfacePlane->normal[2];
                        const float edge0StartDistance =
                            ((traceWork->start[0] *
                              facet->edgePlanes[0].normal[0]) +
                             (traceWork->start[1] *
                              facet->edgePlanes[0].normal[1])) +
                            (traceWork->start[2] *
                             facet->edgePlanes[0].normal[2]) -
                            facet->edgePlanes[0].dist;
                        const float edge1StartDistance =
                            ((traceWork->start[0] *
                              facet->edgePlanes[1].normal[0]) +
                             (traceWork->start[1] *
                              facet->edgePlanes[1].normal[1])) +
                            (traceWork->start[2] *
                             facet->edgePlanes[1].normal[2]) -
                            facet->edgePlanes[1].dist;
                        const float edge0EnterDistance =
                            edge0StartDistance +
                            (capTraceOffset *
                             facet->edgePlanes[0].normal[2]);
#endif

                        /* 0x8055c40/0x8055c53: edge1's enter distance is
                         * computed (and rounded) only after edge0 passes. */
                        if (0.0f <= edge0EnterDistance) {
#if EMULATE_X87
                            const float edge1EnterDistance = x87f_store_f32(
                                x87f_add(x87f_load_f32(edge1StartDistance),
                                         x87f_mul(x87f_load_f32(capTraceOffset),
                                                  x87f_load_f32(
                                                      facet->edgePlanes[1]
                                                          .normal[2]))));

                            /* edge0EnterDistance + edge1EnterDistance is formed
                             * and compared in 80-bit (fadds; fld1; fucompp)
                             * with no intervening store. */
                            if (0.0f <= edge1EnterDistance &&
                                x87f_le(x87f_add(
                                            x87f_load_f32(edge0EnterDistance),
                                            x87f_load_f32(edge1EnterDistance)),
                                        x87f_load_f32(1.0f))) {
#else
                            const float edge1EnterDistance =
                                edge1StartDistance +
                                (capTraceOffset *
                                 facet->edgePlanes[1].normal[2]);

                            if (0.0f <= edge1EnterDistance &&
                                edge0EnterDistance + edge1EnterDistance <=
                                    1.0f) {
#endif
                                traceWork->trace.normal[0] =
                                    surfacePlane->normal[0];
                                traceWork->trace.normal[1] =
                                    surfacePlane->normal[1];
                                traceWork->trace.normal[2] =
                                    surfacePlane->normal[2];
                                traceWork->trace.fraction = 0.0f;
                                traceWork->trace.startsolid = 1;
                                return;
                            }
                        }

#if EMULATE_X87
                        if (capDistance < radius) {
                            capTraceOffset = capDelta;
                        } else {
                            capTraceOffset = x87f_store_f32(x87f_div(
                                x87f_sub(x87f_load_f32(radius),
                                         x87f_load_f32(startDistance)),
                                x87f_load_f32(surfacePlane->normal[2])));
                        }

                        const float edge0LeaveDistance = x87f_store_f32(x87f_add(
                            x87f_load_f32(edge0StartDistance),
                            x87f_mul(
                                x87f_load_f32(capTraceOffset),
                                x87f_load_f32(
                                    facet->edgePlanes[0].normal[2]))));
#else
                        if (capDistance < radius) {
                            capTraceOffset = capDelta;
                        } else {
                            capTraceOffset = (radius - startDistance) /
                                             surfacePlane->normal[2];
                        }

                        const float edge0LeaveDistance =
                            edge0StartDistance +
                            (capTraceOffset *
                             facet->edgePlanes[0].normal[2]);
#endif

                        /* 0x8055d77..0x8055dcb: edge1's leave distance is
                         * computed only after edge0 passes, and the stock
                         * ja-to-next-facet tests continue on unordered, so
                         * the predicates must be the negated > forms. */
                        if (!(0.0f > edge0LeaveDistance)) {
#if EMULATE_X87
                            const float edge1LeaveDistance = x87f_store_f32(
                                x87f_add(x87f_load_f32(edge1StartDistance),
                                         x87f_mul(x87f_load_f32(capTraceOffset),
                                                  x87f_load_f32(
                                                      facet->edgePlanes[1]
                                                          .normal[2]))));

                            /* edge0LeaveDistance + edge1LeaveDistance in 80-bit
                             * (fadds; fld1; fucompp), no store. */
                            if (!(0.0f > edge1LeaveDistance) &&
                                !x87f_lt(
                                    x87f_load_f32(1.0f),
                                    x87f_add(
                                        x87f_load_f32(edge0LeaveDistance),
                                        x87f_load_f32(edge1LeaveDistance)))) {
#else
                            const float edge1LeaveDistance =
                                edge1StartDistance +
                                (capTraceOffset *
                                 facet->edgePlanes[1].normal[2]);

                            if (!(0.0f > edge1LeaveDistance) &&
                                !(edge0LeaveDistance + edge1LeaveDistance >
                                  1.0f)) {
#endif
                                traceWork->trace.normal[0] =
                                    surfacePlane->normal[0];
                                traceWork->trace.normal[1] =
                                    surfacePlane->normal[1];
                                traceWork->trace.normal[2] =
                                    surfacePlane->normal[2];
                                traceWork->trace.fraction = 0.0f;
                                traceWork->trace.startsolid = 1;
                                return;
                            }
                        }
                    }
                } else {
                    float hitFraction;
                    vec3_t hitPoint;

                    if (startDistance < radius) {
                        hitFraction = 0.0f;
                        hitPoint[0] = traceWork->start[0];
                        hitPoint[1] = traceWork->start[1];
                        hitPoint[2] = traceWork->start[2];
                    } else {
#if EMULATE_X87
                        hitFraction = x87f_store_f32(x87f_div(
                            x87f_sub(x87f_load_f32(startDistance),
                                     x87f_load_f32(radius)),
                            x87f_load_f32(surfaceDelta)));
#else
                        hitFraction = (startDistance - radius) / surfaceDelta;
#endif
                        if (traceWork->trace.fraction < hitFraction) {
                            goto nextFacet;
                        }
#if EMULATE_X87
                        hitPoint[0] = x87f_store_f32(x87f_add(
                            x87f_load_f32(traceWork->start[0]),
                            x87f_mul(x87f_load_f32(traceWork->delta[0]),
                                     x87f_load_f32(hitFraction))));
                        hitPoint[1] = x87f_store_f32(x87f_add(
                            x87f_load_f32(traceWork->start[1]),
                            x87f_mul(x87f_load_f32(traceWork->delta[1]),
                                     x87f_load_f32(hitFraction))));
                        hitPoint[2] = x87f_store_f32(x87f_add(
                            x87f_load_f32(traceWork->start[2]),
                            x87f_mul(x87f_load_f32(traceWork->delta[2]),
                                     x87f_load_f32(hitFraction))));
#else
                        hitPoint[0] =
                            traceWork->start[0] +
                            (traceWork->delta[0] * hitFraction);
                        hitPoint[1] =
                            traceWork->start[1] +
                            (traceWork->delta[1] * hitFraction);
                        hitPoint[2] =
                            traceWork->start[2] +
                            (traceWork->delta[2] * hitFraction);
#endif
                    }

#if EMULATE_X87
                    const float edge0Distance = coduo_engine_x87_plane_dist(
                        hitPoint[0], hitPoint[1], hitPoint[2],
                        facet->edgePlanes[0].normal[0],
                        facet->edgePlanes[0].normal[1],
                        facet->edgePlanes[0].normal[2],
                        facet->edgePlanes[0].dist);
                    const float edge1Distance = coduo_engine_x87_plane_dist(
                        hitPoint[0], hitPoint[1], hitPoint[2],
                        facet->edgePlanes[1].normal[0],
                        facet->edgePlanes[1].normal[1],
                        facet->edgePlanes[1].normal[2],
                        facet->edgePlanes[1].dist);

                    /* 1.0f < edge0Distance + edge1Distance: the sum is 80-bit
                     * (fadds; fld1; fucompp; seta), no store. */
                    uint32_t outsideFlags =
                        (uint32_t)x87f_lt(x87f_load_f32(1.0f),
                                          x87f_add(x87f_load_f32(edge0Distance),
                                                   x87f_load_f32(
                                                       edge1Distance)));
#else
                    const float edge0Distance =
                        ((hitPoint[0] * facet->edgePlanes[0].normal[0]) +
                         (hitPoint[1] * facet->edgePlanes[0].normal[1])) +
                        (hitPoint[2] * facet->edgePlanes[0].normal[2]) -
                        facet->edgePlanes[0].dist;
                    const float edge1Distance =
                        ((hitPoint[0] * facet->edgePlanes[1].normal[0]) +
                         (hitPoint[1] * facet->edgePlanes[1].normal[1])) +
                        (hitPoint[2] * facet->edgePlanes[1].normal[2]) -
                        facet->edgePlanes[1].dist;

                    uint32_t outsideFlags =
                        (uint32_t)(1.0f < edge0Distance + edge1Distance);
#endif
                    if (edge0Distance < 0.0f) {
                        outsideFlags |= CODUO_PATCH_OUTSIDE_EDGE0;
                    }
                    if (edge1Distance < 0.0f) {
                        outsideFlags |= CODUO_PATCH_OUTSIDE_EDGE1;
                    }

                    if (outsideFlags == 0U) {
                        traceWork->trace.normal[0] = surfacePlane->normal[0];
                        traceWork->trace.normal[1] = surfacePlane->normal[1];
                        traceWork->trace.normal[2] = surfacePlane->normal[2];
                        if (hitFraction <= CODUO_PATCH_CAPSULE_HIT_EPSILON) {
                            traceWork->trace.fraction = 0.0f;
                            traceWork->trace.startsolid = 1;
                            return;
                        }
#if EMULATE_X87
                        traceWork->trace.fraction = x87f_store_f32(x87f_sub(
                            x87f_load_f32(hitFraction),
                            x87f_load_f32(CODUO_PATCH_CAPSULE_HIT_EPSILON)));
#else
                        traceWork->trace.fraction =
                            hitFraction - CODUO_PATCH_CAPSULE_HIT_EPSILON;
#endif
                    } else {
                        for (int32_t edgeIndex = 0;
                             edgeIndex < CODUO_PATCH_EDGE_COUNT;
                             ++edgeIndex) {
                            if (((outsideFlags >> edgeIndex) & 1U) ==
                                0U) {
                                coduo_patch_vertex_sphere_t *vertexSphere =
                                    facet->vertexSpheres[edgeIndex];

                                if (vertexSphere != NULL &&
                                    vertexSphere->checkcount !=
                                        cm_checkcount) {
                                    vertexSphere->checkcount = cm_checkcount;

#if EMULATE_X87
                                    const float deltaX = x87f_store_f32(x87f_sub(
                                        x87f_load_f32(traceWork->start[0]),
                                        x87f_load_f32(vertexSphere->origin[0])));
                                    const float deltaY = x87f_store_f32(x87f_sub(
                                        x87f_load_f32(traceWork->start[1]),
                                        x87f_load_f32(vertexSphere->origin[1])));
                                    const float deltaZ = x87f_store_f32(x87f_sub(
                                        x87f_load_f32(traceWork->start[2]),
                                        x87f_load_f32(vertexSphere->origin[2])));
                                    /* (dx*dx + dy*dy) + dz*dz - radius*radius,
                                     * one 80-bit chain (fsubrp for the -r*r). */
                                    const float radiusDelta =
                                        x87f_store_f32(x87f_sub(
                                            x87f_add(
                                                x87f_add(
                                                    x87f_mul(
                                                        x87f_load_f32(deltaX),
                                                        x87f_load_f32(deltaX)),
                                                    x87f_mul(
                                                        x87f_load_f32(deltaY),
                                                        x87f_load_f32(deltaY))),
                                                x87f_mul(
                                                    x87f_load_f32(deltaZ),
                                                    x87f_load_f32(deltaZ))),
                                            x87f_mul(x87f_load_f32(radius),
                                                     x87f_load_f32(radius))));
#else
                                    const float deltaX =
                                        traceWork->start[0] -
                                        vertexSphere->origin[0];
                                    const float deltaY =
                                        traceWork->start[1] -
                                        vertexSphere->origin[1];
                                    const float deltaZ =
                                        traceWork->start[2] -
                                        vertexSphere->origin[2];
                                    const float radiusDelta =
                                        ((deltaX * deltaX) +
                                         (deltaY * deltaY)) +
                                        (deltaZ * deltaZ) -
                                        (radius * radius);
#endif

                                    if (radiusDelta <= 0.0f) {
                                        traceWork->trace.normal[0] =
                                            surfacePlane->normal[0];
                                        traceWork->trace.normal[1] =
                                            surfacePlane->normal[1];
                                        traceWork->trace.normal[2] =
                                            surfacePlane->normal[2];
                                        traceWork->trace.fraction = 0.0f;
                                        traceWork->trace.startsolid = 1;
                                        return;
                                    }

#if EMULATE_X87
                                    const float velocityDot =
                                        x87f_store_f32(x87f_add(
                                            x87f_add(
                                                x87f_mul(
                                                    x87f_load_f32(
                                                        traceWork->delta[0]),
                                                    x87f_load_f32(deltaX)),
                                                x87f_mul(
                                                    x87f_load_f32(
                                                        traceWork->delta[1]),
                                                    x87f_load_f32(deltaY))),
                                            x87f_mul(
                                                x87f_load_f32(
                                                    traceWork->delta[2]),
                                                x87f_load_f32(deltaZ))));
#else
                                    const float velocityDot =
                                        ((traceWork->delta[0] * deltaX) +
                                         (traceWork->delta[1] * deltaY)) +
                                        (traceWork->delta[2] * deltaZ);
#endif

                                    if (velocityDot < 0.0f) {
#if EMULATE_X87
                                        /* velocityDot*velocityDot -
                                         * deltaLengthSquared*radiusDelta,
                                         * one 80-bit chain. */
                                        const float discriminant =
                                            x87f_store_f32(x87f_sub(
                                                x87f_mul(
                                                    x87f_load_f32(velocityDot),
                                                    x87f_load_f32(velocityDot)),
                                                x87f_mul(
                                                    x87f_load_f32(
                                                        traceWork
                                                            ->deltaLengthSquared),
                                                    x87f_load_f32(
                                                        radiusDelta))));
#else
                                        const float discriminant =
                                            (velocityDot * velocityDot) -
                                            (traceWork->deltaLengthSquared *
                                             radiusDelta);
#endif

                                        if (0.0f <= discriminant) {
#if EMULATE_X87
                                            /* sqrt takes (double)discriminant
                                             * (fstpl), returns in st0; the
                                             * negate/subtract/divide then run
                                             * in 80-bit (fchs;fsubrp;fdivrp). */
                                            const float vertexFraction =
                                                x87f_store_f32(x87f_div(
                                                    x87f_sub(
                                                        x87f_neg(x87f_load_f64(
                                                            sqrt(x87f_store_f64(
                                                                x87f_load_f32(
                                                                    discriminant))))),
                                                        x87f_load_f32(
                                                            velocityDot)),
                                                    x87f_load_f32(
                                                        traceWork
                                                            ->deltaLengthSquared)));
#else
                                            const float vertexFraction =
                                                (-sqrt(discriminant) -
                                                 velocityDot) /
                                                traceWork->deltaLengthSquared;
#endif

                                            if (vertexFraction <
                                                traceWork->trace.fraction) {
#if EMULATE_X87
                                                traceWork->trace.normal[0] =
                                                    x87f_store_f32(x87f_add(
                                                        x87f_load_f32(deltaX),
                                                        x87f_mul(
                                                            x87f_load_f32(
                                                                traceWork
                                                                    ->delta[0]),
                                                            x87f_load_f32(
                                                                vertexFraction))));
                                                traceWork->trace.normal[1] =
                                                    x87f_store_f32(x87f_add(
                                                        x87f_load_f32(deltaY),
                                                        x87f_mul(
                                                            x87f_load_f32(
                                                                traceWork
                                                                    ->delta[1]),
                                                            x87f_load_f32(
                                                                vertexFraction))));
                                                traceWork->trace.normal[2] =
                                                    x87f_store_f32(x87f_add(
                                                        x87f_load_f32(deltaZ),
                                                        x87f_mul(
                                                            x87f_load_f32(
                                                                traceWork
                                                                    ->delta[2]),
                                                            x87f_load_f32(
                                                                vertexFraction))));
                                                /* stock computes the reciprocal
                                                 * 1.0f/radius, then multiplies
                                                 * each component (fld1;fdivs;
                                                 * fmulp;fstps) — one store. */
                                                traceWork->trace.normal[0] =
                                                    x87f_store_f32(x87f_mul(
                                                        x87f_div(
                                                            x87f_load_f32(1.0f),
                                                            x87f_load_f32(
                                                                radius)),
                                                        x87f_load_f32(
                                                            traceWork->trace
                                                                .normal[0])));
                                                traceWork->trace.normal[1] =
                                                    x87f_store_f32(x87f_mul(
                                                        x87f_div(
                                                            x87f_load_f32(1.0f),
                                                            x87f_load_f32(
                                                                radius)),
                                                        x87f_load_f32(
                                                            traceWork->trace
                                                                .normal[1])));
                                                traceWork->trace.normal[2] =
                                                    x87f_store_f32(x87f_mul(
                                                        x87f_div(
                                                            x87f_load_f32(1.0f),
                                                            x87f_load_f32(
                                                                radius)),
                                                        x87f_load_f32(
                                                            traceWork->trace
                                                                .normal[2])));
#else
                                                traceWork->trace.normal[0] =
                                                    deltaX +
                                                    (traceWork->delta[0] *
                                                     vertexFraction);
                                                traceWork->trace.normal[1] =
                                                    deltaY +
                                                    (traceWork->delta[1] *
                                                     vertexFraction);
                                                traceWork->trace.normal[2] =
                                                    deltaZ +
                                                    (traceWork->delta[2] *
                                                     vertexFraction);
                                                traceWork->trace.normal[0] *=
                                                    1.0f / radius;
                                                traceWork->trace.normal[1] *=
                                                    1.0f / radius;
                                                traceWork->trace.normal[2] *=
                                                    1.0f / radius;
#endif

                                                if (traceWork->trace.fraction <=
                                                    CODUO_PATCH_CAPSULE_HIT_EPSILON) {
                                                    traceWork->trace.fraction =
                                                        0.0f;
                                                    traceWork->trace.startsolid =
                                                        1;
                                                    return;
                                                }
#if EMULATE_X87
                                                traceWork->trace.fraction =
                                                    x87f_store_f32(x87f_sub(
                                                        x87f_load_f32(
                                                            vertexFraction),
                                                        x87f_load_f32(
                                                            CODUO_PATCH_CAPSULE_HIT_EPSILON)));
#else
                                                traceWork->trace.fraction =
                                                    vertexFraction -
                                                    CODUO_PATCH_CAPSULE_HIT_EPSILON;
#endif
                                            }
                                        }
                                    }
                                }
                            } else {
                                coduo_patch_edge_cylinder_t *edgeCylinder =
                                    facet->edgeCylinders[edgeIndex];

                                if (edgeCylinder != NULL &&
                                    edgeCylinder->checkcount !=
                                        cm_checkcount) {
                                    edgeCylinder->checkcount = cm_checkcount;

#if EMULATE_X87
                                    const float deltaX = x87f_store_f32(x87f_sub(
                                        x87f_load_f32(traceWork->start[0]),
                                        x87f_load_f32(edgeCylinder->origin[0])));
                                    const float deltaY = x87f_store_f32(x87f_sub(
                                        x87f_load_f32(traceWork->start[1]),
                                        x87f_load_f32(edgeCylinder->origin[1])));
                                    const float deltaZ = x87f_store_f32(x87f_sub(
                                        x87f_load_f32(traceWork->start[2]),
                                        x87f_load_f32(edgeCylinder->origin[2])));
                                    const float radial0 = x87f_store_f32(
                                        x87f_add(
                                            x87f_add(
                                                x87f_mul(
                                                    x87f_load_f32(deltaX),
                                                    x87f_load_f32(
                                                        edgeCylinder
                                                            ->radialAxes[0][0])),
                                                x87f_mul(
                                                    x87f_load_f32(deltaY),
                                                    x87f_load_f32(
                                                        edgeCylinder
                                                            ->radialAxes[0][1]))),
                                            x87f_mul(
                                                x87f_load_f32(deltaZ),
                                                x87f_load_f32(
                                                    edgeCylinder
                                                        ->radialAxes[0][2]))));
                                    const float radial1 = x87f_store_f32(
                                        x87f_add(
                                            x87f_add(
                                                x87f_mul(
                                                    x87f_load_f32(deltaX),
                                                    x87f_load_f32(
                                                        edgeCylinder
                                                            ->radialAxes[1][0])),
                                                x87f_mul(
                                                    x87f_load_f32(deltaY),
                                                    x87f_load_f32(
                                                        edgeCylinder
                                                            ->radialAxes[1][1]))),
                                            x87f_mul(
                                                x87f_load_f32(deltaZ),
                                                x87f_load_f32(
                                                    edgeCylinder
                                                        ->radialAxes[1][2]))));
                                    float axial = x87f_store_f32(x87f_add(
                                        x87f_add(
                                            x87f_mul(
                                                x87f_load_f32(deltaX),
                                                x87f_load_f32(
                                                    edgeCylinder->axis[0])),
                                            x87f_mul(
                                                x87f_load_f32(deltaY),
                                                x87f_load_f32(
                                                    edgeCylinder->axis[1]))),
                                        x87f_mul(
                                            x87f_load_f32(deltaZ),
                                            x87f_load_f32(
                                                edgeCylinder->axis[2]))));
                                    /* (radial0*radial0 + radial1*radial1) -
                                     * radius*radius, one 80-bit chain. */
                                    const float radiusDelta =
                                        x87f_store_f32(x87f_sub(
                                            x87f_add(
                                                x87f_mul(
                                                    x87f_load_f32(radial0),
                                                    x87f_load_f32(radial0)),
                                                x87f_mul(
                                                    x87f_load_f32(radial1),
                                                    x87f_load_f32(radial1))),
                                            x87f_mul(x87f_load_f32(radius),
                                                     x87f_load_f32(radius))));
#else
                                    const float deltaX =
                                        traceWork->start[0] -
                                        edgeCylinder->origin[0];
                                    const float deltaY =
                                        traceWork->start[1] -
                                        edgeCylinder->origin[1];
                                    const float deltaZ =
                                        traceWork->start[2] -
                                        edgeCylinder->origin[2];
                                    const float radial0 =
                                        ((deltaX *
                                          edgeCylinder->radialAxes[0][0]) +
                                         (deltaY *
                                          edgeCylinder->radialAxes[0][1])) +
                                        (deltaZ *
                                         edgeCylinder->radialAxes[0][2]);
                                    const float radial1 =
                                        ((deltaX *
                                          edgeCylinder->radialAxes[1][0]) +
                                         (deltaY *
                                          edgeCylinder->radialAxes[1][1])) +
                                        (deltaZ *
                                         edgeCylinder->radialAxes[1][2]);
                                    float axial =
                                        ((deltaX * edgeCylinder->axis[0]) +
                                         (deltaY * edgeCylinder->axis[1])) +
                                        (deltaZ * edgeCylinder->axis[2]);
                                    const float radiusDelta =
                                        ((radial0 * radial0) +
                                         (radial1 * radial1)) -
                                        (radius * radius);
#endif

                                    if (radiusDelta <= 0.0f) {
                                        if (0.0f <= axial &&
                                            axial <= edgeCylinder->length) {
                                            traceWork->trace.normal[0] =
                                                surfacePlane->normal[0];
                                            traceWork->trace.normal[1] =
                                                surfacePlane->normal[1];
                                            traceWork->trace.normal[2] =
                                                surfacePlane->normal[2];
                                            traceWork->trace.fraction = 0.0f;
                                            traceWork->trace.startsolid = 1;
                                            return;
                                        }
                                    } else {
#if EMULATE_X87
                                        const float velocity0 =
                                            x87f_store_f32(x87f_add(
                                                x87f_add(
                                                    x87f_mul(
                                                        x87f_load_f32(
                                                            traceWork
                                                                ->delta[0]),
                                                        x87f_load_f32(
                                                            edgeCylinder
                                                                ->radialAxes[0]
                                                                            [0])),
                                                    x87f_mul(
                                                        x87f_load_f32(
                                                            traceWork
                                                                ->delta[1]),
                                                        x87f_load_f32(
                                                            edgeCylinder
                                                                ->radialAxes[0]
                                                                            [1]))),
                                                x87f_mul(
                                                    x87f_load_f32(
                                                        traceWork->delta[2]),
                                                    x87f_load_f32(
                                                        edgeCylinder
                                                            ->radialAxes[0]
                                                                        [2]))));
                                        const float velocity1 =
                                            x87f_store_f32(x87f_add(
                                                x87f_add(
                                                    x87f_mul(
                                                        x87f_load_f32(
                                                            traceWork
                                                                ->delta[0]),
                                                        x87f_load_f32(
                                                            edgeCylinder
                                                                ->radialAxes[1]
                                                                            [0])),
                                                    x87f_mul(
                                                        x87f_load_f32(
                                                            traceWork
                                                                ->delta[1]),
                                                        x87f_load_f32(
                                                            edgeCylinder
                                                                ->radialAxes[1]
                                                                            [1]))),
                                                x87f_mul(
                                                    x87f_load_f32(
                                                        traceWork->delta[2]),
                                                    x87f_load_f32(
                                                        edgeCylinder
                                                            ->radialAxes[1]
                                                                        [2]))));
                                        /* velocity0*radial0 +
                                         * velocity1*radial1, one 80-bit
                                         * chain. */
                                        const float velocityDot =
                                            x87f_store_f32(x87f_add(
                                                x87f_mul(
                                                    x87f_load_f32(velocity0),
                                                    x87f_load_f32(radial0)),
                                                x87f_mul(
                                                    x87f_load_f32(velocity1),
                                                    x87f_load_f32(radial1))));
#else
                                        const float velocity0 =
                                            ((traceWork->delta[0] *
                                              edgeCylinder->radialAxes[0][0]) +
                                             (traceWork->delta[1] *
                                              edgeCylinder->radialAxes[0][1])) +
                                            (traceWork->delta[2] *
                                             edgeCylinder->radialAxes[0][2]);
                                        const float velocity1 =
                                            ((traceWork->delta[0] *
                                              edgeCylinder->radialAxes[1][0]) +
                                             (traceWork->delta[1] *
                                              edgeCylinder->radialAxes[1][1])) +
                                            (traceWork->delta[2] *
                                             edgeCylinder->radialAxes[1][2]);
                                        const float velocityDot =
                                            (velocity0 * radial0) +
                                            (velocity1 * radial1);
#endif

                                        if (velocityDot < 0.0f) {
#if EMULATE_X87
                                            const float velocityLengthSquared =
                                                x87f_store_f32(x87f_add(
                                                    x87f_mul(
                                                        x87f_load_f32(
                                                            velocity0),
                                                        x87f_load_f32(
                                                            velocity0)),
                                                    x87f_mul(
                                                        x87f_load_f32(
                                                            velocity1),
                                                        x87f_load_f32(
                                                            velocity1))));
                                            /* velocityDot*velocityDot -
                                             * velocityLengthSquared*radiusDelta,
                                             * one 80-bit chain. */
                                            const float discriminant =
                                                x87f_store_f32(x87f_sub(
                                                    x87f_mul(
                                                        x87f_load_f32(
                                                            velocityDot),
                                                        x87f_load_f32(
                                                            velocityDot)),
                                                    x87f_mul(
                                                        x87f_load_f32(
                                                            velocityLengthSquared),
                                                        x87f_load_f32(
                                                            radiusDelta))));
#else
                                            const float velocityLengthSquared =
                                                (velocity0 * velocity0) +
                                                (velocity1 * velocity1);
                                            const float discriminant =
                                                (velocityDot * velocityDot) -
                                                (velocityLengthSquared *
                                                 radiusDelta);
#endif

                                            if (0.0f < discriminant) {
#if EMULATE_X87
                                                const float cylinderFraction =
                                                    x87f_store_f32(x87f_div(
                                                        x87f_sub(
                                                            x87f_neg(
                                                                x87f_load_f64(
                                                                    sqrt(x87f_store_f64(
                                                                        x87f_load_f32(
                                                                            discriminant))))),
                                                            x87f_load_f32(
                                                                velocityDot)),
                                                        x87f_load_f32(
                                                            velocityLengthSquared)));
#else
                                                const float cylinderFraction =
                                                    (-sqrt(discriminant) -
                                                     velocityDot) /
                                                    velocityLengthSquared;
#endif

                                                if (cylinderFraction <
                                                    traceWork->trace.fraction) {
#if EMULATE_X87
                                                    const float axialVelocity =
                                                        x87f_store_f32(x87f_add(
                                                            x87f_add(
                                                                x87f_mul(
                                                                    x87f_load_f32(
                                                                        traceWork
                                                                            ->delta[0]),
                                                                    x87f_load_f32(
                                                                        edgeCylinder
                                                                            ->axis[0])),
                                                                x87f_mul(
                                                                    x87f_load_f32(
                                                                        traceWork
                                                                            ->delta[1]),
                                                                    x87f_load_f32(
                                                                        edgeCylinder
                                                                            ->axis[1]))),
                                                            x87f_mul(
                                                                x87f_load_f32(
                                                                    traceWork
                                                                        ->delta[2]),
                                                                x87f_load_f32(
                                                                    edgeCylinder
                                                                        ->axis[2]))));
                                                    axial = x87f_store_f32(
                                                        x87f_add(
                                                            x87f_load_f32(axial),
                                                            x87f_mul(
                                                                x87f_load_f32(
                                                                    cylinderFraction),
                                                                x87f_load_f32(
                                                                    axialVelocity))));
#else
                                                    const float axialVelocity =
                                                        ((traceWork->delta[0] *
                                                          edgeCylinder
                                                              ->axis[0]) +
                                                         (traceWork->delta[1] *
                                                          edgeCylinder
                                                              ->axis[1])) +
                                                        (traceWork->delta[2] *
                                                         edgeCylinder->axis[2]);
                                                    axial +=
                                                        cylinderFraction *
                                                        axialVelocity;
#endif

                                                    if (0.0f <= axial &&
                                                        axial <=
                                                            edgeCylinder
                                                                ->length) {
#if EMULATE_X87
                                                        /* ((cf*velocity0) +
                                                         * radial0) / radius, one
                                                         * 80-bit chain (fdivs,
                                                         * not a reciprocal). */
                                                        const float normal0 =
                                                            x87f_store_f32(x87f_div(
                                                                x87f_add(
                                                                    x87f_mul(
                                                                        x87f_load_f32(
                                                                            cylinderFraction),
                                                                        x87f_load_f32(
                                                                            velocity0)),
                                                                    x87f_load_f32(
                                                                        radial0)),
                                                                x87f_load_f32(
                                                                    radius)));
                                                        const float normal1 =
                                                            x87f_store_f32(x87f_div(
                                                                x87f_add(
                                                                    x87f_mul(
                                                                        x87f_load_f32(
                                                                            cylinderFraction),
                                                                        x87f_load_f32(
                                                                            velocity1)),
                                                                    x87f_load_f32(
                                                                        radial1)),
                                                                x87f_load_f32(
                                                                    radius)));

                                                        traceWork->trace
                                                            .normal[0] =
                                                            x87f_store_f32(x87f_mul(
                                                                x87f_load_f32(
                                                                    edgeCylinder
                                                                        ->radialAxes[0]
                                                                                    [0]),
                                                                x87f_load_f32(
                                                                    normal0)));
                                                        traceWork->trace
                                                            .normal[1] =
                                                            x87f_store_f32(x87f_mul(
                                                                x87f_load_f32(
                                                                    edgeCylinder
                                                                        ->radialAxes[0]
                                                                                    [1]),
                                                                x87f_load_f32(
                                                                    normal0)));
                                                        traceWork->trace
                                                            .normal[2] =
                                                            x87f_store_f32(x87f_mul(
                                                                x87f_load_f32(
                                                                    edgeCylinder
                                                                        ->radialAxes[0]
                                                                                    [2]),
                                                                x87f_load_f32(
                                                                    normal0)));
                                                        traceWork->trace
                                                            .normal[0] =
                                                            x87f_store_f32(x87f_add(
                                                                x87f_load_f32(
                                                                    traceWork
                                                                        ->trace
                                                                        .normal[0]),
                                                                x87f_mul(
                                                                    x87f_load_f32(
                                                                        edgeCylinder
                                                                            ->radialAxes[1]
                                                                                        [0]),
                                                                    x87f_load_f32(
                                                                        normal1))));
                                                        traceWork->trace
                                                            .normal[1] =
                                                            x87f_store_f32(x87f_add(
                                                                x87f_load_f32(
                                                                    traceWork
                                                                        ->trace
                                                                        .normal[1]),
                                                                x87f_mul(
                                                                    x87f_load_f32(
                                                                        edgeCylinder
                                                                            ->radialAxes[1]
                                                                                        [1]),
                                                                    x87f_load_f32(
                                                                        normal1))));
                                                        traceWork->trace
                                                            .normal[2] =
                                                            x87f_store_f32(x87f_add(
                                                                x87f_load_f32(
                                                                    traceWork
                                                                        ->trace
                                                                        .normal[2]),
                                                                x87f_mul(
                                                                    x87f_load_f32(
                                                                        edgeCylinder
                                                                            ->radialAxes[1]
                                                                                        [2]),
                                                                    x87f_load_f32(
                                                                        normal1))));
#else
                                                        const float normal0 =
                                                            ((cylinderFraction *
                                                              velocity0) +
                                                             radial0) /
                                                            radius;
                                                        const float normal1 =
                                                            ((cylinderFraction *
                                                              velocity1) +
                                                             radial1) /
                                                            radius;

                                                        traceWork->trace
                                                            .normal[0] =
                                                            edgeCylinder
                                                                ->radialAxes[0]
                                                                            [0] *
                                                            normal0;
                                                        traceWork->trace
                                                            .normal[1] =
                                                            edgeCylinder
                                                                ->radialAxes[0]
                                                                            [1] *
                                                            normal0;
                                                        traceWork->trace
                                                            .normal[2] =
                                                            edgeCylinder
                                                                ->radialAxes[0]
                                                                            [2] *
                                                            normal0;
                                                        traceWork->trace
                                                            .normal[0] +=
                                                            edgeCylinder
                                                                ->radialAxes[1]
                                                                            [0] *
                                                            normal1;
                                                        traceWork->trace
                                                            .normal[1] +=
                                                            edgeCylinder
                                                                ->radialAxes[1]
                                                                            [1] *
                                                            normal1;
                                                        traceWork->trace
                                                            .normal[2] +=
                                                            edgeCylinder
                                                                ->radialAxes[1]
                                                                            [2] *
                                                            normal1;
#endif

                                                        if (traceWork->trace
                                                                .fraction <=
                                                            CODUO_PATCH_CAPSULE_HIT_EPSILON) {
                                                            traceWork->trace
                                                                .fraction =
                                                                0.0f;
                                                            traceWork->trace
                                                                .startsolid =
                                                                1;
                                                            return;
                                                        }
#if EMULATE_X87
                                                        traceWork->trace
                                                            .fraction =
                                                            x87f_store_f32(x87f_sub(
                                                                x87f_load_f32(
                                                                    cylinderFraction),
                                                                x87f_load_f32(
                                                                    CODUO_PATCH_CAPSULE_HIT_EPSILON)));
#else
                                                        traceWork->trace
                                                            .fraction =
                                                            cylinderFraction -
                                                            CODUO_PATCH_CAPSULE_HIT_EPSILON;
#endif
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

    nextFacet:
        ;
    }
}
