diff options
Diffstat (limited to 'linden/indra/newview/lltoolgrab.cpp')
-rw-r--r-- | linden/indra/newview/lltoolgrab.cpp | 381 |
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 | // |
77 | LLToolGrab::LLToolGrab( LLToolComposite* composite ) | 77 | LLToolGrab::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 | ||
147 | void LLToolGrab::pickCallback(S32 x, S32 y, MASK mask) | 142 | void 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 | ||
176 | BOOL LLToolGrab::handleObjectHit(LLViewerObject *objectp, S32 x, S32 y, MASK mask) | 172 | BOOL 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 | ||
301 | void LLToolGrab::startSpin() | 292 | void 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 | ||
348 | void LLToolGrab::startGrab(S32 x, S32 y) | 350 | void 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 | ||
391 | BOOL LLToolGrab::handleHover(S32 x, S32 y, MASK mask) | 414 | BOOL 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 | ||
451 | const F32 GRAB_SENSITIVITY_X = 0.0075f; | ||
452 | const F32 GRAB_SENSITIVITY_Y = 0.0075f; | ||
453 | |||
425 | 454 | ||
426 | 455 | ||
427 | 456 | ||
428 | // Dragging. | 457 | // Dragging. |
429 | void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask) | 458 | void 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 | ||
716 | void 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 |
683 | void LLToolGrab::handleHoverInactive(S32 x, S32 y, MASK mask) | 873 | void 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 | ||
785 | void LLToolGrab::onMouseCaptureLost() | 975 | void 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 | ||
836 | void LLToolGrab::stopGrab() | 1032 | void 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 | ||
874 | BOOL LLToolGrab::isEditing() | 1095 | BOOL 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 | ||
881 | LLViewerObject* LLToolGrab::getEditingObject() | 1100 | LLViewerObject* LLToolGrab::getEditingObject() |
882 | { | 1101 | { |
883 | return mGrabObject; | 1102 | return mGrabPick.getObject(); |
884 | } | 1103 | } |
885 | 1104 | ||
886 | 1105 | ||