llhudicon.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "llhudicon.h"
00035 
00036 #include "llgl.h"
00037 
00038 #include "llviewerobject.h"
00039 #include "lldrawable.h"
00040 #include "llviewercamera.h"
00041 #include "llviewerimage.h"
00042 #include "llviewerwindow.h"
00043 
00044 //-----------------------------------------------------------------------------
00045 // Local consts
00046 //-----------------------------------------------------------------------------
00047 const F32 ANIM_TIME = 0.4f;
00048 const F32 DIST_START_FADE = 15.f;
00049 const F32 DIST_END_FADE = 30.f;
00050 const F32 MAX_VISIBLE_TIME = 15.f;
00051 const F32 FADE_OUT_TIME = 1.f;
00052 
00053 //-----------------------------------------------------------------------------
00054 // Utility functions
00055 //-----------------------------------------------------------------------------
00056 static F32 calc_bouncy_animation(F32 x)
00057 {
00058         return -(cosf(x * F_PI * 2.5f - F_PI_BY_TWO))*(0.4f + x * -0.1f) + x * 1.3f;
00059 }
00060 
00061 
00062 //-----------------------------------------------------------------------------
00063 // static declarations
00064 //-----------------------------------------------------------------------------
00065 LLHUDIcon::icon_instance_t LLHUDIcon::sIconInstances;
00066 
00067 LLHUDIcon::LLHUDIcon(const U8 type) :
00068                         LLHUDObject(type),
00069                         mImagep(NULL),
00070                         mPickID(0),
00071                         mScale(0.1f),
00072                         mHidden(FALSE)
00073 {
00074         sIconInstances.push_back(this);
00075 }
00076 
00077 LLHUDIcon::~LLHUDIcon()
00078 {
00079         mImagep = NULL;
00080 }
00081 
00082 void LLHUDIcon::renderIcon(BOOL for_select)
00083 {
00084         LLGLSUIDefault texture_state;
00085         LLGLDepthTest gls_depth(GL_TRUE);
00086         LLGLState no_texture(GL_TEXTURE_2D, for_select ? FALSE : TRUE);
00087 
00088         if (mHidden)
00089                 return;
00090 
00091         if (mSourceObject.isNull() || mImagep.isNull())
00092         {
00093                 markDead();
00094                 return;
00095         }
00096 
00097         LLVector3 obj_position = mSourceObject->getRenderPosition();
00098 
00099         // put icon above object, and in front
00100         // RN: don't use drawable radius, it's fricking HUGE
00101         LLVector3 icon_relative_pos = (gCamera->getUpAxis() * ~mSourceObject->getRenderRotation());
00102         icon_relative_pos.abs();
00103 
00104         F32 distance_scale = llmin(mSourceObject->getScale().mV[VX] / icon_relative_pos.mV[VX], 
00105                 mSourceObject->getScale().mV[VY] / icon_relative_pos.mV[VY], 
00106                 mSourceObject->getScale().mV[VZ] / icon_relative_pos.mV[VZ]);
00107         F32 up_distance = 0.5f * distance_scale;
00108         LLVector3 icon_position = obj_position + (up_distance * gCamera->getUpAxis()) * 1.2f;
00109 
00110         LLVector3 icon_to_cam = gCamera->getOrigin() - icon_position;
00111         icon_to_cam.normVec();
00112 
00113         icon_position += icon_to_cam * mSourceObject->mDrawable->getRadius() * 1.1f;
00114 
00115         mDistance = dist_vec(icon_position, gCamera->getOrigin());
00116 
00117         F32 alpha_factor = for_select ? 1.f : clamp_rescale(mDistance, DIST_START_FADE, DIST_END_FADE, 1.f, 0.f);
00118 
00119         LLVector3 x_pixel_vec;
00120         LLVector3 y_pixel_vec;
00121         
00122         gCamera->getPixelVectors(icon_position, y_pixel_vec, x_pixel_vec);
00123 
00124         F32 scale_factor = 1.f;
00125         if (mAnimTimer.getElapsedTimeF32() < ANIM_TIME)
00126         {
00127                 scale_factor = llmax(0.f, calc_bouncy_animation(mAnimTimer.getElapsedTimeF32() / ANIM_TIME));
00128         }
00129 
00130         F32 time_elapsed = mLifeTimer.getElapsedTimeF32();
00131         if (time_elapsed > MAX_VISIBLE_TIME)
00132         {
00133                 markDead();
00134                 return;
00135         }
00136         
00137         if (time_elapsed > MAX_VISIBLE_TIME - FADE_OUT_TIME)
00138         {
00139                 alpha_factor *= clamp_rescale(time_elapsed, MAX_VISIBLE_TIME - FADE_OUT_TIME, MAX_VISIBLE_TIME, 1.f, 0.f);
00140         }
00141 
00142         F32 image_aspect = (F32)mImagep->mFullWidth / (F32)mImagep->mFullHeight;
00143         LLVector3 x_scale = image_aspect * (F32)gViewerWindow->getWindowHeight() * mScale * scale_factor * x_pixel_vec;
00144         LLVector3 y_scale = (F32)gViewerWindow->getWindowHeight() * mScale * scale_factor * y_pixel_vec;
00145 
00146         LLVector3 lower_left = icon_position - (x_scale * 0.5f);
00147         LLVector3 lower_right = icon_position + (x_scale * 0.5f);
00148         LLVector3 upper_left = icon_position - (x_scale * 0.5f) + y_scale;
00149         LLVector3 upper_right = icon_position + (x_scale * 0.5f) + y_scale;
00150 
00151         if (for_select)
00152         {
00153                 // set color to unique color id for picking
00154                 LLColor4U coloru((U8)(mPickID >> 16), (U8)(mPickID >> 8), (U8)mPickID);
00155                 glColor4ubv(coloru.mV);
00156         }
00157         else
00158         {
00159                 LLColor4 icon_color = LLColor4::white;
00160                 icon_color.mV[VALPHA] = alpha_factor;
00161                 glColor4fv(icon_color.mV);
00162                 LLViewerImage::bindTexture(mImagep);
00163         }
00164 
00165         glBegin(GL_QUADS);
00166         {
00167                 glTexCoord2f(0.f, 1.f);
00168                 glVertex3fv(upper_left.mV);
00169                 glTexCoord2f(0.f, 0.f);
00170                 glVertex3fv(lower_left.mV);
00171                 glTexCoord2f(1.f, 0.f);
00172                 glVertex3fv(lower_right.mV);
00173                 glTexCoord2f(1.f, 1.f);
00174                 glVertex3fv(upper_right.mV);
00175         }
00176         glEnd();
00177 }
00178 
00179 void LLHUDIcon::setImage(LLViewerImage* imagep)
00180 {
00181         mImagep = imagep;
00182         mImagep->setClamp(TRUE, TRUE);
00183 }
00184 
00185 void LLHUDIcon::setScale(F32 fraction_of_fov)
00186 {
00187         mScale = fraction_of_fov;
00188 }
00189 
00190 void LLHUDIcon::markDead()
00191 {
00192         if (mSourceObject)
00193         {
00194                 mSourceObject->clearIcon();
00195         }
00196         LLHUDObject::markDead();
00197 }
00198 
00199 void LLHUDIcon::render()
00200 {
00201         renderIcon(FALSE);
00202 }
00203 
00204 void LLHUDIcon::renderForSelect()
00205 {
00206         renderIcon(TRUE);
00207 }
00208 
00209 
00210 //static
00211 S32 LLHUDIcon::generatePickIDs(S32 start_id, S32 step_size)
00212 {
00213         S32 cur_id = start_id;
00214         icon_instance_t::iterator icon_it;
00215 
00216         for(icon_it = sIconInstances.begin(); icon_it != sIconInstances.end(); ++icon_it)
00217         {
00218                 (*icon_it)->mPickID = cur_id;
00219                 cur_id += step_size;
00220         }
00221 
00222         return cur_id;
00223 }
00224 
00225 //static
00226 LLHUDIcon* LLHUDIcon::handlePick(S32 pick_id)
00227 {
00228         icon_instance_t::iterator icon_it;
00229 
00230         for(icon_it = sIconInstances.begin(); icon_it != sIconInstances.end(); ++icon_it)
00231         {
00232                 if (pick_id == (*icon_it)->mPickID)
00233                 {
00234                         return *icon_it;
00235                 }
00236         }
00237 
00238         return NULL;
00239 }
00240 
00241  //static
00242 void LLHUDIcon::updateAll()
00243 {
00244         cleanupDeadIcons();
00245 }
00246 
00247 //static
00248 BOOL LLHUDIcon::iconsNearby()
00249 {
00250         return !sIconInstances.empty();
00251 }
00252 
00253 //static
00254 void LLHUDIcon::cleanupDeadIcons()
00255 {
00256         icon_instance_t::iterator icon_it;
00257 
00258         icon_instance_t icons_to_erase;
00259         for(icon_it = sIconInstances.begin(); icon_it != sIconInstances.end(); ++icon_it)
00260         {
00261                 if ((*icon_it)->mDead)
00262                 {
00263                         icons_to_erase.push_back(*icon_it);
00264                 }
00265         }
00266 
00267         for(icon_it = icons_to_erase.begin(); icon_it != icons_to_erase.end(); ++icon_it)
00268         {
00269                 icon_instance_t::iterator found_it = std::find(sIconInstances.begin(), sIconInstances.end(), *icon_it);
00270                 if (found_it != sIconInstances.end())
00271                 {
00272                         sIconInstances.erase(found_it);
00273                 }
00274         }
00275 }
00276 
00277 //static
00278 S32 LLHUDIcon::getNumInstances()
00279 {
00280         return (S32)sIconInstances.size();
00281 }

Generated on Thu Jul 1 06:08:42 2010 for Second Life Viewer by  doxygen 1.4.7