PageRenderTime 846ms CodeModel.GetById 181ms app.highlight 155ms RepoModel.GetById 454ms app.codeStats 51ms

/indra/newview/llmeshrepository.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 555 lines | 359 code | 141 blank | 55 comment | 1 complexity | 3c39bc7f3b33c3ded8efe6a74b45615b MD5 | raw file
  1/** 
  2 * @file llmeshrepository.h
  3 * @brief Client-side repository of mesh assets.
  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_MESH_REPOSITORY_H
 28#define LL_MESH_REPOSITORY_H
 29
 30#include "llassettype.h"
 31#include "llmodel.h"
 32#include "lluuid.h"
 33#include "llviewertexture.h"
 34#include "llvolume.h"
 35
 36#define LLCONVEXDECOMPINTER_STATIC 1
 37
 38#include "llconvexdecomposition.h"
 39#include "lluploadfloaterobservers.h"
 40
 41class LLVOVolume;
 42class LLMeshResponder;
 43class LLCurlRequest;
 44class LLMutex;
 45class LLCondition;
 46class LLVFS;
 47class LLMeshRepository;
 48
 49class LLMeshUploadData
 50{
 51public:
 52	LLPointer<LLModel> mBaseModel;
 53	LLPointer<LLModel> mModel[5];
 54	LLUUID mUUID;
 55	U32 mRetries;
 56	std::string mRSVP;
 57	std::string mAssetData;
 58	LLSD mPostData;
 59
 60	LLMeshUploadData()
 61	{
 62		mRetries = 0;
 63	}
 64};
 65
 66class LLTextureUploadData
 67{
 68public:
 69	LLViewerFetchedTexture* mTexture;
 70	LLUUID mUUID;
 71	std::string mRSVP;
 72	std::string mLabel;
 73	U32 mRetries;
 74	std::string mAssetData;
 75	LLSD mPostData;
 76
 77	LLTextureUploadData()
 78	{
 79		mRetries = 0;
 80	}
 81
 82	LLTextureUploadData(LLViewerFetchedTexture* texture, std::string& label)
 83		: mTexture(texture), mLabel(label)
 84	{
 85		mRetries = 0;
 86	}
 87};
 88
 89class LLImportMaterial
 90{
 91public:
 92	LLPointer<LLViewerFetchedTexture> mDiffuseMap;
 93	std::string mDiffuseMapFilename;
 94	std::string mDiffuseMapLabel;
 95	std::string mBinding;
 96	LLColor4 mDiffuseColor;
 97	bool mFullbright;
 98
 99	bool operator<(const LLImportMaterial &params) const;
100
101	LLImportMaterial() 
102		: mFullbright(false) 
103	{ 
104		mDiffuseColor.set(1,1,1,1);
105	}
106
107	LLImportMaterial(LLSD& data);
108
109	LLSD asLLSD();
110};
111
112class LLModelInstance 
113{
114public:
115	LLPointer<LLModel> mModel;
116	LLPointer<LLModel> mLOD[5];
117	
118	std::string mLabel;
119
120	LLUUID mMeshID;
121	S32 mLocalMeshID;
122
123	LLMatrix4 mTransform;
124	std::map<std::string, LLImportMaterial> mMaterial;
125
126	LLModelInstance(LLModel* model, const std::string& label, LLMatrix4& transform, std::map<std::string, LLImportMaterial>& materials)
127		: mModel(model), mLabel(label), mTransform(transform), mMaterial(materials)
128	{
129		mLocalMeshID = -1;
130	}
131
132	LLModelInstance(LLSD& data);
133
134	LLSD asLLSD();
135};
136
137class LLPhysicsDecomp : public LLThread
138{
139public:
140
141	typedef std::map<std::string, LLSD> decomp_params;
142
143	class Request : public LLRefCount
144	{
145	public:
146		//input params
147		S32* mDecompID;
148		std::string mStage;
149		std::vector<LLVector3> mPositions;
150		std::vector<U16> mIndices;
151		decomp_params mParams;
152				
153		//output state
154		std::string mStatusMessage;
155		std::vector<LLModel::PhysicsMesh> mHullMesh;
156		LLModel::convex_hull_decomposition mHull;
157			
158		//status message callback, called from decomposition thread
159		virtual S32 statusCallback(const char* status, S32 p1, S32 p2) = 0;
160
161		//completed callback, called from the main thread
162		virtual void completed() = 0;
163
164		virtual void setStatusMessage(const std::string& msg);
165
166		bool isValid() const {return mPositions.size() > 2 && mIndices.size() > 2 ;}
167
168	protected:
169		//internal use
170		LLVector3 mBBox[2] ;
171		F32 mTriangleAreaThreshold ;
172
173		void assignData(LLModel* mdl) ;
174		void updateTriangleAreaThreshold() ;
175		bool isValidTriangle(U16 idx1, U16 idx2, U16 idx3) ;
176	};
177
178	LLCondition* mSignal;
179	LLMutex* mMutex;
180	
181	bool mInited;
182	bool mQuitting;
183	bool mDone;
184	
185	LLPhysicsDecomp();
186	~LLPhysicsDecomp();
187
188	void shutdown();
189		
190	void submitRequest(Request* request);
191	static S32 llcdCallback(const char*, S32, S32);
192	void cancel();
193
194	void setMeshData(LLCDMeshData& mesh, bool vertex_based);
195	void doDecomposition();
196	void doDecompositionSingleHull();
197
198	virtual void run();
199	
200	void completeCurrent();
201	void notifyCompleted();
202
203	std::map<std::string, S32> mStageID;
204
205	typedef std::queue<LLPointer<Request> > request_queue;
206	request_queue mRequestQ;
207
208	LLPointer<Request> mCurRequest;
209
210	std::queue<LLPointer<Request> > mCompletedQ;
211
212};
213
214class LLMeshRepoThread : public LLThread
215{
216public:
217
218	static S32 sActiveHeaderRequests;
219	static S32 sActiveLODRequests;
220	static U32 sMaxConcurrentRequests;
221
222	LLCurlRequest* mCurlRequest;
223	LLMutex*	mMutex;
224	LLMutex*	mHeaderMutex;
225	LLCondition* mSignal;
226
227	bool mWaiting;
228
229	//map of known mesh headers
230	typedef std::map<LLUUID, LLSD> mesh_header_map;
231	mesh_header_map mMeshHeader;
232	
233	std::map<LLUUID, U32> mMeshHeaderSize;
234	
235	class HeaderRequest
236	{ 
237	public:
238		const LLVolumeParams mMeshParams;
239
240		HeaderRequest(const LLVolumeParams&  mesh_params)
241			: mMeshParams(mesh_params)
242		{
243		}
244
245		bool operator<(const HeaderRequest& rhs) const
246		{
247			return mMeshParams < rhs.mMeshParams;
248		}
249	};
250
251	class LODRequest
252	{
253	public:
254		LLVolumeParams  mMeshParams;
255		S32 mLOD;
256		F32 mScore;
257
258		LODRequest(const LLVolumeParams&  mesh_params, S32 lod)
259			: mMeshParams(mesh_params), mLOD(lod), mScore(0.f)
260		{
261		}
262	};
263
264	struct CompareScoreGreater
265	{
266		bool operator()(const LODRequest& lhs, const LODRequest& rhs)
267		{
268			return lhs.mScore > rhs.mScore; // greatest = first
269		}
270	};
271	
272
273	class LoadedMesh
274	{
275	public:
276		LLPointer<LLVolume> mVolume;
277		LLVolumeParams mMeshParams;
278		S32 mLOD;
279
280		LoadedMesh(LLVolume* volume, const LLVolumeParams&  mesh_params, S32 lod)
281			: mVolume(volume), mMeshParams(mesh_params), mLOD(lod)
282		{
283		}
284
285	};
286
287	//set of requested skin info
288	std::set<LLUUID> mSkinRequests;
289	
290	//queue of completed skin info requests
291	std::queue<LLMeshSkinInfo> mSkinInfoQ;
292
293	//set of requested decompositions
294	std::set<LLUUID> mDecompositionRequests;
295
296	//set of requested physics shapes
297	std::set<LLUUID> mPhysicsShapeRequests;
298
299	//queue of completed Decomposition info requests
300	std::queue<LLModel::Decomposition*> mDecompositionQ;
301
302	//queue of requested headers
303	std::queue<HeaderRequest> mHeaderReqQ;
304
305	//queue of requested LODs
306	std::queue<LODRequest> mLODReqQ;
307
308	//queue of unavailable LODs (either asset doesn't exist or asset doesn't have desired LOD)
309	std::queue<LODRequest> mUnavailableQ;
310
311	//queue of successfully loaded meshes
312	std::queue<LoadedMesh> mLoadedQ;
313
314	//map of pending header requests and currently desired LODs
315	typedef std::map<LLVolumeParams, std::vector<S32> > pending_lod_map;
316	pending_lod_map mPendingLOD;
317
318	static std::string constructUrl(LLUUID mesh_id);
319
320	LLMeshRepoThread();
321	~LLMeshRepoThread();
322
323	virtual void run();
324
325	void loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
326	bool fetchMeshHeader(const LLVolumeParams& mesh_params, U32& count);
327	bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count);
328	bool headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size);
329	bool lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size);
330	bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
331	bool decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
332	bool physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
333	LLSD& getMeshHeader(const LLUUID& mesh_id);
334
335	void notifyLoadedMeshes();
336	S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
337	
338	void loadMeshSkinInfo(const LLUUID& mesh_id);
339	void loadMeshDecomposition(const LLUUID& mesh_id);
340	void loadMeshPhysicsShape(const LLUUID& mesh_id);
341
342	//send request for skin info, returns true if header info exists 
343	//  (should hold onto mesh_id and try again later if header info does not exist)
344	bool fetchMeshSkinInfo(const LLUUID& mesh_id);
345
346	//send request for decomposition, returns true if header info exists 
347	//  (should hold onto mesh_id and try again later if header info does not exist)
348	bool fetchMeshDecomposition(const LLUUID& mesh_id);
349
350	//send request for PhysicsShape, returns true if header info exists 
351	//  (should hold onto mesh_id and try again later if header info does not exist)
352	bool fetchMeshPhysicsShape(const LLUUID& mesh_id);
353
354
355};
356
357class LLMeshUploadThread : public LLThread 
358{
359private:
360	S32 mMeshUploadTimeOut ; //maximum time in seconds to execute an uploading request.
361
362public:
363	class DecompRequest : public LLPhysicsDecomp::Request
364	{
365	public:
366		LLPointer<LLModel> mModel;
367		LLPointer<LLModel> mBaseModel;
368
369		LLMeshUploadThread* mThread;
370
371		DecompRequest(LLModel* mdl, LLModel* base_model, LLMeshUploadThread* thread);
372
373		S32 statusCallback(const char* status, S32 p1, S32 p2) { return 1; }
374		void completed();
375	};
376
377	LLPointer<DecompRequest> mFinalDecomp;
378	bool mPhysicsComplete;
379
380	typedef std::map<LLPointer<LLModel>, std::vector<LLVector3> > hull_map;
381	hull_map mHullMap;
382
383	typedef std::vector<LLModelInstance> instance_list;
384	instance_list mInstanceList;
385
386	typedef std::map<LLPointer<LLModel>, instance_list> instance_map;
387	instance_map mInstance;
388
389	LLMutex*					mMutex;
390	LLCurlRequest* mCurlRequest;
391	S32				mPendingUploads;
392	LLVector3		mOrigin;
393	bool			mFinished;	
394	bool			mUploadTextures;
395	bool			mUploadSkin;
396	bool			mUploadJoints;
397	BOOL            mDiscarded ;
398
399	LLHost			mHost;
400	std::string		mWholeModelFeeCapability;
401	std::string		mWholeModelUploadURL;
402
403	LLMeshUploadThread(instance_list& data, LLVector3& scale, bool upload_textures,
404			bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload = true,
405					   LLHandle<LLWholeModelFeeObserver> fee_observer= (LLHandle<LLWholeModelFeeObserver>()), LLHandle<LLWholeModelUploadObserver> upload_observer = (LLHandle<LLWholeModelUploadObserver>()));
406	~LLMeshUploadThread();
407
408	bool finished() { return mFinished; }
409	virtual void run();
410	void preStart();
411	void discard() ;
412	BOOL isDiscarded();
413
414	void generateHulls();
415
416	void doWholeModelUpload();
417	void requestWholeModelFee();
418
419	void wholeModelToLLSD(LLSD& dest, bool include_textures);
420
421	void decomposeMeshMatrix(LLMatrix4& transformation,
422							 LLVector3& result_pos,
423							 LLQuaternion& result_rot,
424							 LLVector3& result_scale);
425
426	void setFeeObserverHandle(LLHandle<LLWholeModelFeeObserver> observer_handle) { mFeeObserverHandle = observer_handle; }
427	void setUploadObserverHandle(LLHandle<LLWholeModelUploadObserver> observer_handle) { mUploadObserverHandle = observer_handle; }
428
429private:
430	LLHandle<LLWholeModelFeeObserver> mFeeObserverHandle;
431	LLHandle<LLWholeModelUploadObserver> mUploadObserverHandle;
432
433	bool mDoUpload; // if FALSE only model data will be requested, otherwise the model will be uploaded
434};
435
436class LLMeshRepository
437{
438public:
439
440	//metrics
441	static U32 sBytesReceived;
442	static U32 sHTTPRequestCount;
443	static U32 sHTTPRetryCount;
444	static U32 sCacheBytesRead;
445	static U32 sCacheBytesWritten;
446	static U32 sPeakKbps;
447	
448	static F32 getStreamingCost(LLSD& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL);
449
450	LLMeshRepository();
451
452	void init();
453	void shutdown();
454	S32 update() ;
455
456	//mesh management functions
457	S32 loadMesh(LLVOVolume* volume, const LLVolumeParams& mesh_params, S32 detail = 0, S32 last_lod = -1);
458	
459	void notifyLoadedMeshes();
460	void notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVolume* volume);
461	void notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 lod);
462	void notifySkinInfoReceived(LLMeshSkinInfo& info);
463	void notifyDecompositionReceived(LLModel::Decomposition* info);
464
465	S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
466	static S32 getActualMeshLOD(LLSD& header, S32 lod);
467	const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj);
468	LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id);
469	void fetchPhysicsShape(const LLUUID& mesh_id);
470	bool hasPhysicsShape(const LLUUID& mesh_id);
471	
472	void buildHull(const LLVolumeParams& params, S32 detail);
473	void buildPhysicsMesh(LLModel::Decomposition& decomp);
474	
475	bool meshUploadEnabled();
476	bool meshRezEnabled();
477	
478
479	LLSD& getMeshHeader(const LLUUID& mesh_id);
480
481	void uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures,
482			bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload = true,
483					 LLHandle<LLWholeModelFeeObserver> fee_observer= (LLHandle<LLWholeModelFeeObserver>()), LLHandle<LLWholeModelUploadObserver> upload_observer = (LLHandle<LLWholeModelUploadObserver>()));
484
485	S32 getMeshSize(const LLUUID& mesh_id, S32 lod);
486
487	typedef std::map<LLVolumeParams, std::set<LLUUID> > mesh_load_map;
488	mesh_load_map mLoadingMeshes[4];
489	
490	typedef std::map<LLUUID, LLMeshSkinInfo> skin_map;
491	skin_map mSkinMap;
492
493	typedef std::map<LLUUID, LLModel::Decomposition*> decomposition_map;
494	decomposition_map mDecompositionMap;
495
496	LLMutex*					mMeshMutex;
497	
498	std::vector<LLMeshRepoThread::LODRequest> mPendingRequests;
499	
500	//list of mesh ids awaiting skin info
501	typedef std::map<LLUUID, std::set<LLUUID> > skin_load_map;
502	skin_load_map mLoadingSkins;
503
504	//list of mesh ids that need to send skin info fetch requests
505	std::queue<LLUUID> mPendingSkinRequests;
506
507	//list of mesh ids awaiting decompositions
508	std::set<LLUUID> mLoadingDecompositions;
509
510	//list of mesh ids that need to send decomposition fetch requests
511	std::queue<LLUUID> mPendingDecompositionRequests;
512	
513	//list of mesh ids awaiting physics shapes
514	std::set<LLUUID> mLoadingPhysicsShapes;
515
516	//list of mesh ids that need to send physics shape fetch requests
517	std::queue<LLUUID> mPendingPhysicsShapeRequests;
518	
519	U32 mMeshThreadCount;
520
521	void cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header);
522	
523	LLMeshRepoThread* mThread;
524	std::vector<LLMeshUploadThread*> mUploads;
525	std::vector<LLMeshUploadThread*> mUploadWaitList;
526
527	LLPhysicsDecomp* mDecompThread;
528	
529	class inventory_data
530	{
531	public:
532		LLSD mPostData;
533		LLSD mResponse;
534
535		inventory_data(const LLSD& data, const LLSD& content)
536			: mPostData(data), mResponse(content)
537		{
538		}
539	};
540
541	std::queue<inventory_data> mInventoryQ;
542
543	std::queue<LLSD> mUploadErrorQ;
544
545	void uploadError(LLSD& args);
546	void updateInventory(inventory_data data);
547
548	std::string mGetMeshCapability;
549
550};
551
552extern LLMeshRepository gMeshRepo;
553
554#endif
555