summaryrefslogtreecommitdiff
path: root/indra/newview/llworld.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llworld.cpp')
-rwxr-xr-x[-rw-r--r--]indra/newview/llworld.cpp751
1 files changed, 307 insertions, 444 deletions
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 399442e5c4..5d657f7eef 100644..100755
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -50,16 +50,18 @@
#include "llviewerstats.h"
#include "llvlcomposition.h"
#include "llvoavatar.h"
+#include "llvocache.h"
#include "llvowater.h"
#include "message.h"
#include "pipeline.h"
#include "llappviewer.h" // for do_disconnect()
-
+#include "llscenemonitor.h"
#include <deque>
#include <queue>
#include <map>
#include <cstring>
+
//
// Globals
//
@@ -68,7 +70,6 @@ U32 gAgentPauseSerialNum = 0;
//
// Constants
//
-const S32 MAX_NUMBER_OF_CLOUDS = 750;
const S32 WORLD_PATCH_SIZE = 16;
extern LLColor4U MAX_WATER_COLOR;
@@ -90,19 +91,13 @@ LLWorld::LLWorld() :
mLastPacketsIn(0),
mLastPacketsOut(0),
mLastPacketsLost(0),
- mSpaceTimeUSec(0),
- mClassicCloudsEnabled(TRUE)
+ mSpaceTimeUSec(0)
{
for (S32 i = 0; i < 8; i++)
{
mEdgeWaterObjects[i] = NULL;
}
- if (gNoRender)
- {
- return;
- }
-
LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,4);
U8 *default_texture = raw->getData();
*(default_texture++) = MAX_WATER_COLOR.mV[0];
@@ -114,6 +109,7 @@ LLWorld::LLWorld() :
gGL.getTexUnit(0)->bind(mDefaultWaterTexturep);
mDefaultWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
+ LLViewerRegion::sVOCacheCullingEnabled = gSavedSettings.getBOOL("RequestFullRegionCache") && gSavedSettings.getBOOL("ObjectCacheEnabled");
}
@@ -126,52 +122,68 @@ void LLWorld::destroyClass()
LLViewerRegion* region_to_delete = *region_it++;
removeRegion(region_to_delete->getHost());
}
- if(LLVOCache::hasInstance())
+
+ LLViewerPartSim::getInstance()->destroyClass();
+
+ mDefaultWaterTexturep = NULL ;
+ for (S32 i = 0; i < 8; i++)
{
- LLVOCache::getInstance()->destroyClass() ;
+ mEdgeWaterObjects[i] = NULL;
}
- LLViewerPartSim::getInstance()->destroyClass();
+
+ //make all visible drawbles invisible.
+ LLDrawable::incrementVisible();
+
+ LLSceneMonitor::deleteSingleton();
}
LLViewerRegion* LLWorld::addRegion(const U64 &region_handle, const LLHost &host)
{
- LLMemType mt(LLMemType::MTYPE_REGIONS);
- llinfos << "Add region with handle: " << region_handle << " on host " << host << llendl;
+ LL_INFOS() << "Add region with handle: " << region_handle << " on host " << host << LL_ENDL;
LLViewerRegion *regionp = getRegionFromHandle(region_handle);
+ std::string seedUrl;
if (regionp)
{
- llinfos << "Region exists, removing it " << llendl;
LLHost old_host = regionp->getHost();
// region already exists!
if (host == old_host && regionp->isAlive())
{
// This is a duplicate for the same host and it's alive, don't bother.
+ LL_INFOS() << "Region already exists and is alive, using existing region" << LL_ENDL;
return regionp;
}
if (host != old_host)
{
- llwarns << "LLWorld::addRegion exists, but old host " << old_host
- << " does not match new host " << host << llendl;
+ LL_WARNS() << "LLWorld::addRegion exists, but old host " << old_host
+ << " does not match new host " << host
+ << ", removing old region and creating new" << LL_ENDL;
}
if (!regionp->isAlive())
{
- llwarns << "LLWorld::addRegion exists, but isn't alive" << llendl;
+ LL_WARNS() << "LLWorld::addRegion exists, but isn't alive. Removing old region and creating new" << LL_ENDL;
}
+ // Save capabilities seed URL
+ seedUrl = regionp->getCapability("Seed");
+
// Kill the old host, and then we can continue on and add the new host. We have to kill even if the host
// matches, because all the agent state for the new camera is completely different.
removeRegion(old_host);
}
+ else
+ {
+ LL_INFOS() << "Region does not exist, creating new one" << LL_ENDL;
+ }
U32 iindex = 0;
U32 jindex = 0;
from_region_handle(region_handle, &iindex, &jindex);
S32 x = (S32)(iindex/mWidth);
S32 y = (S32)(jindex/mWidth);
- llinfos << "Adding new region (" << x << ":" << y << ")" << llendl;
- llinfos << "Host: " << host << llendl;
+ LL_INFOS() << "Adding new region (" << x << ":" << y << ")"
+ << " on host: " << host << LL_ENDL;
LLVector3d origin_global;
@@ -184,12 +196,13 @@ LLViewerRegion* LLWorld::addRegion(const U64 &region_handle, const LLHost &host)
getRegionWidthInMeters() );
if (!regionp)
{
- llerrs << "Unable to create new region!" << llendl;
+ LL_ERRS() << "Unable to create new region!" << LL_ENDL;
}
- regionp->mCloudLayer.create(regionp);
- regionp->mCloudLayer.setWidth((F32)mWidth);
- regionp->mCloudLayer.setWindPointer(&regionp->mWind);
+ if ( !seedUrl.empty() )
+ {
+ regionp->setCapability("Seed", seedUrl);
+ }
mRegionList.push_back(regionp);
mActiveRegionList.push_back(regionp);
@@ -221,7 +234,7 @@ LLViewerRegion* LLWorld::addRegion(const U64 &region_handle, const LLHost &host)
neighborp = getRegionFromHandle(adj_handle);
if (neighborp)
{
- //llinfos << "Connecting " << region_x << ":" << region_y << " -> " << adj_x << ":" << adj_y << llendl;
+ //LL_INFOS() << "Connecting " << region_x << ":" << region_y << " -> " << adj_x << ":" << adj_y << LL_ENDL;
regionp->connectNeighbor(neighborp, dir);
}
}
@@ -239,7 +252,7 @@ void LLWorld::removeRegion(const LLHost &host)
LLViewerRegion *regionp = getRegion(host);
if (!regionp)
{
- llwarns << "Trying to remove region that doesn't exist!" << llendl;
+ LL_WARNS() << "Trying to remove region that doesn't exist!" << LL_ENDL;
return;
}
@@ -249,21 +262,21 @@ void LLWorld::removeRegion(const LLHost &host)
iter != mRegionList.end(); ++iter)
{
LLViewerRegion* reg = *iter;
- llwarns << "RegionDump: " << reg->getName()
+ LL_WARNS() << "RegionDump: " << reg->getName()
<< " " << reg->getHost()
<< " " << reg->getOriginGlobal()
- << llendl;
+ << LL_ENDL;
}
- llwarns << "Agent position global " << gAgent.getPositionGlobal()
+ LL_WARNS() << "Agent position global " << gAgent.getPositionGlobal()
<< " agent " << gAgent.getPositionAgent()
- << llendl;
+ << LL_ENDL;
- llwarns << "Regions visited " << gAgent.getRegionsVisited() << llendl;
+ LL_WARNS() << "Regions visited " << gAgent.getRegionsVisited() << LL_ENDL;
- llwarns << "gFrameTimeSeconds " << gFrameTimeSeconds << llendl;
+ LL_WARNS() << "gFrameTimeSeconds " << gFrameTimeSeconds << LL_ENDL;
- llwarns << "Disabling region " << regionp->getName() << " that agent is in!" << llendl;
+ LL_WARNS() << "Disabling region " << regionp->getName() << " that agent is in!" << LL_ENDL;
LLAppViewer::instance()->forceDisconnect(LLTrans::getString("YouHaveBeenDisconnected"));
regionp->saveObjectCache() ; //force to save objects here in case that the object cache is about to be destroyed.
@@ -271,16 +284,22 @@ void LLWorld::removeRegion(const LLHost &host)
}
from_region_handle(regionp->getHandle(), &x, &y);
- llinfos << "Removing region " << x << ":" << y << llendl;
+ LL_INFOS() << "Removing region " << x << ":" << y << LL_ENDL;
mRegionList.remove(regionp);
mActiveRegionList.remove(regionp);
mCulledRegionList.remove(regionp);
mVisibleRegionList.remove(regionp);
-
+
+ mRegionRemovedSignal(regionp);
+
delete regionp;
updateWaterObjects();
+
+ //double check all objects of this region are removed.
+ gObjectList.clearAllMapObjectsInRegion(regionp) ;
+ //llassert_always(!gObjectList.hasMapObjectInRegion(regionp)) ;
}
@@ -401,6 +420,19 @@ LLViewerRegion* LLWorld::getRegionFromHandle(const U64 &handle)
return NULL;
}
+LLViewerRegion* LLWorld::getRegionFromID(const LLUUID& region_id)
+{
+ for (region_list_t::iterator iter = mRegionList.begin();
+ iter != mRegionList.end(); ++iter)
+ {
+ LLViewerRegion* regionp = *iter;
+ if (regionp->getRegionID() == region_id)
+ {
+ return regionp;
+ }
+ }
+ return NULL;
+}
void LLWorld::updateAgentOffset(const LLVector3d &offset_global)
{
@@ -587,22 +619,23 @@ void LLWorld::updateVisibilities()
{
F32 cur_far_clip = LLViewerCamera::getInstance()->getFar();
- LLViewerCamera::getInstance()->setFar(mLandFarClip);
-
- F32 diagonal_squared = F_SQRT2 * F_SQRT2 * mWidth * mWidth;
- // Go through the culled list and check for visible regions
+ // Go through the culled list and check for visible regions (region is visible if land is visible)
for (region_list_t::iterator iter = mCulledRegionList.begin();
iter != mCulledRegionList.end(); )
{
region_list_t::iterator curiter = iter++;
LLViewerRegion* regionp = *curiter;
- F32 height = regionp->getLand().getMaxZ() - regionp->getLand().getMinZ();
- F32 radius = 0.5f*fsqrtf(height * height + diagonal_squared);
- if (!regionp->getLand().hasZData()
- || LLViewerCamera::getInstance()->sphereInFrustum(regionp->getCenterAgent(), radius))
+
+ LLSpatialPartition* part = regionp->getSpatialPartition(LLViewerRegion::PARTITION_TERRAIN);
+ if (part)
{
- mCulledRegionList.erase(curiter);
- mVisibleRegionList.push_back(regionp);
+ LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0);
+ const LLVector4a* bounds = group->getBounds();
+ if (LLViewerCamera::getInstance()->AABBInFrustum(bounds[0], bounds[1]))
+ {
+ mCulledRegionList.erase(curiter);
+ mVisibleRegionList.push_back(regionp);
+ }
}
}
@@ -617,20 +650,21 @@ void LLWorld::updateVisibilities()
continue;
}
- F32 height = regionp->getLand().getMaxZ() - regionp->getLand().getMinZ();
- F32 radius = 0.5f*fsqrtf(height * height + diagonal_squared);
- if (LLViewerCamera::getInstance()->sphereInFrustum(regionp->getCenterAgent(), radius))
+ LLSpatialPartition* part = regionp->getSpatialPartition(LLViewerRegion::PARTITION_TERRAIN);
+ if (part)
{
- regionp->calculateCameraDistance();
- if (!gNoRender)
+ LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0);
+ const LLVector4a* bounds = group->getBounds();
+ if (LLViewerCamera::getInstance()->AABBInFrustum(bounds[0], bounds[1]))
{
+ regionp->calculateCameraDistance();
regionp->getLand().updatePatchVisibilities(gAgent);
}
- }
- else
- {
- mVisibleRegionList.erase(curiter);
- mCulledRegionList.push_back(regionp);
+ else
+ {
+ mVisibleRegionList.erase(curiter);
+ mCulledRegionList.push_back(regionp);
+ }
}
}
@@ -640,115 +674,82 @@ void LLWorld::updateVisibilities()
LLViewerCamera::getInstance()->setFar(cur_far_clip);
}
+static LLTrace::SampleStatHandle<> sNumActiveCachedObjects("numactivecachedobjects", "Number of objects loaded from cache");
+
void LLWorld::updateRegions(F32 max_update_time)
{
- LLMemType mt_ur(LLMemType::MTYPE_IDLE_UPDATE_REGIONS);
LLTimer update_timer;
- BOOL did_one = FALSE;
+ mNumOfActiveCachedObjects = 0;
- // Perform idle time updates for the regions (and associated surfaces)
- for (region_list_t::iterator iter = mRegionList.begin();
- iter != mRegionList.end(); ++iter)
+ if(LLViewerCamera::getInstance()->isChanged())
{
- LLViewerRegion* regionp = *iter;
- F32 max_time = max_update_time - update_timer.getElapsedTimeF32();
- if (did_one && max_time <= 0.f)
- break;
- max_time = llmin(max_time, max_update_time*.1f);
- did_one |= regionp->idleUpdate(max_update_time);
+ LLViewerRegion::sLastCameraUpdated = LLViewerOctreeEntryData::getCurrentFrame() + 1;
}
-}
-
-void LLWorld::updateParticles()
-{
- LLViewerPartSim::getInstance()->updateSimulation();
-}
-
-void LLWorld::updateClouds(const F32 dt)
-{
- static LLFastTimer::DeclareTimer ftm("World Clouds");
- LLFastTimer t(ftm);
-
- if ( gSavedSettings.getBOOL("FreezeTime") )
+ LLViewerRegion::calcNewObjectCreationThrottle();
+ if(LLViewerRegion::isNewObjectCreationThrottleDisabled())
{
- // don't move clouds in snapshot mode
- return;
+ max_update_time = llmax(max_update_time, 1.0f); //seconds, loosen the time throttle.
}
- if (
- mClassicCloudsEnabled !=
- gSavedSettings.getBOOL("SkyUseClassicClouds") )
- {
- // The classic cloud toggle has been flipped
- // gotta update all of the cloud layers
- mClassicCloudsEnabled =
- gSavedSettings.getBOOL("SkyUseClassicClouds");
+ F32 max_time = llmin((F32)(max_update_time - update_timer.getElapsedTimeF32()), max_update_time * 0.25f);
+ //update the self avatar region
+ LLViewerRegion* self_regionp = gAgent.getRegion();
+ if(self_regionp)
+ {
+ self_regionp->idleUpdate(max_time);
+ }
- if ( !mClassicCloudsEnabled && mActiveRegionList.size() )
+ //sort regions by its mLastUpdate
+ //smaller mLastUpdate first to make sure every region has chance to get updated.
+ LLViewerRegion::region_priority_list_t region_list;
+ for (region_list_t::iterator iter = mRegionList.begin();
+ iter != mRegionList.end(); ++iter)
+ {
+ LLViewerRegion* regionp = *iter;
+ if(regionp != self_regionp)
{
- // We've transitioned to having classic clouds disabled
- // reset all cloud layers.
- for (
- region_list_t::iterator iter = mActiveRegionList.begin();
- iter != mActiveRegionList.end();
- ++iter)
- {
- LLViewerRegion* regionp = *iter;
- regionp->mCloudLayer.reset();
- }
-
- return;
+ region_list.insert(regionp);
}
+ mNumOfActiveCachedObjects += regionp->getNumOfActiveCachedObjects();
}
- else if ( !mClassicCloudsEnabled ) return;
- if (mActiveRegionList.size())
+ // Perform idle time updates for the regions (and associated surfaces)
+ for (LLViewerRegion::region_priority_list_t::iterator iter = region_list.begin();
+ iter != region_list.end(); ++iter)
{
- for (region_list_t::iterator iter = mActiveRegionList.begin();
- iter != mActiveRegionList.end(); ++iter)
+ if(max_time > 0.f)
{
- LLViewerRegion* regionp = *iter;
- regionp->mCloudLayer.updatePuffs(dt);
+ max_time = llmin((F32)(max_update_time - update_timer.getElapsedTimeF32()), max_update_time * 0.25f);
}
- // Reshuffle who owns which puffs
- for (region_list_t::iterator iter = mActiveRegionList.begin();
- iter != mActiveRegionList.end(); ++iter)
+ if(max_time > 0.f)
{
- LLViewerRegion* regionp = *iter;
- regionp->mCloudLayer.updatePuffOwnership();
+ (*iter)->idleUpdate(max_time);
}
-
- // Add new puffs
- for (region_list_t::iterator iter = mActiveRegionList.begin();
- iter != mActiveRegionList.end(); ++iter)
+ else
{
- LLViewerRegion* regionp = *iter;
- regionp->mCloudLayer.updatePuffCount();
- }
+ //perform some necessary but very light updates.
+ (*iter)->lightIdleUpdate();
+ }
}
-}
-LLCloudGroup* LLWorld::findCloudGroup(const LLCloudPuff &puff)
+ sample(sNumActiveCachedObjects, mNumOfActiveCachedObjects);
+ }
+
+void LLWorld::clearAllVisibleObjects()
{
- if (mActiveRegionList.size())
+ for (region_list_t::iterator iter = mRegionList.begin();
+ iter != mRegionList.end(); ++iter)
{
- // Update all the cloud puff positions, and timer based stuff
- // such as death decay
- for (region_list_t::iterator iter = mActiveRegionList.begin();
- iter != mActiveRegionList.end(); ++iter)
- {
- LLViewerRegion* regionp = *iter;
- LLCloudGroup *groupp = regionp->mCloudLayer.findCloudGroup(puff);
- if (groupp)
- {
- return groupp;
- }
- }
+ //clear all cached visible objects.
+ (*iter)->clearCachedVisibleObjects();
}
- return NULL;
}
+void LLWorld::updateParticles()
+{
+ LLViewerPartSim::getInstance()->updateSimulation();
+}
void LLWorld::renderPropertyLines()
{
@@ -767,7 +768,7 @@ void LLWorld::renderPropertyLines()
void LLWorld::updateNetStats()
{
- F32 bits = 0.f;
+ F64Bits bits;
U32 packets = 0;
for (region_list_t::iterator iter = mActiveRegionList.begin();
@@ -775,29 +776,31 @@ void LLWorld::updateNetStats()
{
LLViewerRegion* regionp = *iter;
regionp->updateNetStats();
- bits += regionp->mBitStat.getCurrent();
- packets += llfloor( regionp->mPacketsStat.getCurrent() );
+ bits += regionp->mBitsReceived;
+ packets += llfloor( regionp->mPacketsReceived );
+ regionp->mBitsReceived = (F32Bits)0.f;
+ regionp->mPacketsReceived = 0.f;
}
S32 packets_in = gMessageSystem->mPacketsIn - mLastPacketsIn;
S32 packets_out = gMessageSystem->mPacketsOut - mLastPacketsOut;
S32 packets_lost = gMessageSystem->mDroppedPackets - mLastPacketsLost;
- S32 actual_in_bits = gMessageSystem->mPacketRing.getAndResetActualInBits();
- S32 actual_out_bits = gMessageSystem->mPacketRing.getAndResetActualOutBits();
- LLViewerStats::getInstance()->mActualInKBitStat.addValue(actual_in_bits/1024.f);
- LLViewerStats::getInstance()->mActualOutKBitStat.addValue(actual_out_bits/1024.f);
- LLViewerStats::getInstance()->mKBitStat.addValue(bits/1024.f);
- LLViewerStats::getInstance()->mPacketsInStat.addValue(packets_in);
- LLViewerStats::getInstance()->mPacketsOutStat.addValue(packets_out);
- LLViewerStats::getInstance()->mPacketsLostStat.addValue(gMessageSystem->mDroppedPackets);
- if (packets_in)
- {
- LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(100.f*((F32)packets_lost/(F32)packets_in));
- }
- else
+ F64Bits actual_in_bits(gMessageSystem->mPacketRing.getAndResetActualInBits());
+ F64Bits actual_out_bits(gMessageSystem->mPacketRing.getAndResetActualOutBits());
+
+ add(LLStatViewer::MESSAGE_SYSTEM_DATA_IN, actual_in_bits);
+ add(LLStatViewer::MESSAGE_SYSTEM_DATA_OUT, actual_out_bits);
+ add(LLStatViewer::ACTIVE_MESSAGE_DATA_RECEIVED, bits);
+ add(LLStatViewer::PACKETS_IN, packets_in);
+ add(LLStatViewer::PACKETS_OUT, packets_out);
+ add(LLStatViewer::PACKETS_LOST, packets_lost);
+
+ F32 total_packets_in = LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_IN);
+ if (total_packets_in > 0)
{
- LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(0.f);
+ F32 total_packets_lost = LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_LOST);
+ sample(LLStatViewer::PACKETS_LOST_PERCENT, LLUnits::Ratio::fromValue((F32)total_packets_lost/(F32)total_packets_in));
}
mLastPacketsIn = gMessageSystem->mPacketsIn;
@@ -808,8 +811,8 @@ void LLWorld::updateNetStats()
void LLWorld::printPacketsLost()
{
- llinfos << "Simulators:" << llendl;
- llinfos << "----------" << llendl;
+ LL_INFOS() << "Simulators:" << LL_ENDL;
+ LL_INFOS() << "----------" << LL_ENDL;
LLCircuitData *cdp = NULL;
for (region_list_t::iterator iter = mActiveRegionList.begin();
@@ -821,8 +824,8 @@ void LLWorld::printPacketsLost()
{
LLVector3d range = regionp->getCenterGlobal() - gAgent.getPositionGlobal();
- llinfos << regionp->getHost() << ", range: " << range.length()
- << " packets lost: " << cdp->getPacketsLost() << llendl;
+ LL_INFOS() << regionp->getHost() << ", range: " << range.length()
+ << " packets lost: " << cdp->getPacketsLost() << LL_ENDL;
}
}
}
@@ -870,42 +873,6 @@ void LLWorld::waterHeightRegionInfo(std::string const& sim_name, F32 water_heigh
}
}
-// 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())
@@ -914,191 +881,32 @@ void LLWorld::updateWaterObjects()
}
if (mRegionList.empty())
{
- llwarns << "No regions!" << llendl;
+ LL_WARNS() << "No regions!" << LL_ENDL;
return;
}
- // Region width in meters.
- S32 const rwidth = (S32)REGION_WIDTH_U32;
+ // First, determine the min and max "box" of water objects
+ S32 min_x = 0;
+ S32 min_y = 0;
+ S32 max_x = 0;
+ S32 max_y = 0;
+ U32 region_x, region_y;
- // The distance we might see into the void
- // when standing on the edge of a region, in meters.
- S32 const draw_distance = llceil(mLandFarClip);
+ S32 rwidth = 256;
- // 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;
+ // We only want to fill in water for stuff that's near us, say, within 256 or 512m
+ S32 range = LLViewerCamera::getInstance()->getFar() > 256.f ? 512 : 256;
- // Get South-West corner of current region.
- LLViewerRegion const* regionp = gAgent.getRegion();
- U32 region_x, region_y;
+ LLViewerRegion* regionp = gAgent.getRegion();
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 + range;
- S32 const max_y = (S32)region_y + 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;
+ min_x = (S32)region_x - range;
+ min_y = (S32)region_y - range;
+ max_x = (S32)region_x + range;
+ max_y = (S32)region_y + range;
- // Update all Region water objects.
- for (region_list_t::iterator iter = mRegionList.begin(); iter != mRegionList.end(); ++iter)
+ for (region_list_t::iterator iter = mRegionList.begin();
+ iter != mRegionList.end(); ++iter)
{
LLViewerRegion* regionp = *iter;
LLVOWater* waterp = regionp->getLand().getWaterObj();
@@ -1108,75 +916,96 @@ void LLWorld::updateWaterObjects()
}
}
- // Clean up all existing Hole water objects.
for (std::list<LLVOWater*>::iterator iter = mHoleWaterObjects.begin();
- iter != mHoleWaterObjects.end(); ++iter)
+ 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;
+ // Use the water height of the region we're on for areas where there is no region
+ F32 water_height = gAgent.getRegion()->getWaterHeight();
- // Create new Hole water objects within 'range' where there is no region.
- for (S32 x = min_x; x <= max_x; x += rwidth)
+ // Now, get a list of the holes
+ S32 x, y;
+ for (x = min_x; x <= max_x; x += rwidth)
{
- for (S32 y = min_y; y <= max_y; y += rwidth)
+ for (y = min_y; y <= max_y; y += rwidth)
{
U64 region_handle = to_region_handle(x, y);
if (!getRegionFromHandle(region_handle))
- {
- LLVOWater* waterp = (LLVOWater*)gObjectList.createObjectViewer(LLViewerObject::LL_VO_VOID_WATER, gAgent.getRegion());
+ { // No region at that area, so make water
+ LLVOWater* waterp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, gAgent.getRegion());
waterp->setUseTexture(FALSE);
- waterp->setPositionGlobal(LLVector3d(x + rwidth / 2, y + rwidth / 2, water_center_z));
- waterp->setScale(LLVector3((F32)rwidth, (F32)rwidth, box_height));
+ waterp->setPositionGlobal(LLVector3d(x + rwidth/2,
+ y + rwidth/2,
+ 256.f + water_height));
+ waterp->setScale(LLVector3((F32)rwidth, (F32)rwidth, 512.f));
gPipeline.createObject(waterp);
mHoleWaterObjects.push_back(waterp);
}
}
}
- // Center of the region.
- S32 const center_x = region_x + rwidth / 2;
- S32 const center_y = region_y + rwidth / 2;
- // Width of the area with Hole water objects.
- S32 const width = rwidth + 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.
+ // Update edge water objects
+ S32 wx, wy;
+ S32 center_x, center_y;
+ wx = (max_x - min_x) + rwidth;
+ wy = (max_y - min_y) + rwidth;
+ center_x = min_x + (wx >> 1);
+ center_y = min_y + (wy >> 1);
+
+ S32 add_boundary[4] = {
+ 512 - (max_x - region_x),
+ 512 - (max_y - region_y),
+ 512 - (region_x - min_x),
+ 512 - (region_y - min_y) };
- for (S32 dir = 0; dir < 8; ++dir)
+ S32 dir;
+ for (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];
+ S32 dim[2] = { 0 };
+ switch (gDirAxes[dir][0])
+ {
+ case -1: dim[0] = add_boundary[2]; break;
+ case 0: dim[0] = wx; break;
+ default: dim[0] = add_boundary[0]; break;
+ }
+ switch (gDirAxes[dir][1])
+ {
+ case -1: dim[1] = add_boundary[3]; break;
+ case 0: dim[1] = wy; break;
+ default: dim[1] = add_boundary[1]; break;
+ }
+ // Resize and reshape the water objects
+ const S32 water_center_x = center_x + ll_round((wx + dim[0]) * 0.5f * gDirAxes[dir][0]);
+ const S32 water_center_y = center_y + ll_round((wy + dim[1]) * 0.5f * 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());
+ 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.
+ waterp->setIsEdgePatch(TRUE);
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);
+ LLVector3d water_pos(water_center_x, water_center_y, 256.f + water_height) ;
+ LLVector3 water_scale((F32) dim[0], (F32) dim[1], 512.f);
+
+ //stretch out to horizon
+ water_scale.mV[0] += fabsf(2048.f * gDirAxes[dir][0]);
+ water_scale.mV[1] += fabsf(2048.f * gDirAxes[dir][1]);
+
+ water_pos.mdV[0] += 1024.f * gDirAxes[dir][0];
+ water_pos.mdV[1] += 1024.f * gDirAxes[dir][1];
waterp->setPositionGlobal(water_pos);
waterp->setScale(water_scale);
@@ -1185,6 +1014,7 @@ void LLWorld::updateWaterObjects()
}
}
+
void LLWorld::shiftRegions(const LLVector3& offset)
{
for (region_list_t::const_iterator i = getRegionList().begin(); i != getRegionList().end(); ++i)
@@ -1201,12 +1031,12 @@ LLViewerTexture* LLWorld::getDefaultWaterTexture()
return mDefaultWaterTexturep;
}
-void LLWorld::setSpaceTimeUSec(const U64 space_time_usec)
+void LLWorld::setSpaceTimeUSec(const U64MicrosecondsImplicit space_time_usec)
{
mSpaceTimeUSec = space_time_usec;
}
-U64 LLWorld::getSpaceTimeUSec() const
+U64MicrosecondsImplicit LLWorld::getSpaceTimeUSec() const
{
return mSpaceTimeUSec;
}
@@ -1246,7 +1076,7 @@ void LLWorld::disconnectRegions()
continue;
}
- llinfos << "Sending AgentQuitCopy to: " << regionp->getHost() << llendl;
+ LL_INFOS() << "Sending AgentQuitCopy to: " << regionp->getHost() << LL_ENDL;
msg->newMessageFast(_PREHASH_AgentQuitCopy);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
@@ -1257,11 +1087,11 @@ void LLWorld::disconnectRegions()
}
}
-static LLFastTimer::DeclareTimer FTM_ENABLE_SIMULATOR("Enable Sim");
+static LLTrace::BlockTimerStatHandle FTM_ENABLE_SIMULATOR("Enable Sim");
void process_enable_simulator(LLMessageSystem *msg, void **user_data)
{
- LLFastTimer t(FTM_ENABLE_SIMULATOR);
+ LL_RECORD_BLOCK_TIME(FTM_ENABLE_SIMULATOR);
// enable the appropriate circuit for this simulator and
// add its values into the gSimulator structure
U64 handle;
@@ -1280,7 +1110,7 @@ void process_enable_simulator(LLMessageSystem *msg, void **user_data)
LLWorld::getInstance()->addRegion(handle, sim);
// give the simulator a message it can use to get ip and port
- llinfos << "simulator_enable() Enabling " << sim << " with code " << msg->getOurCircuitCode() << llendl;
+ LL_INFOS() << "simulator_enable() Enabling " << sim << " with code " << msg->getOurCircuitCode() << LL_ENDL;
msg->newMessageFast(_PREHASH_UseCircuitCode);
msg->nextBlockFast(_PREHASH_CircuitCode);
msg->addU32Fast(_PREHASH_Code, msg->getOurCircuitCode());
@@ -1308,7 +1138,7 @@ public:
!input["body"].has("sim-ip-and-port") ||
!input["body"].has("seed-capability"))
{
- llwarns << "invalid parameters" << llendl;
+ LL_WARNS() << "invalid parameters" << LL_ENDL;
return;
}
@@ -1317,10 +1147,12 @@ public:
LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(sim);
if (!regionp)
{
- llwarns << "Got EstablishAgentCommunication for unknown region "
- << sim << llendl;
+ LL_WARNS() << "Got EstablishAgentCommunication for unknown region "
+ << sim << LL_ENDL;
return;
}
+ LL_DEBUGS("CrossingCaps") << "Calling setSeedCapability from LLEstablishAgentCommunication::post. Seed cap == "
+ << input["body"]["seed-capability"] << LL_ENDL;
regionp->setSeedCapability(input["body"]["seed-capability"]);
}
};
@@ -1331,7 +1163,7 @@ void process_disable_simulator(LLMessageSystem *mesgsys, void **user_data)
{
LLHost host = mesgsys->getSender();
- //llinfos << "Disabling simulator with message from " << host << llendl;
+ //LL_INFOS() << "Disabling simulator with message from " << host << LL_ENDL;
LLWorld::getInstance()->removeRegion(host);
mesgsys->disableCircuit(host);
@@ -1344,8 +1176,8 @@ void process_region_handshake(LLMessageSystem* msg, void** user_data)
LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(host);
if (!regionp)
{
- llwarns << "Got region handshake for unknown region "
- << host << llendl;
+ LL_WARNS() << "Got region handshake for unknown region "
+ << host << LL_ENDL;
return;
}
@@ -1383,6 +1215,7 @@ void send_agent_pause()
}
gObjectList.mWasPaused = TRUE;
+ LLViewerStats::instance().getRecording().stop();
}
@@ -1412,36 +1245,27 @@ void send_agent_resume()
gMessageSystem->sendReliable(regionp->getHost());
}
- // Reset the FPS counter to avoid an invalid fps
- LLViewerStats::getInstance()->mFPSStat.start();
+ // Resume data collection to ignore invalid rates
+ LLViewerStats::instance().getRecording().resume();
LLAppViewer::instance()->resumeMainloopTimeout();
}
static LLVector3d unpackLocalToGlobalPosition(U32 compact_local, const LLVector3d& region_origin)
{
- LLVector3d pos_global;
- LLVector3 pos_local;
- U8 bits;
-
- bits = compact_local & 0xFF;
- pos_local.mV[VZ] = F32(bits) * 4.f;
- compact_local >>= 8;
+ LLVector3d pos_local;
- bits = compact_local & 0xFF;
- pos_local.mV[VY] = (F32)bits;
- compact_local >>= 8;
+ pos_local.mdV[VZ] = (compact_local & 0xFFU) * 4;
+ pos_local.mdV[VY] = (compact_local >> 8) & 0xFFU;
+ pos_local.mdV[VX] = (compact_local >> 16) & 0xFFU;
- bits = compact_local & 0xFF;
- pos_local.mV[VX] = (F32)bits;
-
- pos_global.setVec( pos_local );
- pos_global += region_origin;
- return pos_global;
+ return region_origin + pos_local;
}
void LLWorld::getAvatars(uuid_vec_t* 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();
@@ -1450,30 +1274,69 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector<LLVector3d>* positi
{
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->mIsDummy)
+ {
+ LLVector3d pos_global = pVOAvatar->getPositionGlobal();
+ LLUUID uuid = pVOAvatar->getID();
+
+ if (!uuid.isNull()
+ && 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();
+ S32 count = regionp->mMapAvatars.size();
for (S32 i = 0; i < count; i++)
{
- LLVector3d pos_global = unpackLocalToGlobalPosition(regionp->mMapAvatars.get(i), origin_global);
- if(dist_vec(pos_global, relative_to) <= radius)
+ LLVector3d pos_global = unpackLocalToGlobalPosition(regionp->mMapAvatars.at(i), origin_global);
+ if(dist_vec_squared(pos_global, relative_to) <= radius_squared)
{
- if(positions != NULL)
- {
- positions->push_back(pos_global);
- }
- if(avatar_ids != NULL)
+ LLUUID uuid = regionp->mMapAvatarIDs.at(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())
{
- avatar_ids->push_back(regionp->mMapAvatarIDs.get(i));
+ if (positions != NULL)
+ {
+ positions->push_back(pos_global);
+ }
+ avatar_ids->push_back(uuid);
}
}
}
}
}
+bool LLWorld::isRegionListed(const LLViewerRegion* region) const
+{
+ region_list_t::const_iterator it = find(mRegionList.begin(), mRegionList.end(), region);
+ return it != mRegionList.end();
+}
+
+boost::signals2::connection LLWorld::setRegionRemovedCallback(const region_remove_signal_t::slot_type& cb)
+{
+ return mRegionRemovedSignal.connect(cb);
+}
LLHTTPRegistration<LLEstablishAgentCommunication>
gHTTPRegistrationEstablishAgentCommunication(