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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llcloud.cpp
  3.  * @brief Implementation of viewer LLCloudLayer class
  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 "llmath.h"
  34. //#include "vmath.h"
  35. #include "v3math.h"
  36. #include "v4math.h"
  37. #include "llquaternion.h"
  38. #include "llrand.h"
  39. #include "v4color.h"
  40. #include "llwind.h"
  41. #include "llcloud.h"
  42. #include "llgl.h"
  43. #include "llviewerobjectlist.h"
  44. #include "llvoclouds.h"
  45. #include "llvosky.h"
  46. #include "llsky.h"
  47. #include "llviewerregion.h"
  48. #include "patch_dct.h"
  49. #include "patch_code.h"
  50. #include "llglheaders.h"
  51. #include "pipeline.h"
  52. #include "lldrawpool.h"
  53. #include "llworld.h"
  54. extern LLPipeline gPipeline;
  55. const F32 CLOUD_UPDATE_RATE = 1.0f;  // Global time dilation for clouds
  56. const F32 CLOUD_GROW_RATE = 0.05f;
  57. const F32 CLOUD_DECAY_RATE = -0.05f;
  58. const F32 CLOUD_VELOCITY_SCALE = 0.01f;
  59. const F32 CLOUD_DENSITY = 25.f;
  60. const S32 CLOUD_COUNT_MAX = 20;
  61. const F32 CLOUD_HEIGHT_RANGE = 48.f;
  62. const F32 CLOUD_HEIGHT_MEAN = 192.f;
  63. enum
  64. {
  65. LL_PUFF_GROWING = 0,
  66. LL_PUFF_DYING = 1
  67. };
  68. // Used for patch decoder
  69. S32 gBuffer[16*16];
  70. //static
  71. S32 LLCloudPuff::sPuffCount = 0;
  72. LLCloudPuff::LLCloudPuff() :
  73. mAlpha(0.01f),
  74. mRate(CLOUD_GROW_RATE*CLOUD_UPDATE_RATE),
  75. mLifeState(LL_PUFF_GROWING)
  76. {
  77. }
  78. LLCloudGroup::LLCloudGroup() :
  79. mCloudLayerp(NULL),
  80. mDensity(0.f),
  81. mTargetPuffCount(0),
  82. mVOCloudsp(NULL)
  83. {
  84. }
  85. void LLCloudGroup::cleanup()
  86. {
  87. if (mVOCloudsp)
  88. {
  89. if (!mVOCloudsp->isDead())
  90. {
  91. gObjectList.killObject(mVOCloudsp);
  92. }
  93. mVOCloudsp = NULL;
  94. }
  95. }
  96. void LLCloudGroup::setCenterRegion(const LLVector3 &center)
  97. {
  98. mCenterRegion = center;
  99. }
  100. void LLCloudGroup::updatePuffs(const F32 dt)
  101. {
  102. mDensity = mCloudLayerp->getDensityRegion(mCenterRegion);
  103. if (!mVOCloudsp)
  104. {
  105. mVOCloudsp = (LLVOClouds *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_CLOUDS, mCloudLayerp->getRegion());
  106. mVOCloudsp->setCloudGroup(this);
  107. mVOCloudsp->setPositionRegion(mCenterRegion);
  108. mVOCloudsp->setScale(LLVector3(256.f/CLOUD_GROUPS_PER_EDGE + CLOUD_PUFF_WIDTH,
  109.  256.f/CLOUD_GROUPS_PER_EDGE + CLOUD_PUFF_WIDTH,
  110.  CLOUD_HEIGHT_RANGE + CLOUD_PUFF_HEIGHT)*0.5f);
  111. gPipeline.createObject(mVOCloudsp);
  112. }
  113. LLVector3 velocity;
  114. LLVector3d vel_d;
  115. // Update the positions of all of the clouds
  116. for (U32 i = 0; i < mCloudPuffs.size(); i++)
  117. {
  118. LLCloudPuff &puff = mCloudPuffs[i];
  119. velocity = mCloudLayerp->getRegion()->mWind.getCloudVelocity(mCloudLayerp->getRegion()->getPosRegionFromGlobal(puff.mPositionGlobal));
  120. velocity *= CLOUD_VELOCITY_SCALE*CLOUD_UPDATE_RATE;
  121. vel_d.setVec(velocity);
  122. mCloudPuffs[i].mPositionGlobal += vel_d;
  123. mCloudPuffs[i].mAlpha += mCloudPuffs[i].mRate * dt;
  124. mCloudPuffs[i].mAlpha = llmin(1.f, mCloudPuffs[i].mAlpha);
  125. mCloudPuffs[i].mAlpha = llmax(0.f, mCloudPuffs[i].mAlpha);
  126. }
  127. }
  128. void LLCloudGroup::updatePuffOwnership()
  129. {
  130. U32 i = 0;
  131. while (i < mCloudPuffs.size())
  132. {
  133. if (mCloudPuffs[i].getLifeState() == LL_PUFF_DYING)
  134. {
  135. i++;
  136. continue;
  137. }
  138. if (inGroup(mCloudPuffs[i]))
  139. {
  140. i++;
  141. continue;
  142. }
  143. //llinfos << "Cloud moving to new group" << llendl;
  144. LLCloudGroup *new_cgp = LLWorld::getInstance()->findCloudGroup(mCloudPuffs[i]);
  145. if (!new_cgp)
  146. {
  147. //llinfos << "Killing puff not in group" << llendl;
  148. mCloudPuffs[i].setLifeState(LL_PUFF_DYING);
  149. mCloudPuffs[i].mRate = CLOUD_DECAY_RATE*CLOUD_UPDATE_RATE;
  150. i++;
  151. continue;
  152. }
  153. //llinfos << "Puff handed off!" << llendl;
  154. LLCloudPuff puff;
  155. puff.mPositionGlobal = mCloudPuffs[i].mPositionGlobal;
  156. puff.mAlpha = mCloudPuffs[i].mAlpha;
  157. mCloudPuffs.erase(mCloudPuffs.begin() + i);
  158. new_cgp->mCloudPuffs.push_back(puff);
  159. }
  160. //llinfos << "Puff count: " << LLCloudPuff::sPuffCount << llendl;
  161. }
  162. void LLCloudGroup::updatePuffCount()
  163. {
  164. if (!mVOCloudsp)
  165. {
  166. return;
  167. }
  168. S32 i;
  169. S32 target_puff_count = llround(CLOUD_DENSITY * mDensity);
  170. target_puff_count = llmax(0, target_puff_count);
  171. target_puff_count = llmin(CLOUD_COUNT_MAX, target_puff_count);
  172. S32 current_puff_count = (S32) mCloudPuffs.size();
  173. // Create a new cloud if we need one
  174. if (current_puff_count < target_puff_count)
  175. {
  176. LLVector3d puff_pos_global;
  177. mCloudPuffs.resize(target_puff_count);
  178. for (i = current_puff_count; i < target_puff_count; i++)
  179. {
  180. puff_pos_global = mVOCloudsp->getPositionGlobal();
  181. F32 x = ll_frand(256.f/CLOUD_GROUPS_PER_EDGE) - 128.f/CLOUD_GROUPS_PER_EDGE;
  182. F32 y = ll_frand(256.f/CLOUD_GROUPS_PER_EDGE) - 128.f/CLOUD_GROUPS_PER_EDGE;
  183. F32 z = ll_frand(CLOUD_HEIGHT_RANGE) - 0.5f*CLOUD_HEIGHT_RANGE;
  184. puff_pos_global += LLVector3d(x, y, z);
  185. mCloudPuffs[i].mPositionGlobal = puff_pos_global;
  186. mCloudPuffs[i].mAlpha = 0.01f;
  187. LLCloudPuff::sPuffCount++;
  188. }
  189. }
  190. // Count the number of live puffs
  191. S32 live_puff_count = 0;
  192. for (i = 0; i < (S32) mCloudPuffs.size(); i++)
  193. {
  194. if (mCloudPuffs[i].getLifeState() != LL_PUFF_DYING)
  195. {
  196. live_puff_count++;
  197. }
  198. }
  199. // Start killing enough puffs so the live puff count == target puff count
  200. S32 new_dying_count = llmax(0, live_puff_count - target_puff_count);
  201. i = 0;
  202. while (new_dying_count > 0)
  203. {
  204. if (mCloudPuffs[i].getLifeState() != LL_PUFF_DYING)
  205. {
  206. //llinfos << "Killing extra live cloud" << llendl;
  207. mCloudPuffs[i].setLifeState(LL_PUFF_DYING);
  208. mCloudPuffs[i].mRate = CLOUD_DECAY_RATE*CLOUD_UPDATE_RATE;
  209. new_dying_count--;
  210. }
  211. i++;
  212. }
  213. // Remove fully dead puffs
  214. i = 0;
  215. while (i < (S32) mCloudPuffs.size())
  216. {
  217. if (mCloudPuffs[i].isDead())
  218. {
  219. //llinfos << "Removing dead puff!" << llendl;
  220. mCloudPuffs.erase(mCloudPuffs.begin() + i);
  221. LLCloudPuff::sPuffCount--;
  222. }
  223. else
  224. {
  225. i++;
  226. }
  227. }
  228. }
  229. BOOL LLCloudGroup::inGroup(const LLCloudPuff &puff) const
  230. {
  231. // Do min/max check on center of the cloud puff
  232. F32 min_x, min_y, max_x, max_y;
  233. F32 delta = 128.f/CLOUD_GROUPS_PER_EDGE;
  234. min_x = mCenterRegion.mV[VX] - delta;
  235. min_y = mCenterRegion.mV[VY] - delta;
  236. max_x = mCenterRegion.mV[VX] + delta;
  237. max_y = mCenterRegion.mV[VY] + delta;
  238. LLVector3 pos_region = mCloudLayerp->getRegion()->getPosRegionFromGlobal(puff.getPositionGlobal());
  239. if ((pos_region.mV[VX] < min_x)
  240. || (pos_region.mV[VY] < min_y)
  241. || (pos_region.mV[VX] > max_x)
  242. || (pos_region.mV[VY] > max_y))
  243. {
  244. return FALSE;
  245. }
  246. return TRUE;
  247. }
  248. LLCloudLayer::LLCloudLayer()
  249. :  mOriginGlobal(0.0f, 0.0f, 0.0f),
  250. mMetersPerEdge(1.0f),
  251. mMetersPerGrid(1.0f),
  252. mWindp(NULL),
  253. mDensityp(NULL)
  254. {
  255. S32 i, j;
  256. for (i = 0; i < 4; i++)
  257. {
  258. mNeighbors[i] = NULL;
  259. }
  260. F32 x, y;
  261. for (i = 0; i < CLOUD_GROUPS_PER_EDGE; i++)
  262. {
  263. y = (0.5f + i)*(256.f/CLOUD_GROUPS_PER_EDGE);
  264. for (j = 0; j < CLOUD_GROUPS_PER_EDGE; j++)
  265. {
  266. x = (0.5f + j)*(256.f/CLOUD_GROUPS_PER_EDGE);
  267. mCloudGroups[i][j].setCloudLayerp(this);
  268. mCloudGroups[i][j].setCenterRegion(LLVector3(x, y, CLOUD_HEIGHT_MEAN));
  269. }
  270. }
  271. }
  272. LLCloudLayer::~LLCloudLayer()
  273. {
  274. destroy();
  275. }
  276. void LLCloudLayer::create(LLViewerRegion *regionp)
  277. {
  278. llassert(regionp);
  279. mRegionp = regionp;
  280. mDensityp = new F32 [CLOUD_GRIDS_PER_EDGE * CLOUD_GRIDS_PER_EDGE];
  281. U32 i;
  282. for (i = 0; i < CLOUD_GRIDS_PER_EDGE*CLOUD_GRIDS_PER_EDGE; i++)
  283. {
  284. mDensityp[i] = 0.f;
  285. }
  286. }
  287. void LLCloudLayer::setRegion(LLViewerRegion *regionp)
  288. {
  289. mRegionp = regionp;
  290. }
  291. void LLCloudLayer::destroy()
  292. {
  293. // Kill all of the existing puffs
  294. S32 i, j;
  295. for (i = 0; i < CLOUD_GROUPS_PER_EDGE; i++)
  296. {
  297. for (j = 0; j < CLOUD_GROUPS_PER_EDGE; j++)
  298. {
  299. mCloudGroups[i][j].cleanup();
  300. }
  301. }
  302. delete [] mDensityp;
  303. mDensityp = NULL;
  304. mWindp = NULL;
  305. }
  306. void LLCloudLayer::reset()
  307. {
  308. }
  309. void LLCloudLayer::setWindPointer(LLWind *windp)
  310. {
  311. if (mWindp)
  312. {
  313. mWindp->setCloudDensityPointer(NULL);
  314. }
  315. mWindp = windp;
  316. if (mWindp)
  317. {
  318. mWindp->setCloudDensityPointer(mDensityp);
  319. }
  320. }
  321. void LLCloudLayer::setWidth(F32 width)
  322. {
  323. mMetersPerEdge = width;
  324. mMetersPerGrid = width / CLOUD_GRIDS_PER_EDGE;
  325. }
  326. F32 LLCloudLayer::getDensityRegion(const LLVector3 &pos_region)
  327. {
  328. // "position" is region-local
  329. S32 i, j, ii, jj;
  330. i = lltrunc(pos_region.mV[VX] / mMetersPerGrid);
  331. j = lltrunc(pos_region.mV[VY] / mMetersPerGrid);
  332. ii = i + 1;
  333. jj = j + 1;
  334. // clamp 
  335. if (i >= (S32)CLOUD_GRIDS_PER_EDGE)
  336. {
  337. i = CLOUD_GRIDS_PER_EDGE - 1;
  338. ii = i;
  339. }
  340. else if (i < 0)
  341. {
  342. i = 0;
  343. ii = i;
  344. }
  345. else if (ii >= (S32)CLOUD_GRIDS_PER_EDGE || ii < 0)
  346. {
  347. ii = i;
  348. }
  349. if (j >= (S32)CLOUD_GRIDS_PER_EDGE)
  350. {
  351. j = CLOUD_GRIDS_PER_EDGE - 1;
  352. jj = j;
  353. }
  354. else if (j < 0)
  355. {
  356. j = 0;
  357. jj = j;
  358. }
  359. else if (jj >= (S32)CLOUD_GRIDS_PER_EDGE || jj < 0)
  360. {
  361. jj = j;
  362. }
  363. F32 dx = (pos_region.mV[VX] - (F32) i * mMetersPerGrid) / mMetersPerGrid;
  364. F32 dy = (pos_region.mV[VY] - (F32) j * mMetersPerGrid) / mMetersPerGrid;
  365. F32 omdx = 1.0f - dx;
  366. F32 omdy = 1.0f - dy;
  367. F32 density = dx * dy * *(mDensityp + ii + jj * CLOUD_GRIDS_PER_EDGE) + 
  368.       dx * omdy * *(mDensityp + i + jj * CLOUD_GRIDS_PER_EDGE) +
  369.   omdx * dy * *(mDensityp + ii + j * CLOUD_GRIDS_PER_EDGE) +
  370.   omdx * omdy * *(mDensityp + i + j * CLOUD_GRIDS_PER_EDGE);   
  371. return density;
  372. }
  373. void LLCloudLayer::decompress(LLBitPack &bitpack, LLGroupHeader *group_headerp)
  374. {
  375. LLPatchHeader  patch_header;
  376. init_patch_decompressor(group_headerp->patch_size);
  377. // Don't use the packed group_header stride because the strides used on
  378. // simulator and viewer are not equal.
  379. group_headerp->stride = group_headerp->patch_size;  // offset required to step up one row
  380. set_group_of_patch_header(group_headerp);
  381. decode_patch_header(bitpack, &patch_header);
  382. decode_patch(bitpack, gBuffer);
  383. decompress_patch(mDensityp, gBuffer, &patch_header); 
  384. }
  385. void LLCloudLayer::updatePuffs(const F32 dt)
  386. {
  387. // We want to iterate through all of the cloud groups
  388. // and update their density targets
  389. S32 i, j;
  390. for (i = 0; i < CLOUD_GROUPS_PER_EDGE; i++)
  391. {
  392. for (j = 0; j < CLOUD_GROUPS_PER_EDGE; j++)
  393. {
  394. mCloudGroups[i][j].updatePuffs(dt);
  395. }
  396. }
  397. }
  398. void LLCloudLayer::updatePuffOwnership()
  399. {
  400. S32 i, j;
  401. for (i = 0; i < CLOUD_GROUPS_PER_EDGE; i++)
  402. {
  403. for (j = 0; j < CLOUD_GROUPS_PER_EDGE; j++)
  404. {
  405. mCloudGroups[i][j].updatePuffOwnership();
  406. }
  407. }
  408. }
  409. void LLCloudLayer::updatePuffCount()
  410. {
  411. S32 i, j;
  412. for (i = 0; i < CLOUD_GROUPS_PER_EDGE; i++)
  413. {
  414. for (j = 0; j < CLOUD_GROUPS_PER_EDGE; j++)
  415. {
  416. mCloudGroups[i][j].updatePuffCount();
  417. }
  418. }
  419. }
  420. LLCloudGroup *LLCloudLayer::findCloudGroup(const LLCloudPuff &puff)
  421. {
  422. S32 i, j;
  423. for (i = 0; i < CLOUD_GROUPS_PER_EDGE; i++)
  424. {
  425. for (j = 0; j < CLOUD_GROUPS_PER_EDGE; j++)
  426. {
  427. if (mCloudGroups[i][j].inGroup(puff))
  428. {
  429. return &(mCloudGroups[i][j]);
  430. }
  431. }
  432. }
  433. return NULL;
  434. }
  435. void LLCloudLayer::connectNeighbor(LLCloudLayer *cloudp, U32 direction)
  436. {
  437. if (direction >= 4)
  438. {
  439. // Only care about cardinal 4 directions.
  440. return;
  441. }
  442. mNeighbors[direction] = cloudp;
  443. if (cloudp)
  444. mNeighbors[direction]->mNeighbors[gDirOpposite[direction]] = this;
  445. }
  446. void LLCloudLayer::disconnectNeighbor(U32 direction)
  447. {
  448. if (direction >= 4)
  449. {
  450. // Only care about cardinal 4 directions.
  451. return;
  452. }
  453. if (mNeighbors[direction])
  454. {
  455. mNeighbors[direction]->mNeighbors[gDirOpposite[direction]] = NULL;
  456. mNeighbors[direction] = NULL;
  457. }
  458. }
  459. void LLCloudLayer::disconnectAllNeighbors()
  460. {
  461. S32 i;
  462. for (i = 0; i < 4; i++)
  463. {
  464. disconnectNeighbor(i);
  465. }
  466. }