void LLLocalSpeakerMgr::updateSpeakerList()
{
	// pull speakers from voice channel
	LLSpeakerMgr::updateSpeakerList();

	if (gDisconnected)//the world is cleared.
	{
		return ;
	}

	// pick up non-voice speakers in chat range
	uuid_vec_t avatar_ids;
	std::vector<LLVector3d> positions;
	LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, gAgent.getPositionGlobal(), CHAT_NORMAL_RADIUS);
	for(U32 i=0; i<avatar_ids.size(); i++)
	{
		setSpeaker(avatar_ids[i]);
	}

	// check if text only speakers have moved out of chat range
	for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end(); ++speaker_it)
	{
		LLUUID speaker_id = speaker_it->first;
		LLSpeaker* speakerp = speaker_it->second;
		if (speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY)
		{
			LLVOAvatar* avatarp = (LLVOAvatar*)gObjectList.findObject(speaker_id);
			if (!avatarp || dist_vec_squared(avatarp->getPositionAgent(), gAgent.getPositionAgent()) > CHAT_NORMAL_RADIUS_SQUARED)
			{
				setSpeakerNotInChannel(speakerp);
			}
		}
	}
}
Beispiel #2
0
//-----------------------------------------------------------------------------
// setLookAt()
// called by agent logic to set look at behavior locally, and propagate to sim
//-----------------------------------------------------------------------------
BOOL LLHUDEffectLookAt::setLookAt(ELookAtType target_type, LLViewerObject *object, LLVector3 position)
{
	if (!mSourceObject)
	{
		return FALSE;
	}
	
	if (target_type >= LOOKAT_NUM_TARGETS)
	{
		llwarns << "Bad target_type " << (int)target_type << " - ignoring." << llendl;
		return FALSE;
	}

	// must be same or higher priority than existing effect
	if ((*mAttentions)[target_type].mPriority < (*mAttentions)[mTargetType].mPriority)
	{
		return FALSE;
	}

	F32 current_time  = mTimer.getElapsedTimeF32();

	// type of lookat behavior or target object has changed
	BOOL lookAtChanged = (target_type != mTargetType) || (object != mTargetObject);

	// lookat position has moved a certain amount and we haven't just sent an update
	lookAtChanged = lookAtChanged || ((dist_vec_squared(position, mLastSentOffsetGlobal) > MIN_DELTAPOS_FOR_UPDATE_SQUARED) && 
		((current_time - mLastSendTime) > (1.f / MAX_SENDS_PER_SEC)));

	if (lookAtChanged)
	{
		mLastSentOffsetGlobal = position;
		F32 timeout = (*mAttentions)[target_type].mTimeout;
		setDuration(timeout);
		setNeedsSendToSim(TRUE);
	}
 
	if (target_type == LOOKAT_TARGET_CLEAR)
	{
		clearLookAtTarget();
	}
	else
	{
		mTargetType = target_type;
		mTargetObject = object;
		if (object)
		{
			mTargetOffsetGlobal.setVec(position);
		}
		else
		{
			mTargetOffsetGlobal = gAgent.getPosGlobalFromAgent(position);
		}
		mKillTime = mTimer.getElapsedTimeF32() + mDuration;

		update();
	}
	return TRUE;
}
Beispiel #3
0
BOOL LLToolGrab::handleHover(S32 x, S32 y, MASK mask)
{
	if (!gViewerWindow->getLeftMouseDown())
	{
		gViewerWindow->setCursor(UI_CURSOR_TOOLGRAB);
		setMouseCapture(FALSE);
		return TRUE;
	}

// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-0.2.0f
	// Don't allow dragging beyond 1.5m under @fartouch=n
	LLViewerObject* pObj;
	if ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && (GRAB_INACTIVE != mMode) && (hasMouseCapture()) &&
		 ((pObj = mGrabPick.getObject()) != NULL) && (!pObj->isDead()) && (!pObj->isHUDAttachment()) && 
		 (dist_vec_squared(gAgent.getPositionAgent(), pObj->getPositionRegion() + mGrabPick.mObjectOffset) > 1.5f * 1.5f) )
	{
		if (gGrabTransientTool)
		{
			// Prevent the grab tool from popping up as soon as we kill the drag operation
			gBasicToolset->selectTool(gGrabTransientTool);
			gGrabTransientTool = NULL;
		}
		setMouseCapture(FALSE);
	}
// [/RLVa:KB]

	// Do the right hover based on mode
	switch( mMode )
	{
	case GRAB_ACTIVE_CENTER:
		handleHoverActive( x, y, mask );	// cursor hidden
		break;
		
	case GRAB_NONPHYSICAL:
		handleHoverNonPhysical(x, y, mask);
		break;

	case GRAB_INACTIVE:
		handleHoverInactive( x, y, mask );  // cursor set here
		break;

	case GRAB_NOOBJECT:
	case GRAB_LOCKED:
		handleHoverFailed( x, y, mask );
		break;

	}

	mLastMouseX = x;
	mLastMouseY = y;
	
	return TRUE;
}
Beispiel #4
0
	void v4math_object::test<19>()
	{
		F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 1.f, z2 = 1.f;
		F32 val1,val2;
		LLVector4 vec4(x1,y1,z1),vec4a(x2,y2,z2);
		val1 = dist_vec(vec4,vec4a);
		val2 = fsqrtf((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2));
		ensure_equals("dist_vec: Fail ",val2, val1);
		val1 = dist_vec_squared(vec4,vec4a);
		val2 =((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2));
		ensure_equals("dist_vec_squared: Fail ",val2, val1);
	}
Beispiel #5
0
	void v3math_object::test<31>()
	{
		F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 1.f, z2 = 1.f;
		F32 val1,val2;
		LLVector3 vec3(x1,y1,z1),vec3a(x2,y2,z2);
		val1 = dist_vec(vec3,vec3a);
		val2 = fsqrtf((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2));
		ensure_equals("1:dist_vec: Fail ",val2, val1);
		val1 = dist_vec_squared(vec3,vec3a);
		val2 =((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2));
		ensure_equals("2:dist_vec_squared: Fail ",val2, val1);
		val1 = dist_vec_squared2D(vec3, vec3a);
		val2 =(x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2);
		ensure_equals("3:dist_vec_squared2D: Fail ",val2, val1);
	}
Beispiel #6
0
	void v2math_object::test<21>()
	{
		F32 x1 =1.f, y1 = 2.f, x2 = -.32f, y2 = .2234f;
		F32 val1, val2;
		LLVector2 vec2(x1, y1),vec3(x2, y2);		
		val1 = dist_vec_squared2D(vec2, vec3);
		val2 = (x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2);
		ensure_equals("dist_vec_squared2D values are not equal",val2, val1);

		val1 = dist_vec_squared(vec2, vec3);
		ensure_equals("dist_vec_squared values are not equal",val2, val1);

		val1 = 	dist_vec(vec2, vec3);
		val2 = fsqrtf((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2));
		ensure_equals("dist_vec values are not equal",val2, val1);
	}
Beispiel #7
0
void LLToolFace::pickCallback(const LLPickInfo& pick_info)
{
	LLViewerObject* hit_obj	= pick_info.getObject();
	if (hit_obj)
	{
		S32 hit_face = pick_info.mObjectFace;
		
		if (hit_obj->isAvatar())
		{
			// ...clicked on an avatar, so don't do anything
			return;
		}

// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0f
		if ( (rlv_handler_t::isEnabled()) &&
			 ( (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) || 
			   ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && ((!hit_obj->isAttachment()) || (!hit_obj->permYouOwner())) && 
			     (dist_vec_squared(gAgent.getPositionAgent(), hit_obj->getPositionRegion() + pick_info.mObjectOffset) > 1.5f * 1.5f) )))
		{
			return;
		}
// [/RLVa:KB]

		// ...clicked on a world object, try to pick the appropriate face

		if (pick_info.mKeyMask & MASK_SHIFT)
		{
			// If object not selected, need to inform sim
			if ( !hit_obj->isSelected() )
			{
				// object wasn't selected so add the object and face
				LLSelectMgr::getInstance()->selectObjectOnly(hit_obj, hit_face);
			}
			else if (!LLSelectMgr::getInstance()->getSelection()->contains(hit_obj, hit_face) )
			{
				// object is selected, but not this face, so add it.
				LLSelectMgr::getInstance()->addAsIndividual(hit_obj, hit_face);
			}
			else
			{
				// object is selected, as is this face, so remove the face.
				LLSelectMgr::getInstance()->remove(hit_obj, hit_face);

				// BUG: If you remove the last face, the simulator won't know about it.
			}
		}
		else
		{
			// clicked without modifiers, select only
			// this face
			LLSelectMgr::getInstance()->deselectAll();
			LLSelectMgr::getInstance()->selectObjectOnly(hit_obj, hit_face);
		}
	}
	else
	{
		if (!(pick_info.mKeyMask == MASK_SHIFT))
		{
			LLSelectMgr::getInstance()->deselectAll();
		}
	}
}
// Returns true if you got at least one object
void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
{
// [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c
	// Block rectangle selection if:
	//   - prevented from editing and no exceptions are set (see below for the case where exceptions are set)
	//   - prevented from interacting at all
	if ( (rlv_handler_t::isEnabled()) && 
		 ( ((gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) && (!gRlvHandler.hasException(RLV_BHVR_EDIT))) || 
		   (gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT)) ) )
	{
		return;
	}
// [/RLVa:KB]

	LLVector3 av_pos = gAgent.getPositionAgent();
	F32 select_dist_squared = gSavedSettings.getF32("MaxSelectDistance");
	select_dist_squared = select_dist_squared * select_dist_squared;

	BOOL deselect = (mask == MASK_CONTROL);
	S32 left =	llmin(x, mDragStartX);
	S32 right =	llmax(x, mDragStartX);
	S32 top =	llmax(y, mDragStartY);
	S32 bottom =llmin(y, mDragStartY);

	left = llround((F32) left * LLUI::getScaleFactor().mV[VX]);
	right = llround((F32) right * LLUI::getScaleFactor().mV[VX]);
	top = llround((F32) top * LLUI::getScaleFactor().mV[VY]);
	bottom = llround((F32) bottom * LLUI::getScaleFactor().mV[VY]);

	F32 old_far_plane = LLViewerCamera::getInstance()->getFar();
	F32 old_near_plane = LLViewerCamera::getInstance()->getNear();

	S32 width = right - left + 1;
	S32 height = top - bottom + 1;

	BOOL grow_selection = FALSE;
	BOOL shrink_selection = FALSE;

	if (height > mDragLastHeight || width > mDragLastWidth)
	{
		grow_selection = TRUE;
	}
	if (height < mDragLastHeight || width < mDragLastWidth)
	{
		shrink_selection = TRUE;
	}

	if (!grow_selection && !shrink_selection)
	{
		// nothing to do
		return;
	}

	mDragLastHeight = height;
	mDragLastWidth = width;

	S32 center_x = (left + right) / 2;
	S32 center_y = (top + bottom) / 2;

	// save drawing mode
	gGL.matrixMode(LLRender::MM_PROJECTION);
	gGL.pushMatrix();

	BOOL limit_select_distance = gSavedSettings.getBOOL("LimitSelectDistance");
	if (limit_select_distance)
	{
		// ...select distance from control
		LLVector3 relative_av_pos = av_pos;
		relative_av_pos -= LLViewerCamera::getInstance()->getOrigin();

		F32 new_far = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() + gSavedSettings.getF32("MaxSelectDistance");
		F32 new_near = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() - gSavedSettings.getF32("MaxSelectDistance");

		new_near = llmax(new_near, 0.1f);

		LLViewerCamera::getInstance()->setFar(new_far);
		LLViewerCamera::getInstance()->setNear(new_near);
	}
