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;
465 /* -------------------------------------------------
467 ------------------------------------------------- */
471 bb0 = bb = (picoByte_t*) _pico_alloc( bufSize );
472 memcpy( bb, buffer, bufSize );
475 /* check ident and version */
476 if ( *( (int*) mdc->magic ) != *( (int*) MDC_MAGIC ) || _pico_little_long( mdc->version ) != MDC_VERSION ) {
477 /* not an mdc file (todo: set error) */
483 mdc->version = _pico_little_long( mdc->version );
484 mdc->numFrames = _pico_little_long( mdc->numFrames );
485 mdc->numTags = _pico_little_long( mdc->numTags );
486 mdc->numSurfaces = _pico_little_long( mdc->numSurfaces );
487 mdc->numSkins = _pico_little_long( mdc->numSkins );
488 mdc->ofsFrames = _pico_little_long( mdc->ofsFrames );
489 mdc->ofsTags = _pico_little_long( mdc->ofsTags );
490 mdc->ofsTagNames = _pico_little_long( mdc->ofsTagNames );
491 mdc->ofsSurfaces = _pico_little_long( mdc->ofsSurfaces );
492 mdc->ofsEnd = _pico_little_long( mdc->ofsEnd );
495 if ( mdc->numFrames < 1 ) {
496 _pico_printf( PICO_ERROR, "MDC with 0 frames" );
501 if ( frameNum < 0 || frameNum >= mdc->numFrames ) {
502 _pico_printf( PICO_ERROR, "Invalid or out-of-range MDC frame specified" );
508 frame = (mdcFrame_t*) ( bb + mdc->ofsFrames );
509 for ( i = 0; i < mdc->numFrames; i++, frame++ )
511 frame->radius = _pico_little_float( frame->radius );
512 for ( j = 0; j < 3; j++ )
514 frame->bounds[ 0 ][ j ] = _pico_little_float( frame->bounds[ 0 ][ j ] );
515 frame->bounds[ 1 ][ j ] = _pico_little_float( frame->bounds[ 1 ][ j ] );
516 frame->localOrigin[ j ] = _pico_little_float( frame->localOrigin[ j ] );
521 surface = (mdcSurface_t*) ( bb + mdc->ofsSurfaces );
522 for ( i = 0; i < mdc->numSurfaces; i++ )
524 /* swap surface mdc */
525 surface->flags = _pico_little_long( surface->flags );
526 surface->numBaseFrames = _pico_little_long( surface->numBaseFrames );
527 surface->numCompFrames = _pico_little_long( surface->numCompFrames );
528 surface->numShaders = _pico_little_long( surface->numShaders );
529 surface->numTriangles = _pico_little_long( surface->numTriangles );
530 surface->ofsTriangles = _pico_little_long( surface->ofsTriangles );
531 surface->numVerts = _pico_little_long( surface->numVerts );
532 surface->ofsShaders = _pico_little_long( surface->ofsShaders );
533 surface->ofsSt = _pico_little_long( surface->ofsSt );
534 surface->ofsXyzNormals = _pico_little_long( surface->ofsXyzNormals );
535 surface->ofsXyzCompressed = _pico_little_long( surface->ofsXyzCompressed );
536 surface->ofsFrameBaseFrames = _pico_little_long( surface->ofsFrameBaseFrames );
537 surface->ofsFrameCompFrames = _pico_little_long( surface->ofsFrameCompFrames );
538 surface->ofsEnd = _pico_little_long( surface->ofsEnd );
541 triangle = (mdcTriangle_t*) ( (picoByte_t*) surface + surface->ofsTriangles );
542 for ( j = 0; j < surface->numTriangles; j++, triangle++ )
544 /* sea: swaps fixed */
545 triangle->indexes[ 0 ] = _pico_little_long( triangle->indexes[ 0 ] );
546 triangle->indexes[ 1 ] = _pico_little_long( triangle->indexes[ 1 ] );
547 triangle->indexes[ 2 ] = _pico_little_long( triangle->indexes[ 2 ] );
551 texCoord = (mdcTexCoord_t*) ( (picoByte_t*) surface + surface->ofsSt );
552 for ( j = 0; j < surface->numVerts; j++, texCoord++ )
554 texCoord->st[ 0 ] = _pico_little_float( texCoord->st[ 0 ] );
555 texCoord->st[ 1 ] = _pico_little_float( texCoord->st[ 1 ] );
558 /* swap xyz/normals */
559 vertex = (mdcVertex_t*) ( (picoByte_t*) surface + surface->ofsXyzNormals );
560 for ( j = 0; j < ( surface->numVerts * surface->numBaseFrames ); j++, vertex++ )
562 vertex->xyz[ 0 ] = _pico_little_short( vertex->xyz[ 0 ] );
563 vertex->xyz[ 1 ] = _pico_little_short( vertex->xyz[ 1 ] );
564 vertex->xyz[ 2 ] = _pico_little_short( vertex->xyz[ 2 ] );
565 vertex->normal = _pico_little_short( vertex->normal );
568 /* swap xyz/compressed */
569 vertexComp = (mdcXyzCompressed_t*) ( (picoByte_t*) surface + surface->ofsXyzCompressed );
570 for ( j = 0; j < ( surface->numVerts * surface->numCompFrames ); j++, vertexComp++ )
572 vertexComp->ofsVec = _pico_little_long( vertexComp->ofsVec );
575 /* swap base frames */
576 mdcShort = (short *) ( (picoByte_t*) surface + surface->ofsFrameBaseFrames );
577 for ( j = 0; j < mdc->numFrames; j++, mdcShort++ )
579 *mdcShort = _pico_little_short( *mdcShort );
582 /* swap compressed frames */
583 mdcShort = (short *) ( (picoByte_t*) surface + surface->ofsFrameCompFrames );
584 for ( j = 0; j < mdc->numFrames; j++, mdcShort++ )
586 *mdcShort = _pico_little_short( *mdcShort );
589 /* get next surface */
590 surface = (mdcSurface_t*) ( (picoByte_t*) surface + surface->ofsEnd );
593 /* -------------------------------------------------
595 ------------------------------------------------- */
597 /* create new pico model */
598 picoModel = PicoNewModel();
599 if ( picoModel == NULL ) {
600 _pico_printf( PICO_ERROR, "Unable to allocate a new model" );
606 PicoSetModelFrameNum( picoModel, frameNum );
607 PicoSetModelNumFrames( picoModel, mdc->numFrames ); /* sea */
608 PicoSetModelName( picoModel, fileName );
609 PicoSetModelFileName( picoModel, fileName );
611 /* mdc surfaces become picomodel surfaces */
612 surface = (mdcSurface_t*) ( bb + mdc->ofsSurfaces );
614 /* run through mdc surfaces */
615 for ( i = 0; i < mdc->numSurfaces; i++ )
617 /* allocate new pico surface */
618 picoSurface = PicoNewSurface( picoModel );
619 if ( picoSurface == NULL ) {
620 _pico_printf( PICO_ERROR, "Unable to allocate a new model surface" );
621 PicoFreeModel( picoModel ); /* sea */
626 /* mdc model surfaces are all triangle meshes */
627 PicoSetSurfaceType( picoSurface, PICO_TRIANGLES );
629 /* set surface name */
630 PicoSetSurfaceName( picoSurface, surface->name );
632 /* create new pico shader -sea */
633 picoShader = PicoNewShader( picoModel );
634 if ( picoShader == NULL ) {
635 _pico_printf( PICO_ERROR, "Unable to allocate a new model shader" );
636 PicoFreeModel( picoModel );
641 /* detox and set shader name */
642 shader = (mdcShader_t*) ( (picoByte_t*) surface + surface->ofsShaders );
643 _pico_setfext( shader->name, NULL );
644 _pico_unixify( shader->name );
645 PicoSetShaderName( picoShader, shader->name );
647 /* associate current surface with newly created shader */
648 PicoSetSurfaceShader( picoSurface, picoShader );
651 triangle = (mdcTriangle_t *) ( (picoByte_t*) surface + surface->ofsTriangles );
653 for ( j = 0; j < surface->numTriangles; j++, triangle++ )
655 PicoSetSurfaceIndex( picoSurface, ( j * 3 + 0 ), (picoIndex_t) triangle->indexes[ 0 ] );
656 PicoSetSurfaceIndex( picoSurface, ( j * 3 + 1 ), (picoIndex_t) triangle->indexes[ 1 ] );
657 PicoSetSurfaceIndex( picoSurface, ( j * 3 + 2 ), (picoIndex_t) triangle->indexes[ 2 ] );
661 texCoord = (mdcTexCoord_t*) ( (picoByte_t *) surface + surface->ofsSt );
662 mdcShort = (short *) ( (picoByte_t *) surface + surface->ofsXyzNormals ) + ( (int)*( (short *) ( (picoByte_t *) surface + surface->ofsFrameBaseFrames ) + frameNum ) * surface->numVerts * 4 );
663 if ( surface->numCompFrames > 0 ) {
664 mdcCompVert = (short *) ( (picoByte_t *) surface + surface->ofsFrameCompFrames ) + frameNum;
665 if ( *mdcCompVert >= 0 ) {
666 vertexComp = (mdcXyzCompressed_t *) ( (picoByte_t *) surface + surface->ofsXyzCompressed ) + ( *mdcCompVert * surface->numVerts );
670 for ( j = 0; j < surface->numVerts; j++, texCoord++, mdcShort += 4 )
672 /* set vertex origin */
673 xyz[ 0 ] = MDC_SCALE * mdcShort[ 0 ];
674 xyz[ 1 ] = MDC_SCALE * mdcShort[ 1 ];
675 xyz[ 2 ] = MDC_SCALE * mdcShort[ 2 ];
677 /* add compressed ofsVec */
678 if ( surface->numCompFrames > 0 && *mdcCompVert >= 0 ) {
679 xyz[ 0 ] += ( (float) ( ( vertexComp->ofsVec ) & 255 ) - MDC_MAX_OFS ) * MDC_DIST_SCALE;
680 xyz[ 1 ] += ( (float) ( ( vertexComp->ofsVec >> 8 ) & 255 ) - MDC_MAX_OFS ) * MDC_DIST_SCALE;
681 xyz[ 2 ] += ( (float) ( ( vertexComp->ofsVec >> 16 ) & 255 ) - MDC_MAX_OFS ) * MDC_DIST_SCALE;
682 PicoSetSurfaceXYZ( picoSurface, j, xyz );
684 normal[ 0 ] = (float) mdcNormals[ ( vertexComp->ofsVec >> 24 ) ][ 0 ];
685 normal[ 1 ] = (float) mdcNormals[ ( vertexComp->ofsVec >> 24 ) ][ 1 ];
686 normal[ 2 ] = (float) mdcNormals[ ( vertexComp->ofsVec >> 24 ) ][ 2 ];
687 PicoSetSurfaceNormal( picoSurface, j, normal );
693 PicoSetSurfaceXYZ( picoSurface, j, xyz );
695 /* decode lat/lng normal to 3 float normal */
696 lat = (float) ( ( *( mdcShort + 3 ) >> 8 ) & 0xff );
697 lng = (float) ( *( mdcShort + 3 ) & 0xff );
698 lat *= PICO_PI / 128;
699 lng *= PICO_PI / 128;
700 normal[ 0 ] = (picoVec_t) cos( lat ) * (picoVec_t) sin( lng );
701 normal[ 1 ] = (picoVec_t) sin( lat ) * (picoVec_t) sin( lng );
702 normal[ 2 ] = (picoVec_t) cos( lng );
703 PicoSetSurfaceNormal( picoSurface, j, normal );
707 st[ 0 ] = texCoord->st[ 0 ];
708 st[ 1 ] = texCoord->st[ 1 ];
709 PicoSetSurfaceST( picoSurface, 0, j, st );
712 PicoSetSurfaceColor( picoSurface, 0, j, picoColor_white );
715 /* get next surface */
716 surface = (mdcSurface_t*) ( (picoByte_t*) surface + surface->ofsEnd );
719 /* return the new pico model */
726 /* pico file format module definition */
727 const picoModule_t picoModuleMDC =
729 "1.3", /* module version string */
730 "RtCW MDC", /* module display name */
731 "Arnout van Meer", /* author's name */
732 "2002 Arnout van Meer", /* module copyright */
734 "mdc", NULL, NULL, NULL /* default extensions to use */
736 _mdc_canload, /* validation routine */
737 _mdc_load, /* load routine */
738 NULL, /* save validation routine */
739 NULL /* save routine */