source: golgotha/src/golg/frustrum_clip.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: 12.8 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 "frustrum_clip.hh"
10#include "poly/poly.hh"
11#include "math/num_type.hh"
12#include "clip.hh"
13
14#define F_NEXT(i,j) ( ((i+1)==(j))?(0):(i+1) )
15#define F_PREV(i,j) ( ((i)==(0))?(j-1):(i-1) )
16
17#include "arch.hh"
18#include "math/num_type.hh"
19#include "frustrum_clip.hh"
20#include "poly/poly.hh"
21
22i4_polygon_class *g1_full_clip(i4_polygon_class *src,
23                               i4_polygon_class *dest,
24                               w32 center_x, w32 center_y)
25{
26  w32 ORCODE  = 0;
27  w32 ANDCODE = 0xffffffff;
28  w32 i,j,c0,c1;
29  w32 bitmask;
30  i4_float ooz,dx,dy,dz,ds,dt,dr,dg,db,da,t;
31  i4_polygon_class *temp;
32  i4_vertex_class *v,clippoint;   
33 
34  dest->t_verts=0;
35 
36  for (i=0; i<src->t_verts; i++)
37  {   
38    v = &src->vert[i];
39    v->outcode = g1_calc_clip_code(v->v, 0.01f, 0, i4_F);
40
41    ORCODE  |= v->outcode;
42    ANDCODE &= v->outcode;     
43    if (!v->outcode)
44    {
45      ooz = r1_ooz(v->v.z);
46      v->w  = ooz;
47      v->px = ((v->v.x * ooz) * center_x) + center_x;
48      v->py = ((v->v.y * ooz) * center_y) + center_y;       
49    }
50  }
51 
52  //all verts are outside one of the view planes
53  //return a poly with 0 vertices
54  if (ANDCODE)
55  {
56    dest->t_verts=0;
57    return dest;
58  }
59 
60  if (!ORCODE)
61  {
62    return src;
63  }
64 
65  for (bitmask=16;bitmask;bitmask=bitmask>>1)
66  {
67    if ((bitmask&ORCODE)==0) continue;
68   
69    for (i=0;i<src->t_verts;i++)
70    {                   
71     
72      j  = F_NEXT(i,src->t_verts);
73     
74      c0 = bitmask & src->vert[i].outcode;
75      c1 = bitmask & src->vert[j].outcode;
76     
77      //if c0 is not outside of this plane,
78      //add it
79      if (c0==0) {
80        dest->add_vert(&src->vert[i]);
81      }
82     
83      //if they are on the same
84      //side, move to the next vert
85      if (c0==c1) continue;
86     
87      //otherwise, generate a clipped
88      //point
89     
90      dx = src->vert[j].v.x - src->vert[i].v.x;
91      dy = src->vert[j].v.y - src->vert[i].v.y;
92      dz = src->vert[j].v.z - src->vert[i].v.z;
93      ds = src->vert[j].s - src->vert[i].s;
94      dt = src->vert[j].t - src->vert[i].t;
95      dr = src->vert[j].r - src->vert[i].r;
96      dg = src->vert[j].g - src->vert[i].g;
97      db = src->vert[j].b - src->vert[i].b;
98      da = src->vert[j].a - src->vert[i].a;
99     
100     
101
102      switch (bitmask) {
103        case 1:  t = (-src->vert[i].v.x + src->vert[i].v.z) / ( dx - dz);                 
104                 clippoint.v.y = src->vert[i].v.y + (t * dy);
105                 clippoint.v.z = src->vert[i].v.z + (t * dz);
106                 
107                 clippoint.v.x = clippoint.v.z;
108                 break;
109
110        case 2:  t = ( src->vert[i].v.x + src->vert[i].v.z) / (-dx - dz);                 
111                 clippoint.v.y = src->vert[i].v.y + (t * dy);
112                 clippoint.v.z = src->vert[i].v.z + (t * dz);
113                 
114                 clippoint.v.x = -clippoint.v.z;
115                 break;
116       
117        case 4:  t = (-src->vert[i].v.y + src->vert[i].v.z) / ( dy - dz);
118                 clippoint.v.x = src->vert[i].v.x + (t * dx);                 
119                 clippoint.v.z = src->vert[i].v.z + (t * dz);
120                 
121                 clippoint.v.y = clippoint.v.z;
122                 break;
123       
124        case 8:  t = ( src->vert[i].v.y + src->vert[i].v.z) / (-dy - dz);
125                 clippoint.v.x = src->vert[i].v.x + (t * dx);                 
126                 clippoint.v.z = src->vert[i].v.z + (t * dz);
127                 
128                 clippoint.v.y = -clippoint.v.z;
129                 break;
130
131        case 16: t = (0.01 - src->vert[i].v.z) / (dz);                         
132                 clippoint.v.x = src->vert[i].v.x + (t * dx);
133                 clippoint.v.y = src->vert[i].v.y + (t * dy);
134                 
135                 clippoint.v.z = 0.01;
136                 break;
137      }
138     
139      clippoint.s = src->vert[i].s + (t * ds);
140      clippoint.t = src->vert[i].t + (t * dt);
141      clippoint.r = src->vert[i].r + (t * dr);
142      clippoint.g = src->vert[i].g + (t * dg);
143      clippoint.b = src->vert[i].b + (t * db);
144      clippoint.a = src->vert[i].a + (t * da);
145     
146      // no far clip
147      clippoint.outcode = g1_calc_clip_code(clippoint.v, 0.01f, 0, i4_F);
148
149      if (!clippoint.outcode)
150      {
151        ooz = r1_ooz(clippoint.v.z);       
152        clippoint.px = ((clippoint.v.x * ooz) * center_x) + center_x;
153        clippoint.py = ((clippoint.v.y * ooz) * center_y) + center_y;         
154        clippoint.w  = ooz;
155      } 
156      ORCODE |= clippoint.outcode;
157     
158      dest->add_vert(&clippoint);     
159    }
160   
161    temp = src;
162    src = dest;
163    dest = temp;
164    dest->t_verts = 0;
165  }
166  return src;
167}
168
169i4_polygon_class *g1_fast_full_clip(i4_polygon_class *src,
170                                    i4_polygon_class *dest,
171                                    w32 center_x, w32 center_y)
172{
173  w32 ORCODE  = 0;   
174  w32 i,j,c0,c1;
175  w32 bitmask;
176  i4_float ooz,dx,dy,dz,ds,dt,dr,da,t;
177  i4_polygon_class *temp;
178  i4_vertex_class *v,clippoint;   
179 
180  dest->t_verts=0;
181 
182  for (i=0; i<src->t_verts; i++)
183  {     
184    v = &src->vert[i];
185    v->outcode = g1_calc_clip_code(v->v, 0.01f, 0, i4_F);
186
187    ORCODE |= v->outcode;   
188  }
189 
190  for (bitmask=16;bitmask;bitmask=bitmask>>1)
191  {
192    if ((bitmask&ORCODE)==0) continue;
193   
194    for (i=0;i<src->t_verts;i++)
195    {                   
196     
197      j  = F_NEXT(i,src->t_verts);
198     
199      c0 = bitmask & src->vert[i].outcode;
200      c1 = bitmask & src->vert[j].outcode;
201     
202      //if c0 is not outside of this plane,
203      //add it
204      if (c0==0) {
205        dest->add_vert(&src->vert[i]);
206      }
207     
208      //if they are on the same
209      //side, move to the next vert
210      if (c0==c1) continue;
211     
212      //otherwise, generate a clipped
213      //point
214     
215      dx = src->vert[j].v.x - src->vert[i].v.x;
216      dy = src->vert[j].v.y - src->vert[i].v.y;
217      dz = src->vert[j].v.z - src->vert[i].v.z;
218      ds = src->vert[j].s - src->vert[i].s;
219      dt = src->vert[j].t - src->vert[i].t;
220      dr = src->vert[j].r - src->vert[i].r;
221      da = src->vert[j].a - src->vert[i].a;
222
223      switch (bitmask) {
224        case 1:  t = (-src->vert[i].v.x + src->vert[i].v.z) / ( dx - dz);                 
225                 clippoint.v.y = src->vert[i].v.y + (t * dy);
226                 clippoint.v.z = src->vert[i].v.z + (t * dz);
227                 
228                 clippoint.v.x = clippoint.v.z;
229                 break;
230
231        case 2:  t = ( src->vert[i].v.x + src->vert[i].v.z) / (-dx - dz);                 
232                 clippoint.v.y = src->vert[i].v.y + (t * dy);
233                 clippoint.v.z = src->vert[i].v.z + (t * dz);
234                 
235                 clippoint.v.x = -clippoint.v.z;
236                 break;
237       
238        case 4:  t = (-src->vert[i].v.y + src->vert[i].v.z) / ( dy - dz);
239                 clippoint.v.x = src->vert[i].v.x + (t * dx);                 
240                 clippoint.v.z = src->vert[i].v.z + (t * dz);
241                 
242                 clippoint.v.y = clippoint.v.z;
243                 break;
244       
245        case 8:  t = ( src->vert[i].v.y + src->vert[i].v.z) / (-dy - dz);
246                 clippoint.v.x = src->vert[i].v.x + (t * dx);
247                 clippoint.v.y = src->vert[i].v.y + (t * dy);
248                 clippoint.v.z = src->vert[i].v.z + (t * dz);
249                 
250                 clippoint.v.y = -clippoint.v.z;
251                 break;
252
253        case 16: t = (0.01 - src->vert[i].v.z) / (dz);                         
254                 clippoint.v.x = src->vert[i].v.x + (t * dx);
255                 clippoint.v.y = src->vert[i].v.y + (t * dy);
256                 
257                 clippoint.v.z = 0.01;
258                 break;
259      }
260     
261      clippoint.s = src->vert[i].s + (t * ds);
262      clippoint.t = src->vert[i].t + (t * dt);
263      clippoint.r = src->vert[i].r + (t * dr);
264     
265      clippoint.outcode =  g1_calc_clip_code(clippoint.v, 0.01f, 0, i4_F);
266
267      if (!clippoint.outcode)
268      {
269        ooz = r1_ooz(clippoint.v.z);
270        clippoint.px = ((clippoint.v.x * ooz) * center_x) + center_x;
271        clippoint.py = ((clippoint.v.y * ooz) * center_y) + center_y;             
272        clippoint.w  = ooz;
273      }
274     
275      ORCODE |= clippoint.outcode;
276     
277      dest->add_vert(&clippoint);     
278    }
279   
280    temp = src;
281    src = dest;
282    dest = temp;
283    dest->t_verts = 0;
284  }
285  return src;
286}
287
288//only clips x,y,z
289i4_polygon_class *g1_geometric_clip(i4_polygon_class *src,
290                                    i4_polygon_class *dest,
291                                    w32 center_x, w32 center_y)
292{
293  w32 ORCODE  = 0;
294  w32 ANDCODE = 0xffffffff;
295  w32 i,j,c0,c1;
296  w32 bitmask;
297  i4_float ooz,dx,dy,dz,t;
298  i4_polygon_class *temp;
299  i4_vertex_class *v,clippoint;   
300 
301  dest->t_verts=0;
302 
303  for (i=0; i<src->t_verts; i++)
304  {   
305    v = &src->vert[i];
306    v->outcode = g1_calc_clip_code(v->v, 0.01f, 0, i4_F);
307
308    ORCODE  |= v->outcode;
309    ANDCODE &= v->outcode;     
310    if (!v->outcode)
311    {
312      ooz = r1_ooz(v->v.z);
313      v->px = ((v->v.x * ooz) * center_x) + center_x;
314      v->py = ((v->v.y * ooz) * center_y) + center_y;
315      v->w  = ooz;
316    }
317  }
318 
319  //all verts are outside one of the view planes
320  //return a poly with 0 vertices
321  if (ANDCODE)
322  {
323    dest->t_verts=0;
324    return dest;
325  }
326 
327  if (!ORCODE)
328  {
329    return src;
330  }
331 
332  for (bitmask=16;bitmask;bitmask=bitmask>>1)
333  {
334    if ((bitmask&ORCODE)==0) continue;
335   
336    for (i=0;i<src->t_verts;i++)
337    {                   
338     
339      j  = F_NEXT(i,src->t_verts);
340     
341      c0 = bitmask & src->vert[i].outcode;
342      c1 = bitmask & src->vert[j].outcode;
343     
344      //if c0 is not outside of this plane,
345      //add it
346      if (c0==0) {
347        dest->add_vert(&src->vert[i]);
348      }
349     
350      //if they are on the same
351      //side, move to the next vert
352      if (c0==c1) continue;
353     
354      //otherwise, generate a clipped
355      //point
356     
357      dx = src->vert[j].v.x - src->vert[i].v.x;
358      dy = src->vert[j].v.y - src->vert[i].v.y;
359      dz = src->vert[j].v.z - src->vert[i].v.z;
360     
361      switch (bitmask) {
362        case 1:  t = (-src->vert[i].v.x + src->vert[i].v.z) / ( dx - dz);                 
363                 clippoint.v.y = src->vert[i].v.y + (t * dy);
364                 clippoint.v.z = src->vert[i].v.z + (t * dz);
365                 
366                 clippoint.v.x = clippoint.v.z;
367                 break;
368
369        case 2:  t = ( src->vert[i].v.x + src->vert[i].v.z) / (-dx - dz);                 
370                 clippoint.v.y = src->vert[i].v.y + (t * dy);
371                 clippoint.v.z = src->vert[i].v.z + (t * dz);
372                 
373                 clippoint.v.x = -clippoint.v.z;
374                 break;
375       
376        case 4:  t = (-src->vert[i].v.y + src->vert[i].v.z) / ( dy - dz);
377                 clippoint.v.x = src->vert[i].v.x + (t * dx);                 
378                 clippoint.v.z = src->vert[i].v.z + (t * dz);
379                 
380                 clippoint.v.y = clippoint.v.z;
381                 break;
382       
383        case 8:  t = ( src->vert[i].v.y + src->vert[i].v.z) / (-dy - dz);
384                 clippoint.v.x = src->vert[i].v.x + (t * dx);
385                 clippoint.v.y = src->vert[i].v.y + (t * dy);
386                 clippoint.v.z = src->vert[i].v.z + (t * dz);
387                 
388                 clippoint.v.y = -clippoint.v.z;
389                 break;
390
391        case 16: t = (0.01 - src->vert[i].v.z) / (dz);                         
392                 clippoint.v.x = src->vert[i].v.x + (t * dx);
393                 clippoint.v.y = src->vert[i].v.y + (t * dy);
394                 
395                 clippoint.v.z = 0.01;
396                 break;
397      }
398           
399      clippoint.outcode = g1_calc_clip_code(v->v, 0.01f, 0, i4_F);
400
401      if (!clippoint.outcode)
402      {
403        ooz = r1_ooz(clippoint.v.z);
404        clippoint.px = ((clippoint.v.x * ooz) * center_x) + center_x;
405        clippoint.py = ((clippoint.v.y * ooz) * center_y) + center_y;             
406        clippoint.w  = ooz;
407      }
408     
409      ORCODE |= clippoint.outcode;
410     
411      dest->add_vert(&clippoint);     
412    }
413   
414    temp = src;
415    src = dest;
416    dest = temp;
417    dest->t_verts = 0;
418  }
419  return src;
420}
421
Note: See TracBrowser for help on using the repository browser.