#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <float.h>

#include "../animation/xanim_private.h"
#include "../core_cvar/cvar_private.h"
#include "../core_math/core_math_private.h"
#include "../core_memory/core_memory_private.h"
#include "../core_runtime/core_runtime_private.h"
#include "../filesystem/fs_private.h"
#include "../physics_collision/cm_world_sector_private.h"
#include "../scripting/script_memory_private.h"
#include "xmodel_asset_private.h"

#define XMODEL_COLLISION_CONTENTS_MASK 0xdfff7ffbU
#define XMODEL_TRACE_BARYCENTRIC_MIN_BITS 0xba83126fU

typedef uint16_t xmodel_triangle_indices_t[3];
typedef float xmodel_rigid_vertex_t[6];

/* Binary-layout carriers used only with sizeof below. The uint32_t address
 * words represent stock i386 pointer storage; runtime objects continue to use
 * the real pointer-typed XModelPartsData and XModelPartNameTableSlot fields. */
typedef struct xmodel_parts_data_stock_i386_layout_s {
    uint32_t partNameTableSlotAddress;
    int16_t rootPartCount;
    uint8_t padding06[2];
    uint32_t partCollisionsAddress;
    uint32_t baseRotationsAddress;
    uint32_t baseTranslationsAddress;
    uint32_t partStateIndicesAddress;
} xmodel_parts_data_stock_i386_layout_t;

enum {
    XMODEL_ASSET_VERSION = 0x0e,
    XMODEL_DEFAULT_LOD_COUNT = 3,
    XMODEL_DEFAULT_BONE_COUNT = 1,
    XMODEL_DEFAULT_SURFACE_COUNT = 1,
    XMODEL_SURFACE_BONE_USAGE_BYTES = 16,
    XMODEL_SURFACE_TRIANGLE_INDEX_COUNT =
        sizeof(xmodel_triangle_indices_t) / sizeof(uint16_t),
    XMODEL_SURFS_VERTEX_BONE_SHIFT = 6,
    XMODEL_SURFS_BONE_BIT_SHIFT = 3,
    XMODEL_SURFS_BONE_BIT_MASK = 7,
    XMODEL_SURFS_NO_SINGLE_BONE = -1,
    XMODEL_SURFS_MAX_PART_COUNT = 0x7f,
    XMODEL_PART_NAME_STRING_HANDLE_TYPE = 10,
    XMODEL_SURFACE_NAME_STRING_HANDLE_TYPE = 8,
    XMODEL_STACK_ALIGNMENT = 16,
    XMODEL_COLLISION_BOUNDS_EPSILON_BITS = 0x3a83126f,
    XMODEL_TRACE_PLANE_OFFSET_EPSILON_BITS = 0x3e000000,
    XMODEL_TRACE_BARYCENTRIC_MAX_BITS = 0x3f8020c5,
    XMODEL_STATIC_BOUNDS_CORNER_COUNT = 8
};

typedef struct xmodel_surface_blend_info_array_s {
    uint8_t *blendInfo;
} xmodel_surface_blend_info_array_t;

static XModelSurfsData *xmodel_surfsCloneList;
static int32_t xmodel_optimizeEnabled;

static XModelPartNameTable xmodel_defaultPartNameTable;
static uint8_t xmodel_defaultPartStateIndices[XMODEL_DEFAULT_BONE_COUNT];
static XModelPartNameTableSlot xmodel_defaultPartNameSlot;
static XModelPartsData xmodel_defaultParts;
static fileData_t xmodel_defaultPartsEntry;
static XSurface xmodel_defaultSurfaces[XMODEL_DEFAULT_LOD_COUNT];
static XModelSurfsData xmodel_defaultSurfs;
static XModelSurfs xmodel_defaultSurfsEntry;
static XModelInfo xmodel_defaultCollision;
static XModel xmodel_defaultModelEntry;

static xmodel_triangle_indices_t
    xmodel_defaultTriangles[XMODEL_DEFAULT_SURFACE_COUNT];
static XModelPartColl xmodel_defaultPartCollisionSurface;
static XSurfaceRigidVert
    xmodel_defaultRigidVertexData[XMODEL_DEFAULT_BONE_COUNT *
                                  XMODEL_DEFAULT_LOD_COUNT];
static vec2_t xmodel_defaultTexCoords[XMODEL_DEFAULT_BONE_COUNT *
                                      XMODEL_DEFAULT_LOD_COUNT];
static XSurface
    *xmodel_defaultSurfacePtrs[XMODEL_DEFAULT_LOD_COUNT];
static uint16_t
    xmodel_defaultSurfaceNames[XMODEL_DEFAULT_SURFACE_COUNT + 1];
static const char xmodel_defaultName[] = "DEFAULT";
static const char xmodel_emptyName[] = "";
static const char xmodelSurfsType[] = "xmodelsurfs";
static const char xmodelPartsType[] = "xmodelparts";
static const char xmodelDefaultSurfaceName[] = "default";

enum {
    XMODEL_SCRIPT_RUNTIME_TREE_MT_TAG = 5,
    COM_CVAR_LOAD_TRACKED_COUNT = 65536
};

int32_t XModelLittleInt16(int16_t value)
{
    return value;
}

uint32_t XModelLittleUInt32(uint32_t value)
{
    return value;
}

long double XModelLittleFloat(float value)
{
    return (long double)value;
}

void XModelExpandQuatToAxis(float *quat)
{
    /* stock spills the three squares to float slots (0x80c4ec4/0x80c4ed3/
     * 0x80c4ee2) and reuses the rounded values for both lengthSq and the
     * xx/yy/zz scaling below */
    float x2 = quat[0] * quat[0];
    float y2 = quat[1] * quat[1];
    float z2 = quat[2] * quat[2];
    float lengthSq = x2 + y2 + z2 + quat[3] * quat[3];

    if (lengthSq != 0.0f) {
        float scale = 2.0f / lengthSq;
        float xx = x2 * scale;
        float yy = y2 * scale;
        float zz = z2 * scale;
        float x = quat[0] * scale;
        float xy = x * quat[1];
        float xz = x * quat[2];
        /* stock rounds xw/yw to float slots (0x80c4f6f/0x80c4f9c) before the
         * matrix-row sums */
        float xw = x * quat[3];
        float y = quat[1] * scale;
        float yz = y * quat[2];
        float yw = y * quat[3];
        float zw = quat[2] * quat[3] * scale;

        quat[0] = 1.0f - (yy + zz);
        quat[1] = xy + zw;
        quat[2] = xz - yw;
        quat[4] = xy - zw;
        quat[5] = 1.0f - (xx + zz);
        quat[6] = yz + xw;
        quat[8] = xz + yw;
        quat[9] = yz - xw;
        quat[10] = 1.0f - (xx + yy);
    } else {
        quat[0] = 1.0f;
        quat[1] = 0.0f;
        quat[2] = 0.0f;
        quat[4] = 0.0f;
        quat[5] = 1.0f;
        quat[6] = 0.0f;
        quat[8] = 0.0f;
        quat[9] = 0.0f;
        quat[10] = 1.0f;
    }
}

void XSurfaceTransformPoint43(const float point[3],
                              const DObjSkelMat *matrix,
                              float out[3])
{
    out[0] = point[0] * matrix->axis[0][0] +
             point[1] * matrix->axis[1][0] +
             point[2] * matrix->axis[2][0] + matrix->origin[0];
    out[1] = point[0] * matrix->axis[0][1] +
             point[1] * matrix->axis[1][1] +
             point[2] * matrix->axis[2][1] + matrix->origin[1];
    out[2] = point[0] * matrix->axis[0][2] +
             point[1] * matrix->axis[1][2] +
             point[2] * matrix->axis[2][2] + matrix->origin[2];
}

void XSurfaceAccumulateWeightedPoint43(const float point[3], float weight,
                                       const DObjSkelMat *matrix,
                                       float out[3])
{
    out[0] += (point[0] * matrix->axis[0][0] +
               point[1] * matrix->axis[1][0] +
               point[2] * matrix->axis[2][0] + matrix->origin[0]) *
              weight;
    out[1] += (point[0] * matrix->axis[0][1] +
               point[1] * matrix->axis[1][1] +
               point[2] * matrix->axis[2][1] + matrix->origin[1]) *
              weight;
    out[2] += (point[0] * matrix->axis[0][2] +
               point[1] * matrix->axis[1][2] +
               point[2] * matrix->axis[2][2] + matrix->origin[2]) *
              weight;
}

void XSurfaceTransformNormal43(const float normal[3],
                               const DObjSkelMat *matrix,
                               float out[3])
{
    out[0] = normal[0] * matrix->axis[0][0] +
             normal[1] * matrix->axis[1][0] +
             normal[2] * matrix->axis[2][0];
    out[1] = normal[0] * matrix->axis[0][1] +
             normal[1] * matrix->axis[1][1] +
             normal[2] * matrix->axis[2][1];
    out[2] = normal[0] * matrix->axis[0][2] +
             normal[1] * matrix->axis[1][2] +
             normal[2] * matrix->axis[2][2];
}

void XSurfaceTransformVectorRows43(const float vector[3],
                                   const DObjSkelMat *matrix,
                                   float out[3])
{
    out[0] = vector[0] * matrix->axis[0][0] +
             vector[1] * matrix->axis[0][1] +
             vector[2] * matrix->axis[0][2];
    out[1] = vector[0] * matrix->axis[1][0] +
             vector[1] * matrix->axis[1][1] +
             vector[2] * matrix->axis[1][2];
    out[2] = vector[0] * matrix->axis[2][0] +
             vector[1] * matrix->axis[2][1] +
             vector[2] * matrix->axis[2][2];
}

void *Hunk_AllocXAnimCreateTree(size_t size)
{
    return Hunk_AllocLow((size_t)size);
}

void *Hunk_AllocXModelPrecache(size_t size)
{
    return Hunk_Alloc(size);
}

void *Hunk_AllocXModelPrecacheMesh(size_t size)
{
    return Hunk_Alloc(size);
}

XAnimTree *Com_XAnimCreateTree(
    XAnim *sourceTree)
{
    return XAnimAllocRuntimeTree(sourceTree, Hunk_AllocXAnimCreateTree);
}

