VERTSEL.CPP 11 KB

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