diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp index 6d1d3498c..63119a358 100644 --- a/indra/llmessage/message_prehash.cpp +++ b/indra/llmessage/message_prehash.cpp @@ -584,6 +584,7 @@ char const* const _PREHASH_LastName = LLMessageStringTable::getInstance()->getSt char const* const _PREHASH_From = LLMessageStringTable::getInstance()->getString("From"); char const* const _PREHASH_RoleChange = LLMessageStringTable::getInstance()->getString("RoleChange"); char const* const _PREHASH_Port = LLMessageStringTable::getInstance()->getString("Port"); +char const* const _PREHASH_RegionSizeX = LLMessageStringTable::getInstance()->getString("RegionSizeX"); char const* const _PREHASH_MemberTitle = LLMessageStringTable::getInstance()->getString("MemberTitle"); char const* const _PREHASH_LogParcelChanges = LLMessageStringTable::getInstance()->getString("LogParcelChanges"); char const* const _PREHASH_AgentCachedTextureResponse = LLMessageStringTable::getInstance()->getString("AgentCachedTextureResponse"); diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h index d388d8629..0130f399b 100644 --- a/indra/llmessage/message_prehash.h +++ b/indra/llmessage/message_prehash.h @@ -584,6 +584,7 @@ extern char const* const _PREHASH_LastName; extern char const* const _PREHASH_From; extern char const* const _PREHASH_RoleChange; extern char const* const _PREHASH_Port; +extern char const* const _PREHASH_RegionSizeX; extern char const* const _PREHASH_MemberTitle; extern char const* const _PREHASH_LogParcelChanges; extern char const* const _PREHASH_AgentCachedTextureResponse; diff --git a/indra/llmessage/patch_code.cpp b/indra/llmessage/patch_code.cpp index e5d7f1944..7d8559931 100644 --- a/indra/llmessage/patch_code.cpp +++ b/indra/llmessage/patch_code.cpp @@ -229,7 +229,7 @@ void decode_patch_group_header(LLBitPack &bitpack, LLGroupHeader *gopp) gPatchSize = gopp->patch_size; } -void decode_patch_header(LLBitPack &bitpack, LLPatchHeader *ph) +void decode_patch_header(LLBitPack &bitpack, LLPatchHeader *ph, bool b_large_patch) { U8 retvalu8; @@ -268,15 +268,28 @@ void decode_patch_header(LLBitPack &bitpack, LLPatchHeader *ph) #endif ph->range = retvalu16; - retvalu16 = 0; + retvalu32 = 0; #ifdef LL_BIG_ENDIAN - ret = (U8 *)&retvalu16; - bitpack.bitUnpack(&(ret[1]), 8); - bitpack.bitUnpack(&(ret[0]), 2); + ret = (U8*)&retvalu32; + if (b_large_patch) + { + bitpack.bitUnpack(&(ret[3]), 8); + bitpack.bitUnpack(&(ret[2]), 8); + bitpack.bitUnpack(&(ret[1]), 8); + bitpack.bitUnpack(&(ret[0]), 8); + } + else + { + bitpack.bitUnpack(&(ret[1]), 8); + bitpack.bitUnpack(&(ret[0]), 2); + } #else - bitpack.bitUnpack((U8 *)&retvalu16, 10); + if (b_large_patch) + bitpack.bitUnpack((U8*)&retvalu32, 32); + else + bitpack.bitUnpack((U8*)&retvalu32, 10); #endif - ph->patchids = retvalu16; + ph->patchids = retvalu32; gWordBits = (ph->quant_wbits & 0xf) + 2; } diff --git a/indra/llmessage/patch_code.h b/indra/llmessage/patch_code.h index 4c87c9808..bdaabe70b 100644 --- a/indra/llmessage/patch_code.h +++ b/indra/llmessage/patch_code.h @@ -40,7 +40,7 @@ void end_patch_coding(LLBitPack &bitpack); void init_patch_decoding(LLBitPack &bitpack); void decode_patch_group_header(LLBitPack &bitpack, LLGroupHeader *gopp); -void decode_patch_header(LLBitPack &bitpack, LLPatchHeader *ph); +void decode_patch_header(LLBitPack &bitpack, LLPatchHeader *ph, bool b_large_patch = false); void decode_patch(LLBitPack &bitpack, S32 *patches); #endif diff --git a/indra/llmessage/patch_dct.h b/indra/llmessage/patch_dct.h index 101231ec8..9f5d60425 100644 --- a/indra/llmessage/patch_dct.h +++ b/indra/llmessage/patch_dct.h @@ -73,7 +73,7 @@ public: F32 dc_offset; // 4 bytes U16 range; // 2 = 7 ((S16) FP range (breaks if we need > 32K meters in 1 patch) U8 quant_wbits; // 1 = 8 (upper 4 bits is quant - 2, lower 4 bits is word bits - 2) - U16 patchids; // 2 = 10 (actually only uses 10 bits, 5 for each) + U32 patchids; // 2 = 10 (actually only uses 10 bits, 5 for each) }; // Compression routines diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 61b771ea2..c74e59cd6 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -2272,7 +2272,7 @@ void LLAgent::setStartPosition( U32 location_id ) // this simulator. Clamp it to the region the agent is // in, a little bit in on each side. const F32 INSET = 0.5f; //meters - const F32 REGION_WIDTH = LLWorld::getInstance()->getRegionWidthInMeters(); + const F32 REGION_WIDTH = getRegion()->getWidth(); LLVector3 agent_pos = getPositionAgent(); diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index bc6dbbde0..a6978fc68 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -82,6 +82,7 @@ #include "llviewerwindow.h" #include "llvlcomposition.h" #include "llagentui.h" +#include "hippogridmanager.h" // [RLVa:KB] #include "rlvhandler.h" // [/RLVa:KB] @@ -1105,8 +1106,8 @@ BOOL LLPanelRegionTextureInfo::sendUpdate() { llinfos << "LLPanelRegionTextureInfo::sendUpdate()" << llendl; - // Make sure user hasn't chosen wacky textures. - if (!validateTextureSizes()) + // Make sure user hasn't chosen wacky textures on sl grids. + if (gHippoGridManager->getConnectedGrid()->isSecondLife() && !validateTextureSizes()) { return FALSE; } diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index be658d131..e41080de7 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -297,7 +297,7 @@ void LLWind::renderVectors() S32 i,j; F32 x,y; - F32 region_width_meters = LLWorld::getInstance()->getRegionWidthInMeters(); + F32 region_width_meters = gAgent.getRegion()->getWidth(); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.pushMatrix(); @@ -505,7 +505,7 @@ void LLViewerParcelMgr::renderOneSegment(F32 x1, F32 y1, F32 x2, F32 y2, F32 hei return; // HACK: At edge of last region of world, we need to make sure the region // resolves correctly so we can get a height value. - const F32 BORDER = REGION_WIDTH_METERS - 0.1f; + const F32 BORDER = regionp->getWidth() - 0.1f; F32 clamped_x1 = x1; F32 clamped_y1 = y1; diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp index 3ffb93f69..40da060fb 100644 --- a/indra/newview/llmanip.cpp +++ b/indra/newview/llmanip.cpp @@ -53,9 +53,9 @@ #include "llviewercamera.h" #include "llviewerjoint.h" #include "llviewerobject.h" +#include "llviewerregion.h" #include "llviewerwindow.h" #include "llvoavatar.h" -#include "llworld.h" // for LLWorld::getInstance() #include "llresmgr.h" #include "pipeline.h" #include "llglheaders.h" @@ -405,7 +405,7 @@ void LLManip::renderGuidelines(BOOL draw_x, BOOL draw_y, BOOL draw_z) grid_rot.getAngleAxis(&angle_radians, &x, &y, &z); gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z); - F32 region_size = LLWorld::getInstance()->getRegionWidthInMeters(); + F32 region_size = object->getRegion()->getWidth(); const F32 LINE_ALPHA = 0.33f; diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp index e1e6552f9..d6668c838 100644 --- a/indra/newview/llmanipscale.cpp +++ b/indra/newview/llmanipscale.cpp @@ -1356,7 +1356,7 @@ void LLManipScale::renderGuidelinesPart( const LLBBox& bbox ) guideline_end -= guideline_start; guideline_end.normVec(); - guideline_end *= LLWorld::getInstance()->getRegionWidthInMeters(); + guideline_end *= gAgent.getRegion()->getWidth(); guideline_end += guideline_start; { diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 724b15c94..be47072d5 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -105,7 +105,7 @@ LLNetMap::LLNetMap(const std::string& name) : mUpdateNow( FALSE ) { mScale = gSavedSettings.getF32("MiniMapScale"); - mPixelsPerMeter = mScale / LLWorld::getInstance()->getRegionWidthInMeters(); + mPixelsPerMeter = mScale / REGION_WIDTH_METERS; mDotRadius = llmax(DOT_SCALE * mPixelsPerMeter, MIN_DOT_RADIUS); mObjectImageCenterGlobal = gAgentCamera.getCameraPositionGlobal(); @@ -161,13 +161,13 @@ void LLNetMap::setScale( F32 scale ) F32 height = (F32)(getRect().getHeight()); F32 diameter = sqrt(width * width + height * height); F32 region_widths = diameter / mScale; - F32 meters = region_widths * LLWorld::getInstance()->getRegionWidthInMeters(); + F32 meters = region_widths * REGION_WIDTH_METERS; F32 num_pixels = (F32)mObjectImagep->getWidth(); mObjectMapTPM = num_pixels / meters; mObjectMapPixels = diameter; } - mPixelsPerMeter = mScale / LLWorld::getInstance()->getRegionWidthInMeters(); + mPixelsPerMeter = mScale / REGION_WIDTH_METERS; mDotRadius = llmax(DOT_SCALE * mPixelsPerMeter, MIN_DOT_RADIUS); mUpdateNow = TRUE; @@ -262,8 +262,8 @@ void LLNetMap::draw() // background region rectangle F32 bottom = relative_y; F32 left = relative_x; - F32 top = bottom + mScale ; - F32 right = left + mScale ; + F32 top = bottom + region_width/256 * mScale ; + F32 right = left + region_width/256 * mScale ; gGL.color4fv(regionp == gAgent.getRegion() ? this_region_color.mV : live_region_color.mV); if (!regionp->isAlive()) @@ -332,8 +332,8 @@ void LLNetMap::draw() LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal); map_center_agent -= gAgentCamera.getCameraPositionAgent(); - map_center_agent.mV[0] *= mScale/LLWorld::getInstance()->getRegionWidthInMeters(); - map_center_agent.mV[1] *= mScale/LLWorld::getInstance()->getRegionWidthInMeters(); + map_center_agent.mV[0] *= mScale/256; + map_center_agent.mV[1] *= mScale/256; gGL.getTexUnit(0)->bind(mObjectImagep); F32 image_half_width = 0.5f*mObjectMapPixels; @@ -470,7 +470,7 @@ void LLNetMap::draw() dot_width); // Draw frustum - F32 meters_to_pixels = mScale/ LLWorld::getInstance()->getRegionWidthInMeters(); + F32 meters_to_pixels = mScale/ REGION_WIDTH_METERS; F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect(); F32 far_clip_meters = LLViewerCamera::getInstance()->getFar(); @@ -597,7 +597,7 @@ LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y, BOOL rotated ) pos_local.rotVec( rot ); } - pos_local *= ( LLWorld::getInstance()->getRegionWidthInMeters() / mScale ); + pos_local *= ( REGION_WIDTH_METERS / mScale ); LLVector3d pos_global; pos_global.setVec( pos_local ); diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index b1f702bcd..88871d4cc 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -2522,7 +2522,7 @@ void LLPanelObject::onPastePos(void* user_data) LLPanelObject* self = (LLPanelObject*) user_data; LLCalc* calcp = LLCalc::getInstance(); - float region_width = LLWorld::getInstance()->getRegionWidthInMeters(); + float region_width = gAgent.getRegion()->getWidth(); mClipboardPos.mV[VX] = llclamp( mClipboardPos.mV[VX], -3.5f, region_width); mClipboardPos.mV[VY] = llclamp( mClipboardPos.mV[VY], -3.5f, region_width); mClipboardPos.mV[VZ] = llclamp( mClipboardPos.mV[VZ], -3.5f, 4096.f); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 6d1e2d92c..3a86800f5 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -4197,7 +4197,10 @@ bool process_login_success_response(std::string& password) U32 region_y = strtoul(region_y_str.c_str(), NULL, 10); gFirstSimHandle = to_region_handle(region_x, region_y); } - + + text = response["region_size_x"].asString(); + if (!text.empty()) LLViewerParcelMgr::getInstance()->widthUpdate(atoi(text.c_str())); + const std::string look_at_str = response["look_at"]; if (!look_at_str.empty()) { diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index bd1b99911..9b9376d11 100644 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -172,6 +172,7 @@ void LLSurface::create(const S32 grids_per_edge, mNumberOfPatches = mPatchesPerEdge * mPatchesPerEdge; mMetersPerGrid = width / ((F32)(mGridsPerEdge - 1)); mMetersPerEdge = mMetersPerGrid * (mGridsPerEdge - 1); + sTextureSize = width; mOriginGlobal.setVec(origin_global); @@ -295,7 +296,7 @@ void LLSurface::initTextures() 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); + water_pos_global += LLVector3d(mRegionp->getWidth()/2, mRegionp->getWidth()/2, DEFAULT_WATER_HEIGHT); mWaterObjp->setPositionGlobal(water_pos_global); } } @@ -325,8 +326,8 @@ void LLSurface::setOriginGlobal(const LLVector3d &origin_global) // Hack! if (mWaterObjp.notNull() && mWaterObjp->mDrawable.notNull()) { - const F64 x = origin_global.mdV[VX] + 128.0; - const F64 y = origin_global.mdV[VY] + 128.0; + const F64 x = origin_global.mdV[VX] + (F64)mRegionp->getWidth()/2; + const F64 y = origin_global.mdV[VY] + (F64)mRegionp->getWidth()/2; const F64 z = mWaterObjp->getPositionGlobal().mdV[VZ]; LLVector3d water_origin_global(x, y, z); @@ -364,15 +365,49 @@ void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction) { S32 i; LLSurfacePatch *patchp, *neighbor_patchp; + S32 neighborPatchesPerEdge = neighborp->mPatchesPerEdge; mNeighbors[direction] = neighborp; neighborp->mNeighbors[gDirOpposite[direction]] = this; + S32 ppe[2]; + S32 own_offset[2] = {0, 0}; + S32 neighbor_offset[2] = {0, 0}; + U32 own_xpos, own_ypos, neighbor_xpos, neighbor_ypos; + + ppe[0] = (mPatchesPerEdge < neighborPatchesPerEdge) ? mPatchesPerEdge : neighborPatchesPerEdge; // used for x + ppe[1] = ppe[0]; // used for y + + from_region_handle(mRegionp->getHandle(), &own_xpos, &own_ypos); + from_region_handle(neighborp->getRegion()->getHandle(), &neighbor_xpos, &neighbor_ypos); + + if(own_ypos >= neighbor_ypos) + { + neighbor_offset[1] = (own_ypos - neighbor_ypos) / mGridsPerPatchEdge; + ppe[1] = llmin(mPatchesPerEdge, neighborPatchesPerEdge-neighbor_offset[1]); + } + else + { + own_offset[1] = (neighbor_ypos - own_ypos) / mGridsPerPatchEdge; + ppe[1] = llmin(mPatchesPerEdge-own_offset[1], neighborPatchesPerEdge); + } + + if(own_xpos >= neighbor_xpos) + { + neighbor_offset[0] = (own_xpos - neighbor_xpos) / mGridsPerPatchEdge; + ppe[0] = llmin(mPatchesPerEdge, neighborPatchesPerEdge-neighbor_offset[0]); + } + else + { + own_offset[0] = (neighbor_xpos - own_xpos) / mGridsPerPatchEdge; + ppe[0] = llmin(mPatchesPerEdge-own_offset[0], neighborPatchesPerEdge); + } + // Connect patches if (NORTHEAST == direction) { patchp = getPatch(mPatchesPerEdge - 1, mPatchesPerEdge - 1); - neighbor_patchp = neighborp->getPatch(0, 0); + neighbor_patchp = neighborp->getPatch(neighbor_offset[0], neighbor_offset[1]); //0 patchp->connectNeighbor(neighbor_patchp, direction); neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); @@ -382,8 +417,10 @@ void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction) } else if (NORTHWEST == direction) { + S32 off = mPatchesPerEdge + neighbor_offset[1] - own_offset[1]; + patchp = getPatch(0, mPatchesPerEdge - 1); - neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, 0); + neighbor_patchp = neighborp->getPatch(neighbor_offset[0] - 1, off); //neighborPatchesPerEdge - 1 patchp->connectNeighbor(neighbor_patchp, direction); neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); @@ -391,18 +428,20 @@ void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction) else if (SOUTHWEST == direction) { patchp = getPatch(0, 0); - neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, mPatchesPerEdge - 1); + neighbor_patchp = neighborp->getPatch(neighbor_offset[0] - 1, neighbor_offset[1] - 1); //neighborPatchesPerEdge - 1 patchp->connectNeighbor(neighbor_patchp, direction); neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); - neighbor_patchp->updateNorthEdge(); // Only update one of north or east. + neighbor_patchp->updateEastEdge(); // Only update one of north or east. neighbor_patchp->dirtyZ(); } else if (SOUTHEAST == direction) { + S32 off = mPatchesPerEdge + neighbor_offset[0] - own_offset[0]; + patchp = getPatch(mPatchesPerEdge - 1, 0); - neighbor_patchp = neighborp->getPatch(0, mPatchesPerEdge - 1); + neighbor_patchp = neighborp->getPatch(off, neighbor_offset[1] - 1); //0 patchp->connectNeighbor(neighbor_patchp, direction); neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); @@ -410,10 +449,10 @@ void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction) else if (EAST == direction) { // Do east/west connections, first - for (i = 0; i < (S32)mPatchesPerEdge; i++) + for (i = 0; i < ppe[1]; i++) { - patchp = getPatch(mPatchesPerEdge - 1, i); - neighbor_patchp = neighborp->getPatch(0, i); + patchp = getPatch(mPatchesPerEdge - 1, i + own_offset[1]); + neighbor_patchp = neighborp->getPatch(0, i + neighbor_offset[1]); patchp->connectNeighbor(neighbor_patchp, direction); neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); @@ -423,19 +462,19 @@ void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction) } // Now do northeast/southwest connections - for (i = 0; i < (S32)mPatchesPerEdge - 1; i++) + for (i = 0; i < ppe[1] - 1; i++) { - patchp = getPatch(mPatchesPerEdge - 1, i); - neighbor_patchp = neighborp->getPatch(0, i+1); + patchp = getPatch(mPatchesPerEdge - 1, i + own_offset[1]); + neighbor_patchp = neighborp->getPatch(0, i+1 + neighbor_offset[1]); patchp->connectNeighbor(neighbor_patchp, NORTHEAST); neighbor_patchp->connectNeighbor(patchp, SOUTHWEST); } // Now do southeast/northwest connections - for (i = 1; i < (S32)mPatchesPerEdge; i++) + for (i = 1; i < ppe[1]; i++) { - patchp = getPatch(mPatchesPerEdge - 1, i); - neighbor_patchp = neighborp->getPatch(0, i-1); + patchp = getPatch(mPatchesPerEdge - 1, i + own_offset[1]); + neighbor_patchp = neighborp->getPatch(0, i-1 + neighbor_offset[1]); patchp->connectNeighbor(neighbor_patchp, SOUTHEAST); neighbor_patchp->connectNeighbor(patchp, NORTHWEST); @@ -444,10 +483,10 @@ void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction) else if (NORTH == direction) { // Do north/south connections, first - for (i = 0; i < (S32)mPatchesPerEdge; i++) + for (i = 0; i < ppe[0]; i++) { - patchp = getPatch(i, mPatchesPerEdge - 1); - neighbor_patchp = neighborp->getPatch(i, 0); + patchp = getPatch(i + own_offset[0], mPatchesPerEdge - 1); + neighbor_patchp = neighborp->getPatch(i + neighbor_offset[0], 0); patchp->connectNeighbor(neighbor_patchp, direction); neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); @@ -457,19 +496,19 @@ void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction) } // Do northeast/southwest connections - for (i = 0; i < (S32)mPatchesPerEdge - 1; i++) + for (i = 0; i < ppe[0] - 1; i++) { - patchp = getPatch(i, mPatchesPerEdge - 1); - neighbor_patchp = neighborp->getPatch(i+1, 0); + patchp = getPatch(i + own_offset[0], mPatchesPerEdge - 1); + neighbor_patchp = neighborp->getPatch(i+1 + neighbor_offset[0], 0); patchp->connectNeighbor(neighbor_patchp, NORTHEAST); neighbor_patchp->connectNeighbor(patchp, SOUTHWEST); } // Do southeast/northwest connections - for (i = 1; i < (S32)mPatchesPerEdge; i++) + for (i = 1; i < ppe[0]; i++) { - patchp = getPatch(i, mPatchesPerEdge - 1); - neighbor_patchp = neighborp->getPatch(i-1, 0); + patchp = getPatch(i + own_offset[0], mPatchesPerEdge - 1); + neighbor_patchp = neighborp->getPatch(i-1 + neighbor_offset[0], 0); patchp->connectNeighbor(neighbor_patchp, NORTHWEST); neighbor_patchp->connectNeighbor(patchp, SOUTHEAST); @@ -478,10 +517,10 @@ void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction) else if (WEST == direction) { // Do east/west connections, first - for (i = 0; i < mPatchesPerEdge; i++) + for (i = 0; i < ppe[1]; i++) { - patchp = getPatch(0, i); - neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i); + patchp = getPatch(0, i + own_offset[1]); + neighbor_patchp = neighborp->getPatch(neighborPatchesPerEdge - 1, i + neighbor_offset[1]); patchp->connectNeighbor(neighbor_patchp, direction); neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); @@ -491,20 +530,20 @@ void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction) } // Now do northeast/southwest connections - for (i = 1; i < mPatchesPerEdge; i++) + for (i = 1; i < ppe[1]; i++) { - patchp = getPatch(0, i); - neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i - 1); + patchp = getPatch(0, i + own_offset[1]); + neighbor_patchp = neighborp->getPatch(neighborPatchesPerEdge - 1, i - 1 + neighbor_offset[1]); patchp->connectNeighbor(neighbor_patchp, SOUTHWEST); neighbor_patchp->connectNeighbor(patchp, NORTHEAST); } // Now do northwest/southeast connections - for (i = 0; i < mPatchesPerEdge - 1; i++) + for (i = 0; i < ppe[1] - 1; i++) { - patchp = getPatch(0, i); - neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i + 1); + patchp = getPatch(0, i + own_offset[1]); + neighbor_patchp = neighborp->getPatch(neighborPatchesPerEdge - 1, i + 1 + neighbor_offset[1]); patchp->connectNeighbor(neighbor_patchp, NORTHWEST); neighbor_patchp->connectNeighbor(patchp, SOUTHEAST); @@ -513,10 +552,10 @@ void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction) else if (SOUTH == direction) { // Do north/south connections, first - for (i = 0; i < mPatchesPerEdge; i++) + for (i = 0; i < ppe[0]; i++) { - patchp = getPatch(i, 0); - neighbor_patchp = neighborp->getPatch(i, mPatchesPerEdge - 1); + patchp = getPatch(i + own_offset[0], 0); + neighbor_patchp = neighborp->getPatch(i + neighbor_offset[0], neighborPatchesPerEdge - 1); patchp->connectNeighbor(neighbor_patchp, direction); neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]); @@ -526,19 +565,19 @@ void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction) } // Now do northeast/southwest connections - for (i = 1; i < mPatchesPerEdge; i++) + for (i = 1; i < ppe[0]; i++) { - patchp = getPatch(i, 0); - neighbor_patchp = neighborp->getPatch(i - 1, mPatchesPerEdge - 1); + patchp = getPatch(i + own_offset[0], 0); + neighbor_patchp = neighborp->getPatch(i - 1 + neighbor_offset[0], neighborPatchesPerEdge - 1); patchp->connectNeighbor(neighbor_patchp, SOUTHWEST); neighbor_patchp->connectNeighbor(patchp, NORTHEAST); } // Now do northeast/southwest connections - for (i = 0; i < mPatchesPerEdge - 1; i++) + for (i = 0; i < ppe[0] - 1; i++) { - patchp = getPatch(i, 0); - neighbor_patchp = neighborp->getPatch(i + 1, mPatchesPerEdge - 1); + patchp = getPatch(i + own_offset[0], 0); + neighbor_patchp = neighborp->getPatch(i + 1 + neighbor_offset[0], neighborPatchesPerEdge - 1); patchp->connectNeighbor(neighbor_patchp, SOUTHEAST); neighbor_patchp->connectNeighbor(patchp, NORTHWEST); @@ -700,14 +739,22 @@ void LLSurface::decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL while (1) { - decode_patch_header(bitpack, &ph); + decode_patch_header(bitpack, &ph, b_large_patch); if (ph.quant_wbits == END_OF_PATCHES) { break; } - i = ph.patchids >> 5; - j = ph.patchids & 0x1F; + if (b_large_patch) + { + i = ph.patchids >> 16; + j = ph.patchids & 0xFFFF; + } + else + { + i = ph.patchids >> 5; + j = ph.patchids & 0x1F; + } if ((i >= mPatchesPerEdge) || (j >= mPatchesPerEdge)) { @@ -1229,7 +1276,7 @@ BOOL LLSurface::generateWaterTexture(const F32 x, const F32 y, LLPointer raw = new LLImageRaw(tex_width, tex_height, tex_comps); U8 *rawp = raw->getData(); - F32 scale = 256.f * getMetersPerGrid() / (F32)tex_width; + F32 scale = getRegion()->getWidth() * getMetersPerGrid() / (F32)tex_width; F32 scale_inv = 1.f / scale; S32 x_begin, y_begin, x_end, y_end; diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 3ebea883c..b3a774610 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -249,18 +249,22 @@ void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride) const F32 mpg = mSurfacep->getMetersPerGrid() * stride; - S32 poffsets[2][2][2]; + S32 poffsets[2][2][3]; poffsets[0][0][0] = x - stride; poffsets[0][0][1] = y - stride; + poffsets[0][0][2] = surface_stride; poffsets[0][1][0] = x - stride; poffsets[0][1][1] = y + stride; + poffsets[0][1][2] = surface_stride; poffsets[1][0][0] = x + stride; poffsets[1][0][1] = y - stride; + poffsets[1][0][2] = surface_stride; poffsets[1][1][0] = x + stride; poffsets[1][1][1] = y + stride; + poffsets[1][1][2] = surface_stride; const LLSurfacePatch *ppatches[2][2]; @@ -286,6 +290,7 @@ void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride) { poffsets[i][j][0] += patch_width; ppatches[i][j] = ppatches[i][j]->getNeighborPatch(WEST); + poffsets[i][j][2] = ppatches[i][j]->getSurface()->getGridsPerEdge(); } } if (poffsets[i][j][1] < 0) @@ -298,6 +303,7 @@ void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride) { poffsets[i][j][1] += patch_width; ppatches[i][j] = ppatches[i][j]->getNeighborPatch(SOUTH); + poffsets[i][j][2] = ppatches[i][j]->getSurface()->getGridsPerEdge(); } } if (poffsets[i][j][0] >= (S32)patch_width) @@ -310,6 +316,7 @@ void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride) { poffsets[i][j][0] -= patch_width; ppatches[i][j] = ppatches[i][j]->getNeighborPatch(EAST); + poffsets[i][j][2] = ppatches[i][j]->getSurface()->getGridsPerEdge(); } } if (poffsets[i][j][1] >= (S32)patch_width) @@ -322,6 +329,7 @@ void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride) { poffsets[i][j][1] -= patch_width; ppatches[i][j] = ppatches[i][j]->getNeighborPatch(NORTH); + poffsets[i][j][2] = ppatches[i][j]->getSurface()->getGridsPerEdge(); } } } @@ -330,19 +338,19 @@ void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride) LLVector3 p00(-mpg,-mpg, *(ppatches[0][0]->mDataZ + poffsets[0][0][0] - + poffsets[0][0][1]*surface_stride)); + + poffsets[0][0][1]*poffsets[0][0][2])); LLVector3 p01(-mpg,+mpg, *(ppatches[0][1]->mDataZ + poffsets[0][1][0] - + poffsets[0][1][1]*surface_stride)); + + poffsets[0][1][1]*poffsets[0][1][2])); LLVector3 p10(+mpg,-mpg, *(ppatches[1][0]->mDataZ + poffsets[1][0][0] - + poffsets[1][0][1]*surface_stride)); + + poffsets[1][0][1]*poffsets[1][0][2])); LLVector3 p11(+mpg,+mpg, *(ppatches[1][1]->mDataZ + poffsets[1][1][0] - + poffsets[1][1][1]*surface_stride)); + + poffsets[1][1][1]*poffsets[1][1][2])); LLVector3 c1 = p11 - p00; LLVector3 c2 = p01 - p10; @@ -493,6 +501,9 @@ void LLSurfacePatch::updateNormals() // update the west edge if (mNormalsInvalid[NORTHWEST] || mNormalsInvalid[WEST] || mNormalsInvalid[SOUTHWEST]) { + if(!getNeighborPatch(NORTH) && getNeighborPatch(NORTHWEST) && getNeighborPatch(NORTHWEST)->getHasReceivedData()) + *(mDataZ + grids_per_patch_edge*grids_per_edge) = *(getNeighborPatch(NORTHWEST)->mDataZ + grids_per_patch_edge); + for (j = 0; j < grids_per_patch_edge; j++) { calcNormal(0, j, 2); @@ -504,6 +515,9 @@ void LLSurfacePatch::updateNormals() // update the south edge if (mNormalsInvalid[SOUTHWEST] || mNormalsInvalid[SOUTH] || mNormalsInvalid[SOUTHEAST]) { + if(!getNeighborPatch(EAST) && getNeighborPatch(SOUTHEAST) && getNeighborPatch(SOUTHEAST)->getHasReceivedData()) + *(mDataZ + grids_per_patch_edge) = *(getNeighborPatch(SOUTHEAST)->mDataZ + grids_per_patch_edge * getNeighborPatch(SOUTHEAST)->getSurface()->getGridsPerEdge()); + for (i = 0; i < grids_per_patch_edge; i++) { calcNormal(i, 0, 2); @@ -532,7 +546,7 @@ void LLSurfacePatch::updateNormals() { // East, but not north. Pull from your east neighbor's northwest point. *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) = - *(getNeighborPatch(EAST)->mDataZ + (grids_per_patch_edge - 1)*grids_per_edge); + *(getNeighborPatch(EAST)->mDataZ + (getNeighborPatch(EAST)->getSurface()->getGridsPerPatchEdge() - 1)*getNeighborPatch(EAST)->getSurface()->getGridsPerEdge()); } else { @@ -557,7 +571,7 @@ void LLSurfacePatch::updateNormals() { // North, but not east. Pull from your north neighbor's southeast corner. *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) = - *(getNeighborPatch(NORTH)->mDataZ + (grids_per_patch_edge - 1)); + *(getNeighborPatch(NORTH)->mDataZ + (getNeighborPatch(NORTH)->getSurface()->getGridsPerPatchEdge() - 1)); } else { @@ -574,8 +588,17 @@ void LLSurfacePatch::updateNormals() && (!getNeighborPatch(EAST) || (getNeighborPatch(EAST)->mSurfacep != mSurfacep))) { + U32 own_xpos, own_ypos, neighbor_xpos, neighbor_ypos; + S32 own_offset = 0, neighbor_offset = 0; + from_region_handle(mSurfacep->getRegion()->getHandle(), &own_xpos, &own_ypos); + from_region_handle(getNeighborPatch(NORTHEAST)->mSurfacep->getRegion()->getHandle(), &neighbor_xpos, &neighbor_ypos); + if(own_ypos >= neighbor_ypos) + neighbor_offset = own_ypos - neighbor_ypos; + else + own_offset = neighbor_ypos - own_ypos; + *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) = - *(getNeighborPatch(NORTHEAST)->mDataZ); + *(getNeighborPatch(NORTHEAST)->mDataZ + (grids_per_edge + neighbor_offset - own_offset - 1) * getNeighborPatch(NORTHEAST)->getSurface()->getGridsPerEdge()); } } else @@ -618,8 +641,9 @@ void LLSurfacePatch::updateEastEdge() { U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge(); U32 grids_per_edge = mSurfacep->getGridsPerEdge(); + U32 grids_per_edge_east = grids_per_edge; - U32 j, k; + U32 j, k, h; F32 *west_surface, *east_surface; if (!getNeighborPatch(EAST)) @@ -631,6 +655,7 @@ void LLSurfacePatch::updateEastEdge() { west_surface = mDataZ + grids_per_patch_edge; east_surface = getNeighborPatch(EAST)->mDataZ; + grids_per_edge_east = getNeighborPatch(EAST)->getSurface()->getGridsPerEdge(); } else { @@ -642,7 +667,8 @@ void LLSurfacePatch::updateEastEdge() for (j=0; j < grids_per_patch_edge; j++) { k = j * grids_per_edge; - *(west_surface + k) = *(east_surface + k); // update buffer Z + h = j * grids_per_edge_east; + *(west_surface + k) = *(east_surface + h); // update buffer Z } } diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index c452c85ab..64e0d40f9 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -4113,8 +4113,9 @@ void process_teleport_finish(LLMessageSystem* msg, void**) msg->getU64Fast(_PREHASH_Info, _PREHASH_RegionHandle, region_handle); U32 teleport_flags; msg->getU32Fast(_PREHASH_Info, _PREHASH_TeleportFlags, teleport_flags); - - + + LLWorld::getInstance()->setRegionWidth(msg); + std::string seedCap; msg->getStringFast(_PREHASH_Info, _PREHASH_SeedCapability, seedCap); @@ -4435,6 +4436,8 @@ void process_crossed_region(LLMessageSystem* msg, void**) std::string seedCap; msg->getStringFast(_PREHASH_RegionData, _PREHASH_SeedCapability, seedCap); + LLWorld::getInstance()->setRegionWidth(msg); + send_complete_agent_movement(sim_host); LLViewerRegion* regionp = LLWorld::getInstance()->addRegion(region_handle, sim_host); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index f22a1a1af..0f36cf3bd 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -956,7 +956,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, U16 valswizzle[4]; #endif U16 *val; - const F32 size = LLWorld::getInstance()->getRegionWidthInMeters(); + const F32 size = mRegionp->getWidth(); const F32 MAX_HEIGHT = LLWorld::getInstance()->getRegionMaxHeight(); const F32 MIN_HEIGHT = LLWorld::getInstance()->getRegionMinHeight(); S32 length; diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 9c18486cc..94f15b48a 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -144,7 +144,7 @@ LLViewerParcelMgr::LLViewerParcelMgr() mHoverParcel = new LLParcel(); mCollisionParcel = new LLParcel(); - mParcelsPerEdge = S32( REGION_WIDTH_METERS / PARCEL_GRID_STEP_METERS ); + mParcelsPerEdge = S32(8192.f / PARCEL_GRID_STEP_METERS); // 8192 is the maximum region size on Aurora and solves the audio problem. mHighlightSegments = new U8[(mParcelsPerEdge+1)*(mParcelsPerEdge+1)]; resetSegments(mHighlightSegments); @@ -167,9 +167,15 @@ LLViewerParcelMgr::LLViewerParcelMgr() mAgentParcelOverlay[i] = 0; } + mParcelsPerEdge = S32(REGION_WIDTH_METERS / PARCEL_GRID_STEP_METERS); + mTeleportInProgress = TRUE; // the initial parcel update is treated like teleport } +void LLViewerParcelMgr::widthUpdate(F32 region_width) +{ + mParcelsPerEdge = S32(region_width / PARCEL_GRID_STEP_METERS); +} LLViewerParcelMgr::~LLViewerParcelMgr() { @@ -449,9 +455,9 @@ LLParcelSelectionHandle LLViewerParcelMgr::selectParcelInRectangle() void LLViewerParcelMgr::selectCollisionParcel() { // BUG: Claim to be in the agent's region - mWestSouth = gAgent.getRegion()->getOriginGlobal(); + mWestSouth = getSelectionRegion()->getOriginGlobal(); mEastNorth = mWestSouth; - mEastNorth += LLVector3d(PARCEL_GRID_STEP_METERS, PARCEL_GRID_STEP_METERS, 0.0); + mEastNorth += LLVector3d(getSelectionRegion()->getWidth()/REGION_WIDTH_METERS * PARCEL_GRID_STEP_METERS, getSelectionRegion()->getWidth()/REGION_WIDTH_METERS * PARCEL_GRID_STEP_METERS, 0.0); // BUG: must be in the sim you are in LLMessageSystem *msg = gMessageSystem; @@ -1409,8 +1415,7 @@ void LLViewerParcelMgr::processParcelOverlay(LLMessageSystem *msg, void **user) return; } - S32 parcels_per_edge = LLViewerParcelMgr::getInstance()->mParcelsPerEdge; - S32 expected_size = parcels_per_edge * parcels_per_edge / PARCEL_OVERLAY_CHUNKS; + const S32 expected_size = 1024; if (packed_overlay_size != expected_size) { llwarns << "Got parcel overlay size " << packed_overlay_size @@ -1473,6 +1478,11 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use S32 other_clean_time = 0; LLViewerParcelMgr& parcel_mgr = LLViewerParcelMgr::instance(); + LLViewerRegion* msg_region = LLWorld::getInstance()->getRegion(msg->getSender()); + if(msg_region) + parcel_mgr.mParcelsPerEdge = S32(msg_region->getWidth() / PARCEL_GRID_STEP_METERS); + else + parcel_mgr.mParcelsPerEdge = S32(gAgent.getRegion()->getWidth() / PARCEL_GRID_STEP_METERS); msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_RequestResult, request_result ); msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SequenceID, sequence_id ); diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h index 5ae44e2d0..749fbd50b 100644 --- a/indra/newview/llviewerparcelmgr.h +++ b/indra/newview/llviewerparcelmgr.h @@ -89,6 +89,7 @@ public: LLViewerParcelMgr(); ~LLViewerParcelMgr(); + void widthUpdate(F32 region_width); static void cleanupGlobals(); BOOL selectionEmpty() const; diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index 42bf3100c..05934efc3 100644 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -59,6 +59,7 @@ const U8 OVERLAY_IMG_COMPONENTS = 4; LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_width_meters) : mRegion( region ), mParcelGridsPerEdge( S32( region_width_meters / PARCEL_GRID_STEP_METERS ) ), + mRegionSize(S32(region_width_meters)), mDirty( FALSE ), mTimeSinceLastUpdate(), mOverlayTextureIdx(-1), @@ -413,7 +414,8 @@ void LLViewerParcelOverlay::uncompressLandOverlay(S32 chunk, U8 *packed_overlay) { // Unpack the message data into the ownership array S32 size = mParcelGridsPerEdge * mParcelGridsPerEdge; - S32 chunk_size = size / PARCEL_OVERLAY_CHUNKS; + S32 mParcelOverLayChunks = mRegionSize * mRegionSize / (128 * 128); + S32 chunk_size = size / mParcelOverLayChunks; memcpy(mOwnership + chunk*chunk_size, packed_overlay, chunk_size); /*Flawfinder: ignore*/ diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h index 794a485e6..d0ad9d344 100644 --- a/indra/newview/llviewerparceloverlay.h +++ b/indra/newview/llviewerparceloverlay.h @@ -109,6 +109,7 @@ private: LLViewerRegion* mRegion; S32 mParcelGridsPerEdge; + S32 mRegionSize; LLPointer mTexture; LLPointer mImageRaw; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 681cfd4fd..6af91a8fa 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -66,6 +66,7 @@ #include "lltrans.h" #include "llurldispatcher.h" #include "llviewerobjectlist.h" +#include "llviewerparcelmgr.h" #include "llviewerparceloverlay.h" #include "llviewerstatsrecorder.h" #include "llvlmanager.h" @@ -303,9 +304,9 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, mCacheLoaded(FALSE), mCacheDirty(FALSE), mReleaseNotesRequested(FALSE), - mCapabilitiesReceived(false) + mCapabilitiesReceived(false), + mWidth(region_width_meters) { - mWidth = region_width_meters; mImpl->mOriginGlobal = from_region_handle(handle); updateRenderMatrix(); @@ -315,7 +316,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, mImpl->mCompositionp = new LLVLComposition(mImpl->mLandp, grids_per_region_edge, - region_width_meters / grids_per_region_edge); + mWidth / grids_per_region_edge); mImpl->mCompositionp->setSurface(mImpl->mLandp); // Create the surfaces @@ -325,7 +326,8 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, mImpl->mOriginGlobal, mWidth); - mParcelOverlay = new LLViewerParcelOverlay(this, region_width_meters); + mParcelOverlay = new LLViewerParcelOverlay(this, mWidth); + LLViewerParcelMgr::getInstance()->widthUpdate(mWidth); setOriginGlobal(from_region_handle(handle)); calculateCenterGlobal(); @@ -835,11 +837,11 @@ LLVLComposition * LLViewerRegion::getComposition() const F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const { - if (x >= 256) + if (x >= mWidth) { - if (y >= 256) + if (y >= mWidth) { - LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 256.f, 0.f); + LLVector3d center = getCenterGlobal() + LLVector3d(mWidth, mWidth, 0.f); LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center); if (regionp) { @@ -848,8 +850,8 @@ F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const // 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); + F32 our_comp = getComposition()->getValueScaled(mWidth-1.f, mWidth-1.f); + F32 adj_comp = regionp->getComposition()->getValueScaled(x - regionp->getWidth(), y - regionp->getWidth()); while (llabs(our_comp - adj_comp) >= 1.f) { if (our_comp > adj_comp) @@ -866,7 +868,7 @@ F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const } else { - LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 0, 0.f); + LLVector3d center = getCenterGlobal() + LLVector3d(mWidth, 0.f, 0.f); LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center); if (regionp) { @@ -875,8 +877,8 @@ F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const // 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); + F32 our_comp = getComposition()->getValueScaled(mWidth-1.f, (F32)y); + F32 adj_comp = regionp->getComposition()->getValueScaled(x - regionp->getWidth(), (F32)y); while (llabs(our_comp - adj_comp) >= 1.f) { if (our_comp > adj_comp) @@ -892,9 +894,9 @@ F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const } } } - else if (y >= 256) + else if (y >= mWidth) { - LLVector3d center = getCenterGlobal() + LLVector3d(0.f, 256.f, 0.f); + LLVector3d center = getCenterGlobal() + LLVector3d(0.f, mWidth, 0.f); LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center); if (regionp) { @@ -903,8 +905,8 @@ F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const // 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); + F32 our_comp = getComposition()->getValueScaled((F32)x, mWidth-1.f); + F32 adj_comp = regionp->getComposition()->getValueScaled((F32)x, y - regionp->getWidth()); while (llabs(our_comp - adj_comp) >= 1.f) { if (our_comp > adj_comp) diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index 049a89d1a..05bee323b 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -74,7 +74,7 @@ LLVOWater::LLVOWater(const LLUUID &id, { // Terrain must draw during selection passes so it can block objects behind it. mbCanSelect = FALSE; - setScale(LLVector3(256.f, 256.f, 0.f)); // Hack for setting scale for bounding boxes/visibility. + setScale(LLVector3(mRegionp->getWidth(), mRegionp->getWidth(), 0.f)); // Hack for setting scale for bounding boxes/visibility. mUseTexture = TRUE; mIsEdgePatch = FALSE; diff --git a/indra/newview/llwind.cpp b/indra/newview/llwind.cpp index 2b0f0d969..8ae0f404b 100644 --- a/indra/newview/llwind.cpp +++ b/indra/newview/llwind.cpp @@ -50,7 +50,7 @@ #include "noise.h" #include "v4color.h" #include "llagent.h" -#include "llworld.h" +#include "llviewerregion.h" const F32 CLOUD_DIVERGENCE_COEF = 0.5f; @@ -254,7 +254,7 @@ LLVector3 LLWind::getVelocity(const LLVector3 &pos_region) LLVector3 pos_clamped_region(pos_region); - F32 region_width_meters = LLWorld::getInstance()->getRegionWidthInMeters(); + F32 region_width_meters = gAgent.getRegion()->getWidth(); if (pos_clamped_region.mV[VX] < 0.f) { @@ -321,7 +321,7 @@ LLVector3 LLWind::getCloudVelocity(const LLVector3 &pos_region) LLVector3 pos_clamped_region(pos_region); - F32 region_width_meters = LLWorld::getInstance()->getRegionWidthInMeters(); + F32 region_width_meters = gAgent.getRegion()->getWidth(); if (pos_clamped_region.mV[VX] < 0.f) { diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index ff0d1558a..86b9fde48 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -81,12 +81,12 @@ const S32 WORLD_PATCH_SIZE = 16; extern LLColor4U MAX_WATER_COLOR; -const U32 LLWorld::mWidth = 256; +U32 LLWorld::mWidth = 256; // meters/point, therefore mWidth * mScale = meters per edge const F32 LLWorld::mScale = 1.f; -const F32 LLWorld::mWidthInMeters = mWidth * mScale; +F32 LLWorld::mWidthInMeters = mWidth * mScale; // // Functions @@ -146,6 +146,18 @@ void LLWorld::destroyClass() } } +void LLWorld::setRegionWidth(LLMessageSystem* msg) +{ + U32 width; + msg->getU32Fast(_PREHASH_SimulatorInfo, _PREHASH_RegionSizeX, width); + setRegionWidth(width); +} + +void LLWorld::setRegionWidth(const U32 width) +{ + mWidth = width ? width : 256; // Width of 0 is really 256 + mWidthInMeters = mWidth * mScale; +} LLViewerRegion* LLWorld::addRegion(const U64 ®ion_handle, const LLHost &host) { @@ -181,8 +193,8 @@ LLViewerRegion* LLWorld::addRegion(const U64 ®ion_handle, const LLHost &host) U32 iindex = 0; U32 jindex = 0; from_region_handle(region_handle, &iindex, &jindex); - S32 x = (S32)(iindex/mWidth); - S32 y = (S32)(jindex/mWidth); + S32 x = (S32)(iindex/256); + S32 y = (S32)(jindex/256); llinfos << "Adding new region (" << x << ":" << y << ")" << llendl; llinfos << "Host: " << host << llendl; @@ -232,13 +244,40 @@ LLViewerRegion* LLWorld::addRegion(const U64 ®ion_handle, const LLHost &host) { adj_x = region_x + width * gDirAxes[dir][0]; adj_y = region_y + width * gDirAxes[dir][1]; - to_region_handle(adj_x, adj_y, &adj_handle); - neighborp = getRegionFromHandle(adj_handle); - if (neighborp) + if (mWidth == 256) { - //llinfos << "Connecting " << region_x << ":" << region_y << " -> " << adj_x << ":" << adj_y << llendl; - regionp->connectNeighbor(neighborp, dir); + to_region_handle(adj_x, adj_y, &adj_handle); + neighborp = getRegionFromHandle(adj_handle); + if (neighborp) + { + //llinfos << "Connecting " << region_x << ":" << region_y << " -> " << adj_x << ":" << adj_y << llendl; + regionp->connectNeighbor(neighborp, dir); + } + } + else // Unconventional region size + { + LLViewerRegion* last_neighborp = NULL; + if(gDirAxes[dir][0] < 0) adj_x = region_x - WORLD_PATCH_SIZE; + if(gDirAxes[dir][1] < 0) adj_y = region_y - WORLD_PATCH_SIZE; + + for (S32 offset = 0; offset < width; offset += WORLD_PATCH_SIZE) + { + to_region_handle(adj_x, adj_y, &adj_handle); + neighborp = getRegionFromHandle(adj_handle); + + if (neighborp && last_neighborp != neighborp) + { + regionp->connectNeighbor(neighborp, dir); + last_neighborp = neighborp; + } + + if (dir == NORTHEAST || dir == NORTHWEST || dir == SOUTHWEST || dir == SOUTHEAST) + break; + + if (dir == NORTH || dir == SOUTH) adj_x += WORLD_PATCH_SIZE; + if (dir == EAST || dir == WEST) adj_y += WORLD_PATCH_SIZE; + } } } @@ -409,11 +448,19 @@ LLVector3d LLWorld::clipToVisibleRegions(const LLVector3d &start_pos, const LLVe LLViewerRegion* LLWorld::getRegionFromHandle(const U64 &handle) { + U32 x, y; + from_region_handle(handle, &x, &y); + for (region_list_t::iterator iter = mRegionList.begin(); iter != mRegionList.end(); ++iter) { LLViewerRegion* regionp = *iter; - if (regionp->getHandle() == handle) + U32 checkRegionX, checkRegionY; + F32 checkRegionWidth = regionp->getWidth(); + from_region_handle(regionp->getHandle(), &checkRegionX, &checkRegionY); + + if (x >= checkRegionX && x < (checkRegionX + checkRegionWidth) && + y >= checkRegionY && y < (checkRegionY + checkRegionWidth)) { return regionp; } @@ -840,7 +887,7 @@ F32 LLWorld::getLandFarClip() const void LLWorld::setLandFarClip(const F32 far_clip) { - static S32 const rwidth = (S32)REGION_WIDTH_U32; + static S32 const rwidth = (S32)getRegionWidthInMeters(); S32 const n1 = (llceil(mLandFarClip) - 1) / rwidth; S32 const n2 = (llceil(far_clip) - 1) / rwidth; bool need_water_objects_update = n1 != n2; @@ -915,8 +962,10 @@ void LLWorld::updateWaterObjects() return; } + LLViewerRegion const* regionp = gAgent.getRegion(); + // Region width in meters. - S32 const rwidth = (S32)REGION_WIDTH_U32; + S32 const rwidth = (S32)regionp->getWidth(); // The distance we might see into the void // when standing on the edge of a region, in meters. @@ -933,15 +982,14 @@ void LLWorld::updateWaterObjects() S32 const range = nsims * rwidth; // Get South-West corner of current region. - LLViewerRegion const* regionp = gAgent.getRegion(); U32 region_x, region_y; from_region_handle(regionp->getHandle(), ®ion_x, ®ion_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; + 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. @@ -1120,19 +1168,19 @@ void LLWorld::updateWaterObjects() // 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 += rwidth) + for (S32 x = min_x; x <= max_x; x += step) { - for (S32 y = min_y; y <= max_y; y += rwidth) + 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 + rwidth / 2, y + rwidth / 2, water_center_z)); - waterp->setScale(LLVector3((F32)rwidth, (F32)rwidth, box_height)); + 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); } @@ -1140,10 +1188,10 @@ void LLWorld::updateWaterObjects() } // Center of the region. - S32 const center_x = region_x + rwidth / 2; - S32 const center_y = region_y + rwidth / 2; + 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 = rwidth + 2 * range; + 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 @@ -1272,6 +1320,8 @@ void process_enable_simulator(LLMessageSystem *msg, void **user_data) // which simulator should we modify? LLHost sim(ip_u32, port); + LLWorld::getInstance()->setRegionWidth(msg); + // Viewer trusts the simulator. msg->enableCircuit(sim, TRUE); LLWorld::getInstance()->addRegion(handle, sim); diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index a9b3f3b53..66819c5d9 100644 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -113,6 +113,10 @@ public: LLSurfacePatch * resolveLandPatchGlobal(const LLVector3d &position); LLVector3 resolveLandNormalGlobal(const LLVector3d &position); // absolute frame + // update region size + void setRegionWidth(LLMessageSystem* msg); + void setRegionWidth(const U32 width = 0); + U32 getRegionWidthInPoints() const { return mWidth; } F32 getRegionScale() const { return mScale; } @@ -177,12 +181,12 @@ private: region_list_t mCulledRegionList; // Number of points on edge - static const U32 mWidth; + static U32 mWidth; // meters/point, therefore mWidth * mScale = meters per edge static const F32 mScale; - static const F32 mWidthInMeters; + static F32 mWidthInMeters; F32 mLandFarClip; // Far clip distance for land. LLPatchVertexArray mLandPatch; diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp index 3f2d7b5ca..e4b3c722e 100644 --- a/indra/newview/llworldmap.cpp +++ b/indra/newview/llworldmap.cpp @@ -375,10 +375,25 @@ LLSimInfo* LLWorldMap::simInfoFromPosGlobal(const LLVector3d& pos_global) LLSimInfo* LLWorldMap::simInfoFromHandle(const U64 handle) { - sim_info_map_t::iterator it = mSimInfoMap.find(handle); - if (it != mSimInfoMap.end()) + std::map::const_iterator it; + for (it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it) { - return it->second; + const U64 hndl = (*it).first; + LLSimInfo* info = (*it).second; + if (hndl == handle) + { + return info; + } + U32 x = 0, y = 0; + from_region_handle(handle, &x, &y); + U32 checkRegionX, checkRegionY; + from_region_handle(hndl, &checkRegionX, &checkRegionY); + + if (x >= checkRegionX && x < (checkRegionX + info->getSizeX()) && + y >= checkRegionY && y < (checkRegionY + info->getSizeY())) + { + return info; + } } return NULL; }