diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llmanip.cpp | |
parent | README.txt (diff) | |
download | meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2 meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz |
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/newview/llmanip.cpp')
-rw-r--r-- | linden/indra/newview/llmanip.cpp | 602 |
1 files changed, 602 insertions, 0 deletions
diff --git a/linden/indra/newview/llmanip.cpp b/linden/indra/newview/llmanip.cpp new file mode 100644 index 0000000..538e6df --- /dev/null +++ b/linden/indra/newview/llmanip.cpp | |||
@@ -0,0 +1,602 @@ | |||
1 | /** | ||
2 | * @file llmanip.cpp | ||
3 | * @brief LLManip class implementation | ||
4 | * | ||
5 | * Copyright (c) 2001-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #include "llviewerprecompiledheaders.h" | ||
29 | |||
30 | #include "llmanip.h" | ||
31 | |||
32 | #include "llmath.h" | ||
33 | #include "v3math.h" | ||
34 | //#include "llquaternion.h" | ||
35 | #include "llgl.h" | ||
36 | #include "llprimitive.h" | ||
37 | #include "llview.h" | ||
38 | #include "llviewerimagelist.h" | ||
39 | |||
40 | #include "llagent.h" | ||
41 | #include "llviewercontrol.h" | ||
42 | #include "lldrawable.h" | ||
43 | #include "llfontgl.h" | ||
44 | #include "llhudrender.h" | ||
45 | #include "llselectmgr.h" | ||
46 | #include "llui.h" | ||
47 | #include "llviewercamera.h" | ||
48 | #include "llviewerjoint.h" | ||
49 | #include "llviewerobject.h" | ||
50 | #include "llviewerwindow.h" | ||
51 | #include "llvoavatar.h" | ||
52 | #include "llworld.h" // for gWorldPointer | ||
53 | #include "llresmgr.h" | ||
54 | #include "viewer.h" // for gFPS | ||
55 | #include "pipeline.h" | ||
56 | #include "llglheaders.h" | ||
57 | |||
58 | // Local constants... | ||
59 | const S32 VERTICAL_OFFSET = 50; | ||
60 | |||
61 | F32 LLManip::sHelpTextVisibleTime = 2.f; | ||
62 | F32 LLManip::sHelpTextFadeTime = 2.f; | ||
63 | S32 LLManip::sNumTimesHelpTextShown = 0; | ||
64 | S32 LLManip::sMaxTimesShowHelpText = 5; | ||
65 | F32 LLManip::sGridMaxSubdivisionLevel = 32.f; | ||
66 | F32 LLManip::sGridMinSubdivisionLevel = 1.f; | ||
67 | LLVector2 LLManip::sTickLabelSpacing(60.f, 25.f); | ||
68 | |||
69 | |||
70 | //static | ||
71 | void LLManip::rebuild(LLViewerObject* vobj) | ||
72 | { | ||
73 | LLDrawable* drawablep = vobj->mDrawable; | ||
74 | if (drawablep && drawablep->getVOVolume()) | ||
75 | { | ||
76 | |||
77 | gPipeline.markRebuild(drawablep,LLDrawable::REBUILD_VOLUME, TRUE); | ||
78 | //gPipeline.markMoved(drawablep, FALSE); | ||
79 | //gPipeline.updateMoveNormalAsync(vobj->mDrawable); | ||
80 | |||
81 | drawablep->setState(LLDrawable::MOVE_UNDAMPED); // force to UNDAMPED | ||
82 | drawablep->updateMove(); | ||
83 | } | ||
84 | } | ||
85 | |||
86 | ////////////////////////////////////////////////////////////////////////////// | ||
87 | // LLManip | ||
88 | |||
89 | |||
90 | LLManip::LLManip( const LLString& name, LLToolComposite* composite ) | ||
91 | : | ||
92 | LLTool( name, composite ), | ||
93 | mInSnapRegime(FALSE) | ||
94 | {} | ||
95 | |||
96 | |||
97 | void LLManip::getManipNormal(LLViewerObject* object, EManipPart manip, LLVector3 &normal) | ||
98 | { | ||
99 | LLVector3 grid_origin; | ||
100 | LLVector3 grid_scale; | ||
101 | LLQuaternion grid_rotation; | ||
102 | |||
103 | gSelectMgr->getGrid(grid_origin, grid_rotation, grid_scale); | ||
104 | |||
105 | if (manip >= LL_X_ARROW && manip <= LL_Z_ARROW) | ||
106 | { | ||
107 | LLVector3 arrow_axis; | ||
108 | getManipAxis(object, manip, arrow_axis); | ||
109 | |||
110 | LLVector3 origin_dir = grid_origin - gCamera->getOrigin(); | ||
111 | origin_dir.normVec(); | ||
112 | LLVector3 cross = arrow_axis % origin_dir; | ||
113 | normal = cross % arrow_axis; | ||
114 | normal.normVec(); | ||
115 | } | ||
116 | else if (manip >= LL_YZ_PLANE && manip <= LL_XY_PLANE) | ||
117 | { | ||
118 | switch (manip) | ||
119 | { | ||
120 | case LL_YZ_PLANE: | ||
121 | normal = LLVector3::x_axis; | ||
122 | break; | ||
123 | case LL_XZ_PLANE: | ||
124 | normal = LLVector3::y_axis; | ||
125 | break; | ||
126 | case LL_XY_PLANE: | ||
127 | normal = LLVector3::z_axis; | ||
128 | break; | ||
129 | default: | ||
130 | break; | ||
131 | } | ||
132 | normal.rotVec(grid_rotation); | ||
133 | } | ||
134 | else | ||
135 | { | ||
136 | normal.clearVec(); | ||
137 | } | ||
138 | } | ||
139 | |||
140 | |||
141 | BOOL LLManip::getManipAxis(LLViewerObject* object, EManipPart manip, LLVector3 &axis) | ||
142 | { | ||
143 | LLVector3 grid_origin; | ||
144 | LLVector3 grid_scale; | ||
145 | LLQuaternion grid_rotation; | ||
146 | |||
147 | gSelectMgr->getGrid(grid_origin, grid_rotation, grid_scale); | ||
148 | |||
149 | if (manip == LL_X_ARROW) | ||
150 | { | ||
151 | axis = LLVector3::x_axis; | ||
152 | } | ||
153 | else if (manip == LL_Y_ARROW) | ||
154 | { | ||
155 | axis = LLVector3::y_axis; | ||
156 | } | ||
157 | else if (manip == LL_Z_ARROW) | ||
158 | { | ||
159 | axis = LLVector3::z_axis; | ||
160 | } | ||
161 | else | ||
162 | { | ||
163 | return FALSE; | ||
164 | } | ||
165 | |||
166 | axis.rotVec( grid_rotation ); | ||
167 | return TRUE; | ||
168 | } | ||
169 | |||
170 | F32 LLManip::getSubdivisionLevel(const LLVector3 &reference_point, const LLVector3 &translate_axis, F32 grid_scale, S32 min_pixel_spacing) | ||
171 | { | ||
172 | //update current snap subdivision level | ||
173 | LLVector3 cam_to_reference; | ||
174 | if (gSelectMgr->getSelectType() == SELECT_TYPE_HUD) | ||
175 | { | ||
176 | cam_to_reference = LLVector3(1.f / gAgent.getAvatarObject()->mHUDCurZoom, 0.f, 0.f); | ||
177 | } | ||
178 | else | ||
179 | { | ||
180 | cam_to_reference = reference_point - gCamera->getOrigin(); | ||
181 | } | ||
182 | F32 current_range = cam_to_reference.normVec(); | ||
183 | |||
184 | F32 projected_translation_axis_length = (translate_axis % cam_to_reference).magVec(); | ||
185 | F32 subdivisions = llmax(projected_translation_axis_length * grid_scale / (current_range / gCamera->getPixelMeterRatio() * min_pixel_spacing), 0.f); | ||
186 | subdivisions = llclamp((F32)pow(2.f, llfloor(log(subdivisions) / log(2.f))), 1.f / 32.f, 32.f); | ||
187 | |||
188 | return subdivisions; | ||
189 | } | ||
190 | |||
191 | BOOL LLManip::handleHover(S32 x, S32 y, MASK mask) | ||
192 | { | ||
193 | // We only handle the event if mousedown started with us | ||
194 | if( hasMouseCapture() ) | ||
195 | { | ||
196 | if( gSelectMgr->isEmpty() ) | ||
197 | { | ||
198 | // Somehow the object got deselected while we were dragging it. | ||
199 | // Release the mouse | ||
200 | setMouseCapture( FALSE ); | ||
201 | } | ||
202 | |||
203 | lldebugst(LLERR_USER_INPUT) << "hover handled by LLManip (active)" << llendl; | ||
204 | } | ||
205 | else | ||
206 | { | ||
207 | lldebugst(LLERR_USER_INPUT) << "hover handled by LLManip (inactive)" << llendl; | ||
208 | } | ||
209 | gViewerWindow->setCursor(UI_CURSOR_ARROW); | ||
210 | return TRUE; | ||
211 | } | ||
212 | |||
213 | |||
214 | BOOL LLManip::handleMouseUp(S32 x, S32 y, MASK mask) | ||
215 | { | ||
216 | BOOL handled = FALSE; | ||
217 | if( hasMouseCapture() ) | ||
218 | { | ||
219 | handled = TRUE; | ||
220 | setMouseCapture( FALSE ); | ||
221 | } | ||
222 | return handled; | ||
223 | } | ||
224 | |||
225 | void LLManip::updateGridSettings() | ||
226 | { | ||
227 | sGridMaxSubdivisionLevel = gSavedSettings.getBOOL("GridSubUnit") ? (F32)gSavedSettings.getS32("GridSubdivision") : 1.f; | ||
228 | } | ||
229 | |||
230 | BOOL LLManip::getMousePointOnPlaneAgent(LLVector3& point, S32 x, S32 y, LLVector3 origin, LLVector3 normal) | ||
231 | { | ||
232 | LLVector3d origin_double = gAgent.getPosGlobalFromAgent(origin); | ||
233 | LLVector3d global_point; | ||
234 | BOOL result = getMousePointOnPlaneGlobal(global_point, x, y, origin_double, normal); | ||
235 | point = gAgent.getPosAgentFromGlobal(global_point); | ||
236 | return result; | ||
237 | } | ||
238 | |||
239 | BOOL LLManip::getMousePointOnPlaneGlobal(LLVector3d& point, S32 x, S32 y, LLVector3d origin, LLVector3 normal) | ||
240 | { | ||
241 | if (gSelectMgr->getSelectType() == SELECT_TYPE_HUD) | ||
242 | { | ||
243 | BOOL result = FALSE; | ||
244 | F32 mouse_x = ((F32)x / gViewerWindow->getWindowWidth() - 0.5f) * gCamera->getAspect() / gAgent.getAvatarObject()->mHUDCurZoom; | ||
245 | F32 mouse_y = ((F32)y / gViewerWindow->getWindowHeight() - 0.5f) / gAgent.getAvatarObject()->mHUDCurZoom; | ||
246 | |||
247 | LLVector3 origin_agent = gAgent.getPosAgentFromGlobal(origin); | ||
248 | LLVector3 mouse_pos = LLVector3(0.f, -mouse_x, mouse_y); | ||
249 | if (llabs(normal.mV[VX]) < 0.001f) | ||
250 | { | ||
251 | // use largish value that should be outside HUD manipulation range | ||
252 | mouse_pos.mV[VX] = 10.f; | ||
253 | } | ||
254 | else | ||
255 | { | ||
256 | mouse_pos.mV[VX] = (normal * (origin_agent - mouse_pos)) | ||
257 | / (normal.mV[VX]); | ||
258 | result = TRUE; | ||
259 | } | ||
260 | |||
261 | point = gAgent.getPosGlobalFromAgent(mouse_pos); | ||
262 | return result; | ||
263 | } | ||
264 | else | ||
265 | { | ||
266 | return gViewerWindow->mousePointOnPlaneGlobal( | ||
267 | point, x, y, origin, normal ); | ||
268 | } | ||
269 | |||
270 | //return FALSE; | ||
271 | } | ||
272 | |||
273 | // Given the line defined by mouse cursor (a1 + a_param*(a2-a1)) and the line defined by b1 + b_param*(b2-b1), | ||
274 | // returns a_param and b_param for the points where lines are closest to each other. | ||
275 | // Returns false if the two lines are parallel. | ||
276 | BOOL LLManip::nearestPointOnLineFromMouse( S32 x, S32 y, const LLVector3& b1, const LLVector3& b2, F32 &a_param, F32 &b_param ) const | ||
277 | { | ||
278 | LLVector3 a1; | ||
279 | LLVector3 a2; | ||
280 | |||
281 | if (gSelectMgr->getSelectType() == SELECT_TYPE_HUD) | ||
282 | { | ||
283 | F32 mouse_x = (((F32)x / gViewerWindow->getWindowWidth()) - 0.5f) * gCamera->getAspect() / gAgent.getAvatarObject()->mHUDCurZoom; | ||
284 | F32 mouse_y = (((F32)y / gViewerWindow->getWindowHeight()) - 0.5f) / gAgent.getAvatarObject()->mHUDCurZoom; | ||
285 | a1 = LLVector3(llmin(b1.mV[VX] - 0.1f, b2.mV[VX] - 0.1f, 0.f), -mouse_x, mouse_y); | ||
286 | a2 = a1 + LLVector3(1.f, 0.f, 0.f); | ||
287 | } | ||
288 | else | ||
289 | { | ||
290 | a1 = gAgent.getCameraPositionAgent(); | ||
291 | a2 = gAgent.getCameraPositionAgent() + LLVector3(gViewerWindow->mouseDirectionGlobal(x, y)); | ||
292 | } | ||
293 | |||
294 | BOOL parallel = TRUE; | ||
295 | LLVector3 a = a2 - a1; | ||
296 | LLVector3 b = b2 - b1; | ||
297 | |||
298 | LLVector3 normal; | ||
299 | F32 dist, denom; | ||
300 | normal = (b % a) % b; // normal to plane (P) through b and (shortest line between a and b) | ||
301 | normal.normVec(); | ||
302 | dist = b1 * normal; // distance from origin to P | ||
303 | |||
304 | denom = normal * a; | ||
305 | if( (denom < -F_APPROXIMATELY_ZERO) || (F_APPROXIMATELY_ZERO < denom) ) | ||
306 | { | ||
307 | a_param = (dist - normal * a1) / denom; | ||
308 | parallel = FALSE; | ||
309 | } | ||
310 | |||
311 | normal = (a % b) % a; // normal to plane (P) through a and (shortest line between a and b) | ||
312 | normal.normVec(); | ||
313 | dist = a1 * normal; // distance from origin to P | ||
314 | denom = normal * b; | ||
315 | if( (denom < -F_APPROXIMATELY_ZERO) || (F_APPROXIMATELY_ZERO < denom) ) | ||
316 | { | ||
317 | b_param = (dist - normal * b1) / denom; | ||
318 | parallel = FALSE; | ||
319 | } | ||
320 | |||
321 | return parallel; | ||
322 | } | ||
323 | |||
324 | LLVector3 LLManip::getSavedPivotPoint() const | ||
325 | { | ||
326 | return gSelectMgr->getSavedBBoxOfSelection().getCenterAgent(); | ||
327 | } | ||
328 | |||
329 | LLVector3 LLManip::getPivotPoint() const | ||
330 | { | ||
331 | if (gSelectMgr->getFirstObject() && gSelectMgr->getObjectCount() == 1 && gSelectMgr->getSelectType() != SELECT_TYPE_HUD) | ||
332 | { | ||
333 | return gSelectMgr->getFirstObject()->getPivotPositionAgent(); | ||
334 | } | ||
335 | return gSelectMgr->getBBoxOfSelection().getCenterAgent(); | ||
336 | } | ||
337 | |||
338 | |||
339 | void LLManip::renderGuidelines(BOOL draw_x, BOOL draw_y, BOOL draw_z) | ||
340 | { | ||
341 | LLVector3 grid_origin; | ||
342 | LLQuaternion grid_rot; | ||
343 | LLVector3 grid_scale; | ||
344 | gSelectMgr->getGrid(grid_origin, grid_rot, grid_scale); | ||
345 | |||
346 | LLViewerObject* object = gSelectMgr->getFirstRootObject(); | ||
347 | if (!object) | ||
348 | { | ||
349 | object = gSelectMgr->getFirstObject(); | ||
350 | if (!object) | ||
351 | { | ||
352 | return; | ||
353 | } | ||
354 | } | ||
355 | |||
356 | //LLVector3 center_agent = gSelectMgr->getBBoxOfSelection().getCenterAgent(); | ||
357 | LLVector3 center_agent = getPivotPoint(); | ||
358 | |||
359 | glPushMatrix(); | ||
360 | { | ||
361 | glTranslatef(center_agent.mV[VX], center_agent.mV[VY], center_agent.mV[VZ]); | ||
362 | |||
363 | F32 angle_radians, x, y, z; | ||
364 | |||
365 | grid_rot.getAngleAxis(&angle_radians, &x, &y, &z); | ||
366 | glRotatef(angle_radians * RAD_TO_DEG, x, y, z); | ||
367 | |||
368 | F32 region_size = gWorldPointer->getRegionWidthInMeters(); | ||
369 | |||
370 | const F32 LINE_ALPHA = 0.33f; | ||
371 | |||
372 | LLGLSNoTexture gls_no_texture; | ||
373 | LLUI::setLineWidth(1.5f); | ||
374 | |||
375 | if (draw_x) | ||
376 | { | ||
377 | glColor4f(1.f, 0.f, 0.f, LINE_ALPHA); | ||
378 | glBegin(GL_LINES); | ||
379 | glVertex3f( -region_size, 0.f, 0.f ); | ||
380 | glVertex3f( region_size, 0.f, 0.f ); | ||
381 | glEnd(); | ||
382 | } | ||
383 | |||
384 | if (draw_y) | ||
385 | { | ||
386 | glColor4f(0.f, 1.f, 0.f, LINE_ALPHA); | ||
387 | glBegin(GL_LINES); | ||
388 | glVertex3f( 0.f, -region_size, 0.f ); | ||
389 | glVertex3f( 0.f, region_size, 0.f ); | ||
390 | glEnd(); | ||
391 | } | ||
392 | |||
393 | if (draw_z) | ||
394 | { | ||
395 | glColor4f(0.f, 0.f, 1.f, LINE_ALPHA); | ||
396 | glBegin(GL_LINES); | ||
397 | glVertex3f( 0.f, 0.f, -region_size ); | ||
398 | glVertex3f( 0.f, 0.f, region_size ); | ||
399 | glEnd(); | ||
400 | } | ||
401 | LLUI::setLineWidth(1.0f); | ||
402 | } | ||
403 | glPopMatrix(); | ||
404 | } | ||
405 | |||
406 | void LLManip::renderXYZ(const LLVector3 &vec) | ||
407 | { | ||
408 | const S32 PAD = 10; | ||
409 | char feedback_string[128]; | ||
410 | LLVector3 camera_pos = gCamera->getOrigin() + gCamera->getAtAxis(); | ||
411 | S32 vertical_offset = gViewerWindow->getWindowHeight() / 2 - VERTICAL_OFFSET; | ||
412 | S32 window_center_x = gViewerWindow->getWindowWidth() / 2; | ||
413 | S32 window_center_y = gViewerWindow->getWindowHeight() / 2; | ||
414 | |||
415 | LLUUID image_id; | ||
416 | image_id.set(gViewerArt.getString("rounded_square.tga")); | ||
417 | LLViewerImage* imagep = gImageList.getImage(image_id, MIPMAP_FALSE, TRUE); | ||
418 | |||
419 | glPushMatrix(); | ||
420 | { | ||
421 | gViewerWindow->setup2DRender(); | ||
422 | const LLVector2& display_scale = gViewerWindow->getDisplayScale(); | ||
423 | glScalef(display_scale.mV[VX], display_scale.mV[VY], 1.f); | ||
424 | glColor4f(0.f, 0.f, 0.f, 0.7f); | ||
425 | |||
426 | gl_draw_scaled_image_with_border(window_center_x - 115, | ||
427 | window_center_y + vertical_offset - PAD, | ||
428 | 16, | ||
429 | 16, | ||
430 | 235, | ||
431 | PAD * 2 + 10, | ||
432 | imagep, | ||
433 | LLColor4(0.f, 0.f, 0.f, 0.7f) ); | ||
434 | } | ||
435 | glPopMatrix(); | ||
436 | |||
437 | gViewerWindow->setup3DRender(); | ||
438 | |||
439 | { | ||
440 | LLLocale locale(LLLocale::USER_LOCALE); | ||
441 | LLGLDepthTest gls_depth(GL_FALSE); | ||
442 | LLGLEnable tex(GL_TEXTURE_2D); | ||
443 | // render drop shadowed text | ||
444 | sprintf(feedback_string, "X: %.3f", vec.mV[VX]); | ||
445 | hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *gResMgr->getRes( LLFONT_SANSSERIF ), LLFontGL::NORMAL, -102.f + 1.f, (F32)vertical_offset - 1.f, LLColor4::black, FALSE); | ||
446 | |||
447 | sprintf(feedback_string, "Y: %.3f", vec.mV[VY]); | ||
448 | hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *gResMgr->getRes( LLFONT_SANSSERIF ), LLFontGL::NORMAL, -27.f + 1.f, (F32)vertical_offset - 1.f, LLColor4::black, FALSE); | ||
449 | |||
450 | sprintf(feedback_string, "Z: %.3f", vec.mV[VZ]); | ||
451 | hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *gResMgr->getRes( LLFONT_SANSSERIF ), LLFontGL::NORMAL, 48.f + 1.f, (F32)vertical_offset - 1.f, LLColor4::black, FALSE); | ||
452 | |||
453 | // render text on top | ||
454 | sprintf(feedback_string, "X: %.3f", vec.mV[VX]); | ||
455 | hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *gResMgr->getRes( LLFONT_SANSSERIF ), LLFontGL::NORMAL, -102.f, (F32)vertical_offset, LLColor4(1.f, 0.5f, 0.5f, 1.f), FALSE); | ||
456 | |||
457 | glColor3f(0.5f, 1.f, 0.5f); | ||
458 | sprintf(feedback_string, "Y: %.3f", vec.mV[VY]); | ||
459 | hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *gResMgr->getRes( LLFONT_SANSSERIF ), LLFontGL::NORMAL, -27.f, (F32)vertical_offset, LLColor4(0.5f, 1.f, 0.5f, 1.f), FALSE); | ||
460 | |||
461 | glColor3f(0.5f, 0.5f, 1.f); | ||
462 | sprintf(feedback_string, "Z: %.3f", vec.mV[VZ]); | ||
463 | hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *gResMgr->getRes( LLFONT_SANSSERIF ), LLFontGL::NORMAL, 48.f, (F32)vertical_offset, LLColor4(0.5f, 0.5f, 1.f, 1.f), FALSE); | ||
464 | } | ||
465 | } | ||
466 | |||
467 | void LLManip::renderTickText(const LLVector3& pos, const char* text, const LLColor4 &color) | ||
468 | { | ||
469 | const LLFontGL* big_fontp = gResMgr->getRes( LLFONT_SANSSERIF ); | ||
470 | |||
471 | BOOL hud_selection = gSelectMgr->getSelectType() == SELECT_TYPE_HUD; | ||
472 | glMatrixMode(GL_MODELVIEW); | ||
473 | glPushMatrix(); | ||
474 | LLVector3 render_pos = pos; | ||
475 | if (hud_selection) | ||
476 | { | ||
477 | F32 zoom_amt = gAgent.getAvatarObject()->mHUDCurZoom; | ||
478 | F32 inv_zoom_amt = 1.f / zoom_amt; | ||
479 | // scale text back up to counter-act zoom level | ||
480 | render_pos = pos * zoom_amt; | ||
481 | glScalef(inv_zoom_amt, inv_zoom_amt, inv_zoom_amt); | ||
482 | } | ||
483 | |||
484 | // render shadow first | ||
485 | LLColor4 shadow_color = LLColor4::black; | ||
486 | LLGLEnable tex(GL_TEXTURE_2D); | ||
487 | shadow_color.mV[VALPHA] = color.mV[VALPHA] * 0.5f; | ||
488 | gViewerWindow->setupViewport(1, -1); | ||
489 | hud_render_utf8text(text, render_pos, *big_fontp, LLFontGL::NORMAL, -0.5f * big_fontp->getWidthF32(text), 3.f, shadow_color, gSelectMgr->getSelectType() == SELECT_TYPE_HUD); | ||
490 | gViewerWindow->setupViewport(); | ||
491 | hud_render_utf8text(text, render_pos, *big_fontp, LLFontGL::NORMAL, -0.5f * big_fontp->getWidthF32(text), 3.f, color, gSelectMgr->getSelectType() == SELECT_TYPE_HUD); | ||
492 | |||
493 | glPopMatrix(); | ||
494 | } | ||
495 | |||
496 | void LLManip::renderTickValue(const LLVector3& pos, F32 value, const char* suffix, const LLColor4 &color) | ||
497 | { | ||
498 | LLLocale locale(LLLocale::USER_LOCALE); | ||
499 | |||
500 | const LLFontGL* big_fontp = gResMgr->getRes( LLFONT_SANSSERIF ); | ||
501 | const LLFontGL* small_fontp = gResMgr->getRes( LLFONT_SANSSERIF_SMALL ); | ||
502 | |||
503 | char val_string[128]; | ||
504 | char fraction_string[128]; | ||
505 | F32 val_to_print = llround(value, 0.001f); | ||
506 | S32 fractional_portion = llround(fmodf(llabs(val_to_print), 1.f) * 100.f); | ||
507 | if (val_to_print < 0.f) | ||
508 | { | ||
509 | if (fractional_portion == 0) | ||
510 | { | ||
511 | sprintf(val_string, "-%d%s", lltrunc(llabs(val_to_print)), suffix); | ||
512 | } | ||
513 | else | ||
514 | { | ||
515 | sprintf(val_string, "-%d", lltrunc(llabs(val_to_print))); | ||
516 | } | ||
517 | } | ||
518 | else | ||
519 | { | ||
520 | if (fractional_portion == 0) | ||
521 | { | ||
522 | sprintf(val_string, "%d%s", lltrunc(llabs(val_to_print)), suffix); | ||
523 | } | ||
524 | else | ||
525 | { | ||
526 | sprintf(val_string, "%d", lltrunc(val_to_print)); | ||
527 | } | ||
528 | } | ||
529 | |||
530 | BOOL hud_selection = gSelectMgr->getSelectType() == SELECT_TYPE_HUD; | ||
531 | glMatrixMode(GL_MODELVIEW); | ||
532 | glPushMatrix(); | ||
533 | LLVector3 render_pos = pos; | ||
534 | if (hud_selection) | ||
535 | { | ||
536 | F32 zoom_amt = gAgent.getAvatarObject()->mHUDCurZoom; | ||
537 | F32 inv_zoom_amt = 1.f / zoom_amt; | ||
538 | // scale text back up to counter-act zoom level | ||
539 | render_pos = pos * zoom_amt; | ||
540 | glScalef(inv_zoom_amt, inv_zoom_amt, inv_zoom_amt); | ||
541 | } | ||
542 | |||
543 | LLColor4 shadow_color = LLColor4::black; | ||
544 | shadow_color.mV[VALPHA] = color.mV[VALPHA] * 0.5f; | ||
545 | |||
546 | LLGLEnable tex(GL_TEXTURE_2D); | ||
547 | if (fractional_portion != 0) | ||
548 | { | ||
549 | sprintf(fraction_string, "%c%d%s", gResMgr->getDecimalPoint(), fractional_portion, suffix); | ||
550 | |||
551 | gViewerWindow->setupViewport(1, -1); | ||
552 | hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, -1.f * big_fontp->getWidthF32(val_string), 3.f, shadow_color, hud_selection); | ||
553 | hud_render_utf8text(fraction_string, render_pos, *small_fontp, LLFontGL::NORMAL, 1.f, 3.f, shadow_color, hud_selection); | ||
554 | |||
555 | gViewerWindow->setupViewport(); | ||
556 | hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, -1.f * big_fontp->getWidthF32(val_string), 3.f, color, hud_selection); | ||
557 | hud_render_utf8text(fraction_string, render_pos, *small_fontp, LLFontGL::NORMAL, 1.f, 3.f, color, hud_selection); | ||
558 | } | ||
559 | else | ||
560 | { | ||
561 | gViewerWindow->setupViewport(1, -1); | ||
562 | hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, -0.5f * big_fontp->getWidthF32(val_string), 3.f, shadow_color, hud_selection); | ||
563 | gViewerWindow->setupViewport(); | ||
564 | hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, -0.5f * big_fontp->getWidthF32(val_string), 3.f, color, hud_selection); | ||
565 | } | ||
566 | glPopMatrix(); | ||
567 | } | ||
568 | |||
569 | LLColor4 LLManip::setupSnapGuideRenderPass(S32 pass) | ||
570 | { | ||
571 | static LLColor4 grid_color_fg = gColors.getColor("GridlineColor"); | ||
572 | static LLColor4 grid_color_bg = gColors.getColor("GridlineBGColor"); | ||
573 | static LLColor4 grid_color_shadow = gColors.getColor("GridlineShadowColor"); | ||
574 | |||
575 | LLColor4 line_color; | ||
576 | F32 line_alpha = gSavedSettings.getF32("GridOpacity"); | ||
577 | |||
578 | switch(pass) | ||
579 | { | ||
580 | case 0: | ||
581 | // shadow | ||
582 | gViewerWindow->setupViewport(1, -1); | ||
583 | line_color = grid_color_shadow; | ||
584 | line_color.mV[VALPHA] *= line_alpha; | ||
585 | LLUI::setLineWidth(2.f); | ||
586 | break; | ||
587 | case 1: | ||
588 | // hidden lines | ||
589 | gViewerWindow->setupViewport(); | ||
590 | line_color = grid_color_bg; | ||
591 | line_color.mV[VALPHA] *= line_alpha; | ||
592 | LLUI::setLineWidth(1.f); | ||
593 | break; | ||
594 | case 2: | ||
595 | // visible lines | ||
596 | line_color = grid_color_fg; | ||
597 | line_color.mV[VALPHA] *= line_alpha; | ||
598 | break; | ||
599 | } | ||
600 | |||
601 | return line_color; | ||
602 | } | ||