summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/app_settings/settings.xml22
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl332
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl192
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl14
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl12
-rw-r--r--indra/newview/lldrawpoolwlsky.cpp7
-rw-r--r--indra/newview/llenvironment.cpp62
-rw-r--r--indra/newview/llenvironment.h23
-rw-r--r--indra/newview/llfloatereditextdaycycle.cpp140
-rw-r--r--indra/newview/llfloatereditextdaycycle.h6
-rw-r--r--indra/newview/llfloaterfixedenvironment.cpp73
-rw-r--r--indra/newview/llfloaterfixedenvironment.h4
-rw-r--r--indra/newview/llfloaterland.cpp16
-rw-r--r--indra/newview/llfloaterregioninfo.cpp62
-rw-r--r--indra/newview/llfloaterregioninfo.h3
-rw-r--r--indra/newview/llglsandbox.cpp55
-rw-r--r--indra/newview/llpanelenvironment.cpp95
-rw-r--r--indra/newview/llpanelenvironment.h4
-rw-r--r--indra/newview/llsettingsvo.cpp9
-rw-r--r--indra/newview/llsettingsvo.h3
-rw-r--r--indra/newview/llsky.cpp19
-rw-r--r--indra/newview/llsky.h3
-rw-r--r--indra/newview/llviewermenu.cpp8
-rw-r--r--indra/newview/llviewerwindow.cpp16
-rw-r--r--indra/newview/llvosky.cpp24
-rw-r--r--indra/newview/llvosky.h3
-rw-r--r--indra/newview/pipeline.cpp114
-rw-r--r--indra/newview/pipeline.h1
-rw-r--r--indra/newview/skins/default/xui/en/floater_beacons.xml41
-rw-r--r--indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml8
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml2
34 files changed, 946 insertions, 460 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index d7b90e0691..94ce4f6df7 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -14805,6 +14805,28 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>sunbeacon</key>
+ <map>
+ <key>Comment</key>
+ <string>Show direction to the Sun</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>moonbeacon</key>
+ <map>
+ <key>Comment</key>
+ <string>Show direction to the Moon</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>ShowDeviceSettings</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
index f79fc012d1..07b0f2a98a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
@@ -43,6 +43,7 @@ uniform mat3 env_mat;
uniform mat3 ssao_effect_mat;
uniform vec3 sun_dir;
+uniform vec3 moon_dir;
#if HAS_SHADOW
uniform sampler2DShadow shadowMap0;
@@ -280,20 +281,20 @@ void main()
vec2 abnormal = encode_normal(norm.xyz);
norm.xyz = decode_normal(abnormal.xy);
- float da = dot(norm.xyz, sun_dir.xyz);
+ float sun_da = dot(norm.xyz, sun_dir.xyz);
+ float moon_da = dot(norm.xyz, moon_dir.xyz);
- float final_da = da;
+ float final_da = max(sun_da, moon_da);
final_da = min(final_da, shadow);
- final_da = max(final_da, 0.0f);
- final_da = min(final_da, 1.0f);
- final_da = pow(final_da, 1.0/1.3);
+ final_da = clamp(final_da, 0.0f, 1.0f);
+ final_da = pow(final_da, 1.0/1.3);
vec4 color = vec4(0,0,0,0);
color.rgb = atmosFragAmbient(color.rgb, amblit);
color.a = final_alpha;
- float ambient = abs(da);
+ float ambient = abs(final_da);
ambient *= 0.5;
ambient *= ambient;
ambient = (1.0-ambient);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
index 43f0034874..ec05dab57f 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
@@ -1,5 +1,5 @@
/**
- * @file shadowUtil.glsl
+ * @file class1/deferred/deferredUtil.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -39,6 +39,7 @@ uniform float ssao_factor;
uniform float ssao_factor_inv;
uniform vec3 sun_dir;
+uniform vec3 moon_dir;
uniform vec2 shadow_res;
uniform vec2 proj_shadow_res;
uniform mat4 shadow_matrix[6];
@@ -55,7 +56,7 @@ vec3 decode_normal(vec2 enc);
vec2 getScreenCoordinate(vec2 screenpos)
{
- vec2 sc = screenpos.xy * 2.0;
+ vec2 sc = screenpos.xy * 2.0;
if (screen_res.x > 0 && screen_res.y > 0)
{
sc /= screen_res;
@@ -72,41 +73,41 @@ vec3 getNorm(vec2 screenpos)
float getDepth(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen).r;
- return depth;
+ return depth;
}
vec4 getPosition(vec2 pos_screen)
{
float depth = getDepth(pos_screen);
- vec2 sc = getScreenCoordinate(pos_screen);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
+ vec2 sc = getScreenCoordinate(pos_screen);
+ vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
+ vec4 pos = inv_proj * ndc;
+ pos /= pos.w;
+ pos.w = 1.0;
+ return pos;
}
#if USE_DEFERRED_SHADER_API
vec4 getPositionWithDepth(vec2 pos_screen, float depth)
{
- vec2 sc = getScreenCoordinate(pos_screen);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
+ vec2 sc = getScreenCoordinate(pos_screen);
+ vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
+ vec4 pos = inv_proj * ndc;
+ pos /= pos.w;
+ pos.w = 1.0;
+ return pos;
}
float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float bias_scale, vec2 pos_screen)
{
- stc.xyz /= stc.w;
- stc.z += shadow_bias * bias_scale;
-
- stc.x = floor(stc.x*pos_screen.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
-
- float cs = shadow2D(shadowMap, stc.xyz).x;
- float shadow = cs;
+ stc.xyz /= stc.w;
+ stc.z += shadow_bias * bias_scale;
+
+ stc.x = floor(stc.x*pos_screen.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
+
+ float cs = shadow2D(shadowMap, stc.xyz).x;
+ float shadow = cs;
shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
@@ -116,85 +117,90 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float bias_scale, vec2 pos_
float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float bias_scale, vec2 pos_screen)
{
- stc.xyz /= stc.w;
- stc.z += spot_shadow_bias * bias_scale;
- stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap
-
- float cs = shadow2D(shadowMap, stc.xyz).x;
- float shadow = cs;
-
- vec2 off = 1.0/proj_shadow_res;
- off.y *= 1.5;
-
- shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x*2.0, off.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0)).x;
+ stc.xyz /= stc.w;
+ stc.z += spot_shadow_bias * bias_scale;
+ stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap
+
+ float cs = shadow2D(shadowMap, stc.xyz).x;
+ float shadow = cs;
+
+ vec2 off = 1.0/proj_shadow_res;
+ off.y *= 1.5;
+
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x*2.0, off.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0)).x;
return shadow*0.2;
}
float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen)
{
- float dp_directional_light = max(0.0, dot(sun_dir.xyz, norm));
- vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);
- vec3 shadow_pos = pos.xyz + (offset * shadow_bias);
+ float dp_sun = max(0.0, dot(sun_dir.xyz, norm));
+ float dp_moon = max(0.0, dot(moon_dir.xyz, norm));
+ float dp_directional_light = max(dp_sun,dp_moon);
+ dp_directional_light = clamp(dp_directional_light, 0.0, 1.0);
+
+ vec3 light_dir = (dp_moon > dp_sun) ? moon_dir : sun_dir;
+ vec3 offset = light_dir * (1.0-dp_directional_light);
+ vec3 shadow_pos = pos.xyz + (offset * shadow_bias);
float shadow = 0.0f;
- vec4 spos = vec4(shadow_pos,1.0);
- if (spos.z > -shadow_clip.w)
- {
- vec4 lpos;
- vec4 near_split = shadow_clip*-0.75;
- vec4 far_split = shadow_clip*-1.25;
- vec4 transition_domain = near_split-far_split;
- float weight = 0.0;
-
- if (spos.z < near_split.z)
- {
- lpos = shadow_matrix[3]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap3, lpos, 0.5, pos_screen)*w;
- weight += w;
- shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
- }
-
- if (spos.z < near_split.y && spos.z > far_split.z)
- {
- lpos = shadow_matrix[2]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
- w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap2, lpos, 0.75, pos_screen)*w;
- weight += w;
- }
-
- if (spos.z < near_split.x && spos.z > far_split.y)
- {
- lpos = shadow_matrix[1]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
- w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
- shadow += pcfShadow(shadowMap1, lpos, 0.88, pos_screen)*w;
- weight += w;
- }
-
- if (spos.z > far_split.x)
- {
- lpos = shadow_matrix[0]*spos;
-
- float w = 1.0;
- w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
-
- shadow += pcfShadow(shadowMap0, lpos, 1.0, pos_screen)*w;
- weight += w;
- }
-
- shadow /= weight;
- }
+ vec4 spos = vec4(shadow_pos,1.0);
+ if (spos.z > -shadow_clip.w)
+ {
+ vec4 lpos;
+ vec4 near_split = shadow_clip*-0.75;
+ vec4 far_split = shadow_clip*-1.25;
+ vec4 transition_domain = near_split-far_split;
+ float weight = 0.0;
+
+ if (spos.z < near_split.z)
+ {
+ lpos = shadow_matrix[3]*spos;
+
+ float w = 1.0;
+ w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
+ shadow += pcfShadow(shadowMap3, lpos, 0.5, pos_screen)*w;
+ weight += w;
+ shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
+ }
+
+ if (spos.z < near_split.y && spos.z > far_split.z)
+ {
+ lpos = shadow_matrix[2]*spos;
+
+ float w = 1.0;
+ w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
+ w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
+ shadow += pcfShadow(shadowMap2, lpos, 0.75, pos_screen)*w;
+ weight += w;
+ }
+
+ if (spos.z < near_split.x && spos.z > far_split.y)
+ {
+ lpos = shadow_matrix[1]*spos;
+
+ float w = 1.0;
+ w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
+ w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
+ shadow += pcfShadow(shadowMap1, lpos, 0.88, pos_screen)*w;
+ weight += w;
+ }
+
+ if (spos.z > far_split.x)
+ {
+ lpos = shadow_matrix[0]*spos;
+
+ float w = 1.0;
+ w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
+
+ shadow += pcfShadow(shadowMap0, lpos, 1.0, pos_screen)*w;
+ weight += w;
+ }
+
+ shadow /= weight;
+ }
return shadow;
}
@@ -203,88 +209,88 @@ float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen)
float shadow = 0.0f;
pos += norm * spot_shadow_offset;
- vec4 spos = vec4(pos,1.0);
- if (spos.z > -shadow_clip.w)
- {
- vec4 lpos;
-
- vec4 near_split = shadow_clip*-0.75;
- vec4 far_split = shadow_clip*-1.25;
- vec4 transition_domain = near_split-far_split;
- float weight = 0.0;
+ vec4 spos = vec4(pos,1.0);
+ if (spos.z > -shadow_clip.w)
+ {
+ vec4 lpos;
+
+ vec4 near_split = shadow_clip*-0.75;
+ vec4 far_split = shadow_clip*-1.25;
+ vec4 transition_domain = near_split-far_split;
+ float weight = 0.0;
{
- lpos = shadow_matrix[4 + index]*spos;
- float w = 1.0;
- w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
-
- shadow += pcfSpotShadow((index == 0) ? shadowMap4 : shadowMap5, lpos, 0.8, spos.xy)*w;
- weight += w;
- shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
- }
-
- shadow /= weight;
- }
+ lpos = shadow_matrix[4 + index]*spos;
+ float w = 1.0;
+ w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
+
+ shadow += pcfSpotShadow((index == 0) ? shadowMap4 : shadowMap5, lpos, 0.8, spos.xy)*w;
+ weight += w;
+ shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
+ }
+
+ shadow /= weight;
+ }
return shadow;
}
vec2 getKern(int i)
{
- vec2 kern[8];
- // exponentially (^2) distant occlusion samples spread around origin
- kern[0] = vec2(-1.0, 0.0) * 0.125*0.125;
- kern[1] = vec2(1.0, 0.0) * 0.250*0.250;
- kern[2] = vec2(0.0, 1.0) * 0.375*0.375;
- kern[3] = vec2(0.0, -1.0) * 0.500*0.500;
- kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625;
- kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750;
- kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875;
- kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000;
+ vec2 kern[8];
+ // exponentially (^2) distant occlusion samples spread around origin
+ kern[0] = vec2(-1.0, 0.0) * 0.125*0.125;
+ kern[1] = vec2(1.0, 0.0) * 0.250*0.250;
+ kern[2] = vec2(0.0, 1.0) * 0.375*0.375;
+ kern[3] = vec2(0.0, -1.0) * 0.500*0.500;
+ kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625;
+ kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750;
+ kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875;
+ kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000;
- return kern[i];
+ return kern[i];
}
//calculate decreases in ambient lighting when crowded out (SSAO)
float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen)
{
- float ret = 1.0;
- vec3 pos_world = pos.xyz;
- vec2 noise_reflect = texture2D(noiseMap, pos_screen.xy/128.0).xy;
-
- float angle_hidden = 0.0;
- float points = 0;
-
- float scale = min(ssao_radius / -pos_world.z, ssao_max_radius);
-
- // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?)
- for (int i = 0; i < 8; i++)
- {
- vec2 samppos_screen = pos_screen + scale * reflect(getKern(i), noise_reflect);
- vec3 samppos_world = getPosition(samppos_screen).xyz;
-
- vec3 diff = pos_world - samppos_world;
- float dist2 = dot(diff, diff);
-
- // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area
- // --> solid angle shrinking by the square of distance
- //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2
- //(k should vary inversely with # of samples, but this is taken care of later)
-
- float funky_val = (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) ? 1.0 : 0.0;
- angle_hidden = angle_hidden + funky_val * min(1.0/dist2, ssao_factor_inv);
-
- // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"
- float diffz_val = (diff.z > -1.0) ? 1.0 : 0.0;
- points = points + diffz_val;
- }
-
- angle_hidden = min(ssao_factor*angle_hidden/points, 1.0);
-
- float points_val = (points > 0.0) ? 1.0 : 0.0;
- ret = (1.0 - (points_val * angle_hidden));
-
- ret = max(ret, 0.0);
- return min(ret, 1.0);
+ float ret = 1.0;
+ vec3 pos_world = pos.xyz;
+ vec2 noise_reflect = texture2D(noiseMap, pos_screen.xy/128.0).xy;
+
+ float angle_hidden = 0.0;
+ float points = 0;
+
+ float scale = min(ssao_radius / -pos_world.z, ssao_max_radius);
+
+ // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?)
+ for (int i = 0; i < 8; i++)
+ {
+ vec2 samppos_screen = pos_screen + scale * reflect(getKern(i), noise_reflect);
+ vec3 samppos_world = getPosition(samppos_screen).xyz;
+
+ vec3 diff = pos_world - samppos_world;
+ float dist2 = dot(diff, diff);
+
+ // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area
+ // --> solid angle shrinking by the square of distance
+ //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2
+ //(k should vary inversely with # of samples, but this is taken care of later)
+
+ float funky_val = (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) ? 1.0 : 0.0;
+ angle_hidden = angle_hidden + funky_val * min(1.0/dist2, ssao_factor_inv);
+
+ // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"
+ float diffz_val = (diff.z > -1.0) ? 1.0 : 0.0;
+ points = points + diffz_val;
+ }
+
+ angle_hidden = min(ssao_factor*angle_hidden/points, 1.0);
+
+ float points_val = (points > 0.0) ? 1.0 : 0.0;
+ ret = (1.0 - (points_val * angle_hidden));
+
+ ret = max(ret, 0.0);
+ return min(ret, 1.0);
}
#endif
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
index c1c17532b8..7d5ae7c2e7 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
@@ -98,6 +98,7 @@ uniform mat3 env_mat;
uniform mat3 ssao_effect_mat;
uniform vec3 sun_dir;
+uniform vec3 moon_dir;
VARYING vec2 vary_fragcoord;
VARYING vec3 vary_position;
@@ -381,9 +382,10 @@ void main()
vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
- float da =dot(norm.xyz, sun_dir.xyz);
+ float sun_da = dot(norm.xyz, sun_dir.xyz);
+ float moon_da = dot(norm.xyz, moon_dir.xyz);
- float final_da = da;
+ float final_da = max(sun_da,moon_da);
final_da = min(final_da, shadow);
//final_da = max(final_da, diffuse.a);
final_da = max(final_da, 0.0f);
@@ -392,7 +394,7 @@ void main()
col.rgb = atmosFragAmbient(col, amblit);
- float ambient = min(abs(da), 1.0);
+ float ambient = min(abs(final_da), 1.0);
ambient *= 0.5;
ambient *= ambient;
ambient = (1.0-ambient);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
index 5813dd84ee..41eb06126b 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
@@ -56,6 +56,7 @@ uniform mat3 env_mat;
uniform mat3 ssao_effect_mat;
uniform vec3 sun_dir;
+uniform vec3 moon_dir;
VARYING vec2 vary_fragcoord;
uniform mat4 inv_proj;
@@ -104,15 +105,17 @@ void main()
float envIntensity = norm.z;
norm.xyz = decode_normal(norm.xy); // unpack norm
- float da = dot(norm.xyz, sun_dir.xyz);
+ float da_sun = dot(norm.xyz, normalize(sun_dir.xyz));
+ float da_moon = dot(norm.xyz, normalize(moon_dir.xyz));
+ float da = max(da_sun, da_moon);
float final_da = clamp(da, 0.0, 1.0);
- final_da = pow(final_da, 1.0/1.3);
+ final_da = pow(final_da, global_gamma);
vec4 diffuse = texture2DRect(diffuseRect, tc);
//convert to gamma space
- diffuse.rgb = linear_to_srgb(diffuse.rgb);
+ //diffuse.rgb = linear_to_srgb(diffuse.rgb);
vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
vec3 col;
@@ -171,8 +174,7 @@ void main()
bloom = fogged.a;
#endif
- col = srgb_to_linear(col);
-
+ //col = srgb_to_linear(col);
//col = vec3(1,0,1);
//col.g = envIntensity;
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index 541122fb18..184ac13b27 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -39,7 +39,7 @@ uniform sampler2DRect normalMap;
uniform sampler2DRect lightMap;
uniform sampler2DRect depthMap;
uniform samplerCube environmentMap;
-uniform sampler2D lightFunc;
+uniform sampler2D lightFunc;
uniform float blur_size;
uniform float blur_fidelity;
@@ -68,13 +68,12 @@ uniform vec4 shadow_clip;
uniform mat3 ssao_effect_mat;
uniform vec3 sun_dir;
+uniform vec3 moon_dir;
VARYING vec2 vary_fragcoord;
uniform mat4 inv_proj;
uniform vec2 screen_res;
-uniform int no_atmo;
-
vec3 srgb_to_linear(vec3 cs);
vec3 linear_to_srgb(vec3 cl);
vec3 decode_normal (vec2 enc);
@@ -90,20 +89,20 @@ vec3 fullbrightShinyAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten);
vec4 getPosition_d(vec2 pos_screen, float depth)
{
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
+ vec2 sc = pos_screen.xy*2.0;
+ sc /= screen_res;
+ sc -= vec2(1.0,1.0);
+ vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
+ vec4 pos = inv_proj * ndc;
+ pos /= pos.w;
+ pos.w = 1.0;
+ return pos;
}
vec4 getPosition(vec2 pos_screen)
{ //get position in screen space (world units) given window coordinate and depth map
- float depth = texture2DRect(depthMap, pos_screen.xy).r;
- return getPosition_d(pos_screen, depth);
+ float depth = texture2DRect(depthMap, pos_screen.xy).r;
+ return getPosition_d(pos_screen, depth);
}
@@ -113,92 +112,93 @@ vec4 applyWaterFogView(vec3 pos, vec4 color);
void main()
{
- vec2 tc = vary_fragcoord.xy;
- float depth = texture2DRect(depthMap, tc.xy).r;
- vec3 pos = getPosition_d(tc, depth).xyz;
- vec4 norm = texture2DRect(normalMap, tc);
- float envIntensity = norm.z;
- norm.xyz = decode_normal(norm.xy); // unpack norm
-
- float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
-
- float light_gamma = 1.0/1.3;
- da = pow(da, light_gamma);
-
- vec4 diffuse = texture2DRect(diffuseRect, tc);
-
- //convert to gamma space
- diffuse.rgb = linear_to_srgb(diffuse.rgb);
-
- vec3 col;
- float bloom = 0.0;
- {
- vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
-
- vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
- scol_ambocc = pow(scol_ambocc, vec2(light_gamma));
-
- float scol = max(scol_ambocc.r, diffuse.a);
- float ambocc = scol_ambocc.g;
+ vec2 tc = vary_fragcoord.xy;
+ float depth = texture2DRect(depthMap, tc.xy).r;
+ vec3 pos = getPosition_d(tc, depth).xyz;
+ vec4 norm = texture2DRect(normalMap, tc);
+ float envIntensity = norm.z;
+ norm.xyz = decode_normal(norm.xy); // unpack norm
+
+ float da_sun = dot(norm.xyz, normalize(sun_dir.xyz));
+ float da_moon = dot(norm.xyz, normalize(moon_dir.xyz));
+ float da = max(da_sun, da_moon);
+ da = clamp(da, 0.0, 1.0);
+
+ da = pow(da, global_gamma);
+
+ vec4 diffuse = texture2DRect(diffuseRect, tc);
+
+ //convert to gamma space
+ //diffuse.rgb = linear_to_srgb(diffuse.rgb);
+
+ vec3 col;
+ float bloom = 0.0;
+ {
+ vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
+
+ vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
+ scol_ambocc = pow(scol_ambocc, vec2(global_gamma));
+
+ float scol = max(scol_ambocc.r, diffuse.a);
+ float ambocc = scol_ambocc.g;
vec3 sunlit;
vec3 amblit;
vec3 additive;
vec3 atten;
-
- calcFragAtmospherics(pos.xyz, ambocc, sunlit, amblit, additive, atten);
-
- float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
- ambient *= 0.5;
- ambient *= ambient;
- ambient = (1.0-ambient);
-
- col.rgb = amblit;
- col.rgb *= ambient;
- col += sunlit * min(da, scol);
- col *= diffuse.rgb;
-
- vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
-
- if (spec.a > 0.0) // specular reflection
- {
- // the old infinite-sky shiny reflection
- float sa = dot(refnormpersp, sun_dir.xyz);
- vec3 dumbshiny = sunlit*scol_ambocc.r*(texture2D(lightFunc, vec2(sa, spec.a)).r);
-
- // add the two types of shiny together
- vec3 spec_contrib = dumbshiny * spec.rgb;
- bloom = dot(spec_contrib, spec_contrib) / 6;
- col += spec_contrib;
- }
-
- col = mix(col, diffuse.rgb, diffuse.a);
-
- if (envIntensity > 0.0)
- { //add environmentmap
- vec3 env_vec = env_mat * refnormpersp;
- vec3 refcol = textureCube(environmentMap, env_vec).rgb;
- col = mix(col.rgb, refcol, envIntensity);
- }
-
- if (norm.w < 0.5)
- {
- col = mix(atmosFragLighting(col, additive, atten), fullbrightAtmosTransportFrag(col, additive, atten), diffuse.a);
- col = mix(scaleSoftClipFrag(col), fullbrightScaleSoftClipFrag(col), diffuse.a);
- }
-
- #ifdef WATER_FOG
- vec4 fogged = applyWaterFogView(pos.xyz,vec4(col, bloom));
- col = fogged.rgb;
- bloom = fogged.a;
- #endif
-
- col = srgb_to_linear(col);
-
- //col = vec3(1,0,1);
- //col.g = envIntensity;
- }
-
- frag_color.rgb = col;
- frag_color.a = bloom;
+
+ calcFragAtmospherics(pos.xyz, ambocc, sunlit, amblit, additive, atten);
+
+ float ambient = dot(norm.xyz, sun_dir.xyz);
+ ambient *= 0.5;
+ ambient *= ambient;
+ ambient = (1.0-ambient);
+
+ col.rgb = amblit;
+ col.rgb *= min(ambient, max(scol, 0.5));
+
+ col += (sunlit * da) * scol;
+
+ col *= diffuse.rgb;
+
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+
+ if (spec.a > 0.0) // specular reflection
+ {
+ // the old infinite-sky shiny reflection
+ float sa = dot(refnormpersp, sun_dir.xyz);
+ vec3 dumbshiny = sunlit*scol_ambocc.r*(texture2D(lightFunc, vec2(sa, spec.a)).r);
+
+ // add the two types of shiny together
+ vec3 spec_contrib = dumbshiny * spec.rgb;
+ bloom = dot(spec_contrib, spec_contrib) / 6;
+ col += spec_contrib;
+ }
+
+ col = mix(col, diffuse.rgb, diffuse.a);
+
+ if (envIntensity > 0.0)
+ { //add environmentmap
+ vec3 env_vec = env_mat * refnormpersp;
+ vec3 refcol = textureCube(environmentMap, env_vec).rgb;
+ col = mix(col.rgb, refcol, envIntensity);
+ }
+
+ if (norm.w < 0.5)
+ {
+ col = mix(atmosFragLighting(col, additive, atten), fullbrightAtmosTransportFrag(col, additive, atten), diffuse.a);
+ col = mix(scaleSoftClipFrag(col), fullbrightScaleSoftClipFrag(col), diffuse.a);
+ }
+
+ #ifdef WATER_FOG
+ vec4 fogged = applyWaterFogView(pos.xyz,vec4(col, bloom));
+ col = fogged.rgb;
+ bloom = fogged.a;
+ #endif
+
+ //col = srgb_to_linear(col);
+
+ }
+ frag_color.rgb = col;
+ frag_color.a = bloom;
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
index aa5e99a2f7..f2d04c95fe 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
@@ -59,6 +59,7 @@ uniform mat4 inv_proj;
uniform vec2 screen_res;
uniform vec2 proj_shadow_res;
uniform vec3 sun_dir;
+uniform vec3 moon_dir;
uniform vec2 shadow_res;
uniform float shadow_bias;
@@ -138,11 +139,16 @@ void main()
return;
}*/
- float shadow = 0.0;
- float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz));
-
+ float shadow = 0.0;
+ float dp_sun = dot(norm, normalize(sun_dir.xyz));
+ float dp_moon = dot(norm, normalize(moon_dir.xyz));
+ float dp_directional_light = max(dp_sun, dp_moon);
+ dp_directional_light = clamp(dp_directional_light, 0.0, 1.0);
+
+ vec3 light_direction = (dp_moon > dp_sun) ? moon_dir : sun_dir;
+
vec3 shadow_pos = pos.xyz;
- vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);
+ vec3 offset = light_direction.xyz * (1.0-dp_directional_light);
vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0);
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
index 58f3f2f91e..fd3256e9c8 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
@@ -59,6 +59,7 @@ uniform mat4 inv_proj;
uniform vec2 screen_res;
uniform vec2 proj_shadow_res;
uniform vec3 sun_dir;
+uniform vec3 moon_dir;
uniform vec2 shadow_res;
@@ -200,10 +201,15 @@ void main()
}*/
float shadow = 0.0;
- float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz));
-
+ float dp_sun = dot(norm, normalize(sun_dir.xyz));
+ float dp_moon = dot(norm, normalize(moon_dir.xyz));
+ float dp_directional_light = max(dp_sun, dp_moon);
+ dp_directional_light = max(0.0, dp_directional_light);
+
+ vec3 light_direction = (dp_moon > dp_sun) ? moon_dir : sun_dir;
+
vec3 shadow_pos = pos.xyz;
- vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);
+ vec3 offset = light_direction.xyz * (1.0-dp_directional_light);
vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0);
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index 9ce7912c45..8904020ab9 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -395,8 +395,11 @@ void LLDrawPoolWLSky::renderStarsDeferred(void) const
void LLDrawPoolWLSky::renderSkyCloudsAdvanced(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const
{
- if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp->getCloudNoiseTex())
- {
+ if (gPipeline.canUseWindLightShaders()
+ && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS)
+ && gSky.mVOSkyp->getCloudNoiseTex()
+ && gAtmosphere)
+ {
LLGLSPipelineBlendSkyBox pipeline(true, true);
LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
index fa3afa74ca..27b4789dfd 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -76,6 +76,7 @@ namespace
const std::string KEY_DAYNAME("day_name");
const std::string KEY_DAYNAMES("day_names");
const std::string KEY_DAYOFFSET("day_offset");
+ const std::string KEY_ENVVERSION("env_version");
const std::string KEY_ISDEFAULT("is_default");
const std::string KEY_PARCELID("parcel_id");
const std::string KEY_REGIONID("region_id");
@@ -328,6 +329,8 @@ const LLUUID LLEnvironment::KNOWN_SKY_SUNSET("95882e1b-7741-f082-d9d6-3a34ec644c
const LLUUID LLEnvironment::KNOWN_SKY_MIDNIGHT("d8e50d02-a15b-17a7-3425-523bc20f67b8");
const S32 LLEnvironment::NO_TRACK(-1);
+const S32 LLEnvironment::NO_VERSION(-3); // For viewer sided change, like ENV_LOCAL. -3 since -1 and -2 are taken by parcel initial server/viewer version
+const S32 LLEnvironment::VERSION_CLEANUP(-4); // for cleanups
const F32 LLEnvironment::SUN_DELTA_YAW(F_PI); // 180deg
@@ -359,6 +362,8 @@ void LLEnvironment::initSingleton()
gAgent.addParcelChangedCallback([this]() { onParcelChange(); });
//TODO: This frequently results in one more request than we need. It isn't breaking, but should be nicer.
+ // We need to know new env version to fix this, without it we can only do full re-request
+ // Happens: on updates, on opening LLFloaterRegionInfo, on region crossing if info floater is open
LLRegionInfoModel::instance().setUpdateCallback([this]() { requestRegion(); });
gAgent.addRegionChangedCallback([this]() { onRegionChange(); });
@@ -593,7 +598,7 @@ LLEnvironment::DayInstance::ptr_t LLEnvironment::getEnvironmentInstance(LLEnviro
}
-void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset)
+void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, S32 env_version)
{
if ((env < ENV_EDIT) || (env >= ENV_DEFAULT))
{
@@ -609,11 +614,11 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSe
environment->animate();
if (!mSignalEnvChanged.empty())
- mSignalEnvChanged(env);
+ mSignalEnvChanged(env, env_version);
}
-void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironment::fixedEnvironment_t fixed)
+void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironment::fixedEnvironment_t fixed, S32 env_version)
{
if ((env < ENV_EDIT) || (env >= ENV_DEFAULT))
{
@@ -647,12 +652,12 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironm
if (!mSignalEnvChanged.empty())
- mSignalEnvChanged(env);
+ mSignalEnvChanged(env, env_version);
/*TODO: readjust environment*/
}
-void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSettingsBase::ptr_t &settings)
+void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSettingsBase::ptr_t &settings, S32 env_version)
{
DayInstance::ptr_t environment = getEnvironmentInstance(env);
@@ -699,22 +704,33 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSe
}
}
-void LLEnvironment::setEnvironment(EnvSelection_t env, const LLUUID &assetId)
+void LLEnvironment::setEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version)
{
setEnvironment(env, assetId, LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET);
}
-void LLEnvironment::setEnvironment(EnvSelection_t env, const LLUUID &assetId, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset)
+void LLEnvironment::setEnvironment(EnvSelection_t env,
+ const LLUUID &assetId,
+ LLSettingsDay::Seconds daylength,
+ LLSettingsDay::Seconds dayoffset,
+ S32 env_version)
{
LLSettingsVOBase::getSettingsAsset(assetId,
- [this, env, daylength, dayoffset](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat)
+ [this, env, daylength, dayoffset, env_version](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat)
{
- onSetEnvAssetLoaded(env, asset_id, settings, daylength, dayoffset, TRANSITION_DEFAULT, status);
+ onSetEnvAssetLoaded(env, asset_id, settings, daylength, dayoffset, TRANSITION_DEFAULT, status, env_version);
});
}
-void LLEnvironment::onSetEnvAssetLoaded(EnvSelection_t env, LLUUID asset_id, LLSettingsBase::ptr_t settings, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, LLSettingsBase::Seconds transition, S32 status)
+void LLEnvironment::onSetEnvAssetLoaded(EnvSelection_t env,
+ LLUUID asset_id,
+ LLSettingsBase::ptr_t settings,
+ LLSettingsDay::Seconds daylength,
+ LLSettingsDay::Seconds dayoffset,
+ LLSettingsBase::Seconds transition,
+ S32 status,
+ S32 env_version)
{
if (!settings || status)
{
@@ -739,7 +755,7 @@ void LLEnvironment::clearEnvironment(LLEnvironment::EnvSelection_t env)
mEnvironments[env].reset();
if (!mSignalEnvChanged.empty())
- mSignalEnvChanged(env);
+ mSignalEnvChanged(env, VERSION_CLEANUP);
/*TODO: readjust environment*/
}
@@ -1123,7 +1139,7 @@ void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentI
if (!envinfo->mDayCycle)
{
clearEnvironment(ENV_PARCEL);
- setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET);
+ setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET, envinfo->mEnvVersion);
updateEnvironment();
}
else if (envinfo->mDayCycle->isTrackEmpty(LLSettingsDay::TRACK_WATER)
@@ -1131,13 +1147,13 @@ void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentI
{
LL_WARNS("LAPRAS") << "Invalid day cycle for region" << LL_ENDL;
clearEnvironment(ENV_PARCEL);
- setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET);
+ setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET, envinfo->mEnvVersion);
updateEnvironment();
}
else
{
LL_INFOS("LAPRAS") << "Setting Region environment" << LL_ENDL;
- setEnvironment(ENV_REGION, envinfo->mDayCycle, envinfo->mDayLength, envinfo->mDayOffset);
+ setEnvironment(ENV_REGION, envinfo->mDayCycle, envinfo->mDayLength, envinfo->mDayOffset, envinfo->mEnvVersion);
mTrackAltitudes = envinfo->mAltitudes;
}
@@ -1166,7 +1182,7 @@ void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentI
}
else
{
- setEnvironment(ENV_PARCEL, envinfo->mDayCycle, envinfo->mDayLength, envinfo->mDayOffset);
+ setEnvironment(ENV_PARCEL, envinfo->mDayCycle, envinfo->mDayLength, envinfo->mDayOffset, envinfo->mEnvVersion);
}
}
@@ -1538,7 +1554,8 @@ LLEnvironment::EnvironmentInfo::EnvironmentInfo():
mIsDefault(false),
mIsLegacy(false),
mDayCycleName(),
- mNameList()
+ mNameList(),
+ mEnvVersion(INVALID_PARCEL_ENVIRONMENT_VERSION)
{
}
@@ -1594,6 +1611,17 @@ LLEnvironment::EnvironmentInfo::ptr_t LLEnvironment::EnvironmentInfo::extract(LL
}
}
+ if (environment.has(KEY_ENVVERSION))
+ {
+ LLSD version = environment[KEY_ENVVERSION];
+ pinfo->mEnvVersion = version.asInteger();
+ }
+ else
+ {
+ // can be used for region, but versions should be same
+ pinfo->mEnvVersion = pinfo->mIsDefault ? UNSET_PARCEL_ENVIRONMENT_VERSION : INVALID_PARCEL_ENVIRONMENT_VERSION;
+ }
+
return pinfo;
}
@@ -1819,7 +1847,7 @@ void LLEnvironment::setExperienceEnvironment(LLUUID experience_id, LLUUID asset_
mPushEnvironmentExpId = experience_id;
onSetEnvAssetLoaded(ENV_PUSH, asset_id, settings,
LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET,
- LLSettingsBase::Seconds(transition_time), status);
+ LLSettingsBase::Seconds(transition_time), status, NO_VERSION);
});
diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h
index 613bcdb4f8..47e0f0208b 100644
--- a/indra/newview/llenvironment.h
+++ b/indra/newview/llenvironment.h
@@ -64,6 +64,8 @@ public:
static const LLUUID KNOWN_SKY_MIDNIGHT;
static const S32 NO_TRACK;
+ static const S32 NO_VERSION;
+ static const S32 VERSION_CLEANUP;
struct EnvironmentInfo
{
@@ -84,6 +86,7 @@ public:
bool mIsLegacy;
std::string mDayCycleName;
namelist_t mNameList;
+ S32 mEnvVersion;
static ptr_t extract(LLSD);
static ptr_t extractLegacy(LLSD);
@@ -106,7 +109,7 @@ public:
typedef std::pair<LLSettingsSky::ptr_t, LLSettingsWater::ptr_t> fixedEnvironment_t;
typedef std::function<void(S32, EnvironmentInfo::ptr_t)> environment_apply_fn;
- typedef boost::signals2::signal<void(EnvSelection_t)> env_changed_signal_t;
+ typedef boost::signals2::signal<void(EnvSelection_t, S32)> env_changed_signal_t;
typedef env_changed_signal_t::slot_type env_changed_fn;
typedef std::array<F32, 4> altitude_list_t;
typedef std::vector<F32> altitudes_vect_t;
@@ -135,14 +138,14 @@ public:
EnvSelection_t getSelectedEnvironment() const { return mSelectedEnvironment; }
bool hasEnvironment(EnvSelection_t env);
- void setEnvironment(EnvSelection_t env, const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset);
- void setEnvironment(EnvSelection_t env, fixedEnvironment_t fixed);
- void setEnvironment(EnvSelection_t env, const LLSettingsBase::ptr_t &fixed);
- void setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixed) { setEnvironment(env, fixedEnvironment_t(fixed, LLSettingsWater::ptr_t())); }
- void setEnvironment(EnvSelection_t env, const LLSettingsWater::ptr_t & fixed) { setEnvironment(env, fixedEnvironment_t(LLSettingsSky::ptr_t(), fixed)); }
- void setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixeds, const LLSettingsWater::ptr_t & fixedw) { setEnvironment(env, fixedEnvironment_t(fixeds, fixedw)); }
- void setEnvironment(EnvSelection_t env, const LLUUID &assetId, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset);
- void setEnvironment(EnvSelection_t env, const LLUUID &assetId);
+ void setEnvironment(EnvSelection_t env, const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, S32 env_version = NO_VERSION);
+ void setEnvironment(EnvSelection_t env, fixedEnvironment_t fixed, S32 env_version = NO_VERSION);
+ void setEnvironment(EnvSelection_t env, const LLSettingsBase::ptr_t &fixed, S32 env_version = NO_VERSION);
+ void setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixed, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(fixed, LLSettingsWater::ptr_t()), env_version); }
+ void setEnvironment(EnvSelection_t env, const LLSettingsWater::ptr_t & fixed, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(LLSettingsSky::ptr_t(), fixed), env_version); }
+ void setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixeds, const LLSettingsWater::ptr_t & fixedw, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(fixeds, fixedw), env_version); }
+ void setEnvironment(EnvSelection_t env, const LLUUID &assetId, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, S32 env_version = NO_VERSION);
+ void setEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version = NO_VERSION);
void setSharedEnvironment();
@@ -429,7 +432,7 @@ private:
void onAgentPositionHasChanged(const LLVector3 &localpos);
- void onSetEnvAssetLoaded(EnvSelection_t env, LLUUID asset_id, LLSettingsBase::ptr_t settings, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, LLSettingsBase::Seconds transition, S32 status);
+ void onSetEnvAssetLoaded(EnvSelection_t env, LLUUID asset_id, LLSettingsBase::ptr_t settings, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, LLSettingsBase::Seconds transition, S32 status, S32 env_version);
void onUpdateParcelAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, S32 parcel_id, S32 day_length, S32 day_offset, altitudes_vect_t altitudes);
void handleEnvironmentPushClear(LLUUID experience_id, LLSD &message, F32 transition);
diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp
index a30e16ab2b..7184d07ee3 100644
--- a/indra/newview/llfloatereditextdaycycle.cpp
+++ b/indra/newview/llfloatereditextdaycycle.cpp
@@ -126,6 +126,31 @@ const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_PARCEL("parcel");
const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_REGION("region");
//=========================================================================
+
+class LLDaySettingCopiedCallback : public LLInventoryCallback
+{
+public:
+ LLDaySettingCopiedCallback(LLHandle<LLFloater> handle) : mHandle(handle) {}
+
+ virtual void fire(const LLUUID& inv_item_id)
+ {
+ if (!mHandle.isDead())
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item_id);
+ if (item)
+ {
+ LLFloaterEditExtDayCycle* floater = (LLFloaterEditExtDayCycle*)mHandle.get();
+ floater->onInventoryCreated(item->getAssetUUID(), inv_item_id);
+ }
+ }
+ }
+
+private:
+ LLHandle<LLFloater> mHandle;
+};
+
+//=========================================================================
+
LLFloaterEditExtDayCycle::LLFloaterEditExtDayCycle(const LLSD &key) :
LLFloater(key),
mFlyoutControl(nullptr),
@@ -430,7 +455,6 @@ void LLFloaterEditExtDayCycle::refresh()
mFlyoutControl->setMenuItemEnabled(ACTION_APPLY_REGION, canApplyRegion() && show_apply);
mImportButton->setEnabled(mCanMod);
- mLoadFrame->setEnabled(mCanMod);
LLFloater::refresh();
}
@@ -623,7 +647,32 @@ void LLFloaterEditExtDayCycle::onSaveAsCommit(const LLSD& notification, const LL
{
std::string settings_name = response["message"].asString();
LLStringUtil::trim(settings_name);
- doApplyCreateNewInventory(day, settings_name);
+ if (mCanMod)
+ {
+ doApplyCreateNewInventory(day, settings_name);
+ }
+ else if (mInventoryItem)
+ {
+ const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+ LLUUID parent_id = mInventoryItem->getParentUUID();
+ if (marketplacelistings_id == parent_id)
+ {
+ parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
+ }
+
+ LLPointer<LLInventoryCallback> cb = new LLDaySettingCopiedCallback(getHandle());
+ copy_inventory_item(
+ gAgent.getID(),
+ mInventoryItem->getPermissions().getOwner(),
+ mInventoryItem->getUUID(),
+ parent_id,
+ settings_name,
+ cb);
+ }
+ else
+ {
+ LL_WARNS() << "Failed to copy day setting" << LL_ENDL;
+ }
}
}
@@ -903,6 +952,7 @@ void LLFloaterEditExtDayCycle::selectTrack(U32 track_index, bool force )
mSkyTabLayoutContainer->setVisible(!show_water);
mWaterTabLayoutContainer->setVisible(show_water);
updateSlider();
+ updateLabels();
}
void LLFloaterEditExtDayCycle::selectFrame(F32 frame, F32 slop_factor)
@@ -1010,6 +1060,15 @@ void LLFloaterEditExtDayCycle::updateSkyTabs(const LLSettingsSkyPtr_t &p_sky)
}
+void LLFloaterEditExtDayCycle::updateLabels()
+{
+ std::string label_arg = (mCurrentTrack == LLSettingsDay::TRACK_WATER) ? "water_label" : "sky_label";
+
+ mAddFrameButton->setLabelArg("[FRAME]", getString(label_arg));
+ mDeleteFrameButton->setLabelArg("[FRAME]", getString(label_arg));
+ mLoadFrame->setLabelArg("[FRAME]", getString(label_arg));
+}
+
void LLFloaterEditExtDayCycle::updateButtons()
{
// This logic appears to work in reverse, the add frame button
@@ -1020,8 +1079,9 @@ void LLFloaterEditExtDayCycle::updateButtons()
//bool can_add = static_cast<bool>(settings);
//mAddFrameButton->setEnabled(can_add);
//mDeleteFrameButton->setEnabled(!can_add);
- mAddFrameButton->setEnabled(mCanMod && mFramesSlider->canAddSliders());
- mDeleteFrameButton->setEnabled(isRemovingFrameAllowed() && mCanMod);
+ mAddFrameButton->setEnabled(!mIsPlaying && isAddingFrameAllowed() && mCanMod);
+ mDeleteFrameButton->setEnabled(!mIsPlaying && isRemovingFrameAllowed() && mCanMod);
+ mLoadFrame->setEnabled(!mIsPlaying && mCanMod);
}
void LLFloaterEditExtDayCycle::updateSlider()
@@ -1327,11 +1387,20 @@ void LLFloaterEditExtDayCycle::reblendSettings()
void LLFloaterEditExtDayCycle::doApplyCreateNewInventory(const LLSettingsDay::ptr_t &day, std::string settings_name)
{
- // This method knows what sort of settings object to create.
- LLUUID parent_id = mInventoryItem ? mInventoryItem->getParentUUID() : gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
-
- LLSettingsVOBase::createInventoryItem(day, parent_id, settings_name,
+ if (mInventoryItem)
+ {
+ LLUUID parent_id = mInventoryItem->getParentUUID();
+ U32 next_owner_perm = mInventoryItem->getPermissions().getMaskNextOwner();
+ LLSettingsVOBase::createInventoryItem(day, next_owner_perm, parent_id, settings_name,
+ [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
+ }
+ else
+ {
+ LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
+ // This method knows what sort of settings object to create.
+ LLSettingsVOBase::createInventoryItem(day, parent_id, settings_name,
[this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
+ }
}
void LLFloaterEditExtDayCycle::doApplyUpdateInventory(const LLSettingsDay::ptr_t &day)
@@ -1401,6 +1470,8 @@ void LLFloaterEditExtDayCycle::doApplyCommit(LLSettingsDay::ptr_t day)
bool LLFloaterEditExtDayCycle::isRemovingFrameAllowed()
{
+ if (mFramesSlider->getCurSlider().empty()) return false;
+
if (mCurrentTrack <= LLSettingsDay::TRACK_GROUND_LEVEL)
{
return (mSliderKeyMap.size() > 1);
@@ -1411,6 +1482,18 @@ bool LLFloaterEditExtDayCycle::isRemovingFrameAllowed()
}
}
+bool LLFloaterEditExtDayCycle::isAddingFrameAllowed()
+{
+ if (!mFramesSlider->getCurSlider().empty()) return false;
+
+ LLSettingsBase::Seconds frame(mTimeSlider->getCurSliderValue());
+ if ((mEditDay->getSettingsNearKeyframe(frame, mCurrentTrack, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR)).second)
+ {
+ return false;
+ }
+ return mFramesSlider->canAddSliders();
+}
+
void LLFloaterEditExtDayCycle::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results)
{
LL_INFOS("ENVDAYEDIT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL;
@@ -1420,6 +1503,11 @@ void LLFloaterEditExtDayCycle::onInventoryCreated(LLUUID asset_id, LLUUID invent
LLNotificationsUtil::add("CantCreateInventory");
return;
}
+ onInventoryCreated(asset_id, inventory_id);
+}
+
+void LLFloaterEditExtDayCycle::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id)
+{
if (mInventoryItem)
{
@@ -1536,6 +1624,7 @@ void LLFloaterEditExtDayCycle::onIdlePlay(void* user_data)
self->mWaterBlender->setPosition(new_frame);
self->synchronizeTabs();
self->updateTimeAndLabel();
+ self->updateButtons();
}
}
@@ -1614,20 +1703,35 @@ void LLFloaterEditExtDayCycle::onAssetLoadedForFrame(LLUUID item_id, LLUUID asse
{
std::function<void()> cb = [this, settings, frame, track]()
{
- if ((mEditDay->getSettingsNearKeyframe(frame, mCurrentTrack, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR)).second)
+ if (mFramesSlider->getCurSlider().empty())
{
- LL_WARNS("ENVDAYEDIT") << "Attempt to add new frame too close to existing frame." << LL_ENDL;
- return;
+ if ((mEditDay->getSettingsNearKeyframe(frame, mCurrentTrack, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR)).second)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Attempt to add new frame too close to existing frame." << LL_ENDL;
+ return;
+ }
+ if (!mFramesSlider->canAddSliders())
+ {
+ LL_WARNS("ENVDAYEDIT") << "Attempt to add new frame when slider is full." << LL_ENDL;
+ return;
+ }
+ mEditDay->setSettingsAtKeyframe(settings, frame, track);
+ addSliderFrame(frame, settings, false);
+ reblendSettings();
+ synchronizeTabs();
}
- if (!mFramesSlider->canAddSliders())
+ else
{
- LL_WARNS("ENVDAYEDIT") << "Attempt to add new frame when slider is full." << LL_ENDL;
- return;
+ if (mCurrentTrack == LLSettingsDay::TRACK_WATER)
+ {
+ mEditDay->setWaterAtKeyframe(std::static_pointer_cast<LLSettingsWater>(settings), frame);
+ }
+ else
+ {
+ mEditDay->setSkyAtKeyframe(std::static_pointer_cast<LLSettingsSky>(settings), frame, track);
+ }
+ updateTabs();
}
- mEditDay->setSettingsAtKeyframe(settings, frame, track);
- addSliderFrame(frame, settings, false);
- reblendSettings();
- synchronizeTabs();
};
if (!settings || status)
diff --git a/indra/newview/llfloatereditextdaycycle.h b/indra/newview/llfloatereditextdaycycle.h
index fd5fb67837..1dea77571f 100644
--- a/indra/newview/llfloatereditextdaycycle.h
+++ b/indra/newview/llfloatereditextdaycycle.h
@@ -43,6 +43,7 @@ class LLTimeCtrl;
class LLTabContainer;
class LLInventoryItem;
+class LLDaySettingCopiedCallback;
typedef std::shared_ptr<LLSettingsBase> LLSettingsBasePtr_t;
@@ -53,6 +54,8 @@ class LLFloaterEditExtDayCycle : public LLFloater
{
LOG_CLASS(LLFloaterEditExtDayCycle);
+ friend class LLDaySettingCopiedCallback;
+
public:
static const std::string KEY_INVENTORY_ID;
static const std::string KEY_EDIT_CONTEXT;
@@ -131,6 +134,7 @@ private:
void updateWaterTabs(const LLSettingsWaterPtr_t &p_water);
void updateSkyTabs(const LLSettingsSkyPtr_t &p_sky);
void updateButtons();
+ void updateLabels();
void updateSlider(); //generate sliders from current track
void updateTimeAndLabel();
void addSliderFrame(const F32 frame, const LLSettingsBase::ptr_t &setting, bool update_ui = true);
@@ -145,6 +149,7 @@ private:
void doApplyUpdateInventory(const LLSettingsDay::ptr_t &day);
void doApplyEnvironment(const std::string &where, const LLSettingsDay::ptr_t &day);
void doApplyCommit(LLSettingsDay::ptr_t day);
+ void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id);
void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
void onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
@@ -173,6 +178,7 @@ private:
virtual void clearDirtyFlag();
bool isRemovingFrameAllowed();
+ bool isAddingFrameAllowed();
LLSettingsDay::ptr_t mEditDay; // edited copy
LLSettingsDay::Seconds mDayLength;
diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp
index d35dd5ec98..712c7cf31a 100644
--- a/indra/newview/llfloaterfixedenvironment.cpp
+++ b/indra/newview/llfloaterfixedenvironment.cpp
@@ -86,6 +86,30 @@ const std::string LLFloaterFixedEnvironment::KEY_INVENTORY_ID("inventory_id");
//=========================================================================
+
+class LLFixedSettingCopiedCallback : public LLInventoryCallback
+{
+public:
+ LLFixedSettingCopiedCallback(LLHandle<LLFloater> handle) : mHandle(handle) {}
+
+ virtual void fire(const LLUUID& inv_item_id)
+ {
+ if (!mHandle.isDead())
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item_id);
+ if (item)
+ {
+ LLFloaterFixedEnvironment* floater = (LLFloaterFixedEnvironment*)mHandle.get();
+ floater->onInventoryCreated(item->getAssetUUID(), inv_item_id);
+ }
+ }
+ }
+
+private:
+ LLHandle<LLFloater> mHandle;
+};
+
+//=========================================================================
LLFloaterFixedEnvironment::LLFloaterFixedEnvironment(const LLSD &key) :
LLFloater(key),
mFlyoutControl(nullptr),
@@ -429,7 +453,32 @@ void LLFloaterFixedEnvironment::onSaveAsCommit(const LLSD& notification, const L
{
std::string settings_name = response["message"].asString();
LLStringUtil::trim(settings_name);
- doApplyCreateNewInventory(settings_name);
+ if (mCanMod)
+ {
+ doApplyCreateNewInventory(settings_name);
+ }
+ else if (mInventoryItem)
+ {
+ const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+ LLUUID parent_id = mInventoryItem->getParentUUID();
+ if (marketplacelistings_id == parent_id)
+ {
+ parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
+ }
+
+ LLPointer<LLInventoryCallback> cb = new LLFixedSettingCopiedCallback(getHandle());
+ copy_inventory_item(
+ gAgent.getID(),
+ mInventoryItem->getPermissions().getOwner(),
+ mInventoryItem->getUUID(),
+ parent_id,
+ settings_name,
+ cb);
+ }
+ else
+ {
+ LL_WARNS() << "Failed to copy fixed env setting" << LL_ENDL;
+ }
}
}
@@ -448,10 +497,20 @@ void LLFloaterFixedEnvironment::onButtonLoad()
void LLFloaterFixedEnvironment::doApplyCreateNewInventory(std::string settings_name)
{
- LLUUID parent_id = mInventoryItem ? mInventoryItem->getParentUUID() : gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
- // This method knows what sort of settings object to create.
- LLSettingsVOBase::createInventoryItem(mSettings, parent_id, settings_name,
+ if (mInventoryItem)
+ {
+ LLUUID parent_id = mInventoryItem->getParentUUID();
+ U32 next_owner_perm = mInventoryItem->getPermissions().getMaskNextOwner();
+ LLSettingsVOBase::createInventoryItem(mSettings, next_owner_perm, parent_id, settings_name,
[this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
+ }
+ else
+ {
+ LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
+ // This method knows what sort of settings object to create.
+ LLSettingsVOBase::createInventoryItem(mSettings, parent_id, settings_name,
+ [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
+ }
}
void LLFloaterFixedEnvironment::doApplyUpdateInventory()
@@ -537,13 +596,17 @@ void LLFloaterFixedEnvironment::doCloseInventoryFloater(bool quitting)
void LLFloaterFixedEnvironment::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results)
{
LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL;
-
+
if (inventory_id.isNull() || !results["success"].asBoolean())
{
LLNotificationsUtil::add("CantCreateInventory");
return;
}
+ onInventoryCreated(asset_id, inventory_id);
+}
+void LLFloaterFixedEnvironment::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id)
+{
if (mInventoryItem)
{
LLPermissions perms = mInventoryItem->getPermissions();
diff --git a/indra/newview/llfloaterfixedenvironment.h b/indra/newview/llfloaterfixedenvironment.h
index afab75b4ba..12fa64e733 100644
--- a/indra/newview/llfloaterfixedenvironment.h
+++ b/indra/newview/llfloaterfixedenvironment.h
@@ -38,6 +38,7 @@ class LLTabContainer;
class LLButton;
class LLLineEditor;
class LLFloaterSettingsPicker;
+class LLFixedSettingCopiedCallback;
/**
* Floater container for creating and editing fixed environment settings.
@@ -46,6 +47,8 @@ class LLFloaterFixedEnvironment : public LLFloater
{
LOG_CLASS(LLFloaterFixedEnvironment);
+ friend class LLFixedSettingCopiedCallback;
+
public:
static const std::string KEY_INVENTORY_ID;
@@ -100,6 +103,7 @@ protected:
bool mCanCopy;
bool mCanMod;
+ void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id);
void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
void onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 25cbf2f576..b20911edc5 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -3281,16 +3281,18 @@ void LLPanelLandEnvironment::refresh()
setCrossRegion(true);
mCurrentEnvironment.reset();
mLastParcelId = INVALID_PARCEL_ID;
+ mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;
setControlsEnabled(false);
return;
}
if (mLastParcelId != getParcelId())
{
+ mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;
mCurrentEnvironment.reset();
}
- if (!mCurrentEnvironment)
+ if (!mCurrentEnvironment && mCurEnvVersion <= INVALID_PARCEL_ENVIRONMENT_VERSION)
{
refreshFromSource();
return;
@@ -3307,6 +3309,7 @@ void LLPanelLandEnvironment::refreshFromSource()
{
setNoEnvironmentSupport(true);
setControlsEnabled(false);
+ mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;
return;
}
setNoEnvironmentSupport(false);
@@ -3315,17 +3318,25 @@ void LLPanelLandEnvironment::refreshFromSource()
{
setNoSelection(true);
setControlsEnabled(false);
+ mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;
return;
}
setNoSelection(false);
if (isSameRegion())
{
+ LL_DEBUGS("ENVIRONMENT") << "Requesting environment for parcel " << parcel->getLocalID() << ", known version " << mCurEnvVersion << LL_ENDL;
setCrossRegion(false);
LLHandle<LLPanel> that_h = getHandle();
- mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;
+ if (mCurEnvVersion < UNSET_PARCEL_ENVIRONMENT_VERSION)
+ {
+ // to mark as requesting
+ mCurEnvVersion = parcel->getParcelEnvironmentVersion();
+ }
+ mLastParcelId = parcel->getLocalID();
+
LLEnvironment::instance().requestParcel(parcel->getLocalID(),
[that_h](S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo)
{
@@ -3340,6 +3351,7 @@ void LLPanelLandEnvironment::refreshFromSource()
setCrossRegion(true);
mCurrentEnvironment.reset();
mLastParcelId = INVALID_PARCEL_ID;
+ mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;
}
setControlsEnabled(false);
}
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 671f5aca9d..fcaa7d2bf9 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -226,7 +226,8 @@ LLUUID LLFloaterRegionInfo::sRequestInvoice;
LLFloaterRegionInfo::LLFloaterRegionInfo(const LLSD& seed)
: LLFloater(seed),
- mEnvironmentPanel(NULL)
+ mEnvironmentPanel(NULL),
+ mRegionChangedCallback()
{}
BOOL LLFloaterRegionInfo::postBuild()
@@ -285,13 +286,18 @@ BOOL LLFloaterRegionInfo::postBuild()
&processEstateOwnerRequest);
// Request region info when agent region changes.
- gAgent.addRegionChangedCallback(boost::bind(&LLFloaterRegionInfo::requestRegionInfo, this));
+ mRegionChangedCallback = gAgent.addRegionChangedCallback(boost::bind(&LLFloaterRegionInfo::onRegionChanged, this));
return TRUE;
}
LLFloaterRegionInfo::~LLFloaterRegionInfo()
-{}
+{
+ if (mRegionChangedCallback.connected())
+ {
+ mRegionChangedCallback.disconnect();
+ }
+}
void LLFloaterRegionInfo::onOpen(const LLSD& key)
{
@@ -300,20 +306,28 @@ void LLFloaterRegionInfo::onOpen(const LLSD& key)
disableTabCtrls();
return;
}
- refreshFromRegion(gAgent.getRegion());
- requestRegionInfo();
+ requestRegionInfo(); // will cause refreshFromRegion()
requestMeshRezInfo();
}
-// static
-void LLFloaterRegionInfo::requestRegionInfo()
+void LLFloaterRegionInfo::onRegionChanged()
{
- LLTabContainer* tab = getChild<LLTabContainer>("region_panels");
+ if (getVisible()) //otherwise onOpen will do request
+ {
+ requestRegionInfo();
+ }
+}
- tab->getChild<LLPanel>("General")->setCtrlsEnabled(FALSE);
- tab->getChild<LLPanel>("Debug")->setCtrlsEnabled(FALSE);
- tab->getChild<LLPanel>("Terrain")->setCtrlsEnabled(FALSE);
- tab->getChild<LLPanel>("Estate")->setCtrlsEnabled(FALSE);
+void LLFloaterRegionInfo::requestRegionInfo()
+{
+ LLTabContainer* tab = findChild<LLTabContainer>("region_panels");
+ if (tab)
+ {
+ tab->getChild<LLPanel>("General")->setCtrlsEnabled(FALSE);
+ tab->getChild<LLPanel>("Debug")->setCtrlsEnabled(FALSE);
+ tab->getChild<LLPanel>("Terrain")->setCtrlsEnabled(FALSE);
+ tab->getChild<LLPanel>("Estate")->setCtrlsEnabled(FALSE);
+ }
// Must allow anyone to request the RegionInfo data
// so non-owners/non-gods can see the values.
@@ -484,7 +498,12 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
panel->setCtrlsEnabled(allow_modify);
- floater->refreshFromRegion( gAgent.getRegion() );
+ if (floater->getVisible())
+ {
+ // Note: region info also causes LLRegionInfoModel::instance().update(msg); -> requestRegion(); -> changed message
+ // we need to know env version here and in update(msg) to know when to request and when not to, when to filter 'changed'
+ floater->refreshFromRegion(gAgent.getRegion());
+ } // else will rerequest on onOpen either way
}
// static
@@ -3410,7 +3429,10 @@ void LLPanelRegionEnvironment::refresh()
{
if (!mCurrentEnvironment)
{
- refreshFromSource();
+ if (mCurEnvVersion <= INVALID_PARCEL_ENVIRONMENT_VERSION)
+ {
+ refreshFromSource(); // will immediately set mCurEnvVersion
+ } // else - already requesting
return;
}
@@ -3426,15 +3448,17 @@ bool LLPanelRegionEnvironment::refreshFromRegion(LLViewerRegion* region)
{
setNoSelection(true);
setControlsEnabled(false);
+ mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;
}
setNoSelection(false);
if (gAgent.getRegion()->getRegionID() != region->getRegionID())
{
setCrossRegion(true);
+ mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;
}
setCrossRegion(false);
-
+
refreshFromSource();
return true;
}
@@ -3448,9 +3472,15 @@ void LLPanelRegionEnvironment::refreshFromEstate()
void LLPanelRegionEnvironment::refreshFromSource()
{
+ LL_DEBUGS("ENVIRONMENT") << "Requesting environment for region, known version " << mCurEnvVersion << LL_ENDL;
LLHandle<LLPanel> that_h = getHandle();
- mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;
+ if (mCurEnvVersion < UNSET_PARCEL_ENVIRONMENT_VERSION)
+ {
+ // to mark as requesting
+ mCurEnvVersion = UNSET_PARCEL_ENVIRONMENT_VERSION;
+ }
+
LLEnvironment::instance().requestRegion(
[that_h](S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo) { _onEnvironmentReceived(that_h, parcel_id, envifo); });
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index 6d64ae1d60..0566c4b2ce 100644
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -96,6 +96,7 @@ public:
// from LLPanel
virtual void refresh();
+ void onRegionChanged();
void requestRegionInfo();
void requestMeshRezInfo();
void enableTopButtons();
@@ -120,6 +121,8 @@ protected:
LLPanelRegionEnvironment *mEnvironmentPanel;
//static S32 sRequestSerial; // serial # of last EstateOwnerRequest
static LLUUID sRequestInvoice;
+private:
+ boost::signals2::connection mRegionChangedCallback;
};
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index a9b15fc8b6..eb417106b6 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -44,6 +44,7 @@
#include "llviewercamera.h"
#include "llvoavatarself.h"
+#include "llsky.h"
#include "llagent.h"
#include "lltoolmgr.h"
#include "llselectmgr.h"
@@ -771,6 +772,16 @@ void draw_line_cube(F32 width, const LLVector3& center)
gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] - width);
}
+void draw_cross_lines(const LLVector3& center, F32 dx, F32 dy, F32 dz)
+{
+ gGL.vertex3f(center.mV[VX] - dx, center.mV[VY], center.mV[VZ]);
+ gGL.vertex3f(center.mV[VX] + dx, center.mV[VY], center.mV[VZ]);
+ gGL.vertex3f(center.mV[VX], center.mV[VY] - dy, center.mV[VZ]);
+ gGL.vertex3f(center.mV[VX], center.mV[VY] + dy, center.mV[VZ]);
+ gGL.vertex3f(center.mV[VX], center.mV[VY], center.mV[VZ] - dz);
+ gGL.vertex3f(center.mV[VX], center.mV[VY], center.mV[VZ] + dz);
+}
+
void LLViewerObjectList::renderObjectBeacons()
{
if (mDebugBeacons.empty())
@@ -808,13 +819,7 @@ void LLViewerObjectList::renderObjectBeacons()
gGL.begin(LLRender::LINES);
gGL.color4fv(color.mV);
- gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] - 50.f);
- gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] + 50.f);
- gGL.vertex3f(thisline.mV[VX] - 2.f,thisline.mV[VY],thisline.mV[VZ]);
- gGL.vertex3f(thisline.mV[VX] + 2.f,thisline.mV[VY],thisline.mV[VZ]);
- gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] - 2.f,thisline.mV[VZ]);
- gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] + 2.f,thisline.mV[VZ]);
-
+ draw_cross_lines(thisline, 2.0f, 2.0f, 50.f);
draw_line_cube(0.10f, thisline);
gGL.end();
@@ -843,13 +848,7 @@ void LLViewerObjectList::renderObjectBeacons()
const LLVector3 &thisline = debug_beacon.mPositionAgent;
gGL.begin(LLRender::LINES);
gGL.color4fv(debug_beacon.mColor.mV);
- gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] - 0.5f);
- gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] + 0.5f);
- gGL.vertex3f(thisline.mV[VX] - 0.5f,thisline.mV[VY],thisline.mV[VZ]);
- gGL.vertex3f(thisline.mV[VX] + 0.5f,thisline.mV[VY],thisline.mV[VZ]);
- gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] - 0.5f,thisline.mV[VZ]);
- gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] + 0.5f,thisline.mV[VZ]);
-
+ draw_cross_lines(thisline, 0.5f, 0.5f, 0.5f);
draw_line_cube(0.10f, thisline);
gGL.end();
@@ -880,6 +879,34 @@ void LLViewerObjectList::renderObjectBeacons()
}
}
+void LLSky::renderSunMoonBeacons(const LLVector3& pos_agent, const LLVector3& direction, LLColor4 color)
+{
+ LLGLSUIDefault gls_ui;
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ gUIProgram.bind();
+ }
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ LLVector3 pos_end;
+ for (S32 i = 0; i < 3; ++i)
+ {
+ pos_end.mV[i] = pos_agent.mV[i] + (50 * direction.mV[i]);
+ }
+ glLineWidth(LLPipeline::DebugBeaconLineWidth);
+ gGL.begin(LLRender::LINES);
+ color.mV[3] *= 0.5f;
+ gGL.color4fv(color.mV);
+ draw_cross_lines(pos_agent, 0.5f, 0.5f, 0.5f);
+ draw_cross_lines(pos_end, 2.f, 2.f, 2.f);
+ gGL.vertex3fv(pos_agent.mV);
+ gGL.vertex3fv(pos_end.mV);
+ gGL.end();
+
+ gGL.flush();
+ glLineWidth(1.f);
+
+}
//-----------------------------------------------------------------------------
// gpu_benchmark() helper classes
diff --git a/indra/newview/llpanelenvironment.cpp b/indra/newview/llpanelenvironment.cpp
index 8c86e3e8e4..e3be46f1af 100644
--- a/indra/newview/llpanelenvironment.cpp
+++ b/indra/newview/llpanelenvironment.cpp
@@ -151,7 +151,7 @@ BOOL LLPanelEnvironmentInfo::postBuild()
getChild<LLMultiSliderCtrl>(SLD_ALTITUDES)->setCommitCallback([this](LLUICtrl *cntrl, const LLSD &value) { onAltSliderCallback(cntrl, value); });
- mChangeMonitor = LLEnvironment::instance().setEnvironmentChanged([this](LLEnvironment::EnvSelection_t env) { onEnvironmentChanged(env); });
+ mChangeMonitor = LLEnvironment::instance().setEnvironmentChanged([this](LLEnvironment::EnvSelection_t env, S32 version) { onEnvironmentChanged(env, version); });
getChild<LLSettingsDropTarget>(SDT_DROP_TARGET)->setPanel(this);
@@ -255,13 +255,19 @@ void LLPanelEnvironmentInfo::refresh()
LLEnvironment::altitude_list_t altitudes = LLEnvironment::instance().getRegionAltitudes();
if (altitudes.size() > 0)
{
+ LLMultiSliderCtrl *sld = getChild<LLMultiSliderCtrl>(SLD_ALTITUDES);
+ sld->clear();
+
for (S32 idx = 0; idx < ALTITUDE_SLIDER_COUNT; ++idx)
{
- LLMultiSliderCtrl *sld = getChild<LLMultiSliderCtrl>(SLD_ALTITUDES);
- sld->setSliderValue(alt_sliders[idx], altitudes[idx+1], FALSE);
+ sld->addSlider(altitudes[idx + 1], alt_sliders[idx]);
updateAltLabel(alt_labels[idx], idx + 2, altitudes[idx+1]);
mAltitudes[alt_sliders[idx]] = AltitudeData(idx+1, idx, altitudes[idx+1]);
}
+ if (sld->getCurNumSliders() != ALTITUDE_SLIDER_COUNT)
+ {
+ LL_WARNS("ENVPANEL") << "Failed to add altitude sliders!" << LL_ENDL;
+ }
readjustAltLabels();
}
@@ -389,7 +395,7 @@ bool LLPanelEnvironmentInfo::setControlsEnabled(bool enabled)
S32 rdo_selection = getChild<LLRadioGroup>(RDG_ENVIRONMENT_SELECT)->getSelectedIndex();
- bool can_enable = enabled && mCurEnvVersion != INVALID_PARCEL_ENVIRONMENT_VERSION;
+ bool can_enable = enabled && mCurrentEnvironment && mCurEnvVersion != INVALID_PARCEL_ENVIRONMENT_VERSION;
getChild<LLUICtrl>(RDG_ENVIRONMENT_SELECT)->setEnabled(can_enable);
getChild<LLUICtrl>(RDO_USEDEFAULT)->setEnabled(can_enable && !is_legacy);
getChild<LLUICtrl>(RDO_USEINV)->setEnabled(false); // these two are selected automatically based on
@@ -431,16 +437,16 @@ void LLPanelEnvironmentInfo::setDirtyFlag(U32 flag)
{
bool can_edit = canEdit();
mDirtyFlag |= flag;
- getChildView(BTN_APPLY)->setEnabled((mDirtyFlag != 0) && mCurEnvVersion != INVALID_PARCEL_ENVIRONMENT_VERSION && can_edit);
- getChildView(BTN_CANCEL)->setEnabled((mDirtyFlag != 0) && can_edit);
+ getChildView(BTN_APPLY)->setEnabled((mDirtyFlag != 0) && mCurrentEnvironment && mCurEnvVersion != INVALID_PARCEL_ENVIRONMENT_VERSION && can_edit);
+ getChildView(BTN_CANCEL)->setEnabled((mDirtyFlag != 0) && mCurrentEnvironment && can_edit);
}
void LLPanelEnvironmentInfo::clearDirtyFlag(U32 flag)
{
bool can_edit = canEdit();
mDirtyFlag &= ~flag;
- getChildView(BTN_APPLY)->setEnabled((mDirtyFlag != 0) && mCurEnvVersion != INVALID_PARCEL_ENVIRONMENT_VERSION && can_edit);
- getChildView(BTN_CANCEL)->setEnabled((mDirtyFlag != 0) && can_edit);
+ getChildView(BTN_APPLY)->setEnabled((mDirtyFlag != 0) && mCurrentEnvironment && mCurEnvVersion != INVALID_PARCEL_ENVIRONMENT_VERSION && can_edit);
+ getChildView(BTN_CANCEL)->setEnabled((mDirtyFlag != 0) && mCurrentEnvironment && can_edit);
}
void LLPanelEnvironmentInfo::updateAltLabel(const std::string &alt_name, U32 sky_index, F32 alt_value)
@@ -551,7 +557,7 @@ void LLPanelEnvironmentInfo::onSldDayOffsetChanged(F32 value)
{
F32Hours dayoffset(value);
- if (dayoffset.value() < 0.0f)
+ if (dayoffset.value() <= 0.0f)
dayoffset += F32Hours(24.0);
mCurrentEnvironment->mDayOffset = dayoffset;
@@ -663,7 +669,6 @@ void LLPanelEnvironmentInfo::doApply()
if (rdo_selection == 0)
{
- mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;
LLEnvironment::instance().resetParcel(parcel_id,
[that_h](S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo) { _onEnvironmentReceived(that_h, parcel_id, envifo); });
}
@@ -675,7 +680,6 @@ void LLPanelEnvironmentInfo::doApply()
LL_WARNS("ENVPANEL") << "Failed to apply changes from editor! Dirty state: " << mDirtyFlag << " update state: " << mCurEnvVersion << LL_ENDL;
return;
}
- mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;
LLEnvironment::instance().updateParcel(parcel_id,
mCurrentEnvironment->mDayCycle->getAssetId(), std::string(), mCurrentEnvironment->mDayLength.value(),
mCurrentEnvironment->mDayOffset.value(), alts,
@@ -689,7 +693,6 @@ void LLPanelEnvironmentInfo::doApply()
LL_WARNS("ENVPANEL") << "Failed to apply changes from editor! Dirty state: " << mDirtyFlag << " update state: " << mCurEnvVersion << LL_ENDL;
return;
}
- mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;
LLEnvironment::instance().updateParcel(parcel_id,
mCurrentEnvironment->mDayCycle, mCurrentEnvironment->mDayLength.value(), mCurrentEnvironment->mDayOffset.value(), alts,
[that_h](S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo) { _onEnvironmentReceived(that_h, parcel_id, envifo); });
@@ -780,36 +783,55 @@ void LLPanelEnvironmentInfo::onEditCommitted(LLSettingsDay::ptr_t newday)
}
}
-void LLPanelEnvironmentInfo::onEnvironmentChanged(LLEnvironment::EnvSelection_t env)
+void LLPanelEnvironmentInfo::onEnvironmentChanged(LLEnvironment::EnvSelection_t env, S32 new_version)
{
+ if (new_version < INVALID_PARCEL_ENVIRONMENT_VERSION)
+ {
+ // cleanups and local changes, we are only interested in changes sent by server
+ return;
+ }
+
+ LL_DEBUGS("ENVPANEL") << "Received environment update " << mCurEnvVersion << " " << new_version << LL_ENDL;
+
+ // Environment comes from different sources, from environment update callbacks,
+ // from hovers (causes callbacks on version change) and from personal requests
+ // filter out duplicates and out of order packets by checking parcel environment version.
+
if (isRegion())
{
- // Note: at the moment mCurEnvVersion is only applyable to parcels, we might need separate version control for regions
- // but mCurEnvVersion still acts like indicator that update is pending
- if (env == LLEnvironment::ENV_REGION)
+ // Note: region uses same init versions as parcel
+ if (env == LLEnvironment::ENV_REGION
+ // version should be always growing, UNSET_PARCEL_ENVIRONMENT_VERSION is backup case
+ && (mCurEnvVersion < new_version || mCurEnvVersion <= UNSET_PARCEL_ENVIRONMENT_VERSION))
{
+ if (new_version >= UNSET_PARCEL_ENVIRONMENT_VERSION)
+ {
+ // 'pending state' to prevent re-request on following onEnvironmentChanged if there will be any
+ mCurEnvVersion = new_version;
+ }
mCurrentEnvironment.reset();
refreshFromSource();
}
}
- else if ((env == LLEnvironment::ENV_PARCEL) && (getParcelId() == LLViewerParcelMgr::instance().getAgentParcelId()))
+ else if ((env == LLEnvironment::ENV_PARCEL)
+ && (getParcelId() == LLViewerParcelMgr::instance().getAgentParcelId()))
{
- // Panel receives environment from different sources, from environment update callbacks,
- // from hovers (causes callbacks on version change) and from personal requests
- // filter out dupplicates and out of order packets by checking parcel environment version.
LLParcel *parcel = getParcel();
if (parcel)
{
- S32 new_version = parcel->getParcelEnvironmentVersion();
- LL_DEBUGS("ENVPANEL") << "Received environment update " << mCurEnvVersion << " " << new_version << LL_ENDL;
+ // first for parcel own settings, second is for case when parcel uses region settings
if (mCurEnvVersion < new_version
|| (mCurEnvVersion != new_version && new_version == UNSET_PARCEL_ENVIRONMENT_VERSION))
{
+ // 'pending state' to prevent re-request on following onEnvironmentChanged if there will be any
+ mCurEnvVersion = new_version;
mCurrentEnvironment.reset();
+
refreshFromSource();
}
- else
+ else if (mCurrentEnvironment)
{
+ // update controls
refresh();
}
}
@@ -839,30 +861,21 @@ void LLPanelEnvironmentInfo::onEnvironmentReceived(S32 parcel_id, LLEnvironment:
}
mCurrentEnvironment = envifo;
clearDirtyFlag(DIRTY_FLAG_MASK);
- if (parcel_id == INVALID_PARCEL_ID)
+ if (mCurrentEnvironment->mEnvVersion > INVALID_PARCEL_ENVIRONMENT_VERSION)
{
- // region, no version
- // -2 for invalid version viewer -1 for invalid version from server
- mCurEnvVersion = UNSET_PARCEL_ENVIRONMENT_VERSION;
+ // Server provided version, use it
+ mCurEnvVersion = mCurrentEnvironment->mEnvVersion;
+ LL_DEBUGS("ENVPANEL") << " Setting environment version: " << mCurEnvVersion << " for parcel id: " << parcel_id << LL_ENDL;
}
+ // Backup: Version was not provided for some reason
else
{
- LLParcel* parcel = getParcel();
- if (parcel
- && mCurrentEnvironment->mDayCycle
- && mCurrentEnvironment->mDayCycle->getAssetId() != LLSettingsDay::GetDefaultAssetId())
- {
- // not always up to date, we will get onEnvironmentChanged() update in such case.
- mCurEnvVersion = parcel->getParcelEnvironmentVersion();
- }
- else
- {
- // When using 'region' as parcel environment
- mCurEnvVersion = UNSET_PARCEL_ENVIRONMENT_VERSION;
- }
- LL_DEBUGS("ENVPANEL") << " Setting environment version: " << mCurEnvVersion << LL_ENDL;
+ LL_WARNS("ENVPANEL") << " Environment version was not provided for " << parcel_id << ", old env version: " << mCurEnvVersion << LL_ENDL;
}
+
refresh();
+
+ // todo: we have envifo and parcel env version, should we just setEnvironment() and parcel's property to prevent dupplicate requests?
}
void LLPanelEnvironmentInfo::_onEnvironmentReceived(LLHandle<LLPanel> that_h, S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo)
diff --git a/indra/newview/llpanelenvironment.h b/indra/newview/llpanelenvironment.h
index bca7743145..05f25fa78f 100644
--- a/indra/newview/llpanelenvironment.h
+++ b/indra/newview/llpanelenvironment.h
@@ -142,7 +142,7 @@ protected:
LLEnvironment::EnvironmentInfo::ptr_t mCurrentEnvironment;
- void onEnvironmentChanged(LLEnvironment::EnvSelection_t env);
+ void onEnvironmentChanged(LLEnvironment::EnvSelection_t env, S32 version);
class AltitudeData
{
@@ -160,7 +160,7 @@ protected:
};
typedef std::map<std::string, AltitudeData> altitudes_data_t;
altitudes_data_t mAltitudes;
- S32 mCurEnvVersion;
+ S32 mCurEnvVersion; // used to filter duplicate callbacks/refreshes
private:
diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp
index 3925f37703..0def17b32d 100644
--- a/indra/newview/llsettingsvo.cpp
+++ b/indra/newview/llsettingsvo.cpp
@@ -121,8 +121,13 @@ void LLSettingsVOBase::createNewInventoryItem(LLSettingsType::type_e stype, cons
void LLSettingsVOBase::createInventoryItem(const LLSettingsBase::ptr_t &settings, const LLUUID &parent_id, std::string settings_name, inventory_result_fn callback)
{
+ U32 nextOwnerPerm = LLPermissions::DEFAULT.getMaskNextOwner();
+ createInventoryItem(settings, nextOwnerPerm, parent_id, settings_name, callback);
+}
+
+void LLSettingsVOBase::createInventoryItem(const LLSettingsBase::ptr_t &settings, U32 next_owner_perm, const LLUUID &parent_id, std::string settings_name, inventory_result_fn callback)
+{
LLTransactionID tid;
- U32 nextOwnerPerm = LLPermissions::DEFAULT.getMaskNextOwner();
if (!LLEnvironment::instance().isInventoryEnabled())
{
@@ -144,7 +149,7 @@ void LLSettingsVOBase::createInventoryItem(const LLSettingsBase::ptr_t &settings
create_inventory_settings(gAgent.getID(), gAgent.getSessionID(),
parent_id, tid,
settings_name, "",
- settings->getSettingsTypeValue(), nextOwnerPerm, cb);
+ settings->getSettingsTypeValue(), next_owner_perm, cb);
}
void LLSettingsVOBase::onInventoryItemCreated(const LLUUID &inventoryId, LLSettingsBase::ptr_t settings, inventory_result_fn callback)
diff --git a/indra/newview/llsettingsvo.h b/indra/newview/llsettingsvo.h
index 0e8312b849..1ad0091871 100644
--- a/indra/newview/llsettingsvo.h
+++ b/indra/newview/llsettingsvo.h
@@ -51,7 +51,8 @@ public:
static void createNewInventoryItem(LLSettingsType::type_e stype, const LLUUID &parent_id, inventory_result_fn callback = inventory_result_fn());
static void createInventoryItem(const LLSettingsBase::ptr_t &settings, const LLUUID &parent_id, std::string settings_name, inventory_result_fn callback = inventory_result_fn());
-
+ static void createInventoryItem(const LLSettingsBase::ptr_t &settings, U32 next_owner_perm, const LLUUID &parent_id, std::string settings_name, inventory_result_fn callback = inventory_result_fn());
+
static void updateInventoryItem(const LLSettingsBase::ptr_t &settings, LLUUID inv_item_id, inventory_result_fn callback = inventory_result_fn(), bool update_name = true);
static void updateInventoryItem(const LLSettingsBase::ptr_t &settings, LLUUID object_id, LLUUID inv_item_id, inventory_result_fn callback = inventory_result_fn());
diff --git a/indra/newview/llsky.cpp b/indra/newview/llsky.cpp
index 0740878901..71de99b4ec 100644
--- a/indra/newview/llsky.cpp
+++ b/indra/newview/llsky.cpp
@@ -52,7 +52,7 @@
#include "llcubemap.h"
#include "llviewercontrol.h"
#include "llenvironment.h"
-
+#include "llvoavatarself.h"
#include "llvowlsky.h"
F32 azimuth_from_vector(const LLVector3 &v);
@@ -234,6 +234,23 @@ void LLSky::setWind(const LLVector3& average_wind)
}
}
+void LLSky::addSunMoonBeacons()
+{
+ if (!gAgentAvatarp || !mVOSkyp) return;
+
+ static LLUICachedControl<bool> show_sun_beacon("sunbeacon", false);
+ static LLUICachedControl<bool> show_moon_beacon("moonbeacon", false);
+
+ if (show_sun_beacon)
+ {
+ renderSunMoonBeacons(gAgentAvatarp->getPositionAgent(), mVOSkyp->getSun().getDirection(), LLColor4(1.f, 0.5f, 0.f, 0.5f));
+ }
+ if (show_moon_beacon)
+ {
+ renderSunMoonBeacons(gAgentAvatarp->getPositionAgent(), mVOSkyp->getMoon().getDirection(), LLColor4(1.f, 0.f, 0.8f, 0.5f));
+ }
+}
+
//////////////////////////////////////////////////////////////////////
// Private Methods
//////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llsky.h b/indra/newview/llsky.h
index e3cc567888..8c0d70c16c 100644
--- a/indra/newview/llsky.h
+++ b/indra/newview/llsky.h
@@ -84,6 +84,9 @@ public:
void restoreGL();
void resetVertexBuffers();
+ void addSunMoonBeacons();
+ void renderSunMoonBeacons(const LLVector3& pos_agent, const LLVector3& direction, LLColor4 color);
+
public:
LLPointer<LLVOSky> mVOSkyp; // Pointer to the LLVOSky object (only one, ever!)
LLPointer<LLVOGround> mVOGroundp;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 00189f0b11..6e500f7962 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -8258,6 +8258,14 @@ class LLViewToggleBeacon : public view_listener_t
gSavedSettings.setBOOL( "scriptsbeacon", LLPipeline::getRenderScriptedBeacons() );
}
}
+ else if (beacon == "sunbeacon")
+ {
+ gSavedSettings.setBOOL("sunbeacon", !gSavedSettings.getBOOL("sunbeacon"));
+ }
+ else if (beacon == "moonbeacon")
+ {
+ gSavedSettings.setBOOL("moonbeacon", !gSavedSettings.getBOOL("moonbeacon"));
+ }
else if (beacon == "renderbeacons")
{
LLPipeline::toggleRenderBeacons();
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 26678775fb..9be2e905a2 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -357,6 +357,8 @@ public:
static const std::string beacon_scripted_touch = LLTrans::getString("BeaconScriptedTouch");
static const std::string beacon_sound = LLTrans::getString("BeaconSound");
static const std::string beacon_media = LLTrans::getString("BeaconMedia");
+ static const std::string beacon_sun = LLTrans::getString("BeaconSun");
+ static const std::string beacon_moon = LLTrans::getString("BeaconMoon");
static const std::string particle_hiding = LLTrans::getString("ParticleHiding");
// Draw the statistics in a light gray
@@ -791,6 +793,20 @@ public:
}
}
+ static LLUICachedControl<bool> show_sun_beacon("sunbeacon", false);
+ static LLUICachedControl<bool> show_moon_beacon("moonbeacon", false);
+
+ if (show_sun_beacon)
+ {
+ addText(xpos, ypos, beacon_sun);
+ ypos += y_inc;
+ }
+ if (show_moon_beacon)
+ {
+ addText(xpos, ypos, beacon_moon);
+ ypos += y_inc;
+ }
+
if(log_texture_traffic)
{
U32 old_y = ypos ;
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index f5aa003417..d30bb260e1 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -732,8 +732,14 @@ void LLVOSky::updateDirections(void)
{
LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+ mLastSunLightingDirection = mSun.getDirection();
+ mLastMoonLightingDirection = mMoon.getDirection();
+
+ mSun.setDirection(psky->getSunDirection());
+ mMoon.setDirection(psky->getMoonDirection());
+
mSun.setColor(psky->getSunlightColor());
- mMoon.setColor(LLColor3(1.0f, 1.0f, 1.0f));
+ mMoon.setColor(psky->getMoonDiffuse());
mSun.renewDirection();
mSun.renewColor();
@@ -788,17 +794,20 @@ bool LLVOSky::updateSky()
LLVector3 direction = mSun.getDirection();
direction.normalize();
- const F32 dot_lighting = direction * mLastLightingDirection;
+ const F32 dot_sun = direction * mLastSunLightingDirection;
+ const F32 dot_moon = direction * mLastMoonLightingDirection;
LLColor3 delta_color;
delta_color.setVec(mLastTotalAmbient.mV[0] - total_ambient.mV[0],
mLastTotalAmbient.mV[1] - total_ambient.mV[1],
mLastTotalAmbient.mV[2] - total_ambient.mV[2]);
- bool light_direction_changed = (dot_lighting < LIGHT_DIRECTION_THRESHOLD);
- bool color_changed = (delta_color.length() >= COLOR_CHANGE_THRESHOLD);
+ bool sun_direction_changed = (dot_sun < LIGHT_DIRECTION_THRESHOLD);
+ bool moon_direction_changed = (dot_moon < LIGHT_DIRECTION_THRESHOLD);
+ bool color_changed = (delta_color.length() >= COLOR_CHANGE_THRESHOLD);
- mForceUpdate = mForceUpdate || light_direction_changed;
+ mForceUpdate = mForceUpdate || sun_direction_changed;
+ mForceUpdate = mForceUpdate || moon_direction_changed;
mForceUpdate = mForceUpdate || color_changed;
mForceUpdate = mForceUpdate || !mInitialized;
@@ -816,7 +825,6 @@ bool LLVOSky::updateSky()
if (!direction.isExactlyZero())
{
- mLastLightingDirection = direction;
mLastTotalAmbient = total_ambient;
mInitialized = TRUE;
@@ -1623,8 +1631,6 @@ void LLVOSky::setSunAndMoonDirectionsCFR(const LLVector3 &sun_dir_cfr, const LLV
mSun.setDirection(sun_dir_cfr);
mMoon.setDirection(moon_dir_cfr);
- mLastLightingDirection = mSun.getDirection();
-
// Push the sun "South" as it approaches directly overhead so that we can always see bump mapping
// on the upward facing faces of cubes.
{
@@ -1650,8 +1656,6 @@ void LLVOSky::setSunDirectionCFR(const LLVector3 &sun_dir_cfr)
{
mSun.setDirection(sun_dir_cfr);
- mLastLightingDirection = mSun.getDirection();
-
// Push the sun "South" as it approaches directly overhead so that we can always see bump mapping
// on the upward facing faces of cubes.
{
diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h
index 20d0135c21..0713661295 100644
--- a/indra/newview/llvosky.h
+++ b/indra/newview/llvosky.h
@@ -334,7 +334,8 @@ protected:
bool mInitialized;
bool mForceUpdate; //flag to force instantaneous update of cubemap
- LLVector3 mLastLightingDirection;
+ LLVector3 mLastSunLightingDirection;
+ LLVector3 mLastMoonLightingDirection;
LLColor3 mLastTotalAmbient;
F32 mAmbientScale;
LLColor3 mNightColorShift;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 21b70e9c60..7cb6d37cff 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -4578,6 +4578,7 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)
// Render debugging beacons.
gObjectList.renderObjectBeacons();
gObjectList.resetObjectBeacons();
+ gSky.addSunMoonBeacons();
}
else
{
@@ -6008,6 +6009,13 @@ void LLPipeline::setupAvatarLights(bool for_edit)
{
assertInitialized();
+ LLEnvironment& environment = LLEnvironment::instance();
+ LLSettingsSky::ptr_t psky = environment.getCurrentSky();
+
+ bool sun_up = environment.getIsSunUp();
+ bool moon_up = environment.getIsMoonUp();
+ bool sun_is_primary = sun_up || !moon_up;
+
if (for_edit)
{
LLColor4 diffuse(1.f, 1.f, 1.f, 0.f);
@@ -6042,13 +6050,14 @@ void LLPipeline::setupAvatarLights(bool for_edit)
}
else if (gAvatarBacklight) // Always true (unless overridden in a devs .ini)
{
- LLVector3 sun_dir = LLVector3(mSunDir);
- LLVector3 opposite_pos = -sun_dir;
- LLVector3 orthog_light_pos = sun_dir % LLVector3::z_axis;
+ LLVector3 light_dir = sun_is_primary ? LLVector3(mSunDir) : LLVector3(mMoonDir);
+ LLVector3 opposite_pos = -light_dir;
+ LLVector3 orthog_light_pos = light_dir % LLVector3::z_axis;
LLVector4 backlight_pos = LLVector4(lerp(opposite_pos, orthog_light_pos, 0.3f), 0.0f);
backlight_pos.normalize();
-
- LLColor4 light_diffuse = mSunDiffuse;
+
+ LLColor4 light_diffuse = sun_is_primary ? mSunDiffuse : mMoonDiffuse;
+
LLColor4 backlight_diffuse(1.f - light_diffuse.mV[VRED], 1.f - light_diffuse.mV[VGREEN], 1.f - light_diffuse.mV[VBLUE], 1.f);
F32 max_component = 0.001f;
for (S32 i = 0; i < 3; i++)
@@ -6279,6 +6288,10 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
gGL.setAmbientLightColor(ambient);
}
+ bool sun_up = environment.getIsSunUp();
+ bool moon_up = environment.getIsMoonUp();
+ bool sun_is_primary = sun_up || !moon_up;
+
// Light 0 = Sun or Moon (All objects)
{
LLVector4 sun_dir(environment.getSunDirection(), 0.0f);
@@ -6286,15 +6299,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
mSunDir.setVec(sun_dir);
mMoonDir.setVec(moon_dir);
-
- if (environment.getIsSunUp())
- {
- mSunDiffuse.setVec(psky->getSunDiffuse());
- }
- else
- {
- mSunDiffuse.setVec(psky->getMoonDiffuse());
- }
+ mSunDiffuse.setVec(psky->getSunDiffuse());
+ mMoonDiffuse.setVec(psky->getMoonDiffuse());
F32 max_color = llmax(mSunDiffuse.mV[0], mSunDiffuse.mV[1], mSunDiffuse.mV[2]);
if (max_color > 1.f)
@@ -6303,19 +6309,21 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
}
mSunDiffuse.clamp();
- LLColor4 light_diffuse = mSunDiffuse;
+ max_color = llmax(mMoonDiffuse.mV[0], mMoonDiffuse.mV[1], mMoonDiffuse.mV[2]);
+ if (max_color > 1.f)
+ {
+ mMoonDiffuse *= 1.f/max_color;
+ }
+ mMoonDiffuse.clamp();
+
+ LLColor4 light_diffuse = sun_is_primary ? mSunDiffuse : mMoonDiffuse;
+ LLVector4 light_dir = sun_is_primary ? mSunDir : mMoonDir;
mHWLightColors[0] = light_diffuse;
LLLightState* light = gGL.getLight(0);
- if (environment.getIsSunUp())
- {
- light->setPosition(mSunDir);
- }
- else
- {
- light->setPosition(mMoonDir);
- }
+ light->setPosition(light_dir);
+
light->setDiffuse(light_diffuse);
light->setAmbient(LLColor4::black);
light->setSpecular(LLColor4::black);
@@ -8491,17 +8499,32 @@ void LLPipeline::renderDeferredLighting()
vert[0].set(-1,1,0);
vert[1].set(-1,-3,0);
vert[2].set(3,1,0);
+
+ const LLEnvironment& environment = LLEnvironment::instance();
+
+ bool sun_up = environment.getIsSunUp();
+ bool moon_up = environment.getIsMoonUp();
{
setupHWLights(NULL); //to set mSun/MoonDir;
glh::vec4f tc(mSunDir.mV);
mat.mult_matrix_vec(tc);
- mTransformedSunDir.set(tc.v);
- mTransformedSunDir.normalize();
glh::vec4f tc_moon(mMoonDir.mV);
mTransformedMoonDir.set(tc_moon.v);
mTransformedMoonDir.normalize();
+
+ bool sun_is_primary = sun_up || !moon_up;
+ if (sun_is_primary)
+ {
+ mTransformedSunDir.set(tc.v);
+ mTransformedSunDir.normalize();
+ }
+ else
+ {
+ mTransformedSunDir.set(tc_moon.v);
+ mTransformedSunDir.normalize();
+ }
}
gGL.pushMatrix();
@@ -9056,6 +9079,7 @@ void LLPipeline::renderDeferredLighting()
// Render debugging beacons.
gObjectList.renderObjectBeacons();
gObjectList.resetObjectBeacons();
+ gSky.addSunMoonBeacons();
}
}
@@ -9110,16 +9134,31 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target)
vert[1].set(-1,-3,0);
vert[2].set(3,1,0);
+ const LLEnvironment& environment = LLEnvironment::instance();
+
+ bool sun_up = environment.getIsSunUp();
+ bool moon_up = environment.getIsMoonUp();
+
{
setupHWLights(NULL); //to set mSun/MoonDir;
glh::vec4f tc(mSunDir.mV);
mat.mult_matrix_vec(tc);
- mTransformedSunDir.set(tc.v);
- mTransformedSunDir.normalize();
glh::vec4f tc_moon(mMoonDir.mV);
mTransformedMoonDir.set(tc_moon.v);
mTransformedMoonDir.normalize();
+
+ bool sun_is_primary = sun_up || !moon_up;
+ if (sun_is_primary)
+ {
+ mTransformedSunDir.set(tc.v);
+ mTransformedSunDir.normalize();
+ }
+ else
+ {
+ mTransformedSunDir.set(tc_moon.v);
+ mTransformedSunDir.normalize();
+ }
}
gGL.pushMatrix();
@@ -10697,17 +10736,20 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
//LLVector3 n = RenderShadowNearDist;
//F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] };
- LLVector3 sun_dir(mSunDir);
+ LLEnvironment& environment = LLEnvironment::instance();
+ LLSettingsSky::ptr_t psky = environment.getCurrentSky();
+
+ LLVector3 caster_dir(environment.getIsSunUp() ? mSunDir : mMoonDir);
//put together a universal "near clip" plane for shadow frusta
LLPlane shadow_near_clip;
{
LLVector3 p = gAgent.getPositionAgent();
- p += sun_dir * RenderFarClip*2.f;
- shadow_near_clip.setVec(p, sun_dir);
+ p += caster_dir * RenderFarClip*2.f;
+ shadow_near_clip.setVec(p, caster_dir);
}
- LLVector3 lightDir = -sun_dir;
+ LLVector3 lightDir = -caster_dir;
lightDir.normVec();
glh::vec3f light_dir(lightDir.mV);
@@ -10810,9 +10852,15 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
// convenience array of 4 near clip plane distances
F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] };
-
- if (mSunDiffuse == LLColor4::black)
+ bool sun_up = environment.getIsSunUp();
+ bool moon_up = environment.getIsMoonUp();
+ bool sun_is_primary = sun_up || !moon_up;
+ bool ignore_shadows = (sun_is_primary && (mSunDiffuse == LLColor4::black))
+ || (moon_up && (mMoonDiffuse == LLColor4::black))
+ || !(sun_up || moon_up);
+
+ if (ignore_shadows)
{ //sun diffuse is totally black, shadows don't matter
LLGLDepthTest depth(GL_TRUE);
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 57d2331222..9977781065 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -663,6 +663,7 @@ public:
U32 mLightFunc;
LLColor4 mSunDiffuse;
+ LLColor4 mMoonDiffuse;
LLVector4 mSunDir;
LLVector4 mMoonDir;
diff --git a/indra/newview/skins/default/xui/en/floater_beacons.xml b/indra/newview/skins/default/xui/en/floater_beacons.xml
index 3d29356b22..d5947fc0af 100644
--- a/indra/newview/skins/default/xui/en/floater_beacons.xml
+++ b/indra/newview/skins/default/xui/en/floater_beacons.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
legacy_header_height="18"
- height="245"
+ height="310"
layout="topleft"
name="beacons"
help_topic="beacons"
@@ -12,7 +12,7 @@
width="240">
<panel
follows="left|top|right|bottom"
- height="240"
+ height="305"
layout="topleft"
left="10"
name="beacons_panel"
@@ -143,6 +143,43 @@
<check_box.commit_callback
function="Beacons.UICheck" />
</check_box>
+ <view_border
+ bevel_style="in"
+ height="0"
+ layout="topleft"
+ left="0"
+ name="cost_text_border"
+ top_pad="5"
+ width="220"/>
+ <text
+ follows="all"
+ height="16"
+ font="SansSerif"
+ left="0"
+ top_pad="7"
+ name="label_objects"
+ text_color="White"
+ type="string">
+ Show direction to:
+ </text>
+ <check_box
+ control_name="sunbeacon"
+ height="16"
+ label="Sun"
+ layout="topleft"
+ name="sun" >
+ <check_box.commit_callback
+ function="Beacons.UICheck" />
+ </check_box>
+ <check_box
+ control_name="moonbeacon"
+ height="16"
+ label="Moon"
+ layout="topleft"
+ name="moon" >
+ <check_box.commit_callback
+ function="Beacons.UICheck" />
+ </check_box>
</panel>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml b/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml
index 9aa7c6f499..cac6f334c7 100644
--- a/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml
+++ b/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml
@@ -21,6 +21,8 @@
<!-- Substitutions -->
<string name="time_label"> ([HH]:[MM])</string>
<string name="sky_track_label">Sky [ALT]</string>
+ <string name="sky_label">Sky</string>
+ <string name="water_label">Water</string>
<!-- Layout -->
<layout_stack name="outer_stack"
@@ -400,7 +402,7 @@
follows="top|left"
height="23"
width="90"
- label="Add Frame"
+ label="Add [FRAME]"
left_pad="175"
top_delta="-20"
name="add_frame" />
@@ -408,7 +410,7 @@
follows="top|left"
height="23"
width="90"
- label="Load Frame"
+ label="Load [FRAME]"
top_pad="0"
left_delta="0"
name="btn_load_frame" />
@@ -416,7 +418,7 @@
follows="left|top"
height="23"
width="90"
- label="Delete Frame"
+ label="Delete [FRAME]"
top_pad="0"
left_delta="0"
name="delete_frame" />
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 33c2224b9d..10e98719a4 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -4094,6 +4094,8 @@ Try enclosing path to the editor with double quotes.
<string name="BeaconScriptedTouch">Viewing scripted object with touch function beacons (red)</string>
<string name="BeaconSound">Viewing sound beacons (yellow)</string>
<string name="BeaconMedia">Viewing media beacons (white)</string>
+ <string name="BeaconSun">Viewing sun direction beacon (orange)</string>
+ <string name="BeaconMoon">Viewing moon direction beacon (purple)</string>
<string name="ParticleHiding">Hiding Particles</string>
<!-- commands -->