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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llvopartgroup.cpp
  3.  * @brief Group of particle systems
  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 "llvopartgroup.h"
  34. #include "lldrawpoolalpha.h"
  35. #include "llfasttimer.h"
  36. #include "message.h"
  37. #include "v2math.h"
  38. #include "llagent.h"
  39. #include "lldrawable.h"
  40. #include "llface.h"
  41. #include "llsky.h"
  42. #include "llviewercamera.h"
  43. #include "llviewerpartsim.h"
  44. #include "llviewerregion.h"
  45. #include "pipeline.h"
  46. #include "llspatialpartition.h"
  47. const F32 MAX_PART_LIFETIME = 120.f;
  48. extern U64 gFrameTime;
  49. LLVOPartGroup::LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
  50. : LLAlphaObject(id, pcode, regionp),
  51. mViewerPartGroupp(NULL)
  52. {
  53. setNumTEs(1);
  54. setTETexture(0, LLUUID::null);
  55. mbCanSelect = FALSE; // users can't select particle systems
  56. }
  57. LLVOPartGroup::~LLVOPartGroup()
  58. {
  59. }
  60. BOOL LLVOPartGroup::isActive() const
  61. {
  62. return FALSE;
  63. }
  64. F32 LLVOPartGroup::getBinRadius()
  65. return mScale.mV[0]*2.f;
  66. }
  67. void LLVOPartGroup::updateSpatialExtents(LLVector3& newMin, LLVector3& newMax)
  68. {
  69. const LLVector3& pos_agent = getPositionAgent();
  70. newMin = pos_agent - mScale;
  71. newMax = pos_agent + mScale;
  72. mDrawable->setPositionGroup(pos_agent);
  73. }
  74. BOOL LLVOPartGroup::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
  75. {
  76. return TRUE;
  77. }
  78. void LLVOPartGroup::setPixelAreaAndAngle(LLAgent &agent)
  79. {
  80. // mPixelArea is calculated during render
  81. F32 mid_scale = getMidScale();
  82. F32 range = (getRenderPosition()-LLViewerCamera::getInstance()->getOrigin()).length();
  83. if (range < 0.001f || isHUDAttachment()) // range == zero
  84. {
  85. mAppAngle = 180.f;
  86. }
  87. else
  88. {
  89. mAppAngle = (F32) atan2( mid_scale, range) * RAD_TO_DEG;
  90. }
  91. }
  92. void LLVOPartGroup::updateTextures()
  93. {
  94. // Texture stats for particles need to be updated in a different way...
  95. }
  96. LLDrawable* LLVOPartGroup::createDrawable(LLPipeline *pipeline)
  97. {
  98. pipeline->allocDrawable(this);
  99. mDrawable->setLit(FALSE);
  100. mDrawable->setRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
  101. return mDrawable;
  102. }
  103.  const F32 MAX_PARTICLE_AREA_SCALE = 0.02f; // some tuned constant, limits on how much particle area to draw
  104. F32 LLVOPartGroup::getPartSize(S32 idx)
  105. {
  106. if (idx < (S32) mViewerPartGroupp->mParticles.size())
  107. {
  108. return mViewerPartGroupp->mParticles[idx]->mScale.mV[0];
  109. }
  110. return 0.f;
  111. }
  112. LLVector3 LLVOPartGroup::getCameraPosition() const
  113. {
  114. return gAgent.getCameraPositionAgent();
  115. }
  116. static LLFastTimer::DeclareTimer FTM_UPDATE_PARTICLES("Update Particles");
  117. BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
  118. {
  119. LLFastTimer ftm(FTM_UPDATE_PARTICLES);
  120. dirtySpatialGroup();
  121. S32 num_parts = mViewerPartGroupp->getCount();
  122. LLFace *facep;
  123. LLSpatialGroup* group = drawable->getSpatialGroup();
  124. if (!group && num_parts)
  125. {
  126. drawable->movePartition();
  127. group = drawable->getSpatialGroup();
  128. }
  129. if (group && group->isVisible())
  130. {
  131. dirtySpatialGroup(TRUE);
  132. }
  133. if (!num_parts)
  134. {
  135. if (group && drawable->getNumFaces())
  136. {
  137. group->setState(LLSpatialGroup::GEOM_DIRTY);
  138. }
  139. drawable->setNumFaces(0, NULL, getTEImage(0));
  140. LLPipeline::sCompiles++;
  141. return TRUE;
  142. }
  143.   if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES)))
  144. {
  145. return TRUE;
  146. }
  147. if (num_parts > drawable->getNumFaces())
  148. {
  149. drawable->setNumFacesFast(num_parts+num_parts/4, NULL, getTEImage(0));
  150. }
  151. F32 tot_area = 0;
  152. F32 max_area = LLViewerPartSim::getMaxPartCount() * MAX_PARTICLE_AREA_SCALE; 
  153. F32 pixel_meter_ratio = LLViewerCamera::getInstance()->getPixelMeterRatio();
  154. pixel_meter_ratio *= pixel_meter_ratio;
  155. LLViewerPartSim::checkParticleCount(mViewerPartGroupp->mParticles.size()) ;
  156. S32 count=0;
  157. mDepth = 0.f;
  158. S32 i = 0 ;
  159. LLVector3 camera_agent = getCameraPosition();
  160. for (i = 0 ; i < (S32)mViewerPartGroupp->mParticles.size(); i++)
  161. {
  162. const LLViewerPart *part = mViewerPartGroupp->mParticles[i];
  163. LLVector3 part_pos_agent(part->mPosAgent);
  164. LLVector3 at(part_pos_agent - camera_agent);
  165. F32 camera_dist_squared = at.lengthSquared();
  166. F32 inv_camera_dist_squared;
  167. if (camera_dist_squared > 1.f)
  168. inv_camera_dist_squared = 1.f / camera_dist_squared;
  169. else
  170. inv_camera_dist_squared = 1.f;
  171. F32 area = part->mScale.mV[0] * part->mScale.mV[1] * inv_camera_dist_squared;
  172. tot_area = llmax(tot_area, area);
  173.  
  174. if (tot_area > max_area)
  175. {
  176. break;
  177. }
  178. count++;
  179. facep = drawable->getFace(i);
  180. if (!facep)
  181. {
  182. llwarns << "No face found for index " << i << "!" << llendl;
  183. continue;
  184. }
  185. facep->setTEOffset(i);
  186. const F32 NEAR_PART_DIST_SQ = 5.f*5.f;  // Only discard particles > 5 m from the camera
  187. const F32 MIN_PART_AREA = .005f*.005f;  // only less than 5 mm x 5 mm at 1 m from camera
  188. if (camera_dist_squared > NEAR_PART_DIST_SQ && area < MIN_PART_AREA)
  189. {
  190. facep->setSize(0, 0);
  191. continue;
  192. }
  193. facep->setSize(4, 6);
  194. facep->setViewerObject(this);
  195. if (part->mFlags & LLPartData::LL_PART_EMISSIVE_MASK)
  196. {
  197. facep->setState(LLFace::FULLBRIGHT);
  198. }
  199. else
  200. {
  201. facep->clearState(LLFace::FULLBRIGHT);
  202. }
  203. facep->mCenterLocal = part->mPosAgent;
  204. facep->setFaceColor(part->mColor);
  205. facep->setTexture(part->mImagep);
  206. //check if this particle texture is replaced by a parcel media texture.
  207. if(part->mImagep.notNull() && part->mImagep->hasParcelMedia()) 
  208. {
  209. part->mImagep->getParcelMedia()->addMediaToFace(facep) ;
  210. }
  211. mPixelArea = tot_area * pixel_meter_ratio;
  212. const F32 area_scale = 10.f; // scale area to increase priority a bit
  213. facep->setVirtualSize(mPixelArea*area_scale);
  214. }
  215. for (i = count; i < drawable->getNumFaces(); i++)
  216. {
  217. LLFace* facep = drawable->getFace(i);
  218. if (!facep)
  219. {
  220. llwarns << "No face found for index " << i << "!" << llendl;
  221. continue;
  222. }
  223. facep->setTEOffset(i);
  224. facep->setSize(0, 0);
  225. }
  226. mDrawable->movePartition();
  227. LLPipeline::sCompiles++;
  228. return TRUE;
  229. }
  230. void LLVOPartGroup::getGeometry(S32 idx,
  231. LLStrider<LLVector3>& verticesp,
  232. LLStrider<LLVector3>& normalsp, 
  233. LLStrider<LLVector2>& texcoordsp,
  234. LLStrider<LLColor4U>& colorsp, 
  235. LLStrider<U16>& indicesp)
  236. {
  237. if (idx >= (S32) mViewerPartGroupp->mParticles.size())
  238. {
  239. return;
  240. }
  241. const LLViewerPart &part = *((LLViewerPart*) (mViewerPartGroupp->mParticles[idx]));
  242. U32 vert_offset = mDrawable->getFace(idx)->getGeomIndex();
  243. LLVector3 part_pos_agent(part.mPosAgent);
  244. LLVector3 camera_agent = getCameraPosition(); 
  245. LLVector3 at = part_pos_agent - camera_agent;
  246. LLVector3 up;
  247. LLVector3 right;
  248. right = at % LLVector3(0.f, 0.f, 1.f);
  249. right.normalize();
  250. up = right % at;
  251. up.normalize();
  252. if (part.mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK)
  253. {
  254. LLVector3 normvel = part.mVelocity;
  255. normvel.normalize();
  256. LLVector2 up_fracs;
  257. up_fracs.mV[0] = normvel*right;
  258. up_fracs.mV[1] = normvel*up;
  259. up_fracs.normalize();
  260. LLVector3 new_up;
  261. LLVector3 new_right;
  262. new_up = up_fracs.mV[0] * right + up_fracs.mV[1]*up;
  263. new_right = up_fracs.mV[1] * right - up_fracs.mV[0]*up;
  264. up = new_up;
  265. right = new_right;
  266. up.normalize();
  267. right.normalize();
  268. }
  269. right *= 0.5f*part.mScale.mV[0];
  270. up *= 0.5f*part.mScale.mV[1];
  271. LLVector3 normal = -LLViewerCamera::getInstance()->getXAxis();
  272. *verticesp++ = part_pos_agent + up - right;
  273. *verticesp++ = part_pos_agent - up - right;
  274. *verticesp++ = part_pos_agent + up + right;
  275. *verticesp++ = part_pos_agent - up + right;
  276. *colorsp++ = part.mColor;
  277. *colorsp++ = part.mColor;
  278. *colorsp++ = part.mColor;
  279. *colorsp++ = part.mColor;
  280. *texcoordsp++ = LLVector2(0.f, 1.f);
  281. *texcoordsp++ = LLVector2(0.f, 0.f);
  282. *texcoordsp++ = LLVector2(1.f, 1.f);
  283. *texcoordsp++ = LLVector2(1.f, 0.f);
  284. *normalsp++   = normal;
  285. *normalsp++   = normal;
  286. *normalsp++   = normal;
  287. *normalsp++   = normal;
  288. *indicesp++ = vert_offset + 0;
  289. *indicesp++ = vert_offset + 1;
  290. *indicesp++ = vert_offset + 2;
  291. *indicesp++ = vert_offset + 1;
  292. *indicesp++ = vert_offset + 3;
  293. *indicesp++ = vert_offset + 2;
  294. }
  295. U32 LLVOPartGroup::getPartitionType() const
  296. return LLViewerRegion::PARTITION_PARTICLE; 
  297. }
  298. LLParticlePartition::LLParticlePartition()
  299. : LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB)
  300. {
  301. mRenderPass = LLRenderPass::PASS_ALPHA;
  302. mDrawableType = LLPipeline::RENDER_TYPE_PARTICLES;
  303. mPartitionType = LLViewerRegion::PARTITION_PARTICLE;
  304. mSlopRatio = 0.f;
  305. mLODPeriod = 1;
  306. }
  307. LLHUDParticlePartition::LLHUDParticlePartition() :
  308. LLParticlePartition()
  309. {
  310. mDrawableType = LLPipeline::RENDER_TYPE_HUD_PARTICLES;
  311. mPartitionType = LLViewerRegion::PARTITION_HUD_PARTICLE;
  312. }
  313. void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count)
  314. {
  315. group->mBufferUsage = mBufferUsage;
  316. mFaceList.clear();
  317. LLViewerCamera* camera = LLViewerCamera::getInstance();
  318. for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
  319. {
  320. LLDrawable* drawablep = *i;
  321. if (drawablep->isDead())
  322. {
  323. continue;
  324. }
  325. LLAlphaObject* obj = (LLAlphaObject*) drawablep->getVObj().get();
  326. obj->mDepth = 0.f;
  327. if (drawablep->isAnimating())
  328. {
  329. group->mBufferUsage = GL_STREAM_DRAW_ARB;
  330. }
  331. U32 count = 0;
  332. for (S32 j = 0; j < drawablep->getNumFaces(); ++j)
  333. {
  334. drawablep->updateFaceSize(j);
  335. LLFace* facep = drawablep->getFace(j);
  336. if ( !facep || !facep->hasGeometry())
  337. {
  338. continue;
  339. }
  340. count++;
  341. facep->mDistance = (facep->mCenterLocal - camera->getOrigin()) * camera->getAtAxis();
  342. obj->mDepth += facep->mDistance;
  343. mFaceList.push_back(facep);
  344. vertex_count += facep->getGeomCount();
  345. index_count += facep->getIndicesCount();
  346. }
  347. obj->mDepth /= count;
  348. }
  349. }
  350. static LLFastTimer::DeclareTimer FTM_REBUILD_GRASS_VB("Grass VB");
  351. static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_VB("Particle VB");
  352. void LLParticlePartition::getGeometry(LLSpatialGroup* group)
  353. {
  354. LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
  355. LLFastTimer ftm(mDrawableType == LLPipeline::RENDER_TYPE_GRASS ?
  356. FTM_REBUILD_GRASS_VB :
  357. FTM_REBUILD_PARTICLE_VB);
  358. std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater());
  359. U32 index_count = 0;
  360. U32 vertex_count = 0;
  361. group->clearDrawMap();
  362. LLVertexBuffer* buffer = group->mVertexBuffer;
  363. LLStrider<U16> indicesp;
  364. LLStrider<LLVector3> verticesp;
  365. LLStrider<LLVector3> normalsp;
  366. LLStrider<LLVector2> texcoordsp;
  367. LLStrider<LLColor4U> colorsp;
  368. buffer->getVertexStrider(verticesp);
  369. buffer->getNormalStrider(normalsp);
  370. buffer->getColorStrider(colorsp);
  371. buffer->getTexCoord0Strider(texcoordsp);
  372. buffer->getIndexStrider(indicesp);
  373. LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[mRenderPass];
  374. for (std::vector<LLFace*>::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i)
  375. {
  376. LLFace* facep = *i;
  377. LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject();
  378. facep->setGeomIndex(vertex_count);
  379. facep->setIndicesIndex(index_count);
  380. facep->mVertexBuffer = buffer;
  381. facep->setPoolType(LLDrawPool::POOL_ALPHA);
  382. object->getGeometry(facep->getTEOffset(), verticesp, normalsp, texcoordsp, colorsp, indicesp);
  383. vertex_count += facep->getGeomCount();
  384. index_count += facep->getIndicesCount();
  385. S32 idx = draw_vec.size()-1;
  386. BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
  387. F32 vsize = facep->getVirtualSize();
  388. if (idx >= 0 && draw_vec[idx]->mEnd == facep->getGeomIndex()-1 &&
  389. draw_vec[idx]->mTexture == facep->getTexture() &&
  390. (U16) (draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount()) <= (U32) gGLManager.mGLMaxVertexRange &&
  391. //draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&
  392. draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() < 4096 &&
  393. draw_vec[idx]->mFullbright == fullbright)
  394. {
  395. draw_vec[idx]->mCount += facep->getIndicesCount();
  396. draw_vec[idx]->mEnd += facep->getGeomCount();
  397. draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
  398. }
  399. else
  400. {
  401. U32 start = facep->getGeomIndex();
  402. U32 end = start + facep->getGeomCount()-1;
  403. U32 offset = facep->getIndicesStart();
  404. U32 count = facep->getIndicesCount();
  405. LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(), 
  406. //facep->getTexture(),
  407. buffer, fullbright); 
  408. info->mExtents[0] = group->mObjectExtents[0];
  409. info->mExtents[1] = group->mObjectExtents[1];
  410. info->mVSize = vsize;
  411. draw_vec.push_back(info);
  412. //for alpha sorting
  413. facep->setDrawInfo(info);
  414. }
  415. }
  416. buffer->setBuffer(0);
  417. mFaceList.clear();
  418. }
  419. F32 LLParticlePartition::calcPixelArea(LLSpatialGroup* group, LLCamera& camera)
  420. {
  421. return 1024.f;
  422. }
  423. U32 LLVOHUDPartGroup::getPartitionType() const
  424. {
  425. return LLViewerRegion::PARTITION_HUD_PARTICLE; 
  426. }
  427. LLDrawable* LLVOHUDPartGroup::createDrawable(LLPipeline *pipeline)
  428. {
  429. pipeline->allocDrawable(this);
  430. mDrawable->setLit(FALSE);
  431. mDrawable->setRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES);
  432. return mDrawable;
  433. }
  434. LLVector3 LLVOHUDPartGroup::getCameraPosition() const
  435. {
  436. return LLVector3(-1,0,0);
  437. }