// [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e) | Modified: RLVa-1.0.0g
	if (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH))
	{
		// We'll allow drag selection under fartouch, but only within the fartouch range
		// (just copy/paste the code above us to make that work, thank you Lindens!)
		LLVector3 relative_av_pos = av_pos;
		relative_av_pos -= LLViewerCamera::getInstance()->getOrigin();

		F32 new_far = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() + 1.5f;
		F32 new_near = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() - 1.5f;

		new_near = llmax(new_near, 0.1f);

		LLViewerCamera::getInstance()->setFar(new_far);
		LLViewerCamera::getInstance()->setNear(new_near);

		// Usurp these two
		limit_select_distance = TRUE;
		select_dist_squared = 1.5f * 1.5f;
	}
// [/RLVa:KB]
	LLViewerCamera::getInstance()->setPerspective(FOR_SELECTION, 
							center_x-width/2, center_y-height/2, width, height, 
							limit_select_distance);

	if (shrink_selection)
	{
		struct f : public LLSelectedObjectFunctor
		{
			virtual bool apply(LLViewerObject* vobjp)
			{
				LLDrawable* drawable = vobjp->mDrawable;
				if (!drawable || vobjp->getPCode() != LL_PCODE_VOLUME || vobjp->isAttachment())
				{
					return true;
				}
				S32 result = LLViewerCamera::getInstance()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius());
				switch (result)
				{
				  case 0:
					LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp);
					break;
				  case 1:
					// check vertices
					if (!LLViewerCamera::getInstance()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive))
					{
						LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp);
					}
					break;
				  default:
					break;
				}
				return true;
			}
		} func;
		LLSelectMgr::getInstance()->getHighlightedObjects()->applyToObjects(&func);
	}

	if (grow_selection)
	{
		std::vector<LLDrawable*> potentials;
				
		for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
			iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
		{
			LLViewerRegion* region = *iter;
			for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
			{
				LLSpatialPartition* part = region->getSpatialPartition(i);
				if (part)
				{	
					part->cull(*LLViewerCamera::getInstance(), &potentials, TRUE);
				}
			}
		}
		
		for (std::vector<LLDrawable*>::iterator iter = potentials.begin();
			 iter != potentials.end(); iter++)
		{
			LLDrawable* drawable = *iter;
			LLViewerObject* vobjp = drawable->getVObj();

			if (!drawable || !vobjp ||
				vobjp->getPCode() != LL_PCODE_VOLUME || 
				vobjp->isAttachment() ||
				(deselect && !vobjp->isSelected()))
			{
				continue;
			}

			if (limit_select_distance && dist_vec_squared(drawable->getWorldPosition(), av_pos) > select_dist_squared)
			{
				continue;
			}

// [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Added: RLVa-1.3.0c
			if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canEdit(vobjp)) )
			{
				continue;
			}
// [/RLVa:KB]

			S32 result = LLViewerCamera::getInstance()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius());
			if (result)
			{
				switch (result)
				{
				case 1:
					// check vertices
					if (LLViewerCamera::getInstance()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive))
					{
						LLSelectMgr::getInstance()->highlightObjectOnly(vobjp);
					}
					break;
				case 2:
					LLSelectMgr::getInstance()->highlightObjectOnly(vobjp);
					break;
				default:
					break;
				}
			}
		}
	}

	// restore drawing mode
	gGL.matrixMode(LLRender::MM_PROJECTION);
	gGL.popMatrix();
	gGL.matrixMode(LLRender::MM_MODELVIEW);

	// restore camera
	LLViewerCamera::getInstance()->setFar(old_far_plane);
	LLViewerCamera::getInstance()->setNear(old_near_plane);
	gViewerWindow->setup3DRender();
}
Beispiel #9
0
BOOL LLToolGrab::handleObjectHit(const LLPickInfo& info)
{
	mGrabPick = info;
	LLViewerObject* objectp = mGrabPick.getObject();

	if (gDebugClicks)
	{
		llinfos << "LLToolGrab handleObjectHit " << info.mMousePt.mX << "," << info.mMousePt.mY << llendl;
	}

	if (NULL == objectp) // unexpected
	{
		llwarns << "objectp was NULL; returning FALSE" << llendl;
		return FALSE;
	}

	//if (objectp->isAvatar())
// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0f
	if ( (objectp->isAvatar()) ||
		 ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && ((!objectp->isAttachment()) || (!objectp->permYouOwner())) &&
		   (dist_vec_squared(gAgent.getPositionAgent(), mGrabPick.mIntersection) > 1.5f * 1.5f) ) )
// [/RLVa:KB]
	{
		if (gGrabTransientTool)
		{
			gBasicToolset->selectTool( gGrabTransientTool );
			gGrabTransientTool = NULL;
		}
		return TRUE;
	}

	setMouseCapture( TRUE );

	// Grabs always start from the root
	// objectp = (LLViewerObject *)objectp->getRoot();

	LLViewerObject* parent = objectp->getRootEdit();
	BOOL script_touch = (objectp->flagHandleTouch()) || (parent && parent->flagHandleTouch());

	// Clicks on scripted or physical objects are temporary grabs, so
	// not "Build mode"
	mHideBuildHighlight = script_touch || objectp->usePhysics();

	if (!objectp->usePhysics())
	{
		// In mouselook, we shouldn't be able to grab non-physical, 
		// non-touchable objects.  If it has a touch handler, we
		// do grab it (so llDetectedGrab works), but movement is
		// blocked on the server side. JC
		if (gAgent.cameraMouselook() && !script_touch)
		{
			mMode = GRAB_LOCKED;
			gViewerWindow->hideCursor();
			gViewerWindow->moveCursorToCenter();
		}
		else
		{
			mMode = GRAB_NONPHYSICAL;
		}
		// Don't bail out here, go on and grab so buttons can get
		// their "touched" event.
	}
	else if( !objectp->permMove() )
	{
		// if mouse is over a physical object without move permission, show feedback if user tries to move it.
		mMode = GRAB_LOCKED;

		// Don't bail out here, go on and grab so buttons can get
		// their "touched" event.
	}
	else
	{
		// if mouse is over a physical object with move permission, 
		// select it and enter "grab" mode (hiding cursor, etc.)

		mMode = GRAB_ACTIVE_CENTER;

		gViewerWindow->hideCursor();
		gViewerWindow->moveCursorToCenter();
	}

	// Always send "touched" message

	mLastMouseX = gViewerWindow->getCurrentMouseX();
	mLastMouseY = gViewerWindow->getCurrentMouseY();
	mAccumDeltaX = 0;
	mAccumDeltaY = 0;
	mHasMoved = FALSE;
	mOutsideSlop = FALSE;

	mVerticalDragging = (info.mKeyMask == MASK_VERTICAL) || gGrabBtnVertical;

	startGrab();

	if ((info.mKeyMask == MASK_SPIN) || gGrabBtnSpin)
	{
		startSpin();
	}

	LLSelectMgr::getInstance()->updateSelectionCenter();		// update selection beam

	// update point at
	LLViewerObject *edit_object = info.getObject();
	if (edit_object && info.mPickType != LLPickInfo::PICK_FLORA)
	{
		LLVector3 local_edit_point = gAgent.getPosAgentFromGlobal(info.mPosGlobal);
		local_edit_point -= edit_object->getPositionAgent();
		local_edit_point = local_edit_point * ~edit_object->getRenderRotation();
		gAgent.setPointAt(POINTAT_TARGET_GRAB, edit_object, local_edit_point );
		gAgent.setLookAt(LOOKAT_TARGET_SELECT, edit_object, local_edit_point );
	}

	// on transient grabs (clicks on world objects), kill the grab immediately
	if (!gViewerWindow->getLeftMouseDown() 
		&& gGrabTransientTool 
		&& (mMode == GRAB_NONPHYSICAL || mMode == GRAB_LOCKED))
	{
		gBasicToolset->selectTool( gGrabTransientTool );
		gGrabTransientTool = NULL;
	}

	return TRUE;
}
Beispiel #10
0
// static
LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pick, BOOL ignore_group, BOOL temp_select, BOOL select_root)
{
	LLViewerObject* object = pick.getObject();
	if (select_root)
	{
		object = object->getRootEdit();
	}

// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0f
	if (rlv_handler_t::isEnabled())
	{
		if (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT))
		{
			if (!temp_select)
			{
				return LLSelectMgr::getInstance()->getSelection();
			}
			else
			{
				// Temporary selection, but if the build floater is open then it'll be permanent so get rid of the floater
				if (gFloaterTools->getVisible())
				{
					// Copy/paste from toggle_build_mode()
					gAgent.resetView(false);
					gFloaterTools->close();
					gViewerWindow->showCursor();
				}
			}
		}
		
		if ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && (object) && ((!object->isAttachment()) || (!object->permYouOwner())) &&
			 (dist_vec_squared(gAgent.getPositionAgent(), object->getPositionRegion()) > 1.5f * 1.5f) )
		{
			// NOTE-RLVa: see behaviour notes for a rather lengthy explanation of why we're doing things this way
			//if (dist_vec_squared(gAgent.getPositionAgent(), object->getPositionRegion() + pick.mObjectOffset) > 1.5f * 1.5f)
			if (dist_vec_squared(gAgent.getPositionAgent(), pick.mIntersection) > 1.5f * 1.5f)
			{
				if ( (gFloaterTools->getVisible()) && (pick.mKeyMask != MASK_SHIFT) && (pick.mKeyMask != MASK_CONTROL) )
					LLSelectMgr::getInstance()->deselectAll();
				return LLSelectMgr::getInstance()->getSelection();
			}
			else if (gFloaterTools->getVisible())
			{
				// Copy/paste from toggle_build_mode()
				gAgent.resetView(false);
				gFloaterTools->close();
				gViewerWindow->showCursor();
			}
		}
	}
