00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #define PM_MD3_C
00037
00038
00039 #include "picointernal.h"
00040
00041
00042 #define MD3_MAGIC "IDP3"
00043 #define MD3_VERSION 15
00044
00045
00046 #define MD3_SCALE (1.0f / 64.0f)
00047
00048
00049 typedef struct md3Frame_s
00050 {
00051 float bounds[2][3];
00052 float localOrigin[3];
00053 float radius;
00054 char creator[16];
00055 } md3Frame_t;
00056
00057
00058 typedef struct md3Tag_s
00059 {
00060 char name[64];
00061 float origin[3];
00062 float axis[3][3];
00063 } md3Tag_t;
00064
00065
00066 typedef struct md3Surface_s
00067 {
00068 char magic[4];
00069 char name[64];
00070 int flags;
00071 int numFrames;
00072 int numShaders;
00073 int numVerts;
00074 int numTriangles;
00075 int ofsTriangles;
00076 int ofsShaders;
00077 int ofsSt;
00078 int ofsVertexes;
00079 int ofsEnd;
00080 } md3Surface_t;
00081
00082 typedef struct md3Shader_s
00083 {
00084 char name[64];
00085 int shaderIndex;
00086 } md3Shader_t;
00087
00088 typedef struct md3Triangle_s
00089 {
00090 int indexes[3];
00091 } md3Triangle_t;
00092
00093 typedef struct md3TexCoord_s
00094 {
00095 float st[2];
00096 } md3TexCoord_t;
00097
00098 typedef struct md3Vertex_s
00099 {
00100 short xyz[3];
00101 short normal;
00102 } md3Vertex_t;
00103
00104
00105 typedef struct md3_s
00106 {
00107 char magic[4];
00108 int version;
00109 char name[64];
00110 int flags;
00111 int numFrames;
00112 int numTags;
00113 int numSurfaces;
00114 int numSkins;
00115 int ofsFrames;
00116 int ofsTags;
00117 int ofsSurfaces;
00118 int ofsEnd;
00119 } md3_t;
00120
00126 static int _md3_canload (PM_PARAMS_CANLOAD)
00127 {
00128 md3_t *md3;
00129
00130
00131 if (bufSize < (sizeof(*md3) * 2))
00132 return PICO_PMV_ERROR_SIZE;
00133
00134
00135 md3 = (md3_t*) buffer;
00136
00137
00138 if (*((int*) md3->magic) != *((int*) MD3_MAGIC))
00139 return PICO_PMV_ERROR_IDENT;
00140
00141
00142 if (_pico_little_long(md3->version) != MD3_VERSION)
00143 return PICO_PMV_ERROR_VERSION;
00144
00145
00146 return PICO_PMV_OK;
00147 }
00148
00152 static picoModel_t *_md3_load (PM_PARAMS_LOAD)
00153 {
00154 int i, j;
00155 picoByte_t *bb;
00156 md3_t *md3;
00157 md3Surface_t *surface;
00158 md3Shader_t *shader;
00159 md3TexCoord_t *texCoord;
00160 md3Frame_t *frame;
00161 md3Triangle_t *triangle;
00162 md3Vertex_t *vertex;
00163 double lat, lng;
00164
00165 picoModel_t *picoModel;
00166 picoSurface_t *picoSurface;
00167 picoShader_t *picoShader;
00168 picoVec3_t xyz, normal;
00169 picoVec2_t st;
00170 picoColor_t color;
00171
00172
00173
00174
00175
00176
00177 bb = (picoByte_t*) buffer;
00178 md3 = (md3_t*) buffer;
00179
00180
00181 if (*((int*) md3->magic) != *((int*) MD3_MAGIC) || _pico_little_long(md3->version) != MD3_VERSION) {
00182
00183 return NULL;
00184 }
00185
00186
00187 md3->version = _pico_little_long(md3->version);
00188 md3->numFrames = _pico_little_long(md3->numFrames);
00189 md3->numTags = _pico_little_long(md3->numTags);
00190 md3->numSurfaces = _pico_little_long(md3->numSurfaces);
00191 md3->numSkins = _pico_little_long(md3->numSkins);
00192 md3->ofsFrames = _pico_little_long(md3->ofsFrames);
00193 md3->ofsTags = _pico_little_long(md3->ofsTags);
00194 md3->ofsSurfaces = _pico_little_long(md3->ofsSurfaces);
00195 md3->ofsEnd = _pico_little_long(md3->ofsEnd);
00196
00197
00198 if (md3->numFrames < 1) {
00199 _pico_printf(PICO_ERROR, "MD3 with 0 frames");
00200 return NULL;
00201 }
00202
00203 if (frameNum < 0 || frameNum >= md3->numFrames) {
00204 _pico_printf(PICO_ERROR, "Invalid or out-of-range MD3 frame specified");
00205 return NULL;
00206 }
00207
00208
00209 frame = (md3Frame_t*) (bb + md3->ofsFrames);
00210 for (i = 0; i < md3->numFrames; i++, frame++) {
00211 frame->radius = _pico_little_float(frame->radius);
00212 for (j = 0; j < 3; j++) {
00213 frame->bounds[0][j] = _pico_little_float(frame->bounds[0][j]);
00214 frame->bounds[1][j] = _pico_little_float(frame->bounds[1][j]);
00215 frame->localOrigin[j] = _pico_little_float(frame->localOrigin[j]);
00216 }
00217 }
00218
00219
00220 surface = (md3Surface_t*) (bb + md3->ofsSurfaces);
00221 for (i = 0; i < md3->numSurfaces; i++) {
00222
00223 surface->flags = _pico_little_long(surface->flags);
00224 surface->numFrames = _pico_little_long(surface->numFrames);
00225 surface->numShaders = _pico_little_long(surface->numShaders);
00226 surface->numTriangles = _pico_little_long(surface->numTriangles);
00227 surface->ofsTriangles = _pico_little_long(surface->ofsTriangles);
00228 surface->numVerts = _pico_little_long(surface->numVerts);
00229 surface->ofsShaders = _pico_little_long(surface->ofsShaders);
00230 surface->ofsSt = _pico_little_long(surface->ofsSt);
00231 surface->ofsVertexes = _pico_little_long(surface->ofsVertexes);
00232 surface->ofsEnd = _pico_little_long(surface->ofsEnd);
00233
00234
00235 triangle = (md3Triangle_t*) ((picoByte_t*) surface + surface->ofsTriangles);
00236 for (j = 0; j < surface->numTriangles; j++, triangle++) {
00237
00238 triangle->indexes[0] = _pico_little_long(triangle->indexes[0]);
00239 triangle->indexes[1] = _pico_little_long(triangle->indexes[1]);
00240 triangle->indexes[2] = _pico_little_long(triangle->indexes[2]);
00241 }
00242
00243
00244 texCoord = (md3TexCoord_t*) ((picoByte_t*) surface + surface->ofsSt);
00245 for (j = 0; j < surface->numVerts; j++, texCoord++) {
00246 texCoord->st[0] = _pico_little_float(texCoord->st[0]);
00247 texCoord->st[1] = _pico_little_float(texCoord->st[1]);
00248 }
00249
00250
00251 vertex = (md3Vertex_t*) ((picoByte_t*) surface + surface->ofsVertexes);
00252 for (j = 0; j < (surface->numVerts * surface->numFrames); j++, vertex++) {
00253 vertex->xyz[0] = _pico_little_short(vertex->xyz[0]);
00254 vertex->xyz[1] = _pico_little_short(vertex->xyz[1]);
00255 vertex->xyz[2] = _pico_little_short(vertex->xyz[2]);
00256 vertex->normal = _pico_little_short(vertex->normal);
00257 }
00258
00259
00260 surface = (md3Surface_t*) ((picoByte_t*) surface + surface->ofsEnd);
00261 }
00262
00263
00264
00265
00266
00267
00268 picoModel = PicoNewModel();
00269 if (picoModel == NULL) {
00270 _pico_printf(PICO_ERROR, "Unable to allocate a new model");
00271 return NULL;
00272 }
00273
00274
00275 PicoSetModelFrameNum(picoModel, frameNum);
00276 PicoSetModelNumFrames(picoModel, md3->numFrames);
00277 PicoSetModelName(picoModel, fileName);
00278 PicoSetModelFileName(picoModel, fileName);
00279
00280
00281 surface = (md3Surface_t*) (bb + md3->ofsSurfaces);
00282
00283
00284 for (i = 0; i < md3->numSurfaces; i++) {
00285
00286 picoSurface = PicoNewSurface(picoModel);
00287 if (picoSurface == NULL) {
00288 _pico_printf(PICO_ERROR, "Unable to allocate a new model surface");
00289 PicoFreeModel(picoModel);
00290 return NULL;
00291 }
00292
00293
00294 PicoSetSurfaceType(picoSurface, PICO_TRIANGLES);
00295
00296
00297 PicoSetSurfaceName(picoSurface, surface->name);
00298
00299
00300 picoShader = PicoNewShader(picoModel);
00301 if (picoShader == NULL) {
00302 _pico_printf(PICO_ERROR, "Unable to allocate a new model shader");
00303 PicoFreeModel(picoModel);
00304 return NULL;
00305 }
00306
00307
00308 shader = (md3Shader_t*) ((picoByte_t*) surface + surface->ofsShaders);
00309 _pico_setfext(shader->name, "");
00310 _pico_unixify(shader->name);
00311 PicoSetShaderName(picoShader, shader->name);
00312
00313
00314 PicoSetSurfaceShader(picoSurface, picoShader);
00315
00316
00317 triangle = (md3Triangle_t *) ((picoByte_t*) surface + surface->ofsTriangles);
00318
00319 for (j = 0; j < surface->numTriangles; j++, triangle++) {
00320 PicoSetSurfaceIndex(picoSurface, (j * 3 + 0), (picoIndex_t) triangle->indexes[0]);
00321 PicoSetSurfaceIndex(picoSurface, (j * 3 + 1), (picoIndex_t) triangle->indexes[1]);
00322 PicoSetSurfaceIndex(picoSurface, (j * 3 + 2), (picoIndex_t) triangle->indexes[2]);
00323 }
00324
00325
00326 texCoord = (md3TexCoord_t*) ((picoByte_t *) surface + surface->ofsSt);
00327 vertex = (md3Vertex_t*) ((picoByte_t*) surface + surface->ofsVertexes + surface->numVerts * frameNum
00328 * sizeof(md3Vertex_t));
00329 _pico_set_color(color, 255, 255, 255, 255);
00330
00331 for (j = 0; j < surface->numVerts; j++, texCoord++, vertex++) {
00332
00333 xyz[0] = MD3_SCALE * vertex->xyz[0];
00334 xyz[1] = MD3_SCALE * vertex->xyz[1];
00335 xyz[2] = MD3_SCALE * vertex->xyz[2];
00336 PicoSetSurfaceXYZ(picoSurface, j, xyz);
00337
00338
00339 lat = (float) ((vertex->normal >> 8) & 0xff);
00340 lng = (float) (vertex->normal & 0xff);
00341 lat *= PICO_PI / 128;
00342 lng *= PICO_PI / 128;
00343 normal[0] = (picoVec_t) cos(lat) * (picoVec_t) sin(lng);
00344 normal[1] = (picoVec_t) sin(lat) * (picoVec_t) sin(lng);
00345 normal[2] = (picoVec_t) cos(lng);
00346 PicoSetSurfaceNormal(picoSurface, j, normal);
00347
00348
00349 st[0] = texCoord->st[0];
00350 st[1] = texCoord->st[1];
00351 PicoSetSurfaceST(picoSurface, 0, j, st);
00352
00353
00354 PicoSetSurfaceColor(picoSurface, 0, j, color);
00355 }
00356
00357
00358 surface = (md3Surface_t*) ((picoByte_t*) surface + surface->ofsEnd);
00359 }
00360
00361
00362 return picoModel;
00363 }
00364
00365
00366 const picoModule_t picoModuleMD3 = { "1.3",
00367 "Quake 3 Arena",
00368 "Randy Reddig",
00369 "2002 Randy Reddig",
00370 { "md3", NULL, NULL, NULL
00371 }, _md3_canload,
00372 _md3_load,
00373 NULL,
00374 NULL
00375 };