summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llmath/llvolume.cpp67
-rw-r--r--indra/llmath/llvolume.h33
2 files changed, 97 insertions, 3 deletions
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index d85c56046f..9ea3912a88 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -1882,9 +1882,15 @@ bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs
bool retval = false;
if (rhs.mPosition == mPosition && rhs.mTexCoord == mTexCoord)
{
- F32 cur_angle = rhs.mNormal*mNormal;
-
- retval = cur_angle > angle_cutoff;
+ if (angle_cutoff > 1.f)
+ {
+ retval = (mNormal == rhs.mNormal);
+ }
+ else
+ {
+ F32 cur_angle = rhs.mNormal*mNormal;
+ retval = cur_angle > angle_cutoff;
+ }
}
return retval;
@@ -4953,6 +4959,61 @@ BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build)
}
}
+void LLVolumeFace::optimize(F32 angle_cutoff)
+{
+ LLVolumeFace new_face;
+
+ VertexMapData::PointMap point_map;
+
+ //remove redundant vertices
+ for (U32 i = 0; i < mIndices.size(); ++i)
+ {
+ U16 index = mIndices[i];
+
+ LLVolumeFace::VertexData cv = mVertices[index];
+
+ BOOL found = FALSE;
+ VertexMapData::PointMap::iterator point_iter = point_map.find(cv.mPosition);
+ if (point_iter != point_map.end())
+ { //duplicate point might exist
+ for (U32 j = 0; j < point_iter->second.size(); ++j)
+ {
+ LLVolumeFace::VertexData& tv = (point_iter->second)[j];
+ if (tv.compareNormal(cv, angle_cutoff))
+ {
+ found = TRUE;
+ new_face.mIndices.push_back((point_iter->second)[j].mIndex);
+ break;
+ }
+ }
+ }
+
+ if (!found)
+ {
+ new_face.mVertices.push_back(cv);
+ U16 index = (U16) new_face.mVertices.size()-1;
+ new_face.mIndices.push_back(index);
+
+ VertexMapData d;
+ d.mPosition = cv.mPosition;
+ d.mTexCoord = cv.mTexCoord;
+ d.mNormal = cv.mNormal;
+ d.mIndex = index;
+ if (point_iter != point_map.end())
+ {
+ point_iter->second.push_back(d);
+ }
+ else
+ {
+ point_map[d.mPosition].push_back(d);
+ }
+ }
+ }
+
+ mVertices = new_face.mVertices;
+ mIndices = new_face.mIndices;
+}
+
void LerpPlanarVertex(LLVolumeFace::VertexData& v0,
LLVolumeFace::VertexData& v1,
LLVolumeFace::VertexData& v2,
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index 36811785dc..f1c1fdceba 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -820,6 +820,39 @@ public:
bool compareNormal(const VertexData& rhs, F32 angle_cutoff) const;
};
+ class VertexMapData : public LLVolumeFace::VertexData
+ {
+ public:
+ U16 mIndex;
+
+ bool operator==(const LLVolumeFace::VertexData& rhs) const
+ {
+ return mPosition == rhs.mPosition &&
+ mTexCoord == rhs.mTexCoord &&
+ mNormal == rhs.mNormal;
+ }
+
+ struct ComparePosition
+ {
+ bool operator()(const LLVector3& a, const LLVector3& b) const
+ {
+ if (a.mV[0] != b.mV[0])
+ {
+ return a.mV[0] < b.mV[0];
+ }
+ if (a.mV[1] != b.mV[1])
+ {
+ return a.mV[1] < b.mV[1];
+ }
+ return a.mV[2] < b.mV[2];
+ }
+ };
+
+ typedef std::map<LLVector3, std::vector<VertexMapData>, VertexMapData::ComparePosition > PointMap;
+ };
+
+ void optimize(F32 angle_cutoff = 2.f);
+
enum
{
SINGLE_MASK = 0x0001,