summaryrefslogtreecommitdiff
path: root/indra/llmath/llvolume.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmath/llvolume.cpp')
-rw-r--r--indra/llmath/llvolume.cpp99
1 files changed, 63 insertions, 36 deletions
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 4a069b0f63..f43d07ce5e 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -371,7 +371,7 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons
}
}
-class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst<LLVolumeTriangle>
+class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst<LLVolumeTriangle, LLVolumeTriangle*>
{
public:
const LLVolumeFace* mFace;
@@ -381,7 +381,7 @@ public:
mFace = face;
}
- virtual void visit(const LLOctreeNode<LLVolumeTriangle>* branch)
+ virtual void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch)
{ //this is a depth first traversal, so it's safe to assum all children have complete
//bounding data
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
@@ -399,8 +399,7 @@ public:
min = *(tri->mV[0]);
max = *(tri->mV[0]);
- for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter =
- branch->getDataBegin(); iter != branch->getDataEnd(); ++iter)
+ for (LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin(); iter != branch->getDataEnd(); ++iter)
{ //for each triangle in node
//stretch by triangles in node
@@ -684,7 +683,7 @@ LLProfile::Face* LLProfile::addHole(const LLProfileParams& params, BOOL flat, F3
Face *face = addFace(mTotalOut, mTotal-mTotalOut,0,LL_FACE_INNER_SIDE, flat);
- static LLAlignedArray<LLVector4a,64> pt;
+ static thread_local LLAlignedArray<LLVector4a,64> pt;
pt.resize(mTotal) ;
for (S32 i=mTotalOut;i<mTotal;i++)
@@ -1625,9 +1624,6 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
//genNGon(params, llfloor(MIN_DETAIL_FACES * detail), 4.f, 0.f);
genNGon(params, llfloor(MIN_DETAIL_FACES * detail));
- F32 t = 0.f;
- F32 tStep = 1.0f / mPath.size();
-
F32 toggle = 0.5f;
for (S32 i=0;i<(S32)mPath.size();i++)
{
@@ -1636,7 +1632,6 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
toggle = -0.5f;
else
toggle = 0.5f;
- t += tStep;
}
}
@@ -2427,6 +2422,13 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
//copy out indices
S32 num_indices = idx.size() / 2;
+ const S32 indices_to_discard = num_indices % 3;
+ if (indices_to_discard > 0)
+ {
+ // Invalid number of triangle indices
+ LL_WARNS() << "Incomplete triangle discarded from face! Indices count " << num_indices << " was not divisible by 3. face index: " << i << " Total: " << face_count << LL_ENDL;
+ num_indices -= indices_to_discard;
+ }
face.resizeIndices(num_indices);
if (num_indices > 2 && !face.mIndices)
@@ -2442,8 +2444,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
}
U16* indices = (U16*) &(idx[0]);
- U32 count = idx.size()/2;
- for (U32 j = 0; j < count; ++j)
+ for (U32 j = 0; j < num_indices; ++j)
{
face.mIndices[j] = indices[j];
}
@@ -3835,8 +3836,8 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
#if DEBUG_SILHOUETTE_EDGE_MAP
//for each triangle
- U32 count = face.mNumIndices;
- for (U32 j = 0; j < count/3; j++) {
+ U32 tri_count = face.mNumIndices / 3;
+ for (U32 j = 0; j < tri_count; j++) {
//get vertices
S32 v1 = face.mIndices[j*3+0];
S32 v2 = face.mIndices[j*3+1];
@@ -3854,7 +3855,7 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
continue;
}
- if (nIndex >= (S32) count/3) {
+ if (nIndex >= (S32)tri_count) {
continue;
}
//get neighbor vertices
@@ -4146,13 +4147,13 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en
}
else
{
- if (!face.mOctree)
+ if (!face.getOctree())
{
face.createOctree();
}
LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, tangent_out);
- intersect.traverse(face.mOctree);
+ intersect.traverse(face.getOctree());
if (intersect.mHitFace)
{
hit_face = i;
@@ -4707,6 +4708,7 @@ LLVolumeFace::LLVolumeFace() :
#endif
mWeightsScrubbed(FALSE),
mOctree(NULL),
+ mOctreeTriangles(NULL),
mOptimized(FALSE)
{
mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3);
@@ -4736,8 +4738,9 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src)
mJointIndices(NULL),
#endif
mWeightsScrubbed(FALSE),
- mOctree(NULL)
-{
+ mOctree(NULL),
+ mOctreeTriangles(NULL)
+{
mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3);
mCenter = mExtents+2;
*this = src;
@@ -4877,8 +4880,7 @@ void LLVolumeFace::freeData()
mJustWeights = NULL;
#endif
- delete mOctree;
- mOctree = NULL;
+ destroyOctree();
}
BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build)
@@ -4886,8 +4888,7 @@ BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build)
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
//tree for this face is no longer valid
- delete mOctree;
- mOctree = NULL;
+ destroyOctree();
LL_CHECK_MEMORY
BOOL ret = FALSE ;
@@ -5600,21 +5601,27 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
- if (mOctree)
+ if (getOctree())
{
return;
}
- mOctree = new LLOctreeRoot<LLVolumeTriangle>(center, size, NULL);
+ llassert(mNumIndices % 3 == 0);
+
+ mOctree = new LLOctreeRoot<LLVolumeTriangle, LLVolumeTriangle*>(center, size, NULL);
new LLVolumeOctreeListener(mOctree);
+ const U32 num_triangles = mNumIndices / 3;
+ // Initialize all the triangles we need
+ mOctreeTriangles = new LLVolumeTriangle[num_triangles];
- for (U32 i = 0; i < mNumIndices; i+= 3)
+ for (U32 triangle_index = 0; triangle_index < num_triangles; ++triangle_index)
{ //for each triangle
- LLPointer<LLVolumeTriangle> tri = new LLVolumeTriangle();
+ const U32 index = triangle_index * 3;
+ LLVolumeTriangle* tri = &mOctreeTriangles[triangle_index];
- const LLVector4a& v0 = mPositions[mIndices[i]];
- const LLVector4a& v1 = mPositions[mIndices[i+1]];
- const LLVector4a& v2 = mPositions[mIndices[i+2]];
+ const LLVector4a& v0 = mPositions[mIndices[index]];
+ const LLVector4a& v1 = mPositions[mIndices[index + 1]];
+ const LLVector4a& v2 = mPositions[mIndices[index + 2]];
//store pointers to vertex data
tri->mV[0] = &v0;
@@ -5622,9 +5629,9 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe
tri->mV[2] = &v2;
//store indices
- tri->mIndex[0] = mIndices[i];
- tri->mIndex[1] = mIndices[i+1];
- tri->mIndex[2] = mIndices[i+2];
+ tri->mIndex[0] = mIndices[index];
+ tri->mIndex[1] = mIndices[index + 1];
+ tri->mIndex[2] = mIndices[index + 2];
//get minimum point
LLVector4a min = v0;
@@ -5667,6 +5674,19 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe
}
}
+void LLVolumeFace::destroyOctree()
+{
+ delete mOctree;
+ mOctree = NULL;
+ delete[] mOctreeTriangles;
+ mOctreeTriangles = NULL;
+}
+
+const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* LLVolumeFace::getOctree() const
+{
+ return mOctree;
+}
+
void LLVolumeFace::swapData(LLVolumeFace& rhs)
{
@@ -6538,6 +6558,7 @@ void LLVolumeFace::allocateJointIndices(S32 num_verts)
void LLVolumeFace::resizeIndices(S32 num_indices)
{
ll_aligned_free_16(mIndices);
+ llassert(num_indices % 3 == 0);
if (num_indices)
{
@@ -6674,13 +6695,19 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
else
{
// Get s value for tex-coord.
- if (!flat)
+ S32 index = mBeginS + s;
+ if (index >= profile.size())
+ {
+ // edge?
+ ss = flat ? 1.f - begin_stex : 1.f;
+ }
+ else if (!flat)
{
- ss = profile[mBeginS + s][2];
+ ss = profile[index][2];
}
else
{
- ss = profile[mBeginS + s][2] - begin_stex;
+ ss = profile[index][2] - begin_stex;
}
}
@@ -6866,7 +6893,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
LLVector4a* norm = mNormals;
- static LLAlignedArray<LLVector4a, 64> triangle_normals;
+ static thread_local LLAlignedArray<LLVector4a, 64> triangle_normals;
try
{
triangle_normals.resize(count);