llviewerpartsource.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 #include "llviewerpartsource.h"
00034 
00035 #include "llviewercontrol.h"
00036 
00037 #include "llagent.h"
00038 #include "lldrawable.h"
00039 #include "llviewercamera.h"
00040 #include "llviewerimagelist.h"
00041 #include "llviewerobject.h"
00042 #include "llviewerobjectlist.h"
00043 #include "llvoavatar.h"
00044 #include "llworld.h"
00045 #include "pipeline.h"
00046 
00047 LLViewerPartSource::LLViewerPartSource(const U32 type) :
00048         mType(type),
00049         mOwnerUUID(LLUUID::null),
00050         mPartFlags(0)
00051 {
00052         mLastUpdateTime = 0.f;
00053         mLastPartTime = 0.f;
00054         mIsDead = FALSE;
00055         mIsSuspended = FALSE;
00056         static U32 id_seed = 0;
00057         mID = ++id_seed;
00058 
00059         mDelay = 0 ;
00060 }
00061 
00062 void LLViewerPartSource::setDead()
00063 {
00064         mIsDead = TRUE;
00065 }
00066 
00067 
00068 void LLViewerPartSource::updatePart(LLViewerPart &part, const F32 dt)
00069 {
00070 }
00071 
00072 void LLViewerPartSource::update(const F32 dt)
00073 {
00074         llerrs << "Creating default part source!" << llendl;
00075 }
00076 
00077 LLUUID LLViewerPartSource::getImageUUID() const
00078 {
00079         LLViewerImage* imagep = mImagep;
00080         if(imagep)
00081         {
00082                 return imagep->getID();
00083         }
00084         return LLUUID::null;
00085 }
00086 void LLViewerPartSource::setStart()
00087 {
00088         //cancel delaying to start a new added particle source, because some particle source just emits for a short time.
00089         //however, canceling this might cause overall particle emmitting fluctuate for a while because the new added source jumps to 
00090         //the current particle emmitting settings instantly. -->bao
00091         mDelay = 0 ; //99
00092 }
00093 
00094 LLViewerPartSourceScript::LLViewerPartSourceScript(LLViewerObject *source_objp) :
00095         LLViewerPartSource(LL_PART_SOURCE_SCRIPT)
00096 {
00097         LLMemType mt(LLMemType::MTYPE_PARTICLES);
00098         llassert(source_objp);
00099         mSourceObjectp = source_objp;
00100         mPosAgent = mSourceObjectp->getPositionAgent();
00101         mImagep = gImageList.getImageFromFile("pixiesmall.j2c");
00102         mImagep->bind();
00103         mImagep->setClamp(TRUE, TRUE);
00104 }
00105 
00106 
00107 void LLViewerPartSourceScript::setDead()
00108 {
00109         LLMemType mt(LLMemType::MTYPE_PARTICLES);
00110         mIsDead = TRUE;
00111         mSourceObjectp = NULL;
00112         mTargetObjectp = NULL;
00113 }
00114 
00115 void LLViewerPartSourceScript::update(const F32 dt)
00116 {
00117         if( mIsSuspended )
00118                 return;
00119 
00120         LLMemType mt(LLMemType::MTYPE_PARTICLES);
00121         F32 old_update_time = mLastUpdateTime;
00122         mLastUpdateTime += dt;
00123 
00124         F32 ref_rate_travelspeed = llmin(LLViewerPartSim::getInstance()->getRefRate(), 1.f);
00125         
00126         F32 dt_update = mLastUpdateTime - mLastPartTime;
00127 
00128         // Update this for objects which have the follow flag set...
00129         if (!mSourceObjectp.isNull())
00130         {
00131                 if (mSourceObjectp->isDead())
00132                 {
00133                         mSourceObjectp = NULL;
00134                 }
00135                 else if (mSourceObjectp->mDrawable.notNull())
00136                 {
00137                         mPosAgent = mSourceObjectp->getRenderPosition();
00138                 }
00139         }
00140 
00141         if (mTargetObjectp.isNull() 
00142                 && mPartSysData.mTargetUUID.notNull())
00143         {
00144                 //
00145                 // Hmm, missing object, let's see if we can find it...
00146                 //
00147 
00148                 LLViewerObject *target_objp = gObjectList.findObject(mPartSysData.mTargetUUID);
00149                 setTargetObject(target_objp);
00150         }
00151 
00152         if (!mTargetObjectp.isNull())
00153         {
00154                 if (mTargetObjectp->isDead())
00155                 {
00156                         mTargetObjectp = NULL;
00157                 }
00158                 else if (mTargetObjectp->mDrawable.notNull())
00159                 {
00160                         mTargetPosAgent = mTargetObjectp->getRenderPosition();
00161                 }
00162         }
00163 
00164         if (!mTargetObjectp)
00165         {
00166                 mTargetPosAgent = mPosAgent;
00167         }
00168 
00169         if (mPartSysData.mMaxAge && ((mPartSysData.mStartAge + mLastUpdateTime + dt_update) > mPartSysData.mMaxAge))
00170         {
00171                 // Kill particle source because it has outlived its max age...
00172                 setDead();
00173                 return;
00174         }
00175 
00176 
00177         if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PARTICLES))
00178         {
00179                 if (mSourceObjectp.notNull())
00180                 {
00181                         std::ostringstream ostr;
00182                         ostr << mPartSysData;
00183                         mSourceObjectp->setDebugText(ostr.str());
00184                 }
00185         }
00186 
00187         BOOL first_run = FALSE;
00188         if (old_update_time <= 0.f)
00189         {
00190                 first_run = TRUE;
00191         }
00192 
00193         F32 max_time = llmax(1.f, 10.f*mPartSysData.mBurstRate);
00194         dt_update = llmin(max_time, dt_update);
00195         while ((dt_update > mPartSysData.mBurstRate) || first_run)
00196         {
00197                 first_run = FALSE;
00198                 
00199                 // Update the rotation of the particle source by the angular velocity
00200                 // First check to see if there is still an angular velocity.
00201                 F32 angular_velocity_mag = mPartSysData.mAngularVelocity.magVec();
00202                 if (angular_velocity_mag != 0.0f)
00203                 {
00204                         F32 av_angle = dt * angular_velocity_mag;
00205                         LLQuaternion dquat(av_angle, mPartSysData.mAngularVelocity);
00206                         mRotation *= dquat;
00207                 }
00208                 else
00209                 {
00210                         // No angular velocity.  Reset our rotation.
00211                         mRotation.setQuat(0, 0, 0);
00212                 }
00213                 
00214                 if (LLViewerPartSim::getInstance()->aboveParticleLimit())
00215                 {
00216                         // Don't bother doing any more updates if we're above the particle limit,
00217                         // just give up.
00218                         mLastPartTime = mLastUpdateTime;
00219             break;
00220 
00221                 }
00222                 
00223                 // find the greatest length that the shortest side of a system
00224                 // particle is expected to have
00225                 F32 max_short_side =
00226                         llmax(
00227                               llmax(llmin(mPartSysData.mPartData.mStartScale[0],
00228                                           mPartSysData.mPartData.mStartScale[1]),
00229                                     llmin(mPartSysData.mPartData.mEndScale[0],
00230                                           mPartSysData.mPartData.mEndScale[1])),
00231                               llmin((mPartSysData.mPartData.mStartScale[0]
00232                                      + mPartSysData.mPartData.mEndScale[0])/2,
00233                                     (mPartSysData.mPartData.mStartScale[1]
00234                                      + mPartSysData.mPartData.mEndScale[1])/2));
00235                 
00236                 F32 pixel_meter_ratio = LLViewerCamera::getInstance()->getPixelMeterRatio();
00237 
00238                 // Maximum distance at which spawned particles will be viewable
00239                 F32 max_dist = max_short_side * pixel_meter_ratio; 
00240 
00241                 if (max_dist < 0.25f)
00242                 {
00243                         // < 1 pixel wide at a distance of >=25cm.  Particles
00244                         // this tiny are useless and mostly spawned by buggy
00245                         // sources
00246                         mLastPartTime = mLastUpdateTime;
00247                         break;
00248                 }
00249 
00250                 // Distance from camera
00251                 F32 dist = (mPosAgent - LLViewerCamera::getInstance()->getOrigin()).magVec();
00252 
00253                 // Particle size vs distance vs maxage throttling
00254 
00255                 F32 limited_rate=0.f;
00256                 if (dist - max_dist > 0.f)
00257                 {
00258                         if((dist - max_dist) * ref_rate_travelspeed > mPartSysData.mPartData.mMaxAge - 0.2f )
00259                         {
00260                                 // You need to travel faster than 1 divided by reference rate m/s directly towards these particles to see them at least 0.2s
00261                                 mLastPartTime = mLastUpdateTime;
00262                                 break;
00263                         }
00264                         limited_rate = ((dist - max_dist) * ref_rate_travelspeed) / mPartSysData.mPartData.mMaxAge;
00265                 }
00266                 
00267                 if(mDelay)
00268                 {                       
00269                         limited_rate = llmax(limited_rate, 0.01f * mDelay--) ;
00270                 }
00271 
00272                 S32 i;
00273                 for (i = 0; i < mPartSysData.mBurstPartCount; i++)
00274                 {
00275                         if (ll_frand() < llmax(1.0f - LLViewerPartSim::getInstance()->getBurstRate(), limited_rate))
00276                         {
00277                                 // Limit particle generation
00278                                 continue;
00279                         }
00280 
00281                         LLPointer<LLViewerPart> part = new LLViewerPart();
00282 
00283                         part->init(this, mImagep, NULL);
00284                         part->mFlags = mPartSysData.mPartData.mFlags;
00285                         part->mMaxAge = mPartSysData.mPartData.mMaxAge;
00286                         part->mStartColor = mPartSysData.mPartData.mStartColor;
00287                         part->mEndColor = mPartSysData.mPartData.mEndColor;
00288                         part->mColor = part->mStartColor;
00289 
00290                         part->mStartScale = mPartSysData.mPartData.mStartScale;
00291                         part->mEndScale = mPartSysData.mPartData.mEndScale;
00292                         part->mScale = part->mStartScale;
00293 
00294                         part->mAccel = mPartSysData.mPartAccel;
00295 
00296                         if (mPartSysData.mPattern & LLPartSysData::LL_PART_SRC_PATTERN_DROP)
00297                         {
00298                                 part->mPosAgent = mPosAgent;
00299                                 part->mVelocity.setVec(0.f, 0.f, 0.f);
00300                         }
00301                         else if (mPartSysData.mPattern & LLPartSysData::LL_PART_SRC_PATTERN_EXPLODE)
00302                         {
00303                                 part->mPosAgent = mPosAgent;
00304                                 LLVector3 part_dir_vector;
00305 
00306                                 F32 mvs;
00307                                 do
00308                                 {
00309                                         part_dir_vector.mV[VX] = ll_frand(2.f) - 1.f;
00310                                         part_dir_vector.mV[VY] = ll_frand(2.f) - 1.f;
00311                                         part_dir_vector.mV[VZ] = ll_frand(2.f) - 1.f;
00312                                         mvs = part_dir_vector.magVecSquared();
00313                                 }
00314                                 while ((mvs > 1.f) || (mvs < 0.01f));
00315 
00316                                 part_dir_vector.normVec();
00317                                 part->mPosAgent += mPartSysData.mBurstRadius*part_dir_vector;
00318                                 part->mVelocity = part_dir_vector;
00319                                 F32 speed = mPartSysData.mBurstSpeedMin + ll_frand(mPartSysData.mBurstSpeedMax - mPartSysData.mBurstSpeedMin);
00320                                 part->mVelocity *= speed;
00321                         }
00322                         else if (mPartSysData.mPattern & LLPartSysData::LL_PART_SRC_PATTERN_ANGLE
00323                                 || mPartSysData.mPattern & LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE)
00324                         {                               
00325                                 part->mPosAgent = mPosAgent;
00326                                 
00327                                 // original implemenetation for part_dir_vector was just:                                       
00328                                 LLVector3 part_dir_vector(0.0, 0.0, 1.0);
00329                                 // params from the script...
00330                                 // outer = outer cone angle
00331                                 // inner = inner cone angle
00332                                 //              between outer and inner there will be particles
00333                                 F32 innerAngle = mPartSysData.mInnerAngle;
00334                                 F32 outerAngle = mPartSysData.mOuterAngle;
00335 
00336                                 // generate a random angle within the given space...
00337                                 F32 angle = innerAngle + ll_frand(outerAngle - innerAngle);
00338                                 // split which side it will go on randomly...
00339                                 if (ll_frand() < 0.5) 
00340                                 {
00341                                         angle = -angle;
00342                                 }
00343                                 // Both patterns rotate around the x-axis first:
00344                                 part_dir_vector.rotVec(angle, 1.0, 0.0, 0.0);
00345 
00346                                 // If this is a cone pattern, rotate again to create the cone.
00347                                 if (mPartSysData.mPattern & LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE)
00348                                 {
00349                                         part_dir_vector.rotVec(ll_frand(4*F_PI), 0.0, 0.0, 1.0);
00350                                 }
00351                                                                 
00352                                 // Only apply this rotation if using the deprecated angles. 
00353                                 if (! (mPartSysData.mFlags & LLPartSysData::LL_PART_USE_NEW_ANGLE))
00354                                 {
00355                                         // Deprecated...
00356                                         part_dir_vector.rotVec(outerAngle, 1.0, 0.0, 0.0);
00357                                 }
00358                                 
00359                                 if (mSourceObjectp)
00360                                 {
00361                                         part_dir_vector = part_dir_vector * mSourceObjectp->getRenderRotation();
00362                                 }
00363                                                                 
00364                                 part_dir_vector = part_dir_vector * mRotation;
00365                                                                 
00366                                 part->mPosAgent += mPartSysData.mBurstRadius*part_dir_vector;
00367 
00368                                 part->mVelocity = part_dir_vector;
00369 
00370                                 F32 speed = mPartSysData.mBurstSpeedMin + ll_frand(mPartSysData.mBurstSpeedMax - mPartSysData.mBurstSpeedMin);
00371                                 part->mVelocity *= speed;
00372                         }
00373                         else
00374                         {
00375                                 part->mPosAgent = mPosAgent;
00376                                 part->mVelocity.setVec(0.f, 0.f, 0.f);
00377                                 //llwarns << "Unknown source pattern " << (S32)mPartSysData.mPattern << llendl;
00378                         }
00379 
00380                         if (part->mFlags & LLPartData::LL_PART_FOLLOW_SRC_MASK ||       // SVC-193, VWR-717
00381                                 part->mFlags & LLPartData::LL_PART_TARGET_LINEAR_MASK) 
00382                         {
00383                                 mPartSysData.mBurstRadius = 0; 
00384                         }
00385 
00386                         LLViewerPartSim::getInstance()->addPart(part);
00387                 }
00388 
00389                 mLastPartTime = mLastUpdateTime;
00390                 dt_update -= mPartSysData.mBurstRate;
00391         }
00392 }
00393 
00394 // static
00395 LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, const S32 block_num)
00396 {
00397         LLMemType mt(LLMemType::MTYPE_PARTICLES);
00398         if (!pssp)
00399         {
00400                 if (LLPartSysData::isNullPS(block_num))
00401                 {
00402                         return NULL;
00403                 }
00404                 LLPointer<LLViewerPartSourceScript> new_pssp = new LLViewerPartSourceScript(source_objp);
00405                 if (!new_pssp->mPartSysData.unpackBlock(block_num))
00406                 {
00407                         return NULL;
00408                 }
00409                 if (new_pssp->mPartSysData.mTargetUUID.notNull())
00410                 {
00411                         LLViewerObject *target_objp = gObjectList.findObject(new_pssp->mPartSysData.mTargetUUID);
00412                         new_pssp->setTargetObject(target_objp);
00413                 }
00414                 return new_pssp;
00415         }
00416         else
00417         {
00418                 if (LLPartSysData::isNullPS(block_num))
00419                 {
00420                         return NULL;
00421                 }
00422 
00423                 if (!pssp->mPartSysData.unpackBlock(block_num))
00424                 {
00425                         return NULL;
00426                 }
00427                 if (pssp->mPartSysData.mTargetUUID.notNull())
00428                 {
00429                         LLViewerObject *target_objp = gObjectList.findObject(pssp->mPartSysData.mTargetUUID);
00430                         pssp->setTargetObject(target_objp);
00431                 }
00432                 return pssp;
00433         }
00434 }
00435 
00436 
00437 LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, LLDataPacker &dp)
00438 {
00439         LLMemType mt(LLMemType::MTYPE_PARTICLES);
00440         if (!pssp)
00441         {
00442                 LLPointer<LLViewerPartSourceScript> new_pssp = new LLViewerPartSourceScript(source_objp);
00443                 if (!new_pssp->mPartSysData.unpack(dp))
00444                 {
00445                         return NULL;
00446                 }
00447                 if (new_pssp->mPartSysData.mTargetUUID.notNull())
00448                 {
00449                         LLViewerObject *target_objp = gObjectList.findObject(new_pssp->mPartSysData.mTargetUUID);
00450                         new_pssp->setTargetObject(target_objp);
00451                 }
00452                 return new_pssp;
00453         }
00454         else
00455         {
00456                 if (!pssp->mPartSysData.unpack(dp))
00457                 {
00458                         return NULL;
00459                 }
00460                 if (pssp->mPartSysData.mTargetUUID.notNull())
00461                 {
00462                         LLViewerObject *target_objp = gObjectList.findObject(pssp->mPartSysData.mTargetUUID);
00463                         pssp->setTargetObject(target_objp);
00464                 }
00465                 return pssp;
00466         }
00467 }
00468 
00469 
00470 /* static */
00471 LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::createPSS(LLViewerObject *source_objp, const LLPartSysData& particle_parameters)
00472 {
00473         LLMemType mt(LLMemType::MTYPE_PARTICLES);
00474 
00475         LLPointer<LLViewerPartSourceScript> new_pssp = new LLViewerPartSourceScript(source_objp);
00476 
00477         new_pssp->mPartSysData = particle_parameters;
00478 
00479         if (new_pssp->mPartSysData.mTargetUUID.notNull())
00480         {
00481                 LLViewerObject *target_objp = gObjectList.findObject(new_pssp->mPartSysData.mTargetUUID);
00482                 new_pssp->setTargetObject(target_objp);
00483         }
00484         return new_pssp;
00485 }
00486 
00487 
00488 void LLViewerPartSourceScript::setImage(LLViewerImage *imagep)
00489 {
00490         LLMemType mt(LLMemType::MTYPE_PARTICLES);
00491         mImagep = imagep;
00492 }
00493 
00494 void LLViewerPartSourceScript::setTargetObject(LLViewerObject *objp)
00495 {
00496         LLMemType mt(LLMemType::MTYPE_PARTICLES);
00497         mTargetObjectp = objp;
00498 }
00499 
00500 
00501 
00502 
00503 
00504 LLViewerPartSourceSpiral::LLViewerPartSourceSpiral(const LLVector3 &pos) :
00505         LLViewerPartSource(LL_PART_SOURCE_CHAT)
00506 {
00507         mPosAgent = pos;
00508 }
00509 
00510 void LLViewerPartSourceSpiral::setDead()
00511 {
00512         LLMemType mt(LLMemType::MTYPE_PARTICLES);
00513         mIsDead = TRUE;
00514         mSourceObjectp = NULL;
00515 }
00516 
00517 
00518 void LLViewerPartSourceSpiral::updatePart(LLViewerPart &part, const F32 dt)
00519 {
00520         LLMemType mt(LLMemType::MTYPE_PARTICLES);
00521         F32 frac = part.mLastUpdateTime/part.mMaxAge;
00522 
00523         LLVector3 center_pos;
00524         LLPointer<LLViewerPartSource>& ps = part.mPartSourcep;
00525         LLViewerPartSourceSpiral *pss = (LLViewerPartSourceSpiral *)ps.get();
00526         if (!pss->mSourceObjectp.isNull() && !pss->mSourceObjectp->mDrawable.isNull())
00527         {
00528                 part.mPosAgent = pss->mSourceObjectp->getRenderPosition();
00529         }
00530         else
00531         {
00532                 part.mPosAgent = pss->mPosAgent;
00533         }
00534         F32 x = sin(F_TWO_PI*frac + part.mParameter);
00535         F32 y = cos(F_TWO_PI*frac + part.mParameter);
00536 
00537         part.mPosAgent.mV[VX] += x;
00538         part.mPosAgent.mV[VY] += y;
00539         part.mPosAgent.mV[VZ] += -0.5f + frac;
00540 }
00541 
00542 
00543 void LLViewerPartSourceSpiral::update(const F32 dt)
00544 {
00545         LLMemType mt(LLMemType::MTYPE_PARTICLES);
00546         if (!mImagep)
00547         {
00548                 mImagep = gImageList.getImageFromFile("pixiesmall.j2c");
00549         }
00550 
00551         const F32 RATE = 0.025f;
00552 
00553         mLastUpdateTime += dt;
00554 
00555         F32 dt_update = mLastUpdateTime - mLastPartTime;
00556         F32 max_time = llmax(1.f, 10.f*RATE);
00557         dt_update = llmin(max_time, dt_update);
00558 
00559         if (dt_update > RATE)
00560         {
00561                 mLastPartTime = mLastUpdateTime;
00562                 if (!LLViewerPartSim::getInstance()->shouldAddPart())
00563                 {
00564                         // Particle simulation says we have too many particles, skip all this
00565                         return;
00566                 }
00567 
00568                 if (!mSourceObjectp.isNull() && !mSourceObjectp->mDrawable.isNull())
00569                 {
00570                         mPosAgent = mSourceObjectp->getRenderPosition();
00571                 }
00572                 LLPointer<LLViewerPart> part = new LLViewerPart();
00573                 part->init(this, mImagep, updatePart);
00574                 part->mStartColor = mColor;
00575                 part->mEndColor = mColor;
00576                 part->mEndColor.mV[3] = 0.f;
00577                 part->mPosAgent = mPosAgent;
00578                 part->mMaxAge = 1.f;
00579                 part->mFlags = LLViewerPart::LL_PART_INTERP_COLOR_MASK;
00580                 part->mLastUpdateTime = 0.f;
00581                 part->mScale.mV[0] = 0.25f;
00582                 part->mScale.mV[1] = 0.25f;
00583                 part->mParameter = ll_frand(F_TWO_PI);
00584 
00585                 LLViewerPartSim::getInstance()->addPart(part);
00586         }
00587 }
00588 
00589 void LLViewerPartSourceSpiral::setSourceObject(LLViewerObject *objp)
00590 {
00591         LLMemType mt(LLMemType::MTYPE_PARTICLES);
00592         mSourceObjectp = objp;
00593 }
00594 
00595 void LLViewerPartSourceSpiral::setColor(const LLColor4 &color)
00596 {
00597         mColor = color;
00598 }
00599 
00600 
00601 
00602 
00603 
00604 LLViewerPartSourceBeam::LLViewerPartSourceBeam() :
00605         LLViewerPartSource(LL_PART_SOURCE_BEAM)
00606 {
00607 }
00608 
00609 LLViewerPartSourceBeam::~LLViewerPartSourceBeam()
00610 {
00611 }
00612 
00613 void LLViewerPartSourceBeam::setDead()
00614 {
00615         LLMemType mt(LLMemType::MTYPE_PARTICLES);
00616         mIsDead = TRUE;
00617         mSourceObjectp = NULL;
00618         mTargetObjectp = NULL;
00619 }
00620 
00621 void LLViewerPartSourceBeam::setColor(const LLColor4 &color)
00622 {
00623         mColor = color;
00624 }
00625 
00626 
00627 void LLViewerPartSourceBeam::updatePart(LLViewerPart &part, const F32 dt)
00628 {
00629         LLMemType mt(LLMemType::MTYPE_PARTICLES);
00630         F32 frac = part.mLastUpdateTime/part.mMaxAge;
00631 
00632         LLViewerPartSource *ps = (LLViewerPartSource*)part.mPartSourcep;
00633         LLViewerPartSourceBeam *psb = (LLViewerPartSourceBeam *)ps;
00634         if (psb->mSourceObjectp.isNull())
00635         {
00636                 part.mFlags = LLPartData::LL_PART_DEAD_MASK;
00637                 return;
00638         }
00639 
00640         LLVector3 source_pos_agent;
00641         LLVector3 target_pos_agent;
00642         if (!psb->mSourceObjectp.isNull() && !psb->mSourceObjectp->mDrawable.isNull())
00643         {
00644                 if (psb->mSourceObjectp->isAvatar())
00645                 {
00646                         LLViewerObject *objp = psb->mSourceObjectp;
00647                         LLVOAvatar *avp = (LLVOAvatar *)objp;
00648                         source_pos_agent = avp->mWristLeftp->getWorldPosition();
00649                 }
00650                 else
00651                 {
00652                         source_pos_agent = psb->mSourceObjectp->getRenderPosition();
00653                 }
00654         }
00655         if (!psb->mTargetObjectp.isNull() && !psb->mTargetObjectp->mDrawable.isNull())
00656         {
00657                 target_pos_agent = psb->mTargetObjectp->getRenderPosition();
00658         }
00659 
00660         part.mPosAgent = (1.f - frac) * source_pos_agent;
00661         if (psb->mTargetObjectp.isNull())
00662         {
00663                 part.mPosAgent += frac * (gAgent.getPosAgentFromGlobal(psb->mLKGTargetPosGlobal));
00664         }
00665         else
00666         {
00667                 part.mPosAgent += frac * target_pos_agent;
00668         }
00669 }
00670 
00671 
00672 void LLViewerPartSourceBeam::update(const F32 dt)
00673 {
00674         LLMemType mt(LLMemType::MTYPE_PARTICLES);
00675         const F32 RATE = 0.025f;
00676 
00677         mLastUpdateTime += dt;
00678 
00679         if (!mSourceObjectp.isNull() && !mSourceObjectp->mDrawable.isNull())
00680         {
00681                 if (mSourceObjectp->isAvatar())
00682                 {
00683                         LLViewerObject *objp = mSourceObjectp;
00684                         LLVOAvatar *avp = (LLVOAvatar *)objp;
00685                         mPosAgent = avp->mWristLeftp->getWorldPosition();
00686                 }
00687                 else
00688                 {
00689                         mPosAgent = mSourceObjectp->getRenderPosition();
00690                 }
00691         }
00692 
00693         if (!mTargetObjectp.isNull() && !mTargetObjectp->mDrawable.isNull())
00694         {
00695                 mTargetPosAgent = mTargetObjectp->getRenderPosition();
00696         }
00697         else if (!mLKGTargetPosGlobal.isExactlyZero())
00698         {
00699                 mTargetPosAgent = gAgent.getPosAgentFromGlobal(mLKGTargetPosGlobal);
00700         }
00701 
00702         F32 dt_update = mLastUpdateTime - mLastPartTime;
00703         F32 max_time = llmax(1.f, 10.f*RATE);
00704         dt_update = llmin(max_time, dt_update);
00705 
00706         if (dt_update > RATE)
00707         {
00708                 mLastPartTime = mLastUpdateTime;
00709                 if (!LLViewerPartSim::getInstance()->shouldAddPart())
00710                 {
00711                         // Particle simulation says we have too many particles, skip all this
00712                         return;
00713                 }
00714 
00715                 if (!mImagep)
00716                 {
00717                         mImagep = gImageList.getImageFromFile("pixiesmall.j2c");
00718                 }
00719 
00720                 LLPointer<LLViewerPart> part = new LLViewerPart();
00721                 part->init(this, mImagep, NULL);
00722 
00723                 part->mFlags = LLPartData::LL_PART_INTERP_COLOR_MASK |
00724                                                 LLPartData::LL_PART_INTERP_SCALE_MASK |
00725                                                 LLPartData::LL_PART_TARGET_POS_MASK |
00726                                                 LLPartData::LL_PART_FOLLOW_VELOCITY_MASK;
00727                 part->mMaxAge = 0.5f;
00728                 part->mStartColor = mColor;
00729                 part->mEndColor = part->mStartColor;
00730                 part->mEndColor.mV[3] = 0.4f;
00731                 part->mColor = part->mStartColor;
00732 
00733                 part->mStartScale = LLVector2(0.1f, 0.1f);
00734                 part->mEndScale = LLVector2(0.1f, 0.1f);
00735                 part->mScale = part->mStartScale;
00736 
00737                 part->mPosAgent = mPosAgent;
00738                 part->mVelocity = mTargetPosAgent - mPosAgent;
00739 
00740                 LLViewerPartSim::getInstance()->addPart(part);
00741         }
00742 }
00743 
00744 void LLViewerPartSourceBeam::setSourceObject(LLViewerObject* objp)
00745 {
00746         LLMemType mt(LLMemType::MTYPE_PARTICLES);
00747         mSourceObjectp = objp;
00748 }
00749 
00750 void LLViewerPartSourceBeam::setTargetObject(LLViewerObject* objp)
00751 {
00752         LLMemType mt(LLMemType::MTYPE_PARTICLES);
00753         mTargetObjectp = objp;
00754 }
00755 
00756 
00757 
00758 
00759 LLViewerPartSourceChat::LLViewerPartSourceChat(const LLVector3 &pos) :
00760         LLViewerPartSource(LL_PART_SOURCE_SPIRAL)
00761 {
00762         mPosAgent = pos;
00763 }
00764 
00765 void LLViewerPartSourceChat::setDead()
00766 {
00767         LLMemType mt(LLMemType::MTYPE_PARTICLES);
00768         mIsDead = TRUE;
00769         mSourceObjectp = NULL;
00770 }
00771 
00772 
00773 void LLViewerPartSourceChat::updatePart(LLViewerPart &part, const F32 dt)
00774 {
00775         LLMemType mt(LLMemType::MTYPE_PARTICLES);
00776         F32 frac = part.mLastUpdateTime/part.mMaxAge;
00777 
00778         LLVector3 center_pos;
00779         LLViewerPartSource *ps = (LLViewerPartSource*)part.mPartSourcep;
00780         LLViewerPartSourceChat *pss = (LLViewerPartSourceChat *)ps;
00781         if (!pss->mSourceObjectp.isNull() && !pss->mSourceObjectp->mDrawable.isNull())
00782         {
00783                 part.mPosAgent = pss->mSourceObjectp->getRenderPosition();
00784         }
00785         else
00786         {
00787                 part.mPosAgent = pss->mPosAgent;
00788         }
00789         F32 x = sin(F_TWO_PI*frac + part.mParameter);
00790         F32 y = cos(F_TWO_PI*frac + part.mParameter);
00791 
00792         part.mPosAgent.mV[VX] += x;
00793         part.mPosAgent.mV[VY] += y;
00794         part.mPosAgent.mV[VZ] += -0.5f + frac;
00795 }
00796 
00797 
00798 void LLViewerPartSourceChat::update(const F32 dt)
00799 {
00800         LLMemType mt(LLMemType::MTYPE_PARTICLES);
00801         if (!mImagep)
00802         {
00803                 mImagep = gImageList.getImageFromFile("pixiesmall.j2c");
00804         }
00805 
00806 
00807         const F32 RATE = 0.025f;
00808 
00809         mLastUpdateTime += dt;
00810 
00811         if (mLastUpdateTime > 2.f)
00812         {
00813                 // Kill particle source because it has outlived its max age...
00814                 setDead();
00815                 return;
00816         }
00817 
00818         F32 dt_update = mLastUpdateTime - mLastPartTime;
00819 
00820         // Clamp us to generating at most one second's worth of particles on a frame.
00821         F32 max_time = llmax(1.f, 10.f*RATE);
00822         dt_update = llmin(max_time, dt_update);
00823 
00824         if (dt_update > RATE)
00825         {
00826                 mLastPartTime = mLastUpdateTime;
00827                 if (!LLViewerPartSim::getInstance()->shouldAddPart())
00828                 {
00829                         // Particle simulation says we have too many particles, skip all this
00830                         return;
00831                 }
00832 
00833                 if (!mSourceObjectp.isNull() && !mSourceObjectp->mDrawable.isNull())
00834                 {
00835                         mPosAgent = mSourceObjectp->getRenderPosition();
00836                 }
00837                 LLPointer<LLViewerPart> part = new LLViewerPart();
00838                 part->init(this, mImagep, updatePart);
00839                 part->mStartColor = mColor;
00840                 part->mEndColor = mColor;
00841                 part->mEndColor.mV[3] = 0.f;
00842                 part->mPosAgent = mPosAgent;
00843                 part->mMaxAge = 1.f;
00844                 part->mFlags = LLViewerPart::LL_PART_INTERP_COLOR_MASK;
00845                 part->mLastUpdateTime = 0.f;
00846                 part->mScale.mV[0] = 0.25f;
00847                 part->mScale.mV[1] = 0.25f;
00848                 part->mParameter = ll_frand(F_TWO_PI);
00849 
00850                 LLViewerPartSim::getInstance()->addPart(part);
00851         }
00852 }
00853 
00854 void LLViewerPartSourceChat::setSourceObject(LLViewerObject *objp)
00855 {
00856         LLMemType mt(LLMemType::MTYPE_PARTICLES);
00857         mSourceObjectp = objp;
00858 }
00859 
00860 void LLViewerPartSourceChat::setColor(const LLColor4 &color)
00861 {
00862         mColor = color;
00863 }
00864 
00865 

Generated on Fri May 16 08:34:16 2008 for SecondLife by  doxygen 1.5.5