PageRenderTime 71ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/indra/newview/llviewerobjectlist.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 2113 lines | 1572 code | 296 blank | 245 comment | 292 complexity | 66c5db19f29db09b3ae32cb652eb3ab7 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llviewerobjectlist.cpp
  3. * @brief Implementation of LLViewerObjectList class.
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "llviewerprecompiledheaders.h"
  27. #include "llviewerobjectlist.h"
  28. #include "message.h"
  29. #include "timing.h"
  30. #include "llfasttimer.h"
  31. #include "llrender.h"
  32. #include "llwindow.h" // decBusyCount()
  33. #include "llviewercontrol.h"
  34. #include "llface.h"
  35. #include "llvoavatar.h"
  36. #include "llviewerobject.h"
  37. #include "llviewerwindow.h"
  38. #include "llnetmap.h"
  39. #include "llagent.h"
  40. #include "llagentcamera.h"
  41. #include "pipeline.h"
  42. #include "llspatialpartition.h"
  43. #include "lltooltip.h"
  44. #include "llworld.h"
  45. #include "llstring.h"
  46. #include "llhudnametag.h"
  47. #include "lldrawable.h"
  48. #include "xform.h"
  49. #include "llsky.h"
  50. #include "llviewercamera.h"
  51. #include "llselectmgr.h"
  52. #include "llresmgr.h"
  53. #include "llsdutil.h"
  54. #include "llviewerregion.h"
  55. #include "llviewerstats.h"
  56. #include "llviewerstatsrecorder.h"
  57. #include "llvovolume.h"
  58. #include "llvoavatarself.h"
  59. #include "lltoolmgr.h"
  60. #include "lltoolpie.h"
  61. #include "llkeyboard.h"
  62. #include "u64.h"
  63. #include "llviewertexturelist.h"
  64. #include "lldatapacker.h"
  65. #ifdef LL_STANDALONE
  66. #include <zlib.h>
  67. #else
  68. #include "zlib/zlib.h"
  69. #endif
  70. #include "object_flags.h"
  71. #include "llappviewer.h"
  72. extern F32 gMinObjectDistance;
  73. extern BOOL gAnimateTextures;
  74. void dialog_refresh_all();
  75. #define CULL_VIS
  76. //#define ORPHAN_SPAM
  77. //#define IGNORE_DEAD
  78. // Global lists of objects - should go away soon.
  79. LLViewerObjectList gObjectList;
  80. extern LLPipeline gPipeline;
  81. // Statics for object lookup tables.
  82. U32 LLViewerObjectList::sSimulatorMachineIndex = 1; // Not zero deliberately, to speed up index check.
  83. std::map<U64, U32> LLViewerObjectList::sIPAndPortToIndex;
  84. std::map<U64, LLUUID> LLViewerObjectList::sIndexAndLocalIDToUUID;
  85. LLViewerObjectList::LLViewerObjectList()
  86. {
  87. mNumVisCulled = 0;
  88. mNumSizeCulled = 0;
  89. mCurLazyUpdateIndex = 0;
  90. mCurBin = 0;
  91. mNumDeadObjects = 0;
  92. mNumOrphans = 0;
  93. mNumNewObjects = 0;
  94. mWasPaused = FALSE;
  95. mNumDeadObjectUpdates = 0;
  96. mNumUnknownKills = 0;
  97. mNumUnknownUpdates = 0;
  98. }
  99. LLViewerObjectList::~LLViewerObjectList()
  100. {
  101. destroy();
  102. }
  103. void LLViewerObjectList::destroy()
  104. {
  105. killAllObjects();
  106. resetObjectBeacons();
  107. mActiveObjects.clear();
  108. mDeadObjects.clear();
  109. mMapObjects.clear();
  110. mUUIDObjectMap.clear();
  111. }
  112. void LLViewerObjectList::getUUIDFromLocal(LLUUID &id,
  113. const U32 local_id,
  114. const U32 ip,
  115. const U32 port)
  116. {
  117. U64 ipport = (((U64)ip) << 32) | (U64)port;
  118. U32 index = sIPAndPortToIndex[ipport];
  119. if (!index)
  120. {
  121. index = sSimulatorMachineIndex++;
  122. sIPAndPortToIndex[ipport] = index;
  123. }
  124. U64 indexid = (((U64)index) << 32) | (U64)local_id;
  125. id = get_if_there(sIndexAndLocalIDToUUID, indexid, LLUUID::null);
  126. }
  127. U64 LLViewerObjectList::getIndex(const U32 local_id,
  128. const U32 ip,
  129. const U32 port)
  130. {
  131. U64 ipport = (((U64)ip) << 32) | (U64)port;
  132. U32 index = sIPAndPortToIndex[ipport];
  133. if (!index)
  134. {
  135. return 0;
  136. }
  137. return (((U64)index) << 32) | (U64)local_id;
  138. }
  139. BOOL LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject* objectp)
  140. {
  141. if(objectp && objectp->getRegion())
  142. {
  143. U32 local_id = objectp->mLocalID;
  144. U32 ip = objectp->getRegion()->getHost().getAddress();
  145. U32 port = objectp->getRegion()->getHost().getPort();
  146. U64 ipport = (((U64)ip) << 32) | (U64)port;
  147. U32 index = sIPAndPortToIndex[ipport];
  148. // llinfos << "Removing object from table, local ID " << local_id << ", ip " << ip << ":" << port << llendl;
  149. U64 indexid = (((U64)index) << 32) | (U64)local_id;
  150. std::map<U64, LLUUID>::iterator iter = sIndexAndLocalIDToUUID.find(indexid);
  151. if (iter == sIndexAndLocalIDToUUID.end())
  152. {
  153. return FALSE;
  154. }
  155. // Found existing entry
  156. if (iter->second == objectp->getID())
  157. { // Full UUIDs match, so remove the entry
  158. sIndexAndLocalIDToUUID.erase(iter);
  159. return TRUE;
  160. }
  161. // UUIDs did not match - this would zap a valid entry, so don't erase it
  162. //llinfos << "Tried to erase entry where id in table ("
  163. // << iter->second << ") did not match object " << object.getID() << llendl;
  164. }
  165. return FALSE ;
  166. }
  167. void LLViewerObjectList::setUUIDAndLocal(const LLUUID &id,
  168. const U32 local_id,
  169. const U32 ip,
  170. const U32 port)
  171. {
  172. U64 ipport = (((U64)ip) << 32) | (U64)port;
  173. U32 index = sIPAndPortToIndex[ipport];
  174. if (!index)
  175. {
  176. index = sSimulatorMachineIndex++;
  177. sIPAndPortToIndex[ipport] = index;
  178. }
  179. U64 indexid = (((U64)index) << 32) | (U64)local_id;
  180. sIndexAndLocalIDToUUID[indexid] = id;
  181. //llinfos << "Adding object to table, full ID " << id
  182. // << ", local ID " << local_id << ", ip " << ip << ":" << port << llendl;
  183. }
  184. S32 gFullObjectUpdates = 0;
  185. S32 gTerseObjectUpdates = 0;
  186. void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp,
  187. void** user_data,
  188. U32 i,
  189. const EObjectUpdateType update_type,
  190. LLDataPacker* dpp,
  191. BOOL just_created)
  192. {
  193. LLMemType mt(LLMemType::MTYPE_OBJECT_PROCESS_UPDATE_CORE);
  194. LLMessageSystem* msg = gMessageSystem;
  195. // ignore returned flags
  196. objectp->processUpdateMessage(msg, user_data, i, update_type, dpp);
  197. if (objectp->isDead())
  198. {
  199. // The update failed
  200. return;
  201. }
  202. updateActive(objectp);
  203. if (just_created)
  204. {
  205. gPipeline.addObject(objectp);
  206. }
  207. // Also sets the approx. pixel area
  208. objectp->setPixelAreaAndAngle(gAgent);
  209. // RN: this must be called after we have a drawable
  210. // (from gPipeline.addObject)
  211. // so that the drawable parent is set properly
  212. findOrphans(objectp, msg->getSenderIP(), msg->getSenderPort());
  213. // If we're just wandering around, don't create new objects selected.
  214. if (just_created
  215. && update_type != OUT_TERSE_IMPROVED
  216. && objectp->mCreateSelected)
  217. {
  218. if ( LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance() )
  219. {
  220. // llinfos << "DEBUG selecting " << objectp->mID << " "
  221. // << objectp->mLocalID << llendl;
  222. LLSelectMgr::getInstance()->selectObjectAndFamily(objectp);
  223. dialog_refresh_all();
  224. }
  225. objectp->mCreateSelected = false;
  226. gViewerWindow->getWindow()->decBusyCount();
  227. gViewerWindow->setCursor( UI_CURSOR_ARROW );
  228. }
  229. }
  230. static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Objects");
  231. void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
  232. void **user_data,
  233. const EObjectUpdateType update_type,
  234. bool cached, bool compressed)
  235. {
  236. LLMemType mt(LLMemType::MTYPE_OBJECT_PROCESS_UPDATE);
  237. LLFastTimer t(FTM_PROCESS_OBJECTS);
  238. LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal();
  239. LLViewerObject *objectp;
  240. S32 num_objects;
  241. U32 local_id;
  242. LLPCode pcode = 0;
  243. LLUUID fullid;
  244. S32 i;
  245. // figure out which simulator these are from and get it's index
  246. // Coordinates in simulators are region-local
  247. // Until we get region-locality working on viewer we
  248. // have to transform to absolute coordinates.
  249. num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData);
  250. // I don't think this case is ever hit. TODO* Test this.
  251. if (!cached && !compressed && update_type != OUT_FULL)
  252. {
  253. //llinfos << "TEST: !cached && !compressed && update_type != OUT_FULL" << llendl;
  254. gTerseObjectUpdates += num_objects;
  255. S32 size;
  256. if (mesgsys->getReceiveCompressedSize())
  257. {
  258. size = mesgsys->getReceiveCompressedSize();
  259. }
  260. else
  261. {
  262. size = mesgsys->getReceiveSize();
  263. }
  264. //llinfos << "Received terse " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl;
  265. }
  266. else
  267. {
  268. S32 size;
  269. if (mesgsys->getReceiveCompressedSize())
  270. {
  271. size = mesgsys->getReceiveCompressedSize();
  272. }
  273. else
  274. {
  275. size = mesgsys->getReceiveSize();
  276. }
  277. // llinfos << "Received " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl;
  278. gFullObjectUpdates += num_objects;
  279. }
  280. U64 region_handle;
  281. mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle);
  282. LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle);
  283. if (!regionp)
  284. {
  285. llwarns << "Object update from unknown region! " << region_handle << llendl;
  286. return;
  287. }
  288. U8 compressed_dpbuffer[2048];
  289. LLDataPackerBinaryBuffer compressed_dp(compressed_dpbuffer, 2048);
  290. LLDataPacker *cached_dpp = NULL;
  291. #if LL_RECORD_VIEWER_STATS
  292. LLViewerStatsRecorder::instance()->beginObjectUpdateEvents(regionp);
  293. #endif
  294. for (i = 0; i < num_objects; i++)
  295. {
  296. // timer is unused?
  297. LLTimer update_timer;
  298. BOOL justCreated = FALSE;
  299. if (cached)
  300. {
  301. U32 id;
  302. U32 crc;
  303. mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, id, i);
  304. mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_CRC, crc, i);
  305. // Lookup data packer and add this id to cache miss lists if necessary.
  306. U8 cache_miss_type = LLViewerRegion::CACHE_MISS_TYPE_NONE;
  307. cached_dpp = regionp->getDP(id, crc, cache_miss_type);
  308. if (cached_dpp)
  309. {
  310. // Cache Hit.
  311. cached_dpp->reset();
  312. cached_dpp->unpackUUID(fullid, "ID");
  313. cached_dpp->unpackU32(local_id, "LocalID");
  314. cached_dpp->unpackU8(pcode, "PCode");
  315. }
  316. else
  317. {
  318. // Cache Miss.
  319. #if LL_RECORD_VIEWER_STATS
  320. LLViewerStatsRecorder::instance()->recordCacheMissEvent(id, update_type, cache_miss_type);
  321. #endif
  322. continue; // no data packer, skip this object
  323. }
  324. }
  325. else if (compressed)
  326. {
  327. U8 compbuffer[2048];
  328. S32 uncompressed_length = 2048;
  329. S32 compressed_length;
  330. compressed_dp.reset();
  331. U32 flags = 0;
  332. if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?
  333. {
  334. mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i);
  335. }
  336. // I don't think we ever use this flag from the server. DK 2010/12/09
  337. if (flags & FLAGS_ZLIB_COMPRESSED)
  338. {
  339. //llinfos << "TEST: flags & FLAGS_ZLIB_COMPRESSED" << llendl;
  340. compressed_length = mesgsys->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_Data);
  341. mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compbuffer, 0, i);
  342. uncompressed_length = 2048;
  343. uncompress(compressed_dpbuffer, (unsigned long *)&uncompressed_length,
  344. compbuffer, compressed_length);
  345. compressed_dp.assignBuffer(compressed_dpbuffer, uncompressed_length);
  346. }
  347. else
  348. {
  349. uncompressed_length = mesgsys->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_Data);
  350. mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compressed_dpbuffer, 0, i);
  351. compressed_dp.assignBuffer(compressed_dpbuffer, uncompressed_length);
  352. }
  353. if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?
  354. {
  355. compressed_dp.unpackUUID(fullid, "ID");
  356. compressed_dp.unpackU32(local_id, "LocalID");
  357. compressed_dp.unpackU8(pcode, "PCode");
  358. }
  359. else
  360. {
  361. compressed_dp.unpackU32(local_id, "LocalID");
  362. getUUIDFromLocal(fullid,
  363. local_id,
  364. gMessageSystem->getSenderIP(),
  365. gMessageSystem->getSenderPort());
  366. if (fullid.isNull())
  367. {
  368. // llwarns << "update for unknown localid " << local_id << " host " << gMessageSystem->getSender() << ":" << gMessageSystem->getSenderPort() << llendl;
  369. mNumUnknownUpdates++;
  370. }
  371. }
  372. }
  373. else if (update_type != OUT_FULL) // !compressed, !OUT_FULL ==> OUT_FULL_CACHED only?
  374. {
  375. mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);
  376. getUUIDFromLocal(fullid,
  377. local_id,
  378. gMessageSystem->getSenderIP(),
  379. gMessageSystem->getSenderPort());
  380. if (fullid.isNull())
  381. {
  382. // llwarns << "update for unknown localid " << local_id << " host " << gMessageSystem->getSender() << llendl;
  383. mNumUnknownUpdates++;
  384. }
  385. }
  386. else // OUT_FULL only?
  387. {
  388. mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FullID, fullid, i);
  389. mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);
  390. // llinfos << "Full Update, obj " << local_id << ", global ID" << fullid << "from " << mesgsys->getSender() << llendl;
  391. }
  392. objectp = findObject(fullid);
  393. // This looks like it will break if the local_id of the object doesn't change
  394. // upon boundary crossing, but we check for region id matching later...
  395. // Reset object local id and region pointer if things have changed
  396. if (objectp &&
  397. ((objectp->mLocalID != local_id) ||
  398. (objectp->getRegion() != regionp)))
  399. {
  400. //if (objectp->getRegion())
  401. //{
  402. // llinfos << "Local ID change: Removing object from table, local ID " << objectp->mLocalID
  403. // << ", id from message " << local_id << ", from "
  404. // << LLHost(objectp->getRegion()->getHost().getAddress(), objectp->getRegion()->getHost().getPort())
  405. // << ", full id " << fullid
  406. // << ", objects id " << objectp->getID()
  407. // << ", regionp " << (U32) regionp << ", object region " << (U32) objectp->getRegion()
  408. // << llendl;
  409. //}
  410. removeFromLocalIDTable(objectp);
  411. setUUIDAndLocal(fullid,
  412. local_id,
  413. gMessageSystem->getSenderIP(),
  414. gMessageSystem->getSenderPort());
  415. if (objectp->mLocalID != local_id)
  416. { // Update local ID in object with the one sent from the region
  417. objectp->mLocalID = local_id;
  418. }
  419. if (objectp->getRegion() != regionp)
  420. { // Object changed region, so update it
  421. objectp->updateRegion(regionp); // for LLVOAvatar
  422. }
  423. }
  424. if (!objectp)
  425. {
  426. if (compressed)
  427. {
  428. if (update_type == OUT_TERSE_IMPROVED)
  429. {
  430. // llinfos << "terse update for an unknown object (compressed):" << fullid << llendl;
  431. #if LL_RECORD_VIEWER_STATS
  432. LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type);
  433. #endif
  434. continue;
  435. }
  436. }
  437. else if (cached) // Cache hit only?
  438. {
  439. }
  440. else
  441. {
  442. if (update_type != OUT_FULL)
  443. {
  444. //llinfos << "terse update for an unknown object:" << fullid << llendl;
  445. #if LL_RECORD_VIEWER_STATS
  446. LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type);
  447. #endif
  448. continue;
  449. }
  450. mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_PCode, pcode, i);
  451. }
  452. #ifdef IGNORE_DEAD
  453. if (mDeadObjects.find(fullid) != mDeadObjects.end())
  454. {
  455. mNumDeadObjectUpdates++;
  456. //llinfos << "update for a dead object:" << fullid << llendl;
  457. #if LL_RECORD_VIEWER_STATS
  458. LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type);
  459. #endif
  460. continue;
  461. }
  462. #endif
  463. objectp = createObject(pcode, regionp, fullid, local_id, gMessageSystem->getSender());
  464. if (!objectp)
  465. {
  466. llinfos << "createObject failure for object: " << fullid << llendl;
  467. #if LL_RECORD_VIEWER_STATS
  468. LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type);
  469. #endif
  470. continue;
  471. }
  472. justCreated = TRUE;
  473. mNumNewObjects++;
  474. }
  475. if (objectp->isDead())
  476. {
  477. llwarns << "Dead object " << objectp->mID << " in UUID map 1!" << llendl;
  478. }
  479. bool bCached = false;
  480. if (compressed)
  481. {
  482. if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?
  483. {
  484. objectp->mLocalID = local_id;
  485. }
  486. processUpdateCore(objectp, user_data, i, update_type, &compressed_dp, justCreated);
  487. if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?
  488. {
  489. bCached = true;
  490. #if LL_RECORD_VIEWER_STATS
  491. LLViewerRegion::eCacheUpdateResult result = objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp);
  492. LLViewerStatsRecorder::instance()->recordCacheFullUpdate(local_id, update_type, result, objectp);
  493. #else
  494. objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp);
  495. #endif
  496. }
  497. }
  498. else if (cached) // Cache hit only?
  499. {
  500. objectp->mLocalID = local_id;
  501. processUpdateCore(objectp, user_data, i, update_type, cached_dpp, justCreated);
  502. }
  503. else
  504. {
  505. if (update_type == OUT_FULL)
  506. {
  507. objectp->mLocalID = local_id;
  508. }
  509. processUpdateCore(objectp, user_data, i, update_type, NULL, justCreated);
  510. }
  511. #if LL_RECORD_VIEWER_STATS
  512. LLViewerStatsRecorder::instance()->recordObjectUpdateEvent(local_id, update_type, objectp);
  513. #endif
  514. objectp->setLastUpdateType(update_type);
  515. objectp->setLastUpdateCached(bCached);
  516. }
  517. #if LL_RECORD_VIEWER_STATS
  518. LLViewerStatsRecorder::instance()->endObjectUpdateEvents();
  519. #endif
  520. LLVOAvatar::cullAvatarsByPixelArea();
  521. }
  522. void LLViewerObjectList::processCompressedObjectUpdate(LLMessageSystem *mesgsys,
  523. void **user_data,
  524. const EObjectUpdateType update_type)
  525. {
  526. processObjectUpdate(mesgsys, user_data, update_type, false, true);
  527. }
  528. void LLViewerObjectList::processCachedObjectUpdate(LLMessageSystem *mesgsys,
  529. void **user_data,
  530. const EObjectUpdateType update_type)
  531. {
  532. processObjectUpdate(mesgsys, user_data, update_type, true, false);
  533. }
  534. void LLViewerObjectList::dirtyAllObjectInventory()
  535. {
  536. for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
  537. {
  538. (*iter)->dirtyInventory();
  539. }
  540. }
  541. void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
  542. {
  543. S32 i;
  544. S32 num_objects = 0;
  545. LLViewerObject *objectp;
  546. S32 num_updates, max_value;
  547. if (NUM_BINS - 1 == mCurBin)
  548. {
  549. num_updates = (S32) mObjects.size() - mCurLazyUpdateIndex;
  550. max_value = (S32) mObjects.size();
  551. gTextureList.setUpdateStats(TRUE);
  552. }
  553. else
  554. {
  555. num_updates = ((S32) mObjects.size() / NUM_BINS) + 1;
  556. max_value = llmin((S32) mObjects.size(), mCurLazyUpdateIndex + num_updates);
  557. }
  558. // Slam priorities for textures that we care about (hovered, selected, and focused)
  559. // Hovered
  560. // Assumes only one level deep of parenting
  561. LLSelectNode* nodep = LLSelectMgr::instance().getHoverNode();
  562. if (nodep)
  563. {
  564. objectp = nodep->getObject();
  565. if (objectp)
  566. {
  567. objectp->boostTexturePriority();
  568. }
  569. }
  570. // Focused
  571. objectp = gAgentCamera.getFocusObject();
  572. if (objectp)
  573. {
  574. objectp->boostTexturePriority();
  575. }
  576. // Selected
  577. struct f : public LLSelectedObjectFunctor
  578. {
  579. virtual bool apply(LLViewerObject* objectp)
  580. {
  581. objectp->boostTexturePriority();
  582. return true;
  583. }
  584. } func;
  585. LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func);
  586. // Iterate through some of the objects and lazy update their texture priorities
  587. for (i = mCurLazyUpdateIndex; i < max_value; i++)
  588. {
  589. objectp = mObjects[i];
  590. if (!objectp->isDead())
  591. {
  592. num_objects++;
  593. // Update distance & gpw
  594. objectp->setPixelAreaAndAngle(agent); // Also sets the approx. pixel area
  595. objectp->updateTextures(); // Update the image levels of textures for this object.
  596. }
  597. }
  598. mCurLazyUpdateIndex = max_value;
  599. if (mCurLazyUpdateIndex == mObjects.size())
  600. {
  601. mCurLazyUpdateIndex = 0;
  602. }
  603. mCurBin = (mCurBin + 1) % NUM_BINS;
  604. LLVOAvatar::cullAvatarsByPixelArea();
  605. }
  606. class LLObjectCostResponder : public LLCurl::Responder
  607. {
  608. public:
  609. LLObjectCostResponder(const LLSD& object_ids)
  610. : mObjectIDs(object_ids)
  611. {
  612. }
  613. // Clear's the global object list's pending
  614. // request list for all objects requested
  615. void clear_object_list_pending_requests()
  616. {
  617. // TODO*: No more hard coding
  618. for (
  619. LLSD::array_iterator iter = mObjectIDs.beginArray();
  620. iter != mObjectIDs.endArray();
  621. ++iter)
  622. {
  623. gObjectList.onObjectCostFetchFailure(iter->asUUID());
  624. }
  625. }
  626. void error(U32 statusNum, const std::string& reason)
  627. {
  628. llwarns
  629. << "Transport error requesting object cost "
  630. << "HTTP status: " << statusNum << ", reason: "
  631. << reason << "." << llendl;
  632. // TODO*: Error message to user
  633. // For now just clear the request from the pending list
  634. clear_object_list_pending_requests();
  635. }
  636. void result(const LLSD& content)
  637. {
  638. if ( !content.isMap() || content.has("error") )
  639. {
  640. // Improper response or the request had an error,
  641. // show an error to the user?
  642. llwarns
  643. << "Application level error when fetching object "
  644. << "cost. Message: " << content["error"]["message"].asString()
  645. << ", identifier: " << content["error"]["identifier"].asString()
  646. << llendl;
  647. // TODO*: Adaptively adjust request size if the
  648. // service says we've requested too many and retry
  649. // TODO*: Error message if not retrying
  650. clear_object_list_pending_requests();
  651. return;
  652. }
  653. // Success, grab the resource cost and linked set costs
  654. // for an object if one was returned
  655. for (
  656. LLSD::array_iterator iter = mObjectIDs.beginArray();
  657. iter != mObjectIDs.endArray();
  658. ++iter)
  659. {
  660. LLUUID object_id = iter->asUUID();
  661. // Check to see if the request contains data for the object
  662. if ( content.has(iter->asString()) )
  663. {
  664. F32 link_cost =
  665. content[iter->asString()]["linked_set_resource_cost"].asReal();
  666. F32 object_cost =
  667. content[iter->asString()]["resource_cost"].asReal();
  668. F32 physics_cost = content[iter->asString()]["physics_cost"].asReal();
  669. F32 link_physics_cost = content[iter->asString()]["linked_set_physics_cost"].asReal();
  670. gObjectList.updateObjectCost(object_id, object_cost, link_cost, physics_cost, link_physics_cost);
  671. }
  672. else
  673. {
  674. // TODO*: Give user feedback about the missing data?
  675. gObjectList.onObjectCostFetchFailure(object_id);
  676. }
  677. }
  678. }
  679. private:
  680. LLSD mObjectIDs;
  681. };
  682. class LLPhysicsFlagsResponder : public LLCurl::Responder
  683. {
  684. public:
  685. LLPhysicsFlagsResponder(const LLSD& object_ids)
  686. : mObjectIDs(object_ids)
  687. {
  688. }
  689. // Clear's the global object list's pending
  690. // request list for all objects requested
  691. void clear_object_list_pending_requests()
  692. {
  693. // TODO*: No more hard coding
  694. for (
  695. LLSD::array_iterator iter = mObjectIDs.beginArray();
  696. iter != mObjectIDs.endArray();
  697. ++iter)
  698. {
  699. gObjectList.onPhysicsFlagsFetchFailure(iter->asUUID());
  700. }
  701. }
  702. void error(U32 statusNum, const std::string& reason)
  703. {
  704. llwarns
  705. << "Transport error requesting object physics flags "
  706. << "HTTP status: " << statusNum << ", reason: "
  707. << reason << "." << llendl;
  708. // TODO*: Error message to user
  709. // For now just clear the request from the pending list
  710. clear_object_list_pending_requests();
  711. }
  712. void result(const LLSD& content)
  713. {
  714. if ( !content.isMap() || content.has("error") )
  715. {
  716. // Improper response or the request had an error,
  717. // show an error to the user?
  718. llwarns
  719. << "Application level error when fetching object "
  720. << "physics flags. Message: " << content["error"]["message"].asString()
  721. << ", identifier: " << content["error"]["identifier"].asString()
  722. << llendl;
  723. // TODO*: Adaptively adjust request size if the
  724. // service says we've requested too many and retry
  725. // TODO*: Error message if not retrying
  726. clear_object_list_pending_requests();
  727. return;
  728. }
  729. // Success, grab the resource cost and linked set costs
  730. // for an object if one was returned
  731. for (
  732. LLSD::array_iterator iter = mObjectIDs.beginArray();
  733. iter != mObjectIDs.endArray();
  734. ++iter)
  735. {
  736. LLUUID object_id = iter->asUUID();
  737. // Check to see if the request contains data for the object
  738. if ( content.has(iter->asString()) )
  739. {
  740. const LLSD& data = content[iter->asString()];
  741. S32 shape_type = data["PhysicsShapeType"].asInteger();
  742. gObjectList.updatePhysicsShapeType(object_id, shape_type);
  743. if (data.has("Density"))
  744. {
  745. F32 density = data["Density"].asReal();
  746. F32 friction = data["Friction"].asReal();
  747. F32 restitution = data["Restitution"].asReal();
  748. F32 gravity_multiplier = data["GravityMultiplier"].asReal();
  749. gObjectList.updatePhysicsProperties(object_id,
  750. density, friction, restitution, gravity_multiplier);
  751. }
  752. }
  753. else
  754. {
  755. // TODO*: Give user feedback about the missing data?
  756. gObjectList.onPhysicsFlagsFetchFailure(object_id);
  757. }
  758. }
  759. }
  760. private:
  761. LLSD mObjectIDs;
  762. };
  763. void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
  764. {
  765. LLMemType mt(LLMemType::MTYPE_OBJECT);
  766. // Update globals
  767. LLViewerObject::setVelocityInterpolate( gSavedSettings.getBOOL("VelocityInterpolate") );
  768. LLViewerObject::setPingInterpolate( gSavedSettings.getBOOL("PingInterpolate") );
  769. F32 interp_time = gSavedSettings.getF32("InterpolationTime");
  770. F32 phase_out_time = gSavedSettings.getF32("InterpolationPhaseOut");
  771. if (interp_time < 0.0 ||
  772. phase_out_time < 0.0 ||
  773. phase_out_time > interp_time)
  774. {
  775. llwarns << "Invalid values for InterpolationTime or InterpolationPhaseOut, resetting to defaults" << llendl;
  776. interp_time = 3.0f;
  777. phase_out_time = 1.0f;
  778. }
  779. LLViewerObject::setPhaseOutUpdateInterpolationTime( interp_time );
  780. LLViewerObject::setMaxUpdateInterpolationTime( phase_out_time );
  781. gAnimateTextures = gSavedSettings.getBOOL("AnimateTextures");
  782. // update global timer
  783. F32 last_time = gFrameTimeSeconds;
  784. U64 time = totalTime(); // this will become the new gFrameTime when the update is done
  785. // Time _can_ go backwards, for example if the user changes the system clock.
  786. // It doesn't cause any fatal problems (just some oddness with stats), so we shouldn't assert here.
  787. // llassert(time > gFrameTime);
  788. F64 time_diff = U64_to_F64(time - gFrameTime)/(F64)SEC_TO_MICROSEC;
  789. gFrameTime = time;
  790. F64 time_since_start = U64_to_F64(gFrameTime - gStartTime)/(F64)SEC_TO_MICROSEC;
  791. gFrameTimeSeconds = (F32)time_since_start;
  792. gFrameIntervalSeconds = gFrameTimeSeconds - last_time;
  793. if (gFrameIntervalSeconds < 0.f)
  794. {
  795. gFrameIntervalSeconds = 0.f;
  796. }
  797. //clear avatar LOD change counter
  798. LLVOAvatar::sNumLODChangesThisFrame = 0;
  799. const F64 frame_time = LLFrameTimer::getElapsedSeconds();
  800. std::vector<LLViewerObject*> kill_list;
  801. S32 num_active_objects = 0;
  802. LLViewerObject *objectp = NULL;
  803. // Make a copy of the list in case something in idleUpdate() messes with it
  804. std::vector<LLViewerObject*> idle_list;
  805. static LLFastTimer::DeclareTimer idle_copy("Idle Copy");
  806. {
  807. LLFastTimer t(idle_copy);
  808. idle_list.reserve( mActiveObjects.size() );
  809. for (std::set<LLPointer<LLViewerObject> >::iterator active_iter = mActiveObjects.begin();
  810. active_iter != mActiveObjects.end(); active_iter++)
  811. {
  812. objectp = *active_iter;
  813. if (objectp)
  814. {
  815. idle_list.push_back( objectp );
  816. }
  817. else
  818. { // There shouldn't be any NULL pointers in the list, but they have caused
  819. // crashes before. This may be idleUpdate() messing with the list.
  820. llwarns << "LLViewerObjectList::update has a NULL objectp" << llendl;
  821. }
  822. }
  823. }
  824. if (gSavedSettings.getBOOL("FreezeTime"))
  825. {
  826. for (std::vector<LLViewerObject*>::iterator iter = idle_list.begin();
  827. iter != idle_list.end(); iter++)
  828. {
  829. objectp = *iter;
  830. if (objectp->isAvatar())
  831. {
  832. objectp->idleUpdate(agent, world, frame_time);
  833. }
  834. }
  835. }
  836. else
  837. {
  838. for (std::vector<LLViewerObject*>::iterator idle_iter = idle_list.begin();
  839. idle_iter != idle_list.end(); idle_iter++)
  840. {
  841. objectp = *idle_iter;
  842. if (!objectp->idleUpdate(agent, world, frame_time))
  843. {
  844. // If Idle Update returns false, kill object!
  845. kill_list.push_back(objectp);
  846. }
  847. else
  848. {
  849. num_active_objects++;
  850. }
  851. }
  852. for (std::vector<LLViewerObject*>::iterator kill_iter = kill_list.begin();
  853. kill_iter != kill_list.end(); kill_iter++)
  854. {
  855. objectp = *kill_iter;
  856. killObject(objectp);
  857. }
  858. }
  859. fetchObjectCosts();
  860. fetchPhysicsFlags();
  861. mNumSizeCulled = 0;
  862. mNumVisCulled = 0;
  863. // update max computed render cost
  864. LLVOVolume::updateRenderComplexity();
  865. // compute all sorts of time-based stats
  866. // don't factor frames that were paused into the stats
  867. if (! mWasPaused)
  868. {
  869. LLViewerStats::getInstance()->updateFrameStats(time_diff);
  870. }
  871. /*
  872. // Debugging code for viewing orphans, and orphaned parents
  873. LLUUID id;
  874. for (i = 0; i < mOrphanParents.count(); i++)
  875. {
  876. id = sIndexAndLocalIDToUUID[mOrphanParents[i]];
  877. LLViewerObject *objectp = findObject(id);
  878. if (objectp)
  879. {
  880. std::string id_str;
  881. objectp->mID.toString(id_str);
  882. std::string tmpstr = std::string("Par: ") + id_str;
  883. addDebugBeacon(objectp->getPositionAgent(),
  884. tmpstr,
  885. LLColor4(1.f,0.f,0.f,1.f),
  886. LLColor4(1.f,1.f,1.f,1.f));
  887. }
  888. }
  889. LLColor4 text_color;
  890. for (i = 0; i < mOrphanChildren.count(); i++)
  891. {
  892. OrphanInfo oi = mOrphanChildren[i];
  893. LLViewerObject *objectp = findObject(oi.mChildInfo);
  894. if (objectp)
  895. {
  896. std::string id_str;
  897. objectp->mID.toString(id_str);
  898. std::string tmpstr;
  899. if (objectp->getParent())
  900. {
  901. tmpstr = std::string("ChP: ") + id_str;
  902. text_color = LLColor4(0.f, 1.f, 0.f, 1.f);
  903. }
  904. else
  905. {
  906. tmpstr = std::string("ChNoP: ") + id_str;
  907. text_color = LLColor4(1.f, 0.f, 0.f, 1.f);
  908. }
  909. id = sIndexAndLocalIDToUUID[oi.mParentInfo];
  910. addDebugBeacon(objectp->getPositionAgent() + LLVector3(0.f, 0.f, -0.25f),
  911. tmpstr,
  912. LLColor4(0.25f,0.25f,0.25f,1.f),
  913. text_color);
  914. }
  915. i++;
  916. }
  917. */
  918. LLViewerStats::getInstance()->mNumObjectsStat.addValue((S32) mObjects.size());
  919. LLViewerStats::getInstance()->mNumActiveObjectsStat.addValue(num_active_objects);
  920. LLViewerStats::getInstance()->mNumSizeCulledStat.addValue(mNumSizeCulled);
  921. LLViewerStats::getInstance()->mNumVisCulledStat.addValue(mNumVisCulled);
  922. }
  923. void LLViewerObjectList::fetchObjectCosts()
  924. {
  925. // issue http request for stale object physics costs
  926. if (!mStaleObjectCost.empty())
  927. {
  928. LLViewerRegion* regionp = gAgent.getRegion();
  929. if (regionp)
  930. {
  931. std::string url = regionp->getCapability("GetObjectCost");
  932. if (!url.empty())
  933. {
  934. LLSD id_list;
  935. U32 object_index = 0;
  936. U32 count = 0;
  937. for (
  938. std::set<LLUUID>::iterator iter = mStaleObjectCost.begin();
  939. iter != mStaleObjectCost.end();
  940. )
  941. {
  942. // Check to see if a request for this object
  943. // has already been made.
  944. if ( mPendingObjectCost.find(*iter) ==
  945. mPendingObjectCost.end() )
  946. {
  947. mPendingObjectCost.insert(*iter);
  948. id_list[object_index++] = *iter;
  949. }
  950. mStaleObjectCost.erase(iter++);
  951. if (count++ >= 450)
  952. {
  953. break;
  954. }
  955. }
  956. if ( id_list.size() > 0 )
  957. {
  958. LLSD post_data = LLSD::emptyMap();
  959. post_data["object_ids"] = id_list;
  960. LLHTTPClient::post(
  961. url,
  962. post_data,
  963. new LLObjectCostResponder(id_list));
  964. }
  965. }
  966. else
  967. {
  968. mStaleObjectCost.clear();
  969. mPendingObjectCost.clear();
  970. }
  971. }
  972. }
  973. }
  974. void LLViewerObjectList::fetchPhysicsFlags()
  975. {
  976. // issue http request for stale object physics flags
  977. if (!mStalePhysicsFlags.empty())
  978. {
  979. LLViewerRegion* regionp = gAgent.getRegion();
  980. if (regionp)
  981. {
  982. std::string url = regionp->getCapability("GetObjectPhysicsData");
  983. if (!url.empty())
  984. {
  985. LLSD id_list;
  986. U32 object_index = 0;
  987. for (
  988. std::set<LLUUID>::iterator iter = mStalePhysicsFlags.begin();
  989. iter != mStalePhysicsFlags.end();
  990. ++iter)
  991. {
  992. // Check to see if a request for this object
  993. // has already been made.
  994. if ( mPendingPhysicsFlags.find(*iter) ==
  995. mPendingPhysicsFlags.end() )
  996. {
  997. mPendingPhysicsFlags.insert(*iter);
  998. id_list[object_index++] = *iter;
  999. }
  1000. }
  1001. // id_list should now contain all
  1002. // requests in mStalePhysicsFlags before, so clear
  1003. // it now
  1004. mStalePhysicsFlags.clear();
  1005. if ( id_list.size() > 0 )
  1006. {
  1007. LLSD post_data = LLSD::emptyMap();
  1008. post_data["object_ids"] = id_list;
  1009. LLHTTPClient::post(
  1010. url,
  1011. post_data,
  1012. new LLPhysicsFlagsResponder(id_list));
  1013. }
  1014. }
  1015. else
  1016. {
  1017. mStalePhysicsFlags.clear();
  1018. mPendingPhysicsFlags.clear();
  1019. }
  1020. }
  1021. }
  1022. }
  1023. void LLViewerObjectList::clearDebugText()
  1024. {
  1025. for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
  1026. {
  1027. (*iter)->setDebugText("");
  1028. }
  1029. }
  1030. void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp)
  1031. {
  1032. LLMemType mt(LLMemType::MTYPE_OBJECT);
  1033. if (mDeadObjects.find(objectp->mID) != mDeadObjects.end())
  1034. {
  1035. llinfos << "Object " << objectp->mID << " already on dead list!" << llendl;
  1036. }
  1037. else
  1038. {
  1039. mDeadObjects.insert(objectp->mID);
  1040. }
  1041. // Cleanup any references we have to this object
  1042. // Remove from object map so noone can look it up.
  1043. mUUIDObjectMap.erase(objectp->mID);
  1044. //if (objectp->getRegion())
  1045. //{
  1046. // llinfos << "cleanupReferences removing object from table, local ID " << objectp->mLocalID << ", ip "
  1047. // << objectp->getRegion()->getHost().getAddress() << ":"
  1048. // << objectp->getRegion()->getHost().getPort() << llendl;
  1049. //}
  1050. removeFromLocalIDTable(objectp);
  1051. if (objectp->onActiveList())
  1052. {
  1053. //llinfos << "Removing " << objectp->mID << " " << objectp->getPCodeString() << " from active list in cleanupReferences." << llendl;
  1054. objectp->setOnActiveList(FALSE);
  1055. mActiveObjects.erase(objectp);
  1056. }
  1057. if (objectp->isOnMap())
  1058. {
  1059. removeFromMap(objectp);
  1060. }
  1061. // Don't clean up mObject references, these will be cleaned up more efficiently later!
  1062. // Also, not cleaned up
  1063. removeDrawable(objectp->mDrawable);
  1064. mNumDeadObjects++;
  1065. }
  1066. static LLFastTimer::DeclareTimer FTM_REMOVE_DRAWABLE("Remove Drawable");
  1067. void LLViewerObjectList::removeDrawable(LLDrawable* drawablep)
  1068. {
  1069. LLFastTimer t(FTM_REMOVE_DRAWABLE);
  1070. if (!drawablep)
  1071. {
  1072. return;
  1073. }
  1074. for (S32 i = 0; i < drawablep->getNumFaces(); i++)
  1075. {
  1076. LLFace* facep = drawablep->getFace(i) ;
  1077. if(facep)
  1078. {
  1079. LLViewerObject* objectp = facep->getViewerObject();
  1080. if(objectp)
  1081. {
  1082. mSelectPickList.erase(objectp);
  1083. }
  1084. }
  1085. }
  1086. }
  1087. BOOL LLViewerObjectList::killObject(LLViewerObject *objectp)
  1088. {
  1089. // Don't ever kill gAgentAvatarp, just force it to the agent's region
  1090. // unless region is NULL which is assumed to mean you are logging out.
  1091. if ((objectp == gAgentAvatarp) && gAgent.getRegion())
  1092. {
  1093. objectp->setRegion(gAgent.getRegion());
  1094. return FALSE;
  1095. }
  1096. // When we're killing objects, all we do is mark them as dead.
  1097. // We clean up the dead objects later.
  1098. if (objectp)
  1099. {
  1100. if (objectp->isDead())
  1101. {
  1102. // This object is already dead. Don't need to do more.
  1103. return TRUE;
  1104. }
  1105. else
  1106. {
  1107. objectp->markDead();
  1108. }
  1109. return TRUE;
  1110. }
  1111. return FALSE;
  1112. }
  1113. void LLViewerObjectList::killObjects(LLViewerRegion *regionp)
  1114. {
  1115. LLViewerObject *objectp;
  1116. for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
  1117. {
  1118. objectp = *iter;
  1119. if (objectp->mRegionp == regionp)
  1120. {
  1121. killObject(objectp);
  1122. }
  1123. }
  1124. // Have to clean right away because the region is becoming invalid.
  1125. cleanDeadObjects(FALSE);
  1126. }
  1127. void LLViewerObjectList::killAllObjects()
  1128. {
  1129. // Used only on global destruction.
  1130. LLViewerObject *objectp;
  1131. for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
  1132. {
  1133. objectp = *iter;
  1134. killObject(objectp);
  1135. // Object must be dead, or it's the LLVOAvatarSelf which never dies.
  1136. llassert((objectp == gAgentAvatarp) || objectp->isDead());
  1137. }
  1138. cleanDeadObjects(FALSE);
  1139. if(!mObjects.empty())
  1140. {
  1141. llwarns << "LLViewerObjectList::killAllObjects still has entries in mObjects: " << mObjects.size() << llendl;
  1142. mObjects.clear();
  1143. }
  1144. if (!mActiveObjects.empty())
  1145. {
  1146. llwarns << "Some objects still on active object list!" << llendl;
  1147. mActiveObjects.clear();
  1148. }
  1149. if (!mMapObjects.empty())
  1150. {
  1151. llwarns << "Some objects still on map object list!" << llendl;
  1152. mMapObjects.clear();
  1153. }
  1154. }
  1155. void LLViewerObjectList::cleanDeadObjects(BOOL use_timer)
  1156. {
  1157. if (!mNumDeadObjects)
  1158. {
  1159. // No dead objects, don't need to scan object list.
  1160. return;
  1161. }
  1162. S32 num_removed = 0;
  1163. LLViewerObject *objectp;
  1164. vobj_list_t::reverse_iterator target = mObjects.rbegin();
  1165. vobj_list_t::iterator iter = mObjects.begin();
  1166. for ( ; iter != mObjects.end(); )
  1167. {
  1168. // Scan for all of the dead objects and put them all on the end of the list with no ref count ops
  1169. objectp = *iter;
  1170. if (objectp == NULL)
  1171. { //we caught up to the dead tail
  1172. break;
  1173. }
  1174. if (objectp->isDead())
  1175. {
  1176. LLPointer<LLViewerObject>::swap(*iter, *target);
  1177. *target = NULL;
  1178. ++target;
  1179. num_removed++;
  1180. if (num_removed == mNumDeadObjects || iter->isNull())
  1181. {
  1182. // We've cleaned up all of the dead objects or caught up to the dead tail
  1183. break;
  1184. }
  1185. }
  1186. else
  1187. {
  1188. ++iter;
  1189. }
  1190. }
  1191. llassert(num_removed == mNumDeadObjects);
  1192. //erase as a block
  1193. mObjects.erase(mObjects.begin()+(mObjects.size()-mNumDeadObjects), mObjects.end());
  1194. // We've cleaned the global object list, now let's do some paranoia testing on objects
  1195. // before blowing away the dead list.
  1196. mDeadObjects.clear();
  1197. mNumDeadObjects = 0;
  1198. }
  1199. void LLViewerObjectList::updateActive(LLViewerObject *objectp)
  1200. {
  1201. LLMemType mt(LLMemType::MTYPE_OBJECT);
  1202. if (objectp->isDead())
  1203. {
  1204. return; // We don't update dead objects!
  1205. }
  1206. BOOL active = objectp->isActive();
  1207. if (active != objectp->onActiveList())
  1208. {
  1209. if (active)
  1210. {
  1211. //llinfos << "Adding " << objectp->mID << " " << objectp->getPCodeString() << " to active list." << llendl;
  1212. mActiveObjects.insert(objectp);
  1213. objectp->setOnActiveList(TRUE);
  1214. }
  1215. else
  1216. {
  1217. //llinfos << "Removing " << objectp->mID << " " << objectp->getPCodeString() << " from active list." << llendl;
  1218. mActiveObjects.erase(objectp);
  1219. objectp->setOnActiveList(FALSE);
  1220. }
  1221. }
  1222. }
  1223. void LLViewerObjectList::updateObjectCost(LLViewerObject* object)
  1224. {
  1225. if (!object->isRoot())
  1226. { //always fetch cost for the parent when fetching cost for children
  1227. mStaleObjectCost.insert(((LLViewerObject*)object->getParent())->getID());
  1228. }
  1229. mStaleObjectCost.insert(object->getID());
  1230. }
  1231. void LLViewerObjectList::updateObjectCost(const LLUUID& object_id, F32 object_cost, F32 link_cost, F32 physics_cost, F32 link_physics_cost)
  1232. {
  1233. mPendingObjectCost.erase(object_id);
  1234. LLViewerObject* object = findObject(object_id);
  1235. if (object)
  1236. {
  1237. object->setObjectCost(object_cost);
  1238. object->setLinksetCost(link_cost);
  1239. object->setPhysicsCost(physics_cost);
  1240. object->setLinksetPhysicsCost(link_physics_cost);
  1241. }
  1242. }
  1243. void LLViewerObjectList::onObjectCostFetchFailure(const LLUUID& object_id)
  1244. {
  1245. //llwarns << "Failed to fetch object cost for object: " << object_id << llendl;
  1246. mPendingObjectCost.erase(object_id);
  1247. }
  1248. void LLViewerObjectList::updatePhysicsFlags(const LLViewerObject* object)
  1249. {
  1250. mStalePhysicsFlags.insert(object->getID());
  1251. }
  1252. void LLViewerObjectList::updatePhysicsShapeType(const LLUUID& object_id, S32 type)
  1253. {
  1254. mPendingPhysicsFlags.erase(object_id);
  1255. LLViewerObject* object = findObject(object_id);
  1256. if (object)
  1257. {
  1258. object->setPhysicsShapeType(type);
  1259. }
  1260. }
  1261. void LLViewerObjectList::updatePhysicsProperties(const LLUUID& object_id,
  1262. F32 density,
  1263. F32 friction,
  1264. F32 restitution,
  1265. F32 gravity_multiplier)
  1266. {
  1267. mPendingPhysicsFlags.erase(object_id);
  1268. LLViewerObject* object = findObject(object_id);
  1269. if (object)
  1270. {
  1271. object->setPhysicsDensity(density);
  1272. object->setPhysicsFriction(friction);
  1273. object->setPhysicsGravity(gravity_multiplier);
  1274. object->setPhysicsRestitution(restitution);
  1275. }
  1276. }
  1277. void LLViewerObjectList::onPhysicsFlagsFetchFailure(const LLUUID& object_id)
  1278. {
  1279. //llwarns << "Failed to fetch physics flags for object: " << object_id << llendl;
  1280. mPendingPhysicsFlags.erase(object_id);
  1281. }
  1282. void LLViewerObjectList::shiftObjects(const LLVector3 &offset)
  1283. {
  1284. // This is called when we shift our origin when we cross region boundaries...
  1285. // We need to update many object caches, I'll document this more as I dig through the code
  1286. // cleaning things out...
  1287. if (0 == offset.magVecSquared())
  1288. {
  1289. return;
  1290. }
  1291. LLViewerObject *objectp;
  1292. for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
  1293. {
  1294. objectp = *iter;
  1295. // There could be dead objects on the object list, so don't update stuff if the object is dead.
  1296. if (!objectp->isDead())
  1297. {
  1298. objectp->updatePositionCaches();
  1299. if (objectp->mDrawable.notNull() && !objectp->mDrawable->isDead())
  1300. {
  1301. gPipeline.markShift(objectp->mDrawable);
  1302. }
  1303. }
  1304. }
  1305. gPipeline.shiftObjects(offset);
  1306. LLWorld::getInstance()->shiftRegions(offset);
  1307. }
  1308. void LLViewerObjectList::repartitionObjects()
  1309. {
  1310. for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
  1311. {
  1312. LLViewerObject* objectp = *iter;
  1313. if (!objectp->isDead())
  1314. {
  1315. LLDrawable* drawable = objectp->mDrawable;
  1316. if (drawable && !drawable->isDead())
  1317. {
  1318. drawable->updateBinRadius();
  1319. drawable->updateSpatialExtents();
  1320. drawable->movePartition();
  1321. }
  1322. }
  1323. }
  1324. }
  1325. //debug code
  1326. bool LLViewerObjectList::hasMapObjectInRegion(LLViewerRegion* regionp)
  1327. {
  1328. for (vobj_list_t::iterator iter = mMapObjects.begin(); iter != mMapObjects.end(); ++iter)
  1329. {
  1330. LLViewerObject* objectp = *iter;
  1331. if(objectp->isDead() || objectp->getRegion() == regionp)
  1332. {
  1333. return true ;
  1334. }
  1335. }
  1336. return false ;
  1337. }
  1338. //make sure the region is cleaned up.
  1339. void LLViewerObjectList::clearAllMapObjectsInRegion(LLViewerRegion* regionp)
  1340. {
  1341. std::set<LLViewerObject*> dead_object_list ;
  1342. std::set<LLViewerObject*> region_object_list ;
  1343. for (vobj_list_t::iterator iter = mMapObjects.begin(); iter != mMapObjects.end(); ++iter)
  1344. {
  1345. LLViewerObject* objectp = *iter;
  1346. if(objectp->isDead())
  1347. {
  1348. dead_object_list.insert(objectp) ;
  1349. }
  1350. else if(objectp->getRegion() == regionp)
  1351. {
  1352. region_object_list.insert(objectp) ;
  1353. }
  1354. }
  1355. if(dead_object_list.size() > 0)
  1356. {
  1357. llwarns << "There are " << dead_object_list.size() << " dead objects on the map!" << llendl ;
  1358. for(std::set<LLViewerObject*>::iterator iter = dead_object_list.begin(); iter != dead_object_list.end(); ++iter)
  1359. {
  1360. cleanupReferences(*iter) ;
  1361. }
  1362. }
  1363. if(region_object_list.size() > 0)
  1364. {
  1365. llwarns << "There are " << region_object_list.size() << " objects not removed from the deleted region!" << llendl ;
  1366. for(std::set<LLViewerObject*>::iterator iter = region_object_list.begin(); iter != region_object_list.end(); ++iter)
  1367. {
  1368. (*iter)->markDead() ;
  1369. }
  1370. }
  1371. }
  1372. void LLViewerObjectList::renderObjectsForMap(LLNetMap &netmap)
  1373. {
  1374. LLColor4 above_water_color = LLUIColorTable::instance().getColor( "NetMapOtherOwnAboveWater" );
  1375. LLColor4 below_water_color = LLUIColorTable::instance().getColor( "NetMapOtherOwnBelowWater" );
  1376. LLColor4 you_own_above_water_color =
  1377. LLUIColorTable::instance().getColor( "NetMapYouOwnAboveWater" );
  1378. LLColor4 you_own_below_water_color =
  1379. LLUIColorTable::instance().getColor( "NetMapYouOwnBelowWater" );
  1380. LLColor4 group_own_above_water_color =
  1381. LLUIColorTable::instance().getColor( "NetMapGroupOwnAboveWater" );
  1382. LLColor4 group_own_below_water_color =
  1383. LLUIColorTable::instance().getColor( "NetMapGroupOwnBelowWater" );
  1384. F32 max_radius = gSavedSettings.getF32("MiniMapPrimMaxRadius");
  1385. for (vobj_list_t::iterator iter = mMapObjects.begin(); iter != mMapObjects.end(); ++iter)
  1386. {
  1387. LLViewerObject* objectp = *iter;
  1388. if(objectp->isDead())//some dead objects somehow not cleaned.
  1389. {
  1390. continue ;
  1391. }
  1392. if (!objectp->getRegion() || objectp->isOrphaned() || objectp->isAttachment())
  1393. {
  1394. continue;
  1395. }
  1396. const LLVector3& scale = objectp->getScale();
  1397. const LLVector3d pos = objectp->getPositionGlobal();
  1398. const F64 water_height = F64( objectp->getRegion()->getWaterHeight() );
  1399. // LLWorld::getInstance()->getWaterHeight();
  1400. F32 approx_radius = (scale.mV[VX] + scale.mV[VY]) * 0.5f * 0.5f * 1.3f; // 1.3 is a fudge
  1401. // Limit the size of megaprims so they don't blot out everything on the minimap.
  1402. // Attempting to draw very large megaprims also causes client lag.
  1403. // See DEV-17370 and DEV-29869/SNOW-79 for details.
  1404. approx_radius = llmin(approx_radius, max_radius);
  1405. LLColor4U color = above_water_color;
  1406. if( objectp->permYouOwner() )
  1407. {
  1408. const F32 MIN_RADIUS_FOR_OWNED_OBJECTS = 2.f;
  1409. if( approx_radius < MIN_RADIUS_FOR_OWNED_OBJECTS )
  1410. {
  1411. approx_radius = MIN_RADIUS_FOR_OWNED_OBJECTS;
  1412. }
  1413. if( pos.mdV[VZ] >= water_height )
  1414. {
  1415. if ( objectp->permGroupOwner() )
  1416. {
  1417. color = group_own_above_water_color;
  1418. }
  1419. else
  1420. {
  1421. color = you_own_above_water_color;
  1422. }
  1423. }
  1424. else
  1425. {
  1426. if ( objectp->permGroupOwner() )
  1427. {
  1428. color = group_own_below_water_color;
  1429. }
  1430. else
  1431. {
  1432. color = you_own_below_water_color;
  1433. }
  1434. }
  1435. }
  1436. else
  1437. if( pos.mdV[VZ] < water_height )
  1438. {
  1439. color = below_water_color;
  1440. }
  1441. netmap.renderScaledPointGlobal(
  1442. pos,
  1443. color,
  1444. approx_radius );
  1445. }
  1446. }
  1447. void LLViewerObjectList::renderObjectBounds(const LLVector3 &center)
  1448. {
  1449. }
  1450. void LLViewerObjectList::generatePickList(LLCamera &camera)
  1451. {
  1452. LLViewerObject *objectp;
  1453. S32 i;
  1454. // Reset all of the GL names to zero.
  1455. for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
  1456. {
  1457. (*iter)->mGLName = 0;
  1458. }
  1459. mSelectPickList.clear();
  1460. std::vector<LLDrawable*> pick_drawables;
  1461. for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
  1462. iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
  1463. {
  1464. LLViewerRegion* region = *iter;
  1465. for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
  1466. {
  1467. LLSpatialPartition* part = region->getSpatialPartition(i);
  1468. if (part)
  1469. {
  1470. part->cull(camera, &pick_drawables, TRUE);
  1471. }
  1472. }
  1473. }
  1474. for (std::vector<LLDrawable*>::iterator iter = pick_drawables.begin();
  1475. iter != pick_drawables.end(); iter++)
  1476. {
  1477. LLDrawable* drawablep = *iter;
  1478. if( !drawablep )
  1479. continue;
  1480. LLViewerObject* last_objectp = NULL;
  1481. for (S32 face_num = 0; face_num < drawablep->getNumFaces(); face_num++)
  1482. {
  1483. LLViewerObject* objectp = drawablep->getFace(face_num)->getViewerObject();
  1484. if (objectp && objectp != last_objectp)
  1485. {
  1486. mSelectPickList.insert(objectp);
  1487. last_objectp = objectp;
  1488. }
  1489. }
  1490. }
  1491. LLHUDNameTag::addPickable(mSelectPickList);
  1492. for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
  1493. iter != LLCharacter::sInstances.end(); ++iter)
  1494. {
  1495. objectp = (LLVOAvatar*) *iter;
  1496. if (!objectp->isDead())
  1497. {
  1498. if (objectp->mDrawable.notNull() && objectp->mDrawable->isVisible())
  1499. {
  1500. mSelectPickList.insert(objectp);
  1501. }
  1502. }
  1503. }
  1504. // add all hud objects to pick list
  1505. if (isAgentAvatarValid())
  1506. {
  1507. for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
  1508. iter != gAgentAvatarp->mAttachmentPoints.end(); )
  1509. {
  1510. LLVOAvatar::attachment_map_t::iterator curiter = iter++;
  1511. LLViewerJointAttachment* attachment = curiter->second;
  1512. if (attachment->getIsHUDAttachment())
  1513. {
  1514. for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
  1515. attachment_iter != attachment->mAttachedObjects.end();
  1516. ++attachment_iter)
  1517. {
  1518. if (LLViewerObject* attached_object = (*attachment_iter))
  1519. {
  1520. mSelectPickList.insert(attached_object);
  1521. LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
  1522. for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
  1523. iter != child_list.end(); iter++)
  1524. {
  1525. LLViewerObject* childp = *iter;
  1526. if (childp)
  1527. {
  1528. mSelectPickList.insert(childp);
  1529. }
  1530. }
  1531. }
  1532. }
  1533. }
  1534. }
  1535. }
  1536. S32 num_pickables = (S32)mSelectPickList.size() + LLHUDIcon::getNumInstances();
  1537. if (num_pickables != 0)
  1538. {
  1539. S32 step = (0x000fffff - GL_NAME_INDEX_OFFSET) / num_pickables;
  1540. std::set<LLViewerObject*>::iterator pick_it;
  1541. i = 0;
  1542. for (pick_it = mSelectPickList.begin(); pick_it != mSelectPickList.end();)
  1543. {
  1544. LLViewerObject* objp = (*pick_it);
  1545. if (!objp || objp->isDead() || !objp->mbCanSelect)
  1546. {
  1547. mSelectPickList.erase(pick_it++);
  1548. continue;
  1549. }
  1550. objp->mGLName = (i * step) + GL_NAME_INDEX_OFFSET;
  1551. i++;
  1552. ++pick_it;
  1553. }
  1554. LLHUDIcon::generatePickIDs(i * step, step);
  1555. }
  1556. }
  1557. LLViewerObject *LLViewerObjectList::getSelectedObject(const U32 object_id)
  1558. {
  1559. std::set<LLViewerObject*>::iterator pick_it;
  1560. for (pick_it = mSelectPickList.begin(); pick_it != mSelectPickList.end(); ++pick_it)
  1561. {
  1562. if ((*pick_it)->mGLName == object_id)
  1563. {
  1564. return (*pick_it);
  1565. }
  1566. }
  1567. return NULL;
  1568. }
  1569. void LLViewerObjectList::addDebugBeacon(const LLVector3 &pos_agent,
  1570. const std::string &string,
  1571. const LLColor4 &color,
  1572. const LLColor4 &text_color,
  1573. S32 line_width)
  1574. {
  1575. LLDebugBeacon beacon;
  1576. beacon.mPositionAgent = pos_agent;
  1577. beacon.mString = string;
  1578. beacon.mColor = color;
  1579. beacon.mTextColor = text_color;
  1580. beacon.mLineWidth = line_width;
  1581. mDebugBeacons.push_back(beacon);
  1582. }
  1583. void LLViewerObjectList::resetObjectBeacons()
  1584. {
  1585. mDebugBeacons.clear();
  1586. }
  1587. LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLViewerRegion *regionp)
  1588. {
  1589. LLMemType mt(LLMemType::MTYPE_OBJECT);
  1590. LLUUID fullid;
  1591. fullid.generate();
  1592. LLViewerObject *objectp = LLViewerObject::createObject(fullid, pcode, regionp);
  1593. if (!objectp)
  1594. {
  1595. // llwarns << "Couldn't create object of type " << LLPrimitive::pCodeToString(pcode) << llendl;
  1596. return NULL;
  1597. }
  1598. mUUIDObjectMap[fullid] = objectp;
  1599. mObjects.push_back(objectp);
  1600. updateActive(objectp);
  1601. return objectp;
  1602. }
  1603. static LLFastTimer::DeclareTimer FTM_CREATE_OBJECT("Create Object");
  1604. LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRegion *regionp,
  1605. const LLUUID &uuid, const U32 local_id, const LLHost &sender)
  1606. {
  1607. LLMemType mt(LLMemType::MTYPE_OBJECT);
  1608. LLFastTimer t(FTM_CREATE_OBJECT);
  1609. LLUUID fullid;
  1610. if (uuid == LLUUID::null)
  1611. {
  1612. fullid.generate();
  1613. }
  1614. else
  1615. {
  1616. fullid = uuid;
  1617. }
  1618. LLViewerObject *objectp = LLViewerObject::createObject(fullid, pcode, regionp);
  1619. if (!objectp)
  1620. {
  1621. // llwarns << "Couldn't create object of type " << LLPrimitive::pCodeToString(pcode) << " id:" << fullid << llendl;
  1622. return NULL;
  1623. }
  1624. mUUIDObjectMap[fullid] = objectp;
  1625. setUUIDAndLocal(fullid,
  1626. local_id,
  1627. gMessageSystem->getSenderIP(),
  1628. gMessageSystem->getSenderPort());
  1629. mObjects.push_back(objectp);
  1630. updateActive(objectp);
  1631. return objectp;
  1632. }
  1633. LLViewerObject *LLViewerObjectList::replaceObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
  1634. {
  1635. LLViewerObject *old_instance = findObject(id);
  1636. if (old_instance)
  1637. {
  1638. //cleanupReferences(old_instance);
  1639. old_instance->markDead();
  1640. return createObject(pcode, regionp, id, old_instance->getLocalID(), LLHost());
  1641. }
  1642. return NULL;
  1643. }
  1644. S32 LLViewerObjectList::findReferences(LLDrawable *drawablep) const
  1645. {
  1646. LLViewerObject *objectp;
  1647. S32 num_refs = 0;
  1648. for (vobj_list_t::const_iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
  1649. {
  1650. objectp = *iter;
  1651. if (objectp->mDrawable.notNull())
  1652. {
  1653. num_refs += objectp->mDrawable->findReferences(drawablep);
  1654. }
  1655. }
  1656. return num_refs;
  1657. }
  1658. void LLViewerObjectList::orphanize(LLViewerObject *childp, U32 parent_id, U32 ip, U32 port)
  1659. {
  1660. LLMemType mt(LLMemType::MTYPE_OBJECT);
  1661. #ifdef ORPHAN_SPAM
  1662. llinfos << "Orphaning object " << childp->getID() << " with parent " << parent_id << llendl;
  1663. #endif
  1664. // We're an orphan, flag things appropriately.
  1665. childp->mOrphaned = TRUE;
  1666. if (childp->mDrawable.notNull())
  1667. {
  1668. bool make_invisible = true;
  1669. LLViewerObject *parentp = (LLViewerObject *)childp->getParent();
  1670. if (parentp)
  1671. {
  1672. if (parentp->getRegion() != childp->getRegion())
  1673. {
  1674. // This is probably an object flying across a region boundary, the
  1675. // object probably ISN'T being reparented, but just got an object
  1676. // update out of order (child update before parent).
  1677. make_invisible = false;
  1678. //llinfos << "Don't make object handoffs invisible!" << llendl;
  1679. }
  1680. }
  1681. if (make_invisible)
  1682. {
  1683. // Make sure that this object becomes invisible if it's an orphan
  1684. childp->mDrawable->setState(LLDrawable::FORCE_INVISIBLE);
  1685. }
  1686. }
  1687. // Unknown parent, add to orpaned child list
  1688. U64 parent_info = getIndex(parent_id, ip, port);
  1689. if (std::find(mOrphanParents.begin(), mOrphanParents.end(), parent_info) == mOrphanParents.end())
  1690. {
  1691. mOrphanParents.push_back(parent_info);
  1692. }
  1693. LLViewerObjectList::OrphanInfo oi(parent_info, childp->mID);
  1694. if (std::find(mOrphanChildren.begin(), mOrphanChildren.end(), oi) == mOrphanChildren.end())
  1695. {
  1696. mOrphanChildren.push_back(oi);
  1697. mNumOrphans++;
  1698. }
  1699. }
  1700. void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port)
  1701. {
  1702. if (objectp->isDead())
  1703. {
  1704. llwarns << "Trying to find orphans for dead obj " << objectp->mID
  1705. << ":" << objectp->getPCodeString() << llendl;
  1706. return;
  1707. }
  1708. // See if we are a parent of an orphan.
  1709. // Note: This code is fairly inefficient but it should happen very rarely.
  1710. // It can be sped up if this is somehow a performance issue...
  1711. if (mOrphanParents.empty())
  1712. {
  1713. // no known orphan parents
  1714. return;
  1715. }
  1716. if (std::find(mOrphanParents.begin(), mOrphanParents.end(), getIndex(objectp->mLocalID, ip, port)) == mOrphanParents.end())
  1717. {
  1718. // did not find objectp in OrphanParent list
  1719. return;
  1720. }
  1721. U64 parent_info = getIndex(objectp->mLocalID, ip, port);
  1722. BOOL orphans_found = FALSE;
  1723. // Iterate through the orphan list, and set parents of matching children.
  1724. for (std::vector<OrphanInfo>::iterator iter = mOrphanChildren.begin(); iter != mOrphanChildren.end(); )
  1725. {
  1726. if (iter->mParentInfo != parent_info)
  1727. {
  1728. ++iter;
  1729. continue;
  1730. }
  1731. LLViewerObject *childp = findObject(iter->mChildInfo);
  1732. if (childp)
  1733. {
  1734. if (childp == objectp)
  1735. {
  1736. llwarns << objectp->mID << " has self as parent, skipping!"
  1737. << llendl;
  1738. continue;
  1739. }
  1740. #ifdef ORPHAN_SPAM
  1741. llinfos << "Reunited parent " << objectp->mID
  1742. << " with child " << childp->mID << llendl;
  1743. llinfos << "Glob: " << objectp->getPositionGlobal() << llendl;
  1744. llinfos << "Agent: " << objectp->getPositionAgent() << llendl;
  1745. addDebugBeacon(objectp->getPositionAgent(),"");
  1746. #endif
  1747. gPipeline.markMoved(objectp->mDrawable);
  1748. objectp->setChanged(LLXform::MOVED | LLXform::SILHOUETTE);
  1749. // Flag the object as no longer orphaned
  1750. childp->mOrphaned = FALSE;
  1751. if (childp->mDrawable.notNull())
  1752. {
  1753. // Make the drawable visible again and set the drawable parent
  1754. childp->mDrawable->setState(LLDrawable::CLEAR_INVISIBLE);
  1755. childp->setDrawableParent(objectp->mDrawable); // LLViewerObjectList::findOrphans()
  1756. }
  1757. // Make certain particles, icon and HUD aren't hidden
  1758. childp->hideExtraDisplayItems( FALSE );
  1759. objectp->addChild(childp);
  1760. orphans_found = TRUE;
  1761. ++iter;
  1762. }
  1763. else
  1764. {
  1765. llinfos << "Missing orphan child, removing from list" << llendl;
  1766. iter = mOrphanChildren.erase(iter);
  1767. }
  1768. }
  1769. // Remove orphan parent and children from lists now that they've been found
  1770. {
  1771. std::vector<U64>::iterator iter = std::find(mOrphanParents.begin(), mOrphanParents.end(), parent_info);
  1772. if (iter != mOrphanParents.end())
  1773. {
  1774. mOrphanParents.erase(iter);
  1775. }
  1776. }
  1777. for (std::vector<OrphanInfo>::iterator iter = mOrphanChildren.begin(); iter != mOrphanChildren.end(); )
  1778. {
  1779. if (iter->mParentInfo == parent_info)
  1780. {
  1781. iter = mOrphanChildren.erase(iter);
  1782. mNumOrphans--;
  1783. }
  1784. else
  1785. {
  1786. ++iter;
  1787. }
  1788. }
  1789. if (orphans_found && objectp->isSelected())
  1790. {
  1791. LLSelectNode* nodep = LLSelectMgr::getInstance()->getSelection()->findNode(objectp);
  1792. if (nodep && !nodep->mIndividualSelection)
  1793. {
  1794. // rebuild selection with orphans
  1795. LLSelectMgr::getInstance()->deselectObjectAndFamily(objectp);
  1796. LLSelectMgr::getInstance()->selectObjectAndFamily(objectp);
  1797. }
  1798. }
  1799. }
  1800. ////////////////////////////////////////////////////////////////////////////
  1801. LLViewerObjectList::OrphanInfo::OrphanInfo()
  1802. : mParentInfo(0)
  1803. {
  1804. }
  1805. LLViewerObjectList::OrphanInfo::OrphanInfo(const U64 parent_info, const LLUUID child_info)
  1806. : mParentInfo(parent_info), mChildInfo(child_info)
  1807. {
  1808. }
  1809. bool LLViewerObjectList::OrphanInfo::operator==(const OrphanInfo &rhs) const
  1810. {
  1811. return (mParentInfo == rhs.mParentInfo) && (mChildInfo == rhs.mChildInfo);
  1812. }
  1813. bool LLViewerObjectList::OrphanInfo::operator!=(const OrphanInfo &rhs) const
  1814. {
  1815. return !operator==(rhs);
  1816. }