PageRenderTime 54ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llprimitive/llmodel.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 2456 lines | 1860 code | 442 blank | 154 comment | 345 complexity | 75405adb5eb7de9bfb8475a95d1e2d9d MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llmodel.cpp
  3. * @brief Model handling implementation
  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. #include "linden_common.h"
  27. #include "llmodel.h"
  28. #include "llmemory.h"
  29. #include "llconvexdecomposition.h"
  30. #include "llsdserialize.h"
  31. #include "llvector4a.h"
  32. #if LL_MSVC
  33. #pragma warning (disable : 4263)
  34. #pragma warning (disable : 4264)
  35. #endif
  36. #include "dae.h"
  37. #include "dae/daeErrorHandler.h"
  38. #include "dom/domConstants.h"
  39. #include "dom/domMesh.h"
  40. #if LL_MSVC
  41. #pragma warning (default : 4263)
  42. #pragma warning (default : 4264)
  43. #endif
  44. #ifdef LL_STANDALONE
  45. # include <zlib.h>
  46. #else
  47. # include "zlib/zlib.h"
  48. #endif
  49. std::string model_names[] =
  50. {
  51. "lowest_lod",
  52. "low_lod",
  53. "medium_lod",
  54. "high_lod",
  55. "physics_mesh"
  56. };
  57. const int MODEL_NAMES_LENGTH = sizeof(model_names) / sizeof(std::string);
  58. LLModel::LLModel(LLVolumeParams& params, F32 detail)
  59. : LLVolume(params, detail), mNormalizedScale(1,1,1), mNormalizedTranslation(0,0,0)
  60. , mPelvisOffset( 0.0f ), mStatus(NO_ERRORS)
  61. {
  62. mDecompID = -1;
  63. mLocalID = -1;
  64. }
  65. LLModel::~LLModel()
  66. {
  67. if (mDecompID >= 0)
  68. {
  69. LLConvexDecomposition::getInstance()->deleteDecomposition(mDecompID);
  70. }
  71. }
  72. bool get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S32& tc_offset, S32& norm_offset, S32 &idx_stride,
  73. domSource* &pos_source, domSource* &tc_source, domSource* &norm_source)
  74. {
  75. idx_stride = 0;
  76. for (U32 j = 0; j < inputs.getCount(); ++j)
  77. {
  78. idx_stride = llmax((S32) inputs[j]->getOffset(), idx_stride);
  79. if (strcmp(COMMON_PROFILE_INPUT_VERTEX, inputs[j]->getSemantic()) == 0)
  80. { //found vertex array
  81. const domURIFragmentType& uri = inputs[j]->getSource();
  82. daeElementRef elem = uri.getElement();
  83. domVertices* vertices = (domVertices*) elem.cast();
  84. if ( !vertices )
  85. {
  86. return false;
  87. }
  88. domInputLocal_Array& v_inp = vertices->getInput_array();
  89. for (U32 k = 0; k < v_inp.getCount(); ++k)
  90. {
  91. if (strcmp(COMMON_PROFILE_INPUT_POSITION, v_inp[k]->getSemantic()) == 0)
  92. {
  93. pos_offset = inputs[j]->getOffset();
  94. const domURIFragmentType& uri = v_inp[k]->getSource();
  95. daeElementRef elem = uri.getElement();
  96. pos_source = (domSource*) elem.cast();
  97. }
  98. if (strcmp(COMMON_PROFILE_INPUT_NORMAL, v_inp[k]->getSemantic()) == 0)
  99. {
  100. norm_offset = inputs[j]->getOffset();
  101. const domURIFragmentType& uri = v_inp[k]->getSource();
  102. daeElementRef elem = uri.getElement();
  103. norm_source = (domSource*) elem.cast();
  104. }
  105. }
  106. }
  107. if (strcmp(COMMON_PROFILE_INPUT_NORMAL, inputs[j]->getSemantic()) == 0)
  108. {
  109. //found normal array for this triangle list
  110. norm_offset = inputs[j]->getOffset();
  111. const domURIFragmentType& uri = inputs[j]->getSource();
  112. daeElementRef elem = uri.getElement();
  113. norm_source = (domSource*) elem.cast();
  114. }
  115. else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, inputs[j]->getSemantic()) == 0)
  116. { //found texCoords
  117. tc_offset = inputs[j]->getOffset();
  118. const domURIFragmentType& uri = inputs[j]->getSource();
  119. daeElementRef elem = uri.getElement();
  120. tc_source = (domSource*) elem.cast();
  121. }
  122. }
  123. idx_stride += 1;
  124. return true;
  125. }
  126. LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& face_list, std::vector<std::string>& materials, domTrianglesRef& tri)
  127. {
  128. LLVolumeFace face;
  129. std::vector<LLVolumeFace::VertexData> verts;
  130. std::vector<U16> indices;
  131. const domInputLocalOffset_Array& inputs = tri->getInput_array();
  132. S32 pos_offset = -1;
  133. S32 tc_offset = -1;
  134. S32 norm_offset = -1;
  135. domSource* pos_source = NULL;
  136. domSource* tc_source = NULL;
  137. domSource* norm_source = NULL;
  138. S32 idx_stride = 0;
  139. if ( !get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source) || !pos_source )
  140. {
  141. return LLModel::BAD_ELEMENT;
  142. }
  143. domPRef p = tri->getP();
  144. domListOfUInts& idx = p->getValue();
  145. domListOfFloats dummy ;
  146. domListOfFloats& v = pos_source ? pos_source->getFloat_array()->getValue() : dummy ;
  147. domListOfFloats& tc = tc_source ? tc_source->getFloat_array()->getValue() : dummy ;
  148. domListOfFloats& n = norm_source ? norm_source->getFloat_array()->getValue() : dummy ;
  149. if (pos_source)
  150. {
  151. face.mExtents[0].set(v[0], v[1], v[2]);
  152. face.mExtents[1].set(v[0], v[1], v[2]);
  153. }
  154. LLVolumeFace::VertexMapData::PointMap point_map;
  155. for (U32 i = 0; i < idx.getCount(); i += idx_stride)
  156. {
  157. LLVolumeFace::VertexData cv;
  158. if (pos_source)
  159. {
  160. cv.setPosition(LLVector4a(v[idx[i+pos_offset]*3+0],
  161. v[idx[i+pos_offset]*3+1],
  162. v[idx[i+pos_offset]*3+2]));
  163. }
  164. if (tc_source)
  165. {
  166. cv.mTexCoord.setVec(tc[idx[i+tc_offset]*2+0],
  167. tc[idx[i+tc_offset]*2+1]);
  168. }
  169. if (norm_source)
  170. {
  171. cv.setNormal(LLVector4a(n[idx[i+norm_offset]*3+0],
  172. n[idx[i+norm_offset]*3+1],
  173. n[idx[i+norm_offset]*3+2]));
  174. }
  175. BOOL found = FALSE;
  176. LLVolumeFace::VertexMapData::PointMap::iterator point_iter;
  177. point_iter = point_map.find(LLVector3(cv.getPosition().getF32ptr()));
  178. if (point_iter != point_map.end())
  179. {
  180. for (U32 j = 0; j < point_iter->second.size(); ++j)
  181. {
  182. if ((point_iter->second)[j] == cv)
  183. {
  184. found = TRUE;
  185. indices.push_back((point_iter->second)[j].mIndex);
  186. break;
  187. }
  188. }
  189. }
  190. if (!found)
  191. {
  192. update_min_max(face.mExtents[0], face.mExtents[1], cv.getPosition());
  193. verts.push_back(cv);
  194. if (verts.size() >= 65535)
  195. {
  196. //llerrs << "Attempted to write model exceeding 16-bit index buffer limitation." << llendl;
  197. return LLModel::VERTEX_NUMBER_OVERFLOW ;
  198. }
  199. U16 index = (U16) (verts.size()-1);
  200. indices.push_back(index);
  201. LLVolumeFace::VertexMapData d;
  202. d.setPosition(cv.getPosition());
  203. d.mTexCoord = cv.mTexCoord;
  204. d.setNormal(cv.getNormal());
  205. d.mIndex = index;
  206. if (point_iter != point_map.end())
  207. {
  208. point_iter->second.push_back(d);
  209. }
  210. else
  211. {
  212. point_map[LLVector3(d.getPosition().getF32ptr())].push_back(d);
  213. }
  214. }
  215. if (indices.size()%3 == 0 && verts.size() >= 65532)
  216. {
  217. face_list.push_back(face);
  218. face_list.rbegin()->fillFromLegacyData(verts, indices);
  219. LLVolumeFace& new_face = *face_list.rbegin();
  220. if (!norm_source)
  221. {
  222. ll_aligned_free_16(new_face.mNormals);
  223. new_face.mNormals = NULL;
  224. }
  225. if (!tc_source)
  226. {
  227. ll_aligned_free_16(new_face.mTexCoords);
  228. new_face.mTexCoords = NULL;
  229. }
  230. face = LLVolumeFace();
  231. point_map.clear();
  232. }
  233. }
  234. if (!verts.empty())
  235. {
  236. std::string material;
  237. if (tri->getMaterial())
  238. {
  239. material = std::string(tri->getMaterial());
  240. }
  241. materials.push_back(material);
  242. face_list.push_back(face);
  243. face_list.rbegin()->fillFromLegacyData(verts, indices);
  244. LLVolumeFace& new_face = *face_list.rbegin();
  245. if (!norm_source)
  246. {
  247. ll_aligned_free_16(new_face.mNormals);
  248. new_face.mNormals = NULL;
  249. }
  250. if (!tc_source)
  251. {
  252. ll_aligned_free_16(new_face.mTexCoords);
  253. new_face.mTexCoords = NULL;
  254. }
  255. }
  256. return LLModel::NO_ERRORS ;
  257. }
  258. LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& face_list, std::vector<std::string>& materials, domPolylistRef& poly)
  259. {
  260. domPRef p = poly->getP();
  261. domListOfUInts& idx = p->getValue();
  262. if (idx.getCount() == 0)
  263. {
  264. return LLModel::NO_ERRORS ;
  265. }
  266. const domInputLocalOffset_Array& inputs = poly->getInput_array();
  267. domListOfUInts& vcount = poly->getVcount()->getValue();
  268. S32 pos_offset = -1;
  269. S32 tc_offset = -1;
  270. S32 norm_offset = -1;
  271. domSource* pos_source = NULL;
  272. domSource* tc_source = NULL;
  273. domSource* norm_source = NULL;
  274. S32 idx_stride = 0;
  275. if (!get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source))
  276. {
  277. return LLModel::BAD_ELEMENT;
  278. }
  279. LLVolumeFace face;
  280. std::vector<U16> indices;
  281. std::vector<LLVolumeFace::VertexData> verts;
  282. domListOfFloats v;
  283. domListOfFloats tc;
  284. domListOfFloats n;
  285. if (pos_source)
  286. {
  287. v = pos_source->getFloat_array()->getValue();
  288. face.mExtents[0].set(v[0], v[1], v[2]);
  289. face.mExtents[1].set(v[0], v[1], v[2]);
  290. }
  291. if (tc_source)
  292. {
  293. tc = tc_source->getFloat_array()->getValue();
  294. }
  295. if (norm_source)
  296. {
  297. n = norm_source->getFloat_array()->getValue();
  298. }
  299. LLVolumeFace::VertexMapData::PointMap point_map;
  300. U32 cur_idx = 0;
  301. for (U32 i = 0; i < vcount.getCount(); ++i)
  302. { //for each polygon
  303. U32 first_index = 0;
  304. U32 last_index = 0;
  305. for (U32 j = 0; j < vcount[i]; ++j)
  306. { //for each vertex
  307. LLVolumeFace::VertexData cv;
  308. if (pos_source)
  309. {
  310. cv.getPosition().set(v[idx[cur_idx+pos_offset]*3+0],
  311. v[idx[cur_idx+pos_offset]*3+1],
  312. v[idx[cur_idx+pos_offset]*3+2]);
  313. }
  314. if (tc_source)
  315. {
  316. cv.mTexCoord.setVec(tc[idx[cur_idx+tc_offset]*2+0],
  317. tc[idx[cur_idx+tc_offset]*2+1]);
  318. }
  319. if (norm_source)
  320. {
  321. cv.getNormal().set(n[idx[cur_idx+norm_offset]*3+0],
  322. n[idx[cur_idx+norm_offset]*3+1],
  323. n[idx[cur_idx+norm_offset]*3+2]);
  324. }
  325. cur_idx += idx_stride;
  326. BOOL found = FALSE;
  327. LLVolumeFace::VertexMapData::PointMap::iterator point_iter;
  328. LLVector3 pos3(cv.getPosition().getF32ptr());
  329. point_iter = point_map.find(pos3);
  330. if (point_iter != point_map.end())
  331. {
  332. for (U32 k = 0; k < point_iter->second.size(); ++k)
  333. {
  334. if ((point_iter->second)[k] == cv)
  335. {
  336. found = TRUE;
  337. U32 index = (point_iter->second)[k].mIndex;
  338. if (j == 0)
  339. {
  340. first_index = index;
  341. }
  342. else if (j == 1)
  343. {
  344. last_index = index;
  345. }
  346. else
  347. {
  348. indices.push_back(first_index);
  349. indices.push_back(last_index);
  350. indices.push_back(index);
  351. last_index = index;
  352. }
  353. break;
  354. }
  355. }
  356. }
  357. if (!found)
  358. {
  359. update_min_max(face.mExtents[0], face.mExtents[1], cv.getPosition());
  360. verts.push_back(cv);
  361. if (verts.size() >= 65535)
  362. {
  363. //llerrs << "Attempted to write model exceeding 16-bit index buffer limitation." << llendl;
  364. return LLModel::VERTEX_NUMBER_OVERFLOW ;
  365. }
  366. U16 index = (U16) (verts.size()-1);
  367. if (j == 0)
  368. {
  369. first_index = index;
  370. }
  371. else if (j == 1)
  372. {
  373. last_index = index;
  374. }
  375. else
  376. {
  377. indices.push_back(first_index);
  378. indices.push_back(last_index);
  379. indices.push_back(index);
  380. last_index = index;
  381. }
  382. LLVolumeFace::VertexMapData d;
  383. d.setPosition(cv.getPosition());
  384. d.mTexCoord = cv.mTexCoord;
  385. d.setNormal(cv.getNormal());
  386. d.mIndex = index;
  387. if (point_iter != point_map.end())
  388. {
  389. point_iter->second.push_back(d);
  390. }
  391. else
  392. {
  393. point_map[pos3].push_back(d);
  394. }
  395. }
  396. if (indices.size()%3 == 0 && indices.size() >= 65532)
  397. {
  398. face_list.push_back(face);
  399. face_list.rbegin()->fillFromLegacyData(verts, indices);
  400. LLVolumeFace& new_face = *face_list.rbegin();
  401. if (!norm_source)
  402. {
  403. ll_aligned_free_16(new_face.mNormals);
  404. new_face.mNormals = NULL;
  405. }
  406. if (!tc_source)
  407. {
  408. ll_aligned_free_16(new_face.mTexCoords);
  409. new_face.mTexCoords = NULL;
  410. }
  411. face = LLVolumeFace();
  412. verts.clear();
  413. indices.clear();
  414. point_map.clear();
  415. }
  416. }
  417. }
  418. if (!verts.empty())
  419. {
  420. std::string material;
  421. if (poly->getMaterial())
  422. {
  423. material = std::string(poly->getMaterial());
  424. }
  425. materials.push_back(material);
  426. face_list.push_back(face);
  427. face_list.rbegin()->fillFromLegacyData(verts, indices);
  428. LLVolumeFace& new_face = *face_list.rbegin();
  429. if (!norm_source)
  430. {
  431. ll_aligned_free_16(new_face.mNormals);
  432. new_face.mNormals = NULL;
  433. }
  434. if (!tc_source)
  435. {
  436. ll_aligned_free_16(new_face.mTexCoords);
  437. new_face.mTexCoords = NULL;
  438. }
  439. }
  440. return LLModel::NO_ERRORS ;
  441. }
  442. LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& face_list, std::vector<std::string>& materials, domPolygonsRef& poly)
  443. {
  444. LLVolumeFace face;
  445. std::vector<U16> indices;
  446. std::vector<LLVolumeFace::VertexData> verts;
  447. const domInputLocalOffset_Array& inputs = poly->getInput_array();
  448. S32 v_offset = -1;
  449. S32 n_offset = -1;
  450. S32 t_offset = -1;
  451. domListOfFloats* v = NULL;
  452. domListOfFloats* n = NULL;
  453. domListOfFloats* t = NULL;
  454. U32 stride = 0;
  455. for (U32 i = 0; i < inputs.getCount(); ++i)
  456. {
  457. stride = llmax((U32) inputs[i]->getOffset()+1, stride);
  458. if (strcmp(COMMON_PROFILE_INPUT_VERTEX, inputs[i]->getSemantic()) == 0)
  459. { //found vertex array
  460. v_offset = inputs[i]->getOffset();
  461. const domURIFragmentType& uri = inputs[i]->getSource();
  462. daeElementRef elem = uri.getElement();
  463. domVertices* vertices = (domVertices*) elem.cast();
  464. if (!vertices)
  465. {
  466. return LLModel::BAD_ELEMENT;
  467. }
  468. domInputLocal_Array& v_inp = vertices->getInput_array();
  469. for (U32 k = 0; k < v_inp.getCount(); ++k)
  470. {
  471. if (strcmp(COMMON_PROFILE_INPUT_POSITION, v_inp[k]->getSemantic()) == 0)
  472. {
  473. const domURIFragmentType& uri = v_inp[k]->getSource();
  474. daeElementRef elem = uri.getElement();
  475. domSource* src = (domSource*) elem.cast();
  476. if (!src)
  477. {
  478. return LLModel::BAD_ELEMENT;
  479. }
  480. v = &(src->getFloat_array()->getValue());
  481. }
  482. }
  483. }
  484. else if (strcmp(COMMON_PROFILE_INPUT_NORMAL, inputs[i]->getSemantic()) == 0)
  485. {
  486. n_offset = inputs[i]->getOffset();
  487. //found normal array for this triangle list
  488. const domURIFragmentType& uri = inputs[i]->getSource();
  489. daeElementRef elem = uri.getElement();
  490. domSource* src = (domSource*) elem.cast();
  491. if (!src)
  492. {
  493. return LLModel::BAD_ELEMENT;
  494. }
  495. n = &(src->getFloat_array()->getValue());
  496. }
  497. else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, inputs[i]->getSemantic()) == 0 && inputs[i]->getSet() == 0)
  498. { //found texCoords
  499. t_offset = inputs[i]->getOffset();
  500. const domURIFragmentType& uri = inputs[i]->getSource();
  501. daeElementRef elem = uri.getElement();
  502. domSource* src = (domSource*) elem.cast();
  503. if (!src)
  504. {
  505. return LLModel::BAD_ELEMENT;
  506. }
  507. t = &(src->getFloat_array()->getValue());
  508. }
  509. }
  510. domP_Array& ps = poly->getP_array();
  511. //make a triangle list in <verts>
  512. for (U32 i = 0; i < ps.getCount(); ++i)
  513. { //for each polygon
  514. domListOfUInts& idx = ps[i]->getValue();
  515. for (U32 j = 0; j < idx.getCount()/stride; ++j)
  516. { //for each vertex
  517. if (j > 2)
  518. {
  519. U32 size = verts.size();
  520. LLVolumeFace::VertexData v0 = verts[size-3];
  521. LLVolumeFace::VertexData v1 = verts[size-1];
  522. verts.push_back(v0);
  523. verts.push_back(v1);
  524. }
  525. LLVolumeFace::VertexData vert;
  526. if (v)
  527. {
  528. U32 v_idx = idx[j*stride+v_offset]*3;
  529. vert.getPosition().set(v->get(v_idx),
  530. v->get(v_idx+1),
  531. v->get(v_idx+2));
  532. }
  533. if (n)
  534. {
  535. U32 n_idx = idx[j*stride+n_offset]*3;
  536. vert.getNormal().set(n->get(n_idx),
  537. n->get(n_idx+1),
  538. n->get(n_idx+2));
  539. }
  540. if (t)
  541. {
  542. U32 t_idx = idx[j*stride+t_offset]*2;
  543. vert.mTexCoord.setVec(t->get(t_idx),
  544. t->get(t_idx+1));
  545. }
  546. verts.push_back(vert);
  547. }
  548. }
  549. if (verts.empty())
  550. {
  551. return LLModel::NO_ERRORS;
  552. }
  553. face.mExtents[0] = verts[0].getPosition();
  554. face.mExtents[1] = verts[0].getPosition();
  555. //create a map of unique vertices to indices
  556. std::map<LLVolumeFace::VertexData, U32> vert_idx;
  557. U32 cur_idx = 0;
  558. for (U32 i = 0; i < verts.size(); ++i)
  559. {
  560. std::map<LLVolumeFace::VertexData, U32>::iterator iter = vert_idx.find(verts[i]);
  561. if (iter == vert_idx.end())
  562. {
  563. vert_idx[verts[i]] = cur_idx++;
  564. }
  565. }
  566. //build vertex array from map
  567. std::vector<LLVolumeFace::VertexData> new_verts;
  568. new_verts.resize(vert_idx.size());
  569. for (std::map<LLVolumeFace::VertexData, U32>::iterator iter = vert_idx.begin(); iter != vert_idx.end(); ++iter)
  570. {
  571. new_verts[iter->second] = iter->first;
  572. update_min_max(face.mExtents[0], face.mExtents[1], iter->first.getPosition());
  573. }
  574. //build index array from map
  575. indices.resize(verts.size());
  576. for (U32 i = 0; i < verts.size(); ++i)
  577. {
  578. indices[i] = vert_idx[verts[i]];
  579. }
  580. // DEBUG just build an expanded triangle list
  581. /*for (U32 i = 0; i < verts.size(); ++i)
  582. {
  583. indices.push_back((U16) i);
  584. update_min_max(face.mExtents[0], face.mExtents[1], verts[i].getPosition());
  585. }*/
  586. if (!new_verts.empty())
  587. {
  588. std::string material;
  589. if (poly->getMaterial())
  590. {
  591. material = std::string(poly->getMaterial());
  592. }
  593. materials.push_back(material);
  594. face_list.push_back(face);
  595. face_list.rbegin()->fillFromLegacyData(new_verts, indices);
  596. LLVolumeFace& new_face = *face_list.rbegin();
  597. if (!n)
  598. {
  599. ll_aligned_free_16(new_face.mNormals);
  600. new_face.mNormals = NULL;
  601. }
  602. if (!t)
  603. {
  604. ll_aligned_free_16(new_face.mTexCoords);
  605. new_face.mTexCoords = NULL;
  606. }
  607. }
  608. return LLModel::NO_ERRORS ;
  609. }
  610. //static
  611. std::string LLModel::getStatusString(U32 status)
  612. {
  613. const static std::string status_strings[(S32)INVALID_STATUS] = {"status_no_error", "status_vertex_number_overflow","bad_element"};
  614. if(status < INVALID_STATUS)
  615. {
  616. if(status_strings[status] == std::string())
  617. {
  618. llerrs << "No valid status string for this status: " << (U32)status << llendl ;
  619. }
  620. return status_strings[status] ;
  621. }
  622. llerrs << "Invalid model status: " << (U32)status << llendl ;
  623. return std::string() ;
  624. }
  625. void LLModel::addVolumeFacesFromDomMesh(domMesh* mesh)
  626. {
  627. domTriangles_Array& tris = mesh->getTriangles_array();
  628. for (U32 i = 0; i < tris.getCount(); ++i)
  629. {
  630. domTrianglesRef& tri = tris.get(i);
  631. mStatus = load_face_from_dom_triangles(mVolumeFaces, mMaterialList, tri);
  632. if(mStatus != NO_ERRORS)
  633. {
  634. mVolumeFaces.clear() ;
  635. mMaterialList.clear() ;
  636. return ; //abort
  637. }
  638. }
  639. domPolylist_Array& polys = mesh->getPolylist_array();
  640. for (U32 i = 0; i < polys.getCount(); ++i)
  641. {
  642. domPolylistRef& poly = polys.get(i);
  643. mStatus = load_face_from_dom_polylist(mVolumeFaces, mMaterialList, poly);
  644. if(mStatus != NO_ERRORS)
  645. {
  646. mVolumeFaces.clear() ;
  647. mMaterialList.clear() ;
  648. return ; //abort
  649. }
  650. }
  651. domPolygons_Array& polygons = mesh->getPolygons_array();
  652. for (U32 i = 0; i < polygons.getCount(); ++i)
  653. {
  654. domPolygonsRef& poly = polygons.get(i);
  655. mStatus = load_face_from_dom_polygons(mVolumeFaces, mMaterialList, poly);
  656. if(mStatus != NO_ERRORS)
  657. {
  658. mVolumeFaces.clear() ;
  659. mMaterialList.clear() ;
  660. return ; //abort
  661. }
  662. }
  663. }
  664. BOOL LLModel::createVolumeFacesFromDomMesh(domMesh* mesh)
  665. {
  666. if (mesh)
  667. {
  668. mVolumeFaces.clear();
  669. mMaterialList.clear();
  670. addVolumeFacesFromDomMesh(mesh);
  671. if (getNumVolumeFaces() > 0)
  672. {
  673. normalizeVolumeFaces();
  674. optimizeVolumeFaces();
  675. if (getNumVolumeFaces() > 0)
  676. {
  677. return TRUE;
  678. }
  679. }
  680. }
  681. else
  682. {
  683. llwarns << "no mesh found" << llendl;
  684. }
  685. return FALSE;
  686. }
  687. void LLModel::offsetMesh( const LLVector3& pivotPoint )
  688. {
  689. LLVector4a pivot( pivotPoint[VX], pivotPoint[VY], pivotPoint[VZ] );
  690. for (std::vector<LLVolumeFace>::iterator faceIt = mVolumeFaces.begin(); faceIt != mVolumeFaces.end(); )
  691. {
  692. std::vector<LLVolumeFace>:: iterator currentFaceIt = faceIt++;
  693. LLVolumeFace& face = *currentFaceIt;
  694. LLVector4a *pos = (LLVector4a*) face.mPositions;
  695. for (U32 i=0; i<face.mNumVertices; ++i )
  696. {
  697. pos[i].add( pivot );
  698. }
  699. }
  700. }
  701. void LLModel::optimizeVolumeFaces()
  702. {
  703. for (U32 i = 0; i < getNumVolumeFaces(); ++i)
  704. {
  705. mVolumeFaces[i].optimize();
  706. }
  707. }
  708. // Shrink the model to fit
  709. // on a 1x1x1 cube centered at the origin.
  710. // The positions and extents
  711. // multiplied by mNormalizedScale
  712. // and offset by mNormalizedTranslation
  713. // to be the "original" extents and position.
  714. // Also, the positions will fit
  715. // within the unit cube.
  716. void LLModel::normalizeVolumeFaces()
  717. {
  718. // ensure we don't have too many faces
  719. if (mVolumeFaces.size() > LL_SCULPT_MESH_MAX_FACES)
  720. mVolumeFaces.resize(LL_SCULPT_MESH_MAX_FACES);
  721. if (!mVolumeFaces.empty())
  722. {
  723. LLVector4a min, max;
  724. // For all of the volume faces
  725. // in the model, loop over
  726. // them and see what the extents
  727. // of the volume along each axis.
  728. min = mVolumeFaces[0].mExtents[0];
  729. max = mVolumeFaces[0].mExtents[1];
  730. for (U32 i = 1; i < mVolumeFaces.size(); ++i)
  731. {
  732. LLVolumeFace& face = mVolumeFaces[i];
  733. update_min_max(min, max, face.mExtents[0]);
  734. update_min_max(min, max, face.mExtents[1]);
  735. if (face.mTexCoords)
  736. {
  737. LLVector2& min_tc = face.mTexCoordExtents[0];
  738. LLVector2& max_tc = face.mTexCoordExtents[1];
  739. min_tc = face.mTexCoords[0];
  740. max_tc = face.mTexCoords[0];
  741. for (U32 j = 1; j < face.mNumVertices; ++j)
  742. {
  743. update_min_max(min_tc, max_tc, face.mTexCoords[j]);
  744. }
  745. }
  746. else
  747. {
  748. face.mTexCoordExtents[0].set(0,0);
  749. face.mTexCoordExtents[1].set(1,1);
  750. }
  751. }
  752. // Now that we have the extents of the model
  753. // we can compute the offset needed to center
  754. // the model at the origin.
  755. // Compute center of the model
  756. // and make it negative to get translation
  757. // needed to center at origin.
  758. LLVector4a trans;
  759. trans.setAdd(min, max);
  760. trans.mul(-0.5f);
  761. // Compute the total size along all
  762. // axes of the model.
  763. LLVector4a size;
  764. size.setSub(max, min);
  765. // Prevent division by zero.
  766. F32 x = size[0];
  767. F32 y = size[1];
  768. F32 z = size[2];
  769. F32 w = size[3];
  770. if (fabs(x)<F_APPROXIMATELY_ZERO)
  771. {
  772. x = 1.0;
  773. }
  774. if (fabs(y)<F_APPROXIMATELY_ZERO)
  775. {
  776. y = 1.0;
  777. }
  778. if (fabs(z)<F_APPROXIMATELY_ZERO)
  779. {
  780. z = 1.0;
  781. }
  782. size.set(x,y,z,w);
  783. // Compute scale as reciprocal of size
  784. LLVector4a scale;
  785. scale.splat(1.f);
  786. scale.div(size);
  787. LLVector4a inv_scale(1.f);
  788. inv_scale.div(scale);
  789. for (U32 i = 0; i < mVolumeFaces.size(); ++i)
  790. {
  791. LLVolumeFace& face = mVolumeFaces[i];
  792. // We shrink the extents so
  793. // that they fall within
  794. // the unit cube.
  795. face.mExtents[0].add(trans);
  796. face.mExtents[0].mul(scale);
  797. face.mExtents[1].add(trans);
  798. face.mExtents[1].mul(scale);
  799. // For all the positions, we scale
  800. // the positions to fit within the unit cube.
  801. LLVector4a* pos = (LLVector4a*) face.mPositions;
  802. LLVector4a* norm = (LLVector4a*) face.mNormals;
  803. for (U32 j = 0; j < face.mNumVertices; ++j)
  804. {
  805. pos[j].add(trans);
  806. pos[j].mul(scale);
  807. if (norm && !norm[j].equals3(LLVector4a::getZero()))
  808. {
  809. norm[j].mul(inv_scale);
  810. norm[j].normalize3();
  811. }
  812. }
  813. }
  814. // mNormalizedScale is the scale at which
  815. // we would need to multiply the model
  816. // by to get the original size of the
  817. // model instead of the normalized size.
  818. LLVector4a normalized_scale;
  819. normalized_scale.splat(1.f);
  820. normalized_scale.div(scale);
  821. mNormalizedScale.set(normalized_scale.getF32ptr());
  822. mNormalizedTranslation.set(trans.getF32ptr());
  823. mNormalizedTranslation *= -1.f;
  824. }
  825. }
  826. void LLModel::getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& translation_out)
  827. {
  828. scale_out = mNormalizedScale;
  829. translation_out = mNormalizedTranslation;
  830. }
  831. void LLModel::setNumVolumeFaces(S32 count)
  832. {
  833. mVolumeFaces.resize(count);
  834. }
  835. void LLModel::setVolumeFaceData(
  836. S32 f,
  837. LLStrider<LLVector3> pos,
  838. LLStrider<LLVector3> norm,
  839. LLStrider<LLVector2> tc,
  840. LLStrider<U16> ind,
  841. U32 num_verts,
  842. U32 num_indices)
  843. {
  844. LLVolumeFace& face = mVolumeFaces[f];
  845. face.resizeVertices(num_verts);
  846. face.resizeIndices(num_indices);
  847. LLVector4a::memcpyNonAliased16((F32*) face.mPositions, (F32*) pos.get(), num_verts*4*sizeof(F32));
  848. if (norm.get())
  849. {
  850. LLVector4a::memcpyNonAliased16((F32*) face.mNormals, (F32*) norm.get(), num_verts*4*sizeof(F32));
  851. }
  852. else
  853. {
  854. ll_aligned_free_16(face.mNormals);
  855. face.mNormals = NULL;
  856. }
  857. if (tc.get())
  858. {
  859. LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), num_verts*2*sizeof(F32));
  860. }
  861. else
  862. {
  863. ll_aligned_free_16(face.mTexCoords);
  864. face.mTexCoords = NULL;
  865. }
  866. U32 size = (num_indices*2+0xF)&~0xF;
  867. LLVector4a::memcpyNonAliased16((F32*) face.mIndices, (F32*) ind.get(), size);
  868. }
  869. void LLModel::appendFaces(LLModel *model, LLMatrix4 &transform, LLMatrix4& norm_mat)
  870. {
  871. if (mVolumeFaces.empty())
  872. {
  873. setNumVolumeFaces(1);
  874. }
  875. LLVolumeFace& face = mVolumeFaces[mVolumeFaces.size()-1];
  876. for (S32 i = 0; i < model->getNumFaces(); ++i)
  877. {
  878. face.appendFace(model->getVolumeFace(i), transform, norm_mat);
  879. }
  880. }
  881. void LLModel::appendFace(const LLVolumeFace& src_face, std::string src_material, LLMatrix4& mat, LLMatrix4& norm_mat)
  882. {
  883. S32 rindex = getNumVolumeFaces()-1;
  884. if (rindex == -1 ||
  885. mVolumeFaces[rindex].mNumVertices + src_face.mNumVertices >= 65536)
  886. { //empty or overflow will occur, append new face
  887. LLVolumeFace cur_face;
  888. cur_face.appendFace(src_face, mat, norm_mat);
  889. addFace(cur_face);
  890. mMaterialList.push_back(src_material);
  891. }
  892. else
  893. { //append to existing end face
  894. mVolumeFaces.rbegin()->appendFace(src_face, mat, norm_mat);
  895. }
  896. }
  897. void LLModel::addFace(const LLVolumeFace& face)
  898. {
  899. if (face.mNumVertices == 0)
  900. {
  901. llerrs << "Cannot add empty face." << llendl;
  902. }
  903. mVolumeFaces.push_back(face);
  904. if (mVolumeFaces.size() > MAX_MODEL_FACES)
  905. {
  906. llerrs << "Model prims cannot have more than " << MAX_MODEL_FACES << " faces!" << llendl;
  907. }
  908. }
  909. void LLModel::generateNormals(F32 angle_cutoff)
  910. {
  911. //generate normals for all faces by:
  912. // 1 - Create faceted copy of face with no texture coordinates
  913. // 2 - Weld vertices in faceted copy that are shared between triangles with less than "angle_cutoff" difference between normals
  914. // 3 - Generate smoothed set of normals based on welding results
  915. // 4 - Create faceted copy of face with texture coordinates
  916. // 5 - Copy smoothed normals to faceted copy, using closest normal to triangle normal where more than one normal exists for a given position
  917. // 6 - Remove redundant vertices from new faceted (now smooth) copy
  918. angle_cutoff = cosf(angle_cutoff);
  919. for (U32 j = 0; j < mVolumeFaces.size(); ++j)
  920. {
  921. LLVolumeFace& vol_face = mVolumeFaces[j];
  922. if (vol_face.mNumIndices > 65535)
  923. {
  924. llwarns << "Too many vertices for normal generation to work." << llendl;
  925. continue;
  926. }
  927. //create faceted copy of current face with no texture coordinates (step 1)
  928. LLVolumeFace faceted;
  929. LLVector4a* src_pos = (LLVector4a*) vol_face.mPositions;
  930. //LLVector4a* src_norm = (LLVector4a*) vol_face.mNormals;
  931. faceted.resizeVertices(vol_face.mNumIndices);
  932. faceted.resizeIndices(vol_face.mNumIndices);
  933. //bake out triangles into temporary face, clearing texture coordinates
  934. for (U32 i = 0; i < vol_face.mNumIndices; ++i)
  935. {
  936. U32 idx = vol_face.mIndices[i];
  937. faceted.mPositions[i] = src_pos[idx];
  938. faceted.mTexCoords[i] = LLVector2(0,0);
  939. faceted.mIndices[i] = i;
  940. }
  941. //generate normals for temporary face
  942. for (U32 i = 0; i < faceted.mNumIndices; i += 3)
  943. { //for each triangle
  944. U16 i0 = faceted.mIndices[i+0];
  945. U16 i1 = faceted.mIndices[i+1];
  946. U16 i2 = faceted.mIndices[i+2];
  947. LLVector4a& p0 = faceted.mPositions[i0];
  948. LLVector4a& p1 = faceted.mPositions[i1];
  949. LLVector4a& p2 = faceted.mPositions[i2];
  950. LLVector4a& n0 = faceted.mNormals[i0];
  951. LLVector4a& n1 = faceted.mNormals[i1];
  952. LLVector4a& n2 = faceted.mNormals[i2];
  953. LLVector4a lhs, rhs;
  954. lhs.setSub(p1, p0);
  955. rhs.setSub(p2, p0);
  956. n0.setCross3(lhs, rhs);
  957. n0.normalize3();
  958. n1 = n0;
  959. n2 = n0;
  960. }
  961. //weld vertices in temporary face, respecting angle_cutoff (step 2)
  962. faceted.optimize(angle_cutoff);
  963. //generate normals for welded face based on new topology (step 3)
  964. for (U32 i = 0; i < faceted.mNumVertices; i++)
  965. {
  966. faceted.mNormals[i].clear();
  967. }
  968. for (U32 i = 0; i < faceted.mNumIndices; i += 3)
  969. { //for each triangle
  970. U16 i0 = faceted.mIndices[i+0];
  971. U16 i1 = faceted.mIndices[i+1];
  972. U16 i2 = faceted.mIndices[i+2];
  973. LLVector4a& p0 = faceted.mPositions[i0];
  974. LLVector4a& p1 = faceted.mPositions[i1];
  975. LLVector4a& p2 = faceted.mPositions[i2];
  976. LLVector4a& n0 = faceted.mNormals[i0];
  977. LLVector4a& n1 = faceted.mNormals[i1];
  978. LLVector4a& n2 = faceted.mNormals[i2];
  979. LLVector4a lhs, rhs;
  980. lhs.setSub(p1, p0);
  981. rhs.setSub(p2, p0);
  982. LLVector4a n;
  983. n.setCross3(lhs, rhs);
  984. n0.add(n);
  985. n1.add(n);
  986. n2.add(n);
  987. }
  988. //normalize normals and build point map
  989. LLVolumeFace::VertexMapData::PointMap point_map;
  990. for (U32 i = 0; i < faceted.mNumVertices; ++i)
  991. {
  992. faceted.mNormals[i].normalize3();
  993. LLVolumeFace::VertexMapData v;
  994. v.setPosition(faceted.mPositions[i]);
  995. v.setNormal(faceted.mNormals[i]);
  996. point_map[LLVector3(v.getPosition().getF32ptr())].push_back(v);
  997. }
  998. //create faceted copy of current face with texture coordinates (step 4)
  999. LLVolumeFace new_face;
  1000. //bake out triangles into new face
  1001. new_face.resizeIndices(vol_face.mNumIndices);
  1002. new_face.resizeVertices(vol_face.mNumIndices);
  1003. for (U32 i = 0; i < vol_face.mNumIndices; ++i)
  1004. {
  1005. U32 idx = vol_face.mIndices[i];
  1006. LLVolumeFace::VertexData v;
  1007. new_face.mPositions[i] = vol_face.mPositions[idx];
  1008. new_face.mNormals[i].clear();
  1009. new_face.mIndices[i] = i;
  1010. }
  1011. if (vol_face.mTexCoords)
  1012. {
  1013. for (U32 i = 0; i < vol_face.mNumIndices; i++)
  1014. {
  1015. U32 idx = vol_face.mIndices[i];
  1016. new_face.mTexCoords[i] = vol_face.mTexCoords[idx];
  1017. }
  1018. }
  1019. else
  1020. {
  1021. ll_aligned_free_16(new_face.mTexCoords);
  1022. new_face.mTexCoords = NULL;
  1023. }
  1024. //generate normals for new face
  1025. for (U32 i = 0; i < new_face.mNumIndices; i += 3)
  1026. { //for each triangle
  1027. U16 i0 = new_face.mIndices[i+0];
  1028. U16 i1 = new_face.mIndices[i+1];
  1029. U16 i2 = new_face.mIndices[i+2];
  1030. LLVector4a& p0 = new_face.mPositions[i0];
  1031. LLVector4a& p1 = new_face.mPositions[i1];
  1032. LLVector4a& p2 = new_face.mPositions[i2];
  1033. LLVector4a& n0 = new_face.mNormals[i0];
  1034. LLVector4a& n1 = new_face.mNormals[i1];
  1035. LLVector4a& n2 = new_face.mNormals[i2];
  1036. LLVector4a lhs, rhs;
  1037. lhs.setSub(p1, p0);
  1038. rhs.setSub(p2, p0);
  1039. n0.setCross3(lhs, rhs);
  1040. n0.normalize3();
  1041. n1 = n0;
  1042. n2 = n0;
  1043. }
  1044. //swap out normals in new_face with best match from point map (step 5)
  1045. for (U32 i = 0; i < new_face.mNumVertices; ++i)
  1046. {
  1047. //LLVolumeFace::VertexData v = new_face.mVertices[i];
  1048. LLVector4a ref_norm = new_face.mNormals[i];
  1049. LLVolumeFace::VertexMapData::PointMap::iterator iter = point_map.find(LLVector3(new_face.mPositions[i].getF32ptr()));
  1050. if (iter != point_map.end())
  1051. {
  1052. F32 best = -2.f;
  1053. for (U32 k = 0; k < iter->second.size(); ++k)
  1054. {
  1055. LLVector4a& n = iter->second[k].getNormal();
  1056. F32 cur = n.dot3(ref_norm).getF32();
  1057. if (cur > best)
  1058. {
  1059. best = cur;
  1060. new_face.mNormals[i] = n;
  1061. }
  1062. }
  1063. }
  1064. }
  1065. //remove redundant vertices from new face (step 6)
  1066. new_face.optimize();
  1067. mVolumeFaces[j] = new_face;
  1068. }
  1069. }
  1070. //static
  1071. std::string LLModel::getElementLabel(daeElement *element)
  1072. { // try to get a decent label for this element
  1073. // if we have a name attribute, use it
  1074. std::string name = element->getAttribute("name");
  1075. if (name.length())
  1076. {
  1077. return name;
  1078. }
  1079. // if we have an ID attribute, use it
  1080. if (element->getID())
  1081. {
  1082. return std::string(element->getID());
  1083. }
  1084. // if we have a parent, use it
  1085. daeElement* parent = element->getParent();
  1086. if (parent)
  1087. {
  1088. // if parent has a name, use it
  1089. std::string name = parent->getAttribute("name");
  1090. if (name.length())
  1091. {
  1092. return name;
  1093. }
  1094. // if parent has an ID, use it
  1095. if (parent->getID())
  1096. {
  1097. return std::string(parent->getID());
  1098. }
  1099. }
  1100. // try to use our type
  1101. daeString element_name = element->getElementName();
  1102. if (element_name)
  1103. {
  1104. return std::string(element_name);
  1105. }
  1106. // if all else fails, use "object"
  1107. return std::string("object");
  1108. }
  1109. //static
  1110. LLModel* LLModel::loadModelFromDomMesh(domMesh *mesh)
  1111. {
  1112. LLVolumeParams volume_params;
  1113. volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
  1114. LLModel* ret = new LLModel(volume_params, 0.f);
  1115. ret->createVolumeFacesFromDomMesh(mesh);
  1116. ret->mLabel = getElementLabel(mesh);
  1117. return ret;
  1118. }
  1119. std::string LLModel::getName() const
  1120. {
  1121. if (!mRequestedLabel.empty())
  1122. return mRequestedLabel;
  1123. else
  1124. return mLabel;
  1125. }
  1126. //static
  1127. LLSD LLModel::writeModel(
  1128. std::ostream& ostr,
  1129. LLModel* physics,
  1130. LLModel* high,
  1131. LLModel* medium,
  1132. LLModel* low,
  1133. LLModel* impostor,
  1134. const LLModel::Decomposition& decomp,
  1135. BOOL upload_skin,
  1136. BOOL upload_joints,
  1137. BOOL nowrite,
  1138. BOOL as_slm)
  1139. {
  1140. LLSD mdl;
  1141. LLModel* model[] =
  1142. {
  1143. impostor,
  1144. low,
  1145. medium,
  1146. high,
  1147. physics
  1148. };
  1149. bool skinning = upload_skin && high && !high->mSkinWeights.empty();
  1150. if (skinning)
  1151. { //write skinning block
  1152. mdl["skin"] = high->mSkinInfo.asLLSD(upload_joints);
  1153. }
  1154. if (!decomp.mBaseHull.empty() ||
  1155. !decomp.mHull.empty())
  1156. {
  1157. mdl["physics_convex"] = decomp.asLLSD();
  1158. if (!decomp.mHull.empty() && !as_slm)
  1159. { //convex decomposition exists, physics mesh will not be used (unless this is an slm file)
  1160. model[LLModel::LOD_PHYSICS] = NULL;
  1161. }
  1162. }
  1163. if (as_slm)
  1164. { //save material list names
  1165. for (U32 i = 0; i < high->mMaterialList.size(); ++i)
  1166. {
  1167. mdl["material_list"][i] = high->mMaterialList[i];
  1168. }
  1169. }
  1170. for (U32 idx = 0; idx < MODEL_NAMES_LENGTH; ++idx)
  1171. {
  1172. if (model[idx] && model[idx]->getNumVolumeFaces() > 0)
  1173. {
  1174. LLVector3 min_pos = LLVector3(model[idx]->getVolumeFace(0).mPositions[0].getF32ptr());
  1175. LLVector3 max_pos = min_pos;
  1176. //find position domain
  1177. for (S32 i = 0; i < model[idx]->getNumVolumeFaces(); ++i)
  1178. { //for each face
  1179. const LLVolumeFace& face = model[idx]->getVolumeFace(i);
  1180. for (U32 j = 0; j < face.mNumVertices; ++j)
  1181. {
  1182. update_min_max(min_pos, max_pos, face.mPositions[j].getF32ptr());
  1183. }
  1184. }
  1185. LLVector3 pos_range = max_pos - min_pos;
  1186. for (S32 i = 0; i < model[idx]->getNumVolumeFaces(); ++i)
  1187. { //for each face
  1188. const LLVolumeFace& face = model[idx]->getVolumeFace(i);
  1189. if (face.mNumVertices < 3)
  1190. { //don't export an empty face
  1191. mdl[model_names[idx]][i]["NoGeometry"] = true;
  1192. continue;
  1193. }
  1194. LLSD::Binary verts(face.mNumVertices*3*2);
  1195. LLSD::Binary tc(face.mNumVertices*2*2);
  1196. LLSD::Binary normals(face.mNumVertices*3*2);
  1197. LLSD::Binary indices(face.mNumIndices*2);
  1198. U32 vert_idx = 0;
  1199. U32 norm_idx = 0;
  1200. U32 tc_idx = 0;
  1201. LLVector2* ftc = (LLVector2*) face.mTexCoords;
  1202. LLVector2 min_tc;
  1203. LLVector2 max_tc;
  1204. if (ftc)
  1205. {
  1206. min_tc = ftc[0];
  1207. max_tc = min_tc;
  1208. //get texture coordinate domain
  1209. for (U32 j = 0; j < face.mNumVertices; ++j)
  1210. {
  1211. update_min_max(min_tc, max_tc, ftc[j]);
  1212. }
  1213. }
  1214. LLVector2 tc_range = max_tc - min_tc;
  1215. for (U32 j = 0; j < face.mNumVertices; ++j)
  1216. { //for each vert
  1217. F32* pos = face.mPositions[j].getF32ptr();
  1218. //position
  1219. for (U32 k = 0; k < 3; ++k)
  1220. { //for each component
  1221. //convert to 16-bit normalized across domain
  1222. U16 val = (U16) (((pos[k]-min_pos.mV[k])/pos_range.mV[k])*65535);
  1223. U8* buff = (U8*) &val;
  1224. //write to binary buffer
  1225. verts[vert_idx++] = buff[0];
  1226. verts[vert_idx++] = buff[1];
  1227. }
  1228. if (face.mNormals)
  1229. { //normals
  1230. F32* norm = face.mNormals[j].getF32ptr();
  1231. for (U32 k = 0; k < 3; ++k)
  1232. { //for each component
  1233. //convert to 16-bit normalized
  1234. U16 val = (U16) ((norm[k]+1.f)*0.5f*65535);
  1235. U8* buff = (U8*) &val;
  1236. //write to binary buffer
  1237. normals[norm_idx++] = buff[0];
  1238. normals[norm_idx++] = buff[1];
  1239. }
  1240. }
  1241. F32* src_tc = (F32*) face.mTexCoords[j].mV;
  1242. //texcoord
  1243. if (face.mTexCoords)
  1244. {
  1245. for (U32 k = 0; k < 2; ++k)
  1246. { //for each component
  1247. //convert to 16-bit normalized
  1248. U16 val = (U16) ((src_tc[k]-min_tc.mV[k])/tc_range.mV[k]*65535);
  1249. U8* buff = (U8*) &val;
  1250. //write to binary buffer
  1251. tc[tc_idx++] = buff[0];
  1252. tc[tc_idx++] = buff[1];
  1253. }
  1254. }
  1255. }
  1256. U32 idx_idx = 0;
  1257. for (U32 j = 0; j < face.mNumIndices; ++j)
  1258. {
  1259. U8* buff = (U8*) &(face.mIndices[j]);
  1260. indices[idx_idx++] = buff[0];
  1261. indices[idx_idx++] = buff[1];
  1262. }
  1263. //write out face data
  1264. mdl[model_names[idx]][i]["PositionDomain"]["Min"] = min_pos.getValue();
  1265. mdl[model_names[idx]][i]["PositionDomain"]["Max"] = max_pos.getValue();
  1266. mdl[model_names[idx]][i]["Position"] = verts;
  1267. if (face.mNormals)
  1268. {
  1269. mdl[model_names[idx]][i]["Normal"] = normals;
  1270. }
  1271. if (face.mTexCoords)
  1272. {
  1273. mdl[model_names[idx]][i]["TexCoord0Domain"]["Min"] = min_tc.getValue();
  1274. mdl[model_names[idx]][i]["TexCoord0Domain"]["Max"] = max_tc.getValue();
  1275. mdl[model_names[idx]][i]["TexCoord0"] = tc;
  1276. }
  1277. mdl[model_names[idx]][i]["TriangleList"] = indices;
  1278. if (skinning)
  1279. {
  1280. //write out skin weights
  1281. //each influence list entry is up to 4 24-bit values
  1282. // first 8 bits is bone index
  1283. // last 16 bits is bone influence weight
  1284. // a bone index of 0xFF signifies no more influences for this vertex
  1285. std::stringstream ostr;
  1286. for (U32 j = 0; j < face.mNumVertices; ++j)
  1287. {
  1288. LLVector3 pos(face.mPositions[j].getF32ptr());
  1289. weight_list& weights = high->getJointInfluences(pos);
  1290. S32 count = 0;
  1291. for (weight_list::iterator iter = weights.begin(); iter != weights.end(); ++iter)
  1292. {
  1293. if (iter->mJointIdx < 255 && iter->mJointIdx >= 0)
  1294. {
  1295. U8 idx = (U8) iter->mJointIdx;
  1296. ostr.write((const char*) &idx, 1);
  1297. U16 influence = (U16) (iter->mWeight*65535);
  1298. ostr.write((const char*) &influence, 2);
  1299. ++count;
  1300. }
  1301. }
  1302. U8 end_list = 0xFF;
  1303. if (count < 4)
  1304. {
  1305. ostr.write((const char*) &end_list, 1);
  1306. }
  1307. }
  1308. //copy ostr to binary buffer
  1309. std::string data = ostr.str();
  1310. const U8* buff = (U8*) data.data();
  1311. U32 bytes = data.size();
  1312. LLSD::Binary w(bytes);
  1313. for (U32 j = 0; j < bytes; ++j)
  1314. {
  1315. w[j] = buff[j];
  1316. }
  1317. mdl[model_names[idx]][i]["Weights"] = w;
  1318. }
  1319. }
  1320. }
  1321. }
  1322. return writeModelToStream(ostr, mdl, nowrite, as_slm);
  1323. }
  1324. LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BOOL as_slm)
  1325. {
  1326. U32 bytes = 0;
  1327. std::string::size_type cur_offset = 0;
  1328. LLSD header;
  1329. if (as_slm && mdl.has("material_list"))
  1330. { //save material binding names to header
  1331. header["material_list"] = mdl["material_list"];
  1332. }
  1333. std::string skin;
  1334. if (mdl.has("skin"))
  1335. { //write out skin block
  1336. skin = zip_llsd(mdl["skin"]);
  1337. U32 size = skin.size();
  1338. if (size > 0)
  1339. {
  1340. header["skin"]["offset"] = (LLSD::Integer) cur_offset;
  1341. header["skin"]["size"] = (LLSD::Integer) size;
  1342. cur_offset += size;
  1343. bytes += size;
  1344. }
  1345. }
  1346. std::string decomposition;
  1347. if (mdl.has("physics_convex"))
  1348. { //write out convex decomposition
  1349. decomposition = zip_llsd(mdl["physics_convex"]);
  1350. U32 size = decomposition.size();
  1351. if (size > 0)
  1352. {
  1353. header["physics_convex"]["offset"] = (LLSD::Integer) cur_offset;
  1354. header["physics_convex"]["size"] = (LLSD::Integer) size;
  1355. cur_offset += size;
  1356. bytes += size;
  1357. }
  1358. }
  1359. std::string out[MODEL_NAMES_LENGTH];
  1360. for (S32 i = 0; i < MODEL_NAMES_LENGTH; i++)
  1361. {
  1362. if (mdl.has(model_names[i]))
  1363. {
  1364. out[i] = zip_llsd(mdl[model_names[i]]);
  1365. U32 size = out[i].size();
  1366. header[model_names[i]]["offset"] = (LLSD::Integer) cur_offset;
  1367. header[model_names[i]]["size"] = (LLSD::Integer) size;
  1368. cur_offset += size;
  1369. bytes += size;
  1370. }
  1371. }
  1372. if (!nowrite)
  1373. {
  1374. LLSDSerialize::toBinary(header, ostr);
  1375. if (!skin.empty())
  1376. { //write skin block
  1377. ostr.write((const char*) skin.data(), header["skin"]["size"].asInteger());
  1378. }
  1379. if (!decomposition.empty())
  1380. { //write decomposition block
  1381. ostr.write((const char*) decomposition.data(), header["physics_convex"]["size"].asInteger());
  1382. }
  1383. for (S32 i = 0; i < MODEL_NAMES_LENGTH; i++)
  1384. {
  1385. if (!out[i].empty())
  1386. {
  1387. ostr.write((const char*) out[i].data(), header[model_names[i]]["size"].asInteger());
  1388. }
  1389. }
  1390. }
  1391. return header;
  1392. }
  1393. LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos)
  1394. {
  1395. //1. If a vertex has been weighted then we'll find it via pos and return it's weight list
  1396. weight_map::iterator iterPos = mSkinWeights.begin();
  1397. weight_map::iterator iterEnd = mSkinWeights.end();
  1398. for ( ; iterPos!=iterEnd; ++iterPos )
  1399. {
  1400. if ( jointPositionalLookup( iterPos->first, pos ) )
  1401. {
  1402. return iterPos->second;
  1403. }
  1404. }
  1405. //2. Otherwise we'll use the older implementation
  1406. weight_map::iterator iter = mSkinWeights.find(pos);
  1407. if (iter != mSkinWeights.end())
  1408. {
  1409. if ((iter->first - pos).magVec() > 0.1f)
  1410. {
  1411. llerrs << "Couldn't find weight list." << llendl;
  1412. }
  1413. return iter->second;
  1414. }
  1415. else
  1416. { //no exact match found, get closest point
  1417. const F32 epsilon = 1e-5f;
  1418. weight_map::iterator iter_up = mSkinWeights.lower_bound(pos);
  1419. weight_map::iterator iter_down = ++iter_up;
  1420. weight_map::iterator best = iter_up;
  1421. F32 min_dist = (iter->first - pos).magVec();
  1422. bool done = false;
  1423. while (!done)
  1424. { //search up and down mSkinWeights from lower bound of pos until a
  1425. //match is found within epsilon. If no match is found within epsilon,
  1426. //return closest match
  1427. done = true;
  1428. if (iter_up != mSkinWeights.end() && ++iter_up != mSkinWeights.end())
  1429. {
  1430. done = false;
  1431. F32 dist = (iter_up->first - pos).magVec();
  1432. if (dist < epsilon)
  1433. {
  1434. return iter_up->second;
  1435. }
  1436. if (dist < min_dist)
  1437. {
  1438. best = iter_up;
  1439. min_dist = dist;
  1440. }
  1441. }
  1442. if (iter_down != mSkinWeights.begin() && --iter_down != mSkinWeights.begin())
  1443. {
  1444. done = false;
  1445. F32 dist = (iter_down->first - pos).magVec();
  1446. if (dist < epsilon)
  1447. {
  1448. return iter_down->second;
  1449. }
  1450. if (dist < min_dist)
  1451. {
  1452. best = iter_down;
  1453. min_dist = dist;
  1454. }
  1455. }
  1456. }
  1457. return best->second;
  1458. }
  1459. }
  1460. void LLModel::setConvexHullDecomposition(
  1461. const LLModel::convex_hull_decomposition& decomp)
  1462. {
  1463. mPhysics.mHull = decomp;
  1464. mPhysics.mMesh.clear();
  1465. updateHullCenters();
  1466. }
  1467. void LLModel::updateHullCenters()
  1468. {
  1469. mHullCenter.resize(mPhysics.mHull.size());
  1470. mHullPoints = 0;
  1471. mCenterOfHullCenters.clear();
  1472. for (U32 i = 0; i < mPhysics.mHull.size(); ++i)
  1473. {
  1474. LLVector3 cur_center;
  1475. for (U32 j = 0; j < mPhysics.mHull[i].size(); ++j)
  1476. {
  1477. cur_center += mPhysics.mHull[i][j];
  1478. }
  1479. mCenterOfHullCenters += cur_center;
  1480. cur_center *= 1.f/mPhysics.mHull[i].size();
  1481. mHullCenter[i] = cur_center;
  1482. mHullPoints += mPhysics.mHull[i].size();
  1483. }
  1484. if (mHullPoints > 0)
  1485. {
  1486. mCenterOfHullCenters *= 1.f / mHullPoints;
  1487. llassert(mPhysics.hasHullList());
  1488. }
  1489. }
  1490. bool LLModel::loadModel(std::istream& is)
  1491. {
  1492. mSculptLevel = -1; // default is an error occured
  1493. LLSD header;
  1494. {
  1495. if (!LLSDSerialize::fromBinary(header, is, 1024*1024*1024))
  1496. {
  1497. llwarns << "Mesh header parse error. Not a valid mesh asset!" << llendl;
  1498. return false;
  1499. }
  1500. }
  1501. if (header.has("material_list"))
  1502. { //load material list names
  1503. mMaterialList.clear();
  1504. for (U32 i = 0; i < header["material_list"].size(); ++i)
  1505. {
  1506. mMaterialList.push_back(header["material_list"][i].asString());
  1507. }
  1508. }
  1509. std::string nm[] =
  1510. {
  1511. "lowest_lod",
  1512. "low_lod",
  1513. "medium_lod",
  1514. "high_lod",
  1515. "physics_mesh",
  1516. };
  1517. const S32 MODEL_LODS = 5;
  1518. S32 lod = llclamp((S32) mDetail, 0, MODEL_LODS);
  1519. if (header[nm[lod]]["offset"].asInteger() == -1 ||
  1520. header[nm[lod]]["size"].asInteger() == 0 )
  1521. { //cannot load requested LOD
  1522. llwarns << "LoD data is invalid!" << llendl;
  1523. return false;
  1524. }
  1525. bool has_skin = header["skin"]["offset"].asInteger() >=0 &&
  1526. header["skin"]["size"].asInteger() > 0;
  1527. if (lod == LLModel::LOD_HIGH)
  1528. { //try to load skin info and decomp info
  1529. std::ios::pos_type cur_pos = is.tellg();
  1530. loadSkinInfo(header, is);
  1531. is.seekg(cur_pos);
  1532. }
  1533. if (lod == LLModel::LOD_HIGH || lod == LLModel::LOD_PHYSICS)
  1534. {
  1535. std::ios::pos_type cur_pos = is.tellg();
  1536. loadDecomposition(header, is);
  1537. is.seekg(cur_pos);
  1538. }
  1539. is.seekg(header[nm[lod]]["offset"].asInteger(), std::ios_base::cur);
  1540. if (unpackVolumeFaces(is, header[nm[lod]]["size"].asInteger()))
  1541. {
  1542. if (has_skin)
  1543. {
  1544. //build out mSkinWeight from face info
  1545. for (S32 i = 0; i < getNumVolumeFaces(); ++i)
  1546. {
  1547. const LLVolumeFace& face = getVolumeFace(i);
  1548. if (face.mWeights)
  1549. {
  1550. for (S32 j = 0; j < face.mNumVertices; ++j)
  1551. {
  1552. LLVector4a& w = face.mWeights[j];
  1553. std::vector<JointWeight> wght;
  1554. for (S32 k = 0; k < 4; ++k)
  1555. {
  1556. S32 idx = (S32) w[k];
  1557. F32 f = w[k] - idx;
  1558. if (f > 0.f)
  1559. {
  1560. wght.push_back(JointWeight(idx, f));
  1561. }
  1562. }
  1563. if (!wght.empty())
  1564. {
  1565. LLVector3 pos(face.mPositions[j].getF32ptr());
  1566. mSkinWeights[pos] = wght;
  1567. }
  1568. }
  1569. }
  1570. }
  1571. }
  1572. return true;
  1573. }
  1574. else
  1575. {
  1576. llwarns << "unpackVolumeFaces failed!" << llendl;
  1577. }
  1578. return false;
  1579. }
  1580. bool LLModel::isMaterialListSubset( LLModel* ref )
  1581. {
  1582. int refCnt = ref->mMaterialList.size();
  1583. int modelCnt = mMaterialList.size();
  1584. for (U32 src = 0; src < modelCnt; ++src)
  1585. {
  1586. bool foundRef = false;
  1587. for (U32 dst = 0; dst < refCnt; ++dst)
  1588. {
  1589. //llinfos<<mMaterialList[src]<<" "<<ref->mMaterialList[dst]<<llendl;
  1590. foundRef = mMaterialList[src] == ref->mMaterialList[dst];
  1591. if ( foundRef )
  1592. {
  1593. break;
  1594. }
  1595. }
  1596. if (!foundRef)
  1597. {
  1598. return false;
  1599. }
  1600. }
  1601. return true;
  1602. }
  1603. bool LLModel::needToAddFaces( LLModel* ref, int& refFaceCnt, int& modelFaceCnt )
  1604. {
  1605. bool changed = false;
  1606. if ( refFaceCnt< modelFaceCnt )
  1607. {
  1608. refFaceCnt += modelFaceCnt - refFaceCnt;
  1609. changed = true;
  1610. }
  1611. else
  1612. if ( modelFaceCnt < refFaceCnt )
  1613. {
  1614. modelFaceCnt += refFaceCnt - modelFaceCnt;
  1615. changed = true;
  1616. }
  1617. return changed;
  1618. }
  1619. bool LLModel::matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCnt )
  1620. {
  1621. //Is this a subset?
  1622. //LODs cannot currently add new materials, e.g.
  1623. //1. ref = a,b,c lod1 = d,e => This is not permitted
  1624. //2. ref = a,b,c lod1 = c => This would be permitted
  1625. bool isASubset = isMaterialListSubset( ref );
  1626. if ( !isASubset )
  1627. {
  1628. llinfos<<"Material of model is not a subset of reference."<<llendl;
  1629. return false;
  1630. }
  1631. std::map<std::string, U32> index_map;
  1632. //build a map of material slot names to face indexes
  1633. bool reorder = false;
  1634. std::set<std::string> base_mat;
  1635. std::set<std::string> cur_mat;
  1636. for (U32 i = 0; i < mMaterialList.size(); i++)
  1637. {
  1638. index_map[ref->mMaterialList[i]] = i;
  1639. if (!reorder)
  1640. { //if any material name does not match reference, we need to reorder
  1641. reorder = ref->mMaterialList[i] != mMaterialList[i];
  1642. }
  1643. base_mat.insert(ref->mMaterialList[i]);
  1644. cur_mat.insert(mMaterialList[i]);
  1645. }
  1646. if (reorder &&
  1647. base_mat == cur_mat) //don't reorder if material name sets don't match
  1648. {
  1649. std::vector<LLVolumeFace> new_face_list;
  1650. new_face_list.resize(mVolumeFaces.size());
  1651. std::vector<std::string> new_material_list;
  1652. new_material_list.resize(mVolumeFaces.size());
  1653. //rebuild face list so materials have the same order
  1654. //as the reference model
  1655. for (U32 i = 0; i < mMaterialList.size(); ++i)
  1656. {
  1657. U32 ref_idx = index_map[mMaterialList[i]];
  1658. new_face_list[ref_idx] = mVolumeFaces[i];
  1659. new_material_list[ref_idx] = mMaterialList[i];
  1660. }
  1661. llassert(new_material_list == ref->mMaterialList);
  1662. mVolumeFaces = new_face_list;
  1663. }
  1664. //override material list with reference model ordering
  1665. mMaterialList = ref->mMaterialList;
  1666. return true;
  1667. }
  1668. bool LLModel::loadSkinInfo(LLSD& header, std::istream &is)
  1669. {
  1670. S32 offset = header["skin"]["offset"].asInteger();
  1671. S32 size = header["skin"]["size"].asInteger();
  1672. if (offset >= 0 && size > 0)
  1673. {
  1674. is.seekg(offset, std::ios_base::cur);
  1675. LLSD skin_data;
  1676. if (unzip_llsd(skin_data, is, size))
  1677. {
  1678. mSkinInfo.fromLLSD(skin_data);
  1679. return true;
  1680. }
  1681. }
  1682. return false;
  1683. }
  1684. bool LLModel::loadDecomposition(LLSD& header, std::istream& is)
  1685. {
  1686. S32 offset = header["physics_convex"]["offset"].asInteger();
  1687. S32 size = header["physics_convex"]["size"].asInteger();
  1688. if (offset >= 0 && size > 0)
  1689. {
  1690. is.seekg(offset, std::ios_base::cur);
  1691. LLSD data;
  1692. if (unzip_llsd(data, is, size))
  1693. {
  1694. mPhysics.fromLLSD(data);
  1695. updateHullCenters();
  1696. }
  1697. }
  1698. return true;
  1699. }
  1700. LLMeshSkinInfo::LLMeshSkinInfo(LLSD& skin)
  1701. {
  1702. fromLLSD(skin);
  1703. }
  1704. void LLMeshSkinInfo::fromLLSD(LLSD& skin)
  1705. {
  1706. if (skin.has("joint_names"))
  1707. {
  1708. for (U32 i = 0; i < skin["joint_names"].size(); ++i)
  1709. {
  1710. mJointNames.push_back(skin["joint_names"][i]);
  1711. }
  1712. }
  1713. if (skin.has("inverse_bind_matrix"))
  1714. {
  1715. for (U32 i = 0; i < skin["inverse_bind_matrix"].size(); ++i)
  1716. {
  1717. LLMatrix4 mat;
  1718. for (U32 j = 0; j < 4; j++)
  1719. {
  1720. for (U32 k = 0; k < 4; k++)
  1721. {
  1722. mat.mMatrix[j][k] = skin["inverse_bind_matrix"][i][j*4+k].asReal();
  1723. }
  1724. }
  1725. mInvBindMatrix.push_back(mat);
  1726. }
  1727. }
  1728. if (skin.has("bind_shape_matrix"))
  1729. {
  1730. for (U32 j = 0; j < 4; j++)
  1731. {
  1732. for (U32 k = 0; k < 4; k++)
  1733. {
  1734. mBindShapeMatrix.mMatrix[j][k] = skin["bind_shape_matrix"][j*4+k].asReal();
  1735. }
  1736. }
  1737. }
  1738. if (skin.has("alt_inverse_bind_matrix"))
  1739. {
  1740. for (U32 i = 0; i < skin["alt_inverse_bind_matrix"].size(); ++i)
  1741. {
  1742. LLMatrix4 mat;
  1743. for (U32 j = 0; j < 4; j++)
  1744. {
  1745. for (U32 k = 0; k < 4; k++)
  1746. {
  1747. mat.mMatrix[j][k] = skin["alt_inverse_bind_matrix"][i][j*4+k].asReal();
  1748. }
  1749. }
  1750. mAlternateBindMatrix.push_back(mat);
  1751. }
  1752. }
  1753. if (skin.has("pelvis_offset"))
  1754. {
  1755. mPelvisOffset = skin["pelvis_offset"].asReal();
  1756. }
  1757. }
  1758. LLSD LLMeshSkinInfo::asLLSD(bool include_joints) const
  1759. {
  1760. LLSD ret;
  1761. for (U32 i = 0; i < mJointNames.size(); ++i)
  1762. {
  1763. ret["joint_names"][i] = mJointNames[i];
  1764. for (U32 j = 0; j < 4; j++)
  1765. {
  1766. for (U32 k = 0; k < 4; k++)
  1767. {
  1768. ret["inverse_bind_matrix"][i][j*4+k] = mInvBindMatrix[i].mMatrix[j][k];
  1769. }
  1770. }
  1771. }
  1772. for (U32 i = 0; i < 4; i++)
  1773. {
  1774. for (U32 j = 0; j < 4; j++)
  1775. {
  1776. ret["bind_shape_matrix"][i*4+j] = mBindShapeMatrix.mMatrix[i][j];
  1777. }
  1778. }
  1779. if ( include_joints && mAlternateBindMatrix.size() > 0 )
  1780. {
  1781. for (U32 i = 0; i < mJointNames.size(); ++i)
  1782. {
  1783. for (U32 j = 0; j < 4; j++)
  1784. {
  1785. for (U32 k = 0; k < 4; k++)
  1786. {
  1787. ret["alt_inverse_bind_matrix"][i][j*4+k] = mAlternateBindMatrix[i].mMatrix[j][k];
  1788. }
  1789. }
  1790. }
  1791. ret["pelvis_offset"] = mPelvisOffset;
  1792. }
  1793. return ret;
  1794. }
  1795. LLModel::Decomposition::Decomposition(LLSD& data)
  1796. {
  1797. fromLLSD(data);
  1798. }
  1799. void LLModel::Decomposition::fromLLSD(LLSD& decomp)
  1800. {
  1801. if (decomp.has("HullList") && decomp.has("Positions"))
  1802. {
  1803. // updated for const-correctness. gcc is picky about this type of thing - Nyx
  1804. const LLSD::Binary& hulls = decomp["HullList"].asBinary();
  1805. const LLSD::Binary& position = decomp["Positions"].asBinary();
  1806. U16* p = (U16*) &position[0];
  1807. mHull.resize(hulls.size());
  1808. LLVector3 min;
  1809. LLVector3 max;
  1810. LLVector3 range;
  1811. if (decomp.has("Min"))
  1812. {
  1813. min.setValue(decomp["Min"]);
  1814. max.setValue(decomp["Max"]);
  1815. }
  1816. else
  1817. {
  1818. min.set(-0.5f, -0.5f, -0.5f);
  1819. max.set(0.5f, 0.5f, 0.5f);
  1820. }
  1821. range = max-min;
  1822. for (U32 i = 0; i < hulls.size(); ++i)
  1823. {
  1824. U16 count = (hulls[i] == 0) ? 256 : hulls[i];
  1825. std::set<U64> valid;
  1826. //must have at least 4 points
  1827. //llassert(count > 3);
  1828. for (U32 j = 0; j < count; ++j)
  1829. {
  1830. U64 test = (U64) p[0] | ((U64) p[1] << 16) | ((U64) p[2] << 32);
  1831. //point must be unique
  1832. //llassert(valid.find(test) == valid.end());
  1833. valid.insert(test);
  1834. mHull[i].push_back(LLVector3(
  1835. (F32) p[0]/65535.f*range.mV[0]+min.mV[0],
  1836. (F32) p[1]/65535.f*range.mV[1]+min.mV[1],
  1837. (F32) p[2]/65535.f*range.mV[2]+min.mV[2]));
  1838. p += 3;
  1839. }
  1840. //each hull must contain at least 4 unique points
  1841. //llassert(valid.size() > 3);
  1842. }
  1843. }
  1844. if (decomp.has("BoundingVerts"))
  1845. {
  1846. const LLSD::Binary& position = decomp["BoundingVerts"].asBinary();
  1847. U16* p = (U16*) &position[0];
  1848. LLVector3 min;
  1849. LLVector3 max;
  1850. LLVector3 range;
  1851. if (decomp.has("Min"))
  1852. {
  1853. min.setValue(decomp["Min"]);
  1854. max.setValue(decomp["Max"]);
  1855. }
  1856. else
  1857. {
  1858. min.set(-0.5f, -0.5f, -0.5f);
  1859. max.set(0.5f, 0.5f, 0.5f);
  1860. }
  1861. range = max-min;
  1862. U16 count = position.size()/6;
  1863. for (U32 j = 0; j < count; ++j)
  1864. {
  1865. mBaseHull.push_back(LLVector3(
  1866. (F32) p[0]/65535.f*range.mV[0]+min.mV[0],
  1867. (F32) p[1]/65535.f*range.mV[1]+min.mV[1],
  1868. (F32) p[2]/65535.f*range.mV[2]+min.mV[2]));
  1869. p += 3;
  1870. }
  1871. }
  1872. else
  1873. {
  1874. //empty base hull mesh to indicate decomposition has been loaded
  1875. //but contains no base hull
  1876. mBaseHullMesh.clear();
  1877. }
  1878. }
  1879. bool LLModel::Decomposition::hasHullList() const
  1880. {
  1881. return !mHull.empty() ;
  1882. }
  1883. LLSD LLModel::Decomposition::asLLSD() const
  1884. {
  1885. LLSD ret;
  1886. if (mBaseHull.empty() && mHull.empty())
  1887. { //nothing to write
  1888. return ret;
  1889. }
  1890. //write decomposition block
  1891. // ["physics_convex"]["HullList"] -- list of 8 bit integers, each entry represents a hull with specified number of points
  1892. // ["physics_convex"]["Position"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points
  1893. // ["physics_convex"]["BoundingVerts"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points representing a single hull approximation of given shape
  1894. //get minimum and maximum
  1895. LLVector3 min;
  1896. if (mHull.empty())
  1897. {
  1898. min = mBaseHull[0];
  1899. }
  1900. else
  1901. {
  1902. min = mHull[0][0];
  1903. }
  1904. LLVector3 max = min;
  1905. LLSD::Binary hulls(mHull.size());
  1906. U32 total = 0;
  1907. for (U32 i = 0; i < mHull.size(); ++i)
  1908. {
  1909. U32 size = mHull[i].size();
  1910. total += size;
  1911. hulls[i] = (U8) (size);
  1912. for (U32 j = 0; j < mHull[i].size(); ++j)
  1913. {
  1914. update_min_max(min, max, mHull[i][j]);
  1915. }
  1916. }
  1917. for (U32 i = 0; i < mBaseHull.size(); ++i)
  1918. {
  1919. update_min_max(min, max, mBaseHull[i]);
  1920. }
  1921. ret["Min"] = min.getValue();
  1922. ret["Max"] = max.getValue();
  1923. LLVector3 range = max-min;
  1924. if (!hulls.empty())
  1925. {
  1926. ret["HullList"] = hulls;
  1927. }
  1928. if (total > 0)
  1929. {
  1930. LLSD::Binary p(total*3*2);
  1931. U32 vert_idx = 0;
  1932. for (U32 i = 0; i < mHull.size(); ++i)
  1933. {
  1934. std::set<U64> valid;
  1935. llassert(!mHull[i].empty());
  1936. for (U32 j = 0; j < mHull[i].size(); ++j)
  1937. {
  1938. U64 test = 0;
  1939. const F32* src = mHull[i][j].mV;
  1940. for (U32 k = 0; k < 3; k++)
  1941. {
  1942. //convert to 16-bit normalized across domain
  1943. U16 val = (U16) (((src[k]-min.mV[k])/range.mV[k])*65535);
  1944. if(valid.size() < 3)
  1945. {
  1946. switch (k)
  1947. {
  1948. case 0: test = test | (U64) val; break;
  1949. case 1: test = test | ((U64) val << 16); break;
  1950. case 2: test = test | ((U64) val << 32); break;
  1951. };
  1952. valid.insert(test);
  1953. }
  1954. U8* buff = (U8*) &val;
  1955. //write to binary buffer
  1956. p[vert_idx++] = buff[0];
  1957. p[vert_idx++] = buff[1];
  1958. //makes sure we haven't run off the end of the array
  1959. llassert(vert_idx <= p.size());
  1960. }
  1961. }
  1962. //must have at least 3 unique points
  1963. llassert(valid.size() > 2);
  1964. }
  1965. ret["Positions"] = p;
  1966. }
  1967. //llassert(!mBaseHull.empty());
  1968. if (!mBaseHull.empty())
  1969. {
  1970. LLSD::Binary p(mBaseHull.size()*3*2);
  1971. U32 vert_idx = 0;
  1972. for (U32 j = 0; j < mBaseHull.size(); ++j)
  1973. {
  1974. const F32* v = mBaseHull[j].mV;
  1975. for (U32 k = 0; k < 3; k++)
  1976. {
  1977. //convert to 16-bit normalized across domain
  1978. U16 val = (U16) (((v[k]-min.mV[k])/range.mV[k])*65535);
  1979. U8* buff = (U8*) &val;
  1980. //write to binary buffer
  1981. p[vert_idx++] = buff[0];
  1982. p[vert_idx++] = buff[1];
  1983. if (vert_idx > p.size())
  1984. {
  1985. llerrs << "Index out of bounds" << llendl;
  1986. }
  1987. }
  1988. }
  1989. ret["BoundingVerts"] = p;
  1990. }
  1991. return ret;
  1992. }
  1993. void LLModel::Decomposition::merge(const LLModel::Decomposition* rhs)
  1994. {
  1995. if (!rhs)
  1996. {
  1997. return;
  1998. }
  1999. if (mMeshID != rhs->mMeshID)
  2000. {
  2001. llerrs << "Attempted to merge with decomposition of some other mesh." << llendl;
  2002. }
  2003. if (mBaseHull.empty())
  2004. { //take base hull and decomposition from rhs
  2005. mHull = rhs->mHull;
  2006. mBaseHull = rhs->mBaseHull;
  2007. mMesh = rhs->mMesh;
  2008. mBaseHullMesh = rhs->mBaseHullMesh;
  2009. }
  2010. if (mPhysicsShapeMesh.empty())
  2011. { //take physics shape mesh from rhs
  2012. mPhysicsShapeMesh = rhs->mPhysicsShapeMesh;
  2013. }
  2014. }