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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llviewerpartsource.cpp
  3.  * @brief LLViewerPartSource class implementation
  4.  *
  5.  * $LicenseInfo:firstyear=2003&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2003-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 "llviewerpartsource.h"
  34. #include "llviewercontrol.h"
  35. #include "llrender.h"
  36. #include "llagent.h"
  37. #include "lldrawable.h"
  38. #include "llviewercamera.h"
  39. #include "llviewertexturelist.h"
  40. #include "llviewerobject.h"
  41. #include "llviewerobjectlist.h"
  42. #include "llvoavatar.h"
  43. #include "llworld.h"
  44. #include "pipeline.h"
  45. LLViewerPartSource::LLViewerPartSource(const U32 type) :
  46. mType(type),
  47. mOwnerUUID(LLUUID::null),
  48. mPartFlags(0)
  49. {
  50. mLastUpdateTime = 0.f;
  51. mLastPartTime = 0.f;
  52. mIsDead = FALSE;
  53. mIsSuspended = FALSE;
  54. static U32 id_seed = 0;
  55. mID = ++id_seed;
  56. mDelay = 0 ;
  57. }
  58. void LLViewerPartSource::setDead()
  59. {
  60. mIsDead = TRUE;
  61. }
  62. void LLViewerPartSource::updatePart(LLViewerPart &part, const F32 dt)
  63. {
  64. }
  65. void LLViewerPartSource::update(const F32 dt) 
  66. {
  67. llerrs << "Creating default part source!" << llendl;
  68. }
  69. LLUUID LLViewerPartSource::getImageUUID() const
  70. {
  71. LLViewerTexture* imagep = mImagep;
  72. if(imagep)
  73. {
  74. return imagep->getID();
  75. }
  76. return LLUUID::null;
  77. }
  78. void LLViewerPartSource::setStart()
  79. {
  80. //cancel delaying to start a new added particle source, because some particle source just emits for a short time.
  81. //however, canceling this might cause overall particle emmitting fluctuate for a while because the new added source jumps to 
  82. //the current particle emmitting settings instantly. -->bao
  83. mDelay = 0 ; //99
  84. }
  85. LLViewerPartSourceScript::LLViewerPartSourceScript(LLViewerObject *source_objp) :
  86. LLViewerPartSource(LL_PART_SOURCE_SCRIPT)
  87. {
  88. LLMemType mt(LLMemType::MTYPE_PARTICLES);
  89. llassert(source_objp);
  90. mSourceObjectp = source_objp;
  91. mPosAgent = mSourceObjectp->getPositionAgent();
  92. mImagep = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c");
  93. mImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
  94. }
  95. void LLViewerPartSourceScript::setDead()
  96. {
  97. LLMemType mt(LLMemType::MTYPE_PARTICLES);
  98. mIsDead = TRUE;
  99. mSourceObjectp = NULL;
  100. mTargetObjectp = NULL;
  101. }
  102. void LLViewerPartSourceScript::update(const F32 dt)
  103. {
  104. if( mIsSuspended )
  105. return;
  106. LLMemType mt(LLMemType::MTYPE_PARTICLES);
  107. F32 old_update_time = mLastUpdateTime;
  108. mLastUpdateTime += dt;
  109. F32 ref_rate_travelspeed = llmin(LLViewerPartSim::getInstance()->getRefRate(), 1.f);
  110. F32 dt_update = mLastUpdateTime - mLastPartTime;
  111. // Update this for objects which have the follow flag set...
  112. if (!mSourceObjectp.isNull())
  113. {
  114. if (mSourceObjectp->isDead())
  115. {
  116. mSourceObjectp = NULL;
  117. }
  118. else if (mSourceObjectp->mDrawable.notNull())
  119. {
  120. mPosAgent = mSourceObjectp->getRenderPosition();
  121. }
  122. }
  123. if (mTargetObjectp.isNull() 
  124. && mPartSysData.mTargetUUID.notNull())
  125. {
  126. //
  127. // Hmm, missing object, let's see if we can find it...
  128. //
  129. LLViewerObject *target_objp = gObjectList.findObject(mPartSysData.mTargetUUID);
  130. setTargetObject(target_objp);
  131. }
  132. if (!mTargetObjectp.isNull())
  133. {
  134. if (mTargetObjectp->isDead())
  135. {
  136. mTargetObjectp = NULL;
  137. }
  138. else if (mTargetObjectp->mDrawable.notNull())
  139. {
  140. mTargetPosAgent = mTargetObjectp->getRenderPosition();
  141. }
  142. }
  143. if (!mTargetObjectp)
  144. {
  145. mTargetPosAgent = mPosAgent;
  146. }
  147. if (mPartSysData.mMaxAge && ((mPartSysData.mStartAge + mLastUpdateTime + dt_update) > mPartSysData.mMaxAge))
  148. {
  149. // Kill particle source because it has outlived its max age...
  150. setDead();
  151. return;
  152. }
  153. if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PARTICLES))
  154. {
  155. if (mSourceObjectp.notNull())
  156. {
  157. std::ostringstream ostr;
  158. ostr << mPartSysData;
  159. mSourceObjectp->setDebugText(ostr.str());
  160. }
  161. }
  162. BOOL first_run = FALSE;
  163. if (old_update_time <= 0.f)
  164. {
  165. first_run = TRUE;
  166. }
  167. F32 max_time = llmax(1.f, 10.f*mPartSysData.mBurstRate);
  168. dt_update = llmin(max_time, dt_update);
  169. while ((dt_update > mPartSysData.mBurstRate) || first_run)
  170. {
  171. first_run = FALSE;
  172. // Update the rotation of the particle source by the angular velocity
  173. // First check to see if there is still an angular velocity.
  174. F32 angular_velocity_mag = mPartSysData.mAngularVelocity.magVec();
  175. if (angular_velocity_mag != 0.0f)
  176. {
  177. F32 av_angle = dt * angular_velocity_mag;
  178. LLQuaternion dquat(av_angle, mPartSysData.mAngularVelocity);
  179. mRotation *= dquat;
  180. }
  181. else
  182. {
  183. // No angular velocity.  Reset our rotation.
  184. mRotation.setQuat(0, 0, 0);
  185. }
  186. if (LLViewerPartSim::getInstance()->aboveParticleLimit())
  187. {
  188. // Don't bother doing any more updates if we're above the particle limit,
  189. // just give up.
  190. mLastPartTime = mLastUpdateTime;
  191.             break;
  192. }
  193. // find the greatest length that the shortest side of a system
  194. // particle is expected to have
  195. F32 max_short_side =
  196. llmax(
  197.       llmax(llmin(mPartSysData.mPartData.mStartScale[0],
  198.   mPartSysData.mPartData.mStartScale[1]),
  199.     llmin(mPartSysData.mPartData.mEndScale[0],
  200.   mPartSysData.mPartData.mEndScale[1])),
  201.       llmin((mPartSysData.mPartData.mStartScale[0]
  202.      + mPartSysData.mPartData.mEndScale[0])/2,
  203.     (mPartSysData.mPartData.mStartScale[1]
  204.      + mPartSysData.mPartData.mEndScale[1])/2));
  205. F32 pixel_meter_ratio = LLViewerCamera::getInstance()->getPixelMeterRatio();
  206. // Maximum distance at which spawned particles will be viewable
  207. F32 max_dist = max_short_side * pixel_meter_ratio; 
  208. if (max_dist < 0.25f)
  209. {
  210. // < 1 pixel wide at a distance of >=25cm.  Particles
  211. // this tiny are useless and mostly spawned by buggy
  212. // sources
  213. mLastPartTime = mLastUpdateTime;
  214. break;
  215. }
  216. // Distance from camera
  217. F32 dist = (mPosAgent - LLViewerCamera::getInstance()->getOrigin()).magVec();
  218. // Particle size vs distance vs maxage throttling
  219. F32 limited_rate=0.f;
  220. if (dist - max_dist > 0.f)
  221. {
  222. if((dist - max_dist) * ref_rate_travelspeed > mPartSysData.mPartData.mMaxAge - 0.2f )
  223. {
  224. // You need to travel faster than 1 divided by reference rate m/s directly towards these particles to see them at least 0.2s
  225. mLastPartTime = mLastUpdateTime;
  226. break;
  227. }
  228. limited_rate = ((dist - max_dist) * ref_rate_travelspeed) / mPartSysData.mPartData.mMaxAge;
  229. }
  230. if(mDelay)
  231. {
  232. limited_rate = llmax(limited_rate, 0.01f * mDelay--) ;
  233. }
  234. S32 i;
  235. for (i = 0; i < mPartSysData.mBurstPartCount; i++)
  236. {
  237. if (ll_frand() < llmax(1.0f - LLViewerPartSim::getInstance()->getBurstRate(), limited_rate))
  238. {
  239. // Limit particle generation
  240. continue;
  241. }
  242. LLViewerPart* part = new LLViewerPart();
  243. part->init(this, mImagep, NULL);
  244. part->mFlags = mPartSysData.mPartData.mFlags;
  245. if (!mSourceObjectp.isNull() && mSourceObjectp->isHUDAttachment())
  246. {
  247. part->mFlags |= LLPartData::LL_PART_HUD;
  248. }
  249. part->mMaxAge = mPartSysData.mPartData.mMaxAge;
  250. part->mStartColor = mPartSysData.mPartData.mStartColor;
  251. part->mEndColor = mPartSysData.mPartData.mEndColor;
  252. part->mColor = part->mStartColor;
  253. part->mStartScale = mPartSysData.mPartData.mStartScale;
  254. part->mEndScale = mPartSysData.mPartData.mEndScale;
  255. part->mScale = part->mStartScale;
  256. part->mAccel = mPartSysData.mPartAccel;
  257. if (mPartSysData.mPattern & LLPartSysData::LL_PART_SRC_PATTERN_DROP)
  258. {
  259. part->mPosAgent = mPosAgent;
  260. part->mVelocity.setVec(0.f, 0.f, 0.f);
  261. }
  262. else if (mPartSysData.mPattern & LLPartSysData::LL_PART_SRC_PATTERN_EXPLODE)
  263. {
  264. part->mPosAgent = mPosAgent;
  265. LLVector3 part_dir_vector;
  266. F32 mvs;
  267. do
  268. {
  269. part_dir_vector.mV[VX] = ll_frand(2.f) - 1.f;
  270. part_dir_vector.mV[VY] = ll_frand(2.f) - 1.f;
  271. part_dir_vector.mV[VZ] = ll_frand(2.f) - 1.f;
  272. mvs = part_dir_vector.magVecSquared();
  273. }
  274. while ((mvs > 1.f) || (mvs < 0.01f));
  275. part_dir_vector.normVec();
  276. part->mPosAgent += mPartSysData.mBurstRadius*part_dir_vector;
  277. part->mVelocity = part_dir_vector;
  278. F32 speed = mPartSysData.mBurstSpeedMin + ll_frand(mPartSysData.mBurstSpeedMax - mPartSysData.mBurstSpeedMin);
  279. part->mVelocity *= speed;
  280. }
  281. else if (mPartSysData.mPattern & LLPartSysData::LL_PART_SRC_PATTERN_ANGLE
  282. || mPartSysData.mPattern & LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE)
  283. {
  284. part->mPosAgent = mPosAgent;
  285. // original implemenetation for part_dir_vector was just:
  286. LLVector3 part_dir_vector(0.0, 0.0, 1.0);
  287. // params from the script...
  288. // outer = outer cone angle
  289. // inner = inner cone angle
  290. // between outer and inner there will be particles
  291. F32 innerAngle = mPartSysData.mInnerAngle;
  292. F32 outerAngle = mPartSysData.mOuterAngle;
  293. // generate a random angle within the given space...
  294. F32 angle = innerAngle + ll_frand(outerAngle - innerAngle);
  295. // split which side it will go on randomly...
  296. if (ll_frand() < 0.5) 
  297. {
  298. angle = -angle;
  299. }
  300. // Both patterns rotate around the x-axis first:
  301. part_dir_vector.rotVec(angle, 1.0, 0.0, 0.0);
  302. // If this is a cone pattern, rotate again to create the cone.
  303. if (mPartSysData.mPattern & LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE)
  304. {
  305. part_dir_vector.rotVec(ll_frand(4*F_PI), 0.0, 0.0, 1.0);
  306. }
  307. // Only apply this rotation if using the deprecated angles. 
  308. if (! (mPartSysData.mFlags & LLPartSysData::LL_PART_USE_NEW_ANGLE))
  309. {
  310. // Deprecated...
  311. part_dir_vector.rotVec(outerAngle, 1.0, 0.0, 0.0);
  312. }
  313. if (mSourceObjectp)
  314. {
  315. part_dir_vector = part_dir_vector * mSourceObjectp->getRenderRotation();
  316. }
  317. part_dir_vector = part_dir_vector * mRotation;
  318. part->mPosAgent += mPartSysData.mBurstRadius*part_dir_vector;
  319. part->mVelocity = part_dir_vector;
  320. F32 speed = mPartSysData.mBurstSpeedMin + ll_frand(mPartSysData.mBurstSpeedMax - mPartSysData.mBurstSpeedMin);
  321. part->mVelocity *= speed;
  322. }
  323. else
  324. {
  325. part->mPosAgent = mPosAgent;
  326. part->mVelocity.setVec(0.f, 0.f, 0.f);
  327. //llwarns << "Unknown source pattern " << (S32)mPartSysData.mPattern << llendl;
  328. }
  329. if (part->mFlags & LLPartData::LL_PART_FOLLOW_SRC_MASK || // SVC-193, VWR-717
  330. part->mFlags & LLPartData::LL_PART_TARGET_LINEAR_MASK) 
  331. {
  332. mPartSysData.mBurstRadius = 0; 
  333. }
  334. LLViewerPartSim::getInstance()->addPart(part);
  335. }
  336. mLastPartTime = mLastUpdateTime;
  337. dt_update -= mPartSysData.mBurstRate;
  338. }
  339. }
  340. // static
  341. LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, const S32 block_num)
  342. {
  343. LLMemType mt(LLMemType::MTYPE_PARTICLES);
  344. if (!pssp)
  345. {
  346. if (LLPartSysData::isNullPS(block_num))
  347. {
  348. return NULL;
  349. }
  350. LLPointer<LLViewerPartSourceScript> new_pssp = new LLViewerPartSourceScript(source_objp);
  351. if (!new_pssp->mPartSysData.unpackBlock(block_num))
  352. {
  353. return NULL;
  354. }
  355. if (new_pssp->mPartSysData.mTargetUUID.notNull())
  356. {
  357. LLViewerObject *target_objp = gObjectList.findObject(new_pssp->mPartSysData.mTargetUUID);
  358. new_pssp->setTargetObject(target_objp);
  359. }
  360. return new_pssp;
  361. }
  362. else
  363. {
  364. if (LLPartSysData::isNullPS(block_num))
  365. {
  366. return NULL;
  367. }
  368. if (!pssp->mPartSysData.unpackBlock(block_num))
  369. {
  370. return NULL;
  371. }
  372. if (pssp->mPartSysData.mTargetUUID.notNull())
  373. {
  374. LLViewerObject *target_objp = gObjectList.findObject(pssp->mPartSysData.mTargetUUID);
  375. pssp->setTargetObject(target_objp);
  376. }
  377. return pssp;
  378. }
  379. }
  380. LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, LLDataPacker &dp)
  381. {
  382. LLMemType mt(LLMemType::MTYPE_PARTICLES);
  383. if (!pssp)
  384. {
  385. LLPointer<LLViewerPartSourceScript> new_pssp = new LLViewerPartSourceScript(source_objp);
  386. if (!new_pssp->mPartSysData.unpack(dp))
  387. {
  388. return NULL;
  389. }
  390. if (new_pssp->mPartSysData.mTargetUUID.notNull())
  391. {
  392. LLViewerObject *target_objp = gObjectList.findObject(new_pssp->mPartSysData.mTargetUUID);
  393. new_pssp->setTargetObject(target_objp);
  394. }
  395. return new_pssp;
  396. }
  397. else
  398. {
  399. if (!pssp->mPartSysData.unpack(dp))
  400. {
  401. return NULL;
  402. }
  403. if (pssp->mPartSysData.mTargetUUID.notNull())
  404. {
  405. LLViewerObject *target_objp = gObjectList.findObject(pssp->mPartSysData.mTargetUUID);
  406. pssp->setTargetObject(target_objp);
  407. }
  408. return pssp;
  409. }
  410. }
  411. /* static */
  412. LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::createPSS(LLViewerObject *source_objp, const LLPartSysData& particle_parameters)
  413. {
  414. LLMemType mt(LLMemType::MTYPE_PARTICLES);
  415. LLPointer<LLViewerPartSourceScript> new_pssp = new LLViewerPartSourceScript(source_objp);
  416. new_pssp->mPartSysData = particle_parameters;
  417. if (new_pssp->mPartSysData.mTargetUUID.notNull())
  418. {
  419. LLViewerObject *target_objp = gObjectList.findObject(new_pssp->mPartSysData.mTargetUUID);
  420. new_pssp->setTargetObject(target_objp);
  421. }
  422. return new_pssp;
  423. }
  424. void LLViewerPartSourceScript::setImage(LLViewerTexture *imagep)
  425. {
  426. LLMemType mt(LLMemType::MTYPE_PARTICLES);
  427. mImagep = imagep;
  428. }
  429. void LLViewerPartSourceScript::setTargetObject(LLViewerObject *objp)
  430. {
  431. LLMemType mt(LLMemType::MTYPE_PARTICLES);
  432. mTargetObjectp = objp;
  433. }
  434. LLViewerPartSourceSpiral::LLViewerPartSourceSpiral(const LLVector3 &pos) :
  435. LLViewerPartSource(LL_PART_SOURCE_CHAT)
  436. {
  437. mPosAgent = pos;
  438. }
  439. void LLViewerPartSourceSpiral::setDead()
  440. {
  441. LLMemType mt(LLMemType::MTYPE_PARTICLES);
  442. mIsDead = TRUE;
  443. mSourceObjectp = NULL;
  444. }
  445. void LLViewerPartSourceSpiral::updatePart(LLViewerPart &part, const F32 dt)
  446. {
  447. LLMemType mt(LLMemType::MTYPE_PARTICLES);
  448. F32 frac = part.mLastUpdateTime/part.mMaxAge;
  449. LLVector3 center_pos;
  450. LLPointer<LLViewerPartSource>& ps = part.mPartSourcep;
  451. LLViewerPartSourceSpiral *pss = (LLViewerPartSourceSpiral *)ps.get();
  452. if (!pss->mSourceObjectp.isNull() && !pss->mSourceObjectp->mDrawable.isNull())
  453. {
  454. part.mPosAgent = pss->mSourceObjectp->getRenderPosition();
  455. }
  456. else
  457. {
  458. part.mPosAgent = pss->mPosAgent;
  459. }
  460. F32 x = sin(F_TWO_PI*frac + part.mParameter);
  461. F32 y = cos(F_TWO_PI*frac + part.mParameter);
  462. part.mPosAgent.mV[VX] += x;
  463. part.mPosAgent.mV[VY] += y;
  464. part.mPosAgent.mV[VZ] += -0.5f + frac;
  465. }
  466. void LLViewerPartSourceSpiral::update(const F32 dt)
  467. {
  468. LLMemType mt(LLMemType::MTYPE_PARTICLES);
  469. if (!mImagep)
  470. {
  471. mImagep = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c");
  472. }
  473. const F32 RATE = 0.025f;
  474. mLastUpdateTime += dt;
  475. F32 dt_update = mLastUpdateTime - mLastPartTime;
  476. F32 max_time = llmax(1.f, 10.f*RATE);
  477. dt_update = llmin(max_time, dt_update);
  478. if (dt_update > RATE)
  479. {
  480. mLastPartTime = mLastUpdateTime;
  481. if (!LLViewerPartSim::getInstance()->shouldAddPart())
  482. {
  483. // Particle simulation says we have too many particles, skip all this
  484. return;
  485. }
  486. if (!mSourceObjectp.isNull() && !mSourceObjectp->mDrawable.isNull())
  487. {
  488. mPosAgent = mSourceObjectp->getRenderPosition();
  489. }
  490. LLViewerPart* part = new LLViewerPart();
  491. part->init(this, mImagep, updatePart);
  492. part->mStartColor = mColor;
  493. part->mEndColor = mColor;
  494. part->mEndColor.mV[3] = 0.f;
  495. part->mPosAgent = mPosAgent;
  496. part->mMaxAge = 1.f;
  497. part->mFlags = LLViewerPart::LL_PART_INTERP_COLOR_MASK;
  498. part->mLastUpdateTime = 0.f;
  499. part->mScale.mV[0] = 0.25f;
  500. part->mScale.mV[1] = 0.25f;
  501. part->mParameter = ll_frand(F_TWO_PI);
  502. LLViewerPartSim::getInstance()->addPart(part);
  503. }
  504. }
  505. void LLViewerPartSourceSpiral::setSourceObject(LLViewerObject *objp)
  506. {
  507. LLMemType mt(LLMemType::MTYPE_PARTICLES);
  508. mSourceObjectp = objp;
  509. }
  510. void LLViewerPartSourceSpiral::setColor(const LLColor4 &color)
  511. {
  512. mColor = color;
  513. }
  514. LLViewerPartSourceBeam::LLViewerPartSourceBeam() :
  515. LLViewerPartSource(LL_PART_SOURCE_BEAM)
  516. {
  517. }
  518. LLViewerPartSourceBeam::~LLViewerPartSourceBeam()
  519. {
  520. }
  521. void LLViewerPartSourceBeam::setDead()
  522. {
  523. LLMemType mt(LLMemType::MTYPE_PARTICLES);
  524. mIsDead = TRUE;
  525. mSourceObjectp = NULL;
  526. mTargetObjectp = NULL;
  527. }
  528. void LLViewerPartSourceBeam::setColor(const LLColor4 &color)
  529. {
  530. mColor = color;
  531. }
  532. void LLViewerPartSourceBeam::updatePart(LLViewerPart &part, const F32 dt)
  533. {
  534. LLMemType mt(LLMemType::MTYPE_PARTICLES);
  535. F32 frac = part.mLastUpdateTime/part.mMaxAge;
  536. LLViewerPartSource *ps = (LLViewerPartSource*)part.mPartSourcep;
  537. LLViewerPartSourceBeam *psb = (LLViewerPartSourceBeam *)ps;
  538. if (psb->mSourceObjectp.isNull())
  539. {
  540. part.mFlags = LLPartData::LL_PART_DEAD_MASK;
  541. return;
  542. }
  543. LLVector3 source_pos_agent;
  544. LLVector3 target_pos_agent;
  545. if (!psb->mSourceObjectp.isNull() && !psb->mSourceObjectp->mDrawable.isNull())
  546. {
  547. if (psb->mSourceObjectp->isAvatar())
  548. {
  549. LLViewerObject *objp = psb->mSourceObjectp;
  550. LLVOAvatar *avp = (LLVOAvatar *)objp;
  551. source_pos_agent = avp->mWristLeftp->getWorldPosition();
  552. }
  553. else
  554. {
  555. source_pos_agent = psb->mSourceObjectp->getRenderPosition();
  556. }
  557. }
  558. if (!psb->mTargetObjectp.isNull() && !psb->mTargetObjectp->mDrawable.isNull())
  559. {
  560. target_pos_agent = psb->mTargetObjectp->getRenderPosition();
  561. }
  562. part.mPosAgent = (1.f - frac) * source_pos_agent;
  563. if (psb->mTargetObjectp.isNull())
  564. {
  565. part.mPosAgent += frac * (gAgent.getPosAgentFromGlobal(psb->mLKGTargetPosGlobal));
  566. }
  567. else
  568. {
  569. part.mPosAgent += frac * target_pos_agent;
  570. }
  571. }
  572. void LLViewerPartSourceBeam::update(const F32 dt)
  573. {
  574. LLMemType mt(LLMemType::MTYPE_PARTICLES);
  575. const F32 RATE = 0.025f;
  576. mLastUpdateTime += dt;
  577. if (!mSourceObjectp.isNull() && !mSourceObjectp->mDrawable.isNull())
  578. {
  579. if (mSourceObjectp->isAvatar())
  580. {
  581. LLViewerObject *objp = mSourceObjectp;
  582. LLVOAvatar *avp = (LLVOAvatar *)objp;
  583. mPosAgent = avp->mWristLeftp->getWorldPosition();
  584. }
  585. else
  586. {
  587. mPosAgent = mSourceObjectp->getRenderPosition();
  588. }
  589. }
  590. if (!mTargetObjectp.isNull() && !mTargetObjectp->mDrawable.isNull())
  591. {
  592. mTargetPosAgent = mTargetObjectp->getRenderPosition();
  593. }
  594. else if (!mLKGTargetPosGlobal.isExactlyZero())
  595. {
  596. mTargetPosAgent = gAgent.getPosAgentFromGlobal(mLKGTargetPosGlobal);
  597. }
  598. F32 dt_update = mLastUpdateTime - mLastPartTime;
  599. F32 max_time = llmax(1.f, 10.f*RATE);
  600. dt_update = llmin(max_time, dt_update);
  601. if (dt_update > RATE)
  602. {
  603. mLastPartTime = mLastUpdateTime;
  604. if (!LLViewerPartSim::getInstance()->shouldAddPart())
  605. {
  606. // Particle simulation says we have too many particles, skip all this
  607. return;
  608. }
  609. if (!mImagep)
  610. {
  611. mImagep = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c");
  612. }
  613. LLViewerPart* part = new LLViewerPart();
  614. part->init(this, mImagep, NULL);
  615. part->mFlags = LLPartData::LL_PART_INTERP_COLOR_MASK |
  616. LLPartData::LL_PART_INTERP_SCALE_MASK |
  617. LLPartData::LL_PART_TARGET_POS_MASK |
  618. LLPartData::LL_PART_FOLLOW_VELOCITY_MASK;
  619. part->mMaxAge = 0.5f;
  620. part->mStartColor = mColor;
  621. part->mEndColor = part->mStartColor;
  622. part->mEndColor.mV[3] = 0.4f;
  623. part->mColor = part->mStartColor;
  624. part->mStartScale = LLVector2(0.1f, 0.1f);
  625. part->mEndScale = LLVector2(0.1f, 0.1f);
  626. part->mScale = part->mStartScale;
  627. part->mPosAgent = mPosAgent;
  628. part->mVelocity = mTargetPosAgent - mPosAgent;
  629. LLViewerPartSim::getInstance()->addPart(part);
  630. }
  631. }
  632. void LLViewerPartSourceBeam::setSourceObject(LLViewerObject* objp)
  633. {
  634. LLMemType mt(LLMemType::MTYPE_PARTICLES);
  635. mSourceObjectp = objp;
  636. }
  637. void LLViewerPartSourceBeam::setTargetObject(LLViewerObject* objp)
  638. {
  639. LLMemType mt(LLMemType::MTYPE_PARTICLES);
  640. mTargetObjectp = objp;
  641. }
  642. LLViewerPartSourceChat::LLViewerPartSourceChat(const LLVector3 &pos) :
  643. LLViewerPartSource(LL_PART_SOURCE_SPIRAL)
  644. {
  645. mPosAgent = pos;
  646. }
  647. void LLViewerPartSourceChat::setDead()
  648. {
  649. LLMemType mt(LLMemType::MTYPE_PARTICLES);
  650. mIsDead = TRUE;
  651. mSourceObjectp = NULL;
  652. }
  653. void LLViewerPartSourceChat::updatePart(LLViewerPart &part, const F32 dt)
  654. {
  655. LLMemType mt(LLMemType::MTYPE_PARTICLES);
  656. F32 frac = part.mLastUpdateTime/part.mMaxAge;
  657. LLVector3 center_pos;
  658. LLViewerPartSource *ps = (LLViewerPartSource*)part.mPartSourcep;
  659. LLViewerPartSourceChat *pss = (LLViewerPartSourceChat *)ps;
  660. if (!pss->mSourceObjectp.isNull() && !pss->mSourceObjectp->mDrawable.isNull())
  661. {
  662. part.mPosAgent = pss->mSourceObjectp->getRenderPosition();
  663. }
  664. else
  665. {
  666. part.mPosAgent = pss->mPosAgent;
  667. }
  668. F32 x = sin(F_TWO_PI*frac + part.mParameter);
  669. F32 y = cos(F_TWO_PI*frac + part.mParameter);
  670. part.mPosAgent.mV[VX] += x;
  671. part.mPosAgent.mV[VY] += y;
  672. part.mPosAgent.mV[VZ] += -0.5f + frac;
  673. }
  674. void LLViewerPartSourceChat::update(const F32 dt)
  675. {
  676. LLMemType mt(LLMemType::MTYPE_PARTICLES);
  677. if (!mImagep)
  678. {
  679. mImagep = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c");
  680. }
  681. const F32 RATE = 0.025f;
  682. mLastUpdateTime += dt;
  683. if (mLastUpdateTime > 2.f)
  684. {
  685. // Kill particle source because it has outlived its max age...
  686. setDead();
  687. return;
  688. }
  689. F32 dt_update = mLastUpdateTime - mLastPartTime;
  690. // Clamp us to generating at most one second's worth of particles on a frame.
  691. F32 max_time = llmax(1.f, 10.f*RATE);
  692. dt_update = llmin(max_time, dt_update);
  693. if (dt_update > RATE)
  694. {
  695. mLastPartTime = mLastUpdateTime;
  696. if (!LLViewerPartSim::getInstance()->shouldAddPart())
  697. {
  698. // Particle simulation says we have too many particles, skip all this
  699. return;
  700. }
  701. if (!mSourceObjectp.isNull() && !mSourceObjectp->mDrawable.isNull())
  702. {
  703. mPosAgent = mSourceObjectp->getRenderPosition();
  704. }
  705. LLViewerPart* part = new LLViewerPart();
  706. part->init(this, mImagep, updatePart);
  707. part->mStartColor = mColor;
  708. part->mEndColor = mColor;
  709. part->mEndColor.mV[3] = 0.f;
  710. part->mPosAgent = mPosAgent;
  711. part->mMaxAge = 1.f;
  712. part->mFlags = LLViewerPart::LL_PART_INTERP_COLOR_MASK;
  713. part->mLastUpdateTime = 0.f;
  714. part->mScale.mV[0] = 0.25f;
  715. part->mScale.mV[1] = 0.25f;
  716. part->mParameter = ll_frand(F_TWO_PI);
  717. LLViewerPartSim::getInstance()->addPart(part);
  718. }
  719. }
  720. void LLViewerPartSourceChat::setSourceObject(LLViewerObject *objp)
  721. {
  722. LLMemType mt(LLMemType::MTYPE_PARTICLES);
  723. mSourceObjectp = objp;
  724. }
  725. void LLViewerPartSourceChat::setColor(const LLColor4 &color)
  726. {
  727. mColor = color;
  728. }