From e2be90caafc605ecba141172577d9bdff83b005f Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 10 Jun 2020 09:26:55 +0100 Subject: [PATCH] replace lightshare early work --- OpenSim/Data/MySQL/MySQLSimulationData.cs | 222 --- OpenSim/Data/PGSQL/PGSQLSimulationData.cs | 471 ------- OpenSim/Data/SQLite/SQLiteSimulationData.cs | 222 +-- OpenSim/Framework/RegionInfo.cs | 74 - OpenSim/Framework/ViewerEnviroment.cs | 1233 +++++++++++++++++ .../World/LightShare/EnvironmentModule.cs | 591 +++++++- .../World/LightShare/LightShareModule.cs | 301 ---- .../Interfaces/IEnvironmentModule.cs | 6 +- .../Interfaces/ISimulationDataService.cs | 3 - .../Interfaces/ISimulationDataStore.cs | 4 +- .../Region/Framework/Scenes/EventManager.cs | 24 - OpenSim/Region/Framework/Scenes/Scene.cs | 20 +- .../Shared/Api/Implementation/LS_Api.cs | 66 +- .../SimulationDataService.cs | 14 - .../Tests/Common/Mock/MockRegionDataPlugin.cs | 30 - bin/assets/AssetSets.xml | 4 + .../SettingsAssetSet/DefaultDaycycle.xml | 1 + .../SettingsAssetSet/SettingsAssetSet.xml | 9 + bin/assets/TexturesAssetSet/DefaultClouds.j2c | Bin 0 -> 58521 bytes .../TexturesAssetSet/TexturesAssetSet.xml | 7 + bin/inventory/Libraries.xml | 4 + bin/inventory/SettingsLibrary/Folders.xml | 28 + bin/inventory/SettingsLibrary/Items.xml | 40 + 23 files changed, 1917 insertions(+), 1457 deletions(-) create mode 100644 OpenSim/Framework/ViewerEnviroment.cs delete mode 100644 OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs create mode 100644 bin/assets/SettingsAssetSet/DefaultDaycycle.xml create mode 100644 bin/assets/SettingsAssetSet/SettingsAssetSet.xml create mode 100644 bin/assets/TexturesAssetSet/DefaultClouds.j2c create mode 100644 bin/inventory/SettingsLibrary/Folders.xml create mode 100644 bin/inventory/SettingsLibrary/Items.xml diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index f1d33b9a1d..32c5655877 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs @@ -863,107 +863,6 @@ namespace OpenSim.Data.MySQL } } - public virtual RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID) - { - RegionLightShareData nWP = new RegionLightShareData(); - nWP.OnSave += StoreRegionWindlightSettings; - - using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) - { - dbcon.Open(); - - string command = "select * from `regionwindlight` where region_id = ?regionID"; - - using (MySqlCommand cmd = new MySqlCommand(command)) - { - cmd.Connection = dbcon; - - cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString()); - - using(IDataReader result = ExecuteReader(cmd)) - { - if(!result.Read()) - { - //No result, so store our default windlight profile and return it - nWP.regionID = regionUUID; - // StoreRegionWindlightSettings(nWP); - return nWP; - } - else - { - nWP.regionID = DBGuid.FromDB(result["region_id"]); - nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]); - nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]); - nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]); - nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]); - nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]); - nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]); - nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]); - nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]); - nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]); - nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]); - nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]); - nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]); - nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]); - nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]); - nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]); - nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]); - nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]); - UUID.TryParse(result["normal_map_texture"].ToString(),out nWP.normalMapTexture); - nWP.horizon.X = Convert.ToSingle(result["horizon_r"]); - nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]); - nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]); - nWP.horizon.W = Convert.ToSingle(result["horizon_i"]); - nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]); - nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]); - nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]); - nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]); - nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]); - nWP.hazeDensity = Convert.ToSingle(result["haze_density"]); - nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]); - nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]); - nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]); - nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]); - nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]); - nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]); - nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]); - nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]); - nWP.ambient.X = Convert.ToSingle(result["ambient_r"]); - nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]); - nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]); - nWP.ambient.W = Convert.ToSingle(result["ambient_i"]); - nWP.eastAngle = Convert.ToSingle(result["east_angle"]); - nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]); - nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]); - nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]); - nWP.starBrightness = Convert.ToSingle(result["star_brightness"]); - nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]); - nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]); - nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]); - nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]); - nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]); - nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]); - nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]); - nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]); - nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]); - nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]); - nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]); - nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]); - nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]); - nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]); - nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]); - nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]); - nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]); - nWP.valid = true; - } - } - } - dbcon.Close(); - } - - return nWP; - } - public virtual RegionSettings LoadRegionSettings(UUID regionUUID) { RegionSettings rs = null; @@ -1009,127 +908,6 @@ namespace OpenSim.Data.MySQL return rs; } - public virtual void StoreRegionWindlightSettings(RegionLightShareData wl) - { - using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) - { - dbcon.Open(); - - using (MySqlCommand cmd = dbcon.CreateCommand()) - { - cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, " - + "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, " - + "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, " - + "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, " - + "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, " - + "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, " - + "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, " - + "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, " - + "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, " - + "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, " - + "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, " - + "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, " - + "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, " - + "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, " - + "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, " - + "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, " - + "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, " - + "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, " - + "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, " - + "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, " - + "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, " - + "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, " - + "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, " - + "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, " - + "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)" - ; - - cmd.Parameters.AddWithValue("region_id", wl.regionID); - cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X); - cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y); - cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z); - cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent); - cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier); - cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X); - cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y); - cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z); - cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale); - cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset); - cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove); - cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow); - cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier); - cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X); - cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y); - cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X); - cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y); - cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture); - cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X); - cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y); - cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z); - cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W); - cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon); - cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X); - cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y); - cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z); - cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W); - cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity); - cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier); - cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier); - cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude); - cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X); - cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y); - cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z); - cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W); - cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition); - cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X); - cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y); - cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z); - cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W); - cmd.Parameters.AddWithValue("east_angle", wl.eastAngle); - cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus); - cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize); - cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma); - cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness); - cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X); - cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y); - cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z); - cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W); - cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X); - cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y); - cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z); - cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage); - cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale); - cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X); - cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y); - cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z); - cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX); - cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock); - cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY); - cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock); - cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds); - - ExecuteNonQuery(cmd); - } - dbcon.Close(); - } - } - - public virtual void RemoveRegionWindlightSettings(UUID regionID) - { - using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) - { - dbcon.Open(); - - using (MySqlCommand cmd = dbcon.CreateCommand()) - { - cmd.CommandText = "delete from `regionwindlight` where `region_id`=?regionID"; - cmd.Parameters.AddWithValue("?regionID", regionID.ToString()); - ExecuteNonQuery(cmd); - } - dbcon.Close(); - } - } - #region RegionEnvironmentSettings public string LoadRegionEnvironmentSettings(UUID regionUUID) { diff --git a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs index dd2ad449c0..e65576fbc5 100755 --- a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs +++ b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs @@ -825,477 +825,6 @@ namespace OpenSim.Data.PGSQL cmd.ExecuteNonQuery(); } } - public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID) - { - RegionLightShareData nWP = new RegionLightShareData(); - nWP.OnSave += StoreRegionWindlightSettings; - - string sql = @"select * from regionwindlight where ""region_id"" = :regionID"; - - using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) - using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn)) - { - cmd.Parameters.Add(_Database.CreateParameter("regionID", regionUUID.ToString() )); - conn.Open(); - using (NpgsqlDataReader result = cmd.ExecuteReader()) - { - if (!result.Read()) - { - //No result, so store our default windlight profile and return it - nWP.regionID = regionUUID; - StoreRegionWindlightSettings(nWP); - return nWP; - } - else - { - nWP.regionID = DBGuid.FromDB(result["region_id"]); - nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]); - nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]); - nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]); - nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]); - nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]); - nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]); - nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]); - nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]); - nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]); - nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]); - nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]); - nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]); - nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]); - nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]); - nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]); - nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]); - nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]); - UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture); - nWP.horizon.X = Convert.ToSingle(result["horizon_r"]); - nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]); - nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]); - nWP.horizon.W = Convert.ToSingle(result["horizon_i"]); - nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]); - nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]); - nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]); - nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]); - nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]); - nWP.hazeDensity = Convert.ToSingle(result["haze_density"]); - nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]); - nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]); - nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]); - nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]); - nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]); - nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]); - nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]); - nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]); - nWP.ambient.X = Convert.ToSingle(result["ambient_r"]); - nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]); - nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]); - nWP.ambient.W = Convert.ToSingle(result["ambient_i"]); - nWP.eastAngle = Convert.ToSingle(result["east_angle"]); - nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]); - nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]); - nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]); - nWP.starBrightness = Convert.ToSingle(result["star_brightness"]); - nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]); - nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]); - nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]); - nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]); - nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]); - nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]); - nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]); - nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]); - nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]); - nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]); - nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]); - nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]); - nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]); - nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]); - nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]); - nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]); - nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]); - nWP.valid = true; - } - } - } - return nWP; - } - - public void RemoveRegionWindlightSettings(UUID regionID) - { - string sql = @"delete from regionwindlight where ""region_id"" = :region_id"; - using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) - using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn)) - { - conn.Open(); - cmd.Parameters.Add(_Database.CreateParameter("region_id", regionID.ToString())); - cmd.ExecuteNonQuery(); - } - } - - public void StoreRegionWindlightSettings(RegionLightShareData wl) - { - string sql = @"select region_id from regionwindlight where ""region_id"" = :region_id limit 1;"; - bool exists = false; - using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) - { - conn.Open(); - using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn)) - { - cmd.Parameters.Add(_Database.CreateParameter("region_id", wl.regionID.ToString() )); - NpgsqlDataReader dr = cmd.ExecuteReader(); - exists = dr.Read(); - } - } - if (exists) - { - RemoveRegionWindlightSettings(wl.regionID); - } - - // sql insert - sql = @"INSERT INTO regionwindlight - (region_id - ,water_color_r - ,water_color_g - ,water_color_b - ,water_fog_density_exponent - ,underwater_fog_modifier - ,reflection_wavelet_scale_1 - ,reflection_wavelet_scale_2 - ,reflection_wavelet_scale_3 - ,fresnel_scale - ,fresnel_offset - ,refract_scale_above - ,refract_scale_below - ,blur_multiplier - ,big_wave_direction_x - ,big_wave_direction_y - ,little_wave_direction_x - ,little_wave_direction_y - ,normal_map_texture - ,horizon_r - ,horizon_g - ,horizon_b - ,horizon_i - ,haze_horizon - ,blue_density_r - ,blue_density_g - ,blue_density_b - ,blue_density_i - ,haze_density - ,density_multiplier - ,distance_multiplier - ,max_altitude - ,sun_moon_color_r - ,sun_moon_color_g - ,sun_moon_color_b - ,sun_moon_color_i - ,sun_moon_position - ,ambient_r - ,ambient_g - ,ambient_b - ,ambient_i - ,east_angle - ,sun_glow_focus - ,sun_glow_size - ,scene_gamma - ,star_brightness - ,cloud_color_r - ,cloud_color_g - ,cloud_color_b - ,cloud_color_i - ,cloud_x - ,cloud_y - ,cloud_density - ,cloud_coverage - ,cloud_scale - ,cloud_detail_x - ,cloud_detail_y - ,cloud_detail_density - ,cloud_scroll_x - ,cloud_scroll_x_lock - ,cloud_scroll_y - ,cloud_scroll_y_lock - ,draw_classic_clouds) - VALUES - (:region_id - ,:water_color_r - ,:water_color_g - ,:water_color_b - ,:water_fog_density_exponent - ,:underwater_fog_modifier - ,:reflection_wavelet_scale_1 - ,:reflection_wavelet_scale_2 - ,:reflection_wavelet_scale_3 - ,:fresnel_scale - ,:fresnel_offset - ,:refract_scale_above - ,:refract_scale_below - ,:blur_multiplier - ,:big_wave_direction_x - ,:big_wave_direction_y - ,:little_wave_direction_x - ,:little_wave_direction_y - ,:normal_map_texture - ,:horizon_r - ,:horizon_g - ,:horizon_b - ,:horizon_i - ,:haze_horizon - ,:blue_density_r - ,:blue_density_g - ,:blue_density_b - ,:blue_density_i - ,:haze_density - ,:density_multiplier - ,:distance_multiplier - ,:max_altitude - ,:sun_moon_color_r - ,:sun_moon_color_g - ,:sun_moon_color_b - ,:sun_moon_color_i - ,:sun_moon_position - ,:ambient_r - ,:ambient_g - ,:ambient_b - ,:ambient_i - ,:east_angle - ,:sun_glow_focus - ,:sun_glow_size - ,:scene_gamma - ,:star_brightness - ,:cloud_color_r - ,:cloud_color_g - ,:cloud_color_b - ,:cloud_color_i - ,:cloud_x - ,:cloud_y - ,:cloud_density - ,:cloud_coverage - ,:cloud_scale - ,:cloud_detail_x - ,:cloud_detail_y - ,:cloud_detail_density - ,:cloud_scroll_x - ,:cloud_scroll_x_lock - ,:cloud_scroll_y - ,:cloud_scroll_y_lock - ,:draw_classic_clouds);"; - - using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString)) - { - conn.Open(); - using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn)) - { - cmd.Parameters.Add(_Database.CreateParameter("region_id", wl.regionID.ToString())); - cmd.Parameters.Add(_Database.CreateParameter("water_color_r", wl.waterColor.X)); - cmd.Parameters.Add(_Database.CreateParameter("water_color_g", wl.waterColor.Y)); - cmd.Parameters.Add(_Database.CreateParameter("water_color_b", wl.waterColor.Z)); - cmd.Parameters.Add(_Database.CreateParameter("water_fog_density_exponent", wl.waterFogDensityExponent)); - cmd.Parameters.Add(_Database.CreateParameter("underwater_fog_modifier", wl.underwaterFogModifier)); - cmd.Parameters.Add(_Database.CreateParameter("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X)); - cmd.Parameters.Add(_Database.CreateParameter("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y)); - cmd.Parameters.Add(_Database.CreateParameter("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z)); - cmd.Parameters.Add(_Database.CreateParameter("fresnel_scale", wl.fresnelScale)); - cmd.Parameters.Add(_Database.CreateParameter("fresnel_offset", wl.fresnelOffset)); - cmd.Parameters.Add(_Database.CreateParameter("refract_scale_above", wl.refractScaleAbove)); - cmd.Parameters.Add(_Database.CreateParameter("refract_scale_below", wl.refractScaleBelow)); - cmd.Parameters.Add(_Database.CreateParameter("blur_multiplier", wl.blurMultiplier)); - cmd.Parameters.Add(_Database.CreateParameter("big_wave_direction_x", wl.bigWaveDirection.X)); - cmd.Parameters.Add(_Database.CreateParameter("big_wave_direction_y", wl.bigWaveDirection.Y)); - cmd.Parameters.Add(_Database.CreateParameter("little_wave_direction_x", wl.littleWaveDirection.X)); - cmd.Parameters.Add(_Database.CreateParameter("little_wave_direction_y", wl.littleWaveDirection.Y)); - cmd.Parameters.Add(_Database.CreateParameter("normal_map_texture", wl.normalMapTexture.ToString())); - cmd.Parameters.Add(_Database.CreateParameter("horizon_r", wl.horizon.X)); - cmd.Parameters.Add(_Database.CreateParameter("horizon_g", wl.horizon.Y)); - cmd.Parameters.Add(_Database.CreateParameter("horizon_b", wl.horizon.Z)); - cmd.Parameters.Add(_Database.CreateParameter("horizon_i", wl.horizon.W)); - cmd.Parameters.Add(_Database.CreateParameter("haze_horizon", wl.hazeHorizon)); - cmd.Parameters.Add(_Database.CreateParameter("blue_density_r", wl.blueDensity.X)); - cmd.Parameters.Add(_Database.CreateParameter("blue_density_g", wl.blueDensity.Y)); - cmd.Parameters.Add(_Database.CreateParameter("blue_density_b", wl.blueDensity.Z)); - cmd.Parameters.Add(_Database.CreateParameter("blue_density_i", wl.blueDensity.W)); - cmd.Parameters.Add(_Database.CreateParameter("haze_density", wl.hazeDensity)); - cmd.Parameters.Add(_Database.CreateParameter("density_multiplier", wl.densityMultiplier)); - cmd.Parameters.Add(_Database.CreateParameter("distance_multiplier", wl.distanceMultiplier)); - cmd.Parameters.Add(_Database.CreateParameter("max_altitude", wl.maxAltitude)); - cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_r", wl.sunMoonColor.X)); - cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_g", wl.sunMoonColor.Y)); - cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_b", wl.sunMoonColor.Z)); - cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_i", wl.sunMoonColor.W)); - cmd.Parameters.Add(_Database.CreateParameter("sun_moon_position", wl.sunMoonPosition)); - cmd.Parameters.Add(_Database.CreateParameter("ambient_r", wl.ambient.X)); - cmd.Parameters.Add(_Database.CreateParameter("ambient_g", wl.ambient.Y)); - cmd.Parameters.Add(_Database.CreateParameter("ambient_b", wl.ambient.Z)); - cmd.Parameters.Add(_Database.CreateParameter("ambient_i", wl.ambient.W)); - cmd.Parameters.Add(_Database.CreateParameter("east_angle", wl.eastAngle)); - cmd.Parameters.Add(_Database.CreateParameter("sun_glow_focus", wl.sunGlowFocus)); - cmd.Parameters.Add(_Database.CreateParameter("sun_glow_size", wl.sunGlowSize)); - cmd.Parameters.Add(_Database.CreateParameter("scene_gamma", wl.sceneGamma)); - cmd.Parameters.Add(_Database.CreateParameter("star_brightness", wl.starBrightness)); - cmd.Parameters.Add(_Database.CreateParameter("cloud_color_r", wl.cloudColor.X)); - cmd.Parameters.Add(_Database.CreateParameter("cloud_color_g", wl.cloudColor.Y)); - cmd.Parameters.Add(_Database.CreateParameter("cloud_color_b", wl.cloudColor.Z)); - cmd.Parameters.Add(_Database.CreateParameter("cloud_color_i", wl.cloudColor.W)); - cmd.Parameters.Add(_Database.CreateParameter("cloud_x", wl.cloudXYDensity.X)); - cmd.Parameters.Add(_Database.CreateParameter("cloud_y", wl.cloudXYDensity.Y)); - cmd.Parameters.Add(_Database.CreateParameter("cloud_density", wl.cloudXYDensity.Z)); - cmd.Parameters.Add(_Database.CreateParameter("cloud_coverage", wl.cloudCoverage)); - cmd.Parameters.Add(_Database.CreateParameter("cloud_scale", wl.cloudScale)); - cmd.Parameters.Add(_Database.CreateParameter("cloud_detail_x", wl.cloudDetailXYDensity.X)); - cmd.Parameters.Add(_Database.CreateParameter("cloud_detail_y", wl.cloudDetailXYDensity.Y)); - cmd.Parameters.Add(_Database.CreateParameter("cloud_detail_density", wl.cloudDetailXYDensity.Z)); - cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_x", wl.cloudScrollX)); - cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_x_lock", wl.cloudScrollXLock)); - cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_y", wl.cloudScrollY)); - cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_y_lock", wl.cloudScrollYLock)); - cmd.Parameters.Add(_Database.CreateParameter("draw_classic_clouds", wl.drawClassicClouds)); - - cmd.ExecuteNonQuery(); - } - } - #region update - // } - // else - // { - // // sql update - // sql = @"UPDATE [OpenSim].[dbo].[regionwindlight] - // SET [region_id] = @region_id - // ,[water_color_r] = @water_color_r - // ,[water_color_g] = @water_color_g - // ,[water_color_b] = @water_color_b - // ,[water_fog_density_exponent] = @water_fog_density_exponent - // ,[underwater_fog_modifier] = @underwater_fog_modifier - // ,[reflection_wavelet_scale_1] = @reflection_wavelet_scale_1 - // ,[reflection_wavelet_scale_2] = @reflection_wavelet_scale_2 - // ,[reflection_wavelet_scale_3] = @reflection_wavelet_scale_3 - // ,[fresnel_scale] = @fresnel_scale - // ,[fresnel_offset] = @fresnel_offset - // ,[refract_scale_above] = @refract_scale_above - // ,[refract_scale_below] = @refract_scale_below - // ,[blur_multiplier] = @blur_multiplier - // ,[big_wave_direction_x] = @big_wave_direction_x - // ,[big_wave_direction_y] = @big_wave_direction_y - // ,[little_wave_direction_x] = @little_wave_direction_x - // ,[little_wave_direction_y] = @little_wave_direction_y - // ,[normal_map_texture] = @normal_map_texture - // ,[horizon_r] = @horizon_r - // ,[horizon_g] = @horizon_g - // ,[horizon_b] = @horizon_b - // ,[horizon_i] = @horizon_i - // ,[haze_horizon] = @haze_horizon - // ,[blue_density_r] = @blue_density_r - // ,[blue_density_g] = @blue_density_g - // ,[blue_density_b] = @blue_density_b - // ,[blue_density_i] = @blue_density_i - // ,[haze_density] = @haze_density - // ,[density_multiplier] = @density_multiplier - // ,[distance_multiplier] = @distance_multiplier - // ,[max_altitude] = @max_altitude - // ,[sun_moon_color_r] = @sun_moon_color_r - // ,[sun_moon_color_g] = @sun_moon_color_g - // ,[sun_moon_color_b] = @sun_moon_color_b - // ,[sun_moon_color_i] = @sun_moon_color_i - // ,[sun_moon_position] = @sun_moon_position - // ,[ambient_r] = @ambient_r - // ,[ambient_g] = @ambient_g - // ,[ambient_b] = @ambient_b - // ,[ambient_i] = @ambient_i - // ,[east_angle] = @east_angle - // ,[sun_glow_focus] = @sun_glow_focus - // ,[sun_glow_size] = @sun_glow_size - // ,[scene_gamma] = @scene_gamma - // ,[star_brightness] = @star_brightness - // ,[cloud_color_r] = @cloud_color_r - // ,[cloud_color_g] = @cloud_color_g - // ,[cloud_color_b] = @cloud_color_b - // ,[cloud_color_i] = @cloud_color_i - // ,[cloud_x] = @cloud_x - // ,[cloud_y] = @cloud_y - // ,[cloud_density] = @cloud_density - // ,[cloud_coverage] = @cloud_coverage - // ,[cloud_scale] = @cloud_scale - // ,[cloud_detail_x] = @cloud_detail_x - // ,[cloud_detail_y] = @cloud_detail_y - // ,[cloud_detail_density] = @cloud_detail_density - // ,[cloud_scroll_x] = @cloud_scroll_x - // ,[cloud_scroll_x_lock] = @cloud_scroll_x_lock - // ,[cloud_scroll_y] = @cloud_scroll_y - // ,[cloud_scroll_y_lock] = @cloud_scroll_y_lock - // ,[draw_classic_clouds] = @draw_classic_clouds - // WHERE region_id = @region_id"; - // using (SqlConnection conn = new SqlConnection(m_connectionString)) - // { - // conn.Open(); - // using (SqlCommand cmd = new SqlCommand(sql, conn)) - // { - // cmd.Parameters.AddWithValue("region_id", wl.regionID); - // cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X); - // cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y); - // cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z); - // cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent); - // cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier); - // cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X); - // cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y); - // cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z); - // cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale); - // cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset); - // cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove); - // cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow); - // cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier); - // cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X); - // cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y); - // cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X); - // cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y); - // cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture); - // cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X); - // cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y); - // cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z); - // cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W); - // cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon); - // cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X); - // cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y); - // cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z); - // cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W); - // cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity); - // cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier); - // cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier); - // cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude); - // cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X); - // cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y); - // cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z); - // cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W); - // cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition); - // cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X); - // cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y); - // cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z); - // cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W); - // cmd.Parameters.AddWithValue("east_angle", wl.eastAngle); - // cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus); - // cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize); - // cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma); - // cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness); - // cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X); - // cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y); - // cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z); - // cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W); - // cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X); - // cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y); - // cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z); - // cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage); - // cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale); - // cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X); - // cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y); - // cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z); - // cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX); - // cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock); - // cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY); - // cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock); - // cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds); - - // cmd.ExecuteNonQuery(); - // } - // } - // } - #endregion - } #region Environment Settings public string LoadRegionEnvironmentSettings(UUID regionUUID) diff --git a/OpenSim/Data/SQLite/SQLiteSimulationData.cs b/OpenSim/Data/SQLite/SQLiteSimulationData.cs index 3b9e46a884..c51e1c7464 100644 --- a/OpenSim/Data/SQLite/SQLiteSimulationData.cs +++ b/OpenSim/Data/SQLite/SQLiteSimulationData.cs @@ -429,75 +429,6 @@ namespace OpenSim.Data.SQLite } } - /// - /// Load windlight settings from region storage - /// - /// RegionID - public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID) - { - RegionLightShareData wl = null; - - lock (ds) - { - DataTable windlightTable = ds.Tables["regionwindlight"]; - DataRow windlightRow = windlightTable.Rows.Find(regionUUID.ToString()); - if (windlightRow == null) - { - wl = new RegionLightShareData(); - wl.regionID = regionUUID; - StoreRegionWindlightSettings(wl); - return wl; - } - wl = buildRegionWindlight(windlightRow); - return wl; - } - } - - /// - /// Remove windlight settings from region storage - /// - /// RegionID - public void RemoveRegionWindlightSettings(UUID regionID) - { - lock (ds) - { - DataTable windlightTable = ds.Tables["regionwindlight"]; - DataRow windlightRow = windlightTable.Rows.Find(regionID.ToString()); - - if (windlightRow != null) - { - windlightRow.Delete(); - } - } - Commit(); - } - - /// - /// Adds an windlight into region storage - /// - /// RegionLightShareData - public void StoreRegionWindlightSettings(RegionLightShareData wl) - { - lock (ds) - { - DataTable windlightTable = ds.Tables["regionwindlight"]; - DataRow windlightRow = windlightTable.Rows.Find(wl.regionID.ToString()); - - if (windlightRow == null) - { - windlightRow = windlightTable.NewRow(); - fillRegionWindlightRow(windlightRow, wl); - windlightTable.Rows.Add(windlightRow); - } - else - { - fillRegionWindlightRow(windlightRow, wl); - } - - Commit(); - } - } - #region Region Environment Settings public string LoadRegionEnvironmentSettings(UUID regionUUID) { @@ -2038,86 +1969,12 @@ namespace OpenSim.Data.SQLite newSettings.ParcelImageID = new UUID((String)row["parcel_tile_ID"]); newSettings.GodBlockSearch = Convert.ToBoolean(row["block_search"]); newSettings.Casino = Convert.ToBoolean(row["casino"]); + if (!(row["cacheID"] is System.DBNull)) + newSettings.CacheID = new UUID((String)row["cacheID"]); + return newSettings; } - /// - /// Build a windlight entry from the persisted data. - /// - /// - /// RegionLightShareData - private RegionLightShareData buildRegionWindlight(DataRow row) - { - RegionLightShareData windlight = new RegionLightShareData(); - - windlight.regionID = new UUID((string)row["region_id"]); - windlight.waterColor.X = Convert.ToSingle(row["water_color_r"]); - windlight.waterColor.Y = Convert.ToSingle(row["water_color_g"]); - windlight.waterColor.Z = Convert.ToSingle(row["water_color_b"]); - //windlight.waterColor.W = Convert.ToSingle(row["water_color_i"]); //not implemented - windlight.waterFogDensityExponent = Convert.ToSingle(row["water_fog_density_exponent"]); - windlight.underwaterFogModifier = Convert.ToSingle(row["underwater_fog_modifier"]); - windlight.reflectionWaveletScale.X = Convert.ToSingle(row["reflection_wavelet_scale_1"]); - windlight.reflectionWaveletScale.Y = Convert.ToSingle(row["reflection_wavelet_scale_2"]); - windlight.reflectionWaveletScale.Z = Convert.ToSingle(row["reflection_wavelet_scale_3"]); - windlight.fresnelScale = Convert.ToSingle(row["fresnel_scale"]); - windlight.fresnelOffset = Convert.ToSingle(row["fresnel_offset"]); - windlight.refractScaleAbove = Convert.ToSingle(row["refract_scale_above"]); - windlight.refractScaleBelow = Convert.ToSingle(row["refract_scale_below"]); - windlight.blurMultiplier = Convert.ToSingle(row["blur_multiplier"]); - windlight.bigWaveDirection.X = Convert.ToSingle(row["big_wave_direction_x"]); - windlight.bigWaveDirection.Y = Convert.ToSingle(row["big_wave_direction_y"]); - windlight.littleWaveDirection.X = Convert.ToSingle(row["little_wave_direction_x"]); - windlight.littleWaveDirection.Y = Convert.ToSingle(row["little_wave_direction_y"]); - windlight.normalMapTexture = new UUID((string)row["normal_map_texture"]); - windlight.horizon.X = Convert.ToSingle(row["horizon_r"]); - windlight.horizon.Y = Convert.ToSingle(row["horizon_g"]); - windlight.horizon.Z = Convert.ToSingle(row["horizon_b"]); - windlight.horizon.W = Convert.ToSingle(row["horizon_i"]); - windlight.hazeHorizon = Convert.ToSingle(row["haze_horizon"]); - windlight.blueDensity.X = Convert.ToSingle(row["blue_density_r"]); - windlight.blueDensity.Y = Convert.ToSingle(row["blue_density_g"]); - windlight.blueDensity.Z = Convert.ToSingle(row["blue_density_b"]); - windlight.blueDensity.W = Convert.ToSingle(row["blue_density_i"]); - windlight.hazeDensity = Convert.ToSingle(row["haze_density"]); - windlight.densityMultiplier = Convert.ToSingle(row["density_multiplier"]); - windlight.distanceMultiplier = Convert.ToSingle(row["distance_multiplier"]); - windlight.maxAltitude = Convert.ToUInt16(row["max_altitude"]); - windlight.sunMoonColor.X = Convert.ToSingle(row["sun_moon_color_r"]); - windlight.sunMoonColor.Y = Convert.ToSingle(row["sun_moon_color_g"]); - windlight.sunMoonColor.Z = Convert.ToSingle(row["sun_moon_color_b"]); - windlight.sunMoonColor.W = Convert.ToSingle(row["sun_moon_color_i"]); - windlight.sunMoonPosition = Convert.ToSingle(row["sun_moon_position"]); - windlight.ambient.X = Convert.ToSingle(row["ambient_r"]); - windlight.ambient.Y = Convert.ToSingle(row["ambient_g"]); - windlight.ambient.Z = Convert.ToSingle(row["ambient_b"]); - windlight.ambient.W = Convert.ToSingle(row["ambient_i"]); - windlight.eastAngle = Convert.ToSingle(row["east_angle"]); - windlight.sunGlowFocus = Convert.ToSingle(row["sun_glow_focus"]); - windlight.sunGlowSize = Convert.ToSingle(row["sun_glow_size"]); - windlight.sceneGamma = Convert.ToSingle(row["scene_gamma"]); - windlight.starBrightness = Convert.ToSingle(row["star_brightness"]); - windlight.cloudColor.X = Convert.ToSingle(row["cloud_color_r"]); - windlight.cloudColor.Y = Convert.ToSingle(row["cloud_color_g"]); - windlight.cloudColor.Z = Convert.ToSingle(row["cloud_color_b"]); - windlight.cloudColor.W = Convert.ToSingle(row["cloud_color_i"]); - windlight.cloudXYDensity.X = Convert.ToSingle(row["cloud_x"]); - windlight.cloudXYDensity.Y = Convert.ToSingle(row["cloud_y"]); - windlight.cloudXYDensity.Z = Convert.ToSingle(row["cloud_density"]); - windlight.cloudCoverage = Convert.ToSingle(row["cloud_coverage"]); - windlight.cloudScale = Convert.ToSingle(row["cloud_scale"]); - windlight.cloudDetailXYDensity.X = Convert.ToSingle(row["cloud_detail_x"]); - windlight.cloudDetailXYDensity.Y = Convert.ToSingle(row["cloud_detail_y"]); - windlight.cloudDetailXYDensity.Z = Convert.ToSingle(row["cloud_detail_density"]); - windlight.cloudScrollX = Convert.ToSingle(row["cloud_scroll_x"]); - windlight.cloudScrollXLock = Convert.ToBoolean(row["cloud_scroll_x_lock"]); - windlight.cloudScrollY = Convert.ToSingle(row["cloud_scroll_y"]); - windlight.cloudScrollYLock = Convert.ToBoolean(row["cloud_scroll_y_lock"]); - windlight.drawClassicClouds = Convert.ToBoolean(row["draw_classic_clouds"]); - - return windlight; - } - /// /// Build a land access entry from the persisted data. /// @@ -2461,79 +2318,6 @@ namespace OpenSim.Data.SQLite row["cacheID"] = settings.CacheID; } - /// - /// - /// - /// - /// - private static void fillRegionWindlightRow(DataRow row, RegionLightShareData windlight) - { - row["region_id"] = windlight.regionID.ToString(); - row["water_color_r"] = windlight.waterColor.X; - row["water_color_g"] = windlight.waterColor.Y; - row["water_color_b"] = windlight.waterColor.Z; - row["water_color_i"] = 1; //windlight.waterColor.W; //not implemented - row["water_fog_density_exponent"] = windlight.waterFogDensityExponent; - row["underwater_fog_modifier"] = windlight.underwaterFogModifier; - row["reflection_wavelet_scale_1"] = windlight.reflectionWaveletScale.X; - row["reflection_wavelet_scale_2"] = windlight.reflectionWaveletScale.Y; - row["reflection_wavelet_scale_3"] = windlight.reflectionWaveletScale.Z; - row["fresnel_scale"] = windlight.fresnelScale; - row["fresnel_offset"] = windlight.fresnelOffset; - row["refract_scale_above"] = windlight.refractScaleAbove; - row["refract_scale_below"] = windlight.refractScaleBelow; - row["blur_multiplier"] = windlight.blurMultiplier; - row["big_wave_direction_x"] = windlight.bigWaveDirection.X; - row["big_wave_direction_y"] = windlight.bigWaveDirection.Y; - row["little_wave_direction_x"] = windlight.littleWaveDirection.X; - row["little_wave_direction_y"] = windlight.littleWaveDirection.Y; - row["normal_map_texture"] = windlight.normalMapTexture.ToString(); - row["horizon_r"] = windlight.horizon.X; - row["horizon_g"] = windlight.horizon.Y; - row["horizon_b"] = windlight.horizon.Z; - row["horizon_i"] = windlight.horizon.W; - row["haze_horizon"] = windlight.hazeHorizon; - row["blue_density_r"] = windlight.blueDensity.X; - row["blue_density_g"] = windlight.blueDensity.Y; - row["blue_density_b"] = windlight.blueDensity.Z; - row["blue_density_i"] = windlight.blueDensity.W; - row["haze_density"] = windlight.hazeDensity; - row["density_multiplier"] = windlight.densityMultiplier; - row["distance_multiplier"] = windlight.distanceMultiplier; - row["max_altitude"] = windlight.maxAltitude; - row["sun_moon_color_r"] = windlight.sunMoonColor.X; - row["sun_moon_color_g"] = windlight.sunMoonColor.Y; - row["sun_moon_color_b"] = windlight.sunMoonColor.Z; - row["sun_moon_color_i"] = windlight.sunMoonColor.W; - row["sun_moon_position"] = windlight.sunMoonPosition; - row["ambient_r"] = windlight.ambient.X; - row["ambient_g"] = windlight.ambient.Y; - row["ambient_b"] = windlight.ambient.Z; - row["ambient_i"] = windlight.ambient.W; - row["east_angle"] = windlight.eastAngle; - row["sun_glow_focus"] = windlight.sunGlowFocus; - row["sun_glow_size"] = windlight.sunGlowSize; - row["scene_gamma"] = windlight.sceneGamma; - row["star_brightness"] = windlight.starBrightness; - row["cloud_color_r"] = windlight.cloudColor.X; - row["cloud_color_g"] = windlight.cloudColor.Y; - row["cloud_color_b"] = windlight.cloudColor.Z; - row["cloud_color_i"] = windlight.cloudColor.W; - row["cloud_x"] = windlight.cloudXYDensity.X; - row["cloud_y"] = windlight.cloudXYDensity.Y; - row["cloud_density"] = windlight.cloudXYDensity.Z; - row["cloud_coverage"] = windlight.cloudCoverage; - row["cloud_scale"] = windlight.cloudScale; - row["cloud_detail_x"] = windlight.cloudDetailXYDensity.X; - row["cloud_detail_y"] = windlight.cloudDetailXYDensity.Y; - row["cloud_detail_density"] = windlight.cloudDetailXYDensity.Z; - row["cloud_scroll_x"] = windlight.cloudScrollX; - row["cloud_scroll_x_lock"] = windlight.cloudScrollXLock; - row["cloud_scroll_y"] = windlight.cloudScrollY; - row["cloud_scroll_y_lock"] = windlight.cloudScrollYLock; - row["draw_classic_clouds"] = windlight.drawClassicClouds; - } - /// /// /// diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs index d7f1d0ef1e..5af10c12d5 100755 --- a/OpenSim/Framework/RegionInfo.cs +++ b/OpenSim/Framework/RegionInfo.cs @@ -40,69 +40,12 @@ using OpenMetaverse.StructuredData; namespace OpenSim.Framework { - [Serializable] - public class RegionLightShareData : ICloneable - { - public bool valid = false; - public UUID regionID = UUID.Zero; - public Vector3 waterColor = new Vector3(4.0f,38.0f,64.0f); - public float waterFogDensityExponent = 4.0f; - public float underwaterFogModifier = 0.25f; - public Vector3 reflectionWaveletScale = new Vector3(2.0f,2.0f,2.0f); - public float fresnelScale = 0.40f; - public float fresnelOffset = 0.50f; - public float refractScaleAbove = 0.03f; - public float refractScaleBelow = 0.20f; - public float blurMultiplier = 0.040f; - public Vector2 bigWaveDirection = new Vector2(1.05f,-0.42f); - public Vector2 littleWaveDirection = new Vector2(1.11f,-1.16f); - public UUID normalMapTexture = new UUID("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); - public Vector4 horizon = new Vector4(0.25f, 0.25f, 0.32f, 0.32f); - public float hazeHorizon = 0.19f; - public Vector4 blueDensity = new Vector4(0.12f, 0.22f, 0.38f, 0.38f); - public float hazeDensity = 0.70f; - public float densityMultiplier = 0.18f; - public float distanceMultiplier = 0.8f; - public UInt16 maxAltitude = 1605; - public Vector4 sunMoonColor = new Vector4(0.24f, 0.26f, 0.30f, 0.30f); - public float sunMoonPosition = 0.317f; - public Vector4 ambient = new Vector4(0.35f,0.35f,0.35f,0.35f); - public float eastAngle = 0.0f; - public float sunGlowFocus = 0.10f; - public float sunGlowSize = 1.75f; - public float sceneGamma = 1.0f; - public float starBrightness = 0.0f; - public Vector4 cloudColor = new Vector4(0.41f, 0.41f, 0.41f, 0.41f); - public Vector3 cloudXYDensity = new Vector3(1.00f, 0.53f, 1.00f); - public float cloudCoverage = 0.27f; - public float cloudScale = 0.42f; - public Vector3 cloudDetailXYDensity = new Vector3(1.00f, 0.53f, 0.12f); - public float cloudScrollX = 0.20f; - public bool cloudScrollXLock = false; - public float cloudScrollY = 0.01f; - public bool cloudScrollYLock = false; - public bool drawClassicClouds = true; - - public delegate void SaveDelegate(RegionLightShareData wl); - public event SaveDelegate OnSave; - public void Save() - { - if (OnSave != null) - OnSave(this); - } - public object Clone() - { - return this.MemberwiseClone(); // call clone method - } - - } public class RegionInfo { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly string LogHeader = "[REGION INFO]"; - public bool commFailTF = false; public ConfigurationMember configMember; public string DataStore = String.Empty; @@ -134,7 +77,6 @@ namespace OpenSim.Framework private int m_maxPrimsPerUser = -1; private int m_linksetCapacity = 0; private string m_regionType = String.Empty; - private RegionLightShareData m_windlight = new RegionLightShareData(); protected uint m_httpPort; protected string m_serverURI; protected string m_regionName = String.Empty; @@ -222,7 +164,6 @@ namespace OpenSim.Framework source.Save(filename); RegionFile = filename; - return; } @@ -302,21 +243,6 @@ namespace OpenSim.Framework set { m_regionSettings = value; } } - public RegionLightShareData WindlightSettings - { - get - { - if (m_windlight == null) - { - m_windlight = new RegionLightShareData(); - } - - return m_windlight; - } - - set { m_windlight = value; } - } - public float NonphysPrimMin { get { return m_nonphysPrimMin; } diff --git a/OpenSim/Framework/ViewerEnviroment.cs b/OpenSim/Framework/ViewerEnviroment.cs new file mode 100644 index 0000000000..8c6e785538 --- /dev/null +++ b/OpenSim/Framework/ViewerEnviroment.cs @@ -0,0 +1,1233 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +namespace OpenSim.Framework +{ + // legacy lightshare + public class RegionLightShareData + { + public Vector3 waterColor = new Vector3(4.0f, 38.0f, 64.0f); + public float waterFogDensityExponent = 4.0f; + public float underwaterFogModifier = 0.25f; + public Vector3 reflectionWaveletScale = new Vector3(2.0f, 2.0f, 2.0f); + public float fresnelScale = 0.40f; + public float fresnelOffset = 0.50f; + public float refractScaleAbove = 0.03f; + public float refractScaleBelow = 0.20f; + public float blurMultiplier = 0.040f; + public Vector2 bigWaveDirection = new Vector2(1.05f, -0.42f); + public Vector2 littleWaveDirection = new Vector2(1.11f, -1.16f); + public UUID normalMapTexture = new UUID("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); + public Vector4 horizon = new Vector4(0.25f, 0.25f, 0.32f, 0.32f); + public float hazeHorizon = 0.19f; + public Vector4 blueDensity = new Vector4(0.12f, 0.22f, 0.38f, 0.38f); + public float hazeDensity = 0.70f; + public float densityMultiplier = 0.18f; + public float distanceMultiplier = 0.8f; + public UInt16 maxAltitude = 1605; + public Vector4 sunMoonColor = new Vector4(0.24f, 0.26f, 0.30f, 0.30f); + public float sunMoonPosition = 0.317f; + public Vector4 ambient = new Vector4(0.35f, 0.35f, 0.35f, 0.35f); + public float eastAngle = 0.0f; + public float sunGlowFocus = 0.10f; + public float sunGlowSize = 1.75f; + public float sceneGamma = 1.0f; + public float starBrightness = 0.0f; + public Vector4 cloudColor = new Vector4(0.41f, 0.41f, 0.41f, 0.41f); + public Vector3 cloudXYDensity = new Vector3(1.00f, 0.53f, 1.00f); + public float cloudCoverage = 0.27f; + public float cloudScale = 0.42f; + public Vector3 cloudDetailXYDensity = new Vector3(1.00f, 0.53f, 0.12f); + public float cloudScrollX = 0.20f; + public bool cloudScrollXLock = false; + public float cloudScrollY = 0.01f; + public bool cloudScrollYLock = false; + public bool drawClassicClouds = true; + } + + public class SkyData + { + public struct AbsCoefData + { + public float constant_term; + public float exp_scale; + public float exp_term; + public float linear_term; + public float width; + + public AbsCoefData(float w, float expt, float exps, float lin, float cons) + { + constant_term = cons; + exp_scale = exps; + exp_term = expt; + linear_term = lin; + width = w; + } + + public OSDMap ToOSD() + { + OSDMap map = new OSDMap(); + map["constant_term"] = constant_term; + map["exp_scale"] = exp_scale; + map["exp_term"] = exp_term; + map["linear_term"] = linear_term; + map["width"] = width; + return map; + } + + public void FromOSD(OSDMap map) + { + constant_term = map["constant_term"]; + exp_scale = map["exp_scale"]; + exp_term = map["exp_term"]; + linear_term = map["linear_term"]; + width = map["width"]; + } + } + + public struct mCoefData + { + public float anisotropy; + public float constant_term; + public float exp_scale; + public float exp_term; + public float linear_term; + public float width; + + public mCoefData(float w, float expt, float exps, float lin, float cons, float ani) + { + anisotropy = ani; + constant_term = cons; + exp_scale = exps; + exp_term = expt; + linear_term = lin; + width = w; + } + + public OSDMap ToOSD() + { + OSDMap map = new OSDMap(); + map["anisotropy"] = anisotropy; + map["constant_term"] = constant_term; + map["exp_scale"] = exp_scale; + map["exp_term"] = exp_term; + map["linear_term"] = linear_term; + map["width"] = width; + return map; + } + + public void FromOSD(OSDMap map) + { + anisotropy = map["anisotropy"]; + constant_term = map["constant_term"]; + exp_scale = map["exp_scale"]; + exp_term = map["exp_term"]; + linear_term = map["linear_term"]; + width = map["width"]; + } + } + //AbsCoefData(float w, float expt, float exps, float lin, float cons) + public AbsCoefData abscoefA = new AbsCoefData(25000f, 0, 0, 0, 0); + public AbsCoefData abscoefB = new AbsCoefData(0, 0, 0, -6.6666667e-5f, 1f); + public AbsCoefData rayleigh_config = new AbsCoefData(0, 1, -1.25e-4f, 0, 0); + + //mCoefData(float w, float expt, float exps, float lin, float cons, float ani) + public mCoefData mieconf = new mCoefData(0, 1f, -8.333333e-4f, 0, 0, 0.8f); + + UUID bloom_id = new UUID("3c59f7fe-9dc8-47f9-8aaf-a9dd1fbc3bef"); + UUID cloud_id = new UUID("1dc1368f-e8fe-f02d-a08d-9d9f11c1af6b"); + UUID halo_id = new UUID("12149143-f599-91a7-77ac-b52a3c0f59cd"); + UUID moon_id = new UUID("ec4b9f0b-d008-45c6-96a4-01dd947ac621"); + UUID rainbow_id = new UUID("11b4c57c-56b3-04ed-1f82-2004363882e4"); + UUID sun_id = UUID.Zero; + + public Vector3 ambient = new Vector3(0.25f, 0.25f, 0.25f); //? + public Vector3 blue_density = new Vector3(0.2447f, 0.4487f, 0.76f); + public Vector3 blue_horizon = new Vector3(0.4954f, 0.4954f, 0.64f); + public Vector3 cloud_color = new Vector3(0.41f, 0.41f, 0.41f); + public Vector3 cloud_pos_density1 = new Vector3(1, 0.5260f, 1); + public Vector3 cloud_pos_density2 = new Vector3(1, 0.5260f, 1); + public float cloud_scale = 0.42f; + public Vector2 cloud_scroll_rate = new Vector2(0.2f, 0.011f); + public float cloud_shadow = 0.27f; + public float density_multiplier = 0.00018f; + public float distance_multiplier = 0.8f; + public float gamma = 1; + public Vector3 glow = new Vector3(5, 0.0010f, -0.48f); + public float haze_density = 0.7f; + public float haze_horizon = 0.19f; + public float max_y = 1605; + public float star_brightness = 0f; + + public Vector4 sunlight_color = new Vector4(0.7342f, 0.7815f, 0.9f, 0.3f); + public string Name = "Default"; + + public float cloud_variance = 0; + public float dome_offset = 0.96f; + public float dome_radius = 15000f; + public float droplet_radius = 800.0f; + public float ice_level = 0; + + public float moisture_level = 0; + public float sky_bottom_radius = 6360; + public float sky_top_radius = 6420; + + public float sun_arc_radians = 0.00045f; + public Quaternion sun_rotation = new Quaternion(0, -0.3824995f, 0, 0.9239557f); + public float sun_scale = 1; + + public float moon_brightness = 0.5f; + public Quaternion moon_rotation = new Quaternion(0, 0.9239557f, 0, 0.3824995f); + public float moon_scale = 1; + public float planet_radius = 6360f; + + public void FromWLOSD(string name, OSD osd) + { + Vector4 v4tmp; + OSDMap map = osd as OSDMap; + + v4tmp = map["ambient"]; + ambient = new Vector3(v4tmp.X, v4tmp.Y, v4tmp.Z); + v4tmp = map["blue_density"]; + blue_density = new Vector3(v4tmp.X, v4tmp.Y, v4tmp.Z); + v4tmp = map["blue_horizon"]; + blue_horizon = new Vector3(v4tmp.X, v4tmp.Y, v4tmp.Z); + v4tmp = map["cloud_color"]; + cloud_color = new Vector3(v4tmp.X, v4tmp.Y, v4tmp.Z); + v4tmp = map["cloud_pos_density1"]; + cloud_pos_density1 = new Vector3(v4tmp.X, v4tmp.Y, v4tmp.Z); + v4tmp = map["cloud_pos_density2"]; + cloud_pos_density2 = new Vector3(v4tmp.X, v4tmp.Y, v4tmp.Z); + v4tmp = map["cloud_scale"]; + cloud_scale = v4tmp.X; + cloud_scroll_rate = map["cloud_scroll_rate"]; + cloud_scroll_rate.X -= 10f; + cloud_scroll_rate.Y -= 10f; + v4tmp = map["cloud_shadow"]; + cloud_shadow = v4tmp.X; + v4tmp = map["density_multiplier"]; + density_multiplier = v4tmp.X; + v4tmp = map["distance_multiplier"]; + distance_multiplier = v4tmp.X; + + Vector2 v2tmp = map["enable_cloud_scroll"]; + if (v2tmp.X == 0) + cloud_scroll_rate.X = 0; + if (v2tmp.Y == 0) + cloud_scroll_rate.Y = 0; + v4tmp = map["gamma"]; + gamma = v4tmp.X; + v4tmp = map["glow"]; + glow = new Vector3(v4tmp.X, v4tmp.Y, v4tmp.Z); + v4tmp = map["haze_density"]; + haze_density = v4tmp.X; + v4tmp = map["haze_horizon"]; + haze_horizon = v4tmp.X; + //lightnorm = map["lightnorm"]; + v4tmp = map["max_y"]; + max_y = v4tmp.X; + star_brightness = map["star_brightness"] * 250.0f; + + sunlight_color = map["sunlight_color"]; + + ViewerEnviroment.convertFromAngles(this, map["sun_angle"], map["east_angle"]); + Name = name; + } + + public OSD ToWLOSD() + { + OSDMap map = new OSDMap(); + + float sun_angle; + float east_angle; + Vector4 lightnorm; + ViewerEnviroment.convertToAngles(this, out sun_angle, out east_angle, out lightnorm); + + map["ambient"] = new Vector4(ambient.X, ambient.Y, ambient.Z, 1); + map["blue_density"] = new Vector4(blue_density.X, blue_density.Y, blue_density.Z, 1); + map["blue_horizon"] = new Vector4(blue_horizon.X, blue_horizon.Y, blue_horizon.Z, 1); + map["cloud_color"] = new Vector4(cloud_color.X, cloud_color.Y, cloud_color.Z, 1);; + map["cloud_pos_density1"] = new Vector4(cloud_pos_density1.X, cloud_pos_density1.Y, cloud_pos_density1.Z, 1); + map["cloud_pos_density2"] = new Vector4(cloud_pos_density2.X, cloud_pos_density2.Y, cloud_pos_density2.Z, 1); + map["cloud_scale"] = new Vector4(cloud_scale, 0, 0, 1); + map["cloud_scroll_rate"] = new Vector2(cloud_scroll_rate.X + 10f, cloud_scroll_rate.Y + 10f); + map["cloud_shadow"] = new Vector4(cloud_shadow, 0, 0, 1); + map["density_multiplier"] = new Vector4(density_multiplier, 0, 0, 1); + map["distance_multiplier"] = new Vector4(distance_multiplier, 0, 0, 1); + map["east_angle"] = east_angle; + map["enable_cloud_scroll"] = new OSDArray { cloud_scroll_rate.X != 0, cloud_scroll_rate.Y != 0 }; + map["gamma"] = new Vector4(gamma, 0, 0, 1); + map["glow"] = new Vector4(glow.X, glow.Y, glow.Z, 1); + map["haze_density"] = new Vector4(haze_density, 0, 0, 1); + map["haze_horizon"] = new Vector4(haze_horizon, 0, 0, 1); + map["lightnorm"] = lightnorm; + map["max_y"] = new Vector4(max_y, 0, 0, 1); + map["name"] = Name; + map["star_brightness"] = star_brightness / 250.0f; + map["sun_angle"] = sun_angle; + map["sunlight_color"] = sunlight_color; + + return map; + } + + public OSD ToOSD() + { + OSDMap map = new OSDMap(64); + + OSDArray abscfg = new OSDArray(2); + abscfg.Add(abscoefA.ToOSD()); + abscfg.Add(abscoefB.ToOSD()); + map["absorption_config"] = abscfg; + + map["bloom_id"] = bloom_id; + map["cloud_color"] = cloud_color; + map["cloud_id"] = cloud_id; + map["cloud_pos_density1"] = cloud_pos_density1; + map["cloud_pos_density2"] = cloud_pos_density2; + map["cloud_scale"] = cloud_scale; + map["cloud_scroll_rate"] = cloud_scroll_rate; + map["cloud_shadow"] = cloud_shadow; + map["cloud_variance"] = cloud_variance; + map["dome_offset"] = dome_offset; + map["dome_radius"] = dome_radius; + map["droplet_radius"] = droplet_radius; + map["gamma"] = gamma; + map["glow"] = glow; + map["halo_id"] = halo_id; + map["ice_level"] = ice_level; + + OSDMap lhaze = new OSDMap(); + lhaze["ambient"] = ambient; + lhaze["blue_density"] = blue_density; + lhaze["blue_horizon"] = blue_horizon; + lhaze["density_multiplier"] = density_multiplier; + lhaze["distance_multiplier"] = distance_multiplier; + lhaze["haze_density"] = haze_density; + lhaze["haze_horizon"] = haze_horizon; + map["legacy_haze"] = lhaze; + + map["max_y"] = max_y; + + OSDArray miecfg = new OSDArray(); + miecfg.Add(mieconf.ToOSD()); + map["mie_config"] = miecfg; + + map["moisture_level"] = moisture_level; + map["moon_brightness"] = moon_brightness; + map["moon_id"] = moon_id; + map["moon_rotation"] = moon_rotation; + map["moon_scale"] = moon_scale; + map["planet_radius"] = planet_radius; + map["rainbow_id"] = rainbow_id; + + OSDArray rayl = new OSDArray(); + rayl.Add(rayleigh_config.ToOSD()); + map["rayleigh_config"] = rayl; + + map["sky_bottom_radius"] = sky_bottom_radius; + map["sky_top_radius"] = sky_top_radius; + map["star_brightness"] = star_brightness; + + map["sun_arc_radians"] = sun_arc_radians; + map["sun_id"] = sun_id; + map["sun_rotation"] = sun_rotation; + map["sun_scale"] = sun_scale; + map["sunlight_color"] = sunlight_color; + + map["type"] = "sky"; + return map; + } + + public void FromOSD(string name, OSDMap map) + { + OSDArray tmpArray; + OSD otmp; + if (map.TryGetValue("absorption_config",out otmp) && otmp is OSDArray) + { + tmpArray = otmp as OSDArray; + if (tmpArray.Count > 0) + { + abscoefA.FromOSD(tmpArray[0] as OSDMap); + if (tmpArray.Count > 1) + abscoefA.FromOSD(tmpArray[1] as OSDMap); + } + } + if (map.TryGetValue("bloom_id", out otmp)) + bloom_id = otmp; + if (map.TryGetValue("cloud_color", out otmp)) + cloud_color = otmp; + if (map.TryGetValue("cloud_id", out otmp)) + cloud_id = otmp; + if (map.TryGetValue("cloud_pos_density1", out otmp)) + cloud_pos_density1 = otmp; + if (map.TryGetValue("cloud_pos_density2", out otmp)) + cloud_pos_density2 = otmp; + if (map.TryGetValue("cloud_scale", out otmp)) + cloud_scale = otmp; + if (map.TryGetValue("cloud_scroll_rate", out otmp)) + cloud_scroll_rate = otmp; + if (map.TryGetValue("cloud_shadow", out otmp)) + cloud_shadow = otmp; + if (map.TryGetValue("cloud_variance", out otmp)) + cloud_variance = otmp; + if (map.TryGetValue("dome_offset", out otmp)) + dome_offset = otmp; + if (map.TryGetValue("dome_radius", out otmp)) + dome_radius = otmp; + if (map.TryGetValue("droplet_radius", out otmp)) + droplet_radius = otmp; + if (map.TryGetValue("gamma", out otmp)) + gamma = otmp; + if (map.TryGetValue("glow", out otmp)) + glow = otmp; + if (map.TryGetValue("halo_id", out otmp)) + halo_id = otmp; + if (map.TryGetValue("ice_level", out otmp)) + halo_id = otmp; + + if (map.TryGetValue("legacy_haze", out OSD tmp) && tmp is OSDMap) + { + OSDMap lHaze = tmp as OSDMap; + if (lHaze.TryGetValue("ambient", out otmp)) + ambient = otmp; + if (lHaze.TryGetValue("blue_density", out otmp)) + blue_density = otmp; + if (lHaze.TryGetValue("blue_horizon", out otmp)) + blue_horizon = otmp; + if (lHaze.TryGetValue("density_multiplier", out otmp)) + density_multiplier = otmp; + if (lHaze.TryGetValue("distance_multiplier", out otmp)) + distance_multiplier = otmp; + if (lHaze.TryGetValue("haze_density", out otmp)) + haze_density = otmp; + if (lHaze.TryGetValue("haze_horizon", out otmp)) + haze_horizon = otmp; + } + + if (map.TryGetValue("max_y", out otmp)) + max_y = otmp; + + if (map.TryGetValue("mie_config", out otmp) && otmp is OSDArray) + { + tmpArray = otmp as OSDArray; + if (tmpArray.Count > 0) + mieconf.FromOSD(tmpArray[0] as OSDMap); + } + + if (map.TryGetValue("moisture_level", out otmp)) + moisture_level = otmp; + if (map.TryGetValue("moon_brightness", out otmp)) + moon_brightness = otmp; + if (map.TryGetValue("moon_id", out otmp)) + moon_id = otmp; + if (map.TryGetValue("moon_rotation", out otmp)) + moon_rotation = otmp; + if (map.TryGetValue("moon_scale", out otmp)) + moon_scale = otmp; + if (map.TryGetValue("planet_radius", out otmp)) + planet_radius = otmp; + if (map.TryGetValue("rainbow_id", out otmp)) + rainbow_id = otmp; + + if (map.TryGetValue("rayleigh_config", out otmp) && otmp is OSDArray) + { + tmpArray = otmp as OSDArray; + if (tmpArray.Count > 0) + rayleigh_config.FromOSD(tmpArray[0] as OSDMap); + } + + if (map.TryGetValue("sky_bottom_radius", out otmp)) + sky_bottom_radius = otmp; + if (map.TryGetValue("sky_top_radius", out otmp)) + sky_top_radius = otmp; + if (map.TryGetValue("star_brightness", out otmp)) + star_brightness = otmp; + + if (map.TryGetValue("sun_arc_radians", out otmp)) + sun_arc_radians = otmp; + if (map.TryGetValue("sun_id", out otmp)) + sun_id = otmp; + if (map.TryGetValue("sun_rotation", out otmp)) + sun_rotation = otmp; + if (map.TryGetValue("sun_scale", out otmp)) + sun_scale = otmp; + if (map.TryGetValue("sunlight_color", out otmp)) + sunlight_color = otmp; + Name = name; + } + } + + public class WaterData + { + public UUID normalMap = new UUID("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); + public UUID transpTexture = new UUID("2bfd3884-7e27-69b9-ba3a-3e673f680004"); + + public float blurMultiplier = 0.04f; + public float fresnelOffset = 0.5f; + public float fresnelScale = 0.4f; + public Vector3 normScale = new Vector3(2f, 2f, 2f); + public float scaleAbove = 0.03f; + public float scaleBelow = 0.2f; + public float underWaterFogMod = 0.25f; + public Vector3 waterFogColor = new Vector3(0.0156f, 0.149f, 0.2509f); + public float waterFogDensity = 2; + public Vector2 wave1Dir = new Vector2(1.05f, -0.42f); + public Vector2 wave2Dir = new Vector2(1.11f, -1.16f); + public string Name; + + public void FromWLOSD(string name, OSD osd) + { + Vector4 v4tmp; + OSDMap map = osd as OSDMap; + blurMultiplier = map["blurMultiplier"]; + fresnelOffset = map["fresnelOffset"]; + fresnelScale = map["fresnelScale"]; + normScale = map["normScale"]; + normalMap = map["normalMap"]; + scaleAbove = map["scaleAbove"]; + scaleBelow = map["scaleBelow"]; + underWaterFogMod = map["underWaterFogMod"]; + v4tmp = map["waterFogColor"]; + waterFogColor = new Vector3(v4tmp.X, v4tmp.Y, v4tmp.Z); + waterFogDensity = map["waterFogDensity"]; + wave1Dir = map["wave1Dir"]; + wave2Dir = map["wave2Dir"]; + Name = name; + } + + public OSDMap ToWLOSD() + { + OSDMap map = new OSDMap(); + + map["blurMultiplier"] = blurMultiplier; + map["fresnelOffset"] = fresnelOffset; + map["fresnelScale"] = fresnelScale; + map["normScale"] = normScale; + map["normalMap"] = normalMap; + map["scaleAbove"] = scaleAbove; + map["scaleBelow"] = scaleBelow; + map["underWaterFogMod"] = underWaterFogMod; + map["waterFogColor"] = new Vector4(waterFogColor.X, waterFogColor.Y, waterFogColor.Z, 1); + map["waterFogDensity"] = waterFogDensity; + //map["waterFogDensity"] = (float)Math.Pow(2.0f, waterFogDensity); + map["wave1Dir"] = wave1Dir; + map["wave2Dir"] = wave2Dir; + + return map; + } + + public void FromOSD(string name, OSDMap map) + { + OSD otmp; + if (map.TryGetValue("blur_multiplier", out otmp)) + blurMultiplier = otmp; + if (map.TryGetValue("fresnel_offset", out otmp)) + fresnelOffset = otmp; + if (map.TryGetValue("fresnel_scale", out otmp)) + fresnelScale = otmp; + if (map.TryGetValue("normal_scale", out otmp)) + normScale = otmp; + if (map.TryGetValue("normal_map", out otmp)) + normalMap = otmp; + if (map.TryGetValue("scale_above", out otmp)) + scaleAbove = otmp; + if (map.TryGetValue("scale_below", out otmp)) + scaleBelow = otmp; + if (map.TryGetValue("underwater_fog_mod", out otmp)) + underWaterFogMod = otmp; + if (map.TryGetValue("water_fog_color", out otmp)) + waterFogColor = otmp; + if (map.TryGetValue("water_fog_density", out otmp)) + waterFogDensity = otmp; + if (map.TryGetValue("wave1_direction", out otmp)) + wave1Dir = otmp; + if (map.TryGetValue("wave2_direction", out otmp)) + wave2Dir = otmp; + if (map.TryGetValue("transparent_texture", out otmp)) + transpTexture = otmp; + + Name = name; + } + + public OSDMap ToOSD() + { + OSDMap map = new OSDMap(); + + map["blur_multiplier"] = blurMultiplier; + map["fresnel_offset"] = fresnelOffset; + map["fresnel_scale"] = fresnelScale; + map["normal_scale"] = normScale; + map["normal_map"] = normalMap; + map["scale_above"] = scaleAbove; + map["scale_below"] = scaleBelow; + map["underwater_fog_mod"] = underWaterFogMod; + map["water_fog_color"] = waterFogColor; + map["water_fog_density"] = waterFogDensity; + map["wave1_direction"] = wave1Dir; + map["wave2_direction"] = wave2Dir; + map["transparent_texture"] = transpTexture; + map["type"] ="water"; + + return map; + } + } + + public class DayCycle + { + public struct TrackEntry + { + public float time; + public string frameName; + + public TrackEntry(float t, string f) + { + time = t; + frameName = f; + } + } + + public bool IsStaticDayCycle = false; + public List skyTrack0 = new List(); + public List skyTrack1 = new List(); + public List skyTrack2 = new List(); + public List skyTrack3 = new List(); + public List waterTrack = new List(); + + public Dictionary skyframes = new Dictionary(); + public Dictionary waterframes = new Dictionary(); + + public string Name; + + public void FromWLOSD(OSDArray array) + { + TrackEntry track; + + OSDArray skytracksArray = null; + if (array.Count > 1) + skytracksArray = array[1] as OSDArray; + if(skytracksArray != null) + { + foreach (OSD setting in skytracksArray) + { + OSDArray innerSetting = setting as OSDArray; + if(innerSetting != null) + { + track = new TrackEntry((float)innerSetting[0].AsReal(), innerSetting[1].AsString()); + skyTrack0.Add(track); + } + } + } + + OSDMap skyFramesArray = null; + if (array.Count > 2) + skyFramesArray = array[2] as OSDMap; + if(skyFramesArray != null) + { + foreach (KeyValuePair kvp in skyFramesArray) + { + SkyData sky = new SkyData(); + sky.FromWLOSD(kvp.Key, kvp.Value); + skyframes[kvp.Key] = sky; + } + } + + WaterData water = new WaterData(); + OSDMap watermap = null; + if(array.Count > 3) + watermap = array[3] as OSDMap; + if(watermap != null) + water.FromWLOSD("WLWater", watermap); + + waterframes["WLWater"] = water; + track = new TrackEntry(-1f, "WLWater"); + waterTrack.Add(track); + + if (skyTrack0.Count == 1 && skyTrack0[0].time == -1f) + IsStaticDayCycle = true; + } + + public void ToWLOSD(ref OSDArray array) + { + OSDArray track = new OSDArray(); + foreach (TrackEntry te in skyTrack0) + { + track.Add(new OSDArray { te.time, te.frameName }); + } + + array[1] = track; + + OSDMap frames = new OSDMap(); + foreach (KeyValuePair kvp in skyframes) + { + frames[kvp.Key] = kvp.Value.ToWLOSD(); + } + array[2] = frames; + + if(waterTrack.Count > 0) + { + TrackEntry te = waterTrack[0]; + if(waterframes.TryGetValue(te.frameName, out WaterData water)) + { + array[3] = water.ToWLOSD(); + } + } + else + array[3] = new OSDMap(); + } + + public void FromOSD(OSDMap map) + { + OSD otmp; + if(map.TryGetValue("frames", out otmp) && otmp is OSDMap) + { + OSDMap mframes = otmp as OSDMap; + foreach(KeyValuePair kvp in mframes) + { + OSDMap v = kvp.Value as OSDMap; + if(v.TryGetValue("type", out otmp)) + { + string type = otmp; + if (type.Equals("water")) + { + WaterData water = new WaterData(); + water.FromOSD(kvp.Key, v); + waterframes[kvp.Key] = water; + } + else if (type.Equals("sky")) + { + SkyData sky = new SkyData(); + sky.FromOSD(kvp.Key, v); + skyframes[kvp.Key] = sky; + } + } + } + } + + if (map.TryGetValue("name", out otmp)) + Name = otmp; + else + Name ="DayCycle"; + + OSDArray track; + if (map.TryGetValue("tracks", out otmp) && otmp is OSDArray) + { + OSDArray tracks = otmp as OSDArray; + if(tracks.Count > 0) + { + track = tracks[0] as OSDArray; + for(int i = 0; i < track.Count; ++i) + { + OSDMap d = track[i] as OSDMap; + if (d.TryGetValue("key_keyframe", out OSD dtime)) + { + if (d.TryGetValue("key_name", out OSD dname)) + { + TrackEntry t = new TrackEntry(); + t.time = dtime; + t.frameName = dname; + waterTrack.Add(t); + } + } + } + } + if (tracks.Count > 1) + { + track = tracks[1] as OSDArray; + for (int i = 0; i < track.Count; ++i) + { + OSDMap d = track[i] as OSDMap; + if (d.TryGetValue("key_keyframe", out OSD dtime)) + { + if (d.TryGetValue("key_name", out OSD dname)) + { + TrackEntry t = new TrackEntry(); + t.time = dtime; + t.frameName = dname; + skyTrack0.Add(t); + } + } + } + } + if (tracks.Count > 2) + { + track = tracks[2] as OSDArray; + for (int i = 0; i < track.Count; ++i) + { + OSDMap d = track[i] as OSDMap; + if (d.TryGetValue("key_keyframe", out OSD dtime)) + { + if (d.TryGetValue("key_name", out OSD dname)) + { + TrackEntry t = new TrackEntry(); + t.time = dtime; + t.frameName = dname; + skyTrack1.Add(t); + } + } + } + } + if (tracks.Count > 3) + { + track = tracks[3] as OSDArray; + for (int i = 0; i < track.Count; ++i) + { + OSDMap d = track[i] as OSDMap; + if (d.TryGetValue("key_keyframe", out OSD dtime)) + { + if (d.TryGetValue("key_name", out OSD dname)) + { + TrackEntry t = new TrackEntry(); + t.time = dtime; + t.frameName = dname; + skyTrack2.Add(t); + } + } + } + } + if (tracks.Count > 4) + { + track = tracks[4] as OSDArray; + for (int i = 0; i < track.Count; ++i) + { + OSDMap d = track[i] as OSDMap; + if (d.TryGetValue("key_keyframe", out OSD dtime)) + { + if (d.TryGetValue("key_name", out OSD dname)) + { + TrackEntry t = new TrackEntry(); + t.time = dtime; + t.frameName = dname; + skyTrack3.Add(t); + } + } + } + } + } + } + + public OSDMap ToOSD() + { + OSDMap cycle = new OSDMap(); + + OSDMap frames = new OSDMap(); + foreach (KeyValuePair kvp in waterframes) + { + frames[kvp.Key] = kvp.Value.ToOSD(); + } + foreach (KeyValuePair kvp in skyframes) + { + frames[kvp.Key] = kvp.Value.ToOSD(); + } + cycle["frames"] = frames; + + cycle["name"] = Name; + + OSDArray tracks = new OSDArray(); + + OSDArray track = new OSDArray(); + OSDMap tmp; + foreach (TrackEntry te in waterTrack) + { + tmp = new OSDMap(); + if (te.time < 0) + tmp["key_keyframe"] = 0f; + else + tmp["key_keyframe"] = te.time; + tmp["key_name"] = te.frameName; + track.Add(tmp); + } + tracks.Add(track); + + track = new OSDArray(); + foreach (TrackEntry te in skyTrack0) + { + tmp = new OSDMap(); + if (te.time < 0) + tmp["key_keyframe"] = 0f; + else + tmp["key_keyframe"] = te.time; + tmp["key_name"] = te.frameName; + track.Add(tmp); + } + tracks.Add(track); + + track = new OSDArray(); + foreach (TrackEntry te in skyTrack1) + { + tmp = new OSDMap(); + if (te.time < 0) + tmp["key_keyframe"] = 0f; + else + tmp["key_keyframe"] = te.time; + tmp["key_name"] = te.frameName; + track.Add(tmp); + } + tracks.Add(track); + + track = new OSDArray(); + foreach (TrackEntry te in skyTrack2) + { + tmp = new OSDMap(); + if (te.time < 0) + tmp["key_keyframe"] = 0f; + else + tmp["key_keyframe"] = te.time; + tmp["key_name"] = te.frameName; + track.Add(tmp); + } + tracks.Add(track); + + track = new OSDArray(); + foreach (TrackEntry te in skyTrack3) + { + tmp = new OSDMap(); + if (te.time < 0) + tmp["key_keyframe"] = 0f; + else + tmp["key_keyframe"] = te.time; + tmp["key_name"] = te.frameName; + track.Add(tmp); + } + tracks.Add(track); + + cycle["tracks"] = tracks; + cycle["type"] = "daycycle"; + + return cycle; + } + } + + public class ViewerEnviroment + { + DayCycle Cycle = new DayCycle(); + public int DayLength = 14400; + public int DayOffset = 57600; + public int Flags = 0; + + float[] Altitudes = new float[3] {1000f, 2000f, 3000f }; + + //DayHash; + public bool IsLegacy = false; + public string DayCycleName; + + public int version = 0; + + public void FromWLOSD(OSD osd) + { + OSDArray array = osd as OSDArray; + if(osd != null) + { + Cycle = new DayCycle(); + Cycle.FromWLOSD(array); + IsLegacy = true; + Altitudes[0] = 3980f; + Altitudes[1] = 3990f; + Altitudes[2] = 4000f; + } + } + + public OSD ToWLOSD(UUID message, UUID region) + { + OSDArray array = new OSDArray(4) { null, null, null, null }; + array[0] = new OSDMap { {"messageID", message }, { "regionID", region } }; + Cycle.ToWLOSD(ref array); + return array; + } + + private static Quaternion AzAlToRot(float az, float al) + { + if (al == 0) + { + az *= 0.5f; + return new Quaternion(0, 0, (float)Math.Sin(az), (float)Math.Cos(az)); + } + + float sT = (float)Math.Sin(az); + float cT = (float)Math.Cos(az); + float sP = (float)Math.Sin(al); + float cP = (float)Math.Cos(al); + + float angle = (float)Math.Acos(cT * cP); + Vector3 axis = new Vector3( 0, -sP, sT * cP); + axis.Normalize(); + + return Quaternion.CreateFromAxisAngle(axis, angle); + } + + public static void convertFromAngles(SkyData sky, float sun_angle, float east_angle) + { + float az = -east_angle; + float al = sun_angle; + + sky.sun_rotation = AzAlToRot(az, al); + sky.moon_rotation = AzAlToRot(az + (float)Math.PI, -al); + } + + public static Vector3 Xrot(Quaternion rot) + { + Vector3 vec; + rot.Normalize(); // just in case + vec.X = 2 * (rot.X * rot.X + rot.W * rot.W) - 1; + vec.Y = 2 * (rot.X * rot.Y + rot.Z * rot.W); + vec.Z = 2 * (rot.X * rot.Z - rot.Y * rot.W); + return vec; + } + + public static void convertToAngles(SkyData sky, out float sun_angle, out float east_angle, out Vector4 lightnorm) + { + Vector3 v = Xrot(sky.sun_rotation); + lightnorm = new Vector4(v.X, v.Y, v.Z,1); + sun_angle = (float)Math.Asin(v.Z); + east_angle = -(float)Math.Atan2(v.Y, v.X); + + if (Math.Abs(sun_angle) < 1e-6) + sun_angle = 0; + if (Math.Abs(east_angle) < 1e-6) + east_angle = 0; + else if (east_angle < 0) + east_angle = 2f * (float)Math.PI + east_angle; + } + + public void FromLightShare(RegionLightShareData ls) + { + WaterData water = new WaterData(); + + water.waterFogColor = ls.waterColor / 256f; + water.waterFogDensity = (float)Math.Pow(2.0f, ls.waterFogDensityExponent); + //water.waterFogDensity = ls.waterFogDensityExponent; + water.underWaterFogMod = ls.underwaterFogModifier; + water.normScale = ls.reflectionWaveletScale; + water.fresnelScale = ls.fresnelScale; + water.fresnelOffset = ls.fresnelOffset; + water.scaleAbove = ls.refractScaleAbove; + water.scaleBelow = ls.refractScaleBelow; + water.blurMultiplier = ls.blurMultiplier; + water.wave1Dir = ls.littleWaveDirection; + water.wave2Dir = ls.bigWaveDirection; + water.normalMap = ls.normalMapTexture; + water.Name = "LightshareWater"; + + SkyData sky = new SkyData(); + convertFromAngles(sky, 2.0f * (float)Math.PI * ls.sunMoonPosition, 2.0f * (float)Math.PI * ls.eastAngle); + sky.sunlight_color = ls.sunMoonColor * 3.0f; + sky.ambient = new Vector3(ls.ambient.X * 3.0f, ls.ambient.Y * 3.0f, ls.ambient.Z * 3.0f); + sky.blue_horizon = new Vector3(ls.horizon.X * 2.0f, ls.horizon.Y * 2.0f, ls.horizon.Z * 2.0f); + sky.blue_density = new Vector3(ls.blueDensity.X * 2.0f, ls.blueDensity.Y * 2.0f, ls.blueDensity.Z * 2.0f);; + sky.haze_horizon = ls.hazeHorizon; + sky.haze_density = ls.hazeDensity; + sky.cloud_shadow = ls.cloudCoverage; + sky.density_multiplier = ls.densityMultiplier / 1000.0f; + sky.distance_multiplier = ls.distanceMultiplier; + sky.max_y = ls.maxAltitude; + sky.cloud_color = new Vector3(ls.cloudColor.X, ls.cloudColor.Y, ls.cloudColor.Z); + sky.cloud_pos_density1 = ls.cloudXYDensity; + sky.cloud_pos_density2 = ls.cloudDetailXYDensity; + sky.cloud_scale = ls.cloudScale; + sky.gamma=ls.sceneGamma; + sky.glow = new Vector3((2f - ls.sunGlowSize) * 20f, 0f, -ls.sunGlowFocus * 5f); + sky.cloud_scroll_rate = new Vector2(ls.cloudScrollX, ls.cloudScrollY); + if (ls.cloudScrollXLock) + sky.cloud_scroll_rate.X = 0; + if (ls.cloudScrollYLock) + sky.cloud_scroll_rate.Y = 0; + sky.star_brightness = ls.starBrightness * 250f; + sky.Name = "LightshareSky"; + + Cycle = new DayCycle(); + Cycle.Name = "Lightshare"; + Cycle.waterframes.Add(water.Name, water); + DayCycle.TrackEntry track = new DayCycle.TrackEntry(-1, water.Name); + Cycle.waterTrack.Add(track); + + Cycle.skyframes.Add(sky.Name, sky); + track = new DayCycle.TrackEntry(-1, sky.Name); + Cycle.skyTrack0.Add(track); + + Altitudes[0] = 3980f; + Altitudes[1] = 3990f; + Altitudes[2] = 4000f; + } + + public RegionLightShareData ToLightShare() + { + RegionLightShareData ls = new RegionLightShareData(); + + DayCycle.TrackEntry te; + if (Cycle.waterTrack.Count > 0) + { + te = Cycle.waterTrack[0]; + if (Cycle.waterframes.TryGetValue(te.frameName, out WaterData water)) + { + ls.waterColor = water.waterFogColor * 256f; + ls.waterFogDensityExponent = (float)Math.Sqrt(water.waterFogDensity); + //ls.waterFogDensityExponent = water.waterFogDensity; + ls.underwaterFogModifier = water.underWaterFogMod; + ls.reflectionWaveletScale = water.normScale; + ls.fresnelScale = water.fresnelScale; + ls.fresnelOffset = water.fresnelOffset; + ls.refractScaleAbove = water.scaleAbove; + ls.refractScaleBelow = water.scaleBelow; + ls.blurMultiplier = water.blurMultiplier; + ls.littleWaveDirection = water.wave1Dir; + ls.bigWaveDirection = water.wave2Dir; + ls.normalMapTexture = water.normalMap; + } + } + + if (Cycle.skyTrack0.Count > 0) + { + te = Cycle.skyTrack0[0]; + if (Cycle.skyframes.TryGetValue(te.frameName, out SkyData sky)) + { + Vector4 lightnorm; + convertToAngles(sky, out ls.sunMoonPosition, out ls.eastAngle, out lightnorm); + ls.sunMoonPosition *= 0.5f / (float)Math.PI; + ls.eastAngle *= 0.5f / (float)Math.PI; + ls.sunMoonColor = sky.sunlight_color / 3f; + ls.ambient = new Vector4(sky.ambient.X / 3.0f, sky.ambient.Y / 3.0f, sky.ambient.Z / 3.0f, 1); + ls.horizon = new Vector4(sky.blue_horizon.X / 2.0f, sky.blue_horizon.Y / 2.0f, sky.blue_horizon.Z / 2.0f, 1); + ls.blueDensity = new Vector4(sky.blue_density.X / 2.0f, sky.blue_density.Y / 2.0f, sky.blue_density.Z / 2.0f, 1); + ls.hazeHorizon = sky.haze_horizon; + ls.hazeDensity = sky.haze_density; + ls.cloudCoverage = sky.cloud_shadow; + ls.densityMultiplier = 1000f * sky.density_multiplier; + ls.distanceMultiplier = sky.distance_multiplier; + ls.maxAltitude = (ushort)sky.max_y; + ls.cloudColor = new Vector4(sky.cloud_color.X, sky.cloud_color.Y, sky.cloud_color.Z, 1); + ls.cloudXYDensity = sky.cloud_pos_density1; + ls.cloudDetailXYDensity = sky.cloud_pos_density2; + ls.cloudScale = sky.cloud_scale; + ls.sceneGamma = sky.gamma; + ls.sunGlowSize = (2f - sky.glow.X) / 20f; + ls.sunGlowFocus = -sky.glow.Z / 5f; + ls.cloudScrollX = sky.cloud_scroll_rate.X; + ls.cloudScrollY = sky.cloud_scroll_rate.Y; + ls.cloudScrollXLock = ls.cloudScrollX == 0f; + ls.cloudScrollYLock = ls.cloudScrollY == 0f; + ls.starBrightness = sky.star_brightness / 250f; + } + } + return ls; + } + + public void FromOSD(OSD osd) + { + OSDMap map = osd as OSDMap; + if (map == null) + return; + + OSD otmp; + + if (map.TryGetValue("day_cycle", out otmp) && otmp is OSDMap) + { + Cycle = new DayCycle(); + Cycle.FromOSD(otmp as OSDMap); + } + if (Cycle == null) + Cycle = new DayCycle(); + + if (map.TryGetValue("day_length", out otmp)) + DayLength = otmp; + if (map.TryGetValue("day_offset", out otmp)) + DayOffset = otmp; + if (map.TryGetValue("flags", out otmp)) + Flags = otmp; + if (map.TryGetValue("env_version", out otmp)) + version = otmp; + else + ++version; + + if (map.TryGetValue("track_altitudes", out otmp) && otmp is OSDArray) + { + OSDArray alt = otmp as OSDArray; + + for(int i = 0; i < alt.Count && i < 3; ++i) + { + Altitudes[i] = alt[i]; + } + } + + IsLegacy = false; + } + + public void CycleFromOSD(OSD osd) + { + OSDMap map = osd as OSDMap; + if (map == null) + return; + if(!map.TryGetValue("type", out OSD tmp)) + return; + string type = tmp.AsString(); + if(type != "daycycle") + return; + Cycle = new DayCycle(); + Cycle.FromOSD(map); + } + + public OSD ToOSD() + { + OSDMap env = new OSDMap(); + env["day_cycle"] = Cycle.ToOSD(); + env["day_length"] = DayLength; + env["day_offset"] = DayOffset; + env["flags"] = Flags; + env["env_version"] = version; + + OSDArray alt = new OSDArray(); + alt.Add(Altitudes[0]); + alt.Add(Altitudes[1]); + alt.Add(Altitudes[2]); + env["track_altitudes"] = alt; + return env; + } + + public static OSD DefaultToOSD(UUID regionID, int parcel) + { + OSDMap top = new OSDMap(); + OSDMap env = new OSDMap(); + env["is_default"] = true; + if (parcel >= 0) + env["parcel_id"] = parcel; + env["region_id"] = regionID; + OSDArray alt = new OSDArray(); + alt.Add(1000f); + alt.Add(2000f); + alt.Add(3000f); + env["track_altitudes"] = alt; + top["environment"] = env; + if (parcel >= 0) + top["parcel_id"] = parcel; + top["success"] = true; + return top; + } + } +} diff --git a/OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs b/OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs index 4d7da65301..9ff42daeb6 100644 --- a/OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs +++ b/OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs @@ -26,20 +26,25 @@ */ using System; +using System.Collections.Generic; +using System.Net; using System.Reflection; using System.Text; using OpenMetaverse; +using OpenMetaverse.StructuredData; using OpenSim.Framework; using OpenSim.Framework.Capabilities; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; using log4net; using Nini.Config; using Mono.Addins; using Caps = OpenSim.Framework.Capabilities.Caps; - +using OSDArray = OpenMetaverse.StructuredData.OSDArray; +using OSDMap = OpenMetaverse.StructuredData.OSDMap; namespace OpenSim.Region.CoreModules.World.LightShare { @@ -52,6 +57,14 @@ namespace OpenSim.Region.CoreModules.World.LightShare private Scene m_scene = null; private UUID regionID = UUID.Zero; private bool Enabled = false; + private IEstateModule m_estateModule; + private IEventQueue m_eventQueue; + private IAssetService m_assetService; + + private static ViewerEnviroment m_DefaultEnv = null; + private static readonly string m_defaultDayAssetID = "5646d39e-d3d7-6aff-ed71-30fc87d64a91"; + + private int m_regionEnvVersion = -1; #region INonSharedRegionModule public void Initialise(IConfigSource source) @@ -69,6 +82,7 @@ namespace OpenSim.Region.CoreModules.World.LightShare Enabled = true; + m_log.InfoFormat("[{0}]: Module is enabled.", Name); } @@ -101,12 +115,80 @@ namespace OpenSim.Region.CoreModules.World.LightShare if (!Enabled) return; + m_estateModule = scene.RequestModuleInterface(); + if (m_estateModule == null) + { + Enabled = false; + return; + } + + m_eventQueue = m_scene.RequestModuleInterface(); + if (m_eventQueue == null) + { + Enabled = false; + return; + } + + m_assetService = m_scene.AssetService; + if (m_assetService == null) + { + Enabled = false; + return; + } + + if(m_DefaultEnv == null) + { + AssetBase defEnv = m_assetService.Get(m_defaultDayAssetID); + if(defEnv != null) + { + byte[] envData = defEnv.Data; + try + { + OSD oenv = OSDParser.DeserializeLLSDXml(envData); + m_DefaultEnv = new ViewerEnviroment(); + m_DefaultEnv.CycleFromOSD(oenv); + } + catch ( Exception e) + { + m_DefaultEnv = null; + m_log.WarnFormat("[Enviroment {0}]: failed to decode default enviroment asset: {1}", m_scene.Name, e.Message); + } + } + } + + string senv = scene.SimulationDataService.LoadRegionEnvironmentSettings(scene.RegionInfo.RegionID); + if(!string.IsNullOrEmpty(senv)) + { + try + { + OSD oenv = OSDParser.DeserializeLLSDXml(senv); + ViewerEnviroment VEnv = new ViewerEnviroment(); + if(oenv is OSDArray) + VEnv.FromWLOSD(oenv); + else + VEnv.FromOSD(oenv); + scene.RegionEnviroment = VEnv; + m_regionEnvVersion = VEnv.version; + } + catch(Exception e) + { + m_log.ErrorFormat("[Enviroment {0}] failed to load initial enviroment {1}", m_scene.Name, e.Message); + scene.RegionEnviroment = null; + m_regionEnvVersion = -1; + } + } + else + { + scene.RegionEnviroment = null; + m_regionEnvVersion = -1; + } + scene.EventManager.OnRegisterCaps += OnRegisterCaps; } public void RemoveRegion(Scene scene) { - if (Enabled) + if (!Enabled) return; scene.EventManager.OnRegisterCaps -= OnRegisterCaps; @@ -120,57 +202,339 @@ namespace OpenSim.Region.CoreModules.World.LightShare if (!Enabled) return; - m_scene.SimulationDataService.RemoveRegionEnvironmentSettings(regionUUID); + StoreOnRegion(null); + WindlightRefresh(0); + } + + public void WindlightRefresh(int interpolate) + { + List ls = null; + m_scene.ForEachClient(delegate (IClientAPI client) + { + if(!client.IsActive) + return; + + uint vflags = client.GetViewerCaps(); + + if ((vflags & 0x8000) != 0) + m_estateModule.HandleRegionInfoRequest(client); + + else if ((vflags & 0x4000) != 0) + m_eventQueue.WindlightRefreshEvent(interpolate, client.AgentId); + + else + { + if(ls == null) + ls = MakeLightShareData(); + SendLightShare(client, ls); + } + }); + } + + public void FromLightShare(RegionLightShareData ls) + { + if (!Enabled) + return; + + ViewerEnviroment VEnv = new ViewerEnviroment(); + VEnv.FromLightShare(ls); + + StoreOnRegion(VEnv); + WindlightRefresh(0); + } + + public RegionLightShareData ToLightShare() + { + if (!Enabled) + return new RegionLightShareData(); + + RegionLightShareData ls = null; + try + { + ViewerEnviroment VEnv = m_scene.RegionEnviroment; + if(VEnv == null) + return new RegionLightShareData(); + ls = VEnv.ToLightShare(); + } + catch (Exception e) + { + m_log.ErrorFormat("[{0}]: Unable to convert environment to lightShare, Exception: {1} - {2}", + Name, e.Message, e.StackTrace); + } + if(ls == null) + return new RegionLightShareData(); + return ls; } #endregion #region Events private void OnRegisterCaps(UUID agentID, Caps caps) { - // m_log.DebugFormat("[{0}]: Register capability for agentID {1} in region {2}", - // Name, agentID, caps.RegionName); + // m_log.DebugFormat("[{0}]: Register capability for agentID {1} in region {2}", + // Name, agentID, caps.RegionName); - string capsPath = "/CAPS/" + UUID.Random(); + caps.RegisterSimpleHandler("EnvironmentSettings", + new SimpleStreamHandler("/" + UUID.Random(), delegate (IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + { + processEnv(httpRequest, httpResponse, agentID); + })); - // Get handler - caps.RegisterHandler( - "EnvironmentSettings", - new RestStreamHandler( - "GET", - capsPath, - (request, path, param, httpRequest, httpResponse) - => GetEnvironmentSettings(request, path, param, agentID, caps), - "EnvironmentSettings", - agentID.ToString())); - - // Set handler - caps.HttpListener.AddStreamHandler( - new RestStreamHandler( - "POST", - capsPath, - (request, path, param, httpRequest, httpResponse) - => SetEnvironmentSettings(request, path, param, agentID, caps), - "EnvironmentSettings", - agentID.ToString())); + //Extended + caps.RegisterSimpleHandler("ExtEnvironment", + new SimpleStreamHandler("/" + UUID.Random(), delegate (IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + { + processExtEnv(httpRequest, httpResponse, agentID, caps); + })); } #endregion - private string GetEnvironmentSettings(string request, string path, string param, - UUID agentID, Caps caps) + private void processEnv(IOSHttpRequest request, IOSHttpResponse response, UUID agentID) { - // m_log.DebugFormat("[{0}]: Environment GET handle for agentID {1} in region {2}", - // Name, agentID, caps.RegionName); + switch (request.HttpMethod) + { + case "POST": + SetEnvironmentSettings(request, response, agentID); + return; + case "GET": + GetEnvironmentSettings(response, agentID); + return; + default: + { + response.StatusCode = (int)HttpStatusCode.MethodNotAllowed; + return; + } + } + } + + + private void processExtEnv(IOSHttpRequest request, IOSHttpResponse response, UUID agentID, Caps caps) + { + switch(request.HttpMethod) + { + case "PUT": + case "POST": + SetExtEnvironmentSettings(request, response, agentID, caps); + return; + case "GET": + GetExtEnvironmentSettings(request, response, agentID); + return; + case "DELETE": + DeleteExtEnvironmentSettings(request, response, agentID); + return; + default: + { + response.StatusCode = (int)HttpStatusCode.MethodNotAllowed; + return; + } + } + } + + private void DeleteExtEnvironmentSettings(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID agentID) + { + int parcel = -1; + + if (httpRequest.Query.Count > 0) + { + if (httpRequest.Query.ContainsKey("parcelid")) + { + Int32.TryParse((string)httpRequest.Query["parcelid"], out parcel); + } + } + + if(parcel == -1) + StoreOnRegion(null); + + WindlightRefresh(0); + + StringBuilder sb = LLSDxmlEncode.Start(); + LLSDxmlEncode.AddMap(sb); + LLSDxmlEncode.AddElem("messageID", UUID.Zero, sb); + LLSDxmlEncode.AddElem("regionID", regionID, sb); + LLSDxmlEncode.AddElem("success", true, sb); + LLSDxmlEncode.AddEndMap(sb); + httpResponse.RawBuffer = Util.UTF8.GetBytes(LLSDxmlEncode.End(sb)); + httpResponse.StatusCode = (int)HttpStatusCode.OK; + } + + private void GetExtEnvironmentSettings(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID agentID) + { + if (httpRequest.Query.Count > 0) + { + int parcel = -1; + if (httpRequest.Query.ContainsKey("parcelid")) + { + Int32.TryParse((string)httpRequest.Query["parcelid"], out parcel); + } + OSD oenv = ViewerEnviroment.DefaultToOSD(regionID, parcel); + httpResponse.RawBuffer = Util.UTF8.GetBytes(OSDParser.SerializeLLSDXmlString(oenv)); + httpResponse.StatusCode = (int)HttpStatusCode.OK; + } + + ViewerEnviroment VEnv = m_scene.RegionEnviroment; + if (VEnv == null) + VEnv = m_DefaultEnv == null ? new ViewerEnviroment() : m_DefaultEnv; + + OSDMap map = new OpenMetaverse.StructuredData.OSDMap(); + map["environment"] = VEnv.ToOSD(); + string env = OSDParser.SerializeLLSDXmlString(map); + + // only the presence of enviroment seems to matter + if (String.IsNullOrEmpty(env)) + { + StringBuilder sb = LLSDxmlEncode.Start(); + LLSDxmlEncode.AddArray(sb); + LLSDxmlEncode.AddMap(sb); + LLSDxmlEncode.AddElem("messageID", UUID.Zero, sb); + LLSDxmlEncode.AddElem("regionID", regionID, sb); + LLSDxmlEncode.AddEndMap(sb); + LLSDxmlEncode.AddEndArray(sb); + env = LLSDxmlEncode.End(sb); + } + + httpResponse.RawBuffer = Util.UTF8NBGetbytes(env); + httpResponse.StatusCode = (int)HttpStatusCode.OK; + } + + private void SetExtEnvironmentSettings(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID agentID, Caps caps) + { + bool success = false; + string message = "Could not process request"; + int parcel = -1; + int track = -1; + + StringBuilder sb = LLSDxmlEncode.Start(); + + if (httpRequest.Query.Count > 0) + { + if (httpRequest.Query.ContainsKey("parcelid")) + { + Int32.TryParse((string)httpRequest.Query["parcelid"], out parcel); + } + if (httpRequest.Query.ContainsKey("trackno")) + { + Int32.TryParse((string)httpRequest.Query["trackno"], out track); + } + + message = "Parcel Enviroment not supported"; + goto skiped; + } + + if(parcel == -1) + { + if (!m_scene.Permissions.CanIssueEstateCommand(agentID, false)) + { + message = "Insufficient estate permissions, settings has not been saved."; + goto skiped; + } + } + + if(track == -1) + { + try + { + OSD req = OSDParser.DeserializeLLSDXml(httpRequest.InputStream); + if(req is OpenMetaverse.StructuredData.OSDMap) + { + OpenMetaverse.StructuredData.OSDMap map = req as OpenMetaverse.StructuredData.OSDMap; + if(map.TryGetValue("environment", out OSD env)) + { + ViewerEnviroment VEnv = m_scene.RegionEnviroment; + if (VEnv == null) + VEnv = new ViewerEnviroment(); + OSDMap evmap = (OSDMap)env; + if(evmap.TryGetValue("day_asset", out OSD tmp) && !evmap.ContainsKey("day_cycle")) + { + string id = tmp.AsString(); + AssetBase asset = m_assetService.Get(id); + if(asset == null || asset.Data == null || asset.Data.Length == 0) + { + httpResponse.StatusCode = (int)HttpStatusCode.NotFound; + return; + } + try + { + OSD oenv = OSDParser.DeserializeLLSDXml(asset.Data); + VEnv.CycleFromOSD(oenv); + } + catch (Exception e) + { + httpResponse.StatusCode = (int)HttpStatusCode.NotFound; + return; + } + } + VEnv.FromOSD(env); + StoreOnRegion(VEnv); + + WindlightRefresh(0); + + success = true; + m_log.InfoFormat("[{0}]: ExtEnviromet settings saved from agentID {1} in region {2}", + Name, agentID, caps.RegionName); + } + } + else if (req is OSDArray) + { + ViewerEnviroment VEnv = m_scene.RegionEnviroment; + if (VEnv == null) + VEnv = new ViewerEnviroment(); + + VEnv.FromWLOSD(req); + StoreOnRegion(VEnv); + success = true; + + WindlightRefresh(0); + + m_log.InfoFormat("[{0}]: New Environment settings has been saved from agentID {1} in region {2}", + Name, agentID, caps.RegionName); + + LLSDxmlEncode.AddMap(sb); + LLSDxmlEncode.AddElem("messageID", UUID.Zero, sb); + LLSDxmlEncode.AddElem("regionID", regionID, sb); + LLSDxmlEncode.AddElem("success", success, sb); + LLSDxmlEncode.AddEndMap(sb); + httpResponse.RawBuffer = Util.UTF8.GetBytes(LLSDxmlEncode.End(sb)); + httpResponse.StatusCode = (int)HttpStatusCode.OK; + return; + } + } + catch (Exception e) + { + m_log.ErrorFormat("[{0}]: ExtEnvironment settings not saved for region {1}, Exception: {2} - {3}", + Name, caps.RegionName, e.Message, e.StackTrace); + + success = false; + message = String.Format("ExtEnvironment Set for region {0} has failed, settings not saved.", caps.RegionName); + } + } + + skiped: + string response; + + LLSDxmlEncode.AddMap(sb); + LLSDxmlEncode.AddElem("success", success, sb); + if(!success) + LLSDxmlEncode.AddElem("message", message, sb); + LLSDxmlEncode.AddEndMap(sb); + response = LLSDxmlEncode.End(sb); + + httpResponse.RawBuffer = Util.UTF8.GetBytes(response); + httpResponse.StatusCode = (int)HttpStatusCode.OK; + } + + private void GetEnvironmentSettings(IOSHttpResponse response, UUID agentID) + { + // m_log.DebugFormat("[{0}]: Environment GET handle for agentID {1} in region {2}", + // Name, agentID, caps.RegionName); string env = String.Empty; + ViewerEnviroment VEnv = m_scene.RegionEnviroment; + if (VEnv == null) + VEnv = m_DefaultEnv; - try + if (VEnv != null) { - env = m_scene.SimulationDataService.LoadRegionEnvironmentSettings(regionID); - } - catch (Exception e) - { - m_log.ErrorFormat("[{0}]: Unable to load environment settings for region {1}, Exception: {2} - {3}", - Name, caps.RegionName, e.Message, e.StackTrace); + OSD d = VEnv.ToWLOSD(UUID.Zero, regionID); + env = OSDParser.SerializeLLSDXmlString(d); } if (String.IsNullOrEmpty(env)) @@ -185,15 +549,39 @@ namespace OpenSim.Region.CoreModules.World.LightShare env = LLSDxmlEncode.End(sb); } - return env; + response.RawBuffer = Util.UTF8.GetBytes(env); + response.StatusCode = (int)HttpStatusCode.OK; } - private string SetEnvironmentSettings(string request, string path, string param, - UUID agentID, Caps caps) + private void StoreOnRegion(ViewerEnviroment VEnv) { + try + { + if (VEnv == null) + { + m_scene.SimulationDataService.RemoveRegionEnvironmentSettings(regionID); + m_scene.RegionEnviroment = null; + m_regionEnvVersion = -1; + } + else + { + m_regionEnvVersion++; + VEnv.version = m_regionEnvVersion; + OSD env = VEnv.ToOSD(); + m_scene.SimulationDataService.StoreRegionEnvironmentSettings(regionID, OSDParser.SerializeLLSDXmlString(env)); + m_scene.RegionEnviroment = VEnv; + } + } + catch (Exception e) + { + m_log.ErrorFormat("[Enviroment {0}] failed to store enviroment {1}", m_scene.Name, e.Message); + } + } - // m_log.DebugFormat("[{0}]: Environment SET handle from agentID {1} in region {2}", - // Name, agentID, caps.RegionName); + private void SetEnvironmentSettings(IOSHttpRequest request, IOSHttpResponse response, UUID agentID) + { + // m_log.DebugFormat("[{0}]: Environment SET handle from agentID {1} in region {2}", + // Name, agentID, caps.RegionName); bool success = false; string fail_reason = ""; @@ -206,19 +594,24 @@ namespace OpenSim.Region.CoreModules.World.LightShare { try { - m_scene.SimulationDataService.StoreRegionEnvironmentSettings(regionID, request); + ViewerEnviroment VEnv = new ViewerEnviroment(); + OSD env = OSDParser.DeserializeLLSDXml(request.InputStream); + VEnv.FromWLOSD(env); + StoreOnRegion(VEnv); success = true; + WindlightRefresh(0); + m_log.InfoFormat("[{0}]: New Environment settings has been saved from agentID {1} in region {2}", - Name, agentID, caps.RegionName); + Name, agentID, m_scene.Name); } catch (Exception e) { m_log.ErrorFormat("[{0}]: Environment settings has not been saved for region {1}, Exception: {2} - {3}", - Name, caps.RegionName, e.Message, e.StackTrace); + Name, m_scene.Name, e.Message, e.StackTrace); success = false; - fail_reason = String.Format("Environment Set for region {0} has failed, settings not saved.", caps.RegionName); + fail_reason = String.Format("Environment Set for region {0} has failed, settings not saved.", m_scene.Name); } } @@ -230,7 +623,111 @@ namespace OpenSim.Region.CoreModules.World.LightShare if(!success) LLSDxmlEncode.AddElem("fail_reason", fail_reason, sb); LLSDxmlEncode.AddEndMap(sb); - return LLSDxmlEncode.End(sb); + response.RawBuffer = Util.UTF8.GetBytes(LLSDxmlEncode.End(sb)); + response.StatusCode = (int)HttpStatusCode.OK; + } + + public byte[] GetDefaultAssetData(int type) + { + OSD osddata; + switch(type) + { + case 0: + SkyData sky = new SkyData(); + sky.Name = "DefaultSky"; + osddata = sky.ToOSD(); + break; + case 1: + WaterData water = new WaterData(); + water.Name = "DefaultWater"; + osddata = water.ToOSD(); + break; + case 2: + DayCycle day = new DayCycle(); + day.Name="New Daycycle"; + DayCycle.TrackEntry te = new DayCycle.TrackEntry(); + + WaterData dwater = new WaterData(); + dwater.Name = "DefaultWater"; + day.waterframes["DefaultWater"] = dwater; + te.time = 0; + te.frameName = "DefaultWater"; + day.waterTrack.Add(te); + + SkyData dsky = new SkyData(); + dsky.Name = "DefaultSky"; + day.skyframes["DefaultSky"] = dsky; + te.time = 0; + te.frameName = "DefaultSky"; + day.skyTrack0.Add(te); + + osddata = day.ToOSD(); + break; + default: + return null; + } + string sdata = OSDParser.SerializeLLSDXmlString(osddata); + return Util.UTF8NBGetbytes(sdata); + } + + public List MakeLightShareData() + { + if(m_scene.RegionEnviroment == null) + return null; + + RegionLightShareData wl = ToLightShare(); + byte[] mBlock = new Byte[249]; + int pos = 0; + + wl.waterColor.ToBytes(mBlock, 0); pos += 12; + Utils.FloatToBytes(wl.waterFogDensityExponent).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.underwaterFogModifier).CopyTo(mBlock, pos); pos += 4; + wl.reflectionWaveletScale.ToBytes(mBlock, pos); pos += 12; + Utils.FloatToBytes(wl.fresnelScale).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.fresnelOffset).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.refractScaleAbove).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.refractScaleBelow).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.blurMultiplier).CopyTo(mBlock, pos); pos += 4; + wl.bigWaveDirection.ToBytes(mBlock, pos); pos += 8; + wl.littleWaveDirection.ToBytes(mBlock, pos); pos += 8; + wl.normalMapTexture.ToBytes(mBlock, pos); pos += 16; + wl.horizon.ToBytes(mBlock, pos); pos += 16; + Utils.FloatToBytes(wl.hazeHorizon).CopyTo(mBlock, pos); pos += 4; + wl.blueDensity.ToBytes(mBlock, pos); pos += 16; + Utils.FloatToBytes(wl.hazeDensity).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.densityMultiplier).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.distanceMultiplier).CopyTo(mBlock, pos); pos += 4; + wl.sunMoonColor.ToBytes(mBlock, pos); pos += 16; + Utils.FloatToBytes(wl.sunMoonPosition).CopyTo(mBlock, pos); pos += 4; + wl.ambient.ToBytes(mBlock, pos); pos += 16; + Utils.FloatToBytes(wl.eastAngle).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.sunGlowFocus).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.sunGlowSize).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.sceneGamma).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.starBrightness).CopyTo(mBlock, pos); pos += 4; + wl.cloudColor.ToBytes(mBlock, pos); pos += 16; + wl.cloudXYDensity.ToBytes(mBlock, pos); pos += 12; + Utils.FloatToBytes(wl.cloudCoverage).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.cloudScale).CopyTo(mBlock, pos); pos += 4; + wl.cloudDetailXYDensity.ToBytes(mBlock, pos); pos += 12; + Utils.FloatToBytes(wl.cloudScrollX).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.cloudScrollY).CopyTo(mBlock, pos); pos += 4; + Utils.UInt16ToBytes(wl.maxAltitude).CopyTo(mBlock, pos); pos += 2; + mBlock[pos] = Convert.ToByte(wl.cloudScrollXLock); pos++; + mBlock[pos] = Convert.ToByte(wl.cloudScrollYLock); pos++; + mBlock[pos] = Convert.ToByte(wl.drawClassicClouds); pos++; + + List param = new List(); + param.Add(mBlock); + return param; + } + + public void SendLightShare(IClientAPI client, List param) + { + if(param == null || param.Count == 0) + client.SendGenericMessage("WindlightReset", UUID.Random(), new List()); + else + client.SendGenericMessage("Windlight", UUID.Random(), param); } } } diff --git a/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs b/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs deleted file mode 100644 index f13d648a59..0000000000 --- a/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Reflection; -using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Region.CoreModules.Framework.InterfaceCommander; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using log4net; -using Nini.Config; -using Mono.Addins; - -namespace OpenSim.Region.CoreModules.World.LightShare -{ - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LightShareModule")] - public class LightShareModule : INonSharedRegionModule, ILightShareModule, ICommandableModule - { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private readonly Commander m_commander = new Commander("windlight"); - private Scene m_scene; - private static bool m_enableWindlight; - - #region ICommandableModule Members - - public ICommander CommandInterface - { - get { return m_commander; } - } - - #endregion - - #region INonSharedRegionModule Members - - public void Initialise(IConfigSource config) - { - try - { - m_enableWindlight = config.Configs["LightShare"].GetBoolean("enable_windlight", false); - } - catch (Exception) - { - m_log.Debug("[WINDLIGHT]: ini failure for enable_windlight - using default"); - } - - m_log.DebugFormat("[WINDLIGHT]: windlight module {0}", (m_enableWindlight ? "enabled" : "disabled")); - } - - public void AddRegion(Scene scene) - { - if (!m_enableWindlight) - return; - - m_scene = scene; - m_scene.RegisterModuleInterface(this); - m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; - - m_scene.EventManager.OnMakeRootAgent += EventManager_OnMakeRootAgent; - m_scene.EventManager.OnSaveNewWindlightProfile += EventManager_OnSaveNewWindlightProfile; - m_scene.EventManager.OnSendNewWindlightProfileTargeted += EventManager_OnSendNewWindlightProfileTargeted; - m_scene.LoadWindlightProfile(); - - InstallCommands(); - } - - public void RemoveRegion(Scene scene) - { - if (!m_enableWindlight) - return; - - m_scene.EventManager.OnPluginConsole -= EventManager_OnPluginConsole; - - m_scene.EventManager.OnMakeRootAgent -= EventManager_OnMakeRootAgent; - m_scene.EventManager.OnSaveNewWindlightProfile -= EventManager_OnSaveNewWindlightProfile; - m_scene.EventManager.OnSendNewWindlightProfileTargeted -= EventManager_OnSendNewWindlightProfileTargeted; - - m_scene = null; - } - - public void Close() - { - } - - public string Name - { - get { return "LightShareModule"; } - } - - public void RegionLoaded(Scene scene) - { - } - - public Type ReplaceableInterface - { - get { return null; } - } - - #endregion - - public static bool EnableWindlight - { - get - { - return m_enableWindlight; - } - set - { - } - } - - #region events - - private List compileWindlightSettings(RegionLightShareData wl) - { - byte[] mBlock = new Byte[249]; - int pos = 0; - - wl.waterColor.ToBytes(mBlock, 0); pos += 12; - Utils.FloatToBytes(wl.waterFogDensityExponent).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.underwaterFogModifier).CopyTo(mBlock, pos); pos += 4; - wl.reflectionWaveletScale.ToBytes(mBlock, pos); pos += 12; - Utils.FloatToBytes(wl.fresnelScale).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.fresnelOffset).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.refractScaleAbove).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.refractScaleBelow).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.blurMultiplier).CopyTo(mBlock, pos); pos += 4; - wl.bigWaveDirection.ToBytes(mBlock, pos); pos += 8; - wl.littleWaveDirection.ToBytes(mBlock, pos); pos += 8; - wl.normalMapTexture.ToBytes(mBlock, pos); pos += 16; - wl.horizon.ToBytes(mBlock, pos); pos += 16; - Utils.FloatToBytes(wl.hazeHorizon).CopyTo(mBlock, pos); pos += 4; - wl.blueDensity.ToBytes(mBlock, pos); pos += 16; - Utils.FloatToBytes(wl.hazeDensity).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.densityMultiplier).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.distanceMultiplier).CopyTo(mBlock, pos); pos += 4; - wl.sunMoonColor.ToBytes(mBlock, pos); pos += 16; - Utils.FloatToBytes(wl.sunMoonPosition).CopyTo(mBlock, pos); pos += 4; - wl.ambient.ToBytes(mBlock, pos); pos += 16; - Utils.FloatToBytes(wl.eastAngle).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.sunGlowFocus).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.sunGlowSize).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.sceneGamma).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.starBrightness).CopyTo(mBlock, pos); pos += 4; - wl.cloudColor.ToBytes(mBlock, pos); pos += 16; - wl.cloudXYDensity.ToBytes(mBlock, pos); pos += 12; - Utils.FloatToBytes(wl.cloudCoverage).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.cloudScale).CopyTo(mBlock, pos); pos += 4; - wl.cloudDetailXYDensity.ToBytes(mBlock, pos); pos += 12; - Utils.FloatToBytes(wl.cloudScrollX).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.cloudScrollY).CopyTo(mBlock, pos); pos += 4; - Utils.UInt16ToBytes(wl.maxAltitude).CopyTo(mBlock, pos); pos += 2; - mBlock[pos] = Convert.ToByte(wl.cloudScrollXLock); pos++; - mBlock[pos] = Convert.ToByte(wl.cloudScrollYLock); pos++; - mBlock[pos] = Convert.ToByte(wl.drawClassicClouds); pos++; - List param = new List(); - param.Add(mBlock); - return param; - } - - public void SendProfileToClient(IClientAPI client) - { - SendProfileToClient(client, m_scene.RegionInfo.WindlightSettings); - } - - public void SendProfileToClient(IClientAPI client, RegionLightShareData wl) - { - if (client == null) - return; - - if (m_enableWindlight) - { - if (m_scene.RegionInfo.WindlightSettings.valid) - { - List param = compileWindlightSettings(wl); - client.SendGenericMessage("Windlight", UUID.Random(), param); - } - else - { - List param = new List(); - client.SendGenericMessage("WindlightReset", UUID.Random(), param); - } - } - } - - private void EventManager_OnMakeRootAgent(ScenePresence presence) - { - if (m_enableWindlight && m_scene.RegionInfo.WindlightSettings.valid) - m_log.Debug("[WINDLIGHT]: Sending windlight scene to new client"); - SendProfileToClient(presence.ControllingClient); - } - - private void EventManager_OnSendNewWindlightProfileTargeted(RegionLightShareData wl, UUID pUUID) - { - IClientAPI client; - m_scene.TryGetClient(pUUID, out client); - SendProfileToClient(client, wl); - } - - private void EventManager_OnSaveNewWindlightProfile() - { - m_scene.ForEachRootClient(SendProfileToClient); - } - - #endregion - - #region ICommandableModule Members - - private void InstallCommands() - { - Command wlload = new Command("load", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleLoad, "Load windlight profile from the database and broadcast"); - Command wlenable = new Command("enable", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleEnable, "Enable the windlight plugin"); - Command wldisable = new Command("disable", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleDisable, "Disable the windlight plugin"); - - m_commander.RegisterCommand("load", wlload); - m_commander.RegisterCommand("enable", wlenable); - m_commander.RegisterCommand("disable", wldisable); - - m_scene.RegisterModuleCommander(m_commander); - } - - private void HandleLoad(Object[] args) - { - if (!m_enableWindlight) - { - m_log.InfoFormat("[WINDLIGHT]: Cannot load windlight profile, module disabled. Use 'windlight enable' first."); - } - else - { - m_log.InfoFormat("[WINDLIGHT]: Loading Windlight profile from database"); - m_scene.LoadWindlightProfile(); - m_log.InfoFormat("[WINDLIGHT]: Load complete"); - } - } - - private void HandleDisable(Object[] args) - { - m_log.InfoFormat("[WINDLIGHT]: Plugin now disabled"); - m_enableWindlight = false; - } - - private void HandleEnable(Object[] args) - { - m_log.InfoFormat("[WINDLIGHT]: Plugin now enabled"); - m_enableWindlight = true; - } - - /// - /// Processes commandline input. Do not call directly. - /// - /// Commandline arguments - private void EventManager_OnPluginConsole(string[] args) - { - if (args[0] == "windlight") - { - if (args.Length == 1) - { - m_commander.ProcessConsoleCommand("add", new string[0]); - return; - } - - string[] tmpArgs = new string[args.Length - 2]; - int i; - for (i = 2; i < args.Length; i++) - { - tmpArgs[i - 2] = args[i]; - } - - m_commander.ProcessConsoleCommand(args[1], tmpArgs); - } - } - #endregion - - } -} - diff --git a/OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs b/OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs index 80cf2dcc4b..9f48c88ef4 100644 --- a/OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs @@ -33,8 +33,8 @@ namespace OpenSim.Region.Framework.Interfaces public interface IEnvironmentModule { void ResetEnvironmentSettings(UUID regionUUID); - //void FromLightShare(RegionLightShareData wl); - //RegionLightShareData ToLightShare(); - //byte[] GetDefaultAssetData(string name); + void FromLightShare(RegionLightShareData wl); + RegionLightShareData ToLightShare(); + byte[] GetDefaultAssetData(int type); } } diff --git a/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs b/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs index f8a6b53d47..d6b627a94c 100644 --- a/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs +++ b/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs @@ -109,9 +109,6 @@ namespace OpenSim.Region.Framework.Interfaces void StoreRegionSettings(RegionSettings rs); RegionSettings LoadRegionSettings(UUID regionUUID); - RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID); - void StoreRegionWindlightSettings(RegionLightShareData wl); - void RemoveRegionWindlightSettings(UUID regionID); /// /// Load Environment settings from region storage diff --git a/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs b/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs index 19ba787931..624d79c2b8 100644 --- a/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs +++ b/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs @@ -121,9 +121,7 @@ namespace OpenSim.Region.Framework.Interfaces void StoreRegionSettings(RegionSettings rs); RegionSettings LoadRegionSettings(UUID regionUUID); - RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID); - void StoreRegionWindlightSettings(RegionLightShareData wl); - void RemoveRegionWindlightSettings(UUID regionID); + UUID[] GetObjectIDs(UUID regionID); /// diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 2c231b1b13..920005aad1 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -720,9 +720,6 @@ namespace OpenSim.Region.Framework.Scenes /// public event OnMakeChildAgentDelegate OnMakeChildAgent; - public delegate void OnSaveNewWindlightProfileDelegate(); - public delegate void OnSendNewWindlightProfileTargetedDelegate(RegionLightShareData wl, UUID user); - /// /// Triggered after the grunt work for adding a root agent to a /// scene has been performed (resuming attachment scripts, physics, @@ -739,9 +736,6 @@ namespace OpenSim.Region.Framework.Scenes /// public event Action OnMakeRootAgent; - public event OnSendNewWindlightProfileTargetedDelegate OnSendNewWindlightProfileTargeted; - public event OnSaveNewWindlightProfileDelegate OnSaveNewWindlightProfile; - /// /// Triggered when an object or attachment enters a scene /// @@ -2160,24 +2154,6 @@ namespace OpenSim.Region.Framework.Scenes } } - public void TriggerOnSendNewWindlightProfileTargeted(RegionLightShareData wl, UUID user) - { - OnSendNewWindlightProfileTargetedDelegate handlerSendNewWindlightProfileTargeted = OnSendNewWindlightProfileTargeted; - if (handlerSendNewWindlightProfileTargeted != null) - { - handlerSendNewWindlightProfileTargeted(wl, user); - } - } - - public void TriggerOnSaveNewWindlightProfile() - { - OnSaveNewWindlightProfileDelegate handlerSaveNewWindlightProfile = OnSaveNewWindlightProfile; - if (handlerSaveNewWindlightProfile != null) - { - handlerSaveNewWindlightProfile(); - } - } - public void TriggerOnMakeRootAgent(ScenePresence presence) { Action handlerMakeRootAgent = OnMakeRootAgent; diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 3b2afbcd9e..21a2a20123 100755 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2123,17 +2123,17 @@ namespace OpenSim.Region.Framework.Scenes SimulationDataService.StoreBakedTerrain(Bakedmap.GetTerrainData(), RegionInfo.RegionID); } - public void StoreWindlightProfile(RegionLightShareData wl) + private ViewerEnviroment m_regionEnviroment; + public ViewerEnviroment RegionEnviroment { - RegionInfo.WindlightSettings = wl; - SimulationDataService.StoreRegionWindlightSettings(wl); - m_eventManager.TriggerOnSaveNewWindlightProfile(); - } - - public void LoadWindlightProfile() - { - RegionInfo.WindlightSettings = SimulationDataService.LoadRegionWindlightSettings(RegionInfo.RegionID); - m_eventManager.TriggerOnSaveNewWindlightProfile(); + get + { + return m_regionEnviroment; + } + set + { + m_regionEnviroment = value; + } } /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs index 1979012b8b..8bdc061255 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs @@ -62,9 +62,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal bool m_LSFunctionsEnabled = false; internal IScriptModuleComms m_comms = null; internal IConfig m_osslconfig; + internal IEnvironmentModule m_enviroment = null; - public void Initialize( - IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item) + public void Initialize(IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item) { m_ScriptEngine = scriptEngine; m_host = host; @@ -79,6 +79,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_comms = m_ScriptEngine.World.RequestModuleInterface(); if (m_comms == null) m_LSFunctionsEnabled = false; + + m_enviroment = m_ScriptEngine.World.RequestModuleInterface(); } public override Object InitializeLifetimeService() @@ -88,8 +90,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (lease.CurrentState == LeaseState.Initial) { lease.InitialLeaseTime = TimeSpan.FromMinutes(0); - // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0); - // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0); + //lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0); + //lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0); } return lease; } @@ -120,13 +122,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// List of windlight parameters public LSL_List lsGetWindlightScene(LSL_List rules) { - if (!m_LSFunctionsEnabled) + if (!m_LSFunctionsEnabled || m_enviroment == null) { LSShoutError("LightShare functions are not enabled."); return new LSL_List(); } + m_host.AddScriptLPS(1); - RegionLightShareData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings; + + RegionLightShareData wl = m_enviroment.ToLightShare(); LSL_List values = new LSL_List(); int idx = 0; @@ -264,9 +268,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api private RegionLightShareData getWindlightProfileFromRules(LSL_List rules) { - RegionLightShareData wl = (RegionLightShareData)m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.Clone(); + RegionLightShareData wl = m_enviroment.ToLightShare(); -// LSL_List values = new LSL_List(); int idx = 0; while (idx < rules.Length) { @@ -716,12 +719,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// success: true or false public int lsSetWindlightScene(LSL_List rules) { - if (!m_LSFunctionsEnabled) + if (!m_LSFunctionsEnabled || m_enviroment == null) { LSShoutError("LightShare functions are not enabled."); return 0; } + m_host.AddScriptLPS(1); + if (!World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_host.OwnerID)) { ScenePresence sp = World.GetScenePresence(m_host.OwnerID); @@ -733,42 +738,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - int success = 0; - m_host.AddScriptLPS(1); - - if (LightShareModule.EnableWindlight) + try { - RegionLightShareData wl; - try - { - wl = getWindlightProfileFromRules(rules); - } - catch(InvalidCastException e) - { - LSShoutError(e.Message); - return 0; - } - wl.valid = true; - m_host.ParentGroup.Scene.StoreWindlightProfile(wl); - success = 1; + RegionLightShareData wl = getWindlightProfileFromRules(rules); + m_enviroment.FromLightShare(wl); } - else + catch(InvalidCastException e) { - LSShoutError("Windlight module is disabled"); + LSShoutError(e.Message); return 0; } - return success; + return 1; } public void lsClearWindlightScene() { - if (!m_LSFunctionsEnabled) + if (!m_LSFunctionsEnabled || m_enviroment == null) { LSShoutError("LightShare functions are not enabled."); return; } + m_host.AddScriptLPS(1); + if (!World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_host.OwnerID)) { ScenePresence sp = World.GetScenePresence(m_host.OwnerID); @@ -780,11 +773,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.valid = false; - if (m_host.ParentGroup.Scene.SimulationDataService != null) - m_host.ParentGroup.Scene.SimulationDataService.RemoveRegionWindlightSettings(m_host.ParentGroup.Scene.RegionInfo.RegionID); - - m_host.ParentGroup.Scene.EventManager.TriggerOnSaveNewWindlightProfile(); + m_enviroment.ResetEnvironmentSettings(m_host.ParentGroup.Scene.RegionInfo.RegionID); } /// @@ -794,6 +783,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// success: true or false public int lsSetWindlightSceneTargeted(LSL_List rules, LSL_Key target) { + LSShoutError("Function temporary not supported"); + return 0; + + /* disabled code until we add force a WL into a single user if (!m_LSFunctionsEnabled) { LSShoutError("LightShare functions are not enabled."); @@ -814,7 +807,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api int success = 0; m_host.AddScriptLPS(1); - if (LightShareModule.EnableWindlight) + if (m_enviroment != null) { RegionLightShareData wl; try @@ -836,6 +829,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } return success; + */ } } } diff --git a/OpenSim/Services/SimulationService/SimulationDataService.cs b/OpenSim/Services/SimulationService/SimulationDataService.cs index eef958ac4e..84e4a80da9 100644 --- a/OpenSim/Services/SimulationService/SimulationDataService.cs +++ b/OpenSim/Services/SimulationService/SimulationDataService.cs @@ -154,20 +154,6 @@ namespace OpenSim.Services.SimulationService return m_database.LoadRegionSettings(regionUUID); } - public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID) - { - return m_database.LoadRegionWindlightSettings(regionUUID); - } - - public void StoreRegionWindlightSettings(RegionLightShareData wl) - { - m_database.StoreRegionWindlightSettings(wl); - } - public void RemoveRegionWindlightSettings(UUID regionID) - { - m_database.RemoveRegionWindlightSettings(regionID); - } - public string LoadRegionEnvironmentSettings(UUID regionUUID) { return m_database.LoadRegionEnvironmentSettings(regionUUID); diff --git a/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs b/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs index 8379b0aa15..ab0e4f4454 100644 --- a/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs +++ b/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs @@ -119,20 +119,6 @@ namespace OpenSim.Data.Null return m_store.LoadRegionSettings(regionUUID); } - public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID) - { - return m_store.LoadRegionWindlightSettings(regionUUID); - } - - public void RemoveRegionWindlightSettings(UUID regionID) - { - } - - public void StoreRegionWindlightSettings(RegionLightShareData wl) - { - m_store.StoreRegionWindlightSettings(wl); - } - public string LoadRegionEnvironmentSettings(UUID regionUUID) { return m_store.LoadRegionEnvironmentSettings(regionUUID); @@ -197,22 +183,6 @@ namespace OpenSim.Data.Null m_regionSettings[rs.RegionUUID] = rs; } - public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID) - { - //This connector doesn't support the windlight module yet - //Return default LL windlight settings - return new RegionLightShareData(); - } - - public void RemoveRegionWindlightSettings(UUID regionID) - { - } - - public void StoreRegionWindlightSettings(RegionLightShareData wl) - { - //This connector doesn't support the windlight module yet - } - #region Environment Settings public string LoadRegionEnvironmentSettings(UUID regionUUID) { diff --git a/bin/assets/AssetSets.xml b/bin/assets/AssetSets.xml index 829f845e5d..dc440adecf 100644 --- a/bin/assets/AssetSets.xml +++ b/bin/assets/AssetSets.xml @@ -77,5 +77,9 @@
+ +
+ +
diff --git a/bin/assets/SettingsAssetSet/DefaultDaycycle.xml b/bin/assets/SettingsAssetSet/DefaultDaycycle.xml new file mode 100644 index 0000000000..1a3dac446d --- /dev/null +++ b/bin/assets/SettingsAssetSet/DefaultDaycycle.xml @@ -0,0 +1 @@ +frames10809890408763334407absorption_configconstant_term1exp_scale0exp_term0linear_term0width0constant_term1exp_scale0exp_term0linear_term0width0bloom_id3c59f7fe-9dc8-47f9-8aaf-a9dd1fbc3befcloud_color0.22615399956703186035156250.22615399956703186035156250.2261539995670318603515625cloud_id1dc1368f-e8fe-f02d-a08d-9d9f11c1af6bcloud_pos_density110.5260969996452331542968750.87999999523162841796875cloud_pos_density210.5260969996452331542968750.125cloud_scale0.4199999868869781494140625cloud_scroll_rate0.499400138854980468750.0109996795654296875cloud_shadow0.269999980926513671875cloud_variance0dome_offset0.959999978542327880859375dome_radius15000droplet_radius800flags0gamma1glow50.001000000047497451305389404-0.4799999892711639404296875halo_idice_level0legacy_hazeambient0.20405027270317077636718750.24246673285961151123046880.329999983310699462890625blue_density0.4499999880790710449218750.4499999880790710449218750.449999988079071044921875blue_horizon0.23999999463558197021484380.23999999463558197021484380.2399999946355819702148438density_multiplier0.0001590000028954818844795227distance_multiplier9.999999747378751635551453e-05haze_density4haze_horizon0max_y906.20001220703125mie_configanisotropy0.800000011920928955078125constant_term0exp_scale-0.0008333333535119891166687012exp_term1linear_term0width0moisture_level0moon_brightness0.5moon_idec4b9f0b-d008-45c6-96a4-01dd947ac621moon_rotation0-0.707107007503509521484375-4.028524611338415994943318e-140.70710647106170654296875moon_scale1planet_radius6360rainbow_id11b4c57c-56b3-04ed-1f82-2004363882e4rayleigh_configconstant_term0exp_scale-0.0001250000059371814131736755exp_term1linear_term0width0sky_bottom_radius6360sky_top_radius6420star_brightness500sun_arc_radians0.0004499999922700226306915283sun_idsun_rotation00.70710653066635131835937500.70710694789886474609375sun_scale1sunlight_color0.348766922950744628906250.35574248433113098144531250.659999966621398925781250.2199999988079071044921875typesky12059426462794438368blur_multiplier0.04000000283122062683105469flags0fresnel_offset0.5fresnel_scale0.39999997615814208984375normal_map822ded49-9a6c-f61c-cb89-6df54f42cdf4normal_scale222scale_above0.02999999932944774627685547scale_below0.2000000029802322387695313typewaterunderwater_fog_mod0.25water_fog_color0.015686275437474250793457030.14901961386203765869140630.2509804069995880126953125water_fog_density16wave1_direction1.049999713897705078125-0.4200000762939453125wave2_direction1.10999965667724609375-1.160000085830688476562512704758109389341107absorption_configconstant_term1exp_scale0exp_term0linear_term0width0constant_term1exp_scale0exp_term0linear_term0width0bloom_id3c59f7fe-9dc8-47f9-8aaf-a9dd1fbc3befcloud_color0.22615399956703186035156250.22615399956703186035156250.2261539995670318603515625cloud_id1dc1368f-e8fe-f02d-a08d-9d9f11c1af6bcloud_pos_density110.5260969996452331542968750.87999999523162841796875cloud_pos_density210.5260969996452331542968750.125cloud_scale0.4199999868869781494140625cloud_scroll_rate0.499400138854980468750.0109996795654296875cloud_shadow0.269999980926513671875cloud_variance0dome_offset0.959999978542327880859375dome_radius15000droplet_radius800flags0gamma1glow50.001000000047497451305389404-0.4799999892711639404296875halo_idice_level0legacy_hazeambient1.0199999809265136718750.8099999427795410156250.809999942779541015625blue_density0.14522500336170196533203130.39999699592590332031250.80000197887420654296875blue_horizon0.10767599940299987792968750.21348699927330017089843750.25density_multiplier0.0004600000102072954177856445distance_multiplier1haze_density0.699999988079071044921875haze_horizon0.1599999964237213134765625max_y562.5mie_configanisotropy0.800000011920928955078125constant_term0exp_scale-0.0008333333535119891166687012exp_term1linear_term0width0moisture_level0moon_brightness0.5moon_idec4b9f0b-d008-45c6-96a4-01dd947ac621moon_rotation00.037689492106437683105468754.361759309290391684044152e-080.99928951263427734375moon_scale1planet_radius6360rainbow_id11b4c57c-56b3-04ed-1f82-2004363882e4rayleigh_configconstant_term0exp_scale-0.0001250000059371814131736755exp_term1linear_term0width0sky_bottom_radius6360sky_top_radius6420star_brightness0sun_arc_radians0.0004499999922700226306915283sun_idsun_rotation0-0.9992895126342773437500.03768949210643768310546875sun_scale1sunlight_color2.8385701179504394531252.8385701179504394531252.8385701179504394531251typesky13959514211989552638absorption_configconstant_term1exp_scale0exp_term0linear_term0width0constant_term1exp_scale0exp_term0linear_term0width0bloom_id3c59f7fe-9dc8-47f9-8aaf-a9dd1fbc3befcloud_color0.22616603970527648925781250.22616603970527648925781250.2261660397052764892578125cloud_id1dc1368f-e8fe-f02d-a08d-9d9f11c1af6bcloud_pos_density110.5260969996452331542968750.88000023365020751953125cloud_pos_density210.5260969996452331542968750.125cloud_scale0.4199999868869781494140625cloud_scroll_rate0.499400138854980468750.0109996795654296875cloud_shadow0.269999980926513671875cloud_variance0dome_offset0.959999978542327880859375dome_radius15000droplet_radius800flags0gamma1glow5.0009989738464355468750.001000000047497451305389404-0.480001032352447509765625halo_idice_level0legacy_hazeambient0.8099999427795410156250.4628978371620178222656250.629999935626983642578125blue_density0.1579318046569824218750.43499568104743957519531250.87000000476837158203125blue_horizon0.20673196017742156982421880.409883141517639160156250.4799999892711639404296875density_multiplier0.0006200000061653554439544678distance_multiplier2.6999280452728271484375haze_density0.53999996185302734375haze_horizon0.1599999964237213134765625max_y563mie_configanisotropy0.800000011920928955078125constant_term0exp_scale-0.0008333333535119891166687012exp_term1linear_term0width0moisture_level0moon_brightness0.5moon_idec4b9f0b-d008-45c6-96a4-01dd947ac621moon_rotation00.998889923095703125-9.238106599696038756519556e-070.04710662364959716796875moon_scale1planet_radius6360rainbow_id11b4c57c-56b3-04ed-1f82-2004363882e4rayleigh_configconstant_term0exp_scale-0.0001250000059371814131736755exp_term1linear_term0width0sky_bottom_radius6360sky_top_radius6420star_brightness0sun_arc_radians0.0004499999922700226306915283sun_idsun_rotation0-0.0471064895391464233398437500.998889923095703125sun_scale1sunlight_color2.369999885559082031252.369999885559082031252.369999885559082031250.78999996185302734375typesky17057452632552534691absorption_configconstant_term1exp_scale0exp_term0linear_term0width0constant_term1exp_scale0exp_term0linear_term0width0bloom_id3c59f7fe-9dc8-47f9-8aaf-a9dd1fbc3befcloud_color0.22615399956703186035156250.22615399956703186035156250.2261539995670318603515625cloud_id1dc1368f-e8fe-f02d-a08d-9d9f11c1af6bcloud_pos_density110.5260969996452331542968750.87999999523162841796875cloud_pos_density210.5260969996452331542968750.125cloud_scale0.4199999868869781494140625cloud_scroll_rate0.499400138854980468750.0109996795654296875cloud_shadow0.269999980926513671875cloud_variance0dome_offset0.959999978542327880859375dome_radius15000droplet_radius800flags0gamma1glow50.001000000047497451305389404-0.4799999892711639404296875halo_idice_level0legacy_hazeambient0.22259476780891418457031250.264502525329589843750.3599999845027923583984375blue_density0.4499911665916442871093750.4499985575675964355468750.450010120868682861328125blue_horizon0.23999616503715515136718750.2399992346763610839843750.2400002926588058471679688density_multiplier0.0003000046417582780122756958distance_multiplier9.999999747378751635551453e-05haze_density3.9999043941497802734375haze_horizon4.634855940821580588817596e-06max_y906.1900634765625mie_configanisotropy0.800000011920928955078125constant_term0exp_scale-0.0008333333535119891166687012exp_term1linear_term0width0moisture_level0moon_brightness0.5moon_idec4b9f0b-d008-45c6-96a4-01dd947ac621moon_rotation0-0.9238796234130859375-8.076819568714199704118073e-080.382683277130126953125moon_scale1planet_radius6360rainbow_id11b4c57c-56b3-04ed-1f82-2004363882e4rayleigh_configconstant_term0exp_scale-0.0001250000059371814131736755exp_term1linear_term0width0sky_bottom_radius6360sky_top_radius6420star_brightness499.985504150390625sun_arc_radians0.0004499999922700226306915283sun_idsun_rotation00.382683187723159790039062500.9238796234130859375sun_scale1sunlight_color0.60242295265197753906250.614470362663269042968751.139999985694885253906250.37999999523162841796875typesky17616589359191419202absorption_configconstant_term1exp_scale0exp_term0linear_term0width0constant_term1exp_scale0exp_term0linear_term0width0bloom_id3c59f7fe-9dc8-47f9-8aaf-a9dd1fbc3befcloud_color0.40999999642372131347656250.40999999642372131347656250.4099999964237213134765625cloud_id1dc1368f-e8fe-f02d-a08d-9d9f11c1af6bcloud_pos_density110.5260969996452331542968751cloud_pos_density210.5260969996452331542968750.125cloud_scale0.4199999868869781494140625cloud_scroll_rate0.199999809265136718750.0109996795654296875cloud_shadow0.269999980926513671875cloud_variance0dome_offset0.959999978542327880859375dome_radius15000droplet_radius800flags0gamma1glow50.001000000047497451305389404-0.4799999892711639404296875halo_idice_level0legacy_hazeambient1.04999995231628417968751.04999995231628417968751.0499999523162841796875blue_density0.24475814402103424072265630.44872328639030456542968750.7599999904632568359375blue_horizon0.4954838156700134277343750.4954838156700134277343750.63999998569488525390625density_multiplier0.0001799999881768599152565002distance_multiplier0.800000011920928955078125haze_density0.699999988079071044921875haze_horizon0.189999997615814208984375max_y1605mie_configanisotropy0.800000011920928955078125constant_term0exp_scale-0.0008333333535119891166687012exp_term1linear_term0width0moisture_level0moon_brightness0.5moon_idec4b9f0b-d008-45c6-96a4-01dd947ac621moon_rotation00.38268336653709411621093753.345525456666109676007181e-080.923879563808441162109375moon_scale1planet_radius6360rainbow_id11b4c57c-56b3-04ed-1f82-2004363882e4rayleigh_configconstant_term0exp_scale-0.0001250000059371814131736755exp_term1linear_term0width0sky_bottom_radius6360sky_top_radius6420star_brightness0sun_arc_radians0.0004499999922700226306915283sun_idsun_rotation0-0.923879623413085937500.382683277130126953125sun_scale1sunlight_color0.7342105507850646972656250.7815789580345153808593750.899999976158142089843750.2999999821186065673828125typesky18208940288658674853absorption_configconstant_term1exp_scale0exp_term0linear_term0width0constant_term1exp_scale0exp_term0linear_term0width0bloom_id3c59f7fe-9dc8-47f9-8aaf-a9dd1fbc3befcloud_color0.40999999642372131347656250.40999999642372131347656250.4099999964237213134765625cloud_id1dc1368f-e8fe-f02d-a08d-9d9f11c1af6bcloud_pos_density110.5260969996452331542968751cloud_pos_density210.5260969996452331542968750.125cloud_scale0.4199999868869781494140625cloud_scroll_rate0.199999809265136718750.0109996795654296875cloud_shadow0.269999980926513671875cloud_variance0dome_offset0.959999978542327880859375dome_radius15000droplet_radius800flags0gamma1glow50.001000000047497451305389404-0.4799999892711639404296875halo_idice_level0legacy_hazeambient1.04999995231628417968751.04999995231628417968751.0499999523162841796875blue_density0.24475815892219543457031250.44872328639030456542968750.7599999904632568359375blue_horizon0.4954838156700134277343750.4954838156700134277343750.63999998569488525390625density_multiplier0.0001799999881768599152565002distance_multiplier0.800000011920928955078125haze_density0.699999988079071044921875haze_horizon0.189999997615814208984375max_y1605mie_configanisotropy0.800000011920928955078125constant_term0exp_scale-0.0008333333535119891166687012exp_term1linear_term0width0moisture_level0moon_brightness0.5moon_idec4b9f0b-d008-45c6-96a4-01dd947ac621moon_rotation00.7071067690849304199218755.404234527874203497521677e-150.7071068286895751953125moon_scale1planet_radius6360rainbow_id11b4c57c-56b3-04ed-1f82-2004363882e4rayleigh_configconstant_term0exp_scale-0.0001250000059371814131736755exp_term1linear_term0width0sky_bottom_radius6360sky_top_radius6420star_brightness0sun_arc_radians0.0004499999922700226306915283sun_idsun_rotation0-0.707106828689575195312500.7071068286895751953125sun_scale1sunlight_color0.7342105507850646972656250.7815789580345153808593750.899999976158142089843750.2999999821186065673828125typesky3639038607915694966absorption_configconstant_term1exp_scale0exp_term0linear_term0width0constant_term1exp_scale0exp_term0linear_term0width0bloom_id3c59f7fe-9dc8-47f9-8aaf-a9dd1fbc3befcloud_color0.22615399956703186035156250.22615399956703186035156250.2261539995670318603515625cloud_id1dc1368f-e8fe-f02d-a08d-9d9f11c1af6bcloud_pos_density110.5260969996452331542968750.87999999523162841796875cloud_pos_density210.5260969996452331542968750.125cloud_scale0.4199999868869781494140625cloud_scroll_rate0.499400138854980468750.0109996795654296875cloud_shadow0.269999980926513671875cloud_variance0dome_offset0.959999978542327880859375dome_radius15000droplet_radius800flags0gamma1glow50.001000000047497451305389404-0.4799999892711639404296875halo_idice_level0legacy_hazeambient0.20404693484306335449218750.24246276915073394775390630.3300038278102874755859375blue_density0.4499911665916442871093750.4499985575675964355468750.450010120868682861328125blue_horizon0.23999616503715515136718750.2399992346763610839843750.2400002926588058471679688density_multiplier0.0003000046417582780122756958distance_multiplier9.999999747378751635551453e-05haze_density3.9999043941497802734375haze_horizon4.634855940821580588817596e-06max_y906.1900634765625mie_configanisotropy0.800000011920928955078125constant_term0exp_scale-0.0008333333535119891166687012exp_term1linear_term0width0moisture_level0moon_brightness0.5moon_idec4b9f0b-d008-45c6-96a4-01dd947ac621moon_rotation0-0.38268360495567321777343753.345525101394741795957088e-080.92387950420379638671875moon_scale1planet_radius6360rainbow_id11b4c57c-56b3-04ed-1f82-2004363882e4rayleigh_configconstant_term0exp_scale-0.0001250000059371814131736755exp_term1linear_term0width0sky_bottom_radius6360sky_top_radius6420star_brightness499.985504150390625sun_arc_radians0.0004499999922700226306915283sun_idsun_rotation00.9238795042037963867187500.3826837241649627685546875sun_scale1sunlight_color0.348789811134338378906250.35576510429382324218750.66003584861755371093750.2200119793415069580078125typesky4342854188752023401absorption_configconstant_term1exp_scale0exp_term0linear_term0width0constant_term1exp_scale0exp_term0linear_term0width0bloom_id3c59f7fe-9dc8-47f9-8aaf-a9dd1fbc3befcloud_color0.370000004768371582031250.370000004768371582031250.37000000476837158203125cloud_id1dc1368f-e8fe-f02d-a08d-9d9f11c1af6bcloud_pos_density110.5260969996452331542968751cloud_pos_density210.5260969996452331542968750.125cloud_scale0.4199999868869781494140625cloud_scroll_rate0.199999809265136718750.0109996795654296875cloud_shadow0.2733333110809326171875cloud_variance0dome_offset0.959999978542327880859375dome_radius15000droplet_radius800flags0gamma1glow50.001000000047497451305389404-0.4799999892711639404296875halo_idice_level0legacy_hazeambient1.04999995231628417968751.04999995231628417968751.0499999523162841796875blue_density0.15999999642372131347656250.44872328639030456542968750.7599999904632568359375blue_horizon0.539999961853027343750.47999998927116394042968750.699999988079071044921875density_multiplier0.0001799999881768599152565002distance_multiplier0.80000007152557373046875haze_density0.7000000476837158203125haze_horizon0.189999997615814208984375max_y1605mie_configanisotropy0.800000011920928955078125constant_term0exp_scale-0.0008333333535119891166687012exp_term1linear_term0width0moisture_level0moon_brightness0.5moon_idec4b9f0b-d008-45c6-96a4-01dd947ac621moon_rotation00.923879563808441162109375-8.076811752744106343016028e-080.382683277130126953125moon_scale1planet_radius6360rainbow_id11b4c57c-56b3-04ed-1f82-2004363882e4rayleigh_configconstant_term0exp_scale-0.0001250000059371814131736755exp_term1linear_term0width0sky_bottom_radius6360sky_top_radius6420star_brightness0sun_arc_radians0.0004499999922700226306915283sun_idsun_rotation0-0.3826833963394165039062500.923879563808441162109375sun_scale1sunlight_color0.7342105507850646972656250.7815789580345153808593750.899999976158142089843750.2999999821186065673828125typeskynameDefault environmenttrackskey_keyframe0key_name12059426462794438368key_keyframe0key_name10809890408763334407key_keyframe0.125key_name17057452632552534691key_keyframe0.25key_name13959514211989552638key_keyframe0.375key_name4342854188752023401key_keyframe0.5key_name18208940288658674853key_keyframe0.625key_name17616589359191419202key_keyframe0.75key_name12704758109389341107key_keyframe0.875key_name3639038607915694966typedaycycle \ No newline at end of file diff --git a/bin/assets/SettingsAssetSet/SettingsAssetSet.xml b/bin/assets/SettingsAssetSet/SettingsAssetSet.xml new file mode 100644 index 0000000000..3ca9e533ca --- /dev/null +++ b/bin/assets/SettingsAssetSet/SettingsAssetSet.xml @@ -0,0 +1,9 @@ + +
+ + + + +
+ +
diff --git a/bin/assets/TexturesAssetSet/DefaultClouds.j2c b/bin/assets/TexturesAssetSet/DefaultClouds.j2c new file mode 100644 index 0000000000000000000000000000000000000000..4d93df85e9b5320fd2cf171359e1f1d05b079243 GIT binary patch literal 58521 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 U8~9e223yliu9j94U4Vf9*| +
+ + + + +
+ diff --git a/bin/inventory/Libraries.xml b/bin/inventory/Libraries.xml index d9592a4a56..2d1362abbb 100644 --- a/bin/inventory/Libraries.xml +++ b/bin/inventory/Libraries.xml @@ -82,5 +82,9 @@ +
+ + +
diff --git a/bin/inventory/SettingsLibrary/Folders.xml b/bin/inventory/SettingsLibrary/Folders.xml new file mode 100644 index 0000000000..2a51762848 --- /dev/null +++ b/bin/inventory/SettingsLibrary/Folders.xml @@ -0,0 +1,28 @@ + + + +
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
diff --git a/bin/inventory/SettingsLibrary/Items.xml b/bin/inventory/SettingsLibrary/Items.xml new file mode 100644 index 0000000000..4de0f7fc3b --- /dev/null +++ b/bin/inventory/SettingsLibrary/Items.xml @@ -0,0 +1,40 @@ + + + + + + + +
+ + + + + + + + +
+ + +