diff options
| author | Roxie Linden <roxie@lindenlab.com> | 2010-12-23 01:48:44 -0800 |
|---|---|---|
| committer | Roxie Linden <roxie@lindenlab.com> | 2010-12-23 01:48:44 -0800 |
| commit | 57153cf0f1fffe669b9d8871c33f9c4aaba67a2f (patch) | |
| tree | 42e58fd10165bcd4bb7e65f5fbab7a16b518ddc3 /indra/llmath/llplane.h | |
| parent | 4351160958efa1c352e8af1ab3f48c1486ba9c5c (diff) | |
SH-655 - Project mesh viewer crashes on exit.
A copy constructor was implemented which did a memcpy,
which included the vtable pointer which was to another object of another
class (same child though). This resulted in the wrong destructor
being called.
The reason for the memcpy was for alignment purposes.
The solution was to move to LLVector4a, which is intrinsicly aligned.
Also, did some performance optimizations based on the LLVector4a optimizations.
The solution was to re-implement the
Diffstat (limited to 'indra/llmath/llplane.h')
| -rw-r--r-- | indra/llmath/llplane.h | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/indra/llmath/llplane.h b/indra/llmath/llplane.h index 443f3f46b9..a611894721 100644 --- a/indra/llmath/llplane.h +++ b/indra/llmath/llplane.h @@ -36,19 +36,23 @@ // The plane normal = [A, B, C] // The closest approach = D / sqrt(A*A + B*B + C*C) -class LLPlane : public LLVector4 +class LLPlane { public: + + // Constructors LLPlane() {}; // no default constructor LLPlane(const LLVector3 &p0, F32 d) { setVec(p0, d); } LLPlane(const LLVector3 &p0, const LLVector3 &n) { setVec(p0, n); } - void setVec(const LLVector3 &p0, F32 d) { LLVector4::setVec(p0[0], p0[1], p0[2], d); } - void setVec(const LLVector3 &p0, const LLVector3 &n) + inline void setVec(const LLVector3 &p0, F32 d) { mV.set(p0[0], p0[1], p0[2], d); } + + // Set + inline void setVec(const LLVector3 &p0, const LLVector3 &n) { F32 d = -(p0 * n); setVec(n, d); } - void setVec(const LLVector3 &p0, const LLVector3 &p1, const LLVector3 &p2) + inline void setVec(const LLVector3 &p0, const LLVector3 &p1, const LLVector3 &p2) { LLVector3 u, v, w; u = p1 - p0; @@ -58,8 +62,38 @@ public: F32 d = -(w * p0); setVec(w, d); } - LLPlane& operator=(const LLVector4& v2) { LLVector4::setVec(v2[0],v2[1],v2[2],v2[3]); return *this;} + + inline LLPlane& operator=(const LLVector4& v2) { mV.set(v2[0],v2[1],v2[2],v2[3]); return *this;} + + inline LLPlane& operator=(const LLVector4a& v2) { mV.set(v2[0],v2[1],v2[2],v2[3]); return *this;} + + inline void set(const LLPlane& p2) { mV = p2.mV; } + + // F32 dist(const LLVector3 &v2) const { return mV[0]*v2[0] + mV[1]*v2[1] + mV[2]*v2[2] + mV[3]; } + + inline LLSimdScalar dot3(const LLVector4a& b) const { return mV.dot3(b); } + + // Read-only access a single float in this vector. Do not use in proximity to any function call that manipulates + // the data at the whole vector level or you will incur a substantial penalty. Consider using the splat functions instead + inline F32 operator[](const S32 idx) const { return mV[idx]; } + + // preferable when index is known at compile time + template <int N> LL_FORCE_INLINE void getAt(LLSimdScalar& v) const { v = mV.getScalarAt<N>(); } + + // reset the vector to 0, 0, 0, 1 + inline void clear() { mV.set(0, 0, 0, 1); } + + inline void getVector3(LLVector3& vec) const { vec.set(mV[0], mV[1], mV[2]); } + + // Retrieve the mask indicating which of the x, y, or z axis are greater or equal to zero. + inline U8 calcPlaneMask() + { + return mV.greaterEqual(LLVector4a::getZero()).getGatheredBits() & LLVector4Logical::MASK_XYZ; + } + +private: + LLVector4a mV; }; |
