00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034
00035 #include "llselectmgr.h"
00036
00037
00038 #include "llcachename.h"
00039 #include "lldbstrings.h"
00040 #include "lleconomy.h"
00041 #include "llgl.h"
00042 #include "llpermissions.h"
00043 #include "llpermissionsflags.h"
00044 #include "llptrskiplist.h"
00045 #include "llundo.h"
00046 #include "lluuid.h"
00047 #include "llvolume.h"
00048 #include "message.h"
00049 #include "object_flags.h"
00050 #include "llquaternion.h"
00051
00052
00053 #include "llagent.h"
00054 #include "llviewerwindow.h"
00055 #include "lldrawable.h"
00056 #include "llfloaterinspect.h"
00057 #include "llfloaterproperties.h"
00058 #include "llfloaterreporter.h"
00059 #include "llfloatertools.h"
00060 #include "llframetimer.h"
00061 #include "llhudeffecttrail.h"
00062 #include "llhudmanager.h"
00063 #include "llinventorymodel.h"
00064 #include "llmenugl.h"
00065 #include "llstatusbar.h"
00066 #include "llsurface.h"
00067 #include "lltool.h"
00068 #include "lltooldraganddrop.h"
00069 #include "lltoolmgr.h"
00070 #include "lltoolpie.h"
00071 #include "llui.h"
00072 #include "llviewercamera.h"
00073 #include "llviewercontrol.h"
00074 #include "llviewerimagelist.h"
00075 #include "llviewermenu.h"
00076 #include "llviewerobject.h"
00077 #include "llviewerobjectlist.h"
00078 #include "llviewerregion.h"
00079 #include "llviewerstats.h"
00080 #include "llvoavatar.h"
00081 #include "llvovolume.h"
00082 #include "pipeline.h"
00083
00084 #include "llglheaders.h"
00085
00086
00087
00088
00089
00090 const S32 NUM_SELECTION_UNDO_ENTRIES = 200;
00091 const F32 SILHOUETTE_UPDATE_THRESHOLD_SQUARED = 0.02f;
00092 const S32 OWNERSHIP_COST_PER_OBJECT = 10;
00093 const S32 MAX_ACTION_QUEUE_SIZE = 20;
00094 const S32 MAX_SILS_PER_FRAME = 50;
00095 const S32 MAX_OBJECTS_PER_PACKET = 254;
00096
00097 extern LLUUID gLastHitObjectID;
00098 extern LLVector3d gLastHitObjectOffset;
00099
00100
00101
00102
00103 LLSelectMgr* gSelectMgr = NULL;
00104
00105 BOOL gDebugSelectMgr = FALSE;
00106
00107 BOOL gHideSelectedObjects = FALSE;
00108 BOOL gAllowSelectAvatar = FALSE;
00109
00110 BOOL LLSelectMgr::sRectSelectInclusive = TRUE;
00111 BOOL LLSelectMgr::sRenderHiddenSelections = TRUE;
00112 BOOL LLSelectMgr::sRenderLightRadius = FALSE;
00113 F32 LLSelectMgr::sHighlightThickness = 0.f;
00114 F32 LLSelectMgr::sHighlightUScale = 0.f;
00115 F32 LLSelectMgr::sHighlightVScale = 0.f;
00116 F32 LLSelectMgr::sHighlightAlpha = 0.f;
00117 F32 LLSelectMgr::sHighlightAlphaTest = 0.f;
00118 F32 LLSelectMgr::sHighlightUAnim = 0.f;
00119 F32 LLSelectMgr::sHighlightVAnim = 0.f;
00120 LLColor4 LLSelectMgr::sSilhouetteParentColor;
00121 LLColor4 LLSelectMgr::sSilhouetteChildColor;
00122 LLColor4 LLSelectMgr::sHighlightInspectColor;
00123 LLColor4 LLSelectMgr::sHighlightParentColor;
00124 LLColor4 LLSelectMgr::sHighlightChildColor;
00125 LLColor4 LLSelectMgr::sContextSilhouetteColor;
00126
00127 static LLObjectSelection *get_null_object_selection();
00128 template<>
00129 const LLHandle<LLObjectSelection>::NullFunc
00130 LLHandle<LLObjectSelection>::sNullFunc = get_null_object_selection;
00131
00132
00133
00134
00135
00136
00137
00138 struct LLDeRezInfo
00139 {
00140 EDeRezDestination mDestination;
00141 LLUUID mDestinationID;
00142 LLDeRezInfo(EDeRezDestination dest, const LLUUID& dest_id) :
00143 mDestination(dest), mDestinationID(dest_id) {}
00144 };
00145
00146
00147
00148
00149
00150
00151 static LLPointer<LLObjectSelection> sNullSelection;
00152
00153
00154
00155
00156
00157 void LLSelectMgr::cleanupGlobals()
00158 {
00159 delete gSelectMgr;
00160 gSelectMgr = NULL;
00161 sNullSelection = NULL;
00162 }
00163
00164 LLObjectSelection *get_null_object_selection()
00165 {
00166 if (sNullSelection.isNull())
00167 {
00168 sNullSelection = new LLObjectSelection;
00169 }
00170 return sNullSelection;
00171 }
00172
00173
00174
00175
00176
00177 LLSelectMgr::LLSelectMgr()
00178 {
00179 mTEMode = FALSE;
00180 mLastCameraPos.clearVec();
00181
00182 sHighlightThickness = gSavedSettings.getF32("SelectionHighlightThickness");
00183 sHighlightUScale = gSavedSettings.getF32("SelectionHighlightUScale");
00184 sHighlightVScale = gSavedSettings.getF32("SelectionHighlightVScale");
00185 sHighlightAlpha = gSavedSettings.getF32("SelectionHighlightAlpha");
00186 sHighlightAlphaTest = gSavedSettings.getF32("SelectionHighlightAlphaTest");
00187 sHighlightUAnim = gSavedSettings.getF32("SelectionHighlightUAnim");
00188 sHighlightVAnim = gSavedSettings.getF32("SelectionHighlightVAnim");
00189
00190 sSilhouetteParentColor = gColors.getColor("SilhouetteParentColor");
00191 sSilhouetteChildColor = gColors.getColor("SilhouetteChildColor");
00192 sHighlightParentColor = gColors.getColor("HighlightParentColor");
00193 sHighlightChildColor = gColors.getColor("HighlightChildColor");
00194 sHighlightInspectColor = gColors.getColor("HighlightInspectColor");
00195 sContextSilhouetteColor = gColors.getColor("ContextSilhouetteColor")*0.5f;
00196
00197 sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius");
00198
00199 mRenderSilhouettes = TRUE;
00200
00201 mGridMode = GRID_MODE_WORLD;
00202 gSavedSettings.setS32("GridMode", (S32)GRID_MODE_WORLD);
00203 mGridValid = FALSE;
00204
00205 mSelectedObjects = new LLObjectSelection();
00206 mHoverObjects = new LLObjectSelection();
00207 mHighlightedObjects = new LLObjectSelection();
00208 }
00209
00210
00211
00212
00213
00214 LLSelectMgr::~LLSelectMgr()
00215 {
00216 clearSelections();
00217 }
00218
00219 void LLSelectMgr::clearSelections()
00220 {
00221 mHoverObjects->deleteAllNodes();
00222 mSelectedObjects->deleteAllNodes();
00223 mHighlightedObjects->deleteAllNodes();
00224 mRectSelectedObjects.clear();
00225 mGridObjects.deleteAllNodes();
00226 }
00227
00228 void LLSelectMgr::update()
00229 {
00230 mSelectedObjects->cleanupNodes();
00231 }
00232
00233 void LLSelectMgr::updateEffects()
00234 {
00235
00236 struct f : public LLSelectedObjectFunctor
00237 {
00238 virtual bool apply(LLViewerObject* object)
00239 {
00240 LLDrawable* drawable = object->mDrawable;
00241 if (drawable)
00242 {
00243 gPipeline.markMoved(drawable);
00244 }
00245 return true;
00246 }
00247 } func;
00248 mGridObjects.applyToObjects(&func);
00249
00250 if (mEffectsTimer.getElapsedTimeF32() > 1.f)
00251 {
00252 mSelectedObjects->updateEffects();
00253 mEffectsTimer.reset();
00254 }
00255 }
00256
00257 void LLSelectMgr::overrideObjectUpdates()
00258 {
00259
00260 struct f : public LLSelectedNodeFunctor
00261 {
00262 virtual bool apply(LLSelectNode* selectNode)
00263 {
00264 LLViewerObject* object = selectNode->getObject();
00265 if (object->permMove())
00266 {
00267 if (!selectNode->mLastPositionLocal.isExactlyZero())
00268 {
00269 object->setPosition(selectNode->mLastPositionLocal);
00270 }
00271 if (selectNode->mLastRotation != LLQuaternion())
00272 {
00273 object->setRotation(selectNode->mLastRotation);
00274 }
00275 if (!selectNode->mLastScale.isExactlyZero())
00276 {
00277 object->setScale(selectNode->mLastScale);
00278 }
00279 }
00280 return true;
00281 }
00282 } func;
00283 getSelection()->applyToNodes(&func);
00284 }
00285
00286
00287
00288
00289 LLObjectSelectionHandle LLSelectMgr::selectObjectOnly(LLViewerObject* object, S32 face)
00290 {
00291 llassert( object );
00292
00293
00294 mSelectedObjects->mPrimaryObject = object;
00295
00296
00297 if (object->isSelected() ) {
00298
00299 updatePointAt();
00300 gEditMenuHandler = this;
00301 return NULL;
00302 }
00303
00304 if (!canSelectObject(object))
00305 {
00306
00307 return NULL;
00308 }
00309
00310
00311
00312
00313
00314 addAsIndividual(object, face);
00315
00316
00317
00318
00319 object->setVelocity(LLVector3::zero);
00320 object->setAcceleration(LLVector3::zero);
00321
00322 object->resetRot();
00323
00324
00325
00326 gMessageSystem->newMessageFast(_PREHASH_ObjectSelect);
00327 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
00328 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
00329 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00330 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
00331 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() );
00332 LLViewerRegion* regionp = object->getRegion();
00333 gMessageSystem->sendReliable( regionp->getHost());
00334
00335 updatePointAt();
00336 updateSelectionCenter();
00337 saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
00338
00339
00340
00341 if (mSelectedObjects->getObjectCount())
00342 {
00343 gEditMenuHandler = this;
00344 }
00345
00346 return mSelectedObjects;
00347 }
00348
00349
00350
00351
00352 LLObjectSelectionHandle LLSelectMgr::selectObjectAndFamily(LLViewerObject* obj, BOOL add_to_end)
00353 {
00354 llassert( obj );
00355
00356
00357 mSelectedObjects->mPrimaryObject = obj;
00358
00359
00360
00361 if (obj->isSelected() )
00362 {
00363
00364 updatePointAt();
00365 gEditMenuHandler = this;
00366 return NULL;
00367 }
00368
00369 if (!canSelectObject(obj))
00370 {
00371
00372 return NULL;
00373 }
00374
00375
00376
00377 LLViewerObject* root = obj;
00378
00379 while(!root->isAvatar() && root->getParent() && !root->isJointChild())
00380 {
00381 LLViewerObject* parent = (LLViewerObject*)root->getParent();
00382 if (parent->isAvatar())
00383 {
00384 break;
00385 }
00386 root = parent;
00387 }
00388
00389
00390 LLDynamicArray<LLViewerObject*> objects;
00391
00392 root->addThisAndNonJointChildren(objects);
00393 addAsFamily(objects, add_to_end);
00394
00395 updateSelectionCenter();
00396 saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
00397 updatePointAt();
00398
00399 dialog_refresh_all();
00400
00401
00402
00403 sendSelect();
00404
00405
00406
00407 root->setVelocity(LLVector3::zero);
00408 root->setAcceleration(LLVector3::zero);
00409
00410 root->resetRot();
00411
00412
00413 if (gSavedSettings.getBOOL("EditLinkedParts"))
00414 {
00415 gSavedSettings.setBOOL("EditLinkedParts", FALSE);
00416 promoteSelectionToRoot();
00417 }
00418
00419
00420
00421 if (mSelectedObjects->getObjectCount())
00422 {
00423 gEditMenuHandler = this;
00424 }
00425
00426 return mSelectedObjects;
00427 }
00428
00429
00430
00431
00432 LLObjectSelectionHandle LLSelectMgr::selectObjectAndFamily(const std::vector<LLViewerObject*>& object_list,
00433 BOOL send_to_sim)
00434 {
00435
00436 LLDynamicArray<LLViewerObject*> objects;
00437
00438
00439 mSelectedObjects->mPrimaryObject = NULL;
00440
00441 if (object_list.size() < 1)
00442 {
00443 return NULL;
00444 }
00445
00446
00447
00448 for (std::vector<LLViewerObject*>::const_reverse_iterator riter = object_list.rbegin();
00449 riter != object_list.rend(); ++riter)
00450 {
00451 LLViewerObject *object = *riter;
00452
00453 llassert( object );
00454
00455 if (!canSelectObject(object)) continue;
00456
00457 object->addThisAndNonJointChildren(objects);
00458 addAsFamily(objects);
00459
00460
00461
00462 object->setVelocity(LLVector3::zero);
00463 object->setAcceleration(LLVector3::zero);
00464
00465 object->resetRot();
00466 }
00467
00468 updateSelectionCenter();
00469 saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
00470 updatePointAt();
00471 dialog_refresh_all();
00472
00473
00474
00475
00476
00477 if (send_to_sim)
00478 {
00479 sendSelect();
00480 }
00481
00482
00483 if (gSavedSettings.getBOOL("EditLinkedParts"))
00484 {
00485 gSavedSettings.setBOOL("EditLinkedParts", FALSE);
00486 promoteSelectionToRoot();
00487 }
00488
00489
00490
00491 if (mSelectedObjects->getObjectCount())
00492 {
00493 gEditMenuHandler = this;
00494 }
00495
00496 return mSelectedObjects;
00497 }
00498
00499
00500
00501
00502
00503 BOOL LLSelectMgr::removeObjectFromSelections(const LLUUID &id)
00504 {
00505 BOOL object_found = FALSE;
00506 LLTool *tool = NULL;
00507 if (!gNoRender)
00508 {
00509 tool = gToolMgr->getCurrentTool();
00510
00511
00512 LLViewerObject* tool_editing_object = tool->getEditingObject();
00513 if( tool_editing_object && tool_editing_object->mID == id)
00514 {
00515 tool->stopEditing();
00516 object_found = TRUE;
00517 }
00518 }
00519
00520
00521 if( !object_found )
00522 {
00523 for (LLObjectSelection::iterator iter = getSelection()->begin();
00524 iter != getSelection()->end(); )
00525 {
00526 LLObjectSelection::iterator curiter = iter++;
00527 LLViewerObject* object = (*curiter)->getObject();
00528 if (object->mID == id)
00529 {
00530 if (tool)
00531 {
00532 tool->stopEditing();
00533 }
00534
00535
00536 deselectObjectAndFamily(object, FALSE);
00537 object_found = TRUE;
00538 break;
00539 }
00540 else if (object->isAvatar())
00541 {
00542
00543
00544 deselectObjectAndFamily(object, FALSE);
00545 break;
00546 }
00547 }
00548 }
00549
00550 return object_found;
00551 }
00552
00553 void LLSelectMgr::deselectObjectAndFamily(LLViewerObject* object, BOOL send_to_sim, BOOL include_entire_object)
00554 {
00555
00556 if(!object) return;
00557 if(!object->isSelected()) return;
00558
00559
00560 LLDynamicArray<LLViewerObject*> objects;
00561
00562 if (include_entire_object)
00563 {
00564
00565
00566 LLViewerObject* root = object;
00567
00568 while(!root->isAvatar() && root->getParent() && !root->isJointChild())
00569 {
00570 LLViewerObject* parent = (LLViewerObject*)root->getParent();
00571 if (parent->isAvatar())
00572 {
00573 break;
00574 }
00575 root = parent;
00576 }
00577
00578 object = root;
00579 }
00580 else
00581 {
00582 object = (LLViewerObject*)object->getRoot();
00583 }
00584
00585 object->addThisAndAllChildren(objects);
00586 remove(objects);
00587
00588 if (!send_to_sim) return;
00589
00590
00591
00592
00593 LLViewerRegion* regionp = object->getRegion();
00594
00595 BOOL start_new_message = TRUE;
00596 S32 select_count = 0;
00597
00598 LLMessageSystem* msg = gMessageSystem;
00599 for (U32 i = 0; i < objects.size(); i++)
00600 {
00601 if (start_new_message)
00602 {
00603 msg->newMessageFast(_PREHASH_ObjectDeselect);
00604 msg->nextBlockFast(_PREHASH_AgentData);
00605 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
00606 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00607 select_count++;
00608 start_new_message = FALSE;
00609 }
00610
00611 msg->nextBlockFast(_PREHASH_ObjectData);
00612 msg->addU32Fast(_PREHASH_ObjectLocalID, (objects[i])->getLocalID());
00613 select_count++;
00614
00615 if(msg->isSendFull(NULL) || select_count >= MAX_OBJECTS_PER_PACKET)
00616 {
00617 msg->sendReliable(regionp->getHost() );
00618 select_count = 0;
00619 start_new_message = TRUE;
00620 }
00621 }
00622
00623 if (!start_new_message)
00624 {
00625 msg->sendReliable(regionp->getHost() );
00626 }
00627
00628 updatePointAt();
00629 updateSelectionCenter();
00630 }
00631
00632 void LLSelectMgr::deselectObjectOnly(LLViewerObject* object, BOOL send_to_sim)
00633 {
00634
00635 if (!object) return;
00636 if (!object->isSelected() ) return;
00637
00638 if (send_to_sim)
00639 {
00640 LLViewerRegion* region = object->getRegion();
00641 gMessageSystem->newMessageFast(_PREHASH_ObjectDeselect);
00642 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
00643 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
00644 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00645 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
00646 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() );
00647 gMessageSystem->sendReliable(region->getHost());
00648 }
00649
00650
00651 remove( object );
00652
00653 updatePointAt();
00654 updateSelectionCenter();
00655 }
00656
00657
00658
00659
00660
00661
00662 void LLSelectMgr::addAsFamily(std::vector<LLViewerObject*>& objects, BOOL add_to_end)
00663 {
00664 for (std::vector<LLViewerObject*>::iterator iter = objects.begin();
00665 iter != objects.end(); ++iter)
00666 {
00667 LLViewerObject* objectp = *iter;
00668
00669
00670 if (objectp->mID == gAgentID
00671 && !gAllowSelectAvatar)
00672 {
00673 continue;
00674 }
00675
00676 if (!objectp->isSelected())
00677 {
00678 LLSelectNode *nodep = new LLSelectNode(objectp, TRUE);
00679 if (add_to_end)
00680 {
00681 mSelectedObjects->addNodeAtEnd(nodep);
00682 }
00683 else
00684 {
00685 mSelectedObjects->addNode(nodep);
00686 }
00687 objectp->setSelected(TRUE);
00688
00689 if (objectp->getNumTEs() > 0)
00690 {
00691 nodep->selectAllTEs(TRUE);
00692 }
00693 else
00694 {
00695
00696 }
00697 }
00698 else
00699 {
00700
00701
00702 LLSelectNode* select_node = mSelectedObjects->findNode(objectp);
00703 if (select_node)
00704 {
00705 select_node->setTransient(FALSE);
00706 }
00707 }
00708 }
00709 saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
00710 }
00711
00712
00713
00714
00715 void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoable)
00716 {
00717
00718 LLSelectNode *nodep = mSelectedObjects->findNode(objectp);
00719
00720
00721 if (!nodep)
00722 {
00723 nodep = new LLSelectNode(objectp, TRUE);
00724 mSelectedObjects->addNode(nodep);
00725 llassert_always(nodep->getObject());
00726 }
00727 else
00728 {
00729
00730 nodep->setTransient(FALSE);
00731
00732 mSelectedObjects->moveNodeToFront(nodep);
00733 }
00734
00735
00736 objectp->setSelected( TRUE );
00737
00738
00739 nodep->mIndividualSelection = TRUE;
00740
00741
00742 if (objectp->getNumTEs() <= 0)
00743 {
00744
00745 }
00746 else if (face == SELECT_ALL_TES)
00747 {
00748 nodep->selectAllTEs(TRUE);
00749 }
00750 else if (0 <= face && face < SELECT_MAX_TES)
00751 {
00752 nodep->selectTE(face, TRUE);
00753 }
00754 else
00755 {
00756 llerrs << "LLSelectMgr::add face " << face << " out-of-range" << llendl;
00757 return;
00758 }
00759
00760 saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
00761 updateSelectionCenter();
00762 dialog_refresh_all();
00763 }
00764
00765
00766 LLObjectSelectionHandle LLSelectMgr::setHoverObject(LLViewerObject *objectp)
00767 {
00768
00769 mHoverObjects->deleteAllNodes();
00770
00771 if (!objectp)
00772 {
00773 return NULL;
00774 }
00775
00776
00777 if (objectp->mID == gAgentID)
00778 {
00779 return NULL;
00780 }
00781
00782
00783 if (objectp->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH)
00784 {
00785 return NULL;
00786 }
00787
00788
00789 LLDynamicArray<LLViewerObject*> objects;
00790 objectp = objectp->getRootEdit();
00791 objectp->addThisAndNonJointChildren(objects);
00792
00793 for (std::vector<LLViewerObject*>::iterator iter = objects.begin();
00794 iter != objects.end(); ++iter)
00795 {
00796 LLViewerObject* cur_objectp = *iter;
00797 LLSelectNode* nodep = new LLSelectNode(cur_objectp, FALSE);
00798 mHoverObjects->addNodeAtEnd(nodep);
00799 }
00800
00801 requestObjectPropertiesFamily(objectp);
00802 return mHoverObjects;
00803 }
00804
00805 LLSelectNode *LLSelectMgr::getHoverNode()
00806 {
00807 return getHoverObjects()->getFirstRootNode();
00808 }
00809
00810 void LLSelectMgr::highlightObjectOnly(LLViewerObject* objectp)
00811 {
00812 if (!objectp)
00813 {
00814 return;
00815 }
00816
00817 if (objectp->getPCode() != LL_PCODE_VOLUME)
00818 {
00819 return;
00820 }
00821
00822 if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !objectp->permYouOwner()) ||
00823 (gSavedSettings.getBOOL("SelectMovableOnly") && !objectp->permMove()))
00824 {
00825
00826 return;
00827 }
00828
00829 mRectSelectedObjects.insert(objectp);
00830 }
00831
00832 void LLSelectMgr::highlightObjectAndFamily(LLViewerObject* objectp)
00833 {
00834 if (!objectp)
00835 {
00836 return;
00837 }
00838
00839 LLViewerObject* root_obj = (LLViewerObject*)objectp->getRoot();
00840
00841 highlightObjectOnly(root_obj);
00842
00843 for(U32 i = 0; i < root_obj->mChildList.size(); i++)
00844 {
00845 highlightObjectOnly(root_obj->mChildList[i]);
00846 }
00847 }
00848
00849
00850
00851 void LLSelectMgr::highlightObjectAndFamily(const std::vector<LLViewerObject*>& objects)
00852 {
00853 for (std::vector<LLViewerObject*>::const_iterator iter1 = objects.begin();
00854 iter1 != objects.end(); ++iter1)
00855 {
00856 LLViewerObject* object = *iter1;
00857
00858 if (!object)
00859 {
00860 continue;
00861 }
00862 if (object->getPCode() != LL_PCODE_VOLUME)
00863 {
00864 continue;
00865 }
00866
00867 LLViewerObject* root = (LLViewerObject*)object->getRoot();
00868 mRectSelectedObjects.insert(root);
00869
00870 for (LLViewerObject::child_list_t::const_iterator iter2 = root->mChildList.begin();
00871 iter2 != root->mChildList.end(); ++iter2)
00872 {
00873 LLViewerObject* child = *iter2;
00874 mRectSelectedObjects.insert(child);
00875 }
00876 }
00877 }
00878
00879 void LLSelectMgr::unhighlightObjectOnly(LLViewerObject* objectp)
00880 {
00881 if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
00882 {
00883 return;
00884 }
00885
00886 mRectSelectedObjects.erase(objectp);
00887 }
00888
00889 void LLSelectMgr::unhighlightObjectAndFamily(LLViewerObject* objectp)
00890 {
00891 if (!objectp)
00892 {
00893 return;
00894 }
00895
00896 LLViewerObject* root_obj = (LLViewerObject*)objectp->getRoot();
00897
00898 unhighlightObjectOnly(root_obj);
00899
00900 for (LLViewerObject::child_list_t::iterator iter2 = root_obj->mChildList.begin();
00901 iter2 != root_obj->mChildList.end(); ++iter2)
00902 {
00903 LLViewerObject* child = *iter2;
00904 unhighlightObjectOnly(child);
00905 }
00906 }
00907
00908
00909 void LLSelectMgr::unhighlightAll()
00910 {
00911 mRectSelectedObjects.clear();
00912 mHighlightedObjects->deleteAllNodes();
00913 }
00914
00915 LLObjectSelectionHandle LLSelectMgr::selectHighlightedObjects()
00916 {
00917 if (!mHighlightedObjects->getNumNodes())
00918 {
00919 return NULL;
00920 }
00921
00922
00923 mSelectedObjects->mPrimaryObject = NULL;
00924
00925 for (LLObjectSelection::iterator iter = getHighlightedObjects()->begin();
00926 iter != getHighlightedObjects()->end(); )
00927 {
00928 LLObjectSelection::iterator curiter = iter++;
00929
00930 LLSelectNode *nodep = *curiter;
00931 LLViewerObject* objectp = nodep->getObject();
00932
00933 if (!canSelectObject(objectp))
00934 {
00935 continue;
00936 }
00937
00938
00939 if (objectp->isSelected())
00940 {
00941 continue;
00942 }
00943
00944 LLSelectNode* new_nodep = new LLSelectNode(*nodep);
00945 mSelectedObjects->addNode(new_nodep);
00946
00947
00948 objectp->setSelected(TRUE);
00949
00950 mSelectedObjects->mSelectType = getSelectTypeForObject(objectp);
00951
00952
00953 if (objectp->isRootEdit())
00954 {
00955 requestObjectPropertiesFamily(objectp);
00956 }
00957 }
00958
00959
00960 sendSelect();
00961 unhighlightAll();
00962 updateSelectionCenter();
00963 saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
00964 updatePointAt();
00965
00966 if (mSelectedObjects->getObjectCount())
00967 {
00968 gEditMenuHandler = this;
00969 }
00970
00971 return mSelectedObjects;
00972 }
00973
00974 void LLSelectMgr::deselectHighlightedObjects()
00975 {
00976 BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts");
00977 for (std::set<LLPointer<LLViewerObject> >::iterator iter = mRectSelectedObjects.begin();
00978 iter != mRectSelectedObjects.end(); iter++)
00979 {
00980 LLViewerObject *objectp = *iter;
00981 if (!select_linked_set)
00982 {
00983 deselectObjectOnly(objectp);
00984 }
00985 else
00986 {
00987 LLViewerObject* root_object = (LLViewerObject*)objectp->getRoot();
00988 if (root_object->isSelected())
00989 {
00990 deselectObjectAndFamily(root_object);
00991 }
00992 }
00993 }
00994
00995 unhighlightAll();
00996 }
00997
00998 void LLSelectMgr::addGridObject(LLViewerObject* objectp)
00999 {
01000 LLSelectNode* nodep = new LLSelectNode(objectp, FALSE);
01001 mGridObjects.addNodeAtEnd(nodep);
01002
01003 for (LLViewerObject::child_list_t::iterator iter2 = objectp->mChildList.begin();
01004 iter2 != objectp->mChildList.end(); ++iter2)
01005 {
01006 LLViewerObject* child = *iter2;
01007 nodep = new LLSelectNode(child, FALSE);
01008 mGridObjects.addNodeAtEnd(nodep);
01009 }
01010 }
01011
01012 void LLSelectMgr::clearGridObjects()
01013 {
01014 mGridObjects.deleteAllNodes();
01015 }
01016
01017 void LLSelectMgr::setGridMode(EGridMode mode)
01018 {
01019 mGridMode = mode;
01020 gSavedSettings.setS32("GridMode", mode);
01021 updateSelectionCenter();
01022 mGridValid = FALSE;
01023 }
01024
01025 void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &scale)
01026 {
01027 mGridObjects.cleanupNodes();
01028
01029 LLViewerObject* first_grid_object = mGridObjects.getFirstObject();
01030
01031 if (mGridMode == GRID_MODE_LOCAL && mSelectedObjects->getObjectCount())
01032 {
01033 LLBBox bbox = mSavedSelectionBBox;
01034 mGridOrigin = mSavedSelectionBBox.getCenterAgent();
01035 mGridRotation = mSavedSelectionBBox.getRotation();
01036 mGridScale = mSavedSelectionBBox.getExtentLocal() * 0.5f;
01037 }
01038 else if (mGridMode == GRID_MODE_REF_OBJECT && first_grid_object && first_grid_object->mDrawable.notNull())
01039 {
01040 mGridRotation = first_grid_object->getRenderRotation();
01041 LLVector3 first_grid_obj_pos = first_grid_object->getRenderPosition();
01042
01043 LLVector3 min_extents(F32_MAX, F32_MAX, F32_MAX);
01044 LLVector3 max_extents(-F32_MAX, -F32_MAX, -F32_MAX);
01045 BOOL grid_changed = FALSE;
01046 for (LLObjectSelection::iterator iter = mGridObjects.begin();
01047 iter != mGridObjects.end(); ++iter)
01048 {
01049 LLViewerObject* object = (*iter)->getObject();
01050 LLDrawable* drawable = object->mDrawable;
01051 if (drawable)
01052 {
01053 const LLVector3* ext = drawable->getSpatialExtents();
01054 update_min_max(min_extents, max_extents, ext[0]);
01055 update_min_max(min_extents, max_extents, ext[1]);
01056 grid_changed = TRUE;
01057 }
01058 }
01059 if (grid_changed)
01060 {
01061 mGridOrigin = lerp(min_extents, max_extents, 0.5f);
01062 LLDrawable* drawable = first_grid_object->mDrawable;
01063 if (drawable && drawable->isActive())
01064 {
01065 mGridOrigin = mGridOrigin * first_grid_object->getRenderMatrix();
01066 }
01067 mGridScale = (max_extents - min_extents) * 0.5f;
01068 }
01069 }
01070 else
01071 {
01072 const BOOL non_root_ok = TRUE;
01073 LLViewerObject* first_object = mSelectedObjects->getFirstRootObject(non_root_ok);
01074
01075 mGridOrigin.clearVec();
01076 mGridRotation.loadIdentity();
01077
01078 mSelectedObjects->mSelectType = getSelectTypeForObject( first_object );
01079
01080 switch (mSelectedObjects->mSelectType)
01081 {
01082 case SELECT_TYPE_ATTACHMENT:
01083 if (first_object)
01084 {
01085
01086 LLXform* attachment_point_xform = first_object->getRootEdit()->mDrawable->mXform.getParent();
01087 mGridOrigin = attachment_point_xform->getWorldPosition();
01088 mGridRotation = attachment_point_xform->getWorldRotation();
01089 mGridScale = LLVector3(1.f, 1.f, 1.f) * gSavedSettings.getF32("GridResolution");
01090 }
01091 break;
01092 case SELECT_TYPE_HUD:
01093
01094 mGridScale = LLVector3(0.25f, 0.25f, 0.25f);
01095 break;
01096 case SELECT_TYPE_WORLD:
01097 mGridScale = LLVector3(1.f, 1.f, 1.f) * gSavedSettings.getF32("GridResolution");
01098 break;
01099 }
01100 }
01101 llassert(mGridOrigin.isFinite());
01102
01103 origin = mGridOrigin;
01104 rotation = mGridRotation;
01105 scale = mGridScale;
01106 mGridValid = TRUE;
01107 }
01108
01109
01110
01111
01112
01113 void LLSelectMgr::remove(std::vector<LLViewerObject*>& objects)
01114 {
01115 for (std::vector<LLViewerObject*>::iterator iter = objects.begin();
01116 iter != objects.end(); ++iter)
01117 {
01118 LLViewerObject* objectp = *iter;
01119 LLSelectNode* nodep = mSelectedObjects->findNode(objectp);
01120 if (nodep)
01121 {
01122 objectp->setSelected(FALSE);
01123 mSelectedObjects->removeNode(nodep);
01124 nodep = NULL;
01125 }
01126 }
01127 updateSelectionCenter();
01128 dialog_refresh_all();
01129 }
01130
01131
01132
01133
01134
01135 void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable)
01136 {
01137
01138 LLSelectNode *nodep = mSelectedObjects->findNode(objectp);
01139 if (!nodep)
01140 {
01141 return;
01142 }
01143
01144
01145 if ((objectp->getNumTEs() <= 0) || (te == SELECT_ALL_TES))
01146 {
01147
01148 mSelectedObjects->removeNode(nodep);
01149 nodep = NULL;
01150 objectp->setSelected( FALSE );
01151 }
01152 else if (0 <= te && te < SELECT_MAX_TES)
01153 {
01154
01155 if (nodep->isTESelected(te))
01156 {
01157 nodep->selectTE(te, FALSE);
01158 }
01159 else
01160 {
01161 llerrs << "LLSelectMgr::remove - tried to remove TE " << te << " that wasn't selected" << llendl;
01162 return;
01163 }
01164
01165
01166 BOOL found = FALSE;
01167 for (S32 i = 0; i < nodep->getObject()->getNumTEs(); i++)
01168 {
01169 found = found || nodep->isTESelected(i);
01170 }
01171
01172
01173 if (!found)
01174 {
01175 mSelectedObjects->removeNode(nodep);
01176 nodep = NULL;
01177 objectp->setSelected( FALSE );
01178
01179 }
01180 }
01181 else
01182 {
01183
01184 llerrs << "LLSelectMgr::remove - TE " << te << " out of range" << llendl;
01185 }
01186
01187 updateSelectionCenter();
01188 dialog_refresh_all();
01189 }
01190
01191
01192
01193
01194
01195 void LLSelectMgr::removeAll()
01196 {
01197 for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
01198 iter != mSelectedObjects->end(); iter++ )
01199 {
01200 LLViewerObject *objectp = (*iter)->getObject();
01201 objectp->setSelected( FALSE );
01202 }
01203
01204 mSelectedObjects->deleteAllNodes();
01205
01206 updateSelectionCenter();
01207 dialog_refresh_all();
01208 }
01209
01210
01211
01212
01213 void LLSelectMgr::promoteSelectionToRoot()
01214 {
01215 std::set<LLViewerObject*> selection_set;
01216
01217 BOOL selection_changed = FALSE;
01218
01219 for (LLObjectSelection::iterator iter = getSelection()->begin();
01220 iter != getSelection()->end(); )
01221 {
01222 LLObjectSelection::iterator curiter = iter++;
01223 LLSelectNode* nodep = *curiter;
01224 LLViewerObject* object = nodep->getObject();
01225
01226 if (nodep->mIndividualSelection)
01227 {
01228 selection_changed = TRUE;
01229 }
01230
01231 LLViewerObject* parentp = object;
01232 while(parentp->getParent() && !(parentp->isRootEdit() || parentp->isJointChild()))
01233 {
01234 parentp = (LLViewerObject*)parentp->getParent();
01235 }
01236
01237 selection_set.insert(parentp);
01238 }
01239
01240 if (selection_changed)
01241 {
01242 deselectAll();
01243
01244 std::set<LLViewerObject*>::iterator set_iter;
01245 for (set_iter = selection_set.begin(); set_iter != selection_set.end(); ++set_iter)
01246 {
01247 selectObjectAndFamily(*set_iter);
01248 }
01249 }
01250 }
01251
01252
01253
01254
01255 void LLSelectMgr::demoteSelectionToIndividuals()
01256 {
01257 LLDynamicArray<LLViewerObject*> objects;
01258
01259 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
01260 iter != getSelection()->root_end(); iter++)
01261 {
01262 LLViewerObject* object = (*iter)->getObject();
01263 object->addThisAndNonJointChildren(objects);
01264 }
01265
01266 if (objects.getLength())
01267 {
01268 deselectAll();
01269 for (std::vector<LLViewerObject*>::iterator iter = objects.begin();
01270 iter != objects.end(); ++iter)
01271 {
01272 LLViewerObject* objectp = *iter;
01273 selectObjectOnly(objectp);
01274 }
01275 }
01276 }
01277
01278
01279
01280
01281 void LLSelectMgr::dump()
01282 {
01283 llinfos << "Selection Manager: " << mSelectedObjects->getNumNodes() << " items" << llendl;
01284
01285 llinfos << "TE mode " << mTEMode << llendl;
01286
01287 S32 count = 0;
01288 for (LLObjectSelection::iterator iter = getSelection()->begin();
01289 iter != getSelection()->end(); iter++ )
01290 {
01291 LLViewerObject* objectp = (*iter)->getObject();
01292 llinfos << "Object " << count << " type " << LLPrimitive::pCodeToString(objectp->getPCode()) << llendl;
01293 llinfos << " hasLSL " << objectp->flagScripted() << llendl;
01294 llinfos << " hasTouch " << objectp->flagHandleTouch() << llendl;
01295 llinfos << " hasMoney " << objectp->flagTakesMoney() << llendl;
01296 llinfos << " getposition " << objectp->getPosition() << llendl;
01297 llinfos << " getpositionAgent " << objectp->getPositionAgent() << llendl;
01298 llinfos << " getpositionRegion " << objectp->getPositionRegion() << llendl;
01299 llinfos << " getpositionGlobal " << objectp->getPositionGlobal() << llendl;
01300 LLDrawable* drawablep = objectp->mDrawable;
01301 llinfos << " " << (drawablep&& drawablep->isVisible() ? "visible" : "invisible") << llendl;
01302 llinfos << " " << (drawablep&& drawablep->isState(LLDrawable::FORCE_INVISIBLE) ? "force_invisible" : "") << llendl;
01303 count++;
01304 }
01305
01306
01307 for (LLObjectSelection::iterator iter = getSelection()->begin();
01308 iter != getSelection()->end(); iter++ )
01309 {
01310 LLSelectNode* node = *iter;
01311 LLViewerObject* objectp = node->getObject();
01312 for (S32 te = 0; te < objectp->getNumTEs(); ++te )
01313 {
01314 if (node->isTESelected(te))
01315 {
01316 llinfos << "Object " << objectp << " te " << te << llendl;
01317 }
01318 }
01319 }
01320
01321 llinfos << mHighlightedObjects->getNumNodes() << " objects currently highlighted." << llendl;
01322
01323 llinfos << "Center global " << mSelectionCenterGlobal << llendl;
01324 }
01325
01326
01327
01328
01329 void LLSelectMgr::cleanup()
01330 {
01331 mSilhouetteImagep = NULL;
01332 }
01333
01334
01335
01336
01337
01338
01339 struct LLSelectMgrSendFunctor : public LLSelectedObjectFunctor
01340 {
01341 virtual bool apply(LLViewerObject* object)
01342 {
01343 if (object->permModify())
01344 {
01345 object->sendTEUpdate();
01346 }
01347 return true;
01348 }
01349 };
01350
01351
01352
01353
01354
01355 void LLSelectMgr::selectionSetImage(const LLUUID& imageid)
01356 {
01357
01358 LLViewerInventoryItem* item = gInventory.getItem(imageid);
01359 if(item
01360 && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())
01361 && (mSelectedObjects->getNumNodes() > 1) )
01362 {
01363 llwarns << "Attempted to apply no-copy texture to multiple objects"
01364 << llendl;
01365 return;
01366 }
01367
01368 struct f : public LLSelectedTEFunctor
01369 {
01370 LLViewerInventoryItem* mItem;
01371 LLUUID mImageID;
01372 f(LLViewerInventoryItem* item, const LLUUID& id) : mItem(item), mImageID(id) {}
01373 bool apply(LLViewerObject* objectp, S32 te)
01374 {
01375 if (mItem)
01376 {
01377 if (te == -1)
01378 {
01379 LLToolDragAndDrop::dropTextureAllFaces(objectp,
01380 mItem,
01381 LLToolDragAndDrop::SOURCE_AGENT,
01382 LLUUID::null);
01383 }
01384 else
01385 {
01386 LLToolDragAndDrop::dropTextureOneFace(objectp,
01387 te,
01388 mItem,
01389 LLToolDragAndDrop::SOURCE_AGENT,
01390 LLUUID::null);
01391 }
01392 }
01393 else
01394 {
01395
01396
01397
01398 objectp->setTEImage(te, gImageList.getImage(mImageID, TRUE, FALSE));
01399 }
01400 return true;
01401 }
01402 } setfunc(item, imageid);
01403 getSelection()->applyToTEs(&setfunc);
01404
01405 struct g : public LLSelectedObjectFunctor
01406 {
01407 LLViewerInventoryItem* mItem;
01408 g(LLViewerInventoryItem* item) : mItem(item) {}
01409 virtual bool apply(LLViewerObject* object)
01410 {
01411 if (!mItem)
01412 {
01413 object->sendTEUpdate();
01414
01415 LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)gHUDManager->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
01416 effectp->setSourceObject(gAgent.getAvatarObject());
01417 effectp->setTargetObject(object);
01418 effectp->setDuration(LL_HUD_DUR_SHORT);
01419 effectp->setColor(LLColor4U(gAgent.getEffectColor()));
01420 }
01421 return true;
01422 }
01423 } sendfunc(item);
01424 getSelection()->applyToObjects(&sendfunc);
01425 }
01426
01427
01428
01429
01430 void LLSelectMgr::selectionSetColor(const LLColor4 &color)
01431 {
01432 struct f : public LLSelectedTEFunctor
01433 {
01434 LLColor4 mColor;
01435 f(const LLColor4& c) : mColor(c) {}
01436 bool apply(LLViewerObject* object, S32 te)
01437 {
01438 if (object->permModify())
01439 {
01440 object->setTEColor(te, mColor);
01441 }
01442 return true;
01443 }
01444 } setfunc(color);
01445 getSelection()->applyToTEs(&setfunc);
01446
01447 LLSelectMgrSendFunctor sendfunc;
01448 getSelection()->applyToObjects(&sendfunc);
01449 }
01450
01451
01452
01453
01454 void LLSelectMgr::selectionSetColorOnly(const LLColor4 &color)
01455 {
01456 struct f : public LLSelectedTEFunctor
01457 {
01458 LLColor4 mColor;
01459 f(const LLColor4& c) : mColor(c) {}
01460 bool apply(LLViewerObject* object, S32 te)
01461 {
01462 if (object->permModify())
01463 {
01464 LLColor4 prev_color = object->getTE(te)->getColor();
01465 mColor.mV[VALPHA] = prev_color.mV[VALPHA];
01466
01467 object->setTEColor(te, mColor);
01468 }
01469 return true;
01470 }
01471 } setfunc(color);
01472 getSelection()->applyToTEs(&setfunc);
01473
01474 LLSelectMgrSendFunctor sendfunc;
01475 getSelection()->applyToObjects(&sendfunc);
01476 }
01477
01478
01479
01480
01481 void LLSelectMgr::selectionSetAlphaOnly(const F32 alpha)
01482 {
01483 struct f : public LLSelectedTEFunctor
01484 {
01485 F32 mAlpha;
01486 f(const F32& a) : mAlpha(a) {}
01487 bool apply(LLViewerObject* object, S32 te)
01488 {
01489 if (object->permModify())
01490 {
01491 LLColor4 prev_color = object->getTE(te)->getColor();
01492 prev_color.mV[VALPHA] = mAlpha;
01493
01494 object->setTEColor(te, prev_color);
01495 }
01496 return true;
01497 }
01498 } setfunc(alpha);
01499 getSelection()->applyToTEs(&setfunc);
01500
01501 LLSelectMgrSendFunctor sendfunc;
01502 getSelection()->applyToObjects(&sendfunc);
01503 }
01504
01505 void LLSelectMgr::selectionRevertColors()
01506 {
01507 struct f : public LLSelectedTEFunctor
01508 {
01509 LLObjectSelectionHandle mSelectedObjects;
01510 f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {}
01511 bool apply(LLViewerObject* object, S32 te)
01512 {
01513 if (object->permModify())
01514 {
01515 LLSelectNode* nodep = mSelectedObjects->findNode(object);
01516 if (nodep && te < (S32)nodep->mSavedColors.size())
01517 {
01518 LLColor4 color = nodep->mSavedColors[te];
01519
01520 object->setTEColor(te, color);
01521 }
01522 }
01523 return true;
01524 }
01525 } setfunc(mSelectedObjects);
01526 getSelection()->applyToTEs(&setfunc);
01527
01528 LLSelectMgrSendFunctor sendfunc;
01529 getSelection()->applyToObjects(&sendfunc);
01530 }
01531
01532 BOOL LLSelectMgr::selectionRevertTextures()
01533 {
01534 struct f : public LLSelectedTEFunctor
01535 {
01536 LLObjectSelectionHandle mSelectedObjects;
01537 f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {}
01538 bool apply(LLViewerObject* object, S32 te)
01539 {
01540 if (object->permModify())
01541 {
01542 LLSelectNode* nodep = mSelectedObjects->findNode(object);
01543 if (nodep && te < (S32)nodep->mSavedTextures.size())
01544 {
01545 LLUUID id = nodep->mSavedTextures[te];
01546
01547 if (id.isNull())
01548 {
01549
01550 return FALSE;
01551 }
01552 else
01553 {
01554 object->setTEImage(te, gImageList.getImage(id));
01555 }
01556 }
01557 }
01558 return true;
01559 }
01560 } setfunc(mSelectedObjects);
01561 BOOL revert_successful = getSelection()->applyToTEs(&setfunc);
01562
01563 LLSelectMgrSendFunctor sendfunc;
01564 getSelection()->applyToObjects(&sendfunc);
01565
01566 return revert_successful;
01567 }
01568
01569 void LLSelectMgr::selectionSetBumpmap(U8 bumpmap)
01570 {
01571 struct f : public LLSelectedTEFunctor
01572 {
01573 U8 mBump;
01574 f(const U8& b) : mBump(b) {}
01575 bool apply(LLViewerObject* object, S32 te)
01576 {
01577 if (object->permModify())
01578 {
01579
01580 object->setTEBumpmap(te, mBump);
01581 }
01582 return true;
01583 }
01584 } setfunc(bumpmap);
01585 getSelection()->applyToTEs(&setfunc);
01586
01587 LLSelectMgrSendFunctor sendfunc;
01588 getSelection()->applyToObjects(&sendfunc);
01589 }
01590
01591 void LLSelectMgr::selectionSetTexGen(U8 texgen)
01592 {
01593 struct f : public LLSelectedTEFunctor
01594 {
01595 U8 mTexgen;
01596 f(const U8& t) : mTexgen(t) {}
01597 bool apply(LLViewerObject* object, S32 te)
01598 {
01599 if (object->permModify())
01600 {
01601
01602 object->setTETexGen(te, mTexgen);
01603 }
01604 return true;
01605 }
01606 } setfunc(texgen);
01607 getSelection()->applyToTEs(&setfunc);
01608
01609 LLSelectMgrSendFunctor sendfunc;
01610 getSelection()->applyToObjects(&sendfunc);
01611 }
01612
01613
01614 void LLSelectMgr::selectionSetShiny(U8 shiny)
01615 {
01616 struct f : public LLSelectedTEFunctor
01617 {
01618 U8 mShiny;
01619 f(const U8& t) : mShiny(t) {}
01620 bool apply(LLViewerObject* object, S32 te)
01621 {
01622 if (object->permModify())
01623 {
01624
01625 object->setTEShiny(te, mShiny);
01626 }
01627 return true;
01628 }
01629 } setfunc(shiny);
01630 getSelection()->applyToTEs(&setfunc);
01631
01632 LLSelectMgrSendFunctor sendfunc;
01633 getSelection()->applyToObjects(&sendfunc);
01634 }
01635
01636 void LLSelectMgr::selectionSetFullbright(U8 fullbright)
01637 {
01638 struct f : public LLSelectedTEFunctor
01639 {
01640 U8 mFullbright;
01641 f(const U8& t) : mFullbright(t) {}
01642 bool apply(LLViewerObject* object, S32 te)
01643 {
01644 if (object->permModify())
01645 {
01646
01647 object->setTEFullbright(te, mFullbright);
01648 }
01649 return true;
01650 }
01651 } setfunc(fullbright);
01652 getSelection()->applyToTEs(&setfunc);
01653
01654 struct g : public LLSelectedObjectFunctor
01655 {
01656 U8 mFullbright;
01657 g(const U8& t) : mFullbright(t) {}
01658 virtual bool apply(LLViewerObject* object)
01659 {
01660 if (object->permModify())
01661 {
01662 object->sendTEUpdate();
01663 if (mFullbright)
01664 {
01665 U8 material = object->getMaterial();
01666 U8 mcode = material & LL_MCODE_MASK;
01667 if (mcode == LL_MCODE_LIGHT)
01668 {
01669 mcode = LL_MCODE_GLASS;
01670 material = (material & ~LL_MCODE_MASK) | mcode;
01671 object->setMaterial(material);
01672 object->sendMaterialUpdate();
01673 }
01674 }
01675 }
01676 return true;
01677 }
01678 } sendfunc(fullbright);
01679 getSelection()->applyToObjects(&sendfunc);
01680 }
01681
01682 void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string& media_url)
01683 {
01684 U8 media_flags = LLTextureEntry::MF_NONE;
01685 if (media_type == LLViewerObject::MEDIA_TYPE_WEB_PAGE)
01686 {
01687 media_flags = LLTextureEntry::MF_WEB_PAGE;
01688 }
01689
01690 struct f : public LLSelectedTEFunctor
01691 {
01692 U8 mMediaFlags;
01693 f(const U8& t) : mMediaFlags(t) {}
01694 bool apply(LLViewerObject* object, S32 te)
01695 {
01696 if (object->permModify())
01697 {
01698
01699 object->setTEMediaFlags(te, mMediaFlags);
01700 }
01701 return true;
01702 }
01703 } setfunc(media_flags);
01704 getSelection()->applyToTEs(&setfunc);
01705
01706 struct g : public LLSelectedObjectFunctor
01707 {
01708 U8 media_type;
01709 const std::string& media_url ;
01710 g(U8 a, const std::string& b) : media_type(a), media_url(b) {}
01711 virtual bool apply(LLViewerObject* object)
01712 {
01713 if (object->permModify())
01714 {
01715 object->sendTEUpdate();
01716 object->setMediaType(media_type);
01717 object->setMediaURL(media_url);
01718 }
01719 return true;
01720 }
01721 } sendfunc(media_type, media_url);
01722 getSelection()->applyToObjects(&sendfunc);
01723 }
01724
01725
01726
01727
01728
01729
01730 LLPermissions* LLSelectMgr::findObjectPermissions(const LLViewerObject* object)
01731 {
01732 for (LLObjectSelection::valid_iterator iter = getSelection()->valid_begin();
01733 iter != getSelection()->valid_end(); iter++ )
01734 {
01735 LLSelectNode* nodep = *iter;
01736 if (nodep->getObject() == object)
01737 {
01738 return nodep->mPermissions;
01739 }
01740 }
01741
01742 return NULL;
01743 }
01744
01745
01746
01747
01748
01749 void LLSelectMgr::selectionSetMaterial(U8 material)
01750 {
01751 struct f : public LLSelectedObjectFunctor
01752 {
01753 U8 mMaterial;
01754 f(const U8& t) : mMaterial(t) {}
01755 virtual bool apply(LLViewerObject* object)
01756 {
01757 if (object->permModify())
01758 {
01759 U8 cur_material = object->getMaterial();
01760 U8 material = mMaterial | (cur_material & ~LL_MCODE_MASK);
01761 object->setMaterial(material);
01762 object->sendMaterialUpdate();
01763 }
01764 return true;
01765 }
01766 } sendfunc(material);
01767 getSelection()->applyToObjects(&sendfunc);
01768 }
01769
01770
01771 BOOL LLSelectMgr::selectionAllPCode(LLPCode code)
01772 {
01773 struct f : public LLSelectedObjectFunctor
01774 {
01775 LLPCode mCode;
01776 f(const LLPCode& t) : mCode(t) {}
01777 virtual bool apply(LLViewerObject* object)
01778 {
01779 if (object->getPCode() != mCode)
01780 {
01781 return FALSE;
01782 }
01783 return true;
01784 }
01785 } func(code);
01786 BOOL res = getSelection()->applyToObjects(&func);
01787 return res;
01788 }
01789
01790 bool LLSelectMgr::selectionGetIncludeInSearch(bool* include_in_search_out)
01791 {
01792 LLViewerObject *object = mSelectedObjects->getFirstRootObject();
01793 if (!object) return FALSE;
01794
01795 bool include_in_search = object->getIncludeInSearch();
01796
01797 bool identical = true;
01798
01799 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
01800 iter != getSelection()->root_end(); iter++)
01801 {
01802 LLViewerObject* object = (*iter)->getObject();
01803
01804 if ( include_in_search != object->getIncludeInSearch())
01805 {
01806 identical = false;
01807 break;
01808 }
01809 }
01810
01811 *include_in_search_out = include_in_search;
01812 return identical;
01813 }
01814
01815 void LLSelectMgr::selectionSetIncludeInSearch(bool include_in_search)
01816 {
01817 LLViewerObject* object = NULL;
01818 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
01819 iter != getSelection()->root_end(); iter++)
01820 {
01821 object = (*iter)->getObject();
01822 object->setIncludeInSearch(include_in_search);
01823 }
01824 sendListToRegions(
01825 "ObjectIncludeInSearch",
01826 packAgentAndSessionID,
01827 packObjectIncludeInSearch,
01828 &include_in_search,
01829 SEND_ONLY_ROOTS);
01830 }
01831
01832 BOOL LLSelectMgr::selectionGetClickAction(U8 *out_action)
01833 {
01834 LLViewerObject *object = mSelectedObjects->getFirstObject();
01835 if (!object)
01836 {
01837 return FALSE;
01838 }
01839
01840 U8 action = object->getClickAction();
01841 *out_action = action;
01842
01843 struct f : public LLSelectedObjectFunctor
01844 {
01845 U8 mAction;
01846 f(const U8& t) : mAction(t) {}
01847 virtual bool apply(LLViewerObject* object)
01848 {
01849 if ( mAction != object->getClickAction())
01850 {
01851 return false;
01852 }
01853 return true;
01854 }
01855 } func(action);
01856 BOOL res = getSelection()->applyToObjects(&func);
01857 return res;
01858 }
01859
01860 void LLSelectMgr::selectionSetClickAction(U8 action)
01861 {
01862 struct f : public LLSelectedObjectFunctor
01863 {
01864 U8 mAction;
01865 f(const U8& t) : mAction(t) {}
01866 virtual bool apply(LLViewerObject* object)
01867 {
01868 object->setClickAction(mAction);
01869 return true;
01870 }
01871 } func(action);
01872 getSelection()->applyToObjects(&func);
01873
01874 sendListToRegions("ObjectClickAction",
01875 packAgentAndSessionID,
01876 packObjectClickAction,
01877 &action,
01878 SEND_INDIVIDUALS);
01879 }
01880
01881
01882
01883
01884
01885
01886 typedef std::pair<const LLString, const LLString> godlike_request_t;
01887 void LLSelectMgr::sendGodlikeRequest(const LLString& request, const LLString& param)
01888 {
01889
01890
01891 LLString message_type;
01892 if (gAgent.isGodlike())
01893 {
01894 message_type = "GodlikeMessage";
01895 }
01896 else
01897 {
01898 message_type = "EstateOwnerMessage";
01899 }
01900
01901 godlike_request_t data(request, param);
01902 if(!mSelectedObjects->getRootObjectCount())
01903 {
01904 LLMessageSystem* msg = gMessageSystem;
01905 msg->newMessage(message_type.c_str());
01906 LLSelectMgr::packGodlikeHead(&data);
01907 gAgent.sendReliableMessage();
01908 }
01909 else
01910 {
01911 sendListToRegions(message_type, packGodlikeHead, packObjectIDAsParam, &data, SEND_ONLY_ROOTS);
01912 }
01913 }
01914
01915 void LLSelectMgr::packGodlikeHead(void* user_data)
01916 {
01917 LLMessageSystem* msg = gMessageSystem;
01918 msg->nextBlockFast(_PREHASH_AgentData);
01919 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
01920 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
01921 msg->addUUID("TransactionID", LLUUID::null);
01922 godlike_request_t* data = (godlike_request_t*)user_data;
01923 msg->nextBlock("MethodData");
01924 msg->addString("Method", data->first.c_str());
01925 msg->addUUID("Invoice", LLUUID::null);
01926
01927
01928
01929
01930
01931
01932 if(data->second.size() > 0)
01933 {
01934 msg->nextBlock("ParamList");
01935 msg->addString("Parameter", data->second);
01936 }
01937 }
01938
01939
01940 void LLSelectMgr::packObjectIDAsParam(LLSelectNode* node, void *)
01941 {
01942 char buf [MAX_STRING];
01943 snprintf(buf, MAX_STRING, "%u", node->getObject()->getLocalID());
01944 gMessageSystem->nextBlock("ParamList");
01945 gMessageSystem->addString("Parameter", buf);
01946 }
01947
01948
01949
01950
01951 void LLSelectMgr::selectionResetRotation()
01952 {
01953 struct f : public LLSelectedObjectFunctor
01954 {
01955 virtual bool apply(LLViewerObject* object)
01956 {
01957 LLQuaternion identity(0.f, 0.f, 0.f, 1.f);
01958 object->setRotation(identity);
01959 if (object->mDrawable.notNull())
01960 {
01961 gPipeline.markMoved(object->mDrawable, TRUE);
01962 }
01963 object->sendRotationUpdate();
01964 return true;
01965 }
01966 } func;
01967 getSelection()->applyToRootObjects(&func);
01968 }
01969
01970 void LLSelectMgr::selectionRotateAroundZ(F32 degrees)
01971 {
01972 LLQuaternion rot( degrees * DEG_TO_RAD, LLVector3(0,0,1) );
01973 struct f : public LLSelectedObjectFunctor
01974 {
01975 LLQuaternion mRot;
01976 f(const LLQuaternion& rot) : mRot(rot) {}
01977 virtual bool apply(LLViewerObject* object)
01978 {
01979 object->setRotation( object->getRotationEdit() * mRot );
01980 if (object->mDrawable.notNull())
01981 {
01982 gPipeline.markMoved(object->mDrawable, TRUE);
01983 }
01984 object->sendRotationUpdate();
01985 return true;
01986 }
01987 } func(rot);
01988 getSelection()->applyToRootObjects(&func);
01989 }
01990
01991
01992
01993
01994
01995 void LLSelectMgr::selectionTexScaleAutofit(F32 repeats_per_meter)
01996 {
01997 struct f : public LLSelectedTEFunctor
01998 {
01999 F32 mRepeatsPerMeter;
02000 f(const F32& t) : mRepeatsPerMeter(t) {}
02001 bool apply(LLViewerObject* object, S32 te)
02002 {
02003
02004 if (object->permModify())
02005 {
02006
02007 U32 s_axis, t_axis;
02008 if (!LLPrimitive::getTESTAxes(te, &s_axis, &t_axis))
02009 {
02010 return TRUE;
02011 }
02012
02013 F32 new_s = object->getScale().mV[s_axis] * mRepeatsPerMeter;
02014 F32 new_t = object->getScale().mV[t_axis] * mRepeatsPerMeter;
02015
02016 object->setTEScale(te, new_s, new_t);
02017 }
02018 return true;
02019 }
02020 } setfunc(repeats_per_meter);
02021 getSelection()->applyToTEs(&setfunc);
02022
02023 LLSelectMgrSendFunctor sendfunc;
02024 getSelection()->applyToObjects(&sendfunc);
02025 }
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035 void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch)
02036 {
02037 for (LLObjectSelection::iterator iter = getSelection()->begin();
02038 iter != getSelection()->end(); iter++)
02039 {
02040 LLSelectNode* selectNode = *iter;
02041 LLViewerObject* object = selectNode->getObject();
02042
02043 if (!object->permModify())
02044 {
02045 continue;
02046 }
02047
02048 if (object->getNumTEs() == 0)
02049 {
02050 continue;
02051 }
02052
02053 BOOL send = FALSE;
02054
02055 for (U8 te_num = 0; te_num < object->getNumTEs(); te_num++)
02056 {
02057 const LLTextureEntry* tep = object->getTE(te_num);
02058
02059 BOOL planar = tep->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR;
02060 if (planar == stretch)
02061 {
02062
02063 U32 s_axis, t_axis;
02064 if (!LLPrimitive::getTESTAxes(te_num, &s_axis, &t_axis))
02065 {
02066 continue;
02067 }
02068
02069 LLVector3 scale_ratio = selectNode->mTextureScaleRatios[te_num];
02070 LLVector3 object_scale = object->getScale();
02071
02072
02073 if (planar)
02074 {
02075 object->setTEScale(te_num, 1.f/object_scale.mV[s_axis]*scale_ratio.mV[s_axis],
02076 1.f/object_scale.mV[t_axis]*scale_ratio.mV[t_axis]);
02077 }
02078 else
02079 {
02080 object->setTEScale(te_num, scale_ratio.mV[s_axis]*object_scale.mV[s_axis],
02081 scale_ratio.mV[t_axis]*object_scale.mV[t_axis]);
02082 }
02083 send = send_to_sim;
02084 }
02085 }
02086
02087 if (send)
02088 {
02089 object->sendTEUpdate();
02090 }
02091 }
02092 }
02093
02094
02095
02096
02097
02098 BOOL LLSelectMgr::selectGetAllRootsValid()
02099 {
02100 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
02101 iter != getSelection()->root_end(); ++iter )
02102 {
02103 LLSelectNode* node = *iter;
02104 if( !node->mValid )
02105 {
02106 return FALSE;
02107 }
02108 }
02109 return TRUE;
02110 }
02111
02112
02113
02114
02115
02116
02117 BOOL LLSelectMgr::selectGetAllValid()
02118 {
02119 for (LLObjectSelection::iterator iter = getSelection()->begin();
02120 iter != getSelection()->end(); ++iter )
02121 {
02122 LLSelectNode* node = *iter;
02123 if( !node->mValid )
02124 {
02125 return FALSE;
02126 }
02127 }
02128 return TRUE;
02129 }
02130
02131
02132
02133
02134
02135
02136 BOOL LLSelectMgr::selectGetModify()
02137 {
02138 for (LLObjectSelection::iterator iter = getSelection()->begin();
02139 iter != getSelection()->end(); iter++ )
02140 {
02141 LLSelectNode* node = *iter;
02142 LLViewerObject* object = node->getObject();
02143 if( !node->mValid )
02144 {
02145 return FALSE;
02146 }
02147 if( !object->permModify() )
02148 {
02149 return FALSE;
02150 }
02151 }
02152 return TRUE;
02153 }
02154
02155
02156
02157
02158
02159 BOOL LLSelectMgr::selectGetRootsModify()
02160 {
02161 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
02162 iter != getSelection()->root_end(); iter++ )
02163 {
02164 LLSelectNode* node = *iter;
02165 LLViewerObject* object = node->getObject();
02166 if( !node->mValid )
02167 {
02168 return FALSE;
02169 }
02170 if( !object->permModify() )
02171 {
02172 return FALSE;
02173 }
02174 }
02175
02176 return TRUE;
02177 }
02178
02179
02180
02181
02182
02183
02184 BOOL LLSelectMgr::selectGetRootsTransfer()
02185 {
02186 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
02187 iter != getSelection()->root_end(); iter++ )
02188 {
02189 LLSelectNode* node = *iter;
02190 LLViewerObject* object = node->getObject();
02191 if( !node->mValid )
02192 {
02193 return FALSE;
02194 }
02195 if(!object->permTransfer())
02196 {
02197 return FALSE;
02198 }
02199 }
02200 return TRUE;
02201 }
02202
02203
02204
02205
02206
02207 BOOL LLSelectMgr::selectGetRootsCopy()
02208 {
02209 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
02210 iter != getSelection()->root_end(); iter++ )
02211 {
02212 LLSelectNode* node = *iter;
02213 LLViewerObject* object = node->getObject();
02214 if( !node->mValid )
02215 {
02216 return FALSE;
02217 }
02218 if(!object->permCopy())
02219 {
02220 return FALSE;
02221 }
02222 }
02223 return TRUE;
02224 }
02225
02226
02227
02228
02229
02230 BOOL LLSelectMgr::selectGetCreator(LLUUID& result_id, LLString& name)
02231 {
02232 BOOL identical = TRUE;
02233 BOOL first = TRUE;
02234 LLUUID first_id;
02235 for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin();
02236 iter != getSelection()->root_object_end(); iter++ )
02237 {
02238 LLSelectNode* node = *iter;
02239 if (!node->mValid)
02240 {
02241 return FALSE;
02242 }
02243
02244 if (first)
02245 {
02246 first_id = node->mPermissions->getCreator();
02247 first = FALSE;
02248 }
02249 else
02250 {
02251 if ( !(first_id == node->mPermissions->getCreator() ) )
02252 {
02253 identical = FALSE;
02254 break;
02255 }
02256 }
02257 }
02258 if (first_id.isNull())
02259 {
02260 return FALSE;
02261 }
02262
02263 result_id = first_id;
02264
02265 if (identical)
02266 {
02267 char firstname[DB_FIRST_NAME_BUF_SIZE];
02268 char lastname[DB_LAST_NAME_BUF_SIZE];
02269 gCacheName->getName(first_id, firstname, lastname);
02270 name.assign( firstname );
02271 name.append( " " );
02272 name.append( lastname );
02273 }
02274 else
02275 {
02276 name.assign( "(multiple)" );
02277 }
02278
02279 return identical;
02280 }
02281
02282
02283
02284
02285
02286
02287 BOOL LLSelectMgr::selectGetOwner(LLUUID& result_id, LLString& name)
02288 {
02289 BOOL identical = TRUE;
02290 BOOL first = TRUE;
02291 BOOL first_group_owned = FALSE;
02292 LLUUID first_id;
02293 for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin();
02294 iter != getSelection()->root_object_end(); iter++ )
02295 {
02296 LLSelectNode* node = *iter;
02297 if (!node->mValid)
02298 {
02299 return FALSE;
02300 }
02301
02302 if (first)
02303 {
02304 node->mPermissions->getOwnership(first_id, first_group_owned);
02305 first = FALSE;
02306 }
02307 else
02308 {
02309 LLUUID owner_id;
02310 BOOL is_group_owned = FALSE;
02311 if (!(node->mPermissions->getOwnership(owner_id, is_group_owned))
02312 || owner_id != first_id || is_group_owned != first_group_owned)
02313 {
02314 identical = FALSE;
02315 break;
02316 }
02317 }
02318 }
02319 if (first_id.isNull())
02320 {
02321 return FALSE;
02322 }
02323
02324 result_id = first_id;
02325
02326 if (identical)
02327 {
02328 BOOL public_owner = (first_id.isNull() && !first_group_owned);
02329 if (first_group_owned)
02330 {
02331 name.assign( "(Group Owned)");
02332 }
02333 else if(!public_owner)
02334 {
02335 char firstname[DB_FIRST_NAME_BUF_SIZE];
02336 char lastname[DB_LAST_NAME_BUF_SIZE];
02337 gCacheName->getName(first_id, firstname, lastname);
02338 name.assign( firstname );
02339 name.append( " " );
02340 name.append( lastname );
02341 }
02342 else
02343 {
02344 name.assign("Public");
02345 }
02346 }
02347 else
02348 {
02349 name.assign( "(multiple)" );
02350 }
02351
02352 return identical;
02353 }
02354
02355
02356
02357
02358
02359
02360 BOOL LLSelectMgr::selectGetLastOwner(LLUUID& result_id, LLString& name)
02361 {
02362 BOOL identical = TRUE;
02363 BOOL first = TRUE;
02364 LLUUID first_id;
02365 for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin();
02366 iter != getSelection()->root_object_end(); iter++ )
02367 {
02368 LLSelectNode* node = *iter;
02369 if (!node->mValid)
02370 {
02371 return FALSE;
02372 }
02373
02374 if (first)
02375 {
02376 first_id = node->mPermissions->getLastOwner();
02377 first = FALSE;
02378 }
02379 else
02380 {
02381 if ( !(first_id == node->mPermissions->getLastOwner() ) )
02382 {
02383 identical = FALSE;
02384 break;
02385 }
02386 }
02387 }
02388 if (first_id.isNull())
02389 {
02390 return FALSE;
02391 }
02392
02393 result_id = first_id;
02394
02395 if (identical)
02396 {
02397 BOOL public_owner = (first_id.isNull());
02398 if(!public_owner)
02399 {
02400 char firstname[DB_FIRST_NAME_BUF_SIZE];
02401 char lastname[DB_LAST_NAME_BUF_SIZE];
02402 gCacheName->getName(first_id, firstname, lastname);
02403 name.assign( firstname );
02404 name.append( " " );
02405 name.append( lastname );
02406 }
02407 else
02408 {
02409 name.assign("Public or Group");
02410 }
02411 }
02412 else
02413 {
02414 name.assign( "" );
02415 }
02416
02417 return identical;
02418 }
02419
02420
02421
02422
02423
02424
02425 BOOL LLSelectMgr::selectGetGroup(LLUUID& result_id)
02426 {
02427 BOOL identical = TRUE;
02428 BOOL first = TRUE;
02429 LLUUID first_id;
02430 for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin();
02431 iter != getSelection()->root_object_end(); iter++ )
02432 {
02433 LLSelectNode* node = *iter;
02434 if (!node->mValid)
02435 {
02436 return FALSE;
02437 }
02438
02439 if (first)
02440 {
02441 first_id = node->mPermissions->getGroup();
02442 first = FALSE;
02443 }
02444 else
02445 {
02446 if ( !(first_id == node->mPermissions->getGroup() ) )
02447 {
02448 identical = FALSE;
02449 break;
02450 }
02451 }
02452 }
02453 if (first_id.isNull())
02454 {
02455 return FALSE;
02456 }
02457
02458 result_id = first_id;
02459
02460 return identical;
02461 }
02462
02463
02464
02465
02466
02467
02468 BOOL LLSelectMgr::selectIsGroupOwned()
02469 {
02470 BOOL found_one = FALSE;
02471 for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin();
02472 iter != getSelection()->root_object_end(); iter++ )
02473 {
02474 LLSelectNode* node = *iter;
02475 if (!node->mValid)
02476 {
02477 return FALSE;
02478 }
02479 found_one = TRUE;
02480 if (!node->mPermissions->isGroupOwned())
02481 {
02482 return FALSE;
02483 }
02484 }
02485 return found_one ? TRUE : FALSE;
02486 }
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497 BOOL LLSelectMgr::selectGetPerm(U8 which_perm, U32* mask_on, U32* mask_off)
02498 {
02499 U32 mask;
02500 U32 mask_and = 0xffffffff;
02501 U32 mask_or = 0x00000000;
02502 BOOL all_valid = FALSE;
02503
02504 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
02505 iter != getSelection()->root_end(); iter++)
02506 {
02507 LLSelectNode* node = *iter;
02508
02509 if (!node->mValid)
02510 {
02511 all_valid = FALSE;
02512 break;
02513 }
02514
02515 all_valid = TRUE;
02516
02517 switch( which_perm )
02518 {
02519 case PERM_BASE:
02520 mask = node->mPermissions->getMaskBase();
02521 break;
02522 case PERM_OWNER:
02523 mask = node->mPermissions->getMaskOwner();
02524 break;
02525 case PERM_GROUP:
02526 mask = node->mPermissions->getMaskGroup();
02527 break;
02528 case PERM_EVERYONE:
02529 mask = node->mPermissions->getMaskEveryone();
02530 break;
02531 case PERM_NEXT_OWNER:
02532 mask = node->mPermissions->getMaskNextOwner();
02533 break;
02534 default:
02535 mask = 0x0;
02536 break;
02537 }
02538 mask_and &= mask;
02539 mask_or |= mask;
02540 }
02541
02542 if (all_valid)
02543 {
02544
02545 *mask_on = mask_and;
02546
02547
02548 *mask_off = ~mask_or;
02549 return TRUE;
02550 }
02551 else
02552 {
02553 *mask_on = 0;
02554 *mask_off = 0;
02555 return FALSE;
02556 }
02557 }
02558
02559
02560
02561 BOOL LLSelectMgr::selectGetOwnershipCost(S32* out_cost)
02562 {
02563 return mSelectedObjects->getOwnershipCost(*out_cost);
02564 }
02565
02566 BOOL LLSelectMgr::selectGetPermissions(LLPermissions& result_perm)
02567 {
02568 BOOL first = TRUE;
02569 LLPermissions perm;
02570 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
02571 iter != getSelection()->root_end(); iter++ )
02572 {
02573 LLSelectNode* node = *iter;
02574 if (!node->mValid)
02575 {
02576 return FALSE;
02577 }
02578
02579 if (first)
02580 {
02581 perm = *(node->mPermissions);
02582 first = FALSE;
02583 }
02584 else
02585 {
02586 perm.accumulate(*(node->mPermissions));
02587 }
02588 }
02589
02590 result_perm = perm;
02591
02592 return TRUE;
02593 }
02594
02595
02596 void LLSelectMgr::selectDelete()
02597 {
02598 S32 deleteable_count = 0;
02599
02600 BOOL locked_but_deleteable_object = FALSE;
02601 BOOL no_copy_but_deleteable_object = FALSE;
02602 BOOL all_owned_by_you = TRUE;
02603
02604 for (LLObjectSelection::iterator iter = getSelection()->begin();
02605 iter != getSelection()->end(); iter++)
02606 {
02607 LLViewerObject* obj = (*iter)->getObject();
02608
02609 if( obj->isAttachment() )
02610 {
02611 continue;
02612 }
02613
02614 deleteable_count++;
02615
02616
02617 if(!obj->permMove())
02618 {
02619 locked_but_deleteable_object = TRUE;
02620 }
02621 if(!obj->permCopy())
02622 {
02623 no_copy_but_deleteable_object = TRUE;
02624 }
02625 if(!obj->permYouOwner())
02626 {
02627 all_owned_by_you = FALSE;
02628 }
02629 }
02630
02631 if( 0 == deleteable_count )
02632 {
02633 make_ui_sound("UISndInvalidOp");
02634 return;
02635 }
02636
02637 LLObjectSelectionHandle* selection_handlep = new LLObjectSelectionHandle(getSelection());
02638
02639 if(locked_but_deleteable_object ||
02640 no_copy_but_deleteable_object ||
02641 !all_owned_by_you)
02642 {
02643
02644
02645
02646
02647 convertTransient();
02648
02649
02650 if(locked_but_deleteable_object && !no_copy_but_deleteable_object && all_owned_by_you)
02651 {
02652
02653 gViewerWindow->alertXml( "ConfirmObjectDeleteLock",
02654 &LLSelectMgr::confirmDelete,
02655 selection_handlep);
02656 }
02657 else if(!locked_but_deleteable_object && no_copy_but_deleteable_object && all_owned_by_you)
02658 {
02659
02660 gViewerWindow->alertXml( "ConfirmObjectDeleteNoCopy",
02661 &LLSelectMgr::confirmDelete,
02662 selection_handlep);
02663 }
02664 else if(!locked_but_deleteable_object && !no_copy_but_deleteable_object && !all_owned_by_you)
02665 {
02666
02667 gViewerWindow->alertXml( "ConfirmObjectDeleteNoOwn",
02668 &LLSelectMgr::confirmDelete,
02669 selection_handlep);
02670 }
02671 else if(locked_but_deleteable_object && no_copy_but_deleteable_object && all_owned_by_you)
02672 {
02673
02674 gViewerWindow->alertXml( "ConfirmObjectDeleteLockNoCopy",
02675 &LLSelectMgr::confirmDelete,
02676 selection_handlep);
02677 }
02678 else if(locked_but_deleteable_object && !no_copy_but_deleteable_object && !all_owned_by_you)
02679 {
02680
02681 gViewerWindow->alertXml( "ConfirmObjectDeleteLockNoOwn",
02682 &LLSelectMgr::confirmDelete,
02683 selection_handlep);
02684 }
02685 else if(!locked_but_deleteable_object && no_copy_but_deleteable_object && !all_owned_by_you)
02686 {
02687
02688 gViewerWindow->alertXml( "ConfirmObjectDeleteNoCopyNoOwn",
02689 &LLSelectMgr::confirmDelete,
02690 selection_handlep);
02691 }
02692 else
02693 {
02694
02695 gViewerWindow->alertXml( "ConfirmObjectDeleteLockNoCopyNoOwn",
02696 &LLSelectMgr::confirmDelete,
02697 selection_handlep);
02698 }
02699
02700
02701
02702 }
02703 else
02704 {
02705 confirmDelete(0, (void*)selection_handlep);
02706 }
02707 }
02708
02709
02710 void LLSelectMgr::confirmDelete(S32 option, void* data)
02711 {
02712 LLObjectSelectionHandle handle = *(LLObjectSelectionHandle*)data;
02713 delete (LLObjectSelectionHandle*)data;
02714
02715 if (!handle->getObjectCount())
02716 {
02717 llwarns << "Nothing to delete!" << llendl;
02718 return;
02719 }
02720
02721 switch(option)
02722 {
02723 case 0:
02724 {
02725
02726 LLUUID trash_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH);
02727
02728 LLDeRezInfo* info = new LLDeRezInfo(DRD_TRASH, trash_id);
02729 gSelectMgr->sendListToRegions("DeRezObject",
02730 packDeRezHeader,
02731 packObjectLocalID,
02732 (void*)info,
02733 SEND_ONLY_ROOTS);
02734
02735 if (gSelectMgr->mSelectedObjects->mSelectType != SELECT_TYPE_HUD)
02736 {
02737 LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)gHUDManager->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
02738 effectp->setPositionGlobal( gSelectMgr->getSelectionCenterGlobal() );
02739 effectp->setColor(LLColor4U(gAgent.getEffectColor()));
02740 F32 duration = 0.5f;
02741 duration += gSelectMgr->mSelectedObjects->getObjectCount() / 64.f;
02742 effectp->setDuration(duration);
02743 }
02744
02745 gAgent.setLookAt(LOOKAT_TARGET_CLEAR);
02746
02747
02748 F64 obj_delete_count = gViewerStats->getStat(LLViewerStats::ST_OBJECT_DELETE_COUNT);
02749 obj_delete_count += gSelectMgr->mSelectedObjects->getObjectCount();
02750 gViewerStats->setStat(LLViewerStats::ST_OBJECT_DELETE_COUNT, obj_delete_count );
02751 }
02752 break;
02753 case 1:
02754 default:
02755 break;
02756 }
02757 }
02758
02759
02760 void LLSelectMgr::selectForceDelete()
02761 {
02762 sendListToRegions(
02763 "ObjectDelete",
02764 packDeleteHeader,
02765 packObjectLocalID,
02766 (void*)TRUE,
02767 SEND_ONLY_ROOTS);
02768 }
02769
02770
02771
02772
02773 BOOL LLSelectMgr::selectIsForSale(S32& price)
02774 {
02775 BOOL any_for_sale = FALSE;
02776 price = 0;
02777
02778 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
02779 iter != getSelection()->root_end(); iter++)
02780 {
02781 LLSelectNode* node = *iter;
02782 if (node->mSaleInfo.isForSale())
02783 {
02784 price += node->mSaleInfo.getSalePrice();
02785 any_for_sale = TRUE;
02786 }
02787 }
02788
02789 return any_for_sale;
02790
02791 }
02792
02793
02794
02795 BOOL LLSelectMgr::selectGetSaleInfo(LLSaleInfo& result_sale_info)
02796 {
02797 BOOL first = TRUE;
02798 LLSaleInfo sale_info;
02799 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
02800 iter != getSelection()->root_end(); iter++ )
02801 {
02802 LLSelectNode* node = *iter;
02803 if (!node->mValid)
02804 {
02805 return FALSE;
02806 }
02807
02808 if (first)
02809 {
02810 sale_info = node->mSaleInfo;
02811 first = FALSE;
02812 }
02813 else
02814 {
02815 sale_info.accumulate(node->mSaleInfo);
02816 }
02817 }
02818
02819 result_sale_info = sale_info;
02820
02821 return TRUE;
02822 }
02823
02824 BOOL LLSelectMgr::selectGetAggregatePermissions(LLAggregatePermissions& result_perm)
02825 {
02826 BOOL first = TRUE;
02827 LLAggregatePermissions perm;
02828 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
02829 iter != getSelection()->root_end(); iter++ )
02830 {
02831 LLSelectNode* node = *iter;
02832 if (!node->mValid)
02833 {
02834 return FALSE;
02835 }
02836
02837 if (first)
02838 {
02839 perm = node->mAggregatePerm;
02840 first = FALSE;
02841 }
02842 else
02843 {
02844 perm.aggregate(node->mAggregatePerm);
02845 }
02846 }
02847
02848 result_perm = perm;
02849
02850 return TRUE;
02851 }
02852
02853 BOOL LLSelectMgr::selectGetAggregateTexturePermissions(LLAggregatePermissions& result_perm)
02854 {
02855 BOOL first = TRUE;
02856 LLAggregatePermissions perm;
02857 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
02858 iter != getSelection()->root_end(); iter++ )
02859 {
02860 LLSelectNode* node = *iter;
02861 if (!node->mValid)
02862 {
02863 return FALSE;
02864 }
02865
02866 LLAggregatePermissions t_perm = node->getObject()->permYouOwner() ? node->mAggregateTexturePermOwner : node->mAggregateTexturePerm;
02867 if (first)
02868 {
02869 perm = t_perm;
02870 first = FALSE;
02871 }
02872 else
02873 {
02874 perm.aggregate(t_perm);
02875 }
02876 }
02877
02878 result_perm = perm;
02879
02880 return TRUE;
02881 }
02882
02883
02884
02885
02886
02887
02888
02889
02890
02891 struct LLDuplicateData
02892 {
02893 LLVector3 offset;
02894 U32 flags;
02895 };
02896
02897 void LLSelectMgr::selectDuplicate(const LLVector3& offset, BOOL select_copy)
02898 {
02899 if (mSelectedObjects->isAttachment())
02900 {
02901
02902 make_ui_sound("UISndInvalidOp");
02903 return;
02904 }
02905 LLDuplicateData data;
02906
02907 data.offset = offset;
02908 data.flags = (select_copy ? FLAGS_CREATE_SELECTED : 0x0);
02909
02910 sendListToRegions("ObjectDuplicate", packDuplicateHeader, packDuplicate, &data, SEND_ONLY_ROOTS);
02911
02912 if (select_copy)
02913 {
02914
02915 deselectAll();
02916 }
02917 else
02918 {
02919 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
02920 iter != getSelection()->root_end(); iter++ )
02921 {
02922 LLSelectNode* node = *iter;
02923 node->mDuplicated = TRUE;
02924 node->mDuplicatePos = node->getObject()->getPositionGlobal();
02925 node->mDuplicateRot = node->getObject()->getRotation();
02926 }
02927 }
02928 }
02929
02930 void LLSelectMgr::repeatDuplicate()
02931 {
02932 if (mSelectedObjects->isAttachment())
02933 {
02934
02935 make_ui_sound("UISndInvalidOp");
02936 return;
02937 }
02938
02939 std::vector<LLViewerObject*> non_duplicated_objects;
02940
02941 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
02942 iter != getSelection()->root_end(); iter++ )
02943 {
02944 LLSelectNode* node = *iter;
02945 if (!node->mDuplicated)
02946 {
02947 non_duplicated_objects.push_back(node->getObject());
02948 }
02949 }
02950
02951
02952 for (std::vector<LLViewerObject*>::iterator iter = non_duplicated_objects.begin();
02953 iter != non_duplicated_objects.end(); ++iter)
02954 {
02955 LLViewerObject* objectp = *iter;
02956 deselectObjectAndFamily(objectp);
02957 }
02958
02959
02960 LLDuplicateData data;
02961
02962 data.offset = LLVector3::zero;
02963 data.flags = 0x0;
02964
02965 sendListToRegions("ObjectDuplicate", packDuplicateHeader, packDuplicate, &data, SEND_ONLY_ROOTS);
02966
02967
02968 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
02969 iter != getSelection()->root_end(); iter++ )
02970 {
02971 LLSelectNode* node = *iter;
02972 if (node->mDuplicated)
02973 {
02974 LLQuaternion cur_rot = node->getObject()->getRotation();
02975 LLQuaternion rot_delta = (~node->mDuplicateRot * cur_rot);
02976 LLQuaternion new_rot = cur_rot * rot_delta;
02977 LLVector3d cur_pos = node->getObject()->getPositionGlobal();
02978 LLVector3d new_pos = cur_pos + ((cur_pos - node->mDuplicatePos) * rot_delta);
02979
02980 node->mDuplicatePos = node->getObject()->getPositionGlobal();
02981 node->mDuplicateRot = node->getObject()->getRotation();
02982 node->getObject()->setPositionGlobal(new_pos);
02983 node->getObject()->setRotation(new_rot);
02984 }
02985 }
02986
02987 sendMultipleUpdate(UPD_ROTATION | UPD_POSITION);
02988 }
02989
02990
02991 void LLSelectMgr::packDuplicate( LLSelectNode* node, void *duplicate_data )
02992 {
02993 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
02994 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID());
02995 }
02996
02997
02998
02999
03000
03001
03002
03003
03004 struct LLDuplicateOnRayData
03005 {
03006 LLVector3 mRayStartRegion;
03007 LLVector3 mRayEndRegion;
03008 BOOL mBypassRaycast;
03009 BOOL mRayEndIsIntersection;
03010 LLUUID mRayTargetID;
03011 BOOL mCopyCenters;
03012 BOOL mCopyRotates;
03013 U32 mFlags;
03014 };
03015
03016 void LLSelectMgr::selectDuplicateOnRay(const LLVector3 &ray_start_region,
03017 const LLVector3 &ray_end_region,
03018 BOOL bypass_raycast,
03019 BOOL ray_end_is_intersection,
03020 const LLUUID &ray_target_id,
03021 BOOL copy_centers,
03022 BOOL copy_rotates,
03023 BOOL select_copy)
03024 {
03025 if (mSelectedObjects->isAttachment())
03026 {
03027
03028 make_ui_sound("UISndInvalidOp");
03029 return;
03030 }
03031
03032 LLDuplicateOnRayData data;
03033
03034 data.mRayStartRegion = ray_start_region;
03035 data.mRayEndRegion = ray_end_region;
03036 data.mBypassRaycast = bypass_raycast;
03037 data.mRayEndIsIntersection = ray_end_is_intersection;
03038 data.mRayTargetID = ray_target_id;
03039 data.mCopyCenters = copy_centers;
03040 data.mCopyRotates = copy_rotates;
03041 data.mFlags = (select_copy ? FLAGS_CREATE_SELECTED : 0x0);
03042
03043 sendListToRegions("ObjectDuplicateOnRay",
03044 packDuplicateOnRayHead, packObjectLocalID, &data, SEND_ONLY_ROOTS);
03045
03046 if (select_copy)
03047 {
03048
03049 deselectAll();
03050 }
03051 }
03052
03053
03054 void LLSelectMgr::packDuplicateOnRayHead(void *user_data)
03055 {
03056 LLMessageSystem *msg = gMessageSystem;
03057 LLDuplicateOnRayData *data = (LLDuplicateOnRayData *)user_data;
03058
03059 msg->nextBlockFast(_PREHASH_AgentData);
03060 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
03061 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
03062 msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID() );
03063 msg->addVector3Fast(_PREHASH_RayStart, data->mRayStartRegion );
03064 msg->addVector3Fast(_PREHASH_RayEnd, data->mRayEndRegion );
03065 msg->addBOOLFast(_PREHASH_BypassRaycast, data->mBypassRaycast );
03066 msg->addBOOLFast(_PREHASH_RayEndIsIntersection, data->mRayEndIsIntersection );
03067 msg->addBOOLFast(_PREHASH_CopyCenters, data->mCopyCenters );
03068 msg->addBOOLFast(_PREHASH_CopyRotates, data->mCopyRotates );
03069 msg->addUUIDFast(_PREHASH_RayTargetID, data->mRayTargetID );
03070 msg->addU32Fast(_PREHASH_DuplicateFlags, data->mFlags );
03071 }
03072
03073
03074
03075
03076
03077
03078
03079 void LLSelectMgr::sendMultipleUpdate(U32 type)
03080 {
03081 if (type == UPD_NONE) return;
03082
03083 ESendType send_type = (!gSavedSettings.getBOOL("EditLinkedParts") && !getTEMode()) ? SEND_ONLY_ROOTS : SEND_ROOTS_FIRST;
03084 if (send_type == SEND_ONLY_ROOTS)
03085 {
03086
03087 type |= UPD_LINKED_SETS;
03088 }
03089
03090 sendListToRegions(
03091 "MultipleObjectUpdate",
03092 packAgentAndSessionID,
03093 packMultipleUpdate,
03094 &type,
03095 send_type);
03096 }
03097
03098
03099 void LLSelectMgr::packMultipleUpdate(LLSelectNode* node, void *user_data)
03100 {
03101 LLViewerObject* object = node->getObject();
03102 U32 *type32 = (U32 *)user_data;
03103 U8 type = (U8)*type32;
03104 U8 data[256];
03105
03106 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
03107 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() );
03108 gMessageSystem->addU8Fast(_PREHASH_Type, type );
03109
03110 S32 offset = 0;
03111
03112
03113
03114
03115
03116 if (type & UPD_POSITION)
03117 {
03118 htonmemcpy(&data[offset], &(object->getPosition().mV), MVT_LLVector3, 12);
03119 offset += 12;
03120 }
03121 if (type & UPD_ROTATION)
03122 {
03123 LLQuaternion quat = object->getRotation();
03124 LLVector3 vec = quat.packToVector3();
03125 htonmemcpy(&data[offset], &(vec.mV), MVT_LLQuaternion, 12);
03126 offset += 12;
03127 }
03128 if (type & UPD_SCALE)
03129 {
03130
03131 htonmemcpy(&data[offset], &(object->getScale().mV), MVT_LLVector3, 12);
03132 offset += 12;
03133 }
03134 gMessageSystem->addBinaryDataFast(_PREHASH_Data, data, offset);
03135 }
03136
03137
03138
03139
03140 struct LLOwnerData
03141 {
03142 LLUUID owner_id;
03143 LLUUID group_id;
03144 BOOL override;
03145 };
03146
03147 void LLSelectMgr::sendOwner(const LLUUID& owner_id,
03148 const LLUUID& group_id,
03149 BOOL override)
03150 {
03151 LLOwnerData data;
03152
03153 data.owner_id = owner_id;
03154 data.group_id = group_id;
03155 data.override = override;
03156
03157 sendListToRegions("ObjectOwner", packOwnerHead, packObjectLocalID, &data, SEND_ONLY_ROOTS);
03158 }
03159
03160
03161 void LLSelectMgr::packOwnerHead(void *user_data)
03162 {
03163 LLOwnerData *data = (LLOwnerData *)user_data;
03164
03165 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
03166 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
03167 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
03168 gMessageSystem->nextBlockFast(_PREHASH_HeaderData);
03169 gMessageSystem->addBOOLFast(_PREHASH_Override, data->override);
03170 gMessageSystem->addUUIDFast(_PREHASH_OwnerID, data->owner_id);
03171 gMessageSystem->addUUIDFast(_PREHASH_GroupID, data->group_id);
03172 }
03173
03174
03175
03176
03177
03178 void LLSelectMgr::sendGroup(const LLUUID& group_id)
03179 {
03180 LLUUID local_group_id(group_id);
03181 sendListToRegions("ObjectGroup", packAgentAndSessionAndGroupID, packObjectLocalID, &local_group_id, SEND_ONLY_ROOTS);
03182 }
03183
03184
03185
03186
03187
03188
03189 struct LLBuyData
03190 {
03191 std::vector<LLViewerObject*> mObjectsSent;
03192 LLUUID mCategoryID;
03193 LLSaleInfo mSaleInfo;
03194 };
03195
03196
03197
03198
03199
03200 void LLSelectMgr::sendBuy(const LLUUID& buyer_id, const LLUUID& category_id, const LLSaleInfo sale_info)
03201 {
03202 LLBuyData buy;
03203 buy.mCategoryID = category_id;
03204 buy.mSaleInfo = sale_info;
03205 sendListToRegions("ObjectBuy", packAgentGroupAndCatID, packBuyObjectIDs, &buy, SEND_ONLY_ROOTS);
03206 }
03207
03208
03209 void LLSelectMgr::packBuyObjectIDs(LLSelectNode* node, void* data)
03210 {
03211 LLBuyData* buy = (LLBuyData*)data;
03212
03213 LLViewerObject* object = node->getObject();
03214 if (std::find(buy->mObjectsSent.begin(), buy->mObjectsSent.end(), object) == buy->mObjectsSent.end())
03215 {
03216 buy->mObjectsSent.push_back(object);
03217 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
03218 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() );
03219 gMessageSystem->addU8Fast(_PREHASH_SaleType, buy->mSaleInfo.getSaleType());
03220 gMessageSystem->addS32Fast(_PREHASH_SalePrice, buy->mSaleInfo.getSalePrice());
03221 }
03222 }
03223
03224
03225
03226
03227
03228 struct LLPermData
03229 {
03230 U8 mField;
03231 BOOL mSet;
03232 U32 mMask;
03233 BOOL mOverride;
03234 };
03235
03236
03237 void LLSelectMgr::selectionSetObjectPermissions(U8 field,
03238 BOOL set,
03239 U32 mask,
03240 BOOL override)
03241 {
03242 LLPermData data;
03243
03244 data.mField = field;
03245 data.mSet = set;
03246 data.mMask = mask;
03247 data.mOverride = override;
03248
03249 sendListToRegions("ObjectPermissions", packPermissionsHead, packPermissions, &data, SEND_ONLY_ROOTS);
03250 }
03251
03252 void LLSelectMgr::packPermissionsHead(void* user_data)
03253 {
03254 LLPermData* data = (LLPermData*)user_data;
03255 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
03256 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
03257 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
03258 gMessageSystem->nextBlockFast(_PREHASH_HeaderData);
03259 gMessageSystem->addBOOLFast(_PREHASH_Override, data->mOverride);
03260 }
03261
03262
03263
03264
03265
03266
03267
03268
03269
03270
03271
03272 void LLSelectMgr::deselectAll()
03273 {
03274 if (!mSelectedObjects->getNumNodes())
03275 {
03276 return;
03277 }
03278
03279 sendListToRegions(
03280 "ObjectDeselect",
03281 packAgentAndSessionID,
03282 packObjectLocalID,
03283 NULL,
03284 SEND_INDIVIDUALS);
03285
03286 removeAll();
03287
03288 mLastSentSelectionCenterGlobal.clearVec();
03289
03290 updatePointAt();
03291 }
03292
03293 void LLSelectMgr::deselectUnused()
03294 {
03295
03296 if (mSelectedObjects->getNumRefs() == 1)
03297 {
03298 deselectAll();
03299 }
03300 }
03301
03302 void LLSelectMgr::convertTransient()
03303 {
03304 LLObjectSelection::iterator node_it;
03305 for (node_it = mSelectedObjects->begin(); node_it != mSelectedObjects->end(); ++node_it)
03306 {
03307 LLSelectNode *nodep = *node_it;
03308 nodep->setTransient(FALSE);
03309 }
03310 }
03311
03312 void LLSelectMgr::deselectAllIfTooFar()
03313 {
03314 if (mSelectedObjects->isEmpty() || mSelectedObjects->mSelectType == SELECT_TYPE_HUD)
03315 {
03316 return;
03317 }
03318
03319
03320
03321 if (gPieObject->getVisible() || gPieRate->getVisible() )
03322 {
03323 return;
03324 }
03325
03326 LLVector3d selectionCenter = getSelectionCenterGlobal();
03327 if (gSavedSettings.getBOOL("LimitSelectDistance")
03328 && !selectionCenter.isExactlyZero())
03329 {
03330 F32 deselect_dist = gSavedSettings.getF32("MaxSelectDistance");
03331 F32 deselect_dist_sq = deselect_dist * deselect_dist;
03332
03333 LLVector3d select_delta = gAgent.getPositionGlobal() - selectionCenter;
03334 F32 select_dist_sq = (F32) select_delta.magVecSquared();
03335
03336 if (select_dist_sq > deselect_dist_sq)
03337 {
03338 if (gDebugSelectMgr)
03339 {
03340 llinfos << "Selection manager: auto-deselecting, select_dist = " << fsqrtf(select_dist_sq) << llendl;
03341 llinfos << "agent pos global = " << gAgent.getPositionGlobal() << llendl;
03342 llinfos << "selection pos global = " << selectionCenter << llendl;
03343 }
03344
03345 deselectAll();
03346 }
03347 }
03348 }
03349
03350
03351 void LLSelectMgr::selectionSetObjectName(const LLString& name)
03352 {
03353
03354 if(mSelectedObjects->getRootObjectCount() == 1)
03355 {
03356 sendListToRegions("ObjectName",
03357 packAgentAndSessionID,
03358 packObjectName,
03359 (void*)name.c_str(),
03360 SEND_ONLY_ROOTS);
03361 }
03362 else if(mSelectedObjects->getObjectCount() == 1)
03363 {
03364 sendListToRegions("ObjectName",
03365 packAgentAndSessionID,
03366 packObjectName,
03367 (void*)name.c_str(),
03368 SEND_INDIVIDUALS);
03369 }
03370 }
03371
03372 void LLSelectMgr::selectionSetObjectDescription(const LLString& desc)
03373 {
03374
03375 if(mSelectedObjects->getRootObjectCount() == 1)
03376 {
03377 sendListToRegions("ObjectDescription",
03378 packAgentAndSessionID,
03379 packObjectDescription,
03380 (void*)desc.c_str(),
03381 SEND_ONLY_ROOTS);
03382 }
03383 else if(mSelectedObjects->getObjectCount() == 1)
03384 {
03385 sendListToRegions("ObjectDescription",
03386 packAgentAndSessionID,
03387 packObjectDescription,
03388 (void*)desc.c_str(),
03389 SEND_INDIVIDUALS);
03390 }
03391 }
03392
03393 void LLSelectMgr::selectionSetObjectCategory(const LLCategory& category)
03394 {
03395
03396
03397 if(mSelectedObjects->getRootObjectCount() != 1) return;
03398 sendListToRegions("ObjectCategory",
03399 packAgentAndSessionID,
03400 packObjectCategory,
03401 (void*)(&category),
03402 SEND_ONLY_ROOTS);
03403 }
03404
03405 void LLSelectMgr::selectionSetObjectSaleInfo(const LLSaleInfo& sale_info)
03406 {
03407
03408 if(mSelectedObjects->getRootObjectCount() != 1) return;
03409 sendListToRegions("ObjectSaleInfo",
03410 packAgentAndSessionID,
03411 packObjectSaleInfo,
03412 (void*)(&sale_info),
03413 SEND_ONLY_ROOTS);
03414 }
03415
03416
03417
03418
03419
03420 void LLSelectMgr::sendAttach(U8 attachment_point)
03421 {
03422 LLViewerObject* attach_object = mSelectedObjects->getFirstRootObject();
03423
03424 if (!attach_object || !gAgent.getAvatarObject() || mSelectedObjects->mSelectType != SELECT_TYPE_WORLD)
03425 {
03426 return;
03427 }
03428
03429 BOOL build_mode = gToolMgr->inEdit();
03430
03431 if (0 == attachment_point ||
03432 gAgent.getAvatarObject()->mAttachmentPoints.getIfThere(attachment_point))
03433 {
03434 sendListToRegions(
03435 "ObjectAttach",
03436 packAgentIDAndSessionAndAttachment,
03437 packObjectIDAndRotation,
03438 &attachment_point,
03439 SEND_ONLY_ROOTS );
03440 if (!build_mode)
03441 {
03442 deselectAll();
03443 }
03444 }
03445 }
03446
03447 void LLSelectMgr::sendDetach()
03448 {
03449 if (!mSelectedObjects->getNumNodes() || mSelectedObjects->mSelectType == SELECT_TYPE_WORLD)
03450 {
03451 return;
03452 }
03453
03454 sendListToRegions(
03455 "ObjectDetach",
03456 packAgentAndSessionID,
03457 packObjectLocalID,
03458 NULL,
03459 SEND_ONLY_ROOTS );
03460 }
03461
03462
03463 void LLSelectMgr::sendDropAttachment()
03464 {
03465 if (!mSelectedObjects->getNumNodes() || mSelectedObjects->mSelectType == SELECT_TYPE_WORLD)
03466 {
03467 return;
03468 }
03469
03470 sendListToRegions(
03471 "ObjectDrop",
03472 packAgentAndSessionID,
03473 packObjectLocalID,
03474 NULL,
03475 SEND_ONLY_ROOTS);
03476 }
03477
03478
03479
03480
03481
03482 void LLSelectMgr::sendLink()
03483 {
03484 if (!mSelectedObjects->getNumNodes())
03485 {
03486 return;
03487 }
03488
03489 sendListToRegions(
03490 "ObjectLink",
03491 packAgentAndSessionID,
03492 packObjectLocalID,
03493 NULL,
03494 SEND_ONLY_ROOTS);
03495 }
03496
03497 void LLSelectMgr::sendDelink()
03498 {
03499 if (!mSelectedObjects->getNumNodes())
03500 {
03501 return;
03502 }
03503
03504
03505
03506 sendListToRegions(
03507 "ObjectDelink",
03508 packAgentAndSessionID,
03509 packObjectLocalID,
03510 NULL,
03511 SEND_INDIVIDUALS);
03512 }
03513
03514
03515
03516
03517
03518
03519
03520
03521
03522
03523
03524
03525
03526
03527
03528
03529
03530
03531
03532
03533
03534
03535
03536
03537
03538
03539
03540
03541
03542
03543
03544
03545
03546
03547
03548
03549
03550
03551 void LLSelectMgr::sendSelect()
03552 {
03553 if (!mSelectedObjects->getNumNodes())
03554 {
03555 return;
03556 }
03557
03558 sendListToRegions(
03559 "ObjectSelect",
03560 packAgentAndSessionID,
03561 packObjectLocalID,
03562 NULL,
03563 SEND_INDIVIDUALS);
03564 }
03565
03566
03567 void LLSelectMgr::packHingeHead(void *user_data)
03568 {
03569 U8 *type = (U8 *)user_data;
03570
03571 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
03572 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
03573 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
03574 gMessageSystem->nextBlockFast(_PREHASH_JointType);
03575 gMessageSystem->addU8Fast(_PREHASH_Type, *type );
03576 }
03577
03578
03579 void LLSelectMgr::selectionDump()
03580 {
03581 struct f : public LLSelectedObjectFunctor
03582 {
03583 virtual bool apply(LLViewerObject* object)
03584 {
03585 object->dump();
03586 return true;
03587 }
03588 } func;
03589 getSelection()->applyToObjects(&func);
03590 }
03591
03592 void LLSelectMgr::saveSelectedObjectColors()
03593 {
03594 struct f : public LLSelectedNodeFunctor
03595 {
03596 virtual bool apply(LLSelectNode* node)
03597 {
03598 node->saveColors();
03599 return true;
03600 }
03601 } func;
03602 getSelection()->applyToNodes(&func);
03603 }
03604
03605 void LLSelectMgr::saveSelectedObjectTextures()
03606 {
03607
03608 struct f : public LLSelectedNodeFunctor
03609 {
03610 virtual bool apply(LLSelectNode* node)
03611 {
03612 node->mValid = FALSE;
03613 return true;
03614 }
03615 } func;
03616 getSelection()->applyToNodes(&func);
03617
03618
03619 sendSelect();
03620 }
03621
03622
03623
03624
03625 void LLSelectMgr::saveSelectedObjectTransform(EActionType action_type)
03626 {
03627 if (mSelectedObjects->isEmpty())
03628 {
03629
03630 return;
03631 }
03632
03633 struct f : public LLSelectedNodeFunctor
03634 {
03635 EActionType mActionType;
03636 f(EActionType a) : mActionType(a) {}
03637 virtual bool apply(LLSelectNode* selectNode)
03638 {
03639 LLViewerObject* object = selectNode->getObject();
03640 selectNode->mSavedPositionLocal = object->getPosition();
03641 if (object->isAttachment())
03642 {
03643 if (object->isRootEdit())
03644 {
03645 LLXform* parent_xform = object->mDrawable->getXform()->getParent();
03646 if (parent_xform)
03647 {
03648 selectNode->mSavedPositionGlobal = gAgent.getPosGlobalFromAgent((object->getPosition() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition());
03649 }
03650 }
03651 else
03652 {
03653 LLViewerObject* attachment_root = (LLViewerObject*)object->getParent();
03654 LLXform* parent_xform = attachment_root->mDrawable->getXform()->getParent();
03655 LLVector3 root_pos = (attachment_root->getPosition() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition();
03656 LLQuaternion root_rot = (attachment_root->getRotation() * parent_xform->getWorldRotation());
03657 selectNode->mSavedPositionGlobal = gAgent.getPosGlobalFromAgent((object->getPosition() * root_rot) + root_pos);
03658 }
03659 selectNode->mSavedRotation = object->getRenderRotation();
03660 }
03661 else
03662 {
03663 selectNode->mSavedPositionGlobal = object->getPositionGlobal();
03664 selectNode->mSavedRotation = object->getRotationRegion();
03665 }
03666
03667 selectNode->mSavedScale = object->getScale();
03668 selectNode->saveTextureScaleRatios();
03669 return true;
03670 }
03671 } func(action_type);
03672 getSelection()->applyToNodes(&func);
03673
03674 mSavedSelectionBBox = getBBoxOfSelection();
03675 }
03676
03677 struct LLSelectMgrApplyFlags : public LLSelectedObjectFunctor
03678 {
03679 LLSelectMgrApplyFlags(U32 flags, BOOL state) : mFlags(flags), mState(state) {}
03680 U32 mFlags;
03681 BOOL mState;
03682 virtual bool apply(LLViewerObject* object)
03683 {
03684 if ( object->permModify() &&
03685 object->isRoot() &&
03686 !object->isJointChild())
03687 {
03688 object->setFlags( mFlags, mState);
03689 }
03690 return true;
03691 }
03692 };
03693
03694 void LLSelectMgr::selectionUpdatePhysics(BOOL physics)
03695 {
03696 LLSelectMgrApplyFlags func( FLAGS_USE_PHYSICS, physics);
03697 getSelection()->applyToObjects(&func);
03698 }
03699
03700 void LLSelectMgr::selectionUpdateTemporary(BOOL is_temporary)
03701 {
03702 LLSelectMgrApplyFlags func( FLAGS_TEMPORARY_ON_REZ, is_temporary);
03703 getSelection()->applyToObjects(&func);
03704 }
03705
03706 void LLSelectMgr::selectionUpdatePhantom(BOOL is_phantom)
03707 {
03708 LLSelectMgrApplyFlags func( FLAGS_PHANTOM, is_phantom);
03709 getSelection()->applyToObjects(&func);
03710 }
03711
03712 void LLSelectMgr::selectionUpdateCastShadows(BOOL cast_shadows)
03713 {
03714 LLSelectMgrApplyFlags func( FLAGS_CAST_SHADOWS, cast_shadows);
03715 getSelection()->applyToObjects(&func);
03716 }
03717
03718
03719
03720
03721
03722
03723
03724 void LLSelectMgr::packAgentIDAndSessionAndAttachment( void *user_data)
03725 {
03726 U8 *attachment_point = (U8*)user_data;
03727 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
03728 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
03729 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
03730 gMessageSystem->addU8Fast(_PREHASH_AttachmentPoint, *attachment_point);
03731 }
03732
03733
03734 void LLSelectMgr::packAgentID( void *user_data)
03735 {
03736 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
03737 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
03738 }
03739
03740
03741 void LLSelectMgr::packAgentAndSessionID(void* user_data)
03742 {
03743 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
03744 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
03745 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
03746 }
03747
03748
03749 void LLSelectMgr::packAgentAndGroupID(void* user_data)
03750 {
03751 LLOwnerData *data = (LLOwnerData *)user_data;
03752
03753 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
03754 gMessageSystem->addUUIDFast(_PREHASH_AgentID, data->owner_id );
03755 gMessageSystem->addUUIDFast(_PREHASH_GroupID, data->group_id );
03756 }
03757
03758
03759 void LLSelectMgr::packAgentAndSessionAndGroupID(void* user_data)
03760 {
03761 LLUUID* group_idp = (LLUUID*) user_data;
03762 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
03763 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
03764 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
03765 gMessageSystem->addUUIDFast(_PREHASH_GroupID, *group_idp);
03766 }
03767
03768
03769 void LLSelectMgr::packDuplicateHeader(void* data)
03770 {
03771 LLUUID group_id(gAgent.getGroupID());
03772 packAgentAndSessionAndGroupID(&group_id);
03773
03774 LLDuplicateData* dup_data = (LLDuplicateData*) data;
03775
03776 gMessageSystem->nextBlockFast(_PREHASH_SharedData);
03777 gMessageSystem->addVector3Fast(_PREHASH_Offset, dup_data->offset);
03778 gMessageSystem->addU32Fast(_PREHASH_DuplicateFlags, dup_data->flags);
03779 }
03780
03781
03782 void LLSelectMgr::packDeleteHeader(void* userdata)
03783 {
03784 BOOL force = (BOOL)(intptr_t)userdata;
03785
03786 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
03787 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
03788 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
03789 gMessageSystem->addBOOLFast(_PREHASH_Force, force);
03790 }
03791
03792
03793 void LLSelectMgr::packAgentGroupAndCatID(void* user_data)
03794 {
03795 LLBuyData* buy = (LLBuyData*)user_data;
03796 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
03797 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
03798 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
03799 gMessageSystem->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
03800 gMessageSystem->addUUIDFast(_PREHASH_CategoryID, buy->mCategoryID);
03801 }
03802
03803
03804 void LLSelectMgr::packDeRezHeader(void* user_data)
03805 {
03806 LLDeRezInfo* info = (LLDeRezInfo*)user_data;
03807 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
03808 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
03809 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
03810 gMessageSystem->nextBlockFast(_PREHASH_AgentBlock);
03811 gMessageSystem->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
03812 gMessageSystem->addU8Fast(_PREHASH_Destination, (U8)info->mDestination);
03813 gMessageSystem->addUUIDFast(_PREHASH_DestinationID, info->mDestinationID);
03814 LLUUID tid;
03815 tid.generate();
03816 gMessageSystem->addUUIDFast(_PREHASH_TransactionID, tid);
03817 const U8 PACKET = 1;
03818 gMessageSystem->addU8Fast(_PREHASH_PacketCount, PACKET);
03819 gMessageSystem->addU8Fast(_PREHASH_PacketNumber, PACKET);
03820 }
03821
03822
03823 void LLSelectMgr::packObjectID(LLSelectNode* node, void *user_data)
03824 {
03825 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
03826 gMessageSystem->addUUIDFast(_PREHASH_ObjectID, node->getObject()->mID );
03827 }
03828
03829 void LLSelectMgr::packObjectIDAndRotation(LLSelectNode* node, void *user_data)
03830 {
03831 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
03832 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() );
03833 gMessageSystem->addQuatFast(_PREHASH_Rotation, node->getObject()->getRotation());
03834 }
03835
03836 void LLSelectMgr::packObjectClickAction(LLSelectNode* node, void *user_data)
03837 {
03838 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
03839 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() );
03840 gMessageSystem->addU8("ClickAction", node->getObject()->getClickAction());
03841 }
03842
03843 void LLSelectMgr::packObjectIncludeInSearch(LLSelectNode* node, void *user_data)
03844 {
03845 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
03846 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() );
03847 gMessageSystem->addBOOL("IncludeInSearch", node->getObject()->getIncludeInSearch());
03848 }
03849
03850
03851 void LLSelectMgr::packObjectLocalID(LLSelectNode* node, void *)
03852 {
03853 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
03854 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID());
03855 }
03856
03857
03858 void LLSelectMgr::packObjectName(LLSelectNode* node, void* user_data)
03859 {
03860 char* name = (char*)user_data;
03861 if(!name) return;
03862 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
03863 gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID());
03864 gMessageSystem->addStringFast(_PREHASH_Name, name);
03865 }
03866
03867
03868 void LLSelectMgr::packObjectDescription(LLSelectNode* node,
03869 void* user_data)
03870 {
03871 char* desc = (char*)user_data;
03872 if(!desc) return;
03873 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
03874 gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID());
03875 gMessageSystem->addStringFast(_PREHASH_Description, desc);
03876 }
03877
03878
03879 void LLSelectMgr::packObjectCategory(LLSelectNode* node, void* user_data)
03880 {
03881 LLCategory* category = (LLCategory*)user_data;
03882 if(!category) return;
03883 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
03884 gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID());
03885 category->packMessage(gMessageSystem);
03886 }
03887
03888
03889 void LLSelectMgr::packObjectSaleInfo(LLSelectNode* node, void* user_data)
03890 {
03891 LLSaleInfo* sale_info = (LLSaleInfo*)user_data;
03892 if(!sale_info) return;
03893 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
03894 gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID());
03895 sale_info->packMessage(gMessageSystem);
03896 }
03897
03898
03899 void LLSelectMgr::packPhysics(LLSelectNode* node, void *user_data)
03900 {
03901 }
03902
03903
03904 void LLSelectMgr::packShape(LLSelectNode* node, void *user_data)
03905 {
03906 }
03907
03908
03909 void LLSelectMgr::packPermissions(LLSelectNode* node, void *user_data)
03910 {
03911 LLPermData *data = (LLPermData *)user_data;
03912
03913 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
03914 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID());
03915
03916 gMessageSystem->addU8Fast(_PREHASH_Field, data->mField);
03917 gMessageSystem->addBOOLFast(_PREHASH_Set, data->mSet);
03918 gMessageSystem->addU32Fast(_PREHASH_Mask, data->mMask);
03919 }
03920
03921
03922
03923
03924 void LLSelectMgr::sendListToRegions(const LLString& message_name,
03925 void (*pack_header)(void *user_data),
03926 void (*pack_body)(LLSelectNode* node, void *user_data),
03927 void *user_data,
03928 ESendType send_type)
03929 {
03930 LLSelectNode* node;
03931 LLViewerRegion* last_region;
03932 LLViewerRegion* current_region;
03933
03934 S32 objects_sent = 0;
03935 S32 packets_sent = 0;
03936 S32 objects_in_this_packet = 0;
03937
03938
03939 struct f : public LLSelectedNodeFunctor
03940 {
03941 virtual bool apply(LLSelectNode* node)
03942 {
03943 node->mLastPositionLocal.setVec(0,0,0);
03944 node->mLastRotation = LLQuaternion();
03945 node->mLastScale.setVec(0,0,0);
03946 return true;
03947 }
03948 } func;
03949 getSelection()->applyToNodes(&func);
03950
03951 std::queue<LLSelectNode*> nodes_to_send;
03952
03953 struct push_all : public LLSelectedNodeFunctor
03954 {
03955 std::queue<LLSelectNode*>& nodes_to_send;
03956 push_all(std::queue<LLSelectNode*>& n) : nodes_to_send(n) {}
03957 virtual bool apply(LLSelectNode* node)
03958 {
03959 nodes_to_send.push(node);
03960 return true;
03961 }
03962 };
03963 struct push_some : public LLSelectedNodeFunctor
03964 {
03965 std::queue<LLSelectNode*>& nodes_to_send;
03966 bool mRoots;
03967 push_some(std::queue<LLSelectNode*>& n, bool roots) : nodes_to_send(n), mRoots(roots) {}
03968 virtual bool apply(LLSelectNode* node)
03969 {
03970 BOOL is_root = node->getObject()->isRootEdit();
03971 if ((mRoots && is_root) || (!mRoots && !is_root))
03972 {
03973 nodes_to_send.push(node);
03974 }
03975 return true;
03976 }
03977 };
03978 struct push_editable : public LLSelectedNodeFunctor
03979 {
03980 std::queue<LLSelectNode*>& nodes_to_send;
03981 push_editable(std::queue<LLSelectNode*>& n) : nodes_to_send(n) {}
03982 virtual bool apply(LLSelectNode* node)
03983 {
03984
03985 nodes_to_send.push(node);
03986 return true;
03987 }
03988 };
03989 struct push_all pushall(nodes_to_send);
03990 struct push_some pushroots(nodes_to_send, TRUE);
03991 struct push_some pushnonroots(nodes_to_send, FALSE);
03992 struct push_editable pusheditable(nodes_to_send);
03993
03994 switch(send_type)
03995 {
03996 case SEND_ONLY_ROOTS:
03997 getSelection()->applyToRootNodes(&pusheditable);
03998 break;
03999 case SEND_INDIVIDUALS:
04000 getSelection()->applyToNodes(&pushall);
04001 break;
04002 case SEND_ROOTS_FIRST:
04003
04004 getSelection()->applyToNodes(&pushroots);
04005
04006 getSelection()->applyToNodes(&pushnonroots);
04007 break;
04008 case SEND_CHILDREN_FIRST:
04009
04010 getSelection()->applyToNodes(&pushnonroots);
04011
04012 getSelection()->applyToNodes(&pushroots);
04013 break;
04014
04015 default:
04016 llerrs << "Bad send type " << send_type << " passed to SendListToRegions()" << llendl;
04017 }
04018
04019
04020 if (nodes_to_send.empty())
04021 {
04022 return;
04023 }
04024
04025 node = nodes_to_send.front();
04026 nodes_to_send.pop();
04027
04028
04029 current_region = node->getObject()->getRegion();
04030
04031
04032
04033 gMessageSystem->newMessage(message_name.c_str());
04034 (*pack_header)(user_data);
04035
04036
04037 while (node != NULL)
04038 {
04039
04040 last_region = current_region;
04041 current_region = node->getObject()->getRegion();
04042
04043
04044 if ((current_region == last_region)
04045 && (! gMessageSystem->isSendFull(NULL))
04046 && (objects_in_this_packet < MAX_OBJECTS_PER_PACKET))
04047 {
04048
04049 (*pack_body)(node, user_data);
04050 ++objects_sent;
04051 ++objects_in_this_packet;
04052
04053
04054 if(nodes_to_send.empty())
04055 {
04056 node = NULL;
04057 }
04058 else
04059 {
04060 node = nodes_to_send.front();
04061 nodes_to_send.pop();
04062 }
04063 }
04064 else
04065 {
04066
04067 gMessageSystem->sendReliable( last_region->getHost());
04068 packets_sent++;
04069 objects_in_this_packet = 0;
04070
04071 gMessageSystem->newMessage(message_name.c_str());
04072 (*pack_header)(user_data);
04073
04074
04075
04076 }
04077 }
04078
04079
04080 if (gMessageSystem->getCurrentSendTotal() > 0)
04081 {
04082 gMessageSystem->sendReliable( current_region->getHost());
04083 packets_sent++;
04084 }
04085 else
04086 {
04087 gMessageSystem->clearMessage();
04088 }
04089
04090
04091 }
04092
04093
04094
04095
04096
04097
04098 void LLSelectMgr::requestObjectPropertiesFamily(LLViewerObject* object)
04099 {
04100 LLMessageSystem* msg = gMessageSystem;
04101
04102 msg->newMessageFast(_PREHASH_RequestObjectPropertiesFamily);
04103 msg->nextBlockFast(_PREHASH_AgentData);
04104 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
04105 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
04106 msg->nextBlockFast(_PREHASH_ObjectData);
04107 msg->addU32Fast(_PREHASH_RequestFlags, 0x0 );
04108 msg->addUUIDFast(_PREHASH_ObjectID, object->mID );
04109
04110 LLViewerRegion* regionp = object->getRegion();
04111 msg->sendReliable( regionp->getHost() );
04112 }
04113
04114
04115
04116 void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data)
04117 {
04118 S32 i;
04119 S32 count = msg->getNumberOfBlocksFast(_PREHASH_ObjectData);
04120 for (i = 0; i < count; i++)
04121 {
04122 LLUUID id;
04123 msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, id, i);
04124
04125 LLUUID creator_id;
04126 LLUUID owner_id;
04127 LLUUID group_id;
04128 LLUUID last_owner_id;
04129 U64 creation_date;
04130 LLUUID extra_id;
04131 U32 base_mask, owner_mask, group_mask, everyone_mask, next_owner_mask;
04132 LLSaleInfo sale_info;
04133 LLCategory category;
04134 LLAggregatePermissions ag_perms;
04135 LLAggregatePermissions ag_texture_perms;
04136 LLAggregatePermissions ag_texture_perms_owner;
04137
04138 msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_CreatorID, creator_id, i);
04139 msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id, i);
04140 msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_GroupID, group_id, i);
04141 msg->getU64Fast(_PREHASH_ObjectData, _PREHASH_CreationDate, creation_date, i);
04142 msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_BaseMask, base_mask, i);
04143 msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_OwnerMask, owner_mask, i);
04144 msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_GroupMask, group_mask, i);
04145 msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_EveryoneMask, everyone_mask, i);
04146 msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_NextOwnerMask, next_owner_mask, i);
04147 sale_info.unpackMultiMessage(msg, _PREHASH_ObjectData, i);
04148
04149 ag_perms.unpackMessage(msg, _PREHASH_ObjectData, _PREHASH_AggregatePerms, i);
04150 ag_texture_perms.unpackMessage(msg, _PREHASH_ObjectData, _PREHASH_AggregatePermTextures, i);
04151 ag_texture_perms_owner.unpackMessage(msg, _PREHASH_ObjectData, _PREHASH_AggregatePermTexturesOwner, i);
04152 category.unpackMultiMessage(msg, _PREHASH_ObjectData, i);
04153
04154 S16 inv_serial = 0;
04155 msg->getS16Fast(_PREHASH_ObjectData, _PREHASH_InventorySerial, inv_serial, i);
04156
04157 LLUUID item_id;
04158 msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ItemID, item_id, i);
04159 LLUUID folder_id;
04160 msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FolderID, folder_id, i);
04161 LLUUID from_task_id;
04162 msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FromTaskID, from_task_id, i);
04163
04164 msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_LastOwnerID, last_owner_id, i);
04165
04166 char name[DB_INV_ITEM_NAME_BUF_SIZE];
04167 msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Name, DB_INV_ITEM_NAME_BUF_SIZE, name, i);
04168 char desc[DB_INV_ITEM_DESC_BUF_SIZE];
04169 msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Description, DB_INV_ITEM_DESC_BUF_SIZE, desc, i);
04170
04171 char touch_name[DB_INV_ITEM_NAME_BUF_SIZE];
04172 msg->getStringFast(_PREHASH_ObjectData, _PREHASH_TouchName, DB_INV_ITEM_NAME_BUF_SIZE, touch_name, i);
04173 char sit_name[DB_INV_ITEM_DESC_BUF_SIZE];
04174 msg->getStringFast(_PREHASH_ObjectData, _PREHASH_SitName, DB_INV_ITEM_DESC_BUF_SIZE, sit_name, i);
04175
04176
04177 std::vector<LLUUID> texture_ids;
04178 S32 size = msg->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_TextureID);
04179 if (size > 0)
04180 {
04181 S8 packed_buffer[SELECT_MAX_TES * UUID_BYTES];
04182 msg->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextureID, packed_buffer, 0, i, SELECT_MAX_TES * UUID_BYTES);
04183
04184 for (S32 buf_offset = 0; buf_offset < size; buf_offset += UUID_BYTES)
04185 {
04186 LLUUID tid;
04187 memcpy(tid.mData, packed_buffer + buf_offset, UUID_BYTES);
04188 texture_ids.push_back(tid);
04189 }
04190 }
04191
04192
04193
04194 struct f : public LLSelectedNodeFunctor
04195 {
04196 LLUUID mID;
04197 f(const LLUUID& id) : mID(id) {}
04198 virtual bool apply(LLSelectNode* node)
04199 {
04200 return (node->getObject()->mID == mID);
04201 }
04202 } func(id);
04203 LLSelectNode* node = gSelectMgr->getSelection()->getFirstNode(&func);
04204
04205 if (node)
04206 {
04207 if (node->mInventorySerial != inv_serial)
04208 {
04209 node->getObject()->dirtyInventory();
04210 }
04211
04212
04213 if (!node->mValid)
04214 {
04215 BOOL can_copy = FALSE;
04216 BOOL can_transfer = FALSE;
04217
04218 LLAggregatePermissions::EValue value = LLAggregatePermissions::AP_NONE;
04219 if(node->getObject()->permYouOwner())
04220 {
04221 value = ag_texture_perms_owner.getValue(PERM_COPY);
04222 if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL)
04223 {
04224 can_copy = TRUE;
04225 }
04226 value = ag_texture_perms_owner.getValue(PERM_TRANSFER);
04227 if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL)
04228 {
04229 can_transfer = TRUE;
04230 }
04231 }
04232 else
04233 {
04234 value = ag_texture_perms.getValue(PERM_COPY);
04235 if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL)
04236 {
04237 can_copy = TRUE;
04238 }
04239 value = ag_texture_perms.getValue(PERM_TRANSFER);
04240 if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL)
04241 {
04242 can_transfer = TRUE;
04243 }
04244 }
04245
04246 if (can_copy && can_transfer)
04247 {
04248
04249 node->saveTextures(texture_ids);
04250 }
04251 }
04252
04253 node->mValid = TRUE;
04254 node->mPermissions->init(creator_id, owner_id,
04255 last_owner_id, group_id);
04256 node->mPermissions->initMasks(base_mask, owner_mask, everyone_mask, group_mask, next_owner_mask);
04257 node->mCreationDate = creation_date;
04258 node->mItemID = item_id;
04259 node->mFolderID = folder_id;
04260 node->mFromTaskID = from_task_id;
04261 node->mName.assign(name);
04262 node->mDescription.assign(desc);
04263 node->mSaleInfo = sale_info;
04264 node->mAggregatePerm = ag_perms;
04265 node->mAggregateTexturePerm = ag_texture_perms;
04266 node->mAggregateTexturePermOwner = ag_texture_perms_owner;
04267 node->mCategory = category;
04268 node->mInventorySerial = inv_serial;
04269 node->mSitName.assign(sit_name);
04270 node->mTouchName.assign(touch_name);
04271 }
04272 }
04273
04274 dialog_refresh_all();
04275
04276
04277 if(gPopupMenuView->getVisible())
04278 {
04279 gPopupMenuView->setItemEnabled(SAVE_INTO_INVENTORY,
04280 enable_save_into_inventory(NULL));
04281 }
04282
04283
04284 LLToolPie::selectionPropertiesReceived();
04285 }
04286
04287
04288 void LLSelectMgr::processObjectPropertiesFamily(LLMessageSystem* msg, void** user_data)
04289 {
04290 LLUUID id;
04291
04292 U32 request_flags;
04293 LLUUID creator_id;
04294 LLUUID owner_id;
04295 LLUUID group_id;
04296 LLUUID extra_id;
04297 U32 base_mask, owner_mask, group_mask, everyone_mask, next_owner_mask;
04298 LLSaleInfo sale_info;
04299 LLCategory category;
04300
04301 msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_RequestFlags, request_flags );
04302 msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, id );
04303 msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id );
04304 msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_GroupID, group_id );
04305 msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_BaseMask, base_mask );
04306 msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_OwnerMask, owner_mask );
04307 msg->getU32Fast(_PREHASH_ObjectData,_PREHASH_GroupMask, group_mask );
04308 msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_EveryoneMask, everyone_mask );
04309 msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_NextOwnerMask, next_owner_mask);
04310 sale_info.unpackMessage(msg, _PREHASH_ObjectData);
04311 category.unpackMessage(msg, _PREHASH_ObjectData);
04312
04313 LLUUID last_owner_id;
04314 msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_LastOwnerID, last_owner_id );
04315
04316
04317 char name[DB_INV_ITEM_NAME_BUF_SIZE];
04318 msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Name, DB_INV_ITEM_NAME_BUF_SIZE, name);
04319
04320 char desc[DB_INV_ITEM_DESC_BUF_SIZE];
04321 msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Description, DB_INV_ITEM_DESC_BUF_SIZE, desc);
04322
04323
04324 if (request_flags & (COMPLAINT_REPORT_REQUEST | BUG_REPORT_REQUEST))
04325 {
04326 EReportType report_type = (COMPLAINT_REPORT_REQUEST & request_flags) ? COMPLAINT_REPORT : BUG_REPORT;
04327 LLFloaterReporter *reporterp = LLFloaterReporter::getReporter(report_type);
04328 if (reporterp)
04329 {
04330 char first_name[DB_FIRST_NAME_BUF_SIZE];
04331 char last_name[DB_LAST_NAME_BUF_SIZE];
04332 gCacheName->getName(owner_id, first_name, last_name);
04333 LLString fullname(first_name);
04334 fullname.append(" ");
04335 fullname.append(last_name);
04336 reporterp->setPickedObjectProperties(name, fullname, owner_id);
04337 }
04338 }
04339
04340
04341 struct f : public LLSelectedNodeFunctor
04342 {
04343 LLUUID mID;
04344 f(const LLUUID& id) : mID(id) {}
04345 virtual bool apply(LLSelectNode* node)
04346 {
04347 return (node->getObject()->mID == mID);
04348 }
04349 } func(id);
04350 LLSelectNode* node = gSelectMgr->getHoverObjects()->getFirstNode(&func);
04351
04352 if (node)
04353 {
04354 node->mValid = TRUE;
04355 node->mPermissions->init(LLUUID::null, owner_id,
04356 last_owner_id, group_id);
04357 node->mPermissions->initMasks(base_mask, owner_mask, everyone_mask, group_mask, next_owner_mask);
04358 node->mSaleInfo = sale_info;
04359 node->mCategory = category;
04360 node->mName.assign(name);
04361 node->mDescription.assign(desc);
04362 }
04363
04364 dialog_refresh_all();
04365 }
04366
04367
04368
04369 void LLSelectMgr::processForceObjectSelect(LLMessageSystem* msg, void**)
04370 {
04371 BOOL reset_list;
04372 msg->getBOOL("Header", "ResetList", reset_list);
04373
04374 if (reset_list)
04375 {
04376 gSelectMgr->deselectAll();
04377 }
04378
04379 LLUUID full_id;
04380 S32 local_id;
04381 LLViewerObject* object;
04382 std::vector<LLViewerObject*> objects;
04383 S32 i;
04384 S32 block_count = msg->getNumberOfBlocks("Data");
04385
04386 for (i = 0; i < block_count; i++)
04387 {
04388 msg->getS32("Data", "LocalID", local_id, i);
04389
04390 gObjectList.getUUIDFromLocal(full_id,
04391 local_id,
04392 msg->getSenderIP(),
04393 msg->getSenderPort());
04394 object = gObjectList.findObject(full_id);
04395 if (object)
04396 {
04397 objects.push_back(object);
04398 }
04399 }
04400
04401
04402 gSelectMgr->highlightObjectAndFamily(objects);
04403 }
04404
04405
04406 extern LLGLdouble gGLModelView[16];
04407
04408 void LLSelectMgr::updateSilhouettes()
04409 {
04410 S32 num_sils_genned = 0;
04411
04412 LLVector3d cameraPos = gAgent.getCameraPositionGlobal();
04413 F32 currentCameraZoom = gAgent.getCurrentCameraBuildOffset();
04414
04415 if (!mSilhouetteImagep)
04416 {
04417 LLUUID id;
04418 id.set( gViewerArt.getString("silhouette.tga") );
04419 mSilhouetteImagep = gImageList.getImage(id, TRUE, TRUE);
04420 }
04421
04422 mHighlightedObjects->cleanupNodes();
04423
04424 if((cameraPos - mLastCameraPos).magVecSquared() > SILHOUETTE_UPDATE_THRESHOLD_SQUARED * currentCameraZoom * currentCameraZoom)
04425 {
04426 struct f : public LLSelectedObjectFunctor
04427 {
04428 virtual bool apply(LLViewerObject* object)
04429 {
04430 object->setChanged(LLXform::SILHOUETTE);
04431 return true;
04432 }
04433 } func;
04434 getSelection()->applyToObjects(&func);
04435
04436 mLastCameraPos = gAgent.getCameraPositionGlobal();
04437 }
04438
04439 std::vector<LLViewerObject*> changed_objects;
04440
04441 if (mSelectedObjects->getNumNodes())
04442 {
04443
04444
04445
04446
04447
04448 for (S32 pass = 0; pass < 2; pass++)
04449 {
04450 for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
04451 iter != mSelectedObjects->end(); iter++)
04452 {
04453 LLSelectNode* node = *iter;
04454 LLViewerObject* objectp = node->getObject();
04455
04456
04457 BOOL roots_only = (pass == 0);
04458 BOOL is_root = (objectp->isRootEdit());
04459 if (roots_only != is_root || objectp->mDrawable.isNull())
04460 {
04461 continue;
04462 }
04463
04464 if (!node->mSilhouetteExists
04465 || objectp->isChanged(LLXform::SILHOUETTE)
04466 || (objectp->getParent() && objectp->getParent()->isChanged(LLXform::SILHOUETTE)))
04467 {
04468 if (num_sils_genned++ < MAX_SILS_PER_FRAME)
04469 {
04470 generateSilhouette(node, gCamera->getOrigin());
04471 changed_objects.push_back(objectp);
04472 }
04473 else if (objectp->isAttachment())
04474 {
04475
04476 LLViewerJointAttachment* attachment_pt = (LLViewerJointAttachment*)objectp->getRootEdit()->mDrawable->getParent();
04477 if (attachment_pt && attachment_pt->getIsHUDAttachment())
04478 {
04479 LLVector3 camera_pos = LLVector3(-10000.f, 0.f, 0.f);
04480 generateSilhouette(node, camera_pos);
04481 }
04482 }
04483 }
04484 }
04485 }
04486 }
04487
04488 if (mRectSelectedObjects.size() > 0)
04489 {
04490
04491
04492
04493
04494
04495 std::set<LLViewerObject*> roots;
04496
04497
04498
04499
04500
04501 BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts");
04502
04503
04504 for (std::set<LLPointer<LLViewerObject> >::iterator iter = mRectSelectedObjects.begin();
04505 iter != mRectSelectedObjects.end(); iter++)
04506 {
04507 LLViewerObject *objectp = *iter;
04508 if (select_linked_set)
04509 {
04510 LLViewerObject *rootp = (LLViewerObject*)objectp->getRoot();
04511 roots.insert(rootp);
04512 }
04513 else
04514 {
04515 roots.insert(objectp);
04516 }
04517 }
04518
04519
04520 std::vector<LLSelectNode*> remove_these_nodes;
04521 std::vector<LLViewerObject*> remove_these_roots;
04522
04523 for (LLObjectSelection::iterator iter = mHighlightedObjects->begin();
04524 iter != mHighlightedObjects->end(); iter++)
04525 {
04526 LLSelectNode* node = *iter;
04527 LLViewerObject* objectp = node->getObject();
04528 if (objectp->isRoot() || !select_linked_set)
04529 {
04530 if (roots.count(objectp) == 0)
04531 {
04532 remove_these_nodes.push_back(node);
04533 }
04534 else
04535 {
04536 remove_these_roots.push_back(objectp);
04537 }
04538 }
04539 else
04540 {
04541 LLViewerObject* rootp = (LLViewerObject*)objectp->getRoot();
04542
04543 if (roots.count(rootp) == 0)
04544 {
04545 remove_these_nodes.push_back(node);
04546 }
04547 }
04548 }
04549
04550
04551 for (std::vector<LLSelectNode*>::iterator iter = remove_these_nodes.begin();
04552 iter != remove_these_nodes.end(); ++iter)
04553 {
04554 LLSelectNode* nodep = *iter;
04555 mHighlightedObjects->removeNode(nodep);
04556 }
04557
04558
04559 for (std::vector<LLViewerObject*>::iterator iter = remove_these_roots.begin();
04560 iter != remove_these_roots.end(); ++iter)
04561 {
04562 LLViewerObject* objectp = *iter;
04563 roots.erase(objectp);
04564 }
04565
04566
04567 for (std::set<LLViewerObject*>::iterator iter = roots.begin();
04568 iter != roots.end(); iter++)
04569 {
04570 LLViewerObject* objectp = *iter;
04571 LLSelectNode* rect_select_root_node = new LLSelectNode(objectp, TRUE);
04572 rect_select_root_node->selectAllTEs(TRUE);
04573
04574 if (!canSelectObject(objectp))
04575 {
04576 continue;
04577 }
04578
04579 if (!select_linked_set)
04580 {
04581 rect_select_root_node->mIndividualSelection = TRUE;
04582 }
04583 else
04584 {
04585 for (LLViewerObject::child_list_t::iterator iter = objectp->mChildList.begin();
04586 iter != objectp->mChildList.end(); ++iter)
04587 {
04588 LLViewerObject* child_objectp = *iter;
04589
04590 if (!canSelectObject(child_objectp))
04591 {
04592 continue;
04593 }
04594
04595 LLSelectNode* rect_select_node = new LLSelectNode(child_objectp, TRUE);
04596 rect_select_node->selectAllTEs(TRUE);
04597 mHighlightedObjects->addNodeAtEnd(rect_select_node);
04598 }
04599 }
04600
04601
04602 mHighlightedObjects->addNodeAtEnd(rect_select_root_node);
04603 }
04604
04605 num_sils_genned = 0;
04606
04607
04608
04609 for (S32 pass = 0; pass < 2; pass++)
04610 {
04611 for (LLObjectSelection::iterator iter = mHighlightedObjects->begin();
04612 iter != mHighlightedObjects->end(); iter++)
04613 {
04614 LLSelectNode* node = *iter;
04615 LLViewerObject* objectp = node->getObject();
04616
04617
04618 BOOL roots_only = (pass == 0);
04619 BOOL is_root = objectp->isRootEdit();
04620 if (roots_only != is_root)
04621 {
04622 continue;
04623 }
04624
04625 if (!node->mSilhouetteExists
04626 || objectp->isChanged(LLXform::SILHOUETTE)
04627 || (objectp->getParent() && objectp->getParent()->isChanged(LLXform::SILHOUETTE)))
04628 {
04629 if (num_sils_genned++ < MAX_SILS_PER_FRAME)
04630 {
04631 generateSilhouette(node, gCamera->getOrigin());
04632 changed_objects.push_back(objectp);
04633 }
04634 else if (objectp->isAttachment() && objectp->getRootEdit()->mDrawable.notNull())
04635 {
04636
04637 LLViewerJointAttachment* attachment_pt = (LLViewerJointAttachment*)objectp->getRootEdit()->mDrawable->getParent();
04638 if (attachment_pt && attachment_pt->getIsHUDAttachment())
04639 {
04640 LLVector3 camera_pos = LLVector3(-10000.f, 0.f, 0.f);
04641 generateSilhouette(node, camera_pos);
04642 }
04643 }
04644 }
04645
04646
04647
04648
04649
04650
04651
04652
04653
04654
04655
04656 }
04657 }
04658
04659 }
04660 else
04661 {
04662 mHighlightedObjects->deleteAllNodes();
04663 }
04664
04665 for (std::vector<LLViewerObject*>::iterator iter = changed_objects.begin();
04666 iter != changed_objects.end(); ++iter)
04667 {
04668
04669 LLViewerObject* objectp = *iter;
04670 objectp->clearChanged(LLXform::MOVED | LLXform::SILHOUETTE);
04671 }
04672
04673
04674 }
04675
04676 void LLSelectMgr::renderSilhouettes(BOOL for_hud)
04677 {
04678 if (!mRenderSilhouettes)
04679 {
04680 return;
04681 }
04682
04683 LLViewerImage::bindTexture(mSilhouetteImagep);
04684 LLGLSPipelineSelection gls_select;
04685 glAlphaFunc(GL_GREATER, 0.0f);
04686 LLGLEnable blend(GL_BLEND);
04687 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
04688
04689 LLVOAvatar* avatar = gAgent.getAvatarObject();
04690 if (for_hud && avatar)
04691 {
04692 LLBBox hud_bbox = avatar->getHUDBBox();
04693
04694 F32 cur_zoom = avatar->mHUDCurZoom;
04695
04696
04697 glMatrixMode(GL_PROJECTION);
04698 glPushMatrix();
04699 glLoadIdentity();
04700 F32 depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f);
04701 glOrtho(-0.5f * gCamera->getAspect(), 0.5f * gCamera->getAspect(), -0.5f, 0.5f, 0.f, depth);
04702
04703 glMatrixMode(GL_MODELVIEW);
04704 glPushMatrix();
04705 glLoadIdentity();
04706 glLoadMatrixf(OGL_TO_CFR_ROTATION);
04707 glTranslatef(-hud_bbox.getCenterLocal().mV[VX] + (depth *0.5f), 0.f, 0.f);
04708 glScalef(cur_zoom, cur_zoom, cur_zoom);
04709 }
04710 if (mSelectedObjects->getNumNodes())
04711 {
04712 LLUUID inspect_item_id = LLFloaterInspect::getSelectedUUID();
04713 for (S32 pass = 0; pass < 2; pass++)
04714 {
04715 for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
04716 iter != mSelectedObjects->end(); iter++)
04717 {
04718 LLSelectNode* node = *iter;
04719 LLViewerObject* objectp = node->getObject();
04720 if (objectp->isHUDAttachment() != for_hud)
04721 {
04722 continue;
04723 }
04724 if(objectp->getID() == inspect_item_id)
04725 {
04726 node->renderOneSilhouette(sHighlightInspectColor);
04727 }
04728 else if (node->isTransient())
04729 {
04730 BOOL oldHidden = LLSelectMgr::sRenderHiddenSelections;
04731 LLSelectMgr::sRenderHiddenSelections = FALSE;
04732 node->renderOneSilhouette(sContextSilhouetteColor);
04733 LLSelectMgr::sRenderHiddenSelections = oldHidden;
04734 }
04735 else if (objectp->isRootEdit())
04736 {
04737 node->renderOneSilhouette(sSilhouetteParentColor);
04738 }
04739 else
04740 {
04741 node->renderOneSilhouette(sSilhouetteChildColor);
04742 }
04743 }
04744 }
04745 }
04746
04747 if (mHighlightedObjects->getNumNodes())
04748 {
04749
04750 BOOL subtracting_from_selection = (gKeyboard->currentMask(TRUE) == MASK_CONTROL);
04751 for (S32 pass = 0; pass < 2; pass++)
04752 {
04753 for (LLObjectSelection::iterator iter = mHighlightedObjects->begin();
04754 iter != mHighlightedObjects->end(); iter++)
04755 {
04756 LLSelectNode* node = *iter;
04757 LLViewerObject* objectp = node->getObject();
04758 if (objectp->isHUDAttachment() != for_hud)
04759 {
04760 continue;
04761 }
04762
04763 if (subtracting_from_selection)
04764 {
04765 node->renderOneSilhouette(LLColor4::red);
04766 }
04767 else if (!objectp->isSelected())
04768 {
04769 LLColor4 highlight_color = objectp->isRoot() ? sHighlightParentColor : sHighlightChildColor;
04770 node->renderOneSilhouette(highlight_color);
04771 }
04772 }
04773 }
04774 }
04775
04776 if (for_hud && avatar)
04777 {
04778 glMatrixMode(GL_PROJECTION);
04779 glPopMatrix();
04780
04781 glMatrixMode(GL_MODELVIEW);
04782 glPopMatrix();
04783 stop_glerror();
04784 }
04785
04786 mSilhouetteImagep->unbindTexture(0, GL_TEXTURE_2D);
04787 glAlphaFunc(GL_GREATER, 0.01f);
04788 }
04789
04790 void LLSelectMgr::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point)
04791 {
04792 LLViewerObject* objectp = nodep->getObject();
04793
04794 if (objectp && objectp->getPCode() == LL_PCODE_VOLUME)
04795 {
04796 ((LLVOVolume*)objectp)->generateSilhouette(nodep, view_point);
04797 }
04798 }
04799
04800
04801
04802
04803 LLSelectNode::LLSelectNode(LLViewerObject* object, BOOL glow)
04804 {
04805 mObject = object;
04806 selectAllTEs(FALSE);
04807 mIndividualSelection = FALSE;
04808 mTransient = FALSE;
04809 mValid = FALSE;
04810 mPermissions = new LLPermissions();
04811 mInventorySerial = 0;
04812 mName = LLString::null;
04813 mDescription = LLString::null;
04814 mTouchName = LLString::null;
04815 mSitName = LLString::null;
04816 mSilhouetteExists = FALSE;
04817 mDuplicated = FALSE;
04818
04819 saveColors();
04820 }
04821
04822 LLSelectNode::LLSelectNode(const LLSelectNode& nodep)
04823 {
04824 S32 i;
04825 for (i = 0; i < SELECT_MAX_TES; i++)
04826 {
04827 mTESelected[i] = nodep.mTESelected[i];
04828 }
04829 mLastTESelected = nodep.mLastTESelected;
04830
04831 mIndividualSelection = nodep.mIndividualSelection;
04832
04833 mValid = nodep.mValid;
04834 mTransient = nodep.mTransient;
04835 mPermissions = new LLPermissions(*nodep.mPermissions);
04836 mSaleInfo = nodep.mSaleInfo;;
04837 mAggregatePerm = nodep.mAggregatePerm;
04838 mAggregateTexturePerm = nodep.mAggregateTexturePerm;
04839 mAggregateTexturePermOwner = nodep.mAggregateTexturePermOwner;
04840 mName = nodep.mName;
04841 mDescription = nodep.mDescription;
04842 mCategory = nodep.mCategory;
04843 mSavedPositionLocal = nodep.mSavedPositionLocal;
04844 mSavedPositionGlobal = nodep.mSavedPositionGlobal;
04845 mSavedScale = nodep.mSavedScale;
04846 mSavedRotation = nodep.mSavedRotation;
04847 mDuplicated = nodep.mDuplicated;
04848 mDuplicatePos = nodep.mDuplicatePos;
04849 mDuplicateRot = nodep.mDuplicateRot;
04850 mItemID = nodep.mItemID;
04851 mFolderID = nodep.mFolderID;
04852 mFromTaskID = nodep.mFromTaskID;
04853 mTouchName = nodep.mTouchName;
04854 mSitName = nodep.mSitName;
04855
04856 mSilhouetteVertices = nodep.mSilhouetteVertices;
04857 mSilhouetteNormals = nodep.mSilhouetteNormals;
04858 mSilhouetteSegments = nodep.mSilhouetteSegments;
04859 mSilhouetteExists = nodep.mSilhouetteExists;
04860 mObject = nodep.mObject;
04861
04862 std::vector<LLColor4>::const_iterator color_iter;
04863 mSavedColors.clear();
04864 for (color_iter = nodep.mSavedColors.begin(); color_iter != nodep.mSavedColors.end(); ++color_iter)
04865 {
04866 mSavedColors.push_back(*color_iter);
04867 }
04868
04869 saveTextures(nodep.mSavedTextures);
04870 }
04871
04872 LLSelectNode::~LLSelectNode()
04873 {
04874 delete mPermissions;
04875 mPermissions = NULL;
04876 }
04877
04878 void LLSelectNode::selectAllTEs(BOOL b)
04879 {
04880 for (S32 i = 0; i < SELECT_MAX_TES; i++)
04881 {
04882 mTESelected[i] = b;
04883 }
04884 mLastTESelected = 0;
04885 }
04886
04887 void LLSelectNode::selectTE(S32 te_index, BOOL selected)
04888 {
04889 if (te_index < 0 || te_index >= SELECT_MAX_TES)
04890 {
04891 return;
04892 }
04893 mTESelected[te_index] = selected;
04894 mLastTESelected = te_index;
04895 }
04896
04897 BOOL LLSelectNode::isTESelected(S32 te_index)
04898 {
04899 if (te_index < 0 || te_index >= mObject->getNumTEs())
04900 {
04901 return FALSE;
04902 }
04903 return mTESelected[te_index];
04904 }
04905
04906 S32 LLSelectNode::getLastSelectedTE()
04907 {
04908 if (!isTESelected(mLastTESelected))
04909 {
04910 return -1;
04911 }
04912 return mLastTESelected;
04913 }
04914
04915 LLViewerObject* LLSelectNode::getObject()
04916 {
04917 if (!mObject)
04918 {
04919 return NULL;
04920 }
04921 else if (mObject->isDead())
04922 {
04923 mObject = NULL;
04924 }
04925 return mObject;
04926 }
04927
04928 void LLSelectNode::setObject(LLViewerObject* object)
04929 {
04930 mObject = object;
04931 }
04932
04933 void LLSelectNode::saveColors()
04934 {
04935 if (mObject.notNull())
04936 {
04937 mSavedColors.clear();
04938 for (S32 i = 0; i < mObject->getNumTEs(); i++)
04939 {
04940 const LLTextureEntry* tep = mObject->getTE(i);
04941 mSavedColors.push_back(tep->getColor());
04942 }
04943 }
04944 }
04945
04946 void LLSelectNode::saveTextures(const std::vector<LLUUID>& textures)
04947 {
04948 if (mObject.notNull())
04949 {
04950 mSavedTextures.clear();
04951
04952 for (std::vector<LLUUID>::const_iterator texture_it = textures.begin();
04953 texture_it != textures.end(); ++texture_it)
04954 {
04955 mSavedTextures.push_back(*texture_it);
04956 }
04957 }
04958 }
04959
04960 void LLSelectNode::saveTextureScaleRatios()
04961 {
04962 mTextureScaleRatios.clear();
04963 if (mObject.notNull())
04964 {
04965 for (U8 i = 0; i < mObject->getNumTEs(); i++)
04966 {
04967 F32 s,t;
04968 const LLTextureEntry* tep = mObject->getTE(i);
04969 tep->getScale(&s,&t);
04970 U32 s_axis = 0;
04971 U32 t_axis = 0;
04972
04973 LLPrimitive::getTESTAxes(i, &s_axis, &t_axis);
04974
04975 LLVector3 v;
04976 LLVector3 scale = mObject->getScale();
04977
04978 if (tep->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR)
04979 {
04980 v.mV[s_axis] = s*scale.mV[s_axis];
04981 v.mV[t_axis] = t*scale.mV[t_axis];
04982 }
04983 else
04984 {
04985 v.mV[s_axis] = s/scale.mV[s_axis];
04986 v.mV[t_axis] = t/scale.mV[t_axis];
04987 }
04988
04989 mTextureScaleRatios.push_back(v);
04990 }
04991 }
04992 }
04993
04994
04995
04996 BOOL LLSelectNode::allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const
04997 {
04998
04999 BOOL object_is_group_owned = FALSE;
05000 LLUUID object_owner_id;
05001 mPermissions->getOwnership(object_owner_id, object_is_group_owned);
05002
05003
05004 if (!mObject || (mObject->isDead()) || !mPermissions->isOwned())
05005 {
05006 return FALSE;
05007 }
05008
05009
05010 if (PERM_TRANSFER == op)
05011 {
05012
05013 if ( !object_is_group_owned
05014 && (gAgent.getID() == object_owner_id) )
05015 {
05016 return TRUE;
05017 }
05018 else
05019 {
05020
05021 return mObject->permTransfer();
05022 }
05023 }
05024
05025 if (PERM_MOVE == op
05026 || PERM_MODIFY == op)
05027 {
05028
05029
05030 if (mObject->isAttachment() && object_owner_id != gAgent.getID())
05031 {
05032 return FALSE;
05033 }
05034 }
05035
05036
05037
05038
05039 LLUUID group_id = LLUUID::null;
05040 LLUUID proxy_agent_id = gAgent.getID();
05041
05042
05043 if (gAgent.isGodlike())
05044 {
05045 return TRUE;
05046 }
05047
05048
05049 LLUUID object_group_id = mPermissions->getGroup();
05050 if (object_group_id.notNull() &&
05051 gAgent.isInGroup(object_group_id))
05052 {
05053
05054 group_id = object_group_id;
05055 }
05056
05057
05058
05059
05060
05061 if (PERM_COPY != op || mPermissions->allowTransferTo(gAgent.getID()))
05062 {
05063
05064 if ( ( object_is_group_owned
05065 && gAgent.hasPowerInGroup(object_owner_id, group_proxy_power))
05066
05067 || ( (PERM_MOVE == op || PERM_MODIFY == op || PERM_COPY == op)
05068 && (!object_is_group_owned
05069 && gAgent.isGrantedProxy(*mPermissions))))
05070 {
05071
05072 proxy_agent_id = object_owner_id;
05073 }
05074 }
05075
05076
05077 if (PERM_OWNER == op)
05078 {
05079
05080 return (proxy_agent_id == object_owner_id ? TRUE : FALSE);
05081 }
05082
05083
05084 return (mPermissions->allowOperationBy(op, proxy_agent_id, group_id));
05085 }
05086
05087
05088
05089
05090 void LLSelectNode::renderOneSilhouette(const LLColor4 &color)
05091 {
05092 LLViewerObject* objectp = getObject();
05093 if (!objectp)
05094 {
05095 return;
05096 }
05097
05098 LLDrawable* drawable = objectp->mDrawable;
05099 if(!drawable)
05100 {
05101 return;
05102 }
05103
05104 if (!mSilhouetteExists)
05105 {
05106 return;
05107 }
05108
05109 BOOL is_hud_object = objectp->isHUDAttachment();
05110
05111 if (mSilhouetteVertices.size() == 0 || mSilhouetteNormals.size() != mSilhouetteVertices.size())
05112 {
05113 return;
05114 }
05115
05116 glMatrixMode(GL_MODELVIEW);
05117 glPushMatrix();
05118 if (!is_hud_object)
05119 {
05120 glLoadIdentity();
05121 glMultMatrixd(gGLModelView);
05122 }
05123
05124
05125 if (drawable->isActive())
05126 {
05127 glMultMatrixf((F32*) objectp->getRenderMatrix().mMatrix);
05128 }
05129
05130 LLVolume *volume = objectp->getVolume();
05131 if (volume)
05132 {
05133 F32 silhouette_thickness;
05134 if (is_hud_object && gAgent.getAvatarObject())
05135 {
05136 silhouette_thickness = LLSelectMgr::sHighlightThickness / gAgent.getAvatarObject()->mHUDCurZoom;
05137 }
05138 else
05139 {
05140 LLVector3 view_vector = gCamera->getOrigin() - objectp->getRenderPosition();
05141 silhouette_thickness = view_vector.magVec() * LLSelectMgr::sHighlightThickness * (gCamera->getView() / gCamera->getDefaultFOV());
05142 }
05143 F32 animationTime = (F32)LLFrameTimer::getElapsedSeconds();
05144
05145 F32 u_coord = fmod(animationTime * LLSelectMgr::sHighlightUAnim, 1.f);
05146 F32 v_coord = 1.f - fmod(animationTime * LLSelectMgr::sHighlightVAnim, 1.f);
05147 F32 u_divisor = 1.f / ((F32)(mSilhouetteVertices.size() - 1));
05148
05149 if (LLSelectMgr::sRenderHiddenSelections)
05150 {
05151 glBlendFunc(GL_SRC_COLOR, GL_ONE);
05152 LLGLEnable fog(GL_FOG);
05153 glFogi(GL_FOG_MODE, GL_LINEAR);
05154 float d = (gCamera->getPointOfInterest()-gCamera->getOrigin()).magVec();
05155 LLColor4 fogCol = color * (F32)llclamp((gSelectMgr->getSelectionCenterGlobal()-gAgent.getCameraPositionGlobal()).magVec()/(gSelectMgr->getBBoxOfSelection().getExtentLocal().magVec()*4), 0.0, 1.0);
05156 glFogf(GL_FOG_START, d);
05157 glFogf(GL_FOG_END, d*(1 + (gCamera->getView() / gCamera->getDefaultFOV())));
05158 glFogfv(GL_FOG_COLOR, fogCol.mV);
05159
05160 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL);
05161 glAlphaFunc(GL_GREATER, 0.01f);
05162 glBegin(GL_LINES);
05163 {
05164 S32 i = 0;
05165 for (S32 seg_num = 0; seg_num < (S32)mSilhouetteSegments.size(); seg_num++)
05166 {
05167 for(; i < mSilhouetteSegments[seg_num]; i++)
05168 {
05169 u_coord += u_divisor * LLSelectMgr::sHighlightUScale;
05170
05171 glColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
05172 glTexCoord2f( u_coord, v_coord );
05173 glVertex3fv( mSilhouetteVertices[i].mV );
05174 }
05175 }
05176 }
05177 glEnd();
05178 u_coord = fmod(animationTime * LLSelectMgr::sHighlightUAnim, 1.f);
05179 }
05180
05181 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
05182 glBegin(GL_TRIANGLES);
05183 {
05184 S32 i = 0;
05185 for (S32 seg_num = 0; seg_num < (S32)mSilhouetteSegments.size(); seg_num++)
05186 {
05187 S32 first_i = i;
05188 LLVector3 v;
05189 LLVector2 t;
05190
05191 for(; i < mSilhouetteSegments[seg_num]; i++)
05192 {
05193
05194 if (i == first_i) {
05195 LLVector3 vert = (mSilhouetteNormals[i]) * silhouette_thickness;
05196 vert += mSilhouetteVertices[i];
05197
05198 glColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.0f);
05199 glTexCoord2f( u_coord, v_coord + LLSelectMgr::sHighlightVScale );
05200 glVertex3fv( vert.mV );
05201
05202 u_coord += u_divisor * LLSelectMgr::sHighlightUScale;
05203
05204 glColor4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha*2);
05205 glTexCoord2f( u_coord, v_coord );
05206 glVertex3fv( mSilhouetteVertices[i].mV );
05207
05208 v = mSilhouetteVertices[i];
05209 t = LLVector2(u_coord, v_coord);
05210 }
05211 else {
05212 LLVector3 vert = (mSilhouetteNormals[i]) * silhouette_thickness;
05213 vert += mSilhouetteVertices[i];
05214
05215 glColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.0f);
05216 glTexCoord2f( u_coord, v_coord + LLSelectMgr::sHighlightVScale );
05217 glVertex3fv( vert.mV );
05218 glVertex3fv( vert.mV );
05219
05220 glTexCoord2fv(t.mV);
05221 u_coord += u_divisor * LLSelectMgr::sHighlightUScale;
05222 glColor4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha*2);
05223 glVertex3fv(v.mV);
05224 glTexCoord2f( u_coord, v_coord );
05225 glVertex3fv( mSilhouetteVertices[i].mV );
05226
05227 }
05228 }
05229 }
05230 }
05231 glEnd();
05232
05233 }
05234 glPopMatrix();
05235 }
05236
05237
05238
05239
05240
05241
05242 void dialog_refresh_all()
05243 {
05244 if (gNoRender)
05245 {
05246 return;
05247 }
05248
05249
05250
05251 gFloaterTools->dirty();
05252
05253 if( gPieObject->getVisible() )
05254 {
05255 gPieObject->arrange();
05256 }
05257
05258 LLFloaterProperties::dirtyAll();
05259 LLFloaterInspect::dirty();
05260 }
05261
05262 S32 get_family_count(LLViewerObject *parent)
05263 {
05264 if (!parent)
05265 {
05266 llwarns << "Trying to get_family_count on null parent!" << llendl;
05267 }
05268 S32 count = 1;
05269 for (LLViewerObject::child_list_t::iterator iter = parent->mChildList.begin();
05270 iter != parent->mChildList.end(); ++iter)
05271 {
05272 LLViewerObject* child = *iter;
05273
05274 if (!child)
05275 {
05276 llwarns << "Family object has NULL child! Show Doug." << llendl;
05277 }
05278 else if (child->isDead())
05279 {
05280 llwarns << "Family object has dead child object. Show Doug." << llendl;
05281 }
05282 else
05283 {
05284 if (gSelectMgr->canSelectObject(child))
05285 {
05286 count += get_family_count( child );
05287 }
05288 }
05289 }
05290 return count;
05291 }
05292
05293
05294
05295
05296 void LLSelectMgr::updateSelectionCenter()
05297 {
05298 const F32 MOVE_SELECTION_THRESHOLD = 1.f;
05299
05300
05301
05302
05303 overrideObjectUpdates();
05304
05305 LLViewerObject* object = mSelectedObjects->getFirstObject();
05306 if (!object)
05307 {
05308
05309
05310 mSelectionCenterGlobal.clearVec();
05311 mShowSelection = FALSE;
05312 mSelectionBBox = LLBBox();
05313 mPauseRequest = NULL;
05314 resetAgentHUDZoom();
05315
05316 }
05317 else
05318 {
05319 mSelectedObjects->mSelectType = getSelectTypeForObject(object);
05320
05321 if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT && gAgent.getAvatarObject())
05322 {
05323 mPauseRequest = gAgent.getAvatarObject()->requestPause();
05324 }
05325 else
05326 {
05327 mPauseRequest = NULL;
05328 }
05329
05330 if (mSelectedObjects->mSelectType != SELECT_TYPE_HUD && gAgent.getAvatarObject())
05331 {
05332
05333 gAgent.getAvatarObject()->mHUDTargetZoom = 1.f;
05334 gAgent.getAvatarObject()->mHUDCurZoom = 1.f;
05335 }
05336
05337 mShowSelection = FALSE;
05338 LLBBox bbox;
05339
05340
05341 LLVector3d select_center;
05342
05343
05344 std::vector < LLViewerObject *> jointed_objects;
05345
05346 for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
05347 iter != mSelectedObjects->end(); iter++)
05348 {
05349 LLSelectNode* node = *iter;
05350 LLViewerObject* object = node->getObject();
05351 LLViewerObject *myAvatar = gAgent.getAvatarObject();
05352 LLViewerObject *root = object->getRootEdit();
05353 if (mSelectedObjects->mSelectType == SELECT_TYPE_WORLD &&
05354 !root->isChild(myAvatar) &&
05355 !object->isAvatar())
05356 {
05357 mShowSelection = TRUE;
05358 }
05359
05360 bbox.addBBoxAgent( object->getBoundingBoxAgent() );
05361
05362 if (object->isJointChild())
05363 {
05364 jointed_objects.push_back(object);
05365 }
05366 }
05367
05368 LLVector3 bbox_center_agent = bbox.getCenterAgent();
05369 mSelectionCenterGlobal = gAgent.getPosGlobalFromAgent(bbox_center_agent);
05370 mSelectionBBox = bbox;
05371
05372 }
05373
05374 if ( !(gAgentID == LLUUID::null) && gToolMgr)
05375 {
05376 LLTool *tool = gToolMgr->getCurrentTool();
05377 if (mShowSelection)
05378 {
05379 LLVector3d select_center_global;
05380
05381 if( tool->isEditing() )
05382 {
05383 select_center_global = tool->getEditingPointGlobal();
05384 }
05385 else
05386 {
05387 select_center_global = mSelectionCenterGlobal;
05388 }
05389
05390
05391 LLVector3d diff;
05392 diff = select_center_global - mLastSentSelectionCenterGlobal;
05393
05394 if ( diff.magVecSquared() > MOVE_SELECTION_THRESHOLD*MOVE_SELECTION_THRESHOLD )
05395 {
05396
05397 mLastSentSelectionCenterGlobal = select_center_global;
05398 }
05399 }
05400 }
05401
05402
05403 if (gEditMenuHandler == this && mSelectedObjects->getObjectCount() == 0)
05404 {
05405 gEditMenuHandler = NULL;
05406 }
05407 }
05408
05409 void LLSelectMgr::updatePointAt()
05410 {
05411 if (mShowSelection)
05412 {
05413 if (mSelectedObjects->getObjectCount())
05414 {
05415 LLVector3 select_offset;
05416 LLViewerObject *click_object = gObjectList.findObject(gLastHitObjectID);
05417 if (click_object && click_object->isSelected())
05418 {
05419
05420 select_offset.setVec(gLastHitObjectOffset);
05421 select_offset.rotVec(~click_object->getRenderRotation());
05422
05423 gAgent.setPointAt(POINTAT_TARGET_SELECT, click_object, select_offset);
05424 gAgent.setLookAt(LOOKAT_TARGET_SELECT, click_object, select_offset);
05425 }
05426 else
05427 {
05428
05429 gAgent.setPointAt(POINTAT_TARGET_SELECT, mSelectedObjects->getFirstObject());
05430 gAgent.setLookAt(LOOKAT_TARGET_SELECT, mSelectedObjects->getFirstObject());
05431 }
05432 }
05433 else
05434 {
05435 gAgent.setPointAt(POINTAT_TARGET_CLEAR);
05436 gAgent.setLookAt(LOOKAT_TARGET_CLEAR);
05437 }
05438 }
05439 else
05440 {
05441 gAgent.setPointAt(POINTAT_TARGET_CLEAR);
05442 gAgent.setLookAt(LOOKAT_TARGET_CLEAR);
05443 }
05444 }
05445
05446
05447
05448
05449 LLBBox LLSelectMgr::getBBoxOfSelection() const
05450 {
05451 return mSelectionBBox;
05452 }
05453
05454
05455
05456
05457
05458 BOOL LLSelectMgr::canUndo()
05459 {
05460 return mSelectedObjects->getFirstEditableObject() != NULL;
05461 }
05462
05463
05464
05465
05466 void LLSelectMgr::undo()
05467 {
05468 BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts");
05469 LLUUID group_id(gAgent.getGroupID());
05470 sendListToRegions("Undo", packAgentAndSessionAndGroupID, packObjectID, &group_id, select_linked_set ? SEND_ONLY_ROOTS : SEND_CHILDREN_FIRST);
05471 }
05472
05473
05474
05475
05476 BOOL LLSelectMgr::canRedo()
05477 {
05478 return mSelectedObjects->getFirstEditableObject() != NULL;
05479 }
05480
05481
05482
05483
05484 void LLSelectMgr::redo()
05485 {
05486 BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts");
05487 LLUUID group_id(gAgent.getGroupID());
05488 sendListToRegions("Redo", packAgentAndSessionAndGroupID, packObjectID, &group_id, select_linked_set ? SEND_ONLY_ROOTS : SEND_CHILDREN_FIRST);
05489 }
05490
05491
05492
05493
05494 BOOL LLSelectMgr::canDoDelete()
05495 {
05496
05497 return mSelectedObjects->getFirstDeleteableObject() != NULL;
05498 }
05499
05500
05501
05502
05503 void LLSelectMgr::doDelete()
05504 {
05505 selectDelete();
05506 }
05507
05508
05509
05510
05511 BOOL LLSelectMgr::canDeselect()
05512 {
05513 return !mSelectedObjects->isEmpty();
05514 }
05515
05516
05517
05518
05519 void LLSelectMgr::deselect()
05520 {
05521 deselectAll();
05522 }
05523
05524
05525
05526 BOOL LLSelectMgr::canDuplicate()
05527 {
05528 return mSelectedObjects->getFirstCopyableObject() != NULL;
05529 }
05530
05531
05532
05533 void LLSelectMgr::duplicate()
05534 {
05535 LLVector3 offset(0.5f, 0.5f, 0.f);
05536 selectDuplicate(offset, TRUE);
05537 }
05538
05539 ESelectType LLSelectMgr::getSelectTypeForObject(LLViewerObject* object)
05540 {
05541 if (!object)
05542 {
05543 return SELECT_TYPE_WORLD;
05544 }
05545 if (object->isHUDAttachment())
05546 {
05547 return SELECT_TYPE_HUD;
05548 }
05549 else if (object->isAttachment())
05550 {
05551 return SELECT_TYPE_ATTACHMENT;
05552 }
05553 else
05554 {
05555 return SELECT_TYPE_WORLD;
05556 }
05557 }
05558
05559 void LLSelectMgr::validateSelection()
05560 {
05561 struct f : public LLSelectedObjectFunctor
05562 {
05563 virtual bool apply(LLViewerObject* object)
05564 {
05565 if (!gSelectMgr->canSelectObject(object))
05566 {
05567 gSelectMgr->deselectObjectOnly(object);
05568 }
05569 return true;
05570 }
05571 } func;
05572 getSelection()->applyToObjects(&func);
05573 }
05574
05575 BOOL LLSelectMgr::canSelectObject(LLViewerObject* object)
05576 {
05577 if (mForceSelection)
05578 {
05579 return TRUE;
05580 }
05581
05582 if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !object->permYouOwner()) ||
05583 (gSavedSettings.getBOOL("SelectMovableOnly") && !object->permMove()))
05584 {
05585
05586 return FALSE;
05587 }
05588
05589
05590 if (object->isDead()) return FALSE;
05591
05592
05593 if (object->isOrphaned()) return FALSE;
05594
05595
05596 if (object->isAvatar()) return FALSE;
05597
05598
05599 if (object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH) return FALSE;
05600
05601 ESelectType selection_type = getSelectTypeForObject(object);
05602 if (mSelectedObjects->getObjectCount() > 0 && mSelectedObjects->mSelectType != selection_type) return FALSE;
05603
05604 return TRUE;
05605 }
05606
05607 BOOL LLSelectMgr::setForceSelection(BOOL force)
05608 {
05609 std::swap(mForceSelection,force);
05610 return force;
05611 }
05612
05613 void LLSelectMgr::resetAgentHUDZoom()
05614 {
05615 if (gAgent.getAvatarObject())
05616 {
05617 gAgent.getAvatarObject()->mHUDTargetZoom = 1.f;
05618 gAgent.getAvatarObject()->mHUDCurZoom = 1.f;
05619 }
05620 }
05621
05622 void LLSelectMgr::getAgentHUDZoom(F32 &target_zoom, F32 ¤t_zoom) const
05623 {
05624 if (gAgent.getAvatarObject())
05625 {
05626 target_zoom = gAgent.getAvatarObject()->mHUDTargetZoom;
05627 current_zoom = gAgent.getAvatarObject()->mHUDCurZoom;
05628 }
05629 }
05630
05631 void LLSelectMgr::setAgentHUDZoom(F32 target_zoom, F32 current_zoom)
05632 {
05633 if (gAgent.getAvatarObject())
05634 {
05635 gAgent.getAvatarObject()->mHUDTargetZoom = target_zoom;
05636 gAgent.getAvatarObject()->mHUDCurZoom = current_zoom;
05637 }
05638 }
05639
05640 LLObjectSelection::LLObjectSelection() :
05641 LLRefCount(),
05642 mSelectType(SELECT_TYPE_WORLD)
05643 {
05644 }
05645
05646 LLObjectSelection::~LLObjectSelection()
05647 {
05648 deleteAllNodes();
05649 }
05650
05651 void LLObjectSelection::cleanupNodes()
05652 {
05653 for (list_t::iterator iter = mList.begin(); iter != mList.end(); )
05654 {
05655 list_t::iterator curiter = iter++;
05656 LLSelectNode* node = *curiter;
05657 if (node->getObject() == NULL || node->getObject()->isDead())
05658 {
05659 mList.erase(curiter);
05660 delete node;
05661 }
05662 }
05663 }
05664
05665 void LLObjectSelection::updateEffects()
05666 {
05667 }
05668
05669 S32 LLObjectSelection::getNumNodes()
05670 {
05671 return mList.size();
05672 }
05673
05674 void LLObjectSelection::addNode(LLSelectNode *nodep)
05675 {
05676 llassert_always(nodep->getObject() && !nodep->getObject()->isDead());
05677 mList.push_front(nodep);
05678 mSelectNodeMap[nodep->getObject()] = nodep;
05679 }
05680
05681 void LLObjectSelection::addNodeAtEnd(LLSelectNode *nodep)
05682 {
05683 llassert_always(nodep->getObject() && !nodep->getObject()->isDead());
05684 mList.push_back(nodep);
05685 mSelectNodeMap[nodep->getObject()] = nodep;
05686 }
05687
05688 void LLObjectSelection::moveNodeToFront(LLSelectNode *nodep)
05689 {
05690 mList.remove(nodep);
05691 mList.push_front(nodep);
05692 }
05693
05694 void LLObjectSelection::removeNode(LLSelectNode *nodep)
05695 {
05696 mSelectNodeMap.erase(nodep->getObject());
05697 if (nodep->getObject() == mPrimaryObject)
05698 {
05699 mPrimaryObject = NULL;
05700 }
05701 nodep->setObject(NULL);
05702 mList.remove(nodep);
05703 }
05704
05705 void LLObjectSelection::deleteAllNodes()
05706 {
05707 std::for_each(mList.begin(), mList.end(), DeletePointer());
05708 mList.clear();
05709 mSelectNodeMap.clear();
05710 mPrimaryObject = NULL;
05711 }
05712
05713 LLSelectNode* LLObjectSelection::findNode(LLViewerObject* objectp)
05714 {
05715 std::map<LLPointer<LLViewerObject>, LLSelectNode*>::iterator found_it = mSelectNodeMap.find(objectp);
05716 if (found_it != mSelectNodeMap.end())
05717 {
05718 return found_it->second;
05719 }
05720 return NULL;
05721 }
05722
05723
05724
05725
05726 BOOL LLObjectSelection::isEmpty()
05727 {
05728 return (mList.size() == 0);
05729 }
05730
05731
05732
05733
05734 BOOL LLObjectSelection::getOwnershipCost(S32 &cost)
05735 {
05736 S32 count = getObjectCount();
05737 cost = count * OWNERSHIP_COST_PER_OBJECT;
05738 return (count > 0);
05739 }
05740
05741
05742
05743
05744
05745 S32 LLObjectSelection::getObjectCount()
05746 {
05747 cleanupNodes();
05748 S32 count = mList.size();
05749 return count;
05750 }
05751
05752
05753
05754
05755
05756 S32 LLObjectSelection::getTECount()
05757 {
05758 S32 count = 0;
05759 for (LLObjectSelection::iterator iter = begin(); iter != end(); iter++)
05760 {
05761 LLSelectNode* node = *iter;
05762 LLViewerObject* object = node->getObject();
05763 S32 num_tes = object->getNumTEs();
05764 for (S32 te = 0; te < num_tes; te++)
05765 {
05766 if (node->isTESelected(te))
05767 {
05768 ++count;
05769 }
05770 }
05771 }
05772 return count;
05773 }
05774
05775
05776
05777
05778 S32 LLObjectSelection::getRootObjectCount()
05779 {
05780 S32 count = 0;
05781 for (LLObjectSelection::root_iterator iter = root_begin(); iter != root_end(); iter++)
05782 {
05783 ++count;
05784 }
05785 return count;
05786 }
05787
05788 bool LLObjectSelection::applyToObjects(LLSelectedObjectFunctor* func, bool firstonly)
05789 {
05790 bool result = firstonly ? false : true;
05791 for (iterator iter = begin(); iter != end(); )
05792 {
05793 iterator nextiter = iter++;
05794 LLViewerObject* object = (*nextiter)->getObject();
05795 bool r = func->apply(object);
05796 if (firstonly && r)
05797 return true;
05798 else
05799 result = result && r;
05800 }
05801 return result;
05802 }
05803
05804 bool LLObjectSelection::applyToRootObjects(LLSelectedObjectFunctor* func, bool firstonly)
05805 {
05806 bool result = firstonly ? false : true;
05807 for (root_iterator iter = root_begin(); iter != root_end(); )
05808 {
05809 root_iterator nextiter = iter++;
05810 LLViewerObject* object = (*nextiter)->getObject();
05811 bool r = func->apply(object);
05812 if (firstonly && r)
05813 return true;
05814 else
05815 result = result && r;
05816 }
05817 return result;
05818 }
05819
05820 bool LLObjectSelection::applyToTEs(LLSelectedTEFunctor* func, bool firstonly)
05821 {
05822 bool result = firstonly ? false : true;
05823 for (iterator iter = begin(); iter != end(); )
05824 {
05825 iterator nextiter = iter++;
05826 LLSelectNode* node = *nextiter;
05827 LLViewerObject* object = (*nextiter)->getObject();
05828 for (S32 te = 0; te < object->getNumTEs(); ++te)
05829 {
05830 if (node->isTESelected(te))
05831 {
05832 bool r = func->apply(object, te);
05833 if (firstonly && r)
05834 return true;
05835 else
05836 result = result && r;
05837 }
05838 }
05839 }
05840 return result;
05841 }
05842
05843 bool LLObjectSelection::applyToNodes(LLSelectedNodeFunctor *func, bool firstonly)
05844 {
05845 bool result = firstonly ? false : true;
05846 for (iterator iter = begin(); iter != end(); )
05847 {
05848 iterator nextiter = iter++;
05849 LLSelectNode* node = *nextiter;
05850 bool r = func->apply(node);
05851 if (firstonly && r)
05852 return true;
05853 else
05854 result = result && r;
05855 }
05856 return result;
05857 }
05858
05859 bool LLObjectSelection::applyToRootNodes(LLSelectedNodeFunctor *func, bool firstonly)
05860 {
05861 bool result = firstonly ? false : true;
05862 for (root_iterator iter = root_begin(); iter != root_end(); )
05863 {
05864 root_iterator nextiter = iter++;
05865 LLSelectNode* node = *nextiter;
05866 bool r = func->apply(node);
05867 if (firstonly && r)
05868 return true;
05869 else
05870 result = result && r;
05871 }
05872 return result;
05873 }
05874
05875
05876
05877
05878 BOOL LLObjectSelection::contains(LLViewerObject* object)
05879 {
05880 return findNode(object) != NULL;
05881 }
05882
05883
05884
05885
05886
05887 BOOL LLObjectSelection::contains(LLViewerObject* object, S32 te)
05888 {
05889 if (te == SELECT_ALL_TES)
05890 {
05891
05892 for (LLObjectSelection::iterator iter = begin();
05893 iter != end(); iter++)
05894 {
05895 LLSelectNode* nodep = *iter;
05896 if (nodep->getObject() == object)
05897 {
05898 BOOL all_selected = TRUE;
05899 for (S32 i = 0; i < SELECT_MAX_TES; i++)
05900 {
05901 all_selected = all_selected && nodep->isTESelected(i);
05902 }
05903 return all_selected;
05904 }
05905 }
05906 return FALSE;
05907 }
05908 else
05909 {
05910
05911 for (LLObjectSelection::iterator iter = begin(); iter != end(); iter++)
05912 {
05913 LLSelectNode* nodep = *iter;
05914 if (nodep->getObject() == object && nodep->isTESelected(te))
05915 {
05916 return TRUE;
05917 }
05918 }
05919 return FALSE;
05920 }
05921 }
05922
05923
05924 BOOL LLObjectSelection::isAttachment()
05925 {
05926 return (mSelectType == SELECT_TYPE_ATTACHMENT || mSelectType == SELECT_TYPE_HUD);
05927 }
05928
05929
05930
05931
05932 LLViewerObject* getSelectedParentObject(LLViewerObject *object)
05933 {
05934 LLViewerObject *parent;
05935 while (object && (parent = (LLViewerObject*)object->getParent()))
05936 {
05937 if (parent->isSelected())
05938 {
05939 object = parent;
05940 }
05941 else
05942 {
05943 break;
05944 }
05945 }
05946 return object;
05947 }
05948
05949
05950
05951
05952 LLSelectNode* LLObjectSelection::getFirstNode(LLSelectedNodeFunctor* func)
05953 {
05954 for (iterator iter = begin(); iter != end(); ++iter)
05955 {
05956 LLSelectNode* node = *iter;
05957 if (func == NULL || func->apply(node))
05958 {
05959 return node;
05960 }
05961 }
05962 return NULL;
05963 }
05964
05965 LLSelectNode* LLObjectSelection::getFirstRootNode(LLSelectedNodeFunctor* func, BOOL non_root_ok)
05966 {
05967 for (root_iterator iter = root_begin(); iter != root_end(); ++iter)
05968 {
05969 LLSelectNode* node = *iter;
05970 if (func == NULL || func->apply(node))
05971 {
05972 return node;
05973 }
05974 }
05975 if (non_root_ok)
05976 {
05977
05978 return getFirstNode(func);
05979 }
05980 return NULL;
05981 }
05982
05983
05984
05985
05986
05987 LLViewerObject* LLObjectSelection::getFirstSelectedObject(LLSelectedNodeFunctor* func, BOOL get_parent)
05988 {
05989 LLSelectNode* res = getFirstNode(func);
05990 if (res && get_parent)
05991 {
05992 return getSelectedParentObject(res->getObject());
05993 }
05994 else if (res)
05995 {
05996 return res->getObject();
05997 }
05998 return NULL;
05999 }
06000
06001
06002
06003
06004 LLViewerObject* LLObjectSelection::getFirstObject()
06005 {
06006 LLSelectNode* res = getFirstNode(NULL);
06007 return res ? res->getObject() : NULL;
06008 }
06009
06010
06011
06012
06013 LLViewerObject* LLObjectSelection::getFirstRootObject(BOOL non_root_ok)
06014 {
06015 LLSelectNode* res = getFirstRootNode(NULL, non_root_ok);
06016 return res ? res->getObject() : NULL;
06017 }
06018
06019
06020
06021
06022 LLSelectNode* LLObjectSelection::getFirstMoveableNode(BOOL get_root_first)
06023 {
06024 struct f : public LLSelectedNodeFunctor
06025 {
06026 bool apply(LLSelectNode* node)
06027 {
06028 LLViewerObject* obj = node->getObject();
06029 return obj->permMove();
06030 }
06031 } func;
06032 LLSelectNode* res = get_root_first ? getFirstRootNode(&func, TRUE) : getFirstNode(&func);
06033 return res;
06034 }
06035
06036
06037
06038
06039 LLViewerObject* LLObjectSelection::getFirstCopyableObject(BOOL get_parent)
06040 {
06041 struct f : public LLSelectedNodeFunctor
06042 {
06043 bool apply(LLSelectNode* node)
06044 {
06045 LLViewerObject* obj = node->getObject();
06046 return obj->permCopy() && !obj->isAttachment();
06047 }
06048 } func;
06049 return getFirstSelectedObject(&func, get_parent);
06050 }
06051
06052
06053
06054
06055 LLViewerObject* LLObjectSelection::getFirstDeleteableObject()
06056 {
06057
06058
06059
06060 struct f : public LLSelectedNodeFunctor
06061 {
06062 bool apply(LLSelectNode* node)
06063 {
06064 LLViewerObject* obj = node->getObject();
06065
06066
06067
06068
06069 if( (obj->permModify())
06070 || (obj->permYouOwner())
06071 || (!obj->permAnyOwner())
06072 || (obj->isOverAgentOwnedLand())
06073 || (obj->isOverGroupOwnedLand())
06074 )
06075 {
06076 if( !obj->isAttachment() )
06077 {
06078 return TRUE;
06079 }
06080 }
06081 return true;
06082 }
06083 } func;
06084 LLSelectNode* node = getFirstNode(&func);
06085 return node ? node->getObject() : NULL;
06086 }
06087
06088
06089
06090
06091 LLViewerObject* LLObjectSelection::getFirstEditableObject(BOOL get_parent)
06092 {
06093 struct f : public LLSelectedNodeFunctor
06094 {
06095 bool apply(LLSelectNode* node)
06096 {
06097 LLViewerObject* obj = node->getObject();
06098 return obj->permModify();
06099 }
06100 } func;
06101 return getFirstSelectedObject(&func, get_parent);
06102 }
06103
06104
06105
06106
06107 LLViewerObject* LLObjectSelection::getFirstMoveableObject(BOOL get_parent)
06108 {
06109 struct f : public LLSelectedNodeFunctor
06110 {
06111 bool apply(LLSelectNode* node)
06112 {
06113 LLViewerObject* obj = node->getObject();
06114 return obj->permMove();
06115 }
06116 } func;
06117 return getFirstSelectedObject(&func, get_parent);
06118 }
06119