]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/tools/radiant/VERTSEL.CPP
Various Mac OS X tweaks to get this to build. Probably breaking things.
[icculus/iodoom3.git] / neo / tools / radiant / VERTSEL.CPP
1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 
6
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).  
8
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code.  If not, see <http://www.gnu.org/licenses/>.
21
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code.  If not, please request a copy in writing from id Software at the address below.
23
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25
26 ===========================================================================
27 */
28
29 #include "../../idlib/precompiled.h"
30 #pragma hdrstop
31
32 #include "qe3.h"
33
34 #define NEWEDGESEL      1
35
36 /*
37  =======================================================================================================================
38  =======================================================================================================================
39  */
40 int FindPoint(idVec3 point) {
41         int i, j;
42
43         for (i = 0; i < g_qeglobals.d_numpoints; i++) {
44                 for (j = 0; j < 3; j++) {
45                         if (idMath::Fabs(point[j] - g_qeglobals.d_points[i][j]) > 0.1) {
46                                 break;
47                         }
48                 }
49
50                 if (j == 3) {
51                         return i;
52                 }
53         }
54
55         VectorCopy(point, g_qeglobals.d_points[g_qeglobals.d_numpoints]);
56         if (g_qeglobals.d_numpoints < MAX_POINTS - 1) {
57                 g_qeglobals.d_numpoints++;
58         }
59
60         return g_qeglobals.d_numpoints - 1;
61 }
62
63 /*
64  =======================================================================================================================
65  =======================================================================================================================
66  */
67 int FindEdge(int p1, int p2, face_t *f) {
68         int i;
69
70         for (i = 0; i < g_qeglobals.d_numedges; i++) {
71                 if (g_qeglobals.d_edges[i].p1 == p2 && g_qeglobals.d_edges[i].p2 == p1) {
72                         g_qeglobals.d_edges[i].f2 = f;
73                         return i;
74                 }
75         }
76
77         g_qeglobals.d_edges[g_qeglobals.d_numedges].p1 = p1;
78         g_qeglobals.d_edges[g_qeglobals.d_numedges].p2 = p2;
79         g_qeglobals.d_edges[g_qeglobals.d_numedges].f1 = f;
80
81         if (g_qeglobals.d_numedges < MAX_EDGES - 1) {
82                 g_qeglobals.d_numedges++;
83         }
84
85         return g_qeglobals.d_numedges - 1;
86 }
87
88 #ifdef NEWEDGESEL
89 void MakeFace (brush_t * b, face_t * f)
90 #else
91 void MakeFace (face_t * f)
92 #endif 
93 {
94         idWinding       *w;
95         int                     i;
96         int                     pnum[128];
97
98 #ifdef NEWEDGESEL
99         w = Brush_MakeFaceWinding(b, f);
100 #else
101         w = Brush_MakeFaceWinding(selected_brushes.next, f);
102 #endif
103         if (!w) {
104                 return;
105         }
106         for (i = 0; i < w->GetNumPoints(); i++) {
107                 pnum[i] = FindPoint( (*w)[i].ToVec3() );
108         }
109         for (i = 0; i < w->GetNumPoints(); i++) {
110                 FindEdge(pnum[i], pnum[(i + 1) % w->GetNumPoints()], f);
111         }
112         delete w;
113 }
114
115 /*
116  =======================================================================================================================
117  =======================================================================================================================
118  */
119 void SetupVertexSelection(void) {
120         face_t  *f;
121         brush_t *b;
122
123         g_qeglobals.d_numpoints = 0;
124         g_qeglobals.d_numedges = 0;
125
126 #ifdef NEWEDGESEL
127         for (b = selected_brushes.next; b != &selected_brushes; b = b->next) {
128                 for (f = b->brush_faces; f; f = f->next) {
129                         MakeFace(b, f);
130                 }
131         }
132
133 #else
134         if (!QE_SingleBrush()) {
135                 return;
136         }
137
138         b = selected_brushes.next;
139         for (f = b->brush_faces; f; f = f->next) {
140                 MakeFace(b, f);
141         }
142 #endif
143 }
144
145 #ifdef NEWEDGESEL
146 void SelectFaceEdge (brush_t * b, face_t * f, int p1, int p2)
147 #else
148 void SelectFaceEdge (face_t * f, int p1, int p2)
149 #endif 
150 {
151         idWinding       *w;
152         int                     i, j, k;
153         int                     pnum[128];
154
155 #ifdef NEWEDGESEL
156         w = Brush_MakeFaceWinding(b, f);
157 #else
158         w = Brush_MakeFaceWinding(selected_brushes.next, f);
159 #endif
160         if (!w) {
161                 return;
162         }
163         for (i = 0; i < w->GetNumPoints(); i++) {
164                 pnum[i] = FindPoint( (*w)[i].ToVec3() );
165         }
166         for (i = 0; i < w->GetNumPoints(); i++) {
167                 if (pnum[i] == p1 && pnum[(i + 1) % w->GetNumPoints()] == p2) {
168                         VectorCopy(g_qeglobals.d_points[pnum[i]], f->planepts[0]);
169                         VectorCopy(g_qeglobals.d_points[pnum[(i + 1) % w->GetNumPoints()]], f->planepts[1]);
170                         VectorCopy(g_qeglobals.d_points[pnum[(i + 2) % w->GetNumPoints()]], f->planepts[2]);
171                         for (j = 0; j < 3; j++) {
172                                 for (k = 0; k < 3; k++) {
173                                         f->planepts[j][k] =
174                                         floor(f->planepts[j][k] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
175                                 }
176                         }
177                         AddPlanept(&f->planepts[0]);
178                         AddPlanept(&f->planepts[1]);
179                         break;
180                 }
181         }
182         if ( i == w->GetNumPoints() ) {
183                 Sys_Status("SelectFaceEdge: failed\n");
184         }
185         delete w;
186 }
187
188 /*
189  =======================================================================================================================
190  =======================================================================================================================
191  */
192 void SelectVertex(int p1) {
193         brush_t         *b;
194         idWinding       *w;
195         int                     i, j, k;
196         face_t          *f;
197
198 #ifdef NEWEDGESEL
199         for (b = selected_brushes.next; b != &selected_brushes; b = b->next) {
200                 for (f = b->brush_faces; f; f = f->next) {
201                         w = Brush_MakeFaceWinding(b, f);
202                         if (!w) {
203                                 continue;
204                         }
205
206                         for (i = 0; i < w->GetNumPoints(); i++) {
207                                 if ( FindPoint( (*w)[i].ToVec3() ) == p1 ) {
208                                         VectorCopy((*w)[(i + w->GetNumPoints() - 1) % w->GetNumPoints()], f->planepts[0]);
209                                         VectorCopy((*w)[i], f->planepts[1]);
210                                         VectorCopy((*w)[(i + 1) % w->GetNumPoints()], f->planepts[2]);
211                                         for (j = 0; j < 3; j++) {
212                                                 for (k = 0; k < 3; k++) {
213                                                         // f->planepts[j][k] = floor(f->planepts[j][k]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
214                                                 }
215                                         }
216
217                                         AddPlanept(&f->planepts[1]);
218
219                                         // MessageBeep(-1);
220                                         break;
221                                 }
222                         }
223
224                         delete w;
225                 }
226         }
227
228 #else
229         b = selected_brushes.next;
230         for (f = b->brush_faces; f; f = f->next) {
231                 w = Brush_MakeFaceWinding(b, f);
232                 if (!w) {
233                         continue;
234                 }
235
236                 for (i = 0; i < w->GetNumPoints(); i++) {
237                         if (FindPoint(w[i]) == p1) {
238                                 VectorCopy(w[(i + w->GetNumPoints() - 1) % w->GetNumPoints()], f->planepts[0]);
239                                 VectorCopy(w[i], f->planepts[1]);
240                                 VectorCopy(w[(i + 1) % w->GetNumPoints()], f->planepts[2]);
241                                 for (j = 0; j < 3; j++) {
242                                         for (k = 0; k < 3; k++) {
243                                                 // f->planepts[j][k] = floor(f->planepts[j][k]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
244                                         }
245                                 }
246
247                                 AddPlanept(&f->planepts[1]);
248
249                                 // MessageBeep(-1);
250                                 break;
251                         }
252                 }
253
254                 delete w;
255         }
256 #endif
257 }
258
259 /*
260  =======================================================================================================================
261  =======================================================================================================================
262  */
263 void SelectEdgeByRay(idVec3 org, idVec3 dir) {
264         int             i, j, besti;
265         float   d, bestd;
266         idVec3  mid, temp;
267         pedge_t *e;
268
269         // find the edge closest to the ray
270         besti = -1;
271         bestd = 8;
272
273         for (i = 0; i < g_qeglobals.d_numedges; i++) {
274                 for (j = 0; j < 3; j++) {
275                         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]);
276                 }
277
278                 temp = mid - org;
279                 d = temp * dir;
280                 temp = org + d * dir;
281                 temp = mid - temp;
282                 d = temp.Length();
283                 if ( d < bestd ) {
284                         bestd = d;
285                         besti = i;
286                 }
287         }
288
289         if (besti == -1) {
290                 Sys_Status("Click didn't hit an edge\n");
291                 return;
292         }
293
294         Sys_Status("hit edge\n");
295
296         //
297         // make the two faces that border the edge use the two edge points as primary drag
298         // points
299         //
300         g_qeglobals.d_num_move_points = 0;
301         e = &g_qeglobals.d_edges[besti];
302 #ifdef NEWEDGESEL
303         for (brush_t * b = selected_brushes.next; b != &selected_brushes; b = b->next) {
304                 SelectFaceEdge(b, e->f1, e->p1, e->p2);
305                 SelectFaceEdge(b, e->f2, e->p2, e->p1);
306         }
307
308 #else
309         SelectFaceEdge(e->f1, e->p1, e->p2);
310         SelectFaceEdge(e->f2, e->p2, e->p1);
311 #endif
312 }
313
314 /*
315  =======================================================================================================================
316  =======================================================================================================================
317  */
318 void SelectVertexByRay(idVec3 org, idVec3 dir) {
319         int             i, besti;
320         float   d, bestd;
321         idVec3  temp;
322
323         float scale = g_pParentWnd->ActiveXY()->Scale();
324         // find the point closest to the ray
325         besti = -1;
326         bestd = 8 / scale / 2;
327
328         for (i = 0; i < g_qeglobals.d_numpoints; i++) {
329                 temp = g_qeglobals.d_points[i] - org;
330                 d = temp * dir;
331                 temp = org + d * dir;
332                 temp = g_qeglobals.d_points[i] - temp;
333                 d = temp.Length();
334                 if ( d < bestd ) {
335                         bestd = d;
336                         besti = i;
337                 }
338         }
339
340         if (besti == -1 || bestd > 8 / scale / 2 ) {
341                 Sys_Status("Click didn't hit a vertex\n");
342                 return;
343         }
344
345         Sys_Status("hit vertex\n");
346         g_qeglobals.d_move_points[g_qeglobals.d_num_move_points++] = &g_qeglobals.d_points[besti];
347
348         // SelectVertex (besti);
349 }
350
351 extern void AddPatchMovePoint(idVec3 v, bool bMulti, bool bFull);
352
353 /*
354  =======================================================================================================================
355  =======================================================================================================================
356  */
357 void SelectCurvePointByRay(const idVec3 &org, const idVec3 &dir, int buttons) {
358         int             i, besti;
359         float   d, bestd;
360         idVec3  temp;
361
362         // find the point closest to the ray
363         float scale = g_pParentWnd->ActiveXY()->Scale();
364         besti = -1;
365         bestd = 8 / scale / 2;
366         //bestd = 8;
367
368         for (i = 0; i < g_qeglobals.d_numpoints; i++) {
369                 temp = g_qeglobals.d_points[i] - org;
370                 d = temp * dir;
371                 temp = org + d * dir;
372                 temp = g_qeglobals.d_points[i] - temp;
373                 d = temp.Length();
374                 if ( d <= bestd ) {
375                         bestd = d;
376                         besti = i;
377                 }
378         }
379
380         if (besti == -1) {
381                 if (g_pParentWnd->ActiveXY()->AreaSelectOK()) {
382                         g_qeglobals.d_select_mode = sel_area;
383                         VectorCopy(org, g_qeglobals.d_vAreaTL);
384                         VectorCopy(org, g_qeglobals.d_vAreaBR);
385                 }
386
387                 return;
388         }
389
390         // Sys_Status ("hit vertex\n");
391         AddPatchMovePoint( g_qeglobals.d_points[besti], ( buttons & MK_CONTROL ) != 0, ( buttons & MK_SHIFT ) != 0 );
392 }
393
394 /*
395  =======================================================================================================================
396  =======================================================================================================================
397  */
398 void SelectSplinePointByRay(const idVec3 &org, const idVec3 &dir, int buttons) {
399         int             i, besti;
400         float   d, bestd;
401         idVec3  temp;
402
403         // find the point closest to the ray
404         besti = -1;
405         bestd = 8;
406
407         for (i = 0; i < g_qeglobals.d_numpoints; i++) {
408                 temp = g_qeglobals.d_points[i] - org;
409                 d = temp * dir;
410                 temp = org + d * dir;
411                 temp = g_qeglobals.d_points[i] - temp;
412                 d = temp.Length();
413                 if ( d <= bestd ) {
414                         bestd = d;
415                         besti = i;
416                 }
417         }
418
419         if (besti == -1) {
420                 return;
421         }
422
423         Sys_Status("hit curve point\n");
424         g_qeglobals.d_num_move_points = 0;
425         g_qeglobals.d_move_points[g_qeglobals.d_num_move_points++] = &g_qeglobals.d_points[besti];
426
427         // g_splineList->setSelectedPoint(&g_qeglobals.d_points[besti]);
428 }