llhudeffectbeam.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "llhudeffectbeam.h"
00035 #include "message.h"
00036 
00037 #include "llviewerobjectlist.h"
00038 
00039 #include "llagent.h"
00040 #include "lldrawable.h"
00041 #include "llfontgl.h"
00042 #include "llgl.h"
00043 #include "llglheaders.h"
00044 #include "llhudrender.h"
00045 #include "llimagegl.h"
00046 #include "llrendersphere.h"
00047 #include "llviewercamera.h"
00048 #include "llvoavatar.h"
00049 #include "llviewercontrol.h"
00050 
00051 const F32 BEAM_SPACING = 0.075f;
00052 
00053 LLHUDEffectBeam::LLHUDEffectBeam(const U8 type) : LLHUDEffect(type)
00054 {
00055         mKillTime = mDuration;
00056 
00057         // Initialize all of these to defaults
00058         S32 i;
00059         for (i = 0; i < NUM_POINTS; i++)
00060         {
00061                 mInterp[i].setStartTime(BEAM_SPACING*i);
00062                 mInterp[i].setEndTime(BEAM_SPACING*NUM_POINTS + BEAM_SPACING*i);
00063                 mInterp[i].start();
00064                 mInterpFade[i].setStartTime(BEAM_SPACING*NUM_POINTS + BEAM_SPACING*i - 0.5f*NUM_POINTS*BEAM_SPACING);
00065                 mInterpFade[i].setEndTime(BEAM_SPACING*NUM_POINTS + BEAM_SPACING*i);
00066                 mInterpFade[i].setStartVal(1.f);
00067                 mInterpFade[i].setEndVal(0.f);
00068         }
00069 
00070         // Setup default timeouts and fade animations.
00071         F32 fade_length;
00072         fade_length = llmin(0.5f, mDuration);
00073         mFadeInterp.setStartTime(mKillTime - fade_length);
00074         mFadeInterp.setEndTime(mKillTime);
00075         mFadeInterp.setStartVal(1.f);
00076         mFadeInterp.setEndVal(0.f);
00077 }
00078 
00079 LLHUDEffectBeam::~LLHUDEffectBeam()
00080 {
00081 }
00082 
00083 void LLHUDEffectBeam::packData(LLMessageSystem *mesgsys)
00084 {
00085         if (!mSourceObject)
00086         {
00087                 llwarns << "Missing source object!" << llendl;
00088         }
00089 
00090         // Pack the default data
00091         LLHUDEffect::packData(mesgsys);
00092 
00093         // Pack the type-specific data.  Uses a fun packed binary format.  Whee!
00094         // 16 + 24 + 1 = 41
00095         U8 packed_data[41];
00096         memset(packed_data, 0, 41);
00097         if (mSourceObject)
00098         {
00099                 htonmemcpy(packed_data, mSourceObject->mID.mData, MVT_LLUUID, 16);
00100         }
00101 
00102         if (mTargetObject)
00103         {
00104                 packed_data[16] = 1;
00105         }
00106         else
00107         {
00108                 packed_data[16] = 0;
00109         }
00110 
00111         if (mTargetObject)
00112         {
00113                 htonmemcpy(&(packed_data[17]), mTargetObject->mID.mData, MVT_LLUUID, 16);
00114         }
00115         else
00116         {
00117                 htonmemcpy(&(packed_data[17]), mTargetPos.mdV, MVT_LLVector3d, 24);
00118         }
00119         mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, 41);
00120 }
00121 
00122 void LLHUDEffectBeam::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
00123 {
00124         llerrs << "Got beam!" << llendl;
00125         BOOL use_target_object;
00126         LLVector3d new_target;
00127         U8 packed_data[41];
00128 
00129         LLHUDEffect::unpackData(mesgsys, blocknum);
00130         LLUUID source_id;
00131         LLUUID target_id;
00132         S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData);
00133         if (size != 41)
00134         {
00135                 llwarns << "Beam effect with bad size " << size << llendl;
00136                 return;
00137         }
00138         mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, 41, blocknum);
00139         
00140         htonmemcpy(source_id.mData, packed_data, MVT_LLUUID, 16);
00141 
00142         LLViewerObject *objp = gObjectList.findObject(source_id);
00143         if (objp)
00144         {
00145                 setSourceObject(objp);
00146         }
00147 
00148         use_target_object = packed_data[16];
00149 
00150         if (use_target_object)
00151         {
00152                 htonmemcpy(target_id.mData, &packed_data[17], MVT_LLUUID, 16);
00153 
00154                 LLViewerObject *objp = gObjectList.findObject(target_id);
00155                 if (objp)
00156                 {
00157                         setTargetObject(objp);
00158                 }
00159         }
00160         else
00161         {
00162                 htonmemcpy(new_target.mdV, &(packed_data[17]), MVT_LLVector3d, 24);
00163                 setTargetPos(new_target);
00164         }
00165 
00166         // We've received an update for the effect, update the various timeouts
00167         // and fade animations.
00168         mKillTime = mTimer.getElapsedTimeF32() + mDuration;
00169         F32 fade_length;
00170         fade_length = llmin(0.5f, mDuration);
00171         mFadeInterp.setStartTime(mKillTime - fade_length);
00172         mFadeInterp.setEndTime(mKillTime);
00173         mFadeInterp.setStartVal(1.f);
00174         mFadeInterp.setEndVal(0.f);
00175 }
00176 
00177 void LLHUDEffectBeam::setSourceObject(LLViewerObject *objp)
00178 {
00179         if (objp->isDead())
00180         {
00181                 llwarns << "HUDEffectBeam: Source object is dead!" << llendl;
00182                 mSourceObject = NULL;
00183                 return;
00184         }
00185 
00186         if (mSourceObject == objp)
00187         {
00188                 return;
00189         }
00190 
00191         mSourceObject = objp;
00192         if (mSourceObject)
00193         {
00194                 S32 i;
00195                 for (i = 0; i < NUM_POINTS; i++)
00196                 {
00197                         if (mSourceObject->isAvatar())
00198                         {
00199                                 LLViewerObject *objp = mSourceObject;
00200                                 LLVOAvatar *avatarp = (LLVOAvatar *)objp;
00201                                 LLVector3d hand_pos_global = gAgent.getPosGlobalFromAgent(avatarp->mWristLeftp->getWorldPosition());
00202                                 mInterp[i].setStartVal(hand_pos_global);
00203                                 mInterp[i].start();
00204                         }
00205                         else
00206                         {
00207                                 mInterp[i].setStartVal(mSourceObject->getPositionGlobal());
00208                                 mInterp[i].start();
00209                         }
00210                 }
00211         }
00212 }
00213 
00214 
00215 void LLHUDEffectBeam::setTargetObject(LLViewerObject *objp)
00216 {
00217         if (mTargetObject->isDead())
00218         {
00219                 llwarns << "HUDEffectBeam: Target object is dead!" << llendl;
00220         }
00221 
00222         mTargetObject = objp;
00223 }
00224 
00225 void LLHUDEffectBeam::setTargetPos(const LLVector3d &pos_global)
00226 {
00227         mTargetPos = pos_global;
00228         mTargetObject = NULL;
00229 }
00230 
00231 void LLHUDEffectBeam::render()
00232 {
00233         if (!mSourceObject)
00234         {
00235                 markDead();
00236                 return;
00237         }
00238         if (mSourceObject->isDead())
00239         {
00240                 markDead();
00241                 return;
00242         }
00243 
00244         F32 time = mTimer.getElapsedTimeF32();
00245 
00246         // Kill us if our time is over...
00247         if (mKillTime < time)
00248         {
00249                 markDead();
00250                 return;
00251         }
00252 
00253         LLGLSPipelineAlpha gls_pipeline_alpha;
00254         LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
00255 
00256 
00257         // Interpolate the global fade alpha
00258         mFadeInterp.update(time);
00259 
00260         if (mTargetObject.notNull() && mTargetObject->mDrawable.notNull())
00261         {
00262                 // use viewer object position on freshly created objects
00263                 if (mTargetObject->mDrawable->getGeneration() == -1)
00264                 {
00265                         mTargetPos = mTargetObject->getPositionGlobal();
00266                 }
00267                 // otherwise use drawable
00268                 else
00269                 {
00270                         mTargetPos = gAgent.getPosGlobalFromAgent(mTargetObject->mDrawable->getPositionAgent());
00271                 }
00272         }
00273 
00274 
00275         // Init the color of the particles
00276         LLColor4U coloru = mColor;
00277 
00278         // Draw the particles
00279         S32 i;
00280         for (i = 0; i < NUM_POINTS; i++)
00281         {
00282                 mInterp[i].update(time);
00283                 if (!mInterp[i].isActive())
00284                 {
00285                         continue;
00286                 }
00287                 mInterpFade[i].update(time);
00288 
00289                 if (mInterp[i].isDone())
00290                 {
00291                         // Reinitialize the particle when the particle has finished its animation.
00292                         setupParticle(i);
00293                 }
00294 
00295                 F32 frac = mInterp[i].getCurFrac();
00296                 F32 scale = 0.025f + fabs(0.05f*sin(2.f*F_PI*(frac - time)));
00297                 scale *= mInterpFade[i].getCurVal();
00298 
00299                 LLVector3 pos_agent = gAgent.getPosAgentFromGlobal(mInterp[i].getCurVal());
00300 
00301                 F32 alpha = mFadeInterp.getCurVal()*mColor.mV[3];
00302                 alpha *= mInterpFade[i].getCurVal();
00303                 coloru.mV[3] = (U8)alpha;
00304                 glColor4ubv(coloru.mV);
00305 
00306                 glPushMatrix();
00307                 glTranslatef(pos_agent.mV[0], pos_agent.mV[1], pos_agent.mV[2]);
00308                 glScalef(scale, scale, scale);
00309                 gSphere.render(0);
00310                 glPopMatrix();
00311         }
00312 }
00313 
00314 void LLHUDEffectBeam::setupParticle(const S32 i)
00315 {
00316         LLVector3d start_pos_global;
00317         if (mSourceObject->getPCode() == LL_PCODE_LEGACY_AVATAR)
00318         {
00319                 LLViewerObject *objp = mSourceObject;
00320                 LLVOAvatar *avatarp = (LLVOAvatar *)objp;
00321                 start_pos_global = gAgent.getPosGlobalFromAgent(avatarp->mWristLeftp->getWorldPosition());
00322         }
00323         else
00324         {
00325                 start_pos_global = mSourceObject->getPositionGlobal();
00326         }
00327 
00328         // Generate a random offset for the target point.
00329         const F32 SCALE = 0.5f;
00330         F32 x, y, z;
00331         x = ll_frand(SCALE) - 0.5f*SCALE;
00332         y = ll_frand(SCALE) - 0.5f*SCALE;
00333         z = ll_frand(SCALE) - 0.5f*SCALE;
00334 
00335         LLVector3d target_pos_global(mTargetPos);
00336         target_pos_global += LLVector3d(x, y, z);
00337 
00338         mInterp[i].setStartTime(mInterp[i].getEndTime());
00339         mInterp[i].setEndTime(mInterp[i].getStartTime() + BEAM_SPACING*NUM_POINTS);
00340         mInterp[i].setStartVal(start_pos_global);
00341         mInterp[i].setEndVal(target_pos_global);
00342         mInterp[i].start();
00343 
00344 
00345         // Setup the interpolator that fades out the alpha.
00346         mInterpFade[i].setStartTime(mInterp[i].getStartTime() + BEAM_SPACING*NUM_POINTS - 0.5f*NUM_POINTS*BEAM_SPACING);
00347         mInterpFade[i].setEndTime(mInterp[i].getStartTime() + BEAM_SPACING*NUM_POINTS - 0.05f);
00348         mInterpFade[i].start();
00349 }

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