Migrated gl matrix stack to LLMatrix4a

This commit is contained in:
Shyotl
2014-06-22 03:34:51 -05:00
parent 8f6a578ec0
commit 061178ad82
64 changed files with 1533 additions and 1070 deletions

View File

@@ -31,15 +31,72 @@
#include "m4math.h"
#include "m3math.h"
LL_ALIGN_PREFIX(16)
class LLMatrix4a
{
public:
private:
LL_ALIGN_16(LLVector4a mMatrix[4]);
public:
enum
{
ROW_FWD = 0,
ROW_LEFT,
ROW_UP,
ROW_TRANS
};
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
}
LLMatrix4a()
{}
LLMatrix4a(const LLQuad& q1,const LLQuad& q2,const LLQuad& q3,const LLQuad& q4)
{
mMatrix[0] = q1;
mMatrix[1] = q2;
mMatrix[2] = q3;
mMatrix[3] = q4;
}
LLMatrix4a(const LLQuaternion2& quat)
{
const LLVector4a& xyzw = quat.getVector4a();
LLVector4a nyxwz = _mm_shuffle_ps(xyzw, xyzw, _MM_SHUFFLE(2,3,0,1));
nyxwz.negate();
const LLVector4a xnyynx = _mm_unpacklo_ps(xyzw,nyxwz);
const LLVector4a znwwnz = _mm_unpackhi_ps(xyzw,nyxwz);
LLMatrix4a mata;
mata.setRow<0>(_mm_shuffle_ps(xyzw, xnyynx, _MM_SHUFFLE(0,1,2,3)));
mata.setRow<1>(_mm_shuffle_ps(znwwnz, xyzw, _MM_SHUFFLE(1,0,2,3)));
mata.setRow<2>(_mm_shuffle_ps(xnyynx, xyzw, _MM_SHUFFLE(2,3,3,2)));
mata.setRow<3>(_mm_shuffle_ps(xnyynx, znwwnz, _MM_SHUFFLE(2,3,1,3)));
LLMatrix4a matb;
matb.setRow<0>(_mm_shuffle_ps(xyzw, xnyynx, _MM_SHUFFLE(3,1,2,3)));
matb.setRow<1>(_mm_shuffle_ps(znwwnz, xnyynx, _MM_SHUFFLE(1,0,2,3)));
matb.setRow<2>(_mm_shuffle_ps(xnyynx, znwwnz, _MM_SHUFFLE(3,2,3,2)));
matb.setRow<3>(xyzw);
setMul(matb,mata);
}
inline F32* getF32ptr()
{
return mMatrix[0].getF32ptr();
}
inline const F32* getF32ptr() const
{
return mMatrix[0].getF32ptr();
}
inline void clear()
{
@@ -60,10 +117,10 @@ public:
inline void loadu(const LLMatrix4& src)
{
mMatrix[0] = _mm_loadu_ps(src.mMatrix[0]);
mMatrix[1] = _mm_loadu_ps(src.mMatrix[1]);
mMatrix[2] = _mm_loadu_ps(src.mMatrix[2]);
mMatrix[3] = _mm_loadu_ps(src.mMatrix[3]);
mMatrix[0].loadua(src.mMatrix[0]);
mMatrix[1].loadua(src.mMatrix[1]);
mMatrix[2].loadua(src.mMatrix[2]);
mMatrix[3].loadua(src.mMatrix[3]);
}
inline void loadu(const LLMatrix3& src)
@@ -76,10 +133,10 @@ public:
inline void loadu(const F32* src)
{
mMatrix[0] = _mm_loadu_ps(src+0);
mMatrix[1] = _mm_loadu_ps(src+4);
mMatrix[2] = _mm_loadu_ps(src+8);
mMatrix[3] = _mm_loadu_ps(src+12);
mMatrix[0].loadua(src+0);
mMatrix[1].loadua(src+4);
mMatrix[2].loadua(src+8);
mMatrix[3].loadua(src+12);
}
inline void add(const LLMatrix4a& rhs)
@@ -90,6 +147,75 @@ public:
mMatrix[3].add(rhs.mMatrix[3]);
}
inline void mul(const LLMatrix4a& rhs)
{
//Not using rotate4 to avoid extra copy of *this.
LLVector4a x0,y0,z0,w0;
LLVector4a x1,y1,z1,w1;
LLVector4a x2,y2,z2,w2;
LLVector4a x3,y3,z3,w3;
//16 shuffles
x0.splat<0>(rhs.mMatrix[0]);
x1.splat<0>(rhs.mMatrix[1]);
x2.splat<0>(rhs.mMatrix[2]);
x3.splat<0>(rhs.mMatrix[3]);
y0.splat<1>(rhs.mMatrix[0]);
y1.splat<1>(rhs.mMatrix[1]);
y2.splat<1>(rhs.mMatrix[2]);
y3.splat<1>(rhs.mMatrix[3]);
z0.splat<2>(rhs.mMatrix[0]);
z1.splat<2>(rhs.mMatrix[1]);
z2.splat<2>(rhs.mMatrix[2]);
z3.splat<2>(rhs.mMatrix[3]);
w0.splat<3>(rhs.mMatrix[0]);
w1.splat<3>(rhs.mMatrix[1]);
w2.splat<3>(rhs.mMatrix[2]);
w3.splat<3>(rhs.mMatrix[3]);
//16 muls
x0.mul(mMatrix[0]);
x1.mul(mMatrix[0]);
x2.mul(mMatrix[0]);
x3.mul(mMatrix[0]);
y0.mul(mMatrix[1]);
y1.mul(mMatrix[1]);
y2.mul(mMatrix[1]);
y3.mul(mMatrix[1]);
z0.mul(mMatrix[2]);
z1.mul(mMatrix[2]);
z2.mul(mMatrix[2]);
z3.mul(mMatrix[2]);
w0.mul(mMatrix[3]);
w1.mul(mMatrix[3]);
w2.mul(mMatrix[3]);
w3.mul(mMatrix[3]);
//12 adds
x0.add(y0);
z0.add(w0);
x1.add(y1);
z1.add(w1);
x2.add(y2);
z2.add(w2);
x3.add(y3);
z3.add(w3);
mMatrix[0].setAdd(x0,z0);
mMatrix[1].setAdd(x1,z1);
mMatrix[2].setAdd(x2,z2);
mMatrix[3].setAdd(x3,z3);
}
inline void setRows(const LLVector4a& r0, const LLVector4a& r1, const LLVector4a& r2)
{
mMatrix[0] = r0;
@@ -97,6 +223,44 @@ public:
mMatrix[2] = r2;
}
template<int N>
inline void setRow(const LLVector4a& row)
{
mMatrix[N] = row;
}
template<int N>
inline const LLVector4a& getRow() const
{
return mMatrix[N];
}
template<int N>
inline LLVector4a& getRow()
{
return mMatrix[N];
}
template<int N>
inline void setColumn(const LLVector4a& col)
{
mMatrix[0].copyComponent<N>(col.getScalarAt<0>());
mMatrix[1].copyComponent<N>(col.getScalarAt<1>());
mMatrix[2].copyComponent<N>(col.getScalarAt<2>());
mMatrix[3].copyComponent<N>(col.getScalarAt<3>());
}
template<int N>
inline LLVector4a getColumn()
{
LLVector4a v;
v.copyComponent<0>(mMatrix[0].getScalarAt<N>());
v.copyComponent<1>(mMatrix[1].getScalarAt<N>());
v.copyComponent<2>(mMatrix[2].getScalarAt<N>());
v.copyComponent<3>(mMatrix[3].getScalarAt<N>());
return v;
}
inline void setMul(const LLMatrix4a& m, const F32 s)
{
mMatrix[0].setMul(m.mMatrix[0], s);
@@ -136,13 +300,14 @@ public:
//Singu Note: Don't mess with this. It's intentionally different from LL's.
// Note how res isn't manipulated until the very end.
//Fast(er). Treats v[VW] as 0.f
inline void rotate(const LLVector4a& v, LLVector4a& res) const
{
LLVector4a x,y,z;
x = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0));
y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1));
z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2));
x.splat<0>(v);
y.splat<1>(v);
z.splat<2>(v);
x.mul(mMatrix[0]);
y.mul(mMatrix[1]);
@@ -152,14 +317,15 @@ public:
res.setAdd(x,z);
}
//Proper. v[VW] as v[VW]
inline void rotate4(const LLVector4a& v, LLVector4a& res) const
{
LLVector4a x,y,z,w;
x = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0));
y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1));
z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2));
w = _mm_shuffle_ps(v, v, _MM_SHUFFLE(3, 3, 3, 3));
x.splat<0>(v);
y.splat<1>(v);
z.splat<2>(v);
w.splat<3>(v);
x.mul(mMatrix[0]);
y.mul(mMatrix[1]);
@@ -171,14 +337,15 @@ public:
res.setAdd(x,z);
}
//Fast(er). Treats v[VW] as 1.f
inline void affineTransform(const LLVector4a& v, LLVector4a& res) const
{
LLVector4a x,y,z;
x = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0));
y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1));
z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2));
x.splat<0>(v);
y.splat<1>(v);
z.splat<2>(v);
x.mul(mMatrix[0]);
y.mul(mMatrix[1]);
z.mul(mMatrix[2]);
@@ -188,6 +355,36 @@ public:
res.setAdd(x,z);
}
inline void perspectiveTransform(const LLVector4a& v, LLVector4a& res) const
{
LLVector4a x,y,z,s,t,p,q;
x.splat<0>(v);
y.splat<1>(v);
z.splat<2>(v);
s.splat<3>(mMatrix[0]);
t.splat<3>(mMatrix[1]);
p.splat<3>(mMatrix[2]);
q.splat<3>(mMatrix[3]);
s.mul(x);
t.mul(y);
p.mul(z);
q.add(s);
t.add(p);
q.add(t);
x.mul(mMatrix[0]);
y.mul(mMatrix[1]);
z.mul(mMatrix[2]);
x.add(y);
z.add(mMatrix[3]);
res.setAdd(x,z);
res.div(q);
}
inline void transpose()
{
__m128 q1 = _mm_unpackhi_ps(mMatrix[0],mMatrix[1]);
@@ -313,9 +510,186 @@ public:
mMatrix[1] = _mm_shuffle_ps(iA,iB,0x22);
mMatrix[2] = _mm_shuffle_ps(iC,iD,0x77);
mMatrix[3] = _mm_shuffle_ps(iC,iD,0x22);
return *(float*)&det;
F32 ret;
_mm_store_ss(&ret,det);
return ret;
}
};
//=============Affine transformation matrix only=========================
//Multiply matrix with a pure translation matrix.
inline void applyTranslation_affine(const F32& x, const F32& y, const F32& z)
{
const LLVector4a xyz0(x,y,z,0); //load
LLVector4a xxxx;
xxxx.splat<0>(xyz0);
LLVector4a yyyy;
yyyy.splat<1>(xyz0);
LLVector4a zzzz;
zzzz.splat<2>(xyz0);
LLVector4a sum1;
LLVector4a sum2;
LLVector4a sum3;
sum1.setMul(xxxx,mMatrix[0]);
sum2.setMul(yyyy,mMatrix[1]);
sum3.setMul(zzzz,mMatrix[2]);
mMatrix[3].add(sum1);
mMatrix[3].add(sum2);
mMatrix[3].add(sum3);
}
//Multiply matrix with a pure translation matrix.
inline void applyTranslation_affine(const LLVector3& trans)
{
applyTranslation_affine(trans.mV[VX],trans.mV[VY],trans.mV[VZ]);
}
//Multiply matrix with a pure scale matrix.
inline void applyScale_affine(const F32& x, const F32& y, const F32& z)
{
const LLVector4a xyz0(x,y,z,0); //load
LLVector4a xxxx;
xxxx.splat<0>(xyz0);
LLVector4a yyyy;
yyyy.splat<1>(xyz0);
LLVector4a zzzz;
zzzz.splat<2>(xyz0);
mMatrix[0].mul(xxxx);
mMatrix[1].mul(yyyy);
mMatrix[2].mul(zzzz);
}
//Multiply matrix with a pure scale matrix.
inline void applyScale_affine(const LLVector3& scale)
{
applyScale_affine(scale.mV[VX],scale.mV[VY],scale.mV[VZ]);
}
//Multiply matrix with a pure scale matrix.
inline void applyScale_affine(const F32& s)
{
const LLVector4a scale(s); //load
mMatrix[0].mul(scale);
mMatrix[1].mul(scale);
mMatrix[2].mul(scale);
}
//Direct addition to row3.
inline void translate_affine(const LLVector3& trans)
{
LLVector4a translation;
translation.load3(trans.mV);
mMatrix[3].add(translation);
}
//Direct assignment of row3.
inline void setTranslate_affine(const LLVector3& trans)
{
static const LLVector4Logical mask = _mm_load_ps((F32*)&S_V4LOGICAL_MASK_TABLE[3*4]);
LLVector4a translation;
translation.load3(trans.mV);
mMatrix[3].setSelectWithMask(mask,mMatrix[3],translation);
}
inline void mul_affine(const LLMatrix4a& rhs)
{
LLVector4a x0,y0,z0;
LLVector4a x1,y1,z1;
LLVector4a x2,y2,z2;
LLVector4a x3,y3,z3;
//12 shuffles
x0.splat<0>(rhs.mMatrix[0]);
x1.splat<0>(rhs.mMatrix[1]);
x2.splat<0>(rhs.mMatrix[2]);
x3.splat<0>(rhs.mMatrix[3]);
y0.splat<1>(rhs.mMatrix[0]);
y1.splat<1>(rhs.mMatrix[1]);
y2.splat<1>(rhs.mMatrix[2]);
y3.splat<1>(rhs.mMatrix[3]);
z0.splat<2>(rhs.mMatrix[0]);
z1.splat<2>(rhs.mMatrix[1]);
z2.splat<2>(rhs.mMatrix[2]);
z3.splat<2>(rhs.mMatrix[3]);
//12 muls
x0.mul(mMatrix[0]);
x1.mul(mMatrix[0]);
x2.mul(mMatrix[0]);
x3.mul(mMatrix[0]);
y0.mul(mMatrix[1]);
y1.mul(mMatrix[1]);
y2.mul(mMatrix[1]);
y3.mul(mMatrix[1]);
z0.mul(mMatrix[2]);
z1.mul(mMatrix[2]);
z2.mul(mMatrix[2]);
z3.mul(mMatrix[2]);
//9 adds
x0.add(y0);
x1.add(y1);
x2.add(y2);
x3.add(y3);
z3.add(mMatrix[3]);
mMatrix[0].setAdd(x0,z0);
mMatrix[1].setAdd(x1,z1);
mMatrix[2].setAdd(x2,z2);
mMatrix[3].setAdd(x3,z3);
}
inline void extractRotation_affine()
{
static const LLVector4Logical mask = _mm_load_ps((F32*)&S_V4LOGICAL_MASK_TABLE[3*4]);
mMatrix[0].setSelectWithMask(mask,_mm_setzero_ps(),mMatrix[0]);
mMatrix[1].setSelectWithMask(mask,_mm_setzero_ps(),mMatrix[1]);
mMatrix[2].setSelectWithMask(mask,_mm_setzero_ps(),mMatrix[2]);
mMatrix[3].setSelectWithMask(mask,LLVector4a(1.f),_mm_setzero_ps());
}
//======================Logic====================
inline bool isIdentity() const
{
static LLMatrix4a mins;
static LLMatrix4a maxs;
static LLVector4a delta(0.0001f);
static bool init_mins = ( mins.setIdentity(),
mins.getRow<0>().sub(delta),
mins.getRow<1>().sub(delta),
mins.getRow<2>().sub(delta),
mins.getRow<3>().sub(delta), true );
static bool init_maxs = ( maxs.setIdentity(),
maxs.getRow<0>().add(delta),
maxs.getRow<1>().add(delta),
maxs.getRow<2>().add(delta),
maxs.getRow<3>().add(delta), true );
LLVector4a mask1 = _mm_and_ps(_mm_cmpgt_ps(mMatrix[0],mins.getRow<0>()), _mm_cmplt_ps(mMatrix[0],maxs.getRow<0>()));
LLVector4a mask2 = _mm_and_ps(_mm_cmpgt_ps(mMatrix[1],mins.getRow<1>()), _mm_cmplt_ps(mMatrix[1],maxs.getRow<1>()));
LLVector4a mask3 = _mm_and_ps(_mm_cmpgt_ps(mMatrix[2],mins.getRow<2>()), _mm_cmplt_ps(mMatrix[2],maxs.getRow<2>()));
LLVector4a mask4 = _mm_and_ps(_mm_cmpgt_ps(mMatrix[3],mins.getRow<3>()), _mm_cmplt_ps(mMatrix[3],maxs.getRow<3>()));
mask1 = _mm_and_ps(mask1,mask2);
mask2 = _mm_and_ps(mask3,mask4);
return _mm_movemask_epi8(_mm_castps_si128(_mm_and_ps(mask1, mask2))) == 0xFFFF;
}
} LL_ALIGN_POSTFIX(16);
#endif