void *MT_AllocAnimTree(size_t size)
{
    return MT_Alloc(size, XMODEL_SCRIPT_RUNTIME_TREE_MT_TAG);
}

XAnimTree *Com_XAnimCreateSmallTree(
    XAnim *sourceTree)
{
    return XAnimAllocRuntimeTree(sourceTree, MT_AllocAnimTree);
}

void Com_XAnimFreeSmallTree(XAnimTree *runtimeTree)
{
    XAnimCopyRuntimeTree(runtimeTree, MT_Free);
}

void *GetWeaponInfoMemory(int32_t bytes,
                          int32_t *priorState,
                          int32_t callerState)
{
    if (bytes <= 0) {
        return NULL;
    }

    if (weaponInfo_memory == NULL) {
        weaponInfo_memory = Hunk_AllocLow((size_t)bytes);
        weaponInfo_memoryState = callerState;
        *priorState = 0;
    } else {
        *priorState = weaponInfo_memoryState;
        if (weaponInfo_memoryState == 0) {
            weaponInfo_memoryState = callerState;
        }
    }

    return weaponInfo_memory;
}

void FreeWeaponInfoMemory(int32_t callerState,
                          qboolean keepMemory)
{
    if (callerState == weaponInfo_memoryState) {
        if (keepMemory == qfalse) {
            weaponInfo_memory = NULL;
        }
        weaponInfo_memoryState = 0;
    }
}

qboolean Com_SaveCvarsToBuffer(const char *const *cvarNames,
                               int32_t cvarCount, char *buffer,
                               size_t bufferSize)
{
    uint32_t remaining = (uint32_t)bufferSize;

    for (int32_t index = 0; index < cvarCount; ++index) {
        const char *name = cvarNames[index];
        const char *value = Cvar_VariableString(name);
        int32_t written = snprintf(buffer, (size_t)remaining,
                                   "%s \"%s\"\n", name,
                                   value);

        if (written < 0) {
            return qfalse;
        }

        /* ORIGINAL_BINARY_BUG: Linux snprintf reports the full required
         * length after truncation.  Stock accepts that nonnegative result,
         * advances beyond the destination, and wraps the remaining dword
         * capacity before the next iteration; see
         * original-bugs/engine-save-cvars-snprintf-truncation-overrun.md. */
        buffer += written;
        remaining -= (uint32_t)written;
    }

    return qtrue;
}

qboolean Com_LoadCvarsFromBuffer(const char *const *cvarNames,
                                 int32_t cvarCount, char *fileBuffer,
                                 const char *fileName)
{
    char seen[COM_CVAR_LOAD_TRACKED_COUNT];
    int32_t seenCount = 0;

    /* ORIGINAL_BINARY_BUG: the caller-controlled dword count is not bounded
     * to the fixed 65,536-byte seen array.  Preserve the original zero-
     * extended memset extent; see
     * original-bugs/coduomp-load-cvars-count-stack-overflow.md. */
    memset(seen, 0, (uint32_t)cvarCount);
    Com_BeginParseSession(fileName);

    while (qtrue) {
        const char *name = Com_Parse(&fileBuffer);

        if (name[0] == '\0') {
            Com_EndParseSession();
            if (seenCount == cvarCount) {
                return qtrue;
            }

            Com_Printf("^1ERROR: the following cvars were not specified in "
                       "file '%s'\n",
                       fileName);
            for (int32_t index = 0; index < cvarCount; ++index) {
                if (seen[index] == 0) {
                    Com_Printf("^1  %s\n", cvarNames[index]);
                }
            }
            return qfalse;
        }

        for (int32_t index = 0; index < cvarCount; ++index) {
            if (strcasecmp(name, cvarNames[index]) == 0) {
                const char *value = Com_ParseOnLine(&fileBuffer);

                Cvar_Set(cvarNames[index], value);
                if (seen[index] == 0) {
                    seen[index] = 1;
                    ++seenCount;
                }
                goto next_line;
            }
        }

        Com_Printf("^3WARNING: unknown cvar '%s' in file '%s'\n", name,
                   fileName);

    next_line:
        Com_SkipRestOfLine(&fileBuffer);
    }
}

int32_t SurfaceTypeFromName(const char *name)
{
    (void)name;
    return -1;
}

const char *SurfaceTypeToName(int32_t surfaceType)
{
    (void)surfaceType;
    return xmodelDefaultSurfaceName;
}

int Com_AddToString(const char *src, char *dest, int offset, int destsize,
                    qboolean allowIncomplete)
{
    qboolean quote = qfalse;

    if (allowIncomplete != qfalse) {
        if (src[0] == '\0') {
            quote = qtrue;
        } else {
            int scan;

            for (scan = 0; scan < destsize - offset && src[scan] != '\0';
                 ++scan) {
                if (src[scan] < '!') {
                    quote = qtrue;
                    break;
                }
            }
        }
    }

    if (quote != qfalse && offset < destsize) {
        dest[offset] = '"';
        ++offset;
    }

    for (int scan = 0; offset < destsize && src[scan] != '\0'; ++scan) {
        dest[offset] = src[scan];
        ++offset;
    }

    if (quote != qfalse && offset < destsize) {
        dest[offset] = '"';
        ++offset;
    }

    return offset;
}

/* NOT_FROM_ORIGINAL_SOURCE: packed asset stream reader for unaligned int16s. */
static int16_t coduo_xmodel_read_int16(const uint8_t **pos)
{
    int16_t encoded;

    memcpy(&encoded, *pos, sizeof(encoded));
    *pos += sizeof(encoded);
    return (int16_t)XModelLittleInt16(encoded);
}

/* NOT_FROM_ORIGINAL_SOURCE: packed asset stream reader for unaligned uint32s. */
static uint32_t coduo_xmodel_read_uint32(const uint8_t **pos)
{
    uint32_t encoded;

    memcpy(&encoded, *pos, sizeof(encoded));
    *pos += sizeof(encoded);
    return XModelLittleUInt32(encoded);
}

/* NOT_FROM_ORIGINAL_SOURCE: packed asset stream reader for converted floats. */
static float coduo_xmodel_read_float(const uint8_t **pos)
{
    uint32_t bits = coduo_xmodel_read_uint32(pos);
    float value;

    memcpy(&value, &bits, sizeof(value));
    return (float)XModelLittleFloat(value);
}

/* NOT_FROM_ORIGINAL_SOURCE: preserves exact float bit constants from x87 code. */
static float coduo_xmodel_float_constant(uint32_t bits)
{
    float value;

    memcpy(&value, &bits, sizeof(value));
    return value;
}

qboolean XModelBad(const XModel *model)
{
    return model->info == &xmodel_defaultCollision ? qtrue : qfalse;
}

void XModelSetOptimize(qboolean enabled)
{
    xmodel_optimizeEnabled = enabled;
}

void XModelSurfsFree(fileData_t *entry)
{
    (void)entry;
}

void XModelPartsFree(fileData_t *entry)
{
    XModelPartsData *parts = entry->data.xmodelParts;
    XModelPartNameTableSlot *slot = parts->partNameTableSlot;
    XModelPartNameTable *table = slot->partNameTable;

    for (int32_t index = 0; index < table->count; ++index) {
        SL_RemoveRefToString(table->handles[index]);
    }
}

void XModelFree(fileData_t *entry)
{
    XModelInfo *collision = entry->data.xmodelInfo;

    for (int32_t lodIndex = 0; lodIndex < XMODEL_DEFAULT_LOD_COUNT;
         ++lodIndex) {
        XModelLodInfo *lod = &collision->lodRecords[lodIndex];

        if (lod->surfaceNameTable == NULL) {
            continue;
        }

        for (int32_t index = 0; index < lod->surfaceCount; ++index) {
            SL_RemoveRefToString(lod->surfaceNameTable[index]);
        }
        lod->surfaceNameTable = NULL;
    }
}

void ReadBlend(XSurface *surface, XSimpleBlendInfo *blend,
               const uint8_t **pos)
{
    const uint8_t *cursor = *pos;
    int16_t boneIndex = coduo_xmodel_read_int16(&cursor);

    /* ORIGINAL_BINARY_BUG: stock sign-extends the authored bone word and
     * uses it as an unchecked displacement into the 16-byte bone-use mask.
     * See original-bugs/coduomp-xmodel-loader-unbounded-input.md. */
    ((uint8_t *)surface->boneUsage)[boneIndex >> XMODEL_SURFS_BONE_BIT_SHIFT] |=
        (uint8_t)(1U << (boneIndex & XMODEL_SURFS_BONE_BIT_MASK));
    blend->boneMatrixOffset =
        (uint32_t)(int32_t)boneIndex << XMODEL_SURFS_VERTEX_BONE_SHIFT;

    blend->position[0] = coduo_xmodel_read_float(&cursor);
    blend->position[1] = coduo_xmodel_read_float(&cursor);
    blend->position[2] = coduo_xmodel_read_float(&cursor);

    *pos = cursor;
}

void XSurfaceUnstrip(const XStripInfo *strips,
                     xmodel_triangle_indices_t *triangles)
{
    const uint16_t *stripIndex = strips->stripIndices;

    for (int32_t strip = 0; strip < strips->stripCount; ++strip) {
        uint8_t vertexCount = strips->stripVertexCounts[strip];
        /* ORIGINAL_BINARY_BUG: the first three indices are loaded before
         * stock consults the authored vertex count. See original-bugs/
         * coduomp-xmodel-loader-unbounded-input.md. */
        uint16_t previousA = stripIndex[0];
        uint16_t previousB = stripIndex[1];
        uint16_t current = stripIndex[2];

        stripIndex += XMODEL_SURFACE_TRIANGLE_INDEX_COUNT;
        if (previousA != previousB && previousA != current &&
            previousB != current) {
            (*triangles)[0] = previousA;
            (*triangles)[1] = previousB;
            (*triangles)[2] = current;
            triangles++;
        }

        for (int32_t stripVertex = XMODEL_SURFACE_TRIANGLE_INDEX_COUNT;
             stripVertex < vertexCount; stripVertex += 2) {
            uint16_t next = stripIndex[0];
            if (current != previousB && current != next &&
                previousB != next) {
                (*triangles)[0] = current;
                (*triangles)[1] = previousB;
                (*triangles)[2] = next;
                triangles++;
            }

            if (vertexCount <= stripVertex + 1) {
                stripIndex += 1;
                break;
            }

            uint16_t next2 = stripIndex[1];
            stripIndex += 2;
            if (current != next && current != next2 && next != next2) {
                (*triangles)[0] = current;
                (*triangles)[1] = next;
                (*triangles)[2] = next2;
                triangles++;
            }

            current = next2;
            previousB = next;
        }
    }
}

