1 /* -----------------------------------------------------------------------------
\r
5 Copyright (c) 2002, Randy Reddig & seaw0lf
\r
8 Redistribution and use in source and binary forms, with or without modification,
\r
9 are permitted provided that the following conditions are met:
\r
11 Redistributions of source code must retain the above copyright notice, this list
\r
12 of conditions and the following disclaimer.
\r
14 Redistributions in binary form must reproduce the above copyright notice, this
\r
15 list of conditions and the following disclaimer in the documentation and/or
\r
16 other materials provided with the distribution.
\r
18 Neither the names of the copyright holders nor the names of its contributors may
\r
19 be used to endorse or promote products derived from this software without
\r
20 specific prior written permission.
\r
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
\r
23 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
\r
24 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
\r
25 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
\r
26 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
\r
27 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
\r
28 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
\r
29 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
\r
30 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
\r
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
33 ----------------------------------------------------------------------------- */
\r
43 #include "picointernal.h"
\r
45 /* mdc model format */
\r
46 #define MDC_MAGIC "IDPC"
\r
47 #define MDC_VERSION 2
\r
49 /* mdc vertex scale */
\r
50 #define MDC_SCALE (1.0f / 64.0f)
\r
51 #define MDC_MAX_OFS 127.0f
\r
52 #define MDC_DIST_SCALE 0.05f
\r
54 /* mdc decoding normal table */
\r
55 double mdcNormals[ 256 ][ 3 ] =
\r
57 { 1.000000, 0.000000, 0.000000 },
\r
58 { 0.980785, 0.195090, 0.000000 },
\r
59 { 0.923880, 0.382683, 0.000000 },
\r
60 { 0.831470, 0.555570, 0.000000 },
\r
61 { 0.707107, 0.707107, 0.000000 },
\r
62 { 0.555570, 0.831470, 0.000000 },
\r
63 { 0.382683, 0.923880, 0.000000 },
\r
64 { 0.195090, 0.980785, 0.000000 },
\r
65 { -0.000000, 1.000000, 0.000000 },
\r
66 { -0.195090, 0.980785, 0.000000 },
\r
67 { -0.382683, 0.923880, 0.000000 },
\r
68 { -0.555570, 0.831470, 0.000000 },
\r
69 { -0.707107, 0.707107, 0.000000 },
\r
70 { -0.831470, 0.555570, 0.000000 },
\r
71 { -0.923880, 0.382683, 0.000000 },
\r
72 { -0.980785, 0.195090, 0.000000 },
\r
73 { -1.000000, -0.000000, 0.000000 },
\r
74 { -0.980785, -0.195090, 0.000000 },
\r
75 { -0.923880, -0.382683, 0.000000 },
\r
76 { -0.831470, -0.555570, 0.000000 },
\r
77 { -0.707107, -0.707107, 0.000000 },
\r
78 { -0.555570, -0.831469, 0.000000 },
\r
79 { -0.382684, -0.923880, 0.000000 },
\r
80 { -0.195090, -0.980785, 0.000000 },
\r
81 { 0.000000, -1.000000, 0.000000 },
\r
82 { 0.195090, -0.980785, 0.000000 },
\r
83 { 0.382684, -0.923879, 0.000000 },
\r
84 { 0.555570, -0.831470, 0.000000 },
\r
85 { 0.707107, -0.707107, 0.000000 },
\r
86 { 0.831470, -0.555570, 0.000000 },
\r
87 { 0.923880, -0.382683, 0.000000 },
\r
88 { 0.980785, -0.195090, 0.000000 },
\r
89 { 0.980785, 0.000000, -0.195090 },
\r
90 { 0.956195, 0.218245, -0.195090 },
\r
91 { 0.883657, 0.425547, -0.195090 },
\r
92 { 0.766809, 0.611510, -0.195090 },
\r
93 { 0.611510, 0.766809, -0.195090 },
\r
94 { 0.425547, 0.883657, -0.195090 },
\r
95 { 0.218245, 0.956195, -0.195090 },
\r
96 { -0.000000, 0.980785, -0.195090 },
\r
97 { -0.218245, 0.956195, -0.195090 },
\r
98 { -0.425547, 0.883657, -0.195090 },
\r
99 { -0.611510, 0.766809, -0.195090 },
\r
100 { -0.766809, 0.611510, -0.195090 },
\r
101 { -0.883657, 0.425547, -0.195090 },
\r
102 { -0.956195, 0.218245, -0.195090 },
\r
103 { -0.980785, -0.000000, -0.195090 },
\r
104 { -0.956195, -0.218245, -0.195090 },
\r
105 { -0.883657, -0.425547, -0.195090 },
\r
106 { -0.766809, -0.611510, -0.195090 },
\r
107 { -0.611510, -0.766809, -0.195090 },
\r
108 { -0.425547, -0.883657, -0.195090 },
\r
109 { -0.218245, -0.956195, -0.195090 },
\r
110 { 0.000000, -0.980785, -0.195090 },
\r
111 { 0.218245, -0.956195, -0.195090 },
\r
112 { 0.425547, -0.883657, -0.195090 },
\r
113 { 0.611510, -0.766809, -0.195090 },
\r
114 { 0.766809, -0.611510, -0.195090 },
\r
115 { 0.883657, -0.425547, -0.195090 },
\r
116 { 0.956195, -0.218245, -0.195090 },
\r
117 { 0.923880, 0.000000, -0.382683 },
\r
118 { 0.892399, 0.239118, -0.382683 },
\r
119 { 0.800103, 0.461940, -0.382683 },
\r
120 { 0.653281, 0.653281, -0.382683 },
\r
121 { 0.461940, 0.800103, -0.382683 },
\r
122 { 0.239118, 0.892399, -0.382683 },
\r
123 { -0.000000, 0.923880, -0.382683 },
\r
124 { -0.239118, 0.892399, -0.382683 },
\r
125 { -0.461940, 0.800103, -0.382683 },
\r
126 { -0.653281, 0.653281, -0.382683 },
\r
127 { -0.800103, 0.461940, -0.382683 },
\r
128 { -0.892399, 0.239118, -0.382683 },
\r
129 { -0.923880, -0.000000, -0.382683 },
\r
130 { -0.892399, -0.239118, -0.382683 },
\r
131 { -0.800103, -0.461940, -0.382683 },
\r
132 { -0.653282, -0.653281, -0.382683 },
\r
133 { -0.461940, -0.800103, -0.382683 },
\r
134 { -0.239118, -0.892399, -0.382683 },
\r
135 { 0.000000, -0.923880, -0.382683 },
\r
136 { 0.239118, -0.892399, -0.382683 },
\r
137 { 0.461940, -0.800103, -0.382683 },
\r
138 { 0.653281, -0.653282, -0.382683 },
\r
139 { 0.800103, -0.461940, -0.382683 },
\r
140 { 0.892399, -0.239117, -0.382683 },
\r
141 { 0.831470, 0.000000, -0.555570 },
\r
142 { 0.790775, 0.256938, -0.555570 },
\r
143 { 0.672673, 0.488726, -0.555570 },
\r
144 { 0.488726, 0.672673, -0.555570 },
\r
145 { 0.256938, 0.790775, -0.555570 },
\r
146 { -0.000000, 0.831470, -0.555570 },
\r
147 { -0.256938, 0.790775, -0.555570 },
\r
148 { -0.488726, 0.672673, -0.555570 },
\r
149 { -0.672673, 0.488726, -0.555570 },
\r
150 { -0.790775, 0.256938, -0.555570 },
\r
151 { -0.831470, -0.000000, -0.555570 },
\r
152 { -0.790775, -0.256938, -0.555570 },
\r
153 { -0.672673, -0.488726, -0.555570 },
\r
154 { -0.488725, -0.672673, -0.555570 },
\r
155 { -0.256938, -0.790775, -0.555570 },
\r
156 { 0.000000, -0.831470, -0.555570 },
\r
157 { 0.256938, -0.790775, -0.555570 },
\r
158 { 0.488725, -0.672673, -0.555570 },
\r
159 { 0.672673, -0.488726, -0.555570 },
\r
160 { 0.790775, -0.256938, -0.555570 },
\r
161 { 0.707107, 0.000000, -0.707107 },
\r
162 { 0.653281, 0.270598, -0.707107 },
\r
163 { 0.500000, 0.500000, -0.707107 },
\r
164 { 0.270598, 0.653281, -0.707107 },
\r
165 { -0.000000, 0.707107, -0.707107 },
\r
166 { -0.270598, 0.653282, -0.707107 },
\r
167 { -0.500000, 0.500000, -0.707107 },
\r
168 { -0.653281, 0.270598, -0.707107 },
\r
169 { -0.707107, -0.000000, -0.707107 },
\r
170 { -0.653281, -0.270598, -0.707107 },
\r
171 { -0.500000, -0.500000, -0.707107 },
\r
172 { -0.270598, -0.653281, -0.707107 },
\r
173 { 0.000000, -0.707107, -0.707107 },
\r
174 { 0.270598, -0.653281, -0.707107 },
\r
175 { 0.500000, -0.500000, -0.707107 },
\r
176 { 0.653282, -0.270598, -0.707107 },
\r
177 { 0.555570, 0.000000, -0.831470 },
\r
178 { 0.481138, 0.277785, -0.831470 },
\r
179 { 0.277785, 0.481138, -0.831470 },
\r
180 { -0.000000, 0.555570, -0.831470 },
\r
181 { -0.277785, 0.481138, -0.831470 },
\r
182 { -0.481138, 0.277785, -0.831470 },
\r
183 { -0.555570, -0.000000, -0.831470 },
\r
184 { -0.481138, -0.277785, -0.831470 },
\r
185 { -0.277785, -0.481138, -0.831470 },
\r
186 { 0.000000, -0.555570, -0.831470 },
\r
187 { 0.277785, -0.481138, -0.831470 },
\r
188 { 0.481138, -0.277785, -0.831470 },
\r
189 { 0.382683, 0.000000, -0.923880 },
\r
190 { 0.270598, 0.270598, -0.923880 },
\r
191 { -0.000000, 0.382683, -0.923880 },
\r
192 { -0.270598, 0.270598, -0.923880 },
\r
193 { -0.382683, -0.000000, -0.923880 },
\r
194 { -0.270598, -0.270598, -0.923880 },
\r
195 { 0.000000, -0.382683, -0.923880 },
\r
196 { 0.270598, -0.270598, -0.923880 },
\r
197 { 0.195090, 0.000000, -0.980785 },
\r
198 { -0.000000, 0.195090, -0.980785 },
\r
199 { -0.195090, -0.000000, -0.980785 },
\r
200 { 0.000000, -0.195090, -0.980785 },
\r
201 { 0.980785, 0.000000, 0.195090 },
\r
202 { 0.956195, 0.218245, 0.195090 },
\r
203 { 0.883657, 0.425547, 0.195090 },
\r
204 { 0.766809, 0.611510, 0.195090 },
\r
205 { 0.611510, 0.766809, 0.195090 },
\r
206 { 0.425547, 0.883657, 0.195090 },
\r
207 { 0.218245, 0.956195, 0.195090 },
\r
208 { -0.000000, 0.980785, 0.195090 },
\r
209 { -0.218245, 0.956195, 0.195090 },
\r
210 { -0.425547, 0.883657, 0.195090 },
\r
211 { -0.611510, 0.766809, 0.195090 },
\r
212 { -0.766809, 0.611510, 0.195090 },
\r
213 { -0.883657, 0.425547, 0.195090 },
\r
214 { -0.956195, 0.218245, 0.195090 },
\r
215 { -0.980785, -0.000000, 0.195090 },
\r
216 { -0.956195, -0.218245, 0.195090 },
\r
217 { -0.883657, -0.425547, 0.195090 },
\r
218 { -0.766809, -0.611510, 0.195090 },
\r
219 { -0.611510, -0.766809, 0.195090 },
\r
220 { -0.425547, -0.883657, 0.195090 },
\r
221 { -0.218245, -0.956195, 0.195090 },
\r
222 { 0.000000, -0.980785, 0.195090 },
\r
223 { 0.218245, -0.956195, 0.195090 },
\r
224 { 0.425547, -0.883657, 0.195090 },
\r
225 { 0.611510, -0.766809, 0.195090 },
\r
226 { 0.766809, -0.611510, 0.195090 },
\r
227 { 0.883657, -0.425547, 0.195090 },
\r
228 { 0.956195, -0.218245, 0.195090 },
\r
229 { 0.923880, 0.000000, 0.382683 },
\r
230 { 0.892399, 0.239118, 0.382683 },
\r
231 { 0.800103, 0.461940, 0.382683 },
\r
232 { 0.653281, 0.653281, 0.382683 },
\r
233 { 0.461940, 0.800103, 0.382683 },
\r
234 { 0.239118, 0.892399, 0.382683 },
\r
235 { -0.000000, 0.923880, 0.382683 },
\r
236 { -0.239118, 0.892399, 0.382683 },
\r
237 { -0.461940, 0.800103, 0.382683 },
\r
238 { -0.653281, 0.653281, 0.382683 },
\r
239 { -0.800103, 0.461940, 0.382683 },
\r
240 { -0.892399, 0.239118, 0.382683 },
\r
241 { -0.923880, -0.000000, 0.382683 },
\r
242 { -0.892399, -0.239118, 0.382683 },
\r
243 { -0.800103, -0.461940, 0.382683 },
\r
244 { -0.653282, -0.653281, 0.382683 },
\r
245 { -0.461940, -0.800103, 0.382683 },
\r
246 { -0.239118, -0.892399, 0.382683 },
\r
247 { 0.000000, -0.923880, 0.382683 },
\r
248 { 0.239118, -0.892399, 0.382683 },
\r
249 { 0.461940, -0.800103, 0.382683 },
\r
250 { 0.653281, -0.653282, 0.382683 },
\r
251 { 0.800103, -0.461940, 0.382683 },
\r
252 { 0.892399, -0.239117, 0.382683 },
\r
253 { 0.831470, 0.000000, 0.555570 },
\r
254 { 0.790775, 0.256938, 0.555570 },
\r
255 { 0.672673, 0.488726, 0.555570 },
\r
256 { 0.488726, 0.672673, 0.555570 },
\r
257 { 0.256938, 0.790775, 0.555570 },
\r
258 { -0.000000, 0.831470, 0.555570 },
\r
259 { -0.256938, 0.790775, 0.555570 },
\r
260 { -0.488726, 0.672673, 0.555570 },
\r
261 { -0.672673, 0.488726, 0.555570 },
\r
262 { -0.790775, 0.256938, 0.555570 },
\r
263 { -0.831470, -0.000000, 0.555570 },
\r
264 { -0.790775, -0.256938, 0.555570 },
\r
265 { -0.672673, -0.488726, 0.555570 },
\r
266 { -0.488725, -0.672673, 0.555570 },
\r
267 { -0.256938, -0.790775, 0.555570 },
\r
268 { 0.000000, -0.831470, 0.555570 },
\r
269 { 0.256938, -0.790775, 0.555570 },
\r
270 { 0.488725, -0.672673, 0.555570 },
\r
271 { 0.672673, -0.488726, 0.555570 },
\r
272 { 0.790775, -0.256938, 0.555570 },
\r
273 { 0.707107, 0.000000, 0.707107 },
\r
274 { 0.653281, 0.270598, 0.707107 },
\r
275 { 0.500000, 0.500000, 0.707107 },
\r
276 { 0.270598, 0.653281, 0.707107 },
\r
277 { -0.000000, 0.707107, 0.707107 },
\r
278 { -0.270598, 0.653282, 0.707107 },
\r
279 { -0.500000, 0.500000, 0.707107 },
\r
280 { -0.653281, 0.270598, 0.707107 },
\r
281 { -0.707107, -0.000000, 0.707107 },
\r
282 { -0.653281, -0.270598, 0.707107 },
\r
283 { -0.500000, -0.500000, 0.707107 },
\r
284 { -0.270598, -0.653281, 0.707107 },
\r
285 { 0.000000, -0.707107, 0.707107 },
\r
286 { 0.270598, -0.653281, 0.707107 },
\r
287 { 0.500000, -0.500000, 0.707107 },
\r
288 { 0.653282, -0.270598, 0.707107 },
\r
289 { 0.555570, 0.000000, 0.831470 },
\r
290 { 0.481138, 0.277785, 0.831470 },
\r
291 { 0.277785, 0.481138, 0.831470 },
\r
292 { -0.000000, 0.555570, 0.831470 },
\r
293 { -0.277785, 0.481138, 0.831470 },
\r
294 { -0.481138, 0.277785, 0.831470 },
\r
295 { -0.555570, -0.000000, 0.831470 },
\r
296 { -0.481138, -0.277785, 0.831470 },
\r
297 { -0.277785, -0.481138, 0.831470 },
\r
298 { 0.000000, -0.555570, 0.831470 },
\r
299 { 0.277785, -0.481138, 0.831470 },
\r
300 { 0.481138, -0.277785, 0.831470 },
\r
301 { 0.382683, 0.000000, 0.923880 },
\r
302 { 0.270598, 0.270598, 0.923880 },
\r
303 { -0.000000, 0.382683, 0.923880 },
\r
304 { -0.270598, 0.270598, 0.923880 },
\r
305 { -0.382683, -0.000000, 0.923880 },
\r
306 { -0.270598, -0.270598, 0.923880 },
\r
307 { 0.000000, -0.382683, 0.923880 },
\r
308 { 0.270598, -0.270598, 0.923880 },
\r
309 { 0.195090, 0.000000, 0.980785 },
\r
310 { -0.000000, 0.195090, 0.980785 },
\r
311 { -0.195090, -0.000000, 0.980785 },
\r
312 { 0.000000, -0.195090, 0.980785 }
\r
315 /* mdc model frame information */
\r
316 typedef struct mdcFrame_s
\r
318 float bounds[ 2 ][ 3 ];
\r
319 float localOrigin[ 3 ];
\r
321 char creator[ 16 ];
\r
325 /* mdc model tag information */
\r
326 typedef struct mdcTag_s
\r
333 /* mdc surface mdc (one object mesh) */
\r
334 typedef struct mdcSurface_s
\r
337 char name[ 64 ]; /* polyset name */
\r
339 int numCompFrames; /* all surfaces in a model should have the same */
\r
340 int numBaseFrames; /* ditto */
\r
341 int numShaders; /* all model surfaces should have the same */
\r
345 int ofsShaders; /* offset from start of mdcSurface_t */
\r
346 int ofsSt; /* texture coords are common for all frames */
\r
347 int ofsXyzNormals; /* numVerts * numBaseFrames */
\r
348 int ofsXyzCompressed; /* numVerts * numCompFrames */
\r
350 int ofsFrameBaseFrames; /* numFrames */
\r
351 int ofsFrameCompFrames; /* numFrames */
\r
352 int ofsEnd; /* next surface follows */
\r
356 typedef struct mdcShader_s
\r
359 int shaderIndex; /* for ingame use */
\r
363 typedef struct mdcTriangle_s
\r
369 typedef struct mdcTexCoord_s
\r
375 typedef struct mdcVertex_s
\r
382 typedef struct mdcXyzCompressed_s
\r
384 unsigned int ofsVec; /* offset direction from the last base frame */
\r
386 mdcXyzCompressed_t;
\r
389 /* mdc model file mdc structure */
\r
390 typedef struct mdc_s
\r
392 char magic[ 4 ]; /* MDC_MAGIC */
\r
394 char name[ 64 ]; /* model name */
\r
399 int numSkins; /* number of skins for the mesh */
\r
400 int ofsFrames; /* offset for first frame */
\r
401 int ofsTagNames; /* numTags */
\r
402 int ofsTags; /* numFrames * numTags */
\r
403 int ofsSurfaces; /* first surface, others follow */
\r
404 int ofsEnd; /* end of file */
\r
413 validates a Return to Castle Wolfenstein model file. btw, i use the
\r
414 preceding underscore cause it's a static func referenced
\r
415 by one structure only.
\r
418 static int _mdc_canload( PM_PARAMS_CANLOAD )
\r
423 /* to keep the compiler happy */
\r
424 *fileName = *fileName;
\r
427 if( bufSize < ( sizeof( *mdc ) * 2) )
\r
428 return PICO_PMV_ERROR_SIZE;
\r
431 mdc = (mdc_t*) buffer;
\r
433 /* check mdc magic */
\r
434 if( *((int*) mdc->magic) != *((int*) MDC_MAGIC) )
\r
435 return PICO_PMV_ERROR_IDENT;
\r
437 /* check mdc version */
\r
438 if( _pico_little_long( mdc->version ) != MDC_VERSION )
\r
439 return PICO_PMV_ERROR_VERSION;
\r
441 /* file seems to be a valid mdc */
\r
442 return PICO_PMV_OK;
\r
449 loads a Return to Castle Wolfenstein mdc model file.
\r
452 static picoModel_t *_mdc_load( PM_PARAMS_LOAD )
\r
457 mdcSurface_t *surface;
\r
458 mdcShader_t *shader;
\r
459 mdcTexCoord_t *texCoord;
\r
461 mdcTriangle_t *triangle;
\r
462 mdcVertex_t *vertex;
\r
463 mdcXyzCompressed_t *vertexComp;
\r
464 short *mdcShort, *mdcCompVert;
\r
467 picoModel_t *picoModel;
\r
468 picoSurface_t *picoSurface;
\r
469 picoShader_t *picoShader;
\r
470 picoVec3_t xyz, normal;
\r
475 /* -------------------------------------------------
\r
477 ------------------------------------------------- */
\r
481 bb = (picoByte_t*) buffer;
\r
482 mdc = (mdc_t*) buffer;
\r
484 /* check ident and version */
\r
485 if( *((int*) mdc->magic) != *((int*) MDC_MAGIC) || _pico_little_long( mdc->version ) != MDC_VERSION )
\r
487 /* not an mdc file (todo: set error) */
\r
492 mdc->version = _pico_little_long( mdc->version );
\r
493 mdc->numFrames = _pico_little_long( mdc->numFrames );
\r
494 mdc->numTags = _pico_little_long( mdc->numTags );
\r
495 mdc->numSurfaces = _pico_little_long( mdc->numSurfaces );
\r
496 mdc->numSkins = _pico_little_long( mdc->numSkins );
\r
497 mdc->ofsFrames = _pico_little_long( mdc->ofsFrames );
\r
498 mdc->ofsTags = _pico_little_long( mdc->ofsTags );
\r
499 mdc->ofsTagNames = _pico_little_long( mdc->ofsTagNames );
\r
500 mdc->ofsSurfaces = _pico_little_long( mdc->ofsSurfaces );
\r
501 mdc->ofsEnd = _pico_little_long( mdc->ofsEnd );
\r
503 /* do frame check */
\r
504 if( mdc->numFrames < 1 )
\r
506 _pico_printf( PICO_ERROR, "MDC with 0 frames" );
\r
510 if( frameNum < 0 || frameNum >= mdc->numFrames )
\r
512 _pico_printf( PICO_ERROR, "Invalid or out-of-range MDC frame specified" );
\r
517 frame = (mdcFrame_t*) (bb + mdc->ofsFrames );
\r
518 for( i = 0; i < mdc->numFrames; i++, frame++ )
\r
520 frame->radius = _pico_little_float( frame->radius );
\r
521 for( j = 0; j < 3; j++ )
\r
523 frame->bounds[ 0 ][ j ] = _pico_little_float( frame->bounds[ 0 ][ j ] );
\r
524 frame->bounds[ 1 ][ j ] = _pico_little_float( frame->bounds[ 1 ][ j ] );
\r
525 frame->localOrigin[ j ] = _pico_little_float( frame->localOrigin[ j ] );
\r
529 /* swap surfaces */
\r
530 surface = (mdcSurface_t*) (bb + mdc->ofsSurfaces);
\r
531 for( i = 0; i < mdc->numSurfaces; i++ )
\r
533 /* swap surface mdc */
\r
534 surface->flags = _pico_little_long( surface->flags );
\r
535 surface->numBaseFrames = _pico_little_long( surface->numBaseFrames );
\r
536 surface->numCompFrames = _pico_little_long( surface->numCompFrames );
\r
537 surface->numShaders = _pico_little_long( surface->numShaders );
\r
538 surface->numTriangles = _pico_little_long( surface->numTriangles );
\r
539 surface->ofsTriangles = _pico_little_long( surface->ofsTriangles );
\r
540 surface->numVerts = _pico_little_long( surface->numVerts );
\r
541 surface->ofsShaders = _pico_little_long( surface->ofsShaders );
\r
542 surface->ofsSt = _pico_little_long( surface->ofsSt );
\r
543 surface->ofsXyzNormals = _pico_little_long( surface->ofsXyzNormals );
\r
544 surface->ofsXyzCompressed = _pico_little_long( surface->ofsXyzCompressed );
\r
545 surface->ofsFrameBaseFrames = _pico_little_long( surface->ofsFrameBaseFrames );
\r
546 surface->ofsFrameCompFrames = _pico_little_long( surface->ofsFrameCompFrames );
\r
547 surface->ofsEnd = _pico_little_long( surface->ofsEnd );
\r
549 /* swap triangles */
\r
550 triangle = (mdcTriangle_t*) ((picoByte_t*) surface + surface->ofsTriangles);
\r
551 for( j = 0; j < surface->numTriangles; j++, triangle++ )
\r
553 /* sea: swaps fixed */
\r
554 triangle->indexes[ 0 ] = _pico_little_long( triangle->indexes[ 0 ] );
\r
555 triangle->indexes[ 1 ] = _pico_little_long( triangle->indexes[ 1 ] );
\r
556 triangle->indexes[ 2 ] = _pico_little_long( triangle->indexes[ 2 ] );
\r
559 /* swap st coords */
\r
560 texCoord = (mdcTexCoord_t*) ((picoByte_t*) surface + surface->ofsSt);
\r
561 for( j = 0; j < surface->numVerts; j++, texCoord++ )
\r
563 texCoord->st[ 0 ] = _pico_little_float( texCoord->st[ 0 ] );
\r
564 texCoord->st[ 1 ] = _pico_little_float( texCoord->st[ 1 ] );
\r
567 /* swap xyz/normals */
\r
568 vertex = (mdcVertex_t*) ((picoByte_t*) surface + surface->ofsXyzNormals);
\r
569 for( j = 0; j < (surface->numVerts * surface->numBaseFrames); j++, vertex++)
\r
571 vertex->xyz[ 0 ] = _pico_little_short( vertex->xyz[ 0 ] );
\r
572 vertex->xyz[ 1 ] = _pico_little_short( vertex->xyz[ 1 ] );
\r
573 vertex->xyz[ 2 ] = _pico_little_short( vertex->xyz[ 2 ] );
\r
574 vertex->normal = _pico_little_short( vertex->normal );
\r
577 /* swap xyz/compressed */
\r
578 vertexComp = (mdcXyzCompressed_t*) ((picoByte_t*) surface + surface->ofsXyzCompressed);
\r
579 for( j = 0; j < (surface->numVerts * surface->numCompFrames); j++, vertexComp++)
\r
581 vertexComp->ofsVec = _pico_little_long( vertexComp->ofsVec );
\r
584 /* swap base frames */
\r
585 mdcShort = (short *) ((picoByte_t*) surface + surface->ofsFrameBaseFrames);
\r
586 for( j = 0; j < mdc->numFrames; j++, mdcShort++)
\r
588 *mdcShort = _pico_little_short( *mdcShort );
\r
591 /* swap compressed frames */
\r
592 mdcShort = (short *) ((picoByte_t*) surface + surface->ofsFrameCompFrames);
\r
593 for( j = 0; j < mdc->numFrames; j++, mdcShort++)
\r
595 *mdcShort = _pico_little_short( *mdcShort );
\r
598 /* get next surface */
\r
599 surface = (mdcSurface_t*) ((picoByte_t*) surface + surface->ofsEnd);
\r
602 /* -------------------------------------------------
\r
603 pico model creation
\r
604 ------------------------------------------------- */
\r
606 /* create new pico model */
\r
607 picoModel = PicoNewModel();
\r
608 if( picoModel == NULL )
\r
610 _pico_printf( PICO_ERROR, "Unable to allocate a new model" );
\r
614 /* do model setup */
\r
615 PicoSetModelFrameNum( picoModel, frameNum );
\r
616 PicoSetModelNumFrames( picoModel, mdc->numFrames ); /* sea */
\r
617 PicoSetModelName( picoModel, fileName );
\r
618 PicoSetModelFileName( picoModel, fileName );
\r
620 /* mdc surfaces become picomodel surfaces */
\r
621 surface = (mdcSurface_t*) (bb + mdc->ofsSurfaces);
\r
623 /* run through mdc surfaces */
\r
624 for( i = 0; i < mdc->numSurfaces; i++ )
\r
626 /* allocate new pico surface */
\r
627 picoSurface = PicoNewSurface( picoModel );
\r
628 if( picoSurface == NULL )
\r
630 _pico_printf( PICO_ERROR, "Unable to allocate a new model surface" );
\r
631 PicoFreeModel( picoModel ); /* sea */
\r
635 /* mdc model surfaces are all triangle meshes */
\r
636 PicoSetSurfaceType( picoSurface, PICO_TRIANGLES );
\r
638 /* set surface name */
\r
639 PicoSetSurfaceName( picoSurface, surface->name );
\r
641 /* create new pico shader -sea */
\r
642 picoShader = PicoNewShader( picoModel );
\r
643 if( picoShader == NULL )
\r
645 _pico_printf( PICO_ERROR, "Unable to allocate a new model shader" );
\r
646 PicoFreeModel( picoModel );
\r
650 /* detox and set shader name */
\r
651 shader = (mdcShader_t*) ((picoByte_t*) surface + surface->ofsShaders);
\r
652 _pico_setfext( shader->name, "" );
\r
653 _pico_unixify( shader->name );
\r
654 PicoSetShaderName( picoShader, shader->name );
\r
656 /* associate current surface with newly created shader */
\r
657 PicoSetSurfaceShader( picoSurface, picoShader );
\r
660 triangle = (mdcTriangle_t *) ((picoByte_t*) surface + surface->ofsTriangles);
\r
662 for( j = 0; j < surface->numTriangles; j++, triangle++ )
\r
664 PicoSetSurfaceIndex( picoSurface, (j * 3 + 0), (picoIndex_t) triangle->indexes[ 0 ] );
\r
665 PicoSetSurfaceIndex( picoSurface, (j * 3 + 1), (picoIndex_t) triangle->indexes[ 1 ] );
\r
666 PicoSetSurfaceIndex( picoSurface, (j * 3 + 2), (picoIndex_t) triangle->indexes[ 2 ] );
\r
669 /* copy vertexes */
\r
670 texCoord = (mdcTexCoord_t*) ((picoByte_t *) surface + surface->ofsSt);
\r
671 mdcShort = (short *) ((picoByte_t *) surface + surface->ofsXyzNormals) + ((int)*((short *) ((picoByte_t *) surface + surface->ofsFrameBaseFrames) + frameNum) * surface->numVerts * 4);
\r
672 if( surface->numCompFrames > 0 )
\r
674 mdcCompVert = (short *) ((picoByte_t *) surface + surface->ofsFrameCompFrames) + frameNum;
\r
675 if( *mdcCompVert >= 0 )
\r
676 vertexComp = (mdcXyzCompressed_t *) ((picoByte_t *) surface + surface->ofsXyzCompressed) + (*mdcCompVert * surface->numVerts);
\r
678 _pico_set_color( color, 255, 255, 255, 255 );
\r
680 for( j = 0; j < surface->numVerts; j++, texCoord++, mdcShort+=4 )
\r
682 /* set vertex origin */
\r
683 xyz[ 0 ] = MDC_SCALE * mdcShort[ 0 ];
\r
684 xyz[ 1 ] = MDC_SCALE * mdcShort[ 1 ];
\r
685 xyz[ 2 ] = MDC_SCALE * mdcShort[ 2 ];
\r
687 /* add compressed ofsVec */
\r
688 if( surface->numCompFrames > 0 && *mdcCompVert >= 0 )
\r
690 xyz[ 0 ] += ((float) ((vertexComp->ofsVec) & 255) - MDC_MAX_OFS) * MDC_DIST_SCALE;
\r
691 xyz[ 1 ] += ((float) ((vertexComp->ofsVec >> 8) & 255) - MDC_MAX_OFS) * MDC_DIST_SCALE;
\r
692 xyz[ 2 ] += ((float) ((vertexComp->ofsVec >> 16) & 255) - MDC_MAX_OFS) * MDC_DIST_SCALE;
\r
693 PicoSetSurfaceXYZ( picoSurface, j, xyz );
\r
695 normal[ 0 ] = (float) mdcNormals[ (vertexComp->ofsVec >> 24) ][ 0 ];
\r
696 normal[ 1 ] = (float) mdcNormals[ (vertexComp->ofsVec >> 24) ][ 1 ];
\r
697 normal[ 2 ] = (float) mdcNormals[ (vertexComp->ofsVec >> 24) ][ 2 ];
\r
698 PicoSetSurfaceNormal( picoSurface, j, normal );
\r
704 PicoSetSurfaceXYZ( picoSurface, j, xyz );
\r
706 /* decode lat/lng normal to 3 float normal */
\r
707 lat = (float) ((*(mdcShort + 3) >> 8) & 0xff);
\r
708 lng = (float) (*(mdcShort + 3) & 0xff);
\r
709 lat *= PICO_PI / 128;
\r
710 lng *= PICO_PI / 128;
\r
711 normal[ 0 ] = (picoVec_t) cos( lat ) * (picoVec_t) sin( lng );
\r
712 normal[ 1 ] = (picoVec_t) sin( lat ) * (picoVec_t) sin( lng );
\r
713 normal[ 2 ] = (picoVec_t) cos( lng );
\r
714 PicoSetSurfaceNormal( picoSurface, j, normal );
\r
717 /* set st coords */
\r
718 st[ 0 ] = texCoord->st[ 0 ];
\r
719 st[ 1 ] = texCoord->st[ 1 ];
\r
720 PicoSetSurfaceST( picoSurface, 0, j, st );
\r
723 PicoSetSurfaceColor( picoSurface, 0, j, color );
\r
726 /* get next surface */
\r
727 surface = (mdcSurface_t*) ((picoByte_t*) surface + surface->ofsEnd);
\r
730 /* return the new pico model */
\r
736 /* pico file format module definition */
\r
737 const picoModule_t picoModuleMDC =
\r
739 "1.3", /* module version string */
\r
740 "RtCW MDC", /* module display name */
\r
741 "Arnout van Meer", /* author's name */
\r
742 "2002 Arnout van Meer", /* module copyright */
\r
744 "mdc", NULL, NULL, NULL /* default extensions to use */
\r
746 _mdc_canload, /* validation routine */
\r
747 _mdc_load, /* load routine */
\r
748 NULL, /* save validation routine */
\r
749 NULL /* save routine */
\r