View File

@@ -84,6 +84,8 @@ public:
// Quantize this quaternion to 16 bit precision
inline void quantize16();
inline void mul(const LLQuaternion2& b);
/////////////////////////
// Quaternion inspection
/////////////////////////

View File

@@ -50,6 +50,39 @@ inline LLVector4a& LLQuaternion2::getVector4aRw()
return mQ;
}
inline void LLQuaternion2::mul(const LLQuaternion2& b)
{
static LL_ALIGN_16(const unsigned int signMask[4]) = { 0x0, 0x0, 0x0, 0x80000000 };
LLVector4a sum1, sum2, prod1, prod2, prod3, prod4;
const LLVector4a& va = mQ;
const LLVector4a& vb = b.getVector4a();
// [VX] [VY] [VZ] [VW]
//prod1: +wx +wy +wz +ww Bwwww*Axyzw
//prod2: +xw +yw +zw -xx Bxyzx*Awwwx [VW] sign flip
//prod3: +yz +zx +xy -yy Byzxy*Azxyy [VW] sign flip
//prod4: -zy -xz -yx -zz Bzxyz*Ayzzz
const LLVector4a Bwwww = _mm_shuffle_ps(vb,vb,_MM_SHUFFLE(3,3,3,3));
const LLVector4a Bxyzx = _mm_shuffle_ps(vb,vb,_MM_SHUFFLE(0,2,1,0));
const LLVector4a Awwwx = _mm_shuffle_ps(va,va,_MM_SHUFFLE(0,3,3,3));
const LLVector4a Byzxy = _mm_shuffle_ps(vb,vb,_MM_SHUFFLE(1,0,2,1));
const LLVector4a Azxyy = _mm_shuffle_ps(va,va,_MM_SHUFFLE(1,1,0,2));
const LLVector4a Bzxyz = _mm_shuffle_ps(vb,vb,_MM_SHUFFLE(2,1,0,2));
const LLVector4a Ayzxz = _mm_shuffle_ps(va,va,_MM_SHUFFLE(2,0,2,1));
prod1.setMul(Bwwww,va);
prod2.setMul(Bxyzx,Awwwx);
prod3.setMul(Byzxy,Azxyy);
prod4.setMul(Bzxyz,Ayzxz);
sum1.setAdd(prod2,prod3);
sum1 = _mm_xor_ps(sum1, _mm_load_ps((const float*)signMask));
sum2.setSub(prod1,prod4);
mQ.setAdd(sum1,sum2);
}
/////////////////////////
// Quaternion modification
/////////////////////////

