llglsandbox.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:26k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llglsandbox.cpp
  3.  * @brief GL functionality access
  4.  *
  5.  * $LicenseInfo:firstyear=2003&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2003-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. /** 
  33.  * Contains ALL methods which directly access GL functionality 
  34.  * except for core rendering engine functionality.
  35.  */
  36. #include "llviewerprecompiledheaders.h"
  37. #include "llviewercontrol.h"
  38. #include "llgl.h"
  39. #include "llrender.h"
  40. #include "llglheaders.h"
  41. #include "llparcel.h"
  42. #include "llui.h"
  43. #include "lldrawable.h"
  44. #include "lltextureentry.h"
  45. #include "llviewercamera.h"
  46. #include "llvoavatarself.h"
  47. #include "llagent.h"
  48. #include "lltoolmgr.h"
  49. #include "llselectmgr.h"
  50. #include "llhudmanager.h"
  51. #include "llrendersphere.h"
  52. #include "llviewerobjectlist.h"
  53. #include "lltoolselectrect.h"
  54. #include "llviewerwindow.h"
  55. #include "llsurface.h"
  56. #include "llwind.h"
  57. #include "llworld.h"
  58. #include "llviewerparcelmgr.h"
  59. #include "llviewerregion.h"
  60. #include "llpreviewtexture.h"
  61. #include "llresmgr.h"
  62. #include "pipeline.h"
  63. #include "llspatialpartition.h"
  64. // Height of the yellow selection highlight posts for land
  65. const F32 PARCEL_POST_HEIGHT = 0.666f;
  66. BOOL LLAgent::setLookAt(ELookAtType target_type, LLViewerObject *object, LLVector3 position)
  67. {
  68. if(object && object->isAttachment())
  69. {
  70. LLViewerObject* parent = object;
  71. while(parent)
  72. {
  73. if (parent == mAvatarObject)
  74. {
  75. // looking at an attachment on ourselves, which we don't want to do
  76. object = mAvatarObject;
  77. position.clearVec();
  78. }
  79. parent = (LLViewerObject*)parent->getParent();
  80. }
  81. }
  82. if(!mLookAt || mLookAt->isDead())
  83. {
  84. mLookAt = (LLHUDEffectLookAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_LOOKAT);
  85. mLookAt->setSourceObject(mAvatarObject);
  86. }
  87. return mLookAt->setLookAt(target_type, object, position);
  88. }
  89. BOOL LLAgent::setPointAt(EPointAtType target_type, LLViewerObject *object, LLVector3 position)
  90. {
  91. // disallow pointing at attachments and avatars
  92. if (object && (object->isAttachment() || object->isAvatar()))
  93. {
  94. return FALSE;
  95. }
  96. if(!mPointAt || mPointAt->isDead())
  97. {
  98. mPointAt = (LLHUDEffectPointAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINTAT);
  99. mPointAt->setSourceObject(mAvatarObject);
  100. }
  101. return mPointAt->setPointAt(target_type, object, position);
  102. }
  103. ELookAtType LLAgent::getLookAtType()
  104. if (mLookAt) 
  105. {
  106. return mLookAt->getLookAtType();
  107. }
  108. return LOOKAT_TARGET_NONE;
  109. }
  110. EPointAtType LLAgent::getPointAtType()
  111. if (mPointAt) 
  112. {
  113. return mPointAt->getPointAtType();
  114. }
  115. return POINTAT_TARGET_NONE;
  116. }
  117. // Draw a representation of current autopilot target
  118. void LLAgent::renderAutoPilotTarget()
  119. {
  120. if (mAutoPilot)
  121. {
  122. F32 height_meters;
  123. LLVector3d target_global;
  124. glMatrixMode(GL_MODELVIEW);
  125. gGL.pushMatrix();
  126. // not textured
  127. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  128. // lovely green
  129. glColor4f(0.f, 1.f, 1.f, 1.f);
  130. target_global = mAutoPilotTargetGlobal;
  131. gGL.translatef((F32)(target_global.mdV[VX]), (F32)(target_global.mdV[VY]), (F32)(target_global.mdV[VZ]));
  132. height_meters = 1.f;
  133. glScalef(height_meters, height_meters, height_meters);
  134. gSphere.render(1500.f);
  135. gGL.popMatrix();
  136. }
  137. }
  138. // Returns true if you got at least one object
  139. void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
  140. {
  141. LLVector3 av_pos = gAgent.getPositionAgent();
  142. F32 select_dist_squared = gSavedSettings.getF32("MaxSelectDistance");
  143. select_dist_squared = select_dist_squared * select_dist_squared;
  144. BOOL deselect = (mask == MASK_CONTROL);
  145. S32 left = llmin(x, mDragStartX);
  146. S32 right = llmax(x, mDragStartX);
  147. S32 top = llmax(y, mDragStartY);
  148. S32 bottom =llmin(y, mDragStartY);
  149. left = llround((F32) left * LLUI::sGLScaleFactor.mV[VX]);
  150. right = llround((F32) right * LLUI::sGLScaleFactor.mV[VX]);
  151. top = llround((F32) top * LLUI::sGLScaleFactor.mV[VY]);
  152. bottom = llround((F32) bottom * LLUI::sGLScaleFactor.mV[VY]);
  153. F32 old_far_plane = LLViewerCamera::getInstance()->getFar();
  154. F32 old_near_plane = LLViewerCamera::getInstance()->getNear();
  155. S32 width = right - left + 1;
  156. S32 height = top - bottom + 1;
  157. BOOL grow_selection = FALSE;
  158. BOOL shrink_selection = FALSE;
  159. if (height > mDragLastHeight || width > mDragLastWidth)
  160. {
  161. grow_selection = TRUE;
  162. }
  163. if (height < mDragLastHeight || width < mDragLastWidth)
  164. {
  165. shrink_selection = TRUE;
  166. }
  167. if (!grow_selection && !shrink_selection)
  168. {
  169. // nothing to do
  170. return;
  171. }
  172. mDragLastHeight = height;
  173. mDragLastWidth = width;
  174. S32 center_x = (left + right) / 2;
  175. S32 center_y = (top + bottom) / 2;
  176. // save drawing mode
  177. glMatrixMode(GL_PROJECTION);
  178. gGL.pushMatrix();
  179. BOOL limit_select_distance = gSavedSettings.getBOOL("LimitSelectDistance");
  180. if (limit_select_distance)
  181. {
  182. // ...select distance from control
  183. LLVector3 relative_av_pos = av_pos;
  184. relative_av_pos -= LLViewerCamera::getInstance()->getOrigin();
  185. F32 new_far = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() + gSavedSettings.getF32("MaxSelectDistance");
  186. F32 new_near = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() - gSavedSettings.getF32("MaxSelectDistance");
  187. new_near = llmax(new_near, 0.1f);
  188. LLViewerCamera::getInstance()->setFar(new_far);
  189. LLViewerCamera::getInstance()->setNear(new_near);
  190. }
  191. LLViewerCamera::getInstance()->setPerspective(FOR_SELECTION, 
  192. center_x-width/2, center_y-height/2, width, height, 
  193. limit_select_distance);
  194. if (shrink_selection)
  195. {
  196. struct f : public LLSelectedObjectFunctor
  197. {
  198. virtual bool apply(LLViewerObject* vobjp)
  199. {
  200. LLDrawable* drawable = vobjp->mDrawable;
  201. if (!drawable || vobjp->getPCode() != LL_PCODE_VOLUME || vobjp->isAttachment())
  202. {
  203. return true;
  204. }
  205. S32 result = LLViewerCamera::getInstance()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius());
  206. switch (result)
  207. {
  208.   case 0:
  209. LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp);
  210. break;
  211.   case 1:
  212. // check vertices
  213. if (!LLViewerCamera::getInstance()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive))
  214. {
  215. LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp);
  216. }
  217. break;
  218.   default:
  219. break;
  220. }
  221. return true;
  222. }
  223. } func;
  224. LLSelectMgr::getInstance()->getHighlightedObjects()->applyToObjects(&func);
  225. }
  226. if (grow_selection)
  227. {
  228. std::vector<LLDrawable*> potentials;
  229. for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
  230. iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
  231. {
  232. LLViewerRegion* region = *iter;
  233. for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
  234. {
  235. LLSpatialPartition* part = region->getSpatialPartition(i);
  236. if (part)
  237. {
  238. part->cull(*LLViewerCamera::getInstance(), &potentials, TRUE);
  239. }
  240. }
  241. }
  242. for (std::vector<LLDrawable*>::iterator iter = potentials.begin();
  243.  iter != potentials.end(); iter++)
  244. {
  245. LLDrawable* drawable = *iter;
  246. LLViewerObject* vobjp = drawable->getVObj();
  247. if (!drawable || !vobjp ||
  248. vobjp->getPCode() != LL_PCODE_VOLUME || 
  249. vobjp->isAttachment() ||
  250. (deselect && !vobjp->isSelected()))
  251. {
  252. continue;
  253. }
  254. if (limit_select_distance && dist_vec_squared(drawable->getWorldPosition(), av_pos) > select_dist_squared)
  255. {
  256. continue;
  257. }
  258. S32 result = LLViewerCamera::getInstance()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius());
  259. if (result)
  260. {
  261. switch (result)
  262. {
  263. case 1:
  264. // check vertices
  265. if (LLViewerCamera::getInstance()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive))
  266. {
  267. LLSelectMgr::getInstance()->highlightObjectOnly(vobjp);
  268. }
  269. break;
  270. case 2:
  271. LLSelectMgr::getInstance()->highlightObjectOnly(vobjp);
  272. break;
  273. default:
  274. break;
  275. }
  276. }
  277. }
  278. }
  279. // restore drawing mode
  280. glMatrixMode(GL_PROJECTION);
  281. gGL.popMatrix();
  282. glMatrixMode(GL_MODELVIEW);
  283. // restore camera
  284. LLViewerCamera::getInstance()->setFar(old_far_plane);
  285. LLViewerCamera::getInstance()->setNear(old_near_plane);
  286. gViewerWindow->setup3DRender();
  287. }
  288. const F32 WIND_ALTITUDE = 180.f;
  289. void LLWind::renderVectors()
  290. {
  291. // Renders the wind as vectors (used for debug)
  292. S32 i,j;
  293. F32 x,y;
  294. F32 region_width_meters = LLWorld::getInstance()->getRegionWidthInMeters();
  295. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  296. gGL.pushMatrix();
  297. LLVector3 origin_agent;
  298. origin_agent = gAgent.getPosAgentFromGlobal(mOriginGlobal);
  299. gGL.translatef(origin_agent.mV[VX], origin_agent.mV[VY], WIND_ALTITUDE);
  300. for (j = 0; j < mSize; j++)
  301. {
  302. for (i = 0; i < mSize; i++)
  303. {
  304. x = mCloudVelX[i + j*mSize] * WIND_SCALE_HACK;
  305. y = mCloudVelY[i + j*mSize] * WIND_SCALE_HACK;
  306. gGL.pushMatrix();
  307. gGL.translatef((F32)i * region_width_meters/mSize, (F32)j * region_width_meters/mSize, 0.0);
  308. gGL.color3f(0,1,0);
  309. gGL.begin(LLRender::POINTS);
  310. gGL.vertex3f(0,0,0);
  311. gGL.end();
  312. gGL.color3f(1,0,0);
  313. gGL.begin(LLRender::LINES);
  314. gGL.vertex3f(x * 0.1f, y * 0.1f ,0.f);
  315. gGL.vertex3f(x, y, 0.f);
  316. gGL.end();
  317. gGL.popMatrix();
  318. }
  319. }
  320. gGL.popMatrix();
  321. }
  322. // Used by lltoolselectland
  323. void LLViewerParcelMgr::renderRect(const LLVector3d &west_south_bottom_global, 
  324.    const LLVector3d &east_north_top_global )
  325. {
  326. LLGLSUIDefault gls_ui;
  327. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  328. LLGLDepthTest gls_depth(GL_TRUE);
  329. LLVector3 west_south_bottom_agent = gAgent.getPosAgentFromGlobal(west_south_bottom_global);
  330. F32 west = west_south_bottom_agent.mV[VX];
  331. F32 south = west_south_bottom_agent.mV[VY];
  332. // F32 bottom = west_south_bottom_agent.mV[VZ] - 1.f;
  333. LLVector3 east_north_top_agent = gAgent.getPosAgentFromGlobal(east_north_top_global);
  334. F32 east = east_north_top_agent.mV[VX];
  335. F32 north = east_north_top_agent.mV[VY];
  336. // F32 top = east_north_top_agent.mV[VZ] + 1.f;
  337. // HACK: At edge of last region of world, we need to make sure the region
  338. // resolves correctly so we can get a height value.
  339. const F32 FUDGE = 0.01f;
  340. F32 sw_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( west, south, 0.f ) );
  341. F32 se_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( east-FUDGE, south, 0.f ) );
  342. F32 ne_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( east-FUDGE, north-FUDGE, 0.f ) );
  343. F32 nw_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( west, north-FUDGE, 0.f ) );
  344. F32 sw_top = sw_bottom + PARCEL_POST_HEIGHT;
  345. F32 se_top = se_bottom + PARCEL_POST_HEIGHT;
  346. F32 ne_top = ne_bottom + PARCEL_POST_HEIGHT;
  347. F32 nw_top = nw_bottom + PARCEL_POST_HEIGHT;
  348. LLUI::setLineWidth(2.f);
  349. gGL.color4f(1.f, 1.f, 0.f, 1.f);
  350. // Cheat and give this the same pick-name as land
  351. gGL.begin(LLRender::LINES);
  352. gGL.vertex3f(west, north, nw_bottom);
  353. gGL.vertex3f(west, north, nw_top);
  354. gGL.vertex3f(east, north, ne_bottom);
  355. gGL.vertex3f(east, north, ne_top);
  356. gGL.vertex3f(east, south, se_bottom);
  357. gGL.vertex3f(east, south, se_top);
  358. gGL.vertex3f(west, south, sw_bottom);
  359. gGL.vertex3f(west, south, sw_top);
  360. gGL.end();
  361. gGL.color4f(1.f, 1.f, 0.f, 0.2f);
  362. gGL.begin(LLRender::QUADS);
  363. gGL.vertex3f(west, north, nw_bottom);
  364. gGL.vertex3f(west, north, nw_top);
  365. gGL.vertex3f(east, north, ne_top);
  366. gGL.vertex3f(east, north, ne_bottom);
  367. gGL.vertex3f(east, north, ne_bottom);
  368. gGL.vertex3f(east, north, ne_top);
  369. gGL.vertex3f(east, south, se_top);
  370. gGL.vertex3f(east, south, se_bottom);
  371. gGL.vertex3f(east, south, se_bottom);
  372. gGL.vertex3f(east, south, se_top);
  373. gGL.vertex3f(west, south, sw_top);
  374. gGL.vertex3f(west, south, sw_bottom);
  375. gGL.vertex3f(west, south, sw_bottom);
  376. gGL.vertex3f(west, south, sw_top);
  377. gGL.vertex3f(west, north, nw_top);
  378. gGL.vertex3f(west, north, nw_bottom);
  379. gGL.end();
  380. LLUI::setLineWidth(1.f);
  381. }
  382. /*
  383. void LLViewerParcelMgr::renderParcel(LLParcel* parcel )
  384. {
  385. S32 i;
  386. S32 count = parcel->getBoxCount();
  387. for (i = 0; i < count; i++)
  388. {
  389. const LLParcelBox& box = parcel->getBox(i);
  390. F32 west = box.mMin.mV[VX];
  391. F32 south = box.mMin.mV[VY];
  392. F32 east = box.mMax.mV[VX];
  393. F32 north = box.mMax.mV[VY];
  394. // HACK: At edge of last region of world, we need to make sure the region
  395. // resolves correctly so we can get a height value.
  396. const F32 FUDGE = 0.01f;
  397. F32 sw_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( west, south, 0.f ) );
  398. F32 se_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( east-FUDGE, south, 0.f ) );
  399. F32 ne_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( east-FUDGE, north-FUDGE, 0.f ) );
  400. F32 nw_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( west, north-FUDGE, 0.f ) );
  401. // little hack to make nearby lines not Z-fight
  402. east -= 0.1f;
  403. north -= 0.1f;
  404. F32 sw_top = sw_bottom + POST_HEIGHT;
  405. F32 se_top = se_bottom + POST_HEIGHT;
  406. F32 ne_top = ne_bottom + POST_HEIGHT;
  407. F32 nw_top = nw_bottom + POST_HEIGHT;
  408. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  409. LLGLDepthTest gls_depth(GL_TRUE);
  410. LLUI::setLineWidth(2.f);
  411. gGL.color4f(0.f, 1.f, 1.f, 1.f);
  412. // Cheat and give this the same pick-name as land
  413. gGL.begin(LLRender::LINES);
  414. gGL.vertex3f(west, north, nw_bottom);
  415. gGL.vertex3f(west, north, nw_top);
  416. gGL.vertex3f(east, north, ne_bottom);
  417. gGL.vertex3f(east, north, ne_top);
  418. gGL.vertex3f(east, south, se_bottom);
  419. gGL.vertex3f(east, south, se_top);
  420. gGL.vertex3f(west, south, sw_bottom);
  421. gGL.vertex3f(west, south, sw_top);
  422. gGL.end();
  423. gGL.color4f(0.f, 1.f, 1.f, 0.2f);
  424. gGL.begin(LLRender::QUADS);
  425. gGL.vertex3f(west, north, nw_bottom);
  426. gGL.vertex3f(west, north, nw_top);
  427. gGL.vertex3f(east, north, ne_top);
  428. gGL.vertex3f(east, north, ne_bottom);
  429. gGL.vertex3f(east, north, ne_bottom);
  430. gGL.vertex3f(east, north, ne_top);
  431. gGL.vertex3f(east, south, se_top);
  432. gGL.vertex3f(east, south, se_bottom);
  433. gGL.vertex3f(east, south, se_bottom);
  434. gGL.vertex3f(east, south, se_top);
  435. gGL.vertex3f(west, south, sw_top);
  436. gGL.vertex3f(west, south, sw_bottom);
  437. gGL.vertex3f(west, south, sw_bottom);
  438. gGL.vertex3f(west, south, sw_top);
  439. gGL.vertex3f(west, north, nw_top);
  440. gGL.vertex3f(west, north, nw_bottom);
  441. gGL.end();
  442. LLUI::setLineWidth(1.f);
  443. }
  444. }
  445. */
  446. // north = a wall going north/south.  Need that info to set up texture
  447. // coordinates correctly.
  448. void LLViewerParcelMgr::renderOneSegment(F32 x1, F32 y1, F32 x2, F32 y2, F32 height, U8 direction, LLViewerRegion* regionp)
  449. {
  450. // HACK: At edge of last region of world, we need to make sure the region
  451. // resolves correctly so we can get a height value.
  452. const F32 BORDER = REGION_WIDTH_METERS - 0.1f;
  453. F32 clamped_x1 = x1;
  454. F32 clamped_y1 = y1;
  455. F32 clamped_x2 = x2;
  456. F32 clamped_y2 = y2;
  457. if (clamped_x1 > BORDER) clamped_x1 = BORDER;
  458. if (clamped_y1 > BORDER) clamped_y1 = BORDER;
  459. if (clamped_x2 > BORDER) clamped_x2 = BORDER;
  460. if (clamped_y2 > BORDER) clamped_y2 = BORDER;
  461. F32 z;
  462. F32 z1;
  463. F32 z2;
  464. z1 = regionp->getLand().resolveHeightRegion( LLVector3( clamped_x1, clamped_y1, 0.f ) );
  465. z2 = regionp->getLand().resolveHeightRegion( LLVector3( clamped_x2, clamped_y2, 0.f ) );
  466. // Convert x1 and x2 from region-local to agent coords.
  467. LLVector3 origin = regionp->getOriginAgent();
  468. x1 += origin.mV[VX];
  469. x2 += origin.mV[VX];
  470. y1 += origin.mV[VY];
  471. y2 += origin.mV[VY];
  472. if (height < 1.f)
  473. {
  474. z = z1+height;
  475. gGL.vertex3f(x1, y1, z);
  476. gGL.vertex3f(x1, y1, z1);
  477. gGL.vertex3f(x2, y2, z2);
  478. z = z2+height;
  479. gGL.vertex3f(x2, y2, z);
  480. }
  481. else
  482. {
  483. F32 tex_coord1;
  484. F32 tex_coord2;
  485. if (WEST_MASK == direction)
  486. {
  487. tex_coord1 = y1;
  488. tex_coord2 = y2;
  489. }
  490. else if (SOUTH_MASK == direction)
  491. {
  492. tex_coord1 = x1;
  493. tex_coord2 = x2;
  494. }
  495. else if (EAST_MASK == direction)
  496. {
  497. tex_coord1 = y2;
  498. tex_coord2 = y1;
  499. }
  500. else /* (NORTH_MASK == direction) */
  501. {
  502. tex_coord1 = x2;
  503. tex_coord2 = x1;
  504. }
  505. gGL.texCoord2f(tex_coord1*0.5f+0.5f, z1*0.5f);
  506. gGL.vertex3f(x1, y1, z1);
  507. gGL.texCoord2f(tex_coord2*0.5f+0.5f, z2*0.5f);
  508. gGL.vertex3f(x2, y2, z2);
  509. // top edge stairsteps
  510. z = llmax(z2+height, z1+height);
  511. gGL.texCoord2f(tex_coord2*0.5f+0.5f, z*0.5f);
  512. gGL.vertex3f(x2, y2, z);
  513. gGL.texCoord2f(tex_coord1*0.5f+0.5f, z*0.5f);
  514. gGL.vertex3f(x1, y1, z);
  515. }
  516. }
  517. void LLViewerParcelMgr::renderHighlightSegments(const U8* segments, LLViewerRegion* regionp)
  518. {
  519. S32 x, y;
  520. F32 x1, y1; // start point
  521. F32 x2, y2; // end point
  522. bool has_segments = false;
  523. LLGLSUIDefault gls_ui;
  524. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  525. LLGLDepthTest gls_depth(GL_TRUE);
  526. gGL.color4f(1.f, 1.f, 0.f, 0.2f);
  527. const S32 STRIDE = (mParcelsPerEdge+1);
  528. // Cheat and give this the same pick-name as land
  529. for (y = 0; y < STRIDE; y++)
  530. {
  531. for (x = 0; x < STRIDE; x++)
  532. {
  533. U8 segment_mask = segments[x + y*STRIDE];
  534. if (segment_mask & SOUTH_MASK)
  535. {
  536. x1 = x * PARCEL_GRID_STEP_METERS;
  537. y1 = y * PARCEL_GRID_STEP_METERS;
  538. x2 = x1 + PARCEL_GRID_STEP_METERS;
  539. y2 = y1;
  540. if (!has_segments)
  541. {
  542. has_segments = true;
  543. gGL.begin(LLRender::QUADS);
  544. }
  545. renderOneSegment(x1, y1, x2, y2, PARCEL_POST_HEIGHT, SOUTH_MASK, regionp);
  546. }
  547. if (segment_mask & WEST_MASK)
  548. {
  549. x1 = x * PARCEL_GRID_STEP_METERS;
  550. y1 = y * PARCEL_GRID_STEP_METERS;
  551. x2 = x1;
  552. y2 = y1 + PARCEL_GRID_STEP_METERS;
  553. if (!has_segments)
  554. {
  555. has_segments = true;
  556. gGL.begin(LLRender::QUADS);
  557. }
  558. renderOneSegment(x1, y1, x2, y2, PARCEL_POST_HEIGHT, WEST_MASK, regionp);
  559. }
  560. }
  561. }
  562. if (has_segments)
  563. {
  564. gGL.end();
  565. }
  566. }
  567. void LLViewerParcelMgr::renderCollisionSegments(U8* segments, BOOL use_pass, LLViewerRegion* regionp)
  568. {
  569. S32 x, y;
  570. F32 x1, y1; // start point
  571. F32 x2, y2; // end point
  572. F32 alpha = 0;
  573. F32 dist = 0;
  574. F32 dx, dy;
  575. F32 collision_height;
  576. const S32 STRIDE = (mParcelsPerEdge+1);
  577. LLVector3 pos = gAgent.getPositionAgent();
  578. F32 pos_x = pos.mV[VX];
  579. F32 pos_y = pos.mV[VY];
  580. LLGLSUIDefault gls_ui;
  581. LLGLDepthTest gls_depth(GL_TRUE);
  582. LLGLDisable cull(GL_CULL_FACE);
  583. if (mCollisionBanned == BA_BANNED)
  584. {
  585. collision_height = BAN_HEIGHT;
  586. }
  587. else
  588. {
  589. collision_height = PARCEL_HEIGHT;
  590. }
  591. if (use_pass && (mCollisionBanned == BA_NOT_ON_LIST))
  592. {
  593. gGL.getTexUnit(0)->bind(mPassImage);
  594. }
  595. else
  596. {
  597. gGL.getTexUnit(0)->bind(mBlockedImage);
  598. }
  599. gGL.begin(LLRender::QUADS);
  600. for (y = 0; y < STRIDE; y++)
  601. {
  602. for (x = 0; x < STRIDE; x++)
  603. {
  604. U8 segment_mask = segments[x + y*STRIDE];
  605. U8 direction;
  606. const F32 MAX_ALPHA = 0.95f;
  607. const S32 DIST_OFFSET = 5;
  608. const S32 MIN_DIST_SQ = DIST_OFFSET*DIST_OFFSET;
  609. const S32 MAX_DIST_SQ = 169;
  610. if (segment_mask & SOUTH_MASK)
  611. {
  612. x1 = x * PARCEL_GRID_STEP_METERS;
  613. y1 = y * PARCEL_GRID_STEP_METERS;
  614. x2 = x1 + PARCEL_GRID_STEP_METERS;
  615. y2 = y1;
  616. if (gRenderForSelect)
  617. {
  618. LLColor4U color((U8)(GL_NAME_PARCEL_WALL >> 16), (U8)(GL_NAME_PARCEL_WALL >> 8), (U8)GL_NAME_PARCEL_WALL);
  619. gGL.color4ubv(color.mV);
  620. }
  621. else
  622. {
  623. dy = (pos_y - y1) + DIST_OFFSET;
  624. if (pos_x < x1)
  625. dx = pos_x - x1;
  626. else if (pos_x > x2)
  627. dx = pos_x - x2;
  628. else 
  629. dx = 0;
  630. dist = dx*dx+dy*dy;
  631. if (dist < MIN_DIST_SQ)
  632. alpha = MAX_ALPHA;
  633. else if (dist > MAX_DIST_SQ)
  634. alpha = 0.0f;
  635. else
  636. alpha = 30/dist;
  637. alpha = llclamp(alpha, 0.0f, MAX_ALPHA);
  638. gGL.color4f(1.f, 1.f, 1.f, alpha);
  639. }
  640. if ((pos_y - y1) < 0) direction = SOUTH_MASK;
  641. else  direction = NORTH_MASK;
  642. // avoid Z fighting
  643. renderOneSegment(x1+0.1f, y1+0.1f, x2+0.1f, y2+0.1f, collision_height, direction, regionp);
  644. }
  645. if (segment_mask & WEST_MASK)
  646. {
  647. x1 = x * PARCEL_GRID_STEP_METERS;
  648. y1 = y * PARCEL_GRID_STEP_METERS;
  649. x2 = x1;
  650. y2 = y1 + PARCEL_GRID_STEP_METERS;
  651. if (gRenderForSelect)
  652. {
  653. LLColor4U color((U8)(GL_NAME_PARCEL_WALL >> 16), (U8)(GL_NAME_PARCEL_WALL >> 8), (U8)GL_NAME_PARCEL_WALL);
  654. gGL.color4ubv(color.mV);
  655. }
  656. else
  657. {
  658. dx = (pos_x - x1) + DIST_OFFSET;
  659. if (pos_y < y1) 
  660. dy = pos_y - y1;
  661. else if (pos_y > y2)
  662. dy = pos_y - y2;
  663. else 
  664. dy = 0;
  665. dist = dx*dx+dy*dy;
  666. if (dist < MIN_DIST_SQ) 
  667. alpha = MAX_ALPHA;
  668. else if (dist > MAX_DIST_SQ)
  669. alpha = 0.0f;
  670. else
  671. alpha = 30/dist;
  672. alpha = llclamp(alpha, 0.0f, MAX_ALPHA);
  673. gGL.color4f(1.f, 1.f, 1.f, alpha);
  674. }
  675. if ((pos_x - x1) > 0) direction = WEST_MASK;
  676. else  direction = EAST_MASK;
  677. // avoid Z fighting
  678. renderOneSegment(x1+0.1f, y1+0.1f, x2+0.1f, y2+0.1f, collision_height, direction, regionp);
  679. }
  680. }
  681. }
  682. gGL.end();
  683. }
  684. void draw_line_cube(F32 width, const LLVector3& center)
  685. {
  686. width = 0.5f * width;
  687. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] + width);
  688. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] + width);
  689. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] + width);
  690. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] + width);
  691. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] + width);
  692. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] + width);
  693. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] + width);
  694. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] + width);
  695. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] - width);
  696. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] - width);
  697. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] - width);
  698. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] - width);
  699. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] - width);
  700. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] - width);
  701. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] - width);
  702. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] - width);
  703. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] + width);
  704. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] - width);
  705. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] + width);
  706. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] - width);
  707. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] + width);
  708. gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] - width);
  709. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] + width);
  710. gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] - width);
  711. }
  712. void LLViewerObjectList::renderObjectBeacons()
  713. {
  714. if (mDebugBeacons.empty())
  715. {
  716. return;
  717. }
  718. LLGLSUIDefault gls_ui;
  719. {
  720. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  721. S32 last_line_width = -1;
  722. // gGL.begin(LLRender::LINES); // Always happens in (line_width != last_line_width)
  723. for (S32 i = 0; i < mDebugBeacons.count(); i++)
  724. {
  725. const LLDebugBeacon &debug_beacon = mDebugBeacons[i];
  726. LLColor4 color = debug_beacon.mColor;
  727. color.mV[3] *= 0.25f;
  728. S32 line_width = debug_beacon.mLineWidth;
  729. if (line_width != last_line_width)
  730. {
  731. if (i > 0)
  732. {
  733. gGL.end();
  734. gGL.flush();
  735. }
  736. glLineWidth( (F32)line_width );
  737. last_line_width = line_width;
  738. gGL.begin(LLRender::LINES);
  739. }
  740. const LLVector3 &thisline = debug_beacon.mPositionAgent;
  741. gGL.color4fv(color.mV);
  742. gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] - 50.f);
  743. gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] + 50.f);
  744. gGL.vertex3f(thisline.mV[VX] - 2.f,thisline.mV[VY],thisline.mV[VZ]);
  745. gGL.vertex3f(thisline.mV[VX] + 2.f,thisline.mV[VY],thisline.mV[VZ]);
  746. gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] - 2.f,thisline.mV[VZ]);
  747. gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] + 2.f,thisline.mV[VZ]);
  748. draw_line_cube(0.10f, thisline);
  749. }
  750. gGL.end();
  751. }
  752. {
  753. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  754. LLGLDepthTest gls_depth(GL_TRUE);
  755. S32 last_line_width = -1;
  756. // gGL.begin(LLRender::LINES); // Always happens in (line_width != last_line_width)
  757. for (S32 i = 0; i < mDebugBeacons.count(); i++)
  758. {
  759. const LLDebugBeacon &debug_beacon = mDebugBeacons[i];
  760. S32 line_width = debug_beacon.mLineWidth;
  761. if (line_width != last_line_width)
  762. {
  763. if (i > 0)
  764. {
  765. gGL.end();
  766. gGL.flush();
  767. }
  768. glLineWidth( (F32)line_width );
  769. last_line_width = line_width;
  770. gGL.begin(LLRender::LINES);
  771. }
  772. const LLVector3 &thisline = debug_beacon.mPositionAgent;
  773. gGL.color4fv(debug_beacon.mColor.mV);
  774. gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] - 0.5f);
  775. gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] + 0.5f);
  776. gGL.vertex3f(thisline.mV[VX] - 0.5f,thisline.mV[VY],thisline.mV[VZ]);
  777. gGL.vertex3f(thisline.mV[VX] + 0.5f,thisline.mV[VY],thisline.mV[VZ]);
  778. gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] - 0.5f,thisline.mV[VZ]);
  779. gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] + 0.5f,thisline.mV[VZ]);
  780. draw_line_cube(0.10f, thisline);
  781. }
  782. gGL.end();
  783. gGL.flush();
  784. glLineWidth(1.f);
  785. for (S32 i = 0; i < mDebugBeacons.count(); i++)
  786. {
  787. LLDebugBeacon &debug_beacon = mDebugBeacons[i];
  788. if (debug_beacon.mString == "")
  789. {
  790. continue;
  791. }
  792. LLHUDText *hud_textp = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
  793. hud_textp->setZCompare(FALSE);
  794. LLColor4 color;
  795. color = debug_beacon.mTextColor;
  796. color.mV[3] *= 1.f;
  797. hud_textp->setString(utf8str_to_wstring(debug_beacon.mString));
  798. hud_textp->setColor(color);
  799. hud_textp->setPositionAgent(debug_beacon.mPositionAgent);
  800. debug_beacon.mHUDObject = hud_textp;
  801. }
  802. }
  803. }