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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llvovolume.cpp
  3.  * @brief LLVOVolume class implementation
  4.  *
  5.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2001-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. // A "volume" is a box, cylinder, sphere, or other primitive shape.
  33. #include "llviewerprecompiledheaders.h"
  34. #include "llvovolume.h"
  35. #include "llviewercontrol.h"
  36. #include "lldir.h"
  37. #include "llflexibleobject.h"
  38. #include "llmaterialtable.h"
  39. #include "llprimitive.h"
  40. #include "llvolume.h"
  41. #include "llvolumemgr.h"
  42. #include "llvolumemessage.h"
  43. #include "material_codes.h"
  44. #include "message.h"
  45. #include "llpluginclassmedia.h" // for code in the mediaEvent handler
  46. #include "object_flags.h"
  47. #include "llagentconstants.h"
  48. #include "lldrawable.h"
  49. #include "lldrawpoolbump.h"
  50. #include "llface.h"
  51. #include "llspatialpartition.h"
  52. #include "llhudmanager.h"
  53. #include "llflexibleobject.h"
  54. #include "llsky.h"
  55. #include "lltexturefetch.h"
  56. #include "llviewercamera.h"
  57. #include "llviewertexturelist.h"
  58. #include "llviewerregion.h"
  59. #include "llviewertextureanim.h"
  60. #include "llworld.h"
  61. #include "llselectmgr.h"
  62. #include "pipeline.h"
  63. #include "llsdutil.h"
  64. #include "llmediaentry.h"
  65. #include "llmediadataclient.h"
  66. #include "llagent.h"
  67. #include "llviewermediafocus.h"
  68. const S32 MIN_QUIET_FRAMES_COALESCE = 30;
  69. const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
  70. const F32 FORCE_CULL_AREA = 8.f;
  71. const F32 MAX_LOD_DISTANCE = 24.f;
  72. BOOL gAnimateTextures = TRUE;
  73. //extern BOOL gHideSelectedObjects;
  74. F32 LLVOVolume::sLODFactor = 1.f;
  75. F32 LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop 
  76. F32 LLVOVolume::sDistanceFactor = 1.0f;
  77. S32 LLVOVolume::sNumLODChanges = 0;
  78. LLPointer<LLObjectMediaDataClient> LLVOVolume::sObjectMediaClient = NULL;
  79. LLPointer<LLObjectMediaNavigateClient> LLVOVolume::sObjectMediaNavigateClient = NULL;
  80. static LLFastTimer::DeclareTimer FTM_GEN_TRIANGLES("Generate Triangles");
  81. static LLFastTimer::DeclareTimer FTM_GEN_VOLUME("Generate Volumes");
  82. // Implementation class of LLMediaDataClientObject.  See llmediadataclient.h
  83. class LLMediaDataClientObjectImpl : public LLMediaDataClientObject
  84. {
  85. public:
  86. LLMediaDataClientObjectImpl(LLVOVolume *obj, bool isNew) : mObject(obj), mNew(isNew) {}
  87. LLMediaDataClientObjectImpl() { mObject = NULL; }
  88. virtual U8 getMediaDataCount() const 
  89. { return mObject->getNumTEs(); }
  90. virtual LLSD getMediaDataLLSD(U8 index) const 
  91. {
  92. LLSD result;
  93. LLTextureEntry *te = mObject->getTE(index); 
  94. if (NULL != te)
  95. {
  96. llassert((te->getMediaData() != NULL) == te->hasMedia());
  97. if (te->getMediaData() != NULL)
  98. {
  99. result = te->getMediaData()->asLLSD();
  100. // XXX HACK: workaround bug in asLLSD() where whitelist is not set properly
  101. // See DEV-41949
  102. if (!result.has(LLMediaEntry::WHITELIST_KEY))
  103. {
  104. result[LLMediaEntry::WHITELIST_KEY] = LLSD::emptyArray();
  105. }
  106. }
  107. }
  108. return result;
  109. }
  110. virtual LLUUID getID() const
  111. { return mObject->getID(); }
  112. virtual void mediaNavigateBounceBack(U8 index)
  113. { mObject->mediaNavigateBounceBack(index); }
  114. virtual bool hasMedia() const
  115. { return mObject->hasMedia(); }
  116. virtual void updateObjectMediaData(LLSD const &data, const std::string &version_string) 
  117. { mObject->updateObjectMediaData(data, version_string); }
  118. virtual F64 getMediaInterest() const 
  119. F64 interest = mObject->getTotalMediaInterest();
  120. if (interest < (F64)0.0)
  121. {
  122. // media interest not valid yet, try pixel area
  123. interest = mObject->getPixelArea();
  124. // HACK: force recalculation of pixel area if interest is the "magic default" of 1024.
  125. if (interest == 1024.f)
  126. {
  127. const_cast<LLVOVolume*>(static_cast<LLVOVolume*>(mObject))->setPixelAreaAndAngle(gAgent);
  128. interest = mObject->getPixelArea();
  129. }
  130. }
  131. return interest; 
  132. }
  133. virtual bool isInterestingEnough() const
  134. {
  135. return LLViewerMedia::isInterestingEnough(mObject, getMediaInterest());
  136. }
  137. virtual std::string getCapabilityUrl(const std::string &name) const
  138. { return mObject->getRegion()->getCapability(name); }
  139. virtual bool isDead() const
  140. { return mObject->isDead(); }
  141. virtual U32 getMediaVersion() const
  142. { return LLTextureEntry::getVersionFromMediaVersionString(mObject->getMediaURL()); }
  143. virtual bool isNew() const
  144. { return mNew; }
  145. private:
  146. LLPointer<LLVOVolume> mObject;
  147. bool mNew;
  148. };
  149. LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
  150. : LLViewerObject(id, pcode, regionp),
  151.   mVolumeImpl(NULL)
  152. {
  153. mTexAnimMode = 0;
  154. mRelativeXform.setIdentity();
  155. mRelativeXformInvTrans.setIdentity();
  156. mFaceMappingChanged = FALSE;
  157. mLOD = MIN_LOD;
  158. mTextureAnimp = NULL;
  159. mVolumeChanged = FALSE;
  160. mVObjRadius = LLVector3(1,1,0.5f).length();
  161. mNumFaces = 0;
  162. mLODChanged = FALSE;
  163. mSculptChanged = FALSE;
  164. mSpotLightPriority = 0.f;
  165. mMediaImplList.resize(getNumTEs());
  166. mLastFetchedMediaVersion = -1;
  167. mIndexInTex = 0;
  168. }
  169. LLVOVolume::~LLVOVolume()
  170. {
  171. delete mTextureAnimp;
  172. mTextureAnimp = NULL;
  173. delete mVolumeImpl;
  174. mVolumeImpl = NULL;
  175. if(!mMediaImplList.empty())
  176. {
  177. for(U32 i = 0 ; i < mMediaImplList.size() ; i++)
  178. {
  179. if(mMediaImplList[i].notNull())
  180. {
  181. mMediaImplList[i]->removeObject(this) ;
  182. }
  183. }
  184. }
  185. }
  186. void LLVOVolume::markDead()
  187. {
  188. if (!mDead)
  189. {
  190. LLMediaDataClientObject::ptr_t obj = new LLMediaDataClientObjectImpl(const_cast<LLVOVolume*>(this), false);
  191. if (sObjectMediaClient) sObjectMediaClient->removeFromQueue(obj);
  192. if (sObjectMediaNavigateClient) sObjectMediaNavigateClient->removeFromQueue(obj);
  193. // Detach all media impls from this object
  194. for(U32 i = 0 ; i < mMediaImplList.size() ; i++)
  195. {
  196. removeMediaImpl(i);
  197. }
  198. if (mSculptTexture.notNull())
  199. {
  200. mSculptTexture->removeVolume(this);
  201. }
  202. }
  203. LLViewerObject::markDead();
  204. }
  205. // static
  206. void LLVOVolume::initClass()
  207. {
  208. // gSavedSettings better be around
  209. if (gSavedSettings.getBOOL("PrimMediaMasterEnabled"))
  210. {
  211. const F32 queue_timer_delay = gSavedSettings.getF32("PrimMediaRequestQueueDelay");
  212. const F32 retry_timer_delay = gSavedSettings.getF32("PrimMediaRetryTimerDelay");
  213. const U32 max_retries = gSavedSettings.getU32("PrimMediaMaxRetries");
  214. const U32 max_sorted_queue_size = gSavedSettings.getU32("PrimMediaMaxSortedQueueSize");
  215. const U32 max_round_robin_queue_size = gSavedSettings.getU32("PrimMediaMaxRoundRobinQueueSize");
  216. sObjectMediaClient = new LLObjectMediaDataClient(queue_timer_delay, retry_timer_delay, max_retries, 
  217.  max_sorted_queue_size, max_round_robin_queue_size);
  218. sObjectMediaNavigateClient = new LLObjectMediaNavigateClient(queue_timer_delay, retry_timer_delay, 
  219.  max_retries, max_sorted_queue_size, max_round_robin_queue_size);
  220. }
  221. }
  222. // static
  223. void LLVOVolume::cleanupClass()
  224. {
  225.     sObjectMediaClient = NULL;
  226.     sObjectMediaNavigateClient = NULL;
  227. }
  228. U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
  229.   void **user_data,
  230.   U32 block_num, EObjectUpdateType update_type,
  231.   LLDataPacker *dp)
  232. {
  233. LLColor4U color;
  234. const S32 teDirtyBits = (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR|TEM_CHANGE_MEDIA);
  235. // Do base class updates...
  236. U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp);
  237. LLUUID sculpt_id;
  238. U8 sculpt_type = 0;
  239. if (isSculpted())
  240. {
  241. LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
  242. sculpt_id = sculpt_params->getSculptTexture();
  243. sculpt_type = sculpt_params->getSculptType();
  244. }
  245. if (!dp)
  246. {
  247. if (update_type == OUT_FULL)
  248. {
  249. ////////////////////////////////
  250. //
  251. // Unpack texture animation data
  252. //
  253. //
  254. if (mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_TextureAnim))
  255. {
  256. if (!mTextureAnimp)
  257. {
  258. mTextureAnimp = new LLViewerTextureAnim();
  259. }
  260. else
  261. {
  262. if (!(mTextureAnimp->mMode & LLTextureAnim::SMOOTH))
  263. {
  264. mTextureAnimp->reset();
  265. }
  266. }
  267. mTexAnimMode = 0;
  268. mTextureAnimp->unpackTAMessage(mesgsys, block_num);
  269. }
  270. else
  271. {
  272. if (mTextureAnimp)
  273. {
  274. delete mTextureAnimp;
  275. mTextureAnimp = NULL;
  276. gPipeline.markTextured(mDrawable);
  277. mFaceMappingChanged = TRUE;
  278. mTexAnimMode = 0;
  279. }
  280. }
  281. // Unpack volume data
  282. LLVolumeParams volume_params;
  283. LLVolumeMessage::unpackVolumeParams(&volume_params, mesgsys, _PREHASH_ObjectData, block_num);
  284. volume_params.setSculptID(sculpt_id, sculpt_type);
  285. if (setVolume(volume_params, 0))
  286. {
  287. markForUpdate(TRUE);
  288. }
  289. }
  290. // Sigh, this needs to be done AFTER the volume is set as well, otherwise bad stuff happens...
  291. ////////////////////////////
  292. //
  293. // Unpack texture entry data
  294. //
  295. S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num);
  296. if (result & teDirtyBits)
  297. {
  298. updateTEData();
  299. }
  300. if (result & TEM_CHANGE_MEDIA)
  301. {
  302. retval |= MEDIA_FLAGS_CHANGED;
  303. }
  304. }
  305. else
  306. {
  307. // CORY TO DO: Figure out how to get the value here
  308. if (update_type != OUT_TERSE_IMPROVED)
  309. {
  310. LLVolumeParams volume_params;
  311. BOOL res = LLVolumeMessage::unpackVolumeParams(&volume_params, *dp);
  312. if (!res)
  313. {
  314. llwarns << "Bogus volume parameters in object " << getID() << llendl;
  315. llwarns << getRegion()->getOriginGlobal() << llendl;
  316. }
  317. volume_params.setSculptID(sculpt_id, sculpt_type);
  318. if (setVolume(volume_params, 0))
  319. {
  320. markForUpdate(TRUE);
  321. }
  322. S32 res2 = unpackTEMessage(*dp);
  323. if (TEM_INVALID == res2)
  324. {
  325. // Well, crap, there's something bogus in the data that we're unpacking.
  326. dp->dumpBufferToLog();
  327. llwarns << "Flushing cache files" << llendl;
  328. std::string mask;
  329. mask = gDirUtilp->getDirDelimiter() + "*.slc";
  330. gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), mask);
  331. //  llerrs << "Bogus TE data in " << getID() << ", crashing!" << llendl;
  332. llwarns << "Bogus TE data in " << getID() << llendl;
  333. }
  334. else 
  335. {
  336. if (res2 & teDirtyBits) 
  337. {
  338. updateTEData();
  339. }
  340. if (res2 & TEM_CHANGE_MEDIA)
  341. {
  342. retval |= MEDIA_FLAGS_CHANGED;
  343. }
  344. }
  345. U32 value = dp->getPassFlags();
  346. if (value & 0x40)
  347. {
  348. if (!mTextureAnimp)
  349. {
  350. mTextureAnimp = new LLViewerTextureAnim();
  351. }
  352. else
  353. {
  354. if (!(mTextureAnimp->mMode & LLTextureAnim::SMOOTH))
  355. {
  356. mTextureAnimp->reset();
  357. }
  358. }
  359. mTexAnimMode = 0;
  360. mTextureAnimp->unpackTAMessage(*dp);
  361. }
  362. else if (mTextureAnimp)
  363. {
  364. delete mTextureAnimp;
  365. mTextureAnimp = NULL;
  366. gPipeline.markTextured(mDrawable);
  367. mFaceMappingChanged = TRUE;
  368. mTexAnimMode = 0;
  369. }
  370. }
  371. else
  372. {
  373. S32 texture_length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_TextureEntry);
  374. if (texture_length)
  375. {
  376. U8 tdpbuffer[1024];
  377. LLDataPackerBinaryBuffer tdp(tdpbuffer, 1024);
  378. mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextureEntry, tdpbuffer, 0, block_num);
  379. S32 result = unpackTEMessage(tdp);
  380. if (result & teDirtyBits)
  381. {
  382. updateTEData();
  383. }
  384. if (result & TEM_CHANGE_MEDIA)
  385. {
  386. retval |= MEDIA_FLAGS_CHANGED;
  387. }
  388. }
  389. }
  390. }
  391. if (retval & (MEDIA_URL_REMOVED | MEDIA_URL_ADDED | MEDIA_URL_UPDATED | MEDIA_FLAGS_CHANGED)) 
  392. {
  393. // If only the media URL changed, and it isn't a media version URL,
  394. // ignore it
  395. if ( ! ( retval & (MEDIA_URL_ADDED | MEDIA_URL_UPDATED) &&
  396.  mMedia && ! mMedia->mMediaURL.empty() &&
  397.  ! LLTextureEntry::isMediaVersionString(mMedia->mMediaURL) ) )
  398. {
  399. // If the media changed at all, request new media data
  400. LL_DEBUGS("MediaOnAPrim") << "Media update: " << getID() << ": retval=" << retval << " Media URL: " <<
  401.                 ((mMedia) ?  mMedia->mMediaURL : std::string("")) << LL_ENDL;
  402. requestMediaDataUpdate(retval & MEDIA_FLAGS_CHANGED);
  403. }
  404.         else {
  405.             LL_INFOS("MediaOnAPrim") << "Ignoring media update for: " << getID() << " Media URL: " <<
  406.                 ((mMedia) ?  mMedia->mMediaURL : std::string("")) << LL_ENDL;
  407.         }
  408. }
  409. // ...and clean up any media impls
  410. cleanUpMediaImpls();
  411. return retval;
  412. }
  413. void LLVOVolume::animateTextures()
  414. {
  415. F32 off_s = 0.f, off_t = 0.f, scale_s = 1.f, scale_t = 1.f, rot = 0.f;
  416. S32 result = mTextureAnimp->animateTextures(off_s, off_t, scale_s, scale_t, rot);
  417. if (result)
  418. {
  419. if (!mTexAnimMode)
  420. {
  421. mFaceMappingChanged = TRUE;
  422. gPipeline.markTextured(mDrawable);
  423. }
  424. mTexAnimMode = result | mTextureAnimp->mMode;
  425. S32 start=0, end=mDrawable->getNumFaces()-1;
  426. if (mTextureAnimp->mFace >= 0 && mTextureAnimp->mFace <= end)
  427. {
  428. start = end = mTextureAnimp->mFace;
  429. }
  430. for (S32 i = start; i <= end; i++)
  431. {
  432. LLFace* facep = mDrawable->getFace(i);
  433. if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue;
  434. const LLTextureEntry* te = facep->getTextureEntry();
  435. if (!te)
  436. {
  437. continue;
  438. }
  439. if (!(result & LLViewerTextureAnim::ROTATE))
  440. {
  441. te->getRotation(&rot);
  442. }
  443. if (!(result & LLViewerTextureAnim::TRANSLATE))
  444. {
  445. te->getOffset(&off_s,&off_t);
  446. }
  447. if (!(result & LLViewerTextureAnim::SCALE))
  448. {
  449. te->getScale(&scale_s, &scale_t);
  450. }
  451. if (!facep->mTextureMatrix)
  452. {
  453. facep->mTextureMatrix = new LLMatrix4();
  454. }
  455. LLMatrix4& tex_mat = *facep->mTextureMatrix;
  456. tex_mat.setIdentity();
  457. LLVector3 trans ;
  458. if(facep->isAtlasInUse())
  459. {
  460. //
  461. //if use atlas for animated texture
  462. //apply the following transform to the animation matrix.
  463. //
  464. F32 tcoord_xoffset = 0.f ;
  465. F32 tcoord_yoffset = 0.f ;
  466. F32 tcoord_xscale = 1.f ;
  467. F32 tcoord_yscale = 1.f ;
  468. if(facep->isAtlasInUse())
  469. {
  470. const LLVector2* tmp = facep->getTexCoordOffset() ;
  471. tcoord_xoffset = tmp->mV[0] ; 
  472. tcoord_yoffset = tmp->mV[1] ;
  473. tmp = facep->getTexCoordScale() ;
  474. tcoord_xscale = tmp->mV[0] ; 
  475. tcoord_yscale = tmp->mV[1] ;
  476. }
  477. trans.set(LLVector3(tcoord_xoffset + tcoord_xscale * (off_s+0.5f), tcoord_yoffset + tcoord_yscale * (off_t+0.5f), 0.f));
  478. tex_mat.translate(LLVector3(-(tcoord_xoffset + tcoord_xscale * 0.5f), -(tcoord_yoffset + tcoord_yscale * 0.5f), 0.f));
  479. }
  480. else //non atlas
  481. {
  482. trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f));
  483. tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f));
  484. }
  485. LLVector3 scale(scale_s, scale_t, 1.f);
  486. LLQuaternion quat;
  487. quat.setQuat(rot, 0, 0, -1.f);
  488. tex_mat.rotate(quat);
  489. LLMatrix4 mat;
  490. mat.initAll(scale, LLQuaternion(), LLVector3());
  491. tex_mat *= mat;
  492. tex_mat.translate(trans);
  493. }
  494. }
  495. else
  496. {
  497. if (mTexAnimMode && mTextureAnimp->mRate == 0)
  498. {
  499. U8 start, count;
  500. if (mTextureAnimp->mFace == -1)
  501. {
  502. start = 0;
  503. count = getNumTEs();
  504. }
  505. else
  506. {
  507. start = (U8) mTextureAnimp->mFace;
  508. count = 1;
  509. }
  510. for (S32 i = start; i < start + count; i++)
  511. {
  512. if (mTexAnimMode & LLViewerTextureAnim::TRANSLATE)
  513. {
  514. setTEOffset(i, mTextureAnimp->mOffS, mTextureAnimp->mOffT);
  515. }
  516. if (mTexAnimMode & LLViewerTextureAnim::SCALE)
  517. {
  518. setTEScale(i, mTextureAnimp->mScaleS, mTextureAnimp->mScaleT);
  519. }
  520. if (mTexAnimMode & LLViewerTextureAnim::ROTATE)
  521. {
  522. setTERotation(i, mTextureAnimp->mRot);
  523. }
  524. }
  525. gPipeline.markTextured(mDrawable);
  526. mFaceMappingChanged = TRUE;
  527. mTexAnimMode = 0;
  528. }
  529. }
  530. }
  531. BOOL LLVOVolume::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
  532. {
  533. LLViewerObject::idleUpdate(agent, world, time);
  534. if (mDead || mDrawable.isNull())
  535. {
  536. return TRUE;
  537. }
  538. ///////////////////////
  539. //
  540. // Do texture animation stuff
  541. //
  542. if (mTextureAnimp && gAnimateTextures)
  543. {
  544. animateTextures();
  545. }
  546. // Dispatch to implementation
  547. if (mVolumeImpl)
  548. {
  549. mVolumeImpl->doIdleUpdate(agent, world, time);
  550. }
  551. return TRUE;
  552. }
  553. void LLVOVolume::updateTextures()
  554. {
  555. const F32 TEXTURE_AREA_REFRESH_TIME = 5.f; // seconds
  556. if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME)
  557. {
  558. updateTextureVirtualSize();
  559. }
  560. }
  561. void LLVOVolume::updateTextureVirtualSize()
  562. {
  563. // Update the pixel area of all faces
  564. if(mDrawable.isNull() || !mDrawable->isVisible())
  565. {
  566. return ;
  567. }
  568. if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SIMPLE))
  569. {
  570. return;
  571. }
  572. static LLCachedControl<bool> dont_load_textures(gSavedSettings,"TextureDisable");
  573. if (dont_load_textures || LLAppViewer::getTextureFetch()->mDebugPause) // || !mDrawable->isVisible())
  574. {
  575. return;
  576. }
  577. mTextureUpdateTimer.reset();
  578. F32 old_area = mPixelArea;
  579. mPixelArea = 0.f;
  580. const S32 num_faces = mDrawable->getNumFaces();
  581. F32 min_vsize=999999999.f, max_vsize=0.f;
  582. LLViewerCamera* camera = LLViewerCamera::getInstance();
  583. for (S32 i = 0; i < num_faces; i++)
  584. {
  585. LLFace* face = mDrawable->getFace(i);
  586. const LLTextureEntry *te = face->getTextureEntry();
  587. LLViewerTexture *imagep = face->getTexture();
  588. if (!imagep || !te ||
  589. face->mExtents[0] == face->mExtents[1])
  590. {
  591. continue;
  592. }
  593. F32 vsize;
  594. F32 old_size = face->getVirtualSize();
  595. if (isHUDAttachment())
  596. {
  597. F32 area = (F32) camera->getScreenPixelArea();
  598. vsize = area;
  599. imagep->setBoostLevel(LLViewerTexture::BOOST_HUD);
  600.   face->setPixelArea(area); // treat as full screen
  601. face->setVirtualSize(vsize);
  602. }
  603. else
  604. {
  605. vsize = face->getTextureVirtualSize();
  606. }
  607. mPixelArea = llmax(mPixelArea, face->getPixelArea());
  608. if (face->mTextureMatrix != NULL)
  609. {
  610. if ((vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE) ||
  611. (vsize > MIN_TEX_ANIM_SIZE && old_size < MIN_TEX_ANIM_SIZE))
  612. {
  613. gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD, FALSE);
  614. }
  615. }
  616. if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA))
  617. {
  618. if (vsize < min_vsize) min_vsize = vsize;
  619. if (vsize > max_vsize) max_vsize = vsize;
  620. }
  621. else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
  622. {
  623. LLViewerFetchedTexture* img = LLViewerTextureManager::staticCastToFetchedTexture(imagep) ;
  624. if(img)
  625. {
  626. F32 pri = img->getDecodePriority();
  627. pri = llmax(pri, 0.0f);
  628. if (pri < min_vsize) min_vsize = pri;
  629. if (pri > max_vsize) max_vsize = pri;
  630. }
  631. }
  632. else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA))
  633. {
  634. F32 pri = mPixelArea;
  635. if (pri < min_vsize) min_vsize = pri;
  636. if (pri > max_vsize) max_vsize = pri;
  637. }
  638. }
  639. if (isSculpted())
  640. {
  641. LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
  642. LLUUID id =  sculpt_params->getSculptTexture(); 
  643. updateSculptTexture();
  644. if (mSculptTexture.notNull())
  645. {
  646. mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(),
  647. (S32)LLViewerTexture::BOOST_SCULPTED));
  648. mSculptTexture->setForSculpt() ;
  649. if(!mSculptTexture->isCachedRawImageReady())
  650. {
  651. S32 lod = llmin(mLOD, 3);
  652. F32 lodf = ((F32)(lod + 1.0f)/4.f);
  653. F32 tex_size = lodf * LLViewerTexture::sMaxSculptRez ;
  654. mSculptTexture->addTextureStats(2.f * tex_size * tex_size, FALSE);
  655. //if the sculpty very close to the view point, load first
  656. {
  657. LLVector3 lookAt = getPositionAgent() - camera->getOrigin();
  658. F32 dist = lookAt.normVec() ;
  659. F32 cos_angle_to_view_dir = lookAt * camera->getXAxis() ;
  660. mSculptTexture->setAdditionalDecodePriority(0.8f * LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist)) ;
  661. }
  662. }
  663. S32 texture_discard = mSculptTexture->getDiscardLevel(); //try to match the texture
  664. S32 current_discard = getVolume() ? getVolume()->getSculptLevel() : -2 ;
  665. if (texture_discard >= 0 && //texture has some data available
  666. (texture_discard < current_discard || //texture has more data than last rebuild
  667. current_discard < 0)) //no previous rebuild
  668. {
  669. gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE);
  670. mSculptChanged = TRUE;
  671. }
  672. if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SCULPTED))
  673. {
  674. setDebugText(llformat("T%d C%d V%dn%dx%d",
  675.   texture_discard, current_discard, getVolume()->getSculptLevel(),
  676.   mSculptTexture->getHeight(), mSculptTexture->getWidth()));
  677. }
  678. }
  679. }
  680. if (getLightTextureID().notNull())
  681. {
  682. LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
  683. LLUUID id = params->getLightTexture();
  684. mLightTexture = LLViewerTextureManager::getFetchedTexture(id);
  685. if (mLightTexture.notNull())
  686. {
  687. F32 rad = getLightRadius();
  688. mLightTexture->addTextureStats(gPipeline.calcPixelArea(getPositionAgent(), 
  689. LLVector3(rad,rad,rad),
  690. *camera));
  691. }
  692. }
  693. if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA))
  694. {
  695. setDebugText(llformat("%.0f:%.0f", fsqrtf(min_vsize),fsqrtf(max_vsize)));
  696. }
  697.   else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
  698.   {
  699.   setDebugText(llformat("%.0f:%.0f", fsqrtf(min_vsize),fsqrtf(max_vsize)));
  700.   }
  701. else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA))
  702. {
  703. setDebugText(llformat("%.0f:%.0f", fsqrtf(min_vsize),fsqrtf(max_vsize)));
  704. }
  705. if (mPixelArea == 0)
  706. { //flexi phasing issues make this happen
  707. mPixelArea = old_area;
  708. }
  709. }
  710. BOOL LLVOVolume::isActive() const
  711. {
  712. return !mStatic || mTextureAnimp || (mVolumeImpl && mVolumeImpl->isActive());
  713. }
  714. BOOL LLVOVolume::setMaterial(const U8 material)
  715. {
  716. BOOL res = LLViewerObject::setMaterial(material);
  717. return res;
  718. }
  719. void LLVOVolume::setTexture(const S32 face)
  720. {
  721. llassert(face < getNumTEs());
  722. gGL.getTexUnit(0)->bind(getTEImage(face));
  723. }
  724. void LLVOVolume::setScale(const LLVector3 &scale, BOOL damped)
  725. {
  726. if (scale != getScale())
  727. {
  728. // store local radius
  729. LLViewerObject::setScale(scale);
  730. if (mVolumeImpl)
  731. {
  732. mVolumeImpl->onSetScale(scale, damped);
  733. }
  734. updateRadius();
  735. //since drawable transforms do not include scale, changing volume scale
  736. //requires an immediate rebuild of volume verts.
  737. gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION, TRUE);
  738. }
  739. }
  740. LLFace* LLVOVolume::addFace(S32 f)
  741. {
  742. const LLTextureEntry* te = getTE(f);
  743. LLViewerTexture* imagep = getTEImage(f);
  744. return mDrawable->addFace(te, imagep);
  745. }
  746. LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline)
  747. {
  748. pipeline->allocDrawable(this);
  749. mDrawable->setRenderType(LLPipeline::RENDER_TYPE_VOLUME);
  750. S32 max_tes_to_set = getNumTEs();
  751. for (S32 i = 0; i < max_tes_to_set; i++)
  752. {
  753. addFace(i);
  754. }
  755. mNumFaces = max_tes_to_set;
  756. if (isAttachment())
  757. {
  758. mDrawable->makeActive();
  759. }
  760. if (getIsLight())
  761. {
  762. // Add it to the pipeline mLightSet
  763. gPipeline.setLight(mDrawable, TRUE);
  764. }
  765. updateRadius();
  766. bool force_update = true; // avoid non-alpha mDistance update being optimized away
  767. mDrawable->updateDistance(*LLViewerCamera::getInstance(), force_update);
  768. return mDrawable;
  769. }
  770. BOOL LLVOVolume::setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume)
  771. {
  772. // Check if we need to change implementations
  773. bool is_flexible = (volume_params.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE);
  774. if (is_flexible)
  775. {
  776. setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, TRUE, false);
  777. if (!mVolumeImpl)
  778. {
  779. LLFlexibleObjectData* data = (LLFlexibleObjectData*)getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
  780. mVolumeImpl = new LLVolumeImplFlexible(this, data);
  781. }
  782. }
  783. else
  784. {
  785. // Mark the parameter not in use
  786. setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, FALSE, false);
  787. if (mVolumeImpl)
  788. {
  789. delete mVolumeImpl;
  790. mVolumeImpl = NULL;
  791. if (mDrawable.notNull())
  792. {
  793. // Undo the damage we did to this matrix
  794. mDrawable->updateXform(FALSE);
  795. }
  796. }
  797. }
  798. if ((LLPrimitive::setVolume(volume_params, mLOD, (mVolumeImpl && mVolumeImpl->isVolumeUnique()))) || mSculptChanged)
  799. {
  800. mFaceMappingChanged = TRUE;
  801. if (mVolumeImpl)
  802. {
  803. mVolumeImpl->onSetVolume(volume_params, detail);
  804. }
  805. updateSculptTexture();
  806. if (isSculpted())
  807. {
  808. updateSculptTexture();
  809. if (mSculptTexture.notNull())
  810. {
  811. sculpt();
  812. }
  813. }
  814. return TRUE;
  815. }
  816. return FALSE;
  817. }
  818. void LLVOVolume::updateSculptTexture()
  819. {
  820. LLPointer<LLViewerFetchedTexture> old_sculpt = mSculptTexture;
  821. if (isSculpted())
  822. {
  823. LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
  824. LLUUID id =  sculpt_params->getSculptTexture(); 
  825. mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
  826. }
  827. else
  828. {
  829. mSculptTexture = NULL;
  830. }
  831. if (mSculptTexture != old_sculpt)
  832. {
  833. if (old_sculpt.notNull())
  834. {
  835. old_sculpt->removeVolume(this);
  836. }
  837. if (mSculptTexture.notNull())
  838. {
  839. mSculptTexture->addVolume(this);
  840. }
  841. }
  842. }
  843. // sculpt replaces generate() for sculpted surfaces
  844. void LLVOVolume::sculpt()
  845. {
  846. if (mSculptTexture.notNull())
  847. {
  848. U16 sculpt_height = 0;
  849. U16 sculpt_width = 0;
  850. S8 sculpt_components = 0;
  851. const U8* sculpt_data = NULL;
  852. S32 discard_level = mSculptTexture->getDiscardLevel() ;
  853. LLImageRaw* raw_image = mSculptTexture->getCachedRawImage() ;
  854. S32 max_discard = mSculptTexture->getMaxDiscardLevel();
  855. if (discard_level > max_discard)
  856. discard_level = max_discard;    // clamp to the best we can do
  857. S32 current_discard = getVolume()->getSculptLevel() ;
  858. if(current_discard < -2)
  859. {
  860. llwarns << "WARNING!!: Current discard of sculpty at " << current_discard 
  861. << " is less than -2." << llendl;
  862. // corrupted volume... don't update the sculpty
  863. return;
  864. }
  865. else if (current_discard > MAX_DISCARD_LEVEL)
  866. {
  867. llwarns << "WARNING!!: Current discard of sculpty at " << current_discard 
  868. << " is more than than allowed max of " << MAX_DISCARD_LEVEL << llendl;
  869. // corrupted volume... don't update the sculpty
  870. return;
  871. }
  872. if (current_discard == discard_level)  // no work to do here
  873. return;
  874. if(!raw_image)
  875. {
  876. sculpt_width = 0;
  877. sculpt_height = 0;
  878. sculpt_data = NULL ;
  879. if(LLViewerTextureManager::sTesterp)
  880. {
  881. LLViewerTextureManager::sTesterp->updateGrayTextureBinding();
  882. }
  883. }
  884. else
  885. {
  886. sculpt_height = raw_image->getHeight();
  887. sculpt_width = raw_image->getWidth();
  888. sculpt_components = raw_image->getComponents();
  889.    
  890. sculpt_data = raw_image->getData();
  891. if(LLViewerTextureManager::sTesterp)
  892. {
  893. mSculptTexture->updateBindStatsForTester() ;
  894. }
  895. }
  896. getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level);
  897. //notify rebuild any other VOVolumes that reference this sculpty volume
  898. for (S32 i = 0; i < mSculptTexture->getNumVolumes(); ++i)
  899. {
  900. LLVOVolume* volume = (*(mSculptTexture->getVolumeList()))[i];
  901. if (volume != this && volume->getVolume() == getVolume())
  902. {
  903. gPipeline.markRebuild(volume->mDrawable, LLDrawable::REBUILD_GEOMETRY, FALSE);
  904. volume->mSculptChanged = TRUE;
  905. }
  906. }
  907. }
  908. }
  909. S32 LLVOVolume::computeLODDetail(F32 distance, F32 radius)
  910. {
  911. S32 cur_detail;
  912. if (LLPipeline::sDynamicLOD)
  913. {
  914. // We've got LOD in the profile, and in the twist.  Use radius.
  915. F32 tan_angle = (LLVOVolume::sLODFactor*radius)/distance;
  916. cur_detail = LLVolumeLODGroup::getDetailFromTan(llround(tan_angle, 0.01f));
  917. }
  918. else
  919. {
  920. cur_detail = llclamp((S32) (sqrtf(radius)*LLVOVolume::sLODFactor*4.f), 0, 3);
  921. }
  922. return cur_detail;
  923. }
  924. BOOL LLVOVolume::calcLOD()
  925. {
  926. if (mDrawable.isNull())
  927. {
  928. return FALSE;
  929. }
  930. S32 cur_detail = 0;
  931. F32 radius = getVolume()->mLODScaleBias.scaledVec(getScale()).length();
  932. F32 distance = llmin(mDrawable->mDistanceWRTCamera, MAX_LOD_DISTANCE);
  933. distance *= sDistanceFactor;
  934. F32 rampDist = LLVOVolume::sLODFactor * 2;
  935. if (distance < rampDist)
  936. {
  937. // Boost LOD when you're REALLY close
  938. distance *= 1.0f/rampDist;
  939. distance *= distance;
  940. distance *= rampDist;
  941. }
  942. // DON'T Compensate for field of view changing on FOV zoom.
  943. distance *= F_PI/3.f;
  944. cur_detail = computeLODDetail(llround(distance, 0.01f), 
  945. llround(radius, 0.01f));
  946. if (cur_detail != mLOD)
  947. {
  948. mAppAngle = llround((F32) atan2( mDrawable->getRadius(), mDrawable->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f);
  949. mLOD = cur_detail;
  950. return TRUE;
  951. }
  952. else
  953. {
  954. return FALSE;
  955. }
  956. }
  957. BOOL LLVOVolume::updateLOD()
  958. {
  959. if (mDrawable.isNull())
  960. {
  961. return FALSE;
  962. }
  963. BOOL lod_changed = calcLOD();
  964. if (lod_changed)
  965. {
  966. gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE);
  967. mLODChanged = TRUE;
  968. }
  969. lod_changed |= LLViewerObject::updateLOD();
  970. return lod_changed;
  971. }
  972. BOOL LLVOVolume::setDrawableParent(LLDrawable* parentp)
  973. {
  974. if (!LLViewerObject::setDrawableParent(parentp))
  975. {
  976. // no change in drawable parent
  977. return FALSE;
  978. }
  979. if (!mDrawable->isRoot())
  980. {
  981. // rebuild vertices in parent relative space
  982. gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
  983. if (mDrawable->isActive() && !parentp->isActive())
  984. {
  985. parentp->makeActive();
  986. }
  987. else if (mDrawable->isStatic() && parentp->isActive())
  988. {
  989. mDrawable->makeActive();
  990. }
  991. }
  992. return TRUE;
  993. }
  994. void LLVOVolume::updateFaceFlags()
  995. {
  996. for (S32 i = 0; i < getVolume()->getNumFaces(); i++)
  997. {
  998. LLFace *face = mDrawable->getFace(i);
  999. BOOL fullbright = getTE(i)->getFullbright();
  1000. face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT);
  1001. if (fullbright || (mMaterial == LL_MCODE_LIGHT))
  1002. {
  1003. face->setState(LLFace::FULLBRIGHT);
  1004. }
  1005. if (mDrawable->isLight())
  1006. {
  1007. face->setState(LLFace::LIGHT);
  1008. }
  1009. if (isHUDAttachment())
  1010. {
  1011. face->setState(LLFace::HUD_RENDER);
  1012. }
  1013. }
  1014. }
  1015. BOOL LLVOVolume::setParent(LLViewerObject* parent)
  1016. {
  1017. BOOL ret = FALSE ;
  1018. if (parent != getParent())
  1019. {
  1020. ret = LLViewerObject::setParent(parent);
  1021. if (ret && mDrawable)
  1022. {
  1023. gPipeline.markMoved(mDrawable);
  1024. gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
  1025. }
  1026. }
  1027. return ret ;
  1028. }
  1029. // NOTE: regenFaces() MUST be followed by genTriangles()!
  1030. void LLVOVolume::regenFaces()
  1031. {
  1032. // remove existing faces
  1033. BOOL count_changed = mNumFaces != getNumTEs();
  1034. if (count_changed)
  1035. {
  1036. deleteFaces();
  1037. // add new faces
  1038. mNumFaces = getNumTEs();
  1039. }
  1040. for (S32 i = 0; i < mNumFaces; i++)
  1041. {
  1042. LLFace* facep = count_changed ? addFace(i) : mDrawable->getFace(i);
  1043. facep->setTEOffset(i);
  1044. facep->setTexture(getTEImage(i));
  1045. facep->setViewerObject(this);
  1046. // If the face had media on it, this will have broken the link between the LLViewerMediaTexture and the face.
  1047. // Re-establish the link.
  1048. if((int)mMediaImplList.size() > i)
  1049. {
  1050. if(mMediaImplList[i])
  1051. {
  1052. LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[i]->getMediaTextureID()) ;
  1053. if(media_tex)
  1054. {
  1055. media_tex->addMediaToFace(facep) ;
  1056. }
  1057. }
  1058. }
  1059. }
  1060. if (!count_changed)
  1061. {
  1062. updateFaceFlags();
  1063. }
  1064. }
  1065. BOOL LLVOVolume::genBBoxes(BOOL force_global)
  1066. {
  1067. BOOL res = TRUE;
  1068. LLVector3 min,max;
  1069. BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION);
  1070. for (S32 i = 0; i < getVolume()->getNumFaces(); i++)
  1071. {
  1072. LLFace *face = mDrawable->getFace(i);
  1073. res &= face->genVolumeBBoxes(*getVolume(), i,
  1074. mRelativeXform, mRelativeXformInvTrans,
  1075. (mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global);
  1076. if (rebuild)
  1077. {
  1078. if (i == 0)
  1079. {
  1080. min = face->mExtents[0];
  1081. max = face->mExtents[1];
  1082. }
  1083. else
  1084. {
  1085. for (U32 i = 0; i < 3; i++)
  1086. {
  1087. if (face->mExtents[0].mV[i] < min.mV[i])
  1088. {
  1089. min.mV[i] = face->mExtents[0].mV[i];
  1090. }
  1091. if (face->mExtents[1].mV[i] > max.mV[i])
  1092. {
  1093. max.mV[i] = face->mExtents[1].mV[i];
  1094. }
  1095. }
  1096. }
  1097. }
  1098. }
  1099. if (rebuild)
  1100. {
  1101. mDrawable->setSpatialExtents(min,max);
  1102. mDrawable->setPositionGroup((min+max)*0.5f);
  1103. }
  1104. updateRadius();
  1105. mDrawable->movePartition();
  1106. return res;
  1107. }
  1108. void LLVOVolume::preRebuild()
  1109. {
  1110. if (mVolumeImpl != NULL)
  1111. {
  1112. mVolumeImpl->preRebuild();
  1113. }
  1114. }
  1115. void LLVOVolume::updateRelativeXform()
  1116. {
  1117. if (mVolumeImpl)
  1118. {
  1119. mVolumeImpl->updateRelativeXform();
  1120. return;
  1121. }
  1122. LLDrawable* drawable = mDrawable;
  1123. if (drawable->isActive())
  1124. {
  1125. // setup relative transforms
  1126. LLQuaternion delta_rot;
  1127. LLVector3 delta_pos, delta_scale;
  1128. //matrix from local space to parent relative/global space
  1129. delta_rot = drawable->isSpatialRoot() ? LLQuaternion() : mDrawable->getRotation();
  1130. delta_pos = drawable->isSpatialRoot() ? LLVector3(0,0,0) : mDrawable->getPosition();
  1131. delta_scale = mDrawable->getScale();
  1132. // Vertex transform (4x4)
  1133. LLVector3 x_axis = LLVector3(delta_scale.mV[VX], 0.f, 0.f) * delta_rot;
  1134. LLVector3 y_axis = LLVector3(0.f, delta_scale.mV[VY], 0.f) * delta_rot;
  1135. LLVector3 z_axis = LLVector3(0.f, 0.f, delta_scale.mV[VZ]) * delta_rot;
  1136. mRelativeXform.initRows(LLVector4(x_axis, 0.f),
  1137. LLVector4(y_axis, 0.f),
  1138. LLVector4(z_axis, 0.f),
  1139. LLVector4(delta_pos, 1.f));
  1140. // compute inverse transpose for normals
  1141. // mRelativeXformInvTrans.setRows(x_axis, y_axis, z_axis);
  1142. // mRelativeXformInvTrans.invert(); 
  1143. // mRelativeXformInvTrans.setRows(x_axis, y_axis, z_axis);
  1144. // grumble - invert is NOT a matrix invert, so we do it by hand:
  1145. LLMatrix3 rot_inverse = LLMatrix3(~delta_rot);
  1146. LLMatrix3 scale_inverse;
  1147. scale_inverse.setRows(LLVector3(1.0, 0.0, 0.0) / delta_scale.mV[VX],
  1148.   LLVector3(0.0, 1.0, 0.0) / delta_scale.mV[VY],
  1149.   LLVector3(0.0, 0.0, 1.0) / delta_scale.mV[VZ]);
  1150.    
  1151. mRelativeXformInvTrans = rot_inverse * scale_inverse;
  1152. mRelativeXformInvTrans.transpose();
  1153. }
  1154. else
  1155. {
  1156. LLVector3 pos = getPosition();
  1157. LLVector3 scale = getScale();
  1158. LLQuaternion rot = getRotation();
  1159. if (mParent)
  1160. {
  1161. pos *= mParent->getRotation();
  1162. pos += mParent->getPosition();
  1163. rot *= mParent->getRotation();
  1164. }
  1165. //LLViewerRegion* region = getRegion();
  1166. //pos += region->getOriginAgent();
  1167. LLVector3 x_axis = LLVector3(scale.mV[VX], 0.f, 0.f) * rot;
  1168. LLVector3 y_axis = LLVector3(0.f, scale.mV[VY], 0.f) * rot;
  1169. LLVector3 z_axis = LLVector3(0.f, 0.f, scale.mV[VZ]) * rot;
  1170. mRelativeXform.initRows(LLVector4(x_axis, 0.f),
  1171. LLVector4(y_axis, 0.f),
  1172. LLVector4(z_axis, 0.f),
  1173. LLVector4(pos, 1.f));
  1174. // compute inverse transpose for normals
  1175. LLMatrix3 rot_inverse = LLMatrix3(~rot);
  1176. LLMatrix3 scale_inverse;
  1177. scale_inverse.setRows(LLVector3(1.0, 0.0, 0.0) / scale.mV[VX],
  1178.   LLVector3(0.0, 1.0, 0.0) / scale.mV[VY],
  1179.   LLVector3(0.0, 0.0, 1.0) / scale.mV[VZ]);
  1180.    
  1181. mRelativeXformInvTrans = rot_inverse * scale_inverse;
  1182. mRelativeXformInvTrans.transpose();
  1183. }
  1184. }
  1185. static LLFastTimer::DeclareTimer FTM_GEN_FLEX("Generate Flexies");
  1186. static LLFastTimer::DeclareTimer FTM_UPDATE_PRIMITIVES("Update Primitives");
  1187. BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
  1188. {
  1189. LLFastTimer t(FTM_UPDATE_PRIMITIVES);
  1190. if (mVolumeImpl != NULL)
  1191. {
  1192. BOOL res;
  1193. {
  1194. LLFastTimer t(FTM_GEN_FLEX);
  1195. res = mVolumeImpl->doUpdateGeometry(drawable);
  1196. }
  1197. updateFaceFlags();
  1198. return res;
  1199. }
  1200. dirtySpatialGroup();
  1201. BOOL compiled = FALSE;
  1202. updateRelativeXform();
  1203. if (mDrawable.isNull()) // Not sure why this is happening, but it is...
  1204. {
  1205. return TRUE; // No update to complete
  1206. }
  1207. if (mVolumeChanged || mFaceMappingChanged )
  1208. {
  1209. compiled = TRUE;
  1210. if (mVolumeChanged)
  1211. {
  1212. LLFastTimer ftm(FTM_GEN_VOLUME);
  1213. LLVolumeParams volume_params = getVolume()->getParams();
  1214. setVolume(volume_params, 0);
  1215. drawable->setState(LLDrawable::REBUILD_VOLUME);
  1216. }
  1217. {
  1218. LLFastTimer t(FTM_GEN_TRIANGLES);
  1219. regenFaces();
  1220. genBBoxes(FALSE);
  1221. }
  1222. }
  1223. else if ((mLODChanged) || (mSculptChanged))
  1224. {
  1225. LLVolume *old_volumep, *new_volumep;
  1226. F32 old_lod, new_lod;
  1227. S32 old_num_faces, new_num_faces ;
  1228. old_volumep = getVolume();
  1229. old_lod = old_volumep->getDetail();
  1230. old_num_faces = old_volumep->getNumFaces() ;
  1231. old_volumep = NULL ;
  1232. {
  1233. LLFastTimer ftm(FTM_GEN_VOLUME);
  1234. LLVolumeParams volume_params = getVolume()->getParams();
  1235. setVolume(volume_params, 0);
  1236. }
  1237. new_volumep = getVolume();
  1238. new_lod = new_volumep->getDetail();
  1239. new_num_faces = new_volumep->getNumFaces() ;
  1240. new_volumep = NULL ;
  1241. if ((new_lod != old_lod) || mSculptChanged)
  1242. {
  1243. compiled = TRUE;
  1244. sNumLODChanges += new_num_faces ;
  1245. drawable->setState(LLDrawable::REBUILD_VOLUME); // for face->genVolumeTriangles()
  1246. {
  1247. LLFastTimer t(FTM_GEN_TRIANGLES);
  1248. if (new_num_faces != old_num_faces)
  1249. {
  1250. regenFaces();
  1251. }
  1252. genBBoxes(FALSE);
  1253. }
  1254. }
  1255. }
  1256. // it has its own drawable (it's moved) or it has changed UVs or it has changed xforms from global<->local
  1257. else
  1258. {
  1259. compiled = TRUE;
  1260. // All it did was move or we changed the texture coordinate offset
  1261. LLFastTimer t(FTM_GEN_TRIANGLES);
  1262. genBBoxes(FALSE);
  1263. }
  1264. // Update face flags
  1265. updateFaceFlags();
  1266. if(compiled)
  1267. {
  1268. LLPipeline::sCompiles++;
  1269. }
  1270. mVolumeChanged = FALSE;
  1271. mLODChanged = FALSE;
  1272. mSculptChanged = FALSE;
  1273. mFaceMappingChanged = FALSE;
  1274. return LLViewerObject::updateGeometry(drawable);
  1275. }
  1276. void LLVOVolume::updateFaceSize(S32 idx)
  1277. {
  1278. LLFace* facep = mDrawable->getFace(idx);
  1279. if (idx >= getVolume()->getNumVolumeFaces())
  1280. {
  1281. facep->setSize(0,0);
  1282. }
  1283. else
  1284. {
  1285. const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx);
  1286. facep->setSize(vol_face.mVertices.size(), vol_face.mIndices.size());
  1287. }
  1288. }
  1289. BOOL LLVOVolume::isRootEdit() const
  1290. {
  1291. if (mParent && !((LLViewerObject*)mParent)->isAvatar())
  1292. {
  1293. return FALSE;
  1294. }
  1295. return TRUE;
  1296. }
  1297. //virtual
  1298. void LLVOVolume::setNumTEs(const U8 num_tes)
  1299. {
  1300. const U8 old_num_tes = getNumTEs() ;
  1301. if(old_num_tes && old_num_tes < num_tes) //new faces added
  1302. {
  1303. LLViewerObject::setNumTEs(num_tes) ;
  1304. if(mMediaImplList.size() >= old_num_tes && mMediaImplList[old_num_tes -1].notNull())//duplicate the last media textures if exists.
  1305. {
  1306. mMediaImplList.resize(num_tes) ;
  1307. const LLTextureEntry* te = getTE(old_num_tes - 1) ;
  1308. for(U8 i = old_num_tes; i < num_tes ; i++)
  1309. {
  1310. setTE(i, *te) ;
  1311. mMediaImplList[i] = mMediaImplList[old_num_tes -1] ;
  1312. }
  1313. mMediaImplList[old_num_tes -1]->setUpdated(TRUE) ;
  1314. }
  1315. }
  1316. else if(old_num_tes > num_tes && mMediaImplList.size() > num_tes) //old faces removed
  1317. {
  1318. U8 end = mMediaImplList.size() ;
  1319. for(U8 i = num_tes; i < end ; i++)
  1320. {
  1321. removeMediaImpl(i) ;
  1322. }
  1323. mMediaImplList.resize(num_tes) ;
  1324. LLViewerObject::setNumTEs(num_tes) ;
  1325. }
  1326. else
  1327. {
  1328. LLViewerObject::setNumTEs(num_tes) ;
  1329. }
  1330. return ;
  1331. }
  1332. void LLVOVolume::setTEImage(const U8 te, LLViewerTexture *imagep)
  1333. {
  1334. BOOL changed = (mTEImages[te] != imagep);
  1335. LLViewerObject::setTEImage(te, imagep);
  1336. if (changed)
  1337. {
  1338. gPipeline.markTextured(mDrawable);
  1339. mFaceMappingChanged = TRUE;
  1340. }
  1341. }
  1342. S32 LLVOVolume::setTETexture(const U8 te, const LLUUID &uuid)
  1343. {
  1344. S32 res = LLViewerObject::setTETexture(te, uuid);
  1345. if (res)
  1346. {
  1347. gPipeline.markTextured(mDrawable);
  1348. mFaceMappingChanged = TRUE;
  1349. }
  1350. return res;
  1351. }
  1352. S32 LLVOVolume::setTEColor(const U8 te, const LLColor3& color)
  1353. {
  1354. return setTEColor(te, LLColor4(color));
  1355. }
  1356. S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color)
  1357. {
  1358. S32 retval = 0;
  1359. const LLTextureEntry *tep = getTE(te);
  1360. if (!tep)
  1361. {
  1362. llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
  1363. }
  1364. else if (color != tep->getColor())
  1365. {
  1366. if (color.mV[3] != tep->getColor().mV[3])
  1367. {
  1368. gPipeline.markTextured(mDrawable);
  1369. }
  1370. retval = LLPrimitive::setTEColor(te, color);
  1371. if (mDrawable.notNull() && retval)
  1372. {
  1373. // These should only happen on updates which are not the initial update.
  1374. mDrawable->setState(LLDrawable::REBUILD_COLOR);
  1375. dirtyMesh();
  1376. }
  1377. }
  1378. return  retval;
  1379. }
  1380. S32 LLVOVolume::setTEBumpmap(const U8 te, const U8 bumpmap)
  1381. {
  1382. S32 res = LLViewerObject::setTEBumpmap(te, bumpmap);
  1383. if (res)
  1384. {
  1385. gPipeline.markTextured(mDrawable);
  1386. mFaceMappingChanged = TRUE;
  1387. }
  1388. return  res;
  1389. }
  1390. S32 LLVOVolume::setTETexGen(const U8 te, const U8 texgen)
  1391. {
  1392. S32 res = LLViewerObject::setTETexGen(te, texgen);
  1393. if (res)
  1394. {
  1395. gPipeline.markTextured(mDrawable);
  1396. mFaceMappingChanged = TRUE;
  1397. }
  1398. return  res;
  1399. }
  1400. S32 LLVOVolume::setTEMediaTexGen(const U8 te, const U8 media)
  1401. {
  1402. S32 res = LLViewerObject::setTEMediaTexGen(te, media);
  1403. if (res)
  1404. {
  1405. gPipeline.markTextured(mDrawable);
  1406. mFaceMappingChanged = TRUE;
  1407. }
  1408. return  res;
  1409. }
  1410. S32 LLVOVolume::setTEShiny(const U8 te, const U8 shiny)
  1411. {
  1412. S32 res = LLViewerObject::setTEShiny(te, shiny);
  1413. if (res)
  1414. {
  1415. gPipeline.markTextured(mDrawable);
  1416. mFaceMappingChanged = TRUE;
  1417. }
  1418. return  res;
  1419. }
  1420. S32 LLVOVolume::setTEFullbright(const U8 te, const U8 fullbright)
  1421. {
  1422. S32 res = LLViewerObject::setTEFullbright(te, fullbright);
  1423. if (res)
  1424. {
  1425. gPipeline.markTextured(mDrawable);
  1426. mFaceMappingChanged = TRUE;
  1427. }
  1428. return  res;
  1429. }
  1430. S32 LLVOVolume::setTEBumpShinyFullbright(const U8 te, const U8 bump)
  1431. {
  1432. S32 res = LLViewerObject::setTEBumpShinyFullbright(te, bump);
  1433. if (res)
  1434. {
  1435. gPipeline.markTextured(mDrawable);
  1436. mFaceMappingChanged = TRUE;
  1437. }
  1438. return res;
  1439. }
  1440. S32 LLVOVolume::setTEMediaFlags(const U8 te, const U8 media_flags)
  1441. {
  1442. S32 res = LLViewerObject::setTEMediaFlags(te, media_flags);
  1443. if (res)
  1444. {
  1445. gPipeline.markTextured(mDrawable);
  1446. mFaceMappingChanged = TRUE;
  1447. }
  1448. return  res;
  1449. }
  1450. S32 LLVOVolume::setTEGlow(const U8 te, const F32 glow)
  1451. {
  1452. S32 res = LLViewerObject::setTEGlow(te, glow);
  1453. if (res)
  1454. {
  1455. gPipeline.markTextured(mDrawable);
  1456. mFaceMappingChanged = TRUE;
  1457. }
  1458. return  res;
  1459. }
  1460. S32 LLVOVolume::setTEScale(const U8 te, const F32 s, const F32 t)
  1461. {
  1462. S32 res = LLViewerObject::setTEScale(te, s, t);
  1463. if (res)
  1464. {
  1465. gPipeline.markTextured(mDrawable);
  1466. mFaceMappingChanged = TRUE;
  1467. }
  1468. return res;
  1469. }
  1470. S32 LLVOVolume::setTEScaleS(const U8 te, const F32 s)
  1471. {
  1472. S32 res = LLViewerObject::setTEScaleS(te, s);
  1473. if (res)
  1474. {
  1475. gPipeline.markTextured(mDrawable);
  1476. mFaceMappingChanged = TRUE;
  1477. }
  1478. return res;
  1479. }
  1480. S32 LLVOVolume::setTEScaleT(const U8 te, const F32 t)
  1481. {
  1482. S32 res = LLViewerObject::setTEScaleT(te, t);
  1483. if (res)
  1484. {
  1485. gPipeline.markTextured(mDrawable);
  1486. mFaceMappingChanged = TRUE;
  1487. }
  1488. return res;
  1489. }
  1490. void LLVOVolume::updateTEData()
  1491. {
  1492. /*if (mDrawable.notNull())
  1493. {
  1494. mFaceMappingChanged = TRUE;
  1495. gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_MATERIAL, TRUE);
  1496. }*/
  1497. }
  1498. bool LLVOVolume::hasMedia() const
  1499. {
  1500. bool result = false;
  1501. const U8 numTEs = getNumTEs();
  1502. for (U8 i = 0; i < numTEs; i++)
  1503. {
  1504. const LLTextureEntry* te = getTE(i);
  1505. if(te->hasMedia())
  1506. {
  1507. result = true;
  1508. break;
  1509. }
  1510. }
  1511. return result;
  1512. }
  1513. LLVector3 LLVOVolume::getApproximateFaceNormal(U8 face_id)
  1514. {
  1515. LLVolume* volume = getVolume();
  1516. LLVector3 result;
  1517. if (volume && face_id < volume->getNumVolumeFaces())
  1518. {
  1519. const LLVolumeFace& face = volume->getVolumeFace(face_id);
  1520. for (S32 i = 0; i < (S32)face.mVertices.size(); ++i)
  1521. {
  1522. result += face.mVertices[i].mNormal;
  1523. }
  1524. result = volumeDirectionToAgent(result);
  1525. result.normVec();
  1526. }
  1527. return result;
  1528. }
  1529. void LLVOVolume::requestMediaDataUpdate(bool isNew)
  1530. {
  1531.     if (sObjectMediaClient)
  1532. sObjectMediaClient->fetchMedia(new LLMediaDataClientObjectImpl(this, isNew));
  1533. }
  1534. bool LLVOVolume::isMediaDataBeingFetched() const
  1535. {
  1536. // I know what I'm doing by const_casting this away: this is just 
  1537. // a wrapper class that is only going to do a lookup.
  1538. return (sObjectMediaClient) ? sObjectMediaClient->isInQueue(new LLMediaDataClientObjectImpl(const_cast<LLVOVolume*>(this), false)) : false;
  1539. }
  1540. void LLVOVolume::cleanUpMediaImpls()
  1541. {
  1542. // Iterate through our TEs and remove any Impls that are no longer used
  1543. const U8 numTEs = getNumTEs();
  1544. for (U8 i = 0; i < numTEs; i++)
  1545. {
  1546. const LLTextureEntry* te = getTE(i);
  1547. if( ! te->hasMedia())
  1548. {
  1549. // Delete the media IMPL!
  1550. removeMediaImpl(i) ;
  1551. }
  1552. }
  1553. }
  1554. void LLVOVolume::updateObjectMediaData(const LLSD &media_data_array, const std::string &media_version)
  1555. {
  1556. // media_data_array is an array of media entry maps
  1557. // media_version is the version string in the response.
  1558. U32 fetched_version = LLTextureEntry::getVersionFromMediaVersionString(media_version);
  1559. // Only update it if it is newer!
  1560. if ( (S32)fetched_version > mLastFetchedMediaVersion)
  1561. {
  1562. mLastFetchedMediaVersion = fetched_version;
  1563. //llinfos << "updating:" << this->getID() << " " << ll_pretty_print_sd(media_data_array) << llendl;
  1564. LLSD::array_const_iterator iter = media_data_array.beginArray();
  1565. LLSD::array_const_iterator end = media_data_array.endArray();
  1566. U8 texture_index = 0;
  1567. for (; iter != end; ++iter, ++texture_index)
  1568. {
  1569. syncMediaData(texture_index, *iter, false/*merge*/, false/*ignore_agent*/);
  1570. }
  1571. }
  1572. }
  1573. void LLVOVolume::syncMediaData(S32 texture_index, const LLSD &media_data, bool merge, bool ignore_agent)
  1574. {
  1575. if(mDead)
  1576. {
  1577. // If the object has been marked dead, don't process media updates.
  1578. return;
  1579. }
  1580. LLTextureEntry *te = getTE(texture_index);
  1581. LL_DEBUGS("MediaOnAPrim") << "BEFORE: texture_index = " << texture_index
  1582. << " hasMedia = " << te->hasMedia() << " : " 
  1583. << ((NULL == te->getMediaData()) ? "NULL MEDIA DATA" : ll_pretty_print_sd(te->getMediaData()->asLLSD())) << llendl;
  1584. std::string previous_url;
  1585. LLMediaEntry* mep = te->getMediaData();
  1586. if(mep)
  1587. {
  1588. // Save the "current url" from before the update so we can tell if
  1589. // it changes. 
  1590. previous_url = mep->getCurrentURL();
  1591. }
  1592. if (merge)
  1593. {
  1594. te->mergeIntoMediaData(media_data);
  1595. }
  1596. else {
  1597. // XXX Question: what if the media data is undefined LLSD, but the
  1598. // update we got above said that we have media flags?? Here we clobber
  1599. // that, assuming the data from the service is more up-to-date. 
  1600. te->updateMediaData(media_data);
  1601. }
  1602. mep = te->getMediaData();
  1603. if(mep)
  1604. {
  1605. bool update_from_self = false;
  1606. if (!ignore_agent) 
  1607. {
  1608. LLUUID updating_agent = LLTextureEntry::getAgentIDFromMediaVersionString(getMediaURL());
  1609. update_from_self = (updating_agent == gAgent.getID());
  1610. }
  1611. viewer_media_t media_impl = LLViewerMedia::updateMediaImpl(mep, previous_url, update_from_self);
  1612. addMediaImpl(media_impl, texture_index) ;
  1613. }
  1614. else
  1615. {
  1616. removeMediaImpl(texture_index);
  1617. }
  1618. LL_DEBUGS("MediaOnAPrim") << "AFTER: texture_index = " << texture_index
  1619. << " hasMedia = " << te->hasMedia() << " : " 
  1620. << ((NULL == te->getMediaData()) ? "NULL MEDIA DATA" : ll_pretty_print_sd(te->getMediaData()->asLLSD())) << llendl;
  1621. }
  1622. void LLVOVolume::mediaNavigateBounceBack(U8 texture_index)
  1623. {
  1624. // Find the media entry for this navigate
  1625. const LLMediaEntry* mep = NULL;
  1626. viewer_media_t impl = getMediaImpl(texture_index);
  1627. LLTextureEntry *te = getTE(texture_index);
  1628. if(te)
  1629. {
  1630. mep = te->getMediaData();
  1631. }
  1632. if (mep && impl)
  1633. {
  1634.         std::string url = mep->getCurrentURL();
  1635. // Look for a ":", if not there, assume "http://"
  1636. if (!url.empty() && std::string::npos == url.find(':')) 
  1637. {
  1638. url = "http://" + url;
  1639. }
  1640. // If the url we're trying to "bounce back" to is either empty or not
  1641. // allowed by the whitelist, try the home url.  If *that* doesn't work,
  1642. // set the media as failed and unload it
  1643.         if (url.empty() || !mep->checkCandidateUrl(url))
  1644.         {
  1645.             url = mep->getHomeURL();
  1646. // Look for a ":", if not there, assume "http://"
  1647. if (!url.empty() && std::string::npos == url.find(':')) 
  1648. {
  1649. url = "http://" + url;
  1650. }
  1651.         }
  1652.         if (url.empty() || !mep->checkCandidateUrl(url))
  1653. {
  1654. // The url to navigate back to is not good, and we have nowhere else
  1655. // to go.
  1656. LL_WARNS("MediaOnAPrim") << "FAILED to bounce back URL "" << url << "" -- unloading impl" << LL_ENDL;
  1657. impl->setMediaFailed(true);
  1658. }
  1659. else {
  1660. // Okay, navigate now
  1661.             LL_INFOS("MediaOnAPrim") << "bouncing back to URL: " << url << LL_ENDL;
  1662.             impl->navigateTo(url, "", false, true);
  1663.         }
  1664.     }
  1665. }
  1666. bool LLVOVolume::hasMediaPermission(const LLMediaEntry* media_entry, MediaPermType perm_type)
  1667. {
  1668.     // NOTE: This logic ALMOST duplicates the logic in the server (in particular, in llmediaservice.cpp).
  1669.     if (NULL == media_entry ) return false; // XXX should we assert here?
  1670.     
  1671.     // The agent has permissions if:
  1672.     // - world permissions are on, or
  1673.     // - group permissions are on, and agent_id is in the group, or
  1674.     // - agent permissions are on, and agent_id is the owner
  1675.     
  1676. // *NOTE: We *used* to check for modify permissions here (i.e. permissions were
  1677. // granted if permModify() was true).  However, this doesn't make sense in the
  1678. // viewer: we don't want to show controls or allow interaction if the author
  1679. // has deemed it so.  See DEV-42115.
  1680.     U8 media_perms = (perm_type == MEDIA_PERM_INTERACT) ? media_entry->getPermsInteract() : media_entry->getPermsControl();
  1681.     
  1682.     // World permissions
  1683.     if (0 != (media_perms & LLMediaEntry::PERM_ANYONE)) 
  1684.     {
  1685.         return true;
  1686.     }
  1687.     
  1688.     // Group permissions
  1689.     else if (0 != (media_perms & LLMediaEntry::PERM_GROUP) && permGroupOwner())
  1690.     {
  1691.         return true;
  1692.     }
  1693.     
  1694.     // Owner permissions
  1695.     else if (0 != (media_perms & LLMediaEntry::PERM_OWNER) && permYouOwner()) 
  1696.     {
  1697.         return true;
  1698.     }
  1699.     
  1700.     return false;
  1701.     
  1702. }
  1703. void LLVOVolume::mediaNavigated(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, std::string new_location)
  1704. {
  1705. bool block_navigation = false;
  1706. // FIXME: if/when we allow the same media impl to be used by multiple faces, the logic here will need to be fixed
  1707. // to deal with multiple face indices.
  1708. int face_index = getFaceIndexWithMediaImpl(impl, -1);
  1709. // Find the media entry for this navigate
  1710. LLMediaEntry* mep = NULL;
  1711. LLTextureEntry *te = getTE(face_index);
  1712. if(te)
  1713. {
  1714. mep = te->getMediaData();
  1715. }
  1716. if(mep)
  1717. {
  1718. if(!mep->checkCandidateUrl(new_location))
  1719. {
  1720. block_navigation = true;
  1721. }
  1722. if (!block_navigation && !hasMediaPermission(mep, MEDIA_PERM_INTERACT))
  1723. {
  1724. block_navigation = true;
  1725. }
  1726. }
  1727. else
  1728. {
  1729. llwarns << "Couldn't find media entry!" << llendl;
  1730. }
  1731. if(block_navigation)
  1732. {
  1733. llinfos << "blocking navigate to URI " << new_location << llendl;
  1734. // "bounce back" to the current URL from the media entry
  1735. mediaNavigateBounceBack(face_index);
  1736. }
  1737. else if (sObjectMediaNavigateClient)
  1738. {
  1739. llinfos << "broadcasting navigate with URI " << new_location << llendl;
  1740. sObjectMediaNavigateClient->navigate(new LLMediaDataClientObjectImpl(this, false), face_index, new_location);
  1741. }
  1742. }
  1743. void LLVOVolume::mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event)
  1744. {
  1745. switch(event)
  1746. {
  1747. case LLViewerMediaObserver::MEDIA_EVENT_LOCATION_CHANGED:
  1748. {
  1749. switch(impl->getNavState())
  1750. {
  1751. case LLViewerMediaImpl::MEDIANAVSTATE_FIRST_LOCATION_CHANGED:
  1752. {
  1753. // This is the first location changed event after the start of a non-server-directed nav.  It may need to be broadcast or bounced back.
  1754. mediaNavigated(impl, plugin, plugin->getLocation());
  1755. }
  1756. break;
  1757. case LLViewerMediaImpl::MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED:
  1758. // This is the first location changed event after the start of a server-directed nav.  Don't broadcast it.
  1759. llinfos << " NOT broadcasting navigate (server-directed)" << llendl;
  1760. break;
  1761. default:
  1762. // This is a subsequent location-changed due to a redirect.  Don't broadcast.
  1763. llinfos << " NOT broadcasting navigate (redirect)" << llendl;
  1764. break;
  1765. }
  1766. }
  1767. break;
  1768. case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_COMPLETE:
  1769. {
  1770. switch(impl->getNavState())
  1771. {
  1772. case LLViewerMediaImpl::MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED:
  1773. {
  1774. // This is the first location changed event after the start of a non-server-directed nav.  It may need to be broadcast or bounced back.
  1775. mediaNavigated(impl, plugin, plugin->getNavigateURI());
  1776. }
  1777. break;
  1778. case LLViewerMediaImpl::MEDIANAVSTATE_SERVER_COMPLETE_BEFORE_LOCATION_CHANGED:
  1779. // This is the the navigate complete event from a server-directed nav.  Don't broadcast it.
  1780. llinfos << " NOT broadcasting navigate (server-directed)" << llendl;
  1781. break;
  1782. default:
  1783. // For all other states, the navigate should have been handled by LOCATION_CHANGED events already.
  1784. break;
  1785. }
  1786. }
  1787. break;
  1788. default:
  1789. break;
  1790. }
  1791. }
  1792. void LLVOVolume::sendMediaDataUpdate()
  1793. {
  1794.     if (sObjectMediaClient)
  1795. sObjectMediaClient->updateMedia(new LLMediaDataClientObjectImpl(this, false));
  1796. }
  1797. void LLVOVolume::removeMediaImpl(S32 texture_index)
  1798. {
  1799. if(mMediaImplList.size() <= (U32)texture_index || mMediaImplList[texture_index].isNull())
  1800. {
  1801. return ;
  1802. }
  1803. //make the face referencing to mMediaImplList[texture_index] to point back to the old texture.
  1804. if(mDrawable)
  1805. {
  1806. LLFace* facep = mDrawable->getFace(texture_index) ;
  1807. if(facep)
  1808. {
  1809. LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ;
  1810. if(media_tex)
  1811. {
  1812. media_tex->removeMediaFromFace(facep) ;
  1813. }
  1814. }
  1815. }
  1816. //check if some other face(s) of this object reference(s)to this media impl.
  1817. S32 i ;
  1818. S32 end = (S32)mMediaImplList.size() ;
  1819. for(i = 0; i < end ; i++)
  1820. {
  1821. if( i != texture_index && mMediaImplList[i] == mMediaImplList[texture_index])
  1822. {
  1823. break ;
  1824. }
  1825. }
  1826. if(i == end) //this object does not need this media impl.
  1827. {
  1828. mMediaImplList[texture_index]->removeObject(this) ;
  1829. }
  1830. mMediaImplList[texture_index] = NULL ;
  1831. return ;
  1832. }
  1833. void LLVOVolume::addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index)
  1834. {
  1835. if((S32)mMediaImplList.size() < texture_index + 1)
  1836. {
  1837. mMediaImplList.resize(texture_index + 1) ;
  1838. }
  1839. if(mMediaImplList[texture_index].notNull())
  1840. {
  1841. if(mMediaImplList[texture_index] == media_impl)
  1842. {
  1843. return ;
  1844. }
  1845. removeMediaImpl(texture_index) ;
  1846. }
  1847. mMediaImplList[texture_index] = media_impl;
  1848. media_impl->addObject(this) ;
  1849. //add the face to show the media if it is in playing
  1850. if(mDrawable)
  1851. {
  1852. LLFace* facep = mDrawable->getFace(texture_index) ;
  1853. if(facep)
  1854. {
  1855. LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ;
  1856. if(media_tex)
  1857. {
  1858. media_tex->addMediaToFace(facep) ;
  1859. }
  1860. }
  1861. else //the face is not available now, start media on this face later.
  1862. {
  1863. media_impl->setUpdated(TRUE) ;
  1864. }
  1865. }
  1866. return ;
  1867. }
  1868. viewer_media_t LLVOVolume::getMediaImpl(U8 face_id) const
  1869. {
  1870. if(mMediaImplList.size() > face_id)
  1871. {
  1872. return mMediaImplList[face_id];
  1873. }
  1874. return NULL;
  1875. }
  1876. F64 LLVOVolume::getTotalMediaInterest() const
  1877. {
  1878. // If this object is currently focused, this object has "high" interest
  1879. if (LLViewerMediaFocus::getInstance()->getFocusedObjectID() == getID())
  1880. return F64_MAX;
  1881. F64 interest = (F64)-1.0;  // means not interested;
  1882.     
  1883. // If this object is selected, this object has "high" interest, but since 
  1884. // there can be more than one, we still add in calculated impl interest
  1885. // XXX Sadly, 'contains()' doesn't take a const :(
  1886. if (LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this)))
  1887. interest = F64_MAX / 2.0;
  1888. int i = 0;
  1889. const int end = getNumTEs();
  1890. for ( ; i < end; ++i)
  1891. {
  1892. const viewer_media_t &impl = getMediaImpl(i);
  1893. if (!impl.isNull())
  1894. {
  1895. if (interest == (F64)-1.0) interest = (F64)0.0;
  1896. interest += impl->getInterest();
  1897. }
  1898. }
  1899. return interest;
  1900. }
  1901. S32 LLVOVolume::getFaceIndexWithMediaImpl(const LLViewerMediaImpl* media_impl, S32 start_face_id)
  1902. {
  1903. S32 end = (S32)mMediaImplList.size() ;
  1904. for(S32 face_id = start_face_id + 1; face_id < end; face_id++)
  1905. {
  1906. if(mMediaImplList[face_id] == media_impl)
  1907. {
  1908. return face_id ;
  1909. }
  1910. }
  1911. return -1 ;
  1912. }
  1913. //----------------------------------------------------------------------------
  1914. void LLVOVolume::setLightTextureID(LLUUID id)
  1915. {
  1916. if (id.notNull())
  1917. {
  1918. if (!hasLightTexture())
  1919. {
  1920. setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, TRUE, true);
  1921. }
  1922. LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
  1923. if (param_block && param_block->getLightTexture() != id)
  1924. {
  1925. param_block->setLightTexture(id);
  1926. parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true);
  1927. }
  1928. }
  1929. else
  1930. {
  1931. if (hasLightTexture())
  1932. {
  1933. setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, FALSE, true);
  1934. mLightTexture = NULL;
  1935. }
  1936. }
  1937. }
  1938. void LLVOVolume::setSpotLightParams(LLVector3 params)
  1939. {
  1940. LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
  1941. if (param_block && param_block->getParams() != params)
  1942. {
  1943. param_block->setParams(params);
  1944. parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true);
  1945. }
  1946. }
  1947. void LLVOVolume::setIsLight(BOOL is_light)
  1948. {
  1949. if (is_light != getIsLight())
  1950. {
  1951. if (is_light)
  1952. {
  1953. setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT, TRUE, true);
  1954. }
  1955. else
  1956. {
  1957. setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT, FALSE, true);
  1958. }
  1959. if (is_light)
  1960. {
  1961. // Add it to the pipeline mLightSet
  1962. gPipeline.setLight(mDrawable, TRUE);
  1963. }
  1964. else
  1965. {
  1966. // Not a light.  Remove it from the pipeline's light set.
  1967. gPipeline.setLight(mDrawable, FALSE);
  1968. }
  1969. }
  1970. }
  1971. void LLVOVolume::setLightColor(const LLColor3& color)
  1972. {
  1973. LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
  1974. if (param_block)
  1975. {
  1976. if (param_block->getColor() != color)
  1977. {
  1978. param_block->setColor(LLColor4(color, param_block->getColor().mV[3]));
  1979. parameterChanged(LLNetworkData::PARAMS_LIGHT, true);
  1980. gPipeline.markTextured(mDrawable);
  1981. mFaceMappingChanged = TRUE;
  1982. }
  1983. }
  1984. }
  1985. void LLVOVolume::setLightIntensity(F32 intensity)
  1986. {
  1987. LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
  1988. if (param_block)
  1989. {
  1990. if (param_block->getColor().mV[3] != intensity)
  1991. {
  1992. param_block->setColor(LLColor4(LLColor3(param_block->getColor()), intensity));
  1993. parameterChanged(LLNetworkData::PARAMS_LIGHT, true);
  1994. }
  1995. }
  1996. }
  1997. void LLVOVolume::setLightRadius(F32 radius)
  1998. {
  1999. LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
  2000. if (param_block)
  2001. {
  2002. if (param_block->getRadius() != radius)
  2003. {
  2004. param_block->setRadius(radius);
  2005. parameterChanged(LLNetworkData::PARAMS_LIGHT, true);
  2006. }
  2007. }
  2008. }
  2009. void LLVOVolume::setLightFalloff(F32 falloff)
  2010. {
  2011. LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
  2012. if (param_block)
  2013. {
  2014. if (param_block->getFalloff() != falloff)
  2015. {
  2016. param_block->setFalloff(falloff);
  2017. parameterChanged(LLNetworkData::PARAMS_LIGHT, true);
  2018. }
  2019. }
  2020. }
  2021. void LLVOVolume::setLightCutoff(F32 cutoff)
  2022. {
  2023. LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
  2024. if (param_block)
  2025. {
  2026. if (param_block->getCutoff() != cutoff)
  2027. {
  2028. param_block->setCutoff(cutoff);
  2029. parameterChanged(LLNetworkData::PARAMS_LIGHT, true);
  2030. }
  2031. }
  2032. }
  2033. //----------------------------------------------------------------------------
  2034. BOOL LLVOVolume::getIsLight() const
  2035. {
  2036. return getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT);
  2037. }
  2038. LLColor3 LLVOVolume::getLightBaseColor() const
  2039. {
  2040. const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
  2041. if (param_block)
  2042. {
  2043. return LLColor3(param_block->getColor());
  2044. }
  2045. else
  2046. {
  2047. return LLColor3(1,1,1);
  2048. }
  2049. }
  2050. LLColor3 LLVOVolume::getLightColor() const
  2051. {
  2052. const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
  2053. if (param_block)
  2054. {
  2055. return LLColor3(param_block->getColor()) * param_block->getColor().mV[3];
  2056. }
  2057. else
  2058. {
  2059. return LLColor3(1,1,1);
  2060. }
  2061. }
  2062. LLUUID LLVOVolume::getLightTextureID() const
  2063. {
  2064. if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
  2065. {
  2066. const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
  2067. if (param_block)
  2068. {
  2069. return param_block->getLightTexture();
  2070. }
  2071. }
  2072. return LLUUID::null;
  2073. }
  2074. LLVector3 LLVOVolume::getSpotLightParams() const
  2075. {
  2076. if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
  2077. {
  2078. const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
  2079. if (param_block)
  2080. {
  2081. return param_block->getParams();
  2082. }
  2083. }
  2084. return LLVector3();
  2085. }
  2086. F32 LLVOVolume::getSpotLightPriority() const
  2087. {
  2088. return mSpotLightPriority;
  2089. }
  2090. void LLVOVolume::updateSpotLightPriority()
  2091. {
  2092. LLVector3 pos = mDrawable->getPositionAgent();
  2093. LLVector3 at(0,0,-1);
  2094. at *= getRenderRotation();
  2095. F32 r = getLightRadius()*0.5f;
  2096. pos += at * r;
  2097. at = LLViewerCamera::getInstance()->getAtAxis();
  2098. pos -= at * r;
  2099. mSpotLightPriority = gPipeline.calcPixelArea(pos, LLVector3(r,r,r), *LLViewerCamera::getInstance());
  2100. if (mLightTexture.notNull())
  2101. {
  2102. mLightTexture->addTextureStats(mSpotLightPriority);
  2103. mLightTexture->setBoostLevel(LLViewerTexture::BOOST_CLOUDS);
  2104. }
  2105. }
  2106. LLViewerTexture* LLVOVolume::getLightTexture()
  2107. {
  2108. LLUUID id = getLightTextureID();
  2109. if (id.notNull())
  2110. {
  2111. if (mLightTexture.isNull() || id != mLightTexture->getID())
  2112. {
  2113. mLightTexture = LLViewerTextureManager::getFetchedTexture(id);
  2114. }
  2115. }
  2116. else
  2117. {
  2118. mLightTexture = NULL;
  2119. }
  2120. return mLightTexture;
  2121. }
  2122. F32 LLVOVolume::getLightIntensity() const
  2123. {
  2124. const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
  2125. if (param_block)
  2126. {
  2127. return param_block->getColor().mV[3];
  2128. }
  2129. else
  2130. {
  2131. return 1.f;
  2132. }
  2133. }
  2134. F32 LLVOVolume::getLightRadius() const
  2135. {
  2136. const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
  2137. if (param_block)
  2138. {
  2139. return param_block->getRadius();
  2140. }
  2141. else
  2142. {
  2143. return 0.f;
  2144. }
  2145. }
  2146. F32 LLVOVolume::getLightFalloff() const
  2147. {
  2148. const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
  2149. if (param_block)
  2150. {
  2151. return param_block->getFalloff();
  2152. }
  2153. else
  2154. {
  2155. return 0.f;
  2156. }
  2157. }
  2158. F32 LLVOVolume::getLightCutoff() const
  2159. {
  2160. const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
  2161. if (param_block)
  2162. {
  2163. return param_block->getCutoff();
  2164. }
  2165. else
  2166. {
  2167. return 0.f;
  2168. }
  2169. }
  2170. U32 LLVOVolume::getVolumeInterfaceID() const
  2171. {
  2172. if (mVolumeImpl)
  2173. {
  2174. return mVolumeImpl->getID();
  2175. }
  2176. return 0;
  2177. }
  2178. BOOL LLVOVolume::isFlexible() const
  2179. {
  2180. if (getParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE))
  2181. {
  2182. LLVolume* volume = getVolume();
  2183. if (volume && volume->getParams().getPathParams().getCurveType() != LL_PCODE_PATH_FLEXIBLE)
  2184. {
  2185. LLVolumeParams volume_params = getVolume()->getParams();
  2186. U8 profile_and_hole = volume_params.getProfileParams().getCurveType();
  2187. volume_params.setType(profile_and_hole, LL_PCODE_PATH_FLEXIBLE);
  2188. }
  2189. return TRUE;
  2190. }
  2191. else
  2192. {
  2193. return FALSE;
  2194. }
  2195. }
  2196. BOOL LLVOVolume::isSculpted() const
  2197. {
  2198. if (getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
  2199. {
  2200. return TRUE;
  2201. }
  2202. return FALSE;
  2203. }
  2204. BOOL LLVOVolume::hasLightTexture() const
  2205. {
  2206. if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
  2207. {
  2208. return TRUE;
  2209. }
  2210. return FALSE;
  2211. }
  2212. BOOL LLVOVolume::isVolumeGlobal() const
  2213. {
  2214. if (mVolumeImpl)
  2215. {
  2216. return mVolumeImpl->isVolumeGlobal() ? TRUE : FALSE;
  2217. }
  2218. return FALSE;
  2219. }
  2220. BOOL LLVOVolume::canBeFlexible() const
  2221. {
  2222. U8 path = getVolume()->getParams().getPathParams().getCurveType();
  2223. return (path == LL_PCODE_PATH_FLEXIBLE || path == LL_PCODE_PATH_LINE);
  2224. }
  2225. BOOL LLVOVolume::setIsFlexible(BOOL is_flexible)
  2226. {
  2227. BOOL res = FALSE;
  2228. BOOL was_flexible = isFlexible();
  2229. LLVolumeParams volume_params;
  2230. if (is_flexible)
  2231. {
  2232. if (!was_flexible)
  2233. {
  2234. volume_params = getVolume()->getParams();
  2235. U8 profile_and_hole = volume_params.getProfileParams().getCurveType();
  2236. volume_params.setType(profile_and_hole, LL_PCODE_PATH_FLEXIBLE);
  2237. res = TRUE;
  2238. setFlags(FLAGS_USE_PHYSICS, FALSE);
  2239. setFlags(FLAGS_PHANTOM, TRUE);
  2240. setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, TRUE, true);
  2241. if (mDrawable)
  2242. {
  2243. mDrawable->makeActive();
  2244. }
  2245. }
  2246. }
  2247. else
  2248. {
  2249. if (was_flexible)
  2250. {
  2251. volume_params = getVolume()->getParams();
  2252. U8 profile_and_hole = volume_params.getProfileParams().getCurveType();
  2253. volume_params.setType(profile_and_hole, LL_PCODE_PATH_LINE);
  2254. res = TRUE;
  2255. setFlags(FLAGS_PHANTOM, FALSE);
  2256. setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, FALSE, true);
  2257. }
  2258. }
  2259. if (res)
  2260. {
  2261. res = setVolume(volume_params, 1);
  2262. if (res)
  2263. {
  2264. markForUpdate(TRUE);
  2265. }
  2266. }
  2267. return res;
  2268. }
  2269. //----------------------------------------------------------------------------
  2270. void LLVOVolume::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point)
  2271. {
  2272. LLVolume *volume = getVolume();
  2273. if (volume)
  2274. {
  2275. LLVector3 view_vector;
  2276. view_vector = view_point; 
  2277. //transform view vector into volume space
  2278. view_vector -= getRenderPosition();
  2279. mDrawable->mDistanceWRTCamera = view_vector.length();
  2280. LLQuaternion worldRot = getRenderRotation();
  2281. view_vector = view_vector * ~worldRot;
  2282. if (!isVolumeGlobal())
  2283. {
  2284. LLVector3 objScale = getScale();
  2285. LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]);
  2286. view_vector.scaleVec(invObjScale);
  2287. }
  2288. updateRelativeXform();
  2289. LLMatrix4 trans_mat = mRelativeXform;
  2290. if (mDrawable->isStatic())
  2291. {
  2292. trans_mat.translate(getRegion()->getOriginAgent());
  2293. }
  2294. volume->generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals, nodep->mSilhouetteSegments, view_vector, trans_mat, mRelativeXformInvTrans, nodep->getTESelectMask());
  2295. nodep->mSilhouetteExists = TRUE;
  2296. }
  2297. }
  2298. void LLVOVolume::deleteFaces()
  2299. {
  2300. S32 face_count = mNumFaces;
  2301. if (mDrawable.notNull())
  2302. {
  2303. mDrawable->deleteFaces(0, face_count);
  2304. }
  2305. mNumFaces = 0;
  2306. }
  2307. void LLVOVolume::updateRadius()
  2308. {
  2309. if (mDrawable.isNull())
  2310. {
  2311. return;
  2312. }
  2313. mVObjRadius = getScale().length();
  2314. mDrawable->setRadius(mVObjRadius);
  2315. }
  2316. BOOL LLVOVolume::isAttachment() const
  2317. {
  2318. if (mState == 0)
  2319. {
  2320. return FALSE;
  2321. }
  2322. else
  2323. {
  2324. return TRUE;
  2325. }
  2326. }
  2327. BOOL LLVOVolume::isHUDAttachment() const
  2328. {
  2329. // *NOTE: we assume hud attachment points are in defined range
  2330. // since this range is constant for backwards compatibility
  2331. // reasons this is probably a reasonable assumption to make
  2332. S32 attachment_id = ATTACHMENT_ID_FROM_STATE(mState);
  2333. return ( attachment_id >= 31 && attachment_id <= 38 );
  2334. }
  2335. const LLMatrix4 LLVOVolume::getRenderMatrix() const
  2336. {
  2337. if (mDrawable->isActive() && !mDrawable->isRoot())
  2338. {
  2339. return mDrawable->getParent()->getWorldMatrix();
  2340. }
  2341. return mDrawable->getWorldMatrix();
  2342. }
  2343. // Returns a base cost and adds textures to passed in set.
  2344. // total cost is returned value + 5 * size of the resulting set.
  2345. // Cannot include cost of textures, as they may be re-used in linked
  2346. // children, and cost should only be increased for unique textures  -Nyx
  2347. U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const
  2348. {
  2349. // base cost of each prim should be 10 points
  2350. static const U32 ARC_PRIM_COST = 10;
  2351. // per-prim costs
  2352. static const U32 ARC_INVISI_COST = 1;
  2353. static const U32 ARC_SHINY_COST = 1;
  2354. static const U32 ARC_GLOW_COST = 1;
  2355. static const U32 ARC_FLEXI_COST = 8;
  2356. static const U32 ARC_PARTICLE_COST = 16;
  2357. static const U32 ARC_BUMP_COST = 4;
  2358. // per-face costs
  2359. static const U32 ARC_PLANAR_COST = 1;
  2360. static const U32 ARC_ANIM_TEX_COST = 4;
  2361. static const U32 ARC_ALPHA_COST = 4;
  2362. U32 shame = ARC_PRIM_COST;
  2363. U32 invisi = 0;
  2364. U32 shiny = 0;
  2365. U32 glow = 0;
  2366. U32 alpha = 0;
  2367. U32 flexi = 0;
  2368. U32 animtex = 0;
  2369. U32 particles = 0;
  2370. U32 scale = 0;
  2371. U32 bump = 0;
  2372. U32 planar = 0;
  2373. if (isFlexible())
  2374. {
  2375. flexi = 1;
  2376. }
  2377. if (isParticleSource())
  2378. {
  2379. particles = 1;
  2380. }
  2381. const LLVector3& sc = getScale();
  2382. scale += (U32) sc.mV[0] + (U32) sc.mV[1] + (U32) sc.mV[2];
  2383. const LLDrawable* drawablep = mDrawable;
  2384. if (isSculpted())
  2385. {
  2386. const LLSculptParams *sculpt_params = (LLSculptParams *) getParameterEntry(LLNetworkData::PARAMS_SCULPT);
  2387. LLUUID sculpt_id = sculpt_params->getSculptTexture();
  2388. textures.insert(sculpt_id);
  2389. }
  2390. for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
  2391. {
  2392. const LLFace* face = drawablep->getFace(i);
  2393. const LLTextureEntry* te = face->getTextureEntry();
  2394. const LLViewerTexture* img = face->getTexture();
  2395. if (img)
  2396. {
  2397. textures.insert(img->getID());
  2398. }
  2399. if (face->getPoolType() == LLDrawPool::POOL_ALPHA)
  2400. {
  2401. alpha++;
  2402. }
  2403. else if (img && img->getPrimaryFormat() == GL_ALPHA)
  2404. {
  2405. invisi = 1;
  2406. }
  2407. if (te)
  2408. {
  2409. if (te->getBumpmap())
  2410. {
  2411. bump = 1;
  2412. }
  2413. if (te->getShiny())
  2414. {
  2415. shiny = 1;
  2416. }
  2417. if (te->getGlow() > 0.f)
  2418. {
  2419. glow = 1;
  2420. }
  2421. if (face->mTextureMatrix != NULL)
  2422. {
  2423. animtex++;
  2424. }
  2425. if (te->getTexGen())
  2426. {
  2427. planar++;
  2428. }
  2429. }
  2430. }
  2431. shame += invisi * ARC_INVISI_COST;
  2432. shame += shiny * ARC_SHINY_COST;
  2433. shame += glow * ARC_GLOW_COST;
  2434. shame += alpha * ARC_ALPHA_COST;
  2435. shame += flexi * ARC_FLEXI_COST;
  2436. shame += animtex * ARC_ANIM_TEX_COST;
  2437. shame += particles * ARC_PARTICLE_COST;
  2438. shame += bump * ARC_BUMP_COST;
  2439. shame += planar * ARC_PLANAR_COST;
  2440. shame += scale;
  2441. LLViewerObject::const_child_list_t& child_list = getChildren();
  2442. for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
  2443.  iter != child_list.end(); 
  2444.  ++iter)
  2445. {
  2446. const LLViewerObject* child_objectp = *iter;
  2447. const LLDrawable* child_drawablep = child_objectp->mDrawable;
  2448. if (child_drawablep)
  2449. {
  2450. const LLVOVolume* child_volumep = child_drawablep->getVOVolume();
  2451. if (child_volumep)
  2452. {
  2453. shame += child_volumep->getRenderCost(textures);
  2454. }
  2455. }
  2456. }
  2457. return shame;
  2458. }
  2459. //static
  2460. void LLVOVolume::preUpdateGeom()
  2461. {
  2462. sNumLODChanges = 0;
  2463. }
  2464. void LLVOVolume::parameterChanged(U16 param_type, bool local_origin)
  2465. {
  2466. LLViewerObject::parameterChanged(param_type, local_origin);
  2467. }
  2468. void LLVOVolume::parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin)
  2469. {
  2470. LLViewerObject::parameterChanged(param_type, data, in_use, local_origin);
  2471. if (mVolumeImpl)
  2472. {
  2473. mVolumeImpl->onParameterChanged(param_type, data, in_use, local_origin);
  2474. }
  2475. if (mDrawable.notNull())
  2476. {
  2477. BOOL is_light = getIsLight();
  2478. if (is_light != mDrawable->isState(LLDrawable::LIGHT))
  2479. {
  2480. gPipeline.setLight(mDrawable, is_light);
  2481. }
  2482. }
  2483. }
  2484. void LLVOVolume::setSelected(BOOL sel)
  2485. {
  2486. LLViewerObject::setSelected(sel);
  2487. if (mDrawable.notNull())
  2488. {
  2489. markForUpdate(TRUE);
  2490. }
  2491. }
  2492. void LLVOVolume::updateSpatialExtents(LLVector3& newMin, LLVector3& newMax)
  2493. {
  2494. }
  2495. F32 LLVOVolume::getBinRadius()
  2496. {
  2497. F32 radius;
  2498. const LLVector3* ext = mDrawable->getSpatialExtents();
  2499. BOOL shrink_wrap = mDrawable->isAnimating();
  2500. BOOL alpha_wrap = FALSE;
  2501. if (!isHUDAttachment())
  2502. {
  2503. for (S32 i = 0; i < mDrawable->getNumFaces(); i++)
  2504. {
  2505. LLFace* face = mDrawable->getFace(i);
  2506. if (face->getPoolType() == LLDrawPool::POOL_ALPHA &&
  2507. (!LLPipeline::sFastAlpha || 
  2508. face->getFaceColor().mV[3] != 1.f ||
  2509. !face->getTexture()->getIsAlphaMask()))
  2510. {
  2511. alpha_wrap = TRUE;
  2512. break;
  2513. }
  2514. }
  2515. }
  2516. else
  2517. {
  2518. shrink_wrap = FALSE;
  2519. }
  2520. if (alpha_wrap)
  2521. {
  2522. LLVector3 bounds = getScale();
  2523. radius = llmin(bounds.mV[1], bounds.mV[2]);
  2524. radius = llmin(radius, bounds.mV[0]);
  2525. radius *= 0.5f;
  2526. }
  2527. else if (shrink_wrap)
  2528. {
  2529. radius = (ext[1]-ext[0]).length()*0.5f;
  2530. }
  2531. else if (mDrawable->isStatic())
  2532. {
  2533. /*if (mDrawable->getRadius() < 2.0f)
  2534. {
  2535. radius = 16.f;
  2536. }
  2537. else
  2538. {
  2539. radius = llmax(mDrawable->getRadius(), 32.f);
  2540. }*/
  2541. radius = (((S32) mDrawable->getRadius())/2+1)*8;
  2542. }
  2543. else if (mDrawable->getVObj()->isAttachment())
  2544. {
  2545. radius = (((S32) (mDrawable->getRadius()*4)+1))*2;
  2546. }
  2547. else
  2548. {
  2549. radius = 8.f;
  2550. }
  2551. return llclamp(radius, 0.5f, 256.f);
  2552. }
  2553. const LLVector3 LLVOVolume::getPivotPositionAgent() const
  2554. {
  2555. if (mVolumeImpl)
  2556. {
  2557. return mVolumeImpl->getPivotPosition();
  2558. }
  2559. return LLViewerObject::getPivotPositionAgent();
  2560. }
  2561. void LLVOVolume::onShift(const LLVector3 &shift_vector)
  2562. {
  2563. if (mVolumeImpl)
  2564. {
  2565. mVolumeImpl->onShift(shift_vector);
  2566. }
  2567. updateRelativeXform();
  2568. }
  2569. const LLMatrix4& LLVOVolume::getWorldMatrix(LLXformMatrix* xform) const
  2570. {
  2571. if (mVolumeImpl)
  2572. {
  2573. return mVolumeImpl->getWorldMatrix(xform);
  2574. }
  2575. return xform->getWorldMatrix();
  2576. }
  2577. LLVector3 LLVOVolume::agentPositionToVolume(const LLVector3& pos) const
  2578. {
  2579. LLVector3 ret = pos - getRenderPosition();
  2580. ret = ret * ~getRenderRotation();
  2581. LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale();
  2582. LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]);
  2583. ret.scaleVec(invObjScale);
  2584. return ret;
  2585. }
  2586. LLVector3 LLVOVolume::agentDirectionToVolume(const LLVector3& dir) const
  2587. {
  2588. LLVector3 ret = dir * ~getRenderRotation();
  2589. LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale();
  2590. ret.scaleVec(objScale);
  2591. return ret;
  2592. }
  2593. LLVector3 LLVOVolume::volumePositionToAgent(const LLVector3& dir) const
  2594. {
  2595. LLVector3 ret = dir;
  2596. LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale();
  2597. ret.scaleVec(objScale);
  2598. ret = ret * getRenderRotation();
  2599. ret += getRenderPosition();
  2600. return ret;
  2601. }
  2602. LLVector3 LLVOVolume::volumeDirectionToAgent(const LLVector3& dir) const
  2603. {
  2604. LLVector3 ret = dir;
  2605. LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale();
  2606. LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]);
  2607. ret.scaleVec(invObjScale);
  2608. ret = ret * getRenderRotation();
  2609. return ret;
  2610. }
  2611. BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
  2612.   LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
  2613. {
  2614. if (!mbCanSelect 
  2615. || mDrawable->isDead() 
  2616. || !gPipeline.hasRenderType(mDrawable->getRenderType()))
  2617. {
  2618. return FALSE;
  2619. }
  2620. BOOL ret = FALSE;
  2621. LLVolume* volume = getVolume();
  2622. if (volume)
  2623. {
  2624. LLVector3 v_start, v_end, v_dir;
  2625. v_start = agentPositionToVolume(start);
  2626. v_end = agentPositionToVolume(end);
  2627. LLVector3 p;
  2628. LLVector3 n;
  2629. LLVector2 tc;
  2630. LLVector3 bn;
  2631. if (intersection != NULL)
  2632. {
  2633. p = *intersection;
  2634. }
  2635. if (tex_coord != NULL)
  2636. {
  2637. tc = *tex_coord;
  2638. }
  2639. if (normal != NULL)
  2640. {
  2641. n = *normal;
  2642. }
  2643. if (bi_normal != NULL)
  2644. {
  2645. bn = *bi_normal;
  2646. }
  2647. S32 face_hit = -1;
  2648. S32 start_face, end_face;
  2649. if (face == -1)
  2650. {
  2651. start_face = 0;
  2652. end_face = volume->getNumVolumeFaces();
  2653. }
  2654. else
  2655. {
  2656. start_face = face;
  2657. end_face = face+1;
  2658. }
  2659. for (S32 i = start_face; i < end_face; ++i)
  2660. {
  2661. face_hit = volume->lineSegmentIntersect(v_start, v_end, i,
  2662. &p, &tc, &n, &bn);
  2663. if (face_hit >= 0 && mDrawable->getNumFaces() > face_hit)
  2664. {
  2665. LLFace* face = mDrawable->getFace(face_hit);
  2666. if (pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n)))
  2667. {
  2668. v_end = p;
  2669. if (face_hitp != NULL)
  2670. {
  2671. *face_hitp = face_hit;
  2672. }
  2673. if (intersection != NULL)
  2674. {
  2675. *intersection = volumePositionToAgent(p);  // must map back to agent space
  2676. }
  2677. if (normal != NULL)
  2678. {
  2679. *normal = volumeDirectionToAgent(n);
  2680. (*normal).normVec();
  2681. }
  2682. if (bi_normal != NULL)
  2683. {
  2684. *bi_normal = volumeDirectionToAgent(bn);
  2685. (*bi_normal).normVec();
  2686. }
  2687. if (tex_coord != NULL)
  2688. {
  2689. *tex_coord = tc;
  2690. }
  2691. ret = TRUE;
  2692. }
  2693. }
  2694. }
  2695. }
  2696. return ret;
  2697. }
  2698. U32 LLVOVolume::getPartitionType() const
  2699. {
  2700. if (isHUDAttachment())
  2701. {
  2702. return LLViewerRegion::PARTITION_HUD;
  2703. }
  2704. return LLViewerRegion::PARTITION_VOLUME;
  2705. }
  2706. LLVolumePartition::LLVolumePartition()
  2707. : LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB)
  2708. {
  2709. mLODPeriod = 32;
  2710. mDepthMask = FALSE;
  2711. mDrawableType = LLPipeline::RENDER_TYPE_VOLUME;
  2712. mPartitionType = LLViewerRegion::PARTITION_VOLUME;
  2713. mSlopRatio = 0.25f;
  2714. mBufferUsage = GL_DYNAMIC_DRAW_ARB;
  2715. }
  2716. LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep)
  2717. : LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK)
  2718. {
  2719. mDepthMask = FALSE;
  2720. mLODPeriod = 32;
  2721. mDrawableType = LLPipeline::RENDER_TYPE_VOLUME;
  2722. mPartitionType = LLViewerRegion::PARTITION_BRIDGE;
  2723. mBufferUsage = GL_DYNAMIC_DRAW_ARB;
  2724. mSlopRatio = 0.25f;
  2725. }
  2726. void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type)
  2727. {
  2728. LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
  2729. if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects)
  2730. {
  2731. return;
  2732. }
  2733. //add face to drawmap
  2734. LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[type];
  2735. S32 idx = draw_vec.size()-1;
  2736. BOOL fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) ||
  2737.   (type == LLRenderPass::PASS_INVISIBLE) ||
  2738.   (type == LLRenderPass::PASS_ALPHA ? facep->isState(LLFace::FULLBRIGHT) : FALSE);
  2739. if (!fullbright && type != LLRenderPass::PASS_GLOW && !facep->mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL))
  2740. {
  2741. llwarns << "Non fullbright face has no normals!" << llendl;
  2742. return;
  2743. }
  2744. const LLMatrix4* tex_mat = NULL;
  2745. if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE)
  2746. {
  2747. tex_mat = facep->mTextureMatrix;
  2748. }
  2749. const LLMatrix4* model_mat = NULL;
  2750. LLDrawable* drawable = facep->getDrawable();
  2751. if (drawable->isActive())
  2752. {
  2753. model_mat = &(drawable->getRenderMatrix());
  2754. }
  2755. else
  2756. {
  2757. model_mat = &(drawable->getRegion()->mRenderMatrix);
  2758. }
  2759. U8 bump = (type == LLRenderPass::PASS_BUMP ? facep->getTextureEntry()->getBumpmap() : 0);
  2760. LLViewerTexture* tex = facep->getTexture();
  2761. U8 glow = 0;
  2762. if (type == LLRenderPass::PASS_GLOW)
  2763. {
  2764. glow = (U8) (facep->getTextureEntry()->getGlow() * 255);
  2765. }
  2766. if (facep->mVertexBuffer.isNull())
  2767. {
  2768. llerrs << "WTF?" << llendl;
  2769. }
  2770. if (idx >= 0 && 
  2771. draw_vec[idx]->mVertexBuffer == facep->mVertexBuffer &&
  2772. draw_vec[idx]->mEnd == facep->getGeomIndex()-1 &&
  2773. (LLPipeline::sTextureBindTest || draw_vec[idx]->mTexture == tex) &&
  2774. #if LL_DARWIN
  2775. draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange &&
  2776. draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&
  2777. #endif
  2778. draw_vec[idx]->mGlowColor.mV[3] == glow &&
  2779. draw_vec[idx]->mFullbright == fullbright &&
  2780. draw_vec[idx]->mBump == bump &&
  2781. draw_vec[idx]->mTextureMatrix == tex_mat &&
  2782. draw_vec[idx]->mModelMatrix == model_mat)
  2783. {
  2784. draw_vec[idx]->mCount += facep->getIndicesCount();
  2785. draw_vec[idx]->mEnd += facep->getGeomCount();
  2786. draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize());
  2787. validate_draw_info(*draw_vec[idx]);
  2788. update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[0]);
  2789. update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[1]);
  2790. }
  2791. else
  2792. {
  2793. U32 start = facep->getGeomIndex();
  2794. U32 end = start + facep->getGeomCount()-1;
  2795. U32 offset = facep->getIndicesStart();
  2796. U32 count = facep->getIndicesCount();
  2797. LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset, tex, 
  2798. facep->mVertexBuffer, fullbright, bump); 
  2799. draw_info->mGroup = group;
  2800. draw_info->mVSize = facep->getVirtualSize();
  2801. draw_vec.push_back(draw_info);
  2802. draw_info->mTextureMatrix = tex_mat;
  2803. draw_info->mModelMatrix = model_mat;
  2804. draw_info->mGlowColor.setVec(0,0,0,glow);
  2805. if (type == LLRenderPass::PASS_ALPHA)
  2806. { //for alpha sorting
  2807. facep->setDrawInfo(draw_info);
  2808. }
  2809. draw_info->mExtents[0] = facep->mExtents[0];
  2810. draw_info->mExtents[1] = facep->mExtents[1];
  2811. validate_draw_info(*draw_info);
  2812. }
  2813. }
  2814. void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group)
  2815. {
  2816. }
  2817. static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume");
  2818. static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt");
  2819. void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
  2820. {
  2821. llpushcallstacks ;
  2822. if (group->changeLOD())
  2823. {
  2824. group->mLastUpdateDistance = group->mDistance;
  2825. }
  2826. group->mLastUpdateViewAngle = group->mViewAngle;
  2827. if (!group->isState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY))
  2828. {
  2829. if (group->isState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate)
  2830. {
  2831. LLFastTimer ftm(FTM_REBUILD_VBO);
  2832. LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB);
  2833. rebuildMesh(group);
  2834. }
  2835. return;
  2836. }
  2837. group->mBuilt = 1.f;
  2838. LLFastTimer ftm(FTM_REBUILD_VBO);
  2839. LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB);
  2840. group->clearDrawMap();
  2841. mFaceList.clear();
  2842. std::vector<LLFace*> fullbright_faces;
  2843. std::vector<LLFace*> bump_faces;
  2844. std::vector<LLFace*> simple_faces;
  2845. std::vector<LLFace*> alpha_faces;
  2846. U32 useage = group->mSpatialPartition->mBufferUsage;
  2847. U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask);
  2848. U32 max_total = (gSavedSettings.getS32("RenderMaxNodeSize")*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask);
  2849. max_vertices = llmin(max_vertices, (U32) 65535);
  2850. U32 cur_total = 0;
  2851. //get all the faces into a list
  2852. for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
  2853. {
  2854. LLDrawable* drawablep = *drawable_iter;
  2855. if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
  2856. {
  2857. continue;
  2858. }
  2859. if (drawablep->isAnimating())
  2860. { //fall back to stream draw for animating verts
  2861. useage = GL_STREAM_DRAW_ARB;
  2862. }
  2863. LLVOVolume* vobj = drawablep->getVOVolume();
  2864. llassert_always(vobj);
  2865. vobj->updateTextureVirtualSize();
  2866. vobj->preRebuild();
  2867. drawablep->clearState(LLDrawable::HAS_ALPHA);
  2868. //for each face
  2869. for (S32 i = 0; i < drawablep->getNumFaces(); i++)
  2870. {
  2871. //sum up face verts and indices
  2872. drawablep->updateFaceSize(i);
  2873. LLFace* facep = drawablep->getFace(i);
  2874. if (cur_total > max_total)
  2875. {
  2876. facep->mVertexBuffer = NULL;
  2877. facep->mLastVertexBuffer = NULL;
  2878. continue;
  2879. }
  2880. cur_total += facep->getGeomCount();
  2881. if (facep->hasGeometry() && facep->mPixelArea > FORCE_CULL_AREA)
  2882. {
  2883. const LLTextureEntry* te = facep->getTextureEntry();
  2884. LLViewerTexture* tex = facep->getTexture();
  2885. if (facep->isState(LLFace::TEXTURE_ANIM))
  2886. {
  2887. if (!vobj->mTexAnimMode)
  2888. {
  2889. facep->clearState(LLFace::TEXTURE_ANIM);
  2890. }
  2891. }
  2892. BOOL force_simple = (facep->mPixelArea < FORCE_SIMPLE_RENDER_AREA);
  2893. U32 type = gPipeline.getPoolTypeFromTE(te, tex);
  2894. if (type != LLDrawPool::POOL_ALPHA && force_simple)
  2895. {
  2896. type = LLDrawPool::POOL_SIMPLE;
  2897. }
  2898. facep->setPoolType(type);
  2899. if (vobj->isHUDAttachment())
  2900. {
  2901. facep->setState(LLFace::FULLBRIGHT);
  2902. }
  2903. if (vobj->mTextureAnimp && vobj->mTexAnimMode)
  2904. {
  2905. if (vobj->mTextureAnimp->mFace <= -1)
  2906. {
  2907. S32 face;
  2908. for (face = 0; face < vobj->getNumTEs(); face++)
  2909. {
  2910. drawablep->getFace(face)->setState(LLFace::TEXTURE_ANIM);
  2911. }
  2912. }
  2913. else if (vobj->mTextureAnimp->mFace < vobj->getNumTEs())
  2914. {
  2915. drawablep->getFace(vobj->mTextureAnimp->mFace)->setState(LLFace::TEXTURE_ANIM);
  2916. }
  2917. }
  2918. if (type == LLDrawPool::POOL_ALPHA)
  2919. {
  2920. if (LLPipeline::sFastAlpha &&
  2921.     (te->getColor().mV[VW] == 1.0f) &&
  2922.     (!te->getFullbright()) && // hack: alpha masking renders fullbright faces invisible, need to figure out why - for now, avoid
  2923.     facep->getTexture()->getIsAlphaMask())
  2924. { //can be treated as alpha mask
  2925. simple_faces.push_back(facep);
  2926. }
  2927. else
  2928. {
  2929. drawablep->setState(LLDrawable::HAS_ALPHA);
  2930. alpha_faces.push_back(facep);
  2931. }
  2932. }
  2933. else
  2934. {
  2935. if (drawablep->isState(LLDrawable::REBUILD_VOLUME))
  2936. {
  2937. facep->mLastUpdateTime = gFrameTimeSeconds;
  2938. }
  2939. if (gPipeline.canUseWindLightShadersOnObjects()
  2940. && LLPipeline::sRenderBump)
  2941. {
  2942. if (te->getBumpmap())
  2943. { //needs normal + binormal
  2944. bump_faces.push_back(facep);
  2945. }
  2946. else if (te->getShiny() || !te->getFullbright())
  2947. { //needs normal
  2948. simple_faces.push_back(facep);
  2949. }
  2950. else 
  2951. { //doesn't need normal
  2952. facep->setState(LLFace::FULLBRIGHT);
  2953. fullbright_faces.push_back(facep);
  2954. }
  2955. }
  2956. else
  2957. {
  2958. if (te->getBumpmap() && LLPipeline::sRenderBump)
  2959. { //needs normal + binormal
  2960. bump_faces.push_back(facep);
  2961. }
  2962. else if ((te->getShiny() && LLPipeline::sRenderBump) ||
  2963. !te->getFullbright())
  2964. { //needs normal
  2965. simple_faces.push_back(facep);
  2966. }
  2967. else 
  2968. { //doesn't need normal
  2969. facep->setState(LLFace::FULLBRIGHT);
  2970. fullbright_faces.push_back(facep);
  2971. }
  2972. }
  2973. }
  2974. }
  2975. else
  2976. { //face has no renderable geometry
  2977. facep->mVertexBuffer = NULL;
  2978. facep->mLastVertexBuffer = NULL;
  2979. }
  2980. }
  2981. }
  2982. group->mBufferUsage = useage;
  2983. //PROCESS NON-ALPHA FACES
  2984. U32 simple_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
  2985. U32 alpha_mask = simple_mask | 0x80000000; //hack to give alpha verts their own VBO
  2986. U32 bump_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
  2987. U32 fullbright_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
  2988. if (LLPipeline::sRenderDeferred)
  2989. {
  2990. bump_mask |= LLVertexBuffer::MAP_BINORMAL;
  2991. }
  2992. genDrawInfo(group, simple_mask, simple_faces);
  2993. genDrawInfo(group, bump_mask, bump_faces);
  2994. genDrawInfo(group, fullbright_mask, fullbright_faces);
  2995. genDrawInfo(group, alpha_mask, alpha_faces, TRUE);
  2996. if (!LLPipeline::sDelayVBUpdate)
  2997. {
  2998. //drawables have been rebuilt, clear rebuild status
  2999. for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
  3000. {
  3001. LLDrawable* drawablep = *drawable_iter;
  3002. drawablep->clearState(LLDrawable::REBUILD_ALL);
  3003. }
  3004. }
  3005. group->mLastUpdateTime = gFrameTimeSeconds;
  3006. group->mBuilt = 1.f;
  3007. group->clearState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY);
  3008. if (LLPipeline::sDelayVBUpdate)
  3009. {
  3010. group->setState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
  3011. }
  3012. mFaceList.clear();
  3013. }
  3014. static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM("Volume Geometry");
  3015. void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
  3016. {
  3017. llpushcallstacks ;
  3018. llassert(group);
  3019. if (group && group->isState(LLSpatialGroup::MESH_DIRTY) && !group->isState(LLSpatialGroup::GEOM_DIRTY))
  3020. {
  3021. LLFastTimer tm(FTM_VOLUME_GEOM);
  3022. S32 num_mapped_veretx_buffer = LLVertexBuffer::sMappedCount ;
  3023. group->mBuilt = 1.f;
  3024. for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
  3025. {
  3026. LLDrawable* drawablep = *drawable_iter;
  3027. if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
  3028. {
  3029. continue;
  3030. }
  3031. if (drawablep->isState(LLDrawable::REBUILD_ALL))
  3032. {
  3033. LLVOVolume* vobj = drawablep->getVOVolume();
  3034. vobj->preRebuild();
  3035. LLVolume* volume = vobj->getVolume();
  3036. for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
  3037. {
  3038. LLFace* face = drawablep->getFace(i);
  3039. if (face && face->mVertexBuffer.notNull())
  3040. {
  3041. face->getGeometryVolume(*volume, face->getTEOffset(), 
  3042. vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex());
  3043. }
  3044. }
  3045. drawablep->clearState(LLDrawable::REBUILD_ALL);
  3046. }
  3047. }
  3048. //unmap all the buffers
  3049. for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i)
  3050. {
  3051. LLSpatialGroup::buffer_texture_map_t& map = i->second;
  3052. for (LLSpatialGroup::buffer_texture_map_t::iterator j = map.begin(); j != map.end(); ++j)
  3053. {
  3054. LLSpatialGroup::buffer_list_t& list = j->second;
  3055. for (LLSpatialGroup::buffer_list_t::iterator k = list.begin(); k != list.end(); ++k)
  3056. {
  3057. LLVertexBuffer* buffer = *k;
  3058. if (buffer->isLocked())
  3059. {
  3060. buffer->setBuffer(0);
  3061. }
  3062. }
  3063. }
  3064. }
  3065. // don't forget alpha
  3066. if(group != NULL && 
  3067.    !group->mVertexBuffer.isNull() && 
  3068.    group->mVertexBuffer->isLocked())
  3069. {
  3070. group->mVertexBuffer->setBuffer(0);
  3071. }
  3072. //if not all buffers are unmapped
  3073. if(num_mapped_veretx_buffer != LLVertexBuffer::sMappedCount) 
  3074. {
  3075. llwarns << "Not all mapped vertex buffers are unmapped!" << llendl ; 
  3076. for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
  3077. {
  3078. LLDrawable* drawablep = *drawable_iter;
  3079. for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
  3080. {
  3081. LLFace* face = drawablep->getFace(i);
  3082. if (face && face->mVertexBuffer.notNull() && face->mVertexBuffer->isLocked())
  3083. {
  3084. face->mVertexBuffer->setBuffer(0) ;
  3085. }
  3086. }
  3087. }
  3088. group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
  3089. }
  3090. if (group && group->isState(LLSpatialGroup::NEW_DRAWINFO))
  3091. {
  3092. llerrs << "WTF?" << llendl;
  3093. }
  3094. }
  3095. void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort)
  3096. {
  3097. llpushcallstacks ;
  3098. //calculate maximum number of vertices to store in a single buffer
  3099. U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask);
  3100. max_vertices = llmin(max_vertices, (U32) 65535);
  3101. if (!distance_sort)
  3102. {
  3103. //sort faces by things that break batches
  3104. std::sort(faces.begin(), faces.end(), LLFace::CompareBatchBreaker());
  3105. }
  3106. else
  3107. {
  3108. //sort faces by distance
  3109. std::sort(faces.begin(), faces.end(), LLFace::CompareDistanceGreater());
  3110. }
  3111. std::vector<LLFace*>::iterator face_iter = faces.begin();
  3112. LLSpatialGroup::buffer_map_t buffer_map;
  3113. LLViewerTexture* last_tex = NULL;
  3114. S32 buffer_index = 0;
  3115. if (distance_sort)
  3116. {
  3117. buffer_index = -1;
  3118. }
  3119. while (face_iter != faces.end())
  3120. {
  3121. //pull off next face
  3122. LLFace* facep = *face_iter;
  3123. LLViewerTexture* tex = facep->getTexture();
  3124. if (distance_sort)
  3125. {
  3126. tex = NULL;
  3127. }
  3128. if (last_tex == tex)
  3129. {
  3130. buffer_index++;
  3131. }
  3132. else
  3133. {
  3134. last_tex = tex;
  3135. buffer_index = 0;
  3136. }
  3137. U32 index_count = facep->getIndicesCount();
  3138. U32 geom_count = facep->getGeomCount();
  3139. //sum up vertices needed for this texture
  3140. std::vector<LLFace*>::iterator i = face_iter;
  3141. ++i;
  3142. while (i != faces.end() && 
  3143. (LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex)))
  3144. {
  3145. facep = *i;
  3146. if (geom_count + facep->getGeomCount() > max_vertices)
  3147. { //cut vertex buffers on geom count too big
  3148. break;
  3149. }
  3150. ++i;
  3151. index_count += facep->getIndicesCount();
  3152. geom_count += facep->getGeomCount();
  3153. }
  3154. //create/delete/resize vertex buffer if needed
  3155. LLVertexBuffer* buffer = NULL;
  3156. LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(tex);
  3157. if (found_iter != group->mBufferMap[mask].end())
  3158. {
  3159. if ((U32) buffer_index < found_iter->second.size())
  3160. {
  3161. buffer = found_iter->second[buffer_index];
  3162. }
  3163. }
  3164. if (!buffer)
  3165. { //create new buffer if needed
  3166. buffer = createVertexBuffer(mask, 
  3167. group->mBufferUsage);
  3168. buffer->allocateBuffer(geom_count, index_count, TRUE);
  3169. }
  3170. else 
  3171. {
  3172. if (LLVertexBuffer::sEnableVBOs && buffer->getUsage() != group->mBufferUsage)
  3173. {
  3174. buffer = createVertexBuffer(group->mSpatialPartition->mVertexDataMask, 
  3175. group->mBufferUsage);
  3176. buffer->allocateBuffer(geom_count, index_count, TRUE);
  3177. }
  3178. else
  3179. {
  3180. buffer->resizeBuffer(geom_count, index_count);
  3181. }
  3182. }
  3183. buffer_map[mask][tex].push_back(buffer);
  3184. //add face geometry
  3185. U32 indices_index = 0;
  3186. U16 index_offset = 0;
  3187. while (face_iter < i)
  3188. {
  3189. facep = *face_iter;
  3190. facep->mIndicesIndex = indices_index;
  3191. facep->mGeomIndex = index_offset;
  3192. facep->mVertexBuffer = buffer;
  3193. {
  3194. facep->updateRebuildFlags();
  3195. if (!LLPipeline::sDelayVBUpdate)
  3196. {
  3197. LLDrawable* drawablep = facep->getDrawable();
  3198. LLVOVolume* vobj = drawablep->getVOVolume();
  3199. LLVolume* volume = vobj->getVolume();
  3200. U32 te_idx = facep->getTEOffset();
  3201. if (facep->getGeometryVolume(*volume, te_idx, 
  3202. vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset))
  3203. {
  3204. buffer->markDirty(facep->getGeomIndex(), facep->getGeomCount(), 
  3205. facep->getIndicesStart(), facep->getIndicesCount());
  3206. }
  3207. }
  3208. }
  3209. index_offset += facep->getGeomCount();
  3210. indices_index += facep->mIndicesCount;
  3211. BOOL force_simple = facep->mPixelArea < FORCE_SIMPLE_RENDER_AREA;
  3212. BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
  3213. if ((mask & LLVertexBuffer::MAP_NORMAL) == 0)
  3214. { //paranoia check to make sure GL doesn't try to read non-existant normals
  3215. fullbright = TRUE;
  3216. }
  3217. const LLTextureEntry* te = facep->getTextureEntry();
  3218. BOOL is_alpha = facep->getPoolType() == LLDrawPool::POOL_ALPHA ? TRUE : FALSE;
  3219. if (is_alpha)
  3220. {
  3221. // can we safely treat this as an alpha mask?
  3222. if (LLPipeline::sFastAlpha &&
  3223.     (te->getColor().mV[VW] == 1.0f) &&
  3224.     (!te->getFullbright()) && // hack: alpha masking renders fullbright faces invisible, need to figure out why - for now, avoid
  3225.     facep->getTexture()->getIsAlphaMask())
  3226. {
  3227. if (te->getFullbright())
  3228. {
  3229. registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
  3230. }
  3231. else
  3232. {
  3233. registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK);
  3234. }
  3235. }
  3236. else
  3237. {
  3238. registerFace(group, facep, LLRenderPass::PASS_ALPHA);
  3239. }
  3240. if (LLPipeline::sRenderDeferred)
  3241. {
  3242. registerFace(group, facep, LLRenderPass::PASS_ALPHA_SHADOW);
  3243. }
  3244. }
  3245. else if (gPipeline.canUseVertexShaders()
  3246. && group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD 
  3247. && LLPipeline::sRenderBump 
  3248. && te->getShiny())
  3249. {
  3250. if (tex->getPrimaryFormat() == GL_ALPHA)
  3251. {
  3252. registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY);
  3253. registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
  3254. }
  3255. else if (LLPipeline::sRenderDeferred)
  3256. {
  3257. if (te->getBumpmap())
  3258. {
  3259. registerFace(group, facep, LLRenderPass::PASS_BUMP);
  3260. }
  3261. else if (te->getFullbright())
  3262. {
  3263. registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY);
  3264. }
  3265. else
  3266. {
  3267. llassert(mask & LLVertexBuffer::MAP_NORMAL);
  3268. registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
  3269. }
  3270. }
  3271. else if (fullbright)
  3272. {
  3273. registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY);
  3274. }
  3275. else
  3276. {
  3277. registerFace(group, facep, LLRenderPass::PASS_SHINY);
  3278. }
  3279. }
  3280. else
  3281. {
  3282. if (!is_alpha && tex->getPrimaryFormat() == GL_ALPHA)
  3283. {
  3284. registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
  3285. }
  3286. else if (fullbright)
  3287. {
  3288. registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
  3289. }
  3290. else
  3291. {
  3292. if (LLPipeline::sRenderDeferred && te->getBumpmap())
  3293. {
  3294. registerFace(group, facep, LLRenderPass::PASS_BUMP);
  3295. }
  3296. else
  3297. {
  3298. llassert(mask & LLVertexBuffer::MAP_NORMAL);
  3299. registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
  3300. }
  3301. }
  3302. if (!is_alpha && te->getShiny() && LLPipeline::sRenderBump)
  3303. {
  3304. registerFace(group, facep, LLRenderPass::PASS_SHINY);
  3305. }
  3306. }
  3307. if (!is_alpha && !LLPipeline::sRenderDeferred)
  3308. {
  3309. llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright);
  3310. facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE);
  3311. if (!force_simple && te->getBumpmap() && LLPipeline::sRenderBump)
  3312. {
  3313. registerFace(group, facep, LLRenderPass::PASS_BUMP);
  3314. }
  3315. }
  3316. if (LLPipeline::sRenderGlow && te->getGlow() > 0.f)
  3317. {
  3318. registerFace(group, facep, LLRenderPass::PASS_GLOW);
  3319. }
  3320. ++face_iter;
  3321. }
  3322. buffer->setBuffer(0);
  3323. }
  3324. group->mBufferMap[mask].clear();
  3325. for (LLSpatialGroup::buffer_texture_map_t::iterator i = buffer_map[mask].begin(); i != buffer_map[mask].end(); ++i)
  3326. {
  3327. group->mBufferMap[mask][i->first] = i->second;
  3328. }
  3329. }
  3330. void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count)
  3331. {
  3332. //initialize to default usage for this partition
  3333. U32 usage = group->mSpatialPartition->mBufferUsage;
  3334. //clear off any old faces
  3335. mFaceList.clear();
  3336. //for each drawable
  3337. for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
  3338. {
  3339. LLDrawable* drawablep = *drawable_iter;
  3340. if (drawablep->isDead())
  3341. {
  3342. continue;
  3343. }
  3344. if (drawablep->isAnimating())
  3345. { //fall back to stream draw for animating verts
  3346. usage = GL_STREAM_DRAW_ARB;
  3347. }
  3348. //for each face
  3349. for (S32 i = 0; i < drawablep->getNumFaces(); i++)
  3350. {
  3351. //sum up face verts and indices
  3352. drawablep->updateFaceSize(i);
  3353. LLFace* facep = drawablep->getFace(i);
  3354. if (facep->hasGeometry() && facep->mPixelArea > FORCE_CULL_AREA)
  3355. {
  3356. vertex_count += facep->getGeomCount();
  3357. index_count += facep->getIndicesCount();
  3358. //remember face (for sorting)
  3359. mFaceList.push_back(facep);
  3360. }
  3361. else
  3362. {
  3363. facep->mVertexBuffer = NULL;
  3364. facep->mLastVertexBuffer = NULL;
  3365. }
  3366. }
  3367. }
  3368. group->mBufferUsage = usage;
  3369. }
  3370. LLHUDPartition::LLHUDPartition()
  3371. {
  3372. mPartitionType = LLViewerRegion::PARTITION_HUD;
  3373. mDrawableType = LLPipeline::RENDER_TYPE_HUD;
  3374. mSlopRatio = 0.f;
  3375. mLODPeriod = 1;
  3376. }
  3377. void LLHUDPartition::shift(const LLVector3 &offset)
  3378. {
  3379. //HUD objects don't shift with region crossing.  That would be silly.
  3380. }