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

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