2 ===========================================================================
3 Copyright (C) 1997-2006 Id Software, Inc.
5 This file is part of Quake 2 Tools source code.
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.
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.
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 ===========================================================================
25 int FindPoint (vec3_t point)
29 for (i=0 ; i<g_qeglobals.d_numpoints ; i++)
32 if (fabs(point[j] - g_qeglobals.d_points[i][j]) > 0.1)
38 VectorCopy (point, g_qeglobals.d_points[g_qeglobals.d_numpoints]);
39 g_qeglobals.d_numpoints++;
41 return g_qeglobals.d_numpoints-1;
44 int FindEdge (int p1, int p2, face_t *f)
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)
51 g_qeglobals.d_edges[i].f2 = f;
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++;
60 return g_qeglobals.d_numedges-1;
63 void MakeFace (face_t *f)
69 w = MakeFaceWinding (selected_brushes.next, f);
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);
80 void SetupVertexSelection (void)
85 g_qeglobals.d_numpoints = 0;
86 g_qeglobals.d_numedges = 0;
87 if (!QE_SingleBrush())
89 b = selected_brushes.next;
90 for (f=b->brush_faces ; f ; f=f->next)
93 Sys_UpdateWindows (W_ALL);
97 void SelectFaceEdge (face_t *f, int p1, int p2)
103 w = MakeFaceWinding (selected_brushes.next, f);
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)
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++)
116 for (k=0 ; k<3 ; k++)
118 f->planepts[j][k] = floor(f->planepts[j][k]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
122 AddPlanept (f->planepts[0]);
123 AddPlanept (f->planepts[1]);
127 if (i == w->numpoints)
128 Sys_Printf ("SelectFaceEdge: failed\n");
132 void SelectVertex (int p1)
139 b = selected_brushes.next;
140 for (f=b->brush_faces ; f ; f=f->next)
142 w = MakeFaceWinding (b, f);
145 for (i=0 ; i<w->numpoints ; i++)
147 if (FindPoint (w->points[i]) == p1)
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++)
154 for (k=0 ; k<3 ; k++)
156 f->planepts[j][k] = floor(f->planepts[j][k]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
160 AddPlanept (f->planepts[1]);
168 void SelectEdgeByRay (vec3_t org, vec3_t dir)
175 // find the edge closest to the ray
179 for (i=0 ; i<g_qeglobals.d_numedges ; i++)
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]);
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);
198 Sys_Printf ("Click didn't hit an edge\n");
201 Sys_Printf ("hit edge\n");
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);
211 void SelectVertexByRay (vec3_t org, vec3_t dir)
217 // find the point closest to the ray
221 for (i=0 ; i<g_qeglobals.d_numpoints ; i++)
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);
237 Sys_Printf ("Click didn't hit a vertex\n");
240 Sys_Printf ("hit vertex\n");
241 SelectVertex (besti);