aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/lltoolgrab.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/lltoolgrab.cpp')
-rw-r--r--linden/indra/newview/lltoolgrab.cpp381
1 files changed, 300 insertions, 81 deletions
diff --git a/linden/indra/newview/lltoolgrab.cpp b/linden/indra/newview/lltoolgrab.cpp
index a8e789d..5eb688b 100644
--- a/linden/indra/newview/lltoolgrab.cpp
+++ b/linden/indra/newview/lltoolgrab.cpp
@@ -75,15 +75,12 @@ extern BOOL gDebugClicks;
75// Methods 75// Methods
76// 76//
77LLToolGrab::LLToolGrab( LLToolComposite* composite ) 77LLToolGrab::LLToolGrab( LLToolComposite* composite )
78: LLTool( "Grab", composite ), 78: LLTool( std::string("Grab"), composite ),
79 mMode( GRAB_INACTIVE ), 79 mMode( GRAB_INACTIVE ),
80 mVerticalDragging( FALSE ), 80 mVerticalDragging( FALSE ),
81 mHitLand(FALSE),
82 mHitObjectID(),
83 mGrabObject( NULL ),
84 mMouseDownX( -1 ),
85 mMouseDownY( -1 ),
86 mHasMoved( FALSE ), 81 mHasMoved( FALSE ),
82 mOutsideSlop(FALSE),
83 mDeselectedThisClick(FALSE),
87 mSpinGrabbing( FALSE ), 84 mSpinGrabbing( FALSE ),
88 mSpinRotation(), 85 mSpinRotation(),
89 mHideBuildHighlight(FALSE) 86 mHideBuildHighlight(FALSE)
@@ -131,24 +128,23 @@ BOOL LLToolGrab::handleMouseDown(S32 x, S32 y, MASK mask)
131 llinfos << "LLToolGrab handleMouseDown" << llendl; 128 llinfos << "LLToolGrab handleMouseDown" << llendl;
132 } 129 }
133 130
134 mHitLand = FALSE;
135
136 // call the base class to propogate info to sim 131 // call the base class to propogate info to sim
137 LLTool::handleMouseDown(x, y, mask); 132 LLTool::handleMouseDown(x, y, mask);
138 133
139 if (!gAgent.leftButtonGrabbed()) 134 if (!gAgent.leftButtonGrabbed())
140 { 135 {
141 // can grab transparent objects (how touch event propagates, scripters rely on this) 136 // can grab transparent objects (how touch event propagates, scripters rely on this)
142 gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback, TRUE); 137 gViewerWindow->pickAsync(x, y, mask, pickCallback, TRUE, TRUE);
143 } 138 }
144 return TRUE; 139 return TRUE;
145} 140}
146 141
147void LLToolGrab::pickCallback(S32 x, S32 y, MASK mask) 142void LLToolGrab::pickCallback(const LLPickInfo& pick_info)
148{ 143{
149 LLViewerObject *objectp = gObjectList.findObject( gLastHitObjectID ); 144 LLToolGrab::getInstance()->mGrabPick = pick_info;
145 LLViewerObject *objectp = pick_info.getObject();
150 146
151 BOOL extend_select = (mask & MASK_SHIFT); 147 BOOL extend_select = (pick_info.mKeyMask & MASK_SHIFT);
152 148
153 if (!extend_select && !LLSelectMgr::getInstance()->getSelection()->isEmpty()) 149 if (!extend_select && !LLSelectMgr::getInstance()->getSelection()->isEmpty())
154 { 150 {
@@ -165,23 +161,22 @@ void LLToolGrab::pickCallback(S32 x, S32 y, MASK mask)
165 { 161 {
166 LLToolGrab::getInstance()->setMouseCapture(TRUE); 162 LLToolGrab::getInstance()->setMouseCapture(TRUE);
167 LLToolGrab::getInstance()->mMode = GRAB_NOOBJECT; 163 LLToolGrab::getInstance()->mMode = GRAB_NOOBJECT;
168 LLToolGrab::getInstance()->mHitObjectID.setNull(); 164 LLToolGrab::getInstance()->mGrabPick.mObjectID.setNull();
169 } 165 }
170 else 166 else
171 { 167 {
172 LLToolGrab::getInstance()->handleObjectHit(objectp, x, y, mask); 168 LLToolGrab::getInstance()->handleObjectHit(LLToolGrab::getInstance()->mGrabPick);
173 } 169 }
174} 170}
175 171
176BOOL LLToolGrab::handleObjectHit(LLViewerObject *objectp, S32 x, S32 y, MASK mask) 172BOOL LLToolGrab::handleObjectHit(const LLPickInfo& info)
177{ 173{
178 mMouseDownX = x; 174 mGrabPick = info;
179 mMouseDownY = y; 175 LLViewerObject* objectp = mGrabPick.getObject();
180 mMouseMask = mask;
181 176
182 if (gDebugClicks) 177 if (gDebugClicks)
183 { 178 {
184 llinfos << "LLToolGrab handleObjectHit " << mMouseDownX << "," << mMouseDownY << llendl; 179 llinfos << "LLToolGrab handleObjectHit " << info.mMousePt.mX << "," << info.mMousePt.mY << llendl;
185 } 180 }
186 181
187 if (NULL == objectp) // unexpected 182 if (NULL == objectp) // unexpected
@@ -202,8 +197,6 @@ BOOL LLToolGrab::handleObjectHit(LLViewerObject *objectp, S32 x, S32 y, MASK mas
202 197
203 setMouseCapture( TRUE ); 198 setMouseCapture( TRUE );
204 199
205 mHitObjectID = objectp->getID();
206
207 // Grabs always start from the root 200 // Grabs always start from the root
208 // objectp = (LLViewerObject *)objectp->getRoot(); 201 // objectp = (LLViewerObject *)objectp->getRoot();
209 202
@@ -223,13 +216,13 @@ BOOL LLToolGrab::handleObjectHit(LLViewerObject *objectp, S32 x, S32 y, MASK mas
223 if (gAgent.cameraMouselook() && !script_touch) 216 if (gAgent.cameraMouselook() && !script_touch)
224 { 217 {
225 mMode = GRAB_LOCKED; 218 mMode = GRAB_LOCKED;
219 gViewerWindow->hideCursor();
220 gViewerWindow->moveCursorToCenter();
226 } 221 }
227 else 222 else
228 { 223 {
229 mMode = GRAB_NONPHYSICAL; 224 mMode = GRAB_NONPHYSICAL;
230 } 225 }
231 gViewerWindow->hideCursor();
232 gViewerWindow->moveCursorToCenter();
233 // Don't bail out here, go on and grab so buttons can get 226 // Don't bail out here, go on and grab so buttons can get
234 // their "touched" event. 227 // their "touched" event.
235 } 228 }
@@ -254,20 +247,18 @@ BOOL LLToolGrab::handleObjectHit(LLViewerObject *objectp, S32 x, S32 y, MASK mas
254 247
255 // Always send "touched" message 248 // Always send "touched" message
256 249
250 mLastMouseX = gViewerWindow->getCurrentMouseX();
251 mLastMouseY = gViewerWindow->getCurrentMouseY();
257 mAccumDeltaX = 0; 252 mAccumDeltaX = 0;
258 mAccumDeltaY = 0; 253 mAccumDeltaY = 0;
259 mHasMoved = FALSE; 254 mHasMoved = FALSE;
260 mOutsideSlop = FALSE; 255 mOutsideSlop = FALSE;
261 256
262 mGrabObject = objectp; 257 mVerticalDragging = (info.mKeyMask == MASK_VERTICAL) || gGrabBtnVertical;
263 258
264 mGrabOffset.clearVec(); 259 startGrab();
265 260
266 mVerticalDragging = (mask == MASK_VERTICAL) || gGrabBtnVertical; 261 if ((info.mKeyMask == MASK_SPIN) || gGrabBtnSpin)
267
268 startGrab(x, y);
269
270 if ((mask == MASK_SPIN) || gGrabBtnSpin)
271 { 262 {
272 startSpin(); 263 startSpin();
273 } 264 }
@@ -275,10 +266,10 @@ BOOL LLToolGrab::handleObjectHit(LLViewerObject *objectp, S32 x, S32 y, MASK mas
275 LLSelectMgr::getInstance()->updateSelectionCenter(); // update selection beam 266 LLSelectMgr::getInstance()->updateSelectionCenter(); // update selection beam
276 267
277 // update point at 268 // update point at
278 LLViewerObject *edit_object = gObjectList.findObject(mHitObjectID); 269 LLViewerObject *edit_object = info.getObject();
279 if (edit_object) 270 if (edit_object && info.mPickType != LLPickInfo::PICK_FLORA)
280 { 271 {
281 LLVector3 local_edit_point = gAgent.getPosAgentFromGlobal(gLastHitNonFloraPosGlobal); 272 LLVector3 local_edit_point = gAgent.getPosAgentFromGlobal(info.mPosGlobal);
282 local_edit_point -= edit_object->getPositionAgent(); 273 local_edit_point -= edit_object->getPositionAgent();
283 local_edit_point = local_edit_point * ~edit_object->getRenderRotation(); 274 local_edit_point = local_edit_point * ~edit_object->getRenderRotation();
284 gAgent.setPointAt(POINTAT_TARGET_GRAB, edit_object, local_edit_point ); 275 gAgent.setPointAt(POINTAT_TARGET_GRAB, edit_object, local_edit_point );
@@ -300,10 +291,15 @@ BOOL LLToolGrab::handleObjectHit(LLViewerObject *objectp, S32 x, S32 y, MASK mas
300 291
301void LLToolGrab::startSpin() 292void LLToolGrab::startSpin()
302{ 293{
294 LLViewerObject* objectp = mGrabPick.getObject();
295 if (!objectp)
296 {
297 return;
298 }
303 mSpinGrabbing = TRUE; 299 mSpinGrabbing = TRUE;
304 300
305 // Was saveSelectedObjectTransform() 301 // Was saveSelectedObjectTransform()
306 LLViewerObject *root = (LLViewerObject *)mGrabObject->getRoot(); 302 LLViewerObject *root = (LLViewerObject *)objectp->getRoot();
307 mSpinRotation = root->getRotation(); 303 mSpinRotation = root->getRotation();
308 304
309 LLMessageSystem *msg = gMessageSystem; 305 LLMessageSystem *msg = gMessageSystem;
@@ -312,8 +308,8 @@ void LLToolGrab::startSpin()
312 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); 308 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
313 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 309 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
314 msg->nextBlockFast(_PREHASH_ObjectData); 310 msg->nextBlockFast(_PREHASH_ObjectData);
315 msg->addUUIDFast(_PREHASH_ObjectID, mGrabObject->getID() ); 311 msg->addUUIDFast(_PREHASH_ObjectID, mGrabPick.mObjectID );
316 msg->sendMessage( mGrabObject->getRegion()->getHost() ); 312 msg->sendMessage( objectp->getRegion()->getHost() );
317} 313}
318 314
319 315
@@ -321,6 +317,12 @@ void LLToolGrab::stopSpin()
321{ 317{
322 mSpinGrabbing = FALSE; 318 mSpinGrabbing = FALSE;
323 319
320 LLViewerObject* objectp = mGrabPick.getObject();
321 if (!objectp)
322 {
323 return;
324 }
325
324 LLMessageSystem *msg = gMessageSystem; 326 LLMessageSystem *msg = gMessageSystem;
325 switch(mMode) 327 switch(mMode)
326 { 328 {
@@ -332,8 +334,8 @@ void LLToolGrab::stopSpin()
332 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); 334 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
333 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 335 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
334 msg->nextBlockFast(_PREHASH_ObjectData); 336 msg->nextBlockFast(_PREHASH_ObjectData);
335 msg->addUUIDFast(_PREHASH_ObjectID, mGrabObject->getID() ); 337 msg->addUUIDFast(_PREHASH_ObjectID, objectp->getID() );
336 msg->sendMessage( mGrabObject->getRegion()->getHost() ); 338 msg->sendMessage( objectp->getRegion()->getHost() );
337 break; 339 break;
338 340
339 case GRAB_NOOBJECT: 341 case GRAB_NOOBJECT:
@@ -345,11 +347,17 @@ void LLToolGrab::stopSpin()
345} 347}
346 348
347 349
348void LLToolGrab::startGrab(S32 x, S32 y) 350void LLToolGrab::startGrab()
349{ 351{
350 // Compute grab_offset in the OBJECT's root's coordinate frame 352 // Compute grab_offset in the OBJECT's root's coordinate frame
351 // (sometimes root == object) 353 // (sometimes root == object)
352 LLViewerObject *root = (LLViewerObject *)mGrabObject->getRoot(); 354 LLViewerObject* objectp = mGrabPick.getObject();
355 if (!objectp)
356 {
357 return;
358 }
359
360 LLViewerObject *root = (LLViewerObject *)objectp->getRoot();
353 361
354 // drag from center 362 // drag from center
355 LLVector3d grab_start_global = root->getPositionGlobal(); 363 LLVector3d grab_start_global = root->getPositionGlobal();
@@ -358,7 +366,7 @@ void LLToolGrab::startGrab(S32 x, S32 y)
358 // JC - This code looks wonky, but I believe it does the right thing. 366 // JC - This code looks wonky, but I believe it does the right thing.
359 // Otherwise, when you grab a linked object set, it "pops" on the start 367 // Otherwise, when you grab a linked object set, it "pops" on the start
360 // of the drag. 368 // of the drag.
361 LLVector3d grab_offsetd = root->getPositionGlobal() - mGrabObject->getPositionGlobal(); 369 LLVector3d grab_offsetd = root->getPositionGlobal() - objectp->getPositionGlobal();
362 370
363 LLVector3 grab_offset; 371 LLVector3 grab_offset;
364 grab_offset.setVec(grab_offsetd); 372 grab_offset.setVec(grab_offsetd);
@@ -377,22 +385,34 @@ void LLToolGrab::startGrab(S32 x, S32 y)
377 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); 385 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
378 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 386 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
379 msg->nextBlockFast(_PREHASH_ObjectData); 387 msg->nextBlockFast(_PREHASH_ObjectData);
380 msg->addU32Fast(_PREHASH_LocalID, mGrabObject->mLocalID); 388 msg->addU32Fast(_PREHASH_LocalID, objectp->mLocalID);
381 msg->addVector3Fast(_PREHASH_GrabOffset, grab_offset ); 389 msg->addVector3Fast(_PREHASH_GrabOffset, grab_offset );
382 msg->sendMessage( mGrabObject->getRegion()->getHost()); 390 msg->nextBlock("SurfaceInfo");
391 msg->addVector3("UVCoord", LLVector3(mGrabPick.mUVCoords));
392 msg->addVector3("STCoord", LLVector3(mGrabPick.mSTCoords));
393 msg->addS32Fast(_PREHASH_FaceIndex, mGrabPick.mObjectFace);
394 msg->addVector3("Position", mGrabPick.mIntersection);
395 msg->addVector3("Normal", mGrabPick.mNormal);
396 msg->addVector3("Binormal", mGrabPick.mBinormal);
397 msg->sendMessage( objectp->getRegion()->getHost());
383 398
384 mGrabOffsetFromCenterInitial = grab_offset; 399 mGrabOffsetFromCenterInitial = grab_offset;
385 mGrabHiddenOffsetFromCamera = mDragStartFromCamera; 400 mGrabHiddenOffsetFromCamera = mDragStartFromCamera;
386 401
387 mGrabTimer.reset(); 402 mGrabTimer.reset();
403
404 mLastUVCoords = mGrabPick.mUVCoords;
405 mLastSTCoords = mGrabPick.mSTCoords;
406 mLastFace = mGrabPick.mObjectFace;
407 mLastIntersection = mGrabPick.mIntersection;
408 mLastNormal = mGrabPick.mNormal;
409 mLastBinormal = mGrabPick.mBinormal;
410 mLastGrabPos = LLVector3(-1.f, -1.f, -1.f);
388} 411}
389 412
390 413
391BOOL LLToolGrab::handleHover(S32 x, S32 y, MASK mask) 414BOOL LLToolGrab::handleHover(S32 x, S32 y, MASK mask)
392{ 415{
393 mLastMouseX = x;
394 mLastMouseY = y;
395
396 if (!gViewerWindow->getLeftMouseDown()) 416 if (!gViewerWindow->getLeftMouseDown())
397 { 417 {
398 gViewerWindow->setCursor(UI_CURSOR_TOOLGRAB); 418 gViewerWindow->setCursor(UI_CURSOR_TOOLGRAB);
@@ -404,9 +424,12 @@ BOOL LLToolGrab::handleHover(S32 x, S32 y, MASK mask)
404 switch( mMode ) 424 switch( mMode )
405 { 425 {
406 case GRAB_ACTIVE_CENTER: 426 case GRAB_ACTIVE_CENTER:
407 case GRAB_NONPHYSICAL:
408 handleHoverActive( x, y, mask ); // cursor hidden 427 handleHoverActive( x, y, mask ); // cursor hidden
409 break; 428 break;
429
430 case GRAB_NONPHYSICAL:
431 handleHoverNonPhysical(x, y, mask);
432 break;
410 433
411 case GRAB_INACTIVE: 434 case GRAB_INACTIVE:
412 handleHoverInactive( x, y, mask ); // cursor set here 435 handleHoverInactive( x, y, mask ); // cursor set here
@@ -419,18 +442,24 @@ BOOL LLToolGrab::handleHover(S32 x, S32 y, MASK mask)
419 442
420 } 443 }
421 444
445 mLastMouseX = x;
446 mLastMouseY = y;
447
422 return TRUE; 448 return TRUE;
423} 449}
424 450
451const F32 GRAB_SENSITIVITY_X = 0.0075f;
452const F32 GRAB_SENSITIVITY_Y = 0.0075f;
453
425 454
426 455
427 456
428// Dragging. 457// Dragging.
429void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask) 458void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
430{ 459{
431 llassert( hasMouseCapture() ); 460 LLViewerObject* objectp = mGrabPick.getObject();
432 llassert( mGrabObject ); 461 if (!objectp || !hasMouseCapture() ) return;
433 if (mGrabObject->isDead()) 462 if (objectp->isDead())
434 { 463 {
435 // Bail out of drag because object has been killed 464 // Bail out of drag because object has been killed
436 setMouseCapture(FALSE); 465 setMouseCapture(FALSE);
@@ -459,7 +488,7 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
459 // ...switch to horizontal dragging 488 // ...switch to horizontal dragging
460 mVerticalDragging = FALSE; 489 mVerticalDragging = FALSE;
461 490
462 mDragStartPointGlobal = gViewerWindow->clickPointInWorldGlobal(x, y, mGrabObject); 491 mDragStartPointGlobal = gViewerWindow->clickPointInWorldGlobal(x, y, objectp);
463 mDragStartFromCamera = mDragStartPointGlobal - gAgent.getCameraPositionGlobal(); 492 mDragStartFromCamera = mDragStartPointGlobal - gAgent.getCameraPositionGlobal();
464 } 493 }
465 else if (!mVerticalDragging && (mask == MASK_VERTICAL) ) 494 else if (!mVerticalDragging && (mask == MASK_VERTICAL) )
@@ -467,16 +496,13 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
467 // ...switch to vertical dragging 496 // ...switch to vertical dragging
468 mVerticalDragging = TRUE; 497 mVerticalDragging = TRUE;
469 498
470 mDragStartPointGlobal = gViewerWindow->clickPointInWorldGlobal(x, y, mGrabObject); 499 mDragStartPointGlobal = gViewerWindow->clickPointInWorldGlobal(x, y, objectp);
471 mDragStartFromCamera = mDragStartPointGlobal - gAgent.getCameraPositionGlobal(); 500 mDragStartFromCamera = mDragStartPointGlobal - gAgent.getCameraPositionGlobal();
472 } 501 }
473 502
474 const F32 RADIANS_PER_PIXEL_X = 0.01f; 503 const F32 RADIANS_PER_PIXEL_X = 0.01f;
475 const F32 RADIANS_PER_PIXEL_Y = 0.01f; 504 const F32 RADIANS_PER_PIXEL_Y = 0.01f;
476 505
477 const F32 SENSITIVITY_X = 0.0075f;
478 const F32 SENSITIVITY_Y = 0.0075f;
479
480 S32 dx = x - (gViewerWindow->getWindowWidth() / 2); 506 S32 dx = x - (gViewerWindow->getWindowWidth() / 2);
481 S32 dy = y - (gViewerWindow->getWindowHeight() / 2); 507 S32 dy = y - (gViewerWindow->getWindowHeight() / 2);
482 508
@@ -518,9 +544,9 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
518 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); 544 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
519 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 545 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
520 msg->nextBlockFast(_PREHASH_ObjectData); 546 msg->nextBlockFast(_PREHASH_ObjectData);
521 msg->addUUIDFast(_PREHASH_ObjectID, mGrabObject->getID() ); 547 msg->addUUIDFast(_PREHASH_ObjectID, objectp->getID() );
522 msg->addQuatFast(_PREHASH_Rotation, mSpinRotation ); 548 msg->addQuatFast(_PREHASH_Rotation, mSpinRotation );
523 msg->sendMessage( mGrabObject->getRegion()->getHost() ); 549 msg->sendMessage( objectp->getRegion()->getHost() );
524 } 550 }
525 else 551 else
526 { 552 {
@@ -548,8 +574,8 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
548 } 574 }
549 575
550 mGrabHiddenOffsetFromCamera = mGrabHiddenOffsetFromCamera 576 mGrabHiddenOffsetFromCamera = mGrabHiddenOffsetFromCamera
551 + (x_part * (-dx * SENSITIVITY_X)) 577 + (x_part * (-dx * GRAB_SENSITIVITY_X))
552 + (y_part * ( dy * SENSITIVITY_Y)); 578 + (y_part * ( dy * GRAB_SENSITIVITY_Y));
553 579
554 580
555 // Send the message to the viewer. 581 // Send the message to the viewer.
@@ -633,7 +659,7 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
633 && (grab_center_gl.mY > 24)) 659 && (grab_center_gl.mY > 24))
634 { 660 {
635 // Transmit update to simulator 661 // Transmit update to simulator
636 LLVector3 grab_pos_region = mGrabObject->getRegion()->getPosRegionFromGlobal( grab_point_global ); 662 LLVector3 grab_pos_region = objectp->getRegion()->getPosRegionFromGlobal( grab_point_global );
637 663
638 LLMessageSystem *msg = gMessageSystem; 664 LLMessageSystem *msg = gMessageSystem;
639 msg->newMessageFast(_PREHASH_ObjectGrabUpdate); 665 msg->newMessageFast(_PREHASH_ObjectGrabUpdate);
@@ -641,11 +667,19 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
641 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); 667 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
642 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 668 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
643 msg->nextBlockFast(_PREHASH_ObjectData); 669 msg->nextBlockFast(_PREHASH_ObjectData);
644 msg->addUUIDFast(_PREHASH_ObjectID, mGrabObject->getID() ); 670 msg->addUUIDFast(_PREHASH_ObjectID, objectp->getID() );
645 msg->addVector3Fast(_PREHASH_GrabOffsetInitial, mGrabOffsetFromCenterInitial ); 671 msg->addVector3Fast(_PREHASH_GrabOffsetInitial, mGrabOffsetFromCenterInitial );
646 msg->addVector3Fast(_PREHASH_GrabPosition, grab_pos_region ); 672 msg->addVector3Fast(_PREHASH_GrabPosition, grab_pos_region );
647 msg->addU32Fast(_PREHASH_TimeSinceLast, dt_milliseconds ); 673 msg->addU32Fast(_PREHASH_TimeSinceLast, dt_milliseconds );
648 msg->sendMessage( mGrabObject->getRegion()->getHost() ); 674 msg->nextBlock("SurfaceInfo");
675 msg->addVector3("UVCoord", LLVector3(mGrabPick.mUVCoords));
676 msg->addVector3("STCoord", LLVector3(mGrabPick.mSTCoords));
677 msg->addS32Fast(_PREHASH_FaceIndex, mGrabPick.mObjectFace);
678 msg->addVector3("Position", mGrabPick.mIntersection);
679 msg->addVector3("Normal", mGrabPick.mNormal);
680 msg->addVector3("Binormal", mGrabPick.mBinormal);
681
682 msg->sendMessage( objectp->getRegion()->getHost() );
649 } 683 }
650 } 684 }
651 685
@@ -659,8 +693,8 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
659 if (mHasMoved) 693 if (mHasMoved)
660 { 694 {
661 if (!gAgent.cameraMouselook() && 695 if (!gAgent.cameraMouselook() &&
662 !mGrabObject->isHUDAttachment() && 696 !objectp->isHUDAttachment() &&
663 mGrabObject->getRoot() == gAgent.getAvatarObject()->getRoot()) 697 objectp->getRoot() == gAgent.getAvatarObject()->getRoot())
664 { 698 {
665 // force focus to point in space where we were looking previously 699 // force focus to point in space where we were looking previously
666 gAgent.setFocusGlobal(gAgent.calcFocusPositionTargetGlobal(), LLUUID::null); 700 gAgent.setFocusGlobal(gAgent.calcFocusPositionTargetGlobal(), LLUUID::null);
@@ -679,6 +713,162 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
679} 713}
680 714
681 715
716void LLToolGrab::handleHoverNonPhysical(S32 x, S32 y, MASK mask)
717{
718 LLViewerObject* objectp = mGrabPick.getObject();
719 if (!objectp || !hasMouseCapture() ) return;
720 if (objectp->isDead())
721 {
722 // Bail out of drag because object has been killed
723 setMouseCapture(FALSE);
724 return;
725 }
726
727 LLPickInfo pick = mGrabPick;
728 pick.mMousePt = LLCoordGL(x, y);
729 pick.getSurfaceInfo();
730
731 // compute elapsed time
732 F32 dt = mGrabTimer.getElapsedTimeAndResetF32();
733 U32 dt_milliseconds = (U32) (1000.f * dt);
734
735 // i'm not a big fan of the following code - it's been culled from the physical grab case.
736 // ideally these two would be nicely integrated - but the code in that method is a serious
737 // mess of spaghetti. so here we go:
738
739 LLVector3 grab_pos_region(0,0,0);
740
741 const BOOL SUPPORT_LLDETECTED_GRAB = TRUE;
742 if (SUPPORT_LLDETECTED_GRAB)
743 {
744 //--------------------------------------------------
745 // Toggle vertical dragging
746 //--------------------------------------------------
747 if (mVerticalDragging && !(mask == MASK_VERTICAL) && !gGrabBtnVertical)
748 {
749 mVerticalDragging = FALSE;
750 }
751
752 else if (!mVerticalDragging && (mask == MASK_VERTICAL) )
753 {
754 mVerticalDragging = TRUE;
755 }
756
757 S32 dx = x - mLastMouseX;
758 S32 dy = y - mLastMouseY;
759
760 if (dx != 0 || dy != 0)
761 {
762 mAccumDeltaX += dx;
763 mAccumDeltaY += dy;
764
765 S32 dist_sq = mAccumDeltaX * mAccumDeltaX + mAccumDeltaY * mAccumDeltaY;
766 if (dist_sq > SLOP_DIST_SQ)
767 {
768 mOutsideSlop = TRUE;
769 }
770
771 // mouse has moved
772 mHasMoved = TRUE;
773
774 //------------------------------------------------------
775 // Handle grabbing
776 //------------------------------------------------------
777
778 LLVector3d x_part;
779 x_part.setVec(LLViewerCamera::getInstance()->getLeftAxis());
780 x_part.mdV[VZ] = 0.0;
781 x_part.normVec();
782
783 LLVector3d y_part;
784 if( mVerticalDragging )
785 {
786 y_part.setVec(LLViewerCamera::getInstance()->getUpAxis());
787 // y_part.setVec(0.f, 0.f, 1.f);
788 }
789 else
790 {
791 // drag toward camera
792 y_part = x_part % LLVector3d::z_axis;
793 y_part.mdV[VZ] = 0.0;
794 y_part.normVec();
795 }
796
797 mGrabHiddenOffsetFromCamera = mGrabHiddenOffsetFromCamera
798 + (x_part * (-dx * GRAB_SENSITIVITY_X))
799 + (y_part * ( dy * GRAB_SENSITIVITY_Y));
800
801 }
802
803 // need to return offset from mGrabStartPoint
804 LLVector3d grab_point_global = gAgent.getCameraPositionGlobal() + mGrabHiddenOffsetFromCamera;
805 grab_pos_region = objectp->getRegion()->getPosRegionFromGlobal( grab_point_global );
806 }
807
808
809 // only send message if something has changed since last message
810
811 BOOL changed_since_last_update = FALSE;
812
813 // test if touch data needs to be updated
814 if ((pick.mObjectFace != mLastFace) ||
815 (pick.mUVCoords != mLastUVCoords) ||
816 (pick.mSTCoords != mLastSTCoords) ||
817 (pick.mIntersection != mLastIntersection) ||
818 (pick.mNormal != mLastNormal) ||
819 (pick.mBinormal != mLastBinormal) ||
820 (grab_pos_region != mLastGrabPos))
821 {
822 changed_since_last_update = TRUE;
823 }
824
825 if (changed_since_last_update)
826 {
827 LLMessageSystem *msg = gMessageSystem;
828 msg->newMessageFast(_PREHASH_ObjectGrabUpdate);
829 msg->nextBlockFast(_PREHASH_AgentData);
830 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
831 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
832 msg->nextBlockFast(_PREHASH_ObjectData);
833 msg->addUUIDFast(_PREHASH_ObjectID, objectp->getID() );
834 msg->addVector3Fast(_PREHASH_GrabOffsetInitial, mGrabOffsetFromCenterInitial );
835 msg->addVector3Fast(_PREHASH_GrabPosition, grab_pos_region );
836 msg->addU32Fast(_PREHASH_TimeSinceLast, dt_milliseconds );
837 msg->nextBlock("SurfaceInfo");
838 msg->addVector3("UVCoord", LLVector3(pick.mUVCoords));
839 msg->addVector3("STCoord", LLVector3(pick.mSTCoords));
840 msg->addS32Fast(_PREHASH_FaceIndex, pick.mObjectFace);
841 msg->addVector3("Position", pick.mIntersection);
842 msg->addVector3("Normal", pick.mNormal);
843 msg->addVector3("Binormal", pick.mBinormal);
844
845 msg->sendMessage( objectp->getRegion()->getHost() );
846
847 mLastUVCoords = pick.mUVCoords;
848 mLastSTCoords = pick.mSTCoords;
849 mLastFace = pick.mObjectFace;
850 mLastIntersection = pick.mIntersection;
851 mLastNormal= pick.mNormal;
852 mLastBinormal= pick.mBinormal;
853 mLastGrabPos = grab_pos_region;
854 }
855
856 // update point-at / look-at
857 if (pick.mObjectFace != -1) // if the intersection was on the surface of the obejct
858 {
859 LLVector3 local_edit_point = pick.mIntersection;
860 local_edit_point -= objectp->getPositionAgent();
861 local_edit_point = local_edit_point * ~objectp->getRenderRotation();
862 gAgent.setPointAt(POINTAT_TARGET_GRAB, objectp, local_edit_point );
863 gAgent.setLookAt(LOOKAT_TARGET_SELECT, objectp, local_edit_point );
864 }
865
866
867
868 gViewerWindow->setCursor(UI_CURSOR_HAND);
869}
870
871
682// Not dragging. Just showing affordances 872// Not dragging. Just showing affordances
683void LLToolGrab::handleHoverInactive(S32 x, S32 y, MASK mask) 873void LLToolGrab::handleHoverInactive(S32 x, S32 y, MASK mask)
684{ 874{
@@ -719,7 +909,7 @@ void LLToolGrab::handleHoverFailed(S32 x, S32 y, MASK mask)
719 } 909 }
720 else 910 else
721 { 911 {
722 S32 dist_sq = (x-mMouseDownX) * (x-mMouseDownX) + (y-mMouseDownY) * (y-mMouseDownY); 912 S32 dist_sq = (x-mGrabPick.mMousePt.mX) * (x-mGrabPick.mMousePt.mX) + (y-mGrabPick.mMousePt.mY) * (y-mGrabPick.mMousePt.mY);
723 if( mOutsideSlop || dist_sq > SLOP_DIST_SQ ) 913 if( mOutsideSlop || dist_sq > SLOP_DIST_SQ )
724 { 914 {
725 mOutsideSlop = TRUE; 915 mOutsideSlop = TRUE;
@@ -784,23 +974,27 @@ void LLToolGrab::stopEditing()
784 974
785void LLToolGrab::onMouseCaptureLost() 975void LLToolGrab::onMouseCaptureLost()
786{ 976{
977 LLViewerObject* objectp = mGrabPick.getObject();
978 if (!objectp)
979 {
980 gViewerWindow->showCursor();
981 return;
982 }
787 // First, fix cursor placement 983 // First, fix cursor placement
788 if( !gAgent.cameraMouselook() 984 if( !gAgent.cameraMouselook()
789 && (GRAB_ACTIVE_CENTER == mMode || GRAB_NONPHYSICAL == mMode)) 985 && (GRAB_ACTIVE_CENTER == mMode))
790 { 986 {
791 llassert( mGrabObject ); 987 if (objectp->isHUDAttachment())
792
793 if (mGrabObject->isHUDAttachment())
794 { 988 {
795 // ...move cursor "naturally", as if it had moved when hidden 989 // ...move cursor "naturally", as if it had moved when hidden
796 S32 x = mMouseDownX + mAccumDeltaX; 990 S32 x = mGrabPick.mMousePt.mX + mAccumDeltaX;
797 S32 y = mMouseDownY + mAccumDeltaY; 991 S32 y = mGrabPick.mMousePt.mY + mAccumDeltaY;
798 LLUI::setCursorPositionScreen(x, y); 992 LLUI::setCursorPositionScreen(x, y);
799 } 993 }
800 else if (mHasMoved) 994 else if (mHasMoved)
801 { 995 {
802 // ...move cursor back to the center of the object 996 // ...move cursor back to the center of the object
803 LLVector3 grab_point_agent = mGrabObject->getRenderPosition(); 997 LLVector3 grab_point_agent = objectp->getRenderPosition();
804 998
805 LLCoordGL gl_point; 999 LLCoordGL gl_point;
806 if (LLViewerCamera::getInstance()->projectPosAgentToScreen(grab_point_agent, gl_point)) 1000 if (LLViewerCamera::getInstance()->projectPosAgentToScreen(grab_point_agent, gl_point))
@@ -811,19 +1005,21 @@ void LLToolGrab::onMouseCaptureLost()
811 else 1005 else
812 { 1006 {
813 // ...move cursor back to click position 1007 // ...move cursor back to click position
814 LLUI::setCursorPositionScreen(mMouseDownX, mMouseDownY); 1008 LLUI::setCursorPositionScreen(mGrabPick.mMousePt.mX, mGrabPick.mMousePt.mY);
815 } 1009 }
816 1010
817 gViewerWindow->showCursor(); 1011 gViewerWindow->showCursor();
818 } 1012 }
819 1013
820 stopGrab(); 1014 stopGrab();
1015 if (mSpinGrabbing)
821 stopSpin(); 1016 stopSpin();
1017
822 mMode = GRAB_INACTIVE; 1018 mMode = GRAB_INACTIVE;
823 1019
824 mHideBuildHighlight = FALSE; 1020 mHideBuildHighlight = FALSE;
825 1021
826 mGrabObject = NULL; 1022 mGrabPick.mObjectID.setNull();
827 1023
828 LLSelectMgr::getInstance()->updateSelectionCenter(); 1024 LLSelectMgr::getInstance()->updateSelectionCenter();
829 gAgent.setPointAt(POINTAT_TARGET_CLEAR); 1025 gAgent.setPointAt(POINTAT_TARGET_CLEAR);
@@ -835,6 +1031,24 @@ void LLToolGrab::onMouseCaptureLost()
835 1031
836void LLToolGrab::stopGrab() 1032void LLToolGrab::stopGrab()
837{ 1033{
1034 LLViewerObject* objectp = mGrabPick.getObject();
1035 if (!objectp)
1036 {
1037 return;
1038 }
1039
1040 LLPickInfo pick = mGrabPick;
1041
1042 if (mMode == GRAB_NONPHYSICAL)
1043 {
1044 // for non-physical (touch) grabs,
1045 // gather surface info for this degrab (mouse-up)
1046 S32 x = gViewerWindow->getCurrentMouseX();
1047 S32 y = gViewerWindow->getCurrentMouseY();
1048 pick.mMousePt = LLCoordGL(x, y);
1049 pick.getSurfaceInfo();
1050 }
1051
838 // Next, send messages to simulator 1052 // Next, send messages to simulator
839 LLMessageSystem *msg = gMessageSystem; 1053 LLMessageSystem *msg = gMessageSystem;
840 switch(mMode) 1054 switch(mMode)
@@ -847,11 +1061,18 @@ void LLToolGrab::stopGrab()
847 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); 1061 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
848 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 1062 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
849 msg->nextBlockFast(_PREHASH_ObjectData); 1063 msg->nextBlockFast(_PREHASH_ObjectData);
850 msg->addU32Fast(_PREHASH_LocalID, mGrabObject->mLocalID); 1064 msg->addU32Fast(_PREHASH_LocalID, objectp->mLocalID);
851 msg->sendMessage(mGrabObject->getRegion()->getHost()); 1065 msg->nextBlock("SurfaceInfo");
1066 msg->addVector3("UVCoord", LLVector3(pick.mUVCoords));
1067 msg->addVector3("STCoord", LLVector3(pick.mSTCoords));
1068 msg->addS32Fast(_PREHASH_FaceIndex, pick.mObjectFace);
1069 msg->addVector3("Position", pick.mIntersection);
1070 msg->addVector3("Normal", pick.mNormal);
1071 msg->addVector3("Binormal", pick.mBinormal);
1072
1073 msg->sendMessage(objectp->getRegion()->getHost());
852 1074
853 mVerticalDragging = FALSE; 1075 mVerticalDragging = FALSE;
854 mGrabOffset.clearVec();
855 break; 1076 break;
856 1077
857 case GRAB_NOOBJECT: 1078 case GRAB_NOOBJECT:
@@ -873,14 +1094,12 @@ void LLToolGrab::render()
873 1094
874BOOL LLToolGrab::isEditing() 1095BOOL LLToolGrab::isEditing()
875{ 1096{
876 // Can't just compare to null directly due to "smart" pointer. 1097 return (mGrabPick.getObject().notNull());
877 LLViewerObject *obj = mGrabObject;
878 return (obj != NULL);
879} 1098}
880 1099
881LLViewerObject* LLToolGrab::getEditingObject() 1100LLViewerObject* LLToolGrab::getEditingObject()
882{ 1101{
883 return mGrabObject; 1102 return mGrabPick.getObject();
884} 1103}
885 1104
886 1105