From 8919f4811a7dcaf47dc58159e0ba4ba042183325 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 21 May 2010 23:55:18 -0500 Subject: blah --- indra/llmath/llvolume.cpp | 262 +++++++++++++++++++++++++++++++++------------- indra/llmath/llvolume.h | 27 +++-- indra/llmath/v3math.h | 15 +++ 3 files changed, 226 insertions(+), 78 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 5ffc61ce9c..4e342b0b48 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -43,10 +43,12 @@ #include "v4math.h" #include "m4math.h" #include "m3math.h" +#include "llmatrix4a.h" #include "lldarray.h" #include "llvolume.h" #include "llstl.h" #include "llsdserialize.h" +#include "llvector4a.h" #define DEBUG_SILHOUETTE_BINORMALS 0 #define DEBUG_SILHOUETTE_NORMALS 0 // TomY: Use this to display normals using the silhouette @@ -1992,11 +1994,10 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) LLVolumeFace& face = mVolumeFaces[i]; - face.mHasBinormals = false; - //copy out indices - face.mIndices.resize(idx.size()/2); - if (idx.empty() || face.mIndices.size() < 3) + face.resizeIndices(idx.size()/2); + + if (idx.empty() || face.mNumIndices < 3) { //why is there an empty index list? llerrs <<"WTF?" << llendl; continue; @@ -2010,7 +2011,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) //copy out vertices U32 num_verts = pos.size()/(3*2); - face.mVertices.resize(num_verts); + face.resizeVertices(num_verts); if (mdl[i].has("Weights")) { @@ -2059,7 +2060,6 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) LLVector3 max_pos; LLVector2 min_tc; LLVector2 max_tc; - min_pos.setValue(mdl[i]["PositionDomain"]["Min"]); max_pos.setValue(mdl[i]["PositionDomain"]["Max"]); @@ -2074,36 +2074,44 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) min = max = LLVector3(0,0,0); + F32* pos_out = face.mPositions; + F32* norm_out = face.mNormals; + F32* tc_out = face.mTexCoords; + for (U32 j = 0; j < num_verts; ++j) { U16* v = (U16*) &(pos[j*3*2]); - face.mVertices[j].mPosition.setVec( - (F32) v[0] / 65535.f * pos_range.mV[0] + min_pos.mV[0], - (F32) v[1] / 65535.f * pos_range.mV[1] + min_pos.mV[1], - (F32) v[2] / 65535.f * pos_range.mV[2] + min_pos.mV[2]); + pos_out[0] = (F32) v[0] / 65535.f * pos_range.mV[0] + min_pos.mV[0]; + pos_out[1] = (F32) v[1] / 65535.f * pos_range.mV[1] + min_pos.mV[1]; + pos_out[2] = (F32) v[2] / 65535.f * pos_range.mV[2] + min_pos.mV[2]; + if (j == 0) { - min = max = face.mVertices[j].mPosition; + min = max = LLVector3(pos_out); } else { - update_min_max(min,max,face.mVertices[j].mPosition); + update_min_max(min,max,pos_out); } + pos_out += 4; + U16* n = (U16*) &(norm[j*3*2]); - face.mVertices[j].mNormal.setVec( - (F32) n[0] / 65535.f * 2.f - 1.f, - (F32) n[1] / 65535.f * 2.f - 1.f, - (F32) n[2] / 65535.f * 2.f - 1.f); + + norm_out[0] = (F32) n[0] / 65535.f * 2.f - 1.f; + norm_out[1] = (F32) n[1] / 65535.f * 2.f - 1.f; + norm_out[2] = (F32) n[2] / 65535.f * 2.f - 1.f; + norm_out += 4; U16* t = (U16*) &(tc[j*2*2]); - face.mVertices[j].mTexCoord.setVec( - (F32) t[0] / 65535.f * tc_range.mV[0] + min_tc.mV[0], - (F32) t[1] / 65535.f * tc_range.mV[1] + min_tc.mV[1]); + tc_out[0] = (F32) t[0] / 65535.f * tc_range.mV[0] + min_tc.mV[0]; + tc_out[1] = (F32) t[1] / 65535.f * tc_range.mV[1] + min_tc.mV[1]; + + tc_out += 8; } @@ -2133,24 +2141,29 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) if (do_reflect_x) { - for (S32 i = 0; i < face.mVertices.size(); i++) + LLVector4a* p = (LLVector4a*) face.mPositions; + LLVector4a* n = (LLVector4a*) face.mNormals; + + for (S32 i = 0; i < face.mNumVertices; i++) { - face.mVertices[i].mPosition.mV[VX] *= -1.0f; - face.mVertices[i].mNormal.mV[VX] *= -1.0f; + p[i].mul(-1.0f); + n[i].mul(-1.0f); } } if (do_invert_normals) { - for (S32 i = 0; i < face.mVertices.size(); i++) + LLVector4a* n = (LLVector4a*) face.mNormals; + + for (S32 i = 0; i < face.mNumVertices; i++) { - face.mVertices[i].mNormal *= -1.0f; + n[i].mul(-1.0f); } } if (do_reverse_triangles) { - for (U32 j = 0; j < face.mIndices.size(); j += 3) + for (U32 j = 0; j < face.mNumIndices; j += 3) { // swap the 2nd and 3rd index S32 swap = face.mIndices[j+1]; @@ -2215,9 +2228,28 @@ void LLVolume::makeTetrahedron() tetrahedron_set_normal(cv); - face.mVertices.push_back(cv[0]); - face.mVertices.push_back(cv[1]); - face.mVertices.push_back(cv[2]); + face.resizeVertices(12); + face.resizeIndices(12); + + LLVector4a* v = (LLVector4a*) face.mPositions; + LLVector4a* n = (LLVector4a*) face.mNormals; + LLVector2* tc = (LLVector2*) face.mTexCoords; + + v[0].load3(cv[0].mPosition.mV); + v[1].load3(cv[1].mPosition.mV); + v[2].load3(cv[2].mPosition.mV); + v += 3; + + n[0].load3(cv[0].mNormal.mV); + n[1].load3(cv[1].mNormal.mV); + n[2].load3(cv[2].mNormal.mV); + n += 3; + + tc[0] = cv[0].mTexCoord; + tc[1] = cv[1].mTexCoord; + tc[2] = cv[2].mTexCoord; + tc += 3; + //side 2 cv[0].mPosition = p[3]; @@ -2226,9 +2258,20 @@ void LLVolume::makeTetrahedron() tetrahedron_set_normal(cv); - face.mVertices.push_back(cv[0]); - face.mVertices.push_back(cv[1]); - face.mVertices.push_back(cv[2]); + v[0].load3(cv[0].mPosition.mV); + v[1].load3(cv[1].mPosition.mV); + v[2].load3(cv[2].mPosition.mV); + v += 3; + + n[0].load3(cv[0].mNormal.mV); + n[1].load3(cv[1].mNormal.mV); + n[2].load3(cv[2].mNormal.mV); + n += 3; + + tc[0] = cv[0].mTexCoord; + tc[1] = cv[1].mTexCoord; + tc[2] = cv[2].mTexCoord; + tc += 3; //side 3 cv[0].mPosition = p[3]; @@ -2237,9 +2280,20 @@ void LLVolume::makeTetrahedron() tetrahedron_set_normal(cv); - face.mVertices.push_back(cv[0]); - face.mVertices.push_back(cv[1]); - face.mVertices.push_back(cv[2]); + v[0].load3(cv[0].mPosition.mV); + v[1].load3(cv[1].mPosition.mV); + v[2].load3(cv[2].mPosition.mV); + v += 3; + + n[0].load3(cv[0].mNormal.mV); + n[1].load3(cv[1].mNormal.mV); + n[2].load3(cv[2].mNormal.mV); + n += 3; + + tc[0] = cv[0].mTexCoord; + tc[1] = cv[1].mTexCoord; + tc[2] = cv[2].mTexCoord; + tc += 3; //side 4 cv[0].mPosition = p[2]; @@ -2248,14 +2302,25 @@ void LLVolume::makeTetrahedron() tetrahedron_set_normal(cv); - face.mVertices.push_back(cv[0]); - face.mVertices.push_back(cv[1]); - face.mVertices.push_back(cv[2]); + v[0].load3(cv[0].mPosition.mV); + v[1].load3(cv[1].mPosition.mV); + v[2].load3(cv[2].mPosition.mV); + v += 3; + + n[0].load3(cv[0].mNormal.mV); + n[1].load3(cv[1].mNormal.mV); + n[2].load3(cv[2].mNormal.mV); + n += 3; + + tc[0] = cv[0].mTexCoord; + tc[1] = cv[1].mTexCoord; + tc[2] = cv[2].mTexCoord; + tc += 3; //set index buffer - for (U32 i = 0; i < 12; i++) + for (U16 i = 0; i < 12; i++) { - face.mIndices.push_back(i); + face.mIndices[i] = i; } mVolumeFaces.push_back(face); @@ -3831,7 +3896,7 @@ S32 LLVolume::getNumTriangles() const for (S32 i = 0; i < getNumVolumeFaces(); ++i) { - triangle_count += getVolumeFace(i).mIndices.size()/3; + triangle_count += getVolumeFace(i).mNumIndices/3; } return triangle_count; @@ -3844,13 +3909,22 @@ S32 LLVolume::getNumTriangles() const void LLVolume::generateSilhouetteVertices(std::vector &vertices, std::vector &normals, std::vector &segments, - const LLVector3& obj_cam_vec, - const LLMatrix4& mat, - const LLMatrix3& norm_mat, + const LLVector3& obj_cam_vec_in, + const LLMatrix4& mat_in, + const LLMatrix3& norm_mat_in, S32 face_mask) { LLMemType m1(LLMemType::MTYPE_VOLUME); + LLMatrix4a mat; + mat.loadu(mat_in); + + LLMatrix4a norm_mat; + norm_mat.loadu(norm_mat_in); + + LLVector4a obj_cam_vec; + obj_cam_vec.load3(obj_cam_vec_in.mV); + vertices.clear(); normals.clear(); segments.clear(); @@ -3868,7 +3942,7 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, LLVolumeFace& face = *iter; if (!(face_mask & (0x1 << cur_index++)) || - face.mIndices.empty() || face.mEdge.empty()) + face.mNumIndices == 0 || face.mEdge.empty()) { continue; } @@ -3885,7 +3959,7 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, #if DEBUG_SILHOUETTE_EDGE_MAP //for each triangle - U32 count = face.mIndices.size(); + U32 count = face.mNumIndices; for (U32 j = 0; j < count/3; j++) { //get vertices S32 v1 = face.mIndices[j*3+0]; @@ -3938,7 +4012,7 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, #elif DEBUG_SILHOUETTE_NORMALS //for each vertex - for (U32 j = 0; j < face.mVertices.size(); j++) { + for (U32 j = 0; j < face.mNumVertices; j++) { vertices.push_back(face.mVertices[j].mPosition); vertices.push_back(face.mVertices[j].mPosition + face.mVertices[j].mNormal*0.1f); normals.push_back(LLVector3(0,0,1)); @@ -3964,26 +4038,36 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, //for each triangle std::vector fFacing; - vector_append(fFacing, face.mIndices.size()/3); - for (U32 j = 0; j < face.mIndices.size()/3; j++) + vector_append(fFacing, face.mNumIndices/3); + + LLVector4a* v = (LLVector4a*) face.mPositions; + LLVector4a* n = (LLVector4a*) face.mNormals; + + for (U32 j = 0; j < face.mNumIndices/3; j++) { //approximate normal S32 v1 = face.mIndices[j*3+0]; S32 v2 = face.mIndices[j*3+1]; S32 v3 = face.mIndices[j*3+2]; - LLVector3 norm = (face.mVertices[v1].mPosition - face.mVertices[v2].mPosition) % - (face.mVertices[v2].mPosition - face.mVertices[v3].mPosition); - - if (norm.magVecSquared() < 0.00000001f) + LLVector4a c1,c2; + c1.setSub(v[v1], v[v2]); + c2.setSub(v[v2], v[v3]); + + LLVector4a norm; + + norm.setCross3(c1, c2); + + if (norm.dot3(norm) < 0.00000001f) { fFacing[j] = AWAY | TOWARDS; } else { //get view vector - LLVector3 view = (obj_cam_vec-face.mVertices[v1].mPosition); - bool away = view * norm > 0.0f; + LLVector4a view; + view.setSub(obj_cam_vec, v[v1]); + bool away = view.dot3(norm) > 0.0f; if (away) { fFacing[j] = AWAY; @@ -3996,7 +4080,7 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, } //for each triangle - for (U32 j = 0; j < face.mIndices.size()/3; j++) + for (U32 j = 0; j < face.mNumIndices/3; j++) { if (fFacing[j] == (AWAY | TOWARDS)) { //this is a degenerate triangle @@ -4029,9 +4113,14 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, S32 v1 = face.mIndices[j*3+k]; S32 v2 = face.mIndices[j*3+((k+1)%3)]; - vertices.push_back(face.mVertices[v1].mPosition*mat); - LLVector3 norm1 = face.mVertices[v1].mNormal * norm_mat; - norm1.normVec(); + LLVector4a t; + mat.affineTransform(v[v1], t); + vertices.push_back(LLVector3(t[0], t[1], t[2])); + + norm_mat.rotate(n[v1], t); + + t.normalize3Fast(); + LLVector3 norm1 = LLVector3(t[0], t[1], t[2]); normals.push_back(norm1); vertices.push_back(face.mVertices[v2].mPosition*mat); @@ -4088,7 +4177,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, genBinormals(i); } - for (U32 tri = 0; tri < face.mIndices.size()/3; tri++) + for (U32 tri = 0; tri < face.mNumIndices/3; tri++) { S32 index1 = face.mIndices[tri*3+0]; S32 index2 = face.mIndices[tri*3+1]; @@ -4928,7 +5017,7 @@ void LLVolumeFace::optimize(F32 angle_cutoff) VertexMapData::PointMap point_map; //remove redundant vertices - for (U32 i = 0; i < mIndices.size(); ++i) + for (U32 i = 0; i < mNumIndices; ++i) { U16 index = mIndices[i]; @@ -4953,7 +5042,7 @@ void LLVolumeFace::optimize(F32 angle_cutoff) if (!found) { new_face.mVertices.push_back(cv); - U16 index = (U16) new_face.mVertices.size()-1; + U16 index = (U16) new_face.mNumVertices-1; new_face.mIndices.push_back(index); VertexMapData d; @@ -5053,7 +5142,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) mVertices.clear(); } - S32 vtop = mVertices.size(); + S32 vtop = mNumVertices; for(int gx = 0;gx 65536) + if (face.mNumVertices + mNumVertices > 65536) { llerrs << "Cannot append face -- 16-bit overflow will occur." << llendl; } - for (U32 i = 0; i < face.mVertices.size(); ++i) + for (U32 i = 0; i < face.mNumVertices; ++i) { VertexData v = face.mVertices[i]; v.mPosition = v.mPosition*mat; @@ -5676,7 +5796,7 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat, LLMatrix } - for (U32 i = 0; i < face.mIndices.size(); ++i) + for (U32 i = 0; i < face.mNumIndices; ++i) { mIndices.push_back(face.mIndices[i]+offset); } @@ -5823,7 +5943,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) mCenter.clearVec(); face_min = face_max = mVertices[0].mPosition; - for (U32 i = 1; i < mVertices.size(); ++i) + for (U32 i = 1; i < mNumVertices; ++i) { update_min_max(face_min, face_max, mVertices[i].mPosition); } @@ -5922,7 +6042,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) } //generate normals - for (U32 i = 0; i < mIndices.size()/3; i++) //for each triangle + for (U32 i = 0; i < mNumIndices/3; i++) //for each triangle { const U16* idx = &(mIndices[i*3]); diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index c6a156ae37..17be642d4a 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -794,20 +794,28 @@ public: LLVolumeFace() : mID(0), mTypeMask(0), - mHasBinormals(FALSE), mBeginS(0), mBeginT(0), mNumS(0), - mNumT(0) + mNumT(0), + mNumVertices(0), + mNumIndices(0), + mPositions(NULL), + mNormals(NULL), + mBinormals(NULL), + mTexCoords(NULL), + mIndices(NULL) { } BOOL create(LLVolume* volume, BOOL partial_build = FALSE); void createBinormals(); - void makeTriStrip(); void appendFace(const LLVolumeFace& face, LLMatrix4& transform, LLMatrix4& normal_tranform); + void resizeVertices(S32 num_verts); + void resizeIndices(S32 num_indices); + class VertexData { public: @@ -873,7 +881,6 @@ public: S32 mID; U32 mTypeMask; LLVector3 mCenter; - BOOL mHasBinormals; // Only used for INNER/OUTER faces S32 mBeginS; @@ -883,9 +890,15 @@ public: LLVector3 mExtents[2]; //minimum and maximum point of face - std::vector mVertices; - std::vector mIndices; - std::vector mTriStrip; + S32 mNumVertices; + S32 mNumIndices; + + F32* mPositions; + F32* mNormals; + F32* mBinormals; + F32* mTexCoords; + U16* mIndices; + std::vector mEdge; //list of skin weights for rigged volumes diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h index 76dd938887..0e7d72e958 100644 --- a/indra/llmath/v3math.h +++ b/indra/llmath/v3math.h @@ -532,6 +532,21 @@ inline void update_min_max(LLVector3& min, LLVector3& max, const LLVector3& pos) } } +inline void update_min_max(LLVector3& min, LLVector3& max, const F32* pos) +{ + for (U32 i = 0; i < 3; i++) + { + if (min.mV[i] > pos[i]) + { + min.mV[i] = pos[i]; + } + if (max.mV[i] < pos[i]) + { + max.mV[i] = pos[i]; + } + } +} + inline F32 angle_between(const LLVector3& a, const LLVector3& b) { LLVector3 an = a; -- cgit v1.3 From 4d57cb3c0975ff0bcea0d6fb3498f2d90962ff16 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 22 May 2010 04:35:02 -0500 Subject: Vectorize/memory align buffers in llvolumeface WIP --- indra/llmath/llvolume.cpp | 720 ++++++++++++++++---------------- indra/llmath/llvolume.h | 35 +- indra/newview/lldrawpoolavatar.cpp | 6 +- indra/newview/llface.cpp | 55 +-- indra/newview/llfloaterimagepreview.cpp | 6 +- indra/newview/llhudicon.cpp | 2 + indra/newview/llhudtext.cpp | 5 + indra/newview/llviewercamera.cpp | 5 +- indra/newview/llvograss.cpp | 2 + indra/newview/llvotextbubble.cpp | 33 +- indra/newview/llvovolume.cpp | 29 +- 11 files changed, 474 insertions(+), 424 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 4e342b0b48..01fe2be371 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1,4 +1,5 @@ /** + * @file llvolume.cpp * * $LicenseInfo:firstyear=2002&license=viewergpl$ @@ -89,8 +90,6 @@ const F32 SKEW_MAX = 0.95f; const F32 SCULPT_MIN_AREA = 0.002f; const S32 SCULPT_MIN_AREA_DETAIL = 1; -#define GEN_TRI_STRIP 0 - BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, const LLVector3& norm) { LLVector3 test = (pt2-pt1)%(pt3-pt2); @@ -134,21 +133,25 @@ BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, con // and returns the intersection point along dir in intersection_t. // Moller-Trumbore algorithm -BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir, +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, BOOL two_sided) { F32 u, v, t; /* find vectors for two edges sharing vert0 */ - LLVector3 edge1 = vert1 - vert0; + LLVector4a edge1; + edge1.setSub(vert1, vert0); - LLVector3 edge2 = vert2 - vert0;; + + LLVector4a edge2; + edge2.setSub(vert2, vert0); /* begin calculating determinant - also used to calculate U parameter */ - LLVector3 pvec = dir % edge2; - + LLVector4a pvec; + pvec.setCross3(dir, edge2); + /* if determinant is near zero, ray lies in plane of triangle */ - F32 det = edge1 * pvec; + F32 det = edge1.dot3(pvec); if (!two_sided) { @@ -158,10 +161,11 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons } /* calculate distance from vert0 to ray origin */ - LLVector3 tvec = orig - vert0; + LLVector4a tvec; + tvec.setSub(orig, vert0); /* calculate U parameter and test bounds */ - u = tvec * pvec; + u = tvec.dot3(pvec); if (u < 0.f || u > det) { @@ -169,17 +173,18 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons } /* prepare to test V parameter */ - LLVector3 qvec = tvec % edge1; + LLVector4a qvec; + qvec.setCross3(tvec, edge1); /* calculate V parameter and test bounds */ - v = dir * qvec; + v = dir.dot3(qvec); if (v < 0.f || u + v > det) { return FALSE; } /* calculate t, scale parameters, ray intersects triangle */ - t = edge2 * qvec; + t = edge2.dot3(qvec); F32 inv_det = 1.0 / det; t *= inv_det; u *= inv_det; @@ -195,20 +200,22 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons F32 inv_det = 1.0 / det; /* calculate distance from vert0 to ray origin */ - LLVector3 tvec = orig - vert0; + LLVector4a tvec; + tvec.setSub(orig, vert0); /* calculate U parameter and test bounds */ - u = (tvec * pvec) * inv_det; + u = (tvec.dot3(pvec)) * inv_det; if (u < 0.f || u > 1.f) { return FALSE; } /* prepare to test V parameter */ - LLVector3 qvec = tvec - edge1; + LLVector4a qvec; + qvec.setSub(tvec, edge1); /* calculate V parameter and test bounds */ - v = (dir * qvec) * inv_det; + v = (dir.dot3(qvec)) * inv_det; if (v < 0.f || u + v > 1.f) { @@ -216,7 +223,7 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons } /* calculate t, ray intersects triangle */ - t = (edge2 * qvec) * inv_det; + t = (edge2.dot3(qvec)) * inv_det; } if (intersection_a != NULL) @@ -4120,13 +4127,14 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, norm_mat.rotate(n[v1], t); t.normalize3Fast(); - LLVector3 norm1 = LLVector3(t[0], t[1], t[2]); - normals.push_back(norm1); + normals.push_back(LLVector3(t[0], t[1], t[2])); - vertices.push_back(face.mVertices[v2].mPosition*mat); - LLVector3 norm2 = face.mVertices[v2].mNormal * norm_mat; - norm2.normVec(); - normals.push_back(norm2); + mat.affineTransform(v[v2], t); + vertices.push_back(LLVector3(t[0], t[1], t[2])); + + norm_mat.rotate(n[v2], t); + t.normalize3Fast(); + normals.push_back(LLVector3(t[0], t[1], t[2])); segments.push_back(vertices.size()); } @@ -4177,6 +4185,10 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, genBinormals(i); } + LLVector4a starta, dira; + + LLVector4a* p = (LLVector4a*) face.mPositions; + for (U32 tri = 0; tri < face.mNumIndices/3; tri++) { S32 index1 = face.mIndices[tri*3+0]; @@ -4185,15 +4197,15 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, F32 a, b, t; - if (LLTriangleRayIntersect(face.mVertices[index1].mPosition, - face.mVertices[index2].mPosition, - face.mVertices[index3].mPosition, - start, dir, &a, &b, &t, FALSE)) + if (LLTriangleRayIntersect(p[index1], + p[index2], + p[index3], + starta, dira, &a, &b, &t, FALSE)) { if ((t >= 0.f) && // if hit is after start (t <= 1.f) && // and before end (t < closest_t)) // and this hit is closer - { + { closest_t = t; hit_face = i; @@ -4201,27 +4213,35 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, { *intersection = start + dir * closest_t; } - + + if (tex_coord != NULL) - { - *tex_coord = ((1.f - a - b) * face.mVertices[index1].mTexCoord + - a * face.mVertices[index2].mTexCoord + - b * face.mVertices[index3].mTexCoord); + { + LLVector2* tc = (LLVector2*) face.mTexCoords; + *tex_coord = ((1.f - a - b) * tc[index1] + + a * tc[index2] + + b * tc[index3]); } if (normal != NULL) - { - *normal = ((1.f - a - b) * face.mVertices[index1].mNormal + - a * face.mVertices[index2].mNormal + - b * face.mVertices[index3].mNormal); + { + LLVector4* norm = (LLVector4*) face.mNormals; + + *normal = ((1.f - a - b) * LLVector3(norm[index1]) + + a * LLVector3(norm[index2]) + + b * LLVector3(norm[index3])); } if (bi_normal != NULL) - { - *bi_normal = ((1.f - a - b) * face.mVertices[index1].mBinormal + - a * face.mVertices[index2].mBinormal + - b * face.mVertices[index3].mBinormal); + { + LLVector4* binormal = (LLVector4*) face.mBinormals; + if (binormal) + { + *bi_normal = ((1.f - a - b) * LLVector3(binormal[index1]) + + a * LLVector3(binormal[index2]) + + b * LLVector3(binormal[index3])); + } } } @@ -4992,6 +5012,14 @@ std::ostream& operator<<(std::ostream &s, const LLVolume *volumep) return s; } +LLVolumeFace::~LLVolumeFace() +{ + _mm_free(mPositions); + _mm_free(mNormals); + _mm_free(mTexCoords); + _mm_free(mIndices); + _mm_free(mBinormals); +} BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) { @@ -5012,6 +5040,7 @@ BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) void LLVolumeFace::optimize(F32 angle_cutoff) { +#if 0 //disabling until a vectorized version is available LLVolumeFace new_face; VertexMapData::PointMap point_map; @@ -5063,6 +5092,7 @@ void LLVolumeFace::optimize(F32 angle_cutoff) mVertices = new_face.mVertices; mIndices = new_face.mIndices; +#endif } void LerpPlanarVertex(LLVolumeFace::VertexData& v0, @@ -5127,20 +5157,22 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) corners[1].mTexCoord=corners[2].mTexCoord; corners[2].mTexCoord=swap; } - baseVert.mBinormal = calc_binormal_from_triangle( + + LLVector4a binormal; + + calc_binormal_from_triangle( binormal, corners[0].mPosition, corners[0].mTexCoord, corners[1].mPosition, corners[1].mTexCoord, corners[2].mPosition, corners[2].mTexCoord); - for(int t = 0; t < 4; t++){ - corners[t].mBinormal = baseVert.mBinormal; - corners[t].mNormal = baseVert.mNormal; - } - mHasBinormals = TRUE; - if (partial_build) - { - mVertices.clear(); - } + 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; S32 vtop = mNumVertices; for(int gx = 0;gx=0;i--) { - mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]); - } - -#if GEN_TRI_STRIP - if (gy == 0) - { - mTriStrip.push_back((gx+1)*(grid_size+1)); - mTriStrip.push_back((gx+1)*(grid_size+1)); - mTriStrip.push_back(gx*(grid_size+1)); - } - - mTriStrip.push_back(gy+1+(gx+1)*(grid_size+1)); - mTriStrip.push_back(gy+1+gx*(grid_size+1)); - - - if (gy == grid_size-1) - { - mTriStrip.push_back(gy+1+gx*(grid_size+1)); - } -#endif + *out++ = (vtop+(gy*(grid_size+1))+gx+idxs[i]); + } } else { for(S32 i=0;i<6;i++) { - mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]); - } - -#if GEN_TRI_STRIP - if (gy == 0) - { - mTriStrip.push_back(gx*(grid_size+1)); - mTriStrip.push_back(gx*(grid_size+1)); - mTriStrip.push_back((gx+1)*(grid_size+1)); + *out++ = (vtop+(gy*(grid_size+1))+gx+idxs[i]); } - - mTriStrip.push_back(gy+1+gx*(grid_size+1)); - mTriStrip.push_back(gy+1+(gx+1)*(grid_size+1)); - - if (gy == grid_size-1) - { - mTriStrip.push_back(gy+1+(gx+1)*(grid_size+1)); - } -#endif } } } - -#if GEN_TRI_STRIP - if (mTriStrip.size()%2 == 1) - { - mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]); - } -#endif } return TRUE; @@ -5267,11 +5262,25 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) num_vertices = profile.size(); num_indices = (profile.size() - 2)*3; - mVertices.resize(num_vertices); + if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK)) + { + resizeVertices(num_vertices+1); + allocateBinormals(num_vertices+1); - if (!partial_build) + if (!partial_build) + { + resizeIndices(num_indices+3); + } + } + else { - mIndices.resize(num_indices); + resizeVertices(num_vertices); + allocateBinormals(num_vertices); + + if (!partial_build) + { + resizeIndices(num_indices); + } } S32 max_s = volume->getProfile().getTotal(); @@ -5298,79 +5307,87 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) LLVector3& min = mExtents[0]; LLVector3& max = mExtents[1]; + 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++) { if (mTypeMask & TOP_MASK) { - mVertices[i].mTexCoord.mV[0] = profile[i].mV[0]+0.5f; - mVertices[i].mTexCoord.mV[1] = profile[i].mV[1]+0.5f; + tc[i].mV[0] = profile[i].mV[0]+0.5f; + tc[i].mV[1] = profile[i].mV[1]+0.5f; } else { // Mirror for underside. - mVertices[i].mTexCoord.mV[0] = profile[i].mV[0]+0.5f; - mVertices[i].mTexCoord.mV[1] = 0.5f - profile[i].mV[1]; + tc[i].mV[0] = profile[i].mV[0]+0.5f; + tc[i].mV[1] = 0.5f - profile[i].mV[1]; } - mVertices[i].mPosition = mesh[i + offset].mPos; + pos[i].load3(mesh[i + offset].mPos.mV); if (i == 0) { - min = max = mVertices[i].mPosition; - min_uv = max_uv = mVertices[i].mTexCoord; + min = max = mesh[i+offset].mPos; + min_uv = max_uv = tc[i]; } else { - update_min_max(min,max, mVertices[i].mPosition); - update_min_max(min_uv, max_uv, mVertices[i].mTexCoord); + update_min_max(min,max, mesh[i+offset].mPos); + update_min_max(min_uv, max_uv, tc[i]); } } mCenter = (min+max)*0.5f; cuv = (min_uv + max_uv)*0.5f; - LLVector3 binormal = calc_binormal_from_triangle( + LLVector4a binormal; + calc_binormal_from_triangle(binormal, mCenter, cuv, - mVertices[0].mPosition, mVertices[0].mTexCoord, - mVertices[1].mPosition, mVertices[1].mTexCoord); - binormal.normVec(); + mesh[0+offset].mPos, tc[0], + mesh[1+offset].mPos, tc[1]); + binormal.normalize3Fast(); + + LLVector4a normal; + LLVector4a d0, d1; + LLVector4a center; + + center.load3(mCenter.mV); - LLVector3 d0; - LLVector3 d1; - LLVector3 normal; + d0.setSub(center, pos[0]); + d1.setSub(center, pos[1]); - d0 = mCenter-mVertices[0].mPosition; - d1 = mCenter-mVertices[1].mPosition; + if (mTypeMask & TOP_MASK) + { + normal.setCross3(d0, d1); + } + else + { + normal.setCross3(d1, d0); + } - normal = (mTypeMask & TOP_MASK) ? (d0%d1) : (d1%d0); - normal.normVec(); + normal.normalize3Fast(); VertexData vd; vd.mPosition = mCenter; - vd.mNormal = normal; - vd.mBinormal = binormal; vd.mTexCoord = cuv; if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK)) { - mVertices.push_back(vd); + pos[num_vertices].load4a((F32*) ¢er.mQ); + tc[num_vertices] = cuv; num_vertices++; - if (!partial_build) - { - vector_append(mIndices, 3); - } } - for (S32 i = 0; i < num_vertices; i++) { - mVertices[i].mBinormal = binormal; - mVertices[i].mNormal = normal; + binorm[i].load4a((F32*) &binormal.mQ); + norm[i].load4a((F32*) &normal.mQ); } - mHasBinormals = TRUE; - if (partial_build) { return TRUE; @@ -5478,8 +5495,6 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) pt2--; } } - - makeTriStrip(); } else { @@ -5584,8 +5599,6 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) pt2--; } } - - makeTriStrip(); } } else @@ -5607,131 +5620,63 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) mIndices[3*i+v2] = i + 1; } -#if GEN_TRI_STRIP - //make tri strip - if (mTypeMask & OPEN_MASK) - { - makeTriStrip(); - } - else - { - S32 j = num_vertices-2; - if (mTypeMask & TOP_MASK) - { - mTriStrip.push_back(0); - for (S32 i = 0; i <= j; ++i) - { - mTriStrip.push_back(i); - if (i != j) - { - mTriStrip.push_back(j); - } - --j; - } - } - else - { - mTriStrip.push_back(j); - for (S32 i = 0; i <= j; ++i) - { - if (i != j) - { - mTriStrip.push_back(j); - } - mTriStrip.push_back(i); - --j; - } - } - - mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]); - if (mTriStrip.size()%2 == 1) - { - mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]); - } - } -#endif } return TRUE; } -void LLVolumeFace::makeTriStrip() -{ -#if GEN_TRI_STRIP - for (U32 i = 0; i < mNumIndices; i+=3) - { - U16 i0 = mIndices[i]; - U16 i1 = mIndices[i+1]; - U16 i2 = mIndices[i+2]; - - if ((i/3)%2 == 1) - { - mTriStrip.push_back(i0); - mTriStrip.push_back(i0); - mTriStrip.push_back(i1); - mTriStrip.push_back(i2); - mTriStrip.push_back(i2); - } - else - { - mTriStrip.push_back(i2); - mTriStrip.push_back(i2); - mTriStrip.push_back(i1); - mTriStrip.push_back(i0); - mTriStrip.push_back(i0); - } - } - - if (mTriStrip.size()%2 == 1) - { - mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]); - } -#endif -} - void LLVolumeFace::createBinormals() { LLMemType m1(LLMemType::MTYPE_VOLUME); - if (!mHasBinormals) + if (!mBinormals) { + allocateBinormals(mNumVertices); + //generate binormals + LLStrider pos; + pos = (LLVector3*) mPositions; + pos.setStride(16); + + LLVector2* tc = (LLVector2*) mTexCoords; + LLVector4a* binorm = (LLVector4a*) mBinormals; + for (U32 i = 0; i < mNumIndices/3; i++) { //for each triangle - const VertexData& v0 = mVertices[mIndices[i*3+0]]; - const VertexData& v1 = mVertices[mIndices[i*3+1]]; - const VertexData& v2 = mVertices[mIndices[i*3+2]]; + const U16& i0 = mIndices[i*3+0]; + const U16& i1 = mIndices[i*3+1]; + const U16& i2 = mIndices[i*3+2]; //calculate binormal - LLVector3 binorm = calc_binormal_from_triangle(v0.mPosition, v0.mTexCoord, - v1.mPosition, v1.mTexCoord, - v2.mPosition, v2.mTexCoord); + LLVector4a binormal; + calc_binormal_from_triangle(binormal, + pos[i0], tc[i0], + pos[i1], tc[i1], + pos[i2], tc[i2]); - for (U32 j = 0; j < 3; j++) - { //add triangle normal to vertices - mVertices[mIndices[i*3+j]].mBinormal += binorm; // * (weight_sum - d[j])/weight_sum; - } + + //add triangle normal to vertices + binorm[i0].add(binormal); + binorm[i1].add(binormal); + binorm[i2].add(binormal); //even out quad contributions if (i % 2 == 0) { - mVertices[mIndices[i*3+2]].mBinormal += binorm; + binorm[i2].add(binormal); } else { - mVertices[mIndices[i*3+1]].mBinormal += binorm; + binorm[i1].add(binormal); } } //normalize binormals for (U32 i = 0; i < mNumVertices; i++) { - mVertices[i].mBinormal.normVec(); - mVertices[i].mNormal.normVec(); + binorm[i].normalize3Fast(); } - - mHasBinormals = TRUE; } } @@ -5754,6 +5699,13 @@ void LLVolumeFace::resizeVertices(S32 num_verts) mNumVertices = num_verts; } +void LLVolumeFace::allocateBinormals(S32 num_verts) +{ + _mm_free(mBinormals); + mBinormals = (F32*) _mm_malloc(num_verts*16, 16); +} + + void LLVolumeFace::resizeIndices(S32 num_indices) { _mm_free(mIndices); @@ -5761,44 +5713,107 @@ void LLVolumeFace::resizeIndices(S32 num_indices) //pad index block end to allow for QWORD reads S32 size = ((num_indices*2) + 0xF) & ~0xF; - mIndices = (U16*) _mm_malloc(size); + mIndices = (U16*) _mm_malloc(size,16); mNumIndices = num_indices; } -void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat, LLMatrix4& norm_mat) +void LLVolumeFace::fillFromLegacyData(std::vector& v, std::vector& idx) +{ + resizeVertices(v.size()); + resizeIndices(idx.size()); + + for (U32 i = 0; i < v.size(); ++i) + { + for (U32 j = 0; j < 3; ++j) + { + mPositions[i*4+j] = v[i].mPosition[j]; + mNormals[i*4+j] = v[i].mNormal[j]; + } + + mTexCoords[i*2+0] = v[i].mTexCoord.mV[0]; + mTexCoords[i*2+1] = v[i].mTexCoord.mV[1]; + } + + for (U32 i = 0; i < idx.size(); ++i) + { + mIndices[i] = idx[i]; + } +} + +void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMatrix4& norm_mat_in) { U16 offset = mNumVertices; - if (face.mNumVertices + mNumVertices > 65536) + S32 new_count = face.mNumVertices + mNumVertices; + + if (new_count > 65536) { llerrs << "Cannot append face -- 16-bit overflow will occur." << llendl; } + + F32* new_pos = (F32*) _mm_malloc(new_count*16, 16); + F32* new_norm = (F32*) _mm_malloc(new_count*16, 16); + F32* new_tc = (F32*) _mm_malloc((new_count*8+0xF) & ~0xF, 16); + + LLVector4a::memcpyNonAliased16(new_pos, mPositions, new_count*4); + LLVector4a::memcpyNonAliased16(new_norm, mNormals, new_count*4); + LLVector4a::memcpyNonAliased16(new_tc, mTexCoords, new_count*2); + + _mm_free(mPositions); + _mm_free(mNormals); + _mm_free(mTexCoords); + + mPositions = new_pos; + mNormals = new_norm; + mTexCoords = new_tc; + + mNumVertices = new_count; + + LLVector4a* dst_pos = (LLVector4a*) mPositions+offset; + LLVector2* dst_tc = (LLVector2*) mTexCoords+offset; + LLVector4a* dst_norm = (LLVector4a*) mNormals+offset; + + LLVector4a* src_pos = (LLVector4a*) face.mPositions; + LLVector2* src_tc = (LLVector2*) face.mTexCoords; + LLVector4a* src_norm = (LLVector4a*) face.mNormals; + + LLMatrix4a mat, norm_mat; + mat.loadu(mat_in); + norm_mat.loadu(norm_mat_in); + for (U32 i = 0; i < face.mNumVertices; ++i) { - VertexData v = face.mVertices[i]; - v.mPosition = v.mPosition*mat; - v.mNormal = v.mNormal * norm_mat; + mat.affineTransform(src_pos[i], dst_pos[i]); + norm_mat.rotate(src_norm[i], dst_norm[i]); + dst_norm[i].normalize3Fast(); - v.mNormal.normalize(); - - mVertices.push_back(v); + dst_tc[i] = src_tc[i]; if (offset == 0 && i == 0) { - mExtents[0] = mExtents[1] = v.mPosition; + mExtents[0] = mExtents[1] = LLVector3((F32*) &(dst_pos[i].mQ)); } else { - update_min_max(mExtents[0], mExtents[1], v.mPosition); + update_min_max(mExtents[0], mExtents[1], (F32*) &(dst_pos[i].mQ)); } } - + + new_count = mNumIndices + face.mNumIndices; + U16* new_indices = (U16*) _mm_malloc((new_count*2+0xF) & ~0xF, 16); + LLVector4a::memcpyNonAliased16((F32*) new_indices, (F32*) mIndices, new_count/2); + _mm_free(mIndices); + mIndices = new_indices; + mNumIndices = new_count; + + U16* dst_idx = mIndices+offset; + for (U32 i = 0; i < face.mNumIndices; ++i) { - mIndices.push_back(face.mIndices[i]+offset); + dst_idx[i] = face.mIndices[i]+offset; } } @@ -5828,21 +5843,20 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) num_vertices = mNumS*mNumT; num_indices = (mNumS-1)*(mNumT-1)*6; - mVertices.resize(num_vertices); - if (!partial_build) { - mIndices.resize(num_indices); + resizeVertices(num_vertices); + resizeIndices(num_indices); if ((volume->getParams().getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH) { mEdge.resize(num_indices); } } - else - { - mHasBinormals = FALSE; - } + + LLVector4a* pos = (LLVector4a*) mPositions; + LLVector4a* norm = (LLVector4a*) mNormals; + LLVector2* tc = (LLVector2*) mTexCoords; S32 begin_stex = llfloor( profile[mBeginS].mV[2] ); S32 num_s = ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2) ? mNumS/2 : mNumS; @@ -5894,21 +5908,21 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) i = mBeginS + s + max_s*t; } - mVertices[cur_vertex].mPosition = mesh[i].mPos; - mVertices[cur_vertex].mTexCoord = LLVector2(ss,tt); + pos[cur_vertex].load3(mesh[i].mPos.mV); + tc[cur_vertex] = LLVector2(ss,tt); - mVertices[cur_vertex].mNormal = LLVector3(0,0,0); - mVertices[cur_vertex].mBinormal = LLVector3(0,0,0); + norm[cur_vertex].clear(); cur_vertex++; if ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2 && s > 0) { - mVertices[cur_vertex].mPosition = mesh[i].mPos; - mVertices[cur_vertex].mTexCoord = LLVector2(ss,tt); + + pos[cur_vertex].load3(mesh[i].mPos.mV); + tc[cur_vertex] = LLVector2(ss,tt); - mVertices[cur_vertex].mNormal = LLVector3(0,0,0); - mVertices[cur_vertex].mBinormal = LLVector3(0,0,0); + norm[cur_vertex].clear(); + cur_vertex++; } } @@ -5926,12 +5940,10 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) i = mBeginS + s + max_s*t; ss = profile[mBeginS + s].mV[2] - begin_stex; - mVertices[cur_vertex].mPosition = mesh[i].mPos; - mVertices[cur_vertex].mTexCoord = LLVector2(ss,tt); - - mVertices[cur_vertex].mNormal = LLVector3(0,0,0); - mVertices[cur_vertex].mBinormal = LLVector3(0,0,0); - + pos[cur_vertex].load3(mesh[i].mPos.mV); + tc[cur_vertex] = LLVector2(ss,tt); + norm[cur_vertex].clear(); + cur_vertex++; } } @@ -5942,10 +5954,11 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) LLVector3& face_max = mExtents[1]; mCenter.clearVec(); - face_min = face_max = mVertices[0].mPosition; + face_min = face_max = LLVector3((F32*) &(pos[i].mQ)); + for (U32 i = 1; i < mNumVertices; ++i) { - update_min_max(face_min, face_max, mVertices[i].mPosition); + update_min_max(face_min, face_max, (F32*) &(pos[i].mQ)); } mCenter = (face_min + face_max) * 0.5f; @@ -5956,18 +5969,9 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) if (!partial_build) { -#if GEN_TRI_STRIP - mTriStrip.clear(); -#endif - // Now we generate the indices. for (t = 0; t < (mNumT-1); t++) { -#if GEN_TRI_STRIP - //prepend terminating index to strip - mTriStrip.push_back(mNumS*t); -#endif - for (s = 0; s < (mNumS-1); s++) { mIndices[cur_index++] = s + mNumS*t; //bottom left @@ -5977,16 +5981,6 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) mIndices[cur_index++] = s+1 + mNumS*t; //bottom right mIndices[cur_index++] = s+1 + mNumS*(t+1); //top right -#if GEN_TRI_STRIP - if (s == 0) - { - mTriStrip.push_back(s+mNumS*t); - mTriStrip.push_back(s+mNumS*(t+1)); - } - mTriStrip.push_back(s+1+mNumS*t); - mTriStrip.push_back(s+1+mNumS*(t+1)); -#endif - mEdge[cur_edge++] = (mNumS-1)*2*t+s*2+1; //bottom left/top right neighbor face if (t < mNumT-2) { //top right/top left neighbor face mEdge[cur_edge++] = (mNumS-1)*2*(t+1)+s*2+1; @@ -6027,52 +6021,55 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) } mEdge[cur_edge++] = (mNumS-1)*2*t+s*2; //top right/bottom left neighbor face } -#if GEN_TRI_STRIP - //append terminating vertex to strip - mTriStrip.push_back(mNumS-1+mNumS*(t+1)); -#endif } - -#if GEN_TRI_STRIP - if (mTriStrip.size()%2 == 1) - { - mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]); - } -#endif } //generate normals for (U32 i = 0; i < mNumIndices/3; i++) //for each triangle { const U16* idx = &(mIndices[i*3]); - - VertexData* v[] = - { &mVertices[idx[0]], &mVertices[idx[1]], &mVertices[idx[2]] }; - - //calculate triangle normal - LLVector3 norm = (v[0]->mPosition-v[1]->mPosition) % (v[0]->mPosition-v[2]->mPosition); + - v[0]->mNormal += norm; - v[1]->mNormal += norm; - v[2]->mNormal += norm; + LLVector4a* v[] = + { pos+idx[0], pos+idx[1], pos+idx[2] }; + + LLVector4a* n[] = + { norm+idx[0], norm+idx[1], norm+idx[2] }; + + //calculate triangle normal + LLVector4a a, b, c; + + a.setSub(*v[0], *v[1]); + b.setSub(*v[0], *v[2]); + c.setCross3(a,b); + n[0]->add(c); + n[1]->add(c); + n[2]->add(c); + //even out quad contributions - v[i%2+1]->mNormal += norm; + n[i%2+1]->add(c); } // adjust normals based on wrapping and stitching - BOOL s_bottom_converges = ((mVertices[0].mPosition - mVertices[mNumS*(mNumT-2)].mPosition).magVecSquared() < 0.000001f); - BOOL s_top_converges = ((mVertices[mNumS-1].mPosition - mVertices[mNumS*(mNumT-2)+mNumS-1].mPosition).magVecSquared() < 0.000001f); + LLVector4a top; + top.setSub(pos[0], pos[mNumS*(mNumT-2)]); + BOOL s_bottom_converges = (top.dot3(top) < 0.000001f); + + top.setSub(pos[mNumS-1], pos[mNumS*(mNumT-2)+mNumS-1]); + BOOL s_top_converges = (top.dot3(top) < 0.000001f); + if (sculpt_stitching == LL_SCULPT_TYPE_NONE) // logic for non-sculpt volumes { if (volume->getPath().isOpen() == FALSE) { //wrap normals on T for (S32 i = 0; i < mNumS; i++) { - LLVector3 norm = mVertices[i].mNormal + mVertices[mNumS*(mNumT-1)+i].mNormal; - mVertices[i].mNormal = norm; - mVertices[mNumS*(mNumT-1)+i].mNormal = norm; + LLVector4a n; + n.setAdd(norm[i], norm[mNumS*(mNumT-1)+i]); + norm[i] = n; + norm[mNumS*(mNumT-1)+i] = n; } } @@ -6080,9 +6077,10 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) { //wrap normals on S for (S32 i = 0; i < mNumT; i++) { - LLVector3 norm = mVertices[mNumS*i].mNormal + mVertices[mNumS*i+mNumS-1].mNormal; - mVertices[mNumS * i].mNormal = norm; - mVertices[mNumS * i+mNumS-1].mNormal = norm; + LLVector4a n; + n.setAdd(norm[mNumS*i], norm[mNumS*i+mNumS-1]); + norm[mNumS * i] = n; + norm[mNumS * i+mNumS-1] = n; } } @@ -6093,7 +6091,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) { //all lower S have same normal for (S32 i = 0; i < mNumT; i++) { - mVertices[mNumS*i].mNormal = LLVector3(1,0,0); + norm[mNumS*i].set(1,0,0); } } @@ -6101,7 +6099,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) { //all upper S have same normal for (S32 i = 0; i < mNumT; i++) { - mVertices[mNumS*i+mNumS-1].mNormal = LLVector3(-1,0,0); + norm[mNumS*i+mNumS-1].set(-1,0,0); } } } @@ -6129,30 +6127,33 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) { // average normals for north pole - LLVector3 average(0.0, 0.0, 0.0); + LLVector4a average; + average.clear(); + for (S32 i = 0; i < mNumS; i++) { - average += mVertices[i].mNormal; + average.add(norm[i]); } // set average for (S32 i = 0; i < mNumS; i++) { - mVertices[i].mNormal = average; + norm[i] = average; } // average normals for south pole - average = LLVector3(0.0, 0.0, 0.0); + average.clear(); + for (S32 i = 0; i < mNumS; i++) { - average += mVertices[i + mNumS * (mNumT - 1)].mNormal; + average.add(norm[i + mNumS * (mNumT - 1)]); } // set average for (S32 i = 0; i < mNumS; i++) { - mVertices[i + mNumS * (mNumT - 1)].mNormal = average; + norm[i + mNumS * (mNumT - 1)] = average; } } @@ -6162,23 +6163,22 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) { for (S32 i = 0; i < mNumT; i++) { - LLVector3 norm = mVertices[mNumS*i].mNormal + mVertices[mNumS*i+mNumS-1].mNormal; - mVertices[mNumS * i].mNormal = norm; - mVertices[mNumS * i+mNumS-1].mNormal = norm; + LLVector4a n; + n.setAdd(norm[mNumS*i], norm[mNumS*i+mNumS-1]); + norm[mNumS * i] = n; + norm[mNumS * i+mNumS-1] = n; } } - - if (wrap_t) { for (S32 i = 0; i < mNumS; i++) { - LLVector3 norm = mVertices[i].mNormal + mVertices[mNumS*(mNumT-1)+i].mNormal; - mVertices[i].mNormal = norm; - mVertices[mNumS*(mNumT-1)+i].mNormal = norm; + LLVector4a n; + n.setAdd(norm[i], norm[mNumS*(mNumT-1)+i]); + norm[i] = n; + norm[mNumS*(mNumT-1)+i] = n; } - } } @@ -6188,7 +6188,8 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) // Finds binormal based on three vertices with texture coordinates. // Fills in dummy values if the triangle has degenerate texture coordinates. -LLVector3 calc_binormal_from_triangle( +void calc_binormal_from_triangle(LLVector4a& binormal, + const LLVector3& pos0, const LLVector2& tex0, const LLVector3& pos1, @@ -6196,33 +6197,42 @@ LLVector3 calc_binormal_from_triangle( const LLVector3& pos2, const LLVector2& tex2) { - LLVector3 rx0( pos0.mV[VX], tex0.mV[VX], tex0.mV[VY] ); - LLVector3 rx1( pos1.mV[VX], tex1.mV[VX], tex1.mV[VY] ); - LLVector3 rx2( pos2.mV[VX], tex2.mV[VX], tex2.mV[VY] ); + LLVector4a rx0; rx0.set( pos0.mV[VX], tex0.mV[VX], tex0.mV[VY] ); + LLVector4a rx1; rx1.set( pos1.mV[VX], tex1.mV[VX], tex1.mV[VY] ); + LLVector4a rx2; rx2.set( pos2.mV[VX], tex2.mV[VX], tex2.mV[VY] ); - LLVector3 ry0( pos0.mV[VY], tex0.mV[VX], tex0.mV[VY] ); - LLVector3 ry1( pos1.mV[VY], tex1.mV[VX], tex1.mV[VY] ); - LLVector3 ry2( pos2.mV[VY], tex2.mV[VX], tex2.mV[VY] ); + LLVector4a ry0; ry0.set( pos0.mV[VY], tex0.mV[VX], tex0.mV[VY] ); + LLVector4a ry1; ry1.set( pos1.mV[VY], tex1.mV[VX], tex1.mV[VY] ); + LLVector4a ry2; ry2.set( pos2.mV[VY], tex2.mV[VX], tex2.mV[VY] ); - LLVector3 rz0( pos0.mV[VZ], tex0.mV[VX], tex0.mV[VY] ); - LLVector3 rz1( pos1.mV[VZ], tex1.mV[VX], tex1.mV[VY] ); - LLVector3 rz2( pos2.mV[VZ], tex2.mV[VX], tex2.mV[VY] ); + LLVector4a rz0; rz0.set( pos0.mV[VZ], tex0.mV[VX], tex0.mV[VY] ); + LLVector4a rz1; rz1.set( pos1.mV[VZ], tex1.mV[VX], tex1.mV[VY] ); + LLVector4a rz2; rz2.set( pos2.mV[VZ], tex2.mV[VX], tex2.mV[VY] ); - LLVector3 r0 = (rx0 - rx1) % (rx0 - rx2); - LLVector3 r1 = (ry0 - ry1) % (ry0 - ry2); - LLVector3 r2 = (rz0 - rz1) % (rz0 - rz2); + LLVector4a lhs, rhs; + + LLVector4a r0; + lhs.setSub(rx0, rx1); rhs.setSub(rx0, rx2); + r0.setCross3(lhs, rhs); + + LLVector4a r1; + lhs.setSub(ry0, ry1); rhs.setSub(ry0, ry2); + r1.setCross3(lhs, rhs); + + LLVector4a r2; + lhs.setSub(rz0, rz1); rhs.setSub(rz0, rz2); + r2.setCross3(lhs, rhs); - if( r0.mV[VX] && r1.mV[VX] && r2.mV[VX] ) + if( r0[VX] && r1[VX] && r2[VX] ) { - LLVector3 binormal( - -r0.mV[VZ] / r0.mV[VX], - -r1.mV[VZ] / r1.mV[VX], - -r2.mV[VZ] / r2.mV[VX]); + binormal.set( + -r0[VZ] / r0[VX], + -r1[VZ] / r1[VX], + -r2[VZ] / r2[VX]); // binormal.normVec(); - return binormal; } else { - return LLVector3( 0, 1 , 0 ); + binormal.set( 0, 1 , 0 ); } } diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 17be642d4a..911db6f94b 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -40,6 +40,7 @@ class LLPathParams; class LLVolumeParams; class LLProfile; class LLPath; +class LLVector4a; class LLVolumeFace; class LLVolume; @@ -791,6 +792,19 @@ public: class LLVolumeFace { public: + class VertexData + { + public: + LLVector3 mPosition; + LLVector3 mNormal; + LLVector3 mBinormal; + LLVector2 mTexCoord; + + bool operator<(const VertexData& rhs) const; + bool operator==(const VertexData& rhs) const; + bool compareNormal(const VertexData& rhs, F32 angle_cutoff) const; + }; + LLVolumeFace() : mID(0), mTypeMask(0), @@ -808,26 +822,18 @@ public: { } + ~LLVolumeFace(); + BOOL create(LLVolume* volume, BOOL partial_build = FALSE); void createBinormals(); void appendFace(const LLVolumeFace& face, LLMatrix4& transform, LLMatrix4& normal_tranform); void resizeVertices(S32 num_verts); + void allocateBinormals(S32 num_verts); void resizeIndices(S32 num_indices); + void fillFromLegacyData(std::vector& v, std::vector& idx); - class VertexData - { - public: - LLVector3 mPosition; - LLVector3 mNormal; - LLVector3 mBinormal; - LLVector2 mTexCoord; - - bool operator<(const VertexData& rhs) const; - bool operator==(const VertexData& rhs) const; - bool compareNormal(const VertexData& rhs, F32 angle_cutoff) const; - }; class VertexMapData : public LLVolumeFace::VertexData { @@ -1051,7 +1057,8 @@ public: std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params); -LLVector3 calc_binormal_from_triangle( +void calc_binormal_from_triangle( + LLVector4a& binormal, const LLVector3& pos0, const LLVector2& tex0, const LLVector3& pos1, @@ -1060,7 +1067,7 @@ LLVector3 calc_binormal_from_triangle( const LLVector2& tex2); BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size); -BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir, +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, BOOL two_sided); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 4fb8f5266e..0fa0e80cb7 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1201,14 +1201,14 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLFace* face, const LLMeshSk if (!buff || buff->getTypeMask() != data_mask || - buff->getRequestedVerts() != vol_face.mVertices.size()) + buff->getRequestedVerts() != vol_face.mNumVertices) { face->setGeomIndex(0); face->setIndicesIndex(0); - face->setSize(vol_face.mVertices.size(), vol_face.mIndices.size()); + face->setSize(vol_face.mNumVertices, vol_face.mNumIndices); face->mVertexBuffer = new LLVertexBuffer(data_mask, 0); - face->mVertexBuffer->allocateBuffer(vol_face.mVertices.size(), vol_face.mIndices.size(), true); + face->mVertexBuffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true); U16 offset = 0; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 53dc335c16..77e8a6fdf9 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -928,8 +928,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, { LLFastTimer t(FTM_FACE_GET_GEOM); const LLVolumeFace &vf = volume.getVolumeFace(f); - S32 num_vertices = (S32)vf.mVertices.size(); - S32 num_indices = LLPipeline::sUseTriStrips ? (S32)vf.mTriStrip.size() : (S32) vf.mIndices.size(); + S32 num_vertices = (S32)vf.mNumVertices; + S32 num_indices = (S32) vf.mNumIndices; if (mVertexBuffer.notNull()) { @@ -1128,19 +1128,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (full_rebuild) { mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex); - if (LLPipeline::sUseTriStrips) + for (U32 i = 0; i < (U32) num_indices; i++) { - for (U32 i = 0; i < (U32) num_indices; i++) - { - *indicesp++ = vf.mTriStrip[i] + index_offset; - } - } - else - { - for (U32 i = 0; i < (U32) num_indices; i++) - { - *indicesp++ = vf.mIndices[i] + index_offset; - } + *indicesp++ = vf.mIndices[i] + index_offset; } } @@ -1214,28 +1204,41 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, bool bake_sunlight = !getTextureEntry()->getFullbright() && !mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL); + //VECTORIZE THIS for (S32 i = 0; i < num_vertices; i++) { + LLVector3 vf_binormal; + if (vf.mBinormals) + { + vf_binormal.set(vf.mBinormals+i*4); + } + + LLVector3 vf_normal; + vf_normal.set(vf.mNormals+i*4); + + LLVector3 vf_position; + vf_position.set(vf.mPositions+i*4); + if (rebuild_tcoord) { - LLVector2 tc = vf.mVertices[i].mTexCoord; + LLVector2 tc(vf.mTexCoords+i*2); if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) { - LLVector3 vec = vf.mVertices[i].mPosition; + LLVector3 vec = vf_position; vec.scaleVec(scale); switch (texgen) { case LLTextureEntry::TEX_GEN_PLANAR: - planarProjection(tc, vf.mVertices[i].mNormal, vf.mCenter, vec); + planarProjection(tc, vf_normal, vf.mCenter, vec); break; case LLTextureEntry::TEX_GEN_SPHERICAL: - sphericalProjection(tc, vf.mVertices[i].mNormal, vf.mCenter, vec); + sphericalProjection(tc, vf_normal, vf.mCenter, vec); break; case LLTextureEntry::TEX_GEN_CYLINDRICAL: - cylindricalProjection(tc, vf.mVertices[i].mNormal, vf.mCenter, vec); + cylindricalProjection(tc, vf_normal, vf.mCenter, vec); break; default: break; @@ -1345,10 +1348,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)) { - LLVector3 tangent = vf.mVertices[i].mBinormal % vf.mVertices[i].mNormal; + LLVector3 tangent = vf_binormal % vf_normal; LLMatrix3 tangent_to_object; - tangent_to_object.setRows(tangent, vf.mVertices[i].mBinormal, vf.mVertices[i].mNormal); + tangent_to_object.setRows(tangent, vf_binormal, vf_normal); LLVector3 binormal = binormal_dir * tangent_to_object; binormal = binormal * mat_normal; @@ -1366,12 +1369,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (rebuild_pos) { - *vertices++ = vf.mVertices[i].mPosition * mat_vert; + *vertices++ = vf_position * mat_vert; } if (rebuild_normal) { - LLVector3 normal = vf.mVertices[i].mNormal * mat_normal; + LLVector3 normal = vf_normal * mat_normal; normal.normVec(); *normals++ = normal; @@ -1379,21 +1382,21 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (rebuild_binormal) { - LLVector3 binormal = vf.mVertices[i].mBinormal * mat_normal; + LLVector3 binormal = vf_binormal * mat_normal; binormal.normVec(); *binormals++ = binormal; } if (rebuild_weights && vf.mWeights.size() > i) { - *weights++ = vf.mWeights[i]; + (*weights++) = vf.mWeights[i]; } if (rebuild_color) { if (bake_sunlight) { - LLVector3 normal = vf.mVertices[i].mNormal * mat_normal; + LLVector3 normal = vf_normal * mat_normal; normal.normVec(); F32 da = normal * gPipeline.mSunDir; diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index 159e4b41ca..dae301ae29 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -852,6 +852,7 @@ S8 LLImagePreviewSculpted::getType() const void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance) { +#if 0 //VECTORIZE THIS mCameraDistance = distance; mCameraZoom = 1.f; mCameraPitch = 0.f; @@ -892,6 +893,7 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance) { *(index_strider++) = vf.mIndices[i]; } +#endif } @@ -901,7 +903,7 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance) BOOL LLImagePreviewSculpted::render() { mNeedsUpdate = FALSE; - +#if 0 //VECTORIZE THIS LLGLSUIDefault def; LLGLDisable no_blend(GL_BLEND); LLGLEnable cull(GL_CULL_FACE); @@ -959,7 +961,7 @@ BOOL LLImagePreviewSculpted::render() mVertexBuffer->draw(LLRender::TRIANGLES, num_indices, 0); gGL.popMatrix(); - +#endif return TRUE; } diff --git a/indra/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp index 28b0e7356a..c7ad0bde7e 100644 --- a/indra/newview/llhudicon.cpp +++ b/indra/newview/llhudicon.cpp @@ -271,6 +271,7 @@ BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& en LLVector3 upper_left = icon_position - (x_scale * 0.5f) + y_scale; LLVector3 upper_right = icon_position + (x_scale * 0.5f) + y_scale; +#if 0 //VECTORIZE THIS F32 t = 0.f; LLVector3 dir = end-start; @@ -284,6 +285,7 @@ BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& en } return TRUE; } +#endif return FALSE; } diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index 9ed5d13831..64c01d0937 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -206,6 +206,8 @@ BOOL LLHUDText::lineSegmentIntersect(const LLVector3& start, const LLVector3& en gGL.end(); } +#if 0 //VECTORIZE THIS + LLVector3 dir = end-start; F32 t = 0.f; @@ -218,6 +220,9 @@ BOOL LLHUDText::lineSegmentIntersect(const LLVector3& start, const LLVector3& en return TRUE; } } + +#endif + } return FALSE; diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index aa82c216d9..7eca276358 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -788,13 +788,14 @@ BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts) LLMatrix4 render_mat(vo_volume->getRenderRotation(), LLVector4(vo_volume->getRenderPosition())); num_faces = volume->getNumVolumeFaces(); + //VECTORIZE THIS for (i = 0; i < num_faces; i++) { const LLVolumeFace& face = volume->getVolumeFace(i); - for (U32 v = 0; v < face.mVertices.size(); v++) + for (U32 v = 0; v < face.mNumVertices; v++) { - LLVector4 vec = LLVector4(face.mVertices[v].mPosition) * mat; + LLVector4 vec = LLVector4(face.mPositions+v*4) * mat; if (drawablep->isActive()) { diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index a82afbeb76..edb97eef24 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -640,6 +640,7 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en position.mV[2] += blade_height; v[3] = v1 = position + mRegionp->getOriginAgent(); +#if 0 //VECTORIZE THIS F32 a,b,t; @@ -703,6 +704,7 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en } } } +#endif } return ret; diff --git a/indra/newview/llvotextbubble.cpp b/indra/newview/llvotextbubble.cpp index 428ef20006..339da3c0bf 100644 --- a/indra/newview/llvotextbubble.cpp +++ b/indra/newview/llvotextbubble.cpp @@ -45,6 +45,7 @@ #include "llviewertexturelist.h" #include "llvolume.h" #include "pipeline.h" +#include "llvector4a.h" #include "llviewerregion.h" LLVOTextBubble::LLVOTextBubble(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) @@ -217,7 +218,7 @@ void LLVOTextBubble::updateFaceSize(S32 idx) else { const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx); - face->setSize(vol_face.mVertices.size(), vol_face.mIndices.size()); + face->setSize(vol_face.mNumVertices, vol_face.mNumIndices); } } @@ -235,19 +236,37 @@ void LLVOTextBubble::getGeometry(S32 idx, const LLVolumeFace& face = getVolume()->getVolumeFace(idx); - LLVector3 pos = getPositionAgent(); + LLVector4a pos; + pos.load3(getPositionAgent().mV); + + LLVector4a scale; + scale.load3(getScale().mV); + LLColor4U color = LLColor4U(getTE(idx)->getColor()); U32 offset = mDrawable->getFace(idx)->getGeomIndex(); - for (U32 i = 0; i < face.mVertices.size(); i++) + LLVector4a* dst_pos = (LLVector4a*) verticesp.get(); + LLVector4a* src_pos = (LLVector4a*) face.mPositions; + + LLVector4a* dst_norm = (LLVector4a*) normalsp.get(); + LLVector4a* src_norm = (LLVector4a*) face.mNormals; + + LLVector2* dst_tc = (LLVector2*) texcoordsp.get(); + LLVector2* src_tc = (LLVector2*) face.mTexCoords; + + LLVector4a::memcpyNonAliased16((F32*) dst_norm, (F32*) src_norm, face.mNumVertices*4); + LLVector4a::memcpyNonAliased16((F32*) dst_tc, (F32*) src_tc, face.mNumVertices*2); + + + for (U32 i = 0; i < face.mNumVertices; i++) { - *verticesp++ = face.mVertices[i].mPosition.scaledVec(getScale()) + pos; - *normalsp++ = face.mVertices[i].mNormal; - *texcoordsp++ = face.mVertices[i].mTexCoord; + LLVector4a t; + t.setMul(src_pos[i], scale); + dst_pos[i].setAdd(t, pos); *colorsp++ = color; } - for (U32 i = 0; i < face.mIndices.size(); i++) + for (U32 i = 0; i < face.mNumIndices; i++) { *indicesp++ = face.mIndices[i] + offset; } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index cea964a100..7d80a66041 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -60,6 +60,7 @@ #include "llflexibleobject.h" #include "llsky.h" #include "lltexturefetch.h" +#include "llvector4a.h" #include "llviewercamera.h" #include "llviewertexturelist.h" #include "llviewerobjectlist.h" @@ -1601,14 +1602,8 @@ void LLVOVolume::updateFaceSize(S32 idx) else { const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx); - if (LLPipeline::sUseTriStrips) - { - facep->setSize(vol_face.mVertices.size(), vol_face.mTriStrip.size()); - } - else - { - facep->setSize(vol_face.mVertices.size(), vol_face.mIndices.size()); - } + facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices); + } } @@ -1863,21 +1858,25 @@ bool LLVOVolume::hasMedia() const LLVector3 LLVOVolume::getApproximateFaceNormal(U8 face_id) { LLVolume* volume = getVolume(); - LLVector3 result; + LLVector4a result; + result.clear(); + + LLVector3 ret; if (volume && face_id < volume->getNumVolumeFaces()) { const LLVolumeFace& face = volume->getVolumeFace(face_id); - for (S32 i = 0; i < (S32)face.mVertices.size(); ++i) + for (S32 i = 0; i < (S32)face.mNumVertices; ++i) { - result += face.mVertices[i].mNormal; + result.add(*((LLVector4a*) face.mNormals+i*4)); } - result = volumeDirectionToAgent(result); - result.normVec(); + LLVector3 ret((F32*) &result.mQ); + ret = volumeDirectionToAgent(ret); + ret.normVec(); } - return result; + return ret; } void LLVOVolume::requestMediaDataUpdate(bool isNew) @@ -3032,7 +3031,7 @@ F32 LLVOVolume::getBinRadius() for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) { const LLVolumeFace& face = volume->getVolumeFace(i); - vert_count += face.mVertices.size(); + vert_count += face.mNumVertices; } scale = 1.f/llmax(vert_count/1024.f, 1.f); -- cgit v1.3 From d7cab99ba74b214c557d9b5e02a7800b6a25c109 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 22 May 2010 12:37:53 -0500 Subject: Fix for a couple dumb mistakes. --- indra/llmath/llvolume.cpp | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 01fe2be371..88969af4bd 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -5206,7 +5206,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) if (!partial_build) { - resizeIndices(grid_size*6); + resizeIndices(grid_size*grid_size*6); U16* out = mIndices; @@ -5689,12 +5689,21 @@ void LLVolumeFace::resizeVertices(S32 num_verts) mBinormals = NULL; - mPositions = (F32*) _mm_malloc(num_verts*16, 16); - mNormals = (F32*) _mm_malloc(num_verts*16, 16); + if (num_verts) + { + mPositions = (F32*) _mm_malloc(num_verts*16, 16); + mNormals = (F32*) _mm_malloc(num_verts*16, 16); - //pad texture coordinate block end to allow for QWORD reads - S32 size = ((num_verts*8) + 0xF) & ~0xF; - mTexCoords = (F32*) _mm_malloc(size, 16); + //pad texture coordinate block end to allow for QWORD reads + S32 size = ((num_verts*8) + 0xF) & ~0xF; + mTexCoords = (F32*) _mm_malloc(size, 16); + } + else + { + mPositions = NULL; + mNormals = NULL; + mTexCoords = NULL; + } mNumVertices = num_verts; } @@ -5710,10 +5719,17 @@ void LLVolumeFace::resizeIndices(S32 num_indices) { _mm_free(mIndices); - //pad index block end to allow for QWORD reads - S32 size = ((num_indices*2) + 0xF) & ~0xF; - - mIndices = (U16*) _mm_malloc(size,16); + if (num_indices) + { + //pad index block end to allow for QWORD reads + S32 size = ((num_indices*2) + 0xF) & ~0xF; + + mIndices = (U16*) _mm_malloc(size,16); + } + else + { + mIndices = NULL; + } mNumIndices = num_indices; } @@ -5954,7 +5970,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) LLVector3& face_max = mExtents[1]; mCenter.clearVec(); - face_min = face_max = LLVector3((F32*) &(pos[i].mQ)); + face_min = face_max = LLVector3((F32*) &(pos[0].mQ)); for (U32 i = 1; i < mNumVertices; ++i) { -- cgit v1.3 From 8c32e3bf29337e330a313d0e4865ebd03ad9ca50 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 24 May 2010 14:03:10 -0500 Subject: Fix for bad indexes on cube faces. Extra validation on vertex buffers. --- indra/llmath/llvolume.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 88969af4bd..31544016db 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4173,7 +4173,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, for (S32 i = start_face; i <= end_face; i++) { - const LLVolumeFace &face = getVolumeFace((U32)i); + LLVolumeFace &face = mVolumeFaces[i]; LLVector3 box_center = (face.mExtents[0] + face.mExtents[1]) / 2.f; LLVector3 box_size = face.mExtents[1] - face.mExtents[0]; @@ -4235,6 +4235,10 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, if (bi_normal != NULL) { + if (!face.mBinormals) + { + face.createBinormals(); + } LLVector4* binormal = (LLVector4*) face.mBinormals; if (binormal) { @@ -5174,7 +5178,6 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) LLVector4a* binorm = (LLVector4a*) mBinormals; LLVector2* tc = (LLVector2*) mTexCoords; - S32 vtop = mNumVertices; for(int gx = 0;gx=0;i--) { - *out++ = (vtop+(gy*(grid_size+1))+gx+idxs[i]); + *out++ = ((gy*(grid_size+1))+gx+idxs[i]); } } else { for(S32 i=0;i<6;i++) { - *out++ = (vtop+(gy*(grid_size+1))+gx+idxs[i]); + *out++ = ((gy*(grid_size+1))+gx+idxs[i]); } } } -- cgit v1.3 From a2eb86b00927439afcf27219e38e58eba421294f Mon Sep 17 00:00:00 2001 From: "Matthew Breindel (Falcon)" Date: Mon, 24 May 2010 13:37:59 -0700 Subject: Ack. Fixed a bunch of stupid type mistakes in llvector4a. --- indra/llmath/CMakeLists.txt | 2 ++ indra/llmath/llvolume.cpp | 12 ++++++------ indra/newview/llpanelobject.cpp | 17 +++++++++++++++++ indra/newview/llviewerregion.cpp | 3 ++- 4 files changed, 27 insertions(+), 7 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index e93fe90650..367486eee7 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -62,6 +62,8 @@ set(llmath_HEADER_FILES llv4matrix3.h llv4matrix4.h llv4vector3.h + llvector4a.h + llmatrix4a.h llvolume.h llvolumemgr.h llsdutil_math.h diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 88969af4bd..d7d36d901d 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4126,14 +4126,14 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, norm_mat.rotate(n[v1], t); - t.normalize3Fast(); + t.normalize3fast(); normals.push_back(LLVector3(t[0], t[1], t[2])); mat.affineTransform(v[v2], t); vertices.push_back(LLVector3(t[0], t[1], t[2])); norm_mat.rotate(n[v2], t); - t.normalize3Fast(); + t.normalize3fast(); normals.push_back(LLVector3(t[0], t[1], t[2])); segments.push_back(vertices.size()); @@ -5349,7 +5349,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) mCenter, cuv, mesh[0+offset].mPos, tc[0], mesh[1+offset].mPos, tc[1]); - binormal.normalize3Fast(); + binormal.normalize3fast(); LLVector4a normal; LLVector4a d0, d1; @@ -5369,7 +5369,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) normal.setCross3(d1, d0); } - normal.normalize3Fast(); + normal.normalize3fast(); VertexData vd; vd.mPosition = mCenter; @@ -5675,7 +5675,7 @@ void LLVolumeFace::createBinormals() //normalize binormals for (U32 i = 0; i < mNumVertices; i++) { - binorm[i].normalize3Fast(); + binorm[i].normalize3fast(); } } } @@ -5803,7 +5803,7 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat { mat.affineTransform(src_pos[i], dst_pos[i]); norm_mat.rotate(src_norm[i], dst_norm[i]); - dst_norm[i].normalize3Fast(); + dst_norm[i].normalize3fast(); dst_tc[i] = src_tc[i]; diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 669ff3ffd6..77f3984ecb 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -1241,6 +1241,16 @@ void LLPanelObject::sendIsPhantom() } } +#include "llsdutil.h" +class CostResponder : public LLHTTPClient::Responder +{ +public: + CostResponder(U32 id) { mID = id; } + virtual void result(const LLSD& content) { llinfos << ll_pretty_print_sd(content) << llendl; } + + U32 mID; +}; + void LLPanelObject::sendPhysicsShapeType() { U8 value = (U8)mComboPhysicsShapeType->getCurrentIndex(); @@ -1255,6 +1265,13 @@ void LLPanelObject::sendPhysicsShapeType() { llinfos << "update physics shape type not changed" << llendl; } + + std::string url = gAgent.getRegion()->getCapability("GetObjectCost"); + LLSD body = LLSD::emptyArray(); + + body.append(LLSelectMgr::getInstance()->getSelection()->getFirstObject()->getID()); + + LLHTTPClient::post( url, body, new CostResponder(body[0].asInteger()) ); } void LLPanelObject::sendCastShadows() diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 4fdabd7ff0..268e14674e 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1497,6 +1497,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url) capabilityNames.append("FetchLibDescendents"); capabilityNames.append("GetTexture"); capabilityNames.append("GetMesh"); + capabilityNames.append("GetObjectCost"); capabilityNames.append("GroupProposalBallot"); capabilityNames.append("HomeLocation"); capabilityNames.append("LandResources"); @@ -1513,13 +1514,13 @@ void LLViewerRegion::setSeedCapability(const std::string& url) capabilityNames.append("ProvisionVoiceAccountRequest"); capabilityNames.append("RemoteParcelRequest"); capabilityNames.append("RequestTextureDownload"); - capabilityNames.append("SimulatorFeatures"); capabilityNames.append("SearchStatRequest"); capabilityNames.append("SearchStatTracking"); capabilityNames.append("SendPostcard"); capabilityNames.append("SendUserReport"); capabilityNames.append("SendUserReportWithScreenshot"); capabilityNames.append("ServerReleaseNotes"); + capabilityNames.append("SimulatorFeatures"); capabilityNames.append("StartGroupProposal"); capabilityNames.append("TextureStats"); capabilityNames.append("UntrustedSimulatorMessage"); -- cgit v1.3 From c0b654dd4bee466a2ccbf050e532fb4a05acc549 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 24 May 2010 17:33:41 -0500 Subject: Fix for bad feeding of vectorized raycast. --- indra/llmath/llvolume.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 2ff1463b7c..f05e6eb9d9 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4187,6 +4187,9 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector4a starta, dira; + starta.load3(start.mV); + dira.load3(dir.mV); + LLVector4a* p = (LLVector4a*) face.mPositions; for (U32 tri = 0; tri < face.mNumIndices/3; tri++) @@ -4235,17 +4238,10 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, if (bi_normal != NULL) { - if (!face.mBinormals) - { - face.createBinormals(); - } LLVector4* binormal = (LLVector4*) face.mBinormals; - if (binormal) - { - *bi_normal = ((1.f - a - b) * LLVector3(binormal[index1]) + + *bi_normal = ((1.f - a - b) * LLVector3(binormal[index1]) + a * LLVector3(binormal[index2]) + b * LLVector3(binormal[index3])); - } } } -- cgit v1.3 From e6fe3b1f1aa888e4594c89154ef895b3cf5498e9 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 25 May 2010 03:55:01 -0500 Subject: Better vectorization of various things. Turn off debug gl by default. --- indra/llcommon/lldefs.h | 8 + indra/llmath/llvolume.cpp | 383 ++++++++++++++++++++------------ indra/llmath/llvolume.h | 110 +++++++-- indra/newview/app_settings/settings.xml | 4 +- indra/newview/llface.cpp | 8 +- indra/newview/llfloaterimagepreview.cpp | 20 +- indra/newview/llhudicon.cpp | 43 +++- indra/newview/llhudtext.cpp | 5 - indra/newview/llviewercamera.cpp | 16 +- indra/newview/llvograss.cpp | 7 +- indra/newview/llvovolume.cpp | 2 +- 11 files changed, 404 insertions(+), 202 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llcommon/lldefs.h b/indra/llcommon/lldefs.h index f3b5ca361f..10e6cb34bf 100644 --- a/indra/llcommon/lldefs.h +++ b/indra/llcommon/lldefs.h @@ -242,5 +242,13 @@ inline LLDATATYPE llclampb(const LLDATATYPE& a) return llmin(llmax(a, (LLDATATYPE)0), (LLDATATYPE)255); } +template +inline void llswap(LLDATATYPE& lhs, LLDATATYPE& rhs) +{ + LLDATATYPE tmp = lhs; + lhs = rhs; + rhs = tmp; +} + #endif // LL_LLDEFS_H diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index f05e6eb9d9..d8fbc081fa 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -237,6 +237,21 @@ BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, co return TRUE; } +//helper for non-aligned vectors +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) +{ + LLVector4a vert0a, vert1a, vert2a, origa, dira; + vert0a.load3(vert0.mV); + vert1a.load3(vert1.mV); + vert2a.load3(vert2.mV); + origa.load3(orig.mV); + dira.load3(dir.mV); + + return LLTriangleRayIntersect(vert0a, vert1a, vert2a, origa, dira, + intersection_a, intersection_b, intersection_t, two_sided); +} + //------------------------------------------------------------------- // statics @@ -1889,15 +1904,15 @@ bool LLVolumeFace::VertexData::operator==(const LLVolumeFace::VertexData& rhs)co bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs, F32 angle_cutoff) const { bool retval = false; - if (rhs.mPosition == mPosition && rhs.mTexCoord == mTexCoord) + if (rhs.mData[POSITION].equal3(mData[POSITION]) && rhs.mTexCoord == mTexCoord) { if (angle_cutoff > 1.f) { - retval = (mNormal == rhs.mNormal); + retval = (mData[NORMAL].equal3(rhs.mData[NORMAL])); } else { - F32 cur_angle = rhs.mNormal*mNormal; + F32 cur_angle = rhs.mData[NORMAL].dot3(mData[NORMAL]); retval = cur_angle > angle_cutoff; } } @@ -2081,9 +2096,9 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) min = max = LLVector3(0,0,0); - F32* pos_out = face.mPositions; - F32* norm_out = face.mNormals; - F32* tc_out = face.mTexCoords; + F32* pos_out = (F32*) face.mPositions; + F32* norm_out = (F32*) face.mNormals; + F32* tc_out = (F32*) face.mTexCoords; for (U32 j = 0; j < num_verts; ++j) { @@ -2188,13 +2203,15 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) void tetrahedron_set_normal(LLVolumeFace::VertexData* cv) { - LLVector3 nrm = (cv[1].mPosition-cv[0].mPosition)%(cv[2].mPosition-cv[0].mPosition); - - nrm.normVec(); - - cv[0].mNormal = nrm; - cv[1].mNormal = nrm; - cv[2].mNormal = nrm; + LLVector4a v0; + v0.setSub(cv[1].getPosition(), cv[0].getNormal()); + LLVector4a v1; + v1.setSub(cv[2].getNormal(), cv[0].getPosition()); + + cv[0].getNormal().setCross3(v0,v1); + cv[0].getNormal().normalize3fast(); + cv[1].setNormal(cv[0].getNormal()); + cv[2].setNormal(cv[1].getNormal()); } BOOL LLVolume::isTetrahedron() @@ -2209,12 +2226,12 @@ void LLVolume::makeTetrahedron() LLVolumeFace face; F32 x = 0.25f; - LLVector3 p[] = + LLVector4a p[] = { //unit tetrahedron corners - LLVector3(x,x,x), - LLVector3(-x,-x,x), - LLVector3(-x,x,-x), - LLVector3(x,-x,-x) + LLVector4a(x,x,x), + LLVector4a(-x,-x,x), + LLVector4a(-x,x,-x), + LLVector4a(x,-x,-x) }; face.mExtents[0].setVec(-x,-x,-x); @@ -2229,9 +2246,9 @@ void LLVolume::makeTetrahedron() //side 1 - cv[0].mPosition = p[1]; - cv[1].mPosition = p[0]; - cv[2].mPosition = p[2]; + cv[0].setPosition(p[1]); + cv[1].setPosition(p[0]); + cv[2].setPosition(p[2]); tetrahedron_set_normal(cv); @@ -2242,14 +2259,14 @@ void LLVolume::makeTetrahedron() LLVector4a* n = (LLVector4a*) face.mNormals; LLVector2* tc = (LLVector2*) face.mTexCoords; - v[0].load3(cv[0].mPosition.mV); - v[1].load3(cv[1].mPosition.mV); - v[2].load3(cv[2].mPosition.mV); + v[0] = cv[0].getPosition(); + v[1] = cv[1].getPosition(); + v[2] = cv[2].getPosition(); v += 3; - n[0].load3(cv[0].mNormal.mV); - n[1].load3(cv[1].mNormal.mV); - n[2].load3(cv[2].mNormal.mV); + n[0] = cv[0].getNormal(); + n[1] = cv[1].getNormal(); + n[2] = cv[2].getNormal(); n += 3; tc[0] = cv[0].mTexCoord; @@ -2259,20 +2276,20 @@ void LLVolume::makeTetrahedron() //side 2 - cv[0].mPosition = p[3]; - cv[1].mPosition = p[0]; - cv[2].mPosition = p[1]; + cv[0].setPosition(p[3]); + cv[1].setPosition(p[0]); + cv[2].setPosition(p[1]); tetrahedron_set_normal(cv); - v[0].load3(cv[0].mPosition.mV); - v[1].load3(cv[1].mPosition.mV); - v[2].load3(cv[2].mPosition.mV); + v[0] = cv[0].getPosition(); + v[1] = cv[1].getPosition(); + v[2] = cv[2].getPosition(); v += 3; - n[0].load3(cv[0].mNormal.mV); - n[1].load3(cv[1].mNormal.mV); - n[2].load3(cv[2].mNormal.mV); + n[0] = cv[0].getNormal(); + n[1] = cv[1].getNormal(); + n[2] = cv[2].getNormal(); n += 3; tc[0] = cv[0].mTexCoord; @@ -2281,20 +2298,20 @@ void LLVolume::makeTetrahedron() tc += 3; //side 3 - cv[0].mPosition = p[3]; - cv[1].mPosition = p[1]; - cv[2].mPosition = p[2]; + cv[0].setPosition(p[3]); + cv[1].setPosition(p[1]); + cv[2].setPosition(p[2]); tetrahedron_set_normal(cv); - v[0].load3(cv[0].mPosition.mV); - v[1].load3(cv[1].mPosition.mV); - v[2].load3(cv[2].mPosition.mV); + v[0] = cv[0].getPosition(); + v[1] = cv[1].getPosition(); + v[2] = cv[2].getPosition(); v += 3; - n[0].load3(cv[0].mNormal.mV); - n[1].load3(cv[1].mNormal.mV); - n[2].load3(cv[2].mNormal.mV); + n[0] = cv[0].getNormal(); + n[1] = cv[1].getNormal(); + n[2] = cv[2].getNormal(); n += 3; tc[0] = cv[0].mTexCoord; @@ -2303,20 +2320,20 @@ void LLVolume::makeTetrahedron() tc += 3; //side 4 - cv[0].mPosition = p[2]; - cv[1].mPosition = p[0]; - cv[2].mPosition = p[3]; + cv[0].setPosition(p[2]); + cv[1].setPosition(p[0]); + cv[2].setPosition(p[3]); tetrahedron_set_normal(cv); - v[0].load3(cv[0].mPosition.mV); - v[1].load3(cv[1].mPosition.mV); - v[2].load3(cv[2].mPosition.mV); + v[0] = cv[0].getPosition(); + v[1] = cv[1].getPosition(); + v[2] = cv[2].getPosition(); v += 3; - n[0].load3(cv[0].mNormal.mV); - n[1].load3(cv[1].mNormal.mV); - n[2].load3(cv[2].mNormal.mV); + n[0] = cv[0].getNormal(); + n[1] = cv[1].getNormal(); + n[2] = cv[2].getNormal(); n += 3; tc[0] = cv[0].mTexCoord; @@ -3974,9 +3991,9 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, S32 v3 = face.mIndices[j*3+2]; //get current face center - LLVector3 cCenter = (face.mVertices[v1].mPosition + - face.mVertices[v2].mPosition + - face.mVertices[v3].mPosition) / 3.0f; + LLVector3 cCenter = (face.mVertices[v1].getPosition() + + face.mVertices[v2].getPosition() + + face.mVertices[v3].getPosition()) / 3.0f; //for each edge for (S32 k = 0; k < 3; k++) { @@ -3994,9 +4011,9 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, v3 = face.mIndices[nIndex*3+2]; //get neighbor face center - LLVector3 nCenter = (face.mVertices[v1].mPosition + - face.mVertices[v2].mPosition + - face.mVertices[v3].mPosition) / 3.0f; + LLVector3 nCenter = (face.mVertices[v1].getPosition() + + face.mVertices[v2].getPosition() + + face.mVertices[v3].getPosition()) / 3.0f; //draw line vertices.push_back(cCenter); @@ -4020,14 +4037,14 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, //for each vertex for (U32 j = 0; j < face.mNumVertices; j++) { - vertices.push_back(face.mVertices[j].mPosition); - vertices.push_back(face.mVertices[j].mPosition + face.mVertices[j].mNormal*0.1f); + vertices.push_back(face.mVertices[j].getPosition()); + vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].getNormal()*0.1f); normals.push_back(LLVector3(0,0,1)); normals.push_back(LLVector3(0,0,1)); segments.push_back(vertices.size()); #if DEBUG_SILHOUETTE_BINORMALS - vertices.push_back(face.mVertices[j].mPosition); - vertices.push_back(face.mVertices[j].mPosition + face.mVertices[j].mBinormal*0.1f); + vertices.push_back(face.mVertices[j].getPosition()); + vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].mBinormal*0.1f); normals.push_back(LLVector3(0,0,1)); normals.push_back(LLVector3(0,0,1)); segments.push_back(vertices.size()); @@ -5038,9 +5055,15 @@ BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) } } +void LLVolumeFace::getVertexData(U16 index, LLVolumeFace::VertexData& cv) +{ + cv.setPosition(mPositions[index]); + cv.setNormal(mNormals[index]); + cv.mTexCoord = mTexCoords[index]; +} + void LLVolumeFace::optimize(F32 angle_cutoff) { -#if 0 //disabling until a vectorized version is available LLVolumeFace new_face; VertexMapData::PointMap point_map; @@ -5050,10 +5073,11 @@ void LLVolumeFace::optimize(F32 angle_cutoff) { U16 index = mIndices[i]; - LLVolumeFace::VertexData cv = mVertices[index]; - + LLVolumeFace::VertexData cv; + getVertexData(index, cv); + BOOL found = FALSE; - VertexMapData::PointMap::iterator point_iter = point_map.find(cv.mPosition); + VertexMapData::PointMap::iterator point_iter = point_map.find(cv.getPosition()); if (point_iter != point_map.end()) { //duplicate point might exist for (U32 j = 0; j < point_iter->second.size(); ++j) @@ -5062,7 +5086,7 @@ void LLVolumeFace::optimize(F32 angle_cutoff) if (tv.compareNormal(cv, angle_cutoff)) { found = TRUE; - new_face.mIndices.push_back((point_iter->second)[j].mIndex); + new_face.pushIndex((point_iter->second)[j].mIndex); break; } } @@ -5070,14 +5094,14 @@ void LLVolumeFace::optimize(F32 angle_cutoff) if (!found) { - new_face.mVertices.push_back(cv); + new_face.pushVertex(cv); U16 index = (U16) new_face.mNumVertices-1; - new_face.mIndices.push_back(index); + new_face.pushIndex(index); VertexMapData d; - d.mPosition = cv.mPosition; + d.setPosition(cv.getPosition()); d.mTexCoord = cv.mTexCoord; - d.mNormal = cv.mNormal; + d.setNormal(cv.getNormal()); d.mIndex = index; if (point_iter != point_map.end()) { @@ -5085,14 +5109,23 @@ void LLVolumeFace::optimize(F32 angle_cutoff) } else { - point_map[d.mPosition].push_back(d); + point_map[d.getPosition()].push_back(d); } } } - mVertices = new_face.mVertices; - mIndices = new_face.mIndices; -#endif + swapData(new_face); +} + +void LLVolumeFace::swapData(LLVolumeFace& rhs) +{ + llswap(rhs.mPositions, mPositions); + llswap(rhs.mNormals, mNormals); + llswap(rhs.mBinormals, mBinormals); + llswap(rhs.mTexCoords, mTexCoords); + llswap(rhs.mIndices,mIndices); + llswap(rhs.mNumVertices, mNumVertices); + llswap(rhs.mNumIndices, mNumIndices); } void LerpPlanarVertex(LLVolumeFace::VertexData& v0, @@ -5102,10 +5135,21 @@ void LerpPlanarVertex(LLVolumeFace::VertexData& v0, F32 coef01, F32 coef02) { - vout.mPosition = v0.mPosition + ((v1.mPosition-v0.mPosition)*coef01)+((v2.mPosition-v0.mPosition)*coef02); + + LLVector4a lhs; + lhs.setSub(v1.getPosition(), v0.getPosition()); + lhs.mul(coef01); + LLVector4a rhs; + rhs.setSub(v2.getPosition(), v0.getPosition()); + rhs.mul(coef02); + + rhs.add(lhs); + rhs.add(v0.getPosition()); + + vout.setPosition(rhs); + vout.mTexCoord = v0.mTexCoord + ((v1.mTexCoord-v0.mTexCoord)*coef01)+((v2.mTexCoord-v0.mTexCoord)*coef02); - vout.mNormal = v0.mNormal; - vout.mBinormal = v0.mBinormal; + vout.setNormal(v0.getNormal()); } BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) @@ -5137,16 +5181,22 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) VertexData corners[4]; VertexData baseVert; for(int t = 0; t < 4; t++){ - corners[t].mPosition = mesh[offset + (grid_size*t)].mPos; + corners[t].getPosition().load3( mesh[offset + (grid_size*t)].mPos.mV); corners[t].mTexCoord.mV[0] = profile[grid_size*t].mV[0]+0.5f; corners[t].mTexCoord.mV[1] = 0.5f - profile[grid_size*t].mV[1]; } - baseVert.mNormal = - ((corners[1].mPosition-corners[0].mPosition) % - (corners[2].mPosition-corners[1].mPosition)); - baseVert.mNormal.normVec(); + + { + LLVector4a lhs; + lhs.setSub(corners[1].getPosition(), corners[0].getPosition()); + LLVector4a rhs; + rhs.setSub(corners[2].getPosition(), corners[1].getPosition()); + baseVert.getNormal().setCross3(lhs, rhs); + baseVert.getNormal().normalize3fast(); + } + if(!(mTypeMask & TOP_MASK)){ - baseVert.mNormal *= -1.0f; + baseVert.getNormal().mul(-1.0f); }else{ //Swap the UVs on the U(X) axis for top face LLVector2 swap; @@ -5161,9 +5211,9 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) LLVector4a binormal; calc_binormal_from_triangle( binormal, - corners[0].mPosition, corners[0].mTexCoord, - corners[1].mPosition, corners[1].mTexCoord, - corners[2].mPosition, corners[2].mTexCoord); + corners[0].getPosition(), corners[0].mTexCoord, + corners[1].getPosition(), corners[1].mTexCoord, + corners[2].getPosition(), corners[2].mTexCoord); S32 size = (grid_size+1)*(grid_size+1); resizeVertices(size); @@ -5185,18 +5235,18 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) (F32)gx/(F32)grid_size, (F32)gy/(F32)grid_size); - (*pos++).load3(newVert.mPosition.mV); - (*norm++).load3(baseVert.mNormal.mV); - (*tc++) = newVert.mTexCoord; - (*binorm++).load4a((F32*) &binormal.mQ); + *pos++ = newVert.getPosition(); + *norm++ = baseVert.getNormal(); + *tc++ = newVert.mTexCoord; + *binorm++ = binormal; if (gx == 0 && gy == 0) { - min = max = newVert.mPosition; + min = max = LLVector3(newVert.getPosition().getF32()); } else { - update_min_max(min,max,newVert.mPosition); + update_min_max(min,max,newVert.getPosition().getF32()); } } } @@ -5343,18 +5393,19 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) mCenter = (min+max)*0.5f; cuv = (min_uv + max_uv)*0.5f; + LLVector4a center; + center.load3(mCenter.mV); + LLVector4a binormal; calc_binormal_from_triangle(binormal, - mCenter, cuv, - mesh[0+offset].mPos, tc[0], - mesh[1+offset].mPos, tc[1]); + center, cuv, + pos[0], tc[0], + pos[1], tc[1]); binormal.normalize3fast(); LLVector4a normal; LLVector4a d0, d1; - LLVector4a center; - - center.load3(mCenter.mV); + d0.setSub(center, pos[0]); d1.setSub(center, pos[1]); @@ -5371,7 +5422,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) normal.normalize3fast(); VertexData vd; - vd.mPosition = mCenter; + vd.getPosition().load3(mCenter.mV); vd.mTexCoord = cuv; if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK)) @@ -5634,10 +5685,7 @@ void LLVolumeFace::createBinormals() allocateBinormals(mNumVertices); //generate binormals - LLStrider pos; - pos = (LLVector3*) mPositions; - pos.setStride(16); - + LLVector4a* pos = mPositions; LLVector2* tc = (LLVector2*) mTexCoords; LLVector4a* binorm = (LLVector4a*) mBinormals; @@ -5690,12 +5738,12 @@ void LLVolumeFace::resizeVertices(S32 num_verts) if (num_verts) { - mPositions = (F32*) _mm_malloc(num_verts*16, 16); - mNormals = (F32*) _mm_malloc(num_verts*16, 16); + mPositions = (LLVector4a*) _mm_malloc(num_verts*16, 16); + mNormals = (LLVector4a*) _mm_malloc(num_verts*16, 16); //pad texture coordinate block end to allow for QWORD reads S32 size = ((num_verts*8) + 0xF) & ~0xF; - mTexCoords = (F32*) _mm_malloc(size, 16); + mTexCoords = (LLVector2*) _mm_malloc(size, 16); } else { @@ -5707,10 +5755,61 @@ void LLVolumeFace::resizeVertices(S32 num_verts) mNumVertices = num_verts; } +void LLVolumeFace::pushVertex(const LLVolumeFace::VertexData& cv) +{ + pushVertex(cv.getPosition(), cv.getNormal(), cv.mTexCoord); +} + +void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, const LLVector2& tc) +{ + S32 new_verts = mNumVertices+1; + S32 new_size = new_verts*16; + + //positions + LLVector4a* dst = (LLVector4a*) _mm_malloc(new_size, 16); + if (mPositions) + { + LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mPositions, new_size/4); + _mm_free(mPositions); + } + mPositions = dst; + + //normals + dst = (LLVector4a*) _mm_malloc(new_size, 16); + if (mNormals) + { + LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mNormals, new_size/4); + _mm_free(mNormals); + } + mNormals = dst; + + //tex coords + new_size = ((new_verts*8)+0xF) & ~0xF; + + { + LLVector2* dst = (LLVector2*) _mm_malloc(new_size, 16); + if (mTexCoords) + { + LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mTexCoords, new_size/4); + _mm_free(mTexCoords); + } + } + + //just clear binormals + _mm_free(mBinormals); + mBinormals = NULL; + + mPositions[mNumVertices] = pos; + mNormals[mNumVertices] = norm; + mTexCoords[mNumVertices] = tc; + + mNumVertices++; +} + void LLVolumeFace::allocateBinormals(S32 num_verts) { _mm_free(mBinormals); - mBinormals = (F32*) _mm_malloc(num_verts*16, 16); + mBinormals = (LLVector4a*) _mm_malloc(num_verts*16, 16); } @@ -5733,6 +5832,23 @@ void LLVolumeFace::resizeIndices(S32 num_indices) mNumIndices = num_indices; } +void LLVolumeFace::pushIndex(const U16& idx) +{ + S32 new_count = mNumIndices + 1; + S32 new_size = ((new_count*2)+0xF) & ~0xF; + + S32 old_size = (mNumIndices+0xF) & ~0xF; + if (new_size != old_size) + { + U16* dst = (U16*) _mm_malloc(new_size, 16); + LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mIndices, new_size/4); + _mm_free(mIndices); + mIndices = dst; + } + + mIndices[mNumIndices++] = idx; +} + void LLVolumeFace::fillFromLegacyData(std::vector& v, std::vector& idx) { resizeVertices(v.size()); @@ -5740,14 +5856,9 @@ void LLVolumeFace::fillFromLegacyData(std::vector& v, for (U32 i = 0; i < v.size(); ++i) { - for (U32 j = 0; j < 3; ++j) - { - mPositions[i*4+j] = v[i].mPosition[j]; - mNormals[i*4+j] = v[i].mNormal[j]; - } - - mTexCoords[i*2+0] = v[i].mTexCoord.mV[0]; - mTexCoords[i*2+1] = v[i].mTexCoord.mV[1]; + mPositions[i] = v[i].getPosition(); + mNormals[i] = v[i].getNormal(); + mTexCoords[i] = v[i].mTexCoord; } for (U32 i = 0; i < idx.size(); ++i) @@ -5768,13 +5879,13 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat } - F32* new_pos = (F32*) _mm_malloc(new_count*16, 16); - F32* new_norm = (F32*) _mm_malloc(new_count*16, 16); - F32* new_tc = (F32*) _mm_malloc((new_count*8+0xF) & ~0xF, 16); + LLVector4a* new_pos = (LLVector4a*) _mm_malloc(new_count*16, 16); + LLVector4a* new_norm = (LLVector4a*) _mm_malloc(new_count*16, 16); + LLVector2* new_tc = (LLVector2*) _mm_malloc((new_count*8+0xF) & ~0xF, 16); - LLVector4a::memcpyNonAliased16(new_pos, mPositions, new_count*4); - LLVector4a::memcpyNonAliased16(new_norm, mNormals, new_count*4); - LLVector4a::memcpyNonAliased16(new_tc, mTexCoords, new_count*2); + LLVector4a::memcpyNonAliased16((F32*) new_pos, (F32*) mPositions, new_count*4); + LLVector4a::memcpyNonAliased16((F32*) new_norm, (F32*) mNormals, new_count*4); + LLVector4a::memcpyNonAliased16((F32*) new_tc, (F32*) mTexCoords, new_count*2); _mm_free(mPositions); _mm_free(mNormals); @@ -6205,24 +6316,24 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) // Fills in dummy values if the triangle has degenerate texture coordinates. void calc_binormal_from_triangle(LLVector4a& binormal, - const LLVector3& pos0, + const LLVector4a& pos0, const LLVector2& tex0, - const LLVector3& pos1, + const LLVector4a& pos1, const LLVector2& tex1, - const LLVector3& pos2, + const LLVector4a& pos2, const LLVector2& tex2) { - LLVector4a rx0; rx0.set( pos0.mV[VX], tex0.mV[VX], tex0.mV[VY] ); - LLVector4a rx1; rx1.set( pos1.mV[VX], tex1.mV[VX], tex1.mV[VY] ); - LLVector4a rx2; rx2.set( pos2.mV[VX], tex2.mV[VX], tex2.mV[VY] ); + 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; ry0.set( pos0.mV[VY], tex0.mV[VX], tex0.mV[VY] ); - LLVector4a ry1; ry1.set( pos1.mV[VY], tex1.mV[VX], tex1.mV[VY] ); - LLVector4a ry2; ry2.set( pos2.mV[VY], 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; rz0.set( pos0.mV[VZ], tex0.mV[VX], tex0.mV[VY] ); - LLVector4a rz1; rz1.set( pos1.mV[VZ], tex1.mV[VX], tex1.mV[VY] ); - LLVector4a rz2; rz2.set( pos2.mV[VZ], 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; diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 911db6f94b..aa58d6d114 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -40,7 +40,6 @@ class LLPathParams; class LLVolumeParams; class LLProfile; class LLPath; -class LLVector4a; class LLVolumeFace; class LLVolume; @@ -56,6 +55,7 @@ class LLVolume; #include "v4coloru.h" #include "llrefcount.h" #include "llfile.h" +#include "llvector4a.h" //============================================================================ @@ -794,15 +794,74 @@ class LLVolumeFace public: class VertexData { + enum + { + POSITION = 0, + NORMAL = 1 + }; + + private: + void init() + { + mData = (LLVector4a*) _mm_malloc(32, 16); + } public: - LLVector3 mPosition; - LLVector3 mNormal; - LLVector3 mBinormal; + VertexData() + { + init(); + } + + VertexData(const VertexData& rhs) + { + init(); + LLVector4a::memcpyNonAliased16((F32*) mData, (F32*) rhs.mData, 8); + mTexCoord = rhs.mTexCoord; + } + + ~VertexData() + { + _mm_free(mData); + } + + LLVector4a& getPosition() + { + return mData[POSITION]; + } + + LLVector4a& getNormal() + { + return mData[NORMAL]; + } + + const LLVector4a& getPosition() const + { + return mData[POSITION]; + } + + const LLVector4a& getNormal() const + { + return mData[NORMAL]; + } + + + void setPosition(const LLVector4a& pos) + { + mData[POSITION] = pos; + } + + void setNormal(const LLVector4a& norm) + { + mData[NORMAL] = norm; + } + LLVector2 mTexCoord; bool operator<(const VertexData& rhs) const; bool operator==(const VertexData& rhs) const; bool compareNormal(const VertexData& rhs, F32 angle_cutoff) const; + + private: + LLVector4a* mData; }; LLVolumeFace() : @@ -834,6 +893,13 @@ public: void resizeIndices(S32 num_indices); void fillFromLegacyData(std::vector& v, std::vector& idx); + void pushVertex(const VertexData& cv); + void pushVertex(const LLVector4a& pos, const LLVector4a& norm, const LLVector2& tc); + void pushIndex(const U16& idx); + + void swapData(LLVolumeFace& rhs); + + void getVertexData(U16 indx, LLVolumeFace::VertexData& cv); class VertexMapData : public LLVolumeFace::VertexData { @@ -842,28 +908,20 @@ public: bool operator==(const LLVolumeFace::VertexData& rhs) const { - return mPosition == rhs.mPosition && + return getPosition().equal3(rhs.getPosition()) && mTexCoord == rhs.mTexCoord && - mNormal == rhs.mNormal; + getNormal().equal3(rhs.getNormal()); } struct ComparePosition { - bool operator()(const LLVector3& a, const LLVector3& b) const + bool operator()(const LLVector4a& a, const LLVector4a& b) const { - if (a.mV[0] != b.mV[0]) - { - return a.mV[0] < b.mV[0]; - } - if (a.mV[1] != b.mV[1]) - { - return a.mV[1] < b.mV[1]; - } - return a.mV[2] < b.mV[2]; + return a.less3(b); } }; - typedef std::map, VertexMapData::ComparePosition > PointMap; + typedef std::map, VertexMapData::ComparePosition > PointMap; }; void optimize(F32 angle_cutoff = 2.f); @@ -899,10 +957,10 @@ public: S32 mNumVertices; S32 mNumIndices; - F32* mPositions; - F32* mNormals; - F32* mBinormals; - F32* mTexCoords; + LLVector4a* mPositions; + LLVector4a* mNormals; + LLVector4a* mBinormals; + LLVector2* mTexCoords; U16* mIndices; std::vector mEdge; @@ -1059,14 +1117,18 @@ std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params); void calc_binormal_from_triangle( LLVector4a& binormal, - const LLVector3& pos0, + const LLVector4a& pos0, const LLVector2& tex0, - const LLVector3& pos1, + const LLVector4a& pos1, const LLVector2& tex1, - const LLVector3& pos2, + const LLVector4a& pos2, const LLVector2& tex2); BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& 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 LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir, F32* intersection_a, F32* intersection_b, F32* intersection_t, BOOL two_sided); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index b0a4c02a43..9b7cc04120 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6278,7 +6278,7 @@ Type Boolean Value - 1 + 0 RenderDebugPipeline @@ -7735,7 +7735,7 @@ Type Boolean Value - 0 + 1 RenderUseStreamVBO diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 679875e6bd..db3c5cca33 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1216,18 +1216,18 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, LLVector3 vf_binormal; if (vf.mBinormals) { - vf_binormal.set(vf.mBinormals+i*4); + vf_binormal.setVec(vf.mBinormals[i].getF32()); } LLVector3 vf_normal; - vf_normal.set(vf.mNormals+i*4); + vf_normal.set(vf.mNormals[i].getF32()); LLVector3 vf_position; - vf_position.set(vf.mPositions+i*4); + vf_position.set(vf.mPositions[i].getF32()); if (rebuild_tcoord) { - LLVector2 tc(vf.mTexCoords+i*2); + LLVector2 tc(vf.mTexCoords[i]); if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) { diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index dae301ae29..28fe2a14b7 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -852,7 +852,6 @@ S8 LLImagePreviewSculpted::getType() const void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance) { -#if 0 //VECTORIZE THIS mCameraDistance = distance; mCameraZoom = 1.f; mCameraPitch = 0.f; @@ -865,8 +864,8 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance) } const LLVolumeFace &vf = mVolume->getVolumeFace(0); - U32 num_indices = vf.mIndices.size(); - U32 num_vertices = vf.mVertices.size(); + U32 num_indices = vf.mNumIndices; + U32 num_vertices = vf.mNumVertices; mVertexBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL, 0); mVertexBuffer->allocateBuffer(num_vertices, num_indices, TRUE); @@ -880,10 +879,16 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance) mVertexBuffer->getIndexStrider(index_strider); // build vertices and normals + LLStrider pos; + pos = (LLVector3*) vf.mPositions; pos.setStride(16); + LLStrider norm; + norm = (LLVector3*) vf.mNormals; norm.setStride(16); + + for (U32 i = 0; i < num_vertices; i++) { - *(vertex_strider++) = vf.mVertices[i].mPosition; - LLVector3 normal = vf.mVertices[i].mNormal; + *(vertex_strider++) = *pos++; + LLVector3 normal = *norm++; normal.normalize(); *(normal_strider++) = normal; } @@ -893,7 +898,6 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance) { *(index_strider++) = vf.mIndices[i]; } -#endif } @@ -903,7 +907,6 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance) BOOL LLImagePreviewSculpted::render() { mNeedsUpdate = FALSE; -#if 0 //VECTORIZE THIS LLGLSUIDefault def; LLGLDisable no_blend(GL_BLEND); LLGLEnable cull(GL_CULL_FACE); @@ -948,7 +951,7 @@ BOOL LLImagePreviewSculpted::render() LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); const LLVolumeFace &vf = mVolume->getVolumeFace(0); - U32 num_indices = vf.mIndices.size(); + U32 num_indices = vf.mNumIndices; mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL); @@ -961,7 +964,6 @@ BOOL LLImagePreviewSculpted::render() mVertexBuffer->draw(LLRender::TRIANGLES, num_indices, 0); gGL.popMatrix(); -#endif return TRUE; } diff --git a/indra/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp index c7ad0bde7e..3c5a4de7f8 100644 --- a/indra/newview/llhudicon.cpp +++ b/indra/newview/llhudicon.cpp @@ -39,6 +39,7 @@ #include "llviewerobject.h" #include "lldrawable.h" +#include "llvector4a.h" #include "llviewercamera.h" #include "llviewertexture.h" #include "llviewerwindow.h" @@ -266,26 +267,44 @@ BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& en LLVector3 x_scale = image_aspect * (F32)gViewerWindow->getWindowHeightScaled() * mScale * scale_factor * x_pixel_vec; LLVector3 y_scale = (F32)gViewerWindow->getWindowHeightScaled() * mScale * scale_factor * y_pixel_vec; - LLVector3 lower_left = icon_position - (x_scale * 0.5f); - LLVector3 lower_right = icon_position + (x_scale * 0.5f); - LLVector3 upper_left = icon_position - (x_scale * 0.5f) + y_scale; - LLVector3 upper_right = icon_position + (x_scale * 0.5f) + y_scale; + LLVector4a x_scalea; + LLVector4a icon_positiona; + LLVector4a y_scalea; -#if 0 //VECTORIZE THIS - - F32 t = 0.f; - LLVector3 dir = end-start; + x_scalea.load3(x_scale.mV); + x_scalea.mul(0.5f); + y_scalea.load3(y_scale.mV); + + icon_positiona.load3(icon_position.mV); - if (LLTriangleRayIntersect(upper_right, upper_left, lower_right, start, dir, NULL, NULL, &t, FALSE) || - LLTriangleRayIntersect(upper_left, lower_left, lower_right, start, dir, NULL, NULL, &t, FALSE)) + LLVector4a lower_left; + lower_left.setSub(icon_positiona, x_scalea); + LLVector4a lower_right; + lower_right.setAdd(icon_positiona, x_scalea); + LLVector4a upper_left; + upper_left.setAdd(lower_left, y_scalea); + LLVector4a upper_right; + upper_right.setAdd(lower_right, y_scalea); + + F32 t = 0.f; + LLVector4a enda; + enda.load3(end.mV); + LLVector4a starta; + starta.load3(start.mV); + LLVector4a dir; + dir.setSub(enda, starta); + + if (LLTriangleRayIntersect(upper_right, upper_left, lower_right, starta, dir, NULL, NULL, &t, FALSE) || + LLTriangleRayIntersect(upper_left, lower_left, lower_right, starta, dir, NULL, NULL, &t, FALSE)) { if (intersection) { - *intersection = start + dir*t; + dir.mul(t); + starta.add(dir); + *intersection = LLVector3((F32*) &starta.mQ); } return TRUE; } -#endif return FALSE; } diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index 64c01d0937..9ed5d13831 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -206,8 +206,6 @@ BOOL LLHUDText::lineSegmentIntersect(const LLVector3& start, const LLVector3& en gGL.end(); } -#if 0 //VECTORIZE THIS - LLVector3 dir = end-start; F32 t = 0.f; @@ -220,9 +218,6 @@ BOOL LLHUDText::lineSegmentIntersect(const LLVector3& start, const LLVector3& en return TRUE; } } - -#endif - } return FALSE; diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index 7eca276358..cef7c4abbb 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -38,6 +38,7 @@ // Viewer includes #include "llagent.h" #include "llagentcamera.h" +#include "llmatrix4a.h" #include "llviewercontrol.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" @@ -787,22 +788,29 @@ BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts) LLMatrix4 render_mat(vo_volume->getRenderRotation(), LLVector4(vo_volume->getRenderPosition())); + LLMatrix4a render_mata; + render_mata.loadu(render_mat); + LLMatrix4a mata; + mata.loadu(mat); + num_faces = volume->getNumVolumeFaces(); - //VECTORIZE THIS for (i = 0; i < num_faces; i++) { const LLVolumeFace& face = volume->getVolumeFace(i); for (U32 v = 0; v < face.mNumVertices; v++) { - LLVector4 vec = LLVector4(face.mPositions+v*4) * mat; + const LLVector4a& src_vec = face.mPositions[v]; + LLVector4a vec; + mata.affineTransform(src_vec, vec); if (drawablep->isActive()) { - vec = vec * render_mat; + LLVector4a t = vec; + render_mata.affineTransform(t, vec); } - BOOL in_frustum = pointInFrustum(LLVector3(vec)) > 0; + BOOL in_frustum = pointInFrustum(LLVector3(vec.getF32())) > 0; if (( !in_frustum && all_verts) || (in_frustum && !all_verts)) diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index b40e6af496..d2842fd62c 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -594,9 +594,9 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en LLVector2 tc[4]; LLVector3 v[4]; - // LLVector3 n[4]; // unused! + LLVector3 n[4]; - // F32 closest_t = 1.f; // unused! + F32 closest_t = 1.f; for (S32 i = 0; i < mNumBlades; i++) { @@ -640,8 +640,6 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en position.mV[2] += blade_height; v[3] = v1 = position + mRegionp->getOriginAgent(); -#if 0 //VECTORIZE THIS - F32 a,b,t; BOOL hit = FALSE; @@ -704,7 +702,6 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en } } } -#endif } return ret; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index d57a535050..8022f81f19 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1868,7 +1868,7 @@ LLVector3 LLVOVolume::getApproximateFaceNormal(U8 face_id) const LLVolumeFace& face = volume->getVolumeFace(face_id); for (S32 i = 0; i < (S32)face.mNumVertices; ++i) { - result.add(*((LLVector4a*) face.mNormals+i*4)); + result.add(face.mNormals[i]); } LLVector3 ret((F32*) &result.mQ); -- cgit v1.3 From c98b1b3fd9341834978aff0e841714e206d28c0a Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 26 May 2010 03:29:19 -0500 Subject: Fully aligned llvolume --- indra/llmath/llvolume.cpp | 353 ++++++++++++++++++++++------- indra/llmath/llvolume.h | 99 +++----- indra/llmath/v3math.h | 1 - indra/newview/llface.cpp | 272 +++++++++++++--------- indra/newview/llpanelprimmediacontrols.cpp | 4 +- indra/newview/llvovolume.cpp | 3 +- 6 files changed, 468 insertions(+), 264 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index d8fbc081fa..9b6e2488e6 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -107,22 +107,27 @@ BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLV BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size) { - float fAWdU[3]; - LLVector3 dir; - LLVector3 diff; + return LLLineSegmentBoxIntersect(start.mV, end.mV, center.mV, size.mV); +} + +BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* center, const F32* size) +{ + F32 fAWdU[3]; + F32 dir[3]; + F32 diff[3]; for (U32 i = 0; i < 3; i++) { - dir.mV[i] = 0.5f * (end.mV[i] - start.mV[i]); - diff.mV[i] = (0.5f * (end.mV[i] + start.mV[i])) - center.mV[i]; - fAWdU[i] = fabsf(dir.mV[i]); - if(fabsf(diff.mV[i])>size.mV[i] + fAWdU[i]) return false; + dir[i] = 0.5f * (end[i] - start[i]); + diff[i] = (0.5f * (end[i] + start[i])) - center[i]; + fAWdU[i] = fabsf(dir[i]); + if(fabsf(diff[i])>size[i] + fAWdU[i]) return false; } float f; - f = dir.mV[1] * diff.mV[2] - dir.mV[2] * diff.mV[1]; if(fabsf(f)>size.mV[1]*fAWdU[2] + size.mV[2]*fAWdU[1]) return false; - f = dir.mV[2] * diff.mV[0] - dir.mV[0] * diff.mV[2]; if(fabsf(f)>size.mV[0]*fAWdU[2] + size.mV[2]*fAWdU[0]) return false; - f = dir.mV[0] * diff.mV[1] - dir.mV[1] * diff.mV[0]; if(fabsf(f)>size.mV[0]*fAWdU[1] + size.mV[1]*fAWdU[0]) return false; + f = dir[1] * diff[2] - dir[2] * diff[1]; if(fabsf(f)>size[1]*fAWdU[2] + size[2]*fAWdU[1]) return false; + f = dir[2] * diff[0] - dir[0] * diff[2]; if(fabsf(f)>size[0]*fAWdU[2] + size[2]*fAWdU[0]) return false; + f = dir[0] * diff[1] - dir[1] * diff[0]; if(fabsf(f)>size[0]*fAWdU[1] + size[1]*fAWdU[0]) return false; return true; } @@ -1869,6 +1874,59 @@ BOOL LLVolume::generate() return FALSE; } +void LLVolumeFace::VertexData::init() +{ + mData = (LLVector4a*) _mm_malloc(32, 16); +} + +LLVolumeFace::VertexData::VertexData() +{ + init(); +} + +LLVolumeFace::VertexData::VertexData(const VertexData& rhs) +{ + init(); + LLVector4a::memcpyNonAliased16((F32*) mData, (F32*) rhs.mData, 8); + mTexCoord = rhs.mTexCoord; +} + +LLVolumeFace::VertexData::~VertexData() +{ + _mm_free(mData); +} + +LLVector4a& LLVolumeFace::VertexData::getPosition() +{ + return mData[POSITION]; +} + +LLVector4a& LLVolumeFace::VertexData::getNormal() +{ + return mData[NORMAL]; +} + +const LLVector4a& LLVolumeFace::VertexData::getPosition() const +{ + return mData[POSITION]; +} + +const LLVector4a& LLVolumeFace::VertexData::getNormal() const +{ + return mData[NORMAL]; +} + + +void LLVolumeFace::VertexData::setPosition(const LLVector4a& pos) +{ + mData[POSITION] = pos; +} + +void LLVolumeFace::VertexData::setNormal(const LLVector4a& norm) +{ + mData[NORMAL] = norm; +} + bool LLVolumeFace::VertexData::operator<(const LLVolumeFace::VertexData& rhs)const { const U8* l = (const U8*) this; @@ -2037,7 +2095,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) if (mdl[i].has("Weights")) { - face.mWeights.resize(num_verts); + face.allocateWeights(num_verts); LLSD::Binary weights = mdl[i]["Weights"]; @@ -2050,13 +2108,15 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) U8 joint = weights[idx++]; U32 cur_influence = 0; + LLVector4 wght(0,0,0,0); + while (joint != END_INFLUENCES) { U16 influence = weights[idx++]; influence |= ((U16) weights[idx++] << 8); F32 w = llmin((F32) influence / 65535.f, 0.99999f); - face.mWeights[cur_vertex].mV[cur_influence++] = (F32) joint + w; + wght.mV[cur_influence++] = (F32) joint + w; if (cur_influence >= 4) { @@ -2068,6 +2128,8 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) } } + face.mWeights[cur_vertex].loadua(wght.mV); + cur_vertex++; } @@ -2078,62 +2140,70 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) } - LLVector3 min_pos; - LLVector3 max_pos; + LLVector3 minp; + LLVector3 maxp; LLVector2 min_tc; LLVector2 max_tc; - min_pos.setValue(mdl[i]["PositionDomain"]["Min"]); - max_pos.setValue(mdl[i]["PositionDomain"]["Max"]); + minp.setValue(mdl[i]["PositionDomain"]["Min"]); + maxp.setValue(mdl[i]["PositionDomain"]["Max"]); + LLVector4a min_pos, max_pos; + min_pos.load3(minp.mV); + max_pos.load3(maxp.mV); + min_tc.setValue(mdl[i]["TexCoord0Domain"]["Min"]); max_tc.setValue(mdl[i]["TexCoord0Domain"]["Max"]); - LLVector3 pos_range = max_pos - min_pos; + LLVector4a pos_range; + pos_range.setSub(max_pos, min_pos); LLVector2 tc_range = max_tc - min_tc; - LLVector3& min = face.mExtents[0]; - LLVector3& max = face.mExtents[1]; - - min = max = LLVector3(0,0,0); + LLVector4a& min = face.mExtents[0]; + LLVector4a& max = face.mExtents[1]; - F32* pos_out = (F32*) face.mPositions; - F32* norm_out = (F32*) face.mNormals; - F32* tc_out = (F32*) face.mTexCoords; + min.clear(); + max.clear(); + + LLVector4a* pos_out = face.mPositions; + LLVector4a* norm_out = face.mNormals; + LLVector2* tc_out = face.mTexCoords; for (U32 j = 0; j < num_verts; ++j) { U16* v = (U16*) &(pos[j*3*2]); - pos_out[0] = (F32) v[0] / 65535.f * pos_range.mV[0] + min_pos.mV[0]; - pos_out[1] = (F32) v[1] / 65535.f * pos_range.mV[1] + min_pos.mV[1]; - pos_out[2] = (F32) v[2] / 65535.f * pos_range.mV[2] + min_pos.mV[2]; - + pos_out->set((F32) v[0], (F32) v[1], (F32) v[2]); + pos_out->div(65535.f); + pos_out->mul(pos_range); + pos_out->add(min_pos); if (j == 0) { - min = max = LLVector3(pos_out); + min = *pos_out; + max = min; } else { - update_min_max(min,max,pos_out); + min.setMin(*pos_out); + max.setMax(*pos_out); } - pos_out += 4; + pos_out++; U16* n = (U16*) &(norm[j*3*2]); - - norm_out[0] = (F32) n[0] / 65535.f * 2.f - 1.f; - norm_out[1] = (F32) n[1] / 65535.f * 2.f - 1.f; - norm_out[2] = (F32) n[2] / 65535.f * 2.f - 1.f; - norm_out += 4; + norm_out->set((F32) n[0], (F32) n[1], (F32) n[2]); + norm_out->div(65535.f); + norm_out->mul(2.f); + norm_out->sub(1.f); + norm_out++; U16* t = (U16*) &(tc[j*2*2]); - tc_out[0] = (F32) t[0] / 65535.f * tc_range.mV[0] + min_tc.mV[0]; - tc_out[1] = (F32) t[1] / 65535.f * tc_range.mV[1] + min_tc.mV[1]; + tc_out->mV[0] = (F32) t[0] / 65535.f * tc_range.mV[0] + min_tc.mV[0]; + tc_out->mV[1] = (F32) t[1] / 65535.f * tc_range.mV[1] + min_tc.mV[1]; - tc_out += 8; + tc_out++; } @@ -2234,8 +2304,8 @@ void LLVolume::makeTetrahedron() LLVector4a(x,-x,-x) }; - face.mExtents[0].setVec(-x,-x,-x); - face.mExtents[1].setVec(x,x,x); + face.mExtents[0].splat(-x); + face.mExtents[1].splat(x); LLVolumeFace::VertexData cv[3]; @@ -4165,6 +4235,18 @@ void LLVolume::generateSilhouetteVertices(std::vector &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) { S32 hit_face = -1; @@ -4182,7 +4264,8 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, end_face = face; } - LLVector3 dir = end - start; + LLVector4a dir; + dir.setSub(end, start); F32 closest_t = 2.f; // must be larger than 1 @@ -4192,21 +4275,20 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, { LLVolumeFace &face = mVolumeFaces[i]; - LLVector3 box_center = (face.mExtents[0] + face.mExtents[1]) / 2.f; - LLVector3 box_size = face.mExtents[1] - face.mExtents[0]; + LLVector4a box_center; + box_center.setAdd(face.mExtents[0], face.mExtents[1]); + box_center.mul(0.5f); + + LLVector4a box_size; + box_size.setSub(face.mExtents[1], face.mExtents[0]); - if (LLLineSegmentBoxIntersect(start, end, box_center, box_size)) + if (LLLineSegmentBoxIntersect(start.getF32(), end.getF32(), box_center.getF32(), box_size.getF32())) { if (bi_normal != NULL) // if the caller wants binormals, we may need to generate them { genBinormals(i); } - LLVector4a starta, dira; - - starta.load3(start.mV); - dira.load3(dir.mV); - LLVector4a* p = (LLVector4a*) face.mPositions; for (U32 tri = 0; tri < face.mNumIndices/3; tri++) @@ -4220,7 +4302,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, if (LLTriangleRayIntersect(p[index1], p[index2], p[index3], - starta, dira, &a, &b, &t, FALSE)) + start, dir, &a, &b, &t, FALSE)) { if ((t >= 0.f) && // if hit is after start (t <= 1.f) && // and before end @@ -4231,7 +4313,10 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, if (intersection != NULL) { - *intersection = start + dir * closest_t; + LLVector4a intersect = dir; + intersect.mul(closest_t); + intersect.add(start); + intersection->set(intersect.getF32()); } @@ -5029,6 +5114,107 @@ std::ostream& operator<<(std::ostream &s, const LLVolume *volumep) return s; } +LLVolumeFace::LLVolumeFace() : + mID(0), + mTypeMask(0), + mBeginS(0), + mBeginT(0), + mNumS(0), + mNumT(0), + mNumVertices(0), + mNumIndices(0), + mPositions(NULL), + mNormals(NULL), + mBinormals(NULL), + mTexCoords(NULL), + mIndices(NULL), + mWeights(NULL) +{ + mExtents = (LLVector4a*) _mm_malloc(48, 16); + mCenter = mExtents+2; +} + +LLVolumeFace::LLVolumeFace(const LLVolumeFace& src) +{ + mExtents = (LLVector4a*) _mm_malloc(48, 16); + mCenter = mExtents+2; + *this = src; +} + +LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) +{ + if (&src == this) + { //self assignment, do nothing + return *this; + } + + mID = src.mID; + mTypeMask = src.mTypeMask; + mBeginS = src.mBeginS; + mBeginT = src.mBeginT; + mNumS = src.mNumS; + mNumT = src.mNumT; + + mNumVertices = 0; + mNumIndices = 0; + mPositions = NULL; + mNormals = NULL; + mBinormals = NULL; + mTexCoords = NULL; + mWeights = NULL; + mIndices = NULL; + + LLVector4a::memcpyNonAliased16((F32*) mExtents, (F32*) src.mExtents, 12); + + resizeVertices(src.mNumVertices); + resizeIndices(src.mNumIndices); + + if (mNumVertices) + { + S32 vert_size = mNumVertices*4; + S32 tc_size = (mNumVertices*8+0xF) & ~0xF; + tc_size /= 4; + + LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) src.mPositions, vert_size); + LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) src.mNormals, vert_size); + LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, vert_size); + + if (src.mBinormals) + { + allocateBinormals(src.mNumVertices); + LLVector4a::memcpyNonAliased16((F32*) mBinormals, (F32*) src.mBinormals, vert_size); + } + else + { + _mm_free(mBinormals); + mBinormals = NULL; + } + + if (src.mWeights) + { + allocateWeights(src.mNumVertices); + LLVector4a::memcpyNonAliased16((F32*) mWeights, (F32*) src.mWeights, vert_size); + } + else + { + _mm_free(mWeights); + mWeights = NULL; + } + } + + if (mNumIndices) + { + S32 idx_size = (mNumIndices*2+0xF) & ~0xF; + idx_size /= 4; + + LLVector4a::memcpyNonAliased16((F32*) mIndices, (F32*) src.mIndices, idx_size); + } + + + //delete + return *this; +} + LLVolumeFace::~LLVolumeFace() { _mm_free(mPositions); @@ -5036,6 +5222,8 @@ LLVolumeFace::~LLVolumeFace() _mm_free(mTexCoords); _mm_free(mIndices); _mm_free(mBinormals); + _mm_free(mWeights); + _mm_free(mExtents); } BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) @@ -5169,8 +5357,8 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) num_vertices = (grid_size+1)*(grid_size+1); num_indices = quad_count * 4; - LLVector3& min = mExtents[0]; - LLVector3& max = mExtents[1]; + LLVector4a& min = mExtents[0]; + LLVector4a& max = mExtents[1]; S32 offset = 0; if (mTypeMask & TOP_MASK) @@ -5242,16 +5430,18 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) if (gx == 0 && gy == 0) { - min = max = LLVector3(newVert.getPosition().getF32()); + min = max = newVert.getPosition(); } else { - update_min_max(min,max,newVert.getPosition().getF32()); + min.setMin(newVert.getPosition()); + max.setMax(newVert.getPosition()); } } } - mCenter = (min + max) * 0.5f; + mCenter->setAdd(min, max); + mCenter->mul(0.5f); if (!partial_build) { @@ -5335,7 +5525,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) S32 max_s = volume->getProfile().getTotal(); S32 max_t = volume->getPath().mPath.size(); - mCenter.clearVec(); + mCenter->clear(); S32 offset = 0; if (mTypeMask & TOP_MASK) @@ -5353,8 +5543,8 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) LLVector2 cuv; LLVector2 min_uv, max_uv; - LLVector3& min = mExtents[0]; - LLVector3& max = mExtents[1]; + LLVector4a& min = mExtents[0]; + LLVector4a& max = mExtents[1]; LLVector2* tc = (LLVector2*) mTexCoords; LLVector4a* pos = (LLVector4a*) mPositions; @@ -5380,25 +5570,24 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) if (i == 0) { - min = max = mesh[i+offset].mPos; + min = max = pos[i]; min_uv = max_uv = tc[i]; } else { - update_min_max(min,max, mesh[i+offset].mPos); + update_min_max(min,max,pos[i]); update_min_max(min_uv, max_uv, tc[i]); } } - mCenter = (min+max)*0.5f; - cuv = (min_uv + max_uv)*0.5f; + mCenter->setAdd(min, max); + mCenter->mul(0.5f); - LLVector4a center; - center.load3(mCenter.mV); + cuv = (min_uv + max_uv)*0.5f; LLVector4a binormal; calc_binormal_from_triangle(binormal, - center, cuv, + *mCenter, cuv, pos[0], tc[0], pos[1], tc[1]); binormal.normalize3fast(); @@ -5407,8 +5596,8 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) LLVector4a d0, d1; - d0.setSub(center, pos[0]); - d1.setSub(center, pos[1]); + d0.setSub(*mCenter, pos[0]); + d1.setSub(*mCenter, pos[1]); if (mTypeMask & TOP_MASK) { @@ -5422,12 +5611,12 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) normal.normalize3fast(); VertexData vd; - vd.getPosition().load3(mCenter.mV); + vd.setPosition(*mCenter); vd.mTexCoord = cuv; if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK)) { - pos[num_vertices].load4a((F32*) ¢er.mQ); + pos[num_vertices] = *mCenter; tc[num_vertices] = cuv; num_vertices++; } @@ -5812,6 +6001,11 @@ void LLVolumeFace::allocateBinormals(S32 num_verts) mBinormals = (LLVector4a*) _mm_malloc(num_verts*16, 16); } +void LLVolumeFace::allocateWeights(S32 num_verts) +{ + _mm_free(mWeights); + mWeights = (LLVector4a*) _mm_malloc(num_verts*16, 16); +} void LLVolumeFace::resizeIndices(S32 num_indices) { @@ -5919,11 +6113,11 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat if (offset == 0 && i == 0) { - mExtents[0] = mExtents[1] = LLVector3((F32*) &(dst_pos[i].mQ)); + mExtents[0] = mExtents[1] = dst_pos[i]; } else { - update_min_max(mExtents[0], mExtents[1], (F32*) &(dst_pos[i].mQ)); + update_min_max(mExtents[0], mExtents[1], dst_pos[i]); } } @@ -6076,18 +6270,19 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) //get bounding box for this side - LLVector3& face_min = mExtents[0]; - LLVector3& face_max = mExtents[1]; - mCenter.clearVec(); + LLVector4a& face_min = mExtents[0]; + LLVector4a& face_max = mExtents[1]; + mCenter->clear(); - face_min = face_max = LLVector3((F32*) &(pos[0].mQ)); + face_min = face_max = pos[0]; for (U32 i = 1; i < mNumVertices; ++i) { - update_min_max(face_min, face_max, (F32*) &(pos[i].mQ)); + update_min_max(face_min, face_max, pos[i]); } - mCenter = (face_min + face_max) * 0.5f; + mCenter->setAdd(face_min, face_max); + mCenter->mul(0.5f); S32 cur_index = 0; S32 cur_edge = 0; diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index aa58d6d114..7c63266aab 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -50,12 +50,13 @@ class LLVolume; #include "v2math.h" #include "v3math.h" #include "v4math.h" +#include "llvector4a.h" #include "llquaternion.h" #include "llstrider.h" #include "v4coloru.h" #include "llrefcount.h" #include "llfile.h" -#include "llvector4a.h" + //============================================================================ @@ -801,59 +802,19 @@ public: }; private: - void init() - { - mData = (LLVector4a*) _mm_malloc(32, 16); - } + void init(); public: - VertexData() - { - init(); - } - - VertexData(const VertexData& rhs) - { - init(); - LLVector4a::memcpyNonAliased16((F32*) mData, (F32*) rhs.mData, 8); - mTexCoord = rhs.mTexCoord; - } - - ~VertexData() - { - _mm_free(mData); - } - - LLVector4a& getPosition() - { - return mData[POSITION]; - } - - LLVector4a& getNormal() - { - return mData[NORMAL]; - } - - const LLVector4a& getPosition() const - { - return mData[POSITION]; - } - - const LLVector4a& getNormal() const - { - return mData[NORMAL]; - } + VertexData(); + VertexData(const VertexData& rhs); + ~VertexData(); + LLVector4a& getPosition(); + LLVector4a& getNormal(); + const LLVector4a& getPosition() const; + const LLVector4a& getNormal() const; + void setPosition(const LLVector4a& pos); + void setNormal(const LLVector4a& norm); - void setPosition(const LLVector4a& pos) - { - mData[POSITION] = pos; - } - - void setNormal(const LLVector4a& norm) - { - mData[NORMAL] = norm; - } - LLVector2 mTexCoord; bool operator<(const VertexData& rhs) const; @@ -864,22 +825,9 @@ public: LLVector4a* mData; }; - LLVolumeFace() : - mID(0), - mTypeMask(0), - mBeginS(0), - mBeginT(0), - mNumS(0), - mNumT(0), - mNumVertices(0), - mNumIndices(0), - mPositions(NULL), - mNormals(NULL), - mBinormals(NULL), - mTexCoords(NULL), - mIndices(NULL) - { - } + LLVolumeFace(); + LLVolumeFace(const LLVolumeFace& src); + LLVolumeFace& operator=(const LLVolumeFace& rhs); ~LLVolumeFace(); @@ -890,6 +838,7 @@ public: void resizeVertices(S32 num_verts); void allocateBinormals(S32 num_verts); + void allocateWeights(S32 num_verts); void resizeIndices(S32 num_indices); void fillFromLegacyData(std::vector& v, std::vector& idx); @@ -944,15 +893,15 @@ public: public: S32 mID; U32 mTypeMask; - LLVector3 mCenter; - + // Only used for INNER/OUTER faces S32 mBeginS; S32 mBeginT; S32 mNumS; S32 mNumT; - LLVector3 mExtents[2]; //minimum and maximum point of face + LLVector4a* mExtents; //minimum and maximum point of face + LLVector4a* mCenter; S32 mNumVertices; S32 mNumIndices; @@ -968,7 +917,7 @@ public: //list of skin weights for rigged volumes // format is mWeights[vertex_index].mV[influence] = . // mWeights.size() should be empty or match mVertices.size() - std::vector mWeights; + LLVector4a* mWeights; private: BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE); @@ -1051,6 +1000,13 @@ public: LLVector3* normal = NULL, // return the surface normal at the intersection point LLVector3* bi_normal = NULL // return the surface bi-normal 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); // The following cleans up vertices and triangles, // getting rid of degenerate triangles and duplicate vertices, @@ -1124,6 +1080,7 @@ void calc_binormal_from_triangle( 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 LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir, diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h index 0e7d72e958..75c860a91e 100644 --- a/indra/llmath/v3math.h +++ b/indra/llmath/v3math.h @@ -36,7 +36,6 @@ #include "llerror.h" #include "llmath.h" - #include "llsd.h" class LLVector2; class LLVector4; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index db3c5cca33..5cdfdbacde 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -39,6 +39,7 @@ #include "llviewercontrol.h" #include "llvolume.h" #include "m3math.h" +#include "llmatrix4a.h" #include "v3color.h" #include "lldrawpoolavatar.h" @@ -74,35 +75,43 @@ The resulting texture coordinate is: u = 2(B dot P) v = 2(T dot P) */ -void planarProjection(LLVector2 &tc, const LLVector3& normal, - const LLVector3 &mCenter, const LLVector3& vec) -{ //DONE! - LLVector3 binormal; - float d = normal * LLVector3(1,0,0); +void planarProjection(LLVector2 &tc, const LLVector4a& normal, + const LLVector4a ¢er, const LLVector4a& vec) +{ + LLVector4a binormal; + F32 d = normal[0]; + if (d >= 0.5f || d <= -0.5f) { - binormal = LLVector3(0,1,0); - if (normal.mV[0] < 0) + if (d < 0) { - binormal = -binormal; + binormal.set(0,-1,0); + } + else + { + binormal.set(0, 1, 0); } } else { - binormal = LLVector3(1,0,0); - if (normal.mV[1] > 0) + if (normal[1] > 0) + { + binormal.set(-1,0,0); + } + else { - binormal = -binormal; + binormal.set(1,0,0); } } - LLVector3 tangent = binormal % normal; + LLVector4a tangent; + tangent.setCross3(binormal,normal); - tc.mV[1] = -((tangent*vec)*2 - 0.5f); - tc.mV[0] = 1.0f+((binormal*vec)*2 - 0.5f); + tc.mV[1] = -((tangent.dot3(vec))*2 - 0.5f); + tc.mV[0] = 1.0f+((binormal.dot3(vec))*2 - 0.5f); } -void sphericalProjection(LLVector2 &tc, const LLVector3& normal, - const LLVector3 &mCenter, const LLVector3& vec) +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; @@ -113,7 +122,7 @@ void sphericalProjection(LLVector2 &tc, const LLVector3& normal, }*/ } -void cylindricalProjection(LLVector2 &tc, const LLVector3& normal, const LLVector3 &mCenter, const LLVector3& vec) +void cylindricalProjection(LLVector2 &tc, const LLVector4a& normal, const LLVector4a &mCenter, const LLVector4a& vec) { //BROKEN /*LLVector3 binormal; float d = vd.mNormal * LLVector3(1,0,0); @@ -371,7 +380,14 @@ void LLFace::setSize(S32 num_vertices, S32 num_indices, bool align) if (align) { //allocate vertices in blocks of 4 for alignment - S32 num_vertices = (num_vertices + 0x3) & ~0x3; + num_vertices = (num_vertices + 0x3) & ~0x3; + } + else + { + if (mDrawablep->getVOVolume()) + { + llerrs << "WTF?" << llendl; + } } if (mGeomCount != num_vertices || @@ -722,6 +738,7 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, // mLastVertexBuffer = NULL; //} + //VECTORIZE THIS LLVector3 min,max; if (f >= volume.getNumVolumeFaces()) @@ -732,8 +749,8 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, else { const LLVolumeFace &face = volume.getVolumeFace(f); - min = face.mExtents[0]; - max = face.mExtents[1]; + min.set(face.mExtents[0].getF32()); + max.set(face.mExtents[1].getF32()); } //min, max are in volume space, convert to drawable render space @@ -824,18 +841,26 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position, return surface_coord; } + //VECTORIZE THIS // see if we have a non-default mapping U8 texgen = getTextureEntry()->getTexGen(); if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) { - LLVector3 center = mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter; + LLVector4a& center = *(mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter); - LLVector3 scale = (mDrawablep->getVOVolume()->isVolumeGlobal()) ? LLVector3(1,1,1) : mVObjp->getScale(); - LLVector3 volume_position = mDrawablep->getVOVolume()->agentPositionToVolume(position); - volume_position.scaleVec(scale); + LLVector4a volume_position; + volume_position.load3(mDrawablep->getVOVolume()->agentPositionToVolume(position).mV); - LLVector3 volume_normal = mDrawablep->getVOVolume()->agentDirectionToVolume(normal); - volume_normal.normalize(); + if (!mDrawablep->getVOVolume()->isVolumeGlobal()) + { + LLVector4a scale; + scale.load3(mVObjp->getScale().mV); + volume_position.mul(scale); + } + + LLVector4a volume_normal; + volume_normal.load3(mDrawablep->getVOVolume()->agentDirectionToVolume(normal).mV); + volume_normal.normalize3fast(); switch (texgen) { @@ -928,7 +953,7 @@ static LLFastTimer::DeclareTimer FTM_FACE_GET_GEOM("Face Geom"); BOOL LLFace::getGeometryVolume(const LLVolume& volume, const S32 &f, - const LLMatrix4& mat_vert, const LLMatrix3& mat_normal, + const LLMatrix4& mat_vert_in, const LLMatrix3& mat_norm_in, const U16 &index_offset, bool force_rebuild) { @@ -960,14 +985,18 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } } - LLStrider vertices; + LLStrider vert; + LLVector4a* vertices = NULL; LLStrider tex_coords; LLStrider tex_coords2; - LLStrider normals; + LLVector4a* normals = NULL; + LLStrider norm; LLStrider colors; - LLStrider binormals; + LLVector4a* binormals = NULL; + LLStrider binorm; LLStrider indicesp; - LLStrider weights; + LLVector4a* weights = NULL; + LLStrider wght; BOOL full_rebuild = force_rebuild || mDrawablep->isState(LLDrawable::REBUILD_VOLUME); @@ -982,11 +1011,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, scale = mVObjp->getScale(); } - BOOL rebuild_pos = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_POSITION); - BOOL rebuild_color = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_COLOR); - 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_pos = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_POSITION); + bool rebuild_color = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_COLOR); + 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_weights = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_WEIGHT4); const LLTextureEntry *tep = mVObjp->getTE(f); @@ -994,19 +1023,23 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (rebuild_pos) { - mVertexBuffer->getVertexStrider(vertices, mGeomIndex); + mVertexBuffer->getVertexStrider(vert, mGeomIndex); + vertices = (LLVector4a*) vert.get(); } if (rebuild_normal) { - mVertexBuffer->getNormalStrider(normals, mGeomIndex); + mVertexBuffer->getNormalStrider(norm, mGeomIndex); + normals = (LLVector4a*) norm.get(); } if (rebuild_binormal) { - mVertexBuffer->getBinormalStrider(binormals, mGeomIndex); + mVertexBuffer->getBinormalStrider(binorm, mGeomIndex); + binormals = (LLVector4a*) binorm.get(); } if (rebuild_weights) { - mVertexBuffer->getWeight4Strider(weights, mGeomIndex); + mVertexBuffer->getWeight4Strider(wght, mGeomIndex); + weights = (LLVector4a*) wght.get(); } F32 tcoord_xoffset = 0.f ; @@ -1058,8 +1091,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, LLVector2 tmin, tmax; - - if (rebuild_tcoord) { if (tep) @@ -1142,9 +1173,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, //bump setup - LLVector3 binormal_dir( -sin_ang, cos_ang, 0 ); - LLVector3 bump_s_primary_light_ray; - LLVector3 bump_t_primary_light_ray; + LLVector4a binormal_dir( -sin_ang, cos_ang, 0 ); + LLVector4a bump_s_primary_light_ray; + LLVector4a bump_t_primary_light_ray; LLQuaternion bump_quat; if (mDrawablep->isActive()) @@ -1196,8 +1227,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, LLVector3 moon_ray = gSky.getMoonDirection(); LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray; - bump_s_primary_light_ray = offset_multiple * s_scale * primary_light_ray; - bump_t_primary_light_ray = offset_multiple * t_scale * primary_light_ray; + bump_s_primary_light_ray; + bump_s_primary_light_ray.load3((offset_multiple * s_scale * primary_light_ray).mV); + bump_t_primary_light_ray.load3((offset_multiple * t_scale * primary_light_ray).mV); } U8 texgen = getTextureEntry()->getTexGen(); @@ -1206,45 +1238,47 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, mVObjp->getVolume()->genBinormals(f); } + LLMatrix4a mat_normal; + + if (rebuild_normal || rebuild_binormal || rebuild_tcoord) + { + mat_normal.loadu(mat_norm_in); + } + //if it's not fullbright and has no normals, bake sunlight based on face normal bool bake_sunlight = !getTextureEntry()->getFullbright() && !mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL); - //VECTORIZE THIS - for (S32 i = 0; i < num_vertices; i++) + if (rebuild_tcoord) { - LLVector3 vf_binormal; - if (vf.mBinormals) - { - vf_binormal.setVec(vf.mBinormals[i].getF32()); - } + LLVector4a scalea; + scalea.load3(scale.mV); - LLVector3 vf_normal; - vf_normal.set(vf.mNormals[i].getF32()); - LLVector3 vf_position; - vf_position.set(vf.mPositions[i].getF32()); - - if (rebuild_tcoord) - { + for (S32 i = 0; i < num_vertices; i++) + { LLVector2 tc(vf.mTexCoords[i]); + LLVector4a& norm = vf.mNormals[i]; + + LLVector4a& center = *(vf.mCenter); + if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) { - LLVector3 vec = vf_position; + LLVector4a vec = vf.mPositions[i]; - vec.scaleVec(scale); + vec.mul(scalea); switch (texgen) { case LLTextureEntry::TEX_GEN_PLANAR: - planarProjection(tc, vf_normal, vf.mCenter, vec); + planarProjection(tc, norm, center, vec); break; case LLTextureEntry::TEX_GEN_SPHERICAL: - sphericalProjection(tc, vf_normal, vf.mCenter, vec); + sphericalProjection(tc, norm, center, vec); break; case LLTextureEntry::TEX_GEN_CYLINDRICAL: - cylindricalProjection(tc, vf_normal, vf.mCenter, vec); + cylindricalProjection(tc, norm, center, vec); break; default: break; @@ -1351,68 +1385,84 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, *tex_coords++ = tc; - + if (bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)) { - LLVector3 tangent = vf_binormal % vf_normal; - - LLMatrix3 tangent_to_object; - tangent_to_object.setRows(tangent, vf_binormal, vf_normal); - LLVector3 binormal = binormal_dir * tangent_to_object; - binormal = binormal * mat_normal; - + LLVector4a tangent; + tangent.setCross3(vf.mBinormals[i], vf.mNormals[i]); + + LLMatrix4a tangent_to_object; + tangent_to_object.setRows(tangent, vf.mBinormals[i], vf.mNormals[i]); + LLVector4a t; + tangent_to_object.rotate(binormal_dir, t); + LLVector4a binormal; + mat_normal.rotate(t, binormal); + + //VECTORIZE THIS if (mDrawablep->isActive()) { - binormal *= bump_quat; + LLVector3 t; + t.set(binormal.getF32()); + t *= bump_quat; + binormal.load3(t.mV); } - binormal.normVec(); - tc += LLVector2( bump_s_primary_light_ray * tangent, bump_t_primary_light_ray * binormal ); + binormal.normalize3fast(); + tc += LLVector2( bump_s_primary_light_ray.dot3(tangent), bump_t_primary_light_ray.dot3(binormal) ); *tex_coords2++ = tc; } } - - if (rebuild_pos) - { - *vertices++ = vf_position * mat_vert; - } - - if (rebuild_normal) - { - LLVector3 normal = vf_normal * mat_normal; - normal.normVec(); - - *normals++ = normal; + } + + if (rebuild_pos) + { + LLMatrix4a mat_vert; + mat_vert.loadu(mat_vert_in); + + for (S32 i = 0; i < num_vertices; i++) + { + mat_vert.affineTransform(vf.mPositions[i], vertices[i]); } + } - if (rebuild_binormal) - { - LLVector3 binormal = vf_binormal * mat_normal; - binormal.normVec(); - *binormals++ = binormal; + if (rebuild_normal) + { + for (S32 i = 0; i < num_vertices; i++) + { + LLVector4a normal; + mat_normal.rotate(vf.mNormals[i], normal); + normal.normalize3fast(); + normals[i] = normal; } + } - if (rebuild_weights && vf.mWeights.size() > i) - { - (*weights++) = vf.mWeights[i]; + if (rebuild_binormal) + { + for (S32 i = 0; i < num_vertices; i++) + { + LLVector4a binormal; + mat_normal.rotate(vf.mBinormals[i], binormal); + binormal.normalize3fast(); + binormals[i] = binormal; } + } + + if (rebuild_weights && vf.mWeights) + { + LLVector4a::memcpyNonAliased16((F32*) weights, (F32*) vf.mWeights, num_vertices/4); + } - if (rebuild_color) - { - if (bake_sunlight) - { - LLVector3 normal = vf_normal * mat_normal; - normal.normVec(); - - F32 da = normal * gPipeline.mSunDir; + if (rebuild_color) + { + LLVector4a src; - *colors++ = LLColor4U(U8(color.mV[0]*da), U8(color.mV[1]*da), U8(color.mV[2]*da), color.mV[3]); - } - else - { - *colors++ = color; - } + src.splat(reinterpret_cast(color.mAll)); + + F32* dst = (F32*) colors.get(); + for (S32 i = 0; i < num_vertices; i+=4) + { + LLVector4a::copy4a(dst+i, (F32*) &src); } } diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 0648d99685..a5804aa04e 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -574,7 +574,9 @@ void LLPanelPrimMediaControls::updateShape() { const LLVolumeFace& vf = volume->getVolumeFace(mTargetObjectFace); - const LLVector3* ext = vf.mExtents; + LLVector3 ext[2]; + ext[0].set(vf.mExtents[0].getF32()); + ext[1].set(vf.mExtents[1].getF32()); LLVector3 center = (ext[0]+ext[1])*0.5f; LLVector3 size = (ext[1]-ext[0])*0.5f; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 8022f81f19..c03ec67c79 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1602,7 +1602,8 @@ void LLVOVolume::updateFaceSize(S32 idx) else { const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx); - facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices); + facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices, + true); // <--- volume faces should be padded for 16-byte alignment } } -- cgit v1.3 From 0e7f4dc5cef8a97cb1dd08aa2f79538ced267888 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 29 May 2010 05:37:38 -0500 Subject: Octree per LLVolumeFace WIP --- indra/llmath/lloctree.h | 18 + indra/llmath/llvolume.cpp | 625 ++++++++++++++++++++++------- indra/llmath/llvolume.h | 45 ++- indra/newview/llhudicon.cpp | 7 +- indra/newview/llhudtext.cpp | 7 +- indra/newview/llpanelprimmediacontrols.cpp | 1 + indra/newview/llspatialpartition.cpp | 30 ++ indra/newview/llvograss.cpp | 8 +- 8 files changed, 582 insertions(+), 159 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 2f34fb1bb0..8bba12783f 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -72,6 +72,13 @@ public: virtual void visit(const LLOctreeNode* branch) = 0; }; +template +class LLOctreeTravelerDepthFirst : public LLOctreeTraveler +{ +public: + virtual void traverse(const LLOctreeNode* node); +}; + template class LLOctreeNode : public LLTreeNode { @@ -710,4 +717,15 @@ void LLOctreeTraveler::traverse(const LLOctreeNode* node) traverse(node->getChild(i)); } } + +template +void LLOctreeTravelerDepthFirst::traverse(const LLOctreeNode* node) +{ + for (U32 i = 0; i < node->getChildCount(); i++) + { + traverse(node->getChild(i)); + } + node->accept(this); +} + #endif diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 9b6e2488e6..d261811aa2 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -45,6 +45,7 @@ #include "m4math.h" #include "m3math.h" #include "llmatrix4a.h" +#include "lloctree.h" #include "lldarray.h" #include "llvolume.h" #include "llstl.h" @@ -132,6 +133,51 @@ BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* cent return true; } +BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, const LLVector4a& center, const LLVector4a& size) +{ + LLVector4a fAWdU; + LLVector4a dir; + LLVector4a diff; + + dir.setSub(end, start); + dir.mul(0.5f); + + diff.setAdd(end,start); + diff.mul(0.5f); + diff.sub(center); + fAWdU.setAbs(dir); + + LLVector4a rhs; + rhs.setAdd(size, fAWdU); + + LLVector4a lhs; + lhs.setAbs(diff); + + S32 grt = lhs.greaterThan4(rhs).getComparisonMask(); + + if (grt & 0x7) + { + return false; + } + + LLVector4a f; + f.setCross3(dir, diff); + f.setAbs(f); + + LLVector4a v0; v0.mQ = _mm_shuffle_ps(size.mQ, size.mQ, _MM_SHUFFLE(3,1,0,0)); + LLVector4a v1; v1.mQ = _mm_shuffle_ps(fAWdU.mQ, fAWdU.mQ, _MM_SHUFFLE(3,2,2,1)); + lhs.setMul(v0, v1); + + v0.mQ = _mm_shuffle_ps(size.mQ, size.mQ, _MM_SHUFFLE(3,2,2,1)); + v1.mQ = _mm_shuffle_ps(fAWdU.mQ, fAWdU.mQ, _MM_SHUFFLE(3,1,0,0)); + rhs.setMul(v0, v1); + rhs.add(lhs); + + grt = f.greaterThan4(rhs).getComparisonMask(); + + return (grt & 0x7) ? false : true; +} + // intersect test between triangle vert0, vert1, vert2 and a ray from orig in direction dir. // returns TRUE if intersecting and returns barycentric coordinates in intersection_a, intersection_b, @@ -139,15 +185,13 @@ BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* cent // Moller-Trumbore algorithm 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, BOOL two_sided) + F32& intersection_a, F32& intersection_b, F32& intersection_t) { - F32 u, v, t; /* find vectors for two edges sharing vert0 */ LLVector4a edge1; edge1.setSub(vert1, vert0); - LLVector4a edge2; edge2.setSub(vert2, vert0); @@ -156,87 +200,116 @@ BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, co pvec.setCross3(dir, edge2); /* if determinant is near zero, ray lies in plane of triangle */ - F32 det = edge1.dot3(pvec); - - if (!two_sided) + LLVector4a det; + det.setAllDot3(edge1, pvec); + + if (det.greaterEqual4(LLVector4a::getApproximatelyZero()).getComparisonMask()) { - if (det < F_APPROXIMATELY_ZERO) - { - return FALSE; - } - /* calculate distance from vert0 to ray origin */ LLVector4a tvec; tvec.setSub(orig, vert0); /* calculate U parameter and test bounds */ - u = tvec.dot3(pvec); + LLVector4a u; + u.setAllDot3(tvec,pvec); - if (u < 0.f || u > det) + if (u.greaterEqual4(LLVector4a::getZero()).getComparisonMask() && + u.lessEqual4(det).getComparisonMask()) { - return FALSE; + /* prepare to test V parameter */ + LLVector4a qvec; + qvec.setCross3(tvec, edge1); + + /* calculate V parameter and test bounds */ + LLVector4a v; + v.setAllDot3(dir, qvec); + + + //if (!(v < 0.f || u + v > det)) + + LLVector4a sum_uv; + sum_uv.setAdd(u, v); + + S32 v_gequal = v.greaterEqual4(LLVector4a::getZero()).getComparisonMask(); + S32 sum_lequal = sum_uv.lessEqual4(det).getComparisonMask(); + + if (v_gequal && sum_lequal) + { + /* calculate t, scale parameters, ray intersects triangle */ + LLVector4a t; + t.setAllDot3(edge2,qvec); + + t.div(det); + u.div(det); + v.div(det); + + intersection_a = u[0]; + intersection_b = v[0]; + intersection_t = t[0]; + return TRUE; + } } - - /* prepare to test V parameter */ - LLVector4a qvec; - qvec.setCross3(tvec, edge1); + } - /* calculate V parameter and test bounds */ - v = dir.dot3(qvec); - if (v < 0.f || u + v > det) - { - return FALSE; - } + return FALSE; +} - /* calculate t, scale parameters, ray intersects triangle */ - t = edge2.dot3(qvec); - F32 inv_det = 1.0 / det; - t *= inv_det; - u *= inv_det; - v *= inv_det; - } +BOOL LLTriangleRayIntersectTwoSided(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir, + F32& intersection_a, F32& intersection_b, F32& intersection_t) +{ + F32 u, v, t; - else // two sided - { - if (det > -F_APPROXIMATELY_ZERO && det < F_APPROXIMATELY_ZERO) - { - return FALSE; - } - F32 inv_det = 1.0 / det; + /* find vectors for two edges sharing vert0 */ + LLVector4a edge1; + edge1.setSub(vert1, vert0); + + + LLVector4a edge2; + edge2.setSub(vert2, vert0); - /* calculate distance from vert0 to ray origin */ - LLVector4a tvec; - tvec.setSub(orig, vert0); - - /* calculate U parameter and test bounds */ - u = (tvec.dot3(pvec)) * inv_det; - if (u < 0.f || u > 1.f) - { - return FALSE; - } + /* begin calculating determinant - also used to calculate U parameter */ + LLVector4a pvec; + pvec.setCross3(dir, edge2); - /* prepare to test V parameter */ - LLVector4a qvec; - qvec.setSub(tvec, edge1); - - /* calculate V parameter and test bounds */ - v = (dir.dot3(qvec)) * inv_det; - - if (v < 0.f || u + v > 1.f) - { - return FALSE; - } + /* if determinant is near zero, ray lies in plane of triangle */ + F32 det = edge1.dot3(pvec); + + + if (det > -F_APPROXIMATELY_ZERO && det < F_APPROXIMATELY_ZERO) + { + return FALSE; + } + + F32 inv_det = 1.f / det; + + /* calculate distance from vert0 to ray origin */ + LLVector4a tvec; + tvec.setSub(orig, vert0); + + /* calculate U parameter and test bounds */ + u = (tvec.dot3(pvec)) * inv_det; + if (u < 0.f || u > 1.f) + { + return FALSE; + } - /* calculate t, ray intersects triangle */ - t = (edge2.dot3(qvec)) * inv_det; + /* prepare to test V parameter */ + tvec.sub(edge1); + + /* calculate V parameter and test bounds */ + v = (dir.dot3(tvec)) * inv_det; + + if (v < 0.f || u + v > 1.f) + { + return FALSE; } + + /* calculate t, ray intersects triangle */ + t = (edge2.dot3(tvec)) * inv_det; - if (intersection_a != NULL) - *intersection_a = u; - if (intersection_b != NULL) - *intersection_b = v; - if (intersection_t != NULL) - *intersection_t = t; + intersection_a = u; + intersection_b = v; + intersection_t = t; return TRUE; @@ -244,7 +317,7 @@ BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, co //helper for non-aligned vectors 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) + F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided) { LLVector4a vert0a, vert1a, vert2a, origa, dira; vert0a.load3(vert0.mV); @@ -253,11 +326,130 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons origa.load3(orig.mV); dira.load3(dir.mV); - return LLTriangleRayIntersect(vert0a, vert1a, vert2a, origa, dira, - intersection_a, intersection_b, intersection_t, two_sided); + if (two_sided) + { + return LLTriangleRayIntersectTwoSided(vert0a, vert1a, vert2a, origa, dira, + intersection_a, intersection_b, intersection_t); + } + else + { + return LLTriangleRayIntersect(vert0a, vert1a, vert2a, origa, dira, + intersection_a, intersection_b, intersection_t); + } } +class LLVolumeOctreeListener : public LLOctreeListener +{ +public: + + LLVolumeOctreeListener(LLOctreeNode* node) + { + node->addListener(this); + + mBounds = (LLVector4a*) _mm_malloc(sizeof(LLVector4a)*4, 16); + mExtents = mBounds+2; + } + + ~LLVolumeOctreeListener() + { + _mm_free(mBounds); + } + + //LISTENER FUNCTIONS + virtual void handleChildAddition(const LLOctreeNode* parent, + LLOctreeNode* child) + { + new LLVolumeOctreeListener(child); + } + + virtual void handleStateChange(const LLTreeNode* node) { } + virtual void handleChildRemoval(const LLOctreeNode* parent, + const LLOctreeNode* child) { } + virtual void handleInsertion(const LLTreeNode* node, LLVolumeFace::Triangle* tri) { } + virtual void handleRemoval(const LLTreeNode* node, LLVolumeFace::Triangle* tri) { } + virtual void handleDestruction(const LLTreeNode* node) { } + + +public: + LLVector4a* mBounds; // bounding box (center, size) of this node and all its children (tight fit to objects) + LLVector4a* mExtents; // extents (min, max) of this node and all its children +}; + +class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst +{ +public: + const LLVolumeFace* mFace; + + LLVolumeOctreeRebound(const LLVolumeFace* face) + { + mFace = face; + } + + virtual void visit(const LLOctreeNode* branch) + { + LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0); + + LLVector4a& min = node->mExtents[0]; + LLVector4a& max = node->mExtents[1]; + + if (branch->getElementCount() != 0) + { + const LLVolumeFace::Triangle* tri = *(branch->getData().begin()); + + min = *(tri->mV[0]); + max = *(tri->mV[0]); + + for (LLOctreeNode::const_element_iter iter = + branch->getData().begin(); iter != branch->getData().end(); ++iter) + { + //stretch by triangles in node + tri = *iter; + + min.setMin(*tri->mV[0]); + min.setMin(*tri->mV[1]); + min.setMin(*tri->mV[2]); + + max.setMax(*tri->mV[0]); + max.setMax(*tri->mV[1]); + max.setMax(*tri->mV[2]); + } + + for (S32 i = 0; i < branch->getChildCount(); ++i) + { //stretch by child extents + LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(i)->getListener(0); + min.setMin(child->mExtents[0]); + max.setMax(child->mExtents[1]); + } + } + else if (branch->getChildCount() != 0) + { + LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(0)->getListener(0); + + min = child->mExtents[0]; + max = child->mExtents[1]; + + for (S32 i = 1; i < branch->getChildCount(); ++i) + { //stretch by child extents + child = (LLVolumeOctreeListener*) branch->getChild(i)->getListener(0); + min.setMin(child->mExtents[0]); + max.setMax(child->mExtents[1]); + } + } + else + { + llerrs << "WTF? Empty leaf" << llendl; + } + + node->mBounds[0].setAdd(min, max); + node->mBounds[0].mul(0.5f); + + node->mBounds[1].setSub(max,min); + node->mBounds[1].mul(0.5f); + } +}; + + //------------------------------------------------------------------- // statics //------------------------------------------------------------------- @@ -4244,6 +4436,114 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, } +class LLOctreeTriangleRayIntersect : public LLOctreeTraveler +{ +public: + const LLVolumeFace* mFace; + LLVector4a mStart; + LLVector4a mDir; + LLVector4a mEnd; + LLVector3* mIntersection; + LLVector2* mTexCoord; + LLVector3* mNormal; + LLVector3* mBinormal; + 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) + : mFace(face), + mStart(start), + mDir(dir), + mIntersection(intersection), + mTexCoord(tex_coord), + mNormal(normal), + mBinormal(bi_normal), + mClosestT(closest_t), + mHitFace(false) + { + mEnd.setAdd(mStart, mDir); + } + + void traverse(const LLOctreeNode* node) + { + 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])) + { + node->accept(this); + for (S32 i = 0; i < node->getChildCount(); ++i) + { + traverse(node->getChild(i)); + } + } + } + + void visit(const LLOctreeNode* node) + { + for (LLOctreeNode::const_element_iter iter = + node->getData().begin(); iter != node->getData().end(); ++iter) + { + const LLVolumeFace::Triangle* tri = *iter; + + F32 a, b, t; + + if (LLTriangleRayIntersect(*tri->mV[0], *tri->mV[1], *tri->mV[2], + mStart, mDir, a, b, t)) + { + if ((t >= 0.f) && // if hit is after start + (t <= 1.f) && // and before end + (t < *mClosestT)) // and this hit is closer + { + *mClosestT = t; + mHitFace = true; + + if (mIntersection != NULL) + { + LLVector4a intersect = mDir; + intersect.mul(*mClosestT); + intersect.add(mStart); + mIntersection->set(intersect.getF32()); + } + + + 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]]); + + } + + 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]])); + } + + if (mBinormal != 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]])); + } + } + } + } + } +}; + S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) @@ -4288,66 +4588,19 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en { genBinormals(i); } - - LLVector4a* p = (LLVector4a*) face.mPositions; - for (U32 tri = 0; tri < face.mNumIndices/3; tri++) + if (!face.mOctree) { - S32 index1 = face.mIndices[tri*3+0]; - S32 index2 = face.mIndices[tri*3+1]; - S32 index3 = face.mIndices[tri*3+2]; - - F32 a, b, t; + face.createOctree(); + } - if (LLTriangleRayIntersect(p[index1], - p[index2], - p[index3], - start, dir, &a, &b, &t, FALSE)) - { - if ((t >= 0.f) && // if hit is after start - (t <= 1.f) && // and before end - (t < closest_t)) // and this hit is closer - { - closest_t = t; - hit_face = i; - - if (intersection != NULL) - { - LLVector4a intersect = dir; - intersect.mul(closest_t); - intersect.add(start); - intersection->set(intersect.getF32()); - } - - - if (tex_coord != NULL) - { - LLVector2* tc = (LLVector2*) face.mTexCoords; - *tex_coord = ((1.f - a - b) * tc[index1] + - a * tc[index2] + - b * tc[index3]); - - } - - if (normal != NULL) - { - LLVector4* norm = (LLVector4*) face.mNormals; - - *normal = ((1.f - a - b) * LLVector3(norm[index1]) + - a * LLVector3(norm[index2]) + - b * LLVector3(norm[index3])); - } - - if (bi_normal != NULL) - { - LLVector4* binormal = (LLVector4*) face.mBinormals; - *bi_normal = ((1.f - a - b) * LLVector3(binormal[index1]) + - a * LLVector3(binormal[index2]) + - b * LLVector3(binormal[index3])); - } + LLVector4a* p = (LLVector4a*) face.mPositions; - } - } + LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, bi_normal); + intersect.traverse(face.mOctree); + if (intersect.mHitFace) + { + hit_face = i; } } } @@ -5128,13 +5381,29 @@ LLVolumeFace::LLVolumeFace() : mBinormals(NULL), mTexCoords(NULL), mIndices(NULL), - mWeights(NULL) + mWeights(NULL), + mOctree(NULL) { mExtents = (LLVector4a*) _mm_malloc(48, 16); mCenter = mExtents+2; } LLVolumeFace::LLVolumeFace(const LLVolumeFace& src) +: mID(0), + mTypeMask(0), + mBeginS(0), + mBeginT(0), + mNumS(0), + mNumT(0), + mNumVertices(0), + mNumIndices(0), + mPositions(NULL), + mNormals(NULL), + mBinormals(NULL), + mTexCoords(NULL), + mIndices(NULL), + mWeights(NULL), + mOctree(NULL) { mExtents = (LLVector4a*) _mm_malloc(48, 16); mCenter = mExtents+2; @@ -5157,13 +5426,9 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) mNumVertices = 0; mNumIndices = 0; - mPositions = NULL; - mNormals = NULL; - mBinormals = NULL; - mTexCoords = NULL; - mWeights = NULL; - mIndices = NULL; + freeData(); + LLVector4a::memcpyNonAliased16((F32*) mExtents, (F32*) src.mExtents, 12); resizeVertices(src.mNumVertices); @@ -5179,6 +5444,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) src.mNormals, vert_size); LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, vert_size); + if (src.mBinormals) { allocateBinormals(src.mNumVertices); @@ -5216,18 +5482,38 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) } LLVolumeFace::~LLVolumeFace() +{ + _mm_free(mExtents); + mExtents = NULL; + + freeData(); +} + +void LLVolumeFace::freeData() { _mm_free(mPositions); + mPositions = NULL; _mm_free(mNormals); + mNormals = NULL; _mm_free(mTexCoords); + mTexCoords = NULL; _mm_free(mIndices); + mIndices = NULL; _mm_free(mBinormals); + mBinormals = NULL; _mm_free(mWeights); - _mm_free(mExtents); + mWeights = NULL; + + delete mOctree; + mOctree = NULL; } BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) { + //tree for this face is no longer valid + delete mOctree; + mOctree = NULL; + if (mTypeMask & CAP_MASK) { return createCap(volume, partial_build); @@ -5250,6 +5536,18 @@ void LLVolumeFace::getVertexData(U16 index, LLVolumeFace::VertexData& cv) cv.mTexCoord = mTexCoords[index]; } +bool LLVolumeFace::VertexMapData::operator==(const LLVolumeFace::VertexData& rhs) const +{ + return getPosition().equal3(rhs.getPosition()) && + mTexCoord == rhs.mTexCoord && + getNormal().equal3(rhs.getNormal()); +} + +bool LLVolumeFace::VertexMapData::ComparePosition::operator()(const LLVector4a& a, const LLVector4a& b) const +{ + return a.less3(b); +} + void LLVolumeFace::optimize(F32 angle_cutoff) { LLVolumeFace new_face; @@ -5305,6 +5603,65 @@ void LLVolumeFace::optimize(F32 angle_cutoff) swapData(new_face); } + +void LLVolumeFace::createOctree() +{ + mOctree = new LLOctreeRoot(LLVector3d(0,0,0), LLVector3d(1,1,1), NULL); + new LLVolumeOctreeListener(mOctree); + + for (U32 i = 0; i < mNumIndices; i+= 3) + { + Triangle* tri = new Triangle(); + + const LLVector4a& v0 = mPositions[mIndices[i]]; + const LLVector4a& v1 = mPositions[mIndices[i+1]]; + const LLVector4a& v2 = mPositions[mIndices[i+2]]; + + tri->mV[0] = &v0; + tri->mV[1] = &v1; + tri->mV[2] = &v2; + + tri->mIndex[0] = mIndices[i]; + tri->mIndex[1] = mIndices[i+1]; + tri->mIndex[2] = mIndices[i+2]; + + LLVector4a min = v0; + min.setMin(v1); + min.setMin(v2); + + LLVector4a max = v0; + max.setMax(v1); + max.setMax(v2); + + LLVector4a center; + center.setAdd(min, max); + center.mul(0.5f); + + + tri->mPositionGroup.setVec(center[0], center[1], center[2]); + + LLVector4a size; + size.setSub(max,min); + + tri->mRadius = size.length3() * 0.5f; + + mOctree->insert(tri); + } + + LLVolumeOctreeRebound rebound(this); + rebound.traverse(mOctree); +} + +const LLVector3d& LLVolumeFace::Triangle::getPositionGroup() const +{ + return mPositionGroup; +} + +const F64& LLVolumeFace::Triangle::getBinRadius() const +{ + return mRadius; +} + void LLVolumeFace::swapData(LLVolumeFace& rhs) { llswap(rhs.mPositions, mPositions); diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 7c63266aab..a40a21b405 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -40,6 +40,9 @@ class LLPathParams; class LLVolumeParams; class LLProfile; class LLPath; + +template class LLOctreeNode; +class LLVector4a; class LLVolumeFace; class LLVolume; @@ -49,15 +52,14 @@ class LLVolume; //#include "vmath.h" #include "v2math.h" #include "v3math.h" +#include "v3dmath.h" #include "v4math.h" -#include "llvector4a.h" #include "llquaternion.h" #include "llstrider.h" #include "v4coloru.h" #include "llrefcount.h" #include "llfile.h" - //============================================================================ const S32 MIN_DETAIL_FACES = 6; @@ -830,6 +832,9 @@ public: LLVolumeFace& operator=(const LLVolumeFace& rhs); ~LLVolumeFace(); +private: + void freeData(); +public: BOOL create(LLVolume* volume, BOOL partial_build = FALSE); void createBinormals(); @@ -855,26 +860,19 @@ public: public: U16 mIndex; - bool operator==(const LLVolumeFace::VertexData& rhs) const - { - return getPosition().equal3(rhs.getPosition()) && - mTexCoord == rhs.mTexCoord && - getNormal().equal3(rhs.getNormal()); - } + bool operator==(const LLVolumeFace::VertexData& rhs) const; struct ComparePosition { - bool operator()(const LLVector4a& a, const LLVector4a& b) const - { - return a.less3(b); - } + bool operator()(const LLVector4a& a, const LLVector4a& b) const; }; typedef std::map, VertexMapData::ComparePosition > PointMap; }; void optimize(F32 angle_cutoff = 2.f); - + void createOctree(); + enum { SINGLE_MASK = 0x0001, @@ -919,6 +917,21 @@ public: // mWeights.size() should be empty or match mVertices.size() LLVector4a* mWeights; + class Triangle : public LLRefCount + { + public: + const LLVector4a* mV[3]; + U16 mIndex[3]; + + LLVector3d mPositionGroup; + F64 mRadius; + + virtual const LLVector3d& getPositionGroup() const; + virtual const F64& getBinRadius() const; + }; + + LLOctreeNode* mOctree; + private: BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE); BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE); @@ -1084,10 +1097,12 @@ BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* cent BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& 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); + 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, BOOL two_sided); + F32& intersection_a, F32& intersection_b, F32& intersection_t); +BOOL LLTriangleRayIntersectTwoSided(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/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp index 3c5a4de7f8..63040904df 100644 --- a/indra/newview/llhudicon.cpp +++ b/indra/newview/llhudicon.cpp @@ -286,7 +286,6 @@ BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& en LLVector4a upper_right; upper_right.setAdd(lower_right, y_scalea); - F32 t = 0.f; LLVector4a enda; enda.load3(end.mV); LLVector4a starta; @@ -294,8 +293,10 @@ BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& en LLVector4a dir; dir.setSub(enda, starta); - if (LLTriangleRayIntersect(upper_right, upper_left, lower_right, starta, dir, NULL, NULL, &t, FALSE) || - LLTriangleRayIntersect(upper_left, lower_left, lower_right, starta, dir, NULL, NULL, &t, FALSE)) + 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 (intersection) { diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index 9ed5d13831..7f9eddc837 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -207,10 +207,11 @@ BOOL LLHUDText::lineSegmentIntersect(const LLVector3& start, const LLVector3& en } LLVector3 dir = end-start; - F32 t = 0.f; + F32 a,b,t; - if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, NULL, NULL, &t, FALSE) || - LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, NULL, NULL, &t, FALSE) ) + + 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) ) { if (t <= 1.f) { diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index a5804aa04e..98fbebbc5d 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -65,6 +65,7 @@ #include "llweb.h" #include "llwindow.h" #include "llfloatertools.h" // to enable hide if build tools are up +#include "llvector4a.h" // Functions pulled from pipeline.cpp glh::matrix4f glh_get_current_modelview(); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 470c332b42..60e704d360 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -2769,6 +2769,19 @@ void renderLights(LLDrawable* drawablep) } } +class LLRenderOctree : public LLOctreeTraveler +{ +public: + void visit(const LLOctreeNode* branch) + { + const LLVector3d& c = branch->getCenter(); + const LLVector3d& s = branch->getSize(); + + LLVector3 pos((F32) c.mdV[0], (F32) c.mdV[1], (F32) c.mdV[2]); + LLVector3 size((F32) s.mdV[0], (F32) s.mdV[1], (F32) s.mdV[2]); + drawBoxOutline(pos, size); + } +}; void renderRaycast(LLDrawable* drawablep) { @@ -2787,6 +2800,23 @@ void renderRaycast(LLDrawable* drawablep) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); pushVerts(drawablep->getFace(gDebugRaycastFaceHit), LLVertexBuffer::MAP_VERTEX); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + LLVOVolume* vobj = drawablep->getVOVolume(); + LLVolume* volume = vobj->getVolume(); + if (volume && volume->getNumVolumeFaces() > gDebugRaycastFaceHit) + { + const LLVolumeFace& face = volume->getVolumeFace(gDebugRaycastFaceHit); + if (!face.mOctree) + { + ((LLVolumeFace*) &face)->createOctree(); + } + + gGL.pushMatrix(); + glMultMatrixf((F32*) vobj->getRelativeXform().mMatrix); + LLRenderOctree render; + render.traverse(face.mOctree); + gGL.popMatrix(); + } } else if (drawablep->isAvatar()) { diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index 91c9b762c5..fe1e36cbe8 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -647,23 +647,23 @@ 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)) + if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE)) { 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(v[1], v[3], v[2], start, dir, a, b, t, FALSE)) { 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(v[2], v[1], v[0], start, dir, a, b, t, FALSE)) { 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(v[2], v[3], v[1], start, dir, a, b, t, FALSE)) { normal1 = -normal1; hit = TRUE; -- cgit v1.3 From 9a869d630162292864e01fdd1707efc609fbd6b4 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 29 May 2010 19:55:13 -0500 Subject: Octree triven raycast works, time to profile. --- indra/llmath/CMakeLists.txt | 2 + indra/llmath/lltreenode.h | 3 + indra/llmath/llvolume.cpp | 202 ++--------------------------------- indra/llmath/llvolume.h | 2 + indra/newview/llspatialpartition.cpp | 28 +++-- indra/newview/llviewerwindow.cpp | 21 +++- indra/newview/llviewerwindow.h | 6 +- 7 files changed, 58 insertions(+), 206 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index 367486eee7..dda07133d5 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -22,6 +22,7 @@ set(llmath_SOURCE_FILES llsphere.cpp llvolume.cpp llvolumemgr.cpp + llvolumeoctree.cpp llsdutil_math.cpp m3math.cpp m4math.cpp @@ -66,6 +67,7 @@ set(llmath_HEADER_FILES llmatrix4a.h llvolume.h llvolumemgr.h + llvolumeoctree.h llsdutil_math.h m3math.h m4math.h diff --git a/indra/llmath/lltreenode.h b/indra/llmath/lltreenode.h index ee9836241a..e6d2521b2a 100644 --- a/indra/llmath/lltreenode.h +++ b/indra/llmath/lltreenode.h @@ -34,6 +34,9 @@ #include "stdtypes.h" #include "xform.h" +#include "llpointer.h" +#include "llrefcount.h" + #include template class LLTreeNode; diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index d261811aa2..c4172de651 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -48,6 +48,7 @@ #include "lloctree.h" #include "lldarray.h" #include "llvolume.h" +#include "llvolumeoctree.h" #include "llstl.h" #include "llsdserialize.h" #include "llvector4a.h" @@ -133,50 +134,6 @@ BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* cent return true; } -BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, const LLVector4a& center, const LLVector4a& size) -{ - LLVector4a fAWdU; - LLVector4a dir; - LLVector4a diff; - - dir.setSub(end, start); - dir.mul(0.5f); - - diff.setAdd(end,start); - diff.mul(0.5f); - diff.sub(center); - fAWdU.setAbs(dir); - - LLVector4a rhs; - rhs.setAdd(size, fAWdU); - - LLVector4a lhs; - lhs.setAbs(diff); - - S32 grt = lhs.greaterThan4(rhs).getComparisonMask(); - - if (grt & 0x7) - { - return false; - } - - LLVector4a f; - f.setCross3(dir, diff); - f.setAbs(f); - - LLVector4a v0; v0.mQ = _mm_shuffle_ps(size.mQ, size.mQ, _MM_SHUFFLE(3,1,0,0)); - LLVector4a v1; v1.mQ = _mm_shuffle_ps(fAWdU.mQ, fAWdU.mQ, _MM_SHUFFLE(3,2,2,1)); - lhs.setMul(v0, v1); - - v0.mQ = _mm_shuffle_ps(size.mQ, size.mQ, _MM_SHUFFLE(3,2,2,1)); - v1.mQ = _mm_shuffle_ps(fAWdU.mQ, fAWdU.mQ, _MM_SHUFFLE(3,1,0,0)); - rhs.setMul(v0, v1); - rhs.add(lhs); - - grt = f.greaterThan4(rhs).getComparisonMask(); - - return (grt & 0x7) ? false : true; -} // intersect test between triangle vert0, vert1, vert2 and a ray from orig in direction dir. @@ -203,7 +160,7 @@ BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, co LLVector4a det; det.setAllDot3(edge1, pvec); - if (det.greaterEqual4(LLVector4a::getApproximatelyZero()).getComparisonMask()) + if (det.greaterEqual4(LLVector4a::getApproximatelyZero()).getComparisonMask() & 0x7) { /* calculate distance from vert0 to ray origin */ LLVector4a tvec; @@ -213,8 +170,8 @@ BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, co LLVector4a u; u.setAllDot3(tvec,pvec); - if (u.greaterEqual4(LLVector4a::getZero()).getComparisonMask() && - u.lessEqual4(det).getComparisonMask()) + if ((u.greaterEqual4(LLVector4a::getZero()).getComparisonMask() & 0x7) && + (u.lessEqual4(det).getComparisonMask() & 0x7)) { /* prepare to test V parameter */ LLVector4a qvec; @@ -230,10 +187,10 @@ BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, co LLVector4a sum_uv; sum_uv.setAdd(u, v); - S32 v_gequal = v.greaterEqual4(LLVector4a::getZero()).getComparisonMask(); - S32 sum_lequal = sum_uv.lessEqual4(det).getComparisonMask(); + S32 v_gequal = v.greaterEqual4(LLVector4a::getZero()).getComparisonMask() & 0x7; + S32 sum_lequal = sum_uv.lessEqual4(det).getComparisonMask() & 0x7; - if (v_gequal && sum_lequal) + if (v_gequal && sum_lequal) { /* calculate t, scale parameters, ray intersects triangle */ LLVector4a t; @@ -338,44 +295,6 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons } } - -class LLVolumeOctreeListener : public LLOctreeListener -{ -public: - - LLVolumeOctreeListener(LLOctreeNode* node) - { - node->addListener(this); - - mBounds = (LLVector4a*) _mm_malloc(sizeof(LLVector4a)*4, 16); - mExtents = mBounds+2; - } - - ~LLVolumeOctreeListener() - { - _mm_free(mBounds); - } - - //LISTENER FUNCTIONS - virtual void handleChildAddition(const LLOctreeNode* parent, - LLOctreeNode* child) - { - new LLVolumeOctreeListener(child); - } - - virtual void handleStateChange(const LLTreeNode* node) { } - virtual void handleChildRemoval(const LLOctreeNode* parent, - const LLOctreeNode* child) { } - virtual void handleInsertion(const LLTreeNode* node, LLVolumeFace::Triangle* tri) { } - virtual void handleRemoval(const LLTreeNode* node, LLVolumeFace::Triangle* tri) { } - virtual void handleDestruction(const LLTreeNode* node) { } - - -public: - LLVector4a* mBounds; // bounding box (center, size) of this node and all its children (tight fit to objects) - LLVector4a* mExtents; // extents (min, max) of this node and all its children -}; - class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst { public: @@ -4436,113 +4355,6 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, } -class LLOctreeTriangleRayIntersect : public LLOctreeTraveler -{ -public: - const LLVolumeFace* mFace; - LLVector4a mStart; - LLVector4a mDir; - LLVector4a mEnd; - LLVector3* mIntersection; - LLVector2* mTexCoord; - LLVector3* mNormal; - LLVector3* mBinormal; - 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) - : mFace(face), - mStart(start), - mDir(dir), - mIntersection(intersection), - mTexCoord(tex_coord), - mNormal(normal), - mBinormal(bi_normal), - mClosestT(closest_t), - mHitFace(false) - { - mEnd.setAdd(mStart, mDir); - } - - void traverse(const LLOctreeNode* node) - { - 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])) - { - node->accept(this); - for (S32 i = 0; i < node->getChildCount(); ++i) - { - traverse(node->getChild(i)); - } - } - } - - void visit(const LLOctreeNode* node) - { - for (LLOctreeNode::const_element_iter iter = - node->getData().begin(); iter != node->getData().end(); ++iter) - { - const LLVolumeFace::Triangle* tri = *iter; - - F32 a, b, t; - - if (LLTriangleRayIntersect(*tri->mV[0], *tri->mV[1], *tri->mV[2], - mStart, mDir, a, b, t)) - { - if ((t >= 0.f) && // if hit is after start - (t <= 1.f) && // and before end - (t < *mClosestT)) // and this hit is closer - { - *mClosestT = t; - mHitFace = true; - - if (mIntersection != NULL) - { - LLVector4a intersect = mDir; - intersect.mul(*mClosestT); - intersect.add(mStart); - mIntersection->set(intersect.getF32()); - } - - - 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]]); - - } - - 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]])); - } - - if (mBinormal != 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]])); - } - } - } - } - } -}; S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index a40a21b405..0ae8aa19ca 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -42,6 +42,7 @@ class LLProfile; class LLPath; template class LLOctreeNode; + class LLVector4a; class LLVolumeFace; class LLVolume; @@ -1095,6 +1096,7 @@ void calc_binormal_from_triangle( 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); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 60e704d360..355173772b 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -38,6 +38,7 @@ #include "llviewerobjectlist.h" #include "llvovolume.h" #include "llvolume.h" +#include "llvolumeoctree.h" #include "llviewercamera.h" #include "llface.h" #include "llviewercontrol.h" @@ -2769,17 +2770,26 @@ void renderLights(LLDrawable* drawablep) } } -class LLRenderOctree : public LLOctreeTraveler +class LLRenderOctreeRaycast : public LLOctreeTriangleRayIntersect { public: + + LLRenderOctreeRaycast(const LLVector3& start, const LLVector3& end) + { + mStart.load3(start.mV); + mEnd.load3(end.mV); + mDir.setSub(mEnd, mStart); + } + void visit(const LLOctreeNode* branch) { - const LLVector3d& c = branch->getCenter(); - const LLVector3d& s = branch->getSize(); + LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) branch->getListener(0); - LLVector3 pos((F32) c.mdV[0], (F32) c.mdV[1], (F32) c.mdV[2]); - LLVector3 size((F32) s.mdV[0], (F32) s.mdV[1], (F32) s.mdV[2]); - drawBoxOutline(pos, size); + LLVector3 center, size; + center.set(vl->mBounds[0].getF32()); + size.set(vl->mBounds[1].getF32()); + + drawBoxOutline(center, size); } }; @@ -2813,7 +2823,11 @@ void renderRaycast(LLDrawable* drawablep) gGL.pushMatrix(); glMultMatrixf((F32*) vobj->getRelativeXform().mMatrix); - LLRenderOctree render; + LLVector3 start, end; + start = vobj->agentPositionToVolume(gDebugRaycastStart); + end = vobj->agentPositionToVolume(gDebugRaycastEnd); + + LLRenderOctreeRaycast render(start, end); render.traverse(face.mOctree); gGL.popMatrix(); } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 2422995288..0564f02ce5 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -231,6 +231,8 @@ LLVector2 gDebugRaycastTexCoord; LLVector3 gDebugRaycastNormal; LLVector3 gDebugRaycastBinormal; S32 gDebugRaycastFaceHit; +LLVector3 gDebugRaycastStart; +LLVector3 gDebugRaycastEnd; // HUD display lines in lower right BOOL gDisplayWindInfo = FALSE; @@ -2529,7 +2531,9 @@ void LLViewerWindow::updateUI() &gDebugRaycastIntersection, &gDebugRaycastTexCoord, &gDebugRaycastNormal, - &gDebugRaycastBinormal); + &gDebugRaycastBinormal, + &gDebugRaycastStart, + &gDebugRaycastEnd); } updateMouseDelta(); @@ -3445,7 +3449,9 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de LLVector3 *intersection, LLVector2 *uv, LLVector3 *normal, - LLVector3 *binormal) + LLVector3 *binormal, + LLVector3* start, + LLVector3* end) { S32 x = mouse_x; S32 y = mouse_y; @@ -3477,7 +3483,16 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de LLVector3 mouse_world_start = mouse_point_global; LLVector3 mouse_world_end = mouse_point_global + mouse_direction_global * depth; - + if (start) + { + *start = mouse_world_start; + } + + if (end) + { + *end = mouse_world_end; + } + LLViewerObject* found = NULL; if (this_object) // check only this object diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 410445d97f..156a1ff8ad 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -361,7 +361,9 @@ public: LLVector3 *intersection = NULL, LLVector2 *uv = NULL, LLVector3 *normal = NULL, - LLVector3 *binormal = NULL); + LLVector3 *binormal = NULL, + LLVector3* start = NULL, + LLVector3* end = NULL); // Returns a pointer to the last object hit @@ -507,6 +509,8 @@ extern LLVector2 gDebugRaycastTexCoord; extern LLVector3 gDebugRaycastNormal; extern LLVector3 gDebugRaycastBinormal; extern S32 gDebugRaycastFaceHit; +extern LLVector3 gDebugRaycastStart; +extern LLVector3 gDebugRaycastEnd; extern S32 CHAT_BAR_HEIGHT; -- cgit v1.3 From 26ba00b5554d20ee958693ced87b36fa7f6e3d99 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 3 Jun 2010 12:52:28 -0500 Subject: Vectorized octree and much of llspatialpartition and lldrawable. Octree driven raycast. --- indra/llmath/llcamera.cpp | 216 ++++++--------- indra/llmath/llcamera.h | 29 +- indra/llmath/lloctree.h | 239 ++++++++-------- indra/llmath/llvolume.cpp | 31 +-- indra/llmath/llvolume.h | 16 +- indra/llrender/llvertexbuffer.h | 11 + indra/llui/lllineeditor.cpp | 9 +- indra/newview/lldrawable.cpp | 163 ++++++----- indra/newview/lldrawable.h | 34 ++- indra/newview/llface.cpp | 164 +++++++---- indra/newview/llface.h | 15 +- indra/newview/llflexibleobject.cpp | 6 +- indra/newview/llflexibleobject.h | 2 +- indra/newview/llselectmgr.cpp | 16 +- indra/newview/llspatialpartition.cpp | 520 ++++++++++++++++++++++------------- indra/newview/llspatialpartition.h | 80 ++++-- indra/newview/llsurfacepatch.cpp | 6 +- indra/newview/llviewerdisplay.cpp | 7 +- indra/newview/llviewerobject.cpp | 40 ++- indra/newview/llviewerobject.h | 4 +- indra/newview/llviewerpartsim.cpp | 4 +- indra/newview/llvoavatar.cpp | 100 ++++--- indra/newview/llvoavatar.h | 10 +- indra/newview/llvopartgroup.cpp | 10 +- indra/newview/llvopartgroup.h | 2 +- indra/newview/llvosurfacepatch.cpp | 19 +- indra/newview/llvosurfacepatch.h | 2 +- indra/newview/llvotree.cpp | 17 +- indra/newview/llvotree.h | 2 +- indra/newview/llvovolume.cpp | 35 +-- indra/newview/llvovolume.h | 6 +- indra/newview/llvowater.cpp | 20 +- indra/newview/llvowater.h | 2 +- indra/newview/pipeline.cpp | 257 +++++++++++++++-- indra/newview/pipeline.h | 9 + 35 files changed, 1333 insertions(+), 770 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp index 487ed6451f..6b56e4870e 100644 --- a/indra/llmath/llcamera.cpp +++ b/indra/llmath/llcamera.cpp @@ -48,10 +48,10 @@ LLCamera::LLCamera() : mPlaneCount(6), mFrustumCornerDist(0.f) { + alignPlanes(); calculateFrustumPlanes(); } - LLCamera::LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane) : LLCoordFrame(), mViewHeightInPixels(view_height_in_pixels), @@ -59,6 +59,7 @@ LLCamera::LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_p mPlaneCount(6), mFrustumCornerDist(0.f) { + alignPlanes(); mAspect = llclamp(aspect_ratio, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO); mNearPlane = llclamp(near_plane, MIN_NEAR_PLANE, MAX_NEAR_PLANE); if(far_plane < 0) far_plane = DEFAULT_FAR_PLANE; @@ -67,6 +68,23 @@ LLCamera::LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_p setView(vertical_fov_rads); } +LLCamera::~LLCamera() +{ + +} + +const LLCamera& LLCamera::operator=(const LLCamera& rhs) +{ + memcpy(this, &rhs, sizeof(LLCamera)); + alignPlanes(); + LLVector4a::memcpyNonAliased16((F32*) mAgentPlanes, (F32*) rhs.mAgentPlanes, 4*7); + return *this; +} + +void LLCamera::alignPlanes() +{ + mAgentPlanes = (LLPlane*) LL_NEXT_ALIGNED_ADDRESS(mAgentPlaneBuffer); +} // ---------------- LLCamera::getFoo() member functions ---------------- @@ -91,8 +109,8 @@ F32 LLCamera::getMaxView() const void LLCamera::setUserClipPlane(LLPlane plane) { mPlaneCount = 7; - mAgentPlanes[6].p = plane; - mAgentPlanes[6].mask = calcPlaneMask(plane); + mAgentPlanes[6] = plane; + mPlaneMask[6] = calcPlaneMask(plane); } void LLCamera::disableUserClipPlane() @@ -164,129 +182,66 @@ size_t LLCamera::readFrustumFromBuffer(const char *buffer) // ---------------- test methods ---------------- -S32 LLCamera::AABBInFrustum(const LLVector3 ¢er, const LLVector3& radius) -{ - static const LLVector3 scaler[] = { - LLVector3(-1,-1,-1), - LLVector3( 1,-1,-1), - LLVector3(-1, 1,-1), - LLVector3( 1, 1,-1), - LLVector3(-1,-1, 1), - LLVector3( 1,-1, 1), - LLVector3(-1, 1, 1), - LLVector3( 1, 1, 1) +S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius) +{ + static const LLVector4a scaler[] = { + LLVector4a(-1,-1,-1), + LLVector4a( 1,-1,-1), + LLVector4a(-1, 1,-1), + LLVector4a( 1, 1,-1), + LLVector4a(-1,-1, 1), + LLVector4a( 1,-1, 1), + LLVector4a(-1, 1, 1), + LLVector4a( 1, 1, 1) }; U8 mask = 0; S32 result = 2; - /*if (mFrustumCornerDist > 0.f && radius.magVecSquared() > mFrustumCornerDist * mFrustumCornerDist) - { //box is larger than frustum, check frustum quads against box planes - - static const LLVector3 dir[] = - { - LLVector3(1, 0, 0), - LLVector3(-1, 0, 0), - LLVector3(0, 1, 0), - LLVector3(0, -1, 0), - LLVector3(0, 0, 1), - LLVector3(0, 0, -1) - }; - - U32 quads[] = + for (U32 i = 0; i < mPlaneCount; i++) + { + mask = mPlaneMask[i]; + if (mask == 0xff) { - 0, 1, 2, 3, - 0, 1, 5, 4, - 2, 3, 7, 6, - 3, 0, 7, 4, - 1, 2, 6, 4, - 4, 5, 6, 7 - }; - - result = 0; - - BOOL total_inside = TRUE; - for (U32 i = 0; i < 6; i++) - { - LLVector3 p = center + radius.scaledVec(dir[i]); - F32 d = -p*dir[i]; - - for (U32 j = 0; j < 6; j++) - { //for each quad - F32 dist = mAgentFrustum[quads[j*4+0]]*dir[i] + d; - if (dist > 0) - { //at least one frustum point is outside the AABB - total_inside = FALSE; - for (U32 k = 1; k < 4; k++) - { //for each other point on quad - if ( mAgentFrustum[quads[j*4+k]]*dir[i]+d <= 0.f) - { //quad is straddling some plane of AABB - return 1; - } - } - } - else - { - for (U32 k = 1; k < 4; k++) - { - if (mAgentFrustum[quads[j*4+k]]*dir[i]+d > 0.f) - { - return 1; - } - } - } - } + continue; } - if (total_inside) + const LLPlane& p = mAgentPlanes[i]; + const LLVector4a& n = reinterpret_cast(p); + float d = p.mV[3]; + LLVector4a rscale; + rscale.setMul(radius, scaler[mask]); + + LLVector4a minp, maxp; + minp.setSub(center, rscale); + maxp.setAdd(center, rscale); + + if (n.dot3(minp) > -d) { - result = 1; + return 0; } - } - else*/ - { - for (U32 i = 0; i < mPlaneCount; i++) + + if (n.dot3(maxp) > -d) { - mask = mAgentPlanes[i].mask; - if (mask == 0xff) - { - continue; - } - LLPlane p = mAgentPlanes[i].p; - LLVector3 n = LLVector3(p); - float d = p.mV[3]; - LLVector3 rscale = radius.scaledVec(scaler[mask]); - - LLVector3 minp = center - rscale; - LLVector3 maxp = center + rscale; - - if (n * minp > -d) - { - return 0; - } - - if (n * maxp > -d) - { - result = 1; - } + result = 1; } } - return result; } -S32 LLCamera::AABBInFrustumNoFarClip(const LLVector3 ¢er, const LLVector3& radius) -{ - static const LLVector3 scaler[] = { - LLVector3(-1,-1,-1), - LLVector3( 1,-1,-1), - LLVector3(-1, 1,-1), - LLVector3( 1, 1,-1), - LLVector3(-1,-1, 1), - LLVector3( 1,-1, 1), - LLVector3(-1, 1, 1), - LLVector3( 1, 1, 1) + +S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius) +{ + static const LLVector4a scaler[] = { + LLVector4a(-1,-1,-1), + LLVector4a( 1,-1,-1), + LLVector4a(-1, 1,-1), + LLVector4a( 1, 1,-1), + LLVector4a(-1,-1, 1), + LLVector4a( 1,-1, 1), + LLVector4a(-1, 1, 1), + LLVector4a( 1, 1, 1) }; U8 mask = 0; @@ -299,25 +254,28 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector3 ¢er, const LLVector3& r continue; } - mask = mAgentPlanes[i].mask; + mask = mPlaneMask[i]; if (mask == 0xff) { continue; } - LLPlane p = mAgentPlanes[i].p; - LLVector3 n = LLVector3(p); + + const LLPlane& p = mAgentPlanes[i]; + const LLVector4a& n = reinterpret_cast(p); float d = p.mV[3]; - LLVector3 rscale = radius.scaledVec(scaler[mask]); + LLVector4a rscale; + rscale.setMul(radius, scaler[mask]); - LLVector3 minp = center - rscale; - LLVector3 maxp = center + rscale; + LLVector4a minp, maxp; + minp.setSub(center, rscale); + maxp.setAdd(center, rscale); - if (n * minp > -d) + if (n.dot3(minp) > -d) { return 0; } - if (n * maxp > -d) + if (n.dot3(maxp) > -d) { result = 1; } @@ -447,12 +405,12 @@ int LLCamera::sphereInFrustum(const LLVector3 &sphere_center, const F32 radius) int res = 2; for (int i = 0; i < 6; i++) { - if (mAgentPlanes[i].mask == 0xff) + if (mPlaneMask[i] == 0xff) { continue; } - float d = mAgentPlanes[i].p.dist(sphere_center); + float d = mAgentPlanes[i].dist(sphere_center); if (d > radius) { @@ -644,12 +602,14 @@ void LLCamera::ignoreAgentFrustumPlane(S32 idx) return; } - mAgentPlanes[idx].mask = 0xff; - mAgentPlanes[idx].p.clearVec(); + mPlaneMask[idx] = 0xff; + mAgentPlanes[idx].clearVec(); } void LLCamera::calcAgentFrustumPlanes(LLVector3* frust) { + alignPlanes(); + for (int i = 0; i < 8; i++) { mAgentFrustum[i] = frust[i]; @@ -662,27 +622,27 @@ void LLCamera::calcAgentFrustumPlanes(LLVector3* frust) //order of planes is important, keep most likely to fail in the front of the list //near - frust[0], frust[1], frust[2] - mAgentPlanes[2].p = planeFromPoints(frust[0], frust[1], frust[2]); + mAgentPlanes[2] = planeFromPoints(frust[0], frust[1], frust[2]); //far - mAgentPlanes[5].p = planeFromPoints(frust[5], frust[4], frust[6]); + mAgentPlanes[5] = planeFromPoints(frust[5], frust[4], frust[6]); //left - mAgentPlanes[0].p = planeFromPoints(frust[4], frust[0], frust[7]); + mAgentPlanes[0] = planeFromPoints(frust[4], frust[0], frust[7]); //right - mAgentPlanes[1].p = planeFromPoints(frust[1], frust[5], frust[6]); + mAgentPlanes[1] = planeFromPoints(frust[1], frust[5], frust[6]); //top - mAgentPlanes[4].p = planeFromPoints(frust[3], frust[2], frust[6]); + mAgentPlanes[4] = planeFromPoints(frust[3], frust[2], frust[6]); //bottom - mAgentPlanes[3].p = planeFromPoints(frust[1], frust[0], frust[4]); + mAgentPlanes[3] = planeFromPoints(frust[1], frust[0], frust[4]); //cache plane octant facing mask for use in AABBInFrustum for (U32 i = 0; i < mPlaneCount; i++) { - mAgentPlanes[i].mask = calcPlaneMask(mAgentPlanes[i].p); + mPlaneMask[i] = calcPlaneMask(mAgentPlanes[i]); } } diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h index d6c5f7bbb1..c40e819dcf 100644 --- a/indra/llmath/llcamera.h +++ b/indra/llmath/llcamera.h @@ -37,6 +37,7 @@ #include "llmath.h" #include "llcoordframe.h" #include "llplane.h" +#include "llvector4a.h" const F32 DEFAULT_FIELD_OF_VIEW = 60.f * DEG_TO_RAD; const F32 DEFAULT_ASPECT_RATIO = 640.f / 480.f; @@ -79,6 +80,14 @@ class LLCamera : public LLCoordFrame { public: + + LLCamera(const LLCamera& rhs) + { + *this = rhs; + } + + const LLCamera& operator=(const LLCamera& rhs); + enum { PLANE_LEFT = 0, PLANE_RIGHT = 1, @@ -129,13 +138,9 @@ private: LLPlane mWorldPlanes[PLANE_NUM]; LLPlane mHorizPlanes[HORIZ_PLANE_NUM]; - struct frustum_plane - { - frustum_plane() : mask(0) {} - LLPlane p; - U8 mask; - }; - frustum_plane mAgentPlanes[7]; //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP + LLPlane* mAgentPlanes; //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP + U8 mAgentPlaneBuffer[sizeof(LLPlane)*8]; + U8 mPlaneMask[7]; U32 mPlaneCount; //defaults to 6, if setUserClipPlane is called, uses user supplied clip plane in @@ -143,12 +148,14 @@ private: public: LLVector3 mAgentFrustum[8]; //8 corners of 6-plane frustum F32 mFrustumCornerDist; //distance to corner of frustum against far clip plane - LLPlane& getAgentPlane(U32 idx) { return mAgentPlanes[idx].p; } + LLPlane& getAgentPlane(U32 idx) { return mAgentPlanes[idx]; } public: LLCamera(); LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane); - virtual ~LLCamera(){} // no-op virtual destructor + virtual ~LLCamera(); + + void alignPlanes(); void setUserClipPlane(LLPlane plane); void disableUserClipPlane(); @@ -199,8 +206,8 @@ public: S32 sphereInFrustum(const LLVector3 ¢er, const F32 radius) const; S32 pointInFrustum(const LLVector3 &point) const { return sphereInFrustum(point, 0.0f); } S32 sphereInFrustumFull(const LLVector3 ¢er, const F32 radius) const { return sphereInFrustum(center, radius); } - S32 AABBInFrustum(const LLVector3 ¢er, const LLVector3& radius); - S32 AABBInFrustumNoFarClip(const LLVector3 ¢er, const LLVector3& radius); + S32 AABBInFrustum(const LLVector4a& center, const LLVector4a& radius); + S32 AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius); //does a quick 'n dirty sphere-sphere check S32 sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius); diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 8bba12783f..ae2259dba0 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -35,6 +35,7 @@ #include "lltreenode.h" #include "v3math.h" +#include "llvector4a.h" #include #include @@ -44,7 +45,7 @@ #define OCT_ERRS LL_WARNS("OctreeErrors") #endif -#define LL_OCTREE_PARANOIA_CHECK 0 +#define LL_OCTREE_PARANOIA_CHECK 1 #if LL_DARWIN #define LL_OCTREE_MAX_CAPACITY 32 #else @@ -94,23 +95,22 @@ public: typedef LLOctreeNode oct_node; typedef LLOctreeListener oct_listener; - static const U8 OCTANT_POSITIVE_X = 0x01; - static const U8 OCTANT_POSITIVE_Y = 0x02; - static const U8 OCTANT_POSITIVE_Z = 0x04; - - LLOctreeNode( LLVector3d center, - LLVector3d size, + LLOctreeNode( const LLVector4a& center, + const LLVector4a& size, BaseType* parent, - U8 octant = 255) + S32 octant = -1) : mParent((oct_node*)parent), - mCenter(center), - mSize(size), mOctant(octant) { + mD = (LLVector4a*) _mm_malloc(sizeof(LLVector4a)*4, 16); + + mD[CENTER] = center; + mD[SIZE] = size; + updateMinMax(); - if ((mOctant == 255) && mParent) + if ((mOctant == -1) && mParent) { - mOctant = ((oct_node*) mParent)->getOctant(mCenter.mdV); + mOctant = ((oct_node*) mParent)->getOctant(mD[CENTER]); } clearChildren(); @@ -124,43 +124,30 @@ public: { delete getChild(i); } + + _mm_free(mD); } inline const BaseType* getParent() const { return mParent; } - inline void setParent(BaseType* parent) { mParent = (oct_node*) parent; } - inline const LLVector3d& getCenter() const { return mCenter; } - inline const LLVector3d& getSize() const { return mSize; } - inline void setCenter(LLVector3d center) { mCenter = center; } - inline void setSize(LLVector3d size) { mSize = size; } - inline oct_node* getNodeAt(T* data) { return getNodeAt(data->getPositionGroup(), data->getBinRadius()); } - inline U8 getOctant() const { return mOctant; } - inline void setOctant(U8 octant) { mOctant = octant; } + inline void setParent(BaseType* parent) { mParent = (oct_node*) parent; } + inline const LLVector4a& getCenter() const { return mD[CENTER]; } + inline const LLVector4a& getSize() const { return mD[SIZE]; } + inline void setCenter(const LLVector4a& center) { mD[CENTER] = center; } + inline void setSize(const LLVector4a& size) { mD[SIZE] = size; } + inline oct_node* getNodeAt(T* data) { return getNodeAt(data->getPositionGroup(), data->getBinRadius()); } + inline S32 getOctant() const { return mOctant; } + inline void setOctant(S32 octant) { mOctant = octant; } inline const oct_node* getOctParent() const { return (const oct_node*) getParent(); } inline oct_node* getOctParent() { return (oct_node*) getParent(); } - U8 getOctant(const F64 pos[]) const //get the octant pos is in + S32 getOctant(const LLVector4a& pos) const //get the octant pos is in { - U8 ret = 0; - - if (pos[0] > mCenter.mdV[0]) - { - ret |= OCTANT_POSITIVE_X; - } - if (pos[1] > mCenter.mdV[1]) - { - ret |= OCTANT_POSITIVE_Y; - } - if (pos[2] > mCenter.mdV[2]) - { - ret |= OCTANT_POSITIVE_Z; - } - - return ret; + return pos.greaterThan4(mD[CENTER]).getComparisonMask() & 0x7; } - inline bool isInside(const LLVector3d& pos, const F64& rad) const + inline bool isInside(const LLVector4a& pos, const F32& rad) const { - return rad <= mSize.mdV[0]*2.0 && isInside(pos); + return rad <= mD[SIZE][0]*2.f && isInside(pos); } inline bool isInside(T* data) const @@ -168,29 +155,27 @@ public: return isInside(data->getPositionGroup(), data->getBinRadius()); } - bool isInside(const LLVector3d& pos) const + bool isInside(const LLVector4a& pos) const { - const F64& x = pos.mdV[0]; - const F64& y = pos.mdV[1]; - const F64& z = pos.mdV[2]; - - if (x > mMax.mdV[0] || x <= mMin.mdV[0] || - y > mMax.mdV[1] || y <= mMin.mdV[1] || - z > mMax.mdV[2] || z <= mMin.mdV[2]) + S32 gt = pos.greaterThan4(mD[MAX]).getComparisonMask() & 0x7; + if (gt) { return false; } - + + S32 lt = pos.lessEqual4(mD[MIN]).getComparisonMask() & 0x7; + if (lt) + { + return false; + } + return true; } void updateMinMax() { - for (U32 i = 0; i < 3; i++) - { - mMax.mdV[i] = mCenter.mdV[i] + mSize.mdV[i]; - mMin.mdV[i] = mCenter.mdV[i] - mSize.mdV[i]; - } + mD[MAX].setAdd(mD[CENTER], mD[SIZE]); + mD[MIN].setSub(mD[CENTER], mD[SIZE]); } inline oct_listener* getOctListener(U32 index) @@ -203,34 +188,34 @@ public: return contains(xform->getBinRadius()); } - bool contains(F64 radius) + bool contains(F32 radius) { if (mParent == NULL) { //root node contains nothing return false; } - F64 size = mSize.mdV[0]; - F64 p_size = size * 2.0; + F32 size = mD[SIZE][0]; + F32 p_size = size * 2.f; - return (radius <= 0.001 && size <= 0.001) || + return (radius <= 0.001f && size <= 0.001f) || (radius <= p_size && radius > size); } - static void pushCenter(LLVector3d ¢er, const LLVector3d &size, const T* data) + static void pushCenter(LLVector4a ¢er, const LLVector4a &size, const T* data) { - const LLVector3d& pos = data->getPositionGroup(); - for (U32 i = 0; i < 3; i++) - { - if (pos.mdV[i] > center.mdV[i]) - { - center.mdV[i] += size.mdV[i]; - } - else - { - center.mdV[i] -= size.mdV[i]; - } - } + const LLVector4a& pos = data->getPositionGroup(); + + LLVector4a gt = pos.greaterThan4(center); + + LLVector4a up; + up.mQ = _mm_and_ps(size.mQ, gt.mQ); + + LLVector4a down; + down.mQ = _mm_andnot_ps(gt.mQ, size.mQ); + + center.add(up); + center.sub(down); } void accept(oct_traveler* visitor) { visitor->visit(this); } @@ -249,21 +234,21 @@ public: void accept(tree_traveler* visitor) const { visitor->visit(this); } void accept(oct_traveler* visitor) const { visitor->visit(this); } - oct_node* getNodeAt(const LLVector3d& pos, const F64& rad) + oct_node* getNodeAt(const LLVector4a& pos, const F32& rad) { LLOctreeNode* node = this; if (node->isInside(pos, rad)) { //do a quick search by octant - U8 octant = node->getOctant(pos.mdV); + S32 octant = node->getOctant(pos); BOOL keep_going = TRUE; //traverse the tree until we find a node that has no node //at the appropriate octant or is smaller than the object. //by definition, that node is the smallest node that contains // the data - while (keep_going && node->getSize().mdV[0] >= rad) + while (keep_going && node->getSize()[0] >= rad) { keep_going = FALSE; for (U32 i = 0; i < node->getChildCount() && !keep_going; i++) @@ -271,7 +256,7 @@ public: if (node->getChild(i)->getOctant() == octant) { node = node->getChild(i); - octant = node->getOctant(pos.mdV); + octant = node->getOctant(pos); keep_going = TRUE; } } @@ -289,7 +274,7 @@ public: { if (data == NULL) { - //OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE BRANCH !!!" << llendl; + OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE BRANCH !!!" << llendl; return false; } LLOctreeNode* parent = getOctParent(); @@ -299,7 +284,7 @@ public: { if (getElementCount() < LL_OCTREE_MAX_CAPACITY && (contains(data->getBinRadius()) || - (data->getBinRadius() > getSize().mdV[0] && + (data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= LL_OCTREE_MAX_CAPACITY))) { //it belongs here #if LL_OCTREE_PARANOIA_CHECK @@ -330,16 +315,22 @@ public: } //it's here, but no kids are in the right place, make a new kid - LLVector3d center(getCenter()); - LLVector3d size(getSize()*0.5); + LLVector4a center = getCenter(); + LLVector4a size = getSize(); + size.mul(0.5f); //push center in direction of data LLOctreeNode::pushCenter(center, size, data); // handle case where floating point number gets too small - if( llabs(center.mdV[0] - getCenter().mdV[0]) < F_APPROXIMATELY_ZERO && - llabs(center.mdV[1] - getCenter().mdV[1]) < F_APPROXIMATELY_ZERO && - llabs(center.mdV[2] - getCenter().mdV[2]) < F_APPROXIMATELY_ZERO) + LLVector4a val; + val.setSub(center, getCenter()); + val.setAbs(val); + LLVector4a app_zero; + app_zero.mQ = F_APPROXIMATELY_ZERO_4A; + S32 lt = val.lessThan4(app_zero).getComparisonMask() & 0x7; + + if( lt == 0x7 ) { mData.insert(data); BaseType::insert(data); @@ -357,7 +348,7 @@ public: //make sure no existing node matches this position for (U32 i = 0; i < getChildCount(); i++) { - if (mChild[i]->getCenter() == center) + if (mChild[i]->getCenter().equal3(center)) { OCT_ERRS << "Octree detected duplicate child center and gave up." << llendl; return false; @@ -375,7 +366,7 @@ public: else { //it's not in here, give it to the root - //OCT_ERRS << "Octree insertion failed, starting over from root!" << llendl; + OCT_ERRS << "Octree insertion failed, starting over from root!" << llendl; oct_node* node = this; @@ -482,13 +473,19 @@ public: void addChild(oct_node* child, BOOL silent = FALSE) { #if LL_OCTREE_PARANOIA_CHECK + + if (child->getSize().equal3(getSize())) + { + OCT_ERRS << "Child size is same as parent size!" << llendl; + } + for (U32 i = 0; i < getChildCount(); i++) { - if(mChild[i]->getSize() != child->getSize()) + if(!mChild[i]->getSize().equal3(child->getSize())) { OCT_ERRS <<"Invalid octree child size." << llendl; } - if (mChild[i]->getCenter() == child->getCenter()) + if (mChild[i]->getCenter().equal3(child->getCenter())) { OCT_ERRS <<"Duplicate octree child position." << llendl; } @@ -513,7 +510,7 @@ public: } } - void removeChild(U8 index, BOOL destroy = FALSE) + void removeChild(S32 index, BOOL destroy = FALSE) { for (U32 i = 0; i < this->getListenerCount(); i++) { @@ -554,18 +551,26 @@ public: } } - //OCT_ERRS << "Octree failed to delete requested child." << llendl; + OCT_ERRS << "Octree failed to delete requested child." << llendl; } protected: + typedef enum + { + CENTER = 0, + SIZE = 1, + MAX = 2, + MIN = 3 + } eDName; + + LLVector4a* mD; + + oct_node* mParent; + S32 mOctant; + child_list mChild; element_list mData; - oct_node* mParent; - LLVector3d mCenter; - LLVector3d mSize; - LLVector3d mMax; - LLVector3d mMin; - U8 mOctant; + }; //just like a regular node, except it might expand on insert and compress on balance @@ -576,9 +581,9 @@ public: typedef LLOctreeNode BaseType; typedef LLOctreeNode oct_node; - LLOctreeRoot( LLVector3d center, - LLVector3d size, - BaseType* parent) + LLOctreeRoot(const LLVector4a& center, + const LLVector4a& size, + BaseType* parent) : BaseType(center, size, parent) { } @@ -619,28 +624,33 @@ public: { if (data == NULL) { - //OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE ROOT !!!" << llendl; + OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE ROOT !!!" << llendl; return false; } if (data->getBinRadius() > 4096.0) { - //OCT_ERRS << "!!! ELEMENT EXCEEDS MAXIMUM SIZE IN OCTREE ROOT !!!" << llendl; + OCT_ERRS << "!!! ELEMENT EXCEEDS MAXIMUM SIZE IN OCTREE ROOT !!!" << llendl; return false; } - const F64 MAX_MAG = 1024.0*1024.0; + LLVector4a MAX_MAG; + MAX_MAG.splat(1024.f*1024.f); + + const LLVector4a& v = data->getPositionGroup(); + + LLVector4a val; + val.setSub(v, mD[CENTER]); + val.setAbs(val); + S32 lt = val.lessThan4(MAX_MAG).getComparisonMask() & 0x7; - const LLVector3d& v = data->getPositionGroup(); - if (!(fabs(v.mdV[0]-this->mCenter.mdV[0]) < MAX_MAG && - fabs(v.mdV[1]-this->mCenter.mdV[1]) < MAX_MAG && - fabs(v.mdV[2]-this->mCenter.mdV[2]) < MAX_MAG)) + if (lt != 0x7) { - //OCT_ERRS << "!!! ELEMENT EXCEEDS RANGE OF SPATIAL PARTITION !!!" << llendl; + OCT_ERRS << "!!! ELEMENT EXCEEDS RANGE OF SPATIAL PARTITION !!!" << llendl; return false; } - if (this->getSize().mdV[0] > data->getBinRadius() && isInside(data->getPositionGroup())) + if (this->getSize()[0] > data->getBinRadius() && isInside(data->getPositionGroup())) { //we got it, just act like a branch oct_node* node = getNodeAt(data); @@ -656,31 +666,34 @@ public: else if (this->getChildCount() == 0) { //first object being added, just wrap it up - while (!(this->getSize().mdV[0] > data->getBinRadius() && isInside(data->getPositionGroup()))) + while (!(this->getSize()[0] > data->getBinRadius() && isInside(data->getPositionGroup()))) { - LLVector3d center, size; + LLVector4a center, size; center = this->getCenter(); size = this->getSize(); LLOctreeNode::pushCenter(center, size, data); this->setCenter(center); - this->setSize(size*2); + size.mul(2.f); + this->setSize(size); this->updateMinMax(); } LLOctreeNode::insert(data); } else { - while (!(this->getSize().mdV[0] > data->getBinRadius() && isInside(data->getPositionGroup()))) + while (!(this->getSize()[0] > data->getBinRadius() && isInside(data->getPositionGroup()))) { //the data is outside the root node, we need to grow - LLVector3d center(this->getCenter()); - LLVector3d size(this->getSize()); + LLVector4a center(this->getCenter()); + LLVector4a size(this->getSize()); //expand this node - LLVector3d newcenter(center); + LLVector4a newcenter(center); LLOctreeNode::pushCenter(newcenter, size, data); this->setCenter(newcenter); - this->setSize(size*2); + LLVector4a size2 = size; + size2.mul(2.f); + this->setSize(size2); this->updateMinMax(); //copy our children to a new branch diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index c4172de651..72833c019f 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -295,7 +295,7 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons } } -class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst +class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst { public: const LLVolumeFace* mFace; @@ -305,7 +305,7 @@ public: mFace = face; } - virtual void visit(const LLOctreeNode* branch) + virtual void visit(const LLOctreeNode* branch) { LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0); @@ -314,12 +314,12 @@ public: if (branch->getElementCount() != 0) { - const LLVolumeFace::Triangle* tri = *(branch->getData().begin()); + const LLVolumeTriangle* tri = *(branch->getData().begin()); min = *(tri->mV[0]); max = *(tri->mV[0]); - for (LLOctreeNode::const_element_iter iter = + for (LLOctreeNode::const_element_iter iter = branch->getData().begin(); iter != branch->getData().end(); ++iter) { //stretch by triangles in node @@ -4394,7 +4394,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en LLVector4a box_size; box_size.setSub(face.mExtents[1], face.mExtents[0]); - if (LLLineSegmentBoxIntersect(start.getF32(), end.getF32(), box_center.getF32(), box_size.getF32())) + if (LLLineSegmentBoxIntersect(start, end, box_center, box_size)) { if (bi_normal != NULL) // if the caller wants binormals, we may need to generate them { @@ -5418,12 +5418,17 @@ void LLVolumeFace::optimize(F32 angle_cutoff) void LLVolumeFace::createOctree() { - mOctree = new LLOctreeRoot(LLVector3d(0,0,0), LLVector3d(1,1,1), NULL); + LLVector4a center; + LLVector4a size; + center.splat(0.f); + size.splat(1.f); + + mOctree = new LLOctreeRoot(center, size, NULL); new LLVolumeOctreeListener(mOctree); for (U32 i = 0; i < mNumIndices; i+= 3) { - Triangle* tri = new Triangle(); + LLPointer tri = new LLVolumeTriangle(); const LLVector4a& v0 = mPositions[mIndices[i]]; const LLVector4a& v1 = mPositions[mIndices[i+1]]; @@ -5449,8 +5454,7 @@ void LLVolumeFace::createOctree() center.setAdd(min, max); center.mul(0.5f); - - tri->mPositionGroup.setVec(center[0], center[1], center[2]); + *tri->mPositionGroup = center; LLVector4a size; size.setSub(max,min); @@ -5464,15 +5468,6 @@ void LLVolumeFace::createOctree() rebound.traverse(mOctree); } -const LLVector3d& LLVolumeFace::Triangle::getPositionGroup() const -{ - return mPositionGroup; -} - -const F64& LLVolumeFace::Triangle::getBinRadius() const -{ - return mRadius; -} void LLVolumeFace::swapData(LLVolumeFace& rhs) { diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 0ae8aa19ca..c49d1c650d 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -46,6 +46,7 @@ template class LLOctreeNode; class LLVector4a; class LLVolumeFace; class LLVolume; +class LLVolumeTriangle; #include "lldarray.h" #include "lluuid.h" @@ -918,20 +919,7 @@ public: // mWeights.size() should be empty or match mVertices.size() LLVector4a* mWeights; - class Triangle : public LLRefCount - { - public: - const LLVector4a* mV[3]; - U16 mIndex[3]; - - LLVector3d mPositionGroup; - F64 mRadius; - - virtual const LLVector3d& getPositionGroup() const; - virtual const F64& getBinRadius() const; - }; - - LLOctreeNode* mOctree; + LLOctreeNode* mOctree; private: BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE); diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 47146a5ec4..715309b64a 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -79,6 +79,17 @@ protected: class LLVertexBuffer : public LLRefCount { public: + LLVertexBuffer(const LLVertexBuffer& rhs) + { + *this = rhs; + } + + const LLVertexBuffer& operator=(const LLVertexBuffer& rhs) + { + llerrs << "Illegal operation!" << llendl; + return *this; + } + static LLVBOPool sStreamVBOPool; static LLVBOPool sDynamicVBOPool; static LLVBOPool sStreamIBOPool; diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 45f9de8e8d..c0cc294c02 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -377,7 +377,14 @@ void LLLineEditor::setText(const LLStringExplicit &new_text) setCursor(llmin((S32)mText.length(), getCursor())); // Set current history line to end of history. - mCurrentHistoryLine = mLineHistory.end() - 1; + if (mLineHistory.empty()) + { + mCurrentHistoryLine = mLineHistory.end(); + } + else + { + mCurrentHistoryLine = mLineHistory.end() - 1; + } mPrevText = mText; } diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 03eee12707..04e433dcfd 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -41,6 +41,7 @@ #include "llcriticaldamp.h" #include "llface.h" #include "lllightconstants.h" +#include "llmatrix4a.h" #include "llsky.h" #include "llsurfacepatch.h" #include "llviewercamera.h" @@ -91,8 +92,12 @@ void LLDrawable::incrementVisible() sCurVisible++; sCurPixelAngle = (F32) gViewerWindow->getWindowHeightRaw()/LLViewerCamera::getInstance()->getView(); } + void LLDrawable::init() { + mExtents = (LLVector4a*) _mm_malloc(sizeof(LLVector4a)*3, 32); + mPositionGroup = mExtents + 2; + // mXform mParent = NULL; mRenderType = 0; @@ -121,6 +126,11 @@ void LLDrawable::initClass() void LLDrawable::destroy() { + if (gDebugGL) + { + gPipeline.checkReferences(this); + } + if (isDead()) { sNumZombieDrawables--; @@ -139,6 +149,9 @@ void LLDrawable::destroy() { llinfos << "- Zombie drawables: " << sNumZombieDrawables << llendl; }*/ + + _mm_free(mExtents); + mExtents = mPositionGroup = NULL; } void LLDrawable::markDead() @@ -714,12 +727,14 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update) LLFace* facep = getFace(i); if (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA) { - LLVector3 box = (facep->mExtents[1] - facep->mExtents[0]) * 0.25f; + LLVector4a box; + box.setSub(facep->mExtents[1], facep->mExtents[0]); + box.mul(0.25f); LLVector3 v = (facep->mCenterLocal-camera.getOrigin()); const LLVector3& at = camera.getAtAxis(); for (U32 j = 0; j < 3; j++) { - v.mV[j] -= box.mV[j] * at.mV[j]; + v.mV[j] -= box[j] * at.mV[j]; } facep->mDistance = v * camera.getAtAxis(); } @@ -728,7 +743,7 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update) } else { - pos = LLVector3(getPositionGroup()); + pos = LLVector3(getPositionGroup().getF32()); } pos -= camera.getOrigin(); @@ -777,7 +792,7 @@ BOOL LLDrawable::updateGeometry(BOOL priority) return res; } -void LLDrawable::shiftPos(const LLVector3 &shift_vector) +void LLDrawable::shiftPos(const LLVector4a &shift_vector) { if (isDead()) { @@ -809,9 +824,9 @@ void LLDrawable::shiftPos(const LLVector3 &shift_vector) for (S32 i = 0; i < getNumFaces(); i++) { LLFace *facep = getFace(i); - facep->mCenterAgent += shift_vector; - facep->mExtents[0] += shift_vector; - facep->mExtents[1] += shift_vector; + facep->mCenterAgent += LLVector3(shift_vector.getF32()); + facep->mExtents[0].add(shift_vector); + facep->mExtents[1].add(shift_vector); if (!volume && facep->hasGeometry()) { @@ -820,9 +835,9 @@ void LLDrawable::shiftPos(const LLVector3 &shift_vector) } } - mExtents[0] += shift_vector; - mExtents[1] += shift_vector; - mPositionGroup += LLVector3d(shift_vector); + mExtents[0].add(shift_vector); + mExtents[1].add(shift_vector); + mPositionGroup->add(shift_vector); } else if (mSpatialBridge) { @@ -830,9 +845,9 @@ void LLDrawable::shiftPos(const LLVector3 &shift_vector) } else if (isAvatar()) { - mExtents[0] += shift_vector; - mExtents[1] += shift_vector; - mPositionGroup += LLVector3d(shift_vector); + mExtents[0].add(shift_vector); + mExtents[1].add(shift_vector); + mPositionGroup->add(shift_vector); } mVObjp->onShift(shift_vector); @@ -844,21 +859,26 @@ const LLVector3& LLDrawable::getBounds(LLVector3& min, LLVector3& max) const return mXform.getPositionW(); } -const LLVector3* LLDrawable::getSpatialExtents() const +const LLVector4a* LLDrawable::getSpatialExtents() const { return mExtents; } -void LLDrawable::setSpatialExtents(LLVector3 min, LLVector3 max) +void LLDrawable::setSpatialExtents(const LLVector3& min, const LLVector3& max) +{ + mExtents[0].load3(min.mV); + mExtents[1].load3(max.mV); +} + +void LLDrawable::setSpatialExtents(const LLVector4a& min, const LLVector4a& max) { - LLVector3 size = max - min; mExtents[0] = min; - mExtents[1] = max; + mExtents[1] = max; } -void LLDrawable::setPositionGroup(const LLVector3d& pos) +void LLDrawable::setPositionGroup(const LLVector4a& pos) { - mPositionGroup.setVec(pos); + *mPositionGroup = pos; } void LLDrawable::updateSpatialExtents() @@ -872,7 +892,7 @@ void LLDrawable::updateSpatialExtents() if (mSpatialBridge.notNull()) { - mPositionGroup.setVec(0,0,0); + mPositionGroup->splat(0.f); } } @@ -1083,59 +1103,72 @@ void LLSpatialBridge::updateSpatialExtents() root->rebound(); } - LLXformMatrix* mat = mDrawable->getXform(); - - LLVector3 offset = root->mBounds[0]; - LLVector3 size = root->mBounds[1]; + LLVector4a offset; + LLVector4a size = root->mBounds[1]; - LLVector3 center = LLVector3(0,0,0) * mat->getWorldMatrix(); - LLQuaternion rotation = LLQuaternion(mat->getWorldMatrix()); + //VECTORIZE THIS + LLMatrix4a mat; + mat.loadu(mDrawable->getXform()->getWorldMatrix()); + + LLVector4a t; + t.splat(0.f); + + LLVector4a center; + mat.affineTransform(t, center); - offset *= rotation; - center += offset; + mat.rotate(root->mBounds[0], offset); + center.add(offset); - LLVector3 v[4]; + LLVector4a v[4]; + //get 4 corners of bounding box - v[0] = (size * rotation); - v[1] = (LLVector3(-size.mV[0], -size.mV[1], size.mV[2]) * rotation); - v[2] = (LLVector3(size.mV[0], -size.mV[1], -size.mV[2]) * rotation); - v[3] = (LLVector3(-size.mV[0], size.mV[1], -size.mV[2]) * rotation); + mat.rotate(size,v[0]); - LLVector3& newMin = mExtents[0]; - LLVector3& newMax = mExtents[1]; + LLVector4a scale; + + scale.set(-1.f, -1.f, 1.f); + scale.mul(size); + mat.rotate(scale, v[1]); + + scale.set(1.f, -1.f, -1.f); + scale.mul(size); + mat.rotate(scale, v[2]); + + scale.set(-1.f, 1.f, -1.f); + scale.mul(size); + mat.rotate(scale, v[3]); + + + LLVector4a& newMin = mExtents[0]; + LLVector4a& newMax = mExtents[1]; newMin = newMax = center; for (U32 i = 0; i < 4; i++) { - for (U32 j = 0; j < 3; j++) - { - F32 delta = fabsf(v[i].mV[j]); - F32 min = center.mV[j] - delta; - F32 max = center.mV[j] + delta; - - if (min < newMin.mV[j]) - { - newMin.mV[j] = min; - } - - if (max > newMax.mV[j]) - { - newMax.mV[j] = max; - } - } - } + LLVector4a delta; + delta.setAbs(v[i]); + LLVector4a min; + min.setSub(center, delta); + LLVector4a max; + max.setAdd(center, delta); - LLVector3 diagonal = newMax - newMin; - mRadius = diagonal.magVec() * 0.5f; + newMin.setMin(min); + newMax.setMax(max); + } + + LLVector4a diagonal; + diagonal.setSub(newMax, newMin); + mRadius = diagonal.length3() * 0.5f; - mPositionGroup.setVec((newMin + newMax) * 0.5f); + mPositionGroup->setAdd(newMin,newMax); + mPositionGroup->mul(0.5f); updateBinRadius(); } void LLSpatialBridge::updateBinRadius() { - mBinRadius = llmin((F32) mOctree->getSize().mdV[0]*0.5f, 256.f); + mBinRadius = llmin( mOctree->getSize()[0]*0.5f, 256.f); } LLCamera LLSpatialBridge::transformCamera(LLCamera& camera) @@ -1276,8 +1309,12 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector* LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); group->rebound(); - LLVector3 center = (mExtents[0] + mExtents[1]) * 0.5f; - LLVector3 size = (mExtents[1]-mExtents[0]) * 0.5f; + LLVector4a center; + center.setAdd(mExtents[0], mExtents[1]); + center.mul(0.5f); + LLVector4a size; + size.setSub(mExtents[1], mExtents[0]); + size.mul(0.5f); if ((LLPipeline::sShadowRender && camera_in.AABBInFrustum(center, size)) || LLPipeline::sImpostorRender || @@ -1389,11 +1426,11 @@ BOOL LLSpatialBridge::updateMove() return TRUE; } -void LLSpatialBridge::shiftPos(const LLVector3& vec) +void LLSpatialBridge::shiftPos(const LLVector4a& vec) { - mExtents[0] += vec; - mExtents[1] += vec; - mPositionGroup += LLVector3d(vec); + mExtents[0].add(vec); + mExtents[1].add(vec); + mPositionGroup->add(vec); } void LLSpatialBridge::cleanupReferences() @@ -1511,7 +1548,7 @@ F32 LLHUDBridge::calcPixelArea(LLSpatialGroup* group, LLCamera& camera) } -void LLHUDBridge::shiftPos(const LLVector3& vec) +void LLHUDBridge::shiftPos(const LLVector4a& vec) { //don't shift hud bridges on region crossing } diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index c3c6cbe12f..811ff1801b 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -41,6 +41,7 @@ #include "v4math.h" #include "m4math.h" #include "v4coloru.h" +#include "llvector4a.h" #include "llquaternion.h" #include "xform.h" #include "llmemtype.h" @@ -66,6 +67,17 @@ const U32 SILHOUETTE_HIGHLIGHT = 0; class LLDrawable : public LLRefCount { public: + LLDrawable(const LLDrawable& rhs) + { + *this = rhs; + } + + const LLDrawable& operator=(const LLDrawable& rhs) + { + llerrs << "Illegal operation!" << llendl; + return *this; + } + static void initClass(); LLDrawable() { init(); } @@ -94,14 +106,14 @@ public: const LLVector3& getPosition() const { return mXform.getPosition(); } const LLVector3& getWorldPosition() const { return mXform.getPositionW(); } const LLVector3 getPositionAgent() const; - const LLVector3d& getPositionGroup() const { return mPositionGroup; } + const LLVector4a& getPositionGroup() const { return *mPositionGroup; } const LLVector3& getScale() const { return mCurrentScale; } void setScale(const LLVector3& scale) { mCurrentScale = scale; } const LLQuaternion& getWorldRotation() const { return mXform.getWorldRotation(); } const LLQuaternion& getRotation() const { return mXform.getRotation(); } F32 getIntensity() const { return llmin(mXform.getScale().mV[0], 4.f); } S32 getLOD() const { return mVObjp ? mVObjp->getLOD() : 1; } - F64 getBinRadius() const { return mBinRadius; } + F32 getBinRadius() const { return mBinRadius; } void getMinMax(LLVector3& min,LLVector3& max) const { mXform.getMinMax(min,max); } LLXformMatrix* getXform() { return &mXform; } @@ -155,7 +167,7 @@ public: void updateSpecialHoverCursor(BOOL enabled); - virtual void shiftPos(const LLVector3 &shift_vector); + virtual void shiftPos(const LLVector4a &shift_vector); S32 getGeneration() const { return mGeneration; } @@ -173,11 +185,12 @@ public: const LLVector3& getBounds(LLVector3& min, LLVector3& max) const; virtual void updateSpatialExtents(); virtual void updateBinRadius(); - const LLVector3* getSpatialExtents() const; - void setSpatialExtents(LLVector3 min, LLVector3 max); - void setPositionGroup(const LLVector3d& pos); - void setPositionGroup(const LLVector3& pos) { setPositionGroup(LLVector3d(pos)); } + const LLVector4a* getSpatialExtents() const; + void setSpatialExtents(const LLVector3& min, const LLVector3& max); + void setSpatialExtents(const LLVector4a& min, const LLVector4a& max); + void setPositionGroup(const LLVector4a& pos); + void setRenderType(S32 type) { mRenderType = type; } BOOL isRenderType(S32 type) { return mRenderType == type; } S32 getRenderType() { return mRenderType; } @@ -288,6 +301,9 @@ public: private: typedef std::vector face_list_t; + LLVector4a* mExtents; + LLVector4a* mPositionGroup; + U32 mState; S32 mRenderType; LLPointer mVObjp; @@ -297,9 +313,7 @@ private: mutable U32 mVisible; F32 mRadius; - LLVector3 mExtents[2]; - LLVector3d mPositionGroup; - F64 mBinRadius; + F32 mBinRadius; S32 mGeneration; LLVector3 mCurrentScale; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 98a50ca4e7..b8407a6f5b 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -152,6 +152,8 @@ void cylindricalProjection(LLVector2 &tc, const LLVector4a& normal, const LLVect void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp) { + mExtents = (LLVector4a*) _mm_malloc(sizeof(LLVector4a)*2, 16); + mLastUpdateTime = gFrameTimeSeconds; mLastMoveTime = 0.f; mVSize = 0.f; @@ -206,6 +208,12 @@ static LLFastTimer::DeclareTimer FTM_FACE_DEREF("Deref"); void LLFace::destroy() { LLFastTimer t(FTM_DESTROY_FACE); + + if (gDebugGL) + { + gPipeline.checkReferences(this); + } + if(mTexture.notNull()) { LLFastTimer t(FTM_DESTROY_TEXTURE); @@ -260,6 +268,9 @@ void LLFace::destroy() mDrawablep = NULL; mVObjp = NULL; } + + _mm_free(mExtents); + mExtents = NULL; } @@ -725,13 +736,20 @@ static void xform(LLVector2 &tex_coord, F32 cosAng, F32 sinAng, F32 offS, F32 of BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, - const LLMatrix4& mat_vert, const LLMatrix3& mat_normal, BOOL global_volume) + const LLMatrix4& mat_vert_in, const LLMatrix3& mat_normal_in, BOOL global_volume) { LLMemType mt1(LLMemType::MTYPE_DRAWABLE); //get bounding box if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION)) { + //VECTORIZE THIS + LLMatrix4a mat_vert; + mat_vert.loadu(mat_vert_in); + + LLMatrix4a mat_normal; + mat_normal.loadu(mat_normal_in); + //if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME)) //{ //vertex buffer no longer valid // mVertexBuffer = NULL; @@ -739,82 +757,96 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, //} //VECTORIZE THIS - LLVector3 min,max; + LLVector4a min,max; if (f >= volume.getNumVolumeFaces()) { - min = LLVector3(-1,-1,-1); - max = LLVector3(1,1,1); - } - else - { - const LLVolumeFace &face = volume.getVolumeFace(f); - min.set(face.mExtents[0].getF32()); - max.set(face.mExtents[1].getF32()); + llwarns << "Generating bounding box for invalid face index!" << llendl; + f = 0; } + const LLVolumeFace &face = volume.getVolumeFace(f); + min = face.mExtents[0]; + max = face.mExtents[1]; + + //min, max are in volume space, convert to drawable render space - LLVector3 center = ((min + max) * 0.5f)*mat_vert; - LLVector3 size = ((max-min) * 0.5f); + LLVector4a center; + LLVector4a t; + t.setAdd(min, max); + t.mul(0.5f); + mat_vert.affineTransform(t, center); + LLVector4a size; + size.setSub(max, min); + size.mul(0.5f); + if (!global_volume) { - size.scaleVec(mDrawablep->getVObj()->getScale()); + //VECTORIZE THIS + LLVector4a scale; + scale.load3(mDrawablep->getVObj()->getScale().mV); + size.mul(scale); } - LLMatrix3 mat = mat_normal; - LLVector3 x = mat.getFwdRow(); - LLVector3 y = mat.getLeftRow(); - LLVector3 z = mat.getUpRow(); - x.normVec(); - y.normVec(); - z.normVec(); + mat_normal.mMatrix[0].normalize3fast(); + mat_normal.mMatrix[1].normalize3fast(); + mat_normal.mMatrix[2].normalize3fast(); + + LLVector4a v[4]; - mat.setRows(x,y,z); + //get 4 corners of bounding box + mat_normal.rotate(size,v[0]); - LLQuaternion rotation = LLQuaternion(mat); + //VECTORIZE THIS + LLVector4a scale; - LLVector3 v[4]; - //get 4 corners of bounding box - v[0] = (size * rotation); - v[1] = (LLVector3(-size.mV[0], -size.mV[1], size.mV[2]) * rotation); - v[2] = (LLVector3(size.mV[0], -size.mV[1], -size.mV[2]) * rotation); - v[3] = (LLVector3(-size.mV[0], size.mV[1], -size.mV[2]) * rotation); + scale.set(-1.f, -1.f, 1.f); + scale.mul(size); + mat_normal.rotate(scale, v[1]); + + scale.set(1.f, -1.f, -1.f); + scale.mul(size); + mat_normal.rotate(scale, v[2]); + + scale.set(-1.f, 1.f, -1.f); + scale.mul(size); + mat_normal.rotate(scale, v[3]); - LLVector3& newMin = mExtents[0]; - LLVector3& newMax = mExtents[1]; + LLVector4a& newMin = mExtents[0]; + LLVector4a& newMax = mExtents[1]; newMin = newMax = center; for (U32 i = 0; i < 4; i++) { - for (U32 j = 0; j < 3; j++) - { - F32 delta = fabsf(v[i].mV[j]); - F32 min = center.mV[j] - delta; - F32 max = center.mV[j] + delta; - - if (min < newMin.mV[j]) - { - newMin.mV[j] = min; - } - - if (max > newMax.mV[j]) - { - newMax.mV[j] = max; - } - } + LLVector4a delta; + delta.setAbs(v[i]); + LLVector4a min; + min.setSub(center, delta); + LLVector4a max; + max.setAdd(center, delta); + + newMin.setMin(min); + newMax.setMax(max); } if (!mDrawablep->isActive()) { - LLVector3 offset = mDrawablep->getRegion()->getOriginAgent(); - newMin += offset; - newMax += offset; + LLVector4a offset; + offset.load3(mDrawablep->getRegion()->getOriginAgent().mV); + newMin.add(offset); + newMax.add(offset); } - mCenterLocal = (newMin+newMax)*0.5f; - LLVector3 tmp = (newMin - newMax) ; - mBoundingSphereRadius = tmp.length() * 0.5f ; + t.setAdd(newMin, newMax); + t.mul(0.5f); + + //VECTORIZE THIS + mCenterLocal.set(t.getF32()); + + t.setSub(newMax,newMin); + t.mul(0.5f); + mBoundingSphereRadius = t.length3(); updateCenterAgent(); } @@ -1647,20 +1679,31 @@ F32 LLFace::getTextureVirtualSize() BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) { + //VECTORIZE THIS //get area of circle around face - LLVector3 center = getPositionAgent(); - LLVector3 size = (mExtents[1] - mExtents[0]) * 0.5f; + LLVector4a center; + center.load3(getPositionAgent().mV); + LLVector4a size; + size.setSub(mExtents[1], mExtents[0]); + size.mul(0.5f); + LLViewerCamera* camera = LLViewerCamera::getInstance(); - F32 size_squared = size.lengthSquared() ; - LLVector3 lookAt = center - camera->getOrigin(); - F32 dist = lookAt.normVec() ; + F32 size_squared = size.dot3(size); + LLVector4a lookAt; + LLVector4a t; + t.load3(camera->getOrigin().mV); + lookAt.setSub(center, t); + F32 dist = lookAt.length3(); + lookAt.normalize3fast() ; //get area of circle around node F32 app_angle = atanf(fsqrtf(size_squared) / dist); radius = app_angle*LLDrawable::sCurPixelAngle; mPixelArea = radius*radius * 3.14159f; - cos_angle_to_view_dir = lookAt * camera->getXAxis() ; + LLVector4a x_axis; + x_axis.load3(camera->getXAxis().mV); + cos_angle_to_view_dir = lookAt.dot3(x_axis); //if has media, check if the face is out of the view frustum. if(hasMedia()) @@ -1676,7 +1719,10 @@ BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) } else { - if(dist * dist * (lookAt - camera->getXAxis()).lengthSquared() < size_squared) + LLVector4a d; + d.setSub(lookAt, x_axis); + + if(dist * dist * d.dot3(d) < size_squared) { cos_angle_to_view_dir = 1.0f ; } diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 48909d7895..0cd472a2fd 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -65,6 +65,17 @@ class LLFace { public: + LLFace(const LLFace& rhs) + { + *this = rhs; + } + + const LLFace& operator=(const LLFace& rhs) + { + llerrs << "Illegal operation!" << llendl; + return *this; + } + enum EMasks { LIGHT = 0x0001, @@ -221,7 +232,9 @@ public: LLVector3 mCenterLocal; LLVector3 mCenterAgent; - LLVector3 mExtents[2]; + + LLVector4a* mExtents; + LLVector2 mTexExtents[2]; F32 mDistance; LLPointer mVertexBuffer; diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index 561965d021..8be4e34748 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -97,11 +97,13 @@ void LLVolumeImplFlexible::onParameterChanged(U16 param_type, LLNetworkData *dat } } -void LLVolumeImplFlexible::onShift(const LLVector3 &shift_vector) +void LLVolumeImplFlexible::onShift(const LLVector4a &shift_vector) { + //VECTORIZE THIS + LLVector3 shift(shift_vector.getF32()); for (int section = 0; section < (1<getRenderRotation(); LLVector3 first_grid_obj_pos = first_grid_object->getRenderPosition(); - LLVector3 min_extents(F32_MAX, F32_MAX, F32_MAX); - LLVector3 max_extents(-F32_MAX, -F32_MAX, -F32_MAX); + LLVector4a min_extents(F32_MAX); + LLVector4a max_extents(-F32_MAX); BOOL grid_changed = FALSE; for (LLObjectSelection::iterator iter = mGridObjects.begin(); iter != mGridObjects.end(); ++iter) @@ -1110,7 +1110,7 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 & LLDrawable* drawable = object->mDrawable; if (drawable) { - const LLVector3* ext = drawable->getSpatialExtents(); + const LLVector4a* ext = drawable->getSpatialExtents(); update_min_max(min_extents, max_extents, ext[0]); update_min_max(min_extents, max_extents, ext[1]); grid_changed = TRUE; @@ -1118,13 +1118,19 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 & } if (grid_changed) { - mGridOrigin = lerp(min_extents, max_extents, 0.5f); + LLVector4a center, size; + center.setAdd(min_extents, max_extents); + center.mul(0.5f); + size.setSub(max_extents, min_extents); + size.mul(0.5f); + + mGridOrigin.set(center.getF32()); LLDrawable* drawable = first_grid_object->mDrawable; if (drawable && drawable->isActive()) { mGridOrigin = mGridOrigin * first_grid_object->getRenderMatrix(); } - mGridScale = (max_extents - min_extents) * 0.5f; + mGridScale.set(size.getF32()); } } else // GRID_MODE_WORLD or just plain default diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 355173772b..3cf0138303 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -102,23 +102,6 @@ void sg_assert(BOOL expr) #endif } -#if LL_DEBUG -void validate_drawable(LLDrawable* drawablep) -{ - F64 rad = drawablep->getBinRadius(); - const LLVector3* ext = drawablep->getSpatialExtents(); - - if (rad < 0 || rad > 4096 || - (ext[1]-ext[0]).magVec() > 4096) - { - llwarns << "Invalid drawable found in octree." << llendl; - } -} -#else -#define validate_drawable(x) -#endif - - S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad) { return AABBSphereIntersectR2(min, max, origin, rad*rad); @@ -158,6 +141,55 @@ S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVe } +S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad) +{ + return AABBSphereIntersectR2(min, max, origin, rad*rad); +} + +S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &r) +{ + F32 d = 0.f; + F32 t; + + LLVector4a origina; + origina.load3(origin.mV); + + LLVector4a v; + v.setSub(min, origina); + + if (v.dot3(v) < r) + { + v.setSub(max, origina); + if (v.dot3(v) < r) + { + return 2; + } + } + + + for (U32 i = 0; i < 3; i++) + { + if (origin.mV[i] < min[i]) + { + t = min[i] - origin.mV[i]; + d += t*t; + } + else if (origin.mV[i] > max[i]) + { + t = origin.mV[i] - max[i]; + d += t*t; + } + + if (d > r) + { + return 0; + } + } + + return 1; +} + + typedef enum { b000 = 0x00, @@ -193,24 +225,13 @@ static U8 sOcclusionIndices[] = b000, b110, b100, b101, b001, b011, b010, b110, }; -U8* get_box_fan_indices(LLCamera* camera, const LLVector3& center) +U8* get_box_fan_indices(LLCamera* camera, const LLVector4a& center) { - LLVector3 d = center - camera->getOrigin(); - - U8 cypher = 0; - if (d.mV[0] > 0) - { - cypher |= b100; - } - if (d.mV[1] > 0) - { - cypher |= b010; - } - if (d.mV[2] > 0) - { - cypher |= b001; - } + LLVector4a origin; + origin.load3(camera->getOrigin().mV); + S32 cypher = center.greaterThan4(origin).getComparisonMask() & 0x7; + return sOcclusionIndices+cypher*8; } @@ -218,33 +239,49 @@ void LLSpatialGroup::buildOcclusion() { if (!mOcclusionVerts) { - mOcclusionVerts = new F32[8*3]; + mOcclusionVerts = (LLVector4a*) _mm_malloc(sizeof(LLVector4a)*8, 16); } - LLVector3 r = mBounds[1] + LLVector3(SG_OCCLUSION_FUDGE, SG_OCCLUSION_FUDGE, SG_OCCLUSION_FUDGE); + LLVector4a fudge; + fudge.splat(SG_OCCLUSION_FUDGE); - for (U32 k = 0; k < 3; k++) - { - r.mV[k] = llmin(mBounds[1].mV[k]+0.25f, r.mV[k]); - } + LLVector4a r; + r.setAdd(mBounds[1], fudge); - F32* v = mOcclusionVerts; - F32* c = mBounds[0].mV; - F32* s = r.mV; + LLVector4a r2; + r2.splat(0.25f); + r2.add(mBounds[1]); + + r.setMin(r2); + + LLVector4a* v = mOcclusionVerts; + const LLVector4a& c = mBounds[0]; + const LLVector4a& s = r; + static const LLVector4a octant[] = + { + LLVector4a(-1.f, -1.f, -1.f), + LLVector4a(-1.f, -1.f, 1.f), + LLVector4a(-1.f, 1.f, -1.f), + LLVector4a(-1.f, 1.f, 1.f), + + LLVector4a(1.f, -1.f, -1.f), + LLVector4a(1.f, -1.f, 1.f), + LLVector4a(1.f, 1.f, -1.f), + LLVector4a(1.f, 1.f, 1.f), + }; + //vertex positions are encoded so the 3 bits of their vertex index //correspond to their axis facing, with bit position 3,2,1 matching //axis facing x,y,z, bit set meaning positive facing, bit clear //meaning negative facing - v[0] = c[0]-s[0]; v[1] = c[1]-s[1]; v[2] = c[2]-s[2]; // 0 - 0000 - v[3] = c[0]-s[0]; v[4] = c[1]-s[1]; v[5] = c[2]+s[2]; // 1 - 0001 - v[6] = c[0]-s[0]; v[7] = c[1]+s[1]; v[8] = c[2]-s[2]; // 2 - 0010 - v[9] = c[0]-s[0]; v[10] = c[1]+s[1]; v[11] = c[2]+s[2]; // 3 - 0011 - - v[12] = c[0]+s[0]; v[13] = c[1]-s[1]; v[14] = c[2]-s[2]; // 4 - 0100 - v[15] = c[0]+s[0]; v[16] = c[1]-s[1]; v[17] = c[2]+s[2]; // 5 - 0101 - v[18] = c[0]+s[0]; v[19] = c[1]+s[1]; v[20] = c[2]-s[2]; // 6 - 0110 - v[21] = c[0]+s[0]; v[22] = c[1]+s[1]; v[23] = c[2]+s[2]; // 7 - 0111 + + for (S32 i = 0; i < 8; ++i) + { + v[i] = s; + v[i].mul(octant[i]); + v[i].add(c); + } clearState(LLSpatialGroup::OCCLUSION_DIRTY); } @@ -288,6 +325,11 @@ LLSpatialGroup::~LLSpatialGroup() llerrs << "Illegal deletion of LLSpatialGroup!" << llendl; }*/ + if (gDebugGL) + { + gPipeline.checkReferences(this); + } + if (isState(DEAD)) { sZombieGroups--; @@ -300,11 +342,13 @@ LLSpatialGroup::~LLSpatialGroup() sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]); } - delete [] mOcclusionVerts; + _mm_free(mOcclusionVerts); LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); clearDrawMap(); clearAtlasList() ; + + _mm_free(mBounds); } BOOL LLSpatialGroup::hasAtlas(LLTextureAtlas* atlasp) @@ -456,8 +500,10 @@ void LLSpatialGroup::validate() sg_assert(!isState(DIRTY)); sg_assert(!isDead()); - LLVector3 myMin = mBounds[0] - mBounds[1]; - LLVector3 myMax = mBounds[0] + mBounds[1]; + LLVector4a myMin; + myMin.setSub(mBounds[0], mBounds[1]); + LLVector4a myMax; + myMax.setAdd(mBounds[0], mBounds[1]); validateDrawMap(); @@ -489,16 +535,18 @@ void LLSpatialGroup::validate() group->validate(); //ensure all children are enclosed in this node - LLVector3 center = group->mBounds[0]; - LLVector3 size = group->mBounds[1]; + LLVector4a center = group->mBounds[0]; + LLVector4a size = group->mBounds[1]; - LLVector3 min = center - size; - LLVector3 max = center + size; + LLVector4a min; + min.setSub(center, size); + LLVector4a max; + max.setAdd(center, size); for (U32 j = 0; j < 3; j++) { - sg_assert(min.mV[j] >= myMin.mV[j]-0.02f); - sg_assert(max.mV[j] <= myMax.mV[j]+0.02f); + sg_assert(min[j] >= myMin[j]-0.02f); + sg_assert(max[j] <= myMax[j]+0.02f); } } @@ -508,8 +556,8 @@ void LLSpatialGroup::validate() void LLSpatialGroup::checkStates() { #if LL_OCTREE_PARANOIA_CHECK - LLOctreeStateCheck checker; - checker.traverse(mOctreeNode); + //LLOctreeStateCheck checker; + //checker.traverse(mOctreeNode); #endif } @@ -534,19 +582,17 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); drawablep->updateSpatialExtents(); - validate_drawable(drawablep); OctreeNode* parent = mOctreeNode->getOctParent(); if (mOctreeNode->isInside(drawablep->getPositionGroup()) && (mOctreeNode->contains(drawablep) || - (drawablep->getBinRadius() > mOctreeNode->getSize().mdV[0] && + (drawablep->getBinRadius() > mOctreeNode->getSize()[0] && parent && parent->getElementCount() >= LL_OCTREE_MAX_CAPACITY))) { unbound(); setState(OBJECT_DIRTY); //setState(GEOM_DIRTY); - validate_drawable(drawablep); return TRUE; } @@ -564,7 +610,6 @@ BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_oc else { drawablep->setSpatialGroup(this); - validate_drawable(drawablep); setState(OBJECT_DIRTY | GEOM_DIRTY); setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS); gPipeline.markRebuild(this, TRUE); @@ -665,7 +710,7 @@ void LLSpatialPartition::rebuildMesh(LLSpatialGroup* group) } -BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxOut) +BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut) { const OctreeNode* node = mOctreeNode; @@ -678,8 +723,8 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO return FALSE; } - LLVector3& newMin = mObjectExtents[0]; - LLVector3& newMax = mObjectExtents[1]; + LLVector4a& newMin = mObjectExtents[0]; + LLVector4a& newMax = mObjectExtents[1]; if (isState(OBJECT_DIRTY)) { //calculate new bounding box @@ -688,10 +733,10 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO //initialize bounding box to first element OctreeNode::const_element_iter i = node->getData().begin(); LLDrawable* drawablep = *i; - const LLVector3* minMax = drawablep->getSpatialExtents(); + const LLVector4a* minMax = drawablep->getSpatialExtents(); - newMin.setVec(minMax[0]); - newMax.setVec(minMax[1]); + newMin = minMax[0]; + newMax = minMax[1]; for (++i; i != node->getData().end(); ++i) { @@ -715,8 +760,10 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO }*/ } - mObjectBounds[0] = (newMin + newMax) * 0.5f; - mObjectBounds[1] = (newMax - newMin) * 0.5f; + mObjectBounds[0].setAdd(newMin, newMax); + mObjectBounds[0].mul(0.5f); + mObjectBounds[1].setSub(newMax, newMin); + mObjectBounds[1].mul(0.5f); } if (empty) @@ -726,17 +773,8 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO } else { - for (U32 i = 0; i < 3; i++) - { - if (newMin.mV[i] < minOut.mV[i]) - { - minOut.mV[i] = newMin.mV[i]; - } - if (newMax.mV[i] > maxOut.mV[i]) - { - maxOut.mV[i] = newMax.mV[i]; - } - } + minOut.setMin(newMin); + maxOut.setMax(newMax); } return TRUE; @@ -827,18 +865,19 @@ BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) return TRUE; } -void LLSpatialGroup::shift(const LLVector3 &offset) +void LLSpatialGroup::shift(const LLVector4a &offset) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - LLVector3d offsetd(offset); - mOctreeNode->setCenter(mOctreeNode->getCenter()+offsetd); + LLVector4a t = mOctreeNode->getCenter(); + t.add(offset); + mOctreeNode->setCenter(t); mOctreeNode->updateMinMax(); - mBounds[0] += offset; - mExtents[0] += offset; - mExtents[1] += offset; - mObjectBounds[0] += offset; - mObjectExtents[0] += offset; - mObjectExtents[1] += offset; + mBounds[0].add(offset); + mExtents[0].add(offset); + mExtents[1].add(offset); + mObjectBounds[0].add(offset); + mObjectExtents[0].add(offset); + mObjectExtents[1].add(offset); //if (!mSpatialPartition->mRenderByGroup) { @@ -850,10 +889,7 @@ void LLSpatialGroup::shift(const LLVector3 &offset) { for (U32 i = 0; i < 8; i++) { - F32* v = mOcclusionVerts+i*3; - v[0] += offset.mV[0]; - v[1] += offset.mV[1]; - v[2] += offset.mV[2]; + mOcclusionVerts[i].add(offset); } } } @@ -1119,8 +1155,6 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : mDepth(0.f), mLastUpdateDistance(-1.f), mLastUpdateTime(gFrameTimeSeconds), - mViewAngle(0.f), - mLastUpdateViewAngle(-1.f), mAtlasList(4), mCurUpdatingTime(0), mCurUpdatingSlotp(NULL), @@ -1129,13 +1163,25 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : sNodeCount++; LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); + mBounds = (LLVector4a*) _mm_malloc(sizeof(LLVector4a) * V4_COUNT, 16); + mExtents = mBounds + EXTENTS; + mObjectBounds = mBounds + OBJECT_BOUNDS; + mObjectExtents = mBounds + OBJECT_EXTENTS; + mViewAngle = mBounds+VIEW_ANGLE; + mLastUpdateViewAngle = mBounds+LAST_VIEW_ANGLE; + + mViewAngle->splat(0.f); + mLastUpdateViewAngle->splat(-1.f); + mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[0] = mObjectBounds[1] = + mObjectExtents[0] = mObjectExtents[1] = *mViewAngle; + sg_assert(mOctreeNode->getListenerCount() == 0); mOctreeNode->addListener(this); setState(SG_INITIAL_STATE_MASK); gPipeline.markRebuild(this, TRUE); - mBounds[0] = LLVector3(node->getCenter()); - mBounds[1] = LLVector3(node->getSize()); + mBounds[0] = node->getCenter(); + mBounds[1] = node->getSize(); part->mLODSeed = (part->mLODSeed+1)%part->mLODPeriod; mLODHash = part->mLODSeed; @@ -1172,8 +1218,8 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) #endif if (!getData().empty()) { - mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].magVec() : - (F32) mOctreeNode->getSize().magVec(); + mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].length3() : + (F32) mOctreeNode->getSize().length3(); mDistance = mSpatialPartition->calcDistance(this, camera); mPixelArea = mSpatialPartition->calcPixelArea(this, camera); } @@ -1181,27 +1227,34 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) { - LLVector3 eye = group->mObjectBounds[0] - camera.getOrigin(); + LLVector4a eye; + LLVector4a origin; + origin.load3(camera.getOrigin().mV); + + eye.setSub(group->mObjectBounds[0], origin); F32 dist = 0.f; if (group->mDrawMap.find(LLRenderPass::PASS_ALPHA) != group->mDrawMap.end()) { - LLVector3 v = eye; - dist = eye.normVec(); + LLVector4a v = eye; + + dist = eye.length3(); + eye.normalize3fast(); if (!group->isState(LLSpatialGroup::ALPHA_DIRTY)) { if (!group->mSpatialPartition->isBridge()) { - LLVector3 view_angle = LLVector3(eye * LLVector3(1,0,0), - eye * LLVector3(0,1,0), - eye * LLVector3(0,0,1)); + LLVector4a view_angle = eye; - if ((view_angle-group->mLastUpdateViewAngle).magVec() > 0.64f) + LLVector4a diff; + diff.setSub(view_angle, *group->mLastUpdateViewAngle); + + if (diff.length3() > 0.64f) { - group->mViewAngle = view_angle; - group->mLastUpdateViewAngle = view_angle; + *group->mViewAngle = view_angle; + *group->mLastUpdateViewAngle = view_angle; //for occasional alpha sorting within the group //NOTE: If there is a trivial way to detect that alpha sorting here would not change the render order, //not setting this node to dirty would be a very good thing @@ -1215,17 +1268,20 @@ F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) LLVector3 at = camera.getAtAxis(); - //front of bounding box - for (U32 i = 0; i < 3; i++) - { - v.mV[i] -= group->mObjectBounds[1].mV[i]*0.25f * at.mV[i]; - } + LLVector4a ata; + ata.load3(at.mV); - group->mDepth = v * at; + LLVector4a t = ata; + //front of bounding box + t.mul(0.25f); + t.mul(group->mObjectBounds[1]); + v.sub(t); + + group->mDepth = v.dot3(ata); } else { - dist = eye.magVec(); + dist = eye.length3(); } if (dist < 16.f) @@ -1378,7 +1434,7 @@ void LLSpatialGroup::destroyGL() } } - delete [] mOcclusionVerts; + _mm_free(mOcclusionVerts); mOcclusionVerts = NULL; for (LLSpatialGroup::element_iter i = getData().begin(); i != getData().end(); ++i) @@ -1421,8 +1477,8 @@ BOOL LLSpatialGroup::rebound() } else { - LLVector3& newMin = mExtents[0]; - LLVector3& newMax = mExtents[1]; + LLVector4a& newMin = mExtents[0]; + LLVector4a& newMax = mExtents[1]; LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(0)->getListener(0); group->clearState(SKIP_FRUSTUM_CHECK); group->rebound(); @@ -1436,26 +1492,19 @@ BOOL LLSpatialGroup::rebound() group = (LLSpatialGroup*) mOctreeNode->getChild(i)->getListener(0); group->clearState(SKIP_FRUSTUM_CHECK); group->rebound(); - const LLVector3& max = group->mExtents[1]; - const LLVector3& min = group->mExtents[0]; + const LLVector4a& max = group->mExtents[1]; + const LLVector4a& min = group->mExtents[0]; - for (U32 j = 0; j < 3; j++) - { - if (max.mV[j] > newMax.mV[j]) - { - newMax.mV[j] = max.mV[j]; - } - if (min.mV[j] < newMin.mV[j]) - { - newMin.mV[j] = min.mV[j]; - } - } + newMax.setMax(max); + newMin.setMin(min); } boundObjects(FALSE, newMin, newMax); - mBounds[0] = (newMin + newMax)*0.5f; - mBounds[1] = (newMax - newMin)*0.5f; + mBounds[0].setAdd(newMin, newMax); + mBounds[0].mul(0.5f); + mBounds[1].setSub(newMax, newMin); + mBounds[1].mul(0.5f); } setState(OCCLUSION_DIRTY); @@ -1540,7 +1589,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) } glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mOcclusionQuery[LLViewerCamera::sCurCameraID]); - glVertexPointer(3, GL_FLOAT, 0, mOcclusionVerts); + glVertexPointer(3, GL_FLOAT, 16, mOcclusionVerts); if (camera->getOrigin().isExactlyZero()) { //origin is invalid, draw entire box glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, @@ -1581,8 +1630,11 @@ LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 LLGLNamePool::registerPool(&sQueryPool); - mOctree = new LLSpatialGroup::OctreeRoot(LLVector3d(0,0,0), - LLVector3d(1,1,1), + LLVector4a center, size; + center.splat(0.f); + size.splat(1.f); + + mOctree = new LLSpatialGroup::OctreeRoot(center,size, NULL); new LLSpatialGroup(mOctree, this); } @@ -1602,7 +1654,6 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); drawablep->updateSpatialExtents(); - validate_drawable(drawablep); //keep drawable from being garbage collected LLPointer ptr = drawablep; @@ -1686,16 +1737,16 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL class LLSpatialShift : public LLSpatialGroup::OctreeTraveler { public: - LLSpatialShift(LLVector3 offset) : mOffset(offset) { } + const LLVector4a& mOffset; + + LLSpatialShift(const LLVector4a& offset) : mOffset(offset) { } virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->shift(mOffset); } - - LLVector3 mOffset; }; -void LLSpatialPartition::shift(const LLVector3 &offset) +void LLSpatialPartition::shift(const LLVector4a &offset) { //shift octree node bounding boxes by offset LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); LLSpatialShift shifter(offset); @@ -1857,7 +1908,7 @@ public: class LLOctreeCullVisExtents: public LLOctreeCullShadow { public: - LLOctreeCullVisExtents(LLCamera* camera, LLVector3& min, LLVector3& max) + LLOctreeCullVisExtents(LLCamera* camera, LLVector4a& min, LLVector4a& max) : LLOctreeCullShadow(camera), mMin(min), mMax(max), mEmpty(TRUE) { } virtual bool earlyFail(LLSpatialGroup* group) @@ -1924,8 +1975,8 @@ public: } BOOL mEmpty; - LLVector3& mMin; - LLVector3& mMax; + LLVector4a& mMin; + LLVector4a& mMax; }; class LLOctreeCullDetectVisible: public LLOctreeCullShadow @@ -2029,6 +2080,11 @@ void drawBox(const LLVector3& c, const LLVector3& r) gGL.end(); } +void drawBox(const LLVector4a& c, const LLVector4a& r) +{ + drawBox(reinterpret_cast(c), reinterpret_cast(r)); +} + void drawBoxOutline(const LLVector3& pos, const LLVector3& size) { LLVector3 v1 = size.scaledVec(LLVector3( 1, 1,1)); @@ -2075,6 +2131,11 @@ void drawBoxOutline(const LLVector3& pos, const LLVector3& size) gGL.end(); } +void drawBoxOutline(const LLVector4a& pos, const LLVector4a& size) +{ + drawBoxOutline(reinterpret_cast(pos), reinterpret_cast(size)); +} + class LLOctreeDirty : public LLOctreeTraveler { public: @@ -2118,14 +2179,21 @@ BOOL LLSpatialPartition::isOcclusionEnabled() BOOL LLSpatialPartition::getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax) { + LLVector4a visMina, visMaxa; + visMina.load3(visMin.mV); + visMaxa.load3(visMax.mV); + { LLFastTimer ftm(FTM_CULL_REBOUND); LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); group->rebound(); } - LLOctreeCullVisExtents vis(&camera, visMin, visMax); + LLOctreeCullVisExtents vis(&camera, visMina, visMaxa); vis.traverse(mOctree); + + visMin.set(visMina.getF32()); + visMax.set(visMina.getF32()); return vis.mEmpty; } @@ -2188,25 +2256,36 @@ BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group) } const F32 vel = SG_OCCLUSION_FUDGE*2.f; - LLVector3 c = group->mBounds[0]; - LLVector3 r = group->mBounds[1] + LLVector3(vel,vel,vel); - + LLVector4a fudge; + fudge.splat(vel); + + const LLVector4a& c = group->mBounds[0]; + LLVector4a r; + r.setAdd(group->mBounds[1], fudge); + /*if (r.magVecSquared() > 1024.0*1024.0) { return TRUE; }*/ - LLVector3 e = camera->getOrigin(); + LLVector4a e; + e.load3(camera->getOrigin().mV); - LLVector3 min = c - r; - LLVector3 max = c + r; + LLVector4a min; + min.setSub(c,r); + LLVector4a max; + max.setAdd(c,r); - for (U32 j = 0; j < 3; j++) + S32 lt = e.lessThan4(min).getComparisonMask() & 0x7; + if (lt) { - if (e.mV[j] < min.mV[j] || e.mV[j] > max.mV[j]) - { - return FALSE; - } + return FALSE; + } + + S32 gt = e.greaterThan4(max).getComparisonMask() & 0x7; + if (gt) + { + return FALSE; } return TRUE; @@ -2411,7 +2490,13 @@ void renderOctree(LLSpatialGroup* group) } gGL.color4fv(col.mV); - drawBox(group->mObjectBounds[0], group->mObjectBounds[1]*1.01f+LLVector3(0.001f, 0.001f, 0.001f)); + LLVector4a fudge; + fudge.splat(0.001f); + LLVector4a size = group->mObjectBounds[1]; + size.mul(1.01f); + size.add(fudge); + + drawBox(group->mObjectBounds[0], fudge); gGL.setSceneBlendType(LLRender::BT_ALPHA); @@ -2442,8 +2527,12 @@ void renderOctree(LLSpatialGroup* group) for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j) { LLDrawInfo* draw_info = *j; - LLVector3 center = (draw_info->mExtents[1] + draw_info->mExtents[0])*0.5f; - LLVector3 size = (draw_info->mExtents[1] - draw_info->mExtents[0])*0.5f; + LLVector4a center; + center.setAdd(draw_info->mExtents[1], draw_info->mExtents[0]); + center.mul(0.5f); + LLVector4a size; + size.setSub(draw_info->mExtents[1], draw_info->mExtents[0]); + size.mul(0.5f); drawBoxOutline(center, size); } } @@ -2493,7 +2582,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera) else if (camera && group->mOcclusionVerts) { LLVertexBuffer::unbind(); - glVertexPointer(3, GL_FLOAT, 0, group->mOcclusionVerts); + glVertexPointer(3, GL_FLOAT, 16, group->mOcclusionVerts); glColor4f(1.0f, 0.f, 0.f, 0.5f); glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_box_fan_indices(camera, group->mBounds[0])); @@ -2572,8 +2661,8 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE) } } - const LLVector3* ext; - LLVector3 pos, size; + const LLVector4a* ext; + LLVector4a pos, size; //render face bounding boxes for (S32 i = 0; i < drawable->getNumFaces(); i++) @@ -2582,20 +2671,21 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE) ext = facep->mExtents; - if (ext[0].isExactlyZero() && ext[1].isExactlyZero()) - { - continue; - } - pos = (ext[0] + ext[1]) * 0.5f; - size = (ext[1] - ext[0]) * 0.5f; + pos.setAdd(ext[0], ext[1]); + pos.mul(0.5f); + size.setSub(ext[1], ext[0]); + size.mul(0.5f); + drawBoxOutline(pos,size); } //render drawable bounding box ext = drawable->getSpatialExtents(); - pos = (ext[0] + ext[1]) * 0.5f; - size = (ext[1] - ext[0]) * 0.5f; + pos.setAdd(ext[0], ext[1]); + pos.mul(0.5f); + size.setSub(ext[1], ext[0]); + size.mul(0.5f); LLViewerObject* vobj = drawable->getVObj(); if (vobj && vobj->onActiveList()) @@ -2651,8 +2741,13 @@ void renderTexturePriority(LLDrawable* drawable) // gGL.color4f(1,0,1,1); //} - LLVector3 center = (facep->mExtents[1]+facep->mExtents[0])*0.5f; - LLVector3 size = (facep->mExtents[1]-facep->mExtents[0])*0.5f + LLVector3(0.01f, 0.01f, 0.01f); + LLVector4a center; + center.setAdd(facep->mExtents[1],facep->mExtents[0]); + center.mul(0.5f); + LLVector4a size; + size.setSub(facep->mExtents[1],facep->mExtents[0]); + size.mul(0.5f); + size.add(LLVector4a(0.01f)); drawBox(center, size); /*S32 boost = imagep->getBoostLevel(); @@ -2676,7 +2771,6 @@ void renderPoints(LLDrawable* drawablep) { gGL.begin(LLRender::POINTS); gGL.color3f(1,1,1); - LLVector3 center(drawablep->getPositionGroup()); for (S32 i = 0; i < drawablep->getNumFaces(); i++) { gGL.vertex3fv(drawablep->getFace(i)->mCenterLocal.mV); @@ -2708,8 +2802,12 @@ void renderShadowFrusta(LLDrawInfo* params) LLGLEnable blend(GL_BLEND); gGL.setSceneBlendType(LLRender::BT_ADD); - LLVector3 center = (params->mExtents[1]+params->mExtents[0])*0.5f; - LLVector3 size = (params->mExtents[1]-params->mExtents[0])*0.5f; + LLVector4a center; + center.setAdd(params->mExtents[1], params->mExtents[0]); + center.mul(0.5f); + LLVector4a size; + size.setSub(params->mExtents[1],params->mExtents[0]); + size.mul(0.5f); if (gPipeline.mShadowCamera[4].AABBInFrustum(center, size)) { @@ -2753,10 +2851,14 @@ void renderLights(LLDrawable* drawablep) pushVerts(drawablep->getFace(i), LLVertexBuffer::MAP_VERTEX); } - const LLVector3* ext = drawablep->getSpatialExtents(); + const LLVector4a* ext = drawablep->getSpatialExtents(); - LLVector3 pos = (ext[0] + ext[1]) * 0.5f; - LLVector3 size = (ext[1] - ext[0]) * 0.5f; + LLVector4a pos; + pos.setAdd(ext[0], ext[1]); + pos.mul(0.5f); + LLVector4a size; + size.setSub(ext[1], ext[0]); + size.mul(0.5f); { LLGLDepthTest depth(GL_FALSE, GL_TRUE); @@ -2766,7 +2868,7 @@ void renderLights(LLDrawable* drawablep) gGL.color4f(1,1,0,1); F32 rad = drawablep->getVOVolume()->getLightRadius(); - drawBoxOutline(pos, LLVector3(rad,rad,rad)); + drawBoxOutline(pos, LLVector4a(rad)); } } @@ -2781,7 +2883,7 @@ public: mDir.setSub(mEnd, mStart); } - void visit(const LLOctreeNode* branch) + void visit(const LLOctreeNode* branch) { LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) branch->getListener(0); @@ -2859,10 +2961,14 @@ void renderRaycast(LLDrawable* drawablep) glPopMatrix(); // draw bounding box of prim - const LLVector3* ext = drawablep->getSpatialExtents(); + const LLVector4a* ext = drawablep->getSpatialExtents(); - LLVector3 pos = (ext[0] + ext[1]) * 0.5f; - LLVector3 size = (ext[1] - ext[0]) * 0.5f; + LLVector4a pos; + pos.setAdd(ext[0], ext[1]); + pos.mul(0.5f); + LLVector4a size; + size.setSub(ext[1], ext[0]); + size.mul(0.5f); LLGLDepthTest depth(GL_FALSE, GL_TRUE); gGL.color4f(0,0.5f,0.5f,1); @@ -2949,8 +3055,8 @@ public: return; } - LLVector3 nodeCenter = group->mBounds[0]; - LLVector3 octCenter = LLVector3(group->mOctreeNode->getCenter()); + LLVector4a nodeCenter = group->mBounds[0]; + LLVector4a octCenter = group->mOctreeNode->getCenter(); group->rebuildGeom(); group->rebuildMesh(); @@ -2979,8 +3085,14 @@ public: if (drawable->isState(LLDrawable::IN_REBUILD_Q2)) { gGL.color4f(0.6f, 0.6f, 0.1f, 1.f); - const LLVector3* ext = drawable->getSpatialExtents(); - drawBoxOutline((ext[0]+ext[1])*0.5f, (ext[1]-ext[0])*0.5f); + const LLVector4a* ext = drawable->getSpatialExtents(); + LLVector4a center; + center.setAdd(ext[0], ext[1]); + center.mul(0.5f); + LLVector4a size; + size.setSub(ext[1], ext[0]); + size.mul(0.5f); + drawBoxOutline(center, size); } } @@ -3211,7 +3323,11 @@ void LLSpatialPartition::renderDebug() void LLSpatialGroup::drawObjectBox(LLColor4 col) { gGL.color4fv(col.mV); - drawBox(mObjectBounds[0], mObjectBounds[1]*1.01f+LLVector3(0.001f, 0.001f, 0.001f)); + LLVector4a size; + size = mObjectBounds[0]; + size.mul(1.01f); + size.add(LLVector4a(0.001f)); + drawBox(mObjectBounds[0], size); } @@ -3271,8 +3387,8 @@ public: LLSpatialGroup* group = (LLSpatialGroup*) child->getListener(0); - LLVector3 size; - LLVector3 center; + LLVector4a size; + LLVector4a center; size = group->mBounds[1]; center = group->mBounds[0]; @@ -3289,7 +3405,11 @@ public: local_end = mEnd * local_matrix; } - if (LLLineSegmentBoxIntersect(local_start, local_end, center, size)) + LLVector4a start, end; + start.load3(local_start.mV); + end.load3(local_end.mV); + + if (LLLineSegmentBoxIntersect(start, end, center, size)) { check(child); } @@ -3380,6 +3500,7 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, mDrawMode(LLRender::TRIANGLES) { mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset); + mExtents = (LLVector4a*) _mm_malloc(sizeof(LLVector4a)*2, 16); mDebugColor = (rand() << 16) + rand(); } @@ -3395,6 +3516,13 @@ LLDrawInfo::~LLDrawInfo() { mFace->setDrawInfo(NULL); } + + if (gDebugGL) + { + gPipeline.checkReferences(this); + } + + _mm_free(mExtents); } void LLDrawInfo::validate() diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 9b252d1035..119945113a 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -45,7 +45,7 @@ #include "lldrawpool.h" #include "llface.h" #include "llviewercamera.h" - +#include "llvector4a.h" #include #define SG_STATE_INHERIT_MASK (OCCLUDED) @@ -57,12 +57,15 @@ class LLSpatialGroup; class LLTextureAtlas; class LLTextureAtlasSlot; +S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad); +S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &radius_squared); + S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad); S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &radius_squared); void pushVerts(LLFace* face, U32 mask); // get index buffer for binary encoded axis vertex buffer given a box at center being viewed by given camera -U8* get_box_fan_indices(LLCamera* camera, const LLVector3& center); +U8* get_box_fan_indices(LLCamera* camera, const LLVector4a& center); class LLDrawInfo : public LLRefCount { @@ -70,6 +73,18 @@ protected: ~LLDrawInfo(); public: + + LLDrawInfo(const LLDrawInfo& rhs) + { + *this = rhs; + } + + const LLDrawInfo& operator=(const LLDrawInfo& rhs) + { + llerrs << "Illegal operation!" << llendl; + return *this; + } + LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, LLViewerTexture* image, LLVertexBuffer* buffer, BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0); @@ -77,6 +92,8 @@ public: void validate(); + LLVector4a* mExtents; + LLPointer mVertexBuffer; LLPointer mTexture; LLColor4U mGlowColor; @@ -95,7 +112,6 @@ public: LLSpatialGroup* mGroup; LLFace* mFace; //associated face F32 mDistance; - LLVector3 mExtents[2]; U32 mDrawMode; struct CompareTexture @@ -158,11 +174,24 @@ public: }; }; +LL_ALIGN_PREFIX(64) class LLSpatialGroup : public LLOctreeListener { friend class LLSpatialPartition; friend class LLOctreeStateCheck; public: + + LLSpatialGroup(const LLSpatialGroup& rhs) + { + *this = rhs; + } + + const LLSpatialGroup& operator=(const LLSpatialGroup& rhs) + { + llerrs << "Illegal operation!" << llendl; + return *this; + } + static U32 sNodeCount; static BOOL sNoDelete; //deletion of spatial groups and draw info not allowed if TRUE @@ -273,8 +302,8 @@ public: BOOL isVisible() const; BOOL isRecentlyVisible() const; void setVisible(); - void shift(const LLVector3 &offset); - BOOL boundObjects(BOOL empty, LLVector3& newMin, LLVector3& newMax); + void shift(const LLVector4a &offset); + BOOL boundObjects(BOOL empty, LLVector4a& newMin, LLVector4a& newMax); void unbound(); BOOL rebound(); void buildOcclusion(); //rebuild mOcclusionVerts @@ -322,6 +351,27 @@ public: void addAtlas(LLTextureAtlas* atlasp, S8 recursive_level = 3) ; void removeAtlas(LLTextureAtlas* atlasp, BOOL remove_group = TRUE, S8 recursive_level = 3) ; void clearAtlasList() ; + +public: + + typedef enum + { + BOUNDS = 0, + EXTENTS = 2, + OBJECT_BOUNDS = 4, + OBJECT_EXTENTS = 6, + VIEW_ANGLE = 8, + LAST_VIEW_ANGLE = 9, + V4_COUNT = 10 + } eV4Index; + + LLVector4a* mBounds; // bounding box (center, size) of this node and all its children (tight fit to objects) + LLVector4a* mExtents; // extents (min, max) of this node and all its children + LLVector4a* mObjectExtents; // extents (min, max) of objects in this node + LLVector4a* mObjectBounds; // bounding box (center, size) of objects in this node + LLVector4a* mViewAngle; + LLVector4a* mLastUpdateViewAngle; + private: U32 mCurUpdatingTime ; //do not make the below two to use LLPointer @@ -349,14 +399,9 @@ public: F32 mBuilt; OctreeNode* mOctreeNode; LLSpatialPartition* mSpatialPartition; - LLVector3 mBounds[2]; // bounding box (center, size) of this node and all its children (tight fit to objects) - LLVector3 mExtents[2]; // extents (min, max) of this node and all its children - LLVector3 mObjectExtents[2]; // extents (min, max) of objects in this node - LLVector3 mObjectBounds[2]; // bounding box (center, size) of objects in this node - LLPointer mVertexBuffer; - F32* mOcclusionVerts; + LLVector4a* mOcclusionVerts; GLuint mOcclusionQuery[LLViewerCamera::NUM_CAMERAS]; U32 mBufferUsage; @@ -367,13 +412,10 @@ public: F32 mDepth; F32 mLastUpdateDistance; F32 mLastUpdateTime; - - LLVector3 mViewAngle; - LLVector3 mLastUpdateViewAngle; F32 mPixelArea; F32 mRadius; -}; +} LL_ALIGN_POSTFIX(64); class LLGeometryManager { @@ -409,7 +451,7 @@ public: // If the drawable moves, move it here. virtual void move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate = FALSE); - virtual void shift(const LLVector3 &offset); + virtual void shift(const LLVector4a &offset); virtual F32 calcDistance(LLSpatialGroup* group, LLCamera& camera); virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera); @@ -467,7 +509,7 @@ public: virtual void makeActive(); virtual void move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate = FALSE); virtual BOOL updateMove(); - virtual void shiftPos(const LLVector3& vec); + virtual void shiftPos(const LLVector4a& vec); virtual void cleanupReferences(); virtual LLSpatialPartition* asPartition() { return this; } virtual LLSpatialBridge* asBridge() { return this; } @@ -658,7 +700,7 @@ class LLHUDBridge : public LLVolumeBridge { public: LLHUDBridge(LLDrawable* drawablep); - virtual void shiftPos(const LLVector3& vec); + virtual void shiftPos(const LLVector4a& vec); virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera); }; @@ -675,7 +717,7 @@ class LLHUDPartition : public LLBridgePartition { public: LLHUDPartition(); - virtual void shift(const LLVector3 &offset); + virtual void shift(const LLVector4a &offset); }; extern const F32 SG_BOX_SIDE; diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 48e4a6ccc7..06431d428f 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -860,8 +860,10 @@ void LLSurfacePatch::updateVisibility() F32 stride_per_distance = DEFAULT_DELTA_ANGLE / mSurfacep->getMetersPerGrid(); U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge(); - LLVector3 center = mCenterRegion + mSurfacep->getOriginAgent(); - LLVector3 radius = LLVector3(mRadius, mRadius, mRadius); + LLVector4a center; + center.load3( (mCenterRegion + mSurfacep->getOriginAgent()).mV); + LLVector4a radius; + radius.splat(mRadius); // sphere in frustum on global coordinates if (LLViewerCamera::getInstance()->AABBInFrustumNoFarClip(center, radius)) diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 1490f8153c..d31b0f51fd 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -900,9 +900,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) render_ui(); } - gPipeline.rebuildGroups(); - + LLSpatialGroup::sNoDelete = FALSE; + gPipeline.clearReferences(); + + gPipeline.rebuildGroups(); } LLAppViewer::instance()->pingMainloopTimeout("Display:FrameStats"); @@ -1000,6 +1002,7 @@ void render_hud_attachments() gPipeline.renderGeom(hud_cam); LLSpatialGroup::sNoDelete = FALSE; + gPipeline.clearReferences(); render_hud_elements(); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 3aecd0175d..0ed2d1da09 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -2863,21 +2863,26 @@ void LLViewerObject::setScale(const LLVector3 &scale, BOOL damped) } } -void LLViewerObject::updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax) -{ - LLVector3 center = getRenderPosition(); - LLVector3 size = getScale(); - newMin.setVec(center-size); - newMax.setVec(center+size); - mDrawable->setPositionGroup((newMin + newMax) * 0.5f); +void LLViewerObject::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax) +{ + LLVector4a center; + center.load3(getRenderPosition().mV); + LLVector4a size; + size.load3(getScale().mV); + newMin.setSub(center, size); + newMax.setAdd(center, size); + + mDrawable->setPositionGroup(center); } F32 LLViewerObject::getBinRadius() { if (mDrawable.notNull()) { - const LLVector3* ext = mDrawable->getSpatialExtents(); - return (ext[1]-ext[0]).magVec(); + const LLVector4a* ext = mDrawable->getSpatialExtents(); + LLVector4a diff; + diff.setSub(ext[1], ext[0]); + return diff.length3(); } return getScale().magVec(); @@ -3469,12 +3474,21 @@ BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector3& start, const LLVect return FALSE; } - const LLVector3* ext = mDrawable->getSpatialExtents(); + const LLVector4a* ext = mDrawable->getSpatialExtents(); + + //VECTORIZE THIS + LLVector4a center; + center.setAdd(ext[1], ext[0]); + center.mul(0.5f); + LLVector4a size; + size.setSub(ext[1], ext[0]); + size.mul(0.5f); - LLVector3 center = (ext[1]+ext[0])*0.5f; - LLVector3 size = (ext[1]-ext[0])*0.5f; + LLVector4a starta, enda; + starta.load3(start.mV); + enda.load3(end.mV); - return LLLineSegmentBoxIntersect(start, end, center, size); + return LLLineSegmentBoxIntersect(starta, enda, center, size); } U8 LLViewerObject::getMediaType() const diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 0fd0cbfa60..6ebd1cbe21 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -373,7 +373,7 @@ public: void markForUpdate(BOOL priority); void updateVolume(const LLVolumeParams& volume_params); - virtual void updateSpatialExtents(LLVector3& min, LLVector3& max); + virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max); virtual F32 getBinRadius(); LLBBox getBoundingBoxAgent() const; @@ -386,7 +386,7 @@ public: void clearDrawableState(U32 state, BOOL recursive = TRUE); // Called when the drawable shifts - virtual void onShift(const LLVector3 &shift_vector) { } + virtual void onShift(const LLVector4a &shift_vector) { } ////////////////////////////////////// // diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index 6b480ccf8e..41848e8b7a 100644 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -161,8 +161,8 @@ LLViewerPartGroup::LLViewerPartGroup(const LLVector3 ¢er_agent, const F32 bo if (group != NULL) { - LLVector3 center(group->mOctreeNode->getCenter()); - LLVector3 size(group->mOctreeNode->getSize()); + LLVector3 center(group->mOctreeNode->getCenter().getF32()); + LLVector3 size(group->mOctreeNode->getSize().getF32()); size += LLVector3(0.01f, 0.01f, 0.01f); mMinObjPos = center - size; mMaxObjPos = center + size; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index ac109771dd..b097461822 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1286,41 +1286,46 @@ void LLVOAvatar::updateDrawable(BOOL force_damped) clearChanged(SHIFTED); } -void LLVOAvatar::onShift(const LLVector3& shift_vector) +void LLVOAvatar::onShift(const LLVector4a& shift_vector) { - mLastAnimExtents[0] += shift_vector; - mLastAnimExtents[1] += shift_vector; + const LLVector3& shift = reinterpret_cast(shift_vector); + mLastAnimExtents[0] += shift; + mLastAnimExtents[1] += shift; mNeedsImpostorUpdate = TRUE; mNeedsAnimUpdate = TRUE; } -void LLVOAvatar::updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax) +void LLVOAvatar::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax) { if (isImpostor() && !needsImpostorUpdate()) { LLVector3 delta = getRenderPosition() - - ((LLVector3(mDrawable->getPositionGroup())-mImpostorOffset)); + ((LLVector3(mDrawable->getPositionGroup().getF32())-mImpostorOffset)); - newMin = mLastAnimExtents[0] + delta; - newMax = mLastAnimExtents[1] + delta; + newMin.load3( (mLastAnimExtents[0] + delta).mV); + newMax.load3( (mLastAnimExtents[1] + delta).mV); } else { getSpatialExtents(newMin,newMax); - mLastAnimExtents[0] = newMin; - mLastAnimExtents[1] = newMax; - LLVector3 pos_group = (newMin+newMax)*0.5f; - mImpostorOffset = pos_group-getRenderPosition(); + mLastAnimExtents[0].set(newMin.getF32()); + mLastAnimExtents[1].set(newMax.getF32()); + LLVector4a pos_group; + pos_group.setAdd(newMin,newMax); + pos_group.mul(0.5f); + mImpostorOffset = LLVector3(pos_group.getF32())-getRenderPosition(); mDrawable->setPositionGroup(pos_group); } } -void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax) +void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { - LLVector3 buffer(0.25f, 0.25f, 0.25f); - LLVector3 pos = getRenderPosition(); - newMin = pos - buffer; - newMax = pos + buffer; + LLVector4a buffer(0.25f); + LLVector4a pos; + pos.load3(getRenderPosition().mV); + newMin.setSub(pos, buffer); + newMax.setAdd(pos, buffer); + float max_attachment_span = DEFAULT_MAX_PRIM_SCALE * 5.0f; //stretch bounding box by joint positions @@ -1329,12 +1334,20 @@ void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax) LLPolyMesh* mesh = i->second; for (S32 joint_num = 0; joint_num < mesh->mJointRenderData.count(); joint_num++) { - update_min_max(newMin, newMax, - mesh->mJointRenderData[joint_num]->mWorldMatrix->getTranslation()); + LLVector4a trans; + trans.load3( mesh->mJointRenderData[joint_num]->mWorldMatrix->getTranslation().mV); + update_min_max(newMin, newMax, trans); } } - mPixelArea = LLPipeline::calcPixelArea((newMin+newMax)*0.5f, (newMax-newMin)*0.5f, *LLViewerCamera::getInstance()); + LLVector4a center, size; + center.setAdd(newMin, newMax); + center.mul(0.5f); + + size.setSub(newMax,newMin); + size.mul(0.5f); + + mPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance()); //stretch bounding box by attachments for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); @@ -1361,15 +1374,17 @@ void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax) LLSpatialBridge* bridge = drawable->getSpatialBridge(); if (bridge) { - const LLVector3* ext = bridge->getSpatialExtents(); - LLVector3 distance = (ext[1] - ext[0]); + const LLVector4a* ext = bridge->getSpatialExtents(); + LLVector4a distance; + distance.setSub(ext[1], ext[0]); + LLVector4a max_span(max_attachment_span); + + S32 lt = distance.lessThan4(max_span).getComparisonMask() & 0x7; // Only add the prim to spatial extents calculations if it isn't a megaprim. // max_attachment_span calculated at the start of the function // (currently 5 times our max prim size) - if (distance.mV[0] < max_attachment_span - && distance.mV[1] < max_attachment_span - && distance.mV[2] < max_attachment_span) + if (lt == 0x7) { update_min_max(newMin,newMax,ext[0]); update_min_max(newMin,newMax,ext[1]); @@ -1381,8 +1396,9 @@ void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax) } //pad bounding box - newMin -= buffer; - newMax += buffer; + + newMin.sub(buffer); + newMax.add(buffer); } //----------------------------------------------------------------------------- @@ -2371,7 +2387,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) if (isImpostor() && !mNeedsImpostorUpdate) { - LLVector3 ext[2]; + LLVector4a ext[2]; F32 distance; LLVector3 angle; @@ -2400,12 +2416,22 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) } else { + //VECTORIZE THIS getSpatialExtents(ext[0], ext[1]); - if ((ext[1]-mImpostorExtents[1]).length() > 0.05f || - (ext[0]-mImpostorExtents[0]).length() > 0.05f) + LLVector4a diff; + diff.setSub(ext[1], mImpostorExtents[1]); + if (diff.length3() > 0.05f) { mNeedsImpostorUpdate = TRUE; } + else + { + diff.setSub(ext[0], mImpostorExtents[0]); + if (diff.length3() > 0.05f) + { + mNeedsImpostorUpdate = TRUE; + } + } } } } @@ -5151,9 +5177,13 @@ void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent) return; } - const LLVector3* ext = mDrawable->getSpatialExtents(); - LLVector3 center = (ext[1] + ext[0]) * 0.5f; - LLVector3 size = (ext[1]-ext[0])*0.5f; + const LLVector4a* ext = mDrawable->getSpatialExtents(); + LLVector4a center; + center.setAdd(ext[1], ext[0]); + center.mul(0.5f); + LLVector4a size; + size.setSub(ext[1], ext[0]); + size.mul(0.5f); mImpostorPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance()); @@ -5165,7 +5195,7 @@ void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent) } else { - F32 radius = size.length(); + F32 radius = size.length3(); mAppAngle = (F32) atan2( radius, range) * RAD_TO_DEG; } @@ -7546,9 +7576,9 @@ void LLVOAvatar::cacheImpostorValues() getImpostorValues(mImpostorExtents, mImpostorAngle, mImpostorDistance); } -void LLVOAvatar::getImpostorValues(LLVector3* extents, LLVector3& angle, F32& distance) const +void LLVOAvatar::getImpostorValues(LLVector4a* extents, LLVector3& angle, F32& distance) const { - const LLVector3* ext = mDrawable->getSpatialExtents(); + const LLVector4a* ext = mDrawable->getSpatialExtents(); extents[0] = ext[0]; extents[1] = ext[1]; diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index a851b7a150..71c3ed1cc2 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -127,7 +127,7 @@ public: virtual BOOL isActive() const; // Whether this object needs to do an idleUpdate. virtual void updateTextures(); virtual S32 setTETexture(const U8 te, const LLUUID& uuid); // If setting a baked texture, need to request it from a non-local sim. - virtual void onShift(const LLVector3& shift_vector); + virtual void onShift(const LLVector4a& shift_vector); virtual U32 getPartitionType() const; virtual const LLVector3 getRenderPosition() const; virtual void updateDrawable(BOOL force_damped); @@ -135,8 +135,8 @@ public: virtual BOOL updateGeometry(LLDrawable *drawable); virtual void setPixelAreaAndAngle(LLAgent &agent); virtual void updateRegion(LLViewerRegion *regionp); - virtual void updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax); - virtual void getSpatialExtents(LLVector3& newMin, LLVector3& newMax); + virtual void updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax); + virtual void getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); virtual BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face = -1, // which face to check, -1 = ALL_SIDES BOOL pick_transparent = FALSE, @@ -391,7 +391,7 @@ public: BOOL needsImpostorUpdate() const; const LLVector3& getImpostorOffset() const; const LLVector2& getImpostorDim() const; - void getImpostorValues(LLVector3* extents, LLVector3& angle, F32& distance) const; + void getImpostorValues(LLVector4a* extents, LLVector3& angle, F32& distance) const; void cacheImpostorValues(); void setImpostorDim(const LLVector2& dim); static void resetImpostors(); @@ -402,7 +402,7 @@ private: LLVector3 mImpostorOffset; LLVector2 mImpostorDim; BOOL mNeedsAnimUpdate; - LLVector3 mImpostorExtents[2]; + LL_ALIGN_16(LLVector4a mImpostorExtents[2]); LLVector3 mImpostorAngle; F32 mImpostorDistance; F32 mImpostorPixelArea; diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 3ba4ecad0c..b5fd8182c6 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -79,12 +79,14 @@ F32 LLVOPartGroup::getBinRadius() return mScale.mV[0]*2.f; } -void LLVOPartGroup::updateSpatialExtents(LLVector3& newMin, LLVector3& newMax) +void LLVOPartGroup::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { const LLVector3& pos_agent = getPositionAgent(); - newMin = pos_agent - mScale; - newMax = pos_agent + mScale; - mDrawable->setPositionGroup(pos_agent); + newMin.load3( (pos_agent - mScale).mV); + newMax.load3( (pos_agent + mScale).mV); + LLVector4a pos; + pos.load3(pos_agent.mV); + mDrawable->setPositionGroup(pos); } BOOL LLVOPartGroup::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h index 18583b4be9..771ae1c1eb 100644 --- a/indra/newview/llvopartgroup.h +++ b/indra/newview/llvopartgroup.h @@ -57,7 +57,7 @@ public: BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); virtual F32 getBinRadius(); - virtual void updateSpatialExtents(LLVector3& newMin, LLVector3& newMax); + virtual void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); virtual U32 getPartitionType() const; /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index eef62ddf1a..02e7e7e60f 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -995,7 +995,13 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect //step one meter at a time until intersection point found - const LLVector3* ext = mDrawable->getSpatialExtents(); + //VECTORIZE THIS + const LLVector4a* exta = mDrawable->getSpatialExtents(); + + LLVector3 ext[2]; + ext[0].set(exta[0].getF32()); + ext[1].set(exta[1].getF32()); + F32 rad = (delta*tdelta).magVecSquared(); F32 t = 0.f; @@ -1057,13 +1063,16 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect return FALSE; } -void LLVOSurfacePatch::updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax) +void LLVOSurfacePatch::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax) { LLVector3 posAgent = getPositionAgent(); LLVector3 scale = getScale(); - newMin = posAgent-scale*0.5f; // Changing to 2.f makes the culling a -little- better, but still wrong - newMax = posAgent+scale*0.5f; - mDrawable->setPositionGroup((newMin+newMax)*0.5f); + newMin.load3( (posAgent-scale*0.5f).mV); // Changing to 2.f makes the culling a -little- better, but still wrong + newMax.load3( (posAgent+scale*0.5f).mV); + LLVector4a pos; + pos.setAdd(newMin,newMax); + pos.mul(0.5f); + mDrawable->setPositionGroup(pos); } U32 LLVOSurfacePatch::getPartitionType() const diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h index 10a5888526..15442e1947 100644 --- a/indra/newview/llvosurfacepatch.h +++ b/indra/newview/llvosurfacepatch.h @@ -78,7 +78,7 @@ public: /*virtual*/ void updateTextures(); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area - /*virtual*/ void updateSpatialExtents(LLVector3& newMin, LLVector3& newMax); + /*virtual*/ void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. void setPatch(LLSurfacePatch *patchp); diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index b89c0cd638..d564643161 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -1238,7 +1238,7 @@ void LLVOTree::updateRadius() mDrawable->setRadius(32.0f); } -void LLVOTree::updateSpatialExtents(LLVector3& newMin, LLVector3& newMax) +void LLVOTree::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { F32 radius = getScale().length()*0.05f; LLVector3 center = getRenderPosition(); @@ -1248,9 +1248,11 @@ void LLVOTree::updateSpatialExtents(LLVector3& newMin, LLVector3& newMax) center += LLVector3(0, 0, size.mV[2]) * getRotation(); - newMin.set(center-size); - newMax.set(center+size); - mDrawable->setPositionGroup(center); + newMin.load3((center-size).mV); + newMax.load3((center+size).mV); + LLVector4a pos; + pos.load3(center.mV); + mDrawable->setPositionGroup(pos); } BOOL LLVOTree::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp, @@ -1263,8 +1265,13 @@ BOOL LLVOTree::lineSegmentIntersect(const LLVector3& start, const LLVector3& end return FALSE; } - const LLVector3* ext = mDrawable->getSpatialExtents(); + const LLVector4a* exta = mDrawable->getSpatialExtents(); + //VECTORIZE THIS + LLVector3 ext[2]; + ext[0].set(exta[0].getF32()); + ext[1].set(exta[1].getF32()); + LLVector3 center = (ext[1]+ext[0])*0.5f; LLVector3 size = (ext[1]-ext[0]); diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h index feac9e0675..2ce1b03d26 100644 --- a/indra/newview/llvotree.h +++ b/indra/newview/llvotree.h @@ -73,7 +73,7 @@ public: /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); - /*virtual*/ void updateSpatialExtents(LLVector3 &min, LLVector3 &max); + /*virtual*/ void updateSpatialExtents(LLVector4a &min, LLVector4a &max); virtual U32 getPartitionType() const; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index a9f3abeef8..db9e0b88e1 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -701,7 +701,7 @@ void LLVOVolume::updateTextureVirtualSize() const LLTextureEntry *te = face->getTextureEntry(); LLViewerTexture *imagep = face->getTexture(); if (!imagep || !te || - face->mExtents[0] == face->mExtents[1]) + face->mExtents[0].equal3(face->mExtents[1])) { continue; } @@ -1332,7 +1332,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) { BOOL res = TRUE; - LLVector3 min,max; + LLVector4a min,max; BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION); @@ -1356,17 +1356,8 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) } else { - for (U32 i = 0; i < 3; i++) - { - if (face->mExtents[0].mV[i] < min.mV[i]) - { - min.mV[i] = face->mExtents[0].mV[i]; - } - if (face->mExtents[1].mV[i] > max.mV[i]) - { - max.mV[i] = face->mExtents[1].mV[i]; - } - } + min.setMin(face->mExtents[0]); + max.setMax(face->mExtents[1]); } } } @@ -1374,7 +1365,9 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) if (rebuild) { mDrawable->setSpatialExtents(min,max); - mDrawable->setPositionGroup((min+max)*0.5f); + min.add(max); + min.mul(0.5f); + mDrawable->setPositionGroup(min); } updateRadius(); @@ -3007,7 +3000,7 @@ void LLVOVolume::setSelected(BOOL sel) } } -void LLVOVolume::updateSpatialExtents(LLVector3& newMin, LLVector3& newMax) +void LLVOVolume::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { } @@ -3039,7 +3032,7 @@ F32 LLVOVolume::getBinRadius() } } - const LLVector3* ext = mDrawable->getSpatialExtents(); + const LLVector4a* ext = mDrawable->getSpatialExtents(); BOOL shrink_wrap = mDrawable->isAnimating(); BOOL alpha_wrap = FALSE; @@ -3071,7 +3064,10 @@ F32 LLVOVolume::getBinRadius() } else if (shrink_wrap) { - radius = (ext[1]-ext[0]).length()*0.5f; + LLVector4a rad; + rad.setSub(ext[1], ext[0]); + + radius = rad.length3()*0.5f; } else if (mDrawable->isStatic()) { @@ -3107,7 +3103,7 @@ const LLVector3 LLVOVolume::getPivotPositionAgent() const return LLViewerObject::getPivotPositionAgent(); } -void LLVOVolume::onShift(const LLVector3 &shift_vector) +void LLVOVolume::onShift(const LLVector4a &shift_vector) { if (mVolumeImpl) { @@ -3610,7 +3606,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } } } - } continue; @@ -4217,7 +4212,7 @@ LLHUDPartition::LLHUDPartition() mLODPeriod = 1; } -void LLHUDPartition::shift(const LLVector3 &offset) +void LLHUDPartition::shift(const LLVector4a &offset) { //HUD objects don't shift with region crossing. That would be silly. } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 2776988a12..d5606034d0 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -66,7 +66,7 @@ public: virtual void onSetVolume(const LLVolumeParams &volume_params, const S32 detail) = 0; virtual void onSetScale(const LLVector3 &scale, BOOL damped) = 0; virtual void onParameterChanged(U16 param_type, LLNetworkData *data, BOOL in_use, bool local_origin) = 0; - virtual void onShift(const LLVector3 &shift_vector) = 0; + virtual void onShift(const LLVector4a &shift_vector) = 0; virtual bool isVolumeUnique() const = 0; // Do we need a unique LLVolume instance? virtual bool isVolumeGlobal() const = 0; // Are we in global space? virtual bool isActive() const = 0; // Is this object currently active? @@ -145,7 +145,7 @@ public: void markForUpdate(BOOL priority) { LLViewerObject::markForUpdate(priority); mVolumeChanged = TRUE; } - /*virtual*/ void onShift(const LLVector3 &shift_vector); // Called when the drawable shifts + /*virtual*/ void onShift(const LLVector4a &shift_vector); // Called when the drawable shifts /*virtual*/ void parameterChanged(U16 param_type, bool local_origin); /*virtual*/ void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin); @@ -201,7 +201,7 @@ public: void regenFaces(); BOOL genBBoxes(BOOL force_global); void preRebuild(); - virtual void updateSpatialExtents(LLVector3& min, LLVector3& max); + virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max); virtual F32 getBinRadius(); virtual U32 getPartitionType() const; diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index a8c4625f6e..7c1b22d432 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -258,15 +258,21 @@ void LLVOWater::setIsEdgePatch(const BOOL edge_patch) mIsEdgePatch = edge_patch; } -void LLVOWater::updateSpatialExtents(LLVector3 &newMin, LLVector3& newMax) +void LLVOWater::updateSpatialExtents(LLVector4a &newMin, LLVector4a& newMax) { - LLVector3 pos = getPositionAgent(); - LLVector3 scale = getScale(); - - newMin = pos - scale * 0.5f; - newMax = pos + scale * 0.5f; + LLVector4a pos; + pos.load3(getPositionAgent().mV); + LLVector4a scale; + scale.load3(getScale().mV); + scale.mul(0.5f); + + newMin.setSub(pos, scale); + newMax.setAdd(pos, scale); + + pos.setAdd(newMin,newMax); + pos.mul(0.5f); - mDrawable->setPositionGroup((newMin + newMax) * 0.5f); + mDrawable->setPositionGroup(pos); } U32 LLVOWater::getPartitionType() const diff --git a/indra/newview/llvowater.h b/indra/newview/llvowater.h index 3cc031e589..a868afe58b 100644 --- a/indra/newview/llvowater.h +++ b/indra/newview/llvowater.h @@ -66,7 +66,7 @@ public: /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); - /*virtual*/ void updateSpatialExtents(LLVector3& newMin, LLVector3& newMax); + /*virtual*/ void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); /*virtual*/ void updateTextures(); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 91c3805d3b..01027e5be6 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1508,11 +1508,214 @@ F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera return radius*radius * F_PI; } +//static +F32 LLPipeline::calcPixelArea(const LLVector4a& center, const LLVector4a& size, LLCamera &camera) +{ + LLVector4a origin; + origin.load3(camera.getOrigin().mV); + + LLVector4a lookAt; + lookAt.setSub(center, origin); + F32 dist = lookAt.length3(); + + //ramp down distance for nearby objects + //shrink dist by dist/16. + if (dist < 16.f) + { + dist /= 16.f; + dist *= dist; + dist *= 16.f; + } + + //get area of circle around node + F32 app_angle = atanf(size.length3()/dist); + F32 radius = app_angle*LLDrawable::sCurPixelAngle; + return radius*radius * F_PI; +} + void LLPipeline::grabReferences(LLCullResult& result) { sCull = &result; } +void LLPipeline::clearReferences() +{ + sCull = NULL; +} + +void check_references(LLSpatialGroup* group, LLDrawable* drawable) +{ + for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + { + if (drawable == *i) + { + llerrs << "LLDrawable deleted while actively reference by LLPipeline." << llendl; + } + } +} + +void check_references(LLDrawable* drawable, LLFace* face) +{ + for (S32 i = 0; i < drawable->getNumFaces(); ++i) + { + if (drawable->getFace(i) == face) + { + llerrs << "LLFace deleted while actively referenced by LLPipeline." << llendl; + } + } +} + +void check_references(LLSpatialGroup* group, LLFace* face) +{ + for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + { + LLDrawable* drawable = *i; + check_references(drawable, face); + } +} + +void LLPipeline::checkReferences(LLFace* face) +{ +#if 0 + if (sCull) + { + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, face); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, face); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, face); + } + + for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) + { + LLDrawable* drawable = *iter; + check_references(drawable, face); + } + } +#endif +} + +void LLPipeline::checkReferences(LLDrawable* drawable) +{ +#if 0 + if (sCull) + { + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, drawable); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, drawable); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, drawable); + } + + for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) + { + if (drawable == *iter) + { + llerrs << "LLDrawable deleted while actively referenced by LLPipeline." << llendl; + } + } + } +#endif +} + +void check_references(LLSpatialGroup* group, LLDrawInfo* draw_info) +{ + for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) + { + LLSpatialGroup::drawmap_elem_t& draw_vec = i->second; + for (LLSpatialGroup::drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j) + { + LLDrawInfo* params = *j; + if (params == draw_info) + { + llerrs << "LLDrawInfo deleted while actively referenced by LLPipeline." << llendl; + } + } + } +} + + +void LLPipeline::checkReferences(LLDrawInfo* draw_info) +{ +#if 0 + if (sCull) + { + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, draw_info); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, draw_info); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, draw_info); + } + } +#endif +} + +void LLPipeline::checkReferences(LLSpatialGroup* group) +{ +#if 0 + if (sCull) + { + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + if (group == *iter) + { + llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl; + } + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + if (group == *iter) + { + llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl; + } + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + if (group == *iter) + { + llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl; + } + } + } +#endif +} + + BOOL LLPipeline::visibleObjectsInFrustum(LLCamera& camera) { for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); @@ -1714,7 +1917,7 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) } if (sMinRenderSize > 0.f && - llmax(llmax(group->mBounds[1].mV[0], group->mBounds[1].mV[1]), group->mBounds[1].mV[2]) < sMinRenderSize) + llmax(llmax(group->mBounds[1][0], group->mBounds[1][1]), group->mBounds[1][2]) < sMinRenderSize) { return; } @@ -2100,6 +2303,9 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) glClear(GL_DEPTH_BUFFER_BIT); gDepthDirty = TRUE; + LLVector4a offseta; + offseta.load3(offset.mV); + for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); iter != mShiftList.end(); iter++) { @@ -2108,7 +2314,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) { continue; } - drawablep->shiftPos(offset); + drawablep->shiftPos(offseta); drawablep->clearState(LLDrawable::ON_SHIFT_LIST); } mShiftList.resize(0); @@ -2122,7 +2328,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) LLSpatialPartition* part = region->getSpatialPartition(i); if (part) { - part->shift(offset); + part->shift(offseta); } } } @@ -2659,8 +2865,10 @@ void LLPipeline::postSort(LLCamera& camera) { if (sMinRenderSize > 0.f) { - LLVector3 bounds = (*k)->mExtents[1]-(*k)->mExtents[0]; - if (llmax(llmax(bounds.mV[0], bounds.mV[1]), bounds.mV[2]) > sMinRenderSize) + LLVector4a bounds; + bounds.setSub((*k)->mExtents[1],(*k)->mExtents[0]); + + if (llmax(llmax(bounds[0], bounds[1]), bounds[2]) > sMinRenderSize) { sCull->pushDrawInfo(j->first, *k); } @@ -6770,8 +6978,9 @@ void LLPipeline::renderDeferredLighting() } - LLVector3 center = drawablep->getPositionAgent(); - F32* c = center.mV; + LLVector4a center; + center.load3(drawablep->getPositionAgent().mV); + const F32* c = center.getF32(); F32 s = volume->getLightRadius()*1.5f; LLColor3 col = volume->getLightColor(); @@ -6787,7 +6996,9 @@ void LLPipeline::renderDeferredLighting() continue; } - if (camera->AABBInFrustumNoFarClip(center, LLVector3(s,s,s)) == 0) + LLVector4a sa; + sa.splat(s); + if (camera->AABBInFrustumNoFarClip(center, sa) == 0) { continue; } @@ -6865,8 +7076,9 @@ void LLPipeline::renderDeferredLighting() LLVOVolume* volume = drawablep->getVOVolume(); - LLVector3 center = drawablep->getPositionAgent(); - F32* c = center.mV; + LLVector4a center; + center.load3(drawablep->getPositionAgent().mV); + const F32* c = center.getF32(); F32 s = volume->getLightRadius()*1.5f; sVisibleLightCount++; @@ -8952,7 +9164,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) stateSort(*LLViewerCamera::getInstance(), result); - const LLVector3* ext = avatar->mDrawable->getSpatialExtents(); + const LLVector4a* ext = avatar->mDrawable->getSpatialExtents(); LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset()); LLCamera camera = *viewer_camera; @@ -8961,18 +9173,23 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) LLVector2 tdim; - LLVector3 half_height = (ext[1]-ext[0])*0.5f; - LLVector3 left = camera.getLeftAxis(); - left *= left; - left.normalize(); + LLVector4a half_height; + half_height.setSub(ext[1], ext[0]); + half_height.mul(0.5f); + + LLVector4a left; + left.load3(camera.getLeftAxis().mV); + left.mul(left); + left.normalize3fast(); - LLVector3 up = camera.getUpAxis(); - up *= up; - up.normalize(); + LLVector4a up; + up.load3(camera.getUpAxis().mV); + up.mul(up); + up.normalize3fast(); - tdim.mV[0] = fabsf(half_height * left); - tdim.mV[1] = fabsf(half_height * up); + tdim.mV[0] = fabsf(half_height.dot3(left)); + tdim.mV[1] = fabsf(half_height.dot3(up)); glMatrixMode(GL_PROJECTION); glPushMatrix(); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index c9384f5ba2..52f943cd1d 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -217,6 +217,7 @@ public: //calculate pixel area of given box from vantage point of given camera static F32 calcPixelArea(LLVector3 center, LLVector3 size, LLCamera& camera); + static F32 calcPixelArea(const LLVector4a& center, const LLVector4a& size, LLCamera &camera); void stateSort(LLCamera& camera, LLCullResult& result); void stateSort(LLSpatialGroup* group, LLCamera& camera); @@ -229,6 +230,14 @@ public: void renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture); void grabReferences(LLCullResult& result); + void clearReferences(); + + //check references will assert that there are no references in sCullResult to the provided data + void checkReferences(LLFace* face); + void checkReferences(LLDrawable* drawable); + void checkReferences(LLDrawInfo* draw_info); + void checkReferences(LLSpatialGroup* group); + void renderGeom(LLCamera& camera, BOOL forceVBOUpdate = FALSE); void renderGeomDeferred(LLCamera& camera); -- cgit v1.3 From 7db6a5a64d8eacb63b45dc7cc48bdd681f3e19af Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 4 Jun 2010 00:10:05 -0500 Subject: Disable octree paranoia checks. --- indra/llmath/lloctree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index ae2259dba0..f61ce6ce05 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -45,7 +45,7 @@ #define OCT_ERRS LL_WARNS("OctreeErrors") #endif -#define LL_OCTREE_PARANOIA_CHECK 1 +#define LL_OCTREE_PARANOIA_CHECK 0 #if LL_DARWIN #define LL_OCTREE_MAX_CAPACITY 32 #else -- cgit v1.3 From 087b7499082c7f0ae867990a102bc8f90a83471d Mon Sep 17 00:00:00 2001 From: Tofu Linden Date: Fri, 4 Jun 2010 08:46:00 +0100 Subject: fix scoping issues for gcc --- indra/llmath/lloctree.h | 2 +- indra/llmath/llvolume.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index f61ce6ce05..df77971204 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -640,7 +640,7 @@ public: const LLVector4a& v = data->getPositionGroup(); LLVector4a val; - val.setSub(v, mD[CENTER]); + val.setSub(v, BaseType::mD[BaseType::CENTER]); val.setAbs(val); S32 lt = val.lessThan4(MAX_MAG).getComparisonMask() & 0x7; diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 72833c019f..ef1ab57036 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4406,7 +4406,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en face.createOctree(); } - LLVector4a* p = (LLVector4a*) face.mPositions; + //LLVector4a* p = (LLVector4a*) face.mPositions; LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, bi_normal); intersect.traverse(face.mOctree); -- cgit v1.3 From dc2f50642bf6c785263d91ca53ec337f3898b990 Mon Sep 17 00:00:00 2001 From: Tofu Linden Date: Fri, 4 Jun 2010 08:54:03 +0100 Subject: lots of _mm_malloc and _mm_free -> ll_aligned_malloc_16 and ll_aligned_free_16 more to come. --- indra/llcommon/llmemory.h | 2 +- indra/llmath/lloctree.h | 4 +-- indra/llmath/llvolume.cpp | 86 +++++++++++++++++++++++------------------------ 3 files changed, 46 insertions(+), 46 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 117268cfe7..93dd7a7fe3 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -34,7 +34,7 @@ #include -inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed with ll_aligned_free(). +inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed with ll_aligned_free_16(). { #if defined(LL_WINDOWS) return _mm_malloc(size, 16); diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index df77971204..59828ae565 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -102,7 +102,7 @@ public: : mParent((oct_node*)parent), mOctant(octant) { - mD = (LLVector4a*) _mm_malloc(sizeof(LLVector4a)*4, 16); + mD = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*4); mD[CENTER] = center; mD[SIZE] = size; @@ -125,7 +125,7 @@ public: delete getChild(i); } - _mm_free(mD); + ll_aligned_free_16(mD); } inline const BaseType* getParent() const { return mParent; } diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index ef1ab57036..a8684759f3 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1987,7 +1987,7 @@ BOOL LLVolume::generate() void LLVolumeFace::VertexData::init() { - mData = (LLVector4a*) _mm_malloc(32, 16); + mData = (LLVector4a*) ll_aligned_malloc_16(32); } LLVolumeFace::VertexData::VertexData() @@ -2004,7 +2004,7 @@ LLVolumeFace::VertexData::VertexData(const VertexData& rhs) LLVolumeFace::VertexData::~VertexData() { - _mm_free(mData); + ll_aligned_free_16(mData); } LLVector4a& LLVolumeFace::VertexData::getPosition() @@ -5196,7 +5196,7 @@ LLVolumeFace::LLVolumeFace() : mWeights(NULL), mOctree(NULL) { - mExtents = (LLVector4a*) _mm_malloc(48, 16); + mExtents = (LLVector4a*) ll_aligned_malloc_16(48); mCenter = mExtents+2; } @@ -5217,7 +5217,7 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src) mWeights(NULL), mOctree(NULL) { - mExtents = (LLVector4a*) _mm_malloc(48, 16); + mExtents = (LLVector4a*) ll_aligned_malloc_16(48); mCenter = mExtents+2; *this = src; } @@ -5264,7 +5264,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) } else { - _mm_free(mBinormals); + ll_aligned_free_16(mBinormals); mBinormals = NULL; } @@ -5275,7 +5275,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) } else { - _mm_free(mWeights); + ll_aligned_free_16(mWeights); mWeights = NULL; } } @@ -5295,7 +5295,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) LLVolumeFace::~LLVolumeFace() { - _mm_free(mExtents); + ll_aligned_free_16(mExtents); mExtents = NULL; freeData(); @@ -5303,17 +5303,17 @@ LLVolumeFace::~LLVolumeFace() void LLVolumeFace::freeData() { - _mm_free(mPositions); + ll_aligned_free_16(mPositions); mPositions = NULL; - _mm_free(mNormals); + ll_aligned_free_16(mNormals); mNormals = NULL; - _mm_free(mTexCoords); + ll_aligned_free_16(mTexCoords); mTexCoords = NULL; - _mm_free(mIndices); + ll_aligned_free_16(mIndices); mIndices = NULL; - _mm_free(mBinormals); + ll_aligned_free_16(mBinormals); mBinormals = NULL; - _mm_free(mWeights); + ll_aligned_free_16(mWeights); mWeights = NULL; delete mOctree; @@ -6082,21 +6082,21 @@ void LLVolumeFace::createBinormals() void LLVolumeFace::resizeVertices(S32 num_verts) { - _mm_free(mPositions); - _mm_free(mNormals); - _mm_free(mBinormals); - _mm_free(mTexCoords); + ll_aligned_free_16(mPositions); + ll_aligned_free_16(mNormals); + ll_aligned_free_16(mBinormals); + ll_aligned_free_16(mTexCoords); mBinormals = NULL; if (num_verts) { - mPositions = (LLVector4a*) _mm_malloc(num_verts*16, 16); - mNormals = (LLVector4a*) _mm_malloc(num_verts*16, 16); + mPositions = (LLVector4a*) ll_aligned_malloc_16(num_verts*16); + mNormals = (LLVector4a*) ll_aligned_malloc_16(num_verts*16); //pad texture coordinate block end to allow for QWORD reads S32 size = ((num_verts*8) + 0xF) & ~0xF; - mTexCoords = (LLVector2*) _mm_malloc(size, 16); + mTexCoords = (LLVector2*) ll_aligned_malloc_16(size); } else { @@ -6119,20 +6119,20 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con S32 new_size = new_verts*16; //positions - LLVector4a* dst = (LLVector4a*) _mm_malloc(new_size, 16); + LLVector4a* dst = (LLVector4a*) ll_aligned_malloc_16(new_size); if (mPositions) { LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mPositions, new_size/4); - _mm_free(mPositions); + ll_aligned_free_16(mPositions); } mPositions = dst; //normals - dst = (LLVector4a*) _mm_malloc(new_size, 16); + dst = (LLVector4a*) ll_aligned_malloc_16(new_size); if (mNormals) { LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mNormals, new_size/4); - _mm_free(mNormals); + ll_aligned_free_16(mNormals); } mNormals = dst; @@ -6140,16 +6140,16 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con new_size = ((new_verts*8)+0xF) & ~0xF; { - LLVector2* dst = (LLVector2*) _mm_malloc(new_size, 16); + LLVector2* dst = (LLVector2*) ll_aligned_malloc_16(new_size); if (mTexCoords) { LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mTexCoords, new_size/4); - _mm_free(mTexCoords); + ll_aligned_free_16(mTexCoords); } } //just clear binormals - _mm_free(mBinormals); + ll_aligned_free_16(mBinormals); mBinormals = NULL; mPositions[mNumVertices] = pos; @@ -6161,26 +6161,26 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con void LLVolumeFace::allocateBinormals(S32 num_verts) { - _mm_free(mBinormals); - mBinormals = (LLVector4a*) _mm_malloc(num_verts*16, 16); + ll_aligned_free_16(mBinormals); + mBinormals = (LLVector4a*) ll_aligned_malloc_16(num_verts*16); } void LLVolumeFace::allocateWeights(S32 num_verts) { - _mm_free(mWeights); - mWeights = (LLVector4a*) _mm_malloc(num_verts*16, 16); + ll_aligned_free_16(mWeights); + mWeights = (LLVector4a*) ll_aligned_malloc_16(num_verts*16); } void LLVolumeFace::resizeIndices(S32 num_indices) { - _mm_free(mIndices); + ll_aligned_free_16(mIndices); if (num_indices) { //pad index block end to allow for QWORD reads S32 size = ((num_indices*2) + 0xF) & ~0xF; - mIndices = (U16*) _mm_malloc(size,16); + mIndices = (U16*) ll_aligned_malloc_16(size); } else { @@ -6198,9 +6198,9 @@ void LLVolumeFace::pushIndex(const U16& idx) S32 old_size = (mNumIndices+0xF) & ~0xF; if (new_size != old_size) { - U16* dst = (U16*) _mm_malloc(new_size, 16); + U16* dst = (U16*) ll_aligned_malloc_16(new_size); LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mIndices, new_size/4); - _mm_free(mIndices); + ll_aligned_free_16(mIndices); mIndices = dst; } @@ -6237,17 +6237,17 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat } - LLVector4a* new_pos = (LLVector4a*) _mm_malloc(new_count*16, 16); - LLVector4a* new_norm = (LLVector4a*) _mm_malloc(new_count*16, 16); - LLVector2* new_tc = (LLVector2*) _mm_malloc((new_count*8+0xF) & ~0xF, 16); + LLVector4a* new_pos = (LLVector4a*) ll_aligned_malloc_16(new_count*16); + LLVector4a* new_norm = (LLVector4a*) ll_aligned_malloc_16(new_count*16); + LLVector2* new_tc = (LLVector2*) ll_aligned_malloc_16((new_count*8+0xF) & ~0xF); LLVector4a::memcpyNonAliased16((F32*) new_pos, (F32*) mPositions, new_count*4); LLVector4a::memcpyNonAliased16((F32*) new_norm, (F32*) mNormals, new_count*4); LLVector4a::memcpyNonAliased16((F32*) new_tc, (F32*) mTexCoords, new_count*2); - _mm_free(mPositions); - _mm_free(mNormals); - _mm_free(mTexCoords); + ll_aligned_free_16(mPositions); + ll_aligned_free_16(mNormals); + ll_aligned_free_16(mTexCoords); mPositions = new_pos; mNormals = new_norm; @@ -6287,9 +6287,9 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat new_count = mNumIndices + face.mNumIndices; - U16* new_indices = (U16*) _mm_malloc((new_count*2+0xF) & ~0xF, 16); + U16* new_indices = (U16*) ll_aligned_malloc_16((new_count*2+0xF) & ~0xF); LLVector4a::memcpyNonAliased16((F32*) new_indices, (F32*) mIndices, new_count/2); - _mm_free(mIndices); + ll_aligned_free_16(mIndices); mIndices = new_indices; mNumIndices = new_count; -- cgit v1.3 From 6ca40c7afbd794b161904b63b88a95273ae80c9c Mon Sep 17 00:00:00 2001 From: Tofu Linden Date: Fri, 4 Jun 2010 09:10:00 +0100 Subject: more needed #includes --- indra/llmath/llvolume.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index a8684759f3..ce7e20e9b4 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -31,6 +31,7 @@ */ #include "linden_common.h" +#include "llmemory.h" #include "llmath.h" #include -- cgit v1.3 From a8f0e47fd5deee1e45b4126ee43955a7bc68bb5d Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 4 Jun 2010 12:07:55 -0500 Subject: Normal debug display and fix for bad bump mapping and planar texture coordinates. --- indra/llmath/llvolume.cpp | 2 + indra/newview/app_settings/settings.xml | 13 ++++- indra/newview/llspatialpartition.cpp | 57 +++++++++++++++++++++- indra/newview/llviewermenu.cpp | 4 ++ indra/newview/pipeline.h | 1 + indra/newview/skins/default/xui/en/menu_viewer.xml | 10 ++++ 6 files changed, 85 insertions(+), 2 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 72833c019f..8cb9475994 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -6076,6 +6076,8 @@ void LLVolumeFace::createBinormals() for (U32 i = 0; i < mNumVertices; i++) { binorm[i].normalize3fast(); + //bump map/planar projection code requires normals to be normalized + mNormals[i].normalize3fast(); } } } diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 9b7cc04120..a95100d9ba 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6280,7 +6280,18 @@ Value 0 - RenderDebugPipeline + RenderDebugNormalScale + + Comment + Scale of normals in debug display. + Persist + 1 + Type + F32 + Value + 0.03 + + RenderDebugPipeline Comment Enable strict pipeline debugging. diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 05e7bbb6cd..77d36b1c2e 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -2704,7 +2704,56 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE) { drawBoxOutline(pos,size); } - +} + +void renderNormals(LLDrawable* drawablep) +{ + LLVertexBuffer::unbind(); + + LLVOVolume* vol = drawablep->getVOVolume(); + if (vol) + { + LLVolume* volume = vol->getVolume(); + gGL.pushMatrix(); + glMultMatrixf((F32*) vol->getRelativeXform().mMatrix); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + LLVector4a scale(gSavedSettings.getF32("RenderDebugNormalScale")); + + for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) + { + const LLVolumeFace& face = volume->getVolumeFace(i); + + gGL.begin(LLRender::LINES); + + for (S32 j = 0; j < face.mNumVertices; ++j) + { + LLVector4a n,p; + + n.setMul(face.mNormals[j], scale); + p.setAdd(face.mPositions[j], n); + + gGL.color4f(1,1,1,1); + gGL.vertex3fv(face.mPositions[j].getF32()); + gGL.vertex3fv(p.getF32()); + + if (face.mBinormals) + { + n.setMul(face.mBinormals[j], scale); + p.setAdd(face.mPositions[j], n); + + gGL.color4f(0,1,1,1); + gGL.vertex3fv(face.mPositions[j].getF32()); + gGL.vertex3fv(p.getF32()); + } + } + + gGL.end(); + } + + gGL.popMatrix(); + } } void renderTexturePriority(LLDrawable* drawable) @@ -3081,6 +3130,11 @@ public: { renderBoundingBox(drawable); } + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_NORMALS)) + { + renderNormals(drawable); + } if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BUILD_QUEUE)) { @@ -3280,6 +3334,7 @@ void LLSpatialPartition::renderDebug() LLPipeline::RENDER_DEBUG_LIGHTS | LLPipeline::RENDER_DEBUG_BATCH_SIZE | LLPipeline::RENDER_DEBUG_BBOXES | + LLPipeline::RENDER_DEBUG_NORMALS | LLPipeline::RENDER_DEBUG_POINTS | LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY | LLPipeline::RENDER_DEBUG_TEXTURE_ANIM | diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index b63ef921ac..eb2ee94af3 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -857,6 +857,10 @@ U32 info_display_from_string(std::string info_display) { return LLPipeline::RENDER_DEBUG_BBOXES; } + else if ("normals" == info_display) + { + return LLPipeline::RENDER_DEBUG_NORMALS; + } else if ("points" == info_display) { return LLPipeline::RENDER_DEBUG_POINTS; diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 52f943cd1d..4e8760947c 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -440,6 +440,7 @@ public: RENDER_DEBUG_AVATAR_VOLUME = 0x0100000, RENDER_DEBUG_BUILD_QUEUE = 0x0200000, RENDER_DEBUG_AGENT_TARGET = 0x0400000, + RENDER_DEBUG_NORMALS = 0x0800000, }; public: diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index bdc171ea52..9cc1a481f5 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1925,6 +1925,16 @@ function="Advanced.ToggleInfoDisplay" parameter="bboxes" /> + + + + -- cgit v1.3 From f5ae54f8c3fe954a08faa9b2de695c0326f2aeac Mon Sep 17 00:00:00 2001 From: Tofu Linden Date: Tue, 8 Jun 2010 20:48:57 +0100 Subject: DEV-11516 FIXED VWR-5308: Current wind noise generation is CPU intensive. Minor optimizations to wind generation. Patch by gigs and aimee, reviewed by merov. --- doc/contributions.txt | 2 + indra/llaudio/llaudioengine.cpp | 5 +- indra/llaudio/llaudioengine.h | 2 +- indra/llaudio/llaudioengine_fmod.cpp | 92 ++++++++++-------- indra/llaudio/llaudioengine_fmod.h | 7 +- indra/llaudio/llaudioengine_openal.cpp | 10 +- indra/llaudio/llaudioengine_openal.h | 24 ++--- indra/llaudio/llwindgen.h | 165 +++++++++++++++++++++------------ indra/llmath/llmath.h | 15 +-- 9 files changed, 196 insertions(+), 126 deletions(-) (limited to 'indra/llmath') diff --git a/doc/contributions.txt b/doc/contributions.txt index 5667b69c28..a74cf32afa 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -25,6 +25,7 @@ Aimee Trescothick VWR-3903 VWR-4083 VWR-4106 + VWR-5308 VWR-6348 VWR-6358 VWR-6360 @@ -252,6 +253,7 @@ Gigs Taggart VWR-2491 VWR-2502 VWR-2331 + VWR-5308 VWR-8781 VWR-8783 Ginko Bayliss diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index b92ccd1d77..9f4c108dff 100644 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -548,12 +548,11 @@ void LLAudioEngine::enableWind(bool enable) { if (enable && (!mEnableWind)) { - initWind(); - mEnableWind = enable; + mEnableWind = initWind(); } else if (mEnableWind && (!enable)) { - mEnableWind = enable; + mEnableWind = false; cleanupWind(); } } diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h index d287104204..5876cef4ea 100644 --- a/indra/llaudio/llaudioengine.h +++ b/indra/llaudio/llaudioengine.h @@ -195,7 +195,7 @@ protected: virtual LLAudioBuffer *createBuffer() = 0; virtual LLAudioChannel *createChannel() = 0; - virtual void initWind() = 0; + virtual bool initWind() = 0; virtual void cleanupWind() = 0; virtual void setInternalGain(F32 gain) = 0; diff --git a/indra/llaudio/llaudioengine_fmod.cpp b/indra/llaudio/llaudioengine_fmod.cpp index d7f58defca..7a8a04afa1 100644 --- a/indra/llaudio/llaudioengine_fmod.cpp +++ b/indra/llaudio/llaudioengine_fmod.cpp @@ -54,13 +54,12 @@ extern "C" { void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata); } -FSOUND_DSPUNIT *gWindDSP = NULL; - LLAudioEngine_FMOD::LLAudioEngine_FMOD() { mInited = false; mWindGen = NULL; + mWindDSP = NULL; } @@ -258,10 +257,10 @@ void LLAudioEngine_FMOD::allocateListener(void) void LLAudioEngine_FMOD::shutdown() { - if (gWindDSP) + if (mWindDSP) { - FSOUND_DSP_SetActive(gWindDSP,false); - FSOUND_DSP_Free(gWindDSP); + FSOUND_DSP_SetActive(mWindDSP,false); + FSOUND_DSP_Free(mWindDSP); } stopInternetStream(); @@ -289,29 +288,66 @@ LLAudioChannel * LLAudioEngine_FMOD::createChannel() } -void LLAudioEngine_FMOD::initWind() +bool LLAudioEngine_FMOD::initWind() { - mWindGen = new LLWindGen; + if (!mWindGen) + { + bool enable; + + switch (FSOUND_GetMixer()) + { + case FSOUND_MIXER_MMXP5: + case FSOUND_MIXER_MMXP6: + case FSOUND_MIXER_QUALITY_MMXP5: + case FSOUND_MIXER_QUALITY_MMXP6: + enable = (typeid(MIXBUFFERFORMAT) == typeid(S16)); + break; + case FSOUND_MIXER_BLENDMODE: + enable = (typeid(MIXBUFFERFORMAT) == typeid(S32)); + break; + case FSOUND_MIXER_QUALITY_FPU: + enable = (typeid(MIXBUFFERFORMAT) == typeid(F32)); + break; + default: + // FSOUND_GetMixer() does not return a valid mixer type on Darwin + LL_INFOS("AppInit") << "Unknown FMOD mixer type, assuming default" << LL_ENDL; + enable = true; + break; + } + + if (enable) + { + mWindGen = new LLWindGen(FSOUND_GetOutputRate()); + } + else + { + LL_WARNS("AppInit") << "Incompatible FMOD mixer type, wind noise disabled" << LL_ENDL; + } + } + + mNextWindUpdate = 0.0; - if (!gWindDSP) + if (mWindGen && !mWindDSP) { - gWindDSP = FSOUND_DSP_Create(&windCallback, FSOUND_DSP_DEFAULTPRIORITY_CLEARUNIT + 20, mWindGen); + mWindDSP = FSOUND_DSP_Create(&windCallback, FSOUND_DSP_DEFAULTPRIORITY_CLEARUNIT + 20, mWindGen); } - if (gWindDSP) + if (mWindDSP) { - FSOUND_DSP_SetActive(gWindDSP, true); + FSOUND_DSP_SetActive(mWindDSP, true); + return true; } - mNextWindUpdate = 0.0; + + return false; } void LLAudioEngine_FMOD::cleanupWind() { - if (gWindDSP) + if (mWindDSP) { - FSOUND_DSP_SetActive(gWindDSP, false); - FSOUND_DSP_Free(gWindDSP); - gWindDSP = NULL; + FSOUND_DSP_SetActive(mWindDSP, false); + FSOUND_DSP_Free(mWindDSP); + mWindDSP = NULL; } delete mWindGen; @@ -740,30 +776,12 @@ void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int len // originalbuffer = fmod's original mixbuffer. // newbuffer = the buffer passed from the previous DSP unit. // length = length in samples at this mix time. - // param = user parameter passed through in FSOUND_DSP_Create. - // - // modify the buffer in some fashion + // userdata = user parameter passed through in FSOUND_DSP_Create. LLWindGen *windgen = (LLWindGen *)userdata; - U8 stride; - -#if LL_DARWIN - stride = sizeof(LLAudioEngine_FMOD::MIXBUFFERFORMAT); -#else - int mixertype = FSOUND_GetMixer(); - if (mixertype == FSOUND_MIXER_BLENDMODE || - mixertype == FSOUND_MIXER_QUALITY_FPU) - { - stride = 4; - } - else - { - stride = 2; - } -#endif - - newbuffer = windgen->windGenerate((LLAudioEngine_FMOD::MIXBUFFERFORMAT *)newbuffer, length, stride); + + newbuffer = windgen->windGenerate((LLAudioEngine_FMOD::MIXBUFFERFORMAT *)newbuffer, length); return newbuffer; } diff --git a/indra/llaudio/llaudioengine_fmod.h b/indra/llaudio/llaudioengine_fmod.h index 3968657cba..0e386a3884 100644 --- a/indra/llaudio/llaudioengine_fmod.h +++ b/indra/llaudio/llaudioengine_fmod.h @@ -55,15 +55,15 @@ public: virtual void shutdown(); - /*virtual*/ void initWind(); + /*virtual*/ bool initWind(); /*virtual*/ void cleanupWind(); /*virtual*/void updateWind(LLVector3 direction, F32 camera_height_above_water); #if LL_DARWIN - typedef S32 MIXBUFFERFORMAT; + typedef S32 MIXBUFFERFORMAT; #else - typedef S16 MIXBUFFERFORMAT; + typedef S16 MIXBUFFERFORMAT; #endif protected: @@ -83,6 +83,7 @@ protected: void* mUserData; LLWindGen *mWindGen; + FSOUND_DSPUNIT *mWindDSP; }; diff --git a/indra/llaudio/llaudioengine_openal.cpp b/indra/llaudio/llaudioengine_openal.cpp index a5982ccbd6..887c791790 100644 --- a/indra/llaudio/llaudioengine_openal.cpp +++ b/indra/llaudio/llaudioengine_openal.cpp @@ -370,7 +370,7 @@ U32 LLAudioBufferOpenAL::getLength() // ------------ -void LLAudioEngine_OpenAL::initWind() +bool LLAudioEngine_OpenAL::initWind() { ALenum error; llinfos << "LLAudioEngine_OpenAL::initWind() start" << llendl; @@ -397,10 +397,12 @@ void LLAudioEngine_OpenAL::initWind() if(mWindBuf==NULL) { llerrs << "LLAudioEngine_OpenAL::initWind() Error creating wind memory buffer" << llendl; - mEnableWind=false; + return false; } llinfos << "LLAudioEngine_OpenAL::initWind() done" << llendl; + + return true; } void LLAudioEngine_OpenAL::cleanupWind() @@ -508,14 +510,14 @@ void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude) alGenBuffers(1,&buffer); if((error=alGetError()) != AL_NO_ERROR) { - llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind buffer: " << error << llendl; + llwarns << "LLAudioEngine_OpenAL::updateWind() Error creating wind buffer: " << error << llendl; break; } alBufferData(buffer, AL_FORMAT_STEREO16, mWindGen->windGenerate(mWindBuf, - mWindBufSamples, 2), + mWindBufSamples), mWindBufBytes, mWindBufFreq); error = alGetError(); diff --git a/indra/llaudio/llaudioengine_openal.h b/indra/llaudio/llaudioengine_openal.h index 5aca03e195..16125b2476 100644 --- a/indra/llaudio/llaudioengine_openal.h +++ b/indra/llaudio/llaudioengine_openal.h @@ -57,23 +57,23 @@ class LLAudioEngine_OpenAL : public LLAudioEngine LLAudioBuffer* createBuffer(); LLAudioChannel* createChannel(); - /*virtual*/ void initWind(); + /*virtual*/ bool initWind(); /*virtual*/ void cleanupWind(); /*virtual*/ void updateWind(LLVector3 direction, F32 camera_altitude); private: void * windDSP(void *newbuffer, int length); - typedef S16 WIND_SAMPLE_T; - LLWindGen *mWindGen; - S16 *mWindBuf; - U32 mWindBufFreq; - U32 mWindBufSamples; - U32 mWindBufBytes; - ALuint mWindSource; - int mNumEmptyWindALBuffers; - - static const int MAX_NUM_WIND_BUFFERS = 80; - static const float WIND_BUFFER_SIZE_SEC = 0.05f; // 1/20th sec + typedef S16 WIND_SAMPLE_T; + LLWindGen *mWindGen; + S16 *mWindBuf; + U32 mWindBufFreq; + U32 mWindBufSamples; + U32 mWindBufBytes; + ALuint mWindSource; + int mNumEmptyWindALBuffers; + + static const int MAX_NUM_WIND_BUFFERS = 80; + static const float WIND_BUFFER_SIZE_SEC = 0.05f; // 1/20th sec }; class LLAudioChannelOpenAL : public LLAudioChannel diff --git a/indra/llaudio/llwindgen.h b/indra/llaudio/llwindgen.h index 847bfa6e9d..1908b2545f 100644 --- a/indra/llaudio/llwindgen.h +++ b/indra/llaudio/llwindgen.h @@ -33,104 +33,149 @@ #define WINDGEN_H #include "llcommon.h" -#include "llrand.h" template class LLWindGen { public: - LLWindGen() : + LLWindGen(const U32 sample_rate = 44100) : mTargetGain(0.f), mTargetFreq(100.f), mTargetPanGainR(0.5f), - mbuf0(0.0), - mbuf1(0.0), - mbuf2(0.0), - mbuf3(0.0), - mbuf4(0.0), - mbuf5(0.0), - mY0(0.0), - mY1(0.0), + mInputSamplingRate(sample_rate), + mSubSamples(2), + mFilterBandWidth(50.f), + mBuf0(0.0f), + mBuf1(0.0f), + mBuf2(0.0f), + mY0(0.0f), + mY1(0.0f), mCurrentGain(0.f), mCurrentFreq(100.f), - mCurrentPanGainR(0.5f) {}; - - static const U32 getInputSamplingRate() {return mInputSamplingRate;} + mCurrentPanGainR(0.5f) + { + mSamplePeriod = (F32)mSubSamples / (F32)mInputSamplingRate; + mB2 = expf(-F_TWO_PI * mFilterBandWidth * mSamplePeriod); + } + const U32 getInputSamplingRate() { return mInputSamplingRate; } + // newbuffer = the buffer passed from the previous DSP unit. // numsamples = length in samples-per-channel at this mix time. - // stride = number of bytes between start of each sample. // NOTE: generates L/R interleaved stereo - MIXBUFFERFORMAT_T* windGenerate(MIXBUFFERFORMAT_T *newbuffer, int numsamples, int stride) + MIXBUFFERFORMAT_T* windGenerate(MIXBUFFERFORMAT_T *newbuffer, int numsamples) { - U8 *cursamplep = (U8*)newbuffer; + MIXBUFFERFORMAT_T *cursamplep = newbuffer; + + // Filter coefficients + F32 a0 = 0.0f, b1 = 0.0f; - double bandwidth = 50.0F; - double a0,b1,b2; + // No need to clip at normal volumes + bool clip = mCurrentGain > 2.0f; - // calculate resonant filter coeffs - b2 = exp(-(F_TWO_PI) * (bandwidth / mInputSamplingRate)); + bool interp_freq = false; - while (numsamples--) + //if the frequency isn't changing much, we don't need to interpolate in the inner loop + if (llabs(mTargetFreq - mCurrentFreq) < (mCurrentFreq * 0.112)) { - mCurrentFreq = (float)((0.999 * mCurrentFreq) + (0.001 * mTargetFreq)); - mCurrentGain = (float)((0.999 * mCurrentGain) + (0.001 * mTargetGain)); - mCurrentPanGainR = (float)((0.999 * mCurrentPanGainR) + (0.001 * mTargetPanGainR)); - b1 = (-4.0 * b2) / (1.0 + b2) * cos(F_TWO_PI * (mCurrentFreq / mInputSamplingRate)); - a0 = (1.0 - b2) * sqrt(1.0 - (b1 * b1) / (4.0 * b2)); - double nextSample; + // calculate resonant filter coefficients + mCurrentFreq = mTargetFreq; + b1 = (-4.0f * mB2) / (1.0f + mB2) * cosf(F_TWO_PI * (mCurrentFreq * mSamplePeriod)); + a0 = (1.0f - mB2) * sqrtf(1.0f - (b1 * b1) / (4.0f * mB2)); + } + else + { + interp_freq = true; + } + + while (numsamples) + { + F32 next_sample; + + // Start with white noise + // This expression is fragile, rearrange it and it will break! + next_sample = (F32)rand() * (1.0f / (F32)(RAND_MAX / (U16_MAX / 8))) + (F32)(S16_MIN / 8); - // start with white noise - nextSample = ll_frand(2.0f) - 1.0f; + // Apply a pinking filter + // Magic numbers taken from PKE method at http://www.firstpr.com.au/dsp/pink-noise/ + mBuf0 = mBuf0 * 0.99765f + next_sample * 0.0990460f; + mBuf1 = mBuf1 * 0.96300f + next_sample * 0.2965164f; + mBuf2 = mBuf2 * 0.57000f + next_sample * 1.0526913f; - // apply pinking filter - mbuf0 = 0.997f * mbuf0 + 0.0126502f * nextSample; - mbuf1 = 0.985f * mbuf1 + 0.0139083f * nextSample; - mbuf2 = 0.950f * mbuf2 + 0.0205439f * nextSample; - mbuf3 = 0.850f * mbuf3 + 0.0387225f * nextSample; - mbuf4 = 0.620f * mbuf4 + 0.0465932f * nextSample; - mbuf5 = 0.250f * mbuf5 + 0.1093477f * nextSample; + next_sample = mBuf0 + mBuf1 + mBuf2 + next_sample * 0.1848f; - nextSample = mbuf0 + mbuf1 + mbuf2 + mbuf3 + mbuf4 + mbuf5; + if (interp_freq) + { + // calculate and interpolate resonant filter coefficients + mCurrentFreq = (0.999f * mCurrentFreq) + (0.001f * mTargetFreq); + b1 = (-4.0f * mB2) / (1.0f + mB2) * cosf(F_TWO_PI * (mCurrentFreq * mSamplePeriod)); + a0 = (1.0f - mB2) * sqrtf(1.0f - (b1 * b1) / (4.0f * mB2)); + } - // do a resonant filter on the noise - nextSample = (double)( a0 * nextSample - b1 * mY0 - b2 * mY1 ); + // Apply a resonant low-pass filter on the pink noise + next_sample = a0 * next_sample - b1 * mY0 - mB2 * mY1; mY1 = mY0; - mY0 = nextSample; + mY0 = next_sample; - nextSample *= mCurrentGain; + mCurrentGain = (0.999f * mCurrentGain) + (0.001f * mTargetGain); + mCurrentPanGainR = (0.999f * mCurrentPanGainR) + (0.001f * mTargetPanGainR); - MIXBUFFERFORMAT_T sample; + // For a 3dB pan law use: + // next_sample *= mCurrentGain * ((mCurrentPanGainR*(mCurrentPanGainR-1)*1.652+1.413); + next_sample *= mCurrentGain; - sample = llfloor(((F32)nextSample*32768.f*(1.0f - mCurrentPanGainR))+0.5f); - *(MIXBUFFERFORMAT_T*)cursamplep = llclamp(sample, (MIXBUFFERFORMAT_T)-32768, (MIXBUFFERFORMAT_T)32767); - cursamplep += stride; - - sample = llfloor(((F32)nextSample*32768.f*mCurrentPanGainR)+0.5f); - *(MIXBUFFERFORMAT_T*)cursamplep = llclamp(sample, (MIXBUFFERFORMAT_T)-32768, (MIXBUFFERFORMAT_T)32767); - cursamplep += stride; + // delta is used to interpolate between synthesized samples + F32 delta = (next_sample - mLastSample) / (F32)mSubSamples; + + // Fill the audio buffer, clipping if necessary + for (U8 i=mSubSamples; i && numsamples; --i, --numsamples) + { + mLastSample = mLastSample + delta; + S32 sample_right = (S32)(mLastSample * mCurrentPanGainR); + S32 sample_left = (S32)mLastSample - sample_right; + + if (!clip) + { + *cursamplep = (MIXBUFFERFORMAT_T)sample_left; + ++cursamplep; + *cursamplep = (MIXBUFFERFORMAT_T)sample_right; + ++cursamplep; + } + else + { + *cursamplep = (MIXBUFFERFORMAT_T)llclamp(sample_left, (S32)S16_MIN, (S32)S16_MAX); + ++cursamplep; + *cursamplep = (MIXBUFFERFORMAT_T)llclamp(sample_right, (S32)S16_MIN, (S32)S16_MAX); + ++cursamplep; + } + } } return newbuffer; } - + +public: F32 mTargetGain; F32 mTargetFreq; F32 mTargetPanGainR; - + private: - static const U32 mInputSamplingRate = 44100; - F64 mbuf0; - F64 mbuf1; - F64 mbuf2; - F64 mbuf3; - F64 mbuf4; - F64 mbuf5; - F64 mY0; - F64 mY1; + U32 mInputSamplingRate; + U8 mSubSamples; + F32 mSamplePeriod; + F32 mFilterBandWidth; + F32 mB2; + + F32 mBuf0; + F32 mBuf1; + F32 mBuf2; + F32 mY0; + F32 mY1; + F32 mCurrentGain; F32 mCurrentFreq; F32 mCurrentPanGainR; + F32 mLastSample; }; #endif diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h index 209b506c30..c3c15e1374 100644 --- a/indra/llmath/llmath.h +++ b/indra/llmath/llmath.h @@ -61,11 +61,11 @@ #endif // Single Precision Floating Point Routines -#ifndef fsqrtf -#define fsqrtf(x) ((F32)sqrt((F64)(x))) -#endif #ifndef sqrtf -#define sqrtf(x) ((F32)sqrt((F64)(x))) +#define sqrtf(x) ((F32)sqrt((F64)(x))) +#endif +#ifndef fsqrtf +#define fsqrtf(x) sqrtf(x) #endif #ifndef cosf @@ -78,11 +78,14 @@ #define tanf(x) ((F32)tan((F64)(x))) #endif #ifndef acosf -#define acosf(x) ((F32)acos((F64)(x))) +#define acosf(x) ((F32)acos((F64)(x))) #endif #ifndef powf -#define powf(x,y) ((F32)pow((F64)(x),(F64)(y))) +#define powf(x,y) ((F32)pow((F64)(x),(F64)(y))) +#endif +#ifndef expf +#define expf(x) ((F32)exp((F64)(x))) #endif const F32 GRAVITY = -9.8f; -- cgit v1.3 From f9b13d8f8510b1f7f02fcf92685471461b79858e Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 10 Jun 2010 00:45:48 -0500 Subject: Add "LL_MESH_ENABLED" preprocessor flag for toggling mesh code. Couple of merge fixes. --- indra/llcommon/llassettype.cpp | 3 +- indra/llcommon/llassettype.h | 3 +- indra/llinventory/llinventorytype.cpp | 5 ++- indra/llinventory/llinventorytype.h | 2 + indra/llmath/llvolume.cpp | 13 +++--- indra/llmath/llvolume.h | 7 ++++ indra/llrender/llvertexbuffer.cpp | 4 +- indra/llvfs/llvfs.cpp | 2 + indra/newview/app_settings/settings.xml | 4 +- indra/newview/llappviewer.cpp | 4 ++ indra/newview/llassetuploadresponders.cpp | 5 +++ indra/newview/llassetuploadresponders.h | 3 +- indra/newview/lldrawpoolavatar.cpp | 48 +++++++++++++++++++++- indra/newview/lldrawpoolavatar.h | 40 ++++++++++-------- indra/newview/llface.cpp | 2 + indra/newview/llinventorybridge.cpp | 10 ++++- indra/newview/llinventorybridge.h | 4 +- indra/newview/llpanelgroupnotices.cpp | 2 + indra/newview/llpanelobjectinventory.cpp | 6 +++ indra/newview/llselectmgr.cpp | 2 + indra/newview/lltexturectrl.cpp | 12 +++++- indra/newview/lltooldraganddrop.cpp | 10 +++++ indra/newview/lltooldraganddrop.h | 4 ++ indra/newview/llviewerassettype.cpp | 2 + indra/newview/llviewerfloaterreg.cpp | 4 ++ indra/newview/llviewermenufile.cpp | 9 +++- indra/newview/llviewermenufile.h | 2 + indra/newview/llviewertexteditor.cpp | 2 + indra/newview/llviewerwindow.cpp | 4 ++ indra/newview/llvovolume.cpp | 15 ++++++- indra/newview/pipeline.cpp | 4 ++ indra/newview/pipeline.h | 13 +++--- .../default/xui/en/panel_preferences_graphics1.xml | 10 ++--- 33 files changed, 209 insertions(+), 51 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp index e19f8b0454..476a23ec64 100644 --- a/indra/llcommon/llassettype.cpp +++ b/indra/llcommon/llassettype.cpp @@ -99,8 +99,9 @@ LLAssetDictionary::LLAssetDictionary() addEntry(LLAssetType::AT_LINK, new AssetEntry("LINK", "link", "sym link", false, false, true)); addEntry(LLAssetType::AT_LINK_FOLDER, new AssetEntry("FOLDER_LINK", "link_f", "sym folder link", false, false, true)); - +#if LL_MESH_ENABLED addEntry(LLAssetType::AT_MESH, new AssetEntry("MESH", "mesh", "mesh", false, false, false)); +#endif addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, FALSE, FALSE, FALSE)); diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h index 90cd03c433..ebc43134cb 100644 --- a/indra/llcommon/llassettype.h +++ b/indra/llcommon/llassettype.h @@ -114,9 +114,10 @@ public: AT_LINK_FOLDER = 25, // Inventory folder link - +#if LL_MESH_ENABLED AT_MESH = 49, // Mesh data in our proprietary SLM format +#endif AT_COUNT = 50, diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp index 2d4ee604b0..82cd22a832 100644 --- a/indra/llinventory/llinventorytype.cpp +++ b/indra/llinventory/llinventorytype.cpp @@ -89,7 +89,9 @@ LLInventoryDictionary::LLInventoryDictionary() addEntry(LLInventoryType::IT_WEARABLE, new InventoryEntry("wearable", "wearable", 2, LLAssetType::AT_CLOTHING, LLAssetType::AT_BODYPART)); addEntry(LLInventoryType::IT_ANIMATION, new InventoryEntry("animation", "animation", 1, LLAssetType::AT_ANIMATION)); addEntry(LLInventoryType::IT_GESTURE, new InventoryEntry("gesture", "gesture", 1, LLAssetType::AT_GESTURE)); +#if LL_MESH_ENABLED addEntry(LLInventoryType::IT_MESH, new InventoryEntry("mesh", "mesh", 1, LLAssetType::AT_MESH)); +#endif } @@ -150,8 +152,9 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] = LLInventoryType::IT_NONE, // AT_NONE LLInventoryType::IT_NONE, // AT_NONE LLInventoryType::IT_NONE, // AT_NONE - +#if LL_MESH_ENABLED LLInventoryType::IT_MESH // AT_MESH +#endif }; // static diff --git a/indra/llinventory/llinventorytype.h b/indra/llinventory/llinventorytype.h index 37829f5eae..d2fc67ef64 100644 --- a/indra/llinventory/llinventorytype.h +++ b/indra/llinventory/llinventorytype.h @@ -68,7 +68,9 @@ public: IT_ANIMATION = 19, IT_GESTURE = 20, +#if LL_MESH_ENABLED IT_MESH = 22, +#endif IT_COUNT = 23, IT_NONE = -1 diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 09ab47b890..05868e3517 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2546,10 +2546,12 @@ S32 LLVolume::getNumFaces() const { U8 sculpt_type = (mParams.getSculptType() & LL_SCULPT_TYPE_MASK); +#if LL_MESH_ENABLED if (sculpt_type == LL_SCULPT_TYPE_MESH) { return LL_SCULPT_MESH_MAX_FACES; } +#endif return (S32)mProfilep->mFaces.size(); } @@ -2922,11 +2924,6 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, LLMemType m1(LLMemType::MTYPE_VOLUME); U8 sculpt_type = mParams.getSculptType(); - if (sculpt_type & LL_SCULPT_TYPE_MASK == LL_SCULPT_TYPE_MESH) - { - llerrs << "WTF?" << llendl; - } - BOOL data_is_empty = FALSE; if (sculpt_width == 0 || sculpt_height == 0 || sculpt_components < 3 || sculpt_data == NULL) @@ -4135,10 +4132,12 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, normals.clear(); segments.clear(); +#if LL_MESH_ENABLED if ((mParams.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) { return; } +#endif S32 cur_index = 0; //for each face @@ -6335,10 +6334,14 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) resizeVertices(num_vertices); resizeIndices(num_indices); +#if LL_MESH_ENABLED if ((volume->getParams().getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH) { mEdge.resize(num_indices); } +#else + mEdge.resize(num_indices); +#endif } LLVector4a* pos = (LLVector4a*) mPositions; diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index c49d1c650d..0782944079 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -41,6 +41,8 @@ class LLVolumeParams; class LLProfile; class LLPath; +#define LL_MESH_ENABLED 0 + template class LLOctreeNode; class LLVector4a; @@ -190,10 +192,15 @@ const U8 LL_SCULPT_TYPE_SPHERE = 1; const U8 LL_SCULPT_TYPE_TORUS = 2; const U8 LL_SCULPT_TYPE_PLANE = 3; const U8 LL_SCULPT_TYPE_CYLINDER = 4; +#if LL_MESH_ENABLED const U8 LL_SCULPT_TYPE_MESH = 5; const U8 LL_SCULPT_TYPE_MASK = LL_SCULPT_TYPE_SPHERE | LL_SCULPT_TYPE_TORUS | LL_SCULPT_TYPE_PLANE | LL_SCULPT_TYPE_CYLINDER | LL_SCULPT_TYPE_MESH; +#else +const U8 LL_SCULPT_TYPE_MASK = LL_SCULPT_TYPE_SPHERE | LL_SCULPT_TYPE_TORUS | LL_SCULPT_TYPE_PLANE | + LL_SCULPT_TYPE_CYLINDER; +#endif const U8 LL_SCULPT_FLAG_INVERT = 64; const U8 LL_SCULPT_FLAG_MIRROR = 128; diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 48c20b09a8..514ca25aa0 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -1318,7 +1318,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask) { if (mGLBuffer) { - if (useVBOs() && sVBOActive) + if (sVBOActive) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); sBindCount++; @@ -1330,7 +1330,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask) setup = TRUE; // ... or a client memory pointer changed } } - if (useVBOs() && mGLIndices && sIBOActive) + if (mGLIndices && sIBOActive) { /*if (sMapped) { diff --git a/indra/llvfs/llvfs.cpp b/indra/llvfs/llvfs.cpp index ddb76fb2ba..2b01288fd7 100644 --- a/indra/llvfs/llvfs.cpp +++ b/indra/llvfs/llvfs.cpp @@ -2041,9 +2041,11 @@ std::string get_extension(LLAssetType::EType type) case LLAssetType::AT_ANIMATION: extension = ".lla"; break; +#if LL_MESH_ENABLED case LLAssetType::AT_MESH: extension = ".slm"; break; +#endif default: // Just use the asset server filename extension in most cases extension += "."; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 79b58bcd7c..df9393c316 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4908,7 +4908,7 @@ Type Boolean Value - 1 + 0 MigrateCacheDirectory @@ -6818,7 +6818,7 @@ Type F32 Value - 0.0 + -0.001 RenderSpotShadowOffset diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 512b1dde7f..6978cdf672 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1302,8 +1302,10 @@ bool LLAppViewer::cleanup() llinfos << "Cleaning Up" << llendflush; +#if LL_MESH_ENABLED // shut down mesh streamer gMeshRepo.shutdown(); +#endif // Must clean up texture references before viewer window is destroyed. LLHUDManager::getInstance()->updateEffects(); @@ -1728,8 +1730,10 @@ bool LLAppViewer::initThreads() mFastTimerLogThread->start(); } +#if LL_MESH_ENABLED // Mesh streaming and caching gMeshRepo.init(); +#endif LLFilePickerThread::initClass(); diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index c48dcdb061..afb76735ec 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -305,6 +305,7 @@ void LLAssetUploadResponder::uploadComplete(const LLSD& content) { } +#if LL_MESH_ENABLED LLNewAgentInventoryResponder::LLNewAgentInventoryResponder( const LLSD& post_data, const LLUUID& vfile_id, @@ -426,6 +427,7 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) LLImportColladaAssetCache::getInstance()->assetUploaded(mVFileID, content["new_asset"], TRUE); } +#endif LLSendTexLayerResponder::LLSendTexLayerResponder(const LLSD& post_data, const LLUUID& vfile_id, @@ -675,6 +677,7 @@ void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content) } +#if LL_MESH_ENABLED ///////////////////////////////////////////////////// // LLNewAgentInventoryVariablePriceResponder::Impl // ///////////////////////////////////////////////////// @@ -1142,3 +1145,5 @@ void LLNewAgentInventoryVariablePriceResponder::showConfirmationDialog( boost::intrusive_ptr(this))); } } +#endif + diff --git a/indra/newview/llassetuploadresponders.h b/indra/newview/llassetuploadresponders.h index af3b3daf46..9abaccfde0 100644 --- a/indra/newview/llassetuploadresponders.h +++ b/indra/newview/llassetuploadresponders.h @@ -61,7 +61,7 @@ protected: std::string mFileName; }; - +#if LL_MESH_ENABLED // TODO*: Remove this once deprecated class LLNewAgentInventoryResponder : public LLAssetUploadResponder { @@ -116,6 +116,7 @@ private: class Impl; Impl* mImpl; }; +#endif struct LLBakedUploadData; class LLSendTexLayerResponder : public LLAssetUploadResponder diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 9268cb1d47..63ca17d62d 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -103,6 +103,7 @@ S32 normal_channel = -1; S32 specular_channel = -1; S32 cube_channel = -1; +#if LL_MESH_ENABLED static const U32 rigged_data_mask[] = { LLDrawPoolAvatar::RIGGED_SIMPLE_MASK, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_MASK, @@ -114,6 +115,7 @@ static const U32 rigged_data_mask[] = { LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP_MASK, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE_MASK, }; +#endif static LLFastTimer::DeclareTimer FTM_SHADOW_AVATAR("Avatar Shadow"); @@ -194,12 +196,14 @@ void LLDrawPoolAvatar::beginDeferredPass(S32 pass) case 2: beginDeferredSkinned(); break; +#if LL_MESH_ENABLED case 3: beginDeferredRiggedSimple(); break; case 4: beginDeferredRiggedBump(); break; +#endif } } @@ -226,12 +230,14 @@ void LLDrawPoolAvatar::endDeferredPass(S32 pass) case 2: endDeferredSkinned(); break; +#if LL_MESH_ENABLED case 3: endDeferredRiggedSimple(); break; case 4: endDeferredRiggedBump(); break; +#endif } } @@ -242,7 +248,11 @@ void LLDrawPoolAvatar::renderDeferred(S32 pass) S32 LLDrawPoolAvatar::getNumPostDeferredPasses() { +#if LL_MESH_ENABLED return 6; +#else + return 1; +#endif } void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass) @@ -252,6 +262,7 @@ void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass) case 0: beginPostDeferredAlpha(); break; +#if LL_MESH_ENABLED case 1: beginRiggedFullbright(); break; @@ -267,6 +278,7 @@ void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass) case 5: beginRiggedGlow(); break; +#endif } } @@ -284,6 +296,7 @@ void LLDrawPoolAvatar::beginPostDeferredAlpha() enable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]); } +#if LL_MESH_ENABLED void LLDrawPoolAvatar::beginDeferredRiggedAlpha() { sVertexProgram = &gDeferredSkinnedAlphaProgram; @@ -301,6 +314,7 @@ void LLDrawPoolAvatar::endDeferredRiggedAlpha() LLVertexBuffer::sWeight4Loc = -1; sVertexProgram = NULL; } +#endif void LLDrawPoolAvatar::endPostDeferredPass(S32 pass) { @@ -309,6 +323,7 @@ void LLDrawPoolAvatar::endPostDeferredPass(S32 pass) case 0: endPostDeferredAlpha(); break; +#if LL_MESH_ENABLED case 1: endRiggedFullbright(); break; @@ -324,6 +339,7 @@ void LLDrawPoolAvatar::endPostDeferredPass(S32 pass) case 5: endRiggedGlow(); break; +#endif } } @@ -357,7 +373,11 @@ void LLDrawPoolAvatar::renderPostDeferred(S32 pass) S32 LLDrawPoolAvatar::getNumShadowPasses() { +#if LL_MESH_ENABLED return 2; +#else + return 1; +#endif } void LLDrawPoolAvatar::beginShadowPass(S32 pass) @@ -448,6 +468,7 @@ void LLDrawPoolAvatar::renderShadow(S32 pass) avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE); } +#if LL_MESH_ENABLED else { renderRigged(avatarp, RIGGED_SIMPLE); @@ -457,10 +478,12 @@ void LLDrawPoolAvatar::renderShadow(S32 pass) renderRigged(avatarp, RIGGED_SHINY); renderRigged(avatarp, RIGGED_FULLBRIGHT_ALPHA); } +#endif } S32 LLDrawPoolAvatar::getNumPasses() { +#if LL_MESH_ENABLED if (LLPipeline::sImpostorRender) { return 8; @@ -473,8 +496,19 @@ S32 LLDrawPoolAvatar::getNumPasses() { return 3; } +#else + if (LLPipeline::sImpostorRender) + { + return 1; + } + else + { + return 3; + } +#endif } + S32 LLDrawPoolAvatar::getNumDeferredPasses() { if (LLPipeline::sImpostorRender) @@ -522,6 +556,7 @@ void LLDrawPoolAvatar::beginRenderPass(S32 pass) case 2: beginSkinned(); break; +#if LL_MESH_ENABLED case 3: beginRiggedSimple(); break; @@ -543,6 +578,7 @@ void LLDrawPoolAvatar::beginRenderPass(S32 pass) case 9: beginRiggedGlow(); break; +#endif } } @@ -566,6 +602,7 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass) case 2: endSkinned(); break; +#if LL_MESH_ENABLED case 3: endRiggedSimple(); break; @@ -587,6 +624,7 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass) case 9: endRiggedGlow(); break; +#endif } } @@ -772,6 +810,7 @@ void LLDrawPoolAvatar::endSkinned() gGL.getTexUnit(0)->activate(); } +#if LL_MESH_ENABLED void LLDrawPoolAvatar::beginRiggedSimple() { sVertexProgram = &gSkinnedObjectSimpleProgram; @@ -924,6 +963,7 @@ void LLDrawPoolAvatar::endDeferredRiggedBump() sDiffuseChannel = 0; sVertexProgram = NULL; } +#endif void LLDrawPoolAvatar::beginDeferredSkinned() { @@ -1069,6 +1109,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) return; } +#if LL_MESH_ENABLED if (pass == 3) { if (is_deferred_render) @@ -1150,7 +1191,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) gGL.setSceneBlendType(LLRender::BT_ALPHA); return; } - +#endif if (sShaderLevel > 0) { @@ -1188,6 +1229,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) } } +#if LL_MESH_ENABLED void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face) { U32 data_mask = 0; @@ -1377,7 +1419,7 @@ void LLDrawPoolAvatar::renderRiggedGlow(LLVOAvatar* avatar) { renderRigged(avatar, RIGGED_GLOW, true); } - +#endif @@ -1479,6 +1521,7 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const return LLColor3(0.f, 1.f, 0.f); } +#if LL_MESH_ENABLED void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type) { if (facep->mRiggedIndex.empty()) @@ -1533,6 +1576,7 @@ void LLDrawPoolAvatar::removeRiggedFace(LLFace* facep) } } } +#endif LLVertexBufferAvatar::LLVertexBufferAvatar() : LLVertexBuffer(sDataMask, diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 4a5b009412..46ffc42f04 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -96,6 +96,23 @@ public: void beginRigid(); void beginImpostor(); void beginSkinned(); + + void endRigid(); + void endImpostor(); + void endSkinned(); + + void beginDeferredImpostor(); + void beginDeferredRigid(); + void beginDeferredSkinned(); + + void endDeferredImpostor(); + void endDeferredRigid(); + void endDeferredSkinned(); + + void beginPostDeferredAlpha(); + void endPostDeferredAlpha(); + +#if LL_MESH_ENABLED void beginRiggedSimple(); void beginRiggedFullbright(); void beginRiggedFullbrightShiny(); @@ -103,12 +120,8 @@ public: void beginRiggedAlpha(); void beginRiggedFullbrightAlpha(); void beginRiggedGlow(); - void beginPostDeferredAlpha(); void beginDeferredRiggedAlpha(); - void endRigid(); - void endImpostor(); - void endSkinned(); void endRiggedSimple(); void endRiggedFullbright(); void endRiggedFullbrightShiny(); @@ -116,18 +129,11 @@ public: void endRiggedAlpha(); void endRiggedFullbrightAlpha(); void endRiggedGlow(); - void endPostDeferredAlpha(); void endDeferredRiggedAlpha(); - void beginDeferredImpostor(); - void beginDeferredRigid(); - void beginDeferredSkinned(); void beginDeferredRiggedSimple(); void beginDeferredRiggedBump(); - void endDeferredImpostor(); - void endDeferredRigid(); - void endDeferredSkinned(); void endDeferredRiggedSimple(); void endDeferredRiggedBump(); @@ -147,11 +153,6 @@ public: void renderDeferredRiggedSimple(LLVOAvatar* avatar); void renderDeferredRiggedBump(LLVOAvatar* avatar); - /*virtual*/ LLViewerTexture *getDebugTexture(); - /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display - - void renderAvatars(LLVOAvatar *single_avatar, S32 pass = -1); // renders only one avatar if single_avatar is not null. - typedef enum { RIGGED_SIMPLE = 0, @@ -202,6 +203,13 @@ public: void removeRiggedFace(LLFace* facep); std::vector mRiggedFace[NUM_RIGGED_PASSES]; +#endif + + /*virtual*/ LLViewerTexture *getDebugTexture(); + /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display + + void renderAvatars(LLVOAvatar *single_avatar, S32 pass = -1); // renders only one avatar if single_avatar is not null. + static BOOL sSkipOpaque; static BOOL sSkipTransparent; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index e4f9e28c77..c48106863e 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -224,11 +224,13 @@ void LLFace::destroy() { LLFastTimer t(FTM_DESTROY_DRAWPOOL); +#if LL_MESH_ENABLED if (this->isState(LLFace::RIGGED) && mDrawPoolp->getType() == LLDrawPool::POOL_AVATAR) { ((LLDrawPoolAvatar*) mDrawPoolp)->removeRiggedFace(this); } else +#endif { mDrawPoolp->removeFace(this); } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 78789eb9ce..3999a8ee88 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -917,6 +917,7 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, // Only should happen for broken links. new_listener = new LLLinkItemBridge(inventory, root, uuid); break; +#if LL_MESH_ENABLED case LLAssetType::AT_MESH: if(!(inv_type == LLInventoryType::IT_MESH)) { @@ -924,6 +925,7 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, } new_listener = new LLMeshBridge(inventory, root, uuid); break; +#endif default: llinfos << "Unhandled asset type (llassetstorage.h): " @@ -2765,7 +2767,9 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop, case DAD_ANIMATION: case DAD_GESTURE: case DAD_LINK: +#if LL_MESH_ENABLED case DAD_MESH: +#endif accept = dragItemIntoFolder((LLInventoryItem*)cargo_data, drop); break; @@ -3635,7 +3639,9 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop, case DAD_BODYPART: case DAD_ANIMATION: case DAD_GESTURE: - case DAD_MESH: +#if LL_MESH_ENABLED + case DAD_MESH: +#endif { LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data; const LLPermissions& perm = inv_item->getPermissions(); @@ -4843,6 +4849,7 @@ void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags) hide_context_entries(menu, items, disabled_items); } +#if LL_MESH_ENABLED // +=================================================+ // | LLMeshBridge | // +=================================================+ @@ -4899,6 +4906,7 @@ void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags) hide_context_entries(menu, items, disabled_items); } +#endif // +=================================================+ // | LLLinkBridge | diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index d637fc6e36..8de7d63173 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -527,7 +527,7 @@ protected: }; - +#if LL_MESH_ENABLED class LLMeshBridge : public LLItemBridge { friend class LLInvFVBridge; @@ -543,7 +543,7 @@ protected: const LLUUID& uuid) : LLItemBridge(inventory, root, uuid) {} }; - +#endif diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index 7d82a10ca2..d8cfd4fc5d 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -159,7 +159,9 @@ BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, case DAD_ANIMATION: case DAD_GESTURE: case DAD_CALLINGCARD: +#if LL_MESH_ENABLED case DAD_MESH: +#endif { LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data; if(gInventory.getItem(inv_item->getUUID()) diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 898cabb03d..58df2746f3 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -819,7 +819,9 @@ BOOL LLTaskCategoryBridge::dragOrDrop(MASK mask, BOOL drop, case DAD_ANIMATION: case DAD_GESTURE: case DAD_CALLINGCARD: +#if LL_MESH_ENABLED case DAD_MESH: +#endif accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data); if(accept && drop) { @@ -1240,6 +1242,7 @@ LLUIImagePtr LLTaskWearableBridge::getIcon() const return LLInventoryIcon::getIcon(mAssetType, mInventoryType, FALSE, mFlags, FALSE ); } +#if LL_MESH_ENABLED ///---------------------------------------------------------------------------- /// Class LLTaskMeshBridge ///---------------------------------------------------------------------------- @@ -1351,6 +1354,7 @@ void LLTaskMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags) hide_context_entries(menu, items, disabled_items); } +#endif ///---------------------------------------------------------------------------- /// LLTaskInvFVBridge impl @@ -1431,11 +1435,13 @@ LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory* object->getUUID(), object->getName()); break; +#if LL_MESH_ENABLED case LLAssetType::AT_MESH: new_bridge = new LLTaskMeshBridge(panel, object->getUUID(), object->getName()); break; +#endif default: llinfos << "Unhandled inventory type (llassetstorage.h): " << (S32)type << llendl; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index ceef03d2f8..0ce7ffb077 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -6165,6 +6165,7 @@ S32 LLObjectSelection::getObjectCount(BOOL mesh_adjust) cleanupNodes(); S32 count = mList.size(); +#if LL_MESH_ENABLED if (mesh_adjust) { for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) @@ -6185,6 +6186,7 @@ S32 LLObjectSelection::getObjectCount(BOOL mesh_adjust) } } +#endif return count; } diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 7b57f09e59..6088c31559 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -292,7 +292,11 @@ BOOL LLFloaterTexturePicker::handleDragAndDrop( { BOOL handled = FALSE; - if ((cargo_type == DAD_TEXTURE) || (cargo_type == DAD_MESH)) + bool is_mesh = false; +#if LL_MESH_ENABLED + is_mesh = cargo_type == DAD_MESH; +#endif + if ((cargo_type == DAD_TEXTURE) || is_mesh) { LLInventoryItem *item = (LLInventoryItem *)cargo_data; @@ -1177,8 +1181,12 @@ BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, // returns true, then the cast was valid, and we can perform // the third test without problems. LLInventoryItem* item = (LLInventoryItem*)cargo_data; + bool is_mesh = false; +#if LL_MESH_ENABLED + is_mesh = cargo_type == DAD_MESH; +#endif if (getEnabled() && - ((cargo_type == DAD_TEXTURE) || (cargo_type == DAD_MESH)) && + ((cargo_type == DAD_TEXTURE) || is_mesh) && allowDrop(item)) { if (drop) diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 15924d67cf..d679ccd3d8 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -331,7 +331,9 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary() addEntry(DAD_ANIMATION, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_GESTURE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dActivateGesture, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_LINK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL)); +#if LL_MESH_ENABLED addEntry(DAD_MESH, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dMeshObject, &LLToolDragAndDrop::dad3dNULL)); +#endif // TODO: animation on self could play it? edit it? // TODO: gesture on self could play it? edit it? }; @@ -1035,6 +1037,7 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj, hit_obj->sendTEUpdate(); } +#if LL_MESH_EANBLED void LLToolDragAndDrop::dropMesh(LLViewerObject* hit_obj, LLInventoryItem* item, LLToolDragAndDrop::ESource source, @@ -1059,6 +1062,7 @@ void LLToolDragAndDrop::dropMesh(LLViewerObject* hit_obj, dialog_refresh_all(); } +#endif /* void LLToolDragAndDrop::dropTextureOneFaceAvatar(LLVOAvatar* avatar, S32 hit_face, LLInventoryItem* item) @@ -1501,7 +1505,9 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_ case DAD_ANIMATION: case DAD_GESTURE: case DAD_CALLINGCARD: +#if LL_MESH_ENABLED case DAD_MESH: +#endif { LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data; if(gInventory.getItem(inv_item->getUUID()) @@ -1858,10 +1864,12 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject( dropTextureOneFace(obj, face, item, mSource, mSourceID); } } +#if LL_MESH_ENABLED else if (cargo_type == DAD_MESH) { dropMesh(obj, item, mSource, mSourceID); } +#endif else { llwarns << "unsupported asset type" << llendl; @@ -1886,11 +1894,13 @@ EAcceptance LLToolDragAndDrop::dad3dTextureObject( return dad3dApplyToObject(obj, face, mask, drop, DAD_TEXTURE); } +#if LL_MESH_ENABLED EAcceptance LLToolDragAndDrop::dad3dMeshObject( LLViewerObject* obj, S32 face, MASK mask, BOOL drop) { return dad3dApplyToObject(obj, face, mask, drop, DAD_MESH); } +#endif diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h index 596cc2ee88..ceeaa8c820 100644 --- a/indra/newview/lltooldraganddrop.h +++ b/indra/newview/lltooldraganddrop.h @@ -154,8 +154,10 @@ protected: MASK mask, BOOL drop); EAcceptance dad3dTextureObject(LLViewerObject* obj, S32 face, MASK mask, BOOL drop); +#if LL_MESH_ENABLED EAcceptance dad3dMeshObject(LLViewerObject* obj, S32 face, MASK mask, BOOL drop); +#endif // EAcceptance dad3dTextureSelf(LLViewerObject* obj, S32 face, // MASK mask, BOOL drop); EAcceptance dad3dWearItem(LLViewerObject* obj, S32 face, @@ -242,10 +244,12 @@ public: LLInventoryItem* item, ESource source, const LLUUID& src_id); +#if LL_MESH_ENABLED static void dropMesh(LLViewerObject* hit_obj, LLInventoryItem* item, ESource source, const LLUUID& src_id); +#endif //static void dropTextureOneFaceAvatar(LLVOAvatar* avatar,S32 hit_face, // LLInventoryItem* item) diff --git a/indra/newview/llviewerassettype.cpp b/indra/newview/llviewerassettype.cpp index 4c088a72b7..370767002a 100644 --- a/indra/newview/llviewerassettype.cpp +++ b/indra/newview/llviewerassettype.cpp @@ -85,7 +85,9 @@ LLViewerAssetDictionary::LLViewerAssetDictionary() addEntry(LLViewerAssetType::AT_LINK, new ViewerAssetEntry(DAD_LINK)); addEntry(LLViewerAssetType::AT_LINK_FOLDER, new ViewerAssetEntry(DAD_LINK)); +#if LL_MESH_ENABLED addEntry(LLViewerAssetType::AT_MESH, new ViewerAssetEntry(DAD_MESH)); +#endif addEntry(LLViewerAssetType::AT_NONE, new ViewerAssetEntry(DAD_NONE)); }; diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 525610f983..c953fb23e3 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -177,7 +177,9 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("hud", "floater_hud.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); +#if LL_MESH_ENABLED LLFloaterReg::add("import_collada", "floater_import_collada.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); +#endif LLFloaterReg::add("im_container", "floater_im_container.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("im_well_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("incoming_call", "floater_incoming_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); @@ -258,7 +260,9 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("upload_anim", "floater_animation_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build, "upload"); LLFloaterReg::add("upload_image", "floater_image_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build, "upload"); LLFloaterReg::add("upload_sound", "floater_sound_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build, "upload"); +#if LL_MESH_ENABLED LLFloaterReg::add("upload_model", "floater_model_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build, "upload"); +#endif LLFloaterReg::add("voice_controls", "floater_voice_controls.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("voice_effect", "floater_voice_effect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index dd65ca2d25..af4549f7e1 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -350,6 +350,7 @@ class LLFileUploadImage : public view_listener_t } }; +#if LL_MESH_ENABLED class LLFileUploadScene : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -376,6 +377,7 @@ class LLFileUploadModel : public view_listener_t return TRUE; } }; +#endif class LLFileUploadSound : public view_listener_t { @@ -1144,6 +1146,7 @@ void upload_new_resource( lldebugs << "Folder: " << gInventory.findCategoryUUIDForType((destination_folder_type == LLFolderType::FT_NONE) ? LLFolderType::assetTypeToFolderType(asset_type) : destination_folder_type) << llendl; lldebugs << "Asset Type: " << LLAssetType::lookup(asset_type) << llendl; +#if LL_MESH_ENABLED std::string url = gAgent.getRegion()->getCapability( "NewFileAgentInventory"); @@ -1171,8 +1174,8 @@ void upload_new_resource( asset_type)); } else +#endif { - llinfos << "NewAgentInventory capability not found, new agent inventory via asset system." << llendl; // check for adequate funds // TODO: do this check on the sim if (LLAssetType::AT_SOUND == asset_type || @@ -1217,6 +1220,7 @@ void upload_new_resource( } } +#if LL_MESH_ENABLED BOOL upload_new_variable_price_resource( const LLTransactionID &tid, LLAssetType::EType asset_type, @@ -1288,6 +1292,7 @@ BOOL upload_new_variable_price_resource( return FALSE; } } +#endif LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid) { @@ -1358,8 +1363,10 @@ void init_menu_file() view_listener_t::addCommit(new LLFileUploadImage(), "File.UploadImage"); view_listener_t::addCommit(new LLFileUploadSound(), "File.UploadSound"); view_listener_t::addCommit(new LLFileUploadAnim(), "File.UploadAnim"); +#if LL_MESH_ENABLED view_listener_t::addCommit(new LLFileUploadModel(), "File.UploadModel"); view_listener_t::addCommit(new LLFileUploadScene(), "File.UploadScene"); +#endif view_listener_t::addCommit(new LLFileUploadBulk(), "File.UploadBulk"); view_listener_t::addCommit(new LLFileCloseWindow(), "File.CloseWindow"); view_listener_t::addCommit(new LLFileCloseAllWindows(), "File.CloseAllWindows"); diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h index 08444551a9..bb7cfce862 100644 --- a/indra/newview/llviewermenufile.h +++ b/indra/newview/llviewermenufile.h @@ -74,6 +74,7 @@ void upload_new_resource( S32 expected_upload_cost, void *userdata); +#if LL_MESH_ENABLED // TODO* : Move all uploads to use this new function // since at some point, that upload path will be deprecated and no longer // used @@ -91,6 +92,7 @@ BOOL upload_new_variable_price_resource( U32 everyone_perms, const std::string& display_name, const LLSD& asset_resources); +#endif LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid); void increase_new_upload_stats(LLAssetType::EType asset_type); diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index d35be8e1bf..697e8afa65 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -535,7 +535,9 @@ LLUIImagePtr LLEmbeddedItems::getItemImage(llwchar ext_char) const case LLAssetType::AT_BODYPART: img_name = "Inv_Skin"; break; case LLAssetType::AT_ANIMATION: img_name = "Inv_Animation"; break; case LLAssetType::AT_GESTURE: img_name = "Inv_Gesture"; break; +#if LL_MESH_ENABLED case LLAssetType::AT_MESH: img_name = "Inv_Mesh"; break; +#endif default: llassert(0); } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index fc4b590bf4..9f559331b0 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -591,8 +591,10 @@ public: if (gSavedSettings.getBOOL("DebugShowUploadCost")) { +#if LL_MESH_ENABLED addText(xpos, ypos, llformat(" Meshes: L$%d", gPipeline.mDebugMeshUploadCost)); ypos += y_inc/2; +#endif addText(xpos, ypos, llformat(" Sculpties: L$%d", gPipeline.mDebugSculptUploadCost)); ypos += y_inc/2; addText(xpos, ypos, llformat(" Textures: L$%d", gPipeline.mDebugTextureUploadCost)); @@ -602,6 +604,7 @@ public: ypos += y_inc; } +#if LL_MESH_ENABLED //temporary hack to give feedback on mesh upload progress if (!gMeshRepo.mUploads.empty()) { @@ -631,6 +634,7 @@ public: ypos += y_inc; } +#endif } void draw() diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index db9e0b88e1..d66aa567a8 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -926,6 +926,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms, const S32 detail, bool BOOL is404 = FALSE; +#if LL_MESH_ENABLED if (isSculpted()) { // if it's a mesh @@ -945,6 +946,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms, const S32 detail, bool } } } +#endif // Check if we need to change implementations bool is_flexible = (volume_params.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE); @@ -989,10 +991,11 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms, const S32 detail, bool updateSculptTexture(); + if (isSculpted()) { updateSculptTexture(); - +#if LL_MESH_ENABLED // if it's a mesh if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) { @@ -1008,6 +1011,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms, const S32 detail, bool } } else // otherwise is sculptie +#endif { if (mSculptTexture.notNull()) { @@ -2659,12 +2663,13 @@ BOOL LLVOVolume::isMesh() const { LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); U8 sculpt_type = sculpt_params->getSculptType(); - +#if LL_MESH_ENABLED if ((sculpt_type & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) // mesh is a mesh { return TRUE; } +#endif } return FALSE; @@ -3010,6 +3015,7 @@ F32 LLVOVolume::getBinRadius() F32 scale = 1.f; +#if LL_MESH_ENABLED if (isSculpted()) { LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); @@ -3031,6 +3037,7 @@ F32 LLVOVolume::getBinRadius() scale = 1.f/llmax(vert_count/1024.f, 1.f); } } +#endif const LLVector4a* ext = mDrawable->getSpatialExtents(); @@ -3513,9 +3520,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) drawablep->clearState(LLDrawable::HAS_ALPHA); +#if LL_MESH_ENABLED bool rigged = vobj->isAttachment() && vobj->isMesh() && gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID()); +#endif bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic(); @@ -3526,6 +3535,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) drawablep->updateFaceSize(i); LLFace* facep = drawablep->getFace(i); +#if LL_MESH_ENABLED if (rigged) { if (!facep->isState(LLFace::RIGGED)) @@ -3622,6 +3632,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) facep->clearState(LLFace::RIGGED); } } +#endif if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0) { diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 583b3df0e5..c5c7277211 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2025,7 +2025,9 @@ void LLPipeline::rebuildPriorityGroups() assertInitialized(); +#if LL_MESH_ENABLED gMeshRepo.notifyLoadedMeshes(); +#endif // Iterate through all drawables on the priority build queue, for (LLSpatialGroup::sg_list_t::iterator iter = mGroupQ1.begin(); @@ -3859,6 +3861,7 @@ void LLPipeline::renderDebug() gPipeline.mDebugTextureUploadCost = textures.size() * 10; gPipeline.mDebugSculptUploadCost = sculpts.size()*10; +#if LL_MESH_ENABLED U32 mesh_cost = 0; for (std::set::iterator iter = meshes.begin(); iter != meshes.end(); ++iter) @@ -3867,6 +3870,7 @@ void LLPipeline::renderDebug() } gPipeline.mDebugMeshUploadCost = mesh_cost; +#endif } for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 4e8760947c..95f951b393 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -45,6 +45,7 @@ #include "llgl.h" #include "lldrawable.h" #include "llrendertarget.h" +#include "llmodel.h" //for LL_MESH_ENaBLED #include @@ -61,7 +62,10 @@ class LLCullResult; class LLVOAvatar; class LLGLSLShader; class LLCurlRequest; + +#if LL_MESH_ENABLED class LLMeshResponder; +#endif typedef enum e_avatar_skinning_method { @@ -465,7 +469,9 @@ public: S32 mDebugTextureUploadCost; S32 mDebugSculptUploadCost; +#if LL_MESH_ENABLED S32 mDebugMeshUploadCost; +#endif S32 mLightingChanges; S32 mGeometryChanges; @@ -712,13 +718,6 @@ public: protected: std::vector mSelectedFaces; - - typedef std::map > mesh_load_map; - mesh_load_map mLoadingMeshes[4]; - - typedef std::list mesh_response_list; - mesh_response_list mMeshResponseList; - LLPointer mFaceSelectImagep; U32 mLightMask; diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml index 8b431e9c54..b54bad98d0 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -160,7 +160,7 @@ layout="topleft" left="5" name="CustomGraphics Panel" - top="101" + top="76" width="485"> Low @@ -625,7 +625,7 @@ follows="left|top" height="12" layout="topleft" - left_delta="-260" + left="200" name="AvatarRenderingText" top_pad="8" width="128"> @@ -673,7 +673,7 @@ left="358" left_pad="-30" name="TerrainDetailText" - top="488" + top="226" width="155"> Terrain detail: -- cgit v1.3 From 9440f84dca48e3e2f6022dbf5f916d6439c7a826 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 10 Jun 2010 14:58:02 -0500 Subject: Potential fix for busted binormals on cubes. --- indra/llmath/llvolume.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 05868e3517..ba5d5e7ca1 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -5566,6 +5566,8 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) 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); -- cgit v1.3 From d2d49e3d84956ec4efb9f1a7a308d530c7fc4737 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 10 Jun 2010 15:02:41 -0500 Subject: Fix for memcpyNonAliased16 issues. --- indra/llmath/llvolume.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 09ab47b890..cafa1e5c44 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -5255,7 +5255,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) src.mPositions, vert_size); LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) src.mNormals, vert_size); - LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, vert_size); + LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, tc_size); if (src.mBinormals) -- cgit v1.3 From 3ea0018dc6f94c029d7dbf13bdd5b0bc0558c8d8 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 10 Jun 2010 15:07:30 -0500 Subject: Enable meshes. --- indra/llmath/llvolume.h | 2 +- indra/newview/app_settings/settings.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 0782944079..98db7f31c0 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -41,7 +41,7 @@ class LLVolumeParams; class LLProfile; class LLPath; -#define LL_MESH_ENABLED 0 +#define LL_MESH_ENABLED 1 template class LLOctreeNode; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index df9393c316..1d5d1584d3 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4908,7 +4908,7 @@ Type Boolean Value - 0 + 1 MigrateCacheDirectory -- cgit v1.3