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
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
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
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
00104
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
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
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
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
00246 void LLHUDIcon::updateAll()
00247 {
00248 cleanupDeadIcons();
00249 }
00250
00251
00252 BOOL LLHUDIcon::iconsNearby()
00253 {
00254 return !sIconInstances.empty();
00255 }
00256
00257
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
00282 S32 LLHUDIcon::getNumInstances()
00283 {
00284 return (S32)sIconInstances.size();
00285 }