aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorArmin Weatherwax2010-06-14 12:27:35 +0200
committerArmin Weatherwax2010-09-23 15:40:23 +0200
commit791d4c2de7c0219392aeb625cf7940290dc1e79a (patch)
tree4050377f59ec8532a5d3ee5cc1202b38a1878c7a
parentport SG2.0 Mediaplugs (webkit supports flash now) (diff)
downloadmeta-impy-791d4c2de7c0219392aeb625cf7940290dc1e79a.zip
meta-impy-791d4c2de7c0219392aeb625cf7940290dc1e79a.tar.gz
meta-impy-791d4c2de7c0219392aeb625cf7940290dc1e79a.tar.bz2
meta-impy-791d4c2de7c0219392aeb625cf7940290dc1e79a.tar.xz
port llprimitive from SG2.0
-rwxr-xr-x[-rw-r--r--]linden/indra/llcommon/lllslconstants.h2
-rwxr-xr-xlinden/indra/llmath/llsdutil_math.h70
-rwxr-xr-x[-rw-r--r--]linden/indra/llprimitive/CMakeLists.txt12
-rwxr-xr-x[-rw-r--r--]linden/indra/llprimitive/llmaterialtable.cpp16
-rwxr-xr-x[-rw-r--r--]linden/indra/llprimitive/llmaterialtable.h87
-rwxr-xr-xlinden/indra/llprimitive/llmediaentry.cpp602
-rwxr-xr-xlinden/indra/llprimitive/llmediaentry.h228
-rwxr-xr-x[-rw-r--r--]linden/indra/llprimitive/llprimitive.cpp581
-rwxr-xr-x[-rw-r--r--]linden/indra/llprimitive/llprimitive.h58
-rwxr-xr-x[-rw-r--r--]linden/indra/llprimitive/llprimlinkinfo.h2
-rwxr-xr-xlinden/indra/llprimitive/llprimtexturelist.cpp424
-rwxr-xr-xlinden/indra/llprimitive/llprimtexturelist.h127
-rwxr-xr-x[-rw-r--r--]linden/indra/llprimitive/lltextureentry.cpp314
-rwxr-xr-x[-rw-r--r--]linden/indra/llprimitive/lltextureentry.h66
-rwxr-xr-xlinden/indra/llprimitive/material_codes.cpp46
-rwxr-xr-x[-rw-r--r--]linden/indra/llprimitive/material_codes.h21
-rwxr-xr-xlinden/indra/llprimitive/tests/llmediaentry_test.cpp508
-rwxr-xr-xlinden/indra/llprimitive/tests/llmessagesystem_stub.cpp53
-rwxr-xr-xlinden/indra/llprimitive/tests/llprimitive_test.cpp237
-rw-r--r--linden/indra/newview/llselectmgr.cpp2
20 files changed, 3121 insertions, 335 deletions
diff --git a/linden/indra/llcommon/lllslconstants.h b/linden/indra/llcommon/lllslconstants.h
index fc5363f..222b85d 100644..100755
--- a/linden/indra/llcommon/lllslconstants.h
+++ b/linden/indra/llcommon/lllslconstants.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * $LicenseInfo:firstyear=2006&license=viewergpl$ 6 * $LicenseInfo:firstyear=2006&license=viewergpl$
7 * 7 *
8 * Copyright (c) 2006-2009, Linden Research, Inc. 8 * Copyright (c) 2006-2010, Linden Research, Inc.
9 * 9 *
10 * Second Life Viewer Source Code 10 * Second Life Viewer Source Code
11 * The source code in this file ("Source Code") is provided by Linden Lab 11 * The source code in this file ("Source Code") is provided by Linden Lab
diff --git a/linden/indra/llmath/llsdutil_math.h b/linden/indra/llmath/llsdutil_math.h
new file mode 100755
index 0000000..5b64942
--- /dev/null
+++ b/linden/indra/llmath/llsdutil_math.h
@@ -0,0 +1,70 @@
1/**
2 * @file llsdutil_math.h
3 * @author Brad
4 * @date 2009-05-19
5 * @brief Utility classes, functions, etc, for using structured data with math classes.
6 *
7 * $LicenseInfo:firstyear=2009&license=viewergpl$
8 *
9 * Copyright (c) 2009-2010, Linden Research, Inc.
10 *
11 * Second Life Viewer Source Code
12 * The source code in this file ("Source Code") is provided by Linden Lab
13 * to you under the terms of the GNU General Public License, version 2.0
14 * ("GPL"), unless you have obtained a separate licensing agreement
15 * ("Other License"), formally executed by you and Linden Lab. Terms of
16 * the GPL can be found in doc/GPL-license.txt in this distribution, or
17 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
18 *
19 * There are special exceptions to the terms and conditions of the GPL as
20 * it is applied to this Source Code. View the full text of the exception
21 * in the file doc/FLOSS-exception.txt in this software distribution, or
22 * online at
23 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
24 *
25 * By copying, modifying or distributing this software, you acknowledge
26 * that you have read and understood your obligations described above,
27 * and agree to abide by those obligations.
28 *
29 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
30 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
31 * COMPLETENESS OR PERFORMANCE.
32 * $/LicenseInfo$
33 */
34
35#ifndef LL_LLSDUTIL_MATH_H
36#define LL_LLSDUTIL_MATH_H
37
38class LL_COMMON_API LLSD;
39
40// vector3
41class LLVector3;
42LLSD ll_sd_from_vector3(const LLVector3& vec);
43LLVector3 ll_vector3_from_sd(const LLSD& sd, S32 start_index = 0);
44
45// vector4
46class LLVector4;
47LLSD ll_sd_from_vector4(const LLVector4& vec);
48LLVector4 ll_vector4_from_sd(const LLSD& sd, S32 start_index = 0);
49
50// vector3d (double)
51class LLVector3d;
52LLSD ll_sd_from_vector3d(const LLVector3d& vec);
53LLVector3d ll_vector3d_from_sd(const LLSD& sd, S32 start_index = 0);
54
55// vector2
56class LLVector2;
57LLSD ll_sd_from_vector2(const LLVector2& vec);
58LLVector2 ll_vector2_from_sd(const LLSD& sd);
59
60// Quaternion
61class LLQuaternion;
62LLSD ll_sd_from_quaternion(const LLQuaternion& quat);
63LLQuaternion ll_quaternion_from_sd(const LLSD& sd);
64
65// color4
66class LLColor4;
67LLSD ll_sd_from_color4(const LLColor4& c);
68LLColor4 ll_color4_from_sd(const LLSD& sd);
69
70#endif // LL_LLSDUTIL_MATH_H
diff --git a/linden/indra/llprimitive/CMakeLists.txt b/linden/indra/llprimitive/CMakeLists.txt
index 5dc4c70..e7ee811 100644..100755
--- a/linden/indra/llprimitive/CMakeLists.txt
+++ b/linden/indra/llprimitive/CMakeLists.txt
@@ -17,12 +17,15 @@ include_directories(
17 17
18set(llprimitive_SOURCE_FILES 18set(llprimitive_SOURCE_FILES
19 llmaterialtable.cpp 19 llmaterialtable.cpp
20 llmediaentry.cpp
20 llprimitive.cpp 21 llprimitive.cpp
22 llprimtexturelist.cpp
21 lltextureanim.cpp 23 lltextureanim.cpp
22 lltextureentry.cpp 24 lltextureentry.cpp
23 lltreeparams.cpp 25 lltreeparams.cpp
24 llvolumemessage.cpp 26 llvolumemessage.cpp
25 llvolumexml.cpp 27 llvolumexml.cpp
28 material_codes.cpp
26 ) 29 )
27 30
28set(llprimitive_HEADER_FILES 31set(llprimitive_HEADER_FILES
@@ -30,7 +33,9 @@ set(llprimitive_HEADER_FILES
30 33
31 legacy_object_types.h 34 legacy_object_types.h
32 llmaterialtable.h 35 llmaterialtable.h
36 llmediaentry.h
33 llprimitive.h 37 llprimitive.h
38 llprimtexturelist.h
34 lltextureanim.h 39 lltextureanim.h
35 lltextureentry.h 40 lltextureentry.h
36 lltreeparams.h 41 lltreeparams.h
@@ -47,3 +52,10 @@ set_source_files_properties(${llprimitive_HEADER_FILES}
47list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES}) 52list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES})
48 53
49add_library (llprimitive ${llprimitive_SOURCE_FILES}) 54add_library (llprimitive ${llprimitive_SOURCE_FILES})
55
56#add unit tests
57INCLUDE(LLAddBuildTest)
58SET(llprimitive_TEST_SOURCE_FILES
59 llmediaentry.cpp
60 )
61#LL_ADD_PROJECT_UNIT_TESTS(llprimitive "${llprimitive_TEST_SOURCE_FILES}")
diff --git a/linden/indra/llprimitive/llmaterialtable.cpp b/linden/indra/llprimitive/llmaterialtable.cpp
index 4c22203..f06bfe8 100644..100755
--- a/linden/indra/llprimitive/llmaterialtable.cpp
+++ b/linden/indra/llprimitive/llmaterialtable.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
@@ -92,6 +92,9 @@ F32 const LLMaterialTable::DEFAULT_FRICTION = 0.5f;
92F32 const LLMaterialTable::DEFAULT_RESTITUTION = 0.4f; 92F32 const LLMaterialTable::DEFAULT_RESTITUTION = 0.4f;
93 93
94LLMaterialTable::LLMaterialTable() 94LLMaterialTable::LLMaterialTable()
95 : mCollisionSoundMatrix(NULL),
96 mSlidingSoundMatrix(NULL),
97 mRollingSoundMatrix(NULL)
95{ 98{
96} 99}
97 100
@@ -124,6 +127,17 @@ LLMaterialTable::~LLMaterialTable()
124 mMaterialInfoList.clear(); 127 mMaterialInfoList.clear();
125} 128}
126 129
130void LLMaterialTable::initTableTransNames(std::map<std::string, std::string> namemap)
131{
132 for (info_list_t::iterator iter = mMaterialInfoList.begin();
133 iter != mMaterialInfoList.end(); ++iter)
134 {
135 LLMaterialInfo *infop = *iter;
136 std::string name = infop->mName;
137 infop->mName = namemap[name];
138 }
139}
140
127void LLMaterialTable::initBasicTable() 141void LLMaterialTable::initBasicTable()
128{ 142{
129 // *TODO: Translate 143 // *TODO: Translate
diff --git a/linden/indra/llprimitive/llmaterialtable.h b/linden/indra/llprimitive/llmaterialtable.h
index ca9017a..7950c40 100644..100755
--- a/linden/indra/llprimitive/llmaterialtable.h
+++ b/linden/indra/llprimitive/llmaterialtable.h
@@ -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
@@ -38,6 +38,8 @@
38 38
39#include <list> 39#include <list>
40 40
41class LLMaterialInfo;
42
41const U32 LLMATERIAL_INFO_NAME_LENGTH = 256; 43const U32 LLMATERIAL_INFO_NAME_LENGTH = 256;
42 44
43// We've moved toward more reasonable mass values for the Havok4 engine. 45// We've moved toward more reasonable mass values for the Havok4 engine.
@@ -64,45 +66,6 @@ const F32 LEGACY_DEFAULT_OBJECT_DENSITY = 10.0f;
64const F32 DEFAULT_AVATAR_DENSITY = 445.3f; // was 444.24f; 66const F32 DEFAULT_AVATAR_DENSITY = 445.3f; // was 444.24f;
65 67
66 68
67class LLMaterialInfo
68{
69public:
70 U8 mMCode;
71 std::string mName;
72 LLUUID mDefaultTextureID;
73 LLUUID mShatterSoundID;
74 F32 mDensity; // kg/m^3
75 F32 mFriction;
76 F32 mRestitution;
77
78 // damage and energy constants
79 F32 mHPModifier; // modifier on mass based HP total
80 F32 mDamageModifier; // modifier on KE based damage
81 F32 mEPModifier; // modifier on mass based EP total
82
83 LLMaterialInfo(U8 mcode, const std::string& name, const LLUUID &uuid)
84 {
85 init(mcode,name,uuid);
86 };
87
88 void init(U8 mcode, const std::string& name, const LLUUID &uuid)
89 {
90 mDensity = 1000.f; // default to 1000.0 (water)
91 mHPModifier = 1.f;
92 mDamageModifier = 1.f;
93 mEPModifier = 1.f;
94
95 mMCode = mcode;
96 mName = name;
97 mDefaultTextureID = uuid;
98 };
99
100 ~LLMaterialInfo()
101 {
102 };
103
104};
105
106class LLMaterialTable 69class LLMaterialTable
107{ 70{
108public: 71public:
@@ -147,6 +110,8 @@ public:
147 110
148 void initBasicTable(); 111 void initBasicTable();
149 112
113 void initTableTransNames(std::map<std::string, std::string> namemap);
114
150 BOOL add(U8 mcode, const std::string& name, const LLUUID &uuid); 115 BOOL add(U8 mcode, const std::string& name, const LLUUID &uuid);
151 BOOL addCollisionSound(U8 mcode, U8 mcode2, const LLUUID &uuid); 116 BOOL addCollisionSound(U8 mcode, U8 mcode2, const LLUUID &uuid);
152 BOOL addSlidingSound(U8 mcode, U8 mcode2, const LLUUID &uuid); 117 BOOL addSlidingSound(U8 mcode, U8 mcode2, const LLUUID &uuid);
@@ -183,5 +148,47 @@ public:
183 static LLMaterialTable basic; 148 static LLMaterialTable basic;
184}; 149};
185 150
151
152class LLMaterialInfo
153{
154public:
155 U8 mMCode;
156 std::string mName;
157 LLUUID mDefaultTextureID;
158 LLUUID mShatterSoundID;
159 F32 mDensity; // kg/m^3
160 F32 mFriction;
161 F32 mRestitution;
162
163 // damage and energy constants
164 F32 mHPModifier; // modifier on mass based HP total
165 F32 mDamageModifier; // modifier on KE based damage
166 F32 mEPModifier; // modifier on mass based EP total
167
168 LLMaterialInfo(U8 mcode, const std::string& name, const LLUUID &uuid)
169 {
170 init(mcode,name,uuid);
171 };
172
173 void init(U8 mcode, const std::string& name, const LLUUID &uuid)
174 {
175 mDensity = 1000.f; // default to 1000.0 (water)
176 mFriction = LLMaterialTable::DEFAULT_FRICTION;
177 mRestitution = LLMaterialTable::DEFAULT_RESTITUTION;
178 mHPModifier = 1.f;
179 mDamageModifier = 1.f;
180 mEPModifier = 1.f;
181
182 mMCode = mcode;
183 mName = name;
184 mDefaultTextureID = uuid;
185 };
186
187 ~LLMaterialInfo()
188 {
189 };
190
191};
192
186#endif 193#endif
187 194
diff --git a/linden/indra/llprimitive/llmediaentry.cpp b/linden/indra/llprimitive/llmediaentry.cpp
new file mode 100755
index 0000000..e4b31e2
--- /dev/null
+++ b/linden/indra/llprimitive/llmediaentry.cpp
@@ -0,0 +1,602 @@
1/**
2 * @file llmediaentry.cpp
3 * @brief This is a single instance of media data related to the face of a prim
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
33#include "linden_common.h"
34#include "llmediaentry.h"
35#include "lllslconstants.h"
36
37#include <boost/regex.hpp>
38
39// LLSD key defines
40// DO NOT REORDER OR REMOVE THESE!
41
42// Some LLSD keys. Do not change!
43#define MEDIA_ALT_IMAGE_ENABLE_KEY_STR "alt_image_enable"
44#define MEDIA_CONTROLS_KEY_STR "controls"
45#define MEDIA_CURRENT_URL_KEY_STR "current_url"
46#define MEDIA_HOME_URL_KEY_STR "home_url"
47#define MEDIA_AUTO_LOOP_KEY_STR "auto_loop"
48#define MEDIA_AUTO_PLAY_KEY_STR "auto_play"
49#define MEDIA_AUTO_SCALE_KEY_STR "auto_scale"
50#define MEDIA_AUTO_ZOOM_KEY_STR "auto_zoom"
51#define MEDIA_FIRST_CLICK_INTERACT_KEY_STR "first_click_interact"
52#define MEDIA_WIDTH_PIXELS_KEY_STR "width_pixels"
53#define MEDIA_HEIGHT_PIXELS_KEY_STR "height_pixels"
54
55// "security" fields
56#define MEDIA_WHITELIST_ENABLE_KEY_STR "whitelist_enable"
57#define MEDIA_WHITELIST_KEY_STR "whitelist"
58
59// "permissions" fields
60#define MEDIA_PERMS_INTERACT_KEY_STR "perms_interact"
61#define MEDIA_PERMS_CONTROL_KEY_STR "perms_control"
62
63// "general" fields
64const char* LLMediaEntry::ALT_IMAGE_ENABLE_KEY = MEDIA_ALT_IMAGE_ENABLE_KEY_STR;
65const char* LLMediaEntry::CONTROLS_KEY = MEDIA_CONTROLS_KEY_STR;
66const char* LLMediaEntry::CURRENT_URL_KEY = MEDIA_CURRENT_URL_KEY_STR;
67const char* LLMediaEntry::HOME_URL_KEY = MEDIA_HOME_URL_KEY_STR;
68const char* LLMediaEntry::AUTO_LOOP_KEY = MEDIA_AUTO_LOOP_KEY_STR;
69const char* LLMediaEntry::AUTO_PLAY_KEY = MEDIA_AUTO_PLAY_KEY_STR;
70const char* LLMediaEntry::AUTO_SCALE_KEY = MEDIA_AUTO_SCALE_KEY_STR;
71const char* LLMediaEntry::AUTO_ZOOM_KEY = MEDIA_AUTO_ZOOM_KEY_STR;
72const char* LLMediaEntry::FIRST_CLICK_INTERACT_KEY = MEDIA_FIRST_CLICK_INTERACT_KEY_STR;
73const char* LLMediaEntry::WIDTH_PIXELS_KEY = MEDIA_WIDTH_PIXELS_KEY_STR;
74const char* LLMediaEntry::HEIGHT_PIXELS_KEY = MEDIA_HEIGHT_PIXELS_KEY_STR;
75
76// "security" fields
77const char* LLMediaEntry::WHITELIST_ENABLE_KEY = MEDIA_WHITELIST_ENABLE_KEY_STR;
78const char* LLMediaEntry::WHITELIST_KEY = MEDIA_WHITELIST_KEY_STR;
79
80// "permissions" fields
81const char* LLMediaEntry::PERMS_INTERACT_KEY = MEDIA_PERMS_INTERACT_KEY_STR;
82const char* LLMediaEntry::PERMS_CONTROL_KEY = MEDIA_PERMS_CONTROL_KEY_STR;
83
84#define DEFAULT_URL_PREFIX "http://"
85
86// Constructor(s)
87LLMediaEntry::LLMediaEntry() :
88 mAltImageEnable(false),
89 mControls(STANDARD),
90 mCurrentURL(""),
91 mHomeURL(""),
92 mAutoLoop(false),
93 mAutoPlay(false),
94 mAutoScale(false),
95 mAutoZoom(false),
96 mFirstClickInteract(false),
97 mWidthPixels(0),
98 mHeightPixels(0),
99 mWhiteListEnable(false),
100 // mWhiteList
101 mPermsInteract(PERM_ALL),
102 mPermsControl(PERM_ALL),
103 mMediaIDp(NULL)
104{
105}
106
107LLMediaEntry::LLMediaEntry(const LLMediaEntry &rhs) :
108 mMediaIDp(NULL)
109{
110 // "general" fields
111 mAltImageEnable = rhs.mAltImageEnable;
112 mControls = rhs.mControls;
113 mCurrentURL = rhs.mCurrentURL;
114 mHomeURL = rhs.mHomeURL;
115 mAutoLoop = rhs.mAutoLoop;
116 mAutoPlay = rhs.mAutoPlay;
117 mAutoScale = rhs.mAutoScale;
118 mAutoZoom = rhs.mAutoZoom;
119 mFirstClickInteract = rhs.mFirstClickInteract;
120 mWidthPixels = rhs.mWidthPixels;
121 mHeightPixels = rhs.mHeightPixels;
122
123 // "security" fields
124 mWhiteListEnable = rhs.mWhiteListEnable;
125 mWhiteList = rhs.mWhiteList;
126
127 // "permissions" fields
128 mPermsInteract = rhs.mPermsInteract;
129 mPermsControl = rhs.mPermsControl;
130}
131
132LLMediaEntry::~LLMediaEntry()
133{
134 if (NULL != mMediaIDp)
135 {
136 delete mMediaIDp;
137 }
138}
139
140LLSD LLMediaEntry::asLLSD() const
141{
142 LLSD sd;
143 asLLSD(sd);
144 return sd;
145}
146
147//
148// LLSD functions
149//
150void LLMediaEntry::asLLSD(LLSD& sd) const
151{
152 // "general" fields
153 sd[ALT_IMAGE_ENABLE_KEY] = mAltImageEnable;
154 sd[CONTROLS_KEY] = (LLSD::Integer)mControls;
155 sd[CURRENT_URL_KEY] = mCurrentURL;
156 sd[HOME_URL_KEY] = mHomeURL;
157 sd[AUTO_LOOP_KEY] = mAutoLoop;
158 sd[AUTO_PLAY_KEY] = mAutoPlay;
159 sd[AUTO_SCALE_KEY] = mAutoScale;
160 sd[AUTO_ZOOM_KEY] = mAutoZoom;
161 sd[FIRST_CLICK_INTERACT_KEY] = mFirstClickInteract;
162 sd[WIDTH_PIXELS_KEY] = mWidthPixels;
163 sd[HEIGHT_PIXELS_KEY] = mHeightPixels;
164
165 // "security" fields
166 sd[WHITELIST_ENABLE_KEY] = mWhiteListEnable;
167 sd.erase(WHITELIST_KEY);
168 for (U32 i=0; i<mWhiteList.size(); i++)
169 {
170 sd[WHITELIST_KEY].append(mWhiteList[i]);
171 }
172
173 // "permissions" fields
174 sd[PERMS_INTERACT_KEY] = mPermsInteract;
175 sd[PERMS_CONTROL_KEY] = mPermsControl;
176}
177
178// static
179bool LLMediaEntry::checkLLSD(const LLSD& sd)
180{
181 if (sd.isUndefined()) return true;
182 LLMediaEntry temp;
183 return temp.fromLLSDInternal(sd, true);
184}
185
186void LLMediaEntry::fromLLSD(const LLSD& sd)
187{
188 (void)fromLLSDInternal(sd, true);
189}
190
191void LLMediaEntry::mergeFromLLSD(const LLSD& sd)
192{
193 (void)fromLLSDInternal(sd, false);
194}
195
196// *NOTE: returns true if NO failures to set occurred, false otherwise.
197// However, be aware that if a failure to set does occur, it does
198// not stop setting fields from the LLSD!
199bool LLMediaEntry::fromLLSDInternal(const LLSD& sd, bool overwrite)
200{
201 // *HACK: we sort of cheat here and assume that status is a
202 // bit field. We "or" into status and instead of returning
203 // it, we return whether it finishes off as LSL_STATUS_OK or not.
204 U32 status = LSL_STATUS_OK;
205
206 // "general" fields
207 if ( overwrite || sd.has(ALT_IMAGE_ENABLE_KEY) )
208 {
209 status |= setAltImageEnable( sd[ALT_IMAGE_ENABLE_KEY] );
210 }
211 if ( overwrite || sd.has(CONTROLS_KEY) )
212 {
213 status |= setControls( (MediaControls)(LLSD::Integer)sd[CONTROLS_KEY] );
214 }
215 if ( overwrite || sd.has(CURRENT_URL_KEY) )
216 {
217 // Don't check whitelist
218 status |= setCurrentURLInternal( sd[CURRENT_URL_KEY], false );
219 }
220 if ( overwrite || sd.has(HOME_URL_KEY) )
221 {
222 status |= setHomeURL( sd[HOME_URL_KEY] );
223 }
224 if ( overwrite || sd.has(AUTO_LOOP_KEY) )
225 {
226 status |= setAutoLoop( sd[AUTO_LOOP_KEY] );
227 }
228 if ( overwrite || sd.has(AUTO_PLAY_KEY) )
229 {
230 status |= setAutoPlay( sd[AUTO_PLAY_KEY] );
231 }
232 if ( overwrite || sd.has(AUTO_SCALE_KEY) )
233 {
234 status |= setAutoScale( sd[AUTO_SCALE_KEY] );
235 }
236 if ( overwrite || sd.has(AUTO_ZOOM_KEY) )
237 {
238 status |= setAutoZoom( sd[AUTO_ZOOM_KEY] );
239 }
240 if ( overwrite || sd.has(FIRST_CLICK_INTERACT_KEY) )
241 {
242 status |= setFirstClickInteract( sd[FIRST_CLICK_INTERACT_KEY] );
243 }
244 if ( overwrite || sd.has(WIDTH_PIXELS_KEY) )
245 {
246 status |= setWidthPixels( (LLSD::Integer)sd[WIDTH_PIXELS_KEY] );
247 }
248 if ( overwrite || sd.has(HEIGHT_PIXELS_KEY) )
249 {
250 status |= setHeightPixels( (LLSD::Integer)sd[HEIGHT_PIXELS_KEY] );
251 }
252
253 // "security" fields
254 if ( overwrite || sd.has(WHITELIST_ENABLE_KEY) )
255 {
256 status |= setWhiteListEnable( sd[WHITELIST_ENABLE_KEY] );
257 }
258 if ( overwrite || sd.has(WHITELIST_KEY) )
259 {
260 status |= setWhiteList( sd[WHITELIST_KEY] );
261 }
262
263 // "permissions" fields
264 if ( overwrite || sd.has(PERMS_INTERACT_KEY) )
265 {
266 status |= setPermsInteract( 0xff & (LLSD::Integer)sd[PERMS_INTERACT_KEY] );
267 }
268 if ( overwrite || sd.has(PERMS_CONTROL_KEY) )
269 {
270 status |= setPermsControl( 0xff & (LLSD::Integer)sd[PERMS_CONTROL_KEY] );
271 }
272
273 return LSL_STATUS_OK == status;
274}
275
276LLMediaEntry& LLMediaEntry::operator=(const LLMediaEntry &rhs)
277{
278 if (this != &rhs)
279 {
280 // "general" fields
281 mAltImageEnable = rhs.mAltImageEnable;
282 mControls = rhs.mControls;
283 mCurrentURL = rhs.mCurrentURL;
284 mHomeURL = rhs.mHomeURL;
285 mAutoLoop = rhs.mAutoLoop;
286 mAutoPlay = rhs.mAutoPlay;
287 mAutoScale = rhs.mAutoScale;
288 mAutoZoom = rhs.mAutoZoom;
289 mFirstClickInteract = rhs.mFirstClickInteract;
290 mWidthPixels = rhs.mWidthPixels;
291 mHeightPixels = rhs.mHeightPixels;
292
293 // "security" fields
294 mWhiteListEnable = rhs.mWhiteListEnable;
295 mWhiteList = rhs.mWhiteList;
296
297 // "permissions" fields
298 mPermsInteract = rhs.mPermsInteract;
299 mPermsControl = rhs.mPermsControl;
300 }
301
302 return *this;
303}
304
305bool LLMediaEntry::operator==(const LLMediaEntry &rhs) const
306{
307 return (
308 // "general" fields
309 mAltImageEnable == rhs.mAltImageEnable &&
310 mControls == rhs.mControls &&
311 mCurrentURL == rhs.mCurrentURL &&
312 mHomeURL == rhs.mHomeURL &&
313 mAutoLoop == rhs.mAutoLoop &&
314 mAutoPlay == rhs.mAutoPlay &&
315 mAutoScale == rhs.mAutoScale &&
316 mAutoZoom == rhs.mAutoZoom &&
317 mFirstClickInteract == rhs.mFirstClickInteract &&
318 mWidthPixels == rhs.mWidthPixels &&
319 mHeightPixels == rhs.mHeightPixels &&
320
321 // "security" fields
322 mWhiteListEnable == rhs.mWhiteListEnable &&
323 mWhiteList == rhs.mWhiteList &&
324
325 // "permissions" fields
326 mPermsInteract == rhs.mPermsInteract &&
327 mPermsControl == rhs.mPermsControl
328
329 );
330}
331
332bool LLMediaEntry::operator!=(const LLMediaEntry &rhs) const
333{
334 return (
335 // "general" fields
336 mAltImageEnable != rhs.mAltImageEnable ||
337 mControls != rhs.mControls ||
338 mCurrentURL != rhs.mCurrentURL ||
339 mHomeURL != rhs.mHomeURL ||
340 mAutoLoop != rhs.mAutoLoop ||
341 mAutoPlay != rhs.mAutoPlay ||
342 mAutoScale != rhs.mAutoScale ||
343 mAutoZoom != rhs.mAutoZoom ||
344 mFirstClickInteract != rhs.mFirstClickInteract ||
345 mWidthPixels != rhs.mWidthPixels ||
346 mHeightPixels != rhs.mHeightPixels ||
347
348 // "security" fields
349 mWhiteListEnable != rhs.mWhiteListEnable ||
350 mWhiteList != rhs.mWhiteList ||
351
352 // "permissions" fields
353 mPermsInteract != rhs.mPermsInteract ||
354 mPermsControl != rhs.mPermsControl
355
356 );
357}
358
359U32 LLMediaEntry::setWhiteList( const std::vector<std::string> &whitelist )
360{
361 // *NOTE: This code is VERY similar to the setWhitelist below.
362 // IF YOU CHANGE THIS IMPLEMENTATION, BE SURE TO CHANGE THE OTHER!
363 U32 size = 0;
364 U32 count = 0;
365 // First count to make sure the size constraint is not violated
366 std::vector<std::string>::const_iterator iter = whitelist.begin();
367 std::vector<std::string>::const_iterator end = whitelist.end();
368 for ( ; iter < end; ++iter)
369 {
370 const std::string &entry = (*iter);
371 size += entry.length() + 1; // Include one for \0
372 count ++;
373 if (size > MAX_WHITELIST_SIZE || count > MAX_WHITELIST_COUNT)
374 {
375 return LSL_STATUS_BOUNDS_ERROR;
376 }
377 }
378 // Next clear the vector
379 mWhiteList.clear();
380 // Then re-iterate and copy entries
381 iter = whitelist.begin();
382 for ( ; iter < end; ++iter)
383 {
384 const std::string &entry = (*iter);
385 mWhiteList.push_back(entry);
386 }
387 return LSL_STATUS_OK;
388}
389
390U32 LLMediaEntry::setWhiteList( const LLSD &whitelist )
391{
392 // If whitelist is undef, the whitelist is cleared
393 if (whitelist.isUndefined())
394 {
395 mWhiteList.clear();
396 return LSL_STATUS_OK;
397 }
398
399 // However, if the whitelist is an empty array, erase it.
400 if (whitelist.isArray())
401 {
402 // *NOTE: This code is VERY similar to the setWhitelist above.
403 // IF YOU CHANGE THIS IMPLEMENTATION, BE SURE TO CHANGE THE OTHER!
404 U32 size = 0;
405 U32 count = 0;
406 // First check to make sure the size and count constraints are not violated
407 LLSD::array_const_iterator iter = whitelist.beginArray();
408 LLSD::array_const_iterator end = whitelist.endArray();
409 for ( ; iter < end; ++iter)
410 {
411 const std::string &entry = (*iter).asString();
412 size += entry.length() + 1; // Include one for \0
413 count ++;
414 if (size > MAX_WHITELIST_SIZE || count > MAX_WHITELIST_COUNT)
415 {
416 return LSL_STATUS_BOUNDS_ERROR;
417 }
418 }
419 // Next clear the vector
420 mWhiteList.clear();
421 // Then re-iterate and copy entries
422 iter = whitelist.beginArray();
423 for ( ; iter < end; ++iter)
424 {
425 const std::string &entry = (*iter).asString();
426 mWhiteList.push_back(entry);
427 }
428 return LSL_STATUS_OK;
429 }
430 else
431 {
432 return LSL_STATUS_MALFORMED_PARAMS;
433 }
434}
435
436
437static void prefix_with(std::string &str, const char *chars, const char *prefix)
438{
439 // Given string 'str', prefix all instances of any character in 'chars'
440 // with 'prefix'
441 size_t found = str.find_first_of(chars);
442 size_t prefix_len = strlen(prefix);
443 while (found != std::string::npos)
444 {
445 str.insert(found, prefix, prefix_len);
446 found = str.find_first_of(chars, found+prefix_len+1);
447 }
448}
449
450static bool pattern_match(const std::string &candidate_str, const std::string &pattern)
451{
452 // If the pattern is empty, it matches
453 if (pattern.empty()) return true;
454
455 // 'pattern' is a glob pattern, we only accept '*' chars
456 // copy it
457 std::string expression = pattern;
458
459 // Escape perl's regexp chars with a backslash, except all "*" chars
460 prefix_with(expression, ".[{()\\+?|^$", "\\");
461 prefix_with(expression, "*", ".");
462
463 // case-insensitive matching:
464 boost::regex regexp(expression, boost::regex::perl|boost::regex::icase);
465 return boost::regex_match(candidate_str, regexp);
466}
467
468bool LLMediaEntry::checkCandidateUrl(const std::string& url) const
469{
470 if (getWhiteListEnable())
471 {
472 return checkUrlAgainstWhitelist(url, getWhiteList());
473 }
474 else
475 {
476 return true;
477 }
478}
479
480// static
481bool LLMediaEntry::checkUrlAgainstWhitelist(const std::string& url,
482 const std::vector<std::string> &whitelist)
483{
484 bool passes = true;
485 // *NOTE: no entries? Don't check
486 if (whitelist.size() > 0)
487 {
488 passes = false;
489
490 // Case insensitive: the reason why we toUpper both this and the
491 // filter
492 std::string candidate_url = url;
493 // Use lluri to see if there is a path part in the candidate URL. No path? Assume "/"
494 LLURI candidate_uri(candidate_url);
495 std::vector<std::string>::const_iterator iter = whitelist.begin();
496 std::vector<std::string>::const_iterator end = whitelist.end();
497 for ( ; iter < end; ++iter )
498 {
499 std::string filter = *iter;
500
501 LLURI filter_uri(filter);
502 bool scheme_passes = pattern_match( candidate_uri.scheme(), filter_uri.scheme() );
503 if (filter_uri.scheme().empty())
504 {
505 filter_uri = LLURI(DEFAULT_URL_PREFIX + filter);
506 }
507 bool authority_passes = pattern_match( candidate_uri.authority(), filter_uri.authority() );
508 bool path_passes = pattern_match( candidate_uri.escapedPath(), filter_uri.escapedPath() );
509
510 if (scheme_passes && authority_passes && path_passes)
511 {
512 passes = true;
513 break;
514 }
515 }
516 }
517 return passes;
518}
519
520U32 LLMediaEntry::setStringFieldWithLimit( std::string &field, const std::string &value, U32 limit )
521{
522 if ( value.length() > limit )
523 {
524 return LSL_STATUS_BOUNDS_ERROR;
525 }
526 else
527 {
528 field = value;
529 return LSL_STATUS_OK;
530 }
531}
532
533U32 LLMediaEntry::setControls(LLMediaEntry::MediaControls controls)
534{
535 if (controls == STANDARD ||
536 controls == MINI)
537 {
538 mControls = controls;
539 return LSL_STATUS_OK;
540 }
541 return LSL_STATUS_BOUNDS_ERROR;
542}
543
544U32 LLMediaEntry::setPermsInteract( U8 val )
545{
546 mPermsInteract = val & PERM_MASK;
547 return LSL_STATUS_OK;
548}
549
550U32 LLMediaEntry::setPermsControl( U8 val )
551{
552 mPermsControl = val & PERM_MASK;
553 return LSL_STATUS_OK;
554}
555
556U32 LLMediaEntry::setCurrentURL(const std::string& current_url)
557{
558 return setCurrentURLInternal( current_url, true );
559}
560
561U32 LLMediaEntry::setCurrentURLInternal(const std::string& current_url, bool check_whitelist)
562{
563 if ( ! check_whitelist || checkCandidateUrl(current_url))
564 {
565 return setStringFieldWithLimit( mCurrentURL, current_url, MAX_URL_LENGTH );
566 }
567 else
568 {
569 return LSL_STATUS_WHITELIST_FAILED;
570 }
571}
572
573U32 LLMediaEntry::setHomeURL(const std::string& home_url)
574{
575 return setStringFieldWithLimit( mHomeURL, home_url, MAX_URL_LENGTH );
576}
577
578U32 LLMediaEntry::setWidthPixels(U16 width)
579{
580 if (width > MAX_WIDTH_PIXELS) return LSL_STATUS_BOUNDS_ERROR;
581 mWidthPixels = width;
582 return LSL_STATUS_OK;
583}
584
585U32 LLMediaEntry::setHeightPixels(U16 height)
586{
587 if (height > MAX_HEIGHT_PIXELS) return LSL_STATUS_BOUNDS_ERROR;
588 mHeightPixels = height;
589 return LSL_STATUS_OK;
590}
591
592const LLUUID &LLMediaEntry::getMediaID() const
593{
594 // Lazily generate media ID
595 if (NULL == mMediaIDp)
596 {
597 mMediaIDp = new LLUUID();
598 mMediaIDp->generate();
599 }
600 return *mMediaIDp;
601}
602
diff --git a/linden/indra/llprimitive/llmediaentry.h b/linden/indra/llprimitive/llmediaentry.h
new file mode 100755
index 0000000..ca52e6e
--- /dev/null
+++ b/linden/indra/llprimitive/llmediaentry.h
@@ -0,0 +1,228 @@
1/**
2 * @file llmediaentry.h
3 * @brief This is a single instance of media data related to the face of a prim
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
33#ifndef LL_LLMEDIAENTRY_H
34#define LL_LLMEDIAENTRY_H
35
36#include "llsd.h"
37#include "llstring.h"
38
39// For return values of set*
40#include "lllslconstants.h"
41
42class LLMediaEntry
43{
44public:
45 enum MediaControls {
46 STANDARD = 0,
47 MINI
48 };
49
50 // Constructors
51 LLMediaEntry();
52 LLMediaEntry(const LLMediaEntry &rhs);
53
54 LLMediaEntry &operator=(const LLMediaEntry &rhs);
55 virtual ~LLMediaEntry();
56
57 bool operator==(const LLMediaEntry &rhs) const;
58 bool operator!=(const LLMediaEntry &rhs) const;
59
60 // Render as LLSD
61 LLSD asLLSD() const;
62 void asLLSD(LLSD& sd) const;
63 operator LLSD() const { return asLLSD(); }
64 // Returns false iff the given LLSD contains fields that violate any bounds
65 // limits.
66 static bool checkLLSD(const LLSD& sd);
67 // This doesn't merge, it overwrites the data, so will use
68 // LLSD defaults if need be. Note: does not check limits!
69 // Use checkLLSD() above first to ensure the LLSD is valid.
70 void fromLLSD(const LLSD& sd);
71 // This merges data from the incoming LLSD into our fields.
72 // Note that it also does NOT check limits! Use checkLLSD() above first.
73 void mergeFromLLSD(const LLSD& sd);
74
75 // "general" fields
76 bool getAltImageEnable() const { return mAltImageEnable; }
77 MediaControls getControls() const { return mControls; }
78 std::string getCurrentURL() const { return mCurrentURL; }
79 std::string getHomeURL() const { return mHomeURL; }
80 bool getAutoLoop() const { return mAutoLoop; }
81 bool getAutoPlay() const { return mAutoPlay; }
82 bool getAutoScale() const { return mAutoScale; }
83 bool getAutoZoom() const { return mAutoZoom; }
84 bool getFirstClickInteract() const { return mFirstClickInteract; }
85 U16 getWidthPixels() const { return mWidthPixels; }
86 U16 getHeightPixels() const { return mHeightPixels; }
87
88 // "security" fields
89 bool getWhiteListEnable() const { return mWhiteListEnable; }
90 const std::vector<std::string> &getWhiteList() const { return mWhiteList; }
91
92 // "permissions" fields
93 U8 getPermsInteract() const { return mPermsInteract; }
94 U8 getPermsControl() const { return mPermsControl; }
95
96 // Setters. Those that return a U32 return a status error code
97 // See lllslconstants.h
98
99 // "general" fields
100 U32 setAltImageEnable(bool alt_image_enable) { mAltImageEnable = alt_image_enable; return LSL_STATUS_OK; }
101 U32 setControls(MediaControls controls);
102 U32 setCurrentURL(const std::string& current_url);
103 U32 setHomeURL(const std::string& home_url);
104 U32 setAutoLoop(bool auto_loop) { mAutoLoop = auto_loop; return LSL_STATUS_OK; }
105 U32 setAutoPlay(bool auto_play) { mAutoPlay = auto_play; return LSL_STATUS_OK; }
106 U32 setAutoScale(bool auto_scale) { mAutoScale = auto_scale; return LSL_STATUS_OK; }
107 U32 setAutoZoom(bool auto_zoom) { mAutoZoom = auto_zoom; return LSL_STATUS_OK; }
108 U32 setFirstClickInteract(bool first_click) { mFirstClickInteract = first_click; return LSL_STATUS_OK; }
109 U32 setWidthPixels(U16 width);
110 U32 setHeightPixels(U16 height);
111
112 // "security" fields
113 U32 setWhiteListEnable( bool whitelist_enable ) { mWhiteListEnable = whitelist_enable; return LSL_STATUS_OK; }
114 U32 setWhiteList( const std::vector<std::string> &whitelist );
115 U32 setWhiteList( const LLSD &whitelist ); // takes an LLSD array
116
117 // "permissions" fields
118 U32 setPermsInteract( U8 val );
119 U32 setPermsControl( U8 val );
120
121 const LLUUID& getMediaID() const;
122
123 // Helper function to check a candidate URL against the whitelist
124 // Returns true iff candidate URL passes (or if there is no whitelist), false otherwise
125 bool checkCandidateUrl(const std::string& url) const;
126
127public:
128 // Static function to check a URL against a whitelist
129 // Returns true iff url passes the given whitelist
130 static bool checkUrlAgainstWhitelist(const std::string &url,
131 const std::vector<std::string> &whitelist);
132
133public:
134 // LLSD key defines
135 // "general" fields
136 static const char* ALT_IMAGE_ENABLE_KEY;
137 static const char* CONTROLS_KEY;
138 static const char* CURRENT_URL_KEY;
139 static const char* HOME_URL_KEY;
140 static const char* AUTO_LOOP_KEY;
141 static const char* AUTO_PLAY_KEY;
142 static const char* AUTO_SCALE_KEY;
143 static const char* AUTO_ZOOM_KEY;
144 static const char* FIRST_CLICK_INTERACT_KEY;
145 static const char* WIDTH_PIXELS_KEY;
146 static const char* HEIGHT_PIXELS_KEY;
147
148 // "security" fields
149 static const char* WHITELIST_ENABLE_KEY;
150 static const char* WHITELIST_KEY;
151
152 // "permissions" fields
153 static const char* PERMS_INTERACT_KEY;
154 static const char* PERMS_CONTROL_KEY;
155
156 // Field enumerations & constants
157
158 // *NOTE: DO NOT change the order of these, and do not insert values
159 // in the middle!
160 // Add values to the end, and make sure to change PARAM_MAX_ID!
161 enum Fields {
162 ALT_IMAGE_ENABLE_ID = 0,
163 CONTROLS_ID = 1,
164 CURRENT_URL_ID = 2,
165 HOME_URL_ID = 3,
166 AUTO_LOOP_ID = 4,
167 AUTO_PLAY_ID = 5,
168 AUTO_SCALE_ID = 6,
169 AUTO_ZOOM_ID = 7,
170 FIRST_CLICK_INTERACT_ID = 8,
171 WIDTH_PIXELS_ID = 9,
172 HEIGHT_PIXELS_ID = 10,
173 WHITELIST_ENABLE_ID = 11,
174 WHITELIST_ID = 12,
175 PERMS_INTERACT_ID = 13,
176 PERMS_CONTROL_ID = 14,
177 PARAM_MAX_ID = PERMS_CONTROL_ID
178 };
179
180 // "permissions" values
181 // (e.g. (PERM_OWNER | PERM_GROUP) sets permissions on for OWNER and GROUP
182 static const U8 PERM_NONE = 0x0;
183 static const U8 PERM_OWNER = 0x1;
184 static const U8 PERM_GROUP = 0x2;
185 static const U8 PERM_ANYONE = 0x4;
186 static const U8 PERM_ALL = PERM_OWNER|PERM_GROUP|PERM_ANYONE;
187 static const U8 PERM_MASK = PERM_OWNER|PERM_GROUP|PERM_ANYONE;
188
189 // Limits (in bytes)
190 static const U32 MAX_URL_LENGTH = 1024;
191 static const U32 MAX_WHITELIST_SIZE = 1024;
192 static const U32 MAX_WHITELIST_COUNT = 64;
193 static const U16 MAX_WIDTH_PIXELS = 2048;
194 static const U16 MAX_HEIGHT_PIXELS = 2048;
195
196private:
197
198 U32 setStringFieldWithLimit( std::string &field, const std::string &value, U32 limit );
199 U32 setCurrentURLInternal( const std::string &url, bool check_whitelist);
200 bool fromLLSDInternal(const LLSD &sd, bool overwrite);
201
202private:
203 // "general" fields
204 bool mAltImageEnable;
205 MediaControls mControls;
206 std::string mCurrentURL;
207 std::string mHomeURL;
208 bool mAutoLoop;
209 bool mAutoPlay;
210 bool mAutoScale;
211 bool mAutoZoom;
212 bool mFirstClickInteract;
213 U16 mWidthPixels;
214 U16 mHeightPixels;
215
216 // "security" fields
217 bool mWhiteListEnable;
218 std::vector<std::string> mWhiteList;
219
220 // "permissions" fields
221 U8 mPermsInteract;
222 U8 mPermsControl;
223
224 mutable LLUUID *mMediaIDp; // temporary id assigned to media on the viewer
225};
226
227#endif
228
diff --git a/linden/indra/llprimitive/llprimitive.cpp b/linden/indra/llprimitive/llprimitive.cpp
index f1b7522..7546764 100644..100755
--- a/linden/indra/llprimitive/llprimitive.cpp
+++ b/linden/indra/llprimitive/llprimitive.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
@@ -43,7 +43,8 @@
43#include "llvolumemgr.h" 43#include "llvolumemgr.h"
44#include "llstring.h" 44#include "llstring.h"
45#include "lldatapacker.h" 45#include "lldatapacker.h"
46#include "llsdutil.h" 46#include "llsdutil.h"//_math.h"
47#include "llprimtexturelist.h"
47 48
48/** 49/**
49 * exported constants 50 * exported constants
@@ -111,6 +112,7 @@ const F32 FLEXIBLE_OBJECT_DEFAULT_LENGTH = 1.0f;
111const BOOL FLEXIBLE_OBJECT_DEFAULT_USING_COLLISION_SPHERE = FALSE; 112const BOOL FLEXIBLE_OBJECT_DEFAULT_USING_COLLISION_SPHERE = FALSE;
112const BOOL FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE = FALSE; 113const BOOL FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE = FALSE;
113 114
115const S32 MAX_FACE_BITS = 9;
114 116
115const char *SCULPT_DEFAULT_TEXTURE = "be293869-d0d9-0a69-5989-ad27f1946fd4"; // old inverted texture: "7595d345-a24c-e7ef-f0bd-78793792133e"; 117const char *SCULPT_DEFAULT_TEXTURE = "be293869-d0d9-0a69-5989-ad27f1946fd4"; // old inverted texture: "7595d345-a24c-e7ef-f0bd-78793792133e";
116 118
@@ -129,7 +131,7 @@ void LLPrimitive::setVolumeManager( LLVolumeMgr* volume_manager )
129{ 131{
130 if ( !volume_manager || sVolumeManager ) 132 if ( !volume_manager || sVolumeManager )
131 { 133 {
132 llerrs << "Unable to set LLPrimitive::sVolumeManager to NULL" << llendl; 134 llerrs << "LLPrimitive::sVolumeManager attempting to be set to NULL or it already has been set." << llendl;
133 } 135 }
134 sVolumeManager = volume_manager; 136 sVolumeManager = volume_manager;
135} 137}
@@ -150,7 +152,9 @@ bool LLPrimitive::cleanupVolumeManager()
150 152
151//=============================================================== 153//===============================================================
152LLPrimitive::LLPrimitive() 154LLPrimitive::LLPrimitive()
153: mMiscFlags(0) 155: mTextureList(),
156 mNumTEs(0),
157 mMiscFlags(0)
154{ 158{
155 mPrimitiveCode = 0; 159 mPrimitiveCode = 0;
156 160
@@ -167,20 +171,12 @@ LLPrimitive::LLPrimitive()
167 mAngularVelocity.setVec(0.f,0.f,0.f); 171 mAngularVelocity.setVec(0.f,0.f,0.f);
168 172
169 mScale.setVec(1.f,1.f,1.f); 173 mScale.setVec(1.f,1.f,1.f);
170
171 mNumTEs = 0;
172 mTextureList = NULL;
173} 174}
174 175
175//=============================================================== 176//===============================================================
176LLPrimitive::~LLPrimitive() 177LLPrimitive::~LLPrimitive()
177{ 178{
178 if (mTextureList) 179 clearTextureList();
179 {
180 delete [] mTextureList;
181 mTextureList = NULL;
182 }
183
184 // Cleanup handled by volume manager 180 // Cleanup handled by volume manager
185 if (mVolumep) 181 if (mVolumep)
186 { 182 {
@@ -189,6 +185,10 @@ LLPrimitive::~LLPrimitive()
189 mVolumep = NULL; 185 mVolumep = NULL;
190} 186}
191 187
188void LLPrimitive::clearTextureList()
189{
190}
191
192//=============================================================== 192//===============================================================
193// static 193// static
194LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code) 194LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code)
@@ -212,15 +212,7 @@ LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code)
212void LLPrimitive::init_primitive(LLPCode p_code) 212void LLPrimitive::init_primitive(LLPCode p_code)
213{ 213{
214 LLMemType m1(LLMemType::MTYPE_PRIMITIVE); 214 LLMemType m1(LLMemType::MTYPE_PRIMITIVE);
215 if (mNumTEs) 215 clearTextureList();
216 {
217 if (mTextureList)
218 {
219 delete [] mTextureList;
220 }
221 mTextureList = new LLTextureEntry[mNumTEs];
222 }
223
224 mPrimitiveCode = p_code; 216 mPrimitiveCode = p_code;
225} 217}
226 218
@@ -230,82 +222,30 @@ void LLPrimitive::setPCode(const U8 p_code)
230} 222}
231 223
232//=============================================================== 224//===============================================================
233const LLTextureEntry * LLPrimitive::getTE(const U8 te_num) const 225LLTextureEntry* LLPrimitive::getTE(const U8 index) const
234{ 226{
235 // if we're asking for a non-existent face, return null 227 return mTextureList.getTexture(index);
236 if (mNumTEs && (te_num< mNumTEs))
237 {
238 return(&mTextureList[te_num]);
239 }
240 else
241 {
242 return(NULL);
243 }
244} 228}
245 229
246//=============================================================== 230//===============================================================
247void LLPrimitive::setNumTEs(const U8 num_tes) 231void LLPrimitive::setNumTEs(const U8 num_tes)
248{ 232{
249 if (num_tes == mNumTEs) 233 mTextureList.setSize(num_tes);
250 {
251 return;
252 }
253
254 // Right now, we don't try and preserve entries when the number of faces
255 // changes.
256
257 LLMemType m1(LLMemType::MTYPE_PRIMITIVE);
258 if (num_tes)
259 {
260 LLTextureEntry *new_tes;
261 new_tes = new LLTextureEntry[num_tes];
262 U32 i;
263 for (i = 0; i < num_tes; i++)
264 {
265 if (i < mNumTEs)
266 {
267 new_tes[i] = mTextureList[i];
268 }
269 else if (mNumTEs)
270 {
271 new_tes[i] = mTextureList[mNumTEs - 1];
272 }
273 else
274 {
275 new_tes[i] = LLTextureEntry();
276 }
277 }
278 delete[] mTextureList;
279 mTextureList = new_tes;
280 }
281 else
282 {
283 delete[] mTextureList;
284 mTextureList = NULL;
285 }
286
287
288 mNumTEs = num_tes;
289} 234}
290 235
291//=============================================================== 236//===============================================================
292void LLPrimitive::setAllTETextures(const LLUUID &tex_id) 237void LLPrimitive::setAllTETextures(const LLUUID &tex_id)
293{ 238{
294 U8 i; 239 mTextureList.setAllIDs(tex_id);
295
296 for (i = 0; i < mNumTEs; i++)
297 {
298 mTextureList[i].setID(tex_id);
299 }
300} 240}
301 241
302//=============================================================== 242//===============================================================
303void LLPrimitive::setTE(const U8 index, const LLTextureEntry &te) 243void LLPrimitive::setTE(const U8 index, const LLTextureEntry& te)
304{ 244{
305 mTextureList[index] = te; 245 mTextureList.copyTexture(index, te);
306} 246}
307 247
308S32 LLPrimitive::setTETexture(const U8 te, const LLUUID &tex_id) 248S32 LLPrimitive::setTETexture(const U8 index, const LLUUID &id)
309{ 249{
310 // if we're asking for a non-existent face, return null 250 // if we're asking for a non-existent face, return null
311 if (te >= mNumTEs) 251 if (te >= mNumTEs)
@@ -314,10 +254,10 @@ S32 LLPrimitive::setTETexture(const U8 te, const LLUUID &tex_id)
314 return 0; 254 return 0;
315 } 255 }
316 256
317 return mTextureList[te].setID(tex_id); 257 return mTextureList.setID(index, id);
318} 258}
319 259
320S32 LLPrimitive::setTEColor(const U8 te, const LLColor4 &color) 260S32 LLPrimitive::setTEColor(const U8 index, const LLColor4 &color)
321{ 261{
322 // if we're asking for a non-existent face, return null 262 // if we're asking for a non-existent face, return null
323 if (te >= mNumTEs) 263 if (te >= mNumTEs)
@@ -326,10 +266,11 @@ S32 LLPrimitive::setTEColor(const U8 te, const LLColor4 &color)
326 return 0; 266 return 0;
327 } 267 }
328 268
329 return mTextureList[te].setColor(color); 269
270 return mTextureList.setColor(index, color);
330} 271}
331 272
332S32 LLPrimitive::setTEColor(const U8 te, const LLColor3 &color) 273S32 LLPrimitive::setTEColor(const U8 index, const LLColor3 &color)
333{ 274{
334 // if we're asking for a non-existent face, return null 275 // if we're asking for a non-existent face, return null
335 if (te >= mNumTEs) 276 if (te >= mNumTEs)
@@ -338,10 +279,10 @@ S32 LLPrimitive::setTEColor(const U8 te, const LLColor3 &color)
338 return 0; 279 return 0;
339 } 280 }
340 281
341 return mTextureList[te].setColor(color); 282 return mTextureList.setColor(index, color);
342} 283}
343 284
344S32 LLPrimitive::setTEAlpha(const U8 te, const F32 alpha) 285S32 LLPrimitive::setTEAlpha(const U8 index, const F32 alpha)
345{ 286{
346 // if we're asking for a non-existent face, return null 287 // if we're asking for a non-existent face, return null
347 if (te >= mNumTEs) 288 if (te >= mNumTEs)
@@ -350,117 +291,64 @@ S32 LLPrimitive::setTEAlpha(const U8 te, const F32 alpha)
350 return 0; 291 return 0;
351 } 292 }
352 293
353 return mTextureList[te].setAlpha(alpha); 294 return mTextureList.setAlpha(index, alpha);
354} 295}
355 296
356//=============================================================== 297//===============================================================
357S32 LLPrimitive::setTEScale(const U8 te, const F32 s, const F32 t) 298S32 LLPrimitive::setTEScale(const U8 index, const F32 s, const F32 t)
358{ 299{
359 // if we're asking for a non-existent face, return null 300 return mTextureList.setScale(index, s, t);
360 if (te >= mNumTEs)
361 {
362 llwarns << "Setting nonexistent face" << llendl;
363 return 0;
364 }
365
366 return mTextureList[te].setScale(s,t);
367} 301}
368 302
369 303
370// BUG: slow - done this way because texture entries have some 304// BUG: slow - done this way because texture entries have some
371// voodoo related to texture coords 305// voodoo related to texture coords
372S32 LLPrimitive::setTEScaleS(const U8 te, const F32 s) 306S32 LLPrimitive::setTEScaleS(const U8 index, const F32 s)
373{ 307{
374 if (te >= mNumTEs) 308 return mTextureList.setScaleS(index, s);
375 {
376 llwarns << "Setting nonexistent face" << llendl;
377 return 0;
378 }
379
380 F32 ignore, t;
381 mTextureList[te].getScale(&ignore, &t);
382 return mTextureList[te].setScale(s,t);
383} 309}
384 310
385 311
386// BUG: slow - done this way because texture entries have some 312// BUG: slow - done this way because texture entries have some
387// voodoo related to texture coords 313// voodoo related to texture coords
388S32 LLPrimitive::setTEScaleT(const U8 te, const F32 t) 314S32 LLPrimitive::setTEScaleT(const U8 index, const F32 t)
389{ 315{
390 if (te >= mNumTEs) 316 return mTextureList.setScaleT(index, t);
391 {
392 llwarns << "Setting nonexistent face" << llendl;
393 return 0;
394 }
395
396 F32 s, ignore;
397 mTextureList[te].getScale(&s, &ignore);
398 return mTextureList[te].setScale(s,t);
399} 317}
400 318
401 319
402//=============================================================== 320//===============================================================
403S32 LLPrimitive::setTEOffset(const U8 te, const F32 s, const F32 t) 321S32 LLPrimitive::setTEOffset(const U8 index, const F32 s, const F32 t)
404{ 322{
405 // if we're asking for a non-existent face, return null 323 return mTextureList.setOffset(index, s, t);
406 if (te >= mNumTEs)
407 {
408 llwarns << "Setting nonexistent face" << llendl;
409 return 0;
410 }
411
412 return mTextureList[te].setOffset(s,t);
413} 324}
414 325
415 326
416// BUG: slow - done this way because texture entries have some 327// BUG: slow - done this way because texture entries have some
417// voodoo related to texture coords 328// voodoo related to texture coords
418S32 LLPrimitive::setTEOffsetS(const U8 te, const F32 s) 329S32 LLPrimitive::setTEOffsetS(const U8 index, const F32 s)
419{ 330{
420 if (te >= mNumTEs) 331 return mTextureList.setOffsetS(index, s);
421 {
422 llwarns << "Setting nonexistent face" << llendl;
423 return 0;
424 }
425
426 F32 ignore, t;
427 mTextureList[te].getOffset(&ignore, &t);
428 return mTextureList[te].setOffset(s,t);
429} 332}
430 333
431 334
432// BUG: slow - done this way because texture entries have some 335// BUG: slow - done this way because texture entries have some
433// voodoo related to texture coords 336// voodoo related to texture coords
434S32 LLPrimitive::setTEOffsetT(const U8 te, const F32 t) 337S32 LLPrimitive::setTEOffsetT(const U8 index, const F32 t)
435{ 338{
436 if (te >= mNumTEs) 339 return mTextureList.setOffsetT(index, t);
437 {
438 llwarns << "Setting nonexistent face" << llendl;
439 return 0;
440 }
441
442 F32 s, ignore;
443 mTextureList[te].getOffset(&s, &ignore);
444 return mTextureList[te].setOffset(s,t);
445} 340}
446 341
447 342
448//=============================================================== 343//===============================================================
449S32 LLPrimitive::setTERotation(const U8 te, const F32 r) 344S32 LLPrimitive::setTERotation(const U8 index, const F32 r)
450{ 345{
451 // if we're asking for a non-existent face, return null 346 return mTextureList.setRotation(index, r);
452 if (te >= mNumTEs)
453 {
454 llwarns << "Setting nonexistent face" << llendl;
455 return 0;
456 }
457
458 return mTextureList[te].setRotation(r);
459} 347}
460 348
461 349
462//=============================================================== 350//===============================================================
463S32 LLPrimitive::setTEBumpShinyFullbright(const U8 te, const U8 bump) 351S32 LLPrimitive::setTEBumpShinyFullbright(const U8 index, const U8 bump)
464{ 352{
465 // if we're asking for a non-existent face, return null 353 // if we're asking for a non-existent face, return null
466 if (te >= mNumTEs) 354 if (te >= mNumTEs)
@@ -469,10 +357,10 @@ S32 LLPrimitive::setTEBumpShinyFullbright(const U8 te, const U8 bump)
469 return 0; 357 return 0;
470 } 358 }
471 359
472 return mTextureList[te].setBumpShinyFullbright( bump ); 360 return mTextureList.setBumpShinyFullbright(index, bump);
473} 361}
474 362
475S32 LLPrimitive::setTEMediaTexGen(const U8 te, const U8 media) 363S32 LLPrimitive::setTEMediaTexGen(const U8 index, const U8 media)
476{ 364{
477 // if we're asking for a non-existent face, return null 365 // if we're asking for a non-existent face, return null
478 if (te >= mNumTEs) 366 if (te >= mNumTEs)
@@ -481,10 +369,10 @@ S32 LLPrimitive::setTEMediaTexGen(const U8 te, const U8 media)
481 return 0; 369 return 0;
482 } 370 }
483 371
484 return mTextureList[te].setMediaTexGen( media ); 372 return mTextureList.setMediaTexGen(index, media);
485} 373}
486 374
487S32 LLPrimitive::setTEBumpmap(const U8 te, const U8 bump) 375S32 LLPrimitive::setTEBumpmap(const U8 index, const U8 bump)
488{ 376{
489 // if we're asking for a non-existent face, return null 377 // if we're asking for a non-existent face, return null
490 if (te >= mNumTEs) 378 if (te >= mNumTEs)
@@ -493,10 +381,10 @@ S32 LLPrimitive::setTEBumpmap(const U8 te, const U8 bump)
493 return 0; 381 return 0;
494 } 382 }
495 383
496 return mTextureList[te].setBumpmap( bump ); 384 return mTextureList.setBumpMap(index, bump);
497} 385}
498 386
499S32 LLPrimitive::setTEBumpShiny(const U8 te, const U8 bump_shiny) 387S32 LLPrimitive::setTEBumpShiny(const U8 index, const U8 bump_shiny)
500{ 388{
501 // if we're asking for a non-existent face, return null 389 // if we're asking for a non-existent face, return null
502 if (te >= mNumTEs) 390 if (te >= mNumTEs)
@@ -505,10 +393,10 @@ S32 LLPrimitive::setTEBumpShiny(const U8 te, const U8 bump_shiny)
505 return 0; 393 return 0;
506 } 394 }
507 395
508 return mTextureList[te].setBumpShiny( bump_shiny ); 396 return mTextureList.setBumpShiny(index, bump_shiny);
509} 397}
510 398
511S32 LLPrimitive::setTETexGen(const U8 te, const U8 texgen) 399S32 LLPrimitive::setTETexGen(const U8 index, const U8 texgen)
512{ 400{
513 // if we're asking for a non-existent face, return null 401 // if we're asking for a non-existent face, return null
514 if (te >= mNumTEs) 402 if (te >= mNumTEs)
@@ -517,10 +405,10 @@ S32 LLPrimitive::setTETexGen(const U8 te, const U8 texgen)
517 return 0; 405 return 0;
518 } 406 }
519 407
520 return mTextureList[te].setTexGen( texgen ); 408 return mTextureList.setTexGen(index, texgen);
521} 409}
522 410
523S32 LLPrimitive::setTEShiny(const U8 te, const U8 shiny) 411S32 LLPrimitive::setTEShiny(const U8 index, const U8 shiny)
524{ 412{
525 // if we're asking for a non-existent face, return null 413 // if we're asking for a non-existent face, return null
526 if (te >= mNumTEs) 414 if (te >= mNumTEs)
@@ -529,11 +417,13 @@ S32 LLPrimitive::setTEShiny(const U8 te, const U8 shiny)
529 return 0; 417 return 0;
530 } 418 }
531 419
532 return mTextureList[te].setShiny( shiny ); 420
421 return mTextureList.setShiny(index, shiny);
533} 422}
534 423
535S32 LLPrimitive::setTEFullbright(const U8 te, const U8 fullbright) 424S32 LLPrimitive::setTEFullbright(const U8 index, const U8 fullbright)
536{ 425{
426
537 // if we're asking for a non-existent face, return null 427 // if we're asking for a non-existent face, return null
538 if (te >= mNumTEs) 428 if (te >= mNumTEs)
539 { 429 {
@@ -541,10 +431,10 @@ S32 LLPrimitive::setTEFullbright(const U8 te, const U8 fullbright)
541 return 0; 431 return 0;
542 } 432 }
543 433
544 return mTextureList[te].setFullbright( fullbright ); 434 return mTextureList.setFullbright(index, fullbright);
545} 435}
546 436
547S32 LLPrimitive::setTEMediaFlags(const U8 te, const U8 media_flags) 437S32 LLPrimitive::setTEMediaFlags(const U8 index, const U8 media_flags)
548{ 438{
549 // if we're asking for a non-existent face, return null 439 // if we're asking for a non-existent face, return null
550 if (te >= mNumTEs) 440 if (te >= mNumTEs)
@@ -553,10 +443,10 @@ S32 LLPrimitive::setTEMediaFlags(const U8 te, const U8 media_flags)
553 return 0; 443 return 0;
554 } 444 }
555 445
556 return mTextureList[te].setMediaFlags( media_flags ); 446 return mTextureList.setMediaFlags(index, media_flags);
557} 447}
558 448
559S32 LLPrimitive::setTEGlow(const U8 te, const F32 glow) 449S32 LLPrimitive::setTEGlow(const U8 index, const F32 glow)
560{ 450{
561 // if we're asking for a non-existent face, return null 451 // if we're asking for a non-existent face, return null
562 if (te >= mNumTEs) 452 if (te >= mNumTEs)
@@ -565,7 +455,7 @@ S32 LLPrimitive::setTEGlow(const U8 te, const F32 glow)
565 return 0; 455 return 0;
566 } 456 }
567 457
568 return mTextureList[te].setGlow( glow ); 458 return mTextureList.setGlow(index, glow);
569} 459}
570 460
571 461
@@ -877,25 +767,18 @@ std::string LLPrimitive::pCodeToString(const LLPCode pcode)
877void LLPrimitive::copyTEs(const LLPrimitive *primitivep) 767void LLPrimitive::copyTEs(const LLPrimitive *primitivep)
878{ 768{
879 U32 i; 769 U32 i;
880 if (primitivep->getNumTEs() != getNumTEs()) 770 if (primitivep->getExpectedNumTEs() != getExpectedNumTEs())
771 {
772 llwarns << "Primitives don't have same expected number of TE's" << llendl;
773 }
774 U32 num_tes = llmin(primitivep->getExpectedNumTEs(), getExpectedNumTEs());
775 if (mTextureList.size() < getExpectedNumTEs())
881 { 776 {
882 llwarns << "Primitives don't have same number of TE's" << llendl; 777 mTextureList.setSize(getExpectedNumTEs());
883 } 778 }
884 U32 num_tes = llmin(primitivep->getNumTEs(), getNumTEs());
885 for (i = 0; i < num_tes; i++) 779 for (i = 0; i < num_tes; i++)
886 { 780 {
887 const LLTextureEntry *tep = primitivep->getTE(i); 781 mTextureList.copyTexture(i, *(primitivep->getTE(i)));
888 F32 s, t;
889 setTETexture(i, tep->getID());
890 setTEColor(i, tep->getColor());
891 tep->getScale(&s, &t);
892 setTEScale(i, s, t);
893 tep->getOffset(&s, &t);
894 setTEOffset(i, s, t);
895 setTERotation(i, tep->getRotation());
896 setTEBumpShinyFullbright(i, tep->getBumpShinyFullbright());
897 setTEMediaTexGen(i, tep->getMediaTexGen());
898 setTEGlow(i, tep->getGlow());
899 } 782 }
900} 783}
901 784
@@ -957,73 +840,209 @@ BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detai
957 840
958 U32 old_face_mask = mVolumep->mFaceMask; 841 U32 old_face_mask = mVolumep->mFaceMask;
959 842
843
844 S32 face_bit = 0;
845 S32 cur_mask = 0;
846
847 // Grab copies of the old faces from the original shape, ordered by type.
848 // We will use these to figure out what old texture info gets mapped to new
849 // faces in the new shape.
850 std::vector<LLProfile::Face> old_faces;
851 for (S32 face = 0; face < mVolumep->getNumFaces(); face++)
852 {
853 old_faces.push_back(mVolumep->getProfile().mFaces[face]);
854 }
855
856 // Copy the old texture info off to the side, but not in the order in which
857 // they live in the mTextureList, rather in order of ther "face id" which
858 // is the corresponding value of LLVolueParams::LLProfile::mFaces::mIndex.
859 //
860 // Hence, some elements of old_tes::mEntryList will be invalid. It is
861 // initialized to a size of 9 (max number of possible faces on a volume?)
862 // and only the ones with valid types are filled in.
863 LLPrimTextureList old_tes;
864 old_tes.setSize(9);
865 for (face_bit = 0; face_bit < 9; face_bit++)
866 {
867 cur_mask = 0x1 << face_bit;
868 if (old_face_mask & cur_mask)
869 {
870 S32 te_index = face_index_from_id(cur_mask, old_faces);
871 old_tes.copyTexture(face_bit, *(getTE(te_index)));
872 //llinfos << face_bit << ":" << te_index << ":" << old_tes[face_bit].getID() << llendl;
873 }
874 }
875
876
960 // build the new object 877 // build the new object
961 sVolumeManager->unrefVolume(mVolumep); 878 sVolumeManager->unrefVolume(mVolumep);
962 mVolumep = volumep; 879 mVolumep = volumep;
963 880
964 U32 new_face_mask = mVolumep->mFaceMask; 881 U32 new_face_mask = mVolumep->mFaceMask;
965 if (old_face_mask != new_face_mask) 882 S32 i;
966 {
967 setNumTEs(mVolumep->getNumFaces());
968 }
969
970 return TRUE;
971}
972 883
973BOOL LLPrimitive::setMaterial(U8 material) 884 if (old_face_mask == new_face_mask)
974{
975 if (material != mMaterial)
976 { 885 {
977 mMaterial = material; 886 setNumTEs(mVolumep->getNumFaces());
978 return TRUE; 887 return TRUE;
979 } 888 }
980 else
981 {
982 return FALSE;
983 }
984}
985 889
986void LLPrimitive::setTEArrays(const U8 size, 890 // initialize face_mapping
987 const LLUUID* image_ids, 891 S32 face_mapping[9];
988 const F32* scale_s, 892 for (face_bit = 0; face_bit < 9; face_bit++)
989 const F32* scale_t)
990{
991 S32 cur_size = size;
992 if (cur_size > getNumTEs())
993 { 893 {
994 llwarns << "Trying to set more TEs than exist!" << llendl; 894 face_mapping[face_bit] = face_bit;
995 cur_size = getNumTEs();
996 } 895 }
997 896
998 S32 i; 897 // The new shape may have more faces than the original, but we can't just
999 // Copy over image information 898 // add them to the end -- the ordering matters and it may be that we must
1000 for (i = 0; i < cur_size; i++) 899 // insert the new faces in the middle of the list. When we add a face it
900 // will pick up the texture/color info of one of the old faces an so we
901 // now figure out which old face info gets mapped to each new face, and
902 // store in the face_mapping lookup table.
903 for (face_bit = 0; face_bit < 9; face_bit++)
1001 { 904 {
1002 // This is very BAD!!!!!! 905 cur_mask = 0x1 << face_bit;
1003 if (image_ids != NULL) 906 if (!(new_face_mask & cur_mask))
1004 { 907 {
1005 setTETexture(i,image_ids[i]); 908 // Face doesn't exist in new map.
909 face_mapping[face_bit] = -1;
910 continue;
1006 } 911 }
1007 if (scale_s && scale_t) 912 else if (old_face_mask & cur_mask)
1008 { 913 {
1009 setTEScale(i, scale_s[i], scale_t[i]); 914 // Face exists in new and old map.
915 face_mapping[face_bit] = face_bit;
916 continue;
1010 } 917 }
1011 }
1012 918
1013 if (i < getNumTEs()) 919 // OK, how we've got a mismatch, where we have to fill a new face with one from
1014 { 920 // the old face.
1015 cur_size--; 921 if (cur_mask & (LL_FACE_PATH_BEGIN | LL_FACE_PATH_END | LL_FACE_INNER_SIDE))
1016 for (i=i; i < getNumTEs(); i++) // the i=i removes a gcc warning
1017 { 922 {
1018 if (image_ids != NULL) 923 // It's a top/bottom/hollow interior face.
924 if (old_face_mask & LL_FACE_PATH_END)
1019 { 925 {
1020 setTETexture(i, image_ids[cur_size]); 926 face_mapping[face_bit] = 1;
927 continue;
1021 } 928 }
1022 if (scale_s && scale_t) 929 else
1023 { 930 {
1024 setTEScale(i, scale_s[cur_size], scale_t[cur_size]); 931 S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0;
932 for (i = 0; i < 4; i++)
933 {
934 if (old_face_mask & cur_outer_mask)
935 {
936 face_mapping[face_bit] = 5 + i;
937 break;
938 }
939 cur_outer_mask <<= 1;
940 }
941 if (i == 4)
942 {
943 llwarns << "No path end or outer face in volume!" << llendl;
944 }
945 continue;
946 }
947 }
948
949 if (cur_mask & (LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END))
950 {
951 // A cut slice. Use the hollow interior if we have it.
952 if (old_face_mask & LL_FACE_INNER_SIDE)
953 {
954 face_mapping[face_bit] = 2;
955 continue;
956 }
957
958 // No interior, use the bottom face.
959 // Could figure out which of the outer faces was nearest, but that would be harder.
960 if (old_face_mask & LL_FACE_PATH_END)
961 {
962 face_mapping[face_bit] = 1;
963 continue;
964 }
965 else
966 {
967 S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0;
968 for (i = 0; i < 4; i++)
969 {
970 if (old_face_mask & cur_outer_mask)
971 {
972 face_mapping[face_bit] = 5 + i;
973 break;
974 }
975 cur_outer_mask <<= 1;
976 }
977 if (i == 4)
978 {
979 llwarns << "No path end or outer face in volume!" << llendl;
980 }
981 continue;
982 }
983 }
984
985 // OK, the face that's missing is an outer face...
986 // Pull from the nearest adjacent outer face (there's always guaranteed to be one...
987 S32 cur_outer = face_bit - 5;
988 S32 min_dist = 5;
989 S32 min_outer_bit = -1;
990 S32 i;
991 for (i = 0; i < 4; i++)
992 {
993 if (old_face_mask & (LL_FACE_OUTER_SIDE_0 << i))
994 {
995 S32 dist = abs(i - cur_outer);
996 if (dist < min_dist)
997 {
998 min_dist = dist;
999 min_outer_bit = i + 5;
1000 }
1025 } 1001 }
1026 } 1002 }
1003 if (-1 == min_outer_bit)
1004 {
1005 llinfos << (LLVolume *)mVolumep << llendl;
1006 llwarns << "Bad! No outer faces, impossible!" << llendl;
1007 }
1008 face_mapping[face_bit] = min_outer_bit;
1009 }
1010
1011
1012 setNumTEs(mVolumep->getNumFaces());
1013 for (face_bit = 0; face_bit < 9; face_bit++)
1014 {
1015 // For each possible face type on the new shape we check to see if that
1016 // face exists and if it does we create a texture entry that is a copy
1017 // of one of the originals. Since the originals might not have a
1018 // matching face, we use the face_mapping lookup table to figure out
1019 // which face information to copy.
1020 cur_mask = 0x1 << face_bit;
1021 if (new_face_mask & cur_mask)
1022 {
1023 if (-1 == face_mapping[face_bit])
1024 {
1025 llwarns << "No mapping from old face to new face!" << llendl;
1026 }
1027
1028 S32 te_num = face_index_from_id(cur_mask, mVolumep->getProfile().mFaces);
1029 setTE(te_num, *(old_tes.getTexture(face_mapping[face_bit])));
1030 }
1031 }
1032>>>>>>> 5faaca1... port llprimitive from SG2.0
1033 return TRUE;
1034}
1035
1036BOOL LLPrimitive::setMaterial(U8 material)
1037{
1038 if (material != mMaterial)
1039 {
1040 mMaterial = material;
1041 return TRUE;
1042 }
1043 else
1044 {
1045 return FALSE;
1027 } 1046 }
1028} 1047}
1029 1048
@@ -1178,6 +1197,7 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys, int shield) const
1178 else memcpy(&image_ids[face_index*16],LLUUID("4934f1bf-3b1f-cf4f-dbdf-a72550d05bc6").mData,16);//grey block 1197 else memcpy(&image_ids[face_index*16],LLUUID("4934f1bf-3b1f-cf4f-dbdf-a72550d05bc6").mData,16);//grey block
1179 }else memcpy(&image_ids[face_index*16],getTE(face_index)->getID().mData,16); /* Flawfinder: ignore */ 1198 }else memcpy(&image_ids[face_index*16],getTE(face_index)->getID().mData,16); /* Flawfinder: ignore */
1180 1199
1200
1181 // Cast LLColor4 to LLColor4U 1201 // Cast LLColor4 to LLColor4U
1182 coloru.setVec( getTE(face_index)->getColor() ); 1202 coloru.setVec( getTE(face_index)->getColor() );
1183 1203
@@ -1402,6 +1422,7 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, con
1402 color.mV[VALPHA] = F32(255 - coloru.mV[VALPHA]) / 255.f; 1422 color.mV[VALPHA] = F32(255 - coloru.mV[VALPHA]) / 255.f;
1403 1423
1404 retval |= setTEColor(i, color); 1424 retval |= setTEColor(i, color);
1425
1405 } 1426 }
1406 1427
1407 return retval; 1428 return retval;
@@ -1501,11 +1522,24 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
1501 return retval; 1522 return retval;
1502} 1523}
1503 1524
1504void LLPrimitive::setTextureList(LLTextureEntry *listp) 1525U8 LLPrimitive::getExpectedNumTEs() const
1526{
1527 U8 expected_face_count = 0;
1528 if (mVolumep)
1529 {
1530 expected_face_count = mVolumep->getNumFaces();
1531 }
1532 return expected_face_count;
1533}
1534
1535void LLPrimitive::copyTextureList(const LLPrimTextureList& other_list)
1536{
1537 mTextureList.copy(other_list);
1538}
1539
1540void LLPrimitive::takeTextureList(LLPrimTextureList& other_list)
1505{ 1541{
1506 LLTextureEntry* old_texture_list = mTextureList; 1542 mTextureList.take(other_list);
1507 mTextureList = listp;
1508 delete[] old_texture_list;
1509} 1543}
1510 1544
1511//============================================================================ 1545//============================================================================
@@ -1569,6 +1603,8 @@ BOOL LLNetworkData::isValid(U16 param_type, U32 size)
1569 return (size == 16); 1603 return (size == 16);
1570 case PARAMS_SCULPT: 1604 case PARAMS_SCULPT:
1571 return (size == 17); 1605 return (size == 17);
1606 case PARAMS_LIGHT_IMAGE:
1607 return (size == 28);
1572 } 1608 }
1573 1609
1574 return FALSE; 1610 return FALSE;
@@ -1901,3 +1937,78 @@ bool LLSculptParams::fromLLSD(LLSD& sd)
1901 return false; 1937 return false;
1902} 1938}
1903 1939
1940//============================================================================
1941
1942LLLightImageParams::LLLightImageParams()
1943{
1944 mType = PARAMS_LIGHT_IMAGE;
1945 mParams.setVec(F_PI*0.5f, 0.f, 0.f);
1946}
1947
1948BOOL LLLightImageParams::pack(LLDataPacker &dp) const
1949{
1950 dp.packUUID(mLightTexture, "texture");
1951 dp.packVector3(mParams, "params");
1952
1953 return TRUE;
1954}
1955
1956BOOL LLLightImageParams::unpack(LLDataPacker &dp)
1957{
1958 dp.unpackUUID(mLightTexture, "texture");
1959 dp.unpackVector3(mParams, "params");
1960
1961 return TRUE;
1962}
1963
1964bool LLLightImageParams::operator==(const LLNetworkData& data) const
1965{
1966 if (data.mType != PARAMS_LIGHT_IMAGE)
1967 {
1968 return false;
1969 }
1970
1971 const LLLightImageParams *param = (const LLLightImageParams*)&data;
1972 if ( (param->mLightTexture != mLightTexture) )
1973 {
1974 return false;
1975 }
1976
1977 if ( (param->mParams != mParams ) )
1978 {
1979 return false;
1980 }
1981
1982 return true;
1983}
1984
1985void LLLightImageParams::copy(const LLNetworkData& data)
1986{
1987 const LLLightImageParams *param = (LLLightImageParams*)&data;
1988 mLightTexture = param->mLightTexture;
1989 mParams = param->mParams;
1990}
1991
1992
1993
1994LLSD LLLightImageParams::asLLSD() const
1995{
1996 LLSD sd;
1997
1998 sd["texture"] = mLightTexture;
1999 sd["params"] = mParams.getValue();
2000
2001 return sd;
2002}
2003
2004bool LLLightImageParams::fromLLSD(LLSD& sd)
2005{
2006 if (sd.has("texture"))
2007 {
2008 setLightTexture( sd["texture"] );
2009 setParams( LLVector3( sd["params"] ) );
2010 return true;
2011 }
2012
2013 return false;
2014}
diff --git a/linden/indra/llprimitive/llprimitive.h b/linden/indra/llprimitive/llprimitive.h
index efabb82..e146fbe 100644..100755
--- a/linden/indra/llprimitive/llprimitive.h
+++ b/linden/indra/llprimitive/llprimitive.h
@@ -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
@@ -37,9 +37,11 @@
37#include "v3math.h" 37#include "v3math.h"
38#include "xform.h" 38#include "xform.h"
39#include "message.h" 39#include "message.h"
40#include "llmemory.h" 40#include "llmemory.h" // not in SG2.0
41//#include "llpointer.h"// instead in SG2.0
41#include "llvolume.h" 42#include "llvolume.h"
42#include "lltextureentry.h" 43#include "lltextureentry.h"
44#include "llprimtexturelist.h"
43 45
44// Moved to stdtypes.h --JC 46// Moved to stdtypes.h --JC
45// typedef U8 LLPCode; 47// typedef U8 LLPCode;
@@ -105,7 +107,8 @@ public:
105 { 107 {
106 PARAMS_FLEXIBLE = 0x10, 108 PARAMS_FLEXIBLE = 0x10,
107 PARAMS_LIGHT = 0x20, 109 PARAMS_LIGHT = 0x20,
108 PARAMS_SCULPT = 0x30 110 PARAMS_SCULPT = 0x30,
111 PARAMS_LIGHT_IMAGE = 0x40,
109 }; 112 };
110 113
111public: 114public:
@@ -260,11 +263,33 @@ public:
260 bool fromLLSD(LLSD& sd); 263 bool fromLLSD(LLSD& sd);
261 264
262 void setSculptTexture(const LLUUID& id) { mSculptTexture = id; } 265 void setSculptTexture(const LLUUID& id) { mSculptTexture = id; }
263 LLUUID getSculptTexture() { return mSculptTexture; } 266 LLUUID getSculptTexture() const { return mSculptTexture; }
264 void setSculptType(U8 type) { mSculptType = type; } 267 void setSculptType(U8 type) { mSculptType = type; }
265 U8 getSculptType() { return mSculptType; } 268 U8 getSculptType() const { return mSculptType; }
266}; 269};
267 270
271class LLLightImageParams : public LLNetworkData
272{
273protected:
274 LLUUID mLightTexture;
275 LLVector3 mParams;
276
277public:
278 LLLightImageParams();
279 /*virtual*/ BOOL pack(LLDataPacker &dp) const;
280 /*virtual*/ BOOL unpack(LLDataPacker &dp);
281 /*virtual*/ bool operator==(const LLNetworkData& data) const;
282 /*virtual*/ void copy(const LLNetworkData& data);
283 LLSD asLLSD() const;
284 operator LLSD() const { return asLLSD(); }
285 bool fromLLSD(LLSD& sd);
286
287 void setLightTexture(const LLUUID& id) { mLightTexture = id; }
288 LLUUID getLightTexture() const { return mLightTexture; }
289 void setParams(const LLVector3& params) { mParams = params; }
290 LLVector3 getParams() const { return mParams; }
291
292};
268 293
269 294
270class LLPrimitive : public LLXform 295class LLPrimitive : public LLXform
@@ -294,6 +319,8 @@ public:
294 LLPrimitive(); 319 LLPrimitive();
295 virtual ~LLPrimitive(); 320 virtual ~LLPrimitive();
296 321
322 void clearTextureList();
323
297 static LLPrimitive *createPrimitive(LLPCode p_code); 324 static LLPrimitive *createPrimitive(LLPCode p_code);
298 void init_primitive(LLPCode p_code); 325 void init_primitive(LLPCode p_code);
299 326
@@ -304,11 +331,11 @@ public:
304 331
305 // Modify texture entry properties 332 // Modify texture entry properties
306 inline BOOL validTE(const U8 te_num) const; 333 inline BOOL validTE(const U8 te_num) const;
307 const LLTextureEntry *getTE(const U8 te_num) const; 334 LLTextureEntry* getTE(const U8 te_num) const;
308 335
309 virtual void setNumTEs(const U8 num_tes); 336 virtual void setNumTEs(const U8 num_tes);
310 virtual void setAllTETextures(const LLUUID &tex_id); 337 virtual void setAllTETextures(const LLUUID &tex_id);
311 virtual void setTE(const U8 index, const LLTextureEntry &te); 338 virtual void setTE(const U8 index, const LLTextureEntry& te);
312 virtual S32 setTEColor(const U8 te, const LLColor4 &color); 339 virtual S32 setTEColor(const U8 te, const LLColor4 &color);
313 virtual S32 setTEColor(const U8 te, const LLColor3 &color); 340 virtual S32 setTEColor(const U8 te, const LLColor3 &color);
314 virtual S32 setTEAlpha(const U8 te, const F32 alpha); 341 virtual S32 setTEAlpha(const U8 te, const F32 alpha);
@@ -331,10 +358,6 @@ public:
331 virtual S32 setTEGlow(const U8 te, const F32 glow); 358 virtual S32 setTEGlow(const U8 te, const F32 glow);
332 virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed 359 virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed
333 360
334 void setTEArrays(const U8 size,
335 const LLUUID* image_ids,
336 const F32* scale_s,
337 const F32* scale_t);
338 void copyTEs(const LLPrimitive *primitive); 361 void copyTEs(const LLPrimitive *primitive);
339 S32 packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const; 362 S32 packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const;
340 S32 unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 data_size, U8 face_count, EMsgVariableType type); 363 S32 unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 data_size, U8 face_count, EMsgVariableType type);
@@ -382,14 +405,21 @@ public:
382 const LLVector3& getAngularVelocity() const { return mAngularVelocity; } 405 const LLVector3& getAngularVelocity() const { return mAngularVelocity; }
383 const LLVector3& getVelocity() const { return mVelocity; } 406 const LLVector3& getVelocity() const { return mVelocity; }
384 const LLVector3& getAcceleration() const { return mAcceleration; } 407 const LLVector3& getAcceleration() const { return mAcceleration; }
385 U8 getNumTEs() const { return mNumTEs; } 408 U8 getNumTEs() const { return mTextureList.size(); }
409 U8 getExpectedNumTEs() const;
386 410
387 U8 getMaterial() const { return mMaterial; } 411 U8 getMaterial() const { return mMaterial; }
388 412
389 void setVolumeType(const U8 code); 413 void setVolumeType(const U8 code);
390 U8 getVolumeType(); 414 U8 getVolumeType();
391 415
392 void setTextureList(LLTextureEntry *listp); 416 // clears existing textures
417 // copies the contents of other_list into mEntryList
418 void copyTextureList(const LLPrimTextureList& other_list);
419
420 // clears existing textures
421 // takes the contents of other_list and clears other_list
422 void takeTextureList(LLPrimTextureList& other_list);
393 423
394 inline BOOL isAvatar() const; 424 inline BOOL isAvatar() const;
395 inline BOOL isSittingAvatar() const; 425 inline BOOL isSittingAvatar() const;
@@ -414,7 +444,7 @@ protected:
414 LLVector3 mAcceleration; // are we under constant acceleration? 444 LLVector3 mAcceleration; // are we under constant acceleration?
415 LLVector3 mAngularVelocity; // angular velocity 445 LLVector3 mAngularVelocity; // angular velocity
416 LLPointer<LLVolume> mVolumep; 446 LLPointer<LLVolume> mVolumep;
417 LLTextureEntry *mTextureList; // list of texture GUIDs, scales, offsets 447 LLPrimTextureList mTextureList; // list of texture GUIDs, scales, offsets
418 U8 mMaterial; // Material code 448 U8 mMaterial; // Material code
419 U8 mNumTEs; // # of faces on the primitve 449 U8 mNumTEs; // # of faces on the primitve
420 U32 mMiscFlags; // home for misc bools 450 U32 mMiscFlags; // home for misc bools
diff --git a/linden/indra/llprimitive/llprimlinkinfo.h b/linden/indra/llprimitive/llprimlinkinfo.h
index 946fa75..dfe33c1 100644..100755
--- a/linden/indra/llprimitive/llprimlinkinfo.h
+++ b/linden/indra/llprimitive/llprimlinkinfo.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * $LicenseInfo:firstyear=2007&license=viewergpl$ 6 * $LicenseInfo:firstyear=2007&license=viewergpl$
7 * 7 *
8 * Copyright (c) 2007-2009, Linden Research, Inc. 8 * Copyright (c) 2007-2010, Linden Research, Inc.
9 * 9 *
10 * Second Life Viewer Source Code 10 * Second Life Viewer Source Code
11 * The source code in this file ("Source Code") is provided by Linden Lab 11 * The source code in this file ("Source Code") is provided by Linden Lab
diff --git a/linden/indra/llprimitive/llprimtexturelist.cpp b/linden/indra/llprimitive/llprimtexturelist.cpp
new file mode 100755
index 0000000..691eb76
--- /dev/null
+++ b/linden/indra/llprimitive/llprimtexturelist.cpp
@@ -0,0 +1,424 @@
1/**
2 * @file lltexturelist.cpp
3 * @brief LLPrimTextureList (virtual) base class
4 *
5 * $LicenseInfo:firstyear=2008&license=viewergpl$
6 *
7 * Copyright (c) 2008-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
33#include "linden_common.h"
34
35#include "llprimtexturelist.h"
36#include "lltextureentry.h"
37#include "llmemtype.h"
38
39// static
40//int (TMyClass::*pt2Member)(float, char, char) = NULL; // C++
41LLTextureEntry* (*LLPrimTextureList::sNewTextureEntryCallback)() = &(LLTextureEntry::newTextureEntry);
42
43// static
44void LLPrimTextureList::setNewTextureEntryCallback( LLTextureEntry* (*callback)() )
45{
46 if (callback)
47 {
48 LLPrimTextureList::sNewTextureEntryCallback = callback;
49 }
50 else
51 {
52 LLPrimTextureList::sNewTextureEntryCallback = &(LLTextureEntry::newTextureEntry);
53 }
54}
55
56// static
57// call this to get a new texture entry
58LLTextureEntry* LLPrimTextureList::newTextureEntry()
59{
60 return (*sNewTextureEntryCallback)();
61}
62
63LLPrimTextureList::LLPrimTextureList()
64{
65}
66
67// virtual
68LLPrimTextureList::~LLPrimTextureList()
69{
70 clear();
71}
72
73void LLPrimTextureList::clear()
74{
75 texture_list_t::iterator itr = mEntryList.begin();
76 while (itr != mEntryList.end())
77 {
78 delete (*itr);
79 (*itr) = NULL;
80 ++itr;
81 }
82 mEntryList.clear();
83}
84
85
86// clears current entries
87// copies contents of other_list
88// this is somewhat expensive, so it must be called explicitly
89void LLPrimTextureList::copy(const LLPrimTextureList& other_list)
90{
91 // compare the sizes
92 S32 this_size = mEntryList.size();
93 S32 other_size = other_list.mEntryList.size();
94
95 if (this_size > other_size)
96 {
97 // remove the extra entries
98 for (S32 index = this_size; index > other_size; --index)
99 {
100 delete mEntryList[index-1];
101 }
102 mEntryList.resize(other_size);
103 this_size = other_size;
104 }
105
106 S32 index = 0;
107 // copy for the entries that already exist
108 for ( ; index < this_size; ++index)
109 {
110 delete mEntryList[index];
111 mEntryList[index] = other_list.getTexture(index)->newCopy();
112 }
113
114 // add new entires if needed
115 for ( ; index < other_size; ++index)
116 {
117 mEntryList.push_back( other_list.getTexture(index)->newCopy() );
118 }
119}
120
121// clears current copies
122// takes contents of other_list
123// clears other_list
124void LLPrimTextureList::take(LLPrimTextureList& other_list)
125{
126 clear();
127 mEntryList = other_list.mEntryList;
128 other_list.mEntryList.clear();
129}
130
131// virtual
132// copies LLTextureEntry 'te'
133// returns TEM_CHANGE_TEXTURE if successful, otherwise TEM_CHANGE_NONE
134S32 LLPrimTextureList::copyTexture(const U8 index, const LLTextureEntry& te)
135{
136 if (S32(index) >= mEntryList.size())
137 {
138 S32 current_size = mEntryList.size();
139 llwarns << "ignore copy of index = " << S32(index) << " into texture entry list of size = " << current_size << llendl;
140 return TEM_CHANGE_NONE;
141 }
142
143 // we're changing an existing entry
144 llassert(mEntryList[index]);
145 delete (mEntryList[index]);
146 if (&te)
147 {
148 mEntryList[index] = te.newCopy();
149 }
150 else
151 {
152 mEntryList[index] = LLPrimTextureList::newTextureEntry();
153 }
154 return TEM_CHANGE_TEXTURE;
155}
156
157// virtual
158// takes ownership of LLTextureEntry* 'te'
159// returns TEM_CHANGE_TEXTURE if successful, otherwise TEM_CHANGE_NONE
160// IMPORTANT! -- if you use this function you must check the return value
161S32 LLPrimTextureList::takeTexture(const U8 index, LLTextureEntry* te)
162{
163 if (S32(index) >= mEntryList.size())
164 {
165 return TEM_CHANGE_NONE;
166 }
167
168 // we're changing an existing entry
169 llassert(mEntryList[index]);
170 delete (mEntryList[index]);
171 mEntryList[index] = te;
172 return TEM_CHANGE_TEXTURE;
173}
174
175// returns pointer to texture at 'index' slot
176LLTextureEntry* LLPrimTextureList::getTexture(const U8 index) const
177{
178 if (index < mEntryList.size())
179 {
180 return mEntryList[index];
181 }
182 return NULL;
183}
184
185//virtual
186//S32 setTE(const U8 index, const LLTextureEntry& te) = 0;
187
188S32 LLPrimTextureList::setID(const U8 index, const LLUUID& id)
189{
190 if (index < mEntryList.size())
191 {
192 return mEntryList[index]->setID(id);
193 }
194 return TEM_CHANGE_NONE;
195}
196
197S32 LLPrimTextureList::setColor(const U8 index, const LLColor3& color)
198{
199 if (index < mEntryList.size())
200 {
201 return mEntryList[index]->setColor(color);
202 }
203 return TEM_CHANGE_NONE;
204}
205
206S32 LLPrimTextureList::setColor(const U8 index, const LLColor4& color)
207{
208 if (index < mEntryList.size())
209 {
210 return mEntryList[index]->setColor(color);
211 }
212 return TEM_CHANGE_NONE;
213}
214
215S32 LLPrimTextureList::setAlpha(const U8 index, const F32 alpha)
216{
217 if (index < mEntryList.size())
218 {
219 return mEntryList[index]->setAlpha(alpha);
220 }
221 return TEM_CHANGE_NONE;
222}
223
224S32 LLPrimTextureList::setScale(const U8 index, const F32 s, const F32 t)
225{
226 if (index < mEntryList.size())
227 {
228 return mEntryList[index]->setScale(s, t);
229 }
230 return TEM_CHANGE_NONE;
231}
232
233S32 LLPrimTextureList::setScaleS(const U8 index, const F32 s)
234{
235 if (index < mEntryList.size())
236 {
237 return mEntryList[index]->setScaleS(s);
238 }
239 return TEM_CHANGE_NONE;
240}
241
242S32 LLPrimTextureList::setScaleT(const U8 index, const F32 t)
243{
244 if (index < mEntryList.size())
245 {
246 return mEntryList[index]->setScaleT(t);
247 }
248 return TEM_CHANGE_NONE;
249}
250
251S32 LLPrimTextureList::setOffset(const U8 index, const F32 s, const F32 t)
252{
253 if (index < mEntryList.size())
254 {
255 return mEntryList[index]->setOffset(s, t);
256 }
257 return TEM_CHANGE_NONE;
258}
259
260S32 LLPrimTextureList::setOffsetS(const U8 index, const F32 s)
261{
262 if (index < mEntryList.size())
263 {
264 return mEntryList[index]->setOffsetS(s);
265 }
266 return TEM_CHANGE_NONE;
267}
268
269S32 LLPrimTextureList::setOffsetT(const U8 index, const F32 t)
270{
271 if (index < mEntryList.size())
272 {
273 return mEntryList[index]->setOffsetT(t);
274 }
275 return TEM_CHANGE_NONE;
276}
277
278S32 LLPrimTextureList::setRotation(const U8 index, const F32 r)
279{
280 if (index < mEntryList.size())
281 {
282 return mEntryList[index]->setRotation(r);
283 }
284 return TEM_CHANGE_NONE;
285}
286
287S32 LLPrimTextureList::setBumpShinyFullbright(const U8 index, const U8 bump)
288{
289 if (index < mEntryList.size())
290 {
291 return mEntryList[index]->setBumpShinyFullbright(bump);
292 }
293 return TEM_CHANGE_NONE;
294}
295
296S32 LLPrimTextureList::setMediaTexGen(const U8 index, const U8 media)
297{
298 if (index < mEntryList.size())
299 {
300 return mEntryList[index]->setMediaTexGen(media);
301 }
302 return TEM_CHANGE_NONE;
303}
304
305S32 LLPrimTextureList::setBumpMap(const U8 index, const U8 bump)
306{
307 if (index < mEntryList.size())
308 {
309 return mEntryList[index]->setBumpmap(bump);
310 }
311 return TEM_CHANGE_NONE;
312}
313
314S32 LLPrimTextureList::setBumpShiny(const U8 index, const U8 bump_shiny)
315{
316 if (index < mEntryList.size())
317 {
318 return mEntryList[index]->setBumpShiny(bump_shiny);
319 }
320 return TEM_CHANGE_NONE;
321}
322
323S32 LLPrimTextureList::setTexGen(const U8 index, const U8 texgen)
324{
325 if (index < mEntryList.size())
326 {
327 return mEntryList[index]->setTexGen(texgen);
328 }
329 return TEM_CHANGE_NONE;
330}
331
332S32 LLPrimTextureList::setShiny(const U8 index, const U8 shiny)
333{
334 if (index < mEntryList.size())
335 {
336 return mEntryList[index]->setShiny(shiny);
337 }
338 return TEM_CHANGE_NONE;
339}
340
341S32 LLPrimTextureList::setFullbright(const U8 index, const U8 fullbright)
342{
343 if (index < mEntryList.size())
344 {
345 return mEntryList[index]->setFullbright(fullbright);
346 }
347 return TEM_CHANGE_NONE;
348}
349
350S32 LLPrimTextureList::setMediaFlags(const U8 index, const U8 media_flags)
351{
352 if (index < mEntryList.size())
353 {
354 return mEntryList[index]->setMediaFlags(media_flags);
355 }
356 return TEM_CHANGE_NONE;
357}
358
359S32 LLPrimTextureList::setGlow(const U8 index, const F32 glow)
360{
361 if (index < mEntryList.size())
362 {
363 return mEntryList[index]->setGlow(glow);
364 }
365 return TEM_CHANGE_NONE;
366}
367
368S32 LLPrimTextureList::size() const
369{
370 return mEntryList.size();
371}
372
373// sets the size of the mEntryList container
374void LLPrimTextureList::setSize(S32 new_size)
375{
376 LLMemType m1(LLMemType::MTYPE_PRIMITIVE);
377 if (new_size < 0)
378 {
379 new_size = 0;
380 }
381
382 S32 current_size = mEntryList.size();
383
384 if (new_size > current_size)
385 {
386 mEntryList.resize(new_size);
387 for (S32 index = current_size; index < new_size; ++index)
388 {
389 if (current_size > 0
390 && mEntryList[current_size - 1])
391 {
392 // copy the last valid entry for the new one
393 mEntryList[index] = mEntryList[current_size - 1]->newCopy();
394 }
395 else
396 {
397 // no valid enries to copy, so we new one up
398 LLTextureEntry* new_entry = LLPrimTextureList::newTextureEntry();
399 mEntryList[index] = new_entry;
400 }
401 }
402 }
403 else if (new_size < current_size)
404 {
405 for (S32 index = current_size-1; index >= new_size; --index)
406 {
407 delete mEntryList[index];
408 }
409 mEntryList.resize(new_size);
410 }
411}
412
413
414void LLPrimTextureList::setAllIDs(const LLUUID& id)
415{
416 texture_list_t::iterator itr = mEntryList.begin();
417 while (itr != mEntryList.end())
418 {
419 (*itr)->setID(id);
420 ++itr;
421 }
422}
423
424
diff --git a/linden/indra/llprimitive/llprimtexturelist.h b/linden/indra/llprimitive/llprimtexturelist.h
new file mode 100755
index 0000000..c62f7b9
--- /dev/null
+++ b/linden/indra/llprimitive/llprimtexturelist.h
@@ -0,0 +1,127 @@
1/**
2 * @file llprimtexturelist.h
3 * @brief LLPrimTextureList (virtual) base class
4 *
5 * $LicenseInfo:firstyear=2008&license=viewergpl$
6 *
7 * Copyright (c) 2008-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
33#ifndef LL_LLPRIMTEXTURELIST_H
34#define LL_LLPRIMTEXTURELIST_H
35
36#include <vector>
37#include "lluuid.h"
38#include "v3color.h"
39#include "v4color.h"
40
41
42class LLTextureEntry;
43
44// this is a list of LLTextureEntry*'s because in practice the list's elements
45// are of some derived class: LLFooTextureEntry
46typedef std::vector<LLTextureEntry*> texture_list_t;
47
48class LLPrimTextureList
49{
50public:
51 // the LLPrimTextureList needs to know what type of LLTextureEntry
52 // to generate when it needs a new one, so we may need to set a
53 // callback for generating it, (or else use the base class default:
54 // static LLPrimTextureEntry::newTextureEntry() )
55 //typedef LLTextureEntry* (__stdcall *NewTextureEntryFunction)();
56 //static NewTextureEntryFunction sNewTextureEntryCallback;
57 static LLTextureEntry* newTextureEntry();
58 static void setNewTextureEntryCallback( LLTextureEntry* (*callback)() );
59 static LLTextureEntry* (*sNewTextureEntryCallback)();
60
61 LLPrimTextureList();
62 virtual ~LLPrimTextureList();
63
64 void clear();
65
66 // clears current entries
67 // copies contents of other_list
68 // this is somewhat expensive, so it must be called explicitly
69 void copy(const LLPrimTextureList& other_list);
70
71 // clears current copies
72 // takes contents of other_list
73 // clears other_list
74 void take(LLPrimTextureList& other_list);
75
76 // copies LLTextureEntry 'te'
77 // returns TEM_CHANGE_TEXTURE if successful, otherwise TEM_CHANGE_NONE
78 S32 copyTexture(const U8 index, const LLTextureEntry& te);
79
80 // takes ownership of LLTextureEntry* 'te'
81 // returns TEM_CHANGE_TEXTURE if successful, otherwise TEM_CHANGE_NONE
82 // IMPORTANT! -- if you use this function you must check the return value
83 S32 takeTexture(const U8 index, LLTextureEntry* te);
84
85// // copies contents of 'entry' and stores it in 'index' slot
86// void copyTexture(const U8 index, const LLTextureEntry* entry);
87
88 // returns pointer to texture at 'index' slot
89 LLTextureEntry* getTexture(const U8 index) const;
90
91 S32 setID(const U8 index, const LLUUID& id);
92 S32 setColor(const U8 index, const LLColor3& color);
93 S32 setColor(const U8 index, const LLColor4& color);
94 S32 setAlpha(const U8 index, const F32 alpha);
95 S32 setScale(const U8 index, const F32 s, const F32 t);
96 S32 setScaleS(const U8 index, const F32 s);
97 S32 setScaleT(const U8 index, const F32 t);
98 S32 setOffset(const U8 index, const F32 s, const F32 t);
99 S32 setOffsetS(const U8 index, const F32 s);
100 S32 setOffsetT(const U8 index, const F32 t);
101 S32 setRotation(const U8 index, const F32 r);
102 S32 setBumpShinyFullbright(const U8 index, const U8 bump);
103 S32 setMediaTexGen(const U8 index, const U8 media);
104 S32 setBumpMap(const U8 index, const U8 bump);
105 S32 setBumpShiny(const U8 index, const U8 bump_shiny);
106 S32 setTexGen(const U8 index, const U8 texgen);
107 S32 setShiny(const U8 index, const U8 shiny);
108 S32 setFullbright(const U8 index, const U8 t);
109 S32 setMediaFlags(const U8 index, const U8 media_flags);
110 S32 setGlow(const U8 index, const F32 glow);
111
112 S32 size() const;
113
114// void forceResize(S32 new_size);
115 void setSize(S32 new_size);
116
117 void setAllIDs(const LLUUID& id);
118protected:
119 texture_list_t mEntryList;
120private:
121 LLPrimTextureList(const LLPrimTextureList& other_list)
122 {
123 // private so that it can't be used
124 }
125};
126
127#endif
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}
diff --git a/linden/indra/llprimitive/lltextureentry.h b/linden/indra/llprimitive/lltextureentry.h
index c562545..e70673e 100644..100755
--- a/linden/indra/llprimitive/lltextureentry.h
+++ b/linden/indra/llprimitive/lltextureentry.h
@@ -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
@@ -37,9 +37,13 @@
37#include "v4color.h" 37#include "v4color.h"
38#include "llsd.h" 38#include "llsd.h"
39 39
40// These bits are used while unpacking TEM messages to tell which aspects of
41// the texture entry changed.
42const S32 TEM_CHANGE_NONE = 0x0;
40const S32 TEM_CHANGE_COLOR = 0x1; 43const S32 TEM_CHANGE_COLOR = 0x1;
41const S32 TEM_CHANGE_TEXTURE = 0x2; 44const S32 TEM_CHANGE_TEXTURE = 0x2;
42const S32 TEM_INVALID = 0x4; 45const S32 TEM_CHANGE_MEDIA = 0x4;
46const S32 TEM_INVALID = 0x8;
43 47
44const S32 TEM_BUMPMAP_COUNT = 32; 48const S32 TEM_BUMPMAP_COUNT = 32;
45 49
@@ -64,10 +68,13 @@ const S32 TEM_MEDIA_MASK = 0x01;
64const S32 TEM_TEX_GEN_MASK = 0x06; 68const S32 TEM_TEX_GEN_MASK = 0x06;
65const S32 TEM_TEX_GEN_SHIFT = 1; 69const S32 TEM_TEX_GEN_SHIFT = 1;
66 70
71// forward declarations
72class LLMediaEntry;
67 73
68class LLTextureEntry 74class LLTextureEntry
69{ 75{
70public: 76public:
77 static LLTextureEntry* newTextureEntry();
71 78
72 typedef enum e_texgen 79 typedef enum e_texgen
73 { 80 {
@@ -82,14 +89,18 @@ public:
82 LLTextureEntry(const LLTextureEntry &rhs); 89 LLTextureEntry(const LLTextureEntry &rhs);
83 90
84 LLTextureEntry &operator=(const LLTextureEntry &rhs); 91 LLTextureEntry &operator=(const LLTextureEntry &rhs);
85 ~LLTextureEntry(); 92 virtual ~LLTextureEntry();
86 93
87 bool operator==(const LLTextureEntry &rhs) const; 94 bool operator==(const LLTextureEntry &rhs) const;
88 bool operator!=(const LLTextureEntry &rhs) const; 95 bool operator!=(const LLTextureEntry &rhs) const;
89 96
90 LLSD asLLSD() const; 97 LLSD asLLSD() const;
98 void asLLSD(LLSD& sd) const;
91 operator LLSD() const { return asLLSD(); } 99 operator LLSD() const { return asLLSD(); }
92 bool fromLLSD(LLSD& sd); 100 bool fromLLSD(const LLSD& sd);
101
102 virtual LLTextureEntry* newBlank() const;
103 virtual LLTextureEntry* newCopy() const;
93 104
94 void init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 offset_s, F32 offset_t, F32 rotation, U8 bump); 105 void init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 offset_s, F32 offset_t, F32 rotation, U8 bump);
95 106
@@ -99,7 +110,11 @@ public:
99 S32 setColor(const LLColor3 &color); 110 S32 setColor(const LLColor3 &color);
100 S32 setAlpha(const F32 alpha); 111 S32 setAlpha(const F32 alpha);
101 S32 setScale(F32 s, F32 t); 112 S32 setScale(F32 s, F32 t);
113 S32 setScaleS(F32 s);
114 S32 setScaleT(F32 t);
102 S32 setOffset(F32 s, F32 t); 115 S32 setOffset(F32 s, F32 t);
116 S32 setOffsetS(F32 s);
117 S32 setOffsetT(F32 t);
103 S32 setRotation(F32 theta); 118 S32 setRotation(F32 theta);
104 119
105 S32 setBumpmap(U8 bump); 120 S32 setBumpmap(U8 bump);
@@ -113,7 +128,7 @@ public:
113 S32 setMediaTexGen(U8 media); 128 S32 setMediaTexGen(U8 media);
114 S32 setGlow(F32 glow); 129 S32 setGlow(F32 glow);
115 130
116 const LLUUID &getID() const { return mID; } 131 virtual const LLUUID &getID() const { return mID; }
117 const LLColor4 &getColor() const { return mColor; } 132 const LLColor4 &getColor() const { return mColor; }
118 void getScale(F32 *s, F32 *t) const { *s = mScaleS; *t = mScaleT; } 133 void getScale(F32 *s, F32 *t) const { *s = mScaleS; *t = mScaleT; }
119 void getOffset(F32 *s, F32 *t) const { *s = mOffsetS; *t = mOffsetT; } 134 void getOffset(F32 *s, F32 *t) const { *s = mOffsetS; *t = mOffsetT; }
@@ -130,9 +145,37 @@ public:
130 U8 getTexGen() const { return mMediaFlags & TEM_TEX_GEN_MASK; } 145 U8 getTexGen() const { return mMediaFlags & TEM_TEX_GEN_MASK; }
131 U8 getMediaTexGen() const { return mMediaFlags; } 146 U8 getMediaTexGen() const { return mMediaFlags; }
132 F32 getGlow() const { return mGlow; } 147 F32 getGlow() const { return mGlow; }
148
149 // *NOTE: it is possible for hasMedia() to return true, but getMediaData() to return NULL.
150 // CONVERSELY, it is also possible for hasMedia() to return false, but getMediaData()
151 // to NOT return NULL.
152 bool hasMedia() const { return (bool)(mMediaFlags & MF_HAS_MEDIA); }
153 LLMediaEntry* getMediaData() const { return mMediaEntry; }
154
155 // Completely change the media data on this texture entry.
156 void setMediaData(const LLMediaEntry &media_entry);
157 // Returns true if media data was updated, false if it was cleared
158 bool updateMediaData(const LLSD& media_data);
159 // Clears media data, and sets the media flags bit to 0
160 void clearMediaData();
161 // Merges the given LLSD of media fields with this media entry.
162 // Only those fields that are set that match the keys in
163 // LLMediaEntry will be affected. If no fields are set or if
164 // the LLSD is undefined, this is a no-op.
165 void mergeIntoMediaData(const LLSD& media_fields);
166
167 // Takes a media version string (an empty string or a previously-returned string)
168 // and returns a "touched" string, touched by agent_id
169 static std::string touchMediaVersionString(const std::string &in_version, const LLUUID &agent_id);
170 // Given a media version string, return the version
171 static U32 getVersionFromMediaVersionString(const std::string &version_string);
172 // Given a media version string, return the UUID of the agent
173 static LLUUID getAgentIDFromMediaVersionString(const std::string &version_string);
174 // Return whether or not the given string is actually a media version
175 static bool isMediaVersionString(const std::string &version_string);
133 176
134 // Media flags 177 // Media flags
135 enum { MF_NONE = 0x0, MF_WEB_PAGE = 0x1 }; 178 enum { MF_NONE = 0x0, MF_HAS_MEDIA = 0x1 };
136 179
137public: 180public:
138 F32 mScaleS; // S, T offset 181 F32 mScaleS; // S, T offset
@@ -142,6 +185,14 @@ public:
142 F32 mRotation; // anti-clockwise rotation in rad about the bottom left corner 185 F32 mRotation; // anti-clockwise rotation in rad about the bottom left corner
143 186
144 static const LLTextureEntry null; 187 static const LLTextureEntry null;
188
189 // LLSD key defines
190 static const char* OBJECT_ID_KEY;
191 static const char* OBJECT_MEDIA_DATA_KEY;
192 static const char* MEDIA_VERSION_KEY;
193 static const char* TEXTURE_INDEX_KEY;
194 static const char* TEXTURE_MEDIA_DATA_KEY;
195
145protected: 196protected:
146 LLUUID mID; // Texture GUID 197 LLUUID mID; // Texture GUID
147 LLColor4 mColor; 198 LLColor4 mColor;
@@ -149,6 +200,9 @@ protected:
149 U8 mMediaFlags; // replace with web page, movie, etc. 200 U8 mMediaFlags; // replace with web page, movie, etc.
150 F32 mGlow; 201 F32 mGlow;
151 202
203 // Note the media data is not sent via the same message structure as the rest of the TE
204 LLMediaEntry* mMediaEntry; // The media data for the face
205
152 // NOTE: when adding new data to this class, in addition to adding it to the serializers asLLSD/fromLLSD and the 206 // NOTE: when adding new data to this class, in addition to adding it to the serializers asLLSD/fromLLSD and the
153 // message packers (e.g. LLPrimitive::packTEMessage) you must also implement its copy in LLPrimitive::copyTEs() 207 // message packers (e.g. LLPrimitive::packTEMessage) you must also implement its copy in LLPrimitive::copyTEs()
154 208
diff --git a/linden/indra/llprimitive/material_codes.cpp b/linden/indra/llprimitive/material_codes.cpp
new file mode 100755
index 0000000..8eb2ae7
--- /dev/null
+++ b/linden/indra/llprimitive/material_codes.cpp
@@ -0,0 +1,46 @@
1/**
2 * @file material_codes.cpp
3 * @brief Material_codes definitions
4 *
5 * $LicenseInfo:firstyear=2000&license=viewergpl$
6 *
7 * Copyright (c) 2000-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
33#include "linden_common.h"
34
35#include "material_codes.h"
36
37#include "lluuid.h"
38
39const LLUUID LL_DEFAULT_STONE_UUID("87c5765b-aa26-43eb-b8c6-c09a1ca6208e");
40const LLUUID LL_DEFAULT_METAL_UUID("6f3c53e9-ba60-4010-8f3e-30f51a762476");
41const LLUUID LL_DEFAULT_GLASS_UUID("b4ba225c-373f-446d-9f7e-6cb7b5cf9b3d");
42const LLUUID LL_DEFAULT_WOOD_UUID("89556747-24cb-43ed-920b-47caed15465f");
43const LLUUID LL_DEFAULT_FLESH_UUID("80736669-e4b9-450e-8890-d5169f988a50");
44const LLUUID LL_DEFAULT_PLASTIC_UUID("304fcb4e-7d33-4339-ba80-76d3d22dc11a");
45const LLUUID LL_DEFAULT_RUBBER_UUID("9fae0bc5-666d-477e-9f70-84e8556ec867");
46const LLUUID LL_DEFAULT_LIGHT_UUID("00000000-0000-0000-0000-000000000000");
diff --git a/linden/indra/llprimitive/material_codes.h b/linden/indra/llprimitive/material_codes.h
index e5a59a2..c63f295 100644..100755
--- a/linden/indra/llprimitive/material_codes.h
+++ b/linden/indra/llprimitive/material_codes.h
@@ -4,7 +4,7 @@
4 * 4 *
5 * $LicenseInfo:firstyear=2000&license=viewergpl$ 5 * $LicenseInfo:firstyear=2000&license=viewergpl$
6 * 6 *
7 * Copyright (c) 2000-2009, Linden Research, Inc. 7 * Copyright (c) 2000-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
@@ -33,7 +33,7 @@
33#ifndef LL_MATERIAL_CODES_H 33#ifndef LL_MATERIAL_CODES_H
34#define LL_MATERIAL_CODES_H 34#define LL_MATERIAL_CODES_H
35 35
36#include "lluuid.h" 36class LLUUID;
37 37
38 // material types 38 // material types
39const U8 LL_MCODE_STONE = 0; 39const U8 LL_MCODE_STONE = 0;
@@ -47,13 +47,14 @@ const U8 LL_MCODE_LIGHT = 7;
47const U8 LL_MCODE_END = 8; 47const U8 LL_MCODE_END = 8;
48const U8 LL_MCODE_MASK = 0x0F; 48const U8 LL_MCODE_MASK = 0x0F;
49 49
50const LLUUID LL_DEFAULT_STONE_UUID("87c5765b-aa26-43eb-b8c6-c09a1ca6208e"); 50// *NOTE: Define these in .cpp file to reduce duplicate instances
51const LLUUID LL_DEFAULT_METAL_UUID("6f3c53e9-ba60-4010-8f3e-30f51a762476"); 51extern const LLUUID LL_DEFAULT_STONE_UUID;
52const LLUUID LL_DEFAULT_GLASS_UUID("b4ba225c-373f-446d-9f7e-6cb7b5cf9b3d"); 52extern const LLUUID LL_DEFAULT_METAL_UUID;
53const LLUUID LL_DEFAULT_WOOD_UUID("89556747-24cb-43ed-920b-47caed15465f"); 53extern const LLUUID LL_DEFAULT_GLASS_UUID;
54const LLUUID LL_DEFAULT_FLESH_UUID("80736669-e4b9-450e-8890-d5169f988a50"); 54extern const LLUUID LL_DEFAULT_WOOD_UUID;
55const LLUUID LL_DEFAULT_PLASTIC_UUID("304fcb4e-7d33-4339-ba80-76d3d22dc11a"); 55extern const LLUUID LL_DEFAULT_FLESH_UUID;
56const LLUUID LL_DEFAULT_RUBBER_UUID("9fae0bc5-666d-477e-9f70-84e8556ec867"); 56extern const LLUUID LL_DEFAULT_PLASTIC_UUID;
57const LLUUID LL_DEFAULT_LIGHT_UUID("00000000-0000-0000-0000-000000000000"); 57extern const LLUUID LL_DEFAULT_RUBBER_UUID;
58extern const LLUUID LL_DEFAULT_LIGHT_UUID;
58 59
59#endif 60#endif
diff --git a/linden/indra/llprimitive/tests/llmediaentry_test.cpp b/linden/indra/llprimitive/tests/llmediaentry_test.cpp
new file mode 100755
index 0000000..89f778d
--- /dev/null
+++ b/linden/indra/llprimitive/tests/llmediaentry_test.cpp
@@ -0,0 +1,508 @@
1/**
2 * @file llmediaentry_test.cpp
3 * @brief llmediaentry unit tests
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
33#include "linden_common.h"
34#include "lltut.h"
35#if LL_WINDOWS
36#pragma warning (push)
37#pragma warning (disable : 4702) // boost::lexical_cast generates this warning
38#endif
39#include <boost/lexical_cast.hpp>
40#if LL_WINDOWS
41#pragma warning (pop)
42#endif
43#include "llstring.h"
44#include "llsdutil.h"
45#include "llsdserialize.h"
46
47#include "../llmediaentry.h"
48#include "lllslconstants.h"
49
50#define DEFAULT_MEDIA_ENTRY "<llsd>\n\
51 <map>\n\
52 <key>alt_image_enable</key>\n\
53 <boolean>0</boolean>\n\
54 <key>auto_loop</key>\n\
55 <boolean>0</boolean>\n\
56 <key>auto_play</key>\n\
57 <boolean>0</boolean>\n\
58 <key>auto_scale</key>\n\
59 <boolean>0</boolean>\n\
60 <key>auto_zoom</key>\n\
61 <boolean>0</boolean>\n\
62 <key>controls</key>\n\
63 <integer>0</integer>\n\
64 <key>current_url</key>\n\
65 <string />\n\
66 <key>first_click_interact</key>\n\
67 <boolean>0</boolean>\n\
68 <key>height_pixels</key>\n\
69 <integer>0</integer>\n\
70 <key>home_url</key>\n\
71 <string />\n\
72 <key>perms_control</key>\n\
73 <integer>7</integer>\n\
74 <key>perms_interact</key>\n\
75 <integer>7</integer>\n\
76 <key>whitelist_enable</key>\n\
77 <boolean>0</boolean>\n\
78 <key>width_pixels</key>\n\
79 <integer>0</integer>\n\
80 </map>\n\
81 </llsd>"
82
83#define EMPTY_MEDIA_ENTRY "<llsd>\n\
84 <map>\n\
85 <key>alt_image_enable</key>\n\
86 <boolean>0</boolean>\n\
87 <key>auto_loop</key>\n\
88 <boolean>0</boolean>\n\
89 <key>auto_play</key>\n\
90 <boolean>0</boolean>\n\
91 <key>auto_scale</key>\n\
92 <boolean>0</boolean>\n\
93 <key>auto_zoom</key>\n\
94 <boolean>0</boolean>\n\
95 <key>controls</key>\n\
96 <integer>0</integer>\n\
97 <key>current_url</key>\n\
98 <string />\n\
99 <key>first_click_interact</key>\n\
100 <boolean>0</boolean>\n\
101 <key>height_pixels</key>\n\
102 <integer>0</integer>\n\
103 <key>home_url</key>\n\
104 <string />\n\
105 <key>perms_control</key>\n\
106 <integer>0</integer>\n\
107 <key>perms_interact</key>\n\
108 <integer>0</integer>\n\
109 <key>whitelist_enable</key>\n\
110 <boolean>0</boolean>\n\
111 <key>width_pixels</key>\n\
112 <integer>0</integer>\n\
113 </map>\n\
114 </llsd>"
115
116#define PARTIAL_MEDIA_ENTRY(CURRENT_URL) "<llsd>\n\
117 <map>\n\
118 <key>alt_image_enable</key>\n\
119 <boolean>0</boolean>\n\
120 <key>auto_loop</key>\n\
121 <boolean>0</boolean>\n\
122 <key>auto_play</key>\n\
123 <boolean>0</boolean>\n\
124 <key>auto_scale</key>\n\
125 <boolean>0</boolean>\n\
126 <key>auto_zoom</key>\n\
127 <boolean>0</boolean>\n\
128 <key>controls</key>\n\
129 <integer>0</integer>\n\
130 <key>current_url</key>\n\
131 <string>" CURRENT_URL "</string>\n\
132 <key>first_click_interact</key>\n\
133 <boolean>0</boolean>\n\
134 <key>height_pixels</key>\n\
135 <integer>0</integer>\n\
136 <key>home_url</key>\n\
137 <string />\n\
138 <key>perms_control</key>\n\
139 <integer>0</integer>\n\
140 <key>perms_interact</key>\n\
141 <integer>0</integer>\n\
142 <key>whitelist_enable</key>\n\
143 <boolean>0</boolean>\n\
144 <key>width_pixels</key>\n\
145 <integer>0</integer>\n\
146 </map>\n\
147 </llsd>"
148
149namespace tut
150{
151 // this is fixture data that gets created before each test and destroyed
152 // after each test. this is where we put all of the setup/takedown code
153 // and data needed for each test.
154 struct MediaEntry_test
155 {
156 MediaEntry_test() {
157 emptyMediaEntryStr = EMPTY_MEDIA_ENTRY;
158 std::istringstream e(EMPTY_MEDIA_ENTRY);
159 LLSDSerialize::fromXML(emptyMediaEntryLLSD, e);
160 defaultMediaEntryStr = DEFAULT_MEDIA_ENTRY;
161 std::istringstream d(DEFAULT_MEDIA_ENTRY);
162 LLSDSerialize::fromXML(defaultMediaEntryLLSD, d);
163 }
164 std::string emptyMediaEntryStr;
165 LLSD emptyMediaEntryLLSD;
166 std::string defaultMediaEntryStr;
167 LLSD defaultMediaEntryLLSD;
168 };
169
170 typedef test_group<MediaEntry_test, 55> factory;
171 typedef factory::object object;
172}
173
174
175namespace
176{
177 // this is for naming our tests to make pretty output
178 tut::factory tf("MediaEntry Test");
179}
180
181namespace tut
182{
183 void ensure_llsd_equals(const std::string& msg, const LLSD& expected, const LLSD& actual)
184 {
185 if (!llsd_equals(expected, actual))
186 {
187 std::string message = msg;
188 message += ": actual: ";
189 message += ll_pretty_print_sd(actual);
190 message += "\n expected: ";
191 message += ll_pretty_print_sd(expected);
192 message += "\n";
193 ensure(message, false);
194 }
195 }
196
197 void ensure_string_equals(const std::string& msg, const std::string& expected, const std::string& actual)
198 {
199 if ( expected != actual )
200 {
201 std::string message = msg;
202 message += ": actual: ";
203 message += actual;
204 message += "\n expected: ";
205 message += expected;
206 message += "\n";
207 ensure(message, false);
208 }
209 }
210
211 void set_whitelist(LLMediaEntry &entry, const char *str)
212 {
213 std::vector<std::string> tokens;
214 LLStringUtil::getTokens(std::string(str), tokens, ",");
215 entry.setWhiteList(tokens);
216 }
217
218 void whitelist_test(int num, bool enable, const char *whitelist, const char *candidate_url, bool expected_pass)
219 {
220 std::string message = "Whitelist test " + boost::lexical_cast<std::string>(num);
221 LLMediaEntry entry;
222 entry.setWhiteListEnable(enable);
223 set_whitelist(entry, whitelist);
224 bool passed_whitelist = entry.checkCandidateUrl(candidate_url);
225 if (passed_whitelist != expected_pass)
226 {
227 message += " failed: expected ";
228 message += (expected_pass) ? "" : "NOT ";
229 message += "to match\nwhitelist = ";
230 message += whitelist;
231 message += "\ncandidate_url = ";
232 message += candidate_url;
233 }
234 ensure(message, expected_pass == passed_whitelist);
235 }
236
237 void whitelist_test(int num, const char *whitelist, const char *candidate_url, bool expected_pass)
238 {
239 whitelist_test(num, true, whitelist, candidate_url, expected_pass);
240 }
241 void whitelist_test(int num, const char *whitelist, const char *candidate_url)
242 {
243 whitelist_test(num, true, whitelist, candidate_url, true);
244 }
245
246 template<> template<>
247 void object::test<1>()
248 {
249 set_test_name("Test LLMediaEntry Instantiation");
250 LLMediaEntry entry;
251 ensure_llsd_equals(get_test_name() + " failed", defaultMediaEntryLLSD, entry.asLLSD());
252 }
253
254 template<> template<>
255 void object::test<2>()
256 {
257 set_test_name("Test LLMediaEntry Instantiation from LLSD");
258 LLMediaEntry entry;
259 LLSD sd;
260 entry.fromLLSD(sd);
261 ensure_llsd_equals(get_test_name() + " failed", emptyMediaEntryLLSD, entry.asLLSD());
262 }
263
264 template<> template<>
265 void object::test<3>()
266 {
267 set_test_name("Test LLMediaEntry Partial Instantiation from LLSD");
268 LLMediaEntry entry;
269 LLSD sd;
270 sd[LLMediaEntry::CURRENT_URL_KEY] = "http://www.example.com";
271 entry.fromLLSD(sd);
272 LLSD golden;
273 std::istringstream p(PARTIAL_MEDIA_ENTRY("http://www.example.com"));
274 LLSDSerialize::fromXML(golden,p);
275 ensure_llsd_equals(get_test_name() + " failed", golden, entry.asLLSD());
276 }
277
278 template<> template<>
279 void object::test<4>()
280 {
281 set_test_name("Test LLMediaEntry::asLLSD()");
282 LLMediaEntry entry;
283 LLSD sd;
284 // Put some cruft in the LLSD
285 sd[LLMediaEntry::CURRENT_URL_KEY] = "http://www.example.com";
286 LLSD whitelist;
287 whitelist.append("*.example.com");
288 sd[LLMediaEntry::WHITELIST_KEY] = whitelist;
289 entry.asLLSD(sd);
290 ensure_llsd_equals(get_test_name() + " failed", defaultMediaEntryLLSD, sd);
291 }
292
293
294 template<> template<>
295 void object::test<5>()
296 {
297 set_test_name("Test LLMediaEntry::asLLSD() -> LLMediaEntry::fromLLSD()");
298 LLMediaEntry entry1, entry2;
299 // Add a whitelist to entry2
300 std::vector<std::string> whitelist;
301 whitelist.push_back("*.example.com");
302 entry2.setWhiteList(whitelist);
303 // Render entry1 (which has no whitelist) as an LLSD
304 LLSD sd;
305 entry1.asLLSD(sd);
306 // "read" that LLSD into entry 2
307 entry2.fromLLSD(sd);
308 ensure_llsd_equals(get_test_name() + " failed", defaultMediaEntryLLSD, entry2.asLLSD());
309 }
310
311 // limit tests
312 const char *URL_OK = "http://www.example.com";
313 const char *URL_TOO_BIG = "http://www.example.com.qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq";
314
315 template<> template<>
316 void object::test<6>()
317 {
318 set_test_name("Test Limits on setting current URL");
319 LLMediaEntry entry;
320 U32 status = entry.setCurrentURL(URL_OK);
321 ensure(get_test_name() + " ok failed", status == LSL_STATUS_OK);
322 status = entry.setCurrentURL(URL_TOO_BIG);
323 ensure(get_test_name() + " ok failed", status == LSL_STATUS_BOUNDS_ERROR);
324 }
325
326 template<> template<>
327 void object::test<7>()
328 {
329 set_test_name("Test Limits on setting home URL");
330 LLMediaEntry entry;
331 U32 status = entry.setHomeURL(URL_OK);
332 ensure(get_test_name() + " ok failed", status == LSL_STATUS_OK);
333 status = entry.setHomeURL(URL_TOO_BIG);
334 ensure(get_test_name() + " ok failed", status == LSL_STATUS_BOUNDS_ERROR);
335 }
336
337 template<> template<>
338 void object::test<8>()
339 {
340 set_test_name("Test Limits on setting whitelist");
341
342 // Test a valid list
343 LLMediaEntry entry;
344 std::vector<std::string> whitelist;
345 whitelist.push_back(std::string(URL_OK));
346 S32 status = entry.setWhiteList(whitelist);
347 ensure(get_test_name() + " invalid result", status == LSL_STATUS_OK);
348 ensure(get_test_name() + " failed", whitelist == entry.getWhiteList());
349 }
350
351 template<> template<>
352 void object::test<9>()
353 {
354 set_test_name("Test Limits on setting whitelist too big");
355
356 // Test an invalid list
357 LLMediaEntry entry;
358 std::vector<std::string> whitelist, empty;
359 whitelist.push_back(std::string(URL_OK));
360 whitelist.push_back(std::string(URL_TOO_BIG));
361 S32 status = entry.setWhiteList(whitelist);
362 ensure(get_test_name() + " invalid result", status == LSL_STATUS_BOUNDS_ERROR);
363 ensure(get_test_name() + " failed", empty == entry.getWhiteList());
364 }
365
366 template<> template<>
367 void object::test<10>()
368 {
369 set_test_name("Test Limits on setting whitelist too many");
370
371 // Test an invalid list
372 LLMediaEntry entry;
373 std::vector<std::string> whitelist, empty;
374 for (int i=0; i < LLMediaEntry::MAX_WHITELIST_SIZE+1; i++) {
375 whitelist.push_back("Q");
376 }
377 S32 status = entry.setWhiteList(whitelist);
378 ensure(get_test_name() + " invalid result", status == LSL_STATUS_BOUNDS_ERROR);
379 ensure(get_test_name() + " failed", empty == entry.getWhiteList());
380 }
381
382 template<> template<>
383 void object::test<11>()
384 {
385 set_test_name("Test to make sure both setWhiteList() functions behave the same");
386
387 // Test a valid list
388 std::vector<std::string> whitelist, empty;
389 LLSD whitelist_llsd;
390 whitelist.push_back(std::string(URL_OK));
391 whitelist_llsd.append(std::string(URL_OK));
392 LLMediaEntry entry1, entry2;
393 ensure(get_test_name() + " setWhiteList(s) don't match",
394 entry1.setWhiteList(whitelist) == LSL_STATUS_OK &&
395 entry2.setWhiteList(whitelist_llsd)== LSL_STATUS_OK );
396 ensure(get_test_name() + " failed",
397 entry1.getWhiteList() == entry2.getWhiteList());
398 }
399
400 template<> template<>
401 void object::test<12>()
402 {
403 set_test_name("Test to make sure both setWhiteList() functions behave the same");
404
405 // Test an invalid list
406 std::vector<std::string> whitelist, empty;
407 LLSD whitelist_llsd;
408 whitelist.push_back(std::string(URL_OK));
409 whitelist.push_back(std::string(URL_TOO_BIG));
410 whitelist_llsd.append(std::string(URL_OK));
411 whitelist_llsd.append(std::string(URL_TOO_BIG));
412 LLMediaEntry entry1, entry2;
413 ensure(get_test_name() + " setWhiteList(s) don't match",
414 entry1.setWhiteList(whitelist) == LSL_STATUS_BOUNDS_ERROR &&
415 entry2.setWhiteList(whitelist_llsd) == LSL_STATUS_BOUNDS_ERROR);
416 ensure(get_test_name() + " failed",
417 empty == entry1.getWhiteList() &&
418 empty == entry2.getWhiteList());
419 }
420
421 template<> template<>
422 void object::test<13>()
423 {
424 set_test_name("Test to make sure both setWhiteList() functions behave the same");
425
426 // Test an invalid list, too many
427 std::vector<std::string> whitelist, empty;
428 LLSD whitelist_llsd;
429 for (int i=0; i < LLMediaEntry::MAX_WHITELIST_SIZE+1; i++) {
430 whitelist.push_back("Q");
431 whitelist_llsd.append("Q");
432 }
433 LLMediaEntry entry1, entry2;
434 ensure(get_test_name() + " invalid result",
435 entry1.setWhiteList(whitelist) == LSL_STATUS_BOUNDS_ERROR &&
436 entry2.setWhiteList(whitelist_llsd) == LSL_STATUS_BOUNDS_ERROR);
437 ensure(get_test_name() + " failed",
438 empty == entry1.getWhiteList() &&
439 empty == entry2.getWhiteList());
440 }
441
442 template<> template<>
443 void object::test<14>()
444 {
445 // Whitelist check tests
446 int n=0;
447
448 // Check the "empty whitelist" case
449 whitelist_test(++n, "", "http://www.example.com", true);
450
451 // Check the "missing scheme" case
452 whitelist_test(++n, "www.example.com", "http://www.example.com", true);
453
454 // Check the "exactly the same" case
455 whitelist_test(++n, "http://example.com", "http://example.com", true);
456
457 // Check the enable flag
458 whitelist_test(++n, false, "www.example.com", "http://www.secondlife.com", true);
459 whitelist_test(++n, true, "www.example.com", "http://www.secondlife.com", false);
460
461 // Check permutations of trailing slash:
462 whitelist_test(++n, "http://www.example.com", "http://www.example.com/", true);
463 whitelist_test(++n, "http://www.example.com/", "http://www.example.com/", true);
464 whitelist_test(++n, "http://www.example.com/", "http://www.example.com", false);
465 whitelist_test(++n, "http://www.example.com", "http://www.example.com/foobar", true);
466 whitelist_test(++n, "http://www.example.com/", "http://www.example.com/foobar", false);
467
468
469 // More cases...
470 whitelist_test(++n, "http://example.com", "http://example.com/wiki", true);
471 whitelist_test(++n, "www.example.com", "http://www.example.com/help", true);
472 whitelist_test(++n, "http://www.example.com", "http://wwwexample.com", false);
473 whitelist_test(++n, "http://www.example.com", "http://www.example.com/wiki", true);
474 whitelist_test(++n, "example.com", "http://wwwexample.com", false);
475 whitelist_test(++n, "http://www.example.com/", "http://www.amazon.com/wiki", false);
476 whitelist_test(++n, "www.example.com", "http://www.amazon.com", false);
477
478 // regexp cases
479 whitelist_test(++n, "*.example.com", "http://www.example.com", true);
480 whitelist_test(++n, "*.example.com", "http://www.amazon.com", false);
481 whitelist_test(++n, "*.example.com", "http://www.example.com/foo/bar", true);
482 whitelist_test(++n, "*.example.com", "http:/example.com/foo/bar", false);
483 whitelist_test(++n, "*example.com", "http://example.com/foo/bar", true);
484 whitelist_test(++n, "*example.com", "http://my.virus.com/foo/bar?example.com", false);
485 whitelist_test(++n, "example.com", "http://my.virus.com/foo/bar?example.com", false);
486 whitelist_test(++n, "*example.com", "http://my.virus.com/foo/bar?*example.com", false);
487 whitelist_test(++n, "http://*example.com", "http://www.example.com", true);
488 whitelist_test(++n, "http://*.example.com", "http://www.example.com", true);
489 whitelist_test(++n, "http://*.e$?^.com", "http://www.e$?^.com", true);
490 whitelist_test(++n, "*.example.com/foo/bar", "http://www.example.com/", false);
491 whitelist_test(++n, "*.example.com/foo/bar", "http://example.com/foo/bar", false);
492 whitelist_test(++n, "http://*.example.com/foo/bar", "http://www.example.com", false);
493 whitelist_test(++n, "http://*.example.com", "https://www.example.com", false);
494 whitelist_test(++n, "http*://*.example.com", "rtsp://www.example.com", false);
495 whitelist_test(++n, "http*://*.example.com", "https://www.example.com", true);
496 whitelist_test(++n, "example.com", "http://www.example.com", false);
497 whitelist_test(++n, "www.example.com", "http://www.example.com:80", false);
498 whitelist_test(++n, "www.example.com", "http://www.example.com", true);
499 whitelist_test(++n, "www.example.com/", "http://www.example.com", false);
500 whitelist_test(++n, "www.example.com/foo/bar/*", "http://www.example.com/foo/bar/baz", true);
501
502 // Path only
503 whitelist_test(++n, "/foo/*/baz", "http://www.example.com/foo/bar/baz", true);
504 whitelist_test(++n, "/foo/*/baz", "http://www.example.com/foo/bar/", false);
505 }
506
507}
508
diff --git a/linden/indra/llprimitive/tests/llmessagesystem_stub.cpp b/linden/indra/llprimitive/tests/llmessagesystem_stub.cpp
new file mode 100755
index 0000000..37a61de
--- /dev/null
+++ b/linden/indra/llprimitive/tests/llmessagesystem_stub.cpp
@@ -0,0 +1,53 @@
1/**
2 * @file llmessagesystem_stub.cpp
3 *
4 * $LicenseInfo:firstyear=2008&license=viewergpl$
5 *
6 * Copyright (c) 2008-2010, Linden Research, Inc.
7 *
8 * Second Life Viewer Source Code
9 * The source code in this file ("Source Code") is provided by Linden Lab
10 * to you under the terms of the GNU General Public License, version 2.0
11 * ("GPL"), unless you have obtained a separate licensing agreement
12 * ("Other License"), formally executed by you and Linden Lab. Terms of
13 * the GPL can be found in doc/GPL-license.txt in this distribution, or
14 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
15 *
16 * There are special exceptions to the terms and conditions of the GPL as
17 * it is applied to this Source Code. View the full text of the exception
18 * in the file doc/FLOSS-exception.txt in this software distribution, or
19 * online at
20 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
21 *
22 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above,
24 * and agree to abide by those obligations.
25 *
26 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
27 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
28 * COMPLETENESS OR PERFORMANCE.
29 * $/LicenseInfo$
30 */
31
32#include "linden_common.h"
33
34char * _PREHASH_TextureEntry;
35
36S32 LLMessageSystem::getSizeFast(char const*, char const*) const
37{
38 return 0;
39}
40
41S32 LLMessageSystem::getSizeFast(char const*, int, char const*) const
42{
43 return 0;
44}
45
46void LLMessageSystem::getBinaryDataFast(char const*, char const*, void*, int, int, int)
47{
48}
49
50void LLMessageSystem::addBinaryDataFast(char const*, void const*, int)
51{
52}
53
diff --git a/linden/indra/llprimitive/tests/llprimitive_test.cpp b/linden/indra/llprimitive/tests/llprimitive_test.cpp
new file mode 100755
index 0000000..c923442
--- /dev/null
+++ b/linden/indra/llprimitive/tests/llprimitive_test.cpp
@@ -0,0 +1,237 @@
1/**
2 * @file llprimitive_test.cpp
3 * @brief llprimitive tests
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
33#include "linden_common.h"
34
35#include "../test/lltut.h"
36
37#include "../llprimitive.h"
38
39#include "../../llmath/llvolumemgr.h"
40
41class DummyVolumeMgr : public LLVolumeMgr
42{
43public:
44 DummyVolumeMgr() : LLVolumeMgr(), mVolumeTest(NULL), mCurrDetailTest(0) {}
45 ~DummyVolumeMgr()
46 {
47 }
48
49
50 virtual LLVolume *refVolume(const LLVolumeParams &volume_params, const S32 detail)
51 {
52 if (mVolumeTest.isNull() || volume_params != mCurrParamsTest || detail != mCurrDetailTest)
53 {
54 F32 volume_detail = LLVolumeLODGroup::getVolumeScaleFromDetail(detail);
55 mVolumeTest = new LLVolume(volume_params, volume_detail, FALSE, FALSE);
56 mCurrParamsTest = volume_params;
57 mCurrDetailTest = detail;
58 return mVolumeTest;
59 }
60 else
61 {
62 return mVolumeTest;
63 }
64 }
65
66 virtual void unrefVolume(LLVolume *volumep)
67 {
68 if (mVolumeTest == volumep)
69 {
70 mVolumeTest = NULL;
71 }
72 }
73
74private:
75 LLPointer<LLVolume> mVolumeTest;
76 LLVolumeParams mCurrParamsTest;
77 S32 mCurrDetailTest;
78};
79
80class PRIMITIVE_TEST_SETUP
81{
82public:
83 PRIMITIVE_TEST_SETUP()
84 {
85 volume_manager_test = new DummyVolumeMgr();
86 LLPrimitive::setVolumeManager(volume_manager_test);
87 }
88
89 ~PRIMITIVE_TEST_SETUP()
90 {
91 LLPrimitive::cleanupVolumeManager();
92 }
93 DummyVolumeMgr * volume_manager_test;
94};
95
96namespace tut
97{
98 struct llprimitive
99 {
100 PRIMITIVE_TEST_SETUP setup_class;
101 };
102
103 typedef test_group<llprimitive> llprimitive_t;
104 typedef llprimitive_t::object llprimitive_object_t;
105 tut::llprimitive_t tut_llprimitive("llprimitive");
106
107 template<> template<>
108 void llprimitive_object_t::test<1>()
109 {
110 set_test_name("Test LLPrimitive Instantiation");
111 LLPrimitive test;
112 }
113
114 template<> template<>
115 void llprimitive_object_t::test<2>()
116 {
117 set_test_name("Test LLPrimitive PCode setter and getter.");
118 LLPrimitive test;
119 ensure_equals(test.getPCode(), 0);
120 LLPCode code = 1;
121 test.setPCode(code);
122 ensure_equals(test.getPCode(), code);
123 }
124
125 template<> template<>
126 void llprimitive_object_t::test<3>()
127 {
128 set_test_name("Test llprimitive constructor and initer.");
129 LLPCode code = 1;
130 LLPrimitive primitive;
131 primitive.init_primitive(code);
132 ensure_equals(primitive.getPCode(), code);
133 }
134
135 template<> template<>
136 void llprimitive_object_t::test<4>()
137 {
138 set_test_name("Test Static llprimitive constructor and initer.");
139 LLPCode code = 1;
140 LLPrimitive * primitive = LLPrimitive::createPrimitive(code);
141 ensure(primitive != NULL);
142 ensure_equals(primitive->getPCode(), code);
143 }
144
145 template<> template<>
146 void llprimitive_object_t::test<5>()
147 {
148 set_test_name("Test setVolume creation of new unique volume.");
149 LLPrimitive primitive;
150 LLVolumeParams params;
151
152 // Make sure volume starts off null
153 ensure(primitive.getVolume() == NULL);
154
155 // Make sure we have no texture entries before setting the volume
156 ensure_equals(primitive.getNumTEs(), 0);
157
158 // Test that GEOMETRY has not been flagged as changed.
159 ensure(!primitive.isChanged(LLXform::GEOMETRY));
160
161 // Make sure setVolume returns true
162 ensure(primitive.setVolume(params, 0, true) == TRUE);
163 LLVolume* new_volume = primitive.getVolume();
164
165 // make sure new volume was actually created
166 ensure(new_volume != NULL);
167
168 // Make sure that now that we've set the volume we have texture entries
169 ensure_not_equals(primitive.getNumTEs(), 0);
170
171 // Make sure that the number of texture entries equals the number of faces in the volume (should be 6)
172 ensure_equals(new_volume->getNumFaces(), 6);
173 ensure_equals(primitive.getNumTEs(), new_volume->getNumFaces());
174
175 // Test that GEOMETRY has been flagged as changed.
176 ensure(primitive.isChanged(LLXform::GEOMETRY));
177
178 // Run it twice to make sure it doesn't create a different one if params are the same
179 ensure(primitive.setVolume(params, 0, true) == FALSE);
180 ensure(new_volume == primitive.getVolume());
181
182 // Change the param definition and try setting it again.
183 params.setRevolutions(4);
184 ensure(primitive.setVolume(params, 0, true) == TRUE);
185
186 // Ensure that we now have a different volume
187 ensure(new_volume != primitive.getVolume());
188 }
189
190 template<> template<>
191 void llprimitive_object_t::test<6>()
192 {
193 set_test_name("Test setVolume creation of new NOT-unique volume.");
194 LLPrimitive primitive;
195 LLVolumeParams params;
196
197 // Make sure volume starts off null
198 ensure(primitive.getVolume() == NULL);
199
200 // Make sure we have no texture entries before setting the volume
201 ensure_equals(primitive.getNumTEs(), 0);
202
203 // Test that GEOMETRY has not been flagged as changed.
204 ensure(!primitive.isChanged(LLXform::GEOMETRY));
205
206 // Make sure setVolume returns true
207 ensure(primitive.setVolume(params, 0, false) == TRUE);
208
209 LLVolume* new_volume = primitive.getVolume();
210
211 // make sure new volume was actually created
212 ensure(new_volume != NULL);
213
214 // Make sure that now that we've set the volume we have texture entries
215 ensure_not_equals(primitive.getNumTEs(), 0);
216
217 // Make sure that the number of texture entries equals the number of faces in the volume (should be 6)
218 ensure_equals(new_volume->getNumFaces(), 6);
219 ensure_equals(primitive.getNumTEs(), new_volume->getNumFaces());
220
221 // Test that GEOMETRY has been flagged as changed.
222 ensure(primitive.isChanged(LLXform::GEOMETRY));
223
224 // Run it twice to make sure it doesn't create a different one if params are the same
225 ensure(primitive.setVolume(params, 0, false) == FALSE);
226 ensure(new_volume == primitive.getVolume());
227
228 // Change the param definition and try setting it again.
229 params.setRevolutions(4);
230 ensure(primitive.setVolume(params, 0, false) == TRUE);
231
232 // Ensure that we now have a different volume
233 ensure(new_volume != primitive.getVolume());
234 }
235}
236
237#include "llmessagesystem_stub.cpp"
diff --git a/linden/indra/newview/llselectmgr.cpp b/linden/indra/newview/llselectmgr.cpp
index 558d278..b2904b9 100644
--- a/linden/indra/newview/llselectmgr.cpp
+++ b/linden/indra/newview/llselectmgr.cpp
@@ -1715,7 +1715,7 @@ void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string&
1715 U8 media_flags = LLTextureEntry::MF_NONE; 1715 U8 media_flags = LLTextureEntry::MF_NONE;
1716 if (media_type == LLViewerObject::MEDIA_TYPE_WEB_PAGE) 1716 if (media_type == LLViewerObject::MEDIA_TYPE_WEB_PAGE)
1717 { 1717 {
1718 media_flags = LLTextureEntry::MF_WEB_PAGE; 1718 media_flags = LLTextureEntry::MF_HAS_MEDIA;
1719 } 1719 }
1720 1720
1721 struct f : public LLSelectedTEFunctor 1721 struct f : public LLSelectedTEFunctor