FS2_Open
Open source remastering of the Freespace 2 engine
3dclipper.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) Volition, Inc. 1999. All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell
5  * or otherwise commercially exploit the source or things you created based on the
6  * source.
7  *
8 */
9 
10 
11 
12 #include "graphics/tmapper.h"
13 #include "render/3dinternal.h"
14 
15 
17 
20 
21 void init_free_points(void)
22 {
23  int i;
24 
25  for (i=0;i<TMAP_MAX_VERTS;i++)
26  free_points[i] = &temp_points[i];
27 }
28 
29 
31 {
32  vertex *p;
33 
34  p = free_points[free_point_num++];
35 
36  p->flags = PF_TEMP_POINT;
37 
38  return p;
39 }
40 
41 
43 {
45 
46  free_points[--free_point_num] = p;
47 
48  p->flags &= ~PF_TEMP_POINT;
49 }
50 
51 
55 vertex *clip_edge(int plane_flag,vertex *on_pnt,vertex *off_pnt, uint flags)
56 {
57  float ratio;
58  vertex *tmp;
59 
60  tmp = get_temp_point();
61 
62  if ( plane_flag & CC_OFF_USER ) {
63 
64  // Clip with user-defined plane
65  vec3d w, ray_direction;
66  float num,den;
67 
68  vm_vec_sub(&ray_direction,&off_pnt->world,&on_pnt->world);
69 
70  vm_vec_sub(&w,&on_pnt->world,&G3_user_clip_point);
71 
72  den = -vm_vec_dot(&G3_user_clip_normal,&ray_direction);
73  if ( den == 0.0f ) { // Ray & plane are parallel, so there is no intersection
74  Int3(); // Get John
75  ratio = 1.0f;
76  } else {
78 
79  ratio = num / den;
80  }
81 
82  vm_vec_sub(&tmp->world, &off_pnt->world, &on_pnt->world);
83  vm_vec_scale(&tmp->world, ratio);
84  vm_vec_add2(&tmp->world, &on_pnt->world);
85 
86  } else {
87  float a,b,kn,kd;
88 
89  //compute clipping value k = (xs-zs) / (xs-xe-zs+ze)
90  //use x or y as appropriate, and negate x/y value as appropriate
91 
92  if (plane_flag & (CC_OFF_RIGHT | CC_OFF_LEFT)) {
93  a = on_pnt->world.xyz.x;
94  b = off_pnt->world.xyz.x;
95  }
96  else {
97  a = on_pnt->world.xyz.y;
98  b = off_pnt->world.xyz.y;
99  }
100 
101  if (plane_flag & (CC_OFF_LEFT | CC_OFF_BOT)) {
102  a = -a;
103  b = -b;
104  }
105 
106  kn = a - on_pnt->world.xyz.z; //xs-zs
107  kd = kn - b + off_pnt->world.xyz.z; //xs-zs-xe+ze
108 
109  ratio = kn / kd;
110 
111  tmp->world.xyz.x = on_pnt->world.xyz.x + (off_pnt->world.xyz.x-on_pnt->world.xyz.x) * ratio;
112  tmp->world.xyz.y = on_pnt->world.xyz.y + (off_pnt->world.xyz.y-on_pnt->world.xyz.y) * ratio;
113 
114  if (plane_flag & (CC_OFF_TOP|CC_OFF_BOT)) {
115  tmp->world.xyz.z = tmp->world.xyz.y;
116  } else {
117  tmp->world.xyz.z = tmp->world.xyz.x;
118  }
119 
120  if (plane_flag & (CC_OFF_LEFT|CC_OFF_BOT))
121  tmp->world.xyz.z = -tmp->world.xyz.z;
122 
123  }
124 
125  if (flags & TMAP_FLAG_TEXTURED) {
126  tmp->texture_position.u = on_pnt->texture_position.u + (off_pnt->texture_position.u-on_pnt->texture_position.u) * ratio;
127  tmp->texture_position.v = on_pnt->texture_position.v + (off_pnt->texture_position.v-on_pnt->texture_position.v) * ratio;
128  }
129 
130  if (flags & TMAP_FLAG_GOURAUD ) {
131  if (flags & TMAP_FLAG_RAMP) {
132 
133  float on_b, off_b;
134 
135  on_b = i2fl(on_pnt->b);
136  off_b = i2fl(off_pnt->b);
137 
138  tmp->b = ubyte(fl2i(on_b + (off_b-on_b) * ratio));
139  }
140  if (flags & TMAP_FLAG_RGB) {
141  float on_r, on_b, on_g, onspec_r, onspec_g, onspec_b;
142  float off_r, off_b, off_g, offspec_r, offspec_g, offspec_b;
143 
144  on_r = i2fl(on_pnt->r);
145  off_r = i2fl(off_pnt->r);
146 
147  on_g = i2fl(on_pnt->g);
148  off_g = i2fl(off_pnt->g);
149 
150  on_b = i2fl(on_pnt->b);
151  off_b = i2fl(off_pnt->b);
152 
153 
154  onspec_r = i2fl(on_pnt->spec_r);
155  offspec_r = i2fl(off_pnt->spec_r);
156 
157  onspec_g = i2fl(on_pnt->spec_g);
158  offspec_g = i2fl(off_pnt->spec_g);
159 
160  onspec_b = i2fl(on_pnt->spec_b);
161  offspec_b = i2fl(off_pnt->spec_b);
162 
163 
164  tmp->r = ubyte(fl2i(on_r + (off_r-on_r) * ratio));
165  tmp->g = ubyte(fl2i(on_g + (off_g-on_g) * ratio));
166  tmp->b = ubyte(fl2i(on_b + (off_b-on_b) * ratio));
167 
168  tmp->spec_r = ubyte(fl2i(onspec_r + (offspec_r-onspec_r) * ratio));
169  tmp->spec_g = ubyte(fl2i(onspec_g + (offspec_g-onspec_g) * ratio));
170  tmp->spec_b = ubyte(fl2i(onspec_b + (offspec_b-onspec_b) * ratio));
171  }
172  }
173  else
174  {
175  tmp->spec_r=tmp->spec_g=tmp->spec_b=0;
176  }
177 
178  if (flags & TMAP_FLAG_ALPHA) {
179 
180  float on_a, off_a;
181 
182  on_a = i2fl(on_pnt->a);
183  off_a = i2fl(off_pnt->a);
184 
185  tmp->a = ubyte(fl2i(on_a + (off_a-on_a) * ratio));
186  }
187 
188  g3_code_vertex(tmp);
189 
190  return tmp;
191 }
192 
193 
197 void clip_line(vertex **p0,vertex **p1,ubyte codes_or, uint flags)
198 {
199  int plane_flag;
200  vertex *old_p1;
201 
202  for (plane_flag=1;plane_flag<=CC_OFF_USER;plane_flag<<=1)
203  if (codes_or & plane_flag) {
204 
205  if ((*p0)->codes & plane_flag)
206  {vertex *t=*p0; *p0=*p1; *p1=t;} //swap!
207 
208  old_p1 = *p1;
209 
210  *p1 = clip_edge(plane_flag,*p0,*p1,flags);
211  codes_or = (unsigned char)((*p0)->codes | (*p1)->codes); //get new codes
212 
213  if (old_p1->flags & PF_TEMP_POINT)
214  free_temp_point(old_p1);
215  }
216 
217 }
218 
222 int clip_plane(int plane_flag,vertex **src,vertex **dest,int *nv,ccodes *cc,uint flags)
223 {
224  int i;
225  vertex **save_dest=dest;
226 
227  //copy first two verts to end
228  src[*nv] = src[0];
229  src[*nv+1] = src[1];
230 
231  cc->cc_and = 0xff;
232  cc->cc_or = 0;
233 
234  for (i=1;i<=*nv;i++) {
235 
236  if (src[i]->codes & plane_flag) { //cur point off?
237 
238  if (! (src[i-1]->codes & plane_flag)) { //prev not off?
239 
240  *dest = clip_edge(plane_flag,src[i-1],src[i],flags);
241  cc->cc_or |= (*dest)->codes;
242  cc->cc_and &= (*dest)->codes;
243  dest++;
244  }
245 
246  if (! (src[i+1]->codes & plane_flag)) {
247 
248  *dest = clip_edge(plane_flag,src[i+1],src[i],flags);
249  cc->cc_or |= (*dest)->codes;
250  cc->cc_and &= (*dest)->codes;
251  dest++;
252  }
253 
254  //see if must free discarded point
255 
256  if (src[i]->flags & PF_TEMP_POINT)
257  free_temp_point(src[i]);
258  }
259  else { //cur not off, copy to dest buffer
260 
261  *dest++ = src[i];
262 
263  cc->cc_or |= src[i]->codes;
264  cc->cc_and &= src[i]->codes;
265  }
266  }
267 
268  return (dest-save_dest);
269 }
270 
275 {
276  int plane_flag;
277  vertex **t;
278 
279  for (plane_flag=1;plane_flag<=CC_OFF_USER;plane_flag<<=1)
280 
281  if (cc->cc_or & plane_flag) {
282 
283  *nv = clip_plane(plane_flag,src,dest,nv,cc,flags);
284 
285  if (cc->cc_and) //clipped away
286  return dest;
287 
288  t = src; src = dest; dest = t;
289 
290  }
291 
292  return src; //we swapped after we copied
293 }
#define CC_OFF_BOT
Definition: 3d.h:28
int i
Definition: multi_pxo.cpp:466
ubyte spec_g
Definition: pstypes.h:176
ubyte cc_or
Definition: pstypes.h:71
float v
Definition: pstypes.h:135
ubyte g
Definition: pstypes.h:175
Assert(pm!=NULL)
Definition: pstypes.h:88
hull_check p0
Definition: lua.cpp:5051
void init_free_points(void)
Definition: 3dclipper.cpp:21
struct vec3d::@225::@227 xyz
GLclampf f
Definition: Glext.h:7097
void free_temp_point(vertex *p)
Definition: 3dclipper.cpp:42
ubyte spec_b
Definition: pstypes.h:176
ubyte g3_code_vertex(vertex *point)
Definition: 3dmath.cpp:54
#define Int3()
Definition: pstypes.h:292
#define CC_OFF_USER
Definition: 3d.h:30
vertex * free_points[TMAP_MAX_VERTS]
Definition: 3dclipper.cpp:19
ubyte spec_r
Definition: pstypes.h:176
uv_pair texture_position
Definition: pstypes.h:174
ubyte a
Definition: pstypes.h:175
void vm_vec_add2(vec3d *dest, const vec3d *src)
Definition: vecmat.cpp:178
Definition: pstypes.h:70
unsigned int uint
Definition: pstypes.h:64
void vm_vec_scale(vec3d *dest, float s)
Definition: vecmat.cpp:248
#define TMAP_FLAG_GOURAUD
Definition: tmapper.h:40
GLboolean GLboolean GLboolean GLboolean a
Definition: Glext.h:5781
int clip_plane(int plane_flag, vertex **src, vertex **dest, int *nv, ccodes *cc, uint flags)
Clips a plane to the viewing pyramid.
Definition: 3dclipper.cpp:222
vertex * clip_edge(int plane_flag, vertex *on_pnt, vertex *off_pnt, uint flags)
Clips an edge against one plane.
Definition: 3dclipper.cpp:55
#define PF_TEMP_POINT
Definition: 3d.h:23
#define w(p)
Definition: modelsinc.h:68
hull_check p1
Definition: lua.cpp:5052
float u
Definition: pstypes.h:135
#define CC_OFF_RIGHT
Definition: 3d.h:27
GLdouble GLdouble t
Definition: Glext.h:5329
unsigned char ubyte
Definition: pstypes.h:62
vertex ** clip_polygon(vertex **src, vertex **dest, int *nv, ccodes *cc, uint flags)
Clips a polygon to the viewing pyramid.
Definition: 3dclipper.cpp:274
ubyte cc_and
Definition: pstypes.h:71
#define TMAP_FLAG_RGB
Definition: tmapper.h:39
ubyte b
Definition: pstypes.h:175
ubyte flags
Definition: pstypes.h:178
GLbitfield flags
Definition: Glext.h:6722
void vm_vec_sub(vec3d *dest, const vec3d *src0, const vec3d *src1)
Definition: vecmat.cpp:168
GLboolean GLboolean GLboolean b
Definition: Glext.h:5781
GLuint GLuint num
Definition: Glext.h:9089
#define CC_OFF_TOP
Definition: 3d.h:29
#define fl2i(fl)
Definition: floating.h:33
int free_point_num
Definition: 3dclipper.cpp:16
GLfloat GLfloat p
Definition: Glext.h:8373
GLenum src
Definition: Glext.h:5917
#define TMAP_FLAG_ALPHA
Definition: tmapper.h:53
#define TMAP_FLAG_TEXTURED
Definition: tmapper.h:36
vertex temp_points[TMAP_MAX_VERTS]
Definition: 3dclipper.cpp:18
float vm_vec_dot(const vec3d *v0, const vec3d *v1)
Definition: vecmat.cpp:312
#define i2fl(i)
Definition: floating.h:32
vec3d G3_user_clip_point
Definition: 3dsetup.cpp:362
#define TMAP_FLAG_RAMP
Definition: tmapper.h:38
vec3d world
Definition: pstypes.h:172
#define TMAP_MAX_VERTS
Definition: tmapper.h:33
ubyte codes
Definition: pstypes.h:177
vertex * get_temp_point()
Definition: 3dclipper.cpp:30
vec3d G3_user_clip_normal
Definition: 3dsetup.cpp:361
void clip_line(vertex **p0, vertex **p1, ubyte codes_or, uint flags)
Clips a line to the viewing pyramid.
Definition: 3dclipper.cpp:197
#define CC_OFF_LEFT
Definition: 3d.h:26
ubyte r
Definition: pstypes.h:175