1 entity entdup(entity e)
9 entity AllocWinding(entity base)
13 e.classname = "winding";
18 e.winding_point_interpolate = base.winding_point_interpolate;
22 void InsertIntoWinding(entity w, entity e)
25 e.sort_prev = w.sort_prev;
26 e.sort_prev.sort_next = e;
27 e.sort_next.sort_prev = e;
31 void DeleteFromWinding(entity p)
33 p.sort_next.sort_prev = p.sort_prev;
34 p.sort_prev.sort_next = p.sort_next;
38 entity AllocPoint(entity w, vector o)
42 e.classname = "winding_point";
48 void ClearWinding(entity w)
51 for(e = w.sort_next; e != w; )
57 w.sort_next = w.sort_prev = w;
60 void FreeWinding(entity w)
66 entity CopyWinding(entity w)
71 for(e = w.sort_next; e != w; e = e.sort_next)
79 wn.sort_prev.sort_next = wn;
80 for(en = wn.sort_prev; en != wn; en = en.sort_prev)
81 en.sort_prev.sort_next = en;
85 void ClipWindingEpsilon(entity w, vector norm, float dist, float epsilon, float want_sides)
87 // algorithm from q3map2
88 float counts_f, counts_b;
94 for(i = 0, p = w.sort_next; p != w; ++i, p = p.sort_next)
96 dot = p.origin * norm - dist;
99 else if(dot < -epsilon)
106 clipwinding_front = AllocWinding(w);
108 clipwinding_back = CopyWinding(w);
114 clipwinding_front = CopyWinding(w);
116 clipwinding_back = AllocWinding(w);
120 clipwinding_front = AllocWinding(w);
121 clipwinding_back = AllocWinding(w);
123 for(i = 0, p = w.sort_next; p != w; ++i, p = p.sort_next)
128 d = p.origin * norm - dist;
129 d2 = p2.origin * norm - dist;
130 if(d > epsilon) // front
133 InsertIntoWinding(clipwinding_front, entdup(p));
134 if not(d2 < -epsilon) // only if switching side
137 else if(d < -epsilon) // back
140 InsertIntoWinding(clipwinding_back, entdup(p));
141 if not(d2 > epsilon) // only if switching side
146 // point is for both windings
148 InsertIntoWinding(clipwinding_front, entdup(p));
150 InsertIntoWinding(clipwinding_back, entdup(p));
153 // must... make... split... point
155 mid = (1 - dot) * p.origin + dot * p2.origin;
156 pnew = AllocPoint(w, mid);
157 pnew.winding_cutpoint = 1;
158 if(w.winding_point_interpolate)
159 w.winding_point_interpolate(w, pnew, p, p2, dot);
162 InsertIntoWinding(clipwinding_front, pnew);
167 InsertIntoWinding(clipwinding_back, pnew);