aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmath/llvolume.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:45:42 -0500
committerJacek Antonelli2008-08-15 23:45:42 -0500
commitce28e056c20bf2723f565bbf464b87781ec248a2 (patch)
treeef7b0501c4de4b631a916305cbc2a5fdc125e52d /linden/indra/llmath/llvolume.cpp
parentSecond Life viewer sources 1.19.1.4b (diff)
downloadmeta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.zip
meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.gz
meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.bz2
meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.xz
Second Life viewer sources 1.20.2
Diffstat (limited to 'linden/indra/llmath/llvolume.cpp')
-rw-r--r--linden/indra/llmath/llvolume.cpp269
1 files changed, 182 insertions, 87 deletions
diff --git a/linden/indra/llmath/llvolume.cpp b/linden/indra/llmath/llvolume.cpp
index 4f1c260..9c19220 100644
--- a/linden/indra/llmath/llvolume.cpp
+++ b/linden/indra/llmath/llvolume.cpp
@@ -1858,9 +1858,6 @@ inline U32 sculpt_xy_to_index(U32 x, U32 y, U16 sculpt_width, U16 sculpt_height,
1858{ 1858{
1859 U32 index = (x + y * sculpt_width) * sculpt_components; 1859 U32 index = (x + y * sculpt_width) * sculpt_components;
1860 1860
1861 // attempt to resolve DEV-11158 - remove assert later.
1862 //llassert(index < sculpt_width * sculpt_height * sculpt_components);
1863
1864 return index; 1861 return index;
1865} 1862}
1866 1863
@@ -2513,12 +2510,19 @@ bool LLVolumeParams::validate(U8 prof_curve, F32 prof_begin, F32 prof_end, F32 h
2513 return true; 2510 return true;
2514} 2511}
2515 2512
2516#define MAX_INDEX 10000
2517S32 *LLVolume::getTriangleIndices(U32 &num_indices) const 2513S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
2518{ 2514{
2519 S32 index[MAX_INDEX]; 2515 S32 expected_num_triangle_indices = getNumTriangleIndices();
2516 if (expected_num_triangle_indices > MAX_VOLUME_TRIANGLE_INDICES)
2517 {
2518 // we don't allow LLVolumes with this many vertices
2519 llwarns << "Couldn't allocate triangle indices" << llendl;
2520 num_indices = 0;
2521 return NULL;
2522 }
2523
2524 S32* index = new S32[expected_num_triangle_indices];
2520 S32 count = 0; 2525 S32 count = 0;
2521 S32 *indices = NULL;
2522 2526
2523 // Let's do this totally diffently, as we don't care about faces... 2527 // Let's do this totally diffently, as we don't care about faces...
2524 // Counter-clockwise triangles are forward facing... 2528 // Counter-clockwise triangles are forward facing...
@@ -2532,6 +2536,9 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
2532 size_s_out = getProfile().getTotalOut(); 2536 size_s_out = getProfile().getTotalOut();
2533 size_t = getPath().mPath.size(); 2537 size_t = getPath().mPath.size();
2534 2538
2539 // NOTE -- if the construction of the triangles below ever changes
2540 // then getNumTriangleIndices() method may also have to be updated.
2541
2535 if (open) /* Flawfinder: ignore */ 2542 if (open) /* Flawfinder: ignore */
2536 { 2543 {
2537 if (hollow) 2544 if (hollow)
@@ -2539,9 +2546,6 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
2539 // Open hollow -- much like the closed solid, except we 2546 // Open hollow -- much like the closed solid, except we
2540 // we need to stitch up the gap between s=0 and s=size_s-1 2547 // we need to stitch up the gap between s=0 and s=size_s-1
2541 2548
2542 if ( (size_t - 1) * (((size_s -1) * 6) + 6) >= MAX_INDEX)
2543 goto noindices;
2544
2545 for (t = 0; t < size_t - 1; t++) 2549 for (t = 0; t < size_t - 1; t++)
2546 { 2550 {
2547 // The outer face, first cut, and inner face 2551 // The outer face, first cut, and inner face
@@ -2655,8 +2659,6 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
2655 2659
2656 if (use_tri1a2) 2660 if (use_tri1a2)
2657 { 2661 {
2658 if (count + 3 >= MAX_INDEX)
2659 goto noindices;
2660 index[count++] = pt1 + i; 2662 index[count++] = pt1 + i;
2661 index[count++] = pt1 + 1 + i; 2663 index[count++] = pt1 + 1 + i;
2662 index[count++] = pt2 + i; 2664 index[count++] = pt2 + i;
@@ -2664,8 +2666,6 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
2664 } 2666 }
2665 else 2667 else
2666 { 2668 {
2667 if (count + 3 >= MAX_INDEX)
2668 goto noindices;
2669 index[count++] = pt1 + i; 2669 index[count++] = pt1 + i;
2670 index[count++] = pt2 - 1 + i; 2670 index[count++] = pt2 - 1 + i;
2671 index[count++] = pt2 + i; 2671 index[count++] = pt2 + i;
@@ -2756,8 +2756,6 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
2756 2756
2757 if (use_tri1a2) 2757 if (use_tri1a2)
2758 { 2758 {
2759 if (count + 3 >= MAX_INDEX)
2760 goto noindices;
2761 index[count++] = pt1; 2759 index[count++] = pt1;
2762 index[count++] = pt2; 2760 index[count++] = pt2;
2763 index[count++] = pt1 + 1; 2761 index[count++] = pt1 + 1;
@@ -2765,8 +2763,6 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
2765 } 2763 }
2766 else 2764 else
2767 { 2765 {
2768 if (count + 3 >= MAX_INDEX)
2769 goto noindices;
2770 index[count++] = pt1; 2766 index[count++] = pt1;
2771 index[count++] = pt2; 2767 index[count++] = pt2;
2772 index[count++] = pt2 - 1; 2768 index[count++] = pt2 - 1;
@@ -2779,9 +2775,6 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
2779 { 2775 {
2780 // Open solid 2776 // Open solid
2781 2777
2782 if ( (size_t - 1) * (((size_s -1) * 6) + 6) >= MAX_INDEX)
2783 goto noindices;
2784
2785 for (t = 0; t < size_t - 1; t++) 2778 for (t = 0; t < size_t - 1; t++)
2786 { 2779 {
2787 // Outer face + 1 cut face 2780 // Outer face + 1 cut face
@@ -2811,8 +2804,6 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
2811 // Do the top and bottom caps, if necessary 2804 // Do the top and bottom caps, if necessary
2812 if (path_open) 2805 if (path_open)
2813 { 2806 {
2814 if ( count + (size_s - 2) * 3 >= MAX_INDEX)
2815 goto noindices;
2816 for (s = 0; s < size_s - 2; s++) 2807 for (s = 0; s < size_s - 2; s++)
2817 { 2808 {
2818 index[count++] = s+1; 2809 index[count++] = s+1;
@@ -2822,8 +2813,6 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
2822 2813
2823 // We've got a top cap 2814 // We've got a top cap
2824 S32 offset = (size_t - 1)*size_s; 2815 S32 offset = (size_t - 1)*size_s;
2825 if ( count + (size_s - 2) * 3 >= MAX_INDEX)
2826 goto noindices;
2827 for (s = 0; s < size_s - 2; s++) 2816 for (s = 0; s < size_s - 2; s++)
2828 { 2817 {
2829 // Inverted ordering from bottom cap. 2818 // Inverted ordering from bottom cap.
@@ -2839,8 +2828,6 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
2839 // Closed hollow 2828 // Closed hollow
2840 // Outer face 2829 // Outer face
2841 2830
2842 if ( (size_t - 1) * (size_s_out - 1) * 6 >= MAX_INDEX)
2843 goto noindices;
2844 for (t = 0; t < size_t - 1; t++) 2831 for (t = 0; t < size_t - 1; t++)
2845 { 2832 {
2846 for (s = 0; s < size_s_out - 1; s++) 2833 for (s = 0; s < size_s_out - 1; s++)
@@ -2859,8 +2846,6 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
2859 2846
2860 // Inner face 2847 // Inner face
2861 // Invert facing from outer face 2848 // Invert facing from outer face
2862 if ( count + (size_t - 1) * ((size_s - 1) - size_s_out) * 6 >= MAX_INDEX)
2863 goto noindices;
2864 for (t = 0; t < size_t - 1; t++) 2849 for (t = 0; t < size_t - 1; t++)
2865 { 2850 {
2866 for (s = size_s_out; s < size_s - 1; s++) 2851 for (s = size_s_out; s < size_s - 1; s++)
@@ -2965,8 +2950,6 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
2965 2950
2966 if (use_tri1a2) 2951 if (use_tri1a2)
2967 { 2952 {
2968 if (count + 3 >= MAX_INDEX)
2969 goto noindices;
2970 index[count++] = pt1 + i; 2953 index[count++] = pt1 + i;
2971 index[count++] = pt1 + 1 + i; 2954 index[count++] = pt1 + 1 + i;
2972 index[count++] = pt2 + i; 2955 index[count++] = pt2 + i;
@@ -2974,8 +2957,6 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
2974 } 2957 }
2975 else 2958 else
2976 { 2959 {
2977 if (count + 3 >= MAX_INDEX)
2978 goto noindices;
2979 index[count++] = pt1 + i; 2960 index[count++] = pt1 + i;
2980 index[count++] = pt2 - 1 + i; 2961 index[count++] = pt2 - 1 + i;
2981 index[count++] = pt2 + i; 2962 index[count++] = pt2 + i;
@@ -3066,8 +3047,6 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
3066 3047
3067 if (use_tri1a2) 3048 if (use_tri1a2)
3068 { 3049 {
3069 if (count + 3 >= MAX_INDEX)
3070 goto noindices;
3071 index[count++] = pt1; 3050 index[count++] = pt1;
3072 index[count++] = pt2; 3051 index[count++] = pt2;
3073 index[count++] = pt1 + 1; 3052 index[count++] = pt1 + 1;
@@ -3075,8 +3054,6 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
3075 } 3054 }
3076 else 3055 else
3077 { 3056 {
3078 if (count + 3 >= MAX_INDEX)
3079 goto noindices;
3080 index[count++] = pt1; 3057 index[count++] = pt1;
3081 index[count++] = pt2; 3058 index[count++] = pt2;
3082 index[count++] = pt2 - 1; 3059 index[count++] = pt2 - 1;
@@ -3088,8 +3065,6 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
3088 else 3065 else
3089 { 3066 {
3090 // Closed solid. Easy case. 3067 // Closed solid. Easy case.
3091 if ( (size_t - 1) * (size_s - 1) * 6 > MAX_INDEX)
3092 goto noindices;
3093 for (t = 0; t < size_t - 1; t++) 3068 for (t = 0; t < size_t - 1; t++)
3094 { 3069 {
3095 for (s = 0; s < size_s - 1; s++) 3070 for (s = 0; s < size_s - 1; s++)
@@ -3111,8 +3086,6 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
3111 if (path_open) 3086 if (path_open)
3112 { 3087 {
3113 // bottom cap 3088 // bottom cap
3114 if ( count + (size_s - 2 - 1) * 3 >= MAX_INDEX)
3115 goto noindices;
3116 for (s = 1; s < size_s - 2; s++) 3089 for (s = 1; s < size_s - 2; s++)
3117 { 3090 {
3118 index[count++] = s+1; 3091 index[count++] = s+1;
@@ -3122,8 +3095,6 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
3122 3095
3123 // top cap 3096 // top cap
3124 S32 offset = (size_t - 1)*size_s; 3097 S32 offset = (size_t - 1)*size_s;
3125 if ( count + (size_s - 2 - 1) * 3 >= MAX_INDEX)
3126 goto noindices;
3127 for (s = 1; s < size_s - 2; s++) 3098 for (s = 1; s < size_s - 2; s++)
3128 { 3099 {
3129 // Inverted ordering from bottom cap. 3100 // Inverted ordering from bottom cap.
@@ -3134,7 +3105,18 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
3134 } 3105 }
3135 } 3106 }
3136 3107
3108#ifdef LL_DEBUG
3109 // assert that we computed the correct number of indices
3110 if (count != expected_num_triangle_indices )
3111 {
3112 llerrs << "bad index count prediciton:"
3113 << " expected=" << expected_num_triangle_indices
3114 << " actual=" << count << llendl;
3115 }
3116#endif
3117
3137#if 0 3118#if 0
3119 // verify that each index does not point beyond the size of the mesh
3138 S32 num_vertices = mMesh.size(); 3120 S32 num_vertices = mMesh.size();
3139 for (i = 0; i < count; i+=3) 3121 for (i = 0; i < count; i+=3)
3140 { 3122 {
@@ -3145,17 +3127,65 @@ S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
3145 } 3127 }
3146#endif 3128#endif
3147 3129
3148 indices = new S32[count]; 3130 num_indices = count;
3149noindices: 3131 return index;
3150 if (!indices) 3132}
3133
3134S32 LLVolume::getNumTriangleIndices() const
3135{
3136 BOOL profile_open = getProfile().isOpen();
3137 BOOL hollow = getProfile().isHollow();
3138 BOOL path_open = getPath().isOpen();
3139
3140 S32 size_s, size_s_out, size_t;
3141 size_s = getProfile().getTotal();
3142 size_s_out = getProfile().getTotalOut();
3143 size_t = getPath().mPath.size();
3144
3145 S32 count = 0;
3146 if (profile_open) /* Flawfinder: ignore */
3151 { 3147 {
3152 llwarns << "Couldn't allocate triangle indices" << llendl; 3148 if (hollow)
3153 num_indices = 0; 3149 {
3154 return NULL; 3150 // Open hollow -- much like the closed solid, except we
3151 // we need to stitch up the gap between s=0 and s=size_s-1
3152 count = (size_t - 1) * (((size_s -1) * 6) + 6);
3153 }
3154 else
3155 {
3156 count = (size_t - 1) * (((size_s -1) * 6) + 6);
3157 }
3155 } 3158 }
3156 num_indices = count; 3159 else if (hollow)
3157 memcpy(indices, index, count * sizeof(S32)); /* Flawfinder: ignore */ 3160 {
3158 return indices; 3161 // Closed hollow
3162 // Outer face
3163 count = (size_t - 1) * (size_s_out - 1) * 6;
3164
3165 // Inner face
3166 count += (size_t - 1) * ((size_s - 1) - size_s_out) * 6;
3167 }
3168 else
3169 {
3170 // Closed solid. Easy case.
3171 count = (size_t - 1) * (size_s - 1) * 6;
3172 }
3173
3174 if (path_open)
3175 {
3176 S32 cap_triangle_count = size_s - 3;
3177 if ( profile_open
3178 || hollow )
3179 {
3180 cap_triangle_count = size_s - 2;
3181 }
3182 if ( cap_triangle_count > 0 )
3183 {
3184 // top and bottom caps
3185 count += cap_triangle_count * 2 * 3;
3186 }
3187 }
3188 return count;
3159} 3189}
3160 3190
3161//----------------------------------------------------------------------------- 3191//-----------------------------------------------------------------------------
@@ -3486,7 +3516,7 @@ struct lessTriangle
3486 3516
3487BOOL equalTriangle(const S32 *a, const S32 *b) 3517BOOL equalTriangle(const S32 *a, const S32 *b)
3488{ 3518{
3489 if ((*a == *b) && (*(a+1) == *(b+1)) && ((*a+2) == (*b+2))) 3519 if ((*a == *b) && (*(a+1) == *(b+1)) && (*(a+2) == *(b+2)))
3490 { 3520 {
3491 return TRUE; 3521 return TRUE;
3492 } 3522 }
@@ -3502,6 +3532,21 @@ BOOL LLVolume::cleanupTriangleData( const S32 num_input_vertices,
3502 S32 &num_output_triangles, 3532 S32 &num_output_triangles,
3503 S32 **output_triangles) 3533 S32 **output_triangles)
3504{ 3534{
3535 /* Testing: avoid any cleanup
3536 num_output_vertices = num_input_vertices;
3537 num_output_triangles = num_input_triangles;
3538
3539 *output_vertices = new LLVector3[num_input_vertices];
3540 for (S32 i = 0; i < num_input_vertices; i++)
3541 {
3542 (*output_vertices)[i] = input_vertices[i].mPos;
3543 }
3544
3545 *output_triangles = new S32[num_input_triangles*3];
3546 memcpy(*output_triangles, input_triangles, 3*num_input_triangles*sizeof(S32)); // Flawfinder: ignore
3547 return TRUE;
3548 */
3549
3505 // Here's how we do this: 3550 // Here's how we do this:
3506 // Create a structure which contains the original vertex index and the 3551 // Create a structure which contains the original vertex index and the
3507 // LLVector3 data. 3552 // LLVector3 data.
@@ -3552,7 +3597,7 @@ BOOL LLVolume::cleanupTriangleData( const S32 num_input_vertices,
3552 } 3597 }
3553 else 3598 else
3554 { 3599 {
3555 //llinfos << "Removed duplicate vertex " << pairp->mVertex << llendl; 3600 //llinfos << "Removed duplicate vertex " << pairp->mVertex << ", distance magVecSquared() is " << (pairp->mVertex - prev_pairp->mVertex).magVecSquared() << llendl;
3556 } 3601 }
3557 vertex_mapping[pairp->mIndex] = new_num_vertices - 1; 3602 vertex_mapping[pairp->mIndex] = new_num_vertices - 1;
3558 } 3603 }
@@ -3564,50 +3609,54 @@ BOOL LLVolume::cleanupTriangleData( const S32 num_input_vertices,
3564 3609
3565 for (i = 0; i < num_input_triangles; i++) 3610 for (i = 0; i < num_input_triangles; i++)
3566 { 3611 {
3567 //llinfos << "Checking triangle " << input_triangles[i*3] << ":" << input_triangles[i*3+1] << ":" << input_triangles[i*3+2] << llendl; 3612 S32 v1 = i*3;
3568 input_triangles[i*3] = vertex_mapping[input_triangles[i*3]]; 3613 S32 v2 = i*3 + 1;
3569 input_triangles[i*3+1] = vertex_mapping[input_triangles[i*3+1]]; 3614 S32 v3 = i*3 + 2;
3570 input_triangles[i*3+2] = vertex_mapping[input_triangles[i*3+2]]; 3615
3616 //llinfos << "Checking triangle " << input_triangles[v1] << ":" << input_triangles[v2] << ":" << input_triangles[v3] << llendl;
3617 input_triangles[v1] = vertex_mapping[input_triangles[v1]];
3618 input_triangles[v2] = vertex_mapping[input_triangles[v2]];
3619 input_triangles[v3] = vertex_mapping[input_triangles[v3]];
3571 3620
3572 if ((input_triangles[i*3] == input_triangles[i*3+1]) 3621 if ((input_triangles[v1] == input_triangles[v2])
3573 || (input_triangles[i*3] == input_triangles[i*3+2]) 3622 || (input_triangles[v1] == input_triangles[v3])
3574 || (input_triangles[i*3+1] == input_triangles[i*3+2])) 3623 || (input_triangles[v2] == input_triangles[v3]))
3575 { 3624 {
3576 //llinfos << "Removing degenerate triangle " << input_triangles[i*3] << ":" << input_triangles[i*3+1] << ":" << input_triangles[i*3+2] << llendl; 3625 //llinfos << "Removing degenerate triangle " << input_triangles[v1] << ":" << input_triangles[v2] << ":" << input_triangles[v3] << llendl;
3577 // Degenerate triangle, skip 3626 // Degenerate triangle, skip
3578 continue; 3627 continue;
3579 } 3628 }
3580 3629
3581 if (input_triangles[i*3] < input_triangles[i*3+1]) 3630 if (input_triangles[v1] < input_triangles[v2])
3582 { 3631 {
3583 if (input_triangles[i*3] < input_triangles[i*3+2]) 3632 if (input_triangles[v1] < input_triangles[v3])
3584 { 3633 {
3585 // (0 < 1) && (0 < 2) 3634 // (0 < 1) && (0 < 2)
3586 new_triangles[new_num_triangles*3] = input_triangles[i*3]; 3635 new_triangles[new_num_triangles*3] = input_triangles[v1];
3587 new_triangles[new_num_triangles*3+1] = input_triangles[i*3+1]; 3636 new_triangles[new_num_triangles*3+1] = input_triangles[v2];
3588 new_triangles[new_num_triangles*3+2] = input_triangles[i*3+2]; 3637 new_triangles[new_num_triangles*3+2] = input_triangles[v3];
3589 } 3638 }
3590 else 3639 else
3591 { 3640 {
3592 // (0 < 1) && (2 < 0) 3641 // (0 < 1) && (2 < 0)
3593 new_triangles[new_num_triangles*3] = input_triangles[i*3+2]; 3642 new_triangles[new_num_triangles*3] = input_triangles[v3];
3594 new_triangles[new_num_triangles*3+1] = input_triangles[i*3]; 3643 new_triangles[new_num_triangles*3+1] = input_triangles[v1];
3595 new_triangles[new_num_triangles*3+2] = input_triangles[i*3+1]; 3644 new_triangles[new_num_triangles*3+2] = input_triangles[v2];
3596 } 3645 }
3597 } 3646 }
3598 else if (input_triangles[i*3+1] < input_triangles[i*3+2]) 3647 else if (input_triangles[v2] < input_triangles[v3])
3599 { 3648 {
3600 // (1 < 0) && (1 < 2) 3649 // (1 < 0) && (1 < 2)
3601 new_triangles[new_num_triangles*3] = input_triangles[i*3+1]; 3650 new_triangles[new_num_triangles*3] = input_triangles[v2];
3602 new_triangles[new_num_triangles*3+1] = input_triangles[i*3+2]; 3651 new_triangles[new_num_triangles*3+1] = input_triangles[v3];
3603 new_triangles[new_num_triangles*3+2] = input_triangles[i*3]; 3652 new_triangles[new_num_triangles*3+2] = input_triangles[v1];
3604 } 3653 }
3605 else 3654 else
3606 { 3655 {
3607 // (1 < 0) && (2 < 1) 3656 // (1 < 0) && (2 < 1)
3608 new_triangles[new_num_triangles*3] = input_triangles[i*3+2]; 3657 new_triangles[new_num_triangles*3] = input_triangles[v3];
3609 new_triangles[new_num_triangles*3+1] = input_triangles[i*3]; 3658 new_triangles[new_num_triangles*3+1] = input_triangles[v1];
3610 new_triangles[new_num_triangles*3+2] = input_triangles[i*3+1]; 3659 new_triangles[new_num_triangles*3+2] = input_triangles[v2];
3611 } 3660 }
3612 new_num_triangles++; 3661 new_num_triangles++;
3613 } 3662 }
@@ -3848,23 +3897,44 @@ void LLVolumeParams::reduceT(F32 begin, F32 end)
3848 mPathParams.setEnd(a + end * (b - a)); 3897 mPathParams.setEnd(a + end * (b - a));
3849} 3898}
3850 3899
3900const F32 MIN_CONCAVE_PROFILE_WEDGE = 0.125f; // 1/8 unity
3901const F32 MIN_CONCAVE_PATH_WEDGE = 0.111111f; // 1/9 unity
3902
3903// returns TRUE if the shape can be approximated with a convex shape
3904// for collison purposes
3851BOOL LLVolumeParams::isConvex() const 3905BOOL LLVolumeParams::isConvex() const
3852{ 3906{
3853 // The logic for determining convexity is a little convoluted. 3907 F32 path_length = mPathParams.getEnd() - mPathParams.getBegin();
3854 3908
3855 // Do we need to take getTwistBegin into account? DK 08/12/04 3909 if ( mPathParams.getTwist() != mPathParams.getTwistBegin()
3856 if ( mProfileParams.getHollow() != 0.0f 3910 && path_length > MIN_CONCAVE_PATH_WEDGE )
3857 || mPathParams.getTwist() != mPathParams.getTwistBegin() )
3858 { 3911 {
3859 // hollow or twist gaurantees concavity 3912 // twist along a "not too short" path is concave
3860 return FALSE; 3913 return FALSE;
3861 } 3914 }
3862 3915
3863 F32 profile_length = mProfileParams.getEnd() - mProfileParams.getBegin(); 3916 F32 profile_length = mProfileParams.getEnd() - mProfileParams.getBegin();
3864 BOOL concave_profile = (profile_length < 1.0f) && (profile_length > 0.5f); 3917 F32 hollow = mProfileParams.getHollow();
3865 if (concave_profile) 3918 BOOL same_hole = hollow == 0.f
3919 || (mProfileParams.getCurveType() & LL_PCODE_HOLE_MASK) == LL_PCODE_HOLE_SAME;
3920
3921 F32 min_profile_wedge = MIN_CONCAVE_PROFILE_WEDGE;
3922 U8 profile_type = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK;
3923 if ( LL_PCODE_PROFILE_CIRCLE_HALF == profile_type )
3866 { 3924 {
3867 // concave profile 3925 // it is a sphere and spheres get twice the minimum profile wedge
3926 min_profile_wedge = 2.f * MIN_CONCAVE_PROFILE_WEDGE;
3927 }
3928
3929 BOOL convex_profile = ( ( profile_length == 1.f
3930 || profile_length <= 0.5f )
3931 && hollow == 0.f ) // trivially convex
3932 || ( profile_length <= min_profile_wedge
3933 && same_hole ); // effectvely convex (even when hollow)
3934
3935 if (!convex_profile)
3936 {
3937 // profile is concave
3868 return FALSE; 3938 return FALSE;
3869 } 3939 }
3870 3940
@@ -3875,7 +3945,6 @@ BOOL LLVolumeParams::isConvex() const
3875 return TRUE; 3945 return TRUE;
3876 } 3946 }
3877 3947
3878 F32 path_length = mPathParams.getEnd() - mPathParams.getBegin();
3879 BOOL concave_path = (path_length < 1.0f) && (path_length > 0.5f); 3948 BOOL concave_path = (path_length < 1.0f) && (path_length > 0.5f);
3880 if (concave_path) 3949 if (concave_path)
3881 { 3950 {
@@ -3883,17 +3952,43 @@ BOOL LLVolumeParams::isConvex() const
3883 } 3952 }
3884 3953
3885 // we're left with spheres, toroids and tubes 3954 // we're left with spheres, toroids and tubes
3886 // only the spheres can be convex
3887 U8 profile_type = mProfileParams.getCurveType() & LL_PCODE_PROFILE_MASK;
3888 if ( LL_PCODE_PROFILE_CIRCLE_HALF == profile_type ) 3955 if ( LL_PCODE_PROFILE_CIRCLE_HALF == profile_type )
3889 { 3956 {
3957 // at this stage all spheres must be convex
3890 return TRUE; 3958 return TRUE;
3891 } 3959 }
3892 3960
3893 // it's a toroid or tube 3961 // it's a toroid or tube
3962 if ( path_length <= MIN_CONCAVE_PATH_WEDGE )
3963 {
3964 // effectively convex
3965 return TRUE;
3966 }
3967
3894 return FALSE; 3968 return FALSE;
3895} 3969}
3896 3970
3971// debug
3972void LLVolumeParams::setCube()
3973{
3974 mProfileParams.setCurveType(LL_PCODE_PROFILE_SQUARE);
3975 mProfileParams.setBegin(0.f);
3976 mProfileParams.setEnd(1.f);
3977 mProfileParams.setHollow(0.f);
3978
3979 mPathParams.setBegin(0.f);
3980 mPathParams.setEnd(1.f);
3981 mPathParams.setScale(1.f, 1.f);
3982 mPathParams.setShear(0.f, 0.f);
3983 mPathParams.setCurveType(LL_PCODE_PATH_LINE);
3984 mPathParams.setTwistBegin(0.f);
3985 mPathParams.setTwistEnd(0.f);
3986 mPathParams.setRadiusOffset(0.f);
3987 mPathParams.setTaper(0.f, 0.f);
3988 mPathParams.setRevolutions(0.f);
3989 mPathParams.setSkew(0.f);
3990}
3991
3897LLFaceID LLVolume::generateFaceMask() 3992LLFaceID LLVolume::generateFaceMask()
3898{ 3993{
3899 LLFaceID new_mask = 0x0000; 3994 LLFaceID new_mask = 0x0000;