DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
convex.h File Reference
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  convex_builder_state_t
 
struct  convex_corner_t
 
struct  convex_face_t
 

Enumerations

enum  convex_enums { CONVEX_MAX_CORNERS = 256 , CONVEX_MAX_FACES = 1024 }
 

Functions

void convex_builder_add_point (convex_builder_state_t *b, float x, float y, float z)
 
int convex_builder_get_planes4f (convex_builder_state_t *b, float *outplanes4f, int maxplanes, int positivew)
 
int convex_builder_get_points3f (convex_builder_state_t *b, float *outpoints3f, int maxpoints)
 
void convex_builder_initialize (convex_builder_state_t *b, float epsilon)
 

Enumeration Type Documentation

◆ convex_enums

Enumerator
CONVEX_MAX_CORNERS 
CONVEX_MAX_FACES 

Definition at line 31 of file convex.h.

32{
34 CONVEX_MAX_FACES = 1024,
35};
@ CONVEX_MAX_CORNERS
Definition convex.h:33
@ CONVEX_MAX_FACES
Definition convex.h:34

Function Documentation

◆ convex_builder_add_point()

void convex_builder_add_point ( convex_builder_state_t * b,
float x,
float y,
float z )

Definition at line 39 of file convex.c.

40{
41 int i, j, l;
42 convex_corner_t corner;
43 unsigned char removedcorner[CONVEX_MAX_CORNERS];
44 unsigned char removedface[CONVEX_MAX_FACES];
45
46 // we can't add any new points after max generations is reached
47 if (b->numcorners > CONVEX_MAX_CORNERS - 1 || b->numfaces > CONVEX_MAX_FACES - b->numcorners - 2)
48 return;
49
50 // make a corner struct with the same layout we expect to use for vector ops
51 corner.x = x;
52 corner.y = y;
53 corner.z = z;
54 corner.w = 1.0f;
55
56 float epsilon = b->epsilon;
57
58 // add the new corner to the bounding box
59 if (b->numcorners == 0)
60 {
61 b->extents[0][0] = corner.x;
62 b->extents[0][1] = corner.y;
63 b->extents[0][2] = corner.z;
64 b->extents[1][0] = corner.x;
65 b->extents[1][1] = corner.y;
66 b->extents[1][2] = corner.z;
67 }
68 else
69 {
70 if (b->extents[0][0] > corner.x)
71 b->extents[0][0] = corner.x;
72 if (b->extents[0][1] > corner.y)
73 b->extents[0][1] = corner.y;
74 if (b->extents[0][2] > corner.z)
75 b->extents[0][2] = corner.z;
76 if (b->extents[1][0] < corner.x)
77 b->extents[1][0] = corner.x;
78 if (b->extents[1][1] < corner.y)
79 b->extents[1][1] = corner.y;
80 if (b->extents[1][2] < corner.z)
81 b->extents[1][2] = corner.z;
82 }
83
84 if (b->numfaces > 0)
85 {
86 // determine which faces will be inside the resulting solid
87 for (i = 0; i < b->numfaces; i++)
88 {
89 convex_face_t* f = b->faces + i;
90 // face will be removed if it places this corner outside the solid
91 removedface[i] = (f->x * corner.x + f->y * corner.y + f->z * corner.z + f->w * corner.w) > epsilon;
92 }
93
94 // scan for removed faces
95 for (i = 0; i < b->numfaces; i++)
96 if (removedface[i])
97 break;
98
99 // exit early if point is completely inside the solid
100 if (i == b->numfaces)
101 return;
102
103 // garbage collect the removed faces
104 for (j = i + 1; j < b->numfaces; j++)
105 if (!removedface[j])
106 b->faces[i++] = b->faces[j];
107 b->numfaces = i;
108 }
109
110 // iterate active corners to create replacement faces using the new corner
111 for (i = 0; i < b->numcorners; i++)
112 {
113 convex_corner_t ca = b->corners[i];
114 for (j = 0; j < b->numcorners; j++)
115 {
116 // using the same point twice would make a degenerate plane
117 if (i == j)
118 continue;
119 convex_corner_t cb = b->corners[j];
120 // calculate the edge directions
121 convex_corner_t d, e;
122 convex_face_t face;
123 d.x = ca.x - cb.x;
124 d.y = ca.y - cb.y;
125 d.z = ca.z - cb.z;
126 d.w = 0.0f;
127 e.x = corner.x - cb.x;
128 e.y = corner.y - cb.y;
129 e.z = corner.z - cb.z;
130 e.w = 0.0f;
131 // cross product to produce a normal; this is not unit length,
132 // its length is the volume of the triangle *2
133 face.x = d.y * e.z - d.z * e.y;
134 face.y = d.z * e.x - d.x * e.z;
135 face.z = d.x * e.y - d.y * e.x;
136 float len2 = face.x * face.x + face.y * face.y + face.z * face.z;
137 if (len2 == 0.0f)
138 {
139 // we can't do anything with a degenerate plane
140 continue;
141 }
142 // normalize the plane normal
143 float inv = 1.0f / sqrt(len2);
144 face.x *= inv;
145 face.y *= inv;
146 face.z *= inv;
147 face.w = -(corner.x * face.x + corner.y * face.y + corner.z * face.z);
148 // flip the face if it's backwards (not facing center)
149 if ((b->extents[0][0] + b->extents[1][0]) * 0.5f * face.x + (b->extents[0][1] + b->extents[1][1]) * 0.5f * face.y + (b->extents[0][2] + b->extents[1][2]) * 0.5f * face.z + face.w > 0.0f)
150 {
151 face.x *= -1.0f;
152 face.y *= -1.0f;
153 face.z *= -1.0f;
154 face.w *= -1.0f;
155 }
156 // discard the proposed face if it slices through the solid
157 for (l = 0; l < b->numcorners; l++)
158 {
159 convex_corner_t cl = b->corners[l];
160 if (cl.x * face.x + cl.y * face.y + cl.z * face.z + face.w > epsilon)
161 break;
162 }
163 if (l < b->numcorners)
164 continue;
165 // add the new face
166 b->faces[b->numfaces++] = face;
167 }
168 }
169
170 // discard any corners that are no longer on the surface of the solid
171 for (i = 0; i < b->numcorners; i++)
172 {
173 convex_corner_t ca = b->corners[i];
174 for (j = 0; j < b->numfaces; j++)
175 {
176 const convex_face_t *f = b->faces + j;
177 if (ca.x * f->x + ca.y * f->y + ca.z * f->z + ca.w * f->w > -epsilon)
178 break;
179 }
180 // if we didn't find any face that uses this corner, remove the corner
181 removedcorner[i] = (j == b->numfaces);
182 }
183
184 // scan for removed corners and remove them
185 for (i = 0; i < b->numcorners; i++)
186 if (removedcorner[i])
187 break;
188 for (j = i + 1;j < b->numcorners;j++)
189 if (!removedcorner[j])
190 b->corners[i++] = b->corners[j];
191 b->numcorners = i;
192
193 // add the new corner
194 b->corners[b->numcorners++] = corner;
195}
client_state_t cl
Definition cl_main.c:117
GLubyte GLubyte GLubyte z
Definition glquake.h:782
GLint GLenum GLint GLint y
Definition glquake.h:651
GLint GLenum GLint x
Definition glquake.h:651
float sqrt(float f)
int i
float f
dp_FragColor b
float z
Definition convex.h:51
float y
Definition convex.h:50
float x
Definition convex.h:49
float w
Definition convex.h:52