void XModelReadSurface(XSurface *surface, const uint8_t **pos,
                       xmodel_asset_alloc_fn alloc)
{
    /* ORIGINAL_BINARY_BUG: the parser receives no file end and signed counts
     * and strip byte counts drive allocations and reads unchecked. See
     * original-bugs/coduomp-xmodel-loader-unbounded-input.md. */
    const uint8_t *cursor = *pos;

    surface->tileMode = *cursor;
    cursor++;
    surface->vertexCount = coduo_xmodel_read_int16(&cursor);
    surface->triangleCount = coduo_xmodel_read_int16(&cursor);
    int16_t stripCount = coduo_xmodel_read_int16(&cursor);
    int16_t singleBoneIndex = coduo_xmodel_read_int16(&cursor);

    Com_Memset(surface->boneUsage, 0, sizeof(surface->boneUsage));

    int16_t weightedPointCount = 0;
    int16_t compactWeightedVertexCount = 0;
    if (singleBoneIndex == XMODEL_SURFS_NO_SINGLE_BONE) {
        weightedPointCount = coduo_xmodel_read_int16(&cursor);
        compactWeightedVertexCount = coduo_xmodel_read_int16(&cursor);
        surface->boneIndex = XMODEL_SURFS_NO_SINGLE_BONE;
        uint32_t fullBlendVertexCount =
            (uint32_t)(int32_t)surface->vertexCount -
            (uint32_t)(int32_t)compactWeightedVertexCount;
        uint32_t blendPrimaryBytes =
            fullBlendVertexCount * (uint32_t)sizeof(XSurfaceBlendVert) +
            (uint32_t)(int32_t)compactWeightedVertexCount *
                (uint32_t)sizeof(XSurfaceBlendVertNoWeight);
        surface->vertexData.blendPrimaryStream =
            alloc((size_t)blendPrimaryBytes);
        surface->weightedPoints = alloc(
            (size_t)((uint32_t)(int32_t)weightedPointCount *
                     (uint32_t)sizeof(surface->weightedPoints[0])));
        surface->texCoords = alloc(
            (size_t)((uint32_t)(int32_t)surface->vertexCount *
                     (uint32_t)sizeof(surface->texCoords[0])));
    } else {
        surface->boneIndex =
            (int16_t)((uint32_t)(int32_t)singleBoneIndex
                      << XMODEL_SURFS_VERTEX_BONE_SHIFT);
        /* ORIGINAL_BINARY_BUG: the rigid path repeats ReadBlend's unchecked
         * signed bone-mask displacement. See original-bugs/
         * coduomp-xmodel-loader-unbounded-input.md. */
        ((uint8_t *)surface->boneUsage)
            [singleBoneIndex >> XMODEL_SURFS_BONE_BIT_SHIFT] |=
            (uint8_t)(1U << (singleBoneIndex & XMODEL_SURFS_BONE_BIT_MASK));
        surface->vertexData.rigidVertices = alloc(
            (size_t)((uint32_t)(int32_t)surface->vertexCount *
                     (uint32_t)sizeof(
                         surface->vertexData.rigidVertices[0])));
        surface->weightedPoints = NULL;
        surface->texCoords = alloc(
            (size_t)((uint32_t)(int32_t)surface->vertexCount *
                     (uint32_t)sizeof(surface->texCoords[0])));
    }

    int32_t totalStripIndices = 0;
    const uint8_t *stripScan = cursor;
    for (int32_t stripIndex = 0; stripIndex < stripCount; ++stripIndex) {
        uint8_t vertexCount = *stripScan;

        totalStripIndices += vertexCount;
        stripScan += sizeof(vertexCount) +
                     (size_t)vertexCount * sizeof(uint16_t);
    }

    uint32_t stripCountStackBytes =
        ((uint32_t)(int32_t)stripCount +
         (XMODEL_STACK_ALIGNMENT - 1U)) &
        ~(uint32_t)(XMODEL_STACK_ALIGNMENT - 1U);
    uint8_t *stripVertexCounts =
        __builtin_alloca((size_t)stripCountStackBytes);
    uint32_t stripIndexStackBytes =
        ((uint32_t)totalStripIndices * (uint32_t)sizeof(uint16_t) +
         (XMODEL_STACK_ALIGNMENT - 1U)) &
        ~(uint32_t)(XMODEL_STACK_ALIGNMENT - 1U);
    uint16_t *stripIndices =
        __builtin_alloca((size_t)stripIndexStackBytes);
    uint16_t *stripIndexOut = stripIndices;

    for (int32_t stripIndex = 0; stripIndex < stripCount; ++stripIndex) {
        uint8_t vertexCount = *cursor;

        stripVertexCounts[stripIndex] = vertexCount;
        cursor++;
        memcpy(stripIndexOut, cursor,
               (size_t)vertexCount * sizeof(stripIndexOut[0]));
        cursor += (size_t)vertexCount * sizeof(stripIndexOut[0]);
        stripIndexOut += vertexCount;
    }

    uint8_t *weightedVertexCursor = surface->vertexData.blendPrimaryStream;
    XSurfaceRigidVert *rigidVertex = surface->vertexData.rigidVertices;
    for (int32_t vertexIndex = 0; vertexIndex < surface->vertexCount;
         ++vertexIndex) {
        if (singleBoneIndex == XMODEL_SURFS_NO_SINGLE_BONE) {
            XSurfaceBlendVert *weightedVertex =
                (XSurfaceBlendVert *)
                    weightedVertexCursor;

            weightedVertex->normal[0] = coduo_xmodel_read_float(&cursor);
            weightedVertex->normal[1] = coduo_xmodel_read_float(&cursor);
            weightedVertex->normal[2] = coduo_xmodel_read_float(&cursor);
            surface->texCoords[vertexIndex][0] =
                coduo_xmodel_read_float(&cursor);
            surface->texCoords[vertexIndex][1] =
                coduo_xmodel_read_float(&cursor);

            int16_t additiveWeightCount =
                coduo_xmodel_read_int16(&cursor);
            weightedVertex->additiveWeightCount = additiveWeightCount;

            ReadBlend(surface, &weightedVertex->blend, &cursor);
            if (weightedVertex->additiveWeightCount == 0) {
                weightedVertexCursor +=
                    sizeof(XSurfaceBlendVertNoWeight);
            } else {
                weightedVertex->primaryWeight =
                    coduo_xmodel_read_float(&cursor);
                weightedVertexCursor +=
                    sizeof(XSurfaceBlendVert);
            }
        } else {
            rigidVertex->normal[0] = coduo_xmodel_read_float(&cursor);
            rigidVertex->normal[1] = coduo_xmodel_read_float(&cursor);
            rigidVertex->normal[2] = coduo_xmodel_read_float(&cursor);
            surface->texCoords[vertexIndex][0] =
                coduo_xmodel_read_float(&cursor);
            surface->texCoords[vertexIndex][1] =
                coduo_xmodel_read_float(&cursor);
            rigidVertex->position[0] = coduo_xmodel_read_float(&cursor);
            rigidVertex->position[1] = coduo_xmodel_read_float(&cursor);
            rigidVertex->position[2] = coduo_xmodel_read_float(&cursor);
            rigidVertex++;
        }
    }

    for (int32_t pointIndex = 0; pointIndex < weightedPointCount;
         ++pointIndex) {
        ReadBlend(surface, &surface->weightedPoints[pointIndex].blend,
                  &cursor);
        surface->weightedPoints[pointIndex].weight =
            coduo_xmodel_read_float(&cursor);
    }

    int16_t triangleAllocCount = surface->triangleCount;
    if ((triangleAllocCount & 1) != 0) {
        triangleAllocCount++;
    }

    surface->triangles = alloc(
        (int32_t)((int32_t)triangleAllocCount *
                  sizeof(surface->triangles[0])));
    XStripInfo strips = {
        stripCount,
        stripVertexCounts,
        stripIndices,
    };
    XSurfaceUnstrip(&strips, surface->triangles);

    if ((surface->triangleCount & 1) != 0) {
        uint16_t repeated =
            surface->triangles[triangleAllocCount - 2]
                              [XMODEL_SURFACE_TRIANGLE_INDEX_COUNT - 1];

        surface->triangleCount = triangleAllocCount;
        surface->triangles[triangleAllocCount - 1][0] = repeated;
        surface->triangles[triangleAllocCount - 1][1] = repeated;
        surface->triangles[triangleAllocCount - 1][2] = repeated;
    }

    *pos = cursor;
}

void XModelCreateDefaultSurface(XSurface *surface)
{
    surface->triangleCount = XMODEL_DEFAULT_SURFACE_COUNT;
    surface->vertexCount = XMODEL_DEFAULT_LOD_COUNT;
    Com_Memset(surface->boneUsage, 0, sizeof(surface->boneUsage));
    surface->boneIndex = 0;
    surface->vertexData.rigidVertices = xmodel_defaultRigidVertexData;
    surface->texCoords = xmodel_defaultTexCoords;
    surface->weightedPoints = NULL;
    surface->triangles = xmodel_defaultTriangles;

    xmodel_defaultTriangles[0][0] = 0;
    xmodel_defaultTriangles[0][1] = 1;
    xmodel_defaultTriangles[0][2] = 2;

    for (int32_t vertex = 0; vertex < surface->vertexCount; ++vertex) {
        surface->vertexData.rigidVertices[vertex].normal[0] = 1.0f;
        surface->vertexData.rigidVertices[vertex].normal[1] = 0.0f;
        surface->vertexData.rigidVertices[vertex].normal[2] = 0.0f;
        surface->texCoords[vertex][0] = 0.0f;
        surface->texCoords[vertex][1] = 0.0f;
        surface->vertexData.rigidVertices[vertex].position[0] = 0.0f;
        surface->vertexData.rigidVertices[vertex].position[1] = 0.0f;
        surface->vertexData.rigidVertices[vertex].position[2] = 0.0f;
    }
}

