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