+ int i, j, k, version;
+ qbyte *data;
+ msurface_t *surface;
+ surfmesh_t *mesh;
+ md3modelheader_t *pinmodel;
+ md3frameinfo_t *pinframe;
+ md3mesh_t *pinmesh;
+ md3tag_t *pintag;
+ skinfile_t *skinfiles;
+
+ pinmodel = buffer;
+
+ if (memcmp(pinmodel->identifier, "IDP3", 4))
+ Host_Error ("%s is not a MD3 (IDP3) file\n", loadmodel->name);
+ version = LittleLong (pinmodel->version);
+ if (version != MD3VERSION)
+ Host_Error ("%s has wrong version number (%i should be %i)",
+ loadmodel->name, version, MD3VERSION);
+
+ skinfiles = Mod_LoadSkinFiles();
+ if (loadmodel->numskins < 1)
+ loadmodel->numskins = 1;
+
+ loadmodel->type = mod_alias;
+ loadmodel->DrawSky = NULL;
+ loadmodel->Draw = R_Q1BSP_Draw;
+ loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
+ loadmodel->DrawLight = R_Q1BSP_DrawLight;
+ loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
+ loadmodel->flags = LittleLong(pinmodel->flags);
+ loadmodel->synctype = ST_RAND;
+
+ // set up some global info about the model
+ loadmodel->numframes = LittleLong(pinmodel->num_frames);
+ loadmodel->num_surfaces = LittleLong(pinmodel->num_meshes);
+
+ // make skinscenes for the skins (no groups)
+ loadmodel->skinscenes = Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numskins);
+ for (i = 0;i < loadmodel->numskins;i++)
+ {
+ loadmodel->skinscenes[i].firstframe = i;
+ loadmodel->skinscenes[i].framecount = 1;
+ loadmodel->skinscenes[i].loop = true;
+ loadmodel->skinscenes[i].framerate = 10;
+ }
+
+ // load frameinfo
+ loadmodel->animscenes = Mem_Alloc(loadmodel->mempool, loadmodel->numframes * sizeof(animscene_t));
+ for (i = 0, pinframe = (md3frameinfo_t *)((qbyte *)pinmodel + LittleLong(pinmodel->lump_frameinfo));i < loadmodel->numframes;i++, pinframe++)
+ {
+ strcpy(loadmodel->animscenes[i].name, pinframe->name);
+ loadmodel->animscenes[i].firstframe = i;
+ loadmodel->animscenes[i].framecount = 1;
+ loadmodel->animscenes[i].framerate = 10;
+ loadmodel->animscenes[i].loop = true;
+ }
+
+ // load tags
+ loadmodel->num_tagframes = loadmodel->numframes;
+ loadmodel->num_tags = LittleLong(pinmodel->num_tags);
+ loadmodel->data_tags = Mem_Alloc(loadmodel->mempool, loadmodel->num_tagframes * loadmodel->num_tags * sizeof(aliastag_t));
+ for (i = 0, pintag = (md3tag_t *)((qbyte *)pinmodel + LittleLong(pinmodel->lump_tags));i < loadmodel->num_tagframes * loadmodel->num_tags;i++, pintag++)
+ {
+ strcpy(loadmodel->data_tags[i].name, pintag->name);
+ Matrix4x4_CreateIdentity(&loadmodel->data_tags[i].matrix);
+ for (j = 0;j < 3;j++)
+ {
+ for (k = 0;k < 3;k++)
+ loadmodel->data_tags[i].matrix.m[j][k] = LittleFloat(pintag->rotationmatrix[k * 3 + j]);
+ loadmodel->data_tags[i].matrix.m[j][3] = LittleFloat(pintag->origin[j]);
+ }
+ //Con_Printf("model \"%s\" frame #%i tag #%i \"%s\"\n", loadmodel->name, i / loadmodel->num_tags, i % loadmodel->num_tags, loadmodel->data_tags[i].name);
+ }
+
+ // load meshes
+ loadmodel->nummodelsurfaces = loadmodel->num_surfaces;
+ loadmodel->nummeshes = loadmodel->num_surfaces;
+ loadmodel->num_textures = loadmodel->num_surfaces;
+ data = Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->nummeshes * sizeof(surfmesh_t *) + loadmodel->nummeshes * sizeof(surfmesh_t) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t));
+ loadmodel->data_surfaces = (void *)data;data += loadmodel->num_surfaces * sizeof(msurface_t);
+ loadmodel->surfacelist = (void *)data;data += loadmodel->num_surfaces * sizeof(int);
+ loadmodel->meshlist = (void *)data;data += loadmodel->num_surfaces * sizeof(surfmesh_t *);
+ loadmodel->data_textures = (void *)data;data += loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t);
+ for (i = 0;i < loadmodel->num_surfaces;i++)
+ {
+ loadmodel->surfacelist[i] = i;
+ loadmodel->meshlist[i] = (void *)data;data += sizeof(surfmesh_t);
+ }
+ for (i = 0, pinmesh = (md3mesh_t *)((qbyte *)pinmodel + LittleLong(pinmodel->lump_meshes));i < loadmodel->num_surfaces;i++, pinmesh = (md3mesh_t *)((qbyte *)pinmesh + LittleLong(pinmesh->lump_end)))
+ {
+ if (memcmp(pinmesh->identifier, "IDP3", 4))
+ Host_Error("Mod_IDP3_Load: invalid mesh identifier (not IDP3)\n");
+ mesh = loadmodel->meshlist[i];
+ mesh->num_morphframes = LittleLong(pinmesh->num_frames);
+ mesh->num_vertices = LittleLong(pinmesh->num_vertices);
+ mesh->num_triangles = LittleLong(pinmesh->num_triangles);
+ mesh->data_element3i = Mem_Alloc(loadmodel->mempool, mesh->num_triangles * sizeof(int[3]));
+ mesh->data_neighbor3i = Mem_Alloc(loadmodel->mempool, mesh->num_triangles * sizeof(int[3]));
+ mesh->data_texcoordtexture2f = Mem_Alloc(loadmodel->mempool, mesh->num_vertices * sizeof(float[2]));
+ mesh->data_morphvertex3f = Mem_Alloc(loadmodel->mempool, mesh->num_vertices * mesh->num_morphframes * sizeof(float[3]));
+ for (j = 0;j < mesh->num_triangles * 3;j++)
+ mesh->data_element3i[j] = LittleLong(((int *)((qbyte *)pinmesh + LittleLong(pinmesh->lump_elements)))[j]);
+ for (j = 0;j < mesh->num_vertices;j++)
+ {
+ mesh->data_texcoordtexture2f[j * 2 + 0] = LittleFloat(((float *)((qbyte *)pinmesh + LittleLong(pinmesh->lump_texcoords)))[j * 2 + 0]);
+ mesh->data_texcoordtexture2f[j * 2 + 1] = LittleFloat(((float *)((qbyte *)pinmesh + LittleLong(pinmesh->lump_texcoords)))[j * 2 + 1]);
+ }
+ for (j = 0;j < mesh->num_vertices * mesh->num_morphframes;j++)
+ {
+ mesh->data_morphvertex3f[j * 3 + 0] = LittleShort(((short *)((qbyte *)pinmesh + LittleLong(pinmesh->lump_framevertices)))[j * 4 + 0]) * (1.0f / 64.0f);
+ mesh->data_morphvertex3f[j * 3 + 1] = LittleShort(((short *)((qbyte *)pinmesh + LittleLong(pinmesh->lump_framevertices)))[j * 4 + 1]) * (1.0f / 64.0f);
+ mesh->data_morphvertex3f[j * 3 + 2] = LittleShort(((short *)((qbyte *)pinmesh + LittleLong(pinmesh->lump_framevertices)))[j * 4 + 2]) * (1.0f / 64.0f);
+ }
+
+ Mod_ValidateElements(mesh->data_element3i, mesh->num_triangles, mesh->num_vertices, __FILE__, __LINE__);
+ Mod_BuildTriangleNeighbors(mesh->data_neighbor3i, mesh->data_element3i, mesh->num_triangles);
+ Mod_Alias_Mesh_CompileFrameZero(mesh);
+
+ if (LittleLong(pinmesh->num_shaders) >= 1)
+ Mod_BuildAliasSkinsFromSkinFiles(loadmodel->data_textures + i, skinfiles, pinmesh->name, ((md3shader_t *)((qbyte *) pinmesh + LittleLong(pinmesh->lump_shaders)))->name);
+ else
+ for (j = 0;j < loadmodel->numskins;j++)
+ Mod_BuildAliasSkinFromSkinFrame(loadmodel->data_textures + i + j * loadmodel->num_surfaces, NULL);
+
+ surface = loadmodel->data_surfaces + i;
+ surface->groupmesh = mesh;
+ surface->texture = loadmodel->data_textures + i;
+ surface->num_firsttriangle = 0;
+ surface->num_triangles = mesh->num_triangles;
+ surface->num_firstvertex = 0;
+ surface->num_vertices = mesh->num_vertices;
+ }
+ Mod_CalcAliasModelBBoxes();
+ Mod_FreeSkinFiles(skinfiles);