fileData_t *XModelCreateDefaultParts(void)
{
    xmodel_defaultPartNameTable.count = XMODEL_DEFAULT_BONE_COUNT;
    xmodel_defaultPartNameTable.handles[0] = 0;
    xmodel_defaultPartNameSlot.partNameTable = &xmodel_defaultPartNameTable;
    xmodel_defaultParts.partNameTableSlot = &xmodel_defaultPartNameSlot;
    xmodel_defaultParts.baseRotations = NULL;
    xmodel_defaultParts.baseTranslations = NULL;
    xmodel_defaultParts.rootPartCount = XMODEL_DEFAULT_BONE_COUNT;
    xmodel_defaultParts.partStateIndices = xmodel_defaultPartStateIndices;
    xmodel_defaultPartStateIndices[0] = 0;

    xmodel_defaultPartCollisionSurface.mins[0] = -16.0f;
    xmodel_defaultPartCollisionSurface.mins[1] = -16.0f;
    xmodel_defaultPartCollisionSurface.mins[2] = -16.0f;
    xmodel_defaultPartCollisionSurface.maxs[0] = 16.0f;
    xmodel_defaultPartCollisionSurface.maxs[1] = 16.0f;
    xmodel_defaultPartCollisionSurface.maxs[2] = 16.0f;
    xmodel_defaultParts.partCollisions =
        &xmodel_defaultPartCollisionSurface;

    xmodel_defaultPartsEntry.name = xmodel_defaultName;
    xmodel_defaultPartsEntry.data.xmodelParts = &xmodel_defaultParts;
    xmodel_defaultPartsEntry.freeData = NULL;

    return &xmodel_defaultPartsEntry;
}

XModelSurfs *XModelCreateDefaultSurfs(void)
{
    xmodel_defaultSurfs.surfaceCount = XMODEL_DEFAULT_SURFACE_COUNT;
    xmodel_defaultSurfacePtrs[0] = &xmodel_defaultSurfaces[0];
    xmodel_defaultSurfs.surfaces = xmodel_defaultSurfacePtrs;
    XModelCreateDefaultSurface(&xmodel_defaultSurfaces[0]);

    xmodel_defaultSurfsEntry.name = xmodel_defaultName;
    xmodel_defaultSurfsEntry.surfs = &xmodel_defaultSurfs;
    xmodel_defaultSurfsEntry.freeData = NULL;

    return &xmodel_defaultSurfsEntry;
}

/* Original C++ overload: XModelCreateDefault(XModel *). */
void XModelCreateDefault(XModel *entry)
{
    xmodel_defaultCollision.parts = XModelCreateDefaultParts();

    for (int32_t lodIndex = 0; lodIndex < XMODEL_DEFAULT_LOD_COUNT; ++lodIndex) {
        XModelLodInfo *lod = &xmodel_defaultCollision.lodRecords[lodIndex];

        lod->surfs = NULL;
        lod->name = xmodel_emptyName;
        lod->distance = 0.0f;
        lod->surfaceCount = XMODEL_DEFAULT_SURFACE_COUNT;
        lod->surfaceNameTable = xmodel_defaultSurfaceNames;
        xmodel_defaultSurfaceNames[0] = 0;
    }

    xmodel_defaultCollision.lodRecords[0].surfs = XModelCreateDefaultSurfs();
    entry->info = &xmodel_defaultCollision;
    entry->freeData = NULL;
    xmodel_defaultCollision.lodCount = XMODEL_DEFAULT_BONE_COUNT;
    xmodel_defaultCollision.modelFileCount = 0;
}

/* Original C++ overload: XModelCreateDefault(void). The trailing underscore
 * is the C-only overload disambiguation, not a compatibility alias. */
XModel *XModelCreateDefault_(void)
{
    XModelCreateDefault(&xmodel_defaultModelEntry);
    xmodel_defaultModelEntry.name = xmodel_defaultName;
    return &xmodel_defaultModelEntry;
}

XModelSurfs *XModelSurfsCloneSurfs(const XModelSurfs *entry,
                                  xmodel_asset_alloc_fn alloc)
{
    XModelSurfsData *source = entry->surfs;
    XModelSurfsData *clone = alloc(sizeof(*clone));

    clone->surfaceCount = source->surfaceCount;
    clone->surfaces = alloc(
        (size_t)((uint32_t)(int32_t)clone->surfaceCount *
                 (uint32_t)sizeof(clone->surfaces[0])));
    Com_Memcpy(clone->surfaces, source->surfaces,
               (size_t)((uint32_t)(int32_t)clone->surfaceCount *
                        (uint32_t)sizeof(clone->surfaces[0])));

    clone->next = xmodel_surfsCloneList;
    xmodel_surfsCloneList = clone;

    XModelSurfs *asset = alloc(sizeof(*asset));
    asset->surfs = clone;
    asset->freeData = XModelSurfsFree;
    asset->name = entry->name;

    return asset;
}

XModelSurfs *XModelSurfsPrecache(const char *name,
                                xmodel_asset_alloc_fn alloc)
{
    XModelSurfs *entry =
        FS_GetDataForFile(xmodelSurfsType, name, xmodel_emptyName);

    if (entry == NULL) {
        if (xmodel_enforceExist == qfalse) {
            Com_Printf("ERROR: Cannot precache 'xmodelsurfs/%s'", name);
        } else {
            Com_Error(1, "\x15" "Cannot precache 'xmodelsurfs/%s'.\n"
                         "you may need to get latest and run converter to fix",
                      name);
        }
        return NULL;
    }

    if (entry->surfs != NULL) {
        return XModelSurfsCloneSurfs(entry, alloc);
    }

    char path[1024];
    /* ORIGINAL_BINARY_BUG: the model-controlled asset name is formatted into
     * this stack path without a bound. See original-bugs/
     * coduomp-xmodel-loader-unbounded-input.md. */
    sprintf(path, "xmodelsurfs/%s", name);

    void *fileBuffer;
    if (FS_ReadFile(path, &fileBuffer) < 0) {
        Com_Error(1, "\x15" "Cannot find 'xmodelsurfs/%s'.", name);
        return NULL;
    }

    /* ORIGINAL_BINARY_BUG: FS_ReadFile's byte count is discarded and the
     * surface count and nested records are parsed without an end pointer. See
     * original-bugs/coduomp-xmodel-loader-unbounded-input.md. */
    const uint8_t *cursor = fileBuffer;
    int16_t version = coduo_xmodel_read_int16(&cursor);
    if (version != XMODEL_ASSET_VERSION) {
        FS_FreeFile(fileBuffer);
        Com_Error(1,
                  "\x15" "xmodelsurfs '%s' out of date (version %d, "
                         "expecting %d)",
                  name, version, XMODEL_ASSET_VERSION);
        return NULL;
    }

    int16_t surfaceCount = coduo_xmodel_read_int16(&cursor);
    XModelSurfsData *surfs = alloc(sizeof(*surfs));
    surfs->surfaceCount = surfaceCount;
    surfs->surfaces = alloc(
        (size_t)((uint32_t)(int32_t)surfaceCount *
                 (uint32_t)sizeof(surfs->surfaces[0])));

    XSurface *surfaces =
        alloc((size_t)((uint32_t)(int32_t)surfaceCount *
                       (uint32_t)sizeof(surfaces[0])));
    for (int32_t surfaceIndex = 0; surfaceIndex < surfaceCount;
         ++surfaceIndex) {
        surfs->surfaces[surfaceIndex] = &surfaces[surfaceIndex];
        XModelReadSurface(&surfaces[surfaceIndex], &cursor, alloc);
    }

    FS_FreeFile(fileBuffer);
    entry->surfs = surfs;
    entry->freeData = XModelSurfsFree;
    surfs->next = xmodel_surfsCloneList;
    xmodel_surfsCloneList = surfs;

    return entry;
}

