diff options
Diffstat (limited to 'indra/llmath')
| -rw-r--r-- | indra/llmath/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | indra/llmath/llmatrix4a.cpp | 80 | ||||
| -rw-r--r-- | indra/llmath/llmatrix4a.h | 14 | ||||
| -rw-r--r-- | indra/llmath/llrigginginfo.cpp | 96 | ||||
| -rw-r--r-- | indra/llmath/llrigginginfo.h | 58 | ||||
| -rw-r--r-- | indra/llmath/llvector4a.h | 7 | ||||
| -rw-r--r-- | indra/llmath/llvolume.cpp | 17 | ||||
| -rw-r--r-- | indra/llmath/llvolume.h | 5 | 
8 files changed, 272 insertions, 8 deletions
| diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index 4c8bcdac91..379c3ee9ea 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -20,10 +20,12 @@ set(llmath_SOURCE_FILES      llcoordframe.cpp      llline.cpp      llmatrix3a.cpp +    llmatrix4a.cpp      llmodularmath.cpp      lloctree.cpp      llperlin.cpp      llquaternion.cpp +    llrigginginfo.cpp      llrect.cpp      llsphere.cpp      llvector4a.cpp @@ -70,6 +72,7 @@ set(llmath_HEADER_FILES      llquaternion2.h      llquaternion2.inl      llrect.h +    llrigginginfo.h      llsimdmath.h      llsimdtypes.h      llsimdtypes.inl diff --git a/indra/llmath/llmatrix4a.cpp b/indra/llmath/llmatrix4a.cpp new file mode 100644 index 0000000000..fe8f0b98f3 --- /dev/null +++ b/indra/llmath/llmatrix4a.cpp @@ -0,0 +1,80 @@ +/** +* @file llmatrix4a.cpp +* @brief  Functions for vectorized matrix/vector operations +* +* $LicenseInfo:firstyear=2018&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2018, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA +* $/LicenseInfo$ +*/ + +#include "llmath.h" +#include "llmatrix4a.h" + +// Convert a bounding box into other coordinate system. Should give +// the same results as transforming every corner of the bounding box +// and extracting the bounding box of that, although that's not +// necessarily the fastest way to implement. +void matMulBoundBox(const LLMatrix4a &mat, const LLVector4a *in_extents, LLVector4a *out_extents) +{ +		//get 8 corners of bounding box +		LLVector4Logical mask[6]; + +		for (U32 i = 0; i < 6; ++i) +		{ +			mask[i].clear(); +		} + +		mask[0].setElement<2>(); //001 +		mask[1].setElement<1>(); //010 +		mask[2].setElement<1>(); //011 +		mask[2].setElement<2>(); +		mask[3].setElement<0>(); //100 +		mask[4].setElement<0>(); //101 +		mask[4].setElement<2>(); +		mask[5].setElement<0>(); //110 +		mask[5].setElement<1>(); + +		LLVector4a v[8]; + +		v[6] = in_extents[0]; +		v[7] = in_extents[1]; + +		for (U32 i = 0; i < 6; ++i) +		{ +			v[i].setSelectWithMask(mask[i], in_extents[0], in_extents[1]); +		} + +		LLVector4a tv[8]; + +		//transform bounding box into drawable space +		for (U32 i = 0; i < 8; ++i) +		{ +			mat.affineTransform(v[i], tv[i]); +		} +	 +		//find bounding box +		out_extents[0] = out_extents[1] = tv[0]; + +		for (U32 i = 1; i < 8; ++i) +		{ +			out_extents[0].setMin(out_extents[0], tv[i]); +			out_extents[1].setMax(out_extents[1], tv[i]); +		} +} diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h index 216334752a..7ba347062f 100644 --- a/indra/llmath/llmatrix4a.h +++ b/indra/llmath/llmatrix4a.h @@ -121,7 +121,7 @@ public:  		res.add(z);  	} -	inline void affineTransformSSE(const LLVector4a& v, LLVector4a& res) +	inline void affineTransformSSE(const LLVector4a& v, LLVector4a& res) const  	{  		LLVector4a x,y,z; @@ -138,7 +138,7 @@ public:  		res.setAdd(x,z);  	} -    inline void affineTransformNonSSE(const LLVector4a& v, LLVector4a& res) +    inline void affineTransformNonSSE(const LLVector4a& v, LLVector4a& res) const      {          F32 x = v[0] * mMatrix[0][0] + v[1] * mMatrix[1][0] + v[2] * mMatrix[2][0] + mMatrix[3][0];          F32 y = v[0] * mMatrix[0][1] + v[1] * mMatrix[1][1] + v[2] * mMatrix[2][1] + mMatrix[3][1]; @@ -147,7 +147,7 @@ public:          res.set(x,y,z,w);      } -	inline void affineTransform(const LLVector4a& v, LLVector4a& res) +	inline void affineTransform(const LLVector4a& v, LLVector4a& res) const      {          affineTransformSSE(v,res);      } @@ -176,4 +176,12 @@ inline void matMul(const LLMatrix4a &a, const LLMatrix4a &b, LLMatrix4a &res)      res.mMatrix[3] = row3;  } +inline std::ostream& operator<<(std::ostream& s, const LLMatrix4a& m) +{ +    s << "[" << m.mMatrix[0] << ", " << m.mMatrix[1] << ", " << m.mMatrix[2] << ", " << m.mMatrix[3] << "]"; +    return s; +}  + +void matMulBoundBox(const LLMatrix4a &a, const LLVector4a *in_extents, LLVector4a *out_extents); +  #endif diff --git a/indra/llmath/llrigginginfo.cpp b/indra/llmath/llrigginginfo.cpp new file mode 100644 index 0000000000..925179c2ba --- /dev/null +++ b/indra/llmath/llrigginginfo.cpp @@ -0,0 +1,96 @@ +/** +* @file llrigginginfo.cpp +* @brief  Functions for tracking rigged box extents +* +* $LicenseInfo:firstyear=2018&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2018, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA +* $/LicenseInfo$ +*/ + +#include "llmath.h" +#include "llrigginginfo.h" + +//----------------------------------------------------------------------------- +// LLJointRiggingInfo +//----------------------------------------------------------------------------- +LLJointRiggingInfo::LLJointRiggingInfo() +{ +    mRiggedExtents[0].clear(); +    mRiggedExtents[1].clear(); +    mIsRiggedTo = false; +} + +bool LLJointRiggingInfo::isRiggedTo() const +{ +    return mIsRiggedTo; +} + +void LLJointRiggingInfo::setIsRiggedTo(bool val) +{ +    mIsRiggedTo = val; +} +     +LLVector4a *LLJointRiggingInfo::getRiggedExtents() +{ +    return mRiggedExtents; +} + +const LLVector4a *LLJointRiggingInfo::getRiggedExtents() const +{ +    return mRiggedExtents; +} + +// Combine two rigging info states. +// - isRiggedTo if either of the source infos are rigged to +// - box is union of the two sources +void LLJointRiggingInfo::merge(const LLJointRiggingInfo& other) +{ +    if (other.mIsRiggedTo) +    { +        if (mIsRiggedTo) +        { +            // Combine existing boxes +            update_min_max(mRiggedExtents[0], mRiggedExtents[1], other.mRiggedExtents[0]); +            update_min_max(mRiggedExtents[0], mRiggedExtents[1], other.mRiggedExtents[1]); +        } +        else +        { +            // Initialize box +            mIsRiggedTo = true; +            mRiggedExtents[0] = other.mRiggedExtents[0]; +            mRiggedExtents[1] = other.mRiggedExtents[1]; +        } +    } +} + +void mergeRigInfoTab(joint_rig_info_tab& dst, const joint_rig_info_tab& src) +{ +    // Size should be either LL_CHARACTER_MAX_ANIMATED_JOINTS, or 0 if +    // no data. Not necessarily the same for both inputs. +    if (src.size() > dst.size()) +    { +        dst.resize(src.size()); +    } +    S32 size = llmin(src.size(), dst.size()); +    for (S32 i=0; i<size; i++) +    { +        dst[i].merge(src[i]); +    } +} diff --git a/indra/llmath/llrigginginfo.h b/indra/llmath/llrigginginfo.h new file mode 100644 index 0000000000..7b36880a39 --- /dev/null +++ b/indra/llmath/llrigginginfo.h @@ -0,0 +1,58 @@ +/** +* @file llrigginginfo.h +* @brief  Functions for tracking rigged box extents +* +* $LicenseInfo:firstyear=2018&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2018, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA +* $/LicenseInfo$ +*/ + +// Stores information related to associated rigged mesh vertices +// This lives in llmath because llvolume lives in llmath. + +#ifndef	LL_LLRIGGINGINFO_H +#define	LL_LLRIGGINGINFO_H + +#include "llvector4a.h" + +// Extents are in joint space +// isRiggedTo is based on the state of all currently associated rigged meshes +LL_ALIGN_PREFIX(16) +class LLJointRiggingInfo +{ +public: +    LLJointRiggingInfo(); +    bool isRiggedTo() const; +    void setIsRiggedTo(bool val); +    LLVector4a *getRiggedExtents(); +    const LLVector4a *getRiggedExtents() const; +    void merge(const LLJointRiggingInfo& other); +private: +	LL_ALIGN_16(LLVector4a mRiggedExtents[2]); +    bool mIsRiggedTo; +} LL_ALIGN_POSTFIX(16); + +// For storing all the rigging info associated with a given avatar or +// object, keyed by joint_num. +typedef std::vector<LLJointRiggingInfo> joint_rig_info_tab; + +void mergeRigInfoTab(joint_rig_info_tab& dst, const joint_rig_info_tab& src); + +#endif diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h index 79d0a44551..222f3cf235 100644 --- a/indra/llmath/llvector4a.h +++ b/indra/llmath/llvector4a.h @@ -320,7 +320,7 @@ public:  	inline const LLVector4a& operator= ( const LLQuad& rhs );  	inline operator LLQuad() const;	 - +      private:  	LLQuad mQ;  } LL_ALIGN_POSTFIX(16); @@ -331,4 +331,9 @@ inline void update_min_max(LLVector4a& min, LLVector4a& max, const LLVector4a& p  	max.setMax(max, p);  } +inline std::ostream& operator<<(std::ostream& s, const LLVector4a& v) +{ +    s << "(" << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << ")"; +    return s; +}  #endif diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 6b6cd65ce2..8f08394ce9 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1,5 +1,4 @@  /**  -   * @file llvolume.cpp   *   * $LicenseInfo:firstyear=2002&license=viewerlgpl$ @@ -2639,6 +2638,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)  			}  			//calculate bounding box +			// VFExtents change  			LLVector4a& min = face.mExtents[0];  			LLVector4a& max = face.mExtents[1]; @@ -4644,6 +4644,7 @@ LLVolumeFace::LLVolumeFace() :  	mNumVertices(0),  	mNumAllocatedVertices(0),  	mNumIndices(0), +    mJointRiggingInfoTabPtr(NULL),  	mPositions(NULL),  	mNormals(NULL),  	mTangents(NULL), @@ -4675,6 +4676,7 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src)  	mTangents(NULL),  	mTexCoords(NULL),  	mIndices(NULL), +    mJointRiggingInfoTabPtr(NULL),  	mWeights(NULL),      mWeightsScrubbed(FALSE),  	mOctree(NULL) @@ -4768,6 +4770,7 @@ LLVolumeFace::~LLVolumeFace()  {  	ll_aligned_free_16(mExtents);  	mExtents = NULL; +	mCenter = NULL;  	freeData();  } @@ -4788,6 +4791,9 @@ void LLVolumeFace::freeData()  	ll_aligned_free_16(mWeights);  	mWeights = NULL; +    free(mJointRiggingInfoTabPtr); +    mJointRiggingInfoTabPtr = NULL; +      	delete mOctree;  	mOctree = NULL;  } @@ -5570,7 +5576,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)  	// S32 i;  	S32	grid_size = (profile.size()-1)/4; - +	// VFExtents change  	LLVector4a& min = mExtents[0];  	LLVector4a& max = mExtents[1]; @@ -5847,7 +5853,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	LLVector2 cuv;  	LLVector2 min_uv, max_uv; - +	// VFExtents change  	LLVector4a& min = mExtents[0];  	LLVector4a& max = mExtents[1]; @@ -6472,14 +6478,17 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat  		if (offset == 0 && i == 0)  		{ //initialize bounding box +			// VFExtents change  			mExtents[0] = mExtents[1] = dst_pos[i];  		}  		else  		{  			//stretch bounding box +			// VFExtents change  			update_min_max(mExtents[0], mExtents[1], dst_pos[i]);  		}  	} +    LL_DEBUGS("RiggedBox") << "appendFace got extents " << mExtents[0] << ", " << mExtents[1] << " from dst_pos " << LL_ENDL;  	new_count = mNumIndices + face.mNumIndices; @@ -6642,7 +6651,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  	{  		update_min_max(face_min, face_max, *cur_pos++);  	} - +	// VFExtents change  	mExtents[0] = face_min;  	mExtents[1] = face_max; diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index d3c1ac46fe..d518bcf3ef 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -57,6 +57,7 @@ class LLVolumeTriangle;  #include "llpointer.h"  #include "llfile.h"  #include "llalignedarray.h" +#include "llrigginginfo.h"  //============================================================================ @@ -958,6 +959,10 @@ public:  	LLVector4a* mWeights;      mutable BOOL mWeightsScrubbed; + +    // Which joints are rigged to, and the bounding box of any rigged +    // vertices per joint. +    joint_rig_info_tab *mJointRiggingInfoTabPtr;  	LLOctreeNode<LLVolumeTriangle>* mOctree; | 
