diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/llwlparamset.cpp | 403 |
1 files changed, 403 insertions, 0 deletions
diff --git a/linden/indra/newview/llwlparamset.cpp b/linden/indra/newview/llwlparamset.cpp new file mode 100644 index 0000000..d6e1f03 --- /dev/null +++ b/linden/indra/newview/llwlparamset.cpp | |||
@@ -0,0 +1,403 @@ | |||
1 | /** | ||
2 | * @file llwlparamset.cpp | ||
3 | * @brief Implementation for the LLWLParamSet class. | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2005&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2005-2008, 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 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 "llviewerprecompiledheaders.h" | ||
33 | |||
34 | #include "llwlparamset.h" | ||
35 | #include "llwlanimator.h" | ||
36 | |||
37 | #include "llfloaterwindlight.h" | ||
38 | #include "llwlparammanager.h" | ||
39 | #include "lluictrlfactory.h" | ||
40 | #include "llsliderctrl.h" | ||
41 | |||
42 | #include <llgl.h> | ||
43 | |||
44 | #include <sstream> | ||
45 | |||
46 | LLWLParamSet::LLWLParamSet(void) : | ||
47 | mName("Unnamed Preset"), | ||
48 | mCloudScrollXOffset(0.f), mCloudScrollYOffset(0.f) | ||
49 | { | ||
50 | /* REMOVE or init the LLSD | ||
51 | const std::map<std::string, LLVector4>::value_type hardcodedPreset[] = { | ||
52 | std::make_pair("lightnorm", LLVector4(0.f, 0.707f, -0.707f, 0.f)), | ||
53 | std::make_pair("sunlight_color", LLVector4(0.6f, 0.6f, 2.83f, 2.27f)), | ||
54 | std::make_pair("ambient", LLVector4(0.27f, 0.33f, 0.44f, 1.19f)), | ||
55 | std::make_pair("blue_horizon", LLVector4(0.3f, 0.4f, 0.9f, 1.f)), | ||
56 | std::make_pair("blue_density", LLVector4(0.3f, 0.4f, 0.8f, 1.f)), | ||
57 | std::make_pair("haze_horizon", LLVector4(0.6f, 0.6f, 0.6f, 1.f)), | ||
58 | std::make_pair("haze_density", LLVector4(0.3f, 0.3f, 0.3f, 1.f)), | ||
59 | std::make_pair("cloud_shadow", LLVector4(0.f, 0.f, 0.f, 0.f)), | ||
60 | std::make_pair("density_multiplier", LLVector4(0.001f, 0.001f, 0.001f, 0.001f)), | ||
61 | std::make_pair("distance_multiplier", LLVector4(1.f, 1.f, 1.f, 1.f)), | ||
62 | std::make_pair("max_y", LLVector4(600.f, 600.f, 600.f, 0.f)), | ||
63 | std::make_pair("glow", LLVector4(15.f, 0.001f, -0.03125f, 0.f)), | ||
64 | std::make_pair("cloud_color", LLVector4(0.0f, 0.0f, 0.0f, 0.0f)), | ||
65 | std::make_pair("cloud_pos_density1", LLVector4(0.f, 0.f, 0.f, 1.f)), | ||
66 | std::make_pair("cloud_pos_density2", LLVector4(0.f, 0.f, 0.f, 1.f)), | ||
67 | std::make_pair("cloud_scale", LLVector4(0.42f, 0.f, 0.f, 1.f)), | ||
68 | std::make_pair("gamma", LLVector4(2.0f, 2.0f, 2.0f, 0.0f)), | ||
69 | }; | ||
70 | std::map<std::string, LLVector4>::value_type const * endHardcodedPreset = | ||
71 | hardcodedPreset + sizeof(hardcodedPreset)/sizeof(hardcodedPreset[0]); | ||
72 | |||
73 | mParamValues.insert(hardcodedPreset, endHardcodedPreset); | ||
74 | */ | ||
75 | } | ||
76 | |||
77 | void LLWLParamSet::update(LLGLSLShader * shader) const | ||
78 | { | ||
79 | for(LLSD::map_const_iterator i = mParamValues.beginMap(); | ||
80 | i != mParamValues.endMap(); | ||
81 | ++i) | ||
82 | { | ||
83 | const LLString& param = i->first; | ||
84 | |||
85 | if( param == "star_brightness" || param == "preset_num" || param == "sun_angle" || | ||
86 | param == "east_angle" || param == "enable_cloud_scroll" || | ||
87 | param == "cloud_scroll_rate" || param == "lightnorm" ) | ||
88 | { | ||
89 | continue; | ||
90 | } | ||
91 | |||
92 | if(param == "cloud_pos_density1") | ||
93 | { | ||
94 | LLVector4 val; | ||
95 | val.mV[0] = F32(i->second[0].asReal()) + mCloudScrollXOffset; | ||
96 | val.mV[1] = F32(i->second[1].asReal()) + mCloudScrollYOffset; | ||
97 | val.mV[2] = (F32) i->second[2].asReal(); | ||
98 | val.mV[3] = (F32) i->second[3].asReal(); | ||
99 | |||
100 | shader->uniform4fv(param, 1, val.mV); | ||
101 | } | ||
102 | else | ||
103 | { | ||
104 | LLVector4 val; | ||
105 | |||
106 | // handle all the different cases | ||
107 | if(i->second.isArray() && i->second.size() == 4) | ||
108 | { | ||
109 | val.mV[0] = (F32) i->second[0].asReal(); | ||
110 | val.mV[1] = (F32) i->second[1].asReal(); | ||
111 | val.mV[2] = (F32) i->second[2].asReal(); | ||
112 | val.mV[3] = (F32) i->second[3].asReal(); | ||
113 | } | ||
114 | else if(i->second.isReal()) | ||
115 | { | ||
116 | val.mV[0] = (F32) i->second.asReal(); | ||
117 | } | ||
118 | else if(i->second.isInteger()) | ||
119 | { | ||
120 | val.mV[0] = (F32) i->second.asReal(); | ||
121 | } | ||
122 | else if(i->second.isBoolean()) | ||
123 | { | ||
124 | val.mV[0] = i->second.asBoolean(); | ||
125 | } | ||
126 | |||
127 | |||
128 | shader->uniform4fv(param, 1, val.mV); | ||
129 | } | ||
130 | } | ||
131 | } | ||
132 | |||
133 | void LLWLParamSet::set(const char * paramName, float x) | ||
134 | { | ||
135 | // handle case where no array | ||
136 | if(mParamValues[paramName].isReal()) | ||
137 | { | ||
138 | mParamValues[paramName] = x; | ||
139 | } | ||
140 | |||
141 | // handle array | ||
142 | else if(mParamValues[paramName].isArray() && | ||
143 | mParamValues[paramName][0].isReal()) | ||
144 | { | ||
145 | mParamValues[paramName][0] = x; | ||
146 | } | ||
147 | } | ||
148 | |||
149 | void LLWLParamSet::set(const char * paramName, float x, float y) { | ||
150 | mParamValues[paramName][0] = x; | ||
151 | mParamValues[paramName][1] = y; | ||
152 | } | ||
153 | |||
154 | void LLWLParamSet::set(const char * paramName, float x, float y, float z) | ||
155 | { | ||
156 | mParamValues[paramName][0] = x; | ||
157 | mParamValues[paramName][1] = y; | ||
158 | mParamValues[paramName][2] = z; | ||
159 | } | ||
160 | |||
161 | void LLWLParamSet::set(const char * paramName, float x, float y, float z, float w) | ||
162 | { | ||
163 | mParamValues[paramName][0] = x; | ||
164 | mParamValues[paramName][1] = y; | ||
165 | mParamValues[paramName][2] = z; | ||
166 | mParamValues[paramName][3] = w; | ||
167 | } | ||
168 | |||
169 | void LLWLParamSet::set(const char * paramName, const float * val) | ||
170 | { | ||
171 | mParamValues[paramName][0] = val[0]; | ||
172 | mParamValues[paramName][1] = val[1]; | ||
173 | mParamValues[paramName][2] = val[2]; | ||
174 | mParamValues[paramName][3] = val[3]; | ||
175 | } | ||
176 | |||
177 | void LLWLParamSet::set(const char * paramName, const LLVector4 & val) | ||
178 | { | ||
179 | mParamValues[paramName][0] = val.mV[0]; | ||
180 | mParamValues[paramName][1] = val.mV[1]; | ||
181 | mParamValues[paramName][2] = val.mV[2]; | ||
182 | mParamValues[paramName][3] = val.mV[3]; | ||
183 | } | ||
184 | |||
185 | void LLWLParamSet::set(const char * paramName, const LLColor4 & val) | ||
186 | { | ||
187 | mParamValues[paramName][0] = val.mV[0]; | ||
188 | mParamValues[paramName][1] = val.mV[1]; | ||
189 | mParamValues[paramName][2] = val.mV[2]; | ||
190 | mParamValues[paramName][3] = val.mV[3]; | ||
191 | } | ||
192 | |||
193 | LLVector4 LLWLParamSet::getVector(const char * paramName, bool& error) | ||
194 | { | ||
195 | |||
196 | // test to see if right type | ||
197 | LLSD cur_val = mParamValues.get(paramName); | ||
198 | if (!cur_val.isArray()) | ||
199 | { | ||
200 | error = true; | ||
201 | return LLVector4(0,0,0,0); | ||
202 | } | ||
203 | |||
204 | LLVector4 val; | ||
205 | val.mV[0] = (F32) cur_val[0].asReal(); | ||
206 | val.mV[1] = (F32) cur_val[1].asReal(); | ||
207 | val.mV[2] = (F32) cur_val[2].asReal(); | ||
208 | val.mV[3] = (F32) cur_val[3].asReal(); | ||
209 | |||
210 | error = false; | ||
211 | return val; | ||
212 | } | ||
213 | |||
214 | F32 LLWLParamSet::getFloat(const char * paramName, bool& error) | ||
215 | { | ||
216 | |||
217 | // test to see if right type | ||
218 | LLSD cur_val = mParamValues.get(paramName); | ||
219 | if (cur_val.isArray() && cur_val.size() != 0) | ||
220 | { | ||
221 | error = false; | ||
222 | return (F32) cur_val[0].asReal(); | ||
223 | } | ||
224 | |||
225 | if(cur_val.isReal()) | ||
226 | { | ||
227 | error = false; | ||
228 | return (F32) cur_val.asReal(); | ||
229 | } | ||
230 | |||
231 | error = true; | ||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | |||
236 | |||
237 | void LLWLParamSet::setSunAngle(float val) | ||
238 | { | ||
239 | // keep range 0 - 2pi | ||
240 | if(val > F_TWO_PI || val < 0) | ||
241 | { | ||
242 | F32 num = val / F_TWO_PI; | ||
243 | num -= floor(num); | ||
244 | val = F_TWO_PI * num; | ||
245 | } | ||
246 | |||
247 | mParamValues["sun_angle"] = val; | ||
248 | } | ||
249 | |||
250 | |||
251 | void LLWLParamSet::setEastAngle(float val) | ||
252 | { | ||
253 | // keep range 0 - 2pi | ||
254 | if(val > F_TWO_PI || val < 0) | ||
255 | { | ||
256 | F32 num = val / F_TWO_PI; | ||
257 | num -= floor(num); | ||
258 | val = F_TWO_PI * num; | ||
259 | } | ||
260 | |||
261 | mParamValues["east_angle"] = val; | ||
262 | } | ||
263 | |||
264 | |||
265 | void LLWLParamSet::mix(LLWLParamSet& src, LLWLParamSet& dest, F32 weight) | ||
266 | { | ||
267 | // set up the iterators | ||
268 | LLSD::map_iterator cIt = mParamValues.beginMap(); | ||
269 | |||
270 | // keep cloud positions and coverage the same | ||
271 | /// TODO masking will do this later | ||
272 | F32 cloudPos1X = (F32) mParamValues["cloud_pos_density1"][0].asReal(); | ||
273 | F32 cloudPos1Y = (F32) mParamValues["cloud_pos_density1"][1].asReal(); | ||
274 | F32 cloudPos2X = (F32) mParamValues["cloud_pos_density2"][0].asReal(); | ||
275 | F32 cloudPos2Y = (F32) mParamValues["cloud_pos_density2"][1].asReal(); | ||
276 | F32 cloudCover = (F32) mParamValues["cloud_shadow"][0].asReal(); | ||
277 | |||
278 | LLSD srcVal; | ||
279 | LLSD destVal; | ||
280 | |||
281 | // do the interpolation for all the ones saved as vectors | ||
282 | // skip the weird ones | ||
283 | for(; cIt != mParamValues.endMap(); cIt++) { | ||
284 | |||
285 | // check params to make sure they're actually there | ||
286 | if(src.mParamValues.has(cIt->first)) | ||
287 | { | ||
288 | srcVal = src.mParamValues[cIt->first]; | ||
289 | } | ||
290 | else | ||
291 | { | ||
292 | continue; | ||
293 | } | ||
294 | |||
295 | if(dest.mParamValues.has(cIt->first)) | ||
296 | { | ||
297 | destVal = dest.mParamValues[cIt->first]; | ||
298 | } | ||
299 | else | ||
300 | { | ||
301 | continue; | ||
302 | } | ||
303 | |||
304 | // skip if not a vector | ||
305 | if(!cIt->second.isArray()) | ||
306 | { | ||
307 | continue; | ||
308 | } | ||
309 | |||
310 | // only Real vectors allowed | ||
311 | if(!cIt->second[0].isReal()) | ||
312 | { | ||
313 | continue; | ||
314 | } | ||
315 | |||
316 | // make sure all the same size | ||
317 | if( cIt->second.size() != srcVal.size() || | ||
318 | cIt->second.size() != destVal.size()) | ||
319 | { | ||
320 | continue; | ||
321 | } | ||
322 | |||
323 | // more error checking might be necessary; | ||
324 | |||
325 | for(int i=0; i < cIt->second.size(); ++i) | ||
326 | { | ||
327 | cIt->second[i] = (1.0f - weight) * (F32) srcVal[i].asReal() + | ||
328 | weight * (F32) destVal[i].asReal(); | ||
329 | } | ||
330 | } | ||
331 | |||
332 | // now mix the extra parameters | ||
333 | setStarBrightness((1 - weight) * (F32) src.getStarBrightness() | ||
334 | + weight * (F32) dest.getStarBrightness()); | ||
335 | |||
336 | llassert(src.getSunAngle() >= - F_PI && | ||
337 | src.getSunAngle() <= 3 * F_PI); | ||
338 | llassert(dest.getSunAngle() >= - F_PI && | ||
339 | dest.getSunAngle() <= 3 * F_PI); | ||
340 | llassert(src.getEastAngle() >= 0 && | ||
341 | src.getEastAngle() <= 4 * F_PI); | ||
342 | llassert(dest.getEastAngle() >= 0 && | ||
343 | dest.getEastAngle() <= 4 * F_PI); | ||
344 | |||
345 | // sun angle and east angle require some handling to make sure | ||
346 | // they go in circles. Yes quaternions would work better. | ||
347 | F32 srcSunAngle = src.getSunAngle(); | ||
348 | F32 destSunAngle = dest.getSunAngle(); | ||
349 | F32 srcEastAngle = src.getEastAngle(); | ||
350 | F32 destEastAngle = dest.getEastAngle(); | ||
351 | |||
352 | if(fabsf(srcSunAngle - destSunAngle) > F_PI) | ||
353 | { | ||
354 | if(srcSunAngle > destSunAngle) | ||
355 | { | ||
356 | destSunAngle += 2 * F_PI; | ||
357 | } | ||
358 | else | ||
359 | { | ||
360 | srcSunAngle += 2 * F_PI; | ||
361 | } | ||
362 | } | ||
363 | |||
364 | if(fabsf(srcEastAngle - destEastAngle) > F_PI) | ||
365 | { | ||
366 | if(srcEastAngle > destEastAngle) | ||
367 | { | ||
368 | destEastAngle += 2 * F_PI; | ||
369 | } | ||
370 | else | ||
371 | { | ||
372 | srcEastAngle += 2 * F_PI; | ||
373 | } | ||
374 | } | ||
375 | |||
376 | setSunAngle((1 - weight) * srcSunAngle + weight * destSunAngle); | ||
377 | setEastAngle((1 - weight) * srcEastAngle + weight * destEastAngle); | ||
378 | |||
379 | // now setup the sun properly | ||
380 | |||
381 | // reset those cloud positions | ||
382 | mParamValues["cloud_pos_density1"][0] = cloudPos1X; | ||
383 | mParamValues["cloud_pos_density1"][1] = cloudPos1Y; | ||
384 | mParamValues["cloud_pos_density2"][0] = cloudPos2X; | ||
385 | mParamValues["cloud_pos_density2"][1] = cloudPos2Y; | ||
386 | mParamValues["cloud_shadow"][0] = cloudCover; | ||
387 | } | ||
388 | |||
389 | void LLWLParamSet::updateCloudScrolling(void) | ||
390 | { | ||
391 | static LLTimer s_cloud_timer; | ||
392 | |||
393 | F64 delta_t = s_cloud_timer.getElapsedTimeAndResetF64(); | ||
394 | |||
395 | if(getEnableCloudScrollX()) | ||
396 | { | ||
397 | mCloudScrollXOffset += F32(delta_t * (getCloudScrollX() - 10.f) / 100.f); | ||
398 | } | ||
399 | if(getEnableCloudScrollY()) | ||
400 | { | ||
401 | mCloudScrollYOffset += F32(delta_t * (getCloudScrollY() - 10.f) / 100.f); | ||
402 | } | ||
403 | } | ||