diff options
author | Armin Weatherwax | 2010-06-14 12:27:35 +0200 |
---|---|---|
committer | Armin Weatherwax | 2010-09-23 15:40:23 +0200 |
commit | 791d4c2de7c0219392aeb625cf7940290dc1e79a (patch) | |
tree | 4050377f59ec8532a5d3ee5cc1202b38a1878c7a /linden | |
parent | port SG2.0 Mediaplugs (webkit supports flash now) (diff) | |
download | meta-impy-791d4c2de7c0219392aeb625cf7940290dc1e79a.zip meta-impy-791d4c2de7c0219392aeb625cf7940290dc1e79a.tar.gz meta-impy-791d4c2de7c0219392aeb625cf7940290dc1e79a.tar.bz2 meta-impy-791d4c2de7c0219392aeb625cf7940290dc1e79a.tar.xz |
port llprimitive from SG2.0
Diffstat (limited to 'linden')
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 | |||
38 | class LL_COMMON_API LLSD; | ||
39 | |||
40 | // vector3 | ||
41 | class LLVector3; | ||
42 | LLSD ll_sd_from_vector3(const LLVector3& vec); | ||
43 | LLVector3 ll_vector3_from_sd(const LLSD& sd, S32 start_index = 0); | ||
44 | |||
45 | // vector4 | ||
46 | class LLVector4; | ||
47 | LLSD ll_sd_from_vector4(const LLVector4& vec); | ||
48 | LLVector4 ll_vector4_from_sd(const LLSD& sd, S32 start_index = 0); | ||
49 | |||
50 | // vector3d (double) | ||
51 | class LLVector3d; | ||
52 | LLSD ll_sd_from_vector3d(const LLVector3d& vec); | ||
53 | LLVector3d ll_vector3d_from_sd(const LLSD& sd, S32 start_index = 0); | ||
54 | |||
55 | // vector2 | ||
56 | class LLVector2; | ||
57 | LLSD ll_sd_from_vector2(const LLVector2& vec); | ||
58 | LLVector2 ll_vector2_from_sd(const LLSD& sd); | ||
59 | |||
60 | // Quaternion | ||
61 | class LLQuaternion; | ||
62 | LLSD ll_sd_from_quaternion(const LLQuaternion& quat); | ||
63 | LLQuaternion ll_quaternion_from_sd(const LLSD& sd); | ||
64 | |||
65 | // color4 | ||
66 | class LLColor4; | ||
67 | LLSD ll_sd_from_color4(const LLColor4& c); | ||
68 | LLColor4 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 | ||
18 | set(llprimitive_SOURCE_FILES | 18 | set(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 | ||
28 | set(llprimitive_HEADER_FILES | 31 | set(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} | |||
47 | list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES}) | 52 | list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES}) |
48 | 53 | ||
49 | add_library (llprimitive ${llprimitive_SOURCE_FILES}) | 54 | add_library (llprimitive ${llprimitive_SOURCE_FILES}) |
55 | |||
56 | #add unit tests | ||
57 | INCLUDE(LLAddBuildTest) | ||
58 | SET(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; | |||
92 | F32 const LLMaterialTable::DEFAULT_RESTITUTION = 0.4f; | 92 | F32 const LLMaterialTable::DEFAULT_RESTITUTION = 0.4f; |
93 | 93 | ||
94 | LLMaterialTable::LLMaterialTable() | 94 | LLMaterialTable::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 | ||
130 | void 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 | |||
127 | void LLMaterialTable::initBasicTable() | 141 | void 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 | ||
41 | class LLMaterialInfo; | ||
42 | |||
41 | const U32 LLMATERIAL_INFO_NAME_LENGTH = 256; | 43 | const 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; | |||
64 | const F32 DEFAULT_AVATAR_DENSITY = 445.3f; // was 444.24f; | 66 | const F32 DEFAULT_AVATAR_DENSITY = 445.3f; // was 444.24f; |
65 | 67 | ||
66 | 68 | ||
67 | class LLMaterialInfo | ||
68 | { | ||
69 | public: | ||
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 | |||
106 | class LLMaterialTable | 69 | class LLMaterialTable |
107 | { | 70 | { |
108 | public: | 71 | public: |
@@ -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 | |||
152 | class LLMaterialInfo | ||
153 | { | ||
154 | public: | ||
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 | ||
64 | const char* LLMediaEntry::ALT_IMAGE_ENABLE_KEY = MEDIA_ALT_IMAGE_ENABLE_KEY_STR; | ||
65 | const char* LLMediaEntry::CONTROLS_KEY = MEDIA_CONTROLS_KEY_STR; | ||
66 | const char* LLMediaEntry::CURRENT_URL_KEY = MEDIA_CURRENT_URL_KEY_STR; | ||
67 | const char* LLMediaEntry::HOME_URL_KEY = MEDIA_HOME_URL_KEY_STR; | ||
68 | const char* LLMediaEntry::AUTO_LOOP_KEY = MEDIA_AUTO_LOOP_KEY_STR; | ||
69 | const char* LLMediaEntry::AUTO_PLAY_KEY = MEDIA_AUTO_PLAY_KEY_STR; | ||
70 | const char* LLMediaEntry::AUTO_SCALE_KEY = MEDIA_AUTO_SCALE_KEY_STR; | ||
71 | const char* LLMediaEntry::AUTO_ZOOM_KEY = MEDIA_AUTO_ZOOM_KEY_STR; | ||
72 | const char* LLMediaEntry::FIRST_CLICK_INTERACT_KEY = MEDIA_FIRST_CLICK_INTERACT_KEY_STR; | ||
73 | const char* LLMediaEntry::WIDTH_PIXELS_KEY = MEDIA_WIDTH_PIXELS_KEY_STR; | ||
74 | const char* LLMediaEntry::HEIGHT_PIXELS_KEY = MEDIA_HEIGHT_PIXELS_KEY_STR; | ||
75 | |||
76 | // "security" fields | ||
77 | const char* LLMediaEntry::WHITELIST_ENABLE_KEY = MEDIA_WHITELIST_ENABLE_KEY_STR; | ||
78 | const char* LLMediaEntry::WHITELIST_KEY = MEDIA_WHITELIST_KEY_STR; | ||
79 | |||
80 | // "permissions" fields | ||
81 | const char* LLMediaEntry::PERMS_INTERACT_KEY = MEDIA_PERMS_INTERACT_KEY_STR; | ||
82 | const char* LLMediaEntry::PERMS_CONTROL_KEY = MEDIA_PERMS_CONTROL_KEY_STR; | ||
83 | |||
84 | #define DEFAULT_URL_PREFIX "http://" | ||
85 | |||
86 | // Constructor(s) | ||
87 | LLMediaEntry::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 | |||
107 | LLMediaEntry::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 | |||
132 | LLMediaEntry::~LLMediaEntry() | ||
133 | { | ||
134 | if (NULL != mMediaIDp) | ||
135 | { | ||
136 | delete mMediaIDp; | ||
137 | } | ||
138 | } | ||
139 | |||
140 | LLSD LLMediaEntry::asLLSD() const | ||
141 | { | ||
142 | LLSD sd; | ||
143 | asLLSD(sd); | ||
144 | return sd; | ||
145 | } | ||
146 | |||
147 | // | ||
148 | // LLSD functions | ||
149 | // | ||
150 | void 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 | ||
179 | bool LLMediaEntry::checkLLSD(const LLSD& sd) | ||
180 | { | ||
181 | if (sd.isUndefined()) return true; | ||
182 | LLMediaEntry temp; | ||
183 | return temp.fromLLSDInternal(sd, true); | ||
184 | } | ||
185 | |||
186 | void LLMediaEntry::fromLLSD(const LLSD& sd) | ||
187 | { | ||
188 | (void)fromLLSDInternal(sd, true); | ||
189 | } | ||
190 | |||
191 | void 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! | ||
199 | bool 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 | |||
276 | LLMediaEntry& 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 | |||
305 | bool 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 | |||
332 | bool 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 | |||
359 | U32 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 | |||
390 | U32 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 | |||
437 | static 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 | |||
450 | static 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 | |||
468 | bool 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 | ||
481 | bool 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 | |||
520 | U32 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 | |||
533 | U32 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 | |||
544 | U32 LLMediaEntry::setPermsInteract( U8 val ) | ||
545 | { | ||
546 | mPermsInteract = val & PERM_MASK; | ||
547 | return LSL_STATUS_OK; | ||
548 | } | ||
549 | |||
550 | U32 LLMediaEntry::setPermsControl( U8 val ) | ||
551 | { | ||
552 | mPermsControl = val & PERM_MASK; | ||
553 | return LSL_STATUS_OK; | ||
554 | } | ||
555 | |||
556 | U32 LLMediaEntry::setCurrentURL(const std::string& current_url) | ||
557 | { | ||
558 | return setCurrentURLInternal( current_url, true ); | ||
559 | } | ||
560 | |||
561 | U32 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 | |||
573 | U32 LLMediaEntry::setHomeURL(const std::string& home_url) | ||
574 | { | ||
575 | return setStringFieldWithLimit( mHomeURL, home_url, MAX_URL_LENGTH ); | ||
576 | } | ||
577 | |||
578 | U32 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 | |||
585 | U32 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 | |||
592 | const 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 | |||
42 | class LLMediaEntry | ||
43 | { | ||
44 | public: | ||
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 | |||
127 | public: | ||
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 | |||
133 | public: | ||
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 | |||
196 | private: | ||
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 | |||
202 | private: | ||
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; | |||
111 | const BOOL FLEXIBLE_OBJECT_DEFAULT_USING_COLLISION_SPHERE = FALSE; | 112 | const BOOL FLEXIBLE_OBJECT_DEFAULT_USING_COLLISION_SPHERE = FALSE; |
112 | const BOOL FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE = FALSE; | 113 | const BOOL FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE = FALSE; |
113 | 114 | ||
115 | const S32 MAX_FACE_BITS = 9; | ||
114 | 116 | ||
115 | const char *SCULPT_DEFAULT_TEXTURE = "be293869-d0d9-0a69-5989-ad27f1946fd4"; // old inverted texture: "7595d345-a24c-e7ef-f0bd-78793792133e"; | 117 | const 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 | //=============================================================== |
152 | LLPrimitive::LLPrimitive() | 154 | LLPrimitive::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 | //=============================================================== |
176 | LLPrimitive::~LLPrimitive() | 177 | LLPrimitive::~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 | ||
188 | void LLPrimitive::clearTextureList() | ||
189 | { | ||
190 | } | ||
191 | |||
192 | //=============================================================== | 192 | //=============================================================== |
193 | // static | 193 | // static |
194 | LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code) | 194 | LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code) |
@@ -212,15 +212,7 @@ LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code) | |||
212 | void LLPrimitive::init_primitive(LLPCode p_code) | 212 | void 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 | //=============================================================== |
233 | const LLTextureEntry * LLPrimitive::getTE(const U8 te_num) const | 225 | LLTextureEntry* 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 | //=============================================================== |
247 | void LLPrimitive::setNumTEs(const U8 num_tes) | 231 | void 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 | //=============================================================== |
292 | void LLPrimitive::setAllTETextures(const LLUUID &tex_id) | 237 | void 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 | //=============================================================== |
303 | void LLPrimitive::setTE(const U8 index, const LLTextureEntry &te) | 243 | void LLPrimitive::setTE(const U8 index, const LLTextureEntry& te) |
304 | { | 244 | { |
305 | mTextureList[index] = te; | 245 | mTextureList.copyTexture(index, te); |
306 | } | 246 | } |
307 | 247 | ||
308 | S32 LLPrimitive::setTETexture(const U8 te, const LLUUID &tex_id) | 248 | S32 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 | ||
320 | S32 LLPrimitive::setTEColor(const U8 te, const LLColor4 &color) | 260 | S32 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 | ||
332 | S32 LLPrimitive::setTEColor(const U8 te, const LLColor3 &color) | 273 | S32 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 | ||
344 | S32 LLPrimitive::setTEAlpha(const U8 te, const F32 alpha) | 285 | S32 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 | //=============================================================== |
357 | S32 LLPrimitive::setTEScale(const U8 te, const F32 s, const F32 t) | 298 | S32 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 |
372 | S32 LLPrimitive::setTEScaleS(const U8 te, const F32 s) | 306 | S32 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 |
388 | S32 LLPrimitive::setTEScaleT(const U8 te, const F32 t) | 314 | S32 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 | //=============================================================== |
403 | S32 LLPrimitive::setTEOffset(const U8 te, const F32 s, const F32 t) | 321 | S32 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 |
418 | S32 LLPrimitive::setTEOffsetS(const U8 te, const F32 s) | 329 | S32 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 |
434 | S32 LLPrimitive::setTEOffsetT(const U8 te, const F32 t) | 337 | S32 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 | //=============================================================== |
449 | S32 LLPrimitive::setTERotation(const U8 te, const F32 r) | 344 | S32 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 | //=============================================================== |
463 | S32 LLPrimitive::setTEBumpShinyFullbright(const U8 te, const U8 bump) | 351 | S32 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 | ||
475 | S32 LLPrimitive::setTEMediaTexGen(const U8 te, const U8 media) | 363 | S32 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 | ||
487 | S32 LLPrimitive::setTEBumpmap(const U8 te, const U8 bump) | 375 | S32 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 | ||
499 | S32 LLPrimitive::setTEBumpShiny(const U8 te, const U8 bump_shiny) | 387 | S32 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 | ||
511 | S32 LLPrimitive::setTETexGen(const U8 te, const U8 texgen) | 399 | S32 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 | ||
523 | S32 LLPrimitive::setTEShiny(const U8 te, const U8 shiny) | 411 | S32 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 | ||
535 | S32 LLPrimitive::setTEFullbright(const U8 te, const U8 fullbright) | 424 | S32 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 | ||
547 | S32 LLPrimitive::setTEMediaFlags(const U8 te, const U8 media_flags) | 437 | S32 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 | ||
559 | S32 LLPrimitive::setTEGlow(const U8 te, const F32 glow) | 449 | S32 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) | |||
877 | void LLPrimitive::copyTEs(const LLPrimitive *primitivep) | 767 | void 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 | ||
973 | BOOL 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 | ||
986 | void 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 | |||
1036 | BOOL 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 | ||
1504 | void LLPrimitive::setTextureList(LLTextureEntry *listp) | 1525 | U8 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 | |||
1535 | void LLPrimitive::copyTextureList(const LLPrimTextureList& other_list) | ||
1536 | { | ||
1537 | mTextureList.copy(other_list); | ||
1538 | } | ||
1539 | |||
1540 | void 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 | |||
1942 | LLLightImageParams::LLLightImageParams() | ||
1943 | { | ||
1944 | mType = PARAMS_LIGHT_IMAGE; | ||
1945 | mParams.setVec(F_PI*0.5f, 0.f, 0.f); | ||
1946 | } | ||
1947 | |||
1948 | BOOL LLLightImageParams::pack(LLDataPacker &dp) const | ||
1949 | { | ||
1950 | dp.packUUID(mLightTexture, "texture"); | ||
1951 | dp.packVector3(mParams, "params"); | ||
1952 | |||
1953 | return TRUE; | ||
1954 | } | ||
1955 | |||
1956 | BOOL LLLightImageParams::unpack(LLDataPacker &dp) | ||
1957 | { | ||
1958 | dp.unpackUUID(mLightTexture, "texture"); | ||
1959 | dp.unpackVector3(mParams, "params"); | ||
1960 | |||
1961 | return TRUE; | ||
1962 | } | ||
1963 | |||
1964 | bool 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 | |||
1985 | void LLLightImageParams::copy(const LLNetworkData& data) | ||
1986 | { | ||
1987 | const LLLightImageParams *param = (LLLightImageParams*)&data; | ||
1988 | mLightTexture = param->mLightTexture; | ||
1989 | mParams = param->mParams; | ||
1990 | } | ||
1991 | |||
1992 | |||
1993 | |||
1994 | LLSD LLLightImageParams::asLLSD() const | ||
1995 | { | ||
1996 | LLSD sd; | ||
1997 | |||
1998 | sd["texture"] = mLightTexture; | ||
1999 | sd["params"] = mParams.getValue(); | ||
2000 | |||
2001 | return sd; | ||
2002 | } | ||
2003 | |||
2004 | bool 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 | ||
111 | public: | 114 | public: |
@@ -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 | ||
271 | class LLLightImageParams : public LLNetworkData | ||
272 | { | ||
273 | protected: | ||
274 | LLUUID mLightTexture; | ||
275 | LLVector3 mParams; | ||
276 | |||
277 | public: | ||
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 | ||
270 | class LLPrimitive : public LLXform | 295 | class 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++ | ||
41 | LLTextureEntry* (*LLPrimTextureList::sNewTextureEntryCallback)() = &(LLTextureEntry::newTextureEntry); | ||
42 | |||
43 | // static | ||
44 | void 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 | ||
58 | LLTextureEntry* LLPrimTextureList::newTextureEntry() | ||
59 | { | ||
60 | return (*sNewTextureEntryCallback)(); | ||
61 | } | ||
62 | |||
63 | LLPrimTextureList::LLPrimTextureList() | ||
64 | { | ||
65 | } | ||
66 | |||
67 | // virtual | ||
68 | LLPrimTextureList::~LLPrimTextureList() | ||
69 | { | ||
70 | clear(); | ||
71 | } | ||
72 | |||
73 | void 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 | ||
89 | void 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 | ||
124 | void 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 | ||
134 | S32 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 | ||
161 | S32 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 | ||
176 | LLTextureEntry* 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 | |||
188 | S32 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 | |||
197 | S32 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 | |||
206 | S32 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 | |||
215 | S32 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 | |||
224 | S32 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 | |||
233 | S32 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 | |||
242 | S32 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 | |||
251 | S32 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 | |||
260 | S32 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 | |||
269 | S32 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 | |||
278 | S32 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 | |||
287 | S32 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 | |||
296 | S32 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 | |||
305 | S32 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 | |||
314 | S32 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 | |||
323 | S32 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 | |||
332 | S32 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 | |||
341 | S32 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 | |||
350 | S32 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 | |||
359 | S32 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 | |||
368 | S32 LLPrimTextureList::size() const | ||
369 | { | ||
370 | return mEntryList.size(); | ||
371 | } | ||
372 | |||
373 | // sets the size of the mEntryList container | ||
374 | void 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 | |||
414 | void 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 | |||
42 | class LLTextureEntry; | ||
43 | |||
44 | // this is a list of LLTextureEntry*'s because in practice the list's elements | ||
45 | // are of some derived class: LLFooTextureEntry | ||
46 | typedef std::vector<LLTextureEntry*> texture_list_t; | ||
47 | |||
48 | class LLPrimTextureList | ||
49 | { | ||
50 | public: | ||
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); | ||
118 | protected: | ||
119 | texture_list_t mEntryList; | ||
120 | private: | ||
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 | ||
38 | const U8 DEFAULT_BUMP_CODE = 0; // no bump or shininess | 41 | const U8 DEFAULT_BUMP_CODE = 0; // no bump or shininess |
39 | 42 | ||
40 | const LLTextureEntry LLTextureEntry::null; | 43 | const 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 | |||
58 | static const std::string MEDIA_VERSION_STRING_PREFIX = "x-mv:"; | ||
59 | |||
60 | // static | ||
61 | LLTextureEntry* LLTextureEntry::newTextureEntry() | ||
62 | { | ||
63 | return new LLTextureEntry(); | ||
64 | } | ||
65 | |||
42 | //=============================================================== | 66 | //=============================================================== |
43 | LLTextureEntry::LLTextureEntry() | 67 | LLTextureEntry::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 | ||
48 | LLTextureEntry::LLTextureEntry(const LLUUID& tex_id) | 73 | LLTextureEntry::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 | ||
53 | LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs) | 79 | LLTextureEntry::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 | ||
67 | LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs) | 98 | LLTextureEntry &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 | ||
102 | LLTextureEntry::~LLTextureEntry() | 147 | LLTextureEntry::~LLTextureEntry() |
103 | { | 148 | { |
149 | if(mMediaEntry) | ||
150 | { | ||
151 | delete mMediaEntry; | ||
152 | mMediaEntry = NULL; | ||
153 | } | ||
104 | } | 154 | } |
105 | 155 | ||
106 | bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const | 156 | bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const |
@@ -136,23 +186,33 @@ bool LLTextureEntry::operator==(const LLTextureEntry &rhs) const | |||
136 | LLSD LLTextureEntry::asLLSD() const | 186 | LLSD LLTextureEntry::asLLSD() const |
137 | { | 187 | { |
138 | LLSD sd; | 188 | LLSD sd; |
189 | asLLSD(sd); | ||
190 | return sd; | ||
191 | } | ||
139 | 192 | ||
140 | sd["imageid"] = getID(); | 193 | void 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 | ||
155 | bool LLTextureEntry::fromLLSD(LLSD& sd) | 215 | bool 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 | ||
284 | LLTextureEntry* LLTextureEntry::newBlank() const | ||
285 | { | ||
286 | return new LLTextureEntry(); | ||
287 | } | ||
288 | |||
289 | // virtual | ||
290 | LLTextureEntry* LLTextureEntry::newCopy() const | ||
291 | { | ||
292 | return new LLTextureEntry(*this); | ||
293 | } | ||
294 | |||
211 | S32 LLTextureEntry::setID(const LLUUID &tex_id) | 295 | S32 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 | ||
221 | S32 LLTextureEntry::setScale(F32 s, F32 t) | 305 | S32 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 | ||
320 | S32 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 | |||
331 | S32 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 | |||
236 | S32 LLTextureEntry::setColor(const LLColor4 &color) | 342 | S32 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 | ||
246 | S32 LLTextureEntry::setColor(const LLColor3 &color) | 352 | S32 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 | ||
257 | S32 LLTextureEntry::setAlpha(const F32 alpha) | 363 | S32 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 | ||
267 | S32 LLTextureEntry::setOffset(F32 s, F32 t) | 373 | S32 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 | ||
388 | S32 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 | |||
399 | S32 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 | |||
282 | S32 LLTextureEntry::setRotation(F32 theta) | 410 | S32 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 | ||
292 | S32 LLTextureEntry::setBumpShinyFullbright(U8 bump) | 420 | S32 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 | ||
302 | S32 LLTextureEntry::setMediaTexGen(U8 media) | 430 | S32 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 | ||
312 | S32 LLTextureEntry::setBumpmap(U8 bump) | 452 | S32 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 | ||
324 | S32 LLTextureEntry::setFullbright(U8 fullbright) | 464 | S32 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 | ||
336 | S32 LLTextureEntry::setShiny(U8 shiny) | 476 | S32 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 | ||
348 | S32 LLTextureEntry::setBumpShiny(U8 bump_shiny) | 488 | S32 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 | ||
360 | S32 LLTextureEntry::setMediaFlags(U8 media_flags) | 500 | S32 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 | ||
372 | S32 LLTextureEntry::setTexGen(U8 tex_gen) | 524 | S32 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 | ||
384 | S32 LLTextureEntry::setGlow(F32 glow) | 536 | S32 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 | |||
546 | void 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 | |||
556 | bool 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 | |||
577 | void LLTextureEntry::clearMediaData() | ||
578 | { | ||
579 | mMediaFlags &= ~MF_HAS_MEDIA; | ||
580 | if (mMediaEntry != NULL) { | ||
581 | delete mMediaEntry; | ||
582 | } | ||
583 | mMediaEntry = NULL; | ||
584 | } | ||
585 | |||
586 | void 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 | ||
599 | std::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 | ||
614 | U32 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 | ||
631 | LLUUID 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 | ||
651 | bool 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. | ||
42 | const S32 TEM_CHANGE_NONE = 0x0; | ||
40 | const S32 TEM_CHANGE_COLOR = 0x1; | 43 | const S32 TEM_CHANGE_COLOR = 0x1; |
41 | const S32 TEM_CHANGE_TEXTURE = 0x2; | 44 | const S32 TEM_CHANGE_TEXTURE = 0x2; |
42 | const S32 TEM_INVALID = 0x4; | 45 | const S32 TEM_CHANGE_MEDIA = 0x4; |
46 | const S32 TEM_INVALID = 0x8; | ||
43 | 47 | ||
44 | const S32 TEM_BUMPMAP_COUNT = 32; | 48 | const S32 TEM_BUMPMAP_COUNT = 32; |
45 | 49 | ||
@@ -64,10 +68,13 @@ const S32 TEM_MEDIA_MASK = 0x01; | |||
64 | const S32 TEM_TEX_GEN_MASK = 0x06; | 68 | const S32 TEM_TEX_GEN_MASK = 0x06; |
65 | const S32 TEM_TEX_GEN_SHIFT = 1; | 69 | const S32 TEM_TEX_GEN_SHIFT = 1; |
66 | 70 | ||
71 | // forward declarations | ||
72 | class LLMediaEntry; | ||
67 | 73 | ||
68 | class LLTextureEntry | 74 | class LLTextureEntry |
69 | { | 75 | { |
70 | public: | 76 | public: |
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 | ||
137 | public: | 180 | public: |
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 | |||
145 | protected: | 196 | protected: |
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 | |||
39 | const LLUUID LL_DEFAULT_STONE_UUID("87c5765b-aa26-43eb-b8c6-c09a1ca6208e"); | ||
40 | const LLUUID LL_DEFAULT_METAL_UUID("6f3c53e9-ba60-4010-8f3e-30f51a762476"); | ||
41 | const LLUUID LL_DEFAULT_GLASS_UUID("b4ba225c-373f-446d-9f7e-6cb7b5cf9b3d"); | ||
42 | const LLUUID LL_DEFAULT_WOOD_UUID("89556747-24cb-43ed-920b-47caed15465f"); | ||
43 | const LLUUID LL_DEFAULT_FLESH_UUID("80736669-e4b9-450e-8890-d5169f988a50"); | ||
44 | const LLUUID LL_DEFAULT_PLASTIC_UUID("304fcb4e-7d33-4339-ba80-76d3d22dc11a"); | ||
45 | const LLUUID LL_DEFAULT_RUBBER_UUID("9fae0bc5-666d-477e-9f70-84e8556ec867"); | ||
46 | const 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" | 36 | class LLUUID; |
37 | 37 | ||
38 | // material types | 38 | // material types |
39 | const U8 LL_MCODE_STONE = 0; | 39 | const U8 LL_MCODE_STONE = 0; |
@@ -47,13 +47,14 @@ const U8 LL_MCODE_LIGHT = 7; | |||
47 | const U8 LL_MCODE_END = 8; | 47 | const U8 LL_MCODE_END = 8; |
48 | const U8 LL_MCODE_MASK = 0x0F; | 48 | const U8 LL_MCODE_MASK = 0x0F; |
49 | 49 | ||
50 | const LLUUID LL_DEFAULT_STONE_UUID("87c5765b-aa26-43eb-b8c6-c09a1ca6208e"); | 50 | // *NOTE: Define these in .cpp file to reduce duplicate instances |
51 | const LLUUID LL_DEFAULT_METAL_UUID("6f3c53e9-ba60-4010-8f3e-30f51a762476"); | 51 | extern const LLUUID LL_DEFAULT_STONE_UUID; |
52 | const LLUUID LL_DEFAULT_GLASS_UUID("b4ba225c-373f-446d-9f7e-6cb7b5cf9b3d"); | 52 | extern const LLUUID LL_DEFAULT_METAL_UUID; |
53 | const LLUUID LL_DEFAULT_WOOD_UUID("89556747-24cb-43ed-920b-47caed15465f"); | 53 | extern const LLUUID LL_DEFAULT_GLASS_UUID; |
54 | const LLUUID LL_DEFAULT_FLESH_UUID("80736669-e4b9-450e-8890-d5169f988a50"); | 54 | extern const LLUUID LL_DEFAULT_WOOD_UUID; |
55 | const LLUUID LL_DEFAULT_PLASTIC_UUID("304fcb4e-7d33-4339-ba80-76d3d22dc11a"); | 55 | extern const LLUUID LL_DEFAULT_FLESH_UUID; |
56 | const LLUUID LL_DEFAULT_RUBBER_UUID("9fae0bc5-666d-477e-9f70-84e8556ec867"); | 56 | extern const LLUUID LL_DEFAULT_PLASTIC_UUID; |
57 | const LLUUID LL_DEFAULT_LIGHT_UUID("00000000-0000-0000-0000-000000000000"); | 57 | extern const LLUUID LL_DEFAULT_RUBBER_UUID; |
58 | extern 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 | |||
149 | namespace 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 | |||
175 | namespace | ||
176 | { | ||
177 | // this is for naming our tests to make pretty output | ||
178 | tut::factory tf("MediaEntry Test"); | ||
179 | } | ||
180 | |||
181 | namespace 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 | |||
34 | char * _PREHASH_TextureEntry; | ||
35 | |||
36 | S32 LLMessageSystem::getSizeFast(char const*, char const*) const | ||
37 | { | ||
38 | return 0; | ||
39 | } | ||
40 | |||
41 | S32 LLMessageSystem::getSizeFast(char const*, int, char const*) const | ||
42 | { | ||
43 | return 0; | ||
44 | } | ||
45 | |||
46 | void LLMessageSystem::getBinaryDataFast(char const*, char const*, void*, int, int, int) | ||
47 | { | ||
48 | } | ||
49 | |||
50 | void 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 | |||
41 | class DummyVolumeMgr : public LLVolumeMgr | ||
42 | { | ||
43 | public: | ||
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 | |||
74 | private: | ||
75 | LLPointer<LLVolume> mVolumeTest; | ||
76 | LLVolumeParams mCurrParamsTest; | ||
77 | S32 mCurrDetailTest; | ||
78 | }; | ||
79 | |||
80 | class PRIMITIVE_TEST_SETUP | ||
81 | { | ||
82 | public: | ||
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 | |||
96 | namespace 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 |