void LLToolGrab::stopGrab() { LLViewerObject* objectp = mGrabPick.getObject(); if (!objectp) { return; } LLPickInfo pick = mGrabPick; if (mMode == GRAB_NONPHYSICAL) { // for non-physical (touch) grabs, // gather surface info for this degrab (mouse-up) S32 x = gViewerWindow->getCurrentMouseX(); S32 y = gViewerWindow->getCurrentMouseY(); pick.mMousePt = LLCoordGL(x, y); pick.getSurfaceInfo(); } // Next, send messages to simulator LLMessageSystem *msg = gMessageSystem; switch(mMode) { case GRAB_ACTIVE_CENTER: case GRAB_NONPHYSICAL: case GRAB_LOCKED: msg->newMessageFast(_PREHASH_ObjectDeGrab); msg->nextBlockFast(_PREHASH_AgentData); msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); msg->nextBlockFast(_PREHASH_ObjectData); msg->addU32Fast(_PREHASH_LocalID, objectp->mLocalID); msg->nextBlock("SurfaceInfo"); msg->addVector3("UVCoord", LLVector3(pick.mUVCoords)); msg->addVector3("STCoord", LLVector3(pick.mSTCoords)); msg->addS32Fast(_PREHASH_FaceIndex, pick.mObjectFace); msg->addVector3("Position", pick.mIntersection); msg->addVector3("Normal", pick.mNormal); msg->addVector3("Binormal", pick.mBinormal); msg->sendMessage(objectp->getRegion()->getHost()); mVerticalDragging = FALSE; break; case GRAB_NOOBJECT: case GRAB_INACTIVE: default: // do nothing break; } mHideBuildHighlight = FALSE; }
bool LLToolPie::handleMediaClick(const LLPickInfo& pick) { //FIXME: how do we handle object in different parcel than us? LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); LLPointer<LLViewerObject> objectp = pick.getObject(); if (!parcel || objectp.isNull() || pick.mObjectFace < 0 || pick.mObjectFace >= objectp->getNumTEs()) { LLViewerMediaFocus::getInstance()->clearFocus(); return false; } // Does this face have media? const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace); if(!tep) return false; LLMediaEntry* mep = (tep->hasMedia()) ? tep->getMediaData() : NULL; if(!mep) return false; viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID()); if (gSavedSettings.getBOOL("MediaOnAPrimUI")) { if (!LLViewerMediaFocus::getInstance()->isFocusedOnFace(pick.getObject(), pick.mObjectFace) || media_impl.isNull()) { // It's okay to give this a null impl LLViewerMediaFocus::getInstance()->setFocusFace(pick.getObject(), pick.mObjectFace, media_impl, pick.mNormal); } else { // Make sure keyboard focus is set to the media focus object. gFocusMgr.setKeyboardFocus(LLViewerMediaFocus::getInstance()); media_impl->mouseDown(pick.mUVCoords, gKeyboard->currentMask(TRUE)); mMediaMouseCaptureID = mep->getMediaID(); setMouseCapture(TRUE); // This object will send a mouse-up to the media when it loses capture. } return true; } LLViewerMediaFocus::getInstance()->clearFocus(); return false; }
static bool handle_media_click(const LLPickInfo& pick) { //FIXME: how do we handle object in different parcel than us? LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); LLPointer<LLViewerObject> objectp = pick.getObject(); if (!parcel || objectp.isNull() || pick.mObjectFace < 0 || pick.mObjectFace >= objectp->getNumTEs()) { LLSelectMgr::getInstance()->deselect(); LLViewerMediaFocus::getInstance()->clearFocus(); return false; } // HACK: This is directly referencing an impl name. BAD! // This can be removed when we have a truly generic media browser that only // builds an impl based on the type of url it is passed. // is media playing on this face? const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace); viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(tep->getID()); if (tep && media_impl.notNull() && media_impl->hasMedia() && gSavedSettings.getBOOL("MediaOnAPrimUI")) { LLObjectSelectionHandle selection = LLViewerMediaFocus::getInstance()->getSelection(); if (! selection->contains(pick.getObject(), pick.mObjectFace)) { LLViewerMediaFocus::getInstance()->setFocusFace(TRUE, pick.getObject(), pick.mObjectFace, media_impl); } else { media_impl->mouseDown(pick.mXYCoords.mX, pick.mXYCoords.mY); media_impl->mouseCapture(); // the mouse-up will happen when capture is lost } return true; } LLSelectMgr::getInstance()->deselect(); LLViewerMediaFocus::getInstance()->clearFocus(); return false; }
void LLToolGrab::pickCallback(const LLPickInfo& pick_info) { LLToolGrab::getInstance()->mGrabPick = pick_info; LLViewerObject *objectp = pick_info.getObject(); BOOL extend_select = (pick_info.mKeyMask & MASK_SHIFT); if (!extend_select && !LLSelectMgr::getInstance()->getSelection()->isEmpty()) { LLSelectMgr::getInstance()->deselectAll(); LLToolGrab::getInstance()->mDeselectedThisClick = TRUE; } else { LLToolGrab::getInstance()->mDeselectedThisClick = FALSE; } // if not over object, do nothing if (!objectp) { LLToolGrab::getInstance()->setMouseCapture(TRUE); LLToolGrab::getInstance()->mMode = GRAB_NOOBJECT; LLToolGrab::getInstance()->mGrabPick.mObjectID.setNull(); } else { LLToolGrab::getInstance()->handleObjectHit(LLToolGrab::getInstance()->mGrabPick); } }
void LLHoverView::pickCallback(const LLPickInfo& pick_info) { gHoverView->mLastPickInfo = pick_info; LLViewerObject* hit_obj = pick_info.getObject(); if (hit_obj) { gHoverView->setHoverActive(TRUE); LLSelectMgr::getInstance()->setHoverObject(hit_obj, pick_info.mObjectFace); gHoverView->mLastHoverObject = hit_obj; gHoverView->mHoverOffset = pick_info.mObjectOffset; } else { gHoverView->mLastHoverObject = NULL; } // We didn't hit an object, but we did hit land. if (!hit_obj && pick_info.mPosGlobal != LLVector3d::zero) { gHoverView->setHoverActive(TRUE); gHoverView->mHoverLandGlobal = pick_info.mPosGlobal; LLViewerParcelMgr::getInstance()->requestHoverParcelProperties( gHoverView->mHoverLandGlobal ); } else { gHoverView->mHoverLandGlobal = LLVector3d::zero; } gHoverView->mDoneHoverPick = TRUE; }
void LLToolGrab::pickCallback(const LLPickInfo& pick_info) { LLToolGrab::getInstance()->mGrabPick = pick_info; LLViewerObject *objectp = pick_info.getObject(); BOOL extend_select = (pick_info.mKeyMask & MASK_SHIFT); if (!extend_select && !LLSelectMgr::getInstance()->getSelection()->isEmpty()) { LLSelectMgr::getInstance()->deselectAll(); LLToolGrab::getInstance()->mDeselectedThisClick = TRUE; } else { LLToolGrab::getInstance()->mDeselectedThisClick = FALSE; } // if not over object, do nothing // if (!objectp) // [RLVa:KB] - Checked: 2010-03-11 (RLVa-1.2.0e) | Added: RLVa-1.1.0l // Block initiating a drag operation on an object that can't be touched if ( (!objectp) || ((rlv_handler_t::isEnabled()) && (!gRlvHandler.canTouch(objectp, pick_info.mObjectOffset))) ) // [/RLVa:KB] { LLToolGrab::getInstance()->setMouseCapture(TRUE); LLToolGrab::getInstance()->mMode = GRAB_NOOBJECT; LLToolGrab::getInstance()->mGrabPick.mObjectID.setNull(); } else { LLToolGrab::getInstance()->handleObjectHit(LLToolGrab::getInstance()->mGrabPick); } }
void LLToolCompInspect::pickCallback(const LLPickInfo& pick_info) { LLViewerObject* hit_obj = pick_info.getObject(); if (!LLToolCompInspect::getInstance()->mMouseDown) { // fast click on object, but mouse is already up...just do select LLToolCompInspect::getInstance()->mSelectRect->handleObjectSelection(pick_info, gSavedSettings.getBOOL("EditLinkedParts"), FALSE); return; } if( hit_obj ) { if (LLSelectMgr::getInstance()->getSelection()->getObjectCount()) { LLEditMenuHandler::gEditMenuHandler = LLSelectMgr::getInstance(); } LLToolCompInspect::getInstance()->setCurrentTool( LLToolCompInspect::getInstance()->mSelectRect ); LLToolCompInspect::getInstance()->mSelectRect->handlePick( pick_info ); } else { LLToolCompInspect::getInstance()->setCurrentTool( LLToolCompInspect::getInstance()->mSelectRect ); LLToolCompInspect::getInstance()->mSelectRect->handlePick( pick_info ); } }
void LLToolCompRotate::pickCallback(const LLPickInfo& pick_info) { LLViewerObject* hit_obj = pick_info.getObject(); LLToolCompRotate::getInstance()->mManip->highlightManipulators(pick_info.mMousePt.mX, pick_info.mMousePt.mY); if (!LLToolCompRotate::getInstance()->mMouseDown) { // fast click on object, but mouse is already up...just do select LLToolCompRotate::getInstance()->mSelectRect->handleObjectSelection(pick_info, gSavedSettings.getBOOL("EditLinkedParts"), FALSE); return; } if( hit_obj || LLToolCompRotate::getInstance()->mManip->getHighlightedPart() != LLManip::LL_NO_PART) { if (LLToolCompRotate::getInstance()->mManip->getSelection()->getObjectCount()) { LLEditMenuHandler::gEditMenuHandler = LLSelectMgr::getInstance(); } if( LLManip::LL_NO_PART != LLToolCompRotate::getInstance()->mManip->getHighlightedPart() ) { LLToolCompRotate::getInstance()->setCurrentTool( LLToolCompRotate::getInstance()->mManip ); LLToolCompRotate::getInstance()->mManip->handleMouseDownOnPart( pick_info.mMousePt.mX, pick_info.mMousePt.mY, pick_info.mKeyMask ); } else { LLToolCompRotate::getInstance()->setCurrentTool( LLToolCompRotate::getInstance()->mSelectRect ); LLToolCompRotate::getInstance()->mSelectRect->handlePick( pick_info ); } } else { LLToolCompRotate::getInstance()->setCurrentTool( LLToolCompRotate::getInstance()->mSelectRect ); LLToolCompRotate::getInstance()->mSelectRect->handlePick( pick_info ); } }
bool LLToolPie::handleMediaHover(const LLPickInfo& pick) { //FIXME: how do we handle object in different parcel than us? LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if (!parcel) return false; LLPointer<LLViewerObject> objectp = pick.getObject(); // Early out cases. Must clear media hover. // did not hit an object or did not hit a valid face if ( objectp.isNull() || pick.mObjectFace < 0 || pick.mObjectFace >= objectp->getNumTEs() ) { LLViewerMediaFocus::getInstance()->clearHover(); return false; } // Does this face have media? const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace); if(!tep) return false; const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL; if (mep && gSavedSettings.getBOOL("MediaOnAPrimUI")) { viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID()); if(media_impl.notNull()) { // Update media hover object if (!LLViewerMediaFocus::getInstance()->isHoveringOverFace(objectp, pick.mObjectFace)) { LLViewerMediaFocus::getInstance()->setHoverFace(objectp, pick.mObjectFace, media_impl, pick.mNormal); } // If this is the focused media face, send mouse move events. if (LLViewerMediaFocus::getInstance()->isFocusedOnFace(objectp, pick.mObjectFace)) { media_impl->mouseMove(pick.mUVCoords, gKeyboard->currentMask(TRUE)); gViewerWindow->setCursor(media_impl->getLastSetCursor()); } else { // This is not the focused face -- set the default cursor. gViewerWindow->setCursor(UI_CURSOR_ARROW); } return true; } } // In all other cases, clear media hover. LLViewerMediaFocus::getInstance()->clearHover(); return false; }
void LLToolFace::pickCallback(const LLPickInfo& pick_info) { LLViewerObject* hit_obj = pick_info.getObject(); if (hit_obj) { //MK if (gRRenabled && !gAgent.mRRInterface.canTouch (hit_obj)) { return; } //mk S32 hit_face = pick_info.mObjectFace; if (hit_obj->isAvatar()) { // ...clicked on an avatar, so don't do anything return; } // ...clicked on a world object, try to pick the appropriate face if (pick_info.mKeyMask & MASK_SHIFT) { // If object not selected, need to inform sim if ( !hit_obj->isSelected() ) { // object wasn't selected so add the object and face LLSelectMgr::getInstance()->selectObjectOnly(hit_obj, hit_face); } else if (!LLSelectMgr::getInstance()->getSelection()->contains(hit_obj, hit_face) ) { // object is selected, but not this face, so add it. LLSelectMgr::getInstance()->addAsIndividual(hit_obj, hit_face); } else { // object is selected, as is this face, so remove the face. LLSelectMgr::getInstance()->remove(hit_obj, hit_face); // BUG: If you remove the last face, the simulator won't know about it. } } else { // clicked without modifiers, select only // this face LLSelectMgr::getInstance()->deselectAll(); LLSelectMgr::getInstance()->selectObjectOnly(hit_obj, hit_face); } } else { if (!(pick_info.mKeyMask == MASK_SHIFT)) { LLSelectMgr::getInstance()->deselectAll(); } } }
void LLToolIndividual::pickCallback(const LLPickInfo& pick_info) { LLViewerObject* obj = pick_info.getObject(); LLSelectMgr::getInstance()->deselectAll(); if(obj) { LLSelectMgr::getInstance()->selectObjectOnly(obj); } }
void LLToolGrab::stopGrab() { LLViewerObject* objectp = mGrabPick.getObject(); if (!objectp) { return; } LLPickInfo pick = mGrabPick; if (mMode == GRAB_NONPHYSICAL) { // for non-physical (touch) grabs, // gather surface info for this degrab (mouse-up) S32 x = gViewerWindow->getCurrentMouseX(); S32 y = gViewerWindow->getCurrentMouseY(); pick.mMousePt = LLCoordGL(x, y); pick.getSurfaceInfo(); } // Next, send messages to simulator switch(mMode) { case GRAB_ACTIVE_CENTER: case GRAB_NONPHYSICAL: case GRAB_LOCKED: send_ObjectDeGrab_message(objectp, pick); mVerticalDragging = FALSE; break; case GRAB_NOOBJECT: case GRAB_INACTIVE: default: // do nothing break; } mHideBuildHighlight = FALSE; }
static bool handle_media_hover(const LLPickInfo& pick) { //FIXME: how do we handle object in different parcel than us? LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if (!parcel) return false; LLPointer<LLViewerObject> objectp = pick.getObject(); // Early out cases. Must clear mouse over media focus flag // did not hit an object or did not hit a valid face if ( objectp.isNull() || pick.mObjectFace < 0 || pick.mObjectFace >= objectp->getNumTEs() ) { LLViewerMediaFocus::getInstance()->setMouseOverFlag(false); return false; } // HACK: This is directly referencing an impl name. BAD! // This can be removed when we have a truly generic media browser that only // builds an impl based on the type of url it is passed. // is media playing on this face? const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace); viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(tep->getID()); if (tep && media_impl.notNull() && media_impl->hasMedia() && gSavedSettings.getBOOL("MediaOnAPrimUI")) { if(LLViewerMediaFocus::getInstance()->getFocus()) { media_impl->mouseMove(pick.mXYCoords.mX, pick.mXYCoords.mY); } // Set mouse over flag if unset if (! LLViewerMediaFocus::getInstance()->getMouseOverFlag()) { LLSelectMgr::getInstance()->setHoverObject(objectp, pick.mObjectFace); LLViewerMediaFocus::getInstance()->setMouseOverFlag(true, media_impl); LLViewerMediaFocus::getInstance()->setPickInfo(pick); } return true; } LLViewerMediaFocus::getInstance()->setMouseOverFlag(false); return false; }
// static void LLToolPie::playCurrentMedia(const LLPickInfo& info) { //FIXME: how do we handle object in different parcel than us? LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if (!parcel) return; LLPointer<LLViewerObject> objectp = info.getObject(); // Early out cases. Must clear media hover. // did not hit an object or did not hit a valid face if ( objectp.isNull() || info.mObjectFace < 0 || info.mObjectFace >= objectp->getNumTEs() ) { return; } // Does this face have media? const LLTextureEntry* tep = objectp->getTE(info.mObjectFace); if (!tep) return; const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL; if(!mep) return; //TODO: Can you Use it? LLPluginClassMedia* media_plugin = NULL; viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID()); if(media_impl.notNull() && media_impl->hasMedia()) { media_plugin = media_impl->getMediaPlugin(); if (media_plugin && media_plugin->pluginSupportsMediaTime()) { if(media_impl->isMediaPlaying()) { media_impl->pause(); } else { media_impl->play(); } } } }
void LLToolPipette::pickCallback(const LLPickInfo& pick_info) { LLViewerObject* hit_obj = pick_info.getObject(); LLSelectMgr::getInstance()->unhighlightAll(); // if we clicked on a face of a valid prim, save off texture entry data if (hit_obj && hit_obj->getPCode() == LL_PCODE_VOLUME && pick_info.mObjectFace != -1) { //TODO: this should highlight the selected face only LLSelectMgr::getInstance()->highlightObjectOnly(hit_obj); const LLTextureEntry* entry = hit_obj->getTE(pick_info.mObjectFace); LLToolPipette::getInstance()->setTextureEntry(entry); } }
void QToolAlign::pickCallback(const LLPickInfo& pick_info) { LLViewerObject* object = pick_info.getObject(); if (object) { if (object->isAvatar()) { return; } if (pick_info.mKeyMask & MASK_SHIFT) { // If object not selected, select it if ( !object->isSelected() ) { LLSelectMgr::getInstance()->selectObjectAndFamily(object); } else { LLSelectMgr::getInstance()->deselectObjectAndFamily(object); } } else { LLSelectMgr::getInstance()->deselectAll(); LLSelectMgr::getInstance()->selectObjectAndFamily(object); } } else { if (!(pick_info.mKeyMask == MASK_SHIFT)) { LLSelectMgr::getInstance()->deselectAll(); } } LLSelectMgr::getInstance()->promoteSelectionToRoot(); }
// static LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pick, BOOL ignore_group, BOOL temp_select, BOOL select_root) { LLViewerObject* object = pick.getObject(); if (select_root) { object = object->getRootEdit(); } // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0f if (rlv_handler_t::isEnabled()) { if (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) { if (!temp_select) { return LLSelectMgr::getInstance()->getSelection(); } else { // Temporary selection, but if the build floater is open then it'll be permanent so get rid of the floater if (gFloaterTools->getVisible()) { // Copy/paste from toggle_build_mode() gAgent.resetView(false); gFloaterTools->close(); gViewerWindow->showCursor(); } } } if ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && (object) && ((!object->isAttachment()) || (!object->permYouOwner())) && (dist_vec_squared(gAgent.getPositionAgent(), object->getPositionRegion()) > 1.5f * 1.5f) ) { // NOTE-RLVa: see behaviour notes for a rather lengthy explanation of why we're doing things this way //if (dist_vec_squared(gAgent.getPositionAgent(), object->getPositionRegion() + pick.mObjectOffset) > 1.5f * 1.5f) if (dist_vec_squared(gAgent.getPositionAgent(), pick.mIntersection) > 1.5f * 1.5f) { if ( (gFloaterTools->getVisible()) && (pick.mKeyMask != MASK_SHIFT) && (pick.mKeyMask != MASK_CONTROL) ) LLSelectMgr::getInstance()->deselectAll(); return LLSelectMgr::getInstance()->getSelection(); } else if (gFloaterTools->getVisible()) { // Copy/paste from toggle_build_mode() gAgent.resetView(false); gFloaterTools->close(); gViewerWindow->showCursor(); } } } // [/RLVa:KB] BOOL select_owned = gSavedSettings.getBOOL("SelectOwnedOnly"); BOOL select_movable = gSavedSettings.getBOOL("SelectMovableOnly"); BOOL select_region = gSavedSettings.getBOOL("SelectThisRegionOnly"); // *NOTE: These settings must be cleaned up at bottom of function. if (temp_select || gAllowSelectAvatar) { gSavedSettings.setBOOL("SelectOwnedOnly", FALSE); gSavedSettings.setBOOL("SelectMovableOnly", FALSE); gSavedSettings.setBOOL("SelectThisRegionOnly", TRUE); LLSelectMgr::getInstance()->setForceSelection(TRUE); } BOOL extend_select = (pick.mKeyMask == MASK_SHIFT) || (pick.mKeyMask == MASK_CONTROL); // If no object, check for icon, then just deselect if (!object) { LLHUDIcon* last_hit_hud_icon = pick.mHUDIcon; if (last_hit_hud_icon && last_hit_hud_icon->getSourceObject()) { LLFloaterScriptDebug::show(last_hit_hud_icon->getSourceObject()->getID()); } else if (!extend_select) { LLSelectMgr::getInstance()->deselectAll(); } } else { BOOL already_selected = object->isSelected(); if ( extend_select ) { if ( already_selected ) { if ( ignore_group ) { LLSelectMgr::getInstance()->deselectObjectOnly(object); } else { LLSelectMgr::getInstance()->deselectObjectAndFamily(object, TRUE, TRUE); } } else { if ( ignore_group ) { LLSelectMgr::getInstance()->selectObjectOnly(object, SELECT_ALL_TES); } else { LLSelectMgr::getInstance()->selectObjectAndFamily(object); } } } else { // Save the current zoom values because deselect resets them. F32 target_zoom; F32 current_zoom; LLSelectMgr::getInstance()->getAgentHUDZoom(target_zoom, current_zoom); // JC - Change behavior to make it easier to select children // of linked sets. 9/3/2002 if( !already_selected || ignore_group) { // ...lose current selection in favor of just this object LLSelectMgr::getInstance()->deselectAll(); } if ( ignore_group ) { LLSelectMgr::getInstance()->selectObjectOnly(object, SELECT_ALL_TES); } else { LLSelectMgr::getInstance()->selectObjectAndFamily(object); } // restore the zoom to the previously stored values. LLSelectMgr::getInstance()->setAgentHUDZoom(target_zoom, current_zoom); } if (!gAgent.getFocusOnAvatar() && // if camera not glued to avatar LLVOAvatar::findAvatarFromAttachment(object) != gAgent.getAvatarObject() && // and it's not one of your attachments object != gAgent.getAvatarObject()) // and it's not you { // have avatar turn to face the selected object(s) LLVector3d selection_center = LLSelectMgr::getInstance()->getSelectionCenterGlobal(); selection_center = selection_center - gAgent.getPositionGlobal(); LLVector3 selection_dir; selection_dir.setVec(selection_center); selection_dir.mV[VZ] = 0.f; selection_dir.normVec(); if (!object->isAvatar() && gAgent.getAtAxis() * selection_dir < 0.6f) { LLQuaternion target_rot; target_rot.shortestArc(LLVector3::x_axis, selection_dir); gAgent.startAutoPilotGlobal(gAgent.getPositionGlobal(), "", &target_rot, NULL, NULL, 1.f, SELECTION_ROTATION_TRESHOLD); } } if (temp_select) { if (!already_selected) { LLViewerObject* root_object = (LLViewerObject*)object->getRootEdit(); LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); // this is just a temporary selection LLSelectNode* select_node = selection->findNode(root_object); if (select_node) { select_node->setTransient(TRUE); } LLViewerObject::const_child_list_t& child_list = root_object->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); iter != child_list.end(); iter++) { LLViewerObject* child = *iter; select_node = selection->findNode(child); if (select_node) { select_node->setTransient(TRUE); } } } } //if(temp_select) } //if(!object) // Cleanup temp select settings above. if (temp_select || gAllowSelectAvatar) { gSavedSettings.setBOOL("SelectOwnedOnly", select_owned); gSavedSettings.setBOOL("SelectMovableOnly", select_movable); gSavedSettings.setBOOL("SelectThisRegionOnly", select_region); LLSelectMgr::getInstance()->setForceSelection(FALSE); } return LLSelectMgr::getInstance()->getSelection(); }
void LLToolFace::pickCallback(const LLPickInfo& pick_info) { LLViewerObject* hit_obj = pick_info.getObject(); if (hit_obj) { S32 hit_face = pick_info.mObjectFace; if (hit_obj->isAvatar()) { // ...clicked on an avatar, so don't do anything return; } // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0f if ( (rlv_handler_t::isEnabled()) && ( (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) || ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && ((!hit_obj->isAttachment()) || (!hit_obj->permYouOwner())) && (dist_vec_squared(gAgent.getPositionAgent(), hit_obj->getPositionRegion() + pick_info.mObjectOffset) > 1.5f * 1.5f) ))) { return; } // [/RLVa:KB] // ...clicked on a world object, try to pick the appropriate face if (pick_info.mKeyMask & MASK_SHIFT) { // If object not selected, need to inform sim if ( !hit_obj->isSelected() ) { // object wasn't selected so add the object and face LLSelectMgr::getInstance()->selectObjectOnly(hit_obj, hit_face); } else if (!LLSelectMgr::getInstance()->getSelection()->contains(hit_obj, hit_face) ) { // object is selected, but not this face, so add it. LLSelectMgr::getInstance()->addAsIndividual(hit_obj, hit_face); } else { // object is selected, as is this face, so remove the face. LLSelectMgr::getInstance()->remove(hit_obj, hit_face); // BUG: If you remove the last face, the simulator won't know about it. } } else { // clicked without modifiers, select only // this face LLSelectMgr::getInstance()->deselectAll(); LLSelectMgr::getInstance()->selectObjectOnly(hit_obj, hit_face); } } else { if (!(pick_info.mKeyMask == MASK_SHIFT)) { LLSelectMgr::getInstance()->deselectAll(); } } }
BOOL LLToolPlacer::raycastForNewObjPos( S32 x, S32 y, LLViewerObject** hit_obj, S32* hit_face, BOOL* b_hit_land, LLVector3* ray_start_region, LLVector3* ray_end_region, LLViewerRegion** region ) { F32 max_dist_from_camera = gSavedSettings.getF32( "MaxSelectDistance" ) - 1.f; // Viewer-side pick to find the right sim to create the object on. // First find the surface the object will be created on. LLPickInfo pick = gViewerWindow->pickImmediate(x, y, FALSE); // Note: use the frontmost non-flora version because (a) plants usually have lots of alpha and (b) pants' Havok // representations (if any) are NOT the same as their viewer representation. if (pick.mPickType == LLPickInfo::PICK_FLORA) { *hit_obj = NULL; *hit_face = -1; } else { *hit_obj = pick.getObject(); *hit_face = pick.mObjectFace; } *b_hit_land = !(*hit_obj) && !pick.mPosGlobal.isExactlyZero(); LLVector3d land_pos_global = pick.mPosGlobal; // Make sure there's a surface to place the new object on. BOOL bypass_sim_raycast = FALSE; LLVector3d surface_pos_global; if (*b_hit_land) { surface_pos_global = land_pos_global; bypass_sim_raycast = TRUE; } else if (*hit_obj) { surface_pos_global = (*hit_obj)->getPositionGlobal(); } else { return FALSE; } // Make sure the surface isn't too far away. LLVector3d ray_start_global = gAgentCamera.getCameraPositionGlobal(); F32 dist_to_surface_sq = (F32)((surface_pos_global - ray_start_global).magVecSquared()); if( dist_to_surface_sq > (max_dist_from_camera * max_dist_from_camera) ) { return FALSE; } // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0f // NOTE: don't use surface_pos_global since for prims it will be the center of the prim while we need center + offset if ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && (dist_vec_squared(gAgent.getPositionGlobal(), pick.mPosGlobal) > 1.5f * 1.5f) ) { return FALSE; } // [/RLVa:KB] // Find the sim where the surface lives. LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(surface_pos_global); if (!regionp) { llwarns << "Trying to add object outside of all known regions!" << llendl; return FALSE; } // Find the simulator-side ray that will be used to place the object accurately LLVector3d mouse_direction; mouse_direction.setVec( gViewerWindow->mouseDirectionGlobal( x, y ) ); *region = regionp; *ray_start_region = regionp->getPosRegionFromGlobal( ray_start_global ); F32 near_clip = LLViewerCamera::getInstance()->getNear() + 0.01f; // Include an epsilon to avoid rounding issues. *ray_start_region += LLViewerCamera::getInstance()->getAtAxis() * near_clip; if( bypass_sim_raycast ) { // Hack to work around Havok's inability to ray cast onto height fields *ray_end_region = regionp->getPosRegionFromGlobal( surface_pos_global ); // ray end is the viewer's intersection point } else { LLVector3d ray_end_global = ray_start_global + (1.f + max_dist_from_camera) * mouse_direction; // add an epsilon to the sim version of the ray to avoid rounding problems. *ray_end_region = regionp->getPosRegionFromGlobal( ray_end_global ); } return TRUE; }
void LLToolCamera::pickCallback(const LLPickInfo& pick_info) { if (!LLToolCamera::getInstance()->hasMouseCapture()) { return; } LLToolCamera::getInstance()->mMouseDownX = pick_info.mMousePt.mX; LLToolCamera::getInstance()->mMouseDownY = pick_info.mMousePt.mY; gViewerWindow->moveCursorToCenter(); // Potentially recenter if click outside rectangle LLViewerObject* hit_obj = pick_info.getObject(); // Check for hit the sky, or some other invalid point if (!hit_obj && pick_info.mPosGlobal.isExactlyZero()) { LLToolCamera::getInstance()->mValidClickPoint = FALSE; return; } // check for hud attachments if (hit_obj && hit_obj->isHUDAttachment()) { LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); if (!selection->getObjectCount() || selection->getSelectType() != SELECT_TYPE_HUD) { LLToolCamera::getInstance()->mValidClickPoint = FALSE; return; } } if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode() ) { BOOL good_customize_avatar_hit = FALSE; if( hit_obj ) { LLVOAvatar* avatar = gAgent.getAvatarObject(); if( hit_obj == avatar) { // It's you good_customize_avatar_hit = TRUE; } else if( hit_obj->isAttachment() && hit_obj->permYouOwner() ) { // It's an attachment that you're wearing good_customize_avatar_hit = TRUE; } } if( !good_customize_avatar_hit ) { LLToolCamera::getInstance()->mValidClickPoint = FALSE; return; } if( gMorphView ) { gMorphView->setCameraDrivenByKeys( FALSE ); } } //RN: check to see if this is mouse-driving as opposed to ALT-zoom or Focus tool else if (pick_info.mKeyMask & MASK_ALT || (LLToolMgr::getInstance()->getCurrentTool()->getName() == "Camera")) { LLViewerObject* hit_obj = pick_info.getObject(); if (hit_obj) { // ...clicked on a world object, so focus at its position if (!hit_obj->isHUDAttachment()) { gAgent.setFocusOnAvatar(FALSE, ANIMATE); gAgent.setFocusGlobal(pick_info); } } else if (!pick_info.mPosGlobal.isExactlyZero()) { // Hit the ground gAgent.setFocusOnAvatar(FALSE, ANIMATE); gAgent.setFocusGlobal(pick_info); } static const LLCachedControl<bool> freeze_time("FreezeTime",0); if (!(pick_info.mKeyMask & MASK_ALT) && gAgent.cameraThirdPerson() && gViewerWindow->getLeftMouseDown() && !freeze_time && (hit_obj == gAgent.getAvatarObject() || (hit_obj && hit_obj->isAttachment() && LLVOAvatar::findAvatarFromAttachment(hit_obj)->isSelf()))) { LLToolCamera::getInstance()->mMouseSteering = TRUE; } } LLToolCamera::getInstance()->mValidClickPoint = TRUE; if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode() ) { gAgent.setFocusOnAvatar(FALSE, FALSE); LLVector3d cam_pos = gAgent.getCameraPositionGlobal(); cam_pos -= LLVector3d(LLViewerCamera::getInstance()->getLeftAxis() * gAgent.calcCustomizeAvatarUIOffset( cam_pos )); gAgent.setCameraPosAndFocusGlobal( cam_pos, pick_info.mPosGlobal, pick_info.mObjectID); } }
// static LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pick, BOOL ignore_group, BOOL temp_select, BOOL select_root) { LLViewerObject* object = pick.getObject(); if (select_root) { object = object->getRootEdit(); } BOOL select_owned = gSavedSettings.getBOOL("SelectOwnedOnly"); BOOL select_movable = gSavedSettings.getBOOL("SelectMovableOnly"); // *NOTE: These settings must be cleaned up at bottom of function. if (temp_select || LLSelectMgr::getInstance()->mAllowSelectAvatar) { gSavedSettings.setBOOL("SelectOwnedOnly", FALSE); gSavedSettings.setBOOL("SelectMovableOnly", FALSE); LLSelectMgr::getInstance()->setForceSelection(TRUE); } BOOL extend_select = (pick.mKeyMask == MASK_SHIFT) || (pick.mKeyMask == MASK_CONTROL); // If no object, check for icon, then just deselect if (!object) { LLHUDIcon* last_hit_hud_icon = pick.mHUDIcon; if (last_hit_hud_icon && last_hit_hud_icon->getSourceObject()) { LLFloaterScriptDebug::show(last_hit_hud_icon->getSourceObject()->getID()); } else if (!extend_select) { LLSelectMgr::getInstance()->deselectAll(); } } else { BOOL already_selected = object->isSelected(); if (already_selected && object->getNumTEs() > 0 && !LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES)) { const LLTextureEntry* tep = object->getTE(pick.mObjectFace); if (tep && !tep->isSelected() && !LLViewerMediaFocus::getInstance()->getFocusedObjectID().isNull()) { // we were interacting with media and clicked on non selected face, drop media focus LLViewerMediaFocus::getInstance()->clearFocus(); // selection was removed and zoom preserved by clearFocus(), continue with regular selection already_selected = false; extend_select = true; } } if ( extend_select ) { if ( already_selected ) { if ( ignore_group ) { LLSelectMgr::getInstance()->deselectObjectOnly(object); } else { LLSelectMgr::getInstance()->deselectObjectAndFamily(object, TRUE, TRUE); } } else { if ( ignore_group ) { LLSelectMgr::getInstance()->selectObjectOnly(object, SELECT_ALL_TES); } else { LLSelectMgr::getInstance()->selectObjectAndFamily(object); } } } else { // Save the current zoom values because deselect resets them. F32 target_zoom; F32 current_zoom; LLSelectMgr::getInstance()->getAgentHUDZoom(target_zoom, current_zoom); // JC - Change behavior to make it easier to select children // of linked sets. 9/3/2002 if( !already_selected || ignore_group) { // ...lose current selection in favor of just this object LLSelectMgr::getInstance()->deselectAll(); } if ( ignore_group ) { LLSelectMgr::getInstance()->selectObjectOnly(object, SELECT_ALL_TES); } else { LLSelectMgr::getInstance()->selectObjectAndFamily(object); } // restore the zoom to the previously stored values. LLSelectMgr::getInstance()->setAgentHUDZoom(target_zoom, current_zoom); } if (!gAgentCamera.getFocusOnAvatar() && // if camera not glued to avatar LLVOAvatar::findAvatarFromAttachment(object) != gAgentAvatarp && // and it's not one of your attachments object != gAgentAvatarp) // and it's not you { // have avatar turn to face the selected object(s) LLVector3d selection_center = LLSelectMgr::getInstance()->getSelectionCenterGlobal(); selection_center = selection_center - gAgent.getPositionGlobal(); LLVector3 selection_dir; selection_dir.setVec(selection_center); selection_dir.mV[VZ] = 0.f; selection_dir.normVec(); if (!object->isAvatar() && gAgent.getAtAxis() * selection_dir < 0.6f) { LLQuaternion target_rot; target_rot.shortestArc(LLVector3::x_axis, selection_dir); gAgent.startAutoPilotGlobal(gAgent.getPositionGlobal(), "", &target_rot, NULL, NULL, 1.f, SELECTION_ROTATION_TRESHOLD); } } if (temp_select) { if (!already_selected) { LLViewerObject* root_object = (LLViewerObject*)object->getRootEdit(); LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); // this is just a temporary selection LLSelectNode* select_node = selection->findNode(root_object); if (select_node) { select_node->setTransient(TRUE); } LLViewerObject::const_child_list_t& child_list = root_object->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); iter != child_list.end(); iter++) { LLViewerObject* child = *iter; select_node = selection->findNode(child); if (select_node) { select_node->setTransient(TRUE); } } } } //if(temp_select) } //if(!object) // Cleanup temp select settings above. if (temp_select ||LLSelectMgr::getInstance()->mAllowSelectAvatar) { gSavedSettings.setBOOL("SelectOwnedOnly", select_owned); gSavedSettings.setBOOL("SelectMovableOnly", select_movable); LLSelectMgr::getInstance()->setForceSelection(FALSE); } return LLSelectMgr::getInstance()->getSelection(); }
BOOL LLToolGrab::handleObjectHit(const LLPickInfo& info) { mGrabPick = info; LLViewerObject* objectp = mGrabPick.getObject(); if (gDebugClicks) { llinfos << "LLToolGrab handleObjectHit " << info.mMousePt.mX << "," << info.mMousePt.mY << llendl; } if (NULL == objectp) // unexpected { llwarns << "objectp was NULL; returning FALSE" << llendl; return FALSE; } //if (objectp->isAvatar()) // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0f if ( (objectp->isAvatar()) || ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && ((!objectp->isAttachment()) || (!objectp->permYouOwner())) && (dist_vec_squared(gAgent.getPositionAgent(), mGrabPick.mIntersection) > 1.5f * 1.5f) ) ) // [/RLVa:KB] { if (gGrabTransientTool) { gBasicToolset->selectTool( gGrabTransientTool ); gGrabTransientTool = NULL; } return TRUE; } setMouseCapture( TRUE ); // Grabs always start from the root // objectp = (LLViewerObject *)objectp->getRoot(); LLViewerObject* parent = objectp->getRootEdit(); BOOL script_touch = (objectp->flagHandleTouch()) || (parent && parent->flagHandleTouch()); // Clicks on scripted or physical objects are temporary grabs, so // not "Build mode" mHideBuildHighlight = script_touch || objectp->usePhysics(); if (!objectp->usePhysics()) { // In mouselook, we shouldn't be able to grab non-physical, // non-touchable objects. If it has a touch handler, we // do grab it (so llDetectedGrab works), but movement is // blocked on the server side. JC if (gAgent.cameraMouselook() && !script_touch) { mMode = GRAB_LOCKED; gViewerWindow->hideCursor(); gViewerWindow->moveCursorToCenter(); } else { mMode = GRAB_NONPHYSICAL; } // Don't bail out here, go on and grab so buttons can get // their "touched" event. } else if( !objectp->permMove() ) { // if mouse is over a physical object without move permission, show feedback if user tries to move it. mMode = GRAB_LOCKED; // Don't bail out here, go on and grab so buttons can get // their "touched" event. } else { // if mouse is over a physical object with move permission, // select it and enter "grab" mode (hiding cursor, etc.) mMode = GRAB_ACTIVE_CENTER; gViewerWindow->hideCursor(); gViewerWindow->moveCursorToCenter(); } // Always send "touched" message mLastMouseX = gViewerWindow->getCurrentMouseX(); mLastMouseY = gViewerWindow->getCurrentMouseY(); mAccumDeltaX = 0; mAccumDeltaY = 0; mHasMoved = FALSE; mOutsideSlop = FALSE; mVerticalDragging = (info.mKeyMask == MASK_VERTICAL) || gGrabBtnVertical; startGrab(); if ((info.mKeyMask == MASK_SPIN) || gGrabBtnSpin) { startSpin(); } LLSelectMgr::getInstance()->updateSelectionCenter(); // update selection beam // update point at LLViewerObject *edit_object = info.getObject(); if (edit_object && info.mPickType != LLPickInfo::PICK_FLORA) { LLVector3 local_edit_point = gAgent.getPosAgentFromGlobal(info.mPosGlobal); local_edit_point -= edit_object->getPositionAgent(); local_edit_point = local_edit_point * ~edit_object->getRenderRotation(); gAgent.setPointAt(POINTAT_TARGET_GRAB, edit_object, local_edit_point ); gAgent.setLookAt(LOOKAT_TARGET_SELECT, edit_object, local_edit_point ); } // on transient grabs (clicks on world objects), kill the grab immediately if (!gViewerWindow->getLeftMouseDown() && gGrabTransientTool && (mMode == GRAB_NONPHYSICAL || mMode == GRAB_LOCKED)) { gBasicToolset->selectTool( gGrabTransientTool ); gGrabTransientTool = NULL; } return TRUE; }
void LLToolGrab::handleHoverNonPhysical(S32 x, S32 y, MASK mask) { LLViewerObject* objectp = mGrabPick.getObject(); if (!objectp || !hasMouseCapture() ) return; if (objectp->isDead()) { // Bail out of drag because object has been killed setMouseCapture(FALSE); return; } LLPickInfo pick = mGrabPick; pick.mMousePt = LLCoordGL(x, y); pick.getSurfaceInfo(); // compute elapsed time F32 dt = mGrabTimer.getElapsedTimeAndResetF32(); U32 dt_milliseconds = (U32) (1000.f * dt); // i'm not a big fan of the following code - it's been culled from the physical grab case. // ideally these two would be nicely integrated - but the code in that method is a serious // mess of spaghetti. so here we go: LLVector3 grab_pos_region(0,0,0); const BOOL SUPPORT_LLDETECTED_GRAB = TRUE; if (SUPPORT_LLDETECTED_GRAB) { //-------------------------------------------------- // Toggle vertical dragging //-------------------------------------------------- if (mVerticalDragging && !(mask == MASK_VERTICAL) && !gGrabBtnVertical) { mVerticalDragging = FALSE; } else if (!mVerticalDragging && (mask == MASK_VERTICAL) ) { mVerticalDragging = TRUE; } S32 dx = x - mLastMouseX; S32 dy = y - mLastMouseY; if (dx != 0 || dy != 0) { mAccumDeltaX += dx; mAccumDeltaY += dy; S32 dist_sq = mAccumDeltaX * mAccumDeltaX + mAccumDeltaY * mAccumDeltaY; if (dist_sq > SLOP_DIST_SQ) { mOutsideSlop = TRUE; } // mouse has moved mHasMoved = TRUE; //------------------------------------------------------ // Handle grabbing //------------------------------------------------------ LLVector3d x_part; x_part.setVec(LLViewerCamera::getInstance()->getLeftAxis()); x_part.mdV[VZ] = 0.0; x_part.normVec(); LLVector3d y_part; if( mVerticalDragging ) { y_part.setVec(LLViewerCamera::getInstance()->getUpAxis()); // y_part.setVec(0.f, 0.f, 1.f); } else { // drag toward camera y_part = x_part % LLVector3d::z_axis; y_part.mdV[VZ] = 0.0; y_part.normVec(); } mGrabHiddenOffsetFromCamera = mGrabHiddenOffsetFromCamera + (x_part * (-dx * GRAB_SENSITIVITY_X)) + (y_part * ( dy * GRAB_SENSITIVITY_Y)); } // need to return offset from mGrabStartPoint LLVector3d grab_point_global = gAgent.getCameraPositionGlobal() + mGrabHiddenOffsetFromCamera; grab_pos_region = objectp->getRegion()->getPosRegionFromGlobal( grab_point_global ); } LLMessageSystem *msg = gMessageSystem; msg->newMessageFast(_PREHASH_ObjectGrabUpdate); msg->nextBlockFast(_PREHASH_AgentData); msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); msg->nextBlockFast(_PREHASH_ObjectData); msg->addUUIDFast(_PREHASH_ObjectID, objectp->getID() ); msg->addVector3Fast(_PREHASH_GrabOffsetInitial, mGrabOffsetFromCenterInitial ); msg->addVector3Fast(_PREHASH_GrabPosition, grab_pos_region ); msg->addU32Fast(_PREHASH_TimeSinceLast, dt_milliseconds ); msg->nextBlock("SurfaceInfo"); msg->addVector3("UVCoord", LLVector3(pick.mUVCoords)); msg->addVector3("STCoord", LLVector3(pick.mSTCoords)); msg->addS32Fast(_PREHASH_FaceIndex, pick.mObjectFace); msg->addVector3("Position", pick.mIntersection); msg->addVector3("Normal", pick.mNormal); msg->addVector3("Binormal", pick.mBinormal); msg->sendMessage( objectp->getRegion()->getHost() ); // update point-at / look-at if (pick.mObjectFace != -1) // if the intersection was on the surface of the obejct { LLVector3 local_edit_point = pick.mIntersection; local_edit_point -= objectp->getPositionAgent(); local_edit_point = local_edit_point * ~objectp->getRenderRotation(); gAgent.setPointAt(POINTAT_TARGET_GRAB, objectp, local_edit_point ); gAgent.setLookAt(LOOKAT_TARGET_SELECT, objectp, local_edit_point ); } gViewerWindow->setCursor(UI_CURSOR_HAND); }