summaryrefslogtreecommitdiff
path: root/indra/llprimitive/llmodel.h
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llprimitive/llmodel.h')
-rw-r--r--indra/llprimitive/llmodel.h588
1 files changed, 301 insertions, 287 deletions
diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h
index 37736483c6..b5b1ad9515 100644
--- a/indra/llprimitive/llmodel.h
+++ b/indra/llprimitive/llmodel.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llmodel.h
* @brief Model handling class definitions
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, 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$
*/
@@ -45,26 +45,26 @@ class LLMeshSkinInfo : public LLRefCount
{
LL_ALIGN_NEW
public:
- LLMeshSkinInfo();
- LLMeshSkinInfo(LLSD& data);
- LLMeshSkinInfo(const LLUUID& mesh_id, LLSD& data);
- void fromLLSD(LLSD& data);
- LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const;
+ LLMeshSkinInfo();
+ LLMeshSkinInfo(LLSD& data);
+ LLMeshSkinInfo(const LLUUID& mesh_id, LLSD& data);
+ void fromLLSD(LLSD& data);
+ LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const;
void updateHash();
U32 sizeBytes() const;
- LLUUID mMeshID;
- std::vector<std::string> mJointNames;
+ LLUUID mMeshID;
+ std::vector<std::string> mJointNames;
mutable std::vector<S32> mJointNums;
typedef std::vector<LLMatrix4a, boost::alignment::aligned_allocator<LLMatrix4a, 16>> matrix_list_t;
- matrix_list_t mInvBindMatrix;
+ matrix_list_t mInvBindMatrix;
// bones/joints position overrides
- matrix_list_t mAlternateBindMatrix;
+ matrix_list_t mAlternateBindMatrix;
- LL_ALIGN_16(LLMatrix4a mBindShapeMatrix);
+ LL_ALIGN_16(LLMatrix4a mBindShapeMatrix);
- float mPelvisOffset;
+ float mPelvisOffset;
bool mLockScaleIfJointPosition;
bool mInvalidJointsScrubbed;
bool mJointNumsInitialized;
@@ -77,45 +77,47 @@ class LLModel : public LLVolume
LL_ALIGN_NEW
public:
- enum
- {
- LOD_IMPOSTOR = 0,
- LOD_LOW,
- LOD_MEDIUM,
- LOD_HIGH,
- LOD_PHYSICS,
- NUM_LODS
- };
-
- enum EModelStatus
- {
- NO_ERRORS = 0,
- VERTEX_NUMBER_OVERFLOW, //vertex number is >= 65535.
- BAD_ELEMENT,
- INVALID_STATUS
- } ;
-
- //convex_hull_decomposition is a vector of convex hulls
- //each convex hull is a set of points
- typedef std::vector<std::vector<LLVector3> > convex_hull_decomposition;
- typedef std::vector<LLVector3> hull;
-
- class PhysicsMesh
- {
- public:
- std::vector<LLVector3> mPositions;
- std::vector<LLVector3> mNormals;
-
- void clear()
- {
- mPositions.clear();
- mNormals.clear();
- }
-
- bool empty() const
- {
- return mPositions.empty();
- }
+ enum
+ {
+ LOD_IMPOSTOR = 0,
+ LOD_LOW,
+ LOD_MEDIUM,
+ LOD_HIGH,
+ LOD_PHYSICS,
+ NUM_LODS
+ };
+
+ enum EModelStatus
+ {
+ NO_ERRORS = 0,
+ VERTEX_NUMBER_OVERFLOW, //vertex number is >= 65535.
+ BAD_ELEMENT,
+ INVALID_STATUS
+ } ;
+
+ //convex_hull_decomposition is a vector of convex hulls
+ //each convex hull is a set of points
+ typedef std::vector<std::vector<LLVector3> > convex_hull_decomposition;
+ typedef std::vector<LLVector3> hull;
+
+ class PhysicsMesh
+ {
+ public:
+ std::vector<LLVector3> mPositions;
+ std::vector<LLVector3> mNormals;
+
+ ~PhysicsMesh() {}
+
+ void clear()
+ {
+ mPositions.clear();
+ mNormals.clear();
+ }
+
+ bool empty() const
+ {
+ return mPositions.empty();
+ }
U32 sizeBytes() const
{
@@ -124,209 +126,210 @@ public:
res += sizeof(LLVector3) * mNormals.size();
return res;
}
- };
-
- class Decomposition
- {
- public:
- Decomposition() { }
- Decomposition(LLSD& data);
- void fromLLSD(LLSD& data);
- LLSD asLLSD() const;
- bool hasHullList() const;
+ };
+
+ class Decomposition
+ {
+ public:
+ Decomposition() { }
+ Decomposition(LLSD& data);
+ ~Decomposition() { }
+ void fromLLSD(LLSD& data);
+ LLSD asLLSD() const;
+ bool hasHullList() const;
U32 sizeBytes() const;
- void merge(const Decomposition* rhs);
-
- LLUUID mMeshID;
- LLModel::convex_hull_decomposition mHull;
- LLModel::hull mBaseHull;
-
- std::vector<LLModel::PhysicsMesh> mMesh;
- LLModel::PhysicsMesh mBaseHullMesh;
- LLModel::PhysicsMesh mPhysicsShapeMesh;
- };
-
- LLModel(LLVolumeParams& params, F32 detail);
- ~LLModel();
-
- bool loadModel(std::istream& is);
- bool loadSkinInfo(LLSD& header, std::istream& is);
- bool loadDecomposition(LLSD& header, std::istream& is);
-
- static LLSD writeModel(
- std::ostream& ostr,
- LLModel* physics,
- LLModel* high,
- LLModel* medium,
- LLModel* low,
- LLModel* imposotr,
- const LLModel::Decomposition& decomp,
- BOOL upload_skin,
- BOOL upload_joints,
+ void merge(const Decomposition* rhs);
+
+ LLUUID mMeshID;
+ LLModel::convex_hull_decomposition mHull;
+ LLModel::hull mBaseHull;
+
+ std::vector<LLModel::PhysicsMesh> mMesh;
+ LLModel::PhysicsMesh mBaseHullMesh;
+ LLModel::PhysicsMesh mPhysicsShapeMesh;
+ };
+
+ LLModel(LLVolumeParams& params, F32 detail);
+ ~LLModel();
+
+ bool loadModel(std::istream& is);
+ bool loadSkinInfo(LLSD& header, std::istream& is);
+ bool loadDecomposition(LLSD& header, std::istream& is);
+
+ static LLSD writeModel(
+ std::ostream& ostr,
+ LLModel* physics,
+ LLModel* high,
+ LLModel* medium,
+ LLModel* low,
+ LLModel* imposotr,
+ const LLModel::Decomposition& decomp,
+ BOOL upload_skin,
+ BOOL upload_joints,
BOOL lock_scale_if_joint_position,
- BOOL nowrite = FALSE,
- BOOL as_slm = FALSE,
- int submodel_id = 0);
-
- static LLSD writeModelToStream(
- std::ostream& ostr,
- LLSD& mdl,
- BOOL nowrite = FALSE, BOOL as_slm = FALSE);
-
- void ClearFacesAndMaterials() { mVolumeFaces.clear(); mMaterialList.clear(); }
-
- std::string getName() const;
- EModelStatus getStatus() const {return mStatus;}
- static std::string getStatusString(U32 status) ;
-
- void setNumVolumeFaces(S32 count);
- void setVolumeFaceData(
- S32 f,
- LLStrider<LLVector3> pos,
- LLStrider<LLVector3> norm,
- LLStrider<LLVector2> tc,
- LLStrider<U16> ind,
- U32 num_verts,
- U32 num_indices);
-
- void generateNormals(F32 angle_cutoff);
-
- void addFace(const LLVolumeFace& face);
-
- void sortVolumeFacesByMaterialName();
- void normalizeVolumeFaces();
- void trimVolumeFacesToSize(U32 new_count = LL_SCULPT_MESH_MAX_FACES, LLVolume::face_list_t* remainder = NULL);
+ BOOL nowrite = FALSE,
+ BOOL as_slm = FALSE,
+ int submodel_id = 0);
+
+ static LLSD writeModelToStream(
+ std::ostream& ostr,
+ LLSD& mdl,
+ BOOL nowrite = FALSE, BOOL as_slm = FALSE);
+
+ void ClearFacesAndMaterials() { mVolumeFaces.clear(); mMaterialList.clear(); }
+
+ std::string getName() const;
+ EModelStatus getStatus() const {return mStatus;}
+ static std::string getStatusString(U32 status) ;
+
+ void setNumVolumeFaces(S32 count);
+ void setVolumeFaceData(
+ S32 f,
+ LLStrider<LLVector3> pos,
+ LLStrider<LLVector3> norm,
+ LLStrider<LLVector2> tc,
+ LLStrider<U16> ind,
+ U32 num_verts,
+ U32 num_indices);
+
+ void generateNormals(F32 angle_cutoff);
+
+ void addFace(const LLVolumeFace& face);
+
+ void sortVolumeFacesByMaterialName();
+ void normalizeVolumeFaces();
+ void trimVolumeFacesToSize(U32 new_count = LL_SCULPT_MESH_MAX_FACES, LLVolume::face_list_t* remainder = NULL);
void remapVolumeFaces();
- void optimizeVolumeFaces();
- void offsetMesh(const LLVector3& pivotPoint);
- void getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& translation_out) const;
- LLVector3 getTransformedCenter(const LLMatrix4& mat);
-
- //reorder face list based on mMaterialList in this and reference so
- //order matches that of reference (material ordering touchup)
- bool matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCnt );
- bool isMaterialListSubset( LLModel* ref );
- bool needToAddFaces( LLModel* ref, int& refFaceCnt, int& modelFaceCnt );
-
- typedef std::vector<std::string> material_list;
-
- material_list mMaterialList;
-
- material_list& getMaterialList() { return mMaterialList; }
-
- //data used for skin weights
- class JointWeight
- {
- public:
- S32 mJointIdx;
- F32 mWeight;
-
- JointWeight()
- {
- mJointIdx = 0;
- mWeight = 0.f;
- }
-
- JointWeight(S32 idx, F32 weight)
- : mJointIdx(idx), mWeight(weight)
- {
- }
-
- bool operator<(const JointWeight& rhs) const
- {
- if (mWeight == rhs.mWeight)
- {
- return mJointIdx < rhs.mJointIdx;
- }
-
- return mWeight < rhs.mWeight;
- }
-
- };
-
- struct CompareWeightGreater
- {
- bool operator()(const JointWeight& lhs, const JointWeight& rhs)
- {
- return rhs < lhs; // strongest = first
- }
- };
-
-
- //Are the doubles the same w/in epsilon specified tolerance
- bool areEqual( double a, double b )
- {
- const float epsilon = 1e-5f;
- return (fabs((a - b)) < epsilon) ? true : false ;
- }
- //Make sure that we return false for any values that are within the tolerance for equivalence
- bool jointPositionalLookup( const LLVector3& a, const LLVector3& b )
- {
- return ( areEqual( a[0],b[0]) && areEqual( a[1],b[1] ) && areEqual( a[2],b[2]) ) ? true : false;
- }
-
- //copy of position array for this model -- mPosition[idx].mV[X,Y,Z]
- std::vector<LLVector3> mPosition;
-
- //map of positions to skin weights --- mSkinWeights[pos].mV[0..4] == <joint_index>.<weight>
- //joint_index corresponds to mJointList
- typedef std::vector<JointWeight> weight_list;
- typedef std::map<LLVector3, weight_list > weight_map;
- weight_map mSkinWeights;
-
- //get list of weight influences closest to given position
- weight_list& getJointInfluences(const LLVector3& pos);
-
- LLMeshSkinInfo mSkinInfo;
-
- std::string mRequestedLabel; // name requested in UI, if any.
- std::string mLabel; // name computed from dae.
-
- LLVector3 mNormalizedScale;
- LLVector3 mNormalizedTranslation;
-
- float mPelvisOffset;
- // convex hull decomposition
- S32 mDecompID;
-
- void setConvexHullDecomposition(
- const convex_hull_decomposition& decomp);
- void updateHullCenters();
-
- LLVector3 mCenterOfHullCenters;
- std::vector<LLVector3> mHullCenter;
- U32 mHullPoints;
-
- //ID for storing this model in a .slm file
- S32 mLocalID;
-
- Decomposition mPhysics;
-
- EModelStatus mStatus ;
+ void optimizeVolumeFaces();
+ void offsetMesh(const LLVector3& pivotPoint);
+ void getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& translation_out) const;
+ LLVector3 getTransformedCenter(const LLMatrix4& mat);
+
+ //reorder face list based on mMaterialList in this and reference so
+ //order matches that of reference (material ordering touchup)
+ bool matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCnt );
+ bool isMaterialListSubset( LLModel* ref );
+ bool needToAddFaces( LLModel* ref, int& refFaceCnt, int& modelFaceCnt );
+
+ typedef std::vector<std::string> material_list;
+
+ material_list mMaterialList;
+
+ material_list& getMaterialList() { return mMaterialList; }
+
+ //data used for skin weights
+ class JointWeight
+ {
+ public:
+ S32 mJointIdx;
+ F32 mWeight;
+
+ JointWeight()
+ {
+ mJointIdx = 0;
+ mWeight = 0.f;
+ }
+
+ JointWeight(S32 idx, F32 weight)
+ : mJointIdx(idx), mWeight(weight)
+ {
+ }
+
+ bool operator<(const JointWeight& rhs) const
+ {
+ if (mWeight == rhs.mWeight)
+ {
+ return mJointIdx < rhs.mJointIdx;
+ }
+
+ return mWeight < rhs.mWeight;
+ }
+
+ };
+
+ struct CompareWeightGreater
+ {
+ bool operator()(const JointWeight& lhs, const JointWeight& rhs)
+ {
+ return rhs < lhs; // strongest = first
+ }
+ };
+
+
+ //Are the doubles the same w/in epsilon specified tolerance
+ bool areEqual( double a, double b )
+ {
+ const float epsilon = 1e-5f;
+ return (fabs((a - b)) < epsilon) ? true : false ;
+ }
+ //Make sure that we return false for any values that are within the tolerance for equivalence
+ bool jointPositionalLookup( const LLVector3& a, const LLVector3& b )
+ {
+ return ( areEqual( a[0],b[0]) && areEqual( a[1],b[1] ) && areEqual( a[2],b[2]) ) ? true : false;
+ }
+
+ //copy of position array for this model -- mPosition[idx].mV[X,Y,Z]
+ std::vector<LLVector3> mPosition;
+
+ //map of positions to skin weights --- mSkinWeights[pos].mV[0..4] == <joint_index>.<weight>
+ //joint_index corresponds to mJointList
+ typedef std::vector<JointWeight> weight_list;
+ typedef std::map<LLVector3, weight_list > weight_map;
+ weight_map mSkinWeights;
+
+ //get list of weight influences closest to given position
+ weight_list& getJointInfluences(const LLVector3& pos);
+
+ LLMeshSkinInfo mSkinInfo;
+
+ std::string mRequestedLabel; // name requested in UI, if any.
+ std::string mLabel; // name computed from dae.
+
+ LLVector3 mNormalizedScale;
+ LLVector3 mNormalizedTranslation;
+
+ float mPelvisOffset;
+ // convex hull decomposition
+ S32 mDecompID;
+
+ void setConvexHullDecomposition(
+ const convex_hull_decomposition& decomp);
+ void updateHullCenters();
+
+ LLVector3 mCenterOfHullCenters;
+ std::vector<LLVector3> mHullCenter;
+ U32 mHullPoints;
+
+ //ID for storing this model in a .slm file
+ S32 mLocalID;
+
+ Decomposition mPhysics;
+
+ EModelStatus mStatus ;
// A model/object can only have 8 faces, spillover faces will
// be moved to new model/object and assigned a submodel id.
- int mSubmodelID;
+ int mSubmodelID;
} LL_ALIGN_POSTFIX(16);
-typedef std::vector<LLPointer<LLModel> > model_list;
-typedef std::queue<LLPointer<LLModel> > model_queue;
+typedef std::vector<LLPointer<LLModel> > model_list;
+typedef std::queue<LLPointer<LLModel> > model_queue;
class LLModelMaterialBase
{
-public:
- std::string mDiffuseMapFilename;
- std::string mDiffuseMapLabel;
- std::string mBinding;
- LLColor4 mDiffuseColor;
- bool mFullbright;
-
- LLModelMaterialBase()
- : mFullbright(false)
- {
- mDiffuseColor.set(1,1,1,1);
- }
+public:
+ std::string mDiffuseMapFilename;
+ std::string mDiffuseMapLabel;
+ std::string mBinding;
+ LLColor4 mDiffuseColor;
+ bool mFullbright;
+
+ LLModelMaterialBase()
+ : mFullbright(false)
+ {
+ mDiffuseColor.set(1,1,1,1);
+ }
};
class LLImportMaterial : public LLModelMaterialBase
@@ -334,26 +337,26 @@ class LLImportMaterial : public LLModelMaterialBase
public:
friend class LLMeshUploadThread;
friend class LLModelPreview;
-
+
bool operator<(const LLImportMaterial &params) const;
-
+
LLImportMaterial() : LLModelMaterialBase()
{
mDiffuseColor.set(1,1,1,1);
}
-
+
LLImportMaterial(LLSD& data);
virtual ~LLImportMaterial();
-
+
LLSD asLLSD();
-
- const LLUUID& getDiffuseMap() const { return mDiffuseMapID; }
- void setDiffuseMap(const LLUUID& texId) { mDiffuseMapID = texId; }
-
+
+ const LLUUID& getDiffuseMap() const { return mDiffuseMapID; }
+ void setDiffuseMap(const LLUUID& texId) { mDiffuseMapID = texId; }
+
protected:
-
- LLUUID mDiffuseMapID;
- void* mOpaqueData; // allow refs to viewer/platform-specific structs for each material
+
+ LLUUID mDiffuseMapID;
+ void* mOpaqueData; // allow refs to viewer/platform-specific structs for each material
// currently only stores an LLPointer< LLViewerFetchedTexture > > to
// maintain refs to textures associated with each material for free
// ref counting.
@@ -364,22 +367,31 @@ typedef std::map<std::string, LLImportMaterial> material_map;
class LLModelInstanceBase
{
public:
- LLPointer<LLModel> mModel;
- LLPointer<LLModel> mLOD[LLModel::NUM_LODS];
- LLUUID mMeshID;
-
- LLMatrix4 mTransform;
- material_map mMaterial;
-
- LLModelInstanceBase(LLModel* model, LLMatrix4& transform, material_map& materials)
- : mModel(model), mTransform(transform), mMaterial(materials)
- {
- }
-
- LLModelInstanceBase()
- : mModel(NULL)
- {
- }
+ LLPointer<LLModel> mModel;
+ LLPointer<LLModel> mLOD[LLModel::NUM_LODS];
+ LLUUID mMeshID;
+
+ LLMatrix4 mTransform;
+ material_map mMaterial;
+
+ LLModelInstanceBase(LLModel* model, LLMatrix4& transform, material_map& materials)
+ : mModel(model), mTransform(transform), mMaterial(materials)
+ {
+ }
+
+ LLModelInstanceBase()
+ : mModel(NULL)
+ {
+ }
+
+ virtual ~LLModelInstanceBase()
+ {
+ mModel = NULL;
+ for (int j = 0; j < LLModel::NUM_LODS; ++j)
+ {
+ mLOD[j] = NULL;
+ }
+ };
};
typedef std::vector<LLModelInstanceBase> model_instance_list;
@@ -387,29 +399,31 @@ typedef std::vector<LLModelInstanceBase> model_instance_list;
class LLModelInstance : public LLModelInstanceBase
{
public:
- std::string mLabel;
- LLUUID mMeshID;
- S32 mLocalMeshID;
+ std::string mLabel;
+ LLUUID mMeshID;
+ S32 mLocalMeshID;
- LLModelInstance(LLModel* model, const std::string& label, LLMatrix4& transform, material_map& materials)
- : LLModelInstanceBase(model, transform, materials), mLabel(label)
- {
- mLocalMeshID = -1;
- }
+ LLModelInstance(LLModel* model, const std::string& label, LLMatrix4& transform, material_map& materials)
+ : LLModelInstanceBase(model, transform, materials), mLabel(label)
+ {
+ mLocalMeshID = -1;
+ }
- LLModelInstance(LLSD& data);
+ LLModelInstance(LLSD& data);
- LLSD asLLSD();
+ ~LLModelInstance() {}
+
+ LLSD asLLSD();
};
#define LL_DEGENERACY_TOLERANCE 1e-7f
inline F32 dot3fpu(const LLVector4a& a, const LLVector4a& b)
{
- volatile F32 p0 = a[0] * b[0];
- volatile F32 p1 = a[1] * b[1];
- volatile F32 p2 = a[2] * b[2];
- return p0 + p1 + p2;
+ volatile F32 p0 = a[0] * b[0];
+ volatile F32 p1 = a[1] * b[1];
+ volatile F32 p2 = a[2] * b[2];
+ return p0 + p1 + p2;
}
bool ll_is_degenerate(const LLVector4a& a, const LLVector4a& b, const LLVector4a& c, F32 tolerance = LL_DEGENERACY_TOLERANCE);