PageRenderTime 56ms CodeModel.GetById 11ms app.highlight 40ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llprimitive/llmodel.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 281 lines | 190 code | 53 blank | 38 comment | 4 complexity | 6b54840555f5f3495af5de76a89f5a55 MD5 | raw file
  1/** 
  2 * @file llmodel.h
  3 * @brief Model handling class definitions
  4 *
  5 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#ifndef LL_LLMODEL_H
 28#define LL_LLMODEL_H
 29
 30#include "llpointer.h"
 31#include "llvolume.h"
 32#include "v4math.h"
 33#include "m4math.h"
 34
 35class daeElement;
 36class domMesh;
 37
 38#define MAX_MODEL_FACES 8
 39
 40
 41class LLMeshSkinInfo 
 42{
 43public:
 44	LLUUID mMeshID;
 45	std::vector<std::string> mJointNames;
 46	std::vector<LLMatrix4> mInvBindMatrix;
 47	std::vector<LLMatrix4> mAlternateBindMatrix;
 48	std::map<std::string, U32> mJointMap;
 49
 50	LLMeshSkinInfo() { }
 51	LLMeshSkinInfo(LLSD& data);
 52	void fromLLSD(LLSD& data);
 53	LLSD asLLSD(bool include_joints) const;
 54	LLMatrix4 mBindShapeMatrix;
 55	float mPelvisOffset;
 56};
 57
 58class LLModel : public LLVolume
 59{
 60public:
 61
 62	enum
 63	{
 64		LOD_IMPOSTOR = 0,
 65		LOD_LOW,
 66		LOD_MEDIUM,
 67		LOD_HIGH,
 68		LOD_PHYSICS,
 69		NUM_LODS
 70	};
 71	
 72	enum EModelStatus
 73	{
 74		NO_ERRORS = 0,
 75		VERTEX_NUMBER_OVERFLOW, //vertex number is >= 65535.
 76		BAD_ELEMENT,
 77		INVALID_STATUS
 78	} ;
 79
 80	//convex_hull_decomposition is a vector of convex hulls
 81	//each convex hull is a set of points
 82	typedef std::vector<std::vector<LLVector3> > convex_hull_decomposition;
 83	typedef std::vector<LLVector3> hull;
 84	
 85	class PhysicsMesh
 86	{
 87	public:
 88		std::vector<LLVector3> mPositions;
 89		std::vector<LLVector3> mNormals;
 90
 91		void clear()
 92		{
 93			mPositions.clear();
 94			mNormals.clear();
 95		}
 96
 97		bool empty() const
 98		{
 99			return mPositions.empty();
100		}
101	};
102
103	class Decomposition
104	{
105	public:
106		Decomposition() { }
107		Decomposition(LLSD& data);
108		void fromLLSD(LLSD& data);
109		LLSD asLLSD() const;
110		bool hasHullList() const;
111
112		void merge(const Decomposition* rhs);
113
114		LLUUID mMeshID;
115		LLModel::convex_hull_decomposition mHull;
116		LLModel::hull mBaseHull;
117
118		std::vector<LLModel::PhysicsMesh> mMesh;
119		LLModel::PhysicsMesh mBaseHullMesh;
120		LLModel::PhysicsMesh mPhysicsShapeMesh;
121	};
122
123	LLModel(LLVolumeParams& params, F32 detail);
124	~LLModel();
125
126	bool loadModel(std::istream& is);
127	bool loadSkinInfo(LLSD& header, std::istream& is);
128	bool loadDecomposition(LLSD& header, std::istream& is);
129	
130	static LLSD writeModel(
131		std::ostream& ostr,
132		LLModel* physics,
133		LLModel* high,
134		LLModel* medium,
135		LLModel* low,
136		LLModel* imposotr,
137		const LLModel::Decomposition& decomp,
138		BOOL upload_skin,
139		BOOL upload_joints,
140		BOOL nowrite = FALSE,
141		BOOL as_slm = FALSE);
142
143	static LLSD writeModelToStream(
144		std::ostream& ostr,
145		LLSD& mdl,
146		BOOL nowrite = FALSE, BOOL as_slm = FALSE);
147
148	static LLModel* loadModelFromDomMesh(domMesh* mesh);
149	static std::string getElementLabel(daeElement* element);
150	std::string getName() const;
151	std::string getMetric() const {return mMetric;}
152	EModelStatus getStatus() const {return mStatus;}
153	static std::string getStatusString(U32 status) ;
154
155	void appendFaces(LLModel* model, LLMatrix4& transform, LLMatrix4& normal_transform);
156	void appendFace(const LLVolumeFace& src_face, std::string src_material, LLMatrix4& mat, LLMatrix4& norm_mat);
157
158	void setNumVolumeFaces(S32 count);
159	void setVolumeFaceData(
160		S32 f, 
161		LLStrider<LLVector3> pos, 
162		LLStrider<LLVector3> norm, 
163		LLStrider<LLVector2> tc, 
164		LLStrider<U16> ind, 
165		U32 num_verts, 
166		U32 num_indices);
167
168	void generateNormals(F32 angle_cutoff);
169
170	void addFace(const LLVolumeFace& face);
171
172	void normalizeVolumeFaces();
173	void optimizeVolumeFaces();
174	void offsetMesh( const LLVector3& pivotPoint );
175	void getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& translation_out);
176	
177	//reorder face list based on mMaterialList in this and reference so 
178	//order matches that of reference (material ordering touchup)
179	bool matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCnt );
180	bool isMaterialListSubset( LLModel* ref );
181	bool needToAddFaces( LLModel* ref, int& refFaceCnt, int& modelFaceCnt );
182	
183	std::vector<std::string> mMaterialList;
184
185	//data used for skin weights
186	class JointWeight
187	{
188	public:
189		S32 mJointIdx;
190		F32 mWeight;
191		
192		JointWeight()
193		{
194			mJointIdx = 0;
195			mWeight = 0.f;
196		}
197
198		JointWeight(S32 idx, F32 weight)
199			: mJointIdx(idx), mWeight(weight)
200		{
201		}
202
203		bool operator<(const JointWeight& rhs) const
204		{
205			if (mWeight == rhs.mWeight)
206			{
207				return mJointIdx < rhs.mJointIdx;
208			}
209
210			return mWeight < rhs.mWeight;
211		}
212
213	};
214
215	struct CompareWeightGreater
216	{
217		bool operator()(const JointWeight& lhs, const JointWeight& rhs)
218		{
219			return rhs < lhs; // strongest = first
220		}
221	};
222
223	
224	//Are the doubles the same w/in epsilon specified tolerance
225	bool areEqual( double a, double b ) 
226	{
227		const float epsilon = 1e-5f;
228		return (fabs((a - b)) < epsilon) ? true : false ;
229	}
230	//Make sure that we return false for any values that are within the tolerance for equivalence
231	bool jointPositionalLookup( const LLVector3& a, const LLVector3& b ) 
232	{
233		 return ( areEqual( a[0],b[0]) && areEqual( a[1],b[1] ) && areEqual( a[2],b[2]) ) ? true : false;
234	}
235
236	//copy of position array for this model -- mPosition[idx].mV[X,Y,Z]
237	std::vector<LLVector3> mPosition;
238
239	//map of positions to skin weights --- mSkinWeights[pos].mV[0..4] == <joint_index>.<weight>
240	//joint_index corresponds to mJointList
241	typedef std::vector<JointWeight> weight_list;
242	typedef std::map<LLVector3, weight_list > weight_map;
243	weight_map mSkinWeights;
244
245	//get list of weight influences closest to given position
246	weight_list& getJointInfluences(const LLVector3& pos);
247
248	LLMeshSkinInfo mSkinInfo;
249	
250	std::string mRequestedLabel; // name requested in UI, if any.
251	std::string mLabel; // name computed from dae.
252
253	std::string mMetric; // user-supplied metric data for upload
254
255	LLVector3 mNormalizedScale;
256	LLVector3 mNormalizedTranslation;
257
258	float	mPelvisOffset;
259	// convex hull decomposition
260	S32 mDecompID;
261	
262	void setConvexHullDecomposition(
263		const convex_hull_decomposition& decomp);
264	void updateHullCenters();
265
266	LLVector3 mCenterOfHullCenters;
267	std::vector<LLVector3> mHullCenter;
268	U32 mHullPoints;
269
270	//ID for storing this model in a .slm file
271	S32 mLocalID;
272
273	Decomposition mPhysics;
274
275	EModelStatus mStatus ;
276protected:
277	void addVolumeFacesFromDomMesh(domMesh* mesh);
278	virtual BOOL createVolumeFacesFromDomMesh(domMesh *mesh);
279};
280
281#endif //LL_LLMODEL_H