00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "r_local.h"
00027
00028
00029
00030
00031
00032
00033
00038 void R_ModLoadAliasMD3Model (model_t *mod, byte *buffer, int bufSize)
00039 {
00040 int version, i, j, l;
00041 const dmd3_t *md3;
00042 const dmd3frame_t *pinframe;
00043 const dmd3tag_t *pintag;
00044 const dmd3mesh_t *pinmesh;
00045 const dmd3skin_t *pinskin;
00046 const dmd3coord_t *pincoord;
00047 const dmd3vertex_t *pinvert;
00048 const int32_t *pinindex;
00049 int32_t *poutindex;
00050 mAliasVertex_t *poutvert;
00051 mAliasMesh_t *poutmesh;
00052 mAliasTag_t *pouttag;
00053 mAliasFrame_t *poutframe;
00054 float lat, lng;
00055
00056 md3 = (dmd3_t *)buffer;
00057 version = LittleLong(md3->version);
00058
00059 if (version != MD3_ALIAS_VERSION) {
00060 Com_Error(ERR_DROP, "%s has wrong version number (%i should be %i)",
00061 mod->name, version, MD3_ALIAS_VERSION);
00062 }
00063
00064 mod->type = mod_alias_md3;
00065
00066 mod->alias.num_frames = LittleLong(md3->num_frames);
00067 mod->alias.num_tags = LittleLong(md3->num_tags);
00068 mod->alias.num_meshes = LittleLong(md3->num_meshes);
00069
00070 if (mod->alias.num_frames <= 0)
00071 Com_Error(ERR_DROP, "model %s has no frames", mod->name);
00072 else if (mod->alias.num_frames > MD3_MAX_FRAMES)
00073 Com_Error(ERR_DROP, "model %s has too many frames", mod->name);
00074
00075 if (mod->alias.num_tags > MD3_MAX_TAGS)
00076 Com_Error(ERR_DROP, "model %s has too many tags", mod->name);
00077 else if (mod->alias.num_tags < 0)
00078 Com_Error(ERR_DROP, "model %s has invalid number of tags", mod->name);
00079
00080 if (mod->alias.num_meshes <= 0)
00081 Com_Error(ERR_DROP, "model %s has no meshes", mod->name);
00082 else if (mod->alias.num_meshes > MD3_MAX_MESHES)
00083 Com_Error(ERR_DROP, "model %s has too many meshes", mod->name);
00084
00085
00086 pinframe = (const dmd3frame_t *)((const byte *)md3 + LittleLong(md3->ofs_frames));
00087 poutframe = mod->alias.frames = Mem_PoolAlloc(sizeof(mAliasFrame_t) * mod->alias.num_frames, vid_modelPool, 0);
00088
00089 mod->radius = 0;
00090 ClearBounds(mod->mins, mod->maxs);
00091
00092 for (i = 0; i < mod->alias.num_frames; i++, pinframe++, poutframe++) {
00093 for (j = 0; j < 3; j++) {
00094 poutframe->mins[j] = LittleFloat(pinframe->mins[j]);
00095 poutframe->maxs[j] = LittleFloat(pinframe->maxs[j]);
00096 poutframe->translate[j] = LittleFloat(pinframe->translate[j]);
00097 }
00098
00099 poutframe->radius = LittleFloat(pinframe->radius);
00100 mod->radius = max(mod->radius, poutframe->radius);
00101 AddPointToBounds(poutframe->mins, mod->mins, mod->maxs);
00102 AddPointToBounds(poutframe->maxs, mod->mins, mod->maxs);
00103 }
00104
00105
00106 if (mod->alias.num_tags) {
00107 pintag = (const dmd3tag_t *)((const byte *)md3 + LittleLong(md3->ofs_tags));
00108 pouttag = mod->alias.tags = Mem_PoolAlloc(sizeof(mAliasTag_t) * mod->alias.num_frames * mod->alias.num_tags, vid_modelPool, 0);
00109
00110 for (i = 0; i < mod->alias.num_frames; i++) {
00111 for (l = 0; l < mod->alias.num_tags; l++, pintag++, pouttag++) {
00112 memcpy(pouttag->name, pintag->name, MD3_MAX_PATH);
00113 for (j = 0; j < 3; j++) {
00114 pouttag->orient.origin[j] = LittleFloat(pintag->orient.origin[j]);
00115 pouttag->orient.axis[0][j] = LittleFloat(pintag->orient.axis[0][j]);
00116 pouttag->orient.axis[1][j] = LittleFloat(pintag->orient.axis[1][j]);
00117 pouttag->orient.axis[2][j] = LittleFloat(pintag->orient.axis[2][j]);
00118 }
00119
00120
00121
00122
00123 }
00124 }
00125 }
00126
00127
00128 pinmesh = (const dmd3mesh_t *)((const byte *)md3 + LittleLong(md3->ofs_meshes));
00129 poutmesh = mod->alias.meshes = Mem_PoolAlloc(sizeof(mAliasMesh_t) * mod->alias.num_meshes, vid_modelPool, 0);
00130
00131 for (i = 0; i < mod->alias.num_meshes; i++, poutmesh++) {
00132 memcpy(poutmesh->name, pinmesh->name, MD3_MAX_PATH);
00133
00134 if (strncmp(pinmesh->id, "IDP3", 4)) {
00135 Com_Error(ERR_DROP, "mesh %s in model %s has wrong id (%s should be %i)",
00136 poutmesh->name, mod->name, pinmesh->id, IDMD3HEADER);
00137 }
00138
00139 poutmesh->num_tris = LittleLong(pinmesh->num_tris);
00140 poutmesh->num_skins = LittleLong(pinmesh->num_skins);
00141 poutmesh->num_verts = LittleLong(pinmesh->num_verts);
00142
00143 if (poutmesh->num_skins <= 0)
00144 Com_Error(ERR_DROP, "mesh %i in model %s has no skins", i, mod->name);
00145 else if (poutmesh->num_skins > MD3_MAX_SHADERS)
00146 Com_Error(ERR_DROP, "mesh %i in model %s has too many skins", i, mod->name);
00147
00148 if (poutmesh->num_tris <= 0)
00149 Com_Error(ERR_DROP, "mesh %i in model %s has no triangles", i, mod->name);
00150 else if (poutmesh->num_tris > MD3_MAX_TRIANGLES)
00151 Com_Error(ERR_DROP, "mesh %i in model %s has too many triangles", i, mod->name);
00152
00153 if (poutmesh->num_verts <= 0)
00154 Com_Error(ERR_DROP, "mesh %i in model %s has no vertices", i, mod->name);
00155 else if (poutmesh->num_verts > MD3_MAX_VERTS)
00156 Com_Error(ERR_DROP, "mesh %i in model %s has too many vertices", i, mod->name);
00157
00158
00159 pinskin = (const dmd3skin_t *)((const byte *)pinmesh + LittleLong(pinmesh->ofs_skins));
00160 poutmesh->skins = Mem_PoolAlloc(sizeof(mAliasSkin_t) * poutmesh->num_skins, vid_modelPool, 0);
00161
00162 for (j = 0; j < mod->alias.meshes[i].num_skins; j++) {
00163 mod->alias.meshes[i].skins[j].skin = R_AliasModelGetSkin(mod->name, pinskin->name);
00164 Q_strncpyz(mod->alias.meshes[i].skins[j].name,
00165 mod->alias.meshes[i].skins[j].skin->name, MODEL_MAX_PATH);
00166 }
00167
00168
00169 pinindex = (const int32_t *)((const byte *)pinmesh + LittleLong(pinmesh->ofs_tris));
00170 poutindex = poutmesh->indexes = Mem_PoolAlloc(sizeof(int32_t) * poutmesh->num_tris * 3, vid_modelPool, 0);
00171
00172 for (j = 0; j < poutmesh->num_tris; j++, pinindex += 3, poutindex += 3) {
00173 poutindex[0] = (int32_t)LittleLong(pinindex[0]);
00174 poutindex[1] = (int32_t)LittleLong(pinindex[1]);
00175 poutindex[2] = (int32_t)LittleLong(pinindex[2]);
00176 }
00177
00178
00179 pincoord = (const dmd3coord_t *)((const byte *)pinmesh + LittleLong(pinmesh->ofs_tcs));
00180 poutmesh->stcoords = Mem_PoolAlloc(sizeof(mAliasCoord_t) * poutmesh->num_verts, vid_modelPool, 0);
00181
00182 for (j = 0; j < poutmesh->num_verts; j++, pincoord++) {
00183 poutmesh->stcoords[j][0] = LittleFloat(pincoord->st[0]);
00184 poutmesh->stcoords[j][1] = LittleFloat(pincoord->st[1]);
00185 }
00186
00187
00188 pinvert = (const dmd3vertex_t *)((const byte *)pinmesh + LittleLong(pinmesh->ofs_verts));
00189 poutvert = poutmesh->vertexes = Mem_PoolAlloc(mod->alias.num_frames * poutmesh->num_verts * sizeof(mAliasVertex_t), vid_modelPool, 0);
00190
00191 for (l = 0; l < mod->alias.num_frames; l++) {
00192 for (j = 0; j < poutmesh->num_verts; j++, pinvert++, poutvert++) {
00193 poutvert->point[0] = LittleShort(pinvert->point[0]) * MD3_XYZ_SCALE;
00194 poutvert->point[1] = LittleShort(pinvert->point[1]) * MD3_XYZ_SCALE;
00195 poutvert->point[2] = LittleShort(pinvert->point[2]) * MD3_XYZ_SCALE;
00196
00197 lat = (pinvert->norm >> 8) & 0xff;
00198 lng = (pinvert->norm & 0xff);
00199
00200 lat *= M_PI / 128.0f;
00201 lng *= M_PI / 128.0f;
00202
00203 poutvert->normal[0] = cos(lat) * sin(lng);
00204 poutvert->normal[1] = sin(lat) * sin(lng);
00205 poutvert->normal[2] = cos(lng);
00206 }
00207 }
00208 pinmesh = (const dmd3mesh_t *)((const byte *)pinmesh + LittleLong(pinmesh->meshsize));
00209
00210 R_ModLoadArrayData(&mod->alias, poutmesh, qtrue);
00211 }
00212 }