source: golgotha/src/maxtool/max_object.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 12 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 8.0 KB
Line 
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
15void 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
43void 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
54void 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
91void 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
113void 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
137void 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
194void 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
230void 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
244void m1_poly_object_class::add_frame(w32 anim, w32 frame)
245//{{{
246{
247  i4_error("write me!");
248}
249//}}}
250
251void m1_poly_object_class::remove_frame(w32 anim, w32 frame)
252//{{{
253{
254  i4_error("write me!");
255}
256//}}}
257
258w32 m1_poly_object_class::add_vertex()
259//{{{
260{
261  i4_error("write me!");
262  return 0;
263}
264//}}}
265
266void m1_poly_object_class::remove_vertex(w32 num)
267//{{{
268{
269  i4_error("write me!");
270}
271//}}}
272
273w32 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
287void 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
306w32 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
320void 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
332w32 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
349void 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
359void 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//}}}
Note: See TracBrowser for help on using the repository browser.