llprimitive.cpp 47 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014
  1. /**
  2. * @file llprimitive.cpp
  3. * @brief LLPrimitive base class
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewergpl$
  6. *
  7. * Copyright (c) 2001-2009, 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 "llprimitive.h"
  34. #include "llcolor4u.h"
  35. #include "lldatapacker.h"
  36. #include "llmaterialid.h"
  37. #include "llmaterialtable.h"
  38. #include "llmessage.h"
  39. #include "llprimtexturelist.h"
  40. #include "llsdutil_math.h"
  41. #include "llstring.h"
  42. #include "llvolume.h"
  43. #include "llvolumemgr.h"
  44. // gcc 13 sees array bound issues where there are none... HB
  45. #if defined(GCC_VERSION) && GCC_VERSION >= 130000
  46. # pragma GCC diagnostic ignored "-Warray-bounds"
  47. # pragma GCC diagnostic ignored "-Wstringop-overflow"
  48. #endif
  49. // Exported (not so) "constants" (with default value, for SL)
  50. F32 OBJECT_MIN_HOLE_SIZE = 0.05f;
  51. F32 OBJECT_HOLLOW_MAX = 0.95f;
  52. // Old inverted texture: "7595d345-a24c-e7ef-f0bd-78793792133e";
  53. const char* SCULPT_DEFAULT_TEXTURE = "be293869-d0d9-0a69-5989-ad27f1946fd4";
  54. //static
  55. void LLPrimitive::setLimits(bool for_secondlife)
  56. {
  57. if (for_secondlife)
  58. {
  59. OBJECT_HOLLOW_MAX = 0.95f;
  60. OBJECT_MIN_HOLE_SIZE = 0.05f;
  61. }
  62. else
  63. {
  64. OBJECT_HOLLOW_MAX = 0.99f;
  65. OBJECT_MIN_HOLE_SIZE = 0.01f;
  66. }
  67. }
  68. LLPrimitive::LLPrimitive()
  69. : mNumTEs(0),
  70. mMiscFlags(0),
  71. mNumBumpmapTEs(0),
  72. mPrimitiveCode(0),
  73. mMaterial(LL_MCODE_STONE)
  74. {
  75. mChanged = UNCHANGED;
  76. mScale.set(1.f, 1.f, 1.f);
  77. mRotation.loadIdentity();
  78. }
  79. LLPrimitive::~LLPrimitive()
  80. {
  81. // Cleanup handled by volume manager
  82. if (mVolumep && gVolumeMgrp)
  83. {
  84. gVolumeMgrp->unrefVolume(mVolumep);
  85. }
  86. mVolumep = NULL;
  87. }
  88. void LLPrimitive::setPCode(LLPCode p_code)
  89. {
  90. mPrimitiveCode = p_code;
  91. setAvatar(p_code == LL_PCODE_LEGACY_AVATAR);
  92. }
  93. LLTextureEntry* LLPrimitive::getTE(U8 index) const
  94. {
  95. return index != 255 ? mTextureList.getTexture(index) : NULL;
  96. }
  97. //virtual
  98. void LLPrimitive::setNumTEs(U8 num_tes)
  99. {
  100. mTextureList.setSize(num_tes);
  101. }
  102. //virtual
  103. void LLPrimitive::setAllTETextures(const LLUUID& tex_id)
  104. {
  105. mTextureList.setAllIDs(tex_id);
  106. }
  107. //virtual
  108. void LLPrimitive::setTE(U8 index, const LLTextureEntry& te)
  109. {
  110. if (index != 255 &&
  111. mTextureList.copyTexture(index, &te) != TEM_CHANGE_NONE &&
  112. te.getBumpmap() > 0)
  113. {
  114. ++mNumBumpmapTEs;
  115. }
  116. }
  117. //virtual
  118. S32 LLPrimitive::setTETexture(U8 index, const LLUUID& id)
  119. {
  120. return index != 255 ? mTextureList.setID(index, id) : TEM_CHANGE_NONE;
  121. }
  122. //virtual
  123. S32 LLPrimitive::setTEColor(U8 index, const LLColor4& color)
  124. {
  125. return index != 255 ? mTextureList.setColor(index, color)
  126. : TEM_CHANGE_NONE;
  127. }
  128. //virtual
  129. S32 LLPrimitive::setTEColor(U8 index, const LLColor3& color)
  130. {
  131. return index != 255 ? mTextureList.setColor(index, color)
  132. : TEM_CHANGE_NONE;
  133. }
  134. //virtual
  135. S32 LLPrimitive::setTEAlpha(U8 index, F32 alpha)
  136. {
  137. return index != 255 ? mTextureList.setAlpha(index, alpha)
  138. : TEM_CHANGE_NONE;
  139. }
  140. //virtual
  141. S32 LLPrimitive::setTEScale(U8 index, F32 s, F32 t)
  142. {
  143. return index != 255 ? mTextureList.setScale(index, s, t)
  144. : TEM_CHANGE_NONE;
  145. }
  146. // Slow: done this way because texture entries have some voodoo related to
  147. // texture coords
  148. //virtual
  149. S32 LLPrimitive::setTEScaleS(U8 index, F32 s)
  150. {
  151. return index != 255 ? mTextureList.setScaleS(index, s)
  152. : TEM_CHANGE_NONE;
  153. }
  154. // Slow: done this way because texture entries have some voodoo related to
  155. // texture coords
  156. //virtual
  157. S32 LLPrimitive::setTEScaleT(U8 index, F32 t)
  158. {
  159. return index != 255 ? mTextureList.setScaleT(index, t)
  160. : TEM_CHANGE_NONE;
  161. }
  162. //virtual
  163. S32 LLPrimitive::setTEOffset(U8 index, F32 s, F32 t)
  164. {
  165. return index != 255 ? mTextureList.setOffset(index, s, t)
  166. : TEM_CHANGE_NONE;
  167. }
  168. // Slow: done this way because texture entries have some voodoo related to
  169. // texture coords
  170. //virtual
  171. S32 LLPrimitive::setTEOffsetS(U8 index, F32 s)
  172. {
  173. return index != 255 ? mTextureList.setOffsetS(index, s)
  174. : TEM_CHANGE_NONE;
  175. }
  176. // Slow: done this way because texture entries have some voodoo related to
  177. // texture coords
  178. //virtual
  179. S32 LLPrimitive::setTEOffsetT(U8 index, F32 t)
  180. {
  181. return index != 255 ? mTextureList.setOffsetT(index, t)
  182. : TEM_CHANGE_NONE;
  183. }
  184. //virtual
  185. S32 LLPrimitive::setTERotation(U8 index, F32 r)
  186. {
  187. return index != 255 ? mTextureList.setRotation(index, r)
  188. : TEM_CHANGE_NONE;
  189. }
  190. LLMaterialPtr LLPrimitive::getTEMaterialParams(U8 index)
  191. {
  192. return mTextureList.getMaterialParams(index);
  193. }
  194. //virtual
  195. S32 LLPrimitive::setTEBumpShinyFullbright(U8 index, U8 bump)
  196. {
  197. if (index != 255)
  198. {
  199. updateNumBumpmap(index, bump);
  200. return mTextureList.setBumpShinyFullbright(index, bump);
  201. }
  202. return TEM_CHANGE_NONE;
  203. }
  204. S32 LLPrimitive::setTEMediaTexGen(U8 index, U8 media)
  205. {
  206. return index != 255 ? mTextureList.setMediaTexGen(index, media)
  207. : TEM_CHANGE_NONE;
  208. }
  209. //virtual
  210. S32 LLPrimitive::setTEBumpmap(U8 index, U8 bump)
  211. {
  212. if (index != 255)
  213. {
  214. updateNumBumpmap(index, bump);
  215. return mTextureList.setBumpMap(index, bump);
  216. }
  217. return TEM_CHANGE_NONE;
  218. }
  219. //virtual
  220. S32 LLPrimitive::setTEBumpShiny(U8 index, U8 bump_shiny)
  221. {
  222. if (index != 255)
  223. {
  224. updateNumBumpmap(index, bump_shiny);
  225. return mTextureList.setBumpShiny(index, bump_shiny);
  226. }
  227. return TEM_CHANGE_NONE;
  228. }
  229. //virtual
  230. S32 LLPrimitive::setTETexGen(U8 index, U8 texgen)
  231. {
  232. return index != 255 ? mTextureList.setTexGen(index, texgen)
  233. : TEM_CHANGE_NONE;
  234. }
  235. //virtual
  236. S32 LLPrimitive::setTEShiny(U8 index, U8 shiny)
  237. {
  238. return index != 255 ? mTextureList.setShiny(index, shiny)
  239. : TEM_CHANGE_NONE;
  240. }
  241. //virtual
  242. S32 LLPrimitive::setTEFullbright(U8 index, U8 fullbright)
  243. {
  244. return index != 255 ? mTextureList.setFullbright(index, fullbright)
  245. : TEM_CHANGE_NONE;
  246. }
  247. //virtual
  248. S32 LLPrimitive::setTEMediaFlags(U8 index, U8 media_flags)
  249. {
  250. return index != 255 ? mTextureList.setMediaFlags(index, media_flags)
  251. : TEM_CHANGE_NONE;
  252. }
  253. //virtual
  254. S32 LLPrimitive::setTEGlow(U8 index, F32 glow)
  255. {
  256. return index != 255 ? mTextureList.setGlow(index, glow)
  257. : TEM_CHANGE_NONE;
  258. }
  259. //virtual
  260. S32 LLPrimitive::setTEMaterialID(U8 index, const LLMaterialID& matidp)
  261. {
  262. return index != 255 ? mTextureList.setMaterialID(index, matidp)
  263. : TEM_CHANGE_NONE;
  264. }
  265. //virtual
  266. S32 LLPrimitive::setTEMaterialParams(U8 index, const LLMaterialPtr paramsp)
  267. {
  268. return index != 255 ? mTextureList.setMaterialParams(index, paramsp)
  269. : TEM_CHANGE_NONE;
  270. }
  271. //virtual
  272. void LLPrimitive::setAllTESelected(bool sel)
  273. {
  274. for (S32 i = 0, count = getNumTEs(); i < count; ++i)
  275. {
  276. setTESelected(i, sel);
  277. }
  278. }
  279. void LLPrimitive::setTESelected(U8 te, bool sel)
  280. {
  281. LLTextureEntry* tep = getTE(te);
  282. bool was_selected = tep && tep->setSelected(sel);
  283. if (was_selected && !sel && tep->hasPendingMaterialUpdate())
  284. {
  285. LLMaterialID material_id = tep->getMaterialID();
  286. setTEMaterialID(te, material_id);
  287. }
  288. }
  289. // Do not crash or llerrs here ! This function is used for debug strings.
  290. //static
  291. std::string LLPrimitive::pCodeToString(LLPCode pcode)
  292. {
  293. std::string pcode_string;
  294. U8 base_code = pcode & LL_PCODE_BASE_MASK;
  295. if (!pcode)
  296. {
  297. pcode_string = "null";
  298. }
  299. else if (base_code == LL_PCODE_LEGACY)
  300. {
  301. // It is a legacy object
  302. switch (pcode)
  303. {
  304. case LL_PCODE_LEGACY_GRASS:
  305. pcode_string = "grass";
  306. break;
  307. case LL_PCODE_LEGACY_PART_SYS:
  308. pcode_string = "particle system";
  309. break;
  310. case LL_PCODE_LEGACY_AVATAR:
  311. pcode_string = "avatar";
  312. break;
  313. case LL_PCODE_LEGACY_TREE:
  314. pcode_string = "tree";
  315. break;
  316. default:
  317. pcode_string = llformat("unknown legacy pcode %i", (U32)pcode);
  318. }
  319. }
  320. else
  321. {
  322. std::string shape;
  323. std::string mask;
  324. if (base_code == LL_PCODE_CUBE)
  325. {
  326. shape = "cube";
  327. }
  328. else if (base_code == LL_PCODE_CYLINDER)
  329. {
  330. shape = "cylinder";
  331. }
  332. else if (base_code == LL_PCODE_CONE)
  333. {
  334. shape = "cone";
  335. }
  336. else if (base_code == LL_PCODE_PRISM)
  337. {
  338. shape = "prism";
  339. }
  340. else if (base_code == LL_PCODE_PYRAMID)
  341. {
  342. shape = "pyramid";
  343. }
  344. else if (base_code == LL_PCODE_SPHERE)
  345. {
  346. shape = "sphere";
  347. }
  348. else if (base_code == LL_PCODE_TETRAHEDRON)
  349. {
  350. shape = "tetrahedron";
  351. }
  352. else if (base_code == LL_PCODE_VOLUME)
  353. {
  354. shape = "volume";
  355. }
  356. else if (base_code == LL_PCODE_APP)
  357. {
  358. shape = "app";
  359. }
  360. else
  361. {
  362. llwarns << "Unknown base mask for pcode: " << base_code << llendl;
  363. }
  364. U8 mask_code = pcode & (~LL_PCODE_BASE_MASK);
  365. if (base_code == LL_PCODE_APP)
  366. {
  367. mask = llformat("%x", mask_code);
  368. }
  369. else if (mask_code & LL_PCODE_HEMI_MASK)
  370. {
  371. mask = "hemi";
  372. }
  373. else
  374. {
  375. mask = llformat("%x", mask_code);
  376. }
  377. if (mask[0])
  378. {
  379. pcode_string = llformat("%s-%s", shape.c_str(), mask.c_str());
  380. }
  381. else
  382. {
  383. pcode_string = llformat("%s", shape.c_str());
  384. }
  385. }
  386. return pcode_string;
  387. }
  388. void LLPrimitive::copyTEs(const LLPrimitive* primitivep)
  389. {
  390. if (primitivep->getExpectedNumTEs() != getExpectedNumTEs())
  391. {
  392. llwarns << "Primitives do not have same expected number of TE's"
  393. << llendl;
  394. }
  395. U32 num_tes = llmin(primitivep->getExpectedNumTEs(), getExpectedNumTEs());
  396. if (mTextureList.size() < getExpectedNumTEs())
  397. {
  398. mTextureList.setSize(getExpectedNumTEs());
  399. }
  400. for (U32 i = 0; i < num_tes; ++i)
  401. {
  402. mTextureList.copyTexture(i, primitivep->getTE(i));
  403. }
  404. }
  405. S32 face_index_from_id(LLFaceID face_ID,
  406. const std::vector<LLProfile::Face>& faceArray)
  407. {
  408. for (U32 i = 0, count = faceArray.size(); i < count; ++i)
  409. {
  410. if (faceArray[i].mFaceID == face_ID)
  411. {
  412. return i;
  413. }
  414. }
  415. return -1;
  416. }
  417. //virtual
  418. bool LLPrimitive::setVolume(const LLVolumeParams& volume_params,
  419. S32 detail, bool unique_volume)
  420. {
  421. if (detail < 0 || detail >= LLVolumeLODGroup::NUM_LODS)
  422. {
  423. llwarns << "Attempt to set volume with out of range LOD: " << detail
  424. << llendl;
  425. return false;
  426. }
  427. if (!gVolumeMgrp)
  428. {
  429. llwarns << "Attempt to set a volume while the volume manager is not initialized !"
  430. << llendl;
  431. return false;
  432. }
  433. LLVolume* volumep;
  434. if (unique_volume)
  435. {
  436. F32 volume_detail = LLVolumeLODGroup::getVolumeScaleFromDetail(detail);
  437. if (mVolumep.notNull() && volume_params == mVolumep->getParams() &&
  438. volume_detail == mVolumep->getDetail())
  439. {
  440. return false;
  441. }
  442. volumep = new LLVolume(volume_params, volume_detail, false, true);
  443. }
  444. else
  445. {
  446. if (mVolumep.notNull())
  447. {
  448. F32 volume_detail =
  449. LLVolumeLODGroup::getVolumeScaleFromDetail(detail);
  450. if (volume_params == mVolumep->getParams() &&
  451. volume_detail == mVolumep->getDetail())
  452. {
  453. return false;
  454. }
  455. }
  456. volumep = gVolumeMgrp->refVolume(volume_params, detail);
  457. if (volumep == mVolumep)
  458. {
  459. // LLVolumeMgr::refVolume() creates a reference, but we do not need
  460. // a second one.
  461. gVolumeMgrp->unrefVolume(volumep);
  462. return true;
  463. }
  464. }
  465. setChanged(GEOMETRY);
  466. if (!mVolumep)
  467. {
  468. mVolumep = volumep;
  469. setNumTEs(mVolumep->getNumFaces());
  470. return true;
  471. }
  472. // Build the new object
  473. gVolumeMgrp->unrefVolume(mVolumep);
  474. mVolumep = volumep;
  475. setNumTEs(mVolumep->getNumFaces());
  476. return true;
  477. }
  478. //virtual
  479. bool LLPrimitive::setMaterial(U8 material)
  480. {
  481. if (material != mMaterial)
  482. {
  483. mMaterial = material;
  484. return true;
  485. }
  486. return false;
  487. }
  488. S32 LLPrimitive::packTEField(U8* cur_ptr, U8* data_ptr, U8 data_size,
  489. U8 last_face_index, EMsgVariableType type) const
  490. {
  491. U8* start_loc = cur_ptr;
  492. htonmemcpy(cur_ptr, data_ptr + last_face_index * data_size, type,
  493. data_size);
  494. cur_ptr += data_size;
  495. U64 exception_faces;
  496. for (S32 face_index = last_face_index - 1; face_index >= 0; --face_index)
  497. {
  498. bool already_sent = false;
  499. for (S32 i = face_index+1; i <= last_face_index; ++i)
  500. {
  501. if (!memcmp(data_ptr + data_size * face_index,
  502. data_ptr + data_size * i, data_size))
  503. {
  504. already_sent = true;
  505. break;
  506. }
  507. }
  508. if (!already_sent)
  509. {
  510. exception_faces = 0;
  511. for (S32 i = face_index; i >= 0; --i)
  512. {
  513. if (!memcmp(data_ptr+ data_size * face_index,
  514. data_ptr + data_size * i, data_size))
  515. {
  516. exception_faces |= ((U64)1 << i);
  517. }
  518. }
  519. // Assign exception faces to cur_ptr
  520. if (exception_faces >= ((U64)1 << 7))
  521. {
  522. if (exception_faces >= ((U64)1 << 14))
  523. {
  524. if (exception_faces >= ((U64)1 << 21))
  525. {
  526. if (exception_faces >= ((U64)1 << 28))
  527. {
  528. if (exception_faces >= ((U64)1 << 35))
  529. {
  530. if (exception_faces >= ((U64)1 << 42))
  531. {
  532. if (exception_faces >= ((U64)1 << 49))
  533. {
  534. *cur_ptr++ = (U8)(((exception_faces >> 49) & 0x7F) | 0x80);
  535. }
  536. *cur_ptr++ = (U8)(((exception_faces >> 42) & 0x7F) | 0x80);
  537. }
  538. *cur_ptr++ = (U8)(((exception_faces >> 35) & 0x7F) | 0x80);
  539. }
  540. *cur_ptr++ = (U8)(((exception_faces >> 28) & 0x7F) | 0x80);
  541. }
  542. *cur_ptr++ = (U8)(((exception_faces >> 21) & 0x7F) | 0x80);
  543. }
  544. *cur_ptr++ = (U8)(((exception_faces >> 14) & 0x7F) | 0x80);
  545. }
  546. *cur_ptr++ = (U8)(((exception_faces >> 7) & 0x7F) | 0x80);
  547. }
  548. *cur_ptr++ = (U8)(exception_faces & 0x7F);
  549. htonmemcpy(cur_ptr, data_ptr + face_index * data_size, type,
  550. data_size);
  551. cur_ptr += data_size;
  552. }
  553. }
  554. return (S32)(cur_ptr - start_loc);
  555. }
  556. // Pack information about all texture entries into container:
  557. // { TextureEntry Variable 2 }
  558. // Includes information about image ID, color, scale S,T, offset S,T and
  559. // rotation
  560. void LLPrimitive::packTEMessage(LLMessageSystem* mesgsys) const
  561. {
  562. U8 image_ids[MAX_TES * UUID_BYTES];
  563. U8 colors[MAX_TES * 4];
  564. F32 scale_s[MAX_TES];
  565. F32 scale_t[MAX_TES];
  566. S16 offset_s[MAX_TES];
  567. S16 offset_t[MAX_TES];
  568. S16 image_rot[MAX_TES];
  569. U8 bump[MAX_TES];
  570. U8 media_flags[MAX_TES];
  571. U8 glow[MAX_TES];
  572. U8 material_data[MAX_TES * UUID_BYTES];
  573. U8 packed_buffer[MAX_TE_BUFFER];
  574. U8* cur_ptr = packed_buffer;
  575. S32 last_face_index = llmin((U32)getNumTEs(), MAX_TES) - 1;
  576. if (last_face_index > -1)
  577. {
  578. // ...if we hit the front, send one image Id
  579. S8 face_index;
  580. LLColor4U coloru;
  581. for (face_index = 0; face_index <= last_face_index; ++face_index)
  582. {
  583. // Directly sending image_ids is not safe !
  584. memcpy(&image_ids[face_index * UUID_BYTES],
  585. getTE(face_index)->getID().mData, UUID_BYTES);
  586. // Cast LLColor4 to LLColor4U
  587. coloru.set(getTE(face_index)->getColor());
  588. // Note: this is an optimization to send common colors (white) as
  589. // all zeros. However, the subtraction and addition must be done in
  590. // unsigned byte space, not in float space, otherwise off-by-one
  591. // errors occur. JC
  592. colors[4 * face_index] = 255 - coloru.mV[0];
  593. colors[4 * face_index + 1] = 255 - coloru.mV[1];
  594. colors[4 * face_index + 2] = 255 - coloru.mV[2];
  595. colors[4 * face_index + 3] = 255 - coloru.mV[3];
  596. const LLTextureEntry* te = getTE(face_index);
  597. scale_s[face_index] = (F32)te->getScaleS();
  598. scale_t[face_index] = (F32)te->getScaleT();
  599. offset_s[face_index] = (S16)ll_round(llclamp(te->getOffsetS(),
  600. -1.f, 1.f) *
  601. (F32)0x7FFF);
  602. offset_t[face_index] = (S16)ll_round(llclamp(te->getOffsetT(),
  603. -1.f, 1.f) *
  604. (F32)0x7FFF);
  605. image_rot[face_index] = (S16)ll_round((fmodf(te->getRotation(),
  606. F_TWO_PI) /
  607. F_TWO_PI) *
  608. TEXTURE_ROTATION_PACK_FACTOR);
  609. bump[face_index] = te->getBumpShinyFullbright();
  610. media_flags[face_index] = te->getMediaTexGen();
  611. glow[face_index] = (U8)ll_round(llclamp(te->getGlow(), 0.f, 1.f) *
  612. (F32)0xFF);
  613. // Directly sending material_ids is not safe !
  614. memcpy(&material_data[face_index * UUID_BYTES],
  615. getTE(face_index)->getMaterialID().get(), UUID_BYTES);
  616. }
  617. cur_ptr += packTEField(cur_ptr, (U8*)image_ids, sizeof(LLUUID),
  618. last_face_index, MVT_LLUUID);
  619. *cur_ptr++ = 0;
  620. cur_ptr += packTEField(cur_ptr, (U8*)colors, 4, last_face_index,
  621. MVT_U8);
  622. *cur_ptr++ = 0;
  623. cur_ptr += packTEField(cur_ptr, (U8*)scale_s, 4, last_face_index,
  624. MVT_F32);
  625. *cur_ptr++ = 0;
  626. cur_ptr += packTEField(cur_ptr, (U8*)scale_t, 4, last_face_index,
  627. MVT_F32);
  628. *cur_ptr++ = 0;
  629. cur_ptr += packTEField(cur_ptr, (U8*)offset_s, 2, last_face_index,
  630. MVT_S16Array);
  631. *cur_ptr++ = 0;
  632. cur_ptr += packTEField(cur_ptr, (U8*)offset_t, 2, last_face_index,
  633. MVT_S16Array);
  634. *cur_ptr++ = 0;
  635. cur_ptr += packTEField(cur_ptr, (U8*)image_rot, 2, last_face_index,
  636. MVT_S16Array);
  637. *cur_ptr++ = 0;
  638. cur_ptr += packTEField(cur_ptr, (U8*)bump, 1, last_face_index, MVT_U8);
  639. *cur_ptr++ = 0;
  640. cur_ptr += packTEField(cur_ptr, (U8*)media_flags, 1, last_face_index,
  641. MVT_U8);
  642. *cur_ptr++ = 0;
  643. cur_ptr += packTEField(cur_ptr, (U8*)glow, 1, last_face_index, MVT_U8);
  644. *cur_ptr++ = 0;
  645. cur_ptr += packTEField(cur_ptr, (U8*)material_data, UUID_BYTES,
  646. last_face_index, MVT_LLUUID);
  647. }
  648. mesgsys->addBinaryDataFast(_PREHASH_TextureEntry, packed_buffer,
  649. (S32)(cur_ptr - packed_buffer));
  650. }
  651. void LLPrimitive::packTEMessage(LLDataPacker& dp) const
  652. {
  653. U8 image_ids[MAX_TES * UUID_BYTES];
  654. U8 colors[MAX_TES * 4];
  655. F32 scale_s[MAX_TES];
  656. F32 scale_t[MAX_TES];
  657. S16 offset_s[MAX_TES];
  658. S16 offset_t[MAX_TES];
  659. S16 image_rot[MAX_TES];
  660. U8 bump[MAX_TES];
  661. U8 media_flags[MAX_TES];
  662. U8 glow[MAX_TES];
  663. U8 material_data[MAX_TES * UUID_BYTES];
  664. U8 packed_buffer[MAX_TE_BUFFER];
  665. U8* cur_ptr = packed_buffer;
  666. S32 last_face_index = llmin((U32)getNumTEs(), MAX_TES) - 1;
  667. if (last_face_index > -1)
  668. {
  669. // ...if we hit the front, send one image id
  670. S8 face_index;
  671. LLColor4U coloru;
  672. for (face_index = 0; face_index <= last_face_index; ++face_index)
  673. {
  674. // Directly sending image_ids is not safe!
  675. memcpy(&image_ids[face_index * UUID_BYTES],
  676. getTE(face_index)->getID().mData, UUID_BYTES);
  677. // Cast LLColor4 to LLColor4U
  678. coloru.set(getTE(face_index)->getColor());
  679. // Note: this is an optimization to send common colors (white) as
  680. // all zeros. However, the subtraction and addition must be done in
  681. // unsigned byte space, not in float space, otherwise off-by-one
  682. // errors occur. JC
  683. colors[4 * face_index] = 255 - coloru.mV[0];
  684. colors[4 * face_index + 1] = 255 - coloru.mV[1];
  685. colors[4 * face_index + 2] = 255 - coloru.mV[2];
  686. colors[4 * face_index + 3] = 255 - coloru.mV[3];
  687. const LLTextureEntry* te = getTE(face_index);
  688. scale_s[face_index] = (F32)te->getScaleS();
  689. scale_t[face_index] = (F32)te->getScaleT();
  690. offset_s[face_index] = (S16)ll_round(llclamp(te->getOffsetS(),
  691. -1.f, 1.f) *
  692. (F32)0x7FFF);
  693. offset_t[face_index] = (S16)ll_round(llclamp(te->getOffsetT(),
  694. -1.f, 1.f) *
  695. (F32)0x7FFF);
  696. image_rot[face_index] = (S16)ll_round((fmodf(te->getRotation(),
  697. F_TWO_PI) /
  698. F_TWO_PI) *
  699. TEXTURE_ROTATION_PACK_FACTOR);
  700. bump[face_index] = te->getBumpShinyFullbright();
  701. media_flags[face_index] = te->getMediaTexGen();
  702. glow[face_index] = (U8)ll_round(llclamp(te->getGlow(), 0.f, 1.f) *
  703. (F32)0xFF);
  704. // Directly sending material_ids is not safe!
  705. memcpy(&material_data[face_index * UUID_BYTES],
  706. getTE(face_index)->getMaterialID().get(), UUID_BYTES);
  707. }
  708. cur_ptr += packTEField(cur_ptr, (U8*)image_ids, sizeof(LLUUID),
  709. last_face_index, MVT_LLUUID);
  710. *cur_ptr++ = 0;
  711. cur_ptr += packTEField(cur_ptr, (U8*)colors, 4, last_face_index,
  712. MVT_U8);
  713. *cur_ptr++ = 0;
  714. cur_ptr += packTEField(cur_ptr, (U8*)scale_s, 4, last_face_index,
  715. MVT_F32);
  716. *cur_ptr++ = 0;
  717. cur_ptr += packTEField(cur_ptr, (U8*)scale_t, 4, last_face_index,
  718. MVT_F32);
  719. *cur_ptr++ = 0;
  720. cur_ptr += packTEField(cur_ptr, (U8*)offset_s, 2, last_face_index,
  721. MVT_S16Array);
  722. *cur_ptr++ = 0;
  723. cur_ptr += packTEField(cur_ptr, (U8*)offset_t, 2, last_face_index,
  724. MVT_S16Array);
  725. *cur_ptr++ = 0;
  726. cur_ptr += packTEField(cur_ptr, (U8*)image_rot, 2, last_face_index,
  727. MVT_S16Array);
  728. *cur_ptr++ = 0;
  729. cur_ptr += packTEField(cur_ptr, (U8*)bump, 1, last_face_index, MVT_U8);
  730. *cur_ptr++ = 0;
  731. cur_ptr += packTEField(cur_ptr, (U8*)media_flags, 1, last_face_index,
  732. MVT_U8);
  733. *cur_ptr++ = 0;
  734. cur_ptr += packTEField(cur_ptr, (U8*)glow, 1, last_face_index, MVT_U8);
  735. *cur_ptr++ = 0;
  736. cur_ptr += packTEField(cur_ptr, (U8*)material_data, UUID_BYTES,
  737. last_face_index, MVT_LLUUID);
  738. }
  739. dp.packBinaryData(packed_buffer, (S32)(cur_ptr - packed_buffer),
  740. "TextureEntry");
  741. }
  742. namespace LLTEField
  743. {
  744. template<typename T>
  745. bool unpack(T dest[], U8 dest_count, U8*& source, U8* source_end,
  746. EMsgVariableType type)
  747. {
  748. constexpr size_t size = sizeof(T);
  749. // We add 1 to take into account the byte that we know must follow the
  750. // value.
  751. if (source + size + 1 > source_end)
  752. {
  753. llwarns << "Buffer exhausted: " << size + 1
  754. << " bytes needed and only " << source_end - source
  755. << " bytes remaining." << llendl;
  756. source = source_end;
  757. return false;
  758. }
  759. // Extract the default value and fill up the array with it.
  760. htonmemcpy(dest, source, type, size);
  761. source += size;
  762. for (S32 i = 1; i < dest_count; ++i)
  763. {
  764. dest[i] = dest[0];
  765. }
  766. while (source < source_end)
  767. {
  768. // Unpack the variable length bitfield. Each bit represents
  769. // whether the following value will be placed at the corresponding
  770. // array index.
  771. U64 index_flags = 0;
  772. U8 sbit = 0;
  773. do
  774. {
  775. if (source >= source_end)
  776. {
  777. llwarns << "Buffer exhausted while reading index flags."
  778. << llendl;
  779. source = source_end;
  780. return false;
  781. }
  782. sbit = *source++;
  783. index_flags <<= 7;
  784. index_flags |= sbit & 0X7F;
  785. }
  786. while (sbit & 0x80);
  787. if (!index_flags)
  788. {
  789. // We have hit the terminating 0 byte.
  790. break;
  791. }
  792. if (source + size + 1 > source_end)
  793. {
  794. llwarns << "Buffer exhausted: " << size + 1
  795. << " bytes needed and only " << source_end - source
  796. << " bytes remaining." << llendl;
  797. source = source_end;
  798. return false;
  799. }
  800. // Get the value for indexes
  801. T value;
  802. htonmemcpy(&value, source, type, size);
  803. source += size;
  804. U64 mask = 1;
  805. for (S32 i = 0; i < dest_count; ++i)
  806. {
  807. if (index_flags & mask)
  808. {
  809. dest[i] = value;
  810. }
  811. mask <<= 1;
  812. }
  813. }
  814. return true;
  815. }
  816. }
  817. S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys,
  818. char const* block_name, S32 block_num,
  819. LLTEContents& tec)
  820. {
  821. if (block_num < 0)
  822. {
  823. tec.size = mesgsys->getSizeFast(block_name, _PREHASH_TextureEntry);
  824. }
  825. else
  826. {
  827. tec.size = mesgsys->getSizeFast(block_name, block_num,
  828. _PREHASH_TextureEntry);
  829. }
  830. if (tec.size == 0)
  831. {
  832. tec.face_count = 0;
  833. return 0;
  834. }
  835. if (tec.size >= MAX_TE_BUFFER)
  836. {
  837. llwarns << "Excessive buffer size detected in texture entry; truncating."
  838. << llendl;
  839. tec.size = MAX_TE_BUFFER - 1;
  840. }
  841. S32 block = 0;
  842. if (block_num > 0)
  843. {
  844. block = block_num;
  845. }
  846. mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry,
  847. tec.packed_buffer, 0, block, MAX_TE_BUFFER - 1);
  848. // The last field is not zero-terminated. Rather than a special case for
  849. // unpack functions, just add the missing null byte.
  850. tec.packed_buffer[tec.size++] = 0x00;
  851. tec.face_count = llmin((U32)getNumTEs(), MAX_TES);
  852. U8* cur_ptr = tec.packed_buffer;
  853. U8* buffer_end = tec.packed_buffer + tec.size;
  854. const U8 dest_count = tec.face_count;
  855. bool success =
  856. LLTEField::unpack<LLUUID>(tec.image_data, dest_count, cur_ptr,
  857. buffer_end, MVT_LLUUID) &&
  858. LLTEField::unpack<LLColor4U>(tec.colors, dest_count, cur_ptr,
  859. buffer_end, MVT_U8) &&
  860. LLTEField::unpack<F32>(tec.scale_s, dest_count, cur_ptr, buffer_end,
  861. MVT_F32) &&
  862. LLTEField::unpack<F32>(tec.scale_t, dest_count, cur_ptr, buffer_end,
  863. MVT_F32) &&
  864. LLTEField::unpack<S16>(tec.offset_s, dest_count, cur_ptr, buffer_end,
  865. MVT_S16) &&
  866. LLTEField::unpack<S16>(tec.offset_t, dest_count, cur_ptr, buffer_end,
  867. MVT_S16) &&
  868. LLTEField::unpack<S16>(tec.image_rot, dest_count, cur_ptr, buffer_end,
  869. MVT_S16) &&
  870. LLTEField::unpack<U8>(tec.bump, dest_count, cur_ptr, buffer_end,
  871. MVT_U8) &&
  872. LLTEField::unpack<U8>(tec.media_flags, dest_count, cur_ptr, buffer_end,
  873. MVT_U8) &&
  874. LLTEField::unpack<U8>(tec.glow, dest_count, cur_ptr, buffer_end,
  875. MVT_U8);
  876. if (!success)
  877. {
  878. llwarns << "Failure parsing texture entry message due to malformed TE field."
  879. << llendl;
  880. return 0;
  881. }
  882. // Buffer for material ID processing. Static to avoid memory reallocations.
  883. static LLUUID material_data[MAX_TES];
  884. if (cur_ptr >= buffer_end ||
  885. !LLTEField::unpack<LLUUID>(material_data, dest_count, cur_ptr,
  886. buffer_end, MVT_LLUUID))
  887. {
  888. memset((void*)material_data, 0, sizeof(material_data));
  889. }
  890. for (U32 i = 0; i < dest_count; ++i)
  891. {
  892. tec.material_ids[i].set(&material_data[i]);
  893. }
  894. return 1;
  895. }
  896. S32 LLPrimitive::applyParsedTEMessage(LLTEContents& tec)
  897. {
  898. S32 retval = 0;
  899. LLColor4 color;
  900. for (U32 i = 0; i < tec.face_count; ++i)
  901. {
  902. LLUUID& req_id = ((LLUUID*)tec.image_data)[i];
  903. retval |= setTETexture(i, req_id);
  904. retval |= setTEScale(i, tec.scale_s[i], tec.scale_t[i]);
  905. retval |= setTEOffset(i, (F32)tec.offset_s[i] / (F32)0x7FFF,
  906. (F32)tec.offset_t[i] / (F32)0x7FFF);
  907. retval |= setTERotation(i, ((F32)tec.image_rot[i] /
  908. TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI);
  909. retval |= setTEBumpShinyFullbright(i, tec.bump[i]);
  910. retval |= setTEMediaTexGen(i, tec.media_flags[i]);
  911. retval |= setTEGlow(i, (F32)tec.glow[i] / (F32)0xFF);
  912. retval |= setTEMaterialID(i, tec.material_ids[i]);
  913. // Note: this is an optimization to send common colors (white) as all
  914. // zeros. However, the subtraction and addition must be done in
  915. // unsigned byte space, not in float space, otherwise off-by-one errors
  916. // occur. JC
  917. const LLColor4U& coloru = tec.colors[i];
  918. color.mV[VRED] = F32(255 - coloru.mV[VRED]) / 255.f;
  919. color.mV[VGREEN] = F32(255 - coloru.mV[VGREEN]) / 255.f;
  920. color.mV[VBLUE] = F32(255 - coloru.mV[VBLUE]) / 255.f;
  921. color.mV[VALPHA] = F32(255 - coloru.mV[VALPHA]) / 255.f;
  922. retval |= setTEColor(i, color);
  923. }
  924. return retval;
  925. }
  926. S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys,
  927. char const* block_name, S32 block_num)
  928. {
  929. LLTEContents tec;
  930. S32 retval = parseTEMessage(mesgsys, block_name, block_num, tec);
  931. if (!retval)
  932. {
  933. return retval;
  934. }
  935. return applyParsedTEMessage(tec);
  936. }
  937. S32 LLPrimitive::unpackTEMessage(LLDataPacker& dp)
  938. {
  939. // Avoid construction of 90 UUIDs + 45 LLColor4U + 90 F32 + 135 S16 +
  940. // 135 U8 + a 4096 bytes buffer per call...
  941. static LLTEContents data;
  942. memset((void*)&data, 0, sizeof(data));
  943. S32 size;
  944. if (!dp.unpackBinaryData(data.packed_buffer, size, "TextureEntry"))
  945. {
  946. llwarns << "Bad texture entry block ! Aborted !" << llendl;
  947. return TEM_INVALID;
  948. }
  949. if (size == 0)
  950. {
  951. return 0;
  952. }
  953. if ((U32)size >= MAX_TE_BUFFER)
  954. {
  955. llwarns << "Excessive buffer size detected in texture entry; truncating."
  956. << llendl;
  957. size = MAX_TE_BUFFER - 1;
  958. }
  959. // The last field is not zero-terminated. Rather than a special case for
  960. // unpack functions, just add the missing null byte.
  961. data.packed_buffer[size++] = 0x00;
  962. U32 face_count = llmin((U32)getNumTEs(), MAX_TES);
  963. U8* cur_ptr = data.packed_buffer;
  964. U8* buffer_end = cur_ptr + size;
  965. bool success =
  966. LLTEField::unpack<LLUUID>(data.image_data, face_count, cur_ptr,
  967. buffer_end, MVT_LLUUID) &&
  968. LLTEField::unpack<LLColor4U>(data.colors, face_count, cur_ptr,
  969. buffer_end, MVT_U8) &&
  970. LLTEField::unpack<F32>(data.scale_s, face_count, cur_ptr, buffer_end,
  971. MVT_F32) &&
  972. LLTEField::unpack<F32>(data.scale_t, face_count, cur_ptr, buffer_end,
  973. MVT_F32) &&
  974. LLTEField::unpack<S16>(data.offset_s, face_count, cur_ptr, buffer_end,
  975. MVT_S16) &&
  976. LLTEField::unpack<S16>(data.offset_t, face_count, cur_ptr, buffer_end,
  977. MVT_S16) &&
  978. LLTEField::unpack<S16>(data.image_rot, face_count, cur_ptr, buffer_end,
  979. MVT_S16) &&
  980. LLTEField::unpack<U8>(data.bump, face_count, cur_ptr, buffer_end,
  981. MVT_U8) &&
  982. LLTEField::unpack<U8>(data.media_flags, face_count, cur_ptr, buffer_end,
  983. MVT_U8) &&
  984. LLTEField::unpack<U8>(data.glow, face_count, cur_ptr, buffer_end,
  985. MVT_U8);
  986. if (!success)
  987. {
  988. llwarns << "Failure parsing texture entry message due to malformed TE field."
  989. << llendl;
  990. return 0;
  991. }
  992. // Buffer for material ID processing. Static to avoid memory reallocations.
  993. static LLUUID material_data[MAX_TES];
  994. if (cur_ptr >= buffer_end ||
  995. !LLTEField::unpack<LLUUID>(material_data, face_count, cur_ptr,
  996. buffer_end, MVT_LLUUID))
  997. {
  998. memset((void*)material_data, 0, sizeof(material_data));
  999. }
  1000. for (U32 i = 0; i < face_count; ++i)
  1001. {
  1002. data.material_ids[i].set(&material_data[i]);
  1003. }
  1004. S32 retval = 0;
  1005. LLColor4 color;
  1006. for (U32 i = 0; i < face_count; ++i)
  1007. {
  1008. retval |= setTETexture(i, data.image_data[i]);
  1009. retval |= setTEScale(i, data.scale_s[i], data.scale_t[i]);
  1010. retval |= setTEOffset(i, (F32)data.offset_s[i] / (F32)0x7FFF,
  1011. (F32)data.offset_t[i] / (F32)0x7FFF);
  1012. retval |= setTERotation(i,
  1013. ((F32)data.image_rot[i] /
  1014. TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI);
  1015. retval |= setTEBumpShinyFullbright(i, data.bump[i]);
  1016. retval |= setTEMediaTexGen(i, data.media_flags[i]);
  1017. retval |= setTEGlow(i, (F32)data.glow[i] / (F32)0xFF);
  1018. retval |= setTEMaterialID(i, data.material_ids[i]);
  1019. // Note: this is an optimization to send common colors (white) as all
  1020. // zeros. However, the subtraction and addition must be done in
  1021. // unsigned byte space, not in float space, otherwise off-by-one
  1022. // errors occur. JC
  1023. const LLColor4U& coloru = data.colors[i];
  1024. color.mV[VRED] = F32(255 - coloru.mV[VRED]) / 255.f;
  1025. color.mV[VGREEN] = F32(255 - coloru.mV[VGREEN]) / 255.f;
  1026. color.mV[VBLUE] = F32(255 - coloru.mV[VBLUE]) / 255.f;
  1027. color.mV[VALPHA] = F32(255 - coloru.mV[VALPHA]) / 255.f;
  1028. retval |= setTEColor(i, color);
  1029. }
  1030. return retval;
  1031. }
  1032. U8 LLPrimitive::getExpectedNumTEs() const
  1033. {
  1034. U8 expected_face_count = 0;
  1035. if (mVolumep)
  1036. {
  1037. expected_face_count = mVolumep->getNumFaces();
  1038. }
  1039. return expected_face_count;
  1040. }
  1041. void LLPrimitive::copyTextureList(const LLPrimTextureList& other_list)
  1042. {
  1043. mTextureList.copy(other_list);
  1044. }
  1045. void LLPrimitive::takeTextureList(LLPrimTextureList& other_list)
  1046. {
  1047. mTextureList.take(other_list);
  1048. }
  1049. void LLPrimitive::updateNumBumpmap(U8 index, U8 bump)
  1050. {
  1051. LLTextureEntry* te = getTE(index);
  1052. if (!te)
  1053. {
  1054. return;
  1055. }
  1056. U8 old_bump = te->getBumpmap();
  1057. if (old_bump > 0)
  1058. {
  1059. --mNumBumpmapTEs;
  1060. }
  1061. if ((bump & TEM_BUMP_MASK) > 0)
  1062. {
  1063. ++mNumBumpmapTEs;
  1064. }
  1065. }
  1066. //============================================================================
  1067. // Moved from llselectmgr.cpp
  1068. // Limitation: only works for boxes.
  1069. // Face numbering for flex boxes as of 1.14.2
  1070. //static
  1071. bool LLPrimitive::getTESTAxes(U8 face, U32* s_axis, U32* t_axis)
  1072. {
  1073. if (face == 0)
  1074. {
  1075. *s_axis = VX; *t_axis = VY;
  1076. return true;
  1077. }
  1078. else if (face == 1)
  1079. {
  1080. *s_axis = VX; *t_axis = VZ;
  1081. return true;
  1082. }
  1083. else if (face == 2)
  1084. {
  1085. *s_axis = VY; *t_axis = VZ;
  1086. return true;
  1087. }
  1088. else if (face == 3)
  1089. {
  1090. *s_axis = VX; *t_axis = VZ;
  1091. return true;
  1092. }
  1093. else if (face == 4)
  1094. {
  1095. *s_axis = VY; *t_axis = VZ;
  1096. return true;
  1097. }
  1098. else if (face == 5)
  1099. {
  1100. *s_axis = VX; *t_axis = VY;
  1101. return true;
  1102. }
  1103. else if (face == 6)
  1104. {
  1105. *s_axis = VX; *t_axis = VY;
  1106. return true;
  1107. }
  1108. else
  1109. {
  1110. // Unknown face
  1111. return false;
  1112. }
  1113. }
  1114. //============================================================================
  1115. //static
  1116. bool LLNetworkData::isValid(U16 param_type, U32 size)
  1117. {
  1118. switch (param_type)
  1119. {
  1120. case PARAMS_FLEXIBLE:
  1121. return size == 16;
  1122. case PARAMS_LIGHT:
  1123. return size == 16;
  1124. case PARAMS_SCULPT:
  1125. return size == 17;
  1126. case PARAMS_LIGHT_IMAGE:
  1127. return size == 28;
  1128. case PARAMS_EXTENDED_MESH:
  1129. return size == 4;
  1130. case PARAMS_RENDER_MATERIAL:
  1131. return size > 1;
  1132. case PARAMS_REFLECTION_PROBE:
  1133. return size == 9;
  1134. }
  1135. return false;
  1136. }
  1137. //============================================================================
  1138. LLLightParams::LLLightParams()
  1139. {
  1140. mColor.setToWhite();
  1141. mRadius = 10.f;
  1142. mCutoff = 0.f;
  1143. mFalloff = 0.75f;
  1144. mType = PARAMS_LIGHT;
  1145. }
  1146. bool LLLightParams::pack(LLDataPacker& dp) const
  1147. {
  1148. LLColor4U color4u(mColor);
  1149. dp.packColor4U(color4u, "color");
  1150. dp.packF32(mRadius, "radius");
  1151. dp.packF32(mCutoff, "cutoff");
  1152. dp.packF32(mFalloff, "falloff");
  1153. return true;
  1154. }
  1155. bool LLLightParams::unpack(LLDataPacker& dp)
  1156. {
  1157. LLColor4U color;
  1158. dp.unpackColor4U(color, "color");
  1159. setLinearColor(LLColor4(color));
  1160. F32 radius;
  1161. dp.unpackF32(radius, "radius");
  1162. setRadius(radius);
  1163. F32 cutoff;
  1164. dp.unpackF32(cutoff, "cutoff");
  1165. setCutoff(cutoff);
  1166. F32 falloff;
  1167. dp.unpackF32(falloff, "falloff");
  1168. setFalloff(falloff);
  1169. return true;
  1170. }
  1171. bool LLLightParams::operator==(const LLNetworkData& data) const
  1172. {
  1173. if (data.mType != PARAMS_LIGHT)
  1174. {
  1175. return false;
  1176. }
  1177. const LLLightParams* param = (const LLLightParams*)&data;
  1178. if (param->mColor != mColor || param->mRadius != mRadius ||
  1179. param->mCutoff != mCutoff || param->mFalloff != mFalloff)
  1180. {
  1181. return false;
  1182. }
  1183. return true;
  1184. }
  1185. void LLLightParams::copy(const LLNetworkData& data)
  1186. {
  1187. const LLLightParams* param = (LLLightParams*)&data;
  1188. mType = param->mType;
  1189. mColor = param->mColor;
  1190. mRadius = param->mRadius;
  1191. mCutoff = param->mCutoff;
  1192. mFalloff = param->mFalloff;
  1193. }
  1194. LLSD LLLightParams::asLLSD() const
  1195. {
  1196. LLSD sd;
  1197. sd["color"] = ll_sd_from_color4(getLinearColor());
  1198. sd["radius"] = getRadius();
  1199. sd["falloff"] = getFalloff();
  1200. sd["cutoff"] = getCutoff();
  1201. return sd;
  1202. }
  1203. bool LLLightParams::fromLLSD(LLSD& sd)
  1204. {
  1205. const char* w;
  1206. w = "color";
  1207. if (sd.has(w))
  1208. {
  1209. setLinearColor(ll_color4_from_sd(sd[w]));
  1210. }
  1211. else
  1212. {
  1213. return false;
  1214. }
  1215. w = "radius";
  1216. if (sd.has(w))
  1217. {
  1218. setRadius((F32)sd[w].asReal());
  1219. }
  1220. else
  1221. {
  1222. return false;
  1223. }
  1224. w = "falloff";
  1225. if (sd.has(w))
  1226. {
  1227. setFalloff((F32)sd[w].asReal());
  1228. }
  1229. else
  1230. {
  1231. return false;
  1232. }
  1233. w = "cutoff";
  1234. if (sd.has(w))
  1235. {
  1236. setCutoff((F32)sd[w].asReal());
  1237. }
  1238. else
  1239. {
  1240. return false;
  1241. }
  1242. return true;
  1243. }
  1244. //============================================================================
  1245. LLFlexibleObjectData::LLFlexibleObjectData()
  1246. {
  1247. mSimulateLOD = FLEXIBLE_OBJECT_DEFAULT_NUM_SECTIONS;
  1248. mGravity = FLEXIBLE_OBJECT_DEFAULT_GRAVITY;
  1249. mAirFriction = FLEXIBLE_OBJECT_DEFAULT_AIR_FRICTION;
  1250. mWindSensitivity = FLEXIBLE_OBJECT_DEFAULT_WIND_SENSITIVITY;
  1251. mTension = FLEXIBLE_OBJECT_DEFAULT_TENSION;
  1252. mUserForce = LLVector3(0.f, 0.f, 0.f);
  1253. mType = PARAMS_FLEXIBLE;
  1254. #if 0
  1255. mUsingCollisionSphere = FLEXIBLE_OBJECT_DEFAULT_USING_COLLISION_SPHERE;
  1256. mRenderingCollisionSphere = FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE;
  1257. #endif
  1258. }
  1259. bool LLFlexibleObjectData::pack(LLDataPacker& dp) const
  1260. {
  1261. // Custom, uber-svelte pack "softness" in upper bits of tension & drag
  1262. U8 bit1 = (mSimulateLOD & 2) << 6;
  1263. U8 bit2 = (mSimulateLOD & 1) << 7;
  1264. dp.packU8((U8)(mTension * 10.01f) + bit1, "tension");
  1265. dp.packU8((U8)(mAirFriction * 10.01f) + bit2, "drag");
  1266. dp.packU8((U8)((mGravity + 10.f) * 10.01f), "gravity");
  1267. dp.packU8((U8)(mWindSensitivity * 10.01f), "wind");
  1268. dp.packVector3(mUserForce, "userforce");
  1269. return true;
  1270. }
  1271. bool LLFlexibleObjectData::unpack(LLDataPacker& dp)
  1272. {
  1273. U8 tension, friction, gravity, wind;
  1274. U8 bit1, bit2;
  1275. dp.unpackU8(tension, "tension");
  1276. bit1 = (tension >> 6) & 2;
  1277. mTension = (F32)(tension & 0x7f) / 10.f;
  1278. dp.unpackU8(friction, "drag");
  1279. bit2 = (friction >> 7) & 1;
  1280. mAirFriction = (F32)(friction & 0x7f) / 10.f;
  1281. mSimulateLOD = bit1 | bit2;
  1282. dp.unpackU8(gravity, "gravity");
  1283. mGravity = (F32)gravity / 10.f - 10.f;
  1284. dp.unpackU8(wind, "wind");
  1285. mWindSensitivity = (F32)wind / 10.f;
  1286. if (dp.hasNext())
  1287. {
  1288. dp.unpackVector3(mUserForce, "userforce");
  1289. }
  1290. else
  1291. {
  1292. mUserForce.set(0.f, 0.f, 0.f);
  1293. }
  1294. return true;
  1295. }
  1296. bool LLFlexibleObjectData::operator==(const LLNetworkData& data) const
  1297. {
  1298. if (data.mType != PARAMS_FLEXIBLE)
  1299. {
  1300. return false;
  1301. }
  1302. LLFlexibleObjectData *flex_data = (LLFlexibleObjectData*)&data;
  1303. return (mSimulateLOD == flex_data->mSimulateLOD &&
  1304. mGravity == flex_data->mGravity &&
  1305. mAirFriction == flex_data->mAirFriction &&
  1306. mWindSensitivity == flex_data->mWindSensitivity &&
  1307. mTension == flex_data->mTension &&
  1308. mUserForce == flex_data->mUserForce);
  1309. #if 0
  1310. mUsingCollisionSphere == flex_data->mUsingCollisionSphere &&
  1311. mRenderingCollisionSphere == flex_data->mRenderingCollisionSphere;
  1312. #endif
  1313. }
  1314. void LLFlexibleObjectData::copy(const LLNetworkData& data)
  1315. {
  1316. const LLFlexibleObjectData *flex_data = (LLFlexibleObjectData*)&data;
  1317. mSimulateLOD = flex_data->mSimulateLOD;
  1318. mGravity = flex_data->mGravity;
  1319. mAirFriction = flex_data->mAirFriction;
  1320. mWindSensitivity = flex_data->mWindSensitivity;
  1321. mTension = flex_data->mTension;
  1322. mUserForce = flex_data->mUserForce;
  1323. #if 0
  1324. mUsingCollisionSphere = flex_data->mUsingCollisionSphere;
  1325. mRenderingCollisionSphere = flex_data->mRenderingCollisionSphere;
  1326. #endif
  1327. }
  1328. LLSD LLFlexibleObjectData::asLLSD() const
  1329. {
  1330. LLSD sd;
  1331. sd["air_friction"] = getAirFriction();
  1332. sd["gravity"] = getGravity();
  1333. sd["simulate_lod"] = getSimulateLOD();
  1334. sd["tension"] = getTension();
  1335. sd["user_force"] = getUserForce().getValue();
  1336. sd["wind_sensitivity"] = getWindSensitivity();
  1337. return sd;
  1338. }
  1339. bool LLFlexibleObjectData::fromLLSD(LLSD& sd)
  1340. {
  1341. const char* w;
  1342. w = "air_friction";
  1343. if (sd.has(w))
  1344. {
  1345. setAirFriction((F32)sd[w].asReal());
  1346. }
  1347. else
  1348. {
  1349. return false;
  1350. }
  1351. w = "gravity";
  1352. if (sd.has(w))
  1353. {
  1354. setGravity((F32)sd[w].asReal());
  1355. }
  1356. else
  1357. {
  1358. return false;
  1359. }
  1360. w = "simulate_lod";
  1361. if (sd.has(w))
  1362. {
  1363. setSimulateLOD(sd[w].asInteger());
  1364. }
  1365. else
  1366. {
  1367. return false;
  1368. }
  1369. w = "tension";
  1370. if (sd.has(w))
  1371. {
  1372. setTension((F32)sd[w].asReal());
  1373. }
  1374. else
  1375. {
  1376. return false;
  1377. }
  1378. w = "user_force";
  1379. if (sd.has(w))
  1380. {
  1381. LLVector3 user_force = ll_vector3_from_sd(sd[w], 0);
  1382. setUserForce(user_force);
  1383. }
  1384. else
  1385. {
  1386. return false;
  1387. }
  1388. w = "wind_sensitivity";
  1389. if (sd.has(w))
  1390. {
  1391. setWindSensitivity((F32)sd[w].asReal());
  1392. }
  1393. else
  1394. {
  1395. return false;
  1396. }
  1397. return true;
  1398. }
  1399. //============================================================================
  1400. LLSculptParams::LLSculptParams()
  1401. {
  1402. mType = PARAMS_SCULPT;
  1403. mSculptTexture.set(SCULPT_DEFAULT_TEXTURE);
  1404. mSculptType = LL_SCULPT_TYPE_SPHERE;
  1405. }
  1406. bool LLSculptParams::pack(LLDataPacker& dp) const
  1407. {
  1408. dp.packUUID(mSculptTexture, "texture");
  1409. dp.packU8(mSculptType, "type");
  1410. return true;
  1411. }
  1412. bool LLSculptParams::unpack(LLDataPacker& dp)
  1413. {
  1414. LLUUID id;
  1415. dp.unpackUUID(id, "texture");
  1416. U8 type;
  1417. dp.unpackU8(type, "type");
  1418. setSculptTexture(id, type);
  1419. return true;
  1420. }
  1421. bool LLSculptParams::operator==(const LLNetworkData& data) const
  1422. {
  1423. if (data.mType != PARAMS_SCULPT)
  1424. {
  1425. return false;
  1426. }
  1427. const LLSculptParams* param = (const LLSculptParams*)&data;
  1428. return param->mSculptTexture == mSculptTexture &&
  1429. param->mSculptType == mSculptType;
  1430. }
  1431. void LLSculptParams::copy(const LLNetworkData& data)
  1432. {
  1433. const LLSculptParams* param = (LLSculptParams*)&data;
  1434. setSculptTexture(param->mSculptTexture, param->mSculptType);
  1435. }
  1436. LLSD LLSculptParams::asLLSD() const
  1437. {
  1438. LLSD sd;
  1439. sd["texture"] = mSculptTexture;
  1440. sd["type"] = mSculptType;
  1441. return sd;
  1442. }
  1443. bool LLSculptParams::fromLLSD(LLSD& sd)
  1444. {
  1445. if (sd.has("type") && sd.has("texture"))
  1446. {
  1447. setSculptTexture(sd["texture"].asUUID(), sd["type"].asInteger());
  1448. return true;
  1449. }
  1450. return false;
  1451. }
  1452. void LLSculptParams::setSculptTexture(const LLUUID& texture_id, U8 sculpt_type)
  1453. {
  1454. U8 type = sculpt_type & LL_SCULPT_TYPE_MASK;
  1455. U8 flags = sculpt_type & LL_SCULPT_FLAG_MASK;
  1456. if (sculpt_type != (type | flags) || type > LL_SCULPT_TYPE_MAX)
  1457. {
  1458. mSculptTexture.set(SCULPT_DEFAULT_TEXTURE);
  1459. mSculptType = LL_SCULPT_TYPE_SPHERE;
  1460. }
  1461. else
  1462. {
  1463. mSculptTexture = texture_id;
  1464. mSculptType = sculpt_type;
  1465. }
  1466. }
  1467. //============================================================================
  1468. LLLightImageParams::LLLightImageParams()
  1469. {
  1470. mType = PARAMS_LIGHT_IMAGE;
  1471. mParams.set(F_PI * 0.5f, 0.f, 0.f);
  1472. }
  1473. bool LLLightImageParams::pack(LLDataPacker& dp) const
  1474. {
  1475. dp.packUUID(mLightTexture, "texture");
  1476. dp.packVector3(mParams, "params");
  1477. return true;
  1478. }
  1479. bool LLLightImageParams::unpack(LLDataPacker& dp)
  1480. {
  1481. dp.unpackUUID(mLightTexture, "texture");
  1482. dp.unpackVector3(mParams, "params");
  1483. return true;
  1484. }
  1485. bool LLLightImageParams::operator==(const LLNetworkData& data) const
  1486. {
  1487. if (data.mType != PARAMS_LIGHT_IMAGE)
  1488. {
  1489. return false;
  1490. }
  1491. const LLLightImageParams* param = (const LLLightImageParams*)&data;
  1492. return param->mLightTexture == mLightTexture && param->mParams == mParams;
  1493. }
  1494. void LLLightImageParams::copy(const LLNetworkData& data)
  1495. {
  1496. const LLLightImageParams* param = (LLLightImageParams*)&data;
  1497. mLightTexture = param->mLightTexture;
  1498. mParams = param->mParams;
  1499. }
  1500. LLSD LLLightImageParams::asLLSD() const
  1501. {
  1502. LLSD sd;
  1503. sd["texture"] = mLightTexture;
  1504. sd["params"] = mParams.getValue();
  1505. return sd;
  1506. }
  1507. bool LLLightImageParams::fromLLSD(LLSD& sd)
  1508. {
  1509. if (sd.has("texture"))
  1510. {
  1511. setLightTexture(sd["texture"]);
  1512. setParams(LLVector3(sd["params"]));
  1513. return true;
  1514. }
  1515. return false;
  1516. }
  1517. //============================================================================
  1518. LLExtendedMeshParams::LLExtendedMeshParams()
  1519. {
  1520. mType = PARAMS_EXTENDED_MESH;
  1521. mFlags = 0;
  1522. }
  1523. bool LLExtendedMeshParams::pack(LLDataPacker& dp) const
  1524. {
  1525. dp.packU32(mFlags, "flags");
  1526. return true;
  1527. }
  1528. bool LLExtendedMeshParams::unpack(LLDataPacker& dp)
  1529. {
  1530. dp.unpackU32(mFlags, "flags");
  1531. return true;
  1532. }
  1533. bool LLExtendedMeshParams::operator==(const LLNetworkData& data) const
  1534. {
  1535. if (data.mType != PARAMS_EXTENDED_MESH)
  1536. {
  1537. return false;
  1538. }
  1539. const LLExtendedMeshParams* param = (const LLExtendedMeshParams*)&data;
  1540. if (param->mFlags != mFlags)
  1541. {
  1542. return false;
  1543. }
  1544. return true;
  1545. }
  1546. void LLExtendedMeshParams::copy(const LLNetworkData& data)
  1547. {
  1548. const LLExtendedMeshParams* param = (LLExtendedMeshParams*)&data;
  1549. mFlags = param->mFlags;
  1550. }
  1551. LLSD LLExtendedMeshParams::asLLSD() const
  1552. {
  1553. LLSD sd;
  1554. sd["flags"] = LLSD::Integer(mFlags);
  1555. return sd;
  1556. }
  1557. bool LLExtendedMeshParams::fromLLSD(LLSD& sd)
  1558. {
  1559. if (sd.has("flags"))
  1560. {
  1561. setFlags(sd["flags"].asInteger());
  1562. return true;
  1563. }
  1564. return false;
  1565. }
  1566. //============================================================================
  1567. // Relfection probes constants:
  1568. const F32 REFLECTION_PROBE_MIN_AMBIANCE = 0.f;
  1569. const F32 REFLECTION_PROBE_MAX_AMBIANCE = 100.f;
  1570. const F32 REFLECTION_PROBE_DEFAULT_AMBIANCE = 0.f;
  1571. // Note: clip distances are clamped in LLCamera::setNear. The max clip distance
  1572. // is currently limited by the skybox.
  1573. const F32 REFLECTION_PROBE_MIN_CLIP_DISTANCE = 0.f;
  1574. const F32 REFLECTION_PROBE_MAX_CLIP_DISTANCE = 1024.f;
  1575. const F32 REFLECTION_PROBE_DEFAULT_CLIP_DISTANCE = 0.f;
  1576. LLReflectionProbeParams::LLReflectionProbeParams()
  1577. : mAmbiance(REFLECTION_PROBE_DEFAULT_AMBIANCE),
  1578. mClipDistance(REFLECTION_PROBE_DEFAULT_CLIP_DISTANCE),
  1579. mFlags(0)
  1580. {
  1581. mType = PARAMS_REFLECTION_PROBE;
  1582. }
  1583. bool LLReflectionProbeParams::pack(LLDataPacker& dp) const
  1584. {
  1585. dp.packF32(mAmbiance, "ambiance");
  1586. dp.packF32(mClipDistance, "clip_distance");
  1587. dp.packU8(mFlags, "flags");
  1588. return true;
  1589. }
  1590. bool LLReflectionProbeParams::unpack(LLDataPacker& dp)
  1591. {
  1592. F32 ambiance;
  1593. dp.unpackF32(ambiance, "ambiance");
  1594. setAmbiance(ambiance);
  1595. F32 clip_distance;
  1596. dp.unpackF32(clip_distance, "clip_distance");
  1597. setClipDistance(clip_distance);
  1598. dp.unpackU8(mFlags, "flags");
  1599. return true;
  1600. }
  1601. bool LLReflectionProbeParams::operator==(const LLNetworkData& data) const
  1602. {
  1603. if (data.mType != PARAMS_REFLECTION_PROBE)
  1604. {
  1605. return false;
  1606. }
  1607. const LLReflectionProbeParams* paramp =
  1608. (const LLReflectionProbeParams*)&data;
  1609. if (paramp->mAmbiance != mAmbiance)
  1610. {
  1611. return false;
  1612. }
  1613. if (paramp->mClipDistance != mClipDistance)
  1614. {
  1615. return false;
  1616. }
  1617. if (paramp->mFlags != mFlags)
  1618. {
  1619. return false;
  1620. }
  1621. return true;
  1622. }
  1623. void LLReflectionProbeParams::copy(const LLNetworkData& data)
  1624. {
  1625. const LLReflectionProbeParams* paramp = (LLReflectionProbeParams*)&data;
  1626. mType = paramp->mType;
  1627. mAmbiance = paramp->mAmbiance;
  1628. mClipDistance = paramp->mClipDistance;
  1629. mFlags = paramp->mFlags;
  1630. }
  1631. LLSD LLReflectionProbeParams::asLLSD() const
  1632. {
  1633. LLSD sd;
  1634. sd["ambiance"] = getAmbiance();
  1635. sd["clip_distance"] = getClipDistance();
  1636. sd["flags"] = LLSD::Integer(mFlags);
  1637. return sd;
  1638. }
  1639. bool LLReflectionProbeParams::fromLLSD(LLSD& sd)
  1640. {
  1641. if (sd.has("ambiance") && sd.has("clip_distance") && sd.has("flags"))
  1642. {
  1643. setAmbiance((F32)sd["ambiance"].asReal());
  1644. setClipDistance((F32)sd["clip_distance"].asReal());
  1645. mFlags = (U8)sd["flags"].asInteger();
  1646. return true;
  1647. }
  1648. return false;
  1649. }
  1650. //============================================================================
  1651. LLRenderMaterialParams::LLRenderMaterialParams()
  1652. {
  1653. mType = PARAMS_RENDER_MATERIAL;
  1654. }
  1655. bool LLRenderMaterialParams::pack(LLDataPacker& dp) const
  1656. {
  1657. // Limited to 255 bytes, no more than 14 material Ids
  1658. U8 count = (U8)llmin(mEntries.size(), 14);
  1659. dp.packU8(count, "count");
  1660. for (U8 i = 0; i < count; ++i)
  1661. {
  1662. const Entry& entry = mEntries[i];
  1663. dp.packU8(entry.te_idx, "te_idx");
  1664. dp.packUUID(entry.id, "id");
  1665. }
  1666. return true;
  1667. }
  1668. bool LLRenderMaterialParams::unpack(LLDataPacker& dp)
  1669. {
  1670. U8 count;
  1671. dp.unpackU8(count, "count");
  1672. mEntries.clear();
  1673. mEntries.reserve(count);
  1674. U8 te_idx;
  1675. LLUUID id;
  1676. for (U32 i = 0; i < count; ++i)
  1677. {
  1678. dp.unpackU8(te_idx, "te_idx");
  1679. dp.unpackUUID(id, "te_id");
  1680. mEntries.emplace_back(te_idx, id);
  1681. }
  1682. return true;
  1683. }
  1684. bool LLRenderMaterialParams::operator==(const LLNetworkData& data) const
  1685. {
  1686. if (data.mType != PARAMS_RENDER_MATERIAL)
  1687. {
  1688. return false;
  1689. }
  1690. const LLRenderMaterialParams* paramp =
  1691. (const LLRenderMaterialParams*)&data;
  1692. size_t count = mEntries.size();
  1693. if (paramp->mEntries.size() != count)
  1694. {
  1695. return false;
  1696. }
  1697. for (size_t i = 0; i < count; ++i)
  1698. {
  1699. const Entry& entry = mEntries[i];
  1700. if (paramp->getMaterial(entry.te_idx) != entry.id)
  1701. {
  1702. return false;
  1703. }
  1704. }
  1705. return true;
  1706. }
  1707. void LLRenderMaterialParams::copy(const LLNetworkData& data)
  1708. {
  1709. mEntries = ((const LLRenderMaterialParams*)&data)->mEntries;
  1710. }
  1711. #if 0 // Not used
  1712. LLSD LLRenderMaterialParams::asLLSD() const
  1713. {
  1714. LLSD sd;
  1715. for (U32 i = 0, count = mEntries.size(); i < count; ++i)
  1716. {
  1717. const Entry& entry = mEntries[i];
  1718. sd[i]["te_idx"] = entry.te_idx;
  1719. sd[i]["id"] = entry.id;
  1720. }
  1721. return sd;
  1722. }
  1723. bool LLRenderMaterialParams::fromLLSD(LLSD& sd)
  1724. {
  1725. if (!sd.isArray())
  1726. {
  1727. return false;
  1728. }
  1729. U32 count = sd.size();
  1730. mEntries.clear();
  1731. mEntries.reserve(count);
  1732. for (U32 i = 0; i < count; ++i)
  1733. {
  1734. if (!sd[i].has("te_idx") || !sd[i].has("id"))
  1735. {
  1736. return false;
  1737. }
  1738. mEntries.emplace_back(sd[i]["te_idx"].asInteger(),
  1739. sd[i]["id"].asUUID());
  1740. }
  1741. return true;
  1742. }
  1743. #endif
  1744. void LLRenderMaterialParams::setMaterial(U8 te, const LLUUID& id)
  1745. {
  1746. bool erase_entry = id.isNull();
  1747. for (U32 i = 0, count = mEntries.size(); i < count; ++i)
  1748. {
  1749. Entry& entry = mEntries[i];
  1750. if (entry.te_idx == te)
  1751. {
  1752. if (erase_entry)
  1753. {
  1754. mEntries.erase(mEntries.begin() + i);
  1755. }
  1756. else
  1757. {
  1758. entry.id = id;
  1759. }
  1760. return;
  1761. }
  1762. }
  1763. // This is a new te entry.
  1764. mEntries.emplace_back(te, id);
  1765. }
  1766. const LLUUID& LLRenderMaterialParams::getMaterial(U8 te) const
  1767. {
  1768. for (U32 i = 0, count = mEntries.size(); i < count; ++i)
  1769. {
  1770. const Entry& entry = mEntries[i];
  1771. if (entry.te_idx == te)
  1772. {
  1773. return entry.id;
  1774. }
  1775. }
  1776. return LLUUID::null;
  1777. }