summaryrefslogtreecommitdiff
path: root/indra/newview/llpolymesh.h
blob: 2af9cbafaeb64c9a65d79007bd2a855b50f90dee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
/** 
 * @file llpolymesh.h
 * @brief Implementation of LLPolyMesh class
 *
 * $LicenseInfo:firstyear=2001&license=viewergpl$
 * 
 * Copyright (c) 2001-2007, Linden Research, Inc.
 * 
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlife.com/developers/opensource/gplv2
 * 
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at http://secondlife.com/developers/opensource/flossexception
 * 
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 * 
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */

#ifndef LL_LLPOLYMESH_H
#define LL_LLPOLYMESH_H

#include <string>
#include <map>
#include "llstl.h"

#include "v3math.h"
#include "v2math.h"
#include "llquaternion.h"
#include "llpolymorph.h"
#include "lljoint.h"
//#include "lldarray.h"

class LLSkinJoint;
class LLVOAvatar;

//#define USE_STRIPS	// Use tri-strips for rendering.

//-----------------------------------------------------------------------------
// LLPolyFace
// A set of 4 vertex indices.
// An LLPolyFace can represent either a triangle or quad.
// If the last index is -1, it's a triangle.
//-----------------------------------------------------------------------------
typedef S32 LLPolyFace[3];

//struct PrimitiveGroup;

//-----------------------------------------------------------------------------
// LLPolyMesh
// A polyhedra consisting of any number of triangles and quads.
// All instances contain a set of faces, and optionally may include
// faces grouped into named face sets.
//-----------------------------------------------------------------------------
class LLPolyMorphTarget;

class LLPolyMeshSharedData
{
	friend class LLPolyMesh;
private:
	// transform data
	LLVector3				mPosition;
	LLQuaternion			mRotation;
	LLVector3				mScale;
							
	// vertex data			
	S32						mNumVertices;
	LLVector3				*mBaseCoords;
	LLVector3				*mBaseNormals;
	LLVector3				*mBaseBinormals;
	LLVector2				*mTexCoords;
	LLVector2				*mDetailTexCoords;
	F32						*mWeights;
	
	BOOL					mHasWeights;
	BOOL					mHasDetailTexCoords;

	// face data			
	S32						mNumFaces;
	LLPolyFace				*mFaces;
							
	// face set data		
	U32						mNumJointNames;
	std::string*			mJointNames;

	// morph targets
	typedef std::set<LLPolyMorphData*> morphdata_list_t;
	morphdata_list_t			mMorphData;

	std::map<S32, S32> 			mSharedVerts;
	
	LLPolyMeshSharedData*		mReferenceData;
	S32							mLastIndexOffset;

public:
	// Temporarily...
	// Triangle indices
	U32				mNumTriangleIndices;
	U32				*mTriangleIndices;

public:
	LLPolyMeshSharedData();
	~LLPolyMeshSharedData();

private:
	void setupLOD(LLPolyMeshSharedData* reference_data);

	// Frees all mesh memory resources 
	void freeMeshData();

	void setPosition( const LLVector3 &pos ) { 	mPosition = pos; }
	void setRotation( const LLQuaternion &rot ) { mRotation = rot; }
	void setScale( const LLVector3 &scale ) { mScale = scale; }

	BOOL allocateVertexData( U32 numVertices );

	BOOL allocateFaceData( U32 numFaces );

	BOOL allocateJointNames( U32 numJointNames );

	// Retrieve the number of KB of memory used by this instance
	U32 getNumKB();

	// Load mesh data from file
	BOOL loadMesh( const std::string& fileName );

public:
	void genIndices(S32 offset);

	const LLVector2 &getUVs(U32 index);

	const S32	*getSharedVert(S32 vert);

	BOOL isLOD() { return (mReferenceData != NULL); }
};


class LLJointRenderData
{
public:
	LLJointRenderData(const LLMatrix4* world_matrix, LLSkinJoint* skin_joint) : mWorldMatrix(world_matrix), mSkinJoint(skin_joint){}
	~LLJointRenderData(){}

	const LLMatrix4*		mWorldMatrix;
	LLSkinJoint*			mSkinJoint;
};


class LLPolyMesh
{
public:
	