fileData_t *XModelPartsPrecache(const char *name,
                               xmodel_asset_alloc_fn alloc)
{
    fileData_t *entry =
        FS_GetDataForFile(xmodelPartsType, name, xmodel_emptyName);

    if (entry == NULL) {
        if (xmodel_enforceExist == qfalse) {
            Com_Printf("ERROR: Cannot precache 'xmodelparts/%s'", name);
        } else {
            Com_Error(1, "\x15" "Cannot precache 'xmodelparts/%s'.\n"
                         "you may need to get latest and run converter to fix",
                      name);
        }
        return NULL;
    }

    if (entry->data.xmodelParts != NULL) {
        return entry;
    }

    char path[1024];
    /* ORIGINAL_BINARY_BUG: the model-controlled asset name is formatted into
     * this stack path without a bound. See original-bugs/
     * coduomp-xmodel-loader-unbounded-input.md. */
    sprintf(path, "xmodelparts/%s", name);

    void *fileBuffer;
    if (FS_ReadFile(path, &fileBuffer) < 0) {
        Com_Error(1, "\x15" "Cannot find 'xmodelparts/%s'.", name);
        return NULL;
    }

    /* ORIGINAL_BINARY_BUG: FS_ReadFile's byte count is discarded. Signed
     * part counts, names, collision rows, and state bytes advance an unchecked
     * cursor. See original-bugs/coduomp-xmodel-loader-unbounded-input.md. */
    const uint8_t *cursor = fileBuffer;
    int16_t version = coduo_xmodel_read_int16(&cursor);
    if (version != XMODEL_ASSET_VERSION) {
        FS_FreeFile(fileBuffer);
        Com_Error(1,
                  "\x15" "xmodelparts '%s' out of date (version %d, "
                         "expecting %d)",
                  name, version, XMODEL_ASSET_VERSION);
        return NULL;
    }

    int16_t childPartCount = coduo_xmodel_read_int16(&cursor);
    int16_t rootPartCount = coduo_xmodel_read_int16(&cursor);
    int16_t totalPartCount = (int16_t)(rootPartCount + childPartCount);

    uint32_t partNameTableBytes =
        (uint32_t)(sizeof(XModelPartNameTable) -
                   sizeof(((XModelPartNameTable *)0)->handles[0])) +
        (uint32_t)(int32_t)totalPartCount *
            (uint32_t)sizeof(((XModelPartNameTable *)0)->handles[0]);
    XModelPartNameTable *partNameTable =
        alloc((size_t)partNameTableBytes);
    partNameTable->count = totalPartCount;

    if (totalPartCount >= XMODEL_SURFS_MAX_PART_COUNT + 1) {
        Com_Error(1, "\x15" "xmodel '%s' has more than %d bones", name,
                  XMODEL_SURFS_MAX_PART_COUNT);
        return NULL;
    }

    uint32_t partNameSlotBytes =
        (uint32_t)(sizeof(XModelPartNameTableSlot) -
                   sizeof(((XModelPartNameTableSlot *)0)
                              ->parentPartDeltas[0])) +
        (uint32_t)(int32_t)childPartCount *
            (uint32_t)sizeof(((XModelPartNameTableSlot *)0)
                                 ->parentPartDeltas[0]);
    XModelPartNameTableSlot *slot =
        alloc((size_t)partNameSlotBytes);
    slot->partNameTable = partNameTable;

    uint32_t childPartCountBits = (uint32_t)(int32_t)childPartCount;
    uint32_t baseRotationBytes =
        childPartCountBits *
        (uint32_t)sizeof(((XModelPartsData *)0)->baseRotations[0]);
    uint32_t baseTranslationBytes =
        childPartCountBits *
        (uint32_t)sizeof(((XModelPartsData *)0)->baseTranslations[0]);
    /* coduo_lnxded 0x080c2d3e, CoDUOMP.exe 0x0049dddd, and the Mac client
     * 0x000f5148 all request 0x68 + childCount * 0x18 bytes. The loaders write
     * only the 0x18-byte header, childCount packed rotations, and childCount
     * translations. Audited free, base-pose, XAnim, and DObj consumers reach
     * those arrays solely through header pointers and never address the
     * remainder. It is therefore a stock allocation tail unused by this
     * object, not hidden XModelPartsData fields. Preserve it because the
     * allocator cursor is observable, while letting the real pointer-bearing
     * header grow natively. */
    uint32_t stockI386UnusedAllocationBytes =
        (uint32_t)(0x68 -
                   sizeof(xmodel_parts_data_stock_i386_layout_t)) +
        childPartCountBits *
            (uint32_t)(0x18 -
                sizeof(((XModelPartsData *)0)->baseRotations[0]) -
                sizeof(((XModelPartsData *)0)->baseTranslations[0]));
    uint32_t partsAllocationBytes =
        (uint32_t)sizeof(XModelPartsData) + baseRotationBytes +
        baseTranslationBytes + stockI386UnusedAllocationBytes;
    XModelPartsData *parts =
        alloc((size_t)partsAllocationBytes);
    parts->partNameTableSlot = slot;
    parts->rootPartCount = rootPartCount;
    parts->baseRotations =
        (xanim_int16_vec4_t *)((uint8_t *)parts + sizeof(*parts));
    parts->baseTranslations =
        childPartCount == 0
            ? NULL
            : (vec3_t *)((uint8_t *)parts + sizeof(*parts) +
                         baseRotationBytes);
    parts->partStateIndices =
        alloc((size_t)(uint32_t)(int32_t)totalPartCount);
    parts->partCollisions =
        alloc((size_t)((uint32_t)(int32_t)totalPartCount *
                       (uint32_t)sizeof(parts->partCollisions[0])));

    for (int32_t partIndex = rootPartCount; partIndex < totalPartCount;
         ++partIndex) {
        int32_t childIndex = partIndex - rootPartCount;

        slot->parentPartDeltas[childIndex] =
            (uint8_t)(partIndex - *cursor);
        cursor++;
        parts->baseTranslations[childIndex][0] =
            coduo_xmodel_read_float(&cursor);
        parts->baseTranslations[childIndex][1] =
            coduo_xmodel_read_float(&cursor);
        parts->baseTranslations[childIndex][2] =
            coduo_xmodel_read_float(&cursor);

        int16_t packedRotation[3];
        xanim_int16_vec4_t unpackedRotation;

        packedRotation[0] = coduo_xmodel_read_int16(&cursor);
        packedRotation[1] = coduo_xmodel_read_int16(&cursor);
        packedRotation[2] = coduo_xmodel_read_int16(&cursor);
        ReadQuat(packedRotation, &unpackedRotation);
        parts->baseRotations[childIndex].components[0] = unpackedRotation.components[0];
        parts->baseRotations[childIndex].components[1] = unpackedRotation.components[1];
        parts->baseRotations[childIndex].components[2] = unpackedRotation.components[2];
        parts->baseRotations[childIndex].components[3] = unpackedRotation.components[3];
    }

    for (int32_t partIndex = 0; partIndex < totalPartCount; ++partIndex) {
        size_t nameLength = strlen((const char *)cursor);

        partNameTable->handles[partIndex] = SL_GetStringOfLen(
            (const char *)cursor, 0, nameLength + 1,
            XMODEL_PART_NAME_STRING_HANDLE_TYPE);
        cursor += nameLength + 1;

        XModelPartColl *collision =
            &parts->partCollisions[partIndex];
        collision->mins[0] = coduo_xmodel_read_float(&cursor);
        collision->mins[1] = coduo_xmodel_read_float(&cursor);
        collision->mins[2] = coduo_xmodel_read_float(&cursor);
        collision->maxs[0] = coduo_xmodel_read_float(&cursor);
        collision->maxs[1] = coduo_xmodel_read_float(&cursor);
        collision->maxs[2] = coduo_xmodel_read_float(&cursor);

        /* stock stores the three sums to center first, then halves them
         * in place — two float roundings per component (0x80c315f..0x80c31f9) */
        collision->center[0] = collision->mins[0] + collision->maxs[0];
        collision->center[1] = collision->mins[1] + collision->maxs[1];
        collision->center[2] = collision->mins[2] + collision->maxs[2];
        collision->center[0] = collision->center[0] * 0.5f;
        collision->center[1] = collision->center[1] * 0.5f;
        collision->center[2] = collision->center[2] * 0.5f;

        float deltaX = collision->maxs[0] - collision->center[0];
        float deltaY = collision->maxs[1] - collision->center[1];
        float deltaZ = collision->maxs[2] - collision->center[2];
        collision->radiusSq =
            deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ;
    }

    memcpy(parts->partStateIndices, cursor,
           (size_t)(uint32_t)(int32_t)totalPartCount);
    FS_FreeFile(fileBuffer);

    entry->data.xmodelParts = parts;
    entry->freeData = XModelPartsFree;
    return entry;
}

qboolean XModelExists(const char *name)
{
    return FS_GetDataForFile("xmodel", name, xmodel_emptyName) != NULL;
}

const uint8_t *XModelLoadConfigFile(const char *name,
                                    const uint8_t *cursor,
                                    XModelConfig *header)
{
    int16_t version = coduo_xmodel_read_int16(&cursor);

    if (version != XMODEL_ASSET_VERSION) {
        Com_Error(1,
                  "\x15" "xmodel '%s' out of date (version %d, "
                         "expecting %d)",
                  name, version, XMODEL_ASSET_VERSION);
        return NULL;
    }

    header->mins[0] = coduo_xmodel_read_float(&cursor);
    header->mins[1] = coduo_xmodel_read_float(&cursor);
    header->mins[2] = coduo_xmodel_read_float(&cursor);
    header->maxs[0] = coduo_xmodel_read_float(&cursor);
    header->maxs[1] = coduo_xmodel_read_float(&cursor);
    header->maxs[2] = coduo_xmodel_read_float(&cursor);

    for (int32_t lodIndex = 0; lodIndex < XMODEL_DEFAULT_LOD_COUNT;
         ++lodIndex) {
        header->lods[lodIndex].distance =
            coduo_xmodel_read_float(&cursor);
        /* ORIGINAL_BINARY_BUG: stock's NUL copy has no bound on this
         * 1,024-byte LOD-name row. See original-bugs/
         * coduomp-xmodel-loader-unbounded-input.md. */
        strcpy(header->lods[lodIndex].name, (const char *)cursor);
        cursor += strlen((const char *)cursor) + 1;
    }

    header->modelFileCount =
        (int32_t)coduo_xmodel_read_uint32(&cursor);
    return cursor;
}

const uint8_t *XModelLoadCollData(
    const uint8_t *cursor, XModelInfo *collision,
    xmodel_asset_alloc_fn alloc)
{
    /* ORIGINAL_BINARY_BUG: authored collision-surface and triangle counts
     * advance this cursor without a file end or length check. See
     * original-bugs/coduomp-xmodel-loader-unbounded-input.md. */
    float boundsEpsilon =
        coduo_xmodel_float_constant(XMODEL_COLLISION_BOUNDS_EPSILON_BITS);

    collision->collisionSurfaceCount =
        (int32_t)coduo_xmodel_read_uint32(&cursor);
    collision->contents = 0;

    if (collision->collisionSurfaceCount == 0) {
        collision->collisionSurfaces = NULL;
        return cursor;
    }

    collision->collisionSurfaces =
        alloc((size_t)((uint32_t)collision->collisionSurfaceCount *
                       (uint32_t)sizeof(
                           collision->collisionSurfaces[0])));

    for (int32_t surfaceIndex = 0;
         surfaceIndex < collision->collisionSurfaceCount; ++surfaceIndex) {
        XModelCollSurf *surface =
            &collision->collisionSurfaces[surfaceIndex];

        surface->numCollTris =
            (int32_t)coduo_xmodel_read_uint32(&cursor);
        surface->collTris =
            alloc((size_t)((uint32_t)surface->numCollTris *
                           (uint32_t)sizeof(surface->collTris[0])));

        for (int32_t facetIndex = 0; facetIndex < surface->numCollTris;
             ++facetIndex) {
            XModelCollTri *facet =
                &surface->collTris[facetIndex];

            for (int32_t planeIndex = 0;
                 planeIndex < CODUO_XMODEL_COLLISION_FACET_PLANE_COUNT;
                 ++planeIndex) {
                facet->planes[planeIndex].normal[0] =
                    coduo_xmodel_read_float(&cursor);
                facet->planes[planeIndex].normal[1] =
                    coduo_xmodel_read_float(&cursor);
                facet->planes[planeIndex].normal[2] =
                    coduo_xmodel_read_float(&cursor);
                facet->planes[planeIndex].distance =
                    coduo_xmodel_read_float(&cursor);
            }
        }

        surface->expandedMins[0] =
            coduo_xmodel_read_float(&cursor) - boundsEpsilon;
        surface->expandedMins[1] =
            coduo_xmodel_read_float(&cursor) - boundsEpsilon;
        surface->expandedMins[2] =
            coduo_xmodel_read_float(&cursor) - boundsEpsilon;
        surface->expandedMaxs[0] =
            coduo_xmodel_read_float(&cursor) + boundsEpsilon;
        surface->expandedMaxs[1] =
            coduo_xmodel_read_float(&cursor) + boundsEpsilon;
        surface->expandedMaxs[2] =
            coduo_xmodel_read_float(&cursor) + boundsEpsilon;
        surface->basePoseIndex =
            (int32_t)coduo_xmodel_read_uint32(&cursor);
        surface->contents =
            (int32_t)(coduo_xmodel_read_uint32(&cursor) &
                                    XMODEL_COLLISION_CONTENTS_MASK);
        surface->surfaceFlags =
            (int32_t)coduo_xmodel_read_uint32(&cursor);

        collision->contents |= surface->contents;
    }

    return cursor;
}

