1 | /********************************************************************** <BR>
|
---|
2 | This file is part of Crack dot Com's free source code release of
|
---|
3 | Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
|
---|
4 | information about compiling & licensing issues visit this URL</a>
|
---|
5 | <PRE> If that doesn't help, contact Jonathan Clark at
|
---|
6 | golgotha_source@usa.net (Subject should have "GOLG" in it)
|
---|
7 | ***********************************************************************/
|
---|
8 |
|
---|
9 | #include "max_object.hh"
|
---|
10 | #include "saver_id.hh"
|
---|
11 | #include "loaders/dir_save.hh"
|
---|
12 |
|
---|
13 | // Save section
|
---|
14 |
|
---|
15 | void m1_poly_object_class::save_quads(i4_saver_class *fp)
|
---|
16 | //{{{
|
---|
17 | {
|
---|
18 | int i,j;
|
---|
19 |
|
---|
20 | fp->mark_section(G1_SECTION_MODEL_QUADS);
|
---|
21 |
|
---|
22 | int tq=num_quad;
|
---|
23 |
|
---|
24 | fp->write_16(tq);
|
---|
25 | for (i=0; i<tq; i++)
|
---|
26 | {
|
---|
27 | for (j=0; j<quad[i].max_verts(); ++j)
|
---|
28 | {
|
---|
29 | fp->write_16(quad[i].vertex_ref[j]);
|
---|
30 | fp->write_float(quad[i].u[j]);
|
---|
31 | fp->write_float(quad[i].v[j]);
|
---|
32 | }
|
---|
33 | fp->write_float(quad[i].texture_scale);
|
---|
34 | fp->write_16(quad[i].flags);
|
---|
35 |
|
---|
36 | fp->write_float(quad[i].normal.x);
|
---|
37 | fp->write_float(quad[i].normal.y);
|
---|
38 | fp->write_float(quad[i].normal.z);
|
---|
39 | }
|
---|
40 | }
|
---|
41 | //}}}
|
---|
42 |
|
---|
43 | void m1_poly_object_class::save_texture_names(i4_saver_class *fp)
|
---|
44 | //{{{
|
---|
45 | {
|
---|
46 | fp->mark_section(G1_SECTION_MODEL_TEXTURE_NAMES);
|
---|
47 | int tq=num_quad;
|
---|
48 | fp->write_16(tq);
|
---|
49 | for (int i=0; i<tq; i++)
|
---|
50 | fp->write_counted_str(*texture_names[i]);
|
---|
51 | }
|
---|
52 | //}}}
|
---|
53 |
|
---|
54 | void m1_poly_object_class::save_vert_animations(i4_saver_class *fp)
|
---|
55 | //{{{
|
---|
56 | {
|
---|
57 | int i,j,k;
|
---|
58 |
|
---|
59 | fp->mark_section(G1_SECTION_MODEL_VERT_ANIMATION);
|
---|
60 |
|
---|
61 | fp->write_16(num_vertex);
|
---|
62 |
|
---|
63 | int ta=num_animations;
|
---|
64 |
|
---|
65 | fp->write_16(ta);
|
---|
66 | for (i=0; i<ta; i++)
|
---|
67 | {
|
---|
68 | fp->write_counted_str(*animation_names[i]);
|
---|
69 | int nf=animation[i].num_frames;
|
---|
70 | fp->write_16(nf);
|
---|
71 |
|
---|
72 | for (j=0; j<nf; j++)
|
---|
73 | {
|
---|
74 | g1_vert_class *v=get_verts(i,j);
|
---|
75 |
|
---|
76 | for (k=0; k<num_vertex; k++)
|
---|
77 | {
|
---|
78 | fp->write_float(v[k].v.x);
|
---|
79 | fp->write_float(v[k].v.y);
|
---|
80 | fp->write_float(v[k].v.z);
|
---|
81 |
|
---|
82 | fp->write_float(v[k].normal.x);
|
---|
83 | fp->write_float(v[k].normal.y);
|
---|
84 | fp->write_float(v[k].normal.z);
|
---|
85 | }
|
---|
86 | }
|
---|
87 | }
|
---|
88 | }
|
---|
89 | //}}}
|
---|
90 |
|
---|
91 | void m1_poly_object_class::save_mount_points(i4_saver_class *fp)
|
---|
92 | //{{{
|
---|
93 | {
|
---|
94 | int i,j;
|
---|
95 |
|
---|
96 | if (num_mounts==0)
|
---|
97 | return;
|
---|
98 |
|
---|
99 | fp->mark_section("GMOD Mounts");
|
---|
100 |
|
---|
101 | fp->write_16(num_mounts);
|
---|
102 | for (i=0; i<num_mounts; i++)
|
---|
103 | {
|
---|
104 | fp->write_counted_str(*mount_names[i]);
|
---|
105 |
|
---|
106 | fp->write_float(mount[i].x);
|
---|
107 | fp->write_float(mount[i].y);
|
---|
108 | fp->write_float(mount[i].z);
|
---|
109 | }
|
---|
110 | }
|
---|
111 | //}}}
|
---|
112 |
|
---|
113 | void m1_poly_object_class::save_specials(i4_saver_class *fp)
|
---|
114 | //{{{
|
---|
115 | {
|
---|
116 | int i,j;
|
---|
117 |
|
---|
118 | if (num_special==0)
|
---|
119 | return;
|
---|
120 |
|
---|
121 | fp->mark_section("GMOD Texture Animations");
|
---|
122 |
|
---|
123 | fp->write_16(num_special);
|
---|
124 | for (i=0; i<num_special; i++)
|
---|
125 | {
|
---|
126 | fp->write_format("211fff",
|
---|
127 | &special[i].quad_number,
|
---|
128 | &special[i].max_frames,
|
---|
129 | &special[i].frames_x,
|
---|
130 | &special[i].speed,
|
---|
131 | &special[i].du,
|
---|
132 | &special[i].dv);
|
---|
133 | }
|
---|
134 | }
|
---|
135 | //}}}
|
---|
136 |
|
---|
137 | void m1_poly_object_class::calc_quad_normal(g1_vert_class *v,
|
---|
138 | g1_quad_class &q)
|
---|
139 | //{{{
|
---|
140 | {
|
---|
141 | // find the surface normal used in lighting
|
---|
142 | i4_3d_point_class p[4];
|
---|
143 |
|
---|
144 | for (int i=0; i<q.num_verts(); i++)
|
---|
145 | p[i]=v[q.vertex_ref[i]].v;
|
---|
146 |
|
---|
147 | p[1] -= p[0];
|
---|
148 | p[2] -= p[0];
|
---|
149 |
|
---|
150 | q.set_flags(INVALID_QUAD,0);
|
---|
151 | if (q.num_verts()==3)
|
---|
152 | q.normal.cross(p[1], p[2]);
|
---|
153 | else
|
---|
154 | {
|
---|
155 | i4_3d_vector normal1, normal2;
|
---|
156 |
|
---|
157 | p[3] -= p[0];
|
---|
158 | normal1.cross(p[1], p[2]);
|
---|
159 | normal2.cross(p[2], p[3]);
|
---|
160 |
|
---|
161 | i4_float len1 = normal1.length();
|
---|
162 | i4_float len2 = normal2.length();
|
---|
163 |
|
---|
164 | if (len1>len2)
|
---|
165 | q.normal = normal1;
|
---|
166 | else
|
---|
167 | q.normal = normal2;
|
---|
168 |
|
---|
169 | if (len1==0.0 || len2==0.0)
|
---|
170 | // bad normal lengths
|
---|
171 | q.set_flags(INVALID_QUAD);
|
---|
172 | else
|
---|
173 | {
|
---|
174 | normal1 /= len1;
|
---|
175 | normal2 /= len2;
|
---|
176 |
|
---|
177 | if (normal1.dot(normal2)<0.5)
|
---|
178 | q.set_flags(INVALID_QUAD);
|
---|
179 | }
|
---|
180 | }
|
---|
181 |
|
---|
182 | if (q.normal.x==0 && q.normal.y==0 && q.normal.z==0)
|
---|
183 | {
|
---|
184 | // 0 check - invalid polygon!
|
---|
185 | q.normal=i4_3d_vector(0,0,1);
|
---|
186 | q.set_flags(INVALID_QUAD);
|
---|
187 | // i4_warning("very invalid polygon detected!");
|
---|
188 | }
|
---|
189 | else
|
---|
190 | q.normal.normalize();
|
---|
191 | }
|
---|
192 | //}}}
|
---|
193 |
|
---|
194 | void m1_poly_object_class::calc_vert_normals()
|
---|
195 | //{{{
|
---|
196 | {
|
---|
197 | for (int a=0; a<num_animations; a++)
|
---|
198 | {
|
---|
199 | // calculate normal for each face
|
---|
200 | for (w32 i=0; i<num_quad; i++)
|
---|
201 | calc_quad_normal(get_verts(0,0), quad[i]);
|
---|
202 |
|
---|
203 | for (w32 v=0; v<num_vertex; v++)
|
---|
204 | {
|
---|
205 | w32 t=0;
|
---|
206 | i4_3d_vector sum=i4_3d_vector(0,0,0);
|
---|
207 |
|
---|
208 | for (w32 j=0; j<num_quad; j++)
|
---|
209 | {
|
---|
210 | if (quad[j].vertex_ref[0]==v ||
|
---|
211 | quad[j].vertex_ref[1]==v ||
|
---|
212 | quad[j].vertex_ref[2]==v ||
|
---|
213 | quad[j].vertex_ref[3]==v)
|
---|
214 | {
|
---|
215 | t++;
|
---|
216 | sum+=quad[j].normal;
|
---|
217 | }
|
---|
218 | }
|
---|
219 |
|
---|
220 | if (sum.x==0 && sum.y==0 && sum.z==0)
|
---|
221 | sum.set(0,0,1);
|
---|
222 | else
|
---|
223 | sum.normalize();
|
---|
224 | (get_verts(a,0)+v)->normal=sum;
|
---|
225 | }
|
---|
226 | }
|
---|
227 | }
|
---|
228 | //}}}
|
---|
229 |
|
---|
230 | void m1_poly_object_class::save(i4_saver_class *fp)
|
---|
231 | //{{{
|
---|
232 | {
|
---|
233 | int i,j;
|
---|
234 | calc_vert_normals();
|
---|
235 |
|
---|
236 | save_texture_names(fp);
|
---|
237 | save_quads(fp);
|
---|
238 | save_vert_animations(fp);
|
---|
239 | save_mount_points(fp);
|
---|
240 | save_specials(fp);
|
---|
241 | }
|
---|
242 | //}}}
|
---|
243 |
|
---|
244 | void m1_poly_object_class::add_frame(w32 anim, w32 frame)
|
---|
245 | //{{{
|
---|
246 | {
|
---|
247 | i4_error("write me!");
|
---|
248 | }
|
---|
249 | //}}}
|
---|
250 |
|
---|
251 | void m1_poly_object_class::remove_frame(w32 anim, w32 frame)
|
---|
252 | //{{{
|
---|
253 | {
|
---|
254 | i4_error("write me!");
|
---|
255 | }
|
---|
256 | //}}}
|
---|
257 |
|
---|
258 | w32 m1_poly_object_class::add_vertex()
|
---|
259 | //{{{
|
---|
260 | {
|
---|
261 | i4_error("write me!");
|
---|
262 | return 0;
|
---|
263 | }
|
---|
264 | //}}}
|
---|
265 |
|
---|
266 | void m1_poly_object_class::remove_vertex(w32 num)
|
---|
267 | //{{{
|
---|
268 | {
|
---|
269 | i4_error("write me!");
|
---|
270 | }
|
---|
271 | //}}}
|
---|
272 |
|
---|
273 | w32 m1_poly_object_class::add_quad()
|
---|
274 | //{{{
|
---|
275 | {
|
---|
276 | g1_quad_class tmp;
|
---|
277 | w32 ret=quad_store.add(tmp);
|
---|
278 | texture_names.add(new i4_str(""));
|
---|
279 |
|
---|
280 | quad = &quad_store[0];
|
---|
281 | num_quad = quad_store.size();
|
---|
282 |
|
---|
283 | return ret;
|
---|
284 | }
|
---|
285 | //}}}
|
---|
286 |
|
---|
287 | void m1_poly_object_class::remove_quad(w32 num)
|
---|
288 | //{{{
|
---|
289 | {
|
---|
290 | int i=0;
|
---|
291 |
|
---|
292 | for (i=num_special-1; i>=0; i--)
|
---|
293 | {
|
---|
294 | if (special[i].quad_number == num)
|
---|
295 | remove_special(i);
|
---|
296 | else if (special[i].quad_number > num)
|
---|
297 | special[i].quad_number--;
|
---|
298 | }
|
---|
299 |
|
---|
300 | quad_store.remove(num);
|
---|
301 | texture_names.remove(num);
|
---|
302 | num_quad = quad_store.size();
|
---|
303 | }
|
---|
304 | //}}}
|
---|
305 |
|
---|
306 | w32 m1_poly_object_class::add_mount()
|
---|
307 | //{{{
|
---|
308 | {
|
---|
309 | w32 ret=mount_store.add(i4_3d_vector(0,0,0));
|
---|
310 | mount_id_store.add(0);
|
---|
311 | mount_names.add(new i4_str(""));
|
---|
312 |
|
---|
313 | mount = &mount_store[0];
|
---|
314 | num_mounts = mount_store.size();
|
---|
315 |
|
---|
316 | return ret;
|
---|
317 | }
|
---|
318 | //}}}
|
---|
319 |
|
---|
320 | void m1_poly_object_class::remove_mount(w32 num)
|
---|
321 | //{{{
|
---|
322 | {
|
---|
323 | int i=0;
|
---|
324 |
|
---|
325 | mount_store.remove(num);
|
---|
326 | mount_id_store.remove(num);
|
---|
327 | mount_names.remove(num);
|
---|
328 | num_mounts = mount_store.size();
|
---|
329 | }
|
---|
330 | //}}}
|
---|
331 |
|
---|
332 | w32 m1_poly_object_class::add_special(w32 quad_number)
|
---|
333 | //{{{
|
---|
334 | {
|
---|
335 | for (int i=0; i<num_special; i++)
|
---|
336 | if (special[i].quad_number==quad_number)
|
---|
337 | return i;
|
---|
338 |
|
---|
339 | g1_texture_animation tmp;
|
---|
340 | w32 ret=special_store.add(tmp);
|
---|
341 |
|
---|
342 | special = &special_store[0];
|
---|
343 | num_special = special_store.size();
|
---|
344 |
|
---|
345 | return ret;
|
---|
346 | }
|
---|
347 | //}}}
|
---|
348 |
|
---|
349 | void m1_poly_object_class::remove_special(w32 num)
|
---|
350 | //{{{
|
---|
351 | {
|
---|
352 | int i=0;
|
---|
353 |
|
---|
354 | special_store.remove(num);
|
---|
355 | num_special = quad_store.size();
|
---|
356 | }
|
---|
357 | //}}}
|
---|
358 |
|
---|
359 | void m1_poly_object_class::calc_texture_scales()
|
---|
360 | {
|
---|
361 | g1_vert_class *src_vert = get_verts(0,0);
|
---|
362 |
|
---|
363 | for (int i=0; i<num_quad; i++)
|
---|
364 | {
|
---|
365 | i4_3d_point_class *p1=&src_vert[quad[i].vertex_ref[0]].v;
|
---|
366 | i4_3d_point_class *p2=&src_vert[quad[i].vertex_ref[1]].v;
|
---|
367 |
|
---|
368 |
|
---|
369 | float edge_len=sqrt((p1->z-p2->z)*(p1->z-p2->z)+
|
---|
370 | (p1->y-p2->y)*(p1->y-p2->y)+
|
---|
371 | (p1->x-p2->x)*(p1->x-p2->x));
|
---|
372 |
|
---|
373 | float uv_length = sqrt ((quad[i].u[1]-quad[i].u[0]) * (quad[i].u[1]-quad[i].u[0]) +
|
---|
374 | (quad[i].v[1]-quad[i].v[0]) * (quad[i].v[1]-quad[i].v[0]));
|
---|
375 |
|
---|
376 |
|
---|
377 | quad[i].texture_scale=edge_len / uv_length;
|
---|
378 |
|
---|
379 | }
|
---|
380 |
|
---|
381 | }
|
---|
382 |
|
---|
383 |
|
---|
384 | //{{{ Emacs Locals
|
---|
385 | // Local Variables:
|
---|
386 | // folded-file: t
|
---|
387 | // End:
|
---|
388 | //}}}
|
---|