llwearabledata.cpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. /**
  2. * @file llwearabledata.cpp
  3. * @brief LLWearableData class implementation
  4. *
  5. * $LicenseInfo:firstyear=2000&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. #include "linden_common.h"
  33. #include "llwearabledata.h"
  34. #include "llavatarappearance.h"
  35. #include "llavatarappearancedefines.h"
  36. #include "lldriverparam.h"
  37. #include "llmd5.h"
  38. using namespace LLAvatarAppearanceDefines;
  39. LLWearableData::LLWearableData()
  40. : mAvatarAppearance(NULL),
  41. //MK
  42. mCanWearFunc(NULL),
  43. mCanUnwearFunc(NULL)
  44. //mk
  45. {
  46. }
  47. LLWearable* LLWearableData::getWearable(LLWearableType::EType type, U32 index)
  48. {
  49. wearableentry_map_t::iterator it = mWearableDatas.find(type);
  50. if (it == mWearableDatas.end())
  51. {
  52. return NULL;
  53. }
  54. wearableentry_vec_t& wearable_vec = it->second;
  55. return index < wearable_vec.size() ? wearable_vec[index] : NULL;
  56. }
  57. bool LLWearableData::setWearable(LLWearableType::EType type, U32 index,
  58. LLWearable* wearable)
  59. {
  60. //MK
  61. if (mCanWearFunc && !mCanWearFunc(type))
  62. {
  63. return false;
  64. }
  65. //mk
  66. LLWearable* old_wearable = getWearable(type, index);
  67. if (!old_wearable)
  68. {
  69. pushWearable(type, wearable);
  70. return true;
  71. }
  72. //MK
  73. if (mCanUnwearFunc && !mCanUnwearFunc(type))
  74. {
  75. // cannot remove this outfit, so cannot replace it either
  76. return false;
  77. }
  78. //mk
  79. wearableentry_map_t::iterator it = mWearableDatas.find(type);
  80. if (it == mWearableDatas.end())
  81. {
  82. llwarns << "invalid type, type " << type << " index " << index
  83. << llendl;
  84. return false;
  85. }
  86. wearableentry_vec_t& wearable_vec = it->second;
  87. if (index >= wearable_vec.size())
  88. {
  89. llwarns << "invalid index, type " << type << " index " << index
  90. << llendl;
  91. return false;
  92. }
  93. else
  94. {
  95. wearable_vec[index] = wearable;
  96. old_wearable->setUpdated();
  97. wearableUpdated(wearable, false);
  98. }
  99. return true;
  100. }
  101. bool LLWearableData::pushWearable(LLWearableType::EType type,
  102. LLWearable* wearable, bool trigger_updated)
  103. {
  104. if (!wearable)
  105. {
  106. llwarns << "Null wearable sent for type " << type << llendl;
  107. return false;
  108. }
  109. if (canAddWearable(type))
  110. {
  111. //MK
  112. if (mCanWearFunc && !mCanWearFunc(type))
  113. {
  114. return false;
  115. }
  116. //mk
  117. mWearableDatas[type].push_back(wearable);
  118. if (trigger_updated)
  119. {
  120. wearableUpdated(wearable, false);
  121. }
  122. }
  123. return true;
  124. }
  125. //virtual
  126. void LLWearableData::wearableUpdated(LLWearable* wearable, bool removed)
  127. {
  128. wearable->setUpdated();
  129. // *FIXME: avoid updating params via wearables when rendering server-baked
  130. // appearance.
  131. #if 0
  132. if (mAvatarAppearance->isUsingServerBakes() &&
  133. !mAvatarAppearance->isUsingLocalAppearance())
  134. {
  135. return;
  136. }
  137. #endif
  138. if (!removed)
  139. {
  140. pullCrossWearableValues(wearable->getType());
  141. }
  142. }
  143. void LLWearableData::eraseWearable(LLWearable* wearable)
  144. {
  145. if (!wearable)
  146. {
  147. return;
  148. }
  149. U32 index;
  150. if (getWearableIndex(wearable, index))
  151. {
  152. eraseWearable(wearable->getType(), index);
  153. }
  154. }
  155. void LLWearableData::eraseWearable(LLWearableType::EType type, U32 index)
  156. {
  157. LLWearable* wearable = getWearable(type, index);
  158. if (wearable)
  159. {
  160. mWearableDatas[type].erase(mWearableDatas[type].begin() + index);
  161. wearableUpdated(wearable, true);
  162. }
  163. }
  164. void LLWearableData::clearWearableType(LLWearableType::EType type)
  165. {
  166. wearableentry_map_t::iterator it = mWearableDatas.find(type);
  167. if (it == mWearableDatas.end())
  168. {
  169. return;
  170. }
  171. wearableentry_vec_t& wearable_vec = it->second;
  172. wearable_vec.clear();
  173. }
  174. bool LLWearableData::swapWearables(LLWearableType::EType type, U32 index_a,
  175. U32 index_b)
  176. {
  177. wearableentry_map_t::iterator it = mWearableDatas.find(type);
  178. if (it == mWearableDatas.end())
  179. {
  180. return false;
  181. }
  182. wearableentry_vec_t& wearable_vec = it->second;
  183. if (index_a >= wearable_vec.size() || index_b >= wearable_vec.size())
  184. {
  185. return false;
  186. }
  187. LLWearable* wearable = wearable_vec[index_a];
  188. wearable_vec[index_a] = wearable_vec[index_b];
  189. wearable_vec[index_b] = wearable;
  190. return true;
  191. }
  192. void LLWearableData::pullCrossWearableValues(LLWearableType::EType type)
  193. {
  194. if (!mAvatarAppearance)
  195. {
  196. llwarns << "NULL mAvatarAppearance !" << llendl;
  197. llassert(false);
  198. return;
  199. }
  200. // Scan through all of the avatar's visual parameters
  201. for (LLViewerVisualParam* param =
  202. (LLViewerVisualParam*)mAvatarAppearance->getFirstVisualParam();
  203. param;
  204. param = (LLViewerVisualParam*)mAvatarAppearance->getNextVisualParam())
  205. {
  206. if (param)
  207. {
  208. LLDriverParam* driver_param = param->asDriverParam();
  209. if (driver_param)
  210. {
  211. // Parameter is a driver parameter, have it update its
  212. // cross-driven params
  213. driver_param->updateCrossDrivenParams(type);
  214. }
  215. }
  216. }
  217. }
  218. bool LLWearableData::getWearableIndex(const LLWearable* wearable,
  219. U32& index_found) const
  220. {
  221. if (!wearable)
  222. {
  223. return false;
  224. }
  225. LLWearableType::EType type = wearable->getType();
  226. wearableentry_map_t::const_iterator it = mWearableDatas.find(type);
  227. if (it == mWearableDatas.end())
  228. {
  229. llwarns << "Tried to get wearable index with an invalid type !"
  230. << llendl;
  231. return false;
  232. }
  233. const wearableentry_vec_t& wearable_vec = it->second;
  234. for (U32 index = 0, count = wearable_vec.size(); index < count; ++index)
  235. {
  236. if (wearable_vec[index] == wearable)
  237. {
  238. index_found = index;
  239. return true;
  240. }
  241. }
  242. return false;
  243. }
  244. U32 LLWearableData::getClothingLayerCount() const
  245. {
  246. U32 count = 0;
  247. for (S32 i = 0; i < LLWearableType::WT_COUNT; ++i)
  248. {
  249. LLWearableType::EType type = (LLWearableType::EType)i;
  250. if (LLWearableType::getAssetType(type) == LLAssetType::AT_CLOTHING)
  251. {
  252. count += getWearableCount(type);
  253. }
  254. }
  255. return count;
  256. }
  257. bool LLWearableData::canAddWearable(LLWearableType::EType type) const
  258. {
  259. LLAssetType::EType a_type = LLWearableType::getAssetType(type);
  260. if (a_type == LLAssetType::AT_CLOTHING)
  261. {
  262. return getClothingLayerCount() < MAX_CLOTHING_LAYERS;
  263. }
  264. else if (a_type == LLAssetType::AT_BODYPART)
  265. {
  266. return getWearableCount(type) < 1;
  267. }
  268. return false;
  269. }
  270. bool LLWearableData::isOnTop(LLWearable* wearable) const
  271. {
  272. return wearable && getTopWearable(wearable->getType()) == wearable;
  273. }
  274. const LLWearable* LLWearableData::getWearable(LLWearableType::EType type,
  275. U32 index) const
  276. {
  277. wearableentry_map_t::const_iterator it = mWearableDatas.find(type);
  278. if (it == mWearableDatas.end())
  279. {
  280. return NULL;
  281. }
  282. const wearableentry_vec_t& wearable_vec = it->second;
  283. return index < wearable_vec.size() ? wearable_vec[index] : NULL;
  284. }
  285. LLWearable* LLWearableData::getTopWearable(LLWearableType::EType type)
  286. {
  287. U32 count = getWearableCount(type);
  288. return count ? getWearable(type, count - 1) : NULL;
  289. }
  290. const LLWearable* LLWearableData::getTopWearable(LLWearableType::EType type) const
  291. {
  292. U32 count = getWearableCount(type);
  293. return count ? getWearable(type, count - 1) : NULL;
  294. }
  295. LLWearable* LLWearableData::getBottomWearable(LLWearableType::EType type)
  296. {
  297. return getWearableCount(type) ? getWearable(type, 0) : NULL;
  298. }
  299. const LLWearable* LLWearableData::getBottomWearable(LLWearableType::EType type) const
  300. {
  301. return getWearableCount(type) ? getWearable(type, 0) : NULL;
  302. }
  303. U32 LLWearableData::getWearableCount(LLWearableType::EType type) const
  304. {
  305. wearableentry_map_t::const_iterator it = mWearableDatas.find(type);
  306. if (it == mWearableDatas.end())
  307. {
  308. return 0;
  309. }
  310. const wearableentry_vec_t& wearable_vec = it->second;
  311. return wearable_vec.size();
  312. }
  313. U32 LLWearableData::getWearableCount(U32 tex_idx) const
  314. {
  315. LLWearableType::EType wearable_type =
  316. LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)tex_idx);
  317. return getWearableCount(wearable_type);
  318. }
  319. LLUUID LLWearableData::computeBakedTextureHash(EBakedTextureIndex baked_index,
  320. // Set to false if you want to
  321. // upload the baked texture w/o
  322. // putting it in the cache
  323. bool generate_valid_hash)
  324. {
  325. const LLAvatarAppearanceDictionary::BakedEntry* baked_dict =
  326. gAvatarAppDictp->getBakedTexture(baked_index);
  327. LLUUID hash_id;
  328. LLMD5 hash;
  329. bool hash_computed = false;
  330. for (U8 i = 0, count = baked_dict->mWearables.size(); i < count; ++i)
  331. {
  332. LLWearableType::EType baked_type = baked_dict->mWearables[i];
  333. U32 num_wearables = getWearableCount(baked_type);
  334. for (U32 index = 0; index < num_wearables; ++index)
  335. {
  336. const LLWearable* wearable = getWearable(baked_type,index);
  337. if (wearable)
  338. {
  339. wearable->addToBakedTextureHash(hash);
  340. hash_computed = true;
  341. }
  342. }
  343. }
  344. if (hash_computed)
  345. {
  346. hash.update((const unsigned char*)baked_dict->mWearablesHashID.mData,
  347. UUID_BYTES);
  348. if (!generate_valid_hash)
  349. {
  350. invalidateBakedTextureHash(hash);
  351. }
  352. hash.finalize();
  353. hash.raw_digest(hash_id.mData);
  354. }
  355. return hash_id;
  356. }