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 )
423 /* to keep the compiler happy */
424 *fileName = *fileName;
427 if( bufSize < ( sizeof( *mdc ) * 2) )
428 return PICO_PMV_ERROR_SIZE;
431 mdc = (mdc_t*) buffer;
433 /* check mdc magic */
434 if( *((int*) mdc->magic) != *((int*) MDC_MAGIC) )
435 return PICO_PMV_ERROR_IDENT;
437 /* check mdc version */
438 if( _pico_little_long( mdc->version ) != MDC_VERSION )
439 return PICO_PMV_ERROR_VERSION;
441 /* file seems to be a valid mdc */
449 loads a Return to Castle Wolfenstein mdc model file.
452 static picoModel_t *_mdc_load( PM_PARAMS_LOAD )
457 mdcSurface_t *surface;
459 mdcTexCoord_t *texCoord;
461 mdcTriangle_t *triangle;
463 mdcXyzCompressed_t *vertexComp;
464 short *mdcShort, *mdcCompVert;
467 picoModel_t *picoModel;
468 picoSurface_t *picoSurface;
469 picoShader_t *picoShader;
470 picoVec3_t xyz, normal;
475 /* -------------------------------------------------
477 ------------------------------------------------- */
481 bb = (picoByte_t*) buffer;
482 mdc = (mdc_t*) buffer;
484 /* check ident and version */
485 if( *((int*) mdc->magic) != *((int*) MDC_MAGIC) || _pico_little_long( mdc->version ) != MDC_VERSION )
487 /* not an mdc file (todo: set error) */
492 mdc->version = _pico_little_long( mdc->version );
493 mdc->numFrames = _pico_little_long( mdc->numFrames );
494 mdc->numTags = _pico_little_long( mdc->numTags );
495 mdc->numSurfaces = _pico_little_long( mdc->numSurfaces );
496 mdc->numSkins = _pico_little_long( mdc->numSkins );
497 mdc->ofsFrames = _pico_little_long( mdc->ofsFrames );
498 mdc->ofsTags = _pico_little_long( mdc->ofsTags );
499 mdc->ofsTagNames = _pico_little_long( mdc->ofsTagNames );
500 mdc->ofsSurfaces = _pico_little_long( mdc->ofsSurfaces );
501 mdc->ofsEnd = _pico_little_long( mdc->ofsEnd );
504 if( mdc->numFrames < 1 )
506 _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" );
517 frame = (mdcFrame_t*) (bb + mdc->ofsFrames );
518 for( i = 0; i < mdc->numFrames; i++, frame++ )
520 frame->radius = _pico_little_float( frame->radius );
521 for( j = 0; j < 3; j++ )
523 frame->bounds[ 0 ][ j ] = _pico_little_float( frame->bounds[ 0 ][ j ] );
524 frame->bounds[ 1 ][ j ] = _pico_little_float( frame->bounds[ 1 ][ j ] );
525 frame->localOrigin[ j ] = _pico_little_float( frame->localOrigin[ j ] );
530 surface = (mdcSurface_t*) (bb + mdc->ofsSurfaces);
531 for( i = 0; i < mdc->numSurfaces; i++ )
533 /* swap surface mdc */
534 surface->flags = _pico_little_long( surface->flags );
535 surface->numBaseFrames = _pico_little_long( surface->numBaseFrames );
536 surface->numCompFrames = _pico_little_long( surface->numCompFrames );
537 surface->numShaders = _pico_little_long( surface->numShaders );
538 surface->numTriangles = _pico_little_long( surface->numTriangles );
539 surface->ofsTriangles = _pico_little_long( surface->ofsTriangles );
540 surface->numVerts = _pico_little_long( surface->numVerts );
541 surface->ofsShaders = _pico_little_long( surface->ofsShaders );
542 surface->ofsSt = _pico_little_long( surface->ofsSt );
543 surface->ofsXyzNormals = _pico_little_long( surface->ofsXyzNormals );
544 surface->ofsXyzCompressed = _pico_little_long( surface->ofsXyzCompressed );
545 surface->ofsFrameBaseFrames = _pico_little_long( surface->ofsFrameBaseFrames );
546 surface->ofsFrameCompFrames = _pico_little_long( surface->ofsFrameCompFrames );
547 surface->ofsEnd = _pico_little_long( surface->ofsEnd );
550 triangle = (mdcTriangle_t*) ((picoByte_t*) surface + surface->ofsTriangles);
551 for( j = 0; j < surface->numTriangles; j++, triangle++ )
553 /* sea: swaps fixed */
554 triangle->indexes[ 0 ] = _pico_little_long( triangle->indexes[ 0 ] );
555 triangle->indexes[ 1 ] = _pico_little_long( triangle->indexes[ 1 ] );
556 triangle->indexes[ 2 ] = _pico_little_long( triangle->indexes[ 2 ] );
560 texCoord = (mdcTexCoord_t*) ((picoByte_t*) surface + surface->ofsSt);
561 for( j = 0; j < surface->numVerts; j++, texCoord++ )
563 texCoord->st[ 0 ] = _pico_little_float( texCoord->st[ 0 ] );
564 texCoord->st[ 1 ] = _pico_little_float( texCoord->st[ 1 ] );
567 /* swap xyz/normals */
568 vertex = (mdcVertex_t*) ((picoByte_t*) surface + surface->ofsXyzNormals);
569 for( j = 0; j < (surface->numVerts * surface->numBaseFrames); j++, vertex++)
571 vertex->xyz[ 0 ] = _pico_little_short( vertex->xyz[ 0 ] );
572 vertex->xyz[ 1 ] = _pico_little_short( vertex->xyz[ 1 ] );
573 vertex->xyz[ 2 ] = _pico_little_short( vertex->xyz[ 2 ] );
574 vertex->normal = _pico_little_short( vertex->normal );
577 /* swap xyz/compressed */
578 vertexComp = (mdcXyzCompressed_t*) ((picoByte_t*) surface + surface->ofsXyzCompressed);
579 for( j = 0; j < (surface->numVerts * surface->numCompFrames); j++, vertexComp++)
581 vertexComp->ofsVec = _pico_little_long( vertexComp->ofsVec );
584 /* swap base frames */
585 mdcShort = (short *) ((picoByte_t*) surface + surface->ofsFrameBaseFrames);
586 for( j = 0; j < mdc->numFrames; j++, mdcShort++)
588 *mdcShort = _pico_little_short( *mdcShort );
591 /* swap compressed frames */
592 mdcShort = (short *) ((picoByte_t*) surface + surface->ofsFrameCompFrames);
593 for( j = 0; j < mdc->numFrames; j++, mdcShort++)
595 *mdcShort = _pico_little_short( *mdcShort );
598 /* get next surface */
599 surface = (mdcSurface_t*) ((picoByte_t*) surface + surface->ofsEnd);
602 /* -------------------------------------------------
604 ------------------------------------------------- */
606 /* create new pico model */
607 picoModel = PicoNewModel();
608 if( picoModel == NULL )
610 _pico_printf( PICO_ERROR, "Unable to allocate a new model" );
615 PicoSetModelFrameNum( picoModel, frameNum );
616 PicoSetModelNumFrames( picoModel, mdc->numFrames ); /* sea */
617 PicoSetModelName( picoModel, fileName );
618 PicoSetModelFileName( picoModel, fileName );
620 /* mdc surfaces become picomodel surfaces */
621 surface = (mdcSurface_t*) (bb + mdc->ofsSurfaces);
623 /* run through mdc surfaces */
624 for( i = 0; i < mdc->numSurfaces; i++ )
626 /* allocate new pico surface */
627 picoSurface = PicoNewSurface( picoModel );
628 if( picoSurface == NULL )
630 _pico_printf( PICO_ERROR, "Unable to allocate a new model surface" );
631 PicoFreeModel( picoModel ); /* sea */
635 /* mdc model surfaces are all triangle meshes */
636 PicoSetSurfaceType( picoSurface, PICO_TRIANGLES );
638 /* set surface name */
639 PicoSetSurfaceName( picoSurface, surface->name );
641 /* create new pico shader -sea */
642 picoShader = PicoNewShader( picoModel );
643 if( picoShader == NULL )
645 _pico_printf( PICO_ERROR, "Unable to allocate a new model shader" );
646 PicoFreeModel( picoModel );
650 /* detox and set shader name */
651 shader = (mdcShader_t*) ((picoByte_t*) surface + surface->ofsShaders);
652 _pico_setfext( shader->name, "" );
653 _pico_unixify( shader->name );
654 PicoSetShaderName( picoShader, shader->name );
656 /* associate current surface with newly created shader */
657 PicoSetSurfaceShader( picoSurface, picoShader );
660 triangle = (mdcTriangle_t *) ((picoByte_t*) surface + surface->ofsTriangles);
662 for( j = 0; j < surface->numTriangles; j++, triangle++ )
664 PicoSetSurfaceIndex( picoSurface, (j * 3 + 0), (picoIndex_t) triangle->indexes[ 0 ] );
665 PicoSetSurfaceIndex( picoSurface, (j * 3 + 1), (picoIndex_t) triangle->indexes[ 1 ] );
666 PicoSetSurfaceIndex( picoSurface, (j * 3 + 2), (picoIndex_t) triangle->indexes[ 2 ] );
670 texCoord = (mdcTexCoord_t*) ((picoByte_t *) surface + surface->ofsSt);
671 mdcShort = (short *) ((picoByte_t *) surface + surface->ofsXyzNormals) + ((int)*((short *) ((picoByte_t *) surface + surface->ofsFrameBaseFrames) + frameNum) * surface->numVerts * 4);
672 if( surface->numCompFrames > 0 )
674 mdcCompVert = (short *) ((picoByte_t *) surface + surface->ofsFrameCompFrames) + frameNum;
675 if( *mdcCompVert >= 0 )
676 vertexComp = (mdcXyzCompressed_t *) ((picoByte_t *) surface + surface->ofsXyzCompressed) + (*mdcCompVert * surface->numVerts);
678 _pico_set_color( color, 255, 255, 255, 255 );
680 for( j = 0; j < surface->numVerts; j++, texCoord++, mdcShort+=4 )
682 /* set vertex origin */
683 xyz[ 0 ] = MDC_SCALE * mdcShort[ 0 ];
684 xyz[ 1 ] = MDC_SCALE * mdcShort[ 1 ];
685 xyz[ 2 ] = MDC_SCALE * mdcShort[ 2 ];
687 /* add compressed ofsVec */
688 if( surface->numCompFrames > 0 && *mdcCompVert >= 0 )
690 xyz[ 0 ] += ((float) ((vertexComp->ofsVec) & 255) - MDC_MAX_OFS) * MDC_DIST_SCALE;
691 xyz[ 1 ] += ((float) ((vertexComp->ofsVec >> 8) & 255) - MDC_MAX_OFS) * MDC_DIST_SCALE;
692 xyz[ 2 ] += ((float) ((vertexComp->ofsVec >> 16) & 255) - MDC_MAX_OFS) * MDC_DIST_SCALE;
693 PicoSetSurfaceXYZ( picoSurface, j, xyz );
695 normal[ 0 ] = (float) mdcNormals[ (vertexComp->ofsVec >> 24) ][ 0 ];
696 normal[ 1 ] = (float) mdcNormals[ (vertexComp->ofsVec >> 24) ][ 1 ];
697 normal[ 2 ] = (float) mdcNormals[ (vertexComp->ofsVec >> 24) ][ 2 ];
698 PicoSetSurfaceNormal( picoSurface, j, normal );
704 PicoSetSurfaceXYZ( picoSurface, j, xyz );
706 /* decode lat/lng normal to 3 float normal */
707 lat = (float) ((*(mdcShort + 3) >> 8) & 0xff);
708 lng = (float) (*(mdcShort + 3) & 0xff);
709 lat *= PICO_PI / 128;
710 lng *= PICO_PI / 128;
711 normal[ 0 ] = (picoVec_t) cos( lat ) * (picoVec_t) sin( lng );
712 normal[ 1 ] = (picoVec_t) sin( lat ) * (picoVec_t) sin( lng );
713 normal[ 2 ] = (picoVec_t) cos( lng );
714 PicoSetSurfaceNormal( picoSurface, j, normal );
718 st[ 0 ] = texCoord->st[ 0 ];
719 st[ 1 ] = texCoord->st[ 1 ];
720 PicoSetSurfaceST( picoSurface, 0, j, st );
723 PicoSetSurfaceColor( picoSurface, 0, j, color );
726 /* get next surface */
727 surface = (mdcSurface_t*) ((picoByte_t*) surface + surface->ofsEnd);
730 /* return the new pico model */
736 /* pico file format module definition */
737 const picoModule_t picoModuleMDC =
739 "1.3", /* module version string */
740 "RtCW MDC", /* module display name */
741 "Arnout van Meer", /* author's name */
742 "2002 Arnout van Meer", /* module copyright */
744 "mdc", NULL, NULL, NULL /* default extensions to use */
746 _mdc_canload, /* validation routine */
747 _mdc_load, /* load routine */
748 NULL, /* save validation routine */
749 NULL /* save routine */