PageRenderTime 57ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/indra/newview/llpanelobject.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 2039 lines | 1549 code | 302 blank | 188 comment | 293 complexity | cd2ae1e4d4efb992cabd5fecf6e2c075 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llpanelobject.cpp
  3. * @brief Object editing (position, scale, etc.) in the tools floater
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "llviewerprecompiledheaders.h"
  27. // file include
  28. #include "llpanelobject.h"
  29. // linden library includes
  30. #include "lleconomy.h"
  31. #include "llerror.h"
  32. #include "llfontgl.h"
  33. #include "llpermissionsflags.h"
  34. #include "llstring.h"
  35. #include "llvolume.h"
  36. #include "m3math.h"
  37. // project includes
  38. #include "llagent.h"
  39. #include "llbutton.h"
  40. #include "llcalc.h"
  41. #include "llcheckboxctrl.h"
  42. #include "llcolorswatch.h"
  43. #include "llcombobox.h"
  44. #include "llfocusmgr.h"
  45. #include "llmanipscale.h"
  46. #include "llpreviewscript.h"
  47. #include "llresmgr.h"
  48. #include "llselectmgr.h"
  49. #include "llspinctrl.h"
  50. #include "lltexturectrl.h"
  51. #include "lltextbox.h"
  52. #include "lltool.h"
  53. #include "lltoolcomp.h"
  54. #include "lltoolmgr.h"
  55. #include "llui.h"
  56. #include "llviewerobject.h"
  57. #include "llviewerregion.h"
  58. #include "llviewerwindow.h"
  59. #include "llvovolume.h"
  60. #include "llworld.h"
  61. #include "pipeline.h"
  62. #include "llviewercontrol.h"
  63. #include "lluictrlfactory.h"
  64. //#include "llfirstuse.h"
  65. #include "lldrawpool.h"
  66. //
  67. // Constants
  68. //
  69. enum {
  70. MI_BOX,
  71. MI_CYLINDER,
  72. MI_PRISM,
  73. MI_SPHERE,
  74. MI_TORUS,
  75. MI_TUBE,
  76. MI_RING,
  77. MI_SCULPT,
  78. MI_NONE,
  79. MI_VOLUME_COUNT
  80. };
  81. enum {
  82. MI_HOLE_SAME,
  83. MI_HOLE_CIRCLE,
  84. MI_HOLE_SQUARE,
  85. MI_HOLE_TRIANGLE,
  86. MI_HOLE_COUNT
  87. };
  88. //static const std::string LEGACY_FULLBRIGHT_DESC =LLTrans::getString("Fullbright");
  89. BOOL LLPanelObject::postBuild()
  90. {
  91. setMouseOpaque(FALSE);
  92. //--------------------------------------------------------
  93. // Top
  94. //--------------------------------------------------------
  95. // Lock checkbox
  96. mCheckLock = getChild<LLCheckBoxCtrl>("checkbox locked");
  97. childSetCommitCallback("checkbox locked",onCommitLock,this);
  98. // Physical checkbox
  99. mCheckPhysics = getChild<LLCheckBoxCtrl>("Physical Checkbox Ctrl");
  100. childSetCommitCallback("Physical Checkbox Ctrl",onCommitPhysics,this);
  101. // Temporary checkbox
  102. mCheckTemporary = getChild<LLCheckBoxCtrl>("Temporary Checkbox Ctrl");
  103. childSetCommitCallback("Temporary Checkbox Ctrl",onCommitTemporary,this);
  104. // Phantom checkbox
  105. mCheckPhantom = getChild<LLCheckBoxCtrl>("Phantom Checkbox Ctrl");
  106. childSetCommitCallback("Phantom Checkbox Ctrl",onCommitPhantom,this);
  107. // Position
  108. mLabelPosition = getChild<LLTextBox>("label position");
  109. mCtrlPosX = getChild<LLSpinCtrl>("Pos X");
  110. childSetCommitCallback("Pos X",onCommitPosition,this);
  111. mCtrlPosY = getChild<LLSpinCtrl>("Pos Y");
  112. childSetCommitCallback("Pos Y",onCommitPosition,this);
  113. mCtrlPosZ = getChild<LLSpinCtrl>("Pos Z");
  114. childSetCommitCallback("Pos Z",onCommitPosition,this);
  115. // Scale
  116. mLabelSize = getChild<LLTextBox>("label size");
  117. mCtrlScaleX = getChild<LLSpinCtrl>("Scale X");
  118. childSetCommitCallback("Scale X",onCommitScale,this);
  119. // Scale Y
  120. mCtrlScaleY = getChild<LLSpinCtrl>("Scale Y");
  121. childSetCommitCallback("Scale Y",onCommitScale,this);
  122. // Scale Z
  123. mCtrlScaleZ = getChild<LLSpinCtrl>("Scale Z");
  124. childSetCommitCallback("Scale Z",onCommitScale,this);
  125. // Rotation
  126. mLabelRotation = getChild<LLTextBox>("label rotation");
  127. mCtrlRotX = getChild<LLSpinCtrl>("Rot X");
  128. childSetCommitCallback("Rot X",onCommitRotation,this);
  129. mCtrlRotY = getChild<LLSpinCtrl>("Rot Y");
  130. childSetCommitCallback("Rot Y",onCommitRotation,this);
  131. mCtrlRotZ = getChild<LLSpinCtrl>("Rot Z");
  132. childSetCommitCallback("Rot Z",onCommitRotation,this);
  133. //--------------------------------------------------------
  134. // Base Type
  135. mComboBaseType = getChild<LLComboBox>("comboBaseType");
  136. childSetCommitCallback("comboBaseType",onCommitParametric,this);
  137. // Cut
  138. mLabelCut = getChild<LLTextBox>("text cut");
  139. mSpinCutBegin = getChild<LLSpinCtrl>("cut begin");
  140. childSetCommitCallback("cut begin",onCommitParametric,this);
  141. mSpinCutBegin->setValidateBeforeCommit( precommitValidate );
  142. mSpinCutEnd = getChild<LLSpinCtrl>("cut end");
  143. childSetCommitCallback("cut end",onCommitParametric,this);
  144. mSpinCutEnd->setValidateBeforeCommit( &precommitValidate );
  145. // Hollow / Skew
  146. mLabelHollow = getChild<LLTextBox>("text hollow");
  147. mLabelSkew = getChild<LLTextBox>("text skew");
  148. mSpinHollow = getChild<LLSpinCtrl>("Scale 1");
  149. childSetCommitCallback("Scale 1",onCommitParametric,this);
  150. mSpinHollow->setValidateBeforeCommit( &precommitValidate );
  151. mSpinSkew = getChild<LLSpinCtrl>("Skew");
  152. childSetCommitCallback("Skew",onCommitParametric,this);
  153. mSpinSkew->setValidateBeforeCommit( &precommitValidate );
  154. mLabelHoleType = getChild<LLTextBox>("Hollow Shape");
  155. // Hole Type
  156. mComboHoleType = getChild<LLComboBox>("hole");
  157. childSetCommitCallback("hole",onCommitParametric,this);
  158. // Twist
  159. mLabelTwist = getChild<LLTextBox>("text twist");
  160. mSpinTwistBegin = getChild<LLSpinCtrl>("Twist Begin");
  161. childSetCommitCallback("Twist Begin",onCommitParametric,this);
  162. mSpinTwistBegin->setValidateBeforeCommit( precommitValidate );
  163. mSpinTwist = getChild<LLSpinCtrl>("Twist End");
  164. childSetCommitCallback("Twist End",onCommitParametric,this);
  165. mSpinTwist->setValidateBeforeCommit( &precommitValidate );
  166. // Scale
  167. mSpinScaleX = getChild<LLSpinCtrl>("Taper Scale X");
  168. childSetCommitCallback("Taper Scale X",onCommitParametric,this);
  169. mSpinScaleX->setValidateBeforeCommit( &precommitValidate );
  170. mSpinScaleY = getChild<LLSpinCtrl>("Taper Scale Y");
  171. childSetCommitCallback("Taper Scale Y",onCommitParametric,this);
  172. mSpinScaleY->setValidateBeforeCommit( &precommitValidate );
  173. // Shear
  174. mLabelShear = getChild<LLTextBox>("text topshear");
  175. mSpinShearX = getChild<LLSpinCtrl>("Shear X");
  176. childSetCommitCallback("Shear X",onCommitParametric,this);
  177. mSpinShearX->setValidateBeforeCommit( &precommitValidate );
  178. mSpinShearY = getChild<LLSpinCtrl>("Shear Y");
  179. childSetCommitCallback("Shear Y",onCommitParametric,this);
  180. mSpinShearY->setValidateBeforeCommit( &precommitValidate );
  181. // Path / Profile
  182. mCtrlPathBegin = getChild<LLSpinCtrl>("Path Limit Begin");
  183. childSetCommitCallback("Path Limit Begin",onCommitParametric,this);
  184. mCtrlPathBegin->setValidateBeforeCommit( &precommitValidate );
  185. mCtrlPathEnd = getChild<LLSpinCtrl>("Path Limit End");
  186. childSetCommitCallback("Path Limit End",onCommitParametric,this);
  187. mCtrlPathEnd->setValidateBeforeCommit( &precommitValidate );
  188. // Taper
  189. mLabelTaper = getChild<LLTextBox>("text taper2");
  190. mSpinTaperX = getChild<LLSpinCtrl>("Taper X");
  191. childSetCommitCallback("Taper X",onCommitParametric,this);
  192. mSpinTaperX->setValidateBeforeCommit( precommitValidate );
  193. mSpinTaperY = getChild<LLSpinCtrl>("Taper Y");
  194. childSetCommitCallback("Taper Y",onCommitParametric,this);
  195. mSpinTaperY->setValidateBeforeCommit( precommitValidate );
  196. // Radius Offset / Revolutions
  197. mLabelRadiusOffset = getChild<LLTextBox>("text radius delta");
  198. mLabelRevolutions = getChild<LLTextBox>("text revolutions");
  199. mSpinRadiusOffset = getChild<LLSpinCtrl>("Radius Offset");
  200. childSetCommitCallback("Radius Offset",onCommitParametric,this);
  201. mSpinRadiusOffset->setValidateBeforeCommit( &precommitValidate );
  202. mSpinRevolutions = getChild<LLSpinCtrl>("Revolutions");
  203. childSetCommitCallback("Revolutions",onCommitParametric,this);
  204. mSpinRevolutions->setValidateBeforeCommit( &precommitValidate );
  205. // Sculpt
  206. mCtrlSculptTexture = getChild<LLTextureCtrl>("sculpt texture control");
  207. if (mCtrlSculptTexture)
  208. {
  209. mCtrlSculptTexture->setDefaultImageAssetID(LLUUID(SCULPT_DEFAULT_TEXTURE));
  210. mCtrlSculptTexture->setCommitCallback( boost::bind(&LLPanelObject::onCommitSculpt, this, _2 ));
  211. mCtrlSculptTexture->setOnCancelCallback( boost::bind(&LLPanelObject::onCancelSculpt, this, _2 ));
  212. mCtrlSculptTexture->setOnSelectCallback( boost::bind(&LLPanelObject::onSelectSculpt, this, _2 ));
  213. mCtrlSculptTexture->setDropCallback( boost::bind(&LLPanelObject::onDropSculpt, this, _2 ));
  214. // Don't allow (no copy) or (no transfer) textures to be selected during immediate mode
  215. mCtrlSculptTexture->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
  216. // Allow any texture to be used during non-immediate mode.
  217. mCtrlSculptTexture->setNonImmediateFilterPermMask(PERM_NONE);
  218. LLAggregatePermissions texture_perms;
  219. if (LLSelectMgr::getInstance()->selectGetAggregateTexturePermissions(texture_perms))
  220. {
  221. BOOL can_copy =
  222. texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_EMPTY ||
  223. texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_ALL;
  224. BOOL can_transfer =
  225. texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_EMPTY ||
  226. texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_ALL;
  227. mCtrlSculptTexture->setCanApplyImmediately(can_copy && can_transfer);
  228. }
  229. else
  230. {
  231. mCtrlSculptTexture->setCanApplyImmediately(FALSE);
  232. }
  233. }
  234. mLabelSculptType = getChild<LLTextBox>("label sculpt type");
  235. mCtrlSculptType = getChild<LLComboBox>("sculpt type control");
  236. childSetCommitCallback("sculpt type control", onCommitSculptType, this);
  237. mCtrlSculptMirror = getChild<LLCheckBoxCtrl>("sculpt mirror control");
  238. childSetCommitCallback("sculpt mirror control", onCommitSculptType, this);
  239. mCtrlSculptInvert = getChild<LLCheckBoxCtrl>("sculpt invert control");
  240. childSetCommitCallback("sculpt invert control", onCommitSculptType, this);
  241. // Start with everyone disabled
  242. clearCtrls();
  243. return TRUE;
  244. }
  245. LLPanelObject::LLPanelObject()
  246. : LLPanel(),
  247. mIsPhysical(FALSE),
  248. mIsTemporary(FALSE),
  249. mIsPhantom(FALSE),
  250. mCastShadows(TRUE),
  251. mSelectedType(MI_BOX),
  252. mSculptTextureRevert(LLUUID::null),
  253. mSculptTypeRevert(0)
  254. {
  255. }
  256. LLPanelObject::~LLPanelObject()
  257. {
  258. // Children all cleaned up by default view destructor.
  259. }
  260. void LLPanelObject::getState( )
  261. {
  262. LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject();
  263. LLViewerObject* root_objectp = objectp;
  264. if(!objectp)
  265. {
  266. objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
  267. // *FIX: shouldn't we just keep the child?
  268. if (objectp)
  269. {
  270. LLViewerObject* parentp = objectp->getRootEdit();
  271. if (parentp)
  272. {
  273. root_objectp = parentp;
  274. }
  275. else
  276. {
  277. root_objectp = objectp;
  278. }
  279. }
  280. }
  281. LLCalc* calcp = LLCalc::getInstance();
  282. LLVOVolume *volobjp = NULL;
  283. if ( objectp && (objectp->getPCode() == LL_PCODE_VOLUME))
  284. {
  285. volobjp = (LLVOVolume *)objectp;
  286. }
  287. if( !objectp )
  288. {
  289. //forfeit focus
  290. if (gFocusMgr.childHasKeyboardFocus(this))
  291. {
  292. gFocusMgr.setKeyboardFocus(NULL);
  293. }
  294. // Disable all text input fields
  295. clearCtrls();
  296. calcp->clearAllVariables();
  297. return;
  298. }
  299. // can move or rotate only linked group with move permissions, or sub-object with move and modify perms
  300. BOOL enable_move = objectp->permMove() && !objectp->isAttachment() && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
  301. BOOL enable_scale = objectp->permMove() && objectp->permModify();
  302. BOOL enable_rotate = objectp->permMove() && ( (objectp->permModify() && !objectp->isAttachment()) || !gSavedSettings.getBOOL("EditLinkedParts"));
  303. S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
  304. BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ))
  305. && (selected_count == 1);
  306. if (LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() > 1)
  307. {
  308. enable_move = FALSE;
  309. enable_scale = FALSE;
  310. enable_rotate = FALSE;
  311. }
  312. LLVector3 vec;
  313. if (enable_move)
  314. {
  315. vec = objectp->getPositionEdit();
  316. mCtrlPosX->set( vec.mV[VX] );
  317. mCtrlPosY->set( vec.mV[VY] );
  318. mCtrlPosZ->set( vec.mV[VZ] );
  319. calcp->setVar(LLCalc::X_POS, vec.mV[VX]);
  320. calcp->setVar(LLCalc::Y_POS, vec.mV[VY]);
  321. calcp->setVar(LLCalc::Z_POS, vec.mV[VZ]);
  322. }
  323. else
  324. {
  325. mCtrlPosX->clear();
  326. mCtrlPosY->clear();
  327. mCtrlPosZ->clear();
  328. calcp->clearVar(LLCalc::X_POS);
  329. calcp->clearVar(LLCalc::Y_POS);
  330. calcp->clearVar(LLCalc::Z_POS);
  331. }
  332. mLabelPosition->setEnabled( enable_move );
  333. mCtrlPosX->setEnabled(enable_move);
  334. mCtrlPosY->setEnabled(enable_move);
  335. mCtrlPosZ->setEnabled(enable_move);
  336. if (enable_scale)
  337. {
  338. vec = objectp->getScale();
  339. mCtrlScaleX->set( vec.mV[VX] );
  340. mCtrlScaleY->set( vec.mV[VY] );
  341. mCtrlScaleZ->set( vec.mV[VZ] );
  342. calcp->setVar(LLCalc::X_SCALE, vec.mV[VX]);
  343. calcp->setVar(LLCalc::Y_SCALE, vec.mV[VY]);
  344. calcp->setVar(LLCalc::Z_SCALE, vec.mV[VZ]);
  345. }
  346. else
  347. {
  348. mCtrlScaleX->clear();
  349. mCtrlScaleY->clear();
  350. mCtrlScaleZ->clear();
  351. calcp->setVar(LLCalc::X_SCALE, 0.f);
  352. calcp->setVar(LLCalc::Y_SCALE, 0.f);
  353. calcp->setVar(LLCalc::Z_SCALE, 0.f);
  354. }
  355. mLabelSize->setEnabled( enable_scale );
  356. mCtrlScaleX->setEnabled( enable_scale );
  357. mCtrlScaleY->setEnabled( enable_scale );
  358. mCtrlScaleZ->setEnabled( enable_scale );
  359. LLQuaternion object_rot = objectp->getRotationEdit();
  360. object_rot.getEulerAngles(&(mCurEulerDegrees.mV[VX]), &(mCurEulerDegrees.mV[VY]), &(mCurEulerDegrees.mV[VZ]));
  361. mCurEulerDegrees *= RAD_TO_DEG;
  362. mCurEulerDegrees.mV[VX] = fmod(llround(mCurEulerDegrees.mV[VX], OBJECT_ROTATION_PRECISION) + 360.f, 360.f);
  363. mCurEulerDegrees.mV[VY] = fmod(llround(mCurEulerDegrees.mV[VY], OBJECT_ROTATION_PRECISION) + 360.f, 360.f);
  364. mCurEulerDegrees.mV[VZ] = fmod(llround(mCurEulerDegrees.mV[VZ], OBJECT_ROTATION_PRECISION) + 360.f, 360.f);
  365. if (enable_rotate)
  366. {
  367. mCtrlRotX->set( mCurEulerDegrees.mV[VX] );
  368. mCtrlRotY->set( mCurEulerDegrees.mV[VY] );
  369. mCtrlRotZ->set( mCurEulerDegrees.mV[VZ] );
  370. calcp->setVar(LLCalc::X_ROT, mCurEulerDegrees.mV[VX]);
  371. calcp->setVar(LLCalc::Y_ROT, mCurEulerDegrees.mV[VY]);
  372. calcp->setVar(LLCalc::Z_ROT, mCurEulerDegrees.mV[VZ]);
  373. }
  374. else
  375. {
  376. mCtrlRotX->clear();
  377. mCtrlRotY->clear();
  378. mCtrlRotZ->clear();
  379. calcp->clearVar(LLCalc::X_ROT);
  380. calcp->clearVar(LLCalc::Y_ROT);
  381. calcp->clearVar(LLCalc::Z_ROT);
  382. }
  383. mLabelRotation->setEnabled( enable_rotate );
  384. mCtrlRotX->setEnabled( enable_rotate );
  385. mCtrlRotY->setEnabled( enable_rotate );
  386. mCtrlRotZ->setEnabled( enable_rotate );
  387. BOOL owners_identical;
  388. LLUUID owner_id;
  389. std::string owner_name;
  390. owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
  391. // BUG? Check for all objects being editable?
  392. S32 roots_selected = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount();
  393. BOOL editable = root_objectp->permModify();
  394. // Select Single Message
  395. getChildView("select_single")->setVisible( FALSE);
  396. getChildView("edit_object")->setVisible( FALSE);
  397. if (!editable || single_volume || selected_count <= 1)
  398. {
  399. getChildView("edit_object")->setVisible( TRUE);
  400. getChildView("edit_object")->setEnabled(TRUE);
  401. }
  402. else
  403. {
  404. getChildView("select_single")->setVisible( TRUE);
  405. getChildView("select_single")->setEnabled(TRUE);
  406. }
  407. // Lock checkbox - only modifiable if you own the object.
  408. BOOL self_owned = (gAgent.getID() == owner_id);
  409. mCheckLock->setEnabled( roots_selected > 0 && self_owned );
  410. // More lock and debit checkbox - get the values
  411. BOOL valid;
  412. U32 owner_mask_on;
  413. U32 owner_mask_off;
  414. valid = LLSelectMgr::getInstance()->selectGetPerm(PERM_OWNER, &owner_mask_on, &owner_mask_off);
  415. if(valid)
  416. {
  417. if(owner_mask_on & PERM_MOVE)
  418. {
  419. // owner can move, so not locked
  420. mCheckLock->set(FALSE);
  421. mCheckLock->setTentative(FALSE);
  422. }
  423. else if(owner_mask_off & PERM_MOVE)
  424. {
  425. // owner can't move, so locked
  426. mCheckLock->set(TRUE);
  427. mCheckLock->setTentative(FALSE);
  428. }
  429. else
  430. {
  431. // some locked, some not locked
  432. mCheckLock->set(FALSE);
  433. mCheckLock->setTentative(TRUE);
  434. }
  435. }
  436. BOOL is_flexible = volobjp && volobjp->isFlexible();
  437. // Physics checkbox
  438. mIsPhysical = root_objectp->usePhysics();
  439. mCheckPhysics->set( mIsPhysical );
  440. mCheckPhysics->setEnabled( roots_selected>0
  441. && (editable || gAgent.isGodlike())
  442. && !is_flexible);
  443. mIsTemporary = root_objectp->flagTemporaryOnRez();
  444. mCheckTemporary->set( mIsTemporary );
  445. mCheckTemporary->setEnabled( roots_selected>0 && editable );
  446. mIsPhantom = root_objectp->flagPhantom();
  447. mCheckPhantom->set( mIsPhantom );
  448. mCheckPhantom->setEnabled( roots_selected>0 && editable && !is_flexible );
  449. #if 0 // 1.9.2
  450. mCastShadows = root_objectp->flagCastShadows();
  451. mCheckCastShadows->set( mCastShadows );
  452. mCheckCastShadows->setEnabled( roots_selected==1 && editable );
  453. #endif
  454. //----------------------------------------------------------------------------
  455. S32 selected_item = MI_BOX;
  456. S32 selected_hole = MI_HOLE_SAME;
  457. BOOL enabled = FALSE;
  458. BOOL hole_enabled = FALSE;
  459. F32 scale_x=1.f, scale_y=1.f;
  460. BOOL isMesh = FALSE;
  461. if( !objectp || !objectp->getVolume() || !editable || !single_volume)
  462. {
  463. // Clear out all geometry fields.
  464. mComboBaseType->clear();
  465. mSpinHollow->clear();
  466. mSpinCutBegin->clear();
  467. mSpinCutEnd->clear();
  468. mCtrlPathBegin->clear();
  469. mCtrlPathEnd->clear();
  470. mSpinScaleX->clear();
  471. mSpinScaleY->clear();
  472. mSpinTwist->clear();
  473. mSpinTwistBegin->clear();
  474. mComboHoleType->clear();
  475. mSpinShearX->clear();
  476. mSpinShearY->clear();
  477. mSpinTaperX->clear();
  478. mSpinTaperY->clear();
  479. mSpinRadiusOffset->clear();
  480. mSpinRevolutions->clear();
  481. mSpinSkew->clear();
  482. mSelectedType = MI_NONE;
  483. }
  484. else
  485. {
  486. // Only allowed to change these parameters for objects
  487. // that you have permissions on AND are not attachments.
  488. enabled = root_objectp->permModify();
  489. // Volume type
  490. const LLVolumeParams &volume_params = objectp->getVolume()->getParams();
  491. U8 path = volume_params.getPathParams().getCurveType();
  492. U8 profile_and_hole = volume_params.getProfileParams().getCurveType();
  493. U8 profile = profile_and_hole & LL_PCODE_PROFILE_MASK;
  494. U8 hole = profile_and_hole & LL_PCODE_HOLE_MASK;
  495. // Scale goes first so we can differentiate between a sphere and a torus,
  496. // which have the same profile and path types.
  497. // Scale
  498. scale_x = volume_params.getRatioX();
  499. scale_y = volume_params.getRatioY();
  500. BOOL linear_path = (path == LL_PCODE_PATH_LINE) || (path == LL_PCODE_PATH_FLEXIBLE);
  501. if ( linear_path && profile == LL_PCODE_PROFILE_CIRCLE )
  502. {
  503. selected_item = MI_CYLINDER;
  504. }
  505. else if ( linear_path && profile == LL_PCODE_PROFILE_SQUARE )
  506. {
  507. selected_item = MI_BOX;
  508. }
  509. else if ( linear_path && profile == LL_PCODE_PROFILE_ISOTRI )
  510. {
  511. selected_item = MI_PRISM;
  512. }
  513. else if ( linear_path && profile == LL_PCODE_PROFILE_EQUALTRI )
  514. {
  515. selected_item = MI_PRISM;
  516. }
  517. else if ( linear_path && profile == LL_PCODE_PROFILE_RIGHTTRI )
  518. {
  519. selected_item = MI_PRISM;
  520. }
  521. else if (path == LL_PCODE_PATH_FLEXIBLE) // shouldn't happen
  522. {
  523. selected_item = MI_CYLINDER; // reasonable default
  524. }
  525. else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_CIRCLE && scale_y > 0.75f)
  526. {
  527. selected_item = MI_SPHERE;
  528. }
  529. else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_CIRCLE && scale_y <= 0.75f)
  530. {
  531. selected_item = MI_TORUS;
  532. }
  533. else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_CIRCLE_HALF)
  534. {
  535. selected_item = MI_SPHERE;
  536. }
  537. else if ( path == LL_PCODE_PATH_CIRCLE2 && profile == LL_PCODE_PROFILE_CIRCLE )
  538. {
  539. // Spirals aren't supported. Make it into a sphere. JC
  540. selected_item = MI_SPHERE;
  541. }
  542. else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_EQUALTRI )
  543. {
  544. selected_item = MI_RING;
  545. }
  546. else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_SQUARE && scale_y <= 0.75f)
  547. {
  548. selected_item = MI_TUBE;
  549. }
  550. else
  551. {
  552. llinfos << "Unknown path " << (S32) path << " profile " << (S32) profile << " in getState" << llendl;
  553. selected_item = MI_BOX;
  554. }
  555. if (objectp->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
  556. {
  557. selected_item = MI_SCULPT;
  558. //LLFirstUse::useSculptedPrim();
  559. }
  560. mComboBaseType ->setCurrentByIndex( selected_item );
  561. mSelectedType = selected_item;
  562. // Grab S path
  563. F32 begin_s = volume_params.getBeginS();
  564. F32 end_s = volume_params.getEndS();
  565. // Compute cut and advanced cut from S and T
  566. F32 begin_t = volume_params.getBeginT();
  567. F32 end_t = volume_params.getEndT();
  568. // Hollowness
  569. F32 hollow = 100.f * volume_params.getHollow();
  570. mSpinHollow->set( hollow );
  571. calcp->setVar(LLCalc::HOLLOW, hollow);
  572. // All hollow objects allow a shape to be selected.
  573. if (hollow > 0.f)
  574. {
  575. switch (hole)
  576. {
  577. case LL_PCODE_HOLE_CIRCLE:
  578. selected_hole = MI_HOLE_CIRCLE;
  579. break;
  580. case LL_PCODE_HOLE_SQUARE:
  581. selected_hole = MI_HOLE_SQUARE;
  582. break;
  583. case LL_PCODE_HOLE_TRIANGLE:
  584. selected_hole = MI_HOLE_TRIANGLE;
  585. break;
  586. case LL_PCODE_HOLE_SAME:
  587. default:
  588. selected_hole = MI_HOLE_SAME;
  589. break;
  590. }
  591. mComboHoleType->setCurrentByIndex( selected_hole );
  592. hole_enabled = enabled;
  593. }
  594. else
  595. {
  596. mComboHoleType->setCurrentByIndex( MI_HOLE_SAME );
  597. hole_enabled = FALSE;
  598. }
  599. // Cut interpretation varies based on base object type
  600. F32 cut_begin, cut_end, adv_cut_begin, adv_cut_end;
  601. if ( selected_item == MI_SPHERE || selected_item == MI_TORUS ||
  602. selected_item == MI_TUBE || selected_item == MI_RING )
  603. {
  604. cut_begin = begin_t;
  605. cut_end = end_t;
  606. adv_cut_begin = begin_s;
  607. adv_cut_end = end_s;
  608. }
  609. else
  610. {
  611. cut_begin = begin_s;
  612. cut_end = end_s;
  613. adv_cut_begin = begin_t;
  614. adv_cut_end = end_t;
  615. }
  616. mSpinCutBegin ->set( cut_begin );
  617. mSpinCutEnd ->set( cut_end );
  618. mCtrlPathBegin ->set( adv_cut_begin );
  619. mCtrlPathEnd ->set( adv_cut_end );
  620. calcp->setVar(LLCalc::CUT_BEGIN, cut_begin);
  621. calcp->setVar(LLCalc::CUT_END, cut_end);
  622. calcp->setVar(LLCalc::PATH_BEGIN, adv_cut_begin);
  623. calcp->setVar(LLCalc::PATH_END, adv_cut_end);
  624. // Twist
  625. F32 twist = volume_params.getTwist();
  626. F32 twist_begin = volume_params.getTwistBegin();
  627. // Check the path type for conversion.
  628. if (path == LL_PCODE_PATH_LINE || path == LL_PCODE_PATH_FLEXIBLE)
  629. {
  630. twist *= OBJECT_TWIST_LINEAR_MAX;
  631. twist_begin *= OBJECT_TWIST_LINEAR_MAX;
  632. }
  633. else
  634. {
  635. twist *= OBJECT_TWIST_MAX;
  636. twist_begin *= OBJECT_TWIST_MAX;
  637. }
  638. mSpinTwist ->set( twist );
  639. mSpinTwistBegin ->set( twist_begin );
  640. calcp->setVar(LLCalc::TWIST_END, twist);
  641. calcp->setVar(LLCalc::TWIST_BEGIN, twist_begin);
  642. // Shear
  643. F32 shear_x = volume_params.getShearX();
  644. F32 shear_y = volume_params.getShearY();
  645. mSpinShearX->set( shear_x );
  646. mSpinShearY->set( shear_y );
  647. calcp->setVar(LLCalc::X_SHEAR, shear_x);
  648. calcp->setVar(LLCalc::Y_SHEAR, shear_y);
  649. // Taper
  650. F32 taper_x = volume_params.getTaperX();
  651. F32 taper_y = volume_params.getTaperY();
  652. mSpinTaperX->set( taper_x );
  653. mSpinTaperY->set( taper_y );
  654. calcp->setVar(LLCalc::X_TAPER, taper_x);
  655. calcp->setVar(LLCalc::Y_TAPER, taper_y);
  656. // Radius offset.
  657. F32 radius_offset = volume_params.getRadiusOffset();
  658. // Limit radius offset, based on taper and hole size y.
  659. F32 radius_mag = fabs(radius_offset);
  660. F32 hole_y_mag = fabs(scale_y);
  661. F32 taper_y_mag = fabs(taper_y);
  662. // Check to see if the taper effects us.
  663. if ( (radius_offset > 0.f && taper_y < 0.f) ||
  664. (radius_offset < 0.f && taper_y > 0.f) )
  665. {
  666. // The taper does not help increase the radius offset range.
  667. taper_y_mag = 0.f;
  668. }
  669. F32 max_radius_mag = 1.f - hole_y_mag * (1.f - taper_y_mag) / (1.f - hole_y_mag);
  670. // Enforce the maximum magnitude.
  671. if (radius_mag > max_radius_mag)
  672. {
  673. // Check radius offset sign.
  674. if (radius_offset < 0.f)
  675. {
  676. radius_offset = -max_radius_mag;
  677. }
  678. else
  679. {
  680. radius_offset = max_radius_mag;
  681. }
  682. }
  683. mSpinRadiusOffset->set( radius_offset);
  684. calcp->setVar(LLCalc::RADIUS_OFFSET, radius_offset);
  685. // Revolutions
  686. F32 revolutions = volume_params.getRevolutions();
  687. mSpinRevolutions->set( revolutions );
  688. calcp->setVar(LLCalc::REVOLUTIONS, revolutions);
  689. // Skew
  690. F32 skew = volume_params.getSkew();
  691. // Limit skew, based on revolutions hole size x.
  692. F32 skew_mag= fabs(skew);
  693. F32 min_skew_mag = 1.0f - 1.0f / (revolutions * scale_x + 1.0f);
  694. // Discontinuity; A revolution of 1 allows skews below 0.5.
  695. if ( fabs(revolutions - 1.0f) < 0.001)
  696. min_skew_mag = 0.0f;
  697. // Clip skew.
  698. if (skew_mag < min_skew_mag)
  699. {
  700. // Check skew sign.
  701. if (skew < 0.0f)
  702. {
  703. skew = -min_skew_mag;
  704. }
  705. else
  706. {
  707. skew = min_skew_mag;
  708. }
  709. }
  710. mSpinSkew->set( skew );
  711. calcp->setVar(LLCalc::SKEW, skew);
  712. }
  713. // Compute control visibility, label names, and twist range.
  714. // Start with defaults.
  715. BOOL cut_visible = TRUE;
  716. BOOL hollow_visible = TRUE;
  717. BOOL top_size_x_visible = TRUE;
  718. BOOL top_size_y_visible = TRUE;
  719. BOOL top_shear_x_visible = TRUE;
  720. BOOL top_shear_y_visible = TRUE;
  721. BOOL twist_visible = TRUE;
  722. BOOL advanced_cut_visible = FALSE;
  723. BOOL taper_visible = FALSE;
  724. BOOL skew_visible = FALSE;
  725. BOOL radius_offset_visible = FALSE;
  726. BOOL revolutions_visible = FALSE;
  727. BOOL sculpt_texture_visible = FALSE;
  728. F32 twist_min = OBJECT_TWIST_LINEAR_MIN;
  729. F32 twist_max = OBJECT_TWIST_LINEAR_MAX;
  730. F32 twist_inc = OBJECT_TWIST_LINEAR_INC;
  731. BOOL advanced_is_dimple = FALSE;
  732. BOOL advanced_is_slice = FALSE;
  733. BOOL size_is_hole = FALSE;
  734. // Tune based on overall volume type
  735. switch (selected_item)
  736. {
  737. case MI_SPHERE:
  738. top_size_x_visible = FALSE;
  739. top_size_y_visible = FALSE;
  740. top_shear_x_visible = FALSE;
  741. top_shear_y_visible = FALSE;
  742. //twist_visible = FALSE;
  743. advanced_cut_visible = TRUE;
  744. advanced_is_dimple = TRUE;
  745. twist_min = OBJECT_TWIST_MIN;
  746. twist_max = OBJECT_TWIST_MAX;
  747. twist_inc = OBJECT_TWIST_INC;
  748. break;
  749. case MI_TORUS:
  750. case MI_TUBE:
  751. case MI_RING:
  752. //top_size_x_visible = FALSE;
  753. //top_size_y_visible = FALSE;
  754. size_is_hole = TRUE;
  755. skew_visible = TRUE;
  756. advanced_cut_visible = TRUE;
  757. taper_visible = TRUE;
  758. radius_offset_visible = TRUE;
  759. revolutions_visible = TRUE;
  760. twist_min = OBJECT_TWIST_MIN;
  761. twist_max = OBJECT_TWIST_MAX;
  762. twist_inc = OBJECT_TWIST_INC;
  763. break;
  764. case MI_SCULPT:
  765. cut_visible = FALSE;
  766. hollow_visible = FALSE;
  767. twist_visible = FALSE;
  768. top_size_x_visible = FALSE;
  769. top_size_y_visible = FALSE;
  770. top_shear_x_visible = FALSE;
  771. top_shear_y_visible = FALSE;
  772. skew_visible = FALSE;
  773. advanced_cut_visible = FALSE;
  774. taper_visible = FALSE;
  775. radius_offset_visible = FALSE;
  776. revolutions_visible = FALSE;
  777. sculpt_texture_visible = TRUE;
  778. break;
  779. case MI_BOX:
  780. advanced_cut_visible = TRUE;
  781. advanced_is_slice = TRUE;
  782. break;
  783. case MI_CYLINDER:
  784. advanced_cut_visible = TRUE;
  785. advanced_is_slice = TRUE;
  786. break;
  787. case MI_PRISM:
  788. advanced_cut_visible = TRUE;
  789. advanced_is_slice = TRUE;
  790. break;
  791. default:
  792. break;
  793. }
  794. // Check if we need to change top size/hole size params.
  795. switch (selected_item)
  796. {
  797. case MI_SPHERE:
  798. case MI_TORUS:
  799. case MI_TUBE:
  800. case MI_RING:
  801. mSpinScaleX->set( scale_x );
  802. mSpinScaleY->set( scale_y );
  803. calcp->setVar(LLCalc::X_HOLE, scale_x);
  804. calcp->setVar(LLCalc::Y_HOLE, scale_y);
  805. mSpinScaleX->setMinValue(OBJECT_MIN_HOLE_SIZE);
  806. mSpinScaleX->setMaxValue(OBJECT_MAX_HOLE_SIZE_X);
  807. mSpinScaleY->setMinValue(OBJECT_MIN_HOLE_SIZE);
  808. mSpinScaleY->setMaxValue(OBJECT_MAX_HOLE_SIZE_Y);
  809. break;
  810. default:
  811. if (editable)
  812. {
  813. mSpinScaleX->set( 1.f - scale_x );
  814. mSpinScaleY->set( 1.f - scale_y );
  815. mSpinScaleX->setMinValue(-1.f);
  816. mSpinScaleX->setMaxValue(1.f);
  817. mSpinScaleY->setMinValue(-1.f);
  818. mSpinScaleY->setMaxValue(1.f);
  819. // Torus' Hole Size is Box/Cyl/Prism's Taper
  820. calcp->setVar(LLCalc::X_TAPER, 1.f - scale_x);
  821. calcp->setVar(LLCalc::Y_TAPER, 1.f - scale_y);
  822. // Box/Cyl/Prism have no hole size
  823. calcp->setVar(LLCalc::X_HOLE, 0.f);
  824. calcp->setVar(LLCalc::Y_HOLE, 0.f);
  825. }
  826. break;
  827. }
  828. // Check if we need to limit the hollow based on the hole type.
  829. if ( selected_hole == MI_HOLE_SQUARE &&
  830. ( selected_item == MI_CYLINDER || selected_item == MI_TORUS ||
  831. selected_item == MI_PRISM || selected_item == MI_RING ||
  832. selected_item == MI_SPHERE ) )
  833. {
  834. mSpinHollow->setMinValue(0.f);
  835. mSpinHollow->setMaxValue(70.f);
  836. }
  837. else
  838. {
  839. mSpinHollow->setMinValue(0.f);
  840. mSpinHollow->setMaxValue(95.f);
  841. }
  842. // Update field enablement
  843. mComboBaseType ->setEnabled( enabled );
  844. mLabelCut ->setEnabled( enabled );
  845. mSpinCutBegin ->setEnabled( enabled );
  846. mSpinCutEnd ->setEnabled( enabled );
  847. mLabelHollow ->setEnabled( enabled );
  848. mSpinHollow ->setEnabled( enabled );
  849. mLabelHoleType ->setEnabled( hole_enabled );
  850. mComboHoleType ->setEnabled( hole_enabled );
  851. mLabelTwist ->setEnabled( enabled );
  852. mSpinTwist ->setEnabled( enabled );
  853. mSpinTwistBegin ->setEnabled( enabled );
  854. mLabelSkew ->setEnabled( enabled );
  855. mSpinSkew ->setEnabled( enabled );
  856. getChildView("scale_hole")->setVisible( FALSE);
  857. getChildView("scale_taper")->setVisible( FALSE);
  858. if (top_size_x_visible || top_size_y_visible)
  859. {
  860. if (size_is_hole)
  861. {
  862. getChildView("scale_hole")->setVisible( TRUE);
  863. getChildView("scale_hole")->setEnabled(enabled);
  864. }
  865. else
  866. {
  867. getChildView("scale_taper")->setVisible( TRUE);
  868. getChildView("scale_taper")->setEnabled(enabled);
  869. }
  870. }
  871. mSpinScaleX ->setEnabled( enabled );
  872. mSpinScaleY ->setEnabled( enabled );
  873. mLabelShear ->setEnabled( enabled );
  874. mSpinShearX ->setEnabled( enabled );
  875. mSpinShearY ->setEnabled( enabled );
  876. getChildView("advanced_cut")->setVisible( FALSE);
  877. getChildView("advanced_dimple")->setVisible( FALSE);
  878. getChildView("advanced_slice")->setVisible( FALSE);
  879. if (advanced_cut_visible)
  880. {
  881. if (advanced_is_dimple)
  882. {
  883. getChildView("advanced_dimple")->setVisible( TRUE);
  884. getChildView("advanced_dimple")->setEnabled(enabled);
  885. }
  886. else if (advanced_is_slice)
  887. {
  888. getChildView("advanced_slice")->setVisible( TRUE);
  889. getChildView("advanced_slice")->setEnabled(enabled);
  890. }
  891. else
  892. {
  893. getChildView("advanced_cut")->setVisible( TRUE);
  894. getChildView("advanced_cut")->setEnabled(enabled);
  895. }
  896. }
  897. mCtrlPathBegin ->setEnabled( enabled );
  898. mCtrlPathEnd ->setEnabled( enabled );
  899. mLabelTaper ->setEnabled( enabled );
  900. mSpinTaperX ->setEnabled( enabled );
  901. mSpinTaperY ->setEnabled( enabled );
  902. mLabelRadiusOffset->setEnabled( enabled );
  903. mSpinRadiusOffset ->setEnabled( enabled );
  904. mLabelRevolutions->setEnabled( enabled );
  905. mSpinRevolutions ->setEnabled( enabled );
  906. // Update field visibility
  907. mLabelCut ->setVisible( cut_visible );
  908. mSpinCutBegin ->setVisible( cut_visible );
  909. mSpinCutEnd ->setVisible( cut_visible );
  910. mLabelHollow ->setVisible( hollow_visible );
  911. mSpinHollow ->setVisible( hollow_visible );
  912. mLabelHoleType ->setVisible( hollow_visible );
  913. mComboHoleType ->setVisible( hollow_visible );
  914. mLabelTwist ->setVisible( twist_visible );
  915. mSpinTwist ->setVisible( twist_visible );
  916. mSpinTwistBegin ->setVisible( twist_visible );
  917. mSpinTwist ->setMinValue( twist_min );
  918. mSpinTwist ->setMaxValue( twist_max );
  919. mSpinTwist ->setIncrement( twist_inc );
  920. mSpinTwistBegin ->setMinValue( twist_min );
  921. mSpinTwistBegin ->setMaxValue( twist_max );
  922. mSpinTwistBegin ->setIncrement( twist_inc );
  923. mSpinScaleX ->setVisible( top_size_x_visible );
  924. mSpinScaleY ->setVisible( top_size_y_visible );
  925. mLabelSkew ->setVisible( skew_visible );
  926. mSpinSkew ->setVisible( skew_visible );
  927. mLabelShear ->setVisible( top_shear_x_visible || top_shear_y_visible );
  928. mSpinShearX ->setVisible( top_shear_x_visible );
  929. mSpinShearY ->setVisible( top_shear_y_visible );
  930. mCtrlPathBegin ->setVisible( advanced_cut_visible );
  931. mCtrlPathEnd ->setVisible( advanced_cut_visible );
  932. mLabelTaper ->setVisible( taper_visible );
  933. mSpinTaperX ->setVisible( taper_visible );
  934. mSpinTaperY ->setVisible( taper_visible );
  935. mLabelRadiusOffset->setVisible( radius_offset_visible );
  936. mSpinRadiusOffset ->setVisible( radius_offset_visible );
  937. mLabelRevolutions->setVisible( revolutions_visible );
  938. mSpinRevolutions ->setVisible( revolutions_visible );
  939. mCtrlSculptTexture->setVisible(sculpt_texture_visible);
  940. mLabelSculptType->setVisible(sculpt_texture_visible);
  941. mCtrlSculptType->setVisible(sculpt_texture_visible);
  942. // sculpt texture
  943. if (selected_item == MI_SCULPT)
  944. {
  945. LLUUID id;
  946. LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
  947. if (sculpt_params) // if we have a legal sculpt param block for this object:
  948. {
  949. if (mObject != objectp) // we've just selected a new object, so save for undo
  950. {
  951. mSculptTextureRevert = sculpt_params->getSculptTexture();
  952. mSculptTypeRevert = sculpt_params->getSculptType();
  953. }
  954. U8 sculpt_type = sculpt_params->getSculptType();
  955. U8 sculpt_stitching = sculpt_type & LL_SCULPT_TYPE_MASK;
  956. BOOL sculpt_invert = sculpt_type & LL_SCULPT_FLAG_INVERT;
  957. BOOL sculpt_mirror = sculpt_type & LL_SCULPT_FLAG_MIRROR;
  958. isMesh = (sculpt_stitching == LL_SCULPT_TYPE_MESH);
  959. LLTextureCtrl* mTextureCtrl = getChild<LLTextureCtrl>("sculpt texture control");
  960. if(mTextureCtrl)
  961. {
  962. mTextureCtrl->setTentative(FALSE);
  963. mTextureCtrl->setEnabled(editable && !isMesh);
  964. if (editable)
  965. mTextureCtrl->setImageAssetID(sculpt_params->getSculptTexture());
  966. else
  967. mTextureCtrl->setImageAssetID(LLUUID::null);
  968. }
  969. mComboBaseType->setEnabled(!isMesh);
  970. if (mCtrlSculptType)
  971. {
  972. if (sculpt_stitching == LL_SCULPT_TYPE_NONE)
  973. {
  974. // since 'None' is no longer an option in the combo box
  975. // use 'Plane' as an equivalent sculpt type
  976. mCtrlSculptType->setSelectedByValue(LLSD(LL_SCULPT_TYPE_PLANE), true);
  977. }
  978. else
  979. {
  980. mCtrlSculptType->setSelectedByValue(LLSD(sculpt_stitching), true);
  981. }
  982. mCtrlSculptType->setEnabled(editable && !isMesh);
  983. }
  984. if (mCtrlSculptMirror)
  985. {
  986. mCtrlSculptMirror->set(sculpt_mirror);
  987. mCtrlSculptMirror->setEnabled(editable && !isMesh);
  988. }
  989. if (mCtrlSculptInvert)
  990. {
  991. mCtrlSculptInvert->set(sculpt_invert);
  992. mCtrlSculptInvert->setEnabled(editable);
  993. }
  994. if (mLabelSculptType)
  995. {
  996. mLabelSculptType->setEnabled(TRUE);
  997. }
  998. }
  999. }
  1000. else
  1001. {
  1002. mSculptTextureRevert = LLUUID::null;
  1003. }
  1004. mCtrlSculptMirror->setVisible(sculpt_texture_visible && !isMesh);
  1005. mCtrlSculptInvert->setVisible(sculpt_texture_visible && !isMesh);
  1006. //----------------------------------------------------------------------------
  1007. mObject = objectp;
  1008. mRootObject = root_objectp;
  1009. }
  1010. // static
  1011. bool LLPanelObject::precommitValidate( const LLSD& data )
  1012. {
  1013. // TODO: Richard will fill this in later.
  1014. return TRUE; // FALSE means that validation failed and new value should not be commited.
  1015. }
  1016. void LLPanelObject::sendIsPhysical()
  1017. {
  1018. BOOL value = mCheckPhysics->get();
  1019. if( mIsPhysical != value )
  1020. {
  1021. LLSelectMgr::getInstance()->selectionUpdatePhysics(value);
  1022. mIsPhysical = value;
  1023. llinfos << "update physics sent" << llendl;
  1024. }
  1025. else
  1026. {
  1027. llinfos << "update physics not changed" << llendl;
  1028. }
  1029. }
  1030. void LLPanelObject::sendIsTemporary()
  1031. {
  1032. BOOL value = mCheckTemporary->get();
  1033. if( mIsTemporary != value )
  1034. {
  1035. LLSelectMgr::getInstance()->selectionUpdateTemporary(value);
  1036. mIsTemporary = value;
  1037. llinfos << "update temporary sent" << llendl;
  1038. }
  1039. else
  1040. {
  1041. llinfos << "update temporary not changed" << llendl;
  1042. }
  1043. }
  1044. void LLPanelObject::sendIsPhantom()
  1045. {
  1046. BOOL value = mCheckPhantom->get();
  1047. if( mIsPhantom != value )
  1048. {
  1049. LLSelectMgr::getInstance()->selectionUpdatePhantom(value);
  1050. mIsPhantom = value;
  1051. llinfos << "update phantom sent" << llendl;
  1052. }
  1053. else
  1054. {
  1055. llinfos << "update phantom not changed" << llendl;
  1056. }
  1057. }
  1058. void LLPanelObject::sendCastShadows()
  1059. {
  1060. BOOL value = mCheckCastShadows->get();
  1061. if( mCastShadows != value )
  1062. {
  1063. LLSelectMgr::getInstance()->selectionUpdateCastShadows(value);
  1064. mCastShadows = value;
  1065. llinfos << "update cast shadows sent" << llendl;
  1066. }
  1067. else
  1068. {
  1069. llinfos << "update cast shadows not changed" << llendl;
  1070. }
  1071. }
  1072. // static
  1073. void LLPanelObject::onCommitParametric( LLUICtrl* ctrl, void* userdata )
  1074. {
  1075. LLPanelObject* self = (LLPanelObject*) userdata;
  1076. if (self->mObject.isNull())
  1077. {
  1078. return;
  1079. }
  1080. if (self->mObject->getPCode() != LL_PCODE_VOLUME)
  1081. {
  1082. // Don't allow modification of non-volume objects.
  1083. return;
  1084. }
  1085. LLVolume *volume = self->mObject->getVolume();
  1086. if (!volume)
  1087. {
  1088. return;
  1089. }
  1090. LLVolumeParams volume_params;
  1091. self->getVolumeParams(volume_params);
  1092. // set sculpting
  1093. S32 selected_type = self->mComboBaseType->getCurrentIndex();
  1094. if (selected_type == MI_SCULPT)
  1095. {
  1096. self->mObject->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, TRUE, TRUE);
  1097. LLSculptParams *sculpt_params = (LLSculptParams *)self->mObject->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
  1098. if (sculpt_params)
  1099. volume_params.setSculptID(sculpt_params->getSculptTexture(), sculpt_params->getSculptType());
  1100. }
  1101. else
  1102. {
  1103. LLSculptParams *sculpt_params = (LLSculptParams *)self->mObject->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
  1104. if (sculpt_params)
  1105. self->mObject->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, FALSE, TRUE);
  1106. }
  1107. // Update the volume, if necessary.
  1108. self->mObject->updateVolume(volume_params);
  1109. // This was added to make sure thate when changes are made, the UI
  1110. // adjusts to present valid options.
  1111. // *FIX: only some changes, ie, hollow or primitive type changes,
  1112. // require a refresh.
  1113. self->refresh();
  1114. }
  1115. void LLPanelObject::getVolumeParams(LLVolumeParams& volume_params)
  1116. {
  1117. // Figure out what type of volume to make
  1118. S32 was_selected_type = mSelectedType;
  1119. S32 selected_type = mComboBaseType->getCurrentIndex();
  1120. U8 profile;
  1121. U8 path;
  1122. switch ( selected_type )
  1123. {
  1124. case MI_CYLINDER:
  1125. profile = LL_PCODE_PROFILE_CIRCLE;
  1126. path = LL_PCODE_PATH_LINE;
  1127. break;
  1128. case MI_BOX:
  1129. profile = LL_PCODE_PROFILE_SQUARE;
  1130. path = LL_PCODE_PATH_LINE;
  1131. break;
  1132. case MI_PRISM:
  1133. profile = LL_PCODE_PROFILE_EQUALTRI;
  1134. path = LL_PCODE_PATH_LINE;
  1135. break;
  1136. case MI_SPHERE:
  1137. profile = LL_PCODE_PROFILE_CIRCLE_HALF;
  1138. path = LL_PCODE_PATH_CIRCLE;
  1139. break;
  1140. case MI_TORUS:
  1141. profile = LL_PCODE_PROFILE_CIRCLE;
  1142. path = LL_PCODE_PATH_CIRCLE;
  1143. break;
  1144. case MI_TUBE:
  1145. profile = LL_PCODE_PROFILE_SQUARE;
  1146. path = LL_PCODE_PATH_CIRCLE;
  1147. break;
  1148. case MI_RING:
  1149. profile = LL_PCODE_PROFILE_EQUALTRI;
  1150. path = LL_PCODE_PATH_CIRCLE;
  1151. break;
  1152. case MI_SCULPT:
  1153. profile = LL_PCODE_PROFILE_CIRCLE;
  1154. path = LL_PCODE_PATH_CIRCLE;
  1155. break;
  1156. default:
  1157. llwarns << "Unknown base type " << selected_type
  1158. << " in getVolumeParams()" << llendl;
  1159. // assume a box
  1160. selected_type = MI_BOX;
  1161. profile = LL_PCODE_PROFILE_SQUARE;
  1162. path = LL_PCODE_PATH_LINE;
  1163. break;
  1164. }
  1165. if (path == LL_PCODE_PATH_LINE)
  1166. {
  1167. LLVOVolume *volobjp = (LLVOVolume *)(LLViewerObject*)(mObject);
  1168. if (volobjp->isFlexible())
  1169. {
  1170. path = LL_PCODE_PATH_FLEXIBLE;
  1171. }
  1172. }
  1173. S32 selected_hole = mComboHoleType->getCurrentIndex();
  1174. U8 hole;
  1175. switch (selected_hole)
  1176. {
  1177. case MI_HOLE_CIRCLE:
  1178. hole = LL_PCODE_HOLE_CIRCLE;
  1179. break;
  1180. case MI_HOLE_SQUARE:
  1181. hole = LL_PCODE_HOLE_SQUARE;
  1182. break;
  1183. case MI_HOLE_TRIANGLE:
  1184. hole = LL_PCODE_HOLE_TRIANGLE;
  1185. break;
  1186. case MI_HOLE_SAME:
  1187. default:
  1188. hole = LL_PCODE_HOLE_SAME;
  1189. break;
  1190. }
  1191. volume_params.setType(profile | hole, path);
  1192. mSelectedType = selected_type;
  1193. // Compute cut start/end
  1194. F32 cut_begin = mSpinCutBegin->get();
  1195. F32 cut_end = mSpinCutEnd->get();
  1196. // Make sure at least OBJECT_CUT_INC of the object survives
  1197. if (cut_begin > cut_end - OBJECT_MIN_CUT_INC)
  1198. {
  1199. cut_begin = cut_end - OBJECT_MIN_CUT_INC;
  1200. mSpinCutBegin->set(cut_begin);
  1201. }
  1202. F32 adv_cut_begin = mCtrlPathBegin->get();
  1203. F32 adv_cut_end = mCtrlPathEnd->get();
  1204. // Make sure at least OBJECT_CUT_INC of the object survives
  1205. if (adv_cut_begin > adv_cut_end - OBJECT_MIN_CUT_INC)
  1206. {
  1207. adv_cut_begin = adv_cut_end - OBJECT_MIN_CUT_INC;
  1208. mCtrlPathBegin->set(adv_cut_begin);
  1209. }
  1210. F32 begin_s, end_s;
  1211. F32 begin_t, end_t;
  1212. if (selected_type == MI_SPHERE || selected_type == MI_TORUS ||
  1213. selected_type == MI_TUBE || selected_type == MI_RING)
  1214. {
  1215. begin_s = adv_cut_begin;
  1216. end_s = adv_cut_end;
  1217. begin_t = cut_begin;
  1218. end_t = cut_end;
  1219. }
  1220. else
  1221. {
  1222. begin_s = cut_begin;
  1223. end_s = cut_end;
  1224. begin_t = adv_cut_begin;
  1225. end_t = adv_cut_end;
  1226. }
  1227. volume_params.setBeginAndEndS(begin_s, end_s);
  1228. volume_params.setBeginAndEndT(begin_t, end_t);
  1229. // Hollowness
  1230. F32 hollow = mSpinHollow->get() / 100.f;
  1231. if ( selected_hole == MI_HOLE_SQUARE &&
  1232. ( selected_type == MI_CYLINDER || selected_type == MI_TORUS ||
  1233. selected_type == MI_PRISM || selected_type == MI_RING ||
  1234. selected_type == MI_SPHERE ) )
  1235. {
  1236. if (hollow > 0.7f) hollow = 0.7f;
  1237. }
  1238. volume_params.setHollow( hollow );
  1239. // Twist Begin,End
  1240. F32 twist_begin = mSpinTwistBegin->get();
  1241. F32 twist = mSpinTwist->get();
  1242. // Check the path type for twist conversion.
  1243. if (path == LL_PCODE_PATH_LINE || path == LL_PCODE_PATH_FLEXIBLE)
  1244. {
  1245. twist_begin /= OBJECT_TWIST_LINEAR_MAX;
  1246. twist /= OBJECT_TWIST_LINEAR_MAX;
  1247. }
  1248. else
  1249. {
  1250. twist_begin /= OBJECT_TWIST_MAX;
  1251. twist /= OBJECT_TWIST_MAX;
  1252. }
  1253. volume_params.setTwistBegin(twist_begin);
  1254. volume_params.setTwist(twist);
  1255. // Scale X,Y
  1256. F32 scale_x = mSpinScaleX->get();
  1257. F32 scale_y = mSpinScaleY->get();
  1258. if ( was_selected_type == MI_BOX || was_selected_type == MI_CYLINDER || was_selected_type == MI_PRISM)
  1259. {
  1260. scale_x = 1.f - scale_x;
  1261. scale_y = 1.f - scale_y;
  1262. }
  1263. // Skew
  1264. F32 skew = mSpinSkew->get();
  1265. // Taper X,Y
  1266. F32 taper_x = mSpinTaperX->get();
  1267. F32 taper_y = mSpinTaperY->get();
  1268. // Radius offset
  1269. F32 radius_offset = mSpinRadiusOffset->get();
  1270. // Revolutions
  1271. F32 revolutions = mSpinRevolutions->get();
  1272. if ( selected_type == MI_SPHERE )
  1273. {
  1274. // Snap values to valid sphere parameters.
  1275. scale_x = 1.0f;
  1276. scale_y = 1.0f;
  1277. skew = 0.0f;
  1278. taper_x = 0.0f;
  1279. taper_y = 0.0f;
  1280. radius_offset = 0.0f;
  1281. revolutions = 1.0f;
  1282. }
  1283. else if ( selected_type == MI_TORUS || selected_type == MI_TUBE ||
  1284. selected_type == MI_RING )
  1285. {
  1286. scale_x = llclamp(
  1287. scale_x,
  1288. OBJECT_MIN_HOLE_SIZE,
  1289. OBJECT_MAX_HOLE_SIZE_X);
  1290. scale_y = llclamp(
  1291. scale_y,
  1292. OBJECT_MIN_HOLE_SIZE,
  1293. OBJECT_MAX_HOLE_SIZE_Y);
  1294. // Limit radius offset, based on taper and hole size y.
  1295. F32 radius_mag = fabs(radius_offset);
  1296. F32 hole_y_mag = fabs(scale_y);
  1297. F32 taper_y_mag = fabs(taper_y);
  1298. // Check to see if the taper effects us.
  1299. if ( (radius_offset > 0.f && taper_y < 0.f) ||
  1300. (radius_offset < 0.f && taper_y > 0.f) )
  1301. {
  1302. // The taper does not help increase the radius offset range.
  1303. taper_y_mag = 0.f;
  1304. }
  1305. F32 max_radius_mag = 1.f - hole_y_mag * (1.f - taper_y_mag) / (1.f - hole_y_mag);
  1306. // Enforce the maximum magnitude.
  1307. if (radius_mag > max_radius_mag)
  1308. {
  1309. // Check radius offset sign.
  1310. if (radius_offset < 0.f)
  1311. {
  1312. radius_offset = -max_radius_mag;
  1313. }
  1314. else
  1315. {
  1316. radius_offset = max_radius_mag;
  1317. }
  1318. }
  1319. // Check the skew value against the revolutions.
  1320. F32 skew_mag= fabs(skew);
  1321. F32 min_skew_mag = 1.0f - 1.0f / (revolutions * scale_x + 1.0f);
  1322. // Discontinuity; A revolution of 1 allows skews below 0.5.
  1323. if ( fabs(revolutions - 1.0f) < 0.001)
  1324. min_skew_mag = 0.0f;
  1325. // Clip skew.
  1326. if (skew_mag < min_skew_mag)
  1327. {
  1328. // Check skew sign.
  1329. if (skew < 0.0f)
  1330. {
  1331. skew = -min_skew_mag;
  1332. }
  1333. else
  1334. {
  1335. skew = min_skew_mag;
  1336. }
  1337. }
  1338. }
  1339. volume_params.setRatio( scale_x, scale_y );
  1340. volume_params.setSkew(skew);
  1341. volume_params.setTaper( taper_x, taper_y );
  1342. volume_params.setRadiusOffset(radius_offset);
  1343. volume_params.setRevolutions(revolutions);
  1344. // Shear X,Y
  1345. F32 shear_x = mSpinShearX->get();
  1346. F32 shear_y = mSpinShearY->get();
  1347. volume_params.setShear( shear_x, shear_y );
  1348. if (selected_type == MI_SCULPT)
  1349. {
  1350. volume_params.setSculptID(LLUUID::null, 0);
  1351. volume_params.setBeginAndEndT (0, 1);
  1352. volume_params.setBeginAndEndS (0, 1);
  1353. volume_params.setHollow (0);
  1354. volume_params.setTwistBegin (0);
  1355. volume_params.setTwistEnd (0);
  1356. volume_params.setRatio (1, 0.5);
  1357. volume_params.setShear (0, 0);
  1358. volume_params.setTaper (0, 0);
  1359. volume_params.setRevolutions (1);
  1360. volume_params.setRadiusOffset (0);
  1361. volume_params.setSkew (0);
  1362. }
  1363. }
  1364. // BUG: Make work with multiple objects
  1365. void LLPanelObject::sendRotation(BOOL btn_down)
  1366. {
  1367. if (mObject.isNull()) return;
  1368. LLVector3 new_rot(mCtrlRotX->get(), mCtrlRotY->get(), mCtrlRotZ->get());
  1369. new_rot.mV[VX] = llround(new_rot.mV[VX], OBJECT_ROTATION_PRECISION);
  1370. new_rot.mV[VY] = llround(new_rot.mV[VY], OBJECT_ROTATION_PRECISION);
  1371. new_rot.mV[VZ] = llround(new_rot.mV[VZ], OBJECT_ROTATION_PRECISION);
  1372. // Note: must compare before conversion to radians
  1373. LLVector3 delta = new_rot - mCurEulerDegrees;
  1374. if (delta.magVec() >= 0.0005f)
  1375. {
  1376. mCurEulerDegrees = new_rot;
  1377. new_rot *= DEG_TO_RAD;
  1378. LLQuaternion rotation;
  1379. rotation.setQuat(new_rot.mV[VX], new_rot.mV[VY], new_rot.mV[VZ]);
  1380. if (mRootObject != mObject)
  1381. {
  1382. rotation = rotation * ~mRootObject->getRotationRegion();
  1383. }
  1384. std::vector<LLVector3>& child_positions = mObject->mUnselectedChildrenPositions ;
  1385. std::vector<LLQuaternion> child_rotations;
  1386. if (mObject->isRootEdit())
  1387. {
  1388. mObject->saveUnselectedChildrenRotation(child_rotations) ;
  1389. mObject->saveUnselectedChildrenPosition(child_positions) ;
  1390. }
  1391. mObject->setRotation(rotation);
  1392. LLManip::rebuild(mObject) ;
  1393. // for individually selected roots, we need to counterrotate all the children
  1394. if (mObject->isRootEdit())
  1395. {
  1396. mObject->resetChildrenRotationAndPosition(child_rotations, child_positions) ;
  1397. }
  1398. if(!btn_down)
  1399. {
  1400. child_positions.clear() ;
  1401. LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_ROTATION | UPD_POSITION);
  1402. }
  1403. }
  1404. }
  1405. // BUG: Make work with multiple objects
  1406. void LLPanelObject::sendScale(BOOL btn_down)
  1407. {
  1408. if (mObject.isNull()) return;
  1409. LLVector3 newscale(mCtrlScaleX->get(), mCtrlScaleY->get(), mCtrlScaleZ->get());
  1410. LLVector3 delta = newscale - mObject->getScale();
  1411. if (delta.magVec() >= 0.0005f)
  1412. {
  1413. // scale changed by more than 1/2 millimeter
  1414. // check to see if we aren't scaling the textures
  1415. // (in which case the tex coord's need to be recomputed)
  1416. BOOL dont_stretch_textures = !LLManipScale::getStretchTextures();
  1417. if (dont_stretch_textures)
  1418. {
  1419. LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_SCALE);
  1420. }
  1421. mObject->setScale(newscale, TRUE);
  1422. if(!btn_down)
  1423. {
  1424. LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_SCALE | UPD_POSITION);
  1425. }
  1426. LLSelectMgr::getInstance()->adjustTexturesByScale(TRUE, !dont_stretch_textures);
  1427. // llinfos << "scale sent" << llendl;
  1428. }
  1429. else
  1430. {
  1431. // llinfos << "scale not changed" << llendl;
  1432. }
  1433. }
  1434. void LLPanelObject::sendPosition(BOOL btn_down)
  1435. {
  1436. if (mObject.isNull()) return;
  1437. LLVector3 newpos(mCtrlPosX->get(), mCtrlPosY->get(), mCtrlPosZ->get());
  1438. LLViewerRegion* regionp = mObject->getRegion();
  1439. // Clamp the Z height
  1440. const F32 height = newpos.mV[VZ];
  1441. const F32 min_height = LLWorld::getInstance()->getMinAllowedZ(mObject, mObject->getPositionGlobal());
  1442. const F32 max_height = LLWorld::getInstance()->getRegionMaxHeight();
  1443. if (!mObject->isAttachment())
  1444. {
  1445. if ( height < min_height)
  1446. {
  1447. newpos.mV[VZ] = min_height;
  1448. mCtrlPosZ->set( min_height );
  1449. }
  1450. else if ( height > max_height )
  1451. {
  1452. newpos.mV[VZ] = max_height;
  1453. mCtrlPosZ->set( max_height );
  1454. }
  1455. // Grass is always drawn on the ground, so clamp its position to the ground
  1456. if (mObject->getPCode() == LL_PCODE_LEGACY_GRASS)
  1457. {
  1458. mCtrlPosZ->set(LLWorld::getInstance()->resolveLandHeightAgent(newpos) + 1.f);
  1459. }
  1460. }
  1461. // Make sure new position is in a valid region, so the object
  1462. // won't get dumped by the simulator.
  1463. LLVector3d new_pos_global = regionp->getPosGlobalFromRegion(newpos);
  1464. if ( LLWorld::getInstance()->positionRegionValidGlobal(new_pos_global) )
  1465. {
  1466. // send only if the position is changed, that is, the delta vector is not zero
  1467. LLVector3d old_pos_global = mObject->getPositionGlobal();
  1468. LLVector3d delta = new_pos_global - old_pos_global;
  1469. // moved more than 1/2 millimeter
  1470. if (delta.magVec() >= 0.0005f)
  1471. {
  1472. if (mRootObject != mObject)
  1473. {
  1474. newpos = newpos - mRootObject->getPositionRegion();
  1475. newpos = newpos * ~mRootObject->getRotationRegion();
  1476. mObject->setPositionParent(newpos);
  1477. }
  1478. else
  1479. {
  1480. mObject->setPositionEdit(newpos);
  1481. }
  1482. LLManip::rebuild(mObject) ;
  1483. // for individually selected roots, we need to counter-translate all unselected children
  1484. if (mObject->isRootEdit())
  1485. {
  1486. // only offset by parent's translation
  1487. mObject->resetChildrenPosition(LLVector3(-delta), TRUE) ;
  1488. }
  1489. if(!btn_down)
  1490. {
  1491. LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION);
  1492. }
  1493. LLSelectMgr::getInstance()->updateSelectionCenter();
  1494. }
  1495. }
  1496. else
  1497. {
  1498. // move failed, so we update the UI with the correct values
  1499. LLVector3 vec = mRootObject->getPositionRegion();
  1500. mCtrlPosX->set(vec.mV[VX]);
  1501. mCtrlPosY->set(vec.mV[VY]);
  1502. mCtrlPosZ->set(vec.mV[VZ]);
  1503. }
  1504. }
  1505. void LLPanelObject::sendSculpt()
  1506. {
  1507. if (mObject.isNull())
  1508. return;
  1509. LLSculptParams sculpt_params;
  1510. if (mCtrlSculptTexture)
  1511. sculpt_params.setSculptTexture(mCtrlSculptTexture->getImageAssetID());
  1512. U8 sculpt_type = 0;
  1513. if (mCtrlSculptType)
  1514. sculpt_type |= mCtrlSculptType->getValue().asInteger();
  1515. bool enabled = sculpt_type != LL_SCULPT_TYPE_MESH;
  1516. if (mCtrlSculptMirror)
  1517. {
  1518. mCtrlSculptMirror->setEnabled(enabled ? TRUE : FALSE);
  1519. }
  1520. if (mCtrlSculptInvert)
  1521. {
  1522. mCtrlSculptInvert->setEnabled(enabled ? TRUE : FALSE);
  1523. }
  1524. if ((mCtrlSculptMirror) && (mCtrlSculptMirror->get()))
  1525. sculpt_type |= LL_SCULPT_FLAG_MIRROR;
  1526. if ((mCtrlSculptInvert) && (mCtrlSculptInvert->get()))
  1527. sculpt_type |= LL_SCULPT_FLAG_INVERT;
  1528. sculpt_params.setSculptType(sculpt_type);
  1529. mObject->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt_params, TRUE);
  1530. }
  1531. void LLPanelObject::refresh()
  1532. {
  1533. getState();
  1534. if (mObject.notNull() && mObject->isDead())
  1535. {
  1536. mObject = NULL;
  1537. }
  1538. if (mRootObject.notNull() && mRootObject->isDead())
  1539. {
  1540. mRootObject = NULL;
  1541. }
  1542. F32 max_scale = get_default_max_prim_scale(LLPickInfo::isFlora(mObject));
  1543. getChild<LLSpinCtrl>("Scale X")->setMaxValue(max_scale);
  1544. getChild<LLSpinCtrl>("Scale Y")->setMaxValue(max_scale);
  1545. getChild<LLSpinCtrl>("Scale Z")->setMaxValue(max_scale);
  1546. }
  1547. void LLPanelObject::draw()
  1548. {
  1549. const LLColor4 white( 1.0f, 1.0f, 1.0f, 1);
  1550. const LLColor4 red( 1.0f, 0.25f, 0.f, 1);
  1551. const LLColor4 green( 0.f, 1.0f, 0.f, 1);
  1552. const LLColor4 blue( 0.f, 0.5f, 1.0f, 1);
  1553. // Tune the colors of the labels
  1554. LLTool* tool = LLToolMgr::getInstance()->getCurrentTool();
  1555. if (tool == LLToolCompTranslate::getInstance())
  1556. {
  1557. mCtrlPosX ->setLabelColor(red);
  1558. mCtrlPosY ->setLabelColor(green);
  1559. mCtrlPosZ ->setLabelColor(blue);
  1560. mCtrlScaleX ->setLabelColor(white);
  1561. mCtrlScaleY ->setLabelColor(white);
  1562. mCtrlScaleZ ->setLabelColor(white);
  1563. mCtrlRotX ->setLabelColor(white);
  1564. mCtrlRotY ->setLabelColor(white);
  1565. mCtrlRotZ ->setLabelColor(white);
  1566. }
  1567. else if ( tool == LLToolCompScale::getInstance() )
  1568. {
  1569. mCtrlPosX ->setLabelColor(white);
  1570. mCtrlPosY ->setLabelColor(white);
  1571. mCtrlPosZ ->setLabelColor(white);
  1572. mCtrlScaleX ->setLabelColor(red);
  1573. mCtrlScaleY ->setLabelColor(green);
  1574. mCtrlScaleZ ->setLabelColor(blue);
  1575. mCtrlRotX ->setLabelColor(white);
  1576. mCtrlRotY ->setLabelColor(white);
  1577. mCtrlRotZ ->setLabelColor(white);
  1578. }
  1579. else if ( tool == LLToolCompRotate::getInstance() )
  1580. {
  1581. mCtrlPosX ->setLabelColor(white);
  1582. mCtrlPosY ->setLabelColor(white);
  1583. mCtrlPosZ ->setLabelColor(white);
  1584. mCtrlScaleX ->setLabelColor(white);
  1585. mCtrlScaleY ->setLabelColor(white);
  1586. mCtrlScaleZ ->setLabelColor(white);
  1587. mCtrlRotX ->setLabelColor(red);
  1588. mCtrlRotY ->setLabelColor(green);
  1589. mCtrlRotZ ->setLabelColor(blue);
  1590. }
  1591. else
  1592. {
  1593. mCtrlPosX ->setLabelColor(white);
  1594. mCtrlPosY ->setLabelColor(white);
  1595. mCtrlPosZ ->setLabelColor(white);
  1596. mCtrlScaleX ->setLabelColor(white);
  1597. mCtrlScaleY ->setLabelColor(white);
  1598. mCtrlScaleZ ->setLabelColor(white);
  1599. mCtrlRotX ->setLabelColor(white);
  1600. mCtrlRotY ->setLabelColor(white);
  1601. mCtrlRotZ ->setLabelColor(white);
  1602. }
  1603. LLPanel::draw();
  1604. }
  1605. // virtual
  1606. void LLPanelObject::clearCtrls()
  1607. {
  1608. LLPanel::clearCtrls();
  1609. mCheckLock ->set(FALSE);
  1610. mCheckLock ->setEnabled( FALSE );
  1611. mCheckPhysics ->set(FALSE);
  1612. mCheckPhysics ->setEnabled( FALSE );
  1613. mCheckTemporary ->set(FALSE);
  1614. mCheckTemporary ->setEnabled( FALSE );
  1615. mCheckPhantom ->set(FALSE);
  1616. mCheckPhantom ->setEnabled( FALSE );
  1617. #if 0 // 1.9.2
  1618. mCheckCastShadows->set(FALSE);
  1619. mCheckCastShadows->setEnabled( FALSE );
  1620. #endif
  1621. // Disable text labels
  1622. mLabelPosition ->setEnabled( FALSE );
  1623. mLabelSize ->setEnabled( FALSE );
  1624. mLabelRotation ->setEnabled( FALSE );
  1625. mLabelCut ->setEnabled( FALSE );
  1626. mLabelHollow ->setEnabled( FALSE );
  1627. mLabelHoleType ->setEnabled( FALSE );
  1628. mLabelTwist ->setEnabled( FALSE );
  1629. mLabelSkew ->setEnabled( FALSE );
  1630. mLabelShear ->setEnabled( FALSE );
  1631. mLabelTaper ->setEnabled( FALSE );
  1632. mLabelRadiusOffset->setEnabled( FALSE );
  1633. mLabelRevolutions->setEnabled( FALSE );
  1634. getChildView("select_single")->setVisible( FALSE);
  1635. getChildView("edit_object")->setVisible( TRUE);
  1636. getChildView("edit_object")->setEnabled(FALSE);
  1637. getChildView("scale_hole")->setEnabled(FALSE);
  1638. getChildView("scale_taper")->setEnabled(FALSE);
  1639. getChildView("advanced_cut")->setEnabled(FALSE);
  1640. getChildView("advanced_dimple")->setEnabled(FALSE);
  1641. getChildView("advanced_slice")->setVisible( FALSE);
  1642. }
  1643. //
  1644. // Static functions
  1645. //
  1646. // static
  1647. void LLPanelObject::onCommitLock(LLUICtrl *ctrl, void *data)
  1648. {
  1649. // Checkbox will have toggled itself
  1650. LLPanelObject *self = (LLPanelObject *)data;
  1651. if(self->mRootObject.isNull()) return;
  1652. BOOL new_state = self->mCheckLock->get();
  1653. LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_OWNER, !new_state, PERM_MOVE | PERM_MODIFY);
  1654. }
  1655. // static
  1656. void LLPanelObject::onCommitPosition( LLUICtrl* ctrl, void* userdata )
  1657. {
  1658. LLPanelObject* self = (LLPanelObject*) userdata;
  1659. BOOL btn_down = ((LLSpinCtrl*)ctrl)->isMouseHeldDown() ;
  1660. self->sendPosition(btn_down);
  1661. }
  1662. // static
  1663. void LLPanelObject::onCommitScale( LLUICtrl* ctrl, void* userdata )
  1664. {
  1665. LLPanelObject* self = (LLPanelObject*) userdata;
  1666. BOOL btn_down = ((LLSpinCtrl*)ctrl)->isMouseHeldDown() ;
  1667. self->sendScale(btn_down);
  1668. }
  1669. // static
  1670. void LLPanelObject::onCommitRotation( LLUICtrl* ctrl, void* userdata )
  1671. {
  1672. LLPanelObject* self = (LLPanelObject*) userdata;
  1673. BOOL btn_down = ((LLSpinCtrl*)ctrl)->isMouseHeldDown() ;
  1674. self->sendRotation(btn_down);
  1675. }
  1676. // static
  1677. void LLPanelObject::onCommitPhysics( LLUICtrl* ctrl, void* userdata )
  1678. {
  1679. LLPanelObject* self = (LLPanelObject*) userdata;
  1680. self->sendIsPhysical();
  1681. }
  1682. // static
  1683. void LLPanelObject::onCommitTemporary( LLUICtrl* ctrl, void* userdata )
  1684. {
  1685. LLPanelObject* self = (LLPanelObject*) userdata;
  1686. self->sendIsTemporary();
  1687. }
  1688. // static
  1689. void LLPanelObject::onCommitPhantom( LLUICtrl* ctrl, void* userdata )
  1690. {
  1691. LLPanelObject* self = (LLPanelObject*) userdata;
  1692. self->sendIsPhantom();
  1693. }
  1694. // static
  1695. void LLPanelObject::onCommitCastShadows( LLUICtrl* ctrl, void* userdata )
  1696. {
  1697. LLPanelObject* self = (LLPanelObject*) userdata;
  1698. self->sendCastShadows();
  1699. }
  1700. void LLPanelObject::onSelectSculpt(const LLSD& data)
  1701. {
  1702. LLTextureCtrl* mTextureCtrl = getChild<LLTextureCtrl>("sculpt texture control");
  1703. if (mTextureCtrl)
  1704. {
  1705. mSculptTextureRevert = mTextureCtrl->getImageAssetID();
  1706. }
  1707. sendSculpt();
  1708. }
  1709. void LLPanelObject::onCommitSculpt( const LLSD& data )
  1710. {
  1711. sendSculpt();
  1712. }
  1713. BOOL LLPanelObject::onDropSculpt(LLInventoryItem* item)
  1714. {
  1715. LLTextureCtrl* mTextureCtrl = getChild<LLTextureCtrl>("sculpt texture control");
  1716. if (mTextureCtrl)
  1717. {
  1718. LLUUID asset = item->getAssetUUID();
  1719. mTextureCtrl->setImageAssetID(asset);
  1720. mSculptTextureRevert = asset;
  1721. }
  1722. return TRUE;
  1723. }
  1724. void LLPanelObject::onCancelSculpt(const LLSD& data)
  1725. {
  1726. LLTextureCtrl* mTextureCtrl = getChild<LLTextureCtrl>("sculpt texture control");
  1727. if(!mTextureCtrl)
  1728. return;
  1729. mTextureCtrl->setImageAssetID(mSculptTextureRevert);
  1730. sendSculpt();
  1731. }
  1732. // static
  1733. void LLPanelObject::onCommitSculptType(LLUICtrl *ctrl, void* userdata)
  1734. {
  1735. LLPanelObject* self = (LLPanelObject*) userdata;
  1736. self->sendSculpt();
  1737. }