aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llprimitive/lltextureentry.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llprimitive/lltextureentry.cpp')
-rwxr-xr-x[-rw-r--r--]linden/indra/llprimitive/lltextureentry.cpp314
1 files changed, 288 insertions, 26 deletions
diff --git a/linden/indra/llprimitive/lltextureentry.cpp b/linden/indra/llprimitive/lltextureentry.cpp
index 14b4544..11afdc0 100644..100755
--- a/linden/indra/llprimitive/lltextureentry.cpp
+++ b/linden/indra/llprimitive/lltextureentry.cpp
@@ -4,7 +4,7 @@
4 * 4 *
5 * $LicenseInfo:firstyear=2001&license=viewergpl$ 5 * $LicenseInfo:firstyear=2001&license=viewergpl$
6 * 6 *
7 * Copyright (c) 2001-2009, Linden Research, Inc. 7 * Copyright (c) 2001-2010, Linden Research, Inc.
8 * 8 *
9 * Second Life Viewer Source Code 9 * Second Life Viewer Source Code
10 * The source code in this file ("Source Code") is provided by Linden Lab 10 * The source code in this file ("Source Code") is provided by Linden Lab
@@ -32,25 +32,52 @@
32 32
33#include "linden_common.h" 33#include "linden_common.h"
34 34
35#include "lluuid.h"
36#include "llmediaentry.h"
35#include "lltextureentry.h" 37#include "lltextureentry.h"
36#include "llsdutil.h" 38#include "llsdutil.h"//_math.h"
39#include "v4color.h"
37 40
38const U8 DEFAULT_BUMP_CODE = 0; // no bump or shininess 41const U8 DEFAULT_BUMP_CODE = 0; // no bump or shininess
39 42
40const LLTextureEntry LLTextureEntry::null; 43const LLTextureEntry LLTextureEntry::null;
41 44
45// Some LLSD keys. Do not change these!
46#define OBJECT_ID_KEY_STR "object_id"
47#define TEXTURE_INDEX_KEY_STR "texture_index"
48#define OBJECT_MEDIA_VERSION_KEY_STR "object_media_version"
49#define OBJECT_MEDIA_DATA_KEY_STR "object_media_data"
50#define TEXTURE_MEDIA_DATA_KEY_STR "media_data"
51
52/*static*/ const char* LLTextureEntry::OBJECT_ID_KEY = OBJECT_ID_KEY_STR;
53/*static*/ const char* LLTextureEntry::OBJECT_MEDIA_DATA_KEY = OBJECT_MEDIA_DATA_KEY_STR;
54/*static*/ const char* LLTextureEntry::MEDIA_VERSION_KEY = OBJECT_MEDIA_VERSION_KEY_STR;
55/*static*/ const char* LLTextureEntry::TEXTURE_INDEX_KEY = TEXTURE_INDEX_KEY_STR;
56/*static*/ const char* LLTextureEntry::TEXTURE_MEDIA_DATA_KEY = TEXTURE_MEDIA_DATA_KEY_STR;
57
58static const std::string MEDIA_VERSION_STRING_PREFIX = "x-mv:";
59
60// static
61LLTextureEntry* LLTextureEntry::newTextureEntry()
62{
63 return new LLTextureEntry();
64}
65
42//=============================================================== 66//===============================================================
43LLTextureEntry::LLTextureEntry() 67LLTextureEntry::LLTextureEntry()
68 : mMediaEntry(NULL)
44{ 69{
45 init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE); 70 init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
46} 71}
47 72
48LLTextureEntry::LLTextureEntry(const LLUUID& tex_id) 73LLTextureEntry::LLTextureEntry(const LLUUID& tex_id)
74 : mMediaEntry(NULL)
49{ 75{
50 init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE); 76 init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
51} 77}
52 78
53LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs) 79LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
80 : mMediaEntry(NULL)
54{ 81{
55 mID = rhs.mID; 82 mID = rhs.mID;
56 mScaleS = rhs.mScaleS; 83 mScaleS = rhs.mScaleS;
@@ -62,6 +89,10 @@ LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
62 mBump = rhs.mBump; 89 mBump = rhs.mBump;
63 mMediaFlags = rhs.mMediaFlags; 90 mMediaFlags = rhs.mMediaFlags;
64 mGlow = rhs.mGlow; 91 mGlow = rhs.mGlow;
92 if (rhs.mMediaEntry != NULL) {
93 // Make a copy
94 mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry);
95 }
65} 96}
66 97
67LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs) 98LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
@@ -78,6 +109,16 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
78 mBump = rhs.mBump; 109 mBump = rhs.mBump;
79 mMediaFlags = rhs.mMediaFlags; 110 mMediaFlags = rhs.mMediaFlags;
80 mGlow = rhs.mGlow; 111 mGlow = rhs.mGlow;
112 if (mMediaEntry != NULL) {
113 delete mMediaEntry;
114 }
115 if (rhs.mMediaEntry != NULL) {
116 // Make a copy
117 mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry);
118 }
119 else {
120 mMediaEntry = NULL;
121 }
81 } 122 }
82 123
83 return *this; 124 return *this;
@@ -97,10 +138,19 @@ void LLTextureEntry::init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 of
97 mGlow = 0; 138 mGlow = 0;
98 139
99 setColor(LLColor4(1.f, 1.f, 1.f, 1.f)); 140 setColor(LLColor4(1.f, 1.f, 1.f, 1.f));
141 if (mMediaEntry != NULL) {
142 delete mMediaEntry;
143 }
144 mMediaEntry = NULL;
100} 145}
101 146
102LLTextureEntry::~LLTextureEntry() 147LLTextureEntry::~LLTextureEntry()
103{ 148{
149 if(mMediaEntry)
150 {
151 delete mMediaEntry;
152 mMediaEntry = NULL;
153 }
104} 154}
105 155
106bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const 156bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const
@@ -136,23 +186,33 @@ bool LLTextureEntry::operator==(const LLTextureEntry &rhs) const
136LLSD LLTextureEntry::asLLSD() const 186LLSD LLTextureEntry::asLLSD() const
137{ 187{
138 LLSD sd; 188 LLSD sd;
189 asLLSD(sd);
190 return sd;
191}
139 192
140 sd["imageid"] = getID(); 193void LLTextureEntry::asLLSD(LLSD& sd) const
141 sd["colors"] = ll_sd_from_color4(getColor()); 194{
195 sd["imageid"] = mID;
196 sd["colors"] = ll_sd_from_color4(mColor);
142 sd["scales"] = mScaleS; 197 sd["scales"] = mScaleS;
143 sd["scalet"] = mScaleT; 198 sd["scalet"] = mScaleT;
144 sd["offsets"] = mOffsetS; 199 sd["offsets"] = mOffsetS;
145 sd["offsett"] = mOffsetT; 200 sd["offsett"] = mOffsetT;
146 sd["imagerot"] = getRotation(); 201 sd["imagerot"] = mRotation;
147 sd["bump"] = getBumpShiny(); 202 sd["bump"] = getBumpShiny();
148 sd["fullbright"] = getFullbright(); 203 sd["fullbright"] = getFullbright();
149 sd["media_flags"] = getMediaTexGen(); 204 sd["media_flags"] = mMediaFlags;
150 sd["glow"] = getGlow(); 205 if (hasMedia()) {
151 206 LLSD mediaData;
152 return sd; 207 if (NULL != getMediaData()) {
208 getMediaData()->asLLSD(mediaData);
209 }
210 sd[TEXTURE_MEDIA_DATA_KEY] = mediaData;
211 }
212 sd["glow"] = mGlow;
153} 213}
154 214
155bool LLTextureEntry::fromLLSD(LLSD& sd) 215bool LLTextureEntry::fromLLSD(const LLSD& sd)
156{ 216{
157 const char *w, *x; 217 const char *w, *x;
158 w = "imageid"; 218 w = "imageid";
@@ -197,6 +257,17 @@ bool LLTextureEntry::fromLLSD(LLSD& sd)
197 { 257 {
198 setMediaTexGen( sd[w].asInteger() ); 258 setMediaTexGen( sd[w].asInteger() );
199 } else goto fail; 259 } else goto fail;
260 // If the "has media" flag doesn't match the fact that
261 // media data exists, updateMediaData will "fix" it
262 // by either clearing or setting the flag
263 w = TEXTURE_MEDIA_DATA_KEY;
264 if (hasMedia() != sd.has(w))
265 {
266 llwarns << "LLTextureEntry::fromLLSD: media_flags (" << hasMedia() <<
267 ") does not match presence of media_data (" << sd.has(w) << "). Fixing." << llendl;
268 }
269 updateMediaData(sd[w]);
270
200 w = "glow"; 271 w = "glow";
201 if (sd.has(w)) 272 if (sd.has(w))
202 { 273 {
@@ -208,6 +279,19 @@ fail:
208 return false; 279 return false;
209} 280}
210 281
282// virtual
283// override this method for each derived class
284LLTextureEntry* LLTextureEntry::newBlank() const
285{
286 return new LLTextureEntry();
287}
288
289// virtual
290LLTextureEntry* LLTextureEntry::newCopy() const
291{
292 return new LLTextureEntry(*this);
293}
294
211S32 LLTextureEntry::setID(const LLUUID &tex_id) 295S32 LLTextureEntry::setID(const LLUUID &tex_id)
212{ 296{
213 if (mID != tex_id) 297 if (mID != tex_id)
@@ -215,7 +299,7 @@ S32 LLTextureEntry::setID(const LLUUID &tex_id)
215 mID = tex_id; 299 mID = tex_id;
216 return TEM_CHANGE_TEXTURE; 300 return TEM_CHANGE_TEXTURE;
217 } 301 }
218 return 0; 302 return TEM_CHANGE_NONE;
219} 303}
220 304
221S32 LLTextureEntry::setScale(F32 s, F32 t) 305S32 LLTextureEntry::setScale(F32 s, F32 t)
@@ -233,6 +317,28 @@ S32 LLTextureEntry::setScale(F32 s, F32 t)
233 return retval; 317 return retval;
234} 318}
235 319
320S32 LLTextureEntry::setScaleS(F32 s)
321{
322 S32 retval = TEM_CHANGE_NONE;
323 if (mScaleS != s)
324 {
325 mScaleS = s;
326 retval = TEM_CHANGE_TEXTURE;
327 }
328 return retval;
329}
330
331S32 LLTextureEntry::setScaleT(F32 t)
332{
333 S32 retval = TEM_CHANGE_NONE;
334 if (mScaleT != t)
335 {
336 mScaleT = t;
337 retval = TEM_CHANGE_TEXTURE;
338 }
339 return retval;
340}
341
236S32 LLTextureEntry::setColor(const LLColor4 &color) 342S32 LLTextureEntry::setColor(const LLColor4 &color)
237{ 343{
238 if (mColor != color) 344 if (mColor != color)
@@ -240,7 +346,7 @@ S32 LLTextureEntry::setColor(const LLColor4 &color)
240 mColor = color; 346 mColor = color;
241 return TEM_CHANGE_COLOR; 347 return TEM_CHANGE_COLOR;
242 } 348 }
243 return 0; 349 return TEM_CHANGE_NONE;
244} 350}
245 351
246S32 LLTextureEntry::setColor(const LLColor3 &color) 352S32 LLTextureEntry::setColor(const LLColor3 &color)
@@ -251,7 +357,7 @@ S32 LLTextureEntry::setColor(const LLColor3 &color)
251 mColor.setVec(color); 357 mColor.setVec(color);
252 return TEM_CHANGE_COLOR; 358 return TEM_CHANGE_COLOR;
253 } 359 }
254 return 0; 360 return TEM_CHANGE_NONE;
255} 361}
256 362
257S32 LLTextureEntry::setAlpha(const F32 alpha) 363S32 LLTextureEntry::setAlpha(const F32 alpha)
@@ -261,7 +367,7 @@ S32 LLTextureEntry::setAlpha(const F32 alpha)
261 mColor.mV[VW] = alpha; 367 mColor.mV[VW] = alpha;
262 return TEM_CHANGE_COLOR; 368 return TEM_CHANGE_COLOR;
263 } 369 }
264 return 0; 370 return TEM_CHANGE_NONE;
265} 371}
266 372
267S32 LLTextureEntry::setOffset(F32 s, F32 t) 373S32 LLTextureEntry::setOffset(F32 s, F32 t)
@@ -279,6 +385,28 @@ S32 LLTextureEntry::setOffset(F32 s, F32 t)
279 return retval; 385 return retval;
280} 386}
281 387
388S32 LLTextureEntry::setOffsetS(F32 s)
389{
390 S32 retval = 0;
391 if (mOffsetS != s)
392 {
393 mOffsetS = s;
394 retval = TEM_CHANGE_TEXTURE;
395 }
396 return retval;
397}
398
399S32 LLTextureEntry::setOffsetT(F32 t)
400{
401 S32 retval = 0;
402 if (mOffsetT != t)
403 {
404 mOffsetT = t;
405 retval = TEM_CHANGE_TEXTURE;
406 }
407 return retval;
408}
409
282S32 LLTextureEntry::setRotation(F32 theta) 410S32 LLTextureEntry::setRotation(F32 theta)
283{ 411{
284 if (mRotation != theta) 412 if (mRotation != theta)
@@ -286,7 +414,7 @@ S32 LLTextureEntry::setRotation(F32 theta)
286 mRotation = theta; 414 mRotation = theta;
287 return TEM_CHANGE_TEXTURE; 415 return TEM_CHANGE_TEXTURE;
288 } 416 }
289 return 0; 417 return TEM_CHANGE_NONE;
290} 418}
291 419
292S32 LLTextureEntry::setBumpShinyFullbright(U8 bump) 420S32 LLTextureEntry::setBumpShinyFullbright(U8 bump)
@@ -296,7 +424,7 @@ S32 LLTextureEntry::setBumpShinyFullbright(U8 bump)
296 mBump = bump; 424 mBump = bump;
297 return TEM_CHANGE_TEXTURE; 425 return TEM_CHANGE_TEXTURE;
298 } 426 }
299 return 0; 427 return TEM_CHANGE_NONE;
300} 428}
301 429
302S32 LLTextureEntry::setMediaTexGen(U8 media) 430S32 LLTextureEntry::setMediaTexGen(U8 media)
@@ -304,9 +432,21 @@ S32 LLTextureEntry::setMediaTexGen(U8 media)
304 if (mMediaFlags != media) 432 if (mMediaFlags != media)
305 { 433 {
306 mMediaFlags = media; 434 mMediaFlags = media;
307 return TEM_CHANGE_TEXTURE; 435
436 // Special code for media handling
437 if( hasMedia() && mMediaEntry == NULL)
438 {
439 mMediaEntry = new LLMediaEntry;
440 }
441 else if ( ! hasMedia() && mMediaEntry != NULL)
442 {
443 delete mMediaEntry;
444 mMediaEntry = NULL;
445 }
446
447 return TEM_CHANGE_MEDIA;
308 } 448 }
309 return 0; 449 return TEM_CHANGE_NONE;
310} 450}
311 451
312S32 LLTextureEntry::setBumpmap(U8 bump) 452S32 LLTextureEntry::setBumpmap(U8 bump)
@@ -318,7 +458,7 @@ S32 LLTextureEntry::setBumpmap(U8 bump)
318 mBump |= bump; 458 mBump |= bump;
319 return TEM_CHANGE_TEXTURE; 459 return TEM_CHANGE_TEXTURE;
320 } 460 }
321 return 0; 461 return TEM_CHANGE_NONE;
322} 462}
323 463
324S32 LLTextureEntry::setFullbright(U8 fullbright) 464S32 LLTextureEntry::setFullbright(U8 fullbright)
@@ -330,7 +470,7 @@ S32 LLTextureEntry::setFullbright(U8 fullbright)
330 mBump |= fullbright << TEM_FULLBRIGHT_SHIFT; 470 mBump |= fullbright << TEM_FULLBRIGHT_SHIFT;
331 return TEM_CHANGE_TEXTURE; 471 return TEM_CHANGE_TEXTURE;
332 } 472 }
333 return 0; 473 return TEM_CHANGE_NONE;
334} 474}
335 475
336S32 LLTextureEntry::setShiny(U8 shiny) 476S32 LLTextureEntry::setShiny(U8 shiny)
@@ -342,7 +482,7 @@ S32 LLTextureEntry::setShiny(U8 shiny)
342 mBump |= shiny << TEM_SHINY_SHIFT; 482 mBump |= shiny << TEM_SHINY_SHIFT;
343 return TEM_CHANGE_TEXTURE; 483 return TEM_CHANGE_TEXTURE;
344 } 484 }
345 return 0; 485 return TEM_CHANGE_NONE;
346} 486}
347 487
348S32 LLTextureEntry::setBumpShiny(U8 bump_shiny) 488S32 LLTextureEntry::setBumpShiny(U8 bump_shiny)
@@ -354,7 +494,7 @@ S32 LLTextureEntry::setBumpShiny(U8 bump_shiny)
354 mBump |= bump_shiny; 494 mBump |= bump_shiny;
355 return TEM_CHANGE_TEXTURE; 495 return TEM_CHANGE_TEXTURE;
356 } 496 }
357 return 0; 497 return TEM_CHANGE_NONE;
358} 498}
359 499
360S32 LLTextureEntry::setMediaFlags(U8 media_flags) 500S32 LLTextureEntry::setMediaFlags(U8 media_flags)
@@ -364,9 +504,21 @@ S32 LLTextureEntry::setMediaFlags(U8 media_flags)
364 { 504 {
365 mMediaFlags &= ~TEM_MEDIA_MASK; 505 mMediaFlags &= ~TEM_MEDIA_MASK;
366 mMediaFlags |= media_flags; 506 mMediaFlags |= media_flags;
367 return TEM_CHANGE_TEXTURE; 507
508 // Special code for media handling
509 if( hasMedia() && mMediaEntry == NULL)
510 {
511 mMediaEntry = new LLMediaEntry;
512 }
513 else if ( ! hasMedia() && mMediaEntry != NULL)
514 {
515 delete mMediaEntry;
516 mMediaEntry = NULL;
517 }
518
519 return TEM_CHANGE_MEDIA;
368 } 520 }
369 return 0; 521 return TEM_CHANGE_NONE;
370} 522}
371 523
372S32 LLTextureEntry::setTexGen(U8 tex_gen) 524S32 LLTextureEntry::setTexGen(U8 tex_gen)
@@ -378,7 +530,7 @@ S32 LLTextureEntry::setTexGen(U8 tex_gen)
378 mMediaFlags |= tex_gen; 530 mMediaFlags |= tex_gen;
379 return TEM_CHANGE_TEXTURE; 531 return TEM_CHANGE_TEXTURE;
380 } 532 }
381 return 0; 533 return TEM_CHANGE_NONE;
382} 534}
383 535
384S32 LLTextureEntry::setGlow(F32 glow) 536S32 LLTextureEntry::setGlow(F32 glow)
@@ -388,5 +540,115 @@ S32 LLTextureEntry::setGlow(F32 glow)
388 mGlow = glow; 540 mGlow = glow;
389 return TEM_CHANGE_TEXTURE; 541 return TEM_CHANGE_TEXTURE;
390 } 542 }
391 return 0; 543 return TEM_CHANGE_NONE;
544}
545
546void LLTextureEntry::setMediaData(const LLMediaEntry &media_entry)
547{
548 mMediaFlags |= MF_HAS_MEDIA;
549 if (NULL != mMediaEntry)
550 {
551 delete mMediaEntry;
552 }
553 mMediaEntry = new LLMediaEntry(media_entry);
554}
555
556bool LLTextureEntry::updateMediaData(const LLSD& media_data)
557{
558 if (media_data.isUndefined())
559 {
560 // clear the media data
561 clearMediaData();
562 return false;
563 }
564 else {
565 mMediaFlags |= MF_HAS_MEDIA;
566 if (mMediaEntry == NULL)
567 {
568 mMediaEntry = new LLMediaEntry;
569 }
570 // *NOTE: this will *clobber* all of the fields in mMediaEntry
571 // with whatever fields are present (or not present) in media_data!
572 mMediaEntry->fromLLSD(media_data);
573 return true;
574 }
575}
576
577void LLTextureEntry::clearMediaData()
578{
579 mMediaFlags &= ~MF_HAS_MEDIA;
580 if (mMediaEntry != NULL) {
581 delete mMediaEntry;
582 }
583 mMediaEntry = NULL;
584}
585
586void LLTextureEntry::mergeIntoMediaData(const LLSD& media_fields)
587{
588 mMediaFlags |= MF_HAS_MEDIA;
589 if (mMediaEntry == NULL)
590 {
591 mMediaEntry = new LLMediaEntry;
592 }
593 // *NOTE: this will *merge* the data in media_fields
594 // with the data in our media entry
595 mMediaEntry->mergeFromLLSD(media_fields);
596}
597
598//static
599std::string LLTextureEntry::touchMediaVersionString(const std::string &in_version, const LLUUID &agent_id)
600{
601 // XXX TODO: make media version string binary (base64-encoded?)
602 // Media "URL" is a representation of a version and the last-touched agent
603 // x-mv:nnnnn/agent-id
604 // where "nnnnn" is version number
605 // *NOTE: not the most efficient code in the world...
606 U32 current_version = getVersionFromMediaVersionString(in_version) + 1;
607 const size_t MAX_VERSION_LEN = 10; // 2^32 fits in 10 decimal digits
608 char buf[MAX_VERSION_LEN+1];
609 snprintf(buf, (int)MAX_VERSION_LEN+1, "%0*u", (int)MAX_VERSION_LEN, current_version); // added int cast to fix warning/breakage on mac.
610 return MEDIA_VERSION_STRING_PREFIX + buf + "/" + agent_id.asString();
611}
612
613//static
614U32 LLTextureEntry::getVersionFromMediaVersionString(const std::string &version_string)
615{
616 U32 version = 0;
617 if (!version_string.empty())
618 {
619 size_t found = version_string.find(MEDIA_VERSION_STRING_PREFIX);
620 if (found != std::string::npos)
621 {
622 found = version_string.find_first_of("/", found);
623 std::string v = version_string.substr(MEDIA_VERSION_STRING_PREFIX.length(), found);
624 version = strtoul(v.c_str(),NULL,10);
625 }
626 }
627 return version;
628}
629
630//static
631LLUUID LLTextureEntry::getAgentIDFromMediaVersionString(const std::string &version_string)
632{
633 LLUUID id;
634 if (!version_string.empty())
635 {
636 size_t found = version_string.find(MEDIA_VERSION_STRING_PREFIX);
637 if (found != std::string::npos)
638 {
639 found = version_string.find_first_of("/", found);
640 if (found != std::string::npos)
641 {
642 std::string v = version_string.substr(found + 1);
643 id.set(v);
644 }
645 }
646 }
647 return id;
648}
649
650//static
651bool LLTextureEntry::isMediaVersionString(const std::string &version_string)
652{
653 return std::string::npos != version_string.find(MEDIA_VERSION_STRING_PREFIX);
392} 654}