summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2010-05-26 03:29:19 -0500
committerDave Parks <davep@lindenlab.com>2010-05-26 03:29:19 -0500
commitc98b1b3fd9341834978aff0e841714e206d28c0a (patch)
treea7690096c11dd57119726dc4872d57aae083154d /indra
parente6fe3b1f1aa888e4594c89154ef895b3cf5498e9 (diff)
Fully aligned llvolume
Diffstat (limited to 'indra')
-rw-r--r--indra/llmath/llvolume.cpp353
-rw-r--r--indra/llmath/llvolume.h99
-rw-r--r--indra/llmath/v3math.h1
-rw-r--r--indra/newview/llface.cpp272
-rw-r--r--indra/newview/llpanelprimmediacontrols.cpp4
-rw-r--r--indra/newview/llvovolume.cpp3
6 files changed, 468 insertions, 264 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*) &center.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 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 <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 &center, 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<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
}
}