XModel *XModelPrecache(const char *name, qboolean loadSurfaces,
                                     xmodel_asset_alloc_fn alloc,
                                     xmodel_asset_alloc_fn optionalAlloc)
{
    (void)optionalAlloc;

    XModel *entry =
        FS_GetDataForFile("xmodel", name, xmodel_emptyName);

    if (entry == NULL) {
        if (xmodel_enforceExist != qfalse) {
            Com_Error(1, "\x15" "Cannot precache 'xmodel/%s'.\n"
                         "you may need to get latest and run converter to fix",
                      name);
            return NULL;
        }

        Com_Printf("ERROR: Cannot precache 'xmodel/%s'", name);
        return XModelCreateDefault_();
    }

    XModelInfo *collision = entry->info;
    if (collision == NULL) {
        char path[1024];
        void *fileBuffer;
        XModelConfig header;

        /* ORIGINAL_BINARY_BUG: the registry name is formatted into this
         * stack path without a bound. See original-bugs/
         * coduomp-xmodel-loader-unbounded-input.md. */
        sprintf(path, "xmodel/%s", name);
        if (FS_ReadFile(path, &fileBuffer) < 0) {
            Com_Error(1, "\x15" "Cannot find 'xmodel/%s'.", name);
            return NULL;
        }

        /* ORIGINAL_BINARY_BUG: FS_ReadFile's byte count is discarded. The
         * config, collision, LOD surface-count, and surface-name cursors have
         * no input end. See original-bugs/
         * coduomp-xmodel-loader-unbounded-input.md. */
        const uint8_t *cursor =
            XModelLoadConfigFile(name, fileBuffer, &header);
        if (cursor == NULL) {
            FS_FreeFile(fileBuffer);
            return NULL;
        }

        int32_t lodNameBytes = 0;
        int32_t lodNameLengths[XMODEL_DEFAULT_LOD_COUNT];
        for (int32_t lodIndex = 0; lodIndex < XMODEL_DEFAULT_LOD_COUNT;
             ++lodIndex) {
            lodNameLengths[lodIndex] =
                (int32_t)strlen(header.lods[lodIndex].name) + 1;
            lodNameBytes += lodNameLengths[lodIndex];
        }

        collision = alloc(
            (size_t)((uint32_t)sizeof(*collision) +
                     (uint32_t)lodNameBytes));
        cursor = XModelLoadCollData(cursor, collision, alloc);

        char *lodNameStorage = (char *)(collision + 1);
        collision->lodCount = 0;
        for (int32_t lodIndex = 0; lodIndex < XMODEL_DEFAULT_LOD_COUNT;
             ++lodIndex) {
            XModelLodInfo *lod = &collision->lodRecords[lodIndex];

            strcpy(lodNameStorage, header.lods[lodIndex].name);
            lod->name = lodNameStorage;
            lodNameStorage += lodNameLengths[lodIndex];

            if (lod->name[0] == '\0') {
                lod->surfaceNameTable = NULL;
            } else {
                collision->lodCount++;
                lod->surfaceCount = coduo_xmodel_read_int16(&cursor);
                lod->surfaceNameTable =
                    alloc((size_t)((uint32_t)(int32_t)lod->surfaceCount *
                                   (uint32_t)sizeof(
                                       lod->surfaceNameTable[0])));

                for (int32_t surfaceIndex = 0;
                     surfaceIndex < lod->surfaceCount; ++surfaceIndex) {
                    const char *surfaceName = (const char *)cursor;

                    cursor += strlen(surfaceName) + 1;
                    lod->surfaceNameTable[surfaceIndex] = SL_GetString_(
                        surfaceName, 0,
                        XMODEL_SURFACE_NAME_STRING_HANDLE_TYPE);
                }
            }
            lod->distance = header.lods[lodIndex].distance;
        }

        FS_FreeFile(fileBuffer);
        memcpy(collision->mins, header.mins, sizeof(collision->mins));
        memcpy(collision->maxs, header.maxs, sizeof(collision->maxs));
        collision->modelFileCount = (int16_t)header.modelFileCount;

        entry->info = collision;
        entry->freeData = XModelFree;
        collision->lodRecords[0].surfs = NULL;
        collision->lodRecords[1].surfs = NULL;
        collision->lodRecords[2].surfs = NULL;
    } else if (XModelBad(entry) != qfalse) {
        return entry;
    }

    collision->parts =
        XModelPartsPrecache(collision->lodRecords[0].name, alloc);
    if (collision->parts == NULL) {
        XModelFree((fileData_t *)entry);
        XModelCreateDefault(entry);
        return entry;
    }

    if (loadSurfaces == qfalse) {
        return entry;
    }

    for (int32_t lodIndex = 0;
         lodIndex < XMODEL_DEFAULT_LOD_COUNT &&
         collision->lodRecords[lodIndex].name[0] != '\0';
         ++lodIndex) {
        collision->lodRecords[lodIndex].surfs =
            XModelSurfsPrecache(collision->lodRecords[lodIndex].name, alloc);
        if (collision->lodRecords[lodIndex].surfs == NULL) {
            XModelFree((fileData_t *)entry);
            XModelCreateDefault(entry);
            return entry;
        }
    }

    return entry;
}

void XModelClearData(void *rangeStart, void *rangeEnd)
{
    uintptr_t first = (uintptr_t)rangeStart;
    uintptr_t limit = (uintptr_t)rangeEnd;
    XModelSurfsData **link = &xmodel_surfsCloneList;

    while (*link != NULL) {
        XModelSurfsData *surfs = *link;
        uintptr_t surfsAddress = (uintptr_t)surfs;

        if (surfsAddress >= first && surfsAddress < limit) {
            *link = surfs->next;
            continue;
        }

        for (int32_t surfaceIndex = 0; surfaceIndex < surfs->surfaceCount;
             ++surfaceIndex) {
            XSurface *surface = surfs->surfaces[surfaceIndex];

            if (surface == NULL) {
                continue;
            }

            uintptr_t nvAddress = (uintptr_t)surface->optimizedDataNV;
            if (nvAddress >= first && nvAddress < limit) {
                surface->optimizedDataNV = NULL;
            }

            uintptr_t atiAddress = (uintptr_t)surface->optimizedDataATI;
            if (atiAddress >= first && atiAddress < limit) {
                surface->optimizedDataATI = NULL;
            }
        }

        link = &surfs->next;
    }
}

int32_t XModelNumBones(const XModel *model)
{
    const XModelInfo *collision = model->info;
    const fileData_t *partsEntry = collision->parts;
    const XModelPartsData *parts = partsEntry->data.xmodelParts;
    const XModelPartNameTableSlot *slot = parts->partNameTableSlot;

    return slot->partNameTable->count;
}

const uint16_t *XModelBoneNames(const XModel *model)
{
    const XModelInfo *collision = model->info;
    const fileData_t *partsEntry = collision->parts;
    const XModelPartsData *parts = partsEntry->data.xmodelParts;
    const XModelPartNameTableSlot *slot = parts->partNameTableSlot;

    return slot->partNameTable->handles;
}

int32_t XModelGetBoneIndex(const XModel *model, uint16_t name)
{
    const uint16_t *partNames = XModelBoneNames(model);

    int32_t partIndex = XModelNumBones(model) - 1;
    for (; partIndex >= 0; --partIndex) {
        if (partNames[partIndex] == name) {
            return partIndex;
        }
    }

    return partIndex;
}

void XModelGetBounds(const XModel *model, vec3_t mins, vec3_t maxs)
{
    const XModelInfo *collision = model->info;

    memcpy(mins, collision->mins, sizeof(collision->mins));
    memcpy(maxs, collision->maxs, sizeof(collision->maxs));
}

int32_t XSurfaceGetNumVerts(
    const XSurface *surface)
{
    return surface->vertexCount;
}

int32_t XSurfaceGetNumTris(
    const XSurface *surface)
{
    return surface->triangleCount;
}

int32_t XSurfaceTileMode(
    const XSurface *surface)
{
    return surface->tileMode;
}

