llviewerjointattachment.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. /**
  2. * @file llviewerjointattachment.cpp
  3. * @brief Implementation of LLViewerJointAttachment class
  4. *
  5. * $LicenseInfo:firstyear=2002&license=viewergpl$
  6. *
  7. * Copyright (c) 2002-2009, 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 "llviewerjointattachment.h"
  34. #include "llgl.h"
  35. #include "llrender.h"
  36. #include "llvolume.h"
  37. #include "llagent.h" // For MAX_ATTACHMENT_DIST + RLV
  38. #include "lldrawable.h"
  39. #include "llface.h"
  40. #include "llhudtext.h"
  41. #include "llinventorymodel.h"
  42. #include "llpipeline.h"
  43. //MK
  44. #include "mkrlinterface.h"
  45. //mk
  46. #include "llspatialpartition.h"
  47. #include "llviewercontrol.h"
  48. #include "llviewerobjectlist.h"
  49. #include "llvoavatarself.h"
  50. LLViewerJointAttachment::LLViewerJointAttachment()
  51. : mGroup(0),
  52. mVisibleInFirst(false),
  53. mIsHUDAttachment(false),
  54. mPieSlice(-1)
  55. {
  56. mValid = false;
  57. mUpdateXform = false;
  58. mAttachedObjects.clear();
  59. }
  60. //virtual
  61. U32 LLViewerJointAttachment::drawShape(bool first_pass, bool is_dummy)
  62. {
  63. if (LLVOAvatar::sShowAttachmentPoints)
  64. {
  65. LLGLDisable cull_face(GL_CULL_FACE);
  66. gGL.color4f(1.f, 1.f, 1.f, 1.f);
  67. gGL.begin(LLRender::TRIANGLES);
  68. {
  69. gGL.vertex3f(-0.1f, 0.1f, 0.f);
  70. gGL.vertex3f(-0.1f, -0.1f, 0.f);
  71. gGL.vertex3f(0.1f, -0.1f, 0.f);
  72. gGL.vertex3f(-0.1f, 0.1f, 0.f);
  73. gGL.vertex3f(0.1f, -0.1f, 0.f);
  74. gGL.vertex3f(0.1f, 0.1f, 0.f);
  75. }
  76. gGL.end();
  77. }
  78. return 0;
  79. }
  80. void LLViewerJointAttachment::setupDrawable(LLViewerObject* object)
  81. {
  82. if (!object->mDrawable)
  83. {
  84. return;
  85. }
  86. if (object->mDrawable->isActive())
  87. {
  88. object->mDrawable->makeStatic(false);
  89. }
  90. object->mDrawable->mXform.setParent(getXform());
  91. object->mDrawable->makeActive();
  92. LLVector3 current_pos = object->getRenderPosition();
  93. LLQuaternion current_rot = object->getRenderRotation();
  94. LLQuaternion attachment_pt_inv_rot = ~(getWorldRotation());
  95. current_pos -= getWorldPosition();
  96. current_pos.rotVec(attachment_pt_inv_rot);
  97. current_rot = current_rot * attachment_pt_inv_rot;
  98. object->mDrawable->mXform.setPosition(current_pos);
  99. object->mDrawable->mXform.setRotation(current_rot);
  100. gPipeline.markMoved(object->mDrawable);
  101. // face may need to change draw pool to/from POOL_HUD
  102. gPipeline.markTextured(object->mDrawable);
  103. if (mIsHUDAttachment)
  104. {
  105. for (S32 i = 0, count = object->mDrawable->getNumFaces();
  106. i < count; ++i)
  107. {
  108. LLFace* facep = object->mDrawable->getFace(i);
  109. if (facep)
  110. {
  111. facep->setState(LLFace::HUD_RENDER);
  112. }
  113. }
  114. ((LLViewerOctreeEntryData*)object->mDrawable)->setVisible();
  115. }
  116. LLViewerObject::const_child_list_t& child_list = object->getChildren();
  117. for (LLViewerObject::child_list_t::const_iterator
  118. iter = child_list.begin(), end = child_list.end();
  119. iter != end; ++iter)
  120. {
  121. LLViewerObject* childp = *iter;
  122. if (childp && childp->mDrawable.notNull())
  123. {
  124. // Face may need to change draw pool to/from POOL_HUD
  125. gPipeline.markTextured(childp->mDrawable);
  126. gPipeline.markMoved(childp->mDrawable);
  127. if (mIsHUDAttachment)
  128. {
  129. ((LLViewerOctreeEntryData*)childp->mDrawable)->setVisible();
  130. for (S32 i = 0, count = childp->mDrawable->getNumFaces();
  131. i < count; ++i)
  132. {
  133. LLFace* facep = childp->mDrawable->getFace(i);
  134. if (facep)
  135. {
  136. facep->setState(LLFace::HUD_RENDER);
  137. }
  138. }
  139. }
  140. }
  141. }
  142. }
  143. bool LLViewerJointAttachment::addObject(LLViewerObject* object, bool is_self)
  144. {
  145. if (!object || (is_self && !isAgentAvatarValid()))
  146. {
  147. return false;
  148. }
  149. object->extractAttachmentItemID();
  150. if (isObjectAttached(object))
  151. {
  152. llinfos << "Same object re-attached: " << object->getID() << llendl;
  153. #if 0 // Do not do this: OpenSim grids (wrongly) send such duplicate attach
  154. // events after a TP into a new sim, and they (also wrongly) do not
  155. // send an addChild event after the attach event: with this code path
  156. // (i.e. removal of the object from the attachment list and waiting for
  157. // addChild to re-add it), we end up with phantom attachments still
  158. // rendered but not listed in mAttachedObjects !
  159. removeObject(object, is_self);
  160. // Pass through anyway to let setupDrawable() re-connect object to the
  161. // joint correctly
  162. #else // Instead, we make sure the drawable is properly connected and we
  163. // ignore the duplicate reattach event.
  164. setupDrawable(object); // re-connect object to the joint correctly
  165. return false;
  166. #endif
  167. }
  168. // Two instances of the same inventory item attached: request detach and
  169. // kill the object in the meantime.
  170. if (is_self && getAttachedObject(object->getAttachmentItemID()))
  171. {
  172. llinfos << "Same inventory object re-attached, detaching spurious instance: "
  173. << object->getAttachmentItemID() << llendl;
  174. object->markDead();
  175. // If this happens to be attached to self, then detach.
  176. LLVOAvatarSelf::detachAttachmentIntoInventory(object->getAttachmentItemID());
  177. return false;
  178. }
  179. mAttachedObjects.push_back(object);
  180. setupDrawable(object);
  181. if (is_self)
  182. {
  183. if (mIsHUDAttachment)
  184. {
  185. if (object->mText.notNull())
  186. {
  187. object->mText->setOnHUDAttachment(true);
  188. }
  189. LLViewerObject::const_child_list_t& child_list = object->getChildren();
  190. for (LLViewerObject::child_list_t::const_iterator
  191. iter = child_list.begin(), end = child_list.end();
  192. iter != end; ++iter)
  193. {
  194. LLViewerObject* childp = *iter;
  195. if (childp && childp->mText.notNull())
  196. {
  197. childp->mText->setOnHUDAttachment(true);
  198. }
  199. }
  200. }
  201. }
  202. calcLOD();
  203. mUpdateXform = true;
  204. //MK
  205. if (is_self && gRLenabled)
  206. {
  207. LLUUID item_id = object->getAttachmentItemID();
  208. std::string name = getName();
  209. LLStringUtil::toLower(name);
  210. // If this attachment point is locked then force detach, unless the
  211. // attached object was supposed to be reattached automatically
  212. if (!gRLInterface.canAttach(object, name) &&
  213. !gRLInterface.isRestoringOutfit())
  214. {
  215. bool just_reattaching = false;
  216. for (rl_reattach_it_t it = gRLInterface.mAssetsToReattach.begin();
  217. it != gRLInterface.mAssetsToReattach.end(); ++it)
  218. {
  219. if (it->mId == item_id)
  220. {
  221. just_reattaching = true;
  222. break;
  223. }
  224. }
  225. if (!just_reattaching)
  226. {
  227. llinfos << "Illegally attached to a locked point: " << item_id
  228. << ", detaching." << llendl;
  229. LLMessageSystem* msg = gMessageSystemp;
  230. msg->newMessage("ObjectDetach");
  231. msg->nextBlockFast(_PREHASH_AgentData);
  232. msg->addUUIDFast(_PREHASH_AgentID, gAgentID);
  233. msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
  234. msg->nextBlockFast(_PREHASH_ObjectData);
  235. msg->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID());
  236. msg->sendReliable(gAgent.getRegionHost());
  237. gRLInterface.mJustDetached.mId = item_id;
  238. gRLInterface.mJustDetached.mName = getName();
  239. // Now notify that this object has been attached and will be
  240. // detached right away
  241. gRLInterface.notify("attached illegally " + getName());
  242. }
  243. else
  244. {
  245. // Notify that this object has just been reattached
  246. gRLInterface.notify("reattached legally " + getName());
  247. }
  248. }
  249. else
  250. {
  251. // Notify that this object has been attached
  252. gRLInterface.notify("attached legally " + getName());
  253. }
  254. // If the UUID of the attached item is contained in the list of the
  255. // objects waiting to reattach, signal it and remove it from the list.
  256. for (rl_reattach_it_t it = gRLInterface.mAssetsToReattach.begin();
  257. it != gRLInterface.mAssetsToReattach.end(); ++it)
  258. {
  259. if (it->mId == item_id)
  260. {
  261. llinfos << "Reattached asset " << item_id << " automatically"
  262. << llendl;
  263. gRLInterface.mReattaching = false;
  264. gRLInterface.mReattachTimeout = false;
  265. gRLInterface.mAssetsToReattach.erase(it);
  266. #if 0
  267. gRLInterface.mJustReattached.mId = item_id;
  268. gRLInterface.mJustReattached.mName = getName();
  269. #endif
  270. // Replace the previously stored asset id with the new viewer
  271. // id in the list of restrictions
  272. gRLInterface.replace(item_id, object->getRootEdit()->getID());
  273. break;
  274. }
  275. }
  276. }
  277. //mk
  278. return true;
  279. }
  280. void LLViewerJointAttachment::removeObject(LLViewerObject* object,
  281. bool is_self)
  282. {
  283. attachedobjs_vec_t::iterator iter;
  284. attachedobjs_vec_t::iterator iend = mAttachedObjects.end();
  285. for (iter = mAttachedObjects.begin(); iter != iend; ++iter)
  286. {
  287. LLViewerObject* attached_object = iter->get();
  288. if (attached_object == object)
  289. {
  290. break;
  291. }
  292. }
  293. if (iter == iend)
  294. {
  295. llwarns << "Could not find object to detach" << llendl;
  296. return;
  297. }
  298. //MK
  299. if (is_self && gRLenabled && isAgentAvatarValid())
  300. {
  301. // We first need to check whether the object is locked, as some
  302. // techniques (like llAttachToAvatar) can kick even a locked attachment
  303. // off. If so, retain its UUID for later
  304. // Note: we need to delay the reattach a little, or we risk losing the
  305. // item in the inventory.
  306. LLInventoryItem* inv_item;
  307. inv_item = gRLInterface.getItem(object->getRootEdit()->getID());
  308. LLUUID inv_item_id;
  309. if (inv_item)
  310. {
  311. inv_item_id = inv_item->getUUID();
  312. }
  313. std::string target_attachpt;
  314. target_attachpt = gAgentAvatarp->getAttachedPointName(inv_item_id);
  315. inv_item_id = object->getAttachmentItemID();
  316. if (!gRLInterface.canDetach(object) &&
  317. #if 0
  318. // We did not just reattach something to this attach pt automatically
  319. gRLInterface.mJustReattached.mName != target_attachpt &&
  320. #endif
  321. // We did not just detach something from this attach pt automatically
  322. gRLInterface.mJustDetached.mName != target_attachpt)
  323. {
  324. llinfos << "Detached a locked object : " << inv_item_id << " from "
  325. << target_attachpt << llendl;
  326. // Now notify that this object has been detached and will be
  327. // reattached right away
  328. gRLInterface.notify("detached illegally " + getName());
  329. bool found = false;
  330. bool found_for_this_point = false;
  331. for (rl_reattach_it_t it = gRLInterface.mAssetsToReattach.begin();
  332. it != gRLInterface.mAssetsToReattach.end(); ++it)
  333. {
  334. if (it->mId == inv_item_id)
  335. {
  336. found = true;
  337. }
  338. if (it->mName == target_attachpt)
  339. {
  340. found_for_this_point = true;
  341. }
  342. }
  343. if (!found && !found_for_this_point)
  344. {
  345. gRLInterface.mReattachTimer.reset();
  346. gRLInterface.mAssetsToReattach.emplace_back(inv_item_id,
  347. target_attachpt);
  348. // Little hack: store this item's asset id into the list of
  349. // restrictions so they are automatically reapplied when it is
  350. // reattached
  351. gRLInterface.replace(object->getRootEdit()->getID(),
  352. inv_item_id);
  353. }
  354. }
  355. else if (inv_item)
  356. {
  357. // Notify that this object has been detached
  358. gRLInterface.notify("detached legally " + getName());
  359. }
  360. gRLInterface.mJustDetached.mId.setNull();
  361. gRLInterface.mJustDetached.mName.clear();
  362. #if 0
  363. gRLInterface.mJustReattached.mId.setNull();
  364. gRLInterface.mJustReattached.mName.clear();
  365. #endif
  366. }
  367. //mk
  368. // Force object visibile
  369. setAttachmentVisibility(true);
  370. mAttachedObjects.erase(iter);
  371. if (object->mDrawable.notNull())
  372. {
  373. // If object is active, make it static
  374. if (object->mDrawable->isActive())
  375. {
  376. object->mDrawable->makeStatic(false);
  377. }
  378. LLVector3 cur_position = object->getRenderPosition();
  379. LLQuaternion cur_rotation = object->getRenderRotation();
  380. object->mDrawable->mXform.setPosition(cur_position);
  381. object->mDrawable->mXform.setRotation(cur_rotation);
  382. gPipeline.markMoved(object->mDrawable, true);
  383. // Face may need to change draw pool to/from POOL_HUD
  384. gPipeline.markTextured(object->mDrawable);
  385. if (is_self && mIsHUDAttachment)
  386. {
  387. for (S32 i = 0, count = object->mDrawable->getNumFaces();
  388. i < count; ++i)
  389. {
  390. LLFace* facep = object->mDrawable->getFace(i);
  391. if (facep)
  392. {
  393. facep->clearState(LLFace::HUD_RENDER);
  394. }
  395. }
  396. }
  397. }
  398. LLViewerObject::const_child_list_t& child_list = object->getChildren();
  399. for (LLViewerObject::child_list_t::const_iterator
  400. iter = child_list.begin(), end = child_list.end();
  401. iter != end; ++iter)
  402. {
  403. LLViewerObject* childp = *iter;
  404. if (childp && childp->mDrawable.notNull())
  405. {
  406. // Face may need to change draw pool to/from POOL_HUD:
  407. gPipeline.markTextured(childp->mDrawable);
  408. if (is_self && mIsHUDAttachment)
  409. {
  410. for (S32 i = 0, count = childp->mDrawable->getNumFaces();
  411. i < count; ++i)
  412. {
  413. LLFace* facep = childp->mDrawable->getFace(i);
  414. if (facep)
  415. {
  416. facep->clearState(LLFace::HUD_RENDER);
  417. }
  418. }
  419. }
  420. }
  421. }
  422. if (is_self)
  423. {
  424. if (mIsHUDAttachment)
  425. {
  426. if (object->mText.notNull())
  427. {
  428. object->mText->setOnHUDAttachment(false);
  429. }
  430. LLViewerObject::const_child_list_t& child_list = object->getChildren();
  431. for (LLViewerObject::child_list_t::const_iterator
  432. iter = child_list.begin(), end = child_list.end();
  433. iter != end; ++iter)
  434. {
  435. LLViewerObject* childp = *iter;
  436. if (childp && childp->mText.notNull())
  437. {
  438. childp->mText->setOnHUDAttachment(false);
  439. }
  440. }
  441. }
  442. }
  443. if (mAttachedObjects.size() == 0)
  444. {
  445. mUpdateXform = false;
  446. }
  447. object->setAttachmentItemID(LLUUID::null);
  448. }
  449. void LLViewerJointAttachment::setAttachmentVisibility(bool visible)
  450. {
  451. for (attachedobjs_vec_t::const_iterator
  452. iter = mAttachedObjects.begin(), end = mAttachedObjects.end();
  453. iter != end; ++iter)
  454. {
  455. LLViewerObject* attached_obj = iter->get();
  456. if (!attached_obj || attached_obj->mDrawable.isNull() ||
  457. !(attached_obj->mDrawable->getSpatialBridge()))
  458. continue;
  459. if (visible)
  460. {
  461. // *HACK: to make attachments not visible by disabling their type
  462. // mask ! This will break if you can ever attach non-volumes !
  463. // djs 02/14/03
  464. attached_obj->mDrawable->getSpatialBridge()->mDrawableType =
  465. attached_obj->isHUDAttachment() ? LLPipeline::RENDER_TYPE_HUD
  466. : LLPipeline::RENDER_TYPE_VOLUME;
  467. }
  468. else
  469. {
  470. attached_obj->mDrawable->getSpatialBridge()->mDrawableType = 0;
  471. }
  472. }
  473. }
  474. S32 LLViewerJointAttachment::getNumAnimatedObjects() const
  475. {
  476. S32 count = 0;
  477. for (attachedobjs_vec_t::const_iterator
  478. iter = mAttachedObjects.begin(), end = mAttachedObjects.end();
  479. iter != end; ++iter)
  480. {
  481. const LLViewerObject* attached_obj = iter->get();
  482. if (attached_obj && attached_obj->isAnimatedObject())
  483. {
  484. ++count;
  485. }
  486. }
  487. return count;
  488. }
  489. void LLViewerJointAttachment::setOriginalPosition(LLVector3& position)
  490. {
  491. mOriginalPos = position;
  492. setPosition(position);
  493. }
  494. void LLViewerJointAttachment::clampObjectPosition()
  495. {
  496. for (attachedobjs_vec_t::const_iterator iter = mAttachedObjects.begin(),
  497. end = mAttachedObjects.end();
  498. iter != end; ++iter)
  499. {
  500. if (LLViewerObject* attached_object = iter->get())
  501. {
  502. // *NOTE: object can drift when hitting maximum radius
  503. LLVector3 attachmentPos = attached_object->getPosition();
  504. F32 dist = attachmentPos.normalize();
  505. dist = llmin(dist, MAX_ATTACHMENT_DIST);
  506. attachmentPos *= dist;
  507. attached_object->setPosition(attachmentPos);
  508. }
  509. }
  510. }
  511. void LLViewerJointAttachment::calcLOD()
  512. {
  513. F32 maxarea = 0;
  514. for (attachedobjs_vec_t::const_iterator iter = mAttachedObjects.begin(),
  515. end = mAttachedObjects.end();
  516. iter != end; ++iter)
  517. {
  518. if (LLViewerObject* attached_object = iter->get())
  519. {
  520. maxarea = llmax(maxarea,
  521. attached_object->getMaxScale() * attached_object->getMidScale());
  522. LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
  523. for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
  524. iter != child_list.end(); ++iter)
  525. {
  526. LLViewerObject* childp = *iter;
  527. F32 area = childp->getMaxScale() * childp->getMidScale();
  528. maxarea = llmax(maxarea, area);
  529. }
  530. }
  531. }
  532. maxarea = llclamp(maxarea, .01f * .01f, 1.f);
  533. F32 avatar_area = (4.f * 4.f); // pixels for an avatar sized attachment
  534. F32 min_pixel_area = avatar_area / maxarea;
  535. setLOD(min_pixel_area);
  536. }
  537. bool LLViewerJointAttachment::updateLOD(F32 pixel_area, bool activate)
  538. {
  539. if (mValid)
  540. {
  541. return false;
  542. }
  543. setValid(true, true);
  544. return true;
  545. }
  546. bool LLViewerJointAttachment::isObjectAttached(const LLViewerObject* viewer_object) const
  547. {
  548. for (attachedobjs_vec_t::const_iterator iter = mAttachedObjects.begin(),
  549. end = mAttachedObjects.end();
  550. iter != end; ++iter)
  551. {
  552. const LLViewerObject* attached_object = iter->get();
  553. if (attached_object == viewer_object)
  554. {
  555. return true;
  556. }
  557. }
  558. return false;
  559. }
  560. const LLViewerObject* LLViewerJointAttachment::getAttachedObject(const LLUUID& object_id) const
  561. {
  562. for (attachedobjs_vec_t::const_iterator iter = mAttachedObjects.begin(),
  563. end = mAttachedObjects.end();
  564. iter != end; ++iter)
  565. {
  566. const LLViewerObject* attached_object = iter->get();
  567. if (attached_object->getAttachmentItemID() == object_id)
  568. {
  569. return attached_object;
  570. }
  571. }
  572. return NULL;
  573. }
  574. LLViewerObject* LLViewerJointAttachment::getAttachedObject(const LLUUID& object_id)
  575. {
  576. for (attachedobjs_vec_t::const_iterator iter = mAttachedObjects.begin(),
  577. end = mAttachedObjects.end();
  578. iter != end; ++iter)
  579. {
  580. LLViewerObject* attached_object = iter->get();
  581. if (attached_object->getAttachmentItemID() == object_id)
  582. {
  583. return attached_object;
  584. }
  585. }
  586. return NULL;
  587. }