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