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

Generated on Thu Jul 1 06:09:33 2010 for Second Life Viewer by  doxygen 1.4.7