PageRenderTime 39ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/llglsandbox.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 880 lines | 586 code | 153 blank | 141 comment | 96 complexity | 091ed1abc0eb1f3b6396391b02715075 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llglsandbox.cpp
  3. * @brief GL functionality access
  4. *
  5. * $LicenseInfo:firstyear=2003&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. /**
  27. * Contains ALL methods which directly access GL functionality
  28. * except for core rendering engine functionality.
  29. */
  30. #include "llviewerprecompiledheaders.h"
  31. #include "llviewercontrol.h"
  32. #include "llgl.h"
  33. #include "llrender.h"
  34. #include "llglheaders.h"
  35. #include "llparcel.h"
  36. #include "llui.h"
  37. #include "lldrawable.h"
  38. #include "lltextureentry.h"
  39. #include "llviewercamera.h"
  40. #include "llvoavatarself.h"
  41. #include "llagent.h"
  42. #include "lltoolmgr.h"
  43. #include "llselectmgr.h"
  44. #include "llhudmanager.h"
  45. #include "llhudtext.h"
  46. #include "llrendersphere.h"
  47. #include "llviewerobjectlist.h"
  48. #include "lltoolselectrect.h"
  49. #include "llviewerwindow.h"
  50. #include "llsurface.h"
  51. #include "llwind.h"
  52. #include "llworld.h"
  53. #include "llviewerparcelmgr.h"
  54. #include "llviewerregion.h"
  55. #include "llpreviewtexture.h"
  56. #include "llresmgr.h"
  57. #include "pipeline.h"
  58. #include "llspatialpartition.h"
  59. // Height of the yellow selection highlight posts for land
  60. const F32 PARCEL_POST_HEIGHT = 0.666f;
  61. // Returns true if you got at least one object
  62. void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
  63. {
  64. LLVector3 av_pos = gAgent.getPositionAgent();
  65. F32 select_dist_squared = gSavedSettings.getF32("MaxSelectDistance");
  66. select_dist_squared = select_dist_squared * select_dist_squared;
  67. BOOL deselect = (mask == MASK_CONTROL);
  68. S32 left = llmin(x, mDragStartX);
  69. S32 right = llmax(x, mDragStartX);
  70. S32 top = llmax(y, mDragStartY);
  71. S32 bottom =llmin(y, mDragStartY);
  72. left = llround((F32) left * LLUI::sGLScaleFactor.mV[VX]);
  73. right = llround((F32) right * LLUI::sGLScaleFactor.mV[VX]);
  74. top = llround((F32) top * LLUI::sGLScaleFactor.mV[VY]);
  75. bottom = llround((F32) bottom * LLUI::sGLScaleFactor.mV[VY]);
  76. F32 old_far_plane = LLViewerCamera::getInstance()->getFar();
  77. F32 old_near_plane = LLViewerCamera::getInstance()->getNear();
  78. S32 width = right - left + 1;
  79. S32 height = top - bottom + 1;
  80. BOOL grow_selection = FALSE;
  81. BOOL shrink_selection = FALSE;
  82. if (height > mDragLastHeight || width > mDragLastWidth)
  83. {
  84. grow_selection = TRUE;
  85. }
  86. if (height < mDragLastHeight || width < mDragLastWidth)
  87. {
  88. shrink_selection = TRUE;
  89. }
  90. if (!grow_selection && !shrink_selection)
  91. {
  92. // nothing to do
  93. return;
  94. }
  95. mDragLastHeight = height;
  96. mDragLastWidth = width;
  97. S32 center_x = (left + right) / 2;
  98. S32 center_y = (top + bottom) / 2;
  99. // save drawing mode
  100. gGL.matrixMode(LLRender::MM_PROJECTION);
  101. gGL.pushMatrix();
  102. BOOL limit_select_distance = gSavedSettings.getBOOL("LimitSelectDistance");
  103. if (limit_select_distance)
  104. {
  105. // ...select distance from control
  106. LLVector3 relative_av_pos = av_pos;
  107. relative_av_pos -= LLViewerCamera::getInstance()->getOrigin();
  108. F32 new_far = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() + gSavedSettings.getF32("MaxSelectDistance");
  109. F32 new_near = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() - gSavedSettings.getF32("MaxSelectDistance");
  110. new_near = llmax(new_near, 0.1f);
  111. LLViewerCamera::getInstance()->setFar(new_far);
  112. LLViewerCamera::getInstance()->setNear(new_near);
  113. }
  114. LLViewerCamera::getInstance()->setPerspective(FOR_SELECTION,
  115. center_x-width/2, center_y-height/2, width, height,
  116. limit_select_distance);
  117. if (shrink_selection)
  118. {
  119. struct f : public LLSelectedObjectFunctor
  120. {
  121. virtual bool apply(LLViewerObject* vobjp)
  122. {
  123. LLDrawable* drawable = vobjp->mDrawable;
  124. if (!drawable || vobjp->getPCode() != LL_PCODE_VOLUME || vobjp->isAttachment())
  125. {
  126. return true;
  127. }
  128. S32 result = LLViewerCamera::getInstance()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius());
  129. switch (result)
  130. {
  131. case 0:
  132. LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp);
  133. break;
  134. case 1:
  135. // check vertices
  136. if (!LLViewerCamera::getInstance()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive))
  137. {
  138. LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp);
  139. }
  140. break;
  141. default:
  142. break;
  143. }
  144. return true;
  145. }
  146. } func;
  147. LLSelectMgr::getInstance()->getHighlightedObjects()->applyToObjects(&func);
  148. }
  149. if (grow_selection)
  150. {
  151. std::vector<LLDrawable*> potentials;
  152. for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
  153. iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
  154. {
  155. LLViewerRegion* region = *iter;
  156. for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
  157. {
  158. LLSpatialPartition* part = region->getSpatialPartition(i);
  159. if (part)
  160. {
  161. part->cull(*LLViewerCamera::getInstance(), &potentials, TRUE);
  162. }
  163. }
  164. }
  165. for (std::vector<LLDrawable*>::iterator iter = potentials.begin();
  166. iter != potentials.end(); iter++)
  167. {
  168. LLDrawable* drawable = *iter;
  169. LLViewerObject* vobjp = drawable->getVObj();
  170. if (!drawable || !vobjp ||
  171. vobjp->getPCode() != LL_PCODE_VOLUME ||
  172. vobjp->isAttachment() ||
  173. (deselect && !vobjp->isSelected()))
  174. {
  175. continue;
  176. }
  177. if (limit_select_distance && dist_vec_squared(drawable->getWorldPosition(), av_pos) > select_dist_squared)
  178. {
  179. continue;
  180. }
  181. S32 result = LLViewerCamera::getInstance()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius());
  182. if (result)
  183. {
  184. switch (result)
  185. {
  186. case 1:
  187. // check vertices
  188. if (LLViewerCamera::getInstance()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive))
  189. {
  190. LLSelectMgr::getInstance()->highlightObjectOnly(vobjp);
  191. }
  192. break;
  193. case 2:
  194. LLSelectMgr::getInstance()->highlightObjectOnly(vobjp);
  195. break;
  196. default:
  197. break;
  198. }
  199. }
  200. }
  201. }
  202. // restore drawing mode
  203. gGL.matrixMode(LLRender::MM_PROJECTION);
  204. gGL.popMatrix();
  205. gGL.matrixMode(LLRender::MM_MODELVIEW);
  206. // restore camera
  207. LLViewerCamera::getInstance()->setFar(old_far_plane);
  208. LLViewerCamera::getInstance()->setNear(old_near_plane);
  209. gViewerWindow->setup3DRender();
  210. }
  211. const F32 WIND_RELATIVE_ALTITUDE = 25.f;
  212. void LLWind::renderVectors()
  213. {
  214. // Renders the wind as vectors (used for debug)
  215. S32 i,j;
  216. F32 x,y;
  217. F32 region_width_meters = LLWorld::getInstance()->getRegionWidthInMeters();
  218. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  219. gGL.pushMatrix();
  220. LLVector3 origin_agent;
  221. origin_agent = gAgent.getPosAgentFromGlobal(mOriginGlobal);
  222. gGL.translatef(origin_agent.mV[VX], origin_agent.mV[VY], gAgent.getPositionAgent().mV[VZ] + WIND_RELATIVE_ALTITUDE);
  223. for (j = 0; j < mSize; j++)
  224. {
  225. for (i = 0; i < mSize; i++)
  226. {
  227. x = mVelX[i + j*mSize] * WIND_SCALE_HACK;
  228. y = mVelY[i + j*mSize] * WIND_SCALE_HACK;
  229. gGL.pushMatrix();
  230. gGL.translatef((F32)i * region_width_meters/mSize, (F32)j * region_width_meters/mSize, 0.0);
  231. gGL.color3f(0,1,0);
  232. gGL.begin(LLRender::POINTS);
  233. gGL.vertex3f(0,0,0);
  234. gGL.end();
  235. gGL.color3f(1,0,0);
  236. gGL.begin(LLRender::LINES);
  237. gGL.vertex3f(x * 0.1f, y * 0.1f ,0.f);
  238. gGL.vertex3f(x, y, 0.f);
  239. gGL.end();
  240. gGL.popMatrix();
  241. }
  242. }
  243. gGL.popMatrix();
  244. }
  245. // Used by lltoolselectland
  246. void LLViewerParcelMgr::renderRect(const LLVector3d &west_south_bottom_global,
  247. const LLVector3d &east_north_top_global )
  248. {
  249. LLGLSUIDefault gls_ui;
  250. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  251. LLGLDepthTest gls_depth(GL_TRUE);
  252. LLVector3 west_south_bottom_agent = gAgent.getPosAgentFromGlobal(west_south_bottom_global);
  253. F32 west = west_south_bottom_agent.mV[VX];
  254. F32 south = west_south_bottom_agent.mV[VY];
  255. // F32 bottom = west_south_bottom_agent.mV[VZ] - 1.f;
  256. LLVector3 east_north_top_agent = gAgent.getPosAgentFromGlobal(east_north_top_global);
  257. F32 east = east_north_top_agent.mV[VX];
  258. F32 north = east_north_top_agent.mV[VY];
  259. // F32 top = east_north_top_agent.mV[VZ] + 1.f;
  260. // HACK: At edge of last region of world, we need to make sure the region
  261. // resolves correctly so we can get a height value.
  262. const F32 FUDGE = 0.01f;
  263. F32 sw_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( west, south, 0.f ) );
  264. F32 se_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( east-FUDGE, south, 0.f ) );
  265. F32 ne_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( east-FUDGE, north-FUDGE, 0.f ) );
  266. F32 nw_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( west, north-FUDGE, 0.f ) );
  267. F32 sw_top = sw_bottom + PARCEL_POST_HEIGHT;
  268. F32 se_top = se_bottom + PARCEL_POST_HEIGHT;
  269. F32 ne_top = ne_bottom + PARCEL_POST_HEIGHT;
  270. F32 nw_top = nw_bottom + PARCEL_POST_HEIGHT;
  271. LLUI::setLineWidth(2.f);
  272. gGL.color4f(1.f, 1.f, 0.f, 1.f);
  273. // Cheat and give this the same pick-name as land
  274. gGL.begin(LLRender::LINES);
  275. gGL.vertex3f(west, north, nw_bottom);
  276. gGL.vertex3f(west, north, nw_top);
  277. gGL.vertex3f(east, north, ne_bottom);
  278. gGL.vertex3f(east, north, ne_top);
  279. gGL.vertex3f(east, south, se_bottom);
  280. gGL.vertex3f(east, south, se_top);
  281. gGL.vertex3f(west, south, sw_bottom);
  282. gGL.vertex3f(west, south, sw_top);
  283. gGL.end();
  284. gGL.color4f(1.f, 1.f, 0.f, 0.2f);
  285. gGL.begin(LLRender::QUADS);
  286. gGL.vertex3f(west, north, nw_bottom);
  287. gGL.vertex3f(west, north, nw_top);
  288. gGL.vertex3f(east, north, ne_top);
  289. gGL.vertex3f(east, north, ne_bottom);
  290. gGL.vertex3f(east, north, ne_bottom);
  291. gGL.vertex3f(east, north, ne_top);
  292. gGL.vertex3f(east, south, se_top);
  293. gGL.vertex3f(east, south, se_bottom);
  294. gGL.vertex3f(east, south, se_bottom);
  295. gGL.vertex3f(east, south, se_top);
  296. gGL.vertex3f(west, south, sw_top);
  297. gGL.vertex3f(west, south, sw_bottom);
  298. gGL.vertex3f(west, south, sw_bottom);
  299. gGL.vertex3f(west, south, sw_top);
  300. gGL.vertex3f(west, north, nw_top);
  301. gGL.vertex3f(west, north, nw_bottom);
  302. gGL.end();
  303. LLUI::setLineWidth(1.f);
  304. }
  305. /*
  306. void LLViewerParcelMgr::renderParcel(LLParcel* parcel )
  307. {
  308. S32 i;
  309. S32 count = parcel->getBoxCount();
  310. for (i = 0; i < count; i++)
  311. {
  312. const LLParcelBox& box = parcel->getBox(i);
  313. F32 west = box.mMin.mV[VX];
  314. F32 south = box.mMin.mV[VY];
  315. F32 east = box.mMax.mV[VX];
  316. F32 north = box.mMax.mV[VY];
  317. // HACK: At edge of last region of world, we need to make sure the region
  318. // resolves correctly so we can get a height value.
  319. const F32 FUDGE = 0.01f;
  320. F32 sw_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( west, south, 0.f ) );
  321. F32 se_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( east-FUDGE, south, 0.f ) );
  322. F32 ne_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( east-FUDGE, north-FUDGE, 0.f ) );
  323. F32 nw_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( west, north-FUDGE, 0.f ) );
  324. // little hack to make nearby lines not Z-fight
  325. east -= 0.1f;
  326. north -= 0.1f;
  327. F32 sw_top = sw_bottom + POST_HEIGHT;
  328. F32 se_top = se_bottom + POST_HEIGHT;
  329. F32 ne_top = ne_bottom + POST_HEIGHT;
  330. F32 nw_top = nw_bottom + POST_HEIGHT;
  331. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  332. LLGLDepthTest gls_depth(GL_TRUE);
  333. LLUI::setLineWidth(2.f);
  334. gGL.color4f(0.f, 1.f, 1.f, 1.f);
  335. // Cheat and give this the same pick-name as land
  336. gGL.begin(LLRender::LINES);
  337. gGL.vertex3f(west, north, nw_bottom);
  338. gGL.vertex3f(west, north, nw_top);
  339. gGL.vertex3f(east, north, ne_bottom);
  340. gGL.vertex3f(east, north, ne_top);
  341. gGL.vertex3f(east, south, se_bottom);
  342. gGL.vertex3f(east, south, se_top);
  343. gGL.vertex3f(west, south, sw_bottom);
  344. gGL.vertex3f(west, south, sw_top);
  345. gGL.end();
  346. gGL.color4f(0.f, 1.f, 1.f, 0.2f);
  347. gGL.begin(LLRender::QUADS);
  348. gGL.vertex3f(west, north, nw_bottom);
  349. gGL.vertex3f(west, north, nw_top);
  350. gGL.vertex3f(east, north, ne_top);
  351. gGL.vertex3f(east, north, ne_bottom);
  352. gGL.vertex3f(east, north, ne_bottom);
  353. gGL.vertex3f(east, north, ne_top);
  354. gGL.vertex3f(east, south, se_top);
  355. gGL.vertex3f(east, south, se_bottom);
  356. gGL.vertex3f(east, south, se_bottom);
  357. gGL.vertex3f(east, south, se_top);
  358. gGL.vertex3f(west, south, sw_top);
  359. gGL.vertex3f(west, south, sw_bottom);
  360. gGL.vertex3f(west, south, sw_bottom);
  361. gGL.vertex3f(west, south, sw_top);
  362. gGL.vertex3f(west, north, nw_top);
  363. gGL.vertex3f(west, north, nw_bottom);
  364. gGL.end();
  365. LLUI::setLineWidth(1.f);
  366. }
  367. }
  368. */
  369. // north = a wall going north/south. Need that info to set up texture
  370. // coordinates correctly.
  371. void LLViewerParcelMgr::renderOneSegment(F32 x1, F32 y1, F32 x2, F32 y2, F32 height, U8 direction, LLViewerRegion* regionp)
  372. {
  373. // HACK: At edge of last region of world, we need to make sure the region
  374. // resolves correctly so we can get a height value.
  375. const F32 BORDER = REGION_WIDTH_METERS - 0.1f;
  376. F32 clamped_x1 = x1;
  377. F32 clamped_y1 = y1;
  378. F32 clamped_x2 = x2;
  379. F32 clamped_y2 = y2;
  380. if (clamped_x1 > BORDER) clamped_x1 = BORDER;
  381. if (clamped_y1 > BORDER) clamped_y1 = BORDER;
  382. if (clamped_x2 > BORDER) clamped_x2 = BORDER;
  383. if (clamped_y2 > BORDER) clamped_y2 = BORDER;
  384. F32 z;
  385. F32 z1;
  386. F32 z2;
  387. z1 = regionp->getLand().resolveHeightRegion( LLVector3( clamped_x1, clamped_y1, 0.f ) );
  388. z2 = regionp->getLand().resolveHeightRegion( LLVector3( clamped_x2, clamped_y2, 0.f ) );
  389. // Convert x1 and x2 from region-local to agent coords.
  390. LLVector3 origin = regionp->getOriginAgent();
  391. x1 += origin.mV[VX];
  392. x2 += origin.mV[VX];
  393. y1 += origin.mV[VY];
  394. y2 += origin.mV[VY];
  395. if (height < 1.f)
  396. {
  397. z = z1+height;
  398. gGL.vertex3f(x1, y1, z);
  399. gGL.vertex3f(x1, y1, z1);
  400. gGL.vertex3f(x2, y2, z2);
  401. z = z2+height;
  402. gGL.vertex3f(x2, y2, z);
  403. }
  404. else
  405. {
  406. F32 tex_coord1;
  407. F32 tex_coord2;
  408. if (WEST_MASK == direction)
  409. {
  410. tex_coord1 = y1;
  411. tex_coord2 = y2;
  412. }
  413. else if (SOUTH_MASK == direction)
  414. {
  415. tex_coord1 = x1;
  416. tex_coord2 = x2;
  417. }
  418. else if (EAST_MASK == direction)
  419. {
  420. tex_coord1 = y2;
  421. tex_coord2 = y1;
  422. }
  423. else /* (NORTH_MASK == direction) */
  424. {
  425. tex_coord1 = x2;
  426. tex_coord2 = x1;
  427. }
  428. gGL.texCoord2f(tex_coord1*0.5f+0.5f, z1*0.5f);
  429. gGL.vertex3f(x1, y1, z1);
  430. gGL.texCoord2f(tex_coord2*0.5f+0.5f, z2*0.5f);
  431. gGL.vertex3f(x2, y2, z2);
  432. // top edge stairsteps
  433. z = llmax(z2+height, z1+height);
  434. gGL.texCoord2f(tex_coord2*0.5f+0.5f, z*0.5f);
  435. gGL.vertex3f(x2, y2, z);
  436. gGL.texCoord2f(tex_coord1*0.5f+0.5f, z*0.5f);
  437. gGL.vertex3f(x1, y1, z);
  438. }
  439. }
  440. void LLViewerParcelMgr::renderHighlightSegments(const U8* segments, LLViewerRegion* regionp)
  441. {
  442. S32 x, y;
  443. F32 x1, y1; // start point
  444. F32 x2, y2; // end point
  445. bool has_segments = false;
  446. LLGLSUIDefault gls_ui;
  447. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  448. LLGLDepthTest gls_depth(GL_TRUE);
  449. gGL.color4f(1.f, 1.f, 0.f, 0.2f);
  450. const S32 STRIDE = (mParcelsPerEdge+1);
  451. // Cheat and give this the same pick-name as land
  452. for (y = 0; y < STRIDE; y++)
  453. {
  454. for (x = 0; x < STRIDE; x++)
  455. {
  456. U8 segment_mask = segments[x + y*STRIDE];
  457. if (segment_mask & SOUTH_MASK)
  458. {
  459. x1 = x * PARCEL_GRID_STEP_METERS;
  460. y1 = y * PARCEL_GRID_STEP_METERS;
  461. x2 = x1 + PARCEL_GRID_STEP_METERS;
  462. y2 = y1;
  463. if (!has_segments)
  464. {
  465. has_segments = true;
  466. gGL.begin(LLRender::QUADS);
  467. }
  468. renderOneSegment(x1, y1, x2, y2, PARCEL_POST_HEIGHT, SOUTH_MASK, regionp);
  469. }
  470. if (segment_mask & WEST_MASK)
  471. {
  472. x1 = x * PARCEL_GRID_STEP_METERS;
  473. y1 = y * PARCEL_GRID_STEP_METERS;
  474. x2 = x1;
  475. y2 = y1 + PARCEL_GRID_STEP_METERS;
  476. if (!has_segments)
  477. {
  478. has_segments = true;
  479. gGL.begin(LLRender::QUADS);
  480. }
  481. renderOneSegment(x1, y1, x2, y2, PARCEL_POST_HEIGHT, WEST_MASK, regionp);
  482. }
  483. }
  484. }
  485. if (has_segments)
  486. {
  487. gGL.end();
  488. }
  489. }
  490. void LLViewerParcelMgr::renderCollisionSegments(U8* segments, BOOL use_pass, LLViewerRegion* regionp)
  491. {
  492. S32 x, y;
  493. F32 x1, y1; // start point
  494. F32 x2, y2; // end point
  495. F32 alpha = 0;
  496. F32 dist = 0;
  497. F32 dx, dy;
  498. F32 collision_height;
  499. const S32 STRIDE = (mParcelsPerEdge+1);
  500. LLVector3 pos = gAgent.getPositionAgent();
  501. F32 pos_x = pos.mV[VX];
  502. F32 pos_y = pos.mV[VY];
  503. LLGLSUIDefault gls_ui;
  504. LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
  505. LLGLDisable cull(GL_CULL_FACE);
  506. if (mCollisionBanned == BA_BANNED)
  507. {
  508. collision_height = BAN_HEIGHT;
  509. }
  510. else
  511. {
  512. collision_height = PARCEL_HEIGHT;
  513. }
  514. if (use_pass && (mCollisionBanned == BA_NOT_ON_LIST))
  515. {
  516. gGL.getTexUnit(0)->bind(mPassImage);
  517. }
  518. else
  519. {
  520. gGL.getTexUnit(0)->bind(mBlockedImage);
  521. }
  522. gGL.begin(LLRender::QUADS);
  523. for (y = 0; y < STRIDE; y++)
  524. {
  525. for (x = 0; x < STRIDE; x++)
  526. {
  527. U8 segment_mask = segments[x + y*STRIDE];
  528. U8 direction;
  529. const F32 MAX_ALPHA = 0.95f;
  530. const S32 DIST_OFFSET = 5;
  531. const S32 MIN_DIST_SQ = DIST_OFFSET*DIST_OFFSET;
  532. const S32 MAX_DIST_SQ = 169;
  533. if (segment_mask & SOUTH_MASK)
  534. {
  535. x1 = x * PARCEL_GRID_STEP_METERS;
  536. y1 = y * PARCEL_GRID_STEP_METERS;
  537. x2 = x1 + PARCEL_GRID_STEP_METERS;
  538. y2 = y1;
  539. dy = (pos_y - y1) + DIST_OFFSET;
  540. if (pos_x < x1)
  541. dx = pos_x - x1;
  542. else if (pos_x > x2)
  543. dx = pos_x - x2;
  544. else
  545. dx = 0;
  546. dist = dx*dx+dy*dy;
  547. if (dist < MIN_DIST_SQ)
  548. alpha = MAX_ALPHA;
  549. else if (dist > MAX_DIST_SQ)
  550. alpha = 0.0f;
  551. else
  552. alpha = 30/dist;
  553. alpha = llclamp(alpha, 0.0f, MAX_ALPHA);
  554. gGL.color4f(1.f, 1.f, 1.f, alpha);
  555. if ((pos_y - y1) < 0) direction = SOUTH_MASK;
  556. else direction = NORTH_MASK;
  557. // avoid Z fighting
  558. renderOneSegment(x1+0.1f, y1+0.1f, x2+0.1f, y2+0.1f, collision_height, direction, regionp);
  559. }
  560. if (segment_mask & WEST_MASK)
  561. {
  562. x1 = x * PARCEL_GRID_STEP_METERS;
  563. y1 = y * PARCEL_GRID_STEP_METERS;
  564. x2 = x1;
  565. y2 = y1 + PARCEL_GRID_STEP_METERS;
  566. dx = (pos_x - x1) + DIST_OFFSET;
  567. if (pos_y < y1)
  568. dy = pos_y - y1;
  569. else if (pos_y > y2)
  570. dy = pos_y - y2;
  571. else
  572. dy = 0;
  573. dist = dx*dx+dy*dy;
  574. if (dist < MIN_DIST_SQ)
  575. alpha = MAX_ALPHA;
  576. else if (dist > MAX_DIST_SQ)
  577. alpha = 0.0f;
  578. else
  579. alpha = 30/dist;
  580. alpha = llclamp(alpha, 0.0f, MAX_ALPHA);
  581. gGL.color4f(1.f, 1.f, 1.f, alpha);
  582. if ((pos_x - x1) > 0) direction = WEST_MASK;
  583. else direction = EAST_MASK;
  584. // avoid Z fighting
  585. renderOneSegment(x1+0.1f, y1+0.1f, x2+0.1f, y2+0.1f, collision_height, direction, regionp);
  586. }
  587. }
  588. }
  589. gGL.end();
  590. }
  591. void draw_line_cube(F32 width, const LLVector3& center)
  592. {
  593. width = 0.5f * width;
  594. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] + width);
  595. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] + width);
  596. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] + width);
  597. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] + width);
  598. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] + width);
  599. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] + width);
  600. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] + width);
  601. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] + width);
  602. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] - width);
  603. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] - width);
  604. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] - width);
  605. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] - width);
  606. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] - width);
  607. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] - width);
  608. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] - width);
  609. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] - width);
  610. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] + width);
  611. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] - width);
  612. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] + width);
  613. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] - width);
  614. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] + width);
  615. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] - width);
  616. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] + width);
  617. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] - width);
  618. }
  619. void LLViewerObjectList::renderObjectBeacons()
  620. {
  621. if (mDebugBeacons.empty())
  622. {
  623. return;
  624. }
  625. LLGLSUIDefault gls_ui;
  626. if (LLGLSLShader::sNoFixedFunction)
  627. {
  628. gUIProgram.bind();
  629. }
  630. {
  631. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  632. S32 last_line_width = -1;
  633. // gGL.begin(LLRender::LINES); // Always happens in (line_width != last_line_width)
  634. for (std::vector<LLDebugBeacon>::iterator iter = mDebugBeacons.begin(); iter != mDebugBeacons.end(); ++iter)
  635. {
  636. const LLDebugBeacon &debug_beacon = *iter;
  637. LLColor4 color = debug_beacon.mColor;
  638. color.mV[3] *= 0.25f;
  639. S32 line_width = debug_beacon.mLineWidth;
  640. if (line_width != last_line_width)
  641. {
  642. gGL.flush();
  643. glLineWidth( (F32)line_width );
  644. last_line_width = line_width;
  645. }
  646. const LLVector3 &thisline = debug_beacon.mPositionAgent;
  647. gGL.begin(LLRender::LINES);
  648. gGL.color4fv(color.mV);
  649. gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] - 50.f);
  650. gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] + 50.f);
  651. gGL.vertex3f(thisline.mV[VX] - 2.f,thisline.mV[VY],thisline.mV[VZ]);
  652. gGL.vertex3f(thisline.mV[VX] + 2.f,thisline.mV[VY],thisline.mV[VZ]);
  653. gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] - 2.f,thisline.mV[VZ]);
  654. gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] + 2.f,thisline.mV[VZ]);
  655. draw_line_cube(0.10f, thisline);
  656. gGL.end();
  657. }
  658. }
  659. {
  660. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  661. LLGLDepthTest gls_depth(GL_TRUE);
  662. S32 last_line_width = -1;
  663. // gGL.begin(LLRender::LINES); // Always happens in (line_width != last_line_width)
  664. for (std::vector<LLDebugBeacon>::iterator iter = mDebugBeacons.begin(); iter != mDebugBeacons.end(); ++iter)
  665. {
  666. const LLDebugBeacon &debug_beacon = *iter;
  667. S32 line_width = debug_beacon.mLineWidth;
  668. if (line_width != last_line_width)
  669. {
  670. gGL.flush();
  671. glLineWidth( (F32)line_width );
  672. last_line_width = line_width;
  673. }
  674. const LLVector3 &thisline = debug_beacon.mPositionAgent;
  675. gGL.begin(LLRender::LINES);
  676. gGL.color4fv(debug_beacon.mColor.mV);
  677. gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] - 0.5f);
  678. gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] + 0.5f);
  679. gGL.vertex3f(thisline.mV[VX] - 0.5f,thisline.mV[VY],thisline.mV[VZ]);
  680. gGL.vertex3f(thisline.mV[VX] + 0.5f,thisline.mV[VY],thisline.mV[VZ]);
  681. gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] - 0.5f,thisline.mV[VZ]);
  682. gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] + 0.5f,thisline.mV[VZ]);
  683. draw_line_cube(0.10f, thisline);
  684. gGL.end();
  685. }
  686. gGL.flush();
  687. glLineWidth(1.f);
  688. for (std::vector<LLDebugBeacon>::iterator iter = mDebugBeacons.begin(); iter != mDebugBeacons.end(); ++iter)
  689. {
  690. LLDebugBeacon &debug_beacon = *iter;
  691. if (debug_beacon.mString == "")
  692. {
  693. continue;
  694. }
  695. LLHUDText *hud_textp = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
  696. hud_textp->setZCompare(FALSE);
  697. LLColor4 color;
  698. color = debug_beacon.mTextColor;
  699. color.mV[3] *= 1.f;
  700. hud_textp->setString(debug_beacon.mString);
  701. hud_textp->setColor(color);
  702. hud_textp->setPositionAgent(debug_beacon.mPositionAgent);
  703. debug_beacon.mHUDObject = hud_textp;
  704. }
  705. }
  706. }