View File

@@ -127,7 +127,7 @@ public:
inline void loadua(const F32* src);
// Load only three floats beginning at address 'src'. Slowest method.
inline void load3(const F32* src);
inline void load3(const F32* src, const F32 w=0.f);
// Store to a 16-byte aligned memory address
inline void store4a(F32* dst) const;
@@ -169,6 +169,9 @@ public:
// Set all 4 elements to element i of v, with i NOT known at compile time
inline void splat(const LLVector4a& v, U32 i);
// Sets element N to that of src's element N. Much cleaner than.. {LLVector4Logical mask; mask.clear(); mask.setElement<N>(); target.setSelectWithMask(mask,src,target);}
template <int N> inline void copyComponent(const LLVector4a& src);
// Select bits from sourceIfTrue and sourceIfFalse according to bits in mask
inline void setSelectWithMask( const LLVector4Logical& mask, const LLVector4a& sourceIfTrue, const LLVector4a& sourceIfFalse );
@@ -281,6 +284,8 @@ public:
void quantize8( const LLVector4a& low, const LLVector4a& high );
void quantize16( const LLVector4a& low, const LLVector4a& high );
void negate();
////////////////////////////////////
// LOGICAL
////////////////////////////////////

View File

@@ -41,11 +41,11 @@ inline void LLVector4a::loadua(const F32* src)
}
// Load only three floats beginning at address 'src'. Slowest method.
inline void LLVector4a::load3(const F32* src)
inline void LLVector4a::load3(const F32* src, const F32 w)
{
// mQ = { 0.f, src[2], src[1], src[0] } = { W, Z, Y, X }
// NB: This differs from the convention of { Z, Y, X, W }
mQ = _mm_set_ps(0.f, src[2], src[1], src[0]);
mQ = _mm_set_ps(w, src[2], src[1], src[0]);
}
// Store to a 16-byte aligned memory address
@@ -154,6 +154,13 @@ inline void LLVector4a::splat(const LLVector4a& v, U32 i)
}
}
// Sets element N to that of src's element N
template <int N> inline void LLVector4a::copyComponent(const LLVector4a& src)
{
static const LLVector4Logical mask = _mm_load_ps((F32*)&S_V4LOGICAL_MASK_TABLE[N*4]);
setSelectWithMask(mask,src,mQ);
}
// Select bits from sourceIfTrue and sourceIfFalse according to bits in mask
inline void LLVector4a::setSelectWithMask( const LLVector4Logical& mask, const LLVector4a& sourceIfTrue, const LLVector4a& sourceIfFalse )
{
@@ -529,6 +536,11 @@ inline void LLVector4a::clamp( const LLVector4a& low, const LLVector4a& high )
setSelectWithMask( lowMask, low, *this );
}
inline void LLVector4a::negate()
{
static LL_ALIGN_16(const U32 signMask[4]) = {0x80000000, 0x80000000, 0x80000000, 0x80000000 };
mQ = _mm_xor_ps(*reinterpret_cast<const LLQuad*>(signMask), mQ);
}
////////////////////////////////////
// LOGICAL

