PageRenderTime 33ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/llmeshrepository.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 2581 lines | 2011 code | 444 blank | 126 comment | 336 complexity | 8ee4dde486a2ada7ec4f722c201b0648 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llmeshrepository.cpp
  3. * @brief Mesh repository implementation.
  4. *
  5. * $LicenseInfo:firstyear=2005&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. #include "llviewerprecompiledheaders.h"
  27. #include "apr_pools.h"
  28. #include "apr_dso.h"
  29. #include "llhttpstatuscodes.h"
  30. #include "llmeshrepository.h"
  31. #include "llagent.h"
  32. #include "llappviewer.h"
  33. #include "llbufferstream.h"
  34. #include "llcallbacklist.h"
  35. #include "llcurl.h"
  36. #include "lldatapacker.h"
  37. #include "llfloatermodelpreview.h"
  38. #include "llfloaterperms.h"
  39. #include "lleconomy.h"
  40. #include "llimagej2c.h"
  41. #include "llhost.h"
  42. #include "llnotificationsutil.h"
  43. #include "llsd.h"
  44. #include "llsdutil_math.h"
  45. #include "llsdserialize.h"
  46. #include "llthread.h"
  47. #include "llvfile.h"
  48. #include "llviewercontrol.h"
  49. #include "llviewerinventory.h"
  50. #include "llviewermenufile.h"
  51. #include "llviewerobjectlist.h"
  52. #include "llviewerregion.h"
  53. #include "llviewertexturelist.h"
  54. #include "llvolume.h"
  55. #include "llvolumemgr.h"
  56. #include "llvovolume.h"
  57. #include "llworld.h"
  58. #include "material_codes.h"
  59. #include "pipeline.h"
  60. #include "llinventorymodel.h"
  61. #include "llfoldertype.h"
  62. #include "llviewerparcelmgr.h"
  63. #include "lluploadfloaterobservers.h"
  64. #include "boost/lexical_cast.hpp"
  65. #ifndef LL_WINDOWS
  66. #include "netdb.h"
  67. #endif
  68. #include <queue>
  69. LLMeshRepository gMeshRepo;
  70. const U32 MAX_MESH_REQUESTS_PER_SECOND = 100;
  71. // Maximum mesh version to support. Three least significant digits are reserved for the minor version,
  72. // with major version changes indicating a format change that is not backwards compatible and should not
  73. // be parsed by viewers that don't specifically support that version. For example, if the integer "1" is
  74. // present, the version is 0.001. A viewer that can parse version 0.001 can also parse versions up to 0.999,
  75. // but not 1.0 (integer 1000).
  76. // See wiki at https://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format
  77. const S32 MAX_MESH_VERSION = 999;
  78. U32 LLMeshRepository::sBytesReceived = 0;
  79. U32 LLMeshRepository::sHTTPRequestCount = 0;
  80. U32 LLMeshRepository::sHTTPRetryCount = 0;
  81. U32 LLMeshRepository::sCacheBytesRead = 0;
  82. U32 LLMeshRepository::sCacheBytesWritten = 0;
  83. U32 LLMeshRepository::sPeakKbps = 0;
  84. const U32 MAX_TEXTURE_UPLOAD_RETRIES = 5;
  85. static S32 dump_num = 0;
  86. std::string make_dump_name(std::string prefix, S32 num)
  87. {
  88. return prefix + boost::lexical_cast<std::string>(num) + std::string(".xml");
  89. }
  90. void dump_llsd_to_file(const LLSD& content, std::string filename);
  91. LLSD llsd_from_file(std::string filename);
  92. std::string header_lod[] =
  93. {
  94. "lowest_lod",
  95. "low_lod",
  96. "medium_lod",
  97. "high_lod"
  98. };
  99. //get the number of bytes resident in memory for given volume
  100. U32 get_volume_memory_size(const LLVolume* volume)
  101. {
  102. U32 indices = 0;
  103. U32 vertices = 0;
  104. for (U32 i = 0; i < volume->getNumVolumeFaces(); ++i)
  105. {
  106. const LLVolumeFace& face = volume->getVolumeFace(i);
  107. indices += face.mNumIndices;
  108. vertices += face.mNumVertices;
  109. }
  110. return indices*2+vertices*11+sizeof(LLVolume)+sizeof(LLVolumeFace)*volume->getNumVolumeFaces();
  111. }
  112. void get_vertex_buffer_from_mesh(LLCDMeshData& mesh, LLModel::PhysicsMesh& res, F32 scale = 1.f)
  113. {
  114. res.mPositions.clear();
  115. res.mNormals.clear();
  116. const F32* v = mesh.mVertexBase;
  117. if (mesh.mIndexType == LLCDMeshData::INT_16)
  118. {
  119. U16* idx = (U16*) mesh.mIndexBase;
  120. for (S32 j = 0; j < mesh.mNumTriangles; ++j)
  121. {
  122. F32* mp0 = (F32*) ((U8*)v+idx[0]*mesh.mVertexStrideBytes);
  123. F32* mp1 = (F32*) ((U8*)v+idx[1]*mesh.mVertexStrideBytes);
  124. F32* mp2 = (F32*) ((U8*)v+idx[2]*mesh.mVertexStrideBytes);
  125. idx = (U16*) (((U8*)idx)+mesh.mIndexStrideBytes);
  126. LLVector3 v0(mp0);
  127. LLVector3 v1(mp1);
  128. LLVector3 v2(mp2);
  129. LLVector3 n = (v1-v0)%(v2-v0);
  130. n.normalize();
  131. res.mPositions.push_back(v0*scale);
  132. res.mPositions.push_back(v1*scale);
  133. res.mPositions.push_back(v2*scale);
  134. res.mNormals.push_back(n);
  135. res.mNormals.push_back(n);
  136. res.mNormals.push_back(n);
  137. }
  138. }
  139. else
  140. {
  141. U32* idx = (U32*) mesh.mIndexBase;
  142. for (S32 j = 0; j < mesh.mNumTriangles; ++j)
  143. {
  144. F32* mp0 = (F32*) ((U8*)v+idx[0]*mesh.mVertexStrideBytes);
  145. F32* mp1 = (F32*) ((U8*)v+idx[1]*mesh.mVertexStrideBytes);
  146. F32* mp2 = (F32*) ((U8*)v+idx[2]*mesh.mVertexStrideBytes);
  147. idx = (U32*) (((U8*)idx)+mesh.mIndexStrideBytes);
  148. LLVector3 v0(mp0);
  149. LLVector3 v1(mp1);
  150. LLVector3 v2(mp2);
  151. LLVector3 n = (v1-v0)%(v2-v0);
  152. n.normalize();
  153. res.mPositions.push_back(v0*scale);
  154. res.mPositions.push_back(v1*scale);
  155. res.mPositions.push_back(v2*scale);
  156. res.mNormals.push_back(n);
  157. res.mNormals.push_back(n);
  158. res.mNormals.push_back(n);
  159. }
  160. }
  161. }
  162. S32 LLMeshRepoThread::sActiveHeaderRequests = 0;
  163. S32 LLMeshRepoThread::sActiveLODRequests = 0;
  164. U32 LLMeshRepoThread::sMaxConcurrentRequests = 1;
  165. class LLMeshHeaderResponder : public LLCurl::Responder
  166. {
  167. public:
  168. LLVolumeParams mMeshParams;
  169. LLMeshHeaderResponder(const LLVolumeParams& mesh_params)
  170. : mMeshParams(mesh_params)
  171. {
  172. }
  173. virtual void completedRaw(U32 status, const std::string& reason,
  174. const LLChannelDescriptors& channels,
  175. const LLIOPipe::buffer_ptr_t& buffer);
  176. };
  177. class LLMeshLODResponder : public LLCurl::Responder
  178. {
  179. public:
  180. LLVolumeParams mMeshParams;
  181. S32 mLOD;
  182. U32 mRequestedBytes;
  183. U32 mOffset;
  184. LLMeshLODResponder(const LLVolumeParams& mesh_params, S32 lod, U32 offset, U32 requested_bytes)
  185. : mMeshParams(mesh_params), mLOD(lod), mOffset(offset), mRequestedBytes(requested_bytes)
  186. {
  187. }
  188. virtual void completedRaw(U32 status, const std::string& reason,
  189. const LLChannelDescriptors& channels,
  190. const LLIOPipe::buffer_ptr_t& buffer);
  191. };
  192. class LLMeshSkinInfoResponder : public LLCurl::Responder
  193. {
  194. public:
  195. LLUUID mMeshID;
  196. U32 mRequestedBytes;
  197. U32 mOffset;
  198. LLMeshSkinInfoResponder(const LLUUID& id, U32 offset, U32 size)
  199. : mMeshID(id), mRequestedBytes(size), mOffset(offset)
  200. {
  201. }
  202. virtual void completedRaw(U32 status, const std::string& reason,
  203. const LLChannelDescriptors& channels,
  204. const LLIOPipe::buffer_ptr_t& buffer);
  205. };
  206. class LLMeshDecompositionResponder : public LLCurl::Responder
  207. {
  208. public:
  209. LLUUID mMeshID;
  210. U32 mRequestedBytes;
  211. U32 mOffset;
  212. LLMeshDecompositionResponder(const LLUUID& id, U32 offset, U32 size)
  213. : mMeshID(id), mRequestedBytes(size), mOffset(offset)
  214. {
  215. }
  216. virtual void completedRaw(U32 status, const std::string& reason,
  217. const LLChannelDescriptors& channels,
  218. const LLIOPipe::buffer_ptr_t& buffer);
  219. };
  220. class LLMeshPhysicsShapeResponder : public LLCurl::Responder
  221. {
  222. public:
  223. LLUUID mMeshID;
  224. U32 mRequestedBytes;
  225. U32 mOffset;
  226. LLMeshPhysicsShapeResponder(const LLUUID& id, U32 offset, U32 size)
  227. : mMeshID(id), mRequestedBytes(size), mOffset(offset)
  228. {
  229. }
  230. virtual void completedRaw(U32 status, const std::string& reason,
  231. const LLChannelDescriptors& channels,
  232. const LLIOPipe::buffer_ptr_t& buffer);
  233. };
  234. void log_upload_error(S32 status, const LLSD& content, std::string stage, std::string model_name)
  235. {
  236. // Add notification popup.
  237. LLSD args;
  238. std::string message = content["error"]["message"];
  239. std::string identifier = content["error"]["identifier"];
  240. args["MESSAGE"] = message;
  241. args["IDENTIFIER"] = identifier;
  242. args["LABEL"] = model_name;
  243. gMeshRepo.uploadError(args);
  244. // Log details.
  245. llwarns << "stage: " << stage << " http status: " << status << llendl;
  246. if (content.has("error"))
  247. {
  248. const LLSD& err = content["error"];
  249. llwarns << "err: " << err << llendl;
  250. llwarns << "mesh upload failed, stage '" << stage
  251. << "' error '" << err["error"].asString()
  252. << "', message '" << err["message"].asString()
  253. << "', id '" << err["identifier"].asString()
  254. << "'" << llendl;
  255. if (err.has("errors"))
  256. {
  257. S32 error_num = 0;
  258. const LLSD& err_list = err["errors"];
  259. for (LLSD::array_const_iterator it = err_list.beginArray();
  260. it != err_list.endArray();
  261. ++it)
  262. {
  263. const LLSD& err_entry = *it;
  264. llwarns << "error[" << error_num << "]:" << llendl;
  265. for (LLSD::map_const_iterator map_it = err_entry.beginMap();
  266. map_it != err_entry.endMap();
  267. ++map_it)
  268. {
  269. llwarns << "\t" << map_it->first << ": "
  270. << map_it->second << llendl;
  271. }
  272. error_num++;
  273. }
  274. }
  275. }
  276. else
  277. {
  278. llwarns << "bad mesh, no error information available" << llendl;
  279. }
  280. }
  281. class LLWholeModelFeeResponder: public LLCurl::Responder
  282. {
  283. LLMeshUploadThread* mThread;
  284. LLSD mModelData;
  285. LLHandle<LLWholeModelFeeObserver> mObserverHandle;
  286. public:
  287. LLWholeModelFeeResponder(LLMeshUploadThread* thread, LLSD& model_data, LLHandle<LLWholeModelFeeObserver> observer_handle):
  288. mThread(thread),
  289. mModelData(model_data),
  290. mObserverHandle(observer_handle)
  291. {
  292. }
  293. virtual void completed(U32 status,
  294. const std::string& reason,
  295. const LLSD& content)
  296. {
  297. LLSD cc = content;
  298. if (gSavedSettings.getS32("MeshUploadFakeErrors")&1)
  299. {
  300. cc = llsd_from_file("fake_upload_error.xml");
  301. }
  302. mThread->mPendingUploads--;
  303. dump_llsd_to_file(cc,make_dump_name("whole_model_fee_response_",dump_num));
  304. LLWholeModelFeeObserver* observer = mObserverHandle.get();
  305. if (isGoodStatus(status) &&
  306. cc["state"].asString() == "upload")
  307. {
  308. mThread->mWholeModelUploadURL = cc["uploader"].asString();
  309. if (observer)
  310. {
  311. cc["data"]["upload_price"] = cc["upload_price"];
  312. observer->onModelPhysicsFeeReceived(cc["data"], mThread->mWholeModelUploadURL);
  313. }
  314. }
  315. else
  316. {
  317. llwarns << "fee request failed" << llendl;
  318. log_upload_error(status,cc,"fee",mModelData["name"]);
  319. mThread->mWholeModelUploadURL = "";
  320. if (observer)
  321. {
  322. observer->setModelPhysicsFeeErrorStatus(status, reason);
  323. }
  324. }
  325. }
  326. };
  327. class LLWholeModelUploadResponder: public LLCurl::Responder
  328. {
  329. LLMeshUploadThread* mThread;
  330. LLSD mModelData;
  331. LLHandle<LLWholeModelUploadObserver> mObserverHandle;
  332. public:
  333. LLWholeModelUploadResponder(LLMeshUploadThread* thread, LLSD& model_data, LLHandle<LLWholeModelUploadObserver> observer_handle):
  334. mThread(thread),
  335. mModelData(model_data),
  336. mObserverHandle(observer_handle)
  337. {
  338. }
  339. virtual void completed(U32 status,
  340. const std::string& reason,
  341. const LLSD& content)
  342. {
  343. LLSD cc = content;
  344. if (gSavedSettings.getS32("MeshUploadFakeErrors")&2)
  345. {
  346. cc = llsd_from_file("fake_upload_error.xml");
  347. }
  348. mThread->mPendingUploads--;
  349. dump_llsd_to_file(cc,make_dump_name("whole_model_upload_response_",dump_num));
  350. LLWholeModelUploadObserver* observer = mObserverHandle.get();
  351. // requested "mesh" asset type isn't actually the type
  352. // of the resultant object, fix it up here.
  353. if (isGoodStatus(status) &&
  354. cc["state"].asString() == "complete")
  355. {
  356. mModelData["asset_type"] = "object";
  357. gMeshRepo.updateInventory(LLMeshRepository::inventory_data(mModelData,cc));
  358. if (observer)
  359. {
  360. doOnIdleOneTime(boost::bind(&LLWholeModelUploadObserver::onModelUploadSuccess, observer));
  361. }
  362. }
  363. else
  364. {
  365. llwarns << "upload failed" << llendl;
  366. std::string model_name = mModelData["name"].asString();
  367. log_upload_error(status,cc,"upload",model_name);
  368. if (observer)
  369. {
  370. doOnIdleOneTime(boost::bind(&LLWholeModelUploadObserver::onModelUploadFailure, observer));
  371. }
  372. }
  373. }
  374. };
  375. LLMeshRepoThread::LLMeshRepoThread()
  376. : LLThread("mesh repo")
  377. {
  378. mWaiting = false;
  379. mMutex = new LLMutex(NULL);
  380. mHeaderMutex = new LLMutex(NULL);
  381. mSignal = new LLCondition(NULL);
  382. }
  383. LLMeshRepoThread::~LLMeshRepoThread()
  384. {
  385. delete mMutex;
  386. mMutex = NULL;
  387. delete mHeaderMutex;
  388. mHeaderMutex = NULL;
  389. delete mSignal;
  390. mSignal = NULL;
  391. }
  392. void LLMeshRepoThread::run()
  393. {
  394. mCurlRequest = new LLCurlRequest();
  395. LLCDResult res = LLConvexDecomposition::initThread();
  396. if (res != LLCD_OK)
  397. {
  398. llwarns << "convex decomposition unable to be loaded" << llendl;
  399. }
  400. while (!LLApp::isQuitting())
  401. {
  402. mWaiting = true;
  403. mSignal->wait();
  404. mWaiting = false;
  405. if (!LLApp::isQuitting())
  406. {
  407. static U32 count = 0;
  408. static F32 last_hundred = gFrameTimeSeconds;
  409. if (gFrameTimeSeconds - last_hundred > 1.f)
  410. { //a second has gone by, clear count
  411. last_hundred = gFrameTimeSeconds;
  412. count = 0;
  413. }
  414. // NOTE: throttling intentionally favors LOD requests over header requests
  415. while (!mLODReqQ.empty() && count < MAX_MESH_REQUESTS_PER_SECOND && sActiveLODRequests < sMaxConcurrentRequests)
  416. {
  417. {
  418. mMutex->lock();
  419. LODRequest req = mLODReqQ.front();
  420. mLODReqQ.pop();
  421. mMutex->unlock();
  422. if (!fetchMeshLOD(req.mMeshParams, req.mLOD, count))//failed, resubmit
  423. {
  424. mMutex->lock();
  425. mLODReqQ.push(req) ;
  426. mMutex->unlock();
  427. }
  428. }
  429. }
  430. while (!mHeaderReqQ.empty() && count < MAX_MESH_REQUESTS_PER_SECOND && sActiveHeaderRequests < sMaxConcurrentRequests)
  431. {
  432. {
  433. mMutex->lock();
  434. HeaderRequest req = mHeaderReqQ.front();
  435. mHeaderReqQ.pop();
  436. mMutex->unlock();
  437. if (!fetchMeshHeader(req.mMeshParams, count))//failed, resubmit
  438. {
  439. mMutex->lock();
  440. mHeaderReqQ.push(req) ;
  441. mMutex->unlock();
  442. }
  443. }
  444. }
  445. { //mSkinRequests is protected by mSignal
  446. std::set<LLUUID> incomplete;
  447. for (std::set<LLUUID>::iterator iter = mSkinRequests.begin(); iter != mSkinRequests.end(); ++iter)
  448. {
  449. LLUUID mesh_id = *iter;
  450. if (!fetchMeshSkinInfo(mesh_id))
  451. {
  452. incomplete.insert(mesh_id);
  453. }
  454. }
  455. mSkinRequests = incomplete;
  456. }
  457. { //mDecompositionRequests is protected by mSignal
  458. std::set<LLUUID> incomplete;
  459. for (std::set<LLUUID>::iterator iter = mDecompositionRequests.begin(); iter != mDecompositionRequests.end(); ++iter)
  460. {
  461. LLUUID mesh_id = *iter;
  462. if (!fetchMeshDecomposition(mesh_id))
  463. {
  464. incomplete.insert(mesh_id);
  465. }
  466. }
  467. mDecompositionRequests = incomplete;
  468. }
  469. { //mPhysicsShapeRequests is protected by mSignal
  470. std::set<LLUUID> incomplete;
  471. for (std::set<LLUUID>::iterator iter = mPhysicsShapeRequests.begin(); iter != mPhysicsShapeRequests.end(); ++iter)
  472. {
  473. LLUUID mesh_id = *iter;
  474. if (!fetchMeshPhysicsShape(mesh_id))
  475. {
  476. incomplete.insert(mesh_id);
  477. }
  478. }
  479. mPhysicsShapeRequests = incomplete;
  480. }
  481. mCurlRequest->process();
  482. }
  483. }
  484. if (mSignal->isLocked())
  485. { //make sure to let go of the mutex associated with the given signal before shutting down
  486. mSignal->unlock();
  487. }
  488. res = LLConvexDecomposition::quitThread();
  489. if (res != LLCD_OK)
  490. {
  491. llwarns << "convex decomposition unable to be quit" << llendl;
  492. }
  493. delete mCurlRequest;
  494. mCurlRequest = NULL;
  495. }
  496. void LLMeshRepoThread::loadMeshSkinInfo(const LLUUID& mesh_id)
  497. { //protected by mSignal, no locking needed here
  498. mSkinRequests.insert(mesh_id);
  499. }
  500. void LLMeshRepoThread::loadMeshDecomposition(const LLUUID& mesh_id)
  501. { //protected by mSignal, no locking needed here
  502. mDecompositionRequests.insert(mesh_id);
  503. }
  504. void LLMeshRepoThread::loadMeshPhysicsShape(const LLUUID& mesh_id)
  505. { //protected by mSignal, no locking needed here
  506. mPhysicsShapeRequests.insert(mesh_id);
  507. }
  508. void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
  509. { //protected by mSignal, no locking needed here
  510. mesh_header_map::iterator iter = mMeshHeader.find(mesh_params.getSculptID());
  511. if (iter != mMeshHeader.end())
  512. { //if we have the header, request LOD byte range
  513. LODRequest req(mesh_params, lod);
  514. {
  515. LLMutexLock lock(mMutex);
  516. mLODReqQ.push(req);
  517. }
  518. }
  519. else
  520. {
  521. HeaderRequest req(mesh_params);
  522. pending_lod_map::iterator pending = mPendingLOD.find(mesh_params);
  523. if (pending != mPendingLOD.end())
  524. { //append this lod request to existing header request
  525. pending->second.push_back(lod);
  526. llassert(pending->second.size() <= LLModel::NUM_LODS)
  527. }
  528. else
  529. { //if no header request is pending, fetch header
  530. LLMutexLock lock(mMutex);
  531. mHeaderReqQ.push(req);
  532. mPendingLOD[mesh_params].push_back(lod);
  533. }
  534. }
  535. }
  536. //static
  537. std::string LLMeshRepoThread::constructUrl(LLUUID mesh_id)
  538. {
  539. std::string http_url;
  540. if (gAgent.getRegion())
  541. {
  542. http_url = gMeshRepo.mGetMeshCapability;
  543. }
  544. if (!http_url.empty())
  545. {
  546. http_url += "/?mesh_id=";
  547. http_url += mesh_id.asString().c_str();
  548. }
  549. else
  550. {
  551. llwarns << "Current region does not have GetMesh capability! Cannot load " << mesh_id << ".mesh" << llendl;
  552. }
  553. return http_url;
  554. }
  555. bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
  556. { //protected by mMutex
  557. mHeaderMutex->lock();
  558. if (mMeshHeader.find(mesh_id) == mMeshHeader.end())
  559. { //we have no header info for this mesh, do nothing
  560. mHeaderMutex->unlock();
  561. return false;
  562. }
  563. bool ret = true ;
  564. U32 header_size = mMeshHeaderSize[mesh_id];
  565. if (header_size > 0)
  566. {
  567. S32 version = mMeshHeader[mesh_id]["version"].asInteger();
  568. S32 offset = header_size + mMeshHeader[mesh_id]["skin"]["offset"].asInteger();
  569. S32 size = mMeshHeader[mesh_id]["skin"]["size"].asInteger();
  570. mHeaderMutex->unlock();
  571. if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0)
  572. {
  573. //check VFS for mesh skin info
  574. LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH);
  575. if (file.getSize() >= offset+size)
  576. {
  577. LLMeshRepository::sCacheBytesRead += size;
  578. file.seek(offset);
  579. U8* buffer = new U8[size];
  580. file.read(buffer, size);
  581. //make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written)
  582. bool zero = true;
  583. for (S32 i = 0; i < llmin(size, 1024) && zero; ++i)
  584. {
  585. zero = buffer[i] > 0 ? false : true;
  586. }
  587. if (!zero)
  588. { //attempt to parse
  589. if (skinInfoReceived(mesh_id, buffer, size))
  590. {
  591. delete[] buffer;
  592. return true;
  593. }
  594. }
  595. delete[] buffer;
  596. }
  597. //reading from VFS failed for whatever reason, fetch from sim
  598. std::vector<std::string> headers;
  599. headers.push_back("Accept: application/octet-stream");
  600. std::string http_url = constructUrl(mesh_id);
  601. if (!http_url.empty())
  602. {
  603. ret = mCurlRequest->getByteRange(http_url, headers, offset, size,
  604. new LLMeshSkinInfoResponder(mesh_id, offset, size));
  605. if(ret)
  606. {
  607. ++sActiveLODRequests;
  608. LLMeshRepository::sHTTPRequestCount++;
  609. }
  610. }
  611. }
  612. }
  613. else
  614. {
  615. mHeaderMutex->unlock();
  616. }
  617. //early out was not hit, effectively fetched
  618. return ret;
  619. }
  620. bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
  621. { //protected by mMutex
  622. mHeaderMutex->lock();
  623. if (mMeshHeader.find(mesh_id) == mMeshHeader.end())
  624. { //we have no header info for this mesh, do nothing
  625. mHeaderMutex->unlock();
  626. return false;
  627. }
  628. U32 header_size = mMeshHeaderSize[mesh_id];
  629. bool ret = true ;
  630. if (header_size > 0)
  631. {
  632. S32 version = mMeshHeader[mesh_id]["version"].asInteger();
  633. S32 offset = header_size + mMeshHeader[mesh_id]["physics_convex"]["offset"].asInteger();
  634. S32 size = mMeshHeader[mesh_id]["physics_convex"]["size"].asInteger();
  635. mHeaderMutex->unlock();
  636. if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0)
  637. {
  638. //check VFS for mesh skin info
  639. LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH);
  640. if (file.getSize() >= offset+size)
  641. {
  642. LLMeshRepository::sCacheBytesRead += size;
  643. file.seek(offset);
  644. U8* buffer = new U8[size];
  645. file.read(buffer, size);
  646. //make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written)
  647. bool zero = true;
  648. for (S32 i = 0; i < llmin(size, 1024) && zero; ++i)
  649. {
  650. zero = buffer[i] > 0 ? false : true;
  651. }
  652. if (!zero)
  653. { //attempt to parse
  654. if (decompositionReceived(mesh_id, buffer, size))
  655. {
  656. delete[] buffer;
  657. return true;
  658. }
  659. }
  660. delete[] buffer;
  661. }
  662. //reading from VFS failed for whatever reason, fetch from sim
  663. std::vector<std::string> headers;
  664. headers.push_back("Accept: application/octet-stream");
  665. std::string http_url = constructUrl(mesh_id);
  666. if (!http_url.empty())
  667. {
  668. ret = mCurlRequest->getByteRange(http_url, headers, offset, size,
  669. new LLMeshDecompositionResponder(mesh_id, offset, size));
  670. if(ret)
  671. {
  672. ++sActiveLODRequests;
  673. LLMeshRepository::sHTTPRequestCount++;
  674. }
  675. }
  676. }
  677. }
  678. else
  679. {
  680. mHeaderMutex->unlock();
  681. }
  682. //early out was not hit, effectively fetched
  683. return ret;
  684. }
  685. bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
  686. { //protected by mMutex
  687. mHeaderMutex->lock();
  688. if (mMeshHeader.find(mesh_id) == mMeshHeader.end())
  689. { //we have no header info for this mesh, do nothing
  690. mHeaderMutex->unlock();
  691. return false;
  692. }
  693. U32 header_size = mMeshHeaderSize[mesh_id];
  694. bool ret = true ;
  695. if (header_size > 0)
  696. {
  697. S32 version = mMeshHeader[mesh_id]["version"].asInteger();
  698. S32 offset = header_size + mMeshHeader[mesh_id]["physics_mesh"]["offset"].asInteger();
  699. S32 size = mMeshHeader[mesh_id]["physics_mesh"]["size"].asInteger();
  700. mHeaderMutex->unlock();
  701. if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0)
  702. {
  703. //check VFS for mesh physics shape info
  704. LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH);
  705. if (file.getSize() >= offset+size)
  706. {
  707. LLMeshRepository::sCacheBytesRead += size;
  708. file.seek(offset);
  709. U8* buffer = new U8[size];
  710. file.read(buffer, size);
  711. //make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written)
  712. bool zero = true;
  713. for (S32 i = 0; i < llmin(size, 1024) && zero; ++i)
  714. {
  715. zero = buffer[i] > 0 ? false : true;
  716. }
  717. if (!zero)
  718. { //attempt to parse
  719. if (physicsShapeReceived(mesh_id, buffer, size))
  720. {
  721. delete[] buffer;
  722. return true;
  723. }
  724. }
  725. delete[] buffer;
  726. }
  727. //reading from VFS failed for whatever reason, fetch from sim
  728. std::vector<std::string> headers;
  729. headers.push_back("Accept: application/octet-stream");
  730. std::string http_url = constructUrl(mesh_id);
  731. if (!http_url.empty())
  732. {
  733. ret = mCurlRequest->getByteRange(http_url, headers, offset, size,
  734. new LLMeshPhysicsShapeResponder(mesh_id, offset, size));
  735. if(ret)
  736. {
  737. ++sActiveLODRequests;
  738. LLMeshRepository::sHTTPRequestCount++;
  739. }
  740. }
  741. }
  742. else
  743. { //no physics shape whatsoever, report back NULL
  744. physicsShapeReceived(mesh_id, NULL, 0);
  745. }
  746. }
  747. else
  748. {
  749. mHeaderMutex->unlock();
  750. }
  751. //early out was not hit, effectively fetched
  752. return ret;
  753. }
  754. //return false if failed to get header
  755. bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, U32& count)
  756. {
  757. {
  758. //look for mesh in asset in vfs
  759. LLVFile file(gVFS, mesh_params.getSculptID(), LLAssetType::AT_MESH);
  760. S32 size = file.getSize();
  761. if (size > 0)
  762. { //NOTE -- if the header size is ever more than 4KB, this will break
  763. U8 buffer[4096];
  764. S32 bytes = llmin(size, 4096);
  765. LLMeshRepository::sCacheBytesRead += bytes;
  766. file.read(buffer, bytes);
  767. if (headerReceived(mesh_params, buffer, bytes))
  768. { //did not do an HTTP request, return false
  769. return true;
  770. }
  771. }
  772. }
  773. //either cache entry doesn't exist or is corrupt, request header from simulator
  774. bool retval = true ;
  775. std::vector<std::string> headers;
  776. headers.push_back("Accept: application/octet-stream");
  777. std::string http_url = constructUrl(mesh_params.getSculptID());
  778. if (!http_url.empty())
  779. {
  780. //grab first 4KB if we're going to bother with a fetch. Cache will prevent future fetches if a full mesh fits
  781. //within the first 4KB
  782. //NOTE -- this will break of headers ever exceed 4KB
  783. retval = mCurlRequest->getByteRange(http_url, headers, 0, 4096, new LLMeshHeaderResponder(mesh_params));
  784. if(retval)
  785. {
  786. ++sActiveHeaderRequests;
  787. LLMeshRepository::sHTTPRequestCount++;
  788. }
  789. count++;
  790. }
  791. return retval;
  792. }
  793. //return false if failed to get mesh lod.
  794. bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count)
  795. { //protected by mMutex
  796. mHeaderMutex->lock();
  797. bool retval = true;
  798. LLUUID mesh_id = mesh_params.getSculptID();
  799. U32 header_size = mMeshHeaderSize[mesh_id];
  800. if (header_size > 0)
  801. {
  802. S32 version = mMeshHeader[mesh_id]["version"].asInteger();
  803. S32 offset = header_size + mMeshHeader[mesh_id][header_lod[lod]]["offset"].asInteger();
  804. S32 size = mMeshHeader[mesh_id][header_lod[lod]]["size"].asInteger();
  805. mHeaderMutex->unlock();
  806. if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0)
  807. {
  808. //check VFS for mesh asset
  809. LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH);
  810. if (file.getSize() >= offset+size)
  811. {
  812. LLMeshRepository::sCacheBytesRead += size;
  813. file.seek(offset);
  814. U8* buffer = new U8[size];
  815. file.read(buffer, size);
  816. //make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written)
  817. bool zero = true;
  818. for (S32 i = 0; i < llmin(size, 1024) && zero; ++i)
  819. {
  820. zero = buffer[i] > 0 ? false : true;
  821. }
  822. if (!zero)
  823. { //attempt to parse
  824. if (lodReceived(mesh_params, lod, buffer, size))
  825. {
  826. delete[] buffer;
  827. return true;
  828. }
  829. }
  830. delete[] buffer;
  831. }
  832. //reading from VFS failed for whatever reason, fetch from sim
  833. std::vector<std::string> headers;
  834. headers.push_back("Accept: application/octet-stream");
  835. std::string http_url = constructUrl(mesh_id);
  836. if (!http_url.empty())
  837. {
  838. retval = mCurlRequest->getByteRange(constructUrl(mesh_id), headers, offset, size,
  839. new LLMeshLODResponder(mesh_params, lod, offset, size));
  840. if(retval)
  841. {
  842. ++sActiveLODRequests;
  843. LLMeshRepository::sHTTPRequestCount++;
  844. }
  845. count++;
  846. }
  847. else
  848. {
  849. mUnavailableQ.push(LODRequest(mesh_params, lod));
  850. }
  851. }
  852. else
  853. {
  854. mUnavailableQ.push(LODRequest(mesh_params, lod));
  855. }
  856. }
  857. else
  858. {
  859. mHeaderMutex->unlock();
  860. }
  861. return retval;
  862. }
  863. bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size)
  864. {
  865. LLSD header;
  866. U32 header_size = 0;
  867. if (data_size > 0)
  868. {
  869. std::string res_str((char*) data, data_size);
  870. std::string deprecated_header("<? LLSD/Binary ?>");
  871. if (res_str.substr(0, deprecated_header.size()) == deprecated_header)
  872. {
  873. res_str = res_str.substr(deprecated_header.size()+1, data_size);
  874. header_size = deprecated_header.size()+1;
  875. }
  876. data_size = res_str.size();
  877. std::istringstream stream(res_str);
  878. if (!LLSDSerialize::fromBinary(header, stream, data_size))
  879. {
  880. llwarns << "Mesh header parse error. Not a valid mesh asset!" << llendl;
  881. return false;
  882. }
  883. header_size += stream.tellg();
  884. }
  885. else
  886. {
  887. llinfos
  888. << "Marking header as non-existent, will not retry." << llendl;
  889. header["404"] = 1;
  890. }
  891. {
  892. LLUUID mesh_id = mesh_params.getSculptID();
  893. mHeaderMutex->lock();
  894. mMeshHeaderSize[mesh_id] = header_size;
  895. mMeshHeader[mesh_id] = header;
  896. mHeaderMutex->unlock();
  897. //check for pending requests
  898. pending_lod_map::iterator iter = mPendingLOD.find(mesh_params);
  899. if (iter != mPendingLOD.end())
  900. {
  901. LLMutexLock lock(mMutex);
  902. for (U32 i = 0; i < iter->second.size(); ++i)
  903. {
  904. LODRequest req(mesh_params, iter->second[i]);
  905. mLODReqQ.push(req);
  906. }
  907. }
  908. mPendingLOD.erase(iter);
  909. }
  910. return true;
  911. }
  912. bool LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size)
  913. {
  914. LLVolume* volume = new LLVolume(mesh_params, LLVolumeLODGroup::getVolumeScaleFromDetail(lod));
  915. std::string mesh_string((char*) data, data_size);
  916. std::istringstream stream(mesh_string);
  917. if (volume->unpackVolumeFaces(stream, data_size))
  918. {
  919. LoadedMesh mesh(volume, mesh_params, lod);
  920. if (volume->getNumFaces() > 0)
  921. {
  922. LLMutexLock lock(mMutex);
  923. mLoadedQ.push(mesh);
  924. return true;
  925. }
  926. }
  927. return false;
  928. }
  929. bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size)
  930. {
  931. LLSD skin;
  932. if (data_size > 0)
  933. {
  934. std::string res_str((char*) data, data_size);
  935. std::istringstream stream(res_str);
  936. if (!unzip_llsd(skin, stream, data_size))
  937. {
  938. llwarns << "Mesh skin info parse error. Not a valid mesh asset!" << llendl;
  939. return false;
  940. }
  941. }
  942. {
  943. LLMeshSkinInfo info(skin);
  944. info.mMeshID = mesh_id;
  945. //llinfos<<"info pelvis offset"<<info.mPelvisOffset<<llendl;
  946. mSkinInfoQ.push(info);
  947. }
  948. return true;
  949. }
  950. bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size)
  951. {
  952. LLSD decomp;
  953. if (data_size > 0)
  954. {
  955. std::string res_str((char*) data, data_size);
  956. std::istringstream stream(res_str);
  957. if (!unzip_llsd(decomp, stream, data_size))
  958. {
  959. llwarns << "Mesh decomposition parse error. Not a valid mesh asset!" << llendl;
  960. return false;
  961. }
  962. }
  963. {
  964. LLModel::Decomposition* d = new LLModel::Decomposition(decomp);
  965. d->mMeshID = mesh_id;
  966. mDecompositionQ.push(d);
  967. }
  968. return true;
  969. }
  970. bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size)
  971. {
  972. LLSD physics_shape;
  973. LLModel::Decomposition* d = new LLModel::Decomposition();
  974. d->mMeshID = mesh_id;
  975. if (data == NULL)
  976. { //no data, no physics shape exists
  977. d->mPhysicsShapeMesh.clear();
  978. }
  979. else
  980. {
  981. LLVolumeParams volume_params;
  982. volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
  983. volume_params.setSculptID(mesh_id, LL_SCULPT_TYPE_MESH);
  984. LLPointer<LLVolume> volume = new LLVolume(volume_params,0);
  985. std::string mesh_string((char*) data, data_size);
  986. std::istringstream stream(mesh_string);
  987. if (volume->unpackVolumeFaces(stream, data_size))
  988. {
  989. //load volume faces into decomposition buffer
  990. S32 vertex_count = 0;
  991. S32 index_count = 0;
  992. for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
  993. {
  994. const LLVolumeFace& face = volume->getVolumeFace(i);
  995. vertex_count += face.mNumVertices;
  996. index_count += face.mNumIndices;
  997. }
  998. d->mPhysicsShapeMesh.clear();
  999. std::vector<LLVector3>& pos = d->mPhysicsShapeMesh.mPositions;
  1000. std::vector<LLVector3>& norm = d->mPhysicsShapeMesh.mNormals;
  1001. for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
  1002. {
  1003. const LLVolumeFace& face = volume->getVolumeFace(i);
  1004. for (S32 i = 0; i < face.mNumIndices; ++i)
  1005. {
  1006. U16 idx = face.mIndices[i];
  1007. pos.push_back(LLVector3(face.mPositions[idx].getF32ptr()));
  1008. norm.push_back(LLVector3(face.mNormals[idx].getF32ptr()));
  1009. }
  1010. }
  1011. }
  1012. }
  1013. mDecompositionQ.push(d);
  1014. return true;
  1015. }
  1016. LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, LLVector3& scale, bool upload_textures,
  1017. bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload,
  1018. LLHandle<LLWholeModelFeeObserver> fee_observer, LLHandle<LLWholeModelUploadObserver> upload_observer)
  1019. : LLThread("mesh upload"),
  1020. mDiscarded(FALSE),
  1021. mDoUpload(do_upload),
  1022. mWholeModelUploadURL(upload_url),
  1023. mFeeObserverHandle(fee_observer),
  1024. mUploadObserverHandle(upload_observer)
  1025. {
  1026. mInstanceList = data;
  1027. mUploadTextures = upload_textures;
  1028. mUploadSkin = upload_skin;
  1029. mUploadJoints = upload_joints;
  1030. mMutex = new LLMutex(NULL);
  1031. mCurlRequest = NULL;
  1032. mPendingUploads = 0;
  1033. mFinished = false;
  1034. mOrigin = gAgent.getPositionAgent();
  1035. mHost = gAgent.getRegionHost();
  1036. mWholeModelFeeCapability = gAgent.getRegion()->getCapability("NewFileAgentInventory");
  1037. mOrigin += gAgent.getAtAxis() * scale.magVec();
  1038. mMeshUploadTimeOut = gSavedSettings.getS32("MeshUploadTimeOut") ;
  1039. }
  1040. LLMeshUploadThread::~LLMeshUploadThread()
  1041. {
  1042. }
  1043. LLMeshUploadThread::DecompRequest::DecompRequest(LLModel* mdl, LLModel* base_model, LLMeshUploadThread* thread)
  1044. {
  1045. mStage = "single_hull";
  1046. mModel = mdl;
  1047. mDecompID = &mdl->mDecompID;
  1048. mBaseModel = base_model;
  1049. mThread = thread;
  1050. //copy out positions and indices
  1051. assignData(mdl) ;
  1052. mThread->mFinalDecomp = this;
  1053. mThread->mPhysicsComplete = false;
  1054. }
  1055. void LLMeshUploadThread::DecompRequest::completed()
  1056. {
  1057. if (mThread->mFinalDecomp == this)
  1058. {
  1059. mThread->mPhysicsComplete = true;
  1060. }
  1061. llassert(mHull.size() == 1);
  1062. mThread->mHullMap[mBaseModel] = mHull[0];
  1063. }
  1064. //called in the main thread.
  1065. void LLMeshUploadThread::preStart()
  1066. {
  1067. //build map of LLModel refs to instances for callbacks
  1068. for (instance_list::iterator iter = mInstanceList.begin(); iter != mInstanceList.end(); ++iter)
  1069. {
  1070. mInstance[iter->mModel].push_back(*iter);
  1071. }
  1072. }
  1073. void LLMeshUploadThread::discard()
  1074. {
  1075. LLMutexLock lock(mMutex) ;
  1076. mDiscarded = TRUE ;
  1077. }
  1078. BOOL LLMeshUploadThread::isDiscarded()
  1079. {
  1080. LLMutexLock lock(mMutex) ;
  1081. return mDiscarded ;
  1082. }
  1083. void LLMeshUploadThread::run()
  1084. {
  1085. if (mDoUpload)
  1086. {
  1087. doWholeModelUpload();
  1088. }
  1089. else
  1090. {
  1091. requestWholeModelFee();
  1092. }
  1093. }
  1094. void dump_llsd_to_file(const LLSD& content, std::string filename)
  1095. {
  1096. if (gSavedSettings.getBOOL("MeshUploadLogXML"))
  1097. {
  1098. std::ofstream of(filename.c_str());
  1099. LLSDSerialize::toPrettyXML(content,of);
  1100. }
  1101. }
  1102. LLSD llsd_from_file(std::string filename)
  1103. {
  1104. std::ifstream ifs(filename.c_str());
  1105. LLSD result;
  1106. LLSDSerialize::fromXML(result,ifs);
  1107. return result;
  1108. }
  1109. void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
  1110. {
  1111. LLSD result;
  1112. LLSD res;
  1113. result["folder_id"] = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT);
  1114. result["texture_folder_id"] = gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE);
  1115. result["asset_type"] = "mesh";
  1116. result["inventory_type"] = "object";
  1117. result["description"] = "(No Description)";
  1118. result["next_owner_mask"] = LLSD::Integer(LLFloaterPerms::getNextOwnerPerms());
  1119. result["group_mask"] = LLSD::Integer(LLFloaterPerms::getGroupPerms());
  1120. result["everyone_mask"] = LLSD::Integer(LLFloaterPerms::getEveryonePerms());
  1121. res["mesh_list"] = LLSD::emptyArray();
  1122. res["texture_list"] = LLSD::emptyArray();
  1123. res["instance_list"] = LLSD::emptyArray();
  1124. S32 mesh_num = 0;
  1125. S32 texture_num = 0;
  1126. std::set<LLViewerTexture* > textures;
  1127. std::map<LLViewerTexture*,S32> texture_index;
  1128. std::map<LLModel*,S32> mesh_index;
  1129. std::string model_name;
  1130. std::string model_metric;
  1131. S32 instance_num = 0;
  1132. for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter)
  1133. {
  1134. LLMeshUploadData data;
  1135. data.mBaseModel = iter->first;
  1136. LLModelInstance& first_instance = *(iter->second.begin());
  1137. for (S32 i = 0; i < 5; i++)
  1138. {
  1139. data.mModel[i] = first_instance.mLOD[i];
  1140. }
  1141. if (mesh_index.find(data.mBaseModel) == mesh_index.end())
  1142. {
  1143. // Have not seen this model before - create a new mesh_list entry for it.
  1144. if (model_name.empty())
  1145. {
  1146. model_name = data.mBaseModel->getName();
  1147. }
  1148. if (model_metric.empty())
  1149. {
  1150. model_metric = data.mBaseModel->getMetric();
  1151. }
  1152. std::stringstream ostr;
  1153. LLModel::Decomposition& decomp =
  1154. data.mModel[LLModel::LOD_PHYSICS].notNull() ?
  1155. data.mModel[LLModel::LOD_PHYSICS]->mPhysics :
  1156. data.mBaseModel->mPhysics;
  1157. decomp.mBaseHull = mHullMap[data.mBaseModel];
  1158. LLSD mesh_header = LLModel::writeModel(
  1159. ostr,
  1160. data.mModel[LLModel::LOD_PHYSICS],
  1161. data.mModel[LLModel::LOD_HIGH],
  1162. data.mModel[LLModel::LOD_MEDIUM],
  1163. data.mModel[LLModel::LOD_LOW],
  1164. data.mModel[LLModel::LOD_IMPOSTOR],
  1165. decomp,
  1166. mUploadSkin,
  1167. mUploadJoints);
  1168. data.mAssetData = ostr.str();
  1169. std::string str = ostr.str();
  1170. res["mesh_list"][mesh_num] = LLSD::Binary(str.begin(),str.end());
  1171. mesh_index[data.mBaseModel] = mesh_num;
  1172. mesh_num++;
  1173. }
  1174. // For all instances that use this model
  1175. for (instance_list::iterator instance_iter = iter->second.begin();
  1176. instance_iter != iter->second.end();
  1177. ++instance_iter)
  1178. {
  1179. LLModelInstance& instance = *instance_iter;
  1180. LLSD instance_entry;
  1181. for (S32 i = 0; i < 5; i++)
  1182. {
  1183. data.mModel[i] = instance.mLOD[i];
  1184. }
  1185. LLVector3 pos, scale;
  1186. LLQuaternion rot;
  1187. LLMatrix4 transformation = instance.mTransform;
  1188. decomposeMeshMatrix(transformation,pos,rot,scale);
  1189. instance_entry["position"] = ll_sd_from_vector3(pos);
  1190. instance_entry["rotation"] = ll_sd_from_quaternion(rot);
  1191. instance_entry["scale"] = ll_sd_from_vector3(scale);
  1192. instance_entry["material"] = LL_MCODE_WOOD;
  1193. instance_entry["physics_shape_type"] = (U8)(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL);
  1194. instance_entry["mesh"] = mesh_index[data.mBaseModel];
  1195. instance_entry["face_list"] = LLSD::emptyArray();
  1196. S32 end = llmin((S32)data.mBaseModel->mMaterialList.size(), data.mBaseModel->getNumVolumeFaces()) ;
  1197. for (S32 face_num = 0; face_num < end; face_num++)
  1198. {
  1199. LLImportMaterial& material = instance.mMaterial[data.mBaseModel->mMaterialList[face_num]];
  1200. LLSD face_entry = LLSD::emptyMap();
  1201. LLViewerFetchedTexture *texture = material.mDiffuseMap.get();
  1202. if ((texture != NULL) &&
  1203. (textures.find(texture) == textures.end()))
  1204. {
  1205. textures.insert(texture);
  1206. }
  1207. std::stringstream texture_str;
  1208. if (texture != NULL && include_textures && mUploadTextures)
  1209. {
  1210. if(texture->hasSavedRawImage())
  1211. {
  1212. LLPointer<LLImageJ2C> upload_file =
  1213. LLViewerTextureList::convertToUploadFile(texture->getSavedRawImage());
  1214. texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize());
  1215. }
  1216. }
  1217. if (texture != NULL &&
  1218. mUploadTextures &&
  1219. texture_index.find(texture) == texture_index.end())
  1220. {
  1221. texture_index[texture] = texture_num;
  1222. std::string str = texture_str.str();
  1223. res["texture_list"][texture_num] = LLSD::Binary(str.begin(),str.end());
  1224. texture_num++;
  1225. }
  1226. // Subset of TextureEntry fields.
  1227. if (texture != NULL && mUploadTextures)
  1228. {
  1229. face_entry["image"] = texture_index[texture];
  1230. face_entry["scales"] = 1.0;
  1231. face_entry["scalet"] = 1.0;
  1232. face_entry["offsets"] = 0.0;
  1233. face_entry["offsett"] = 0.0;
  1234. face_entry["imagerot"] = 0.0;
  1235. }
  1236. face_entry["diffuse_color"] = ll_sd_from_color4(material.mDiffuseColor);
  1237. face_entry["fullbright"] = material.mFullbright;
  1238. instance_entry["face_list"][face_num] = face_entry;
  1239. }
  1240. res["instance_list"][instance_num] = instance_entry;
  1241. instance_num++;
  1242. }
  1243. }
  1244. if (model_name.empty()) model_name = "mesh model";
  1245. result["name"] = model_name;
  1246. if (model_metric.empty()) model_metric = "MUT_Unspecified";
  1247. res["metric"] = model_metric;
  1248. result["asset_resources"] = res;
  1249. dump_llsd_to_file(result,make_dump_name("whole_model_",dump_num));
  1250. dest = result;
  1251. }
  1252. void LLMeshUploadThread::generateHulls()
  1253. {
  1254. bool has_valid_requests = false ;
  1255. for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter)
  1256. {
  1257. LLMeshUploadData data;
  1258. data.mBaseModel = iter->first;
  1259. LLModelInstance& instance = *(iter->second.begin());
  1260. for (S32 i = 0; i < 5; i++)
  1261. {
  1262. data.mModel[i] = instance.mLOD[i];
  1263. }
  1264. //queue up models for hull generation
  1265. LLModel* physics = NULL;
  1266. if (data.mModel[LLModel::LOD_PHYSICS].notNull())
  1267. {
  1268. physics = data.mModel[LLModel::LOD_PHYSICS];
  1269. }
  1270. else if (data.mModel[LLModel::LOD_LOW].notNull())
  1271. {
  1272. physics = data.mModel[LLModel::LOD_LOW];
  1273. }
  1274. else if (data.mModel[LLModel::LOD_MEDIUM].notNull())
  1275. {
  1276. physics = data.mModel[LLModel::LOD_MEDIUM];
  1277. }
  1278. else
  1279. {
  1280. physics = data.mModel[LLModel::LOD_HIGH];
  1281. }
  1282. llassert(physics != NULL);
  1283. DecompRequest* request = new DecompRequest(physics, data.mBaseModel, this);
  1284. if(request->isValid())
  1285. {
  1286. gMeshRepo.mDecompThread->submitRequest(request);
  1287. has_valid_requests = true ;
  1288. }
  1289. }
  1290. if(has_valid_requests)
  1291. {
  1292. while (!mPhysicsComplete)
  1293. {
  1294. apr_sleep(100);
  1295. }
  1296. }
  1297. }
  1298. void LLMeshUploadThread::doWholeModelUpload()
  1299. {
  1300. mCurlRequest = new LLCurlRequest();
  1301. if (mWholeModelUploadURL.empty())
  1302. {
  1303. llinfos << "unable to upload, fee request failed" << llendl;
  1304. }
  1305. else
  1306. {
  1307. generateHulls();
  1308. LLSD full_model_data;
  1309. wholeModelToLLSD(full_model_data, true);
  1310. LLSD body = full_model_data["asset_resources"];
  1311. dump_llsd_to_file(body,make_dump_name("whole_model_body_",dump_num));
  1312. LLCurlRequest::headers_t headers;
  1313. {
  1314. LLCurl::ResponderPtr responder = new LLWholeModelUploadResponder(this, full_model_data, mUploadObserverHandle) ;
  1315. while(!mCurlRequest->post(mWholeModelUploadURL, headers, body, responder, mMeshUploadTimeOut))
  1316. {
  1317. //sleep for 10ms to prevent eating a whole core
  1318. apr_sleep(10000);
  1319. }
  1320. }
  1321. do
  1322. {
  1323. mCurlRequest->process();
  1324. //sleep for 10ms to prevent eating a whole core
  1325. apr_sleep(10000);
  1326. } while (mCurlRequest->getQueued() > 0);
  1327. }
  1328. delete mCurlRequest;
  1329. mCurlRequest = NULL;
  1330. // Currently a no-op.
  1331. mFinished = true;
  1332. }
  1333. void LLMeshUploadThread::requestWholeModelFee()
  1334. {
  1335. dump_num++;
  1336. mCurlRequest = new LLCurlRequest();
  1337. generateHulls();
  1338. LLSD model_data;
  1339. wholeModelToLLSD(model_data,false);
  1340. dump_llsd_to_file(model_data,make_dump_name("whole_model_fee_request_",dump_num));
  1341. mPendingUploads++;
  1342. LLCurlRequest::headers_t headers;
  1343. {
  1344. LLCurl::ResponderPtr responder = new LLWholeModelFeeResponder(this,model_data, mFeeObserverHandle) ;
  1345. while(!mCurlRequest->post(mWholeModelFeeCapability, headers, model_data, responder, mMeshUploadTimeOut))
  1346. {
  1347. //sleep for 10ms to prevent eating a whole core
  1348. apr_sleep(10000);
  1349. }
  1350. }
  1351. do
  1352. {
  1353. mCurlRequest->process();
  1354. //sleep for 10ms to prevent eating a whole core
  1355. apr_sleep(10000);
  1356. } while (mCurlRequest->getQueued() > 0);
  1357. delete mCurlRequest;
  1358. mCurlRequest = NULL;
  1359. // Currently a no-op.
  1360. mFinished = true;
  1361. }
  1362. void LLMeshRepoThread::notifyLoadedMeshes()
  1363. {
  1364. while (!mLoadedQ.empty())
  1365. {
  1366. mMutex->lock();
  1367. LoadedMesh mesh = mLoadedQ.front();
  1368. mLoadedQ.pop();
  1369. mMutex->unlock();
  1370. if (mesh.mVolume && mesh.mVolume->getNumVolumeFaces() > 0)
  1371. {
  1372. gMeshRepo.notifyMeshLoaded(mesh.mMeshParams, mesh.mVolume);
  1373. }
  1374. else
  1375. {
  1376. gMeshRepo.notifyMeshUnavailable(mesh.mMeshParams,
  1377. LLVolumeLODGroup::getVolumeDetailFromScale(mesh.mVolume->getDetail()));
  1378. }
  1379. }
  1380. while (!mUnavailableQ.empty())
  1381. {
  1382. mMutex->lock();
  1383. LODRequest req = mUnavailableQ.front();
  1384. mUnavailableQ.pop();
  1385. mMutex->unlock();
  1386. gMeshRepo.notifyMeshUnavailable(req.mMeshParams, req.mLOD);
  1387. }
  1388. while (!mSkinInfoQ.empty())
  1389. {
  1390. gMeshRepo.notifySkinInfoReceived(mSkinInfoQ.front());
  1391. mSkinInfoQ.pop();
  1392. }
  1393. while (!mDecompositionQ.empty())
  1394. {
  1395. gMeshRepo.notifyDecompositionReceived(mDecompositionQ.front());
  1396. mDecompositionQ.pop();
  1397. }
  1398. }
  1399. S32 LLMeshRepoThread::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
  1400. { //only ever called from main thread
  1401. LLMutexLock lock(mHeaderMutex);
  1402. mesh_header_map::iterator iter = mMeshHeader.find(mesh_params.getSculptID());
  1403. if (iter != mMeshHeader.end())
  1404. {
  1405. LLSD& header = iter->second;
  1406. return LLMeshRepository::getActualMeshLOD(header, lod);
  1407. }
  1408. return lod;
  1409. }
  1410. //static
  1411. S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod)
  1412. {
  1413. lod = llclamp(lod, 0, 3);
  1414. S32 version = header["version"];
  1415. if (header.has("404") || version > MAX_MESH_VERSION)
  1416. {
  1417. return -1;
  1418. }
  1419. if (header[header_lod[lod]]["size"].asInteger() > 0)
  1420. {
  1421. return lod;
  1422. }
  1423. //search down to find the next available lower lod
  1424. for (S32 i = lod-1; i >= 0; --i)
  1425. {
  1426. if (header[header_lod[i]]["size"].asInteger() > 0)
  1427. {
  1428. return i;
  1429. }
  1430. }
  1431. //search up to find then ext available higher lod
  1432. for (S32 i = lod+1; i < 4; ++i)
  1433. {
  1434. if (header[header_lod[i]]["size"].asInteger() > 0)
  1435. {
  1436. return i;
  1437. }
  1438. }
  1439. //header exists and no good lod found, treat as 404
  1440. header["404"] = 1;
  1441. return -1;
  1442. }
  1443. void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header)
  1444. {
  1445. mThread->mMeshHeader[data.mUUID] = header;
  1446. // we cache the mesh for default parameters
  1447. LLVolumeParams volume_params;
  1448. volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
  1449. volume_params.setSculptID(data.mUUID, LL_SCULPT_TYPE_MESH);
  1450. for (U32 i = 0; i < 4; i++)
  1451. {
  1452. if (data.mModel[i].notNull())
  1453. {
  1454. LLPointer<LLVolume> volume = new LLVolume(volume_params, LLVolumeLODGroup::getVolumeScaleFromDetail(i));
  1455. volume->copyVolumeFaces(data.mModel[i]);
  1456. volume->setMeshAssetLoaded(TRUE);
  1457. }
  1458. }
  1459. }
  1460. void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason,
  1461. const LLChannelDescriptors& channels,
  1462. const LLIOPipe::buffer_ptr_t& buffer)
  1463. {
  1464. LLMeshRepoThread::sActiveLODRequests--;
  1465. S32 data_size = buffer->countAfter(channels.in(), NULL);
  1466. if (status < 200 || status > 400)
  1467. {
  1468. llwarns << status << ": " << reason << llendl;
  1469. }
  1470. if (data_size < mRequestedBytes)
  1471. {
  1472. if (status == 499 || status == 503)
  1473. { //timeout or service unavailable, try again
  1474. LLMeshRepository::sHTTPRetryCount++;
  1475. gMeshRepo.mThread->loadMeshLOD(mMeshParams, mLOD);
  1476. }
  1477. else
  1478. {
  1479. llwarns << "Unhandled status " << status << llendl;
  1480. }
  1481. return;
  1482. }
  1483. LLMeshRepository::sBytesReceived += mRequestedBytes;
  1484. U8* data = NULL;
  1485. if (data_size > 0)
  1486. {
  1487. data = new U8[data_size];
  1488. buffer->readAfter(channels.in(), NULL, data, data_size);
  1489. }
  1490. if (gMeshRepo.mThread->lodReceived(mMeshParams, mLOD, data, data_size))
  1491. {
  1492. //good fetch from sim, write to VFS for caching
  1493. LLVFile file(gVFS, mMeshParams.getSculptID(), LLAssetType::AT_MESH, LLVFile::WRITE);
  1494. S32 offset = mOffset;
  1495. S32 size = mRequestedBytes;
  1496. if (file.getSize() >= offset+size)
  1497. {
  1498. file.seek(offset);
  1499. file.write(data, size);
  1500. LLMeshRepository::sCacheBytesWritten += size;
  1501. }
  1502. }
  1503. delete [] data;
  1504. }
  1505. void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason,
  1506. const LLChannelDescriptors& channels,
  1507. const LLIOPipe::buffer_ptr_t& buffer)
  1508. {
  1509. S32 data_size = buffer->countAfter(channels.in(), NULL);
  1510. if (status < 200 || status > 400)
  1511. {
  1512. llwarns << status << ": " << reason << llendl;
  1513. }
  1514. if (data_size < mRequestedBytes)
  1515. {
  1516. if (status == 499 || status == 503)
  1517. { //timeout or service unavailable, try again
  1518. LLMeshRepository::sHTTPRetryCount++;
  1519. gMeshRepo.mThread->loadMeshSkinInfo(mMeshID);
  1520. }
  1521. else
  1522. {
  1523. llwarns << "Unhandled status " << status << llendl;
  1524. }
  1525. return;
  1526. }
  1527. LLMeshRepository::sBytesReceived += mRequestedBytes;
  1528. U8* data = NULL;
  1529. if (data_size > 0)
  1530. {
  1531. data = new U8[data_size];
  1532. buffer->readAfter(channels.in(), NULL, data, data_size);
  1533. }
  1534. if (gMeshRepo.mThread->skinInfoReceived(mMeshID, data, data_size))
  1535. {
  1536. //good fetch from sim, write to VFS for caching
  1537. LLVFile file(gVFS, mMeshID, LLAssetType::AT_MESH, LLVFile::WRITE);
  1538. S32 offset = mOffset;
  1539. S32 size = mRequestedBytes;
  1540. if (file.getSize() >= offset+size)
  1541. {
  1542. LLMeshRepository::sCacheBytesWritten += size;
  1543. file.seek(offset);
  1544. file.write(data, size);
  1545. }
  1546. }
  1547. delete [] data;
  1548. }
  1549. void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& reason,
  1550. const LLChannelDescriptors& channels,
  1551. const LLIOPipe::buffer_ptr_t& buffer)
  1552. {
  1553. S32 data_size = buffer->countAfter(channels.in(), NULL);
  1554. if (status < 200 || status > 400)
  1555. {
  1556. llwarns << status << ": " << reason << llendl;
  1557. }
  1558. if (data_size < mRequestedBytes)
  1559. {
  1560. if (status == 499 || status == 503)
  1561. { //timeout or service unavailable, try again
  1562. LLMeshRepository::sHTTPRetryCount++;
  1563. gMeshRepo.mThread->loadMeshDecomposition(mMeshID);
  1564. }
  1565. else
  1566. {
  1567. llwarns << "Unhandled status " << status << llendl;
  1568. }
  1569. return;
  1570. }
  1571. LLMeshRepository::sBytesReceived += mRequestedBytes;
  1572. U8* data = NULL;
  1573. if (data_size > 0)
  1574. {
  1575. data = new U8[data_size];
  1576. buffer->readAfter(channels.in(), NULL, data, data_size);
  1577. }
  1578. if (gMeshRepo.mThread->decompositionReceived(mMeshID, data, data_size))
  1579. {
  1580. //good fetch from sim, write to VFS for caching
  1581. LLVFile file(gVFS, mMeshID, LLAssetType::AT_MESH, LLVFile::WRITE);
  1582. S32 offset = mOffset;
  1583. S32 size = mRequestedBytes;
  1584. if (file.getSize() >= offset+size)
  1585. {
  1586. LLMeshRepository::sCacheBytesWritten += size;
  1587. file.seek(offset);
  1588. file.write(data, size);
  1589. }
  1590. }
  1591. delete [] data;
  1592. }
  1593. void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& reason,
  1594. const LLChannelDescriptors& channels,
  1595. const LLIOPipe::buffer_ptr_t& buffer)
  1596. {
  1597. S32 data_size = buffer->countAfter(channels.in(), NULL);
  1598. if (status < 200 || status > 400)
  1599. {
  1600. llwarns << status << ": " << reason << llendl;
  1601. }
  1602. if (data_size < mRequestedBytes)
  1603. {
  1604. if (status == 499 || status == 503)
  1605. { //timeout or service unavailable, try again
  1606. LLMeshRepository::sHTTPRetryCount++;
  1607. gMeshRepo.mThread->loadMeshPhysicsShape(mMeshID);
  1608. }
  1609. else
  1610. {
  1611. llwarns << "Unhandled status " << status << llendl;
  1612. }
  1613. return;
  1614. }
  1615. LLMeshRepository::sBytesReceived += mRequestedBytes;
  1616. U8* data = NULL;
  1617. if (data_size > 0)
  1618. {
  1619. data = new U8[data_size];
  1620. buffer->readAfter(channels.in(), NULL, data, data_size);
  1621. }
  1622. if (gMeshRepo.mThread->physicsShapeReceived(mMeshID, data, data_size))
  1623. {
  1624. //good fetch from sim, write to VFS for caching
  1625. LLVFile file(gVFS, mMeshID, LLAssetType::AT_MESH, LLVFile::WRITE);
  1626. S32 offset = mOffset;
  1627. S32 size = mRequestedBytes;
  1628. if (file.getSize() >= offset+size)
  1629. {
  1630. LLMeshRepository::sCacheBytesWritten += size;
  1631. file.seek(offset);
  1632. file.write(data, size);
  1633. }
  1634. }
  1635. delete [] data;
  1636. }
  1637. void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
  1638. const LLChannelDescriptors& channels,
  1639. const LLIOPipe::buffer_ptr_t& buffer)
  1640. {
  1641. LLMeshRepoThread::sActiveHeaderRequests--;
  1642. if (status < 200 || status > 400)
  1643. {
  1644. //llwarns
  1645. // << "Header responder failed with status: "
  1646. // << status << ": " << reason << llendl;
  1647. // 503 (service unavailable) or 499 (timeout)
  1648. // can be due to server load and can be retried
  1649. // TODO*: Add maximum retry logic, exponential backoff
  1650. // and (somewhat more optional than the others) retries
  1651. // again after some set period of time
  1652. if (status == 503 || status == 499)
  1653. { //retry
  1654. LLMeshRepository::sHTTPRetryCount++;
  1655. LLMeshRepoThread::HeaderRequest req(mMeshParams);
  1656. LLMutexLock lock(gMeshRepo.mThread->mMutex);
  1657. gMeshRepo.mThread->mHeaderReqQ.push(req);
  1658. return;
  1659. }
  1660. }
  1661. S32 data_size = buffer->countAfter(channels.in(), NULL);
  1662. U8* data = NULL;
  1663. if (data_size > 0)
  1664. {
  1665. data = new U8[data_size];
  1666. buffer->readAfter(channels.in(), NULL, data, data_size);
  1667. }
  1668. LLMeshRepository::sBytesReceived += llmin(data_size, 4096);
  1669. if (!gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size))
  1670. {
  1671. llwarns
  1672. << "Unable to parse mesh header: "
  1673. << status << ": " << reason << llendl;
  1674. }
  1675. else if (data && data_size > 0)
  1676. {
  1677. //header was successfully retrieved from sim, cache in vfs
  1678. LLUUID mesh_id = mMeshParams.getSculptID();
  1679. LLSD header = gMeshRepo.mThread->mMeshHeader[mesh_id];
  1680. S32 version = header["version"].asInteger();
  1681. if (version <= MAX_MESH_VERSION)
  1682. {
  1683. std::stringstream str;
  1684. S32 lod_bytes = 0;
  1685. for (U32 i = 0; i < LLModel::LOD_PHYSICS; ++i)
  1686. { //figure out how many bytes we'll need to reserve in the file
  1687. std::string lod_name = header_lod[i];
  1688. lod_bytes = llmax(lod_bytes, header[lod_name]["offset"].asInteger()+header[lod_name]["size"].asInteger());
  1689. }
  1690. //just in case skin info or decomposition is at the end of the file (which it shouldn't be)
  1691. lod_bytes = llmax(lod_bytes, header["skin"]["offset"].asInteger() + header["skin"]["size"].asInteger());
  1692. lod_bytes = llmax(lod_bytes, header["physics_convex"]["offset"].asInteger() + header["physics_convex"]["size"].asInteger());
  1693. S32 header_bytes = (S32) gMeshRepo.mThread->mMeshHeaderSize[mesh_id];
  1694. S32 bytes = lod_bytes + header_bytes;
  1695. //it's possible for the remote asset to have more data than is needed for the local cache
  1696. //only allocate as much space in the VFS as is needed for the local cache
  1697. data_size = llmin(data_size, bytes);
  1698. LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH, LLVFile::WRITE);
  1699. if (file.getMaxSize() >= bytes || file.setMaxSize(bytes))
  1700. {
  1701. LLMeshRepository::sCacheBytesWritten += data_size;
  1702. file.write((const U8*) data, data_size);
  1703. //zero out the rest of the file
  1704. U8 block[4096];
  1705. memset(block, 0, 4096);
  1706. while (bytes-file.tell() > 4096)
  1707. {
  1708. file.write(block, 4096);
  1709. }
  1710. S32 remaining = bytes-file.tell();
  1711. if (remaining > 0)
  1712. {
  1713. file.write(block, remaining);
  1714. }
  1715. }
  1716. }
  1717. }
  1718. delete [] data;
  1719. }
  1720. LLMeshRepository::LLMeshRepository()
  1721. : mMeshMutex(NULL),
  1722. mMeshThreadCount(0),
  1723. mThread(NULL)
  1724. {
  1725. }
  1726. void LLMeshRepository::init()
  1727. {
  1728. mMeshMutex = new LLMutex(NULL);
  1729. LLConvexDecomposition::getInstance()->initSystem();
  1730. mDecompThread = new LLPhysicsDecomp();
  1731. mDecompThread->start();
  1732. while (!mDecompThread->mInited)
  1733. { //wait for physics decomp thread to init
  1734. apr_sleep(100);
  1735. }
  1736. mThread = new LLMeshRepoThread();
  1737. mThread->start();
  1738. }
  1739. void LLMeshRepository::shutdown()
  1740. {
  1741. llinfos << "Shutting down mesh repository." << llendl;
  1742. for (U32 i = 0; i < mUploads.size(); ++i)
  1743. {
  1744. llinfos << "Discard the pending mesh uploads " << llendl;
  1745. mUploads[i]->discard() ; //discard the uploading requests.
  1746. }
  1747. mThread->mSignal->signal();
  1748. while (!mThread->isStopped())
  1749. {
  1750. apr_sleep(10);
  1751. }
  1752. delete mThread;
  1753. mThread = NULL;
  1754. for (U32 i = 0; i < mUploads.size(); ++i)
  1755. {
  1756. llinfos << "Waiting for pending mesh upload " << i << "/" << mUploads.size() << llendl;
  1757. while (!mUploads[i]->isStopped())
  1758. {
  1759. apr_sleep(10);
  1760. }
  1761. delete mUploads[i];
  1762. }
  1763. mUploads.clear();
  1764. delete mMeshMutex;
  1765. mMeshMutex = NULL;
  1766. llinfos << "Shutting down decomposition system." << llendl;
  1767. if (mDecompThread)
  1768. {
  1769. mDecompThread->shutdown();
  1770. delete mDecompThread;
  1771. mDecompThread = NULL;
  1772. }
  1773. LLConvexDecomposition::quitSystem();
  1774. }
  1775. //called in the main thread.
  1776. S32 LLMeshRepository::update()
  1777. {
  1778. if(mUploadWaitList.empty())
  1779. {
  1780. return 0 ;
  1781. }
  1782. S32 size = mUploadWaitList.size() ;
  1783. for (S32 i = 0; i < size; ++i)
  1784. {
  1785. mUploads.push_back(mUploadWaitList[i]);
  1786. mUploadWaitList[i]->preStart() ;
  1787. mUploadWaitList[i]->start() ;
  1788. }
  1789. mUploadWaitList.clear() ;
  1790. return size ;
  1791. }
  1792. S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 detail, S32 last_lod)
  1793. {
  1794. if (detail < 0 || detail > 4)
  1795. {
  1796. return detail;
  1797. }
  1798. {
  1799. LLMutexLock lock(mMeshMutex);
  1800. //add volume to list of loading meshes
  1801. mesh_load_map::iterator iter = mLoadingMeshes[detail].find(mesh_params);
  1802. if (iter != mLoadingMeshes[detail].end())
  1803. { //request pending for this mesh, append volume id to list
  1804. iter->second.insert(vobj->getID());
  1805. }
  1806. else
  1807. {
  1808. //first request for this mesh
  1809. mLoadingMeshes[detail][mesh_params].insert(vobj->getID());
  1810. mPendingRequests.push_back(LLMeshRepoThread::LODRequest(mesh_params, detail));
  1811. }
  1812. }
  1813. //do a quick search to see if we can't display something while we wait for this mesh to load
  1814. LLVolume* volume = vobj->getVolume();
  1815. if (volume)
  1816. {
  1817. LLVolumeParams params = volume->getParams();
  1818. LLVolumeLODGroup* group = LLPrimitive::getVolumeManager()->getGroup(params);
  1819. if (group)
  1820. {
  1821. //first, see if last_lod is available (don't transition down to avoid funny popping a la SH-641)
  1822. if (last_lod >= 0)
  1823. {
  1824. LLVolume* lod = group->refLOD(last_lod);
  1825. if (lod && lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0)
  1826. {
  1827. group->derefLOD(lod);
  1828. return last_lod;
  1829. }
  1830. group->derefLOD(lod);
  1831. }
  1832. //next, see what the next lowest LOD available might be
  1833. for (S32 i = detail-1; i >= 0; --i)
  1834. {
  1835. LLVolume* lod = group->refLOD(i);
  1836. if (lod && lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0)
  1837. {
  1838. group->derefLOD(lod);
  1839. return i;
  1840. }
  1841. group->derefLOD(lod);
  1842. }
  1843. //no lower LOD is a available, is a higher lod available?
  1844. for (S32 i = detail+1; i < 4; ++i)
  1845. {
  1846. LLVolume* lod = group->refLOD(i);
  1847. if (lod && lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0)
  1848. {
  1849. group->derefLOD(lod);
  1850. return i;
  1851. }
  1852. group->derefLOD(lod);
  1853. }
  1854. }
  1855. }
  1856. return detail;
  1857. }
  1858. void LLMeshRepository::notifyLoadedMeshes()
  1859. { //called from main thread
  1860. LLMeshRepoThread::sMaxConcurrentRequests = gSavedSettings.getU32("MeshMaxConcurrentRequests");
  1861. //clean up completed upload threads
  1862. for (std::vector<LLMeshUploadThread*>::iterator iter = mUploads.begin(); iter != mUploads.end(); )
  1863. {
  1864. LLMeshUploadThread* thread = *iter;
  1865. if (thread->isStopped() && thread->finished())
  1866. {
  1867. iter = mUploads.erase(iter);
  1868. delete thread;
  1869. }
  1870. else
  1871. {
  1872. ++iter;
  1873. }
  1874. }
  1875. //update inventory
  1876. if (!mInventoryQ.empty())
  1877. {
  1878. LLMutexLock lock(mMeshMutex);
  1879. while (!mInventoryQ.empty())
  1880. {
  1881. inventory_data& data = mInventoryQ.front();
  1882. LLAssetType::EType asset_type = LLAssetType::lookup(data.mPostData["asset_type"].asString());
  1883. LLInventoryType::EType inventory_type = LLInventoryType::lookup(data.mPostData["inventory_type"].asString());
  1884. // Handle addition of texture, if any.
  1885. if ( data.mResponse.has("new_texture_folder_id") )
  1886. {
  1887. const LLUUID& folder_id = data.mResponse["new_texture_folder_id"].asUUID();
  1888. if ( folder_id.notNull() )
  1889. {
  1890. LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE);
  1891. std::string name;
  1892. // Check if the server built a different name for the texture folder
  1893. if ( data.mResponse.has("new_texture_folder_name") )
  1894. {
  1895. name = data.mResponse["new_texture_folder_name"].asString();
  1896. }
  1897. else
  1898. {
  1899. name = data.mPostData["name"].asString();
  1900. }
  1901. // Add the category to the internal representation
  1902. LLPointer<LLViewerInventoryCategory> cat =
  1903. new LLViewerInventoryCategory(folder_id, parent_id,
  1904. LLFolderType::FT_NONE, name, gAgent.getID());
  1905. cat->setVersion(LLViewerInventoryCategory::VERSION_UNKNOWN);
  1906. LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
  1907. gInventory.accountForUpdate(update);
  1908. gInventory.updateCategory(cat);
  1909. }
  1910. }
  1911. on_new_single_inventory_upload_complete(
  1912. asset_type,
  1913. inventory_type,
  1914. data.mPostData["asset_type"].asString(),
  1915. data.mPostData["folder_id"].asUUID(),
  1916. data.mPostData["name"],
  1917. data.mPostData["description"],
  1918. data.mResponse,
  1919. data.mResponse["upload_price"]);
  1920. //}
  1921. mInventoryQ.pop();
  1922. }
  1923. }
  1924. //call completed callbacks on finished decompositions
  1925. mDecompThread->notifyCompleted();
  1926. if (!mThread->mWaiting)
  1927. { //curl thread is churning, wait for it to go idle
  1928. return;
  1929. }
  1930. static std::string region_name("never name a region this");
  1931. if (gAgent.getRegion())
  1932. { //update capability url
  1933. if (gAgent.getRegion()->getName() != region_name && gAgent.getRegion()->capabilitiesReceived())
  1934. {
  1935. region_name = gAgent.getRegion()->getName();
  1936. mGetMeshCapability = gAgent.getRegion()->getCapability("GetMesh");
  1937. }
  1938. }
  1939. mMeshMutex->lock();
  1940. mThread->mMutex->lock();
  1941. //popup queued error messages from background threads
  1942. while (!mUploadErrorQ.empty())
  1943. {
  1944. LLNotificationsUtil::add("MeshUploadError", mUploadErrorQ.front());
  1945. mUploadErrorQ.pop();
  1946. }
  1947. S32 push_count = LLMeshRepoThread::sMaxConcurrentRequests-(LLMeshRepoThread::sActiveHeaderRequests+LLMeshRepoThread::sActiveLODRequests);
  1948. if (push_count > 0)
  1949. {
  1950. //calculate "score" for pending requests
  1951. //create score map
  1952. std::map<LLUUID, F32> score_map;
  1953. for (U32 i = 0; i < 4; ++i)
  1954. {
  1955. for (mesh_load_map::iterator iter = mLoadingMeshes[i].begin(); iter != mLoadingMeshes[i].end(); ++iter)
  1956. {
  1957. F32 max_score = 0.f;
  1958. for (std::set<LLUUID>::iterator obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter)
  1959. {
  1960. LLViewerObject* object = gObjectList.findObject(*obj_iter);
  1961. if (object)
  1962. {
  1963. LLDrawable* drawable = object->mDrawable;
  1964. if (drawable)
  1965. {
  1966. F32 cur_score = drawable->getRadius()/llmax(drawable->mDistanceWRTCamera, 1.f);
  1967. max_score = llmax(max_score, cur_score);
  1968. }
  1969. }
  1970. }
  1971. score_map[iter->first.getSculptID()] = max_score;
  1972. }
  1973. }
  1974. //set "score" for pending requests
  1975. for (std::vector<LLMeshRepoThread::LODRequest>::iterator iter = mPendingRequests.begin(); iter != mPendingRequests.end(); ++iter)
  1976. {
  1977. iter->mScore = score_map[iter->mMeshParams.getSculptID()];
  1978. }
  1979. //sort by "score"
  1980. std::sort(mPendingRequests.begin(), mPendingRequests.end(), LLMeshRepoThread::CompareScoreGreater());
  1981. while (!mPendingRequests.empty() && push_count > 0)
  1982. {
  1983. LLMeshRepoThread::LODRequest& request = mPendingRequests.front();
  1984. mThread->loadMeshLOD(request.mMeshParams, request.mLOD);
  1985. mPendingRequests.erase(mPendingRequests.begin());
  1986. push_count--;
  1987. }
  1988. }
  1989. //send skin info requests
  1990. while (!mPendingSkinRequests.empty())
  1991. {
  1992. mThread->loadMeshSkinInfo(mPendingSkinRequests.front());
  1993. mPendingSkinRequests.pop();
  1994. }
  1995. //send decomposition requests
  1996. while (!mPendingDecompositionRequests.empty())
  1997. {
  1998. mThread->loadMeshDecomposition(mPendingDecompositionRequests.front());
  1999. mPendingDecompositionRequests.pop();
  2000. }
  2001. //send physics shapes decomposition requests
  2002. while (!mPendingPhysicsShapeRequests.empty())
  2003. {
  2004. mThread->loadMeshPhysicsShape(mPendingPhysicsShapeRequests.front());
  2005. mPendingPhysicsShapeRequests.pop();
  2006. }
  2007. mThread->notifyLoadedMeshes();
  2008. mThread->mMutex->unlock();
  2009. mMeshMutex->unlock();
  2010. mThread->mSignal->signal();
  2011. }
  2012. void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo& info)
  2013. {
  2014. mSkinMap[info.mMeshID] = info;
  2015. skin_load_map::iterator iter = mLoadingSkins.find(info.mMeshID);
  2016. if (iter != mLoadingSkins.end())
  2017. {
  2018. for (std::set<LLUUID>::iterator obj_id = iter->second.begin(); obj_id != iter->second.end(); ++obj_id)
  2019. {
  2020. LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*obj_id);
  2021. if (vobj)
  2022. {
  2023. vobj->notifyMeshLoaded();
  2024. }
  2025. }
  2026. }
  2027. mLoadingSkins.erase(info.mMeshID);
  2028. }
  2029. void LLMeshRepository::notifyDecompositionReceived(LLModel::Decomposition* decomp)
  2030. {
  2031. decomposition_map::iterator iter = mDecompositionMap.find(decomp->mMeshID);
  2032. if (iter == mDecompositionMap.end())
  2033. { //just insert decomp into map
  2034. mDecompositionMap[decomp->mMeshID] = decomp;
  2035. }
  2036. else
  2037. { //merge decomp with existing entry
  2038. iter->second->merge(decomp);
  2039. delete decomp;
  2040. }
  2041. mLoadingDecompositions.erase(decomp->mMeshID);
  2042. }
  2043. void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVolume* volume)
  2044. { //called from main thread
  2045. S32 detail = LLVolumeLODGroup::getVolumeDetailFromScale(volume->getDetail());
  2046. //get list of objects waiting to be notified this mesh is loaded
  2047. mesh_load_map::iterator obj_iter = mLoadingMeshes[detail].find(mesh_params);
  2048. if (volume && obj_iter != mLoadingMeshes[detail].end())
  2049. {
  2050. //make sure target volume is still valid
  2051. if (volume->getNumVolumeFaces() <= 0)
  2052. {
  2053. llwarns << "Mesh loading returned empty volume." << llendl;
  2054. }
  2055. { //update system volume
  2056. LLVolume* sys_volume = LLPrimitive::getVolumeManager()->refVolume(mesh_params, detail);
  2057. if (sys_volume)
  2058. {
  2059. sys_volume->copyVolumeFaces(volume);
  2060. sys_volume->setMeshAssetLoaded(TRUE);
  2061. LLPrimitive::getVolumeManager()->unrefVolume(sys_volume);
  2062. }
  2063. else
  2064. {
  2065. llwarns << "Couldn't find system volume for given mesh." << llendl;
  2066. }
  2067. }
  2068. //notify waiting LLVOVolume instances that their requested mesh is available
  2069. for (std::set<LLUUID>::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter)
  2070. {
  2071. LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*vobj_iter);
  2072. if (vobj)
  2073. {
  2074. vobj->notifyMeshLoaded();
  2075. }
  2076. }
  2077. mLoadingMeshes[detail].erase(mesh_params);
  2078. }
  2079. }
  2080. void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 lod)
  2081. { //called from main thread
  2082. //get list of objects waiting to be notified this mesh is loaded
  2083. mesh_load_map::iterator obj_iter = mLoadingMeshes[lod].find(mesh_params);
  2084. F32 detail = LLVolumeLODGroup::getVolumeScaleFromDetail(lod);
  2085. if (obj_iter != mLoadingMeshes[lod].end())
  2086. {
  2087. for (std::set<LLUUID>::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter)
  2088. {
  2089. LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*vobj_iter);
  2090. if (vobj)
  2091. {
  2092. LLVolume* obj_volume = vobj->getVolume();
  2093. if (obj_volume &&
  2094. obj_volume->getDetail() == detail &&
  2095. obj_volume->getParams() == mesh_params)
  2096. { //should force volume to find most appropriate LOD
  2097. vobj->setVolume(obj_volume->getParams(), lod);
  2098. }
  2099. }
  2100. }
  2101. mLoadingMeshes[lod].erase(mesh_params);
  2102. }
  2103. }
  2104. S32 LLMeshRepository::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
  2105. {
  2106. return mThread->getActualMeshLOD(mesh_params, lod);
  2107. }
  2108. const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj)
  2109. {
  2110. if (mesh_id.notNull())
  2111. {
  2112. skin_map::iterator iter = mSkinMap.find(mesh_id);
  2113. if (iter != mSkinMap.end())
  2114. {
  2115. return &(iter->second);
  2116. }
  2117. //no skin info known about given mesh, try to fetch it
  2118. {
  2119. LLMutexLock lock(mMeshMutex);
  2120. //add volume to list of loading meshes
  2121. skin_load_map::iterator iter = mLoadingSkins.find(mesh_id);
  2122. if (iter == mLoadingSkins.end())
  2123. { //no request pending for this skin info
  2124. mPendingSkinRequests.push(mesh_id);
  2125. }
  2126. mLoadingSkins[mesh_id].insert(requesting_obj->getID());
  2127. }
  2128. }
  2129. return NULL;
  2130. }
  2131. void LLMeshRepository::fetchPhysicsShape(const LLUUID& mesh_id)
  2132. {
  2133. if (mesh_id.notNull())
  2134. {
  2135. LLModel::Decomposition* decomp = NULL;
  2136. decomposition_map::iterator iter = mDecompositionMap.find(mesh_id);
  2137. if (iter != mDecompositionMap.