PageRenderTime 63ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llviewerobject.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 2282 lines | 1728 code | 247 blank | 307 comment | 282 complexity | 0138c1b0fc42dc89e785b38421c470fd MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llviewerobject.cpp
  3. * @brief Base class for viewer objects
  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 "llviewerobject.h"
  28. #include "llaudioengine.h"
  29. #include "imageids.h"
  30. #include "indra_constants.h"
  31. #include "llmath.h"
  32. #include "llflexibleobject.h"
  33. #include "llviewercontrol.h"
  34. #include "lldatapacker.h"
  35. #include "llfasttimer.h"
  36. #include "llfloaterreg.h"
  37. #include "llfontgl.h"
  38. #include "llframetimer.h"
  39. #include "llinventory.h"
  40. #include "llinventorydefines.h"
  41. #include "llmaterialtable.h"
  42. #include "llmutelist.h"
  43. #include "llnamevalue.h"
  44. #include "llprimitive.h"
  45. #include "llquantize.h"
  46. #include "llregionhandle.h"
  47. #include "llsdserialize.h"
  48. #include "lltree_common.h"
  49. #include "llxfermanager.h"
  50. #include "message.h"
  51. #include "object_flags.h"
  52. #include "timing.h"
  53. #include "llaudiosourcevo.h"
  54. #include "llagent.h"
  55. #include "llagentcamera.h"
  56. #include "llbbox.h"
  57. #include "llbox.h"
  58. #include "llcylinder.h"
  59. #include "lldrawable.h"
  60. #include "llface.h"
  61. #include "llfloaterproperties.h"
  62. #include "llfloatertools.h"
  63. #include "llfollowcam.h"
  64. #include "llhudtext.h"
  65. #include "llselectmgr.h"
  66. #include "llrendersphere.h"
  67. #include "lltooldraganddrop.h"
  68. #include "llviewercamera.h"
  69. #include "llviewertexturelist.h"
  70. #include "llviewerinventory.h"
  71. #include "llviewerobjectlist.h"
  72. #include "llviewerparceloverlay.h"
  73. #include "llviewerpartsource.h"
  74. #include "llviewerregion.h"
  75. #include "llviewerstats.h"
  76. #include "llviewertextureanim.h"
  77. #include "llviewerwindow.h" // For getSpinAxis
  78. #include "llvoavatar.h"
  79. #include "llvoavatarself.h"
  80. #include "llvograss.h"
  81. #include "llvoground.h"
  82. #include "llvolume.h"
  83. #include "llvolumemessage.h"
  84. #include "llvopartgroup.h"
  85. #include "llvosky.h"
  86. #include "llvosurfacepatch.h"
  87. #include "llvotree.h"
  88. #include "llvovolume.h"
  89. #include "llvowater.h"
  90. #include "llworld.h"
  91. #include "llui.h"
  92. #include "pipeline.h"
  93. #include "llviewernetwork.h"
  94. #include "llvowlsky.h"
  95. #include "llmanip.h"
  96. #include "lltrans.h"
  97. #include "llsdutil.h"
  98. #include "llmediaentry.h"
  99. //#define DEBUG_UPDATE_TYPE
  100. BOOL LLViewerObject::sVelocityInterpolate = TRUE;
  101. BOOL LLViewerObject::sPingInterpolate = TRUE;
  102. U32 LLViewerObject::sNumZombieObjects = 0;
  103. S32 LLViewerObject::sNumObjects = 0;
  104. BOOL LLViewerObject::sMapDebug = TRUE;
  105. LLColor4 LLViewerObject::sEditSelectColor( 1.0f, 1.f, 0.f, 0.3f); // Edit OK
  106. LLColor4 LLViewerObject::sNoEditSelectColor( 1.0f, 0.f, 0.f, 0.3f); // Can't edit
  107. S32 LLViewerObject::sAxisArrowLength(50);
  108. BOOL LLViewerObject::sPulseEnabled(FALSE);
  109. BOOL LLViewerObject::sUseSharedDrawables(FALSE); // TRUE
  110. // sMaxUpdateInterpolationTime must be greater than sPhaseOutUpdateInterpolationTime
  111. F64 LLViewerObject::sMaxUpdateInterpolationTime = 3.0; // For motion interpolation: after X seconds with no updates, don't predict object motion
  112. F64 LLViewerObject::sPhaseOutUpdateInterpolationTime = 2.0; // For motion interpolation: after Y seconds with no updates, taper off motion prediction
  113. static LLFastTimer::DeclareTimer FTM_CREATE_OBJECT("Create Object");
  114. // static
  115. LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
  116. {
  117. LLViewerObject *res = NULL;
  118. LLFastTimer t1(FTM_CREATE_OBJECT);
  119. switch (pcode)
  120. {
  121. case LL_PCODE_VOLUME:
  122. res = new LLVOVolume(id, pcode, regionp); break;
  123. case LL_PCODE_LEGACY_AVATAR:
  124. {
  125. if (id == gAgentID)
  126. {
  127. if (!gAgentAvatarp)
  128. {
  129. gAgentAvatarp = new LLVOAvatarSelf(id, pcode, regionp);
  130. gAgentAvatarp->initInstance();
  131. }
  132. else
  133. {
  134. gAgentAvatarp->updateRegion(regionp);
  135. }
  136. res = gAgentAvatarp;
  137. }
  138. else
  139. {
  140. LLVOAvatar *avatar = new LLVOAvatar(id, pcode, regionp);
  141. avatar->initInstance();
  142. res = avatar;
  143. }
  144. break;
  145. }
  146. case LL_PCODE_LEGACY_GRASS:
  147. res = new LLVOGrass(id, pcode, regionp); break;
  148. case LL_PCODE_LEGACY_PART_SYS:
  149. // llwarns << "Creating old part sys!" << llendl;
  150. // res = new LLVOPart(id, pcode, regionp); break;
  151. res = NULL; break;
  152. case LL_PCODE_LEGACY_TREE:
  153. res = new LLVOTree(id, pcode, regionp); break;
  154. case LL_PCODE_TREE_NEW:
  155. // llwarns << "Creating new tree!" << llendl;
  156. // res = new LLVOTree(id, pcode, regionp); break;
  157. res = NULL; break;
  158. case LL_VO_SURFACE_PATCH:
  159. res = new LLVOSurfacePatch(id, pcode, regionp); break;
  160. case LL_VO_SKY:
  161. res = new LLVOSky(id, pcode, regionp); break;
  162. case LL_VO_VOID_WATER:
  163. res = new LLVOVoidWater(id, pcode, regionp); break;
  164. case LL_VO_WATER:
  165. res = new LLVOWater(id, pcode, regionp); break;
  166. case LL_VO_GROUND:
  167. res = new LLVOGround(id, pcode, regionp); break;
  168. case LL_VO_PART_GROUP:
  169. res = new LLVOPartGroup(id, pcode, regionp); break;
  170. case LL_VO_HUD_PART_GROUP:
  171. res = new LLVOHUDPartGroup(id, pcode, regionp); break;
  172. case LL_VO_WL_SKY:
  173. res = new LLVOWLSky(id, pcode, regionp); break;
  174. default:
  175. llwarns << "Unknown object pcode " << (S32)pcode << llendl;
  176. res = NULL; break;
  177. }
  178. return res;
  179. }
  180. LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp, BOOL is_global)
  181. : LLPrimitive(),
  182. mChildList(),
  183. mID(id),
  184. mLocalID(0),
  185. mTotalCRC(0),
  186. mTEImages(NULL),
  187. mGLName(0),
  188. mbCanSelect(TRUE),
  189. mFlags(0),
  190. mPhysicsShapeType(0),
  191. mPhysicsGravity(0),
  192. mPhysicsFriction(0),
  193. mPhysicsDensity(0),
  194. mPhysicsRestitution(0),
  195. mDrawable(),
  196. mCreateSelected(FALSE),
  197. mRenderMedia(FALSE),
  198. mBestUpdatePrecision(0),
  199. mText(),
  200. mLastInterpUpdateSecs(0.f),
  201. mLastMessageUpdateSecs(0.f),
  202. mLatestRecvPacketID(0),
  203. mData(NULL),
  204. mAudioSourcep(NULL),
  205. mAudioGain(1.f),
  206. mAppAngle(0.f),
  207. mPixelArea(1024.f),
  208. mInventory(NULL),
  209. mInventorySerialNum(0),
  210. mRegionp( regionp ),
  211. mInventoryPending(FALSE),
  212. mInventoryDirty(FALSE),
  213. mDead(FALSE),
  214. mOrphaned(FALSE),
  215. mUserSelected(FALSE),
  216. mOnActiveList(FALSE),
  217. mOnMap(FALSE),
  218. mStatic(FALSE),
  219. mNumFaces(0),
  220. mTimeDilation(1.f),
  221. mRotTime(0.f),
  222. mJointInfo(NULL),
  223. mState(0),
  224. mMedia(NULL),
  225. mClickAction(0),
  226. mObjectCost(0),
  227. mLinksetCost(0),
  228. mPhysicsCost(0),
  229. mLinksetPhysicsCost(0.f),
  230. mCostStale(true),
  231. mPhysicsShapeUnknown(true),
  232. mAttachmentItemID(LLUUID::null),
  233. mLastUpdateType(OUT_UNKNOWN),
  234. mLastUpdateCached(FALSE)
  235. {
  236. if (!is_global)
  237. {
  238. llassert(mRegionp);
  239. }
  240. LLPrimitive::init_primitive(pcode);
  241. // CP: added 12/2/2005 - this was being initialised to 0, not the current frame time
  242. mLastInterpUpdateSecs = LLFrameTimer::getElapsedSeconds();
  243. mPositionRegion = LLVector3(0.f, 0.f, 0.f);
  244. if (!is_global && mRegionp)
  245. {
  246. mPositionAgent = mRegionp->getOriginAgent();
  247. }
  248. LLViewerObject::sNumObjects++;
  249. }
  250. LLViewerObject::~LLViewerObject()
  251. {
  252. deleteTEImages();
  253. if(mInventory)
  254. {
  255. mInventory->clear(); // will deref and delete entries
  256. delete mInventory;
  257. mInventory = NULL;
  258. }
  259. if (mJointInfo)
  260. {
  261. delete mJointInfo;
  262. mJointInfo = NULL;
  263. }
  264. if (mPartSourcep)
  265. {
  266. mPartSourcep->setDead();
  267. mPartSourcep = NULL;
  268. }
  269. // Delete memory associated with extra parameters.
  270. std::map<U16, ExtraParameter*>::iterator iter;
  271. for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
  272. {
  273. if(iter->second != NULL)
  274. {
  275. delete iter->second->data;
  276. delete iter->second;
  277. }
  278. }
  279. mExtraParameterList.clear();
  280. for_each(mNameValuePairs.begin(), mNameValuePairs.end(), DeletePairedPointer()) ;
  281. mNameValuePairs.clear();
  282. delete[] mData;
  283. mData = NULL;
  284. delete mMedia;
  285. mMedia = NULL;
  286. sNumObjects--;
  287. sNumZombieObjects--;
  288. llassert(mChildList.size() == 0);
  289. clearInventoryListeners();
  290. }
  291. void LLViewerObject::deleteTEImages()
  292. {
  293. delete[] mTEImages;
  294. mTEImages = NULL;
  295. }
  296. void LLViewerObject::markDead()
  297. {
  298. if (!mDead)
  299. {
  300. //llinfos << "Marking self " << mLocalID << " as dead." << llendl;
  301. // Root object of this hierarchy unlinks itself.
  302. if (getParent())
  303. {
  304. ((LLViewerObject *)getParent())->removeChild(this);
  305. // go ahead and delete any jointinfo's that we find
  306. delete mJointInfo;
  307. mJointInfo = NULL;
  308. }
  309. // Mark itself as dead
  310. mDead = TRUE;
  311. gObjectList.cleanupReferences(this);
  312. LLViewerObject *childp;
  313. while (mChildList.size() > 0)
  314. {
  315. childp = mChildList.back();
  316. if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR)
  317. {
  318. //llinfos << "Marking child " << childp->getLocalID() << " as dead." << llendl;
  319. childp->setParent(NULL); // LLViewerObject::markDead 1
  320. childp->markDead();
  321. }
  322. else
  323. {
  324. // make sure avatar is no longer parented,
  325. // so we can properly set it's position
  326. childp->setDrawableParent(NULL);
  327. ((LLVOAvatar*)childp)->getOffObject();
  328. childp->setParent(NULL); // LLViewerObject::markDead 2
  329. }
  330. mChildList.pop_back();
  331. }
  332. if (mDrawable.notNull())
  333. {
  334. // Drawables are reference counted, mark as dead, then nuke the pointer.
  335. mDrawable->markDead();
  336. mDrawable = NULL;
  337. }
  338. if (mText)
  339. {
  340. mText->markDead();
  341. mText = NULL;
  342. }
  343. if (mIcon)
  344. {
  345. mIcon->markDead();
  346. mIcon = NULL;
  347. }
  348. if (mPartSourcep)
  349. {
  350. mPartSourcep->setDead();
  351. mPartSourcep = NULL;
  352. }
  353. if (mAudioSourcep)
  354. {
  355. // Do some cleanup
  356. if (gAudiop)
  357. {
  358. gAudiop->cleanupAudioSource(mAudioSourcep);
  359. }
  360. mAudioSourcep = NULL;
  361. }
  362. if (flagAnimSource())
  363. {
  364. if (isAgentAvatarValid())
  365. {
  366. // stop motions associated with this object
  367. gAgentAvatarp->stopMotionFromSource(mID);
  368. }
  369. }
  370. if (flagCameraSource())
  371. {
  372. LLFollowCamMgr::removeFollowCamParams(mID);
  373. }
  374. sNumZombieObjects++;
  375. }
  376. }
  377. void LLViewerObject::dump() const
  378. {
  379. llinfos << "Type: " << pCodeToString(mPrimitiveCode) << llendl;
  380. llinfos << "Drawable: " << (LLDrawable *)mDrawable << llendl;
  381. llinfos << "Update Age: " << LLFrameTimer::getElapsedSeconds() - mLastMessageUpdateSecs << llendl;
  382. llinfos << "Parent: " << getParent() << llendl;
  383. llinfos << "ID: " << mID << llendl;
  384. llinfos << "LocalID: " << mLocalID << llendl;
  385. llinfos << "PositionRegion: " << getPositionRegion() << llendl;
  386. llinfos << "PositionAgent: " << getPositionAgent() << llendl;
  387. llinfos << "PositionGlobal: " << getPositionGlobal() << llendl;
  388. llinfos << "Velocity: " << getVelocity() << llendl;
  389. if (mDrawable.notNull() && mDrawable->getNumFaces())
  390. {
  391. LLFacePool *poolp = mDrawable->getFace(0)->getPool();
  392. if (poolp)
  393. {
  394. llinfos << "Pool: " << poolp << llendl;
  395. llinfos << "Pool reference count: " << poolp->mReferences.size() << llendl;
  396. }
  397. }
  398. //llinfos << "BoxTree Min: " << mDrawable->getBox()->getMin() << llendl;
  399. //llinfos << "BoxTree Max: " << mDrawable->getBox()->getMin() << llendl;
  400. /*
  401. llinfos << "Velocity: " << getVelocity() << llendl;
  402. llinfos << "AnyOwner: " << permAnyOwner() << " YouOwner: " << permYouOwner() << " Edit: " << mPermEdit << llendl;
  403. llinfos << "UsePhysics: " << usePhysics() << " CanSelect " << mbCanSelect << " UserSelected " << mUserSelected << llendl;
  404. llinfos << "AppAngle: " << mAppAngle << llendl;
  405. llinfos << "PixelArea: " << mPixelArea << llendl;
  406. char buffer[1000];
  407. char *key;
  408. for (key = mNameValuePairs.getFirstKey(); key; key = mNameValuePairs.getNextKey() )
  409. {
  410. mNameValuePairs[key]->printNameValue(buffer);
  411. llinfos << buffer << llendl;
  412. }
  413. for (child_list_t::iterator iter = mChildList.begin();
  414. iter != mChildList.end(); iter++)
  415. {
  416. LLViewerObject* child = *iter;
  417. llinfos << " child " << child->getID() << llendl;
  418. }
  419. */
  420. }
  421. void LLViewerObject::printNameValuePairs() const
  422. {
  423. for (name_value_map_t::const_iterator iter = mNameValuePairs.begin();
  424. iter != mNameValuePairs.end(); iter++)
  425. {
  426. LLNameValue* nv = iter->second;
  427. llinfos << nv->printNameValue() << llendl;
  428. }
  429. }
  430. void LLViewerObject::initVOClasses()
  431. {
  432. // Initialized shared class stuff first.
  433. LLVOAvatar::initClass();
  434. LLVOTree::initClass();
  435. llinfos << "Viewer Object size: " << sizeof(LLViewerObject) << llendl;
  436. LLVOGrass::initClass();
  437. LLVOWater::initClass();
  438. LLVOVolume::initClass();
  439. }
  440. void LLViewerObject::cleanupVOClasses()
  441. {
  442. LLVOGrass::cleanupClass();
  443. LLVOWater::cleanupClass();
  444. LLVOTree::cleanupClass();
  445. LLVOAvatar::cleanupClass();
  446. LLVOVolume::cleanupClass();
  447. }
  448. // Replaces all name value pairs with data from \n delimited list
  449. // Does not update server
  450. void LLViewerObject::setNameValueList(const std::string& name_value_list)
  451. {
  452. // Clear out the old
  453. for_each(mNameValuePairs.begin(), mNameValuePairs.end(), DeletePairedPointer()) ;
  454. mNameValuePairs.clear();
  455. // Bring in the new
  456. std::string::size_type length = name_value_list.length();
  457. std::string::size_type start = 0;
  458. while (start < length)
  459. {
  460. std::string::size_type end = name_value_list.find_first_of("\n", start);
  461. if (end == std::string::npos) end = length;
  462. if (end > start)
  463. {
  464. std::string tok = name_value_list.substr(start, end - start);
  465. addNVPair(tok);
  466. }
  467. start = end+1;
  468. }
  469. }
  470. // This method returns true if the object is over land owned by the
  471. // agent.
  472. bool LLViewerObject::isReturnable()
  473. {
  474. if (isAttachment())
  475. {
  476. return false;
  477. }
  478. std::vector<LLBBox> boxes;
  479. boxes.push_back(LLBBox(getPositionRegion(), getRotationRegion(), getScale() * -0.5f, getScale() * 0.5f).getAxisAligned());
  480. for (child_list_t::iterator iter = mChildList.begin();
  481. iter != mChildList.end(); iter++)
  482. {
  483. LLViewerObject* child = *iter;
  484. boxes.push_back( LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned());
  485. }
  486. bool result = (mRegionp && mRegionp->objectIsReturnable(getPositionRegion(), boxes)) ? 1 : 0;
  487. if ( !result )
  488. {
  489. //Get list of neighboring regions relative to this vo's region
  490. std::vector<LLViewerRegion*> uniqueRegions;
  491. mRegionp->getNeighboringRegions( uniqueRegions );
  492. //Build aabb's - for root and all children
  493. std::vector<PotentialReturnableObject> returnables;
  494. typedef std::vector<LLViewerRegion*>::iterator RegionIt;
  495. RegionIt regionStart = uniqueRegions.begin();
  496. RegionIt regionEnd = uniqueRegions.end();
  497. for (; regionStart != regionEnd; ++regionStart )
  498. {
  499. LLViewerRegion* pTargetRegion = *regionStart;
  500. //Add the root vo as there may be no children and we still want
  501. //to test for any edge overlap
  502. buildReturnablesForChildrenVO( returnables, this, pTargetRegion );
  503. //Add it's children
  504. for (child_list_t::iterator iter = mChildList.begin(); iter != mChildList.end(); iter++)
  505. {
  506. LLViewerObject* pChild = *iter;
  507. buildReturnablesForChildrenVO( returnables, pChild, pTargetRegion );
  508. }
  509. }
  510. //TBD#Eventually create a region -> box list map
  511. typedef std::vector<PotentialReturnableObject>::iterator ReturnablesIt;
  512. ReturnablesIt retCurrentIt = returnables.begin();
  513. ReturnablesIt retEndIt = returnables.end();
  514. for ( ; retCurrentIt !=retEndIt; ++retCurrentIt )
  515. {
  516. boxes.clear();
  517. LLViewerRegion* pRegion = (*retCurrentIt).pRegion;
  518. boxes.push_back( (*retCurrentIt).box );
  519. bool retResult = pRegion
  520. && pRegion->childrenObjectReturnable( boxes )
  521. && pRegion->canManageEstate();
  522. if ( retResult )
  523. {
  524. result = true;
  525. break;
  526. }
  527. }
  528. }
  529. return result;
  530. }
  531. void LLViewerObject::buildReturnablesForChildrenVO( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion )
  532. {
  533. if ( !pChild )
  534. {
  535. llerrs<<"child viewerobject is NULL "<<llendl;
  536. }
  537. constructAndAddReturnable( returnables, pChild, pTargetRegion );
  538. //We want to handle any children VO's as well
  539. for (child_list_t::iterator iter = pChild->mChildList.begin(); iter != pChild->mChildList.end(); iter++)
  540. {
  541. LLViewerObject* pChildofChild = *iter;
  542. buildReturnablesForChildrenVO( returnables, pChildofChild, pTargetRegion );
  543. }
  544. }
  545. void LLViewerObject::constructAndAddReturnable( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion )
  546. {
  547. LLVector3 targetRegionPos;
  548. targetRegionPos.setVec( pChild->getPositionGlobal() );
  549. LLBBox childBBox = LLBBox( targetRegionPos, pChild->getRotationRegion(), pChild->getScale() * -0.5f,
  550. pChild->getScale() * 0.5f).getAxisAligned();
  551. LLVector3 edgeA = targetRegionPos + childBBox.getMinLocal();
  552. LLVector3 edgeB = targetRegionPos + childBBox.getMaxLocal();
  553. LLVector3d edgeAd, edgeBd;
  554. edgeAd.setVec(edgeA);
  555. edgeBd.setVec(edgeB);
  556. //Only add the box when either of the extents are in a neighboring region
  557. if ( pTargetRegion->pointInRegionGlobal( edgeAd ) || pTargetRegion->pointInRegionGlobal( edgeBd ) )
  558. {
  559. PotentialReturnableObject returnableObj;
  560. returnableObj.box = childBBox;
  561. returnableObj.pRegion = pTargetRegion;
  562. returnables.push_back( returnableObj );
  563. }
  564. }
  565. bool LLViewerObject::crossesParcelBounds()
  566. {
  567. std::vector<LLBBox> boxes;
  568. boxes.push_back(LLBBox(getPositionRegion(), getRotationRegion(), getScale() * -0.5f, getScale() * 0.5f).getAxisAligned());
  569. for (child_list_t::iterator iter = mChildList.begin();
  570. iter != mChildList.end(); iter++)
  571. {
  572. LLViewerObject* child = *iter;
  573. boxes.push_back(LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned());
  574. }
  575. return mRegionp && mRegionp->objectsCrossParcel(boxes);
  576. }
  577. BOOL LLViewerObject::setParent(LLViewerObject* parent)
  578. {
  579. if(mParent != parent)
  580. {
  581. LLViewerObject* old_parent = (LLViewerObject*)mParent ;
  582. BOOL ret = LLPrimitive::setParent(parent);
  583. if(ret && old_parent && parent)
  584. {
  585. old_parent->removeChild(this) ;
  586. }
  587. return ret ;
  588. }
  589. return FALSE ;
  590. }
  591. void LLViewerObject::addChild(LLViewerObject *childp)
  592. {
  593. for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i)
  594. {
  595. if (*i == childp)
  596. { //already has child
  597. return;
  598. }
  599. }
  600. if (!isAvatar())
  601. {
  602. // propagate selection properties
  603. childp->mbCanSelect = mbCanSelect;
  604. }
  605. if(childp->setParent(this))
  606. {
  607. mChildList.push_back(childp);
  608. }
  609. }
  610. void LLViewerObject::removeChild(LLViewerObject *childp)
  611. {
  612. for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i)
  613. {
  614. if (*i == childp)
  615. {
  616. if (!childp->isAvatar() && mDrawable.notNull() && mDrawable->isActive() && childp->mDrawable.notNull() && !isAvatar())
  617. {
  618. gPipeline.markRebuild(childp->mDrawable, LLDrawable::REBUILD_VOLUME);
  619. }
  620. mChildList.erase(i);
  621. if(childp->getParent() == this)
  622. {
  623. childp->setParent(NULL);
  624. }
  625. break;
  626. }
  627. }
  628. if (childp->isSelected())
  629. {
  630. LLSelectMgr::getInstance()->deselectObjectAndFamily(childp);
  631. BOOL add_to_end = TRUE;
  632. LLSelectMgr::getInstance()->selectObjectAndFamily(childp, add_to_end);
  633. }
  634. }
  635. void LLViewerObject::addThisAndAllChildren(std::vector<LLViewerObject*>& objects)
  636. {
  637. objects.push_back(this);
  638. for (child_list_t::iterator iter = mChildList.begin();
  639. iter != mChildList.end(); iter++)
  640. {
  641. LLViewerObject* child = *iter;
  642. if (!child->isAvatar())
  643. {
  644. child->addThisAndAllChildren(objects);
  645. }
  646. }
  647. }
  648. void LLViewerObject::addThisAndNonJointChildren(std::vector<LLViewerObject*>& objects)
  649. {
  650. objects.push_back(this);
  651. // don't add any attachments when temporarily selecting avatar
  652. if (isAvatar())
  653. {
  654. return;
  655. }
  656. for (child_list_t::iterator iter = mChildList.begin();
  657. iter != mChildList.end(); iter++)
  658. {
  659. LLViewerObject* child = *iter;
  660. if ( (!child->isAvatar()) && (!child->isJointChild()))
  661. {
  662. child->addThisAndNonJointChildren(objects);
  663. }
  664. }
  665. }
  666. BOOL LLViewerObject::isChild(LLViewerObject *childp) const
  667. {
  668. for (child_list_t::const_iterator iter = mChildList.begin();
  669. iter != mChildList.end(); iter++)
  670. {
  671. LLViewerObject* testchild = *iter;
  672. if (testchild == childp)
  673. return TRUE;
  674. }
  675. return FALSE;
  676. }
  677. // returns TRUE if at least one avatar is sitting on this object
  678. BOOL LLViewerObject::isSeat() const
  679. {
  680. for (child_list_t::const_iterator iter = mChildList.begin();
  681. iter != mChildList.end(); iter++)
  682. {
  683. LLViewerObject* child = *iter;
  684. if (child->isAvatar())
  685. {
  686. return TRUE;
  687. }
  688. }
  689. return FALSE;
  690. }
  691. BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp)
  692. {
  693. if (mDrawable.isNull())
  694. {
  695. return FALSE;
  696. }
  697. BOOL ret = mDrawable->mXform.setParent(parentp ? &parentp->mXform : NULL);
  698. if(!ret)
  699. {
  700. return FALSE ;
  701. }
  702. LLDrawable* old_parent = mDrawable->mParent;
  703. mDrawable->mParent = parentp;
  704. gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
  705. if( (old_parent != parentp && old_parent)
  706. || (parentp && parentp->isActive()))
  707. {
  708. // *TODO we should not be relying on setDrawable parent to call markMoved
  709. gPipeline.markMoved(mDrawable, FALSE);
  710. }
  711. else if (!mDrawable->isAvatar())
  712. {
  713. mDrawable->updateXform(TRUE);
  714. /*if (!mDrawable->getSpatialGroup())
  715. {
  716. mDrawable->movePartition();
  717. }*/
  718. }
  719. return ret;
  720. }
  721. // Show or hide particles, icon and HUD
  722. void LLViewerObject::hideExtraDisplayItems( BOOL hidden )
  723. {
  724. if( mPartSourcep.notNull() )
  725. {
  726. LLViewerPartSourceScript *partSourceScript = mPartSourcep.get();
  727. partSourceScript->setSuspended( hidden );
  728. }
  729. if( mText.notNull() )
  730. {
  731. LLHUDText *hudText = mText.get();
  732. hudText->setHidden( hidden );
  733. }
  734. if( mIcon.notNull() )
  735. {
  736. LLHUDIcon *hudIcon = mIcon.get();
  737. hudIcon->setHidden( hidden );
  738. }
  739. }
  740. U32 LLViewerObject::checkMediaURL(const std::string &media_url)
  741. {
  742. U32 retval = (U32)0x0;
  743. if (!mMedia && !media_url.empty())
  744. {
  745. retval |= MEDIA_URL_ADDED;
  746. mMedia = new LLViewerObjectMedia;
  747. mMedia->mMediaURL = media_url;
  748. mMedia->mMediaType = LLViewerObject::MEDIA_SET;
  749. mMedia->mPassedWhitelist = FALSE;
  750. }
  751. else if (mMedia)
  752. {
  753. if (media_url.empty())
  754. {
  755. retval |= MEDIA_URL_REMOVED;
  756. delete mMedia;
  757. mMedia = NULL;
  758. }
  759. else if (mMedia->mMediaURL != media_url) // <-- This is an optimization. If they are equal don't bother with below's test.
  760. {
  761. /*if (! (LLTextureEntry::getAgentIDFromMediaVersionString(media_url) == gAgent.getID() &&
  762. LLTextureEntry::getVersionFromMediaVersionString(media_url) ==
  763. LLTextureEntry::getVersionFromMediaVersionString(mMedia->mMediaURL) + 1))
  764. */
  765. {
  766. // If the media URL is different and WE were not the one who
  767. // changed it, mark dirty.
  768. retval |= MEDIA_URL_UPDATED;
  769. }
  770. mMedia->mMediaURL = media_url;
  771. mMedia->mPassedWhitelist = FALSE;
  772. }
  773. }
  774. return retval;
  775. }
  776. U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
  777. void **user_data,
  778. U32 block_num,
  779. const EObjectUpdateType update_type,
  780. LLDataPacker *dp)
  781. {
  782. LLMemType mt(LLMemType::MTYPE_OBJECT);
  783. U32 retval = 0x0;
  784. // Coordinates of objects on simulators are region-local.
  785. U64 region_handle;
  786. mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle);
  787. {
  788. LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle);
  789. if(regionp != mRegionp && regionp && mRegionp)//region cross
  790. {
  791. //this is the redundant position and region update, but it is necessary in case the viewer misses the following
  792. //position and region update messages from sim.
  793. //this redundant update should not cause any problems.
  794. LLVector3 delta_pos = mRegionp->getOriginAgent() - regionp->getOriginAgent();
  795. setPositionParent(getPosition() + delta_pos); //update to the new region position immediately.
  796. setRegion(regionp) ; //change the region.
  797. }
  798. else
  799. {
  800. mRegionp = regionp ;
  801. }
  802. }
  803. if (!mRegionp)
  804. {
  805. U32 x, y;
  806. from_region_handle(region_handle, &x, &y);
  807. llerrs << "Object has invalid region " << x << ":" << y << "!" << llendl;
  808. return retval;
  809. }
  810. U16 time_dilation16;
  811. mesgsys->getU16Fast(_PREHASH_RegionData, _PREHASH_TimeDilation, time_dilation16);
  812. F32 time_dilation = ((F32) time_dilation16) / 65535.f;
  813. mTimeDilation = time_dilation;
  814. mRegionp->setTimeDilation(time_dilation);
  815. // this will be used to determine if we've really changed position
  816. // Use getPosition, not getPositionRegion, since this is what we're comparing directly against.
  817. LLVector3 test_pos_parent = getPosition();
  818. U8 data[60+16]; // This needs to match the largest size below.
  819. #ifdef LL_BIG_ENDIAN
  820. U16 valswizzle[4];
  821. #endif
  822. U16 *val;
  823. const F32 size = LLWorld::getInstance()->getRegionWidthInMeters();
  824. const F32 MAX_HEIGHT = LLWorld::getInstance()->getRegionMaxHeight();
  825. const F32 MIN_HEIGHT = LLWorld::getInstance()->getRegionMinHeight();
  826. S32 length;
  827. S32 count;
  828. S32 this_update_precision = 32; // in bits
  829. // Temporaries, because we need to compare w/ previous to set dirty flags...
  830. LLVector3 new_pos_parent;
  831. LLVector3 new_vel;
  832. LLVector3 new_acc;
  833. LLVector3 new_angv;
  834. LLVector3 old_angv = getAngularVelocity();
  835. LLQuaternion new_rot;
  836. LLVector3 new_scale = getScale();
  837. U32 parent_id = 0;
  838. U8 material = 0;
  839. U8 click_action = 0;
  840. U32 crc = 0;
  841. bool old_special_hover_cursor = specialHoverCursor();
  842. LLViewerObject *cur_parentp = (LLViewerObject *)getParent();
  843. if (cur_parentp)
  844. {
  845. parent_id = cur_parentp->mLocalID;
  846. }
  847. if (!dp)
  848. {
  849. switch(update_type)
  850. {
  851. case OUT_FULL:
  852. {
  853. #ifdef DEBUG_UPDATE_TYPE
  854. llinfos << "Full:" << getID() << llendl;
  855. #endif
  856. //clear cost and linkset cost
  857. mCostStale = true;
  858. if (isSelected())
  859. {
  860. gFloaterTools->dirty();
  861. }
  862. LLUUID audio_uuid;
  863. LLUUID owner_id; // only valid if audio_uuid or particle system is not null
  864. F32 gain;
  865. U8 sound_flags;
  866. mesgsys->getU32Fast( _PREHASH_ObjectData, _PREHASH_CRC, crc, block_num);
  867. mesgsys->getU32Fast( _PREHASH_ObjectData, _PREHASH_ParentID, parent_id, block_num);
  868. mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_Sound, audio_uuid, block_num );
  869. // HACK: Owner id only valid if non-null sound id or particle system
  870. mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id, block_num );
  871. mesgsys->getF32Fast( _PREHASH_ObjectData, _PREHASH_Gain, gain, block_num );
  872. mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_Flags, sound_flags, block_num );
  873. mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_Material, material, block_num );
  874. mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_ClickAction, click_action, block_num);
  875. mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_Scale, new_scale, block_num );
  876. length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ObjectData);
  877. mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num);
  878. mTotalCRC = crc;
  879. // Owner ID used for sound muting or particle system muting
  880. setAttachedSound(audio_uuid, owner_id, gain, sound_flags);
  881. U8 old_material = getMaterial();
  882. if (old_material != material)
  883. {
  884. setMaterial(material);
  885. if (mDrawable.notNull())
  886. {
  887. gPipeline.markMoved(mDrawable, FALSE); // undamped
  888. }
  889. }
  890. setClickAction(click_action);
  891. count = 0;
  892. LLVector4 collision_plane;
  893. switch(length)
  894. {
  895. case (60 + 16):
  896. // pull out collision normal for avatar
  897. htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
  898. ((LLVOAvatar*)this)->setFootPlane(collision_plane);
  899. count += sizeof(LLVector4);
  900. // fall through
  901. case 60:
  902. this_update_precision = 32;
  903. // this is a terse update
  904. // pos
  905. htonmemcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
  906. count += sizeof(LLVector3);
  907. // vel
  908. htonmemcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
  909. count += sizeof(LLVector3);
  910. // acc
  911. htonmemcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
  912. count += sizeof(LLVector3);
  913. // theta
  914. {
  915. LLVector3 vec;
  916. htonmemcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
  917. new_rot.unpackFromVector3(vec);
  918. }
  919. count += sizeof(LLVector3);
  920. // omega
  921. htonmemcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
  922. if (new_angv.isExactlyZero())
  923. {
  924. // reset rotation time
  925. resetRot();
  926. }
  927. setAngularVelocity(new_angv);
  928. #if LL_DARWIN
  929. if (length == 76)
  930. {
  931. setAngularVelocity(LLVector3::zero);
  932. }
  933. #endif
  934. break;
  935. case(32 + 16):
  936. // pull out collision normal for avatar
  937. htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
  938. ((LLVOAvatar*)this)->setFootPlane(collision_plane);
  939. count += sizeof(LLVector4);
  940. // fall through
  941. case 32:
  942. this_update_precision = 16;
  943. test_pos_parent.quantize16(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
  944. // This is a terse 16 update, so treat data as an array of U16's.
  945. #ifdef LL_BIG_ENDIAN
  946. htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
  947. val = valswizzle;
  948. #else
  949. val = (U16 *) &data[count];
  950. #endif
  951. count += sizeof(U16)*3;
  952. new_pos_parent.mV[VX] = U16_to_F32(val[VX], -0.5f*size, 1.5f*size);
  953. new_pos_parent.mV[VY] = U16_to_F32(val[VY], -0.5f*size, 1.5f*size);
  954. new_pos_parent.mV[VZ] = U16_to_F32(val[VZ], MIN_HEIGHT, MAX_HEIGHT);
  955. #ifdef LL_BIG_ENDIAN
  956. htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
  957. val = valswizzle;
  958. #else
  959. val = (U16 *) &data[count];
  960. #endif
  961. count += sizeof(U16)*3;
  962. setVelocity(LLVector3(U16_to_F32(val[VX], -size, size),
  963. U16_to_F32(val[VY], -size, size),
  964. U16_to_F32(val[VZ], -size, size)));
  965. #ifdef LL_BIG_ENDIAN
  966. htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
  967. val = valswizzle;
  968. #else
  969. val = (U16 *) &data[count];
  970. #endif
  971. count += sizeof(U16)*3;
  972. setAcceleration(LLVector3(U16_to_F32(val[VX], -size, size),
  973. U16_to_F32(val[VY], -size, size),
  974. U16_to_F32(val[VZ], -size, size)));
  975. #ifdef LL_BIG_ENDIAN
  976. htonmemcpy(valswizzle, &data[count], MVT_U16Quat, 4);
  977. val = valswizzle;
  978. #else
  979. val = (U16 *) &data[count];
  980. #endif
  981. count += sizeof(U16)*4;
  982. new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f);
  983. new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f);
  984. new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f);
  985. new_rot.mQ[VW] = U16_to_F32(val[VW], -1.f, 1.f);
  986. #ifdef LL_BIG_ENDIAN
  987. htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
  988. val = valswizzle;
  989. #else
  990. val = (U16 *) &data[count];
  991. #endif
  992. new_angv.setVec(U16_to_F32(val[VX], -size, size),
  993. U16_to_F32(val[VY], -size, size),
  994. U16_to_F32(val[VZ], -size, size));
  995. if (new_angv.isExactlyZero())
  996. {
  997. // reset rotation time
  998. resetRot();
  999. }
  1000. setAngularVelocity(new_angv);
  1001. break;
  1002. case 16:
  1003. this_update_precision = 8;
  1004. test_pos_parent.quantize8(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
  1005. // this is a terse 8 update
  1006. new_pos_parent.mV[VX] = U8_to_F32(data[0], -0.5f*size, 1.5f*size);
  1007. new_pos_parent.mV[VY] = U8_to_F32(data[1], -0.5f*size, 1.5f*size);
  1008. new_pos_parent.mV[VZ] = U8_to_F32(data[2], MIN_HEIGHT, MAX_HEIGHT);
  1009. setVelocity(U8_to_F32(data[3], -size, size),
  1010. U8_to_F32(data[4], -size, size),
  1011. U8_to_F32(data[5], -size, size) );
  1012. setAcceleration(U8_to_F32(data[6], -size, size),
  1013. U8_to_F32(data[7], -size, size),
  1014. U8_to_F32(data[8], -size, size) );
  1015. new_rot.mQ[VX] = U8_to_F32(data[9], -1.f, 1.f);
  1016. new_rot.mQ[VY] = U8_to_F32(data[10], -1.f, 1.f);
  1017. new_rot.mQ[VZ] = U8_to_F32(data[11], -1.f, 1.f);
  1018. new_rot.mQ[VW] = U8_to_F32(data[12], -1.f, 1.f);
  1019. new_angv.setVec(U8_to_F32(data[13], -size, size),
  1020. U8_to_F32(data[14], -size, size),
  1021. U8_to_F32(data[15], -size, size) );
  1022. if (new_angv.isExactlyZero())
  1023. {
  1024. // reset rotation time
  1025. resetRot();
  1026. }
  1027. setAngularVelocity(new_angv);
  1028. break;
  1029. }
  1030. ////////////////////////////////////////////////////
  1031. //
  1032. // Here we handle data specific to the full message.
  1033. //
  1034. U32 flags;
  1035. mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num);
  1036. // clear all but local flags
  1037. mFlags &= FLAGS_LOCAL;
  1038. mFlags |= flags;
  1039. U8 state;
  1040. mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num );
  1041. mState = state;
  1042. // ...new objects that should come in selected need to be added to the selected list
  1043. mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0);
  1044. // Set all name value pairs
  1045. S32 nv_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_NameValue);
  1046. if (nv_size > 0)
  1047. {
  1048. std::string name_value_list;
  1049. mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_NameValue, name_value_list, block_num);
  1050. setNameValueList(name_value_list);
  1051. }
  1052. // Clear out any existing generic data
  1053. if (mData)
  1054. {
  1055. delete [] mData;
  1056. }
  1057. // Check for appended generic data
  1058. S32 data_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Data);
  1059. if (data_size <= 0)
  1060. {
  1061. mData = NULL;
  1062. }
  1063. else
  1064. {
  1065. // ...has generic data
  1066. mData = new U8[data_size];
  1067. mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, mData, data_size, block_num);
  1068. }
  1069. S32 text_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Text);
  1070. if (text_size > 1)
  1071. {
  1072. // Setup object text
  1073. if (!mText)
  1074. {
  1075. mText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
  1076. mText->setFont(LLFontGL::getFontSansSerif());
  1077. mText->setVertAlignment(LLHUDText::ALIGN_VERT_TOP);
  1078. mText->setMaxLines(-1);
  1079. mText->setSourceObject(this);
  1080. mText->setOnHUDAttachment(isHUDAttachment());
  1081. }
  1082. std::string temp_string;
  1083. mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_Text, temp_string, block_num );
  1084. LLColor4U coloru;
  1085. mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextColor, coloru.mV, 4, block_num);
  1086. // alpha was flipped so that it zero encoded better
  1087. coloru.mV[3] = 255 - coloru.mV[3];
  1088. mText->setColor(LLColor4(coloru));
  1089. mText->setString(temp_string);
  1090. if (mDrawable.notNull())
  1091. {
  1092. setChanged(MOVED | SILHOUETTE);
  1093. gPipeline.markMoved(mDrawable, FALSE); // undamped
  1094. }
  1095. }
  1096. else if (mText.notNull())
  1097. {
  1098. mText->markDead();
  1099. mText = NULL;
  1100. }
  1101. std::string media_url;
  1102. mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_MediaURL, media_url, block_num);
  1103. retval |= checkMediaURL(media_url);
  1104. //
  1105. // Unpack particle system data
  1106. //
  1107. unpackParticleSource(block_num, owner_id);
  1108. // Mark all extra parameters not used
  1109. std::map<U16, ExtraParameter*>::iterator iter;
  1110. for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
  1111. {
  1112. iter->second->in_use = FALSE;
  1113. }
  1114. // Unpack extra parameters
  1115. S32 size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ExtraParams);
  1116. if (size > 0)
  1117. {
  1118. U8 *buffer = new U8[size];
  1119. mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ExtraParams, buffer, size, block_num);
  1120. LLDataPackerBinaryBuffer dp(buffer, size);
  1121. U8 num_parameters;
  1122. dp.unpackU8(num_parameters, "num_params");
  1123. U8 param_block[MAX_OBJECT_PARAMS_SIZE];
  1124. for (U8 param=0; param<num_parameters; ++param)
  1125. {
  1126. U16 param_type;
  1127. S32 param_size;
  1128. dp.unpackU16(param_type, "param_type");
  1129. dp.unpackBinaryData(param_block, param_size, "param_data");
  1130. //llinfos << "Param type: " << param_type << ", Size: " << param_size << llendl;
  1131. LLDataPackerBinaryBuffer dp2(param_block, param_size);
  1132. unpackParameterEntry(param_type, &dp2);
  1133. }
  1134. delete[] buffer;
  1135. }
  1136. for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
  1137. {
  1138. if (!iter->second->in_use)
  1139. {
  1140. // Send an update message in case it was formerly in use
  1141. parameterChanged(iter->first, iter->second->data, FALSE, false);
  1142. }
  1143. }
  1144. U8 joint_type = 0;
  1145. mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_JointType, joint_type, block_num);
  1146. if (joint_type)
  1147. {
  1148. // create new joint info
  1149. if (!mJointInfo)
  1150. {
  1151. mJointInfo = new LLVOJointInfo;
  1152. }
  1153. mJointInfo->mJointType = (EHavokJointType) joint_type;
  1154. mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_JointPivot, mJointInfo->mPivot, block_num);
  1155. mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_JointAxisOrAnchor, mJointInfo->mAxisOrAnchor, block_num);
  1156. }
  1157. else if (mJointInfo)
  1158. {
  1159. // this joint info is no longer needed
  1160. delete mJointInfo;
  1161. mJointInfo = NULL;
  1162. }
  1163. break;
  1164. }
  1165. case OUT_TERSE_IMPROVED:
  1166. {
  1167. #ifdef DEBUG_UPDATE_TYPE
  1168. llinfos << "TI:" << getID() << llendl;
  1169. #endif
  1170. length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ObjectData);
  1171. mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num);
  1172. count = 0;
  1173. LLVector4 collision_plane;
  1174. switch(length)
  1175. {
  1176. case(60 + 16):
  1177. // pull out collision normal for avatar
  1178. htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
  1179. ((LLVOAvatar*)this)->setFootPlane(collision_plane);
  1180. count += sizeof(LLVector4);
  1181. // fall through
  1182. case 60:
  1183. // this is a terse 32 update
  1184. // pos
  1185. this_update_precision = 32;
  1186. htonmemcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
  1187. count += sizeof(LLVector3);
  1188. // vel
  1189. htonmemcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
  1190. count += sizeof(LLVector3);
  1191. // acc
  1192. htonmemcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
  1193. count += sizeof(LLVector3);
  1194. // theta
  1195. {
  1196. LLVector3 vec;
  1197. htonmemcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
  1198. new_rot.unpackFromVector3(vec);
  1199. }
  1200. count += sizeof(LLVector3);
  1201. // omega
  1202. htonmemcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
  1203. if (new_angv.isExactlyZero())
  1204. {
  1205. // reset rotation time
  1206. resetRot();
  1207. }
  1208. setAngularVelocity(new_angv);
  1209. #if LL_DARWIN
  1210. if (length == 76)
  1211. {
  1212. setAngularVelocity(LLVector3::zero);
  1213. }
  1214. #endif
  1215. break;
  1216. case(32 + 16):
  1217. // pull out collision normal for avatar
  1218. htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
  1219. ((LLVOAvatar*)this)->setFootPlane(collision_plane);
  1220. count += sizeof(LLVector4);
  1221. // fall through
  1222. case 32:
  1223. // this is a terse 16 update
  1224. this_update_precision = 16;
  1225. test_pos_parent.quantize16(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
  1226. #ifdef LL_BIG_ENDIAN
  1227. htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
  1228. val = valswizzle;
  1229. #else
  1230. val = (U16 *) &data[count];
  1231. #endif
  1232. count += sizeof(U16)*3;
  1233. new_pos_parent.mV[VX] = U16_to_F32(val[VX], -0.5f*size, 1.5f*size);
  1234. new_pos_parent.mV[VY] = U16_to_F32(val[VY], -0.5f*size, 1.5f*size);
  1235. new_pos_parent.mV[VZ] = U16_to_F32(val[VZ], MIN_HEIGHT, MAX_HEIGHT);
  1236. #ifdef LL_BIG_ENDIAN
  1237. htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
  1238. val = valswizzle;
  1239. #else
  1240. val = (U16 *) &data[count];
  1241. #endif
  1242. count += sizeof(U16)*3;
  1243. setVelocity(U16_to_F32(val[VX], -size, size),
  1244. U16_to_F32(val[VY], -size, size),
  1245. U16_to_F32(val[VZ], -size, size));
  1246. #ifdef LL_BIG_ENDIAN
  1247. htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
  1248. val = valswizzle;
  1249. #else
  1250. val = (U16 *) &data[count];
  1251. #endif
  1252. count += sizeof(U16)*3;
  1253. setAcceleration(U16_to_F32(val[VX], -size, size),
  1254. U16_to_F32(val[VY], -size, size),
  1255. U16_to_F32(val[VZ], -size, size));
  1256. #ifdef LL_BIG_ENDIAN
  1257. htonmemcpy(valswizzle, &data[count], MVT_U16Quat, 8);
  1258. val = valswizzle;
  1259. #else
  1260. val = (U16 *) &data[count];
  1261. #endif
  1262. count += sizeof(U16)*4;
  1263. new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f);
  1264. new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f);
  1265. new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f);
  1266. new_rot.mQ[VW] = U16_to_F32(val[VW], -1.f, 1.f);
  1267. #ifdef LL_BIG_ENDIAN
  1268. htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
  1269. val = valswizzle;
  1270. #else
  1271. val = (U16 *) &data[count];
  1272. #endif
  1273. setAngularVelocity( U16_to_F32(val[VX], -size, size),
  1274. U16_to_F32(val[VY], -size, size),
  1275. U16_to_F32(val[VZ], -size, size));
  1276. break;
  1277. case 16:
  1278. // this is a terse 8 update
  1279. this_update_precision = 8;
  1280. test_pos_parent.quantize8(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
  1281. new_pos_parent.mV[VX] = U8_to_F32(data[0], -0.5f*size, 1.5f*size);
  1282. new_pos_parent.mV[VY] = U8_to_F32(data[1], -0.5f*size, 1.5f*size);
  1283. new_pos_parent.mV[VZ] = U8_to_F32(data[2], MIN_HEIGHT, MAX_HEIGHT);
  1284. setVelocity(U8_to_F32(data[3], -size, size),
  1285. U8_to_F32(data[4], -size, size),
  1286. U8_to_F32(data[5], -size, size) );
  1287. setAcceleration(U8_to_F32(data[6], -size, size),
  1288. U8_to_F32(data[7], -size, size),
  1289. U8_to_F32(data[8], -size, size) );
  1290. new_rot.mQ[VX] = U8_to_F32(data[9], -1.f, 1.f);
  1291. new_rot.mQ[VY] = U8_to_F32(data[10], -1.f, 1.f);
  1292. new_rot.mQ[VZ] = U8_to_F32(data[11], -1.f, 1.f);
  1293. new_rot.mQ[VW] = U8_to_F32(data[12], -1.f, 1.f);
  1294. setAngularVelocity( U8_to_F32(data[13], -size, size),
  1295. U8_to_F32(data[14], -size, size),
  1296. U8_to_F32(data[15], -size, size) );
  1297. break;
  1298. }
  1299. U8 state;
  1300. mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num );
  1301. mState = state;
  1302. break;
  1303. }
  1304. default:
  1305. break;
  1306. }
  1307. }
  1308. else
  1309. {
  1310. // handle the compressed case
  1311. LLUUID sound_uuid;
  1312. LLUUID owner_id;
  1313. F32 gain = 0;
  1314. U8 sound_flags = 0;
  1315. F32 cutoff = 0;
  1316. U16 val[4];
  1317. U8 state;
  1318. dp->unpackU8(state, "State");
  1319. mState = state;
  1320. switch(update_type)
  1321. {
  1322. case OUT_TERSE_IMPROVED:
  1323. {
  1324. #ifdef DEBUG_UPDATE_TYPE
  1325. llinfos << "CompTI:" << getID() << llendl;
  1326. #endif
  1327. U8 value;
  1328. dp->unpackU8(value, "agent");
  1329. if (value)
  1330. {
  1331. LLVector4 collision_plane;
  1332. dp->unpackVector4(collision_plane, "Plane");
  1333. ((LLVOAvatar*)this)->setFootPlane(collision_plane);
  1334. }
  1335. test_pos_parent = getPosition();
  1336. dp->unpackVector3(new_pos_parent, "Pos");
  1337. dp->unpackU16(val[VX], "VelX");
  1338. dp->unpackU16(val[VY], "VelY");
  1339. dp->unpackU16(val[VZ], "VelZ");
  1340. setVelocity(U16_to_F32(val[VX], -128.f, 128.f),
  1341. U16_to_F32(val[VY], -128.f, 128.f),
  1342. U16_to_F32(val[VZ], -128.f, 128.f));
  1343. dp->unpackU16(val[VX], "AccX");
  1344. dp->unpackU16(val[VY], "AccY");
  1345. dp->unpackU16(val[VZ], "AccZ");
  1346. setAcceleration(U16_to_F32(val[VX], -64.f, 64.f),
  1347. U16_to_F32(val[VY], -64.f, 64.f),
  1348. U16_to_F32(val[VZ], -64.f, 64.f));
  1349. dp->unpackU16(val[VX], "ThetaX");
  1350. dp->unpackU16(val[VY], "ThetaY");
  1351. dp->unpackU16(val[VZ], "ThetaZ");
  1352. dp->unpackU16(val[VS], "ThetaS");
  1353. new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f);
  1354. new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f);
  1355. new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f);
  1356. new_rot.mQ[VS] = U16_to_F32(val[VS], -1.f, 1.f);
  1357. dp->unpackU16(val[VX], "AccX");
  1358. dp->unpackU16(val[VY], "AccY");
  1359. dp->unpackU16(val[VZ], "AccZ");
  1360. setAngularVelocity( U16_to_F32(val[VX], -64.f, 64.f),
  1361. U16_to_F32(val[VY], -64.f, 64.f),
  1362. U16_to_F32(val[VZ], -64.f, 64.f));
  1363. }
  1364. break;
  1365. case OUT_FULL_COMPRESSED:
  1366. case OUT_FULL_CACHED:
  1367. {
  1368. #ifdef DEBUG_UPDATE_TYPE
  1369. llinfos << "CompFull:" << getID() << llendl;
  1370. #endif
  1371. mCostStale = true;
  1372. if (isSelected())
  1373. {
  1374. gFloaterTools->dirty();
  1375. }
  1376. dp->unpackU32(crc, "CRC");
  1377. mTotalCRC = crc;
  1378. dp->unpackU8(material, "Material");
  1379. U8 old_material = getMaterial();
  1380. if (old_material != material)
  1381. {
  1382. setMaterial(material);
  1383. if (mDrawable.notNull())
  1384. {
  1385. gPipeline.markMoved(mDrawable, FALSE); // undamped
  1386. }
  1387. }
  1388. dp->unpackU8(click_action, "ClickAction");
  1389. setClickAction(click_action);
  1390. dp->unpackVector3(new_scale, "Scale");
  1391. dp->unpackVector3(new_pos_parent, "Pos");
  1392. LLVector3 vec;
  1393. dp->unpackVector3(vec, "Rot");
  1394. new_rot.unpackFromVector3(vec);
  1395. setAcceleration(LLVector3::zero);
  1396. U32 value;
  1397. dp->unpackU32(value, "SpecialCode");
  1398. dp->setPassFlags(value);
  1399. dp->unpackUUID(owner_id, "Owner");
  1400. if (value & 0x80)
  1401. {
  1402. dp->unpackVector3(vec, "Omega");
  1403. setAngularVelocity(vec);
  1404. }
  1405. if (value & 0x20)
  1406. {
  1407. dp->unpackU32(parent_id, "ParentID");
  1408. }
  1409. else
  1410. {
  1411. parent_id = 0;
  1412. }
  1413. S32 sp_size;
  1414. U32 size;
  1415. if (value & 0x2)
  1416. {
  1417. sp_size = 1;
  1418. delete [] mData;
  1419. mData = new U8[1];
  1420. dp->unpackU8(((U8*)mData)[0], "TreeData");
  1421. }
  1422. else if (value & 0x1)
  1423. {
  1424. dp->unpackU32(size, "ScratchPadSize");
  1425. delete [] mData;
  1426. mData = new U8[size];
  1427. dp->unpackBinaryData((U8 *)mData, sp_size, "PartData");
  1428. }
  1429. else
  1430. {
  1431. mData = NULL;
  1432. }
  1433. // Setup object text
  1434. if (!mText && (value & 0x4))
  1435. {
  1436. mText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
  1437. mText->setFont(LLFontGL::getFontSansSerif());
  1438. mText->setVertAlignment(LLHUDText::ALIGN_VERT_TOP);
  1439. mText->setMaxLines(-1); // Set to match current agni behavior.
  1440. mText->setSourceObject(this);
  1441. mText->setOnHUDAttachment(isHUDAttachment());
  1442. }
  1443. if (value & 0x4)
  1444. {
  1445. std::string temp_string;
  1446. dp->unpackString(temp_string, "Text");
  1447. LLColor4U coloru;
  1448. dp->unpackBinaryDataFixed(coloru.mV, 4, "Color");
  1449. coloru.mV[3] = 255 - coloru.mV[3];
  1450. mText->setColor(LLColor4(coloru));
  1451. mText->setString(temp_string);
  1452. setChanged(TEXTURE);
  1453. }
  1454. else if(mText.notNull())
  1455. {
  1456. mText->markDead();
  1457. mText = NULL;
  1458. }
  1459. std::string media_url;
  1460. if (value & 0x200)
  1461. {
  1462. dp->unpackString(media_url, "MediaURL");
  1463. }
  1464. retval |= checkMediaURL(media_url);
  1465. //
  1466. // Unpack particle system data
  1467. //
  1468. if (value & 0x8)
  1469. {
  1470. unpackParticleSource(*dp, owner_id);
  1471. }
  1472. else
  1473. {
  1474. deleteParticleSource();
  1475. }
  1476. // Mark all extra parameters not used
  1477. std::map<U16, ExtraParameter*>::iterator iter;
  1478. for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
  1479. {
  1480. iter->second->in_use = FALSE;
  1481. }
  1482. // Unpack extra params
  1483. U8 num_parameters;
  1484. dp->unpackU8(num_parameters, "num_params");
  1485. U8 param_block[MAX_OBJECT_PARAMS_SIZE];
  1486. for (U8 param=0; param<num_parameters; ++param)
  1487. {
  1488. U16 param_type;
  1489. S32 param_size;
  1490. dp->unpackU16(param_type, "param_type");
  1491. dp->unpackBinaryData(param_block, param_size, "param_data");
  1492. //llinfos << "Param type: " << param_type << ", Size: " << param_size << llendl;
  1493. LLDataPackerBinaryBuffer dp2(param_block, param_size);
  1494. unpackParameterEntry(param_type, &dp2);
  1495. }
  1496. for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
  1497. {
  1498. if (!iter->second->in_use)
  1499. {
  1500. // Send an update message in case it was formerly in use
  1501. parameterChanged(iter->first, iter->second->data, FALSE, false);
  1502. }
  1503. }
  1504. if (value & 0x10)
  1505. {
  1506. dp->unpackUUID(sound_uuid, "SoundUUID");
  1507. dp->unpackF32(gain, "SoundGain");
  1508. dp->unpackU8(sound_flags, "SoundFlags");
  1509. dp->unpackF32(cutoff, "SoundRadius");
  1510. }
  1511. if (value & 0x100)
  1512. {
  1513. std::string name_value_list;
  1514. dp->unpackString(name_value_list, "NV");
  1515. setNameValueList(name_value_list);
  1516. }
  1517. mTotalCRC = crc;
  1518. setAttachedSound(sound_uuid, owner_id, gain, sound_flags);
  1519. // only get these flags on updates from sim, not cached ones
  1520. // Preload these five flags for every object.
  1521. // Finer shades require the object to be selected, and the selection manager
  1522. // stores the extended permission info.
  1523. U32 flags;
  1524. mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num);
  1525. // keep local flags and overwrite remote-controlled flags
  1526. mFlags = (mFlags & FLAGS_LOCAL) | flags;
  1527. // ...new objects that should come in selected need to be added to the selected list
  1528. mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0);
  1529. }
  1530. break;
  1531. default:
  1532. break;
  1533. }
  1534. }
  1535. //
  1536. // Fix object parenting.
  1537. //
  1538. BOOL b_changed_status = FALSE;
  1539. if (OUT_TERSE_IMPROVED != update_type)
  1540. {
  1541. // We only need to update parenting on full updates, terse updates
  1542. // don't send parenting information.
  1543. if (!cur_parentp)
  1544. {
  1545. if (parent_id == 0)
  1546. {
  1547. // No parent now, no parent in message -> do nothing
  1548. }
  1549. else
  1550. {
  1551. // No parent now, new parent in message -> attach to that parent if possible
  1552. LLUUID parent_uuid;
  1553. LLViewerObjectList::getUUIDFromLocal(parent_uuid,
  1554. parent_id,
  1555. mesgsys->getSenderIP(),
  1556. mesgsys->getSenderPort());
  1557. LLViewerObject *sent_parentp = gObjectList.findObject(parent_uuid);
  1558. //
  1559. // Check to see if we have the corresponding viewer object for the parent.
  1560. //
  1561. if (sent_parentp && sent_parentp->getParent() == this)
  1562. {
  1563. // Try to recover if we attempt to attach a parent to its child
  1564. llwarns << "Attempt to attach a parent to it's child: " << this->getID() << " to " << sent_parentp->getID() << llendl;
  1565. this->removeChild(sent_parentp);
  1566. sent_parentp->setDrawableParent(NULL);
  1567. }
  1568. if (sent_parentp && (sent_parentp != this) && !sent_parentp->isDead())
  1569. {
  1570. //
  1571. // We have a viewer object for the parent, and it's not dead.
  1572. // Do the actual reparenting here.
  1573. //
  1574. // new parent is valid
  1575. b_changed_status = TRUE;
  1576. // ...no current parent, so don't try to remove child
  1577. if (mDrawable.notNull())
  1578. {
  1579. if (mDrawable->isDead() || !mDrawable->getVObj())
  1580. {
  1581. llwarns << "Drawable is dead or no VObj!" << llendl;
  1582. sent_parentp->addChild(this);
  1583. }
  1584. else
  1585. {
  1586. if (!setDrawableParent(sent_parentp->mDrawable)) // LLViewerObject::processUpdateMessage 1
  1587. {
  1588. // Bad, we got a cycle somehow.
  1589. // Kill both the parent and the child, and
  1590. // set cache misses for both of them.
  1591. llwarns << "Attempting to recover from parenting cycle!" << llendl;
  1592. llwarns << "Killing " << sent_parentp->getID() << " and " << getID() << llendl;
  1593. llwarns << "Adding to cache miss list" << llendl;
  1594. setParent(NULL);
  1595. sent_parentp->setParent(NULL);
  1596. getRegion()->addCacheMissFull(getLocalID());
  1597. getRegion()->addCacheMissFull(sent_parentp->getLocalID());
  1598. gObjectList.killObject(sent_parentp);
  1599. gObjectList.killObject(this);
  1600. return retval;
  1601. }
  1602. sent_parentp->addChild(this);
  1603. // make sure this object gets a non-damped update
  1604. if (sent_parentp->mDrawable.notNull())
  1605. {
  1606. gPipeline.markMoved(sent_parentp->mDrawable, FALSE); // undamped
  1607. }
  1608. }
  1609. }
  1610. else
  1611. {
  1612. sent_parentp->addChild(this);
  1613. }
  1614. // Show particles, icon and HUD
  1615. hideExtraDisplayItems( FALSE );
  1616. setChanged(MOVED | SILHOUETTE);
  1617. }
  1618. else
  1619. {
  1620. //
  1621. // No corresponding viewer object for the parent, put the various
  1622. // pieces on the orphan list.
  1623. //
  1624. //parent_id
  1625. U32 ip = mesgsys->getSenderIP();
  1626. U32 port = mesgsys->getSenderPort();
  1627. gObjectList.orphanize(this, parent_id, ip, port);
  1628. // Hide particles, icon and HUD
  1629. hideExtraDisplayItems( TRUE );
  1630. }
  1631. }
  1632. }
  1633. else
  1634. {
  1635. // BUG: this is a bad assumption once border crossing is alowed
  1636. if ( (parent_id == cur_parentp->mLocalID)
  1637. &&(update_type == OUT_TERSE_IMPROVED))
  1638. {
  1639. // Parent now, same parent in message -> do nothing
  1640. // Debugging for suspected problems with local ids.
  1641. //LLUUID parent_uuid;
  1642. //LLViewerObjectList::getUUIDFromLocal(parent_uuid, parent_id, mesgsys->getSenderIP(), mesgsys->getSenderPort() );
  1643. //if (parent_uuid != cur_parentp->getID() )
  1644. //{
  1645. // llerrs << "Local ID match but UUID mismatch of viewer object" << llendl;
  1646. //}
  1647. }
  1648. else
  1649. {
  1650. // Parented now, different parent in message
  1651. LLViewerObject *sent_parentp;
  1652. if (parent_id == 0)
  1653. {
  1654. //
  1655. // This object is no longer parented, we sent in a zero parent ID.
  1656. //
  1657. sent_parentp = NULL;
  1658. }
  1659. else
  1660. {
  1661. LLUUID parent_uuid;
  1662. LLViewerObjectList::getUUIDFromLocal(parent_uuid,
  1663. parent_id,
  1664. gMessageSystem->getSenderIP(),
  1665. gMessageSystem->getSenderPort());
  1666. sent_parentp = gObjectList.findObject(parent_uuid);
  1667. if (isAvatar())
  1668. {
  1669. // This logic is meant to handle the case where a sitting avatar has reached a new sim
  1670. // ahead of the object she was sitting on (which is common as objects are transfered through
  1671. // a slower route than agents)...
  1672. // In this case, the local id for the object will not be valid, since the viewer has not received
  1673. // a full update for the object from that sim yet, so we assume that the agent is still sitting
  1674. // where she was originally. --RN
  1675. if (!sent_parentp)
  1676. {
  1677. sent_parentp = cur_parentp;
  1678. }
  1679. }
  1680. else if (!sent_parentp)
  1681. {
  1682. //
  1683. // Switching parents, but we don't know the new parent.
  1684. //
  1685. U32 ip = mesgsys->getSenderIP();
  1686. U32 port = mesgsys->getSenderPort();
  1687. // We're an orphan, flag things appropriately.
  1688. gObjectList.orphanize(this, parent_id, ip, port);
  1689. }
  1690. }
  1691. // Reattach if possible.
  1692. if (sent_parentp && sent_parentp != cur_parentp && sent_parentp != this)
  1693. {
  1694. // New parent is valid, detach and reattach
  1695. b_changed_status = TRUE;
  1696. if (mDrawable.notNull())
  1697. {
  1698. if (!setDrawableParent(sent_parentp->mDrawable)) // LLViewerObject::processUpdateMessage 2
  1699. {
  1700. // Bad, we got a cycle somehow.
  1701. // Kill both the parent and the child, and
  1702. // set cache misses for both of them.
  1703. llwarns << "Attempting to recover from parenting cycle!" << llendl;
  1704. llwarns << "Killing " << sent_parentp->getID() << " and " << getID() << llendl;
  1705. llwarns << "Adding to cache miss list" << llendl;
  1706. setParent(NULL);
  1707. sent_parentp->setParent(NULL);
  1708. getRegion()->addCacheMissFull(getLocalID());
  1709. getRegion()->addCacheMissFull(sent_parentp->getLocalID());
  1710. gObjectList.killObject(sent_parentp);
  1711. gObjectList.killObject(this);
  1712. return retval;
  1713. }
  1714. // make sure this object gets a non-damped update
  1715. }
  1716. cur_parentp->removeChild(this);
  1717. sent_parentp->addChild(this);
  1718. setChanged(MOVED | SILHOUETTE);
  1719. sent_parentp->setChanged(MOVED | SILHOUETTE);
  1720. if (sent_parentp->mDrawable.notNull())
  1721. {
  1722. gPipeline.markMoved(sent_parentp->mDrawable, FALSE); // undamped
  1723. }
  1724. }
  1725. else if (!sent_parentp)
  1726. {
  1727. bool remove_parent = true;
  1728. // No new parent, or the parent that we sent doesn't exist on the viewer.
  1729. LLViewerObject *parentp = (LLViewerObject *)getParent();
  1730. if (parentp)
  1731. {
  1732. if (parentp->getRegion() != getRegion())
  1733. {
  1734. // This is probably an object flying across a region boundary, the
  1735. // object probably ISN'T being reparented, but just got an object
  1736. // update out of order (child update before parent).
  1737. //llinfos << "Don't reparent object handoffs!" << llendl;
  1738. remove_parent = false;
  1739. }
  1740. }
  1741. if (remove_parent)
  1742. {
  1743. b_changed_status = TRUE;
  1744. if (mDrawable.notNull())
  1745. {
  1746. // clear parent to removeChild can put the drawable on the damped list
  1747. setDrawableParent(NULL); // LLViewerObject::processUpdateMessage 3
  1748. }
  1749. cur_parentp->removeChild(this);
  1750. if (mJointInfo && !parent_id)
  1751. {
  1752. // since this object is no longer parent-relative
  1753. // we make sure we delete any joint info
  1754. delete mJointInfo;
  1755. mJointInfo = NULL;
  1756. }
  1757. setChanged(MOVED | SILHOUETTE);
  1758. if (mDrawable.notNull())
  1759. {
  1760. // make sure this object gets a non-damped update
  1761. gPipeline.markMoved(mDrawable, FALSE); // undamped
  1762. }
  1763. }
  1764. }
  1765. }
  1766. }
  1767. }
  1768. new_rot.normQuat();
  1769. if (sPingInterpolate)
  1770. {
  1771. LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mesgsys->getSender());
  1772. if (cdp)
  1773. {
  1774. F32 ping_delay = 0.5f * mTimeDilation * ( ((F32)cdp->getPingDelay()) * 0.001f + gFrameDTClamped);
  1775. LLVector3 diff = getVelocity() * ping_delay;
  1776. new_pos_parent += diff;
  1777. }
  1778. else
  1779. {
  1780. llwarns << "findCircuit() returned NULL; skipping interpolation" << llendl;
  1781. }
  1782. }
  1783. //////////////////////////
  1784. //
  1785. // Set the generic change flags...
  1786. //
  1787. //
  1788. // If we're going to skip this message, why are we
  1789. // doing all the parenting, etc above?
  1790. U32 packet_id = mesgsys->getCurrentRecvPacketID();
  1791. if (packet_id < mLatestRecvPacketID &&
  1792. mLatestRecvPacketID - packet_id < 65536)
  1793. {
  1794. //skip application of this message, it's old
  1795. return retval;
  1796. }
  1797. mLatestRecvPacketID = packet_id;
  1798. // Set the change flags for scale
  1799. if (new_scale != getScale())
  1800. {
  1801. setChanged(SCALED | SILHOUETTE);
  1802. setScale(new_scale); // Must follow setting permYouOwner()
  1803. }
  1804. // first, let's see if the new position is actually a change
  1805. //static S32 counter = 0;
  1806. F32 vel_mag_sq = getVelocity().magVecSquared();
  1807. F32 accel_mag_sq = getAcceleration().magVecSquared();
  1808. if ( ((b_changed_status)||(test_pos_parent != new_pos_parent))
  1809. ||( (!isSelected())
  1810. &&( (vel_mag_sq != 0.f)
  1811. ||(accel_mag_sq != 0.f)
  1812. ||(this_update_precision > mBestUpdatePrecision))))
  1813. {
  1814. mBestUpdatePrecision = this_update_precision;
  1815. LLVector3 diff = new_pos_parent - test_pos_parent ;
  1816. F32 mag_sqr = diff.magVecSquared() ;
  1817. if(llfinite(mag_sqr))
  1818. {
  1819. setPositionParent(new_pos_parent);
  1820. }
  1821. else
  1822. {
  1823. llwarns << "Can not move the object/avatar to an infinite location!" << llendl ;
  1824. retval |= INVALID_UPDATE ;
  1825. }
  1826. if (mParent && ((LLViewerObject*)mParent)->isAvatar())
  1827. {
  1828. // we have changed the position of an attachment, so we need to clamp it
  1829. LLVOAvatar *avatar = (LLVOAvatar*)mParent;
  1830. avatar->clampAttachmentPositions();
  1831. }
  1832. // If we're snapping the position by more than 0.5m, update LLViewerStats::mAgentPositionSnaps
  1833. if ( asAvatar() && asAvatar()->isSelf() && (mag_sqr > 0.25f) )
  1834. {
  1835. LLViewerStats::getInstance()->mAgentPositionSnaps.push( diff.length() );
  1836. }
  1837. }
  1838. if (new_rot != mLastRot
  1839. || new_angv != old_angv)
  1840. {
  1841. if (new_rot != mLastRot)
  1842. {
  1843. mLastRot = new_rot;
  1844. setRotation(new_rot);
  1845. }
  1846. setChanged(ROTATED | SILHOUETTE);
  1847. resetRot();
  1848. }
  1849. if ( gShowObjectUpdates )
  1850. {
  1851. LLColor4 color;
  1852. if (update_type == OUT_TERSE_IMPROVED)
  1853. {
  1854. color.setVec(0.f, 0.f, 1.f, 1.f);
  1855. }
  1856. else
  1857. {
  1858. color.setVec(1.f, 0.f, 0.f, 1.f);
  1859. }
  1860. gPipeline.addDebugBlip(getPositionAgent(), color);
  1861. }
  1862. if ((0.0f == vel_mag_sq) &&
  1863. (0.0f == accel_mag_sq) &&
  1864. (0.0f == getAngularVelocity().magVecSquared()))
  1865. {
  1866. mStatic = TRUE; // This object doesn't move!
  1867. }
  1868. else
  1869. {
  1870. mStatic = FALSE;
  1871. }
  1872. // BUG: This code leads to problems during group rotate and any scale operation.
  1873. // Small discepencies between the simulator and viewer representations cause the
  1874. // selection center to creep, leading to objects moving around the wrong center.
  1875. //
  1876. // Removing this, however, means that if someone else drags an object you have
  1877. // selected, your selection center and dialog boxes will be wrong. It also means
  1878. // that higher precision information on selected objects will be ignored.
  1879. //
  1880. // I believe the group rotation problem is fixed. JNC 1.21.2002
  1881. //
  1882. // Additionally, if any child is selected, need to update the dialogs and selection
  1883. // center.
  1884. BOOL needs_refresh = mUserSelected;
  1885. for (child_list_t::iterator iter = mChildList.begin();
  1886. iter != mChildList.end(); iter++)
  1887. {
  1888. LLViewerObject* child = *iter;
  1889. needs_refresh = needs_refresh || child->mUserSelected;
  1890. }
  1891. if (needs_refresh)
  1892. {
  1893. LLSelectMgr::getInstance()->updateSelectionCenter();
  1894. dialog_refresh_all();
  1895. }
  1896. // Mark update time as approx. now, with the ping delay.
  1897. // Ping delay is off because it's not set for velocity interpolation, causing
  1898. // much jumping and hopping around...
  1899. // U32 ping_delay = mesgsys->mCircuitInfo.getPingDelay();
  1900. mLastInterpUpdateSecs = LLFrameTimer::getElapsedSeconds();
  1901. mLastMessageUpdateSecs = mLastInterpUpdateSecs;
  1902. if (mDrawable.notNull())
  1903. {
  1904. // Don't clear invisibility flag on update if still orphaned!
  1905. if (mDrawable->isState(LLDrawable::FORCE_INVISIBLE) && !mOrphaned)
  1906. {
  1907. // lldebugs << "Clearing force invisible: " << mID << ":" << getPCodeString() << ":" << getPositionAgent() << llendl;
  1908. mDrawable->setState(LLDrawable::CLEAR_INVISIBLE);
  1909. }
  1910. }
  1911. // Update special hover cursor status
  1912. bool special_hover_cursor = specialHoverCursor();
  1913. if (old_special_hover_cursor != special_hover_cursor
  1914. && mDrawable.notNull())
  1915. {
  1916. mDrawable->updateSpecialHoverCursor(special_hover_cursor);
  1917. }
  1918. return retval;
  1919. }
  1920. BOOL LLViewerObject::isActive() const
  1921. {
  1922. return TRUE;
  1923. }
  1924. BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
  1925. {
  1926. static LLFastTimer::DeclareTimer ftm("Viewer Object");
  1927. LLFastTimer t(ftm);
  1928. if (mDead)
  1929. {
  1930. // It's dead. Don't update it.
  1931. return TRUE;
  1932. }
  1933. // CRO - don't velocity interp linked objects!
  1934. // Leviathan - but DO velocity interp joints
  1935. if (!mStatic && sVelocityInterpolate && !isSelected())
  1936. {
  1937. // calculate dt from last update
  1938. F32 dt_raw = (F32)(time - mLastInterpUpdateSecs);
  1939. F32 dt = mTimeDilation * dt_raw;
  1940. if (!mJointInfo)
  1941. {
  1942. applyAngularVelocity(dt);
  1943. }
  1944. LLViewerObject *parentp = (LLViewerObject *) getParent();
  1945. if (mJointInfo)
  1946. {
  1947. if (parentp)
  1948. {
  1949. // do parent-relative stuff
  1950. LLVector3 ang_vel = getAngularVelocity();
  1951. F32 omega = ang_vel.magVecSquared();
  1952. F32 angle = 0.0f;
  1953. LLQuaternion dQ;
  1954. if (omega > 0.00001f)
  1955. {
  1956. omega = sqrt(omega);
  1957. angle = omega * dt;
  1958. dQ.setQuat(angle, ang_vel);
  1959. }
  1960. LLVector3 pos = getPosition();
  1961. if (HJT_HINGE == mJointInfo->mJointType)
  1962. {
  1963. // hinge = uniform circular motion
  1964. LLVector3 parent_pivot = getVelocity();
  1965. LLVector3 parent_axis = getAcceleration();
  1966. angle = dt * (ang_vel * mJointInfo->mAxisOrAnchor); // AxisOrAnchor = axis
  1967. dQ.setQuat(angle, mJointInfo->mAxisOrAnchor); // AxisOrAnchor = axis
  1968. LLVector3 pivot_offset = pos - mJointInfo->mPivot; // pos in pivot-frame
  1969. pivot_offset = pivot_offset * dQ; // new rotated pivot-frame pos
  1970. pos = mJointInfo->mPivot + pivot_offset; // parent-frame
  1971. LLViewerObject::setPosition(pos);
  1972. LLQuaternion Q_PC = getRotation();
  1973. setRotation(Q_PC * dQ);
  1974. mLastInterpUpdateSecs = time;
  1975. }
  1976. else if (HJT_POINT == mJointInfo->mJointType)
  1977. // || HJT_LPOINT == mJointInfo->mJointType)
  1978. {
  1979. // point-to-point = spin about axis and uniform circular motion
  1980. // of axis about the pivot point
  1981. //
  1982. // NOTE: this interpolation scheme is not quite good enough to
  1983. // reduce the bandwidth -- needs a gravitational correction.
  1984. // Similarly for hinges with axes that deviate from vertical.
  1985. LLQuaternion Q_PC = getRotation();
  1986. Q_PC = Q_PC * dQ;
  1987. setRotation(Q_PC);
  1988. LLVector3 pivot_to_child = - mJointInfo->mAxisOrAnchor; // AxisOrAnchor = anchor
  1989. pos = mJointInfo->mPivot + pivot_to_child * Q_PC;
  1990. LLViewerObject::setPosition(pos);
  1991. mLastInterpUpdateSecs = time;
  1992. }
  1993. /* else if (HJT_WHEEL == mJointInfo->mJointInfo)
  1994. {
  1995. // wheel = uniform rotation about axis, with linear
  1996. // velocity interpolation (if any)
  1997. LLVector3 parent_axis = getAcceleration(); // HACK -- accel stores the parent-axis (parent-frame)
  1998. LLQuaternion Q_PC = getRotation();
  1999. angle = dt * (parent_axis * ang_vel);
  2000. dQ.setQuat(angle, parent_axis);
  2001. Q_PC = Q_PC * dQ;
  2002. setRotation(Q_PC);
  2003. pos = getPosition() + dt * getVelocity();
  2004. LLViewerObject::setPosition(pos);
  2005. mLastInterpUpdateSecs = time;
  2006. }*/
  2007. }
  2008. }
  2009. else if (isAttachment())
  2010. {
  2011. mLastInterpUpdateSecs = time;
  2012. return TRUE;
  2013. }
  2014. else
  2015. { // Move object based on it's velocity and rotation
  2016. interpolateLinearMotion(time, dt);
  2017. }
  2018. }
  2019. updateDrawable(FALSE);
  2020. return TRUE;
  2021. }
  2022. // Move an object due to idle-time viewer side updates by iterpolating motion
  2023. void LLViewerObject::interpolateLinearMotion(const F64 & time, const F32 & dt)
  2024. {
  2025. // linear motion
  2026. // PHYSICS_TIMESTEP is used below to correct for the fact that the velocity in object
  2027. // updates represents the average velocity of the last timestep, rather than the final velocity.
  2028. // the time dilation above should guarantee that dt is never less than PHYSICS_TIMESTEP, theoretically
  2029. //
  2030. // *TODO: sh