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

游戏引擎

开发平台:

C++ Builder

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