00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034
00035 #include "llcoord.h"
00036 #include "lldarray.h"
00037 #include "llfontgl.h"
00038 #include "llgl.h"
00039 #include "llglimmediate.h"
00040 #include "llinventory.h"
00041 #include "llmemory.h"
00042 #include "llstring.h"
00043 #include "lluuid.h"
00044 #include "v3math.h"
00045 #include "v3dmath.h"
00046 #include "v4color.h"
00047
00048
00049 #include "llappviewer.h"
00050 #include "lltracker.h"
00051 #include "llagent.h"
00052 #include "llcallingcard.h"
00053 #include "llcolorscheme.h"
00054 #include "llfloaterworldmap.h"
00055 #include "llhudtext.h"
00056 #include "llhudview.h"
00057 #include "llinventorymodel.h"
00058 #include "lllandmarklist.h"
00059 #include "llsky.h"
00060 #include "llui.h"
00061 #include "llviewercamera.h"
00062 #include "llviewerinventory.h"
00063 #include "llworld.h"
00064 #include "llworldmapview.h"
00065 #include "llviewercontrol.h"
00066
00067 const F32 DESTINATION_REACHED_RADIUS = 3.0f;
00068 const F32 DESTINATION_VISITED_RADIUS = 6.0f;
00069
00070
00071
00072 const F32 DESTINATION_UNVISITED_RADIUS = 12.0f;
00073
00074 const S32 ARROW_OFF_RADIUS_SQRD = 100;
00075
00076 const S32 HUD_ARROW_SIZE = 32;
00077
00078
00079 LLTracker *LLTracker::sTrackerp = NULL;
00080 BOOL LLTracker::sCheesyBeacon = FALSE;
00081
00082 LLTracker::LLTracker()
00083 : mTrackingStatus(TRACKING_NOTHING),
00084 mTrackingLocationType(LOCATION_NOTHING),
00085 mHUDArrowCenterX(0),
00086 mHUDArrowCenterY(0),
00087 mToolTip( "" ),
00088 mTrackedLandmarkName(""),
00089 mHasReachedLandmark(FALSE),
00090 mHasLandmarkPosition(FALSE),
00091 mLandmarkHasBeenVisited(FALSE),
00092 mTrackedLocationName( "" ),
00093 mIsTrackingLocation(FALSE)
00094 { }
00095
00096
00097 LLTracker::~LLTracker()
00098 {
00099 purgeBeaconText();
00100 }
00101
00102
00103
00104 void LLTracker::stopTracking(void* userdata)
00105 {
00106 BOOL clear_ui = ((BOOL)(intptr_t)userdata);
00107 instance()->stopTrackingAll(clear_ui);
00108 }
00109
00110
00111
00112 void LLTracker::drawHUDArrow()
00113 {
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 switch (getTrackingStatus())
00124 {
00125 case TRACKING_AVATAR:
00126
00127 if(LLAvatarTracker::instance().haveTrackingInfo())
00128 {
00129 instance()->drawMarker( LLAvatarTracker::instance().getGlobalPos(), gTrackColor );
00130 }
00131 break;
00132
00133 case TRACKING_LANDMARK:
00134 instance()->drawMarker( getTrackedPositionGlobal(), gTrackColor );
00135 break;
00136
00137 case TRACKING_LOCATION:
00138
00139 #if 0
00140
00141 instance()->mTrackedPositionGlobal.mdV[VZ] =
00142 0.9f * instance()->mTrackedPositionGlobal.mdV[VZ]
00143 + 0.1f * (LLWorld::getInstance()->resolveLandHeightGlobal(getTrackedPositionGlobal()) + 1.5f);
00144 #endif
00145 instance()->mTrackedPositionGlobal.mdV[VZ] = llclamp((F32)instance()->mTrackedPositionGlobal.mdV[VZ], LLWorld::getInstance()->resolveLandHeightGlobal(getTrackedPositionGlobal()) + 1.5f, (F32)instance()->getTrackedPositionGlobal().mdV[VZ]);
00146 instance()->drawMarker( getTrackedPositionGlobal(), gTrackColor );
00147 break;
00148
00149 default:
00150 break;
00151 }
00152 }
00153
00154
00155
00156 void LLTracker::render3D()
00157 {
00158 if (!gFloaterWorldMap)
00159 {
00160 return;
00161 }
00162
00163
00164 if( instance()->mIsTrackingLocation )
00165 {
00166 if (!instance()->mBeaconText)
00167 {
00168 instance()->mBeaconText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
00169 instance()->mBeaconText->setDoFade(FALSE);
00170 }
00171
00172 LLVector3d pos_global = instance()->mTrackedPositionGlobal;
00173
00174
00175 F32 dist = gFloaterWorldMap->getDistanceToDestination(pos_global, 0.5f);
00176 if (dist < DESTINATION_REACHED_RADIUS)
00177 {
00178 instance()->stopTrackingLocation();
00179 }
00180 else
00181 {
00182 renderBeacon( instance()->mTrackedPositionGlobal, gTrackColor,
00183 instance()->mBeaconText, instance()->mTrackedLocationName );
00184 }
00185 }
00186
00187
00188 else if( !instance()->mTrackedLandmarkAssetID.isNull() )
00189 {
00190 if (!instance()->mBeaconText)
00191 {
00192 instance()->mBeaconText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
00193 instance()->mBeaconText->setDoFade(FALSE);
00194 }
00195
00196 if (instance()->mHasLandmarkPosition)
00197 {
00198 F32 dist = gFloaterWorldMap->getDistanceToDestination(instance()->mTrackedPositionGlobal, 1.0f);
00199
00200 if ( !instance()->mLandmarkHasBeenVisited
00201 && dist < DESTINATION_VISITED_RADIUS )
00202 {
00203
00204 instance()->setLandmarkVisited();
00205 }
00206
00207 if ( !instance()->mHasReachedLandmark
00208 && dist < DESTINATION_REACHED_RADIUS )
00209 {
00210
00211 instance()->stopTrackingLandmark();
00212 }
00213 else
00214 {
00215 if ( instance()->mHasReachedLandmark
00216 && dist > DESTINATION_UNVISITED_RADIUS )
00217 {
00218
00219
00220
00221
00222 instance()->mHasReachedLandmark = FALSE;
00223 }
00224 renderBeacon( instance()->mTrackedPositionGlobal, gTrackColor,
00225 instance()->mBeaconText, instance()->mTrackedLandmarkName );
00226 }
00227 }
00228 else
00229 {
00230
00231 instance()->cacheLandmarkPosition();
00232 }
00233 }
00234 else
00235 {
00236
00237 LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
00238 if(av_tracker.haveTrackingInfo())
00239 {
00240 if (!instance()->mBeaconText)
00241 {
00242 instance()->mBeaconText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
00243 instance()->mBeaconText->setDoFade(FALSE);
00244 }
00245
00246 F32 dist = gFloaterWorldMap->getDistanceToDestination(instance()->mTrackedPositionGlobal, 0.0f);
00247 if (dist < DESTINATION_REACHED_RADIUS)
00248 {
00249 instance()->stopTrackingAvatar();
00250 }
00251 else
00252 {
00253 renderBeacon( av_tracker.getGlobalPos(), gTrackColor,
00254 instance()->mBeaconText, av_tracker.getName() );
00255 }
00256 }
00257 else
00258 {
00259 BOOL stop_tracking = FALSE;
00260 const LLUUID& avatar_id = av_tracker.getAvatarID();
00261 if(avatar_id.isNull())
00262 {
00263 stop_tracking = TRUE;
00264 }
00265 else
00266 {
00267 const LLRelationship* buddy = av_tracker.getBuddyInfo(avatar_id);
00268 if(buddy && !buddy->isOnline() && !gAgent.isGodlike())
00269 {
00270 stop_tracking = TRUE;
00271 }
00272 if(!buddy && !gAgent.isGodlike())
00273 {
00274 stop_tracking = TRUE;
00275 }
00276 }
00277 if(stop_tracking)
00278 {
00279 instance()->stopTrackingAvatar();
00280 }
00281 }
00282 }
00283 }
00284
00285
00286
00287 void LLTracker::trackAvatar( const LLUUID& avatar_id, const LLString& name )
00288 {
00289 instance()->stopTrackingLandmark();
00290 instance()->stopTrackingLocation();
00291
00292 LLAvatarTracker::instance().track( avatar_id, name );
00293 instance()->mTrackingStatus = TRACKING_AVATAR;
00294 instance()->mLabel = name;
00295 }
00296
00297
00298
00299 void LLTracker::trackLandmark( const LLUUID& asset_id, const LLUUID& item_id, const LLString& name)
00300 {
00301 instance()->stopTrackingAvatar();
00302 instance()->stopTrackingLocation();
00303
00304 instance()->mTrackedLandmarkAssetID = asset_id;
00305 instance()->mTrackedLandmarkItemID = item_id;
00306 instance()->mTrackedLandmarkName = name;
00307 instance()->cacheLandmarkPosition();
00308 instance()->mTrackingStatus = TRACKING_LANDMARK;
00309 instance()->mLabel = name;
00310 }
00311
00312
00313
00314 void LLTracker::trackLocation(const LLVector3d& pos_global, const LLString& full_name, const LLString& tooltip, ETrackingLocationType location_type)
00315 {
00316 instance()->stopTrackingAvatar();
00317 instance()->stopTrackingLandmark();
00318
00319 instance()->mTrackedPositionGlobal = pos_global;
00320 instance()->mTrackedLocationName = full_name;
00321 instance()->mIsTrackingLocation = TRUE;
00322 instance()->mTrackingStatus = TRACKING_LOCATION;
00323 instance()->mTrackingLocationType = location_type;
00324 instance()->mLabel = full_name;
00325 instance()->mToolTip = tooltip;
00326 }
00327
00328
00329
00330 BOOL LLTracker::handleMouseDown(S32 x, S32 y)
00331 {
00332 BOOL eat_mouse_click = FALSE;
00333
00334 S32 dist_sqrd = (x - instance()->mHUDArrowCenterX) * (x - instance()->mHUDArrowCenterX) +
00335 (y - instance()->mHUDArrowCenterY) * (y - instance()->mHUDArrowCenterY);
00336 if (dist_sqrd < ARROW_OFF_RADIUS_SQRD)
00337 {
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 if (getTrackingStatus())
00348 {
00349 instance()->stopTrackingAll();
00350 eat_mouse_click = TRUE;
00351 }
00352 }
00353 return eat_mouse_click;
00354 }
00355
00356
00357
00358 LLVector3d LLTracker::getTrackedPositionGlobal()
00359 {
00360 LLVector3d pos_global;
00361 switch (getTrackingStatus())
00362 {
00363 case TRACKING_AVATAR:
00364 {
00365 LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
00366 if (av_tracker.haveTrackingInfo())
00367 {
00368 pos_global = av_tracker.getGlobalPos(); }
00369 break;
00370 }
00371 case TRACKING_LANDMARK:
00372 if( instance()->mHasLandmarkPosition )
00373 {
00374 pos_global = instance()->mTrackedPositionGlobal;
00375 }
00376 break;
00377 case TRACKING_LOCATION:
00378 pos_global = instance()->mTrackedPositionGlobal;
00379 break;
00380 default:
00381 break;
00382 }
00383 return pos_global;
00384 }
00385
00386
00387
00388 BOOL LLTracker::hasLandmarkPosition()
00389 {
00390 if (!instance()->mHasLandmarkPosition)
00391 {
00392
00393 instance()->cacheLandmarkPosition();
00394 }
00395 return instance()->mHasLandmarkPosition;
00396 }
00397
00398
00399
00400 const LLString& LLTracker::getTrackedLocationName()
00401 {
00402 return instance()->mTrackedLocationName;
00403 }
00404
00405 F32 pulse_func(F32 t, F32 z)
00406 {
00407 if (!LLTracker::sCheesyBeacon)
00408 {
00409 return 0.f;
00410 }
00411
00412 t *= 3.14159f;
00413 z -= t*64.f - 256.f;
00414
00415 F32 a = cosf(z*3.14159/512.f)*10.0f;
00416 a = llmax(a, 9.9f);
00417 a -= 9.9f;
00418 a *= 10.f;
00419 return a;
00420 }
00421
00422 void draw_shockwave(F32 center_z, F32 t, S32 steps, LLColor4 color)
00423 {
00424 if (!LLTracker::sCheesyBeacon)
00425 {
00426 return;
00427 }
00428
00429 t *= 0.6284f/3.14159f;
00430
00431 t -= (F32) (S32) t;
00432
00433 t = llmax(t, 0.5f);
00434 t -= 0.5f;
00435 t *= 2.0f;
00436
00437 F32 radius = t*16536.f;
00438
00439
00440 F32 delta = F_TWO_PI / steps;
00441 F32 sin_delta = sin( delta );
00442 F32 cos_delta = cos( delta );
00443 F32 x = radius;
00444 F32 y = 0.f;
00445
00446 LLColor4 ccol = LLColor4(1,1,1,(1.f-t)*0.25f);
00447 gGL.begin(LLVertexBuffer::TRIANGLE_FAN);
00448 gGL.color4fv(ccol.mV);
00449 gGL.vertex3f(0.f, 0.f, center_z);
00450
00451 steps += 1;
00452
00453 color.mV[3] = (1.f-t*t);
00454
00455 gGL.color4fv(color.mV);
00456 while( steps-- )
00457 {
00458
00459 gGL.vertex3f( x, y, center_z );
00460 F32 x_new = x * cos_delta - y * sin_delta;
00461 y = x * sin_delta + y * cos_delta;
00462 x = x_new;
00463 }
00464 gGL.end();
00465 }
00466
00467
00468
00469 void LLTracker::renderBeacon(LLVector3d pos_global,
00470 const LLColor4& color,
00471 LLHUDText* hud_textp,
00472 const std::string& label )
00473 {
00474 sCheesyBeacon = gSavedSettings.getBOOL("CheesyBeacon");
00475 LLVector3d to_vec = pos_global - gAgent.getCameraPositionGlobal();
00476
00477 F32 dist = (F32)to_vec.magVec();
00478 F32 color_frac = 1.f;
00479 if (dist > 0.99f * LLViewerCamera::getInstance()->getFar())
00480 {
00481 color_frac = 0.4f;
00482
00483 }
00484 else
00485 {
00486 color_frac = 1.f - 0.6f*(dist/LLViewerCamera::getInstance()->getFar());
00487 }
00488
00489 LLColor4 fogged_color = color_frac * color + (1 - color_frac)*gSky.getFogColor();
00490
00491 F32 FADE_DIST = 3.f;
00492 fogged_color.mV[3] = llmax(0.2f, llmin(0.5f,(dist-FADE_DIST)/FADE_DIST));
00493
00494 LLVector3 pos_agent = gAgent.getPosAgentFromGlobal(pos_global);
00495
00496 LLGLSTracker gls_tracker;
00497 LLGLDisable cull_face(GL_CULL_FACE);
00498 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
00499
00500
00501 glMatrixMode(GL_MODELVIEW);
00502 glPushMatrix();
00503 glTranslatef(pos_agent.mV[0], pos_agent.mV[1], pos_agent.mV[2]);
00504
00505 draw_shockwave(1024.f, gRenderStartTime.getElapsedTimeF32(), 32, fogged_color);
00506
00507 gGL.color4fv(fogged_color.mV);
00508 const U32 BEACON_VERTS = 256;
00509 const F32 step = 1024.0f/BEACON_VERTS;
00510
00511 LLVector3 x_axis = LLViewerCamera::getInstance()->getLeftAxis();
00512 F32 t = gRenderStartTime.getElapsedTimeF32();
00513 F32 dr = dist/LLViewerCamera::getInstance()->getFar();
00514
00515 for (U32 i = 0; i < BEACON_VERTS; i++)
00516 {
00517 F32 x = x_axis.mV[0];
00518 F32 y = x_axis.mV[1];
00519
00520 F32 z = i * step;
00521 F32 z_next = (i+1)*step;
00522
00523 F32 a = pulse_func(t, z);
00524 F32 an = pulse_func(t, z_next);
00525
00526 LLColor4 c_col = fogged_color + LLColor4(a,a,a,a);
00527 LLColor4 col_next = fogged_color + LLColor4(an,an,an,an);
00528 LLColor4 col_edge = fogged_color * LLColor4(a,a,a,0.0f);
00529 LLColor4 col_edge_next = fogged_color * LLColor4(an,an,an,0.0f);
00530
00531 a *= 2.f;
00532 a += 1.0f+dr;
00533
00534 an *= 2.f;
00535 an += 1.0f+dr;
00536
00537 gGL.begin(LLVertexBuffer::TRIANGLE_STRIP);
00538 gGL.color4fv(col_edge.mV);
00539 gGL.vertex3f(-x*a, -y*a, z);
00540 gGL.color4fv(col_edge_next.mV);
00541 gGL.vertex3f(-x*an, -y*an, z_next);
00542
00543 gGL.color4fv(c_col.mV);
00544 gGL.vertex3f(0, 0, z);
00545 gGL.color4fv(col_next.mV);
00546 gGL.vertex3f(0, 0, z_next);
00547
00548 gGL.color4fv(col_edge.mV);
00549 gGL.vertex3f(x*a,y*a,z);
00550 gGL.color4fv(col_edge_next.mV);
00551 gGL.vertex3f(x*an,y*an,z_next);
00552
00553 gGL.end();
00554 }
00555
00556
00557 glPopMatrix();
00558
00559 char text[1024];
00560 snprintf(text, sizeof(text), "%.0f m", to_vec.magVec());
00561
00562 LLWString wstr;
00563 wstr += utf8str_to_wstring(label);
00564 wstr += '\n';
00565 wstr += utf8str_to_wstring(text);
00566
00567 hud_textp->setFont(LLFontGL::sSansSerif);
00568 hud_textp->setZCompare(FALSE);
00569 hud_textp->setColor(LLColor4(1.f, 1.f, 1.f, llmax(0.2f, llmin(1.f,(dist-FADE_DIST)/FADE_DIST))));
00570
00571 hud_textp->setString(wstr);
00572 hud_textp->setVertAlignment(LLHUDText::ALIGN_VERT_CENTER);
00573 hud_textp->setPositionAgent(pos_agent);
00574 }
00575
00576
00577 void LLTracker::stopTrackingAll(BOOL clear_ui)
00578 {
00579 switch (mTrackingStatus)
00580 {
00581 case TRACKING_AVATAR :
00582 stopTrackingAvatar(clear_ui);
00583 break;
00584 case TRACKING_LANDMARK :
00585 stopTrackingLandmark(clear_ui);
00586 break;
00587 case TRACKING_LOCATION :
00588 stopTrackingLocation(clear_ui);
00589 break;
00590 default:
00591 mTrackingStatus = TRACKING_NOTHING;
00592 break;
00593 }
00594 }
00595
00596
00597 void LLTracker::stopTrackingAvatar(BOOL clear_ui)
00598 {
00599 LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
00600 if( !av_tracker.getAvatarID().isNull() )
00601 {
00602 av_tracker.untrack( av_tracker.getAvatarID() );
00603 }
00604
00605 purgeBeaconText();
00606 gFloaterWorldMap->clearAvatarSelection(clear_ui);
00607 mTrackingStatus = TRACKING_NOTHING;
00608 }
00609
00610
00611 void LLTracker::stopTrackingLandmark(BOOL clear_ui)
00612 {
00613 purgeBeaconText();
00614 mTrackedLandmarkAssetID.setNull();
00615 mTrackedLandmarkItemID.setNull();
00616 mTrackedLandmarkName.assign("");
00617 mTrackedPositionGlobal.zeroVec();
00618 mHasLandmarkPosition = FALSE;
00619 mHasReachedLandmark = FALSE;
00620 mLandmarkHasBeenVisited = TRUE;
00621 gFloaterWorldMap->clearLandmarkSelection(clear_ui);
00622 mTrackingStatus = TRACKING_NOTHING;
00623 }
00624
00625
00626 void LLTracker::stopTrackingLocation(BOOL clear_ui)
00627 {
00628 purgeBeaconText();
00629 mTrackedLocationName.assign("");
00630 mIsTrackingLocation = FALSE;
00631 mTrackedPositionGlobal.zeroVec();
00632 gFloaterWorldMap->clearLocationSelection(clear_ui);
00633 mTrackingStatus = TRACKING_NOTHING;
00634 mTrackingLocationType = LOCATION_NOTHING;
00635 }
00636
00637 void LLTracker::clearFocus()
00638 {
00639 instance()->mTrackingStatus = TRACKING_NOTHING;
00640 }
00641
00642 void LLTracker::drawMarker(const LLVector3d& pos_global, const LLColor4& color)
00643 {
00644
00645 LLVector3 pos_local = gAgent.getPosAgentFromGlobal(pos_global);
00646
00647
00648 LLCoordGL screen;
00649 S32 x = 0;
00650 S32 y = 0;
00651 const BOOL CLAMP = TRUE;
00652
00653 if (LLViewerCamera::getInstance()->projectPosAgentToScreen(pos_local, screen, CLAMP)
00654 || LLViewerCamera::getInstance()->projectPosAgentToScreenEdge(pos_local, screen) )
00655 {
00656 gHUDView->screenPointToLocal(screen.mX, screen.mY, &x, &y);
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667 LLRect rect = gHUDView->getRect();
00668 S32 x_center = lltrunc(0.5f * (F32)rect.getWidth());
00669 S32 y_center = lltrunc(0.5f * (F32)rect.getHeight());
00670 x = x - x_center;
00671 y = y - y_center;
00672 F32 dist = sqrt((F32)(x*x + y*y));
00673 S32 half_arrow_size = lltrunc(0.5f * HUD_ARROW_SIZE);
00674 if (dist > 0.f)
00675 {
00676 const F32 ARROW_ELLIPSE_RADIUS_X = 2 * HUD_ARROW_SIZE;
00677 const F32 ARROW_ELLIPSE_RADIUS_Y = HUD_ARROW_SIZE;
00678
00679
00680 F32 x_target = (F32)(x + x_center) - (ARROW_ELLIPSE_RADIUS_X * ((F32)x / dist) );
00681 F32 y_target = (F32)(y + y_center) - (ARROW_ELLIPSE_RADIUS_Y * ((F32)y / dist) );
00682
00683
00684 F32 x_clamped = llclamp( x_target, (F32)half_arrow_size, (F32)(rect.getWidth() - half_arrow_size));
00685 F32 y_clamped = llclamp( y_target, (F32)half_arrow_size, (F32)(rect.getHeight() - half_arrow_size));
00686
00687 F32 slope = (F32)(y) / (F32)(x);
00688 F32 window_ratio = (F32)(rect.getHeight() - HUD_ARROW_SIZE) / (F32)(rect.getWidth() - HUD_ARROW_SIZE);
00689
00690
00691
00692 if (llabs(slope) > window_ratio)
00693 {
00694 if (y_clamped != (F32)y_target)
00695 {
00696
00697 x_clamped = (y_clamped - (F32)y_center) / slope + (F32)x_center;
00698 }
00699 }
00700 else if (x_clamped != (F32)x_target)
00701 {
00702
00703 y_clamped = (x_clamped - (F32)x_center) * slope + (F32)y_center;
00704 }
00705 mHUDArrowCenterX = lltrunc(x_clamped);
00706 mHUDArrowCenterY = lltrunc(y_clamped);
00707 }
00708 else
00709 {
00710
00711 x = mHUDArrowCenterX - x_center;
00712 y = mHUDArrowCenterY - y_center;
00713 }
00714
00715 F32 angle = atan2( (F32)y, (F32)x );
00716
00717 gl_draw_scaled_rotated_image(mHUDArrowCenterX - half_arrow_size,
00718 mHUDArrowCenterY - half_arrow_size,
00719 HUD_ARROW_SIZE, HUD_ARROW_SIZE,
00720 RAD_TO_DEG * angle,
00721 LLWorldMapView::sTrackArrowImage->getImage(),
00722 color);
00723 }
00724 }
00725
00726
00727 void LLTracker::setLandmarkVisited()
00728 {
00729
00730 if (!mTrackedLandmarkItemID.isNull())
00731 {
00732 LLInventoryItem* i = gInventory.getItem( mTrackedLandmarkItemID );
00733 LLViewerInventoryItem* item = (LLViewerInventoryItem*)i;
00734 if ( item
00735 && !(item->getFlags()&LLInventoryItem::II_FLAGS_LANDMARK_VISITED))
00736 {
00737 U32 flags = item->getFlags();
00738 flags |= LLInventoryItem::II_FLAGS_LANDMARK_VISITED;
00739 item->setFlags(flags);
00740 LLMessageSystem* msg = gMessageSystem;
00741 msg->newMessage("ChangeInventoryItemFlags");
00742 msg->nextBlock("AgentData");
00743 msg->addUUID("AgentID", gAgent.getID());
00744 msg->addUUID("SessionID", gAgent.getSessionID());
00745 msg->nextBlock("InventoryData");
00746 msg->addUUID("ItemID", mTrackedLandmarkItemID);
00747 msg->addU32("Flags", flags);
00748 gAgent.sendReliableMessage();
00749
00750 LLInventoryModel::LLCategoryUpdate up(item->getParentUUID(), 0);
00751 gInventory.accountForUpdate(up);
00752
00753
00754 gInventory.addChangedMask(LLInventoryObserver::INTERNAL, item->getUUID());
00755 gInventory.notifyObservers();
00756 }
00757 }
00758 }
00759
00760
00761 void LLTracker::cacheLandmarkPosition()
00762 {
00763
00764
00765 BOOL found_landmark = FALSE;
00766 if( mTrackedLandmarkAssetID == LLFloaterWorldMap::getHomeID())
00767 {
00768 LLVector3d pos_global;
00769 if ( gAgent.getHomePosGlobal( &mTrackedPositionGlobal ))
00770 {
00771 found_landmark = TRUE;
00772 }
00773 else
00774 {
00775 llwarns << "LLTracker couldn't find home pos" << llendl;
00776 mTrackedLandmarkAssetID.setNull();
00777 mTrackedLandmarkItemID.setNull();
00778 }
00779 }
00780 else
00781 {
00782 LLLandmark* landmark = gLandmarkList.getAsset(mTrackedLandmarkAssetID);
00783 if(landmark && landmark->getGlobalPos(mTrackedPositionGlobal))
00784 {
00785 found_landmark = TRUE;
00786
00787
00788 mLandmarkHasBeenVisited = FALSE;
00789 LLInventoryItem* item = gInventory.getItem(mTrackedLandmarkItemID);
00790 if ( item
00791 && item->getFlags()&LLInventoryItem::II_FLAGS_LANDMARK_VISITED)
00792 {
00793 mLandmarkHasBeenVisited = TRUE;
00794 }
00795 }
00796 }
00797 if ( found_landmark && gFloaterWorldMap )
00798 {
00799 mHasReachedLandmark = FALSE;
00800 F32 dist = gFloaterWorldMap->getDistanceToDestination(mTrackedPositionGlobal, 1.0f);
00801 if ( dist < DESTINATION_UNVISITED_RADIUS )
00802 {
00803 mHasReachedLandmark = TRUE;
00804 }
00805 mHasLandmarkPosition = TRUE;
00806 }
00807 mHasLandmarkPosition = found_landmark;
00808 }
00809
00810
00811 void LLTracker::purgeBeaconText()
00812 {
00813 if(!mBeaconText.isNull())
00814 {
00815 mBeaconText->markDead();
00816 mBeaconText = NULL;
00817 }
00818 }
00819