PageRenderTime 39ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

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