From 57153cf0f1fffe669b9d8871c33f9c4aaba67a2f Mon Sep 17 00:00:00 2001 From: Roxie Linden Date: Thu, 23 Dec 2010 01:48:44 -0800 Subject: 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 --- indra/llmath/llcamera.cpp | 171 ++++++++++++++++------------------------------ indra/llmath/llcamera.h | 11 +-- indra/llmath/llplane.h | 44 ++++++++++-- indra/llmath/llvector4a.h | 2 +- 4 files changed, 102 insertions(+), 126 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp index a442a0edb8..a30a50ab2e 100644 --- a/indra/llmath/llcamera.cpp +++ b/indra/llmath/llcamera.cpp @@ -42,7 +42,6 @@ LLCamera::LLCamera() : mPlaneCount(6), mFrustumCornerDist(0.f) { - alignPlanes(); calculateFrustumPlanes(); } @@ -53,7 +52,6 @@ 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,19 +65,6 @@ LLCamera::~LLCamera() } -const LLCamera& LLCamera::operator=(const LLCamera& rhs) -{ - memcpy(this, &rhs, sizeof(LLCamera)); - alignPlanes(); - LLVector4a::memcpyNonAliased16((F32*) mAgentPlanes, (F32*) rhs.mAgentPlanes, 4*7*sizeof(F32)); - return *this; -} - -void LLCamera::alignPlanes() -{ - mAgentPlanes = (LLPlane*) LL_NEXT_ALIGNED_ADDRESS(mAgentPlaneBuffer); -} - // ---------------- LLCamera::getFoo() member functions ---------------- F32 LLCamera::getMinView() const @@ -104,7 +89,7 @@ void LLCamera::setUserClipPlane(LLPlane plane) { mPlaneCount = 7; mAgentPlanes[6] = plane; - mPlaneMask[6] = calcPlaneMask(plane); + mPlaneMask[6] = plane.calcPlaneMask(); } void LLCamera::disableUserClipPlane() @@ -190,38 +175,33 @@ S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius) }; U8 mask = 0; - S32 result = 2; - + bool result = false; + LLVector4a rscale, maxp, minp; + LLSimdScalar d; for (U32 i = 0; i < mPlaneCount; i++) { mask = mPlaneMask[i]; - if (mask == 0xff) - { - continue; - } - - 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) + if (mask != 0xff) { - return 0; - } - - if (n.dot3(maxp) > -d) - { - result = 1; + const LLPlane& p(mAgentPlanes[i]); + p.getAt<3>(d); + rscale.setMul(radius, scaler[mask]); + minp.setSub(center, rscale); + d = -d; + if (p.dot3(minp).getF32() > d) + { + return 0; + } + + if(!result) + { + maxp.setAdd(center, rscale); + result = (p.dot3(maxp).getF32() > d); + } } } - return result; + return result?1:2; } @@ -239,43 +219,33 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& }; U8 mask = 0; - S32 result = 2; - + bool result = false; + LLVector4a rscale, maxp, minp; + LLSimdScalar d; for (U32 i = 0; i < mPlaneCount; i++) { - if (i == 5) - { - continue; - } - mask = mPlaneMask[i]; - if (mask == 0xff) - { - continue; - } - - 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) - { - return 0; - } - - if (n.dot3(maxp) > -d) + if ((i != 5) && (mask != 0xff)) { - result = 1; + const LLPlane& p(mAgentPlanes[i]); + p.getAt<3>(d); + rscale.setMul(radius, scaler[mask]); + minp.setSub(center, rscale); + d = -d; + if (p.dot3(minp).getF32() > d) + { + return 0; + } + + if(!result) + { + maxp.setAdd(center, rscale); + result = (p.dot3(maxp).getF32() > d); + } } } - return result; + return result?1:2; } int LLCamera::sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius) @@ -396,28 +366,22 @@ int LLCamera::sphereInFrustumOld(const LLVector3 &sphere_center, const F32 radiu int LLCamera::sphereInFrustum(const LLVector3 &sphere_center, const F32 radius) const { // Returns 1 if sphere is in frustum, 0 if not. - int res = 2; + bool res = false; for (int i = 0; i < 6; i++) { - if (mPlaneMask[i] == 0xff) - { - continue; - } - - float d = mAgentPlanes[i].dist(sphere_center); - - if (d > radius) + if (mPlaneMask[i] != 0xff) { - return 0; - } + float d = mAgentPlanes[i].dist(sphere_center); - if (d > -radius) - { - res = 1; + if (d > radius) + { + return 0; + } + res |= (d > -radius); } } - return res; + return res?1:2; } @@ -569,25 +533,6 @@ LLPlane planeFromPoints(LLVector3 p1, LLVector3 p2, LLVector3 p3) return LLPlane(p1, n); } -U8 LLCamera::calcPlaneMask(const LLPlane& plane) -{ - U8 mask = 0; - - if (plane.mV[0] >= 0) - { - mask |= 1; - } - if (plane.mV[1] >= 0) - { - mask |= 2; - } - if (plane.mV[2] >= 0) - { - mask |= 4; - } - - return mask; -} void LLCamera::ignoreAgentFrustumPlane(S32 idx) { @@ -597,13 +542,12 @@ void LLCamera::ignoreAgentFrustumPlane(S32 idx) } mPlaneMask[idx] = 0xff; - mAgentPlanes[idx].clearVec(); + mAgentPlanes[idx].clear(); } void LLCamera::calcAgentFrustumPlanes(LLVector3* frust) { - alignPlanes(); - + for (int i = 0; i < 8; i++) { mAgentFrustum[i] = frust[i]; @@ -636,7 +580,7 @@ void LLCamera::calcAgentFrustumPlanes(LLVector3* frust) //cache plane octant facing mask for use in AABBInFrustum for (U32 i = 0; i < mPlaneCount; i++) { - mPlaneMask[i] = calcPlaneMask(mAgentPlanes[i]); + mPlaneMask[i] = mAgentPlanes[i].calcPlaneMask(); } } @@ -689,9 +633,10 @@ void LLCamera::calculateWorldFrustumPlanes() F32 d; LLVector3 center = mOrigin - mXAxis*mNearPlane; mWorldPlanePos = center; + LLVector3 pnorm; for (int p=0; p<4; p++) { - LLVector3 pnorm = LLVector3(mLocalPlanes[p]); + mLocalPlanes[p].getVector3(pnorm); LLVector3 norm = rotateToAbsolute(pnorm); norm.normVec(); d = -(center * norm); @@ -701,13 +646,15 @@ void LLCamera::calculateWorldFrustumPlanes() LLVector3 zaxis(0, 0, 1.0f); F32 yaw = getYaw(); { - LLVector3 tnorm = LLVector3(mLocalPlanes[PLANE_LEFT]); + LLVector3 tnorm; + mLocalPlanes[PLANE_LEFT].getVector3(tnorm); tnorm.rotVec(yaw, zaxis); d = -(mOrigin * tnorm); mHorizPlanes[HORIZ_PLANE_LEFT] = LLPlane(tnorm, d); } { - LLVector3 tnorm = LLVector3(mLocalPlanes[PLANE_RIGHT]); + LLVector3 tnorm; + mLocalPlanes[PLANE_RIGHT].getVector3(tnorm); tnorm.rotVec(yaw, zaxis); d = -(mOrigin * tnorm); mHorizPlanes[HORIZ_PLANE_RIGHT] = LLPlane(tnorm, d); diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h index e15bd7ad43..a346322e0e 100644 --- a/indra/llmath/llcamera.h +++ b/indra/llmath/llcamera.h @@ -79,8 +79,6 @@ public: { *this = rhs; } - - const LLCamera& operator=(const LLCamera& rhs); enum { PLANE_LEFT = 0, @@ -119,6 +117,9 @@ public: }; private: + LLPlane mAgentPlanes[7]; //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP + U8 mPlaneMask[8]; // 8 for alignment + F32 mView; // angle between top and bottom frustum planes in radians. F32 mAspect; // width/height S32 mViewHeightInPixels; // for ViewHeightInPixels() only @@ -132,10 +133,6 @@ private: LLPlane mWorldPlanes[PLANE_NUM]; LLPlane mHorizPlanes[HORIZ_PLANE_NUM]; - 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 LLVector3 mWorldPlanePos; // Position of World Planes (may be offset from camera) @@ -149,11 +146,9 @@ public: LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane); virtual ~LLCamera(); - void alignPlanes(); void setUserClipPlane(LLPlane plane); void disableUserClipPlane(); - U8 calcPlaneMask(const LLPlane& plane); virtual void setView(F32 vertical_fov_rads); void setViewHeightInPixels(S32 height); void setAspect(F32 new_aspect); 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 LL_FORCE_INLINE void getAt(LLSimdScalar& v) const { v = mV.getScalarAt(); } + + // 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; }; diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h index 79022eade3..596082509d 100644 --- a/indra/llmath/llvector4a.h +++ b/indra/llmath/llvector4a.h @@ -67,7 +67,7 @@ public: extern const LLVector4a LL_V4A_ZERO; return LL_V4A_ZERO; } - + // Return a vector of all epsilon, where epsilon is a small float suitable for approximate equality checks static inline const LLVector4a& getEpsilon() { -- cgit v1.2.3 From 0b4c2fa99e50129a6ef5ac6a3d0337ee2b1b1e97 Mon Sep 17 00:00:00 2001 From: Roxie Linden Date: Thu, 23 Dec 2010 23:31:25 -0800 Subject: Fix windows build break --- indra/llmath/llcamera.cpp | 2 +- indra/llmath/llcamera.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp index a30a50ab2e..c681e00b32 100644 --- a/indra/llmath/llcamera.cpp +++ b/indra/llmath/llcamera.cpp @@ -85,7 +85,7 @@ F32 LLCamera::getMaxView() const // ---------------- LLCamera::setFoo() member functions ---------------- -void LLCamera::setUserClipPlane(LLPlane plane) +void LLCamera::setUserClipPlane(LLPlane& plane) { mPlaneCount = 7; mAgentPlanes[6] = plane; diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h index a346322e0e..82d80f1057 100644 --- a/indra/llmath/llcamera.h +++ b/indra/llmath/llcamera.h @@ -147,7 +147,7 @@ public: virtual ~LLCamera(); - void setUserClipPlane(LLPlane plane); + void setUserClipPlane(LLPlane& plane); void disableUserClipPlane(); virtual void setView(F32 vertical_fov_rads); void setViewHeightInPixels(S32 height); -- cgit v1.2.3 From fad456e2b13fab83206240d7973dd2529b53de9e Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 29 Dec 2010 16:29:34 -0600 Subject: SH-647 Switch asserts to warnings in octree for development builds (were already warnings in release builds). --- indra/llmath/lloctree.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index ed97ff76ba..276f7b0f06 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -33,11 +33,7 @@ #include #include -#if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG -#define OCT_ERRS LL_ERRS("OctreeErrors") -#else #define OCT_ERRS LL_WARNS("OctreeErrors") -#endif #define LL_OCTREE_PARANOIA_CHECK 0 #if LL_DARWIN -- cgit v1.2.3 From ca9df698db9c7a118d29adfe52f49054c333d982 Mon Sep 17 00:00:00 2001 From: Roxie Linden Date: Thu, 30 Dec 2010 22:08:25 -0800 Subject: Code review fix from davep - use booling or operator and not binary one Remove unnecessary state check. Initial dialog work for showing physics cost in upload dialog --- indra/llmath/llcamera.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp index c681e00b32..2ffc56644f 100644 --- a/indra/llmath/llcamera.cpp +++ b/indra/llmath/llcamera.cpp @@ -377,7 +377,7 @@ int LLCamera::sphereInFrustum(const LLVector3 &sphere_center, const F32 radius) { return 0; } - res |= (d > -radius); + res = res || (d > -radius); } } -- cgit v1.2.3