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; |