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 if ( (size_t) bufSize < ( sizeof( *mdc ) * 2 ) ) {
424 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;
435 /* check mdc version */
436 if ( _pico_little_long( mdc->version ) != MDC_VERSION ) {
437 return PICO_PMV_ERROR_VERSION;
440 /* file seems to be a valid mdc */
448 loads a Return to Castle Wolfenstein mdc model file.
451 static picoModel_t *_mdc_load( PM_PARAMS_LOAD ){
453 picoByte_t *bb, *bb0;
455 mdcSurface_t *surface;
457 mdcTexCoord_t *texCoord;
459 mdcTriangle_t *triangle;
461 mdcXyzCompressed_t *vertexComp = NULL;
462 short *mdcShort, *mdcCompVert = NULL;
465 picoModel_t *picoModel;
466 picoSurface_t *picoSurface;
467 picoShader_t *picoShader;
468 picoVec3_t xyz, normal;
473 /* -------------------------------------------------
475 ------------------------------------------------- */
479 bb0 = bb = (picoByte_t*) _pico_alloc( bufSize );
480 memcpy( bb, buffer, bufSize );
483 /* check ident and version */
484 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 ) {
504 _pico_printf( PICO_ERROR, "MDC with 0 frames" );
509 if ( frameNum < 0 || frameNum >= mdc->numFrames ) {
510 _pico_printf( PICO_ERROR, "Invalid or out-of-range MDC frame specified" );
516 frame = (mdcFrame_t*) ( bb + mdc->ofsFrames );
517 for ( i = 0; i < mdc->numFrames; i++, frame++ )
519 frame->radius = _pico_little_float( frame->radius );
520 for ( j = 0; j < 3; j++ )
522 frame->bounds[ 0 ][ j ] = _pico_little_float( frame->bounds[ 0 ][ j ] );
523 frame->bounds[ 1 ][ j ] = _pico_little_float( frame->bounds[ 1 ][ j ] );
524 frame->localOrigin[ j ] = _pico_little_float( frame->localOrigin[ j ] );
529 surface = (mdcSurface_t*) ( bb + mdc->ofsSurfaces );
530 for ( i = 0; i < mdc->numSurfaces; i++ )
532 /* swap surface mdc */
533 surface->flags = _pico_little_long( surface->flags );
534 surface->numBaseFrames = _pico_little_long( surface->numBaseFrames );
535 surface->numCompFrames = _pico_little_long( surface->numCompFrames );
536 surface->numShaders = _pico_little_long( surface->numShaders );
537 surface->numTriangles = _pico_little_long( surface->numTriangles );
538 surface->ofsTriangles = _pico_little_long( surface->ofsTriangles );
539 surface->numVerts = _pico_little_long( surface->numVerts );
540 surface->ofsShaders = _pico_little_long( surface->ofsShaders );
541 surface->ofsSt = _pico_little_long( surface->ofsSt );
542 surface->ofsXyzNormals = _pico_little_long( surface->ofsXyzNormals );
543 surface->ofsXyzCompressed = _pico_little_long( surface->ofsXyzCompressed );
544 surface->ofsFrameBaseFrames = _pico_little_long( surface->ofsFrameBaseFrames );
545 surface->ofsFrameCompFrames = _pico_little_long( surface->ofsFrameCompFrames );
546 surface->ofsEnd = _pico_little_long( surface->ofsEnd );
549 triangle = (mdcTriangle_t*) ( (picoByte_t*) surface + surface->ofsTriangles );
550 for ( j = 0; j < surface->numTriangles; j++, triangle++ )
552 /* sea: swaps fixed */
553 triangle->indexes[ 0 ] = _pico_little_long( triangle->indexes[ 0 ] );
554 triangle->indexes[ 1 ] = _pico_little_long( triangle->indexes[ 1 ] );
555 triangle->indexes[ 2 ] = _pico_little_long( triangle->indexes[ 2 ] );
559 texCoord = (mdcTexCoord_t*) ( (picoByte_t*) surface + surface->ofsSt );
560 for ( j = 0; j < surface->numVerts; j++, texCoord++ )
562 texCoord->st[ 0 ] = _pico_little_float( texCoord->st[ 0 ] );
563 texCoord->st[ 1 ] = _pico_little_float( texCoord->st[ 1 ] );
566 /* swap xyz/normals */
567 vertex = (mdcVertex_t*) ( (picoByte_t*) surface + surface->ofsXyzNormals );
568 for ( j = 0; j < ( surface->numVerts * surface->numBaseFrames ); j++, vertex++ )
570 vertex->xyz[ 0 ] = _pico_little_short( vertex->xyz[ 0 ] );
571 vertex->xyz[ 1 ] = _pico_little_short( vertex->xyz[ 1 ] );
572 vertex->xyz[ 2 ] = _pico_little_short( vertex->xyz[ 2 ] );
573 vertex->normal = _pico_little_short( vertex->normal );
576 /* swap xyz/compressed */
577 vertexComp = (mdcXyzCompressed_t*) ( (picoByte_t*) surface + surface->ofsXyzCompressed );
578 for ( j = 0; j < ( surface->numVerts * surface->numCompFrames ); j++, vertexComp++ )
580 vertexComp->ofsVec = _pico_little_long( vertexComp->ofsVec );
583 /* swap base frames */
584 mdcShort = (short *) ( (picoByte_t*) surface + surface->ofsFrameBaseFrames );
585 for ( j = 0; j < mdc->numFrames; j++, mdcShort++ )
587 *mdcShort = _pico_little_short( *mdcShort );
590 /* swap compressed frames */
591 mdcShort = (short *) ( (picoByte_t*) surface + surface->ofsFrameCompFrames );
592 for ( j = 0; j < mdc->numFrames; j++, mdcShort++ )
594 *mdcShort = _pico_little_short( *mdcShort );
597 /* get next surface */
598 surface = (mdcSurface_t*) ( (picoByte_t*) surface + surface->ofsEnd );
601 /* -------------------------------------------------
603 ------------------------------------------------- */
605 /* create new pico model */
606 picoModel = PicoNewModel();
607 if ( picoModel == NULL ) {
608 _pico_printf( PICO_ERROR, "Unable to allocate a new model" );
614 PicoSetModelFrameNum( picoModel, frameNum );
615 PicoSetModelNumFrames( picoModel, mdc->numFrames ); /* sea */
616 PicoSetModelName( picoModel, fileName );
617 PicoSetModelFileName( picoModel, fileName );
619 /* mdc surfaces become picomodel surfaces */
620 surface = (mdcSurface_t*) ( bb + mdc->ofsSurfaces );
622 /* run through mdc surfaces */
623 for ( i = 0; i < mdc->numSurfaces; i++ )
625 /* allocate new pico surface */
626 picoSurface = PicoNewSurface( picoModel );
627 if ( picoSurface == NULL ) {
628 _pico_printf( PICO_ERROR, "Unable to allocate a new model surface" );
629 PicoFreeModel( picoModel ); /* sea */
634 /* mdc model surfaces are all triangle meshes */
635 PicoSetSurfaceType( picoSurface, PICO_TRIANGLES );
637 /* set surface name */
638 PicoSetSurfaceName( picoSurface, surface->name );
640 /* create new pico shader -sea */
641 picoShader = PicoNewShader( picoModel );
642 if ( picoShader == NULL ) {
643 _pico_printf( PICO_ERROR, "Unable to allocate a new model shader" );
644 PicoFreeModel( picoModel );
649 /* detox and set shader name */
650 shader = (mdcShader_t*) ( (picoByte_t*) surface + surface->ofsShaders );
651 _pico_setfext( shader->name, "" );
652 _pico_unixify( shader->name );
653 PicoSetShaderName( picoShader, shader->name );
655 /* associate current surface with newly created shader */
656 PicoSetSurfaceShader( picoSurface, picoShader );
659 triangle = (mdcTriangle_t *) ( (picoByte_t*) surface + surface->ofsTriangles );
661 for ( j = 0; j < surface->numTriangles; j++, triangle++ )
663 PicoSetSurfaceIndex( picoSurface, ( j * 3 + 0 ), (picoIndex_t) triangle->indexes[ 0 ] );
664 PicoSetSurfaceIndex( picoSurface, ( j * 3 + 1 ), (picoIndex_t) triangle->indexes[ 1 ] );
665 PicoSetSurfaceIndex( picoSurface, ( j * 3 + 2 ), (picoIndex_t) triangle->indexes[ 2 ] );
669 texCoord = (mdcTexCoord_t*) ( (picoByte_t *) surface + surface->ofsSt );
670 mdcShort = (short *) ( (picoByte_t *) surface + surface->ofsXyzNormals ) + ( (int)*( (short *) ( (picoByte_t *) surface + surface->ofsFrameBaseFrames ) + frameNum ) * surface->numVerts * 4 );
671 if ( surface->numCompFrames > 0 ) {
672 mdcCompVert = (short *) ( (picoByte_t *) surface + surface->ofsFrameCompFrames ) + frameNum;
673 if ( *mdcCompVert >= 0 ) {
674 vertexComp = (mdcXyzCompressed_t *) ( (picoByte_t *) surface + surface->ofsXyzCompressed ) + ( *mdcCompVert * surface->numVerts );
677 _pico_set_color( color, 255, 255, 255, 255 );
679 for ( j = 0; j < surface->numVerts; j++, texCoord++, mdcShort += 4 )
681 /* set vertex origin */
682 xyz[ 0 ] = MDC_SCALE * mdcShort[ 0 ];
683 xyz[ 1 ] = MDC_SCALE * mdcShort[ 1 ];
684 xyz[ 2 ] = MDC_SCALE * mdcShort[ 2 ];
686 /* add compressed ofsVec */
687 if ( surface->numCompFrames > 0 && *mdcCompVert >= 0 ) {
688 xyz[ 0 ] += ( (float) ( ( vertexComp->ofsVec ) & 255 ) - MDC_MAX_OFS ) * MDC_DIST_SCALE;
689 xyz[ 1 ] += ( (float) ( ( vertexComp->ofsVec >> 8 ) & 255 ) - MDC_MAX_OFS ) * MDC_DIST_SCALE;
690 xyz[ 2 ] += ( (float) ( ( vertexComp->ofsVec >> 16 ) & 255 ) - MDC_MAX_OFS ) * MDC_DIST_SCALE;
691 PicoSetSurfaceXYZ( picoSurface, j, xyz );
693 normal[ 0 ] = (float) mdcNormals[ ( vertexComp->ofsVec >> 24 ) ][ 0 ];
694 normal[ 1 ] = (float) mdcNormals[ ( vertexComp->ofsVec >> 24 ) ][ 1 ];
695 normal[ 2 ] = (float) mdcNormals[ ( vertexComp->ofsVec >> 24 ) ][ 2 ];
696 PicoSetSurfaceNormal( picoSurface, j, normal );
702 PicoSetSurfaceXYZ( picoSurface, j, xyz );
704 /* decode lat/lng normal to 3 float normal */
705 lat = (float) ( ( *( mdcShort + 3 ) >> 8 ) & 0xff );
706 lng = (float) ( *( mdcShort + 3 ) & 0xff );
707 lat *= PICO_PI / 128;
708 lng *= PICO_PI / 128;
709 normal[ 0 ] = (picoVec_t) cos( lat ) * (picoVec_t) sin( lng );
710 normal[ 1 ] = (picoVec_t) sin( lat ) * (picoVec_t) sin( lng );
711 normal[ 2 ] = (picoVec_t) cos( lng );
712 PicoSetSurfaceNormal( picoSurface, j, normal );
716 st[ 0 ] = texCoord->st[ 0 ];
717 st[ 1 ] = texCoord->st[ 1 ];
718 PicoSetSurfaceST( picoSurface, 0, j, st );
721 PicoSetSurfaceColor( picoSurface, 0, j, color );
724 /* get next surface */
725 surface = (mdcSurface_t*) ( (picoByte_t*) surface + surface->ofsEnd );
728 /* return the new pico model */
735 /* pico file format module definition */
736 const picoModule_t picoModuleMDC =
738 "1.3", /* module version string */
739 "RtCW MDC", /* module display name */
740 "Arnout van Meer", /* author's name */
741 "2002 Arnout van Meer", /* module copyright */
743 "mdc", NULL, NULL, NULL /* default extensions to use */
745 _mdc_canload, /* validation routine */
746 _mdc_load, /* load routine */
747 NULL, /* save validation routine */
748 NULL /* save routine */