2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
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.
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.
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/>.
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.
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.
26 ===========================================================================
29 #include "../../idlib/precompiled.h"
37 =======================================================================================================================
38 =======================================================================================================================
40 int FindPoint(idVec3 point) {
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) {
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++;
60 return g_qeglobals.d_numpoints - 1;
64 =======================================================================================================================
65 =======================================================================================================================
67 int FindEdge(int p1, int p2, face_t *f) {
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;
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;
81 if (g_qeglobals.d_numedges < MAX_EDGES - 1) {
82 g_qeglobals.d_numedges++;
85 return g_qeglobals.d_numedges - 1;
89 void MakeFace (brush_t * b, face_t * f)
91 void MakeFace (face_t * f)
99 w = Brush_MakeFaceWinding(b, f);
101 w = Brush_MakeFaceWinding(selected_brushes.next, f);
106 for (i = 0; i < w->GetNumPoints(); i++) {
107 pnum[i] = FindPoint( (*w)[i].ToVec3() );
109 for (i = 0; i < w->GetNumPoints(); i++) {
110 FindEdge(pnum[i], pnum[(i + 1) % w->GetNumPoints()], f);
116 =======================================================================================================================
117 =======================================================================================================================
119 void SetupVertexSelection(void) {
123 g_qeglobals.d_numpoints = 0;
124 g_qeglobals.d_numedges = 0;
127 for (b = selected_brushes.next; b != &selected_brushes; b = b->next) {
128 for (f = b->brush_faces; f; f = f->next) {
134 if (!QE_SingleBrush()) {
138 b = selected_brushes.next;
139 for (f = b->brush_faces; f; f = f->next) {
146 void SelectFaceEdge (brush_t * b, face_t * f, int p1, int p2)
148 void SelectFaceEdge (face_t * f, int p1, int p2)
156 w = Brush_MakeFaceWinding(b, f);
158 w = Brush_MakeFaceWinding(selected_brushes.next, f);
163 for (i = 0; i < w->GetNumPoints(); i++) {
164 pnum[i] = FindPoint( (*w)[i].ToVec3() );
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++) {
174 floor(f->planepts[j][k] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
177 AddPlanept(&f->planepts[0]);
178 AddPlanept(&f->planepts[1]);
182 if ( i == w->GetNumPoints() ) {
183 Sys_Status("SelectFaceEdge: failed\n");
189 =======================================================================================================================
190 =======================================================================================================================
192 void SelectVertex(int p1) {
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);
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;
217 AddPlanept(&f->planepts[1]);
229 b = selected_brushes.next;
230 for (f = b->brush_faces; f; f = f->next) {
231 w = Brush_MakeFaceWinding(b, f);
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;
247 AddPlanept(&f->planepts[1]);
260 =======================================================================================================================
261 =======================================================================================================================
263 void SelectEdgeByRay(idVec3 org, idVec3 dir) {
269 // find the edge closest to the ray
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]);
280 temp = org + d * dir;
290 Sys_Status("Click didn't hit an edge\n");
294 Sys_Status("hit edge\n");
297 // make the two faces that border the edge use the two edge points as primary drag
300 g_qeglobals.d_num_move_points = 0;
301 e = &g_qeglobals.d_edges[besti];
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);
309 SelectFaceEdge(e->f1, e->p1, e->p2);
310 SelectFaceEdge(e->f2, e->p2, e->p1);
315 =======================================================================================================================
316 =======================================================================================================================
318 void SelectVertexByRay(idVec3 org, idVec3 dir) {
323 float scale = g_pParentWnd->ActiveXY()->Scale();
324 // find the point closest to the ray
326 bestd = 8 / scale / 2;
328 for (i = 0; i < g_qeglobals.d_numpoints; i++) {
329 temp = g_qeglobals.d_points[i] - org;
331 temp = org + d * dir;
332 temp = g_qeglobals.d_points[i] - temp;
340 if (besti == -1 || bestd > 8 / scale / 2 ) {
341 Sys_Status("Click didn't hit a vertex\n");
345 Sys_Status("hit vertex\n");
346 g_qeglobals.d_move_points[g_qeglobals.d_num_move_points++] = &g_qeglobals.d_points[besti];
348 // SelectVertex (besti);
351 extern void AddPatchMovePoint(idVec3 v, bool bMulti, bool bFull);
354 =======================================================================================================================
355 =======================================================================================================================
357 void SelectCurvePointByRay(const idVec3 &org, const idVec3 &dir, int buttons) {
362 // find the point closest to the ray
363 float scale = g_pParentWnd->ActiveXY()->Scale();
365 bestd = 8 / scale / 2;
368 for (i = 0; i < g_qeglobals.d_numpoints; i++) {
369 temp = g_qeglobals.d_points[i] - org;
371 temp = org + d * dir;
372 temp = g_qeglobals.d_points[i] - temp;
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);
390 // Sys_Status ("hit vertex\n");
391 AddPatchMovePoint( g_qeglobals.d_points[besti], ( buttons & MK_CONTROL ) != 0, ( buttons & MK_SHIFT ) != 0 );
395 =======================================================================================================================
396 =======================================================================================================================
398 void SelectSplinePointByRay(const idVec3 &org, const idVec3 &dir, int buttons) {
403 // find the point closest to the ray
407 for (i = 0; i < g_qeglobals.d_numpoints; i++) {
408 temp = g_qeglobals.d_points[i] - org;
410 temp = org + d * dir;
411 temp = g_qeglobals.d_points[i] - temp;
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];
427 // g_splineList->setSelectedPoint(&g_qeglobals.d_points[besti]);