View File

@@ -79,7 +79,7 @@ public:
{
static const LL_ALIGN_16(U32 allOnes[4]) = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
ll_assert_aligned(allOnes,16);
mQ = _mm_andnot_ps( mQ, *(LLQuad*)(allOnes) );
mQ = _mm_andnot_ps( mQ, _mm_load_ps((F32*)(allOnes)));
return *this;
}
@@ -115,7 +115,7 @@ public:
template<int N> void setElement()
{
mQ = _mm_or_ps( mQ, *reinterpret_cast<const LLQuad*>(S_V4LOGICAL_MASK_TABLE + 4*N) );
mQ = _mm_or_ps( mQ, _mm_load_ps( (F32*)&S_V4LOGICAL_MASK_TABLE[4*N] ) );
}
private:

View File

@@ -96,30 +96,29 @@ void LLXformMatrix::updateMatrix(BOOL update_bounds)
{
update();
mWorldMatrix.initAll(mScale, mWorldRotation, mWorldPosition);
LLMatrix4 world_matrix;
world_matrix.initAll(mScale, mWorldRotation, mWorldPosition);
mWorldMatrix.loadu(world_matrix);
if (update_bounds && (mChanged & MOVED))
{
mMin.mV[0] = mMax.mV[0] = mWorldMatrix.mMatrix[3][0];
mMin.mV[1] = mMax.mV[1] = mWorldMatrix.mMatrix[3][1];
mMin.mV[2] = mMax.mV[2] = mWorldMatrix.mMatrix[3][2];
mMax = mMin = mWorldMatrix.getRow<3>();
F32 f0 = (fabs(mWorldMatrix.mMatrix[0][0])+fabs(mWorldMatrix.mMatrix[1][0])+fabs(mWorldMatrix.mMatrix[2][0])) * 0.5f;
F32 f1 = (fabs(mWorldMatrix.mMatrix[0][1])+fabs(mWorldMatrix.mMatrix[1][1])+fabs(mWorldMatrix.mMatrix[2][1])) * 0.5f;
F32 f2 = (fabs(mWorldMatrix.mMatrix[0][2])+fabs(mWorldMatrix.mMatrix[1][2])+fabs(mWorldMatrix.mMatrix[2][2])) * 0.5f;
LLVector4a total_sum,sum1,sum2;
total_sum.setAbs(mWorldMatrix.getRow<0>());
sum1.setAbs(mWorldMatrix.getRow<1>());
sum2.setAbs(mWorldMatrix.getRow<2>());
sum1.add(sum2);
total_sum.add(sum1);
total_sum.mul(.5f);
mMin.mV[0] -= f0;
mMin.mV[1] -= f1;
mMin.mV[2] -= f2;
mMax.mV[0] += f0;
mMax.mV[1] += f1;
mMax.mV[2] += f2;
mMax.add(total_sum);
mMin.sub(total_sum);
}
}
void LLXformMatrix::getMinMax(LLVector3& min, LLVector3& max) const
{
min = mMin;
max = mMax;
min.set(mMin.getF32ptr());
max.set(mMax.getF32ptr());
}

