PageRenderTime 53ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llviewerjointattachment.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 449 lines | 338 code | 42 blank | 69 comment | 69 complexity | b7ba1faacc865a974da5040b691c7dba MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llviewerjointattachment.cpp
  3. * @brief Implementation of LLViewerJointAttachment class
  4. *
  5. * $LicenseInfo:firstyear=2002&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 "llviewerjointattachment.h"
  28. #include "llagentconstants.h"
  29. #include "llviewercontrol.h"
  30. #include "lldrawable.h"
  31. #include "llgl.h"
  32. #include "llhudtext.h"
  33. #include "llrender.h"
  34. #include "llvoavatarself.h"
  35. #include "llvolume.h"
  36. #include "pipeline.h"
  37. #include "llspatialpartition.h"
  38. #include "llinventorymodel.h"
  39. #include "llviewerobjectlist.h"
  40. #include "llface.h"
  41. #include "llvoavatar.h"
  42. #include "llglheaders.h"
  43. extern LLPipeline gPipeline;
  44. //-----------------------------------------------------------------------------
  45. // LLViewerJointAttachment()
  46. //-----------------------------------------------------------------------------
  47. LLViewerJointAttachment::LLViewerJointAttachment() :
  48. mVisibleInFirst(FALSE),
  49. mGroup(0),
  50. mIsHUDAttachment(FALSE),
  51. mPieSlice(-1)
  52. {
  53. mValid = FALSE;
  54. mUpdateXform = FALSE;
  55. mAttachedObjects.clear();
  56. }
  57. //-----------------------------------------------------------------------------
  58. // ~LLViewerJointAttachment()
  59. //-----------------------------------------------------------------------------
  60. LLViewerJointAttachment::~LLViewerJointAttachment()
  61. {
  62. }
  63. //-----------------------------------------------------------------------------
  64. // isTransparent()
  65. //-----------------------------------------------------------------------------
  66. BOOL LLViewerJointAttachment::isTransparent()
  67. {
  68. return FALSE;
  69. }
  70. //-----------------------------------------------------------------------------
  71. // drawShape()
  72. //-----------------------------------------------------------------------------
  73. U32 LLViewerJointAttachment::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
  74. {
  75. if (LLVOAvatar::sShowAttachmentPoints)
  76. {
  77. LLGLDisable cull_face(GL_CULL_FACE);
  78. gGL.color4f(1.f, 1.f, 1.f, 1.f);
  79. gGL.begin(LLRender::QUADS);
  80. {
  81. gGL.vertex3f(-0.1f, 0.1f, 0.f);
  82. gGL.vertex3f(-0.1f, -0.1f, 0.f);
  83. gGL.vertex3f(0.1f, -0.1f, 0.f);
  84. gGL.vertex3f(0.1f, 0.1f, 0.f);
  85. }gGL.end();
  86. }
  87. return 0;
  88. }
  89. void LLViewerJointAttachment::setupDrawable(LLViewerObject *object)
  90. {
  91. if (!object->mDrawable)
  92. return;
  93. if (object->mDrawable->isActive())
  94. {
  95. object->mDrawable->makeStatic(FALSE);
  96. }
  97. object->mDrawable->mXform.setParent(getXform()); // LLViewerJointAttachment::lazyAttach
  98. object->mDrawable->makeActive();
  99. LLVector3 current_pos = object->getRenderPosition();
  100. LLQuaternion current_rot = object->getRenderRotation();
  101. LLQuaternion attachment_pt_inv_rot = ~(getWorldRotation());
  102. current_pos -= getWorldPosition();
  103. current_pos.rotVec(attachment_pt_inv_rot);
  104. current_rot = current_rot * attachment_pt_inv_rot;
  105. object->mDrawable->mXform.setPosition(current_pos);
  106. object->mDrawable->mXform.setRotation(current_rot);
  107. gPipeline.markMoved(object->mDrawable);
  108. gPipeline.markTextured(object->mDrawable); // face may need to change draw pool to/from POOL_HUD
  109. object->mDrawable->setState(LLDrawable::USE_BACKLIGHT);
  110. if(mIsHUDAttachment)
  111. {
  112. for (S32 face_num = 0; face_num < object->mDrawable->getNumFaces(); face_num++)
  113. {
  114. object->mDrawable->getFace(face_num)->setState(LLFace::HUD_RENDER);
  115. }
  116. }
  117. LLViewerObject::const_child_list_t& child_list = object->getChildren();
  118. for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
  119. iter != child_list.end(); ++iter)
  120. {
  121. LLViewerObject* childp = *iter;
  122. if (childp && childp->mDrawable.notNull())
  123. {
  124. childp->mDrawable->setState(LLDrawable::USE_BACKLIGHT);
  125. gPipeline.markTextured(childp->mDrawable); // face may need to change draw pool to/from POOL_HUD
  126. gPipeline.markMoved(childp->mDrawable);
  127. if(mIsHUDAttachment)
  128. {
  129. for (S32 face_num = 0; face_num < childp->mDrawable->getNumFaces(); face_num++)
  130. {
  131. childp->mDrawable->getFace(face_num)->setState(LLFace::HUD_RENDER);
  132. }
  133. }
  134. }
  135. }
  136. }
  137. //-----------------------------------------------------------------------------
  138. // addObject()
  139. //-----------------------------------------------------------------------------
  140. BOOL LLViewerJointAttachment::addObject(LLViewerObject* object)
  141. {
  142. object->extractAttachmentItemID();
  143. // Same object reattached
  144. if (isObjectAttached(object))
  145. {
  146. llinfos << "(same object re-attached)" << llendl;
  147. removeObject(object);
  148. // Pass through anyway to let setupDrawable()
  149. // re-connect object to the joint correctly
  150. }
  151. // Two instances of the same inventory item attached --
  152. // Request detach, and kill the object in the meantime.
  153. if (getAttachedObject(object->getAttachmentItemID()))
  154. {
  155. llinfos << "(same object re-attached)" << llendl;
  156. object->markDead();
  157. // If this happens to be attached to self, then detach.
  158. LLVOAvatarSelf::detachAttachmentIntoInventory(object->getAttachmentItemID());
  159. return FALSE;
  160. }
  161. mAttachedObjects.push_back(object);
  162. setupDrawable(object);
  163. if (mIsHUDAttachment)
  164. {
  165. if (object->mText.notNull())
  166. {
  167. object->mText->setOnHUDAttachment(TRUE);
  168. }
  169. LLViewerObject::const_child_list_t& child_list = object->getChildren();
  170. for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
  171. iter != child_list.end(); ++iter)
  172. {
  173. LLViewerObject* childp = *iter;
  174. if (childp && childp->mText.notNull())
  175. {
  176. childp->mText->setOnHUDAttachment(TRUE);
  177. }
  178. }
  179. }
  180. calcLOD();
  181. mUpdateXform = TRUE;
  182. return TRUE;
  183. }
  184. //-----------------------------------------------------------------------------
  185. // removeObject()
  186. //-----------------------------------------------------------------------------
  187. void LLViewerJointAttachment::removeObject(LLViewerObject *object)
  188. {
  189. attachedobjs_vec_t::iterator iter;
  190. for (iter = mAttachedObjects.begin();
  191. iter != mAttachedObjects.end();
  192. ++iter)
  193. {
  194. LLViewerObject *attached_object = (*iter);
  195. if (attached_object == object)
  196. {
  197. break;
  198. }
  199. }
  200. if (iter == mAttachedObjects.end())
  201. {
  202. llwarns << "Could not find object to detach" << llendl;
  203. return;
  204. }
  205. // force object visibile
  206. setAttachmentVisibility(TRUE);
  207. mAttachedObjects.erase(iter);
  208. if (object->mDrawable.notNull())
  209. {
  210. //if object is active, make it static
  211. if(object->mDrawable->isActive())
  212. {
  213. object->mDrawable->makeStatic(FALSE);
  214. }
  215. LLVector3 cur_position = object->getRenderPosition();
  216. LLQuaternion cur_rotation = object->getRenderRotation();
  217. object->mDrawable->mXform.setPosition(cur_position);
  218. object->mDrawable->mXform.setRotation(cur_rotation);
  219. gPipeline.markMoved(object->mDrawable, TRUE);
  220. gPipeline.markTextured(object->mDrawable); // face may need to change draw pool to/from POOL_HUD
  221. object->mDrawable->clearState(LLDrawable::USE_BACKLIGHT);
  222. if (mIsHUDAttachment)
  223. {
  224. for (S32 face_num = 0; face_num < object->mDrawable->getNumFaces(); face_num++)
  225. {
  226. object->mDrawable->getFace(face_num)->clearState(LLFace::HUD_RENDER);
  227. }
  228. }
  229. }
  230. LLViewerObject::const_child_list_t& child_list = object->getChildren();
  231. for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
  232. iter != child_list.end(); ++iter)
  233. {
  234. LLViewerObject* childp = *iter;
  235. if (childp && childp->mDrawable.notNull())
  236. {
  237. childp->mDrawable->clearState(LLDrawable::USE_BACKLIGHT);
  238. gPipeline.markTextured(childp->mDrawable); // face may need to change draw pool to/from POOL_HUD
  239. if (mIsHUDAttachment)
  240. {
  241. for (S32 face_num = 0; face_num < childp->mDrawable->getNumFaces(); face_num++)
  242. {
  243. childp->mDrawable->getFace(face_num)->clearState(LLFace::HUD_RENDER);
  244. }
  245. }
  246. }
  247. }
  248. if (mIsHUDAttachment)
  249. {
  250. if (object->mText.notNull())
  251. {
  252. object->mText->setOnHUDAttachment(FALSE);
  253. }
  254. LLViewerObject::const_child_list_t& child_list = object->getChildren();
  255. for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
  256. iter != child_list.end(); ++iter)
  257. {
  258. LLViewerObject* childp = *iter;
  259. if (childp->mText.notNull())
  260. {
  261. childp->mText->setOnHUDAttachment(FALSE);
  262. }
  263. }
  264. }
  265. if (mAttachedObjects.size() == 0)
  266. {
  267. mUpdateXform = FALSE;
  268. }
  269. object->setAttachmentItemID(LLUUID::null);
  270. }
  271. //-----------------------------------------------------------------------------
  272. // setAttachmentVisibility()
  273. //-----------------------------------------------------------------------------
  274. void LLViewerJointAttachment::setAttachmentVisibility(BOOL visible)
  275. {
  276. for (attachedobjs_vec_t::const_iterator iter = mAttachedObjects.begin();
  277. iter != mAttachedObjects.end();
  278. ++iter)
  279. {
  280. LLViewerObject *attached_obj = (*iter);
  281. if (!attached_obj || attached_obj->mDrawable.isNull() ||
  282. !(attached_obj->mDrawable->getSpatialBridge()))
  283. continue;
  284. if (visible)
  285. {
  286. // Hack to make attachments not visible by disabling their type mask!
  287. // This will break if you can ever attach non-volumes! - djs 02/14/03
  288. attached_obj->mDrawable->getSpatialBridge()->mDrawableType =
  289. attached_obj->isHUDAttachment() ? LLPipeline::RENDER_TYPE_HUD : LLPipeline::RENDER_TYPE_VOLUME;
  290. }
  291. else
  292. {
  293. attached_obj->mDrawable->getSpatialBridge()->mDrawableType = 0;
  294. }
  295. }
  296. }
  297. //-----------------------------------------------------------------------------
  298. // setOriginalPosition()
  299. //-----------------------------------------------------------------------------
  300. void LLViewerJointAttachment::setOriginalPosition(LLVector3& position)
  301. {
  302. mOriginalPos = position;
  303. setPosition(position);
  304. }
  305. //-----------------------------------------------------------------------------
  306. // clampObjectPosition()
  307. //-----------------------------------------------------------------------------
  308. void LLViewerJointAttachment::clampObjectPosition()
  309. {
  310. for (attachedobjs_vec_t::const_iterator iter = mAttachedObjects.begin();
  311. iter != mAttachedObjects.end();
  312. ++iter)
  313. {
  314. if (LLViewerObject *attached_object = (*iter))
  315. {
  316. // *NOTE: object can drift when hitting maximum radius
  317. LLVector3 attachmentPos = attached_object->getPosition();
  318. F32 dist = attachmentPos.normVec();
  319. dist = llmin(dist, MAX_ATTACHMENT_DIST);
  320. attachmentPos *= dist;
  321. attached_object->setPosition(attachmentPos);
  322. }
  323. }
  324. }
  325. //-----------------------------------------------------------------------------
  326. // calcLOD()
  327. //-----------------------------------------------------------------------------
  328. void LLViewerJointAttachment::calcLOD()
  329. {
  330. F32 maxarea = 0;
  331. for (attachedobjs_vec_t::const_iterator iter = mAttachedObjects.begin();
  332. iter != mAttachedObjects.end();
  333. ++iter)
  334. {
  335. if (LLViewerObject *attached_object = (*iter))
  336. {
  337. maxarea = llmax(maxarea,attached_object->getMaxScale() * attached_object->getMidScale());
  338. LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
  339. for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
  340. iter != child_list.end(); ++iter)
  341. {
  342. LLViewerObject* childp = *iter;
  343. F32 area = childp->getMaxScale() * childp->getMidScale();
  344. maxarea = llmax(maxarea, area);
  345. }
  346. }
  347. }
  348. maxarea = llclamp(maxarea, .01f*.01f, 1.f);
  349. F32 avatar_area = (4.f * 4.f); // pixels for an avatar sized attachment
  350. F32 min_pixel_area = avatar_area / maxarea;
  351. setLOD(min_pixel_area);
  352. }
  353. //-----------------------------------------------------------------------------
  354. // updateLOD()
  355. //-----------------------------------------------------------------------------
  356. BOOL LLViewerJointAttachment::updateLOD(F32 pixel_area, BOOL activate)
  357. {
  358. BOOL res = FALSE;
  359. if (!mValid)
  360. {
  361. setValid(TRUE, TRUE);
  362. res = TRUE;
  363. }
  364. return res;
  365. }
  366. BOOL LLViewerJointAttachment::isObjectAttached(const LLViewerObject *viewer_object) const
  367. {
  368. for (attachedobjs_vec_t::const_iterator iter = mAttachedObjects.begin();
  369. iter != mAttachedObjects.end();
  370. ++iter)
  371. {
  372. const LLViewerObject* attached_object = (*iter);
  373. if (attached_object == viewer_object)
  374. {
  375. return TRUE;
  376. }
  377. }
  378. return FALSE;
  379. }
  380. const LLViewerObject *LLViewerJointAttachment::getAttachedObject(const LLUUID &object_id) const
  381. {
  382. for (attachedobjs_vec_t::const_iterator iter = mAttachedObjects.begin();
  383. iter != mAttachedObjects.end();
  384. ++iter)
  385. {
  386. const LLViewerObject* attached_object = (*iter);
  387. if (attached_object->getAttachmentItemID() == object_id)
  388. {
  389. return attached_object;
  390. }
  391. }
  392. return NULL;
  393. }
  394. LLViewerObject *LLViewerJointAttachment::getAttachedObject(const LLUUID &object_id)
  395. {
  396. for (attachedobjs_vec_t::iterator iter = mAttachedObjects.begin();
  397. iter != mAttachedObjects.end();
  398. ++iter)
  399. {
  400. LLViewerObject* attached_object = (*iter);
  401. if (attached_object->getAttachmentItemID() == object_id)
  402. {
  403. return attached_object;
  404. }
  405. }
  406. return NULL;
  407. }