1 /* -----------------------------------------------------------------------------
5 Copyright (c) 2002, Randy Reddig & seaw0lf
8 Redistribution and use in source and binary forms, with or without modification,
9 are permitted provided that the following conditions are met:
11 Redistributions of source code must retain the above copyright notice, this list
12 of conditions and the following disclaimer.
14 Redistributions in binary form must reproduce the above copyright notice, this
15 list of conditions and the following disclaimer in the documentation and/or
16 other materials provided with the distribution.
18 Neither the names of the copyright holders nor the names of its contributors may
19 be used to endorse or promote products derived from this software without
20 specific prior written permission.
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
26 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 ----------------------------------------------------------------------------- */
43 #include "picointernal.h"
45 /* mdc model format */
46 #define MDC_MAGIC "IDPC"
49 /* mdc vertex scale */
50 #define MDC_SCALE (1.0f / 64.0f)
51 #define MDC_MAX_OFS 127.0f
52 #define MDC_DIST_SCALE 0.05f
54 /* mdc decoding normal table */
55 double mdcNormals[ 256 ][ 3 ] =
57 { 1.000000, 0.000000, 0.000000 },
58 { 0.980785, 0.195090, 0.000000 },
59 { 0.923880, 0.382683, 0.000000 },
60 { 0.831470, 0.555570, 0.000000 },
61 { 0.707107, 0.707107, 0.000000 },
62 { 0.555570, 0.831470, 0.000000 },
63 { 0.382683, 0.923880, 0.000000 },
64 { 0.195090, 0.980785, 0.000000 },
65 { -0.000000, 1.000000, 0.000000 },
66 { -0.195090, 0.980785, 0.000000 },
67 { -0.382683, 0.923880, 0.000000 },
68 { -0.555570, 0.831470, 0.000000 },
69 { -0.707107, 0.707107, 0.000000 },
70 { -0.831470, 0.555570, 0.000000 },
71 { -0.923880, 0.382683, 0.000000 },
72 { -0.980785, 0.195090, 0.000000 },
73 { -1.000000, -0.000000, 0.000000 },
74 { -0.980785, -0.195090, 0.000000 },
75 { -0.923880, -0.382683, 0.000000 },
76 { -0.831470, -0.555570, 0.000000 },
77 { -0.707107, -0.707107, 0.000000 },
78 { -0.555570, -0.831469, 0.000000 },
79 { -0.382684, -0.923880, 0.000000 },
80 { -0.195090, -0.980785, 0.000000 },
81 { 0.000000, -1.000000, 0.000000 },
82 { 0.195090, -0.980785, 0.000000 },
83 { 0.382684, -0.923879, 0.000000 },
84 { 0.555570, -0.831470, 0.000000 },
85 { 0.707107, -0.707107, 0.000000 },
86 { 0.831470, -0.555570, 0.000000 },
87 { 0.923880, -0.382683, 0.000000 },
88 { 0.980785, -0.195090, 0.000000 },
89 { 0.980785, 0.000000, -0.195090 },
90 { 0.956195, 0.218245, -0.195090 },
91 { 0.883657, 0.425547, -0.195090 },
92 { 0.766809, 0.611510, -0.195090 },
93 { 0.611510, 0.766809, -0.195090 },
94 { 0.425547, 0.883657, -0.195090 },
95 { 0.218245, 0.956195, -0.195090 },
96 { -0.000000, 0.980785, -0.195090 },
97 { -0.218245, 0.956195, -0.195090 },
98 { -0.425547, 0.883657, -0.195090 },
99 { -0.611510, 0.766809, -0.195090 },
100 { -0.766809, 0.611510, -0.195090 },
101 { -0.883657, 0.425547, -0.195090 },
102 { -0.956195, 0.218245, -0.195090 },
103 { -0.980785, -0.000000, -0.195090 },
104 { -0.956195, -0.218245, -0.195090 },
105 { -0.883657, -0.425547, -0.195090 },
106 { -0.766809, -0.611510, -0.195090 },
107 { -0.611510, -0.766809, -0.195090 },
108 { -0.425547, -0.883657, -0.195090 },
109 { -0.218245, -0.956195, -0.195090 },
110 { 0.000000, -0.980785, -0.195090 },
111 { 0.218245, -0.956195, -0.195090 },
112 { 0.425547, -0.883657, -0.195090 },
113 { 0.611510, -0.766809, -0.195090 },
114 { 0.766809, -0.611510, -0.195090 },
115 { 0.883657, -0.425547, -0.195090 },
116 { 0.956195, -0.218245, -0.195090 },
117 { 0.923880, 0.000000, -0.382683 },
118 { 0.892399, 0.239118, -0.382683 },
119 { 0.800103, 0.461940, -0.382683 },
120 { 0.653281, 0.653281, -0.382683 },
121 { 0.461940, 0.800103, -0.382683 },
122 { 0.239118, 0.892399, -0.382683 },
123 { -0.000000, 0.923880, -0.382683 },
124 { -0.239118, 0.892399, -0.382683 },
125 { -0.461940, 0.800103, -0.382683 },
126 { -0.653281, 0.653281, -0.382683 },
127 { -0.800103, 0.461940, -0.382683 },
128 { -0.892399, 0.239118, -0.382683 },
129 { -0.923880, -0.000000, -0.382683 },
130 { -0.892399, -0.239118, -0.382683 },
131 { -0.800103, -0.461940, -0.382683 },
132 { -0.653282, -0.653281, -0.382683 },
133 { -0.461940, -0.800103, -0.382683 },
134 { -0.239118, -0.892399, -0.382683 },
135 { 0.000000, -0.923880, -0.382683 },
136 { 0.239118, -0.892399, -0.382683 },
137 { 0.461940, -0.800103, -0.382683 },
138 { 0.653281, -0.653282, -0.382683 },
139 { 0.800103, -0.461940, -0.382683 },
140 { 0.892399, -0.239117, -0.382683 },
141 { 0.831470, 0.000000, -0.555570 },
142 { 0.790775, 0.256938, -0.555570 },
143 { 0.672673, 0.488726, -0.555570 },
144 { 0.488726, 0.672673, -0.555570 },
145 { 0.256938, 0.790775, -0.555570 },
146 { -0.000000, 0.831470, -0.555570 },
147 { -0.256938, 0.790775, -0.555570 },
148 { -0.488726, 0.672673, -0.555570 },
149 { -0.672673, 0.488726, -0.555570 },
150 { -0.790775, 0.256938, -0.555570 },
151 { -0.831470, -0.000000, -0.555570 },
152 { -0.790775, -0.256938, -0.555570 },
153 { -0.672673, -0.488726, -0.555570 },
154 { -0.488725, -0.672673, -0.555570 },
155 { -0.256938, -0.790775, -0.555570 },
156 { 0.000000, -0.831470, -0.555570 },
157 { 0.256938, -0.790775, -0.555570 },
158 { 0.488725, -0.672673, -0.555570 },
159 { 0.672673, -0.488726, -0.555570 },
160 { 0.790775, -0.256938, -0.555570 },
161 { 0.707107, 0.000000, -0.707107 },
162 { 0.653281, 0.270598, -0.707107 },
163 { 0.500000, 0.500000, -0.707107 },
164 { 0.270598, 0.653281, -0.707107 },
165 { -0.000000, 0.707107, -0.707107 },
166 { -0.270598, 0.653282, -0.707107 },
167 { -0.500000, 0.500000, -0.707107 },
168 { -0.653281, 0.270598, -0.707107 },
169 { -0.707107, -0.000000, -0.707107 },
170 { -0.653281, -0.270598, -0.707107 },
171 { -0.500000, -0.500000, -0.707107 },
172 { -0.270598, -0.653281, -0.707107 },
173 { 0.000000, -0.707107, -0.707107 },
174 { 0.270598, -0.653281, -0.707107 },
175 { 0.500000, -0.500000, -0.707107 },
176 { 0.653282, -0.270598, -0.707107 },
177 { 0.555570, 0.000000, -0.831470 },
178 { 0.481138, 0.277785, -0.831470 },
179 { 0.277785, 0.481138, -0.831470 },
180 { -0.000000, 0.555570, -0.831470 },
181 { -0.277785, 0.481138, -0.831470 },
182 { -0.481138, 0.277785, -0.831470 },
183 { -0.555570, -0.000000, -0.831470 },
184 { -0.481138, -0.277785, -0.831470 },
185 { -0.277785, -0.481138, -0.831470 },
186 { 0.000000, -0.555570, -0.831470 },
187 { 0.277785, -0.481138, -0.831470 },
188 { 0.481138, -0.277785, -0.831470 },
189 { 0.382683, 0.000000, -0.923880 },
190 { 0.270598, 0.270598, -0.923880 },
191 { -0.000000, 0.382683, -0.923880 },
192 { -0.270598, 0.270598, -0.923880 },
193 { -0.382683, -0.000000, -0.923880 },
194 { -0.270598, -0.270598, -0.923880 },
195 { 0.000000, -0.382683, -0.923880 },
196 { 0.270598, -0.270598, -0.923880 },
197 { 0.195090, 0.000000, -0.980785 },
198 { -0.000000, 0.195090, -0.980785 },
199 { -0.195090, -0.000000, -0.980785 },
200 { 0.000000, -0.195090, -0.980785 },
201 { 0.980785, 0.000000, 0.195090 },
202 { 0.956195, 0.218245, 0.195090 },
203 { 0.883657, 0.425547, 0.195090 },
204 { 0.766809, 0.611510, 0.195090 },
205 { 0.611510, 0.766809, 0.195090 },
206 { 0.425547, 0.883657, 0.195090 },
207 { 0.218245, 0.956195, 0.195090 },
208 { -0.000000, 0.980785, 0.195090 },
209 { -0.218245, 0.956195, 0.195090 },
210 { -0.425547, 0.883657, 0.195090 },
211 { -0.611510, 0.766809, 0.195090 },
212 { -0.766809, 0.611510, 0.195090 },
213 { -0.883657, 0.425547, 0.195090 },
214 { -0.956195, 0.218245, 0.195090 },
215 { -0.980785, -0.000000, 0.195090 },
216 { -0.956195, -0.218245, 0.195090 },
217 { -0.883657, -0.425547, 0.195090 },
218 { -0.766809, -0.611510, 0.195090 },
219 { -0.611510, -0.766809, 0.195090 },
220 { -0.425547, -0.883657, 0.195090 },
221 { -0.218245, -0.956195, 0.195090 },
222 { 0.000000, -0.980785, 0.195090 },
223 { 0.218245, -0.956195, 0.195090 },
224 { 0.425547, -0.883657, 0.195090 },
225 { 0.611510, -0.766809, 0.195090 },
226 { 0.766809, -0.611510, 0.195090 },
227 { 0.883657, -0.425547, 0.195090 },
228 { 0.956195, -0.218245, 0.195090 },
229 { 0.923880, 0.000000, 0.382683 },
230 { 0.892399, 0.239118, 0.382683 },
231 { 0.800103, 0.461940, 0.382683 },
232 { 0.653281, 0.653281, 0.382683 },
233 { 0.461940, 0.800103, 0.382683 },
234 { 0.239118, 0.892399, 0.382683 },
235 { -0.000000, 0.923880, 0.382683 },
236 { -0.239118, 0.892399, 0.382683 },
237 { -0.461940, 0.800103, 0.382683 },
238 { -0.653281, 0.653281, 0.382683 },
239 { -0.800103, 0.461940, 0.382683 },
240 { -0.892399, 0.239118, 0.382683 },
241 { -0.923880, -0.000000, 0.382683 },
242 { -0.892399, -0.239118, 0.382683 },
243 { -0.800103, -0.461940, 0.382683 },
244 { -0.653282, -0.653281, 0.382683 },
245 { -0.461940, -0.800103, 0.382683 },
246 { -0.239118, -0.892399, 0.382683 },
247 { 0.000000, -0.923880, 0.382683 },
248 { 0.239118, -0.892399, 0.382683 },
249 { 0.461940, -0.800103, 0.382683 },
250 { 0.653281, -0.653282, 0.382683 },
251 { 0.800103, -0.461940, 0.382683 },
252 { 0.892399, -0.239117, 0.382683 },
253 { 0.831470, 0.000000, 0.555570 },
254 { 0.790775, 0.256938, 0.555570 },
255 { 0.672673, 0.488726, 0.555570 },
256 { 0.488726, 0.672673, 0.555570 },
257 { 0.256938, 0.790775, 0.555570 },
258 { -0.000000, 0.831470, 0.555570 },
259 { -0.256938, 0.790775, 0.555570 },
260 { -0.488726, 0.672673, 0.555570 },
261 { -0.672673, 0.488726, 0.555570 },
262 { -0.790775, 0.256938, 0.555570 },
263 { -0.831470, -0.000000, 0.555570 },
264 { -0.790775, -0.256938, 0.555570 },
265 { -0.672673, -0.488726, 0.555570 },
266 { -0.488725, -0.672673, 0.555570 },
267 { -0.256938, -0.790775, 0.555570 },
268 { 0.000000, -0.831470, 0.555570 },
269 { 0.256938, -0.790775, 0.555570 },
270 { 0.488725, -0.672673, 0.555570 },
271 { 0.672673, -0.488726, 0.555570 },
272 { 0.790775, -0.256938, 0.555570 },
273 { 0.707107, 0.000000, 0.707107 },
274 { 0.653281, 0.270598, 0.707107 },
275 { 0.500000, 0.500000, 0.707107 },
276 { 0.270598, 0.653281, 0.707107 },
277 { -0.000000, 0.707107, 0.707107 },
278 { -0.270598, 0.653282, 0.707107 },
279 { -0.500000, 0.500000, 0.707107 },
280 { -0.653281, 0.270598, 0.707107 },
281 { -0.707107, -0.000000, 0.707107 },
282 { -0.653281, -0.270598, 0.707107 },
283 { -0.500000, -0.500000, 0.707107 },
284 { -0.270598, -0.653281, 0.707107 },
285 { 0.000000, -0.707107, 0.707107 },
286 { 0.270598, -0.653281, 0.707107 },
287 { 0.500000, -0.500000, 0.707107 },
288 { 0.653282, -0.270598, 0.707107 },
289 { 0.555570, 0.000000, 0.831470 },
290 { 0.481138, 0.277785, 0.831470 },
291 { 0.277785, 0.481138, 0.831470 },
292 { -0.000000, 0.555570, 0.831470 },
293 { -0.277785, 0.481138, 0.831470 },
294 { -0.481138, 0.277785, 0.831470 },
295 { -0.555570, -0.000000, 0.831470 },
296 { -0.481138, -0.277785, 0.831470 },
297 { -0.277785, -0.481138, 0.831470 },
298 { 0.000000, -0.555570, 0.831470 },
299 { 0.277785, -0.481138, 0.831470 },
300 { 0.481138, -0.277785, 0.831470 },
301 { 0.382683, 0.000000, 0.923880 },
302 { 0.270598, 0.270598, 0.923880 },
303 { -0.000000, 0.382683, 0.923880 },
304 { -0.270598, 0.270598, 0.923880 },
305 { -0.382683, -0.000000, 0.923880 },
306 { -0.270598, -0.270598, 0.923880 },
307 { 0.000000, -0.382683, 0.923880 },
308 { 0.270598, -0.270598, 0.923880 },
309 { 0.195090, 0.000000, 0.980785 },
310 { -0.000000, 0.195090, 0.980785 },
311 { -0.195090, -0.000000, 0.980785 },
312 { 0.000000, -0.195090, 0.980785 }
315 /* mdc model frame information */
316 typedef struct mdcFrame_s
318 float bounds[ 2 ][ 3 ];
319 float localOrigin[ 3 ];
325 /* mdc model tag information */
326 typedef struct mdcTag_s
333 /* mdc surface mdc (one object mesh) */
334 typedef struct mdcSurface_s
337 char name[ 64 ]; /* polyset name */
339 int numCompFrames; /* all surfaces in a model should have the same */
340 int numBaseFrames; /* ditto */
341 int numShaders; /* all model surfaces should have the same */
345 int ofsShaders; /* offset from start of mdcSurface_t */
346 int ofsSt; /* texture coords are common for all frames */
347 int ofsXyzNormals; /* numVerts * numBaseFrames */
348 int ofsXyzCompressed; /* numVerts * numCompFrames */
350 int ofsFrameBaseFrames; /* numFrames */
351 int ofsFrameCompFrames; /* numFrames */
352 int ofsEnd; /* next surface follows */
356 typedef struct mdcShader_s
359 int shaderIndex; /* for ingame use */
363 typedef struct mdcTriangle_s
369 typedef struct mdcTexCoord_s
375 typedef struct mdcVertex_s
382 typedef struct mdcXyzCompressed_s
384 unsigned int ofsVec; /* offset direction from the last base frame */
389 /* mdc model file mdc structure */
392 char magic[ 4 ]; /* MDC_MAGIC */
394 char name[ 64 ]; /* model name */
399 int numSkins; /* number of skins for the mesh */
400 int ofsFrames; /* offset for first frame */
401 int ofsTagNames; /* numTags */
402 int ofsTags; /* numFrames * numTags */
403 int ofsSurfaces; /* first surface, others follow */
404 int ofsEnd; /* end of file */
413 validates a Return to Castle Wolfenstein model file. btw, i use the
414 preceding underscore cause it's a static func referenced
415 by one structure only.
418 static int _mdc_canload( PM_PARAMS_CANLOAD )
424 if( (size_t) bufSize < ( sizeof( *mdc ) * 2) )
425 return PICO_PMV_ERROR_SIZE;
428 mdc = (const mdc_t*) buffer;
430 /* check mdc magic */
431 if( *((const int*) mdc->magic) != *((const int*) MDC_MAGIC) )
432 return PICO_PMV_ERROR_IDENT;
434 /* check mdc version */
435 if( _pico_little_long( mdc->version ) != MDC_VERSION )
436 return PICO_PMV_ERROR_VERSION;
438 /* file seems to be a valid mdc */
446 loads a Return to Castle Wolfenstein mdc model file.
449 static picoModel_t *_mdc_load( PM_PARAMS_LOAD )
452 picoByte_t *bb, *bb0;
454 mdcSurface_t *surface;
456 mdcTexCoord_t *texCoord;
458 mdcTriangle_t *triangle;
460 mdcXyzCompressed_t *vertexComp = NULL;
461 short *mdcShort, *mdcCompVert = NULL;
464 picoModel_t *picoModel;
465 picoSurface_t *picoSurface;
466 picoShader_t *picoShader;
467 picoVec3_t xyz, normal;
472 /* -------------------------------------------------
474 ------------------------------------------------- */
478 bb0 = bb = (picoByte_t*) _pico_alloc(bufSize);
479 memcpy(bb, buffer, bufSize);
482 /* check ident and version */
483 if( *((int*) mdc->magic) != *((int*) MDC_MAGIC) || _pico_little_long( mdc->version ) != MDC_VERSION )
485 /* not an mdc file (todo: set error) */
491 mdc->version = _pico_little_long( mdc->version );
492 mdc->numFrames = _pico_little_long( mdc->numFrames );
493 mdc->numTags = _pico_little_long( mdc->numTags );
494 mdc->numSurfaces = _pico_little_long( mdc->numSurfaces );
495 mdc->numSkins = _pico_little_long( mdc->numSkins );
496 mdc->ofsFrames = _pico_little_long( mdc->ofsFrames );
497 mdc->ofsTags = _pico_little_long( mdc->ofsTags );
498 mdc->ofsTagNames = _pico_little_long( mdc->ofsTagNames );
499 mdc->ofsSurfaces = _pico_little_long( mdc->ofsSurfaces );
500 mdc->ofsEnd = _pico_little_long( mdc->ofsEnd );
503 if( mdc->numFrames < 1 )
505 _pico_printf( PICO_ERROR, "MDC with 0 frames" );
510 if( frameNum < 0 || frameNum >= mdc->numFrames )
512 _pico_printf( PICO_ERROR, "Invalid or out-of-range MDC frame specified" );
518 frame = (mdcFrame_t*) (bb + mdc->ofsFrames );
519 for( i = 0; i < mdc->numFrames; i++, frame++ )
521 frame->radius = _pico_little_float( frame->radius );
522 for( j = 0; j < 3; j++ )
524 frame->bounds[ 0 ][ j ] = _pico_little_float( frame->bounds[ 0 ][ j ] );
525 frame->bounds[ 1 ][ j ] = _pico_little_float( frame->bounds[ 1 ][ j ] );
526 frame->localOrigin[ j ] = _pico_little_float( frame->localOrigin[ j ] );
531 surface = (mdcSurface_t*) (bb + mdc->ofsSurfaces);
532 for( i = 0; i < mdc->numSurfaces; i++ )
534 /* swap surface mdc */
535 surface->flags = _pico_little_long( surface->flags );
536 surface->numBaseFrames = _pico_little_long( surface->numBaseFrames );
537 surface->numCompFrames = _pico_little_long( surface->numCompFrames );
538 surface->numShaders = _pico_little_long( surface->numShaders );
539 surface->numTriangles = _pico_little_long( surface->numTriangles );
540 surface->ofsTriangles = _pico_little_long( surface->ofsTriangles );
541 surface->numVerts = _pico_little_long( surface->numVerts );
542 surface->ofsShaders = _pico_little_long( surface->ofsShaders );
543 surface->ofsSt = _pico_little_long( surface->ofsSt );
544 surface->ofsXyzNormals = _pico_little_long( surface->ofsXyzNormals );
545 surface->ofsXyzCompressed = _pico_little_long( surface->ofsXyzCompressed );
546 surface->ofsFrameBaseFrames = _pico_little_long( surface->ofsFrameBaseFrames );
547 surface->ofsFrameCompFrames = _pico_little_long( surface->ofsFrameCompFrames );
548 surface->ofsEnd = _pico_little_long( surface->ofsEnd );
551 triangle = (mdcTriangle_t*) ((picoByte_t*) surface + surface->ofsTriangles);
552 for( j = 0; j < surface->numTriangles; j++, triangle++ )
554 /* sea: swaps fixed */
555 triangle->indexes[ 0 ] = _pico_little_long( triangle->indexes[ 0 ] );
556 triangle->indexes[ 1 ] = _pico_little_long( triangle->indexes[ 1 ] );
557 triangle->indexes[ 2 ] = _pico_little_long( triangle->indexes[ 2 ] );
561 texCoord = (mdcTexCoord_t*) ((picoByte_t*) surface + surface->ofsSt);
562 for( j = 0; j < surface->numVerts; j++, texCoord++ )
564 texCoord->st[ 0 ] = _pico_little_float( texCoord->st[ 0 ] );
565 texCoord->st[ 1 ] = _pico_little_float( texCoord->st[ 1 ] );
568 /* swap xyz/normals */
569 vertex = (mdcVertex_t*) ((picoByte_t*) surface + surface->ofsXyzNormals);
570 for( j = 0; j < (surface->numVerts * surface->numBaseFrames); j++, vertex++)
572 vertex->xyz[ 0 ] = _pico_little_short( vertex->xyz[ 0 ] );
573 vertex->xyz[ 1 ] = _pico_little_short( vertex->xyz[ 1 ] );
574 vertex->xyz[ 2 ] = _pico_little_short( vertex->xyz[ 2 ] );
575 vertex->normal = _pico_little_short( vertex->normal );
578 /* swap xyz/compressed */
579 vertexComp = (mdcXyzCompressed_t*) ((picoByte_t*) surface + surface->ofsXyzCompressed);
580 for( j = 0; j < (surface->numVerts * surface->numCompFrames); j++, vertexComp++)
582 vertexComp->ofsVec = _pico_little_long( vertexComp->ofsVec );
585 /* swap base frames */
586 mdcShort = (short *) ((picoByte_t*) surface + surface->ofsFrameBaseFrames);
587 for( j = 0; j < mdc->numFrames; j++, mdcShort++)
589 *mdcShort = _pico_little_short( *mdcShort );
592 /* swap compressed frames */
593 mdcShort = (short *) ((picoByte_t*) surface + surface->ofsFrameCompFrames);
594 for( j = 0; j < mdc->numFrames; j++, mdcShort++)
596 *mdcShort = _pico_little_short( *mdcShort );
599 /* get next surface */
600 surface = (mdcSurface_t*) ((picoByte_t*) surface + surface->ofsEnd);
603 /* -------------------------------------------------
605 ------------------------------------------------- */
607 /* create new pico model */
608 picoModel = PicoNewModel();
609 if( picoModel == NULL )
611 _pico_printf( PICO_ERROR, "Unable to allocate a new model" );
617 PicoSetModelFrameNum( picoModel, frameNum );
618 PicoSetModelNumFrames( picoModel, mdc->numFrames ); /* sea */
619 PicoSetModelName( picoModel, fileName );
620 PicoSetModelFileName( picoModel, fileName );
622 /* mdc surfaces become picomodel surfaces */
623 surface = (mdcSurface_t*) (bb + mdc->ofsSurfaces);
625 /* run through mdc surfaces */
626 for( i = 0; i < mdc->numSurfaces; i++ )
628 /* allocate new pico surface */
629 picoSurface = PicoNewSurface( picoModel );
630 if( picoSurface == NULL )
632 _pico_printf( PICO_ERROR, "Unable to allocate a new model surface" );
633 PicoFreeModel( picoModel ); /* sea */
638 /* mdc model surfaces are all triangle meshes */
639 PicoSetSurfaceType( picoSurface, PICO_TRIANGLES );
641 /* set surface name */
642 PicoSetSurfaceName( picoSurface, surface->name );
644 /* create new pico shader -sea */
645 picoShader = PicoNewShader( picoModel );
646 if( picoShader == NULL )
648 _pico_printf( PICO_ERROR, "Unable to allocate a new model shader" );
649 PicoFreeModel( picoModel );
654 /* detox and set shader name */
655 shader = (mdcShader_t*) ((picoByte_t*) surface + surface->ofsShaders);
656 _pico_setfext( shader->name, "" );
657 _pico_unixify( shader->name );
658 PicoSetShaderName( picoShader, shader->name );
660 /* associate current surface with newly created shader */
661 PicoSetSurfaceShader( picoSurface, picoShader );
664 triangle = (mdcTriangle_t *) ((picoByte_t*) surface + surface->ofsTriangles);
666 for( j = 0; j < surface->numTriangles; j++, triangle++ )
668 PicoSetSurfaceIndex( picoSurface, (j * 3 + 0), (picoIndex_t) triangle->indexes[ 0 ] );
669 PicoSetSurfaceIndex( picoSurface, (j * 3 + 1), (picoIndex_t) triangle->indexes[ 1 ] );
670 PicoSetSurfaceIndex( picoSurface, (j * 3 + 2), (picoIndex_t) triangle->indexes[ 2 ] );
674 texCoord = (mdcTexCoord_t*) ((picoByte_t *) surface + surface->ofsSt);
675 mdcShort = (short *) ((picoByte_t *) surface + surface->ofsXyzNormals) + ((int)*((short *) ((picoByte_t *) surface + surface->ofsFrameBaseFrames) + frameNum) * surface->numVerts * 4);
676 if( surface->numCompFrames > 0 )
678 mdcCompVert = (short *) ((picoByte_t *) surface + surface->ofsFrameCompFrames) + frameNum;
679 if( *mdcCompVert >= 0 )
680 vertexComp = (mdcXyzCompressed_t *) ((picoByte_t *) surface + surface->ofsXyzCompressed) + (*mdcCompVert * surface->numVerts);
682 _pico_set_color( color, 255, 255, 255, 255 );
684 for( j = 0; j < surface->numVerts; j++, texCoord++, mdcShort+=4 )
686 /* set vertex origin */
687 xyz[ 0 ] = MDC_SCALE * mdcShort[ 0 ];
688 xyz[ 1 ] = MDC_SCALE * mdcShort[ 1 ];
689 xyz[ 2 ] = MDC_SCALE * mdcShort[ 2 ];
691 /* add compressed ofsVec */
692 if( surface->numCompFrames > 0 && *mdcCompVert >= 0 )
694 xyz[ 0 ] += ((float) ((vertexComp->ofsVec) & 255) - MDC_MAX_OFS) * MDC_DIST_SCALE;
695 xyz[ 1 ] += ((float) ((vertexComp->ofsVec >> 8) & 255) - MDC_MAX_OFS) * MDC_DIST_SCALE;
696 xyz[ 2 ] += ((float) ((vertexComp->ofsVec >> 16) & 255) - MDC_MAX_OFS) * MDC_DIST_SCALE;
697 PicoSetSurfaceXYZ( picoSurface, j, xyz );
699 normal[ 0 ] = (float) mdcNormals[ (vertexComp->ofsVec >> 24) ][ 0 ];
700 normal[ 1 ] = (float) mdcNormals[ (vertexComp->ofsVec >> 24) ][ 1 ];
701 normal[ 2 ] = (float) mdcNormals[ (vertexComp->ofsVec >> 24) ][ 2 ];
702 PicoSetSurfaceNormal( picoSurface, j, normal );
708 PicoSetSurfaceXYZ( picoSurface, j, xyz );
710 /* decode lat/lng normal to 3 float normal */
711 lat = (float) ((*(mdcShort + 3) >> 8) & 0xff);
712 lng = (float) (*(mdcShort + 3) & 0xff);
713 lat *= PICO_PI / 128;
714 lng *= PICO_PI / 128;
715 normal[ 0 ] = (picoVec_t) cos( lat ) * (picoVec_t) sin( lng );
716 normal[ 1 ] = (picoVec_t) sin( lat ) * (picoVec_t) sin( lng );
717 normal[ 2 ] = (picoVec_t) cos( lng );
718 PicoSetSurfaceNormal( picoSurface, j, normal );
722 st[ 0 ] = texCoord->st[ 0 ];
723 st[ 1 ] = texCoord->st[ 1 ];
724 PicoSetSurfaceST( picoSurface, 0, j, st );
727 PicoSetSurfaceColor( picoSurface, 0, j, color );
730 /* get next surface */
731 surface = (mdcSurface_t*) ((picoByte_t*) surface + surface->ofsEnd);
734 /* return the new pico model */
741 /* pico file format module definition */
742 const picoModule_t picoModuleMDC =
744 "1.3", /* module version string */
745 "RtCW MDC", /* module display name */
746 "Arnout van Meer", /* author's name */
747 "2002 Arnout van Meer", /* module copyright */
749 "mdc", NULL, NULL, NULL /* default extensions to use */
751 _mdc_canload, /* validation routine */
752 _mdc_load, /* load routine */
753 NULL, /* save validation routine */
754 NULL /* save routine */