diff options
Diffstat (limited to 'indra/llmath')
| -rw-r--r-- | indra/llmath/llcamera.cpp | 171 | ||||
| -rw-r--r-- | indra/llmath/llcamera.h | 11 | ||||
| -rw-r--r-- | indra/llmath/llplane.h | 44 | ||||
| -rw-r--r-- | indra/llmath/llvector4a.h | 2 | 
4 files changed, 102 insertions, 126 deletions
| 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<U8>(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<const LLVector4a&>(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<const LLVector4a&>(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 <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;  }; 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()  	{ | 
