VERTSEL.CPP 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. #include "stdafx.h"
  19. #include "qe3.h"
  20. #include "winding.h"
  21. #define NEWEDGESEL 1
  22. int FindPoint (vec3_t point)
  23. {
  24. int i, j;
  25. for (i=0 ; i<g_qeglobals.d_numpoints ; i++)
  26. {
  27. for (j=0 ; j<3 ; j++)
  28. if (fabs(point[j] - g_qeglobals.d_points[i][j]) > 0.1)
  29. break;
  30. if (j == 3)
  31. return i;
  32. }
  33. VectorCopy (point, g_qeglobals.d_points[g_qeglobals.d_numpoints]);
  34. if (g_qeglobals.d_numpoints < MAX_POINTS-1)
  35. {
  36. g_qeglobals.d_numpoints++;
  37. }
  38. return g_qeglobals.d_numpoints-1;
  39. }
  40. int FindEdge (int p1, int p2, face_t *f)
  41. {
  42. int i;
  43. for (i=0 ; i<g_qeglobals.d_numedges ; i++)
  44. if (g_qeglobals.d_edges[i].p1 == p2 && g_qeglobals.d_edges[i].p2 == p1)
  45. {
  46. g_qeglobals.d_edges[i].f2 = f;
  47. return i;
  48. }
  49. g_qeglobals.d_edges[g_qeglobals.d_numedges].p1 = p1;
  50. g_qeglobals.d_edges[g_qeglobals.d_numedges].p2 = p2;
  51. g_qeglobals.d_edges[g_qeglobals.d_numedges].f1 = f;
  52. if (g_qeglobals.d_numedges < MAX_EDGES-1)
  53. {
  54. g_qeglobals.d_numedges++;
  55. }
  56. return g_qeglobals.d_numedges-1;
  57. }
  58. #ifdef NEWEDGESEL
  59. void MakeFace (brush_t* b, face_t *f)
  60. #else
  61. void MakeFace (face_t *f)
  62. #endif
  63. {
  64. winding_t *w;
  65. int i;
  66. int pnum[128];
  67. #ifdef NEWEDGESEL
  68. w = Brush_MakeFaceWinding (b, f);
  69. #else
  70. w = Brush_MakeFaceWinding (selected_brushes.next, f);
  71. #endif
  72. if (!w)
  73. return;
  74. for (i=0 ; i<w->numpoints ; i++)
  75. pnum[i] = FindPoint (w->points[i]);
  76. for (i=0 ; i<w->numpoints ; i++)
  77. FindEdge (pnum[i], pnum[(i+1)%w->numpoints], f);
  78. free (w);
  79. }
  80. void SetupVertexSelection (void)
  81. {
  82. face_t *f;
  83. brush_t *b;
  84. g_qeglobals.d_numpoints = 0;
  85. g_qeglobals.d_numedges = 0;
  86. #ifdef NEWEDGESEL
  87. for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  88. {
  89. for (f=b->brush_faces ; f ; f=f->next)
  90. MakeFace (b,f);
  91. }
  92. #else
  93. if (!QE_SingleBrush())
  94. return;
  95. b = selected_brushes.next;
  96. for (f=b->brush_faces ; f ; f=f->next)
  97. MakeFace (b,f);
  98. #endif
  99. }
  100. #ifdef NEWEDGESEL
  101. void SelectFaceEdge (brush_t* b, face_t *f, int p1, int p2)
  102. #else
  103. void SelectFaceEdge (face_t *f, int p1, int p2)
  104. #endif
  105. {
  106. winding_t *w;
  107. int i, j, k;
  108. int pnum[128];
  109. #ifdef NEWEDGESEL
  110. w = Brush_MakeFaceWinding (b, f);
  111. #else
  112. w = Brush_MakeFaceWinding (selected_brushes.next, f);
  113. #endif
  114. if (!w)
  115. return;
  116. for (i=0 ; i<w->numpoints ; i++)
  117. pnum[i] = FindPoint (w->points[i]);
  118. for (i=0 ; i<w->numpoints ; i++)
  119. if (pnum[i] == p1 && pnum[(i+1)%w->numpoints] == p2)
  120. {
  121. VectorCopy (g_qeglobals.d_points[pnum[i]], f->planepts[0]);
  122. VectorCopy (g_qeglobals.d_points[pnum[(i+1)%w->numpoints]], f->planepts[1]);
  123. VectorCopy (g_qeglobals.d_points[pnum[(i+2)%w->numpoints]], f->planepts[2]);
  124. for (j=0 ; j<3 ; j++)
  125. {
  126. for (k=0 ; k<3 ; k++)
  127. {
  128. f->planepts[j][k] = floor(f->planepts[j][k]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
  129. }
  130. }
  131. AddPlanept (f->planepts[0]);
  132. AddPlanept (f->planepts[1]);
  133. break;
  134. }
  135. if (i == w->numpoints)
  136. Sys_Printf ("SelectFaceEdge: failed\n");
  137. free (w);
  138. }
  139. void SelectVertex (int p1)
  140. {
  141. brush_t *b;
  142. winding_t *w;
  143. int i, j, k;
  144. face_t *f;
  145. #ifdef NEWEDGESEL
  146. for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  147. {
  148. for (f=b->brush_faces ; f ; f=f->next)
  149. {
  150. w = Brush_MakeFaceWinding (b, f);
  151. if (!w)
  152. continue;
  153. for (i=0 ; i<w->numpoints ; i++)
  154. {
  155. if (FindPoint (w->points[i]) == p1)
  156. {
  157. VectorCopy (w->points[(i+w->numpoints-1)%w->numpoints], f->planepts[0]);
  158. VectorCopy (w->points[i], f->planepts[1]);
  159. VectorCopy (w->points[(i+1)%w->numpoints], f->planepts[2]);
  160. for (j=0 ; j<3 ; j++)
  161. {
  162. for (k=0 ; k<3 ; k++)
  163. {
  164. ;//f->planepts[j][k] = floor(f->planepts[j][k]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
  165. }
  166. }
  167. AddPlanept (f->planepts[1]);
  168. //MessageBeep(-1);
  169. break;
  170. }
  171. }
  172. free (w);
  173. }
  174. }
  175. #else
  176. b = selected_brushes.next;
  177. for (f=b->brush_faces ; f ; f=f->next)
  178. {
  179. w = Brush_MakeFaceWinding (b, f);
  180. if (!w)
  181. continue;
  182. for (i=0 ; i<w->numpoints ; i++)
  183. {
  184. if (FindPoint (w->points[i]) == p1)
  185. {
  186. VectorCopy (w->points[(i+w->numpoints-1)%w->numpoints], f->planepts[0]);
  187. VectorCopy (w->points[i], f->planepts[1]);
  188. VectorCopy (w->points[(i+1)%w->numpoints], f->planepts[2]);
  189. for (j=0 ; j<3 ; j++)
  190. {
  191. for (k=0 ; k<3 ; k++)
  192. {
  193. ;//f->planepts[j][k] = floor(f->planepts[j][k]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
  194. }
  195. }
  196. AddPlanept (f->planepts[1]);
  197. //MessageBeep(-1);
  198. break;
  199. }
  200. }
  201. free (w);
  202. }
  203. #endif
  204. }
  205. void SelectEdgeByRay (vec3_t org, vec3_t dir)
  206. {
  207. int i, j, besti;
  208. float d, bestd;
  209. vec3_t mid, temp;
  210. pedge_t *e;
  211. // find the edge closest to the ray
  212. besti = -1;
  213. bestd = 8;
  214. for (i=0 ; i<g_qeglobals.d_numedges ; i++)
  215. {
  216. for (j=0 ; j<3 ; j++)
  217. 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]);
  218. VectorSubtract (mid, org, temp);
  219. d = DotProduct (temp, dir);
  220. VectorMA (org, d, dir, temp);
  221. VectorSubtract (mid, temp, temp);
  222. d = VectorLength (temp);
  223. if (d < bestd)
  224. {
  225. bestd = d;
  226. besti = i;
  227. }
  228. }
  229. if (besti == -1)
  230. {
  231. Sys_Printf ("Click didn't hit an edge\n");
  232. return;
  233. }
  234. Sys_Printf ("hit edge\n");
  235. // make the two faces that border the edge use the two edge points
  236. // as primary drag points
  237. g_qeglobals.d_num_move_points = 0;
  238. e = &g_qeglobals.d_edges[besti];
  239. #ifdef NEWEDGESEL
  240. for (brush_t* b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  241. {
  242. SelectFaceEdge (b, e->f1, e->p1, e->p2);
  243. SelectFaceEdge (b, e->f2, e->p2, e->p1);
  244. }
  245. #else
  246. SelectFaceEdge (e->f1, e->p1, e->p2);
  247. SelectFaceEdge (e->f2, e->p2, e->p1);
  248. #endif
  249. }
  250. void SelectVertexByRay (vec3_t org, vec3_t dir)
  251. {
  252. int i, besti;
  253. float d, bestd;
  254. vec3_t temp;
  255. // find the point closest to the ray
  256. besti = -1;
  257. bestd = 8;
  258. for (i=0 ; i<g_qeglobals.d_numpoints ; i++)
  259. {
  260. VectorSubtract (g_qeglobals.d_points[i], org, temp);
  261. d = DotProduct (temp, dir);
  262. VectorMA (org, d, dir, temp);
  263. VectorSubtract (g_qeglobals.d_points[i], temp, temp);
  264. d = VectorLength (temp);
  265. if (d < bestd)
  266. {
  267. bestd = d;
  268. besti = i;
  269. }
  270. }
  271. if (besti == -1)
  272. {
  273. Sys_Printf ("Click didn't hit a vertex\n");
  274. return;
  275. }
  276. Sys_Printf ("hit vertex\n");
  277. g_qeglobals.d_move_points[g_qeglobals.d_num_move_points++] = g_qeglobals.d_points[besti];
  278. //SelectVertex (besti);
  279. }
  280. extern void AddPatchMovePoint(vec3_t v, bool bMulti, bool bFull);
  281. void SelectCurvePointByRay (vec3_t org, vec3_t dir, int buttons)
  282. {
  283. int i, besti;
  284. float d, bestd;
  285. vec3_t temp;
  286. // find the point closest to the ray
  287. besti = -1;
  288. bestd = 8;
  289. for (i=0 ; i<g_qeglobals.d_numpoints ; i++)
  290. {
  291. VectorSubtract (g_qeglobals.d_points[i], org, temp);
  292. d = DotProduct (temp, dir);
  293. VectorMA (org, d, dir, temp);
  294. VectorSubtract (g_qeglobals.d_points[i], temp, temp);
  295. d = VectorLength (temp);
  296. if (d <= bestd)
  297. {
  298. bestd = d;
  299. besti = i;
  300. }
  301. }
  302. if (besti == -1)
  303. {
  304. if (g_pParentWnd->ActiveXY()->AreaSelectOK())
  305. {
  306. g_qeglobals.d_select_mode = sel_area;
  307. VectorCopy(org, g_qeglobals.d_vAreaTL);
  308. VectorCopy(org, g_qeglobals.d_vAreaBR);
  309. }
  310. return;
  311. }
  312. //Sys_Printf ("hit vertex\n");
  313. AddPatchMovePoint(g_qeglobals.d_points[besti], buttons & MK_CONTROL, buttons & MK_SHIFT);
  314. }