diff options
Diffstat (limited to 'linden/indra/newview/llhudicon.cpp')
-rw-r--r-- | linden/indra/newview/llhudicon.cpp | 103 |
1 files changed, 102 insertions, 1 deletions
diff --git a/linden/indra/newview/llhudicon.cpp b/linden/indra/newview/llhudicon.cpp index 5d5c6a1..3658b8e 100644 --- a/linden/indra/newview/llhudicon.cpp +++ b/linden/indra/newview/llhudicon.cpp | |||
@@ -4,7 +4,7 @@ | |||
4 | * | 4 | * |
5 | * $LicenseInfo:firstyear=2006&license=viewergpl$ | 5 | * $LicenseInfo:firstyear=2006&license=viewergpl$ |
6 | * | 6 | * |
7 | * Copyright (c) 2006-2008, Linden Research, Inc. | 7 | * Copyright (c) 2006-2009, Linden Research, Inc. |
8 | * | 8 | * |
9 | * Second Life Viewer Source Code | 9 | * Second Life Viewer Source Code |
10 | * The source code in this file ("Source Code") is provided by Linden Lab | 10 | * The source code in this file ("Source Code") is provided by Linden Lab |
@@ -210,6 +210,80 @@ void LLHUDIcon::renderForSelect() | |||
210 | renderIcon(TRUE); | 210 | renderIcon(TRUE); |
211 | } | 211 | } |
212 | 212 | ||
213 | BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3* intersection) | ||
214 | { | ||
215 | if (mHidden) | ||
216 | return FALSE; | ||
217 | |||
218 | if (mSourceObject.isNull() || mImagep.isNull()) | ||
219 | { | ||
220 | markDead(); | ||
221 | return FALSE; | ||
222 | } | ||
223 | |||
224 | LLVector3 obj_position = mSourceObject->getRenderPosition(); | ||
225 | |||
226 | // put icon above object, and in front | ||
227 | // RN: don't use drawable radius, it's fricking HUGE | ||
228 | LLVector3 icon_relative_pos = (LLViewerCamera::getInstance()->getUpAxis() * ~mSourceObject->getRenderRotation()); | ||
229 | icon_relative_pos.abs(); | ||
230 | |||
231 | F32 distance_scale = llmin(mSourceObject->getScale().mV[VX] / icon_relative_pos.mV[VX], | ||
232 | mSourceObject->getScale().mV[VY] / icon_relative_pos.mV[VY], | ||
233 | mSourceObject->getScale().mV[VZ] / icon_relative_pos.mV[VZ]); | ||
234 | F32 up_distance = 0.5f * distance_scale; | ||
235 | LLVector3 icon_position = obj_position + (up_distance * LLViewerCamera::getInstance()->getUpAxis()) * 1.2f; | ||
236 | |||
237 | LLVector3 icon_to_cam = LLViewerCamera::getInstance()->getOrigin() - icon_position; | ||
238 | icon_to_cam.normVec(); | ||
239 | |||
240 | icon_position += icon_to_cam * mSourceObject->mDrawable->getRadius() * 1.1f; | ||
241 | |||
242 | mDistance = dist_vec(icon_position, LLViewerCamera::getInstance()->getOrigin()); | ||
243 | |||
244 | LLVector3 x_pixel_vec; | ||
245 | LLVector3 y_pixel_vec; | ||
246 | |||
247 | LLViewerCamera::getInstance()->getPixelVectors(icon_position, y_pixel_vec, x_pixel_vec); | ||
248 | |||
249 | F32 scale_factor = 1.f; | ||
250 | if (mAnimTimer.getElapsedTimeF32() < ANIM_TIME) | ||
251 | { | ||
252 | scale_factor = llmax(0.f, calc_bouncy_animation(mAnimTimer.getElapsedTimeF32() / ANIM_TIME)); | ||
253 | } | ||
254 | |||
255 | F32 time_elapsed = mLifeTimer.getElapsedTimeF32(); | ||
256 | if (time_elapsed > MAX_VISIBLE_TIME) | ||
257 | { | ||
258 | markDead(); | ||
259 | return FALSE; | ||
260 | } | ||
261 | |||
262 | F32 image_aspect = (F32)mImagep->mFullWidth / (F32)mImagep->mFullHeight; | ||
263 | LLVector3 x_scale = image_aspect * (F32)gViewerWindow->getWindowHeight() * mScale * scale_factor * x_pixel_vec; | ||
264 | LLVector3 y_scale = (F32)gViewerWindow->getWindowHeight() * mScale * scale_factor * y_pixel_vec; | ||
265 | |||
266 | LLVector3 lower_left = icon_position - (x_scale * 0.5f); | ||
267 | LLVector3 lower_right = icon_position + (x_scale * 0.5f); | ||
268 | LLVector3 upper_left = icon_position - (x_scale * 0.5f) + y_scale; | ||
269 | LLVector3 upper_right = icon_position + (x_scale * 0.5f) + y_scale; | ||
270 | |||
271 | |||
272 | F32 t = 0.f; | ||
273 | LLVector3 dir = end-start; | ||
274 | |||
275 | if (LLTriangleRayIntersect(upper_right, upper_left, lower_right, start, dir, NULL, NULL, &t, FALSE) || | ||
276 | LLTriangleRayIntersect(lower_left, lower_right, upper_left, start, dir, NULL, NULL, &t, FALSE)) | ||
277 | { | ||
278 | if (intersection) | ||
279 | { | ||
280 | *intersection = start + dir*t; | ||
281 | } | ||
282 | return TRUE; | ||
283 | } | ||
284 | |||
285 | return FALSE; | ||
286 | } | ||
213 | 287 | ||
214 | //static | 288 | //static |
215 | S32 LLHUDIcon::generatePickIDs(S32 start_id, S32 step_size) | 289 | S32 LLHUDIcon::generatePickIDs(S32 start_id, S32 step_size) |
@@ -242,6 +316,33 @@ LLHUDIcon* LLHUDIcon::handlePick(S32 pick_id) | |||
242 | return NULL; | 316 | return NULL; |
243 | } | 317 | } |
244 | 318 | ||
319 | //static | ||
320 | LLHUDIcon* LLHUDIcon::lineSegmentIntersectAll(const LLVector3& start, const LLVector3& end, LLVector3* intersection) | ||
321 | { | ||
322 | icon_instance_t::iterator icon_it; | ||
323 | |||
324 | LLVector3 local_end = end; | ||
325 | LLVector3 position; | ||
326 | |||
327 | LLHUDIcon* ret = NULL; | ||
328 | for(icon_it = sIconInstances.begin(); icon_it != sIconInstances.end(); ++icon_it) | ||
329 | { | ||
330 | LLHUDIcon* icon = *icon_it; | ||
331 | if (icon->lineSegmentIntersect(start, local_end, &position)) | ||
332 | { | ||
333 | ret = icon; | ||
334 | if (intersection) | ||
335 | { | ||
336 | *intersection = position; | ||
337 | } | ||
338 | local_end = position; | ||
339 | } | ||
340 | } | ||
341 | |||
342 | return ret; | ||
343 | } | ||
344 | |||
345 | |||
245 | //static | 346 | //static |
246 | void LLHUDIcon::updateAll() | 347 | void LLHUDIcon::updateAll() |
247 | { | 348 | { |