summaryrefslogtreecommitdiff
path: root/indra/llmath
diff options
context:
space:
mode:
authorAdam Moss <moss@lindenlab.com>2009-02-03 17:56:26 +0000
committerAdam Moss <moss@lindenlab.com>2009-02-03 17:56:26 +0000
commite188badaf29a1a02307f93864eed6737096bd9a1 (patch)
tree767259ad3385fd9ede9722e04752bea008469f8c /indra/llmath
parent4ad54702fce32905402cb6055c085ac14de188a2 (diff)
QAR-1177 maint-viewer-12 + uploadfees-viewer combo mergeme
svn merge -r108355:109316 svn+ssh://svn.lindenlab.com/svn/linden/branches/moss/maint-viewer-12-uploadfees-qa108314 Whew.
Diffstat (limited to 'indra/llmath')
-rw-r--r--indra/llmath/llvolume.cpp84
-rw-r--r--indra/llmath/llvolume.h2
2 files changed, 50 insertions, 36 deletions
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 7d01ba059c..1250f539f5 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -1973,34 +1973,29 @@ inline LLVector3 sculpt_xy_to_vector(U32 x, U32 y, U16 sculpt_width, U16 sculpt_
}
-F32 LLVolume::sculptGetSurfaceArea(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data)
+F32 LLVolume::sculptGetSurfaceArea()
{
// test to see if image has enough variation to create non-degenerate geometry
+ F32 area = 0;
+
S32 sizeS = mPathp->mPath.size();
S32 sizeT = mProfilep->mProfile.size();
-
- F32 area = 0;
-
- if ((sculpt_width != 0) &&
- (sculpt_height != 0) &&
- (sculpt_components != 0) &&
- (sculpt_data != NULL))
+
+ for (S32 s = 0; s < sizeS-1; s++)
{
- for (S32 s = 0; s < sizeS - 1; s++)
+ for (S32 t = 0; t < sizeT-1; t++)
{
- for (S32 t = 0; t < sizeT - 1; t++)
- {
- // convert image data to vectors
- 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)
- LLVector3 cross = (p1 - p2) % (p1 - p3);
- area += cross.magVec();
- }
+ // get four corners of quad
+ LLVector3 p1 = mMesh[(s )*sizeT + (t )].mPos;
+ LLVector3 p2 = mMesh[(s+1)*sizeT + (t )].mPos;
+ LLVector3 p3 = mMesh[(s )*sizeT + (t+1)].mPos;
+ LLVector3 p4 = mMesh[(s+1)*sizeT + (t+1)].mPos;
+
+ // compute the area of the quad by taking the length of the cross product of the two triangles
+ LLVector3 cross1 = (p1 - p2) % (p1 - p3);
+ LLVector3 cross2 = (p4 - p2) % (p4 - p3);
+ area += (cross1.magVec() + cross2.magVec()) / 2.0;
}
}
@@ -2164,7 +2159,21 @@ S32 sculpt_sides(F32 detail)
// determine the number of vertices in both s and t direction for this sculpt
void sculpt_calc_mesh_resolution(U16 width, U16 height, U8 type, F32 detail, S32& s, S32& t)
{
- S32 vertices = sculpt_sides(detail);
+ // this code has the following properties:
+ // 1) the aspect ratio of the mesh is as close as possible to the ratio of the map
+ // while still using all available verts
+ // 2) the mesh cannot have more verts than is allowed by LOD
+ // 3) the mesh cannot have more verts than is allowed by the map
+
+ S32 max_vertices_lod = (S32)pow((double)sculpt_sides(detail), 2.0);
+ S32 max_vertices_map = width * height / 4;
+
+ S32 vertices;
+ if (max_vertices_map > 0)
+ vertices = llmin(max_vertices_lod, max_vertices_map);
+ else
+ vertices = max_vertices_lod;
+
F32 ratio;
if ((width == 0) || (height == 0))
@@ -2173,13 +2182,13 @@ void sculpt_calc_mesh_resolution(U16 width, U16 height, U8 type, F32 detail, S32
ratio = (F32) width / (F32) height;
- s = (S32)(vertices / fsqrtf(ratio));
+ s = (S32)fsqrtf(((F32)vertices / ratio));
- s = llmax(s, 3); // no degenerate sizes, please
- t = vertices * vertices / s;
+ s = llmax(s, 4); // no degenerate sizes, please
+ t = vertices / s;
- t = llmax(t, 3); // no degenerate sizes, please
- s = vertices * vertices / t;
+ t = llmax(t, 4); // no degenerate sizes, please
+ s = vertices / t;
}
// sculpt replaces generate() for sculpted surfaces
@@ -2216,20 +2225,25 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components,
sNumMeshPoints -= mMesh.size();
mMesh.resize(sizeS * sizeT);
sNumMeshPoints += mMesh.size();
-
- if (!data_is_empty && 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
+ if (!data_is_empty)
{
sculptGenerateMapVertices(sculpt_width, sculpt_height, sculpt_components, sculpt_data, sculpt_type);
+
+ if (sculptGetSurfaceArea() < SCULPT_MIN_AREA)
+ {
+ data_is_empty = TRUE;
+ }
}
+ if (data_is_empty)
+ {
+ sculptGeneratePlaceholder();
+ }
+
+
+
for (S32 i = 0; i < (S32)mProfilep->mFaces.size(); i++)
{
mFaceMask |= mProfilep->mFaces[i].mFaceID;
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index ab30d78333..e55fe52c91 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -943,8 +943,8 @@ public:
void sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level);
private:
- F32 sculptGetSurfaceArea(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data);
void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type);
+ F32 sculptGetSurfaceArea();
void sculptGeneratePlaceholder();
void sculptCalcMeshResolution(U16 width, U16 height, U8 type, S32& s, S32& t);