llfloatermodelpreview.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. /**
  2. * @file llfloatermodelpreview.h
  3. * @brief LLFloaterModelPreview class definition
  4. *
  5. * $LicenseInfo:firstyear=2004&license=viewergpl$
  6. *
  7. * Copyright (c) 2010, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #ifndef LL_LLFLOATERMODELPREVIEW_H
  33. #define LL_LLFLOATERMODELPREVIEW_H
  34. #include "llcontrol.h"
  35. #include "llfloater.h"
  36. #include "llhandle.h"
  37. #include "llmodelloader.h"
  38. #include "llquaternion.h"
  39. #include "llthread.h"
  40. #include "lldynamictexture.h"
  41. #include "llmeshrepository.h"
  42. #include "llviewermenu.h"
  43. class DAE;
  44. class daeElement;
  45. class domProfile_COMMON;
  46. class domInstance_geometry;
  47. class domNode;
  48. class domTranslate;
  49. class domController;
  50. class domMesh;
  51. class domSkin;
  52. class LLComboBox;
  53. class LLVOAvatar;
  54. class LLVertexBuffer;
  55. class LLModelPreview;
  56. class LLFloaterModelPreview;
  57. class LLScrollListCtrl;
  58. class LLTabContainer;
  59. class LLTextBox;
  60. class LLTextEditor;
  61. class LLUploadPermissionsObserver
  62. {
  63. protected:
  64. LOG_CLASS(LLUploadPermissionsObserver);
  65. public:
  66. LLUploadPermissionsObserver() { mUploadPermObserverHandle.bind(this); }
  67. virtual ~LLUploadPermissionsObserver() {}
  68. virtual void onPermissionsReceived(const LLSD& result) = 0;
  69. virtual void setPermissonsErrorStatus(S32 status, const std::string& reason) = 0;
  70. LLHandle<LLUploadPermissionsObserver> getPermObserverHandle() const
  71. {
  72. return mUploadPermObserverHandle;
  73. }
  74. protected:
  75. LLRootHandle<LLUploadPermissionsObserver> mUploadPermObserverHandle;
  76. };
  77. class LLFloaterModelUploadBase : public LLFloater,
  78. public LLUploadPermissionsObserver,
  79. public LLWholeModelFeeObserver,
  80. public LLWholeModelUploadObserver
  81. {
  82. protected:
  83. LOG_CLASS(LLFloaterModelUploadBase);
  84. public:
  85. LLFloaterModelUploadBase();
  86. ~LLFloaterModelUploadBase() override {}
  87. void setPermissonsErrorStatus(S32 status,
  88. const std::string& reason) override = 0;
  89. void onPermissionsReceived(const LLSD& result) override = 0;
  90. void onModelPhysicsFeeReceived(const LLSD& result,
  91. std::string upload_url) override = 0;
  92. void setModelPhysicsFeeErrorStatus(S32 status, const std::string& reason,
  93. const LLSD& result) override = 0;
  94. void onModelUploadSuccess() override {}
  95. void onModelUploadFailure() override {}
  96. protected:
  97. // Requests agent's permissions to upload model
  98. void requestAgentUploadPermissions();
  99. void requestUploadPermCoro(std::string url,
  100. LLHandle<LLUploadPermissionsObserver> handle);
  101. protected:
  102. std::string mUploadModelUrl;
  103. bool mHasUploadPerm;
  104. };
  105. class LLFloaterModelPreview final
  106. : public LLFloaterModelUploadBase,
  107. public LLFloaterSingleton<LLFloaterModelPreview>
  108. {
  109. friend class LLModelPreview;
  110. friend class LLPhysicsDecomp;
  111. friend class LLUISingleton<LLFloaterModelPreview,
  112. VisibilityPolicy<LLFloater> >;
  113. protected:
  114. LOG_CLASS(LLFloaterModelPreview);
  115. public:
  116. class DecompRequest : public LLPhysicsDecomp::Request
  117. {
  118. public:
  119. S32 mContinue;
  120. LLPointer<LLModel> mModel;
  121. DecompRequest(const std::string& stage, LLModel* mdl);
  122. virtual S32 statusCallback(const char* status, S32 p1, S32 p2);
  123. virtual void completed();
  124. };
  125. ~LLFloaterModelPreview() override;
  126. bool postBuild() override;
  127. void onOpen() override;
  128. void initModelPreview();
  129. bool handleMouseDown(S32 x, S32 y, MASK mask) override;
  130. bool handleMouseUp(S32 x, S32 y, MASK mask) override;
  131. bool handleHover(S32 x, S32 y, MASK mask) override;
  132. bool handleScrollWheel(S32 x, S32 y, S32 clicks) override;
  133. static void onMouseCaptureLostModelPreview(LLMouseHandler*);
  134. LL_INLINE static void setUploadAmount(S32 amount) { sUploadAmount = amount; }
  135. static LLModelPreview* getModelPreview();
  136. void setDetails(F32 x, F32 y, F32 z);
  137. void refresh() override;
  138. void loadModel(S32 lod);
  139. void loadModel(S32 lod, const std::string& file_name,
  140. bool force_disable_slm = false);
  141. void clearSkinningInfo();
  142. void updateSkinningInfo(bool highlight_overrides);
  143. bool isViewOptionChecked(const LLSD& userdata);
  144. bool isViewOptionEnabled(const LLSD& userdata);
  145. void setViewOptionEnabled(const char* option, bool enabled);
  146. void enableViewOption(const char* option);
  147. void disableViewOption(const char* option);
  148. // Shows warning message if agent has no permissions to upload model
  149. void onPermissionsReceived(const LLSD& result) override;
  150. // Called when error occurs during permissions request
  151. void setPermissonsErrorStatus(S32 status,
  152. const std::string& reason) override;
  153. void onModelPhysicsFeeReceived(const LLSD& result,
  154. std::string upload_url) override;
  155. void handleModelPhysicsFeeReceived();
  156. void setModelPhysicsFeeErrorStatus(S32 status, const std::string& reason,
  157. const LLSD& result) override;
  158. void onModelUploadSuccess() override;
  159. void onModelUploadFailure() override;
  160. bool isModelUploadAllowed();
  161. protected:
  162. // Open only via LLFloaterSingleton interface, i.e. showInstance() or
  163. // toggleInstance(), or implicitely via getInstance().
  164. LLFloaterModelPreview(const LLSD&);
  165. bool prepareToLoadModel(S32 lod);
  166. static void onTabChanged(void* userdata, bool);
  167. static void onUpload(void* userdata);
  168. static void onReset(void* userdata);
  169. static void onImportScaleCommit(LLUICtrl*, void* userdata);
  170. static void onPelvisOffsetCommit(LLUICtrl*, void* userdata);
  171. static void onUploadJointsCommit(LLUICtrl*, void* userdata);
  172. static void onUploadSkinCommit(LLUICtrl*, void* userdata);
  173. static void onJointListSelection(LLUICtrl*, void* userdata);
  174. // NOTE: for these, userdata bears the LOD level instead of "this"
  175. static void onBrowseLOD(void* userdata);
  176. static void onPreviewLODCommit(LLUICtrl* ctrl, void* userdata);
  177. static void onLoDSourceCommit(LLUICtrl*, void* userdata);
  178. static void onLODParamCommit(LLUICtrl*, void* userdata);
  179. static void onLODParamCommitEnforceTriLimit(LLUICtrl*, void* userdata);
  180. static void onGenerateNormalsCommit(LLUICtrl*, void* userdata);
  181. static void toggleGenerateNormals(LLUICtrl*, void* userdata);
  182. static void onExplodeCommit(LLUICtrl*, void* userdata);
  183. static void onAutoFillCommit(LLUICtrl*, void* userdata);
  184. static void toggleCalculateButtonCallBack(LLUICtrl*, void* userdata);
  185. static void onClickTextLOD(void* userdata);
  186. static void onClickCalculateBtn(void* userdata);
  187. static void onViewOptionChecked(LLUICtrl* ctrl, void* userdata);
  188. // For this one, userdata bears a LLCDStageData pointer instead of "this"
  189. static void onPhysicsStageExecute(LLUICtrl*, void* userdata);
  190. static void onPhysicsParamCommit(LLUICtrl* ctrl, void* userdata);
  191. static void onPhysicsStageCancel(void* userdata);
  192. static void onCancel(void* userdata);
  193. static void onPhysicsBrowse(void* userdata);
  194. static void onPhysicsUseLOD(LLUICtrl*, void* userdata);
  195. #if 0 // Not implemented (not needed/supported with HACD)
  196. static void onPhysicsOptimize(void* userdata);
  197. static void onPhysicsDecomposeBack(void* userdata);
  198. static void onPhysicsSimplifyBack(void* userdata);
  199. #endif
  200. static void onClickValidateURL(void* userdata);
  201. void draw() override;
  202. void initDecompControls();
  203. void setStatusMessage(const std::string& msg);
  204. void addMessageToLog(const std::string& line, const LLSD& args, S32 lod,
  205. bool flash = false);
  206. void addLineToLog(const std::string& line, bool flash = false);
  207. void clearLog();
  208. private:
  209. // Toggles between "Calculate weights & fee" and "Upload" buttons.
  210. void toggleCalculateButton(bool visible);
  211. // Calls the above after clearing mModelPhysicsFee.
  212. void modelUpdated(bool visible);
  213. // Resets display options of model preview to their defaults.
  214. void resetDisplayOptions();
  215. void createSmoothComboBox(LLComboBox* combo_box, F32 min, F32 max);
  216. protected:
  217. LLModelPreview* mModelPreview;
  218. LLPhysicsDecomp::decomp_params_t mDecompParams;
  219. S32 mLastMouseX;
  220. S32 mLastMouseY;
  221. LLRect mPreviewRect;
  222. static S32 sUploadAmount;
  223. std::set<LLPointer<DecompRequest> > mCurRequest;
  224. std::string mStatusMessage;
  225. // Use "disabled" as false by default
  226. std::map<std::string, bool> mViewOptionDisabled;
  227. // stores which lod mode each LOD is using
  228. // 0 - load from file
  229. // 1 - auto generate
  230. // 2 - use LoD above
  231. S32 mLODMode[4];
  232. LLMutex* mStatusLock;
  233. LLSD mModelPhysicsFee;
  234. private:
  235. LLTabContainer* mTabContainer;
  236. LLPanel* mModifiersPanel;
  237. LLPanel* mLogPanel;
  238. LLButton* mUploadBtn;
  239. LLButton* mCalculateBtn;
  240. LLScrollListCtrl* mJointsList;
  241. LLScrollListCtrl* mJointsOverrides;
  242. LLTextBox* mConflictsText;
  243. LLTextBox* mOverridesLabel;
  244. LLTextEditor* mUploadLogText;
  245. // Account upload permission validation URL
  246. std::string mValidateURL;
  247. std::string mSelectedJointName;
  248. struct JointOverrideData
  249. {
  250. JointOverrideData()
  251. : mHasConflicts(false)
  252. {
  253. }
  254. // Models with overrides
  255. std::map<std::string, LLVector3> mPosOverrides;
  256. // Models without overrides
  257. std::set<std::string> mModelsNoOverrides;
  258. bool mHasConflicts;
  259. };
  260. typedef std::map<std::string, JointOverrideData> overrides_map_t;
  261. overrides_map_t mJointOverrides[LLModel::NUM_LODS];
  262. // true while waiting for a reply to a fee request
  263. bool mSentFeeRequest;
  264. // true while waiting for the end of an upload
  265. bool mSentUploadRequest;
  266. // true when HACD library is detected.
  267. bool mLibIsHACD;
  268. };
  269. class LLModelPreview final : public LLViewerDynamicTexture, public LLMutex
  270. {
  271. friend class LLModelLoader;
  272. friend class LLFloaterModelPreview;
  273. friend class LLFloaterModelPreview::DecompRequest;
  274. friend class LLPhysicsDecomp;
  275. protected:
  276. LOG_CLASS(LLModelPreview);
  277. public:
  278. typedef enum
  279. {
  280. LOD_FROM_FILE = 0,
  281. GENERATE,
  282. // Automatically selects method based on model or face:
  283. MESH_OPTIMIZER_AUTO,
  284. MESH_OPTIMIZER_PRECISE,
  285. MESH_OPTIMIZER_SLOPPY,
  286. USE_LOD_ABOVE
  287. } eLoDMode;
  288. LLModelPreview(S32 width, S32 height, LLFloaterModelPreview* fmp);
  289. ~LLModelPreview() override;
  290. void resetPreviewTarget();
  291. void setPreviewTarget(F32 distance);
  292. LL_INLINE void setTexture(U32 name) { mTextureName = name; }
  293. void setPhysicsFromLOD(S32 lod);
  294. void update();
  295. void genBuffers(S32 lod, bool skinned);
  296. void clearBuffers();
  297. LL_INLINE void refresh() { mNeedsUpdate = true; }
  298. // LLViewerDynamicTexture override
  299. LL_INLINE bool needsRender() override { return mNeedsUpdate; }
  300. bool render() override;
  301. void rotate(F32 yaw_radians, F32 pitch_radians);
  302. void zoom(F32 zoom_amt);
  303. void pan(F32 right, F32 up);
  304. void setPreviewLOD(S32 lod);
  305. void clearModel(S32 lod);
  306. void getJointAliases(JointMap& joint_map);
  307. void loadModel(std::string filename, S32 lod,
  308. bool force_disable_slm = false,
  309. bool allow_preprocess = true);
  310. void loadModelCallback(S32 lod);
  311. LL_INLINE bool lodsReady() { return !mGenLOD && mLodsQuery.empty(); }
  312. LL_INLINE void queryLODs() { mGenLOD = true; }
  313. // Returns false if GLOD failed to optimize the LOD.
  314. bool genGlodLODs(S32 which_lod = -1, U32 decimation = 3,
  315. bool enforce_tri_limit = false);
  316. void genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode,
  317. U32 decimation = 3,
  318. bool enforce_tri_limit = false);
  319. void generateNormals();
  320. void restoreNormals();
  321. void updateDimentionsAndOffsets();
  322. void rebuildUploadData();
  323. void saveUploadData(bool save_skinweights, bool save_joint_poisitions,
  324. bool lock_scale_if_joint_pos);
  325. void saveUploadData(const std::string& filename, bool save_skinweights,
  326. bool save_joint_poisitions,
  327. bool lock_scale_if_joint_pos);
  328. void clearIncompatible(S32 lod);
  329. void updateStatusMessages();
  330. void updateLodControls(S32 lod);
  331. void clearGLODGroup();
  332. void onLODParamCommit(S32 lod, bool enforce_tri_limit);
  333. void addEmptyFace(LLModel* pTarget);
  334. LL_INLINE bool getModelPivot() const { return mHasPivot; }
  335. LL_INLINE void setHasPivot(bool val) { mHasPivot = val; }
  336. LL_INLINE void setModelPivot(const LLVector3& pivot) { mModelPivot = pivot; }
  337. // Is a rig valid so that it can be used as a criteria for allowing for
  338. // uploading of joint positions
  339. LL_INLINE bool isRigValidForJointPositionUpload() const { return mRigValidJointUpload; }
  340. // Accessors for the legacy rigs
  341. LL_INLINE bool isLegacyRigValid() const { return mLegacyRigFlags == 0; }
  342. LL_INLINE U32 getLegacyRigFlags() const { return mLegacyRigFlags; }
  343. protected:
  344. typedef boost::signals2::signal<void (F32 x, F32 y, F32 z)> details_sig_t;
  345. boost::signals2::connection setDetailsCallback(const details_sig_t::slot_type& cb)
  346. {
  347. return mDetailsSignal.connect(cb);
  348. }
  349. typedef boost::signals2::signal<void ()> loaded_sig_t;
  350. boost::signals2::connection setModelLoadedCallback(const loaded_sig_t::slot_type& cb)
  351. {
  352. return mModelLoadedSignal.connect(cb);
  353. }
  354. typedef boost::signals2::signal<void (bool)> updated_sig_t;
  355. boost::signals2::connection setModelUpdatedCallback(const updated_sig_t::slot_type& cb)
  356. {
  357. return mModelUpdatedSignal.connect(cb);
  358. }
  359. LL_INLINE void setLoadState(U32 state) { mLoadState = state; }
  360. LL_INLINE U32 getLoadState() const { return mLoadState; }
  361. bool matchMaterialOrder(LLModel* lod, LLModel* ref,
  362. S32& ref_face_cnt, S32& model_face_cnt);
  363. static void textureLoadedCallback(bool success,
  364. LLViewerFetchedTexture* src_vi,
  365. LLImageRaw* src, LLImageRaw* src_aux,
  366. S32 discard_level, bool is_final,
  367. void* userdata);
  368. static bool lodQueryCallback();
  369. static void loadedCallback(LLModelLoader::scene& scene,
  370. LLModelLoader::model_list& model_list,
  371. S32 lod, void* userdata);
  372. static void stateChangedCallback(U32 state, void* userdata);
  373. static LLJoint* lookupJointByName(const std::string&, void* userdata);
  374. static U32 loadTextures(LLImportMaterial& material, void* userdata);
  375. private:
  376. // Utility method for controller vertex compare
  377. bool verifyCount(int expected, int result);
  378. // Creates the dummy avatar for the preview window
  379. void createPreviewAvatar();
  380. void renderGroundPlane(F32 z_offset);
  381. // Count amount of original models, excluding sub-models
  382. static U32 countRootModels(LLModelLoader::model_list models);
  383. enum
  384. {
  385. MESH_OPTIMIZER_FULL,
  386. MESH_OPTIMIZER_NO_NORMALS,
  387. MESH_OPTIMIZER_NO_UVS,
  388. MESH_OPTIMIZER_NO_TOPOLOGY,
  389. };
  390. // Methods using the meshoptimizer library, returning the reached
  391. // simplification ratio, or -1.f on failure to simplify the model.
  392. F32 genMeshOptimizerPerModel(LLModel* base_model, LLModel* target_model,
  393. F32 indices_ratio, F32 error_threshold,
  394. S32 simplification_mode);
  395. F32 genMeshOptimizerPerFace(LLModel* base_model, LLModel* target_model,
  396. U32 face_idx, F32 indices_ratio,
  397. F32 error_threshold, S32 simplification_mode);
  398. protected:
  399. LLFloaterModelPreview* mFMP;
  400. LLModelLoader* mModelLoader;
  401. LLPointer<LLModel> mDefaultPhysModel;
  402. LLPointer<LLVOAvatar> mPreviewAvatar;
  403. LLVector3 mGroundPlane[4];
  404. U32 mTextureName;
  405. F32 mCameraDistance;
  406. F32 mCameraYaw;
  407. F32 mCameraPitch;
  408. F32 mCameraZoom;
  409. S32 mPreviewLOD;
  410. U32 mLoadState;
  411. S32 mPhysicsSearchLOD;
  412. U32 mGroup;
  413. // Amount of triangles in original (base) model
  414. U32 mMaxTriangleLimit;
  415. F32 mPelvisZOffset;
  416. LLVector3 mCameraOffset;
  417. LLVector3 mPreviewTarget;
  418. LLVector3 mPreviewScale;
  419. LLVector3 mModelPivot;
  420. std::string mLODFile[LLModel::NUM_LODS];
  421. typedef std::map<std::string, bool> view_option_map_t;
  422. view_option_map_t mViewOption;
  423. U32 mLegacyRigFlags;
  424. bool mRigValidJointUpload;
  425. bool mFirstSkinUpdate;
  426. bool mNeedsUpdate;
  427. bool mDirty;
  428. bool mModelNoErrors;
  429. bool mGenLOD;
  430. bool mWarnPhysModel;
  431. bool mLoading;
  432. bool mResetJoints;
  433. bool mHasPivot;
  434. bool mLastJointUpdate;
  435. bool mHasDegenerate;
  436. // GLOD object parameters (must rebuild object if these change)
  437. bool mLODFrozen;
  438. F32 mBuildShareTolerance;
  439. U32 mBuildQueueMode;
  440. U32 mBuildOperator;
  441. U32 mBuildBorderMode;
  442. U32 mRequestedLoDMode[LLModel::NUM_LODS];
  443. S32 mRequestedTriangleCount[LLModel::NUM_LODS];
  444. F32 mRequestedErrorThreshold[LLModel::NUM_LODS];
  445. U32 mRequestedBuildOperator[LLModel::NUM_LODS];
  446. U32 mRequestedQueueMode[LLModel::NUM_LODS];
  447. U32 mRequestedBorderMode[LLModel::NUM_LODS];
  448. F32 mRequestedShareTolerance[LLModel::NUM_LODS];
  449. F32 mRequestedCreaseAngle[LLModel::NUM_LODS];
  450. LLModelLoader::scene mScene[LLModel::NUM_LODS];
  451. LLModelLoader::scene mBaseScene;
  452. LLModelLoader::model_list mModel[LLModel::NUM_LODS];
  453. LLModelLoader::model_list mBaseModel;
  454. typedef std::vector<LLVolumeFace> v_LLVolumeFace_t;
  455. typedef std::vector<v_LLVolumeFace_t> vv_LLVolumeFace_t;
  456. vv_LLVolumeFace_t mModelFacesCopy[LLModel::NUM_LODS];
  457. vv_LLVolumeFace_t mBaseModelFacesCopy;
  458. std::vector<S32> mLodsQuery;
  459. std::vector<S32> mLodsWithParsingError;
  460. typedef std::map<LLPointer<LLModel>, U32> model_object_map_t;
  461. model_object_map_t mObject;
  462. LLMeshUploadThread::instance_list_t mUploadData;
  463. std::set<LLViewerFetchedTexture*> mTextureSet;
  464. // Map of vertex buffers to models (one vertex buffer in vector per face in
  465. // model).
  466. typedef std::map<LLModel*,
  467. std::vector<LLPointer<LLVertexBuffer> > > model_vb_map_t;
  468. model_vb_map_t mVertexBuffer[LLModel::NUM_LODS + 1];
  469. details_sig_t mDetailsSignal;
  470. loaded_sig_t mModelLoadedSignal;
  471. updated_sig_t mModelUpdatedSignal;
  472. JointNameSet mJointsFromNode;
  473. JointTransformMap mJointTransformMap;
  474. LLCachedControl<bool> mImporterDebug;
  475. };
  476. #endif // LL_LLFLOATERMODELPREVIEW_H