// [/RLVa:KB]

	BOOL select_owned = gSavedSettings.getBOOL("SelectOwnedOnly");
	BOOL select_movable = gSavedSettings.getBOOL("SelectMovableOnly");
	BOOL select_region = gSavedSettings.getBOOL("SelectThisRegionOnly");
	
	// *NOTE: These settings must be cleaned up at bottom of function.
	if (temp_select || gAllowSelectAvatar)
	{
		gSavedSettings.setBOOL("SelectOwnedOnly", FALSE);
		gSavedSettings.setBOOL("SelectMovableOnly", FALSE);
		gSavedSettings.setBOOL("SelectThisRegionOnly", TRUE);
		LLSelectMgr::getInstance()->setForceSelection(TRUE);
	}

	BOOL extend_select = (pick.mKeyMask == MASK_SHIFT) || (pick.mKeyMask == MASK_CONTROL);

	// If no object, check for icon, then just deselect
	if (!object)
	{
		LLHUDIcon* last_hit_hud_icon = pick.mHUDIcon;

		if (last_hit_hud_icon && last_hit_hud_icon->getSourceObject())
		{
			LLFloaterScriptDebug::show(last_hit_hud_icon->getSourceObject()->getID());
		}
		else if (!extend_select)
		{
			LLSelectMgr::getInstance()->deselectAll();
		}
	}
	else
	{
		BOOL already_selected = object->isSelected();

		if ( extend_select )
		{
			if ( already_selected )
			{
				if ( ignore_group )
				{
					LLSelectMgr::getInstance()->deselectObjectOnly(object);
				}
				else
				{
					LLSelectMgr::getInstance()->deselectObjectAndFamily(object, TRUE, TRUE);
				}
			}
			else
			{
				if ( ignore_group )
				{
					LLSelectMgr::getInstance()->selectObjectOnly(object, SELECT_ALL_TES);
				}
				else
				{
					LLSelectMgr::getInstance()->selectObjectAndFamily(object);
				}
			}
		}
		else
		{
			// Save the current zoom values because deselect resets them.
			F32 target_zoom;
			F32 current_zoom;
			LLSelectMgr::getInstance()->getAgentHUDZoom(target_zoom, current_zoom);

			// JC - Change behavior to make it easier to select children
			// of linked sets. 9/3/2002
			if( !already_selected || ignore_group)
			{
				// ...lose current selection in favor of just this object
				LLSelectMgr::getInstance()->deselectAll();
			}

			if ( ignore_group )
			{
				LLSelectMgr::getInstance()->selectObjectOnly(object, SELECT_ALL_TES);
			}
			else
			{
				LLSelectMgr::getInstance()->selectObjectAndFamily(object);
			}

			// restore the zoom to the previously stored values.
			LLSelectMgr::getInstance()->setAgentHUDZoom(target_zoom, current_zoom);
		}

		if (!gAgent.getFocusOnAvatar() &&										// if camera not glued to avatar
			LLVOAvatar::findAvatarFromAttachment(object) != gAgent.getAvatarObject() &&	// and it's not one of your attachments
			object != gAgent.getAvatarObject())									// and it's not you
		{
			// have avatar turn to face the selected object(s)
			LLVector3d selection_center = LLSelectMgr::getInstance()->getSelectionCenterGlobal();
			selection_center = selection_center - gAgent.getPositionGlobal();
			LLVector3 selection_dir;
			selection_dir.setVec(selection_center);
			selection_dir.mV[VZ] = 0.f;
			selection_dir.normVec();
			if (!object->isAvatar() && gAgent.getAtAxis() * selection_dir < 0.6f)
			{
				LLQuaternion target_rot;
				target_rot.shortestArc(LLVector3::x_axis, selection_dir);
				gAgent.startAutoPilotGlobal(gAgent.getPositionGlobal(), "", &target_rot, NULL, NULL, 1.f, SELECTION_ROTATION_TRESHOLD);
			}
		}

		if (temp_select)
		{
			if (!already_selected)
			{
				LLViewerObject* root_object = (LLViewerObject*)object->getRootEdit();
				LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();

				// this is just a temporary selection
				LLSelectNode* select_node = selection->findNode(root_object);
				if (select_node)
				{
					select_node->setTransient(TRUE);
				}

				LLViewerObject::const_child_list_t& child_list = root_object->getChildren();
				for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
					 iter != child_list.end(); iter++)
				{
					LLViewerObject* child = *iter;
					select_node = selection->findNode(child);
					if (select_node)
					{
						select_node->setTransient(TRUE);
					}
				}

			}
		} //if(temp_select)
	} //if(!object)

	// Cleanup temp select settings above.
	if (temp_select || gAllowSelectAvatar)
	{
		gSavedSettings.setBOOL("SelectOwnedOnly", select_owned);
		gSavedSettings.setBOOL("SelectMovableOnly", select_movable);
		gSavedSettings.setBOOL("SelectThisRegionOnly", select_region);
		LLSelectMgr::getInstance()->setForceSelection(FALSE);
	}

	return LLSelectMgr::getInstance()->getSelection();
}
//-----------------------------------------------------------------------------
// LLBVHLoader::optimize()
//-----------------------------------------------------------------------------
void LLBVHLoader::optimize()
{
	//RN: assumes motion blend, which is the default now
	if (!mLoop && mEaseIn + mEaseOut > mDuration && mDuration != 0.f)
	{
		F32 factor = mDuration / (mEaseIn + mEaseOut);
		mEaseIn *= factor;
		mEaseOut *= factor;
	}

	JointVector::iterator ji;
	for (ji = mJoints.begin(); ji != mJoints.end(); ++ji)
	{
		Joint *joint = *ji;
		BOOL pos_changed = FALSE;
		BOOL rot_changed = FALSE;

		if ( ! joint->mIgnore )
		{
			joint->mNumPosKeys = 0;
			joint->mNumRotKeys = 0;
			LLQuaternion::Order order = bvhStringToOrder( joint->mOrder );

			KeyVector::iterator first_key = joint->mKeys.begin();

			// no keys?
			if (first_key == joint->mKeys.end())
			{
				joint->mIgnore = TRUE;
				continue;
			}

			LLVector3 first_frame_pos(first_key->mPos);
			LLQuaternion first_frame_rot = mayaQ( first_key->mRot[0], first_key->mRot[1], first_key->mRot[2], order);
	
			// skip first key
			KeyVector::iterator ki = joint->mKeys.begin();
			if (joint->mKeys.size() == 1)
			{
				// *FIX: use single frame to move pelvis
				// if only one keyframe force output for this joint
				rot_changed = TRUE;
			}
			else
			{
				// if more than one keyframe, use first frame as reference and skip to second
				first_key->mIgnorePos = TRUE;
				first_key->mIgnoreRot = TRUE;
				++ki;
			}

			KeyVector::iterator ki_prev = ki;
			KeyVector::iterator ki_last_good_pos = ki;
			KeyVector::iterator ki_last_good_rot = ki;
			S32 numPosFramesConsidered = 2;
			S32 numRotFramesConsidered = 2;

			F32 rot_threshold = ROTATION_KEYFRAME_THRESHOLD / llmax((F32)joint->mChildTreeMaxDepth * 0.33f, 1.f);

			double diff_max = 0;
			KeyVector::iterator ki_max = ki;
			for (; ki != joint->mKeys.end(); ++ki)
			{
				if (ki_prev == ki_last_good_pos)
				{
					joint->mNumPosKeys++;
					if (dist_vec_squared(LLVector3(ki_prev->mPos), first_frame_pos) > POSITION_MOTION_THRESHOLD_SQUARED)
					{
						pos_changed = TRUE;
					}
				}
				else
				{
					//check position for noticeable effect
					LLVector3 test_pos(ki_prev->mPos);
					LLVector3 last_good_pos(ki_last_good_pos->mPos);
					LLVector3 current_pos(ki->mPos);
					LLVector3 interp_pos = lerp(current_pos, last_good_pos, 1.f / (F32)numPosFramesConsidered);

					if (dist_vec_squared(current_pos, first_frame_pos) > POSITION_MOTION_THRESHOLD_SQUARED)
					{
						pos_changed = TRUE;
					}

					if (dist_vec_squared(interp_pos, test_pos) < POSITION_KEYFRAME_THRESHOLD_SQUARED)
					{
						ki_prev->mIgnorePos = TRUE;
						numPosFramesConsidered++;
					}
					else
					{
						numPosFramesConsidered = 2;
						ki_last_good_pos = ki_prev;
						joint->mNumPosKeys++;
					}
				}

				if (ki_prev == ki_last_good_rot)
				{
					joint->mNumRotKeys++;
					LLQuaternion test_rot = mayaQ( ki_prev->mRot[0], ki_prev->mRot[1], ki_prev->mRot[2], order);
					F32 x_delta = dist_vec(LLVector3::x_axis * first_frame_rot, LLVector3::x_axis * test_rot);
					F32 y_delta = dist_vec(LLVector3::y_axis * first_frame_rot, LLVector3::y_axis * test_rot);
					F32 rot_test = x_delta + y_delta;

					if (rot_test > ROTATION_MOTION_THRESHOLD)
					{
						rot_changed = TRUE;
					}
				}
				else
				{
					//check rotation for noticeable effect
					LLQuaternion test_rot = mayaQ( ki_prev->mRot[0], ki_prev->mRot[1], ki_prev->mRot[2], order);
					LLQuaternion last_good_rot = mayaQ( ki_last_good_rot->mRot[0], ki_last_good_rot->mRot[1], ki_last_good_rot->mRot[2], order);
					LLQuaternion current_rot = mayaQ( ki->mRot[0], ki->mRot[1], ki->mRot[2], order);
					LLQuaternion interp_rot = lerp(1.f / (F32)numRotFramesConsidered, current_rot, last_good_rot);

					F32 x_delta;
					F32 y_delta;
					F32 rot_test;
					
					// Test if the rotation has changed significantly since the very first frame.  If false
					// for all frames, then we'll just throw out this joint's rotation entirely.
					x_delta = dist_vec(LLVector3::x_axis * first_frame_rot, LLVector3::x_axis * test_rot);
					y_delta = dist_vec(LLVector3::y_axis * first_frame_rot, LLVector3::y_axis * test_rot);
					rot_test = x_delta + y_delta;
					if (rot_test > ROTATION_MOTION_THRESHOLD)
					{
						rot_changed = TRUE;
					}
					x_delta = dist_vec(LLVector3::x_axis * interp_rot, LLVector3::x_axis * test_rot);
					y_delta = dist_vec(LLVector3::y_axis * interp_rot, LLVector3::y_axis * test_rot);
					rot_test = x_delta + y_delta;

					// Draw a line between the last good keyframe and current.  Test the distance between the last frame (current-1, i.e. ki_prev)
					// and the line.  If it's greater than some threshold, then it represents a significant frame and we want to include it.
					if (rot_test >= rot_threshold ||
						(ki+1 == joint->mKeys.end() && numRotFramesConsidered > 2))
					{
						// Add the current test keyframe (which is technically the previous key, i.e. ki_prev).
						numRotFramesConsidered = 2;
						ki_last_good_rot = ki_prev;
						joint->mNumRotKeys++;

						// Add another keyframe between the last good keyframe and current, at whatever point was the most "significant" (i.e.
						// had the largest deviation from the earlier tests).  Note that a more robust approach would be test all intermediate
						// keyframes against the line between the last good keyframe and current, but we're settling for this other method
						// because it's significantly faster.
						if (diff_max > 0)
						{
							if (ki_max->mIgnoreRot == TRUE)
							{
								ki_max->mIgnoreRot = FALSE;
								joint->mNumRotKeys++;
							}
							diff_max = 0;
						}
					}
					else
					{
						// This keyframe isn't significant enough, throw it away.
						ki_prev->mIgnoreRot = TRUE;
						numRotFramesConsidered++;
						// Store away the keyframe that has the largest deviation from the interpolated line, for insertion later.
						if (rot_test > diff_max)
						{
							diff_max = rot_test;
							ki_max = ki;
						}
					}
				}

				ki_prev = ki;
			}
		}	

		// don't output joints with no motion
		if (!(pos_changed || rot_changed))
		{
			//LL_INFOS() << "Ignoring joint " << joint->mName << LL_ENDL;
			joint->mIgnore = TRUE;
		}
	}
}
Beispiel #12
0
// Returns "distance" between target destination and resulting xfrom
F32 LLDrawable::updateXform(BOOL undamped)
{
	BOOL damped = !undamped;

	// Position
	LLVector3 old_pos(mXform.getPosition());
	LLVector3 target_pos;
	if (mXform.isRoot())
	{
		// get root position in your agent's region
		target_pos = mVObjp->getPositionAgent();
	}
	else
	{
		// parent-relative position
		target_pos = mVObjp->getPosition();
	}
	
	// Rotation
	LLQuaternion old_rot(mXform.getRotation());
	LLQuaternion target_rot = mVObjp->getRotation();
	//scaling
	LLVector3 target_scale = mVObjp->getScale();
	LLVector3 old_scale = mCurrentScale;
	
	// Damping
	F32 dist_squared = 0.f;
	F32 camdist2 = (mDistanceWRTCamera * mDistanceWRTCamera);

	if (damped && isVisible())
	{
		F32 lerp_amt = llclamp(LLCriticalDamp::getInterpolant(OBJECT_DAMPING_TIME_CONSTANT), 0.f, 1.f);
		LLVector3 new_pos = lerp(old_pos, target_pos, lerp_amt);
		dist_squared = dist_vec_squared(new_pos, target_pos);

		LLQuaternion new_rot = nlerp(lerp_amt, old_rot, target_rot);
		// FIXME: This can be negative! It is be possible for some rots to 'cancel out' pos or size changes.
		dist_squared += (1.f - dot(new_rot, target_rot)) * 10.f;

		LLVector3 new_scale = lerp(old_scale, target_scale, lerp_amt);
		dist_squared += dist_vec_squared(new_scale, target_scale);

		if ((dist_squared >= MIN_INTERPOLATE_DISTANCE_SQUARED * camdist2) &&
			(dist_squared <= MAX_INTERPOLATE_DISTANCE_SQUARED))
		{
			// interpolate
			target_pos = new_pos;
			target_rot = new_rot;
			target_scale = new_scale;
		}
		else if (mVObjp->getAngularVelocity().isExactlyZero())
		{
			// snap to final position (only if no target omega is applied)
			dist_squared = 0.0f;
			if (getVOVolume() && !isRoot())
			{ //child prim snapping to some position, needs a rebuild
				gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
			}
		}
	}
	else
	{
		// The following fixes MAINT-1742 but breaks vehicles similar to MAINT-2275
		// dist_squared = dist_vec_squared(old_pos, target_pos);

		// The following fixes MAINT-2247 but causes MAINT-2275
		//dist_squared += (1.f - dot(old_rot, target_rot)) * 10.f;
		//dist_squared += dist_vec_squared(old_scale, target_scale);
	}

	LLVector3 vec = mCurrentScale-target_scale;
	
	if (vec*vec > MIN_INTERPOLATE_DISTANCE_SQUARED)
	{ //scale change requires immediate rebuild
		mCurrentScale = target_scale;
		gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
	}
	else if (!isRoot() && 
		 (!mVObjp->getAngularVelocity().isExactlyZero() ||
			dist_squared > 0.f))
	{ //child prim moving relative to parent, tag as needing to be rendered atomically and rebuild
		dist_squared = 1.f; //keep this object on the move list
		if (!isState(LLDrawable::ANIMATED_CHILD))
		{			
			setState(LLDrawable::ANIMATED_CHILD);
			gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE);
			mVObjp->dirtySpatialGroup();
		}
	}
	else if (!isRoot() &&
			((dist_vec_squared(old_pos, target_pos) > 0.f)
			|| (1.f - dot(old_rot, target_rot)) > 0.f))
	{ //fix for BUG-840, MAINT-2275, MAINT-1742, MAINT-2247
		gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
	}
	else if (!getVOVolume() && !isAvatar())
	{
		movePartition();
	}

	// Update
	mXform.setPosition(target_pos);
	mXform.setRotation(target_rot);
	mXform.setScale(LLVector3(1,1,1)); //no scale in drawable transforms (IT'S A RULE!)
	mXform.updateMatrix();

	if (mSpatialBridge)
	{
		gPipeline.markMoved(mSpatialBridge, FALSE);
	}
	return dist_squared;
}
// Returns "distance" between target destination and resulting xfrom
F32 LLDrawable::updateXform(BOOL undamped)
{
	BOOL damped = !undamped;

	// Position
	LLVector3 old_pos(mXform.getPosition());
	LLVector3 target_pos;
	if (mXform.isRoot())
	{
		// get root position in your agent's region
		target_pos = mVObjp->getPositionAgent();
	}
	else
	{
		// parent-relative position
		target_pos = mVObjp->getPosition();
	}
	
	// Rotation
	LLQuaternion old_rot(mXform.getRotation());
	LLQuaternion target_rot = mVObjp->getRotation();
	//scaling
	LLVector3 target_scale = mVObjp->getScale();
	LLVector3 old_scale = mCurrentScale;
	LLVector3 dest_scale = target_scale;
	
	// Damping
	F32 dist_squared = 0.f;
	F32 camdist2 = (mDistanceWRTCamera * mDistanceWRTCamera);

	if (damped && isVisible())
	{
		F32 lerp_amt = llclamp(LLCriticalDamp::getInterpolant(OBJECT_DAMPING_TIME_CONSTANT), 0.f, 1.f);
		LLVector3 new_pos = lerp(old_pos, target_pos, lerp_amt);
		dist_squared = dist_vec_squared(new_pos, target_pos);

		LLQuaternion new_rot = nlerp(lerp_amt, old_rot, target_rot);
		dist_squared += (1.f - dot(new_rot, target_rot)) * 10.f;

		LLVector3 new_scale = lerp(old_scale, target_scale, lerp_amt);
		dist_squared += dist_vec_squared(new_scale, target_scale);

		if ((dist_squared >= MIN_INTERPOLATE_DISTANCE_SQUARED * camdist2) &&
			(dist_squared <= MAX_INTERPOLATE_DISTANCE_SQUARED))
		{
			// interpolate
			target_pos = new_pos;
			target_rot = new_rot;
			target_scale = new_scale;
		}
		else
		{
			// snap to final position
			dist_squared = 0.0f;
			if (getVOVolume() && !isRoot())
			{ //child prim snapping to some position, needs a rebuild
				gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
			}
		}
	}

	if ((mCurrentScale != target_scale) ||
		(!isRoot() && 
		 (dist_squared >= MIN_INTERPOLATE_DISTANCE_SQUARED || 
		 !mVObjp->getAngularVelocity().isExactlyZero() ||
		 target_pos != mXform.getPosition() ||
		 target_rot != mXform.getRotation())))
	{ //child prim moving or scale change requires immediate rebuild
		gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
	}
	else if (!getVOVolume() && !isAvatar())
	{
		movePartition();
	}

	// Update
	mXform.setPosition(target_pos);
	mXform.setRotation(target_rot);
	mXform.setScale(LLVector3(1,1,1)); //no scale in drawable transforms (IT'S A RULE!)
	mXform.updateMatrix();
	
	mCurrentScale = target_scale;
	
	if (mSpatialBridge)
	{
		gPipeline.markMoved(mSpatialBridge, FALSE);
	}
	return dist_squared;
}
BOOL LLToolPlacer::raycastForNewObjPos( S32 x, S32 y, LLViewerObject** hit_obj, S32* hit_face, 
							 BOOL* b_hit_land, LLVector3* ray_start_region, LLVector3* ray_end_region, LLViewerRegion** region )
{
	F32 max_dist_from_camera = gSavedSettings.getF32( "MaxSelectDistance" ) - 1.f;

	// Viewer-side pick to find the right sim to create the object on.  
	// First find the surface the object will be created on.
	LLPickInfo pick = gViewerWindow->pickImmediate(x, y, FALSE);
	
	// Note: use the frontmost non-flora version because (a) plants usually have lots of alpha and (b) pants' Havok
	// representations (if any) are NOT the same as their viewer representation.
	if (pick.mPickType == LLPickInfo::PICK_FLORA)
	{
		*hit_obj = NULL;
		*hit_face = -1;
	}
	else
	{
		*hit_obj = pick.getObject();
		*hit_face = pick.mObjectFace;
	}
	*b_hit_land = !(*hit_obj) && !pick.mPosGlobal.isExactlyZero();
	LLVector3d land_pos_global = pick.mPosGlobal;

	// Make sure there's a surface to place the new object on.
	BOOL bypass_sim_raycast = FALSE;
	LLVector3d	surface_pos_global;
	if (*b_hit_land)
	{
		surface_pos_global = land_pos_global; 
		bypass_sim_raycast = TRUE;
	}
	else 
	if (*hit_obj)
	{
		surface_pos_global = (*hit_obj)->getPositionGlobal();
	}
	else
	{
		return FALSE;
	}

	// Make sure the surface isn't too far away.
	LLVector3d ray_start_global = gAgentCamera.getCameraPositionGlobal();
	F32 dist_to_surface_sq = (F32)((surface_pos_global - ray_start_global).magVecSquared());
	if( dist_to_surface_sq > (max_dist_from_camera * max_dist_from_camera) )
	{
		return FALSE;
	}

// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0f
	// NOTE: don't use surface_pos_global since for prims it will be the center of the prim while we need center + offset
	if ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && (dist_vec_squared(gAgent.getPositionGlobal(), pick.mPosGlobal) > 1.5f * 1.5f) )
	{
		return FALSE;
	}
