diff options
author | Dave Parks <davep@lindenlab.com> | 2013-06-03 12:50:48 -0500 |
---|---|---|
committer | Dave Parks <davep@lindenlab.com> | 2013-06-03 12:50:48 -0500 |
commit | c3f14b915c38a4978745f12f1f816572cce4b5a0 (patch) | |
tree | f1a817ec82c8acefc950e724fd5fa3f068fc7181 /indra | |
parent | a16d32e82edb19b6a3df6516c9726ac5913c1689 (diff) |
NORSPEC-229 Fix for bad binormals on mirrored surfaces (use tangent calculator instead of binormal calculator, convert binormal centric code to tangent centric)
Diffstat (limited to 'indra')
43 files changed, 717 insertions, 609 deletions
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 3f06e6b99e..bf03c971cd 100755 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2079,9 +2079,9 @@ void LLVolume::regen() createVolumeFaces(); } -void LLVolume::genBinormals(S32 face) +void LLVolume::genTangents(S32 face) { - mVolumeFaces[face].createBinormals(); + mVolumeFaces[face].createTangents(); } LLVolume::~LLVolume() @@ -4392,7 +4392,7 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices, segments.push_back(vertices.size()); #if DEBUG_SILHOUETTE_BINORMALS vertices.push_back(face.mVertices[j].getPosition()); - vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].mBinormal*0.1f); + vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].mTangent*0.1f); normals.push_back(LLVector3(0,0,1)); normals.push_back(LLVector3(0,0,1)); segments.push_back(vertices.size()); @@ -4508,22 +4508,9 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices, } } -S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, - S32 face, - LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) -{ - LLVector4a starta, enda; - starta.load3(start.mV); - enda.load3(end.mV); - - return lineSegmentIntersect(starta, enda, face, intersection, tex_coord, normal, bi_normal); - -} - - S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, - LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) + LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent_out) { S32 hit_face = -1; @@ -4561,9 +4548,9 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en if (LLLineSegmentBoxIntersect(start, end, box_center, box_size)) { - if (bi_normal != NULL) // if the caller wants binormals, we may need to generate them + if (tangent_out != NULL) // if the caller wants tangents, we may need to generate them { - genBinormals(i); + genTangents(i); } if (isUnique()) @@ -4597,7 +4584,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en LLVector4a intersect = dir; intersect.mul(closest_t); intersect.add(start); - intersection->set(intersect.getF32ptr()); + *intersection = intersect; } @@ -4612,19 +4599,42 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en if (normal!= NULL) { - LLVector4* norm = (LLVector4*) face.mNormals; - - *normal = ((1.f - a - b) * LLVector3(norm[idx0]) + - a * LLVector3(norm[idx1]) + - b * LLVector3(norm[idx2])); + LLVector4a* norm = face.mNormals; + + LLVector4a n1,n2,n3; + n1 = norm[idx0]; + n1.mul(1.f-a-b); + + n2 = norm[idx1]; + n2.mul(a); + + n3 = norm[idx2]; + n3.mul(b); + + n1.add(n2); + n1.add(n3); + + *normal = n1; } - if (bi_normal != NULL) + if (tangent_out != NULL) { - LLVector4* binormal = (LLVector4*) face.mBinormals; - *bi_normal = ((1.f - a - b) * LLVector3(binormal[idx0]) + - a * LLVector3(binormal[idx1]) + - b * LLVector3(binormal[idx2])); + LLVector4a* tangents = face.mTangents; + + LLVector4a t1,t2,t3; + t1 = tangents[idx0]; + t1.mul(1.f-a-b); + + t2 = tangents[idx1]; + t2.mul(a); + + t3 = tangents[idx2]; + t3.mul(b); + + t1.add(t2); + t1.add(t3); + + *tangent_out = t1; } } } @@ -4637,7 +4647,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en face.createOctree(); } - LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, bi_normal); + LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, tangent_out); intersect.traverse(face.mOctree); if (intersect.mHitFace) { @@ -5183,7 +5193,7 @@ LLVolumeFace::LLVolumeFace() : mNumIndices(0), mPositions(NULL), mNormals(NULL), - mBinormals(NULL), + mTangents(NULL), mTexCoords(NULL), mIndices(NULL), mWeights(NULL), @@ -5206,7 +5216,7 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src) mNumIndices(0), mPositions(NULL), mNormals(NULL), - mBinormals(NULL), + mTangents(NULL), mTexCoords(NULL), mIndices(NULL), mWeights(NULL), @@ -5264,15 +5274,15 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) } - if (src.mBinormals) + if (src.mTangents) { - allocateBinormals(src.mNumVertices); - LLVector4a::memcpyNonAliased16((F32*) mBinormals, (F32*) src.mBinormals, vert_size); + allocateTangents(src.mNumVertices); + LLVector4a::memcpyNonAliased16((F32*) mTangents, (F32*) src.mTangents, vert_size); } else { - ll_aligned_free_16(mBinormals); - mBinormals = NULL; + ll_aligned_free_16(mTangents); + mTangents = NULL; } if (src.mWeights) @@ -5316,8 +5326,8 @@ void LLVolumeFace::freeData() mTexCoords = NULL; ll_aligned_free_16(mIndices); mIndices = NULL; - ll_aligned_free_16(mBinormals); - mBinormals = NULL; + ll_aligned_free_16(mTangents); + mTangents = NULL; ll_aligned_free_16(mWeights); mWeights = NULL; @@ -5897,7 +5907,7 @@ void LLVolumeFace::cacheOptimize() } LLVector4a* binorm = NULL; - if (mBinormals) + if (mTangents) { binorm = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); } @@ -5922,9 +5932,9 @@ void LLVolumeFace::cacheOptimize() { wght[cur_idx] = mWeights[idx]; } - if (mBinormals) + if (mTangents) { - binorm[cur_idx] = mBinormals[idx]; + binorm[cur_idx] = mTangents[idx]; } cur_idx++; @@ -5940,13 +5950,13 @@ void LLVolumeFace::cacheOptimize() ll_aligned_free_16(mNormals); ll_aligned_free_16(mTexCoords); ll_aligned_free_16(mWeights); - ll_aligned_free_16(mBinormals); + ll_aligned_free_16(mTangents); mPositions = pos; mNormals = norm; mTexCoords = tc; mWeights = wght; - mBinormals = binorm; + mTangents = binorm; //std::string result = llformat("ACMR pre/post: %.3f/%.3f -- %d triangles %d breaks", pre_acmr, post_acmr, mNumIndices/3, breaks); //llinfos << result << llendl; @@ -6027,7 +6037,7 @@ void LLVolumeFace::swapData(LLVolumeFace& rhs) { llswap(rhs.mPositions, mPositions); llswap(rhs.mNormals, mNormals); - llswap(rhs.mBinormals, mBinormals); + llswap(rhs.mTangents, mTangents); llswap(rhs.mTexCoords, mTexCoords); llswap(rhs.mIndices,mIndices); llswap(rhs.mNumVertices, mNumVertices); @@ -6116,22 +6126,11 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) corners[2].mTexCoord=swap; } - LLVector4a binormal; - - calc_binormal_from_triangle( binormal, - corners[0].getPosition(), corners[0].mTexCoord, - corners[1].getPosition(), corners[1].mTexCoord, - corners[2].getPosition(), corners[2].mTexCoord); - - binormal.normalize3fast(); - S32 size = (grid_size+1)*(grid_size+1); resizeVertices(size); - allocateBinormals(size); - + LLVector4a* pos = (LLVector4a*) mPositions; LLVector4a* norm = (LLVector4a*) mNormals; - LLVector4a* binorm = (LLVector4a*) mBinormals; LLVector2* tc = (LLVector2*) mTexCoords; for(int gx = 0;gx<grid_size+1;gx++) @@ -6150,8 +6149,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) *pos++ = newVert.getPosition(); *norm++ = baseVert.getNormal(); *tc++ = newVert.mTexCoord; - *binorm++ = binormal; - + if (gx == 0 && gy == 0) { min = newVert.getPosition(); @@ -6227,8 +6225,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK)) { resizeVertices(num_vertices+1); - allocateBinormals(num_vertices+1); - + if (!partial_build) { resizeIndices(num_indices+3); @@ -6237,8 +6234,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) else { resizeVertices(num_vertices); - allocateBinormals(num_vertices); - + if (!partial_build) { resizeIndices(num_indices); @@ -6272,8 +6268,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) LLVector2* tc = (LLVector2*) mTexCoords; LLVector4a* pos = (LLVector4a*) mPositions; LLVector4a* norm = (LLVector4a*) mNormals; - LLVector4a* binorm = (LLVector4a*) mBinormals; - + // Copy the vertices into the array for (S32 i = 0; i < num_vertices; i++) { @@ -6309,13 +6304,6 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) cuv = (min_uv + max_uv)*0.5f; - LLVector4a binormal; - calc_binormal_from_triangle(binormal, - *mCenter, cuv, - pos[0], tc[0], - pos[1], tc[1]); - binormal.normalize3fast(); - LLVector4a normal; LLVector4a d0, d1; @@ -6347,7 +6335,6 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) for (S32 i = 0; i < num_vertices; i++) { - binorm[i].load4a(binormal.getF32ptr()); norm[i].load4a(normal.getF32ptr()); } @@ -6589,59 +6576,65 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) return TRUE; } -void LLVolumeFace::createBinormals() +void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, + const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent); + +void LLVolumeFace::createTangents() { - if (!mBinormals) + if (!mTangents) { - allocateBinormals(mNumVertices); + allocateTangents(mNumVertices); - //generate binormals - LLVector4a* pos = mPositions; - LLVector2* tc = (LLVector2*) mTexCoords; - LLVector4a* binorm = (LLVector4a*) mBinormals; + //generate tangents + //LLVector4a* pos = mPositions; + //LLVector2* tc = (LLVector2*) mTexCoords; + LLVector4a* binorm = (LLVector4a*) mTangents; - LLVector4a* end = mBinormals+mNumVertices; + LLVector4a* end = mTangents+mNumVertices; while (binorm < end) { (*binorm++).clear(); } - binorm = mBinormals; + binorm = mTangents; + + CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices/3, mIndices, mTangents); - for (U32 i = 0; i < mNumIndices/3; i++) + /*for (U32 i = 0; i < mNumIndices/3; i++) { //for each triangle const U16& i0 = mIndices[i*3+0]; const U16& i1 = mIndices[i*3+1]; const U16& i2 = mIndices[i*3+2]; - //calculate binormal - LLVector4a binormal; - calc_binormal_from_triangle(binormal, + //calculate tangent + LLVector4a tangent; + calc_tangent_from_triangle(tangent, pos[i0], tc[i0], pos[i1], tc[i1], pos[i2], tc[i2]); //add triangle normal to vertices - binorm[i0].add(binormal); - binorm[i1].add(binormal); - binorm[i2].add(binormal); + binorm[i0].add(tangent); + binorm[i1].add(tangent); + binorm[i2].add(tangent); //even out quad contributions if (i % 2 == 0) { - binorm[i2].add(binormal); + binorm[i2].add(tangent); } else { - binorm[i1].add(binormal); + binorm[i1].add(tangent); } - } + }*/ + - //normalize binormals + //normalize tangents for (U32 i = 0; i < mNumVertices; i++) { - binorm[i].normalize3fast(); + //binorm[i].normalize3fast(); //bump map/planar projection code requires normals to be normalized mNormals[i].normalize3fast(); } @@ -6652,10 +6645,10 @@ void LLVolumeFace::resizeVertices(S32 num_verts) { ll_aligned_free_16(mPositions); ll_aligned_free_16(mNormals); - ll_aligned_free_16(mBinormals); + ll_aligned_free_16(mTangents); ll_aligned_free_16(mTexCoords); - mBinormals = NULL; + mTangents = NULL; if (num_verts) { @@ -6705,9 +6698,9 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con ll_assert_aligned(mTexCoords,16); - //just clear binormals - ll_aligned_free_16(mBinormals); - mBinormals = NULL; + //just clear tangents + ll_aligned_free_16(mTangents); + mTangents = NULL; mPositions[mNumVertices] = pos; mNormals[mNumVertices] = norm; @@ -6716,10 +6709,10 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con mNumVertices++; } -void LLVolumeFace::allocateBinormals(S32 num_verts) +void LLVolumeFace::allocateTangents(S32 num_verts) { - ll_aligned_free_16(mBinormals); - mBinormals = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); + ll_aligned_free_16(mTangents); + mTangents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); } void LLVolumeFace::allocateWeights(S32 num_verts) @@ -7231,53 +7224,87 @@ 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); +//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) +{ + //LLVector4a *tan1 = new LLVector4a[vertexCount * 2]; + LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a)); + + 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++; + + 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 F32* v1ptr = v1.getF32ptr(); + const F32* v2ptr = v2.getF32ptr(); + const F32* v3ptr = v3.getF32ptr(); - 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); + 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 r = 1.0F / (s1 * t2 - s2 * t1); + 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); + + tan1[i1].add(sdir); + tan1[i2].add(sdir); + tan1[i3].add(sdir); + + tan2[i1].add(tdir); + tan2[i2].add(tdir); + tan2[i3].add(tdir); + } + + for (U32 a = 0; a < vertexCount; a++) + { + LLVector4a n = normal[a]; + const LLVector4a& t = tan1[a]; + + LLVector4a ncrosst; + ncrosst.setCross3(n,t); + + // Gram-Schmidt orthogonalize + n.mul(n.dot3(t).getF32()); + + LLVector4a tsubn; + tsubn.setSub(t,n); + + tsubn.normalize3fast(); + + // Calculate handedness + F32 handedness = ncrosst.dot3(tan2[a]).getF32() < 0.f ? -1.f : 1.f; + + tsubn.getF32ptr()[3] = handedness; - 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 ); - } + tangent[a] = tsubn; + } + + ll_aligned_free_16(tan1); } + + diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index c845556557..164b8d6652 100755 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -844,12 +844,12 @@ private: public: BOOL create(LLVolume* volume, BOOL partial_build = FALSE); - void createBinormals(); + void createTangents(); void appendFace(const LLVolumeFace& face, LLMatrix4& transform, LLMatrix4& normal_tranform); void resizeVertices(S32 num_verts); - void allocateBinormals(S32 num_verts); + void allocateTangents(S32 num_verts); void allocateWeights(S32 num_verts); void resizeIndices(S32 num_indices); void fillFromLegacyData(std::vector<LLVolumeFace::VertexData>& v, std::vector<U16>& idx); @@ -916,7 +916,7 @@ public: LLVector4a* mPositions; LLVector4a* mNormals; - LLVector4a* mBinormals; + LLVector4a* mTangents; LLVector2* mTexCoords; U16* mIndices; @@ -980,7 +980,7 @@ public: void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); } void regen(); - void genBinormals(S32 face); + void genTangents(S32 face); BOOL isConvex() const; BOOL isCap(S32 face); @@ -1008,21 +1008,14 @@ public: //get the face index of the face that intersects with the given line segment at the point //closest to start. Moves end to the point of intersection. Returns -1 if no intersection. //Line segment must be in volume space. - S32 lineSegmentIntersect(const LLVector3& start, const LLVector3& end, + S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face = -1, // which face to check, -1 = ALL_SIDES - LLVector3* intersection = NULL, // return the intersection point + LLVector4a* intersection = NULL, // return the intersection point LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point - LLVector3* normal = NULL, // return the surface normal at the intersection point - LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point + LLVector4a* normal = NULL, // return the surface normal at the intersection point + LLVector4a* tangent = NULL // return the surface tangent at the intersection point ); - S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, - S32 face = 1, - LLVector3* intersection = NULL, - LLVector2* tex_coord = NULL, - LLVector3* normal = NULL, - LLVector3* bi_normal = NULL); - LLFaceID generateFaceMask(); BOOL isFaceMaskValid(LLFaceID face_mask); @@ -1081,21 +1074,12 @@ public: std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params); -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); - BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* center, const F32* size); BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size); BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, const LLVector4a& center, const LLVector4a& size); -BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir, - F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided); +//BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir, +// F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided); BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir, F32& intersection_a, F32& intersection_b, F32& intersection_t); diff --git a/indra/llmath/llvolumeoctree.cpp b/indra/llmath/llvolumeoctree.cpp index cc83cb7235..0728b49c1f 100755 --- a/indra/llmath/llvolumeoctree.cpp +++ b/indra/llmath/llvolumeoctree.cpp @@ -94,14 +94,14 @@ void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode<LLVolumeTria LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir, const LLVolumeFace* face, F32* closest_t, - LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) + LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) : mFace(face), mStart(start), mDir(dir), mIntersection(intersection), mTexCoord(tex_coord), mNormal(normal), - mBinormal(bi_normal), + mTangent(tangent), mClosestT(closest_t), mHitFace(false) { @@ -112,13 +112,7 @@ void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle> { LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) node->getListener(0); - /*const F32* start = mStart.getF32(); - const F32* end = mEnd.getF32(); - const F32* center = vl->mBounds[0].getF32(); - const F32* size = vl->mBounds[1].getF32();*/ - - //if (LLLineSegmentBoxIntersect(mStart, mEnd, vl->mBounds[0], vl->mBounds[1])) - if (LLLineSegmentBoxIntersect(mStart.getF32ptr(), mEnd.getF32ptr(), vl->mBounds[0].getF32ptr(), vl->mBounds[1].getF32ptr())) + if (LLLineSegmentBoxIntersect(mStart, mEnd, vl->mBounds[0], vl->mBounds[1])) { node->accept(this); for (S32 i = 0; i < node->getChildCount(); ++i) @@ -152,34 +146,60 @@ void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode<LLVolumeTriangle>* n LLVector4a intersect = mDir; intersect.mul(*mClosestT); intersect.add(mStart); - mIntersection->set(intersect.getF32ptr()); + *mIntersection = intersect; } + U32 idx0 = tri->mIndex[0]; + U32 idx1 = tri->mIndex[1]; + U32 idx2 = tri->mIndex[2]; if (mTexCoord != NULL) { LLVector2* tc = (LLVector2*) mFace->mTexCoords; - *mTexCoord = ((1.f - a - b) * tc[tri->mIndex[0]] + - a * tc[tri->mIndex[1]] + - b * tc[tri->mIndex[2]]); + *mTexCoord = ((1.f - a - b) * tc[idx0] + + a * tc[idx1] + + b * tc[idx2]); } if (mNormal != NULL) { - LLVector4* norm = (LLVector4*) mFace->mNormals; - - *mNormal = ((1.f - a - b) * LLVector3(norm[tri->mIndex[0]]) + - a * LLVector3(norm[tri->mIndex[1]]) + - b * LLVector3(norm[tri->mIndex[2]])); + LLVector4a* norm = mFace->mNormals; + + LLVector4a n1,n2,n3; + n1 = norm[idx0]; + n1.mul(1.f-a-b); + + n2 = norm[idx1]; + n2.mul(a); + + n3 = norm[idx2]; + n3.mul(b); + + n1.add(n2); + n1.add(n3); + + *mNormal = n1; } - if (mBinormal != NULL) + if (mTangent != NULL) { - LLVector4* binormal = (LLVector4*) mFace->mBinormals; - *mBinormal = ((1.f - a - b) * LLVector3(binormal[tri->mIndex[0]]) + - a * LLVector3(binormal[tri->mIndex[1]]) + - b * LLVector3(binormal[tri->mIndex[2]])); + LLVector4a* tangents = mFace->mTangents; + + LLVector4a t1,t2,t3; + t1 = tangents[idx0]; + t1.mul(1.f-a-b); + + t2 = tangents[idx1]; + t2.mul(a); + + t3 = tangents[idx2]; + t3.mul(b); + + t1.add(t2); + t1.add(t3); + + *mTangent = t1; } } } diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h index 9ae34a0c4e..80d6ced36d 100755 --- a/indra/llmath/llvolumeoctree.h +++ b/indra/llmath/llvolumeoctree.h @@ -137,16 +137,16 @@ public: LLVector4a mStart; LLVector4a mDir; LLVector4a mEnd; - LLVector3* mIntersection; + LLVector4a* mIntersection; LLVector2* mTexCoord; - LLVector3* mNormal; - LLVector3* mBinormal; + LLVector4a* mNormal; + LLVector4a* mTangent; F32* mClosestT; bool mHitFace; LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir, const LLVolumeFace* face, F32* closest_t, - LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal); + LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent); void traverse(const LLOctreeNode<LLVolumeTriangle>* node); diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 37b9c0e0e0..fea4ee2819 100755 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -977,7 +977,7 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedAttribs.push_back("texcoord3"); mReservedAttribs.push_back("diffuse_color"); mReservedAttribs.push_back("emissive"); - mReservedAttribs.push_back("binormal"); + mReservedAttribs.push_back("tangent"); mReservedAttribs.push_back("weight"); mReservedAttribs.push_back("weight4"); mReservedAttribs.push_back("clothing"); diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 08f2d30aa4..01541026b1 100755 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -342,7 +342,7 @@ S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] = sizeof(LLVector2), // TYPE_TEXCOORD3, sizeof(LLColor4U), // TYPE_COLOR, sizeof(LLColor4U), // TYPE_EMISSIVE, only alpha is used currently - sizeof(LLVector4), // TYPE_BINORMAL, + sizeof(LLVector4), // TYPE_TANGENT, sizeof(F32), // TYPE_WEIGHT, sizeof(LLVector4), // TYPE_WEIGHT4, sizeof(LLVector4), // TYPE_CLOTHWEIGHT, @@ -359,7 +359,7 @@ static std::string vb_type_name[] = "TYPE_TEXCOORD3", "TYPE_COLOR", "TYPE_EMISSIVE", - "TYPE_BINORMAL", + "TYPE_TANGENT", "TYPE_WEIGHT", "TYPE_WEIGHT4", "TYPE_CLOTHWEIGHT", @@ -542,16 +542,16 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) } } - if (sLastMask & MAP_BINORMAL) + if (sLastMask & MAP_TANGENT) { - if (!(data_mask & MAP_BINORMAL)) + if (!(data_mask & MAP_TANGENT)) { glClientActiveTextureARB(GL_TEXTURE2_ARB); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glClientActiveTextureARB(GL_TEXTURE0_ARB); } } - else if (data_mask & MAP_BINORMAL) + else if (data_mask & MAP_TANGENT) { glClientActiveTextureARB(GL_TEXTURE2_ARB); glEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -1354,7 +1354,7 @@ void LLVertexBuffer::setupVertexArray() 2, //TYPE_TEXCOORD3, 4, //TYPE_COLOR, 4, //TYPE_EMISSIVE, - 3, //TYPE_BINORMAL, + 4, //TYPE_TANGENT, 1, //TYPE_WEIGHT, 4, //TYPE_WEIGHT4, 4, //TYPE_CLOTHWEIGHT, @@ -1371,7 +1371,7 @@ void LLVertexBuffer::setupVertexArray() GL_FLOAT, //TYPE_TEXCOORD3, GL_UNSIGNED_BYTE, //TYPE_COLOR, GL_UNSIGNED_BYTE, //TYPE_EMISSIVE, - GL_FLOAT, //TYPE_BINORMAL, + GL_FLOAT, //TYPE_TANGENT, GL_FLOAT, //TYPE_WEIGHT, GL_FLOAT, //TYPE_WEIGHT4, GL_FLOAT, //TYPE_CLOTHWEIGHT, @@ -1388,7 +1388,7 @@ void LLVertexBuffer::setupVertexArray() false, //TYPE_TEXCOORD3, false, //TYPE_COLOR, false, //TYPE_EMISSIVE, - false, //TYPE_BINORMAL, + false, //TYPE_TANGENT, false, //TYPE_WEIGHT, false, //TYPE_WEIGHT4, false, //TYPE_CLOTHWEIGHT, @@ -1405,7 +1405,7 @@ void LLVertexBuffer::setupVertexArray() GL_FALSE, //TYPE_TEXCOORD3, GL_TRUE, //TYPE_COLOR, GL_TRUE, //TYPE_EMISSIVE, - GL_FALSE, //TYPE_BINORMAL, + GL_FALSE, //TYPE_TANGENT, GL_FALSE, //TYPE_WEIGHT, GL_FALSE, //TYPE_WEIGHT4, GL_FALSE, //TYPE_CLOTHWEIGHT, @@ -2078,9 +2078,13 @@ bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index, { return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index, count, map_range); } -bool LLVertexBuffer::getBinormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range) +bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range) { - return VertexBufferStrider<LLVector3,TYPE_BINORMAL>::get(*this, strider, index, count, map_range); + return VertexBufferStrider<LLVector3,TYPE_TANGENT>::get(*this, strider, index, count, map_range); +} +bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector4a>& strider, S32 index, S32 count, bool map_range) +{ + return VertexBufferStrider<LLVector4a,TYPE_TANGENT>::get(*this, strider, index, count, map_range); } bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index, S32 count, bool map_range) { @@ -2390,11 +2394,11 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]); glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr); } - if (data_mask & MAP_BINORMAL) + if (data_mask & MAP_TANGENT) { - S32 loc = TYPE_BINORMAL; - void* ptr = (void*)(base + mOffsets[TYPE_BINORMAL]); - glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], ptr); + S32 loc = TYPE_TANGENT; + void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]); + glVertexAttribPointerARB(loc, 4,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr); } if (data_mask & MAP_TEXCOORD0) { @@ -2472,10 +2476,10 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1])); glClientActiveTextureARB(GL_TEXTURE0_ARB); } - if (data_mask & MAP_BINORMAL) + if (data_mask & MAP_TANGENT) { glClientActiveTextureARB(GL_TEXTURE2_ARB); - glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL])); + glTexCoordPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TANGENT], (void*)(base + mOffsets[TYPE_TANGENT])); glClientActiveTextureARB(GL_TEXTURE0_ARB); } if (data_mask & MAP_TEXCOORD0) diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 1be9b79e84..04806c1d8c 100755 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -174,7 +174,7 @@ public: TYPE_TEXCOORD3, TYPE_COLOR, TYPE_EMISSIVE, - TYPE_BINORMAL, + TYPE_TANGENT, TYPE_WEIGHT, TYPE_WEIGHT4, TYPE_CLOTHWEIGHT, @@ -192,7 +192,7 @@ public: MAP_COLOR = (1<<TYPE_COLOR), MAP_EMISSIVE = (1<<TYPE_EMISSIVE), // These use VertexAttribPointer and should possibly be made generic - MAP_BINORMAL = (1<<TYPE_BINORMAL), + MAP_TANGENT = (1<<TYPE_TANGENT), MAP_WEIGHT = (1<<TYPE_WEIGHT), MAP_WEIGHT4 = (1<<TYPE_WEIGHT4), MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT), @@ -252,7 +252,8 @@ public: bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false); - bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false); + bool getTangentStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false); + bool getTangentStrider(LLStrider<LLVector4a>& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getTextureIndexStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getEmissiveStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false); diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl index 8ba75010a2..10144f3e16 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl @@ -30,7 +30,7 @@ ATTRIBUTE vec3 position; ATTRIBUTE vec4 diffuse_color; ATTRIBUTE vec3 normal; ATTRIBUTE vec2 texcoord0; -ATTRIBUTE vec3 binormal; +ATTRIBUTE vec4 tangent; VARYING vec3 vary_mat0; VARYING vec3 vary_mat1; @@ -52,8 +52,8 @@ void main() vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz); - vec3 b = normalize((mat * vec4(binormal.xyz+position.xyz, 1.0)).xyz-pos.xyz); - vec3 t = cross(b, n); + vec3 t = normalize((mat * vec4(tangent.xyz+position.xyz, 1.0)).xyz-pos.xyz); + vec3 b = cross(n, t) * tangent.w; vary_mat0 = vec3(t.x, b.x, n.x); vary_mat1 = vec3(t.y, b.y, n.y); diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl index c8d38bb8f7..9f9749394e 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl @@ -31,7 +31,7 @@ ATTRIBUTE vec3 position; ATTRIBUTE vec4 diffuse_color; ATTRIBUTE vec3 normal; ATTRIBUTE vec2 texcoord0; -ATTRIBUTE vec3 binormal; +ATTRIBUTE vec4 tangent; VARYING vec3 vary_mat0; VARYING vec3 vary_mat1; @@ -46,8 +46,8 @@ void main() vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; vec3 n = normalize(normal_matrix * normal); - vec3 b = normalize(normal_matrix * binormal); - vec3 t = cross(b, n); + vec3 t = normalize(normal_matrix * tangent.xyz); + vec3 b = cross(n, t) * tangent.w; vary_mat0 = vec3(t.x, b.x, n.x); vary_mat1 = vec3(t.y, b.y, n.y); diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl index 17aa0e32a7..df8e7a6c0b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -495,7 +495,7 @@ void main() //final_color.rgb *= 1 - spec.a * env_intensity; //final_specular.rgb *= specular_color.rgb; - vec4 final_normal = vec4(encode_normal(normalize(tnorm)), spec.a * env_intensity, 0.0); + vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, 0.0); final_specular.a = specular_color.a * norm.a; #else vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, 0.0); diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl index 0638dcfa55..b25032866b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl @@ -56,7 +56,7 @@ ATTRIBUTE vec2 texcoord0; #if HAS_NORMAL_MAP -ATTRIBUTE vec3 binormal; +ATTRIBUTE vec4 tangent; ATTRIBUTE vec2 texcoord1; VARYING vec3 vary_mat0; @@ -110,8 +110,8 @@ void main() #if HAS_SKIN vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz); #if HAS_NORMAL_MAP - vec3 b = normalize((mat*vec4(binormal.xyz+position.xyz,1.0)).xyz-pos.xyz); - vec3 t = cross(b, n); + vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz); + vec3 b = cross(n, t)*tangent.w; vary_mat0 = vec3(t.x, b.x, n.x); vary_mat1 = vec3(t.y, b.y, n.y); @@ -122,8 +122,9 @@ vary_normal = n; #else //HAS_SKIN vec3 n = normalize(normal_matrix * normal); #if HAS_NORMAL_MAP - vec3 b = normalize(normal_matrix * binormal); - vec3 t = cross(b, n); + vec3 t = normalize(normal_matrix * tangent.xyz); + vec3 b = cross(n,t)*tangent.w; + //vec3 t = cross(b,n) * binormal.w; vary_mat0 = vec3(t.x, b.x, n.x); vary_mat1 = vec3(t.y, b.y, n.y); diff --git a/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl b/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl index 44f1aa34a0..449d8d8b4e 100755 --- a/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl +++ b/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl @@ -25,12 +25,12 @@ uniform mat3 normal_matrix; -ATTRIBUTE vec3 binormal; +ATTRIBUTE vec4 tangent; -VARYING vec4 binormal_out; +VARYING vec4 tangent_out; void main() { - binormal_out = vec4(normal_matrix * binormal, 0.0); + tangent_out = vec4(normal_matrix * tangent.xyz), tangent.w); } diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 5ed8bbca50..c832e1401d 100755 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -239,7 +239,7 @@ void LLDrawPoolAlpha::render(S32 pass) if (mVertexShaderLevel > 0) { - renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2); + renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2); } else { diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index bb9126c162..7d0368a945 100755 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -207,7 +207,7 @@ public: RIGGED_NORMMAP_VMASK = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | - LLVertexBuffer::MAP_BINORMAL | + LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_COLOR | @@ -218,7 +218,7 @@ public: RIGGED_NORMSPEC_VMASK = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | - LLVertexBuffer::MAP_BINORMAL | + LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2 | @@ -247,7 +247,7 @@ public: RIGGED_DEFERRED_BUMP_MASK = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0 | - LLVertexBuffer::MAP_BINORMAL | + LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_WEIGHT4, RIGGED_DEFERRED_SIMPLE_MASK = LLVertexBuffer::MAP_VERTEX | diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 29076de54b..7152a34094 100755 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -856,7 +856,7 @@ void LLDrawPoolBump::renderDeferred(S32 pass) LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); - U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR; + U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR; for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) { diff --git a/indra/newview/lldrawpoolmaterials.h b/indra/newview/lldrawpoolmaterials.h index cfbd13f335..eae1aba87c 100644 --- a/indra/newview/lldrawpoolmaterials.h +++ b/indra/newview/lldrawpoolmaterials.h @@ -52,7 +52,7 @@ public: LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2 | LLVertexBuffer::MAP_COLOR | - LLVertexBuffer::MAP_BINORMAL + LLVertexBuffer::MAP_TANGENT }; /*virtual*/ U32 getVertexDataMask() { return VERTEX_DATA_MASK; } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 63919630fc..46d6a1a97f 100755 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -106,41 +106,6 @@ void planarProjection(LLVector2 &tc, const LLVector4a& normal, tc.mV[0] = 1.0f+((binormal.dot3(vec).getF32())*2 - 0.5f); } -void sphericalProjection(LLVector2 &tc, const LLVector4a& normal, - const LLVector4a &mCenter, const LLVector4a& vec) -{ //BROKEN - /*tc.mV[0] = acosf(vd.mNormal * LLVector3(1,0,0))/3.14159f; - - tc.mV[1] = acosf(vd.mNormal * LLVector3(0,0,1))/6.284f; - if (vd.mNormal.mV[1] > 0) - { - tc.mV[1] = 1.0f-tc.mV[1]; - }*/ -} - -void cylindricalProjection(LLVector2 &tc, const LLVector4a& normal, const LLVector4a &mCenter, const LLVector4a& vec) -{ //BROKEN - /*LLVector3 binormal; - float d = vd.mNormal * LLVector3(1,0,0); - if (d >= 0.5f || d <= -0.5f) - { - binormal = LLVector3(0,1,0); - } - else{ - binormal = LLVector3(1,0,0); - } - LLVector3 tangent = binormal % vd.mNormal; - - tc.mV[1] = -((tangent*vec)*2 - 0.5f); - - tc.mV[0] = acosf(vd.mNormal * LLVector3(1,0,0))/6.284f; - - if (vd.mNormal.mV[1] < 0) - { - tc.mV[0] = 1.0f-tc.mV[0]; - }*/ -} - //////////////////// // // LLFace implementation @@ -937,7 +902,7 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, // integrated with getGeometryVolume() for its texture coordinate // generation - but i'll leave that to someone more familiar // with the implications. -LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position, LLVector3 normal) +LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, const LLVector4a& position, const LLVector4a& normal) { LLVector2 tc = surface_coord; @@ -957,7 +922,9 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position, LLVector4a& center = *(mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter); LLVector4a volume_position; - volume_position.load3(mDrawablep->getVOVolume()->agentPositionToVolume(position).mV); + LLVector3 v_position(position.getF32ptr()); + + volume_position.load3(mDrawablep->getVOVolume()->agentPositionToVolume(v_position).mV); if (!mDrawablep->getVOVolume()->isVolumeGlobal()) { @@ -967,23 +934,14 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position, } LLVector4a volume_normal; - volume_normal.load3(mDrawablep->getVOVolume()->agentDirectionToVolume(normal).mV); + LLVector3 v_normal(normal.getF32ptr()); + volume_normal.load3(mDrawablep->getVOVolume()->agentDirectionToVolume(v_normal).mV); volume_normal.normalize3fast(); - switch (texgen) + if (texgen == LLTextureEntry::TEX_GEN_PLANAR) { - case LLTextureEntry::TEX_GEN_PLANAR: planarProjection(tc, volume_normal, center, volume_position); - break; - case LLTextureEntry::TEX_GEN_SPHERICAL: - sphericalProjection(tc, volume_normal, center, volume_position); - break; - case LLTextureEntry::TEX_GEN_CYLINDRICAL: - cylindricalProjection(tc, volume_normal, center, volume_position); - break; - default: - break; - } + } } if (mTextureMatrix) // if we have a texture matrix, use it @@ -1010,7 +968,12 @@ void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_po const LLMatrix4& vol_mat = getWorldMatrix(); const LLVolumeFace& vf = getViewerObject()->getVolume()->getVolumeFace(mTEOffset); const LLVector4a& normal4a = vf.mNormals[0]; - const LLVector4a& binormal4a = vf.mBinormals[0]; + const LLVector4a& tangent = vf.mTangents[0]; + + LLVector4a binormal4a; + binormal4a.setCross3(normal4a, tangent); + binormal4a.mul(tangent.getF32ptr()[3]); + LLVector2 projected_binormal; planarProjection(projected_binormal, normal4a, *vf.mCenter, binormal4a); projected_binormal -= LLVector2(0.5f, 0.5f); // this normally happens in xform() @@ -1138,7 +1101,7 @@ void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf) { LLFastTimer t(FTM_FACE_GEOM_VOLUME); U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | - LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_NORMAL; + LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL; if (vf.mWeights) { @@ -1151,11 +1114,11 @@ void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf) buff->allocateBuffer(vf.mNumVertices, 0, true); LLStrider<LLVector4a> f_vert; - LLStrider<LLVector3> f_binorm; + LLStrider<LLVector4a> f_tangent; LLStrider<LLVector3> f_norm; LLStrider<LLVector2> f_tc; - buff->getBinormalStrider(f_binorm); + buff->getTangentStrider(f_tangent); buff->getVertexStrider(f_vert); buff->getNormalStrider(f_norm); buff->getTexCoord0Strider(f_tc); @@ -1163,7 +1126,7 @@ void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf) for (U32 i = 0; i < vf.mNumVertices; ++i) { *f_vert++ = vf.mPositions[i]; - (*f_binorm++).set(vf.mBinormals[i].getF32ptr()); + *f_tangent++ = vf.mTangents[i]; *f_tc++ = vf.mTexCoords[i]; (*f_norm++).set(vf.mNormals[i].getF32ptr()); } @@ -1205,7 +1168,7 @@ static LLFastTimer::DeclareTimer FTM_FACE_GEOM_TEXTURE("Texture"); static LLFastTimer::DeclareTimer FTM_FACE_GEOM_COLOR("Color"); static LLFastTimer::DeclareTimer FTM_FACE_GEOM_EMISSIVE("Emissive"); static LLFastTimer::DeclareTimer FTM_FACE_GEOM_WEIGHTS("Weights"); -static LLFastTimer::DeclareTimer FTM_FACE_GEOM_BINORMAL("Binormal"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_TANGENT("Binormal"); static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX("Index"); static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX_TAIL("Tail"); static LLFastTimer::DeclareTimer FTM_FACE_POSITION_STORE("Pos"); @@ -1271,7 +1234,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, LLStrider<LLVector2> tex_coords2; LLStrider<LLVector3> norm; LLStrider<LLColor4U> colors; - LLStrider<LLVector3> binorm; + LLStrider<LLVector3> tangent; LLStrider<U16> indicesp; LLStrider<LLVector4> wght; @@ -1293,7 +1256,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, bool rebuild_emissive = rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE); bool rebuild_tcoord = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_TCOORD); bool rebuild_normal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL); - bool rebuild_binormal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_BINORMAL); + bool rebuild_tangent = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TANGENT); bool rebuild_weights = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_WEIGHT4); const LLTextureEntry *tep = mVObjp->getTE(f); @@ -1441,7 +1404,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices) { - mVObjp->getVolume()->genBinormals(f); + mVObjp->getVolume()->genTangents(f); LLFace::cacheFaceInVRAM(vf); buff = (LLVertexBuffer*) vf.mVertexBuffer.get(); } @@ -1526,15 +1489,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, glEndTransformFeedback(); } - if (rebuild_binormal) + if (rebuild_tangent) { - LLFastTimer t(FTM_FACE_GEOM_BINORMAL); - gTransformBinormalProgram.bind(); + LLFastTimer t(FTM_FACE_GEOM_TANGENT); + gTransformTangentProgram.bind(); - mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_BINORMAL, mGeomIndex, mGeomCount); + mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TANGENT, mGeomIndex, mGeomCount); glBeginTransformFeedback(GL_POINTS); - buff->setBuffer(LLVertexBuffer::MAP_BINORMAL); + buff->setBuffer(LLVertexBuffer::MAP_TANGENT); push_for_transform(buff, vf.mNumVertices, mGeomCount); glEndTransformFeedback(); } @@ -1596,7 +1559,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (bump_code) { - mVObjp->getVolume()->genBinormals(f); + mVObjp->getVolume()->genTangents(f); F32 offset_multiple; switch( bump_code ) { @@ -1645,7 +1608,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, U8 texgen = getTextureEntry()->getTexGen(); if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT) { //planar texgen needs binormals - mVObjp->getVolume()->genBinormals(f); + mVObjp->getVolume()->genTangents(f); } U8 tex_mode = 0; @@ -1887,20 +1850,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, vec.mul(scalea); - switch (texgen) + if (texgen == LLTextureEntry::TEX_GEN_PLANAR) { - case LLTextureEntry::TEX_GEN_PLANAR: - planarProjection(tc, norm, center, vec); - break; - case LLTextureEntry::TEX_GEN_SPHERICAL: - sphericalProjection(tc, norm, center, vec); - break; - case LLTextureEntry::TEX_GEN_CYLINDRICAL: - cylindricalProjection(tc, norm, center, vec); - break; - default: - break; - } + planarProjection(tc, norm, center, vec); + } } if (tex_mode && mTextureMatrix) @@ -1934,11 +1887,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, for (S32 i = 0; i < num_vertices; i++) { - LLVector4a tangent; - tangent.setCross3(vf.mBinormals[i], vf.mNormals[i]); + LLVector4a tangent = vf.mTangents[i]; + LLVector4a binorm; + binorm.setCross3(vf.mNormals[i], tangent); + binorm.mul(tangent.getF32ptr()[3]); + LLMatrix4a tangent_to_object; - tangent_to_object.setRows(tangent, vf.mBinormals[i], vf.mNormals[i]); + tangent_to_object.setRows(tangent, binorm, vf.mNormals[i]); LLVector4a t; tangent_to_object.rotate(binormal_dir, t); LLVector4a binormal; @@ -2056,21 +2012,28 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } } - if (rebuild_binormal) + if (rebuild_tangent) { - LLFastTimer t(FTM_FACE_GEOM_BINORMAL); - mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range); - F32* binormals = (F32*) binorm.get(); + LLFastTimer t(FTM_FACE_GEOM_TANGENT); + mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount, map_range); + F32* tangents = (F32*) tangent.get(); - mVObjp->getVolume()->genBinormals(f); + mVObjp->getVolume()->genTangents(f); + LLVector4Logical mask; + mask.clear(); + mask.setElement<3>(); + for (S32 i = 0; i < num_vertices; i++) { - LLVector4a binormal; - mat_normal.rotate(vf.mBinormals[i], binormal); - binormal.normalize3fast(); - binormal.store4a(binormals); - binormals += 4; + LLVector4a tangent_out; + mat_normal.rotate(vf.mTangents[i], tangent_out); + tangent_out.normalize3fast(); + + tangent_out.setSelectWithMask(mask, vf.mTangents[i], tangent_out); + tangent_out.store4a(tangents); + + tangents += 4; } if (map_range) diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 453d2c23d4..0687544d53 100755 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -118,7 +118,7 @@ public: LLXformMatrix* getXform() const { return mXform; } BOOL hasGeometry() const { return mGeomCount > 0; } LLVector3 getPositionAgent() const; - LLVector2 surfaceToTexture(LLVector2 surface_coord, LLVector3 position, LLVector3 normal); + LLVector2 surfaceToTexture(LLVector2 surface_coord, const LLVector4a& position, const LLVector4a& normal); void getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_pos, F32* scale) const; bool calcAlignedPlanarTE(const LLFace* align_to, LLVector2* st_offset, LLVector2* st_scale, F32* st_rot) const; diff --git a/indra/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp index 7e1025c41b..825c2b31be 100755 --- a/indra/newview/llhudicon.cpp +++ b/indra/newview/llhudicon.cpp @@ -202,7 +202,7 @@ void LLHUDIcon::render() renderIcon(FALSE); } -BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3* intersection) +BOOL LLHUDIcon::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection) { if (mHidden) return FALSE; @@ -275,23 +275,18 @@ BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& en LLVector4a upper_right; upper_right.setAdd(lower_right, y_scalea); - LLVector4a enda; - enda.load3(end.mV); - LLVector4a starta; - starta.load3(start.mV); LLVector4a dir; - dir.setSub(enda, starta); + dir.setSub(end, start); F32 a,b,t; - if (LLTriangleRayIntersect(upper_right, upper_left, lower_right, starta, dir, a,b,t) || - LLTriangleRayIntersect(upper_left, lower_left, lower_right, starta, dir, a,b,t)) + if (LLTriangleRayIntersect(upper_right, upper_left, lower_right, start, dir, a,b,t) || + LLTriangleRayIntersect(upper_left, lower_left, lower_right, start, dir, a,b,t)) { if (intersection) { dir.mul(t); - starta.add(dir); - *intersection = LLVector3(starta.getF32ptr()); + intersection->setAdd(start, dir); } return TRUE; } @@ -331,12 +326,12 @@ LLHUDIcon* LLHUDIcon::handlePick(S32 pick_id) } //static -LLHUDIcon* LLHUDIcon::lineSegmentIntersectAll(const LLVector3& start, const LLVector3& end, LLVector3* intersection) +LLHUDIcon* LLHUDIcon::lineSegmentIntersectAll(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection) { icon_instance_t::iterator icon_it; - LLVector3 local_end = end; - LLVector3 position; + LLVector4a local_end = end; + LLVector4a position; LLHUDIcon* ret = NULL; for(icon_it = sIconInstances.begin(); icon_it != sIconInstances.end(); ++icon_it) diff --git a/indra/newview/llhudicon.h b/indra/newview/llhudicon.h index 644daa0299..557252ab0b 100755 --- a/indra/newview/llhudicon.h +++ b/indra/newview/llhudicon.h @@ -62,7 +62,7 @@ public: static S32 generatePickIDs(S32 start_id, S32 step_size); static LLHUDIcon* handlePick(S32 pick_id); - static LLHUDIcon* lineSegmentIntersectAll(const LLVector3& start, const LLVector3& end, LLVector3* intersection); + static LLHUDIcon* lineSegmentIntersectAll(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection); static void updateAll(); static void cleanupDeadIcons(); @@ -73,7 +73,7 @@ public: BOOL getHidden() const { return mHidden; } void setHidden( BOOL hide ) { mHidden = hide; } - BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3* intersection); + BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection); protected: LLHUDIcon(const U8 type); diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index 3336097955..c3b49f739a 100755 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -116,7 +116,7 @@ LLHUDNameTag::~LLHUDNameTag() } -BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render) +BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a& intersection, BOOL debug_render) { if (!mVisible || mHidden) { @@ -199,15 +199,23 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3& bg_pos + height_vec, }; - LLVector3 dir = end-start; + LLVector4a dir; + dir.setSub(end,start); F32 a, b, t; - if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE) || - LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, a, b, t, FALSE) ) + LLVector4a v0,v1,v2,v3; + v0.load3(v[0].mV); + v1.load3(v[1].mV); + v2.load3(v[2].mV); + v3.load3(v[3].mV); + + if (LLTriangleRayIntersect(v0, v1, v2, start, dir, a, b, t) || + LLTriangleRayIntersect(v2, v3, v0, start, dir, a, b, t) ) { if (t <= 1.f) { - intersection = start + dir*t; + dir.mul(t); + intersection.setAdd(start, dir); return TRUE; } } diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h index 72647d5b26..38a4f18415 100755 --- a/indra/newview/llhudnametag.h +++ b/indra/newview/llhudnametag.h @@ -124,7 +124,7 @@ public: void setHidden( BOOL hide ) { mHidden = hide; } void shift(const LLVector3& offset); - BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render = FALSE); + BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a& intersection, BOOL debug_render = FALSE); static void shiftAll(const LLVector3& offset); static void addPickable(std::set<LLViewerObject*> &pick_list); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 252f129133..78401020a6 100755 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -3039,9 +3039,9 @@ void renderNormals(LLDrawable* drawablep) gGL.vertex3fv(face.mPositions[j].getF32ptr()); gGL.vertex3fv(p.getF32ptr()); - if (face.mBinormals) + if (face.mTangents) { - n.setMul(face.mBinormals[j], scale); + n.setMul(face.mTangents[j], scale); p.setAdd(face.mPositions[j], n); gGL.diffuseColor4f(0,1,1,1); @@ -3888,11 +3888,17 @@ void renderRaycast(LLDrawable* drawablep) gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]); gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix); - LLVector3 start, end; + LLVector4a start, end; if (transform) { - start = vobj->agentPositionToVolume(gDebugRaycastStart); - end = vobj->agentPositionToVolume(gDebugRaycastEnd); + LLVector3 v_start(gDebugRaycastStart.getF32ptr()); + LLVector3 v_end(gDebugRaycastEnd.getF32ptr()); + + v_start = vobj->agentPositionToVolume(v_start); + v_end = vobj->agentPositionToVolume(v_end); + + start.load3(v_start.mV); + end.load3(v_end.mV); } else { @@ -3900,11 +3906,8 @@ void renderRaycast(LLDrawable* drawablep) end = gDebugRaycastEnd; } - LLVector4a starta, enda; - starta.load3(start.mV); - enda.load3(end.mV); LLVector4a dir; - dir.setSub(enda, starta); + dir.setSub(end, start); gGL.flush(); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); @@ -3927,7 +3930,7 @@ void renderRaycast(LLDrawable* drawablep) ((LLVolumeFace*) &face)->createOctree(); } - LLRenderOctreeRaycast render(starta, dir, &t); + LLRenderOctreeRaycast render(start, dir, &t); render.traverse(face.mOctree); } @@ -3952,10 +3955,18 @@ void renderRaycast(LLDrawable* drawablep) // draw intersection point gGL.pushMatrix(); gGL.loadMatrix(gGLModelView); - LLVector3 translate = gDebugRaycastIntersection; + LLVector3 translate(gDebugRaycastIntersection.getF32ptr()); gGL.translatef(translate.mV[0], translate.mV[1], translate.mV[2]); LLCoordFrame orient; - orient.lookDir(gDebugRaycastNormal, gDebugRaycastBinormal); + LLVector4a debug_binormal; + + debug_binormal.setCross3(gDebugRaycastNormal, gDebugRaycastTangent); + debug_binormal.mul(gDebugRaycastTangent.getF32ptr()[3]); + + LLVector3 normal(gDebugRaycastNormal.getF32ptr()); + LLVector3 binormal(debug_binormal.getF32ptr()); + + orient.lookDir(normal, binormal); LLMatrix4 rotation; orient.getRotMatrixToParent(rotation); gGL.multMatrix((float*)rotation.mMatrix); @@ -4457,28 +4468,30 @@ BOOL LLSpatialPartition::isVisible(const LLVector3& v) return TRUE; } +LL_ALIGN_PREFIX(16) class LLOctreeIntersect : public LLSpatialGroup::OctreeTraveler { public: - LLVector3 mStart; - LLVector3 mEnd; + LL_ALIGN_16(LLVector4a mStart); + LL_ALIGN_16(LLVector4a mEnd); + S32 *mFaceHit; - LLVector3 *mIntersection; + LLVector4a *mIntersection; LLVector2 *mTexCoord; - LLVector3 *mNormal; - LLVector3 *mBinormal; + LLVector4a *mNormal; + LLVector4a *mTangent; LLDrawable* mHit; BOOL mPickTransparent; - LLOctreeIntersect(LLVector3 start, LLVector3 end, BOOL pick_transparent, - S32* face_hit, LLVector3* intersection, LLVector2* tex_coord, LLVector3* normal, LLVector3* binormal) + LLOctreeIntersect(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent, + S32* face_hit, LLVector4a* intersection, LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) : mStart(start), mEnd(end), mFaceHit(face_hit), mIntersection(intersection), mTexCoord(tex_coord), mNormal(normal), - mBinormal(binormal), + mTangent(tangent), mHit(NULL), mPickTransparent(pick_transparent) { @@ -4509,23 +4522,22 @@ public: size = group->mBounds[1]; center = group->mBounds[0]; - LLVector3 local_start = mStart; - LLVector3 local_end = mEnd; + LLVector4a local_start = mStart; + LLVector4a local_end = mEnd; if (group->mSpatialPartition->isBridge()) { LLMatrix4 local_matrix = group->mSpatialPartition->asBridge()->mDrawable->getRenderMatrix(); local_matrix.invert(); - - local_start = mStart * local_matrix; - local_end = mEnd * local_matrix; - } - LLVector4a start, end; - start.load3(local_start.mV); - end.load3(local_end.mV); + LLMatrix4a local_matrix4a; + local_matrix4a.loadu(local_matrix); - if (LLLineSegmentBoxIntersect(start, end, center, size)) + local_matrix4a.affineTransform(mStart, local_start); + local_matrix4a.affineTransform(mEnd, local_end); + } + + if (LLLineSegmentBoxIntersect(local_start, local_end, center, size)) { check(child); } @@ -4556,14 +4568,14 @@ public: if (vobj) { - LLVector3 intersection; + LLVector4a intersection; bool skip_check = false; if (vobj->isAvatar()) { LLVOAvatar* avatar = (LLVOAvatar*) vobj; if (avatar->isSelf() && LLFloater::isVisible(gFloaterTools)) { - LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal); + LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mTangent); if (hit) { mEnd = intersection; @@ -4579,7 +4591,7 @@ public: } } - if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal)) + if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mTangent)) { mEnd = intersection; // shorten ray so we only find CLOSER hits if (mIntersection) @@ -4594,19 +4606,19 @@ public: return false; } -}; +} LL_ALIGN_POSTFIX(16); -LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent, S32* face_hit, // return the face hit - LLVector3* intersection, // return the intersection point + LLVector4a* intersection, // return the intersection point LLVector2* tex_coord, // return the texture coordinates of the intersection point - LLVector3* normal, // return the surface normal at the intersection point - LLVector3* bi_normal // return the surface bi-normal at the intersection point + LLVector4a* normal, // return the surface normal at the intersection point + LLVector4a* tangent // return the surface tangent at the intersection point ) { - LLOctreeIntersect intersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, bi_normal); + LLOctreeIntersect intersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, tangent); LLDrawable* drawable = intersect.check(mOctree); return drawable; diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 8ccc3efd66..9732be90af 100755 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -204,7 +204,7 @@ public: }; }; -LL_ALIGN_PREFIX(16) +LL_ALIGN_PREFIX(64) class LLSpatialGroup : public LLOctreeListener<LLDrawable> { friend class LLSpatialPartition; @@ -490,13 +490,13 @@ public: LLSpatialGroup *put(LLDrawable *drawablep, BOOL was_visible = FALSE); BOOL remove(LLDrawable *drawablep, LLSpatialGroup *curp); - LLDrawable* lineSegmentIntersect(const LLVector3& start, const LLVector3& end, + LLDrawable* lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent, S32* face_hit, // return the face hit - LLVector3* intersection = NULL, // return the intersection point + LLVector4a* intersection = NULL, // return the intersection point LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point - LLVector3* normal = NULL, // return the surface normal at the intersection point - LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point + LLVector4a* normal = NULL, // return the surface normal at the intersection point + LLVector4a* tangent = NULL // return the surface tangent at the intersection point ); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 4e233d479a..198b13ee06 100755 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -3821,19 +3821,19 @@ LLViewerObject* LLViewerObject::getRootEdit() const } -BOOL LLViewerObject::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +BOOL LLViewerObject::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32* face_hit, - LLVector3* intersection, + LLVector4a* intersection, LLVector2* tex_coord, - LLVector3* normal, - LLVector3* bi_normal) + LLVector4a* normal, + LLVector4a* tangent) { return false; } -BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector3& start, const LLVector3& end) +BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector4a& start, const LLVector4a& end) { if (mDrawable.isNull() || mDrawable->isDead()) { @@ -3850,11 +3850,7 @@ BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector3& start, const LLVect size.setSub(ext[1], ext[0]); size.mul(0.5f); - LLVector4a starta, enda; - starta.load3(start.mV); - enda.load3(end.mV); - - return LLLineSegmentBoxIntersect(starta, enda, center, size); + return LLLineSegmentBoxIntersect(start, end, center, size); } U8 LLViewerObject::getMediaType() const diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index bcb74a8d1f..932846c211 100755 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -258,17 +258,17 @@ public: //detect if given line segment (in agent space) intersects with this viewer object. //returns TRUE if intersection detected and returns information about intersection - virtual BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, + virtual BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face = -1, // which face to check, -1 = ALL_SIDES BOOL pick_transparent = FALSE, S32* face_hit = NULL, // which face was hit - LLVector3* intersection = NULL, // return the intersection point + LLVector4a* intersection = NULL, // return the intersection point LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point - LLVector3* normal = NULL, // return the surface normal at the intersection point - LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point + LLVector4a* normal = NULL, // return the surface normal at the intersection point + LLVector4a* tangent = NULL // return the surface tangent at the intersection point ); - virtual BOOL lineSegmentBoundingBox(const LLVector3& start, const LLVector3& end); + virtual BOOL lineSegmentBoundingBox(const LLVector4a& start, const LLVector4a& end); virtual const LLVector3d getPositionGlobal() const; virtual const LLVector3 &getPositionRegion() const; diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 5f08e8ca2e..636214290d 100755 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -68,7 +68,7 @@ LLGLSLShader gTransformPositionProgram; LLGLSLShader gTransformTexCoordProgram; LLGLSLShader gTransformNormalProgram; LLGLSLShader gTransformColorProgram; -LLGLSLShader gTransformBinormalProgram; +LLGLSLShader gTransformTangentProgram; //utility shaders LLGLSLShader gOcclusionProgram; @@ -789,7 +789,7 @@ void LLViewerShaderMgr::unloadShaders() gTransformTexCoordProgram.unload(); gTransformNormalProgram.unload(); gTransformColorProgram.unload(); - gTransformBinormalProgram.unload(); + gTransformTangentProgram.unload(); mVertexShaderLevel[SHADER_LIGHTING] = 0; mVertexShaderLevel[SHADER_OBJECT] = 0; @@ -3043,7 +3043,7 @@ BOOL LLViewerShaderMgr::loadTransformShaders() gTransformTexCoordProgram.unload(); gTransformNormalProgram.unload(); gTransformColorProgram.unload(); - gTransformBinormalProgram.unload(); + gTransformTangentProgram.unload(); return TRUE; } @@ -3106,16 +3106,16 @@ BOOL LLViewerShaderMgr::loadTransformShaders() if (success) { - gTransformBinormalProgram.mName = "Binormal Transform Shader"; - gTransformBinormalProgram.mShaderFiles.clear(); - gTransformBinormalProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB)); - gTransformBinormalProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM]; + gTransformTangentProgram.mName = "Binormal Transform Shader"; + gTransformTangentProgram.mShaderFiles.clear(); + gTransformTangentProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB)); + gTransformTangentProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM]; const char* varyings[] = { - "binormal_out", + "tangent_out", }; - success = gTransformBinormalProgram.createShader(NULL, NULL, 1, varyings); + success = gTransformTangentProgram.createShader(NULL, NULL, 1, varyings); } diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 702a92c69c..8c7de05062 100755 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -217,7 +217,7 @@ extern LLGLSLShader gTransformPositionProgram; extern LLGLSLShader gTransformTexCoordProgram; extern LLGLSLShader gTransformNormalProgram; extern LLGLSLShader gTransformColorProgram; -extern LLGLSLShader gTransformBinormalProgram; +extern LLGLSLShader gTransformTangentProgram; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index fe4d5b3e4d..65a906d3c0 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -229,13 +229,13 @@ LLFrameTimer gAwayTriggerTimer; BOOL gShowOverlayTitle = FALSE; LLViewerObject* gDebugRaycastObject = NULL; -LLVector3 gDebugRaycastIntersection; -LLVector2 gDebugRaycastTexCoord; -LLVector3 gDebugRaycastNormal; -LLVector3 gDebugRaycastBinormal; -S32 gDebugRaycastFaceHit; -LLVector3 gDebugRaycastStart; -LLVector3 gDebugRaycastEnd; +LLVector4a gDebugRaycastIntersection; +LLVector2 gDebugRaycastTexCoord; +LLVector4a gDebugRaycastNormal; +LLVector4a gDebugRaycastTangent; +S32 gDebugRaycastFaceHit; +LLVector4a gDebugRaycastStart; +LLVector4a gDebugRaycastEnd; // HUD display lines in lower right BOOL gDisplayWindInfo = FALSE; @@ -2841,7 +2841,7 @@ void LLViewerWindow::updateUI() &gDebugRaycastIntersection, &gDebugRaycastTexCoord, &gDebugRaycastNormal, - &gDebugRaycastBinormal, + &gDebugRaycastTangent, &gDebugRaycastStart, &gDebugRaycastEnd); } @@ -3739,7 +3739,7 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_trans } LLHUDIcon* LLViewerWindow::cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth, - LLVector3* intersection) + LLVector4a* intersection) { S32 x = mouse_x; S32 y = mouse_y; @@ -3751,14 +3751,17 @@ LLHUDIcon* LLViewerWindow::cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 dep } // world coordinates of mouse + // VECTORIZE THIS LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y); LLVector3 mouse_point_global = LLViewerCamera::getInstance()->getOrigin(); LLVector3 mouse_world_start = mouse_point_global; LLVector3 mouse_world_end = mouse_point_global + mouse_direction_global * depth; - return LLHUDIcon::lineSegmentIntersectAll(mouse_world_start, mouse_world_end, intersection); - + LLVector4a start, end; + start.load3(mouse_world_start.mV); + end.load3(mouse_world_end.mV); + return LLHUDIcon::lineSegmentIntersectAll(start, end, intersection); } LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 depth, @@ -3766,12 +3769,12 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de S32 this_face, BOOL pick_transparent, S32* face_hit, - LLVector3 *intersection, + LLVector4a *intersection, LLVector2 *uv, - LLVector3 *normal, - LLVector3 *binormal, - LLVector3* start, - LLVector3* end) + LLVector4a *normal, + LLVector4a *tangent, + LLVector4a* start, + LLVector4a* end) { S32 x = mouse_x; S32 y = mouse_y; @@ -3806,17 +3809,27 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de if (!LLViewerJoystick::getInstance()->getOverrideCamera()) { //always set raycast intersection to mouse_world_end unless //flycam is on (for DoF effect) - gDebugRaycastIntersection = mouse_world_end; + gDebugRaycastIntersection.load3(mouse_world_end.mV); } + LLVector4a mw_start; + mw_start.load3(mouse_world_start.mV); + LLVector4a mw_end; + mw_end.load3(mouse_world_end.mV); + + LLVector4a mh_start; + mh_start.load3(mouse_hud_start.mV); + LLVector4a mh_end; + mh_end.load3(mouse_hud_end.mV); + if (start) { - *start = mouse_world_start; + *start = mw_start; } if (end) { - *end = mouse_world_end; + *end = mw_end; } LLViewerObject* found = NULL; @@ -3825,16 +3838,16 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de { if (this_object->isHUDAttachment()) // is a HUD object? { - if (this_object->lineSegmentIntersect(mouse_hud_start, mouse_hud_end, this_face, pick_transparent, - face_hit, intersection, uv, normal, binormal)) + if (this_object->lineSegmentIntersect(mh_start, mh_end, this_face, pick_transparent, + face_hit, intersection, uv, normal, tangent)) { found = this_object; } } else // is a world object { - if (this_object->lineSegmentIntersect(mouse_world_start, mouse_world_end, this_face, pick_transparent, - face_hit, intersection, uv, normal, binormal)) + if (this_object->lineSegmentIntersect(mw_start, mw_end, this_face, pick_transparent, + face_hit, intersection, uv, normal, tangent)) { found = this_object; } @@ -3842,20 +3855,20 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de } else // check ALL objects { - found = gPipeline.lineSegmentIntersectInHUD(mouse_hud_start, mouse_hud_end, pick_transparent, - face_hit, intersection, uv, normal, binormal); + found = gPipeline.lineSegmentIntersectInHUD(mh_start, mh_end, pick_transparent, + face_hit, intersection, uv, normal, tangent); if (!found) // if not found in HUD, look in world: { - found = gPipeline.lineSegmentIntersectInWorld(mouse_world_start, mouse_world_end, pick_transparent, - face_hit, intersection, uv, normal, binormal); + found = gPipeline.lineSegmentIntersectInWorld(mw_start, mw_end, pick_transparent, + face_hit, intersection, uv, normal, tangent); if (found && !pick_transparent) { gDebugRaycastIntersection = *intersection; } } } - + return found; } @@ -5112,6 +5125,7 @@ LLPickInfo::LLPickInfo() mXYCoords(-1, -1), mIntersection(), mNormal(), + mTangent(), mBinormal(), mHUDIcon(NULL), mPickTransparent(FALSE) @@ -5133,6 +5147,7 @@ LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos, mSTCoords(-1.f, -1.f), mXYCoords(-1, -1), mNormal(), + mTangent(), mBinormal(), mHUDIcon(NULL), mPickTransparent(pick_transparent) @@ -5143,19 +5158,26 @@ void LLPickInfo::fetchResults() { S32 face_hit = -1; - LLVector3 intersection, normal, binormal; + LLVector4a intersection, normal; + LLVector4a tangent; + LLVector2 uv; LLHUDIcon* hit_icon = gViewerWindow->cursorIntersectIcon(mMousePt.mX, mMousePt.mY, 512.f, &intersection); + LLVector4a origin; + origin.load3(LLViewerCamera::getInstance()->getOrigin().mV); F32 icon_dist = 0.f; if (hit_icon) { - icon_dist = (LLViewerCamera::getInstance()->getOrigin()-intersection).magVec(); + LLVector4a delta; + delta.setSub(intersection, origin); + icon_dist = delta.getLength3().getF32(); } + LLViewerObject* hit_object = gViewerWindow->cursorIntersect(mMousePt.mX, mMousePt.mY, 512.f, NULL, -1, mPickTransparent, &face_hit, - &intersection, &uv, &normal, &binormal); + &intersection, &uv, &normal, &tangent); mPickPt = mMousePt; @@ -5165,9 +5187,13 @@ void LLPickInfo::fetchResults() LLViewerObject* objectp = hit_object; + + LLVector4a delta; + delta.setSub(origin, intersection); + if (hit_icon && (!objectp || - icon_dist < (LLViewerCamera::getInstance()->getOrigin()-intersection).magVec())) + icon_dist < delta.getLength3().getF32())) { // was this name referring to a hud icon? mHUDIcon = hit_icon; @@ -5204,11 +5230,16 @@ void LLPickInfo::fetchResults() { mPickType = PICK_OBJECT; } - mObjectOffset = gAgentCamera.calcFocusOffset(objectp, intersection, mPickPt.mX, mPickPt.mY); + + LLVector3 v_intersection(intersection.getF32ptr()); + + mObjectOffset = gAgentCamera.calcFocusOffset(objectp, v_intersection, mPickPt.mX, mPickPt.mY); mObjectID = objectp->mID; mObjectFace = (te_offset == NO_FACE) ? -1 : (S32)te_offset; - mPosGlobal = gAgent.getPosGlobalFromAgent(intersection); + + + mPosGlobal = gAgent.getPosGlobalFromAgent(v_intersection); if (mWantSurfaceInfo) { @@ -5252,7 +5283,16 @@ void LLPickInfo::getSurfaceInfo() mIntersection = LLVector3(0,0,0); mNormal = LLVector3(0,0,0); mBinormal = LLVector3(0,0,0); + mTangent = LLVector4(0,0,0,0); + LLVector4a tangent; + LLVector4a intersection; + LLVector4a normal; + + tangent.clear(); + normal.clear(); + intersection.clear(); + LLViewerObject* objectp = getObject(); if (objectp) @@ -5260,10 +5300,10 @@ void LLPickInfo::getSurfaceInfo() if (gViewerWindow->cursorIntersect(llround((F32)mMousePt.mX), llround((F32)mMousePt.mY), 1024.f, objectp, -1, mPickTransparent, &mObjectFace, - &mIntersection, + &intersection, &mSTCoords, - &mNormal, - &mBinormal)) + &normal, + &tangent)) { // if we succeeded with the intersect above, compute the texture coordinates: @@ -5272,10 +5312,26 @@ void LLPickInfo::getSurfaceInfo() LLFace* facep = objectp->mDrawable->getFace(mObjectFace); if (facep) { - mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal); - } + mUVCoords = facep->surfaceToTexture(mSTCoords, intersection, normal); + } } + mIntersection.set(intersection.getF32ptr()); + mNormal.set(normal.getF32ptr()); + mTangent.set(tangent.getF32ptr()); + + //extrapoloate binormal from normal and tangent + + LLVector4a binormal; + binormal.setCross3(normal, tangent); + binormal.mul(tangent.getF32ptr()[3]); + + mBinormal.set(binormal.getF32ptr()); + + mBinormal.normalize(); + mNormal.normalize(); + mTangent.normalize(); + // and XY coords: updateXYCoords(); diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index b33488fd78..89f6e3bc26 100755 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -115,6 +115,7 @@ public: LLVector2 mSTCoords; LLCoordScreen mXYCoords; LLVector3 mNormal; + LLVector4 mTangent; LLVector3 mBinormal; BOOL mPickTransparent; void getSurfaceInfo(); @@ -357,19 +358,19 @@ public: void pickAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback)(const LLPickInfo& pick_info), BOOL pick_transparent = FALSE); LLPickInfo pickImmediate(S32 x, S32 y, BOOL pick_transparent); LLHUDIcon* cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth, - LLVector3* intersection); + LLVector4a* intersection); LLViewerObject* cursorIntersect(S32 mouse_x = -1, S32 mouse_y = -1, F32 depth = 512.f, LLViewerObject *this_object = NULL, S32 this_face = -1, BOOL pick_transparent = FALSE, S32* face_hit = NULL, - LLVector3 *intersection = NULL, + LLVector4a *intersection = NULL, LLVector2 *uv = NULL, - LLVector3 *normal = NULL, - LLVector3 *binormal = NULL, - LLVector3* start = NULL, - LLVector3* end = NULL); + LLVector4a *normal = NULL, + LLVector4a *tangent = NULL, + LLVector4a* start = NULL, + LLVector4a* end = NULL); // Returns a pointer to the last object hit @@ -499,13 +500,13 @@ extern LLFrameTimer gAwayTimer; // tracks time before setting the avatar awa extern LLFrameTimer gAwayTriggerTimer; // how long the avatar has been away extern LLViewerObject* gDebugRaycastObject; -extern LLVector3 gDebugRaycastIntersection; +extern LLVector4a gDebugRaycastIntersection; extern LLVector2 gDebugRaycastTexCoord; -extern LLVector3 gDebugRaycastNormal; -extern LLVector3 gDebugRaycastBinormal; +extern LLVector4a gDebugRaycastNormal; +extern LLVector4a gDebugRaycastTangent; extern S32 gDebugRaycastFaceHit; -extern LLVector3 gDebugRaycastStart; -extern LLVector3 gDebugRaycastEnd; +extern LLVector4a gDebugRaycastStart; +extern LLVector4a gDebugRaycastEnd; extern BOOL gDisplayCameraPos; extern BOOL gDisplayWindInfo; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 373a59ad6b..1a050800b4 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1388,19 +1388,20 @@ void LLVOAvatar::renderCollisionVolumes() if (mNameText.notNull()) { - LLVector3 unused; - mNameText->lineSegmentIntersect(LLVector3(0,0,0), LLVector3(0,0,1), unused, TRUE); + LLVector4a unused; + + mNameText->lineSegmentIntersect(unused, unused, unused, TRUE); } } -BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32* face_hit, - LLVector3* intersection, + LLVector4a* intersection, LLVector2* tex_coord, - LLVector3* normal, - LLVector3* bi_normal) + LLVector4a* normal, + LLVector4a* tangent) { if ((isSelf() && !gAgent.needsRenderAvatar()) || !LLPipeline::sPickAvatar) { @@ -1417,8 +1418,8 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e glh::matrix4f inverse = mat.inverse(); glh::matrix4f norm_mat = inverse.transpose(); - glh::vec3f p1(start.mV); - glh::vec3f p2(end.mV); + glh::vec3f p1(start.getF32ptr()); + glh::vec3f p2(end.getF32ptr()); inverse.mult_matrix_vec(p1); inverse.mult_matrix_vec(p2); @@ -1437,12 +1438,12 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e if (intersection) { - *intersection = LLVector3(res_pos.v); + intersection->load3(res_pos.v); } if (normal) { - *normal = LLVector3(res_norm.v); + normal->load3(res_norm.v); } return TRUE; @@ -1478,7 +1479,7 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e - LLVector3 position; + LLVector4a position; if (mNameText.notNull() && mNameText->lineSegmentIntersect(start, end, position)) { if (intersection) @@ -1492,14 +1493,14 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e return FALSE; } -LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end, +LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32* face_hit, - LLVector3* intersection, + LLVector4a* intersection, LLVector2* tex_coord, - LLVector3* normal, - LLVector3* bi_normal) + LLVector4a* normal, + LLVector4a* tangent) { if (isSelf() && !gAgent.needsRenderAvatar()) { @@ -1510,8 +1511,8 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector if (lineSegmentBoundingBox(start, end)) { - LLVector3 local_end = end; - LLVector3 local_intersection; + LLVector4a local_end = end; + LLVector4a local_intersection; for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); @@ -1525,7 +1526,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector { LLViewerObject* attached_object = (*attachment_iter); - if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, face_hit, &local_intersection, tex_coord, normal, bi_normal)) + if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, face_hit, &local_intersection, tex_coord, normal, tangent)) { local_end = local_intersection; if (intersection) diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index e7f249be69..b05eed344b 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -162,22 +162,22 @@ public: /*virtual*/ void updateRegion(LLViewerRegion *regionp); /*virtual*/ void updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax); /*virtual*/ void getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); - /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, + /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face = -1, // which face to check, -1 = ALL_SIDES BOOL pick_transparent = FALSE, S32* face_hit = NULL, // which face was hit - LLVector3* intersection = NULL, // return the intersection point + LLVector4a* intersection = NULL, // return the intersection point LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point - LLVector3* normal = NULL, // return the surface normal at the intersection point - LLVector3* bi_normal = NULL); // return the surface bi-normal at the intersection point - LLViewerObject* lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end, + LLVector4a* normal = NULL, // return the surface normal at the intersection point + LLVector4a* tangent = NULL); // return the surface tangent at the intersection point + LLViewerObject* lineSegmentIntersectRiggedAttachments(const LLVector4a& start, const LLVector4a& end, S32 face = -1, // which face to check, -1 = ALL_SIDES BOOL pick_transparent = FALSE, S32* face_hit = NULL, // which face was hit - LLVector3* intersection = NULL, // return the intersection point + LLVector4a* intersection = NULL, // return the intersection point LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point - LLVector3* normal = NULL, // return the surface normal at the intersection point - LLVector3* bi_normal = NULL); // return the surface bi-normal at the intersection point + LLVector4a* normal = NULL, // return the surface normal at the intersection point + LLVector4a* tangent = NULL); // return the surface tangent at the intersection point //-------------------------------------------------------------------- // LLCharacter interface and related diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index 6a25b765cf..cab5c4bc1d 100755 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -764,8 +764,8 @@ void LLVOGrass::updateDrawable(BOOL force_damped) } // virtual -BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp, - LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) +BOOL LLVOGrass::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp, + LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) { BOOL ret = FALSE; @@ -776,7 +776,8 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en return FALSE; } - LLVector3 dir = end-start; + LLVector4a dir; + dir.setSub(end, start); mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion()); @@ -844,23 +845,31 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en U32 idx0 = 0,idx1 = 0,idx2 = 0; - if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE)) + LLVector4a v0a,v1a,v2a,v3a; + + v0a.load3(v[0].mV); + v1a.load3(v[1].mV); + v2a.load3(v[2].mV); + v3a.load3(v[3].mV); + + + if (LLTriangleRayIntersect(v0a, v1a, v2a, start, dir, a, b, t)) { hit = TRUE; idx0 = 0; idx1 = 1; idx2 = 2; } - else if (LLTriangleRayIntersect(v[1], v[3], v[2], start, dir, a, b, t, FALSE)) + else if (LLTriangleRayIntersect(v1a, v3a, v2a, start, dir, a, b, t)) { hit = TRUE; idx0 = 1; idx1 = 3; idx2 = 2; } - else if (LLTriangleRayIntersect(v[2], v[1], v[0], start, dir, a, b, t, FALSE)) + else if (LLTriangleRayIntersect(v2a, v1a, v0a, start, dir, a, b, t)) { normal1 = -normal1; hit = TRUE; idx0 = 2; idx1 = 1; idx2 = 0; } - else if (LLTriangleRayIntersect(v[2], v[3], v[1], start, dir, a, b, t, FALSE)) + else if (LLTriangleRayIntersect(v2a, v3a, v1a, start, dir, a, b, t)) { normal1 = -normal1; hit = TRUE; @@ -883,7 +892,8 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en closest_t = t; if (intersection != NULL) { - *intersection = start+dir*closest_t; + dir.mul(closest_t); + intersection->setAdd(start, dir); } if (tex_coord != NULL) @@ -893,7 +903,7 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en if (normal != NULL) { - *normal = normal1; + normal->load3(normal1.mV); } ret = TRUE; } diff --git a/indra/newview/llvograss.h b/indra/newview/llvograss.h index b9835b8802..122806766d 100755 --- a/indra/newview/llvograss.h +++ b/indra/newview/llvograss.h @@ -75,14 +75,14 @@ public: /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); - /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, + /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face = -1, // which face to check, -1 = ALL_SIDES BOOL pick_transparent = FALSE, S32* face_hit = NULL, // which face was hit - LLVector3* intersection = NULL, // return the intersection point + LLVector4a* intersection = NULL, // return the intersection point LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point - LLVector3* normal = NULL, // return the surface normal at the intersection point - LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point + LLVector4a* normal = NULL, // return the surface normal at the intersection point + LLVector4a* tangent = NULL // return the surface tangent at the intersection point ); static S32 sMaxGrassSpecies; diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 65711d2339..6a7f26bdb5 100755 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -67,7 +67,7 @@ void LLVOPartGroup::restoreGL() { //TODO: optimize out binormal mask here. Specular and normal coords as well. - sVB = new LLVertexBuffer(VERTEX_DATA_MASK | LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, GL_STREAM_DRAW_ARB); + sVB = new LLVertexBuffer(VERTEX_DATA_MASK | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, GL_STREAM_DRAW_ARB); U32 count = LL_MAX_PARTICLE_COUNT; sVB->allocateBuffer(count*4, count*6, true); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index de15f0ef43..9a5c5831ca 100755 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -97,10 +97,10 @@ public: glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1])); glClientActiveTextureARB(GL_TEXTURE0_ARB); } - if (data_mask & MAP_BINORMAL) + if (data_mask & MAP_TANGENT) { glClientActiveTextureARB(GL_TEXTURE2_ARB); - glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL])); + glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TANGENT], (void*)(base + mOffsets[TYPE_TANGENT])); glClientActiveTextureARB(GL_TEXTURE0_ARB); } if (data_mask & MAP_TEXCOORD0) @@ -936,8 +936,8 @@ void LLVOSurfacePatch::getGeomSizesEast(const S32 stride, const S32 east_stride, } } -BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp, - LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) +BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp, + LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) { @@ -946,7 +946,9 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect return FALSE; } - LLVector3 delta = end-start; + LLVector4a da; + da.setSub(end, start); + LLVector3 delta(da.getF32ptr()); LLVector3 pdelta = delta; pdelta.mV[2] = 0; @@ -955,7 +957,9 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect F32 tdelta = 1.f/plength; - LLVector3 origin = start - mRegionp->getOriginAgent(); + LLVector3 v_start(start.getF32ptr()); + + LLVector3 origin = v_start - mRegionp->getOriginAgent(); if (mRegionp->getLandHeightRegion(origin) > origin.mV[2]) { @@ -1010,12 +1014,12 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect { sample.mV[2] = mRegionp->getLandHeightRegion(sample); } - *intersection = sample + mRegionp->getOriginAgent(); + intersection->load3((sample + mRegionp->getOriginAgent()).mV); } if (normal) { - *normal = mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample)); + normal->load3((mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample))).mV); } return TRUE; diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h index a15878368e..7b53219be8 100755 --- a/indra/newview/llvosurfacepatch.h +++ b/indra/newview/llvosurfacepatch.h @@ -79,14 +79,14 @@ public: void dirtyPatch(); void dirtyGeom(); - /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, + /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face = -1, // which face to check, -1 = ALL_SIDES BOOL pick_transparent = FALSE, S32* face_hit = NULL, // which face was hit - LLVector3* intersection = NULL, // return the intersection point + LLVector4a* intersection = NULL, // return the intersection point LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point - LLVector3* normal = NULL, // return the surface normal at the intersection point - LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point + LLVector4a* normal = NULL, // return the surface normal at the intersection point + LLVector4a* tangent = NULL // return the surface tangent at the intersection point ); BOOL mDirtiedPatch; diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index a1b36e3c8d..cd12cd9552 100755 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -1112,8 +1112,8 @@ void LLVOTree::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) mDrawable->setPositionGroup(pos); } -BOOL LLVOTree::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp, - LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) +BOOL LLVOTree::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp, + LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) { @@ -1142,16 +1142,19 @@ BOOL LLVOTree::lineSegmentIntersect(const LLVector3& start, const LLVector3& end LLVector3 pos, norm; - if (linesegment_tetrahedron(start, end, center, size, quat, pos, norm)) + LLVector3 start3(start.getF32ptr()); + LLVector3 end3(end.getF32ptr()); + + if (linesegment_tetrahedron(start3, end3, center, size, quat, pos, norm)) { if (intersection) { - *intersection = pos; + intersection->load3(pos.mV); } if (normal) { - *normal = norm; + normal->load3(norm.mV); } return TRUE; } diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h index 2a7eb21238..2ecb0303a1 100755 --- a/indra/newview/llvotree.h +++ b/indra/newview/llvotree.h @@ -106,14 +106,14 @@ public: F32 branches, F32 alpha); - /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, + /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face = -1, // which face to check, -1 = ALL_SIDES BOOL pick_transparent = FALSE, S32* face_hit = NULL, // which face was hit - LLVector3* intersection = NULL, // return the intersection point + LLVector4a* intersection = NULL, // return the intersection point LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point - LLVector3* normal = NULL, // return the surface normal at the intersection point - LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point + LLVector4a* normal = NULL, // return the surface normal at the intersection point + LLVector4a* tangent = NULL // return the surface tangent at the intersection point ); static S32 sMaxTreeSpecies; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index b107f43e4c..677d79d601 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1046,7 +1046,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo { //already cached break; } - volume->genBinormals(i); + volume->genTangents(i); LLFace::cacheFaceInVRAM(face); } } @@ -3612,8 +3612,8 @@ LLVector3 LLVOVolume::volumeDirectionToAgent(const LLVector3& dir) const } -BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp, - LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) +BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp, + LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) { if (!mbCanSelect @@ -3645,23 +3645,25 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e if (volume) { - LLVector3 v_start, v_end, v_dir; - + LLVector4a local_start = start; + LLVector4a local_end = end; + if (transform) { - v_start = agentPositionToVolume(start); - v_end = agentPositionToVolume(end); - } - else - { - v_start = start; - v_end = end; - } + LLVector3 v_start(start.getF32ptr()); + LLVector3 v_end(end.getF32ptr()); - LLVector3 p; - LLVector3 n; + v_start = agentPositionToVolume(v_start); + v_end = agentPositionToVolume(v_end); + + local_start.load3(v_start.mV); + local_end.load3(v_end.mV); + } + + LLVector4a p; + LLVector4a n; LLVector2 tc; - LLVector3 bn; + LLVector4a tn; if (intersection != NULL) { @@ -3678,9 +3680,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e n = *normal; } - if (bi_normal != NULL) + if (tangent != NULL) { - bn = *bi_normal; + tn = *tangent; } S32 face_hit = -1; @@ -3706,8 +3708,8 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e continue; } - face_hit = volume->lineSegmentIntersect(v_start, v_end, i, - &p, &tc, &n, &bn); + face_hit = volume->lineSegmentIntersect(local_start, local_end, i, + &p, &tc, &n, &tn); if (face_hit >= 0 && mDrawable->getNumFaces() > face_hit) { @@ -3716,7 +3718,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e if (face && (pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n)))) { - v_end = p; + local_end = p; if (face_hitp != NULL) { *face_hitp = face_hit; @@ -3726,7 +3728,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e { if (transform) { - *intersection = volumePositionToAgent(p); // must map back to agent space + LLVector3 v_p(p.getF32ptr()); + + intersection->load3(volumePositionToAgent(v_p).mV); // must map back to agent space } else { @@ -3738,27 +3742,37 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e { if (transform) { - *normal = volumeDirectionToAgent(n); + LLVector3 v_n(n.getF32ptr()); + normal->load3(volumeDirectionToAgent(v_n).mV); } else { *normal = n; } - (*normal).normVec(); + (*normal).normalize3fast(); } - if (bi_normal != NULL) + if (tangent != NULL) { if (transform) { - *bi_normal = volumeDirectionToAgent(bn); + LLVector3 v_tn(tn.getF32ptr()); + + LLVector4a trans_tangent; + trans_tangent.load3(volumeDirectionToAgent(v_tn).mV); + + LLVector4Logical mask; + mask.clear(); + mask.setElement<3>(); + + tangent->setSelectWithMask(mask, tn, trans_tangent); } else { - *bi_normal = bn; + *tangent = tn; } - (*bi_normal).normVec(); + (*tangent).normalize3fast(); } if (tex_coord != NULL) @@ -4038,7 +4052,7 @@ static LLFastTimer::DeclareTimer FTM_REGISTER_FACE("Register Face"); void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type) { LLFastTimer t(FTM_REGISTER_FACE); - if (type == LLRenderPass::PASS_ALPHA && facep->getTextureEntry()->getMaterialParams().notNull() && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_BINORMAL)) + if (type == LLRenderPass::PASS_ALPHA && facep->getTextureEntry()->getMaterialParams().notNull() && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT)) { LL_WARNS("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL; } @@ -4747,11 +4761,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (mat->getNormalID().notNull()) { if (mat->getSpecularID().notNull()) - { //has normal and specular maps (needs texcoord1, texcoord2, and binormal) + { //has normal and specular maps (needs texcoord1, texcoord2, and tangent) normspec_faces.push_back(facep); } else - { //has normal map (needs texcoord1 and binormal) + { //has normal map (needs texcoord1 and tangent) norm_faces.push_back(facep); } } @@ -4765,7 +4779,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } } else if (te->getBumpmap()) - { //needs normal + binormal + { //needs normal + tangent bump_faces.push_back(facep); } else if (te->getShiny() || !te->getFullbright()) @@ -4781,7 +4795,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) else { if (te->getBumpmap() && LLPipeline::sRenderBump) - { //needs normal + binormal + { //needs normal + tangent bump_faces.push_back(facep); } else if ((te->getShiny() && LLPipeline::sRenderBump) || @@ -4822,7 +4836,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) U32 bump_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; U32 fullbright_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; - U32 norm_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_BINORMAL; + U32 norm_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TANGENT; U32 normspec_mask = norm_mask | LLVertexBuffer::MAP_TEXCOORD2; U32 spec_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD2; @@ -4841,9 +4855,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (batch_textures) { - bump_mask = bump_mask | LLVertexBuffer::MAP_BINORMAL; + bump_mask = bump_mask | LLVertexBuffer::MAP_TANGENT; simple_mask = simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX; - alpha_mask = alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2; + alpha_mask = alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2; fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX; } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 928ff7f66b..7503f8c5aa 100755 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -137,14 +137,14 @@ public: /*virtual*/ U32 getTriangleCount(S32* vcount = NULL) const; /*virtual*/ U32 getHighLODTriangleCount(); - /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, + /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face = -1, // which face to check, -1 = ALL_SIDES BOOL pick_transparent = FALSE, S32* face_hit = NULL, // which face was hit - LLVector3* intersection = NULL, // return the intersection point + LLVector4a* intersection = NULL, // return the intersection point LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point - LLVector3* normal = NULL, // return the surface normal at the intersection point - LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point + LLVector4a* normal = NULL, // return the surface normal at the intersection point + LLVector4a* tangent = NULL // return the surface tangent at the intersection point ); LLVector3 agentPositionToVolume(const LLVector3& pos) const; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 6dc89742ec..cbcf3165c4 100755 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -6886,20 +6886,20 @@ void LLPipeline::setRenderHighlightTextureChannel(LLRender::eTexIndex channel) sRenderHighlightTextureChannel = channel; } -LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end, +LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent, S32* face_hit, - LLVector3* intersection, // return the intersection point + LLVector4a* intersection, // return the intersection point LLVector2* tex_coord, // return the texture coordinates of the intersection point - LLVector3* normal, // return the surface normal at the intersection point - LLVector3* bi_normal // return the surface bi-normal at the intersection point + LLVector4a* normal, // return the surface normal at the intersection point + LLVector4a* tangent // return the surface tangent at the intersection point ) { LLDrawable* drawable = NULL; - LLVector3 local_end = end; + LLVector4a local_end = end; - LLVector3 position; + LLVector4a position; sPickAvatar = FALSE; //LLToolMgr::getInstance()->inBuildMode() ? FALSE : TRUE; @@ -6919,7 +6919,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, LLSpatialPartition* part = region->getSpatialPartition(j); if (part && hasRenderType(part->mDrawableType)) { - LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, bi_normal); + LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, tangent); if (hit) { drawable = hit; @@ -6934,8 +6934,8 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, { //save hit info in case we need to restore //due to attachment override - LLVector3 local_normal; - LLVector3 local_binormal; + LLVector4a local_normal; + LLVector4a local_tangent; LLVector2 local_texcoord; S32 local_face_hit = -1; @@ -6947,9 +6947,9 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, { local_texcoord = *tex_coord; } - if (bi_normal) + if (tangent) { - local_binormal = *bi_normal; + local_tangent = *tangent; } if (normal) { @@ -6968,12 +6968,15 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_BRIDGE); if (part && hasRenderType(part->mDrawableType)) { - LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, bi_normal); + LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, tangent); if (hit) { + LLVector4a delta; + delta.setSub(position, local_end); + if (!drawable || !drawable->getVObj()->isAttachment() || - (position-local_end).magVec() > ATTACHMENT_OVERRIDE_DIST) + delta.getLength3().getF32() > ATTACHMENT_OVERRIDE_DIST) { //avatar overrides if previously hit drawable is not an attachment or //attachment is far enough away from detected intersection drawable = hit; @@ -6991,9 +6994,9 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, { *tex_coord = local_texcoord; } - if (bi_normal) + if (tangent) { - *bi_normal = local_binormal; + *tangent = local_tangent; } if (normal) { @@ -7027,13 +7030,13 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, return drawable ? drawable->getVObj().get() : NULL; } -LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, const LLVector3& end, +LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent, S32* face_hit, - LLVector3* intersection, // return the intersection point + LLVector4a* intersection, // return the intersection point LLVector2* tex_coord, // return the texture coordinates of the intersection point - LLVector3* normal, // return the surface normal at the intersection point - LLVector3* bi_normal // return the surface bi-normal at the intersection point + LLVector4a* normal, // return the surface normal at the intersection point + LLVector4a* tangent // return the surface tangent at the intersection point ) { LLDrawable* drawable = NULL; @@ -7053,7 +7056,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, co LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD); if (part) { - LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, bi_normal); + LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, tangent); if (hit) { drawable = hit; @@ -7513,13 +7516,18 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) { if (LLViewerJoystick::getInstance()->getOverrideCamera()) { //focus on point under cursor - focus_point = gDebugRaycastIntersection; + focus_point.set(gDebugRaycastIntersection.getF32ptr()); } else if (gAgentCamera.cameraMouselook()) { //focus on point under mouselook crosshairs + LLVector4a result; + result.clear(); + gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, NULL, - &focus_point); + &result); + + focus_point.set(result.getF32ptr()); } else { diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index a8362953b4..2c023a6f70 100755 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -188,21 +188,21 @@ public: void markMeshDirty(LLSpatialGroup* group); //get the object between start and end that's closest to start. - LLViewerObject* lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end, + LLViewerObject* lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent, S32* face_hit, // return the face hit - LLVector3* intersection = NULL, // return the intersection point + LLVector4a* intersection = NULL, // return the intersection point LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point - LLVector3* normal = NULL, // return the surface normal at the intersection point - LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point + LLVector4a* normal = NULL, // return the surface normal at the intersection point + LLVector4a* tangent = NULL // return the surface tangent at the intersection point ); - LLViewerObject* lineSegmentIntersectInHUD(const LLVector3& start, const LLVector3& end, + LLViewerObject* lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent, S32* face_hit, // return the face hit - LLVector3* intersection = NULL, // return the intersection point + LLVector4a* intersection = NULL, // return the intersection point LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point - LLVector3* normal = NULL, // return the surface normal at the intersection point - LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point + LLVector4a* normal = NULL, // return the surface normal at the intersection point + LLVector4a* tangent = NULL // return the surface tangent at the intersection point ); // Something about these textures has changed. Dirty them. |