llviewerobjectexport.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. /**
  2. * @file llviewerobjectexport.h
  3. * @authors Latif Khalifa (DAE exporter) / Apelsin & Lirusaito (wavefront
  4. * exporter). Backported/adapted/optimized by Henri Beauchamp.
  5. *
  6. * $LicenseInfo:firstyear=2013&license=viewergpl$
  7. *
  8. * Second Life Viewer Source Code
  9. * The source code in this file ("Source Code") is provided by Linden Lab
  10. * to you under the terms of the GNU General Public License, version 2.0
  11. * ("GPL"), unless you have obtained a separate licensing agreement
  12. * ("Other License"), formally executed by you and Linden Lab. Terms of
  13. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  14. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  15. *
  16. * There are special exceptions to the terms and conditions of the GPL as
  17. * it is applied to this Source Code. View the full text of the exception
  18. * in the file doc/FLOSS-exception.txt in this software distribution, or
  19. * online at
  20. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  21. *
  22. * By copying, modifying or distributing this software, you acknowledge
  23. * that you have read and understood your obligations described above,
  24. * and agree to abide by those obligations.
  25. *
  26. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  27. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  28. * COMPLETENESS OR PERFORMANCE.
  29. * $/LicenseInfo$
  30. */
  31. #ifndef LL_LLVIEWEROBJECTEXPORT_H
  32. #define LL_LLVIEWEROBJECTEXPORT_H
  33. #include <string>
  34. #include <vector>
  35. #include "dom/domElements.h"
  36. #include "hbfastmap.h"
  37. #include "llfile.h"
  38. #include "hbfileselector.h"
  39. #include "llsd.h"
  40. #include "lltextureentry.h"
  41. #include "lluuid.h"
  42. class LLButton;
  43. class LLCheckBoxCtrl;
  44. class LLComboBox;
  45. class LLFace;
  46. class LLPolyMesh;
  47. class LLSelectNode;
  48. class LLUIString;
  49. class LLViewerObject;
  50. class LLVOAvatar;
  51. class LLVolume;
  52. class LLVolumeFace;
  53. class LLXform;
  54. ///////////////////////////////////////////////////////////////////////////////
  55. // Collada exporter
  56. ///////////////////////////////////////////////////////////////////////////////
  57. class LKDAESaver
  58. {
  59. protected:
  60. LOG_CLASS(LKDAESaver);
  61. public:
  62. LKDAESaver() {}
  63. ~LKDAESaver() {}
  64. bool addSelectedObjects(std::string& root_name, U32& total);
  65. bool saveDAE(std::string filename);
  66. enum image_format_type
  67. {
  68. ft_tga,
  69. ft_png,
  70. ft_j2c,
  71. ft_bmp,
  72. ft_jpg
  73. };
  74. static const std::string image_format_ext[];
  75. class MaterialInfo
  76. {
  77. public:
  78. LL_INLINE bool matches(LLTextureEntry* te)
  79. {
  80. return mTextureID == te->getID() && mColor == te->getColor();
  81. }
  82. LL_INLINE bool operator==(const MaterialInfo& rhs)
  83. {
  84. return mTextureID == rhs.mTextureID && mColor == rhs.mColor &&
  85. mName == rhs.mName;
  86. }
  87. LL_INLINE bool operator!=(const MaterialInfo& rhs)
  88. {
  89. return mTextureID != rhs.mTextureID || mColor != rhs.mColor ||
  90. mName != rhs.mName;
  91. }
  92. MaterialInfo(const LLUUID& tex_id, const LLColor4& color,
  93. const std::string& name)
  94. : mTextureID(tex_id),
  95. mColor(color),
  96. mName(name)
  97. {
  98. }
  99. MaterialInfo(const MaterialInfo& rhs)
  100. {
  101. mTextureID = rhs.mTextureID;
  102. mColor = rhs.mColor;
  103. mName = rhs.mName;
  104. }
  105. MaterialInfo& operator= (const MaterialInfo& rhs)
  106. {
  107. mTextureID = rhs.mTextureID;
  108. mColor = rhs.mColor;
  109. mName = rhs.mName;
  110. return *this;
  111. }
  112. public:
  113. LLUUID mTextureID;
  114. LLColor4 mColor;
  115. std::string mName;
  116. };
  117. typedef std::vector<std::pair<LLViewerObject*, std::string> > obj_info_t;
  118. typedef std::vector<std::string> string_list_t;
  119. typedef std::vector<S32> int_list_t;
  120. typedef std::vector<MaterialInfo> material_list_t;
  121. private:
  122. void add(LLViewerObject* prim, const std::string& name);
  123. void transformTexCoord(S32 num_vert, LLVector2* coord,
  124. LLVector3* positions, LLVector3* normals,
  125. LLTextureEntry* te, LLVector3 scale);
  126. void addSource(daeElement* mesh, const char* src_id, std::string params,
  127. const std::vector<F32>& vals);
  128. void addPolygons(daeElement* mesh, const char* geomID,
  129. const char* mat_id, LLViewerObject* obj,
  130. int_list_t* faces_to_include);
  131. bool skipFace(LLTextureEntry* te);
  132. MaterialInfo getMaterial(LLTextureEntry* te);
  133. void getMaterials(LLViewerObject* obj, material_list_t* ret);
  134. void getFacesWithMaterial(LLViewerObject* obj,
  135. MaterialInfo& mat, int_list_t* ret);
  136. void generateEffects(daeElement* effects);
  137. void generateImagesSection(daeElement* images);
  138. void updateTextureInfo();
  139. public:
  140. LLVector3 mOffset;
  141. S32 mTotalNumMaterials;
  142. material_list_t mAllMaterials;
  143. uuid_vec_t mTextures;
  144. string_list_t mTextureNames;
  145. obj_info_t mObjects;
  146. std::string mImageFormat;
  147. };
  148. ///////////////////////////////////////////////////////////////////////////////
  149. // Floater for the Collada exporter
  150. ///////////////////////////////////////////////////////////////////////////////
  151. class LKFloaterColladaExport final
  152. : public LLFloater, public LLFloaterSingleton<LKFloaterColladaExport>
  153. {
  154. friend class LLUISingleton<LKFloaterColladaExport,
  155. VisibilityPolicy<LLFloater> >;
  156. protected:
  157. LOG_CLASS(LKFloaterColladaExport);
  158. public:
  159. ~LKFloaterColladaExport() override;
  160. bool postBuild() override;
  161. static void saveTexturesWorker(void* data);
  162. private:
  163. // Open only via LLFloaterSingleton interface, i.e. showInstance() or
  164. // toggleInstance().
  165. LKFloaterColladaExport(const LLSD&);
  166. void addSelectedObjects();
  167. void updateTitleProgress();
  168. static void onTextureExportCheck(LLUICtrl* ctrl, void* data);
  169. static void onClickExport(void* data);
  170. static void filePickerCallback(HBFileSelector::ESaveFilter type,
  171. std::string& filename, void* data);
  172. void saveTextures();
  173. void saveDAE();
  174. private:
  175. LLButton* mExportButton;
  176. LLCheckBoxCtrl* mTextureExportCheck;
  177. LLComboBox* mTextureTypeCombo;
  178. U32 mTotal;
  179. U32 mNumTextures;
  180. U32 mNumExportableTextures;
  181. LLTimer mTimer;
  182. LKDAESaver mSaver;
  183. std::string mTitle;
  184. std::string mObjectName;
  185. std::string mFilename;
  186. std::string mFolder;
  187. typedef fast_hmap<LLUUID, std::string> texture_list_t;
  188. texture_list_t mTexturesToSave;
  189. };
  190. ///////////////////////////////////////////////////////////////////////////////
  191. // Wavefront exporter
  192. ///////////////////////////////////////////////////////////////////////////////
  193. // Avatar exporting plain does not work: the avatar data istelf is screwed and
  194. // the resulting OBJ file would nott reproduce the avatar after loaded in any
  195. // 3D modelling program (I tried with Blender, Wings 3D and a couple others, to
  196. // no avail): it just reproduces a few half-spheres !
  197. // The attachments cannot be exported either with the algorithm used here
  198. // because the latter relies on select node permissions to be received for each
  199. // attachment prim already, while it cannot happen on the same frame since when
  200. // selection is done a message is sent to the server and the reply arrives only
  201. // a few milliseconds later: to get attachments export working, the same idle
  202. // callbacks based export worker algorithm as in hbobjectbackup.cpp should be
  203. // implemented instead (but it does not make sense implementing it either as
  204. // long as the avatar OBJ export itself is not fixed). HB
  205. #define LL_EXPORT_AVATAR_OBJ 0
  206. typedef std::vector<std::pair<LLVector3, LLVector2> > vert_t;
  207. typedef std::vector<LLVector3> vec3_t;
  208. struct tri
  209. {
  210. tri(int a, int b, int c) : v0(a), v1(b), v2(c) {}
  211. int v0;
  212. int v1;
  213. int v2;
  214. };
  215. typedef std::vector<tri> tri_t;
  216. class ALWavefront
  217. {
  218. public:
  219. ALWavefront(vert_t v, tri_t t);
  220. ALWavefront(const LLVolumeFace* face, const LLXform* transform = NULL,
  221. const LLXform* transform_normals = NULL);
  222. ALWavefront(LLFace* face, LLPolyMesh* mesh = NULL,
  223. const LLXform* transform = NULL,
  224. const LLXform* transform_normals = NULL);
  225. static void Transform(vert_t& v, const LLXform* x);
  226. static void Transform(vec3_t& v, const LLXform* x);
  227. public:
  228. vert_t mVertices;
  229. vec3_t mNormals; // null unless otherwise specified !
  230. tri_t mTriangles; // because almost all surfaces in SL are triangles
  231. std::string mName;
  232. };
  233. class ALWavefrontSaver
  234. {
  235. public:
  236. ALWavefrontSaver() {}
  237. ~ALWavefrontSaver() {}
  238. static void exportSelection();
  239. #if LL_EXPORT_AVATAR_OBJ
  240. static void exportAvatar(bool with_attachments = false);
  241. #endif
  242. private:
  243. void add(const ALWavefront& obj);
  244. void add(const LLVolume* vol, const LLXform* transform = NULL,
  245. const LLXform* transform_normals = NULL);
  246. void add(const LLViewerObject* some_vo);
  247. #if LL_EXPORT_AVATAR_OBJ
  248. bool add(const LLVOAvatar* av_vo, bool with_attachments);
  249. #endif
  250. bool saveToFile(LLFILE* fp);
  251. static void saveOpenPicker(ALWavefrontSaver* wfsaver, std::string name);
  252. static void saveNotificationCallback(const LLSD& notification,
  253. const LLSD& response,
  254. ALWavefrontSaver* wfsaver,
  255. std::string name);
  256. static void savePickerCallback(HBFileSelector::ESaveFilter type,
  257. std::string& filename, void* userdata);
  258. private:
  259. LLVector3 mOffset;
  260. std::vector<ALWavefront> mWavefrontObjects;
  261. };
  262. #endif // LL_LLVIEWEROBJECTEXPORT_H