References b, cl, CONVEX_MAX_CORNERS, CONVEX_MAX_FACES, f, i, sqrt(), convex_corner_t::w, convex_face_t::w, convex_corner_t::x, convex_face_t::x, x, convex_corner_t::y, convex_face_t::y, y, convex_corner_t::z, convex_face_t::z, and z.

◆ convex_builder_get_planes4f()

int convex_builder_get_planes4f ( convex_builder_state_t * b,
float * outplanes4f,
int maxplanes,
int positivew )

Definition at line 197 of file convex.c.

198{
199 int i;
200 int n = b->numfaces < maxplanes ? b->numfaces : maxplanes;
201 if (positivew)
202 {
203 for (i = 0; i < n; i++)
204 {
205 const convex_face_t* f = b->faces + i;
206 outplanes4f[i * 4 + 0] = f->x;
207 outplanes4f[i * 4 + 1] = f->y;
208 outplanes4f[i * 4 + 2] = f->z;
209 outplanes4f[i * 4 + 3] = f->w * -1.0f;
210 }
211 }
212 else
213 {
214 for (i = 0; i < n; i++)
215 {
216 const convex_face_t* f = b->faces + i;
217 outplanes4f[i * 4 + 0] = f->x;
218 outplanes4f[i * 4 + 1] = f->y;
219 outplanes4f[i * 4 + 2] = f->z;
220 outplanes4f[i * 4 + 3] = f->w;
221 }
222 }
223 return b->numfaces;
224}
#define n(x, y)

References b, f, i, and n.

◆ convex_builder_get_points3f()

int convex_builder_get_points3f ( convex_builder_state_t * b,
float * outpoints3f,
int maxpoints )

Definition at line 226 of file convex.c.

227{
228 int i;
229 int n = b->numcorners < maxpoints ? b->numcorners : maxpoints;
230 for (i = 0; i < n; i++)
231 {
232 const convex_corner_t* c = b->corners + i;
233 outpoints3f[i * 3 + 0] = c->x;
234 outpoints3f[i * 3 + 1] = c->y;
235 outpoints3f[i * 3 + 2] = c->z;
236 }
237 return b->numcorners;
238}

References b, i, n, convex_corner_t::x, convex_corner_t::y, and convex_corner_t::z.

◆ convex_builder_initialize()

void convex_builder_initialize ( convex_builder_state_t * b,
float epsilon )

Definition at line 26 of file convex.c.

27{
28 b->numcorners = 0;
29 b->numfaces = 0;
30 b->epsilon = 0.0f;
31}

References b.