void XSurfaceGetTris(const XSurface *surface,
                     xmodel_triangle_indices_t *triangles,
                     int16_t baseIndex)
{
    if (baseIndex == 0) {
        memcpy(triangles, surface->triangles,
               (size_t)((uint32_t)(int32_t)surface->triangleCount *
                        (uint32_t)sizeof(surface->triangles[0])));
        return;
    }

    /* ORIGINAL_BINARY_BUG: stock enters this pair-copy body once even when
     * the signed triangle count yields zero complete pairs. See
     * original-bugs/coduomp-xsurface-gettris-short-pair-oob.md. */
    uint16_t truncatedBaseIndex = (uint16_t)baseIndex;
    uint32_t packedBaseIndex =
        (uint32_t)truncatedBaseIndex |
        ((uint32_t)truncatedBaseIndex << 16);
    const uint8_t *sourceBytes = (const uint8_t *)surface->triangles;
    uint8_t *destBytes = (uint8_t *)triangles;
    int32_t packedTrianglePairCount = surface->triangleCount >> 1;
    int32_t trianglePairIndex = 0;
    do {
        for (int32_t packedLane = 0;
             packedLane < XMODEL_SURFACE_TRIANGLE_INDEX_COUNT; ++packedLane) {
            int32_t wordIndex =
                trianglePairIndex * XMODEL_SURFACE_TRIANGLE_INDEX_COUNT +
                packedLane;
            uint32_t packedIndices;

            memcpy(&packedIndices,
                   &sourceBytes[wordIndex * sizeof(packedIndices)],
                   sizeof(packedIndices));
            packedIndices += packedBaseIndex;
            memcpy(&destBytes[wordIndex * sizeof(packedIndices)],
                   &packedIndices, sizeof(packedIndices));
        }
        ++trianglePairIndex;
        --packedTrianglePairCount;
    } while (packedTrianglePairCount != 0);
}

xmodel_surface_blend_info_array_t
XSurfaceGetBlendInfoArray(const XSurface *surface)
{
    xmodel_surface_blend_info_array_t result;

    result.blendInfo = surface->vertexData.blendPrimaryStream;
    return result;
}

vec2_t *XSurfaceGetTexCoordArray(const XSurface *surface)
{
    return surface->texCoords;
}

XSurfaceWeightedPoint *XSurfaceGetVertexInfoArray(
    const XSurface *surface)
{
    return surface->weightedPoints;
}

int32_t XSurfaceGetBoneIndex(
    const XSurface *surface)
{
    return surface->boneIndex;
}

void XSurfaceRemapTextureCoordinates(XSurface *surface,
                                     const vec2_t scale, const vec2_t offset,
                                     int32_t sourceUIndex,
                                     int32_t sourceVIndex)
{
    vec2_t *texCoords = surface->texCoords;
    int32_t vertexCount = surface->vertexCount;
    if (vertexCount == 0) {
        return;
    }

    /* ORIGINAL_BINARY_BUG: negative authored vertex counts are nonzero and
     * drive this dword countdown until wrap. See
     * original-bugs/coduomp-xmodel-loader-unbounded-input.md. */
    int32_t vertexIndex = 0;
    do {
        float sourceV = texCoords[vertexIndex][sourceVIndex];

        texCoords[vertexIndex][0] =
            offset[0] + scale[0] * texCoords[vertexIndex][sourceUIndex];
        texCoords[vertexIndex][1] = offset[1] + scale[1] * sourceV;
        ++vertexIndex;
        --vertexCount;
    } while (vertexCount != 0);
}

const char *XModelGetName(XModel *model)
{
    const XModel *entry =
        model;

    return entry->name;
}

int32_t XModelGetContents(XModel *model)
{
    const XModel *entry =
        model;
    const XModelInfo *collision = entry->info;

    return collision->contents;
}

int32_t XModelGetNumLods(XModel *model)
{
    const XModel *entry =
        model;
    const XModelInfo *collision = entry->info;

    return collision->lodCount;
}

int16_t
XModelGetModelFileCount(XModel *model)
{
    const XModel *entry =
        model;
    const XModelInfo *collision = entry->info;

    return collision->modelFileCount;
}

void XModelSetTestLods(int32_t lodIndex,
                       float distance)
{
    if (lodIndex == 0) {
        xmodel_testLodsEnabled = 0.0f <= distance;
    }

    if (distance < 0.0f) {
        distance = 0.0f;
    }

    xmodel_testLodDistances[lodIndex].distance = distance;
}

void XModelSetTestLodDist(float distance)
{
    xmodel_testLodDist = distance > 0.0f ? distance : 0.0f;
}

int32_t XModelGetLodForDist(
    const XModel *model, float distance)
{
    const XModelInfo *collision = model->info;

    if (xmodel_testLodDist != 0.0f) {
        distance = xmodel_testLodDist;
    }

    for (int32_t lodIndex = 0;
         lodIndex < XModelGetNumLods((XModel *)model);
         ++lodIndex) {
        float lodDistance =
            xmodel_testLodsEnabled != qfalse
                ? xmodel_testLodDistances[lodIndex].distance
                : collision->lodRecords[lodIndex].distance;

        if (lodDistance == 0.0f || distance < lodDistance) {
            return lodIndex;
        }
    }

    return -1;
}

int32_t XModelGetSurfaces(
    const XModel *model, XSurface ***surfacesOut,
    int32_t lodIndex)
{
    const XModelInfo *collision = model->info;
    const XModelLodInfo *lod = &collision->lodRecords[lodIndex];
    const XModelSurfsData *surfs = lod->surfs->surfs;

    *surfacesOut = surfs->surfaces;
    return surfs->surfaceCount;
}

const char *XModelGetSurfaceName(const XModel *model,
                                 int32_t surfaceIndex,
                                 int32_t lodIndex)
{
    const XModelInfo *collision = model->info;
    const XModelLodInfo *lod = &collision->lodRecords[lodIndex];
    uint16_t name =
        lod->surfaceNameTable[surfaceIndex];

    if (name == 0) {
        return xmodel_defaultName;
    }

    return SL_ConvertToString(name);
}

XSurface *XSurfaceCloneSurface(
    const XSurface *surface, xmodel_asset_alloc_fn alloc)
{
    XSurface *clone = alloc(sizeof(*clone));

    *clone = *surface;
    clone->optimizedDataATI = NULL;
    clone->optimizedDataNV = NULL;
    clone->texCoords = alloc(
        (size_t)((uint32_t)(int32_t)surface->vertexCount *
                 (uint32_t)sizeof(surface->texCoords[0])));
    Com_Memcpy(clone->texCoords, surface->texCoords,
               (size_t)((uint32_t)(int32_t)surface->vertexCount *
                        (uint32_t)sizeof(surface->texCoords[0])));

    return clone;
}

void XModelGetBasePose(XModel *model,
                       DObjSkelMat *basePose)
{
    const XModel *entry =
        model;
    const XModelInfo *collision = entry->info;
    const fileData_t *partsEntry = collision->parts;
    const XModelPartsData *parts = partsEntry->data.xmodelParts;
    const XModelPartNameTableSlot *slot = parts->partNameTableSlot;
    int32_t totalPartCount = slot->partNameTable->count;
    int32_t rootPartCount = parts->rootPartCount;
    const float packedQuatScale =
        3.0518509447574615e-05f; /* It is effectively the binary32 representation of 1.0 / 32767.0. */

    /* ORIGINAL_BINARY_BUG: all four stock part walks use signed nonzero
     * countdowns. Negative authored root or derived child counts therefore
     * walk pose and packed-part storage until dword wrap. See
     * original-bugs/coduomp-xmodel-loader-unbounded-input.md. */
    int32_t remaining = rootPartCount;
    int32_t partIndex = 0;
    if (remaining != 0) {
        do {
            basePose[partIndex].axis[0][0] = 0.0f;
            basePose[partIndex].axis[0][1] = 0.0f;
            basePose[partIndex].axis[0][2] = 0.0f;
            basePose[partIndex].axis[0][3] = 1.0f;
            ++partIndex;
            --remaining;
        } while (remaining != 0);
    }

    remaining = totalPartCount - rootPartCount;
    partIndex = rootPartCount;
    int32_t childIndex = 0;
    if (remaining != 0) {
        do {
            vec4_t localRotation;

            /* no (float) casts on the int16 rotations: stock feeds each bare
             * fild straight into the fmul (0x80c4704..0x80c4747) */
            localRotation[0] =
                parts->baseRotations[childIndex].components[0] *
                packedQuatScale;
            localRotation[1] =
                parts->baseRotations[childIndex].components[1] *
                packedQuatScale;
            localRotation[2] =
                parts->baseRotations[childIndex].components[2] *
                packedQuatScale;
            localRotation[3] =
                parts->baseRotations[childIndex].components[3] *
                packedQuatScale;

            QuatMultiply(localRotation,
                         basePose[partIndex -
                                  slot->parentPartDeltas[childIndex]]
                             .axis[0],
                         basePose[partIndex].axis[0]);
            ++childIndex;
            ++partIndex;
            --remaining;
        } while (remaining != 0);
    }

    remaining = rootPartCount;
    partIndex = 0;
    if (remaining != 0) {
        do {
            basePose[partIndex].axis[0][0] = 1.0f;
            basePose[partIndex].axis[0][1] = 0.0f;
            basePose[partIndex].axis[0][2] = 0.0f;
            basePose[partIndex].axis[1][0] = 0.0f;
            basePose[partIndex].axis[1][1] = 1.0f;
            basePose[partIndex].axis[1][2] = 0.0f;
            basePose[partIndex].axis[2][0] = 0.0f;
            basePose[partIndex].axis[2][1] = 0.0f;
            basePose[partIndex].axis[2][2] = 1.0f;
            basePose[partIndex].origin[0] = 0.0f;
            basePose[partIndex].origin[1] = 0.0f;
            basePose[partIndex].origin[2] = 0.0f;
            ++partIndex;
            --remaining;
        } while (remaining != 0);
    }

    remaining = totalPartCount - rootPartCount;
    partIndex = rootPartCount;
    childIndex = 0;
    if (remaining != 0) {
        do {
            DObjSkelMat *pose = &basePose[partIndex];
            const DObjSkelMat *parent =
                &basePose[partIndex -
                          slot->parentPartDeltas[childIndex]];

            XModelExpandQuatToAxis(pose->axis[0]);
            XSurfaceTransformPoint43(parts->baseTranslations[childIndex],
                                     parent, pose->origin);
            ++childIndex;
            ++partIndex;
            --remaining;
        } while (remaining != 0);
    }
}

