diff options
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llmath/llvolume.cpp | 353 | ||||
-rw-r--r-- | indra/llmath/llvolume.h | 99 | ||||
-rw-r--r-- | indra/llmath/v3math.h | 1 | ||||
-rw-r--r-- | indra/newview/llface.cpp | 270 | ||||
-rw-r--r-- | indra/newview/llpanelprimmediacontrols.cpp | 4 | ||||
-rw-r--r-- | indra/newview/llvovolume.cpp | 3 |
6 files changed, 467 insertions, 263 deletions
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]; @@ -4166,6 +4236,18 @@ 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; S32 start_face; @@ -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<LLVolumeFace::VertexData>& v, std::vector<U16>& 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] = <joint_index>.<weight> // mWeights.size() should be empty or match mVertices.size() - std::vector<LLVector4> 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 1571bab7de..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 <u,v> 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); @@ -373,6 +382,13 @@ void LLFace::setSize(S32 num_vertices, S32 num_indices, bool align) //allocate vertices in blocks of 4 for alignment num_vertices = (num_vertices + 0x3) & ~0x3; } + else + { + if (mDrawablep->getVOVolume()) + { + llerrs << "WTF?" << llendl; + } + } if (mGeomCount != num_vertices || mIndicesCount != num_indices) @@ -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<LLVector3> vertices; + LLStrider<LLVector3> vert; + LLVector4a* vertices = NULL; LLStrider<LLVector2> tex_coords; LLStrider<LLVector2> tex_coords2; - LLStrider<LLVector3> normals; + LLVector4a* normals = NULL; + LLStrider<LLVector3> norm; LLStrider<LLColor4U> colors; - LLStrider<LLVector3> binormals; + LLVector4a* binormals = NULL; + LLStrider<LLVector3> binorm; LLStrider<U16> indicesp; - LLStrider<LLVector4> weights; + LLVector4a* weights = NULL; + LLStrider<LLVector4> 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<F32&>(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 } } |