diff options
author | McCabe Maxsted | 2010-04-30 04:43:58 -0700 |
---|---|---|
committer | Jacek Antonelli | 2010-06-19 02:43:28 -0500 |
commit | b9e1ca3150cb9553bfbb7a15c90761e9a400f6b9 (patch) | |
tree | 2a99be246f51f7ba57f39857f89f7c6a2255c8fc /linden/indra/newview | |
parent | Clarified the simulator version change chat message with some text (diff) | |
download | meta-impy-b9e1ca3150cb9553bfbb7a15c90761e9a400f6b9.zip meta-impy-b9e1ca3150cb9553bfbb7a15c90761e9a400f6b9.tar.gz meta-impy-b9e1ca3150cb9553bfbb7a15c90761e9a400f6b9.tar.bz2 meta-impy-b9e1ca3150cb9553bfbb7a15c90761e9a400f6b9.tar.xz |
Applied patch for SNOW-586 by Thickbrick Sleaford: Add option to align textures across (planar-mapped, co-planar) faces
Was accidentally left out of a rebase
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/llface.cpp | 66 | ||||
-rw-r--r-- | linden/indra/newview/llface.h | 3 | ||||
-rw-r--r-- | linden/indra/newview/llpanelface.cpp | 161 | ||||
-rw-r--r-- | linden/indra/newview/llpanelface.h | 1 | ||||
-rw-r--r-- | linden/indra/newview/skins/default/xui/en-us/floater_tools.xml | 4 |
5 files changed, 233 insertions, 2 deletions
diff --git a/linden/indra/newview/llface.cpp b/linden/indra/newview/llface.cpp index dab1dac..aa8cd15 100644 --- a/linden/indra/newview/llface.cpp +++ b/linden/indra/newview/llface.cpp | |||
@@ -801,6 +801,72 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position, | |||
801 | return tc; | 801 | return tc; |
802 | } | 802 | } |
803 | 803 | ||
804 | // Returns scale compared to default texgen, and face orientation as calculated | ||
805 | // by planarProjection(). This is needed to match planar texgen parameters. | ||
806 | void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_pos, F32* scale) const | ||
807 | { | ||
808 | const LLVolumeFace& vf = getViewerObject()->getVolume()->getVolumeFace(mTEOffset); | ||
809 | LLVector3 normal = vf.mVertices[0].mNormal; | ||
810 | LLVector3 binormal = vf.mVertices[0].mBinormal; | ||
811 | LLVector2 projected_binormal; | ||
812 | planarProjection(projected_binormal, normal, vf.mCenter, binormal); | ||
813 | projected_binormal -= LLVector2(0.5f, 0.5f); // this normally happens in xform() | ||
814 | *scale = projected_binormal.length(); | ||
815 | // rotate binormal to match what planarProjection() thinks it is, | ||
816 | // then find face's rotation from normal and rotated binormal: | ||
817 | projected_binormal.normalize(); | ||
818 | F32 ang = acos(projected_binormal.mV[VY]); | ||
819 | ang = (projected_binormal.mV[VX] < 0.f) ? -ang : ang; | ||
820 | binormal.rotVec(ang, normal); | ||
821 | LLQuaternion local_rot( binormal % normal, binormal, normal ); | ||
822 | *face_rot = local_rot * mXform->getWorldRotation(); | ||
823 | *face_pos = mXform->getWorldPosition(); | ||
824 | } | ||
825 | |||
826 | // Returns the necessary texture transform to align this face's TE to align_to's TE | ||
827 | bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offset, | ||
828 | LLVector2* res_st_scale, F32* res_st_rot) const | ||
829 | { | ||
830 | if (!align_to) | ||
831 | { | ||
832 | return false; | ||
833 | } | ||
834 | const LLTextureEntry *orig_tep = align_to->getTextureEntry(); | ||
835 | if ((orig_tep->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR) || | ||
836 | (getTextureEntry()->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR)) | ||
837 | { | ||
838 | return false; | ||
839 | } | ||
840 | |||
841 | LLVector3 orig_pos, this_pos; | ||
842 | LLQuaternion orig_face_rot, this_face_rot; | ||
843 | F32 orig_proj_scale, this_proj_scale; | ||
844 | align_to->getPlanarProjectedParams(&orig_face_rot, &orig_pos, &orig_proj_scale); | ||
845 | getPlanarProjectedParams(&this_face_rot, &this_pos, &this_proj_scale); | ||
846 | |||
847 | // The rotation of "this face's" texture: | ||
848 | LLQuaternion orig_st_rot = LLQuaternion(orig_tep->getRotation(), LLVector3::z_axis) * orig_face_rot; | ||
849 | LLQuaternion this_st_rot = orig_st_rot * ~this_face_rot; | ||
850 | F32 x_ang, y_ang, z_ang; | ||
851 | this_st_rot.getEulerAngles(&x_ang, &y_ang, &z_ang); | ||
852 | *res_st_rot = z_ang; | ||
853 | |||
854 | // Offset and scale of "this face's" texture: | ||
855 | LLVector3 centers_dist = (this_pos - orig_pos) * ~orig_st_rot; | ||
856 | LLVector3 st_scale(orig_tep->mScaleS, orig_tep->mScaleT, 1.f); | ||
857 | st_scale *= orig_proj_scale; | ||
858 | centers_dist.scaleVec(st_scale); | ||
859 | LLVector2 orig_st_offset(orig_tep->mOffsetS, orig_tep->mOffsetT); | ||
860 | |||
861 | *res_st_offset = orig_st_offset + (LLVector2)centers_dist; | ||
862 | res_st_offset->mV[VX] -= (S32)res_st_offset->mV[VX]; | ||
863 | res_st_offset->mV[VY] -= (S32)res_st_offset->mV[VY]; | ||
864 | |||
865 | st_scale /= this_proj_scale; | ||
866 | *res_st_scale = (LLVector2)st_scale; | ||
867 | return true; | ||
868 | } | ||
869 | |||
804 | void LLFace::updateRebuildFlags() | 870 | void LLFace::updateRebuildFlags() |
805 | { | 871 | { |
806 | if (!mDrawablep->isState(LLDrawable::REBUILD_VOLUME)) | 872 | if (!mDrawablep->isState(LLDrawable::REBUILD_VOLUME)) |
diff --git a/linden/indra/newview/llface.h b/linden/indra/newview/llface.h index 5e422b4..4893e82 100644 --- a/linden/indra/newview/llface.h +++ b/linden/indra/newview/llface.h | |||
@@ -93,6 +93,9 @@ public: | |||
93 | BOOL hasGeometry() const { return mGeomCount > 0; } | 93 | BOOL hasGeometry() const { return mGeomCount > 0; } |
94 | LLVector3 getPositionAgent() const; | 94 | LLVector3 getPositionAgent() const; |
95 | LLVector2 surfaceToTexture(LLVector2 surface_coord, LLVector3 position, LLVector3 normal); | 95 | LLVector2 surfaceToTexture(LLVector2 surface_coord, LLVector3 position, LLVector3 normal); |
96 | void getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_pos, F32* scale) const; | ||
97 | bool calcAlignedPlanarTE(const LLFace* align_to, LLVector2* st_offset, | ||
98 | LLVector2* st_scale, F32* st_rot) const; | ||
96 | 99 | ||
97 | U32 getState() const { return mState; } | 100 | U32 getState() const { return mState; } |
98 | void setState(U32 state) { mState |= state; } | 101 | void setState(U32 state) { mState |= state; } |
diff --git a/linden/indra/newview/llpanelface.cpp b/linden/indra/newview/llpanelface.cpp index 6ae2ffe..bd9edec 100644 --- a/linden/indra/newview/llpanelface.cpp +++ b/linden/indra/newview/llpanelface.cpp | |||
@@ -48,7 +48,9 @@ | |||
48 | #include "llcheckboxctrl.h" | 48 | #include "llcheckboxctrl.h" |
49 | #include "llcolorswatch.h" | 49 | #include "llcolorswatch.h" |
50 | #include "llcombobox.h" | 50 | #include "llcombobox.h" |
51 | #include "lldrawable.h" | ||
51 | #include "lldrawpoolbump.h" | 52 | #include "lldrawpoolbump.h" |
53 | #include "llface.h" | ||
52 | #include "lllineeditor.h" | 54 | #include "lllineeditor.h" |
53 | #include "llresmgr.h" | 55 | #include "llresmgr.h" |
54 | #include "llselectmgr.h" | 56 | #include "llselectmgr.h" |
@@ -173,6 +175,7 @@ BOOL LLPanelFace::postBuild() | |||
173 | 175 | ||
174 | childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this); | 176 | childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this); |
175 | childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this); | 177 | childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this); |
178 | childSetCommitCallback("checkbox planar align",&LLPanelFace::onCommitPlanarAlign, this); | ||
176 | childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this); | 179 | childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this); |
177 | childSetCommitCallback("checkbox flip s",&LLPanelFace::onCommitTextureInfo, this); | 180 | childSetCommitCallback("checkbox flip s",&LLPanelFace::onCommitTextureInfo, this); |
178 | childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureInfo, this); | 181 | childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureInfo, this); |
@@ -364,6 +367,93 @@ private: | |||
364 | LLPanelFace* mPanel; | 367 | LLPanelFace* mPanel; |
365 | }; | 368 | }; |
366 | 369 | ||
370 | // Functor that aligns a face to mCenterFace | ||
371 | struct LLPanelFaceSetAlignedTEFunctor : public LLSelectedTEFunctor | ||
372 | { | ||
373 | LLPanelFaceSetAlignedTEFunctor(LLPanelFace* panel, LLFace* center_face) : | ||
374 | mPanel(panel), | ||
375 | mCenterFace(center_face) {} | ||
376 | |||
377 | virtual bool apply(LLViewerObject* object, S32 te) | ||
378 | { | ||
379 | LLFace* facep = object->mDrawable->getFace(te); | ||
380 | if (!facep) | ||
381 | { | ||
382 | return true; | ||
383 | } | ||
384 | |||
385 | bool set_aligned = true; | ||
386 | if (facep == mCenterFace) | ||
387 | { | ||
388 | set_aligned = false; | ||
389 | } | ||
390 | if (set_aligned) | ||
391 | { | ||
392 | LLVector2 uv_offset, uv_scale; | ||
393 | F32 uv_rot; | ||
394 | set_aligned = facep->calcAlignedPlanarTE(mCenterFace, &uv_offset, &uv_scale, &uv_rot); | ||
395 | if (set_aligned) | ||
396 | { | ||
397 | object->setTEOffset(te, uv_offset.mV[VX], uv_offset.mV[VY]); | ||
398 | object->setTEScale(te, uv_scale.mV[VX], uv_scale.mV[VY]); | ||
399 | object->setTERotation(te, uv_rot); | ||
400 | } | ||
401 | } | ||
402 | if (!set_aligned) | ||
403 | { | ||
404 | LLPanelFaceSetTEFunctor setfunc(mPanel); | ||
405 | setfunc.apply(object, te); | ||
406 | } | ||
407 | return true; | ||
408 | } | ||
409 | private: | ||
410 | LLPanelFace* mPanel; | ||
411 | LLFace* mCenterFace; | ||
412 | }; | ||
413 | |||
414 | // Functor that tests if a face is aligned to mCenterFace | ||
415 | struct LLPanelFaceGetIsAlignedTEFunctor : public LLSelectedTEFunctor | ||
416 | { | ||
417 | LLPanelFaceGetIsAlignedTEFunctor(LLFace* center_face) : | ||
418 | mCenterFace(center_face) {} | ||
419 | |||
420 | virtual bool apply(LLViewerObject* object, S32 te) | ||
421 | { | ||
422 | LLFace* facep = object->mDrawable->getFace(te); | ||
423 | if (!facep) | ||
424 | { | ||
425 | return false; | ||
426 | } | ||
427 | if (facep == mCenterFace) | ||
428 | { | ||
429 | return true; | ||
430 | } | ||
431 | |||
432 | LLVector2 aligned_st_offset, aligned_st_scale; | ||
433 | F32 aligned_st_rot; | ||
434 | if ( facep->calcAlignedPlanarTE(mCenterFace, &aligned_st_offset, &aligned_st_scale, &aligned_st_rot) ) | ||
435 | { | ||
436 | const LLTextureEntry* tep = facep->getTextureEntry(); | ||
437 | LLVector2 st_offset, st_scale; | ||
438 | tep->getOffset(&st_offset.mV[VX], &st_offset.mV[VY]); | ||
439 | tep->getScale(&st_scale.mV[VX], &st_scale.mV[VY]); | ||
440 | F32 st_rot = tep->getRotation(); | ||
441 | // needs a fuzzy comparison, because of fp errors | ||
442 | if (is_approx_equal_fraction(st_offset.mV[VX], aligned_st_offset.mV[VX], 14) && | ||
443 | is_approx_equal_fraction(st_offset.mV[VY], aligned_st_offset.mV[VY], 14) && | ||
444 | is_approx_equal_fraction(st_scale.mV[VX], aligned_st_scale.mV[VX], 14) && | ||
445 | is_approx_equal_fraction(st_scale.mV[VY], aligned_st_scale.mV[VY], 14) && | ||
446 | is_approx_equal_fraction(st_rot, aligned_st_rot, 10)) | ||
447 | { | ||
448 | return true; | ||
449 | } | ||
450 | } | ||
451 | return false; | ||
452 | } | ||
453 | private: | ||
454 | LLFace* mCenterFace; | ||
455 | }; | ||
456 | |||
367 | struct LLPanelFaceSendFunctor : public LLSelectedObjectFunctor | 457 | struct LLPanelFaceSendFunctor : public LLSelectedObjectFunctor |
368 | { | 458 | { |
369 | virtual bool apply(LLViewerObject* object) | 459 | virtual bool apply(LLViewerObject* object) |
@@ -375,8 +465,26 @@ struct LLPanelFaceSendFunctor : public LLSelectedObjectFunctor | |||
375 | 465 | ||
376 | void LLPanelFace::sendTextureInfo() | 466 | void LLPanelFace::sendTextureInfo() |
377 | { | 467 | { |
378 | LLPanelFaceSetTEFunctor setfunc(this); | 468 | if ((bool)childGetValue("checkbox planar align").asBoolean()) |
379 | LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); | 469 | { |
470 | struct f1 : public LLSelectedTEGetFunctor<LLFace *> | ||
471 | { | ||
472 | LLFace* get(LLViewerObject* object, S32 te) | ||
473 | { | ||
474 | return (object->mDrawable) ? object->mDrawable->getFace(te): NULL; | ||
475 | } | ||
476 | } get_last_face_func; | ||
477 | LLFace* last_face; | ||
478 | LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_last_face_func, last_face); | ||
479 | |||
480 | LLPanelFaceSetAlignedTEFunctor setfunc(this, last_face); | ||
481 | LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); | ||
482 | } | ||
483 | else | ||
484 | { | ||
485 | LLPanelFaceSetTEFunctor setfunc(this); | ||
486 | LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); | ||
487 | } | ||
380 | 488 | ||
381 | LLPanelFaceSendFunctor sendfunc; | 489 | LLPanelFaceSendFunctor sendfunc; |
382 | LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc); | 490 | LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc); |
@@ -483,6 +591,43 @@ void LLPanelFace::getState() | |||
483 | } | 591 | } |
484 | } | 592 | } |
485 | 593 | ||
594 | // planar align | ||
595 | bool align_planar = false; | ||
596 | bool identical_planar_aligned = false; | ||
597 | { | ||
598 | LLCheckBoxCtrl* cb_planar_align = getChild<LLCheckBoxCtrl>("checkbox planar align"); | ||
599 | align_planar = (cb_planar_align && cb_planar_align->get()); | ||
600 | struct f1 : public LLSelectedTEGetFunctor<bool> | ||
601 | { | ||
602 | bool get(LLViewerObject* object, S32 face) | ||
603 | { | ||
604 | return (object->getTE(face)->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR); | ||
605 | } | ||
606 | } func; | ||
607 | |||
608 | bool is_planar; | ||
609 | bool texgens_identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, is_planar ); | ||
610 | bool enabled = (editable && texgens_identical && is_planar); | ||
611 | childSetValue("checkbox planar align", align_planar && enabled); | ||
612 | childSetEnabled("checkbox planar align", enabled); | ||
613 | |||
614 | if (align_planar && enabled) | ||
615 | { | ||
616 | struct f2 : public LLSelectedTEGetFunctor<LLFace *> | ||
617 | { | ||
618 | LLFace* get(LLViewerObject* object, S32 te) | ||
619 | { | ||
620 | return (object->mDrawable) ? object->mDrawable->getFace(te): NULL; | ||
621 | } | ||
622 | } get_te_face_func; | ||
623 | LLFace* last_face; | ||
624 | LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, last_face); | ||
625 | LLPanelFaceGetIsAlignedTEFunctor get_is_aligend_func(last_face); | ||
626 | // this will determine if the texture param controls are tentative: | ||
627 | identical_planar_aligned = LLSelectMgr::getInstance()->getSelection()->applyToTEs(&get_is_aligend_func); | ||
628 | } | ||
629 | } | ||
630 | |||
486 | // Texture scale | 631 | // Texture scale |
487 | { | 632 | { |
488 | childSetEnabled("tex scale",editable); | 633 | childSetEnabled("tex scale",editable); |
@@ -496,6 +641,7 @@ void LLPanelFace::getState() | |||
496 | } | 641 | } |
497 | } func; | 642 | } func; |
498 | identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_s ); | 643 | identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_s ); |
644 | identical = align_planar ? identical_planar_aligned : identical; | ||
499 | childSetValue("TexScaleU",editable ? llabs(scale_s) : 0); | 645 | childSetValue("TexScaleU",editable ? llabs(scale_s) : 0); |
500 | childSetTentative("TexScaleU",LLSD((BOOL)(!identical))); | 646 | childSetTentative("TexScaleU",LLSD((BOOL)(!identical))); |
501 | childSetEnabled("TexScaleU",editable); | 647 | childSetEnabled("TexScaleU",editable); |
@@ -514,6 +660,7 @@ void LLPanelFace::getState() | |||
514 | } | 660 | } |
515 | } func; | 661 | } func; |
516 | identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_t ); | 662 | identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_t ); |
663 | identical = align_planar ? identical_planar_aligned : identical; | ||
517 | 664 | ||
518 | childSetValue("TexScaleV",llabs(editable ? llabs(scale_t) : 0)); | 665 | childSetValue("TexScaleV",llabs(editable ? llabs(scale_t) : 0)); |
519 | childSetTentative("TexScaleV",LLSD((BOOL)(!identical))); | 666 | childSetTentative("TexScaleV",LLSD((BOOL)(!identical))); |
@@ -535,6 +682,7 @@ void LLPanelFace::getState() | |||
535 | } | 682 | } |
536 | } func; | 683 | } func; |
537 | identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, offset_s ); | 684 | identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, offset_s ); |
685 | identical = align_planar ? identical_planar_aligned : identical; | ||
538 | childSetValue("TexOffsetU", editable ? offset_s : 0); | 686 | childSetValue("TexOffsetU", editable ? offset_s : 0); |
539 | childSetTentative("TexOffsetU",!identical); | 687 | childSetTentative("TexOffsetU",!identical); |
540 | childSetEnabled("TexOffsetU",editable); | 688 | childSetEnabled("TexOffsetU",editable); |
@@ -550,6 +698,7 @@ void LLPanelFace::getState() | |||
550 | } | 698 | } |
551 | } func; | 699 | } func; |
552 | identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, offset_t ); | 700 | identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, offset_t ); |
701 | identical = align_planar ? identical_planar_aligned : identical; | ||
553 | childSetValue("TexOffsetV", editable ? offset_t : 0); | 702 | childSetValue("TexOffsetV", editable ? offset_t : 0); |
554 | childSetTentative("TexOffsetV",!identical); | 703 | childSetTentative("TexOffsetV",!identical); |
555 | childSetEnabled("TexOffsetV",editable); | 704 | childSetEnabled("TexOffsetV",editable); |
@@ -567,6 +716,7 @@ void LLPanelFace::getState() | |||
567 | } | 716 | } |
568 | } func; | 717 | } func; |
569 | identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, rotation ); | 718 | identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, rotation ); |
719 | identical = align_planar ? identical_planar_aligned : identical; | ||
570 | childSetValue("TexRot", editable ? rotation * RAD_TO_DEG : 0); | 720 | childSetValue("TexRot", editable ? rotation * RAD_TO_DEG : 0); |
571 | childSetTentative("TexRot",!identical); | 721 | childSetTentative("TexRot",!identical); |
572 | childSetEnabled("TexRot",editable); | 722 | childSetEnabled("TexRot",editable); |
@@ -999,6 +1149,13 @@ void LLPanelFace::onClickAutoFix(void* userdata) | |||
999 | } | 1149 | } |
1000 | 1150 | ||
1001 | // static | 1151 | // static |
1152 | void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata) | ||
1153 | { | ||
1154 | LLPanelFace* self = (LLPanelFace*) userdata; | ||
1155 | self->getState(); | ||
1156 | } | ||
1157 | |||
1158 | // static | ||
1002 | void LLPanelFace::onClickTextureConstants(void *) | 1159 | void LLPanelFace::onClickTextureConstants(void *) |
1003 | { | 1160 | { |
1004 | LLNotifications::instance().add("ClickTextureConstants"); | 1161 | LLNotifications::instance().add("ClickTextureConstants"); |
diff --git a/linden/indra/newview/llpanelface.h b/linden/indra/newview/llpanelface.h index 33c84c8..8e4d4db 100644 --- a/linden/indra/newview/llpanelface.h +++ b/linden/indra/newview/llpanelface.h | |||
@@ -86,6 +86,7 @@ protected: | |||
86 | static void onCommitShiny( LLUICtrl* ctrl, void* userdata); | 86 | static void onCommitShiny( LLUICtrl* ctrl, void* userdata); |
87 | static void onCommitFullbright( LLUICtrl* ctrl, void* userdata); | 87 | static void onCommitFullbright( LLUICtrl* ctrl, void* userdata); |
88 | static void onCommitGlow( LLUICtrl* ctrl, void *userdata); | 88 | static void onCommitGlow( LLUICtrl* ctrl, void *userdata); |
89 | static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata); | ||
89 | 90 | ||
90 | static void onClickApply(void*); | 91 | static void onClickApply(void*); |
91 | static void onClickAutoFix(void*); | 92 | static void onClickAutoFix(void*); |
diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml b/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml index ce08d4c..78eacf4 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml | |||
@@ -1157,6 +1157,10 @@ | |||
1157 | weave | 1157 | weave |
1158 | </combo_item> | 1158 | </combo_item> |
1159 | </combo_box> | 1159 | </combo_box> |
1160 | <check_box bottom="-148" follows="left|top" font="SansSerifSmall" height="16" | ||
1161 | initial_value="false" enabled="false" label="Align across planar faces" | ||
1162 | left="8" mouse_opaque="true" name="checkbox planar align" width="160" | ||
1163 | tool_tip="When checked, aligns textures on all selected faces to the last selected face. Requires Planar texture mapping." /> | ||
1160 | <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | 1164 | <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" |
1161 | bottom="-158" drop_shadow_visible="true" follows="left|top" | 1165 | bottom="-158" drop_shadow_visible="true" follows="left|top" |
1162 | font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10" | 1166 | font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10" |