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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llviewerjointattachment.cpp
  3.  * @brief Implementation of LLViewerJointAttachment class
  4.  *
  5.  * $LicenseInfo:firstyear=2002&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2002-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llviewerjointattachment.h"
  34. #include "llagentconstants.h"
  35. #include "llviewercontrol.h"
  36. #include "lldrawable.h"
  37. #include "llgl.h"
  38. #include "llrender.h"
  39. #include "llvoavatar.h"
  40. #include "llvolume.h"
  41. #include "pipeline.h"
  42. #include "llspatialpartition.h"
  43. #include "llinventorymodel.h"
  44. #include "llviewerobjectlist.h"
  45. #include "llface.h"
  46. #include "llvoavatar.h"
  47. #include "llglheaders.h"
  48. extern LLPipeline gPipeline;
  49. //-----------------------------------------------------------------------------
  50. // LLViewerJointAttachment()
  51. //-----------------------------------------------------------------------------
  52. LLViewerJointAttachment::LLViewerJointAttachment() :
  53. mVisibleInFirst(FALSE),
  54. mGroup(0),
  55. mIsHUDAttachment(FALSE),
  56. mPieSlice(-1)
  57. {
  58. mValid = FALSE;
  59. mUpdateXform = FALSE;
  60. mAttachedObjects.clear();
  61. }
  62. //-----------------------------------------------------------------------------
  63. // ~LLViewerJointAttachment()
  64. //-----------------------------------------------------------------------------
  65. LLViewerJointAttachment::~LLViewerJointAttachment()
  66. {
  67. }
  68. //-----------------------------------------------------------------------------
  69. // isTransparent()
  70. //-----------------------------------------------------------------------------
  71. BOOL LLViewerJointAttachment::isTransparent()
  72. {
  73. return FALSE;
  74. }
  75. //-----------------------------------------------------------------------------
  76. // drawShape()
  77. //-----------------------------------------------------------------------------
  78. U32 LLViewerJointAttachment::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
  79. {
  80. if (LLVOAvatar::sShowAttachmentPoints)
  81. {
  82. LLGLDisable cull_face(GL_CULL_FACE);
  83. gGL.color4f(1.f, 1.f, 1.f, 1.f);
  84. gGL.begin(LLRender::QUADS);
  85. {
  86. gGL.vertex3f(-0.1f, 0.1f, 0.f);
  87. gGL.vertex3f(-0.1f, -0.1f, 0.f);
  88. gGL.vertex3f(0.1f, -0.1f, 0.f);
  89. gGL.vertex3f(0.1f, 0.1f, 0.f);
  90. }gGL.end();
  91. }
  92. return 0;
  93. }
  94. void LLViewerJointAttachment::setupDrawable(LLViewerObject *object)
  95. {
  96. if (!object->mDrawable)
  97. return;
  98. if (object->mDrawable->isActive())
  99. {
  100. object->mDrawable->makeStatic(FALSE);
  101. }
  102. object->mDrawable->mXform.setParent(getXform()); // LLViewerJointAttachment::lazyAttach
  103. object->mDrawable->makeActive();
  104. LLVector3 current_pos = object->getRenderPosition();
  105. LLQuaternion current_rot = object->getRenderRotation();
  106. LLQuaternion attachment_pt_inv_rot = ~(getWorldRotation());
  107. current_pos -= getWorldPosition();
  108. current_pos.rotVec(attachment_pt_inv_rot);
  109. current_rot = current_rot * attachment_pt_inv_rot;
  110. object->mDrawable->mXform.setPosition(current_pos);
  111. object->mDrawable->mXform.setRotation(current_rot);
  112. gPipeline.markMoved(object->mDrawable);
  113. gPipeline.markTextured(object->mDrawable); // face may need to change draw pool to/from POOL_HUD
  114. object->mDrawable->setState(LLDrawable::USE_BACKLIGHT);
  115. if(mIsHUDAttachment)
  116. {
  117. for (S32 face_num = 0; face_num < object->mDrawable->getNumFaces(); face_num++)
  118. {
  119. object->mDrawable->getFace(face_num)->setState(LLFace::HUD_RENDER);
  120. }
  121. }
  122. LLViewerObject::const_child_list_t& child_list = object->getChildren();
  123. for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
  124.  iter != child_list.end(); ++iter)
  125. {
  126. LLViewerObject* childp = *iter;
  127. if (childp && childp->mDrawable.notNull())
  128. {
  129. childp->mDrawable->setState(LLDrawable::USE_BACKLIGHT);
  130. gPipeline.markTextured(childp->mDrawable); // face may need to change draw pool to/from POOL_HUD
  131. gPipeline.markMoved(childp->mDrawable);
  132. if(mIsHUDAttachment)
  133. {
  134. for (S32 face_num = 0; face_num < childp->mDrawable->getNumFaces(); face_num++)
  135. {
  136. childp->mDrawable->getFace(face_num)->setState(LLFace::HUD_RENDER);
  137. }
  138. }
  139. }
  140. }
  141. }
  142. //-----------------------------------------------------------------------------
  143. // addObject()
  144. //-----------------------------------------------------------------------------
  145. BOOL LLViewerJointAttachment::addObject(LLViewerObject* object)
  146. {
  147. if (isObjectAttached(object))
  148. {
  149. llinfos << "(same object re-attached)" << llendl;
  150. removeObject(object);
  151. // Pass through anyway to let setupDrawable()
  152. // re-connect object to the joint correctly
  153. }
  154. // Find the inventory item ID of the attached object
  155. LLNameValue* item_id_nv = object->getNVPair("AttachItemID");
  156. if( item_id_nv )
  157. {
  158. const char* s = item_id_nv->getString();
  159. if( s )
  160. {
  161. LLUUID item_id;
  162. item_id.set(s);
  163. object->setItemID(item_id);
  164. lldebugs << "getNVPair( AttachItemID ) = " << item_id << llendl;
  165. }
  166. }
  167. mAttachedObjects.push_back(object);
  168. setupDrawable(object);
  169. if (mIsHUDAttachment)
  170. {
  171. if (object->mText.notNull())
  172. {
  173. object->mText->setOnHUDAttachment(TRUE);
  174. }
  175. LLViewerObject::const_child_list_t& child_list = object->getChildren();
  176. for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
  177.  iter != child_list.end(); ++iter)
  178. {
  179. LLViewerObject* childp = *iter;
  180. if (childp && childp->mText.notNull())
  181. {
  182. childp->mText->setOnHUDAttachment(TRUE);
  183. }
  184. }
  185. }
  186. calcLOD();
  187. mUpdateXform = TRUE;
  188. return TRUE;
  189. }
  190. //-----------------------------------------------------------------------------
  191. // removeObject()
  192. //-----------------------------------------------------------------------------
  193. void LLViewerJointAttachment::removeObject(LLViewerObject *object)
  194. {
  195. attachedobjs_vec_t::iterator iter;
  196. for (iter = mAttachedObjects.begin();
  197.  iter != mAttachedObjects.end();
  198.  ++iter)
  199. {
  200. LLViewerObject *attached_object = (*iter);
  201. if (attached_object == object)
  202. {
  203. break;
  204. }
  205. }
  206. if (iter == mAttachedObjects.end())
  207. {
  208. llwarns << "Could not find object to detach" << llendl;
  209. return;
  210. }
  211. // force object visibile
  212. setAttachmentVisibility(TRUE);
  213. mAttachedObjects.erase(iter);
  214. if (object->mDrawable.notNull())
  215. {
  216. //if object is active, make it static
  217. if(object->mDrawable->isActive())
  218. {
  219. object->mDrawable->makeStatic(FALSE);
  220. }
  221. LLVector3 cur_position = object->getRenderPosition();
  222. LLQuaternion cur_rotation = object->getRenderRotation();
  223. object->mDrawable->mXform.setPosition(cur_position);
  224. object->mDrawable->mXform.setRotation(cur_rotation);
  225. gPipeline.markMoved(object->mDrawable, TRUE);
  226. gPipeline.markTextured(object->mDrawable); // face may need to change draw pool to/from POOL_HUD
  227. object->mDrawable->clearState(LLDrawable::USE_BACKLIGHT);
  228. if (mIsHUDAttachment)
  229. {
  230. for (S32 face_num = 0; face_num < object->mDrawable->getNumFaces(); face_num++)
  231. {
  232. object->mDrawable->getFace(face_num)->clearState(LLFace::HUD_RENDER);
  233. }
  234. }
  235. }
  236. LLViewerObject::const_child_list_t& child_list = object->getChildren();
  237. for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
  238.  iter != child_list.end(); ++iter)
  239. {
  240. LLViewerObject* childp = *iter;
  241. if (childp && childp->mDrawable.notNull())
  242. {
  243. childp->mDrawable->clearState(LLDrawable::USE_BACKLIGHT);
  244. gPipeline.markTextured(childp->mDrawable); // face may need to change draw pool to/from POOL_HUD
  245. if (mIsHUDAttachment)
  246. {
  247. for (S32 face_num = 0; face_num < childp->mDrawable->getNumFaces(); face_num++)
  248. {
  249. childp->mDrawable->getFace(face_num)->clearState(LLFace::HUD_RENDER);
  250. }
  251. }
  252. }
  253. if (mIsHUDAttachment)
  254. {
  255. if (object->mText.notNull())
  256. {
  257. object->mText->setOnHUDAttachment(FALSE);
  258. }
  259. LLViewerObject::const_child_list_t& child_list = object->getChildren();
  260. for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
  261.  iter != child_list.end(); ++iter)
  262. {
  263. LLViewerObject* childp = *iter;
  264. if (childp->mText.notNull())
  265. {
  266. childp->mText->setOnHUDAttachment(FALSE);
  267. }
  268. }
  269. }
  270. if (mAttachedObjects.size() == 0)
  271. {
  272. mUpdateXform = FALSE;
  273. }
  274. object->setItemID(LLUUID::null);
  275. }
  276. //-----------------------------------------------------------------------------
  277. // setAttachmentVisibility()
  278. //-----------------------------------------------------------------------------
  279. void LLViewerJointAttachment::setAttachmentVisibility(BOOL visible)
  280. {
  281. for (attachedobjs_vec_t::const_iterator iter = mAttachedObjects.begin();
  282.  iter != mAttachedObjects.end();
  283.  ++iter)
  284. {
  285. LLViewerObject *attached_obj = (*iter);
  286. if (!attached_obj || attached_obj->mDrawable.isNull() || 
  287. !(attached_obj->mDrawable->getSpatialBridge()))
  288. continue;
  289. if (visible)
  290. {
  291. // Hack to make attachments not visible by disabling their type mask!
  292. // This will break if you can ever attach non-volumes! - djs 02/14/03
  293. attached_obj->mDrawable->getSpatialBridge()->mDrawableType = 
  294. attached_obj->isHUDAttachment() ? LLPipeline::RENDER_TYPE_HUD : LLPipeline::RENDER_TYPE_VOLUME;
  295. }
  296. else
  297. {
  298. attached_obj->mDrawable->getSpatialBridge()->mDrawableType = 0;
  299. }
  300. }
  301. }
  302. //-----------------------------------------------------------------------------
  303. // setOriginalPosition()
  304. //-----------------------------------------------------------------------------
  305. void LLViewerJointAttachment::setOriginalPosition(LLVector3& position)
  306. {
  307. mOriginalPos = position;
  308. setPosition(position);
  309. }
  310. //-----------------------------------------------------------------------------
  311. // clampObjectPosition()
  312. //-----------------------------------------------------------------------------
  313. void LLViewerJointAttachment::clampObjectPosition()
  314. {
  315. for (attachedobjs_vec_t::const_iterator iter = mAttachedObjects.begin();
  316.  iter != mAttachedObjects.end();
  317.  ++iter)
  318. {
  319. if (LLViewerObject *attached_object = (*iter))
  320. {
  321. // *NOTE: object can drift when hitting maximum radius
  322. LLVector3 attachmentPos = attached_object->getPosition();
  323. F32 dist = attachmentPos.normVec();
  324. dist = llmin(dist, MAX_ATTACHMENT_DIST);
  325. attachmentPos *= dist;
  326. attached_object->setPosition(attachmentPos);
  327. }
  328. }
  329. }
  330. //-----------------------------------------------------------------------------
  331. // calcLOD()
  332. //-----------------------------------------------------------------------------
  333. void LLViewerJointAttachment::calcLOD()
  334. {
  335. F32 maxarea = 0;
  336. for (attachedobjs_vec_t::const_iterator iter = mAttachedObjects.begin();
  337.  iter != mAttachedObjects.end();
  338.  ++iter)
  339. {
  340. if (LLViewerObject *attached_object = (*iter))
  341. {
  342. maxarea = llmax(maxarea,attached_object->getMaxScale() * attached_object->getMidScale());
  343. LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
  344. for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
  345.  iter != child_list.end(); ++iter)
  346. {
  347. LLViewerObject* childp = *iter;
  348. F32 area = childp->getMaxScale() * childp->getMidScale();
  349. maxarea = llmax(maxarea, area);
  350. }
  351. }
  352. }
  353. maxarea = llclamp(maxarea, .01f*.01f, 1.f);
  354. F32 avatar_area = (4.f * 4.f); // pixels for an avatar sized attachment
  355. F32 min_pixel_area = avatar_area / maxarea;
  356. setLOD(min_pixel_area);
  357. }
  358. //-----------------------------------------------------------------------------
  359. // updateLOD()
  360. //-----------------------------------------------------------------------------
  361. BOOL LLViewerJointAttachment::updateLOD(F32 pixel_area, BOOL activate)
  362. {
  363. BOOL res = FALSE;
  364. if (!mValid)
  365. {
  366. setValid(TRUE, TRUE);
  367. res = TRUE;
  368. }
  369. return res;
  370. }
  371. BOOL LLViewerJointAttachment::isObjectAttached(const LLViewerObject *viewer_object) const
  372. {
  373. for (attachedobjs_vec_t::const_iterator iter = mAttachedObjects.begin();
  374.  iter != mAttachedObjects.end();
  375.  ++iter)
  376. {
  377. const LLViewerObject* attached_object = (*iter);
  378. if (attached_object == viewer_object)
  379. {
  380. return TRUE;
  381. }
  382. }
  383. return FALSE;
  384. }
  385. const LLViewerObject *LLViewerJointAttachment::getAttachedObject(const LLUUID &object_id) const
  386. {
  387. for (attachedobjs_vec_t::const_iterator iter = mAttachedObjects.begin();
  388.  iter != mAttachedObjects.end();
  389.  ++iter)
  390. {
  391. const LLViewerObject* attached_object = (*iter);
  392. if (attached_object->getItemID() == object_id)
  393. {
  394. return attached_object;
  395. }
  396. }
  397. return NULL;
  398. }
  399. LLViewerObject *LLViewerJointAttachment::getAttachedObject(const LLUUID &object_id)
  400. {
  401. for (attachedobjs_vec_t::iterator iter = mAttachedObjects.begin();
  402.  iter != mAttachedObjects.end();
  403.  ++iter)
  404. {
  405. LLViewerObject* attached_object = (*iter);
  406. if (attached_object->getItemID() == object_id)
  407. {
  408. return attached_object;
  409. }
  410. }
  411. return NULL;
  412. }