void LLHUDText::renderText()
{
	if (!mVisible || mHidden)
	{
		return;
	}

	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);

	LLGLState gls_blend(GL_BLEND, TRUE);
	LLGLState gls_alpha(GL_ALPHA_TEST, TRUE);
	
	LLColor4 shadow_color(0.f, 0.f, 0.f, 1.f);
	F32 alpha_factor = 1.f;
	LLColor4 text_color = mColor;
	if (mDoFade)
	{
		if (mLastDistance > mFadeDistance)
		{
			alpha_factor = llmax(0.f, 1.f - (mLastDistance - mFadeDistance)/mFadeRange);
			text_color.mV[3] = text_color.mV[3]*alpha_factor;
		}
	}
	if (text_color.mV[3] < 0.01f)
	{
		return;
	}
	shadow_color.mV[3] = text_color.mV[3];

	mOffsetY = lltrunc(mHeight * ((mVertAlignment == ALIGN_VERT_CENTER) ? 0.5f : 1.f));

	// *TODO: cache this image
	LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Square");

	// *TODO: make this a per-text setting
	LLColor4 bg_color = LLUIColorTable::instance().getColor("ObjectBubbleColor");
	bg_color.setAlpha(gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);

	const S32 border_height = 16;
	const S32 border_width = 16;

	// *TODO move this into helper function
	F32 border_scale = 1.f;

	if (border_height * 2 > mHeight)
	{
		border_scale = (F32)mHeight / ((F32)border_height * 2.f);
	}
	if (border_width * 2 > mWidth)
	{
		border_scale = llmin(border_scale, (F32)mWidth / ((F32)border_width * 2.f));
	}

	// scale screen size of borders down
	//RN: for now, text on hud objects is never occluded

	LLVector3 x_pixel_vec;
	LLVector3 y_pixel_vec;
	
	if (mOnHUDAttachment)
	{
		x_pixel_vec = LLVector3::y_axis / (F32)gViewerWindow->getWorldViewWidthRaw();
		y_pixel_vec = LLVector3::z_axis / (F32)gViewerWindow->getWorldViewHeightRaw();
	}
	else
	{
		LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);
	}

	LLVector3 width_vec = mWidth * x_pixel_vec;
	LLVector3 height_vec = mHeight * y_pixel_vec;

	mRadius = (width_vec + height_vec).magVec() * 0.5f;

	LLVector2 screen_offset;
	screen_offset = mPositionOffset;

	LLVector3 render_position = mPositionAgent  
			+ (x_pixel_vec * screen_offset.mV[VX])
			+ (y_pixel_vec * screen_offset.mV[VY]);

	F32 y_offset = (F32)mOffsetY;
		
	// Render label
	{
		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
	}

	// Render text
	{
		// -1 mMaxLines means unlimited lines.
		S32 start_segment;
		S32 max_lines = getMaxLines();

		if (max_lines < 0) 
		{
			start_segment = 0;
		}
		else 
		{
			start_segment = llmax((S32)0, (S32)mTextSegments.size() - max_lines);
		}

		for (std::vector<LLHUDTextSegment>::iterator segment_iter = mTextSegments.begin() + start_segment;
			 segment_iter != mTextSegments.end(); ++segment_iter )
		{
			const LLFontGL* fontp = segment_iter->mFont;
			y_offset -= fontp->getLineHeight() - 1; // correction factor to match legacy font metrics

			U8 style = segment_iter->mStyle;
			LLFontGL::ShadowType shadow = LLFontGL::DROP_SHADOW;
	
			F32 x_offset;
			if (mTextAlignment== ALIGN_TEXT_CENTER)
			{
				x_offset = -0.5f*segment_iter->getWidth(fontp);
			}
			else // ALIGN_LEFT
			{
				x_offset = -0.5f * mWidth + (HORIZONTAL_PADDING / 2.f);
			}

			text_color = segment_iter->mColor;
			text_color.mV[VALPHA] *= alpha_factor;

			hud_render_text(segment_iter->getText(), render_position, *fontp, style, shadow, x_offset, y_offset, text_color, mOnHUDAttachment);
		}
	}
	/// Reset the default color to white.  The renderer expects this to be the default. 
	gGL.color4f(1.0f, 1.0f, 1.0f, 1.0f);
}
BOOL LLVOSurfacePatch::updateGeometry(LLDrawable *drawable)
{
	LL_RECORD_BLOCK_TIME(FTM_UPDATE_TERRAIN);

	dirtySpatialGroup(TRUE);
	
	S32 min_comp, max_comp, range;
	min_comp = lltrunc(mPatchp->getMinComposition());
	max_comp = lltrunc(ceil(mPatchp->getMaxComposition()));
	range = (max_comp - min_comp);
	range++;
	S32 new_base_comp = lltrunc(mPatchp->getMinComposition());
	if (range > 3)
	{
		if ((mPatchp->getMinComposition() - min_comp) > (max_comp - mPatchp->getMaxComposition()))
		{
			// The top side runs over more
			new_base_comp++;
		}
		range = 3;
	}

	// Pick the two closest detail textures for this patch...
	// Then create the draw pool for it.
	// Actually, should get the average composition instead of the center.
	mBaseComp = new_base_comp;

	//////////////////////////
	//
	// Figure out the strides
	//
	//

	U32 patch_width, render_stride, north_stride, east_stride, length;
	render_stride = mPatchp->getRenderStride();
	patch_width = mPatchp->getSurface()->getGridsPerPatchEdge();

	length = patch_width / render_stride;

	if (mPatchp->getNeighborPatch(NORTH))
	{
		north_stride = mPatchp->getNeighborPatch(NORTH)->getRenderStride();
	}
	else
	{
		north_stride = render_stride;
	}

	if (mPatchp->getNeighborPatch(EAST))
	{
		east_stride = mPatchp->getNeighborPatch(EAST)->getRenderStride();
	}
	else
	{
		east_stride = render_stride;
	}

	mLastLength = length;
	mLastStride = render_stride;
	mLastNorthStride = north_stride;
	mLastEastStride = east_stride;

	return TRUE;
}
Esempio n. 3
0
// Per-frame updates of visibility
void LLStatusBar::refresh()
{
	// Adding Net Stat Meter back in
	F32 bwtotal = gViewerThrottle.getMaxBandwidth() / 1000.f;
	mSGBandwidth->setMin(0.f);
	mSGBandwidth->setMax(bwtotal*1.25f);
	mSGBandwidth->setThreshold(0, bwtotal*0.75f);
	mSGBandwidth->setThreshold(1, bwtotal);
	mSGBandwidth->setThreshold(2, bwtotal);

	// *TODO: Localize / translate time

	// Get current UTC time, adjusted for the user's clock
	// being off.
	time_t utc_time;
	utc_time = time_corrected();

	// There's only one internal tm buffer.
	struct tm* internal_time;

	// Convert to Pacific, based on server's opinion of whether
	// it's daylight savings time there.
	internal_time = utc_to_pacific_time(utc_time, gPacificDaylightTime);

	S32 hour = internal_time->tm_hour;
	S32 min  = internal_time->tm_min;

	std::string am_pm = "AM";
	if (hour > 11)
	{
		hour -= 12;
		am_pm = "PM";
	}

	std::string tz = "PST";
	if (gPacificDaylightTime)
	{
		tz = "PDT";
	}
	// Zero hour is 12 AM
	if (hour == 0) hour = 12;
	std::ostringstream t;
	t << std::setfill(' ') << std::setw(2) << hour << ":" 
		<< std::setfill('0') << std::setw(2) << min 
		<< " " << am_pm << " " << tz;
	mTextTime->setText(t.str());

	// Year starts at 1900, set the tooltip to have the date
	std::ostringstream date;
	date	<< sDays[internal_time->tm_wday] << ", "
		<< std::setfill('0') << std::setw(2) << internal_time->tm_mday << " "
		<< sMonths[internal_time->tm_mon] << " "
		<< internal_time->tm_year + 1900;
	mTextTime->setToolTip(date.str());

	LLRect r;
	const S32 MENU_RIGHT = gMenuBarView->getRightmostMenuEdge();
	S32 x = MENU_RIGHT + MENU_PARCEL_SPACING;
	S32 y = 0;

	bool search_visible = gSavedSettings.getBOOL("ShowSearchBar");

	// reshape menu bar to its content's width
	if (MENU_RIGHT != gMenuBarView->getRect().getWidth())
	{
		gMenuBarView->reshape(MENU_RIGHT, gMenuBarView->getRect().getHeight());
	}

	LLViewerRegion *region = gAgent.getRegion();
	LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();

	LLRect buttonRect;

	if (LLHUDIcon::iconsNearby())
	{
		childGetRect( "scriptout", buttonRect );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect("scriptout",r);
		childSetVisible("scriptout", true);
		x += buttonRect.getWidth();
	}
	else
	{
		childSetVisible("scriptout", false);
	}

	if ((region && region->getAllowDamage()) ||
		(parcel && parcel->getAllowDamage()) )
	{
		// set visibility based on flashing
		if( mHealthTimer->hasExpired() )
		{
			childSetVisible("health", true);
		}
		else
		{
			BOOL flash = S32(mHealthTimer->getElapsedSeconds() * ICON_FLASH_FREQUENCY) & 1;
			childSetVisible("health", flash);
		}
		mTextHealth->setVisible(TRUE);

		// Health
		childGetRect( "health", buttonRect );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect("health", r);
		x += buttonRect.getWidth();

		const S32 health_width = S32( LLFontGL::getFontSansSerifSmall()->getWidth(std::string("100%")) );
		r.set(x, y+TEXT_HEIGHT - 2, x+health_width, y);
		mTextHealth->setRect(r);
		x += health_width;
	}
	else
	{
		// invisible if region doesn't allow damage
		childSetVisible("health", false);
		mTextHealth->setVisible(FALSE);
	}

	if ((region && region->getBlockFly()) ||
		(parcel && !parcel->getAllowFly()) )
	{
		// No Fly Zone
		childGetRect( "no_fly", buttonRect );
		childSetVisible( "no_fly", true );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect( "no_fly", r );
		x += buttonRect.getWidth();
	}
	else
	{
		// Fly Zone
		childSetVisible("no_fly", false);
	}

	BOOL no_build = parcel && !parcel->getAllowModify();
	if (no_build)
	{
		childSetVisible("no_build", TRUE);
		childGetRect( "no_build", buttonRect );
		// No Build Zone
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect( "no_build", r );
		x += buttonRect.getWidth();
	}
	else
	{
		childSetVisible("no_build", FALSE);
	}

	BOOL no_scripts = FALSE;
	if((region
		&& ((region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS)
		|| (region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS)))
		|| (parcel && !parcel->getAllowOtherScripts()))
	{
		no_scripts = TRUE;
	}
	if (no_scripts)
	{
		// No scripts
		childSetVisible("no_scripts", TRUE);
		childGetRect( "no_scripts", buttonRect );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect( "no_scripts", r );
		x += buttonRect.getWidth();
	}
	else
	{
		// Yes scripts
		childSetVisible("no_scripts", FALSE);
	}

	BOOL no_region_push = (region && region->getRestrictPushObject());
	BOOL no_push = no_region_push || (parcel && parcel->getRestrictPushObject());
	if (no_push)
	{
		childSetVisible("restrictpush", TRUE);
		childGetRect( "restrictpush", buttonRect );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect( "restrictpush", r );
		x += buttonRect.getWidth();
	}
	else
	{
		childSetVisible("restrictpush", FALSE);
	}

	BOOL have_voice = parcel && parcel->getParcelFlagAllowVoice(); 
	if (have_voice)
	{
		childSetVisible("status_no_voice", FALSE);
	}
	else
	{
		childSetVisible("status_no_voice", TRUE);
		childGetRect( "status_no_voice", buttonRect );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect( "status_no_voice", r );
		x += buttonRect.getWidth();
	}

	BOOL canBuyLand = parcel
		&& !parcel->isPublic()
		&& LLViewerParcelMgr::getInstance()->canAgentBuyParcel(parcel, false);
	childSetVisible("buyland", canBuyLand);
	if (canBuyLand)
	{
		//HACK: layout tweak until this is all xml
		x += 9;
		childGetRect( "buyland", buttonRect );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect( "buyland", r );
		x += buttonRect.getWidth();
	}

	std::string location_name;
	if (region)
	{
		const LLVector3& agent_pos_region = gAgent.getPositionAgent();
		S32 pos_x = lltrunc( agent_pos_region.mV[VX] );
		S32 pos_y = lltrunc( agent_pos_region.mV[VY] );
		S32 pos_z = lltrunc( agent_pos_region.mV[VZ] );

		// Round the numbers based on the velocity
		LLVector3 agent_velocity = gAgent.getVelocity();
		F32 velocity_mag_sq = agent_velocity.magVecSquared();

		const F32 FLY_CUTOFF = 6.f;		// meters/sec
		const F32 FLY_CUTOFF_SQ = FLY_CUTOFF * FLY_CUTOFF;
		const F32 WALK_CUTOFF = 1.5f;	// meters/sec
		const F32 WALK_CUTOFF_SQ = WALK_CUTOFF * WALK_CUTOFF;

		if (velocity_mag_sq > FLY_CUTOFF_SQ)
		{
			pos_x -= pos_x % 4;
			pos_y -= pos_y % 4;
		}
		else if (velocity_mag_sq > WALK_CUTOFF_SQ)
		{
			pos_x -= pos_x % 2;
			pos_y -= pos_y % 2;
		}

		mRegionDetails.mTime = mTextTime->getText();
		mRegionDetails.mBalance = mBalance;
		mRegionDetails.mAccessString = region->getSimAccessString();
		mRegionDetails.mPing = region->getNetDetailsForLCD();
		if (parcel)
		{
			location_name = region->getName()
				+ llformat(" %d, %d, %d (%s) - %s", 
						   pos_x, pos_y, pos_z,
						   region->getSimAccessString().c_str(),
						   parcel->getName().c_str());

			// keep these around for the LCD to use
			mRegionDetails.mRegionName = region->getName();
			mRegionDetails.mParcelName = parcel->getName();
			mRegionDetails.mX = pos_x;
			mRegionDetails.mY = pos_y;
			mRegionDetails.mZ = pos_z;

			mRegionDetails.mArea = parcel->getArea();
			mRegionDetails.mForSale = parcel->getForSale();
			mRegionDetails.mTraffic = LLViewerParcelMgr::getInstance()->getDwelling();
			
			if (parcel->isPublic())
			{
				mRegionDetails.mOwner = "Public";
			}
			else
			{
				if (parcel->getIsGroupOwned())
				{
					if(!parcel->getGroupID().isNull())
					{
						gCacheName->getGroupName(parcel->getGroupID(), mRegionDetails.mOwner);
					}
					else
					{
						mRegionDetails.mOwner = "Group Owned";
					}
				}
				else
				{
					// Figure out the owner's name
					gCacheName->getFullName(parcel->getOwnerID(), mRegionDetails.mOwner);
				}
			}
		}
		else
		{
			location_name = region->getName()
				+ llformat(" %d, %d, %d (%s)", 
						   pos_x, pos_y, pos_z,
						   region->getSimAccessString().c_str());
			// keep these around for the LCD to use
			mRegionDetails.mRegionName = region->getName();
			mRegionDetails.mParcelName = "Unknown";
			
			mRegionDetails.mX = pos_x;
			mRegionDetails.mY = pos_y;
			mRegionDetails.mZ = pos_z;
			mRegionDetails.mArea = 0;
			mRegionDetails.mForSale = FALSE;
			mRegionDetails.mOwner = "Unknown";
			mRegionDetails.mTraffic = 0.0f;
		}
	}
	else
	{
		// no region
		location_name = "(Unknown)";
		// keep these around for the LCD to use
		mRegionDetails.mRegionName = "Unknown";
		mRegionDetails.mParcelName = "Unknown";
		mRegionDetails.mAccessString = "Unknown";
		mRegionDetails.mX = 0;
		mRegionDetails.mY = 0;
		mRegionDetails.mZ = 0;
		mRegionDetails.mArea = 0;
		mRegionDetails.mForSale = FALSE;
		mRegionDetails.mOwner = "Unknown";
		mRegionDetails.mTraffic = 0.0f;
	}

// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | Modified: RLVa-1.0.0a
	if ( (region) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) )	// region == NULL if we loose our connection to the grid
	{
		// TODO-RLVa: find out whether the LCD code is still used because if so then we need to filter that as well
		location_name = llformat("%s (%s) - %s", 
			rlv_handler_t::cstrHiddenRegion.c_str(), region->getSimAccessString().c_str(), rlv_handler_t::cstrHidden.c_str());
	}
