diff options
author | Jacek Antonelli | 2008-08-15 23:45:42 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:42 -0500 |
commit | ce28e056c20bf2723f565bbf464b87781ec248a2 (patch) | |
tree | ef7b0501c4de4b631a916305cbc2a5fdc125e52d /linden/indra/llmath/llvolume.cpp | |
parent | Second Life viewer sources 1.19.1.4b (diff) | |
download | meta-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.cpp | 269 |
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 | ||
2517 | S32 *LLVolume::getTriangleIndices(U32 &num_indices) const | 2513 | S32 *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; |
3149 | noindices: | 3131 | return index; |
3150 | if (!indices) | 3132 | } |
3133 | |||
3134 | S32 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 | ||
3487 | BOOL equalTriangle(const S32 *a, const S32 *b) | 3517 | BOOL 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 | ||
3900 | const F32 MIN_CONCAVE_PROFILE_WEDGE = 0.125f; // 1/8 unity | ||
3901 | const 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 | ||
3851 | BOOL LLVolumeParams::isConvex() const | 3905 | BOOL 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 | ||
3972 | void 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 | |||
3897 | LLFaceID LLVolume::generateFaceMask() | 3992 | LLFaceID LLVolume::generateFaceMask() |
3898 | { | 3993 | { |
3899 | LLFaceID new_mask = 0x0000; | 3994 | LLFaceID new_mask = 0x0000; |