SELECT.CPP 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801
  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. // select.c
  19. #include "stdafx.h"
  20. #include "qe3.h"
  21. // externs
  22. CPtrArray g_SelectedFaces;
  23. CPtrArray g_SelectedFaceBrushes;
  24. CPtrArray& g_ptrSelectedFaces = g_SelectedFaces;
  25. CPtrArray& g_ptrSelectedFaceBrushes = g_SelectedFaceBrushes;
  26. void clearSelection() {
  27. g_qeglobals.d_select_mode = sel_brush;
  28. g_qeglobals.selectObject = NULL;
  29. }
  30. /*
  31. ===========
  32. Test_Ray
  33. ===========
  34. */
  35. #define DIST_START 999999
  36. trace_t Test_Ray (vec3_t origin, vec3_t dir, int flags)
  37. {
  38. brush_t *brush;
  39. face_t *face;
  40. float dist;
  41. trace_t t;
  42. memset (&t, 0, sizeof(t));
  43. t.dist = DIST_START;
  44. if (flags & SF_CYCLE)
  45. {
  46. CPtrArray array;
  47. brush_t *pToSelect = (selected_brushes.next != &selected_brushes) ? selected_brushes.next : NULL;
  48. Select_Deselect();
  49. // go through active brushes and accumulate all "hit" brushes
  50. for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next)
  51. {
  52. //if ( (flags & SF_ENTITIES_FIRST) && brush->owner == world_entity)
  53. // continue;
  54. if (FilterBrush (brush))
  55. continue;
  56. if (!g_PrefsDlg.m_bSelectCurves && brush->patchBrush)
  57. continue;
  58. if( !g_PrefsDlg.m_bSelectTerrain && brush->terrainBrush )
  59. continue;
  60. //if (!g_bShowPatchBounds && brush->patchBrush)
  61. // continue;
  62. face = Brush_Ray (origin, dir, brush, &dist);
  63. if (face)
  64. {
  65. if ( brush->terrainBrush )
  66. {
  67. Terrain_Ray( origin, dir, brush, &dist );
  68. if( dist == 0 )
  69. {
  70. // didn't actually hit the terrain
  71. continue;
  72. }
  73. }
  74. array.Add(brush);
  75. }
  76. }
  77. int nSize = array.GetSize();
  78. if (nSize > 0)
  79. {
  80. bool bFound = false;
  81. for (int i = 0; i < nSize; i++)
  82. {
  83. brush_t *b = reinterpret_cast<brush_t*>(array.GetAt(i));
  84. // did we hit the last one selected yet ?
  85. if (b == pToSelect)
  86. {
  87. // yes we want to select the next one in the list
  88. int n = (i > 0) ? i-1 : nSize-1;
  89. pToSelect = reinterpret_cast<brush_t*>(array.GetAt(n));
  90. bFound = true;
  91. break;
  92. }
  93. }
  94. if (!bFound)
  95. pToSelect = reinterpret_cast<brush_t*>(array.GetAt(0));
  96. }
  97. if (pToSelect)
  98. {
  99. face = Brush_Ray (origin, dir, pToSelect, &dist);
  100. if ( pToSelect->terrainBrush )
  101. {
  102. t.terraface = Terrain_Ray( origin, dir, pToSelect, &dist );
  103. }
  104. t.dist = dist;
  105. t.brush = pToSelect;
  106. t.face = face;
  107. t.selected = false;
  108. return t;
  109. }
  110. }
  111. if (! (flags & SF_SELECTED_ONLY) )
  112. {
  113. for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next)
  114. {
  115. if ( (flags & SF_ENTITIES_FIRST) && brush->owner == world_entity)
  116. continue;
  117. if (FilterBrush (brush))
  118. continue;
  119. if (!g_PrefsDlg.m_bSelectCurves && brush->patchBrush)
  120. continue;
  121. if( !g_PrefsDlg.m_bSelectTerrain && brush->terrainBrush )
  122. continue;
  123. //if (!g_bShowPatchBounds && brush->patchBrush)
  124. // continue;
  125. face = Brush_Ray (origin, dir, brush, &dist);
  126. if ( face ) {
  127. if ( brush->terrainBrush )
  128. {
  129. t.terraface = Terrain_Ray( origin, dir, brush, &dist );
  130. }
  131. }
  132. if (dist > 0 && dist < t.dist)
  133. {
  134. t.dist = dist;
  135. t.brush = brush;
  136. t.face = face;
  137. t.selected = false;
  138. }
  139. }
  140. }
  141. for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next)
  142. {
  143. if ( (flags & SF_ENTITIES_FIRST) && brush->owner == world_entity)
  144. continue;
  145. if (FilterBrush (brush))
  146. continue;
  147. if (!g_PrefsDlg.m_bSelectCurves && brush->patchBrush)
  148. continue;
  149. if( !g_PrefsDlg.m_bSelectTerrain && brush->terrainBrush )
  150. continue;
  151. face = Brush_Ray (origin, dir, brush, &dist);
  152. if ( face ) {
  153. if ( brush->terrainBrush )
  154. {
  155. t.terraface = Terrain_Ray( origin, dir, brush, &dist );
  156. }
  157. }
  158. if (dist > 0 && dist < t.dist)
  159. {
  160. t.dist = dist;
  161. t.brush = brush;
  162. t.face = face;
  163. t.selected = true;
  164. }
  165. }
  166. // if entites first, but didn't find any, check regular
  167. if ( (flags & SF_ENTITIES_FIRST) && t.brush == NULL)
  168. return Test_Ray (origin, dir, flags - SF_ENTITIES_FIRST);
  169. return t;
  170. }
  171. /*
  172. ============
  173. Select_Brush
  174. ============
  175. */
  176. void Select_Brush (brush_t *brush, bool bComplete, bool bStatus)
  177. {
  178. brush_t *b;
  179. entity_t *e;
  180. g_ptrSelectedFaces.RemoveAll();
  181. g_ptrSelectedFaceBrushes.RemoveAll();
  182. //selected_face = NULL;
  183. if (g_qeglobals.d_select_count < 2)
  184. g_qeglobals.d_select_order[g_qeglobals.d_select_count] = brush;
  185. g_qeglobals.d_select_count++;
  186. //if (brush->patchBrush)
  187. // Patch_Select(brush->nPatchID);
  188. e = brush->owner;
  189. if (e)
  190. {
  191. // select complete entity on first click
  192. if (e != world_entity && bComplete == true)
  193. {
  194. for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  195. if (b->owner == e)
  196. goto singleselect;
  197. for (b=e->brushes.onext ; b != &e->brushes ; b=b->onext)
  198. {
  199. Brush_RemoveFromList (b);
  200. Brush_AddToList (b, &selected_brushes);
  201. }
  202. }
  203. else
  204. {
  205. singleselect:
  206. Brush_RemoveFromList (brush);
  207. Brush_AddToList (brush, &selected_brushes);
  208. UpdateSurfaceDialog();
  209. UpdatePatchInspector();
  210. }
  211. if (e->eclass)
  212. {
  213. UpdateEntitySel(brush->owner->eclass);
  214. }
  215. }
  216. if (bStatus)
  217. {
  218. vec3_t vMin, vMax, vSize;
  219. Select_GetBounds (vMin, vMax);
  220. VectorSubtract(vMax, vMin, vSize);
  221. CString strStatus;
  222. strStatus.Format("Selection X:: %.1f Y:: %.1f Z:: %.1f", vSize[0], vSize[1], vSize[2]);
  223. g_pParentWnd->SetStatusText(2, strStatus);
  224. }
  225. }
  226. /*
  227. ============
  228. Select_Ray
  229. If the origin is inside a brush, that brush will be ignored.
  230. ============
  231. */
  232. void Select_Ray (vec3_t origin, vec3_t dir, int flags)
  233. {
  234. trace_t t;
  235. t = Test_Ray (origin, dir, flags);
  236. if (!t.brush)
  237. return;
  238. if (flags == SF_SINGLEFACE)
  239. {
  240. int nCount = g_SelectedFaces.GetSize();
  241. bool bOk = true;
  242. for (int i = 0; i < nCount; i++)
  243. {
  244. if (t.face == reinterpret_cast<face_t*>(g_SelectedFaces.GetAt(i)))
  245. {
  246. bOk = false;
  247. // need to move remove i'th entry
  248. g_SelectedFaces.RemoveAt(i, 1);
  249. g_SelectedFaceBrushes.RemoveAt(i, 1);
  250. }
  251. }
  252. if (bOk)
  253. {
  254. g_SelectedFaces.Add(t.face);
  255. g_SelectedFaceBrushes.Add(t.brush);
  256. }
  257. //selected_face = t.face;
  258. //selected_face_brush = t.brush;
  259. Sys_UpdateWindows (W_ALL);
  260. clearSelection();
  261. // Texture_SetTexture requires a brushprimit_texdef fitted to the default width=2 height=2 texture
  262. brushprimit_texdef_t brushprimit_texdef;
  263. ConvertTexMatWithQTexture ( &t.face->brushprimit_texdef, t.face->d_texture, &brushprimit_texdef, NULL );
  264. Texture_SetTexture ( &t.face->texdef, &brushprimit_texdef, false, GETPLUGINTEXDEF(t.face), false );
  265. UpdateSurfaceDialog();
  266. return;
  267. }
  268. // move the brush to the other list
  269. clearSelection();
  270. if (t.selected)
  271. {
  272. Brush_RemoveFromList (t.brush);
  273. Brush_AddToList (t.brush, &active_brushes);
  274. UpdatePatchInspector();
  275. }
  276. else
  277. {
  278. Select_Brush (t.brush, !(GetKeyState(VK_MENU) & 0x8000));
  279. }
  280. Sys_UpdateWindows (W_ALL);
  281. }
  282. void Select_Delete (void)
  283. {
  284. brush_t *brush;
  285. g_ptrSelectedFaces.RemoveAll();
  286. g_ptrSelectedFaceBrushes.RemoveAll();
  287. //selected_face = NULL;
  288. clearSelection();
  289. g_qeglobals.d_select_count = 0;
  290. g_qeglobals.d_num_move_points = 0;
  291. while (selected_brushes.next != &selected_brushes)
  292. {
  293. brush = selected_brushes.next;
  294. if (brush->patchBrush)
  295. {
  296. //Patch_Delete(brush->nPatchID);
  297. Patch_Delete(brush->pPatch);
  298. }
  299. if (brush->terrainBrush)
  300. {
  301. Terrain_Delete(brush->pTerrain );
  302. }
  303. Brush_Free (brush);
  304. }
  305. // FIXME: remove any entities with no brushes
  306. Sys_UpdateWindows (W_ALL);
  307. }
  308. void Select_Deselect (bool bDeselectFaces)
  309. {
  310. brush_t *b;
  311. Patch_Deselect();
  312. g_pParentWnd->ActiveXY()->UndoClear();
  313. g_qeglobals.d_workcount++;
  314. g_qeglobals.d_select_count = 0;
  315. g_qeglobals.d_num_move_points = 0;
  316. b = selected_brushes.next;
  317. if (b == &selected_brushes)
  318. {
  319. if (bDeselectFaces)
  320. {
  321. g_ptrSelectedFaces.RemoveAll();
  322. g_ptrSelectedFaceBrushes.RemoveAll();
  323. //selected_face = NULL;
  324. }
  325. Sys_UpdateWindows (W_ALL);
  326. return;
  327. }
  328. if (bDeselectFaces)
  329. {
  330. g_ptrSelectedFaces.RemoveAll();
  331. g_ptrSelectedFaceBrushes.RemoveAll();
  332. //selected_face = NULL;
  333. }
  334. clearSelection();
  335. // grab top / bottom height for new brushes
  336. if (b->mins[2] < b->maxs[2])
  337. {
  338. g_qeglobals.d_new_brush_bottom_z = b->mins[2];
  339. g_qeglobals.d_new_brush_top_z = b->maxs[2];
  340. }
  341. selected_brushes.next->prev = &active_brushes;
  342. selected_brushes.prev->next = active_brushes.next;
  343. active_brushes.next->prev = selected_brushes.prev;
  344. active_brushes.next = selected_brushes.next;
  345. selected_brushes.prev = selected_brushes.next = &selected_brushes;
  346. Sys_UpdateWindows (W_ALL);
  347. }
  348. /*
  349. ============
  350. Select_Move
  351. ============
  352. */
  353. void Select_Move (vec3_t delta, bool bSnap)
  354. {
  355. brush_t *b;
  356. // actually move the selected brushes
  357. for (b = selected_brushes.next ; b != &selected_brushes ; b=b->next)
  358. Brush_Move (b, delta, bSnap);
  359. vec3_t vMin, vMax;
  360. Select_GetBounds (vMin, vMax);
  361. CString strStatus;
  362. strStatus.Format("Origin X:: %.1f Y:: %.1f Z:: %.1f", vMin[0], vMax[1], vMax[2]);
  363. g_pParentWnd->SetStatusText(2, strStatus);
  364. // Sys_UpdateWindows (W_ALL);
  365. }
  366. /*
  367. ============
  368. Select_Clone
  369. Creates an exact duplicate of the selection in place, then moves
  370. the selected brushes off of their old positions
  371. ============
  372. */
  373. void Select_Clone (void)
  374. {
  375. #if 1
  376. ASSERT(g_pParentWnd->ActiveXY());
  377. g_bScreenUpdates = false;
  378. g_pParentWnd->ActiveXY()->Copy();
  379. g_pParentWnd->ActiveXY()->Paste();
  380. g_pParentWnd->NudgeSelection(2, g_qeglobals.d_gridsize);
  381. g_pParentWnd->NudgeSelection(3, g_qeglobals.d_gridsize);
  382. g_bScreenUpdates = true;
  383. Sys_UpdateWindows(W_ALL);
  384. #else
  385. brush_t *b, *b2, *n, *next, *next2;
  386. vec3_t delta;
  387. entity_t *e;
  388. g_qeglobals.d_workcount++;
  389. clearSelection();
  390. delta[0] = g_qeglobals.d_gridsize;
  391. delta[1] = g_qeglobals.d_gridsize;
  392. delta[2] = 0;
  393. for (b=selected_brushes.next ; b != &selected_brushes ; b=next)
  394. {
  395. next = b->next;
  396. // if the brush is a world brush, handle simply
  397. if (b->owner == world_entity)
  398. {
  399. n = Brush_Clone (b);
  400. Brush_AddToList (n, &active_brushes);
  401. Entity_LinkBrush (world_entity, n);
  402. Brush_Build( n );
  403. Brush_Move (b, delta);
  404. continue;
  405. }
  406. e = Entity_Clone (b->owner);
  407. // clear the target / targetname
  408. DeleteKey (e, "target");
  409. DeleteKey (e, "targetname");
  410. // if the brush is a fixed size entity, create a new entity
  411. if (b->owner->eclass->fixedsize)
  412. {
  413. n = Brush_Clone (b);
  414. Brush_AddToList (n, &active_brushes);
  415. Entity_LinkBrush (e, n);
  416. Brush_Build( n );
  417. Brush_Move (b, delta);
  418. continue;
  419. }
  420. // brush is a complex entity, grab all the other ones now
  421. next = &selected_brushes;
  422. for ( b2 = b ; b2 != &selected_brushes ; b2=next2)
  423. {
  424. next2 = b2->next;
  425. if (b2->owner != b->owner)
  426. {
  427. if (next == &selected_brushes)
  428. next = b2;
  429. continue;
  430. }
  431. // move b2 to the start of selected_brushes,
  432. // so it won't be hit again
  433. Brush_RemoveFromList (b2);
  434. Brush_AddToList (b2, &selected_brushes);
  435. n = Brush_Clone (b2);
  436. Brush_AddToList (n, &active_brushes);
  437. Entity_LinkBrush (e, n);
  438. Brush_Build( n );
  439. Brush_Move (b2, delta, true);
  440. }
  441. }
  442. Sys_UpdateWindows (W_ALL);
  443. #endif
  444. }
  445. /*
  446. ============
  447. Select_SetTexture
  448. Timo : bFitScale to compute scale on the plane and counteract plane / axial plane snapping
  449. Timo : brush primitive texturing
  450. the brushprimit_texdef given must be understood as a qtexture_t width=2 height=2 ( HiRes )
  451. Timo : texture plugin, added an IPluginTexdef* parameter
  452. must be casted to an IPluginTexdef!
  453. if not NULL, get ->Copy() of it into each face or brush ( and remember to hook )
  454. if NULL, means we have no information, ask for a default
  455. ============
  456. */
  457. void WINAPI Select_SetTexture (texdef_t *texdef, brushprimit_texdef_t *brushprimit_texdef, bool bFitScale, void* pPlugTexdef )
  458. {
  459. brush_t *b;
  460. int nCount = g_ptrSelectedFaces.GetSize();
  461. if (nCount > 0)
  462. {
  463. Undo_Start("set face textures");
  464. ASSERT(g_ptrSelectedFaces.GetSize() == g_ptrSelectedFaceBrushes.GetSize());
  465. for (int i = 0; i < nCount; i++)
  466. {
  467. face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(i));
  468. brush_t *selBrush = reinterpret_cast<brush_t*>(g_ptrSelectedFaceBrushes.GetAt(i));
  469. Undo_AddBrush(selBrush);
  470. SetFaceTexdef (selBrush, selFace, texdef, brushprimit_texdef, bFitScale, static_cast<IPluginTexdef *>(pPlugTexdef) );
  471. Brush_Build(selBrush, bFitScale);
  472. Undo_EndBrush(selBrush);
  473. }
  474. Undo_End();
  475. }
  476. else if (selected_brushes.next != &selected_brushes)
  477. {
  478. Undo_Start("set brush textures");
  479. for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  480. if (!b->owner->eclass->fixedsize)
  481. {
  482. Undo_AddBrush(b);
  483. Brush_SetTexture (b, texdef, brushprimit_texdef, bFitScale, static_cast<IPluginTexdef *>(pPlugTexdef) );
  484. Undo_EndBrush(b);
  485. }
  486. Undo_End();
  487. }
  488. Sys_UpdateWindows (W_ALL);
  489. }
  490. /*
  491. ================================================================
  492. TRANSFORMATIONS
  493. ================================================================
  494. */
  495. void Select_GetBounds (vec3_t mins, vec3_t maxs)
  496. {
  497. brush_t *b;
  498. int i;
  499. for (i=0 ; i<3 ; i++)
  500. {
  501. mins[i] = 99999;
  502. maxs[i] = -99999;
  503. }
  504. for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  505. for (i=0 ; i<3 ; i++)
  506. {
  507. if (b->mins[i] < mins[i])
  508. mins[i] = b->mins[i];
  509. if (b->maxs[i] > maxs[i])
  510. maxs[i] = b->maxs[i];
  511. }
  512. }
  513. void Select_GetTrueMid (vec3_t mid)
  514. {
  515. vec3_t mins, maxs;
  516. Select_GetBounds (mins, maxs);
  517. for (int i=0 ; i<3 ; i++)
  518. mid[i] = (mins[i] + ((maxs[i] - mins[i]) / 2));
  519. }
  520. void Select_GetMid (vec3_t mid)
  521. {
  522. vec3_t mins, maxs;
  523. int i;
  524. if (g_PrefsDlg.m_bNoClamp)
  525. {
  526. Select_GetTrueMid(mid);
  527. return;
  528. }
  529. Select_GetBounds (mins, maxs);
  530. for (i=0 ; i<3 ; i++)
  531. mid[i] = g_qeglobals.d_gridsize*floor ( ( (mins[i] + maxs[i])*0.5 )/g_qeglobals.d_gridsize );
  532. }
  533. vec3_t select_origin;
  534. vec3_t select_matrix[3];
  535. qboolean select_fliporder;
  536. void Select_ApplyMatrix (bool bSnap, bool bRotation, int nAxis, float fDeg)
  537. {
  538. brush_t *b;
  539. face_t *f;
  540. int i, j;
  541. vec3_t temp;
  542. for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  543. {
  544. for (f=b->brush_faces ; f ; f=f->next)
  545. {
  546. for (i=0 ; i<3 ; i++)
  547. {
  548. VectorSubtract (f->planepts[i], select_origin, temp);
  549. for (j=0 ; j<3 ; j++)
  550. f->planepts[i][j] = DotProduct(temp, select_matrix[j]) + select_origin[j];
  551. }
  552. if (select_fliporder)
  553. {
  554. VectorCopy (f->planepts[0], temp);
  555. VectorCopy (f->planepts[2], f->planepts[0]);
  556. VectorCopy (temp, f->planepts[2]);
  557. }
  558. }
  559. if(b->owner->eclass->fixedsize)
  560. {
  561. if (bRotation && b->owner->md3Class)
  562. {
  563. b->owner->vRotation[nAxis] += fDeg;
  564. }
  565. }
  566. Brush_Build(b, bSnap);
  567. if (b->patchBrush)
  568. {
  569. //Patch_ApplyMatrix(b->nPatchID, select_origin, select_matrix);
  570. Patch_ApplyMatrix(b->pPatch, select_origin, select_matrix, bSnap);
  571. }
  572. if (b->terrainBrush)
  573. {
  574. Terrain_ApplyMatrix(b->pTerrain, select_origin, select_matrix, bSnap);
  575. }
  576. }
  577. }
  578. void ProjectOnPlane(vec3_t& normal,float dist,vec3_t& ez, vec3_t& p)
  579. {
  580. if (fabs(ez[0]) == 1)
  581. p[0] = (dist - normal[1] * p[1] - normal[2] * p[2]) / normal[0];
  582. else if (fabs(ez[1]) == 1)
  583. p[1] = (dist - normal[0] * p[0] - normal[2] * p[2]) / normal[1];
  584. else
  585. p[2] = (dist - normal[0] * p[0] - normal[1] * p[1]) / normal[2];
  586. }
  587. void Back(vec3_t& dir, vec3_t& p)
  588. {
  589. if (fabs(dir[0]) == 1)
  590. p[0] = 0;
  591. else if (fabs(dir[1]) == 1)
  592. p[1] = 0;
  593. else p[2] = 0;
  594. }
  595. // using scale[0] and scale[1]
  596. void ComputeScale(vec3_t& rex, vec3_t& rey, vec3_t& p, face_t* f)
  597. {
  598. float px = DotProduct(rex, p);
  599. float py = DotProduct(rey, p);
  600. px *= f->texdef.scale[0];
  601. py *= f->texdef.scale[1];
  602. vec3_t aux;
  603. VectorCopy(rex, aux);
  604. VectorScale(aux, px, aux);
  605. VectorCopy(aux, p);
  606. VectorCopy(rey, aux);
  607. VectorScale(aux, py, aux);
  608. VectorAdd(p, aux, p);
  609. }
  610. void ComputeAbsolute(face_t* f, vec3_t& p1, vec3_t& p2, vec3_t& p3)
  611. {
  612. vec3_t ex,ey,ez; // local axis base
  613. #ifdef _DEBUG
  614. if (g_qeglobals.m_bBrushPrimitMode)
  615. Sys_Printf("Warning : illegal call of ComputeAbsolute in brush primitive mode\n");
  616. #endif
  617. // compute first local axis base
  618. TextureAxisFromPlane(&f->plane, ex, ey);
  619. CrossProduct(ex, ey, ez);
  620. vec3_t aux;
  621. VectorCopy(ex, aux);
  622. VectorScale(aux, -f->texdef.shift[0], aux);
  623. VectorCopy(aux, p1);
  624. VectorCopy(ey, aux);
  625. VectorScale(aux, -f->texdef.shift[1], aux);
  626. VectorAdd(p1, aux, p1);
  627. VectorCopy(p1, p2);
  628. VectorAdd(p2, ex, p2);
  629. VectorCopy(p1, p3);
  630. VectorAdd(p3, ey, p3);
  631. VectorCopy(ez, aux);
  632. VectorScale(aux, -f->texdef.rotate, aux);
  633. VectorRotate(p1, aux, p1);
  634. VectorRotate(p2, aux, p2);
  635. VectorRotate(p3, aux, p3);
  636. // computing rotated local axis base
  637. vec3_t rex,rey;
  638. VectorCopy(ex, rex);
  639. VectorRotate(rex, aux, rex);
  640. VectorCopy(ey, rey);
  641. VectorRotate(rey, aux, rey);
  642. ComputeScale(rex,rey,p1,f);
  643. ComputeScale(rex,rey,p2,f);
  644. ComputeScale(rex,rey,p3,f);
  645. // project on normal plane
  646. // along ez
  647. // assumes plane normal is normalized
  648. ProjectOnPlane(f->plane.normal,f->plane.dist,ez,p1);
  649. ProjectOnPlane(f->plane.normal,f->plane.dist,ez,p2);
  650. ProjectOnPlane(f->plane.normal,f->plane.dist,ez,p3);
  651. };
  652. void AbsoluteToLocal(plane_t normal2, face_t* f, vec3_t& p1, vec3_t& p2, vec3_t& p3)
  653. {
  654. vec3_t ex,ey,ez;
  655. #ifdef _DEBUG
  656. if (g_qeglobals.m_bBrushPrimitMode)
  657. Sys_Printf("Warning : illegal call of AbsoluteToLocal in brush primitive mode\n");
  658. #endif
  659. // computing new local axis base
  660. TextureAxisFromPlane(&normal2, ex, ey);
  661. CrossProduct(ex, ey, ez);
  662. // projecting back on (ex,ey)
  663. Back(ez,p1);
  664. Back(ez,p2);
  665. Back(ez,p3);
  666. vec3_t aux;
  667. // rotation
  668. VectorCopy(p2, aux);
  669. VectorSubtract(aux, p1,aux);
  670. float x = DotProduct(aux,ex);
  671. float y = DotProduct(aux,ey);
  672. f->texdef.rotate = 180 * atan2(y,x) / Q_PI;
  673. vec3_t rex,rey;
  674. // computing rotated local axis base
  675. VectorCopy(ez, aux);
  676. VectorScale(aux, f->texdef.rotate, aux);
  677. VectorCopy(ex, rex);
  678. VectorRotate(rex, aux, rex);
  679. VectorCopy(ey, rey);
  680. VectorRotate(rey, aux, rey);
  681. // scale
  682. VectorCopy(p2, aux);
  683. VectorSubtract(aux, p1, aux);
  684. f->texdef.scale[0] = DotProduct(aux, rex);
  685. VectorCopy(p3, aux);
  686. VectorSubtract(aux, p1, aux);
  687. f->texdef.scale[1] = DotProduct(aux, rey);
  688. // shift
  689. // only using p1
  690. x = DotProduct(rex,p1);
  691. y = DotProduct(rey,p1);
  692. x /= f->texdef.scale[0];
  693. y /= f->texdef.scale[1];
  694. VectorCopy(rex, p1);
  695. VectorScale(p1, x, p1);
  696. VectorCopy(rey, aux);
  697. VectorScale(aux, y, aux);
  698. VectorAdd(p1, aux, p1);
  699. VectorCopy(ez, aux);
  700. VectorScale(aux, -f->texdef.rotate, aux);
  701. VectorRotate(p1, aux, p1);
  702. f->texdef.shift[0] = -DotProduct(p1, ex);
  703. f->texdef.shift[1] = -DotProduct(p1, ey);
  704. // stored rot is good considering local axis base
  705. // change it if necessary
  706. f->texdef.rotate = -f->texdef.rotate;
  707. Clamp(f->texdef.shift[0], f->d_texture->width);
  708. Clamp(f->texdef.shift[1], f->d_texture->height);
  709. Clamp(f->texdef.rotate, 360);
  710. }
  711. void RotateFaceTexture(face_t* f, int nAxis, float fDeg)
  712. {
  713. vec3_t p1,p2,p3, rota;
  714. p1[0] = p1[1] = p1[2] = 0;
  715. VectorCopy(p1, p2);
  716. VectorCopy(p1, p3);
  717. VectorCopy(p1, rota);
  718. ComputeAbsolute(f, p1, p2, p3);
  719. rota[nAxis] = fDeg;
  720. VectorRotate(p1, rota, select_origin, p1);
  721. VectorRotate(p2, rota, select_origin, p2);
  722. VectorRotate(p3, rota, select_origin, p3);
  723. plane_t normal2;
  724. vec3_t vNormal;
  725. vNormal[0] = f->plane.normal[0];
  726. vNormal[1] = f->plane.normal[1];
  727. vNormal[2] = f->plane.normal[2];
  728. VectorRotate(vNormal, rota, vNormal);
  729. normal2.normal[0] = vNormal[0];
  730. normal2.normal[1] = vNormal[1];
  731. normal2.normal[2] = vNormal[2];
  732. AbsoluteToLocal(normal2, f, p1, p2 ,p3);
  733. }
  734. void RotateTextures(int nAxis, float fDeg, vec3_t vOrigin)
  735. {
  736. for (brush_t* b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  737. {
  738. for (face_t* f=b->brush_faces ; f ; f=f->next)
  739. {
  740. if (g_qeglobals.m_bBrushPrimitMode)
  741. RotateFaceTexture_BrushPrimit( f, nAxis, fDeg, vOrigin );
  742. else
  743. RotateFaceTexture(f, nAxis, fDeg);
  744. //++timo removed that call .. works fine .. ???????
  745. // Brush_Build(b, false);
  746. }
  747. Brush_Build(b, false);
  748. }
  749. }
  750. void Select_FlipAxis (int axis)
  751. {
  752. int i;
  753. Select_GetMid (select_origin);
  754. for (i=0 ; i<3 ; i++)
  755. {
  756. VectorCopy (vec3_origin, select_matrix[i]);
  757. select_matrix[i][i] = 1;
  758. }
  759. select_matrix[axis][axis] = -1;
  760. select_fliporder = true;
  761. Select_ApplyMatrix (true, false, 0, 0);
  762. Sys_UpdateWindows (W_ALL);
  763. }
  764. void Select_Scale(float x, float y, float z)
  765. {
  766. Select_GetMid (select_origin);
  767. for (brush_t* b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  768. {
  769. for (face_t* f=b->brush_faces ; f ; f=f->next)
  770. {
  771. for (int i=0 ; i<3 ; i++)
  772. {
  773. f->planepts[i][0] -= select_origin[0];
  774. f->planepts[i][1] -= select_origin[1];
  775. f->planepts[i][2] -= select_origin[2];
  776. f->planepts[i][0] *= x;
  777. //f->planepts[i][0] = floor(f->planepts[i][0] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
  778. f->planepts[i][1] *= y;
  779. //f->planepts[i][1] = floor(f->planepts[i][1] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
  780. f->planepts[i][2] *= z;
  781. //f->planepts[i][2] = floor(f->planepts[i][2] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
  782. f->planepts[i][0] += select_origin[0];
  783. f->planepts[i][1] += select_origin[1];
  784. f->planepts[i][2] += select_origin[2];
  785. }
  786. }
  787. Brush_Build(b, false);
  788. if (b->patchBrush)
  789. {
  790. vec3_t v;
  791. v[0] = x;
  792. v[1] = y;
  793. v[2] = z;
  794. //Patch_Scale(b->nPatchID, select_origin, v);
  795. Patch_Scale(b->pPatch, select_origin, v);
  796. }
  797. if (b->terrainBrush)
  798. {
  799. vec3_t v;
  800. v[0] = x;
  801. v[1] = y;
  802. v[2] = z;
  803. Terrain_Scale(b->pTerrain, select_origin, v);
  804. }
  805. }
  806. }
  807. void Select_RotateAxis (int axis, float deg, bool bPaint, bool bMouse)
  808. {
  809. vec3_t temp;
  810. int i, j;
  811. vec_t c, s;
  812. if (deg == 0)
  813. {
  814. //Sys_Printf("0 deg\n");
  815. return;
  816. }
  817. if (bMouse)
  818. {
  819. VectorCopy(g_pParentWnd->ActiveXY()->RotateOrigin(), select_origin);
  820. }
  821. else
  822. {
  823. Select_GetMid (select_origin);
  824. }
  825. select_fliporder = false;
  826. if (deg == 90)
  827. {
  828. for (i=0 ; i<3 ; i++)
  829. {
  830. VectorCopy (vec3_origin, select_matrix[i]);
  831. select_matrix[i][i] = 1;
  832. }
  833. i = (axis+1)%3;
  834. j = (axis+2)%3;
  835. VectorCopy (select_matrix[i], temp);
  836. VectorCopy (select_matrix[j], select_matrix[i]);
  837. VectorSubtract (vec3_origin, temp, select_matrix[j]);
  838. }
  839. else
  840. {
  841. deg = -deg;
  842. if (deg == -180.0)
  843. {
  844. c = -1;
  845. s = 0;
  846. }
  847. else if (deg == -270.0)
  848. {
  849. c = 0;
  850. s = -1;
  851. }
  852. else
  853. {
  854. c = cos(deg * Q_PI / 180.0);
  855. s = sin(deg * Q_PI / 180.0);
  856. }
  857. for (i=0 ; i<3 ; i++)
  858. {
  859. VectorCopy (vec3_origin, select_matrix[i]);
  860. select_matrix[i][i] = 1;
  861. }
  862. switch (axis)
  863. {
  864. case 0:
  865. select_matrix[1][1] = c;
  866. select_matrix[1][2] = -s;
  867. select_matrix[2][1] = s;
  868. select_matrix[2][2] = c;
  869. break;
  870. case 1:
  871. select_matrix[0][0] = c;
  872. select_matrix[0][2] = s;
  873. select_matrix[2][0] = -s;
  874. select_matrix[2][2] = c;
  875. break;
  876. case 2:
  877. select_matrix[0][0] = c;
  878. select_matrix[0][1] = -s;
  879. select_matrix[1][0] = s;
  880. select_matrix[1][1] = c;
  881. break;
  882. }
  883. }
  884. if (g_PrefsDlg.m_bRotateLock)
  885. RotateTextures(axis, deg, select_origin);
  886. Select_ApplyMatrix(!bMouse, true, axis, deg);
  887. if (bPaint)
  888. Sys_UpdateWindows (W_ALL);
  889. }
  890. /*
  891. ================================================================
  892. GROUP SELECTIONS
  893. ================================================================
  894. */
  895. void Select_CompleteTall (void)
  896. {
  897. brush_t *b, *next;
  898. //int i;
  899. vec3_t mins, maxs;
  900. if (!QE_SingleBrush ())
  901. return;
  902. clearSelection();
  903. VectorCopy (selected_brushes.next->mins, mins);
  904. VectorCopy (selected_brushes.next->maxs, maxs);
  905. Select_Delete ();
  906. int nDim1 = (g_pParentWnd->ActiveXY()->GetViewType() == YZ) ? 1 : 0;
  907. int nDim2 = (g_pParentWnd->ActiveXY()->GetViewType() == XY) ? 1 : 2;
  908. for (b=active_brushes.next ; b != &active_brushes ; b=next)
  909. {
  910. next = b->next;
  911. if ( (b->maxs[nDim1] > maxs[nDim1] || b->mins[nDim1] < mins[nDim1])
  912. || (b->maxs[nDim2] > maxs[nDim2] || b->mins[nDim2] < mins[nDim2]) )
  913. continue;
  914. if (FilterBrush (b))
  915. continue;
  916. Brush_RemoveFromList (b);
  917. Brush_AddToList (b, &selected_brushes);
  918. #if 0
  919. // old stuff
  920. for (i=0 ; i<2 ; i++)
  921. if (b->maxs[i] > maxs[i] || b->mins[i] < mins[i])
  922. break;
  923. if (i == 2)
  924. {
  925. Brush_RemoveFromList (b);
  926. Brush_AddToList (b, &selected_brushes);
  927. }
  928. #endif
  929. }
  930. Sys_UpdateWindows (W_ALL);
  931. }
  932. void Select_PartialTall (void)
  933. {
  934. brush_t *b, *next;
  935. //int i;
  936. vec3_t mins, maxs;
  937. if (!QE_SingleBrush ())
  938. return;
  939. clearSelection();
  940. VectorCopy (selected_brushes.next->mins, mins);
  941. VectorCopy (selected_brushes.next->maxs, maxs);
  942. Select_Delete ();
  943. int nDim1 = (g_pParentWnd->ActiveXY()->GetViewType() == YZ) ? 1 : 0;
  944. int nDim2 = (g_pParentWnd->ActiveXY()->GetViewType() == XY) ? 1 : 2;
  945. for (b=active_brushes.next ; b != &active_brushes ; b=next)
  946. {
  947. next = b->next;
  948. if ( (b->mins[nDim1] > maxs[nDim1] || b->maxs[nDim1] < mins[nDim1])
  949. || (b->mins[nDim2] > maxs[nDim2] || b->maxs[nDim2] < mins[nDim2]) )
  950. continue;
  951. if (FilterBrush (b))
  952. continue;
  953. Brush_RemoveFromList (b);
  954. Brush_AddToList (b, &selected_brushes);
  955. #if 0
  956. // old stuff
  957. for (i=0 ; i<2 ; i++)
  958. if (b->mins[i] > maxs[i] || b->maxs[i] < mins[i])
  959. break;
  960. if (i == 2)
  961. {
  962. Brush_RemoveFromList (b);
  963. Brush_AddToList (b, &selected_brushes);
  964. }
  965. #endif
  966. }
  967. Sys_UpdateWindows (W_ALL);
  968. }
  969. void Select_Touching (void)
  970. {
  971. brush_t *b, *next;
  972. int i;
  973. vec3_t mins, maxs;
  974. if (!QE_SingleBrush ())
  975. return;
  976. clearSelection();
  977. VectorCopy (selected_brushes.next->mins, mins);
  978. VectorCopy (selected_brushes.next->maxs, maxs);
  979. for (b=active_brushes.next ; b != &active_brushes ; b=next)
  980. {
  981. next = b->next;
  982. if (FilterBrush (b))
  983. continue;
  984. for (i=0 ; i<3 ; i++)
  985. if (b->mins[i] > maxs[i]+1 || b->maxs[i] < mins[i]-1)
  986. break;
  987. if (i == 3)
  988. {
  989. Brush_RemoveFromList (b);
  990. Brush_AddToList (b, &selected_brushes);
  991. }
  992. }
  993. Sys_UpdateWindows (W_ALL);
  994. }
  995. void Select_Inside (void)
  996. {
  997. brush_t *b, *next;
  998. int i;
  999. vec3_t mins, maxs;
  1000. if (!QE_SingleBrush ())
  1001. return;
  1002. clearSelection();
  1003. VectorCopy (selected_brushes.next->mins, mins);
  1004. VectorCopy (selected_brushes.next->maxs, maxs);
  1005. Select_Delete ();
  1006. for (b=active_brushes.next ; b != &active_brushes ; b=next)
  1007. {
  1008. next = b->next;
  1009. if (FilterBrush (b))
  1010. continue;
  1011. for (i=0 ; i<3 ; i++)
  1012. if (b->maxs[i] > maxs[i] || b->mins[i] < mins[i])
  1013. break;
  1014. if (i == 3)
  1015. {
  1016. Brush_RemoveFromList (b);
  1017. Brush_AddToList (b, &selected_brushes);
  1018. }
  1019. }
  1020. Sys_UpdateWindows (W_ALL);
  1021. }
  1022. /*
  1023. =============
  1024. Select_Ungroup
  1025. Turn the currently selected entity back into normal brushes
  1026. =============
  1027. */
  1028. void Select_Ungroup(void)
  1029. {
  1030. int numselectedgroups;
  1031. entity_t *e;
  1032. brush_t *b, *sb;
  1033. numselectedgroups = 0;
  1034. for (sb = selected_brushes.next; sb != &selected_brushes; sb = sb->next)
  1035. {
  1036. e = sb->owner;
  1037. if (!e || e == world_entity || e->eclass->fixedsize)
  1038. {
  1039. continue;
  1040. }
  1041. for (b = e->brushes.onext; b != &e->brushes; b = e->brushes.onext)
  1042. {
  1043. //Brush_RemoveFromList (b);
  1044. //Brush_AddToList (b, &active_brushes);
  1045. Entity_UnlinkBrush (b);
  1046. Entity_LinkBrush (world_entity, b);
  1047. Brush_Build( b );
  1048. b->owner = world_entity;
  1049. }
  1050. Entity_Free (e);
  1051. numselectedgroups++;
  1052. }
  1053. if (numselectedgroups <= 0)
  1054. {
  1055. Sys_Printf("No grouped entities selected.\n");
  1056. return;
  1057. }
  1058. Sys_Printf("Ungrouped %d entit%s.\n", numselectedgroups, (numselectedgroups == 1)?"y":"ies");
  1059. Sys_UpdateWindows (W_ALL);
  1060. }
  1061. /*
  1062. ====================
  1063. Select_MakeStructural
  1064. ====================
  1065. */
  1066. void Select_MakeStructural (void)
  1067. {
  1068. brush_t *b;
  1069. face_t *f;
  1070. for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  1071. for (f=b->brush_faces ; f ; f=f->next)
  1072. f->texdef.contents &= ~CONTENTS_DETAIL;
  1073. Select_Deselect ();
  1074. Sys_UpdateWindows (W_ALL);
  1075. }
  1076. void Select_MakeDetail (void)
  1077. {
  1078. brush_t *b;
  1079. face_t *f;
  1080. for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  1081. for (f=b->brush_faces ; f ; f=f->next)
  1082. f->texdef.contents |= CONTENTS_DETAIL;
  1083. Select_Deselect ();
  1084. Sys_UpdateWindows (W_ALL);
  1085. }
  1086. void Select_ShiftTexture(int x, int y)
  1087. {
  1088. brush_t *b;
  1089. face_t *f;
  1090. int nFaceCount = g_ptrSelectedFaces.GetSize();
  1091. if(selected_brushes.next == &selected_brushes && nFaceCount == 0)
  1092. return;
  1093. for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  1094. {
  1095. for (f=b->brush_faces ; f ; f=f->next)
  1096. {
  1097. if (g_qeglobals.m_bBrushPrimitMode)
  1098. {
  1099. // use face normal to compute a true translation
  1100. Select_ShiftTexture_BrushPrimit( f, x, y );
  1101. }
  1102. else
  1103. {
  1104. f->texdef.shift[0] += x;
  1105. f->texdef.shift[1] += y;
  1106. }
  1107. }
  1108. Brush_Build(b);
  1109. if (b->patchBrush)
  1110. {
  1111. //Patch_ShiftTexture(b->nPatchID, x, y);
  1112. Patch_ShiftTexture(b->pPatch, x, y);
  1113. }
  1114. }
  1115. if (nFaceCount > 0)
  1116. {
  1117. for (int i = 0; i < nFaceCount; i++)
  1118. {
  1119. face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(i));
  1120. brush_t *selBrush = reinterpret_cast<brush_t*>(g_ptrSelectedFaceBrushes.GetAt(i));
  1121. if (g_qeglobals.m_bBrushPrimitMode)
  1122. {
  1123. // use face normal to compute a true translation
  1124. // Select_ShiftTexture_BrushPrimit( selected_face, x, y );
  1125. // use camera view to compute texture shift
  1126. g_pParentWnd->GetCamera()->ShiftTexture_BrushPrimit( selFace, x, y );
  1127. }
  1128. else
  1129. {
  1130. selFace->texdef.shift[0] += x;
  1131. selFace->texdef.shift[1] += y;
  1132. }
  1133. Brush_Build(selBrush);
  1134. }
  1135. }
  1136. Sys_UpdateWindows (W_CAMERA);
  1137. }
  1138. void Select_ScaleTexture(int x, int y)
  1139. {
  1140. brush_t *b;
  1141. face_t *f;
  1142. int nFaceCount = g_ptrSelectedFaces.GetSize();
  1143. if(selected_brushes.next == &selected_brushes && nFaceCount == 0)
  1144. {
  1145. return;
  1146. }
  1147. for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  1148. {
  1149. for (f=b->brush_faces ; f ; f=f->next)
  1150. {
  1151. if (g_qeglobals.m_bBrushPrimitMode)
  1152. {
  1153. // apply same scale as the spinner button of the surface inspector
  1154. float shift[2];
  1155. float rotate;
  1156. float scale[2];
  1157. brushprimit_texdef_t bp;
  1158. // compute normalized texture matrix
  1159. ConvertTexMatWithQTexture( &f->brushprimit_texdef, f->d_texture, &bp, NULL );
  1160. // compute fake shift scale rot
  1161. TexMatToFakeTexCoords( bp.coords, shift, &rotate, scale );
  1162. // update
  1163. scale[0]+=static_cast<float>(x)*0.1;
  1164. scale[1]+=static_cast<float>(y)*0.1;
  1165. // compute new normalized texture matrix
  1166. FakeTexCoordsToTexMat( shift, rotate, scale, bp.coords );
  1167. // apply to face texture matrix
  1168. ConvertTexMatWithQTexture( &bp, NULL, &f->brushprimit_texdef, f->d_texture );
  1169. }
  1170. else
  1171. {
  1172. f->texdef.scale[0] += x;
  1173. f->texdef.scale[1] += y;
  1174. }
  1175. }
  1176. Brush_Build(b);
  1177. if (b->patchBrush)
  1178. {
  1179. Patch_ScaleTexture(b->pPatch, x, y);
  1180. }
  1181. }
  1182. if (nFaceCount > 0)
  1183. {
  1184. for (int i = 0; i < nFaceCount; i++)
  1185. {
  1186. face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(i));
  1187. brush_t *selBrush = reinterpret_cast<brush_t*>(g_ptrSelectedFaceBrushes.GetAt(i));
  1188. if (g_qeglobals.m_bBrushPrimitMode)
  1189. {
  1190. float shift[2];
  1191. float rotate;
  1192. float scale[2];
  1193. brushprimit_texdef_t bp;
  1194. ConvertTexMatWithQTexture( &selFace->brushprimit_texdef, selFace->d_texture, &bp, NULL );
  1195. TexMatToFakeTexCoords( bp.coords, shift, &rotate, scale );
  1196. scale[0]+=static_cast<float>(x)*0.1;
  1197. scale[1]+=static_cast<float>(y)*0.1;
  1198. FakeTexCoordsToTexMat( shift, rotate, scale, bp.coords );
  1199. ConvertTexMatWithQTexture( &bp, NULL, &selFace->brushprimit_texdef, selFace->d_texture );
  1200. }
  1201. else
  1202. {
  1203. selFace->texdef.scale[0] += x;
  1204. selFace->texdef.scale[1] += y;
  1205. }
  1206. Brush_Build(selBrush);
  1207. }
  1208. }
  1209. Sys_UpdateWindows (W_CAMERA);
  1210. }
  1211. void Select_RotateTexture(int amt)
  1212. {
  1213. brush_t *b;
  1214. face_t *f;
  1215. int nFaceCount = g_ptrSelectedFaces.GetSize();
  1216. if(selected_brushes.next == &selected_brushes && nFaceCount == 0)
  1217. {
  1218. return;
  1219. }
  1220. for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  1221. {
  1222. for (f=b->brush_faces ; f ; f=f->next)
  1223. {
  1224. if (g_qeglobals.m_bBrushPrimitMode)
  1225. {
  1226. // apply same scale as the spinner button of the surface inspector
  1227. float shift[2];
  1228. float rotate;
  1229. float scale[2];
  1230. brushprimit_texdef_t bp;
  1231. // compute normalized texture matrix
  1232. ConvertTexMatWithQTexture( &f->brushprimit_texdef, f->d_texture, &bp, NULL );
  1233. // compute fake shift scale rot
  1234. TexMatToFakeTexCoords( bp.coords, shift, &rotate, scale );
  1235. // update
  1236. rotate += amt;
  1237. // compute new normalized texture matrix
  1238. FakeTexCoordsToTexMat( shift, rotate, scale, bp.coords );
  1239. // apply to face texture matrix
  1240. ConvertTexMatWithQTexture( &bp, NULL, &f->brushprimit_texdef, f->d_texture );
  1241. }
  1242. else
  1243. {
  1244. f->texdef.rotate += amt;
  1245. f->texdef.rotate = static_cast<int>(f->texdef.rotate) % 360;
  1246. }
  1247. }
  1248. Brush_Build(b);
  1249. if (b->patchBrush)
  1250. {
  1251. //Patch_RotateTexture(b->nPatchID, amt);
  1252. Patch_RotateTexture(b->pPatch, amt);
  1253. }
  1254. }
  1255. if (nFaceCount > 0)
  1256. {
  1257. for (int i = 0; i < nFaceCount; i++)
  1258. {
  1259. face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(i));
  1260. brush_t *selBrush = reinterpret_cast<brush_t*>(g_ptrSelectedFaceBrushes.GetAt(i));
  1261. if (g_qeglobals.m_bBrushPrimitMode)
  1262. {
  1263. float shift[2];
  1264. float rotate;
  1265. float scale[2];
  1266. brushprimit_texdef_t bp;
  1267. ConvertTexMatWithQTexture( &selFace->brushprimit_texdef, selFace->d_texture, &bp, NULL );
  1268. TexMatToFakeTexCoords( bp.coords, shift, &rotate, scale );
  1269. rotate += amt;
  1270. FakeTexCoordsToTexMat( shift, rotate, scale, bp.coords );
  1271. ConvertTexMatWithQTexture( &bp, NULL, &selFace->brushprimit_texdef, selFace->d_texture );
  1272. }
  1273. else
  1274. {
  1275. selFace->texdef.rotate += amt;
  1276. selFace->texdef.rotate = static_cast<int>(selFace->texdef.rotate) % 360;
  1277. }
  1278. Brush_Build(selBrush);
  1279. }
  1280. }
  1281. Sys_UpdateWindows (W_CAMERA);
  1282. }
  1283. void FindReplaceTextures(const char* pFind, const char* pReplace, bool bSelected, bool bForce)
  1284. {
  1285. brush_t* pList = (bSelected) ? &selected_brushes : &active_brushes;
  1286. if (!bSelected)
  1287. {
  1288. Select_Deselect();
  1289. }
  1290. for (brush_t* pBrush = pList->next ; pBrush != pList; pBrush = pBrush->next)
  1291. {
  1292. if (pBrush->patchBrush)
  1293. {
  1294. Patch_FindReplaceTexture(pBrush, pFind, pReplace, bForce);
  1295. }
  1296. if (pBrush->terrainBrush)
  1297. {
  1298. Terrain_FindReplaceTexture(pBrush->pTerrain, pFind, pReplace, bForce);
  1299. }
  1300. for (face_t* pFace = pBrush->brush_faces; pFace; pFace = pFace->next)
  1301. {
  1302. if(bForce || strcmpi(pFace->texdef.name, pFind) == 0)
  1303. {
  1304. pFace->d_texture = Texture_ForName(pReplace);
  1305. //strcpy(pFace->texdef.name, pReplace);
  1306. pFace->texdef.SetName(pReplace);
  1307. }
  1308. }
  1309. Brush_Build(pBrush);
  1310. }
  1311. Sys_UpdateWindows (W_CAMERA);
  1312. }
  1313. void Select_AllOfType()
  1314. {
  1315. brush_t *b, *next;
  1316. entity_t *e;
  1317. if ( (selected_brushes.next == &selected_brushes)
  1318. || (selected_brushes.next->next != &selected_brushes) )
  1319. {
  1320. CString strName;
  1321. if (g_ptrSelectedFaces.GetSize() == 0)
  1322. {
  1323. strName = g_qeglobals.d_texturewin.texdef.name;
  1324. }
  1325. else
  1326. {
  1327. face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(0));
  1328. strName = selFace->texdef.name;
  1329. }
  1330. Select_Deselect();
  1331. for (b=active_brushes.next ; b != &active_brushes ; b=next)
  1332. {
  1333. next = b->next;
  1334. if (FilterBrush (b))
  1335. continue;
  1336. if (b->patchBrush)
  1337. {
  1338. if (strcmpi(strName, b->pPatch->d_texture->name) == 0)
  1339. {
  1340. Brush_RemoveFromList (b);
  1341. Brush_AddToList (b, &selected_brushes);
  1342. }
  1343. }
  1344. else
  1345. {
  1346. for (face_t* pFace = b->brush_faces; pFace; pFace = pFace->next)
  1347. {
  1348. if (strcmpi(strName, pFace->texdef.name) == 0)
  1349. {
  1350. Brush_RemoveFromList (b);
  1351. Brush_AddToList (b, &selected_brushes);
  1352. }
  1353. }
  1354. }
  1355. }
  1356. Sys_UpdateWindows(W_ALL);
  1357. return;
  1358. }
  1359. b = selected_brushes.next;
  1360. e = b->owner;
  1361. if (e != NULL)
  1362. {
  1363. if (e != world_entity)
  1364. {
  1365. CString strName = e->eclass->name;
  1366. CString strKey, strVal;
  1367. bool bCriteria = GetSelectAllCriteria(strKey, strVal);
  1368. Sys_Printf("Selecting all %s(s)\n", strName);
  1369. Select_Deselect();
  1370. for (b=active_brushes.next ; b != &active_brushes ; b=next)
  1371. {
  1372. next = b->next;
  1373. if (FilterBrush (b))
  1374. continue;
  1375. e = b->owner;
  1376. if (e != NULL)
  1377. {
  1378. if (strcmpi(e->eclass->name, strName) == 0)
  1379. {
  1380. bool doIt = true;
  1381. if (bCriteria) {
  1382. CString str = ValueForKey (e, strKey);
  1383. if (str.CompareNoCase(strVal) != 0) {
  1384. doIt = false;
  1385. }
  1386. }
  1387. if (doIt) {
  1388. Brush_RemoveFromList (b);
  1389. Brush_AddToList (b, &selected_brushes);
  1390. }
  1391. }
  1392. }
  1393. }
  1394. }
  1395. }
  1396. Sys_UpdateWindows (W_ALL);
  1397. }
  1398. void Select_Reselect()
  1399. {
  1400. CPtrArray holdArray;
  1401. for (brush_t* b=selected_brushes.next ; b && b != &selected_brushes ; b=b->next)
  1402. {
  1403. holdArray.Add(reinterpret_cast<void*>(b));
  1404. }
  1405. int n = holdArray.GetSize();
  1406. while (n-- > 0)
  1407. {
  1408. b = reinterpret_cast<brush_t*>(holdArray.GetAt(n));
  1409. Select_Brush(b);
  1410. }
  1411. Sys_UpdateWindows (W_ALL);
  1412. }
  1413. void Select_FitTexture(int nHeight, int nWidth)
  1414. {
  1415. brush_t *b;
  1416. int nFaceCount = g_ptrSelectedFaces.GetSize();
  1417. if(selected_brushes.next == &selected_brushes && nFaceCount == 0)
  1418. return;
  1419. for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
  1420. {
  1421. Brush_FitTexture(b, nHeight, nWidth);
  1422. Brush_Build(b);
  1423. }
  1424. if (nFaceCount > 0)
  1425. {
  1426. for (int i = 0; i < nFaceCount; i++)
  1427. {
  1428. face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(i));
  1429. brush_t *selBrush = reinterpret_cast<brush_t*>(g_ptrSelectedFaceBrushes.GetAt(i));
  1430. Face_FitTexture(selFace, nHeight, nWidth);
  1431. Brush_Build(selBrush);
  1432. }
  1433. }
  1434. Sys_UpdateWindows (W_CAMERA);
  1435. }
  1436. void Select_AxialTexture()
  1437. {
  1438. }
  1439. void Select_Hide()
  1440. {
  1441. for (brush_t* b=selected_brushes.next ; b && b != &selected_brushes ; b=b->next)
  1442. {
  1443. b->hiddenBrush = true;
  1444. }
  1445. Sys_UpdateWindows (W_ALL);
  1446. }
  1447. void Select_ShowAllHidden()
  1448. {
  1449. brush_t* b;
  1450. for (b=selected_brushes.next ; b && b != &selected_brushes ; b=b->next)
  1451. {
  1452. b->hiddenBrush = false;
  1453. }
  1454. for (b=active_brushes.next ; b && b != &active_brushes ; b=b->next)
  1455. {
  1456. b->hiddenBrush = false;
  1457. }
  1458. Sys_UpdateWindows (W_ALL);
  1459. }
  1460. /*
  1461. ============
  1462. Select_Invert
  1463. ============
  1464. */
  1465. void Select_Invert(void)
  1466. {
  1467. brush_t *next, *prev;
  1468. Sys_Printf("inverting selection...\n");
  1469. next = active_brushes.next;
  1470. prev = active_brushes.prev;
  1471. if (selected_brushes.next != &selected_brushes)
  1472. {
  1473. active_brushes.next = selected_brushes.next;
  1474. active_brushes.prev = selected_brushes.prev;
  1475. active_brushes.next->prev = &active_brushes;
  1476. active_brushes.prev->next = &active_brushes;
  1477. }
  1478. else
  1479. {
  1480. active_brushes.next = &active_brushes;
  1481. active_brushes.prev = &active_brushes;
  1482. }
  1483. if (next != &active_brushes)
  1484. {
  1485. selected_brushes.next = next;
  1486. selected_brushes.prev = prev;
  1487. selected_brushes.next->prev = &selected_brushes;
  1488. selected_brushes.prev->next = &selected_brushes;
  1489. }
  1490. else
  1491. {
  1492. selected_brushes.next = &selected_brushes;
  1493. selected_brushes.prev = &selected_brushes;
  1494. }
  1495. Sys_UpdateWindows(W_ALL);
  1496. Sys_Printf("done.\n");
  1497. }
  1498. /*
  1499. ===========
  1500. Select_Name
  1501. ===========
  1502. */
  1503. void Select_Name(const char *pName)
  1504. {
  1505. if (g_qeglobals.m_bBrushPrimitMode)
  1506. {
  1507. for (brush_t* b=selected_brushes.next ; b && b != &selected_brushes ; b=b->next)
  1508. {
  1509. Brush_SetEpair(b, "Name", pName);
  1510. }
  1511. }
  1512. }
  1513. /*
  1514. =================
  1515. Select_AddToGroup
  1516. add selected brushes to a group, update the tree
  1517. =================
  1518. */
  1519. void Select_AddToGroup(const char *pName)
  1520. {
  1521. if (g_qeglobals.m_bBrushPrimitMode)
  1522. {
  1523. for (brush_t* b=selected_brushes.next ; b && b != &selected_brushes ; b=b->next)
  1524. {
  1525. Brush_SetEpair(b, "group", pName);
  1526. Group_AddToProperGroup(b);
  1527. }
  1528. }
  1529. }