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/llpanelface.cpp | |
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 'linden/indra/newview/llpanelface.cpp')
-rw-r--r-- | linden/indra/newview/llpanelface.cpp | 161 |
1 files changed, 159 insertions, 2 deletions
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"); |