VERTSEL.CPP (8287B)
1 /* 2 =========================================================================== 3 Copyright (C) 1999-2005 Id Software, Inc. 4 5 This file is part of Quake III Arena source code. 6 7 Quake III Arena 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 III Arena 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 Foobar; 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 "stdafx.h" 24 #include "qe3.h" 25 #include "winding.h" 26 27 #define NEWEDGESEL 1 28 29 30 int FindPoint (vec3_t point) 31 { 32 int i, j; 33 34 for (i=0 ; i<g_qeglobals.d_numpoints ; i++) 35 { 36 for (j=0 ; j<3 ; j++) 37 if (fabs(point[j] - g_qeglobals.d_points[i][j]) > 0.1) 38 break; 39 if (j == 3) 40 return i; 41 } 42 43 VectorCopy (point, g_qeglobals.d_points[g_qeglobals.d_numpoints]); 44 if (g_qeglobals.d_numpoints < MAX_POINTS-1) 45 { 46 g_qeglobals.d_numpoints++; 47 } 48 49 return g_qeglobals.d_numpoints-1; 50 } 51 52 int FindEdge (int p1, int p2, face_t *f) 53 { 54 int i; 55 56 for (i=0 ; i<g_qeglobals.d_numedges ; i++) 57 if (g_qeglobals.d_edges[i].p1 == p2 && g_qeglobals.d_edges[i].p2 == p1) 58 { 59 g_qeglobals.d_edges[i].f2 = f; 60 return i; 61 } 62 63 g_qeglobals.d_edges[g_qeglobals.d_numedges].p1 = p1; 64 g_qeglobals.d_edges[g_qeglobals.d_numedges].p2 = p2; 65 g_qeglobals.d_edges[g_qeglobals.d_numedges].f1 = f; 66 67 if (g_qeglobals.d_numedges < MAX_EDGES-1) 68 { 69 g_qeglobals.d_numedges++; 70 } 71 72 return g_qeglobals.d_numedges-1; 73 } 74 75 #ifdef NEWEDGESEL 76 void MakeFace (brush_t* b, face_t *f) 77 #else 78 void MakeFace (face_t *f) 79 #endif 80 { 81 winding_t *w; 82 int i; 83 int pnum[128]; 84 85 #ifdef NEWEDGESEL 86 w = Brush_MakeFaceWinding (b, f); 87 #else 88 w = Brush_MakeFaceWinding (selected_brushes.next, f); 89 #endif 90 if (!w) 91 return; 92 for (i=0 ; i<w->numpoints ; i++) 93 pnum[i] = FindPoint (w->points[i]); 94 for (i=0 ; i<w->numpoints ; i++) 95 FindEdge (pnum[i], pnum[(i+1)%w->numpoints], f); 96 97 free (w); 98 } 99 100 void SetupVertexSelection (void) 101 { 102 face_t *f; 103 brush_t *b; 104 105 g_qeglobals.d_numpoints = 0; 106 g_qeglobals.d_numedges = 0; 107 108 #ifdef NEWEDGESEL 109 for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next) 110 { 111 for (f=b->brush_faces ; f ; f=f->next) 112 MakeFace (b,f); 113 } 114 #else 115 if (!QE_SingleBrush()) 116 return; 117 118 b = selected_brushes.next; 119 for (f=b->brush_faces ; f ; f=f->next) 120 MakeFace (b,f); 121 #endif 122 123 } 124 125 126 #ifdef NEWEDGESEL 127 void SelectFaceEdge (brush_t* b, face_t *f, int p1, int p2) 128 #else 129 void SelectFaceEdge (face_t *f, int p1, int p2) 130 #endif 131 { 132 winding_t *w; 133 int i, j, k; 134 int pnum[128]; 135 136 #ifdef NEWEDGESEL 137 w = Brush_MakeFaceWinding (b, f); 138 #else 139 w = Brush_MakeFaceWinding (selected_brushes.next, f); 140 #endif 141 if (!w) 142 return; 143 for (i=0 ; i<w->numpoints ; i++) 144 pnum[i] = FindPoint (w->points[i]); 145 146 for (i=0 ; i<w->numpoints ; i++) 147 if (pnum[i] == p1 && pnum[(i+1)%w->numpoints] == p2) 148 { 149 VectorCopy (g_qeglobals.d_points[pnum[i]], f->planepts[0]); 150 VectorCopy (g_qeglobals.d_points[pnum[(i+1)%w->numpoints]], f->planepts[1]); 151 VectorCopy (g_qeglobals.d_points[pnum[(i+2)%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[0]); 161 AddPlanept (f->planepts[1]); 162 break; 163 } 164 165 if (i == w->numpoints) 166 Sys_Printf ("SelectFaceEdge: failed\n"); 167 free (w); 168 } 169 170 171 void SelectVertex (int p1) 172 { 173 brush_t *b; 174 winding_t *w; 175 int i, j, k; 176 face_t *f; 177 178 #ifdef NEWEDGESEL 179 for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next) 180 { 181 for (f=b->brush_faces ; f ; f=f->next) 182 { 183 w = Brush_MakeFaceWinding (b, f); 184 if (!w) 185 continue; 186 for (i=0 ; i<w->numpoints ; i++) 187 { 188 if (FindPoint (w->points[i]) == p1) 189 { 190 VectorCopy (w->points[(i+w->numpoints-1)%w->numpoints], f->planepts[0]); 191 VectorCopy (w->points[i], f->planepts[1]); 192 VectorCopy (w->points[(i+1)%w->numpoints], f->planepts[2]); 193 for (j=0 ; j<3 ; j++) 194 { 195 for (k=0 ; k<3 ; k++) 196 { 197 ;//f->planepts[j][k] = floor(f->planepts[j][k]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize; 198 } 199 } 200 201 AddPlanept (f->planepts[1]); 202 //MessageBeep(-1); 203 204 break; 205 } 206 } 207 free (w); 208 } 209 } 210 #else 211 b = selected_brushes.next; 212 for (f=b->brush_faces ; f ; f=f->next) 213 { 214 w = Brush_MakeFaceWinding (b, f); 215 if (!w) 216 continue; 217 for (i=0 ; i<w->numpoints ; i++) 218 { 219 if (FindPoint (w->points[i]) == p1) 220 { 221 VectorCopy (w->points[(i+w->numpoints-1)%w->numpoints], f->planepts[0]); 222 VectorCopy (w->points[i], f->planepts[1]); 223 VectorCopy (w->points[(i+1)%w->numpoints], f->planepts[2]); 224 for (j=0 ; j<3 ; j++) 225 { 226 for (k=0 ; k<3 ; k++) 227 { 228 ;//f->planepts[j][k] = floor(f->planepts[j][k]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize; 229 } 230 } 231 232 AddPlanept (f->planepts[1]); 233 //MessageBeep(-1); 234 235 break; 236 } 237 } 238 free (w); 239 } 240 #endif 241 } 242 243 void SelectEdgeByRay (vec3_t org, vec3_t dir) 244 { 245 int i, j, besti; 246 float d, bestd; 247 vec3_t mid, temp; 248 pedge_t *e; 249 250 // find the edge closest to the ray 251 besti = -1; 252 bestd = 8; 253 254 for (i=0 ; i<g_qeglobals.d_numedges ; i++) 255 { 256 for (j=0 ; j<3 ; j++) 257 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]); 258 259 VectorSubtract (mid, org, temp); 260 d = DotProduct (temp, dir); 261 VectorMA (org, d, dir, temp); 262 VectorSubtract (mid, temp, temp); 263 d = VectorLength (temp); 264 if (d < bestd) 265 { 266 bestd = d; 267 besti = i; 268 } 269 } 270 271 if (besti == -1) 272 { 273 Sys_Printf ("Click didn't hit an edge\n"); 274 return; 275 } 276 Sys_Printf ("hit edge\n"); 277 278 // make the two faces that border the edge use the two edge points 279 // as primary drag points 280 g_qeglobals.d_num_move_points = 0; 281 e = &g_qeglobals.d_edges[besti]; 282 #ifdef NEWEDGESEL 283 for (brush_t* b=selected_brushes.next ; b != &selected_brushes ; b=b->next) 284 { 285 SelectFaceEdge (b, e->f1, e->p1, e->p2); 286 SelectFaceEdge (b, e->f2, e->p2, e->p1); 287 } 288 #else 289 SelectFaceEdge (e->f1, e->p1, e->p2); 290 SelectFaceEdge (e->f2, e->p2, e->p1); 291 #endif 292 293 294 } 295 296 void SelectVertexByRay (vec3_t org, vec3_t dir) 297 { 298 int i, besti; 299 float d, bestd; 300 vec3_t temp; 301 302 // find the point closest to the ray 303 besti = -1; 304 bestd = 8; 305 306 for (i=0 ; i<g_qeglobals.d_numpoints ; i++) 307 { 308 VectorSubtract (g_qeglobals.d_points[i], org, temp); 309 d = DotProduct (temp, dir); 310 VectorMA (org, d, dir, temp); 311 VectorSubtract (g_qeglobals.d_points[i], temp, temp); 312 d = VectorLength (temp); 313 if (d < bestd) 314 { 315 bestd = d; 316 besti = i; 317 } 318 } 319 320 if (besti == -1) 321 { 322 Sys_Printf ("Click didn't hit a vertex\n"); 323 return; 324 } 325 Sys_Printf ("hit vertex\n"); 326 g_qeglobals.d_move_points[g_qeglobals.d_num_move_points++] = g_qeglobals.d_points[besti]; 327 //SelectVertex (besti); 328 } 329 330 331 332 extern void AddPatchMovePoint(vec3_t v, bool bMulti, bool bFull); 333 void SelectCurvePointByRay (vec3_t org, vec3_t dir, int buttons) 334 { 335 int i, besti; 336 float d, bestd; 337 vec3_t temp; 338 339 // find the point closest to the ray 340 besti = -1; 341 bestd = 8; 342 343 for (i=0 ; i<g_qeglobals.d_numpoints ; i++) 344 { 345 VectorSubtract (g_qeglobals.d_points[i], org, temp); 346 d = DotProduct (temp, dir); 347 VectorMA (org, d, dir, temp); 348 VectorSubtract (g_qeglobals.d_points[i], temp, temp); 349 d = VectorLength (temp); 350 if (d <= bestd) 351 { 352 bestd = d; 353 besti = i; 354 } 355 } 356 357 if (besti == -1) 358 { 359 if (g_pParentWnd->ActiveXY()->AreaSelectOK()) 360 { 361 g_qeglobals.d_select_mode = sel_area; 362 VectorCopy(org, g_qeglobals.d_vAreaTL); 363 VectorCopy(org, g_qeglobals.d_vAreaBR); 364 } 365 return; 366 } 367 //Sys_Printf ("hit vertex\n"); 368 AddPatchMovePoint(g_qeglobals.d_points[besti], buttons & MK_CONTROL, buttons & MK_SHIFT); 369 } 370 371 372