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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llface.cpp
  3.  * @brief LLFace 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. #include "llviewerprecompiledheaders.h"
  33. #include "lldrawable.h" // lldrawable needs to be included before llface
  34. #include "llface.h"
  35. #include "llviewertextureanim.h"
  36. #include "llviewercontrol.h"
  37. #include "llvolume.h"
  38. #include "m3math.h"
  39. #include "v3color.h"
  40. #include "lldrawpoolbump.h"
  41. #include "llgl.h"
  42. #include "llrender.h"
  43. #include "lllightconstants.h"
  44. #include "llsky.h"
  45. #include "llviewercamera.h"
  46. #include "llviewertexturelist.h"
  47. #include "llvosky.h"
  48. #include "llvovolume.h"
  49. #include "pipeline.h"
  50. #include "llviewerregion.h"
  51. #include "llviewerwindow.h"
  52. #define LL_MAX_INDICES_COUNT 1000000
  53. BOOL LLFace::sSafeRenderSelect = TRUE; // FALSE
  54. #define DOTVEC(a,b) (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2])
  55. /*
  56. For each vertex, given:
  57. B - binormal
  58. T - tangent
  59. N - normal
  60. P - position
  61. The resulting texture coordinate <u,v> is:
  62. u = 2(B dot P)
  63. v = 2(T dot P)
  64. */
  65. void planarProjection(LLVector2 &tc, const LLVector3& normal,
  66.   const LLVector3 &mCenter, const LLVector3& vec)
  67. { //DONE!
  68. LLVector3 binormal;
  69. float d = normal * LLVector3(1,0,0);
  70. if (d >= 0.5f || d <= -0.5f)
  71. {
  72. binormal = LLVector3(0,1,0);
  73. if (normal.mV[0] < 0)
  74. {
  75. binormal = -binormal;
  76. }
  77. }
  78. else
  79. {
  80.         binormal = LLVector3(1,0,0);
  81. if (normal.mV[1] > 0)
  82. {
  83. binormal = -binormal;
  84. }
  85. }
  86. LLVector3 tangent = binormal % normal;
  87. tc.mV[1] = -((tangent*vec)*2 - 0.5f);
  88. tc.mV[0] = 1.0f+((binormal*vec)*2 - 0.5f);
  89. }
  90. void sphericalProjection(LLVector2 &tc, const LLVector3& normal,
  91.  const LLVector3 &mCenter, const LLVector3& vec)
  92. { //BROKEN
  93. /*tc.mV[0] = acosf(vd.mNormal * LLVector3(1,0,0))/3.14159f;
  94. tc.mV[1] = acosf(vd.mNormal * LLVector3(0,0,1))/6.284f;
  95. if (vd.mNormal.mV[1] > 0)
  96. {
  97. tc.mV[1] = 1.0f-tc.mV[1];
  98. }*/
  99. }
  100. void cylindricalProjection(LLVector2 &tc, const LLVector3& normal, const LLVector3 &mCenter, const LLVector3& vec)
  101. { //BROKEN
  102. /*LLVector3 binormal;
  103. float d = vd.mNormal * LLVector3(1,0,0);
  104. if (d >= 0.5f || d <= -0.5f)
  105. {
  106. binormal = LLVector3(0,1,0);
  107. }
  108. else{
  109. binormal = LLVector3(1,0,0);
  110. }
  111. LLVector3 tangent = binormal % vd.mNormal;
  112. tc.mV[1] = -((tangent*vec)*2 - 0.5f);
  113. tc.mV[0] = acosf(vd.mNormal * LLVector3(1,0,0))/6.284f;
  114. if (vd.mNormal.mV[1] < 0)
  115. {
  116. tc.mV[0] = 1.0f-tc.mV[0];
  117. }*/
  118. }
  119. ////////////////////
  120. //
  121. // LLFace implementation
  122. //
  123. void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
  124. {
  125. mLastUpdateTime = gFrameTimeSeconds;
  126. mLastMoveTime = 0.f;
  127. mVSize = 0.f;
  128. mPixelArea = 16.f;
  129. mState      = GLOBAL;
  130. mDrawPoolp  = NULL;
  131. mPoolType = 0;
  132. mCenterLocal = objp->getPosition();
  133. mCenterAgent = drawablep->getPositionAgent();
  134. mDistance = 0.f;
  135. mGeomCount = 0;
  136. mGeomIndex = 0;
  137. mIndicesCount = 0;
  138. mIndicesIndex = 0;
  139. mIndexInTex = 0;
  140. mTexture = NULL;
  141. mTEOffset = -1;
  142. setDrawable(drawablep);
  143. mVObjp = objp;
  144. mReferenceIndex = -1;
  145. mTextureMatrix = NULL;
  146. mDrawInfo = NULL;
  147. mFaceColor = LLColor4(1,0,0,1);
  148. mLastVertexBuffer = mVertexBuffer;
  149. mLastGeomCount = mGeomCount;
  150. mLastGeomIndex = mGeomIndex;
  151. mLastIndicesCount = mIndicesCount;
  152. mLastIndicesIndex = mIndicesIndex;
  153. mImportanceToCamera = 0.f ;
  154. mBoundingSphereRadius = 0.0f ;
  155. mAtlasInfop = NULL ;
  156. mUsingAtlas  = FALSE ;
  157. mHasMedia = FALSE ;
  158. }
  159. void LLFace::destroy()
  160. {
  161. if(mTexture.notNull())
  162. {
  163. mTexture->removeFace(this) ;
  164. }
  165. if (mDrawPoolp)
  166. {
  167. mDrawPoolp->removeFace(this);
  168. mDrawPoolp = NULL;
  169. }
  170. if (mTextureMatrix)
  171. {
  172. delete mTextureMatrix;
  173. mTextureMatrix = NULL;
  174. if (mDrawablep.notNull())
  175. {
  176. LLSpatialGroup* group = mDrawablep->getSpatialGroup();
  177. if (group)
  178. {
  179. group->dirtyGeom();
  180. gPipeline.markRebuild(group, TRUE);
  181. }
  182. }
  183. }
  184. setDrawInfo(NULL);
  185. removeAtlas();
  186. mDrawablep = NULL;
  187. mVObjp = NULL;
  188. }
  189. // static
  190. void LLFace::initClass()
  191. {
  192. }
  193. void LLFace::setWorldMatrix(const LLMatrix4 &mat)
  194. {
  195. llerrs << "Faces on this drawable are not independently modifiablen" << llendl;
  196. }
  197. void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep)
  198. {
  199. LLMemType mt1(LLMemType::MTYPE_DRAWABLE);
  200. if (!new_pool)
  201. {
  202. llerrs << "Setting pool to null!" << llendl;
  203. }
  204. if (new_pool != mDrawPoolp)
  205. {
  206. // Remove from old pool
  207. if (mDrawPoolp)
  208. {
  209. mDrawPoolp->removeFace(this);
  210. if (mDrawablep)
  211. {
  212. gPipeline.markRebuild(mDrawablep, LLDrawable::REBUILD_ALL, TRUE);
  213. }
  214. }
  215. mGeomIndex = 0;
  216. // Add to new pool
  217. if (new_pool)
  218. {
  219. new_pool->addFace(this);
  220. }
  221. mDrawPoolp = new_pool;
  222. }
  223. setTexture(texturep) ;
  224. }
  225. void LLFace::setTexture(LLViewerTexture* tex) 
  226. {
  227. if(mTexture == tex)
  228. {
  229. return ;
  230. }
  231. if(mTexture.notNull())
  232. {
  233. mTexture->removeFace(this) ;
  234. removeAtlas() ;
  235. }
  236. if(tex)
  237. {
  238. tex->addFace(this) ;
  239. }
  240. mTexture = tex ;
  241. }
  242. void LLFace::dirtyTexture()
  243. {
  244. gPipeline.markTextured(getDrawable());
  245. }
  246. void LLFace::switchTexture(LLViewerTexture* new_texture)
  247. {
  248. if(mTexture == new_texture)
  249. {
  250. return ;
  251. }
  252. if(!new_texture)
  253. {
  254. llerrs << "Can not switch to a null texture." << llendl;
  255. return;
  256. }
  257. new_texture->addTextureStats(mTexture->getMaxVirtualSize()) ;
  258. getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
  259. setTexture(new_texture) ;
  260. dirtyTexture();
  261. }
  262. void LLFace::setTEOffset(const S32 te_offset)
  263. {
  264. mTEOffset = te_offset;
  265. }
  266. void LLFace::setFaceColor(const LLColor4& color)
  267. {
  268. mFaceColor = color;
  269. setState(USE_FACE_COLOR);
  270. }
  271. void LLFace::unsetFaceColor()
  272. {
  273. clearState(USE_FACE_COLOR);
  274. }
  275. void LLFace::setDrawable(LLDrawable *drawable)
  276. {
  277. mDrawablep  = drawable;
  278. mXform      = &drawable->mXform;
  279. }
  280. void LLFace::setSize(const S32 num_vertices, const S32 num_indices)
  281. {
  282. if (mGeomCount != num_vertices ||
  283. mIndicesCount != num_indices)
  284. {
  285. mGeomCount    = num_vertices;
  286. mIndicesCount = num_indices;
  287. mVertexBuffer = NULL;
  288. mLastVertexBuffer = NULL;
  289. }
  290. }
  291. //============================================================================
  292. U16 LLFace::getGeometryAvatar(
  293. LLStrider<LLVector3> &vertices,
  294. LLStrider<LLVector3> &normals,
  295. LLStrider<LLVector2> &tex_coords,
  296. LLStrider<F32>  &vertex_weights,
  297. LLStrider<LLVector4> &clothing_weights)
  298. {
  299. LLMemType mt1(LLMemType::MTYPE_DRAWABLE);
  300. if (mVertexBuffer.notNull())
  301. {
  302. mVertexBuffer->getVertexStrider      (vertices, mGeomIndex);
  303. mVertexBuffer->getNormalStrider      (normals, mGeomIndex);
  304. mVertexBuffer->getTexCoord0Strider    (tex_coords, mGeomIndex);
  305. mVertexBuffer->getWeightStrider(vertex_weights, mGeomIndex);
  306. mVertexBuffer->getClothWeightStrider(clothing_weights, mGeomIndex);
  307. }
  308. return mGeomIndex;
  309. }
  310. U16 LLFace::getGeometry(LLStrider<LLVector3> &vertices, LLStrider<LLVector3> &normals,
  311.     LLStrider<LLVector2> &tex_coords, LLStrider<U16> &indicesp)
  312. {
  313. LLMemType mt1(LLMemType::MTYPE_DRAWABLE);
  314. if (mVertexBuffer.notNull())
  315. {
  316. mVertexBuffer->getVertexStrider(vertices,   mGeomIndex);
  317. if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL))
  318. {
  319. mVertexBuffer->getNormalStrider(normals,    mGeomIndex);
  320. }
  321. if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD0))
  322. {
  323. mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex);
  324. }
  325. mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex);
  326. }
  327. return mGeomIndex;
  328. }
  329. void LLFace::updateCenterAgent()
  330. {
  331. if (mDrawablep->isActive())
  332. {
  333. mCenterAgent = mCenterLocal * getRenderMatrix();
  334. }
  335. else
  336. {
  337. mCenterAgent = mCenterLocal;
  338. }
  339. }
  340. void LLFace::renderForSelect(U32 data_mask)
  341. {
  342. if(mDrawablep.isNull() || mVertexBuffer.isNull())
  343. {
  344. return;
  345. }
  346. LLSpatialGroup* group = mDrawablep->getSpatialGroup();
  347. if (!group || group->isState(LLSpatialGroup::GEOM_DIRTY))
  348. {
  349. return;
  350. }
  351. if (mVObjp->mGLName)
  352. {
  353. S32 name = mVObjp->mGLName;
  354. LLColor4U color((U8)(name >> 16), (U8)(name >> 8), (U8)name);
  355. #if 0 // *FIX: Postponing this fix until we have texcoord pick info...
  356. if (mTEOffset != -1)
  357. {
  358. color.mV[VALPHA] = (U8)(getTextureEntry()->getColor().mV[VALPHA] * 255.f);
  359. }
  360. #endif
  361. glColor4ubv(color.mV);
  362. if (!getPool())
  363. {
  364. switch (getPoolType())
  365. {
  366. case LLDrawPool::POOL_ALPHA:
  367. gGL.getTexUnit(0)->bind(getTexture());
  368. break;
  369. default:
  370. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  371. break;
  372. }
  373. }
  374. mVertexBuffer->setBuffer(data_mask);
  375. #if !LL_RELEASE_FOR_DOWNLOAD
  376. LLGLState::checkClientArrays("", data_mask);
  377. #endif
  378. if (mTEOffset != -1)
  379. {
  380. // mask off high 4 bits (16 total possible faces)
  381. color.mV[0] &= 0x0f;
  382. color.mV[0] |= (mTEOffset & 0x0f) << 4;
  383. glColor4ubv(color.mV);
  384. }
  385. if (mIndicesCount)
  386. {
  387. if (isState(GLOBAL))
  388. {
  389. if (mDrawablep->getVOVolume())
  390. {
  391. glPushMatrix();
  392. glMultMatrixf((float*) mDrawablep->getRegion()->mRenderMatrix.mMatrix);
  393. mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex);
  394. glPopMatrix();
  395. }
  396. else
  397. {
  398. mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex);
  399. }
  400. }
  401. else
  402. {
  403. glPushMatrix();
  404. glMultMatrixf((float*)getRenderMatrix().mMatrix);
  405. mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex);
  406. glPopMatrix();
  407. }
  408. }
  409. }
  410. }
  411. void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
  412. {
  413. if (mDrawablep->getSpatialGroup() == NULL)
  414. {
  415. return;
  416. }
  417. mDrawablep->getSpatialGroup()->rebuildGeom();
  418. mDrawablep->getSpatialGroup()->rebuildMesh();
  419. if(mDrawablep.isNull() || mVertexBuffer.isNull())
  420. {
  421. return;
  422. }
  423. if (mGeomCount > 0 && mIndicesCount > 0)
  424. {
  425. gGL.getTexUnit(0)->bind(imagep);
  426. gGL.pushMatrix();
  427. if (mDrawablep->isActive())
  428. {
  429. glMultMatrixf((GLfloat*)mDrawablep->getRenderMatrix().mMatrix);
  430. }
  431. else
  432. {
  433. glMultMatrixf((GLfloat*)mDrawablep->getRegion()->mRenderMatrix.mMatrix);
  434. }
  435. glColor4fv(color.mV);
  436. mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0);
  437. mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex);
  438. gGL.popMatrix();
  439. }
  440. }
  441. /* removed in lieu of raycast uv detection
  442. void LLFace::renderSelectedUV()
  443. {
  444. LLViewerTexture* red_blue_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test1.j2c", TRUE, LLViewerTexture::BOOST_UI);
  445. LLViewerTexture* green_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test2.tga", TRUE, LLViewerTexture::BOOST_UI);
  446. LLGLSUVSelect object_select;
  447. // use red/blue gradient to get coarse UV coordinates
  448. renderSelected(red_blue_imagep, LLColor4::white);
  449. static F32 bias = 0.f;
  450. static F32 factor = -10.f;
  451. glPolygonOffset(factor, bias);
  452. // add green dither pattern on top of red/blue gradient
  453. gGL.blendFunc(LLRender::BF_ONE, LLRender::BF_ONE);
  454. glMatrixMode(GL_TEXTURE);
  455. glPushMatrix();
  456. // make green pattern repeat once per texel in red/blue texture
  457. glScalef(256.f, 256.f, 1.f);
  458. glMatrixMode(GL_MODELVIEW);
  459. renderSelected(green_imagep, LLColor4::white);
  460. glMatrixMode(GL_TEXTURE);
  461. glPopMatrix();
  462. glMatrixMode(GL_MODELVIEW);
  463. gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
  464. }
  465. */
  466. void LLFace::setDrawInfo(LLDrawInfo* draw_info)
  467. {
  468. if (draw_info)
  469. {
  470. if (draw_info->mFace)
  471. {
  472. draw_info->mFace->setDrawInfo(NULL);
  473. }
  474. draw_info->mFace = this;
  475. }
  476. if (mDrawInfo)
  477. {
  478. mDrawInfo->mFace = NULL;
  479. }
  480. mDrawInfo = draw_info;
  481. }
  482. void LLFace::printDebugInfo() const
  483. {
  484. LLFacePool *poolp = getPool();
  485. llinfos << "Object: " << getViewerObject()->mID << llendl;
  486. if (getDrawable())
  487. {
  488. llinfos << "Type: " << LLPrimitive::pCodeToString(getDrawable()->getVObj()->getPCode()) << llendl;
  489. }
  490. if (getTexture())
  491. {
  492. llinfos << "Texture: " << getTexture() << " Comps: " << (U32)getTexture()->getComponents() << llendl;
  493. }
  494. else
  495. {
  496. llinfos << "No texture: " << llendl;
  497. }
  498. llinfos << "Face: " << this << llendl;
  499. llinfos << "State: " << getState() << llendl;
  500. llinfos << "Geom Index Data:" << llendl;
  501. llinfos << "--------------------" << llendl;
  502. llinfos << "GI: " << mGeomIndex << " Count:" << mGeomCount << llendl;
  503. llinfos << "Face Index Data:" << llendl;
  504. llinfos << "--------------------" << llendl;
  505. llinfos << "II: " << mIndicesIndex << " Count:" << mIndicesCount << llendl;
  506. llinfos << llendl;
  507. poolp->printDebugInfo();
  508. S32 pool_references = 0;
  509. for (std::vector<LLFace*>::iterator iter = poolp->mReferences.begin();
  510.  iter != poolp->mReferences.end(); iter++)
  511. {
  512. LLFace *facep = *iter;
  513. if (facep == this)
  514. {
  515. llinfos << "Pool reference: " << pool_references << llendl;
  516. pool_references++;
  517. }
  518. }
  519. if (pool_references != 1)
  520. {
  521. llinfos << "Incorrect number of pool references!" << llendl;
  522. }
  523. #if 0
  524. llinfos << "Indices:" << llendl;
  525. llinfos << "--------------------" << llendl;
  526. const U32 *indicesp = getRawIndices();
  527. S32 indices_count = getIndicesCount();
  528. S32 geom_start = getGeomStart();
  529. for (S32 i = 0; i < indices_count; i++)
  530. {
  531. llinfos << i << ":" << indicesp[i] << ":" << (S32)(indicesp[i] - geom_start) << llendl;
  532. }
  533. llinfos << llendl;
  534. llinfos << "Vertices:" << llendl;
  535. llinfos << "--------------------" << llendl;
  536. for (S32 i = 0; i < mGeomCount; i++)
  537. {
  538. llinfos << mGeomIndex + i << ":" << poolp->getVertex(mGeomIndex + i) << llendl;
  539. }
  540. llinfos << llendl;
  541. #endif
  542. }
  543. // Transform the texture coordinates for this face.
  544. static void xform(LLVector2 &tex_coord, F32 cosAng, F32 sinAng, F32 offS, F32 offT, F32 magS, F32 magT)
  545. {
  546. // New, good way
  547. F32 s = tex_coord.mV[0];
  548. F32 t = tex_coord.mV[1];
  549. // Texture transforms are done about the center of the face.
  550. s -= 0.5; 
  551. t -= 0.5;
  552. // Handle rotation
  553. F32 temp = s;
  554. s  = s     * cosAng + t * sinAng;
  555. t  = -temp * sinAng + t * cosAng;
  556. // Then scale
  557. s *= magS;
  558. t *= magT;
  559. // Then offset
  560. s += offS + 0.5f; 
  561. t += offT + 0.5f;
  562. tex_coord.mV[0] = s;
  563. tex_coord.mV[1] = t;
  564. }
  565. BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
  566. const LLMatrix4& mat_vert, const LLMatrix3& mat_normal, BOOL global_volume)
  567. {
  568. LLMemType mt1(LLMemType::MTYPE_DRAWABLE);
  569. //get bounding box
  570. if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION))
  571. {
  572. //if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME))
  573. //{ //vertex buffer no longer valid
  574. // mVertexBuffer = NULL;
  575. // mLastVertexBuffer = NULL;
  576. //}
  577. LLVector3 min,max;
  578. if (f >= volume.getNumVolumeFaces())
  579. {
  580. min = LLVector3(-1,-1,-1);
  581. max = LLVector3(1,1,1);
  582. }
  583. else
  584. {
  585. const LLVolumeFace &face = volume.getVolumeFace(f);
  586. min = face.mExtents[0];
  587. max = face.mExtents[1];
  588. }
  589. //min, max are in volume space, convert to drawable render space
  590. LLVector3 center = ((min + max) * 0.5f)*mat_vert;
  591. LLVector3 size = ((max-min) * 0.5f);
  592. if (!global_volume)
  593. {
  594. size.scaleVec(mDrawablep->getVObj()->getScale());
  595. }
  596. LLMatrix3 mat = mat_normal;
  597. LLVector3 x = mat.getFwdRow();
  598. LLVector3 y = mat.getLeftRow();
  599. LLVector3 z = mat.getUpRow();
  600. x.normVec();
  601. y.normVec();
  602. z.normVec();
  603. mat.setRows(x,y,z);
  604. LLQuaternion rotation = LLQuaternion(mat);
  605. LLVector3 v[4];
  606. //get 4 corners of bounding box
  607. v[0] = (size * rotation);
  608. v[1] = (LLVector3(-size.mV[0], -size.mV[1], size.mV[2]) * rotation);
  609. v[2] = (LLVector3(size.mV[0], -size.mV[1], -size.mV[2]) * rotation);
  610. v[3] = (LLVector3(-size.mV[0], size.mV[1], -size.mV[2]) * rotation);
  611. LLVector3& newMin = mExtents[0];
  612. LLVector3& newMax = mExtents[1];
  613. newMin = newMax = center;
  614. for (U32 i = 0; i < 4; i++)
  615. {
  616. for (U32 j = 0; j < 3; j++)
  617. {
  618. F32 delta = fabsf(v[i].mV[j]);
  619. F32 min = center.mV[j] - delta;
  620. F32 max = center.mV[j] + delta;
  621. if (min < newMin.mV[j])
  622. {
  623. newMin.mV[j] = min;
  624. }
  625. if (max > newMax.mV[j])
  626. {
  627. newMax.mV[j] = max;
  628. }
  629. }
  630. }
  631. if (!mDrawablep->isActive())
  632. {
  633. LLVector3 offset = mDrawablep->getRegion()->getOriginAgent();
  634. newMin += offset;
  635. newMax += offset;
  636. }
  637. mCenterLocal = (newMin+newMax)*0.5f;
  638. LLVector3 tmp = (newMin - newMax) ;
  639. mBoundingSphereRadius = tmp.length() * 0.5f ;
  640. updateCenterAgent();
  641. }
  642. return TRUE;
  643. }
  644. // convert surface coordinates to texture coordinates, based on
  645. // the values in the texture entry.  probably should be
  646. // integrated with getGeometryVolume() for its texture coordinate
  647. // generation - but i'll leave that to someone more familiar
  648. // with the implications.
  649. LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position, LLVector3 normal)
  650. {
  651. LLVector2 tc = surface_coord;
  652. const LLTextureEntry *tep = getTextureEntry();
  653. if (tep == NULL)
  654. {
  655. // can't do much without the texture entry
  656. return surface_coord;
  657. }
  658. // see if we have a non-default mapping
  659.     U8 texgen = getTextureEntry()->getTexGen();
  660. if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
  661. {
  662. LLVector3 center = mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter;
  663. LLVector3 scale  = (mDrawablep->getVOVolume()->isVolumeGlobal()) ? LLVector3(1,1,1) : mVObjp->getScale();
  664. LLVector3 volume_position = mDrawablep->getVOVolume()->agentPositionToVolume(position);
  665. volume_position.scaleVec(scale);
  666. LLVector3 volume_normal   = mDrawablep->getVOVolume()->agentDirectionToVolume(normal);
  667. volume_normal.normalize();
  668. switch (texgen)
  669. {
  670. case LLTextureEntry::TEX_GEN_PLANAR:
  671. planarProjection(tc, volume_normal, center, volume_position);
  672. break;
  673. case LLTextureEntry::TEX_GEN_SPHERICAL:
  674. sphericalProjection(tc, volume_normal, center, volume_position);
  675. break;
  676. case LLTextureEntry::TEX_GEN_CYLINDRICAL:
  677. cylindricalProjection(tc, volume_normal, center, volume_position);
  678. break;
  679. default:
  680. break;
  681. }
  682. }
  683. if (mTextureMatrix) // if we have a texture matrix, use it
  684. {
  685. LLVector3 tc3(tc);
  686. tc3 = tc3 * *mTextureMatrix;
  687. tc = LLVector2(tc3);
  688. }
  689. else // otherwise use the texture entry parameters
  690. {
  691. xform(tc, cos(tep->getRotation()), sin(tep->getRotation()),
  692.   tep->mOffsetS, tep->mOffsetT, tep->mScaleS, tep->mScaleT);
  693. }
  694. return tc;
  695. }
  696. void LLFace::updateRebuildFlags()
  697. {
  698. if (!mDrawablep->isState(LLDrawable::REBUILD_VOLUME))
  699. {
  700. BOOL moved = TRUE;
  701. if (mLastVertexBuffer == mVertexBuffer && 
  702. !mVertexBuffer->isEmpty())
  703. { //this face really doesn't need to be regenerated, try real hard not to do so
  704. if (mLastGeomCount == mGeomCount &&
  705. mLastGeomIndex == mGeomIndex &&
  706. mLastIndicesCount == mIndicesCount &&
  707. mLastIndicesIndex == mIndicesIndex)
  708. { //data is in same location in vertex buffer
  709. moved = FALSE;
  710. }
  711. }
  712. mLastMoveTime = gFrameTimeSeconds;
  713. if (moved)
  714. {
  715. mDrawablep->setState(LLDrawable::REBUILD_VOLUME);
  716. }
  717. }
  718. else
  719. {
  720. mLastUpdateTime = gFrameTimeSeconds;
  721. }
  722. }
  723. BOOL LLFace::getGeometryVolume(const LLVolume& volume,
  724.    const S32 &f,
  725. const LLMatrix4& mat_vert, const LLMatrix3& mat_normal,
  726. const U16 &index_offset)
  727. {
  728. llpushcallstacks ;
  729. const LLVolumeFace &vf = volume.getVolumeFace(f);
  730. S32 num_vertices = (S32)vf.mVertices.size();
  731. S32 num_indices = (S32)vf.mIndices.size();
  732. if (mVertexBuffer.notNull())
  733. {
  734. if (num_indices + (S32) mIndicesIndex > mVertexBuffer->getNumIndices())
  735. {
  736. llwarns << "Index buffer overflow!" << llendl;
  737. llwarns << "Indices Count: " << mIndicesCount
  738. << " VF Num Indices: " << num_indices
  739. << " Indices Index: " << mIndicesIndex
  740. << " VB Num Indices: " << mVertexBuffer->getNumIndices() << llendl;
  741. llwarns << "Last Indices Count: " << mLastIndicesCount
  742. << " Last Indices Index: " << mLastIndicesIndex
  743. << " Face Index: " << f
  744. << " Pool Type: " << mPoolType << llendl;
  745. return FALSE;
  746. }
  747. if (num_vertices + mGeomIndex > mVertexBuffer->getNumVerts())
  748. {
  749. llwarns << "Vertex buffer overflow!" << llendl;
  750. return FALSE;
  751. }
  752. }
  753. LLStrider<LLVector3> vertices;
  754. LLStrider<LLVector2> tex_coords;
  755. LLStrider<LLVector2> tex_coords2;
  756. LLStrider<LLVector3> normals;
  757. LLStrider<LLColor4U> colors;
  758. LLStrider<LLVector3> binormals;
  759. LLStrider<U16> indicesp;
  760. BOOL full_rebuild = mDrawablep->isState(LLDrawable::REBUILD_VOLUME);
  761. BOOL global_volume = mDrawablep->getVOVolume()->isVolumeGlobal();
  762. LLVector3 scale;
  763. if (global_volume)
  764. {
  765. scale.setVec(1,1,1);
  766. }
  767. else
  768. {
  769. scale = mVObjp->getScale();
  770. }
  771. BOOL rebuild_pos = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_POSITION);
  772. BOOL rebuild_color = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_COLOR);
  773. BOOL rebuild_tcoord = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_TCOORD);
  774. BOOL rebuild_normal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL);
  775. BOOL rebuild_binormal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_BINORMAL);
  776. const LLTextureEntry *tep = mVObjp->getTE(f);
  777. U8  bump_code = tep ? tep->getBumpmap() : 0;
  778. if (rebuild_pos)
  779. {
  780. mVertexBuffer->getVertexStrider(vertices, mGeomIndex);
  781. }
  782. if (rebuild_normal)
  783. {
  784. mVertexBuffer->getNormalStrider(normals, mGeomIndex);
  785. }
  786. if (rebuild_binormal)
  787. {
  788. mVertexBuffer->getBinormalStrider(binormals, mGeomIndex);
  789. }
  790. F32 tcoord_xoffset = 0.f ;
  791. F32 tcoord_yoffset = 0.f ;
  792. F32 tcoord_xscale = 1.f ;
  793. F32 tcoord_yscale = 1.f ;
  794. BOOL in_atlas = FALSE ;
  795. if (rebuild_tcoord)
  796. {
  797. mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex);
  798. if (bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1))
  799. {
  800. mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex);
  801. }
  802. in_atlas = isAtlasInUse() ;
  803. if(in_atlas)
  804. {
  805. const LLVector2* tmp = getTexCoordOffset() ;
  806. tcoord_xoffset = tmp->mV[0] ; 
  807. tcoord_yoffset = tmp->mV[1] ;
  808. tmp = getTexCoordScale() ;
  809. tcoord_xscale = tmp->mV[0] ; 
  810. tcoord_yscale = tmp->mV[1] ;
  811. }
  812. }
  813. if (rebuild_color)
  814. {
  815. mVertexBuffer->getColorStrider(colors, mGeomIndex);
  816. }
  817. F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0;
  818. BOOL is_static = mDrawablep->isStatic();
  819. BOOL is_global = is_static;
  820. LLVector3 center_sum(0.f, 0.f, 0.f);
  821. if (is_global)
  822. {
  823. setState(GLOBAL);
  824. }
  825. else
  826. {
  827. clearState(GLOBAL);
  828. }
  829. LLVector2 tmin, tmax;
  830. if (rebuild_tcoord)
  831. {
  832. if (tep)
  833. {
  834. r  = tep->getRotation();
  835. os = tep->mOffsetS;
  836. ot = tep->mOffsetT;
  837. ms = tep->mScaleS;
  838. mt = tep->mScaleT;
  839. cos_ang = cos(r);
  840. sin_ang = sin(r);
  841. }
  842. else
  843. {
  844. cos_ang = 1.0f;
  845. sin_ang = 0.0f;
  846. os = 0.0f;
  847. ot = 0.0f;
  848. ms = 1.0f;
  849. mt = 1.0f;
  850. }
  851. }
  852. U8 tex_mode = 0;
  853. if (isState(TEXTURE_ANIM))
  854. {
  855. LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;
  856. tex_mode = vobj->mTexAnimMode;
  857. if (!tex_mode)
  858. {
  859. clearState(TEXTURE_ANIM);
  860. }
  861. else
  862. {
  863. os = ot = 0.f;
  864. r = 0.f;
  865. cos_ang = 1.f;
  866. sin_ang = 0.f;
  867. ms = mt = 1.f;
  868. }
  869. if (getVirtualSize() >= MIN_TEX_ANIM_SIZE)
  870. { //don't override texture transform during tc bake
  871. tex_mode = 0;
  872. }
  873. }
  874. LLColor4U color = tep->getColor();
  875. if (rebuild_color)
  876. {
  877. if (tep)
  878. {
  879. GLfloat alpha[4] =
  880. {
  881. 0.00f,
  882. 0.25f,
  883. 0.5f,
  884. 0.75f
  885. };
  886. if (getPoolType() != LLDrawPool::POOL_ALPHA && (LLPipeline::sRenderDeferred || (LLPipeline::sRenderBump && tep->getShiny())))
  887. {
  888. color.mV[3] = U8 (alpha[tep->getShiny()] * 255);
  889. }
  890. }
  891. }
  892.     // INDICES
  893. if (full_rebuild)
  894. {
  895. mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex);
  896. for (U16 i = 0; i < num_indices; i++)
  897. {
  898. *indicesp++ = vf.mIndices[i] + index_offset;
  899. }
  900. }
  901. //bump setup
  902. LLVector3 binormal_dir( -sin_ang, cos_ang, 0 );
  903. LLVector3 bump_s_primary_light_ray;
  904. LLVector3 bump_t_primary_light_ray;
  905. LLQuaternion bump_quat;
  906. if (mDrawablep->isActive())
  907. {
  908. bump_quat = LLQuaternion(mDrawablep->getRenderMatrix());
  909. }
  910. if (bump_code)
  911. {
  912. mVObjp->getVolume()->genBinormals(f);
  913. F32 offset_multiple; 
  914. switch( bump_code )
  915. {
  916. case BE_NO_BUMP:
  917. offset_multiple = 0.f;
  918. break;
  919. case BE_BRIGHTNESS:
  920. case BE_DARKNESS:
  921. if( mTexture.notNull() && mTexture->hasGLTexture())
  922. {
  923. // Offset by approximately one texel
  924. S32 cur_discard = mTexture->getDiscardLevel();
  925. S32 max_size = llmax( mTexture->getWidth(), mTexture->getHeight() );
  926. max_size <<= cur_discard;
  927. const F32 ARTIFICIAL_OFFSET = 2.f;
  928. offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size;
  929. }
  930. else
  931. {
  932. offset_multiple = 1.f/256;
  933. }
  934. break;
  935. default:  // Standard bumpmap textures.  Assumed to be 256x256
  936. offset_multiple = 1.f / 256;
  937. break;
  938. }
  939. F32 s_scale = 1.f;
  940. F32 t_scale = 1.f;
  941. if( tep )
  942. {
  943. tep->getScale( &s_scale, &t_scale );
  944. }
  945. // Use the nudged south when coming from above sun angle, such
  946. // that emboss mapping always shows up on the upward faces of cubes when 
  947. // it's noon (since a lot of builders build with the sun forced to noon).
  948. LLVector3   sun_ray  = gSky.mVOSkyp->mBumpSunDir;
  949. LLVector3   moon_ray = gSky.getMoonDirection();
  950. LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray;
  951. bump_s_primary_light_ray = offset_multiple * s_scale * primary_light_ray;
  952. bump_t_primary_light_ray = offset_multiple * t_scale * primary_light_ray;
  953. }
  954. U8 texgen = getTextureEntry()->getTexGen();
  955. if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT)
  956. { //planar texgen needs binormals
  957. mVObjp->getVolume()->genBinormals(f);
  958. }
  959. for (S32 i = 0; i < num_vertices; i++)
  960. {
  961. if (rebuild_tcoord)
  962. {
  963. LLVector2 tc = vf.mVertices[i].mTexCoord;
  964. if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
  965. {
  966. LLVector3 vec = vf.mVertices[i].mPosition; 
  967. vec.scaleVec(scale);
  968. switch (texgen)
  969. {
  970. case LLTextureEntry::TEX_GEN_PLANAR:
  971. planarProjection(tc, vf.mVertices[i].mNormal, vf.mCenter, vec);
  972. break;
  973. case LLTextureEntry::TEX_GEN_SPHERICAL:
  974. sphericalProjection(tc, vf.mVertices[i].mNormal, vf.mCenter, vec);
  975. break;
  976. case LLTextureEntry::TEX_GEN_CYLINDRICAL:
  977. cylindricalProjection(tc, vf.mVertices[i].mNormal, vf.mCenter, vec);
  978. break;
  979. default:
  980. break;
  981. }
  982. }
  983. if (tex_mode && mTextureMatrix)
  984. {
  985. LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
  986. tmp = tmp * *mTextureMatrix;
  987. tc.mV[0] = tmp.mV[0];
  988. tc.mV[1] = tmp.mV[1];
  989. }
  990. else
  991. {
  992. xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
  993. }
  994. if(in_atlas)
  995. {
  996. //
  997. //manually calculate tex-coord per vertex for varying address modes.
  998. //should be removed if shader can handle this.
  999. //
  1000. S32 int_part = 0 ;
  1001. switch(mTexture->getAddressMode())
  1002. {
  1003. case LLTexUnit::TAM_CLAMP:
  1004. if(tc.mV[0] < 0.f)
  1005. {
  1006. tc.mV[0] = 0.f ;
  1007. }
  1008. else if(tc.mV[0] > 1.f)
  1009. {
  1010. tc.mV[0] = 1.f;
  1011. }
  1012. if(tc.mV[1] < 0.f)
  1013. {
  1014. tc.mV[1] = 0.f ;
  1015. }
  1016. else if(tc.mV[1] > 1.f)
  1017. {
  1018. tc.mV[1] = 1.f;
  1019. }
  1020. break;
  1021. case LLTexUnit::TAM_MIRROR:
  1022. if(tc.mV[0] < 0.f)
  1023. {
  1024. tc.mV[0] = -tc.mV[0] ;
  1025. }
  1026. int_part = (S32)tc.mV[0] ;
  1027. if(int_part & 1) //odd number
  1028. {
  1029. tc.mV[0] = int_part + 1 - tc.mV[0] ;
  1030. }
  1031. else //even number
  1032. {
  1033. tc.mV[0] -= int_part ;
  1034. }
  1035. if(tc.mV[1] < 0.f)
  1036. {
  1037. tc.mV[1] = -tc.mV[1] ;
  1038. }
  1039. int_part = (S32)tc.mV[1] ;
  1040. if(int_part & 1) //odd number
  1041. {
  1042. tc.mV[1] = int_part + 1 - tc.mV[1] ;
  1043. }
  1044. else //even number
  1045. {
  1046. tc.mV[1] -= int_part ;
  1047. }
  1048. break;
  1049. case LLTexUnit::TAM_WRAP:
  1050. if(tc.mV[0] > 1.f)
  1051. tc.mV[0] -= (S32)(tc.mV[0] - 0.00001f) ;
  1052. else if(tc.mV[0] < -1.f)
  1053. tc.mV[0] -= (S32)(tc.mV[0] + 0.00001f) ;
  1054. if(tc.mV[1] > 1.f)
  1055. tc.mV[1] -= (S32)(tc.mV[1] - 0.00001f) ;
  1056. else if(tc.mV[1] < -1.f)
  1057. tc.mV[1] -= (S32)(tc.mV[1] + 0.00001f) ;
  1058. if(tc.mV[0] < 0.f)
  1059. {
  1060. tc.mV[0] = 1.0f + tc.mV[0] ;
  1061. }
  1062. if(tc.mV[1] < 0.f)
  1063. {
  1064. tc.mV[1] = 1.0f + tc.mV[1] ;
  1065. }
  1066. break;
  1067. default:
  1068. break;
  1069. }
  1070. tc.mV[0] = tcoord_xoffset + tcoord_xscale * tc.mV[0] ;
  1071. tc.mV[1] = tcoord_yoffset + tcoord_yscale * tc.mV[1] ;
  1072. }
  1073. *tex_coords++ = tc;
  1074. if (bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1))
  1075. {
  1076. LLVector3 tangent = vf.mVertices[i].mBinormal % vf.mVertices[i].mNormal;
  1077. LLMatrix3 tangent_to_object;
  1078. tangent_to_object.setRows(tangent, vf.mVertices[i].mBinormal, vf.mVertices[i].mNormal);
  1079. LLVector3 binormal = binormal_dir * tangent_to_object;
  1080. binormal = binormal * mat_normal;
  1081. if (mDrawablep->isActive())
  1082. {
  1083. binormal *= bump_quat;
  1084. }
  1085. binormal.normVec();
  1086. tc += LLVector2( bump_s_primary_light_ray * tangent, bump_t_primary_light_ray * binormal );
  1087. *tex_coords2++ = tc;
  1088. }
  1089. }
  1090. if (rebuild_pos)
  1091. {
  1092. *vertices++ = vf.mVertices[i].mPosition * mat_vert;
  1093. }
  1094. if (rebuild_normal)
  1095. {
  1096. LLVector3 normal = vf.mVertices[i].mNormal * mat_normal;
  1097. normal.normVec();
  1098. *normals++ = normal;
  1099. }
  1100. if (rebuild_binormal)
  1101. {
  1102. LLVector3 binormal = vf.mVertices[i].mBinormal * mat_normal;
  1103. binormal.normVec();
  1104. *binormals++ = binormal;
  1105. }
  1106. if (rebuild_color)
  1107. {
  1108. *colors++ = color;
  1109. }
  1110. }
  1111. if (rebuild_tcoord)
  1112. {
  1113. mTexExtents[0].setVec(0,0);
  1114. mTexExtents[1].setVec(1,1);
  1115. xform(mTexExtents[0], cos_ang, sin_ang, os, ot, ms, mt);
  1116. xform(mTexExtents[1], cos_ang, sin_ang, os, ot, ms, mt);
  1117. }
  1118. mLastVertexBuffer = mVertexBuffer;
  1119. mLastGeomCount = mGeomCount;
  1120. mLastGeomIndex = mGeomIndex;
  1121. mLastIndicesCount = mIndicesCount;
  1122. mLastIndicesIndex = mIndicesIndex;
  1123. return TRUE;
  1124. }
  1125. //check if the face has a media
  1126. BOOL LLFace::hasMedia() const 
  1127. {
  1128. if(mHasMedia)
  1129. {
  1130. return TRUE ;
  1131. }
  1132. if(mTexture.notNull()) 
  1133. {
  1134. return mTexture->hasParcelMedia() ;  //if has a parcel media
  1135. }
  1136. return FALSE ; //no media.
  1137. }
  1138. const F32 LEAST_IMPORTANCE = 0.05f ;
  1139. const F32 LEAST_IMPORTANCE_FOR_LARGE_IMAGE = 0.3f ;
  1140. F32 LLFace::getTextureVirtualSize()
  1141. {
  1142. F32 radius;
  1143. F32 cos_angle_to_view_dir;
  1144. BOOL in_frustum = calcPixelArea(cos_angle_to_view_dir, radius);
  1145. if (mPixelArea < 0.0001f || !in_frustum)
  1146. {
  1147. setVirtualSize(0.f) ;
  1148. return 0.f;
  1149. }
  1150. //get area of circle in texture space
  1151. LLVector2 tdim = mTexExtents[1] - mTexExtents[0];
  1152. F32 texel_area = (tdim * 0.5f).lengthSquared()*3.14159f;
  1153. if (texel_area <= 0)
  1154. {
  1155. // Probably animated, use default
  1156. texel_area = 1.f;
  1157. }
  1158. //apply texel area to face area to get accurate ratio
  1159. //face_area /= llclamp(texel_area, 1.f/64.f, 16.f);
  1160. F32 face_area = mPixelArea / llclamp(texel_area, 0.015625f, 128.f);
  1161. if(face_area > LLViewerTexture::sMaxSmallImageSize)
  1162. {
  1163. if(mImportanceToCamera < LEAST_IMPORTANCE) //if the face is not important, do not load hi-res.
  1164. {
  1165. static const F32 MAX_LEAST_IMPORTANCE_IMAGE_SIZE = 128.0f * 128.0f ;
  1166. face_area = llmin(face_area * 0.5f, MAX_LEAST_IMPORTANCE_IMAGE_SIZE) ;
  1167. }
  1168. else if(face_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.
  1169. {
  1170. if(mImportanceToCamera < LEAST_IMPORTANCE_FOR_LARGE_IMAGE)//if the face is not important, do not load hi-res.
  1171. {
  1172. face_area = LLViewerTexture::sMinLargeImageSize ;
  1173. }
  1174. else if(mTexture.notNull() && mTexture->isLargeImage())
  1175. {
  1176. face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius );
  1177. }
  1178. }
  1179. }
  1180. setVirtualSize(face_area) ;
  1181. return face_area;
  1182. }
  1183. BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
  1184. {
  1185. //get area of circle around face
  1186. LLVector3 center = getPositionAgent();
  1187. LLVector3 size = (mExtents[1] - mExtents[0]) * 0.5f;
  1188. LLViewerCamera* camera = LLViewerCamera::getInstance();
  1189. F32 size_squared = size.lengthSquared() ;
  1190. LLVector3 lookAt = center - camera->getOrigin();
  1191. F32 dist = lookAt.normVec() ;
  1192. //get area of circle around node
  1193. F32 app_angle = atanf(fsqrtf(size_squared) / dist);
  1194. radius = app_angle*LLDrawable::sCurPixelAngle;
  1195. mPixelArea = radius*radius * 3.14159f;
  1196. cos_angle_to_view_dir = lookAt * camera->getXAxis() ;
  1197. //if has media, check if the face is out of the view frustum.
  1198. if(hasMedia())
  1199. {
  1200. if(!camera->AABBInFrustum(center, size)) 
  1201. {
  1202. mImportanceToCamera = 0.f ;
  1203. return false ;
  1204. }
  1205. if(cos_angle_to_view_dir > camera->getCosHalfFov()) //the center is within the view frustum
  1206. {
  1207. cos_angle_to_view_dir = 1.0f ;
  1208. }
  1209. else
  1210. {
  1211. if(dist * dist * (lookAt - camera->getXAxis()).lengthSquared() < size_squared)
  1212. {
  1213. cos_angle_to_view_dir = 1.0f ;
  1214. }
  1215. }
  1216. }
  1217. if(dist < mBoundingSphereRadius) //camera is very close
  1218. {
  1219. cos_angle_to_view_dir = 1.0f ;
  1220. mImportanceToCamera = 1.0f ;
  1221. }
  1222. else
  1223. {
  1224. mImportanceToCamera = LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist) ;
  1225. }
  1226. return true ;
  1227. }
  1228. //the projection of the face partially overlaps with the screen
  1229. F32 LLFace::adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius )
  1230. {
  1231. F32 screen_radius = (F32)llmax(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw()) ;
  1232. F32 center_angle = acosf(cos_angle_to_view_dir) ;
  1233. F32 d = center_angle * LLDrawable::sCurPixelAngle ;
  1234. if(d + radius > screen_radius + 5.f)
  1235. {
  1236. //----------------------------------------------
  1237. //calculate the intersection area of two circles
  1238. //F32 radius_square = radius * radius ;
  1239. //F32 d_square = d * d ;
  1240. //F32 screen_radius_square = screen_radius * screen_radius ;
  1241. //face_area = 
  1242. // radius_square * acosf((d_square + radius_square - screen_radius_square)/(2 * d * radius)) +
  1243. // screen_radius_square * acosf((d_square + screen_radius_square - radius_square)/(2 * d * screen_radius)) -
  1244. // 0.5f * sqrtf((-d + radius + screen_radius) * (d + radius - screen_radius) * (d - radius + screen_radius) * (d + radius + screen_radius)) ;
  1245. //----------------------------------------------
  1246. //the above calculation is too expensive
  1247. //the below is a good estimation: bounding box of the bounding sphere:
  1248. F32 alpha = 0.5f * (radius + screen_radius - d) / radius ;
  1249. alpha = llclamp(alpha, 0.f, 1.f) ;
  1250. return alpha * alpha ;
  1251. }
  1252. return 1.0f ;
  1253. }
  1254. const S8 FACE_IMPORTANCE_LEVEL = 4 ;
  1255. const F32 FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[FACE_IMPORTANCE_LEVEL][2] = //{distance, importance_weight}
  1256. {{16.1f, 1.0f}, {32.1f, 0.5f}, {48.1f, 0.2f}, {96.1f, 0.05f} } ;
  1257. const F32 FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[FACE_IMPORTANCE_LEVEL][2] =    //{cos(angle), importance_weight}
  1258. {{0.985f /*cos(10 degrees)*/, 1.0f}, {0.94f /*cos(20 degrees)*/, 0.8f}, {0.866f /*cos(30 degrees)*/, 0.64f}, {0.0f, 0.36f}} ;
  1259. //static 
  1260. F32 LLFace::calcImportanceToCamera(F32 cos_angle_to_view_dir, F32 dist)
  1261. {
  1262. F32 importance = 0.f ;
  1263. if(cos_angle_to_view_dir > LLViewerCamera::getInstance()->getCosHalfFov() && 
  1264. dist < FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[FACE_IMPORTANCE_LEVEL - 1][0]) 
  1265. {
  1266. LLViewerCamera* camera = LLViewerCamera::getInstance();
  1267. F32 camera_moving_speed = camera->getAverageSpeed() ;
  1268. F32 camera_angular_speed = camera->getAverageAngularSpeed();
  1269. if(camera_moving_speed > 10.0f || camera_angular_speed > 1.0f)
  1270. {
  1271. //if camera moves or rotates too fast, ignore the importance factor
  1272. return 0.f ;
  1273. }
  1274. //F32 camera_relative_speed = camera_moving_speed * (lookAt * LLViewerCamera::getInstance()->getVelocityDir()) ;
  1275. S32 i = 0 ;
  1276. for(i = 0; i < FACE_IMPORTANCE_LEVEL && dist > FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][0]; ++i);
  1277. i = llmin(i, FACE_IMPORTANCE_LEVEL - 1) ;
  1278. F32 dist_factor = FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][1] ;
  1279. for(i = 0; i < FACE_IMPORTANCE_LEVEL && cos_angle_to_view_dir < FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[i][0] ; ++i) ;
  1280. i = llmin(i, FACE_IMPORTANCE_LEVEL - 1) ;
  1281. importance = dist_factor * FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[i][1] ;
  1282. }
  1283. return importance ;
  1284. }
  1285. BOOL LLFace::verify(const U32* indices_array) const
  1286. {
  1287. BOOL ok = TRUE;
  1288. if( mVertexBuffer.isNull() )
  1289. {
  1290. if( mGeomCount )
  1291. {
  1292. // This happens before teleports as faces are torn down.
  1293. // Stop the crash in DEV-31893 with a null pointer check,
  1294. // but present this info.
  1295. // To clean up the log, the geometry could be cleared, or the
  1296. // face could otherwise be marked for no ::verify.
  1297. llinfos << "Face with no vertex buffer and " << mGeomCount << " mGeomCount" << llendl;
  1298. }
  1299. return TRUE;
  1300. }
  1301. // First, check whether the face data fits within the pool's range.
  1302. if ((mGeomIndex + mGeomCount) > mVertexBuffer->getNumVerts())
  1303. {
  1304. ok = FALSE;
  1305. llinfos << "Face not within pool range!" << llendl;
  1306. }
  1307. S32 indices_count = (S32)getIndicesCount();
  1308. if (!indices_count)
  1309. {
  1310. return TRUE;
  1311. }
  1312. if (indices_count > LL_MAX_INDICES_COUNT)
  1313. {
  1314. ok = FALSE;
  1315. llinfos << "Face has bogus indices count" << llendl;
  1316. }
  1317. #if 0
  1318. S32 geom_start = getGeomStart();
  1319. S32 geom_count = mGeomCount;
  1320. const U32 *indicesp = indices_array ? indices_array + mIndicesIndex : getRawIndices();
  1321. for (S32 i = 0; i < indices_count; i++)
  1322. {
  1323. S32 delta = indicesp[i] - geom_start;
  1324. if (0 > delta)
  1325. {
  1326. llwarns << "Face index too low!" << llendl;
  1327. llinfos << "i:" << i << " Index:" << indicesp[i] << " GStart: " << geom_start << llendl;
  1328. ok = FALSE;
  1329. }
  1330. else if (delta >= geom_count)
  1331. {
  1332. llwarns << "Face index too high!" << llendl;
  1333. llinfos << "i:" << i << " Index:" << indicesp[i] << " GEnd: " << geom_start + geom_count << llendl;
  1334. ok = FALSE;
  1335. }
  1336. }
  1337. #endif
  1338. if (!ok)
  1339. {
  1340. printDebugInfo();
  1341. }
  1342. return ok;
  1343. }
  1344. void LLFace::setViewerObject(LLViewerObject* objp)
  1345. {
  1346. mVObjp = objp;
  1347. }
  1348. const LLColor4& LLFace::getRenderColor() const
  1349. {
  1350. if (isState(USE_FACE_COLOR))
  1351. {
  1352.   return mFaceColor; // Face Color
  1353. }
  1354. else
  1355. {
  1356. const LLTextureEntry* tep = getTextureEntry();
  1357. return (tep ? tep->getColor() : LLColor4::white);
  1358. }
  1359. }
  1360. void LLFace::renderSetColor() const
  1361. {
  1362. if (!LLFacePool::LLOverrideFaceColor::sOverrideFaceColor)
  1363. {
  1364. const LLColor4* color = &(getRenderColor());
  1365. glColor4fv(color->mV);
  1366. }
  1367. }
  1368. S32 LLFace::pushVertices(const U16* index_array) const
  1369. {
  1370. if (mIndicesCount)
  1371. {
  1372. mVertexBuffer->drawRange(LLRender::TRIANGLES, mGeomIndex, mGeomIndex+mGeomCount-1, mIndicesCount, mIndicesIndex);
  1373. gPipeline.addTrianglesDrawn(mIndicesCount/3);
  1374. }
  1375. return mIndicesCount;
  1376. }
  1377. const LLMatrix4& LLFace::getRenderMatrix() const
  1378. {
  1379. return mDrawablep->getRenderMatrix();
  1380. }
  1381. S32 LLFace::renderElements(const U16 *index_array) const
  1382. {
  1383. S32 ret = 0;
  1384. if (isState(GLOBAL))
  1385. {
  1386. ret = pushVertices(index_array);
  1387. }
  1388. else
  1389. {
  1390. glPushMatrix();
  1391. glMultMatrixf((float*)getRenderMatrix().mMatrix);
  1392. ret = pushVertices(index_array);
  1393. glPopMatrix();
  1394. }
  1395. return ret;
  1396. }
  1397. S32 LLFace::renderIndexed()
  1398. {
  1399. if(mDrawablep.isNull() || mDrawPoolp == NULL)
  1400. {
  1401. return 0;
  1402. }
  1403. return renderIndexed(mDrawPoolp->getVertexDataMask());
  1404. }
  1405. S32 LLFace::renderIndexed(U32 mask)
  1406. {
  1407. if (mVertexBuffer.isNull())
  1408. {
  1409. return 0;
  1410. }
  1411. mVertexBuffer->setBuffer(mask);
  1412. U16* index_array = (U16*) mVertexBuffer->getIndicesPointer();
  1413. return renderElements(index_array);
  1414. }
  1415. //============================================================================
  1416. // From llface.inl
  1417. S32 LLFace::getColors(LLStrider<LLColor4U> &colors)
  1418. {
  1419. if (!mGeomCount)
  1420. {
  1421. return -1;
  1422. }
  1423. // llassert(mGeomIndex >= 0);
  1424. mVertexBuffer->getColorStrider(colors, mGeomIndex);
  1425. return mGeomIndex;
  1426. }
  1427. S32 LLFace::getIndices(LLStrider<U16> &indicesp)
  1428. {
  1429. mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex);
  1430. llassert(indicesp[0] != indicesp[1]);
  1431. return mIndicesIndex;
  1432. }
  1433. LLVector3 LLFace::getPositionAgent() const
  1434. {
  1435. if (mDrawablep->isStatic())
  1436. {
  1437. return mCenterAgent;
  1438. }
  1439. else
  1440. {
  1441. return mCenterLocal * getRenderMatrix();
  1442. }
  1443. }
  1444. //
  1445. //atlas
  1446. //
  1447. void LLFace::removeAtlas()
  1448. {
  1449. setAtlasInUse(FALSE) ;
  1450. mAtlasInfop = NULL ;
  1451. }
  1452. const LLTextureAtlas* LLFace::getAtlas()const 
  1453. {
  1454. if(mAtlasInfop)
  1455. {
  1456. return mAtlasInfop->getAtlas() ;
  1457. }
  1458. return NULL ;
  1459. }
  1460. const LLVector2* LLFace::getTexCoordOffset()const 
  1461. {
  1462. if(isAtlasInUse())
  1463. {
  1464. return mAtlasInfop->getTexCoordOffset() ;
  1465. }
  1466. return NULL ;
  1467. }
  1468. const LLVector2* LLFace::getTexCoordScale() const 
  1469. {
  1470. if(isAtlasInUse())
  1471. {
  1472. return mAtlasInfop->getTexCoordScale() ;
  1473. }
  1474. return NULL ;
  1475. }
  1476. BOOL LLFace::isAtlasInUse()const
  1477. {
  1478. return mUsingAtlas ;
  1479. }
  1480. BOOL LLFace::canUseAtlas()const
  1481. {
  1482. //no drawable or no spatial group, do not use atlas
  1483. if(!mDrawablep || !mDrawablep->getSpatialGroup())
  1484. {
  1485. return FALSE ;
  1486. }
  1487. //if bump face, do not use atlas
  1488. if(getTextureEntry() && getTextureEntry()->getBumpmap())
  1489. {
  1490. return FALSE ;
  1491. }
  1492. //if animated texture, do not use atlas
  1493. if(isState(TEXTURE_ANIM))
  1494. {
  1495. return FALSE ;
  1496. }
  1497. return TRUE ;
  1498. }
  1499. void LLFace::setAtlasInUse(BOOL flag)
  1500. {
  1501. //no valid atlas to use.
  1502. if(flag && (!mAtlasInfop || !mAtlasInfop->isValid()))
  1503. {
  1504. flag = FALSE ;
  1505. }
  1506. if(!flag && !mUsingAtlas)
  1507. {
  1508. return ;
  1509. }
  1510. //
  1511. //at this stage (flag || mUsingAtlas) is always true.
  1512. //
  1513. //rebuild the tex coords
  1514. if(mDrawablep)
  1515. {
  1516. gPipeline.markRebuild(mDrawablep, LLDrawable::REBUILD_TCOORD);
  1517. mUsingAtlas = flag ;
  1518. }
  1519. else
  1520. {
  1521. mUsingAtlas = FALSE ;
  1522. }
  1523. }
  1524. LLTextureAtlasSlot* LLFace::getAtlasInfo()
  1525. {
  1526. return mAtlasInfop ;
  1527. }
  1528. void LLFace::setAtlasInfo(LLTextureAtlasSlot* atlasp)
  1529. {
  1530. if(mAtlasInfop != atlasp)
  1531. {
  1532. if(mAtlasInfop)
  1533. {
  1534. //llerrs << "Atlas slot changed!" << llendl ;
  1535. }
  1536. mAtlasInfop = atlasp ;
  1537. }
  1538. }
  1539. LLViewerTexture* LLFace::getTexture() const
  1540. {
  1541. if(isAtlasInUse())
  1542. {
  1543. return (LLViewerTexture*)mAtlasInfop->getAtlas() ;
  1544. }
  1545. return mTexture ;
  1546. }
  1547. //switch to atlas or switch back to gl texture 
  1548. //return TRUE if using atlas.
  1549. BOOL LLFace::switchTexture()
  1550. {
  1551. //no valid atlas or texture
  1552. if(!mAtlasInfop || !mAtlasInfop->isValid() || !mTexture)
  1553. {
  1554. return FALSE ;
  1555. }
  1556. if(mTexture->getTexelsInAtlas() >= (U32)mVSize || 
  1557. mTexture->getTexelsInAtlas() >= mTexture->getTexelsInGLTexture())
  1558. {
  1559. //switch to use atlas
  1560. //atlas resolution is qualified, use it.
  1561. if(!mUsingAtlas)
  1562. {
  1563. setAtlasInUse(TRUE) ;
  1564. }
  1565. }
  1566. else //if atlas not qualified.
  1567. {
  1568. //switch back to GL texture
  1569. if(mUsingAtlas && mTexture->isGLTextureCreated() && 
  1570. mTexture->getDiscardLevel() < mTexture->getDiscardLevelInAtlas())
  1571. {
  1572. setAtlasInUse(FALSE) ;
  1573. }
  1574. }
  1575. return mUsingAtlas ;
  1576. }