Esempio n. 1
0
static void postcard_upload_callback(const LLUUID& asset_id, void *user_data, S32 result, LLExtStat ext_status)
{
	LLSD* postcard_data = (LLSD*)user_data;

	if (result)
	{
		// TODO: display the error messages in UI
		llwarns << "Failed to send postcard: " << LLAssetStorage::getErrorString(result) << llendl;
		LLPostCard::reportPostResult(false);
	}
	else
	{
		// only create the postcard once the upload succeeds

		// request the postcard
		const LLSD& data = *postcard_data;
		LLMessageSystem* msg = gMessageSystem;
		msg->newMessage("SendPostcard");
		msg->nextBlock("AgentData");
		msg->addUUID("AgentID",			gAgent.getID());
		msg->addUUID("SessionID",		gAgent.getSessionID());
		msg->addUUID("AssetID",			data["asset-id"].asUUID());
		msg->addVector3d("PosGlobal",	LLVector3d(data["pos-global"]));
		msg->addString("To",			data["to"]);
		msg->addString("From",			data["from"]);
		msg->addString("Name",			data["name"]);
		msg->addString("Subject",		data["subject"]);
		msg->addString("Msg",			data["msg"]);
		msg->addBOOL("AllowPublish",	FALSE);
		msg->addBOOL("MaturePublish",	FALSE);
		gAgent.sendReliableMessage();

		LLPostCard::reportPostResult(true);
	}

	delete postcard_data;
}
Esempio n. 2
0
void LLSurface::initTextures()
{
	///////////////////////
	//
	// Main surface texture
	//
	createSTexture();

	///////////////////////
	//
	// Water texture
	//
	if (gSavedSettings.getBOOL("RenderWater") )
	{
		createWaterTexture();
		mWaterObjp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, mRegionp);
		gPipeline.createObject(mWaterObjp);
		LLVector3d water_pos_global = from_region_handle(mRegionp->getHandle());
		//water_pos_global += LLVector3d(128.0, 128.0, DEFAULT_WATER_HEIGHT);
		//added line below var sams
		water_pos_global += LLVector3d(mRegionp->getWidth()/2, mRegionp->getWidth()/2, DEFAULT_WATER_HEIGHT);
		mWaterObjp->setPositionGlobal(water_pos_global);
	}
}
void LLHUDEffectBeam::setupParticle(const S32 i)
{
	LLVector3d start_pos_global;
	if (mSourceObject->getPCode() == LL_PCODE_LEGACY_AVATAR)
	{
		LLViewerObject *objp = mSourceObject;
		LLVOAvatar *avatarp = (LLVOAvatar *)objp;
		start_pos_global = gAgent.getPosGlobalFromAgent(avatarp->mWristLeftp->getWorldPosition());
	}
	else
	{
		start_pos_global = mSourceObject->getPositionGlobal();
	}

	// Generate a random offset for the target point.
	const F32 SCALE = 0.5f;
	F32 x, y, z;
	x = ll_frand(SCALE) - 0.5f*SCALE;
	y = ll_frand(SCALE) - 0.5f*SCALE;
	z = ll_frand(SCALE) - 0.5f*SCALE;

	LLVector3d target_pos_global(mTargetPos);
	target_pos_global += LLVector3d(x, y, z);

	mInterp[i].setStartTime(mInterp[i].getEndTime());
	mInterp[i].setEndTime(mInterp[i].getStartTime() + BEAM_SPACING*NUM_POINTS);
	mInterp[i].setStartVal(start_pos_global);
	mInterp[i].setEndVal(target_pos_global);
	mInterp[i].start();


	// Setup the interpolator that fades out the alpha.
	mInterpFade[i].setStartTime(mInterp[i].getStartTime() + BEAM_SPACING*NUM_POINTS - 0.5f*NUM_POINTS*BEAM_SPACING);
	mInterpFade[i].setEndTime(mInterp[i].getStartTime() + BEAM_SPACING*NUM_POINTS - 0.05f);
	mInterpFade[i].start();
}
Esempio n. 4
0
void test_cached_control()
{
    static const LLCachedControl<std::string> mySetting_string("TestCachedControlstring", "Default String Value");
    static const LLCachedControl<std::string> test_BrowserHomePage("BrowserHomePage", "hahahahahha", "Not the real comment");

#define TEST_LLCC(T, V) if((T)mySetting_##T != V) llerrs << "Fail "#T << llendl; \
						mySetting_##T = V;\
						if((T)mySetting_##T != V) llerrs << "Fail "#T << "Pass # 2" << llendl;

    TEST_LLCC(U32, 666);
    TEST_LLCC(S32, (S32)-666);
    TEST_LLCC(F32, (F32)-666.666);
    TEST_LLCC(bool, true);
    TEST_LLCC(BOOL, FALSE);
    if((std::string)mySetting_string != "Default String Value") llerrs << "Fail string" << llendl;
    TEST_LLCC(LLVector3, LLVector3(1.0f, 2.0f, 3.0f));
    TEST_LLCC(LLVector3d, LLVector3d(6.0f, 5.0f, 4.0f));
    TEST_LLCC(LLRect, LLRect(0, 0, 100, 500));
    TEST_LLCC(LLColor4, LLColor4(0.0f, 0.5f, 1.0f));
    TEST_LLCC(LLColor3, LLColor3(1.0f, 0.f, 0.5f));
//There's no LLSD comparsion for LLCC yet. TEST_LLCC(LLSD, test_llsd);

    if((std::string)test_BrowserHomePage != "http://www.singularityviewer.org") llerrs << "Fail BrowserHomePage" << llendl;
}
/*static*/
void LLURLDispatcherImpl::regionNameCallback(U64 region_handle, const std::string& url, const LLUUID& snapshot_id, bool teleport)
{
	std::string sim_string = stripProtocol(url);
	std::string region_name;
	S32 x = 128;
	S32 y = 128;
	S32 z = 0;
	LLURLSimString::parse(sim_string, &region_name, &x, &y, &z);

	LLVector3 local_pos;
	local_pos.mV[VX] = (F32)x;
	local_pos.mV[VY] = (F32)y;
	local_pos.mV[VZ] = (F32)z;

	
	// determine whether the point is in this region
	if ((x >= 0) && (x < REGION_WIDTH_UNITS) &&
		(y >= 0) && (y < REGION_WIDTH_UNITS))
	{
		// if so, we're done
		regionHandleCallback(region_handle, url, snapshot_id, teleport);
	}

	else
	{
		// otherwise find the new region from the location
		
		// add the position to get the new region
		LLVector3d global_pos = from_region_handle(region_handle) + LLVector3d(local_pos);

		U64 new_region_handle = to_region_handle(global_pos);
		LLWorldMap::getInstance()->sendHandleRegionRequest(new_region_handle,
										   LLURLDispatcherImpl::regionHandleCallback,
										   url, teleport);
	}
}
void LLToolCamera::pickCallback(const LLPickInfo& pick_info)
{
	if (!LLToolCamera::getInstance()->hasMouseCapture())
	{
		return;
	}

	LLToolCamera::getInstance()->mMouseDownX = pick_info.mMousePt.mX;
	LLToolCamera::getInstance()->mMouseDownY = pick_info.mMousePt.mY;

	gViewerWindow->moveCursorToCenter();

	// Potentially recenter if click outside rectangle
	LLViewerObject* hit_obj = pick_info.getObject();

	// Check for hit the sky, or some other invalid point
	if (!hit_obj && pick_info.mPosGlobal.isExactlyZero())
	{
		LLToolCamera::getInstance()->mValidClickPoint = FALSE;
		return;
	}

	// check for hud attachments
	if (hit_obj && hit_obj->isHUDAttachment())
	{
		LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
		if (!selection->getObjectCount() || selection->getSelectType() != SELECT_TYPE_HUD)
		{
			LLToolCamera::getInstance()->mValidClickPoint = FALSE;
			return;
		}
	}

	if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode() )
	{
		BOOL good_customize_avatar_hit = FALSE;
		if( hit_obj )
		{
			LLVOAvatar* avatar = gAgent.getAvatarObject();
			if( hit_obj == avatar) 
			{
				// It's you
				good_customize_avatar_hit = TRUE;
			}
			else
			if( hit_obj->isAttachment() && hit_obj->permYouOwner() )
			{
				// It's an attachment that you're wearing
				good_customize_avatar_hit = TRUE;
			}
		}

		if( !good_customize_avatar_hit )
		{
			LLToolCamera::getInstance()->mValidClickPoint = FALSE;
			return;
		}

		if( gMorphView )
		{
			gMorphView->setCameraDrivenByKeys( FALSE );
		}
	}
	//RN: check to see if this is mouse-driving as opposed to ALT-zoom or Focus tool
	else if (pick_info.mKeyMask & MASK_ALT || 
			(LLToolMgr::getInstance()->getCurrentTool()->getName() == "Camera")) 
	{
		LLViewerObject* hit_obj = pick_info.getObject();
		if (hit_obj)
		{
			// ...clicked on a world object, so focus at its position
			if (!hit_obj->isHUDAttachment())
			{
				gAgent.setFocusOnAvatar(FALSE, ANIMATE);
				gAgent.setFocusGlobal(pick_info);
			}
		}
		else if (!pick_info.mPosGlobal.isExactlyZero())
		{
			// Hit the ground
			gAgent.setFocusOnAvatar(FALSE, ANIMATE);
			gAgent.setFocusGlobal(pick_info);
		}

		static const LLCachedControl<bool> freeze_time("FreezeTime",0);
		if (!(pick_info.mKeyMask & MASK_ALT) &&
			gAgent.cameraThirdPerson() &&
			gViewerWindow->getLeftMouseDown() && 
			!freeze_time &&
			(hit_obj == gAgent.getAvatarObject() || 
				(hit_obj && hit_obj->isAttachment() && LLVOAvatar::findAvatarFromAttachment(hit_obj)->isSelf())))
		{
			LLToolCamera::getInstance()->mMouseSteering = TRUE;
		}

	}

	LLToolCamera::getInstance()->mValidClickPoint = TRUE;

	if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode() )
	{
		gAgent.setFocusOnAvatar(FALSE, FALSE);
		
		LLVector3d cam_pos = gAgent.getCameraPositionGlobal();
		cam_pos -= LLVector3d(LLViewerCamera::getInstance()->getLeftAxis() * gAgent.calcCustomizeAvatarUIOffset( cam_pos ));

		gAgent.setCameraPosAndFocusGlobal( cam_pos, pick_info.mPosGlobal, pick_info.mObjectID);
	}
}
Esempio n. 7
0
F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const
{
	if (x >= 256)
	{
		if (y >= 256)
		{
			LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 256.f, 0.f);
			LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
			if (regionp)
			{
				// OK, we need to do some hackery here - different simulators no longer use
				// the same composition values, necessarily.
				// If we're attempting to blend, then we want to make the fractional part of
				// this region match the fractional of the adjacent.  For now, just minimize
				// the delta.
				F32 our_comp = getComposition()->getValueScaled(255, 255);
				F32 adj_comp = regionp->getComposition()->getValueScaled(x - 256.f, y - 256.f);
				while (llabs(our_comp - adj_comp) >= 1.f)
				{
					if (our_comp > adj_comp)
					{
						adj_comp += 1.f;
					}
					else
					{
						adj_comp -= 1.f;
					}
				}
				return adj_comp;
			}
		}
		else
		{
			LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 0, 0.f);
			LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
			if (regionp)
			{
				// OK, we need to do some hackery here - different simulators no longer use
				// the same composition values, necessarily.
				// If we're attempting to blend, then we want to make the fractional part of
				// this region match the fractional of the adjacent.  For now, just minimize
				// the delta.
				F32 our_comp = getComposition()->getValueScaled(255.f, (F32)y);
				F32 adj_comp = regionp->getComposition()->getValueScaled(x - 256.f, (F32)y);
				while (llabs(our_comp - adj_comp) >= 1.f)
				{
					if (our_comp > adj_comp)
					{
						adj_comp += 1.f;
					}
					else
					{
						adj_comp -= 1.f;
					}
				}
				return adj_comp;
			}
		}
	}
	else if (y >= 256)
	{
		LLVector3d center = getCenterGlobal() + LLVector3d(0.f, 256.f, 0.f);
		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
		if (regionp)
		{
			// OK, we need to do some hackery here - different simulators no longer use
			// the same composition values, necessarily.
			// If we're attempting to blend, then we want to make the fractional part of
			// this region match the fractional of the adjacent.  For now, just minimize
			// the delta.
			F32 our_comp = getComposition()->getValueScaled((F32)x, 255.f);
			F32 adj_comp = regionp->getComposition()->getValueScaled((F32)x, y - 256.f);
			while (llabs(our_comp - adj_comp) >= 1.f)
			{
				if (our_comp > adj_comp)
				{
					adj_comp += 1.f;
				}
				else
				{
					adj_comp -= 1.f;
				}
			}
			return adj_comp;
		}
	}

	return getComposition()->getValueScaled((F32)x, (F32)y);
}
Esempio n. 8
0
void LLToolMgr::toggleBuildMode()
{
    if (inBuildMode())
    {
        if (gSavedSettings.getBOOL("EditCameraMovement"))
        {
            // just reset the view, will pull us out of edit mode
            handle_reset_view();
        }
        else
        {
            // manually disable edit mode, but do not affect the camera
            gAgentCamera.resetView(false);
            gFloaterTools->close();
            gViewerWindow->showCursor();
        }
        // avoid spurious avatar movements pulling out of edit mode
        LLViewerJoystick::getInstance()->setNeedsReset();
    }
    else
    {
        ECameraMode camMode = gAgentCamera.getCameraMode();
        if (CAMERA_MODE_MOUSELOOK == camMode ||	CAMERA_MODE_CUSTOMIZE_AVATAR == camMode)
        {
            // pull the user out of mouselook or appearance mode when entering build mode
            handle_reset_view();
        }

        if (gSavedSettings.getBOOL("EditCameraMovement"))
        {
            // camera should be set
            if (LLViewerJoystick::getInstance()->getOverrideCamera())
            {
                handle_toggle_flycam();
            }

            if (gAgentCamera.getFocusOnAvatar())
            {
                // zoom in if we're looking at the avatar
                gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
                gAgentCamera.setFocusGlobal(gAgent.getPositionGlobal() + 2.0 * LLVector3d(gAgent.getAtAxis()));
                gAgentCamera.cameraZoomIn(0.666f);
                gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD );
            }
        }

// [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b)
        bool fRlvCanEdit = (!gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) && (!gRlvHandler.hasBehaviour(RLV_BHVR_EDITOBJ));
        if (!fRlvCanEdit)
        {
            LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection();
            RlvSelectIsEditable f;
            if ((hSel.notNull()) && ((hSel->getFirstRootNode(&f, TRUE)) != NULL))
                LLSelectMgr::getInstance()->deselectAll();
        }
// [/RLVa:KB]

        setCurrentToolset(gBasicToolset);
        getCurrentToolset()->selectTool( LLToolCompCreate::getInstance() );

        // Could be first use
        LLFirstUse::useBuild();

        gAgentCamera.resetView(false);

        // avoid spurious avatar movements
        LLViewerJoystick::getInstance()->setNeedsReset();

    }
}
Esempio n. 9
0
void LLToolMgr::toggleBuildMode(const LLSD& sdname)
{
	const std::string& param = sdname.asString();

// [RLVa:KB] - Checked: 2012-04-26 (RLVa-1.4.6) | Added: RLVa-1.4.6 | Ansa: Changed because of FIRE-5552
	//if (param == "build" && !canEdit())
	if (param == "build" && !RlvUIEnabler::isBuildEnabled())
// [/RLVa:KB]
	{
		return;
	}

	LLFloaterReg::toggleInstanceOrBringToFront("build");

	bool build_visible = LLFloaterReg::instanceVisible("build");
	if (build_visible)
	{
		ECameraMode camMode = gAgentCamera.getCameraMode();
		if (CAMERA_MODE_MOUSELOOK == camMode ||	CAMERA_MODE_CUSTOMIZE_AVATAR == camMode)
		{
			// pull the user out of mouselook or appearance mode when entering build mode
			handle_reset_view();
		}

		if (gSavedSettings.getBOOL("EditCameraMovement"))
		{
			// camera should be set
			if (LLViewerJoystick::getInstance()->getOverrideCamera())
			{
				handle_toggle_flycam();
			}

			if (gAgentCamera.getFocusOnAvatar())
			{
				// zoom in if we're looking at the avatar
				gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
				gAgentCamera.setFocusGlobal(gAgent.getPositionGlobal() + 2.0 * LLVector3d(gAgent.getAtAxis()));
				gAgentCamera.cameraZoomIn(0.666f);
				gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD );
			}
		}


		setCurrentToolset(gBasicToolset);
		getCurrentToolset()->selectTool( LLToolCompCreate::getInstance() );

		// Could be first use
		//LLFirstUse::useBuild();

		gAgentCamera.resetView(false);

		// avoid spurious avatar movements
		LLViewerJoystick::getInstance()->setNeedsReset();

	}
	else
	{
		if (gSavedSettings.getBOOL("EditCameraMovement"))
		{
			// just reset the view, will pull us out of edit mode
			handle_reset_view();
		}
		else
		{
			// manually disable edit mode, but do not affect the camera
			gAgentCamera.resetView(false);
			LLFloaterReg::hideInstance("build");
			gViewerWindow->showCursor();			
		}
		// avoid spurious avatar movements pulling out of edit mode
		LLViewerJoystick::getInstance()->setNeedsReset();
	}

}
	out = in;
	return TYPE_LLSD; 
}


