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 ----------------------------------------------------------------------------- */
36 #include "picointernal.h"
38 /* mdc model format */
39 const char *MDC_MAGIC = "IDPC";
40 const int MDC_VERSION = 2;
42 /* mdc vertex scale */
43 const float MDC_SCALE = ( 1.0f / 64.0f );
44 const float MDC_MAX_OFS = 127.0f;
45 const float MDC_DIST_SCALE = 0.05f;
47 /* mdc decoding normal table */
48 double mdcNormals[ 256 ][ 3 ] =
50 { 1.000000, 0.000000, 0.000000 },
51 { 0.980785, 0.195090, 0.000000 },
52 { 0.923880, 0.382683, 0.000000 },
53 { 0.831470, 0.555570, 0.000000 },
54 { 0.707107, 0.707107, 0.000000 },
55 { 0.555570, 0.831470, 0.000000 },
56 { 0.382683, 0.923880, 0.000000 },
57 { 0.195090, 0.980785, 0.000000 },
58 { -0.000000, 1.000000, 0.000000 },
59 { -0.195090, 0.980785, 0.000000 },
60 { -0.382683, 0.923880, 0.000000 },
61 { -0.555570, 0.831470, 0.000000 },
62 { -0.707107, 0.707107, 0.000000 },
63 { -0.831470, 0.555570, 0.000000 },
64 { -0.923880, 0.382683, 0.000000 },
65 { -0.980785, 0.195090, 0.000000 },
66 { -1.000000, -0.000000, 0.000000 },
67 { -0.980785, -0.195090, 0.000000 },
68 { -0.923880, -0.382683, 0.000000 },
69 { -0.831470, -0.555570, 0.000000 },
70 { -0.707107, -0.707107, 0.000000 },
71 { -0.555570, -0.831469, 0.000000 },
72 { -0.382684, -0.923880, 0.000000 },
73 { -0.195090, -0.980785, 0.000000 },
74 { 0.000000, -1.000000, 0.000000 },
75 { 0.195090, -0.980785, 0.000000 },
76 { 0.382684, -0.923879, 0.000000 },
77 { 0.555570, -0.831470, 0.000000 },
78 { 0.707107, -0.707107, 0.000000 },
79 { 0.831470, -0.555570, 0.000000 },
80 { 0.923880, -0.382683, 0.000000 },
81 { 0.980785, -0.195090, 0.000000 },
82 { 0.980785, 0.000000, -0.195090 },
83 { 0.956195, 0.218245, -0.195090 },
84 { 0.883657, 0.425547, -0.195090 },
85 { 0.766809, 0.611510, -0.195090 },
86 { 0.611510, 0.766809, -0.195090 },
87 { 0.425547, 0.883657, -0.195090 },
88 { 0.218245, 0.956195, -0.195090 },
89 { -0.000000, 0.980785, -0.195090 },
90 { -0.218245, 0.956195, -0.195090 },
91 { -0.425547, 0.883657, -0.195090 },
92 { -0.611510, 0.766809, -0.195090 },
93 { -0.766809, 0.611510, -0.195090 },
94 { -0.883657, 0.425547, -0.195090 },
95 { -0.956195, 0.218245, -0.195090 },
96 { -0.980785, -0.000000, -0.195090 },
97 { -0.956195, -0.218245, -0.195090 },
98 { -0.883657, -0.425547, -0.195090 },
99 { -0.766809, -0.611510, -0.195090 },
100 { -0.611510, -0.766809, -0.195090 },
101 { -0.425547, -0.883657, -0.195090 },
102 { -0.218245, -0.956195, -0.195090 },
103 { 0.000000, -0.980785, -0.195090 },
104 { 0.218245, -0.956195, -0.195090 },
105 { 0.425547, -0.883657, -0.195090 },
106 { 0.611510, -0.766809, -0.195090 },
107 { 0.766809, -0.611510, -0.195090 },
108 { 0.883657, -0.425547, -0.195090 },
109 { 0.956195, -0.218245, -0.195090 },
110 { 0.923880, 0.000000, -0.382683 },
111 { 0.892399, 0.239118, -0.382683 },
112 { 0.800103, 0.461940, -0.382683 },
113 { 0.653281, 0.653281, -0.382683 },
114 { 0.461940, 0.800103, -0.382683 },
115 { 0.239118, 0.892399, -0.382683 },
116 { -0.000000, 0.923880, -0.382683 },
117 { -0.239118, 0.892399, -0.382683 },
118 { -0.461940, 0.800103, -0.382683 },
119 { -0.653281, 0.653281, -0.382683 },
120 { -0.800103, 0.461940, -0.382683 },
121 { -0.892399, 0.239118, -0.382683 },
122 { -0.923880, -0.000000, -0.382683 },
123 { -0.892399, -0.239118, -0.382683 },
124 { -0.800103, -0.461940, -0.382683 },
125 { -0.653282, -0.653281, -0.382683 },
126 { -0.461940, -0.800103, -0.382683 },
127 { -0.239118, -0.892399, -0.382683 },
128 { 0.000000, -0.923880, -0.382683 },
129 { 0.239118, -0.892399, -0.382683 },
130 { 0.461940, -0.800103, -0.382683 },
131 { 0.653281, -0.653282, -0.382683 },
132 { 0.800103, -0.461940, -0.382683 },
133 { 0.892399, -0.239117, -0.382683 },
134 { 0.831470, 0.000000, -0.555570 },
135 { 0.790775, 0.256938, -0.555570 },
136 { 0.672673, 0.488726, -0.555570 },
137 { 0.488726, 0.672673, -0.555570 },
138 { 0.256938, 0.790775, -0.555570 },
139 { -0.000000, 0.831470, -0.555570 },
140 { -0.256938, 0.790775, -0.555570 },
141 { -0.488726, 0.672673, -0.555570 },
142 { -0.672673, 0.488726, -0.555570 },
143 { -0.790775, 0.256938, -0.555570 },
144 { -0.831470, -0.000000, -0.555570 },
145 { -0.790775, -0.256938, -0.555570 },
146 { -0.672673, -0.488726, -0.555570 },
147 { -0.488725, -0.672673, -0.555570 },
148 { -0.256938, -0.790775, -0.555570 },
149 { 0.000000, -0.831470, -0.555570 },
150 { 0.256938, -0.790775, -0.555570 },
151 { 0.488725, -0.672673, -0.555570 },
152 { 0.672673, -0.488726, -0.555570 },
153 { 0.790775, -0.256938, -0.555570 },
154 { 0.707107, 0.000000, -0.707107 },
155 { 0.653281, 0.270598, -0.707107 },
156 { 0.500000, 0.500000, -0.707107 },
157 { 0.270598, 0.653281, -0.707107 },
158 { -0.000000, 0.707107, -0.707107 },
159 { -0.270598, 0.653282, -0.707107 },
160 { -0.500000, 0.500000, -0.707107 },
161 { -0.653281, 0.270598, -0.707107 },
162 { -0.707107, -0.000000, -0.707107 },
163 { -0.653281, -0.270598, -0.707107 },
164 { -0.500000, -0.500000, -0.707107 },
165 { -0.270598, -0.653281, -0.707107 },
166 { 0.000000, -0.707107, -0.707107 },
167 { 0.270598, -0.653281, -0.707107 },
168 { 0.500000, -0.500000, -0.707107 },
169 { 0.653282, -0.270598, -0.707107 },
170 { 0.555570, 0.000000, -0.831470 },
171 { 0.481138, 0.277785, -0.831470 },
172 { 0.277785, 0.481138, -0.831470 },
173 { -0.000000, 0.555570, -0.831470 },
174 { -0.277785, 0.481138, -0.831470 },
175 { -0.481138, 0.277785, -0.831470 },
176 { -0.555570, -0.000000, -0.831470 },
177 { -0.481138, -0.277785, -0.831470 },
178 { -0.277785, -0.481138, -0.831470 },
179 { 0.000000, -0.555570, -0.831470 },
180 { 0.277785, -0.481138, -0.831470 },
181 { 0.481138, -0.277785, -0.831470 },
182 { 0.382683, 0.000000, -0.923880 },
183 { 0.270598, 0.270598, -0.923880 },
184 { -0.000000, 0.382683, -0.923880 },
185 { -0.270598, 0.270598, -0.923880 },
186 { -0.382683, -0.000000, -0.923880 },
187 { -0.270598, -0.270598, -0.923880 },
188 { 0.000000, -0.382683, -0.923880 },
189 { 0.270598, -0.270598, -0.923880 },
190 { 0.195090, 0.000000, -0.980785 },
191 { -0.000000, 0.195090, -0.980785 },
192 { -0.195090, -0.000000, -0.980785 },
193 { 0.000000, -0.195090, -0.980785 },
194 { 0.980785, 0.000000, 0.195090 },
195 { 0.956195, 0.218245, 0.195090 },
196 { 0.883657, 0.425547, 0.195090 },
197 { 0.766809, 0.611510, 0.195090 },
198 { 0.611510, 0.766809, 0.195090 },
199 { 0.425547, 0.883657, 0.195090 },
200 { 0.218245, 0.956195, 0.195090 },
201 { -0.000000, 0.980785, 0.195090 },
202 { -0.218245, 0.956195, 0.195090 },
203 { -0.425547, 0.883657, 0.195090 },
204 { -0.611510, 0.766809, 0.195090 },
205 { -0.766809, 0.611510, 0.195090 },
206 { -0.883657, 0.425547, 0.195090 },
207 { -0.956195, 0.218245, 0.195090 },
208 { -0.980785, -0.000000, 0.195090 },
209 { -0.956195, -0.218245, 0.195090 },
210 { -0.883657, -0.425547, 0.195090 },
211 { -0.766809, -0.611510, 0.195090 },
212 { -0.611510, -0.766809, 0.195090 },
213 { -0.425547, -0.883657, 0.195090 },
214 { -0.218245, -0.956195, 0.195090 },
215 { 0.000000, -0.980785, 0.195090 },
216 { 0.218245, -0.956195, 0.195090 },
217 { 0.425547, -0.883657, 0.195090 },
218 { 0.611510, -0.766809, 0.195090 },
219 { 0.766809, -0.611510, 0.195090 },
220 { 0.883657, -0.425547, 0.195090 },
221 { 0.956195, -0.218245, 0.195090 },
222 { 0.923880, 0.000000, 0.382683 },
223 { 0.892399, 0.239118, 0.382683 },
224 { 0.800103, 0.461940, 0.382683 },
225 { 0.653281, 0.653281, 0.382683 },
226 { 0.461940, 0.800103, 0.382683 },
227 { 0.239118, 0.892399, 0.382683 },
228 { -0.000000, 0.923880, 0.382683 },
229 { -0.239118, 0.892399, 0.382683 },
230 { -0.461940, 0.800103, 0.382683 },
231 { -0.653281, 0.653281, 0.382683 },
232 { -0.800103, 0.461940, 0.382683 },
233 { -0.892399, 0.239118, 0.382683 },
234 { -0.923880, -0.000000, 0.382683 },
235 { -0.892399, -0.239118, 0.382683 },
236 { -0.800103, -0.461940, 0.382683 },
237 { -0.653282, -0.653281, 0.382683 },
238 { -0.461940, -0.800103, 0.382683 },
239 { -0.239118, -0.892399, 0.382683 },
240 { 0.000000, -0.923880, 0.382683 },
241 { 0.239118, -0.892399, 0.382683 },
242 { 0.461940, -0.800103, 0.382683 },
243 { 0.653281, -0.653282, 0.382683 },
244 { 0.800103, -0.461940, 0.382683 },
245 { 0.892399, -0.239117, 0.382683 },
246 { 0.831470, 0.000000, 0.555570 },
247 { 0.790775, 0.256938, 0.555570 },
248 { 0.672673, 0.488726, 0.555570 },
249 { 0.488726, 0.672673, 0.555570 },
250 { 0.256938, 0.790775, 0.555570 },
251 { -0.000000, 0.831470, 0.555570 },
252 { -0.256938, 0.790775, 0.555570 },
253 { -0.488726, 0.672673, 0.555570 },
254 { -0.672673, 0.488726, 0.555570 },
255 { -0.790775, 0.256938, 0.555570 },
256 { -0.831470, -0.000000, 0.555570 },
257 { -0.790775, -0.256938, 0.555570 },
258 { -0.672673, -0.488726, 0.555570 },
259 { -0.488725, -0.672673, 0.555570 },
260 { -0.256938, -0.790775, 0.555570 },
261 { 0.000000, -0.831470, 0.555570 },
262 { 0.256938, -0.790775, 0.555570 },
263 { 0.488725, -0.672673, 0.555570 },
264 { 0.672673, -0.488726, 0.555570 },
265 { 0.790775, -0.256938, 0.555570 },
266 { 0.707107, 0.000000, 0.707107 },
267 { 0.653281, 0.270598, 0.707107 },
268 { 0.500000, 0.500000, 0.707107 },
269 { 0.270598, 0.653281, 0.707107 },
270 { -0.000000, 0.707107, 0.707107 },
271 { -0.270598, 0.653282, 0.707107 },
272 { -0.500000, 0.500000, 0.707107 },
273 { -0.653281, 0.270598, 0.707107 },
274 { -0.707107, -0.000000, 0.707107 },
275 { -0.653281, -0.270598, 0.707107 },
276 { -0.500000, -0.500000, 0.707107 },
277 { -0.270598, -0.653281, 0.707107 },
278 { 0.000000, -0.707107, 0.707107 },
279 { 0.270598, -0.653281, 0.707107 },
280 { 0.500000, -0.500000, 0.707107 },
281 { 0.653282, -0.270598, 0.707107 },
282 { 0.555570, 0.000000, 0.831470 },
283 { 0.481138, 0.277785, 0.831470 },
284 { 0.277785, 0.481138, 0.831470 },
285 { -0.000000, 0.555570, 0.831470 },
286 { -0.277785, 0.481138, 0.831470 },
287 { -0.481138, 0.277785, 0.831470 },
288 { -0.555570, -0.000000, 0.831470 },
289 { -0.481138, -0.277785, 0.831470 },
290 { -0.277785, -0.481138, 0.831470 },
291 { 0.000000, -0.555570, 0.831470 },
292 { 0.277785, -0.481138, 0.831470 },
293 { 0.481138, -0.277785, 0.831470 },
294 { 0.382683, 0.000000, 0.923880 },
295 { 0.270598, 0.270598, 0.923880 },
296 { -0.000000, 0.382683, 0.923880 },
297 { -0.270598, 0.270598, 0.923880 },
298 { -0.382683, -0.000000, 0.923880 },
299 { -0.270598, -0.270598, 0.923880 },
300 { 0.000000, -0.382683, 0.923880 },
301 { 0.270598, -0.270598, 0.923880 },
302 { 0.195090, 0.000000, 0.980785 },
303 { -0.000000, 0.195090, 0.980785 },
304 { -0.195090, -0.000000, 0.980785 },
305 { 0.000000, -0.195090, 0.980785 }
308 /* mdc model frame information */
309 typedef struct mdcFrame_s
311 float bounds[ 2 ][ 3 ];
312 float localOrigin[ 3 ];
318 /* mdc model tag information */
319 typedef struct mdcTag_s
326 /* mdc surface mdc (one object mesh) */
327 typedef struct mdcSurface_s
330 char name[ 64 ]; /* polyset name */
332 int numCompFrames; /* all surfaces in a model should have the same */
333 int numBaseFrames; /* ditto */
334 int numShaders; /* all model surfaces should have the same */
338 int ofsShaders; /* offset from start of mdcSurface_t */
339 int ofsSt; /* texture coords are common for all frames */
340 int ofsXyzNormals; /* numVerts * numBaseFrames */
341 int ofsXyzCompressed; /* numVerts * numCompFrames */
343 int ofsFrameBaseFrames; /* numFrames */
344 int ofsFrameCompFrames; /* numFrames */
345 int ofsEnd; /* next surface follows */
349 typedef struct mdcShader_s
352 int shaderIndex; /* for ingame use */
356 typedef struct mdcTriangle_s
362 typedef struct mdcTexCoord_s
368 typedef struct mdcVertex_s
375 typedef struct mdcXyzCompressed_s
377 unsigned int ofsVec; /* offset direction from the last base frame */
382 /* mdc model file mdc structure */
385 char magic[ 4 ]; /* MDC_MAGIC */
387 char name[ 64 ]; /* model name */
392 int numSkins; /* number of skins for the mesh */
393 int ofsFrames; /* offset for first frame */
394 int ofsTagNames; /* numTags */
395 int ofsTags; /* numFrames * numTags */
396 int ofsSurfaces; /* first surface, others follow */
397 int ofsEnd; /* end of file */
406 validates a Return to Castle Wolfenstein model file. btw, i use the
407 preceding underscore cause it's a static func referenced
408 by one structure only.
411 static int _mdc_canload( PM_PARAMS_CANLOAD ){
416 if ( (size_t) bufSize < ( sizeof( *mdc ) * 2 ) ) {
417 return PICO_PMV_ERROR_SIZE;
421 mdc = (const mdc_t*) buffer;
423 /* check mdc magic */
424 if ( *( (const int*) mdc->magic ) != *( (const int*) MDC_MAGIC ) ) {
425 return PICO_PMV_ERROR_IDENT;
428 /* check mdc version */
429 if ( _pico_little_long( mdc->version ) != MDC_VERSION ) {
430 return PICO_PMV_ERROR_VERSION;
433 /* file seems to be a valid mdc */
441 loads a Return to Castle Wolfenstein mdc model file.
444 static picoModel_t *_mdc_load( PM_PARAMS_LOAD ){
446 picoByte_t *bb, *bb0;
448 mdcSurface_t *surface;
450 mdcTexCoord_t *texCoord;
452 mdcTriangle_t *triangle;
454 mdcXyzCompressed_t *vertexComp = NULL;
455 short *mdcShort, *mdcCompVert = NULL;
458 picoModel_t *picoModel;
459 picoSurface_t *picoSurface;
460 picoShader_t *picoShader;
461 picoVec3_t xyz, normal;
466 /* -------------------------------------------------
468 ------------------------------------------------- */
472 bb0 = bb = (picoByte_t*) _pico_alloc( bufSize );
473 memcpy( bb, buffer, bufSize );
476 /* check ident and version */
477 if ( *( (int*) mdc->magic ) != *( (int*) MDC_MAGIC ) || _pico_little_long( mdc->version ) != MDC_VERSION ) {
478 /* not an mdc file (todo: set error) */
484 mdc->version = _pico_little_long( mdc->version );
485 mdc->numFrames = _pico_little_long( mdc->numFrames );
486 mdc->numTags = _pico_little_long( mdc->numTags );
487 mdc->numSurfaces = _pico_little_long( mdc->numSurfaces );
488 mdc->numSkins = _pico_little_long( mdc->numSkins );
489 mdc->ofsFrames = _pico_little_long( mdc->ofsFrames );
490 mdc->ofsTags = _pico_little_long( mdc->ofsTags );
491 mdc->ofsTagNames = _pico_little_long( mdc->ofsTagNames );
492 mdc->ofsSurfaces = _pico_little_long( mdc->ofsSurfaces );
493 mdc->ofsEnd = _pico_little_long( mdc->ofsEnd );
496 if ( mdc->numFrames < 1 ) {
497 _pico_printf( PICO_ERROR, "MDC with 0 frames" );
502 if ( frameNum < 0 || frameNum >= mdc->numFrames ) {
503 _pico_printf( PICO_ERROR, "Invalid or out-of-range MDC frame specified" );
509 frame = (mdcFrame_t*) ( bb + mdc->ofsFrames );
510 for ( i = 0; i < mdc->numFrames; i++, frame++ )
512 frame->radius = _pico_little_float( frame->radius );
513 for ( j = 0; j < 3; j++ )
515 frame->bounds[ 0 ][ j ] = _pico_little_float( frame->bounds[ 0 ][ j ] );
516 frame->bounds[ 1 ][ j ] = _pico_little_float( frame->bounds[ 1 ][ j ] );
517 frame->localOrigin[ j ] = _pico_little_float( frame->localOrigin[ j ] );
522 surface = (mdcSurface_t*) ( bb + mdc->ofsSurfaces );
523 for ( i = 0; i < mdc->numSurfaces; i++ )
525 /* swap surface mdc */
526 surface->flags = _pico_little_long( surface->flags );
527 surface->numBaseFrames = _pico_little_long( surface->numBaseFrames );
528 surface->numCompFrames = _pico_little_long( surface->numCompFrames );
529 surface->numShaders = _pico_little_long( surface->numShaders );
530 surface->numTriangles = _pico_little_long( surface->numTriangles );
531 surface->ofsTriangles = _pico_little_long( surface->ofsTriangles );
532 surface->numVerts = _pico_little_long( surface->numVerts );
533 surface->ofsShaders = _pico_little_long( surface->ofsShaders );
534 surface->ofsSt = _pico_little_long( surface->ofsSt );
535 surface->ofsXyzNormals = _pico_little_long( surface->ofsXyzNormals );
536 surface->ofsXyzCompressed = _pico_little_long( surface->ofsXyzCompressed );
537 surface->ofsFrameBaseFrames = _pico_little_long( surface->ofsFrameBaseFrames );
538 surface->ofsFrameCompFrames = _pico_little_long( surface->ofsFrameCompFrames );
539 surface->ofsEnd = _pico_little_long( surface->ofsEnd );
542 triangle = (mdcTriangle_t*) ( (picoByte_t*) surface + surface->ofsTriangles );
543 for ( j = 0; j < surface->numTriangles; j++, triangle++ )
545 /* sea: swaps fixed */
546 triangle->indexes[ 0 ] = _pico_little_long( triangle->indexes[ 0 ] );
547 triangle->indexes[ 1 ] = _pico_little_long( triangle->indexes[ 1 ] );
548 triangle->indexes[ 2 ] = _pico_little_long( triangle->indexes[ 2 ] );
552 texCoord = (mdcTexCoord_t*) ( (picoByte_t*) surface + surface->ofsSt );
553 for ( j = 0; j < surface->numVerts; j++, texCoord++ )
555 texCoord->st[ 0 ] = _pico_little_float( texCoord->st[ 0 ] );
556 texCoord->st[ 1 ] = _pico_little_float( texCoord->st[ 1 ] );
559 /* swap xyz/normals */
560 vertex = (mdcVertex_t*) ( (picoByte_t*) surface + surface->ofsXyzNormals );
561 for ( j = 0; j < ( surface->numVerts * surface->numBaseFrames ); j++, vertex++ )
563 vertex->xyz[ 0 ] = _pico_little_short( vertex->xyz[ 0 ] );
564 vertex->xyz[ 1 ] = _pico_little_short( vertex->xyz[ 1 ] );
565 vertex->xyz[ 2 ] = _pico_little_short( vertex->xyz[ 2 ] );
566 vertex->normal = _pico_little_short( vertex->normal );
569 /* swap xyz/compressed */
570 vertexComp = (mdcXyzCompressed_t*) ( (picoByte_t*) surface + surface->ofsXyzCompressed );
571 for ( j = 0; j < ( surface->numVerts * surface->numCompFrames ); j++, vertexComp++ )
573 vertexComp->ofsVec = _pico_little_long( vertexComp->ofsVec );
576 /* swap base frames */
577 mdcShort = (short *) ( (picoByte_t*) surface + surface->ofsFrameBaseFrames );
578 for ( j = 0; j < mdc->numFrames; j++, mdcShort++ )
580 *mdcShort = _pico_little_short( *mdcShort );
583 /* swap compressed frames */
584 mdcShort = (short *) ( (picoByte_t*) surface + surface->ofsFrameCompFrames );
585 for ( j = 0; j < mdc->numFrames; j++, mdcShort++ )
587 *mdcShort = _pico_little_short( *mdcShort );
590 /* get next surface */
591 surface = (mdcSurface_t*) ( (picoByte_t*) surface + surface->ofsEnd );
594 /* -------------------------------------------------
596 ------------------------------------------------- */
598 /* create new pico model */
599 picoModel = PicoNewModel();
600 if ( picoModel == NULL ) {
601 _pico_printf( PICO_ERROR, "Unable to allocate a new model" );
607 PicoSetModelFrameNum( picoModel, frameNum );
608 PicoSetModelNumFrames( picoModel, mdc->numFrames ); /* sea */
609 PicoSetModelName( picoModel, fileName );
610 PicoSetModelFileName( picoModel, fileName );
612 /* mdc surfaces become picomodel surfaces */
613 surface = (mdcSurface_t*) ( bb + mdc->ofsSurfaces );
615 /* run through mdc surfaces */
616 for ( i = 0; i < mdc->numSurfaces; i++ )
618 /* allocate new pico surface */
619 picoSurface = PicoNewSurface( picoModel );
620 if ( picoSurface == NULL ) {
621 _pico_printf( PICO_ERROR, "Unable to allocate a new model surface" );
622 PicoFreeModel( picoModel ); /* sea */
627 /* mdc model surfaces are all triangle meshes */
628 PicoSetSurfaceType( picoSurface, PICO_TRIANGLES );
630 /* set surface name */
631 PicoSetSurfaceName( picoSurface, surface->name );
633 /* create new pico shader -sea */
634 picoShader = PicoNewShader( picoModel );
635 if ( picoShader == NULL ) {
636 _pico_printf( PICO_ERROR, "Unable to allocate a new model shader" );
637 PicoFreeModel( picoModel );
642 /* detox and set shader name */
643 shader = (mdcShader_t*) ( (picoByte_t*) surface + surface->ofsShaders );
644 _pico_setfext( shader->name, "" );
645 _pico_unixify( shader->name );
646 PicoSetShaderName( picoShader, shader->name );
648 /* associate current surface with newly created shader */
649 PicoSetSurfaceShader( picoSurface, picoShader );
652 triangle = (mdcTriangle_t *) ( (picoByte_t*) surface + surface->ofsTriangles );
654 for ( j = 0; j < surface->numTriangles; j++, triangle++ )
656 PicoSetSurfaceIndex( picoSurface, ( j * 3 + 0 ), (picoIndex_t) triangle->indexes[ 0 ] );
657 PicoSetSurfaceIndex( picoSurface, ( j * 3 + 1 ), (picoIndex_t) triangle->indexes[ 1 ] );
658 PicoSetSurfaceIndex( picoSurface, ( j * 3 + 2 ), (picoIndex_t) triangle->indexes[ 2 ] );
662 texCoord = (mdcTexCoord_t*) ( (picoByte_t *) surface + surface->ofsSt );
663 mdcShort = (short *) ( (picoByte_t *) surface + surface->ofsXyzNormals ) + ( (int)*( (short *) ( (picoByte_t *) surface + surface->ofsFrameBaseFrames ) + frameNum ) * surface->numVerts * 4 );
664 if ( surface->numCompFrames > 0 ) {
665 mdcCompVert = (short *) ( (picoByte_t *) surface + surface->ofsFrameCompFrames ) + frameNum;
666 if ( *mdcCompVert >= 0 ) {
667 vertexComp = (mdcXyzCompressed_t *) ( (picoByte_t *) surface + surface->ofsXyzCompressed ) + ( *mdcCompVert * surface->numVerts );
670 _pico_set_color( color, 255, 255, 255, 255 );
672 for ( j = 0; j < surface->numVerts; j++, texCoord++, mdcShort += 4 )
674 /* set vertex origin */
675 xyz[ 0 ] = MDC_SCALE * mdcShort[ 0 ];
676 xyz[ 1 ] = MDC_SCALE * mdcShort[ 1 ];
677 xyz[ 2 ] = MDC_SCALE * mdcShort[ 2 ];
679 /* add compressed ofsVec */
680 if ( surface->numCompFrames > 0 && *mdcCompVert >= 0 ) {
681 xyz[ 0 ] += ( (float) ( ( vertexComp->ofsVec ) & 255 ) - MDC_MAX_OFS ) * MDC_DIST_SCALE;
682 xyz[ 1 ] += ( (float) ( ( vertexComp->ofsVec >> 8 ) & 255 ) - MDC_MAX_OFS ) * MDC_DIST_SCALE;
683 xyz[ 2 ] += ( (float) ( ( vertexComp->ofsVec >> 16 ) & 255 ) - MDC_MAX_OFS ) * MDC_DIST_SCALE;
684 PicoSetSurfaceXYZ( picoSurface, j, xyz );
686 normal[ 0 ] = (float) mdcNormals[ ( vertexComp->ofsVec >> 24 ) ][ 0 ];
687 normal[ 1 ] = (float) mdcNormals[ ( vertexComp->ofsVec >> 24 ) ][ 1 ];
688 normal[ 2 ] = (float) mdcNormals[ ( vertexComp->ofsVec >> 24 ) ][ 2 ];
689 PicoSetSurfaceNormal( picoSurface, j, normal );
695 PicoSetSurfaceXYZ( picoSurface, j, xyz );
697 /* decode lat/lng normal to 3 float normal */
698 lat = (float) ( ( *( mdcShort + 3 ) >> 8 ) & 0xff );
699 lng = (float) ( *( mdcShort + 3 ) & 0xff );
700 lat *= PICO_PI / 128;
701 lng *= PICO_PI / 128;
702 normal[ 0 ] = (picoVec_t) cos( lat ) * (picoVec_t) sin( lng );
703 normal[ 1 ] = (picoVec_t) sin( lat ) * (picoVec_t) sin( lng );
704 normal[ 2 ] = (picoVec_t) cos( lng );
705 PicoSetSurfaceNormal( picoSurface, j, normal );
709 st[ 0 ] = texCoord->st[ 0 ];
710 st[ 1 ] = texCoord->st[ 1 ];
711 PicoSetSurfaceST( picoSurface, 0, j, st );
714 PicoSetSurfaceColor( picoSurface, 0, j, color );
717 /* get next surface */
718 surface = (mdcSurface_t*) ( (picoByte_t*) surface + surface->ofsEnd );
721 /* return the new pico model */
728 /* pico file format module definition */
729 const picoModule_t picoModuleMDC =
731 "1.3", /* module version string */
732 "RtCW MDC", /* module display name */
733 "Arnout van Meer", /* author's name */
734 "2002 Arnout van Meer", /* module copyright */
736 "mdc", NULL, NULL, NULL /* default extensions to use */
738 _mdc_canload, /* validation routine */
739 _mdc_load, /* load routine */
740 NULL, /* save validation routine */
741 NULL /* save routine */