void XSurfaceGetVerts(const XSurface *surface,
                      const DObjSkelMat *basePose,
                      vec3_t *outVerts, vec2_t *outTexCoords,
                      vec3_t *outNormals)
{
    if (outTexCoords != NULL) {
        memcpy(outTexCoords, surface->texCoords,
               (size_t)((uint32_t)(int32_t)surface->vertexCount *
                        (uint32_t)sizeof(surface->texCoords[0])));
    }

    /* ORIGINAL_BINARY_BUG: both vertex paths and every nonzero additive-
     * weight path use signed nonzero dword countdowns. Negative authored
     * counts therefore walk vertex, pose, and output storage until wrap. See
     * original-bugs/coduomp-xmodel-loader-unbounded-input.md. */
    if (XSurfaceGetBoneIndex(surface) == XMODEL_SURFS_NO_SINGLE_BONE) {
        const uint8_t *primaryVertexCursor =
            surface->vertexData.blendPrimaryStream;
        const XSurfaceWeightedPoint *additiveVerts =
            (const XSurfaceWeightedPoint *)
                surface->weightedPoints;

        int32_t remainingVertices = surface->vertexCount;
        int32_t vertexIndex = 0;
        while (remainingVertices != 0) {
            const XSurfaceBlendVert *primary =
                (const XSurfaceBlendVert *)
                    primaryVertexCursor;
            const DObjSkelMat *primaryPose =
                (const DObjSkelMat
                     *)((const uint8_t *)basePose +
                        primary->blend.boneMatrixOffset);

            if (outNormals != NULL) {
                XSurfaceTransformNormal43(primary->normal, primaryPose,
                                          outNormals[vertexIndex]);
            }

            XSurfaceTransformPoint43(primary->blend.position, primaryPose,
                                     outVerts[vertexIndex]);

            if (primary->additiveWeightCount != 0) {
                outVerts[vertexIndex][0] *= primary->primaryWeight;
                outVerts[vertexIndex][1] *= primary->primaryWeight;
                outVerts[vertexIndex][2] *= primary->primaryWeight;

                int32_t remainingWeights = primary->additiveWeightCount;
                do {
                    const XSurfaceWeightedPoint *additive =
                        additiveVerts++;
                    const DObjSkelMat *additivePose =
                        (const DObjSkelMat *)(
                            (const uint8_t *)basePose +
                            additive->blend.boneMatrixOffset);

                    XSurfaceAccumulateWeightedPoint43(
                        additive->blend.position, additive->weight,
                        additivePose, outVerts[vertexIndex]);
                    --remainingWeights;
                } while (remainingWeights != 0);

                primaryVertexCursor +=
                    sizeof(XSurfaceBlendVert);
            } else {
                primaryVertexCursor +=
                    sizeof(XSurfaceBlendVertNoWeight);
            }

            ++vertexIndex;
            --remainingVertices;
        }

        return;
    }

    const DObjSkelMat *rigidPose =
        (const DObjSkelMat *)((const uint8_t *)basePose +
                                           surface->boneIndex);
    const XSurfaceRigidVert *rigidVerts =
        surface->vertexData.rigidVertices;

    int32_t remainingVertices = surface->vertexCount;
    int32_t vertexIndex = 0;
    while (remainingVertices != 0) {
        if (outNormals != NULL) {
            XSurfaceTransformNormal43(rigidVerts[vertexIndex].normal,
                                      rigidPose, outNormals[vertexIndex]);
        }

        XSurfaceTransformPoint43(rigidVerts[vertexIndex].position,
                                 rigidPose, outVerts[vertexIndex]);
        ++vertexIndex;
        --remainingVertices;
    }
}

int32_t
XModelTraceLine(XModel *model,
                trace_t *traceState,
                const DObjSkelMat *basePose, const vec3_t start,
                const vec3_t end, int32_t contentMask)
{
    const XModel *entry =
        model;
    const XModelInfo *collision = entry->info;
    (void)XModelNumBones(model);
    int32_t hitPart = -1;
    float planeOffsetEpsilon =
        coduo_xmodel_float_constant(
            XMODEL_TRACE_PLANE_OFFSET_EPSILON_BITS);
    float barycentricMin =
        coduo_xmodel_float_constant(XMODEL_TRACE_BARYCENTRIC_MIN_BITS);
    float barycentricMax =
        coduo_xmodel_float_constant(XMODEL_TRACE_BARYCENTRIC_MAX_BITS);

    for (int32_t surfaceIndex = 0;
         surfaceIndex < collision->collisionSurfaceCount; ++surfaceIndex) {
        const XModelCollSurf *surface =
            &collision->collisionSurfaces[surfaceIndex];

        if ((contentMask & surface->contents) == 0) {
            continue;
        }

        const DObjSkelMat *pose =
            &basePose[surface->basePoseIndex];
        vec3_t offsetStart;
        vec3_t offsetEnd;
        vec3_t localStart;
        vec3_t localEnd;

        offsetStart[0] = start[0] - pose->origin[0];
        offsetStart[1] = start[1] - pose->origin[1];
        offsetStart[2] = start[2] - pose->origin[2];
        XSurfaceTransformVectorRows43(offsetStart, pose, localStart);

        offsetEnd[0] = end[0] - pose->origin[0];
        offsetEnd[1] = end[1] - pose->origin[1];
        offsetEnd[2] = end[2] - pose->origin[2];
        XSurfaceTransformVectorRows43(offsetEnd, pose, localEnd);

        if (CM_TraceLineSkipsBox(localStart, localEnd, surface->expandedMins,
                                 surface->expandedMaxs,
                                 traceState->fraction) != qfalse) {
            continue;
        }

        vec3_t delta = {
            localEnd[0] - localStart[0],
            localEnd[1] - localStart[1],
            localEnd[2] - localStart[2],
        };

        for (int32_t facetIndex = 0; facetIndex < surface->numCollTris;
             ++facetIndex) {
            const XModelCollTri *facet =
                &surface->collTris[facetIndex];
            const XModelCollTriPlane *plane0 =
                &facet->planes[0];

            float endDist = localEnd[0] * plane0->normal[0] +
                            localEnd[1] * plane0->normal[1] +
                            localEnd[2] * plane0->normal[2] -
                            plane0->distance;

            if (endDist >= 0.0f) {
                continue;
            }

            float startDist =
                localStart[0] * plane0->normal[0] +
                localStart[1] * plane0->normal[1] +
                localStart[2] * plane0->normal[2] - plane0->distance;

            if (startDist <= 0.0f) {
                continue;
            }

            float hitFraction =
                (startDist - planeOffsetEpsilon) / (startDist - endDist);
            if (hitFraction >= traceState->fraction) {
                continue;
            }

            float planeFraction = startDist / (startDist - endDist);
            vec3_t hitPoint = {
                localStart[0] + delta[0] * planeFraction,
                localStart[1] + delta[1] * planeFraction,
                localStart[2] + delta[2] * planeFraction,
            };

            const XModelCollTriPlane *plane1 =
                &facet->planes[1];
            float bary0 = hitPoint[0] * plane1->normal[0] +
                          hitPoint[1] * plane1->normal[1] +
                          hitPoint[2] * plane1->normal[2] - plane1->distance;
            if (bary0 < barycentricMin || bary0 > barycentricMax) {
                continue;
            }

            const XModelCollTriPlane *plane2 =
                &facet->planes[2];
            float bary1 = hitPoint[0] * plane2->normal[0] +
                          hitPoint[1] * plane2->normal[1] +
                          hitPoint[2] * plane2->normal[2] - plane2->distance;
            if (bary1 < barycentricMin ||
                bary0 + bary1 > barycentricMax) {
                continue;
            }

            hitPart = surface->basePoseIndex;
            traceState->allsolid = 0;
            traceState->startsolid = 0;
            traceState->fraction = hitFraction;
            traceState->surfaceFlags = surface->surfaceFlags;
            traceState->contents = surface->contents;
            traceState->normal[0] = plane0->normal[0];
            traceState->normal[1] = plane0->normal[1];
            traceState->normal[2] = plane0->normal[2];
        }
    }

    if (hitPart < 0) {
        return -1;
    }

    const DObjSkelMat *pose = &basePose[hitPart];
    vec3_t worldNormal;

    XSurfaceTransformNormal43(traceState->normal, pose, worldNormal);
    traceState->normal[0] = worldNormal[0];
    traceState->normal[1] = worldNormal[1];
    traceState->normal[2] = worldNormal[2];

    return hitPart;
}

qboolean XModelGetStaticBounds(XModel *model,
                               vec3_t transform[3],
                               vec3_t mins, vec3_t maxs)
{
    const XModel *entry =
        model;
    const XModelInfo *collision = entry->info;

    if (collision->collisionSurfaceCount == 0) {
        return qfalse;
    }

    mins[0] = FLT_MAX;
    mins[1] = FLT_MAX;
    mins[2] = FLT_MAX;
    maxs[0] = -FLT_MAX;
    maxs[1] = -FLT_MAX;
    maxs[2] = -FLT_MAX;

    for (int32_t surfaceIndex = 0;
         surfaceIndex < collision->collisionSurfaceCount; ++surfaceIndex) {
        const XModelCollSurf *surface =
            &collision->collisionSurfaces[surfaceIndex];

        for (int32_t corner = 0; corner < XMODEL_STATIC_BOUNDS_CORNER_COUNT;
             ++corner) {
            vec3_t localCorner;
            vec3_t transformedCorner;

            localCorner[0] =
                (corner & 1) == 0 ? surface->expandedMaxs[0]
                                  : surface->expandedMins[0];
            localCorner[1] =
                (corner & 2) == 0 ? surface->expandedMaxs[1]
                                  : surface->expandedMins[1];
            localCorner[2] =
                (corner & 4) == 0 ? surface->expandedMaxs[2]
                                  : surface->expandedMins[2];

            MatrixTransformVector(localCorner, transform, transformedCorner);

            for (int32_t axis = 0; axis < 3; ++axis) {
                if (transformedCorner[axis] < mins[axis]) {
                    mins[axis] = transformedCorner[axis];
                }
                if (maxs[axis] < transformedCorner[axis]) {
                    maxs[axis] = transformedCorner[axis];
                }
            }
        }
    }

    return qtrue;
}
