diff options
Diffstat (limited to 'indra/newview/lltoolbrush.cpp')
-rw-r--r-- | indra/newview/lltoolbrush.cpp | 208 |
1 files changed, 139 insertions, 69 deletions
diff --git a/indra/newview/lltoolbrush.cpp b/indra/newview/lltoolbrush.cpp index d39ce57e56..9782b90cf1 100644 --- a/indra/newview/lltoolbrush.cpp +++ b/indra/newview/lltoolbrush.cpp @@ -2,30 +2,25 @@ * @file lltoolbrush.cpp * @brief Implementation of the toolbrushes * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,9 +29,10 @@ #include "lltoolbrush.h" #include "lltoolselectland.h" +// library headers #include "llgl.h" -#include "llglimmediate.h" - +#include "llnotificationsutil.h" +#include "llrender.h" #include "message.h" #include "llagent.h" @@ -62,8 +58,6 @@ const std::string REGION_BLOCKS_TERRAFORM_MSG = "This region does not allow terraforming.\n" "You will need to buy land in another part of the world to terraform it."; -// Globals -LLToolBrushLand *gToolLand = NULL; ///============================================================================ /// Local function declarations, constants, enums, and typedefs @@ -91,22 +85,39 @@ const LLColor4 OVERLAY_COLOR(1.0f, 1.0f, 1.0f, 1.0f); // constructor LLToolBrushLand::LLToolBrushLand() -: LLTool("Land"), +: LLTool(std::string("Land")), mStartingZ( 0.0f ), mMouseX( 0 ), mMouseY(0), mGotHover(FALSE), - mLastShowParcelOwners(FALSE), mBrushSelected(FALSE) { - mBrushIndex = gSavedSettings.getS32("RadioLandBrushSize"); + mBrushSize = gSavedSettings.getF32("LandBrushSize"); +} + + +U8 LLToolBrushLand::getBrushIndex() +{ + // find the best index for desired size + // (compatibility with old sims, brush_index is now depricated - DEV-8252) + U8 index = 0; + for (U8 i = 0; i < LAND_BRUSH_SIZE_COUNT; i++) + { + if (mBrushSize > LAND_BRUSH_SIZE[i]) + { + index = i; + } + } + + return index; } void LLToolBrushLand::modifyLandAtPointGlobal(const LLVector3d &pos_global, MASK mask) { S32 radioAction = gSavedSettings.getS32("RadioLandBrushAction"); - + + mLastAffectedRegions.clear(); determineAffectedRegions(mLastAffectedRegions, pos_global); for(region_list_t::iterator iter = mLastAffectedRegions.begin(); iter != mLastAffectedRegions.end(); ++iter) @@ -156,10 +167,9 @@ void LLToolBrushLand::modifyLandAtPointGlobal(const LLVector3d &pos_global, regionp->forceUpdate(); // tell the simulator what we've done - F32 seconds = 1.0f / gFPSClamped; + F32 seconds = (1.0f / gFPSClamped) * gSavedSettings.getF32("LandBrushForce"); F32 x_pos = (F32)pos_region.mV[VX]; F32 y_pos = (F32)pos_region.mV[VY]; - U8 brush_size = (U8)mBrushIndex; LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_ModifyLand); msg->nextBlockFast(_PREHASH_AgentData); @@ -167,7 +177,7 @@ void LLToolBrushLand::modifyLandAtPointGlobal(const LLVector3d &pos_global, msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); msg->nextBlockFast(_PREHASH_ModifyBlock); msg->addU8Fast(_PREHASH_Action, (U8)action); - msg->addU8Fast(_PREHASH_BrushSize, brush_size); + msg->addU8Fast(_PREHASH_BrushSize, getBrushIndex()); msg->addF32Fast(_PREHASH_Seconds, seconds); msg->addF32Fast(_PREHASH_Height, mStartingZ); msg->nextBlockFast(_PREHASH_ParcelData); @@ -176,18 +186,20 @@ void LLToolBrushLand::modifyLandAtPointGlobal(const LLVector3d &pos_global, msg->addF32Fast(_PREHASH_South, y_pos ); msg->addF32Fast(_PREHASH_East, x_pos ); msg->addF32Fast(_PREHASH_North, y_pos ); + msg->nextBlock("ModifyBlockExtended"); + msg->addF32("BrushSize", mBrushSize); msg->sendMessage(regionp->getHost()); } } void LLToolBrushLand::modifyLandInSelectionGlobal() { - if (gParcelMgr->selectionEmpty()) + if (LLViewerParcelMgr::getInstance()->selectionEmpty()) { return; } - if (gToolMgr->getCurrentTool() == gToolParcel) + if (LLToolMgr::getInstance()->getCurrentTool() == LLToolSelectLand::getInstance()) { // selecting land, don't do anything return; @@ -196,7 +208,7 @@ void LLToolBrushLand::modifyLandInSelectionGlobal() LLVector3d min; LLVector3d max; - gParcelMgr->getSelection(min, max); + LLViewerParcelMgr::getInstance()->getSelection(min, max); S32 radioAction = gSavedSettings.getS32("RadioLandBrushAction"); @@ -244,7 +256,7 @@ void LLToolBrushLand::modifyLandInSelectionGlobal() min_region.clamp(0.f, regionp->getWidth()); max_region.clamp(0.f, regionp->getWidth()); - F32 seconds = 1.0f; + F32 seconds = gSavedSettings.getF32("LandBrushForce"); LLSurface &land = regionp->getLand(); char action = E_LAND_LEVEL; @@ -253,21 +265,23 @@ void LLToolBrushLand::modifyLandInSelectionGlobal() case 0: // // average toward mStartingZ action = E_LAND_LEVEL; - seconds = 1.f; + 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 = 10.f; + seconds *= 5.0f; break; case 4: action = E_LAND_NOISE; - seconds = 0.5f; + seconds *= 0.5f; break; case 5: action = E_LAND_REVERT; @@ -294,7 +308,6 @@ void LLToolBrushLand::modifyLandInSelectionGlobal() regionp->forceUpdate(); // tell the simulator what we've done - U8 brush_size = (U8)mBrushIndex; LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_ModifyLand); msg->nextBlockFast(_PREHASH_AgentData); @@ -302,12 +315,12 @@ void LLToolBrushLand::modifyLandInSelectionGlobal() msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); msg->nextBlockFast(_PREHASH_ModifyBlock); msg->addU8Fast(_PREHASH_Action, (U8)action); - msg->addU8Fast(_PREHASH_BrushSize, brush_size); + msg->addU8Fast(_PREHASH_BrushSize, getBrushIndex()); msg->addF32Fast(_PREHASH_Seconds, seconds); msg->addF32Fast(_PREHASH_Height, mStartingZ); - BOOL parcel_selected = gParcelMgr->getParcelSelection()->getWholeParcelSelected(); - LLParcel* selected_parcel = gParcelMgr->getParcelSelection()->getParcel(); + BOOL parcel_selected = LLViewerParcelMgr::getInstance()->getParcelSelection()->getWholeParcelSelected(); + LLParcel* selected_parcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel(); if (parcel_selected && selected_parcel) { @@ -327,6 +340,9 @@ void LLToolBrushLand::modifyLandInSelectionGlobal() 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()); } @@ -376,7 +392,7 @@ BOOL LLToolBrushLand::handleMouseDown(S32 x, S32 y, MASK mask) gIdleCallbacks.addFunction( &LLToolBrushLand::onIdle, (void*)this ); setMouseCapture( TRUE ); - gParcelMgr->setSelectionVisible(FALSE); + LLViewerParcelMgr::getInstance()->setSelectionVisible(FALSE); handled = TRUE; } @@ -391,7 +407,7 @@ BOOL LLToolBrushLand::handleHover( S32 x, S32 y, MASK mask ) mMouseX = x; mMouseY = y; mGotHover = TRUE; - gViewerWindow->getWindow()->setCursor(UI_CURSOR_TOOLLAND); + gViewerWindow->setCursor(UI_CURSOR_TOOLLAND); return TRUE; } @@ -404,7 +420,7 @@ BOOL LLToolBrushLand::handleMouseUp(S32 x, S32 y, MASK mask) // Release the mouse setMouseCapture( FALSE ); - gParcelMgr->setSelectionVisible(TRUE); + LLViewerParcelMgr::getInstance()->setSelectionVisible(TRUE); gIdleCallbacks.deleteFunction( &LLToolBrushLand::onIdle, (void*)this ); handled = TRUE; @@ -420,8 +436,6 @@ void LLToolBrushLand::handleSelect() gFloaterTools->setStatusText("modifyland"); // if (!mBrushSelected) { - mLastShowParcelOwners = gSavedSettings.getBOOL("ShowParcelOwners"); - gSavedSettings.setBOOL("ShowParcelOwners", mLastShowParcelOwners); mBrushSelected = TRUE; } } @@ -433,9 +447,7 @@ void LLToolBrushLand::handleDeselect() { gEditMenuHandler = NULL; } - mLastShowParcelOwners = gSavedSettings.getBOOL("ShowParcelOwners"); - gSavedSettings.setBOOL("ShowParcelOwners", mLastShowParcelOwners); - gParcelMgr->setSelectionVisible(TRUE); + LLViewerParcelMgr::getInstance()->setSelectionVisible(TRUE); mBrushSelected = FALSE; } @@ -451,7 +463,8 @@ void LLToolBrushLand::render() spot.mdV[VX] = floor( spot.mdV[VX] + 0.5 ); spot.mdV[VY] = floor( spot.mdV[VY] + 0.5 ); - mBrushIndex = gSavedSettings.getS32("RadioLandBrushSize"); + mBrushSize = gSavedSettings.getF32("LandBrushSize"); + region_list_t regions; determineAffectedRegions(regions, spot); @@ -470,11 +483,32 @@ void LLToolBrushLand::render() } } +/* + * Draw vertical lines from each vertex straight up in world space + * with lengths indicating the current "strength" slider. + * Decorate the tops and bottoms of the lines like this: + * + * Raise Revert + * /|\ ___ + * | | + * | | + * + * Rough Smooth + * /|\ ___ + * | | + * | | + * \|/..........._|_ + * + * Lower Flatten + * | | + * | | + * \|/..........._|_ + */ void LLToolBrushLand::renderOverlay(LLSurface& land, const LLVector3& pos_region, const LLVector3& pos_world) { glMatrixMode(GL_MODELVIEW); - LLGLSNoTexture gls_no_texture; + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); LLGLDepthTest mDepthTest(GL_TRUE); glPushMatrix(); gGL.color4fv(OVERLAY_COLOR.mV); @@ -482,20 +516,56 @@ void LLToolBrushLand::renderOverlay(LLSurface& land, const LLVector3& pos_region S32 i = (S32) pos_region.mV[VX]; S32 j = (S32) pos_region.mV[VY]; - S32 half_edge = llfloor(LAND_BRUSH_SIZE[mBrushIndex]); + S32 half_edge = llfloor(mBrushSize); + S32 radioAction = gSavedSettings.getS32("RadioLandBrushAction"); + F32 force = gSavedSettings.getF32("LandBrushForce"); // .1 to 100? - gGL.begin(GL_POINTS); + gGL.begin(LLRender::LINES); for(S32 di = -half_edge; di <= half_edge; di++) { if((i+di) < 0 || (i+di) >= (S32)land.mGridsPerEdge) continue; for(S32 dj = -half_edge; dj <= half_edge; dj++) { if( (j+dj) < 0 || (j+dj) >= (S32)land.mGridsPerEdge ) continue; - gGL.vertex3f(pos_world.mV[VX] + di, pos_world.mV[VY] + dj, - land.getZ((i+di)+(j+dj)*land.mGridsPerEdge)); + const F32 + wx = pos_world.mV[VX] + di, + wy = pos_world.mV[VY] + dj, + wz = land.getZ((i+di)+(j+dj)*land.mGridsPerEdge), + norm_dist = sqrt((float)di*di + dj*dj) / half_edge, + force_scale = sqrt(2.f) - norm_dist, // 1 at center, 0 at corner + wz2 = wz + .2 + (.2 + force/100) * force_scale, // top vertex + tic = .075f; // arrowhead size + // vertical line + gGL.vertex3f(wx, wy, wz); + gGL.vertex3f(wx, wy, wz2); + if(radioAction == E_LAND_RAISE || radioAction == E_LAND_NOISE) // up arrow + { + gGL.vertex3f(wx, wy, wz2); + gGL.vertex3f(wx+tic, wy, wz2-tic); + gGL.vertex3f(wx, wy, wz2); + gGL.vertex3f(wx-tic, wy, wz2-tic); + } + if(radioAction == E_LAND_LOWER || radioAction == E_LAND_NOISE) // down arrow + { + gGL.vertex3f(wx, wy, wz); + gGL.vertex3f(wx+tic, wy, wz+tic); + gGL.vertex3f(wx, wy, wz); + gGL.vertex3f(wx-tic, wy, wz+tic); + } + if(radioAction == E_LAND_REVERT || radioAction == E_LAND_SMOOTH) // flat top + { + gGL.vertex3f(wx-tic, wy, wz2); + gGL.vertex3f(wx+tic, wy, wz2); + } + if(radioAction == E_LAND_LEVEL || radioAction == E_LAND_SMOOTH) // flat bottom + { + gGL.vertex3f(wx-tic, wy, wz); + gGL.vertex3f(wx+tic, wy, wz); + } } } gGL.end(); + glPopMatrix(); } @@ -503,28 +573,28 @@ void LLToolBrushLand::determineAffectedRegions(region_list_t& regions, const LLVector3d& spot ) const { LLVector3d corner(spot); - corner.mdV[VX] -= (LAND_BRUSH_SIZE[mBrushIndex] / 2); - corner.mdV[VY] -= (LAND_BRUSH_SIZE[mBrushIndex] / 2); + corner.mdV[VX] -= (mBrushSize / 2); + corner.mdV[VY] -= (mBrushSize / 2); LLViewerRegion* region = NULL; - region = gWorldPointer->getRegionFromPosGlobal(corner); + region = LLWorld::getInstance()->getRegionFromPosGlobal(corner); if(region && regions.find(region) == regions.end()) { regions.insert(region); } - corner.mdV[VY] += LAND_BRUSH_SIZE[mBrushIndex]; - region = gWorldPointer->getRegionFromPosGlobal(corner); + corner.mdV[VY] += mBrushSize; + region = LLWorld::getInstance()->getRegionFromPosGlobal(corner); if(region && regions.find(region) == regions.end()) { regions.insert(region); } - corner.mdV[VX] += LAND_BRUSH_SIZE[mBrushIndex]; - region = gWorldPointer->getRegionFromPosGlobal(corner); + corner.mdV[VX] += mBrushSize; + region = LLWorld::getInstance()->getRegionFromPosGlobal(corner); if(region && regions.find(region) == regions.end()) { regions.insert(region); } - corner.mdV[VY] -= LAND_BRUSH_SIZE[mBrushIndex]; - region = gWorldPointer->getRegionFromPosGlobal(corner); + corner.mdV[VY] -= mBrushSize; + region = LLWorld::getInstance()->getRegionFromPosGlobal(corner); if(region && regions.find(region) == regions.end()) { regions.insert(region); @@ -536,7 +606,7 @@ void LLToolBrushLand::onIdle( void* brush_tool ) { LLToolBrushLand* self = reinterpret_cast<LLToolBrushLand*>(brush_tool); - if( gToolMgr->getCurrentTool() == self ) + if( LLToolMgr::getInstance()->getCurrentTool() == self ) { self->brush(); } @@ -595,9 +665,9 @@ void LLToolBrushLand::alertNoTerraform(LLViewerRegion* regionp) { if (!regionp) return; - LLStringBase<char>::format_map_t args; - args["[REGION]"] = regionp->getName(); - gViewerWindow->alertXml("RegionNoTerraforming", args); + LLSD args; + args["REGION"] = regionp->getName(); + LLNotificationsUtil::add("RegionNoTerraforming", args); } |