#if TEST_CACHED_CONTROL

#define DECL_LLCC(T, V) static LLCachedControl<T> mySetting_##T("TestCachedControl"#T, V)
DECL_LLCC(U32, (U32)666);
DECL_LLCC(S32, (S32)-666);
DECL_LLCC(F32, (F32)-666.666);
DECL_LLCC(bool, true);
DECL_LLCC(BOOL, FALSE);
static LLCachedControl<std::string> mySetting_string("TestCachedControlstring", "Default String Value");
DECL_LLCC(LLVector3, LLVector3(1.0f, 2.0f, 3.0f));
DECL_LLCC(LLVector3d, LLVector3d(6.0f, 5.0f, 4.0f));
DECL_LLCC(LLRect, LLRect(0, 0, 100, 500));
DECL_LLCC(LLColor4, LLColor4(0.0f, 0.5f, 1.0f));
DECL_LLCC(LLColor3, LLColor3(1.0f, 0.f, 0.5f));
DECL_LLCC(LLColor4U, LLColor4U(255, 200, 100, 255));

LLSD test_llsd = LLSD()["testing1"] = LLSD()["testing2"];
DECL_LLCC(LLSD, test_llsd);

static LLCachedControl<std::string> test_BrowserHomePage("BrowserHomePage", "hahahahahha", "Not the real comment");

