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
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
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
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
00100
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
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
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
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
00242 void LLHUDIcon::updateAll()
00243 {
00244 cleanupDeadIcons();
00245 }
00246
00247
00248 BOOL LLHUDIcon::iconsNearby()
00249 {
00250 return !sIconInstances.empty();
00251 }
00252
00253
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
00278 S32 LLHUDIcon::getNumInstances()
00279 {
00280 return (S32)sIconInstances.size();
00281 }