PageRenderTime 46ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/llmanip.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 612 lines | 479 code | 86 blank | 47 comment | 53 complexity | 1ae2b383832c995ecc4f0a707cb564b3 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llmanip.cpp
  3. * @brief LLManip class implementation
  4. *
  5. * $LicenseInfo:firstyear=2001&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. #include "llviewerprecompiledheaders.h"
  27. #include "llmanip.h"
  28. #include "llmath.h"
  29. #include "v3math.h"
  30. #include "llgl.h"
  31. #include "llrender.h"
  32. #include "llprimitive.h"
  33. #include "llview.h"
  34. #include "llviewertexturelist.h"
  35. #include "llagent.h"
  36. #include "llagentcamera.h"
  37. #include "llviewercontrol.h"
  38. #include "lldrawable.h"
  39. #include "llfontgl.h"
  40. #include "llhudrender.h"
  41. #include "llselectmgr.h"
  42. #include "llui.h"
  43. #include "llviewercamera.h"
  44. #include "llviewerjoint.h"
  45. #include "llviewerobject.h"
  46. #include "llviewerwindow.h"
  47. #include "llvoavatar.h"
  48. #include "llworld.h" // for LLWorld::getInstance()
  49. #include "llresmgr.h"
  50. #include "pipeline.h"
  51. #include "llglheaders.h"
  52. // Local constants...
  53. const S32 VERTICAL_OFFSET = 50;
  54. F32 LLManip::sHelpTextVisibleTime = 2.f;
  55. F32 LLManip::sHelpTextFadeTime = 2.f;
  56. S32 LLManip::sNumTimesHelpTextShown = 0;
  57. S32 LLManip::sMaxTimesShowHelpText = 5;
  58. F32 LLManip::sGridMaxSubdivisionLevel = 32.f;
  59. F32 LLManip::sGridMinSubdivisionLevel = 1.f;
  60. LLVector2 LLManip::sTickLabelSpacing(60.f, 25.f);
  61. //static
  62. void LLManip::rebuild(LLViewerObject* vobj)
  63. {
  64. LLDrawable* drawablep = vobj->mDrawable;
  65. if (drawablep && drawablep->getVOVolume())
  66. {
  67. gPipeline.markRebuild(drawablep,LLDrawable::REBUILD_VOLUME, TRUE);
  68. drawablep->setState(LLDrawable::MOVE_UNDAMPED); // force to UNDAMPED
  69. drawablep->updateMove();
  70. LLSpatialGroup* group = drawablep->getSpatialGroup();
  71. if (group)
  72. {
  73. group->dirtyGeom();
  74. gPipeline.markRebuild(group, TRUE);
  75. }
  76. }
  77. }
  78. //////////////////////////////////////////////////////////////////////////////
  79. // LLManip
  80. LLManip::LLManip( const std::string& name, LLToolComposite* composite )
  81. :
  82. LLTool( name, composite ),
  83. mInSnapRegime(FALSE),
  84. mHighlightedPart(LL_NO_PART),
  85. mManipPart(LL_NO_PART)
  86. {
  87. }
  88. void LLManip::getManipNormal(LLViewerObject* object, EManipPart manip, LLVector3 &normal)
  89. {
  90. LLVector3 grid_origin;
  91. LLVector3 grid_scale;
  92. LLQuaternion grid_rotation;
  93. LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
  94. if (manip >= LL_X_ARROW && manip <= LL_Z_ARROW)
  95. {
  96. LLVector3 arrow_axis;
  97. getManipAxis(object, manip, arrow_axis);
  98. LLVector3 cross = arrow_axis % LLViewerCamera::getInstance()->getAtAxis();
  99. normal = cross % arrow_axis;
  100. normal.normVec();
  101. }
  102. else if (manip >= LL_YZ_PLANE && manip <= LL_XY_PLANE)
  103. {
  104. switch (manip)
  105. {
  106. case LL_YZ_PLANE:
  107. normal = LLVector3::x_axis;
  108. break;
  109. case LL_XZ_PLANE:
  110. normal = LLVector3::y_axis;
  111. break;
  112. case LL_XY_PLANE:
  113. normal = LLVector3::z_axis;
  114. break;
  115. default:
  116. break;
  117. }
  118. normal.rotVec(grid_rotation);
  119. }
  120. else
  121. {
  122. normal.clearVec();
  123. }
  124. }
  125. BOOL LLManip::getManipAxis(LLViewerObject* object, EManipPart manip, LLVector3 &axis)
  126. {
  127. LLVector3 grid_origin;
  128. LLVector3 grid_scale;
  129. LLQuaternion grid_rotation;
  130. LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
  131. if (manip == LL_X_ARROW)
  132. {
  133. axis = LLVector3::x_axis;
  134. }
  135. else if (manip == LL_Y_ARROW)
  136. {
  137. axis = LLVector3::y_axis;
  138. }
  139. else if (manip == LL_Z_ARROW)
  140. {
  141. axis = LLVector3::z_axis;
  142. }
  143. else
  144. {
  145. return FALSE;
  146. }
  147. axis.rotVec( grid_rotation );
  148. return TRUE;
  149. }
  150. F32 LLManip::getSubdivisionLevel(const LLVector3 &reference_point, const LLVector3 &translate_axis, F32 grid_scale, S32 min_pixel_spacing)
  151. {
  152. //update current snap subdivision level
  153. LLVector3 cam_to_reference;
  154. if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
  155. {
  156. cam_to_reference = LLVector3(1.f / gAgentCamera.mHUDCurZoom, 0.f, 0.f);
  157. }
  158. else
  159. {
  160. cam_to_reference = reference_point - LLViewerCamera::getInstance()->getOrigin();
  161. }
  162. F32 current_range = cam_to_reference.normVec();
  163. F32 projected_translation_axis_length = (translate_axis % cam_to_reference).magVec();
  164. F32 subdivisions = llmax(projected_translation_axis_length * grid_scale / (current_range / LLViewerCamera::getInstance()->getPixelMeterRatio() * min_pixel_spacing), 0.f);
  165. subdivisions = llclamp((F32)pow(2.f, llfloor(log(subdivisions) / log(2.f))), 1.f / 32.f, 32.f);
  166. return subdivisions;
  167. }
  168. void LLManip::handleSelect()
  169. {
  170. mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
  171. }
  172. void LLManip::handleDeselect()
  173. {
  174. mHighlightedPart = LL_NO_PART;
  175. mManipPart = LL_NO_PART;
  176. mObjectSelection = NULL;
  177. }
  178. LLObjectSelectionHandle LLManip::getSelection()
  179. {
  180. return mObjectSelection;
  181. }
  182. BOOL LLManip::handleHover(S32 x, S32 y, MASK mask)
  183. {
  184. // We only handle the event if mousedown started with us
  185. if( hasMouseCapture() )
  186. {
  187. if( mObjectSelection->isEmpty() )
  188. {
  189. // Somehow the object got deselected while we were dragging it.
  190. // Release the mouse
  191. setMouseCapture( FALSE );
  192. }
  193. lldebugst(LLERR_USER_INPUT) << "hover handled by LLManip (active)" << llendl;
  194. }
  195. else
  196. {
  197. lldebugst(LLERR_USER_INPUT) << "hover handled by LLManip (inactive)" << llendl;
  198. }
  199. gViewerWindow->setCursor(UI_CURSOR_ARROW);
  200. return TRUE;
  201. }
  202. BOOL LLManip::handleMouseUp(S32 x, S32 y, MASK mask)
  203. {
  204. BOOL handled = FALSE;
  205. if( hasMouseCapture() )
  206. {
  207. handled = TRUE;
  208. setMouseCapture( FALSE );
  209. }
  210. return handled;
  211. }
  212. void LLManip::updateGridSettings()
  213. {
  214. sGridMaxSubdivisionLevel = gSavedSettings.getBOOL("GridSubUnit") ? (F32)gSavedSettings.getS32("GridSubdivision") : 1.f;
  215. }
  216. BOOL LLManip::getMousePointOnPlaneAgent(LLVector3& point, S32 x, S32 y, LLVector3 origin, LLVector3 normal)
  217. {
  218. LLVector3d origin_double = gAgent.getPosGlobalFromAgent(origin);
  219. LLVector3d global_point;
  220. BOOL result = getMousePointOnPlaneGlobal(global_point, x, y, origin_double, normal);
  221. point = gAgent.getPosAgentFromGlobal(global_point);
  222. return result;
  223. }
  224. BOOL LLManip::getMousePointOnPlaneGlobal(LLVector3d& point, S32 x, S32 y, LLVector3d origin, LLVector3 normal) const
  225. {
  226. if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
  227. {
  228. BOOL result = FALSE;
  229. F32 mouse_x = ((F32)x / gViewerWindow->getWorldViewWidthScaled() - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgentCamera.mHUDCurZoom;
  230. F32 mouse_y = ((F32)y / gViewerWindow->getWorldViewHeightScaled() - 0.5f) / gAgentCamera.mHUDCurZoom;
  231. LLVector3 origin_agent = gAgent.getPosAgentFromGlobal(origin);
  232. LLVector3 mouse_pos = LLVector3(0.f, -mouse_x, mouse_y);
  233. if (llabs(normal.mV[VX]) < 0.001f)
  234. {
  235. // use largish value that should be outside HUD manipulation range
  236. mouse_pos.mV[VX] = 10.f;
  237. }
  238. else
  239. {
  240. mouse_pos.mV[VX] = (normal * (origin_agent - mouse_pos))
  241. / (normal.mV[VX]);
  242. result = TRUE;
  243. }
  244. point = gAgent.getPosGlobalFromAgent(mouse_pos);
  245. return result;
  246. }
  247. else
  248. {
  249. return gViewerWindow->mousePointOnPlaneGlobal(
  250. point, x, y, origin, normal );
  251. }
  252. //return FALSE;
  253. }
  254. // Given the line defined by mouse cursor (a1 + a_param*(a2-a1)) and the line defined by b1 + b_param*(b2-b1),
  255. // returns a_param and b_param for the points where lines are closest to each other.
  256. // Returns false if the two lines are parallel.
  257. BOOL LLManip::nearestPointOnLineFromMouse( S32 x, S32 y, const LLVector3& b1, const LLVector3& b2, F32 &a_param, F32 &b_param )
  258. {
  259. LLVector3 a1;
  260. LLVector3 a2;
  261. if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
  262. {
  263. F32 mouse_x = (((F32)x / gViewerWindow->getWindowWidthScaled()) - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgentCamera.mHUDCurZoom;
  264. F32 mouse_y = (((F32)y / gViewerWindow->getWindowHeightScaled()) - 0.5f) / gAgentCamera.mHUDCurZoom;
  265. a1 = LLVector3(llmin(b1.mV[VX] - 0.1f, b2.mV[VX] - 0.1f, 0.f), -mouse_x, mouse_y);
  266. a2 = a1 + LLVector3(1.f, 0.f, 0.f);
  267. }
  268. else
  269. {
  270. a1 = gAgentCamera.getCameraPositionAgent();
  271. a2 = gAgentCamera.getCameraPositionAgent() + LLVector3(gViewerWindow->mouseDirectionGlobal(x, y));
  272. }
  273. BOOL parallel = TRUE;
  274. LLVector3 a = a2 - a1;
  275. LLVector3 b = b2 - b1;
  276. LLVector3 normal;
  277. F32 dist, denom;
  278. normal = (b % a) % b; // normal to plane (P) through b and (shortest line between a and b)
  279. normal.normVec();
  280. dist = b1 * normal; // distance from origin to P
  281. denom = normal * a;
  282. if( (denom < -F_APPROXIMATELY_ZERO) || (F_APPROXIMATELY_ZERO < denom) )
  283. {
  284. a_param = (dist - normal * a1) / denom;
  285. parallel = FALSE;
  286. }
  287. normal = (a % b) % a; // normal to plane (P) through a and (shortest line between a and b)
  288. normal.normVec();
  289. dist = a1 * normal; // distance from origin to P
  290. denom = normal * b;
  291. if( (denom < -F_APPROXIMATELY_ZERO) || (F_APPROXIMATELY_ZERO < denom) )
  292. {
  293. b_param = (dist - normal * b1) / denom;
  294. parallel = FALSE;
  295. }
  296. return parallel;
  297. }
  298. LLVector3 LLManip::getSavedPivotPoint() const
  299. {
  300. return LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent();
  301. }
  302. LLVector3 LLManip::getPivotPoint()
  303. {
  304. if (mObjectSelection->getFirstObject() && mObjectSelection->getObjectCount() == 1 && mObjectSelection->getSelectType() != SELECT_TYPE_HUD)
  305. {
  306. return mObjectSelection->getFirstObject()->getPivotPositionAgent();
  307. }
  308. return LLSelectMgr::getInstance()->getBBoxOfSelection().getCenterAgent();
  309. }
  310. void LLManip::renderGuidelines(BOOL draw_x, BOOL draw_y, BOOL draw_z)
  311. {
  312. LLVector3 grid_origin;
  313. LLQuaternion grid_rot;
  314. LLVector3 grid_scale;
  315. LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rot, grid_scale);
  316. const BOOL children_ok = TRUE;
  317. LLViewerObject* object = mObjectSelection->getFirstRootObject(children_ok);
  318. if (!object)
  319. {
  320. return;
  321. }
  322. //LLVector3 center_agent = LLSelectMgr::getInstance()->getBBoxOfSelection().getCenterAgent();
  323. LLVector3 center_agent = getPivotPoint();
  324. gGL.pushMatrix();
  325. {
  326. gGL.translatef(center_agent.mV[VX], center_agent.mV[VY], center_agent.mV[VZ]);
  327. F32 angle_radians, x, y, z;
  328. grid_rot.getAngleAxis(&angle_radians, &x, &y, &z);
  329. gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
  330. F32 region_size = LLWorld::getInstance()->getRegionWidthInMeters();
  331. const F32 LINE_ALPHA = 0.33f;
  332. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  333. LLUI::setLineWidth(1.5f);
  334. if (draw_x)
  335. {
  336. gGL.color4f(1.f, 0.f, 0.f, LINE_ALPHA);
  337. gGL.begin(LLRender::LINES);
  338. gGL.vertex3f( -region_size, 0.f, 0.f );
  339. gGL.vertex3f( region_size, 0.f, 0.f );
  340. gGL.end();
  341. }
  342. if (draw_y)
  343. {
  344. gGL.color4f(0.f, 1.f, 0.f, LINE_ALPHA);
  345. gGL.begin(LLRender::LINES);
  346. gGL.vertex3f( 0.f, -region_size, 0.f );
  347. gGL.vertex3f( 0.f, region_size, 0.f );
  348. gGL.end();
  349. }
  350. if (draw_z)
  351. {
  352. gGL.color4f(0.f, 0.f, 1.f, LINE_ALPHA);
  353. gGL.begin(LLRender::LINES);
  354. gGL.vertex3f( 0.f, 0.f, -region_size );
  355. gGL.vertex3f( 0.f, 0.f, region_size );
  356. gGL.end();
  357. }
  358. LLUI::setLineWidth(1.0f);
  359. }
  360. gGL.popMatrix();
  361. }
  362. void LLManip::renderXYZ(const LLVector3 &vec)
  363. {
  364. const S32 PAD = 10;
  365. std::string feedback_string;
  366. LLVector3 camera_pos = LLViewerCamera::getInstance()->getOrigin() + LLViewerCamera::getInstance()->getAtAxis();
  367. S32 window_center_x = gViewerWindow->getWorldViewRectScaled().getWidth() / 2;
  368. S32 window_center_y = gViewerWindow->getWorldViewRectScaled().getHeight() / 2;
  369. S32 vertical_offset = window_center_y - VERTICAL_OFFSET;
  370. gGL.pushMatrix();
  371. {
  372. LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Square");
  373. gViewerWindow->setup2DRender();
  374. const LLVector2& display_scale = gViewerWindow->getDisplayScale();
  375. gGL.scalef(display_scale.mV[VX], display_scale.mV[VY], 1.f);
  376. gGL.color4f(0.f, 0.f, 0.f, 0.7f);
  377. imagep->draw(
  378. window_center_x - 115,
  379. window_center_y + vertical_offset - PAD,
  380. 235,
  381. PAD * 2 + 10,
  382. LLColor4(0.f, 0.f, 0.f, 0.7f) );
  383. }
  384. gGL.popMatrix();
  385. gViewerWindow->setup3DRender();
  386. {
  387. LLFontGL* font = LLFontGL::getFontSansSerif();
  388. LLLocale locale(LLLocale::USER_LOCALE);
  389. LLGLDepthTest gls_depth(GL_FALSE);
  390. // render drop shadowed text
  391. feedback_string = llformat("X: %.3f", vec.mV[VX]);
  392. hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -102.f + 1.f, (F32)vertical_offset - 1.f, LLColor4::black, FALSE);
  393. feedback_string = llformat("Y: %.3f", vec.mV[VY]);
  394. hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -27.f + 1.f, (F32)vertical_offset - 1.f, LLColor4::black, FALSE);
  395. feedback_string = llformat("Z: %.3f", vec.mV[VZ]);
  396. hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, 48.f + 1.f, (F32)vertical_offset - 1.f, LLColor4::black, FALSE);
  397. // render text on top
  398. feedback_string = llformat("X: %.3f", vec.mV[VX]);
  399. hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -102.f, (F32)vertical_offset, LLColor4(1.f, 0.5f, 0.5f, 1.f), FALSE);
  400. gGL.diffuseColor3f(0.5f, 1.f, 0.5f);
  401. feedback_string = llformat("Y: %.3f", vec.mV[VY]);
  402. hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -27.f, (F32)vertical_offset, LLColor4(0.5f, 1.f, 0.5f, 1.f), FALSE);
  403. gGL.diffuseColor3f(0.5f, 0.5f, 1.f);
  404. feedback_string = llformat("Z: %.3f", vec.mV[VZ]);
  405. hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, 48.f, (F32)vertical_offset, LLColor4(0.5f, 0.5f, 1.f, 1.f), FALSE);
  406. }
  407. }
  408. void LLManip::renderTickText(const LLVector3& pos, const std::string& text, const LLColor4 &color)
  409. {
  410. const LLFontGL* big_fontp = LLFontGL::getFontSansSerif();
  411. BOOL hud_selection = mObjectSelection->getSelectType() == SELECT_TYPE_HUD;
  412. gGL.matrixMode(LLRender::MM_MODELVIEW);
  413. gGL.pushMatrix();
  414. LLVector3 render_pos = pos;
  415. if (hud_selection)
  416. {
  417. F32 zoom_amt = gAgentCamera.mHUDCurZoom;
  418. F32 inv_zoom_amt = 1.f / zoom_amt;
  419. // scale text back up to counter-act zoom level
  420. render_pos = pos * zoom_amt;
  421. gGL.scalef(inv_zoom_amt, inv_zoom_amt, inv_zoom_amt);
  422. }
  423. // render shadow first
  424. LLColor4 shadow_color = LLColor4::black;
  425. shadow_color.mV[VALPHA] = color.mV[VALPHA] * 0.5f;
  426. gViewerWindow->setup3DViewport(1, -1);
  427. hud_render_utf8text(text, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(text), 3.f, shadow_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
  428. gViewerWindow->setup3DViewport();
  429. hud_render_utf8text(text, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(text), 3.f, color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
  430. gGL.popMatrix();
  431. }
  432. void LLManip::renderTickValue(const LLVector3& pos, F32 value, const std::string& suffix, const LLColor4 &color)
  433. {
  434. LLLocale locale(LLLocale::USER_LOCALE);
  435. const LLFontGL* big_fontp = LLFontGL::getFontSansSerif();
  436. const LLFontGL* small_fontp = LLFontGL::getFontSansSerifSmall();
  437. std::string val_string;
  438. std::string fraction_string;
  439. F32 val_to_print = llround(value, 0.001f);
  440. S32 fractional_portion = llround(fmodf(llabs(val_to_print), 1.f) * 100.f);
  441. if (val_to_print < 0.f)
  442. {
  443. if (fractional_portion == 0)
  444. {
  445. val_string = llformat("-%d%s", lltrunc(llabs(val_to_print)), suffix.c_str());
  446. }
  447. else
  448. {
  449. val_string = llformat("-%d", lltrunc(llabs(val_to_print)));
  450. }
  451. }
  452. else
  453. {
  454. if (fractional_portion == 0)
  455. {
  456. val_string = llformat("%d%s", lltrunc(llabs(val_to_print)), suffix.c_str());
  457. }
  458. else
  459. {
  460. val_string = llformat("%d", lltrunc(val_to_print));
  461. }
  462. }
  463. BOOL hud_selection = mObjectSelection->getSelectType() == SELECT_TYPE_HUD;
  464. gGL.matrixMode(LLRender::MM_MODELVIEW);
  465. gGL.pushMatrix();
  466. LLVector3 render_pos = pos;
  467. if (hud_selection)
  468. {
  469. F32 zoom_amt = gAgentCamera.mHUDCurZoom;
  470. F32 inv_zoom_amt = 1.f / zoom_amt;
  471. // scale text back up to counter-act zoom level
  472. render_pos = pos * zoom_amt;
  473. gGL.scalef(inv_zoom_amt, inv_zoom_amt, inv_zoom_amt);
  474. }
  475. LLColor4 shadow_color = LLColor4::black;
  476. shadow_color.mV[VALPHA] = color.mV[VALPHA] * 0.5f;
  477. if (fractional_portion != 0)
  478. {
  479. fraction_string = llformat("%c%02d%s", LLResMgr::getInstance()->getDecimalPoint(), fractional_portion, suffix.c_str());
  480. gViewerWindow->setup3DViewport(1, -1);
  481. hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -1.f * big_fontp->getWidthF32(val_string), 3.f, shadow_color, hud_selection);
  482. hud_render_utf8text(fraction_string, render_pos, *small_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, 1.f, 3.f, shadow_color, hud_selection);
  483. gViewerWindow->setup3DViewport();
  484. hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -1.f * big_fontp->getWidthF32(val_string), 3.f, color, hud_selection);
  485. hud_render_utf8text(fraction_string, render_pos, *small_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, 1.f, 3.f, color, hud_selection);
  486. }
  487. else
  488. {
  489. gViewerWindow->setup3DViewport(1, -1);
  490. hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(val_string), 3.f, shadow_color, hud_selection);
  491. gViewerWindow->setup3DViewport();
  492. hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(val_string), 3.f, color, hud_selection);
  493. }
  494. gGL.popMatrix();
  495. }
  496. LLColor4 LLManip::setupSnapGuideRenderPass(S32 pass)
  497. {
  498. static LLColor4 grid_color_fg = LLUIColorTable::instance().getColor("GridlineColor");
  499. static LLColor4 grid_color_bg = LLUIColorTable::instance().getColor("GridlineBGColor");
  500. static LLColor4 grid_color_shadow = LLUIColorTable::instance().getColor("GridlineShadowColor");
  501. LLColor4 line_color;
  502. F32 line_alpha = gSavedSettings.getF32("GridOpacity");
  503. switch(pass)
  504. {
  505. case 0:
  506. // shadow
  507. gViewerWindow->setup3DViewport(1, -1);
  508. line_color = grid_color_shadow;
  509. line_color.mV[VALPHA] *= line_alpha;
  510. LLUI::setLineWidth(2.f);
  511. break;
  512. case 1:
  513. // hidden lines
  514. gViewerWindow->setup3DViewport();
  515. line_color = grid_color_bg;
  516. line_color.mV[VALPHA] *= line_alpha;
  517. LLUI::setLineWidth(1.f);
  518. break;
  519. case 2:
  520. // visible lines
  521. line_color = grid_color_fg;
  522. line_color.mV[VALPHA] *= line_alpha;
  523. break;
  524. }
  525. return line_color;
  526. }