	// Constructor
	LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_mesh);

	// Destructor 
	~LLPolyMesh();

	// Requests a mesh by name.
	// If the mesh already exists in the global mesh table, it is returned,
	// otherwise it is loaded from file, added to the table, and returned.
	static LLPolyMesh *getMesh( const std::string &name, LLPolyMesh* reference_mesh = NULL);

	// Frees all loaded meshes.
	// This should only be called once you know there are no outstanding
	// references to these objects.  Generally, upon exit of the application.
	static void freeAllMeshes();

	//--------------------------------------------------------------------
	// Transform Data Access
	//--------------------------------------------------------------------
	// Get position
	const LLVector3 &getPosition() { 
		llassert (mSharedData);
		return mSharedData->mPosition; 
	}

	// Get rotation
	const LLQuaternion &getRotation() { 
		llassert (mSharedData);
		return mSharedData->mRotation; 
	}

	// Get scale
	const LLVector3 &getScale() { 
		llassert (mSharedData);
		return mSharedData->mScale; 
	}

	//--------------------------------------------------------------------
	// Vertex Data Access
	//--------------------------------------------------------------------
	// Get number of vertices
	U32 getNumVertices() { 
		llassert (mSharedData);
		return mSharedData->mNumVertices; 
	}

	// Returns whether or not the mesh has detail texture coords
	BOOL hasDetailTexCoords() { 
		llassert (mSharedData);
		return mSharedData->mHasDetailTexCoords; 
	}

	// Returns whether or not the mesh has vertex weights
	BOOL hasWeights() const{ 
		llassert (mSharedData);
		return mSharedData->mHasWeights; 
	}

	// Get coords
	const LLVector3	*getCoords() const{
		return mCoords;
	}

	// non const version
	LLVector3 *getWritableCoords();

	// Get normals
	const LLVector3	*getNormals() const{ 
		return mNormals; 
	}

	// Get normals
	const LLVector3	*getBinormals() const{ 
		return mBinormals; 
	}

	// Get base mesh normals
	const LLVector3 *getBaseNormals() const{
		llassert(mSharedData);
		return mSharedData->mBaseNormals;
	}

	// Get base mesh normals
	const LLVector3 *getBaseBinormals() const{
		llassert(mSharedData);
		return mSharedData->mBaseBinormals;
	}

	// intermediate morphed normals and output normals
	LLVector3 *getWritableNormals();
	LLVector3 *getScaledNormals();

	LLVector3 *getWritableBinormals();
	LLVector3 *getScaledBinormals();

	// Get texCoords
	const LLVector2	*getTexCoords() const { 
		return mTexCoords; 
	}

	// non const version
	LLVector2 *getWritableTexCoords();

	// Get detailTexCoords
	const LLVector2	*getDetailTexCoords() const { 
		llassert (mSharedData);
		return mSharedData->mDetailTexCoords; 
	}

	// Get weights
	const F32 *getWeights() const {
		llassert (mSharedData);
		return mSharedData->mWeights;
	}

	F32			*getWritableWeights() const;

	LLVector4	*getWritableClothingWeights();

	const LLVector4		*getClothingWeights()
	{
		return mClothingWeights;	
	}

	//--------------------------------------------------------------------
	// Face Data Access
	//--------------------------------------------------------------------
	// Get number of faces
	S32 getNumFaces() { 
		llassert (mSharedData);
		return mSharedData->mNumFaces; 
	}

	// Get faces
	LLPolyFace *getFaces() { 
		llassert (mSharedData);
		return mSharedData->mFaces;
	}

	U32 getNumJointNames() { 
		llassert (mSharedData);
		return mSharedData->mNumJointNames; 
	}

	std::string *getJointNames() { 
		llassert (mSharedData);
		return mSharedData->mJointNames;
	}

	LLPolyMorphData*	getMorphData(const std::string& morph_name);
// 	void	removeMorphData(LLPolyMorphData *morph_target);
// 	void	deleteAllMorphData();

	LLPolyMeshSharedData *getSharedData() const;
	LLPolyMesh *getReferenceMesh() { return mReferenceMesh ? mReferenceMesh : this; }

	// Get indices
	U32*	getIndices() { return mSharedData ? mSharedData->mTriangleIndices : NULL; }

	BOOL	isLOD() { return mSharedData && mSharedData->isLOD(); }

	void setAvatar(LLVOAvatar* avatarp) { mAvatarp = avatarp; }
	LLVOAvatar* getAvatar() { return mAvatarp; }

	LLDynamicArray<LLJointRenderData*>	mJointRenderData;

	U32				mFaceVertexOffset;
	U32				mFaceVertexCount;
	U32				mFaceIndexOffset;
	U32				mFaceIndexCount;
	U32				mCurVertexCount;
