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 ){
422 /* to keep the compiler happy */
423 *fileName = *fileName;
426 if ( bufSize < ( sizeof( *mdc ) * 2 ) ) {
427 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;
438 /* check mdc version */
439 if ( _pico_little_long( mdc->version ) != MDC_VERSION ) {
440 return PICO_PMV_ERROR_VERSION;
443 /* file seems to be a valid mdc */
451 loads a Return to Castle Wolfenstein mdc model file.
454 static picoModel_t *_mdc_load( PM_PARAMS_LOAD ){
458 mdcSurface_t *surface;
460 mdcTexCoord_t *texCoord;
462 mdcTriangle_t *triangle;
464 mdcXyzCompressed_t *vertexComp;
465 short *mdcShort, *mdcCompVert;
468 picoModel_t *picoModel;
469 picoSurface_t *picoSurface;
470 picoShader_t *picoShader;
471 picoVec3_t xyz, normal;
476 /* -------------------------------------------------
478 ------------------------------------------------- */
482 bb = (picoByte_t*) buffer;
483 mdc = (mdc_t*) buffer;
485 /* check ident and version */
486 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 ) {
505 _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" );
515 frame = (mdcFrame_t*) ( bb + mdc->ofsFrames );
516 for ( i = 0; i < mdc->numFrames; i++, frame++ )
518 frame->radius = _pico_little_float( frame->radius );
519 for ( j = 0; j < 3; j++ )
521 frame->bounds[ 0 ][ j ] = _pico_little_float( frame->bounds[ 0 ][ j ] );
522 frame->bounds[ 1 ][ j ] = _pico_little_float( frame->bounds[ 1 ][ j ] );
523 frame->localOrigin[ j ] = _pico_little_float( frame->localOrigin[ j ] );
528 surface = (mdcSurface_t*) ( bb + mdc->ofsSurfaces );
529 for ( i = 0; i < mdc->numSurfaces; i++ )
531 /* swap surface mdc */
532 surface->flags = _pico_little_long( surface->flags );
533 surface->numBaseFrames = _pico_little_long( surface->numBaseFrames );
534 surface->numCompFrames = _pico_little_long( surface->numCompFrames );
535 surface->numShaders = _pico_little_long( surface->numShaders );
536 surface->numTriangles = _pico_little_long( surface->numTriangles );
537 surface->ofsTriangles = _pico_little_long( surface->ofsTriangles );
538 surface->numVerts = _pico_little_long( surface->numVerts );
539 surface->ofsShaders = _pico_little_long( surface->ofsShaders );
540 surface->ofsSt = _pico_little_long( surface->ofsSt );
541 surface->ofsXyzNormals = _pico_little_long( surface->ofsXyzNormals );
542 surface->ofsXyzCompressed = _pico_little_long( surface->ofsXyzCompressed );
543 surface->ofsFrameBaseFrames = _pico_little_long( surface->ofsFrameBaseFrames );
544 surface->ofsFrameCompFrames = _pico_little_long( surface->ofsFrameCompFrames );
545 surface->ofsEnd = _pico_little_long( surface->ofsEnd );
548 triangle = (mdcTriangle_t*) ( (picoByte_t*) surface + surface->ofsTriangles );
549 for ( j = 0; j < surface->numTriangles; j++, triangle++ )
551 /* sea: swaps fixed */
552 triangle->indexes[ 0 ] = _pico_little_long( triangle->indexes[ 0 ] );
553 triangle->indexes[ 1 ] = _pico_little_long( triangle->indexes[ 1 ] );
554 triangle->indexes[ 2 ] = _pico_little_long( triangle->indexes[ 2 ] );
558 texCoord = (mdcTexCoord_t*) ( (picoByte_t*) surface + surface->ofsSt );
559 for ( j = 0; j < surface->numVerts; j++, texCoord++ )
561 texCoord->st[ 0 ] = _pico_little_float( texCoord->st[ 0 ] );
562 texCoord->st[ 1 ] = _pico_little_float( texCoord->st[ 1 ] );
565 /* swap xyz/normals */
566 vertex = (mdcVertex_t*) ( (picoByte_t*) surface + surface->ofsXyzNormals );
567 for ( j = 0; j < ( surface->numVerts * surface->numBaseFrames ); j++, vertex++ )
569 vertex->xyz[ 0 ] = _pico_little_short( vertex->xyz[ 0 ] );
570 vertex->xyz[ 1 ] = _pico_little_short( vertex->xyz[ 1 ] );
571 vertex->xyz[ 2 ] = _pico_little_short( vertex->xyz[ 2 ] );
572 vertex->normal = _pico_little_short( vertex->normal );
575 /* swap xyz/compressed */
576 vertexComp = (mdcXyzCompressed_t*) ( (picoByte_t*) surface + surface->ofsXyzCompressed );
577 for ( j = 0; j < ( surface->numVerts * surface->numCompFrames ); j++, vertexComp++ )
579 vertexComp->ofsVec = _pico_little_long( vertexComp->ofsVec );
582 /* swap base frames */
583 mdcShort = (short *) ( (picoByte_t*) surface + surface->ofsFrameBaseFrames );
584 for ( j = 0; j < mdc->numFrames; j++, mdcShort++ )
586 *mdcShort = _pico_little_short( *mdcShort );
589 /* swap compressed frames */
590 mdcShort = (short *) ( (picoByte_t*) surface + surface->ofsFrameCompFrames );
591 for ( j = 0; j < mdc->numFrames; j++, mdcShort++ )
593 *mdcShort = _pico_little_short( *mdcShort );
596 /* get next surface */
597 surface = (mdcSurface_t*) ( (picoByte_t*) surface + surface->ofsEnd );
600 /* -------------------------------------------------
602 ------------------------------------------------- */
604 /* create new pico model */
605 picoModel = PicoNewModel();
606 if ( picoModel == NULL ) {
607 _pico_printf( PICO_ERROR, "Unable to allocate a new model" );
612 PicoSetModelFrameNum( picoModel, frameNum );
613 PicoSetModelNumFrames( picoModel, mdc->numFrames ); /* sea */
614 PicoSetModelName( picoModel, fileName );
615 PicoSetModelFileName( picoModel, fileName );
617 /* mdc surfaces become picomodel surfaces */
618 surface = (mdcSurface_t*) ( bb + mdc->ofsSurfaces );
620 /* run through mdc surfaces */
621 for ( i = 0; i < mdc->numSurfaces; i++ )
623 /* allocate new pico surface */
624 picoSurface = PicoNewSurface( picoModel );
625 if ( picoSurface == NULL ) {
626 _pico_printf( PICO_ERROR, "Unable to allocate a new model surface" );
627 PicoFreeModel( picoModel ); /* sea */
631 /* mdc model surfaces are all triangle meshes */
632 PicoSetSurfaceType( picoSurface, PICO_TRIANGLES );
634 /* set surface name */
635 PicoSetSurfaceName( picoSurface, surface->name );
637 /* create new pico shader -sea */
638 picoShader = PicoNewShader( picoModel );
639 if ( picoShader == NULL ) {
640 _pico_printf( PICO_ERROR, "Unable to allocate a new model shader" );
641 PicoFreeModel( picoModel );
645 /* detox and set shader name */
646 shader = (mdcShader_t*) ( (picoByte_t*) surface + surface->ofsShaders );
647 _pico_setfext( shader->name, "" );
648 _pico_unixify( shader->name );
649 PicoSetShaderName( picoShader, shader->name );
651 /* associate current surface with newly created shader */
652 PicoSetSurfaceShader( picoSurface, picoShader );
655 triangle = (mdcTriangle_t *) ( (picoByte_t*) surface + surface->ofsTriangles );
657 for ( j = 0; j < surface->numTriangles; j++, triangle++ )
659 PicoSetSurfaceIndex( picoSurface, ( j * 3 + 0 ), (picoIndex_t) triangle->indexes[ 0 ] );
660 PicoSetSurfaceIndex( picoSurface, ( j * 3 + 1 ), (picoIndex_t) triangle->indexes[ 1 ] );
661 PicoSetSurfaceIndex( picoSurface, ( j * 3 + 2 ), (picoIndex_t) triangle->indexes[ 2 ] );
665 texCoord = (mdcTexCoord_t*) ( (picoByte_t *) surface + surface->ofsSt );
666 mdcShort = (short *) ( (picoByte_t *) surface + surface->ofsXyzNormals ) + ( (int)*( (short *) ( (picoByte_t *) surface + surface->ofsFrameBaseFrames ) + frameNum ) * surface->numVerts * 4 );
667 if ( surface->numCompFrames > 0 ) {
668 mdcCompVert = (short *) ( (picoByte_t *) surface + surface->ofsFrameCompFrames ) + frameNum;
669 if ( *mdcCompVert >= 0 ) {
670 vertexComp = (mdcXyzCompressed_t *) ( (picoByte_t *) surface + surface->ofsXyzCompressed ) + ( *mdcCompVert * surface->numVerts );
673 _pico_set_color( color, 255, 255, 255, 255 );
675 for ( j = 0; j < surface->numVerts; j++, texCoord++, mdcShort += 4 )
677 /* set vertex origin */
678 xyz[ 0 ] = MDC_SCALE * mdcShort[ 0 ];
679 xyz[ 1 ] = MDC_SCALE * mdcShort[ 1 ];
680 xyz[ 2 ] = MDC_SCALE * mdcShort[ 2 ];
682 /* add compressed ofsVec */
683 if ( surface->numCompFrames > 0 && *mdcCompVert >= 0 ) {
684 xyz[ 0 ] += ( (float) ( ( vertexComp->ofsVec ) & 255 ) - MDC_MAX_OFS ) * MDC_DIST_SCALE;
685 xyz[ 1 ] += ( (float) ( ( vertexComp->ofsVec >> 8 ) & 255 ) - MDC_MAX_OFS ) * MDC_DIST_SCALE;
686 xyz[ 2 ] += ( (float) ( ( vertexComp->ofsVec >> 16 ) & 255 ) - MDC_MAX_OFS ) * MDC_DIST_SCALE;
687 PicoSetSurfaceXYZ( picoSurface, j, xyz );
689 normal[ 0 ] = (float) mdcNormals[ ( vertexComp->ofsVec >> 24 ) ][ 0 ];
690 normal[ 1 ] = (float) mdcNormals[ ( vertexComp->ofsVec >> 24 ) ][ 1 ];
691 normal[ 2 ] = (float) mdcNormals[ ( vertexComp->ofsVec >> 24 ) ][ 2 ];
692 PicoSetSurfaceNormal( picoSurface, j, normal );
698 PicoSetSurfaceXYZ( picoSurface, j, xyz );
700 /* decode lat/lng normal to 3 float normal */
701 lat = (float) ( ( *( mdcShort + 3 ) >> 8 ) & 0xff );
702 lng = (float) ( *( mdcShort + 3 ) & 0xff );
703 lat *= PICO_PI / 128;
704 lng *= PICO_PI / 128;
705 normal[ 0 ] = (picoVec_t) cos( lat ) * (picoVec_t) sin( lng );
706 normal[ 1 ] = (picoVec_t) sin( lat ) * (picoVec_t) sin( lng );
707 normal[ 2 ] = (picoVec_t) cos( lng );
708 PicoSetSurfaceNormal( picoSurface, j, normal );
712 st[ 0 ] = texCoord->st[ 0 ];
713 st[ 1 ] = texCoord->st[ 1 ];
714 PicoSetSurfaceST( picoSurface, 0, j, st );
717 PicoSetSurfaceColor( picoSurface, 0, j, color );
720 /* get next surface */
721 surface = (mdcSurface_t*) ( (picoByte_t*) surface + surface->ofsEnd );
724 /* return the new pico model */
730 /* pico file format module definition */
731 const picoModule_t picoModuleMDC =
733 "1.3", /* module version string */
734 "RtCW MDC", /* module display name */
735 "Arnout van Meer", /* author's name */
736 "2002 Arnout van Meer", /* module copyright */
738 "mdc", NULL, NULL, NULL /* default extensions to use */
740 _mdc_canload, /* validation routine */
741 _mdc_load, /* load routine */
742 NULL, /* save validation routine */
743 NULL /* save routine */