SELECT.CPP 63 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210
  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. #include "../../renderer/model_local.h" // for idRenderModelPrt
  24. // externs
  25. CPtrArray g_SelectedFaces;
  26. CPtrArray g_SelectedFaceBrushes;
  27. CPtrArray &g_ptrSelectedFaces = g_SelectedFaces;
  28. CPtrArray &g_ptrSelectedFaceBrushes = g_SelectedFaceBrushes;
  29. extern void Brush_Resize(brush_t *b, idVec3 vMin, idVec3 vMax);
  30. /*
  31. =======================================================================================================================
  32. =======================================================================================================================
  33. */
  34. qertrace_t Test_Ray(const idVec3 &origin, const idVec3 &dir, int flags) {
  35. brush_t *brush;
  36. face_t *face;
  37. float dist;
  38. qertrace_t t;
  39. memset(&t, 0, sizeof(t));
  40. t.dist = HUGE_DISTANCE*2;
  41. // check for points first
  42. CDragPoint *drag = PointRay(origin, dir, &dist);
  43. if (drag) {
  44. t.dist = dist;
  45. t.brush = NULL;
  46. t.face = NULL;
  47. t.point = drag;
  48. t.selected = false;
  49. return t;
  50. }
  51. if (flags & SF_CYCLE) {
  52. CPtrArray array;
  53. brush_t *pToSelect = (selected_brushes.next != &selected_brushes) ? selected_brushes.next : NULL;
  54. Select_Deselect();
  55. // go through active brushes and accumulate all "hit" brushes
  56. for (brush = active_brushes.next; brush != &active_brushes; brush = brush->next) {
  57. // if ( (flags & SF_ENTITIES_FIRST) && brush->owner == world_entity) continue;
  58. if (FilterBrush(brush)) {
  59. continue;
  60. }
  61. if (g_PrefsDlg.m_selectOnlyBrushes) {
  62. if (brush->pPatch || brush->modelHandle > 0) {
  63. continue;
  64. }
  65. }
  66. if (g_PrefsDlg.m_selectNoModels) {
  67. if (brush->modelHandle > 0) {
  68. continue;
  69. }
  70. }
  71. // if (!g_bShowPatchBounds && brush->pPatch) continue;
  72. face = Brush_Ray(origin, dir, brush, &dist, true);
  73. if (face) {
  74. array.Add(brush);
  75. }
  76. }
  77. int nSize = array.GetSize();
  78. if (nSize > 0) {
  79. bool bFound = false;
  80. for (int i = 0; i < nSize; i++) {
  81. brush_t *b = reinterpret_cast < brush_t * > (array.GetAt(i));
  82. // did we hit the last one selected yet ?
  83. if (b == pToSelect) {
  84. // yes we want to select the next one in the list
  85. int n = (i > 0) ? i - 1 : nSize - 1;
  86. pToSelect = reinterpret_cast < brush_t * > (array.GetAt(n));
  87. bFound = true;
  88. break;
  89. }
  90. }
  91. if (!bFound) {
  92. pToSelect = reinterpret_cast < brush_t * > (array.GetAt(0));
  93. }
  94. }
  95. if (pToSelect) {
  96. face = Brush_Ray(origin, dir, pToSelect, &dist, true);
  97. t.dist = dist;
  98. t.brush = pToSelect;
  99. t.face = face;
  100. t.selected = false;
  101. return t;
  102. }
  103. }
  104. if (!(flags & SF_SELECTED_ONLY)) {
  105. for (brush = active_brushes.next; brush != &active_brushes; brush = brush->next) {
  106. if ((flags & SF_ENTITIES_FIRST) && brush->owner == world_entity) {
  107. continue;
  108. }
  109. if (FilterBrush(brush)) {
  110. continue;
  111. }
  112. if (g_PrefsDlg.m_selectOnlyBrushes) {
  113. if (brush->pPatch || brush->modelHandle > 0) {
  114. continue;
  115. }
  116. }
  117. if (g_PrefsDlg.m_selectNoModels) {
  118. if (brush->modelHandle > 0) {
  119. continue;
  120. }
  121. }
  122. face = Brush_Ray(origin, dir, brush, &dist, true);
  123. if (dist > 0 && dist < t.dist) {
  124. t.dist = dist;
  125. t.brush = brush;
  126. t.face = face;
  127. t.selected = false;
  128. }
  129. }
  130. }
  131. for (brush = selected_brushes.next; brush != &selected_brushes; brush = brush->next) {
  132. if ((flags & SF_ENTITIES_FIRST) && brush->owner == world_entity) {
  133. continue;
  134. }
  135. if (FilterBrush(brush)) {
  136. continue;
  137. }
  138. if (g_PrefsDlg.m_selectOnlyBrushes) {
  139. if (brush->pPatch || brush->modelHandle > 0) {
  140. continue;
  141. }
  142. }
  143. if (g_PrefsDlg.m_selectNoModels) {
  144. if (brush->modelHandle > 0) {
  145. continue;
  146. }
  147. }
  148. face = Brush_Ray(origin, dir, brush, &dist, true);
  149. if (dist > 0 && dist < t.dist) {
  150. t.dist = dist;
  151. t.brush = brush;
  152. t.face = face;
  153. t.selected = true;
  154. }
  155. }
  156. // if entites first, but didn't find any, check regular
  157. if ((flags & SF_ENTITIES_FIRST) && t.brush == NULL) {
  158. return Test_Ray(origin, dir, flags - SF_ENTITIES_FIRST);
  159. }
  160. return t;
  161. }
  162. extern void AddSelectablePoint(brush_t *b, idVec3 v, int type, bool priority);
  163. extern void ClearSelectablePoints(brush_t *b);
  164. extern idVec3 Brush_TransformedPoint(brush_t *b, const idVec3 &in);
  165. /*
  166. =======================================================================================================================
  167. Select_Brush
  168. =======================================================================================================================
  169. */
  170. void Select_Brush(brush_t *brush, bool bComplete, bool bStatus) {
  171. brush_t *b;
  172. entity_t *e;
  173. g_ptrSelectedFaces.RemoveAll();
  174. g_ptrSelectedFaceBrushes.RemoveAll();
  175. // selected_face = NULL;
  176. if (g_qeglobals.d_select_count < MAX_MAP_ENTITIES) {
  177. g_qeglobals.d_select_order[g_qeglobals.d_select_count] = brush;
  178. }
  179. g_qeglobals.d_select_count++;
  180. e = brush->owner;
  181. if (e) {
  182. if ( e == world_entity && radiant_entityMode.GetBool() ) {
  183. return;
  184. }
  185. // select complete entity on first click
  186. if (e != world_entity && bComplete == true) {
  187. for (b = selected_brushes.next; b != &selected_brushes; b = b->next) {
  188. if (b->owner == e) {
  189. goto singleselect;
  190. }
  191. }
  192. for (b = e->brushes.onext; b != &e->brushes; b = b->onext) {
  193. Brush_RemoveFromList(b);
  194. Brush_AddToList(b, &selected_brushes);
  195. }
  196. }
  197. else
  198. {
  199. singleselect:
  200. Brush_RemoveFromList(brush);
  201. Brush_AddToList(brush, &selected_brushes);
  202. UpdateSurfaceDialog();
  203. UpdatePatchInspector();
  204. UpdateLightInspector();
  205. }
  206. if (e->eclass) {
  207. g_Inspectors->UpdateEntitySel(brush->owner->eclass);
  208. if ( radiant_entityMode.GetBool() && e->eclass->nShowFlags & (ECLASS_LIGHT | ECLASS_SPEAKER) ) {
  209. const char *p = ValueForKey(e, "s_shader");
  210. if (p && *p) {
  211. g_Inspectors->mediaDlg.SelectCurrentItem(true, p, CDialogTextures::SOUNDS);
  212. }
  213. }
  214. if ( ( e->eclass->nShowFlags & ECLASS_LIGHT ) && !brush->entityModel ) {
  215. if (brush->pointLight) {
  216. // add center drag point if not at the origin
  217. if (brush->lightCenter[0] || brush->lightCenter[1] || brush->lightCenter[2]) {
  218. AddSelectablePoint(brush, Brush_TransformedPoint(brush, brush->lightCenter), LIGHT_CENTER, false);
  219. }
  220. }
  221. else {
  222. AddSelectablePoint(brush, Brush_TransformedPoint(brush, brush->lightTarget), LIGHT_TARGET, true);
  223. AddSelectablePoint(brush, Brush_TransformedPoint(brush, brush->lightUp), LIGHT_UP, false);
  224. AddSelectablePoint(brush, Brush_TransformedPoint(brush, brush->lightRight), LIGHT_RIGHT, false);
  225. if (brush->startEnd) {
  226. AddSelectablePoint(brush, Brush_TransformedPoint(brush, brush->lightStart), LIGHT_START, false);
  227. AddSelectablePoint(brush, Brush_TransformedPoint(brush, brush->lightEnd), LIGHT_END, false);
  228. }
  229. }
  230. UpdateLightInspector();
  231. }
  232. if (e->eclass->nShowFlags & ECLASS_CAMERAVIEW) {
  233. g_pParentWnd->GetCamera()->UpdateCameraView();
  234. }
  235. }
  236. }
  237. if (bStatus) {
  238. idVec3 vMin, vMax, vSize;
  239. Select_GetBounds(vMin, vMax);
  240. VectorSubtract(vMax, vMin, vSize);
  241. CString strStatus;
  242. strStatus.Format("Selection X:: %.1f Y:: %.1f Z:: %.1f", vSize[0], vSize[1], vSize[2]);
  243. g_pParentWnd->SetStatusText(2, strStatus);
  244. }
  245. }
  246. /*
  247. =======================================================================================================================
  248. Select_Ray If the origin is inside a brush, that brush will be ignored.
  249. =======================================================================================================================
  250. */
  251. void Select_Ray(idVec3 origin, idVec3 dir, int flags) {
  252. qertrace_t t;
  253. t = Test_Ray(origin, dir, flags);
  254. if (!t.brush) {
  255. return;
  256. }
  257. if (flags == SF_SINGLEFACE) {
  258. int nCount = g_SelectedFaces.GetSize();
  259. bool bOk = true;
  260. for (int i = 0; i < nCount; i++) {
  261. if (t.face == reinterpret_cast < face_t * > (g_SelectedFaces.GetAt(i))) {
  262. bOk = false;
  263. // need to move remove i'th entry
  264. g_SelectedFaces.RemoveAt(i, 1);
  265. g_SelectedFaceBrushes.RemoveAt(i, 1);
  266. nCount--;
  267. }
  268. }
  269. if (bOk) {
  270. if ( t.selected ) {
  271. face_t *face;
  272. // DeSelect brush
  273. Brush_RemoveFromList(t.brush);
  274. Brush_AddToList(t.brush, &active_brushes);
  275. // Select all brush faces
  276. for ( face = t.brush->brush_faces; face; face = face->next ) {
  277. //Don't add face that was clicked
  278. if ( face != t.face ) {
  279. g_SelectedFaces.Add( face );
  280. g_SelectedFaceBrushes.Add( t.brush );
  281. }
  282. }
  283. } else {
  284. g_SelectedFaces.Add(t.face);
  285. g_SelectedFaceBrushes.Add(t.brush);
  286. }
  287. }
  288. // selected_face = t.face; selected_face_brush = t.brush;
  289. Sys_UpdateWindows(W_ALL);
  290. g_qeglobals.d_select_mode = sel_brush;
  291. //common->Printf("before\n");
  292. //extern void Face_Info_BrushPrimit(face_t *face);
  293. //Face_Info_BrushPrimit(t.face);
  294. //common->Printf("after\n");
  295. //
  296. // Texture_SetTexture requires a brushprimit_texdef fitted to the default width=2
  297. // height=2 texture
  298. //
  299. brushprimit_texdef_t brushprimit_texdef;
  300. ConvertTexMatWithQTexture(&t.face->brushprimit_texdef, t.face->d_texture, &brushprimit_texdef, NULL);
  301. Texture_SetTexture(&t.face->texdef, &brushprimit_texdef, false, false);
  302. UpdateSurfaceDialog();
  303. return;
  304. }
  305. // move the brush to the other list
  306. g_qeglobals.d_select_mode = sel_brush;
  307. if (t.selected) {
  308. Brush_RemoveFromList(t.brush);
  309. Brush_AddToList(t.brush, &active_brushes);
  310. UpdatePatchInspector();
  311. UpdateSurfaceDialog();
  312. entity_t *e = t.brush->owner;
  313. if (e->eclass->nShowFlags & ECLASS_LIGHT && !t.brush->entityModel) {
  314. if (t.brush->pointLight) {
  315. }
  316. else {
  317. ClearSelectablePoints(t.brush);
  318. }
  319. }
  320. }
  321. else {
  322. Select_Brush(t.brush, !(GetAsyncKeyState(VK_MENU) & 0x8000));
  323. }
  324. Sys_UpdateWindows(W_ALL);
  325. }
  326. /*
  327. =======================================================================================================================
  328. =======================================================================================================================
  329. */
  330. void Select_Delete(void) {
  331. brush_t *brush;
  332. g_ptrSelectedFaces.RemoveAll();
  333. g_ptrSelectedFaceBrushes.RemoveAll();
  334. // selected_face = NULL;
  335. g_qeglobals.d_select_mode = sel_brush;
  336. g_qeglobals.d_select_count = 0;
  337. g_qeglobals.d_num_move_points = 0;
  338. while (selected_brushes.next != &selected_brushes) {
  339. brush = selected_brushes.next;
  340. if (brush->pPatch) {
  341. // Patch_Delete(brush->nPatchID);
  342. Patch_Delete(brush->pPatch);
  343. }
  344. Brush_Free(brush);
  345. }
  346. // FIXME: remove any entities with no brushes
  347. Sys_UpdateWindows(W_ALL);
  348. }
  349. /*
  350. =======================================================================================================================
  351. =======================================================================================================================
  352. */
  353. void Select_Deselect(bool bDeselectFaces) {
  354. brush_t *b;
  355. ClearSelectablePoints(NULL);
  356. Patch_Deselect();
  357. g_pParentWnd->ActiveXY()->UndoClear();
  358. g_qeglobals.d_workcount++;
  359. g_qeglobals.d_select_count = 0;
  360. g_qeglobals.d_num_move_points = 0;
  361. b = selected_brushes.next;
  362. if (b == &selected_brushes) {
  363. if (bDeselectFaces) {
  364. g_ptrSelectedFaces.RemoveAll();
  365. g_ptrSelectedFaceBrushes.RemoveAll();
  366. // selected_face = NULL;
  367. }
  368. Sys_UpdateWindows(W_ALL);
  369. return;
  370. }
  371. if (bDeselectFaces) {
  372. g_ptrSelectedFaces.RemoveAll();
  373. g_ptrSelectedFaceBrushes.RemoveAll();
  374. // selected_face = NULL;
  375. }
  376. g_qeglobals.d_select_mode = sel_brush;
  377. // grab top / bottom height for new brushes
  378. if (b->mins[2] < b->maxs[2]) {
  379. g_qeglobals.d_new_brush_bottom = b->mins;
  380. g_qeglobals.d_new_brush_top = b->maxs;
  381. }
  382. selected_brushes.next->prev = &active_brushes;
  383. selected_brushes.prev->next = active_brushes.next;
  384. active_brushes.next->prev = selected_brushes.prev;
  385. active_brushes.next = selected_brushes.next;
  386. selected_brushes.prev = selected_brushes.next = &selected_brushes;
  387. g_pParentWnd->GetCamera()->UpdateCameraView();
  388. Sys_UpdateWindows(W_ALL);
  389. }
  390. /*
  391. =======================================================================================================================
  392. Select_Move
  393. =======================================================================================================================
  394. */
  395. void Select_Move(idVec3 delta, bool bSnap) {
  396. brush_t *b;
  397. // actually move the selected brushes
  398. bool updateOrigin = true;
  399. entity_t *lastOwner = selected_brushes.next->owner;
  400. for (b = selected_brushes.next; b != &selected_brushes; b = b->next) {
  401. Brush_Move(b, delta, bSnap, updateOrigin);
  402. if (updateOrigin) {
  403. updateOrigin = false;
  404. }
  405. if (b->next->owner != lastOwner) {
  406. updateOrigin = true;
  407. lastOwner = b->next->owner;
  408. }
  409. }
  410. idVec3 vMin, vMax;
  411. Select_GetBounds(vMin, vMax);
  412. CString strStatus;
  413. strStatus.Format("Origin X:: %.1f Y:: %.1f Z:: %.1f", vMin[0], vMax[1], vMax[2]);
  414. g_pParentWnd->SetStatusText(2, strStatus);
  415. g_pParentWnd->GetCamera()->UpdateCameraView();
  416. // Sys_UpdateWindows (W_ALL);
  417. }
  418. /*
  419. =======================================================================================================================
  420. Select_Clone Creates an exact duplicate of the selection in place, then moves the selected brushes off of their old
  421. positions
  422. =======================================================================================================================
  423. */
  424. void Select_Clone(void) {
  425. ASSERT(g_pParentWnd->ActiveXY());
  426. g_bScreenUpdates = false;
  427. g_pParentWnd->ActiveXY()->Copy();
  428. g_pParentWnd->ActiveXY()->Paste();
  429. g_pParentWnd->NudgeSelection(2, g_qeglobals.d_gridsize);
  430. g_pParentWnd->NudgeSelection(3, g_qeglobals.d_gridsize);
  431. g_bScreenUpdates = true;
  432. Sys_UpdateWindows(W_ALL);
  433. }
  434. /*
  435. =======================================================================================================================
  436. Select_SetTexture Timo:: bFitScale to compute scale on the plane and counteract plane / axial plane snapping Timo::
  437. brush primitive texturing the brushprimit_texdef given must be understood as a qtexture_t width=2 height=2 ( HiRes
  438. ) Timo:: texture plugin, added an IPluginTexdef* parameter must be casted to an IPluginTexdef! if not NULL, get
  439. ->Copy() of it into each face or brush ( and remember to hook ) if NULL, means we have no information, ask for a
  440. default
  441. =======================================================================================================================
  442. */
  443. void WINAPI Select_SetTexture(texdef_t *texdef,brushprimit_texdef_t *brushprimit_texdef,bool bFitScale,void *pPlugTexdef,bool update) {
  444. brush_t *b;
  445. int nCount = g_ptrSelectedFaces.GetSize();
  446. if (nCount > 0) {
  447. Undo_Start("set face textures");
  448. ASSERT(g_ptrSelectedFaces.GetSize() == g_ptrSelectedFaceBrushes.GetSize());
  449. for (int i = 0; i < nCount; i++) {
  450. face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(i));
  451. brush_t *selBrush = reinterpret_cast < brush_t * > (g_ptrSelectedFaceBrushes.GetAt(i));
  452. Undo_AddBrush(selBrush);
  453. SetFaceTexdef(selBrush,selFace,texdef,brushprimit_texdef,bFitScale);
  454. Brush_Build(selBrush, bFitScale);
  455. Undo_EndBrush(selBrush);
  456. }
  457. Undo_End();
  458. }
  459. else if (selected_brushes.next != &selected_brushes) {
  460. Undo_Start("set brush textures");
  461. for (b = selected_brushes.next; b != &selected_brushes; b = b->next) {
  462. if (!b->owner->eclass->fixedsize) {
  463. Undo_AddBrush(b);
  464. Brush_SetTexture(b, texdef, brushprimit_texdef, bFitScale);
  465. Undo_EndBrush(b);
  466. } else if (b->owner->eclass->nShowFlags & ECLASS_LIGHT) {
  467. if ( idStr::Cmpn(texdef->name, "lights/", strlen("lights/")) == 0 ) {
  468. SetKeyValue(b->owner, "texture", texdef->name);
  469. g_Inspectors->UpdateEntitySel(b->owner->eclass);
  470. UpdateLightInspector();
  471. Brush_Build(b);
  472. } else {
  473. Undo_AddBrush(b);
  474. Brush_SetTexture(b, texdef, brushprimit_texdef, bFitScale);
  475. Undo_EndBrush(b);
  476. }
  477. }
  478. }
  479. Undo_End();
  480. }
  481. if (update) {
  482. Sys_UpdateWindows(W_ALL);
  483. }
  484. }
  485. /*
  486. =======================================================================================================================
  487. TRANSFORMATIONS
  488. =======================================================================================================================
  489. */
  490. void Select_GetBounds(idVec3 &mins, idVec3 &maxs) {
  491. brush_t *b;
  492. int i;
  493. for (i = 0; i < 3; i++) {
  494. mins[i] = 999999;
  495. maxs[i] = -999999;
  496. }
  497. for (b = selected_brushes.next; b != &selected_brushes; b = b->next) {
  498. for (i = 0; i < 3; i++) {
  499. if (b->mins[i] < mins[i]) {
  500. mins[i] = b->mins[i];
  501. }
  502. if (b->maxs[i] > maxs[i]) {
  503. maxs[i] = b->maxs[i];
  504. }
  505. }
  506. }
  507. }
  508. /*
  509. =======================================================================================================================
  510. =======================================================================================================================
  511. */
  512. void Select_GetTrueMid(idVec3 &mid) {
  513. idVec3 mins, maxs;
  514. Select_GetBounds(mins, maxs);
  515. for (int i = 0; i < 3; i++) {
  516. mid[i] = (mins[i] + ((maxs[i] - mins[i]) / 2));
  517. }
  518. }
  519. /*
  520. =======================================================================================================================
  521. =======================================================================================================================
  522. */
  523. void Select_GetMid(idVec3 &mid) {
  524. #if 0
  525. Select_GetTrueMid(mid);
  526. return;
  527. #else
  528. idVec3 mins, maxs;
  529. int i;
  530. //if (g_PrefsDlg.m_bNoClamp) {
  531. // Select_GetTrueMid(mid);
  532. // return;
  533. //}
  534. Select_GetBounds(mins, maxs);
  535. for (i = 0; i < 3; i++) {
  536. mid[i] = g_qeglobals.d_gridsize * floor(((mins[i] + maxs[i]) * 0.5) / g_qeglobals.d_gridsize);
  537. }
  538. #endif
  539. }
  540. idVec3 select_origin;
  541. idMat3 select_matrix;
  542. idMat3 select_bmatrix;
  543. idRotation select_rotation;
  544. bool select_fliporder;
  545. int select_flipAxis;
  546. float select_orgDeg;
  547. void Select_InitializeRotation() {
  548. for (brush_t *b = selected_brushes.next; b != &selected_brushes; b = b->next) {
  549. for (face_t *f = b->brush_faces; f; f = f->next) {
  550. for (int i = 0; i < 3; i++) {
  551. f->orgplanepts[i] = f->planepts[i];
  552. }
  553. }
  554. }
  555. select_orgDeg = 0.0;
  556. }
  557. void Select_FinalizeRotation() {
  558. }
  559. bool Select_OnlyModelsSelected() {
  560. for (brush_t *b = selected_brushes.next; b != &selected_brushes; b = b->next) {
  561. if (!b->modelHandle) {
  562. return false;
  563. }
  564. }
  565. return true;
  566. }
  567. bool OkForRotationKey(brush_t *b) {
  568. if (b->owner->eclass->nShowFlags & ECLASS_WORLDSPAWN) {
  569. return false;
  570. }
  571. if (stricmp(b->owner->epairs.GetString("name"), b->owner->epairs.GetString("model")) == 0) {
  572. return false;
  573. }
  574. return true;
  575. }
  576. /*
  577. =================
  578. VectorRotate3
  579. rotation order is roll - pitch - yaw
  580. =================
  581. */
  582. void VectorRotate3( const idVec3 &vIn, const idVec3 &vRotation, idVec3 &out) {
  583. #if 1
  584. int i, nIndex[3][2];
  585. idVec3 vWork, va;
  586. va = vIn;
  587. vWork = va;
  588. nIndex[0][0] = 1; nIndex[0][1] = 2;
  589. nIndex[1][0] = 2; nIndex[1][1] = 0;
  590. nIndex[2][0] = 0; nIndex[2][1] = 1;
  591. for (i = 0; i < 3; i++) {
  592. if ( vRotation[i] != 0.0f ) {
  593. double dAngle = DEG2RAD( vRotation[i] );
  594. double c = cos( dAngle );
  595. double s = sin( dAngle );
  596. vWork[nIndex[i][0]] = va[nIndex[i][0]] * c - va[nIndex[i][1]] * s;
  597. vWork[nIndex[i][1]] = va[nIndex[i][0]] * s + va[nIndex[i][1]] * c;
  598. }
  599. va = vWork;
  600. }
  601. out = vWork;
  602. #else
  603. idAngles angles;
  604. angles.pitch = vRotation[1];
  605. angles.yaw = vRotation[2];
  606. angles.roll = vRotation[0];
  607. out = vIn * angles.ToMat3();
  608. #endif
  609. }
  610. /*
  611. =================
  612. VectorRotate3Origin
  613. =================
  614. */
  615. void VectorRotate3Origin( const idVec3 &vIn, const idVec3 &vRotation, const idVec3 &vOrigin, idVec3 &out ) {
  616. out = vIn - vOrigin;
  617. VectorRotate3( out, vRotation, out );
  618. out += vOrigin;
  619. }
  620. /*
  621. =======================================================================================================================
  622. =======================================================================================================================
  623. */
  624. extern void Brush_Rotate(brush_t *b, idMat3 matrix, idVec3 origin, bool bBuild);
  625. void Select_ApplyMatrix(bool bSnap, bool rotateOrigins) {
  626. brush_t *b;
  627. face_t *f;
  628. int i;
  629. idVec3 temp;
  630. idStr str;
  631. char text[128];
  632. entity_t *lastOwner = NULL;
  633. for (b = selected_brushes.next; b != &selected_brushes; b = b->next) {
  634. bool doBrush = true;
  635. if (!(b->owner->eclass->nShowFlags & ECLASS_WORLDSPAWN) && b->owner != lastOwner) {
  636. if (b->modelHandle || b->owner->eclass->nShowFlags & ECLASS_ROTATABLE) {
  637. if (rotateOrigins) {
  638. b->owner->rotation *= select_matrix;
  639. b->owner->origin *= select_rotation;
  640. SetKeyVec3(b->owner, "origin", b->owner->origin);
  641. if (b->trackLightOrigin) {
  642. b->owner->lightRotation *= select_matrix;
  643. b->owner->lightOrigin *= select_rotation;
  644. SetKeyVec3(b->owner, "light_origin", b->owner->lightOrigin);
  645. }
  646. } else {
  647. b->owner->rotation *= select_matrix;
  648. if ( select_fliporder ) {
  649. if ( select_flipAxis == 0 ) {
  650. temp = b->owner->rotation[1];
  651. b->owner->rotation[1] = b->owner->rotation[2];
  652. b->owner->rotation[2] = temp;
  653. } else if ( select_flipAxis == 1 ) {
  654. temp = b->owner->rotation[0];
  655. b->owner->rotation[0] = b->owner->rotation[1];
  656. b->owner->rotation[1] = temp;
  657. } else {
  658. temp = b->owner->rotation[0];
  659. b->owner->rotation[0] = b->owner->rotation[2];
  660. b->owner->rotation[2] = temp;
  661. }
  662. }
  663. if (b->trackLightOrigin) {
  664. b->owner->lightRotation = select_matrix * b->owner->lightRotation;
  665. }
  666. }
  667. b->owner->rotation.OrthoNormalizeSelf();
  668. b->owner->lightRotation.OrthoNormalizeSelf();
  669. if (b->modelHandle) {
  670. idBounds bo, bo2;
  671. bo2.Zero();
  672. if ( dynamic_cast<idRenderModelPrt*>( b->modelHandle ) || dynamic_cast<idRenderModelLiquid*>( b->modelHandle ) ) {
  673. bo2.ExpandSelf( 12.0f );
  674. } else {
  675. bo2 = b->modelHandle->Bounds();
  676. }
  677. bo.FromTransformedBounds(bo2, b->owner->origin, b->owner->rotation);
  678. Brush_Resize(b, bo[0], bo[1]);
  679. doBrush = false;
  680. }
  681. if (b->owner->eclass->fixedsize) {
  682. doBrush = false;
  683. }
  684. } else if (b->owner->eclass->fixedsize && !rotateOrigins) {
  685. doBrush = false;
  686. } else {
  687. b->owner->origin -= select_origin;
  688. b->owner->origin *= select_matrix;
  689. b->owner->origin += select_origin;
  690. sprintf(text, "%i %i %i", (int)b->owner->origin[0], (int)b->owner->origin[1], (int)b->owner->origin[2]);
  691. SetKeyValue(b->owner, "origin", text);
  692. }
  693. if (OkForRotationKey(b)) {
  694. sprintf(str, "%g %g %g %g %g %g %g %g %g",b->owner->rotation[0][0],b->owner->rotation[0][1],b->owner->rotation[0][2],
  695. b->owner->rotation[1][0],b->owner->rotation[1][1],b->owner->rotation[1][2],b->owner->rotation[2][0],
  696. b->owner->rotation[2][1],b->owner->rotation[2][2]);
  697. SetKeyValue(b->owner, "rotation", str);
  698. }
  699. if (b->trackLightOrigin) {
  700. sprintf(str, "%g %g %g %g %g %g %g %g %g",b->owner->lightRotation[0][0],b->owner->lightRotation[0][1],b->owner->lightRotation[0][2],
  701. b->owner->lightRotation[1][0],b->owner->lightRotation[1][1],b->owner->lightRotation[1][2],b->owner->lightRotation[2][0],
  702. b->owner->lightRotation[2][1],b->owner->lightRotation[2][2]);
  703. SetKeyValue(b->owner, "light_rotation", str);
  704. }
  705. DeleteKey(b->owner, "angle");
  706. DeleteKey(b->owner, "angles");
  707. }
  708. if (doBrush) {
  709. for (f = b->brush_faces; f; f = f->next) {
  710. for (i = 0; i < 3; i++) {
  711. f->planepts[i] = ( ((g_bRotateMode) ? f->orgplanepts[i] : f->planepts[i]) - select_origin ) * ((g_bRotateMode) ? select_bmatrix : select_matrix) + select_origin;
  712. }
  713. if ( select_fliporder ) {
  714. VectorCopy(f->planepts[0], temp);
  715. VectorCopy(f->planepts[2], f->planepts[0]);
  716. VectorCopy(temp, f->planepts[2]);
  717. }
  718. }
  719. }
  720. if (b->owner->eclass->fixedsize && b->owner->eclass->entityModel == NULL) {
  721. idVec3 min, max;
  722. if (b->trackLightOrigin) {
  723. min = b->owner->lightOrigin + b->owner->eclass->mins;
  724. max = b->owner->lightOrigin + b->owner->eclass->maxs;
  725. } else {
  726. min = b->owner->origin + b->owner->eclass->mins;
  727. max = b->owner->origin + b->owner->eclass->maxs;
  728. }
  729. Brush_Resize(b, min, max);
  730. } else {
  731. Brush_Build(b, bSnap);
  732. }
  733. if (b->pPatch) {
  734. Patch_ApplyMatrix(b->pPatch, select_origin, select_matrix, bSnap);
  735. }
  736. if ( b->owner->curve ) {
  737. int c = b->owner->curve->GetNumValues();
  738. for ( i = 0; i < c; i++ ) {
  739. idVec3 v = b->owner->curve->GetValue( i );
  740. v -= select_origin;
  741. v *= select_matrix;
  742. v += select_origin;
  743. b->owner->curve->SetValue( i, v );
  744. }
  745. }
  746. lastOwner = b->owner;
  747. }
  748. }
  749. /*
  750. =======================================================================================================================
  751. =======================================================================================================================
  752. */
  753. void RotateFaceTexture(face_t *f, int nAxis, float fDeg) {
  754. idVec3 p1, p2, p3, rota;
  755. p1[0] = p1[1] = p1[2] = 0;
  756. VectorCopy(p1, p2);
  757. VectorCopy(p1, p3);
  758. VectorCopy(p1, rota);
  759. ComputeAbsolute(f, p1, p2, p3);
  760. rota[nAxis] = fDeg;
  761. VectorRotate3Origin(p1, rota, select_origin, p1);
  762. VectorRotate3Origin(p2, rota, select_origin, p2);
  763. VectorRotate3Origin(p3, rota, select_origin, p3);
  764. idPlane normal2;
  765. idVec3 vNormal;
  766. vNormal[0] = f->plane[0];
  767. vNormal[1] = f->plane[1];
  768. vNormal[2] = f->plane[2];
  769. VectorRotate3(vNormal, rota, vNormal);
  770. normal2[0] = vNormal[0];
  771. normal2[1] = vNormal[1];
  772. normal2[2] = vNormal[2];
  773. AbsoluteToLocal(normal2, f, p1, p2, p3);
  774. }
  775. /*
  776. =======================================================================================================================
  777. =======================================================================================================================
  778. */
  779. void RotateTextures(int nAxis, float fDeg, idVec3 vOrigin) {
  780. for (brush_t * b = selected_brushes.next; b != &selected_brushes; b = b->next) {
  781. for (face_t * f = b->brush_faces; f; f = f->next) {
  782. if (g_qeglobals.m_bBrushPrimitMode) {
  783. RotateFaceTexture_BrushPrimit(f, nAxis, fDeg, vOrigin);
  784. }
  785. else {
  786. RotateFaceTexture(f, nAxis, fDeg);
  787. }
  788. // ++timo removed that call .. works fine .. ??????? Brush_Build(b, false);
  789. }
  790. Brush_Build(b, false);
  791. }
  792. }
  793. /*
  794. =======================================================================================================================
  795. =======================================================================================================================
  796. */
  797. void Select_ApplyMatrix_BrushPrimit() {
  798. for (brush_t * b = selected_brushes.next; b != &selected_brushes; b = b->next) {
  799. for (face_t * f = b->brush_faces; f; f = f->next) {
  800. ApplyMatrix_BrushPrimit(f, select_matrix, select_origin);
  801. }
  802. }
  803. }
  804. /*
  805. =======================================================================================================================
  806. =======================================================================================================================
  807. */
  808. void Select_RotateAxis(int axis, float deg, bool bPaint, bool bMouse) {
  809. idVec3 temp;
  810. if (deg == 0) {
  811. return;
  812. }
  813. if (bMouse) {
  814. if (g_qeglobals.flatRotation == 2) {
  815. Select_GetTrueMid(select_origin);
  816. } else {
  817. VectorCopy(g_pParentWnd->ActiveXY()->RotateOrigin(), select_origin);
  818. }
  819. } else {
  820. Select_GetMid(select_origin);
  821. }
  822. select_fliporder = false;
  823. idVec3 vec = vec3_origin;
  824. vec[axis] = 1.0f;
  825. if (g_bRotateMode) {
  826. select_orgDeg += deg;
  827. }
  828. select_rotation.Set( select_origin, vec, deg );
  829. select_matrix = select_rotation.ToMat3();
  830. idRotation rot(select_origin, vec, select_orgDeg);
  831. rot.Normalize360();
  832. select_bmatrix = rot.ToMat3();
  833. if (g_PrefsDlg.m_bRotateLock) {
  834. select_matrix.TransposeSelf();
  835. Select_ApplyMatrix_BrushPrimit();
  836. //RotateTextures(axis, -deg, select_origin);
  837. }
  838. select_matrix.TransposeSelf();
  839. Select_ApplyMatrix( !bMouse, ( g_qeglobals.flatRotation != 0 ) );
  840. if (bPaint) {
  841. Sys_UpdateWindows(W_ALL);
  842. }
  843. }
  844. /*
  845. =======================================================================================================================
  846. =======================================================================================================================
  847. */
  848. void ProjectOnPlane( const idVec3 &normal, float dist, idVec3 &ez, idVec3 &p) {
  849. if (idMath::Fabs(ez[0]) == 1) {
  850. p[0] = (dist - normal[1] * p[1] - normal[2] * p[2]) / normal[0];
  851. }
  852. else if (idMath::Fabs(ez[1]) == 1) {
  853. p[1] = (dist - normal[0] * p[0] - normal[2] * p[2]) / normal[1];
  854. }
  855. else {
  856. p[2] = (dist - normal[0] * p[0] - normal[1] * p[1]) / normal[2];
  857. }
  858. }
  859. /*
  860. =======================================================================================================================
  861. =======================================================================================================================
  862. */
  863. void Back(idVec3 &dir, idVec3 &p) {
  864. if (idMath::Fabs(dir[0]) == 1) {
  865. p[0] = 0;
  866. }
  867. else if (idMath::Fabs(dir[1]) == 1) {
  868. p[1] = 0;
  869. }
  870. else {
  871. p[2] = 0;
  872. }
  873. }
  874. //
  875. // =======================================================================================================================
  876. // using scale[0] and scale[1]
  877. // =======================================================================================================================
  878. //
  879. void ComputeScale(idVec3 &rex, idVec3 &rey, idVec3 &p, face_t *f) {
  880. float px = DotProduct(rex, p);
  881. float py = DotProduct(rey, p);
  882. px *= f->texdef.scale[0];
  883. py *= f->texdef.scale[1];
  884. idVec3 aux;
  885. VectorCopy(rex, aux);
  886. VectorScale(aux, px, aux);
  887. VectorCopy(aux, p);
  888. VectorCopy(rey, aux);
  889. VectorScale(aux, py, aux);
  890. VectorAdd(p, aux, p);
  891. }
  892. /*
  893. =======================================================================================================================
  894. =======================================================================================================================
  895. */
  896. void ComputeAbsolute(face_t *f, idVec3 &p1, idVec3 &p2, idVec3 &p3) {
  897. idVec3 ex, ey, ez; // local axis base
  898. #ifdef _DEBUG
  899. if (g_qeglobals.m_bBrushPrimitMode) {
  900. common->Printf("Warning : illegal call of ComputeAbsolute in brush primitive mode\n");
  901. }
  902. #endif
  903. // compute first local axis base
  904. TextureAxisFromPlane( f->plane, ex, ey );
  905. ez = ex.Cross( ey );
  906. idVec3 aux;
  907. VectorCopy(ex, aux);
  908. VectorScale(aux, -f->texdef.shift[0], aux);
  909. VectorCopy(aux, p1);
  910. VectorCopy(ey, aux);
  911. VectorScale(aux, -f->texdef.shift[1], aux);
  912. VectorAdd(p1, aux, p1);
  913. VectorCopy(p1, p2);
  914. VectorAdd(p2, ex, p2);
  915. VectorCopy(p1, p3);
  916. VectorAdd(p3, ey, p3);
  917. VectorCopy(ez, aux);
  918. VectorScale(aux, -f->texdef.rotate, aux);
  919. VectorRotate3(p1, aux, p1);
  920. VectorRotate3(p2, aux, p2);
  921. VectorRotate3(p3, aux, p3);
  922. // computing rotated local axis base
  923. idVec3 rex, rey;
  924. VectorCopy(ex, rex);
  925. VectorRotate3(rex, aux, rex);
  926. VectorCopy(ey, rey);
  927. VectorRotate3(rey, aux, rey);
  928. ComputeScale(rex, rey, p1, f);
  929. ComputeScale(rex, rey, p2, f);
  930. ComputeScale(rex, rey, p3, f);
  931. // project on normal plane along ez assumes plane normal is normalized
  932. ProjectOnPlane(f->plane.Normal(), -f->plane[3], ez, p1);
  933. ProjectOnPlane(f->plane.Normal(), -f->plane[3], ez, p2);
  934. ProjectOnPlane(f->plane.Normal(), -f->plane[3], ez, p3);
  935. };
  936. /*
  937. =======================================================================================================================
  938. =======================================================================================================================
  939. */
  940. void AbsoluteToLocal( const idPlane &normal2, face_t *f, idVec3 &p1, idVec3 &p2, idVec3 &p3) {
  941. idVec3 ex, ey, ez;
  942. #ifdef _DEBUG
  943. if (g_qeglobals.m_bBrushPrimitMode) {
  944. common->Printf("Warning : illegal call of AbsoluteToLocal in brush primitive mode\n");
  945. }
  946. #endif
  947. // computing new local axis base
  948. TextureAxisFromPlane( normal2, ex, ey );
  949. ez = ex.Cross( ey );
  950. // projecting back on (ex,ey)
  951. Back(ez, p1);
  952. Back(ez, p2);
  953. Back(ez, p3);
  954. idVec3 aux;
  955. // rotation
  956. VectorCopy(p2, aux);
  957. VectorSubtract(aux, p1, aux);
  958. float x = DotProduct(aux, ex);
  959. float y = DotProduct(aux, ey);
  960. f->texdef.rotate = RAD2DEG( atan2(y, x) );
  961. idVec3 rex, rey;
  962. // computing rotated local axis base
  963. VectorCopy(ez, aux);
  964. VectorScale(aux, f->texdef.rotate, aux);
  965. VectorCopy(ex, rex);
  966. VectorRotate3(rex, aux, rex);
  967. VectorCopy(ey, rey);
  968. VectorRotate3(rey, aux, rey);
  969. // scale
  970. VectorCopy(p2, aux);
  971. VectorSubtract(aux, p1, aux);
  972. f->texdef.scale[0] = DotProduct(aux, rex);
  973. VectorCopy(p3, aux);
  974. VectorSubtract(aux, p1, aux);
  975. f->texdef.scale[1] = DotProduct(aux, rey);
  976. // shift only using p1
  977. x = DotProduct(rex, p1);
  978. y = DotProduct(rey, p1);
  979. x /= f->texdef.scale[0];
  980. y /= f->texdef.scale[1];
  981. VectorCopy(rex, p1);
  982. VectorScale(p1, x, p1);
  983. VectorCopy(rey, aux);
  984. VectorScale(aux, y, aux);
  985. VectorAdd(p1, aux, p1);
  986. VectorCopy(ez, aux);
  987. VectorScale(aux, -f->texdef.rotate, aux);
  988. VectorRotate3(p1, aux, p1);
  989. f->texdef.shift[0] = -DotProduct(p1, ex);
  990. f->texdef.shift[1] = -DotProduct(p1, ey);
  991. // stored rot is good considering local axis base change it if necessary
  992. f->texdef.rotate = -f->texdef.rotate;
  993. Clamp(f->texdef.shift[0], f->d_texture->GetEditorImage()->uploadWidth);
  994. Clamp(f->texdef.shift[1], f->d_texture->GetEditorImage()->uploadHeight);
  995. Clamp(f->texdef.rotate, 360);
  996. }
  997. /*
  998. =======================================================================================================================
  999. =======================================================================================================================
  1000. */
  1001. void Select_FlipAxis(int axis) {
  1002. Select_GetMid( select_origin );
  1003. for ( int i = 0; i < 3; i++) {
  1004. VectorCopy(vec3_origin, select_matrix[i]);
  1005. select_matrix[i][i] = 1;
  1006. }
  1007. select_matrix[axis][axis] = -1;
  1008. select_matrix.Identity();
  1009. select_matrix[axis][axis] = -1;
  1010. select_fliporder = true;
  1011. select_flipAxis = axis;
  1012. // texture locking
  1013. if (g_PrefsDlg.m_bRotateLock) {
  1014. //
  1015. // axis flipping inverts space orientation, we have to use a general texture
  1016. // locking algorithm instead of the RotateFaceTexture
  1017. //
  1018. if (g_qeglobals.m_bBrushPrimitMode) {
  1019. Select_ApplyMatrix_BrushPrimit();
  1020. }
  1021. else {
  1022. //
  1023. // there's never been flip locking for non BP mode, this would be tricky to write
  1024. // and there's not much interest for it with the coming of BP format what could be
  1025. // done is converting regular to BP, locking, then back to regular :)
  1026. // Sys_FPrintf(SYS_WRN, "WARNING: regular texturing doesn't have texture lock on
  1027. // flipping operations\n");
  1028. //
  1029. }
  1030. }
  1031. // geometric transformation
  1032. Select_ApplyMatrix(true, false);
  1033. Sys_UpdateWindows(W_ALL);}
  1034. /*
  1035. =======================================================================================================================
  1036. =======================================================================================================================
  1037. */
  1038. void Select_Scale(float x, float y, float z) {
  1039. Select_GetMid(select_origin);
  1040. for (brush_t * b = selected_brushes.next; b != &selected_brushes; b = b->next) {
  1041. for (face_t * f = b->brush_faces; f; f = f->next) {
  1042. for (int i = 0; i < 3; i++) {
  1043. f->planepts[i][0] -= select_origin[0];
  1044. f->planepts[i][1] -= select_origin[1];
  1045. f->planepts[i][2] -= select_origin[2];
  1046. f->planepts[i][0] *= x;
  1047. //
  1048. // f->planepts[i][0] = floor(f->planepts[i][0] / g_qeglobals.d_gridsize + 0.5) *
  1049. // g_qeglobals.d_gridsize;
  1050. //
  1051. f->planepts[i][1] *= y;
  1052. //
  1053. // f->planepts[i][1] = floor(f->planepts[i][1] / g_qeglobals.d_gridsize + 0.5) *
  1054. // g_qeglobals.d_gridsize;
  1055. //
  1056. f->planepts[i][2] *= z;
  1057. //
  1058. // f->planepts[i][2] = floor(f->planepts[i][2] / g_qeglobals.d_gridsize + 0.5) *
  1059. // g_qeglobals.d_gridsize;
  1060. //
  1061. f->planepts[i][0] += select_origin[0];
  1062. f->planepts[i][1] += select_origin[1];
  1063. f->planepts[i][2] += select_origin[2];
  1064. }
  1065. }
  1066. Brush_Build(b, false);
  1067. if (b->pPatch) {
  1068. idVec3 v;
  1069. v[0] = x;
  1070. v[1] = y;
  1071. v[2] = z;
  1072. // Patch_Scale(b->nPatchID, select_origin, v);
  1073. Patch_Scale(b->pPatch, select_origin, v);
  1074. }
  1075. }
  1076. }
  1077. /*
  1078. =======================================================================================================================
  1079. GROUP SELECTIONS
  1080. =======================================================================================================================
  1081. */
  1082. void Select_CompleteTall(void) {
  1083. brush_t *b, *next;
  1084. // int i;
  1085. idVec3 mins, maxs;
  1086. if (!QE_SingleBrush()) {
  1087. return;
  1088. }
  1089. g_qeglobals.d_select_mode = sel_brush;
  1090. VectorCopy(selected_brushes.next->mins, mins);
  1091. VectorCopy(selected_brushes.next->maxs, maxs);
  1092. Select_Delete();
  1093. int nDim1 = (g_pParentWnd->ActiveXY()->GetViewType() == YZ) ? 1 : 0;
  1094. int nDim2 = (g_pParentWnd->ActiveXY()->GetViewType() == XY) ? 1 : 2;
  1095. for (b = active_brushes.next; b != &active_brushes; b = next) {
  1096. next = b->next;
  1097. if ((b->maxs[nDim1] > maxs[nDim1] || b->mins[nDim1] < mins[nDim1]) || (b->maxs[nDim2] > maxs[nDim2] || b->mins[nDim2] < mins[nDim2])) {
  1098. if (!(b->owner->origin[nDim1] > mins[nDim1] && b->owner->origin[nDim1] < maxs[nDim1] && b->owner->origin[nDim2] > mins[nDim2] && b->owner->origin[nDim2] < maxs[nDim2])) {
  1099. continue;
  1100. }
  1101. if (b->owner->eclass->nShowFlags & ECLASS_WORLDSPAWN) {
  1102. continue;
  1103. }
  1104. }
  1105. if (FilterBrush(b)) {
  1106. continue;
  1107. }
  1108. Brush_RemoveFromList(b);
  1109. Brush_AddToList(b, &selected_brushes);
  1110. }
  1111. Sys_UpdateWindows(W_ALL);
  1112. }
  1113. /*
  1114. =======================================================================================================================
  1115. =======================================================================================================================
  1116. */
  1117. void Select_PartialTall(void) {
  1118. brush_t *b, *next;
  1119. // int i;
  1120. idVec3 mins, maxs;
  1121. if (!QE_SingleBrush()) {
  1122. return;
  1123. }
  1124. g_qeglobals.d_select_mode = sel_brush;
  1125. VectorCopy(selected_brushes.next->mins, mins);
  1126. VectorCopy(selected_brushes.next->maxs, maxs);
  1127. Select_Delete();
  1128. int nDim1 = (g_pParentWnd->ActiveXY()->GetViewType() == YZ) ? 1 : 0;
  1129. int nDim2 = (g_pParentWnd->ActiveXY()->GetViewType() == XY) ? 1 : 2;
  1130. for (b = active_brushes.next; b != &active_brushes; b = next) {
  1131. next = b->next;
  1132. if
  1133. (
  1134. (b->mins[nDim1] > maxs[nDim1] || b->maxs[nDim1] < mins[nDim1]) ||
  1135. (b->mins[nDim2] > maxs[nDim2] || b->maxs[nDim2] < mins[nDim2])
  1136. ) {
  1137. continue;
  1138. }
  1139. if (FilterBrush(b)) {
  1140. continue;
  1141. }
  1142. Brush_RemoveFromList(b);
  1143. Brush_AddToList(b, &selected_brushes);
  1144. #if 0
  1145. // old stuff
  1146. for (i = 0; i < 2; i++) {
  1147. if (b->mins[i] > maxs[i] || b->maxs[i] < mins[i]) {
  1148. break;
  1149. }
  1150. }
  1151. if (i == 2) {
  1152. Brush_RemoveFromList(b);
  1153. Brush_AddToList(b, &selected_brushes);
  1154. }
  1155. #endif
  1156. }
  1157. Sys_UpdateWindows(W_ALL);
  1158. }
  1159. /*
  1160. =======================================================================================================================
  1161. =======================================================================================================================
  1162. */
  1163. void Select_Touching(void) {
  1164. brush_t *b, *next;
  1165. int i;
  1166. idVec3 mins, maxs;
  1167. if (!QE_SingleBrush()) {
  1168. return;
  1169. }
  1170. g_qeglobals.d_select_mode = sel_brush;
  1171. VectorCopy(selected_brushes.next->mins, mins);
  1172. VectorCopy(selected_brushes.next->maxs, maxs);
  1173. for (b = active_brushes.next; b != &active_brushes; b = next) {
  1174. next = b->next;
  1175. if (FilterBrush(b)) {
  1176. continue;
  1177. }
  1178. for (i = 0; i < 3; i++) {
  1179. if (b->mins[i] > maxs[i] + 1 || b->maxs[i] < mins[i] - 1) {
  1180. break;
  1181. }
  1182. }
  1183. if (i == 3) {
  1184. Brush_RemoveFromList(b);
  1185. Brush_AddToList(b, &selected_brushes);
  1186. }
  1187. }
  1188. Sys_UpdateWindows(W_ALL);
  1189. }
  1190. /*
  1191. =======================================================================================================================
  1192. =======================================================================================================================
  1193. */
  1194. void Select_Inside(void) {
  1195. brush_t *b, *next;
  1196. int i;
  1197. idVec3 mins, maxs;
  1198. if (!QE_SingleBrush()) {
  1199. return;
  1200. }
  1201. g_qeglobals.d_select_mode = sel_brush;
  1202. VectorCopy(selected_brushes.next->mins, mins);
  1203. VectorCopy(selected_brushes.next->maxs, maxs);
  1204. Select_Delete();
  1205. for (b = active_brushes.next; b != &active_brushes; b = next) {
  1206. next = b->next;
  1207. if (FilterBrush(b)) {
  1208. continue;
  1209. }
  1210. for (i = 0; i < 3; i++) {
  1211. if (b->maxs[i] > maxs[i] || b->mins[i] < mins[i]) {
  1212. break;
  1213. }
  1214. }
  1215. if (i == 3) {
  1216. Brush_RemoveFromList(b);
  1217. Brush_AddToList(b, &selected_brushes);
  1218. }
  1219. }
  1220. Sys_UpdateWindows(W_ALL);
  1221. }
  1222. /*
  1223. =======================================================================================================================
  1224. Select_Ungroup Turn the currently selected entity back into normal brushes
  1225. =======================================================================================================================
  1226. */
  1227. void Select_Ungroup() {
  1228. int numselectedgroups;
  1229. entity_t *e;
  1230. brush_t *b, *sb;
  1231. numselectedgroups = 0;
  1232. for (sb = selected_brushes.next; sb != &selected_brushes; sb = sb->next) {
  1233. e = sb->owner;
  1234. if (!e || e == world_entity) {
  1235. continue;
  1236. }
  1237. for (b = e->brushes.onext; b != &e->brushes; b = e->brushes.onext) {
  1238. Entity_UnlinkBrush(b);
  1239. Entity_LinkBrush(world_entity, b);
  1240. Brush_Build(b);
  1241. b->owner = world_entity;
  1242. }
  1243. Entity_Free(e);
  1244. numselectedgroups++;
  1245. }
  1246. if (numselectedgroups <= 0) {
  1247. Sys_Status("No grouped entities selected.\n");
  1248. return;
  1249. }
  1250. common->Printf("Ungrouped %d entit%s.\n", numselectedgroups, (numselectedgroups == 1) ? "y" : "ies");
  1251. Sys_UpdateWindows(W_ALL);
  1252. }
  1253. /*
  1254. =======================================================================================================================
  1255. =======================================================================================================================
  1256. */
  1257. void Select_ShiftTexture(float x, float y, bool autoAdjust) {
  1258. brush_t *b;
  1259. face_t *f;
  1260. int nFaceCount = g_ptrSelectedFaces.GetSize();
  1261. if (selected_brushes.next == &selected_brushes && nFaceCount == 0) {
  1262. return;
  1263. }
  1264. x = -x;
  1265. Undo_Start("Select shift textures");
  1266. for (b = selected_brushes.next; b != &selected_brushes; b = b->next) {
  1267. for (f = b->brush_faces; f; f = f->next) {
  1268. if (g_qeglobals.m_bBrushPrimitMode) {
  1269. // use face normal to compute a true translation
  1270. Select_ShiftTexture_BrushPrimit(f, x, y, autoAdjust);
  1271. }
  1272. else {
  1273. f->texdef.shift[0] += x;
  1274. f->texdef.shift[1] += y;
  1275. }
  1276. }
  1277. Brush_Build(b);
  1278. if (b->pPatch) {
  1279. // Patch_ShiftTexture(b->nPatchID, x, y);
  1280. Patch_ShiftTexture(b->pPatch, x, y, autoAdjust);
  1281. }
  1282. }
  1283. if (nFaceCount > 0) {
  1284. for (int i = 0; i < nFaceCount; i++) {
  1285. face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(i));
  1286. brush_t *selBrush = reinterpret_cast < brush_t * > (g_ptrSelectedFaceBrushes.GetAt(i));
  1287. if (g_qeglobals.m_bBrushPrimitMode) {
  1288. //
  1289. // use face normal to compute a true translation Select_ShiftTexture_BrushPrimit(
  1290. // selected_face, x, y ); use camera view to compute texture shift
  1291. //
  1292. Select_ShiftTexture_BrushPrimit(selFace, x, y, autoAdjust);
  1293. }
  1294. else {
  1295. selFace->texdef.shift[0] += x;
  1296. selFace->texdef.shift[1] += y;
  1297. }
  1298. Brush_Build(selBrush);
  1299. }
  1300. }
  1301. Undo_End();
  1302. Sys_UpdateWindows(W_CAMERA);
  1303. }
  1304. extern void Face_SetExplicitScale_BrushPrimit(face_t *face, float s, float t);
  1305. extern void Face_ScaleTexture_BrushPrimit(face_t *face, float sS, float sT);
  1306. /*
  1307. =======================================================================================================================
  1308. =======================================================================================================================
  1309. */
  1310. void Select_ScaleTexture(float x, float y, bool update, bool absolute) {
  1311. brush_t *b;
  1312. face_t *f;
  1313. int nFaceCount = g_ptrSelectedFaces.GetSize();
  1314. if (selected_brushes.next == &selected_brushes && nFaceCount == 0) {
  1315. return;
  1316. }
  1317. Undo_Start("Select_SetExplicitScale_BrushPrimit");
  1318. for (b = selected_brushes.next; b != &selected_brushes; b = b->next) {
  1319. for (f = b->brush_faces; f; f = f->next) {
  1320. if (g_qeglobals.m_bBrushPrimitMode && f->face_winding) {
  1321. if (absolute) {
  1322. Face_SetExplicitScale_BrushPrimit(f, x, y);
  1323. } else {
  1324. Face_ScaleTexture_BrushPrimit(f, x, y);
  1325. }
  1326. }
  1327. else {
  1328. f->texdef.scale[0] += x;
  1329. f->texdef.scale[1] += y;
  1330. }
  1331. }
  1332. Brush_Build(b);
  1333. if (b->pPatch) {
  1334. Patch_ScaleTexture(b->pPatch, x, y, absolute);
  1335. }
  1336. }
  1337. if (nFaceCount > 0) {
  1338. for (int i = 0; i < nFaceCount; i++) {
  1339. face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(i));
  1340. brush_t *selBrush = reinterpret_cast < brush_t * > (g_ptrSelectedFaceBrushes.GetAt(i));
  1341. if (g_qeglobals.m_bBrushPrimitMode) {
  1342. if (absolute) {
  1343. Face_SetExplicitScale_BrushPrimit(selFace, x, y);
  1344. } else {
  1345. Face_ScaleTexture_BrushPrimit(selFace, x, y);
  1346. }
  1347. }
  1348. else {
  1349. selFace->texdef.scale[0] += x;
  1350. selFace->texdef.scale[1] += y;
  1351. }
  1352. Brush_Build(selBrush);
  1353. }
  1354. }
  1355. Undo_End();
  1356. if (update) {
  1357. Sys_UpdateWindows(W_CAMERA);
  1358. }
  1359. }
  1360. extern void Face_RotateTexture_BrushPrimit(face_t *face, float amount, idVec3 origin);
  1361. /*
  1362. =======================================================================================================================
  1363. =======================================================================================================================
  1364. */
  1365. void Select_RotateTexture(float amt, bool absolute) {
  1366. brush_t *b;
  1367. face_t *f;
  1368. int nFaceCount = g_ptrSelectedFaces.GetSize();
  1369. if (selected_brushes.next == &selected_brushes && nFaceCount == 0) {
  1370. return;
  1371. }
  1372. Undo_Start("Select_RotateTexture_BrushPrimit");
  1373. for (b = selected_brushes.next; b != &selected_brushes; b = b->next) {
  1374. for (f = b->brush_faces; f; f = f->next) {
  1375. if (g_qeglobals.m_bBrushPrimitMode) {
  1376. Face_RotateTexture_BrushPrimit(f, amt, b->owner->origin);
  1377. }
  1378. else {
  1379. f->texdef.rotate += amt;
  1380. f->texdef.rotate = static_cast<int>(f->texdef.rotate) % 360;
  1381. }
  1382. }
  1383. Brush_Build(b);
  1384. if (b->pPatch) {
  1385. // Patch_RotateTexture(b->nPatchID, amt);
  1386. Patch_RotateTexture(b->pPatch, amt);
  1387. }
  1388. }
  1389. if (nFaceCount > 0) {
  1390. for (int i = 0; i < nFaceCount; i++) {
  1391. face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(i));
  1392. brush_t *selBrush = reinterpret_cast < brush_t * > (g_ptrSelectedFaceBrushes.GetAt(i));
  1393. if (g_qeglobals.m_bBrushPrimitMode) {
  1394. idVec3 org;
  1395. org.Zero();
  1396. //Face_RotateTexture_BrushPrimit(selFace, amt, selBrush->owner->origin);
  1397. Face_RotateTexture_BrushPrimit(selFace, amt, org);
  1398. }
  1399. else {
  1400. selFace->texdef.rotate += amt;
  1401. selFace->texdef.rotate = static_cast<int>(selFace->texdef.rotate) % 360;
  1402. }
  1403. Brush_Build(selBrush);
  1404. }
  1405. }
  1406. Undo_End();
  1407. Sys_UpdateWindows(W_CAMERA);
  1408. }
  1409. /*
  1410. =======================================================================================================================
  1411. =======================================================================================================================
  1412. */
  1413. void FindReplaceTextures(const char *pFind, const char *pReplace, bool bSelected, bool bForce) {
  1414. brush_t *pList = (bSelected) ? &selected_brushes : &active_brushes;
  1415. if (!bSelected) {
  1416. Select_Deselect();
  1417. }
  1418. for (brush_t * pBrush = pList->next; pBrush != pList; pBrush = pBrush->next) {
  1419. if (pBrush->pPatch) {
  1420. Patch_FindReplaceTexture(pBrush, pFind, pReplace, bForce);
  1421. }
  1422. for (face_t * pFace = pBrush->brush_faces; pFace; pFace = pFace->next) {
  1423. if (bForce || idStr::Icmp(pFace->texdef.name, pFind) == 0 ) {
  1424. pFace->d_texture = Texture_ForName(pReplace);
  1425. // strcpy(pFace->texdef.name, pReplace);
  1426. pFace->texdef.SetName(pReplace);
  1427. }
  1428. }
  1429. Brush_Build(pBrush);
  1430. }
  1431. Sys_UpdateWindows(W_CAMERA);
  1432. }
  1433. /*
  1434. =======================================================================================================================
  1435. =======================================================================================================================
  1436. */
  1437. void Select_AllOfType() {
  1438. brush_t *b, *next;
  1439. entity_t *e;
  1440. if ((selected_brushes.next == &selected_brushes) || (selected_brushes.next->next != &selected_brushes)) {
  1441. CString strName;
  1442. if (g_ptrSelectedFaces.GetSize() == 0) {
  1443. strName = g_qeglobals.d_texturewin.texdef.name;
  1444. }
  1445. else {
  1446. face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(0));
  1447. strName = selFace->texdef.name;
  1448. }
  1449. Select_Deselect();
  1450. for (b = active_brushes.next; b != &active_brushes; b = next) {
  1451. next = b->next;
  1452. if (FilterBrush(b)) {
  1453. continue;
  1454. }
  1455. if (b->pPatch) {
  1456. if ( idStr::Icmp(strName, b->pPatch->d_texture->GetName()) == 0 ) {
  1457. Brush_RemoveFromList(b);
  1458. Brush_AddToList(b, &selected_brushes);
  1459. }
  1460. }
  1461. else {
  1462. for (face_t * pFace = b->brush_faces; pFace; pFace = pFace->next) {
  1463. if ( idStr::Icmp(strName, pFace->texdef.name) == 0 ) {
  1464. Brush_RemoveFromList(b);
  1465. Brush_AddToList(b, &selected_brushes);
  1466. }
  1467. }
  1468. }
  1469. }
  1470. Sys_UpdateWindows(W_ALL);
  1471. return;
  1472. }
  1473. b = selected_brushes.next;
  1474. e = b->owner;
  1475. if (e != NULL) {
  1476. if (e != world_entity) {
  1477. CString strName = e->eclass->name;
  1478. idStr strKey, strVal;
  1479. bool bCriteria = g_Inspectors->GetSelectAllCriteria(strKey, strVal);
  1480. common->Printf("Selecting all %s(s)\n", strName);
  1481. Select_Deselect();
  1482. for (b = active_brushes.next; b != &active_brushes; b = next) {
  1483. next = b->next;
  1484. if (FilterBrush(b)) {
  1485. continue;
  1486. }
  1487. e = b->owner;
  1488. if (e != NULL) {
  1489. if ( idStr::Icmp(e->eclass->name, strName) == 0 ) {
  1490. bool doIt = true;
  1491. if (bCriteria) {
  1492. CString str = ValueForKey(e, strKey);
  1493. if (str.CompareNoCase(strVal) != 0) {
  1494. doIt = false;
  1495. }
  1496. }
  1497. if (doIt) {
  1498. Brush_RemoveFromList(b);
  1499. Brush_AddToList(b, &selected_brushes);
  1500. }
  1501. }
  1502. }
  1503. }
  1504. }
  1505. }
  1506. if ( selected_brushes.next && selected_brushes.next->owner ) {
  1507. g_Inspectors->UpdateEntitySel( selected_brushes.next->owner->eclass );
  1508. }
  1509. Sys_UpdateWindows(W_ALL);
  1510. }
  1511. /*
  1512. =======================================================================================================================
  1513. =======================================================================================================================
  1514. */
  1515. void Select_Reselect() {
  1516. CPtrArray holdArray;
  1517. brush_t *b;
  1518. for ( b = selected_brushes.next; b && b != &selected_brushes; b = b->next ) {
  1519. holdArray.Add(reinterpret_cast < void * > (b));
  1520. }
  1521. int n = holdArray.GetSize();
  1522. while (n-- > 0) {
  1523. b = reinterpret_cast < brush_t * > (holdArray.GetAt(n));
  1524. Select_Brush(b);
  1525. }
  1526. Sys_UpdateWindows(W_ALL);
  1527. }
  1528. /*
  1529. =======================================================================================================================
  1530. =======================================================================================================================
  1531. */
  1532. void Select_FitTexture(float height, float width) {
  1533. brush_t *b;
  1534. int nFaceCount = g_ptrSelectedFaces.GetSize();
  1535. if (selected_brushes.next == &selected_brushes && nFaceCount == 0) {
  1536. return;
  1537. }
  1538. Undo_Start("Select_FitTexture");
  1539. for (b = selected_brushes.next; b != &selected_brushes; b = b->next) {
  1540. if (b->pPatch) {
  1541. Patch_FitTexture(b->pPatch, width, height);
  1542. }
  1543. else {
  1544. Brush_FitTexture(b, height, width);
  1545. Brush_Build(b);
  1546. }
  1547. }
  1548. if (nFaceCount > 0) {
  1549. for (int i = 0; i < nFaceCount; i++) {
  1550. face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(i));
  1551. brush_t *selBrush = reinterpret_cast < brush_t * > (g_ptrSelectedFaceBrushes.GetAt(i));
  1552. Face_FitTexture(selFace, height, width);
  1553. Brush_Build(selBrush);
  1554. }
  1555. }
  1556. Undo_End();
  1557. Sys_UpdateWindows(W_CAMERA);
  1558. }
  1559. /*
  1560. =======================================================================================================================
  1561. =======================================================================================================================
  1562. */
  1563. void Select_AxialTexture() {
  1564. }
  1565. /*
  1566. =======================================================================================================================
  1567. =======================================================================================================================
  1568. */
  1569. void Select_Hide(bool invert) {
  1570. if (invert) {
  1571. for (brush_t * b = active_brushes.next; b && b != &active_brushes; b = b->next) {
  1572. b->hiddenBrush = true;
  1573. }
  1574. } else {
  1575. for (brush_t * b = selected_brushes.next; b && b != &selected_brushes; b = b->next) {
  1576. b->hiddenBrush = true;
  1577. }
  1578. }
  1579. Sys_UpdateWindows(W_ALL);
  1580. }
  1581. void Select_WireFrame( bool wireFrame ) {
  1582. for (brush_t * b = selected_brushes.next; b && b != &selected_brushes; b = b->next) {
  1583. b->forceWireFrame = wireFrame;
  1584. }
  1585. Sys_UpdateWindows(W_ALL);
  1586. }
  1587. void Select_ForceVisible( bool visible ) {
  1588. for (brush_t * b = selected_brushes.next; b && b != &selected_brushes; b = b->next) {
  1589. b->forceVisibile = visible;
  1590. }
  1591. Sys_UpdateWindows(W_ALL);
  1592. }
  1593. /*
  1594. =======================================================================================================================
  1595. =======================================================================================================================
  1596. */
  1597. void Select_ShowAllHidden() {
  1598. brush_t *b;
  1599. for (b = selected_brushes.next; b && b != &selected_brushes; b = b->next) {
  1600. b->hiddenBrush = false;
  1601. }
  1602. for (b = active_brushes.next; b && b != &active_brushes; b = b->next) {
  1603. b->hiddenBrush = false;
  1604. }
  1605. Sys_UpdateWindows(W_ALL);
  1606. }
  1607. /*
  1608. =======================================================================================================================
  1609. Select_Invert
  1610. =======================================================================================================================
  1611. */
  1612. void Select_Invert(void) {
  1613. brush_t *next, *prev;
  1614. Sys_Status("inverting selection...\n");
  1615. next = active_brushes.next;
  1616. prev = active_brushes.prev;
  1617. if (selected_brushes.next != &selected_brushes) {
  1618. active_brushes.next = selected_brushes.next;
  1619. active_brushes.prev = selected_brushes.prev;
  1620. active_brushes.next->prev = &active_brushes;
  1621. active_brushes.prev->next = &active_brushes;
  1622. }
  1623. else {
  1624. active_brushes.next = &active_brushes;
  1625. active_brushes.prev = &active_brushes;
  1626. }
  1627. if (next != &active_brushes) {
  1628. selected_brushes.next = next;
  1629. selected_brushes.prev = prev;
  1630. selected_brushes.next->prev = &selected_brushes;
  1631. selected_brushes.prev->next = &selected_brushes;
  1632. }
  1633. else {
  1634. selected_brushes.next = &selected_brushes;
  1635. selected_brushes.prev = &selected_brushes;
  1636. }
  1637. Sys_UpdateWindows(W_ALL);
  1638. Sys_Status("done.\n");
  1639. }
  1640. /*
  1641. =======================================================================================================================
  1642. Select_Name
  1643. =======================================================================================================================
  1644. */
  1645. void Select_Name(const char *pName) {
  1646. if (g_qeglobals.m_bBrushPrimitMode) {
  1647. for (brush_t * b = selected_brushes.next; b && b != &selected_brushes; b = b->next) {
  1648. Brush_SetEpair(b, "Name", pName);
  1649. }
  1650. }
  1651. }
  1652. /*
  1653. =======================================================================================================================
  1654. =======================================================================================================================
  1655. */
  1656. void Select_CenterOrigin() {
  1657. idVec3 mid;
  1658. Select_GetTrueMid(mid);
  1659. mid.Snap();
  1660. brush_t *b = selected_brushes.next;
  1661. entity_t *e = b->owner;
  1662. if (e != NULL) {
  1663. if (e != world_entity) {
  1664. char text[1024];
  1665. sprintf(text, "%i %i %i", (int)mid[0], (int)mid[1], (int)mid[2]);
  1666. SetKeyValue(e, "origin", text);
  1667. VectorCopy(mid, e->origin);
  1668. }
  1669. }
  1670. Sys_UpdateWindows(W_ALL);
  1671. }
  1672. /*
  1673. =======================================================================================================================
  1674. =======================================================================================================================
  1675. */
  1676. int Select_NumSelectedFaces() {
  1677. return g_ptrSelectedFaces.GetSize();
  1678. }
  1679. /*
  1680. =======================================================================================================================
  1681. =======================================================================================================================
  1682. */
  1683. face_t *Select_GetSelectedFace(int index) {
  1684. assert(index >= 0 && index < Select_NumSelectedFaces());
  1685. return reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(index));
  1686. }
  1687. /*
  1688. =======================================================================================================================
  1689. =======================================================================================================================
  1690. */
  1691. brush_t *Select_GetSelectedFaceBrush(int index) {
  1692. assert(index >= 0 && index < Select_NumSelectedFaces());
  1693. return reinterpret_cast < brush_t * > (g_ptrSelectedFaceBrushes.GetAt(index));
  1694. }
  1695. /*
  1696. =======================================================================================================================
  1697. =======================================================================================================================
  1698. */
  1699. void Select_SetDefaultTexture(const idMaterial *mat, bool fitScale, bool setTexture) {
  1700. texdef_t tex;
  1701. brushprimit_texdef_t brushprimit_tex;
  1702. memset(&tex, 0, sizeof(tex));
  1703. memset(&brushprimit_tex, 0, sizeof(brushprimit_tex));
  1704. if (g_qeglobals.m_bBrushPrimitMode) {
  1705. // brushprimit fitted to a 2x2 texture
  1706. brushprimit_tex.coords[0][0] = 1.0f;
  1707. brushprimit_tex.coords[1][1] = 1.0f;
  1708. }
  1709. else {
  1710. tex.scale[0] = (g_PrefsDlg.m_bHiColorTextures) ? 0.5 : 1;
  1711. tex.scale[1] = (g_PrefsDlg.m_bHiColorTextures) ? 0.5 : 1;
  1712. }
  1713. tex.SetName(mat->GetName());
  1714. Texture_SetTexture(&tex, &brushprimit_tex, fitScale, setTexture);
  1715. CString strTex;
  1716. strTex.Format
  1717. (
  1718. "%s (%s) W: %i H: %i",
  1719. mat->GetName(),
  1720. mat->GetDescription(),
  1721. mat->GetEditorImage()->uploadWidth,
  1722. mat->GetEditorImage()->uploadHeight
  1723. );
  1724. g_pParentWnd->SetStatusText(3, strTex);
  1725. }
  1726. void Select_UpdateTextureName(const char *name) {
  1727. brush_t *b;
  1728. int nCount = g_ptrSelectedFaces.GetSize();
  1729. if (nCount > 0) {
  1730. Undo_Start("set face texture name");
  1731. ASSERT(g_ptrSelectedFaces.GetSize() == g_ptrSelectedFaceBrushes.GetSize());
  1732. for (int i = 0; i < nCount; i++) {
  1733. face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(i));
  1734. brush_t *selBrush = reinterpret_cast < brush_t * > (g_ptrSelectedFaceBrushes.GetAt(i));
  1735. Undo_AddBrush(selBrush);
  1736. selFace->texdef.SetName(name);
  1737. Brush_Build(selBrush);
  1738. Undo_EndBrush(selBrush);
  1739. }
  1740. Undo_End();
  1741. }
  1742. else if (selected_brushes.next != &selected_brushes) {
  1743. Undo_Start("set brush textures");
  1744. for (b = selected_brushes.next; b != &selected_brushes; b = b->next) {
  1745. if (!b->owner->eclass->fixedsize) {
  1746. Undo_AddBrush(b);
  1747. Brush_SetTextureName(b, name);
  1748. Undo_EndBrush(b);
  1749. } else if (b->owner->eclass->nShowFlags & ECLASS_LIGHT) {
  1750. if ( idStr::Cmpn(name, "lights/", strlen("lights/")) == 0 ) {
  1751. SetKeyValue(b->owner, "texture", name);
  1752. g_Inspectors->UpdateEntitySel(b->owner->eclass);
  1753. UpdateLightInspector();
  1754. Brush_Build(b);
  1755. }
  1756. }
  1757. }
  1758. Undo_End();
  1759. }
  1760. Sys_UpdateWindows(W_ALL);
  1761. }
  1762. /*
  1763. =======================================================================================================================
  1764. =======================================================================================================================
  1765. */
  1766. void Select_FlipTexture(bool y) {
  1767. int faceCount = g_ptrSelectedFaces.GetSize();
  1768. Undo_Start("Select_FlipTexture");
  1769. for (brush_t *b = selected_brushes.next; b != &selected_brushes; b = b->next) {
  1770. if (b->pPatch) {
  1771. Patch_FlipTexture(b->pPatch, y);
  1772. } else {
  1773. Brush_FlipTexture_BrushPrimit(b, y);
  1774. }
  1775. }
  1776. if (faceCount > 0) {
  1777. for (int i = 0; i < faceCount; i++) {
  1778. face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(i));
  1779. brush_t *selBrush = reinterpret_cast < brush_t * > (g_ptrSelectedFaceBrushes.GetAt(i));
  1780. Face_FlipTexture_BrushPrimit(selFace, y);
  1781. }
  1782. }
  1783. Undo_End();
  1784. Sys_UpdateWindows(W_CAMERA);
  1785. }
  1786. /*
  1787. =======================================================================================================================
  1788. Select_SetKeyVal
  1789. sets values on non-world entities
  1790. =======================================================================================================================
  1791. */
  1792. void Select_SetKeyVal(const char *key, const char *val) {
  1793. for (brush_t * b = selected_brushes.next; b && b != &selected_brushes; b = b->next) {
  1794. if (b->owner != world_entity) {
  1795. SetKeyValue(b->owner, key, val, false);
  1796. }
  1797. }
  1798. }
  1799. /*
  1800. =======================================================================================================================
  1801. Select_CopyPatchTextureCoords( patchMesh_t *p )
  1802. =======================================================================================================================
  1803. */
  1804. void Select_CopyPatchTextureCoords( patchMesh_t *p ) {
  1805. for (brush_t * b = selected_brushes.next; b && b != &selected_brushes; b = b->next) {
  1806. if (b->pPatch) {
  1807. if ( b->pPatch->width <= p->width && b->pPatch->height <= p->height ) {
  1808. for ( int i = 0; i < b->pPatch->width; i ++ ) {
  1809. for ( int j = 0; j < b->pPatch->height; j++ ) {
  1810. b->pPatch->ctrl(i, j).st = p->ctrl(i, j).st;
  1811. }
  1812. }
  1813. }
  1814. }
  1815. }
  1816. }
  1817. /*
  1818. =======================================================================================================================
  1819. Select_SetProjectFaceOntoPatch
  1820. =======================================================================================================================
  1821. */
  1822. void Select_ProjectFaceOntoPatch( face_t *face ) {
  1823. for (brush_t * b = selected_brushes.next; b && b != &selected_brushes; b = b->next) {
  1824. if (b->pPatch) {
  1825. EmitBrushPrimitTextureCoordinates(face, NULL, b->pPatch);
  1826. Patch_MakeDirty(b->pPatch);
  1827. }
  1828. }
  1829. }
  1830. /*
  1831. =======================================================================================================================
  1832. Select_SetPatchFit
  1833. =======================================================================================================================
  1834. */
  1835. extern float Patch_Width(patchMesh_t *p);
  1836. extern float Patch_Height(patchMesh_t *p);
  1837. void Select_SetPatchFit(float dim1, float dim2, float srcWidth, float srcHeight, float rot) {
  1838. for (brush_t * b = selected_brushes.next; b && b != &selected_brushes; b = b->next) {
  1839. if (b->pPatch) {
  1840. float w = Patch_Width(b->pPatch);
  1841. float h = Patch_Height(b->pPatch);
  1842. Patch_RotateTexture(b->pPatch, -90 + rot);
  1843. Patch_FitTexture(b->pPatch, dim1 * (w / srcWidth), dim2 * (h / srcHeight));
  1844. Patch_FlipTexture(b->pPatch, true);
  1845. }
  1846. }
  1847. }
  1848. void Select_SetPatchST(float s1, float t1, float s2, float t2) {
  1849. }
  1850. void Select_AllTargets() {
  1851. for (brush_t * b = selected_brushes.next; b && b != &selected_brushes; b = b->next) {
  1852. if (b->owner != world_entity) {
  1853. const idKeyValue *kv = b->owner->epairs.MatchPrefix("target", NULL);
  1854. while (kv) {
  1855. entity_t *ent = FindEntity("name", kv->GetValue());
  1856. if (ent) {
  1857. Select_Brush(ent->brushes.onext, true, false);
  1858. }
  1859. kv = b->owner->epairs.MatchPrefix("target", kv);
  1860. }
  1861. }
  1862. }
  1863. }