llviewerobjectlist.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:41k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llviewerobjectlist.cpp
  3.  * @brief Implementation of LLViewerObjectList class.
  4.  *
  5.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2001-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llviewerobjectlist.h"
  34. #include "message.h"
  35. #include "timing.h"
  36. #include "llfasttimer.h"
  37. #include "llrender.h"
  38. #include "llwindow.h" // decBusyCount()
  39. #include "llviewercontrol.h"
  40. #include "llface.h"
  41. #include "llvoavatar.h"
  42. #include "llviewerobject.h"
  43. #include "llviewerwindow.h"
  44. #include "llnetmap.h"
  45. #include "llagent.h"
  46. #include "pipeline.h"
  47. #include "llspatialpartition.h"
  48. #include "lltooltip.h"
  49. #include "llworld.h"
  50. #include "llstring.h"
  51. #include "llhudtext.h"
  52. #include "lldrawable.h"
  53. #include "xform.h"
  54. #include "llsky.h"
  55. #include "llviewercamera.h"
  56. #include "llselectmgr.h"
  57. #include "llresmgr.h"
  58. #include "llviewerregion.h"
  59. #include "llviewerstats.h"
  60. #include "llvoavatarself.h"
  61. #include "lltoolmgr.h"
  62. #include "lltoolpie.h"
  63. #include "llkeyboard.h"
  64. #include "u64.h"
  65. #include "llviewertexturelist.h"
  66. #include "lldatapacker.h"
  67. #ifdef LL_STANDALONE
  68. #include <zlib.h>
  69. #else
  70. #include "zlib/zlib.h"
  71. #endif
  72. #include "object_flags.h"
  73. #include "llappviewer.h"
  74. extern F32 gMinObjectDistance;
  75. extern BOOL gAnimateTextures;
  76. void dialog_refresh_all();
  77. #define CULL_VIS
  78. //#define ORPHAN_SPAM
  79. //#define IGNORE_DEAD
  80. // Global lists of objects - should go away soon.
  81. LLViewerObjectList gObjectList;
  82. extern LLPipeline gPipeline;
  83. // Statics for object lookup tables.
  84. U32 LLViewerObjectList::sSimulatorMachineIndex = 1; // Not zero deliberately, to speed up index check.
  85. LLMap<U64, U32> LLViewerObjectList::sIPAndPortToIndex;
  86. std::map<U64, LLUUID> LLViewerObjectList::sIndexAndLocalIDToUUID;
  87. LLViewerObjectList::LLViewerObjectList()
  88. {
  89. mNumVisCulled = 0;
  90. mNumSizeCulled = 0;
  91. mCurLazyUpdateIndex = 0;
  92. mCurBin = 0;
  93. mNumDeadObjects = 0;
  94. mNumOrphans = 0;
  95. mNumNewObjects = 0;
  96. mWasPaused = FALSE;
  97. mNumDeadObjectUpdates = 0;
  98. mNumUnknownKills = 0;
  99. mNumUnknownUpdates = 0;
  100. }
  101. LLViewerObjectList::~LLViewerObjectList()
  102. {
  103. destroy();
  104. }
  105. void LLViewerObjectList::destroy()
  106. {
  107. killAllObjects();
  108. resetObjectBeacons();
  109. mActiveObjects.clear();
  110. mDeadObjects.clear();
  111. mMapObjects.clear();
  112. mUUIDObjectMap.clear();
  113. }
  114. void LLViewerObjectList::getUUIDFromLocal(LLUUID &id,
  115.   const U32 local_id,
  116.   const U32 ip,
  117.   const U32 port)
  118. {
  119. U64 ipport = (((U64)ip) << 32) | (U64)port;
  120. U32 index = sIPAndPortToIndex[ipport];
  121. if (!index)
  122. {
  123. index = sSimulatorMachineIndex++;
  124. sIPAndPortToIndex[ipport] = index;
  125. }
  126. U64 indexid = (((U64)index) << 32) | (U64)local_id;
  127. id = get_if_there(sIndexAndLocalIDToUUID, indexid, LLUUID::null);
  128. }
  129. U64 LLViewerObjectList::getIndex(const U32 local_id,
  130.  const U32 ip,
  131.  const U32 port)
  132. {
  133. U64 ipport = (((U64)ip) << 32) | (U64)port;
  134. U32 index = sIPAndPortToIndex[ipport];
  135. if (!index)
  136. {
  137. return 0;
  138. }
  139. return (((U64)index) << 32) | (U64)local_id;
  140. }
  141. BOOL LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject &object)
  142. {
  143. if(object.getRegion())
  144. {
  145. U32 local_id = object.mLocalID;
  146. LLHost region_host = object.getRegion()->getHost();
  147. U32 ip = region_host.getAddress();
  148. U32 port = region_host.getPort();
  149. U64 ipport = (((U64)ip) << 32) | (U64)port;
  150. U32 index = sIPAndPortToIndex[ipport];
  151. // llinfos << "Removing object from table, local ID " << local_id << ", ip " << ip << ":" << port << llendl;
  152. U64 indexid = (((U64)index) << 32) | (U64)local_id;
  153. std::map<U64, LLUUID>::iterator iter = sIndexAndLocalIDToUUID.find(indexid);
  154. if (iter == sIndexAndLocalIDToUUID.end())
  155. {
  156. return FALSE;
  157. }
  158. // Found existing entry
  159. if (iter->second == object.getID())
  160. {   // Full UUIDs match, so remove the entry
  161. sIndexAndLocalIDToUUID.erase(iter);
  162. return TRUE;
  163. }
  164. // UUIDs did not match - this would zap a valid entry, so don't erase it
  165. //llinfos << "Tried to erase entry where id in table (" 
  166. // << iter->second << ") did not match object " << object.getID() << llendl;
  167. }
  168. return FALSE ;
  169. }
  170. void LLViewerObjectList::setUUIDAndLocal(const LLUUID &id,
  171.   const U32 local_id,
  172.   const U32 ip,
  173.   const U32 port)
  174. {
  175. U64 ipport = (((U64)ip) << 32) | (U64)port;
  176. U32 index = sIPAndPortToIndex[ipport];
  177. if (!index)
  178. {
  179. index = sSimulatorMachineIndex++;
  180. sIPAndPortToIndex[ipport] = index;
  181. }
  182. U64 indexid = (((U64)index) << 32) | (U64)local_id;
  183. sIndexAndLocalIDToUUID[indexid] = id;
  184. //llinfos << "Adding object to table, full ID " << id
  185. // << ", local ID " << local_id << ", ip " << ip << ":" << port << llendl;
  186. }
  187. S32 gFullObjectUpdates = 0;
  188. S32 gTerseObjectUpdates = 0;
  189. void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, 
  190.    void** user_data, 
  191.    U32 i, 
  192.    const EObjectUpdateType update_type, 
  193.    LLDataPacker* dpp, 
  194.    BOOL just_created)
  195. {
  196. LLMemType mt(LLMemType::MTYPE_OBJECT_PROCESS_UPDATE_CORE);
  197. LLMessageSystem* msg = gMessageSystem;
  198. // ignore returned flags
  199. objectp->processUpdateMessage(msg, user_data, i, update_type, dpp);
  200. if (objectp->isDead())
  201. {
  202. // The update failed
  203. return;
  204. }
  205. updateActive(objectp);
  206. if (just_created) 
  207. {
  208. gPipeline.addObject(objectp);
  209. }
  210. // Also sets the approx. pixel area
  211. objectp->setPixelAreaAndAngle(gAgent);
  212. // RN: this must be called after we have a drawable 
  213. // (from gPipeline.addObject)
  214. // so that the drawable parent is set properly
  215. findOrphans(objectp, msg->getSenderIP(), msg->getSenderPort());
  216. // If we're just wandering around, don't create new objects selected.
  217. if (just_created 
  218. && update_type != OUT_TERSE_IMPROVED 
  219. && objectp->mCreateSelected)
  220. {
  221. if ( LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance() )
  222. {
  223. // llinfos << "DEBUG selecting " << objectp->mID << " " 
  224. // << objectp->mLocalID << llendl;
  225. LLSelectMgr::getInstance()->selectObjectAndFamily(objectp);
  226. dialog_refresh_all();
  227. }
  228. objectp->mCreateSelected = false;
  229. gViewerWindow->getWindow()->decBusyCount();
  230. gViewerWindow->setCursor( UI_CURSOR_ARROW );
  231. }
  232. }
  233. static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Objects");
  234. void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
  235.  void **user_data,
  236.  const EObjectUpdateType update_type,
  237.  bool cached, bool compressed)
  238. {
  239. LLMemType mt(LLMemType::MTYPE_OBJECT_PROCESS_UPDATE);
  240. LLFastTimer t(FTM_PROCESS_OBJECTS);
  241. LLVector3d camera_global = gAgent.getCameraPositionGlobal();
  242. LLViewerObject *objectp;
  243. S32 num_objects;
  244. U32 local_id;
  245. LLPCode pcode = 0;
  246. LLUUID fullid;
  247. S32 i;
  248. // figure out which simulator these are from and get it's index
  249. // Coordinates in simulators are region-local
  250. // Until we get region-locality working on viewer we
  251. // have to transform to absolute coordinates.
  252. num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData);
  253. if (!cached && !compressed && update_type != OUT_FULL)
  254. {
  255. gTerseObjectUpdates += num_objects;
  256. S32 size;
  257. if (mesgsys->getReceiveCompressedSize())
  258. {
  259. size = mesgsys->getReceiveCompressedSize();
  260. }
  261. else
  262. {
  263. size = mesgsys->getReceiveSize();
  264. }
  265. // llinfos << "Received terse " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl;
  266. }
  267. else
  268. {
  269. S32 size;
  270. if (mesgsys->getReceiveCompressedSize())
  271. {
  272. size = mesgsys->getReceiveCompressedSize();
  273. }
  274. else
  275. {
  276. size = mesgsys->getReceiveSize();
  277. }
  278. // llinfos << "Received " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl;
  279. gFullObjectUpdates += num_objects;
  280. }
  281. U64 region_handle;
  282. mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle);
  283. LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle);
  284. if (!regionp)
  285. {
  286. llwarns << "Object update from unknown region! " << region_handle << llendl;
  287. return;
  288. }
  289. U8 compressed_dpbuffer[2048];
  290. LLDataPackerBinaryBuffer compressed_dp(compressed_dpbuffer, 2048);
  291. LLDataPacker *cached_dpp = NULL;
  292. for (i = 0; i < num_objects; i++)
  293. {
  294. LLTimer update_timer;
  295. BOOL justCreated = FALSE;
  296. if (cached)
  297. {
  298. U32 id;
  299. U32 crc;
  300. mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, id, i);
  301. mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_CRC, crc, i);
  302. // Lookup data packer and add this id to cache miss lists if necessary.
  303. cached_dpp = regionp->getDP(id, crc);
  304. if (cached_dpp)
  305. {
  306. cached_dpp->reset();
  307. cached_dpp->unpackUUID(fullid, "ID");
  308. cached_dpp->unpackU32(local_id, "LocalID");
  309. cached_dpp->unpackU8(pcode, "PCode");
  310. }
  311. else
  312. {
  313. continue; // no data packer, skip this object
  314. }
  315. }
  316. else if (compressed)
  317. {
  318. U8 compbuffer[2048];
  319. S32 uncompressed_length = 2048;
  320. S32 compressed_length;
  321. compressed_dp.reset();
  322. U32 flags = 0;
  323. if (update_type != OUT_TERSE_IMPROVED)
  324. {
  325. mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i);
  326. }
  327. if (flags & FLAGS_ZLIB_COMPRESSED)
  328. {
  329. compressed_length = mesgsys->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_Data);
  330. mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compbuffer, 0, i);
  331. uncompressed_length = 2048;
  332. uncompress(compressed_dpbuffer, (unsigned long *)&uncompressed_length,
  333.    compbuffer, compressed_length);
  334. compressed_dp.assignBuffer(compressed_dpbuffer, uncompressed_length);
  335. }
  336. else
  337. {
  338. uncompressed_length = mesgsys->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_Data);
  339. mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compressed_dpbuffer, 0, i);
  340. compressed_dp.assignBuffer(compressed_dpbuffer, uncompressed_length);
  341. }
  342. if (update_type != OUT_TERSE_IMPROVED)
  343. {
  344. compressed_dp.unpackUUID(fullid, "ID");
  345. compressed_dp.unpackU32(local_id, "LocalID");
  346. compressed_dp.unpackU8(pcode, "PCode");
  347. }
  348. else
  349. {
  350. compressed_dp.unpackU32(local_id, "LocalID");
  351. getUUIDFromLocal(fullid,
  352.  local_id,
  353.  gMessageSystem->getSenderIP(),
  354.  gMessageSystem->getSenderPort());
  355. if (fullid.isNull())
  356. {
  357. // llwarns << "update for unknown localid " << local_id << " host " << gMessageSystem->getSender() << ":" << gMessageSystem->getSenderPort() << llendl;
  358. mNumUnknownUpdates++;
  359. }
  360. }
  361. }
  362. else if (update_type != OUT_FULL)
  363. {
  364. mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);
  365. getUUIDFromLocal(fullid,
  366. local_id,
  367. gMessageSystem->getSenderIP(),
  368. gMessageSystem->getSenderPort());
  369. if (fullid.isNull())
  370. {
  371. // llwarns << "update for unknown localid " << local_id << " host " << gMessageSystem->getSender() << llendl;
  372. mNumUnknownUpdates++;
  373. }
  374. }
  375. else
  376. {
  377. mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FullID, fullid, i);
  378. mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);
  379. // llinfos << "Full Update, obj " << local_id << ", global ID" << fullid << "from " << mesgsys->getSender() << llendl;
  380. }
  381. objectp = findObject(fullid);
  382. // This looks like it will break if the local_id of the object doesn't change
  383. // upon boundary crossing, but we check for region id matching later...
  384. // Reset object local id and region pointer if things have changed
  385. if (objectp && 
  386. ((objectp->mLocalID != local_id) ||
  387.  (objectp->getRegion() != regionp)))
  388. {
  389. //if (objectp->getRegion())
  390. //{
  391. // llinfos << "Local ID change: Removing object from table, local ID " << objectp->mLocalID 
  392. // << ", id from message " << local_id << ", from " 
  393. // << LLHost(objectp->getRegion()->getHost().getAddress(), objectp->getRegion()->getHost().getPort())
  394. // << ", full id " << fullid 
  395. // << ", objects id " << objectp->getID()
  396. // << ", regionp " << (U32) regionp << ", object region " << (U32) objectp->getRegion()
  397. // << llendl;
  398. //}
  399. removeFromLocalIDTable(*objectp);
  400. setUUIDAndLocal(fullid,
  401. local_id,
  402. gMessageSystem->getSenderIP(),
  403. gMessageSystem->getSenderPort());
  404. if (objectp->mLocalID != local_id)
  405. {    // Update local ID in object with the one sent from the region
  406. objectp->mLocalID = local_id;
  407. }
  408. if (objectp->getRegion() != regionp)
  409. {    // Object changed region, so update it
  410. objectp->setRegion(regionp);
  411. objectp->updateRegion(regionp); // for LLVOAvatar
  412. }
  413. }
  414. if (!objectp)
  415. {
  416. if (compressed)
  417. {
  418. if (update_type == OUT_TERSE_IMPROVED)
  419. {
  420. // llinfos << "terse update for an unknown object:" << fullid << llendl;
  421. continue;
  422. }
  423. }
  424. else if (cached)
  425. {
  426. }
  427. else
  428. {
  429. if (update_type != OUT_FULL)
  430. {
  431. // llinfos << "terse update for an unknown object:" << fullid << llendl;
  432. continue;
  433. }
  434. mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_PCode, pcode, i);
  435. }
  436. #ifdef IGNORE_DEAD
  437. if (mDeadObjects.find(fullid) != mDeadObjects.end())
  438. {
  439. mNumDeadObjectUpdates++;
  440. // llinfos << "update for a dead object:" << fullid << llendl;
  441. continue;
  442. }
  443. #endif
  444. objectp = createObject(pcode, regionp, fullid, local_id, gMessageSystem->getSender());
  445. if (!objectp)
  446. {
  447. continue;
  448. }
  449. justCreated = TRUE;
  450. mNumNewObjects++;
  451. }
  452. if (objectp->isDead())
  453. {
  454. llwarns << "Dead object " << objectp->mID << " in UUID map 1!" << llendl;
  455. }
  456. if (compressed)
  457. {
  458. if (update_type != OUT_TERSE_IMPROVED)
  459. {
  460. objectp->mLocalID = local_id;
  461. }
  462. processUpdateCore(objectp, user_data, i, update_type, &compressed_dp, justCreated);
  463. if (update_type != OUT_TERSE_IMPROVED)
  464. {
  465. objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp);
  466. }
  467. }
  468. else if (cached)
  469. {
  470. objectp->mLocalID = local_id;
  471. processUpdateCore(objectp, user_data, i, update_type, cached_dpp, justCreated);
  472. }
  473. else
  474. {
  475. if (update_type == OUT_FULL)
  476. {
  477. objectp->mLocalID = local_id;
  478. }
  479. processUpdateCore(objectp, user_data, i, update_type, NULL, justCreated);
  480. }
  481. }
  482. LLVOAvatar::cullAvatarsByPixelArea();
  483. }
  484. void LLViewerObjectList::processCompressedObjectUpdate(LLMessageSystem *mesgsys,
  485.  void **user_data,
  486.  const EObjectUpdateType update_type)
  487. {
  488. processObjectUpdate(mesgsys, user_data, update_type, false, true);
  489. }
  490. void LLViewerObjectList::processCachedObjectUpdate(LLMessageSystem *mesgsys,
  491.  void **user_data,
  492.  const EObjectUpdateType update_type)
  493. {
  494. processObjectUpdate(mesgsys, user_data, update_type, true, false);
  495. }
  496. void LLViewerObjectList::dirtyAllObjectInventory()
  497. {
  498. S32 count = mObjects.count();
  499. for(S32 i = 0; i < count; ++i)
  500. {
  501. mObjects[i]->dirtyInventory();
  502. }
  503. }
  504. void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
  505. {
  506. S32 i;
  507. S32 num_objects = 0;
  508. LLViewerObject *objectp;
  509. S32 num_updates, max_value;
  510. if (NUM_BINS - 1 == mCurBin)
  511. {
  512. num_updates = mObjects.count() - mCurLazyUpdateIndex;
  513. max_value = mObjects.count();
  514. gTextureList.setUpdateStats(TRUE);
  515. }
  516. else
  517. {
  518. num_updates = (mObjects.count() / NUM_BINS) + 1;
  519. max_value = llmin(mObjects.count(), mCurLazyUpdateIndex + num_updates);
  520. }
  521. if (!gNoRender)
  522. {
  523. // Slam priorities for textures that we care about (hovered, selected, and focused)
  524. // Hovered
  525. // Assumes only one level deep of parenting
  526. LLSelectNode* nodep = LLSelectMgr::instance().getHoverNode();
  527. if (nodep)
  528. {
  529. objectp = nodep->getObject();
  530. if (objectp)
  531. {
  532. objectp->boostTexturePriority();
  533. }
  534. }
  535. }
  536. // Focused
  537. objectp = gAgent.getFocusObject();
  538. if (objectp)
  539. {
  540. objectp->boostTexturePriority();
  541. }
  542. // Selected
  543. struct f : public LLSelectedObjectFunctor
  544. {
  545. virtual bool apply(LLViewerObject* objectp)
  546. {
  547. objectp->boostTexturePriority();
  548. return true;
  549. }
  550. } func;
  551. LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func);
  552. // Iterate through some of the objects and lazy update their texture priorities
  553. for (i = mCurLazyUpdateIndex; i < max_value; i++)
  554. {
  555. objectp = mObjects[i];
  556. if (!objectp->isDead())
  557. {
  558. num_objects++;
  559. //  Update distance & gpw 
  560. objectp->setPixelAreaAndAngle(agent); // Also sets the approx. pixel area
  561. objectp->updateTextures(); // Update the image levels of textures for this object.
  562. }
  563. }
  564. mCurLazyUpdateIndex = max_value;
  565. if (mCurLazyUpdateIndex == mObjects.count())
  566. {
  567. mCurLazyUpdateIndex = 0;
  568. }
  569. mCurBin = (mCurBin + 1) % NUM_BINS;
  570. LLVOAvatar::cullAvatarsByPixelArea();
  571. }
  572. void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
  573. {
  574. LLMemType mt(LLMemType::MTYPE_OBJECT);
  575. // Update globals
  576. gVelocityInterpolate = gSavedSettings.getBOOL("VelocityInterpolate");
  577. gPingInterpolate = gSavedSettings.getBOOL("PingInterpolate");
  578. gAnimateTextures = gSavedSettings.getBOOL("AnimateTextures");
  579. // update global timer
  580. F32 last_time = gFrameTimeSeconds;
  581. U64 time = totalTime();                 // this will become the new gFrameTime when the update is done
  582. // Time _can_ go backwards, for example if the user changes the system clock.
  583. // It doesn't cause any fatal problems (just some oddness with stats), so we shouldn't assert here.
  584. // llassert(time > gFrameTime);
  585. F64 time_diff = U64_to_F64(time - gFrameTime)/(F64)SEC_TO_MICROSEC;
  586. gFrameTime    = time;
  587. F64 time_since_start = U64_to_F64(gFrameTime - gStartTime)/(F64)SEC_TO_MICROSEC;
  588. gFrameTimeSeconds = (F32)time_since_start;
  589. gFrameIntervalSeconds = gFrameTimeSeconds - last_time;
  590. if (gFrameIntervalSeconds < 0.f)
  591. {
  592. gFrameIntervalSeconds = 0.f;
  593. }
  594. //clear avatar LOD change counter
  595. LLVOAvatar::sNumLODChangesThisFrame = 0;
  596. const F64 frame_time = LLFrameTimer::getElapsedSeconds();
  597. std::vector<LLViewerObject*> kill_list;
  598. S32 num_active_objects = 0;
  599. LLViewerObject *objectp = NULL;
  600. // Make a copy of the list in case something in idleUpdate() messes with it
  601. std::vector<LLViewerObject*> idle_list;
  602. idle_list.reserve( mActiveObjects.size() );
  603.   for (std::set<LLPointer<LLViewerObject> >::iterator active_iter = mActiveObjects.begin();
  604. active_iter != mActiveObjects.end(); active_iter++)
  605. {
  606. objectp = *active_iter;
  607. if (objectp)
  608. {
  609. idle_list.push_back( objectp );
  610. }
  611. else
  612. { // There shouldn't be any NULL pointers in the list, but they have caused
  613. // crashes before.  This may be idleUpdate() messing with the list.
  614. llwarns << "LLViewerObjectList::update has a NULL objectp" << llendl;
  615. }
  616. }
  617. if (gSavedSettings.getBOOL("FreezeTime"))
  618. {
  619. for (std::vector<LLViewerObject*>::iterator iter = idle_list.begin();
  620. iter != idle_list.end(); iter++)
  621. {
  622. objectp = *iter;
  623. if (objectp->getPCode() == LLViewerObject::LL_VO_CLOUDS ||
  624. objectp->isAvatar())
  625. {
  626. objectp->idleUpdate(agent, world, frame_time);
  627. }
  628. }
  629. }
  630. else
  631. {
  632. for (std::vector<LLViewerObject*>::iterator idle_iter = idle_list.begin();
  633. idle_iter != idle_list.end(); idle_iter++)
  634. {
  635. objectp = *idle_iter;
  636. if (!objectp->idleUpdate(agent, world, frame_time))
  637. {
  638. //  If Idle Update returns false, kill object!
  639. kill_list.push_back(objectp);
  640. }
  641. else
  642. {
  643. num_active_objects++;
  644. }
  645. }
  646. for (std::vector<LLViewerObject*>::iterator kill_iter = kill_list.begin();
  647. kill_iter != kill_list.end(); kill_iter++)
  648. {
  649. objectp = *kill_iter;
  650. killObject(objectp);
  651. }
  652. }
  653. mNumSizeCulled = 0;
  654. mNumVisCulled = 0;
  655. // compute all sorts of time-based stats
  656. // don't factor frames that were paused into the stats
  657. if (! mWasPaused)
  658. {
  659. LLViewerStats::getInstance()->updateFrameStats(time_diff);
  660. }
  661. /*
  662. // Debugging code for viewing orphans, and orphaned parents
  663. LLUUID id;
  664. for (i = 0; i < mOrphanParents.count(); i++)
  665. {
  666. id = sIndexAndLocalIDToUUID[mOrphanParents[i]];
  667. LLViewerObject *objectp = findObject(id);
  668. if (objectp)
  669. {
  670. std::string id_str;
  671. objectp->mID.toString(id_str);
  672. std::string tmpstr = std::string("Par:    ") + id_str;
  673. addDebugBeacon(objectp->getPositionAgent(),
  674. tmpstr,
  675. LLColor4(1.f,0.f,0.f,1.f),
  676. LLColor4(1.f,1.f,1.f,1.f));
  677. }
  678. }
  679. LLColor4 text_color;
  680. for (i = 0; i < mOrphanChildren.count(); i++)
  681. {
  682. OrphanInfo oi = mOrphanChildren[i];
  683. LLViewerObject *objectp = findObject(oi.mChildInfo);
  684. if (objectp)
  685. {
  686. std::string id_str;
  687. objectp->mID.toString(id_str);
  688. std::string tmpstr;
  689. if (objectp->getParent())
  690. {
  691. tmpstr = std::string("ChP:    ") + id_str;
  692. text_color = LLColor4(0.f, 1.f, 0.f, 1.f);
  693. }
  694. else
  695. {
  696. tmpstr = std::string("ChNoP:    ") + id_str;
  697. text_color = LLColor4(1.f, 0.f, 0.f, 1.f);
  698. }
  699. id = sIndexAndLocalIDToUUID[oi.mParentInfo];
  700. addDebugBeacon(objectp->getPositionAgent() + LLVector3(0.f, 0.f, -0.25f),
  701. tmpstr,
  702. LLColor4(0.25f,0.25f,0.25f,1.f),
  703. text_color);
  704. }
  705. i++;
  706. }
  707. */
  708. LLViewerStats::getInstance()->mNumObjectsStat.addValue(mObjects.count());
  709. LLViewerStats::getInstance()->mNumActiveObjectsStat.addValue(num_active_objects);
  710. LLViewerStats::getInstance()->mNumSizeCulledStat.addValue(mNumSizeCulled);
  711. LLViewerStats::getInstance()->mNumVisCulledStat.addValue(mNumVisCulled);
  712. }
  713. void LLViewerObjectList::clearDebugText()
  714. {
  715. for (S32 i = 0; i < mObjects.count(); i++)
  716. {
  717. mObjects[i]->setDebugText("");
  718. }
  719. }
  720. void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp)
  721. {
  722. LLMemType mt(LLMemType::MTYPE_OBJECT);
  723. if (mDeadObjects.count(objectp->mID))
  724. {
  725. llinfos << "Object " << objectp->mID << " already on dead list, ignoring cleanup!" << llendl;
  726. return;
  727. }
  728. mDeadObjects.insert(std::pair<LLUUID, LLPointer<LLViewerObject> >(objectp->mID, objectp));
  729. // Cleanup any references we have to this object
  730. // Remove from object map so noone can look it up.
  731. mUUIDObjectMap.erase(objectp->mID);
  732. //if (objectp->getRegion())
  733. //{
  734. // llinfos << "cleanupReferences removing object from table, local ID " << objectp->mLocalID << ", ip " 
  735. // << objectp->getRegion()->getHost().getAddress() << ":" 
  736. // << objectp->getRegion()->getHost().getPort() << llendl;
  737. //}
  738. removeFromLocalIDTable(*objectp);
  739. if (objectp->onActiveList())
  740. {
  741. //llinfos << "Removing " << objectp->mID << " " << objectp->getPCodeString() << " from active list in cleanupReferences." << llendl;
  742. objectp->setOnActiveList(FALSE);
  743. mActiveObjects.erase(objectp);
  744. }
  745. if (objectp->isOnMap())
  746. {
  747. mMapObjects.removeObj(objectp);
  748. }
  749. // Don't clean up mObject references, these will be cleaned up more efficiently later!
  750. // Also, not cleaned up
  751. removeDrawable(objectp->mDrawable);
  752. mNumDeadObjects++;
  753. }
  754. void LLViewerObjectList::removeDrawable(LLDrawable* drawablep)
  755. {
  756. if (!drawablep)
  757. {
  758. return;
  759. }
  760. for (S32 i = 0; i < drawablep->getNumFaces(); i++)
  761. {
  762. LLFace* facep = drawablep->getFace(i) ;
  763. if(facep)
  764. {
  765.    LLViewerObject* objectp = facep->getViewerObject();
  766.    if(objectp)
  767.    {
  768.    mSelectPickList.erase(objectp);
  769.    }
  770. }
  771. }
  772. }
  773. BOOL LLViewerObjectList::killObject(LLViewerObject *objectp)
  774. {
  775. // When we're killing objects, all we do is mark them as dead.
  776. // We clean up the dead objects later.
  777. if (objectp)
  778. {
  779. if (objectp->isDead())
  780. {
  781. // This object is already dead.  Don't need to do more.
  782. return TRUE;
  783. }
  784. else
  785. {
  786. objectp->markDead();
  787. }
  788. return TRUE;
  789. }
  790. return FALSE;
  791. }
  792. void LLViewerObjectList::killObjects(LLViewerRegion *regionp)
  793. {
  794. LLViewerObject *objectp;
  795. S32 i;
  796. for (i = 0; i < mObjects.count(); i++)
  797. {
  798. objectp = mObjects[i];
  799. if (objectp->mRegionp == regionp)
  800. {
  801. killObject(objectp);
  802. }
  803. }
  804. // Have to clean right away because the region is becoming invalid.
  805. cleanDeadObjects(FALSE);
  806. }
  807. void LLViewerObjectList::killAllObjects()
  808. {
  809. // Used only on global destruction.
  810. LLViewerObject *objectp;
  811. for (S32 i = 0; i < mObjects.count(); i++)
  812. {
  813. objectp = mObjects[i];
  814. killObject(objectp);
  815. llassert(objectp->isDead());
  816. }
  817. cleanDeadObjects(FALSE);
  818. if(!mObjects.empty())
  819. {
  820. llwarns << "LLViewerObjectList::killAllObjects still has entries in mObjects: " << mObjects.count() << llendl;
  821. mObjects.clear();
  822. }
  823. if (!mActiveObjects.empty())
  824. {
  825. llwarns << "Some objects still on active object list!" << llendl;
  826. mActiveObjects.clear();
  827. }
  828. if (!mMapObjects.empty())
  829. {
  830. llwarns << "Some objects still on map object list!" << llendl;
  831. mMapObjects.clear();
  832. }
  833. }
  834. void LLViewerObjectList::cleanDeadObjects(BOOL use_timer)
  835. {
  836. if (!mNumDeadObjects)
  837. {
  838. // No dead objects, don't need to scan object list.
  839. return;
  840. }
  841. S32 i = 0;
  842. S32 num_removed = 0;
  843. LLViewerObject *objectp;
  844. while (i < mObjects.count())
  845. {
  846. // Scan for all of the dead objects and remove any "global" references to them.
  847. objectp = mObjects[i];
  848. if (objectp->isDead())
  849. {
  850. mObjects.remove(i);
  851. num_removed++;
  852. if (num_removed == mNumDeadObjects)
  853. {
  854. // We've cleaned up all of the dead objects.
  855. break;
  856. }
  857. }
  858. else
  859. {
  860. // iterate, this isn't a dead object.
  861. i++;
  862. }
  863. }
  864. // We've cleaned the global object list, now let's do some paranoia testing on objects
  865. // before blowing away the dead list.
  866. mDeadObjects.clear();
  867. mNumDeadObjects = 0;
  868. }
  869. void LLViewerObjectList::updateActive(LLViewerObject *objectp)
  870. {
  871. LLMemType mt(LLMemType::MTYPE_OBJECT);
  872. if (objectp->isDead())
  873. {
  874. return; // We don't update dead objects!
  875. }
  876. BOOL active = objectp->isActive();
  877. if (active != objectp->onActiveList())
  878. {
  879. if (active)
  880. {
  881. //llinfos << "Adding " << objectp->mID << " " << objectp->getPCodeString() << " to active list." << llendl;
  882. mActiveObjects.insert(objectp);
  883. objectp->setOnActiveList(TRUE);
  884. }
  885. else
  886. {
  887. //llinfos << "Removing " << objectp->mID << " " << objectp->getPCodeString() << " from active list." << llendl;
  888. mActiveObjects.erase(objectp);
  889. objectp->setOnActiveList(FALSE);
  890. }
  891. }
  892. }
  893. void LLViewerObjectList::shiftObjects(const LLVector3 &offset)
  894. {
  895. // This is called when we shift our origin when we cross region boundaries...
  896. // We need to update many object caches, I'll document this more as I dig through the code
  897. // cleaning things out...
  898. if (gNoRender || 0 == offset.magVecSquared())
  899. {
  900. return;
  901. }
  902. LLViewerObject *objectp;
  903. S32 i;
  904. for (i = 0; i < mObjects.count(); i++)
  905. {
  906. objectp = getObject(i);
  907. // There could be dead objects on the object list, so don't update stuff if the object is dead.
  908. if (objectp)
  909. {
  910. objectp->updatePositionCaches();
  911. if (objectp->mDrawable.notNull() && !objectp->mDrawable->isDead())
  912. {
  913. gPipeline.markShift(objectp->mDrawable);
  914. }
  915. }
  916. }
  917. gPipeline.shiftObjects(offset);
  918. LLWorld::getInstance()->shiftRegions(offset);
  919. }
  920. void LLViewerObjectList::renderObjectsForMap(LLNetMap &netmap)
  921. {
  922. LLColor4 above_water_color = LLUIColorTable::instance().getColor( "NetMapOtherOwnAboveWater" );
  923. LLColor4 below_water_color = LLUIColorTable::instance().getColor( "NetMapOtherOwnBelowWater" );
  924. LLColor4 you_own_above_water_color = 
  925. LLUIColorTable::instance().getColor( "NetMapYouOwnAboveWater" );
  926. LLColor4 you_own_below_water_color = 
  927. LLUIColorTable::instance().getColor( "NetMapYouOwnBelowWater" );
  928. LLColor4 group_own_above_water_color = 
  929. LLUIColorTable::instance().getColor( "NetMapGroupOwnAboveWater" );
  930. LLColor4 group_own_below_water_color = 
  931. LLUIColorTable::instance().getColor( "NetMapGroupOwnBelowWater" );
  932. F32 max_radius = gSavedSettings.getF32("MiniMapPrimMaxRadius");
  933. for (S32 i = 0; i < mMapObjects.count(); i++)
  934. {
  935. LLViewerObject* objectp = mMapObjects[i];
  936. if (!objectp->getRegion() || objectp->isOrphaned() || objectp->isAttachment())
  937. {
  938. continue;
  939. }
  940. const LLVector3& scale = objectp->getScale();
  941. const LLVector3d pos = objectp->getPositionGlobal();
  942. const F64 water_height = F64( objectp->getRegion()->getWaterHeight() );
  943. // LLWorld::getInstance()->getWaterHeight();
  944. F32 approx_radius = (scale.mV[VX] + scale.mV[VY]) * 0.5f * 0.5f * 1.3f;  // 1.3 is a fudge
  945. // Limit the size of megaprims so they don't blot out everything on the minimap.
  946. // Attempting to draw very large megaprims also causes client lag.
  947. // See DEV-17370 and DEV-29869/SNOW-79 for details.
  948. approx_radius = llmin(approx_radius, max_radius);
  949. LLColor4U color = above_water_color;
  950. if( objectp->permYouOwner() )
  951. {
  952. const F32 MIN_RADIUS_FOR_OWNED_OBJECTS = 2.f;
  953. if( approx_radius < MIN_RADIUS_FOR_OWNED_OBJECTS )
  954. {
  955. approx_radius = MIN_RADIUS_FOR_OWNED_OBJECTS;
  956. }
  957. if( pos.mdV[VZ] >= water_height )
  958. {
  959. if ( objectp->permGroupOwner() )
  960. {
  961. color = group_own_above_water_color;
  962. }
  963. else
  964. {
  965. color = you_own_above_water_color;
  966. }
  967. }
  968. else
  969. {
  970. if ( objectp->permGroupOwner() )
  971. {
  972. color = group_own_below_water_color;
  973. }
  974. else
  975. {
  976. color = you_own_below_water_color;
  977. }
  978. }
  979. }
  980. else
  981. if( pos.mdV[VZ] < water_height )
  982. {
  983. color = below_water_color;
  984. }
  985. netmap.renderScaledPointGlobal( 
  986. pos, 
  987. color,
  988. approx_radius );
  989. }
  990. }
  991. void LLViewerObjectList::renderObjectBounds(const LLVector3 &center)
  992. {
  993. }
  994. void LLViewerObjectList::renderObjectsForSelect(LLCamera &camera, const LLRect& screen_rect, BOOL pick_parcel_wall, BOOL render_transparent)
  995. {
  996. generatePickList(camera);
  997. renderPickList(screen_rect, pick_parcel_wall, render_transparent);
  998. }
  999. void LLViewerObjectList::generatePickList(LLCamera &camera)
  1000. {
  1001. LLViewerObject *objectp;
  1002. S32 i;
  1003. // Reset all of the GL names to zero.
  1004. for (i = 0; i < mObjects.count(); i++)
  1005. {
  1006. objectp = mObjects[i];
  1007. objectp->mGLName = 0;
  1008. }
  1009. mSelectPickList.clear();
  1010. std::vector<LLDrawable*> pick_drawables;
  1011. for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
  1012. iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
  1013. {
  1014. LLViewerRegion* region = *iter;
  1015. for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
  1016. {
  1017. LLSpatialPartition* part = region->getSpatialPartition(i);
  1018. if (part)
  1019. {
  1020. part->cull(camera, &pick_drawables, TRUE);
  1021. }
  1022. }
  1023. }
  1024. for (std::vector<LLDrawable*>::iterator iter = pick_drawables.begin();
  1025. iter != pick_drawables.end(); iter++)
  1026. {
  1027. LLDrawable* drawablep = *iter;
  1028. if( !drawablep )
  1029. continue;
  1030. LLViewerObject* last_objectp = NULL;
  1031. for (S32 face_num = 0; face_num < drawablep->getNumFaces(); face_num++)
  1032. {
  1033. LLViewerObject* objectp = drawablep->getFace(face_num)->getViewerObject();
  1034. if (objectp && objectp != last_objectp)
  1035. {
  1036. mSelectPickList.insert(objectp);
  1037. last_objectp = objectp;
  1038. }
  1039. }
  1040. }
  1041. LLHUDText::addPickable(mSelectPickList);
  1042. for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
  1043. iter != LLCharacter::sInstances.end(); ++iter)
  1044. {
  1045. objectp = (LLVOAvatar*) *iter;
  1046. if (!objectp->isDead())
  1047. {
  1048. if (objectp->mDrawable.notNull() && objectp->mDrawable->isVisible())
  1049. {
  1050. mSelectPickList.insert(objectp);
  1051. }
  1052. }
  1053. }
  1054. // add all hud objects to pick list
  1055. LLVOAvatar* avatarp = gAgent.getAvatarObject();
  1056. if (avatarp)
  1057. {
  1058. for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); 
  1059.  iter != avatarp->mAttachmentPoints.end(); )
  1060. {
  1061. LLVOAvatar::attachment_map_t::iterator curiter = iter++;
  1062. LLViewerJointAttachment* attachment = curiter->second;
  1063. if (attachment->getIsHUDAttachment())
  1064. {
  1065. for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
  1066.  attachment_iter != attachment->mAttachedObjects.end();
  1067.  ++attachment_iter)
  1068. {
  1069. if (LLViewerObject* attached_object = (*attachment_iter))
  1070. {
  1071. mSelectPickList.insert(attached_object);
  1072. LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
  1073. for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
  1074.  iter != child_list.end(); iter++)
  1075. {
  1076. LLViewerObject* childp = *iter;
  1077. if (childp)
  1078. {
  1079. mSelectPickList.insert(childp);
  1080. }
  1081. }
  1082. }
  1083. }
  1084. }
  1085. }
  1086. }
  1087. S32 num_pickables = (S32)mSelectPickList.size() + LLHUDIcon::getNumInstances();
  1088. if (num_pickables != 0)
  1089. {
  1090. S32 step = (0x000fffff - GL_NAME_INDEX_OFFSET) / num_pickables;
  1091. std::set<LLViewerObject*>::iterator pick_it;
  1092. i = 0;
  1093. for (pick_it = mSelectPickList.begin(); pick_it != mSelectPickList.end();)
  1094. {
  1095. LLViewerObject* objp = (*pick_it);
  1096. if (!objp || objp->isDead() || !objp->mbCanSelect)
  1097. {
  1098. mSelectPickList.erase(pick_it++);
  1099. continue;
  1100. }
  1101. objp->mGLName = (i * step) + GL_NAME_INDEX_OFFSET;
  1102. i++;
  1103. ++pick_it;
  1104. }
  1105. LLHUDIcon::generatePickIDs(i * step, step);
  1106. }
  1107. }
  1108. void LLViewerObjectList::renderPickList(const LLRect& screen_rect, BOOL pick_parcel_wall, BOOL render_transparent)
  1109. {
  1110. gRenderForSelect = TRUE;
  1111. gPipeline.renderForSelect(mSelectPickList, render_transparent, screen_rect);
  1112. //
  1113. // Render pass for selected objects
  1114. //
  1115. gGL.color4f(1,1,1,1);
  1116. gViewerWindow->renderSelections( TRUE, pick_parcel_wall, FALSE );
  1117. //fix for DEV-19335.  Don't pick hud objects when customizing avatar (camera mode doesn't play nice with nametags).
  1118. if (!gAgent.cameraCustomizeAvatar())
  1119. {
  1120. // render pickable ui elements, like names, etc.
  1121. LLHUDObject::renderAllForSelect();
  1122. }
  1123. gGL.flush();
  1124. LLVertexBuffer::unbind();
  1125. gRenderForSelect = FALSE;
  1126. //llinfos << "Rendered " << count << " for select" << llendl;
  1127. //llinfos << "Took " << pick_timer.getElapsedTimeF32()*1000.f << "ms to pick" << llendl;
  1128. }
  1129. LLViewerObject *LLViewerObjectList::getSelectedObject(const U32 object_id)
  1130. {
  1131. std::set<LLViewerObject*>::iterator pick_it;
  1132. for (pick_it = mSelectPickList.begin(); pick_it != mSelectPickList.end(); ++pick_it)
  1133. {
  1134. if ((*pick_it)->mGLName == object_id)
  1135. {
  1136. return (*pick_it);
  1137. }
  1138. }
  1139. return NULL;
  1140. }
  1141. void LLViewerObjectList::addDebugBeacon(const LLVector3 &pos_agent,
  1142. const std::string &string,
  1143. const LLColor4 &color,
  1144. const LLColor4 &text_color,
  1145. S32 line_width)
  1146. {
  1147. LLDebugBeacon *beaconp = mDebugBeacons.reserve_block(1);
  1148. beaconp->mPositionAgent = pos_agent;
  1149. beaconp->mString = string;
  1150. beaconp->mColor = color;
  1151. beaconp->mTextColor = text_color;
  1152. beaconp->mLineWidth = line_width;
  1153. }
  1154. void LLViewerObjectList::resetObjectBeacons()
  1155. {
  1156. mDebugBeacons.reset();
  1157. }
  1158. LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLViewerRegion *regionp)
  1159. {
  1160. LLMemType mt(LLMemType::MTYPE_OBJECT);
  1161. LLUUID fullid;
  1162. fullid.generate();
  1163. LLViewerObject *objectp = LLViewerObject::createObject(fullid, pcode, regionp);
  1164. if (!objectp)
  1165. {
  1166. //  llwarns << "Couldn't create object of type " << LLPrimitive::pCodeToString(pcode) << llendl;
  1167. return NULL;
  1168. }
  1169. mUUIDObjectMap[fullid] = objectp;
  1170. mObjects.put(objectp);
  1171. updateActive(objectp);
  1172. return objectp;
  1173. }
  1174. static LLFastTimer::DeclareTimer FTM_CREATE_OBJECT("Create Object");
  1175. LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRegion *regionp,
  1176.  const LLUUID &uuid, const U32 local_id, const LLHost &sender)
  1177. {
  1178. LLMemType mt(LLMemType::MTYPE_OBJECT);
  1179. LLFastTimer t(FTM_CREATE_OBJECT);
  1180. LLUUID fullid;
  1181. if (uuid == LLUUID::null)
  1182. {
  1183. fullid.generate();
  1184. }
  1185. else
  1186. {
  1187. fullid = uuid;
  1188. }
  1189. LLViewerObject *objectp = LLViewerObject::createObject(fullid, pcode, regionp);
  1190. if (!objectp)
  1191. {
  1192. //  llwarns << "Couldn't create object of type " << LLPrimitive::pCodeToString(pcode) << " id:" << fullid << llendl;
  1193. return NULL;
  1194. }
  1195. mUUIDObjectMap[fullid] = objectp;
  1196. setUUIDAndLocal(fullid,
  1197. local_id,
  1198. gMessageSystem->getSenderIP(),
  1199. gMessageSystem->getSenderPort());
  1200. mObjects.put(objectp);
  1201. updateActive(objectp);
  1202. return objectp;
  1203. }
  1204. LLViewerObject *LLViewerObjectList::replaceObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
  1205. {
  1206. LLViewerObject *old_instance = findObject(id);
  1207. if (old_instance)
  1208. {
  1209. cleanupReferences(old_instance);
  1210. old_instance->markDead();
  1211. return createObject(pcode, regionp, id, old_instance->getLocalID(), LLHost());
  1212. }
  1213. return NULL;
  1214. }
  1215. S32 LLViewerObjectList::findReferences(LLDrawable *drawablep) const
  1216. {
  1217. LLViewerObject *objectp;
  1218. S32 i;
  1219. S32 num_refs = 0;
  1220. for (i = 0; i < mObjects.count(); i++)
  1221. {
  1222. objectp = mObjects[i];
  1223. if (objectp->mDrawable.notNull())
  1224. {
  1225. num_refs += objectp->mDrawable->findReferences(drawablep);
  1226. }
  1227. }
  1228. return num_refs;
  1229. }
  1230. void LLViewerObjectList::orphanize(LLViewerObject *childp, U32 parent_id, U32 ip, U32 port)
  1231. {
  1232. LLMemType mt(LLMemType::MTYPE_OBJECT);
  1233. #ifdef ORPHAN_SPAM
  1234. llinfos << "Orphaning object " << childp->getID() << " with parent " << parent_id << llendl;
  1235. #endif
  1236. // We're an orphan, flag things appropriately.
  1237. childp->mOrphaned = TRUE;
  1238. if (childp->mDrawable.notNull())
  1239. {
  1240. bool make_invisible = true;
  1241. LLViewerObject *parentp = (LLViewerObject *)childp->getParent();
  1242. if (parentp)
  1243. {
  1244. if (parentp->getRegion() != childp->getRegion())
  1245. {
  1246. // This is probably an object flying across a region boundary, the
  1247. // object probably ISN'T being reparented, but just got an object
  1248. // update out of order (child update before parent).
  1249. make_invisible = false;
  1250. //llinfos << "Don't make object handoffs invisible!" << llendl;
  1251. }
  1252. }
  1253. if (make_invisible)
  1254. {
  1255. // Make sure that this object becomes invisible if it's an orphan
  1256. childp->mDrawable->setState(LLDrawable::FORCE_INVISIBLE);
  1257. }
  1258. }
  1259. // Unknown parent, add to orpaned child list
  1260. U64 parent_info = getIndex(parent_id, ip, port);
  1261. if (-1 == mOrphanParents.find(parent_info))
  1262. {
  1263. mOrphanParents.put(parent_info);
  1264. }
  1265. LLViewerObjectList::OrphanInfo oi(parent_info, childp->mID);
  1266. if (-1 == mOrphanChildren.find(oi))
  1267. {
  1268. mOrphanChildren.put(oi);
  1269. mNumOrphans++;
  1270. }
  1271. }
  1272. void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port)
  1273. {
  1274. if (gNoRender)
  1275. {
  1276. return;
  1277. }
  1278. if (objectp->isDead())
  1279. {
  1280. llwarns << "Trying to find orphans for dead obj " << objectp->mID 
  1281. << ":" << objectp->getPCodeString() << llendl;
  1282. return;
  1283. }
  1284. // See if we are a parent of an orphan.
  1285. // Note:  This code is fairly inefficient but it should happen very rarely.
  1286. // It can be sped up if this is somehow a performance issue...
  1287. if (0 == mOrphanParents.count())
  1288. {
  1289. // no known orphan parents
  1290. return;
  1291. }
  1292. if (-1 == mOrphanParents.find(getIndex(objectp->mLocalID, ip, port)))
  1293. {
  1294. // did not find objectp in OrphanParent list
  1295. return;
  1296. }
  1297. S32 i;
  1298. U64 parent_info = getIndex(objectp->mLocalID, ip, port);
  1299. BOOL orphans_found = FALSE;
  1300. // Iterate through the orphan list, and set parents of matching children.
  1301. for (i = 0; i < mOrphanChildren.count(); i++)
  1302. {
  1303. if (mOrphanChildren[i].mParentInfo != parent_info)
  1304. {
  1305. continue;
  1306. }
  1307. LLViewerObject *childp = findObject(mOrphanChildren[i].mChildInfo);
  1308. if (childp)
  1309. {
  1310. if (childp == objectp)
  1311. {
  1312. llwarns << objectp->mID << " has self as parent, skipping!" 
  1313. << llendl;
  1314. continue;
  1315. }
  1316. #ifdef ORPHAN_SPAM
  1317. llinfos << "Reunited parent " << objectp->mID 
  1318. << " with child " << childp->mID << llendl;
  1319. llinfos << "Glob: " << objectp->getPositionGlobal() << llendl;
  1320. llinfos << "Agent: " << objectp->getPositionAgent() << llendl;
  1321. addDebugBeacon(objectp->getPositionAgent(),"");
  1322. #endif
  1323.             gPipeline.markMoved(objectp->mDrawable);                
  1324.             objectp->setChanged(LLXform::MOVED | LLXform::SILHOUETTE);
  1325. // Flag the object as no longer orphaned
  1326. childp->mOrphaned = FALSE;
  1327. if (childp->mDrawable.notNull())
  1328. {
  1329. // Make the drawable visible again and set the drawable parent
  1330.   childp->mDrawable->setState(LLDrawable::CLEAR_INVISIBLE);
  1331. childp->setDrawableParent(objectp->mDrawable); // LLViewerObjectList::findOrphans()
  1332. }
  1333. // Make certain particles, icon and HUD aren't hidden
  1334. childp->hideExtraDisplayItems( FALSE );
  1335. objectp->addChild(childp);
  1336. orphans_found = TRUE;
  1337. }
  1338. else
  1339. {
  1340. llinfos << "Missing orphan child, removing from list" << llendl;
  1341. mOrphanChildren.remove(i);
  1342. i--;
  1343. }
  1344. }
  1345. // Remove orphan parent and children from lists now that they've been found
  1346. mOrphanParents.remove(mOrphanParents.find(parent_info));
  1347. i = 0;
  1348. while (i < mOrphanChildren.count())
  1349. {
  1350. if (mOrphanChildren[i].mParentInfo == parent_info)
  1351. {
  1352. mOrphanChildren.remove(i);
  1353. mNumOrphans--;
  1354. }
  1355. else
  1356. {
  1357. i++;
  1358. }
  1359. }
  1360. if (orphans_found && objectp->isSelected())
  1361. {
  1362. LLSelectNode* nodep = LLSelectMgr::getInstance()->getSelection()->findNode(objectp);
  1363. if (nodep && !nodep->mIndividualSelection)
  1364. {
  1365. // rebuild selection with orphans
  1366. LLSelectMgr::getInstance()->deselectObjectAndFamily(objectp);
  1367. LLSelectMgr::getInstance()->selectObjectAndFamily(objectp);
  1368. }
  1369. }
  1370. }
  1371. ////////////////////////////////////////////////////////////////////////////
  1372. LLViewerObjectList::OrphanInfo::OrphanInfo()
  1373. : mParentInfo(0)
  1374. {
  1375. }
  1376. LLViewerObjectList::OrphanInfo::OrphanInfo(const U64 parent_info, const LLUUID child_info)
  1377. : mParentInfo(parent_info), mChildInfo(child_info)
  1378. {
  1379. }
  1380. bool LLViewerObjectList::OrphanInfo::operator==(const OrphanInfo &rhs) const
  1381. {
  1382. return (mParentInfo == rhs.mParentInfo) && (mChildInfo == rhs.mChildInfo);
  1383. }
  1384. bool LLViewerObjectList::OrphanInfo::operator!=(const OrphanInfo &rhs) const
  1385. {
  1386. return !operator==(rhs);
  1387. }