// [/RLVa:KB]

	mTextParcelName->setText(location_name);



	// x = right edge
	// loop through: stat graphs, search btn, search text editor, money, buy money, clock
	// adjust rect
	// finally adjust parcel name rect

	S32 new_right = getRect().getWidth();
	if (search_visible)
	{
		childGetRect("search_btn", r);
		//r.translate( new_right - r.mRight, 0);
		//childSetRect("search_btn", r);
		new_right -= r.getWidth();

		childGetRect("search_editor", r);
		//r.translate( new_right - r.mRight, 0);
		//childSetRect("search_editor", r);
		new_right -= r.getWidth() + 6;
	}
	else
	{
		childGetRect("stat_btn", r);
		r.translate( new_right - r.mRight, 0);
		childSetRect("stat_btn", r);
		new_right -= r.getWidth() + 6;
	}

	// Set rects of money, buy money, time
	childGetRect("BalanceText", r);
	r.translate( new_right - r.mRight, 0);
	childSetRect("BalanceText", r);
	new_right -= r.getWidth() - 18;

	childGetRect("buycurrency", r);
	r.translate( new_right - r.mRight, 0);
	childSetRect("buycurrency", r);
	new_right -= r.getWidth() + 6;

	childGetRect("TimeText", r);
	// mTextTime->getTextPixelWidth();
	r.translate( new_right - r.mRight, 0);
	childSetRect("TimeText", r);
	// new_right -= r.getWidth() + MENU_PARCEL_SPACING;


	// Adjust region name and parcel name
	x += 8;

	const S32 PARCEL_RIGHT =  llmin(mTextTime->getRect().mLeft, mTextParcelName->getTextPixelWidth() + x + 5);
	r.set(x+4, getRect().getHeight() - 2, PARCEL_RIGHT, 0);
	mTextParcelName->setRect(r);

	// Set search bar visibility
	childSetVisible("search_editor", search_visible);
	childSetVisible("search_btn", search_visible);
	childSetVisible("menubar_search_bevel_bg", search_visible);
	mSGBandwidth->setVisible(! search_visible);
	mSGPacketLoss->setVisible(! search_visible);
	childSetEnabled("stat_btn", ! search_visible);
}
Esempio n. 4
0
// Uses the last GL matrices set in set_perspective to project a point from
// the agent's region space to the nearest edge in screen coordinates.
// Returns TRUE if projection succeeds.
BOOL LLViewerCamera::projectPosAgentToScreenEdge(const LLVector3 &pos_agent,
												LLCoordGL &out_point) const
{
	LLVector3 dir_to_point = pos_agent - getOrigin();
	dir_to_point /= dir_to_point.magVec();

	BOOL in_front = TRUE;
	if (dir_to_point * getAtAxis() < 0.f)
	{
		in_front = FALSE;
	}

	GLdouble	x, y, z;			// object's window coords, GL-style
	if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY],
							  pos_agent.mV[VZ], gGLModelView,
							  gGLProjection, (GLint*)gGLViewport,
							  &x, &y, &z))
	{
		x /= gViewerWindow->getDisplayScale().mV[VX];
		y /= gViewerWindow->getDisplayScale().mV[VY];
		// should now have the x,y coords of grab_point in screen space
		const LLRect& window_rect = gViewerWindow->getVirtualWindowRect();

		// ...sanity check
		S32 int_x = lltrunc(x);
		S32 int_y = lltrunc(y);

		// find the center
		GLdouble center_x = (GLdouble)(0.5f * (window_rect.mLeft + window_rect.mRight));
		GLdouble center_y = (GLdouble)(0.5f * (window_rect.mBottom + window_rect.mTop));

		if (x == center_x  &&  y == center_y)
		{
			// can't project to edge from exact center
			return FALSE;
		}

		// find the line from center to local
		GLdouble line_x = x - center_x;
		GLdouble line_y = y - center_y;

		int_x = lltrunc(center_x);
		int_y = lltrunc(center_y);


		if (0.f == line_x)
		{
			// the slope of the line is undefined
			if (line_y > 0.f)
			{
				int_y = window_rect.mTop;
			}
			else
			{
				int_y = window_rect.mBottom;
			}
		}
		else if (0 == window_rect.getWidth())
		{
			// the diagonal slope of the view is undefined
			if (y < window_rect.mBottom)
			{
				int_y = window_rect.mBottom;
			}
			else if ( y > window_rect.mTop)
			{
				int_y = window_rect.mTop;
			}
		}
		else
		{
			F32 line_slope = (F32)(line_y / line_x);
			F32 rect_slope = ((F32)window_rect.getHeight()) / ((F32)window_rect.getWidth());

			if (fabs(line_slope) > rect_slope)
			{
				if (line_y < 0.f)
				{
					// bottom
					int_y = window_rect.mBottom;
				}
				else
				{
					// top
					int_y = window_rect.mTop;
				}
				int_x = lltrunc(((GLdouble)int_y - center_y) / line_slope + center_x);
			}
			else if (fabs(line_slope) < rect_slope)
			{
				if (line_x < 0.f)
				{
					// left
					int_x = window_rect.mLeft;
				}
				else
				{
					// right
					int_x = window_rect.mRight;
				}
				int_y = lltrunc(((GLdouble)int_x - center_x) * line_slope + center_y);
			}
			else
			{
				// exactly parallel ==> push to the corners
				if (line_x > 0.f)
				{
					int_x = window_rect.mRight;
				}
				else
				{
					int_x = window_rect.mLeft;
				}
				if (line_y > 0.0f)
				{
					int_y = window_rect.mTop;
				}
				else
				{
					int_y = window_rect.mBottom;
				}
			}
		}
		if (!in_front)
		{
			int_x = window_rect.mLeft + window_rect.mRight - int_x;
			int_y = window_rect.mBottom + window_rect.mTop - int_y;
		}
		out_point.mX = int_x;
		out_point.mY = int_y;
		return TRUE;
	}
	return FALSE;
}
Esempio n. 5
0
// Per-frame updates of visibility
void LLStatusBar::refresh()
{
	F32 bwtotal = gViewerThrottle.getMaxBandwidth() / 1000.f;
	mSGBandwidth->setMin(0.f);
	mSGBandwidth->setMax(bwtotal*1.25f);
	mSGBandwidth->setThreshold(0, bwtotal*0.75f);
	mSGBandwidth->setThreshold(1, bwtotal);
	mSGBandwidth->setThreshold(2, bwtotal);

	// Get current UTC time, adjusted for the user's clock
	// being off.
	U32 utc_time;
	utc_time = time_corrected();

	// There's only one internal tm buffer.
	struct tm* internal_time;

	// Convert to Pacific, based on server's opinion of whether
	// it's daylight savings time there.
	internal_time = utc_to_pacific_time(utc_time, gPacificDaylightTime);

	S32 hour = internal_time->tm_hour;
	S32 min  = internal_time->tm_min;

	std::string am_pm = "AM";
	if (hour > 11)
	{
		hour -= 12;
		am_pm = "PM";
	}

	std::string tz = "PST";
	if (gPacificDaylightTime)
	{
		tz = "PDT";
	}
	// Zero hour is 12 AM
	if (hour == 0) hour = 12;
	std::ostringstream t;
	t << std::setfill(' ') << std::setw(2) << hour << ":" 
	  << std::setfill('0') << std::setw(2) << min 
	  << " " << am_pm << " " << tz;
	mTextTime->setText(t.str().c_str());

	LLRect r;
	const S32 MENU_RIGHT = gMenuBarView->getRightmostMenuEdge();
	S32 x = MENU_RIGHT + MENU_PARCEL_SPACING;
	S32 y = 0;
	
	// reshape menu bar to its content's width
	if (MENU_RIGHT != gMenuBarView->getRect().getWidth())
	{
		gMenuBarView->reshape(MENU_RIGHT, gMenuBarView->getRect().getHeight());
	}

	LLViewerRegion *region = gAgent.getRegion();
	LLParcel *parcel = gParcelMgr->getAgentParcel();

	LLRect buttonRect;

	if (LLHUDIcon::iconsNearby())
	{
		childGetRect( "scriptout", buttonRect );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		mBtnScriptOut->setRect(r);
		mBtnScriptOut->setVisible(TRUE);
		x += buttonRect.getWidth();
	}
	else
	{
		mBtnScriptOut->setVisible(FALSE);
	}

	if ((region && region->getAllowDamage()) ||
		(parcel && parcel->getAllowDamage()) )
	{
		// set visibility based on flashing
		if( mHealthTimer->hasExpired() )
		{
			mBtnHealth->setVisible( TRUE );
		}
		else
		{
			BOOL flash = S32(mHealthTimer->getElapsedSeconds() * ICON_FLASH_FREQUENCY) & 1;
			mBtnHealth->setVisible( flash );
		}
		mTextHealth->setVisible(TRUE);

		// Health
		childGetRect( "health", buttonRect );
		r.setOriginAndSize( x, y-GRAPHIC_FUDGE, buttonRect.getWidth(), buttonRect.getHeight());
		mBtnHealth->setRect(r);
		x += buttonRect.getWidth();

		const S32 health_width = S32( LLFontGL::sSansSerifSmall->getWidth("100%") );
		r.set(x, y+TEXT_HEIGHT - 2, x+health_width, y);
		mTextHealth->setRect(r);
		x += health_width;
	}
	else
	{
		// invisible if region doesn't allow damage
		mBtnHealth->setVisible(FALSE);
		mTextHealth->setVisible(FALSE);
	}

	if ((region && region->getBlockFly()) ||
		(parcel && !parcel->getAllowFly()) )
	{
		// No Fly Zone
		childGetRect( "fly", buttonRect );
		mBtnFly->setVisible(TRUE);
		r.setOriginAndSize( x, y-GRAPHIC_FUDGE, buttonRect.getWidth(), buttonRect.getHeight());
		mBtnFly->setRect(r);
		x += buttonRect.getWidth();
	}
	else
	{
		mBtnFly->setVisible(FALSE);
	}

	BOOL no_build = parcel && !parcel->getAllowModify();
	mBtnBuild->setVisible( no_build );
	if (no_build)
	{
		childGetRect( "build", buttonRect );
		// No Build Zone
		r.setOriginAndSize( x, y-GRAPHIC_FUDGE, buttonRect.getWidth(), buttonRect.getHeight());
		mBtnBuild->setRect(r);
		x += buttonRect.getWidth();
	}

	BOOL no_scripts = FALSE;
	if((region
		&& ((region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS)
			|| (region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS)))
	   || (parcel && !parcel->getAllowOtherScripts()))
	{
		no_scripts = TRUE;
	}
	mBtnScripts->setVisible( no_scripts );
	if (no_scripts)
	{
		// No scripts
		childGetRect( "scripts", buttonRect );
		r.setOriginAndSize( x, y-GRAPHIC_FUDGE, buttonRect.getWidth(), buttonRect.getHeight());
		mBtnScripts->setRect(r);
		x += buttonRect.getWidth();
	}

	BOOL no_region_push = (region && region->getRestrictPushObject());
	BOOL no_push = no_region_push || (parcel && parcel->getRestrictPushObject());
	mBtnPush->setVisible( no_push );
	if (no_push)
	{
		childGetRect( "restrictpush", buttonRect );
		// No Push Zone
		r.setOriginAndSize( x, y-GRAPHIC_FUDGE, buttonRect.getWidth(), buttonRect.getHeight());
		mBtnPush->setRect(r);
		x += buttonRect.getWidth();
	}

	BOOL canBuyLand = parcel
		&& !parcel->isPublic()
		&& gParcelMgr->canAgentBuyParcel(parcel, false);
	mBtnBuyLand->setVisible(canBuyLand);
	if (canBuyLand)
	{
		childGetRect( "buyland", buttonRect );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		mBtnBuyLand->setRect(r);
		x += buttonRect.getWidth();
	}

	LLString location_name;
	if (region)
	{
		const LLVector3& agent_pos_region = gAgent.getPositionAgent();
		S32 pos_x = lltrunc( agent_pos_region.mV[VX] );
		S32 pos_y = lltrunc( agent_pos_region.mV[VY] );
		S32 pos_z = lltrunc( agent_pos_region.mV[VZ] );

		// Round the numbers based on the velocity
		LLVector3 agent_velocity = gAgent.getVelocity();
		F32 velocity_mag_sq = agent_velocity.magVecSquared();

		const F32 FLY_CUTOFF = 6.f;		// meters/sec
		const F32 FLY_CUTOFF_SQ = FLY_CUTOFF * FLY_CUTOFF;
		const F32 WALK_CUTOFF = 1.5f;	// meters/sec
		const F32 WALK_CUTOFF_SQ = WALK_CUTOFF * WALK_CUTOFF;

		if (velocity_mag_sq > FLY_CUTOFF_SQ)
		{
			pos_x -= pos_x % 4;
			pos_y -= pos_y % 4;
		}
		else if (velocity_mag_sq > WALK_CUTOFF_SQ)
		{
			pos_x -= pos_x % 2;
			pos_y -= pos_y % 2;
		}

		if (parcel && parcel->getName())
		{
			location_name = region->getName()
				+ llformat(" %d, %d, %d (%s) - %s", 
						   pos_x, pos_y, pos_z,
						   region->getSimAccessString(),
						   parcel->getName());
		}
		else
		{
			location_name = region->getName()
				+ llformat(" %d, %d, %d (%s)", 
						   pos_x, pos_y, pos_z,
						   region->getSimAccessString());
		}
	}
	else
	{
		// no region
		location_name = "(Unknown)";
	}
	mTextParcelName->setText(location_name);

	// Adjust region name and parcel name
	x += 4;

	const S32 PARCEL_RIGHT =  llmin(mTextTime->getRect().mLeft, mTextParcelName->getTextPixelWidth() + x + 5);
	r.set(x+4, mRect.getHeight() - 2, PARCEL_RIGHT, 0);
	mTextParcelName->setRect(r);
}
void LLSurfacePatch::updateVisibility()
{
	if (mVObjp.isNull())
	{
		return;
	}

	const F32 DEFAULT_DELTA_ANGLE 	= (0.15f);
	U32 old_render_stride, max_render_stride;
	U32 new_render_level;
	F32 stride_per_distance = DEFAULT_DELTA_ANGLE / mSurfacep->getMetersPerGrid();
	U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge();

	LLVector4a center;
	center.load3( (mCenterRegion + mSurfacep->getOriginAgent()).mV);
	LLVector4a radius;
	radius.splat(mRadius);

	// sphere in frustum on global coordinates
	if (LLViewerCamera::getInstance()->AABBInFrustumNoFarClip(center, radius))
	{
		// We now need to calculate the render stride based on patchp's distance 
		// from LLCamera render_stride is governed by a relation something like this...
		//
		//                       delta_angle * patch.distance
		// render_stride <=  ----------------------------------------
		//                           mMetersPerGrid
		//
		// where 'delta_angle' is the desired solid angle of the average polgon on a patch.
		//
		// Any render_stride smaller than the RHS would be 'satisfactory'.  Smaller 
		// strides give more resolution, but efficiency suggests that we use the largest 
		// of the render_strides that obey the relation.  Flexibility is achieved by 
		// modulating 'delta_angle' until we have an acceptable number of triangles.
	
		old_render_stride = mVisInfo.mRenderStride;

		// Calculate the render_stride using information in agent
		max_render_stride = lltrunc(mVisInfo.mDistance * stride_per_distance);
		max_render_stride = llmin(max_render_stride , 2*grids_per_patch_edge);

		// We only use render_strides that are powers of two, so we use look-up tables to figure out
		// the render_level and corresponding render_stride
		new_render_level = mVisInfo.mRenderLevel = mSurfacep->getRenderLevel(max_render_stride);
		mVisInfo.mRenderStride = mSurfacep->getRenderStride(new_render_level);

		if ((mVisInfo.mRenderStride != old_render_stride)) 
			// The reason we check !mbIsVisible is because non-visible patches normals 
			// are not updated when their data is changed.  When this changes we can get 
			// rid of mbIsVisible altogether.
		{
			if (mVObjp)
			{
				mVObjp->dirtyGeom();
				if (getNeighborPatch(WEST))
				{
					getNeighborPatch(WEST)->mVObjp->dirtyGeom();
				}
				if (getNeighborPatch(SOUTH))
				{
					getNeighborPatch(SOUTH)->mVObjp->dirtyGeom();
				}
			}
		}
		mVisInfo.mbIsVisible = TRUE;
	}
	else
	{
		mVisInfo.mbIsVisible = FALSE;
	}
}
Esempio n. 7
0
// Uses the last GL matrices set in set_perspective to project a point from
// the agent's region space to screen coordinates.  Returns TRUE if point in within
// the current window.
BOOL LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoordGL &out_point, const BOOL clamp) const
{
	BOOL in_front = TRUE;
	GLdouble	x, y, z;			// object's window coords, GL-style

	LLVector3 dir_to_point = pos_agent - getOrigin();
	dir_to_point /= dir_to_point.magVec();

	if (dir_to_point * getAtAxis() < 0.f)
	{
		if (clamp)
		{
			return FALSE;
		}
		else
		{
			in_front = FALSE;
		}
	}

	if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ],
								gGLModelView, gGLProjection, (GLint*)gGLViewport,
								&x, &y, &z))
	{
		// convert screen coordinates to virtual UI coordinates
		x /= gViewerWindow->getDisplayScale().mV[VX];
		y /= gViewerWindow->getDisplayScale().mV[VY];

		// should now have the x,y coords of grab_point in screen space
		const LLRect& window_rect = gViewerWindow->getWindowRect();

		// ...sanity check
		S32 int_x = lltrunc(x);
		S32 int_y = lltrunc(y);

		BOOL valid = TRUE;

		if (clamp)
		{
			if (int_x < window_rect.mLeft)
			{
				out_point.mX = window_rect.mLeft;
				valid = FALSE;
			}
			else if (int_x > window_rect.mRight)
			{
				out_point.mX = window_rect.mRight;
				valid = FALSE;
			}
			else
			{
				out_point.mX = int_x;
			}

			if (int_y < window_rect.mBottom)
			{
				out_point.mY = window_rect.mBottom;
				valid = FALSE;
			}
			else if (int_y > window_rect.mTop)
			{
				out_point.mY = window_rect.mTop;
				valid = FALSE;
			}
			else
			{
				out_point.mY = int_y;
			}
			return valid;
		}
		else
		{
			out_point.mX = int_x;
			out_point.mY = int_y;

			if (int_x < window_rect.mLeft)
			{
				valid = FALSE;
			}
			else if (int_x > window_rect.mRight)
			{
				valid = FALSE;
			}
			if (int_y < window_rect.mBottom)
			{
				valid = FALSE;
			}
			else if (int_y > window_rect.mTop)
			{
				valid = FALSE;
			}

			return in_front && valid;
		}
	}
	else
	{
		return FALSE;
	}
}
Esempio n. 8
0
inline long long lltrunc(__gmp_expr<T,U> const& x, const Policy& pol)
{
   return lltrunc(static_cast<mpfr_class>(x), pol);
}
void LLManip::renderTickValue(const LLVector3& pos, F32 value, const std::string& suffix, const LLColor4 &color)
{
	LLLocale locale(LLLocale::USER_LOCALE);

	const LLFontGL* big_fontp = LLFontGL::getFontSansSerif();
	const LLFontGL* small_fontp = LLFontGL::getFontSansSerifSmall();

	std::string val_string;
	std::string fraction_string;
	F32 val_to_print = ll_round(value, 0.001f);
	S32 fractional_portion = ll_round(fmodf(llabs(val_to_print), 1.f) * 100.f);
	if (val_to_print < 0.f)
	{
		if (fractional_portion == 0)
		{
			val_string = llformat("-%d%s", lltrunc(llabs(val_to_print)), suffix.c_str());
		}
		else
		{
			val_string = llformat("-%d", lltrunc(llabs(val_to_print)));
		}
	}
	else
	{
		if (fractional_portion == 0)
		{
			val_string = llformat("%d%s", lltrunc(llabs(val_to_print)), suffix.c_str());
		}
		else
		{
			val_string = llformat("%d", lltrunc(val_to_print));
		}
	}

	BOOL hud_selection = mObjectSelection->getSelectType() == SELECT_TYPE_HUD;
	gGL.matrixMode(LLRender::MM_MODELVIEW);
	gGL.pushMatrix();
	LLVector3 render_pos = pos;
	if (hud_selection)
	{
		F32 zoom_amt = gAgentCamera.mHUDCurZoom;
		F32 inv_zoom_amt = 1.f / zoom_amt;
		// scale text back up to counter-act zoom level
		render_pos = pos * zoom_amt;
		gGL.scalef(inv_zoom_amt, inv_zoom_amt, inv_zoom_amt);
	}

	LLColor4 shadow_color = LLColor4::black;
	shadow_color.mV[VALPHA] = color.mV[VALPHA] * 0.5f;

	if (fractional_portion != 0)
	{
		fraction_string = llformat("%c%02d%s", LLResMgr::getInstance()->getDecimalPoint(), fractional_portion, suffix.c_str());

		gViewerWindow->setup3DViewport(1, -1);
		hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -1.f * big_fontp->getWidthF32(val_string), 3.f, shadow_color, hud_selection);
		hud_render_utf8text(fraction_string, render_pos, *small_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, 1.f, 3.f, shadow_color, hud_selection);

		gViewerWindow->setup3DViewport();
		hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -1.f * big_fontp->getWidthF32(val_string), 3.f, color, hud_selection);
		hud_render_utf8text(fraction_string, render_pos, *small_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, 1.f, 3.f, color, hud_selection);
	}
	else
	{
		gViewerWindow->setup3DViewport(1, -1);
		hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(val_string), 3.f, shadow_color, hud_selection);
		gViewerWindow->setup3DViewport();
		hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(val_string), 3.f, color, hud_selection);
	}
	gGL.popMatrix();
}
Esempio n. 10
0
BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
									  const F32 width, const F32 height)
{
	llassert(mSurfacep);
	llassert(x >= 0.f);
	llassert(y >= 0.f);

	LLTimer gen_timer;

	///////////////////////////
	//
	// Generate raw data arrays for surface textures
	//
	//

	// These have already been validated by generateComposition.
	U8* st_data[4];
	S32 st_data_size[4]; // for debugging

	for (S32 i = 0; i < 4; i++)
	{
		if (mRawImages[i].isNull())
		{
			// Read back a raw image for this discard level, if it exists
			S32 min_dim = llmin(mDetailTextures[i]->getFullWidth(), mDetailTextures[i]->getFullHeight());
			S32 ddiscard = 0;
			while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL)
			{
				ddiscard++;
				min_dim /= 2;
			}
			BOOL delete_raw = (mDetailTextures[i]->reloadRawImage(ddiscard) != NULL);
			if (mDetailTextures[i]->getRawImageLevel() != ddiscard)	//raw iamge is not ready, will enter here again later.
			{
				if(delete_raw)
				{
					mDetailTextures[i]->destroyRawImage();
				}
				lldebugs << "cached raw data for terrain detail texture is not ready yet: " << mDetailTextures[i]->getID() << llendl;
				return FALSE;
			}

			mRawImages[i] = mDetailTextures[i]->getCachedRawImage();
			if (delete_raw)
			{
				mDetailTextures[i]->destroyRawImage();
			}
			if (mDetailTextures[i]->getWidth(ddiscard) != BASE_SIZE ||
				mDetailTextures[i]->getHeight(ddiscard) != BASE_SIZE ||
				mDetailTextures[i]->getComponents() != 3)
			{
				LLPointer<LLImageRaw> newraw = new LLImageRaw(BASE_SIZE, BASE_SIZE, 3);
				newraw->composite(mRawImages[i]);
				mRawImages[i] = newraw; // deletes old
			}
		}
		st_data[i] = mRawImages[i]->getData();
		st_data_size[i] = mRawImages[i]->getDataSize();
	}

	///////////////////////////////////////
	//
	// Generate and clamp x/y bounding box.
	//
	//

	S32 x_begin, y_begin, x_end, y_end;
	x_begin = (S32)(x * mScaleInv);
	y_begin = (S32)(y * mScaleInv);
	x_end = llround( (x + width) * mScaleInv );
	y_end = llround( (y + width) * mScaleInv );

	if (x_end > mWidth)
	{
		llwarns << "x end > width" << llendl;
		x_end = mWidth;
	}
	if (y_end > mWidth)
	{
		llwarns << "y end > width" << llendl;
		y_end = mWidth;
	}


	///////////////////////////////////////////
	//
	// Generate target texture information, stride ratios.
	//
	//

	LLViewerTexture *texturep;
	U32 tex_width, tex_height, tex_comps;
	U32 tex_stride;
	F32 tex_x_scalef, tex_y_scalef;
	S32 tex_x_begin, tex_y_begin, tex_x_end, tex_y_end;
	F32 tex_x_ratiof, tex_y_ratiof;

	texturep = mSurfacep->getSTexture();
	tex_width = texturep->getWidth();
	tex_height = texturep->getHeight();
	tex_comps = texturep->getComponents();
	tex_stride = tex_width * tex_comps;

	U32 st_comps = 3;
	U32 st_width = BASE_SIZE;
	U32 st_height = BASE_SIZE;
	
	if (tex_comps != st_comps)
	{
		llwarns << "Base texture comps != input texture comps" << llendl;
		return FALSE;
	}

	tex_x_scalef = (F32)tex_width / (F32)mWidth;
	tex_y_scalef = (F32)tex_height / (F32)mWidth;
	tex_x_begin = (S32)((F32)x_begin * tex_x_scalef);
	tex_y_begin = (S32)((F32)y_begin * tex_y_scalef);
	tex_x_end = (S32)((F32)x_end * tex_x_scalef);
	tex_y_end = (S32)((F32)y_end * tex_y_scalef);

	tex_x_ratiof = (F32)mWidth*mScale / (F32)tex_width;
	tex_y_ratiof = (F32)mWidth*mScale / (F32)tex_height;

	LLPointer<LLImageRaw> raw = new LLImageRaw(tex_width, tex_height, tex_comps);
	U8 *rawp = raw->getData();

	F32 tex_width_inv = 1.f/tex_width;
	F32 tex_height_inv = 1.f/tex_height;

	F32 st_x_stride, st_y_stride;
	st_x_stride = ((F32)st_width / (F32)mTexScaleX)*((F32)mWidth / (F32)tex_width);
	st_y_stride = ((F32)st_height / (F32)mTexScaleY)*((F32)mWidth / (F32)tex_height);

	llassert(st_x_stride > 0.f);
	llassert(st_y_stride > 0.f);
	////////////////////////////////
	//
	// Iterate through the target texture, striding through the
	// subtextures and interpolating appropriately.
	//
	//

	F32 sti, stj;
	S32 st_offset;
	sti = (tex_x_begin * st_x_stride) - st_width*(llfloor((tex_x_begin * st_x_stride)/st_width));
	stj = (tex_y_begin * st_y_stride) - st_height*(llfloor((tex_y_begin * st_y_stride)/st_height));

	st_offset = (llfloor(stj * st_width) + llfloor(sti)) * st_comps;
	for (S32 j = tex_y_begin; j < tex_y_end; j++)
	{
		U32 offset = j * tex_stride + tex_x_begin * tex_comps;
		sti = (tex_x_begin * st_x_stride) - st_width*((U32)(tex_x_begin * st_x_stride)/st_width);
		for (S32 i = tex_x_begin; i < tex_x_end; i++)
		{
			S32 tex0, tex1;
			F32 composition = getValueScaled(i*tex_x_ratiof, j*tex_y_ratiof);

			tex0 = llfloor( composition );
			tex0 = llclamp(tex0, 0, 3);
			composition -= tex0;
			tex1 = tex0 + 1;
			tex1 = llclamp(tex1, 0, 3);

			F32 xy_int_i, xy_int_j;

			xy_int_i = i * tex_width_inv;
			xy_int_j = j * tex_height_inv;

			st_offset = (lltrunc(sti) + lltrunc(stj)*st_width) * st_comps;
			for (U32 k = 0; k < tex_comps; k++)
			{
				// Linearly interpolate based on composition.
				if (st_offset >= st_data_size[tex0] || st_offset >= st_data_size[tex1])
				{
					// SJB: This shouldn't be happening, but does... Rounding error?
					//llwarns << "offset 0 [" << tex0 << "] =" << st_offset << " >= size=" << st_data_size[tex0] << llendl;
					//llwarns << "offset 1 [" << tex1 << "] =" << st_offset << " >= size=" << st_data_size[tex1] << llendl;
				}
				else
				{
					F32 a = *(st_data[tex0] + st_offset);
					F32 b = *(st_data[tex1] + st_offset);
					rawp[ offset ] = (U8)lltrunc( a + composition * (b - a) );
				}
				offset++;
				st_offset++;
			}

			sti += st_x_stride;
			if (sti >= st_width)
			{
				sti -= st_width;
			}
		}

		stj += st_y_stride;
		if (stj >= st_height)
		{
			stj -= st_height;
		}
	}

	if (!texturep->hasGLTexture())
	{
		texturep->createGLTexture(0, raw);
	}
	texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin);
	LLSurface::sTextureUpdateTime += gen_timer.getElapsedTimeF32();
	LLSurface::sTexelsUpdated += (tex_x_end - tex_x_begin) * (tex_y_end - tex_y_begin);

	for (S32 i = 0; i < 4; i++)
	{
		// Un-boost detatil textures (will get re-boosted if rendering in high detail)
		mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_NONE);
		mDetailTextures[i]->setMinDiscardLevel(MAX_DISCARD_LEVEL + 1);
	}
	
	return TRUE;
}
Esempio n. 11
0
inline mpfr_class modf(const mpfr_class& v, long long* ipart, const Policy& pol)
{
   *ipart = lltrunc(v, pol);
   return v - boost::math::tools::real_cast<mpfr_class>(*ipart);
}
Esempio n. 12
0
File: modf.hpp Progetto: 3DJ/ofxOgre
inline T modf(const T& v, boost::long_long_type* ipart, const Policy& pol)
{
   *ipart = lltrunc(v, pol);
   return v - *ipart;
}
Esempio n. 13
0
void LLTracker::drawMarker(const LLVector3d& pos_global, const LLColor4& color)
{
	// get position
	LLVector3 pos_local = gAgent.getPosAgentFromGlobal(pos_global);

	// check in frustum
	LLCoordGL screen;
	S32 x = 0;
	S32 y = 0;
	const BOOL CLAMP = TRUE;

	if (LLViewerCamera::getInstance()->projectPosAgentToScreen(pos_local, screen, CLAMP)
		|| LLViewerCamera::getInstance()->projectPosAgentToScreenEdge(pos_local, screen) )
	{
		gHUDView->screenPointToLocal(screen.mX, screen.mY, &x, &y);

		// the center of the rendered position of the arrow obeys 
		// the following rules:
		// (1) it lies on an ellipse centered on the target position 
		// (2) it lies on the line between the target and the window center
		// (3) right now the radii of the ellipse are fixed, but eventually
		//     they will be a function of the target text
		// 
		// from those rules we can compute the position of the 
		// lower left corner of the image
		LLRect rect = gHUDView->getRect();
		S32 x_center = lltrunc(0.5f * (F32)rect.getWidth());
		S32 y_center = lltrunc(0.5f * (F32)rect.getHeight());
		x = x - x_center;	// x and y relative to center
		y = y - y_center;
		F32 dist = sqrt((F32)(x*x + y*y));
		S32 half_arrow_size = lltrunc(0.5f * HUD_ARROW_SIZE);
		if (dist > 0.f)
		{
			const F32 ARROW_ELLIPSE_RADIUS_X = 2 * HUD_ARROW_SIZE;
			const F32 ARROW_ELLIPSE_RADIUS_Y = HUD_ARROW_SIZE;

			// compute where the arrow should be
			F32 x_target = (F32)(x + x_center) - (ARROW_ELLIPSE_RADIUS_X * ((F32)x / dist) );	
			F32 y_target = (F32)(y + y_center) - (ARROW_ELLIPSE_RADIUS_Y * ((F32)y / dist) );

			// keep the arrow within the window
			F32 x_clamped = llclamp( x_target, (F32)half_arrow_size, (F32)(rect.getWidth() - half_arrow_size));
			F32 y_clamped = llclamp( y_target, (F32)half_arrow_size, (F32)(rect.getHeight() - half_arrow_size));

			F32 slope = (F32)(y) / (F32)(x);
			F32 window_ratio = (F32)(rect.getHeight() - HUD_ARROW_SIZE) / (F32)(rect.getWidth() - HUD_ARROW_SIZE);

			// if the arrow has been clamped on one axis
			// then we need to compute the other axis
			if (llabs(slope) > window_ratio)
			{  
				if (y_clamped != (F32)y_target)
				{
					// clamp by y 
					x_clamped = (y_clamped - (F32)y_center) / slope + (F32)x_center;
				}
			}
			else if (x_clamped != (F32)x_target)
			{
				// clamp by x
				y_clamped = (x_clamped - (F32)x_center) * slope + (F32)y_center;
			}
			mHUDArrowCenterX = lltrunc(x_clamped);
			mHUDArrowCenterY = lltrunc(y_clamped);
		}
		else
		{
			// recycle the old values
			x = mHUDArrowCenterX - x_center;
			y = mHUDArrowCenterY - y_center;
		}

		F32 angle = atan2( (F32)y, (F32)x );

		gl_draw_scaled_rotated_image(mHUDArrowCenterX - half_arrow_size, 
									 mHUDArrowCenterY - half_arrow_size, 
									 HUD_ARROW_SIZE, HUD_ARROW_SIZE, 
									 RAD_TO_DEG * angle, 
									 LLWorldMapView::sTrackArrowImage->getImage(), 
									 color);
	}
}
// Per-frame updates of visibility
void LLStatusBar::refresh()
{
 	if(gDisconnected)
 		return; //or crash if the sim crashes; because: already ~LLMenuBarGL()

	// Adding Net Stat Meter back in
	F32 bwtotal = gViewerThrottle.getMaxBandwidth() / 1000.f;
	mSGBandwidth->setMin(0.f);
	mSGBandwidth->setMax(bwtotal*1.25f);
	mSGBandwidth->setThreshold(0, bwtotal*0.75f);
	mSGBandwidth->setThreshold(1, bwtotal);
	mSGBandwidth->setThreshold(2, bwtotal);

	// Let's not have to reformat time everywhere, shall we? -- MC
	gViewerTime->refresh();
	mTextTime->setText(gViewerTime->getCurTimeStr());
	mTextTime->setToolTip(gViewerTime->getCurDateStr());

	LLRect r;
	const S32 MENU_RIGHT = gMenuBarView->getRightmostMenuEdge();
	S32 x = MENU_RIGHT + MENU_PARCEL_SPACING;
	S32 y = 0;

	bool search_visible = gSavedSettings.getBOOL("ShowSearchBar");

	// reshape menu bar to its content's width
	if (MENU_RIGHT != gMenuBarView->getRect().getWidth())
	{
		gMenuBarView->reshape(MENU_RIGHT, gMenuBarView->getRect().getHeight());
	}

	LLViewerRegion *region = gAgent.getRegion();
	LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();

	LLRect buttonRect;

	if (LLHUDIcon::iconsNearby())
	{
		childGetRect( "scriptout", buttonRect );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect("scriptout",r);
		childSetVisible("scriptout", true);
		x += buttonRect.getWidth();
	}
	else
	{
		childSetVisible("scriptout", false);
	}

	if ((region && region->getAllowDamage()) ||
		(parcel && parcel->getAllowDamage()) )
	{
		// set visibility based on flashing
		if( mHealthTimer->hasExpired() )
		{
			childSetVisible("health", true);
		}
		else
		{
			BOOL flash = S32(mHealthTimer->getElapsedSeconds() * ICON_FLASH_FREQUENCY) & 1;
			childSetVisible("health", flash);
		}
		mTextHealth->setVisible(TRUE);

		// Health
		childGetRect( "health", buttonRect );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect("health", r);
		x += buttonRect.getWidth();

		const S32 health_width = S32( LLFontGL::getFontSansSerifSmall()->getWidth(std::string("100%")) );
		r.set(x, y+TEXT_HEIGHT - 2, x+health_width, y);
		mTextHealth->setRect(r);
		x += health_width;
	}
	else
	{
		// invisible if region doesn't allow damage
		childSetVisible("health", false);
		mTextHealth->setVisible(FALSE);
	}

	if ((region && region->getBlockFly()) ||
		(parcel && !parcel->getAllowFly()) )
	{
		// No Fly Zone
		childGetRect( "no_fly", buttonRect );
		childSetVisible( "no_fly", true );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect( "no_fly", r );
		x += buttonRect.getWidth();
	}
	else
	{
		// Fly Zone
		childSetVisible("no_fly", false);
	}

	BOOL no_build = parcel && !parcel->getAllowModify();
	if (no_build)
	{
		childSetVisible("no_build", TRUE);
		childGetRect( "no_build", buttonRect );
		// No Build Zone
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect( "no_build", r );
		x += buttonRect.getWidth();
	}
	else
	{
		childSetVisible("no_build", FALSE);
	}

	BOOL no_scripts = FALSE;
	if((region
		&& ((region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS)
		|| (region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS)))
		|| (parcel && !parcel->getAllowOtherScripts()))
	{
		no_scripts = TRUE;
	}
	if (no_scripts)
	{
		// No scripts
		childSetVisible("no_scripts", TRUE);
		childGetRect( "no_scripts", buttonRect );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect( "no_scripts", r );
		x += buttonRect.getWidth();
	}
	else
	{
		// Yes scripts
		childSetVisible("no_scripts", FALSE);
	}

	BOOL no_region_push = (region && region->getRestrictPushObject());
	BOOL no_push = no_region_push || (parcel && parcel->getRestrictPushObject());
	if (no_push)
	{
		childSetVisible("restrictpush", TRUE);
		childGetRect( "restrictpush", buttonRect );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect( "restrictpush", r );
		x += buttonRect.getWidth();
	}
	else
	{
		childSetVisible("restrictpush", FALSE);
	}

	BOOL have_voice = parcel && parcel->getParcelFlagAllowVoice(); 
	if (have_voice)
	{
		childSetVisible("status_no_voice", FALSE);
	}
	else
	{
		childSetVisible("status_no_voice", TRUE);
		childGetRect( "status_no_voice", buttonRect );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect( "status_no_voice", r );
		x += buttonRect.getWidth();
	}

	// TODO: disable buy land button when connected to non-SL grids
	// that don't support currency.
	// TODO: make this brandable -- MC
	BOOL canBuyLand = parcel
		&& !parcel->isPublic()
		&& LLViewerParcelMgr::getInstance()->canAgentBuyParcel(parcel, false);
	childSetVisible("buyland", canBuyLand);
	if (canBuyLand)
	{
		//HACK: layout tweak until this is all xml
		x += 9;
		childGetRect( "buyland", buttonRect );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect( "buyland", r );
		x += buttonRect.getWidth();
	}

	std::string location_name;
	if (region)
	{
		const LLVector3& agent_pos_region = gAgent.getPositionAgent();
		S32 pos_x = lltrunc( agent_pos_region.mV[VX] );
		S32 pos_y = lltrunc( agent_pos_region.mV[VY] );
		S32 pos_z = lltrunc( agent_pos_region.mV[VZ] );

		// Round the numbers based on the velocity
		LLVector3 agent_velocity = gAgent.getVelocity();
		F32 velocity_mag_sq = agent_velocity.magVecSquared();

		const F32 FLY_CUTOFF = 6.f;		// meters/sec
		const F32 FLY_CUTOFF_SQ = FLY_CUTOFF * FLY_CUTOFF;
		const F32 WALK_CUTOFF = 1.5f;	// meters/sec
		const F32 WALK_CUTOFF_SQ = WALK_CUTOFF * WALK_CUTOFF;

		if (velocity_mag_sq > FLY_CUTOFF_SQ)
		{
			pos_x -= pos_x % 4;
			pos_y -= pos_y % 4;
		}
		else if (velocity_mag_sq > WALK_CUTOFF_SQ)
		{
			pos_x -= pos_x % 2;
			pos_y -= pos_y % 2;
		}

		mRegionDetails.mTime = mTextTime->getText();
		mRegionDetails.mBalance = mBalance;
		mRegionDetails.mAccessString = region->getSimAccessString();
		mRegionDetails.mPing = region->getNetDetailsForLCD();
		if (parcel)
		{
			location_name = region->getName()
				+ llformat(" %d, %d, %d (%s) - %s", 
						   pos_x, pos_y, pos_z,
						   region->getSimAccessString().c_str(),
						   parcel->getName().c_str());

			// keep these around for the LCD to use
			mRegionDetails.mRegionName = region->getName();
			mRegionDetails.mParcelName = parcel->getName();
			mRegionDetails.mX = pos_x;
			mRegionDetails.mY = pos_y;
			mRegionDetails.mZ = pos_z;

			mRegionDetails.mArea = parcel->getArea();
			mRegionDetails.mForSale = parcel->getForSale();
			mRegionDetails.mTraffic = LLViewerParcelMgr::getInstance()->getDwelling();
			
			if (parcel->isPublic())
			{
				mRegionDetails.mOwner = "Public";
			}
			else
			{
				if (parcel->getIsGroupOwned())
				{
					if(!parcel->getGroupID().isNull())
					{
						gCacheName->getGroupName(parcel->getGroupID(), mRegionDetails.mOwner);
					}
					else
					{
						mRegionDetails.mOwner = "Group Owned";
					}
				}
				else
				{
					// Figure out the owner's name
					gCacheName->getFullName(parcel->getOwnerID(), mRegionDetails.mOwner);
				}
			}
		}
		else
		{
			location_name = region->getName()
				+ llformat(" %d, %d, %d (%s)", 
						   pos_x, pos_y, pos_z,
						   region->getSimAccessString().c_str());
			// keep these around for the LCD to use
			mRegionDetails.mRegionName = region->getName();
			mRegionDetails.mParcelName = "Unknown";
			
			mRegionDetails.mX = pos_x;
			mRegionDetails.mY = pos_y;
			mRegionDetails.mZ = pos_z;
			mRegionDetails.mArea = 0;
			mRegionDetails.mForSale = FALSE;
			mRegionDetails.mOwner = "Unknown";
			mRegionDetails.mTraffic = 0.0f;
		}
	}
	else
	{
		// no region
		location_name = "(Unknown)";
		// keep these around for the LCD to use
		mRegionDetails.mRegionName = "Unknown";
		mRegionDetails.mParcelName = "Unknown";
		mRegionDetails.mAccessString = "Unknown";
		mRegionDetails.mX = 0;
		mRegionDetails.mY = 0;
		mRegionDetails.mZ = 0;
		mRegionDetails.mArea = 0;
		mRegionDetails.mForSale = FALSE;
		mRegionDetails.mOwner = "Unknown";
		mRegionDetails.mTraffic = 0.0f;
	}

// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | Modified: RLVa-1.0.0a
	if ( (region) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) )	// region == NULL if we loose our connection to the grid
	{
		// TODO-RLVa: find out whether the LCD code is still used because if so then we need to filter that as well
		location_name = llformat("%s (%s) - %s", 
			RlvStrings::getString(RLV_STRING_HIDDEN_REGION).c_str(), region->getSimAccessString().c_str(),
			RlvStrings::getString(RLV_STRING_HIDDEN).c_str());
	}
