1 /* -----------------------------------------------------------------------------
\r
5 Copyright (c) 2002, Randy Reddig & seaw0lf
\r
8 Redistribution and use in source and binary forms, with or without modification,
\r
9 are permitted provided that the following conditions are met:
\r
11 Redistributions of source code must retain the above copyright notice, this list
\r
12 of conditions and the following disclaimer.
\r
14 Redistributions in binary form must reproduce the above copyright notice, this
\r
15 list of conditions and the following disclaimer in the documentation and/or
\r
16 other materials provided with the distribution.
\r
18 Neither the names of the copyright holders nor the names of its contributors may
\r
19 be used to endorse or promote products derived from this software without
\r
20 specific prior written permission.
\r
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
\r
23 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
\r
24 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
\r
25 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
\r
26 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
\r
27 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
\r
28 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
\r
29 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
\r
30 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
\r
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
33 ----------------------------------------------------------------------------- */
\r
36 Nurail: Used pm_md3.c (Randy Reddig) as a template.
\r
44 #include "picointernal.h"
\r
47 /* md2 model format */
\r
48 #define MD2_MAGIC "IDP2"
\r
49 #define MD2_VERSION 8
\r
51 #define MD2_NUMVERTEXNORMALS 162
\r
52 #define MD2_MAX_SKINNAME 64
\r
53 #define MD2_MAX_TRIANGLES 4096
\r
54 #define MD2_MAX_VERTS 2048
\r
55 #define MD2_MAX_FRAMES 512
\r
56 #define MD2_MAX_MD2SKINS 32
\r
57 #define MD2_MAX_SKINNAME 64
\r
60 #define byte unsigned char
\r
63 typedef struct index_LUT_s
\r
67 struct index_LUT_s *next;
\r
71 typedef struct index_DUP_LUT_s
\r
92 byte v[3]; // scaled byte to fit in frame mins/maxs
\r
93 byte lightnormalindex;
\r
96 typedef struct md2Frame_s
\r
98 float scale[3]; // multiply byte verts by this
\r
99 float translate[3]; // then add this
\r
100 char name[16]; // frame name from grabbing
\r
101 md2XyzNormal_t verts[1]; // variable sized
\r
106 /* md2 model file md2 structure */
\r
107 typedef struct md2_s
\r
132 float md2_normals[ MD2_NUMVERTEXNORMALS ][ 3 ] =
\r
134 { -0.525731f, 0.000000f, 0.850651f },
\r
135 { -0.442863f, 0.238856f, 0.864188f },
\r
136 { -0.295242f, 0.000000f, 0.955423f },
\r
137 { -0.309017f, 0.500000f, 0.809017f },
\r
138 { -0.162460f, 0.262866f, 0.951056f },
\r
139 { 0.000000f, 0.000000f, 1.000000f },
\r
140 { 0.000000f, 0.850651f, 0.525731f },
\r
141 { -0.147621f, 0.716567f, 0.681718f },
\r
142 { 0.147621f, 0.716567f, 0.681718f },
\r
143 { 0.000000f, 0.525731f, 0.850651f },
\r
144 { 0.309017f, 0.500000f, 0.809017f },
\r
145 { 0.525731f, 0.000000f, 0.850651f },
\r
146 { 0.295242f, 0.000000f, 0.955423f },
\r
147 { 0.442863f, 0.238856f, 0.864188f },
\r
148 { 0.162460f, 0.262866f, 0.951056f },
\r
149 { -0.681718f, 0.147621f, 0.716567f },
\r
150 { -0.809017f, 0.309017f, 0.500000f },
\r
151 { -0.587785f, 0.425325f, 0.688191f },
\r
152 { -0.850651f, 0.525731f, 0.000000f },
\r
153 { -0.864188f, 0.442863f, 0.238856f },
\r
154 { -0.716567f, 0.681718f, 0.147621f },
\r
155 { -0.688191f, 0.587785f, 0.425325f },
\r
156 { -0.500000f, 0.809017f, 0.309017f },
\r
157 { -0.238856f, 0.864188f, 0.442863f },
\r
158 { -0.425325f, 0.688191f, 0.587785f },
\r
159 { -0.716567f, 0.681718f, -0.147621f },
\r
160 { -0.500000f, 0.809017f, -0.309017f },
\r
161 { -0.525731f, 0.850651f, 0.000000f },
\r
162 { 0.000000f, 0.850651f, -0.525731f },
\r
163 { -0.238856f, 0.864188f, -0.442863f },
\r
164 { 0.000000f, 0.955423f, -0.295242f },
\r
165 { -0.262866f, 0.951056f, -0.162460f },
\r
166 { 0.000000f, 1.000000f, 0.000000f },
\r
167 { 0.000000f, 0.955423f, 0.295242f },
\r
168 { -0.262866f, 0.951056f, 0.162460f },
\r
169 { 0.238856f, 0.864188f, 0.442863f },
\r
170 { 0.262866f, 0.951056f, 0.162460f },
\r
171 { 0.500000f, 0.809017f, 0.309017f },
\r
172 { 0.238856f, 0.864188f, -0.442863f },
\r
173 { 0.262866f, 0.951056f, -0.162460f },
\r
174 { 0.500000f, 0.809017f, -0.309017f },
\r
175 { 0.850651f, 0.525731f, 0.000000f },
\r
176 { 0.716567f, 0.681718f, 0.147621f },
\r
177 { 0.716567f, 0.681718f, -0.147621f },
\r
178 { 0.525731f, 0.850651f, 0.000000f },
\r
179 { 0.425325f, 0.688191f, 0.587785f },
\r
180 { 0.864188f, 0.442863f, 0.238856f },
\r
181 { 0.688191f, 0.587785f, 0.425325f },
\r
182 { 0.809017f, 0.309017f, 0.500000f },
\r
183 { 0.681718f, 0.147621f, 0.716567f },
\r
184 { 0.587785f, 0.425325f, 0.688191f },
\r
185 { 0.955423f, 0.295242f, 0.000000f },
\r
186 { 1.000000f, 0.000000f, 0.000000f },
\r
187 { 0.951056f, 0.162460f, 0.262866f },
\r
188 { 0.850651f, -0.525731f, 0.000000f },
\r
189 { 0.955423f, -0.295242f, 0.000000f },
\r
190 { 0.864188f, -0.442863f, 0.238856f },
\r
191 { 0.951056f, -0.162460f, 0.262866f },
\r
192 { 0.809017f, -0.309017f, 0.500000f },
\r
193 { 0.681718f, -0.147621f, 0.716567f },
\r
194 { 0.850651f, 0.000000f, 0.525731f },
\r
195 { 0.864188f, 0.442863f, -0.238856f },
\r
196 { 0.809017f, 0.309017f, -0.500000f },
\r
197 { 0.951056f, 0.162460f, -0.262866f },
\r
198 { 0.525731f, 0.000000f, -0.850651f },
\r
199 { 0.681718f, 0.147621f, -0.716567f },
\r
200 { 0.681718f, -0.147621f, -0.716567f },
\r
201 { 0.850651f, 0.000000f, -0.525731f },
\r
202 { 0.809017f, -0.309017f, -0.500000f },
\r
203 { 0.864188f, -0.442863f, -0.238856f },
\r
204 { 0.951056f, -0.162460f, -0.262866f },
\r
205 { 0.147621f, 0.716567f, -0.681718f },
\r
206 { 0.309017f, 0.500000f, -0.809017f },
\r
207 { 0.425325f, 0.688191f, -0.587785f },
\r
208 { 0.442863f, 0.238856f, -0.864188f },
\r
209 { 0.587785f, 0.425325f, -0.688191f },
\r
210 { 0.688191f, 0.587785f, -0.425325f },
\r
211 { -0.147621f, 0.716567f, -0.681718f },
\r
212 { -0.309017f, 0.500000f, -0.809017f },
\r
213 { 0.000000f, 0.525731f, -0.850651f },
\r
214 { -0.525731f, 0.000000f, -0.850651f },
\r
215 { -0.442863f, 0.238856f, -0.864188f },
\r
216 { -0.295242f, 0.000000f, -0.955423f },
\r
217 { -0.162460f, 0.262866f, -0.951056f },
\r
218 { 0.000000f, 0.000000f, -1.000000f },
\r
219 { 0.295242f, 0.000000f, -0.955423f },
\r
220 { 0.162460f, 0.262866f, -0.951056f },
\r
221 { -0.442863f, -0.238856f, -0.864188f },
\r
222 { -0.309017f, -0.500000f, -0.809017f },
\r
223 { -0.162460f, -0.262866f, -0.951056f },
\r
224 { 0.000000f, -0.850651f, -0.525731f },
\r
225 { -0.147621f, -0.716567f, -0.681718f },
\r
226 { 0.147621f, -0.716567f, -0.681718f },
\r
227 { 0.000000f, -0.525731f, -0.850651f },
\r
228 { 0.309017f, -0.500000f, -0.809017f },
\r
229 { 0.442863f, -0.238856f, -0.864188f },
\r
230 { 0.162460f, -0.262866f, -0.951056f },
\r
231 { 0.238856f, -0.864188f, -0.442863f },
\r
232 { 0.500000f, -0.809017f, -0.309017f },
\r
233 { 0.425325f, -0.688191f, -0.587785f },
\r
234 { 0.716567f, -0.681718f, -0.147621f },
\r
235 { 0.688191f, -0.587785f, -0.425325f },
\r
236 { 0.587785f, -0.425325f, -0.688191f },
\r
237 { 0.000000f, -0.955423f, -0.295242f },
\r
238 { 0.000000f, -1.000000f, 0.000000f },
\r
239 { 0.262866f, -0.951056f, -0.162460f },
\r
240 { 0.000000f, -0.850651f, 0.525731f },
\r
241 { 0.000000f, -0.955423f, 0.295242f },
\r
242 { 0.238856f, -0.864188f, 0.442863f },
\r
243 { 0.262866f, -0.951056f, 0.162460f },
\r
244 { 0.500000f, -0.809017f, 0.309017f },
\r
245 { 0.716567f, -0.681718f, 0.147621f },
\r
246 { 0.525731f, -0.850651f, 0.000000f },
\r
247 { -0.238856f, -0.864188f, -0.442863f },
\r
248 { -0.500000f, -0.809017f, -0.309017f },
\r
249 { -0.262866f, -0.951056f, -0.162460f },
\r
250 { -0.850651f, -0.525731f, 0.000000f },
\r
251 { -0.716567f, -0.681718f, -0.147621f },
\r
252 { -0.716567f, -0.681718f, 0.147621f },
\r
253 { -0.525731f, -0.850651f, 0.000000f },
\r
254 { -0.500000f, -0.809017f, 0.309017f },
\r
255 { -0.238856f, -0.864188f, 0.442863f },
\r
256 { -0.262866f, -0.951056f, 0.162460f },
\r
257 { -0.864188f, -0.442863f, 0.238856f },
\r
258 { -0.809017f, -0.309017f, 0.500000f },
\r
259 { -0.688191f, -0.587785f, 0.425325f },
\r
260 { -0.681718f, -0.147621f, 0.716567f },
\r
261 { -0.442863f, -0.238856f, 0.864188f },
\r
262 { -0.587785f, -0.425325f, 0.688191f },
\r
263 { -0.309017f, -0.500000f, 0.809017f },
\r
264 { -0.147621f, -0.716567f, 0.681718f },
\r
265 { -0.425325f, -0.688191f, 0.587785f },
\r
266 { -0.162460f, -0.262866f, 0.951056f },
\r
267 { 0.442863f, -0.238856f, 0.864188f },
\r
268 { 0.162460f, -0.262866f, 0.951056f },
\r
269 { 0.309017f, -0.500000f, 0.809017f },
\r
270 { 0.147621f, -0.716567f, 0.681718f },
\r
271 { 0.000000f, -0.525731f, 0.850651f },
\r
272 { 0.425325f, -0.688191f, 0.587785f },
\r
273 { 0.587785f, -0.425325f, 0.688191f },
\r
274 { 0.688191f, -0.587785f, 0.425325f },
\r
275 { -0.955423f, 0.295242f, 0.000000f },
\r
276 { -0.951056f, 0.162460f, 0.262866f },
\r
277 { -1.000000f, 0.000000f, 0.000000f },
\r
278 { -0.850651f, 0.000000f, 0.525731f },
\r
279 { -0.955423f, -0.295242f, 0.000000f },
\r
280 { -0.951056f, -0.162460f, 0.262866f },
\r
281 { -0.864188f, 0.442863f, -0.238856f },
\r
282 { -0.951056f, 0.162460f, -0.262866f },
\r
283 { -0.809017f, 0.309017f, -0.500000f },
\r
284 { -0.864188f, -0.442863f, -0.238856f },
\r
285 { -0.951056f, -0.162460f, -0.262866f },
\r
286 { -0.809017f, -0.309017f, -0.500000f },
\r
287 { -0.681718f, 0.147621f, -0.716567f },
\r
288 { -0.681718f, -0.147621f, -0.716567f },
\r
289 { -0.850651f, 0.000000f, -0.525731f },
\r
290 { -0.688191f, 0.587785f, -0.425325f },
\r
291 { -0.587785f, 0.425325f, -0.688191f },
\r
292 { -0.425325f, 0.688191f, -0.587785f },
\r
293 { -0.425325f, -0.688191f, -0.587785f },
\r
294 { -0.587785f, -0.425325f, -0.688191f },
\r
295 { -0.688191f, -0.587785f, -0.425325f },
\r
301 static int _md2_canload( PM_PARAMS_CANLOAD )
\r
305 /* to keep the compiler happy */
\r
306 *fileName = *fileName;
\r
309 if( bufSize < ( sizeof( *md2 ) * 2) )
\r
310 return PICO_PMV_ERROR_SIZE;
\r
313 md2 = (md2_t*) buffer;
\r
315 /* check md2 magic */
\r
316 if( *((int*) md2->magic) != *((int*) MD2_MAGIC) )
\r
317 return PICO_PMV_ERROR_IDENT;
\r
319 /* check md2 version */
\r
320 if( _pico_little_long( md2->version ) != MD2_VERSION )
\r
321 return PICO_PMV_ERROR_VERSION;
\r
323 /* file seems to be a valid md2 */
\r
324 return PICO_PMV_OK;
\r
329 // _md2_load() loads a quake2 md2 model file.
\r
332 static picoModel_t *_md2_load( PM_PARAMS_LOAD )
\r
334 int i, j, dups, dup_index;
\r
335 short tot_numVerts;
\r
336 index_LUT_t *p_index_LUT, *p_index_LUT2, *p_index_LUT3;
\r
337 index_DUP_LUT_t *p_index_LUT_DUPS;
\r
338 md2Triangle_t *p_md2Triangle;
\r
340 char skinname[ MD2_MAX_SKINNAME ];
\r
344 md2Triangle_t *triangle;
\r
345 md2XyzNormal_t *vertex;
\r
348 picoModel_t *picoModel;
\r
349 picoSurface_t *picoSurface;
\r
350 picoShader_t *picoShader;
\r
351 picoVec3_t xyz, normal;
\r
357 _pico_printf( PICO_NORMAL, "Loading \"%s\"", fileName );
\r
360 bb = (picoByte_t*) buffer;
\r
361 md2 = (md2_t*) buffer;
\r
363 /* check ident and version */
\r
364 if( *((int*) md2->magic) != *((int*) MD2_MAGIC) || _pico_little_long( md2->version ) != MD2_VERSION )
\r
366 /* not an md2 file (todo: set error) */
\r
367 _pico_printf( PICO_ERROR, "%s is not an MD2 File!", fileName );
\r
372 md2->version = _pico_little_long( md2->version );
\r
374 md2->skinWidth = _pico_little_long( md2->skinWidth );
\r
375 md2->skinHeight = _pico_little_long( md2->skinHeight );
\r
376 md2->frameSize = _pico_little_long( md2->frameSize );
\r
378 md2->numSkins = _pico_little_long( md2->numSkins );
\r
379 md2->numXYZ = _pico_little_long( md2->numXYZ );
\r
380 md2->numST = _pico_little_long( md2->numST );
\r
381 md2->numTris = _pico_little_long( md2->numTris );
\r
382 md2->numGLCmds = _pico_little_long( md2->numGLCmds );
\r
383 md2->numFrames = _pico_little_long( md2->numFrames );
\r
385 md2->ofsSkins = _pico_little_long( md2->ofsSkins );
\r
386 md2->ofsST = _pico_little_long( md2->ofsST );
\r
387 md2->ofsTris = _pico_little_long( md2->ofsTris );
\r
388 md2->ofsFrames = _pico_little_long( md2->ofsFrames );
\r
389 md2->ofsGLCmds = _pico_little_long( md2->ofsGLCmds );
\r
390 md2->ofsEnd = _pico_little_long( md2->ofsEnd );
\r
393 if( md2->numFrames < 1 )
\r
395 _pico_printf( PICO_ERROR, "%s has 0 frames!", fileName );
\r
399 if( frameNum < 0 || frameNum >= md2->numFrames )
\r
401 _pico_printf( PICO_ERROR, "Invalid or out-of-range MD2 frame specified" );
\r
406 frame = (md2Frame_t *) (bb + md2->ofsFrames + (sizeof(md2Frame_t) * frameNum));
\r
408 // swap frame scale and translation
\r
409 for( i = 0; i < 3; i++ )
\r
411 frame->scale[ i ] = _pico_little_float( frame->scale[ i ] );
\r
412 frame->translate[ i ] = _pico_little_float( frame->translate[ i ] );
\r
416 triangle = (md2Triangle_t *) ((picoByte_t *) (bb + md2->ofsTris) );
\r
417 for( i = 0; i < md2->numTris; i++, triangle++ )
\r
419 for( j = 0; j < 3; j++ )
\r
421 triangle->index_xyz[ j ] = _pico_little_short( triangle->index_xyz[ j ] );
\r
422 triangle->index_st[ j ] = _pico_little_short( triangle->index_st[ j ] );
\r
427 texCoord = (md2St_t*) ((picoByte_t *) (bb + md2->ofsST) );
\r
428 for( i = 0; i < md2->numST; i++, texCoord++ )
\r
430 texCoord->s = _pico_little_short( texCoord->s );
\r
431 texCoord->t = _pico_little_short( texCoord->t );
\r
435 strncpy(skinname, (bb + md2->ofsSkins), MD2_MAX_SKINNAME );
\r
437 // Print out md2 values
\r
438 _pico_printf(PICO_VERBOSE,"Skins: %d Verts: %d STs: %d Triangles: %d Frames: %d\nSkin Name \"%s\"\n", md2->numSkins, md2->numXYZ, md2->numST, md2->numTris, md2->numFrames, &skinname );
\r
441 _pico_setfext( skinname, "" );
\r
442 _pico_unixify( skinname );
\r
444 /* create new pico model */
\r
445 picoModel = PicoNewModel();
\r
446 if( picoModel == NULL )
\r
448 _pico_printf( PICO_ERROR, "Unable to allocate a new model" );
\r
452 /* do model setup */
\r
453 PicoSetModelFrameNum( picoModel, frameNum );
\r
454 PicoSetModelNumFrames( picoModel, md2->numFrames ); /* sea */
\r
455 PicoSetModelName( picoModel, fileName );
\r
456 PicoSetModelFileName( picoModel, fileName );
\r
458 // allocate new pico surface
\r
459 picoSurface = PicoNewSurface( picoModel );
\r
460 if( picoSurface == NULL )
\r
462 _pico_printf( PICO_ERROR, "Unable to allocate a new model surface" );
\r
463 PicoFreeModel( picoModel );
\r
468 PicoSetSurfaceType( picoSurface, PICO_TRIANGLES );
\r
469 PicoSetSurfaceName( picoSurface, frame->name );
\r
470 picoShader = PicoNewShader( picoModel );
\r
471 if( picoShader == NULL )
\r
473 _pico_printf( PICO_ERROR, "Unable to allocate a new model shader" );
\r
474 PicoFreeModel( picoModel );
\r
478 PicoSetShaderName( picoShader, skinname );
\r
480 // associate current surface with newly created shader
\r
481 PicoSetSurfaceShader( picoSurface, picoShader );
\r
483 // Init LUT for Verts
\r
484 p_index_LUT = (index_LUT_t *)_pico_alloc(sizeof(index_LUT_t) * md2->numXYZ);
\r
485 for(i=0; i<md2->numXYZ; i++)
\r
487 p_index_LUT[i].Vert = -1;
\r
488 p_index_LUT[i].ST = -1;
\r
489 p_index_LUT[i].next = NULL;
\r
492 // Fill in Look Up Table, and allocate/fill Linked List from vert array as needed for dup STs per Vert.
\r
493 tot_numVerts = md2->numXYZ;
\r
495 for(i=0; i<md2->numTris; i++)
\r
497 p_md2Triangle = (md2Triangle_t *) ( bb + md2->ofsTris + (sizeof(md2Triangle_t)*i));
\r
500 if (p_index_LUT[p_md2Triangle->index_xyz[j]].ST == -1) // No Main Entry
\r
501 p_index_LUT[p_md2Triangle->index_xyz[j]].ST = p_md2Triangle->index_st[j];
\r
503 else if (p_md2Triangle->index_st[j] == p_index_LUT[p_md2Triangle->index_xyz[j]].ST ) // Equal to Main Entry
\r
506 else if ( (p_index_LUT[p_md2Triangle->index_xyz[j]].next == NULL) ) // Not equal to Main entry, and no LL entry
\r
507 { // Add first entry of LL from Main
\r
508 p_index_LUT2 = (index_LUT_t *)_pico_alloc(sizeof(index_LUT_t));
\r
509 if (p_index_LUT2 == NULL)
\r
510 _pico_printf( PICO_ERROR," Couldn't allocate memory!\n");
\r
511 p_index_LUT[p_md2Triangle->index_xyz[j]].next = (index_LUT_t *)p_index_LUT2;
\r
512 p_index_LUT2->Vert = dups;
\r
513 p_index_LUT2->ST = p_md2Triangle->index_st[j];
\r
514 p_index_LUT2->next = NULL;
\r
515 p_md2Triangle->index_xyz[j] = dups + md2->numXYZ; // Make change in Tri hunk
\r
518 else // Try to find in LL from Main Entry
\r
520 p_index_LUT3 = p_index_LUT2 = p_index_LUT[p_md2Triangle->index_xyz[j]].next;
\r
521 while ( (p_index_LUT2 != NULL) && (p_md2Triangle->index_xyz[j] != p_index_LUT2->Vert) ) // Walk down LL
\r
523 p_index_LUT3 = p_index_LUT2;
\r
524 p_index_LUT2 = p_index_LUT2->next;
\r
526 p_index_LUT2 = p_index_LUT3;
\r
528 if ( p_md2Triangle->index_st[j] == p_index_LUT2->ST ) // Found it
\r
530 p_md2Triangle->index_xyz[j] = p_index_LUT2->Vert + md2->numXYZ; // Make change in Tri hunk
\r
534 if ( p_index_LUT2->next == NULL) // Didn't find it. Add entry to LL.
\r
537 p_index_LUT3 = (index_LUT_t *)_pico_alloc(sizeof(index_LUT_t));
\r
538 if (p_index_LUT3 == NULL)
\r
539 _pico_printf( PICO_ERROR," Couldn't allocate memory!\n");
\r
540 p_index_LUT2->next = (index_LUT_t *)p_index_LUT3;
\r
541 p_index_LUT3->Vert = p_md2Triangle->index_xyz[j];
\r
542 p_index_LUT3->ST = p_md2Triangle->index_st[j];
\r
543 p_index_LUT3->next = NULL;
\r
544 p_md2Triangle->index_xyz[j] = dups + md2->numXYZ; // Make change in Tri hunk
\r
551 // malloc and build array for Dup STs
\r
552 p_index_LUT_DUPS = (index_DUP_LUT_t *)_pico_alloc(sizeof(index_DUP_LUT_t) * dups);
\r
553 if (p_index_LUT_DUPS == NULL)
\r
554 _pico_printf( PICO_ERROR," Couldn't allocate memory!\n");
\r
557 for(i=0; i<md2->numXYZ; i++)
\r
559 p_index_LUT2 = p_index_LUT[i].next;
\r
560 while (p_index_LUT2 != NULL)
\r
562 p_index_LUT_DUPS[p_index_LUT2->Vert].OldVert = i;
\r
563 p_index_LUT_DUPS[p_index_LUT2->Vert].ST = p_index_LUT2->ST;
\r
565 p_index_LUT2 = p_index_LUT2->next;
\r
570 triangle = (md2Triangle_t *) ((picoByte_t *) (bb + md2->ofsTris) );
\r
571 texCoord = (md2St_t*) ((picoByte_t *) (bb + md2->ofsST) );
\r
572 vertex = (md2XyzNormal_t*) ((picoByte_t*) (frame->verts) );
\r
573 for( j = 0; j < md2->numTris; j++, triangle++ )
\r
575 PicoSetSurfaceIndex( picoSurface, j*3 , triangle->index_xyz[0] );
\r
576 PicoSetSurfaceIndex( picoSurface, j*3+1 , triangle->index_xyz[1] );
\r
577 PicoSetSurfaceIndex( picoSurface, j*3+2 , triangle->index_xyz[2] );
\r
580 for(i=0; i< md2->numXYZ; i++, vertex++)
\r
582 /* set vertex origin */
\r
583 xyz[ 0 ] = vertex->v[0] * frame->scale[0] + frame->translate[0];
\r
584 xyz[ 1 ] = vertex->v[1] * frame->scale[1] + frame->translate[1];
\r
585 xyz[ 2 ] = vertex->v[2] * frame->scale[2] + frame->translate[2];
\r
586 PicoSetSurfaceXYZ( picoSurface, i , xyz );
\r
589 normal[ 0 ] = md2_normals[vertex->lightnormalindex][0];
\r
590 normal[ 1 ] = md2_normals[vertex->lightnormalindex][1];
\r
591 normal[ 2 ] = md2_normals[vertex->lightnormalindex][2];
\r
592 PicoSetSurfaceNormal( picoSurface, i , normal );
\r
594 /* set st coords */
\r
595 st[ 0 ] = ((texCoord[p_index_LUT[i].ST].s) / ((float)md2->skinWidth));
\r
596 st[ 1 ] = (texCoord[p_index_LUT[i].ST].t / ((float)md2->skinHeight));
\r
597 PicoSetSurfaceST( picoSurface, 0, i , st );
\r
602 for(i=0; i<dups; i++)
\r
604 j = p_index_LUT_DUPS[i].OldVert;
\r
605 /* set vertex origin */
\r
606 xyz[ 0 ] = frame->verts[j].v[0] * frame->scale[0] + frame->translate[0];
\r
607 xyz[ 1 ] = frame->verts[j].v[1] * frame->scale[1] + frame->translate[1];
\r
608 xyz[ 2 ] = frame->verts[j].v[2] * frame->scale[2] + frame->translate[2];
\r
609 PicoSetSurfaceXYZ( picoSurface, i + md2->numXYZ , xyz );
\r
612 normal[ 0 ] = md2_normals[frame->verts[j].lightnormalindex][0];
\r
613 normal[ 1 ] = md2_normals[frame->verts[j].lightnormalindex][1];
\r
614 normal[ 2 ] = md2_normals[frame->verts[j].lightnormalindex][2];
\r
615 PicoSetSurfaceNormal( picoSurface, i + md2->numXYZ , normal );
\r
617 /* set st coords */
\r
618 st[ 0 ] = ((texCoord[p_index_LUT_DUPS[i].ST].s) / ((float)md2->skinWidth));
\r
619 st[ 1 ] = (texCoord[p_index_LUT_DUPS[i].ST].t / ((float)md2->skinHeight));
\r
620 PicoSetSurfaceST( picoSurface, 0, i + md2->numXYZ , st );
\r
625 PicoSetSurfaceColor( picoSurface, 0, 0, color );
\r
627 // Free up malloc'ed LL entries
\r
628 for(i=0; i<md2->numXYZ; i++)
\r
630 if(p_index_LUT[i].next != NULL)
\r
632 p_index_LUT2 = p_index_LUT[i].next;
\r
634 p_index_LUT3 = p_index_LUT2->next;
\r
635 _pico_free(p_index_LUT2);
\r
636 p_index_LUT2 = p_index_LUT3;
\r
638 } while (p_index_LUT2 != NULL);
\r
643 _pico_printf(PICO_WARNING, " Not all LL mallocs freed\n");
\r
645 // Free malloc'ed LUTs
\r
646 _pico_free(p_index_LUT);
\r
647 _pico_free(p_index_LUT_DUPS);
\r
649 /* return the new pico model */
\r
656 /* pico file format module definition */
\r
657 const picoModule_t picoModuleMD2 =
\r
659 "0.875", /* module version string */
\r
660 "Quake 2 MD2", /* module display name */
\r
661 "Nurail", /* author's name */
\r
662 "2003 Nurail", /* module copyright */
\r
664 "md2", NULL, NULL, NULL /* default extensions to use */
\r
666 _md2_canload, /* validation routine */
\r
667 _md2_load, /* load routine */
\r
668 NULL, /* save validation routine */
\r
669 NULL /* save routine */
\r