PageRenderTime 58ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/llfloatermodelpreview.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 2236 lines | 1677 code | 365 blank | 194 comment | 273 complexity | ec1ea93da092dfb0a77706f06582b3f6 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llfloatermodelpreview.cpp
  3. * @brief LLFloaterModelPreview class implementation
  4. *
  5. * $LicenseInfo:firstyear=2004&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. #if LL_MSVC
  28. #pragma warning (disable : 4263)
  29. #pragma warning (disable : 4264)
  30. #endif
  31. #include "dae.h"
  32. //#include "dom.h"
  33. #include "dom/domAsset.h"
  34. #include "dom/domBind_material.h"
  35. #include "dom/domCOLLADA.h"
  36. #include "dom/domConstants.h"
  37. #include "dom/domController.h"
  38. #include "dom/domEffect.h"
  39. #include "dom/domGeometry.h"
  40. #include "dom/domInstance_geometry.h"
  41. #include "dom/domInstance_material.h"
  42. #include "dom/domInstance_node.h"
  43. #include "dom/domInstance_effect.h"
  44. #include "dom/domMaterial.h"
  45. #include "dom/domMatrix.h"
  46. #include "dom/domNode.h"
  47. #include "dom/domProfile_COMMON.h"
  48. #include "dom/domRotate.h"
  49. #include "dom/domScale.h"
  50. #include "dom/domTranslate.h"
  51. #include "dom/domVisual_scene.h"
  52. #if LL_MSVC
  53. #pragma warning (default : 4263)
  54. #pragma warning (default : 4264)
  55. #endif
  56. #include "llfloatermodelpreview.h"
  57. #include "llfilepicker.h"
  58. #include "llimagebmp.h"
  59. #include "llimagetga.h"
  60. #include "llimagejpeg.h"
  61. #include "llimagepng.h"
  62. #include "llagent.h"
  63. #include "llbutton.h"
  64. #include "llcombobox.h"
  65. #include "lldatapacker.h"
  66. #include "lldrawable.h"
  67. #include "lldrawpoolavatar.h"
  68. #include "llrender.h"
  69. #include "llface.h"
  70. #include "lleconomy.h"
  71. #include "llfocusmgr.h"
  72. #include "llfloaterperms.h"
  73. #include "lliconctrl.h"
  74. #include "llmatrix4a.h"
  75. #include "llmenubutton.h"
  76. #include "llmeshrepository.h"
  77. #include "llnotificationsutil.h"
  78. #include "llsdutil_math.h"
  79. #include "lltextbox.h"
  80. #include "lltoolmgr.h"
  81. #include "llui.h"
  82. #include "llvector4a.h"
  83. #include "llviewercamera.h"
  84. #include "llviewerwindow.h"
  85. #include "llvoavatar.h"
  86. #include "llvoavatarself.h"
  87. #include "pipeline.h"
  88. #include "lluictrlfactory.h"
  89. #include "llviewercontrol.h"
  90. #include "llviewermenu.h"
  91. #include "llviewermenufile.h"
  92. #include "llviewerregion.h"
  93. #include "llviewertexturelist.h"
  94. #include "llstring.h"
  95. #include "llbutton.h"
  96. #include "llcheckboxctrl.h"
  97. #include "llradiogroup.h"
  98. #include "llsdserialize.h"
  99. #include "llsliderctrl.h"
  100. #include "llspinctrl.h"
  101. #include "lltoggleablemenu.h"
  102. #include "lltrans.h"
  103. #include "llvfile.h"
  104. #include "llvfs.h"
  105. #include "llcallbacklist.h"
  106. #include "llviewerobjectlist.h"
  107. #include "llanimationstates.h"
  108. #include "llviewernetwork.h"
  109. #include "llviewershadermgr.h"
  110. #include "glod/glod.h"
  111. #include <boost/algorithm/string.hpp>
  112. const S32 SLM_SUPPORTED_VERSION = 3;
  113. //static
  114. S32 LLFloaterModelPreview::sUploadAmount = 10;
  115. LLFloaterModelPreview* LLFloaterModelPreview::sInstance = NULL;
  116. std::list<LLModelLoader*> LLModelLoader::sActiveLoaderList;
  117. const S32 PREVIEW_BORDER_WIDTH = 2;
  118. const S32 PREVIEW_RESIZE_HANDLE_SIZE = S32(RESIZE_HANDLE_WIDTH * OO_SQRT2) + PREVIEW_BORDER_WIDTH;
  119. const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE;
  120. const S32 PREF_BUTTON_HEIGHT = 16 + 7 + 16;
  121. const S32 PREVIEW_TEXTURE_HEIGHT = 300;
  122. // "Retain%" decomp parameter has values from 0.0 to 1.0 by 0.01
  123. // But according to the UI spec for upload model floater, this parameter
  124. // should be represented by Retain spinner with values from 1 to 100 by 1.
  125. // To achieve this, RETAIN_COEFFICIENT is used while creating spinner
  126. // and when value is requested from spinner.
  127. const double RETAIN_COEFFICIENT = 100;
  128. // "Cosine%" decomp parameter has values from 0.9 to 1 by 0.001
  129. // But according to the UI spec for upload model floater, this parameter
  130. // should be represented by Smooth combobox with only 10 values.
  131. // So this const is used as a size of Smooth combobox list.
  132. const S32 SMOOTH_VALUES_NUMBER = 10;
  133. void drawBoxOutline(const LLVector3& pos, const LLVector3& size);
  134. std::string lod_name[NUM_LOD+1] =
  135. {
  136. "lowest",
  137. "low",
  138. "medium",
  139. "high",
  140. "I went off the end of the lod_name array. Me so smart."
  141. };
  142. std::string lod_triangles_name[NUM_LOD+1] =
  143. {
  144. "lowest_triangles",
  145. "low_triangles",
  146. "medium_triangles",
  147. "high_triangles",
  148. "I went off the end of the lod_triangles_name array. Me so smart."
  149. };
  150. std::string lod_vertices_name[NUM_LOD+1] =
  151. {
  152. "lowest_vertices",
  153. "low_vertices",
  154. "medium_vertices",
  155. "high_vertices",
  156. "I went off the end of the lod_vertices_name array. Me so smart."
  157. };
  158. std::string lod_status_name[NUM_LOD+1] =
  159. {
  160. "lowest_status",
  161. "low_status",
  162. "medium_status",
  163. "high_status",
  164. "I went off the end of the lod_status_name array. Me so smart."
  165. };
  166. std::string lod_icon_name[NUM_LOD+1] =
  167. {
  168. "status_icon_lowest",
  169. "status_icon_low",
  170. "status_icon_medium",
  171. "status_icon_high",
  172. "I went off the end of the lod_status_name array. Me so smart."
  173. };
  174. std::string lod_status_image[NUM_LOD+1] =
  175. {
  176. "ModelImport_Status_Good",
  177. "ModelImport_Status_Warning",
  178. "ModelImport_Status_Error",
  179. "I went off the end of the lod_status_image array. Me so smart."
  180. };
  181. std::string lod_label_name[NUM_LOD+1] =
  182. {
  183. "lowest_label",
  184. "low_label",
  185. "medium_label",
  186. "high_label",
  187. "I went off the end of the lod_label_name array. Me so smart."
  188. };
  189. std::string colladaVersion[VERSIONTYPE_COUNT+1] =
  190. {
  191. "1.4.0",
  192. "1.4.1",
  193. "Unsupported"
  194. };
  195. #define LL_DEGENERACY_TOLERANCE 1e-7f
  196. inline F32 dot3fpu(const LLVector4a& a, const LLVector4a& b)
  197. {
  198. volatile F32 p0 = a[0] * b[0];
  199. volatile F32 p1 = a[1] * b[1];
  200. volatile F32 p2 = a[2] * b[2];
  201. return p0 + p1 + p2;
  202. }
  203. bool ll_is_degenerate(const LLVector4a& a, const LLVector4a& b, const LLVector4a& c, F32 tolerance = LL_DEGENERACY_TOLERANCE)
  204. {
  205. // small area check
  206. {
  207. LLVector4a edge1; edge1.setSub( a, b );
  208. LLVector4a edge2; edge2.setSub( a, c );
  209. //////////////////////////////////////////////////////////////////////////
  210. /// Linden Modified
  211. //////////////////////////////////////////////////////////////////////////
  212. // If no one edge is more than 10x longer than any other edge, we weaken
  213. // the tolerance by a factor of 1e-4f.
  214. LLVector4a edge3; edge3.setSub( c, b );
  215. const F32 len1sq = edge1.dot3(edge1).getF32();
  216. const F32 len2sq = edge2.dot3(edge2).getF32();
  217. const F32 len3sq = edge3.dot3(edge3).getF32();
  218. bool abOK = (len1sq <= 100.f * len2sq) && (len1sq <= 100.f * len3sq);
  219. bool acOK = (len2sq <= 100.f * len1sq) && (len1sq <= 100.f * len3sq);
  220. bool cbOK = (len3sq <= 100.f * len1sq) && (len1sq <= 100.f * len2sq);
  221. if ( abOK && acOK && cbOK )
  222. {
  223. tolerance *= 1e-4f;
  224. }
  225. //////////////////////////////////////////////////////////////////////////
  226. /// End Modified
  227. //////////////////////////////////////////////////////////////////////////
  228. LLVector4a cross; cross.setCross3( edge1, edge2 );
  229. LLVector4a edge1b; edge1b.setSub( b, a );
  230. LLVector4a edge2b; edge2b.setSub( b, c );
  231. LLVector4a crossb; crossb.setCross3( edge1b, edge2b );
  232. if ( ( cross.dot3(cross).getF32() < tolerance ) || ( crossb.dot3(crossb).getF32() < tolerance ))
  233. {
  234. return true;
  235. }
  236. }
  237. // point triangle distance check
  238. {
  239. LLVector4a Q; Q.setSub(a, b);
  240. LLVector4a R; R.setSub(c, b);
  241. const F32 QQ = dot3fpu(Q, Q);
  242. const F32 RR = dot3fpu(R, R);
  243. const F32 QR = dot3fpu(R, Q);
  244. volatile F32 QQRR = QQ * RR;
  245. volatile F32 QRQR = QR * QR;
  246. F32 Det = (QQRR - QRQR);
  247. if( Det == 0.0f )
  248. {
  249. return true;
  250. }
  251. }
  252. return false;
  253. }
  254. bool validate_face(const LLVolumeFace& face)
  255. {
  256. for (U32 i = 0; i < face.mNumIndices; ++i)
  257. {
  258. if (face.mIndices[i] >= face.mNumVertices)
  259. {
  260. llwarns << "Face has invalid index." << llendl;
  261. return false;
  262. }
  263. }
  264. if (face.mNumIndices % 3 != 0 || face.mNumIndices == 0)
  265. {
  266. llwarns << "Face has invalid number of indices." << llendl;
  267. return false;
  268. }
  269. /*const LLVector4a scale(0.5f);
  270. for (U32 i = 0; i < face.mNumIndices; i+=3)
  271. {
  272. U16 idx1 = face.mIndices[i];
  273. U16 idx2 = face.mIndices[i+1];
  274. U16 idx3 = face.mIndices[i+2];
  275. LLVector4a v1; v1.setMul(face.mPositions[idx1], scale);
  276. LLVector4a v2; v2.setMul(face.mPositions[idx2], scale);
  277. LLVector4a v3; v3.setMul(face.mPositions[idx3], scale);
  278. if (ll_is_degenerate(v1,v2,v3))
  279. {
  280. llwarns << "Degenerate face found!" << llendl;
  281. return false;
  282. }
  283. }*/
  284. return true;
  285. }
  286. bool validate_model(const LLModel* mdl)
  287. {
  288. if (mdl->getNumVolumeFaces() == 0)
  289. {
  290. llwarns << "Model has no faces!" << llendl;
  291. return false;
  292. }
  293. for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i)
  294. {
  295. if (mdl->getVolumeFace(i).mNumVertices == 0)
  296. {
  297. llwarns << "Face has no vertices." << llendl;
  298. return false;
  299. }
  300. if (mdl->getVolumeFace(i).mNumIndices == 0)
  301. {
  302. llwarns << "Face has no indices." << llendl;
  303. return false;
  304. }
  305. if (!validate_face(mdl->getVolumeFace(i)))
  306. {
  307. return false;
  308. }
  309. }
  310. return true;
  311. }
  312. BOOL stop_gloderror()
  313. {
  314. GLuint error = glodGetError();
  315. if (error != GLOD_NO_ERROR)
  316. {
  317. llwarns << "GLOD error detected, cannot generate LOD: " << std::hex << error << llendl;
  318. return TRUE;
  319. }
  320. return FALSE;
  321. }
  322. LLMeshFilePicker::LLMeshFilePicker(LLModelPreview* mp, S32 lod)
  323. : LLFilePickerThread(LLFilePicker::FFLOAD_COLLADA)
  324. {
  325. mMP = mp;
  326. mLOD = lod;
  327. }
  328. void LLMeshFilePicker::notify(const std::string& filename)
  329. {
  330. mMP->loadModel(mFile, mLOD);
  331. }
  332. //-----------------------------------------------------------------------------
  333. // LLFloaterModelPreview()
  334. //-----------------------------------------------------------------------------
  335. LLFloaterModelPreview::LLFloaterModelPreview(const LLSD& key) :
  336. LLFloaterModelUploadBase(key),
  337. mUploadBtn(NULL),
  338. mCalculateBtn(NULL)
  339. {
  340. sInstance = this;
  341. mLastMouseX = 0;
  342. mLastMouseY = 0;
  343. mGLName = 0;
  344. mStatusLock = new LLMutex(NULL);
  345. mModelPreview = NULL;
  346. mLODMode[LLModel::LOD_HIGH] = 0;
  347. for (U32 i = 0; i < LLModel::LOD_HIGH; i++)
  348. {
  349. mLODMode[i] = 1;
  350. }
  351. }
  352. //-----------------------------------------------------------------------------
  353. // postBuild()
  354. //-----------------------------------------------------------------------------
  355. BOOL LLFloaterModelPreview::postBuild()
  356. {
  357. if (!LLFloater::postBuild())
  358. {
  359. return FALSE;
  360. }
  361. childSetCommitCallback("cancel_btn", onCancel, this);
  362. childSetCommitCallback("crease_angle", onGenerateNormalsCommit, this);
  363. getChild<LLCheckBoxCtrl>("gen_normals")->setCommitCallback(boost::bind(&LLFloaterModelPreview::toggleGenarateNormals, this));
  364. childSetCommitCallback("lod_generate", onAutoFillCommit, this);
  365. for (S32 lod = 0; lod <= LLModel::LOD_HIGH; ++lod)
  366. {
  367. LLComboBox* lod_source_combo = getChild<LLComboBox>("lod_source_" + lod_name[lod]);
  368. lod_source_combo->setCommitCallback(boost::bind(&LLFloaterModelPreview::onLoDSourceCommit, this, lod));
  369. lod_source_combo->setCurrentByIndex(mLODMode[lod]);
  370. getChild<LLButton>("lod_browse_" + lod_name[lod])->setCommitCallback(boost::bind(&LLFloaterModelPreview::onBrowseLOD, this, lod));
  371. getChild<LLComboBox>("lod_mode_" + lod_name[lod])->setCommitCallback(boost::bind(&LLFloaterModelPreview::onLODParamCommit, this, lod, false));
  372. getChild<LLSpinCtrl>("lod_error_threshold_" + lod_name[lod])->setCommitCallback(boost::bind(&LLFloaterModelPreview::onLODParamCommit, this, lod, false));
  373. getChild<LLSpinCtrl>("lod_triangle_limit_" + lod_name[lod])->setCommitCallback(boost::bind(&LLFloaterModelPreview::onLODParamCommit, this, lod, true));
  374. }
  375. childSetCommitCallback("upload_skin", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL);
  376. childSetCommitCallback("upload_joints", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL);
  377. childSetCommitCallback("upload_textures", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL);
  378. childSetTextArg("status", "[STATUS]", getString("status_idle"));
  379. childSetAction("ok_btn", onUpload, this);
  380. childDisable("ok_btn");
  381. childSetAction("reset_btn", onReset, this);
  382. childSetCommitCallback("preview_lod_combo", onPreviewLODCommit, this);
  383. childSetCommitCallback("upload_skin", onUploadSkinCommit, this);
  384. childSetCommitCallback("upload_joints", onUploadJointsCommit, this);
  385. childSetCommitCallback("import_scale", onImportScaleCommit, this);
  386. childSetCommitCallback("pelvis_offset", onPelvisOffsetCommit, this);
  387. getChild<LLCheckBoxCtrl>("show_edges")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
  388. getChild<LLCheckBoxCtrl>("show_physics")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
  389. getChild<LLCheckBoxCtrl>("show_textures")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
  390. getChild<LLCheckBoxCtrl>("show_skin_weight")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
  391. getChild<LLCheckBoxCtrl>("show_joint_positions")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
  392. childDisable("upload_skin");
  393. childDisable("upload_joints");
  394. initDecompControls();
  395. LLView* preview_panel = getChild<LLView>("preview_panel");
  396. mPreviewRect = preview_panel->getRect();
  397. initModelPreview();
  398. //set callbacks for left click on line editor rows
  399. for (U32 i = 0; i <= LLModel::LOD_HIGH; i++)
  400. {
  401. LLTextBox* text = getChild<LLTextBox>(lod_label_name[i]);
  402. if (text)
  403. {
  404. text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i));
  405. }
  406. text = getChild<LLTextBox>(lod_triangles_name[i]);
  407. if (text)
  408. {
  409. text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i));
  410. }
  411. text = getChild<LLTextBox>(lod_vertices_name[i]);
  412. if (text)
  413. {
  414. text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i));
  415. }
  416. text = getChild<LLTextBox>(lod_status_name[i]);
  417. if (text)
  418. {
  419. text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i));
  420. }
  421. }
  422. std::string current_grid = LLGridManager::getInstance()->getGridLabel();
  423. std::transform(current_grid.begin(),current_grid.end(),current_grid.begin(),::tolower);
  424. std::string validate_url;
  425. if (current_grid == "agni")
  426. {
  427. validate_url = "http://secondlife.com/my/account/mesh.php";
  428. }
  429. else if (current_grid == "damballah")
  430. {
  431. // Staging grid has its own naming scheme.
  432. validate_url = "http://secondlife-staging.com/my/account/mesh.php";
  433. }
  434. else
  435. {
  436. validate_url = llformat("http://secondlife.%s.lindenlab.com/my/account/mesh.php",current_grid.c_str());
  437. }
  438. getChild<LLTextBox>("warning_message")->setTextArg("[VURL]", validate_url);
  439. mUploadBtn = getChild<LLButton>("ok_btn");
  440. mCalculateBtn = getChild<LLButton>("calculate_btn");
  441. mCalculateBtn->setClickedCallback(boost::bind(&LLFloaterModelPreview::onClickCalculateBtn, this));
  442. toggleCalculateButton(true);
  443. return TRUE;
  444. }
  445. //-----------------------------------------------------------------------------
  446. // LLFloaterModelPreview()
  447. //-----------------------------------------------------------------------------
  448. LLFloaterModelPreview::~LLFloaterModelPreview()
  449. {
  450. sInstance = NULL;
  451. if ( mModelPreview )
  452. {
  453. delete mModelPreview;
  454. }
  455. if (mGLName)
  456. {
  457. LLImageGL::deleteTextures(1, &mGLName );
  458. }
  459. delete mStatusLock;
  460. mStatusLock = NULL;
  461. }
  462. void LLFloaterModelPreview::initModelPreview()
  463. {
  464. if (mModelPreview)
  465. {
  466. delete mModelPreview;
  467. }
  468. mModelPreview = new LLModelPreview(512, 512, this );
  469. mModelPreview->setPreviewTarget(16.f);
  470. mModelPreview->setDetailsCallback(boost::bind(&LLFloaterModelPreview::setDetails, this, _1, _2, _3, _4, _5));
  471. mModelPreview->setModelUpdatedCallback(boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this, _1));
  472. }
  473. void LLFloaterModelPreview::onViewOptionChecked(LLUICtrl* ctrl)
  474. {
  475. if (mModelPreview)
  476. {
  477. mModelPreview->mViewOption[ctrl->getName()] = !mModelPreview->mViewOption[ctrl->getName()];
  478. mModelPreview->refresh();
  479. }
  480. }
  481. bool LLFloaterModelPreview::isViewOptionChecked(const LLSD& userdata)
  482. {
  483. if (mModelPreview)
  484. {
  485. return mModelPreview->mViewOption[userdata.asString()];
  486. }
  487. return false;
  488. }
  489. bool LLFloaterModelPreview::isViewOptionEnabled(const LLSD& userdata)
  490. {
  491. return childIsEnabled(userdata.asString());
  492. }
  493. void LLFloaterModelPreview::setViewOptionEnabled(const std::string& option, bool enabled)
  494. {
  495. childSetEnabled(option, enabled);
  496. }
  497. void LLFloaterModelPreview::enableViewOption(const std::string& option)
  498. {
  499. setViewOptionEnabled(option, true);
  500. }
  501. void LLFloaterModelPreview::disableViewOption(const std::string& option)
  502. {
  503. setViewOptionEnabled(option, false);
  504. }
  505. void LLFloaterModelPreview::loadModel(S32 lod)
  506. {
  507. mModelPreview->mLoading = true;
  508. (new LLMeshFilePicker(mModelPreview, lod))->getFile();
  509. }
  510. void LLFloaterModelPreview::loadModel(S32 lod, const std::string& file_name, bool force_disable_slm)
  511. {
  512. mModelPreview->mLoading = true;
  513. mModelPreview->loadModel(file_name, lod, force_disable_slm);
  514. }
  515. void LLFloaterModelPreview::onClickCalculateBtn()
  516. {
  517. mModelPreview->rebuildUploadData();
  518. bool upload_skinweights = childGetValue("upload_skin").asBoolean();
  519. bool upload_joint_positions = childGetValue("upload_joints").asBoolean();
  520. mUploadModelUrl.clear();
  521. gMeshRepo.uploadModel(mModelPreview->mUploadData, mModelPreview->mPreviewScale,
  522. childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions, mUploadModelUrl, false,
  523. getWholeModelFeeObserverHandle());
  524. toggleCalculateButton(false);
  525. mUploadBtn->setEnabled(false);
  526. }
  527. //static
  528. void LLFloaterModelPreview::onImportScaleCommit(LLUICtrl*,void* userdata)
  529. {
  530. LLFloaterModelPreview *fp =(LLFloaterModelPreview *)userdata;
  531. if (!fp->mModelPreview)
  532. {
  533. return;
  534. }
  535. fp->mModelPreview->mDirty = true;
  536. fp->toggleCalculateButton(true);
  537. fp->mModelPreview->refresh();
  538. }
  539. //static
  540. void LLFloaterModelPreview::onPelvisOffsetCommit( LLUICtrl*, void* userdata )
  541. {
  542. LLFloaterModelPreview *fp =(LLFloaterModelPreview*)userdata;
  543. if (!fp->mModelPreview)
  544. {
  545. return;
  546. }
  547. fp->mModelPreview->mDirty = true;
  548. fp->toggleCalculateButton(true);
  549. fp->mModelPreview->refresh();
  550. }
  551. //static
  552. void LLFloaterModelPreview::onUploadJointsCommit(LLUICtrl*,void* userdata)
  553. {
  554. LLFloaterModelPreview *fp =(LLFloaterModelPreview *)userdata;
  555. if (!fp->mModelPreview)
  556. {
  557. return;
  558. }
  559. fp->mModelPreview->refresh();
  560. }
  561. //static
  562. void LLFloaterModelPreview::onUploadSkinCommit(LLUICtrl*,void* userdata)
  563. {
  564. LLFloaterModelPreview *fp =(LLFloaterModelPreview *)userdata;
  565. if (!fp->mModelPreview)
  566. {
  567. return;
  568. }
  569. fp->mModelPreview->refresh();
  570. fp->mModelPreview->resetPreviewTarget();
  571. fp->mModelPreview->clearBuffers();
  572. }
  573. //static
  574. void LLFloaterModelPreview::onPreviewLODCommit(LLUICtrl* ctrl, void* userdata)
  575. {
  576. LLFloaterModelPreview *fp =(LLFloaterModelPreview *)userdata;
  577. if (!fp->mModelPreview)
  578. {
  579. return;
  580. }
  581. S32 which_mode = 0;
  582. LLComboBox* combo = (LLComboBox*) ctrl;
  583. which_mode = (NUM_LOD-1)-combo->getFirstSelectedIndex(); // combo box list of lods is in reverse order
  584. fp->mModelPreview->setPreviewLOD(which_mode);
  585. }
  586. //static
  587. void LLFloaterModelPreview::onGenerateNormalsCommit(LLUICtrl* ctrl, void* userdata)
  588. {
  589. LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata;
  590. fp->mModelPreview->generateNormals();
  591. }
  592. void LLFloaterModelPreview::toggleGenarateNormals()
  593. {
  594. bool enabled = childGetValue("gen_normals").asBoolean();
  595. childSetEnabled("crease_angle", enabled);
  596. }
  597. //static
  598. void LLFloaterModelPreview::onExplodeCommit(LLUICtrl* ctrl, void* userdata)
  599. {
  600. LLFloaterModelPreview* fp = LLFloaterModelPreview::sInstance;
  601. fp->mModelPreview->refresh();
  602. }
  603. //static
  604. void LLFloaterModelPreview::onAutoFillCommit(LLUICtrl* ctrl, void* userdata)
  605. {
  606. LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata;
  607. fp->mModelPreview->genLODs();
  608. }
  609. void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
  610. {
  611. mModelPreview->onLODParamCommit(lod, enforce_tri_limit);
  612. }
  613. //-----------------------------------------------------------------------------
  614. // draw()
  615. //-----------------------------------------------------------------------------
  616. void LLFloaterModelPreview::draw()
  617. {
  618. LLFloater::draw();
  619. LLRect r = getRect();
  620. mModelPreview->update();
  621. if (!mModelPreview->mLoading)
  622. {
  623. if ( mModelPreview->getLoadState() == LLModelLoader::ERROR_MATERIALS )
  624. {
  625. childSetTextArg("status", "[STATUS]", getString("status_material_mismatch"));
  626. }
  627. else
  628. if ( mModelPreview->getLoadState() > LLModelLoader::ERROR_PARSING )
  629. {
  630. childSetTextArg("status", "[STATUS]", getString(LLModel::getStatusString(mModelPreview->getLoadState() - LLModelLoader::ERROR_PARSING)));
  631. }
  632. else
  633. if ( mModelPreview->getLoadState() == LLModelLoader::ERROR_PARSING )
  634. {
  635. childSetTextArg("status", "[STATUS]", getString("status_parse_error"));
  636. toggleCalculateButton(false);
  637. }
  638. else
  639. {
  640. childSetTextArg("status", "[STATUS]", getString("status_idle"));
  641. }
  642. }
  643. childSetTextArg("prim_cost", "[PRIM_COST]", llformat("%d", mModelPreview->mResourceCost));
  644. childSetTextArg("description_label", "[TEXTURES]", llformat("%d", mModelPreview->mTextureSet.size()));
  645. if (mModelPreview)
  646. {
  647. gGL.color3f(1.f, 1.f, 1.f);
  648. gGL.getTexUnit(0)->bind(mModelPreview);
  649. LLView* preview_panel = getChild<LLView>("preview_panel");
  650. LLRect rect = preview_panel->getRect();
  651. if (rect != mPreviewRect)
  652. {
  653. mModelPreview->refresh();
  654. mPreviewRect = preview_panel->getRect();
  655. }
  656. gGL.begin( LLRender::QUADS );
  657. {
  658. gGL.texCoord2f(0.f, 1.f);
  659. gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop-1);
  660. gGL.texCoord2f(0.f, 0.f);
  661. gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mBottom);
  662. gGL.texCoord2f(1.f, 0.f);
  663. gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mBottom);
  664. gGL.texCoord2f(1.f, 1.f);
  665. gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mTop-1);
  666. }
  667. gGL.end();
  668. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  669. }
  670. }
  671. //-----------------------------------------------------------------------------
  672. // handleMouseDown()
  673. //-----------------------------------------------------------------------------
  674. BOOL LLFloaterModelPreview::handleMouseDown(S32 x, S32 y, MASK mask)
  675. {
  676. if (mPreviewRect.pointInRect(x, y))
  677. {
  678. bringToFront( x, y );
  679. gFocusMgr.setMouseCapture(this);
  680. gViewerWindow->hideCursor();
  681. mLastMouseX = x;
  682. mLastMouseY = y;
  683. return TRUE;
  684. }
  685. return LLFloater::handleMouseDown(x, y, mask);
  686. }
  687. //-----------------------------------------------------------------------------
  688. // handleMouseUp()
  689. //-----------------------------------------------------------------------------
  690. BOOL LLFloaterModelPreview::handleMouseUp(S32 x, S32 y, MASK mask)
  691. {
  692. gFocusMgr.setMouseCapture(FALSE);
  693. gViewerWindow->showCursor();
  694. return LLFloater::handleMouseUp(x, y, mask);
  695. }
  696. //-----------------------------------------------------------------------------
  697. // handleHover()
  698. //-----------------------------------------------------------------------------
  699. BOOL LLFloaterModelPreview::handleHover (S32 x, S32 y, MASK mask)
  700. {
  701. MASK local_mask = mask & ~MASK_ALT;
  702. if (mModelPreview && hasMouseCapture())
  703. {
  704. if (local_mask == MASK_PAN)
  705. {
  706. // pan here
  707. mModelPreview->pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f);
  708. }
  709. else if (local_mask == MASK_ORBIT)
  710. {
  711. F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f;
  712. F32 pitch_radians = (F32)(y - mLastMouseY) * 0.02f;
  713. mModelPreview->rotate(yaw_radians, pitch_radians);
  714. }
  715. else
  716. {
  717. F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f;
  718. F32 zoom_amt = (F32)(y - mLastMouseY) * 0.02f;
  719. mModelPreview->rotate(yaw_radians, 0.f);
  720. mModelPreview->zoom(zoom_amt);
  721. }
  722. mModelPreview->refresh();
  723. LLUI::setMousePositionLocal(this, mLastMouseX, mLastMouseY);
  724. }
  725. if (!mPreviewRect.pointInRect(x, y) || !mModelPreview)
  726. {
  727. return LLFloater::handleHover(x, y, mask);
  728. }
  729. else if (local_mask == MASK_ORBIT)
  730. {
  731. gViewerWindow->setCursor(UI_CURSOR_TOOLCAMERA);
  732. }
  733. else if (local_mask == MASK_PAN)
  734. {
  735. gViewerWindow->setCursor(UI_CURSOR_TOOLPAN);
  736. }
  737. else
  738. {
  739. gViewerWindow->setCursor(UI_CURSOR_TOOLZOOMIN);
  740. }
  741. return TRUE;
  742. }
  743. //-----------------------------------------------------------------------------
  744. // handleScrollWheel()
  745. //-----------------------------------------------------------------------------
  746. BOOL LLFloaterModelPreview::handleScrollWheel(S32 x, S32 y, S32 clicks)
  747. {
  748. if (mPreviewRect.pointInRect(x, y) && mModelPreview)
  749. {
  750. mModelPreview->zoom((F32)clicks * -0.2f);
  751. mModelPreview->refresh();
  752. }
  753. return TRUE;
  754. }
  755. /*virtual*/
  756. void LLFloaterModelPreview::onOpen(const LLSD& key)
  757. {
  758. requestAgentUploadPermissions();
  759. }
  760. //static
  761. void LLFloaterModelPreview::onPhysicsParamCommit(LLUICtrl* ctrl, void* data)
  762. {
  763. if (LLConvexDecomposition::getInstance() == NULL)
  764. {
  765. llinfos << "convex decomposition tool is a stub on this platform. cannot get decomp." << llendl;
  766. return;
  767. }
  768. if (sInstance)
  769. {
  770. LLCDParam* param = (LLCDParam*) data;
  771. std::string name(param->mName);
  772. LLSD value = ctrl->getValue();
  773. if("Retain%" == name)
  774. {
  775. value = ctrl->getValue().asReal() / RETAIN_COEFFICIENT;
  776. }
  777. sInstance->mDecompParams[name] = value;
  778. if (name == "Simplify Method")
  779. {
  780. bool show_retain = false;
  781. bool show_detail = true;
  782. if (ctrl->getValue().asInteger() == 0)
  783. {
  784. show_retain = true;
  785. show_detail = false;
  786. }
  787. sInstance->childSetVisible("Retain%", show_retain);
  788. sInstance->childSetVisible("Retain%_label", show_retain);
  789. sInstance->childSetVisible("Detail Scale", show_detail);
  790. sInstance->childSetVisible("Detail Scale label", show_detail);
  791. }
  792. }
  793. }
  794. //static
  795. void LLFloaterModelPreview::onPhysicsStageExecute(LLUICtrl* ctrl, void* data)
  796. {
  797. LLCDStageData* stage_data = (LLCDStageData*) data;
  798. std::string stage = stage_data->mName;
  799. if (sInstance)
  800. {
  801. if (!sInstance->mCurRequest.empty())
  802. {
  803. llinfos << "Decomposition request still pending." << llendl;
  804. return;
  805. }
  806. if (sInstance->mModelPreview)
  807. {
  808. for (S32 i = 0; i < sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS].size(); ++i)
  809. {
  810. LLModel* mdl = sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS][i];
  811. DecompRequest* request = new DecompRequest(stage, mdl);
  812. sInstance->mCurRequest.insert(request);
  813. gMeshRepo.mDecompThread->submitRequest(request);
  814. }
  815. }
  816. if (stage == "Decompose")
  817. {
  818. sInstance->setStatusMessage(sInstance->getString("decomposing"));
  819. sInstance->childSetVisible("Decompose", false);
  820. sInstance->childSetVisible("decompose_cancel", true);
  821. sInstance->childDisable("Simplify");
  822. }
  823. else if (stage == "Simplify")
  824. {
  825. sInstance->setStatusMessage(sInstance->getString("simplifying"));
  826. sInstance->childSetVisible("Simplify", false);
  827. sInstance->childSetVisible("simplify_cancel", true);
  828. sInstance->childDisable("Decompose");
  829. }
  830. }
  831. }
  832. //static
  833. void LLFloaterModelPreview::onPhysicsBrowse(LLUICtrl* ctrl, void* userdata)
  834. {
  835. sInstance->loadModel(LLModel::LOD_PHYSICS);
  836. }
  837. //static
  838. void LLFloaterModelPreview::onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata)
  839. {
  840. S32 num_lods = 4;
  841. S32 which_mode;
  842. LLCtrlSelectionInterface* iface = sInstance->childGetSelectionInterface("physics_lod_combo");
  843. if (iface)
  844. {
  845. which_mode = iface->getFirstSelectedIndex();
  846. }
  847. else
  848. {
  849. llwarns << "no iface" << llendl;
  850. return;
  851. }
  852. if (which_mode <= 0)
  853. {
  854. llwarns << "which_mode out of range, " << which_mode << llendl;
  855. }
  856. S32 file_mode = iface->getItemCount() - 1;
  857. if (which_mode < file_mode)
  858. {
  859. S32 which_lod = num_lods - which_mode;
  860. sInstance->mModelPreview->setPhysicsFromLOD(which_lod);
  861. }
  862. LLModelPreview *model_preview = sInstance->mModelPreview;
  863. if (model_preview)
  864. {
  865. model_preview->refresh();
  866. model_preview->updateStatusMessages();
  867. }
  868. }
  869. //static
  870. void LLFloaterModelPreview::onCancel(LLUICtrl* ctrl, void* data)
  871. {
  872. if (sInstance)
  873. {
  874. sInstance->closeFloater(false);
  875. }
  876. }
  877. //static
  878. void LLFloaterModelPreview::onPhysicsStageCancel(LLUICtrl* ctrl, void*data)
  879. {
  880. if (sInstance)
  881. {
  882. for (std::set<LLPointer<DecompRequest> >::iterator iter = sInstance->mCurRequest.begin();
  883. iter != sInstance->mCurRequest.end(); ++iter)
  884. {
  885. DecompRequest* req = *iter;
  886. req->mContinue = 0;
  887. }
  888. sInstance->mCurRequest.clear();
  889. if (sInstance->mModelPreview)
  890. {
  891. sInstance->mModelPreview->updateStatusMessages();
  892. }
  893. }
  894. }
  895. void LLFloaterModelPreview::initDecompControls()
  896. {
  897. LLSD key;
  898. childSetCommitCallback("simplify_cancel", onPhysicsStageCancel, NULL);
  899. childSetCommitCallback("decompose_cancel", onPhysicsStageCancel, NULL);
  900. childSetCommitCallback("physics_lod_combo", onPhysicsUseLOD, NULL);
  901. childSetCommitCallback("physics_browse", onPhysicsBrowse, NULL);
  902. static const LLCDStageData* stage = NULL;
  903. static S32 stage_count = 0;
  904. if (!stage && LLConvexDecomposition::getInstance() != NULL)
  905. {
  906. stage_count = LLConvexDecomposition::getInstance()->getStages(&stage);
  907. }
  908. static const LLCDParam* param = NULL;
  909. static S32 param_count = 0;
  910. if (!param && LLConvexDecomposition::getInstance() != NULL)
  911. {
  912. param_count = LLConvexDecomposition::getInstance()->getParameters(&param);
  913. }
  914. for (S32 j = stage_count-1; j >= 0; --j)
  915. {
  916. LLButton* button = getChild<LLButton>(stage[j].mName);
  917. if (button)
  918. {
  919. button->setCommitCallback(onPhysicsStageExecute, (void*) &stage[j]);
  920. }
  921. gMeshRepo.mDecompThread->mStageID[stage[j].mName] = j;
  922. // protected against stub by stage_count being 0 for stub above
  923. LLConvexDecomposition::getInstance()->registerCallback(j, LLPhysicsDecomp::llcdCallback);
  924. //llinfos << "Physics decomp stage " << stage[j].mName << " (" << j << ") parameters:" << llendl;
  925. //llinfos << "------------------------------------" << llendl;
  926. for (S32 i = 0; i < param_count; ++i)
  927. {
  928. if (param[i].mStage != j)
  929. {
  930. continue;
  931. }
  932. std::string name(param[i].mName ? param[i].mName : "");
  933. std::string description(param[i].mDescription ? param[i].mDescription : "");
  934. std::string type = "unknown";
  935. llinfos << name << " - " << description << llendl;
  936. if (param[i].mType == LLCDParam::LLCD_FLOAT)
  937. {
  938. mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mFloat);
  939. //llinfos << "Type: float, Default: " << param[i].mDefault.mFloat << llendl;
  940. LLUICtrl* ctrl = getChild<LLUICtrl>(name);
  941. if (LLSliderCtrl* slider = dynamic_cast<LLSliderCtrl*>(ctrl))
  942. {
  943. slider->setMinValue(param[i].mDetails.mRange.mLow.mFloat);
  944. slider->setMaxValue(param[i].mDetails.mRange.mHigh.mFloat);
  945. slider->setIncrement(param[i].mDetails.mRange.mDelta.mFloat);
  946. slider->setValue(param[i].mDefault.mFloat);
  947. slider->setCommitCallback(onPhysicsParamCommit, (void*) &param[i]);
  948. }
  949. else if (LLSpinCtrl* spinner = dynamic_cast<LLSpinCtrl*>(ctrl))
  950. {
  951. bool is_retain_ctrl = "Retain%" == name;
  952. double coefficient = is_retain_ctrl ? RETAIN_COEFFICIENT : 1.f;
  953. spinner->setMinValue(param[i].mDetails.mRange.mLow.mFloat * coefficient);
  954. spinner->setMaxValue(param[i].mDetails.mRange.mHigh.mFloat * coefficient);
  955. spinner->setIncrement(param[i].mDetails.mRange.mDelta.mFloat * coefficient);
  956. spinner->setValue(param[i].mDefault.mFloat * coefficient);
  957. spinner->setCommitCallback(onPhysicsParamCommit, (void*) &param[i]);
  958. }
  959. else if (LLComboBox* combo_box = dynamic_cast<LLComboBox*>(ctrl))
  960. {
  961. float min = param[i].mDetails.mRange.mLow.mFloat;
  962. float max = param[i].mDetails.mRange.mHigh.mFloat;
  963. float delta = param[i].mDetails.mRange.mDelta.mFloat;
  964. if ("Cosine%" == name)
  965. {
  966. createSmoothComboBox(combo_box, min, max);
  967. }
  968. else
  969. {
  970. for(float value = min; value <= max; value += delta)
  971. {
  972. std::string label = llformat("%.1f", value);
  973. combo_box->add(label, value, ADD_BOTTOM, true);
  974. }
  975. combo_box->setValue(param[i].mDefault.mFloat);
  976. }
  977. combo_box->setCommitCallback(onPhysicsParamCommit, (void*) &param[i]);
  978. }
  979. }
  980. else if (param[i].mType == LLCDParam::LLCD_INTEGER)
  981. {
  982. mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue);
  983. //llinfos << "Type: integer, Default: " << param[i].mDefault.mIntOrEnumValue << llendl;
  984. LLUICtrl* ctrl = getChild<LLUICtrl>(name);
  985. if (LLSliderCtrl* slider = dynamic_cast<LLSliderCtrl*>(ctrl))
  986. {
  987. slider->setMinValue(param[i].mDetails.mRange.mLow.mIntOrEnumValue);
  988. slider->setMaxValue(param[i].mDetails.mRange.mHigh.mIntOrEnumValue);
  989. slider->setIncrement(param[i].mDetails.mRange.mDelta.mIntOrEnumValue);
  990. slider->setValue(param[i].mDefault.mIntOrEnumValue);
  991. slider->setCommitCallback(onPhysicsParamCommit, (void*) &param[i]);
  992. }
  993. else if (LLComboBox* combo_box = dynamic_cast<LLComboBox*>(ctrl))
  994. {
  995. for(int k = param[i].mDetails.mRange.mLow.mIntOrEnumValue; k<=param[i].mDetails.mRange.mHigh.mIntOrEnumValue; k+=param[i].mDetails.mRange.mDelta.mIntOrEnumValue)
  996. {
  997. std::string name = llformat("%.1d", k);
  998. combo_box->add(name, k, ADD_BOTTOM, true);
  999. }
  1000. combo_box->setValue(param[i].mDefault.mIntOrEnumValue);
  1001. combo_box->setCommitCallback(onPhysicsParamCommit, (void*) &param[i]);
  1002. }
  1003. }
  1004. else if (param[i].mType == LLCDParam::LLCD_BOOLEAN)
  1005. {
  1006. mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mBool);
  1007. //llinfos << "Type: boolean, Default: " << (param[i].mDefault.mBool ? "True" : "False") << llendl;
  1008. LLCheckBoxCtrl* check_box = getChild<LLCheckBoxCtrl>(name);
  1009. if (check_box)
  1010. {
  1011. check_box->setValue(param[i].mDefault.mBool);
  1012. check_box->setCommitCallback(onPhysicsParamCommit, (void*) &param[i]);
  1013. }
  1014. }
  1015. else if (param[i].mType == LLCDParam::LLCD_ENUM)
  1016. {
  1017. mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue);
  1018. //llinfos << "Type: enum, Default: " << param[i].mDefault.mIntOrEnumValue << llendl;
  1019. { //plug into combo box
  1020. //llinfos << "Accepted values: " << llendl;
  1021. LLComboBox* combo_box = getChild<LLComboBox>(name);
  1022. for (S32 k = 0; k < param[i].mDetails.mEnumValues.mNumEnums; ++k)
  1023. {
  1024. //llinfos << param[i].mDetails.mEnumValues.mEnumsArray[k].mValue
  1025. // << " - " << param[i].mDetails.mEnumValues.mEnumsArray[k].mName << llendl;
  1026. std::string name(param[i].mDetails.mEnumValues.mEnumsArray[k].mName);
  1027. std::string localized_name;
  1028. bool is_localized = LLTrans::findString(localized_name, name);
  1029. combo_box->add(is_localized ? localized_name : name,
  1030. LLSD::Integer(param[i].mDetails.mEnumValues.mEnumsArray[k].mValue));
  1031. }
  1032. combo_box->setValue(param[i].mDefault.mIntOrEnumValue);
  1033. combo_box->setCommitCallback(onPhysicsParamCommit, (void*) &param[i]);
  1034. }
  1035. //llinfos << "----" << llendl;
  1036. }
  1037. //llinfos << "-----------------------------" << llendl;
  1038. }
  1039. }
  1040. childSetCommitCallback("physics_explode", LLFloaterModelPreview::onExplodeCommit, this);
  1041. }
  1042. void LLFloaterModelPreview::createSmoothComboBox(LLComboBox* combo_box, float min, float max)
  1043. {
  1044. float delta = (max - min) / SMOOTH_VALUES_NUMBER;
  1045. int ilabel = 0;
  1046. combo_box->add("0 (none)", ADD_BOTTOM, true);
  1047. for(float value = min + delta; value < max; value += delta)
  1048. {
  1049. std::string label = (++ilabel == SMOOTH_VALUES_NUMBER) ? "10 (max)" : llformat("%.1d", ilabel);
  1050. combo_box->add(label, value, ADD_BOTTOM, true);
  1051. }
  1052. }
  1053. //-----------------------------------------------------------------------------
  1054. // onMouseCaptureLost()
  1055. //-----------------------------------------------------------------------------
  1056. // static
  1057. void LLFloaterModelPreview::onMouseCaptureLostModelPreview(LLMouseHandler* handler)
  1058. {
  1059. gViewerWindow->showCursor();
  1060. }
  1061. //-----------------------------------------------------------------------------
  1062. // LLModelLoader
  1063. //-----------------------------------------------------------------------------
  1064. LLModelLoader::LLModelLoader( std::string filename, S32 lod, LLModelPreview* preview, JointTransformMap& jointMap,
  1065. std::deque<std::string>& jointsFromNodes )
  1066. : mJointList( jointMap )
  1067. , mJointsFromNode( jointsFromNodes )
  1068. , LLThread("Model Loader"), mFilename(filename), mLod(lod), mPreview(preview), mFirstTransform(TRUE), mNumOfFetchingTextures(0)
  1069. {
  1070. mJointMap["mPelvis"] = "mPelvis";
  1071. mJointMap["mTorso"] = "mTorso";
  1072. mJointMap["mChest"] = "mChest";
  1073. mJointMap["mNeck"] = "mNeck";
  1074. mJointMap["mHead"] = "mHead";
  1075. mJointMap["mSkull"] = "mSkull";
  1076. mJointMap["mEyeRight"] = "mEyeRight";
  1077. mJointMap["mEyeLeft"] = "mEyeLeft";
  1078. mJointMap["mCollarLeft"] = "mCollarLeft";
  1079. mJointMap["mShoulderLeft"] = "mShoulderLeft";
  1080. mJointMap["mElbowLeft"] = "mElbowLeft";
  1081. mJointMap["mWristLeft"] = "mWristLeft";
  1082. mJointMap["mCollarRight"] = "mCollarRight";
  1083. mJointMap["mShoulderRight"] = "mShoulderRight";
  1084. mJointMap["mElbowRight"] = "mElbowRight";
  1085. mJointMap["mWristRight"] = "mWristRight";
  1086. mJointMap["mHipRight"] = "mHipRight";
  1087. mJointMap["mKneeRight"] = "mKneeRight";
  1088. mJointMap["mAnkleRight"] = "mAnkleRight";
  1089. mJointMap["mFootRight"] = "mFootRight";
  1090. mJointMap["mToeRight"] = "mToeRight";
  1091. mJointMap["mHipLeft"] = "mHipLeft";
  1092. mJointMap["mKneeLeft"] = "mKneeLeft";
  1093. mJointMap["mAnkleLeft"] = "mAnkleLeft";
  1094. mJointMap["mFootLeft"] = "mFootLeft";
  1095. mJointMap["mToeLeft"] = "mToeLeft";
  1096. mJointMap["avatar_mPelvis"] = "mPelvis";
  1097. mJointMap["avatar_mTorso"] = "mTorso";
  1098. mJointMap["avatar_mChest"] = "mChest";
  1099. mJointMap["avatar_mNeck"] = "mNeck";
  1100. mJointMap["avatar_mHead"] = "mHead";
  1101. mJointMap["avatar_mSkull"] = "mSkull";
  1102. mJointMap["avatar_mEyeRight"] = "mEyeRight";
  1103. mJointMap["avatar_mEyeLeft"] = "mEyeLeft";
  1104. mJointMap["avatar_mCollarLeft"] = "mCollarLeft";
  1105. mJointMap["avatar_mShoulderLeft"] = "mShoulderLeft";
  1106. mJointMap["avatar_mElbowLeft"] = "mElbowLeft";
  1107. mJointMap["avatar_mWristLeft"] = "mWristLeft";
  1108. mJointMap["avatar_mCollarRight"] = "mCollarRight";
  1109. mJointMap["avatar_mShoulderRight"] = "mShoulderRight";
  1110. mJointMap["avatar_mElbowRight"] = "mElbowRight";
  1111. mJointMap["avatar_mWristRight"] = "mWristRight";
  1112. mJointMap["avatar_mHipRight"] = "mHipRight";
  1113. mJointMap["avatar_mKneeRight"] = "mKneeRight";
  1114. mJointMap["avatar_mAnkleRight"] = "mAnkleRight";
  1115. mJointMap["avatar_mFootRight"] = "mFootRight";
  1116. mJointMap["avatar_mToeRight"] = "mToeRight";
  1117. mJointMap["avatar_mHipLeft"] = "mHipLeft";
  1118. mJointMap["avatar_mKneeLeft"] = "mKneeLeft";
  1119. mJointMap["avatar_mAnkleLeft"] = "mAnkleLeft";
  1120. mJointMap["avatar_mFootLeft"] = "mFootLeft";
  1121. mJointMap["avatar_mToeLeft"] = "mToeLeft";
  1122. mJointMap["hip"] = "mPelvis";
  1123. mJointMap["abdomen"] = "mTorso";
  1124. mJointMap["chest"] = "mChest";
  1125. mJointMap["neck"] = "mNeck";
  1126. mJointMap["head"] = "mHead";
  1127. mJointMap["figureHair"] = "mSkull";
  1128. mJointMap["lCollar"] = "mCollarLeft";
  1129. mJointMap["lShldr"] = "mShoulderLeft";
  1130. mJointMap["lForeArm"] = "mElbowLeft";
  1131. mJointMap["lHand"] = "mWristLeft";
  1132. mJointMap["rCollar"] = "mCollarRight";
  1133. mJointMap["rShldr"] = "mShoulderRight";
  1134. mJointMap["rForeArm"] = "mElbowRight";
  1135. mJointMap["rHand"] = "mWristRight";
  1136. mJointMap["rThigh"] = "mHipRight";
  1137. mJointMap["rShin"] = "mKneeRight";
  1138. mJointMap["rFoot"] = "mFootRight";
  1139. mJointMap["lThigh"] = "mHipLeft";
  1140. mJointMap["lShin"] = "mKneeLeft";
  1141. mJointMap["lFoot"] = "mFootLeft";
  1142. if (mPreview)
  1143. {
  1144. //only try to load from slm if viewer is configured to do so and this is the
  1145. //initial model load (not an LoD or physics shape)
  1146. mTrySLM = gSavedSettings.getBOOL("MeshImportUseSLM") && mPreview->mUploadData.empty();
  1147. mPreview->setLoadState(STARTING);
  1148. }
  1149. else
  1150. {
  1151. mTrySLM = false;
  1152. }
  1153. assert_main_thread();
  1154. sActiveLoaderList.push_back(this) ;
  1155. }
  1156. LLModelLoader::~LLModelLoader()
  1157. {
  1158. assert_main_thread();
  1159. sActiveLoaderList.remove(this);
  1160. }
  1161. void stretch_extents(LLModel* model, LLMatrix4a& mat, LLVector4a& min, LLVector4a& max, BOOL& first_transform)
  1162. {
  1163. LLVector4a box[] =
  1164. {
  1165. LLVector4a(-1, 1,-1),
  1166. LLVector4a(-1, 1, 1),
  1167. LLVector4a(-1,-1,-1),
  1168. LLVector4a(-1,-1, 1),
  1169. LLVector4a( 1, 1,-1),
  1170. LLVector4a( 1, 1, 1),
  1171. LLVector4a( 1,-1,-1),
  1172. LLVector4a( 1,-1, 1),
  1173. };
  1174. for (S32 j = 0; j < model->getNumVolumeFaces(); ++j)
  1175. {
  1176. const LLVolumeFace& face = model->getVolumeFace(j);
  1177. LLVector4a center;
  1178. center.setAdd(face.mExtents[0], face.mExtents[1]);
  1179. center.mul(0.5f);
  1180. LLVector4a size;
  1181. size.setSub(face.mExtents[1],face.mExtents[0]);
  1182. size.mul(0.5f);
  1183. for (U32 i = 0; i < 8; i++)
  1184. {
  1185. LLVector4a t;
  1186. t.setMul(size, box[i]);
  1187. t.add(center);
  1188. LLVector4a v;
  1189. mat.affineTransform(t, v);
  1190. if (first_transform)
  1191. {
  1192. first_transform = FALSE;
  1193. min = max = v;
  1194. }
  1195. else
  1196. {
  1197. update_min_max(min, max, v);
  1198. }
  1199. }
  1200. }
  1201. }
  1202. void stretch_extents(LLModel* model, LLMatrix4& mat, LLVector3& min, LLVector3& max, BOOL& first_transform)
  1203. {
  1204. LLVector4a mina, maxa;
  1205. LLMatrix4a mata;
  1206. mata.loadu(mat);
  1207. mina.load3(min.mV);
  1208. maxa.load3(max.mV);
  1209. stretch_extents(model, mata, mina, maxa, first_transform);
  1210. min.set(mina.getF32ptr());
  1211. max.set(maxa.getF32ptr());
  1212. }
  1213. void LLModelLoader::run()
  1214. {
  1215. doLoadModel();
  1216. doOnIdleOneTime(boost::bind(&LLModelLoader::loadModelCallback,this));
  1217. }
  1218. bool LLModelLoader::doLoadModel()
  1219. {
  1220. //first, look for a .slm file of the same name that was modified later
  1221. //than the .dae
  1222. if (mTrySLM)
  1223. {
  1224. std::string filename = mFilename;
  1225. std::string::size_type i = filename.rfind(".");
  1226. if (i != std::string::npos)
  1227. {
  1228. filename.replace(i, filename.size()-1, ".slm");
  1229. llstat slm_status;
  1230. if (LLFile::stat(filename, &slm_status) == 0)
  1231. { //slm file exists
  1232. llstat dae_status;
  1233. if (LLFile::stat(mFilename, &dae_status) != 0 ||
  1234. dae_status.st_mtime < slm_status.st_mtime)
  1235. {
  1236. if (loadFromSLM(filename))
  1237. { //slm successfully loaded, if this fails, fall through and
  1238. //try loading from dae
  1239. mLod = -1; //successfully loading from an slm implicitly sets all
  1240. //LoDs
  1241. return true;
  1242. }
  1243. }
  1244. }
  1245. }
  1246. }
  1247. //no suitable slm exists, load from the .dae file
  1248. DAE dae;
  1249. domCOLLADA* dom = dae.open(mFilename);
  1250. if (!dom)
  1251. {
  1252. llinfos<<" Error with dae - traditionally indicates a corrupt file."<<llendl;
  1253. setLoadState( ERROR_PARSING );
  1254. return false;
  1255. }
  1256. //Dom version
  1257. daeString domVersion = dae.getDomVersion();
  1258. std::string sldom(domVersion);
  1259. llinfos<<"Collada Importer Version: "<<sldom<<llendl;
  1260. //Dae version
  1261. domVersionType docVersion = dom->getVersion();
  1262. //0=1.4
  1263. //1=1.4.1
  1264. //2=Currently unsupported, however may work
  1265. if (docVersion > 1 )
  1266. {
  1267. docVersion = VERSIONTYPE_COUNT;
  1268. }
  1269. llinfos<<"Dae version "<<colladaVersion[docVersion]<<llendl;
  1270. daeDatabase* db = dae.getDatabase();
  1271. daeInt count = db->getElementCount(NULL, COLLADA_TYPE_MESH);
  1272. daeDocument* doc = dae.getDoc(mFilename);
  1273. if (!doc)
  1274. {
  1275. llwarns << "can't find internal doc" << llendl;
  1276. return false;
  1277. }
  1278. daeElement* root = doc->getDomRoot();
  1279. if (!root)
  1280. {
  1281. llwarns << "document has no root" << llendl;
  1282. return false;
  1283. }
  1284. //Verify some basic properties of the dae
  1285. //1. Basic validity check on controller
  1286. U32 controllerCount = (int) db->getElementCount( NULL, "controller" );
  1287. bool result = false;
  1288. for ( int i=0; i<controllerCount; ++i )
  1289. {
  1290. domController* pController = NULL;
  1291. db->getElement( (daeElement**) &pController, i , NULL, "controller" );
  1292. result = mPreview->verifyController( pController );
  1293. if (!result)
  1294. {
  1295. setLoadState( ERROR_PARSING );
  1296. return true;
  1297. }
  1298. }
  1299. //get unit scale
  1300. mTransform.setIdentity();
  1301. domAsset::domUnit* unit = daeSafeCast<domAsset::domUnit>(root->getDescendant(daeElement::matchType(domAsset::domUnit::ID())));
  1302. if (unit)
  1303. {
  1304. F32 meter = unit->getMeter();
  1305. mTransform.mMatrix[0][0] = meter;
  1306. mTransform.mMatrix[1][1] = meter;
  1307. mTransform.mMatrix[2][2] = meter;
  1308. }
  1309. //get up axis rotation
  1310. LLMatrix4 rotation;
  1311. domUpAxisType up = UPAXISTYPE_Y_UP; // default is Y_UP
  1312. domAsset::domUp_axis* up_axis =
  1313. daeSafeCast<domAsset::domUp_axis>(root->getDescendant(daeElement::matchType(domAsset::domUp_axis::ID())));
  1314. if (up_axis)
  1315. {
  1316. up = up_axis->getValue();
  1317. }
  1318. if (up == UPAXISTYPE_X_UP)
  1319. {
  1320. rotation.initRotation(0.0f, 90.0f * DEG_TO_RAD, 0.0f);
  1321. }
  1322. else if (up == UPAXISTYPE_Y_UP)
  1323. {
  1324. rotation.initRotation(90.0f * DEG_TO_RAD, 0.0f, 0.0f);
  1325. }
  1326. rotation *= mTransform;
  1327. mTransform = rotation;
  1328. for (daeInt idx = 0; idx < count; ++idx)
  1329. { //build map of domEntities to LLModel
  1330. domMesh* mesh = NULL;
  1331. db->getElement((daeElement**) &mesh, idx, NULL, COLLADA_TYPE_MESH);
  1332. if (mesh)
  1333. {
  1334. LLPointer<LLModel> model = LLModel::loadModelFromDomMesh(mesh);
  1335. if(model->getStatus() != LLModel::NO_ERRORS)
  1336. {
  1337. setLoadState(ERROR_PARSING + model->getStatus()) ;
  1338. return false; //abort
  1339. }
  1340. if (model.notNull() && validate_model(model))
  1341. {
  1342. mModelList.push_back(model);
  1343. mModel[mesh] = model;
  1344. }
  1345. }
  1346. }
  1347. count = db->getElementCount(NULL, COLLADA_TYPE_SKIN);
  1348. for (daeInt idx = 0; idx < count; ++idx)
  1349. { //add skinned meshes as instances
  1350. domSkin* skin = NULL;
  1351. db->getElement((daeElement**) &skin, idx, NULL, COLLADA_TYPE_SKIN);
  1352. if (skin)
  1353. {
  1354. domGeometry* geom = daeSafeCast<domGeometry>(skin->getSource().getElement());
  1355. if (geom)
  1356. {
  1357. domMesh* mesh = geom->getMesh();
  1358. if (mesh)
  1359. {
  1360. LLModel* model = mModel[mesh];
  1361. if (model)
  1362. {
  1363. LLVector3 mesh_scale_vector;
  1364. LLVector3 mesh_translation_vector;
  1365. model->getNormalizedScaleTranslation(mesh_scale_vector, mesh_translation_vector);
  1366. LLMatrix4 normalized_transformation;
  1367. normalized_transformation.setTranslation(mesh_translation_vector);
  1368. LLMatrix4 mesh_scale;
  1369. mesh_scale.initScale(mesh_scale_vector);
  1370. mesh_scale *= normalized_transformation;
  1371. normalized_transformation = mesh_scale;
  1372. glh::matrix4f inv_mat((F32*) normalized_transformation.mMatrix);
  1373. inv_mat = inv_mat.inverse();
  1374. LLMatrix4 inverse_normalized_transformation(inv_mat.m);
  1375. domSkin::domBind_shape_matrix* bind_mat = skin->getBind_shape_matrix();
  1376. if (bind_mat)
  1377. { //get bind shape matrix
  1378. domFloat4x4& dom_value = bind_mat->getValue();
  1379. LLMeshSkinInfo& skin_info = model->mSkinInfo;
  1380. for (int i = 0; i < 4; i++)
  1381. {
  1382. for(int j = 0; j < 4; j++)
  1383. {
  1384. skin_info.mBindShapeMatrix.mMatrix[i][j] = dom_value[i + j*4];
  1385. }
  1386. }
  1387. LLMatrix4 trans = normalized_transformation;
  1388. trans *= skin_info.mBindShapeMatrix;
  1389. skin_info.mBindShapeMatrix = trans;
  1390. }
  1391. //Some collada setup for accessing the skeleton
  1392. daeElement* pElement = 0;
  1393. dae.getDatabase()->getElement( &pElement, 0, 0, "skeleton" );
  1394. //Try to get at the skeletal instance controller
  1395. domInstance_controller::domSkeleton* pSkeleton = daeSafeCast<domInstance_controller::domSkeleton>( pElement );
  1396. bool missingSkeletonOrScene = false;
  1397. //If no skeleton, do a breadth-first search to get at specific joints
  1398. bool rootNode = false;
  1399. bool skeletonWithNoRootNode = false;
  1400. //Need to test for a skeleton that does not have a root node
  1401. //This occurs when your instance controller does not have an associated scene
  1402. if ( pSkeleton )
  1403. {
  1404. daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement();
  1405. if ( pSkeletonRootNode )
  1406. {
  1407. rootNode = true;
  1408. }
  1409. else
  1410. {
  1411. skeletonWithNoRootNode = true;
  1412. }
  1413. }
  1414. if ( !pSkeleton || !rootNode )
  1415. {
  1416. daeElement* pScene = root->getDescendant("visual_scene");
  1417. if ( !pScene )
  1418. {
  1419. llwarns<<"No visual scene - unable to parse bone offsets "<<llendl;
  1420. missingSkeletonOrScene = true;
  1421. }
  1422. else
  1423. {
  1424. //Get the children at this level
  1425. daeTArray< daeSmartRef<daeElement> > children = pScene->getChildren();
  1426. S32 childCount = children.getCount();
  1427. //Process any children that are joints
  1428. //Not all children are joints, some code be ambient lights, cameras, geometry etc..
  1429. for (S32 i = 0; i < childCount; ++i)
  1430. {
  1431. domNode* pNode = daeSafeCast<domNode>(children[i]);
  1432. if ( isNodeAJoint( pNode ) )
  1433. {
  1434. processJointNode( pNode, mJointList );
  1435. }
  1436. }
  1437. }
  1438. }
  1439. else
  1440. //Has Skeleton
  1441. {
  1442. //Get the root node of the skeleton
  1443. daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement();
  1444. if ( pSkeletonRootNode )
  1445. {
  1446. //Once we have the root node - start acccessing it's joint components
  1447. const int jointCnt = mJointMap.size();
  1448. std::map<std::string, std::string> :: const_iterator jointIt = mJointMap.begin();
  1449. //Loop over all the possible joints within the .dae - using the allowed joint list in the ctor.
  1450. for ( int i=0; i<jointCnt; ++i, ++jointIt )
  1451. {
  1452. //Build a joint for the resolver to work with
  1453. char str[64]={0};
  1454. sprintf(str,"./%s",(*jointIt).first.c_str() );
  1455. //llwarns<<"Joint "<< str <<llendl;
  1456. //Setup the resolver
  1457. daeSIDResolver resolver( pSkeletonRootNode, str );
  1458. //Look for the joint
  1459. domNode* pJoint = daeSafeCast<domNode>( resolver.getElement() );
  1460. if ( pJoint )
  1461. {
  1462. //Pull out the translate id and store it in the jointTranslations map
  1463. daeSIDResolver jointResolverA( pJoint, "./translate" );
  1464. domTranslate* pTranslateA = daeSafeCast<domTranslate>( jointResolverA.getElement() );
  1465. daeSIDResolver jointResolverB( pJoint, "./location" );
  1466. domTranslate* pTranslateB = daeSafeCast<domTranslate>( jointResolverB.getElement() );
  1467. LLMatrix4 workingTransform;
  1468. //Translation via SID
  1469. if ( pTranslateA )
  1470. {
  1471. extractTranslation( pTranslateA, workingTransform );
  1472. }
  1473. else
  1474. if ( pTranslateB )
  1475. {
  1476. extractTranslation( pTranslateB, workingTransform );
  1477. }
  1478. else
  1479. {
  1480. //Translation via child from element
  1481. daeElement* pTranslateElement = getChildFromElement( pJoint, "translate" );
  1482. if ( pTranslateElement && pTranslateElement->typeID() != domTranslate::ID() )
  1483. {
  1484. llwarns<< "The found element is not a translate node" <<llendl;
  1485. missingSkeletonOrScene = true;
  1486. }
  1487. else
  1488. if ( pTranslateElement )
  1489. {
  1490. extractTranslationViaElement( pTranslateElement, workingTransform );
  1491. }
  1492. else
  1493. {
  1494. extractTranslationViaSID( pJoint, workingTransform );
  1495. }
  1496. }
  1497. //Store the joint transform w/respect to it's name.
  1498. mJointList[(*jointIt).second.c_str()] = workingTransform;
  1499. }
  1500. }
  1501. //If anything failed in regards to extracting the skeleton, joints or translation id,
  1502. //mention it
  1503. if ( missingSkeletonOrScene )
  1504. {
  1505. llwarns<< "Partial jointmap found in asset - did you mean to just have a partial map?" << llendl;
  1506. }
  1507. }//got skeleton?
  1508. }
  1509. domSkin::domJoints* joints = skin->getJoints();
  1510. domInputLocal_Array& joint_input = joints->getInput_array();
  1511. for (size_t i = 0; i < joint_input.getCount(); ++i)
  1512. {
  1513. domInputLocal* input = joint_input.get(i);
  1514. xsNMTOKEN semantic = input->getSemantic();
  1515. if (strcmp(semantic, COMMON_PROFILE_INPUT_JOINT) == 0)
  1516. { //found joint source, fill model->mJointMap and model->mSkinInfo.mJointNames
  1517. daeElement* elem = input->getSource().getElement();
  1518. domSource* source = daeSafeCast<domSource>(elem);
  1519. if (source)
  1520. {
  1521. domName_array* names_source = source->getName_array();
  1522. if (names_source)
  1523. {
  1524. domListOfNames &names = names_source->getValue();
  1525. for (size_t j = 0; j < names.getCount(); ++j)
  1526. {
  1527. std::string name(names.get(j));
  1528. if (mJointMap.find(name) != mJointMap.end())
  1529. {
  1530. name = mJointMap[name];
  1531. }
  1532. model->mSkinInfo.mJointNames.push_back(name);
  1533. model->mSkinInfo.mJointMap[name] = j;
  1534. }
  1535. }
  1536. else
  1537. {
  1538. domIDREF_array* names_source = source->getIDREF_array();
  1539. if (names_source)
  1540. {
  1541. xsIDREFS& names = names_source->getValue();
  1542. for (size_t j = 0; j < names.getCount(); ++j)
  1543. {
  1544. std::string name(names.get(j).getID());
  1545. if (mJointMap.find(name) != mJointMap.end())
  1546. {
  1547. name = mJointMap[name];
  1548. }
  1549. model->mSkinInfo.mJointNames.push_back(name);
  1550. model->mSkinInfo.mJointMap[name] = j;
  1551. }
  1552. }
  1553. }
  1554. }
  1555. }
  1556. else if (strcmp(semantic, COMMON_PROFILE_INPUT_INV_BIND_MATRIX) == 0)
  1557. { //found inv_bind_matrix array, fill model->mInvBindMatrix
  1558. domSource* source = daeSafeCast<domSource>(input->getSource().getElement());
  1559. if (source)
  1560. {
  1561. domFloat_array* t = source->getFloat_array();
  1562. if (t)
  1563. {
  1564. domListOfFloats& transform = t->getValue();
  1565. S32 count = transform.getCount()/16;
  1566. for (S32 k = 0; k < count; ++k)
  1567. {
  1568. LLMatrix4 mat;
  1569. for (int i = 0; i < 4; i++)
  1570. {
  1571. for(int j = 0; j < 4; j++)
  1572. {
  1573. mat.mMatrix[i][j] = transform[k*16 + i + j*4];
  1574. }
  1575. }
  1576. model->mSkinInfo.mInvBindMatrix.push_back(mat);
  1577. }
  1578. }
  1579. }
  1580. }
  1581. }
  1582. //Now that we've parsed the joint array, let's determine if we have a full rig
  1583. //(which means we have all the joint sthat are required for an avatar versus
  1584. //a skinned asset attached to a node in a file that contains an entire skeleton,
  1585. //but does not use the skeleton).
  1586. buildJointToNodeMappingFromScene( root );
  1587. mPreview->critiqueRigForUploadApplicability( model->mSkinInfo.mJointNames );
  1588. if ( !missingSkeletonOrScene )
  1589. {
  1590. //Set the joint translations on the avatar - if it's a full mapping
  1591. //The joints are reset in the dtor
  1592. if ( mPreview->getRigWithSceneParity() )
  1593. {
  1594. std::map<std::string, std::string> :: const_iterator masterJointIt = mJointMap.begin();
  1595. std::map<std::string, std::string> :: const_iterator masterJointItEnd = mJointMap.end();
  1596. for (;masterJointIt!=masterJointItEnd;++masterJointIt )
  1597. {
  1598. std::string lookingForJoint = (*masterJointIt).first.c_str();
  1599. if ( mJointList.find( lookingForJoint ) != mJointList.end() )
  1600. {
  1601. //llinfos<<"joint "<<lookingForJoint.c_str()<<llendl;
  1602. LLMatrix4 jointTransform = mJointList[lookingForJoint];
  1603. LLJoint* pJoint = mPreview->getPreviewAvatar()->getJoint( lookingForJoint );
  1604. if ( pJoint )
  1605. {
  1606. pJoint->storeCurrentXform( jointTransform.getTranslation() );
  1607. }
  1608. else
  1609. {
  1610. //Most likely an error in the asset.
  1611. llwarns<<"Tried to apply joint position from .dae, but it did not exist in the avatar rig." << llendl;
  1612. }
  1613. }
  1614. }
  1615. }
  1616. } //missingSkeletonOrScene
  1617. //We need to construct the alternate bind matrix (which contains the new joint positions)
  1618. //in the same order as they were stored in the joint buffer. The joints associated
  1619. //with the skeleton are not stored in the same order as they are in the exported joint buffer.
  1620. //This remaps the skeletal joints to be in the same order as the joints stored in the model.
  1621. std::vector<std::string> :: const_iterator jointIt = model->mSkinInfo.mJointNames.begin();
  1622. const int jointCnt = model->mSkinInfo.mJointNames.size();
  1623. for ( int i=0; i<jointCnt; ++i, ++jointIt )
  1624. {
  1625. std::string lookingForJoint = (*jointIt).c_str();
  1626. //Look for the joint xform that we extracted from the skeleton, using the jointIt as the key
  1627. //and store it in the alternate bind matrix
  1628. if ( mJointList.find( lookingForJoint ) != mJointList.end() )
  1629. {
  1630. LLMatrix4 jointTransform = mJointList[lookingForJoint];
  1631. LLMatrix4 newInverse = model->mSkinInfo.mInvBindMatrix[i];
  1632. newInverse.setTranslation( mJointList[lookingForJoint].getTranslation() );
  1633. model->mSkinInfo.mAlternateBindMatrix.push_back( newInverse );
  1634. }
  1635. else
  1636. {
  1637. llwarns<<"Possibly misnamed/missing joint [" <<lookingForJoint.c_str()<<" ] "<<llendl;
  1638. }
  1639. }
  1640. //grab raw position array
  1641. domVertices* verts = mesh->getVertices();
  1642. if (verts)
  1643. {
  1644. domInputLocal_Array& inputs = verts->getInput_array();
  1645. for (size_t i = 0; i < inputs.getCount() && model->mPosition.empty(); ++i)
  1646. {
  1647. if (strcmp(inputs[i]->getSemantic(), COMMON_PROFILE_INPUT_POSITION) == 0)
  1648. {
  1649. domSource* pos_source = daeSafeCast<domSource>(inputs[i]->getSource().getElement());
  1650. if (pos_source)
  1651. {
  1652. domFloat_array* pos_array = pos_source->getFloat_array();
  1653. if (pos_array)
  1654. {
  1655. domListOfFloats& pos = pos_array->getValue();
  1656. for (size_t j = 0; j < pos.getCount(); j += 3)
  1657. {
  1658. if (pos.getCount() <= j+2)
  1659. {
  1660. llerrs << "Invalid position array size." << llendl;
  1661. }
  1662. LLVector3 v(pos[j], pos[j+1], pos[j+2]);
  1663. //transform from COLLADA space to volume space
  1664. v = v * inverse_normalized_transformation;
  1665. model->mPosition.push_back(v);
  1666. }
  1667. }
  1668. }
  1669. }
  1670. }
  1671. }
  1672. //grab skin weights array
  1673. domSkin::domVertex_weights* weights = skin->getVertex_weights();
  1674. if (weights)
  1675. {
  1676. domInputLocalOffset_Array& inputs = weights->getInput_array();
  1677. domFloat_array* vertex_weights = NULL;
  1678. for (size_t i = 0; i < inputs.getCount(); ++i)
  1679. {
  1680. if (strcmp(inputs[i]->getSemantic(), COMMON_PROFILE_INPUT_WEIGHT) == 0)
  1681. {
  1682. domSource* weight_source = daeSafeCast<domSource>(inputs[i]->getSource().getElement());
  1683. if (weight_source)
  1684. {
  1685. vertex_weights = weight_source->getFloat_array();
  1686. }
  1687. }
  1688. }
  1689. if (vertex_weights)
  1690. {
  1691. domListOfFloats& w = vertex_weights->getValue();
  1692. domListOfUInts& vcount = weights->getVcount()->getValue();
  1693. domListOfInts& v = weights->getV()->getValue();
  1694. U32 c_idx = 0;
  1695. for (size_t vc_idx = 0; vc_idx < vcount.getCount(); ++vc_idx)
  1696. { //for each vertex
  1697. daeUInt count = vcount[vc_idx];
  1698. //create list of weights that influence this vertex
  1699. LLModel::weight_list weight_list;
  1700. for (daeUInt i = 0; i < count; ++i)
  1701. { //for each weight
  1702. daeInt joint_idx = v[c_idx++];
  1703. daeInt weight_idx = v[c_idx++];
  1704. if (joint_idx == -1)
  1705. {
  1706. //ignore bindings to bind_shape_matrix
  1707. continue;
  1708. }
  1709. F32 weight_value = w[weight_idx];
  1710. weight_list.push_back(LLModel::JointWeight(joint_idx, weight_value));
  1711. }
  1712. //sort by joint weight
  1713. std::sort(weight_list.begin(), weight_list.end(), LLModel::CompareWeightGreater());
  1714. std::vector<LLModel::JointWeight> wght;
  1715. F32 total = 0.f;
  1716. for (U32 i = 0; i < llmin((U32) 4, (U32) weight_list.size()); ++i)
  1717. { //take up to 4 most significant weights
  1718. if (weight_list[i].mWeight > 0.f)
  1719. {
  1720. wght.push_back( weight_list[i] );
  1721. total += weight_list[i].mWeight;
  1722. }
  1723. }
  1724. F32 scale = 1.f/total;
  1725. if (scale != 1.f)
  1726. { //normalize weights
  1727. for (U32 i = 0; i < wght.size(); ++i)
  1728. {
  1729. wght[i].mWeight *= scale;
  1730. }
  1731. }
  1732. model->mSkinWeights[model->mPosition[vc_idx]] = wght;
  1733. }
  1734. //add instance to scene for this model
  1735. LLMatrix4 transformation = mTransform;
  1736. // adjust the transformation to compensate for mesh normalization
  1737. LLMatrix4 mesh_translation;
  1738. mesh_translation.setTranslation(mesh_translation_vector);
  1739. mesh_translation *= transformation;
  1740. transformation = mesh_translation;
  1741. LLMatrix4 mesh_scale;
  1742. mesh_scale.initScale(mesh_scale_vector);
  1743. mesh_scale *= transformation;
  1744. transformation = mesh_scale;
  1745. std::map<std::string, LLImportMaterial> materials;
  1746. for (U32 i = 0; i < model->mMaterialList.size(); ++i)
  1747. {
  1748. materials[model->mMaterialList[i]] = LLImportMaterial();
  1749. }
  1750. mScene[transformation].push_back(LLModelInstance(model, model->mLabel, transformation, materials));
  1751. stretch_extents(model, transformation, mExtents[0], mExtents[1], mFirstTransform);
  1752. }
  1753. }
  1754. }
  1755. }
  1756. }
  1757. }
  1758. }
  1759. daeElement* scene = root->getDescendant("visual_scene");
  1760. if (!scene)
  1761. {
  1762. llwarns << "document has no visual_scene" << llendl;
  1763. setLoadState( ERROR_PARSING );
  1764. return true;
  1765. }
  1766. setLoadState( DONE );
  1767. bool badElement = false;
  1768. processElement( scene, badElement );
  1769. if ( badElement )
  1770. {
  1771. setLoadState( ERROR_PARSING );
  1772. }
  1773. return true;
  1774. }
  1775. void LLModelLoader::setLoadState(U32 state)
  1776. {
  1777. if (mPreview)
  1778. {
  1779. mPreview->setLoadState(state);
  1780. }
  1781. }
  1782. bool LLModelLoader::loadFromSLM(const std::string& filename)
  1783. {
  1784. //only need to populate mScene with data from slm
  1785. llstat stat;
  1786. if (LLFile::stat(filename, &stat))
  1787. { //file does not exist
  1788. return false;
  1789. }
  1790. S32 file_size = (S32) stat.st_size;
  1791. llifstream ifstream(filename, std::ifstream::in | std::ifstream::binary);
  1792. LLSD data;
  1793. LLSDSerialize::fromBinary(data, ifstream, file_size);
  1794. ifstream.close();
  1795. //build model list for each LoD
  1796. model_list model[LLModel::NUM_LODS];
  1797. if (data["version"].asInteger() != SLM_SUPPORTED_VERSION)
  1798. { //unsupported version
  1799. return false;
  1800. }
  1801. LLSD& mesh = data["mesh"];
  1802. LLVolumeParams volume_params;
  1803. volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
  1804. for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod)
  1805. {
  1806. for (U32 i = 0; i < mesh.size(); ++i)
  1807. {
  1808. std::stringstream str(mesh[i].asString());
  1809. LLPointer<LLModel> loaded_model = new LLModel(volume_params, (F32) lod);
  1810. if (loaded_model->loadModel(str))
  1811. {
  1812. loaded_model->mLocalID = i;
  1813. model[lod].push_back(loaded_model);
  1814. if (lod == LLModel::LOD_HIGH && !loaded_model->mSkinInfo.mJointNames.empty())
  1815. {
  1816. //check to see if rig is valid
  1817. mPreview->critiqueRigForUploadApplicability( loaded_model->mSkinInfo.mJointNames );
  1818. }
  1819. }
  1820. }
  1821. }
  1822. if (model[LLModel::LOD_HIGH].empty())
  1823. { //failed to load high lod
  1824. return false;
  1825. }
  1826. // Set name.
  1827. std::string name = data["name"];
  1828. if (!name.empty())
  1829. {
  1830. model[LLModel::LOD_HIGH][0]->mLabel = name;
  1831. }
  1832. //load instance list
  1833. model_instance_list instance_list;
  1834. LLSD& instance = data["instance"];
  1835. for (U32 i = 0; i < instance.size(); ++i)
  1836. {
  1837. //deserialize instance list
  1838. instance_list.push_back(LLModelInstance(instance[i]));
  1839. //match up model instance pointers
  1840. S32 idx = instance_list[i].mLocalMeshID;
  1841. for (U32 lod = 0; lod < LLModel::NUM_LODS; ++lod)
  1842. {
  1843. if (!model[lod].empty())
  1844. {
  1845. instance_list[i].mLOD[lod] = model[lod][idx];
  1846. }
  1847. }
  1848. instance_list[i].mModel = model[LLModel::LOD_HIGH][idx];
  1849. }
  1850. //convert instance_list to mScene
  1851. mFirstTransform = TRUE;
  1852. for (U32 i = 0; i < instance_list.size(); ++i)
  1853. {
  1854. LLModelInstance& cur_instance = instance_list[i];
  1855. mScene[cur_instance.mTransform].push_back(cur_instance);
  1856. stretch_extents(cur_instance.mModel, cur_instance.mTransform, mExtents[0], mExtents[1], mFirstTransform);
  1857. }
  1858. setLoadState( DONE );
  1859. return true;
  1860. }
  1861. //static
  1862. bool LLModelLoader::isAlive(LLModelLoader* loader)
  1863. {
  1864. if(!loader)
  1865. {
  1866. return false ;
  1867. }
  1868. std::list<LLMode