// [/RLVa:KB]

	mTextParcelName->setText(location_name);



	// x = right edge
	// loop through: stat graphs, search btn, search text editor, money, buy money, clock
	// adjust rect
	// finally adjust parcel name rect

	S32 new_right = getRect().getWidth();
	if (search_visible)
	{
		childGetRect("search_btn", r);
		//r.translate( new_right - r.mRight, 0);
		//childSetRect("search_btn", r);
		new_right -= r.getWidth();

		childGetRect("search_editor", r);
		//r.translate( new_right - r.mRight, 0);
		//childSetRect("search_editor", r);
		new_right -= r.getWidth() + 6;
	}
	else
	{
		childGetRect("stat_btn", r);
		r.translate( new_right - r.mRight, 0);
		childSetRect("stat_btn", r);
		new_right -= r.getWidth() + 6;
	}

	// Set rects of money, buy money, time
	childGetRect("BalanceText", r);
	r.translate( new_right - r.mRight, 0);
	childSetRect("BalanceText", r);
	new_right -= r.getWidth() - 2;

	childGetRect("buycurrency", r);
	r.translate( new_right - r.mRight, 0);
	childSetRect("buycurrency", r);
	new_right -= r.getWidth() + 6;

	// Don't toggle this visibility while in mouselook -- MC
	if (!gAgent.cameraMouselook())
	{
		// Set search bar visibility
		childSetVisible("search_editor", search_visible);
		childSetVisible("search_btn", search_visible);
		childSetVisible("menubar_search_bevel_bg", search_visible);
		mSGBandwidth->setVisible(! search_visible);
		mSGPacketLoss->setVisible(! search_visible);
		childSetEnabled("stat_btn", ! search_visible);
	}

	childGetRect("TimeText", r);
	// mTextTime->getTextPixelWidth();
	r.translate( new_right - r.mRight, 0);
	childSetRect("TimeText", r);
	// new_right -= r.getWidth() + MENU_PARCEL_SPACING;


	// Adjust region name and parcel name
	x += 8;

	const S32 PARCEL_RIGHT =  llmin(mTextTime->getRect().mLeft, mTextParcelName->getTextPixelWidth() + x + 5);
	r.set(x+4, getRect().getHeight() - 2, PARCEL_RIGHT, 0);
	mTextParcelName->setRect(r);
}
Esempio n. 15
0
inline mpfr::mpreal modf(const mpfr::mpreal& v, long long* ipart, const Policy& pol)
{
   *ipart = lltrunc(v, pol);
   return v - lslboost::math::tools::real_cast<mpfr::mpreal>(*ipart);
}
Esempio n. 16
0
// Per-frame updates of visibility
void LLStatusBar::refresh()
{
	if(gDisconnected)
	return; //or crash if the sim crashes; because: already ~LLMenuBarGL()

	// Adding Net Stat Meter back in
	F32 bwtotal = gViewerThrottle.getMaxBandwidth() / 1000.f;
	mSGBandwidth->setMin(0.f);
	mSGBandwidth->setMax(bwtotal*1.25f);
	mSGBandwidth->setThreshold(0, bwtotal*0.75f);
	mSGBandwidth->setThreshold(1, bwtotal);
	mSGBandwidth->setThreshold(2, bwtotal);

	// *TODO: Localize / translate time

	// Get current UTC time, adjusted for the user's clock
	// being off.
	time_t utc_time;
	utc_time = time_corrected();

	// There's only one internal tm buffer.
	struct tm* internal_time;

	// Convert to Pacific, based on server's opinion of whether
	// it's daylight savings time there.
	internal_time = utc_to_pacific_time(utc_time, gPacificDaylightTime);

	std::string t;
	timeStructToFormattedString(internal_time, gSavedSettings.getString("ShortTimeFormat"), t);
	if (gPacificDaylightTime)
	{
		t += " PDT";
	}
	else
	{
		t += " PST";
	}
	mTextTime->setText(t);

	std::string date;
	timeStructToFormattedString(internal_time, gSavedSettings.getString("LongDateFormat"), date);
	mTextTime->setToolTip(date);

	LLRect r;
	const S32 MENU_RIGHT = gMenuBarView->getRightmostMenuEdge();
	S32 x = MENU_RIGHT + MENU_PARCEL_SPACING;
	S32 y = 0;

	bool search_visible = gSavedSettings.getBOOL("ShowSearchBar");

	// reshape menu bar to its content's width
	if (MENU_RIGHT != gMenuBarView->getRect().getWidth())
	{
		gMenuBarView->reshape(MENU_RIGHT, gMenuBarView->getRect().getHeight());
	}

	LLViewerRegion *region = gAgent.getRegion();
	LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();

	LLRect buttonRect;

	if (LLHUDIcon::iconsNearby())
	{
		childGetRect( "scriptout", buttonRect );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect("scriptout",r);
		childSetVisible("scriptout", true);
		x += buttonRect.getWidth();
	}
	else
	{
		childSetVisible("scriptout", false);
	}

	if ((region && region->getAllowDamage()) ||
		(parcel && parcel->getAllowDamage()) )
	{
		// set visibility based on flashing
		if( mHealthTimer->hasExpired() )
		{
			childSetVisible("health", true);
		}
		else
		{
			BOOL flash = S32(mHealthTimer->getElapsedSeconds() * ICON_FLASH_FREQUENCY) & 1;
			childSetVisible("health", flash);
		}
		mTextHealth->setVisible(TRUE);

		// Health
		childGetRect( "health", buttonRect );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect("health", r);
		x += buttonRect.getWidth();

		const S32 health_width = S32( LLFontGL::getFontSansSerifSmall()->getWidth(std::string("100%")) );
		r.set(x, y+TEXT_HEIGHT - 2, x+health_width, y);
		mTextHealth->setRect(r);
		x += health_width;
	}
	else
	{
		// invisible if region doesn't allow damage
		childSetVisible("health", false);
		mTextHealth->setVisible(FALSE);
	}

	if ((region && region->getBlockFly()) ||
		(parcel && !parcel->getAllowFly()) )
	{
		// No Fly Zone
		childGetRect( "no_fly", buttonRect );
		childSetVisible( "no_fly", true );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect( "no_fly", r );
		x += buttonRect.getWidth();
	}
	else
	{
		// Fly Zone
		childSetVisible("no_fly", false);
	}

	BOOL no_build = parcel && !parcel->getAllowModify();
	if (no_build)
	{
		childSetVisible("no_build", TRUE);
		childGetRect( "no_build", buttonRect );
		// No Build Zone
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect( "no_build", r );
		x += buttonRect.getWidth();
	}
	else
	{
		childSetVisible("no_build", FALSE);
	}

	BOOL no_scripts = FALSE;
	if((region
		&& (region->getRegionFlag(REGION_FLAGS_SKIP_SCRIPTS)
		|| region->getRegionFlag(REGION_FLAGS_ESTATE_SKIP_SCRIPTS)))
		|| (parcel && !parcel->getAllowOtherScripts()))
	{
		no_scripts = TRUE;
	}
	if (no_scripts)
	{
		// No scripts
		childSetVisible("no_scripts", TRUE);
		childGetRect( "no_scripts", buttonRect );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect( "no_scripts", r );
		x += buttonRect.getWidth();
	}
	else
	{
		// Yes scripts
		childSetVisible("no_scripts", FALSE);
	}

	BOOL no_region_push = (region && region->getRestrictPushObject());
	BOOL no_push = no_region_push || (parcel && parcel->getRestrictPushObject());
	if (no_push)
	{
		childSetVisible("restrictpush", TRUE);
		childGetRect( "restrictpush", buttonRect );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect( "restrictpush", r );
		x += buttonRect.getWidth();
	}
	else
	{
		childSetVisible("restrictpush", FALSE);
	}

	BOOL have_voice = parcel && parcel->getParcelFlagAllowVoice(); 
	if (have_voice)
	{
		childSetVisible("status_no_voice", FALSE);
	}
	else
	{
		childSetVisible("status_no_voice", TRUE);
		childGetRect( "status_no_voice", buttonRect );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect( "status_no_voice", r );
		x += buttonRect.getWidth();
	}

	bool no_see_avs = parcel && !parcel->getSeeAVs();
	childSetVisible("status_SeeAV", no_see_avs);
	if (no_see_avs)
	{
		childGetRect( "status_SeeAV", buttonRect );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect( "status_SeeAV", r );
		x += buttonRect.getWidth();
	}

	BOOL canBuyLand = parcel
		&& !parcel->isPublic()
		&& LLViewerParcelMgr::getInstance()->canAgentBuyParcel(parcel, false);
	childSetVisible("buyland", canBuyLand);
	if (canBuyLand)
	{
		//HACK: layout tweak until this is all xml
		x += 9;
		childGetRect( "buyland", buttonRect );
		r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
		childSetRect( "buyland", r );
		x += buttonRect.getWidth();
	}

	std::string location_name;
	if (region)
	{
		const LLVector3& agent_pos_region = gAgent.getPositionAgent();
		S32 pos_x = lltrunc( agent_pos_region.mV[VX] );
		S32 pos_y = lltrunc( agent_pos_region.mV[VY] );
		S32 pos_z = lltrunc( agent_pos_region.mV[VZ] );

		// Round the numbers based on the velocity
		LLVector3 agent_velocity = gAgent.getVelocity();
		F32 velocity_mag_sq = agent_velocity.magVecSquared();

		const F32 FLY_CUTOFF = 6.f;		// meters/sec
		const F32 FLY_CUTOFF_SQ = FLY_CUTOFF * FLY_CUTOFF;
		const F32 WALK_CUTOFF = 1.5f;	// meters/sec
		const F32 WALK_CUTOFF_SQ = WALK_CUTOFF * WALK_CUTOFF;

		if (velocity_mag_sq > FLY_CUTOFF_SQ)
		{
			pos_x -= pos_x % 4;
			pos_y -= pos_y % 4;
		}
		else if (velocity_mag_sq > WALK_CUTOFF_SQ)
		{
			pos_x -= pos_x % 2;
			pos_y -= pos_y % 2;
		}

		if (parcel)
		{
			if (!LLAgentUI::buildLocationString(location_name, LLAgentUI::LOCATION_FORMAT_FULL)) 
			{
				location_name = "???";
			}
		}
		else
		{
			location_name = region->getName()
				+ llformat(" %d, %d, %d (%s)", 
						   pos_x, pos_y, pos_z,
						   region->getSimAccessString().c_str());
		}
		static LLCachedControl<bool> show_channel("ShowSimChannel");
		if (show_channel && !gLastVersionChannel.empty()) location_name += " - " + gLastVersionChannel;
	}
	else
	{
		// no region
		location_name = "(Unknown)";
	}

// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | Modified: RLVa-1.0.0a
	if ( (region) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) )	// region == NULL if we lose our connection to the grid
	{
		location_name = llformat("%s (%s) - %s", 
			RlvStrings::getString(RLV_STRING_HIDDEN_REGION).c_str(), region->getSimAccessString().c_str(), 
			RlvStrings::getString(RLV_STRING_HIDDEN).c_str());
	}
