source: golgotha/src/golg/map_vis.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: 7.3 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 "map_cell.hh"
10#include <stdlib.h>
11#include "poly/polyclip.hh"
12#include "poly/polydraw.hh"
13#include "map.hh"
14#include "math/transform.hh"
15#include "time/profile.hh"
16#include "r1_api.hh"
17#include "g1_render.hh"
18#include "tile.hh"
19#include "map_vert.hh"
20#include "map_view.hh"
21
22static i4_profile_class pf_map_calc_visible("map::calc_visible");
23
24static int cell_compare(const void *a, const void *b)
25{
26  g1_map_vertex_class *v1=  g1_verts + ((g1_visible_cell *)a)->x +
27    ((g1_visible_cell *)a)->y * g1_map_width_plus_one;
28
29  g1_map_vertex_class *v2=  g1_verts + ((g1_visible_cell *)b)->x +
30    ((g1_visible_cell *)b)->y * g1_map_width_plus_one;
31
32  if (v1->v.z<v2->v.z)
33    return 1;
34  else if (v1->v.z>v2->v.z)
35    return -1;
36  else return 0;
37}
38
39
40class g1_map_clip_class
41{
42public:
43  i4_float cx2, cy2;
44
45  g1_map_clip_class(i4_float cx2, i4_float cy2)
46    : cx2(cx2), cy2(cy2) {}
47 
48  void project(i4_vertex_class *v)
49  {
50    v->px=v->v.x;
51    v->py=v->v.y;
52  }
53 
54  // used by poly_clip template function
55  i4_float intersect(i4_vertex_class *v1, i4_vertex_class *v2, int plane)
56  {
57    switch (plane)
58    {
59      case I4_CLIP_PLANE_Z1 :
60      case I4_CLIP_PLANE_Z2 :
61        return 0;
62
63      case I4_CLIP_PLANE_Y1 :
64      {
65        if (v1->v.y < v2->v.y)
66          return (0.0-v1->v.y)/(v2->v.y-v1->v.y);
67        else
68          return (v1->v.y)/(v1->v.y-v2->v.y);
69      } break;
70
71      case I4_CLIP_PLANE_Y2 :
72      {
73        if (v1->v.y < v2->v.y)
74          return (cy2-v1->v.y)/(v2->v.y-v1->v.y);
75        else
76          return (v1->v.y-cy2)/(v1->v.y-v2->v.y);
77      } break;
78
79      case I4_CLIP_PLANE_X1 :
80      {
81        if (v1->v.x < v2->v.x)
82          return (0.0-v1->v.x)/(v2->v.x-v1->v.x);
83        else
84          return (v1->v.x)/(v1->v.x-v2->v.x);
85      } break;
86
87      case I4_CLIP_PLANE_X2 :
88      {
89        if (v1->v.x < v2->v.x)
90          return (cx2-v1->v.x)/(v2->v.x-v1->v.x);
91        else
92          return (v1->v.x-cx2)/(v1->v.x-v2->v.x);
93      } break;
94
95    }
96    return 0;
97  }
98
99};
100
101class g1_vert_transformer
102{
103public:
104  w32 max_cells;
105  w32 t_cells;
106  g1_visible_cell *cell_list;
107  i4_transform_class t;
108  g1_map_vertex_class *verts;
109  int map_width_p1;
110  i4_float xscale, yscale;
111
112  void add_cell(w8 x, w8 y)
113  {
114    if (t_cells<max_cells)
115    {
116      cell_list[t_cells].x=x;
117      cell_list[t_cells].y=y;
118      t_cells++;
119    }
120  }
121
122  g1_vert_transformer(i4_transform_class &trans,
123                      g1_map_vertex_class *verts,
124                      int map_width_p1,
125                      g1_visible_cell *cell_list,
126                      w32 max_cells,
127                      i4_float xscale, i4_float yscale)
128
129
130    : verts(verts), map_width_p1(map_width_p1),
131      cell_list(cell_list), max_cells(max_cells),
132      xscale(xscale), yscale(yscale)
133  {
134    t=trans;
135    t_cells=0;   
136  }
137
138  int feature(int x) { return 0; }
139
140  class screen_pointer
141  {
142
143  public:
144    i4_3d_vector ground;
145    g1_map_vertex_class *v;
146    w8 x,y;
147
148    screen_pointer& operator=(const screen_pointer& p)
149    {
150      ground=p.ground;
151      v=p.v;
152      x=p.x;
153      y=p.y;
154      return *this;
155    }
156
157    void move_to(int _x, int _y, g1_vert_transformer &vp)
158    {
159      x=_x;
160      y=_y;
161      i4_3d_point_class g=i4_3d_point_class(_x,_y,0);
162      vp.t.transform(g, ground);
163      v=vp.verts + _x + _y * vp.map_width_p1;
164    }
165
166    void add(int amount, g1_vert_transformer &vp)
167    {
168      x+=amount;
169
170      ground.x += vp.t.x.x * amount;
171      ground.y += vp.t.x.y * amount;
172      ground.z += vp.t.x.z * amount;
173
174      v+=amount;
175    }
176
177    void next_line(g1_vert_transformer &vp)
178    {
179      y++;
180      ground.x+=vp.t.y.x;
181      ground.y+=vp.t.y.y;
182      ground.z+=vp.t.y.z;
183
184      v+=vp.map_width_p1;
185    }
186    int get_twidth(g1_vert_transformer &ref)
187    {
188      return 0;
189    }
190
191    w16 * get_ptr(g1_vert_transformer &ref)
192    {
193      return NULL;
194    }
195
196    i4_float * get_lookup(g1_vert_transformer &ref)
197    {
198      return NULL;
199    }
200
201    w16 * get_tptr(g1_vert_transformer &ref)
202    {
203      return NULL;
204    }
205
206    w32 get_screen_width(g1_vert_transformer &ref)
207    {
208      return 0;
209    }
210
211    void write(int s, int t,
212               i4_float w,
213               i4_float r, i4_float g, i4_float b, i4_float a,
214               g1_vert_transformer &vp)
215    {
216      if ((v->flags & g1_map_vertex_class::APPLY_WAVE_FUNCTION)==0)
217      {
218        i4_float h=v->get_height();
219        i4_3d_vector v_air;
220        v_air.x = (ground.x + h * vp.t.z.x) * vp.xscale;
221        v_air.y = (ground.y + h * vp.t.z.y) * vp.yscale;
222        v_air.z = ground.z + h * vp.t.z.z;
223     
224      //      v->transform(vp.t, x,y);
225
226        v->v=v_air;
227      }
228      else
229      {
230        v->wave_transform(vp.t, x, y);
231        v->v.x *= vp.xscale;
232        v->v.y *= vp.yscale;
233      }
234
235
236      v->set_is_transformed(1);
237
238      vp.add_cell(x,y);
239    }
240  }; 
241};
242
243
244
245int g1_map_class::calc_visible(i4_transform_class &t,
246                               i4_polygon_class *area_poly,
247                               g1_visible_cell *buffer, w32 buf_elements,
248                               i4_float xscale, i4_float yscale)
249{
250  pf_map_calc_visible.start();
251
252  int ret=0,i;
253
254  i4_polygon_class poly, clipped_poly;
255
256  for (i =0; i<area_poly->t_verts; i++)
257  {
258    area_poly->vert[i].px=area_poly->vert[i].v.x;
259    area_poly->vert[i].py=area_poly->vert[i].v.y;
260  }
261
262  poly=*area_poly;
263  g1_map_clip_class cell_clip(width(), height());
264  i4_poly_clip(cell_clip, poly, clipped_poly,
265               (float)0.0,(float)0.0,(float) -1.0,
266               (float)(width()),
267               (float)(height()), (float)1.0);
268
269
270  if (clipped_poly.t_verts>=3)
271  {
272    g1_vert_transformer vt(t,
273                           verts, width()+1,
274                           buffer, buf_elements,
275                           xscale, yscale);
276
277
278    i4_poly_draw_class<g1_vert_transformer> draw(vt, clipped_poly);
279    ret=vt.t_cells;
280  }
281
282
283  for (i=0; i<ret; i++)
284    if (buffer[i].x>=width() || buffer[i].y>=height())
285    {
286      i4_warning("bad cell");
287      return 0;
288    }
289     
290
291  g1_radar_looking_at(clipped_poly.vert[0].v.x,
292                      clipped_poly.vert[0].v.y,
293                      clipped_poly.vert[2].v.x,
294                      clipped_poly.vert[2].v.y);
295                     
296
297  if (ret)
298  {
299    //if we're using a software rasterizer, must sort the cells (technically not necessary anymore)
300    //if (g1_render.r_api->get_render_device_flags() & R1_SOFTWARE)
301      //qsort(buffer, ret, sizeof(g1_visible_cell), cell_compare);
302   
303    //else
304      //sort the cells by texture
305      //qsort(buffer, ret, sizeof(g1_visible_cell), cell_texture_compare);
306  }
307
308  pf_map_calc_visible.stop();
309  return ret;
310}
311
312
313
Note: See TracBrowser for help on using the repository browser.