diff options
author | Steven Bennetts <steve@lindenlab.com> | 2008-03-11 01:47:36 +0000 |
---|---|---|
committer | Steven Bennetts <steve@lindenlab.com> | 2008-03-11 01:47:36 +0000 |
commit | 377ae59c21215473cf05e3cb8a86eb14c9e7715c (patch) | |
tree | a8cb48901c3c30bc1c2ddfd5d8b2d0cab7c6c95d /indra/llmath/llvolume.cpp | |
parent | 9d12bd5e273b8cb032e25574461a8b4528d96343 (diff) |
merge Branch_1-19-1-Viewer -r 80930 : 81609 -> release
DEV-11202: Unhandled Excpetion in pipeline.cpp.
Merged over updated windlight ui help text from windlight14.
Reverting a const change in a virtual that was not propagated to all overrides.
DEV-10957 stop and pause Media and music buttons do not work
DEV-10762 Displayed page in the client browser disappears when crossing property boundaries.
DEV-11220 replace misspellings in alerts.xml parameters of 'messsage'
DEV-11221 fix a misspelling of 'participants' in floater_chat_history.xml tooltip
DEV-11193 clean up some viewer strings related to Windlight help text
svn merge -r81144:81147 svn+ssh://svn/svn/linden/branches/1-19-1-viewer-threads
DEV-11110 Media browser history dropdown does not save items across sessions
Ran the xuiparse -process tool on all en-us xml files. This does NOT change any data, merely reorders attributes and cleans up tab/spacing.
DEV-11349 XML CLEANUP: fix duplicate sibling names in en-us xui files
DEV-11348 Change to llmimetypes.cpp broke Media Type dropdown
dev-10623 "parcels that played movies no longer work in combo-merge-ui"
DEV-11379 - crash in LLTabContainer::draw()
DEV-11377 Elminiate dangerous LLLinkedList and LLDoubleLinkedList from newview
DEV-11158 sculpties on the top10 crash list
DEV-11404 "Send Current URL to Parcel" does not set the MIME type
merge 80958:80959 maint-ui-9-qa, DEV-11105 -- Searching for people with 3 characters like "j l" hurts the database.
DEV-10489: no draw distance cheating
DEV-879: water noise frequency
DEV-10764: macbook air support
DEV-10878: Linux Intel945 support
DEV-7551: featuretable adjustments for framerate.
DEV-11426 Enormous mini-map.
DEV-11505 - Crash in gunzip_file.
Removed final LinkedList, SkipMap, and AssocList templates from the Viewer!
DEV-11115 truncated word in the Advanced Water Editor's modal help dialog
Diffstat (limited to 'indra/llmath/llvolume.cpp')
-rw-r--r-- | indra/llmath/llvolume.cpp | 269 |
1 files changed, 168 insertions, 101 deletions
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index ab2eef0ee9..44fef9daf6 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1854,55 +1854,70 @@ inline LLVector3 sculpt_rgb_to_vector(U8 r, U8 g, U8 b) return value; } +inline U32 sculpt_xy_to_index(U32 x, U32 y, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components) +{ + U32 index = (x + y * sculpt_width) * sculpt_components; -// sculpt replaces generate() for sculpted surfaces -void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level) + // attempt to resolve DEV-11158 - remove assert later. + llassert(index < sculpt_width * sculpt_height * sculpt_components); + + return index; +} + + +inline U32 sculpt_st_to_index(S32 s, S32 t, S32 size_s, S32 size_t, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components) { - U8 sculpt_type = mParams.getSculptType(); + U32 x = (U32) ((F32)s/(size_s) * (F32) sculpt_width); + U32 y = (U32) ((F32)t/(size_t) * (F32) sculpt_height); - BOOL data_is_empty = FALSE; + return sculpt_xy_to_index(x, y, sculpt_width, sculpt_height, sculpt_components); +} - if (sculpt_width == 0 || sculpt_height == 0 || sculpt_data == NULL) - { - sculpt_level = -1; - data_is_empty = TRUE; - } - mPathp->generate(mDetail, 0, TRUE); - mProfilep->generate(mPathp->isOpen(), mDetail, 0, TRUE); - +inline LLVector3 sculpt_index_to_vector(U32 index, const U8* sculpt_data) +{ + LLVector3 v = sculpt_rgb_to_vector(sculpt_data[index], sculpt_data[index+1], sculpt_data[index+2]); + + return v; +} + +inline LLVector3 sculpt_st_to_vector(S32 s, S32 t, S32 size_s, S32 size_t, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data) +{ + U32 index = sculpt_st_to_index(s, t, size_s, size_t, sculpt_width, sculpt_height, sculpt_components); + + return sculpt_index_to_vector(index, sculpt_data); +} + +inline LLVector3 sculpt_xy_to_vector(U32 x, U32 y, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data) +{ + U32 index = sculpt_xy_to_index(x, y, sculpt_width, sculpt_height, sculpt_components); + + return sculpt_index_to_vector(index, sculpt_data); +} + + +F32 LLVolume::sculptGetSurfaceArea(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data) +{ + // test to see if image has enough variation to create non-degenerate geometry + S32 sizeS = mPathp->mPath.size(); S32 sizeT = mProfilep->mProfile.size(); - sNumMeshPoints -= mMesh.size(); - mMesh.resize(sizeS * sizeT); - sNumMeshPoints += mMesh.size(); - F32 area = 0; - // first test to see if image has enough variation to create non-degenerate geometry - if (!data_is_empty) + + if ((sculpt_width != 0) && + (sculpt_height != 0) && + (sculpt_components != 0) && + (sculpt_data != NULL)) { for (S32 s = 0; s < sizeS - 1; s++) { for (S32 t = 0; t < sizeT - 1; t++) { - // first coordinate - U32 x = (U32) ((F32)s/(sizeS) * (F32) sculpt_width); - U32 y = (U32) ((F32)t/(sizeT) * (F32) sculpt_height); - - // coordinate offset by 1 - U32 x2 = (U32) ((F32)(s+1)/(sizeS) * (F32) sculpt_width); - U32 y2 = (U32) ((F32)(t+1)/(sizeT) * (F32) sculpt_height); - - // three points on a triagle - find the image indices first - U32 p1_index = (x + y * sculpt_width) * sculpt_components; - U32 p2_index = (x2 + y * sculpt_width) * sculpt_components; - U32 p3_index = (x + y2 * sculpt_width) * sculpt_components; - // convert image data to vectors - LLVector3 p1 = sculpt_rgb_to_vector(sculpt_data[p1_index], sculpt_data[p1_index+1], sculpt_data[p1_index+2]); - LLVector3 p2 = sculpt_rgb_to_vector(sculpt_data[p2_index], sculpt_data[p2_index+1], sculpt_data[p2_index+2]); - LLVector3 p3 = sculpt_rgb_to_vector(sculpt_data[p3_index], sculpt_data[p3_index+1], sculpt_data[p3_index+2]); + LLVector3 p1 = sculpt_st_to_vector(s, t, sizeS, sizeT, sculpt_width, sculpt_height, sculpt_components, sculpt_data); + LLVector3 p2 = sculpt_st_to_vector(s+1, t, sizeS, sizeT, sculpt_width, sculpt_height, sculpt_components, sculpt_data); + LLVector3 p3 = sculpt_st_to_vector(s, t+1, sizeS, sizeT, sculpt_width, sculpt_height, sculpt_components, sculpt_data); // compute the area of the parallelogram by taking the length of the cross product: // (parallegram is an approximation of two triangles) @@ -1910,99 +1925,151 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, area += cross.magVec(); } } - if (area < SCULPT_MIN_AREA) - data_is_empty = TRUE; } - //generate vertex positions - if (data_is_empty) // if empty, make a sphere - { - S32 line = 0; + return area; +} + +// create placeholder shape +void LLVolume::sculptGeneratePlaceholder() +{ + S32 sizeS = mPathp->mPath.size(); + S32 sizeT = mProfilep->mProfile.size(); + + S32 line = 0; - for (S32 s = 0; s < sizeS; s++) + // for now, this is a sphere. + for (S32 s = 0; s < sizeS; s++) + { + for (S32 t = 0; t < sizeT; t++) { - for (S32 t = 0; t < sizeT; t++) - { - S32 i = t + line; - Point& pt = mMesh[i]; + S32 i = t + line; + Point& pt = mMesh[i]; - F32 u = (F32)s/(sizeS-1); - F32 v = (F32)t/(sizeT-1); + F32 u = (F32)s/(sizeS-1); + F32 v = (F32)t/(sizeT-1); - const F32 RADIUS = (F32) 0.3; + const F32 RADIUS = (F32) 0.3; - pt.mPos.mV[0] = (F32)(sin(F_PI * v) * cos(2.0 * F_PI * u) * RADIUS); - pt.mPos.mV[1] = (F32)(sin(F_PI * v) * sin(2.0 * F_PI * u) * RADIUS); - pt.mPos.mV[2] = (F32)(cos(F_PI * v) * RADIUS); + pt.mPos.mV[0] = (F32)(sin(F_PI * v) * cos(2.0 * F_PI * u) * RADIUS); + pt.mPos.mV[1] = (F32)(sin(F_PI * v) * sin(2.0 * F_PI * u) * RADIUS); + pt.mPos.mV[2] = (F32)(cos(F_PI * v) * RADIUS); - } - line += sizeT; } - } - else + line += sizeT; + } +} + +// create the vertices from the map +void LLVolume::sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type) +{ + S32 sizeS = mPathp->mPath.size(); + S32 sizeT = mProfilep->mProfile.size(); + + S32 line = 0; + for (S32 s = 0; s < sizeS; s++) { - S32 line = 0; - for (S32 s = 0; s < sizeS; s++) + // Run along the profile. + for (S32 t = 0; t < sizeT; t++) { - // Run along the profile. - for (S32 t = 0; t < sizeT; t++) - { - S32 i = t + line; - Point& pt = mMesh[i]; + S32 i = t + line; + Point& pt = mMesh[i]; - U32 x = (U32) ((F32)t/(sizeT-1) * (F32) sculpt_width); - U32 y = (U32) ((F32)s/(sizeS-1) * (F32) sculpt_height); + U32 x = (U32) ((F32)t/(sizeT-1) * (F32) sculpt_width); + U32 y = (U32) ((F32)s/(sizeS-1) * (F32) sculpt_height); - if (y == 0) // top row stitching + if (y == 0) // top row stitching + { + // pinch? + if (sculpt_type == LL_SCULPT_TYPE_SPHERE) { - // pinch? - if (sculpt_type == LL_SCULPT_TYPE_SPHERE) - { - x = sculpt_width / 2; - } + x = sculpt_width / 2; } + } - if (y == sculpt_height) // bottom row stitching + if (y == sculpt_height) // bottom row stitching + { + // wrap? + if (sculpt_type == LL_SCULPT_TYPE_TORUS) { - // wrap? - if (sculpt_type == LL_SCULPT_TYPE_TORUS) - { - y = 0; - } - else - { - y = sculpt_height - 1; - } + y = 0; + } + else + { + y = sculpt_height - 1; + } - // pinch? - if (sculpt_type == LL_SCULPT_TYPE_SPHERE) - { - x = sculpt_width / 2; - } + // pinch? + if (sculpt_type == LL_SCULPT_TYPE_SPHERE) + { + x = sculpt_width / 2; } + } - if (x == sculpt_width) // side stitching + if (x == sculpt_width) // side stitching + { + // wrap? + if ((sculpt_type == LL_SCULPT_TYPE_SPHERE) || + (sculpt_type == LL_SCULPT_TYPE_TORUS) || + (sculpt_type == LL_SCULPT_TYPE_CYLINDER)) { - // wrap? - if ((sculpt_type == LL_SCULPT_TYPE_SPHERE) || - (sculpt_type == LL_SCULPT_TYPE_TORUS) || - (sculpt_type == LL_SCULPT_TYPE_CYLINDER)) - { - x = 0; - } + x = 0; + } - else - { - x = sculpt_width - 1; - } + else + { + x = sculpt_width - 1; } - - U32 index = (x + y * sculpt_width) * sculpt_components; - pt.mPos = sculpt_rgb_to_vector(sculpt_data[index], sculpt_data[index+1], sculpt_data[index+2]); } - line += sizeT; + + pt.mPos = sculpt_xy_to_vector(x, y, sculpt_width, sculpt_height, sculpt_components, sculpt_data); } + line += sizeT; + } +} + + +// sculpt replaces generate() for sculpted surfaces +void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level) +{ + U8 sculpt_type = mParams.getSculptType(); + + BOOL data_is_empty = FALSE; + + if (sculpt_width == 0 || sculpt_height == 0 || sculpt_components == 0 || sculpt_data == NULL) + { + sculpt_level = -1; + data_is_empty = TRUE; + } + + mPathp->generate(mDetail, 0, TRUE); + mProfilep->generate(mPathp->isOpen(), mDetail, 0, TRUE); + + S32 sizeS = mPathp->mPath.size(); + S32 sizeT = mProfilep->mProfile.size(); + + // weird crash bug - DEV-11158 - trying to collect more data: + if ((sizeS == 0) || (sizeT == 0)) + { + llwarns << "sculpt bad mesh size " << sizeS << " " << sizeT << llendl; + } + + sNumMeshPoints -= mMesh.size(); + mMesh.resize(sizeS * sizeT); + sNumMeshPoints += mMesh.size(); + + if (sculptGetSurfaceArea(sculpt_width, sculpt_height, sculpt_components, sculpt_data) < SCULPT_MIN_AREA) + data_is_empty = TRUE; + + //generate vertex positions + if (data_is_empty) // if empty, make a placeholder mesh + { + sculptGeneratePlaceholder(); + } + else + { + sculptGenerateMapVertices(sculpt_width, sculpt_height, sculpt_components, sculpt_data, sculpt_type); } for (S32 i = 0; i < (S32)mProfilep->mFaces.size(); i++) |