aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmath
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:45:44 -0500
committerJacek Antonelli2008-08-15 23:45:44 -0500
commitacfdcf2b1deeb04698174c78e8cb22b093445bb1 (patch)
tree811293650bcf81d01ea7c54d7c2cf263110aa329 /linden/indra/llmath
parentSecond Life viewer sources 1.20.2 (diff)
downloadmeta-impy-acfdcf2b1deeb04698174c78e8cb22b093445bb1.zip
meta-impy-acfdcf2b1deeb04698174c78e8cb22b093445bb1.tar.gz
meta-impy-acfdcf2b1deeb04698174c78e8cb22b093445bb1.tar.bz2
meta-impy-acfdcf2b1deeb04698174c78e8cb22b093445bb1.tar.xz
Second Life viewer sources 1.20.3
Diffstat (limited to '')
-rw-r--r--linden/indra/llmath/llvolume.cpp467
-rw-r--r--linden/indra/llmath/llvolume.h59
-rw-r--r--linden/indra/llmath/llvolumemgr.cpp132
-rw-r--r--linden/indra/llmath/llvolumemgr.h46
4 files changed, 301 insertions, 403 deletions
diff --git a/linden/indra/llmath/llvolume.cpp b/linden/indra/llmath/llvolume.cpp
index 9c19220..527100a 100644
--- a/linden/indra/llmath/llvolume.cpp
+++ b/linden/indra/llmath/llvolume.cpp
@@ -34,6 +34,7 @@
34#include <set> 34#include <set>
35 35
36#include "llerror.h" 36#include "llerror.h"
37#include "llmemtype.h"
37 38
38#include "llvolumemgr.h" 39#include "llvolumemgr.h"
39#include "v2math.h" 40#include "v2math.h"
@@ -155,6 +156,8 @@ BOOL LLTriangleLineSegmentIntersect( const LLVector3& pt1, const LLVector3& pt2,
155 156
156LLProfile::Face* LLProfile::addCap(S16 faceID) 157LLProfile::Face* LLProfile::addCap(S16 faceID)
157{ 158{
159 LLMemType m1(LLMemType::MTYPE_VOLUME);
160
158 Face *face = vector_append(mFaces, 1); 161 Face *face = vector_append(mFaces, 1);
159 162
160 face->mIndex = 0; 163 face->mIndex = 0;
@@ -167,6 +170,8 @@ LLProfile::Face* LLProfile::addCap(S16 faceID)
167 170
168LLProfile::Face* LLProfile::addFace(S32 i, S32 count, F32 scaleU, S16 faceID, BOOL flat) 171LLProfile::Face* LLProfile::addFace(S32 i, S32 count, F32 scaleU, S16 faceID, BOOL flat)
169{ 172{
173 LLMemType m1(LLMemType::MTYPE_VOLUME);
174
170 Face *face = vector_append(mFaces, 1); 175 Face *face = vector_append(mFaces, 1);
171 176
172 face->mIndex = i; 177 face->mIndex = i;
@@ -182,8 +187,10 @@ LLProfile::Face* LLProfile::addFace(S32 i, S32 count, F32 scaleU, S16 faceID, BO
182// What is the bevel parameter used for? - DJS 04/05/02 187// What is the bevel parameter used for? - DJS 04/05/02
183// Bevel parameter is currently unused but presumedly would support 188// Bevel parameter is currently unused but presumedly would support
184// filleted and chamfered corners 189// filleted and chamfered corners
185void LLProfile::genNGon(S32 sides, F32 offset, F32 bevel, F32 ang_scale, S32 split) 190void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F32 bevel, F32 ang_scale, S32 split)
186{ 191{
192 LLMemType m1(LLMemType::MTYPE_VOLUME);
193
187 // Generate an n-sided "circular" path. 194 // Generate an n-sided "circular" path.
188 // 0 is (1,0), and we go counter-clockwise along a circular path from there. 195 // 0 is (1,0), and we go counter-clockwise along a circular path from there.
189 const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f }; 196 const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f };
@@ -194,8 +201,8 @@ void LLProfile::genNGon(S32 sides, F32 offset, F32 bevel, F32 ang_scale, S32 spl
194 mMaxX = 0.f; 201 mMaxX = 0.f;
195 mMinX = 0.f; 202 mMinX = 0.f;
196 203
197 F32 begin = mParams.getBegin(); 204 F32 begin = params.getBegin();
198 F32 end = mParams.getEnd(); 205 F32 end = params.getEnd();
199 206
200 t_step = 1.0f / sides; 207 t_step = 1.0f / sides;
201 ang_step = 2.0f*F_PI*t_step*ang_scale; 208 ang_step = 2.0f*F_PI*t_step*ang_scale;
@@ -311,7 +318,7 @@ void LLProfile::genNGon(S32 sides, F32 offset, F32 bevel, F32 ang_scale, S32 spl
311 mConcave = FALSE; 318 mConcave = FALSE;
312 } 319 }
313 mOpen = TRUE; 320 mOpen = TRUE;
314 if (!isHollow()) 321 if (params.getHollow() <= 0)
315 { 322 {
316 // put center point if not hollow. 323 // put center point if not hollow.
317 mProfile.push_back(LLVector3(0,0,0)); 324 mProfile.push_back(LLVector3(0,0,0));
@@ -327,7 +334,7 @@ void LLProfile::genNGon(S32 sides, F32 offset, F32 bevel, F32 ang_scale, S32 spl
327 mTotal = mProfile.size(); 334 mTotal = mProfile.size();
328} 335}
329 336
330void LLProfile::genNormals() 337void LLProfile::genNormals(const LLProfileParams& params)
331{ 338{
332 S32 count = mProfile.size(); 339 S32 count = mProfile.size();
333 340
@@ -347,8 +354,7 @@ void LLProfile::genNormals()
347 354
348 LLVector2 pt0,pt1; 355 LLVector2 pt0,pt1;
349 356
350 BOOL hollow; 357 BOOL hollow = (params.getHollow() > 0);
351 hollow = isHollow();
352 358
353 S32 i0, i1, i2, i3, i4; 359 S32 i0, i1, i2, i3, i4;
354 360
@@ -428,7 +434,7 @@ void LLProfile::genNormals()
428// Hollow is percent of the original bounding box, not of this particular 434// Hollow is percent of the original bounding box, not of this particular
429// profile's geometry. Thus, a swept triangle needs lower hollow values than 435// profile's geometry. Thus, a swept triangle needs lower hollow values than
430// a swept square. 436// a swept square.
431LLProfile::Face* LLProfile::addHole(BOOL flat, F32 sides, F32 offset, F32 box_hollow, F32 ang_scale, S32 split) 437LLProfile::Face* LLProfile::addHole(const LLProfileParams& params, BOOL flat, F32 sides, F32 offset, F32 box_hollow, F32 ang_scale, S32 split)
432{ 438{
433 // Note that addHole will NOT work for non-"circular" profiles, if we ever decide to use them. 439 // Note that addHole will NOT work for non-"circular" profiles, if we ever decide to use them.
434 440
@@ -436,11 +442,12 @@ LLProfile::Face* LLProfile::addHole(BOOL flat, F32 sides, F32 offset, F32 box_ho
436 mTotalOut = mTotal; 442 mTotalOut = mTotal;
437 443
438 // Why is the "bevel" parameter -1? DJS 04/05/02 444 // Why is the "bevel" parameter -1? DJS 04/05/02
439 genNGon(llfloor(sides),offset,-1, ang_scale, split); 445 genNGon(params, llfloor(sides),offset,-1, ang_scale, split);
440 446
441 Face *face = addFace(mTotalOut, mTotal-mTotalOut,0,LL_FACE_INNER_SIDE, flat); 447 Face *face = addFace(mTotalOut, mTotal-mTotalOut,0,LL_FACE_INNER_SIDE, flat);
442 448
443 LLVector3 pt[128]; 449 std::vector<LLVector3> pt;
450 pt.resize(mTotal) ;
444 451
445 for (S32 i=mTotalOut;i<mTotal;i++) 452 for (S32 i=mTotalOut;i<mTotal;i++)
446 { 453 {
@@ -489,8 +496,10 @@ S32 sculpt_sides(F32 detail)
489} 496}
490 497
491 498
492BOOL LLProfile::generate(BOOL path_open,F32 detail, S32 split, BOOL is_sculpted) 499BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detail, S32 split, BOOL is_sculpted)
493{ 500{
501 LLMemType m1(LLMemType::MTYPE_VOLUME);
502
494 if ((!mDirty) && (!is_sculpted)) 503 if ((!mDirty) && (!is_sculpted))
495 { 504 {
496 return FALSE; 505 return FALSE;
@@ -508,9 +517,9 @@ BOOL LLProfile::generate(BOOL path_open,F32 detail, S32 split, BOOL is_sculpted)
508 517
509 // Generate the face data 518 // Generate the face data
510 S32 i; 519 S32 i;
511 F32 begin = mParams.getBegin(); 520 F32 begin = params.getBegin();
512 F32 end = mParams.getEnd(); 521 F32 end = params.getEnd();
513 F32 hollow = mParams.getHollow(); 522 F32 hollow = params.getHollow();
514 523
515 // Quick validation to eliminate some server crashes. 524 // Quick validation to eliminate some server crashes.
516 if (begin > end - 0.01f) 525 if (begin > end - 0.01f)
@@ -521,11 +530,11 @@ BOOL LLProfile::generate(BOOL path_open,F32 detail, S32 split, BOOL is_sculpted)
521 530
522 S32 face_num = 0; 531 S32 face_num = 0;
523 532
524 switch (mParams.getCurveType() & LL_PCODE_PROFILE_MASK) 533 switch (params.getCurveType() & LL_PCODE_PROFILE_MASK)
525 { 534 {
526 case LL_PCODE_PROFILE_SQUARE: 535 case LL_PCODE_PROFILE_SQUARE:
527 { 536 {
528 genNGon(4,-0.375, 0, 1, split); 537 genNGon(params, 4,-0.375, 0, 1, split);
529 if (path_open) 538 if (path_open)
530 { 539 {
531 addCap (LL_FACE_PATH_BEGIN); 540 addCap (LL_FACE_PATH_BEGIN);
@@ -544,20 +553,20 @@ BOOL LLProfile::generate(BOOL path_open,F32 detail, S32 split, BOOL is_sculpted)
544 553
545 if (hollow) 554 if (hollow)
546 { 555 {
547 switch (mParams.getCurveType() & LL_PCODE_HOLE_MASK) 556 switch (params.getCurveType() & LL_PCODE_HOLE_MASK)
548 { 557 {
549 case LL_PCODE_HOLE_TRIANGLE: 558 case LL_PCODE_HOLE_TRIANGLE:
550 // This offset is not correct, but we can't change it now... DK 11/17/04 559 // This offset is not correct, but we can't change it now... DK 11/17/04
551 addHole(TRUE, 3, -0.375f, hollow, 1.f, split); 560 addHole(params, TRUE, 3, -0.375f, hollow, 1.f, split);
552 break; 561 break;
553 case LL_PCODE_HOLE_CIRCLE: 562 case LL_PCODE_HOLE_CIRCLE:
554 // TODO: Compute actual detail levels for cubes 563 // TODO: Compute actual detail levels for cubes
555 addHole(FALSE, MIN_DETAIL_FACES * detail, -0.375f, hollow, 1.f); 564 addHole(params, FALSE, MIN_DETAIL_FACES * detail, -0.375f, hollow, 1.f);
556 break; 565 break;
557 case LL_PCODE_HOLE_SAME: 566 case LL_PCODE_HOLE_SAME:
558 case LL_PCODE_HOLE_SQUARE: 567 case LL_PCODE_HOLE_SQUARE:
559 default: 568 default:
560 addHole(TRUE, 4, -0.375f, hollow, 1.f, split); 569 addHole(params, TRUE, 4, -0.375f, hollow, 1.f, split);
561 break; 570 break;
562 } 571 }
563 } 572 }
@@ -571,7 +580,7 @@ BOOL LLProfile::generate(BOOL path_open,F32 detail, S32 split, BOOL is_sculpted)
571 case LL_PCODE_PROFILE_RIGHTTRI: 580 case LL_PCODE_PROFILE_RIGHTTRI:
572 case LL_PCODE_PROFILE_EQUALTRI: 581 case LL_PCODE_PROFILE_EQUALTRI:
573 { 582 {
574 genNGon(3,0, 0, 1, split); 583 genNGon(params, 3,0, 0, 1, split);
575 for (i = 0; i <(S32) mProfile.size(); i++) 584 for (i = 0; i <(S32) mProfile.size(); i++)
576 { 585 {
577 // Scale by 3 to generate proper tex coords. 586 // Scale by 3 to generate proper tex coords.
@@ -593,19 +602,19 @@ BOOL LLProfile::generate(BOOL path_open,F32 detail, S32 split, BOOL is_sculpted)
593 // because the triangle doesn't fill the bounding box. 602 // because the triangle doesn't fill the bounding box.
594 F32 triangle_hollow = hollow / 2.f; 603 F32 triangle_hollow = hollow / 2.f;
595 604
596 switch (mParams.getCurveType() & LL_PCODE_HOLE_MASK) 605 switch (params.getCurveType() & LL_PCODE_HOLE_MASK)
597 { 606 {
598 case LL_PCODE_HOLE_CIRCLE: 607 case LL_PCODE_HOLE_CIRCLE:
599 // TODO: Actually generate level of detail for triangles 608 // TODO: Actually generate level of detail for triangles
600 addHole(FALSE, MIN_DETAIL_FACES * detail, 0, triangle_hollow, 1.f); 609 addHole(params, FALSE, MIN_DETAIL_FACES * detail, 0, triangle_hollow, 1.f);
601 break; 610 break;
602 case LL_PCODE_HOLE_SQUARE: 611 case LL_PCODE_HOLE_SQUARE:
603 addHole(TRUE, 4, 0, triangle_hollow, 1.f, split); 612 addHole(params, TRUE, 4, 0, triangle_hollow, 1.f, split);
604 break; 613 break;
605 case LL_PCODE_HOLE_SAME: 614 case LL_PCODE_HOLE_SAME:
606 case LL_PCODE_HOLE_TRIANGLE: 615 case LL_PCODE_HOLE_TRIANGLE:
607 default: 616 default:
608 addHole(TRUE, 3, 0, triangle_hollow, 1.f, split); 617 addHole(params, TRUE, 3, 0, triangle_hollow, 1.f, split);
609 break; 618 break;
610 } 619 }
611 } 620 }
@@ -619,7 +628,7 @@ BOOL LLProfile::generate(BOOL path_open,F32 detail, S32 split, BOOL is_sculpted)
619 F32 circle_detail = MIN_DETAIL_FACES * detail; 628 F32 circle_detail = MIN_DETAIL_FACES * detail;
620 if (hollow) 629 if (hollow)
621 { 630 {
622 hole_type = mParams.getCurveType() & LL_PCODE_HOLE_MASK; 631 hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK;
623 if (hole_type == LL_PCODE_HOLE_SQUARE) 632 if (hole_type == LL_PCODE_HOLE_SQUARE)
624 { 633 {
625 // Snap to the next multiple of four sides, 634 // Snap to the next multiple of four sides,
@@ -633,7 +642,7 @@ BOOL LLProfile::generate(BOOL path_open,F32 detail, S32 split, BOOL is_sculpted)
633 if (is_sculpted) 642 if (is_sculpted)
634 sides = sculpt_sides(detail); 643 sides = sculpt_sides(detail);
635 644
636 genNGon(sides); 645 genNGon(params, sides);
637 646
638 if (path_open) 647 if (path_open)
639 { 648 {
@@ -654,15 +663,15 @@ BOOL LLProfile::generate(BOOL path_open,F32 detail, S32 split, BOOL is_sculpted)
654 switch (hole_type) 663 switch (hole_type)
655 { 664 {
656 case LL_PCODE_HOLE_SQUARE: 665 case LL_PCODE_HOLE_SQUARE:
657 addHole(TRUE, 4, 0, hollow, 1.f, split); 666 addHole(params, TRUE, 4, 0, hollow, 1.f, split);
658 break; 667 break;
659 case LL_PCODE_HOLE_TRIANGLE: 668 case LL_PCODE_HOLE_TRIANGLE:
660 addHole(TRUE, 3, 0, hollow, 1.f, split); 669 addHole(params, TRUE, 3, 0, hollow, 1.f, split);
661 break; 670 break;
662 case LL_PCODE_HOLE_CIRCLE: 671 case LL_PCODE_HOLE_CIRCLE:
663 case LL_PCODE_HOLE_SAME: 672 case LL_PCODE_HOLE_SAME:
664 default: 673 default:
665 addHole(FALSE, circle_detail, 0, hollow, 1.f); 674 addHole(params, FALSE, circle_detail, 0, hollow, 1.f);
666 break; 675 break;
667 } 676 }
668 } 677 }
@@ -677,7 +686,7 @@ BOOL LLProfile::generate(BOOL path_open,F32 detail, S32 split, BOOL is_sculpted)
677 F32 circle_detail = MIN_DETAIL_FACES * detail * 0.5f; 686 F32 circle_detail = MIN_DETAIL_FACES * detail * 0.5f;
678 if (hollow) 687 if (hollow)
679 { 688 {
680 hole_type = mParams.getCurveType() & LL_PCODE_HOLE_MASK; 689 hole_type = params.getCurveType() & LL_PCODE_HOLE_MASK;
681 if (hole_type == LL_PCODE_HOLE_SQUARE) 690 if (hole_type == LL_PCODE_HOLE_SQUARE)
682 { 691 {
683 // Snap to the next multiple of four sides (div 2), 692 // Snap to the next multiple of four sides (div 2),
@@ -685,12 +694,12 @@ BOOL LLProfile::generate(BOOL path_open,F32 detail, S32 split, BOOL is_sculpted)
685 circle_detail = llceil(circle_detail / 2.0f) * 2.0f; 694 circle_detail = llceil(circle_detail / 2.0f) * 2.0f;
686 } 695 }
687 } 696 }
688 genNGon(llfloor(circle_detail), 0.5f, 0.f, 0.5f); 697 genNGon(params, llfloor(circle_detail), 0.5f, 0.f, 0.5f);
689 if (path_open) 698 if (path_open)
690 { 699 {
691 addCap(LL_FACE_PATH_BEGIN); 700 addCap(LL_FACE_PATH_BEGIN);
692 } 701 }
693 if (mOpen && !mParams.getHollow()) 702 if (mOpen && !params.getHollow())
694 { 703 {
695 addFace(0,mTotal-1,0,LL_FACE_OUTER_SIDE_0, FALSE); 704 addFace(0,mTotal-1,0,LL_FACE_OUTER_SIDE_0, FALSE);
696 } 705 }
@@ -704,21 +713,21 @@ BOOL LLProfile::generate(BOOL path_open,F32 detail, S32 split, BOOL is_sculpted)
704 switch (hole_type) 713 switch (hole_type)
705 { 714 {
706 case LL_PCODE_HOLE_SQUARE: 715 case LL_PCODE_HOLE_SQUARE:
707 addHole(TRUE, 2, 0.5f, hollow, 0.5f, split); 716 addHole(params, TRUE, 2, 0.5f, hollow, 0.5f, split);
708 break; 717 break;
709 case LL_PCODE_HOLE_TRIANGLE: 718 case LL_PCODE_HOLE_TRIANGLE:
710 addHole(TRUE, 3, 0.5f, hollow, 0.5f, split); 719 addHole(params, TRUE, 3, 0.5f, hollow, 0.5f, split);
711 break; 720 break;
712 case LL_PCODE_HOLE_CIRCLE: 721 case LL_PCODE_HOLE_CIRCLE:
713 case LL_PCODE_HOLE_SAME: 722 case LL_PCODE_HOLE_SAME:
714 default: 723 default:
715 addHole(FALSE, circle_detail, 0.5f, hollow, 0.5f); 724 addHole(params, FALSE, circle_detail, 0.5f, hollow, 0.5f);
716 break; 725 break;
717 } 726 }
718 } 727 }
719 728
720 // Special case for openness of sphere 729 // Special case for openness of sphere
721 if ((mParams.getEnd() - mParams.getBegin()) < 1.f) 730 if ((params.getEnd() - params.getBegin()) < 1.f)
722 { 731 {
723 mOpen = TRUE; 732 mOpen = TRUE;
724 } 733 }
@@ -731,7 +740,7 @@ BOOL LLProfile::generate(BOOL path_open,F32 detail, S32 split, BOOL is_sculpted)
731 } 740 }
732 break; 741 break;
733 default: 742 default:
734 llerrs << "Unknown profile: getCurveType()=" << mParams.getCurveType() << llendl; 743 llerrs << "Unknown profile: getCurveType()=" << params.getCurveType() << llendl;
735 break; 744 break;
736 }; 745 };
737 746
@@ -754,7 +763,7 @@ BOOL LLProfile::generate(BOOL path_open,F32 detail, S32 split, BOOL is_sculpted)
754 } 763 }
755 } 764 }
756 765
757 //genNormals(); 766 //genNormals(params);
758 767
759 return TRUE; 768 return TRUE;
760} 769}
@@ -763,6 +772,8 @@ BOOL LLProfile::generate(BOOL path_open,F32 detail, S32 split, BOOL is_sculpted)
763 772
764BOOL LLProfileParams::importFile(FILE *fp) 773BOOL LLProfileParams::importFile(FILE *fp)
765{ 774{
775 LLMemType m1(LLMemType::MTYPE_VOLUME);
776
766 const S32 BUFSIZE = 16384; 777 const S32 BUFSIZE = 16384;
767 char buffer[BUFSIZE]; /* Flawfinder: ignore */ 778 char buffer[BUFSIZE]; /* Flawfinder: ignore */
768 // *NOTE: changing the size or type of these buffers will require 779 // *NOTE: changing the size or type of these buffers will require
@@ -838,6 +849,8 @@ BOOL LLProfileParams::exportFile(FILE *fp) const
838 849
839BOOL LLProfileParams::importLegacyStream(std::istream& input_stream) 850BOOL LLProfileParams::importLegacyStream(std::istream& input_stream)
840{ 851{
852 LLMemType m1(LLMemType::MTYPE_VOLUME);
853
841 const S32 BUFSIZE = 16384; 854 const S32 BUFSIZE = 16384;
842 char buffer[BUFSIZE]; /* Flawfinder: ignore */ 855 char buffer[BUFSIZE]; /* Flawfinder: ignore */
843 // *NOTE: changing the size or type of these buffers will require 856 // *NOTE: changing the size or type of these buffers will require
@@ -929,6 +942,7 @@ bool LLProfileParams::fromLLSD(LLSD& sd)
929 942
930void LLProfileParams::copyParams(const LLProfileParams &params) 943void LLProfileParams::copyParams(const LLProfileParams &params)
931{ 944{
945 LLMemType m1(LLMemType::MTYPE_VOLUME);
932 setCurveType(params.getCurveType()); 946 setCurveType(params.getCurveType());
933 setBegin(params.getBegin()); 947 setBegin(params.getBegin());
934 setEnd(params.getEnd()); 948 setEnd(params.getEnd());
@@ -940,22 +954,22 @@ LLPath::~LLPath()
940{ 954{
941} 955}
942 956
943void LLPath::genNGon(S32 sides, F32 startOff, F32 end_scale, F32 twist_scale) 957void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale)
944{ 958{
945 // Generates a circular path, starting at (1, 0, 0), counterclockwise along the xz plane. 959 // Generates a circular path, starting at (1, 0, 0), counterclockwise along the xz plane.
946 const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f }; 960 const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f };
947 961
948 F32 revolutions = mParams.getRevolutions(); 962 F32 revolutions = params.getRevolutions();
949 F32 skew = mParams.getSkew(); 963 F32 skew = params.getSkew();
950 F32 skew_mag = fabs(skew); 964 F32 skew_mag = fabs(skew);
951 F32 hole_x = mParams.getScaleX() * (1.0f - skew_mag); 965 F32 hole_x = params.getScaleX() * (1.0f - skew_mag);
952 F32 hole_y = mParams.getScaleY(); 966 F32 hole_y = params.getScaleY();
953 967
954 // Calculate taper begin/end for x,y (Negative means taper the beginning) 968 // Calculate taper begin/end for x,y (Negative means taper the beginning)
955 F32 taper_x_begin = 1.0f; 969 F32 taper_x_begin = 1.0f;
956 F32 taper_x_end = 1.0f - mParams.getTaperX(); 970 F32 taper_x_end = 1.0f - params.getTaperX();
957 F32 taper_y_begin = 1.0f; 971 F32 taper_y_begin = 1.0f;
958 F32 taper_y_end = 1.0f - mParams.getTaperY(); 972 F32 taper_y_end = 1.0f - params.getTaperY();
959 973
960 if ( taper_x_end > 1.0f ) 974 if ( taper_x_end > 1.0f )
961 { 975 {
@@ -983,7 +997,7 @@ void LLPath::genNGon(S32 sides, F32 startOff, F32 end_scale, F32 twist_scale)
983 // Now check the radius offset to calculate the start,end radius. (Negative means 997 // Now check the radius offset to calculate the start,end radius. (Negative means
984 // decrease the start radius instead). 998 // decrease the start radius instead).
985 F32 radius_end = radius_start; 999 F32 radius_end = radius_start;
986 F32 radius_offset = mParams.getRadiusOffset(); 1000 F32 radius_offset = params.getRadiusOffset();
987 if (radius_offset < 0.f) 1001 if (radius_offset < 0.f)
988 { 1002 {
989 radius_start *= 1.f + radius_offset; 1003 radius_start *= 1.f + radius_offset;
@@ -994,7 +1008,7 @@ void LLPath::genNGon(S32 sides, F32 startOff, F32 end_scale, F32 twist_scale)
994 } 1008 }
995 1009
996 // Is the path NOT a closed loop? 1010 // Is the path NOT a closed loop?
997 mOpen = ( (mParams.getEnd()*end_scale - mParams.getBegin() < 1.0f) || 1011 mOpen = ( (params.getEnd()*end_scale - params.getBegin() < 1.0f) ||
998 (skew_mag > 0.001f) || 1012 (skew_mag > 0.001f) ||
999 (fabs(taper_x_end - taper_x_begin) > 0.001f) || 1013 (fabs(taper_x_end - taper_x_begin) > 0.001f) ||
1000 (fabs(taper_y_end - taper_y_begin) > 0.001f) || 1014 (fabs(taper_y_end - taper_y_begin) > 0.001f) ||
@@ -1005,22 +1019,22 @@ void LLPath::genNGon(S32 sides, F32 startOff, F32 end_scale, F32 twist_scale)
1005 PathPt *pt; 1019 PathPt *pt;
1006 LLVector3 path_axis (1.f, 0.f, 0.f); 1020 LLVector3 path_axis (1.f, 0.f, 0.f);
1007 //LLVector3 twist_axis(0.f, 0.f, 1.f); 1021 //LLVector3 twist_axis(0.f, 0.f, 1.f);
1008 F32 twist_begin = mParams.getTwistBegin() * twist_scale; 1022 F32 twist_begin = params.getTwistBegin() * twist_scale;
1009 F32 twist_end = mParams.getTwist() * twist_scale; 1023 F32 twist_end = params.getTwist() * twist_scale;
1010 1024
1011 // We run through this once before the main loop, to make sure 1025 // We run through this once before the main loop, to make sure
1012 // the path begins at the correct cut. 1026 // the path begins at the correct cut.
1013 F32 step= 1.0f / sides; 1027 F32 step= 1.0f / sides;
1014 F32 t = mParams.getBegin(); 1028 F32 t = params.getBegin();
1015 pt = vector_append(mPath, 1); 1029 pt = vector_append(mPath, 1);
1016 ang = 2.0f*F_PI*revolutions * t; 1030 ang = 2.0f*F_PI*revolutions * t;
1017 s = sin(ang)*lerp(radius_start, radius_end, t); 1031 s = sin(ang)*lerp(radius_start, radius_end, t);
1018 c = cos(ang)*lerp(radius_start, radius_end, t); 1032 c = cos(ang)*lerp(radius_start, radius_end, t);
1019 1033
1020 1034
1021 pt->mPos.setVec(0 + lerp(0,mParams.getShear().mV[0],s) 1035 pt->mPos.setVec(0 + lerp(0,params.getShear().mV[0],s)
1022 + lerp(-skew ,skew, t) * 0.5f, 1036 + lerp(-skew ,skew, t) * 0.5f,
1023 c + lerp(0,mParams.getShear().mV[1],s), 1037 c + lerp(0,params.getShear().mV[1],s),
1024 s); 1038 s);
1025 pt->mScale.mV[VX] = hole_x * lerp(taper_x_begin, taper_x_end, t); 1039 pt->mScale.mV[VX] = hole_x * lerp(taper_x_begin, taper_x_end, t);
1026 pt->mScale.mV[VY] = hole_y * lerp(taper_y_begin, taper_y_end, t); 1040 pt->mScale.mV[VY] = hole_y * lerp(taper_y_begin, taper_y_end, t);
@@ -1039,7 +1053,7 @@ void LLPath::genNGon(S32 sides, F32 startOff, F32 end_scale, F32 twist_scale)
1039 t = ((S32)(t * sides)) / (F32)sides; 1053 t = ((S32)(t * sides)) / (F32)sides;
1040 1054
1041 // Run through the non-cut dependent points. 1055 // Run through the non-cut dependent points.
1042 while (t < mParams.getEnd()) 1056 while (t < params.getEnd())
1043 { 1057 {
1044 pt = vector_append(mPath, 1); 1058 pt = vector_append(mPath, 1);
1045 1059
@@ -1047,9 +1061,9 @@ void LLPath::genNGon(S32 sides, F32 startOff, F32 end_scale, F32 twist_scale)
1047 c = cos(ang)*lerp(radius_start, radius_end, t); 1061 c = cos(ang)*lerp(radius_start, radius_end, t);
1048 s = sin(ang)*lerp(radius_start, radius_end, t); 1062 s = sin(ang)*lerp(radius_start, radius_end, t);
1049 1063
1050 pt->mPos.setVec(0 + lerp(0,mParams.getShear().mV[0],s) 1064 pt->mPos.setVec(0 + lerp(0,params.getShear().mV[0],s)
1051 + lerp(-skew ,skew, t) * 0.5f, 1065 + lerp(-skew ,skew, t) * 0.5f,
1052 c + lerp(0,mParams.getShear().mV[1],s), 1066 c + lerp(0,params.getShear().mV[1],s),
1053 s); 1067 s);
1054 1068
1055 pt->mScale.mV[VX] = hole_x * lerp(taper_x_begin, taper_x_end, t); 1069 pt->mScale.mV[VX] = hole_x * lerp(taper_x_begin, taper_x_end, t);
@@ -1066,15 +1080,15 @@ void LLPath::genNGon(S32 sides, F32 startOff, F32 end_scale, F32 twist_scale)
1066 } 1080 }
1067 1081
1068 // Make one final pass for the end cut. 1082 // Make one final pass for the end cut.
1069 t = mParams.getEnd(); 1083 t = params.getEnd();
1070 pt = vector_append(mPath, 1); 1084 pt = vector_append(mPath, 1);
1071 ang = 2.0f*F_PI*revolutions * t; 1085 ang = 2.0f*F_PI*revolutions * t;
1072 c = cos(ang)*lerp(radius_start, radius_end, t); 1086 c = cos(ang)*lerp(radius_start, radius_end, t);
1073 s = sin(ang)*lerp(radius_start, radius_end, t); 1087 s = sin(ang)*lerp(radius_start, radius_end, t);
1074 1088
1075 pt->mPos.setVec(0 + lerp(0,mParams.getShear().mV[0],s) 1089 pt->mPos.setVec(0 + lerp(0,params.getShear().mV[0],s)
1076 + lerp(-skew ,skew, t) * 0.5f, 1090 + lerp(-skew ,skew, t) * 0.5f,
1077 c + lerp(0,mParams.getShear().mV[1],s), 1091 c + lerp(0,params.getShear().mV[1],s),
1078 s); 1092 s);
1079 pt->mScale.mV[VX] = hole_x * lerp(taper_x_begin, taper_x_end, t); 1093 pt->mScale.mV[VX] = hole_x * lerp(taper_x_begin, taper_x_end, t);
1080 pt->mScale.mV[VY] = hole_y * lerp(taper_y_begin, taper_y_end, t); 1094 pt->mScale.mV[VY] = hole_y * lerp(taper_y_begin, taper_y_end, t);
@@ -1117,8 +1131,10 @@ const LLVector2 LLPathParams::getEndScale() const
1117 return end_scale; 1131 return end_scale;
1118} 1132}
1119 1133
1120BOOL LLPath::generate(F32 detail, S32 split, BOOL is_sculpted) 1134BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split, BOOL is_sculpted)
1121{ 1135{
1136 LLMemType m1(LLMemType::MTYPE_VOLUME);
1137
1122 if ((!mDirty) && (!is_sculpted)) 1138 if ((!mDirty) && (!is_sculpted))
1123 { 1139 {
1124 return FALSE; 1140 return FALSE;
@@ -1137,13 +1153,13 @@ BOOL LLPath::generate(F32 detail, S32 split, BOOL is_sculpted)
1137 mOpen = TRUE; 1153 mOpen = TRUE;
1138 1154
1139 // Is this 0xf0 mask really necessary? DK 03/02/05 1155 // Is this 0xf0 mask really necessary? DK 03/02/05
1140 switch (mParams.getCurveType() & 0xf0) 1156 switch (params.getCurveType() & 0xf0)
1141 { 1157 {
1142 default: 1158 default:
1143 case LL_PCODE_PATH_LINE: 1159 case LL_PCODE_PATH_LINE:
1144 { 1160 {
1145 // Take the begin/end twist into account for detail. 1161 // Take the begin/end twist into account for detail.
1146 np = llfloor(fabs(mParams.getTwistBegin() - mParams.getTwist()) * 3.5f * (detail-0.5f)) + 2; 1162 np = llfloor(fabs(params.getTwistBegin() - params.getTwist()) * 3.5f * (detail-0.5f)) + 2;
1147 if (np < split+2) 1163 if (np < split+2)
1148 { 1164 {
1149 np = split+2; 1165 np = split+2;
@@ -1153,16 +1169,16 @@ BOOL LLPath::generate(F32 detail, S32 split, BOOL is_sculpted)
1153 1169
1154 mPath.resize(np); 1170 mPath.resize(np);
1155 1171
1156 LLVector2 start_scale = mParams.getBeginScale(); 1172 LLVector2 start_scale = params.getBeginScale();
1157 LLVector2 end_scale = mParams.getEndScale(); 1173 LLVector2 end_scale = params.getEndScale();
1158 1174
1159 for (S32 i=0;i<np;i++) 1175 for (S32 i=0;i<np;i++)
1160 { 1176 {
1161 F32 t = lerp(mParams.getBegin(),mParams.getEnd(),(F32)i * mStep); 1177 F32 t = lerp(params.getBegin(),params.getEnd(),(F32)i * mStep);
1162 mPath[i].mPos.setVec(lerp(0,mParams.getShear().mV[0],t), 1178 mPath[i].mPos.setVec(lerp(0,params.getShear().mV[0],t),
1163 lerp(0,mParams.getShear().mV[1],t), 1179 lerp(0,params.getShear().mV[1],t),
1164 t - 0.5f); 1180 t - 0.5f);
1165 mPath[i].mRot.setQuat(lerp(F_PI * mParams.getTwistBegin(),F_PI * mParams.getTwist(),t),0,0,1); 1181 mPath[i].mRot.setQuat(lerp(F_PI * params.getTwistBegin(),F_PI * params.getTwist(),t),0,0,1);
1166 mPath[i].mScale.mV[0] = lerp(start_scale.mV[0],end_scale.mV[0],t); 1182 mPath[i].mScale.mV[0] = lerp(start_scale.mV[0],end_scale.mV[0],t);
1167 mPath[i].mScale.mV[1] = lerp(start_scale.mV[1],end_scale.mV[1],t); 1183 mPath[i].mScale.mV[1] = lerp(start_scale.mV[1],end_scale.mV[1],t);
1168 mPath[i].mTexT = t; 1184 mPath[i].mTexT = t;
@@ -1173,27 +1189,27 @@ BOOL LLPath::generate(F32 detail, S32 split, BOOL is_sculpted)
1173 case LL_PCODE_PATH_CIRCLE: 1189 case LL_PCODE_PATH_CIRCLE:
1174 { 1190 {
1175 // Increase the detail as the revolutions and twist increase. 1191 // Increase the detail as the revolutions and twist increase.
1176 F32 twist_mag = fabs(mParams.getTwistBegin() - mParams.getTwist()); 1192 F32 twist_mag = fabs(params.getTwistBegin() - params.getTwist());
1177 1193
1178 S32 sides = (S32)llfloor(llfloor((MIN_DETAIL_FACES * detail + twist_mag * 3.5f * (detail-0.5f))) * mParams.getRevolutions()); 1194 S32 sides = (S32)llfloor(llfloor((MIN_DETAIL_FACES * detail + twist_mag * 3.5f * (detail-0.5f))) * params.getRevolutions());
1179 1195
1180 if (is_sculpted) 1196 if (is_sculpted)
1181 sides = sculpt_sides(detail); 1197 sides = sculpt_sides(detail);
1182 1198
1183 genNGon(sides); 1199 genNGon(params, sides);
1184 } 1200 }
1185 break; 1201 break;
1186 1202
1187 case LL_PCODE_PATH_CIRCLE2: 1203 case LL_PCODE_PATH_CIRCLE2:
1188 { 1204 {
1189 if (mParams.getEnd() - mParams.getBegin() >= 0.99f && 1205 if (params.getEnd() - params.getBegin() >= 0.99f &&
1190 mParams.getScaleX() >= .99f) 1206 params.getScaleX() >= .99f)
1191 { 1207 {
1192 mOpen = FALSE; 1208 mOpen = FALSE;
1193 } 1209 }
1194 1210
1195 //genNGon(llfloor(MIN_DETAIL_FACES * detail), 4.f, 0.f); 1211 //genNGon(params, llfloor(MIN_DETAIL_FACES * detail), 4.f, 0.f);
1196 genNGon(llfloor(MIN_DETAIL_FACES * detail)); 1212 genNGon(params, llfloor(MIN_DETAIL_FACES * detail));
1197 1213
1198 F32 t = 0.f; 1214 F32 t = 0.f;
1199 F32 tStep = 1.0f / mPath.size(); 1215 F32 tStep = 1.0f / mPath.size();
@@ -1223,28 +1239,30 @@ BOOL LLPath::generate(F32 detail, S32 split, BOOL is_sculpted)
1223 { 1239 {
1224 F32 t = (F32)i * mStep; 1240 F32 t = (F32)i * mStep;
1225 mPath[i].mPos.setVec(0, 1241 mPath[i].mPos.setVec(0,
1226 lerp(0, -sin(F_PI*mParams.getTwist()*t)*0.5f,t), 1242 lerp(0, -sin(F_PI*params.getTwist()*t)*0.5f,t),
1227 lerp(-0.5, cos(F_PI*mParams.getTwist()*t)*0.5f,t)); 1243 lerp(-0.5, cos(F_PI*params.getTwist()*t)*0.5f,t));
1228 mPath[i].mScale.mV[0] = lerp(1,mParams.getScale().mV[0],t); 1244 mPath[i].mScale.mV[0] = lerp(1,params.getScale().mV[0],t);
1229 mPath[i].mScale.mV[1] = lerp(1,mParams.getScale().mV[1],t); 1245 mPath[i].mScale.mV[1] = lerp(1,params.getScale().mV[1],t);
1230 mPath[i].mTexT = t; 1246 mPath[i].mTexT = t;
1231 mPath[i].mRot.setQuat(F_PI * mParams.getTwist() * t,1,0,0); 1247 mPath[i].mRot.setQuat(F_PI * params.getTwist() * t,1,0,0);
1232 } 1248 }
1233 1249
1234 break; 1250 break;
1235 }; 1251 };
1236 1252
1237 if (mParams.getTwist() != mParams.getTwistBegin()) mOpen = TRUE; 1253 if (params.getTwist() != params.getTwistBegin()) mOpen = TRUE;
1238 1254
1239 //if ((int(fabsf(mParams.getTwist() - mParams.getTwistBegin())*100))%100 != 0) { 1255 //if ((int(fabsf(params.getTwist() - params.getTwistBegin())*100))%100 != 0) {
1240 // mOpen = TRUE; 1256 // mOpen = TRUE;
1241 //} 1257 //}
1242 1258
1243 return TRUE; 1259 return TRUE;
1244} 1260}
1245 1261
1246BOOL LLDynamicPath::generate(F32 detail, S32 split, BOOL is_sculpted) 1262BOOL LLDynamicPath::generate(const LLPathParams& params, F32 detail, S32 split, BOOL is_sculpted)
1247{ 1263{
1264 LLMemType m1(LLMemType::MTYPE_VOLUME);
1265
1248 mOpen = TRUE; // Draw end caps 1266 mOpen = TRUE; // Draw end caps
1249 if (getPathLength() == 0) 1267 if (getPathLength() == 0)
1250 { 1268 {
@@ -1266,6 +1284,8 @@ BOOL LLDynamicPath::generate(F32 detail, S32 split, BOOL is_sculpted)
1266 1284
1267BOOL LLPathParams::importFile(FILE *fp) 1285BOOL LLPathParams::importFile(FILE *fp)
1268{ 1286{
1287 LLMemType m1(LLMemType::MTYPE_VOLUME);
1288
1269 const S32 BUFSIZE = 16384; 1289 const S32 BUFSIZE = 16384;
1270 char buffer[BUFSIZE]; /* Flawfinder: ignore */ 1290 char buffer[BUFSIZE]; /* Flawfinder: ignore */
1271 // *NOTE: changing the size or type of these buffers will require 1291 // *NOTE: changing the size or type of these buffers will require
@@ -1410,6 +1430,8 @@ BOOL LLPathParams::exportFile(FILE *fp) const
1410 1430
1411BOOL LLPathParams::importLegacyStream(std::istream& input_stream) 1431BOOL LLPathParams::importLegacyStream(std::istream& input_stream)
1412{ 1432{
1433 LLMemType m1(LLMemType::MTYPE_VOLUME);
1434
1413 const S32 BUFSIZE = 16384; 1435 const S32 BUFSIZE = 16384;
1414 char buffer[BUFSIZE]; /* Flawfinder: ignore */ 1436 char buffer[BUFSIZE]; /* Flawfinder: ignore */
1415 // *NOTE: changing the size or type of these buffers will require 1437 // *NOTE: changing the size or type of these buffers will require
@@ -1610,8 +1632,11 @@ LLProfile::~LLProfile()
1610 1632
1611S32 LLVolume::sNumMeshPoints = 0; 1633S32 LLVolume::sNumMeshPoints = 0;
1612 1634
1613LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL generate_single_face, const BOOL is_unique) : mParams(params) 1635LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL generate_single_face, const BOOL is_unique)
1636 : mParams(params)
1614{ 1637{
1638 LLMemType m1(LLMemType::MTYPE_VOLUME);
1639
1615 mUnique = is_unique; 1640 mUnique = is_unique;
1616 mFaceMask = 0x0; 1641 mFaceMask = 0x0;
1617 mDetail = detail; 1642 mDetail = detail;
@@ -1620,16 +1645,14 @@ LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL ge
1620 // set defaults 1645 // set defaults
1621 if (mParams.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE) 1646 if (mParams.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE)
1622 { 1647 {
1623 mPathp = new LLDynamicPath(mParams.getPathParams()); 1648 mPathp = new LLDynamicPath();
1624 } 1649 }
1625 else 1650 else
1626 { 1651 {
1627 mPathp = new LLPath(mParams.getPathParams()); 1652 mPathp = new LLPath();
1628 } 1653 }
1629 mProfilep = new LLProfile(mParams.getProfileParams()); 1654 mProfilep = new LLProfile();
1630 1655
1631 mNumVolumeFaces = 0;
1632 mVolumeFaces = NULL;
1633 mGenerateSingleFace = generate_single_face; 1656 mGenerateSingleFace = generate_single_face;
1634 1657
1635 generate(); 1658 generate();
@@ -1642,11 +1665,7 @@ LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL ge
1642void LLVolume::resizePath(S32 length) 1665void LLVolume::resizePath(S32 length)
1643{ 1666{
1644 mPathp->resizePath(length); 1667 mPathp->resizePath(length);
1645 if (mVolumeFaces != NULL) 1668 mVolumeFaces.clear();
1646 {
1647 delete[] mVolumeFaces;
1648 mVolumeFaces = NULL;
1649 }
1650} 1669}
1651 1670
1652void LLVolume::regen() 1671void LLVolume::regen()
@@ -1665,15 +1684,14 @@ LLVolume::~LLVolume()
1665 sNumMeshPoints -= mMesh.size(); 1684 sNumMeshPoints -= mMesh.size();
1666 delete mPathp; 1685 delete mPathp;
1667 delete mProfilep; 1686 delete mProfilep;
1668 delete[] mVolumeFaces;
1669
1670 mPathp = NULL; 1687 mPathp = NULL;
1671 mProfilep = NULL; 1688 mProfilep = NULL;
1672 mVolumeFaces = NULL; 1689 mVolumeFaces.clear();
1673} 1690}
1674 1691
1675BOOL LLVolume::generate() 1692BOOL LLVolume::generate()
1676{ 1693{
1694 LLMemType m1(LLMemType::MTYPE_VOLUME);
1677 llassert_always(mProfilep); 1695 llassert_always(mProfilep);
1678 1696
1679 //Added 10.03.05 Dave Parks 1697 //Added 10.03.05 Dave Parks
@@ -1682,13 +1700,13 @@ BOOL LLVolume::generate()
1682 // stretched due to twisting or scaling on the path. 1700 // stretched due to twisting or scaling on the path.
1683 S32 split = (S32) ((mDetail)*0.66f); 1701 S32 split = (S32) ((mDetail)*0.66f);
1684 1702
1685 if (mPathp->mParams.getCurveType() == LL_PCODE_PATH_LINE && 1703 if (mParams.getPathParams().getCurveType() == LL_PCODE_PATH_LINE &&
1686 (mPathp->mParams.getScale().mV[0] != 1.0f || 1704 (mParams.getPathParams().getScale().mV[0] != 1.0f ||
1687 mPathp->mParams.getScale().mV[1] != 1.0f) && 1705 mParams.getPathParams().getScale().mV[1] != 1.0f) &&
1688 (mProfilep->mParams.getCurveType() == LL_PCODE_PROFILE_SQUARE || 1706 (mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_SQUARE ||
1689 mProfilep->mParams.getCurveType() == LL_PCODE_PROFILE_ISOTRI || 1707 mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_ISOTRI ||
1690 mProfilep->mParams.getCurveType() == LL_PCODE_PROFILE_EQUALTRI || 1708 mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_EQUALTRI ||
1691 mProfilep->mParams.getCurveType() == LL_PCODE_PROFILE_RIGHTTRI)) 1709 mParams.getProfileParams().getCurveType() == LL_PCODE_PROFILE_RIGHTTRI))
1692 { 1710 {
1693 split = 0; 1711 split = 0;
1694 } 1712 }
@@ -1698,8 +1716,8 @@ BOOL LLVolume::generate()
1698 F32 profile_detail = mDetail; 1716 F32 profile_detail = mDetail;
1699 F32 path_detail = mDetail; 1717 F32 path_detail = mDetail;
1700 1718
1701 U8 path_type = mPathp->mParams.getCurveType(); 1719 U8 path_type = mParams.getPathParams().getCurveType();
1702 U8 profile_type = mProfilep->mParams.getCurveType(); 1720 U8 profile_type = mParams.getProfileParams().getCurveType();
1703 1721
1704 if (path_type == LL_PCODE_PATH_LINE && profile_type == LL_PCODE_PROFILE_CIRCLE) 1722 if (path_type == LL_PCODE_PATH_LINE && profile_type == LL_PCODE_PROFILE_CIRCLE)
1705 { //cylinders don't care about Z-Axis 1723 { //cylinders don't care about Z-Axis
@@ -1710,8 +1728,8 @@ BOOL LLVolume::generate()
1710 mLODScaleBias.setVec(0.6f, 0.6f, 0.6f); 1728 mLODScaleBias.setVec(0.6f, 0.6f, 0.6f);
1711 } 1729 }
1712 1730
1713 BOOL regenPath = mPathp->generate(path_detail, split); 1731 BOOL regenPath = mPathp->generate(mParams.getPathParams(), path_detail, split);
1714 BOOL regenProf = mProfilep->generate(mPathp->isOpen(),profile_detail, split); 1732 BOOL regenProf = mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(),profile_detail, split);
1715 1733
1716 if (regenPath || regenProf ) 1734 if (regenPath || regenProf )
1717 { 1735 {
@@ -1759,28 +1777,26 @@ BOOL LLVolume::generate()
1759 1777
1760void LLVolume::createVolumeFaces() 1778void LLVolume::createVolumeFaces()
1761{ 1779{
1762 S32 i; 1780 LLMemType m1(LLMemType::MTYPE_VOLUME);
1763 1781
1764 if (mGenerateSingleFace) 1782 if (mGenerateSingleFace)
1765 { 1783 {
1766 mNumVolumeFaces = 0; 1784 // do nothing
1767 } 1785 }
1768 else 1786 else
1769 { 1787 {
1770 S32 num_faces = getNumFaces(); 1788 S32 num_faces = getNumFaces();
1771 mNumVolumeFaces = num_faces;
1772 BOOL partial_build = TRUE; 1789 BOOL partial_build = TRUE;
1773 if (!mVolumeFaces) 1790 if (num_faces != mVolumeFaces.size())
1774 { 1791 {
1775 partial_build = FALSE; 1792 partial_build = FALSE;
1776 mVolumeFaces = new LLVolumeFace[num_faces]; 1793 mVolumeFaces.resize(num_faces);
1777 } 1794 }
1778 // Initialize volume faces with parameter data 1795 // Initialize volume faces with parameter data
1779 for (i = 0; i < num_faces; i++) 1796 for (S32 i = 0; i < (S32)mVolumeFaces.size(); i++)
1780 { 1797 {
1781 LLVolumeFace &vf = mVolumeFaces[i]; 1798 LLVolumeFace& vf = mVolumeFaces[i];
1782 LLProfile::Face &face = mProfilep->mFaces[i]; 1799 LLProfile::Face& face = mProfilep->mFaces[i];
1783 vf.mVolumep = this;
1784 vf.mBeginS = face.mIndex; 1800 vf.mBeginS = face.mIndex;
1785 vf.mNumS = face.mCount; 1801 vf.mNumS = face.mCount;
1786 vf.mBeginT = 0; 1802 vf.mBeginT = 0;
@@ -1788,7 +1804,7 @@ void LLVolume::createVolumeFaces()
1788 vf.mID = i; 1804 vf.mID = i;
1789 1805
1790 // Set the type mask bits correctly 1806 // Set the type mask bits correctly
1791 if (mProfilep->isHollow()) 1807 if (mParams.getProfileParams().getHollow() > 0)
1792 { 1808 {
1793 vf.mTypeMask |= LLVolumeFace::HOLLOW_MASK; 1809 vf.mTypeMask |= LLVolumeFace::HOLLOW_MASK;
1794 } 1810 }
@@ -1835,9 +1851,10 @@ void LLVolume::createVolumeFaces()
1835 } 1851 }
1836 } 1852 }
1837 1853
1838 for (i = 0; i < mNumVolumeFaces; i++) 1854 for (face_list_t::iterator iter = mVolumeFaces.begin();
1855 iter != mVolumeFaces.end(); ++iter)
1839 { 1856 {
1840 mVolumeFaces[i].create(partial_build); 1857 (*iter).create(this, partial_build);
1841 } 1858 }
1842 } 1859 }
1843} 1860}
@@ -1930,6 +1947,8 @@ F32 LLVolume::sculptGetSurfaceArea(U16 sculpt_width, U16 sculpt_height, S8 sculp
1930// create placeholder shape 1947// create placeholder shape
1931void LLVolume::sculptGeneratePlaceholder() 1948void LLVolume::sculptGeneratePlaceholder()
1932{ 1949{
1950 LLMemType m1(LLMemType::MTYPE_VOLUME);
1951
1933 S32 sizeS = mPathp->mPath.size(); 1952 S32 sizeS = mPathp->mPath.size();
1934 S32 sizeT = mProfilep->mProfile.size(); 1953 S32 sizeT = mProfilep->mProfile.size();
1935 1954
@@ -1961,6 +1980,8 @@ void LLVolume::sculptGeneratePlaceholder()
1961// create the vertices from the map 1980// create the vertices from the map
1962void LLVolume::sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type) 1981void LLVolume::sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type)
1963{ 1982{
1983 LLMemType m1(LLMemType::MTYPE_VOLUME);
1984
1964 S32 sizeS = mPathp->mPath.size(); 1985 S32 sizeS = mPathp->mPath.size();
1965 S32 sizeT = mProfilep->mProfile.size(); 1986 S32 sizeT = mProfilep->mProfile.size();
1966 1987
@@ -2030,18 +2051,19 @@ void LLVolume::sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8
2030// sculpt replaces generate() for sculpted surfaces 2051// sculpt replaces generate() for sculpted surfaces
2031void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level) 2052void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level)
2032{ 2053{
2054 LLMemType m1(LLMemType::MTYPE_VOLUME);
2033 U8 sculpt_type = mParams.getSculptType(); 2055 U8 sculpt_type = mParams.getSculptType();
2034 2056
2035 BOOL data_is_empty = FALSE; 2057 BOOL data_is_empty = FALSE;
2036 2058
2037 if (sculpt_width == 0 || sculpt_height == 0 || sculpt_components == 0 || sculpt_data == NULL) 2059 if (sculpt_width == 0 || sculpt_height == 0 || sculpt_components < 3 || sculpt_data == NULL)
2038 { 2060 {
2039 sculpt_level = -1; 2061 sculpt_level = -1;
2040 data_is_empty = TRUE; 2062 data_is_empty = TRUE;
2041 } 2063 }
2042 2064
2043 mPathp->generate(mDetail, 0, TRUE); 2065 mPathp->generate(mParams.getPathParams(), mDetail, 0, TRUE);
2044 mProfilep->generate(mPathp->isOpen(), mDetail, 0, TRUE); 2066 mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(), mDetail, 0, TRUE);
2045 2067
2046 S32 sizeS = mPathp->mPath.size(); 2068 S32 sizeS = mPathp->mPath.size();
2047 S32 sizeT = mProfilep->mProfile.size(); 2069 S32 sizeT = mProfilep->mProfile.size();
@@ -2056,7 +2078,7 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components,
2056 mMesh.resize(sizeS * sizeT); 2078 mMesh.resize(sizeS * sizeT);
2057 sNumMeshPoints += mMesh.size(); 2079 sNumMeshPoints += mMesh.size();
2058 2080
2059 if (sculptGetSurfaceArea(sculpt_width, sculpt_height, sculpt_components, sculpt_data) < SCULPT_MIN_AREA) 2081 if (!data_is_empty && sculptGetSurfaceArea(sculpt_width, sculpt_height, sculpt_components, sculpt_data) < SCULPT_MIN_AREA)
2060 data_is_empty = TRUE; 2082 data_is_empty = TRUE;
2061 2083
2062 //generate vertex positions 2084 //generate vertex positions
@@ -2077,11 +2099,7 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components,
2077 mSculptLevel = sculpt_level; 2099 mSculptLevel = sculpt_level;
2078 2100
2079 // Delete any existing faces so that they get regenerated 2101 // Delete any existing faces so that they get regenerated
2080 if (mVolumeFaces) 2102 mVolumeFaces.clear();
2081 {
2082 delete[] mVolumeFaces;
2083 mVolumeFaces = NULL;
2084 }
2085 2103
2086 createVolumeFaces(); 2104 createVolumeFaces();
2087} 2105}
@@ -2141,6 +2159,7 @@ bool LLVolumeParams::operator<(const LLVolumeParams &params) const
2141 2159
2142void LLVolumeParams::copyParams(const LLVolumeParams &params) 2160void LLVolumeParams::copyParams(const LLVolumeParams &params)
2143{ 2161{
2162 LLMemType m1(LLMemType::MTYPE_VOLUME);
2144 mProfileParams.copyParams(params.mProfileParams); 2163 mProfileParams.copyParams(params.mProfileParams);
2145 mPathParams.copyParams(params.mPathParams); 2164 mPathParams.copyParams(params.mPathParams);
2146 mSculptID = params.getSculptID(); 2165 mSculptID = params.getSculptID();
@@ -2512,6 +2531,8 @@ bool LLVolumeParams::validate(U8 prof_curve, F32 prof_begin, F32 prof_end, F32 h
2512 2531
2513S32 *LLVolume::getTriangleIndices(U32 &num_indices) const 2532S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
2514{ 2533{
2534 LLMemType m1(LLMemType::MTYPE_VOLUME);
2535
2515 S32 expected_num_triangle_indices = getNumTriangleIndices(); 2536 S32 expected_num_triangle_indices = getNumTriangleIndices();
2516 if (expected_num_triangle_indices > MAX_VOLUME_TRIANGLE_INDICES) 2537 if (expected_num_triangle_indices > MAX_VOLUME_TRIANGLE_INDICES)
2517 { 2538 {
@@ -2528,7 +2549,7 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
2528 // Counter-clockwise triangles are forward facing... 2549 // Counter-clockwise triangles are forward facing...
2529 2550
2530 BOOL open = getProfile().isOpen(); 2551 BOOL open = getProfile().isOpen();
2531 BOOL hollow = getProfile().isHollow(); 2552 BOOL hollow = (mParams.getProfileParams().getHollow() > 0);
2532 BOOL path_open = getPath().isOpen(); 2553 BOOL path_open = getPath().isOpen();
2533 S32 size_s, size_s_out, size_t; 2554 S32 size_s, size_s_out, size_t;
2534 S32 s, t, i; 2555 S32 s, t, i;
@@ -3134,7 +3155,7 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
3134S32 LLVolume::getNumTriangleIndices() const 3155S32 LLVolume::getNumTriangleIndices() const
3135{ 3156{
3136 BOOL profile_open = getProfile().isOpen(); 3157 BOOL profile_open = getProfile().isOpen();
3137 BOOL hollow = getProfile().isHollow(); 3158 BOOL hollow = (mParams.getProfileParams().getHollow() > 0);
3138 BOOL path_open = getPath().isOpen(); 3159 BOOL path_open = getPath().isOpen();
3139 3160
3140 S32 size_s, size_s_out, size_t; 3161 S32 size_s, size_s_out, size_t;
@@ -3198,13 +3219,17 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
3198 const LLMatrix4& mat, 3219 const LLMatrix4& mat,
3199 const LLMatrix3& norm_mat) 3220 const LLMatrix3& norm_mat)
3200{ 3221{
3222 LLMemType m1(LLMemType::MTYPE_VOLUME);
3223
3201 vertices.clear(); 3224 vertices.clear();
3202 normals.clear(); 3225 normals.clear();
3203 segments.clear(); 3226 segments.clear();
3204 3227
3205 //for each face 3228 //for each face
3206 for (S32 i = 0; i < getNumVolumeFaces(); i++) { 3229 for (face_list_t::iterator iter = mVolumeFaces.begin();
3207 LLVolumeFace face = this->getVolumeFace(i); 3230 iter != mVolumeFaces.end(); ++iter)
3231 {
3232 const LLVolumeFace& face = *iter;
3208 3233
3209 if (face.mTypeMask & (LLVolumeFace::CAP_MASK)) { 3234 if (face.mTypeMask & (LLVolumeFace::CAP_MASK)) {
3210 3235
@@ -3387,9 +3412,9 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, LLVector3& end) const
3387 3412
3388 LLVector3 vec = end - start; 3413 LLVector3 vec = end - start;
3389 3414
3390 for (U32 i = 0; i < (U32)getNumFaces(); i++) 3415 for (S32 i = 0; i < getNumFaces(); i++)
3391 { 3416 {
3392 LLVolumeFace face = getVolumeFace(i); 3417 const LLVolumeFace& face = getVolumeFace(i);
3393 3418
3394 for (U32 j = 0; j < face.mIndices.size()/3; j++) 3419 for (U32 j = 0; j < face.mIndices.size()/3; j++)
3395 { 3420 {
@@ -3532,6 +3557,8 @@ BOOL LLVolume::cleanupTriangleData( const S32 num_input_vertices,
3532 S32 &num_output_triangles, 3557 S32 &num_output_triangles,
3533 S32 **output_triangles) 3558 S32 **output_triangles)
3534{ 3559{
3560 LLMemType m1(LLMemType::MTYPE_VOLUME);
3561
3535 /* Testing: avoid any cleanup 3562 /* Testing: avoid any cleanup
3536 num_output_vertices = num_input_vertices; 3563 num_output_vertices = num_input_vertices;
3537 num_output_triangles = num_input_triangles; 3564 num_output_triangles = num_input_triangles;
@@ -3749,6 +3776,8 @@ BOOL LLVolume::cleanupTriangleData( const S32 num_input_vertices,
3749 3776
3750BOOL LLVolumeParams::importFile(FILE *fp) 3777BOOL LLVolumeParams::importFile(FILE *fp)
3751{ 3778{
3779 LLMemType m1(LLMemType::MTYPE_VOLUME);
3780
3752 //llinfos << "importing volume" << llendl; 3781 //llinfos << "importing volume" << llendl;
3753 const S32 BUFSIZE = 16384; 3782 const S32 BUFSIZE = 16384;
3754 char buffer[BUFSIZE]; /* Flawfinder: ignore */ 3783 char buffer[BUFSIZE]; /* Flawfinder: ignore */
@@ -3803,6 +3832,8 @@ BOOL LLVolumeParams::exportFile(FILE *fp) const
3803 3832
3804BOOL LLVolumeParams::importLegacyStream(std::istream& input_stream) 3833BOOL LLVolumeParams::importLegacyStream(std::istream& input_stream)
3805{ 3834{
3835 LLMemType m1(LLMemType::MTYPE_VOLUME);
3836
3806 //llinfos << "importing volume" << llendl; 3837 //llinfos << "importing volume" << llendl;
3807 const S32 BUFSIZE = 16384; 3838 const S32 BUFSIZE = 16384;
3808 // *NOTE: changing the size or type of this buffer will require 3839 // *NOTE: changing the size or type of this buffer will require
@@ -3842,6 +3873,8 @@ BOOL LLVolumeParams::importLegacyStream(std::istream& input_stream)
3842 3873
3843BOOL LLVolumeParams::exportLegacyStream(std::ostream& output_stream) const 3874BOOL LLVolumeParams::exportLegacyStream(std::ostream& output_stream) const
3844{ 3875{
3876 LLMemType m1(LLMemType::MTYPE_VOLUME);
3877
3845 output_stream <<"\tshape 0\n"; 3878 output_stream <<"\tshape 0\n";
3846 output_stream <<"\t{\n"; 3879 output_stream <<"\t{\n";
3847 mPathParams.exportLegacyStream(output_stream); 3880 mPathParams.exportLegacyStream(output_stream);
@@ -3993,7 +4026,7 @@ LLFaceID LLVolume::generateFaceMask()
3993{ 4026{
3994 LLFaceID new_mask = 0x0000; 4027 LLFaceID new_mask = 0x0000;
3995 4028
3996 switch(mProfilep->mParams.getCurveType() & LL_PCODE_PROFILE_MASK) 4029 switch(mParams.getProfileParams().getCurveType() & LL_PCODE_PROFILE_MASK)
3997 { 4030 {
3998 case LL_PCODE_PROFILE_CIRCLE: 4031 case LL_PCODE_PROFILE_CIRCLE:
3999 case LL_PCODE_PROFILE_CIRCLE_HALF: 4032 case LL_PCODE_PROFILE_CIRCLE_HALF:
@@ -4001,7 +4034,7 @@ LLFaceID LLVolume::generateFaceMask()
4001 break; 4034 break;
4002 case LL_PCODE_PROFILE_SQUARE: 4035 case LL_PCODE_PROFILE_SQUARE:
4003 { 4036 {
4004 for(S32 side = (S32)(mProfilep->mParams.getBegin() * 4.f); side < llceil(mProfilep->mParams.getEnd() * 4.f); side++) 4037 for(S32 side = (S32)(mParams.getProfileParams().getBegin() * 4.f); side < llceil(mParams.getProfileParams().getEnd() * 4.f); side++)
4005 { 4038 {
4006 new_mask |= LL_FACE_OUTER_SIDE_0 << side; 4039 new_mask |= LL_FACE_OUTER_SIDE_0 << side;
4007 } 4040 }
@@ -4011,7 +4044,7 @@ LLFaceID LLVolume::generateFaceMask()
4011 case LL_PCODE_PROFILE_EQUALTRI: 4044 case LL_PCODE_PROFILE_EQUALTRI:
4012 case LL_PCODE_PROFILE_RIGHTTRI: 4045 case LL_PCODE_PROFILE_RIGHTTRI:
4013 { 4046 {
4014 for(S32 side = (S32)(mProfilep->mParams.getBegin() * 3.f); side < llceil(mProfilep->mParams.getEnd() * 3.f); side++) 4047 for(S32 side = (S32)(mParams.getProfileParams().getBegin() * 3.f); side < llceil(mParams.getProfileParams().getEnd() * 3.f); side++)
4015 { 4048 {
4016 new_mask |= LL_FACE_OUTER_SIDE_0 << side; 4049 new_mask |= LL_FACE_OUTER_SIDE_0 << side;
4017 } 4050 }
@@ -4023,7 +4056,7 @@ LLFaceID LLVolume::generateFaceMask()
4023 } 4056 }
4024 4057
4025 // handle hollow objects 4058 // handle hollow objects
4026 if (mProfilep->isHollow()) 4059 if (mParams.getProfileParams().getHollow() > 0)
4027 { 4060 {
4028 new_mask |= LL_FACE_INNER_SIDE; 4061 new_mask |= LL_FACE_INNER_SIDE;
4029 } 4062 }
@@ -4125,7 +4158,7 @@ std::ostream& operator<<(std::ostream &s, const LLPath &path)
4125 4158
4126std::ostream& operator<<(std::ostream &s, const LLVolume &volume) 4159std::ostream& operator<<(std::ostream &s, const LLVolume &volume)
4127{ 4160{
4128 s << "{params = " << volume.mParams; 4161 s << "{params = " << volume.getParams();
4129 s << ", path = " << *volume.mPathp; 4162 s << ", path = " << *volume.mPathp;
4130 s << ", profile = " << *volume.mProfilep; 4163 s << ", profile = " << *volume.mProfilep;
4131 s << "}"; 4164 s << "}";
@@ -4135,7 +4168,7 @@ std::ostream& operator<<(std::ostream &s, const LLVolume &volume)
4135 4168
4136std::ostream& operator<<(std::ostream &s, const LLVolume *volumep) 4169std::ostream& operator<<(std::ostream &s, const LLVolume *volumep)
4137{ 4170{
4138 s << "{params = " << volumep->mParams; 4171 s << "{params = " << volumep->getParams();
4139 s << ", path = " << *(volumep->mPathp); 4172 s << ", path = " << *(volumep->mPathp);
4140 s << ", profile = " << *(volumep->mProfilep); 4173 s << ", profile = " << *(volumep->mProfilep);
4141 s << "}"; 4174 s << "}";
@@ -4155,15 +4188,15 @@ LLVolumeFace::LLVolumeFace()
4155} 4188}
4156 4189
4157 4190
4158BOOL LLVolumeFace::create(BOOL partial_build) 4191BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build)
4159{ 4192{
4160 if (mTypeMask & CAP_MASK) 4193 if (mTypeMask & CAP_MASK)
4161 { 4194 {
4162 return createCap(partial_build); 4195 return createCap(volume, partial_build);
4163 } 4196 }
4164 else if ((mTypeMask & END_MASK) || (mTypeMask & SIDE_MASK)) 4197 else if ((mTypeMask & END_MASK) || (mTypeMask & SIDE_MASK))
4165 { 4198 {
4166 return createSide(partial_build); 4199 return createSide(volume, partial_build);
4167 } 4200 }
4168 else 4201 else
4169 { 4202 {
@@ -4185,12 +4218,14 @@ void LerpPlanarVertex(LLVolumeFace::VertexData& v0,
4185 vout.mBinormal = v0.mBinormal; 4218 vout.mBinormal = v0.mBinormal;
4186} 4219}
4187 4220
4188BOOL LLVolumeFace::createUnCutCubeCap(BOOL partial_build) 4221BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
4189{ 4222{
4190 const std::vector<LLVolume::Point>& mesh = mVolumep->getMesh(); 4223 LLMemType m1(LLMemType::MTYPE_VOLUME);
4191 const std::vector<LLVector3>& profile = mVolumep->getProfile().mProfile; 4224
4192 S32 max_s = mVolumep->getProfile().getTotal(); 4225 const std::vector<LLVolume::Point>& mesh = volume->getMesh();
4193 S32 max_t = mVolumep->getPath().mPath.size(); 4226 const std::vector<LLVector3>& profile = volume->getProfile().mProfile;
4227 S32 max_s = volume->getProfile().getTotal();
4228 S32 max_t = volume->getPath().mPath.size();
4194 4229
4195 // S32 i; 4230 // S32 i;
4196 S32 num_vertices = 0, num_indices = 0; 4231 S32 num_vertices = 0, num_indices = 0;
@@ -4291,23 +4326,24 @@ BOOL LLVolumeFace::createUnCutCubeCap(BOOL partial_build)
4291} 4326}
4292 4327
4293 4328
4294BOOL LLVolumeFace::createCap(BOOL partial_build) 4329BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
4295{ 4330{
4331 LLMemType m1(LLMemType::MTYPE_VOLUME);
4332
4296 if (!(mTypeMask & HOLLOW_MASK) && 4333 if (!(mTypeMask & HOLLOW_MASK) &&
4297 !(mTypeMask & OPEN_MASK) && 4334 !(mTypeMask & OPEN_MASK) &&
4298 ((this->mVolumep->getParams().getPathParams().getBegin()==0.0f)&& 4335 ((volume->getParams().getPathParams().getBegin()==0.0f)&&
4299 (this->mVolumep->getParams().getPathParams().getEnd()==1.0f))&& 4336 (volume->getParams().getPathParams().getEnd()==1.0f))&&
4300 (mVolumep->getProfile().mParams.getCurveType()==LL_PCODE_PROFILE_SQUARE && 4337 (volume->getParams().getProfileParams().getCurveType()==LL_PCODE_PROFILE_SQUARE &&
4301 mVolumep->getPath().mParams.getCurveType()==LL_PCODE_PATH_LINE) 4338 volume->getParams().getPathParams().getCurveType()==LL_PCODE_PATH_LINE)
4302 ){ 4339 ){
4303 return createUnCutCubeCap(partial_build); 4340 return createUnCutCubeCap(volume, partial_build);
4304 } 4341 }
4305 4342
4306 S32 i;
4307 S32 num_vertices = 0, num_indices = 0; 4343 S32 num_vertices = 0, num_indices = 0;
4308 4344
4309 const std::vector<LLVolume::Point>& mesh = mVolumep->getMesh(); 4345 const std::vector<LLVolume::Point>& mesh = volume->getMesh();
4310 const std::vector<LLVector3>& profile = mVolumep->getProfile().mProfile; 4346 const std::vector<LLVector3>& profile = volume->getProfile().mProfile;
4311 4347
4312 // All types of caps have the same number of vertices and indices 4348 // All types of caps have the same number of vertices and indices
4313 num_vertices = profile.size(); 4349 num_vertices = profile.size();
@@ -4320,8 +4356,8 @@ BOOL LLVolumeFace::createCap(BOOL partial_build)
4320 mIndices.resize(num_indices); 4356 mIndices.resize(num_indices);
4321 } 4357 }
4322 4358
4323 S32 max_s = mVolumep->getProfile().getTotal(); 4359 S32 max_s = volume->getProfile().getTotal();
4324 S32 max_t = mVolumep->getPath().mPath.size(); 4360 S32 max_t = volume->getPath().mPath.size();
4325 4361
4326 mCenter.clearVec(); 4362 mCenter.clearVec();
4327 4363
@@ -4345,7 +4381,7 @@ BOOL LLVolumeFace::createCap(BOOL partial_build)
4345 LLVector3& max = mExtents[1]; 4381 LLVector3& max = mExtents[1];
4346 4382
4347 // Copy the vertices into the array 4383 // Copy the vertices into the array
4348 for (i = 0; i < num_vertices; i++) 4384 for (S32 i = 0; i < num_vertices; i++)
4349 { 4385 {
4350 if (mTypeMask & TOP_MASK) 4386 if (mTypeMask & TOP_MASK)
4351 { 4387 {
@@ -4409,7 +4445,7 @@ BOOL LLVolumeFace::createCap(BOOL partial_build)
4409 } 4445 }
4410 4446
4411 4447
4412 for (i = 0; i < num_vertices; i++) 4448 for (S32 i = 0; i < num_vertices; i++)
4413 { 4449 {
4414 mVertices[i].mBinormal = binormal; 4450 mVertices[i].mBinormal = binormal;
4415 mVertices[i].mNormal = normal; 4451 mVertices[i].mNormal = normal;
@@ -4430,7 +4466,7 @@ BOOL LLVolumeFace::createCap(BOOL partial_build)
4430 // Does it matter if it's open or closed? - djs 4466 // Does it matter if it's open or closed? - djs
4431 4467
4432 S32 pt1 = 0, pt2 = num_vertices - 1; 4468 S32 pt1 = 0, pt2 = num_vertices - 1;
4433 i = 0; 4469 S32 i = 0;
4434 while (pt2 - pt1 > 1) 4470 while (pt2 - pt1 > 1)
4435 { 4471 {
4436 // Use the profile points instead of the mesh, since you want 4472 // Use the profile points instead of the mesh, since you want
@@ -4533,7 +4569,7 @@ BOOL LLVolumeFace::createCap(BOOL partial_build)
4533 llassert(mTypeMask & BOTTOM_MASK); 4569 llassert(mTypeMask & BOTTOM_MASK);
4534 S32 pt1 = 0, pt2 = num_vertices - 1; 4570 S32 pt1 = 0, pt2 = num_vertices - 1;
4535 4571
4536 i = 0; 4572 S32 i = 0;
4537 while (pt2 - pt1 > 1) 4573 while (pt2 - pt1 > 1)
4538 { 4574 {
4539 // Use the profile points instead of the mesh, since you want 4575 // Use the profile points instead of the mesh, since you want
@@ -4640,7 +4676,7 @@ BOOL LLVolumeFace::createCap(BOOL partial_build)
4640 // SOLID OPEN TOP 4676 // SOLID OPEN TOP
4641 // Generate indices 4677 // Generate indices
4642 // This is a tri-fan, so we reuse the same first point for all triangles. 4678 // This is a tri-fan, so we reuse the same first point for all triangles.
4643 for (i = 0; i < (num_vertices - 2); i++) 4679 for (S32 i = 0; i < (num_vertices - 2); i++)
4644 { 4680 {
4645 mIndices[3*i] = num_vertices - 1; 4681 mIndices[3*i] = num_vertices - 1;
4646 mIndices[3*i+1] = i; 4682 mIndices[3*i+1] = i;
@@ -4650,7 +4686,7 @@ BOOL LLVolumeFace::createCap(BOOL partial_build)
4650 else 4686 else
4651 { 4687 {
4652 // SOLID CLOSED TOP 4688 // SOLID CLOSED TOP
4653 for (i = 0; i < (num_vertices - 2); i++) 4689 for (S32 i = 0; i < (num_vertices - 2); i++)
4654 { 4690 {
4655 //MSMSM fix these caps but only for the un-cut case 4691 //MSMSM fix these caps but only for the un-cut case
4656 mIndices[3*i] = num_vertices - 1; 4692 mIndices[3*i] = num_vertices - 1;
@@ -4666,7 +4702,7 @@ BOOL LLVolumeFace::createCap(BOOL partial_build)
4666 // SOLID OPEN BOTTOM 4702 // SOLID OPEN BOTTOM
4667 // Generate indices 4703 // Generate indices
4668 // This is a tri-fan, so we reuse the same first point for all triangles. 4704 // This is a tri-fan, so we reuse the same first point for all triangles.
4669 for (i = 0; i < (num_vertices - 2); i++) 4705 for (S32 i = 0; i < (num_vertices - 2); i++)
4670 { 4706 {
4671 mIndices[3*i] = num_vertices - 1; 4707 mIndices[3*i] = num_vertices - 1;
4672 mIndices[3*i+1] = i + 1; 4708 mIndices[3*i+1] = i + 1;
@@ -4676,7 +4712,7 @@ BOOL LLVolumeFace::createCap(BOOL partial_build)
4676 else 4712 else
4677 { 4713 {
4678 // SOLID CLOSED BOTTOM 4714 // SOLID CLOSED BOTTOM
4679 for (i = 0; i < (num_vertices - 2); i++) 4715 for (S32 i = 0; i < (num_vertices - 2); i++)
4680 { 4716 {
4681 //MSMSM fix these caps but only for the un-cut case 4717 //MSMSM fix these caps but only for the un-cut case
4682 mIndices[3*i] = num_vertices - 1; 4718 mIndices[3*i] = num_vertices - 1;
@@ -4691,6 +4727,8 @@ BOOL LLVolumeFace::createCap(BOOL partial_build)
4691 4727
4692void LLVolumeFace::createBinormals() 4728void LLVolumeFace::createBinormals()
4693{ 4729{
4730 LLMemType m1(LLMemType::MTYPE_VOLUME);
4731
4694 if (!mHasBinormals) 4732 if (!mHasBinormals)
4695 { 4733 {
4696 //generate binormals 4734 //generate binormals
@@ -4732,16 +4770,18 @@ void LLVolumeFace::createBinormals()
4732 } 4770 }
4733} 4771}
4734 4772
4735BOOL LLVolumeFace::createSide(BOOL partial_build) 4773BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
4736{ 4774{
4775 LLMemType m1(LLMemType::MTYPE_VOLUME);
4776
4737 BOOL flat = mTypeMask & FLAT_MASK; 4777 BOOL flat = mTypeMask & FLAT_MASK;
4738 S32 num_vertices, num_indices; 4778 S32 num_vertices, num_indices;
4739 4779
4740 const std::vector<LLVolume::Point>& mesh = mVolumep->getMesh(); 4780 const std::vector<LLVolume::Point>& mesh = volume->getMesh();
4741 const std::vector<LLVector3>& profile = mVolumep->getProfile().mProfile; 4781 const std::vector<LLVector3>& profile = volume->getProfile().mProfile;
4742 const std::vector<LLPath::PathPt>& path_data = mVolumep->getPath().mPath; 4782 const std::vector<LLPath::PathPt>& path_data = volume->getPath().mPath;
4743 4783
4744 S32 max_s = mVolumep->getProfile().getTotal(); 4784 S32 max_s = volume->getProfile().getTotal();
4745 4785
4746 S32 s, t, i; 4786 S32 s, t, i;
4747 F32 ss, tt; 4787 F32 ss, tt;
@@ -4884,7 +4924,7 @@ BOOL LLVolumeFace::createSide(BOOL partial_build)
4884 if (t < mNumT-2) { //top right/top left neighbor face 4924 if (t < mNumT-2) { //top right/top left neighbor face
4885 mEdge[cur_edge++] = (mNumS-1)*2*(t+1)+s*2+1; 4925 mEdge[cur_edge++] = (mNumS-1)*2*(t+1)+s*2+1;
4886 } 4926 }
4887 else if (mNumT <= 3 || mVolumep->getPath().isOpen() == TRUE) { //no neighbor 4927 else if (mNumT <= 3 || volume->getPath().isOpen() == TRUE) { //no neighbor
4888 mEdge[cur_edge++] = -1; 4928 mEdge[cur_edge++] = -1;
4889 } 4929 }
4890 else { //wrap on T 4930 else { //wrap on T
@@ -4893,7 +4933,7 @@ BOOL LLVolumeFace::createSide(BOOL partial_build)
4893 if (s > 0) { //top left/bottom left neighbor face 4933 if (s > 0) { //top left/bottom left neighbor face
4894 mEdge[cur_edge++] = (mNumS-1)*2*t+s*2-1; 4934 mEdge[cur_edge++] = (mNumS-1)*2*t+s*2-1;
4895 } 4935 }
4896 else if (flat_face || mVolumep->getProfile().isOpen() == TRUE) { //no neighbor 4936 else if (flat_face || volume->getProfile().isOpen() == TRUE) { //no neighbor
4897 mEdge[cur_edge++] = -1; 4937 mEdge[cur_edge++] = -1;
4898 } 4938 }
4899 else { //wrap on S 4939 else { //wrap on S
@@ -4903,7 +4943,7 @@ BOOL LLVolumeFace::createSide(BOOL partial_build)
4903 if (t > 0) { //bottom left/bottom right neighbor face 4943 if (t > 0) { //bottom left/bottom right neighbor face
4904 mEdge[cur_edge++] = (mNumS-1)*2*(t-1)+s*2; 4944 mEdge[cur_edge++] = (mNumS-1)*2*(t-1)+s*2;
4905 } 4945 }
4906 else if (mNumT <= 3 || mVolumep->getPath().isOpen() == TRUE) { //no neighbor 4946 else if (mNumT <= 3 || volume->getPath().isOpen() == TRUE) { //no neighbor
4907 mEdge[cur_edge++] = -1; 4947 mEdge[cur_edge++] = -1;
4908 } 4948 }
4909 else { //wrap on T 4949 else { //wrap on T
@@ -4912,7 +4952,7 @@ BOOL LLVolumeFace::createSide(BOOL partial_build)
4912 if (s < mNumS-2) { //bottom right/top right neighbor face 4952 if (s < mNumS-2) { //bottom right/top right neighbor face
4913 mEdge[cur_edge++] = (mNumS-1)*2*t+(s+1)*2; 4953 mEdge[cur_edge++] = (mNumS-1)*2*t+(s+1)*2;
4914 } 4954 }
4915 else if (flat_face || mVolumep->getProfile().isOpen() == TRUE) { //no neighbor 4955 else if (flat_face || volume->getProfile().isOpen() == TRUE) { //no neighbor
4916 mEdge[cur_edge++] = -1; 4956 mEdge[cur_edge++] = -1;
4917 } 4957 }
4918 else { //wrap on S 4958 else { //wrap on S
@@ -4957,11 +4997,11 @@ BOOL LLVolumeFace::createSide(BOOL partial_build)
4957 4997
4958 BOOL s_bottom_converges = ((mVertices[0].mPosition - mVertices[mNumS*(mNumT-2)].mPosition).magVecSquared() < 0.000001f); 4998 BOOL s_bottom_converges = ((mVertices[0].mPosition - mVertices[mNumS*(mNumT-2)].mPosition).magVecSquared() < 0.000001f);
4959 BOOL s_top_converges = ((mVertices[mNumS-1].mPosition - mVertices[mNumS*(mNumT-2)+mNumS-1].mPosition).magVecSquared() < 0.000001f); 4999 BOOL s_top_converges = ((mVertices[mNumS-1].mPosition - mVertices[mNumS*(mNumT-2)+mNumS-1].mPosition).magVecSquared() < 0.000001f);
4960 U8 sculpt_type = mVolumep->getParams().getSculptType(); 5000 U8 sculpt_type = volume->getParams().getSculptType();
4961 5001
4962 if (sculpt_type == LL_SCULPT_TYPE_NONE) // logic for non-sculpt volumes 5002 if (sculpt_type == LL_SCULPT_TYPE_NONE) // logic for non-sculpt volumes
4963 { 5003 {
4964 if (mVolumep->getPath().isOpen() == FALSE) 5004 if (volume->getPath().isOpen() == FALSE)
4965 { //wrap normals on T 5005 { //wrap normals on T
4966 for (S32 i = 0; i < mNumS; i++) 5006 for (S32 i = 0; i < mNumS; i++)
4967 { 5007 {
@@ -4971,7 +5011,7 @@ BOOL LLVolumeFace::createSide(BOOL partial_build)
4971 } 5011 }
4972 } 5012 }
4973 5013
4974 if ((mVolumep->getProfile().isOpen() == FALSE) && !(s_bottom_converges)) 5014 if ((volume->getProfile().isOpen() == FALSE) && !(s_bottom_converges))
4975 { //wrap normals on S 5015 { //wrap normals on S
4976 for (S32 i = 0; i < mNumT; i++) 5016 for (S32 i = 0; i < mNumT; i++)
4977 { 5017 {
@@ -4981,8 +5021,8 @@ BOOL LLVolumeFace::createSide(BOOL partial_build)
4981 } 5021 }
4982 } 5022 }
4983 5023
4984 if (mVolumep->getPathType() == LL_PCODE_PATH_CIRCLE && 5024 if (volume->getPathType() == LL_PCODE_PATH_CIRCLE &&
4985 ((mVolumep->getProfileType() & LL_PCODE_PROFILE_MASK) == LL_PCODE_PROFILE_CIRCLE_HALF)) 5025 ((volume->getProfileType() & LL_PCODE_PROFILE_MASK) == LL_PCODE_PROFILE_CIRCLE_HALF))
4986 { 5026 {
4987 if (s_bottom_converges) 5027 if (s_bottom_converges)
4988 { //all lower S have same normal 5028 { //all lower S have same normal
@@ -5081,69 +5121,6 @@ BOOL LLVolumeFace::createSide(BOOL partial_build)
5081 return TRUE; 5121 return TRUE;
5082} 5122}
5083 5123
5084// Static
5085BOOL LLVolumeFace::updateColors(LLColor4U *old_colors, const S32 num_old, const LLVolumeFace &old_vf,
5086 LLStrider<LLColor4U> &new_colors, const S32 num_new, const LLVolumeFace &new_vf)
5087{
5088 if (new_vf.mTypeMask & CAP_MASK)
5089 {
5090 // These aren't interpolated correctly. Need to fix when shadows go in...
5091 F32 ratio = (F32)num_old / (F32)num_new;
5092 S32 v = 0;
5093 for (v = 0; v < num_new; v++)
5094 {
5095 new_colors[v] = old_colors[(S32)(v*ratio)];
5096 }
5097 return FALSE;
5098 }
5099 else if (new_vf.mTypeMask & END_MASK)
5100 {
5101 // These aren't interpolated correctly. Need to fix when shadows go in...
5102 F32 ratio = (F32)num_old / (F32)num_new;
5103 S32 v = 0;
5104 for (v = 0; v < num_new; v++)
5105 {
5106 new_colors[v] = old_colors[(S32)(v*ratio)];
5107 }
5108 return FALSE;
5109 }
5110 else if (new_vf.mTypeMask & SIDE_MASK)
5111 {
5112 S32 s, t;
5113 F32 s_ratio = (F32)old_vf.mNumS / (F32)new_vf.mNumS;
5114 F32 t_ratio = (F32)old_vf.mNumT / (F32)new_vf.mNumT;
5115
5116 S32 v = 0;
5117 for (t = 0; t < new_vf.mNumT; t++)
5118 {
5119 F32 t_frac = t * t_ratio;
5120 S32 old_t = (S32)t_frac;
5121 S32 t_target = llmin(old_t + 1, (old_vf.mNumT - 1));
5122 t_frac -= old_t;
5123 for (s = 0; s < new_vf.mNumS; s++)
5124 {
5125 F32 s_frac = s * s_ratio;
5126 S32 old_s = (S32)s_frac;
5127 S32 s_target = llmin(old_s + 1, (old_vf.mNumS - 1));
5128 s_frac -= old_s;
5129
5130 // Interpolate along s, then along t.
5131 LLColor4U s_interp0 = old_colors[old_t * old_vf.mNumS + old_s].multAll(1.f - s_frac).addClampMax(old_colors[old_t * old_vf.mNumS + s_target].multAll(s_frac));
5132 LLColor4U s_interp1 = old_colors[t_target * old_vf.mNumS + old_s].multAll(1.f - s_frac).addClampMax(old_colors[t_target * old_vf.mNumS + s_target].multAll(s_frac));
5133 new_colors[v] = s_interp0.multAll(1.f - t_frac).addClampMax(s_interp1.multAll(t_frac));
5134 v++;
5135 }
5136 }
5137 }
5138 else
5139 {
5140 llerrs << "Unknown/uninitialized face type!" << llendl;
5141 return FALSE;
5142 }
5143 return TRUE;
5144}
5145
5146
5147// Finds binormal based on three vertices with texture coordinates. 5124// Finds binormal based on three vertices with texture coordinates.
5148// Fills in dummy values if the triangle has degenerate texture coordinates. 5125// Fills in dummy values if the triangle has degenerate texture coordinates.
5149LLVector3 calc_binormal_from_triangle( 5126LLVector3 calc_binormal_from_triangle(
diff --git a/linden/indra/llmath/llvolume.h b/linden/indra/llmath/llvolume.h
index 9dbea7a..c239685 100644
--- a/linden/indra/llmath/llvolume.h
+++ b/linden/indra/llmath/llvolume.h
@@ -643,9 +643,8 @@ protected:
643class LLProfile 643class LLProfile
644{ 644{
645public: 645public:
646 LLProfile(const LLProfileParams &params) 646 LLProfile()
647 : mParams(params), 647 : mOpen(FALSE),
648 mOpen(FALSE),
649 mConcave(FALSE), 648 mConcave(FALSE),
650 mDirty(TRUE), 649 mDirty(TRUE),
651 mTotalOut(0), 650 mTotalOut(0),
@@ -657,15 +656,12 @@ public:
657 656
658 S32 getTotal() const { return mTotal; } 657 S32 getTotal() const { return mTotal; }
659 S32 getTotalOut() const { return mTotalOut; } // Total number of outside points 658 S32 getTotalOut() const { return mTotalOut; } // Total number of outside points
660 BOOL isHollow() const { return (mParams.getHollow() > 0); }
661 BOOL isFlat(S32 face) const { return (mFaces[face].mCount == 2); } 659 BOOL isFlat(S32 face) const { return (mFaces[face].mCount == 2); }
662 BOOL isOpen() const { return mOpen; } 660 BOOL isOpen() const { return mOpen; }
663 void setDirty() { mDirty = TRUE; } 661 void setDirty() { mDirty = TRUE; }
664 BOOL generate(BOOL path_open, F32 detail = 1.0f, S32 split = 0, BOOL is_sculpted = FALSE); 662 BOOL generate(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0, BOOL is_sculpted = FALSE);
665 BOOL isConcave() const { return mConcave; } 663 BOOL isConcave() const { return mConcave; }
666public: 664public:
667 const LLProfileParams &mParams;
668
669 struct Face 665 struct Face
670 { 666 {
671 S32 mIndex; 667 S32 mIndex;
@@ -687,10 +683,10 @@ public:
687 friend std::ostream& operator<<(std::ostream &s, const LLProfile &profile); 683 friend std::ostream& operator<<(std::ostream &s, const LLProfile &profile);
688 684
689protected: 685protected:
690 void genNormals(); 686 void genNormals(const LLProfileParams& params);
691 void genNGon(S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0); 687 void genNGon(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0);
692 688
693 Face* addHole(BOOL flat, F32 sides, F32 offset, F32 box_hollow, F32 ang_scale, S32 split = 0); 689 Face* addHole(const LLProfileParams& params, BOOL flat, F32 sides, F32 offset, F32 box_hollow, F32 ang_scale, S32 split = 0);
694 Face* addCap (S16 faceID); 690 Face* addCap (S16 faceID);
695 Face* addFace(S32 index, S32 count, F32 scaleU, S16 faceID, BOOL flat); 691 Face* addFace(S32 index, S32 count, F32 scaleU, S16 faceID, BOOL flat);
696 692
@@ -720,9 +716,8 @@ public:
720 }; 716 };
721 717
722public: 718public:
723 LLPath(const LLPathParams &params) 719 LLPath()
724 : mParams(params), 720 : mOpen(FALSE),
725 mOpen(FALSE),
726 mTotal(0), 721 mTotal(0),
727 mDirty(TRUE), 722 mDirty(TRUE),
728 mStep(1) 723 mStep(1)
@@ -731,8 +726,8 @@ public:
731 726
732 virtual ~LLPath(); 727 virtual ~LLPath();
733 728
734 void genNGon(S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f); 729 void genNGon(const LLPathParams& params, S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f);
735 virtual BOOL generate(F32 detail=1.0f, S32 split = 0, BOOL is_sculpted = FALSE); 730 virtual BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0, BOOL is_sculpted = FALSE);
736 731
737 BOOL isOpen() const { return mOpen; } 732 BOOL isOpen() const { return mOpen; }
738 F32 getStep() const { return mStep; } 733 F32 getStep() const { return mStep; }
@@ -745,7 +740,6 @@ public:
745 friend std::ostream& operator<<(std::ostream &s, const LLPath &path); 740 friend std::ostream& operator<<(std::ostream &s, const LLPath &path);
746 741
747public: 742public:
748 const LLPathParams &mParams;
749 std::vector<PathPt> mPath; 743 std::vector<PathPt> mPath;
750 744
751protected: 745protected:
@@ -758,8 +752,8 @@ protected:
758class LLDynamicPath : public LLPath 752class LLDynamicPath : public LLPath
759{ 753{
760public: 754public:
761 LLDynamicPath(const LLPathParams &params) : LLPath(params) { } 755 LLDynamicPath() : LLPath() { }
762 BOOL generate(F32 detail=1.0f, S32 split = 0, BOOL is_sculpted = FALSE); 756 /*virtual*/ BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0, BOOL is_sculpted = FALSE);
763}; 757};
764 758
765// Yet another "face" class - caches volume-specific, but not instance-specific data for faces) 759// Yet another "face" class - caches volume-specific, but not instance-specific data for faces)
@@ -767,7 +761,7 @@ class LLVolumeFace
767{ 761{
768public: 762public:
769 LLVolumeFace(); 763 LLVolumeFace();
770 BOOL create(BOOL partial_build = FALSE); 764 BOOL create(LLVolume* volume, BOOL partial_build = FALSE);
771 void createBinormals(); 765 void createBinormals();
772 766
773 class VertexData 767 class VertexData
@@ -811,16 +805,11 @@ public:
811 std::vector<VertexData> mVertices; 805 std::vector<VertexData> mVertices;
812 std::vector<U16> mIndices; 806 std::vector<U16> mIndices;
813 std::vector<S32> mEdge; 807 std::vector<S32> mEdge;
814 LLVolume *mVolumep; // Deliberately NOT reference counted - djs 11/20/03 - otherwise would make an annoying circular reference
815 808
816 // Shouldn't need num_old and num_new, really - djs 809private:
817 static BOOL updateColors(LLColor4U *old_colors, const S32 num_old, const LLVolumeFace &old_face, 810 BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE);
818 LLStrider<LLColor4U> &new_colors, const S32 num_new, const LLVolumeFace &new_face); 811 BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE);
819 812 BOOL createSide(LLVolume* volume, BOOL partial_build = FALSE);
820protected:
821 BOOL createUnCutCubeCap(BOOL partial_build = FALSE);
822 BOOL createCap(BOOL partial_build = FALSE);
823 BOOL createSide(BOOL partial_build = FALSE);
824}; 813};
825 814
826class LLVolume : public LLRefCount 815class LLVolume : public LLRefCount
@@ -848,12 +837,12 @@ public:
848 837
849 LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL generate_single_face = FALSE, const BOOL is_unique = FALSE); 838 LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL generate_single_face = FALSE, const BOOL is_unique = FALSE);
850 839
851 U8 getProfileType() const { return mProfilep->mParams.getCurveType(); } 840 U8 getProfileType() const { return mParams.getProfileParams().getCurveType(); }
852 U8 getPathType() const { return mPathp->mParams.getCurveType(); } 841 U8 getPathType() const { return mParams.getPathParams().getCurveType(); }
853 S32 getNumFaces() const { return (S32)mProfilep->mFaces.size(); } 842 S32 getNumFaces() const { return (S32)mProfilep->mFaces.size(); }
854 S32 getNumVolumeFaces() const { return mNumVolumeFaces; } 843 S32 getNumVolumeFaces() const { return mVolumeFaces.size(); }
855 F32 getDetail() const { return mDetail; } 844 F32 getDetail() const { return mDetail; }
856 const LLVolumeParams & getParams() const { return mParams; } 845 const LLVolumeParams& getParams() const { return mParams; }
857 LLVolumeParams getCopyOfParams() const { return mParams; } 846 LLVolumeParams getCopyOfParams() const { return mParams; }
858 const LLProfile& getProfile() const { return *mProfilep; } 847 const LLProfile& getProfile() const { return *mProfilep; }
859 LLPath& getPath() const { return *mPathp; } 848 LLPath& getPath() const { return *mPathp; }
@@ -932,8 +921,8 @@ protected:
932 std::vector<Point> mMesh; 921 std::vector<Point> mMesh;
933 922
934 BOOL mGenerateSingleFace; 923 BOOL mGenerateSingleFace;
935 S32 mNumVolumeFaces; 924 typedef std::vector<LLVolumeFace> face_list_t;
936 LLVolumeFace *mVolumeFaces; 925 face_list_t mVolumeFaces;
937}; 926};
938 927
939std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params); 928std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params);
diff --git a/linden/indra/llmath/llvolumemgr.cpp b/linden/indra/llmath/llvolumemgr.cpp
index d9bca70..0b49bb3 100644
--- a/linden/indra/llmath/llvolumemgr.cpp
+++ b/linden/indra/llmath/llvolumemgr.cpp
@@ -31,13 +31,10 @@
31#include "linden_common.h" 31#include "linden_common.h"
32 32
33#include "llvolumemgr.h" 33#include "llvolumemgr.h"
34#include "llmemtype.h"
34#include "llvolume.h" 35#include "llvolume.h"
35 36
36 37
37//#define DEBUG_VOLUME
38
39//LLVolumeMgr* gVolumeMgr = 0;
40
41const F32 BASE_THRESHOLD = 0.03f; 38const F32 BASE_THRESHOLD = 0.03f;
42 39
43//static 40//static
@@ -70,11 +67,6 @@ LLVolumeMgr::~LLVolumeMgr()
70 67
71BOOL LLVolumeMgr::cleanup() 68BOOL LLVolumeMgr::cleanup()
72{ 69{
73 #ifdef DEBUG_VOLUME
74 {
75 lldebugs << "LLVolumeMgr::cleanup()" << llendl;
76 }
77 #endif
78 BOOL no_refs = TRUE; 70 BOOL no_refs = TRUE;
79 if (mDataMutex) 71 if (mDataMutex)
80 { 72 {
@@ -85,14 +77,14 @@ BOOL LLVolumeMgr::cleanup()
85 iter != end; iter++) 77 iter != end; iter++)
86 { 78 {
87 LLVolumeLODGroup *volgroupp = iter->second; 79 LLVolumeLODGroup *volgroupp = iter->second;
88 if (volgroupp->getNumRefs() != 1) 80 if (volgroupp->getNumRefs() != 0)
89 { 81 {
90 llwarns << "Volume group " << volgroupp << " has " 82 llwarns << "Volume group " << volgroupp << " has "
91 << volgroupp->getNumRefs() << " remaining refs" << llendl; 83 << volgroupp->getNumRefs() << " remaining refs" << llendl;
92 llwarns << volgroupp->getParams() << llendl; 84 llwarns << *volgroupp->getVolumeParams() << llendl;
93 no_refs = FALSE; 85 no_refs = FALSE;
94 } 86 }
95 volgroupp->unref();// this ); 87 delete volgroupp;
96 } 88 }
97 mVolumeLODGroups.clear(); 89 mVolumeLODGroups.clear();
98 if (mDataMutex) 90 if (mDataMutex)
@@ -102,10 +94,11 @@ BOOL LLVolumeMgr::cleanup()
102 return no_refs; 94 return no_refs;
103} 95}
104 96
105// whatever calls getVolume() never owns the LLVolume* and 97// Always only ever store the results of refVolume in a LLPointer
106// cannot keep references for long since it may be deleted 98// Note however that LLVolumeLODGroup that contains the volume
107// later. For best results hold it in an LLPointer<LLVolume>. 99// also holds a LLPointer so the volume will only go away after
108LLVolume *LLVolumeMgr::getVolume(const LLVolumeParams &volume_params, const S32 detail) 100// anything holding the volume and the LODGroup are destroyed
101LLVolume* LLVolumeMgr::refVolume(const LLVolumeParams &volume_params, const S32 detail)
109{ 102{
110 LLVolumeLODGroup* volgroupp; 103 LLVolumeLODGroup* volgroupp;
111 if (mDataMutex) 104 if (mDataMutex)
@@ -121,17 +114,11 @@ LLVolume *LLVolumeMgr::getVolume(const LLVolumeParams &volume_params, const S32
121 { 114 {
122 volgroupp = iter->second; 115 volgroupp = iter->second;
123 } 116 }
124 volgroupp->ref();
125 if (mDataMutex) 117 if (mDataMutex)
126 { 118 {
127 mDataMutex->unlock(); 119 mDataMutex->unlock();
128 } 120 }
129 #ifdef DEBUG_VOLUME 121 return volgroupp->getLODVolume(detail);
130 {
131 lldebugs << "LLVolumeMgr::getVolume() " << (*this) << llendl;
132 }
133 #endif
134 return volgroupp->getLOD(detail);
135} 122}
136 123
137// virtual 124// virtual
@@ -154,15 +141,14 @@ LLVolumeLODGroup* LLVolumeMgr::getGroup( const LLVolumeParams& volume_params ) c
154 return volgroupp; 141 return volgroupp;
155} 142}
156 143
157// virtual 144void LLVolumeMgr::unrefVolume(LLVolume *volumep)
158void LLVolumeMgr::cleanupVolume(LLVolume *volumep)
159{ 145{
160 if (volumep->isUnique()) 146 if (volumep->isUnique())
161 { 147 {
162 // TomY: Don't need to manage this volume. It is a unique instance. 148 // TomY: Don't need to manage this volume. It is a unique instance.
163 return; 149 return;
164 } 150 }
165 LLVolumeParams* params = (LLVolumeParams*) &(volumep->getParams()); 151 const LLVolumeParams* params = &(volumep->getParams());
166 if (mDataMutex) 152 if (mDataMutex)
167 { 153 {
168 mDataMutex->lock(); 154 mDataMutex->lock();
@@ -182,11 +168,10 @@ void LLVolumeMgr::cleanupVolume(LLVolume *volumep)
182 LLVolumeLODGroup* volgroupp = iter->second; 168 LLVolumeLODGroup* volgroupp = iter->second;
183 169
184 volgroupp->derefLOD(volumep); 170 volgroupp->derefLOD(volumep);
185 volgroupp->unref();// this ); 171 if (volgroupp->getNumRefs() == 0)
186 if (volgroupp->getNumRefs() == 1)
187 { 172 {
188 mVolumeLODGroups.erase(params); 173 mVolumeLODGroups.erase(params);
189 volgroupp->unref();// this ); 174 delete volgroupp;
190 } 175 }
191 } 176 }
192 if (mDataMutex) 177 if (mDataMutex)
@@ -194,40 +179,21 @@ void LLVolumeMgr::cleanupVolume(LLVolume *volumep)
194 mDataMutex->unlock(); 179 mDataMutex->unlock();
195 } 180 }
196 181
197 #ifdef DEBUG_VOLUME
198 {
199 lldebugs << "LLVolumeMgr::cleanupVolume() " << (*this) << llendl;
200 }
201 #endif
202} 182}
203 183
204#ifdef DEBUG_VOLUME 184// protected
205S32 LLVolumeMgr::getTotalRefCount() const 185void LLVolumeMgr::insertGroup(LLVolumeLODGroup* volgroup)
206{
207 S32 total_ref_count = 0;
208 for ( volume_lod_group_map_t::const_iterator iter = mVolumeLODGroups.begin(),
209 end = mVolumeLODGroups.end();
210 iter != end; iter++)
211 {
212 total_ref_count += iter->second->getTotalVolumeRefCount();
213 }
214 return total_ref_count;
215}
216
217S32 LLVolumeMgr::getGroupCount() const
218{ 186{
219 return mVolumeLODGroups.size(); 187 mVolumeLODGroups[volgroup->getVolumeParams()] = volgroup;
220} 188}
221#endif
222 189
223// protected 190// protected
224LLVolumeLODGroup* LLVolumeMgr::createNewGroup(const LLVolumeParams& volume_params) 191LLVolumeLODGroup* LLVolumeMgr::createNewGroup(const LLVolumeParams& volume_params)
225{ 192{
226 LLVolumeLODGroup* group = new LLVolumeLODGroup(volume_params); 193 LLMemType m1(LLMemType::MTYPE_VOLUME);
227 const LLVolumeParams* params = &(group->getParams()); 194 LLVolumeLODGroup* volgroup = new LLVolumeLODGroup(volume_params);
228 mVolumeLODGroups[params] = group; 195 insertGroup(volgroup);
229 group->ref(); // initial reference 196 return volgroup;
230 return group;
231} 197}
232 198
233// virtual 199// virtual
@@ -272,9 +238,8 @@ std::ostream& operator<<(std::ostream& s, const LLVolumeMgr& volume_mgr)
272 volume_mgr.mDataMutex->lock(); 238 volume_mgr.mDataMutex->lock();
273 } 239 }
274 240
275 LLVolumeMgr::volume_lod_group_map_iter iter = volume_mgr.mVolumeLODGroups.begin(); 241 for (LLVolumeMgr::volume_lod_group_map_t::const_iterator iter = volume_mgr.mVolumeLODGroups.begin();
276 LLVolumeMgr::volume_lod_group_map_iter end = volume_mgr.mVolumeLODGroups.end(); 242 iter != volume_mgr.mVolumeLODGroups.end(); ++iter)
277 for ( ; iter != end; ++iter)
278 { 243 {
279 LLVolumeLODGroup *volgroupp = iter->second; 244 LLVolumeLODGroup *volgroupp = iter->second;
280 total_refs += volgroupp->getNumRefs(); 245 total_refs += volgroupp->getNumRefs();
@@ -291,72 +256,55 @@ std::ostream& operator<<(std::ostream& s, const LLVolumeMgr& volume_mgr)
291} 256}
292 257
293LLVolumeLODGroup::LLVolumeLODGroup(const LLVolumeParams &params) 258LLVolumeLODGroup::LLVolumeLODGroup(const LLVolumeParams &params)
259 : mVolumeParams(params),
260 mRefs(0)
294{ 261{
295 S32 i; 262 for (S32 i = 0; i < NUM_LODS; i++)
296 mParams = params;
297
298 for (i = 0; i < NUM_LODS; i++)
299 { 263 {
300 mLODRefs[i] = 0; 264 mLODRefs[i] = 0;
301 // no need to initialize mVolumeLODs, they are smart pointers
302 //mVolumeLODs[i] = NULL;
303 mAccessCount[i] = 0; 265 mAccessCount[i] = 0;
304 } 266 }
305} 267}
306 268
307#ifdef DEBUG_VOLUME
308S32 LLVolumeLODGroup::getTotalVolumeRefCount() const
309{
310 S32 total_ref_count = 0;
311 for (S32 i = 0; i < NUM_LODS; i++)
312 {
313 total_ref_count += mLODRefs[i];
314 }
315 return total_ref_count;
316}
317#endif
318
319// protected
320LLVolumeLODGroup::~LLVolumeLODGroup() 269LLVolumeLODGroup::~LLVolumeLODGroup()
321{ 270{
322 destroy();
323}
324
325// protected
326void LLVolumeLODGroup::destroy()
327{
328 for (S32 i = 0; i < NUM_LODS; i++) 271 for (S32 i = 0; i < NUM_LODS; i++)
329 { 272 {
330 // remember that mVolumeLODs are smart pointers! 273 llassert_always(mLODRefs[i] == 0);
331 mVolumeLODs[i] = NULL;
332 } 274 }
333} 275}
334 276
335LLVolume * LLVolumeLODGroup::getLOD(const S32 detail) 277LLVolume* LLVolumeLODGroup::getLODVolume(const S32 detail)
336{ 278{
337 llassert(detail >=0 && detail < NUM_LODS); 279 llassert(detail >=0 && detail < NUM_LODS);
338 mAccessCount[detail]++; 280 mAccessCount[detail]++;
339 281
340 if (!mLODRefs[detail]) 282 mRefs++;
283 if (mVolumeLODs[detail].isNull())
341 { 284 {
342 mVolumeLODs[detail] = new LLVolume(mParams, mDetailScales[detail]); 285 LLMemType m1(LLMemType::MTYPE_VOLUME);
286 mVolumeLODs[detail] = new LLVolume(mVolumeParams, mDetailScales[detail]);
343 } 287 }
344 mLODRefs[detail]++; 288 mLODRefs[detail]++;
345 return mVolumeLODs[detail].get(); 289 return mVolumeLODs[detail];
346} 290}
347 291
348BOOL LLVolumeLODGroup::derefLOD(LLVolume *volumep) 292BOOL LLVolumeLODGroup::derefLOD(LLVolume *volumep)
349{ 293{
350 S32 i; 294 llassert_always(mRefs > 0);
351 for (i = 0; i < NUM_LODS; i++) 295 mRefs--;
296 for (S32 i = 0; i < NUM_LODS; i++)
352 { 297 {
353 if (mVolumeLODs[i] == volumep) 298 if (mVolumeLODs[i] == volumep)
354 { 299 {
300 llassert_always(mLODRefs[i] > 0);
355 mLODRefs[i]--; 301 mLODRefs[i]--;
302#if 1 // SJB: Possible opt: keep other lods around
356 if (!mLODRefs[i]) 303 if (!mLODRefs[i])
357 { 304 {
358 mVolumeLODs[i] = NULL; 305 mVolumeLODs[i] = NULL;
359 } 306 }
307#endif
360 return TRUE; 308 return TRUE;
361 } 309 }
362 } 310 }
@@ -428,7 +376,7 @@ F32 LLVolumeLODGroup::dump()
428std::ostream& operator<<(std::ostream& s, const LLVolumeLODGroup& volgroup) 376std::ostream& operator<<(std::ostream& s, const LLVolumeLODGroup& volgroup)
429{ 377{
430 s << "{ numRefs=" << volgroup.getNumRefs(); 378 s << "{ numRefs=" << volgroup.getNumRefs();
431 s << ", mParams=" << volgroup.mParams; 379 s << ", mParams=" << volgroup.getVolumeParams();
432 s << " }"; 380 s << " }";
433 381
434 return s; 382 return s;
diff --git a/linden/indra/llmath/llvolumemgr.h b/linden/indra/llmath/llvolumemgr.h
index 0a2249e..8f107f6 100644
--- a/linden/indra/llmath/llvolumemgr.h
+++ b/linden/indra/llmath/llvolumemgr.h
@@ -41,8 +41,10 @@
41class LLVolumeParams; 41class LLVolumeParams;
42class LLVolumeLODGroup; 42class LLVolumeLODGroup;
43 43
44class LLVolumeLODGroup : public LLThreadSafeRefCount 44class LLVolumeLODGroup
45{ 45{
46 LOG_CLASS(LLVolumeLODGroup);
47
46public: 48public:
47 enum 49 enum
48 { 50 {
@@ -50,29 +52,25 @@ public:
50 }; 52 };
51 53
52 LLVolumeLODGroup(const LLVolumeParams &params); 54 LLVolumeLODGroup(const LLVolumeParams &params);
55 ~LLVolumeLODGroup();
53 56
54 BOOL derefLOD(LLVolume *volumep);
55 static S32 getDetailFromTan(const F32 tan_angle); 57 static S32 getDetailFromTan(const F32 tan_angle);
56 static void getDetailProximity(const F32 tan_angle, F32 &to_lower, F32& to_higher); 58 static void getDetailProximity(const F32 tan_angle, F32 &to_lower, F32& to_higher);
57 static F32 getVolumeScaleFromDetail(const S32 detail); 59 static F32 getVolumeScaleFromDetail(const S32 detail);
58 60
59 LLVolume *getLOD(const S32 detail); 61 LLVolume* getLODVolume(const S32 detail);
60 const LLVolumeParams& getParams() const { return mParams; }; 62 BOOL derefLOD(LLVolume *volumep);
63 S32 getNumRefs() const { return mRefs; }
64
65 const LLVolumeParams* getVolumeParams() const { return &mVolumeParams; };
61 66
62 F32 dump(); 67 F32 dump();
63 friend std::ostream& operator<<(std::ostream& s, const LLVolumeLODGroup& volgroup); 68 friend std::ostream& operator<<(std::ostream& s, const LLVolumeLODGroup& volgroup);
64 69
65#ifdef DEBUG_VOLUME
66 S32 getTotalVolumeRefCount() const;
67#endif
68
69protected: 70protected:
70 virtual ~LLVolumeLODGroup(); 71 LLVolumeParams mVolumeParams;
71 void destroy();
72
73protected:
74 LLVolumeParams mParams;
75 72
73 S32 mRefs;
76 S32 mLODRefs[NUM_LODS]; 74 S32 mLODRefs[NUM_LODS];
77 LLPointer<LLVolume> mVolumeLODs[NUM_LODS]; 75 LLPointer<LLVolume> mVolumeLODs[NUM_LODS];
78 static F32 mDetailThresholds[NUM_LODS]; 76 static F32 mDetailThresholds[NUM_LODS];
@@ -82,10 +80,6 @@ protected:
82 80
83class LLVolumeMgr 81class LLVolumeMgr
84{ 82{
85//public:
86// static void initClass();
87// static BOOL cleanupClass();
88
89public: 83public:
90 LLVolumeMgr(); 84 LLVolumeMgr();
91 virtual ~LLVolumeMgr(); 85 virtual ~LLVolumeMgr();
@@ -96,36 +90,26 @@ public:
96 // whatever calls getVolume() never owns the LLVolume* and 90 // whatever calls getVolume() never owns the LLVolume* and
97 // cannot keep references for long since it may be deleted 91 // cannot keep references for long since it may be deleted
98 // later. For best results hold it in an LLPointer<LLVolume>. 92 // later. For best results hold it in an LLPointer<LLVolume>.
99 LLVolume *getVolume(const LLVolumeParams &volume_params, const S32 detail); 93 LLVolume *refVolume(const LLVolumeParams &volume_params, const S32 detail);
100 94 void unrefVolume(LLVolume *volumep);
101 void cleanupVolume(LLVolume *volumep);
102 95
103 void dump(); 96 void dump();
104 97
105 // manually call this for mutex magic 98 // manually call this for mutex magic
106 void useMutex(); 99 void useMutex();
107 100
108#ifdef DEBUG_VOLUME
109 S32 getTotalRefCount() const;
110 S32 getGroupCount() const;
111#endif
112 friend std::ostream& operator<<(std::ostream& s, const LLVolumeMgr& volume_mgr); 101 friend std::ostream& operator<<(std::ostream& s, const LLVolumeMgr& volume_mgr);
113 102
114protected: 103protected:
104 void insertGroup(LLVolumeLODGroup* volgroup);
105 // Overridden in llphysics/abstract/utils/llphysicsvolumemanager.h
115 virtual LLVolumeLODGroup* createNewGroup(const LLVolumeParams& volume_params); 106 virtual LLVolumeLODGroup* createNewGroup(const LLVolumeParams& volume_params);
116 107
117protected: 108protected:
118 typedef std::map<const LLVolumeParams*, LLVolumeLODGroup*, LLVolumeParams::compare> volume_lod_group_map_t; 109 typedef std::map<const LLVolumeParams*, LLVolumeLODGroup*, LLVolumeParams::compare> volume_lod_group_map_t;
119 typedef volume_lod_group_map_t::const_iterator volume_lod_group_map_iter;
120 volume_lod_group_map_t mVolumeLODGroups; 110 volume_lod_group_map_t mVolumeLODGroups;
121 111
122 LLMutex* mDataMutex; 112 LLMutex* mDataMutex;
123
124 // We need to be able to disable threadsafe checks to prevent
125 // some unit_tests from blocking on failure
126 bool mThreadSafe;
127}; 113};
128 114
129//extern LLVolumeMgr* gVolumeMgr;
130
131#endif // LL_LLVOLUMEMGR_H 115#endif // LL_LLVOLUMEMGR_H