// [/RLVa:KB]

	// Find the sim where the surface lives.
	LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(surface_pos_global);
	if (!regionp)
	{
		llwarns << "Trying to add object outside of all known regions!" << llendl;
		return FALSE;
	}

	// Find the simulator-side ray that will be used to place the object accurately
	LLVector3d		mouse_direction;
	mouse_direction.setVec( gViewerWindow->mouseDirectionGlobal( x, y ) );

	*region = regionp;
	*ray_start_region =	regionp->getPosRegionFromGlobal( ray_start_global );
	F32 near_clip = LLViewerCamera::getInstance()->getNear() + 0.01f;  // Include an epsilon to avoid rounding issues.
	*ray_start_region += LLViewerCamera::getInstance()->getAtAxis() * near_clip;

	if( bypass_sim_raycast )
	{
		// Hack to work around Havok's inability to ray cast onto height fields
		*ray_end_region = regionp->getPosRegionFromGlobal( surface_pos_global );  // ray end is the viewer's intersection point
	}
	else
	{
		LLVector3d		ray_end_global = ray_start_global + (1.f + max_dist_from_camera) * mouse_direction;  // add an epsilon to the sim version of the ray to avoid rounding problems.
		*ray_end_region = regionp->getPosRegionFromGlobal( ray_end_global );
	}

	return TRUE;
}
Beispiel #15
0
//-----------------------------------------------------------------------------
// setPointAt()
// called by agent logic to set look at behavior locally, and propagate to sim
//-----------------------------------------------------------------------------
BOOL LLHUDEffectPointAt::setPointAt(EPointAtType target_type, LLViewerObject *object, LLVector3 position)
{
	if (!mSourceObject)
	{
		return FALSE;
	}
	
	if (target_type >= POINTAT_NUM_TARGETS)
	{
		llwarns << "Bad target_type " << (int)target_type << " - ignoring." << llendl;
		return FALSE;
	}

	// must be same or higher priority than existing effect
	if (POINTAT_PRIORITIES[target_type] < POINTAT_PRIORITIES[mTargetType])
	{
		return FALSE;
	}

	F32 current_time  = mTimer.getElapsedTimeF32();
	
	// type of pointat behavior or target object has changed
	BOOL targetTypeChanged = (target_type != mTargetType) ||
		(object != mTargetObject);

	BOOL targetPosChanged = (dist_vec_squared(position, mLastSentOffsetGlobal) > MIN_DELTAPOS_FOR_UPDATE_SQUARED) && 
		((current_time - mLastSendTime) > (1.f / MAX_SENDS_PER_SEC));

	if (targetTypeChanged || targetPosChanged)
	{
		mLastSentOffsetGlobal = position;
		setDuration(POINTAT_TIMEOUTS[target_type]);
		setNeedsSendToSim(TRUE);
//		llinfos << "Sending pointat data" << llendl;
	}

	if (target_type == POINTAT_TARGET_CLEAR)
	{
		clearPointAtTarget();
	}
	else
	{
		mTargetType = target_type;
		mTargetObject = object;
		if (object)
		{
			mTargetOffsetGlobal.setVec(position);
		}
		else
		{
			mTargetOffsetGlobal = gAgent.getPosGlobalFromAgent(position);
		}

		mKillTime = mTimer.getElapsedTimeF32() + mDuration;

		//set up requisite animation data
		update();
	}

	return TRUE;
}
// Returns true if you got at least one object
void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
{
	LLVector3 av_pos = gAgent.getPositionAgent();
	F32 select_dist_squared = gSavedSettings.getF32("MaxSelectDistance");
	select_dist_squared = select_dist_squared * select_dist_squared;

	BOOL deselect = (mask == MASK_CONTROL);
	S32 left =	llmin(x, mDragStartX);
	S32 right =	llmax(x, mDragStartX);
	S32 top =	llmax(y, mDragStartY);
	S32 bottom =llmin(y, mDragStartY);

	left = llround((F32) left * LLUI::sGLScaleFactor.mV[VX]);
	right = llround((F32) right * LLUI::sGLScaleFactor.mV[VX]);
	top = llround((F32) top * LLUI::sGLScaleFactor.mV[VY]);
	bottom = llround((F32) bottom * LLUI::sGLScaleFactor.mV[VY]);

	F32 old_far_plane = LLViewerCamera::getInstance()->getFar();
	F32 old_near_plane = LLViewerCamera::getInstance()->getNear();

	S32 width = right - left + 1;
	S32 height = top - bottom + 1;

	BOOL grow_selection = FALSE;
	BOOL shrink_selection = FALSE;

	if (height > mDragLastHeight || width > mDragLastWidth)
	{
		grow_selection = TRUE;
	}
	if (height < mDragLastHeight || width < mDragLastWidth)
	{
		shrink_selection = TRUE;
	}

	if (!grow_selection && !shrink_selection)
	{
		// nothing to do
		return;
	}

	mDragLastHeight = height;
	mDragLastWidth = width;

	S32 center_x = (left + right) / 2;
	S32 center_y = (top + bottom) / 2;

	// save drawing mode
	glMatrixMode(GL_PROJECTION);
	gGL.pushMatrix();

	BOOL limit_select_distance = gSavedSettings.getBOOL("LimitSelectDistance");
	if (limit_select_distance)
	{
		// ...select distance from control
		LLVector3 relative_av_pos = av_pos;
		relative_av_pos -= LLViewerCamera::getInstance()->getOrigin();

		F32 new_far = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() + gSavedSettings.getF32("MaxSelectDistance");
		F32 new_near = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() - gSavedSettings.getF32("MaxSelectDistance");

		new_near = llmax(new_near, 0.1f);

		LLViewerCamera::getInstance()->setFar(new_far);
		LLViewerCamera::getInstance()->setNear(new_near);
	}
	LLViewerCamera::getInstance()->setPerspective(FOR_SELECTION, 
							center_x-width/2, center_y-height/2, width, height, 
							limit_select_distance);

	if (shrink_selection)
	{
		struct f : public LLSelectedObjectFunctor
		{
			virtual bool apply(LLViewerObject* vobjp)
			{
				LLDrawable* drawable = vobjp->mDrawable;
				if (!drawable || vobjp->getPCode() != LL_PCODE_VOLUME || vobjp->isAttachment())
				{
					return true;
				}
				S32 result = LLViewerCamera::getInstance()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius());
				switch (result)
				{
				  case 0:
					LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp);
					break;
				  case 1:
					// check vertices
					if (!LLViewerCamera::getInstance()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive))
					{
						LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp);
					}
					break;
				  default:
					break;
				}
				return true;
			}
		} func;
		LLSelectMgr::getInstance()->getHighlightedObjects()->applyToObjects(&func);
	}

	if (grow_selection)
	{
		std::vector<LLDrawable*> potentials;
				
		for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
			iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
		{
			LLViewerRegion* region = *iter;
			for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
			{
				LLSpatialPartition* part = region->getSpatialPartition(i);
				if (part)
				{	
					part->cull(*LLViewerCamera::getInstance(), &potentials, TRUE);
				}
			}
		}
		
		for (std::vector<LLDrawable*>::iterator iter = potentials.begin();
			 iter != potentials.end(); iter++)
		{
			LLDrawable* drawable = *iter;
			LLViewerObject* vobjp = drawable->getVObj();

			if (!drawable || !vobjp ||
				vobjp->getPCode() != LL_PCODE_VOLUME || 
				vobjp->isAttachment() ||
				(deselect && !vobjp->isSelected()))
			{
				continue;
			}

			if (limit_select_distance && dist_vec_squared(drawable->getWorldPosition(), av_pos) > select_dist_squared)
			{
				continue;
			}

			S32 result = LLViewerCamera::getInstance()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius());
			if (result)
			{
				switch (result)
				{
				case 1:
					// check vertices
					if (LLViewerCamera::getInstance()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive))
					{
						LLSelectMgr::getInstance()->highlightObjectOnly(vobjp);
					}
					break;
				case 2:
					LLSelectMgr::getInstance()->highlightObjectOnly(vobjp);
					break;
				default:
					break;
				}
			}
		}
	}

	// restore drawing mode
	glMatrixMode(GL_PROJECTION);
	gGL.popMatrix();
	glMatrixMode(GL_MODELVIEW);

	// restore camera
	LLViewerCamera::getInstance()->setFar(old_far_plane);
	LLViewerCamera::getInstance()->setNear(old_near_plane);
	gViewerWindow->setup3DRender();
}
//static 
void LLViewerChat::getChatColor(const LLChat& chat, LLColor4& r_color)
{
	if(chat.mMuted)
	{
		r_color= LLUIColorTable::instance().getColor("LtGray");
	}
	else
	{
		switch(chat.mSourceType)
		{
			case CHAT_SOURCE_SYSTEM:
				r_color = LLUIColorTable::instance().getColor("SystemChatColor"); 
				break;
			case CHAT_SOURCE_AGENT:
				if (chat.mFromID.isNull() || SYSTEM_FROM == chat.mFromName)
				{
					r_color = LLUIColorTable::instance().getColor("SystemChatColor");
				}
				else
				{
					if(gAgentID == chat.mFromID)
					{
						r_color = LLUIColorTable::instance().getColor("UserChatColor");
					}
					else
					{
						r_color = LLUIColorTable::instance().getColor("AgentChatColor");
					}
				}
				break;
			case CHAT_SOURCE_OBJECT:
				if (chat.mChatType == CHAT_TYPE_DEBUG_MSG)
				{
					r_color = LLUIColorTable::instance().getColor("ScriptErrorColor");
				}
				else if ( chat.mChatType == CHAT_TYPE_OWNER )
				{
					r_color = LLUIColorTable::instance().getColor("llOwnerSayChatColor");
				}
				else if ( chat.mChatType == CHAT_TYPE_DIRECT )
				{
					r_color = LLUIColorTable::instance().getColor("DirectChatColor");
				}
				else
				{
					r_color = LLUIColorTable::instance().getColor("ObjectChatColor");
				}
				break;
			default:
				r_color.setToWhite();
		}
		
		if (!chat.mPosAgent.isExactlyZero())
		{
			LLVector3 pos_agent = gAgent.getPositionAgent();
			F32 distance_squared = dist_vec_squared(pos_agent, chat.mPosAgent);
			F32 dist_near_chat = gAgent.getNearChatRadius();
			if (distance_squared > dist_near_chat * dist_near_chat)
			{
				// diminish far-off chat
				r_color.mV[VALPHA] = 0.8f;
			}
		}
	}
}
Beispiel #18
0
void LLWorld::getAvatars(std::vector<LLUUID>* avatar_ids, std::vector<LLVector3d>* positions, const LLVector3d& relative_to, F32 radius) const
{
	F32 radius_squared = radius * radius;
	
	if(avatar_ids != NULL)
	{
		avatar_ids->clear();
	}
	if(positions != NULL)
	{
		positions->clear();
	}
	// get the list of avatars from the character list first, so distances are correct
	// when agent is above 1020m and other avatars are nearby
	for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
		iter != LLCharacter::sInstances.end(); ++iter)
	{
		LLVOAvatar* pVOAvatar = (LLVOAvatar*) *iter;

		if (!pVOAvatar->isDead() && !pVOAvatar->isSelf() && !pVOAvatar->mIsDummy)
		{
			LLUUID uuid = pVOAvatar->getID();
			if(!uuid.isNull())
			{
				LLVector3d pos_global = pVOAvatar->getPositionGlobal();
				if(dist_vec_squared(pos_global, relative_to) <= radius_squared)
				{
					if(positions != NULL)
					{
						positions->push_back(pos_global);
					}
					if(avatar_ids !=NULL)
					{
						avatar_ids->push_back(uuid);
					}
				}
			}
		}
	}
	// region avatars added for situations where radius is greater than RenderFarClip
	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
		iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
	{
		LLViewerRegion* regionp = *iter;
		const LLVector3d& origin_global = regionp->getOriginGlobal();
		S32 count = regionp->mMapAvatars.count();
		for (S32 i = 0; i < count; i++)
		{
			LLVector3d pos_global = unpackLocalToGlobalPosition(regionp->mMapAvatars.get(i), origin_global);
			if(dist_vec_squared(pos_global, relative_to) <= radius_squared)
			{
				LLUUID uuid = regionp->mMapAvatarIDs.get(i);
				// if this avatar doesn't already exist in the list, add it
				if(uuid.notNull() && avatar_ids != NULL && std::find(avatar_ids->begin(), avatar_ids->end(), uuid) == avatar_ids->end())
				{
					if(positions != NULL)
					{
						positions->push_back(pos_global);
					}
					avatar_ids->push_back(uuid);
				}
			}
		}
	}
}
LLColor4 get_text_color(const LLChat& chat)
{
	LLColor4 text_color;

	if(chat.mMuted)
	{
		text_color.setVec(0.8f, 0.8f, 0.8f, 1.f);
	}
	else
	{
		switch(chat.mSourceType)
		{
		case CHAT_SOURCE_SYSTEM:
			text_color = LLUIColorTable::instance().getColor("SystemChatColor");
			break;
		case CHAT_SOURCE_AGENT:
		    if (chat.mFromID.isNull())
			{
				text_color = LLUIColorTable::instance().getColor("SystemChatColor");
			}
			else
			{
				if(gAgent.getID() == chat.mFromID)
				{
					text_color = LLUIColorTable::instance().getColor("UserChatColor");
				}
				else
				{
					text_color = LLUIColorTable::instance().getColor("AgentChatColor");
				}
			}
			break;
		case CHAT_SOURCE_OBJECT:
			if (chat.mChatType == CHAT_TYPE_DEBUG_MSG)
			{
				text_color = LLUIColorTable::instance().getColor("ScriptErrorColor");
			}
			else if ( chat.mChatType == CHAT_TYPE_OWNER )
			{
				text_color = LLUIColorTable::instance().getColor("llOwnerSayChatColor");
			}
			else
			{
				text_color = LLUIColorTable::instance().getColor("ObjectChatColor");
			}
			break;
		default:
			text_color.setToWhite();
		}

		if (!chat.mPosAgent.isExactlyZero())
		{
			LLVector3 pos_agent = gAgent.getPositionAgent();
			F32 distance_squared = dist_vec_squared(pos_agent, chat.mPosAgent);
			F32 dist_near_chat = gAgent.getNearChatRadius();
			if (distance_squared > dist_near_chat * dist_near_chat)
			{
				// diminish far-off chat
				text_color.mV[VALPHA] = 0.8f;
			}
		}
	}

	return text_color;
}
Beispiel #20
0
void LLNetMap::draw()
{
 	static LLFrameTimer map_timer;
	static LLUIColor map_avatar_color = LLUIColorTable::instance().getColor("MapAvatarColor", LLColor4::white);
	static LLUIColor map_avatar_friend_color = LLUIColorTable::instance().getColor("MapAvatarFriendColor", LLColor4::white);
	static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white);
	//static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white);
	static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white);
	static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white);
	
	if (mObjectImagep.isNull())
	{
		createObjectImage();
	}

	static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
	if (auto_center)
	{
		mCurPan = lerp(mCurPan, mTargetPan, LLSmoothInterpolation::getInterpolant(0.1f));
	}

	// Prepare a scissor region
	F32 rotation = 0;

	gGL.pushMatrix();
	gGL.pushUIMatrix();
	
	LLVector3 offset = gGL.getUITranslation();
	LLVector3 scale = gGL.getUIScale();

	gGL.loadIdentity();
	gGL.loadUIIdentity();

	gGL.scalef(scale.mV[0], scale.mV[1], scale.mV[2]);
	gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]);
	
	{
		LLLocalClipRect clip(getLocalRect());
		{
			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);

			gGL.matrixMode(LLRender::MM_MODELVIEW);

			// Draw background rectangle
			LLColor4 background_color = mBackgroundColor.get();
			gGL.color4fv( background_color.mV );
			gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0);
		}

		// region 0,0 is in the middle
		S32 center_sw_left = getRect().getWidth() / 2 + llfloor(mCurPan.mV[VX]);
		S32 center_sw_bottom = getRect().getHeight() / 2 + llfloor(mCurPan.mV[VY]);

		gGL.pushMatrix();

		gGL.translatef( (F32) center_sw_left, (F32) center_sw_bottom, 0.f);

		static LLUICachedControl<bool> rotate_map("MiniMapRotate", true);
		if( rotate_map )
		{
			// rotate subsequent draws to agent rotation
			rotation = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] );
			gGL.rotatef( rotation * RAD_TO_DEG, 0.f, 0.f, 1.f);
		}

		// figure out where agent is
		S32 region_width = ll_round(LLWorld::getInstance()->getRegionWidthInMeters());

		for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
			 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
		{
			LLViewerRegion* regionp = *iter;
			// Find x and y position relative to camera's center.
			LLVector3 origin_agent = regionp->getOriginAgent();
			LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent();
			F32 relative_x = (rel_region_pos.mV[0] / region_width) * mScale;
			F32 relative_y = (rel_region_pos.mV[1] / region_width) * mScale;

			// background region rectangle
			F32 bottom =	relative_y;
			F32 left =		relative_x;
			F32 top =		bottom + mScale ;
			F32 right =		left + mScale ;

			if (regionp == gAgent.getRegion())
			{
				gGL.color4f(1.f, 1.f, 1.f, 1.f);
			}
			else
			{
				gGL.color4f(0.8f, 0.8f, 0.8f, 1.f);
			}

			if (!regionp->isAlive())
			{
				gGL.color4f(1.f, 0.5f, 0.5f, 1.f);
			}


			// Draw using texture.
			gGL.getTexUnit(0)->bind(regionp->getLand().getSTexture());
			gGL.begin(LLRender::QUADS);
				gGL.texCoord2f(0.f, 1.f);
				gGL.vertex2f(left, top);
				gGL.texCoord2f(0.f, 0.f);
				gGL.vertex2f(left, bottom);
				gGL.texCoord2f(1.f, 0.f);
				gGL.vertex2f(right, bottom);
				gGL.texCoord2f(1.f, 1.f);
				gGL.vertex2f(right, top);
			gGL.end();

			// Draw water
			gGL.setAlphaRejectSettings(LLRender::CF_GREATER, ABOVE_WATERLINE_ALPHA / 255.f);
			{
				if (regionp->getLand().getWaterTexture())
				{
					gGL.getTexUnit(0)->bind(regionp->getLand().getWaterTexture());
					gGL.begin(LLRender::QUADS);
						gGL.texCoord2f(0.f, 1.f);
						gGL.vertex2f(left, top);
						gGL.texCoord2f(0.f, 0.f);
						gGL.vertex2f(left, bottom);
						gGL.texCoord2f(1.f, 0.f);
						gGL.vertex2f(right, bottom);
						gGL.texCoord2f(1.f, 1.f);
						gGL.vertex2f(right, top);
					gGL.end();
				}
			}
			gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
		}

		// Redraw object layer periodically
		if (mUpdateNow || (map_timer.getElapsedTimeF32() > 0.5f))
		{
			mUpdateNow = false;

			// Locate the centre of the object layer, accounting for panning
			LLVector3 new_center = globalPosToView(gAgentCamera.getCameraPositionGlobal());
			new_center.mV[VX] -= mCurPan.mV[VX];
			new_center.mV[VY] -= mCurPan.mV[VY];
			new_center.mV[VZ] = 0.f;
			mObjectImageCenterGlobal = viewPosToGlobal(llfloor(new_center.mV[VX]), llfloor(new_center.mV[VY]));

			// Create the base texture.
			U8 *default_texture = mObjectRawImagep->getData();
			memset( default_texture, 0, mObjectImagep->getWidth() * mObjectImagep->getHeight() * mObjectImagep->getComponents() );

			// Draw objects
			gObjectList.renderObjectsForMap(*this);

			mObjectImagep->setSubImage(mObjectRawImagep, 0, 0, mObjectImagep->getWidth(), mObjectImagep->getHeight());
			
			map_timer.reset();
		}

		LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal);
		LLVector3 camera_position = gAgentCamera.getCameraPositionAgent();
		map_center_agent -= camera_position;
		map_center_agent.mV[VX] *= mScale/region_width;
		map_center_agent.mV[VY] *= mScale/region_width;

		gGL.getTexUnit(0)->bind(mObjectImagep);
		F32 image_half_width = 0.5f*mObjectMapPixels;
		F32 image_half_height = 0.5f*mObjectMapPixels;

		gGL.begin(LLRender::QUADS);
			gGL.texCoord2f(0.f, 1.f);
			gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, image_half_height + map_center_agent.mV[VY]);
			gGL.texCoord2f(0.f, 0.f);
			gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, map_center_agent.mV[VY] - image_half_height);
			gGL.texCoord2f(1.f, 0.f);
			gGL.vertex2f(image_half_width + map_center_agent.mV[VX], map_center_agent.mV[VY] - image_half_height);
			gGL.texCoord2f(1.f, 1.f);
			gGL.vertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]);
		gGL.end();

		gGL.popMatrix();

		// Mouse pointer in local coordinates
		S32 local_mouse_x;
		S32 local_mouse_y;
		//localMouse(&local_mouse_x, &local_mouse_y);
		LLUI::getMousePositionLocal(this, &local_mouse_x, &local_mouse_y);
		mClosestAgentToCursor.setNull();
		F32 closest_dist_squared = F32_MAX; // value will be overridden in the loop
		F32 min_pick_dist_squared = (mDotRadius * MIN_PICK_SCALE) * (mDotRadius * MIN_PICK_SCALE);

		LLVector3 pos_map;
		uuid_vec_t avatar_ids;
		std::vector<LLVector3d> positions;
		bool unknown_relative_z;

		LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, gAgentCamera.getCameraPositionGlobal());

		// Draw avatars
		for (U32 i = 0; i < avatar_ids.size(); i++)
		{
			LLUUID uuid = avatar_ids[i];
			// Skip self, we'll draw it later
			if (uuid == gAgent.getID()) continue;

			pos_map = globalPosToView(positions[i]);

			bool show_as_friend = (LLAvatarTracker::instance().getBuddyInfo(uuid) != NULL);

			LLColor4 color = show_as_friend ? map_avatar_friend_color : map_avatar_color;

			unknown_relative_z = positions[i].mdV[VZ] == COARSEUPDATE_MAX_Z &&
					camera_position.mV[VZ] >= COARSEUPDATE_MAX_Z;

			LLWorldMapView::drawAvatar(
				pos_map.mV[VX], pos_map.mV[VY], 
				color, 
				pos_map.mV[VZ], mDotRadius,
				unknown_relative_z);

			if(uuid.notNull())
			{
				bool selected = false;
				uuid_vec_t::iterator sel_iter = gmSelected.begin();
				for (; sel_iter != gmSelected.end(); sel_iter++)
				{
					if(*sel_iter == uuid)
					{
						selected = true;
						break;
					}
				}
				if(selected)
				{
					if( (pos_map.mV[VX] < 0) ||
						(pos_map.mV[VY] < 0) ||
						(pos_map.mV[VX] >= getRect().getWidth()) ||
						(pos_map.mV[VY] >= getRect().getHeight()) )
					{
						S32 x = ll_round( pos_map.mV[VX] );
						S32 y = ll_round( pos_map.mV[VY] );
						LLWorldMapView::drawTrackingCircle( getRect(), x, y, color, 1, 10);
					} else
					{
						LLWorldMapView::drawTrackingDot(pos_map.mV[VX],pos_map.mV[VY],color,0.f);
					}
				}
			}

			F32	dist_to_cursor_squared = dist_vec_squared(LLVector2(pos_map.mV[VX], pos_map.mV[VY]),
										  LLVector2(local_mouse_x,local_mouse_y));
			if(dist_to_cursor_squared < min_pick_dist_squared && dist_to_cursor_squared < closest_dist_squared)
			{
				closest_dist_squared = dist_to_cursor_squared;
				mClosestAgentToCursor = uuid;
			}
		}

		// Draw dot for autopilot target
		if (gAgent.getAutoPilot())
		{
			drawTracking( gAgent.getAutoPilotTargetGlobal(), map_track_color );
		}
		else
		{
			LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus();
			if (  LLTracker::TRACKING_AVATAR == tracking_status )
			{
				drawTracking( LLAvatarTracker::instance().getGlobalPos(), map_track_color );
			} 
			else if ( LLTracker::TRACKING_LANDMARK == tracking_status 
					|| LLTracker::TRACKING_LOCATION == tracking_status )
			{
				drawTracking( LLTracker::getTrackedPositionGlobal(), map_track_color );
			}
		}

		// Draw dot for self avatar position
		LLVector3d pos_global = gAgent.getPositionGlobal();
		pos_map = globalPosToView(pos_global);
		S32 dot_width = ll_round(mDotRadius * 2.f);
		LLUIImagePtr you = LLWorldMapView::sAvatarYouLargeImage;
		if (you)
		{
			you->draw(ll_round(pos_map.mV[VX] - mDotRadius),
					  ll_round(pos_map.mV[VY] - mDotRadius),
					  dot_width,
					  dot_width);

			F32	dist_to_cursor_squared = dist_vec_squared(LLVector2(pos_map.mV[VX], pos_map.mV[VY]),
										  LLVector2(local_mouse_x,local_mouse_y));
			if(dist_to_cursor_squared < min_pick_dist_squared && dist_to_cursor_squared < closest_dist_squared)
			{
				mClosestAgentToCursor = gAgent.getID();
			}
		}

		// Draw frustum
		F32 meters_to_pixels = mScale/ LLWorld::getInstance()->getRegionWidthInMeters();

		F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect();
		F32 far_clip_meters = LLViewerCamera::getInstance()->getFar();
		F32 far_clip_pixels = far_clip_meters * meters_to_pixels;

		F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 );
		F32 half_width_pixels = half_width_meters * meters_to_pixels;
		
		F32 ctr_x = (F32)center_sw_left;
		F32 ctr_y = (F32)center_sw_bottom;


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

		if( rotate_map )
		{
			gGL.color4fv((map_frustum_color()).mV);

			gGL.begin( LLRender::TRIANGLES  );
				gGL.vertex2f( ctr_x, ctr_y );
				gGL.vertex2f( ctr_x - half_width_pixels, ctr_y + far_clip_pixels );
				gGL.vertex2f( ctr_x + half_width_pixels, ctr_y + far_clip_pixels );
			gGL.end();
		}
		else
		{
			gGL.color4fv((map_frustum_rotating_color()).mV);
			
			// If we don't rotate the map, we have to rotate the frustum.
			gGL.pushMatrix();
				gGL.translatef( ctr_x, ctr_y, 0 );
				gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f);
				gGL.begin( LLRender::TRIANGLES  );
					gGL.vertex2f( 0, 0 );
					gGL.vertex2f( -half_width_pixels, far_clip_pixels );
					gGL.vertex2f(  half_width_pixels, far_clip_pixels );
				gGL.end();
			gGL.popMatrix();
		}
	}
	
	gGL.popMatrix();
	gGL.popUIMatrix();

	LLUICtrl::draw();
}
// This function selects an ideal viewing distance based on the focused object, pick normal, and padding value
void LLViewerMediaFocus::setCameraZoom(LLViewerObject* object, LLVector3 normal, F32 padding_factor, bool zoom_in_only)
{
	if (object)
	{
		gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);

		LLBBox bbox = object->getBoundingBoxAgent();
		LLVector3d center = gAgent.getPosGlobalFromAgent(bbox.getCenterAgent());
		F32 height;
		F32 width;
		F32 depth;
		F32 angle_of_view;
		F32 distance;

		// We need the aspect ratio, and the 3 components of the bbox as height, width, and depth.
		F32 aspect_ratio = getBBoxAspectRatio(bbox, normal, &height, &width, &depth);
		F32 camera_aspect = LLViewerCamera::getInstance()->getAspect();
		
		lldebugs << "normal = " << normal << ", aspect_ratio = " << aspect_ratio << ", camera_aspect = " << camera_aspect << llendl;

		// We will normally use the side of the volume aligned with the short side of the screen (i.e. the height for 
		// a screen in a landscape aspect ratio), however there is an edge case where the aspect ratio of the object is 
		// more extreme than the screen.  In this case we invert the logic, using the longer component of both the object
		// and the screen.  
		bool invert = (camera_aspect > 1.0f && aspect_ratio > camera_aspect) ||
			(camera_aspect < 1.0f && aspect_ratio < camera_aspect);

		// To calculate the optimum viewing distance we will need the angle of the shorter side of the view rectangle.
		// In portrait mode this is the width, and in landscape it is the height.
		// We then calculate the distance based on the corresponding side of the object bbox (width for portrait, height for landscape)
		// We will add half the depth of the bounding box, as the distance projection uses the center point of the bbox.
		if(camera_aspect < 1.0f || invert)
		{
			angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect());
			distance = width * 0.5 * padding_factor / tan(angle_of_view * 0.5f );

			lldebugs << "using width (" << width << "), angle_of_view = " << angle_of_view << ", distance = " << distance << llendl;
		}
		else
		{
			angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getView());
			distance = height * 0.5 * padding_factor / tan(angle_of_view * 0.5f );

			lldebugs << "using height (" << height << "), angle_of_view = " << angle_of_view << ", distance = " << distance << llendl;
		}

		distance += depth * 0.5;

		// Finally animate the camera to this new position and focal point
		LLVector3d camera_pos, target_pos;
		// The target lookat position is the center of the selection (in global coords)
		target_pos = center;
		// Target look-from (camera) position is "distance" away from the target along the normal 
		LLVector3d pickNormal = LLVector3d(normal);
		pickNormal.normalize();
        camera_pos = target_pos + pickNormal * distance;
        if (pickNormal == LLVector3d::z_axis || pickNormal == LLVector3d::z_axis_neg)
        {
			// If the normal points directly up, the camera will "flip" around.
			// We try to avoid this by adjusting the target camera position a 
			// smidge towards current camera position
			// *NOTE: this solution is not perfect.  All it attempts to solve is the
			// "looking down" problem where the camera flips around when it animates
			// to that position.  You still are not guaranteed to be looking at the
			// media in the correct orientation.  What this solution does is it will
			// put the camera into position keeping as best it can the current 
			// orientation with respect to the face.  In other words, if before zoom
			// the media appears "upside down" from the camera, after zooming it will
			// still be upside down, but at least it will not flip.
            LLVector3d cur_camera_pos = LLVector3d(gAgentCamera.getCameraPositionGlobal());
            LLVector3d delta = (cur_camera_pos - camera_pos);
            F64 len = delta.length();
            delta.normalize();
            // Move 1% of the distance towards original camera location
            camera_pos += 0.01 * len * delta;
        }

		// If we are not allowing zooming out and the old camera position is closer to 
		// the center then the new intended camera position, don't move camera and return
		if (zoom_in_only &&
		    (dist_vec_squared(gAgentCamera.getCameraPositionGlobal(), target_pos) < dist_vec_squared(camera_pos, target_pos)))
		{
			return;
		}

		gAgentCamera.setCameraPosAndFocusGlobal(camera_pos, target_pos, object->getID() );

	}
	else
	{
		// If we have no object, focus back on the avatar.
		gAgentCamera.setFocusOnAvatar(TRUE, ANIMATE);
	}
}
Beispiel #22
0
//static 
void LLViewerChat::getChatColor(const LLChat& chat, std::string& r_color_name, F32& r_color_alpha)
{
	if(chat.mMuted)
	{
		r_color_name = "LtGray";
	}
	else
	{
		switch(chat.mSourceType)
		{
			case CHAT_SOURCE_SYSTEM:
				r_color_name = "SystemChatColor";
				break;
				
			case CHAT_SOURCE_AGENT:
				if (chat.mFromID.isNull())
				{
					r_color_name = "SystemChatColor";
				}
				else
				{
					if(gAgentID == chat.mFromID)
					{
						r_color_name = "UserChatColor";
					}
					else
					{
						r_color_name = "AgentChatColor";
					}
				}
				break;
				
			case CHAT_SOURCE_OBJECT:
				if (chat.mChatType == CHAT_TYPE_DEBUG_MSG)
				{
					r_color_name = "ScriptErrorColor";
				}
				else if ( chat.mChatType == CHAT_TYPE_OWNER )
				{
					r_color_name = "llOwnerSayChatColor";
				}
				else if ( chat.mChatType == CHAT_TYPE_DIRECT )
				{
					r_color_name = "DirectChatColor";
				}
				else if ( chat.mChatType == CHAT_TYPE_IM )
				{
					r_color_name = "ObjectIMColor";
				}
				else
				{
					r_color_name = "ObjectChatColor";
				}
				break;
			default:
				r_color_name = "White";
		}
		
		if (!chat.mPosAgent.isExactlyZero())
		{
			LLVector3 pos_agent = gAgent.getPositionAgent();
			F32 distance_squared = dist_vec_squared(pos_agent, chat.mPosAgent);
			F32 dist_near_chat = LLWorld::getInstance()->getSayDistance();
			if (distance_squared > dist_near_chat * dist_near_chat)
			{
				// diminish far-off chat
				r_color_alpha = 0.8f; 
			}
			else
			{
				r_color_alpha = 1.0f;
			}
		}
	}
	
}
Beispiel #23
0
void LLNetMap::draw()
{
	// Ansariel: Synchronize netmap scale throughout instances
	if (mScale != sScale)
	{
		setScale(sScale);
	}

 	static LLFrameTimer map_timer;
	static LLUIColor map_avatar_color = LLUIColorTable::instance().getColor("MapAvatarColor", LLColor4::white);
	static LLUIColor map_avatar_friend_color = LLUIColorTable::instance().getColor("MapAvatarFriendColor", LLColor4::white);
	static LLUIColor map_avatar_linden_color = LLUIColorTable::instance().getColor("MapAvatarLindenColor", LLColor4::blue);
	static LLUIColor map_avatar_muted_color = LLUIColorTable::instance().getColor("MapAvatarMutedColor", LLColor4::grey3);
	static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white);
	static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white);
	static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white);
	static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white);
	static LLUIColor map_chat_ring_color = LLUIColorTable::instance().getColor("MapChatRingColor", LLColor4::yellow);
	static LLUIColor map_shout_ring_color = LLUIColorTable::instance().getColor("MapShoutRingColor", LLColor4::red);
	
	if (mObjectImagep.isNull())
	{
		createObjectImage();
	}

	static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
	if (auto_center)
	{
		mCurPan = lerp(mCurPan, mTargetPan, LLCriticalDamp::getInterpolant(0.1f));
	}

	// Prepare a scissor region
	F32 rotation = 0;

	gGL.pushMatrix();
	gGL.pushUIMatrix();
	
	LLVector3 offset = gGL.getUITranslation();
	LLVector3 scale = gGL.getUIScale();

	gGL.loadIdentity();
	gGL.loadUIIdentity();

	gGL.scalef(scale.mV[0], scale.mV[1], scale.mV[2]);
	gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]);
	
	{
		LLLocalClipRect clip(getLocalRect());
		{
			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);

			gGL.matrixMode(LLRender::MM_MODELVIEW);

			// Draw background rectangle
			LLColor4 background_color = mBackgroundColor.get();
			gGL.color4fv( background_color.mV );
			gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0);
		}

		// region 0,0 is in the middle
		S32 center_sw_left = getRect().getWidth() / 2 + llfloor(mCurPan.mV[VX]);
		S32 center_sw_bottom = getRect().getHeight() / 2 + llfloor(mCurPan.mV[VY]);

		gGL.pushMatrix();

		gGL.translatef( (F32) center_sw_left, (F32) center_sw_bottom, 0.f);

		static LLUICachedControl<bool> rotate_map("MiniMapRotate", true);
		if( rotate_map )
		{
			// rotate subsequent draws to agent rotation
			rotation = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] );
			gGL.rotatef( rotation * RAD_TO_DEG, 0.f, 0.f, 1.f);
		}

		// figure out where agent is
		S32 region_width = llround(LLWorld::getInstance()->getRegionWidthInMeters());

		for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
			 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
		{
			LLViewerRegion* regionp = *iter;
			// Find x and y position relative to camera's center.
			LLVector3 origin_agent = regionp->getOriginAgent();
			LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent();
			F32 relative_x = (rel_region_pos.mV[0] / region_width) * mScale;
			F32 relative_y = (rel_region_pos.mV[1] / region_width) * mScale;

			// background region rectangle
			F32 bottom =	relative_y;
			F32 left =		relative_x;
			F32 top =		bottom + mScale ;
			F32 right =		left + mScale ;

			if (regionp == gAgent.getRegion())
			{
				gGL.color4f(1.f, 1.f, 1.f, 1.f);
			}
			else
			{
				gGL.color4f(0.8f, 0.8f, 0.8f, 1.f);
			}

			if (!regionp->isAlive())
			{
				gGL.color4f(1.f, 0.5f, 0.5f, 1.f);
			}


			// Draw using texture.
			gGL.getTexUnit(0)->bind(regionp->getLand().getSTexture());
			gGL.begin(LLRender::QUADS);
				gGL.texCoord2f(0.f, 1.f);
				gGL.vertex2f(left, top);
				gGL.texCoord2f(0.f, 0.f);
				gGL.vertex2f(left, bottom);
				gGL.texCoord2f(1.f, 0.f);
				gGL.vertex2f(right, bottom);
				gGL.texCoord2f(1.f, 1.f);
				gGL.vertex2f(right, top);
			gGL.end();

			// Draw water
			gGL.setAlphaRejectSettings(LLRender::CF_GREATER, ABOVE_WATERLINE_ALPHA / 255.f);
			{
				if (regionp->getLand().getWaterTexture())
				{
					gGL.getTexUnit(0)->bind(regionp->getLand().getWaterTexture());
					gGL.begin(LLRender::QUADS);
						gGL.texCoord2f(0.f, 1.f);
						gGL.vertex2f(left, top);
						gGL.texCoord2f(0.f, 0.f);
						gGL.vertex2f(left, bottom);
						gGL.texCoord2f(1.f, 0.f);
						gGL.vertex2f(right, bottom);
						gGL.texCoord2f(1.f, 1.f);
						gGL.vertex2f(right, top);
					gGL.end();
				}
			}
			gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
		}

		// Redraw object layer periodically
		if (mUpdateNow || (map_timer.getElapsedTimeF32() > 0.5f))
		{
			mUpdateNow = false;

			// Locate the centre of the object layer, accounting for panning
			LLVector3 new_center = globalPosToView(gAgentCamera.getCameraPositionGlobal());
			new_center.mV[VX] -= mCurPan.mV[VX];
			new_center.mV[VY] -= mCurPan.mV[VY];
			new_center.mV[VZ] = 0.f;
			mObjectImageCenterGlobal = viewPosToGlobal(llfloor(new_center.mV[VX]), llfloor(new_center.mV[VY]));

			// Create the base texture.
			U8 *default_texture = mObjectRawImagep->getData();
			memset( default_texture, 0, mObjectImagep->getWidth() * mObjectImagep->getHeight() * mObjectImagep->getComponents() );

			// Draw objects
			gObjectList.renderObjectsForMap(*this);

			mObjectImagep->setSubImage(mObjectRawImagep, 0, 0, mObjectImagep->getWidth(), mObjectImagep->getHeight());
			
			map_timer.reset();
		}

		LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal);
		LLVector3 camera_position = gAgentCamera.getCameraPositionAgent();
		map_center_agent -= camera_position;
		map_center_agent.mV[VX] *= mScale/region_width;
		map_center_agent.mV[VY] *= mScale/region_width;

		gGL.getTexUnit(0)->bind(mObjectImagep);
		F32 image_half_width = 0.5f*mObjectMapPixels;
		F32 image_half_height = 0.5f*mObjectMapPixels;

		gGL.begin(LLRender::QUADS);
			gGL.texCoord2f(0.f, 1.f);
			gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, image_half_height + map_center_agent.mV[VY]);
			gGL.texCoord2f(0.f, 0.f);
			gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, map_center_agent.mV[VY] - image_half_height);
			gGL.texCoord2f(1.f, 0.f);
			gGL.vertex2f(image_half_width + map_center_agent.mV[VX], map_center_agent.mV[VY] - image_half_height);
			gGL.texCoord2f(1.f, 1.f);
			gGL.vertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]);
		gGL.end();

		gGL.popMatrix();

		// Mouse pointer in local coordinates
		S32 local_mouse_x;
		S32 local_mouse_y;
		//localMouse(&local_mouse_x, &local_mouse_y);
		LLUI::getMousePositionLocal(this, &local_mouse_x, &local_mouse_y);
		mClosestAgentToCursor.setNull();
		F32 closest_dist_squared = F32_MAX; // value will be overridden in the loop
		F32 min_pick_dist_squared = (mDotRadius * MIN_PICK_SCALE) * (mDotRadius * MIN_PICK_SCALE);

		LLVector3 pos_map;
		uuid_vec_t avatar_ids;
		std::vector<LLVector3d> positions;
		bool unknown_relative_z;

		LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, gAgentCamera.getCameraPositionGlobal());

		// Draw avatars
		for (U32 i = 0; i < avatar_ids.size(); i++)
		{
			pos_map = globalPosToView(positions[i]);
			LLUUID uuid = avatar_ids[i];

			bool show_as_friend = (LLAvatarTracker::instance().getBuddyInfo(uuid) != NULL);

			LLColor4 color = show_as_friend ? map_avatar_friend_color : map_avatar_color;

			// <FS:Ansariel> Check for unknown Z-offset => AVATAR_UNKNOWN_Z_OFFSET
			//unknown_relative_z = positions[i].mdV[VZ] == COARSEUPDATE_MAX_Z &&
			//		camera_position.mV[VZ] >= COARSEUPDATE_MAX_Z;
			unknown_relative_z = false;
			if (positions[i].mdV[VZ] == AVATAR_UNKNOWN_Z_OFFSET)
			{
				if (camera_position.mV[VZ] >= COARSEUPDATE_MAX_Z)
				{
					// No exact data and cam >=1020 => we don't know if
					// other avatar is above or below us => unknown
					unknown_relative_z = true;
				}
				else
				{
					// No exact data but cam is below 1020 => other avatar
					// is definitely above us => bump Z-offset to F32_MAX
					// so we get the up chevron
					pos_map.mV[VZ] = F32_MAX;
				}
			}
			// </FS:Ansariel>

			// Colorize muted avatars and Lindens
			std::string fullName;
			LLMuteList* muteListInstance = LLMuteList::getInstance();

			if (muteListInstance->isMuted(uuid)) color = map_avatar_muted_color;
			else if (gCacheName->getFullName(uuid, fullName) && muteListInstance->isLinden(fullName)) color = map_avatar_linden_color;			

			// Mark Avatars with special colors - Ansariel
			if (LLNetMap::sAvatarMarksMap.find(uuid) != LLNetMap::sAvatarMarksMap.end())
			{
				color = LLNetMap::sAvatarMarksMap[uuid];
			}
					
			//color based on contact sets prefs
			if(LGGContactSets::getInstance()->hasFriendColorThatShouldShow(uuid,FALSE,FALSE,FALSE,TRUE))
			{
				color = LGGContactSets::getInstance()->getFriendColor(uuid);
			}

// [RLVa:KB] - Checked: 2010-04-19 (RLVa-1.2.0f) | Modified: RLVa-1.2.0f | FS-Specific
			LLWorldMapView::drawAvatar(
				pos_map.mV[VX], pos_map.mV[VY],
				((!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? color : map_avatar_color.get()),
				pos_map.mV[VZ], mDotRadius,
				unknown_relative_z);
// [/RLVa:KB]
//			LLWorldMapView::drawAvatar(
//				pos_map.mV[VX], pos_map.mV[VY], 
//				color, 
//				pos_map.mV[VZ], mDotRadius,
//				unknown_relative_z);

			if(uuid.notNull())
			{
				bool selected = false;
				uuid_vec_t::iterator sel_iter = gmSelected.begin();
				for (; sel_iter != gmSelected.end(); sel_iter++)
				{
					if(*sel_iter == uuid)
					{
						selected = true;
						break;
					}
				}
				if(selected)
				{
					if( (pos_map.mV[VX] < 0) ||
						(pos_map.mV[VY] < 0) ||
						(pos_map.mV[VX] >= getRect().getWidth()) ||
						(pos_map.mV[VY] >= getRect().getHeight()) )
					{
						S32 x = llround( pos_map.mV[VX] );
						S32 y = llround( pos_map.mV[VY] );
						LLWorldMapView::drawTrackingCircle( getRect(), x, y, color, 1, 10);
					} else
					{
						LLWorldMapView::drawTrackingDot(pos_map.mV[VX],pos_map.mV[VY],color,0.f);
					}
				}
			}

			F32	dist_to_cursor_squared = dist_vec_squared(LLVector2(pos_map.mV[VX], pos_map.mV[VY]),
											LLVector2(local_mouse_x,local_mouse_y));
			if(dist_to_cursor_squared < min_pick_dist_squared && dist_to_cursor_squared < closest_dist_squared)
			{
				closest_dist_squared = dist_to_cursor_squared;
				mClosestAgentToCursor = uuid;
				mClosestAgentPosition = positions[i];
			}
		}

		// Draw dot for autopilot target
		if (gAgent.getAutoPilot())
		{
			drawTracking( gAgent.getAutoPilotTargetGlobal(), map_track_color );
		}
		else
		{
			LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus();
			if (  LLTracker::TRACKING_AVATAR == tracking_status )
			{
				drawTracking( LLAvatarTracker::instance().getGlobalPos(), map_track_color );
			} 
			else if ( LLTracker::TRACKING_LANDMARK == tracking_status 
					|| LLTracker::TRACKING_LOCATION == tracking_status )
			{
				drawTracking( LLTracker::getTrackedPositionGlobal(), map_track_color );
			}
		}

		// Draw dot for self avatar position
		LLVector3d pos_global = gAgent.getPositionGlobal();
		pos_map = globalPosToView(pos_global);
		S32 dot_width = llround(mDotRadius * 2.f);
		LLUIImagePtr you = LLWorldMapView::sAvatarYouLargeImage;
		if (you)
		{
			you->draw(llround(pos_map.mV[VX] - mDotRadius),
					  llround(pos_map.mV[VY] - mDotRadius),
					  dot_width,
					  dot_width);

			F32	dist_to_cursor_squared = dist_vec_squared(LLVector2(pos_map.mV[VX], pos_map.mV[VY]),
										  LLVector2(local_mouse_x,local_mouse_y));
			if(dist_to_cursor_squared < min_pick_dist_squared && dist_to_cursor_squared < closest_dist_squared)
			{
				mClosestAgentToCursor = gAgent.getID();
				mClosestAgentPosition = pos_global;
			}

			// Draw chat range ring(s)
			static LLUICachedControl<bool> chat_ring("MiniMapChatRing", true);
			if(chat_ring)
			{
				drawRing(LLWorld::getInstance()->getSayDistance(), pos_map, map_chat_ring_color);
				drawRing(LLWorld::getInstance()->getShoutDistance(), pos_map, map_shout_ring_color);
			}
		}

		// Draw frustum
		F32 meters_to_pixels = mScale/ LLWorld::getInstance()->getRegionWidthInMeters();

		F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect();
		F32 far_clip_meters = LLViewerCamera::getInstance()->getFar();
		F32 far_clip_pixels = far_clip_meters * meters_to_pixels;

		F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 );
		F32 half_width_pixels = half_width_meters * meters_to_pixels;
		
		F32 ctr_x = (F32)center_sw_left;
		F32 ctr_y = (F32)center_sw_bottom;


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

		if( rotate_map )
		{
			gGL.color4fv((map_frustum_color()).mV);

			gGL.begin( LLRender::TRIANGLES  );
				gGL.vertex2f( ctr_x, ctr_y );
				gGL.vertex2f( ctr_x - half_width_pixels, ctr_y + far_clip_pixels );
				gGL.vertex2f( ctr_x + half_width_pixels, ctr_y + far_clip_pixels );
			gGL.end();
		}
		else
		{
			gGL.color4fv((map_frustum_rotating_color()).mV);
			
			// If we don't rotate the map, we have to rotate the frustum.
			gGL.pushMatrix();
				gGL.translatef( ctr_x, ctr_y, 0 );
				gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f);
				gGL.begin( LLRender::TRIANGLES  );
					gGL.vertex2f( 0, 0 );
					gGL.vertex2f( -half_width_pixels, far_clip_pixels );
					gGL.vertex2f(  half_width_pixels, far_clip_pixels );
				gGL.end();
			gGL.popMatrix();
		}
	}
	
	gGL.popMatrix();
	gGL.popUIMatrix();

	LLUICtrl::draw();
}
Beispiel #24
0
//static 
void LLViewerChat::getChatColor(const LLChat& chat, LLColor4& r_color, bool is_local)
{
	if(chat.mMuted)
	{
		r_color= LLUIColorTable::instance().getColor("LtGray");
	}
	else
	{
		switch(chat.mSourceType)
		{
			case CHAT_SOURCE_SYSTEM:
				r_color = LLUIColorTable::instance().getColor("SystemChatColor"); 
				break;
			case CHAT_SOURCE_AGENT:
				if (chat.mFromID.isNull() || SYSTEM_FROM == chat.mFromName)
				{
					r_color = LLUIColorTable::instance().getColor("SystemChatColor");
				}
				else
				{
					if(gAgentID == chat.mFromID)
					{
						r_color = LLUIColorTable::instance().getColor("UserChatColor");
					}
					else
					{
						r_color = LLUIColorTable::instance().getColor("AgentChatColor");
					}
					//color based on contact sets prefs
					if(LGGContactSets::getInstance()->hasFriendColorThatShouldShow(chat.mFromID,TRUE))
					{
						r_color = LGGContactSets::getInstance()->getFriendColor(chat.mFromID);
					}
				}
				break;
			case CHAT_SOURCE_OBJECT:
				if (chat.mChatType == CHAT_TYPE_DEBUG_MSG)
				{
					r_color = LLUIColorTable::instance().getColor("ScriptErrorColor");
				}
				else if ( chat.mChatType == CHAT_TYPE_OWNER )
				{
					r_color = LLUIColorTable::instance().getColor("llOwnerSayChatColor");
				}
				else if ( chat.mChatType == CHAT_TYPE_DIRECT )
				{
					r_color = LLUIColorTable::instance().getColor("DirectChatColor");
				}
				else if ( chat.mChatType == CHAT_TYPE_IM )
				{
					r_color = LLUIColorTable::instance().getColor("ObjectIMColor");
				}
				else
				{
					r_color = LLUIColorTable::instance().getColor("ObjectChatColor");
				}
				break;
			default:
				r_color.setToWhite();
		}
		
		//Keyword alerts -KC
		if ((gAgentID != chat.mFromID || chat.mFromName == SYSTEM_FROM) && FSKeywords::getInstance()->chatContainsKeyword(chat, is_local))
		{
			std::string msg = chat.mFromName;
			std::string prefix = chat.mText.substr(0, 4);
			if(prefix == "/me " || prefix == "/me'")
			{
				msg = msg + chat.mText.substr(3);
			}
			else
			{
				msg = msg + ": " + chat.mText;
			}
#if LL_WINDOWS
			gGrowlManager->notify("Keyword Alert", msg, "Keyword Alert");
#endif
			static LLCachedControl<bool> sFSKeywordChangeColor(gSavedPerAccountSettings, "FSKeywordChangeColor");
			if (sFSKeywordChangeColor)
			{
				static LLCachedControl<LLColor4> sFSKeywordColor(gSavedPerAccountSettings, "FSKeywordColor");
				r_color = sFSKeywordColor;
			}
		}
		
		if (!chat.mPosAgent.isExactlyZero())
		{
			LLVector3 pos_agent = gAgent.getPositionAgent();
			F32 distance_squared = dist_vec_squared(pos_agent, chat.mPosAgent);
			F32 dist_near_chat = LLWorld::getInstance()->getSayDistance();
			if (distance_squared > dist_near_chat * dist_near_chat)
			{
				// diminish far-off chat
				r_color.mV[VALPHA] = 0.8f;
			}
		}
	}
}