DRAG.CPP 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829
  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. /*
  21. drag either multiple brushes, or select plane points from
  22. a single brush.
  23. */
  24. qboolean drag_ok;
  25. vec3_t drag_xvec;
  26. vec3_t drag_yvec;
  27. static int buttonstate;
  28. int pressx, pressy;
  29. static vec3_t pressdelta;
  30. static vec3_t vPressStart;
  31. static int buttonx, buttony;
  32. //int num_move_points;
  33. //float *move_points[1024];
  34. int lastx, lasty;
  35. qboolean drag_first;
  36. void AxializeVector (vec3_t v)
  37. {
  38. vec3_t a;
  39. float o;
  40. int i;
  41. if (!v[0] && !v[1])
  42. return;
  43. if (!v[1] && !v[2])
  44. return;
  45. if (!v[0] && !v[2])
  46. return;
  47. for (i=0 ; i<3 ; i++)
  48. a[i] = fabs(v[i]);
  49. if (a[0] > a[1] && a[0] > a[2])
  50. i = 0;
  51. else if (a[1] > a[0] && a[1] > a[2])
  52. i = 1;
  53. else
  54. i = 2;
  55. o = v[i];
  56. VectorCopy (vec3_origin, v);
  57. if (o<0)
  58. v[i] = -1;
  59. else
  60. v[i] = 1;
  61. }
  62. /*
  63. ===========
  64. Drag_Setup
  65. ===========
  66. */
  67. void Drag_Setup (int x, int y, int buttons,
  68. vec3_t xaxis, vec3_t yaxis,
  69. vec3_t origin, vec3_t dir)
  70. {
  71. trace_t t;
  72. face_t *f;
  73. drag_first = true;
  74. VectorCopy (vec3_origin, pressdelta);
  75. pressx = x;
  76. pressy = y;
  77. VectorCopy (xaxis, drag_xvec);
  78. AxializeVector (drag_xvec);
  79. VectorCopy (yaxis, drag_yvec);
  80. AxializeVector (drag_yvec);
  81. if (g_qeglobals.d_select_mode == sel_addpoint) {
  82. if (g_qeglobals.selectObject) {
  83. g_qeglobals.selectObject->addPoint(origin[0], origin[1], origin[2]);
  84. } else {
  85. clearSelection();
  86. }
  87. return;
  88. }
  89. if (g_qeglobals.d_select_mode == sel_editpoint) {
  90. if (g_qeglobals.selectObject) {
  91. if (g_qeglobals.selectObject->selectPointByRay(origin[0], origin[1], origin[2], dir[0], dir[1], dir[2], !(buttons == MK_SHIFT)) >= 0) {
  92. drag_ok = true;
  93. }
  94. return;
  95. } else {
  96. clearSelection();
  97. }
  98. Sys_UpdateWindows(W_ALL);
  99. Undo_Start("drag object point");
  100. return;
  101. }
  102. extern void SelectCurvePointByRay (vec3_t org, vec3_t dir, int buttons);
  103. if (g_qeglobals.d_select_mode == sel_curvepoint)
  104. {
  105. //if ((buttons == MK_LBUTTON))
  106. // g_qeglobals.d_num_move_points = 0;
  107. SelectCurvePointByRay (origin, dir, buttons);
  108. if (g_qeglobals.d_num_move_points || g_qeglobals.d_select_mode == sel_area)
  109. {
  110. drag_ok = true;
  111. }
  112. Sys_UpdateWindows(W_ALL);
  113. Undo_Start("drag curve point");
  114. Undo_AddBrushList(&selected_brushes);
  115. return;
  116. }
  117. else if (g_qeglobals.d_select_mode == sel_terrainpoint)
  118. {
  119. Terrain_SelectPointByRay( origin, dir, buttons );
  120. if (g_qeglobals.d_numterrapoints || g_qeglobals.d_select_mode == sel_area)
  121. {
  122. drag_ok = true;
  123. }
  124. Sys_UpdateWindows(W_ALL);
  125. Undo_Start("drag terrain point");
  126. Undo_AddBrushList(&selected_brushes);
  127. return;
  128. }
  129. else if (g_qeglobals.d_select_mode == sel_terraintexture)
  130. {
  131. Terrain_SelectPointByRay( origin, dir, buttons );
  132. if (g_qeglobals.d_numterrapoints || g_qeglobals.d_select_mode == sel_area)
  133. {
  134. drag_ok = true;
  135. }
  136. Sys_UpdateWindows(W_ALL);
  137. Undo_Start("drag terrain point");
  138. Undo_AddBrushList(&selected_brushes);
  139. return;
  140. }
  141. else
  142. {
  143. g_qeglobals.d_num_move_points = 0;
  144. }
  145. if (selected_brushes.next == &selected_brushes)
  146. {
  147. //in this case a new brush is created when the dragging
  148. //takes place in the XYWnd, An useless undo is created
  149. //when the dragging takes place in the CamWnd
  150. Undo_Start("create brush");
  151. Sys_Status("No selection to drag\n", 0);
  152. return;
  153. }
  154. if (g_qeglobals.d_select_mode == sel_vertex)
  155. {
  156. SelectVertexByRay (origin, dir);
  157. if (g_qeglobals.d_num_move_points)
  158. {
  159. drag_ok = true;
  160. Undo_Start("drag vertex");
  161. Undo_AddBrushList(&selected_brushes);
  162. return;
  163. }
  164. }
  165. if (g_qeglobals.d_select_mode == sel_edge)
  166. {
  167. SelectEdgeByRay (origin, dir);
  168. if (g_qeglobals.d_num_move_points)
  169. {
  170. drag_ok = true;
  171. Undo_Start("drag edge");
  172. Undo_AddBrushList(&selected_brushes);
  173. return;
  174. }
  175. }
  176. //
  177. // check for direct hit first
  178. //
  179. t = Test_Ray (origin, dir, true);
  180. if (t.selected)
  181. {
  182. drag_ok = true;
  183. Undo_Start("drag selection");
  184. Undo_AddBrushList(&selected_brushes);
  185. if (buttons == (MK_LBUTTON|MK_CONTROL) )
  186. {
  187. Sys_Printf ("Shear dragging face\n");
  188. Brush_SelectFaceForDragging (t.brush, t.face, true);
  189. }
  190. else if (buttons == (MK_LBUTTON|MK_CONTROL|MK_SHIFT) )
  191. {
  192. Sys_Printf ("Sticky dragging brush\n");
  193. for (f=t.brush->brush_faces ; f ; f=f->next)
  194. Brush_SelectFaceForDragging (t.brush, f, false);
  195. }
  196. else
  197. Sys_Printf ("Dragging entire selection\n");
  198. return;
  199. }
  200. if (g_qeglobals.d_select_mode == sel_vertex || g_qeglobals.d_select_mode == sel_edge)
  201. return;
  202. //
  203. // check for side hit
  204. //
  205. // multiple brushes selected?
  206. if (selected_brushes.next->next != &selected_brushes)
  207. {
  208. // yes, special handling
  209. bool bOK = (g_PrefsDlg.m_bALTEdge) ? (static_cast<bool>(::GetAsyncKeyState(VK_MENU))) : true;
  210. if (bOK)
  211. {
  212. for (brush_t* pBrush = selected_brushes.next ; pBrush != &selected_brushes ; pBrush = pBrush->next)
  213. {
  214. if (buttons & MK_CONTROL)
  215. Brush_SideSelect (pBrush, origin, dir, true);
  216. else
  217. Brush_SideSelect (pBrush, origin, dir, false);
  218. }
  219. }
  220. else
  221. {
  222. Sys_Printf ("press ALT to drag multiple edges\n");
  223. return;
  224. }
  225. }
  226. else
  227. {
  228. // single select.. trying to drag fixed entities handle themselves and just move
  229. if (buttons & MK_CONTROL)
  230. Brush_SideSelect (selected_brushes.next, origin, dir, true);
  231. else
  232. Brush_SideSelect (selected_brushes.next, origin, dir, false);
  233. }
  234. Sys_Printf ("Side stretch\n");
  235. drag_ok = true;
  236. Undo_Start("side stretch");
  237. Undo_AddBrushList(&selected_brushes);
  238. }
  239. entity_t *peLink;
  240. void UpdateTarget(vec3_t origin, vec3_t dir)
  241. {
  242. trace_t t;
  243. entity_t *pe;
  244. int i;
  245. char sz[128];
  246. t = Test_Ray (origin, dir, 0);
  247. if (!t.brush)
  248. return;
  249. pe = t.brush->owner;
  250. if (pe == NULL)
  251. return;
  252. // is this the first?
  253. if (peLink != NULL)
  254. {
  255. // Get the target id from out current target
  256. // if there is no id, make one
  257. i = IntForKey(pe, "target");
  258. if (i <= 0)
  259. {
  260. i = GetUniqueTargetId(1);
  261. sprintf(sz, "%d", i);
  262. SetKeyValue(pe, "target", sz);
  263. }
  264. // set the target # into our src
  265. sprintf(sz, "%d", i);
  266. SetKeyValue(peLink, "targetname", sz);
  267. Sys_UpdateWindows(W_ENTITY);
  268. }
  269. // promote the target to the src
  270. peLink = pe;
  271. }
  272. /*
  273. ===========
  274. Drag_Begin
  275. //++timo test three button mouse and three button emulation here ?
  276. ===========
  277. */
  278. void Drag_Begin (int x, int y, int buttons,
  279. vec3_t xaxis, vec3_t yaxis,
  280. vec3_t origin, vec3_t dir)
  281. {
  282. trace_t t;
  283. bool altdown;
  284. drag_ok = false;
  285. VectorCopy (vec3_origin, pressdelta);
  286. VectorCopy (vec3_origin, vPressStart);
  287. drag_first = true;
  288. peLink = NULL;
  289. altdown = static_cast<bool>(::GetAsyncKeyState(VK_MENU));
  290. // shift-LBUTTON = select entire brush
  291. if (buttons == (MK_LBUTTON | MK_SHIFT) && g_qeglobals.d_select_mode != sel_curvepoint &&
  292. g_qeglobals.d_select_mode != sel_terrainpoint && g_qeglobals.d_select_mode != sel_terraintexture)
  293. {
  294. int nFlag = altdown ? SF_CYCLE : 0;
  295. if (dir[0] == 0 || dir[1] == 0 || dir[2] == 0) // extremely low chance of this happening from camera
  296. Select_Ray (origin, dir, nFlag | SF_ENTITIES_FIRST); // hack for XY
  297. else
  298. Select_Ray (origin, dir, nFlag);
  299. return;
  300. }
  301. // ctrl-alt-LBUTTON = multiple brush select without selecting whole entities
  302. if (buttons == (MK_LBUTTON | MK_CONTROL) && altdown && g_qeglobals.d_select_mode != sel_curvepoint &&
  303. g_qeglobals.d_select_mode != sel_terrainpoint && g_qeglobals.d_select_mode != sel_terraintexture)
  304. {
  305. if (dir[0] == 0 || dir[1] == 0 || dir[2] == 0) // extremely low chance of this happening from camera
  306. Select_Ray (origin, dir, SF_ENTITIES_FIRST); // hack for XY
  307. else
  308. Select_Ray (origin, dir, 0);
  309. return;
  310. }
  311. // ctrl-shift-LBUTTON = select single face
  312. if (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT) && g_qeglobals.d_select_mode != sel_curvepoint &&
  313. g_qeglobals.d_select_mode != sel_terrainpoint && g_qeglobals.d_select_mode != sel_terraintexture)
  314. {
  315. Select_Deselect (!static_cast<bool>(::GetAsyncKeyState(VK_MENU)));
  316. Select_Ray (origin, dir, SF_SINGLEFACE);
  317. return;
  318. }
  319. // LBUTTON + all other modifiers = manipulate selection
  320. if (buttons & MK_LBUTTON)
  321. {
  322. //
  323. Drag_Setup (x, y, buttons, xaxis, yaxis, origin, dir);
  324. return;
  325. }
  326. int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON;
  327. // middle button = grab texture
  328. if (buttons == nMouseButton)
  329. {
  330. t = Test_Ray (origin, dir, false);
  331. if (t.face)
  332. {
  333. g_qeglobals.d_new_brush_bottom_z = t.brush->mins[2];
  334. g_qeglobals.d_new_brush_top_z = t.brush->maxs[2];
  335. // use a local brushprimit_texdef fitted to a default 2x2 texture
  336. brushprimit_texdef_t bp_local;
  337. ConvertTexMatWithQTexture( &t.face->brushprimit_texdef, t.face->d_texture, &bp_local, NULL );
  338. Texture_SetTexture ( &t.face->texdef, &bp_local, false, GETPLUGINTEXDEF(t.face));
  339. UpdateSurfaceDialog();
  340. UpdatePatchInspector();
  341. }
  342. else
  343. Sys_Printf ("Did not select a texture\n");
  344. return;
  345. }
  346. // ctrl-middle button = set entire brush to texture
  347. if (buttons == (nMouseButton|MK_CONTROL) )
  348. {
  349. t = Test_Ray (origin, dir, false);
  350. if (t.brush)
  351. {
  352. if (t.brush->brush_faces->texdef.name[0] == '(')
  353. Sys_Printf ("Can't change an entity texture\n");
  354. else
  355. {
  356. Brush_SetTexture (t.brush, &g_qeglobals.d_texturewin.texdef, &g_qeglobals.d_texturewin.brushprimit_texdef, false, static_cast<IPluginTexdef *>( g_qeglobals.d_texturewin.pTexdef ) );
  357. Sys_UpdateWindows (W_ALL);
  358. }
  359. }
  360. else
  361. Sys_Printf ("Didn't hit a btrush\n");
  362. return;
  363. }
  364. // ctrl-shift-middle button = set single face to texture
  365. if (buttons == (nMouseButton|MK_SHIFT|MK_CONTROL) )
  366. {
  367. t = Test_Ray (origin, dir, false);
  368. if (t.brush)
  369. {
  370. if (t.brush->brush_faces->texdef.name[0] == '(')
  371. Sys_Printf ("Can't change an entity texture\n");
  372. else
  373. {
  374. SetFaceTexdef (t.brush, t.face, &g_qeglobals.d_texturewin.texdef, &g_qeglobals.d_texturewin.brushprimit_texdef);
  375. Brush_Build( t.brush );
  376. Sys_UpdateWindows (W_ALL);
  377. }
  378. }
  379. else
  380. Sys_Printf ("Didn't hit a btrush\n");
  381. return;
  382. }
  383. if (buttons == (nMouseButton | MK_SHIFT))
  384. {
  385. Sys_Printf("Set brush face texture info\n");
  386. t = Test_Ray (origin, dir, false);
  387. if (t.brush)
  388. {
  389. if (t.brush->brush_faces->texdef.name[0] == '(')
  390. {
  391. if (t.brush->owner->eclass->nShowFlags & ECLASS_LIGHT)
  392. {
  393. CString strBuff;
  394. qtexture_t* pTex = Texture_ForName(g_qeglobals.d_texturewin.texdef.name);
  395. if (pTex)
  396. {
  397. vec3_t vColor;
  398. VectorCopy(pTex->color, vColor);
  399. float fLargest = 0.0f;
  400. for (int i = 0; i < 3; i++)
  401. {
  402. if (vColor[i] > fLargest)
  403. fLargest = vColor[i];
  404. }
  405. if (fLargest == 0.0f)
  406. {
  407. vColor[0] = vColor[1] = vColor[2] = 1.0f;
  408. }
  409. else
  410. {
  411. float fScale = 1.0f / fLargest;
  412. for (int i = 0; i < 3; i++)
  413. {
  414. vColor[i] *= fScale;
  415. }
  416. }
  417. strBuff.Format("%f %f %f",pTex->color[0], pTex->color[1], pTex->color[2]);
  418. SetKeyValue(t.brush->owner, "_color", strBuff.GetBuffer(0));
  419. Sys_UpdateWindows (W_ALL);
  420. }
  421. }
  422. else
  423. {
  424. Sys_Printf ("Can't select an entity brush face\n");
  425. }
  426. }
  427. else
  428. {
  429. //strcpy(t.face->texdef.name,g_qeglobals.d_texturewin.texdef.name);
  430. t.face->texdef.SetName(g_qeglobals.d_texturewin.texdef.name);
  431. Brush_Build(t.brush);
  432. Sys_UpdateWindows (W_ALL);
  433. }
  434. }
  435. else
  436. Sys_Printf ("Didn't hit a brush\n");
  437. return;
  438. }
  439. }
  440. //
  441. //===========
  442. //MoveSelection
  443. //===========
  444. //
  445. void MoveSelection (vec3_t move)
  446. {
  447. int i, success;
  448. brush_t *b;
  449. CString strStatus;
  450. vec3_t vTemp, vTemp2, end;
  451. if (!move[0] && !move[1] && !move[2])
  452. return;
  453. move[0] = (g_nScaleHow & SCALE_X) ? 0 : move[0];
  454. move[1] = (g_nScaleHow & SCALE_Y) ? 0 : move[1];
  455. move[2] = (g_nScaleHow & SCALE_Z) ? 0 : move[2];
  456. if (g_pParentWnd->ActiveXY()->RotateMode() || g_bPatchBendMode)
  457. {
  458. float fDeg = -move[2];
  459. float fAdj = move[2];
  460. int nAxis = 0;
  461. if (g_pParentWnd->ActiveXY()->GetViewType() == XY)
  462. {
  463. fDeg = -move[1];
  464. fAdj = move[1];
  465. nAxis = 2;
  466. }
  467. else
  468. if (g_pParentWnd->ActiveXY()->GetViewType() == XZ)
  469. {
  470. fDeg = move[2];
  471. fAdj = move[2];
  472. nAxis = 1;
  473. }
  474. else
  475. nAxis = 0;
  476. g_pParentWnd->ActiveXY()->Rotation()[nAxis] += fAdj;
  477. strStatus.Format("%s x:: %.1f y:: %.1f z:: %.1f", (g_bPatchBendMode) ? "Bend angle" : "Rotation", g_pParentWnd->ActiveXY()->Rotation()[0], g_pParentWnd->ActiveXY()->Rotation()[1], g_pParentWnd->ActiveXY()->Rotation()[2]);
  478. g_pParentWnd->SetStatusText(2, strStatus);
  479. if (g_bPatchBendMode)
  480. {
  481. Patch_SelectBendNormal();
  482. Select_RotateAxis(nAxis, fDeg*2, false, true);
  483. Patch_SelectBendAxis();
  484. Select_RotateAxis(nAxis, fDeg, false, true);
  485. }
  486. else
  487. {
  488. Select_RotateAxis(nAxis, fDeg, false, true);
  489. }
  490. return;
  491. }
  492. if (g_pParentWnd->ActiveXY()->ScaleMode())
  493. {
  494. vec3_t v;
  495. v[0] = v[1] = v[2] = 1.0;
  496. if (move[1] > 0)
  497. {
  498. v[0] = 1.1;
  499. v[1] = 1.1;
  500. v[2] = 1.1;
  501. }
  502. else
  503. if (move[1] < 0)
  504. {
  505. v[0] = 0.9;
  506. v[1] = 0.9;
  507. v[2] = 0.9;
  508. }
  509. Select_Scale((g_nScaleHow & SCALE_X) ? 1.0 : v[0],
  510. (g_nScaleHow & SCALE_Y) ? 1.0 : v[1],
  511. (g_nScaleHow & SCALE_Z) ? 1.0 : v[2]);
  512. Sys_UpdateWindows (W_ALL);
  513. return;
  514. }
  515. vec3_t vDistance;
  516. VectorSubtract(pressdelta, vPressStart, vDistance);
  517. strStatus.Format("Distance x: %.1f y: %.1f z: %.1f", vDistance[0], vDistance[1], vDistance[2]);
  518. g_pParentWnd->SetStatusText(3, strStatus);
  519. //
  520. // dragging only a part of the selection
  521. //
  522. //point object selection
  523. if (g_qeglobals.d_select_mode == sel_editpoint) {
  524. if (g_qeglobals.selectObject) {
  525. g_qeglobals.selectObject->updateSelection(move[0], move[1], move[2]);
  526. }
  527. return;
  528. }
  529. // this is fairly crappy way to deal with curvepoint and area selection
  530. // but it touches the smallest amount of code this way
  531. //
  532. if (g_qeglobals.d_num_move_points || g_qeglobals.d_numterrapoints || g_qeglobals.d_select_mode == sel_area)
  533. {
  534. //area selection
  535. if (g_qeglobals.d_select_mode == sel_area)
  536. {
  537. VectorAdd(g_qeglobals.d_vAreaBR, move, g_qeglobals.d_vAreaBR);
  538. return;
  539. }
  540. //curve point selection
  541. if (g_qeglobals.d_select_mode == sel_curvepoint)
  542. {
  543. Patch_UpdateSelected(move);
  544. return;
  545. }
  546. //terrain point selection
  547. if ( ( g_qeglobals.d_select_mode == sel_terrainpoint ) || ( g_qeglobals.d_select_mode == sel_terraintexture ) )
  548. {
  549. Terrain_UpdateSelected(move);
  550. return;
  551. }
  552. //vertex selection
  553. if (g_qeglobals.d_select_mode == sel_vertex)
  554. {
  555. success = true;
  556. for (b = selected_brushes.next; b != &selected_brushes; b = b->next)
  557. {
  558. success &= Brush_MoveVertex(b, g_qeglobals.d_move_points[0], move, end, true);
  559. }
  560. if (success)
  561. VectorCopy(end, g_qeglobals.d_move_points[0]);
  562. return;
  563. }
  564. //all other selection types
  565. for (i=0 ; i<g_qeglobals.d_num_move_points ; i++)
  566. VectorAdd (g_qeglobals.d_move_points[i], move, g_qeglobals.d_move_points[i]);
  567. //VectorScale(move, .5, move);
  568. //for (i=0 ; i<g_qeglobals.d_num_move_points2 ; i++)
  569. // VectorAdd (g_qeglobals.d_move_points2[i], move, g_qeglobals.d_move_points2[i]);
  570. for (b = selected_brushes.next; b != &selected_brushes; b = b->next)
  571. {
  572. VectorCopy(b->maxs, vTemp);
  573. VectorSubtract(vTemp, b->mins, vTemp);
  574. Brush_Build( b );
  575. for (i=0 ; i<3 ; i++)
  576. if (b->mins[i] > b->maxs[i]
  577. || b->maxs[i] - b->mins[i] > MAX_BRUSH_SIZE)
  578. break; // dragged backwards or fucked up
  579. if (i != 3)
  580. break;
  581. if (b->patchBrush)
  582. {
  583. VectorCopy(b->maxs, vTemp2);
  584. VectorSubtract(vTemp2, b->mins, vTemp2);
  585. VectorSubtract(vTemp2, vTemp, vTemp2);
  586. //if (!Patch_DragScale(b->nPatchID, vTemp2, move))
  587. if (!Patch_DragScale(b->pPatch, vTemp2, move))
  588. {
  589. b = NULL;
  590. break;
  591. }
  592. }
  593. if (b->terrainBrush)
  594. {
  595. VectorCopy(b->maxs, vTemp2);
  596. VectorSubtract(vTemp2, b->mins, vTemp2);
  597. VectorSubtract(vTemp2, vTemp, vTemp2);
  598. if (!Terrain_DragScale(b->pTerrain, vTemp2, move))
  599. {
  600. b = NULL;
  601. break;
  602. }
  603. }
  604. }
  605. // if any of the brushes were crushed out of existance
  606. // calcel the entire move
  607. if (b != &selected_brushes)
  608. {
  609. Sys_Printf ("Brush dragged backwards, move canceled\n");
  610. for (i=0 ; i<g_qeglobals.d_num_move_points ; i++)
  611. VectorSubtract (g_qeglobals.d_move_points[i], move, g_qeglobals.d_move_points[i]);
  612. for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  613. Brush_Build( b );
  614. }
  615. }
  616. else
  617. {
  618. // reset face originals from vertex edit mode
  619. // this is dirty, but unfortunately necessary because Brush_Build
  620. // can remove windings
  621. for (b = selected_brushes.next; b != &selected_brushes; b = b->next)
  622. {
  623. Brush_ResetFaceOriginals(b);
  624. }
  625. //
  626. // if there are lots of brushes selected, just translate instead
  627. // of rebuilding the brushes
  628. //
  629. if (drag_yvec[2] == 0 && selected_brushes.next->next != &selected_brushes)
  630. {
  631. Select_Move (move);
  632. //VectorAdd (g_qeglobals.d_select_translate, move, g_qeglobals.d_select_translate);
  633. }
  634. else
  635. {
  636. Select_Move (move);
  637. }
  638. }
  639. }
  640. /*
  641. ===========
  642. Drag_MouseMoved
  643. ===========
  644. */
  645. void Drag_MouseMoved (int x, int y, int buttons)
  646. {
  647. vec3_t move, delta;
  648. int i;
  649. if (!buttons)
  650. {
  651. drag_ok = false;
  652. return;
  653. }
  654. if (!drag_ok)
  655. return;
  656. // clear along one axis
  657. if (buttons & MK_SHIFT)
  658. {
  659. drag_first = false;
  660. if (abs(x-pressx) > abs(y-pressy))
  661. y = pressy;
  662. else
  663. x = pressx;
  664. }
  665. for (i=0 ; i<3 ; i++)
  666. {
  667. move[i] = drag_xvec[i]*(x - pressx) + drag_yvec[i]*(y - pressy);
  668. if (!g_PrefsDlg.m_bNoClamp)
  669. {
  670. move[i] = floor(move[i]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
  671. }
  672. }
  673. VectorSubtract (move, pressdelta, delta);
  674. VectorCopy (move, pressdelta);
  675. MoveSelection (delta);
  676. }
  677. /*
  678. ===========
  679. Drag_MouseUp
  680. ===========
  681. */
  682. void Drag_MouseUp (int nButtons)
  683. {
  684. Sys_Status ("drag completed.", 0);
  685. if (g_qeglobals.d_select_mode == sel_area)
  686. {
  687. if ( OnlyTerrainSelected() )
  688. {
  689. Terrain_SelectAreaPoints();
  690. g_qeglobals.d_select_mode = sel_terrainpoint;
  691. Sys_UpdateWindows (W_ALL);
  692. }
  693. else
  694. {
  695. Patch_SelectAreaPoints();
  696. g_qeglobals.d_select_mode = sel_curvepoint;
  697. Sys_UpdateWindows (W_ALL);
  698. }
  699. }
  700. if (g_qeglobals.d_select_translate[0] || g_qeglobals.d_select_translate[1] || g_qeglobals.d_select_translate[2])
  701. {
  702. Select_Move (g_qeglobals.d_select_translate);
  703. VectorCopy (vec3_origin, g_qeglobals.d_select_translate);
  704. Sys_UpdateWindows (W_CAMERA);
  705. }
  706. g_pParentWnd->SetStatusText(3, "");
  707. //
  708. Undo_EndBrushList(&selected_brushes);
  709. Undo_End();
  710. }