From 55159162364c30c08a6206bae1cc3dd3caaeb0d0 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 7 Dec 2012 12:56:28 -0600 Subject: Optimization -- falcon says not using static here is more performant. --- indra/llmath/llcamera.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp index 22ba26f99b..c14c117da9 100644 --- a/indra/llmath/llcamera.cpp +++ b/indra/llmath/llcamera.cpp @@ -163,7 +163,7 @@ size_t LLCamera::readFrustumFromBuffer(const char *buffer) S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius) { - static const LLVector4a scaler[] = { + const LLVector4a scaler[] = { LLVector4a(-1,-1,-1), LLVector4a( 1,-1,-1), LLVector4a(-1, 1,-1), @@ -207,7 +207,7 @@ S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius) S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius) { - static const LLVector4a scaler[] = { + const LLVector4a scaler[] = { LLVector4a(-1,-1,-1), LLVector4a( 1,-1,-1), LLVector4a(-1, 1,-1), -- cgit v1.2.3 From 4e46ce5520cb3d8793921c2a0f9e67f16ad776ba Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 20 Jun 2013 17:17:28 -0500 Subject: MATBUG-204 Fix for crash in genVolumeBBoxes --- indra/llmath/llvolume.cpp | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index c4e1f0c84c..14cebfe5aa 100755 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -7277,9 +7277,6 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe const LLVector4a& t = tan1[a]; - llassert(tan1[a].getLength3().getF32() >= 0.f); - llassert(tan2[a].getLength3().getF32() >= 0.f); - LLVector4a ncrosst; ncrosst.setCross3(n,t); @@ -7299,16 +7296,6 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe tsubn.getF32ptr()[3] = handedness; tangent[a] = tsubn; - - /* - These are going off on invalid input and hindering other debugging. - llassert(llfinite(tangent[a].getF32ptr()[0])); - llassert(llfinite(tangent[a].getF32ptr()[1])); - llassert(llfinite(tangent[a].getF32ptr()[2])); - - llassert(!llisnan(tangent[a].getF32ptr()[0])); - llassert(!llisnan(tangent[a].getF32ptr()[1])); - llassert(!llisnan(tangent[a].getF32ptr()[2]));*/ } else { //degenerate, make up a value -- cgit v1.2.3 From 705a0ab6770459d89474b3495b05214315a49c94 Mon Sep 17 00:00:00 2001 From: Graham Linden Date: Tue, 25 Jun 2013 11:16:27 -0700 Subject: NORSPEC-288 WIP fixes the issue with normal gen, but may be a bigger perf hit than we want --- indra/llmath/llvector4a.inl | 20 +++++++++++ indra/llmath/llvolume.cpp | 83 ++++++++++++++++++++++++--------------------- 2 files changed, 64 insertions(+), 39 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvector4a.inl b/indra/llmath/llvector4a.inl index 7c52ffef21..558fe09323 100755 --- a/indra/llmath/llvector4a.inl +++ b/indra/llmath/llvector4a.inl @@ -409,6 +409,26 @@ inline void LLVector4a::normalize3fast() mQ = _mm_mul_ps( mQ, approxRsqrt ); } +inline void LLVector4a::normalize3fast_checked(LLVector4a* d) +{ + if (!isFinite3()) + { + *this = d ? *d : LLVector4a(0,1,0,1); + return; + } + + LLVector4a lenSqrd; lenSqrd.setAllDot3( *this, *this ); + + if (lenSqrd.getF32ptr()[0] <= FLT_EPSILON) + { + *this = d ? *d : LLVector4a(0,1,0,1); + return; + } + + const LLQuad approxRsqrt = _mm_rsqrt_ps(lenSqrd.mQ); + mQ = _mm_mul_ps( mQ, approxRsqrt ); +} + // Return true if this vector is normalized with respect to x,y,z up to tolerance inline LLBool32 LLVector4a::isNormalized3( F32 tolerance ) const { diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 14cebfe5aa..58cac57e7f 100755 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4472,6 +4472,9 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, continue; //skip degenerate face } + LLVector4a default_norm; + default_norm.set(0,1,0,1); + //for each edge for (S32 k = 0; k < 3; k++) { S32 index = face.mEdge[j*3+k]; @@ -4493,14 +4496,14 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, norm_mat.rotate(n[v1], t); - t.normalize3fast(); + t.normalize3fast_checked(&default_norm); normals.push_back(LLVector3(t[0], t[1], t[2])); mat.affineTransform(v[v2], t); vertices.push_back(LLVector3(t[0], t[1], t[2])); norm_mat.rotate(n[v2], t); - t.normalize3fast(); + t.normalize3fast_checked(&default_norm); normals.push_back(LLVector3(t[0], t[1], t[2])); } } @@ -6096,6 +6099,9 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) { VertexData corners[4]; VertexData baseVert; + LLVector4a default_norm; + default_norm.set(0,1,0,1); + for(S32 t = 0; t < 4; t++) { corners[t].getPosition().load3( mesh[offset + (grid_size*t)].mPos.mV); @@ -6108,8 +6114,8 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) lhs.setSub(corners[1].getPosition(), corners[0].getPosition()); LLVector4a rhs; rhs.setSub(corners[2].getPosition(), corners[1].getPosition()); - baseVert.getNormal().setCross3(lhs, rhs); - baseVert.getNormal().normalize3fast(); + baseVert.getNormal().setCross3(lhs, rhs); + baseVert.getNormal().normalize3fast_checked(&default_norm); } if(!(mTypeMask & TOP_MASK)) @@ -6559,17 +6565,12 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) d1.setSub(mPositions[mIndices[2]], mPositions[mIndices[0]]); LLVector4a normal; - normal.setCross3(d0,d1); - - if (normal.dot3(normal).getF32() > F_APPROXIMATELY_ZERO) - { - normal.normalize3fast(); - } - else - { //degenerate, make up a value - normal.set(0,0,1); - } + LLVector4a default_norm; + default_norm.set(0,1,0,1); + normal.setCross3(d0,d1); + normal.normalize3fast_checked(&default_norm); + llassert(llfinite(normal.getF32ptr()[0])); llassert(llfinite(normal.getF32ptr()[1])); llassert(llfinite(normal.getF32ptr()[2])); @@ -6611,11 +6612,13 @@ void LLVolumeFace::createTangents() CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices/3, mIndices, mTangents); //normalize tangents + LLVector4a default_norm; + default_norm.set(0,1,0,1); for (U32 i = 0; i < mNumVertices; i++) { //binorm[i].normalize3fast(); //bump map/planar projection code requires normals to be normalized - mNormals[i].normalize3fast(); + mNormals[i].normalize3fast_checked(&default_norm); } } } @@ -6793,6 +6796,9 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat mat.loadu(mat_in); norm_mat.loadu(norm_mat_in); + LLVector4a default_norm; + default_norm.set(0,1,0,1); + for (U32 i = 0; i < face.mNumVertices; ++i) { //transform appended face position and store @@ -6800,7 +6806,7 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat //transform appended face normal and store norm_mat.rotate(src_norm[i], dst_norm[i]); - dst_norm[i].normalize3fast(); + dst_norm[i].normalize3fast_checked(&default_norm); //copy appended face texture coordinate dst_tc[i] = src_tc[i]; @@ -7213,42 +7219,41 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent) { - //LLVector4a *tan1 = new LLVector4a[vertexCount * 2]; LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a)); - LLVector4a* tan2 = tan1 + vertexCount; + LLVector4a* tan2 = tan1 + vertexCount; memset(tan1, 0, vertexCount*2*sizeof(LLVector4a)); - for (U32 a = 0; a < triangleCount; a++) - { - U32 i1 = *index_array++; - U32 i2 = *index_array++; - U32 i3 = *index_array++; + for (U32 a = 0; a < triangleCount; a++) + { + U32 i1 = *index_array++; + U32 i2 = *index_array++; + U32 i3 = *index_array++; - const LLVector4a& v1 = vertex[i1]; - const LLVector4a& v2 = vertex[i2]; - const LLVector4a& v3 = vertex[i3]; + const LLVector4a& v1 = vertex[i1]; + const LLVector4a& v2 = vertex[i2]; + const LLVector4a& v3 = vertex[i3]; - const LLVector2& w1 = texcoord[i1]; - const LLVector2& w2 = texcoord[i2]; - const LLVector2& w3 = texcoord[i3]; + const LLVector2& w1 = texcoord[i1]; + const LLVector2& w2 = texcoord[i2]; + const LLVector2& w3 = texcoord[i3]; const F32* v1ptr = v1.getF32ptr(); const F32* v2ptr = v2.getF32ptr(); const F32* v3ptr = v3.getF32ptr(); - float x1 = v2ptr[0] - v1ptr[0]; - float x2 = v3ptr[0] - v1ptr[0]; - float y1 = v2ptr[1] - v1ptr[1]; - float y2 = v3ptr[1] - v1ptr[1]; - float z1 = v2ptr[2] - v1ptr[2]; - float z2 = v3ptr[2] - v1ptr[2]; + float x1 = v2ptr[0] - v1ptr[0]; + float x2 = v3ptr[0] - v1ptr[0]; + float y1 = v2ptr[1] - v1ptr[1]; + float y2 = v3ptr[1] - v1ptr[1]; + float z1 = v2ptr[2] - v1ptr[2]; + float z2 = v3ptr[2] - v1ptr[2]; - float s1 = w2.mV[0] - w1.mV[0]; - float s2 = w3.mV[0] - w1.mV[0]; - float t1 = w2.mV[1] - w1.mV[1]; - float t2 = w3.mV[1] - w1.mV[1]; + float s1 = w2.mV[0] - w1.mV[0]; + float s2 = w3.mV[0] - w1.mV[0]; + float t1 = w2.mV[1] - w1.mV[1]; + float t2 = w3.mV[1] - w1.mV[1]; F32 rd = s1*t2-s2*t1; -- cgit v1.2.3 From c5fc5d9b46121bb0d44d3b35402d604514e2dd4e Mon Sep 17 00:00:00 2001 From: Graham Linden Date: Sun, 28 Jul 2013 15:43:10 -0700 Subject: NORSPEC-323 fix norm/tangent gen for prim caps --- indra/llmath/llvolume.cpp | 253 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 202 insertions(+), 51 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 58cac57e7f..b90830ddd8 100755 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -94,6 +94,16 @@ const S32 SCULPT_MIN_AREA_DETAIL = 1; extern BOOL gDebugGL; +void calc_tangent_from_triangle( + LLVector4a& normal, + LLVector4a& tangent_out, + const LLVector4a& v1, + const LLVector2& w1, + const LLVector4a& v2, + const LLVector2& w2, + const LLVector4a& v3, + const LLVector2& w3); + BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, const LLVector3& norm) { LLVector3 test = (pt2-pt1)%(pt3-pt2); @@ -1594,7 +1604,7 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split, S32 sides = (S32)llfloor(llfloor((MIN_DETAIL_FACES * detail + twist_mag * 3.5f * (detail-0.5f))) * params.getRevolutions()); if (is_sculpted) - sides = llmax(sculpt_size, 1); + sides = llmax(sculpt_size,1); genNGon(params, sides); } @@ -2062,7 +2072,7 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge generate(); - if (mParams.getSculptID().isNull() && mParams.getSculptType() == LL_SCULPT_TYPE_NONE || mParams.getSculptType() == LL_SCULPT_TYPE_MESH) + if (mParams.getSculptID().isNull() && ((mParams.getSculptType() == LL_SCULPT_TYPE_NONE) || (mParams.getSculptType() == LL_SCULPT_TYPE_MESH))) { createVolumeFaces(); } @@ -4472,9 +4482,6 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, continue; //skip degenerate face } - LLVector4a default_norm; - default_norm.set(0,1,0,1); - //for each edge for (S32 k = 0; k < 3; k++) { S32 index = face.mEdge[j*3+k]; @@ -4496,14 +4503,14 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, norm_mat.rotate(n[v1], t); - t.normalize3fast_checked(&default_norm); + t.normalize3fast(); normals.push_back(LLVector3(t[0], t[1], t[2])); mat.affineTransform(v[v2], t); vertices.push_back(LLVector3(t[0], t[1], t[2])); norm_mat.rotate(n[v2], t); - t.normalize3fast_checked(&default_norm); + t.normalize3fast(); normals.push_back(LLVector3(t[0], t[1], t[2])); } } @@ -5282,6 +5289,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) if (src.mTangents) { allocateTangents(src.mNumVertices); + llassert(mTangents); LLVector4a::memcpyNonAliased16((F32*) mTangents, (F32*) src.mTangents, vert_size); } else @@ -5293,6 +5301,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) if (src.mWeights) { allocateWeights(src.mNumVertices); + llassert(mWeights); LLVector4a::memcpyNonAliased16((F32*) mWeights, (F32*) src.mWeights, vert_size); } else @@ -5308,14 +5317,14 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) LLVector4a::memcpyNonAliased16((F32*) mIndices, (F32*) src.mIndices, idx_size); } - + //delete return *this; } LLVolumeFace::~LLVolumeFace() { - ll_aligned_free_16(mExtents); + ll_aligned_free_16(mExtents); mExtents = NULL; freeData(); @@ -5325,7 +5334,7 @@ void LLVolumeFace::freeData() { ll_aligned_free_16(mPositions); mPositions = NULL; - ll_aligned_free_16( mNormals); + ll_aligned_free_16(mNormals); mNormals = NULL; ll_aligned_free_16(mTexCoords); mTexCoords = NULL; @@ -5911,10 +5920,10 @@ void LLVolumeFace::cacheOptimize() wght = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); } - LLVector4a* binorm = NULL; + LLVector4a* tangent = NULL; if (mTangents) { - binorm = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); + tangent = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); } //allocate mapping of old indices to new indices @@ -5939,7 +5948,7 @@ void LLVolumeFace::cacheOptimize() } if (mTangents) { - binorm[cur_idx] = mTangents[idx]; + tangent[cur_idx] = mTangents[idx]; } cur_idx++; @@ -5961,7 +5970,7 @@ void LLVolumeFace::cacheOptimize() mNormals = norm; mTexCoords = tc; mWeights = wght; - mTangents = binorm; + mTangents = tangent; //std::string result = llformat("ACMR pre/post: %.3f/%.3f -- %d triangles %d breaks", pre_acmr, post_acmr, mNumIndices/3, breaks); //llinfos << result << llendl; @@ -6099,9 +6108,6 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) { VertexData corners[4]; VertexData baseVert; - LLVector4a default_norm; - default_norm.set(0,1,0,1); - for(S32 t = 0; t < 4; t++) { corners[t].getPosition().load3( mesh[offset + (grid_size*t)].mPos.mV); @@ -6115,7 +6121,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) LLVector4a rhs; rhs.setSub(corners[2].getPosition(), corners[1].getPosition()); baseVert.getNormal().setCross3(lhs, rhs); - baseVert.getNormal().normalize3fast_checked(&default_norm); + baseVert.getNormal().normalize3fast(); } if(!(mTypeMask & TOP_MASK)) @@ -6312,6 +6318,43 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) cuv = (min_uv + max_uv)*0.5f; + + LLVector4a tangent; + calc_tangent_from_triangle( + *norm, + tangent, + *mCenter, cuv, + pos[0], tc[0], + pos[1], tc[1]); + + if (tangent.getLength3() < 0.01) + { + tangent.set(1,0,0,1); + } + else + { + LLVector4a default_tangent; + default_tangent.set(1,0,0,1); + tangent.normalize3fast_checked(&default_tangent); + } + + LLVector4a normal; + LLVector4a d0, d1; + + d0.setSub(*mCenter, pos[0]); + d1.setSub(*mCenter, pos[1]); + + if (mTypeMask & TOP_MASK) + { + normal.setCross3(d0, d1); + } + else + { + normal.setCross3(d1, d0); + } + + normal.normalize3fast_checked(); + VertexData vd; vd.setPosition(*mCenter); vd.mTexCoord = cuv; @@ -6323,7 +6366,15 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) num_vertices++; } - + + allocateTangents(num_vertices); + + for (S32 i = 0; i < num_vertices; i++) + { + mTangents[i].load4a(tangent.getF32ptr()); + norm[i].load4a(normal.getF32ptr()); + } + if (partial_build) { return TRUE; @@ -6559,31 +6610,6 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) } - LLVector4a d0,d1; - - d0.setSub(mPositions[mIndices[1]], mPositions[mIndices[0]]); - d1.setSub(mPositions[mIndices[2]], mPositions[mIndices[0]]); - - LLVector4a normal; - LLVector4a default_norm; - default_norm.set(0,1,0,1); - - normal.setCross3(d0,d1); - normal.normalize3fast_checked(&default_norm); - - llassert(llfinite(normal.getF32ptr()[0])); - llassert(llfinite(normal.getF32ptr()[1])); - llassert(llfinite(normal.getF32ptr()[2])); - - llassert(!llisnan(normal.getF32ptr()[0])); - llassert(!llisnan(normal.getF32ptr()[1])); - llassert(!llisnan(normal.getF32ptr()[2])); - - for (S32 i = 0; i < num_vertices; i++) - { - norm[i].load4a(normal.getF32ptr()); - } - return TRUE; } @@ -6616,9 +6642,9 @@ void LLVolumeFace::createTangents() default_norm.set(0,1,0,1); for (U32 i = 0; i < mNumVertices; i++) { - //binorm[i].normalize3fast(); + //tangent[i].normalize3fast(); //bump map/planar projection code requires normals to be normalized - mNormals[i].normalize3fast_checked(&default_norm); + mNormals[i].normalize3fast_checked(); } } } @@ -6693,7 +6719,7 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con void LLVolumeFace::allocateTangents(S32 num_verts) { - ll_aligned_free_16(mTangents); + ll_aligned_free_16(mTangents); mTangents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); } @@ -6796,9 +6822,6 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat mat.loadu(mat_in); norm_mat.loadu(norm_mat_in); - LLVector4a default_norm; - default_norm.set(0,1,0,1); - for (U32 i = 0; i < face.mNumVertices; ++i) { //transform appended face position and store @@ -6806,7 +6829,7 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat //transform appended face normal and store norm_mat.rotate(src_norm[i], dst_norm[i]); - dst_norm[i].normalize3fast_checked(&default_norm); + dst_norm[i].normalize3fast_checked(); //copy appended face texture coordinate dst_tc[i] = src_tc[i]; @@ -7215,6 +7238,134 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) return TRUE; } +// Finds binormal based on three vertices with texture coordinates. +// Fills in dummy values if the triangle has degenerate texture coordinates. +void calc_binormal_from_triangle(LLVector4a& binormal, + + const LLVector4a& pos0, + const LLVector2& tex0, + const LLVector4a& pos1, + const LLVector2& tex1, + const LLVector4a& pos2, + const LLVector2& tex2) +{ + LLVector4a rx0( pos0[VX], tex0.mV[VX], tex0.mV[VY] ); + LLVector4a rx1( pos1[VX], tex1.mV[VX], tex1.mV[VY] ); + LLVector4a rx2( pos2[VX], tex2.mV[VX], tex2.mV[VY] ); + + LLVector4a ry0( pos0[VY], tex0.mV[VX], tex0.mV[VY] ); + LLVector4a ry1( pos1[VY], tex1.mV[VX], tex1.mV[VY] ); + LLVector4a ry2( pos2[VY], tex2.mV[VX], tex2.mV[VY] ); + + LLVector4a rz0( pos0[VZ], tex0.mV[VX], tex0.mV[VY] ); + LLVector4a rz1( pos1[VZ], tex1.mV[VX], tex1.mV[VY] ); + LLVector4a rz2( pos2[VZ], tex2.mV[VX], tex2.mV[VY] ); + + LLVector4a lhs, rhs; + + LLVector4a r0; + lhs.setSub(rx0, rx1); rhs.setSub(rx0, rx2); + r0.setCross3(lhs, rhs); + + LLVector4a r1; + lhs.setSub(ry0, ry1); rhs.setSub(ry0, ry2); + r1.setCross3(lhs, rhs); + + LLVector4a r2; + lhs.setSub(rz0, rz1); rhs.setSub(rz0, rz2); + r2.setCross3(lhs, rhs); + + if( r0[VX] && r1[VX] && r2[VX] ) + { + binormal.set( + -r0[VZ] / r0[VX], + -r1[VZ] / r1[VX], + -r2[VZ] / r2[VX]); + // binormal.normVec(); + } + else + { + binormal.set( 0, 1 , 0 ); + } +} + +// Finds binormal based on three vertices with texture coordinates. +// Fills in dummy values if the triangle has degenerate texture coordinates. +void calc_tangent_from_triangle( + LLVector4a& normal, + LLVector4a& tangent_out, + const LLVector4a& v1, + const LLVector2& w1, + const LLVector4a& v2, + const LLVector2& w2, + const LLVector4a& v3, + const LLVector2& w3) +{ + const F32* v1ptr = v1.getF32ptr(); + const F32* v2ptr = v2.getF32ptr(); + const F32* v3ptr = v3.getF32ptr(); + + float x1 = v2ptr[0] - v1ptr[0]; + float x2 = v3ptr[0] - v1ptr[0]; + float y1 = v2ptr[1] - v1ptr[1]; + float y2 = v3ptr[1] - v1ptr[1]; + float z1 = v2ptr[2] - v1ptr[2]; + float z2 = v3ptr[2] - v1ptr[2]; + + float s1 = w2.mV[0] - w1.mV[0]; + float s2 = w3.mV[0] - w1.mV[0]; + float t1 = w2.mV[1] - w1.mV[1]; + float t2 = w3.mV[1] - w1.mV[1]; + + F32 rd = s1*t2-s2*t1; + + float r = ((rd*rd) > FLT_EPSILON) ? 1.0F / rd : 1024.f; //some made up large ratio for division by zero + + llassert(llfinite(r)); + llassert(!llisnan(r)); + + LLVector4a sdir( + (t2 * x1 - t1 * x2) * r, + (t2 * y1 - t1 * y2) * r, + (t2 * z1 - t1 * z2) * r); + + LLVector4a tdir( + (s1 * x2 - s2 * x1) * r, + (s1 * y2 - s2 * y1) * r, + (s1 * z2 - s2 * z1) * r); + + LLVector4a n = normal; + LLVector4a t = sdir; + + LLVector4a ncrosst; + ncrosst.setCross3(n,t); + + // Gram-Schmidt orthogonalize + n.mul(n.dot3(t).getF32()); + + LLVector4a tsubn; + tsubn.setSub(t,n); + + if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO) + { + tsubn.normalize3fast_checked(); + + // Calculate handedness + F32 handedness = ncrosst.dot3(tdir).getF32() < 0.f ? -1.f : 1.f; + + tsubn.getF32ptr()[3] = handedness; + + tangent_out = tsubn; + } + else + { + // degenerate, make up a value + // + tangent_out.set(0,0,1,1); + } + +} + //adapted from Lengyel, Eric. “Computing Tangent Space Basis Vectors for an Arbitrary Mesh”. Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent) -- cgit v1.2.3 From 6db14e3988a1248141d085e5005baa70e48f8172 Mon Sep 17 00:00:00 2001 From: simon Date: Tue, 30 Jul 2013 15:12:02 -0700 Subject: MAINT-2913: crash in LLCamera::AABBInFrustum. Tried to make array indexes bullet-proof. Reviewed by Kelly --- indra/llmath/llcamera.cpp | 86 ++++++++++++++++++++++++----------------------- indra/llmath/llcamera.h | 37 +++++++++++++------- 2 files changed, 69 insertions(+), 54 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp index c14c117da9..33cf185196 100755 --- a/indra/llmath/llcamera.cpp +++ b/indra/llmath/llcamera.cpp @@ -42,6 +42,11 @@ LLCamera::LLCamera() : mPlaneCount(6), mFrustumCornerDist(0.f) { + for (U32 i = 0; i < PLANE_MASK_NUM; i++) + { + mPlaneMask[i] = PLANE_MASK_NONE; + } + calculateFrustumPlanes(); } @@ -52,6 +57,11 @@ LLCamera::LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_p mPlaneCount(6), mFrustumCornerDist(0.f) { + for (U32 i = 0; i < PLANE_MASK_NUM; i++) + { + mPlaneMask[i] = PLANE_MASK_NONE; + } + mAspect = llclamp(aspect_ratio, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO); mNearPlane = llclamp(near_plane, MIN_NEAR_PLANE, MAX_NEAR_PLANE); if(far_plane < 0) far_plane = DEFAULT_FAR_PLANE; @@ -87,14 +97,14 @@ F32 LLCamera::getMaxView() const void LLCamera::setUserClipPlane(LLPlane& plane) { - mPlaneCount = 7; - mAgentPlanes[6] = plane; - mPlaneMask[6] = plane.calcPlaneMask(); + mPlaneCount = AGENT_PLANE_USER_CLIP_NUM; + mAgentPlanes[AGENT_PLANE_USER_CLIP] = plane; + mPlaneMask[AGENT_PLANE_USER_CLIP] = plane.calcPlaneMask(); } void LLCamera::disableUserClipPlane() { - mPlaneCount = 6; + mPlaneCount = AGENT_PLANE_NO_USER_CLIP_NUM; } void LLCamera::setView(F32 vertical_fov_rads) @@ -161,31 +171,33 @@ size_t LLCamera::readFrustumFromBuffer(const char *buffer) // ---------------- test methods ---------------- -S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius) +static const LLVector4a sFrustumScaler[] = { - const LLVector4a scaler[] = { - LLVector4a(-1,-1,-1), - LLVector4a( 1,-1,-1), - LLVector4a(-1, 1,-1), - LLVector4a( 1, 1,-1), - LLVector4a(-1,-1, 1), - LLVector4a( 1,-1, 1), - LLVector4a(-1, 1, 1), - LLVector4a( 1, 1, 1) - }; + LLVector4a(-1,-1,-1), + LLVector4a( 1,-1,-1), + LLVector4a(-1, 1,-1), + LLVector4a( 1, 1,-1), + LLVector4a(-1,-1, 1), + LLVector4a( 1,-1, 1), + LLVector4a(-1, 1, 1), + LLVector4a( 1, 1, 1) // 8 entries +}; +S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius) +{ U8 mask = 0; bool result = false; LLVector4a rscale, maxp, minp; LLSimdScalar d; - for (U32 i = 0; i < mPlaneCount; i++) + U32 max_planes = llmin(mPlaneCount, (U32) AGENT_PLANE_USER_CLIP_NUM); // mAgentPlanes[] size is 7 + for (U32 i = 0; i < max_planes; i++) { mask = mPlaneMask[i]; - if (mask != 0xff) + if (mask < PLANE_MASK_NUM) { const LLPlane& p(mAgentPlanes[i]); p.getAt<3>(d); - rscale.setMul(radius, scaler[mask]); + rscale.setMul(radius, sFrustumScaler[mask]); minp.setSub(center, rscale); d = -d; if (p.dot3(minp).getF32() > d) @@ -207,29 +219,19 @@ S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius) S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius) { - const LLVector4a scaler[] = { - LLVector4a(-1,-1,-1), - LLVector4a( 1,-1,-1), - LLVector4a(-1, 1,-1), - LLVector4a( 1, 1,-1), - LLVector4a(-1,-1, 1), - LLVector4a( 1,-1, 1), - LLVector4a(-1, 1, 1), - LLVector4a( 1, 1, 1) - }; - U8 mask = 0; bool result = false; LLVector4a rscale, maxp, minp; LLSimdScalar d; - for (U32 i = 0; i < mPlaneCount; i++) + U32 max_planes = llmin(mPlaneCount, (U32) AGENT_PLANE_USER_CLIP_NUM); // mAgentPlanes[] size is 7 + for (U32 i = 0; i < max_planes; i++) { mask = mPlaneMask[i]; - if ((i != 5) && (mask != 0xff)) + if ((i != 5) && (mask < PLANE_MASK_NUM)) { const LLPlane& p(mAgentPlanes[i]); p.getAt<3>(d); - rscale.setMul(radius, scaler[mask]); + rscale.setMul(radius, sFrustumScaler[mask]); minp.setSub(center, rscale); d = -d; if (p.dot3(minp).getF32() > d) @@ -369,7 +371,7 @@ int LLCamera::sphereInFrustum(const LLVector3 &sphere_center, const F32 radius) bool res = false; for (int i = 0; i < 6; i++) { - if (mPlaneMask[i] != 0xff) + if (mPlaneMask[i] != PLANE_MASK_NONE) { float d = mAgentPlanes[i].dist(sphere_center); @@ -541,14 +543,14 @@ void LLCamera::ignoreAgentFrustumPlane(S32 idx) return; } - mPlaneMask[idx] = 0xff; + mPlaneMask[idx] = PLANE_MASK_NONE; mAgentPlanes[idx].clear(); } void LLCamera::calcAgentFrustumPlanes(LLVector3* frust) { - for (int i = 0; i < 8; i++) + for (int i = 0; i < AGENT_FRUSTRUM_NUM; i++) { mAgentFrustum[i] = frust[i]; } @@ -560,22 +562,22 @@ void LLCamera::calcAgentFrustumPlanes(LLVector3* frust) //order of planes is important, keep most likely to fail in the front of the list //near - frust[0], frust[1], frust[2] - mAgentPlanes[2] = planeFromPoints(frust[0], frust[1], frust[2]); + mAgentPlanes[AGENT_PLANE_NEAR] = planeFromPoints(frust[0], frust[1], frust[2]); //far - mAgentPlanes[5] = planeFromPoints(frust[5], frust[4], frust[6]); + mAgentPlanes[AGENT_PLANE_FAR] = planeFromPoints(frust[5], frust[4], frust[6]); //left - mAgentPlanes[0] = planeFromPoints(frust[4], frust[0], frust[7]); + mAgentPlanes[AGENT_PLANE_LEFT] = planeFromPoints(frust[4], frust[0], frust[7]); //right - mAgentPlanes[1] = planeFromPoints(frust[1], frust[5], frust[6]); + mAgentPlanes[AGENT_PLANE_RIGHT] = planeFromPoints(frust[1], frust[5], frust[6]); //top - mAgentPlanes[4] = planeFromPoints(frust[3], frust[2], frust[6]); + mAgentPlanes[AGENT_PLANE_TOP] = planeFromPoints(frust[3], frust[2], frust[6]); //bottom - mAgentPlanes[3] = planeFromPoints(frust[1], frust[0], frust[4]); + mAgentPlanes[AGENT_PLANE_BOTTOM] = planeFromPoints(frust[1], frust[0], frust[4]); //cache plane octant facing mask for use in AABBInFrustum for (U32 i = 0; i < mPlaneCount; i++) @@ -635,7 +637,7 @@ void LLCamera::calculateWorldFrustumPlanes() LLVector3 center = mOrigin - mXAxis*mNearPlane; mWorldPlanePos = center; LLVector3 pnorm; - for (int p=0; p<4; p++) + for (int p = 0; p < PLANE_NUM; p++) { mLocalPlanes[p].getVector3(pnorm); LLVector3 norm = rotateToAbsolute(pnorm); diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h index 0b591be622..1283cfb16b 100755 --- a/indra/llmath/llcamera.h +++ b/indra/llmath/llcamera.h @@ -76,26 +76,39 @@ public: PLANE_RIGHT = 1, PLANE_BOTTOM = 2, PLANE_TOP = 3, - PLANE_NUM = 4 + PLANE_NUM = 4, + PLANE_MASK_NONE = 0xff // Disable this plane }; enum { PLANE_LEFT_MASK = (1< Date: Mon, 19 Aug 2013 12:56:04 -0700 Subject: Fix merge issues from genBBoxes optimizations fighting with genBBoxes optimizations and missing statics --- indra/llmath/llvolume.cpp | 157 +++++++++++++++++++++++----------------------- 1 file changed, 78 insertions(+), 79 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index ad0ca618a0..a030d889af 100755 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -136,6 +136,82 @@ BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* cent return true; } +// Finds tangent vec based on three vertices with texture coordinates. +// Fills in dummy values if the triangle has degenerate texture coordinates. +void calc_tangent_from_triangle( + LLVector4a& normal, + LLVector4a& tangent_out, + const LLVector4a& v1, + const LLVector2& w1, + const LLVector4a& v2, + const LLVector2& w2, + const LLVector4a& v3, + const LLVector2& w3) +{ + const F32* v1ptr = v1.getF32ptr(); + const F32* v2ptr = v2.getF32ptr(); + const F32* v3ptr = v3.getF32ptr(); + + float x1 = v2ptr[0] - v1ptr[0]; + float x2 = v3ptr[0] - v1ptr[0]; + float y1 = v2ptr[1] - v1ptr[1]; + float y2 = v3ptr[1] - v1ptr[1]; + float z1 = v2ptr[2] - v1ptr[2]; + float z2 = v3ptr[2] - v1ptr[2]; + + float s1 = w2.mV[0] - w1.mV[0]; + float s2 = w3.mV[0] - w1.mV[0]; + float t1 = w2.mV[1] - w1.mV[1]; + float t2 = w3.mV[1] - w1.mV[1]; + + F32 rd = s1*t2-s2*t1; + + float r = ((rd*rd) > FLT_EPSILON) ? 1.0F / rd : 1024.f; //some made up large ratio for division by zero + + llassert(llfinite(r)); + llassert(!llisnan(r)); + + LLVector4a sdir( + (t2 * x1 - t1 * x2) * r, + (t2 * y1 - t1 * y2) * r, + (t2 * z1 - t1 * z2) * r); + + LLVector4a tdir( + (s1 * x2 - s2 * x1) * r, + (s1 * y2 - s2 * y1) * r, + (s1 * z2 - s2 * z1) * r); + + LLVector4a n = normal; + LLVector4a t = sdir; + + LLVector4a ncrosst; + ncrosst.setCross3(n,t); + + // Gram-Schmidt orthogonalize + n.mul(n.dot3(t).getF32()); + + LLVector4a tsubn; + tsubn.setSub(t,n); + + if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO) + { + tsubn.normalize3fast_checked(); + + // Calculate handedness + F32 handedness = ncrosst.dot3(tdir).getF32() < 0.f ? -1.f : 1.f; + + tsubn.getF32ptr()[3] = handedness; + + tangent_out = tsubn; + } + else + { + // degenerate, make up a value + // + tangent_out.set(0,0,1,1); + } + +} // intersect test between triangle vert0, vert1, vert2 and a ray from orig in direction dir. @@ -5908,10 +5984,10 @@ void LLVolumeFace::cacheOptimize() wght = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); } - LLVector4a* binorm = NULL; + LLVector4a* tangent = NULL; if (mTangents) { - binorm = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); + tangent = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); } //allocate mapping of old indices to new indices @@ -7277,83 +7353,6 @@ void calc_binormal_from_triangle(LLVector4a& binormal, } } -// Finds binormal based on three vertices with texture coordinates. -// Fills in dummy values if the triangle has degenerate texture coordinates. -void calc_tangent_from_triangle( - LLVector4a& normal, - LLVector4a& tangent_out, - const LLVector4a& v1, - const LLVector2& w1, - const LLVector4a& v2, - const LLVector2& w2, - const LLVector4a& v3, - const LLVector2& w3) -{ - const F32* v1ptr = v1.getF32ptr(); - const F32* v2ptr = v2.getF32ptr(); - const F32* v3ptr = v3.getF32ptr(); - - float x1 = v2ptr[0] - v1ptr[0]; - float x2 = v3ptr[0] - v1ptr[0]; - float y1 = v2ptr[1] - v1ptr[1]; - float y2 = v3ptr[1] - v1ptr[1]; - float z1 = v2ptr[2] - v1ptr[2]; - float z2 = v3ptr[2] - v1ptr[2]; - - float s1 = w2.mV[0] - w1.mV[0]; - float s2 = w3.mV[0] - w1.mV[0]; - float t1 = w2.mV[1] - w1.mV[1]; - float t2 = w3.mV[1] - w1.mV[1]; - - F32 rd = s1*t2-s2*t1; - - float r = ((rd*rd) > FLT_EPSILON) ? 1.0F / rd : 1024.f; //some made up large ratio for division by zero - - llassert(llfinite(r)); - llassert(!llisnan(r)); - - LLVector4a sdir( - (t2 * x1 - t1 * x2) * r, - (t2 * y1 - t1 * y2) * r, - (t2 * z1 - t1 * z2) * r); - - LLVector4a tdir( - (s1 * x2 - s2 * x1) * r, - (s1 * y2 - s2 * y1) * r, - (s1 * z2 - s2 * z1) * r); - - LLVector4a n = normal; - LLVector4a t = sdir; - - LLVector4a ncrosst; - ncrosst.setCross3(n,t); - - // Gram-Schmidt orthogonalize - n.mul(n.dot3(t).getF32()); - - LLVector4a tsubn; - tsubn.setSub(t,n); - - if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO) - { - tsubn.normalize3fast_checked(); - - // Calculate handedness - F32 handedness = ncrosst.dot3(tdir).getF32() < 0.f ? -1.f : 1.f; - - tsubn.getF32ptr()[3] = handedness; - - tangent_out = tsubn; - } - else - { - // degenerate, make up a value - // - tangent_out.set(0,0,1,1); - } - -} - //adapted from Lengyel, Eric. “Computing Tangent Space Basis Vectors for an Arbitrary Mesh”. Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent) -- cgit v1.2.3