// [/RLVa:KB]

	mTextParcelName->setText(location_name);



	// x = right edge
	// loop through: stat graphs, search btn, search text editor, money, buy money, clock
	// adjust rect
	// finally adjust parcel name rect

	S32 new_right = getRect().getWidth();
	if (search_visible)
	{
		childGetRect("search_btn", r);
		//r.translate( new_right - r.mRight, 0);
		//childSetRect("search_btn", r);
		new_right -= r.getWidth();

		childGetRect("search_editor", r);
		//r.translate( new_right - r.mRight, 0);
		//childSetRect("search_editor", r);
		new_right -= r.getWidth() + 6;
	}
	else
	{
		childGetRect("stat_btn", r);
		r.translate( new_right - r.mRight, 0);
		childSetRect("stat_btn", r);
		new_right -= r.getWidth() + 6;
	}

	// Set rects of money, buy money, time
	childGetRect("BalanceText", r);
	r.translate( new_right - r.mRight, 0);
	childSetRect("BalanceText", r);
	new_right -= r.getWidth() - 18;

	childGetRect("buycurrency", r);
	r.translate( new_right - r.mRight, 0);
	childSetRect("buycurrency", r);
	new_right -= r.getWidth() + 6;

	childGetRect("TimeText", r);
	// mTextTime->getTextPixelWidth();
	r.translate( new_right - r.mRight, 0);
	childSetRect("TimeText", r);
	// new_right -= r.getWidth() + MENU_PARCEL_SPACING;


	// Adjust region name and parcel name
	x += 8;

	const S32 PARCEL_RIGHT =  llmin(mTextTime->getRect().mLeft, mTextParcelName->getTextPixelWidth() + x + 5);
	r.set(x+4, getRect().getHeight() - 2, PARCEL_RIGHT, 0);
	mTextParcelName->setRect(r);

	// Set search bar visibility
	childSetVisible("search_editor", search_visible);
	childSetVisible("search_btn", search_visible);
	childSetVisible("menubar_search_bevel_bg", search_visible);
	mSGBandwidth->setVisible(! search_visible);
	mSGPacketLoss->setVisible(! search_visible);
	childSetEnabled("stat_btn", ! search_visible);
}