summaryrefslogtreecommitdiff
path: root/indra/newview/lltoolbrush.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/lltoolbrush.cpp')
-rw-r--r--indra/newview/lltoolbrush.cpp208
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);
}