225 lines
6.6 KiB
C++
225 lines
6.6 KiB
C++
/**
|
|
* @file lltoolplacer.cpp
|
|
* @brief Tool for placing new objects into the world
|
|
*
|
|
* Copyright (c) 2001-$CurrentYear$, Linden Research, Inc.
|
|
* $License$
|
|
*/
|
|
|
|
#include "llviewerprecompiledheaders.h"
|
|
|
|
// self header
|
|
#include "lltoolplacer.h"
|
|
|
|
// linden library headers
|
|
#include "llprimitive.h"
|
|
|
|
// viewer headers
|
|
#include "llbutton.h"
|
|
#include "llviewercontrol.h"
|
|
#include "llfirstuse.h"
|
|
#include "llfloatertools.h"
|
|
#include "llselectmgr.h"
|
|
#include "llstatusbar.h"
|
|
#include "lltoolcomp.h"
|
|
#include "lltoolmgr.h"
|
|
#include "llviewerobject.h"
|
|
#include "llviewerregion.h"
|
|
#include "llviewerwindow.h"
|
|
#include "llworld.h"
|
|
#include "viewer.h"
|
|
#include "llui.h"
|
|
|
|
//static
|
|
LLPCode LLToolPlacer::sObjectType = LL_PCODE_CUBE;
|
|
|
|
LLToolPlacer::LLToolPlacer()
|
|
: LLTool( "Create" )
|
|
{
|
|
}
|
|
|
|
// Used by the placer tool to add copies of the current selection.
|
|
// Inspired by add_object(). JC
|
|
BOOL add_duplicate(S32 x, S32 y)
|
|
{
|
|
LLVector3 ray_start_region;
|
|
LLVector3 ray_end_region;
|
|
LLViewerRegion* regionp = NULL;
|
|
BOOL b_hit_land = FALSE;
|
|
S32 hit_face = -1;
|
|
LLViewerObject* hit_obj = NULL;
|
|
BOOL success = raycast_for_new_obj_pos( x, y, &hit_obj, &hit_face, &b_hit_land, &ray_start_region, &ray_end_region, ®ionp );
|
|
if( !success )
|
|
{
|
|
make_ui_sound("UISndInvalidOp");
|
|
return FALSE;
|
|
}
|
|
if( hit_obj && (hit_obj->isAvatar() || hit_obj->isAttachment()) )
|
|
{
|
|
// Can't create objects on avatars or attachments
|
|
make_ui_sound("UISndInvalidOp");
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
// Limit raycast to a single object.
|
|
// Speeds up server raycast + avoid problems with server ray hitting objects
|
|
// that were clipped by the near plane or culled on the viewer.
|
|
LLUUID ray_target_id;
|
|
if( hit_obj )
|
|
{
|
|
ray_target_id = hit_obj->getID();
|
|
}
|
|
else
|
|
{
|
|
ray_target_id.setNull();
|
|
}
|
|
|
|
gSelectMgr->selectDuplicateOnRay(ray_start_region,
|
|
ray_end_region,
|
|
b_hit_land, // suppress raycast
|
|
FALSE, // intersection
|
|
ray_target_id,
|
|
gSavedSettings.getBOOL("CreateToolCopyCenters"),
|
|
gSavedSettings.getBOOL("CreateToolCopyRotates"),
|
|
FALSE); // select copy
|
|
|
|
if (regionp
|
|
&& (regionp->getRegionFlags() & REGION_FLAGS_SANDBOX))
|
|
{
|
|
LLFirstUse::useSandbox();
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL LLToolPlacer::placeObject(S32 x, S32 y, MASK mask)
|
|
{
|
|
BOOL added = TRUE;
|
|
|
|
if (gSavedSettings.getBOOL("CreateToolCopySelection"))
|
|
{
|
|
added = add_duplicate(x, y);
|
|
}
|
|
else
|
|
{
|
|
added = add_object( sObjectType, x, y, NO_PHYSICS );
|
|
}
|
|
|
|
// ...and go back to the default tool
|
|
if (added && !gSavedSettings.getBOOL("CreateToolKeepSelected"))
|
|
{
|
|
gToolMgr->getCurrentToolset()->selectTool( gToolTranslate );
|
|
}
|
|
|
|
return added;
|
|
}
|
|
|
|
BOOL LLToolPlacer::handleHover(S32 x, S32 y, MASK mask)
|
|
{
|
|
lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPlacer" << llendl;
|
|
gViewerWindow->getWindow()->setCursor(UI_CURSOR_TOOLCREATE);
|
|
return TRUE;
|
|
}
|
|
|
|
void LLToolPlacer::handleSelect()
|
|
{
|
|
gFloaterTools->setStatusText("Click in the world to create, shift-click to select");
|
|
}
|
|
|
|
void LLToolPlacer::handleDeselect()
|
|
{
|
|
gFloaterTools->setStatusText("");
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
// LLToolPlacerPanel
|
|
|
|
// static
|
|
LLPCode LLToolPlacerPanel::sCube = LL_PCODE_CUBE;
|
|
LLPCode LLToolPlacerPanel::sPrism = LL_PCODE_PRISM;
|
|
LLPCode LLToolPlacerPanel::sPyramid = LL_PCODE_PYRAMID;
|
|
LLPCode LLToolPlacerPanel::sTetrahedron = LL_PCODE_TETRAHEDRON;
|
|
LLPCode LLToolPlacerPanel::sCylinder = LL_PCODE_CYLINDER;
|
|
LLPCode LLToolPlacerPanel::sCylinderHemi= LL_PCODE_CYLINDER_HEMI;
|
|
LLPCode LLToolPlacerPanel::sCone = LL_PCODE_CONE;
|
|
LLPCode LLToolPlacerPanel::sConeHemi = LL_PCODE_CONE_HEMI;
|
|
LLPCode LLToolPlacerPanel::sTorus = LL_PCODE_TORUS;
|
|
LLPCode LLToolPlacerPanel::sSquareTorus = LLViewerObject::LL_VO_SQUARE_TORUS;
|
|
LLPCode LLToolPlacerPanel::sTriangleTorus = LLViewerObject::LL_VO_TRIANGLE_TORUS;
|
|
LLPCode LLToolPlacerPanel::sSphere = LL_PCODE_SPHERE;
|
|
LLPCode LLToolPlacerPanel::sSphereHemi = LL_PCODE_SPHERE_HEMI;
|
|
LLPCode LLToolPlacerPanel::sTree = LL_PCODE_LEGACY_TREE;
|
|
LLPCode LLToolPlacerPanel::sGrass = LL_PCODE_LEGACY_GRASS;
|
|
|
|
S32 LLToolPlacerPanel::sButtonsAdded = 0;
|
|
LLButton* LLToolPlacerPanel::sButtons[ TOOL_PLACER_NUM_BUTTONS ];
|
|
|
|
LLToolPlacerPanel::LLToolPlacerPanel(const std::string& name, const LLRect& rect)
|
|
:
|
|
LLPanel( name, rect )
|
|
{
|
|
/* DEPRECATED - JC
|
|
addButton( "UIImgCubeUUID", "UIImgCubeSelectedUUID", &LLToolPlacerPanel::sCube );
|
|
addButton( "UIImgPrismUUID", "UIImgPrismSelectedUUID", &LLToolPlacerPanel::sPrism );
|
|
addButton( "UIImgPyramidUUID", "UIImgPyramidSelectedUUID", &LLToolPlacerPanel::sPyramid );
|
|
addButton( "UIImgTetrahedronUUID", "UIImgTetrahedronSelectedUUID", &LLToolPlacerPanel::sTetrahedron );
|
|
addButton( "UIImgCylinderUUID", "UIImgCylinderSelectedUUID", &LLToolPlacerPanel::sCylinder );
|
|
addButton( "UIImgHalfCylinderUUID", "UIImgHalfCylinderSelectedUUID",&LLToolPlacerPanel::sCylinderHemi );
|
|
addButton( "UIImgConeUUID", "UIImgConeSelectedUUID", &LLToolPlacerPanel::sCone );
|
|
addButton( "UIImgHalfConeUUID", "UIImgHalfConeSelectedUUID", &LLToolPlacerPanel::sConeHemi );
|
|
addButton( "UIImgSphereUUID", "UIImgSphereSelectedUUID", &LLToolPlacerPanel::sSphere );
|
|
addButton( "UIImgHalfSphereUUID", "UIImgHalfSphereSelectedUUID", &LLToolPlacerPanel::sSphereHemi );
|
|
addButton( "UIImgTreeUUID", "UIImgTreeSelectedUUID", &LLToolPlacerPanel::sTree );
|
|
addButton( "UIImgGrassUUID", "UIImgGrassSelectedUUID", &LLToolPlacerPanel::sGrass );
|
|
addButton( "ObjectTorusImageID", "ObjectTorusActiveImageID", &LLToolPlacerPanel::sTorus );
|
|
addButton( "ObjectTubeImageID", "ObjectTubeActiveImageID", &LLToolPlacerPanel::sSquareTorus );
|
|
*/
|
|
}
|
|
|
|
void LLToolPlacerPanel::addButton( const LLString& up_state, const LLString& down_state, LLPCode* pcode )
|
|
{
|
|
const S32 TOOL_SIZE = 32;
|
|
const S32 HORIZ_SPACING = TOOL_SIZE + 5;
|
|
const S32 VERT_SPACING = TOOL_SIZE + 5;
|
|
const S32 VPAD = 10;
|
|
const S32 HPAD = 7;
|
|
|
|
S32 row = sButtonsAdded / 4;
|
|
S32 column = sButtonsAdded % 4;
|
|
|
|
LLRect help_rect = gSavedSettings.getRect("ToolHelpRect");
|
|
|
|
// Build the rectangle, recalling the origin is at lower left
|
|
// and we want the icons to build down from the top.
|
|
LLRect rect;
|
|
rect.setLeftTopAndSize(
|
|
HPAD + (column * HORIZ_SPACING),
|
|
help_rect.mBottom - VPAD - (row * VERT_SPACING),
|
|
TOOL_SIZE,
|
|
TOOL_SIZE );
|
|
|
|
LLButton* btn = new LLButton(
|
|
"ToolPlacerOptBtn",
|
|
rect,
|
|
up_state,
|
|
down_state,
|
|
"", &LLToolPlacerPanel::setObjectType,
|
|
pcode,
|
|
LLFontGL::sSansSerif);
|
|
btn->setFollowsBottom();
|
|
btn->setFollowsLeft();
|
|
addChild(btn);
|
|
|
|
sButtons[sButtonsAdded] = btn;
|
|
sButtonsAdded++;
|
|
}
|
|
|
|
// static
|
|
void LLToolPlacerPanel::setObjectType( void* data )
|
|
{
|
|
LLPCode pcode = *(LLPCode*) data;
|
|
LLToolPlacer::setObjectType( pcode );
|
|
}
|