View File

@@ -28,6 +28,7 @@
#include "v3math.h"
#include "m4math.h"
#include "llmatrix4a.h"
#include "llquaternion.h"
const F32 MAX_OBJECT_Z = 4096.f; // should match REGION_HEIGHT_METERS, Pre-havok4: 768.f
@@ -130,20 +131,21 @@ public:
const LLVector3& getWorldPosition() const { return mWorldPosition; }
};
LL_ALIGN_PREFIX(16)
class LLXformMatrix : public LLXform
{
public:
LLXformMatrix() : LLXform() {};
virtual ~LLXformMatrix();
const LLMatrix4& getWorldMatrix() const { return mWorldMatrix; }
void setWorldMatrix (const LLMatrix4& mat) { mWorldMatrix = mat; }
const LLMatrix4a& getWorldMatrix() const { return mWorldMatrix; }
void setWorldMatrix (const LLMatrix4a& mat) { mWorldMatrix = mat; }
void init()
{
mWorldMatrix.setIdentity();
mMin.clearVec();
mMax.clearVec();
mMin.clear();
mMax.clear();
LLXform::init();
}
@@ -153,11 +155,11 @@ public:
void getMinMax(LLVector3& min,LLVector3& max) const;
protected:
LLMatrix4 mWorldMatrix;
LLVector3 mMin;
LLVector3 mMax;
LL_ALIGN_16(LLMatrix4a mWorldMatrix);
LL_ALIGN_16(LLVector4a mMin);
LL_ALIGN_16(LLVector4a mMax);
};
} LL_ALIGN_POSTFIX(16);
BOOL LLXform::setParent(LLXform* parent)
{