llprimitive.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:48k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llprimitive.cpp
  3.  * @brief LLPrimitive base class
  4.  *
  5.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2001-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 "material_codes.h"
  34. #include "llmemtype.h"
  35. #include "llerror.h"
  36. #include "message.h"
  37. #include "llprimitive.h"
  38. #include "llvolume.h"
  39. #include "legacy_object_types.h"
  40. #include "v4coloru.h"
  41. #include "llvolumemgr.h"
  42. #include "llstring.h"
  43. #include "lldatapacker.h"
  44. #include "llsdutil_math.h"
  45. #include "llprimtexturelist.h"
  46. /**
  47.  * exported constants
  48.  */
  49. const F32 OBJECT_CUT_MIN = 0.f;
  50. const F32 OBJECT_CUT_MAX = 1.f;
  51. const F32 OBJECT_CUT_INC = 0.05f;
  52. const F32 OBJECT_MIN_CUT_INC = 0.02f;
  53. const F32 OBJECT_ROTATION_PRECISION = 0.05f;
  54. const F32 OBJECT_TWIST_MIN = -360.f;
  55. const F32 OBJECT_TWIST_MAX =  360.f;
  56. const F32 OBJECT_TWIST_INC =   18.f;
  57. // This is used for linear paths,
  58. // since twist is used in a slightly different manner.
  59. const F32 OBJECT_TWIST_LINEAR_MIN = -180.f;
  60. const F32 OBJECT_TWIST_LINEAR_MAX =  180.f;
  61. const F32 OBJECT_TWIST_LINEAR_INC =    9.f;
  62. const F32 OBJECT_MIN_HOLE_SIZE = 0.05f;
  63. const F32 OBJECT_MAX_HOLE_SIZE_X = 1.0f;
  64. const F32 OBJECT_MAX_HOLE_SIZE_Y = 0.5f;
  65. // Revolutions parameters.
  66. const F32 OBJECT_REV_MIN = 1.0f;
  67. const F32 OBJECT_REV_MAX = 4.0f;
  68. const F32 OBJECT_REV_INC = 0.1f;
  69. // lights
  70. const F32 LIGHT_MIN_RADIUS = 0.0f;
  71. const F32 LIGHT_DEFAULT_RADIUS = 5.0f;
  72. const F32 LIGHT_MAX_RADIUS = 20.0f;
  73. const F32 LIGHT_MIN_FALLOFF = 0.0f;
  74. const F32 LIGHT_DEFAULT_FALLOFF = 1.0f;
  75. const F32 LIGHT_MAX_FALLOFF = 2.0f;
  76. const F32 LIGHT_MIN_CUTOFF = 0.0f;
  77. const F32 LIGHT_DEFAULT_CUTOFF = 0.0f;
  78. const F32 LIGHT_MAX_CUTOFF = 180.f;
  79. // "Tension" => [0,10], increments of 0.1
  80. const F32 FLEXIBLE_OBJECT_MIN_TENSION = 0.0f;
  81. const F32 FLEXIBLE_OBJECT_DEFAULT_TENSION = 1.0f;
  82. const F32 FLEXIBLE_OBJECT_MAX_TENSION = 10.0f; 
  83. // "Drag" => [0,10], increments of 0.1
  84. const F32 FLEXIBLE_OBJECT_MIN_AIR_FRICTION = 0.0f;
  85. const F32 FLEXIBLE_OBJECT_DEFAULT_AIR_FRICTION = 2.0f;
  86. const F32 FLEXIBLE_OBJECT_MAX_AIR_FRICTION = 10.0f;
  87. // "Gravity" = [-10,10], increments of 0.1
  88. const F32 FLEXIBLE_OBJECT_MIN_GRAVITY = -10.0f;
  89. const F32 FLEXIBLE_OBJECT_DEFAULT_GRAVITY = 0.3f;
  90. const F32 FLEXIBLE_OBJECT_MAX_GRAVITY = 10.0f;
  91. // "Wind" = [0,10], increments of 0.1
  92. const F32 FLEXIBLE_OBJECT_MIN_WIND_SENSITIVITY = 0.0f;
  93. const F32 FLEXIBLE_OBJECT_DEFAULT_WIND_SENSITIVITY = 0.0f;
  94. const F32 FLEXIBLE_OBJECT_MAX_WIND_SENSITIVITY = 10.0f;
  95. // I'll explain later...
  96. const F32 FLEXIBLE_OBJECT_MAX_INTERNAL_TENSION_FORCE = 0.99f; 
  97. const F32 FLEXIBLE_OBJECT_DEFAULT_LENGTH = 1.0f;
  98. const BOOL FLEXIBLE_OBJECT_DEFAULT_USING_COLLISION_SPHERE = FALSE;
  99. const BOOL FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE = FALSE;
  100. const S32 MAX_FACE_BITS = 9;
  101. const char *SCULPT_DEFAULT_TEXTURE = "be293869-d0d9-0a69-5989-ad27f1946fd4"; // old inverted texture: "7595d345-a24c-e7ef-f0bd-78793792133e";
  102. // Texture rotations are sent over the wire as a S16.  This is used to scale the actual float
  103. // value to a S16.   Don't use 7FFF as it introduces some odd rounding with 180 since it 
  104. // can't be divided by 2.   See DEV-19108
  105. const F32 TEXTURE_ROTATION_PACK_FACTOR = ((F32) 0x08000);
  106. //static 
  107. // LEGACY: by default we use the LLVolumeMgr::gVolumeMgr global
  108. // TODO -- eliminate this global from the codebase!
  109. LLVolumeMgr* LLPrimitive::sVolumeManager = NULL;
  110. // static
  111. void LLPrimitive::setVolumeManager( LLVolumeMgr* volume_manager )
  112. {
  113. if ( !volume_manager || sVolumeManager )
  114. {
  115. llerrs << "LLPrimitive::sVolumeManager attempting to be set to NULL or it already has been set." << llendl;
  116. }
  117. sVolumeManager = volume_manager;
  118. }
  119. // static
  120. bool LLPrimitive::cleanupVolumeManager()
  121. {
  122. BOOL res = FALSE;
  123. if (sVolumeManager) 
  124. {
  125. res = sVolumeManager->cleanup();
  126. delete sVolumeManager;
  127. sVolumeManager = NULL;
  128. }
  129. return res;
  130. }
  131. //===============================================================
  132. LLPrimitive::LLPrimitive()
  133. : mTextureList(),
  134. mNumTEs(0),
  135. mMiscFlags(0)
  136. {
  137. mPrimitiveCode = 0;
  138. mMaterial = LL_MCODE_STONE;
  139. mVolumep  = NULL;
  140. mChanged  = UNCHANGED;
  141. mPosition.setVec(0.f,0.f,0.f);
  142. mVelocity.setVec(0.f,0.f,0.f);
  143. mAcceleration.setVec(0.f,0.f,0.f);
  144. mRotation.loadIdentity();
  145. mAngularVelocity.setVec(0.f,0.f,0.f);
  146. mScale.setVec(1.f,1.f,1.f);
  147. }
  148. //===============================================================
  149. LLPrimitive::~LLPrimitive()
  150. {
  151. clearTextureList();
  152. // Cleanup handled by volume manager
  153. if (mVolumep)
  154. {
  155. sVolumeManager->unrefVolume(mVolumep);
  156. }
  157. mVolumep = NULL;
  158. }
  159. void LLPrimitive::clearTextureList()
  160. {
  161. }
  162. //===============================================================
  163. // static
  164. LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code)
  165. {
  166. LLMemType m1(LLMemType::MTYPE_PRIMITIVE);
  167. LLPrimitive *retval = new LLPrimitive();
  168. if (retval)
  169. {
  170. retval->init_primitive(p_code);
  171. }
  172. else
  173. {
  174. llerrs << "primitive allocation failed" << llendl;
  175. }
  176. return retval;
  177. }
  178. //===============================================================
  179. void LLPrimitive::init_primitive(LLPCode p_code)
  180. {
  181. LLMemType m1(LLMemType::MTYPE_PRIMITIVE);
  182. clearTextureList();
  183. mPrimitiveCode = p_code;
  184. }
  185. void LLPrimitive::setPCode(const U8 p_code)
  186. {
  187. mPrimitiveCode = p_code;
  188. }
  189. //===============================================================
  190. LLTextureEntry* LLPrimitive::getTE(const U8 index) const
  191. {
  192. return mTextureList.getTexture(index);
  193. }
  194. //===============================================================
  195. void LLPrimitive::setNumTEs(const U8 num_tes)
  196. {
  197. mTextureList.setSize(num_tes);
  198. }
  199. //===============================================================
  200. void  LLPrimitive::setAllTETextures(const LLUUID &tex_id)
  201. {
  202. mTextureList.setAllIDs(tex_id);
  203. }
  204. //===============================================================
  205. void LLPrimitive::setTE(const U8 index, const LLTextureEntry& te)
  206. {
  207. mTextureList.copyTexture(index, te);
  208. }
  209. S32  LLPrimitive::setTETexture(const U8 index, const LLUUID &id)
  210. {
  211. return mTextureList.setID(index, id);
  212. }
  213. S32  LLPrimitive::setTEColor(const U8 index, const LLColor4 &color)
  214. {
  215. return mTextureList.setColor(index, color);
  216. }
  217. S32  LLPrimitive::setTEColor(const U8 index, const LLColor3 &color)
  218. {
  219. return mTextureList.setColor(index, color);
  220. }
  221. S32  LLPrimitive::setTEAlpha(const U8 index, const F32 alpha)
  222. {
  223. return mTextureList.setAlpha(index, alpha);
  224. }
  225. //===============================================================
  226. S32  LLPrimitive::setTEScale(const U8 index, const F32 s, const F32 t)
  227. {
  228. return mTextureList.setScale(index, s, t);
  229. }
  230. // BUG: slow - done this way because texture entries have some
  231. // voodoo related to texture coords
  232. S32 LLPrimitive::setTEScaleS(const U8 index, const F32 s)
  233. {
  234. return mTextureList.setScaleS(index, s);
  235. }
  236. // BUG: slow - done this way because texture entries have some
  237. // voodoo related to texture coords
  238. S32 LLPrimitive::setTEScaleT(const U8 index, const F32 t)
  239. {
  240. return mTextureList.setScaleT(index, t);
  241. }
  242. //===============================================================
  243. S32  LLPrimitive::setTEOffset(const U8 index, const F32 s, const F32 t)
  244. {
  245. return mTextureList.setOffset(index, s, t);
  246. }
  247. // BUG: slow - done this way because texture entries have some
  248. // voodoo related to texture coords
  249. S32 LLPrimitive::setTEOffsetS(const U8 index, const F32 s)
  250. {
  251. return mTextureList.setOffsetS(index, s);
  252. }
  253. // BUG: slow - done this way because texture entries have some
  254. // voodoo related to texture coords
  255. S32 LLPrimitive::setTEOffsetT(const U8 index, const F32 t)
  256. {
  257. return mTextureList.setOffsetT(index, t);
  258. }
  259. //===============================================================
  260. S32  LLPrimitive::setTERotation(const U8 index, const F32 r)
  261. {
  262. return mTextureList.setRotation(index, r);
  263. }
  264. //===============================================================
  265. S32  LLPrimitive::setTEBumpShinyFullbright(const U8 index, const U8 bump)
  266. {
  267. return mTextureList.setBumpShinyFullbright(index, bump);
  268. }
  269. S32  LLPrimitive::setTEMediaTexGen(const U8 index, const U8 media)
  270. {
  271. return mTextureList.setMediaTexGen(index, media);
  272. }
  273. S32  LLPrimitive::setTEBumpmap(const U8 index, const U8 bump)
  274. {
  275. return mTextureList.setBumpMap(index, bump);
  276. }
  277. S32  LLPrimitive::setTEBumpShiny(const U8 index, const U8 bump_shiny)
  278. {
  279. return mTextureList.setBumpShiny(index, bump_shiny);
  280. }
  281. S32  LLPrimitive::setTETexGen(const U8 index, const U8 texgen)
  282. {
  283. return mTextureList.setTexGen(index, texgen);
  284. }
  285. S32  LLPrimitive::setTEShiny(const U8 index, const U8 shiny)
  286. {
  287. return mTextureList.setShiny(index, shiny);
  288. }
  289. S32  LLPrimitive::setTEFullbright(const U8 index, const U8 fullbright)
  290. {
  291. return mTextureList.setFullbright(index, fullbright);
  292. }
  293. S32  LLPrimitive::setTEMediaFlags(const U8 index, const U8 media_flags)
  294. {
  295. return mTextureList.setMediaFlags(index, media_flags);
  296. }
  297. S32 LLPrimitive::setTEGlow(const U8 index, const F32 glow)
  298. {
  299. return mTextureList.setGlow(index, glow);
  300. }
  301. LLPCode LLPrimitive::legacyToPCode(const U8 legacy)
  302. {
  303. // TODO: Should this default to something valid?
  304. // Maybe volume?
  305. LLPCode pcode = 0;
  306. switch (legacy)
  307. {
  308. /*
  309. case BOX:
  310. pcode = LL_PCODE_CUBE;
  311. break;
  312. case CYLINDER:
  313. pcode = LL_PCODE_CYLINDER;
  314. break;
  315. case CONE:
  316. pcode = LL_PCODE_CONE;
  317. break;
  318. case HALF_CONE:
  319. pcode = LL_PCODE_CONE_HEMI;
  320. break;
  321. case HALF_CYLINDER:
  322. pcode = LL_PCODE_CYLINDER_HEMI;
  323. break;
  324. case HALF_SPHERE:
  325. pcode = LL_PCODE_SPHERE_HEMI;
  326. break;
  327. case PRISM:
  328. pcode = LL_PCODE_PRISM;
  329. break;
  330. case PYRAMID:
  331. pcode = LL_PCODE_PYRAMID;
  332. break;
  333. case SPHERE:
  334. pcode = LL_PCODE_SPHERE;
  335. break;
  336. case TETRAHEDRON:
  337. pcode = LL_PCODE_TETRAHEDRON;
  338. break;
  339. case DEMON:
  340. pcode = LL_PCODE_LEGACY_DEMON;
  341. break;
  342. case LSL_TEST:
  343. pcode = LL_PCODE_LEGACY_LSL_TEST;
  344. break;
  345. case ORACLE:
  346. pcode = LL_PCODE_LEGACY_ORACLE;
  347. break;
  348. case TEXTBUBBLE:
  349. pcode = LL_PCODE_LEGACY_TEXT_BUBBLE;
  350. break;
  351. case ATOR:
  352. pcode = LL_PCODE_LEGACY_ATOR;
  353. break;
  354. case BASIC_SHOT:
  355. pcode = LL_PCODE_LEGACY_SHOT;
  356. break;
  357. case BIG_SHOT:
  358. pcode = LL_PCODE_LEGACY_SHOT_BIG;
  359. break;
  360. case BIRD:
  361. pcode = LL_PCODE_LEGACY_BIRD;
  362. break;
  363. case ROCK:
  364. pcode = LL_PCODE_LEGACY_ROCK;
  365. break;
  366. case SMOKE:
  367. pcode = LL_PCODE_LEGACY_SMOKE;
  368. break;
  369. case SPARK:
  370. pcode = LL_PCODE_LEGACY_SPARK;
  371. break;
  372. */
  373. case PRIMITIVE_VOLUME:
  374. pcode = LL_PCODE_VOLUME;
  375. break;
  376. case GRASS:
  377. pcode = LL_PCODE_LEGACY_GRASS;
  378. break;
  379. case PART_SYS:
  380. pcode = LL_PCODE_LEGACY_PART_SYS;
  381. break;
  382. case PLAYER:
  383. pcode = LL_PCODE_LEGACY_AVATAR;
  384. break;
  385. case TREE:
  386. pcode = LL_PCODE_LEGACY_TREE;
  387. break;
  388. case TREE_NEW:
  389. pcode = LL_PCODE_TREE_NEW;
  390. break;
  391. default:
  392. llwarns << "Unknown legacy code " << legacy << " [" << (S32)legacy << "]!" << llendl;
  393. }
  394. return pcode;
  395. }
  396. U8 LLPrimitive::pCodeToLegacy(const LLPCode pcode)
  397. {
  398. U8 legacy;
  399. switch (pcode)
  400. {
  401. /*
  402. case LL_PCODE_CUBE:
  403. legacy = BOX;
  404. break;
  405. case LL_PCODE_CYLINDER:
  406. legacy = CYLINDER;
  407. break;
  408. case LL_PCODE_CONE:
  409. legacy = CONE;
  410. break;
  411. case LL_PCODE_CONE_HEMI:
  412. legacy = HALF_CONE;
  413. break;
  414. case LL_PCODE_CYLINDER_HEMI:
  415. legacy = HALF_CYLINDER;
  416. break;
  417. case LL_PCODE_SPHERE_HEMI:
  418. legacy = HALF_SPHERE;
  419. break;
  420. case LL_PCODE_PRISM:
  421. legacy = PRISM;
  422. break;
  423. case LL_PCODE_PYRAMID:
  424. legacy = PYRAMID;
  425. break;
  426. case LL_PCODE_SPHERE:
  427. legacy = SPHERE;
  428. break;
  429. case LL_PCODE_TETRAHEDRON:
  430. legacy = TETRAHEDRON;
  431. break;
  432. case LL_PCODE_LEGACY_ATOR:
  433. legacy = ATOR;
  434. break;
  435. case LL_PCODE_LEGACY_SHOT:
  436. legacy = BASIC_SHOT;
  437. break;
  438. case LL_PCODE_LEGACY_SHOT_BIG:
  439. legacy = BIG_SHOT;
  440. break;
  441. case LL_PCODE_LEGACY_BIRD:
  442. legacy = BIRD;
  443. break;
  444. case LL_PCODE_LEGACY_DEMON:
  445. legacy = DEMON;
  446. break;
  447. case LL_PCODE_LEGACY_LSL_TEST:
  448. legacy = LSL_TEST;
  449. break;
  450. case LL_PCODE_LEGACY_ORACLE:
  451. legacy = ORACLE;
  452. break;
  453. case LL_PCODE_LEGACY_ROCK:
  454. legacy = ROCK;
  455. break;
  456. case LL_PCODE_LEGACY_TEXT_BUBBLE:
  457. legacy = TEXTBUBBLE;
  458. break;
  459. case LL_PCODE_LEGACY_SMOKE:
  460. legacy = SMOKE;
  461. break;
  462. case LL_PCODE_LEGACY_SPARK:
  463. legacy = SPARK;
  464. break;
  465. */
  466. case LL_PCODE_VOLUME:
  467. legacy = PRIMITIVE_VOLUME;
  468. break;
  469. case LL_PCODE_LEGACY_GRASS:
  470. legacy = GRASS;
  471. break;
  472. case LL_PCODE_LEGACY_PART_SYS:
  473. legacy = PART_SYS;
  474. break;
  475. case LL_PCODE_LEGACY_AVATAR:
  476. legacy = PLAYER;
  477. break;
  478. case LL_PCODE_LEGACY_TREE:
  479. legacy = TREE;
  480. break;
  481. case LL_PCODE_TREE_NEW:
  482. legacy = TREE_NEW;
  483. break;
  484. default:
  485. llwarns << "Unknown pcode " << (S32)pcode << ":" << pcode << "!" << llendl;
  486. return 0;
  487. }
  488. return legacy;
  489. }
  490. // static
  491. // Don't crash or llerrs here!  This function is used for debug strings.
  492. std::string LLPrimitive::pCodeToString(const LLPCode pcode)
  493. {
  494. std::string pcode_string;
  495. U8 base_code = pcode & LL_PCODE_BASE_MASK;
  496. if (!pcode)
  497. {
  498. pcode_string = "null";
  499. }
  500. else if ((base_code) == LL_PCODE_LEGACY)
  501. {
  502. // It's a legacy object
  503. switch (pcode)
  504. {
  505. case LL_PCODE_LEGACY_GRASS:
  506.   pcode_string = "grass";
  507. break;
  508. case LL_PCODE_LEGACY_PART_SYS:
  509.   pcode_string = "particle system";
  510. break;
  511. case LL_PCODE_LEGACY_AVATAR:
  512.   pcode_string = "avatar";
  513. break;
  514. case LL_PCODE_LEGACY_TEXT_BUBBLE:
  515.   pcode_string = "text bubble";
  516. break;
  517. case LL_PCODE_LEGACY_TREE:
  518.   pcode_string = "tree";
  519. break;
  520. case LL_PCODE_TREE_NEW:
  521.   pcode_string = "tree_new";
  522. break;
  523. default:
  524.   pcode_string = llformat( "unknown legacy pcode %i",(U32)pcode);
  525. }
  526. }
  527. else
  528. {
  529. std::string shape;
  530. std::string mask;
  531. if (base_code == LL_PCODE_CUBE)
  532. {
  533. shape = "cube";
  534. }
  535. else if (base_code == LL_PCODE_CYLINDER)
  536. {
  537. shape = "cylinder";
  538. }
  539. else if (base_code == LL_PCODE_CONE)
  540. {
  541. shape = "cone";
  542. }
  543. else if (base_code == LL_PCODE_PRISM)
  544. {
  545. shape = "prism";
  546. }
  547. else if (base_code == LL_PCODE_PYRAMID)
  548. {
  549. shape = "pyramid";
  550. }
  551. else if (base_code == LL_PCODE_SPHERE)
  552. {
  553. shape = "sphere";
  554. }
  555. else if (base_code == LL_PCODE_TETRAHEDRON)
  556. {
  557. shape = "tetrahedron";
  558. }
  559. else if (base_code == LL_PCODE_VOLUME)
  560. {
  561. shape = "volume";
  562. }
  563. else if (base_code == LL_PCODE_APP)
  564. {
  565. shape = "app";
  566. }
  567. else
  568. {
  569. llwarns << "Unknown base mask for pcode: " << base_code << llendl;
  570. }
  571. U8 mask_code = pcode & (~LL_PCODE_BASE_MASK);
  572. if (base_code == LL_PCODE_APP)
  573. {
  574. mask = llformat( "%x", mask_code);
  575. }
  576. else if (mask_code & LL_PCODE_HEMI_MASK)
  577. {
  578. mask = "hemi";
  579. }
  580. else 
  581. {
  582. mask = llformat( "%x", mask_code);
  583. }
  584. if (mask[0])
  585. {
  586. pcode_string = llformat( "%s-%s", shape.c_str(), mask.c_str());
  587. }
  588. else
  589. {
  590. pcode_string = llformat( "%s", shape.c_str());
  591. }
  592. }
  593. return pcode_string;
  594. }
  595. void LLPrimitive::copyTEs(const LLPrimitive *primitivep)
  596. {
  597. U32 i;
  598. if (primitivep->getExpectedNumTEs() != getExpectedNumTEs())
  599. {
  600. llwarns << "Primitives don't have same expected number of TE's" << llendl;
  601. }
  602. U32 num_tes = llmin(primitivep->getExpectedNumTEs(), getExpectedNumTEs());
  603. if (mTextureList.size() < getExpectedNumTEs())
  604. {
  605. mTextureList.setSize(getExpectedNumTEs());
  606. }
  607. for (i = 0; i < num_tes; i++)
  608. {
  609. mTextureList.copyTexture(i, *(primitivep->getTE(i)));
  610. }
  611. }
  612. S32 face_index_from_id(LLFaceID face_ID, const std::vector<LLProfile::Face>& faceArray)
  613. {
  614. S32 i;
  615. for (i = 0; i < (S32)faceArray.size(); i++)
  616. {
  617. if (faceArray[i].mFaceID == face_ID)
  618. {
  619. return i;
  620. }
  621. }
  622. return -1;
  623. }
  624. BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume)
  625. {
  626. LLMemType m1(LLMemType::MTYPE_VOLUME);
  627. LLVolume *volumep;
  628. if (unique_volume)
  629. {
  630. F32 volume_detail = LLVolumeLODGroup::getVolumeScaleFromDetail(detail);
  631. if (mVolumep.notNull() && volume_params == mVolumep->getParams() && (volume_detail == mVolumep->getDetail()))
  632. {
  633. return FALSE;
  634. }
  635. volumep = new LLVolume(volume_params, volume_detail, FALSE, TRUE);
  636. }
  637. else
  638. {
  639. if (mVolumep.notNull())
  640. {
  641. F32 volume_detail = LLVolumeLODGroup::getVolumeScaleFromDetail(detail);
  642. if (volume_params == mVolumep->getParams() && (volume_detail == mVolumep->getDetail()))
  643. {
  644. return FALSE;
  645. }
  646. }
  647. volumep = sVolumeManager->refVolume(volume_params, detail);
  648. if (volumep == mVolumep)
  649. {
  650. sVolumeManager->unrefVolume( volumep );  // LLVolumeMgr::refVolume() creates a reference, but we don't need a second one.
  651. return TRUE;
  652. }
  653. }
  654. setChanged(GEOMETRY);
  655. if (!mVolumep)
  656. {
  657. mVolumep = volumep;
  658. //mFaceMask = mVolumep->generateFaceMask();
  659. setNumTEs(mVolumep->getNumFaces());
  660. return TRUE;
  661. }
  662. U32 old_face_mask = mVolumep->mFaceMask;
  663. S32 face_bit = 0;
  664. S32 cur_mask = 0;
  665. // Grab copies of the old faces from the original shape, ordered by type.
  666. // We will use these to figure out what old texture info gets mapped to new
  667. // faces in the new shape.
  668. std::vector<LLProfile::Face> old_faces; 
  669. for (S32 face = 0; face < mVolumep->getNumFaces(); face++)
  670. {
  671. old_faces.push_back(mVolumep->getProfile().mFaces[face]);
  672. }
  673. // Copy the old texture info off to the side, but not in the order in which
  674. // they live in the mTextureList, rather in order of ther "face id" which
  675. // is the corresponding value of LLVolueParams::LLProfile::mFaces::mIndex.
  676. //
  677. // Hence, some elements of old_tes::mEntryList will be invalid.  It is
  678. // initialized to a size of 9 (max number of possible faces on a volume?)
  679. // and only the ones with valid types are filled in.
  680. LLPrimTextureList old_tes;
  681. old_tes.setSize(9);
  682. for (face_bit = 0; face_bit < 9; face_bit++)
  683. {
  684. cur_mask = 0x1 << face_bit;
  685. if (old_face_mask & cur_mask)
  686. {
  687. S32 te_index = face_index_from_id(cur_mask, old_faces);
  688. old_tes.copyTexture(face_bit, *(getTE(te_index)));
  689. //llinfos << face_bit << ":" << te_index << ":" << old_tes[face_bit].getID() << llendl;
  690. }
  691. }
  692. // build the new object
  693. sVolumeManager->unrefVolume(mVolumep);
  694. mVolumep = volumep;
  695. U32 new_face_mask = mVolumep->mFaceMask;
  696. S32 i;
  697. if (old_face_mask == new_face_mask) 
  698. {
  699. // nothing to do
  700. return TRUE;
  701. }
  702. if (mVolumep->getNumFaces() == 0 && new_face_mask != 0)
  703. {
  704. llwarns << "Object with 0 faces found...INCORRECT!" << llendl;
  705. setNumTEs(mVolumep->getNumFaces());
  706. return TRUE;
  707. }
  708. // initialize face_mapping
  709. S32 face_mapping[9];
  710. for (face_bit = 0; face_bit < 9; face_bit++)
  711. {
  712. face_mapping[face_bit] = face_bit;
  713. }
  714. // The new shape may have more faces than the original, but we can't just
  715. // add them to the end -- the ordering matters and it may be that we must
  716. // insert the new faces in the middle of the list.  When we add a face it
  717. // will pick up the texture/color info of one of the old faces an so we
  718. // now figure out which old face info gets mapped to each new face, and 
  719. // store in the face_mapping lookup table.
  720. for (face_bit = 0; face_bit < 9; face_bit++)
  721. {
  722. cur_mask = 0x1 << face_bit;
  723. if (!(new_face_mask & cur_mask))
  724. {
  725. // Face doesn't exist in new map.
  726. face_mapping[face_bit] = -1;
  727. continue;
  728. }
  729. else if (old_face_mask & cur_mask)
  730. {
  731. // Face exists in new and old map.
  732. face_mapping[face_bit] = face_bit;
  733. continue;
  734. }
  735. // OK, how we've got a mismatch, where we have to fill a new face with one from
  736. // the old face.
  737. if (cur_mask & (LL_FACE_PATH_BEGIN | LL_FACE_PATH_END | LL_FACE_INNER_SIDE))
  738. {
  739. // It's a top/bottom/hollow interior face.
  740. if (old_face_mask & LL_FACE_PATH_END)
  741. {
  742. face_mapping[face_bit] = 1;
  743. continue;
  744. }
  745. else
  746. {
  747. S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0;
  748. for (i = 0; i < 4; i++)
  749. {
  750. if (old_face_mask & cur_outer_mask)
  751. {
  752. face_mapping[face_bit] = 5 + i;
  753. break;
  754. }
  755. cur_outer_mask <<= 1;
  756. }
  757. if (i == 4)
  758. {
  759. llwarns << "No path end or outer face in volume!" << llendl;
  760. }
  761. continue;
  762. }
  763. }
  764. if (cur_mask & (LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END))
  765. {
  766. // A cut slice.  Use the hollow interior if we have it.
  767. if (old_face_mask & LL_FACE_INNER_SIDE)
  768. {
  769. face_mapping[face_bit] = 2;
  770. continue;
  771. }
  772. // No interior, use the bottom face.
  773. // Could figure out which of the outer faces was nearest, but that would be harder.
  774. if (old_face_mask & LL_FACE_PATH_END)
  775. {
  776. face_mapping[face_bit] = 1;
  777. continue;
  778. }
  779. else
  780. {
  781. S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0;
  782. for (i = 0; i < 4; i++)
  783. {
  784. if (old_face_mask & cur_outer_mask)
  785. {
  786. face_mapping[face_bit] = 5 + i;
  787. break;
  788. }
  789. cur_outer_mask <<= 1;
  790. }
  791. if (i == 4)
  792. {
  793. llwarns << "No path end or outer face in volume!" << llendl;
  794. }
  795. continue;
  796. }
  797. }
  798. // OK, the face that's missing is an outer face...
  799. // Pull from the nearest adjacent outer face (there's always guaranteed to be one...
  800. S32 cur_outer = face_bit - 5;
  801. S32 min_dist = 5;
  802. S32 min_outer_bit = -1;
  803. S32 i;
  804. for (i = 0; i < 4; i++)
  805. {
  806. if (old_face_mask & (LL_FACE_OUTER_SIDE_0 << i))
  807. {
  808. S32 dist = abs(i - cur_outer);
  809. if (dist < min_dist)
  810. {
  811. min_dist = dist;
  812. min_outer_bit = i + 5;
  813. }
  814. }
  815. }
  816. if (-1 == min_outer_bit)
  817. {
  818. llinfos << (LLVolume *)mVolumep << llendl;
  819. llwarns << "Bad!  No outer faces, impossible!" << llendl;
  820. }
  821. face_mapping[face_bit] = min_outer_bit;
  822. }
  823. setNumTEs(mVolumep->getNumFaces());
  824. for (face_bit = 0; face_bit < 9; face_bit++)
  825. {
  826. // For each possible face type on the new shape we check to see if that
  827. // face exists and if it does we create a texture entry that is a copy
  828. // of one of the originals.  Since the originals might not have a
  829. // matching face, we use the face_mapping lookup table to figure out
  830. // which face information to copy.
  831. cur_mask = 0x1 << face_bit;
  832. if (new_face_mask & cur_mask)
  833. {
  834. if (-1 == face_mapping[face_bit])
  835. {
  836. llwarns << "No mapping from old face to new face!" << llendl;
  837. }
  838. S32 te_num = face_index_from_id(cur_mask, mVolumep->getProfile().mFaces);
  839. setTE(te_num, *(old_tes.getTexture(face_mapping[face_bit])));
  840. }
  841. }
  842. return TRUE;
  843. }
  844. BOOL LLPrimitive::setMaterial(U8 material)
  845. {
  846. if (material != mMaterial)
  847. {
  848. mMaterial = material;
  849. return TRUE;
  850. }
  851. else
  852. {
  853. return FALSE;
  854. }
  855. }
  856. const F32 LL_MAX_SCALE_S = 100.0f;
  857. const F32 LL_MAX_SCALE_T = 100.0f;
  858. S32 LLPrimitive::packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const
  859. {
  860. S32 face_index;
  861. S32 i;
  862. U64 exception_faces;
  863. U8 *start_loc = cur_ptr;
  864. htonmemcpy(cur_ptr,data_ptr + (last_face_index * data_size), type, data_size);
  865. cur_ptr += data_size;
  866. for (face_index = last_face_index-1; face_index >= 0; face_index--)
  867. {
  868. BOOL already_sent = FALSE;
  869. for (i = face_index+1; i <= last_face_index; i++)
  870. if (!memcmp(data_ptr+(data_size *face_index), data_ptr+(data_size *i), data_size))
  871. {
  872. already_sent = TRUE;
  873. break;
  874. }
  875. }
  876. if (!already_sent)
  877. {
  878. exception_faces = 0;
  879. for (i = face_index; i >= 0; i--)
  880. if (!memcmp(data_ptr+(data_size *face_index), data_ptr+(data_size *i), data_size))
  881. {
  882. exception_faces |= ((U64)1 << i); 
  883. }
  884. }
  885. //assign exception faces to cur_ptr
  886. if (exception_faces >= (0x1 << 7))
  887. {
  888. if (exception_faces >= (0x1 << 14))
  889. {
  890. if (exception_faces >= (0x1 << 21))
  891. {
  892. if (exception_faces >= (0x1 << 28))
  893. {
  894. *cur_ptr++ = (U8)(((exception_faces >> 28) & 0x7F) | 0x80);
  895. }
  896. *cur_ptr++ = (U8)(((exception_faces >> 21) & 0x7F) | 0x80);
  897. }
  898. *cur_ptr++ = (U8)(((exception_faces >> 14) & 0x7F) | 0x80);
  899. }
  900. *cur_ptr++ = (U8)(((exception_faces >> 7) & 0x7F) | 0x80);
  901. }
  902. *cur_ptr++ = (U8)(exception_faces & 0x7F);
  903. htonmemcpy(cur_ptr,data_ptr + (face_index * data_size), type, data_size);
  904. cur_ptr += data_size;
  905.     }
  906. }
  907. return (S32)(cur_ptr - start_loc);
  908. }
  909. S32 LLPrimitive::unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 data_size, U8 face_count, EMsgVariableType type)
  910. {
  911. U8 *start_loc = cur_ptr;
  912. U64 i;
  913. htonmemcpy(data_ptr,cur_ptr, type,data_size);
  914. cur_ptr += data_size;
  915. for (i = 1; i < face_count; i++)
  916. {
  917. // Already unswizzled, don't need to unswizzle it again!
  918. memcpy(data_ptr+(i*data_size),data_ptr,data_size); /* Flawfinder: ignore */ 
  919. }
  920. while ((cur_ptr < buffer_end) && (*cur_ptr != 0))
  921. {
  922. // llinfos << "TE exception" << llendl;
  923. i = 0;
  924. while (*cur_ptr & 0x80)
  925. {
  926. i |= ((*cur_ptr++) & 0x7F);
  927. i = i << 7;
  928. }
  929. i |= *cur_ptr++;
  930. for (S32 j = 0; j < face_count; j++)
  931. {
  932. if (i & 0x01)
  933. {
  934. htonmemcpy(data_ptr+(j*data_size),cur_ptr,type,data_size);
  935. // char foo[64];
  936. // sprintf(foo,"%x %x",*(data_ptr+(j*data_size)), *(data_ptr+(j*data_size)+1));
  937. // llinfos << "Assigning " << foo << " to face " << j << llendl;
  938. }
  939. i = i >> 1;
  940. }
  941. cur_ptr += data_size;
  942. }
  943. return (S32)(cur_ptr - start_loc);
  944. }
  945. // Pack information about all texture entries into container:
  946. // { TextureEntry Variable 2 }
  947. // Includes information about image ID, color, scale S,T, offset S,T and rotation
  948. BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
  949. {
  950. const U32 MAX_TES = 32;
  951. U8     image_ids[MAX_TES*16];
  952. U8     colors[MAX_TES*4];
  953. F32    scale_s[MAX_TES];
  954. F32    scale_t[MAX_TES];
  955. S16    offset_s[MAX_TES];
  956. S16    offset_t[MAX_TES];
  957. S16    image_rot[MAX_TES];
  958. U8    bump[MAX_TES];
  959. U8    media_flags[MAX_TES];
  960.     U8     glow[MAX_TES];
  961. const U32 MAX_TE_BUFFER = 4096;
  962. U8 packed_buffer[MAX_TE_BUFFER];
  963. U8 *cur_ptr = packed_buffer;
  964. S32 last_face_index = getNumTEs() - 1;
  965. if (last_face_index > -1)
  966. {
  967. // ...if we hit the front, send one image id
  968. S8 face_index;
  969. LLColor4U coloru;
  970. for (face_index = 0; face_index <= last_face_index; face_index++)
  971. {
  972. // Directly sending image_ids is not safe!
  973. memcpy(&image_ids[face_index*16],getTE(face_index)->getID().mData,16); /* Flawfinder: ignore */ 
  974. // Cast LLColor4 to LLColor4U
  975. coloru.setVec( getTE(face_index)->getColor() );
  976. // Note:  This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
  977. // as all zeros.  However, the subtraction and addition must be done in unsigned
  978. // byte space, not in float space, otherwise off-by-one errors occur. JC
  979. colors[4*face_index]     = 255 - coloru.mV[0];
  980. colors[4*face_index + 1] = 255 - coloru.mV[1];
  981. colors[4*face_index + 2] = 255 - coloru.mV[2];
  982. colors[4*face_index + 3] = 255 - coloru.mV[3];
  983. const LLTextureEntry* te = getTE(face_index);
  984. scale_s[face_index] = (F32) te->mScaleS;
  985. scale_t[face_index] = (F32) te->mScaleT;
  986. offset_s[face_index] = (S16) llround((llclamp(te->mOffsetS,-1.0f,1.0f) * (F32)0x7FFF)) ;
  987. offset_t[face_index] = (S16) llround((llclamp(te->mOffsetT,-1.0f,1.0f) * (F32)0x7FFF)) ;
  988. image_rot[face_index] = (S16) llround(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * TEXTURE_ROTATION_PACK_FACTOR));
  989. bump[face_index] = te->getBumpShinyFullbright();
  990. media_flags[face_index] = te->getMediaTexGen();
  991. glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF));
  992. }
  993. cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID);
  994. *cur_ptr++ = 0;
  995. cur_ptr += packTEField(cur_ptr, (U8 *)colors, 4 ,last_face_index, MVT_U8);
  996. *cur_ptr++ = 0;
  997. cur_ptr += packTEField(cur_ptr, (U8 *)scale_s, 4 ,last_face_index, MVT_F32);
  998. *cur_ptr++ = 0;
  999. cur_ptr += packTEField(cur_ptr, (U8 *)scale_t, 4 ,last_face_index, MVT_F32);
  1000. *cur_ptr++ = 0;
  1001. cur_ptr += packTEField(cur_ptr, (U8 *)offset_s, 2 ,last_face_index, MVT_S16Array);
  1002. *cur_ptr++ = 0;
  1003. cur_ptr += packTEField(cur_ptr, (U8 *)offset_t, 2 ,last_face_index, MVT_S16Array);
  1004. *cur_ptr++ = 0;
  1005. cur_ptr += packTEField(cur_ptr, (U8 *)image_rot, 2 ,last_face_index, MVT_S16Array);
  1006. *cur_ptr++ = 0;
  1007. cur_ptr += packTEField(cur_ptr, (U8 *)bump, 1 ,last_face_index, MVT_U8);
  1008. *cur_ptr++ = 0;
  1009. cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);
  1010. *cur_ptr++ = 0;
  1011. cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8);
  1012. }
  1013.     mesgsys->addBinaryDataFast(_PREHASH_TextureEntry, packed_buffer, (S32)(cur_ptr - packed_buffer));
  1014. return FALSE;
  1015. }
  1016. BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
  1017. {
  1018. const U32 MAX_TES = 32;
  1019. U8     image_ids[MAX_TES*16];
  1020. U8     colors[MAX_TES*4];
  1021. F32    scale_s[MAX_TES];
  1022. F32    scale_t[MAX_TES];
  1023. S16    offset_s[MAX_TES];
  1024. S16    offset_t[MAX_TES];
  1025. S16    image_rot[MAX_TES];
  1026. U8    bump[MAX_TES];
  1027. U8    media_flags[MAX_TES];
  1028.     U8     glow[MAX_TES];
  1029. const U32 MAX_TE_BUFFER = 4096;
  1030. U8 packed_buffer[MAX_TE_BUFFER];
  1031. U8 *cur_ptr = packed_buffer;
  1032. S32 last_face_index = getNumTEs() - 1;
  1033. if (last_face_index > -1)
  1034. {
  1035. // ...if we hit the front, send one image id
  1036. S8 face_index;
  1037. LLColor4U coloru;
  1038. for (face_index = 0; face_index <= last_face_index; face_index++)
  1039. {
  1040. // Directly sending image_ids is not safe!
  1041. memcpy(&image_ids[face_index*16],getTE(face_index)->getID().mData,16); /* Flawfinder: ignore */ 
  1042. // Cast LLColor4 to LLColor4U
  1043. coloru.setVec( getTE(face_index)->getColor() );
  1044. // Note:  This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
  1045. // as all zeros.  However, the subtraction and addition must be done in unsigned
  1046. // byte space, not in float space, otherwise off-by-one errors occur. JC
  1047. colors[4*face_index]     = 255 - coloru.mV[0];
  1048. colors[4*face_index + 1] = 255 - coloru.mV[1];
  1049. colors[4*face_index + 2] = 255 - coloru.mV[2];
  1050. colors[4*face_index + 3] = 255 - coloru.mV[3];
  1051. const LLTextureEntry* te = getTE(face_index);
  1052. scale_s[face_index] = (F32) te->mScaleS;
  1053. scale_t[face_index] = (F32) te->mScaleT;
  1054. offset_s[face_index] = (S16) llround((llclamp(te->mOffsetS,-1.0f,1.0f) * (F32)0x7FFF)) ;
  1055. offset_t[face_index] = (S16) llround((llclamp(te->mOffsetT,-1.0f,1.0f) * (F32)0x7FFF)) ;
  1056. image_rot[face_index] = (S16) llround(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * TEXTURE_ROTATION_PACK_FACTOR));
  1057. bump[face_index] = te->getBumpShinyFullbright();
  1058. media_flags[face_index] = te->getMediaTexGen();
  1059.             glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF));
  1060. }
  1061. cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID);
  1062. *cur_ptr++ = 0;
  1063. cur_ptr += packTEField(cur_ptr, (U8 *)colors, 4 ,last_face_index, MVT_U8);
  1064. *cur_ptr++ = 0;
  1065. cur_ptr += packTEField(cur_ptr, (U8 *)scale_s, 4 ,last_face_index, MVT_F32);
  1066. *cur_ptr++ = 0;
  1067. cur_ptr += packTEField(cur_ptr, (U8 *)scale_t, 4 ,last_face_index, MVT_F32);
  1068. *cur_ptr++ = 0;
  1069. cur_ptr += packTEField(cur_ptr, (U8 *)offset_s, 2 ,last_face_index, MVT_S16Array);
  1070. *cur_ptr++ = 0;
  1071. cur_ptr += packTEField(cur_ptr, (U8 *)offset_t, 2 ,last_face_index, MVT_S16Array);
  1072. *cur_ptr++ = 0;
  1073. cur_ptr += packTEField(cur_ptr, (U8 *)image_rot, 2 ,last_face_index, MVT_S16Array);
  1074. *cur_ptr++ = 0;
  1075. cur_ptr += packTEField(cur_ptr, (U8 *)bump, 1 ,last_face_index, MVT_U8);
  1076. *cur_ptr++ = 0;
  1077. cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);
  1078. *cur_ptr++ = 0;
  1079. cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8);
  1080. }
  1081. dp.packBinaryData(packed_buffer, (S32)(cur_ptr - packed_buffer), "TextureEntry");
  1082. return FALSE;
  1083. }
  1084. S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name)
  1085. {
  1086. return(unpackTEMessage(mesgsys,block_name,-1));
  1087. }
  1088. S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, const S32 block_num)
  1089. {
  1090. // use a negative block_num to indicate a single-block read (a non-variable block)
  1091. S32 retval = 0;
  1092. const U32 MAX_TES = 32;
  1093. // Avoid construction of 32 UUIDs per call. JC
  1094. U8     image_data[MAX_TES*16];
  1095. U8   colors[MAX_TES*4];
  1096. F32    scale_s[MAX_TES];
  1097. F32    scale_t[MAX_TES];
  1098. S16    offset_s[MAX_TES];
  1099. S16    offset_t[MAX_TES];
  1100. S16    image_rot[MAX_TES];
  1101. U8    bump[MAX_TES];
  1102. U8    media_flags[MAX_TES];
  1103.     U8     glow[MAX_TES];
  1104. const U32 MAX_TE_BUFFER = 4096;
  1105. U8 packed_buffer[MAX_TE_BUFFER];
  1106. U8 *cur_ptr = packed_buffer;
  1107. U32 size;
  1108. U32 face_count = 0;
  1109. if (block_num < 0)
  1110. {
  1111. size = mesgsys->getSizeFast(block_name, _PREHASH_TextureEntry);
  1112. }
  1113. else
  1114. {
  1115. size = mesgsys->getSizeFast(block_name, block_num, _PREHASH_TextureEntry);
  1116. }
  1117. if (size == 0)
  1118. {
  1119. return retval;
  1120. }
  1121. if (block_num < 0)
  1122. {
  1123. mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, packed_buffer, 0, 0, MAX_TE_BUFFER);
  1124. }
  1125. else
  1126. {
  1127. mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, packed_buffer, 0, block_num, MAX_TE_BUFFER);
  1128. }
  1129. face_count = getNumTEs();
  1130. cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_data, 16, face_count, MVT_LLUUID);
  1131. cur_ptr++;
  1132. cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)colors, 4, face_count, MVT_U8);
  1133. cur_ptr++;
  1134. cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_s, 4, face_count, MVT_F32);
  1135. cur_ptr++;
  1136. cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_t, 4, face_count, MVT_F32);
  1137. cur_ptr++;
  1138. cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_s, 2, face_count, MVT_S16Array);
  1139. cur_ptr++;
  1140. cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_t, 2, face_count, MVT_S16Array);
  1141. cur_ptr++;
  1142. cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_rot, 2, face_count, MVT_S16Array);
  1143. cur_ptr++;
  1144. cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)bump, 1, face_count, MVT_U8);
  1145. cur_ptr++;
  1146. cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8);
  1147. cur_ptr++;
  1148. cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8);
  1149. LLColor4 color;
  1150. LLColor4U coloru;
  1151. for (U32 i = 0; i < face_count; i++)
  1152. {
  1153. retval |= setTETexture(i, ((LLUUID*)image_data)[i]);
  1154. retval |= setTEScale(i, scale_s[i], scale_t[i]);
  1155. retval |= setTEOffset(i, (F32)offset_s[i] / (F32)0x7FFF, (F32) offset_t[i] / (F32) 0x7FFF);
  1156. retval |= setTERotation(i, ((F32)image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI);
  1157. retval |= setTEBumpShinyFullbright(i, bump[i]);
  1158. retval |= setTEMediaTexGen(i, media_flags[i]);
  1159. retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF);
  1160. coloru = LLColor4U(colors + 4*i);
  1161. // Note:  This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
  1162. // as all zeros.  However, the subtraction and addition must be done in unsigned
  1163. // byte space, not in float space, otherwise off-by-one errors occur. JC
  1164. color.mV[VRED] = F32(255 - coloru.mV[VRED])   / 255.f;
  1165. color.mV[VGREEN] = F32(255 - coloru.mV[VGREEN]) / 255.f;
  1166. color.mV[VBLUE] = F32(255 - coloru.mV[VBLUE])  / 255.f;
  1167. color.mV[VALPHA] = F32(255 - coloru.mV[VALPHA]) / 255.f;
  1168. retval |= setTEColor(i, color);
  1169. }
  1170. return retval;
  1171. }
  1172. S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
  1173. {
  1174. // use a negative block_num to indicate a single-block read (a non-variable block)
  1175. S32 retval = 0;
  1176. const U32 MAX_TES = 32;
  1177. // Avoid construction of 32 UUIDs per call
  1178. static LLUUID image_ids[MAX_TES];
  1179. U8     image_data[MAX_TES*16];
  1180. U8    colors[MAX_TES*4];
  1181. F32    scale_s[MAX_TES];
  1182. F32    scale_t[MAX_TES];
  1183. S16    offset_s[MAX_TES];
  1184. S16    offset_t[MAX_TES];
  1185. S16    image_rot[MAX_TES];
  1186. U8    bump[MAX_TES];
  1187. U8    media_flags[MAX_TES];
  1188.     U8     glow[MAX_TES];
  1189. const U32 MAX_TE_BUFFER = 4096;
  1190. U8 packed_buffer[MAX_TE_BUFFER];
  1191. U8 *cur_ptr = packed_buffer;
  1192. S32 size;
  1193. U32 face_count = 0;
  1194. if (!dp.unpackBinaryData(packed_buffer, size, "TextureEntry"))
  1195. {
  1196. retval = TEM_INVALID;
  1197. llwarns << "Bad texture entry block!  Abort!" << llendl;
  1198. return retval;
  1199. }
  1200. if (size == 0)
  1201. {
  1202. return retval;
  1203. }
  1204. face_count = getNumTEs();
  1205. U32 i;
  1206. cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_data, 16, face_count, MVT_LLUUID);
  1207. cur_ptr++;
  1208. cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)colors, 4, face_count, MVT_U8);
  1209. cur_ptr++;
  1210. cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_s, 4, face_count, MVT_F32);
  1211. cur_ptr++;
  1212. cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_t, 4, face_count, MVT_F32);
  1213. cur_ptr++;
  1214. cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_s, 2, face_count, MVT_S16Array);
  1215. cur_ptr++;
  1216. cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_t, 2, face_count, MVT_S16Array);
  1217. cur_ptr++;
  1218. cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_rot, 2, face_count, MVT_S16Array);
  1219. cur_ptr++;
  1220. cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)bump, 1, face_count, MVT_U8);
  1221. cur_ptr++;
  1222. cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8);
  1223. cur_ptr++;
  1224. cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8);
  1225. for (i = 0; i < face_count; i++)
  1226. {
  1227. memcpy(image_ids[i].mData,&image_data[i*16],16); /* Flawfinder: ignore */ 
  1228. }
  1229. LLColor4 color;
  1230. LLColor4U coloru;
  1231. for (i = 0; i < face_count; i++)
  1232. {
  1233. retval |= setTETexture(i, image_ids[i]);
  1234. retval |= setTEScale(i, scale_s[i], scale_t[i]);
  1235. retval |= setTEOffset(i, (F32)offset_s[i] / (F32)0x7FFF, (F32) offset_t[i] / (F32) 0x7FFF);
  1236. retval |= setTERotation(i, ((F32)image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI);
  1237. retval |= setTEBumpShinyFullbright(i, bump[i]);
  1238. retval |= setTEMediaTexGen(i, media_flags[i]);
  1239. retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF);
  1240. coloru = LLColor4U(colors + 4*i);
  1241. // Note:  This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
  1242. // as all zeros.  However, the subtraction and addition must be done in unsigned
  1243. // byte space, not in float space, otherwise off-by-one errors occur. JC
  1244. color.mV[VRED] = F32(255 - coloru.mV[VRED])   / 255.f;
  1245. color.mV[VGREEN] = F32(255 - coloru.mV[VGREEN]) / 255.f;
  1246. color.mV[VBLUE] = F32(255 - coloru.mV[VBLUE])  / 255.f;
  1247. color.mV[VALPHA] = F32(255 - coloru.mV[VALPHA]) / 255.f;
  1248. retval |= setTEColor(i, color);
  1249. }
  1250. return retval;
  1251. }
  1252. U8 LLPrimitive::getExpectedNumTEs() const
  1253. {
  1254. U8 expected_face_count = 0;
  1255. if (mVolumep)
  1256. {
  1257. expected_face_count = mVolumep->getNumFaces();
  1258. }
  1259. return expected_face_count;
  1260. }
  1261. void LLPrimitive::copyTextureList(const LLPrimTextureList& other_list)
  1262. {
  1263. mTextureList.copy(other_list);
  1264. }
  1265. void LLPrimitive::takeTextureList(LLPrimTextureList& other_list)
  1266. {
  1267. mTextureList.take(other_list);
  1268. }
  1269. //============================================================================
  1270. // Moved from llselectmgr.cpp
  1271. // BUG: Only works for boxes.
  1272. // Face numbering for flex boxes as of 1.14.2
  1273. // static
  1274. bool LLPrimitive::getTESTAxes(const U8 face, U32* s_axis, U32* t_axis)
  1275. {
  1276. if (face == 0)
  1277. {
  1278. *s_axis = VX; *t_axis = VY;
  1279. return true;
  1280. }
  1281. else if (face == 1)
  1282. {
  1283. *s_axis = VX; *t_axis = VZ;
  1284. return true;
  1285. }
  1286. else if (face == 2)
  1287. {
  1288. *s_axis = VY; *t_axis = VZ;
  1289. return true;
  1290. }
  1291. else if (face == 3)
  1292. {
  1293. *s_axis = VX; *t_axis = VZ;
  1294. return true;
  1295. }
  1296. else if (face == 4)
  1297. {
  1298. *s_axis = VY; *t_axis = VZ;
  1299. return true;
  1300. }
  1301. else if (face == 5)
  1302. {
  1303. *s_axis = VX; *t_axis = VY;
  1304. return true;
  1305. }
  1306. else
  1307. {
  1308. // unknown face
  1309. return false;
  1310. }
  1311. }
  1312. //============================================================================
  1313. //static 
  1314. BOOL LLNetworkData::isValid(U16 param_type, U32 size)
  1315. {
  1316. // ew - better mechanism needed
  1317. switch(param_type)
  1318. {
  1319. case PARAMS_FLEXIBLE:
  1320. return (size == 16);
  1321. case PARAMS_LIGHT:
  1322. return (size == 16);
  1323. case PARAMS_SCULPT:
  1324. return (size == 17);
  1325. case PARAMS_LIGHT_IMAGE:
  1326. return (size == 28);
  1327. }
  1328. return FALSE;
  1329. }
  1330. //============================================================================
  1331. LLLightParams::LLLightParams()
  1332. {
  1333. mColor.setToWhite();
  1334. mRadius = 10.f;
  1335. mCutoff = 0.0f;
  1336. mFalloff = 0.75f;
  1337. mType = PARAMS_LIGHT;
  1338. }
  1339. BOOL LLLightParams::pack(LLDataPacker &dp) const
  1340. {
  1341. LLColor4U color4u(mColor);
  1342. dp.packColor4U(color4u, "color");
  1343. dp.packF32(mRadius, "radius");
  1344. dp.packF32(mCutoff, "cutoff");
  1345. dp.packF32(mFalloff, "falloff");
  1346. return TRUE;
  1347. }
  1348. BOOL LLLightParams::unpack(LLDataPacker &dp)
  1349. {
  1350. LLColor4U color;
  1351. dp.unpackColor4U(color, "color");
  1352. setColor(LLColor4(color));
  1353. F32 radius;
  1354. dp.unpackF32(radius, "radius");
  1355. setRadius(radius);
  1356. F32 cutoff;
  1357. dp.unpackF32(cutoff, "cutoff");
  1358. setCutoff(cutoff);
  1359. F32 falloff;
  1360. dp.unpackF32(falloff, "falloff");
  1361. setFalloff(falloff);
  1362. return TRUE;
  1363. }
  1364. bool LLLightParams::operator==(const LLNetworkData& data) const
  1365. {
  1366. if (data.mType != PARAMS_LIGHT)
  1367. {
  1368. return false;
  1369. }
  1370. const LLLightParams *param = (const LLLightParams*)&data;
  1371. if (param->mColor != mColor ||
  1372. param->mRadius != mRadius ||
  1373. param->mCutoff != mCutoff ||
  1374. param->mFalloff != mFalloff)
  1375. {
  1376. return false;
  1377. }
  1378. return true;
  1379. }
  1380. void LLLightParams::copy(const LLNetworkData& data)
  1381. {
  1382. const LLLightParams *param = (LLLightParams*)&data;
  1383. mType = param->mType;
  1384. mColor = param->mColor;
  1385. mRadius = param->mRadius;
  1386. mCutoff = param->mCutoff;
  1387. mFalloff = param->mFalloff;
  1388. }
  1389. LLSD LLLightParams::asLLSD() const
  1390. {
  1391. LLSD sd;
  1392. sd["color"] = ll_sd_from_color4(getColor());
  1393. sd["radius"] = getRadius();
  1394. sd["falloff"] = getFalloff();
  1395. sd["cutoff"] = getCutoff();
  1396. return sd;
  1397. }
  1398. bool LLLightParams::fromLLSD(LLSD& sd)
  1399. {
  1400. const char *w;
  1401. w = "color";
  1402. if (sd.has(w))
  1403. {
  1404. setColor( ll_color4_from_sd(sd["color"]) );
  1405. } else goto fail;
  1406. w = "radius";
  1407. if (sd.has(w))
  1408. {
  1409. setRadius( (F32)sd[w].asReal() );
  1410. } else goto fail;
  1411. w = "falloff";
  1412. if (sd.has(w))
  1413. {
  1414. setFalloff( (F32)sd[w].asReal() );
  1415. } else goto fail;
  1416. w = "cutoff";
  1417. if (sd.has(w))
  1418. {
  1419. setCutoff( (F32)sd[w].asReal() );
  1420. } else goto fail;
  1421. return true;
  1422.  fail:
  1423. return false;
  1424. }
  1425. //============================================================================
  1426. LLFlexibleObjectData::LLFlexibleObjectData()
  1427. {
  1428. mSimulateLOD = FLEXIBLE_OBJECT_DEFAULT_NUM_SECTIONS;
  1429. mGravity = FLEXIBLE_OBJECT_DEFAULT_GRAVITY;
  1430. mAirFriction = FLEXIBLE_OBJECT_DEFAULT_AIR_FRICTION;
  1431. mWindSensitivity = FLEXIBLE_OBJECT_DEFAULT_WIND_SENSITIVITY;
  1432. mTension = FLEXIBLE_OBJECT_DEFAULT_TENSION;
  1433. //mUsingCollisionSphere = FLEXIBLE_OBJECT_DEFAULT_USING_COLLISION_SPHERE;
  1434. //mRenderingCollisionSphere = FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE;
  1435. mUserForce = LLVector3(0.f, 0.f, 0.f);
  1436. mType = PARAMS_FLEXIBLE;
  1437. }
  1438. BOOL LLFlexibleObjectData::pack(LLDataPacker &dp) const
  1439. {
  1440. // Custom, uber-svelte pack "softness" in upper bits of tension & drag
  1441. U8 bit1 = (mSimulateLOD & 2) << 6;
  1442. U8 bit2 = (mSimulateLOD & 1) << 7;
  1443. dp.packU8((U8)(mTension*10.01f) + bit1, "tension");
  1444. dp.packU8((U8)(mAirFriction*10.01f) + bit2, "drag");
  1445. dp.packU8((U8)((mGravity+10.f)*10.01f), "gravity");
  1446. dp.packU8((U8)(mWindSensitivity*10.01f), "wind");
  1447. dp.packVector3(mUserForce, "userforce");
  1448. return TRUE;
  1449. }
  1450. BOOL LLFlexibleObjectData::unpack(LLDataPacker &dp)
  1451. {
  1452. U8 tension, friction, gravity, wind;
  1453. U8 bit1, bit2;
  1454. dp.unpackU8(tension, "tension"); bit1 = (tension >> 6) & 2;
  1455. mTension = ((F32)(tension&0x7f))/10.f;
  1456. dp.unpackU8(friction, "drag"); bit2 = (friction >> 7) & 1;
  1457. mAirFriction = ((F32)(friction&0x7f))/10.f;
  1458. mSimulateLOD = bit1 | bit2;
  1459. dp.unpackU8(gravity, "gravity"); mGravity = ((F32)gravity)/10.f - 10.f;
  1460. dp.unpackU8(wind, "wind"); mWindSensitivity = ((F32)wind)/10.f;
  1461. if (dp.hasNext())
  1462. {
  1463. dp.unpackVector3(mUserForce, "userforce");
  1464. }
  1465. else
  1466. {
  1467. mUserForce.setVec(0.f, 0.f, 0.f);
  1468. }
  1469. return TRUE;
  1470. }
  1471. bool LLFlexibleObjectData::operator==(const LLNetworkData& data) const
  1472. {
  1473. if (data.mType != PARAMS_FLEXIBLE)
  1474. {
  1475. return false;
  1476. }
  1477. LLFlexibleObjectData *flex_data = (LLFlexibleObjectData*)&data;
  1478. return (mSimulateLOD == flex_data->mSimulateLOD &&
  1479. mGravity == flex_data->mGravity &&
  1480. mAirFriction == flex_data->mAirFriction &&
  1481. mWindSensitivity == flex_data->mWindSensitivity &&
  1482. mTension == flex_data->mTension &&
  1483. mUserForce == flex_data->mUserForce);
  1484. //mUsingCollisionSphere == flex_data->mUsingCollisionSphere &&
  1485. //mRenderingCollisionSphere == flex_data->mRenderingCollisionSphere
  1486. }
  1487. void LLFlexibleObjectData::copy(const LLNetworkData& data)
  1488. {
  1489. const LLFlexibleObjectData *flex_data = (LLFlexibleObjectData*)&data;
  1490. mSimulateLOD = flex_data->mSimulateLOD;
  1491. mGravity = flex_data->mGravity;
  1492. mAirFriction = flex_data->mAirFriction;
  1493. mWindSensitivity = flex_data->mWindSensitivity;
  1494. mTension = flex_data->mTension;
  1495. mUserForce = flex_data->mUserForce;
  1496. //mUsingCollisionSphere = flex_data->mUsingCollisionSphere;
  1497. //mRenderingCollisionSphere = flex_data->mRenderingCollisionSphere;
  1498. }
  1499. LLSD LLFlexibleObjectData::asLLSD() const
  1500. {
  1501. LLSD sd;
  1502. sd["air_friction"] = getAirFriction();
  1503. sd["gravity"] = getGravity();
  1504. sd["simulate_lod"] = getSimulateLOD();
  1505. sd["tension"] = getTension();
  1506. sd["user_force"] = getUserForce().getValue();
  1507. sd["wind_sensitivity"] = getWindSensitivity();
  1508. return sd;
  1509. }
  1510. bool LLFlexibleObjectData::fromLLSD(LLSD& sd)
  1511. {
  1512. const char *w;
  1513. w = "air_friction";
  1514. if (sd.has(w))
  1515. {
  1516. setAirFriction( (F32)sd[w].asReal() );
  1517. } else goto fail;
  1518. w = "gravity";
  1519. if (sd.has(w))
  1520. {
  1521. setGravity( (F32)sd[w].asReal() );
  1522. } else goto fail;
  1523. w = "simulate_lod";
  1524. if (sd.has(w))
  1525. {
  1526. setSimulateLOD( sd[w].asInteger() );
  1527. } else goto fail;
  1528. w = "tension";
  1529. if (sd.has(w))
  1530. {
  1531. setTension( (F32)sd[w].asReal() );
  1532. } else goto fail;
  1533. w = "user_force";
  1534. if (sd.has(w))
  1535. {
  1536. LLVector3 user_force = ll_vector3_from_sd(sd[w], 0);
  1537. setUserForce( user_force );
  1538. } else goto fail;
  1539. w = "wind_sensitivity";
  1540. if (sd.has(w))
  1541. {
  1542. setWindSensitivity( (F32)sd[w].asReal() );
  1543. } else goto fail;
  1544. return true;
  1545.  fail:
  1546. return false;
  1547. }
  1548. //============================================================================
  1549. LLSculptParams::LLSculptParams()
  1550. {
  1551. mType = PARAMS_SCULPT;
  1552. mSculptTexture.set(SCULPT_DEFAULT_TEXTURE);
  1553. mSculptType = LL_SCULPT_TYPE_SPHERE;
  1554. }
  1555. BOOL LLSculptParams::pack(LLDataPacker &dp) const
  1556. {
  1557. dp.packUUID(mSculptTexture, "texture");
  1558. dp.packU8(mSculptType, "type");
  1559. return TRUE;
  1560. }
  1561. BOOL LLSculptParams::unpack(LLDataPacker &dp)
  1562. {
  1563. dp.unpackUUID(mSculptTexture, "texture");
  1564. dp.unpackU8(mSculptType, "type");
  1565. return TRUE;
  1566. }
  1567. bool LLSculptParams::operator==(const LLNetworkData& data) const
  1568. {
  1569. if (data.mType != PARAMS_SCULPT)
  1570. {
  1571. return false;
  1572. }
  1573. const LLSculptParams *param = (const LLSculptParams*)&data;
  1574. if ( (param->mSculptTexture != mSculptTexture) ||
  1575.  (param->mSculptType != mSculptType) )
  1576.  
  1577. {
  1578. return false;
  1579. }
  1580. return true;
  1581. }
  1582. void LLSculptParams::copy(const LLNetworkData& data)
  1583. {
  1584. const LLSculptParams *param = (LLSculptParams*)&data;
  1585. mSculptTexture = param->mSculptTexture;
  1586. mSculptType = param->mSculptType;
  1587. }
  1588. LLSD LLSculptParams::asLLSD() const
  1589. {
  1590. LLSD sd;
  1591. sd["texture"] = mSculptTexture;
  1592. sd["type"] = mSculptType;
  1593. return sd;
  1594. }
  1595. bool LLSculptParams::fromLLSD(LLSD& sd)
  1596. {
  1597. const char *w;
  1598. w = "texture";
  1599. if (sd.has(w))
  1600. {
  1601. setSculptTexture( sd[w] );
  1602. } else goto fail;
  1603. w = "type";
  1604. if (sd.has(w))
  1605. {
  1606. setSculptType( (U8)sd[w].asInteger() );
  1607. } else goto fail;
  1608. return true;
  1609.  fail:
  1610. return false;
  1611. }
  1612. //============================================================================
  1613. LLLightImageParams::LLLightImageParams()
  1614. {
  1615. mType = PARAMS_LIGHT_IMAGE;
  1616. mParams.setVec(F_PI*0.5f, 0.f, 0.f);
  1617. }
  1618. BOOL LLLightImageParams::pack(LLDataPacker &dp) const
  1619. {
  1620. dp.packUUID(mLightTexture, "texture");
  1621. dp.packVector3(mParams, "params");
  1622. return TRUE;
  1623. }
  1624. BOOL LLLightImageParams::unpack(LLDataPacker &dp)
  1625. {
  1626. dp.unpackUUID(mLightTexture, "texture");
  1627. dp.unpackVector3(mParams, "params");
  1628. return TRUE;
  1629. }
  1630. bool LLLightImageParams::operator==(const LLNetworkData& data) const
  1631. {
  1632. if (data.mType != PARAMS_LIGHT_IMAGE)
  1633. {
  1634. return false;
  1635. }
  1636. const LLLightImageParams *param = (const LLLightImageParams*)&data;
  1637. if ( (param->mLightTexture != mLightTexture) )
  1638. {
  1639. return false;
  1640. }
  1641. if ( (param->mParams != mParams ) )
  1642. {
  1643. return false;
  1644. }
  1645. return true;
  1646. }
  1647. void LLLightImageParams::copy(const LLNetworkData& data)
  1648. {
  1649. const LLLightImageParams *param = (LLLightImageParams*)&data;
  1650. mLightTexture = param->mLightTexture;
  1651. mParams = param->mParams;
  1652. }
  1653. LLSD LLLightImageParams::asLLSD() const
  1654. {
  1655. LLSD sd;
  1656. sd["texture"] = mLightTexture;
  1657. sd["params"] = mParams.getValue();
  1658. return sd;
  1659. }
  1660. bool LLLightImageParams::fromLLSD(LLSD& sd)
  1661. {
  1662. if (sd.has("texture"))
  1663. {
  1664. setLightTexture( sd["texture"] );
  1665. setParams( LLVector3( sd["params"] ) );
  1666. return true;
  1667. return false;
  1668. }