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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file lltextureentry.cpp
  3.  * @brief LLTextureEntry 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 "lluuid.h"
  34. #include "llmediaentry.h"
  35. #include "lltextureentry.h"
  36. #include "llsdutil_math.h"
  37. #include "v4color.h"
  38. const U8 DEFAULT_BUMP_CODE = 0;  // no bump or shininess
  39. const LLTextureEntry LLTextureEntry::null;
  40. // Some LLSD keys.  Do not change these!
  41. #define OBJECT_ID_KEY_STR "object_id"
  42. #define TEXTURE_INDEX_KEY_STR "texture_index"
  43. #define OBJECT_MEDIA_VERSION_KEY_STR "object_media_version"
  44. #define OBJECT_MEDIA_DATA_KEY_STR "object_media_data"
  45. #define TEXTURE_MEDIA_DATA_KEY_STR "media_data"
  46. /*static*/ const char* LLTextureEntry::OBJECT_ID_KEY = OBJECT_ID_KEY_STR;
  47. /*static*/ const char* LLTextureEntry::OBJECT_MEDIA_DATA_KEY = OBJECT_MEDIA_DATA_KEY_STR;
  48. /*static*/ const char* LLTextureEntry::MEDIA_VERSION_KEY = OBJECT_MEDIA_VERSION_KEY_STR;
  49. /*static*/ const char* LLTextureEntry::TEXTURE_INDEX_KEY = TEXTURE_INDEX_KEY_STR;
  50. /*static*/ const char* LLTextureEntry::TEXTURE_MEDIA_DATA_KEY = TEXTURE_MEDIA_DATA_KEY_STR;
  51. static const std::string MEDIA_VERSION_STRING_PREFIX = "x-mv:";
  52. // static 
  53. LLTextureEntry* LLTextureEntry::newTextureEntry()
  54. {
  55. return new LLTextureEntry();
  56. }
  57. //===============================================================
  58. LLTextureEntry::LLTextureEntry()
  59.   : mMediaEntry(NULL)
  60. {
  61. init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
  62. }
  63. LLTextureEntry::LLTextureEntry(const LLUUID& tex_id)
  64.   : mMediaEntry(NULL)
  65. {
  66. init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
  67. }
  68. LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
  69.   : mMediaEntry(NULL)
  70. {
  71. mID = rhs.mID;
  72. mScaleS = rhs.mScaleS;
  73. mScaleT = rhs.mScaleT;
  74. mOffsetS = rhs.mOffsetS;
  75. mOffsetT = rhs.mOffsetT;
  76. mRotation = rhs.mRotation;
  77. mColor = rhs.mColor;
  78. mBump = rhs.mBump;
  79. mMediaFlags = rhs.mMediaFlags;
  80. mGlow = rhs.mGlow;
  81. if (rhs.mMediaEntry != NULL) {
  82. // Make a copy
  83. mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry);
  84. }
  85. }
  86. LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
  87. {
  88. if (this != &rhs)
  89. {
  90. mID = rhs.mID;
  91. mScaleS = rhs.mScaleS;
  92. mScaleT = rhs.mScaleT;
  93. mOffsetS = rhs.mOffsetS;
  94. mOffsetT = rhs.mOffsetT;
  95. mRotation = rhs.mRotation;
  96. mColor = rhs.mColor;
  97. mBump = rhs.mBump;
  98. mMediaFlags = rhs.mMediaFlags;
  99. mGlow = rhs.mGlow;
  100. if (mMediaEntry != NULL) {
  101. delete mMediaEntry;
  102. }
  103. if (rhs.mMediaEntry != NULL) {
  104. // Make a copy
  105. mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry);
  106. }
  107. else {
  108. mMediaEntry = NULL;
  109. }
  110. }
  111. return *this;
  112. }
  113. void LLTextureEntry::init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 offset_s, F32 offset_t, F32 rotation, U8 bump)
  114. {
  115. setID(tex_id);
  116. mScaleS = scale_s;
  117. mScaleT = scale_t;
  118. mOffsetS = offset_s;
  119. mOffsetT = offset_t;
  120. mRotation = rotation;
  121. mBump = bump;
  122. mMediaFlags = 0x0;
  123.     mGlow = 0;
  124. setColor(LLColor4(1.f, 1.f, 1.f, 1.f));
  125. if (mMediaEntry != NULL) {
  126.     delete mMediaEntry;
  127. }
  128. mMediaEntry = NULL;
  129. }
  130. LLTextureEntry::~LLTextureEntry()
  131. {
  132. if(mMediaEntry)
  133. {
  134. delete mMediaEntry;
  135. mMediaEntry = NULL;
  136. }
  137. }
  138. bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const
  139. {
  140. if (mID != rhs.mID) return(true);
  141. if (mScaleS != rhs.mScaleS) return(true);
  142. if (mScaleT != rhs.mScaleT) return(true);
  143. if (mOffsetS != rhs.mOffsetS) return(true);
  144. if (mOffsetT != rhs.mOffsetT) return(true);
  145. if (mRotation != rhs.mRotation) return(true);
  146. if (mColor != rhs.mColor) return (true);
  147. if (mBump != rhs.mBump) return (true);
  148. if (mMediaFlags != rhs.mMediaFlags) return (true);
  149. if (mGlow != rhs.mGlow) return (true);
  150. return(false);
  151. }
  152. bool LLTextureEntry::operator==(const LLTextureEntry &rhs) const
  153. {
  154. if (mID != rhs.mID) return(false);
  155. if (mScaleS != rhs.mScaleS) return(false);
  156. if (mScaleT != rhs.mScaleT) return(false);
  157. if (mOffsetS != rhs.mOffsetS) return(false);
  158. if (mOffsetT != rhs.mOffsetT) return(false);
  159. if (mRotation != rhs.mRotation) return(false);
  160. if (mColor != rhs.mColor) return (false);
  161. if (mBump != rhs.mBump) return (false);
  162. if (mMediaFlags != rhs.mMediaFlags) return false;
  163. if (mGlow != rhs.mGlow) return false;
  164. return(true);
  165. }
  166. LLSD LLTextureEntry::asLLSD() const
  167. {
  168. LLSD sd;
  169. asLLSD(sd);
  170. return sd;
  171. }
  172. void LLTextureEntry::asLLSD(LLSD& sd) const
  173. {
  174. sd["imageid"] = mID;
  175. sd["colors"] = ll_sd_from_color4(mColor);
  176. sd["scales"] = mScaleS;
  177. sd["scalet"] = mScaleT;
  178. sd["offsets"] = mOffsetS;
  179. sd["offsett"] = mOffsetT;
  180. sd["imagerot"] = mRotation;
  181. sd["bump"] = getBumpShiny();
  182. sd["fullbright"] = getFullbright();
  183. sd["media_flags"] = mMediaFlags;
  184. if (hasMedia()) {
  185. LLSD mediaData;
  186.         if (NULL != getMediaData()) {
  187.             getMediaData()->asLLSD(mediaData);
  188.         }
  189. sd[TEXTURE_MEDIA_DATA_KEY] = mediaData;
  190. }
  191. sd["glow"] = mGlow;
  192. }
  193. bool LLTextureEntry::fromLLSD(const LLSD& sd)
  194. {
  195. const char *w, *x;
  196. w = "imageid";
  197. if (sd.has(w))
  198. {
  199. setID( sd[w] );
  200. } else goto fail;
  201. w = "colors";
  202. if (sd.has(w))
  203. {
  204. setColor( ll_color4_from_sd(sd["colors"]) );
  205. } else goto fail;
  206. w = "scales";
  207. x = "scalet";
  208. if (sd.has(w) && sd.has(x))
  209. {
  210. setScale( (F32)sd[w].asReal(), (F32)sd[x].asReal() );
  211. } else goto fail;
  212. w = "offsets";
  213. x = "offsett";
  214. if (sd.has(w) && sd.has(x))
  215. {
  216. setOffset( (F32)sd[w].asReal(), (F32)sd[x].asReal() );
  217. } else goto fail;
  218. w = "imagerot";
  219. if (sd.has(w))
  220. {
  221. setRotation( (F32)sd[w].asReal() );
  222. } else goto fail;
  223. w = "bump";
  224. if (sd.has(w))
  225. {
  226. setBumpShiny( sd[w].asInteger() );
  227. } else goto fail;
  228. w = "fullbright";
  229. if (sd.has(w))
  230. {
  231. setFullbright( sd[w].asInteger() );
  232. } else goto fail;
  233. w = "media_flags";
  234. if (sd.has(w))
  235. {
  236. setMediaTexGen( sd[w].asInteger() );
  237. } else goto fail;
  238. // If the "has media" flag doesn't match the fact that 
  239. // media data exists, updateMediaData will "fix" it
  240. // by either clearing or setting the flag
  241. w = TEXTURE_MEDIA_DATA_KEY;
  242. if (hasMedia() != sd.has(w))
  243. {
  244. llwarns << "LLTextureEntry::fromLLSD: media_flags (" << hasMedia() <<
  245. ") does not match presence of media_data (" << sd.has(w) << ").  Fixing." << llendl;
  246. }
  247. updateMediaData(sd[w]);
  248. w = "glow";
  249. if (sd.has(w))
  250. {
  251. setGlow((F32)sd[w].asReal() );
  252. }
  253. return true;
  254. fail:
  255. return false;
  256. }
  257. // virtual 
  258. // override this method for each derived class
  259. LLTextureEntry* LLTextureEntry::newBlank() const
  260. {
  261. return new LLTextureEntry();
  262. }
  263. // virtual 
  264. LLTextureEntry* LLTextureEntry::newCopy() const
  265. {
  266. return new LLTextureEntry(*this);
  267. }
  268. S32 LLTextureEntry::setID(const LLUUID &tex_id)
  269. {
  270. if (mID != tex_id)
  271. {
  272. mID = tex_id;
  273. return TEM_CHANGE_TEXTURE;
  274. }
  275. return TEM_CHANGE_NONE;
  276. }
  277. S32 LLTextureEntry::setScale(F32 s, F32 t)
  278. {
  279. S32 retval = 0;
  280. if (  (mScaleS != s)
  281. ||(mScaleT != t))
  282. {
  283. mScaleS = s;
  284. mScaleT = t;
  285. retval = TEM_CHANGE_TEXTURE;
  286. }
  287. return retval;
  288. }
  289. S32 LLTextureEntry::setScaleS(F32 s)
  290. {
  291. S32 retval = TEM_CHANGE_NONE;
  292. if (mScaleS != s)
  293. {
  294. mScaleS = s;
  295. retval = TEM_CHANGE_TEXTURE;
  296. }
  297. return retval;
  298. }
  299. S32 LLTextureEntry::setScaleT(F32 t)
  300. {
  301. S32 retval = TEM_CHANGE_NONE;
  302. if (mScaleT != t)
  303. {
  304. mScaleT = t;
  305. retval = TEM_CHANGE_TEXTURE;
  306. }
  307. return retval;
  308. }
  309. S32 LLTextureEntry::setColor(const LLColor4 &color)
  310. {
  311. if (mColor != color)
  312. {
  313. mColor = color;
  314. return TEM_CHANGE_COLOR;
  315. }
  316. return TEM_CHANGE_NONE;
  317. }
  318. S32 LLTextureEntry::setColor(const LLColor3 &color)
  319. {
  320. if (mColor != color)
  321. {
  322. // This preserves alpha.
  323. mColor.setVec(color);
  324. return TEM_CHANGE_COLOR;
  325. }
  326. return TEM_CHANGE_NONE;
  327. }
  328. S32 LLTextureEntry::setAlpha(const F32 alpha)
  329. {
  330. if (mColor.mV[VW] != alpha)
  331. {
  332. mColor.mV[VW] = alpha;
  333. return TEM_CHANGE_COLOR;
  334. }
  335. return TEM_CHANGE_NONE;
  336. }
  337. S32 LLTextureEntry::setOffset(F32 s, F32 t)
  338. {
  339. S32 retval = 0;
  340. if (  (mOffsetS != s)
  341. ||(mOffsetT != t))
  342. {
  343. mOffsetS = s;
  344. mOffsetT = t;
  345. retval = TEM_CHANGE_TEXTURE;
  346. }
  347. return retval;
  348. }
  349. S32 LLTextureEntry::setOffsetS(F32 s)
  350. {
  351. S32 retval = 0;
  352. if (mOffsetS != s)
  353. {
  354. mOffsetS = s;
  355. retval = TEM_CHANGE_TEXTURE;
  356. }
  357. return retval;
  358. }
  359. S32 LLTextureEntry::setOffsetT(F32 t)
  360. {
  361. S32 retval = 0;
  362. if (mOffsetT != t)
  363. {
  364. mOffsetT = t;
  365. retval = TEM_CHANGE_TEXTURE;
  366. }
  367. return retval;
  368. }
  369. S32 LLTextureEntry::setRotation(F32 theta)
  370. {
  371. if (mRotation != theta)
  372. {
  373. mRotation = theta;
  374. return TEM_CHANGE_TEXTURE;
  375. }
  376. return TEM_CHANGE_NONE;
  377. }
  378. S32 LLTextureEntry::setBumpShinyFullbright(U8 bump)
  379. {
  380. if (mBump != bump)
  381. {
  382. mBump = bump;
  383. return TEM_CHANGE_TEXTURE;
  384. }
  385. return TEM_CHANGE_NONE;
  386. }
  387. S32 LLTextureEntry::setMediaTexGen(U8 media)
  388. {
  389. if (mMediaFlags != media)
  390. {
  391. mMediaFlags = media;
  392. // Special code for media handling
  393. if( hasMedia() && mMediaEntry == NULL)
  394. {
  395. mMediaEntry = new LLMediaEntry;
  396. }
  397.         else if ( ! hasMedia() && mMediaEntry != NULL)
  398.         {
  399.             delete mMediaEntry;
  400.             mMediaEntry = NULL;
  401.         }
  402. return TEM_CHANGE_MEDIA;
  403. }
  404. return TEM_CHANGE_NONE;
  405. }
  406. S32 LLTextureEntry::setBumpmap(U8 bump)
  407. {
  408. bump &= TEM_BUMP_MASK;
  409. if (getBumpmap() != bump)
  410. {
  411. mBump &= ~TEM_BUMP_MASK;
  412. mBump |= bump;
  413. return TEM_CHANGE_TEXTURE;
  414. }
  415. return TEM_CHANGE_NONE;
  416. }
  417. S32 LLTextureEntry::setFullbright(U8 fullbright)
  418. {
  419. fullbright &= TEM_FULLBRIGHT_MASK;
  420. if (getFullbright() != fullbright)
  421. {
  422. mBump &= ~(TEM_FULLBRIGHT_MASK<<TEM_FULLBRIGHT_SHIFT);
  423. mBump |= fullbright << TEM_FULLBRIGHT_SHIFT;
  424. return TEM_CHANGE_TEXTURE;
  425. }
  426. return TEM_CHANGE_NONE;
  427. }
  428. S32 LLTextureEntry::setShiny(U8 shiny)
  429. {
  430. shiny &= TEM_SHINY_MASK;
  431. if (getShiny() != shiny)
  432. {
  433. mBump &= ~(TEM_SHINY_MASK<<TEM_SHINY_SHIFT);
  434. mBump |= shiny << TEM_SHINY_SHIFT;
  435. return TEM_CHANGE_TEXTURE;
  436. }
  437. return TEM_CHANGE_NONE;
  438. }
  439. S32 LLTextureEntry::setBumpShiny(U8 bump_shiny)
  440. {
  441. bump_shiny &= TEM_BUMP_SHINY_MASK;
  442. if (getBumpShiny() != bump_shiny)
  443. {
  444. mBump &= ~TEM_BUMP_SHINY_MASK;
  445. mBump |= bump_shiny;
  446. return TEM_CHANGE_TEXTURE;
  447. }
  448. return TEM_CHANGE_NONE;
  449. }
  450. S32 LLTextureEntry::setMediaFlags(U8 media_flags)
  451. {
  452. media_flags &= TEM_MEDIA_MASK;
  453. if (getMediaFlags() != media_flags)
  454. {
  455. mMediaFlags &= ~TEM_MEDIA_MASK;
  456. mMediaFlags |= media_flags;
  457.         
  458. // Special code for media handling
  459. if( hasMedia() && mMediaEntry == NULL)
  460. {
  461. mMediaEntry = new LLMediaEntry;
  462. }
  463.         else if ( ! hasMedia() && mMediaEntry != NULL)
  464.         {
  465.             delete mMediaEntry;
  466.             mMediaEntry = NULL;
  467.         }
  468.         
  469. return TEM_CHANGE_MEDIA;
  470. }
  471. return TEM_CHANGE_NONE;
  472. }
  473. S32 LLTextureEntry::setTexGen(U8 tex_gen)
  474. {
  475. tex_gen &= TEM_TEX_GEN_MASK;
  476. if (getTexGen() != tex_gen)
  477. {
  478. mMediaFlags &= ~TEM_TEX_GEN_MASK;
  479. mMediaFlags |= tex_gen;
  480. return TEM_CHANGE_TEXTURE;
  481. }
  482. return TEM_CHANGE_NONE;
  483. }
  484. S32 LLTextureEntry::setGlow(F32 glow)
  485. {
  486. if (mGlow != glow)
  487. {
  488. mGlow = glow;
  489. return TEM_CHANGE_TEXTURE;
  490. }
  491. return TEM_CHANGE_NONE;
  492. }
  493. void LLTextureEntry::setMediaData(const LLMediaEntry &media_entry)
  494. {
  495.     mMediaFlags |= MF_HAS_MEDIA;
  496.     if (NULL != mMediaEntry)
  497.     {
  498.         delete mMediaEntry;
  499.     }
  500.     mMediaEntry = new LLMediaEntry(media_entry);
  501. }
  502. bool LLTextureEntry::updateMediaData(const LLSD& media_data)
  503. {
  504. if (media_data.isUndefined())
  505. {
  506. // clear the media data
  507.         clearMediaData();
  508. return false;
  509. }
  510. else {
  511. mMediaFlags |= MF_HAS_MEDIA;
  512. if (mMediaEntry == NULL)
  513. {
  514. mMediaEntry = new LLMediaEntry;
  515. }
  516.         // *NOTE: this will *clobber* all of the fields in mMediaEntry 
  517.         // with whatever fields are present (or not present) in media_data!
  518.   mMediaEntry->fromLLSD(media_data);
  519. return true;
  520. }
  521. }
  522. void LLTextureEntry::clearMediaData()
  523. {
  524.     mMediaFlags &= ~MF_HAS_MEDIA;
  525.     if (mMediaEntry != NULL) {
  526.         delete mMediaEntry;
  527.     }
  528.     mMediaEntry = NULL;
  529. }    
  530. void LLTextureEntry::mergeIntoMediaData(const LLSD& media_fields)
  531. {
  532.     mMediaFlags |= MF_HAS_MEDIA;
  533.     if (mMediaEntry == NULL)
  534.     {
  535.         mMediaEntry = new LLMediaEntry;
  536.     }
  537.     // *NOTE: this will *merge* the data in media_fields
  538.     // with the data in our media entry
  539.     mMediaEntry->mergeFromLLSD(media_fields);
  540. }
  541. //static
  542. std::string LLTextureEntry::touchMediaVersionString(const std::string &in_version, const LLUUID &agent_id)
  543. {
  544.     // XXX TODO: make media version string binary (base64-encoded?)
  545.     // Media "URL" is a representation of a version and the last-touched agent
  546.     // x-mv:nnnnn/agent-id
  547.     // where "nnnnn" is version number
  548.     // *NOTE: not the most efficient code in the world...
  549.     U32 current_version = getVersionFromMediaVersionString(in_version) + 1;
  550.     const size_t MAX_VERSION_LEN = 10; // 2^32 fits in 10 decimal digits
  551.     char buf[MAX_VERSION_LEN+1];
  552.     snprintf(buf, (int)MAX_VERSION_LEN+1, "%0*u", (int)MAX_VERSION_LEN, current_version);  // added int cast to fix warning/breakage on mac.
  553.     return MEDIA_VERSION_STRING_PREFIX + buf + "/" + agent_id.asString();
  554. }
  555. //static
  556. U32 LLTextureEntry::getVersionFromMediaVersionString(const std::string &version_string)
  557. {
  558.     U32 version = 0;
  559.     if (!version_string.empty()) 
  560.     {
  561.         size_t found = version_string.find(MEDIA_VERSION_STRING_PREFIX);
  562.         if (found != std::string::npos) 
  563.         {
  564.             found = version_string.find_first_of("/", found);
  565.             std::string v = version_string.substr(MEDIA_VERSION_STRING_PREFIX.length(), found);
  566.             version = strtoul(v.c_str(),NULL,10);
  567.         }
  568.     }
  569.     return version;
  570. }
  571. //static
  572. LLUUID LLTextureEntry::getAgentIDFromMediaVersionString(const std::string &version_string)
  573. {
  574.     LLUUID id;
  575.     if (!version_string.empty()) 
  576.     {
  577.         size_t found = version_string.find(MEDIA_VERSION_STRING_PREFIX);
  578.         if (found != std::string::npos) 
  579.         {
  580.             found = version_string.find_first_of("/", found);
  581.             if (found != std::string::npos) 
  582.             {
  583.                 std::string v = version_string.substr(found + 1);
  584.                 id.set(v);
  585.             }
  586.         }
  587.     }
  588.     return id;
  589. }
  590. //static
  591. bool LLTextureEntry::isMediaVersionString(const std::string &version_string)
  592. {
  593. return std::string::npos != version_string.find(MEDIA_VERSION_STRING_PREFIX);
  594. }