00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034
00035 #include "llpanelobject.h"
00036
00037
00038 #include "lleconomy.h"
00039 #include "llerror.h"
00040 #include "llfontgl.h"
00041 #include "llpermissionsflags.h"
00042 #include "llstring.h"
00043 #include "llvolume.h"
00044 #include "m3math.h"
00045
00046
00047 #include "llagent.h"
00048 #include "llbutton.h"
00049 #include "llcheckboxctrl.h"
00050 #include "llcolorswatch.h"
00051 #include "llcombobox.h"
00052 #include "llfocusmgr.h"
00053 #include "llmanipscale.h"
00054 #include "llpanelinventory.h"
00055 #include "llpreviewscript.h"
00056 #include "llresmgr.h"
00057 #include "llselectmgr.h"
00058 #include "llspinctrl.h"
00059 #include "lltexturectrl.h"
00060 #include "lltextbox.h"
00061 #include "lltool.h"
00062 #include "lltoolcomp.h"
00063 #include "lltoolmgr.h"
00064 #include "llui.h"
00065 #include "llviewerobject.h"
00066 #include "llviewerregion.h"
00067 #include "llviewerwindow.h"
00068 #include "llvovolume.h"
00069 #include "llworld.h"
00070 #include "pipeline.h"
00071 #include "viewer.h"
00072 #include "llvieweruictrlfactory.h"
00073 #include "llfirstuse.h"
00074
00075 #include "lldrawpool.h"
00076
00077
00078
00079
00080 enum {
00081 MI_BOX,
00082 MI_CYLINDER,
00083 MI_PRISM,
00084 MI_SPHERE,
00085 MI_TORUS,
00086 MI_TUBE,
00087 MI_RING,
00088 MI_SCULPT,
00089 MI_NONE,
00090 MI_VOLUME_COUNT
00091 };
00092
00093 enum {
00094 MI_HOLE_SAME,
00095 MI_HOLE_CIRCLE,
00096 MI_HOLE_SQUARE,
00097 MI_HOLE_TRIANGLE,
00098 MI_HOLE_COUNT
00099 };
00100
00101
00102 static const LLString LEGACY_FULLBRIGHT_DESC("Fullbright (Legacy)");
00103
00104 BOOL LLPanelObject::postBuild()
00105 {
00106 setMouseOpaque(FALSE);
00107
00108
00109
00110
00111
00112
00113 mCheckLock = gUICtrlFactory->getCheckBoxByName(this,"checkbox locked");
00114 childSetCommitCallback("checkbox locked",onCommitLock,this);
00115
00116
00117 mCheckPhysics = gUICtrlFactory->getCheckBoxByName(this,"Physical Checkbox Ctrl");
00118 childSetCommitCallback("Physical Checkbox Ctrl",onCommitPhysics,this);
00119
00120
00121 mCheckTemporary = gUICtrlFactory->getCheckBoxByName(this,"Temporary Checkbox Ctrl");
00122 childSetCommitCallback("Temporary Checkbox Ctrl",onCommitTemporary,this);
00123
00124
00125 mCheckPhantom = gUICtrlFactory->getCheckBoxByName(this,"Phantom Checkbox Ctrl");
00126 childSetCommitCallback("Phantom Checkbox Ctrl",onCommitPhantom,this);
00127
00128
00129 mLabelPosition = gUICtrlFactory->getTextBoxByName(this,"label position");
00130 mCtrlPosX = gUICtrlFactory->getSpinnerByName(this,"Pos X");
00131 childSetCommitCallback("Pos X",onCommitPosition,this);
00132 mCtrlPosY = gUICtrlFactory->getSpinnerByName(this,"Pos Y");
00133 childSetCommitCallback("Pos Y",onCommitPosition,this);
00134 mCtrlPosZ = gUICtrlFactory->getSpinnerByName(this,"Pos Z");
00135 childSetCommitCallback("Pos Z",onCommitPosition,this);
00136
00137
00138 mLabelSize = gUICtrlFactory->getTextBoxByName(this,"label size");
00139 mCtrlScaleX = gUICtrlFactory->getSpinnerByName(this,"Scale X");
00140 childSetCommitCallback("Scale X",onCommitScale,this);
00141
00142
00143 mCtrlScaleY = gUICtrlFactory->getSpinnerByName(this,"Scale Y");
00144 childSetCommitCallback("Scale Y",onCommitScale,this);
00145
00146
00147 mCtrlScaleZ = gUICtrlFactory->getSpinnerByName(this,"Scale Z");
00148 childSetCommitCallback("Scale Z",onCommitScale,this);
00149
00150
00151 mLabelRotation = gUICtrlFactory->getTextBoxByName(this,"label rotation");
00152 mCtrlRotX = gUICtrlFactory->getSpinnerByName(this,"Rot X");
00153 childSetCommitCallback("Rot X",onCommitRotation,this);
00154 mCtrlRotY = gUICtrlFactory->getSpinnerByName(this,"Rot Y");
00155 childSetCommitCallback("Rot Y",onCommitRotation,this);
00156 mCtrlRotZ = gUICtrlFactory->getSpinnerByName(this,"Rot Z");
00157 childSetCommitCallback("Rot Z",onCommitRotation,this);
00158
00159
00160
00161
00162 mLabelMaterial = gUICtrlFactory->getTextBoxByName(this,"label material");
00163 mComboMaterial = gUICtrlFactory->getComboBoxByName(this,"material");
00164 childSetCommitCallback("material",onCommitMaterial,this);
00165 mComboMaterial->removeall();
00166
00167 LLMaterialInfo *minfop;
00168 for (minfop = LLMaterialTable::basic.mMaterialInfoList.getFirstData();
00169 minfop != NULL;
00170 minfop = LLMaterialTable::basic.mMaterialInfoList.getNextData())
00171 {
00172 if (minfop->mMCode != LL_MCODE_LIGHT)
00173 {
00174 mComboMaterial->add(minfop->mName);
00175 }
00176 }
00177 mComboMaterialItemCount = mComboMaterial->getItemCount();
00178
00179
00180 mLabelBaseType = gUICtrlFactory->getTextBoxByName(this,"label basetype");
00181 mComboBaseType = gUICtrlFactory->getComboBoxByName(this,"comboBaseType");
00182 childSetCommitCallback("comboBaseType",onCommitParametric,this);
00183
00184
00185 mLabelCut = gUICtrlFactory->getTextBoxByName(this,"text cut");
00186 mSpinCutBegin = gUICtrlFactory->getSpinnerByName(this,"cut begin");
00187 childSetCommitCallback("cut begin",onCommitParametric,this);
00188 mSpinCutBegin->setValidateBeforeCommit( precommitValidate );
00189 mSpinCutEnd = gUICtrlFactory->getSpinnerByName(this,"cut end");
00190 childSetCommitCallback("cut end",onCommitParametric,this);
00191 mSpinCutEnd->setValidateBeforeCommit( &precommitValidate );
00192
00193
00194 mLabelHollow = gUICtrlFactory->getTextBoxByName(this,"text hollow");
00195 mLabelSkew = gUICtrlFactory->getTextBoxByName(this,"text skew");
00196 mSpinHollow = gUICtrlFactory->getSpinnerByName(this,"Scale 1");
00197 childSetCommitCallback("Scale 1",onCommitParametric,this);
00198 mSpinHollow->setValidateBeforeCommit( &precommitValidate );
00199 mSpinSkew = gUICtrlFactory->getSpinnerByName(this,"Skew");
00200 childSetCommitCallback("Skew",onCommitParametric,this);
00201 mSpinSkew->setValidateBeforeCommit( &precommitValidate );
00202 mLabelHoleType = gUICtrlFactory->getTextBoxByName(this,"Hollow Shape");
00203
00204
00205 mComboHoleType = gUICtrlFactory->getComboBoxByName(this,"hole");
00206 childSetCommitCallback("hole",onCommitParametric,this);
00207
00208
00209 mLabelTwist = gUICtrlFactory->getTextBoxByName(this,"text twist");
00210 mSpinTwistBegin = gUICtrlFactory->getSpinnerByName(this,"Twist Begin");
00211 childSetCommitCallback("Twist Begin",onCommitParametric,this);
00212 mSpinTwistBegin->setValidateBeforeCommit( precommitValidate );
00213 mSpinTwist = gUICtrlFactory->getSpinnerByName(this,"Twist End");
00214 childSetCommitCallback("Twist End",onCommitParametric,this);
00215 mSpinTwist->setValidateBeforeCommit( &precommitValidate );
00216
00217
00218 mSpinScaleX = gUICtrlFactory->getSpinnerByName(this,"Taper Scale X");
00219 childSetCommitCallback("Taper Scale X",onCommitParametric,this);
00220 mSpinScaleX->setValidateBeforeCommit( &precommitValidate );
00221 mSpinScaleY = gUICtrlFactory->getSpinnerByName(this,"Taper Scale Y");
00222 childSetCommitCallback("Taper Scale Y",onCommitParametric,this);
00223 mSpinScaleY->setValidateBeforeCommit( &precommitValidate );
00224
00225
00226 mLabelShear = gUICtrlFactory->getTextBoxByName(this,"text topshear");
00227 mSpinShearX = gUICtrlFactory->getSpinnerByName(this,"Shear X");
00228 childSetCommitCallback("Shear X",onCommitParametric,this);
00229 mSpinShearX->setValidateBeforeCommit( &precommitValidate );
00230 mSpinShearY = gUICtrlFactory->getSpinnerByName(this,"Shear Y");
00231 childSetCommitCallback("Shear Y",onCommitParametric,this);
00232 mSpinShearY->setValidateBeforeCommit( &precommitValidate );
00233
00234
00235 mCtrlPathBegin = gUICtrlFactory->getSpinnerByName(this,"Path Limit Begin");
00236 childSetCommitCallback("Path Limit Begin",onCommitParametric,this);
00237 mCtrlPathBegin->setValidateBeforeCommit( &precommitValidate );
00238 mCtrlPathEnd = gUICtrlFactory->getSpinnerByName(this,"Path Limit End");
00239 childSetCommitCallback("Path Limit End",onCommitParametric,this);
00240 mCtrlPathEnd->setValidateBeforeCommit( &precommitValidate );
00241
00242
00243 mLabelTaper = gUICtrlFactory->getTextBoxByName(this,"text taper2");
00244 mSpinTaperX = gUICtrlFactory->getSpinnerByName(this,"Taper X");
00245 childSetCommitCallback("Taper X",onCommitParametric,this);
00246 mSpinTaperX->setValidateBeforeCommit( precommitValidate );
00247 mSpinTaperY = gUICtrlFactory->getSpinnerByName(this,"Taper Y");
00248 childSetCommitCallback("Taper Y",onCommitParametric,this);
00249 mSpinTaperY->setValidateBeforeCommit( precommitValidate );
00250
00251
00252 mLabelRadiusOffset = gUICtrlFactory->getTextBoxByName(this,"text radius delta");
00253 mLabelRevolutions = gUICtrlFactory->getTextBoxByName(this,"text revolutions");
00254 mSpinRadiusOffset = gUICtrlFactory->getSpinnerByName(this,"Radius Offset");
00255 childSetCommitCallback("Radius Offset",onCommitParametric,this);
00256 mSpinRadiusOffset->setValidateBeforeCommit( &precommitValidate );
00257 mSpinRevolutions = gUICtrlFactory->getSpinnerByName(this,"Revolutions");
00258 childSetCommitCallback("Revolutions",onCommitParametric,this);
00259 mSpinRevolutions->setValidateBeforeCommit( &precommitValidate );
00260
00261
00262 mCtrlSculptTexture = LLUICtrlFactory::getTexturePickerByName(this,"sculpt texture control");
00263 if (mCtrlSculptTexture)
00264 {
00265 mCtrlSculptTexture->setDefaultImageAssetID(LLUUID(SCULPT_DEFAULT_TEXTURE));
00266 mCtrlSculptTexture->setCommitCallback( LLPanelObject::onCommitSculpt );
00267 mCtrlSculptTexture->setOnCancelCallback( LLPanelObject::onCancelSculpt );
00268 mCtrlSculptTexture->setOnSelectCallback( LLPanelObject::onSelectSculpt );
00269 mCtrlSculptTexture->setDropCallback(LLPanelObject::onDropSculpt);
00270 mCtrlSculptTexture->setCallbackUserData( this );
00271
00272 mCtrlSculptTexture->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
00273
00274 mCtrlSculptTexture->setNonImmediateFilterPermMask(PERM_NONE);
00275 LLAggregatePermissions texture_perms;
00276 if (gSelectMgr->selectGetAggregateTexturePermissions(texture_perms))
00277 {
00278 BOOL can_copy =
00279 texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_EMPTY ||
00280 texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_ALL;
00281 BOOL can_transfer =
00282 texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_EMPTY ||
00283 texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_ALL;
00284 mCtrlSculptTexture->setCanApplyImmediately(can_copy && can_transfer);
00285 }
00286 else
00287 {
00288 mCtrlSculptTexture->setCanApplyImmediately(FALSE);
00289 }
00290 }
00291
00292 mLabelSculptType = gUICtrlFactory->getTextBoxByName(this, "label sculpt type");
00293 mCtrlSculptType = gUICtrlFactory->getComboBoxByName(this, "sculpt type control");
00294 childSetCommitCallback("sculpt type control", onCommitSculptType, this);
00295
00296
00297
00298 clearCtrls();
00299
00300 return TRUE;
00301 }
00302
00303 LLPanelObject::LLPanelObject(const std::string& name)
00304 : LLPanel(name),
00305 mIsPhysical(FALSE),
00306 mIsTemporary(FALSE),
00307 mIsPhantom(FALSE),
00308 mCastShadows(TRUE),
00309 mSelectedType(MI_BOX)
00310 {
00311 }
00312
00313
00314 LLPanelObject::~LLPanelObject()
00315 {
00316
00317 }
00318
00319 void LLPanelObject::getState( )
00320 {
00321 LLViewerObject* objectp = gSelectMgr->getSelection()->getFirstRootObject();
00322 LLViewerObject* root_objectp = objectp;
00323 if(!objectp)
00324 {
00325 objectp = gSelectMgr->getSelection()->getFirstObject();
00326
00327 if (objectp)
00328 {
00329 LLViewerObject* parentp = objectp->getSubParent();
00330
00331 if (parentp)
00332 {
00333 root_objectp = parentp;
00334 }
00335 else
00336 {
00337 root_objectp = objectp;
00338 }
00339 }
00340 }
00341
00342 LLVOVolume *volobjp = NULL;
00343 if ( objectp && (objectp->getPCode() == LL_PCODE_VOLUME))
00344 {
00345 volobjp = (LLVOVolume *)objectp;
00346 }
00347
00348 if( !objectp )
00349 {
00350
00351 if (gFocusMgr.childHasKeyboardFocus(this))
00352 {
00353 gFocusMgr.setKeyboardFocus(NULL, NULL);
00354 }
00355
00356
00357 clearCtrls();
00358 return;
00359 }
00360
00361
00362 BOOL enable_move = objectp->permMove() && !objectp->isAttachment() && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
00363 BOOL enable_scale = objectp->permMove() && objectp->permModify();
00364 BOOL enable_rotate = objectp->permMove() && ( (objectp->permModify() && !objectp->isAttachment()) || !gSavedSettings.getBOOL("EditLinkedParts"));
00365
00366 LLVector3 vec;
00367 if (enable_move)
00368 {
00369 vec = objectp->getPositionEdit();
00370 mCtrlPosX->set( vec.mV[VX] );
00371 mCtrlPosY->set( vec.mV[VY] );
00372 mCtrlPosZ->set( vec.mV[VZ] );
00373 }
00374 else
00375 {
00376 mCtrlPosX->clear();
00377 mCtrlPosY->clear();
00378 mCtrlPosZ->clear();
00379 }
00380
00381
00382 mLabelPosition->setEnabled( enable_move );
00383 mCtrlPosX->setEnabled(enable_move);
00384 mCtrlPosY->setEnabled(enable_move);
00385 mCtrlPosZ->setEnabled(enable_move);
00386
00387 if (enable_scale)
00388 {
00389 vec = objectp->getScale();
00390 mCtrlScaleX->set( vec.mV[VX] );
00391 mCtrlScaleY->set( vec.mV[VY] );
00392 mCtrlScaleZ->set( vec.mV[VZ] );
00393 }
00394 else
00395 {
00396 mCtrlScaleX->clear();
00397 mCtrlScaleY->clear();
00398 mCtrlScaleZ->clear();
00399 }
00400
00401 mLabelSize->setEnabled( enable_scale );
00402 mCtrlScaleX->setEnabled( enable_scale );
00403 mCtrlScaleY->setEnabled( enable_scale );
00404 mCtrlScaleZ->setEnabled( enable_scale );
00405
00406 LLQuaternion object_rot = objectp->getRotationEdit();
00407 object_rot.getEulerAngles(&(mCurEulerDegrees.mV[VX]), &(mCurEulerDegrees.mV[VY]), &(mCurEulerDegrees.mV[VZ]));
00408 mCurEulerDegrees *= RAD_TO_DEG;
00409 mCurEulerDegrees.mV[VX] = fmod(llround(mCurEulerDegrees.mV[VX], OBJECT_ROTATION_PRECISION) + 360.f, 360.f);
00410 mCurEulerDegrees.mV[VY] = fmod(llround(mCurEulerDegrees.mV[VY], OBJECT_ROTATION_PRECISION) + 360.f, 360.f);
00411 mCurEulerDegrees.mV[VZ] = fmod(llround(mCurEulerDegrees.mV[VZ], OBJECT_ROTATION_PRECISION) + 360.f, 360.f);
00412
00413 if (enable_rotate)
00414 {
00415 mCtrlRotX->set( mCurEulerDegrees.mV[VX] );
00416 mCtrlRotY->set( mCurEulerDegrees.mV[VY] );
00417 mCtrlRotZ->set( mCurEulerDegrees.mV[VZ] );
00418 }
00419 else
00420 {
00421 mCtrlRotX->clear();
00422 mCtrlRotY->clear();
00423 mCtrlRotZ->clear();
00424 }
00425
00426 mLabelRotation->setEnabled( enable_rotate );
00427 mCtrlRotX->setEnabled( enable_rotate );
00428 mCtrlRotY->setEnabled( enable_rotate );
00429 mCtrlRotZ->setEnabled( enable_rotate );
00430
00431 BOOL owners_identical;
00432 LLUUID owner_id;
00433 LLString owner_name;
00434 owners_identical = gSelectMgr->selectGetOwner(owner_id, owner_name);
00435
00436
00437 S32 roots_selected = gSelectMgr->getSelection()->getRootObjectCount();
00438 BOOL editable = root_objectp->permModify();
00439 S32 selected_count = gSelectMgr->getSelection()->getObjectCount();
00440 BOOL single_volume = (gSelectMgr->selectionAllPCode( LL_PCODE_VOLUME ))
00441 && (selected_count == 1);
00442
00443
00444 childSetVisible("select_single", FALSE);
00445 childSetVisible("edit_object", FALSE);
00446 if (!editable || single_volume || selected_count <= 1)
00447 {
00448 childSetVisible("edit_object", TRUE);
00449 childSetEnabled("edit_object", TRUE);
00450 }
00451 else
00452 {
00453 childSetVisible("select_single", TRUE);
00454 childSetEnabled("select_single", TRUE);
00455 }
00456
00457 BOOL self_owned = (gAgent.getID() == owner_id);
00458 mCheckLock->setEnabled( roots_selected > 0 && self_owned );
00459
00460
00461 BOOL valid;
00462 U32 owner_mask_on;
00463 U32 owner_mask_off;
00464 valid = gSelectMgr->selectGetPerm(PERM_OWNER, &owner_mask_on, &owner_mask_off);
00465
00466 if(valid)
00467 {
00468 if(owner_mask_on & PERM_MOVE)
00469 {
00470
00471 mCheckLock->set(FALSE);
00472 mCheckLock->setTentative(FALSE);
00473 }
00474 else if(owner_mask_off & PERM_MOVE)
00475 {
00476
00477 mCheckLock->set(TRUE);
00478 mCheckLock->setTentative(FALSE);
00479 }
00480 else
00481 {
00482
00483 mCheckLock->set(FALSE);
00484 mCheckLock->setTentative(TRUE);
00485 }
00486 }
00487
00488 BOOL is_flexible = volobjp && volobjp->isFlexible();
00489
00490
00491 mIsPhysical = root_objectp->usePhysics();
00492 mCheckPhysics->set( mIsPhysical );
00493 mCheckPhysics->setEnabled( roots_selected>0
00494 && (editable || gAgent.isGodlike())
00495 && !is_flexible);
00496
00497 mIsTemporary = root_objectp->flagTemporaryOnRez();
00498 mCheckTemporary->set( mIsTemporary );
00499 mCheckTemporary->setEnabled( roots_selected>0 && editable );
00500
00501 mIsPhantom = root_objectp->flagPhantom();
00502 mCheckPhantom->set( mIsPhantom );
00503 mCheckPhantom->setEnabled( roots_selected>0 && editable && !is_flexible );
00504
00505 #if 0 // 1.9.2
00506 mCastShadows = root_objectp->flagCastShadows();
00507 mCheckCastShadows->set( mCastShadows );
00508 mCheckCastShadows->setEnabled( roots_selected==1 && editable );
00509 #endif
00510
00511
00512
00513 U8 material_code = 0;
00514 struct f : public LLSelectedTEGetFunctor<U8>
00515 {
00516 U8 get(LLViewerObject* object, S32 te)
00517 {
00518 return object->getMaterial();
00519 }
00520 } func;
00521 bool material_same = gSelectMgr->getSelection()->getSelectedTEValue( &func, material_code );
00522
00523 if (editable && single_volume && material_same)
00524 {
00525 mComboMaterial->setEnabled( TRUE );
00526 mLabelMaterial->setEnabled( TRUE );
00527 if (material_code == LL_MCODE_LIGHT)
00528 {
00529 if (mComboMaterial->getItemCount() == mComboMaterialItemCount)
00530 {
00531 mComboMaterial->add(LEGACY_FULLBRIGHT_DESC);
00532 }
00533 mComboMaterial->setSimple(LEGACY_FULLBRIGHT_DESC);
00534 }
00535 else
00536 {
00537 if (mComboMaterial->getItemCount() != mComboMaterialItemCount)
00538 {
00539 mComboMaterial->remove(LEGACY_FULLBRIGHT_DESC);
00540 }
00541
00542 mComboMaterial->setSimple(LLString(LLMaterialTable::basic.getName(material_code)));
00543 }
00544 }
00545 else
00546 {
00547 mComboMaterial->setEnabled( FALSE );
00548 mLabelMaterial->setEnabled( FALSE );
00549 }
00550
00551
00552 S32 selected_item = MI_BOX;
00553 S32 selected_hole = MI_HOLE_SAME;
00554 BOOL enabled = FALSE;
00555 BOOL hole_enabled = FALSE;
00556 F32 scale_x=1.f, scale_y=1.f;
00557
00558 if( !objectp || !objectp->getVolume() || !editable || !single_volume)
00559 {
00560
00561 mComboBaseType->clear();
00562 mSpinHollow->clear();
00563 mSpinCutBegin->clear();
00564 mSpinCutEnd->clear();
00565 mCtrlPathBegin->clear();
00566 mCtrlPathEnd->clear();
00567 mSpinScaleX->clear();
00568 mSpinScaleY->clear();
00569 mSpinTwist->clear();
00570 mSpinTwistBegin->clear();
00571 mComboHoleType->clear();
00572 mSpinShearX->clear();
00573 mSpinShearY->clear();
00574 mSpinTaperX->clear();
00575 mSpinTaperY->clear();
00576 mSpinRadiusOffset->clear();
00577 mSpinRevolutions->clear();
00578 mSpinSkew->clear();
00579
00580 mSelectedType = MI_NONE;
00581 }
00582 else
00583 {
00584
00585
00586 enabled = root_objectp->permModify();
00587
00588 const LLVolumeParams &volume_params = objectp->getVolume()->getParams();
00589
00590
00591 U8 path = volume_params.getPathParams().getCurveType();
00592 U8 profile_and_hole = volume_params.getProfileParams().getCurveType();
00593 U8 profile = profile_and_hole & LL_PCODE_PROFILE_MASK;
00594 U8 hole = profile_and_hole & LL_PCODE_HOLE_MASK;
00595
00596
00597
00598
00599
00600 scale_x = volume_params.getRatioX();
00601 scale_y = volume_params.getRatioY();
00602
00603 BOOL linear_path = (path == LL_PCODE_PATH_LINE) || (path == LL_PCODE_PATH_FLEXIBLE);
00604 if ( linear_path && profile == LL_PCODE_PROFILE_CIRCLE )
00605 {
00606 selected_item = MI_CYLINDER;
00607 }
00608 else if ( linear_path && profile == LL_PCODE_PROFILE_SQUARE )
00609 {
00610 selected_item = MI_BOX;
00611 }
00612 else if ( linear_path && profile == LL_PCODE_PROFILE_ISOTRI )
00613 {
00614 selected_item = MI_PRISM;
00615 }
00616 else if ( linear_path && profile == LL_PCODE_PROFILE_EQUALTRI )
00617 {
00618 selected_item = MI_PRISM;
00619 }
00620 else if ( linear_path && profile == LL_PCODE_PROFILE_RIGHTTRI )
00621 {
00622 selected_item = MI_PRISM;
00623 }
00624 else if (path == LL_PCODE_PATH_FLEXIBLE)
00625 {
00626 selected_item = MI_CYLINDER;
00627 }
00628 else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_CIRCLE && scale_y > 0.75f)
00629 {
00630 selected_item = MI_SPHERE;
00631 }
00632 else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_CIRCLE && scale_y <= 0.75f)
00633 {
00634 selected_item = MI_TORUS;
00635 }
00636 else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_CIRCLE_HALF)
00637 {
00638 selected_item = MI_SPHERE;
00639 }
00640 else if ( path == LL_PCODE_PATH_CIRCLE2 && profile == LL_PCODE_PROFILE_CIRCLE )
00641 {
00642
00643 selected_item = MI_SPHERE;
00644 }
00645 else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_EQUALTRI )
00646 {
00647 selected_item = MI_RING;
00648 }
00649 else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_SQUARE && scale_y <= 0.75f)
00650 {
00651 selected_item = MI_TUBE;
00652 }
00653 else
00654 {
00655 llinfos << "Unknown path " << (S32) path << " profile " << (S32) profile << " in getState" << llendl;
00656 selected_item = MI_BOX;
00657 }
00658
00659
00660 if (objectp->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
00661 {
00662 selected_item = MI_SCULPT;
00663 LLFirstUse::useSculptedPrim();
00664 }
00665
00666
00667 mComboBaseType ->setCurrentByIndex( selected_item );
00668 mSelectedType = selected_item;
00669
00670
00671 F32 begin_s = volume_params.getBeginS();
00672 F32 end_s = volume_params.getEndS();
00673
00674
00675 F32 begin_t = volume_params.getBeginT();
00676 F32 end_t = volume_params.getEndT();
00677
00678
00679 F32 hollow = volume_params.getHollow();
00680 mSpinHollow->set( 100.f * hollow );
00681
00682
00683 if (hollow > 0.f)
00684 {
00685 switch (hole)
00686 {
00687 case LL_PCODE_HOLE_CIRCLE:
00688 selected_hole = MI_HOLE_CIRCLE;
00689 break;
00690 case LL_PCODE_HOLE_SQUARE:
00691 selected_hole = MI_HOLE_SQUARE;
00692 break;
00693 case LL_PCODE_HOLE_TRIANGLE:
00694 selected_hole = MI_HOLE_TRIANGLE;
00695 break;
00696 case LL_PCODE_HOLE_SAME:
00697 default:
00698 selected_hole = MI_HOLE_SAME;
00699 break;
00700 }
00701 mComboHoleType->setCurrentByIndex( selected_hole );
00702 hole_enabled = enabled;
00703 }
00704 else
00705 {
00706 mComboHoleType->setCurrentByIndex( MI_HOLE_SAME );
00707 hole_enabled = FALSE;
00708 }
00709
00710
00711 F32 cut_begin, cut_end, adv_cut_begin, adv_cut_end;
00712
00713 if ( selected_item == MI_SPHERE || selected_item == MI_TORUS ||
00714 selected_item == MI_TUBE || selected_item == MI_RING )
00715 {
00716 cut_begin = begin_t;
00717 cut_end = end_t;
00718 adv_cut_begin = begin_s;
00719 adv_cut_end = end_s;
00720 }
00721 else
00722 {
00723 cut_begin = begin_s;
00724 cut_end = end_s;
00725 adv_cut_begin = begin_t;
00726 adv_cut_end = end_t;
00727 }
00728
00729 mSpinCutBegin ->set( cut_begin );
00730 mSpinCutEnd ->set( cut_end );
00731 mCtrlPathBegin ->set( adv_cut_begin );
00732 mCtrlPathEnd ->set( adv_cut_end );
00733
00734
00735 F32 twist = volume_params.getTwist();
00736 F32 twist_begin = volume_params.getTwistBegin();
00737
00738 if (path == LL_PCODE_PATH_LINE || path == LL_PCODE_PATH_FLEXIBLE)
00739 {
00740 twist *= OBJECT_TWIST_LINEAR_MAX;
00741 twist_begin *= OBJECT_TWIST_LINEAR_MAX;
00742 }
00743 else
00744 {
00745 twist *= OBJECT_TWIST_MAX;
00746 twist_begin *= OBJECT_TWIST_MAX;
00747 }
00748
00749 mSpinTwist ->set( twist );
00750 mSpinTwistBegin ->set( twist_begin );
00751
00752
00753 F32 shear_x = volume_params.getShearX();
00754 F32 shear_y = volume_params.getShearY();
00755 mSpinShearX->set( shear_x );
00756 mSpinShearY->set( shear_y );
00757
00758
00759 F32 taper_x = volume_params.getTaperX();
00760 F32 taper_y = volume_params.getTaperY();
00761 mSpinTaperX->set( taper_x );
00762 mSpinTaperY->set( taper_y );
00763
00764
00765 F32 radius_offset = volume_params.getRadiusOffset();
00766
00767 F32 radius_mag = fabs(radius_offset);
00768 F32 hole_y_mag = fabs(scale_y);
00769 F32 taper_y_mag = fabs(taper_y);
00770
00771 if ( (radius_offset > 0.f && taper_y < 0.f) ||
00772 (radius_offset < 0.f && taper_y > 0.f) )
00773 {
00774
00775 taper_y_mag = 0.f;
00776 }
00777 F32 max_radius_mag = 1.f - hole_y_mag * (1.f - taper_y_mag) / (1.f - hole_y_mag);
00778
00779 if (radius_mag > max_radius_mag)
00780 {
00781
00782 if (radius_offset < 0.f)
00783 {
00784 radius_offset = -max_radius_mag;
00785 }
00786 else
00787 {
00788 radius_offset = max_radius_mag;
00789 }
00790 }
00791 mSpinRadiusOffset->set( radius_offset);
00792
00793
00794 F32 revolutions = volume_params.getRevolutions();
00795 mSpinRevolutions->set( revolutions );
00796
00797
00798 F32 skew = volume_params.getSkew();
00799
00800 F32 skew_mag= fabs(skew);
00801 F32 min_skew_mag = 1.0f - 1.0f / (revolutions * scale_x + 1.0f);
00802
00803 if ( fabs(revolutions - 1.0f) < 0.001)
00804 min_skew_mag = 0.0f;
00805
00806
00807 if (skew_mag < min_skew_mag)
00808 {
00809
00810 if (skew < 0.0f)
00811 {
00812 skew = -min_skew_mag;
00813 }
00814 else
00815 {
00816 skew = min_skew_mag;
00817 }
00818 }
00819 mSpinSkew->set( skew );
00820 }
00821
00822
00823
00824 BOOL cut_visible = TRUE;
00825 BOOL hollow_visible = TRUE;
00826 BOOL top_size_x_visible = TRUE;
00827 BOOL top_size_y_visible = TRUE;
00828 BOOL top_shear_x_visible = TRUE;
00829 BOOL top_shear_y_visible = TRUE;
00830 BOOL twist_visible = TRUE;
00831 BOOL advanced_cut_visible = FALSE;
00832 BOOL taper_visible = FALSE;
00833 BOOL skew_visible = FALSE;
00834 BOOL radius_offset_visible = FALSE;
00835 BOOL revolutions_visible = FALSE;
00836 BOOL sculpt_texture_visible = FALSE;
00837 F32 twist_min = OBJECT_TWIST_LINEAR_MIN;
00838 F32 twist_max = OBJECT_TWIST_LINEAR_MAX;
00839 F32 twist_inc = OBJECT_TWIST_LINEAR_INC;
00840
00841 BOOL advanced_is_dimple = FALSE;
00842 BOOL size_is_hole = FALSE;
00843
00844
00845 switch (selected_item)
00846 {
00847 case MI_SPHERE:
00848 top_size_x_visible = FALSE;
00849 top_size_y_visible = FALSE;
00850 top_shear_x_visible = FALSE;
00851 top_shear_y_visible = FALSE;
00852
00853 advanced_cut_visible = TRUE;
00854 advanced_is_dimple = TRUE;
00855 twist_min = OBJECT_TWIST_MIN;
00856 twist_max = OBJECT_TWIST_MAX;
00857 twist_inc = OBJECT_TWIST_INC;
00858 break;
00859
00860 case MI_TORUS:
00861 case MI_TUBE:
00862 case MI_RING:
00863
00864
00865 size_is_hole = TRUE;
00866 skew_visible = TRUE;
00867 advanced_cut_visible = TRUE;
00868 taper_visible = TRUE;
00869 radius_offset_visible = TRUE;
00870 revolutions_visible = TRUE;
00871 twist_min = OBJECT_TWIST_MIN;
00872 twist_max = OBJECT_TWIST_MAX;
00873 twist_inc = OBJECT_TWIST_INC;
00874
00875 break;
00876
00877 case MI_SCULPT:
00878 cut_visible = FALSE;
00879 hollow_visible = FALSE;
00880 twist_visible = FALSE;
00881 top_size_x_visible = FALSE;
00882 top_size_y_visible = FALSE;
00883 top_shear_x_visible = FALSE;
00884 top_shear_y_visible = FALSE;
00885 skew_visible = FALSE;
00886 advanced_cut_visible = FALSE;
00887 taper_visible = FALSE;
00888 radius_offset_visible = FALSE;
00889 revolutions_visible = FALSE;
00890 sculpt_texture_visible = TRUE;
00891
00892 break;
00893
00894 case MI_BOX:
00895 case MI_CYLINDER:
00896 case MI_PRISM:
00897 default:
00898 break;
00899 }
00900
00901
00902 switch (selected_item)
00903 {
00904 case MI_SPHERE:
00905 case MI_TORUS:
00906 case MI_TUBE:
00907 case MI_RING:
00908 mSpinScaleX->set( scale_x );
00909 mSpinScaleY->set( scale_y );
00910 mSpinScaleX->setMinValue(OBJECT_MIN_HOLE_SIZE);
00911 mSpinScaleX->setMaxValue(OBJECT_MAX_HOLE_SIZE_X);
00912 mSpinScaleY->setMinValue(OBJECT_MIN_HOLE_SIZE);
00913 mSpinScaleY->setMaxValue(OBJECT_MAX_HOLE_SIZE_Y);
00914 break;
00915 default:
00916 mSpinScaleX->set( 1.f - scale_x );
00917 mSpinScaleY->set( 1.f - scale_y );
00918 mSpinScaleX->setMinValue(-1.f);
00919 mSpinScaleX->setMaxValue(1.f);
00920 mSpinScaleY->setMinValue(-1.f);
00921 mSpinScaleY->setMaxValue(1.f);
00922 break;
00923 }
00924
00925
00926 if ( selected_hole == MI_HOLE_SQUARE &&
00927 ( selected_item == MI_CYLINDER || selected_item == MI_TORUS ||
00928 selected_item == MI_PRISM || selected_item == MI_RING ||
00929 selected_item == MI_SPHERE ) )
00930 {
00931 mSpinHollow->setMinValue(0.f);
00932 mSpinHollow->setMaxValue(70.f);
00933 }
00934 else
00935 {
00936 mSpinHollow->setMinValue(0.f);
00937 mSpinHollow->setMaxValue(95.f);
00938 }
00939
00940
00941 mLabelBaseType ->setEnabled( enabled );
00942 mComboBaseType ->setEnabled( enabled );
00943
00944 mLabelCut ->setEnabled( enabled );
00945 mSpinCutBegin ->setEnabled( enabled );
00946 mSpinCutEnd ->setEnabled( enabled );
00947
00948 mLabelHollow ->setEnabled( enabled );
00949 mSpinHollow ->setEnabled( enabled );
00950 mLabelHoleType ->setEnabled( hole_enabled );
00951 mComboHoleType ->setEnabled( hole_enabled );
00952
00953 mLabelTwist ->setEnabled( enabled );
00954 mSpinTwist ->setEnabled( enabled );
00955 mSpinTwistBegin ->setEnabled( enabled );
00956
00957 mLabelSkew ->setEnabled( enabled );
00958 mSpinSkew ->setEnabled( enabled );
00959
00960 childSetVisible("scale_hole", FALSE);
00961 childSetVisible("scale_taper", FALSE);
00962 if (top_size_x_visible || top_size_y_visible)
00963 {
00964 if (size_is_hole)
00965 {
00966 childSetVisible("scale_hole", TRUE);
00967 childSetEnabled("scale_hole", enabled);
00968 }
00969 else
00970 {
00971 childSetVisible("scale_taper", TRUE);
00972 childSetEnabled("scale_taper", enabled);
00973 }
00974 }
00975
00976 mSpinScaleX ->setEnabled( enabled );
00977 mSpinScaleY ->setEnabled( enabled );
00978
00979 mLabelShear ->setEnabled( enabled );
00980 mSpinShearX ->setEnabled( enabled );
00981 mSpinShearY ->setEnabled( enabled );
00982
00983 childSetVisible("advanced_cut", FALSE);
00984 childSetVisible("advanced_dimple", FALSE);
00985 if (advanced_cut_visible)
00986 {
00987 if (advanced_is_dimple)
00988 {
00989 childSetVisible("advanced_dimple", TRUE);
00990 childSetEnabled("advanced_dimple", enabled);
00991 }
00992 else
00993 {
00994 childSetVisible("advanced_cut", TRUE);
00995 childSetEnabled("advanced_cut", enabled);
00996 }
00997 }
00998
00999 mCtrlPathBegin ->setEnabled( enabled );
01000 mCtrlPathEnd ->setEnabled( enabled );
01001
01002 mLabelTaper ->setEnabled( enabled );
01003 mSpinTaperX ->setEnabled( enabled );
01004 mSpinTaperY ->setEnabled( enabled );
01005
01006 mLabelRadiusOffset->setEnabled( enabled );
01007 mSpinRadiusOffset ->setEnabled( enabled );
01008
01009 mLabelRevolutions->setEnabled( enabled );
01010 mSpinRevolutions ->setEnabled( enabled );
01011
01012
01013 mLabelCut ->setVisible( cut_visible );
01014 mSpinCutBegin ->setVisible( cut_visible );
01015 mSpinCutEnd ->setVisible( cut_visible );
01016
01017 mLabelHollow ->setVisible( hollow_visible );
01018 mSpinHollow ->setVisible( hollow_visible );
01019 mLabelHoleType ->setVisible( hollow_visible );
01020 mComboHoleType ->setVisible( hollow_visible );
01021
01022 mLabelTwist ->setVisible( twist_visible );
01023 mSpinTwist ->setVisible( twist_visible );
01024 mSpinTwistBegin ->setVisible( twist_visible );
01025 mSpinTwist ->setMinValue( twist_min );
01026 mSpinTwist ->setMaxValue( twist_max );
01027 mSpinTwist ->setIncrement( twist_inc );
01028 mSpinTwistBegin ->setMinValue( twist_min );
01029 mSpinTwistBegin ->setMaxValue( twist_max );
01030 mSpinTwistBegin ->setIncrement( twist_inc );
01031
01032 mSpinScaleX ->setVisible( top_size_x_visible );
01033 mSpinScaleY ->setVisible( top_size_y_visible );
01034
01035 mLabelSkew ->setVisible( skew_visible );
01036 mSpinSkew ->setVisible( skew_visible );
01037
01038 mLabelShear ->setVisible( top_shear_x_visible || top_shear_y_visible );
01039 mSpinShearX ->setVisible( top_shear_x_visible );
01040 mSpinShearY ->setVisible( top_shear_y_visible );
01041
01042 mCtrlPathBegin ->setVisible( advanced_cut_visible );
01043 mCtrlPathEnd ->setVisible( advanced_cut_visible );
01044
01045 mLabelTaper ->setVisible( taper_visible );
01046 mSpinTaperX ->setVisible( taper_visible );
01047 mSpinTaperY ->setVisible( taper_visible );
01048
01049 mLabelRadiusOffset->setVisible( radius_offset_visible );
01050 mSpinRadiusOffset ->setVisible( radius_offset_visible );
01051
01052 mLabelRevolutions->setVisible( revolutions_visible );
01053 mSpinRevolutions ->setVisible( revolutions_visible );
01054
01055 bool sculpt_type_visible = FALSE;
01056 mCtrlSculptTexture->setVisible(sculpt_texture_visible);
01057 mLabelSculptType->setVisible(sculpt_texture_visible && sculpt_type_visible);
01058 mCtrlSculptType->setVisible(sculpt_texture_visible && sculpt_type_visible);
01059
01060
01061
01062
01063 if (selected_item == MI_SCULPT)
01064 {
01065 LLUUID id;
01066 LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
01067
01068
01069 if (sculpt_params)
01070 {
01071 if (mObject != objectp)
01072 {
01073 mSculptTextureRevert = sculpt_params->getSculptTexture();
01074 mSculptTypeRevert = sculpt_params->getSculptType();
01075 }
01076
01077 LLTextureCtrl* mTextureCtrl = LLViewerUICtrlFactory::getTexturePickerByName(this,"sculpt texture control");
01078 if(mTextureCtrl)
01079 {
01080 mTextureCtrl->setTentative(FALSE);
01081 mTextureCtrl->setEnabled(editable);
01082 if (editable)
01083 mTextureCtrl->setImageAssetID(sculpt_params->getSculptTexture());
01084 else
01085 mTextureCtrl->setImageAssetID(LLUUID::null);
01086 }
01087
01088 if (mCtrlSculptType)
01089 {
01090 mCtrlSculptType->setCurrentByIndex(sculpt_params->getSculptType());
01091 mCtrlSculptType->setEnabled(editable);
01092 }
01093
01094 if (mLabelSculptType)
01095 {
01096 mLabelSculptType->setEnabled(TRUE);
01097 }
01098
01099
01100 }
01101 }
01102
01103
01104
01105
01106 mObject = objectp;
01107 mRootObject = root_objectp;
01108 }
01109
01110
01111 BOOL LLPanelObject::precommitValidate( LLUICtrl* ctrl, void* userdata )
01112 {
01113
01114 return TRUE;
01115 }
01116
01117 void LLPanelObject::sendIsPhysical()
01118 {
01119 BOOL value = mCheckPhysics->get();
01120 if( mIsPhysical != value )
01121 {
01122 gSelectMgr->selectionUpdatePhysics(value);
01123 mIsPhysical = value;
01124
01125 llinfos << "update physics sent" << llendl;
01126 }
01127 else
01128 {
01129 llinfos << "update physics not changed" << llendl;
01130 }
01131 }
01132
01133 void LLPanelObject::sendIsTemporary()
01134 {
01135 BOOL value = mCheckTemporary->get();
01136 if( mIsTemporary != value )
01137 {
01138 gSelectMgr->selectionUpdateTemporary(value);
01139 mIsTemporary = value;
01140
01141 llinfos << "update temporary sent" << llendl;
01142 }
01143 else
01144 {
01145 llinfos << "update temporary not changed" << llendl;
01146 }
01147 }
01148
01149
01150 void LLPanelObject::sendIsPhantom()
01151 {
01152 BOOL value = mCheckPhantom->get();
01153 if( mIsPhantom != value )
01154 {
01155 gSelectMgr->selectionUpdatePhantom(value);
01156 mIsPhantom = value;
01157
01158 llinfos << "update phantom sent" << llendl;
01159 }
01160 else
01161 {
01162 llinfos << "update phantom not changed" << llendl;
01163 }
01164 }
01165
01166 void LLPanelObject::sendCastShadows()
01167 {
01168 BOOL value = mCheckCastShadows->get();
01169 if( mCastShadows != value )
01170 {
01171 gSelectMgr->selectionUpdateCastShadows(value);
01172 mCastShadows = value;
01173
01174 llinfos << "update cast shadows sent" << llendl;
01175 }
01176 else
01177 {
01178 llinfos << "update cast shadows not changed" << llendl;
01179 }
01180 }
01181
01182
01183 void LLPanelObject::onCommitMaterial( LLUICtrl* ctrl, void* userdata )
01184 {
01185
01186 LLComboBox* box = (LLComboBox*) ctrl;
01187
01188 if (box)
01189 {
01190
01191 const LLString& material_name = box->getSimple();
01192 if (material_name != LEGACY_FULLBRIGHT_DESC)
01193 {
01194 U8 material_code = LLMaterialTable::basic.getMCode(material_name.c_str());
01195 gSelectMgr->selectionSetMaterial(material_code);
01196 }
01197 }
01198 }
01199
01200
01201 void LLPanelObject::onCommitParametric( LLUICtrl* ctrl, void* userdata )
01202 {
01203 LLPanelObject* self = (LLPanelObject*) userdata;
01204
01205 if (self->mObject.isNull())
01206 {
01207 return;
01208 }
01209
01210 if (self->mObject->getPCode() != LL_PCODE_VOLUME)
01211 {
01212
01213 return;
01214 }
01215
01216 LLVolume *volume = self->mObject->getVolume();
01217 if (!volume)
01218 {
01219 return;
01220 }
01221
01222 LLVolumeParams volume_params;
01223 self->getVolumeParams(volume_params);
01224
01225
01226
01227
01228 S32 selected_type = self->mComboBaseType->getCurrentIndex();
01229
01230 if (selected_type == MI_SCULPT)
01231 {
01232 self->mObject->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, TRUE, TRUE);
01233 LLSculptParams *sculpt_params = (LLSculptParams *)self->mObject->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
01234 if (sculpt_params)
01235 volume_params.setSculptID(sculpt_params->getSculptTexture(), sculpt_params->getSculptType());
01236 }
01237 else
01238 {
01239 LLSculptParams *sculpt_params = (LLSculptParams *)self->mObject->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
01240 if (sculpt_params)
01241 self->mObject->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, FALSE, TRUE);
01242 }
01243
01244
01245 self->mObject->updateVolume(volume_params);
01246
01247
01248
01249
01250
01251
01252 self->refresh();
01253
01254 }
01255
01256 void LLPanelObject::getVolumeParams(LLVolumeParams& volume_params)
01257 {
01258
01259 S32 was_selected_type = mSelectedType;
01260 S32 selected_type = mComboBaseType->getCurrentIndex();
01261 U8 profile;
01262 U8 path;
01263 switch ( selected_type )
01264 {
01265 case MI_CYLINDER:
01266 profile = LL_PCODE_PROFILE_CIRCLE;
01267 path = LL_PCODE_PATH_LINE;
01268 break;
01269
01270 case MI_BOX:
01271 profile = LL_PCODE_PROFILE_SQUARE;
01272 path = LL_PCODE_PATH_LINE;
01273 break;
01274
01275 case MI_PRISM:
01276 profile = LL_PCODE_PROFILE_EQUALTRI;
01277 path = LL_PCODE_PATH_LINE;
01278 break;
01279
01280 case MI_SPHERE:
01281 profile = LL_PCODE_PROFILE_CIRCLE_HALF;
01282 path = LL_PCODE_PATH_CIRCLE;
01283 break;
01284
01285 case MI_TORUS:
01286 profile = LL_PCODE_PROFILE_CIRCLE;
01287 path = LL_PCODE_PATH_CIRCLE;
01288 break;
01289
01290 case MI_TUBE:
01291 profile = LL_PCODE_PROFILE_SQUARE;
01292 path = LL_PCODE_PATH_CIRCLE;
01293 break;
01294
01295 case MI_RING:
01296 profile = LL_PCODE_PROFILE_EQUALTRI;
01297 path = LL_PCODE_PATH_CIRCLE;
01298 break;
01299
01300 case MI_SCULPT:
01301 profile = LL_PCODE_PROFILE_CIRCLE;
01302 path = LL_PCODE_PATH_CIRCLE;
01303 break;
01304
01305 default:
01306 llwarns << "Unknown base type " << selected_type
01307 << " in getVolumeParams()" << llendl;
01308
01309 selected_type = MI_BOX;
01310 profile = LL_PCODE_PROFILE_SQUARE;
01311 path = LL_PCODE_PATH_LINE;
01312 break;
01313 }
01314
01315
01316 if (path == LL_PCODE_PATH_LINE)
01317 {
01318 LLVOVolume *volobjp = (LLVOVolume *)(LLViewerObject*)(mObject);
01319 if (volobjp->isFlexible())
01320 {
01321 path = LL_PCODE_PATH_FLEXIBLE;
01322 }
01323 }
01324
01325 S32 selected_hole = mComboHoleType->getCurrentIndex();
01326 U8 hole;
01327 switch (selected_hole)
01328 {
01329 case MI_HOLE_CIRCLE:
01330 hole = LL_PCODE_HOLE_CIRCLE;
01331 break;
01332 case MI_HOLE_SQUARE:
01333 hole = LL_PCODE_HOLE_SQUARE;
01334 break;
01335 case MI_HOLE_TRIANGLE:
01336 hole = LL_PCODE_HOLE_TRIANGLE;
01337 break;
01338 case MI_HOLE_SAME:
01339 default:
01340 hole = LL_PCODE_HOLE_SAME;
01341 break;
01342 }
01343
01344 volume_params.setType(profile | hole, path);
01345 mSelectedType = selected_type;
01346
01347
01348 F32 cut_begin = mSpinCutBegin->get();
01349 F32 cut_end = mSpinCutEnd->get();
01350
01351
01352 if (cut_begin > cut_end - OBJECT_MIN_CUT_INC)
01353 {
01354 cut_begin = cut_end - OBJECT_MIN_CUT_INC;
01355 mSpinCutBegin->set(cut_begin);
01356 }
01357
01358 F32 adv_cut_begin = mCtrlPathBegin->get();
01359 F32 adv_cut_end = mCtrlPathEnd->get();
01360
01361
01362 if (adv_cut_begin > adv_cut_end - OBJECT_MIN_CUT_INC)
01363 {
01364 adv_cut_begin = adv_cut_end - OBJECT_MIN_CUT_INC;
01365 mCtrlPathBegin->set(adv_cut_begin);
01366 }
01367
01368 F32 begin_s, end_s;
01369 F32 begin_t, end_t;
01370
01371 if (selected_type == MI_SPHERE || selected_type == MI_TORUS ||
01372 selected_type == MI_TUBE || selected_type == MI_RING)
01373 {
01374 begin_s = adv_cut_begin;
01375 end_s = adv_cut_end;
01376
01377 begin_t = cut_begin;
01378 end_t = cut_end;
01379 }
01380 else
01381 {
01382 begin_s = cut_begin;
01383 end_s = cut_end;
01384
01385 begin_t = adv_cut_begin;
01386 end_t = adv_cut_end;
01387 }
01388
01389 volume_params.setBeginAndEndS(begin_s, end_s);
01390 volume_params.setBeginAndEndT(begin_t, end_t);
01391
01392
01393 F32 hollow = mSpinHollow->get() / 100.f;
01394
01395 if ( selected_hole == MI_HOLE_SQUARE &&
01396 ( selected_type == MI_CYLINDER || selected_type == MI_TORUS ||
01397 selected_type == MI_PRISM || selected_type == MI_RING ||
01398 selected_type == MI_SPHERE ) )
01399 {
01400 if (hollow > 0.7f) hollow = 0.7f;
01401 }
01402
01403 volume_params.setHollow( hollow );
01404
01405
01406 F32 twist_begin = mSpinTwistBegin->get();
01407 F32 twist = mSpinTwist->get();
01408
01409 if (path == LL_PCODE_PATH_LINE || path == LL_PCODE_PATH_FLEXIBLE)
01410 {
01411 twist_begin /= OBJECT_TWIST_LINEAR_MAX;
01412 twist /= OBJECT_TWIST_LINEAR_MAX;
01413 }
01414 else
01415 {
01416 twist_begin /= OBJECT_TWIST_MAX;
01417 twist /= OBJECT_TWIST_MAX;
01418 }
01419
01420 volume_params.setTwistBegin(twist_begin);
01421 volume_params.setTwist(twist);
01422
01423
01424 F32 scale_x = mSpinScaleX->get();
01425 F32 scale_y = mSpinScaleY->get();
01426 if ( was_selected_type == MI_BOX || was_selected_type == MI_CYLINDER || was_selected_type == MI_PRISM)
01427 {
01428 scale_x = 1.f - scale_x;
01429 scale_y = 1.f - scale_y;
01430 }
01431
01432
01433 F32 skew = mSpinSkew->get();
01434
01435
01436 F32 taper_x = mSpinTaperX->get();
01437 F32 taper_y = mSpinTaperY->get();
01438
01439
01440 F32 radius_offset = mSpinRadiusOffset->get();
01441
01442
01443 F32 revolutions = mSpinRevolutions->get();
01444
01445 if ( selected_type == MI_SPHERE )
01446 {
01447
01448 scale_x = 1.0f;
01449 scale_y = 1.0f;
01450 skew = 0.0f;
01451 taper_x = 0.0f;
01452 taper_y = 0.0f;
01453 radius_offset = 0.0f;
01454 revolutions = 1.0f;
01455 }
01456 else if ( selected_type == MI_TORUS || selected_type == MI_TUBE ||
01457 selected_type == MI_RING )
01458 {
01459 scale_x = llclamp(
01460 scale_x,
01461 OBJECT_MIN_HOLE_SIZE,
01462 OBJECT_MAX_HOLE_SIZE_X);
01463 scale_y = llclamp(
01464 scale_y,
01465 OBJECT_MIN_HOLE_SIZE,
01466 OBJECT_MAX_HOLE_SIZE_Y);
01467
01468
01469 F32 radius_mag = fabs(radius_offset);
01470 F32 hole_y_mag = fabs(scale_y);
01471 F32 taper_y_mag = fabs(taper_y);
01472
01473 if ( (radius_offset > 0.f && taper_y < 0.f) ||
01474 (radius_offset < 0.f && taper_y > 0.f) )
01475 {
01476
01477 taper_y_mag = 0.f;
01478 }
01479 F32 max_radius_mag = 1.f - hole_y_mag * (1.f - taper_y_mag) / (1.f - hole_y_mag);
01480
01481 if (radius_mag > max_radius_mag)
01482 {
01483
01484 if (radius_offset < 0.f)
01485 {
01486 radius_offset = -max_radius_mag;
01487 }
01488 else
01489 {
01490 radius_offset = max_radius_mag;
01491 }
01492 }
01493
01494
01495 F32 skew_mag= fabs(skew);
01496 F32 min_skew_mag = 1.0f - 1.0f / (revolutions * scale_x + 1.0f);
01497
01498 if ( fabs(revolutions - 1.0f) < 0.001)
01499 min_skew_mag = 0.0f;
01500
01501
01502 if (skew_mag < min_skew_mag)
01503 {
01504
01505 if (skew < 0.0f)
01506 {
01507 skew = -min_skew_mag;
01508 }
01509 else
01510 {
01511 skew = min_skew_mag;
01512 }
01513 }
01514 }
01515
01516 volume_params.setRatio( scale_x, scale_y );
01517 volume_params.setSkew(skew);
01518 volume_params.setTaper( taper_x, taper_y );
01519 volume_params.setRadiusOffset(radius_offset);
01520 volume_params.setRevolutions(revolutions);
01521
01522
01523 F32 shear_x = mSpinShearX->get();
01524 F32 shear_y = mSpinShearY->get();
01525 volume_params.setShear( shear_x, shear_y );
01526
01527 if (selected_type == MI_SCULPT)
01528 {
01529 volume_params.setSculptID(LLUUID::null, 0);
01530 volume_params.setBeginAndEndT (0, 1);
01531 volume_params.setBeginAndEndS (0, 1);
01532 volume_params.setHollow (0);
01533 volume_params.setTwistBegin (0);
01534 volume_params.setTwistEnd (0);
01535 volume_params.setRatio (1, 0.5);
01536 volume_params.setShear (0, 0);
01537 volume_params.setTaper (0, 0);
01538 volume_params.setRevolutions (1);
01539 volume_params.setRadiusOffset (0);
01540 volume_params.setSkew (0);
01541 }
01542
01543 }
01544
01545
01546 void LLPanelObject::sendRotation()
01547 {
01548 if (mObject.isNull()) return;
01549
01550 LLVector3 new_rot(mCtrlRotX->get(), mCtrlRotY->get(), mCtrlRotZ->get());
01551 new_rot.mV[VX] = llround(new_rot.mV[VX], OBJECT_ROTATION_PRECISION);
01552 new_rot.mV[VY] = llround(new_rot.mV[VY], OBJECT_ROTATION_PRECISION);
01553 new_rot.mV[VZ] = llround(new_rot.mV[VZ], OBJECT_ROTATION_PRECISION);
01554
01555
01556 LLVector3 delta = new_rot - mCurEulerDegrees;
01557
01558 if (delta.magVec() >= 0.0005f)
01559 {
01560 mCurEulerDegrees = new_rot;
01561 new_rot *= DEG_TO_RAD;
01562
01563 LLQuaternion rotation;
01564 rotation.setQuat(new_rot.mV[VX], new_rot.mV[VY], new_rot.mV[VZ]);
01565
01566 if (mRootObject != mObject)
01567 {
01568 rotation = rotation * ~mRootObject->getRotationRegion();
01569 }
01570
01571 mObject->setRotation(rotation, TRUE );
01572
01573 gSelectMgr->sendMultipleUpdate(UPD_ROTATION);
01574 }
01575 }
01576
01577
01578
01579 void LLPanelObject::sendScale()
01580 {
01581 if (mObject.isNull()) return;
01582
01583 LLVector3 newscale(mCtrlScaleX->get(), mCtrlScaleY->get(), mCtrlScaleZ->get());
01584
01585 LLVector3 delta = newscale - mObject->getScale();
01586 if (delta.magVec() >= 0.0005f)
01587 {
01588
01589
01590
01591
01592 BOOL dont_stretch_textures = !LLManipScale::getStretchTextures();
01593 if (dont_stretch_textures)
01594 {
01595 gSelectMgr->saveSelectedObjectTransform(SELECT_ACTION_TYPE_SCALE);
01596 }
01597
01598 mObject->setScale(newscale, TRUE);
01599 gSelectMgr->sendMultipleUpdate(UPD_SCALE | UPD_POSITION);
01600
01601 gSelectMgr->adjustTexturesByScale(TRUE, !dont_stretch_textures);
01602
01603 }
01604 else
01605 {
01606
01607 }
01608 }
01609
01610
01611 void LLPanelObject::sendPosition()
01612 {
01613 if (mObject.isNull()) return;
01614
01615 LLVector3 newpos(mCtrlPosX->get(), mCtrlPosY->get(), mCtrlPosZ->get());
01616 LLViewerRegion* regionp = mObject->getRegion();
01617
01618
01619 const F32 height = newpos.mV[VZ];
01620 const F32 min_height = gWorldp->getMinAllowedZ(mObject);
01621 const F32 max_height = gWorldPointer->getRegionMaxHeight();
01622
01623 if (!mObject->isAttachment())
01624 {
01625 if ( height < min_height)
01626 {
01627 newpos.mV[VZ] = min_height;
01628 mCtrlPosZ->set( min_height );
01629 }
01630 else if ( height > max_height )
01631 {
01632 newpos.mV[VZ] = max_height;
01633 mCtrlPosZ->set( max_height );
01634 }
01635
01636
01637 if (mObject->getPCode() == LL_PCODE_LEGACY_GRASS)
01638 {
01639 mCtrlPosZ->set(gWorldp->resolveLandHeightAgent(newpos) + 1.f);
01640 }
01641 }
01642
01643
01644
01645 LLVector3d new_pos_global = regionp->getPosGlobalFromRegion(newpos);
01646
01647 if ( gWorldPointer->positionRegionValidGlobal(new_pos_global) )
01648 {
01649
01650 LLVector3d old_pos_global = mObject->getPositionGlobal();
01651 LLVector3d delta = new_pos_global - old_pos_global;
01652
01653 if (delta.magVec() >= 0.0005f)
01654 {
01655 if (mRootObject != mObject)
01656 {
01657 newpos = newpos - mRootObject->getPositionRegion();
01658 newpos = newpos * ~mRootObject->getRotationRegion();
01659 mObject->setPositionParent(newpos);
01660 }
01661 else
01662 {
01663 mObject->setPositionEdit(newpos);
01664 }
01665 gSelectMgr->sendMultipleUpdate(UPD_POSITION);
01666
01667
01668 gSelectMgr->updateSelectionCenter();
01669
01670
01671 }
01672 else
01673 {
01674
01675 }
01676 }
01677 else
01678 {
01679
01680 LLVector3 vec = mRootObject->getPositionRegion();
01681 mCtrlPosX->set(vec.mV[VX]);
01682 mCtrlPosY->set(vec.mV[VY]);
01683 mCtrlPosZ->set(vec.mV[VZ]);
01684 }
01685 }
01686
01687 void LLPanelObject::sendSculpt()
01688 {
01689 if (mObject.isNull())
01690 return;
01691
01692 LLSculptParams sculpt_params;
01693
01694 if (mCtrlSculptTexture)
01695 sculpt_params.setSculptTexture(mCtrlSculptTexture->getImageAssetID());
01696
01697 if (mCtrlSculptType)
01698 sculpt_params.setSculptType(mCtrlSculptType->getCurrentIndex());
01699
01700 mObject->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt_params, TRUE);
01701 }
01702
01703 void LLPanelObject::refresh()
01704 {
01705 getState();
01706 if (mObject.notNull() && mObject->isDead())
01707 {
01708 mObject = NULL;
01709 }
01710
01711 if (mRootObject.notNull() && mRootObject->isDead())
01712 {
01713 mRootObject = NULL;
01714 }
01715 }
01716
01717
01718 void LLPanelObject::draw()
01719 {
01720 const LLColor4 white( 1.0f, 1.0f, 1.0f, 1);
01721 const LLColor4 red( 1.0f, 0.25f, 0.f, 1);
01722 const LLColor4 green( 0.f, 1.0f, 0.f, 1);
01723 const LLColor4 blue( 0.f, 0.5f, 1.0f, 1);
01724
01725
01726 LLTool* tool = gToolMgr->getCurrentTool();
01727
01728 if (tool == gToolTranslate)
01729 {
01730 mCtrlPosX ->setLabelColor(red);
01731 mCtrlPosY ->setLabelColor(green);
01732 mCtrlPosZ ->setLabelColor(blue);
01733
01734 mCtrlScaleX ->setLabelColor(white);
01735 mCtrlScaleY ->setLabelColor(white);
01736 mCtrlScaleZ ->setLabelColor(white);
01737
01738 mCtrlRotX ->setLabelColor(white);
01739 mCtrlRotY ->setLabelColor(white);
01740 mCtrlRotZ ->setLabelColor(white);
01741 }
01742 else if ( tool == gToolStretch )
01743 {
01744 mCtrlPosX ->setLabelColor(white);
01745 mCtrlPosY ->setLabelColor(white);
01746 mCtrlPosZ ->setLabelColor(white);
01747
01748 mCtrlScaleX ->setLabelColor(red);
01749 mCtrlScaleY ->setLabelColor(green);
01750 mCtrlScaleZ ->setLabelColor(blue);
01751
01752 mCtrlRotX ->setLabelColor(white);
01753 mCtrlRotY ->setLabelColor(white);
01754 mCtrlRotZ ->setLabelColor(white);
01755 }
01756 else if ( tool == gToolRotate )
01757 {
01758 mCtrlPosX ->setLabelColor(white);
01759 mCtrlPosY ->setLabelColor(white);
01760 mCtrlPosZ ->setLabelColor(white);
01761
01762 mCtrlScaleX ->setLabelColor(white);
01763 mCtrlScaleY ->setLabelColor(white);
01764 mCtrlScaleZ ->setLabelColor(white);
01765
01766 mCtrlRotX ->setLabelColor(red);
01767 mCtrlRotY ->setLabelColor(green);
01768 mCtrlRotZ ->setLabelColor(blue);
01769 }
01770 else
01771 {
01772 mCtrlPosX ->setLabelColor(white);
01773 mCtrlPosY ->setLabelColor(white);
01774 mCtrlPosZ ->setLabelColor(white);
01775
01776 mCtrlScaleX ->setLabelColor(white);
01777 mCtrlScaleY ->setLabelColor(white);
01778 mCtrlScaleZ ->setLabelColor(white);
01779
01780 mCtrlRotX ->setLabelColor(white);
01781 mCtrlRotY ->setLabelColor(white);
01782 mCtrlRotZ ->setLabelColor(white);
01783 }
01784
01785 LLPanel::draw();
01786 }
01787
01788
01789 void LLPanelObject::clearCtrls()
01790 {
01791 LLPanel::clearCtrls();
01792
01793 mCheckLock ->set(FALSE);
01794 mCheckLock ->setEnabled( FALSE );
01795 mCheckPhysics ->set(FALSE);
01796 mCheckPhysics ->setEnabled( FALSE );
01797 mCheckTemporary ->set(FALSE);
01798 mCheckTemporary ->setEnabled( FALSE );
01799 mCheckPhantom ->set(FALSE);
01800 mCheckPhantom ->setEnabled( FALSE );
01801 #if 0 // 1.9.2
01802 mCheckCastShadows->set(FALSE);
01803 mCheckCastShadows->setEnabled( FALSE );
01804 #endif
01805 mComboMaterial ->setEnabled( FALSE );
01806 mLabelMaterial ->setEnabled( FALSE );
01807
01808 mLabelPosition ->setEnabled( FALSE );
01809 mLabelSize ->setEnabled( FALSE );
01810 mLabelRotation ->setEnabled( FALSE );
01811 mLabelBaseType ->setEnabled( FALSE );
01812 mLabelCut ->setEnabled( FALSE );
01813 mLabelHollow ->setEnabled( FALSE );
01814 mLabelHoleType ->setEnabled( FALSE );
01815 mLabelTwist ->setEnabled( FALSE );
01816 mLabelSkew ->setEnabled( FALSE );
01817 mLabelShear ->setEnabled( FALSE );
01818 mLabelTaper ->setEnabled( FALSE );
01819 mLabelRadiusOffset->setEnabled( FALSE );
01820 mLabelRevolutions->setEnabled( FALSE );
01821
01822 childSetVisible("select_single", TRUE);
01823 childSetVisible("edit_object", TRUE);
01824 childSetEnabled("edit_object", FALSE);
01825
01826 childSetEnabled("scale_hole", FALSE);
01827 childSetEnabled("scale_taper", FALSE);
01828 childSetEnabled( "advanced_cut", FALSE );
01829 childSetEnabled( "advanced_dimple", FALSE );
01830 }
01831
01832
01833
01834
01835
01836
01837 void LLPanelObject::onCommitLock(LLUICtrl *ctrl, void *data)
01838 {
01839
01840 LLPanelObject *self = (LLPanelObject *)data;
01841
01842 if(self->mRootObject.isNull()) return;
01843
01844 BOOL new_state = self->mCheckLock->get();
01845
01846 gSelectMgr->selectionSetObjectPermissions(PERM_OWNER, !new_state, PERM_MOVE | PERM_MODIFY);
01847 }
01848
01849
01850 void LLPanelObject::onCommitPosition( LLUICtrl* ctrl, void* userdata )
01851 {
01852 LLPanelObject* self = (LLPanelObject*) userdata;
01853 self->sendPosition();
01854 }
01855
01856
01857 void LLPanelObject::onCommitScale( LLUICtrl* ctrl, void* userdata )
01858 {
01859 LLPanelObject* self = (LLPanelObject*) userdata;
01860 self->sendScale();
01861 }
01862
01863
01864 void LLPanelObject::onCommitRotation( LLUICtrl* ctrl, void* userdata )
01865 {
01866 LLPanelObject* self = (LLPanelObject*) userdata;
01867 self->sendRotation();
01868 }
01869
01870
01871 void LLPanelObject::onCommitPhysics( LLUICtrl* ctrl, void* userdata )
01872 {
01873 LLPanelObject* self = (LLPanelObject*) userdata;
01874 self->sendIsPhysical();
01875 }
01876
01877
01878 void LLPanelObject::onCommitTemporary( LLUICtrl* ctrl, void* userdata )
01879 {
01880 LLPanelObject* self = (LLPanelObject*) userdata;
01881 self->sendIsTemporary();
01882 }
01883
01884
01885 void LLPanelObject::onCommitPhantom( LLUICtrl* ctrl, void* userdata )
01886 {
01887 LLPanelObject* self = (LLPanelObject*) userdata;
01888 self->sendIsPhantom();
01889 }
01890
01891
01892 void LLPanelObject::onCommitCastShadows( LLUICtrl* ctrl, void* userdata )
01893 {
01894 LLPanelObject* self = (LLPanelObject*) userdata;
01895 self->sendCastShadows();
01896 }
01897
01898
01899
01900 void LLPanelObject::onSelectSculpt(LLUICtrl* ctrl, void* userdata)
01901 {
01902 LLPanelObject* self = (LLPanelObject*) userdata;
01903
01904 LLTextureCtrl* mTextureCtrl = gUICtrlFactory->getTexturePickerByName(self, "sculpt texture control");
01905
01906 if (mTextureCtrl)
01907 {
01908 self->mSculptTextureRevert = mTextureCtrl->getImageAssetID();
01909 }
01910
01911 self->sendSculpt();
01912 }
01913
01914
01915 void LLPanelObject::onCommitSculpt( LLUICtrl* ctrl, void* userdata )
01916 {
01917 LLPanelObject* self = (LLPanelObject*) userdata;
01918
01919 self->sendSculpt();
01920 }
01921
01922
01923 BOOL LLPanelObject::onDropSculpt(LLUICtrl*, LLInventoryItem* item, void* userdata)
01924 {
01925 LLPanelObject* self = (LLPanelObject*) userdata;
01926
01927 LLTextureCtrl* mTextureCtrl = gUICtrlFactory->getTexturePickerByName(self, "sculpt texture control");
01928
01929 if (mTextureCtrl)
01930 {
01931 LLUUID asset = item->getAssetUUID();
01932
01933 mTextureCtrl->setImageAssetID(asset);
01934 self->mSculptTextureRevert = asset;
01935 }
01936
01937 return TRUE;
01938 }
01939
01940
01941
01942 void LLPanelObject::onCancelSculpt(LLUICtrl* ctrl, void* userdata)
01943 {
01944 LLPanelObject* self = (LLPanelObject*) userdata;
01945
01946 LLTextureCtrl* mTextureCtrl = gUICtrlFactory->getTexturePickerByName(self,"sculpt texture control");
01947 if(!mTextureCtrl)
01948 return;
01949
01950 mTextureCtrl->setImageAssetID(self->mSculptTextureRevert);
01951
01952 self->sendSculpt();
01953 }
01954
01955
01956 void LLPanelObject::onCommitSculptType(LLUICtrl *ctrl, void* userdata)
01957 {
01958 LLPanelObject* self = (LLPanelObject*) userdata;
01959
01960 self->sendSculpt();
01961 }