]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake2/extra/qe4/vertsel.c
Q2Tools source - didn't import this in initially
[xonotic/netradiant.git] / tools / quake2 / extra / qe4 / vertsel.c
1 /*
2 ===========================================================================
3 Copyright (C) 1997-2006 Id Software, Inc.
4
5 This file is part of Quake 2 Tools source code.
6
7 Quake 2 Tools source code is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
11
12 Quake 2 Tools source code is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Quake 2 Tools source code; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 ===========================================================================
21 */
22
23 #include "qe3.h"
24
25 int     FindPoint (vec3_t point)
26 {
27         int             i, j;
28
29         for (i=0 ; i<g_qeglobals.d_numpoints ; i++)
30         {
31                 for (j=0 ; j<3 ; j++)
32                         if (fabs(point[j] - g_qeglobals.d_points[i][j]) > 0.1)
33                                 break;
34                 if (j == 3)
35                         return i;
36         }
37
38         VectorCopy (point, g_qeglobals.d_points[g_qeglobals.d_numpoints]);
39         g_qeglobals.d_numpoints++;
40
41         return g_qeglobals.d_numpoints-1;
42 }
43
44 int FindEdge (int p1, int p2, face_t *f)
45 {
46         int             i;
47
48         for (i=0 ; i<g_qeglobals.d_numedges ; i++)
49                 if (g_qeglobals.d_edges[i].p1 == p2 && g_qeglobals.d_edges[i].p2 == p1)
50                 {
51                         g_qeglobals.d_edges[i].f2 = f;
52                         return i;
53                 }
54
55         g_qeglobals.d_edges[g_qeglobals.d_numedges].p1 = p1;
56         g_qeglobals.d_edges[g_qeglobals.d_numedges].p2 = p2;
57         g_qeglobals.d_edges[g_qeglobals.d_numedges].f1 = f;
58         g_qeglobals.d_numedges++;
59
60         return g_qeglobals.d_numedges-1;
61 }
62
63 void MakeFace (face_t *f)
64 {
65         winding_t       *w;
66         int                     i;
67         int                     pnum[128];
68
69         w = MakeFaceWinding (selected_brushes.next, f);
70         if (!w)
71                 return;
72         for (i=0 ; i<w->numpoints ; i++)
73                 pnum[i] = FindPoint (w->points[i]);
74         for (i=0 ; i<w->numpoints ; i++)
75                 FindEdge (pnum[i], pnum[(i+1)%w->numpoints], f);
76
77         free (w);
78 }
79
80 void SetupVertexSelection (void)
81 {
82         face_t  *f;
83         brush_t *b;
84
85         g_qeglobals.d_numpoints = 0;
86         g_qeglobals.d_numedges = 0;
87         if (!QE_SingleBrush())
88                 return;
89         b = selected_brushes.next;
90         for (f=b->brush_faces ; f ; f=f->next)
91                 MakeFace (f);
92
93         Sys_UpdateWindows (W_ALL);
94 }
95
96
97 void SelectFaceEdge (face_t *f, int p1, int p2)
98 {
99         winding_t       *w;
100         int                     i, j, k;
101         int                     pnum[128];
102
103         w = MakeFaceWinding (selected_brushes.next, f);
104         if (!w)
105                 return;
106         for (i=0 ; i<w->numpoints ; i++)
107                 pnum[i] = FindPoint (w->points[i]);
108         for (i=0 ; i<w->numpoints ; i++)
109                 if (pnum[i] == p1 && pnum[(i+1)%w->numpoints] == p2)
110                 {
111                         VectorCopy (g_qeglobals.d_points[pnum[i]], f->planepts[0]);
112                         VectorCopy (g_qeglobals.d_points[pnum[(i+1)%w->numpoints]], f->planepts[1]);
113                         VectorCopy (g_qeglobals.d_points[pnum[(i+2)%w->numpoints]], f->planepts[2]);
114                         for (j=0 ; j<3 ; j++)
115                         {
116                                 for (k=0 ; k<3 ; k++)
117                                 {
118                                         f->planepts[j][k] = floor(f->planepts[j][k]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
119                                 }
120                         }
121
122                         AddPlanept (f->planepts[0]);
123                         AddPlanept (f->planepts[1]);
124                         break;
125                 }
126
127         if (i == w->numpoints)
128                 Sys_Printf ("SelectFaceEdge: failed\n");
129         free (w);
130 }
131
132 void SelectVertex (int p1)
133 {
134         brush_t         *b;
135         winding_t       *w;
136         int                     i, j, k;
137         face_t          *f;
138
139         b = selected_brushes.next;
140         for (f=b->brush_faces ; f ; f=f->next)
141         {
142                 w =  MakeFaceWinding (b, f);
143                 if (!w)
144                         continue;
145                 for (i=0 ; i<w->numpoints ; i++)
146                 {
147                         if (FindPoint (w->points[i]) == p1)
148                         {
149                                 VectorCopy (w->points[(i+w->numpoints-1)%w->numpoints], f->planepts[0]);
150                                 VectorCopy (w->points[i], f->planepts[1]);
151                                 VectorCopy (w->points[(i+1)%w->numpoints], f->planepts[2]);
152                         for (j=0 ; j<3 ; j++)
153                         {
154                                 for (k=0 ; k<3 ; k++)
155                                 {
156                                         f->planepts[j][k] = floor(f->planepts[j][k]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
157                                 }
158                         }
159
160                                 AddPlanept (f->planepts[1]);
161                                 break;
162                         }
163                 }
164                 free (w);
165         }
166 }
167
168 void SelectEdgeByRay (vec3_t org, vec3_t dir)
169 {
170         int             i, j, besti;
171         float   d, bestd;
172         vec3_t  mid, temp;
173         pedge_t *e;
174
175         // find the edge closest to the ray
176         besti = -1;
177         bestd = 8;
178
179         for (i=0 ; i<g_qeglobals.d_numedges ; i++)
180         {
181                 for (j=0 ; j<3 ; j++)
182                         mid[j] = 0.5*(g_qeglobals.d_points[g_qeglobals.d_edges[i].p1][j] + g_qeglobals.d_points[g_qeglobals.d_edges[i].p2][j]);
183
184                 VectorSubtract (mid, org, temp);
185                 d = DotProduct (temp, dir);
186                 VectorMA (org, d, dir, temp);
187                 VectorSubtract (mid, temp, temp);
188                 d = VectorLength (temp);
189                 if (d < bestd)
190                 {
191                         bestd = d;
192                         besti = i;
193                 }
194         }
195
196         if (besti == -1)
197         {
198                 Sys_Printf ("Click didn't hit an edge\n");
199                 return;
200         }
201         Sys_Printf ("hit edge\n");
202
203         // make the two faces that border the edge use the two edge points
204         // as primary drag points
205         g_qeglobals.d_num_move_points = 0;
206         e = &g_qeglobals.d_edges[besti];
207         SelectFaceEdge (e->f1, e->p1, e->p2);
208         SelectFaceEdge (e->f2, e->p2, e->p1);
209 }
210
211 void SelectVertexByRay (vec3_t org, vec3_t dir)
212 {
213         int             i, besti;
214         float   d, bestd;
215         vec3_t  temp;
216
217         // find the point closest to the ray
218         besti = -1;
219         bestd = 8;
220
221         for (i=0 ; i<g_qeglobals.d_numpoints ; i++)
222         {
223                 VectorSubtract (g_qeglobals.d_points[i], org, temp);
224                 d = DotProduct (temp, dir);
225                 VectorMA (org, d, dir, temp);
226                 VectorSubtract (g_qeglobals.d_points[i], temp, temp);
227                 d = VectorLength (temp);
228                 if (d < bestd)
229                 {
230                         bestd = d;
231                         besti = i;
232                 }
233         }
234
235         if (besti == -1)
236         {
237                 Sys_Printf ("Click didn't hit a vertex\n");
238                 return;
239         }
240         Sys_Printf ("hit vertex\n");
241         SelectVertex (besti);
242 }
243
244
245