/** * @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 ); }