void test_cached_control()
{
#define TEST_LLCC(T, V) if((T)mySetting_##T != V) llerrs << "Fail "#T << llendl
	TEST_LLCC(U32, 666);
	TEST_LLCC(S32, (S32)-666);
#include "lluictrlfactory.h"
#include "llscrolllistctrl.h"

#include "llagent.h"
#include "lltracker.h"
#include "llviewerobjectlist.h"
#include "llviewercontrol.h"
#include "jcfloaterareasearch.h"

JCFloaterAreaSearch* JCFloaterAreaSearch::sInstance = NULL;
LLViewerRegion* JCFloaterAreaSearch::sLastRegion = NULL;
S32 JCFloaterAreaSearch::sRequested = 0;
bool JCFloaterAreaSearch::sIsDirty = false;
bool JCFloaterAreaSearch::sTracking = false;
LLUUID JCFloaterAreaSearch::sTrackingObjectID = LLUUID::null;
LLVector3d JCFloaterAreaSearch::sTrackingLocation = LLVector3d();
std::string JCFloaterAreaSearch::sTrackingInfoLine;
std::map<LLUUID, AObjectDetails> JCFloaterAreaSearch::sObjectDetails;
std::string JCFloaterAreaSearch::sSearchedName;
std::string JCFloaterAreaSearch::sSearchedDesc;
std::string JCFloaterAreaSearch::sSearchedOwner;
std::string JCFloaterAreaSearch::sSearchedGroup;

const std::string REQUEST_STRING = "JCFloaterAreaSearch::Requested_ø§µ";
const F32 min_refresh_interval = 0.25f;	// Minimum interval between list refreshes in seconds.

JCFloaterAreaSearch::JCFloaterAreaSearch() :  
	LLFloater(),
	mCounterText(NULL),
	mResultList(NULL)
{
// This is called when user presses enter in the location input
// or selects a location from the typed locations dropdown.
void LLNavigationBar::onLocationSelection()
{
	std::string typed_location = mCmbLocation->getSimple();
	LLStringUtil::trim(typed_location);

	// Will not teleport to empty location.
	if (typed_location.empty())
		return;
	//get selected item from combobox item
	LLSD value = mCmbLocation->getSelectedValue();
	if(value.isUndefined() && !mCmbLocation->getTextEntry()->isDirty())
	{
		// At this point we know that: there is no selected item in list and text field has NOT been changed
		// So there is no sense to try to change the location
		return;
	}
	/* since navbar list support autocompletion it contains several types of item: landmark, teleport hystory item,
	 * typed by user slurl or region name. Let's find out which type of item the user has selected 
	 * to make decision about adding this location into typed history. see mSaveToLocationHistory
	 * Note:
	 * Only TYPED_REGION_SLURL item will be added into LLLocationHistory 
	 */  
	
	if(value.has("item_type"))
	{

		switch(value["item_type"].asInteger())
		{
		case LANDMARK:
			
			if(value.has("AssetUUID"))
			{
				
				gAgent.teleportViaLandmark( LLUUID(value["AssetUUID"].asString()));
				return;
			}
			else
			{
				LLInventoryModel::item_array_t landmark_items =
						LLLandmarkActions::fetchLandmarksByName(typed_location,
								FALSE);
				if (!landmark_items.empty())
				{
					gAgent.teleportViaLandmark( landmark_items[0]->getAssetUUID());
					return; 
				}
			}
			break;
			
		case TELEPORT_HISTORY:
			//in case of teleport item was selected, teleport by position too.
		case TYPED_REGION_SLURL:
			if(value.has("global_pos"))
			{
				gAgent.teleportViaLocation(LLVector3d(value["global_pos"]));
				return;
			}
			break;
			
		default:
			break;		
		}
	}
	//Let's parse slurl or region name
	
	std::string region_name;
	LLVector3 local_coords(128, 128, 0);
	S32 x = 0, y = 0, z = 0;
	// Is the typed location a SLURL?
	if (LLSLURL::isSLURL(typed_location))
	{
		// Yes. Extract region name and local coordinates from it.
		if (LLURLSimString::parse(LLSLURL::stripProtocol(typed_location), &region_name, &x, &y, &z))
				local_coords.set(x, y, z);
		else
			return;
	}
	// we have to do this check after previous, because LLUrlRegistry contains handlers for slurl too  
	//but we need to know whether typed_location is a simple http url.
	else if (LLUrlRegistry::instance().isUrl(typed_location)) 
	{
		// display http:// URLs in the media browser, or
		// anything else is sent to the search floater
		LLWeb::loadURL(typed_location);
		return;
	}
	else
	{
		// assume that an user has typed the {region name} or possible {region_name, parcel}
		region_name  = typed_location.substr(0,typed_location.find(','));
	}
	
	// Resolve the region name to its global coordinates.
	// If resolution succeeds we'll teleport.
	LLWorldMapMessage::url_callback_t cb = boost::bind(
			&LLNavigationBar::onRegionNameResponse, this,
			typed_location, region_name, local_coords, _1, _2, _3, _4);
	mSaveToLocationHistory = true;
	LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name, cb, std::string("unused"), false);
}
Esempio n. 13
0
void LLSpatialBridge::shiftPos(const LLVector3& vec)
{
	mExtents[0] += vec;
	mExtents[1] += vec;
	mPositionGroup += LLVector3d(vec);
}
LLVector3d	LLWorld::clipToVisibleRegions(const LLVector3d &start_pos, const LLVector3d &end_pos)
{
	if (positionRegionValidGlobal(end_pos))
	{
		return end_pos;
	}

	LLViewerRegion* regionp = getRegionFromPosGlobal(start_pos);
	if (!regionp) 
	{
		return start_pos;
	}

	LLVector3d delta_pos = end_pos - start_pos;
	LLVector3d delta_pos_abs;
	delta_pos_abs.setVec(delta_pos);
	delta_pos_abs.abs();

	LLVector3 region_coord = regionp->getPosRegionFromGlobal(end_pos);
	F64 clip_factor = 1.0;
	F32 region_width = regionp->getWidth();
	if (region_coord.mV[VX] < 0.f)
	{
		if (region_coord.mV[VY] < region_coord.mV[VX])
		{
			// clip along y -
			clip_factor = -(region_coord.mV[VY] / delta_pos_abs.mdV[VY]);
		}
		else
		{
			// clip along x -
			clip_factor = -(region_coord.mV[VX] / delta_pos_abs.mdV[VX]);
		}
	}
	else if (region_coord.mV[VX] > region_width)
	{
		if (region_coord.mV[VY] > region_coord.mV[VX])
		{
			// clip along y +
			clip_factor = (region_coord.mV[VY] - region_width) / delta_pos_abs.mdV[VY];
		}
		else
		{
			//clip along x +
			clip_factor = (region_coord.mV[VX] - region_width) / delta_pos_abs.mdV[VX];
		}
	}
	else if (region_coord.mV[VY] < 0.f)
	{
		// clip along y -
		clip_factor = -(region_coord.mV[VY] / delta_pos_abs.mdV[VY]);
	}
	else if (region_coord.mV[VY] > region_width)
	{ 
		// clip along y +
		clip_factor = (region_coord.mV[VY] - region_width) / delta_pos_abs.mdV[VY];
	}

	// clamp to < 256 to stay in sim
	LLVector3d final_region_pos = LLVector3d(region_coord) - (delta_pos * clip_factor);
	final_region_pos.clamp(0.0, 255.999);
	return regionp->getPosGlobalFromRegion(LLVector3(final_region_pos));
}
void LLTeleportHistory::updateCurrentLocation(const LLVector3d& new_pos)
{
	if (!mTeleportHistoryStorage)
	{
		mTeleportHistoryStorage = LLTeleportHistoryStorage::getInstance();
	}
	if (mRequestedItem != -1) // teleport within the history in progress?
	{
		mCurrentItem = mRequestedItem;
		mRequestedItem = -1;
	}
	else
	{
		//EXT-7034
		//skip initial update if agent avatar is no valid yet
		//this may happen when updateCurrentLocation called while login process
		//sometimes isAgentAvatarValid return false and in this case new_pos
		//(which actually is gAgent.getPositionGlobal() ) is invalid
		//if this position will be saved then teleport back will teleport user to wrong position
		if ( !mGotInitialUpdate && !isAgentAvatarValid() )
		{
			return ;
		}

		// If we're getting the initial location update
		// while we already have a (loaded) non-empty history,
		// there's no need to purge forward items or add a new item.

		if (mGotInitialUpdate || mItems.size() == 0)
		{
			// Purge forward items (if any).
			if(mItems.size())
				mItems.erase (mItems.begin() + mCurrentItem + 1, mItems.end());
			
			// Append an empty item to the history and make it current.
//			mItems.push_back(LLTeleportHistoryItem("", LLVector3d()));
//			mCurrentItem++;
// [RLVa:KB] - Checked: 2010-09-03 (RLVa-1.2.1b) | Added: RLVa-1.2.1b
			// Only append a new item if the list is currently empty or if not @showloc=n restricted and the last entry wasn't zero'ed out
			if ( (mItems.size() == 0) || ((!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) && (!mItems.back().mGlobalPos.isExactlyZero())) )
			{
				mItems.push_back(LLTeleportHistoryItem("", LLVector3d()));
				mCurrentItem++;
			}
// [RLVa:KB]
		}

		// Update current history item.
		if (mCurrentItem < 0 || mCurrentItem >= (int) mItems.size()) // sanity check
		{
			llwarns << "Invalid current item. (this should not happen)" << llendl;
			llassert(!"Invalid current teleport history item");
			return;
		}

// [RLVa:KB] - Checked: 2010-09-03 (RLVa-1.2.1b) | Added: RLVa-1.2.1b
		if (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))
		{
// [/RLVa:KB]
			LLVector3 new_pos_local = gAgent.getPosAgentFromGlobal(new_pos);
			mItems[mCurrentItem].mFullTitle = getCurrentLocationTitle(true, new_pos_local);
			mItems[mCurrentItem].mTitle = getCurrentLocationTitle(false, new_pos_local);
			mItems[mCurrentItem].mGlobalPos	= new_pos;
			mItems[mCurrentItem].mRegionID = gAgent.getRegion()->getRegionID();
// [RLVa:KB] - Checked: 2010-09-03 (RLVa-1.2.1b) | Added: RLVa-1.2.1b
		}
		else
		{
			mItems[mCurrentItem] = LLTeleportHistoryItem(RlvStrings::getString(RLV_STRING_HIDDEN_PARCEL), LLVector3d::zero);
		}
// [/RLVa:KB]
	}

	dump();
	
	if (!mGotInitialUpdate)
		mGotInitialUpdate = true;

	// Signal the interesting party that we've changed. 
	onHistoryChanged();
}
// This function selects an ideal viewing distance given a selection bounding box, normal, and padding value
void LLViewerMediaFocus::setCameraZoom(F32 padding_factor)
{
	LLPickInfo& pick = LLToolPie::getInstance()->getPick();

	if(LLSelectMgr::getInstance()->getSelection()->isEmpty())
	{
		pick = mPickInfo;
		setFocusFace(true, pick.getObject(), pick.mObjectFace, mMediaImpl);
	}

	if (!LLSelectMgr::getInstance()->getSelection()->isEmpty())
	{
		gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);

		LLBBox selection_bbox = LLSelectMgr::getInstance()->getBBoxOfSelection();
		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(selection_bbox, pick.mNormal, &height, &width, &depth);
		F32 camera_aspect = LLViewerCamera::getInstance()->getAspect();

		// 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 );
		}
		else
		{
			angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getView());
			distance = height * 0.5 * padding_factor / tan(angle_of_view * 0.5f );
		}

		distance += depth * 0.5;

		// Finally animate the camera to this new position and focal point
		gAgentCamera.setCameraPosAndFocusGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal() + LLVector3d(pick.mNormal * distance), 
			LLSelectMgr::getInstance()->getSelectionCenterGlobal(), LLSelectMgr::getInstance()->getSelection()->getFirstObject()->mID );
	}
}
Esempio n. 17
0
// static
void LLKeyTool::openKey(LLUUID id, LLKeyType key_type, LLAssetType::EType asset_type)
{
	if(key_type == LLKeyTool::KT_ASSET)
	{
		LLLocalInventory::addItem(id.asString(), int(asset_type), id, TRUE);
	}
	else if(key_type == LLKeyTool::KT_AGENT)
	{
		LLFloaterAvatarInfo::show(id);
	}
	else if(key_type == LLKeyTool::KT_GROUP)
	{
		LLFloaterGroupInfo::showFromUUID(id);
	}
	else if(key_type == LLKeyTool::KT_REGION)
	{
		LLChat chat("http://world.secondlife.com/region/" + id.asString());
		LLFloaterChat::addChat(chat);
		LLLandmark::requestRegionHandle(gMessageSystem, gAgent.getRegionHost(),
			id, boost::bind(&region_track_callback, _2));
	}
	else if(key_type == LLKeyTool::KT_PARCEL)
	{
		LLFloaterParcelInfo::show(id);
	}
	else if(key_type == LLKeyTool::KT_ITEM)
	{
		LLLocalInventory::open(id);
	}
	else if(key_type == LLKeyTool::KT_TASK)
	{
		LLViewerObject* object = gObjectList.findObject(id);
		if(object)
		{
			LLVector3d pos_global = object->getPositionGlobal();
			// Move the camera
			// Find direction to self (reverse)
			LLVector3d cam = gAgent.getPositionGlobal() - pos_global;
			cam.normalize();
			// Go 4 meters back and 3 meters up
			cam *= 4.0f;
			cam += pos_global;
			cam += LLVector3d(0.f, 0.f, 3.0f);

			gAgentCamera.setFocusOnAvatar(FALSE, FALSE);
			gAgentCamera.setCameraPosAndFocusGlobal(cam, pos_global, id);
			gAgentCamera.setCameraAnimating(FALSE);

			if(!object->isAvatar())
			{
				gFloaterTools->open();		/* Flawfinder: ignore */
				LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
				gFloaterTools->setEditTool( LLToolCompTranslate::getInstance() );
				LLSelectMgr::getInstance()->selectObjectAndFamily(object, FALSE);
			}

		}
		else
		{
			// Todo: ObjectPropertiesFamily display
		}
	}
	else
	{
		llwarns << "Unhandled key type " << key_type << llendl;
	}
}
Esempio n. 18
0
// True if you selected an object.
BOOL LLToolPie::pickLeftMouseDownCallback()
{
	S32 x = mPick.mMousePt.mX;
	S32 y = mPick.mMousePt.mY;
	MASK mask = mPick.mKeyMask;
	if (mPick.mPickType == LLPickInfo::PICK_PARCEL_WALL)
	{
		LLParcel* parcel = LLViewerParcelMgr::getInstance()->getCollisionParcel();
		if (parcel)
		{
			LLViewerParcelMgr::getInstance()->selectCollisionParcel();
			if (parcel->getParcelFlag(PF_USE_PASS_LIST) 
				&& !LLViewerParcelMgr::getInstance()->isCollisionBanned())
			{
				// if selling passes, just buy one
				void* deselect_when_done = (void*)TRUE;
				LLPanelLandGeneral::onClickBuyPass(deselect_when_done);
			}
			else
			{
				// not selling passes, get info
				LLFloaterReg::showInstance("about_land");
			}
		}

		gFocusMgr.setKeyboardFocus(NULL);
		return LLTool::handleMouseDown(x, y, mask);
	}

	// didn't click in any UI object, so must have clicked in the world
	LLViewerObject *object = mPick.getObject();
	LLViewerObject *parent = NULL;

	if (mPick.mPickType != LLPickInfo::PICK_LAND)
	{
		LLViewerParcelMgr::getInstance()->deselectLand();
	}
	
	if (object)
	{
		parent = object->getRootEdit();
	}

	if (handleMediaClick(mPick))
	{
		return TRUE;
	}

	// If it's a left-click, and we have a special action, do it.
	if (useClickAction(mask, object, parent))
	{
		mClickAction = 0;
		if (object && object->getClickAction()) 
		{
			mClickAction = object->getClickAction();
		}
		else if (parent && parent->getClickAction()) 
		{
			mClickAction = parent->getClickAction();
		}

		switch(mClickAction)
		{
		case CLICK_ACTION_TOUCH:
			// touch behavior down below...
			break;
		case CLICK_ACTION_SIT:
			{
				if (isAgentAvatarValid() && !gAgentAvatarp->isSitting()) // agent not already sitting
				{
					handle_object_sit_or_stand();
					// put focus in world when sitting on an object
					gFocusMgr.setKeyboardFocus(NULL);
					return TRUE;
				} // else nothing (fall through to touch)
			}
		case CLICK_ACTION_PAY:
			if ((object && object->flagTakesMoney())
				|| (parent && parent->flagTakesMoney()))
			{
				// pay event goes to object actually clicked on
				mClickActionObject = object;
				mLeftClickSelection = LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE);
				if (LLSelectMgr::getInstance()->selectGetAllValid())
				{
					// call this right away, since we have all the info we need to continue the action
					selectionPropertiesReceived();
				}
				return TRUE;
			}
			break;
		case CLICK_ACTION_BUY:
			mClickActionObject = parent;
			mLeftClickSelection = LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE, TRUE);
			if (LLSelectMgr::getInstance()->selectGetAllValid())
			{
				// call this right away, since we have all the info we need to continue the action
				selectionPropertiesReceived();
			}
			return TRUE;
		case CLICK_ACTION_OPEN:
			if (parent && parent->allowOpen())
			{
				mClickActionObject = parent;
				mLeftClickSelection = LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE, TRUE);
				if (LLSelectMgr::getInstance()->selectGetAllValid())
				{
					// call this right away, since we have all the info we need to continue the action
					selectionPropertiesReceived();
				}
			}
			return TRUE;	
		case CLICK_ACTION_PLAY:
			handle_click_action_play();
			return TRUE;
		case CLICK_ACTION_OPEN_MEDIA:
			// mClickActionObject = object;
			handle_click_action_open_media(object);
			return TRUE;
		case CLICK_ACTION_ZOOM:
			{	
				const F32 PADDING_FACTOR = 2.f;
				LLViewerObject* object = gObjectList.findObject(mPick.mObjectID);
				
				if (object)
				{
					gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
					
					LLBBox bbox = object->getBoundingBoxAgent() ;
					F32 angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getAspect() > 1.f ? LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect() : LLViewerCamera::getInstance()->getView());
					F32 distance = bbox.getExtentLocal().magVec() * PADDING_FACTOR / atan(angle_of_view);
				
					LLVector3 obj_to_cam = LLViewerCamera::getInstance()->getOrigin() - bbox.getCenterAgent();
					obj_to_cam.normVec();
					
					LLVector3d object_center_global = gAgent.getPosGlobalFromAgent(bbox.getCenterAgent());
					gAgentCamera.setCameraPosAndFocusGlobal(object_center_global + LLVector3d(obj_to_cam * distance), 
													  object_center_global, 
													  mPick.mObjectID );
				}
			}
			return TRUE;			
		default:
			// nothing
			break;
		}
	}

	// put focus back "in world"
	gFocusMgr.setKeyboardFocus(NULL);

	BOOL touchable = (object && object->flagHandleTouch()) 
					 || (parent && parent->flagHandleTouch());

	// Switch to grab tool if physical or triggerable
	if (object && 
		!object->isAvatar() && 
		((object->usePhysics() || (parent && !parent->isAvatar() && parent->usePhysics())) || touchable) 
		)
	{
		gGrabTransientTool = this;
		LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolGrab::getInstance() );
		return LLToolGrab::getInstance()->handleObjectHit( mPick );
	}
	
	LLHUDIcon* last_hit_hud_icon = mPick.mHUDIcon;
	if (!object && last_hit_hud_icon && last_hit_hud_icon->getSourceObject())
	{
		LLFloaterScriptDebug::show(last_hit_hud_icon->getSourceObject()->getID());
	}

	// If left-click never selects or spawns a menu
	// Eat the event.
	if (!gSavedSettings.getBOOL("LeftClickShowMenu"))
	{
		// mouse already released
		if (!mGrabMouseButtonDown)
		{
			return TRUE;
		}

		while( object && object->isAttachment() && !object->flagHandleTouch())
		{
			// don't pick avatar through hud attachment
			if (object->isHUDAttachment())
			{
				break;
			}
			object = (LLViewerObject*)object->getParent();
		}
		if (object && object == gAgentAvatarp)
		{
			// we left clicked on avatar, switch to focus mode
			LLToolMgr::getInstance()->setTransientTool(LLToolCamera::getInstance());
			gViewerWindow->hideCursor();
			LLToolCamera::getInstance()->setMouseCapture(TRUE);
			LLToolCamera::getInstance()->pickCallback(mPick);
			gAgentCamera.setFocusOnAvatar(TRUE, TRUE);

			return TRUE;
		}
	//////////
	//	// Could be first left-click on nothing
	//	LLFirstUse::useLeftClickNoHit();
	/////////
		
		// Eat the event
		return LLTool::handleMouseDown(x, y, mask);
	}

	if (gAgent.leftButtonGrabbed())
	{
		// if the left button is grabbed, don't put up the pie menu
		return LLTool::handleMouseDown(x, y, mask);
	}

	// Can't ignore children here.
	LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE);

	// Spawn pie menu
	LLTool::handleRightMouseDown(x, y, mask);
	return TRUE;
}
Esempio n. 19
0
void LLTeleportHistory::updateCurrentLocation(const LLVector3d& new_pos)
{
	if (!mTeleportHistoryStorage)
	{
		mTeleportHistoryStorage = LLTeleportHistoryStorage::getInstance();
	}
	if (mRequestedItem != -1) // teleport within the history in progress?
	{
		mCurrentItem = mRequestedItem;
		mRequestedItem = -1;
	}
	else
	{
		//EXT-7034
		//skip initial update if agent avatar is no valid yet
		//this may happen when updateCurrentLocation called while login process
		//sometimes isAgentAvatarValid return false and in this case new_pos
		//(which actually is gAgent.getPositionGlobal() ) is invalid
		//if this position will be saved then teleport back will teleport user to wrong position
		if ( !mGotInitialUpdate && !isAgentAvatarValid() )
		{
			return ;
		}

		// If we're getting the initial location update
		// while we already have a (loaded) non-empty history,
		// there's no need to purge forward items or add a new item.

		if (mGotInitialUpdate || mItems.size() == 0)
		{
			// Purge forward items (if any).
			if(mItems.size())
				mItems.erase (mItems.begin() + mCurrentItem + 1, mItems.end());
			
			// Append an empty item to the history and make it current.
			mItems.push_back(LLTeleportHistoryItem("", LLVector3d()));
			mCurrentItem++;
		}

		// Update current history item.
		if (mCurrentItem < 0 || mCurrentItem >= (int) mItems.size()) // sanity check
		{
			LL_WARNS() << "Invalid current item. (this should not happen)" << LL_ENDL;
			llassert(!"Invalid current teleport history item");
			return;
		}
		LLVector3 new_pos_local = gAgent.getPosAgentFromGlobal(new_pos);
		mItems[mCurrentItem].mFullTitle = getCurrentLocationTitle(true, new_pos_local);
		mItems[mCurrentItem].mTitle = getCurrentLocationTitle(false, new_pos_local);
		mItems[mCurrentItem].mGlobalPos	= new_pos;
		mItems[mCurrentItem].mRegionID = gAgent.getRegion()->getRegionID();
	}

	dump();
	
	if (!mGotInitialUpdate)
		mGotInitialUpdate = true;

	// Signal the interesting party that we've changed. 
	onHistoryChanged();
}
Esempio n. 20
0
LLVector3d	LLWorld::clipToVisibleRegions(const LLVector3d &start_pos, const LLVector3d &end_pos)
{
	if (positionRegionValidGlobal(end_pos))
	{
		return end_pos;
	}

	LLViewerRegion* regionp = getRegionFromPosGlobal(start_pos);
	if (!regionp) 
	{
		return start_pos;
	}

	LLVector3d delta_pos = end_pos - start_pos;
	LLVector3d delta_pos_abs;
	delta_pos_abs.setVec(delta_pos);
	delta_pos_abs.abs();

	LLVector3 region_coord = regionp->getPosRegionFromGlobal(end_pos);
	F64 clip_factor = 1.0;
	F32 region_width = regionp->getWidth();
	if (region_coord.mV[VX] < 0.f)
	{
		if (region_coord.mV[VY] < region_coord.mV[VX])
		{
			// clip along y -
			clip_factor = -(region_coord.mV[VY] / delta_pos_abs.mdV[VY]);
		}
		else
		{
			// clip along x -
			clip_factor = -(region_coord.mV[VX] / delta_pos_abs.mdV[VX]);
		}
	}
	else if (region_coord.mV[VX] > region_width)
	{
		if (region_coord.mV[VY] > region_coord.mV[VX])
		{
			// clip along y +
			clip_factor = (region_coord.mV[VY] - region_width) / delta_pos_abs.mdV[VY];
		}
		else
		{
			//clip along x +
			clip_factor = (region_coord.mV[VX] - region_width) / delta_pos_abs.mdV[VX];
		}
	}
	else if (region_coord.mV[VY] < 0.f)
	{
		// clip along y -
		clip_factor = -(region_coord.mV[VY] / delta_pos_abs.mdV[VY]);
	}
	else if (region_coord.mV[VY] > region_width)
	{ 
		// clip along y +
		clip_factor = (region_coord.mV[VY] - region_width) / delta_pos_abs.mdV[VY];
	}

	// clamp to < 256 to stay in sim
	LLVector3d final_region_pos = LLVector3d(region_coord) - (delta_pos * clip_factor);
	// clamp x, y to [0,256[ and z to [0,REGION_HEIGHT_METERS] (the clamp function cannot be used here)
	if (final_region_pos.mdV[VX] < 0) final_region_pos.mdV[VX] = 0.0;
	if (final_region_pos.mdV[VY] < 0) final_region_pos.mdV[VY] = 0.0;
	if (final_region_pos.mdV[VZ] < 0) final_region_pos.mdV[VZ] = 0.0;
	if (final_region_pos.mdV[VX] > 255.999) final_region_pos.mdV[VX] = 255.999; 
	if (final_region_pos.mdV[VY] > 255.999) final_region_pos.mdV[VY] = 255.999;
	if (final_region_pos.mdV[VZ] > REGION_HEIGHT_METERS) final_region_pos.mdV[VZ] = REGION_HEIGHT_METERS;
	//final_region_pos.clamp(0.0, 255.999);
	return regionp->getPosGlobalFromRegion(LLVector3(final_region_pos));
}
Esempio n. 21
0
void LLToolBrushLand::modifyLandInSelectionGlobal()
{
	if (LLViewerParcelMgr::getInstance()->selectionEmpty())
	{
		return;
	}

	if (LLToolMgr::getInstance()->getCurrentTool() == LLToolSelectLand::getInstance())
	{
		// selecting land, don't do anything
		return;
	}

	LLVector3d min;
	LLVector3d max;

	LLViewerParcelMgr::getInstance()->getSelection(min, max);

	S32 radioAction = gSavedSettings.getS32("RadioLandBrushAction");

	mLastAffectedRegions.clear();

	determineAffectedRegions(mLastAffectedRegions, LLVector3d(min.mdV[VX], min.mdV[VY], 0));
	determineAffectedRegions(mLastAffectedRegions, LLVector3d(min.mdV[VX], max.mdV[VY], 0));
	determineAffectedRegions(mLastAffectedRegions, LLVector3d(max.mdV[VX], min.mdV[VY], 0));
	determineAffectedRegions(mLastAffectedRegions, LLVector3d(max.mdV[VX], max.mdV[VY], 0));

	LLRegionPosition mid_point_region((min + max) * 0.5);
	LLViewerRegion* center_region = mid_point_region.getRegion();
	if (center_region)
	{
		LLVector3 pos_region = mid_point_region.getPositionRegion();
		U32 grids = center_region->getLand().mGridsPerEdge;
		S32 i = llclamp( (S32)pos_region.mV[VX], 0, (S32)grids );
		S32 j = llclamp( (S32)pos_region.mV[VY], 0, (S32)grids );
		mStartingZ = center_region->getLand().getZ(i+j*grids);
	}
	else
	{
		mStartingZ = 0.f;
	}

	// Stop if our selection include a no-terraform region
	for(region_list_t::iterator iter = mLastAffectedRegions.begin();
		iter != mLastAffectedRegions.end(); ++iter)
	{
		LLViewerRegion* regionp = *iter;
		if (!canTerraform(regionp))
		{
			alertNoTerraform(regionp);
			return;
		}
	}

	for(region_list_t::iterator iter = mLastAffectedRegions.begin();
		iter != mLastAffectedRegions.end(); ++iter)
	{
		LLViewerRegion* regionp = *iter;
		//BOOL is_changed = FALSE;
		LLVector3 min_region = regionp->getPosRegionFromGlobal(min);
		LLVector3 max_region = regionp->getPosRegionFromGlobal(max);
	
		min_region.clamp(0.f, regionp->getWidth());
		max_region.clamp(0.f, regionp->getWidth());
		F32 seconds = gSavedSettings.getF32("LandBrushForce");

		LLSurface &land = regionp->getLand();
		char action = E_LAND_LEVEL;
		switch (radioAction)
		{
		case 0:
		//	// average toward mStartingZ
			action = E_LAND_LEVEL;
			seconds *= 0.25f;
			break;
		case 1:
			action = E_LAND_RAISE;
			seconds *= 0.25f;
			break;
		case 2:
			action = E_LAND_LOWER;
			seconds *= 0.25f;
			break;
		case 3:
			action = E_LAND_SMOOTH;
			seconds *= 5.0f;
			break;
		case 4:
			action = E_LAND_NOISE;
			seconds *= 0.5f;
			break;
		case 5:
			action = E_LAND_REVERT;
			seconds = 0.5f;
			break;
		default:
			//action = E_LAND_INVALID;
			//seconds = 0.0f;
			return;
			break;
		}

		// Don't send a message to the region if nothing changed.
		//if(!is_changed) continue;

		// Now to update the patch information so it will redraw correctly.
		LLSurfacePatch *patchp= land.resolvePatchRegion(min_region);
		if (patchp)
		{
			patchp->dirtyZ();
		}

		// Also force the property lines to update, normals to recompute, etc.
		regionp->forceUpdate();

		// tell the simulator what we've done
		LLMessageSystem* msg = gMessageSystem;
		msg->newMessageFast(_PREHASH_ModifyLand);
		msg->nextBlockFast(_PREHASH_AgentData);
		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
		msg->nextBlockFast(_PREHASH_ModifyBlock);
		msg->addU8Fast(_PREHASH_Action, (U8)action);
		msg->addU8Fast(_PREHASH_BrushSize, getBrushIndex());
		msg->addF32Fast(_PREHASH_Seconds, seconds);
		msg->addF32Fast(_PREHASH_Height, mStartingZ);

		BOOL parcel_selected = LLViewerParcelMgr::getInstance()->getParcelSelection()->getWholeParcelSelected();
		LLParcel* selected_parcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel();

		if (parcel_selected && selected_parcel)
		{
			msg->nextBlockFast(_PREHASH_ParcelData);
			msg->addS32Fast(_PREHASH_LocalID, selected_parcel->getLocalID());
			msg->addF32Fast(_PREHASH_West,  min_region.mV[VX] );
			msg->addF32Fast(_PREHASH_South, min_region.mV[VY] );
			msg->addF32Fast(_PREHASH_East,  max_region.mV[VX] );
			msg->addF32Fast(_PREHASH_North, max_region.mV[VY] );
		}
		else
		{
			msg->nextBlockFast(_PREHASH_ParcelData);
			msg->addS32Fast(_PREHASH_LocalID, -1);
			msg->addF32Fast(_PREHASH_West,  min_region.mV[VX] );
			msg->addF32Fast(_PREHASH_South, min_region.mV[VY] );
			msg->addF32Fast(_PREHASH_East,  max_region.mV[VX] );
			msg->addF32Fast(_PREHASH_North, max_region.mV[VY] );
		}
		
		msg->nextBlock("ModifyBlockExtended");
		msg->addF32("BrushSize", mBrushSize);

		msg->sendMessage(regionp->getHost());
	}
}
Esempio n. 22
0
LLVector3d	LLWorld::clipToVisibleRegions(const LLVector3d &start_pos, const LLVector3d &end_pos)
{
	if (positionRegionValidGlobal(end_pos))
	{
		return end_pos;
	}

	LLViewerRegion* regionp = getRegionFromPosGlobal(start_pos);
	if (!regionp) 
	{
		return start_pos;
	}

	LLVector3d delta_pos = end_pos - start_pos;
	LLVector3d delta_pos_abs;
	delta_pos_abs.setVec(delta_pos);
	delta_pos_abs.abs();

	LLVector3 region_coord = regionp->getPosRegionFromGlobal(end_pos);
	F64 clip_factor = 1.0;
	F32 region_width = regionp->getWidth();
	if (region_coord.mV[VX] < 0.f)
	{
		if (region_coord.mV[VY] < region_coord.mV[VX])
		{
			// clip along y -
			clip_factor = -(region_coord.mV[VY] / delta_pos_abs.mdV[VY]);
		}
		else
		{
			// clip along x -
			clip_factor = -(region_coord.mV[VX] / delta_pos_abs.mdV[VX]);
		}
	}
	else if (region_coord.mV[VX] > region_width)
	{
		if (region_coord.mV[VY] > region_coord.mV[VX])
		{
			// clip along y +
			clip_factor = (region_coord.mV[VY] - region_width) / delta_pos_abs.mdV[VY];
		}
		else
		{
			//clip along x +
			clip_factor = (region_coord.mV[VX] - region_width) / delta_pos_abs.mdV[VX];
		}
	}
	else if (region_coord.mV[VY] < 0.f)
	{
		// clip along y -
		clip_factor = -(region_coord.mV[VY] / delta_pos_abs.mdV[VY]);
	}
	else if (region_coord.mV[VY] > region_width)
	{ 
		// clip along y +
		clip_factor = (region_coord.mV[VY] - region_width) / delta_pos_abs.mdV[VY];
	}

	// clamp to within region dimensions
	LLVector3d final_region_pos = LLVector3d(region_coord) - (delta_pos * clip_factor);
	final_region_pos.mdV[VX] = llclamp(final_region_pos.mdV[VX], 0.0,
									   (F64)(region_width - F_ALMOST_ZERO));
	final_region_pos.mdV[VY] = llclamp(final_region_pos.mdV[VY], 0.0,
									   (F64)(region_width - F_ALMOST_ZERO));
	final_region_pos.mdV[VZ] = llclamp(final_region_pos.mdV[VZ], 0.0,
									   (F64)(LLWorld::getInstance()->getRegionMaxHeight() - F_ALMOST_ZERO));
	return regionp->getPosGlobalFromRegion(LLVector3(final_region_pos));
}
Esempio n. 23
0
// 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);
	}
}
Esempio n. 24
0
// There are three types of water objects:
// Region water objects: the water in a region.
// Hole water objects: water in the void but within current draw distance.
// Edge water objects: the water outside the draw distance, up till the horizon.
//
// For example:
//
// -----------------------horizon-------------------------
// |                 |                 |                 |
// |  Edge Water     |                 |                 |
// |                 |                 |                 |
// |                 |                 |                 |
// |                 |                 |                 |
// |                 |                 |                 |
// |                 |      rwidth     |                 |
// |                 |     <----->     |                 |
// -------------------------------------------------------
// |                 |Hole |other|     |                 |
// |                 |Water|reg. |     |                 |
// |                 |-----------------|                 |
// |                 |other|cur. |<--> |                 |
// |                 |reg. | reg.|  \__|_ draw distance  |
// |                 |-----------------|                 |
// |                 |     |     |<--->|                 |
// |                 |     |     |  \__|_ range          |
// -------------------------------------------------------
// |                 |<----width------>|<--horizon ext.->|
// |                 |                 |                 |
// |                 |                 |                 |
// |                 |                 |                 |
// |                 |                 |                 |
// |                 |                 |                 |
// |                 |                 |                 |
// |                 |                 |                 |
// -------------------------------------------------------
//
void LLWorld::updateWaterObjects()
{
	if (!gAgent.getRegion())
	{
		return;
	}
	if (mRegionList.empty())
	{
		llwarns << "No regions!" << llendl;
		return;
	}

	LLViewerRegion const* regionp = gAgent.getRegion();

	// Region width in meters.
	S32 const rwidth = (S32)regionp->getWidth();

	// The distance we might see into the void
	// when standing on the edge of a region, in meters.
	S32 const draw_distance = llceil(mLandFarClip);

	// We can only have "holes" in the water (where there no region) if we
	// can have existing regions around it. Taking into account that this
	// code is only executed when we enter a region, and not when we walk
	// around in it, we (only) need to take into account regions that fall
	// within the draw_distance.
	//
	// Set 'range' to draw_distance, rounded up to the nearest multiple of rwidth.
	S32 const nsims = (draw_distance + rwidth - 1) / rwidth;
	S32 const range = nsims * rwidth;

	// Get South-West corner of current region.
	U32 region_x, region_y;
	from_region_handle(regionp->getHandle(), &region_x, &region_y);

	// The min. and max. coordinates of the South-West corners of the Hole water objects.
	S32 const min_x = (S32)region_x - range;
	S32 const min_y = (S32)region_y - range;
	S32 const max_x = (S32)region_x + rwidth-256 + range;
	S32 const max_y = (S32)region_y + rwidth-256 + range;

	// Attempt to determine a sensible water height for all the
	// Hole Water objects.
	//
	// It make little sense to try to guess what the best water
	// height should be when that isn't completely obvious: if it's
	// impossible to satisfy every region's water height without
	// getting a jump in the water height.
	//
	// In order to keep the reasoning simple, we assume something
	// logical as a group of connected regions, where the coastline
	// is at the outer edge. Anything more complex that would "break"
	// under such an assumption would probably break anyway (would
	// depend on terrain editing and existing mega prims, say, if
	// anything would make sense at all).
	//
	// So, what we do is find all connected regions within the
	// draw distance that border void, and then pick the lowest
	// water height of those (coast) regions.
	S32 const n = 2 * nsims + 1;
	S32 const origin = nsims + nsims * n;
	std::vector<F32> water_heights(n * n);
	std::vector<U8> checked(n * n, 0);		// index = nx + ny * n + origin;
	U8 const region_bit = 1;
	U8 const hole_bit = 2;
	U8 const bordering_hole_bit = 4;
	U8 const bordering_edge_bit = 8;
	// Use the legacy waterheight for the Edge water in the case
	// that we don't find any Hole water at all.
	F32 water_height = DEFAULT_WATER_HEIGHT;
	int max_count = 0;
	LL_DEBUGS("WaterHeight") << "Current region: " << regionp->getName() << "; water height: " << regionp->getWaterHeight() << " m." << LL_ENDL;
	std::map<S32, int> water_height_counts;
	typedef std::queue<std::pair<S32, S32>, std::deque<std::pair<S32, S32> > > nxny_pairs_type;
	nxny_pairs_type nxny_pairs;
	nxny_pairs.push(nxny_pairs_type::value_type(0, 0));
	water_heights[origin] = regionp->getWaterHeight();
	checked[origin] = region_bit;
	// For debugging purposes.
	int number_of_connected_regions = 1;
	int uninitialized_regions = 0;
	int bordering_hole = 0;
	int bordering_edge = 0;
	while(!nxny_pairs.empty())
	{
		S32 const nx = nxny_pairs.front().first;
		S32 const ny = nxny_pairs.front().second;
		LL_DEBUGS("WaterHeight") << "nx,ny = " << nx << "," << ny << LL_ENDL;
		S32 const index = nx + ny * n + origin;
		nxny_pairs.pop();
		for (S32 dir = 0; dir < 4; ++dir)
		{
			S32 const cnx = nx + gDirAxes[dir][0];
			S32 const cny = ny + gDirAxes[dir][1];
			LL_DEBUGS("WaterHeight") << "dir = " << dir << "; cnx,cny = " << cnx << "," << cny << LL_ENDL;
			S32 const cindex = cnx + cny * n + origin;
			bool is_hole = false;
			bool is_edge = false;
			LLViewerRegion* new_region_found = NULL;
			if (cnx < -nsims || cnx > nsims ||
			    cny < -nsims || cny > nsims)
			{
				LL_DEBUGS("WaterHeight") << "  Edge Water!" << LL_ENDL;
				// Bumped into Edge water object.
				is_edge = true;
			}
			else if (checked[cindex])
			{
				LL_DEBUGS("WaterHeight") << "  Already checked before!" << LL_ENDL;
				// Already checked.
				is_hole = (checked[cindex] & hole_bit);
			}
			else
			{
				S32 x = (S32)region_x + cnx * rwidth;
				S32 y = (S32)region_y + cny * rwidth;
				U64 region_handle = to_region_handle(x, y);
				new_region_found = getRegionFromHandle(region_handle);
				is_hole = !new_region_found;
				checked[cindex] = is_hole ? hole_bit : region_bit;
			}
			if (is_hole)
			{
				// This was a region that borders at least one 'hole'.
				// Count the found coastline.
				F32 new_water_height = water_heights[index];
				LL_DEBUGS("WaterHeight") << "  This is void; counting coastline with water height of " << new_water_height << LL_ENDL;
				S32 new_water_height_cm = llround(new_water_height * 100);
				int count = (water_height_counts[new_water_height_cm] += 1);
				// Just use the lowest water height: this is mainly about the horizon water,
				// and whatever we do, we don't want it to be possible to look under the water
				// when looking in the distance: it is better to make a step downwards in water
				// height when going away from the avie than a step upwards. However, since
				// everyone is used to DEFAULT_WATER_HEIGHT, don't allow a single region
				// to drag the water level below DEFAULT_WATER_HEIGHT on it's own.
				if (bordering_hole == 0 ||			// First time we get here.
				    (new_water_height >= DEFAULT_WATER_HEIGHT &&
					 new_water_height < water_height) ||
				    (new_water_height < DEFAULT_WATER_HEIGHT &&
					 count > max_count)
				   )
				{
					water_height = new_water_height;
				}
				if (count > max_count)
				{
					max_count = count;
				}
				if (!(checked[index] & bordering_hole_bit))
				{
					checked[index] |= bordering_hole_bit;
					++bordering_hole;
				}
			}
			else if (is_edge && !(checked[index] & bordering_edge_bit))
			{
				checked[index] |= bordering_edge_bit;
				++bordering_edge;
			}
			if (!new_region_found)
			{
				// Dead end, there is no region here.
				continue;
			}
			// Found a new connected region.
			++number_of_connected_regions;
			if (new_region_found->getName().empty())
			{
				// Uninitialized LLViewerRegion, don't use it's water height.
				LL_DEBUGS("WaterHeight") << "  Uninitialized region." << LL_ENDL;
				++uninitialized_regions;
				continue;
			}
			nxny_pairs.push(nxny_pairs_type::value_type(cnx, cny));
			water_heights[cindex] = new_region_found->getWaterHeight();
			LL_DEBUGS("WaterHeight") << "  Found a new region (name: " << new_region_found->getName() << "; water height: " << water_heights[cindex] << " m)!" << LL_ENDL;
		}
	}
	llinfos << "Number of connected regions: " << number_of_connected_regions << " (" << uninitialized_regions <<
		" uninitialized); number of regions bordering Hole water: " << bordering_hole <<
		"; number of regions bordering Edge water: " << bordering_edge << llendl;
	llinfos << "Coastline count (height, count): ";
	bool first = true;
	for (std::map<S32, int>::iterator iter = water_height_counts.begin(); iter != water_height_counts.end(); ++iter)
	{
		if (!first) llcont << ", ";
		llcont << "(" << (iter->first / 100.f) << ", " << iter->second << ")";
		first = false;
	}
	llcont << llendl;
	llinfos << "Water height used for Hole and Edge water objects: " << water_height << llendl;

	// Update all Region water objects.
	for (region_list_t::iterator iter = mRegionList.begin(); iter != mRegionList.end(); ++iter)
	{
		LLViewerRegion* regionp = *iter;
		LLVOWater* waterp = regionp->getLand().getWaterObj();
		if (waterp)
		{
			gObjectList.updateActive(waterp);
		}
	}

	// Clean up all existing Hole water objects.
	for (std::list<LLVOWater*>::iterator iter = mHoleWaterObjects.begin();
		 iter != mHoleWaterObjects.end(); ++iter)
	{
		LLVOWater* waterp = *iter;
		gObjectList.killObject(waterp);
	}
	mHoleWaterObjects.clear();

	// Let the Edge and Hole water boxes be 1024 meter high so that they
	// are never too small to be drawn (A LL_VO_*_WATER box has water
	// rendered on it's bottom surface only), and put their bottom at
	// the current regions water height.
	F32 const box_height = 1024;
	F32 const water_center_z = water_height + box_height / 2;
	const S32 step = 256;
	// Create new Hole water objects within 'range' where there is no region.
	for (S32 x = min_x; x <= max_x; x += step)
	{
		for (S32 y = min_y; y <= max_y; y += step)
		{
			U64 region_handle = to_region_handle(x, y);
			if (!getRegionFromHandle(region_handle))
			{
				LLVOWater* waterp = (LLVOWater*)gObjectList.createObjectViewer(LLViewerObject::LL_VO_VOID_WATER, gAgent.getRegion());
				waterp->setUseTexture(FALSE);
				waterp->setPositionGlobal(LLVector3d(x + step / 2, y + step / 2, water_center_z));
				waterp->setScale(LLVector3((F32)step, (F32)step, box_height));
				gPipeline.createObject(waterp);
				mHoleWaterObjects.push_back(waterp);
			}
		}
	}

	// Center of the region.
	S32 const center_x = region_x + step / 2;
	S32 const center_y = region_y + step / 2;
	// Width of the area with Hole water objects.
	S32 const width = step + 2 * range;
	S32 const horizon_extend = 2048 + 512 - range;	// Legacy value.
	// The overlap is needed to get rid of sky pixels being visible between the
	// Edge and Hole water object at greater distances (due to floating point
	// round off errors).
	S32 const edge_hole_overlap = 1;		// Twice the actual overlap.
		
	for (S32 dir = 0; dir < 8; ++dir)
	{
		// Size of the Edge water objects.
		S32 const dim_x = (gDirAxes[dir][0] == 0) ? width : (horizon_extend + edge_hole_overlap);
		S32 const dim_y = (gDirAxes[dir][1] == 0) ? width : (horizon_extend + edge_hole_overlap);
		// And their position.
		S32 const water_center_x = center_x + (width + horizon_extend) / 2 * gDirAxes[dir][0];
		S32 const water_center_y = center_y + (width + horizon_extend) / 2 * gDirAxes[dir][1];

		LLVOWater* waterp = mEdgeWaterObjects[dir];
		if (!waterp || waterp->isDead())
		{
			// The edge water objects can be dead because they're attached to the region that the
			// agent was in when they were originally created.
			mEdgeWaterObjects[dir] = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_VOID_WATER, gAgent.getRegion());
			waterp = mEdgeWaterObjects[dir];
			waterp->setUseTexture(FALSE);
			waterp->setIsEdgePatch(TRUE);		// Mark that this is edge water and not hole water.
			gPipeline.createObject(waterp);
		}

		waterp->setRegion(gAgent.getRegion());
		LLVector3d water_pos(water_center_x, water_center_y, water_center_z);
		LLVector3 water_scale((F32) dim_x, (F32) dim_y, box_height);

		waterp->setPositionGlobal(water_pos);
		waterp->setScale(water_scale);

		gObjectList.updateActive(waterp);
	}
}
Esempio n. 25
0
void LLCloudGroup::updatePuffCount()
{
	if (!mVOCloudsp)
	{
		return;
	}
	S32 i;
	S32 target_puff_count = llround(CLOUD_DENSITY * mDensity);
	target_puff_count = llmax(0, target_puff_count);
	target_puff_count = llmin(CLOUD_COUNT_MAX, target_puff_count);
	S32 current_puff_count = (S32) mCloudPuffs.size();
	// Create a new cloud if we need one
	if (current_puff_count < target_puff_count)
	{
		LLVector3d puff_pos_global;
		mCloudPuffs.resize(target_puff_count);
		for (i = current_puff_count; i < target_puff_count; i++)
		{
			puff_pos_global = mVOCloudsp->getPositionGlobal();
			F32 x = ll_frand(256.f/CLOUD_GROUPS_PER_EDGE) - 128.f/CLOUD_GROUPS_PER_EDGE;
			F32 y = ll_frand(256.f/CLOUD_GROUPS_PER_EDGE) - 128.f/CLOUD_GROUPS_PER_EDGE;
			F32 z = ll_frand(CLOUD_HEIGHT_RANGE) - 0.5f*CLOUD_HEIGHT_RANGE;
			puff_pos_global += LLVector3d(x, y, z);
			mCloudPuffs[i].mPositionGlobal = puff_pos_global;
			mCloudPuffs[i].mAlpha = 0.01f;
			LLCloudPuff::sPuffCount++;
		}
	}

	// Count the number of live puffs
	S32 live_puff_count = 0;
	for (i = 0; i < (S32) mCloudPuffs.size(); i++)
	{
		if (mCloudPuffs[i].getLifeState() != LL_PUFF_DYING)
		{
			live_puff_count++;
		}
	}


	// Start killing enough puffs so the live puff count == target puff count
	S32 new_dying_count = llmax(0, live_puff_count - target_puff_count);
	i = 0;
	while (new_dying_count > 0)
	{
		if (mCloudPuffs[i].getLifeState() != LL_PUFF_DYING)
		{
			//llinfos << "Killing extra live cloud" << llendl;
			mCloudPuffs[i].setLifeState(LL_PUFF_DYING);
			mCloudPuffs[i].mRate = CLOUD_DECAY_RATE*CLOUD_UPDATE_RATE;
			new_dying_count--;
		}
		i++;
	}

	// Remove fully dead puffs
	i = 0;
	while (i < (S32) mCloudPuffs.size())
	{
		if (mCloudPuffs[i].isDead())
		{
			//llinfos << "Removing dead puff!" << llendl;
			mCloudPuffs.erase(mCloudPuffs.begin() + i);
			LLCloudPuff::sPuffCount--;
		}
		else
		{
			i++;
		}
	}
}
Esempio n. 26
0
void LLPanelPlaces::onOpen(const LLSD& key)
{
	if (!mPlaceProfile || !mLandmarkInfo)
		return;

	if (key.size() != 0)
	{
		mFilterEditor->clear();
		onFilterEdit("", false);

		mPlaceInfoType = key["type"].asString();
		mPosGlobal.setZero();
		mItem = NULL;
		isLandmarkEditModeOn = false;
		togglePlaceInfoPanel(TRUE);

		if (mPlaceInfoType == AGENT_INFO_TYPE)
		{
			mPlaceProfile->setInfoType(LLPanelPlaceInfo::AGENT);
		}
		else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
		{
			mLandmarkInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK);

			if (key.has("x") && key.has("y") && key.has("z"))
			{
				mPosGlobal = LLVector3d(key["x"].asReal(),
										key["y"].asReal(),
										key["z"].asReal());
			}
			else
			{
				mPosGlobal = gAgent.getPositionGlobal();
			}

			mLandmarkInfo->displayParcelInfo(LLUUID(), mPosGlobal);

			// Disabling "Save", "Close" and "Back" buttons to prevent closing "Create Landmark"
			// panel before created landmark is loaded.
			// These buttons will be enabled when created landmark is added to inventory.
			mSaveBtn->setEnabled(FALSE);
			mCloseBtn->setEnabled(FALSE);
			mLandmarkInfoBackBtn->setEnabled(FALSE);
		}
		else if (mPlaceInfoType == LANDMARK_INFO_TYPE)
		{
			mLandmarkInfo->setInfoType(LLPanelPlaceInfo::LANDMARK);

			LLInventoryItem* item = gInventory.getItem(key["id"].asUUID());
			if (!item)
				return;

			setItem(item);
		}
		else if (mPlaceInfoType == REMOTE_PLACE_INFO_TYPE)
		{
			if (key.has("id"))
			{
				LLUUID parcel_id = key["id"].asUUID();
				mPlaceProfile->setParcelID(parcel_id);

				// query the server to get the global 3D position of this
				// parcel - we need this for teleport/mapping functions.
				mRemoteParcelObserver->setParcelID(parcel_id);
			}
			else
			{
				mPosGlobal = LLVector3d(key["x"].asReal(),
										key["y"].asReal(),
										key["z"].asReal());
				mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal);
			}

			mPlaceProfile->setInfoType(LLPanelPlaceInfo::PLACE);
		}
		else if (mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE)
		{
			S32 index = key["id"].asInteger();

			const LLTeleportHistoryStorage::slurl_list_t& hist_items =
						LLTeleportHistoryStorage::getInstance()->getItems();

			mPosGlobal = hist_items[index].mGlobalPos;

			mPlaceProfile->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY);
			mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal);
		}

		updateVerbs();
	}

	LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
	if (!parcel_mgr)
		return;

	// Start using LLViewerParcelMgr for land selection if
	// information about nearby land is requested.
	// Otherwise stop using land selection and deselect land.
	if (mPlaceInfoType == AGENT_INFO_TYPE)
	{
		// We don't know if we are already added to LLViewerParcelMgr observers list
		// so try to remove observer not to add an extra one.
		parcel_mgr->removeObserver(mParcelObserver);

		parcel_mgr->addObserver(mParcelObserver);
		parcel_mgr->selectParcelAt(gAgent.getPositionGlobal());
	}
	else
	{
		parcel_mgr->removeObserver(mParcelObserver);

		// Clear the reference to selection to allow its removal in deselectUnused().
		mParcel.clear();

		if (!parcel_mgr->selectionEmpty())
		{
			parcel_mgr->deselectUnused();
		}
	}
}