xy.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1997-2006 Id Software, Inc.
  4. This file is part of Quake 2 Tools source code.
  5. Quake 2 Tools 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 2 Tools 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 Quake 2 Tools source code; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. #include "qe3.h"
  19. #define PAGEFLIPS 2
  20. /*
  21. ============
  22. XY_Init
  23. ============
  24. */
  25. void XY_Init (void)
  26. {
  27. g_qeglobals.d_xy.origin[0] = 0;
  28. g_qeglobals.d_xy.origin[1] = 20;
  29. g_qeglobals.d_xy.origin[2] = 46;
  30. g_qeglobals.d_xy.scale = 1;
  31. }
  32. /*
  33. ============================================================================
  34. MOUSE ACTIONS
  35. ============================================================================
  36. */
  37. static int cursorx, cursory;
  38. static int buttonstate;
  39. static int pressx, pressy;
  40. static vec3_t pressdelta;
  41. static qboolean press_selection;
  42. void XY_ToPoint (int x, int y, vec3_t point)
  43. {
  44. point[0] = g_qeglobals.d_xy.origin[0] + (x - g_qeglobals.d_xy.width/2)/g_qeglobals.d_xy.scale;
  45. point[1] = g_qeglobals.d_xy.origin[1] + (y - g_qeglobals.d_xy.height/2)/g_qeglobals.d_xy.scale;
  46. point[2] = 0;
  47. }
  48. void XY_ToGridPoint (int x, int y, vec3_t point)
  49. {
  50. point[0] = g_qeglobals.d_xy.origin[0] + (x - g_qeglobals.d_xy.width/2)/g_qeglobals.d_xy.scale;
  51. point[1] = g_qeglobals.d_xy.origin[1] + (y - g_qeglobals.d_xy.height/2)/g_qeglobals.d_xy.scale;
  52. point[2] = 0;
  53. point[0] = floor(point[0]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
  54. point[1] = floor(point[1]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
  55. }
  56. /*
  57. ==============
  58. XY_MouseDown
  59. ==============
  60. */
  61. void XY_MouseDown (int x, int y, int buttons)
  62. {
  63. vec3_t point;
  64. vec3_t origin, dir, right, up;
  65. buttonstate = buttons;
  66. pressx = x;
  67. pressy = y;
  68. VectorCopy (vec3_origin, pressdelta);
  69. XY_ToPoint (x, y, point);
  70. VectorCopy (point, origin);
  71. origin[2] = 8192;
  72. dir[0] = 0; dir[1] = 0; dir[2] = -1;
  73. right[0] = 1/g_qeglobals.d_xy.scale; right[1] = 0; right[2] = 0;
  74. up[0] = 0; up[1] = 1/g_qeglobals.d_xy.scale; up[2] = 0;
  75. press_selection = (selected_brushes.next != &selected_brushes);
  76. Sys_GetCursorPos (&cursorx, &cursory);
  77. // lbutton = manipulate selection
  78. // shift-LBUTTON = select
  79. if ( (buttons == MK_LBUTTON)
  80. || (buttons == (MK_LBUTTON | MK_SHIFT))
  81. || (buttons == (MK_LBUTTON | MK_CONTROL))
  82. || (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT)) )
  83. {
  84. Drag_Begin (x, y, buttons,
  85. right, up,
  86. origin, dir);
  87. return;
  88. }
  89. // control mbutton = move camera
  90. if (buttonstate == (MK_CONTROL|MK_MBUTTON) )
  91. {
  92. camera.origin[0] = point[0];
  93. camera.origin[1] = point[1];
  94. Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY);
  95. }
  96. // mbutton = angle camera
  97. if (buttonstate == MK_MBUTTON)
  98. {
  99. VectorSubtract (point, camera.origin, point);
  100. if (point[1] || point[0])
  101. {
  102. camera.angles[YAW] = 180/Q_PI*atan2 (point[1], point[0]);
  103. Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY);
  104. }
  105. }
  106. // shift mbutton = move z checker
  107. if (buttonstate == (MK_SHIFT|MK_MBUTTON) )
  108. {
  109. XY_ToPoint (x, y, point);
  110. z.origin[0] = point[0];
  111. z.origin[1] = point[1];
  112. Sys_UpdateWindows (W_XY_OVERLAY|W_Z);
  113. return;
  114. }
  115. }
  116. /*
  117. ==============
  118. XY_MouseUp
  119. ==============
  120. */
  121. void XY_MouseUp (int x, int y, int buttons)
  122. {
  123. Drag_MouseUp ();
  124. if (!press_selection)
  125. Sys_UpdateWindows (W_ALL);
  126. buttonstate = 0;
  127. }
  128. qboolean DragDelta (int x, int y, vec3_t move)
  129. {
  130. vec3_t xvec, yvec, delta;
  131. int i;
  132. xvec[0] = 1/g_qeglobals.d_xy.scale;
  133. xvec[1] = xvec[2] = 0;
  134. yvec[1] = 1/g_qeglobals.d_xy.scale;
  135. yvec[0] = yvec[2] = 0;
  136. for (i=0 ; i<3 ; i++)
  137. {
  138. delta[i] = xvec[i]*(x - pressx) + yvec[i]*(y - pressy);
  139. delta[i] = floor(delta[i]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
  140. }
  141. VectorSubtract (delta, pressdelta, move);
  142. VectorCopy (delta, pressdelta);
  143. if (move[0] || move[1] || move[2])
  144. return true;
  145. return false;
  146. }
  147. /*
  148. ==============
  149. NewBrushDrag
  150. ==============
  151. */
  152. void NewBrushDrag (int x, int y)
  153. {
  154. vec3_t mins, maxs, junk;
  155. int i;
  156. float temp;
  157. brush_t *n;
  158. if (!DragDelta (x,y, junk))
  159. return;
  160. // delete the current selection
  161. if (selected_brushes.next != &selected_brushes)
  162. Brush_Free (selected_brushes.next);
  163. XY_ToGridPoint (pressx, pressy, mins);
  164. mins[2] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_bottom_z/g_qeglobals.d_gridsize));
  165. XY_ToGridPoint (x, y, maxs);
  166. maxs[2] = g_qeglobals.d_gridsize * ((int)(g_qeglobals.d_new_brush_top_z/g_qeglobals.d_gridsize));
  167. if (maxs[2] <= mins[2])
  168. maxs[2] = mins[2] + g_qeglobals.d_gridsize;
  169. for (i=0 ; i<3 ; i++)
  170. {
  171. if (mins[i] == maxs[i])
  172. return; // don't create a degenerate brush
  173. if (mins[i] > maxs[i])
  174. {
  175. temp = mins[i];
  176. mins[i] = maxs[i];
  177. maxs[i] = temp;
  178. }
  179. }
  180. n = Brush_Create (mins, maxs, &g_qeglobals.d_texturewin.texdef);
  181. if (!n)
  182. return;
  183. Brush_AddToList (n, &selected_brushes);
  184. Entity_LinkBrush (world_entity, n);
  185. Brush_Build( n );
  186. // Sys_UpdateWindows (W_ALL);
  187. Sys_UpdateWindows (W_XY| W_CAMERA);
  188. }
  189. /*
  190. ==============
  191. XY_MouseMoved
  192. ==============
  193. */
  194. void XY_MouseMoved (int x, int y, int buttons)
  195. {
  196. vec3_t point;
  197. if (!buttonstate)
  198. return;
  199. // lbutton without selection = drag new brush
  200. if (buttonstate == MK_LBUTTON && !press_selection)
  201. {
  202. NewBrushDrag (x, y);
  203. return;
  204. }
  205. // lbutton (possibly with control and or shift)
  206. // with selection = drag selection
  207. if (buttonstate & MK_LBUTTON)
  208. {
  209. Drag_MouseMoved (x, y, buttons);
  210. Sys_UpdateWindows (W_XY_OVERLAY | W_CAMERA);
  211. return;
  212. }
  213. // control mbutton = move camera
  214. if (buttonstate == (MK_CONTROL|MK_MBUTTON) )
  215. {
  216. XY_ToPoint (x, y, point);
  217. camera.origin[0] = point[0];
  218. camera.origin[1] = point[1];
  219. Sys_UpdateWindows (W_XY_OVERLAY | W_CAMERA);
  220. return;
  221. }
  222. // shift mbutton = move z checker
  223. if (buttonstate == (MK_SHIFT|MK_MBUTTON) )
  224. {
  225. XY_ToPoint (x, y, point);
  226. z.origin[0] = point[0];
  227. z.origin[1] = point[1];
  228. Sys_UpdateWindows (W_XY_OVERLAY|W_Z);
  229. return;
  230. }
  231. // mbutton = angle camera
  232. if (buttonstate == MK_MBUTTON )
  233. {
  234. XY_ToPoint (x, y, point);
  235. VectorSubtract (point, camera.origin, point);
  236. if (point[1] || point[0])
  237. {
  238. camera.angles[YAW] = 180/Q_PI*atan2 (point[1], point[0]);
  239. Sys_UpdateWindows (W_XY_OVERLAY | W_CAMERA);
  240. }
  241. return;
  242. }
  243. // rbutton = drag xy origin
  244. if (buttonstate == MK_RBUTTON)
  245. {
  246. Sys_GetCursorPos (&x, &y);
  247. if (x != cursorx || y != cursory)
  248. {
  249. g_qeglobals.d_xy.origin[0] -= (x-cursorx)/g_qeglobals.d_xy.scale;
  250. g_qeglobals.d_xy.origin[1] += (y-cursory)/g_qeglobals.d_xy.scale;
  251. Sys_SetCursorPos (cursorx, cursory);
  252. Sys_UpdateWindows (W_XY | W_XY_OVERLAY);
  253. }
  254. return;
  255. }
  256. }
  257. /*
  258. ============================================================================
  259. DRAWING
  260. ============================================================================
  261. */
  262. /*
  263. ==============
  264. XY_DrawGrid
  265. ==============
  266. */
  267. void XY_DrawGrid (void)
  268. {
  269. float x, y, xb, xe, yb, ye;
  270. int w, h;
  271. char text[32];
  272. glDisable(GL_TEXTURE_2D);
  273. glDisable(GL_TEXTURE_1D);
  274. glDisable(GL_DEPTH_TEST);
  275. glDisable(GL_BLEND);
  276. w = g_qeglobals.d_xy.width/2 / g_qeglobals.d_xy.scale;
  277. h = g_qeglobals.d_xy.height/2 / g_qeglobals.d_xy.scale;
  278. xb = g_qeglobals.d_xy.origin[0] - w;
  279. if (xb < region_mins[0])
  280. xb = region_mins[0];
  281. xb = 64 * floor (xb/64);
  282. xe = g_qeglobals.d_xy.origin[0] + w;
  283. if (xe > region_maxs[0])
  284. xe = region_maxs[0];
  285. xe = 64 * ceil (xe/64);
  286. yb = g_qeglobals.d_xy.origin[1] - h;
  287. if (yb < region_mins[1])
  288. yb = region_mins[1];
  289. yb = 64 * floor (yb/64);
  290. ye = g_qeglobals.d_xy.origin[1] + h;
  291. if (ye > region_maxs[1])
  292. ye = region_maxs[1];
  293. ye = 64 * ceil (ye/64);
  294. // draw major blocks
  295. glColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR]);
  296. if ( g_qeglobals.d_showgrid )
  297. {
  298. glBegin (GL_LINES);
  299. for (x=xb ; x<=xe ; x+=64)
  300. {
  301. glVertex2f (x, yb);
  302. glVertex2f (x, ye);
  303. }
  304. for (y=yb ; y<=ye ; y+=64)
  305. {
  306. glVertex2f (xb, y);
  307. glVertex2f (xe, y);
  308. }
  309. glEnd ();
  310. }
  311. // draw minor blocks
  312. if ( g_qeglobals.d_showgrid && g_qeglobals.d_gridsize*g_qeglobals.d_xy.scale >= 4)
  313. {
  314. glColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR]);
  315. glBegin (GL_LINES);
  316. for (x=xb ; x<xe ; x += g_qeglobals.d_gridsize)
  317. {
  318. if ( ! ((int)x & 63) )
  319. continue;
  320. glVertex2f (x, yb);
  321. glVertex2f (x, ye);
  322. }
  323. for (y=yb ; y<ye ; y+=g_qeglobals.d_gridsize)
  324. {
  325. if ( ! ((int)y & 63) )
  326. continue;
  327. glVertex2f (xb, y);
  328. glVertex2f (xe, y);
  329. }
  330. glEnd ();
  331. }
  332. // draw coordinate text if needed
  333. if ( g_qeglobals.d_savedinfo.show_coordinates)
  334. {
  335. glColor4f(0, 0, 0, 0);
  336. for (x=xb ; x<xe ; x+=64)
  337. {
  338. glRasterPos2f (x, g_qeglobals.d_xy.origin[1] + h - 6/g_qeglobals.d_xy.scale);
  339. sprintf (text, "%i",(int)x);
  340. glCallLists (strlen(text), GL_UNSIGNED_BYTE, text);
  341. }
  342. for (y=yb ; y<ye ; y+=64)
  343. {
  344. glRasterPos2f (g_qeglobals.d_xy.origin[0] - w + 1, y);
  345. sprintf (text, "%i",(int)y);
  346. glCallLists (strlen(text), GL_UNSIGNED_BYTE, text);
  347. }
  348. }
  349. }
  350. /*
  351. ==============
  352. XY_DrawBlockGrid
  353. ==============
  354. */
  355. void XY_DrawBlockGrid (void)
  356. {
  357. float x, y, xb, xe, yb, ye;
  358. int w, h;
  359. char text[32];
  360. glDisable(GL_TEXTURE_2D);
  361. glDisable(GL_TEXTURE_1D);
  362. glDisable(GL_DEPTH_TEST);
  363. glDisable(GL_BLEND);
  364. w = g_qeglobals.d_xy.width/2 / g_qeglobals.d_xy.scale;
  365. h = g_qeglobals.d_xy.height/2 / g_qeglobals.d_xy.scale;
  366. xb = g_qeglobals.d_xy.origin[0] - w;
  367. if (xb < region_mins[0])
  368. xb = region_mins[0];
  369. xb = 1024 * floor (xb/1024);
  370. xe = g_qeglobals.d_xy.origin[0] + w;
  371. if (xe > region_maxs[0])
  372. xe = region_maxs[0];
  373. xe = 1024 * ceil (xe/1024);
  374. yb = g_qeglobals.d_xy.origin[1] - h;
  375. if (yb < region_mins[1])
  376. yb = region_mins[1];
  377. yb = 1024 * floor (yb/1024);
  378. ye = g_qeglobals.d_xy.origin[1] + h;
  379. if (ye > region_maxs[1])
  380. ye = region_maxs[1];
  381. ye = 1024 * ceil (ye/1024);
  382. // draw major blocks
  383. glColor3f(0,0,1);
  384. glLineWidth (2);
  385. glBegin (GL_LINES);
  386. for (x=xb ; x<=xe ; x+=1024)
  387. {
  388. glVertex2f (x, yb);
  389. glVertex2f (x, ye);
  390. }
  391. for (y=yb ; y<=ye ; y+=1024)
  392. {
  393. glVertex2f (xb, y);
  394. glVertex2f (xe, y);
  395. }
  396. glEnd ();
  397. glLineWidth (1);
  398. // draw coordinate text if needed
  399. for (x=xb ; x<xe ; x+=1024)
  400. for (y=yb ; y<ye ; y+=1024)
  401. {
  402. glRasterPos2f (x+512, y+512);
  403. sprintf (text, "%i,%i",(int)floor(x/1024), (int)floor(y/1024) );
  404. glCallLists (strlen(text), GL_UNSIGNED_BYTE, text);
  405. }
  406. glColor4f(0, 0, 0, 0);
  407. }
  408. void DrawCameraIcon (void)
  409. {
  410. float x, y, a;
  411. x = camera.origin[0];
  412. y = camera.origin[1];
  413. a = camera.angles[YAW]/180*Q_PI;
  414. glColor3f (0.0, 0.0, 1.0);
  415. glBegin(GL_LINE_STRIP);
  416. glVertex3f (x-16,y,0);
  417. glVertex3f (x,y+8,0);
  418. glVertex3f (x+16,y,0);
  419. glVertex3f (x,y-8,0);
  420. glVertex3f (x-16,y,0);
  421. glVertex3f (x+16,y,0);
  422. glEnd ();
  423. glBegin(GL_LINE_STRIP);
  424. glVertex3f (x+48*cos(a+Q_PI/4), y+48*sin(a+Q_PI/4), 0);
  425. glVertex3f (x, y, 0);
  426. glVertex3f (x+48*cos(a-Q_PI/4), y+48*sin(a-Q_PI/4), 0);
  427. glEnd ();
  428. }
  429. void DrawZIcon (void)
  430. {
  431. float x, y;
  432. x = z.origin[0];
  433. y = z.origin[1];
  434. glEnable (GL_BLEND);
  435. glDisable (GL_TEXTURE_2D);
  436. glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
  437. glDisable (GL_CULL_FACE);
  438. glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  439. glColor4f (0.0, 0.0, 1.0, 0.25);
  440. glBegin(GL_QUADS);
  441. glVertex3f (x-8,y-8,0);
  442. glVertex3f (x+8,y-8,0);
  443. glVertex3f (x+8,y+8,0);
  444. glVertex3f (x-8,y+8,0);
  445. glEnd ();
  446. glDisable (GL_BLEND);
  447. glColor4f (0.0, 0.0, 1.0, 1);
  448. glBegin(GL_LINE_LOOP);
  449. glVertex3f (x-8,y-8,0);
  450. glVertex3f (x+8,y-8,0);
  451. glVertex3f (x+8,y+8,0);
  452. glVertex3f (x-8,y+8,0);
  453. glEnd ();
  454. glBegin(GL_LINE_STRIP);
  455. glVertex3f (x-4,y+4,0);
  456. glVertex3f (x+4,y+4,0);
  457. glVertex3f (x-4,y-4,0);
  458. glVertex3f (x+4,y-4,0);
  459. glEnd ();
  460. }
  461. /*
  462. ==================
  463. FilterBrush
  464. ==================
  465. */
  466. BOOL FilterBrush(brush_t *pb)
  467. {
  468. if (!pb->owner)
  469. return FALSE; // during construction
  470. if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CLIP)
  471. {
  472. if (!strncmp(pb->brush_faces->texdef.name, "clip", 4))
  473. return TRUE;
  474. }
  475. if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_WATER)
  476. {
  477. if (pb->brush_faces->texdef.name[0] == '*')
  478. return TRUE;
  479. }
  480. if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_DETAIL)
  481. {
  482. if (pb->brush_faces->texdef.contents & CONTENTS_DETAIL)
  483. return TRUE;
  484. }
  485. if (pb->owner == world_entity)
  486. {
  487. if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_WORLD)
  488. return TRUE;
  489. return FALSE;
  490. }
  491. else if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_ENT)
  492. return TRUE;
  493. if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_LIGHTS)
  494. {
  495. if (!strncmp(pb->owner->eclass->name, "light", 5))
  496. return TRUE;
  497. }
  498. if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_PATHS)
  499. {
  500. if (!strncmp(pb->owner->eclass->name, "path", 4))
  501. return TRUE;
  502. }
  503. return FALSE;
  504. }
  505. /*
  506. =============================================================
  507. PATH LINES
  508. =============================================================
  509. */
  510. /*
  511. ==================
  512. DrawPathLines
  513. Draws connections between entities.
  514. Needs to consider all entities, not just ones on screen,
  515. because the lines can be visible when neither end is.
  516. Called for both camera view and xy view.
  517. ==================
  518. */
  519. void DrawPathLines (void)
  520. {
  521. int i, j, k;
  522. vec3_t mid, mid1;
  523. entity_t *se, *te;
  524. brush_t *sb, *tb;
  525. char *psz;
  526. vec3_t dir, s1, s2;
  527. vec_t len, f;
  528. int arrows;
  529. int num_entities;
  530. char *ent_target[MAX_MAP_ENTITIES];
  531. entity_t *ent_entity[MAX_MAP_ENTITIES];
  532. num_entities = 0;
  533. for (te = entities.next ; te != &entities && num_entities != MAX_MAP_ENTITIES ; te = te->next)
  534. {
  535. ent_target[num_entities] = ValueForKey (te, "target");
  536. if (ent_target[num_entities][0])
  537. {
  538. ent_entity[num_entities] = te;
  539. num_entities++;
  540. }
  541. }
  542. for (se = entities.next ; se != &entities ; se = se->next)
  543. {
  544. psz = ValueForKey(se, "targetname");
  545. if (psz == NULL || psz[0] == '\0')
  546. continue;
  547. sb = se->brushes.onext;
  548. if (sb == &se->brushes)
  549. continue;
  550. for (k=0 ; k<num_entities ; k++)
  551. {
  552. if (strcmp (ent_target[k], psz))
  553. continue;
  554. te = ent_entity[k];
  555. tb = te->brushes.onext;
  556. if (tb == &te->brushes)
  557. continue;
  558. for (i=0 ; i<3 ; i++)
  559. mid[i] = (sb->mins[i] + sb->maxs[i])*0.5;
  560. for (i=0 ; i<3 ; i++)
  561. mid1[i] = (tb->mins[i] + tb->maxs[i])*0.5;
  562. VectorSubtract (mid1, mid, dir);
  563. len = VectorNormalize (dir);
  564. s1[0] = -dir[1]*8 + dir[0]*8;
  565. s2[0] = dir[1]*8 + dir[0]*8;
  566. s1[1] = dir[0]*8 + dir[1]*8;
  567. s2[1] = -dir[0]*8 + dir[1]*8;
  568. glColor3f (se->eclass->color[0], se->eclass->color[1], se->eclass->color[2]);
  569. glBegin(GL_LINES);
  570. glVertex3fv(mid);
  571. glVertex3fv(mid1);
  572. arrows = (int)(len / 256) + 1;
  573. for (i=0 ; i<arrows ; i++)
  574. {
  575. f = len * (i + 0.5) / arrows;
  576. for (j=0 ; j<3 ; j++)
  577. mid1[j] = mid[j] + f*dir[j];
  578. glVertex3fv (mid1);
  579. glVertex3f (mid1[0] + s1[0], mid1[1] + s1[1], mid1[2]);
  580. glVertex3fv (mid1);
  581. glVertex3f (mid1[0] + s2[0], mid1[1] + s2[1], mid1[2]);
  582. }
  583. glEnd();
  584. }
  585. }
  586. return;
  587. }
  588. //=============================================================
  589. /*
  590. ==============
  591. XY_Draw
  592. ==============
  593. */
  594. void XY_Draw (void)
  595. {
  596. brush_t *brush;
  597. float w, h;
  598. entity_t *e;
  599. double start, end;
  600. vec3_t mins, maxs;
  601. int drawn, culled;
  602. int i;
  603. if (!active_brushes.next)
  604. return; // not valid yet
  605. if (g_qeglobals.d_xy.timing)
  606. start = Sys_DoubleTime ();
  607. //
  608. // clear
  609. //
  610. g_qeglobals.d_xy.d_dirty = false;
  611. glViewport(0, 0, g_qeglobals.d_xy.width, g_qeglobals.d_xy.height);
  612. glClearColor (
  613. g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][0],
  614. g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][1],
  615. g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][2],
  616. 0);
  617. glClear(GL_COLOR_BUFFER_BIT);
  618. //
  619. // set up viewpoint
  620. //
  621. glMatrixMode(GL_PROJECTION);
  622. glLoadIdentity ();
  623. w = g_qeglobals.d_xy.width/2 / g_qeglobals.d_xy.scale;
  624. h = g_qeglobals.d_xy.height/2 / g_qeglobals.d_xy.scale;
  625. mins[0] = g_qeglobals.d_xy.origin[0] - w;
  626. maxs[0] = g_qeglobals.d_xy.origin[0] + w;
  627. mins[1] = g_qeglobals.d_xy.origin[1] - h;
  628. maxs[1] = g_qeglobals.d_xy.origin[1] + h;
  629. glOrtho (mins[0], maxs[0], mins[1], maxs[1], -8000, 8000);
  630. //
  631. // now draw the grid
  632. //
  633. XY_DrawGrid ();
  634. //
  635. // draw stuff
  636. //
  637. glShadeModel (GL_FLAT);
  638. glDisable(GL_TEXTURE_2D);
  639. glDisable(GL_TEXTURE_1D);
  640. glDisable(GL_DEPTH_TEST);
  641. glDisable(GL_BLEND);
  642. glColor3f(0, 0, 0);
  643. // glEnable (GL_LINE_SMOOTH);
  644. drawn = culled = 0;
  645. e = NULL;
  646. for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next)
  647. {
  648. if (brush->mins[0] > maxs[0]
  649. || brush->mins[1] > maxs[1]
  650. || brush->maxs[0] < mins[0]
  651. || brush->maxs[1] < mins[1] )
  652. {
  653. culled++;
  654. continue; // off screen
  655. }
  656. if (FilterBrush (brush))
  657. continue;
  658. drawn++;
  659. if (brush->owner != e)
  660. {
  661. e = brush->owner;
  662. glColor3fv(e->eclass->color);
  663. }
  664. Brush_DrawXY( brush );
  665. }
  666. DrawPathLines ();
  667. //
  668. // draw pointfile
  669. //
  670. if ( g_qeglobals.d_pointfile_display_list)
  671. glCallList (g_qeglobals.d_pointfile_display_list);
  672. //
  673. // draw block grid
  674. //
  675. if ( g_qeglobals.show_blocks)
  676. XY_DrawBlockGrid ();
  677. //
  678. // now draw selected brushes
  679. //
  680. glTranslatef( g_qeglobals.d_select_translate[0], g_qeglobals.d_select_translate[1], g_qeglobals.d_select_translate[2]);
  681. glColor3f(1.0, 0.0, 0.0);
  682. glEnable (GL_LINE_STIPPLE);
  683. glLineStipple (3, 0xaaaa);
  684. glLineWidth (2);
  685. for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next)
  686. {
  687. drawn++;
  688. Brush_DrawXY( brush );
  689. }
  690. glDisable (GL_LINE_STIPPLE);
  691. glLineWidth (1);
  692. // edge / vertex flags
  693. if (g_qeglobals.d_select_mode == sel_vertex)
  694. {
  695. glPointSize (4);
  696. glColor3f (0,1,0);
  697. glBegin (GL_POINTS);
  698. for (i=0 ; i<g_qeglobals.d_numpoints ; i++)
  699. glVertex3fv (g_qeglobals.d_points[i]);
  700. glEnd ();
  701. glPointSize (1);
  702. }
  703. else if (g_qeglobals.d_select_mode == sel_edge)
  704. {
  705. float *v1, *v2;
  706. glPointSize (4);
  707. glColor3f (0,0,1);
  708. glBegin (GL_POINTS);
  709. for (i=0 ; i<g_qeglobals.d_numedges ; i++)
  710. {
  711. v1 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p1];
  712. v2 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p2];
  713. glVertex3f ( (v1[0]+v2[0])*0.5,(v1[1]+v2[1])*0.5,(v1[2]+v2[2])*0.5);
  714. }
  715. glEnd ();
  716. glPointSize (1);
  717. }
  718. glTranslatef (-g_qeglobals.d_select_translate[0], -g_qeglobals.d_select_translate[1], -g_qeglobals.d_select_translate[2]);
  719. //
  720. // now draw camera point
  721. //
  722. DrawCameraIcon ();
  723. DrawZIcon ();
  724. glFinish();
  725. QE_CheckOpenGLForErrors();
  726. if (g_qeglobals.d_xy.timing)
  727. {
  728. end = Sys_DoubleTime ();
  729. Sys_Printf ("xy: %i ms\n", (int)(1000*(end-start)));
  730. }
  731. }
  732. /*
  733. ==============
  734. XY_Overlay
  735. ==============
  736. */
  737. void XY_Overlay (void)
  738. {
  739. int w, h;
  740. int r[4];
  741. static vec3_t lastz;
  742. static vec3_t lastcamera;
  743. glViewport(0, 0, g_qeglobals.d_xy.width, g_qeglobals.d_xy.height);
  744. //
  745. // set up viewpoint
  746. //
  747. glMatrixMode(GL_PROJECTION);
  748. glLoadIdentity ();
  749. w = g_qeglobals.d_xy.width/2 / g_qeglobals.d_xy.scale;
  750. h = g_qeglobals.d_xy.height/2 / g_qeglobals.d_xy.scale;
  751. glOrtho (g_qeglobals.d_xy.origin[0] - w, g_qeglobals.d_xy.origin[0] + w
  752. , g_qeglobals.d_xy.origin[1] - h, g_qeglobals.d_xy.origin[1] + h, -8000, 8000);
  753. //
  754. // erase the old camera and z checker positions
  755. // if the entire xy hasn't been redrawn
  756. //
  757. if (g_qeglobals.d_xy.d_dirty)
  758. {
  759. glReadBuffer (GL_BACK);
  760. glDrawBuffer (GL_FRONT);
  761. glRasterPos2f (lastz[0]-9, lastz[1]-9);
  762. glGetIntegerv (GL_CURRENT_RASTER_POSITION,r);
  763. glCopyPixels(r[0], r[1], 18,18, GL_COLOR);
  764. glRasterPos2f (lastcamera[0]-50, lastcamera[1]-50);
  765. glGetIntegerv (GL_CURRENT_RASTER_POSITION,r);
  766. glCopyPixels(r[0], r[1], 100,100, GL_COLOR);
  767. }
  768. g_qeglobals.d_xy.d_dirty = true;
  769. //
  770. // save off underneath where we are about to draw
  771. //
  772. VectorCopy (z.origin, lastz);
  773. VectorCopy (camera.origin, lastcamera);
  774. glReadBuffer (GL_FRONT);
  775. glDrawBuffer (GL_BACK);
  776. glRasterPos2f (lastz[0]-9, lastz[1]-9);
  777. glGetIntegerv (GL_CURRENT_RASTER_POSITION,r);
  778. glCopyPixels(r[0], r[1], 18,18, GL_COLOR);
  779. glRasterPos2f (lastcamera[0]-50, lastcamera[1]-50);
  780. glGetIntegerv (GL_CURRENT_RASTER_POSITION,r);
  781. glCopyPixels(r[0], r[1], 100,100, GL_COLOR);
  782. //
  783. // draw the new icons
  784. //
  785. glDrawBuffer (GL_FRONT);
  786. glShadeModel (GL_FLAT);
  787. glDisable(GL_TEXTURE_2D);
  788. glDisable(GL_TEXTURE_1D);
  789. glDisable(GL_DEPTH_TEST);
  790. glDisable(GL_BLEND);
  791. glColor3f(0, 0, 0);
  792. DrawCameraIcon ();
  793. DrawZIcon ();
  794. glDrawBuffer (GL_BACK);
  795. glFinish();
  796. }