20 #include "format/md2.h" 
   21 #include "format/md3.h" 
   22 #include "format/sp2.h" 
   24 #if MAX_ALIAS_VERTS > TESS_MAX_VERTICES 
   25 #error TESS_MAX_VERTICES 
   28 #if MD2_MAX_TRIANGLES > TESS_MAX_INDICES / 3 
   29 #error TESS_MAX_INDICES 
   35     dmd2frame_t     *src_frame;
 
   36     dmd2trivertx_t  *src_vert;
 
   37     dmd2triangle_t  *src_tri;
 
   49     int             numverts, numindices;
 
   50     char            skinname[MAX_QPATH];
 
   51     vec_t           scale_s, scale_t;
 
   55     if (length < 
sizeof(header)) {
 
   56         return Q_ERR_FILE_TOO_SMALL;
 
   60     header = *(dmd2header_t *)rawdata;
 
   61     for (i = 0; i < 
sizeof(header) / 4; i++) {
 
   62         ((uint32_t *)&header)[i] = LittleLong(((uint32_t *)&header)[i]);
 
   68         if (ret == Q_ERR_TOO_FEW) {
 
   70             model->type = MOD_EMPTY;
 
   78     src_tri = (dmd2triangle_t *)((
byte *)rawdata + header.ofs_tris);
 
   79     for (i = 0; i < header.num_tris; i++) {
 
   80         for (j = 0; j < 3; j++) {
 
   81             uint16_t idx_xyz = LittleShort(src_tri->index_xyz[j]);
 
   82             uint16_t idx_st = LittleShort(src_tri->index_st[j]);
 
   85             if (idx_xyz >= header.num_xyz || idx_st >= header.num_st) {
 
   89             vertIndices[numindices + j] = idx_xyz;
 
   90             tcIndices[numindices + j] = idx_st;
 
  100         return Q_ERR_TOO_FEW;
 
  103     for (i = 0; i < numindices; i++) {
 
  109     src_tc = (dmd2stvert_t *)((
byte *)rawdata + header.ofs_st);
 
  110     for (i = 0; i < numindices; i++) {
 
  111         if (remap[i] != 0xFFFF) {
 
  115         for (j = i + 1; j < numindices; j++) {
 
  116             if (vertIndices[i] == vertIndices[j] &&
 
  117                 (src_tc[tcIndices[i]].s == src_tc[tcIndices[j]].s &&
 
  118                  src_tc[tcIndices[i]].t == src_tc[tcIndices[j]].t)) {
 
  121                 finalIndices[j] = numverts;
 
  127         finalIndices[i] = numverts++;
 
  131         return Q_ERR_TOO_MANY;
 
  135     model->type = MOD_ALIAS;
 
  136     model->nummeshes = 1;
 
  137     model->numframes = header.num_frames;
 
  139     model->frames = MOD_Malloc(header.num_frames * 
sizeof(
maliasframe_t));
 
  141     dst_mesh = model->meshes;
 
  142     dst_mesh->
numtris = numindices / 3;
 
  145     dst_mesh->
numskins = header.num_skins;
 
  146     dst_mesh->
verts = MOD_Malloc(numverts * header.num_frames * 
sizeof(
maliasvert_t));
 
  150     if (dst_mesh->
numtris != header.num_tris) {
 
  151         Com_DPrintf(
"%s has %d bad triangles\n", model->name, header.num_tris - dst_mesh->
numtris);
 
  155     for (i = 0; i < numindices; i++) {
 
  156         dst_mesh->
indices[i] = finalIndices[i];
 
  160     src_skin = (
char *)rawdata + header.ofs_skins;
 
  161     for (i = 0; i < header.num_skins; i++) {
 
  162         if (!
Q_memccpy(skinname, src_skin, 0, 
sizeof(skinname))) {
 
  163             ret = Q_ERR_STRING_TRUNCATED;
 
  168         src_skin += MD2_MAX_SKINNAME;
 
  172     src_tc = (dmd2stvert_t *)((
byte *)rawdata + header.ofs_st);
 
  174     scale_s = 1.0f / header.skinwidth;
 
  175     scale_t = 1.0f / header.skinheight;
 
  176     for (i = 0; i < numindices; i++) {
 
  180         dst_tc[finalIndices[i]].
st[0] =
 
  181             (int16_t)LittleShort(src_tc[tcIndices[i]].s) * scale_s;
 
  182         dst_tc[finalIndices[i]].
st[1] =
 
  183             (int16_t)LittleShort(src_tc[tcIndices[i]].t) * scale_t;
 
  187     src_frame = (dmd2frame_t *)((
byte *)rawdata + header.ofs_frames);
 
  188     dst_frame = model->frames;
 
  189     for (j = 0; j < header.num_frames; j++) {
 
  190         LittleVector(src_frame->scale, dst_frame->
scale);
 
  191         LittleVector(src_frame->translate, dst_frame->
translate);
 
  195         for (i = 0; i < numindices; i++) {
 
  199             src_vert = &src_frame->verts[vertIndices[i]];
 
  200             dst_vert = &dst_mesh->
verts[j * numverts + finalIndices[i]];
 
  202             dst_vert->
pos[0] = src_vert->v[0];
 
  203             dst_vert->
pos[1] = src_vert->v[1];
 
  204             dst_vert->
pos[2] = src_vert->v[2];
 
  206             val = src_vert->lightnormalindex;
 
  207             if (val >= NUMVERTEXNORMALS) {
 
  208                 dst_vert->
norm[0] = 0;
 
  209                 dst_vert->
norm[1] = 0;
 
  215             for (k = 0; k < 3; k++) {
 
  216                 val = dst_vert->
pos[k];
 
  224         VectorVectorScale(mins, dst_frame->
scale, mins);
 
  225         VectorVectorScale(maxs, dst_frame->
scale, maxs);
 
  232         src_frame = (dmd2frame_t *)((
byte *)src_frame + header.framesize);
 
  237     return Q_ERR_SUCCESS;
 
  245 static qerror_t MOD_LoadMD3Mesh(model_t *model, 
maliasmesh_t *mesh,
 
  246                                 const byte *rawdata, 
size_t length, 
size_t *offset_p)
 
  250     dmd3vertex_t    *src_vert;
 
  252     dmd3skin_t      *src_skin;
 
  258     char            skinname[MAX_QPATH];
 
  261     if (length < 
sizeof(header))
 
  262         return Q_ERR_BAD_EXTENT;
 
  265     header = *(dmd3mesh_t *)rawdata;
 
  266     for (i = 0; i < 
sizeof(header) / 4; i++)
 
  267         ((uint32_t *)&header)[i] = LittleLong(((uint32_t *)&header)[i]);
 
  269     if (header.meshsize < 
sizeof(header) || header.meshsize > length)
 
  270         return Q_ERR_BAD_EXTENT;
 
  271     if (header.num_verts < 3)
 
  272         return Q_ERR_TOO_FEW;
 
  274         return Q_ERR_TOO_MANY;
 
  275     if (header.num_tris < 1)
 
  276         return Q_ERR_TOO_FEW;
 
  278         return Q_ERR_TOO_MANY;
 
  279     if (header.num_skins > MAX_ALIAS_SKINS)
 
  280         return Q_ERR_TOO_MANY;
 
  281     end = header.ofs_skins + header.num_skins * 
sizeof(dmd3skin_t);
 
  282     if (end < header.ofs_skins || end > length)
 
  283         return Q_ERR_BAD_EXTENT;
 
  284     end = header.ofs_verts + header.num_verts * model->numframes * 
sizeof(dmd3vertex_t);
 
  285     if (end < header.ofs_verts || end > length)
 
  286         return Q_ERR_BAD_EXTENT;
 
  287     end = header.ofs_tcs + header.num_verts * 
sizeof(dmd3coord_t);
 
  288     if (end < header.ofs_tcs || end > length)
 
  289         return Q_ERR_BAD_EXTENT;
 
  290     end = header.ofs_indexes + header.num_tris * 3 * 
sizeof(uint32_t);
 
  291     if (end < header.ofs_indexes || end > length)
 
  292         return Q_ERR_BAD_EXTENT;
 
  294     mesh->
numtris = header.num_tris;
 
  298     mesh->
verts = MOD_Malloc(
sizeof(
maliasvert_t) * header.num_verts * model->numframes);
 
  303     src_skin = (dmd3skin_t *)(rawdata + header.ofs_skins);
 
  304     for (i = 0; i < header.num_skins; i++) {
 
  305         if (!
Q_memccpy(skinname, src_skin->name, 0, 
sizeof(skinname)))
 
  306             return Q_ERR_STRING_TRUNCATED;
 
  312     src_vert = (dmd3vertex_t *)(rawdata + header.ofs_verts);
 
  313     dst_vert = mesh->
verts;
 
  314     for (i = 0; i < header.num_verts * model->numframes; i++) {
 
  315         dst_vert->
pos[0] = (int16_t)LittleShort(src_vert->point[0]);
 
  316         dst_vert->
pos[1] = (int16_t)LittleShort(src_vert->point[1]);
 
  317         dst_vert->
pos[2] = (int16_t)LittleShort(src_vert->point[2]);
 
  319         dst_vert->
norm[0] = src_vert->norm[0];
 
  320         dst_vert->
norm[1] = src_vert->norm[1];
 
  322         src_vert++; dst_vert++;
 
  326     src_tc = (dmd3coord_t *)(rawdata + header.ofs_tcs);
 
  328     for (i = 0; i < header.num_verts; i++) {
 
  329         dst_tc->
st[0] = LittleFloat(src_tc->st[0]);
 
  330         dst_tc->
st[1] = LittleFloat(src_tc->st[1]);
 
  335     src_idx = (uint32_t *)(rawdata + header.ofs_indexes);
 
  337     for (i = 0; i < header.num_tris * 3; i++) {
 
  338         index = LittleLong(*src_idx++);
 
  339         if (index >= header.num_verts)
 
  340             return Q_ERR_BAD_INDEX;
 
  344     *offset_p = header.meshsize;
 
  345     return Q_ERR_SUCCESS;
 
  348 qerror_t 
MOD_LoadMD3_GL(model_t *model, 
const void *rawdata, 
size_t length)
 
  351     size_t          end, offset, remaining;
 
  352     dmd3frame_t     *src_frame;
 
  354     const byte      *src_mesh;
 
  358     if (length < 
sizeof(header))
 
  359         return Q_ERR_FILE_TOO_SMALL;
 
  362     header = *(dmd3header_t *)rawdata;
 
  363     for (i = 0; i < 
sizeof(header) / 4; i++)
 
  364         ((uint32_t *)&header)[i] = LittleLong(((uint32_t *)&header)[i]);
 
  366     if (header.ident != MD3_IDENT)
 
  367         return Q_ERR_UNKNOWN_FORMAT;
 
  368     if (header.version != MD3_VERSION)
 
  369         return Q_ERR_UNKNOWN_FORMAT;
 
  370     if (header.num_frames < 1)
 
  371         return Q_ERR_TOO_FEW;
 
  372     if (header.num_frames > MD3_MAX_FRAMES)
 
  373         return Q_ERR_TOO_MANY;
 
  374     end = header.ofs_frames + 
sizeof(dmd3frame_t) * header.num_frames;
 
  375     if (end < header.ofs_frames || end > length)
 
  376         return Q_ERR_BAD_EXTENT;
 
  377     if (header.num_meshes < 1)
 
  378         return Q_ERR_TOO_FEW;
 
  379     if (header.num_meshes > MD3_MAX_MESHES)
 
  380         return Q_ERR_TOO_MANY;
 
  381     if (header.ofs_meshes > length)
 
  382         return Q_ERR_BAD_EXTENT;
 
  385     model->type = MOD_ALIAS;
 
  386     model->numframes = header.num_frames;
 
  387     model->nummeshes = header.num_meshes;
 
  388     model->meshes = MOD_Malloc(
sizeof(
maliasmesh_t) * header.num_meshes);
 
  389     model->frames = MOD_Malloc(
sizeof(
maliasframe_t) * header.num_frames);
 
  392     src_frame = (dmd3frame_t *)((
byte *)rawdata + header.ofs_frames);
 
  393     dst_frame = model->frames;
 
  394     for (i = 0; i < header.num_frames; i++) {
 
  395         LittleVector(src_frame->translate, dst_frame->
translate);
 
  396         VectorSet(dst_frame->
scale, MD3_XYZ_SCALE, MD3_XYZ_SCALE, MD3_XYZ_SCALE);
 
  398         LittleVector(src_frame->mins, dst_frame->
bounds[0]);
 
  399         LittleVector(src_frame->maxs, dst_frame->
bounds[1]);
 
  400         dst_frame->
radius = LittleFloat(src_frame->radius);
 
  402         src_frame++; dst_frame++;
 
  406     src_mesh = (
const byte *)rawdata + header.ofs_meshes;
 
  407     remaining = length - header.ofs_meshes;
 
  408     for (i = 0; i < header.num_meshes; i++) {
 
  409         ret = MOD_LoadMD3Mesh(model, &model->meshes[i], src_mesh, remaining, &offset);
 
  417     return Q_ERR_SUCCESS;
 
  430     switch (model->type) {
 
  432         for (i = 0; i < model->nummeshes; i++) {
 
  434             for (j = 0; j < mesh->
numskins; j++) {
 
  440         for (i = 0; i < model->numframes; i++) {
 
  447         Com_Error(ERR_FATAL, 
"%s: bad model type", __func__);