llmodel.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. /**
  2. * @file llmodel.h
  3. * @brief Model handling class definitions
  4. *
  5. * $LicenseInfo:firstyear=2001&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_LLMODEL_H
  33. #define LL_LLMODEL_H
  34. #include <queue>
  35. #include "llpointer.h"
  36. #include "llrefcount.h"
  37. #include "llvolume.h"
  38. #include "llvector4.h"
  39. #include "llmatrix4.h"
  40. class daeElement;
  41. class domMesh;
  42. #define MAX_MODEL_FACES 8
  43. // Fix for MAINT-6901, now reverted...
  44. #define LL_NORMALIZE_ALL_MODELS 0
  45. class LLMeshSkinInfo : public LLThreadSafeRefCount
  46. {
  47. public:
  48. LLMeshSkinInfo();
  49. LLMeshSkinInfo(const LLSD& data);
  50. LLMeshSkinInfo(const LLSD& data, const LLUUID& mesh_id);
  51. // Since LLMeshSkinInfo derives from LLThreadSafeRefCount, the default copy
  52. // constructor and operator are deleted, but we need (in the mesh model
  53. // upload floater) to clone a base LLMeshSkinInfo to LODs, so here is the
  54. // way to do it. HB
  55. void clone(const LLMeshSkinInfo& from);
  56. void fromLLSD(const LLSD& data);
  57. LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const;
  58. void updateHash(bool force = false);
  59. public:
  60. LLUUID mMeshID;
  61. LLMatrix4 mBindShapeMatrix;
  62. std::vector<std::string> mJointNames;
  63. std::vector<U32> mJointKeys;
  64. std::vector<LLMatrix4> mInvBindMatrix;
  65. std::vector<LLMatrix4> mAlternateBindMatrix;
  66. std::vector<LLMatrix4> mInvBindShapeMatrix;
  67. U64 mHash;
  68. F32 mPelvisOffset;
  69. bool mLockScaleIfJointPosition;
  70. bool mInvalidJointsScrubbed;
  71. };
  72. class LLModel : public LLVolume
  73. {
  74. protected:
  75. LOG_CLASS(LLModel);
  76. public:
  77. // Beware: LLModel::NUM_LODS != LLVolumeLODGroup::NUM_LODS but we must have
  78. // LLModel::LOD_HIGH < LLVolumeLODGroup::NUM_LODS, which is the case here.
  79. enum
  80. {
  81. LOD_IMPOSTOR = 0,
  82. LOD_LOW,
  83. LOD_MEDIUM,
  84. LOD_HIGH,
  85. LOD_PHYSICS,
  86. NUM_LODS
  87. };
  88. enum EModelStatus
  89. {
  90. NO_ERRORS = 0,
  91. VERTEX_NUMBER_OVERFLOW, //vertex number is >= 65535.
  92. BAD_ELEMENT,
  93. INVALID_STATUS
  94. };
  95. // hull_decomp is a vector of convex hulls; each convex hull is a set of
  96. // points.
  97. typedef std::vector<std::vector<LLVector3> > hull_decomp;
  98. typedef std::vector<LLVector3> hull;
  99. class PhysicsMesh
  100. {
  101. public:
  102. std::vector<LLVector3> mPositions;
  103. std::vector<LLVector3> mNormals;
  104. LL_INLINE void clear()
  105. {
  106. mPositions.clear();
  107. mNormals.clear();
  108. }
  109. LL_INLINE bool empty() const { return mPositions.empty(); }
  110. };
  111. class Decomposition
  112. {
  113. public:
  114. Decomposition() = default;
  115. Decomposition(const LLSD& data);
  116. Decomposition(const LLSD& data, const LLUUID& mesh_id);
  117. void fromLLSD(const LLSD& data);
  118. LLSD asLLSD() const;
  119. bool hasHullList() const;
  120. void merge(const Decomposition* rhs);
  121. public:
  122. LLUUID mMeshID;
  123. LLModel::hull_decomp mHull;
  124. LLModel::hull mBaseHull;
  125. std::vector<LLModel::PhysicsMesh> mMesh;
  126. LLModel::PhysicsMesh mBaseHullMesh;
  127. LLModel::PhysicsMesh mPhysicsShapeMesh;
  128. };
  129. LLModel(const LLVolumeParams& params, F32 detail);
  130. ~LLModel();
  131. std::string getName() const;
  132. bool loadModel(std::istream& is);
  133. bool loadSkinInfo(const LLSD& header, std::istream& is);
  134. bool loadDecomposition(const LLSD& header, std::istream& is);
  135. static LLSD writeModel(std::ostream& ostr, LLModel* physics, LLModel* high,
  136. LLModel* medium, LLModel* low, LLModel* imposotr,
  137. const LLModel::Decomposition& decomp,
  138. bool upload_skin, bool upload_joints,
  139. bool lock_scale_if_joint_position,
  140. bool nowrite = false, bool as_slm = false,
  141. S32 submodel_id = 0);
  142. static LLSD writeModelToStream(std::ostream& ostr, LLSD& mdl,
  143. bool nowrite = false, bool as_slm = false);
  144. LL_INLINE void clearFacesAndMaterials()
  145. {
  146. mVolumeFaces.clear();
  147. mMaterialList.clear();
  148. }
  149. LL_INLINE EModelStatus getStatus() const { return mStatus; }
  150. static std::string getStatusString(U32 status);
  151. void setNumVolumeFaces(S32 count);
  152. void setVolumeFaceData(S32 f, LLStrider<LLVector3> pos,
  153. LLStrider<LLVector3> norm, LLStrider<LLVector2> tc,
  154. LLStrider<U16> ind, U32 num_verts, U32 num_indices);
  155. void generateNormals(F32 angle_cutoff);
  156. void addFace(const LLVolumeFace& face);
  157. void sortVolumeFacesByMaterialName();
  158. void normalizeVolumeFaces();
  159. #if LL_NORMALIZE_ALL_MODELS
  160. static void normalizeModels(const std::vector<LLPointer<LLModel> >& model_list);
  161. #endif
  162. void trimVolumeFacesToSize(U32 new_count = LL_SCULPT_MESH_MAX_FACES,
  163. LLVolume::face_list_t* remainder = NULL);
  164. void remapVolumeFaces();
  165. void optimizeVolumeFaces();
  166. void offsetMesh(const LLVector3& pivotPoint);
  167. void getNormalizedScaleTranslation(LLVector3& scale_out,
  168. LLVector3& translation_out);
  169. bool isMaterialListSubset(LLModel* ref);
  170. #if 0 // Not used
  171. bool needToAddFaces(LLModel* ref, S32& ref_face_cnt, S32& mdl_face_cnt);
  172. #endif
  173. #if 0 // Moved to llfloatermodelpreview.cpp
  174. // Reorder face list based on mMaterialList in this and reference so order
  175. // matches that of reference (material ordering touchup)
  176. bool matchMaterialOrder(LLModel* ref, S32& ref_face_cnt,
  177. S32& mdl_face_cnt);
  178. #endif
  179. typedef std::vector<std::string> material_list;
  180. LL_INLINE material_list& getMaterialList() { return mMaterialList; }
  181. // Data used for skin weights
  182. class JointWeight
  183. {
  184. public:
  185. JointWeight()
  186. : mJointIdx(0),
  187. mWeight(0.f)
  188. {
  189. }
  190. JointWeight(S32 idx, F32 weight)
  191. : mJointIdx(idx),
  192. mWeight(weight)
  193. {
  194. }
  195. LL_INLINE bool operator<(const JointWeight& rhs) const
  196. {
  197. if (mWeight == rhs.mWeight)
  198. {
  199. return mJointIdx < rhs.mJointIdx;
  200. }
  201. return mWeight < rhs.mWeight;
  202. }
  203. public:
  204. S32 mJointIdx;
  205. F32 mWeight;
  206. };
  207. struct CompareWeightGreater
  208. {
  209. LL_INLINE bool operator()(const JointWeight& lhs,
  210. const JointWeight& rhs)
  211. {
  212. return rhs < lhs; // strongest = first
  213. }
  214. };
  215. // Returns false for values that are not within the tolerance for
  216. // equivalence
  217. LL_INLINE bool jointPositionalLookup(const LLVector3& a,
  218. const LLVector3& b)
  219. {
  220. constexpr F32 epsilon = 1e-5f;
  221. return fabs(a[0] - b[0]) < epsilon && fabs(a[1] - b[1]) < epsilon &&
  222. fabs(a[2] - b[2]) < epsilon;
  223. }
  224. // Gets the list of weight influences closest to given position
  225. typedef std::vector<JointWeight> weight_list;
  226. weight_list& getJointInfluences(const LLVector3& pos);
  227. void setConvexHullDecomposition(const hull_decomp& decomp);
  228. void updateHullCenters();
  229. // Used to be a validate_model(const LLModel* mdl) global function. HB
  230. bool validate(bool check_nans = false) const;
  231. protected:
  232. void addVolumeFacesFromDomMesh(domMesh* mesh);
  233. public:
  234. EModelStatus mStatus;
  235. S32 mDecompID; // Convex hull decomposition
  236. S32 mLocalID; // Id of model in its .slm file
  237. // A model/object can only have 8 faces, spillover faces will be moved to
  238. // new model/object and assigned a submodel id.
  239. S32 mSubmodelID;
  240. U32 mHullPoints;
  241. F32 mPelvisOffset;
  242. std::string mRequestedLabel; // Name requested in UI, if any
  243. std::string mLabel; // Name computed from dae
  244. material_list mMaterialList;
  245. std::vector<LLVector3> mHullCenter;
  246. // Copy of position array for this model -- mPosition[idx].mV[X, Y, Z]
  247. std::vector<LLVector3> mPosition;
  248. // Map of positions to skin weights:
  249. // mSkinWeights[pos].mV[0..4] == <joint_index>.<weight>
  250. // joint_index corresponds to mJointList
  251. typedef std::map<LLVector3, weight_list> weight_map;
  252. weight_map mSkinWeights;
  253. LLVector3 mNormalizedScale;
  254. LLVector3 mNormalizedTranslation;
  255. LLVector3 mCenterOfHullCenters;
  256. LLMeshSkinInfo mSkinInfo;
  257. Decomposition mPhysics;
  258. };
  259. typedef std::vector<LLPointer<LLModel> > model_list;
  260. typedef std::queue<LLPointer<LLModel> > model_queue;
  261. class LLModelMaterialBase
  262. {
  263. public:
  264. LLModelMaterialBase()
  265. : mFullbright(false),
  266. mDiffuseColor(1.f, 1.f, 1.f, 1.f)
  267. {
  268. }
  269. public:
  270. LLColor4 mDiffuseColor;
  271. std::string mDiffuseMapFilename;
  272. std::string mDiffuseMapLabel;
  273. std::string mBinding;
  274. bool mFullbright;
  275. };
  276. class LLImportMaterial : public LLModelMaterialBase
  277. {
  278. friend class LLMeshUploadThread;
  279. friend class LLModelPreview;
  280. public:
  281. bool operator<(const LLImportMaterial& params) const;
  282. LLImportMaterial()
  283. : LLModelMaterialBase(),
  284. mUserData(NULL)
  285. {
  286. mDiffuseColor.set(1, 1, 1, 1);
  287. }
  288. LLImportMaterial(const LLSD& data);
  289. LLSD asLLSD();
  290. LL_INLINE const LLUUID& getDiffuseMap() const { return mDiffuseMapID; }
  291. LL_INLINE void setDiffuseMap(const LLUUID& id) { mDiffuseMapID = id; }
  292. protected:
  293. LLUUID mDiffuseMapID;
  294. // Allows refs to viewer/platform-specific structs for each material
  295. // currently only stores an LLPointer<LLViewerFetchedTexture> > to
  296. // maintain refs to textures associated with each material for free
  297. // ref counting.
  298. void* mUserData;
  299. };
  300. typedef std::map<std::string, LLImportMaterial> material_map;
  301. class LLModelInstanceBase
  302. {
  303. public:
  304. LLModelInstanceBase(LLModel* modelp, const LLMatrix4& transform,
  305. const material_map& materials)
  306. : mModel(modelp),
  307. mTransform(transform),
  308. mMaterial(materials)
  309. {
  310. }
  311. LLModelInstanceBase()
  312. : mModel(NULL)
  313. {
  314. }
  315. virtual ~LLModelInstanceBase()
  316. {
  317. mModel = NULL;
  318. for (U32 i = 0; i < LLModel::NUM_LODS; ++i)
  319. {
  320. mLOD[i] = NULL;
  321. }
  322. }
  323. public:
  324. LLPointer<LLModel> mModel;
  325. LLPointer<LLModel> mLOD[LLModel::NUM_LODS];
  326. LLUUID mMeshID;
  327. LLMatrix4 mTransform;
  328. material_map mMaterial;
  329. };
  330. class LLModelInstance : public LLModelInstanceBase
  331. {
  332. public:
  333. LLModelInstance(LLModel* modelp, const std::string& label,
  334. const LLMatrix4& transform, const material_map& materials)
  335. : LLModelInstanceBase(modelp, transform, materials),
  336. mLabel(label),
  337. mLocalMeshID(-1)
  338. {
  339. }
  340. LLModelInstance(const LLSD& data);
  341. LLSD asLLSD();
  342. public:
  343. LLUUID mMeshID;
  344. S32 mLocalMeshID;
  345. std::string mLabel;
  346. };
  347. #endif //LL_LLMODEL_H