00001
00036 #include "llviewerprecompiledheaders.h"
00037
00038 #include "llmaniptranslate.h"
00039
00040 #include "llgl.h"
00041
00042 #include "llagent.h"
00043 #include "llbbox.h"
00044 #include "llbox.h"
00045 #include "llviewercontrol.h"
00046 #include "llcriticaldamp.h"
00047 #include "llcylinder.h"
00048 #include "lldrawable.h"
00049 #include "llfloatertools.h"
00050 #include "llfontgl.h"
00051 #include "llglheaders.h"
00052 #include "llhudrender.h"
00053 #include "llresmgr.h"
00054 #include "llselectmgr.h"
00055 #include "llsphere.h"
00056 #include "llstatusbar.h"
00057 #include "lltoolmgr.h"
00058 #include "llviewercamera.h"
00059 #include "llviewerjoint.h"
00060 #include "llviewerobject.h"
00061 #include "llviewerwindow.h"
00062 #include "llvoavatar.h"
00063 #include "llworld.h"
00064 #include "viewer.h"
00065 #include "llui.h"
00066 #include "pipeline.h"
00067
00068 const S32 NUM_AXES = 3;
00069 const S32 MOUSE_DRAG_SLOP = 2;
00070 const F32 HANDLE_HIDE_ANGLE = 0.15f;
00071 const F32 SELECTED_ARROW_SCALE = 1.3f;
00072 const F32 MANIPULATOR_HOTSPOT_START = 0.2f;
00073 const F32 MANIPULATOR_HOTSPOT_END = 1.2f;
00074 const F32 SNAP_GUIDE_SCREEN_SIZE = 0.7f;
00075 const F32 MIN_PLANE_MANIP_DOT_PRODUCT = 0.25f;
00076 const F32 PLANE_TICK_SIZE = 0.4f;
00077 const F32 MANIPULATOR_SCALE_HALF_LIFE = 0.07f;
00078 const F32 SNAP_ARROW_SCALE = 0.7f;
00079
00080 static GLuint sGridTex = 0;
00081
00082 const LLManip::EManipPart MANIPULATOR_IDS[9] =
00083 {
00084 LLManip::LL_X_ARROW,
00085 LLManip::LL_Y_ARROW,
00086 LLManip::LL_Z_ARROW,
00087 LLManip::LL_X_ARROW,
00088 LLManip::LL_Y_ARROW,
00089 LLManip::LL_Z_ARROW,
00090 LLManip::LL_YZ_PLANE,
00091 LLManip::LL_XZ_PLANE,
00092 LLManip::LL_XY_PLANE
00093 };
00094
00095 const U32 ARROW_TO_AXIS[4] =
00096 {
00097 VX,
00098 VX,
00099 VY,
00100 VZ
00101 };
00102
00103 BOOL sort_manip_by_end_z(LLManipTranslate::ManipulatorHandle *new_manip, LLManipTranslate::ManipulatorHandle *test_manip)
00104 {
00105 return (new_manip->mEndPosition.mV[VZ] < test_manip->mEndPosition.mV[VZ]);
00106 }
00107
00108 LLManipTranslate::LLManipTranslate( LLToolComposite* composite )
00109 : LLManip( "Move", composite ),
00110 mLastHoverMouseX(-1),
00111 mLastHoverMouseY(-1),
00112 mSendUpdateOnMouseUp(FALSE),
00113 mMouseOutsideSlop(FALSE),
00114 mCopyMadeThisDrag(FALSE),
00115 mMouseDownX(-1),
00116 mMouseDownY(-1),
00117 mAxisArrowLength(50),
00118 mConeSize(0),
00119 mArrowLengthMeters(0.f),
00120 mPlaneManipOffsetMeters(0.f),
00121 mManipPart(LL_NO_PART),
00122 mUpdateTimer(),
00123 mSnapOffsetMeters(0.f),
00124 mArrowScales(1.f, 1.f, 1.f),
00125 mPlaneScales(1.f, 1.f, 1.f),
00126 mPlaneManipPositions(1.f, 1.f, 1.f, 1.f)
00127 {
00128 mProjectedManipulators.setInsertBefore(sort_manip_by_end_z);
00129
00130 if (sGridTex == 0)
00131 {
00132 restoreGL();
00133 }
00134 }
00135
00136
00137 void LLManipTranslate::restoreGL()
00138 {
00139
00140 U32 rez = 512;
00141 U32 mip = 0;
00142
00143 GLuint* d = new GLuint[rez*rez];
00144 LLGLEnable tex2d(GL_TEXTURE_2D);
00145 glGenTextures(1, &sGridTex);
00146 glBindTexture(GL_TEXTURE_2D, sGridTex);
00147 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
00148 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00149
00150 while (rez >= 1)
00151 {
00152 for (U32 i = 0; i < rez*rez; i++)
00153 {
00154 d[i] = 0x00FFFFFF;
00155 }
00156
00157 U32 subcol = 0xFFFFFFFF;
00158 if (rez >= 4)
00159 {
00160 for (U32 i = 0; i < rez; i++)
00161 {
00162 if (rez <= 16)
00163 {
00164 if (rez == 16)
00165 {
00166 subcol = 0xA0FFFFFF;
00167 }
00168 else if (rez == 8)
00169 {
00170 subcol = 0x80FFFFFF;
00171 }
00172 else
00173 {
00174 subcol = 0x40FFFFFF;
00175 }
00176 }
00177 else
00178 {
00179 subcol = 0xFFFFFFFF;
00180 }
00181 d[i *rez+ 0 ] = subcol;
00182 d[0 *rez+ i ] = subcol;
00183 if (rez >= 32)
00184 {
00185 d[i *rez+ (rez-1)] = subcol;
00186 d[(rez-1) *rez+ i ] = subcol;
00187 }
00188
00189 if (rez >= 64)
00190 {
00191 subcol = 0xFFFFFFFF;
00192
00193 if (i > 0 && i < (rez-1))
00194 {
00195 d[i *rez+ 1 ] = subcol;
00196 d[i *rez+ (rez-2)] = subcol;
00197 d[1 *rez+ i ] = subcol;
00198 d[(rez-2) *rez+ i ] = subcol;
00199 }
00200 }
00201 }
00202 }
00203
00204 subcol = 0x50A0A0A0;
00205 if (rez >= 128)
00206 {
00207 for (U32 i = 8; i < rez; i+=8)
00208 {
00209 for (U32 j = 2; j < rez-2; j++)
00210 {
00211 d[i *rez+ j] = subcol;
00212 d[j *rez+ i] = subcol;
00213 }
00214 }
00215 }
00216 if (rez >= 64)
00217 {
00218 if (rez == 64)
00219 {
00220 subcol = 0x50A0A0A0;
00221 }
00222 else
00223 {
00224 subcol = 0xA0D0D0D0;
00225 }
00226
00227 for (U32 i = 32; i < rez; i+=32)
00228 {
00229 U32 pi = i-1;
00230 for (U32 j = 2; j < rez-2; j++)
00231 {
00232 d[i *rez+ j] = subcol;
00233 d[j *rez+ i] = subcol;
00234
00235 if (rez > 128)
00236 {
00237 d[pi *rez+ j] = subcol;
00238 d[j *rez+ pi] = subcol;
00239 }
00240 }
00241 }
00242 }
00243 #ifdef LL_WINDOWS
00244 glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA, rez, rez, 0, GL_RGBA, GL_UNSIGNED_BYTE, d);
00245 #else
00246 glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA, rez, rez, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, d);
00247 #endif
00248 rez = rez >> 1;
00249 mip++;
00250 }
00251 delete [] d;
00252 }
00253
00254
00255 LLManipTranslate::~LLManipTranslate()
00256 {
00257 mProjectedManipulators.deleteAllData();
00258 }
00259
00260
00261 void LLManipTranslate::handleSelect()
00262 {
00263 gSelectMgr->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
00264 gFloaterTools->setStatusText("move");
00265 LLManip::handleSelect();
00266 }
00267
00268 void LLManipTranslate::handleDeselect()
00269 {
00270 mHighlightedPart = LL_NO_PART;
00271 mManipPart = LL_NO_PART;
00272 LLManip::handleDeselect();
00273 }
00274
00275 BOOL LLManipTranslate::handleMouseDown(S32 x, S32 y, MASK mask)
00276 {
00277 BOOL handled = FALSE;
00278
00279
00280 LLViewerObject* hit_obj = gViewerWindow->lastObjectHit();
00281 if( hit_obj &&
00282 (mHighlightedPart == LL_X_ARROW ||
00283 mHighlightedPart == LL_Y_ARROW ||
00284 mHighlightedPart == LL_Z_ARROW ||
00285 mHighlightedPart == LL_YZ_PLANE ||
00286 mHighlightedPart == LL_XZ_PLANE ||
00287 mHighlightedPart == LL_XY_PLANE ) )
00288 {
00289 handled = handleMouseDownOnPart( x, y, mask );
00290 }
00291
00292 return handled;
00293 }
00294
00295
00296 BOOL LLManipTranslate::handleMouseDownOnPart( S32 x, S32 y, MASK mask )
00297 {
00298 BOOL can_move = canAffectSelection();
00299 if (!can_move)
00300 {
00301 return FALSE;
00302 }
00303
00304 highlightManipulators(x, y);
00305 S32 hit_part = mHighlightedPart;
00306
00307 if( (hit_part != LL_X_ARROW) &&
00308 (hit_part != LL_Y_ARROW) &&
00309 (hit_part != LL_Z_ARROW) &&
00310 (hit_part != LL_YZ_PLANE) &&
00311 (hit_part != LL_XZ_PLANE) &&
00312 (hit_part != LL_XY_PLANE) )
00313 {
00314 return TRUE;
00315 }
00316
00317 mHelpTextTimer.reset();
00318 sNumTimesHelpTextShown++;
00319
00320 gSelectMgr->getGrid(mGridOrigin, mGridRotation, mGridScale);
00321
00322 gSelectMgr->enableSilhouette(FALSE);
00323
00324
00325 gSelectMgr->saveSelectedObjectTransform(SELECT_ACTION_TYPE_MOVE);
00326
00327 mManipPart = (EManipPart)hit_part;
00328 mMouseDownX = x;
00329 mMouseDownY = y;
00330 mMouseOutsideSlop = FALSE;
00331
00332 LLVector3 axis;
00333
00334 LLSelectNode *selectNode = mObjectSelection->getFirstMoveableNode(TRUE);
00335
00336 if (!selectNode)
00337 {
00338
00339 llwarns << "Trying to translate an unselected object" << llendl;
00340 return TRUE;
00341 }
00342
00343 LLViewerObject *selected_object = selectNode->getObject();
00344 if (!selected_object)
00345 {
00346
00347 llwarns << "Translate manip lost the object, no selected object" << llendl;
00348 gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
00349 return TRUE;
00350 }
00351
00352
00353 BOOL axis_exists = getManipAxis(selected_object, mManipPart, axis);
00354 getManipNormal(selected_object, mManipPart, mManipNormal);
00355
00356
00357
00358 LLVector3 select_center_agent = getPivotPoint();
00359 mSubdivisions = llclamp(getSubdivisionLevel(select_center_agent, axis_exists ? axis : LLVector3::z_axis, getMinGridScale()), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
00360
00361
00362 if (mManipPart >= LL_YZ_PLANE && mManipPart <= LL_XY_PLANE)
00363 {
00364 LLCoordGL mouse_pos;
00365 if (!gCamera->projectPosAgentToScreen(select_center_agent, mouse_pos))
00366 {
00367
00368 llwarns << "Failed to project object center to screen" << llendl;
00369 }
00370 else if (gSavedSettings.getBOOL("SnapToMouseCursor"))
00371 {
00372 LLUI::setCursorPositionScreen(mouse_pos.mX, mouse_pos.mY);
00373 x = mouse_pos.mX;
00374 y = mouse_pos.mY;
00375 }
00376 }
00377
00378 gSelectMgr->updateSelectionCenter();
00379 LLVector3d object_start_global = gAgent.getPosGlobalFromAgent(getPivotPoint());
00380 getMousePointOnPlaneGlobal(mDragCursorStartGlobal, x, y, object_start_global, mManipNormal);
00381 mDragSelectionStartGlobal = object_start_global;
00382 mCopyMadeThisDrag = FALSE;
00383
00384
00385 setMouseCapture( TRUE );
00386
00387 return TRUE;
00388 }
00389
00390 BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
00391 {
00392
00393
00394 if( !hasMouseCapture() )
00395 {
00396 lldebugst(LLERR_USER_INPUT) << "hover handled by LLManipTranslate (inactive)" << llendl;
00397
00398
00399 gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
00400
00401 highlightManipulators(x, y);
00402 return TRUE;
00403 }
00404
00405
00406 const F32 ROTATE_ANGLE_PER_SECOND = 30.f * DEG_TO_RAD;
00407 const S32 ROTATE_H_MARGIN = gViewerWindow->getWindowWidth() / 20;
00408 const F32 rotate_angle = ROTATE_ANGLE_PER_SECOND / gFPSClamped;
00409 BOOL rotated = FALSE;
00410
00411
00412 if (mObjectSelection->getSelectType() != SELECT_TYPE_HUD)
00413 {
00414 if (x < ROTATE_H_MARGIN)
00415 {
00416 gAgent.cameraOrbitAround(rotate_angle);
00417 rotated = TRUE;
00418 }
00419 else if (x > gViewerWindow->getWindowWidth() - ROTATE_H_MARGIN)
00420 {
00421 gAgent.cameraOrbitAround(-rotate_angle);
00422 rotated = TRUE;
00423 }
00424 }
00425
00426
00427
00428
00429 if( x == mLastHoverMouseX && y == mLastHoverMouseY && !rotated)
00430 {
00431 lldebugst(LLERR_USER_INPUT) << "hover handled by LLManipTranslate (mouse unmoved)" << llendl;
00432 gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
00433 return TRUE;
00434 }
00435 mLastHoverMouseX = x;
00436 mLastHoverMouseY = y;
00437
00438
00439
00440 if( !mMouseOutsideSlop )
00441 {
00442 if (abs(mMouseDownX - x) < MOUSE_DRAG_SLOP && abs(mMouseDownY - y) < MOUSE_DRAG_SLOP )
00443 {
00444 lldebugst(LLERR_USER_INPUT) << "hover handled by LLManipTranslate (mouse inside slop)" << llendl;
00445 gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
00446 return TRUE;
00447 }
00448 else
00449 {
00450
00451 mMouseOutsideSlop = TRUE;
00452
00453 if (mask == MASK_COPY)
00454 {
00455
00456 gSelectMgr->selectDuplicate(LLVector3::zero, FALSE);
00457 mCopyMadeThisDrag = TRUE;
00458
00459
00460
00461 lldebugst(LLERR_USER_INPUT) << "hover handled by LLManipTranslate (made copy)" << llendl;
00462 gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
00463 }
00464 }
00465 }
00466
00467
00468 BOOL send_update = FALSE;
00469
00470 LLVector3 axis_f;
00471 LLVector3d axis_d;
00472
00473
00474
00475 LLSelectNode* selectNode = mObjectSelection->getFirstMoveableNode(TRUE);
00476 if (!selectNode)
00477 {
00478
00479 llwarns << "Translate manip lost the object, no selectNode" << llendl;
00480 gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
00481 return TRUE;
00482 }
00483
00484 LLViewerObject* object = selectNode->getObject();
00485 if (!object)
00486 {
00487
00488 llwarns << "Translate manip lost the object, no object in selectNode" << llendl;
00489 gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
00490 return TRUE;
00491 }
00492
00493
00494 BOOL axis_exists = getManipAxis(object, mManipPart, axis_f);
00495
00496 axis_d.setVec(axis_f);
00497
00498 gSelectMgr->updateSelectionCenter();
00499 LLVector3d current_pos_global = gAgent.getPosGlobalFromAgent(getPivotPoint());
00500
00501 mSubdivisions = llclamp(getSubdivisionLevel(getPivotPoint(), axis_f, getMinGridScale()), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
00502
00503
00504 LLVector3d relative_move;
00505 getMousePointOnPlaneGlobal(relative_move, x, y, current_pos_global, mManipNormal);\
00506 relative_move -= mDragCursorStartGlobal;
00507
00508
00509 if (gSavedSettings.getBOOL("LimitDragDistance"))
00510 {
00511 F32 max_drag_distance = gSavedSettings.getF32("MaxDragDistance");
00512
00513 if (relative_move.magVecSquared() > max_drag_distance * max_drag_distance)
00514 {
00515 lldebugst(LLERR_USER_INPUT) << "hover handled by LLManipTranslate (too far)" << llendl;
00516 gViewerWindow->setCursor(UI_CURSOR_NOLOCKED);
00517 return TRUE;
00518 }
00519 }
00520
00521 F64 axis_magnitude = relative_move * axis_d;
00522 LLVector3d cursor_point_snap_line;
00523
00524 F64 off_axis_magnitude;
00525
00526 getMousePointOnPlaneGlobal(cursor_point_snap_line, x, y, current_pos_global, mSnapOffsetAxis % axis_f);
00527 off_axis_magnitude = axis_exists ? llabs((cursor_point_snap_line - current_pos_global) * LLVector3d(mSnapOffsetAxis)) : 0.f;
00528
00529 if (gSavedSettings.getBOOL("SnapEnabled"))
00530 {
00531 if (off_axis_magnitude > mSnapOffsetMeters)
00532 {
00533 mInSnapRegime = TRUE;
00534 LLVector3 mouse_down_offset(mDragCursorStartGlobal - mDragSelectionStartGlobal);
00535 LLVector3 cursor_snap_agent = gAgent.getPosAgentFromGlobal(cursor_point_snap_line);
00536 if (!gSavedSettings.getBOOL("SnapToMouseCursor"))
00537 {
00538 cursor_snap_agent -= mouse_down_offset;
00539 }
00540
00541 F32 cursor_grid_dist = (cursor_snap_agent - mGridOrigin) * axis_f;
00542
00543 F32 snap_dist = getMinGridScale() / (2.f * mSubdivisions);
00544 F32 relative_snap_dist = fmodf(llabs(cursor_grid_dist) + snap_dist, getMinGridScale() / mSubdivisions);
00545 if (relative_snap_dist < snap_dist * 2.f)
00546 {
00547 if (cursor_grid_dist > 0.f)
00548 {
00549 cursor_grid_dist -= relative_snap_dist - snap_dist;
00550 }
00551 else
00552 {
00553 cursor_grid_dist += relative_snap_dist - snap_dist;
00554 }
00555 }
00556
00557 F32 object_start_on_axis = (gAgent.getPosAgentFromGlobal(mDragSelectionStartGlobal) - mGridOrigin) * axis_f;
00558 axis_magnitude = cursor_grid_dist - object_start_on_axis;
00559 }
00560 else if (mManipPart >= LL_YZ_PLANE && mManipPart <= LL_XY_PLANE)
00561 {
00562
00563 LLVector3d cursor_point_global;
00564 getMousePointOnPlaneGlobal( cursor_point_global, x, y, current_pos_global, mManipNormal );
00565 cursor_point_global -= (mDragCursorStartGlobal - mDragSelectionStartGlobal);
00566
00567
00568 LLVector3 cursor_point_agent = gAgent.getPosAgentFromGlobal(cursor_point_global);
00569 LLVector3 camera_plane_projection = gCamera->getAtAxis();
00570 camera_plane_projection -= projected_vec(camera_plane_projection, mManipNormal);
00571 camera_plane_projection.normVec();
00572 LLVector3 camera_projected_dir = camera_plane_projection;
00573 camera_plane_projection.rotVec(~mGridRotation);
00574 camera_plane_projection.scaleVec(mGridScale);
00575 camera_plane_projection.abs();
00576 F32 max_grid_scale;
00577 if (camera_plane_projection.mV[VX] > camera_plane_projection.mV[VY] &&
00578 camera_plane_projection.mV[VX] > camera_plane_projection.mV[VZ])
00579 {
00580 max_grid_scale = mGridScale.mV[VX];
00581 }
00582 else if (camera_plane_projection.mV[VY] > camera_plane_projection.mV[VZ])
00583 {
00584 max_grid_scale = mGridScale.mV[VY];
00585 }
00586 else
00587 {
00588 max_grid_scale = mGridScale.mV[VZ];
00589 }
00590
00591 F32 num_subdivisions = llclamp(getSubdivisionLevel(getPivotPoint(), camera_projected_dir, max_grid_scale), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
00592
00593 F32 grid_scale_a;
00594 F32 grid_scale_b;
00595 LLVector3 cursor_point_grid = (cursor_point_agent - mGridOrigin) * ~mGridRotation;
00596
00597 switch (mManipPart)
00598 {
00599 case LL_YZ_PLANE:
00600 grid_scale_a = mGridScale.mV[VY] / num_subdivisions;
00601 grid_scale_b = mGridScale.mV[VZ] / num_subdivisions;
00602 cursor_point_grid.mV[VY] -= fmod(cursor_point_grid.mV[VY] + grid_scale_a * 0.5f, grid_scale_a) - grid_scale_a * 0.5f;
00603 cursor_point_grid.mV[VZ] -= fmod(cursor_point_grid.mV[VZ] + grid_scale_b * 0.5f, grid_scale_b) - grid_scale_b * 0.5f;
00604 break;
00605 case LL_XZ_PLANE:
00606 grid_scale_a = mGridScale.mV[VX] / num_subdivisions;
00607 grid_scale_b = mGridScale.mV[VZ] / num_subdivisions;
00608 cursor_point_grid.mV[VX] -= fmod(cursor_point_grid.mV[VX] + grid_scale_a * 0.5f, grid_scale_a) - grid_scale_a * 0.5f;
00609 cursor_point_grid.mV[VZ] -= fmod(cursor_point_grid.mV[VZ] + grid_scale_b * 0.5f, grid_scale_b) - grid_scale_b * 0.5f;
00610 break;
00611 case LL_XY_PLANE:
00612 grid_scale_a = mGridScale.mV[VX] / num_subdivisions;
00613 grid_scale_b = mGridScale.mV[VY] / num_subdivisions;
00614 cursor_point_grid.mV[VX] -= fmod(cursor_point_grid.mV[VX] + grid_scale_a * 0.5f, grid_scale_a) - grid_scale_a * 0.5f;
00615 cursor_point_grid.mV[VY] -= fmod(cursor_point_grid.mV[VY] + grid_scale_b * 0.5f, grid_scale_b) - grid_scale_b * 0.5f;
00616 break;
00617 default:
00618 break;
00619 }
00620 cursor_point_agent = (cursor_point_grid * mGridRotation) + mGridOrigin;
00621 relative_move.setVec(cursor_point_agent - gAgent.getPosAgentFromGlobal(mDragSelectionStartGlobal));
00622 mInSnapRegime = TRUE;
00623 }
00624 else
00625 {
00626 mInSnapRegime = FALSE;
00627 }
00628 }
00629 else
00630 {
00631 mInSnapRegime = FALSE;
00632 }
00633
00634
00635
00636 if (!axis_exists)
00637 {
00638 axis_magnitude = relative_move.normVec();
00639 axis_d.setVec(relative_move);
00640 axis_d.normVec();
00641 axis_f.setVec(axis_d);
00642 }
00643
00644 LLVector3d clamped_relative_move = axis_magnitude * axis_d;
00645 LLVector3 clamped_relative_move_f = (F32)axis_magnitude * axis_f;
00646
00647 for (LLObjectSelection::iterator iter = mObjectSelection->begin();
00648 iter != mObjectSelection->end(); iter++)
00649 {
00650 LLSelectNode* selectNode = *iter;
00651 LLViewerObject* object = selectNode->getObject();
00652
00653
00654
00655 if (!object->isRootEdit() && !selectNode->mIndividualSelection)
00656 {
00657 continue;
00658 }
00659
00660 if (!object->isRootEdit())
00661 {
00662
00663 LLViewerObject* editable_root = (LLViewerObject*)object->getParent();
00664 if (editable_root->isSelected())
00665 {
00666
00667 continue;
00668 }
00669 }
00670
00671 if (object->permMove())
00672 {
00673
00674 if (object->isAttachment() && object->mDrawable.notNull())
00675 {
00676
00677 LLQuaternion objWorldRotation = object->mDrawable->mXform.getParent()->getWorldRotation();
00678 objWorldRotation.transQuat();
00679
00680 LLVector3 old_position_local = object->getPosition();
00681 LLVector3 new_position_local = selectNode->mSavedPositionLocal + (clamped_relative_move_f * objWorldRotation);
00682
00683
00684 if (new_position_local != old_position_local)
00685 {
00686 send_update = TRUE;
00687 }
00688
00689
00690 object->setPosition(new_position_local);
00691 rebuild(object);
00692 gAgent.getAvatarObject()->clampAttachmentPositions();
00693 new_position_local = object->getPosition();
00694
00695 if (selectNode->mIndividualSelection)
00696 {
00697 send_update = FALSE;
00698 LLVector3 child_offset = (old_position_local - new_position_local) * ~object->getRotation();
00699
00700
00701 for (U32 child_num = 0; child_num < object->mChildList.size(); child_num++)
00702 {
00703 LLViewerObject* childp = object->mChildList[child_num];
00704
00705 if (!childp->isSelected())
00706 {
00707 childp->setPosition(childp->getPosition() + child_offset);
00708 rebuild(childp);
00709 }
00710 }
00711 }
00712 }
00713 else
00714 {
00715
00716
00717 LLVector3d new_position_global = selectNode->mSavedPositionGlobal + clamped_relative_move;
00718
00719
00720 F64 min_height = gWorldp->getMinAllowedZ(object);
00721 if (new_position_global.mdV[VZ] < min_height)
00722 {
00723 new_position_global.mdV[VZ] = min_height;
00724 }
00725
00726
00727 if (new_position_global.mdV[VZ] > MAX_OBJECT_Z)
00728 {
00729 new_position_global.mdV[VZ] = MAX_OBJECT_Z;
00730 }
00731
00732
00733 if (object->getPCode() == LL_PCODE_LEGACY_GRASS)
00734 {
00735 new_position_global.mdV[VZ] = gWorldp->resolveLandHeightGlobal(new_position_global) + 1.f;
00736 }
00737
00738 if (object->isRootEdit())
00739 {
00740 new_position_global = gWorldp->clipToVisibleRegions(object->getPositionGlobal(), new_position_global);
00741 }
00742
00743
00744 LLVector3d old_position_global = object->getPositionGlobal();
00745 LLVector3 old_position_agent = object->getPositionAgent();
00746 LLVector3 new_position_agent = gAgent.getPosAgentFromGlobal(new_position_global);
00747 if (object->isRootEdit())
00748 {
00749
00750 object->setPositionAgent(new_position_agent);
00751 rebuild(object);
00752 }
00753 else
00754 {
00755 LLViewerObject* root_object = object->getRootEdit();
00756 new_position_agent -= root_object->getPositionAgent();
00757 new_position_agent = new_position_agent * ~root_object->getRotation();
00758 object->setPositionParent(new_position_agent, FALSE);
00759 rebuild(object);
00760 }
00761
00762 if (selectNode->mIndividualSelection)
00763 {
00764 LLVector3 parent_offset = (new_position_agent - old_position_agent) * ~object->getRotation();
00765
00766
00767 for (U32 child_num = 0; child_num < object->mChildList.size(); child_num++)
00768 {
00769 LLViewerObject* childp = object->mChildList[child_num];
00770 if (!childp->isSelected())
00771 {
00772 childp->setPosition(childp->getPosition() - parent_offset);
00773 rebuild(childp);
00774 }
00775 }
00776 send_update = FALSE;
00777 }
00778 else if (old_position_global != new_position_global)
00779 {
00780 send_update = TRUE;
00781 }
00782 }
00783 selectNode->mLastPositionLocal = object->getPosition();
00784 }
00785 }
00786
00787 gSelectMgr->updateSelectionCenter();
00788 gAgent.clearFocusObject();
00789 dialog_refresh_all();
00790
00791 lldebugst(LLERR_USER_INPUT) << "hover handled by LLManipTranslate (active)" << llendl;
00792 gViewerWindow->setCursor(UI_CURSOR_TOOLTRANSLATE);
00793 return TRUE;
00794 }
00795
00796 void LLManipTranslate::highlightManipulators(S32 x, S32 y)
00797 {
00798 mHighlightedPart = LL_NO_PART;
00799
00800 if (!mObjectSelection->getObjectCount())
00801 {
00802 return;
00803 }
00804
00805
00806 LLMatrix4 projMatrix = gCamera->getProjection();
00807 LLMatrix4 modelView = gCamera->getModelview();
00808
00809 LLVector3 object_position = getPivotPoint();
00810
00811 LLVector3 grid_origin;
00812 LLVector3 grid_scale;
00813 LLQuaternion grid_rotation;
00814
00815 gSelectMgr->getGrid(grid_origin, grid_rotation, grid_scale);
00816
00817 LLVector3 relative_camera_dir;
00818
00819 LLMatrix4 transform;
00820
00821 if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
00822 {
00823 relative_camera_dir = LLVector3(1.f, 0.f, 0.f) * ~grid_rotation;
00824 LLVector4 translation(object_position);
00825 transform.initRotTrans(grid_rotation, translation);
00826 LLMatrix4 cfr(OGL_TO_CFR_ROTATION);
00827 transform *= cfr;
00828 LLMatrix4 window_scale;
00829 F32 zoom_level = 2.f * gAgent.getAvatarObject()->mHUDCurZoom;
00830 window_scale.initAll(LLVector3(zoom_level / gCamera->getAspect(), zoom_level, 0.f),
00831 LLQuaternion::DEFAULT,
00832 LLVector3::zero);
00833 transform *= window_scale;
00834 }
00835 else
00836 {
00837 relative_camera_dir = (object_position - gCamera->getOrigin()) * ~grid_rotation;
00838 relative_camera_dir.normVec();
00839
00840 transform.initRotTrans(grid_rotation, LLVector4(object_position));
00841 transform *= modelView;
00842 transform *= projMatrix;
00843 }
00844
00845 mProjectedManipulators.deleteAllData();
00846
00847 S32 numManips = 0;
00848
00849
00850 mManipulatorVertices[numManips++] = LLVector4(mArrowLengthMeters * MANIPULATOR_HOTSPOT_START, 0.f, 0.f, 1.f);
00851 mManipulatorVertices[numManips++] = LLVector4(mArrowLengthMeters * MANIPULATOR_HOTSPOT_END, 0.f, 0.f, 1.f);
00852
00853 mManipulatorVertices[numManips++] = LLVector4(0.f, mArrowLengthMeters * MANIPULATOR_HOTSPOT_START, 0.f, 1.f);
00854 mManipulatorVertices[numManips++] = LLVector4(0.f, mArrowLengthMeters * MANIPULATOR_HOTSPOT_END, 0.f, 1.f);
00855
00856 mManipulatorVertices[numManips++] = LLVector4(0.f, 0.f, mArrowLengthMeters * MANIPULATOR_HOTSPOT_START, 1.f);
00857 mManipulatorVertices[numManips++] = LLVector4(0.f, 0.f, mArrowLengthMeters * MANIPULATOR_HOTSPOT_END, 1.f);
00858
00859 mManipulatorVertices[numManips++] = LLVector4(mArrowLengthMeters * -MANIPULATOR_HOTSPOT_START, 0.f, 0.f, 1.f);
00860 mManipulatorVertices[numManips++] = LLVector4(mArrowLengthMeters * -MANIPULATOR_HOTSPOT_END, 0.f, 0.f, 1.f);
00861
00862 mManipulatorVertices[numManips++] = LLVector4(0.f, mArrowLengthMeters * -MANIPULATOR_HOTSPOT_START, 0.f, 1.f);
00863 mManipulatorVertices[numManips++] = LLVector4(0.f, mArrowLengthMeters * -MANIPULATOR_HOTSPOT_END, 0.f, 1.f);
00864
00865 mManipulatorVertices[numManips++] = LLVector4(0.f, 0.f, mArrowLengthMeters * -MANIPULATOR_HOTSPOT_START, 1.f);
00866 mManipulatorVertices[numManips++] = LLVector4(0.f, 0.f, mArrowLengthMeters * -MANIPULATOR_HOTSPOT_END, 1.f);
00867
00868 S32 num_arrow_manips = numManips;
00869
00870
00871 BOOL planar_manip_yz_visible = FALSE;
00872 BOOL planar_manip_xz_visible = FALSE;
00873 BOOL planar_manip_xy_visible = FALSE;
00874
00875 mManipulatorVertices[numManips] = LLVector4(0.f, mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), 1.f);
00876 mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions);
00877 mManipulatorVertices[numManips] = LLVector4(0.f, mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), 1.f);
00878 mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions);
00879 if (llabs(relative_camera_dir.mV[VX]) > MIN_PLANE_MANIP_DOT_PRODUCT)
00880 {
00881 planar_manip_yz_visible = TRUE;
00882 }
00883
00884 mManipulatorVertices[numManips] = LLVector4(mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), 0.f, mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), 1.f);
00885 mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions);
00886 mManipulatorVertices[numManips] = LLVector4(mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), 0.f, mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), 1.f);
00887 mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions);
00888 if (llabs(relative_camera_dir.mV[VY]) > MIN_PLANE_MANIP_DOT_PRODUCT)
00889 {
00890 planar_manip_xz_visible = TRUE;
00891 }
00892
00893 mManipulatorVertices[numManips] = LLVector4(mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), mPlaneManipOffsetMeters * (1.f - PLANE_TICK_SIZE * 0.5f), 0.f, 1.f);
00894 mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions);
00895 mManipulatorVertices[numManips] = LLVector4(mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), mPlaneManipOffsetMeters * (1.f + PLANE_TICK_SIZE * 0.5f), 0.f, 1.f);
00896 mManipulatorVertices[numManips++].scaleVec(mPlaneManipPositions);
00897 if (llabs(relative_camera_dir.mV[VZ]) > MIN_PLANE_MANIP_DOT_PRODUCT)
00898 {
00899 planar_manip_xy_visible = TRUE;
00900 }
00901
00902 for (S32 i = 0; i < num_arrow_manips; i+= 2)
00903 {
00904 LLVector4 projected_start = mManipulatorVertices[i] * transform;
00905 projected_start = projected_start * (1.f / projected_start.mV[VW]);
00906
00907 LLVector4 projected_end = mManipulatorVertices[i + 1] * transform;
00908 projected_end = projected_end * (1.f / projected_end.mV[VW]);
00909
00910 ManipulatorHandle* projManipulator =
00911 new ManipulatorHandle(LLVector3(projected_start.mV[VX], projected_start.mV[VY], projected_start.mV[VZ]),
00912 LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]),
00913 MANIPULATOR_IDS[i / 2],
00914 10.f);
00915 mProjectedManipulators.addDataSorted(projManipulator);
00916 }
00917
00918 if (planar_manip_yz_visible)
00919 {
00920 S32 i = num_arrow_manips;
00921 LLVector4 projected_start = mManipulatorVertices[i] * transform;
00922 projected_start = projected_start * (1.f / projected_start.mV[VW]);
00923
00924 LLVector4 projected_end = mManipulatorVertices[i + 1] * transform;
00925 projected_end = projected_end * (1.f / projected_end.mV[VW]);
00926
00927 ManipulatorHandle* projManipulator =
00928 new ManipulatorHandle(LLVector3(projected_start.mV[VX], projected_start.mV[VY], projected_start.mV[VZ]),
00929 LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]),
00930 MANIPULATOR_IDS[i / 2],
00931 20.f);
00932 mProjectedManipulators.addDataSorted(projManipulator);
00933 }
00934
00935 if (planar_manip_xz_visible)
00936 {
00937 S32 i = num_arrow_manips + 2;
00938 LLVector4 projected_start = mManipulatorVertices[i] * transform;
00939 projected_start = projected_start * (1.f / projected_start.mV[VW]);
00940
00941 LLVector4 projected_end = mManipulatorVertices[i + 1] * transform;
00942 projected_end = projected_end * (1.f / projected_end.mV[VW]);
00943
00944 ManipulatorHandle* projManipulator =
00945 new ManipulatorHandle(LLVector3(projected_start.mV[VX], projected_start.mV[VY], projected_start.mV[VZ]),
00946 LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]),
00947 MANIPULATOR_IDS[i / 2],
00948 20.f);
00949 mProjectedManipulators.addDataSorted(projManipulator);
00950 }
00951
00952 if (planar_manip_xy_visible)
00953 {
00954 S32 i = num_arrow_manips + 4;
00955 LLVector4 projected_start = mManipulatorVertices[i] * transform;
00956 projected_start = projected_start * (1.f / projected_start.mV[VW]);
00957
00958 LLVector4 projected_end = mManipulatorVertices[i + 1] * transform;
00959 projected_end = projected_end * (1.f / projected_end.mV[VW]);
00960
00961 ManipulatorHandle* projManipulator =
00962 new ManipulatorHandle(LLVector3(projected_start.mV[VX], projected_start.mV[VY], projected_start.mV[VZ]),
00963 LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]),
00964 MANIPULATOR_IDS[i / 2],
00965 20.f);
00966 mProjectedManipulators.addDataSorted(projManipulator);
00967 }
00968
00969 LLVector2 manip_start_2d;
00970 LLVector2 manip_end_2d;
00971 LLVector2 manip_dir;
00972 F32 half_width = gViewerWindow->getWindowWidth() / 2.f;
00973 F32 half_height = gViewerWindow->getWindowHeight() / 2.f;
00974 LLVector2 mousePos((F32)x - half_width, (F32)y - half_height);
00975 LLVector2 mouse_delta;
00976
00977 for (ManipulatorHandle* manipulator = mProjectedManipulators.getFirstData();
00978 manipulator;
00979 manipulator = mProjectedManipulators.getNextData())
00980 {
00981 manip_start_2d.setVec(manipulator->mStartPosition.mV[VX] * half_width, manipulator->mStartPosition.mV[VY] * half_height);
00982 manip_end_2d.setVec(manipulator->mEndPosition.mV[VX] * half_width, manipulator->mEndPosition.mV[VY] * half_height);
00983 manip_dir = manip_end_2d - manip_start_2d;
00984
00985 mouse_delta = mousePos - manip_start_2d;
00986
00987 F32 manip_length = manip_dir.normVec();
00988
00989 F32 mouse_pos_manip = mouse_delta * manip_dir;
00990 F32 mouse_dist_manip_squared = mouse_delta.magVecSquared() - (mouse_pos_manip * mouse_pos_manip);
00991
00992 if (mouse_pos_manip > 0.f &&
00993 mouse_pos_manip < manip_length &&
00994 mouse_dist_manip_squared < manipulator->mHotSpotRadius * manipulator->mHotSpotRadius)
00995 {
00996 mHighlightedPart = manipulator->mManipID;
00997 break;
00998 }
00999 }
01000 }
01001
01002 F32 LLManipTranslate::getMinGridScale()
01003 {
01004 F32 scale;
01005 switch (mManipPart)
01006 {
01007 case LL_NO_PART:
01008 default:
01009 scale = 1.f;
01010 break;
01011 case LL_X_ARROW:
01012 scale = mGridScale.mV[VX];
01013 break;
01014 case LL_Y_ARROW:
01015 scale = mGridScale.mV[VY];
01016 break;
01017 case LL_Z_ARROW:
01018 scale = mGridScale.mV[VZ];
01019 break;
01020 case LL_YZ_PLANE:
01021 scale = llmin(mGridScale.mV[VY], mGridScale.mV[VZ]);
01022 break;
01023 case LL_XZ_PLANE:
01024 scale = llmin(mGridScale.mV[VX], mGridScale.mV[VZ]);
01025 break;
01026 case LL_XY_PLANE:
01027 scale = llmin(mGridScale.mV[VX], mGridScale.mV[VY]);
01028 break;
01029 }
01030
01031 return scale;
01032 }
01033
01034
01035 BOOL LLManipTranslate::handleMouseUp(S32 x, S32 y, MASK mask)
01036 {
01037
01038 handleHover(x, y, mask);
01039
01040 if(hasMouseCapture())
01041 {
01042
01043 mManipPart = LL_NO_PART;
01044 gSelectMgr->enableSilhouette(TRUE);
01045
01046
01047 gSelectMgr->sendMultipleUpdate( UPD_POSITION );
01048
01049 mInSnapRegime = FALSE;
01050 gSelectMgr->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
01051
01052 }
01053
01054 return LLManip::handleMouseUp(x, y, mask);
01055 }
01056
01057
01058 void LLManipTranslate::render()
01059 {
01060 glMatrixMode(GL_MODELVIEW);
01061 glPushMatrix();
01062 if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
01063 {
01064 F32 zoom = gAgent.getAvatarObject()->mHUDCurZoom;
01065 glScalef(zoom, zoom, zoom);
01066 }
01067 {
01068 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
01069 renderGuidelines();
01070 }
01071 {
01072 renderTranslationHandles();
01073 renderSnapGuides();
01074 }
01075 glPopMatrix();
01076
01077 renderText();
01078 }
01079
01080 void LLManipTranslate::renderSnapGuides()
01081 {
01082 if (!gSavedSettings.getBOOL("SnapEnabled"))
01083 {
01084 return;
01085 }
01086
01087 F32 max_subdivisions = sGridMaxSubdivisionLevel;
01088 F32 line_alpha = gSavedSettings.getF32("GridOpacity");
01089
01090 LLGLSNoTexture gls_no_texture;
01091 LLGLDepthTest gls_depth(GL_TRUE);
01092 LLGLDisable gls_cull(GL_CULL_FACE);
01093 LLVector3 translate_axis;
01094
01095 if (mManipPart == LL_NO_PART)
01096 {
01097 return;
01098 }
01099
01100 LLSelectNode *first_node = mObjectSelection->getFirstMoveableNode(TRUE);
01101 if (!first_node)
01102 {
01103 return;
01104 }
01105
01106 updateGridSettings();
01107
01108 F32 smallest_grid_unit_scale = getMinGridScale() / max_subdivisions;
01109 LLVector3 grid_origin;
01110 LLVector3 grid_scale;
01111 LLQuaternion grid_rotation;
01112
01113 gSelectMgr->getGrid(grid_origin, grid_rotation, grid_scale);
01114 LLVector3 saved_selection_center = getSavedPivotPoint();
01115 LLVector3 selection_center = getPivotPoint();
01116
01117 LLViewerObject *first_object = first_node->getObject();
01118
01119
01120 if (mManipPart >= LL_X_ARROW && mManipPart <= LL_Z_ARROW)
01121 {
01122 LLVector3 normal;
01123 LLColor4 inner_color;
01124 LLManip::EManipPart temp_manip = mManipPart;
01125 switch (mManipPart)
01126 {
01127 case LL_X_ARROW:
01128 normal.setVec(1,0,0);
01129 inner_color.setVec(0,1,1,line_alpha);
01130 mManipPart = LL_YZ_PLANE;
01131 break;
01132 case LL_Y_ARROW:
01133 normal.setVec(0,1,0);
01134 inner_color.setVec(1,0,1,line_alpha);
01135 mManipPart = LL_XZ_PLANE;
01136 break;
01137 case LL_Z_ARROW:
01138 normal.setVec(0,0,1);
01139 inner_color.setVec(1,1,0,line_alpha);
01140 mManipPart = LL_XY_PLANE;
01141 break;
01142 default:
01143 break;
01144 }
01145
01146 highlightIntersection(normal, selection_center, grid_rotation, inner_color);
01147 mManipPart = temp_manip;
01148 getManipAxis(first_object, mManipPart, translate_axis);
01149
01150 LLVector3 at_axis_abs;
01151 if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
01152 {
01153 at_axis_abs = LLVector3::x_axis * ~grid_rotation;
01154 }
01155 else
01156 {
01157 at_axis_abs = saved_selection_center - gCamera->getOrigin();
01158 at_axis_abs.normVec();
01159
01160 at_axis_abs = at_axis_abs * ~grid_rotation;
01161 }
01162 at_axis_abs.abs();
01163
01164 if (at_axis_abs.mV[VX] > at_axis_abs.mV[VY] && at_axis_abs.mV[VX] > at_axis_abs.mV[VZ])
01165 {
01166 if (mManipPart == LL_Y_ARROW)
01167 {
01168 mSnapOffsetAxis = LLVector3::z_axis;
01169 }
01170 else if (mManipPart == LL_Z_ARROW)
01171 {
01172 mSnapOffsetAxis = LLVector3::y_axis;
01173 }
01174 else if (at_axis_abs.mV[VY] > at_axis_abs.mV[VZ])
01175 {
01176 mSnapOffsetAxis = LLVector3::z_axis;
01177 }
01178 else
01179 {
01180 mSnapOffsetAxis = LLVector3::y_axis;
01181 }
01182 }
01183 else if (at_axis_abs.mV[VY] > at_axis_abs.mV[VZ])
01184 {
01185 if (mManipPart == LL_X_ARROW)
01186 {
01187 mSnapOffsetAxis = LLVector3::z_axis;
01188 }
01189 else if (mManipPart == LL_Z_ARROW)
01190 {
01191 mSnapOffsetAxis = LLVector3::x_axis;
01192 }
01193 else if (at_axis_abs.mV[VX] > at_axis_abs.mV[VZ])
01194 {
01195 mSnapOffsetAxis = LLVector3::z_axis;
01196 }
01197 else
01198 {
01199 mSnapOffsetAxis = LLVector3::x_axis;
01200 }
01201 }
01202 else
01203 {
01204 if (mManipPart == LL_X_ARROW)
01205 {
01206 mSnapOffsetAxis = LLVector3::y_axis;
01207 }
01208 else if (mManipPart == LL_Y_ARROW)
01209 {
01210 mSnapOffsetAxis = LLVector3::x_axis;
01211 }
01212 else if (at_axis_abs.mV[VX] > at_axis_abs.mV[VY])
01213 {
01214 mSnapOffsetAxis = LLVector3::y_axis;
01215 }
01216 else
01217 {
01218 mSnapOffsetAxis = LLVector3::x_axis;
01219 }
01220 }
01221
01222 mSnapOffsetAxis = mSnapOffsetAxis * grid_rotation;
01223
01224 F32 guide_size_meters;
01225
01226 if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
01227 {
01228 guide_size_meters = 1.f / gAgent.getAvatarObject()->mHUDCurZoom;
01229 mSnapOffsetMeters = mArrowLengthMeters * 1.5f;
01230 }
01231 else
01232 {
01233 LLVector3 cam_to_selection = getPivotPoint() - gCamera->getOrigin();
01234 F32 current_range = cam_to_selection.normVec();
01235 guide_size_meters = SNAP_GUIDE_SCREEN_SIZE * gViewerWindow->getWindowHeight() * current_range / gCamera->getPixelMeterRatio();
01236
01237 F32 fraction_of_fov = mAxisArrowLength / (F32) gCamera->getViewHeightInPixels();
01238 F32 apparent_angle = fraction_of_fov * gCamera->getView();
01239 F32 offset_at_camera = tan(apparent_angle) * 1.5f;
01240 F32 range = dist_vec(gAgent.getPosAgentFromGlobal(first_node->mSavedPositionGlobal), gCamera->getOrigin());
01241 mSnapOffsetMeters = range * offset_at_camera;
01242 }
01243
01244 LLVector3 tick_start;
01245 LLVector3 tick_end;
01246
01247
01248 F32 dist_grid_axis = (selection_center - mGridOrigin) * translate_axis;
01249
01250 F32 offset_nearest_grid_unit = fmodf(dist_grid_axis, smallest_grid_unit_scale);
01251
01252 S32 sub_div_offset = llround(fmod(dist_grid_axis - offset_nearest_grid_unit, getMinGridScale() / sGridMinSubdivisionLevel) / smallest_grid_unit_scale);
01253 S32 num_ticks_per_side = llmax(1, llfloor(0.5f * guide_size_meters / smallest_grid_unit_scale));
01254
01255 LLGLDepthTest gls_depth(GL_FALSE);
01256
01257 for (S32 pass = 0; pass < 3; pass++)
01258 {
01259 LLColor4 line_color = setupSnapGuideRenderPass(pass);
01260
01261 glBegin(GL_LINES);
01262 {
01263 LLVector3 line_start = selection_center + (mSnapOffsetMeters * mSnapOffsetAxis) + (translate_axis * (guide_size_meters * 0.5f + offset_nearest_grid_unit));
01264 LLVector3 line_end = selection_center + (mSnapOffsetMeters * mSnapOffsetAxis) - (translate_axis * (guide_size_meters * 0.5f + offset_nearest_grid_unit));
01265 LLVector3 line_mid = (line_start + line_end) * 0.5f;
01266
01267 glColor4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f);
01268 glVertex3fv(line_start.mV);
01269 glColor4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]);
01270 glVertex3fv(line_mid.mV);
01271 glVertex3fv(line_mid.mV);
01272 glColor4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f);
01273 glVertex3fv(line_end.mV);
01274
01275 line_start.setVec(selection_center + (mSnapOffsetAxis * -mSnapOffsetMeters) + (translate_axis * guide_size_meters * 0.5f));
01276 line_end.setVec(selection_center + (mSnapOffsetAxis * -mSnapOffsetMeters) - (translate_axis * guide_size_meters * 0.5f));
01277 line_mid = (line_start + line_end) * 0.5f;
01278
01279 glColor4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f);
01280 glVertex3fv(line_start.mV);
01281 glColor4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]);
01282 glVertex3fv(line_mid.mV);
01283 glVertex3fv(line_mid.mV);
01284 glColor4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f);
01285 glVertex3fv(line_end.mV);
01286
01287 for (S32 i = -num_ticks_per_side; i <= num_ticks_per_side; i++)
01288 {
01289 tick_start = selection_center + (translate_axis * (smallest_grid_unit_scale * (F32)i - offset_nearest_grid_unit));
01290
01291 F32 cur_subdivisions = llclamp(getSubdivisionLevel(tick_start, translate_axis, getMinGridScale()), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
01292
01293 if (fmodf((F32)(i + sub_div_offset), (max_subdivisions / cur_subdivisions)) != 0.f)
01294 {
01295 continue;
01296 }
01297
01298
01299 tick_start += (mSnapOffsetAxis * mSnapOffsetMeters);
01300
01301 BOOL is_sub_tick = FALSE;
01302 F32 tick_scale = 1.f;
01303 for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
01304 {
01305 if (fmodf((F32)(i + sub_div_offset), division_level) == 0.f)
01306 {
01307 break;
01308 }
01309 tick_scale *= 0.7f;
01310 is_sub_tick = TRUE;
01311 }
01312
01313
01314
01315
01316 tick_end = tick_start + (mSnapOffsetAxis * mSnapOffsetMeters * tick_scale);
01317
01318 glColor4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]);
01319 glVertex3fv(tick_start.mV);
01320 glVertex3fv(tick_end.mV);
01321
01322 tick_start = selection_center + (mSnapOffsetAxis * -mSnapOffsetMeters) +
01323 (translate_axis * (getMinGridScale() / (F32)(max_subdivisions) * (F32)i - offset_nearest_grid_unit));
01324 tick_end = tick_start - (mSnapOffsetAxis * mSnapOffsetMeters * tick_scale);
01325
01326 glVertex3fv(tick_start.mV);
01327 glVertex3fv(tick_end.mV);
01328 }
01329 }
01330 glEnd();
01331
01332 if (mInSnapRegime)
01333 {
01334 LLVector3 line_start = selection_center - mSnapOffsetAxis * mSnapOffsetMeters;
01335 LLVector3 line_end = selection_center + mSnapOffsetAxis * mSnapOffsetMeters;
01336
01337 glBegin(GL_LINES);
01338 {
01339 glColor4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]);
01340
01341 glVertex3fv(line_start.mV);
01342 glVertex3fv(line_end.mV);
01343 }
01344 glEnd();
01345
01346
01347 glBegin(GL_TRIANGLES);
01348 {
01349 glColor4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]);
01350
01351 LLVector3 arrow_dir;
01352 LLVector3 arrow_span = translate_axis;
01353
01354 arrow_dir = -mSnapOffsetAxis;
01355 glVertex3fv((line_start + arrow_dir * mConeSize * SNAP_ARROW_SCALE).mV);
01356 glVertex3fv((line_start + arrow_span * mConeSize * SNAP_ARROW_SCALE).mV);
01357 glVertex3fv((line_start - arrow_span * mConeSize * SNAP_ARROW_SCALE).mV);
01358
01359 arrow_dir = mSnapOffsetAxis;
01360 glVertex3fv((line_end + arrow_dir * mConeSize * SNAP_ARROW_SCALE).mV);
01361 glVertex3fv((line_end + arrow_span * mConeSize * SNAP_ARROW_SCALE).mV);
01362 glVertex3fv((line_end - arrow_span * mConeSize * SNAP_ARROW_SCALE).mV);
01363 }
01364 glEnd();
01365 }
01366 }
01367
01368 sub_div_offset = llround(fmod(dist_grid_axis - offset_nearest_grid_unit, getMinGridScale() * 32.f) / smallest_grid_unit_scale);
01369
01370 LLVector2 screen_translate_axis(llabs(translate_axis * gCamera->getLeftAxis()), llabs(translate_axis * gCamera->getUpAxis()));
01371 screen_translate_axis.normVec();
01372
01373 S32 tick_label_spacing = llround(screen_translate_axis * sTickLabelSpacing);
01374
01375
01376 for (S32 i = -num_ticks_per_side; i <= num_ticks_per_side; i++)
01377 {
01378 LLVector3 tick_pos = selection_center + (translate_axis * ((smallest_grid_unit_scale * (F32)i) - offset_nearest_grid_unit));
01379 F32 alpha = line_alpha * (1.f - (0.5f * ((F32)llabs(i) / (F32)num_ticks_per_side)));
01380
01381 F32 tick_scale = 1.f;
01382 for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
01383 {
01384 if (fmodf((F32)(i + sub_div_offset), division_level) == 0.f)
01385 {
01386 break;
01387 }
01388 tick_scale *= 0.7f;
01389 }
01390
01391 if (fmodf((F32)(i + sub_div_offset), (max_subdivisions / llmin(sGridMaxSubdivisionLevel, getSubdivisionLevel(tick_pos, translate_axis, getMinGridScale(), tick_label_spacing)))) == 0.f)
01392 {
01393 F32 snap_offset_meters;
01394
01395 if (mSnapOffsetAxis * gCamera->getUpAxis() > 0.f)
01396 {
01397 snap_offset_meters = mSnapOffsetMeters;
01398 }
01399 else
01400 {
01401 snap_offset_meters = -mSnapOffsetMeters;
01402 }
01403 LLVector3 text_origin = selection_center +
01404 (translate_axis * ((smallest_grid_unit_scale * (F32)i) - offset_nearest_grid_unit)) +
01405 (mSnapOffsetAxis * snap_offset_meters * (1.f + tick_scale));
01406
01407 LLVector3 tick_offset = (tick_pos - mGridOrigin) * ~mGridRotation;
01408 F32 offset_val = 0.5f * tick_offset.mV[ARROW_TO_AXIS[mManipPart]] / getMinGridScale();
01409 EGridMode grid_mode = gSelectMgr->getGridMode();
01410 F32 text_highlight = 0.8f;
01411 if(i - llround(offset_nearest_grid_unit / smallest_grid_unit_scale) == 0 && mInSnapRegime)
01412 {
01413 text_highlight = 1.f;
01414 }
01415
01416 if (grid_mode == GRID_MODE_WORLD)
01417 {
01418
01419 offset_val *= 2.f * grid_scale[ARROW_TO_AXIS[mManipPart]];
01420 renderTickValue(text_origin, offset_val, "m", LLColor4(text_highlight, text_highlight, text_highlight, alpha));
01421 }
01422 else
01423 {
01424 renderTickValue(text_origin, offset_val, "x", LLColor4(text_highlight, text_highlight, text_highlight, alpha));
01425 }
01426 }
01427 }
01428 if (mObjectSelection->getSelectType() != SELECT_TYPE_HUD)
01429 {
01430
01431 if (mHelpTextTimer.getElapsedTimeF32() < sHelpTextVisibleTime + sHelpTextFadeTime && sNumTimesHelpTextShown < sMaxTimesShowHelpText)
01432 {
01433 F32 snap_offset_meters_up;
01434 if (mSnapOffsetAxis * gCamera->getUpAxis() > 0.f)
01435 {
01436 snap_offset_meters_up = mSnapOffsetMeters;
01437 }
01438 else
01439 {
01440 snap_offset_meters_up = -mSnapOffsetMeters;
01441 }
01442
01443 LLVector3 selection_center_start = getSavedPivotPoint();
01444
01445 LLVector3 help_text_pos = selection_center_start + (snap_offset_meters_up * 3.f * mSnapOffsetAxis);
01446 const LLFontGL* big_fontp = LLFontGL::sSansSerif;
01447
01448 LLGLSTexture gls_texture;
01449 std::string help_text = "Move mouse cursor over ruler to snap";
01450 LLColor4 help_text_color = LLColor4::white;
01451 help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, line_alpha, 0.f);
01452 hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
01453 help_text = "to snap to grid";
01454 help_text_pos -= gCamera->getUpAxis() * mSnapOffsetMeters * 0.2f;
01455 hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
01456 }
01457 }
01458 }
01459 else
01460 {
01461
01462
01463 F32 u = 0, v = 0;
01464 LLColor4 inner_color;
01465 LLVector3 normal;
01466 LLVector3 grid_center = selection_center - grid_origin;
01467 F32 usc = 1;
01468 F32 vsc = 1;
01469
01470 grid_center *= ~grid_rotation;
01471
01472 switch (mManipPart)
01473 {
01474 case LL_YZ_PLANE:
01475 u = grid_center.mV[VY];
01476 v = grid_center.mV[VZ];
01477 usc = grid_scale.mV[VY];
01478 vsc = grid_scale.mV[VZ];
01479 inner_color.setVec(0,1,1,line_alpha);
01480 normal.setVec(1,0,0);
01481 break;
01482 case LL_XZ_PLANE:
01483 u = grid_center.mV[VX];
01484 v = grid_center.mV[VZ];
01485 usc = grid_scale.mV[VX];
01486 vsc = grid_scale.mV[VZ];
01487 inner_color.setVec(1,0,1,line_alpha);
01488 normal.setVec(0,1,0);
01489 break;
01490 case LL_XY_PLANE:
01491 u = grid_center.mV[VX];
01492 v = grid_center.mV[VY];
01493 usc = grid_scale.mV[VX];
01494 vsc = grid_scale.mV[VY];
01495 inner_color.setVec(1,1,0,line_alpha);
01496 normal.setVec(0,0,1);
01497 break;
01498 default:
01499 break;
01500 }
01501
01502 highlightIntersection(normal, selection_center, grid_rotation, inner_color);
01503
01504 glPushMatrix();
01505
01506 F32 x,y,z,angle_radians;
01507 grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z);
01508 glTranslatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]);
01509 glRotatef(angle_radians * RAD_TO_DEG, x, y, z);
01510
01511 F32 sz = mGridSizeMeters;
01512 F32 tiles = sz;
01513 glMatrixMode(GL_TEXTURE);
01514 glPushMatrix();
01515 usc = 1.0f/usc;
01516 vsc = 1.0f/vsc;
01517
01518 while (usc > vsc*4.0f)
01519 {
01520 usc *= 0.5f;
01521 }
01522 while (vsc > usc * 4.0f)
01523 {
01524 vsc *= 0.5f;
01525 }
01526
01527 glScalef(usc, vsc, 1.0f);
01528 glTranslatef(u, v, 0);
01529
01530 float a = line_alpha;
01531
01532 LLColor4 col = gColors.getColor("SilhouetteChildColor");
01533 {
01534
01535 LLGLSTexture tex2d;
01536 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
01537
01538 {
01539 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER);
01540 glBindTexture(GL_TEXTURE_2D, sGridTex);
01541 glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
01542 renderGrid(u,v,tiles,0.9f, 0.9f, 0.9f,a*0.15f);
01543 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
01544 }
01545
01546 {
01547 LLGLDisable alpha_test(GL_ALPHA_TEST);
01548
01549 glBindTexture(GL_TEXTURE_2D, 0);
01550 renderGrid(u,v,tiles,0.0f, 0.0f, 0.0f,a*0.16f);
01551
01552
01553 glBindTexture(GL_TEXTURE_2D, sGridTex);
01554 renderGrid(u,v,tiles,1,1,1,a);
01555
01556 glPopMatrix();
01557 glMatrixMode(GL_MODELVIEW);
01558 glPopMatrix();
01559
01560 {
01561 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
01562 renderGuidelines();
01563 }
01564
01565 {
01566 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER);
01567 LLGLEnable stipple(GL_LINE_STIPPLE);
01568 glLineStipple(1, 0x3333);
01569
01570 switch (mManipPart)
01571 {
01572 case LL_YZ_PLANE:
01573 renderGuidelines(FALSE, TRUE, TRUE);
01574 break;
01575 case LL_XZ_PLANE:
01576 renderGuidelines(TRUE, FALSE, TRUE);
01577 break;
01578 case LL_XY_PLANE:
01579 renderGuidelines(TRUE, TRUE, FALSE);
01580 break;
01581 default:
01582 break;
01583 }
01584 }
01585 }
01586 }
01587 }
01588 }
01589
01590 void LLManipTranslate::renderGrid(F32 x, F32 y, F32 size, F32 r, F32 g, F32 b, F32 a)
01591 {
01592 F32 d = size*0.5f;
01593
01594 for (F32 xx = -size-d; xx < size+d; xx += d)
01595 {
01596 glBegin(GL_TRIANGLE_STRIP);
01597 for (F32 yy = -size-d; yy < size+d; yy += d)
01598 {
01599 float dx, dy, da;
01600
01601 dx = xx; dy = yy;
01602 da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a;
01603 glTexCoord2f(dx, dy);
01604 renderGridVert(dx,dy,r,g,b,da);
01605
01606 dx = xx+d; dy = yy;
01607 da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a;
01608 glTexCoord2f(dx, dy);
01609 renderGridVert(dx,dy,r,g,b,da);
01610
01611 dx = xx; dy = yy+d;
01612 da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a;
01613 glTexCoord2f(dx, dy);
01614 renderGridVert(dx,dy,r,g,b,da);
01615
01616 dx = xx+d; dy = yy+d;
01617 da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a;
01618 glTexCoord2f(dx, dy);
01619 renderGridVert(dx,dy,r,g,b,da);
01620 }
01621 glEnd();
01622 }
01623
01624
01625 }
01626
01627 void LLManipTranslate::highlightIntersection(LLVector3 normal,
01628 LLVector3 selection_center,
01629 LLQuaternion grid_rotation,
01630 LLColor4 inner_color)
01631 {
01632 if (!gSavedSettings.getBOOL("GridCrossSections"))
01633 {
01634 return;
01635 }
01636
01637 U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_ALPHA, LLRenderPass::PASS_FULLBRIGHT };
01638
01639 GLuint stencil_mask = 0xFFFFFFFF;
01640
01641 {
01642 glStencilMask(stencil_mask);
01643 glClearStencil(1);
01644 glClear(GL_STENCIL_BUFFER_BIT);
01645 LLGLEnable cull_face(GL_CULL_FACE);
01646 LLGLEnable stencil(GL_STENCIL_TEST);
01647 LLGLDepthTest depth (GL_TRUE, GL_FALSE, GL_ALWAYS);
01648 glStencilFunc(GL_ALWAYS, 0, stencil_mask);
01649
01650
01651
01652 GLboolean mask[4];
01653 glGetBooleanv(GL_COLOR_WRITEMASK,mask);
01654
01655
01656 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
01657 LLGLDisable tex(GL_TEXTURE_2D);
01658 glColor4f(1,1,1,1);
01659
01660
01661 normal = normal * grid_rotation;
01662 if (normal * (gCamera->getOrigin()-selection_center) < 0)
01663 {
01664 normal = -normal;
01665 }
01666 F32 d = -(selection_center * normal);
01667 F64 plane[] = { normal.mV[0], normal.mV[1], normal.mV[2], d };
01668 LLGLEnable clip(GL_CLIP_PLANE0);
01669 glClipPlane(GL_CLIP_PLANE0, plane);
01670
01671 BOOL particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
01672 BOOL clouds = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS);
01673
01674 if (particles)
01675 {
01676 LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
01677 }
01678 if (clouds)
01679 {
01680 LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_CLOUDS);
01681 }
01682
01683
01684 glStencilOp(GL_INCR, GL_INCR, GL_INCR);
01685 glCullFace(GL_FRONT);
01686 for (U32 i = 0; i < 3; i++)
01687 {
01688 gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE);
01689 }
01690
01691 glStencilOp(GL_DECR, GL_DECR, GL_DECR);
01692 glCullFace(GL_BACK);
01693 for (U32 i = 0; i < 3; i++)
01694 {
01695 gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE);
01696 }
01697
01698 if (particles)
01699 {
01700 LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
01701 }
01702 if (clouds)
01703 {
01704 LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_CLOUDS);
01705 }
01706
01707
01708 glColorMask(mask[0], mask[1], mask[2], mask[3]);
01709
01710 }
01711
01712 glPushMatrix();
01713
01714 F32 x,y,z,angle_radians;
01715 grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z);
01716 glTranslatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]);
01717 glRotatef(angle_radians * RAD_TO_DEG, x, y, z);
01718
01719 F32 sz = mGridSizeMeters;
01720 F32 tiles = sz;
01721
01722
01723 {
01724 LLGLDisable tex(GL_TEXTURE_2D);
01725 LLGLDepthTest depth(GL_FALSE);
01726 LLGLEnable stencil(GL_STENCIL_TEST);
01727 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
01728 glStencilFunc(GL_EQUAL, 0, stencil_mask);
01729 renderGrid(0,0,tiles,inner_color.mV[0], inner_color.mV[1], inner_color.mV[2], 0.25f);
01730 }
01731
01732 glPopMatrix();
01733 }
01734
01735 void LLManipTranslate::renderText()
01736 {
01737 if (mObjectSelection->getRootObjectCount() && !mObjectSelection->isAttachment())
01738 {
01739 LLVector3 pos = getPivotPoint();
01740 renderXYZ(pos);
01741 }
01742 else
01743 {
01744 const BOOL children_ok = TRUE;
01745 LLViewerObject* objectp = mObjectSelection->getFirstRootObject(children_ok);
01746 if (objectp)
01747 {
01748 renderXYZ(objectp->getPositionEdit());
01749 }
01750 }
01751 }
01752
01753 void LLManipTranslate::renderTranslationHandles()
01754 {
01755 LLVector3 grid_origin;
01756 LLVector3 grid_scale;
01757 LLQuaternion grid_rotation;
01758 LLGLDepthTest gls_depth(GL_FALSE);
01759
01760 gSelectMgr->getGrid(grid_origin, grid_rotation, grid_scale);
01761 LLVector3 at_axis;
01762 if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
01763 {
01764 at_axis = LLVector3::x_axis * ~grid_rotation;
01765 }
01766 else
01767 {
01768 at_axis = gCamera->getAtAxis() * ~grid_rotation;
01769 }
01770
01771 if (at_axis.mV[VX] > 0.f)
01772 {
01773 mPlaneManipPositions.mV[VX] = 1.f;
01774 }
01775 else
01776 {
01777 mPlaneManipPositions.mV[VX] = -1.f;
01778 }
01779
01780 if (at_axis.mV[VY] > 0.f)
01781 {
01782 mPlaneManipPositions.mV[VY] = 1.f;
01783 }
01784 else
01785 {
01786 mPlaneManipPositions.mV[VY] = -1.f;
01787 }
01788
01789 if (at_axis.mV[VZ] > 0.f)
01790 {
01791 mPlaneManipPositions.mV[VZ] = 1.f;
01792 }
01793 else
01794 {
01795 mPlaneManipPositions.mV[VZ] = -1.f;
01796 }
01797
01798 LLViewerObject *first_object = mObjectSelection->getFirstMoveableObject(TRUE);
01799 if (!first_object) return;
01800
01801 LLVector3 selection_center = getPivotPoint();
01802
01803
01804 if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
01805 {
01806 mArrowLengthMeters = mAxisArrowLength / gViewerWindow->getWindowHeight();
01807 mArrowLengthMeters /= gAgent.getAvatarObject()->mHUDCurZoom;
01808 }
01809 else
01810 {
01811 LLVector3 camera_pos_agent = gAgent.getCameraPositionAgent();
01812 F32 range = dist_vec(camera_pos_agent, selection_center);
01813 F32 range_from_agent = dist_vec(gAgent.getPositionAgent(), selection_center);
01814
01815
01816 if (gSavedSettings.getBOOL("LimitSelectDistance"))
01817 {
01818 if (range_from_agent > gSavedSettings.getF32("MaxSelectDistance"))
01819 {
01820 return;
01821 }
01822 }
01823
01824 if (range > 0.001f)
01825 {
01826
01827 F32 fraction_of_fov = mAxisArrowLength / (F32) gCamera->getViewHeightInPixels();
01828 F32 apparent_angle = fraction_of_fov * gCamera->getView();
01829 mArrowLengthMeters = range * tan(apparent_angle);
01830 }
01831 else
01832 {
01833
01834 mArrowLengthMeters = 1.0f;
01835 }
01836 }
01837
01838 mPlaneManipOffsetMeters = mArrowLengthMeters * 1.8f;
01839 mGridSizeMeters = gSavedSettings.getF32("GridDrawSize");
01840 mConeSize = mArrowLengthMeters / 4.f;
01841
01842 glMatrixMode(GL_MODELVIEW);
01843 glPushMatrix();
01844 {
01845 glTranslatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]);
01846
01847 F32 angle_radians, x, y, z;
01848 grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z);
01849
01850 glRotatef(angle_radians * RAD_TO_DEG, x, y, z);
01851
01852 LLQuaternion invRotation = grid_rotation;
01853 invRotation.conjQuat();
01854
01855 LLVector3 relative_camera_dir;
01856
01857 if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
01858 {
01859 relative_camera_dir = LLVector3::x_axis * invRotation;
01860 }
01861 else
01862 {
01863 relative_camera_dir = (selection_center - gCamera->getOrigin()) * invRotation;
01864 }
01865 relative_camera_dir.normVec();
01866
01867 {
01868 LLGLSNoTexture gls_ui_no_texture;
01869 LLGLDisable cull_face(GL_CULL_FACE);
01870
01871 LLColor4 color1;
01872 LLColor4 color2;
01873
01874
01875 for (S32 index = 0; index < 3; index++)
01876 {
01877 if (index == mManipPart - LL_X_ARROW || index == mHighlightedPart - LL_X_ARROW)
01878 {
01879 mArrowScales.mV[index] = lerp(mArrowScales.mV[index], SELECTED_ARROW_SCALE, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
01880 mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
01881 }
01882 else if (index == mManipPart - LL_YZ_PLANE || index == mHighlightedPart - LL_YZ_PLANE)
01883 {
01884 mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
01885 mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], SELECTED_ARROW_SCALE, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
01886 }
01887 else
01888 {
01889 mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
01890 mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
01891 }
01892 }
01893
01894 if ((mManipPart == LL_NO_PART || mManipPart == LL_YZ_PLANE) && llabs(relative_camera_dir.mV[VX]) > MIN_PLANE_MANIP_DOT_PRODUCT)
01895 {
01896
01897 glPushMatrix();
01898 glScalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]);
01899 glTranslatef(0.f, mPlaneManipOffsetMeters, mPlaneManipOffsetMeters);
01900 glScalef(mPlaneScales.mV[VX], mPlaneScales.mV[VX], mPlaneScales.mV[VX]);
01901 if (mHighlightedPart == LL_YZ_PLANE)
01902 {
01903 color1.setVec(0.f, 1.f, 0.f, 1.f);
01904 color2.setVec(0.f, 0.f, 1.f, 1.f);
01905 }
01906 else
01907 {
01908 color1.setVec(0.f, 1.f, 0.f, 0.6f);
01909 color2.setVec(0.f, 0.f, 1.f, 0.6f);
01910 }
01911 glBegin(GL_TRIANGLES);
01912 {
01913 glColor4fv(color1.mV);
01914 glVertex3f(0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f));
01915 glVertex3f(0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f));
01916 glVertex3f(0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f));
01917
01918 glColor4fv(color2.mV);
01919 glVertex3f(0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f));
01920 glVertex3f(0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f));
01921 glVertex3f(0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f));
01922 }
01923 glEnd();
01924
01925 LLUI::setLineWidth(3.0f);
01926 glBegin(GL_LINES);
01927 {
01928 glColor4f(0.f, 0.f, 0.f, 0.3f);
01929 glVertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
01930 glVertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
01931 glVertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
01932 glVertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f);
01933 glVertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
01934 glVertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f);
01935
01936 glVertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
01937 glVertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f);
01938 glVertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f);
01939 glVertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f);
01940 glVertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f);
01941 glVertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f);
01942 }
01943 glEnd();
01944 LLUI::setLineWidth(1.0f);
01945 glPopMatrix();
01946 }
01947
01948 if ((mManipPart == LL_NO_PART || mManipPart == LL_XZ_PLANE) && llabs(relative_camera_dir.mV[VY]) > MIN_PLANE_MANIP_DOT_PRODUCT)
01949 {
01950
01951 glPushMatrix();
01952 glScalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]);
01953 glTranslatef(mPlaneManipOffsetMeters, 0.f, mPlaneManipOffsetMeters);
01954 glScalef(mPlaneScales.mV[VY], mPlaneScales.mV[VY], mPlaneScales.mV[VY]);
01955 if (mHighlightedPart == LL_XZ_PLANE)
01956 {
01957 color1.setVec(0.f, 0.f, 1.f, 1.f);
01958 color2.setVec(1.f, 0.f, 0.f, 1.f);
01959 }
01960 else
01961 {
01962 color1.setVec(0.f, 0.f, 1.f, 0.6f);
01963 color2.setVec(1.f, 0.f, 0.f, 0.6f);
01964 }
01965
01966 glBegin(GL_TRIANGLES);
01967 {
01968 glColor4fv(color1.mV);
01969 glVertex3f(mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f));
01970 glVertex3f(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), 0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f));
01971 glVertex3f(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f));
01972
01973 glColor4fv(color2.mV);
01974 glVertex3f(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f));
01975 glVertex3f(mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f));
01976 glVertex3f(mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f));
01977 }
01978 glEnd();
01979
01980 LLUI::setLineWidth(3.0f);
01981 glBegin(GL_LINES);
01982 {
01983 glColor4f(0.f, 0.f, 0.f, 0.3f);
01984 glVertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
01985 glVertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
01986 glVertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
01987 glVertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f);
01988 glVertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
01989 glVertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f);
01990
01991 glVertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
01992 glVertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f);
01993 glVertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f);
01994 glVertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f);
01995 glVertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f);
01996 glVertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f);
01997 }
01998 glEnd();
01999 LLUI::setLineWidth(1.0f);
02000
02001 glPopMatrix();
02002 }
02003
02004 if ((mManipPart == LL_NO_PART || mManipPart == LL_XY_PLANE) && llabs(relative_camera_dir.mV[VZ]) > MIN_PLANE_MANIP_DOT_PRODUCT)
02005 {
02006
02007 glPushMatrix();
02008 glScalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]);
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018 LLVector3 v0,v1,v2,v3;
02019 #if 0
02020
02021 glTranslatef(-mPlaneManipOffsetMeters, -mPlaneManipOffsetMeters, 0.f);
02022 v0 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), 0.f);
02023 v1 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.75f), 0.f);
02024 v2 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f);
02025 v3 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.75f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f);
02026 #else
02027 glTranslatef(mPlaneManipOffsetMeters, mPlaneManipOffsetMeters, 0.f);
02028 v0 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f);
02029 v1 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), 0.f);
02030 v2 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), 0.f);
02031 v3 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), 0.f);
02032 #endif
02033 glScalef(mPlaneScales.mV[VZ], mPlaneScales.mV[VZ], mPlaneScales.mV[VZ]);
02034 if (mHighlightedPart == LL_XY_PLANE)
02035 {
02036 color1.setVec(1.f, 0.f, 0.f, 1.f);
02037 color2.setVec(0.f, 1.f, 0.f, 1.f);
02038 }
02039 else
02040 {
02041 color1.setVec(0.8f, 0.f, 0.f, 0.6f);
02042 color2.setVec(0.f, 0.8f, 0.f, 0.6f);
02043 }
02044
02045 glBegin(GL_TRIANGLES);
02046 {
02047 glColor4fv(color1.mV);
02048 glVertex3fv(v0.mV);
02049 glVertex3fv(v1.mV);
02050 glVertex3fv(v2.mV);
02051
02052 glColor4fv(color2.mV);
02053 glVertex3fv(v2.mV);
02054 glVertex3fv(v3.mV);
02055 glVertex3fv(v0.mV);
02056 }
02057 glEnd();
02058
02059 LLUI::setLineWidth(3.0f);
02060 glBegin(GL_LINES);
02061 {
02062 glColor4f(0.f, 0.f, 0.f, 0.3f);
02063 LLVector3 v12 = (v1 + v2) * .5f;
02064 glVertex3fv(v0.mV);
02065 glVertex3fv(v12.mV);
02066 glVertex3fv(v12.mV);
02067 glVertex3fv((v12 + (v0-v12)*.3f + (v2-v12)*.3f).mV);
02068 glVertex3fv(v12.mV);
02069 glVertex3fv((v12 + (v0-v12)*.3f + (v1-v12)*.3f).mV);
02070
02071 LLVector3 v23 = (v2 + v3) * .5f;
02072 glVertex3fv(v0.mV);
02073 glVertex3fv(v23.mV);
02074 glVertex3fv(v23.mV);
02075 glVertex3fv((v23 + (v0-v23)*.3f + (v3-v23)*.3f).mV);
02076 glVertex3fv(v23.mV);
02077 glVertex3fv((v23 + (v0-v23)*.3f + (v2-v23)*.3f).mV);
02078 }
02079 glEnd();
02080 LLUI::setLineWidth(1.0f);
02081
02082 glPopMatrix();
02083 }
02084 }
02085 {
02086 LLGLSNoTexture gls_ui_no_texture;
02087
02088
02089
02090
02091
02092 LLVector3 pos_agent = first_object->getPositionAgent();
02093 LLVector3 camera_agent = gAgent.getCameraPositionAgent();
02094 LLVector3 headPos = pos_agent - camera_agent;
02095
02096 LLVector3 orientWRTHead = headPos * invRotation;
02097
02098
02099 U32 nearest = (orientWRTHead.mV[0] < 0.0f ? 1 : 0) +
02100 (orientWRTHead.mV[1] < 0.0f ? 2 : 0) +
02101 (orientWRTHead.mV[2] < 0.0f ? 4 : 0);
02102
02103
02104
02105
02106
02107
02108
02109 static U32 face_list[8][NUM_AXES*2] = {
02110 { 2,0,1, 4,5,3 },
02111 { 2,0,3, 4,5,1 },
02112 { 4,0,1, 2,5,3 },
02113 { 4,0,3, 2,5,1 },
02114 { 2,5,1, 4,0,3 },
02115 { 2,5,3, 4,0,1 },
02116 { 4,5,1, 2,0,3 },
02117 { 4,5,3, 2,0,1 },
02118 };
02119 static const EManipPart which_arrow[6] = {
02120 LL_Z_ARROW,
02121 LL_X_ARROW,
02122 LL_Y_ARROW,
02123 LL_X_ARROW,
02124 LL_Y_ARROW,
02125 LL_Z_ARROW};
02126
02127
02128 LLVector3 camera_axis;
02129 if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
02130 {
02131 camera_axis = LLVector3::x_axis;
02132 }
02133 else
02134 {
02135 camera_axis.setVec(gAgent.getCameraPositionAgent() - first_object->getPositionAgent());
02136 }
02137
02138 for (U32 i = 0; i < NUM_AXES*2; i++)
02139 {
02140 U32 face = face_list[nearest][i];
02141
02142 LLVector3 arrow_axis;
02143 getManipAxis(first_object, which_arrow[face], arrow_axis);
02144
02145 if (fabs(angle_between(camera_axis, arrow_axis) - F_PI_BY_TWO) < F_PI_BY_TWO - HANDLE_HIDE_ANGLE)
02146 {
02147 renderArrow(which_arrow[face],
02148 mManipPart,
02149 (face >= 3) ? -mConeSize : mConeSize,
02150 (face >= 3) ? -mArrowLengthMeters : mArrowLengthMeters,
02151 mConeSize,
02152 FALSE);
02153 }
02154 }
02155 }
02156 }
02157 glPopMatrix();
02158 }
02159
02160
02161 void LLManipTranslate::renderArrow(S32 which_arrow, S32 selected_arrow, F32 box_size, F32 arrow_size, F32 handle_size, BOOL reverse_direction)
02162 {
02163 LLGLSNoTexture gls_ui_no_texture;
02164 LLGLEnable gls_blend(GL_BLEND);
02165 LLGLEnable gls_color_material(GL_COLOR_MATERIAL);
02166
02167 for (S32 pass = 1; pass <= 2; pass++)
02168 {
02169 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, pass == 1 ? GL_LEQUAL : GL_GREATER);
02170 glPushMatrix();
02171
02172 S32 index = 0;
02173
02174 index = ARROW_TO_AXIS[which_arrow];
02175
02176
02177 LLColor4 color;
02178 if (which_arrow == selected_arrow || which_arrow == mHighlightedPart)
02179 {
02180 color.mV[index] = (pass == 1) ? 1.f : 0.5f;
02181 }
02182 else if (selected_arrow != LL_NO_PART)
02183 {
02184 color.mV[VALPHA] = 0.f;
02185 }
02186 else
02187 {
02188 color.mV[index] = pass == 1 ? .8f : .35f ;
02189 color.mV[VALPHA] = 0.6f;
02190 }
02191 glColor4fv( color.mV );
02192
02193 LLVector3 vec;
02194
02195 {
02196
02197
02198
02199
02200 LLUI::setLineWidth(2.0f);
02201 glBegin(GL_LINES);
02202 vec.mV[index] = box_size;
02203 glVertex3f(vec.mV[0], vec.mV[1], vec.mV[2]);
02204
02205 vec.mV[index] = arrow_size;
02206 glVertex3f(vec.mV[0], vec.mV[1], vec.mV[2]);
02207 glEnd();
02208 LLUI::setLineWidth(1.0f);
02209 }
02210
02211 glTranslatef(vec.mV[0], vec.mV[1], vec.mV[2]);
02212 glScalef(handle_size, handle_size, handle_size);
02213
02214 F32 rot = 0.0f;
02215 LLVector3 axis;
02216
02217 switch(which_arrow)
02218 {
02219 case LL_X_ARROW:
02220 rot = reverse_direction ? -90.0f : 90.0f;
02221 axis.mV[1] = 1.0f;
02222 break;
02223 case LL_Y_ARROW:
02224 rot = reverse_direction ? 90.0f : -90.0f;
02225 axis.mV[0] = 1.0f;
02226 break;
02227 case LL_Z_ARROW:
02228 rot = reverse_direction ? 180.0f : 0.0f;
02229 axis.mV[0] = 1.0f;
02230 break;
02231 default:
02232 llerrs << "renderArrow called with bad arrow " << which_arrow << llendl;
02233 break;
02234 }
02235
02236 glRotatef(rot, axis.mV[0], axis.mV[1], axis.mV[2]);
02237 glScalef(mArrowScales.mV[index], mArrowScales.mV[index], mArrowScales.mV[index] * 1.5f);
02238
02239 gCone.render(CONE_LOD_HIGHEST);
02240
02241 glPopMatrix();
02242 }
02243 }
02244
02245 void LLManipTranslate::renderGridVert(F32 x_trans, F32 y_trans, F32 r, F32 g, F32 b, F32 alpha)
02246 {
02247 glColor4f(r, g, b, alpha);
02248 switch (mManipPart)
02249 {
02250 case LL_YZ_PLANE:
02251 glVertex3f(0, x_trans, y_trans);
02252 break;
02253 case LL_XZ_PLANE:
02254 glVertex3f(x_trans, 0, y_trans);
02255 break;
02256 case LL_XY_PLANE:
02257 glVertex3f(x_trans, y_trans, 0);
02258 break;
02259 default:
02260 glVertex3f(0,0,0);
02261 break;
02262 }
02263
02264 }
02265
02266
02267 BOOL LLManipTranslate::canAffectSelection()
02268 {
02269 BOOL can_move = mObjectSelection->getObjectCount() != 0;
02270 if (can_move)
02271 {
02272 struct f : public LLSelectedObjectFunctor
02273 {
02274 virtual bool apply(LLViewerObject* objectp)
02275 {
02276 return objectp->permMove() && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
02277 }
02278 } func;
02279 can_move = mObjectSelection->applyToObjects(&func);
02280 }
02281 return can_move;
02282 }