private:
	void initializeForMorph();

	// Dumps diagnostic information about the global mesh table
	static void dumpDiagInfo();

protected:
	// mesh data shared across all instances of a given mesh
	LLPolyMeshSharedData	*mSharedData;
	// Single array of floats for allocation / deletion
	F32						*mVertexData;
	// deformed vertices (resulting from application of morph targets)
	LLVector3				*mCoords;
	// deformed normals (resulting from application of morph targets)
	LLVector3				*mScaledNormals;
	// output normals (after normalization)
	LLVector3				*mNormals;
	// deformed binormals (resulting from application of morph targets)
	LLVector3				*mScaledBinormals;
	// output binormals (after normalization)
	LLVector3				*mBinormals;
	// weight values that mark verts as clothing/skin
	LLVector4				*mClothingWeights;
	// output texture coordinates
	LLVector2				*mTexCoords;
	
	LLPolyMesh				*mReferenceMesh;

	// global mesh list
	typedef std::map<std::string, LLPolyMeshSharedData*> LLPolyMeshSharedDataTable; 
	static LLPolyMeshSharedDataTable sGlobalSharedMeshList;

	// Backlink only; don't make this an LLPointer.
	LLVOAvatar* mAvatarp;
};

//-----------------------------------------------------------------------------
// LLPolySkeletalDeformationInfo
// Shared information for LLPolySkeletalDeformations
//-----------------------------------------------------------------------------
struct LLPolySkeletalBoneInfo
{
	LLPolySkeletalBoneInfo(std::string &name, LLVector3 &scale, LLVector3 &pos, BOOL haspos)
		: mBoneName(name),
		  mScaleDeformation(scale),
		  mPositionDeformation(pos),
		  mHasPositionDeformation(haspos) {}
	std::string mBoneName;
	LLVector3 mScaleDeformation;
	LLVector3 mPositionDeformation;
	BOOL mHasPositionDeformation;
};

class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo
{
	friend class LLPolySkeletalDistortion;
public:
	LLPolySkeletalDistortionInfo();
	/*virtual*/ ~LLPolySkeletalDistortionInfo() {};
	
	/*virtual*/ BOOL parseXml(LLXmlTreeNode* node);

protected:
	typedef std::vector<LLPolySkeletalBoneInfo> bone_info_list_t;
	bone_info_list_t mBoneInfoList;
};

//-----------------------------------------------------------------------------
// LLPolySkeletalDeformation
// A set of joint scale data for deforming the avatar mesh
//-----------------------------------------------------------------------------
class LLPolySkeletalDistortion : public LLViewerVisualParam
{
public:
	LLPolySkeletalDistortion(LLVOAvatar *avatarp);
	~LLPolySkeletalDistortion();

	// Special: These functions are overridden by child classes
	LLPolySkeletalDistortionInfo*	getInfo() const { return (LLPolySkeletalDistortionInfo*)mInfo; }
	//   This sets mInfo and calls initialization functions
	BOOL							setInfo(LLPolySkeletalDistortionInfo *info);

	// LLVisualParam Virtual functions
	///*virtual*/ BOOL				parseData(LLXmlTreeNode* node);
	/*virtual*/ void				apply( ESex sex );
	
	// LLViewerVisualParam Virtual functions
	/*virtual*/ F32					getTotalDistortion() { return 0.1f; }
	/*virtual*/ const LLVector3&	getAvgDistortion()	{ return mDefaultVec; }
	/*virtual*/ F32					getMaxDistortion() { return 0.1f; }
	/*virtual*/ LLVector3			getVertexDistortion(S32 index, LLPolyMesh *poly_mesh){return LLVector3(0.001f, 0.001f, 0.001f);}
	/*virtual*/ const LLVector3*	getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return &mDefaultVec;};
	/*virtual*/ const LLVector3*	getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;};

protected:
	typedef std::map<LLJoint*, LLVector3> joint_vec_map_t;
	joint_vec_map_t mJointScales;
	joint_vec_map_t mJointOffsets;
	LLVector3	mDefaultVec;
	// Backlink only; don't make this an LLPointer.
	LLVOAvatar *mAvatar;
};

#endif // LL_LLPOLYMESH_H